[Ameba] Wifi connectivity update (#25955)

* [wifi] store wifi info into kvs after commissioning complete
- for onnetwork devices, wifi info not stored
- cleanup connectivitymgr

* [wifi] make ChangeWiFiStationState accessible from NetworkCommissioningDriver

* fix dhcp issue

* restyle

* add comments
diff --git a/examples/all-clusters-app/ameba/main/DeviceCallbacks.cpp b/examples/all-clusters-app/ameba/main/DeviceCallbacks.cpp
index a60b605..b31d262 100644
--- a/examples/all-clusters-app/ameba/main/DeviceCallbacks.cpp
+++ b/examples/all-clusters-app/ameba/main/DeviceCallbacks.cpp
@@ -33,6 +33,7 @@
 #include <app/util/basic-types.h>
 #include <app/util/util.h>
 #include <lib/dnssd/Advertiser.h>
+#include <platform/Ameba/AmebaUtils.h>
 #include <route_hook/ameba_route_hook.h>
 #include <support/CodeUtils.h>
 #include <support/logging/CHIPLogging.h>
@@ -103,6 +104,7 @@
 
     case DeviceEventType::kCommissioningComplete:
         ChipLogProgress(DeviceLayer, "Commissioning Complete");
+        chip::DeviceLayer::Internal::AmebaUtils::SetCurrentProvisionedNetwork();
         break;
     }
 }
diff --git a/examples/light-switch-app/ameba/main/DeviceCallbacks.cpp b/examples/light-switch-app/ameba/main/DeviceCallbacks.cpp
index 6d72c6a..b5fbaf1 100644
--- a/examples/light-switch-app/ameba/main/DeviceCallbacks.cpp
+++ b/examples/light-switch-app/ameba/main/DeviceCallbacks.cpp
@@ -32,6 +32,7 @@
 #include <app/util/basic-types.h>
 #include <app/util/util.h>
 #include <lib/dnssd/Advertiser.h>
+#include <platform/Ameba/AmebaUtils.h>
 #include <route_hook/ameba_route_hook.h>
 #include <support/CodeUtils.h>
 #include <support/logging/CHIPLogging.h>
@@ -103,6 +104,7 @@
 
     case DeviceEventType::kCommissioningComplete:
         ChipLogProgress(DeviceLayer, "Commissioning Complete");
+        chip::DeviceLayer::Internal::AmebaUtils::SetCurrentProvisionedNetwork();
         break;
     }
 }
diff --git a/examples/lighting-app/ameba/main/DeviceCallbacks.cpp b/examples/lighting-app/ameba/main/DeviceCallbacks.cpp
index 6ed98af..abc6472 100644
--- a/examples/lighting-app/ameba/main/DeviceCallbacks.cpp
+++ b/examples/lighting-app/ameba/main/DeviceCallbacks.cpp
@@ -33,6 +33,7 @@
 #include <app/util/basic-types.h>
 #include <app/util/util.h>
 #include <lib/dnssd/Advertiser.h>
+#include <platform/Ameba/AmebaUtils.h>
 #include <route_hook/ameba_route_hook.h>
 #include <support/CodeUtils.h>
 #include <support/logging/CHIPLogging.h>
@@ -101,6 +102,7 @@
 
     case DeviceEventType::kCommissioningComplete:
         ChipLogProgress(DeviceLayer, "Commissioning Complete");
+        chip::DeviceLayer::Internal::AmebaUtils::SetCurrentProvisionedNetwork();
         break;
     }
 }
diff --git a/examples/ota-requestor-app/ameba/main/DeviceCallbacks.cpp b/examples/ota-requestor-app/ameba/main/DeviceCallbacks.cpp
index d62996b..67cb1ac 100644
--- a/examples/ota-requestor-app/ameba/main/DeviceCallbacks.cpp
+++ b/examples/ota-requestor-app/ameba/main/DeviceCallbacks.cpp
@@ -33,6 +33,7 @@
 #include <app/util/basic-types.h>
 #include <app/util/util.h>
 #include <lib/dnssd/Advertiser.h>
