blob: 38ba90c9e855dc126b6feadba494aac484dd3edf [file] [log] [blame]
/*
*
* Copyright (c) 2020 Project CHIP Authors
* Copyright (c) 2018 Nest Labs, Inc.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <platform/ConnectivityManager.h>
#include <platform/internal/CHIPDeviceLayerInternal.h>
#include <platform/mbed/ConnectivityManagerImpl.h>
#include <platform/mbed/NetworkCommissioningDriver.h>
#include <platform/internal/GenericConnectivityManagerImpl_WiFi.ipp>
#include <app/clusters/network-commissioning/network-commissioning.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>
using namespace ::chip;
using namespace ::chip::Inet;
using namespace ::chip::System;
using namespace ::chip::DeviceLayer;
using namespace ::chip::DeviceLayer::Internal;
namespace chip {
namespace DeviceLayer {
#if CHIP_DEVICE_ENABLE_DATA_MODEL
namespace {
app::Clusters::NetworkCommissioning::Instance
sWiFiNetworkCommissioningInstance(0 /* Endpoint Id */, &(NetworkCommissioning::WiFiDriverImpl::GetInstance()));
} // namespace
#endif // CHIP_DEVICE_ENABLE_DATA_MODEL
CHIP_ERROR ConnectivityManagerImpl::InitWiFi()
{
CHIP_ERROR err = CHIP_NO_ERROR;
NetworkCommissioning::NetworkIterator * networks;
mWiFiStationState = kWiFiStationState_NotConnected;
mWiFiStationReconnectInterval = System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_WIFI_STATION_RECONNECT_INTERVAL);
#if CHIP_DEVICE_ENABLE_DATA_MODEL
err = sWiFiNetworkCommissioningInstance.Init();
#else
err = NetworkCommissioning::WiFiDriverImpl::GetInstance().Init(nullptr);
#endif
VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(DeviceLayer, "WiFi driver init failed: %s", chip::ErrorStr(err)));
mWiFiStationMode = kWiFiStationMode_Enabled;
networks = NetworkCommissioning::WiFiDriverImpl::GetInstance().GetNetworks();
if (networks != nullptr && networks->Count() > 0)
{
mIsProvisioned = true;
}
else
{
mIsProvisioned = false;
}
if (networks != nullptr)
{
networks->Release();
}
exit:
return err;
}
void ConnectivityManagerImpl::OnWiFiPlatformEvent(const ChipDeviceEvent * event)
{
if (event->Type == DeviceEventType::kWiFiConnectivityChange)
{
WiFiStationState wifiStaState;
switch (event->WiFiConnectivityChange.Result)
{
case kConnectivity_NoChange:
wifiStaState = kWiFiStationState_Connecting;
break;
case kConnectivity_Established:
ChipLogProgress(DeviceLayer, "WiFi station connected");
wifiStaState = kWiFiStationState_Connected;
break;
case kConnectivity_Lost:
ChipLogProgress(DeviceLayer, "WiFi station disconnected");
wifiStaState = kWiFiStationState_NotConnected;
NetworkCommissioning::WiFiDriverImpl::GetInstance().SetLastDisconnectReason(event);
break;
default:
ChipLogError(DeviceLayer, "Unknown WiFi connectivity state");
return;
}
ChangeWiFiStationState(wifiStaState);
}
}
void ConnectivityManagerImpl::ChangeWiFiStationState(WiFiStationState newState)
{
if (mWiFiStationState != newState)
{
ChipLogProgress(DeviceLayer, "WiFi station state change: %s -> %s", WiFiStationStateToStr(mWiFiStationState),
WiFiStationStateToStr(newState));
mWiFiStationState = newState;
SystemLayer().ScheduleLambda([]() { NetworkCommissioning::WiFiDriverImpl::GetInstance().OnNetworkStatusChange(); });
}
}
CHIP_ERROR ConnectivityManagerImpl::_SetWiFiStationMode(WiFiStationMode val)
{
CHIP_ERROR err = CHIP_NO_ERROR;
VerifyOrExit(val != kWiFiStationMode_NotSupported, err = CHIP_ERROR_INVALID_ARGUMENT);
if (mWiFiStationMode != val)
{
ChipLogProgress(DeviceLayer, "WiFi station mode change: %s -> %s", WiFiStationModeToStr(mWiFiStationMode),
WiFiStationModeToStr(val));
mWiFiStationMode = val;
if (mWiFiStationMode != kWiFiStationMode_ApplicationControlled)
{
if (mWiFiStationMode == kWiFiStationMode_Enabled)
{
NetworkCommissioning::WiFiDriverImpl::GetInstance().Init(nullptr);
}
else if (mWiFiStationMode == kWiFiStationMode_Disabled)
{
NetworkCommissioning::WiFiDriverImpl::GetInstance().Shutdown();
}
}
}
exit:
return err;
}
CHIP_ERROR ConnectivityManagerImpl::_SetWiFiStationReconnectInterval(System::Clock::Timeout val)
{
CHIP_ERROR err = CHIP_NO_ERROR;
if (mWiFiStationReconnectInterval != val)
{
ChipLogProgress(DeviceLayer, "WiFi station reconnect interval change: %lu ms -> %lu ms",
System::Clock::Milliseconds32(mWiFiStationReconnectInterval).count(),
System::Clock::Milliseconds32(val).count());
}
mWiFiStationReconnectInterval = val;
return err;
}
void ConnectivityManagerImpl::_ClearWiFiStationProvision(void)
{
if (mWiFiStationMode != kWiFiStationMode_ApplicationControlled)
{
auto networks = NetworkCommissioning::WiFiDriverImpl::GetInstance().GetNetworks();
NetworkCommissioning::Network network;
for (; networks != nullptr && networks->Next(network);)
{
MutableCharSpan emptyBufferForDebugText;
uint8_t outNetworkIndex;
if (network.connected)
{
NetworkCommissioning::WiFiDriverImpl::GetInstance().DisconnectNetwork(
ByteSpan(network.networkID, network.networkIDLen));
}
NetworkCommissioning::WiFiDriverImpl::GetInstance().RemoveNetwork(ByteSpan(network.networkID, network.networkIDLen),
emptyBufferForDebugText, outNetworkIndex);
}
if (networks != nullptr)
{
networks->Release();
}
}
}
} // namespace DeviceLayer
} // namespace chip