From d9e2d5cf939eac44775136282346b6df092858ac Mon Sep 17 00:00:00 2001 From: pankore <86098180+pankore@users.noreply.github.com> Date: Wed, 20 Apr 2022 23:03:01 +0800 Subject: [PATCH] [Ameba] Autonomous connection status networkcommissioning driver (#17534) * [NetworkCommissioning] Implement callback for wifi disconnect event - Add new kRtkWiFiStationDisconnectedEvent event - Add callbacks for wifi disconnect event - Update network commissioning driver - Get last disconnect reason * [NetworkCommissioning] Fix hardfault during commissioning - Move registration of wifi event handlers to ConnectivityManagerImpl::_Init() - Set mpStatusChangeCallback at the start of AmebaWiFiDriver::Init() - Clean up loggings --- src/platform/Ameba/CHIPDevicePlatformEvent.h | 1 + .../Ameba/ConnectivityManagerImpl.cpp | 23 ++++- src/platform/Ameba/ConnectivityManagerImpl.h | 1 + .../Ameba/NetworkCommissioningDriver.h | 7 ++ .../Ameba/NetworkCommissioningWiFiDriver.cpp | 88 ++++++++++++++----- 5 files changed, 97 insertions(+), 23 deletions(-) diff --git a/src/platform/Ameba/CHIPDevicePlatformEvent.h b/src/platform/Ameba/CHIPDevicePlatformEvent.h index 02bf61d0fadd1e..1f198123453587 100644 --- a/src/platform/Ameba/CHIPDevicePlatformEvent.h +++ b/src/platform/Ameba/CHIPDevicePlatformEvent.h @@ -49,6 +49,7 @@ enum InternalPlatformSpecificEventTypes kCHIPoBLERXCharWriteEvent, kCHIPoBLETXCharWriteEvent, kRtkWiFiStationConnectedEvent, + kRtkWiFiStationDisconnectedEvent, kRtkWiFiScanCompletedEvent, }; diff --git a/src/platform/Ameba/ConnectivityManagerImpl.cpp b/src/platform/Ameba/ConnectivityManagerImpl.cpp index 534e4cb2c6c971..0f7878639add42 100644 --- a/src/platform/Ameba/ConnectivityManagerImpl.cpp +++ b/src/platform/Ameba/ConnectivityManagerImpl.cpp @@ -72,6 +72,10 @@ CHIP_ERROR ConnectivityManagerImpl::_Init() // Set callback functions from chip_porting chip_connmgr_set_callback_func((chip_connmgr_callback)(conn_callback_dispatcher), this); + + // Register WiFi event handlers + wifi_reg_event_handler(WIFI_EVENT_CONNECT, ConnectivityManagerImpl::RtkWiFiStationConnectedHandler, NULL); + wifi_reg_event_handler(WIFI_EVENT_DISCONNECT, ConnectivityManagerImpl::RtkWiFiStationDisconnectedHandler, NULL); // Ensure that station mode is enabled. wifi_on(RTW_MODE_STA); @@ -148,6 +152,15 @@ void ConnectivityManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) DriveStationState(); DHCPProcess(); } + if (event->Type == DeviceEventType::kRtkWiFiStationDisconnectedEvent) + { + ChipLogProgress(DeviceLayer, "WiFiStationDisconnected"); + NetworkCommissioning::AmebaWiFiDriver::GetInstance().SetLastDisconnectReason(event); + if (mWiFiStationState == kWiFiStationState_Connecting) + { + ChangeWiFiStationState(kWiFiStationState_Connecting_Failed); + } + } if (event->Type == DeviceEventType::kRtkWiFiScanCompletedEvent) { ChipLogProgress(DeviceLayer, "WiFiScanCompleted"); @@ -540,7 +553,6 @@ void ConnectivityManagerImpl::DriveStationState() ChipLogProgress(DeviceLayer, "Attempting to connect WiFi station interface"); rtw_wifi_setting_t wifi_info; CHIP_GetWiFiConfig(&wifi_info); - wifi_reg_event_handler(WIFI_EVENT_CONNECT, ConnectivityManagerImpl::RtkWiFiStationConnectedHandler, NULL); wifi_connect((char *) wifi_info.ssid, RTW_SECURITY_WPA_WPA2_MIXED, (char *) wifi_info.password, strlen((const char *) wifi_info.ssid), strlen((const char *) wifi_info.password), 0, NULL); ChangeWiFiStationState(kWiFiStationState_Connecting); @@ -593,6 +605,7 @@ void ConnectivityManagerImpl::ChangeWiFiStationState(WiFiStationState newState) { ChipLogProgress(DeviceLayer, "WiFi station state change: %d -> %d", (mWiFiStationState), (newState)); mWiFiStationState = newState; + SystemLayer().ScheduleLambda([]() { NetworkCommissioning::AmebaWiFiDriver::GetInstance().OnNetworkStatusChange(); }); } } @@ -786,6 +799,14 @@ void ConnectivityManagerImpl::RtkWiFiStationConnectedHandler(char * buf, int buf PlatformMgr().PostEventOrDie(&event); } +void ConnectivityManagerImpl::RtkWiFiStationDisconnectedHandler(char * buf, int buf_len, int flags, void * userdata) +{ + ChipDeviceEvent event; + memset(&event, 0, sizeof(event)); + event.Type = DeviceEventType::kRtkWiFiStationDisconnectedEvent; + PlatformMgr().PostEventOrDie(&event); +} + void ConnectivityManagerImpl::RtkWiFiScanCompletedHandler(void) { ChipDeviceEvent event; diff --git a/src/platform/Ameba/ConnectivityManagerImpl.h b/src/platform/Ameba/ConnectivityManagerImpl.h index 861a2581452d33..61f602961f2ce4 100644 --- a/src/platform/Ameba/ConnectivityManagerImpl.h +++ b/src/platform/Ameba/ConnectivityManagerImpl.h @@ -144,6 +144,7 @@ class ConnectivityManagerImpl final : public ConnectivityManager, static ConnectivityManagerImpl sInstance; static void RefreshMessageLayer(void); static void RtkWiFiStationConnectedHandler(char * buf, int buf_len, int flags, void * userdata); + static void RtkWiFiStationDisconnectedHandler(char * buf, int buf_len, int flags, void * userdata); static void RtkWiFiScanCompletedHandler(void); void DHCPProcess(void); static void DHCPProcessThread(void * param); diff --git a/src/platform/Ameba/NetworkCommissioningDriver.h b/src/platform/Ameba/NetworkCommissioningDriver.h index ceaba4aca1f1af..dfaf995d6be6de 100644 --- a/src/platform/Ameba/NetworkCommissioningDriver.h +++ b/src/platform/Ameba/NetworkCommissioningDriver.h @@ -112,6 +112,11 @@ class AmebaWiFiDriver final : public WiFiDriver CHIP_ERROR ConnectWiFiNetwork(const char * ssid, uint8_t ssidLen, const char * key, uint8_t keyLen); void OnConnectWiFiNetwork(); void OnScanWiFiNetworkDone(); + void OnNetworkStatusChange(); + + CHIP_ERROR SetLastDisconnectReason(const ChipDeviceEvent * event); + int32_t GetLastDisconnectReason(); + static AmebaWiFiDriver & GetInstance() { static AmebaWiFiDriver instance; @@ -127,6 +132,8 @@ class AmebaWiFiDriver final : public WiFiDriver WiFiNetwork mStagingNetwork; ScanCallback * mpScanCallback; ConnectCallback * mpConnectCallback; + NetworkStatusChangeCallback * mpStatusChangeCallback = nullptr; + int32_t mLastDisconnectedReason; }; } // namespace NetworkCommissioning diff --git a/src/platform/Ameba/NetworkCommissioningWiFiDriver.cpp b/src/platform/Ameba/NetworkCommissioningWiFiDriver.cpp index d96a99a44afc72..57bc627697b12e 100644 --- a/src/platform/Ameba/NetworkCommissioningWiFiDriver.cpp +++ b/src/platform/Ameba/NetworkCommissioningWiFiDriver.cpp @@ -35,21 +35,24 @@ constexpr char kWiFiSSIDKeyName[] = "wifi-ssid"; constexpr char kWiFiCredentialsKeyName[] = "wifi-pass"; } // namespace -CHIP_ERROR AmebaWiFiDriver::Init(NetworkStatusChangeCallback *) +CHIP_ERROR AmebaWiFiDriver::Init(NetworkStatusChangeCallback * networkStatusChangeCallback) { CHIP_ERROR err; size_t ssidLen = 0; size_t credentialsLen = 0; + mpScanCallback = nullptr; + mpConnectCallback = nullptr; + mpStatusChangeCallback = networkStatusChangeCallback; err = PersistedStorage::KeyValueStoreMgr().Get(kWiFiCredentialsKeyName, mSavedNetwork.credentials, sizeof(mSavedNetwork.credentials), &credentialsLen); - if (err == CHIP_ERROR_NOT_FOUND) + if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND) { return CHIP_NO_ERROR; } err = PersistedStorage::KeyValueStoreMgr().Get(kWiFiSSIDKeyName, mSavedNetwork.ssid, sizeof(mSavedNetwork.ssid), &ssidLen); - if (err == CHIP_ERROR_NOT_FOUND) + if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND) { return CHIP_NO_ERROR; } @@ -57,13 +60,12 @@ CHIP_ERROR AmebaWiFiDriver::Init(NetworkStatusChangeCallback *) mSavedNetwork.ssidLen = ssidLen; mStagingNetwork = mSavedNetwork; - mpScanCallback = nullptr; - mpConnectCallback = nullptr; return err; } CHIP_ERROR AmebaWiFiDriver::Shutdown() { + mpStatusChangeCallback = nullptr; return CHIP_NO_ERROR; } @@ -244,6 +246,49 @@ void AmebaWiFiDriver::OnScanWiFiNetworkDone() vPortFree(ScanResult); } +CHIP_ERROR GetConfiguredNetwork(Network & network) +{ + rtw_wifi_setting_t wifi_setting; + CHIP_GetWiFiConfig(&wifi_setting); + + uint8_t length = strnlen(reinterpret_cast(wifi_setting.ssid), DeviceLayer::Internal::kMaxWiFiSSIDLength); + if (length > sizeof(network.networkID)) + { + ChipLogError(DeviceLayer, "SSID too long"); + return CHIP_ERROR_INTERNAL; + } + + memcpy(network.networkID, wifi_setting.ssid, length); + network.networkIDLen = length; + return CHIP_NO_ERROR; +} + +void AmebaWiFiDriver::OnNetworkStatusChange() +{ + Network configuredNetwork; + rtw_wifi_setting_t mWiFiSetting; + CHIP_GetWiFiConfig(&mWiFiSetting); + bool staEnable = (mWiFiSetting.mode == RTW_MODE_STA || mWiFiSetting.mode == RTW_MODE_STA_AP); + bool staConnected = (mWiFiSetting.ssid[0] != 0); + + CHIP_ERROR err = GetConfiguredNetwork(configuredNetwork); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to get configured network when updating network status: %s", err.AsString()); + return; + } + + if (staConnected) + { + mpStatusChangeCallback->OnNetworkingStatusChange( + Status::kSuccess, MakeOptional(ByteSpan(configuredNetwork.networkID, configuredNetwork.networkIDLen)), NullOptional); + return; + } + mpStatusChangeCallback->OnNetworkingStatusChange( + Status::kUnknownError, MakeOptional(ByteSpan(configuredNetwork.networkID, configuredNetwork.networkIDLen)), + MakeOptional(GetLastDisconnectReason())); +} + void AmebaWiFiDriver::ScanNetworks(ByteSpan ssid, WiFiDriver::ScanCallback * callback) { if (callback != nullptr) @@ -257,23 +302,18 @@ void AmebaWiFiDriver::ScanNetworks(ByteSpan ssid, WiFiDriver::ScanCallback * cal } } -CHIP_ERROR GetConnectedNetwork(Network & network) +CHIP_ERROR AmebaWiFiDriver::SetLastDisconnectReason(const ChipDeviceEvent * event) { - rtw_wifi_setting_t wifi_setting; - CHIP_GetWiFiConfig(&wifi_setting); - - uint8_t length = strnlen(reinterpret_cast(wifi_setting.ssid), DeviceLayer::Internal::kMaxWiFiSSIDLength); - if (length > sizeof(network.networkID)) - { - ChipLogError(DeviceLayer, "SSID too long"); - return CHIP_ERROR_INTERNAL; - } - - memcpy(network.networkID, wifi_setting.ssid, length); - network.networkIDLen = length; + VerifyOrReturnError(event->Type == DeviceEventType::kRtkWiFiStationDisconnectedEvent, CHIP_ERROR_INVALID_ARGUMENT); + mLastDisconnectedReason = wifi_get_last_error(); return CHIP_NO_ERROR; } +int32_t AmebaWiFiDriver::GetLastDisconnectReason() +{ + return mLastDisconnectedReason; +} + size_t AmebaWiFiDriver::WiFiNetworkIterator::Count() { return mDriver->mStagingNetwork.ssidLen == 0 ? 0 : 1; @@ -290,12 +330,16 @@ bool AmebaWiFiDriver::WiFiNetworkIterator::Next(Network & item) item.connected = false; mExhausted = true; - Network connectedNetwork; - CHIP_ERROR err = GetConnectedNetwork(connectedNetwork); + Network configuredNetwork; + CHIP_ERROR err = GetConfiguredNetwork(configuredNetwork); if (err == CHIP_NO_ERROR) { - if (connectedNetwork.networkIDLen == item.networkIDLen && - memcmp(connectedNetwork.networkID, item.networkID, item.networkIDLen) == 0) + rtw_wifi_setting_t mWiFiSetting; + CHIP_GetWiFiConfig(&mWiFiSetting); + bool isConnected = (mWiFiSetting.ssid[0] != 0); + + if (isConnected && configuredNetwork.networkIDLen == item.networkIDLen && + memcmp(configuredNetwork.networkID, item.networkID, item.networkIDLen) == 0) { item.connected = true; }