+#include <platform/Ameba/AmebaUtils.h>
 #include <route_hook/ameba_route_hook.h>
 #include <support/CodeUtils.h>
 #include <support/logging/CHIPLogging.h>
@@ -103,6 +104,7 @@
 
     case DeviceEventType::kCommissioningComplete:
         ChipLogProgress(DeviceLayer, "Commissioning Complete");
+        chip::DeviceLayer::Internal::AmebaUtils::SetCurrentProvisionedNetwork();
         break;
     }
 }
diff --git a/src/platform/Ameba/AmebaUtils.cpp b/src/platform/Ameba/AmebaUtils.cpp
index 72d0e7f..578ffab 100644
--- a/src/platform/Ameba/AmebaUtils.cpp
+++ b/src/platform/Ameba/AmebaUtils.cpp
@@ -136,7 +136,7 @@
     return err;
 }
 
-CHIP_ERROR AmebaUtils::WiFiConnect(void)
+CHIP_ERROR AmebaUtils::WiFiConnectProvisionedNetwork(void)
 {
     CHIP_ERROR err             = CHIP_NO_ERROR;
     rtw_wifi_config_t * config = (rtw_wifi_config_t *) pvPortMalloc(sizeof(rtw_wifi_config_t));
@@ -144,9 +144,56 @@
     GetWiFiConfig(config);
     ChipLogProgress(DeviceLayer, "Connecting to AP : [%s]", (char *) config->ssid);
     int ameba_err = matter_wifi_connect((char *) config->ssid, RTW_SECURITY_WPA_WPA2_MIXED, (char *) config->password,
-                                        strlen((const char *) config->ssid), strlen((const char *) config->password), 0, NULL);
+                                        strlen((const char *) config->ssid), strlen((const char *) config->password), 0, nullptr);
 
     vPortFree(config);
     err = (ameba_err == RTW_SUCCESS) ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL;
     return err;
 }
+
+CHIP_ERROR AmebaUtils::WiFiConnect(const char * ssid, const char * password)
+{
+    CHIP_ERROR err = CHIP_NO_ERROR;
+    ChipLogProgress(DeviceLayer, "Connecting to AP : [%s]", (char *) ssid);
+    int ameba_err = matter_wifi_connect((char *) ssid, RTW_SECURITY_WPA_WPA2_MIXED, (char *) password, strlen(ssid),
+                                        strlen(password), 0, nullptr);
+    err           = (ameba_err == RTW_SUCCESS) ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL;
+    return err;
+}
+
+CHIP_ERROR AmebaUtils::SetCurrentProvisionedNetwork()
+{
+    CHIP_ERROR err = CHIP_NO_ERROR;
+    rtw_wifi_setting_t pSetting;
+    int ret = matter_get_sta_wifi_info(&pSetting);
+    if (ret < 0)
+    {
+        ChipLogProgress(DeviceLayer, "STA No Wi-Fi Info");
+        goto exit;
+    }
+    else
+    {
+        rtw_wifi_config_t config = { 0 };
+        GetWiFiConfig(&config);
+        if (!memcmp(config.ssid, pSetting.ssid, strlen((const char *) pSetting.ssid) + 1))
+        {
+            ChipLogProgress(DeviceLayer, "STA Wi-Fi Info exist, do nothing");
+            goto exit;
+        }
+        else
+        {
+            ChipLogProgress(DeviceLayer, "STA Wi-Fi Info ");
+
+            memcpy(config.ssid, pSetting.ssid, strlen((const char *) pSetting.ssid) + 1);
+            memcpy(config.password, pSetting.password, strlen((const char *) pSetting.password) + 1);
+            err = SetWiFiConfig(&config);
+            if (err != CHIP_NO_ERROR)
+            {
+                ChipLogError(DeviceLayer, "SetWiFiConfig() failed");
+                goto exit;
+            }
+        }
+    }
+exit:
+    return err;
+}
diff --git a/src/platform/Ameba/AmebaUtils.h b/src/platform/Ameba/AmebaUtils.h
index b2f68f3..5fcc5c9 100644
--- a/src/platform/Ameba/AmebaUtils.h
+++ b/src/platform/Ameba/AmebaUtils.h
@@ -36,7 +36,9 @@
     static CHIP_ERROR GetWiFiConfig(rtw_wifi_config_t * config);
     static CHIP_ERROR ClearWiFiConfig(void);
     static CHIP_ERROR WiFiDisconnect(void);
-    static CHIP_ERROR WiFiConnect(void);
+    static CHIP_ERROR WiFiConnectProvisionedNetwork(void);
+    static CHIP_ERROR WiFiConnect(const char * ssid, const char * password);
+    static CHIP_ERROR SetCurrentProvisionedNetwork(void);
 };
 
 } // namespace Internal
diff --git a/src/platform/Ameba/ConnectivityManagerImpl.cpp b/src/platform/Ameba/ConnectivityManagerImpl.cpp
index 670c060..ba289b1 100644
--- a/src/platform/Ameba/ConnectivityManagerImpl.cpp
+++ b/src/platform/Ameba/ConnectivityManagerImpl.cpp
@@ -83,7 +83,7 @@
     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_FOURWAY_HANDSHAKE_DONE, ConnectivityManagerImpl::RtkWiFiStationConnectedHandler, NULL);
     wifi_reg_event_handler(WIFI_EVENT_DISCONNECT, ConnectivityManagerImpl::RtkWiFiStationDisconnectedHandler, NULL);
 
     err = Internal::AmebaUtils::StartWiFi();
@@ -148,14 +148,17 @@
     if (event->Type == DeviceEventType::kRtkWiFiStationConnectedEvent)
     {
         ChipLogProgress(DeviceLayer, "WiFiStationConnected");
+        // Only do DHCP when connecting to wifi via matter provisioning
+        // External wifi provisioning will do DHCP on their own
         if (mWiFiStationState == kWiFiStationState_Connecting)
         {
-            ChangeWiFiStationState(kWiFiStationState_Connecting_Succeeded);
-        }
-        if (rtw_join_status & JOIN_HANDSHAKE_DONE)
-        {
             DHCPProcess();
         }
+        // Allow external wifi provisioning methods by allowing NotConnected states to advance to Connecting_succeed
+        if ((mWiFiStationState == kWiFiStationState_Connecting) || (mWiFiStationState == kWiFiStationState_NotConnected))
+        {
+            ChangeWiFiStationState(kWiFiStationState_Connecting_Succeeded);
+        }
         DriveStationState();
     }
     if (event->Type == DeviceEventType::kRtkWiFiStationDisconnectedEvent)
@@ -166,6 +169,10 @@
         {
             ChangeWiFiStationState(kWiFiStationState_Connecting_Failed);
         }
+        if (mWiFiStationState == kWiFiStationState_Connected)
+        {
+            ChangeWiFiStationState(kWiFiStationState_Disconnecting);
+        }
         DriveStationState();
     }
     if (event->Type == DeviceEventType::kRtkWiFiScanCompletedEvent)
@@ -204,7 +211,8 @@
 
     if (mWiFiStationMode != val)
     {
-        ChipLogProgress(DeviceLayer, "WiFi station mode change: %d -> %d", (mWiFiStationMode), (val));
+        ChipLogProgress(DeviceLayer, "WiFi station mode change: %s -> %s", WiFiStationModeToStr(mWiFiStationMode),
+                        WiFiStationModeToStr(val));
     }
 
     mWiFiStationMode = val;
@@ -221,9 +229,7 @@
 void ConnectivityManagerImpl::_ClearWiFiStationProvision(void)
 {
     // Clear Ameba WiFi station config
-    rtw_wifi_config_t wifiConfig;
-    memset(&wifiConfig, 0, sizeof(wifiConfig));
-    Internal::AmebaUtils::SetWiFiConfig(&wifiConfig);
+    Internal::AmebaUtils::ClearWiFiConfig();
 }
 
 CHIP_ERROR ConnectivityManagerImpl::_SetWiFiAPMode(WiFiAPMode val)
@@ -496,9 +502,9 @@
     // If the station interface is currently connected ...
     if (stationConnected)
     {
-        // Advance the station state to Connected if it was previously NotConnected or
+        // Advance the station state to Connected if
         // a previously initiated connect attempt succeeded.
-        if (mWiFiStationState == kWiFiStationState_NotConnected || mWiFiStationState == kWiFiStationState_Connecting_Succeeded)
+        if (mWiFiStationState == kWiFiStationState_Connecting_Succeeded)
         {
             ChangeWiFiStationState(kWiFiStationState_Connected);
             ChipLogProgress(DeviceLayer, "WiFi station interface connected");
@@ -512,23 +518,23 @@
     {
         System::Clock::Timestamp now = System::SystemClock().GetMonotonicTimestamp();
 
-        // Advance the station state to NotConnected if it was previously Connected or Disconnecting,
+        // Advance the station state to NotConnected if it was previously Disconnecting,
         // or if a previous initiated connect attempt failed.
-        if (mWiFiStationState == kWiFiStationState_Connected || mWiFiStationState == kWiFiStationState_Disconnecting ||
-            mWiFiStationState == kWiFiStationState_Connecting_Failed)
+        if (mWiFiStationState == kWiFiStationState_Disconnecting || mWiFiStationState == kWiFiStationState_Connecting_Failed)
         {
             WiFiStationState prevState = mWiFiStationState;
             ChangeWiFiStationState(kWiFiStationState_NotConnected);
             if (prevState != kWiFiStationState_Connecting_Failed)
             {
-                ChipLogProgress(DeviceLayer, "WiFi station interface disconnected");
-                mLastStationConnectFailTime = System::Clock::kZero;
-                OnStationDisconnected();
+                ChipLogProgress(DeviceLayer, "WiFi station failed to connect");
+                // TODO: check retry count if exceeded, then clearwificonfig
             }
             else
             {
-                mLastStationConnectFailTime = now;
+                ChipLogProgress(DeviceLayer, "WiFi station disconnected");
             }
+            mLastStationConnectFailTime = now;
+            OnStationDisconnected();
         }
         // If the WiFi station interface is now enabled and provisioned (and by implication,
         // not presently under application control), AND the system is not in the process of
@@ -541,14 +547,13 @@
                 now >= mLastStationConnectFailTime + mWiFiStationReconnectInterval)
             {
                 ChipLogProgress(DeviceLayer, "Attempting to connect WiFi station interface");
-                err = Internal::AmebaUtils::WiFiConnect();
+                ChangeWiFiStationState(kWiFiStationState_Connecting);
+                err = Internal::AmebaUtils::WiFiConnectProvisionedNetwork();
                 if (err != CHIP_NO_ERROR)
                 {
-                    ChipLogError(DeviceLayer, "WiFiConnect() failed: %s", chip::ErrorStr(err));
+                    ChipLogError(DeviceLayer, "WiFiConnectProvisionedNetwork() failed: %s", chip::ErrorStr(err));
                 }
                 SuccessOrExit(err);
-
-                ChangeWiFiStationState(kWiFiStationState_Connecting);
             }
 
             // Otherwise arrange another connection attempt at a suitable point in the future.
@@ -644,7 +649,8 @@
 {
     if (mWiFiStationState != newState)
     {
-        ChipLogProgress(DeviceLayer, "WiFi station state change: %d -> %d", (mWiFiStationState), (newState));
+        ChipLogProgress(DeviceLayer, "WiFi station state change: %s -> %s", WiFiStationStateToStr(mWiFiStationState),
+                        WiFiStationStateToStr(newState));
         mWiFiStationState = newState;
         SystemLayer().ScheduleLambda([]() { NetworkCommissioning::AmebaWiFiDriver::GetInstance().OnNetworkStatusChange(); });
     }
diff --git a/src/platform/Ameba/ConnectivityManagerImpl.h b/src/platform/Ameba/ConnectivityManagerImpl.h
index 9863c47..c4c04c5 100644
--- a/src/platform/Ameba/ConnectivityManagerImpl.h
+++ b/src/platform/Ameba/ConnectivityManagerImpl.h
@@ -84,6 +84,9 @@
     // the implementation methods provided by this class.
     friend class ConnectivityManager;
 
+public:
+    void ChangeWiFiStationState(WiFiStationState newState);
+
 private:
     CHIP_ERROR _Init(void);
     void _OnPlatformEvent(const ChipDeviceEvent * event);
@@ -130,7 +133,6 @@
     void DriveStationState(void);
     void OnStationConnected(void);
     void OnStationDisconnected(void);
-    void ChangeWiFiStationState(WiFiStationState newState);
     static void DriveStationState(::chip::System::Layer * aLayer, void * aAppState);
 
     void DriveAPState(void);
diff --git a/src/platform/Ameba/NetworkCommissioningWiFiDriver.cpp b/src/platform/Ameba/NetworkCommissioningWiFiDriver.cpp
index e89bc63..38be3f2 100644
--- a/src/platform/Ameba/NetworkCommissioningWiFiDriver.cpp
+++ b/src/platform/Ameba/NetworkCommissioningWiFiDriver.cpp
@@ -18,6 +18,7 @@
 #include <lib/support/CodeUtils.h>
 #include <lib/support/SafeInt.h>
 #include <platform/Ameba/AmebaUtils.h>
+#include <platform/Ameba/ConnectivityManagerImpl.h>
 #include <platform/Ameba/NetworkCommissioningDriver.h>
 #include <platform/CHIPDeviceLayer.h>
 
@@ -145,25 +146,10 @@
         }
     }
 
-    ReturnErrorOnFailure(ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Disabled));
+    ConnectivityMgrImpl().ChangeWiFiStationState(ConnectivityManager::kWiFiStationState_Connecting);
 
-    rtw_wifi_config_t wifiConfig;
-
-    // Set the wifi configuration
-    memset(&wifiConfig, 0, sizeof(wifiConfig));
-    memcpy(wifiConfig.ssid, ssid, ssidLen + 1);
-    memcpy(wifiConfig.password, key, keyLen + 1);
-
-    // Configure the WiFi interface.
-    err = chip::DeviceLayer::Internal::AmebaUtils::SetWiFiConfig(&wifiConfig);
-    if (err != CHIP_NO_ERROR)
-    {
-        ChipLogError(DeviceLayer, "SetWiFiConfig() failed");
-        return err;
-    }
-
-    ReturnErrorOnFailure(ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Disabled));
-    return ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Enabled);
+    err = chip::DeviceLayer::Internal::AmebaUtils::WiFiConnect(ssid, key);
+    return err;
 }
 
 void AmebaWiFiDriver::OnConnectWiFiNetwork()
@@ -318,7 +304,7 @@
 CHIP_ERROR AmebaWiFiDriver::SetLastDisconnectReason(const ChipDeviceEvent * event)
 {
     VerifyOrReturnError(event->Type == DeviceEventType::kRtkWiFiStationDisconnectedEvent, CHIP_ERROR_INVALID_ARGUMENT);
-    mLastDisconnectedReason = wifi_get_last_error();
+    mLastDisconnectedReason = wifi_get_last_error(); // TODO: change this to wrapper
     return CHIP_NO_ERROR;
 }