[nrfconnect] Bump nRF Connect SDK to 2.2.0 (#24302)

* [nrfconnect] Bump nRF Connect SDK to 2.2.0

Change the recommended nRF Connect SDK version to v2.2.0.

* Start using Zephyr WiFi net_mgmt API and events

- replace wpa_supplicant API calls with generic Zephyr net_mgmt API
- use net events to manage WiFi connection
- refactoring of the whole platform/nrfconnect/wifi code

Signed-off-by: Marcin Kajor <marcin.kajor@nordicsemi.no>

* Implemented proper handling of WiFi security modes.

With the current net_mgmt API it is necessary to scan networks to get
the security mode supported by an AP which we want to connect with.
Also fixed the invalid handling of net_mgmt event life time.

Signed-off-by: Marcin Kajor <marcin.kajor@nordicsemi.no>

* Aligned Matter SDK to Zephyr 0.15.x revision.

These changes were implied the the recent Zephyr upmerge:
- updates of Zephyr include paths
- removal of disabling of gpio1 in board DTS overlays
- fix for the possible dangling pointer compilation error
  after gcc got more picky about that (v10.3 vs. v12.1)

Signed-off-by: Marcin Kajor <marcin.kajor@nordicsemi.no>

* Increased the max number of BLE connections.

This is a workaround for the non-unreferenced BLE connection object
when restarting advertising in BLE disconnect callback.

Signed-off-by: Marcin Kajor <marcin.kajor@nordicsemi.no>

* WiFi fail-safe related fixes

Make sure the fail-safe works as expected with WiFi networking:
- disconnect when reverting the configuration
- always cleanup the provisioning data structures before connecting
  to avoid dummy buffer overwriting and data length issues

Signed-off-by: Marcin Kajor <marcin.kajor@nordicsemi.no>

* Introduced a workaround to send Router Solicitation after connect

Router Solicitation is not sent after connecting to the Wi-Fi
network by the Wi-Fi driver, so in result Thread Border Router
doesn't send Router Advertisement to the device. As a workaround
sending RS was added in the Matter platform code.

* Forward the channel number and RSSI from WIFiManager.

We can now use this feature in spite of stats still
not being implemented.

Signed-off-by: Marcin Kajor <marcin.kajor@nordicsemi.no>

* Minor fixes for heap usage

Fix build with CHIP_MALLOC_SYS_HEAP Kconfig option that
replaces default malloc/free with alternatives based on
Zephyr's sys_heap.

Signed-off-by: Damian Krolik <damian.krolik@nordicsemi.no>

* Wi-Fi status handling fixes.

* Increase the SYSTEM_WORKQUEUE_STACK_SIZE to match supplicant needs
* Decrease the connection timeout to be lower than failsafe (35s)
* Adapt WiFiRequestStatus to follow supplicant implementation
* All of above makes the failsafe more robust

Signed-off-by: Marcin Kajor <marcin.kajor@nordicsemi.no>

* wifi: RevertConfiguration optimization.

Do not disconnect/reconnect to the already attached network.

Signed-off-by: Marcin Kajor <marcin.kajor@nordicsemi.no>

* Define _DEFAULT_SOURCE

This commit updates the chip-module build configurations to define
`_DEFAULT_SOURCE` when compiling Matter because it uses non-standard
functions that are only available when `_DEFAULT_SOURCE` is defined.

Note that this used to be not necessary only because of a quirk in the
way Newlib handles the feature test macro, which resulted in Newlib
defining `_DEFAULT_SOURCE` when compiling with `-std=gnu`.

For more details, refer to the issue zephyrproject-rtos/zephyr#52739.

* Align examples with samples included in nRF Connect SDK 2.2.0

* Update remaining Docker images to 0.6.27

* Restyled by clang-format

* Restyled by shellharden

Signed-off-by: Marcin Kajor <marcin.kajor@nordicsemi.no>
Signed-off-by: Damian Krolik <damian.krolik@nordicsemi.no>
Co-authored-by: Marcin Kajor <marcin.kajor@nordicsemi.no>
Co-authored-by: Kamil Kasperczyk <kamil.kasperczyk@nordicsemi.no>
Co-authored-by: Restyled.io <commits@restyled.io>
Co-authored-by: Andrei Litvin <andy314@gmail.com>
diff --git a/src/include/platform/internal/GenericPlatformManagerImpl_Zephyr.h b/src/include/platform/internal/GenericPlatformManagerImpl_Zephyr.h
index c3f1de4..88d98ec 100644
--- a/src/include/platform/internal/GenericPlatformManagerImpl_Zephyr.h
+++ b/src/include/platform/internal/GenericPlatformManagerImpl_Zephyr.h
@@ -27,7 +27,7 @@
 #include <platform/internal/GenericPlatformManagerImpl.h>
 
 #include <sys/select.h>
-#include <zephyr/zephyr.h>
+#include <zephyr/kernel.h>
 
 namespace chip {
 namespace DeviceLayer {
diff --git a/src/platform/Zephyr/BLEManagerImpl.cpp b/src/platform/Zephyr/BLEManagerImpl.cpp
index 88edbd3..d4639f8 100644
--- a/src/platform/Zephyr/BLEManagerImpl.cpp
+++ b/src/platform/Zephyr/BLEManagerImpl.cpp
@@ -37,11 +37,11 @@
 #include <setup_payload/AdditionalDataPayloadGenerator.h>
 #endif
 
-#include <bluetooth/addr.h>
-#include <bluetooth/gatt.h>
-#include <random/rand32.h>
-#include <sys/byteorder.h>
-#include <sys/util.h>
+#include <zephyr/bluetooth/addr.h>
+#include <zephyr/bluetooth/gatt.h>
+#include <zephyr/random/rand32.h>
+#include <zephyr/sys/byteorder.h>
+#include <zephyr/sys/util.h>
 
 using namespace ::chip;
 using namespace ::chip::Ble;
diff --git a/src/platform/Zephyr/BLEManagerImpl.h b/src/platform/Zephyr/BLEManagerImpl.h
index a99847c..fae4799 100644
--- a/src/platform/Zephyr/BLEManagerImpl.h
+++ b/src/platform/Zephyr/BLEManagerImpl.h
@@ -25,9 +25,9 @@
 
 #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
 
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/conn.h>
-#include <bluetooth/gatt.h>
+#include <zephyr/bluetooth/bluetooth.h>
+#include <zephyr/bluetooth/conn.h>
+#include <zephyr/bluetooth/gatt.h>
 
 #include <lib/support/logging/CHIPLogging.h>
 
diff --git a/src/platform/Zephyr/KeyValueStoreManagerImpl.h b/src/platform/Zephyr/KeyValueStoreManagerImpl.h
index 1d4ee7d..de8707f 100644
--- a/src/platform/Zephyr/KeyValueStoreManagerImpl.h
+++ b/src/platform/Zephyr/KeyValueStoreManagerImpl.h
@@ -24,7 +24,7 @@
 
 #pragma once
 
-#include <zephyr/zephyr.h>
+#include <zephyr/kernel.h>
 
 namespace chip {
 namespace DeviceLayer {
diff --git a/src/platform/Zephyr/NFCManagerImpl.cpp b/src/platform/Zephyr/NFCManagerImpl.cpp
index 53856af..dd28457 100644
--- a/src/platform/Zephyr/NFCManagerImpl.cpp
+++ b/src/platform/Zephyr/NFCManagerImpl.cpp
@@ -26,7 +26,7 @@
 #include <nfc/ndef/uri_msg.h>
 #include <nfc/ndef/uri_rec.h>
 #include <nfc_t2t_lib.h>
-#include <zephyr.h>
+#include <zephyr/kernel.h>
 
 namespace chip {
 namespace DeviceLayer {
diff --git a/src/platform/Zephyr/SysHeapMalloc.cpp b/src/platform/Zephyr/SysHeapMalloc.cpp
index e65ec8a..1a80fad 100644
--- a/src/platform/Zephyr/SysHeapMalloc.cpp
+++ b/src/platform/Zephyr/SysHeapMalloc.cpp
@@ -21,10 +21,10 @@
 #include <system/SystemError.h>
 
 extern "C" {
-#include <init.h>
-#include <sys/math_extras.h>
-#include <sys/mutex.h>
-#include <sys/sys_heap.h>
+#include <zephyr/init.h>
+#include <zephyr/sys/math_extras.h>
+#include <zephyr/sys/mutex.h>
+#include <zephyr/sys/sys_heap.h>
 }
 
 #include <cstdint>
@@ -131,7 +131,7 @@
     LockGuard lockGuard;
     ReturnErrorOnFailure(lockGuard.Error());
 
-    sys_heap_runtime_stats sysHeapStats;
+    sys_memory_stats sysHeapStats;
     ReturnErrorOnFailure(System::MapErrorZephyr(sys_heap_runtime_stats_get(&sHeap, &sysHeapStats)));
 
     stats.free    = sysHeapStats.free_bytes;
diff --git a/src/platform/Zephyr/SystemTimeSupport.cpp b/src/platform/Zephyr/SystemTimeSupport.cpp
index 90b63ad..c9ebdf7 100644
--- a/src/platform/Zephyr/SystemTimeSupport.cpp
+++ b/src/platform/Zephyr/SystemTimeSupport.cpp
@@ -26,7 +26,7 @@
 
 #include <system/SystemError.h>
 
-#include <zephyr/zephyr.h>
+#include <zephyr/kernel.h>
 
 #if !CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS
 
diff --git a/src/platform/Zephyr/ThreadStackManagerImpl.h b/src/platform/Zephyr/ThreadStackManagerImpl.h
index 6600554..d9a9020 100644
--- a/src/platform/Zephyr/ThreadStackManagerImpl.h
+++ b/src/platform/Zephyr/ThreadStackManagerImpl.h
@@ -25,8 +25,8 @@
 
 #include <platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h>
 
+#include <zephyr/kernel.h>
 #include <zephyr/net/openthread.h>
-#include <zephyr/zephyr.h>
 
 #include <openthread/thread.h>
 #if !CONFIG_SOC_SERIES_RISCV_TELINK_B91
diff --git a/src/platform/nrfconnect/DiagnosticDataProviderImplNrf.cpp b/src/platform/nrfconnect/DiagnosticDataProviderImplNrf.cpp
index 5f7bc1a..e7326ed 100644
--- a/src/platform/nrfconnect/DiagnosticDataProviderImplNrf.cpp
+++ b/src/platform/nrfconnect/DiagnosticDataProviderImplNrf.cpp
@@ -71,9 +71,7 @@
     WiFiManager::WiFiInfo info;
     CHIP_ERROR err = WiFiManager::Instance().GetWiFiInfo(info);
     channelNumber  = info.mChannel;
-    (void) err;
-    // above will return 0 until the wpa_supplicant driver API implementation is refined
-    return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
+    return err;
 }
 
 CHIP_ERROR DiagnosticDataProviderImplNrf::GetWiFiRssi(int8_t & rssi)
@@ -81,9 +79,7 @@
     WiFiManager::WiFiInfo info;
     CHIP_ERROR err = WiFiManager::Instance().GetWiFiInfo(info);
     rssi           = info.mRssi;
-    (void) err;
-    // above will return -128 until the wpa_supplicant driver API implementation is refined
-    return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
+    return err;
 }
 
 // below will be implemented when the WiFi driver exposes Zephyr NET_STATISTICS API
diff --git a/src/platform/nrfconnect/FactoryDataParser.c b/src/platform/nrfconnect/FactoryDataParser.c
index 1960188..85caee5 100644
--- a/src/platform/nrfconnect/FactoryDataParser.c
+++ b/src/platform/nrfconnect/FactoryDataParser.c
@@ -17,8 +17,8 @@
 
 #include "FactoryDataParser.h"
 
-#include <logging/log.h>
 #include <zcbor_decode.h>
+#include <zephyr/logging/log.h>
 
 #include <ctype.h>
 #include <string.h>
diff --git a/src/platform/nrfconnect/FactoryDataProvider.cpp b/src/platform/nrfconnect/FactoryDataProvider.cpp
index cd52046..200b8fa 100644
--- a/src/platform/nrfconnect/FactoryDataProvider.cpp
+++ b/src/platform/nrfconnect/FactoryDataProvider.cpp
@@ -24,7 +24,7 @@
 #include <platform/Zephyr/ZephyrConfig.h>
 #endif
 
-#include <logging/log.h>
+#include <zephyr/logging/log.h>
 
 namespace chip {
 namespace {
diff --git a/src/platform/nrfconnect/FactoryDataProvider.h b/src/platform/nrfconnect/FactoryDataProvider.h
index 3d46076..c551791 100644
--- a/src/platform/nrfconnect/FactoryDataProvider.h
+++ b/src/platform/nrfconnect/FactoryDataProvider.h
@@ -21,10 +21,10 @@
 #include <platform/CommissionableDataProvider.h>
 #include <platform/DeviceInstanceInfoProvider.h>
 
-#include <drivers/flash.h>
 #include <fprotect.h>
 #include <pm_config.h>
 #include <system/SystemError.h>
+#include <zephyr/drivers/flash.h>
 
 #include "FactoryDataParser.h"
 
diff --git a/src/platform/nrfconnect/OTAImageProcessorImpl.cpp b/src/platform/nrfconnect/OTAImageProcessorImpl.cpp
index 0daf01c..7448ffe 100644
--- a/src/platform/nrfconnect/OTAImageProcessorImpl.cpp
+++ b/src/platform/nrfconnect/OTAImageProcessorImpl.cpp
@@ -28,15 +28,15 @@
 #if CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE
 #include <credentials/CertificationDeclaration.h>
 #include <platform/Zephyr/ZephyrConfig.h>
-#include <settings/settings.h>
+#include <zephyr/settings/settings.h>
 #endif
 
 #include <dfu/dfu_multi_image.h>
 #include <dfu/dfu_target.h>
 #include <dfu/dfu_target_mcuboot.h>
-#include <dfu/mcuboot.h>
-#include <logging/log.h>
-#include <pm/device.h>
+#include <zephyr/dfu/mcuboot.h>
+#include <zephyr/logging/log.h>
+#include <zephyr/pm/device.h>
 
 #if CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE
 // Cd globals are needed to be accessed from dfu image writer lambdas
diff --git a/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.cpp b/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.cpp
index 73e1630..b3bdede 100644
--- a/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.cpp
+++ b/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.cpp
@@ -52,27 +52,9 @@
 
 CHIP_ERROR ConnectivityManagerImplWiFi::_SetWiFiStationMode(ConnectivityManager::WiFiStationMode aMode)
 {
-    VerifyOrReturnError(ConnectivityManager::WiFiStationMode::kWiFiStationMode_NotSupported != aMode,
-                        CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE);
+    VerifyOrReturnError(ConnectivityManager::WiFiStationMode::kWiFiStationMode_NotSupported != aMode, CHIP_ERROR_INVALID_ARGUMENT);
 
-    if (aMode != mStationMode)
-    {
-        mStationMode = aMode;
-        if (mStationMode != ConnectivityManager::WiFiStationMode::kWiFiStationMode_ApplicationControlled)
-        {
-            bool doEnable{ ConnectivityManager::WiFiStationMode::kWiFiStationMode_Enabled == mStationMode };
-            // TODO: when the connection/disconnection callback API is provided
-            // below calls should be used as a base of disconnect callback
-            if (doEnable)
-            {
-                OnStationConnected();
-            }
-            else
-            {
-                OnStationDisconnected();
-            }
-        }
-    }
+    mStationMode = aMode;
 
     return CHIP_NO_ERROR;
 }
@@ -89,7 +71,7 @@
 
 bool ConnectivityManagerImplWiFi::_IsWiFiStationConnected(void)
 {
-    return (WiFiManager::StationStatus::FULLY_PROVISIONED == WiFiManager().Instance().GetStationStatus());
+    return (WiFiManager::StationStatus::CONNECTED == WiFiManager().Instance().GetStationStatus());
 }
 
 System::Clock::Timeout ConnectivityManagerImplWiFi::_GetWiFiStationReconnectInterval(void)
@@ -141,38 +123,6 @@
     return CHIP_NO_ERROR;
 }
 
-void ConnectivityManagerImplWiFi::OnStationConnected()
-{
-    // ensure the station is connected
-    if (_IsWiFiStationConnected())
-    {
-        ChipDeviceEvent connectEvent{};
-        connectEvent.Type                          = DeviceEventType::kWiFiConnectivityChange;
-        connectEvent.WiFiConnectivityChange.Result = kConnectivity_Established;
-        PlatformMgr().PostEventOrDie(&connectEvent);
-    }
-    else
-    {
-        ChipLogError(DeviceLayer, "WiFi Station is not connected!");
-    }
-}
-
-void ConnectivityManagerImplWiFi::OnStationDisconnected()
-{
-    // ensure the station is disconnected
-    if (WiFiManager::StationStatus::DISCONNECTED == WiFiManager().Instance().GetStationStatus())
-    {
-        ChipDeviceEvent disconnectEvent{};
-        disconnectEvent.Type                          = DeviceEventType::kWiFiConnectivityChange;
-        disconnectEvent.WiFiConnectivityChange.Result = kConnectivity_Lost;
-        PlatformMgr().PostEventOrDie(&disconnectEvent);
-    }
-    else
-    {
-        ChipLogError(DeviceLayer, "WiFi Station is not disconnected!");
-    }
-}
-
 ConnectivityManager::WiFiAPMode ConnectivityManagerImplWiFi::_GetWiFiAPMode(void)
 {
     /* AP mode is unsupported */
diff --git a/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.h b/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.h
index 8198453..dfa6a05 100644
--- a/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.h
+++ b/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.h
@@ -54,8 +54,6 @@
     bool _CanStartWiFiScan();
     void _OnWiFiScanDone();
     void _OnWiFiStationProvisionChange();
-    void OnStationConnected();
-    void OnStationDisconnected();
 
     // Wi-Fi access point - not supported
     ConnectivityManager::WiFiAPMode _GetWiFiAPMode(void);
diff --git a/src/platform/nrfconnect/wifi/NrfWiFiDriver.cpp b/src/platform/nrfconnect/wifi/NrfWiFiDriver.cpp
index 5092384..e8e5d10 100644
--- a/src/platform/nrfconnect/wifi/NrfWiFiDriver.cpp
+++ b/src/platform/nrfconnect/wifi/NrfWiFiDriver.cpp
@@ -17,7 +17,6 @@
 
 #include "NrfWiFiDriver.h"
 
-#include "WiFiManager.h"
 #include <platform/KeyValueStoreManager.h>
 
 #include <lib/support/CodeUtils.h>
@@ -27,6 +26,7 @@
 using namespace ::chip;
 using namespace ::chip::DeviceLayer::Internal;
 using namespace ::chip::DeviceLayer::PersistedStorage;
+using namespace ::chip::app::Clusters::NetworkCommissioning;
 
 namespace chip {
 namespace DeviceLayer {
@@ -105,7 +105,7 @@
     {
         WiFiManager::ConnectionHandling handling{ [] { Instance().OnNetworkStatusChanged(Status::kSuccess); },
                                                   [] { Instance().OnNetworkStatusChanged(Status::kUnknownError); },
-                                                  System::Clock::Timeout{ 40000 } };
+                                                  System::Clock::Seconds32{ kWiFiConnectNetworkTimeoutSeconds } };
         ReturnErrorOnFailure(
             WiFiManager::Instance().Connect(mStagingNetwork.GetSsidSpan(), mStagingNetwork.GetPassSpan(), handling));
     }
@@ -121,7 +121,15 @@
     }
 
     if (mpNetworkStatusChangeCallback)
+    {
         mpNetworkStatusChangeCallback->OnNetworkingStatusChange(status, NullOptional, NullOptional);
+    }
+
+    if (mpConnectCallback)
+    {
+        mpConnectCallback->OnResult(status, CharSpan(), 0);
+        mpConnectCallback = nullptr;
+    }
 }
 
 void NrfWiFiDriver::Shutdown()
@@ -141,11 +149,24 @@
 {
     LoadFromStorage();
 
+    if (WiFiManager::StationStatus::CONNECTING <= WiFiManager::Instance().GetStationStatus())
+    {
+        WiFiManager::WiFiInfo wifiInfo;
+        ReturnErrorOnFailure(WiFiManager::Instance().GetWiFiInfo(wifiInfo));
+        if (mStagingNetwork.GetSsidSpan().data_equal(ByteSpan(wifiInfo.mSsid, wifiInfo.mSsidLen)))
+        {
+            // we are already connected to this network, so return prematurely
+            return CHIP_NO_ERROR;
+        }
+
+        WiFiManager::Instance().Disconnect();
+    }
+
     if (mStagingNetwork.IsConfigured())
     {
-        WiFiManager::ConnectionHandling handling{ [] { Instance().OnConnectWiFiNetwork(); },
-                                                  [] { Instance().OnConnectWiFiNetworkFailed(); },
-                                                  System::Clock::Timeout{ 40000 } };
+        WiFiManager::ConnectionHandling handling{ [] { Instance().OnNetworkStatusChanged(Status::kSuccess); },
+                                                  [] { Instance().OnNetworkStatusChanged(Status::kUnknownError); },
+                                                  System::Clock::Seconds32{ kWiFiConnectNetworkTimeoutSeconds } };
         ReturnErrorOnFailure(
             WiFiManager::Instance().Connect(mStagingNetwork.GetSsidSpan(), mStagingNetwork.GetPassSpan(), handling));
     }
@@ -163,6 +184,7 @@
     VerifyOrReturnError(ssid.size() <= sizeof(mStagingNetwork.ssid), Status::kOutOfRange);
     VerifyOrReturnError(credentials.size() <= sizeof(mStagingNetwork.pass), Status::kOutOfRange);
 
+    mStagingNetwork.Erase();
     memcpy(mStagingNetwork.ssid, ssid.data(), ssid.size());
     memcpy(mStagingNetwork.pass, credentials.data(), credentials.size());
     mStagingNetwork.ssidLen = ssid.size();
@@ -196,9 +218,12 @@
 void NrfWiFiDriver::ConnectNetwork(ByteSpan networkId, ConnectCallback * callback)
 {
     Status status = Status::kSuccess;
-    WiFiManager::ConnectionHandling handling{ [] { Instance().OnConnectWiFiNetwork(); },
-                                              [] { Instance().OnConnectWiFiNetworkFailed(); }, System::Clock::Timeout{ 40000 } };
+    WiFiManager::ConnectionHandling handling{ [] { Instance().OnNetworkStatusChanged(Status::kSuccess); },
+                                              [] { Instance().OnNetworkStatusChanged(Status::kUnknownError); },
+                                              System::Clock::Seconds32{ kWiFiConnectNetworkTimeoutSeconds } };
 
+    VerifyOrExit(WiFiManager::StationStatus::CONNECTING != WiFiManager::Instance().GetStationStatus(),
+                 status = Status::kOtherConnectionFailure);
     VerifyOrExit(networkId.data_equal(mStagingNetwork.GetSsidSpan()), status = Status::kNetworkIDNotFound);
     VerifyOrExit(mpConnectCallback == nullptr, status = Status::kUnknownError);
 
@@ -206,43 +231,42 @@
     WiFiManager::Instance().Connect(mStagingNetwork.GetSsidSpan(), mStagingNetwork.GetPassSpan(), handling);
 
 exit:
-    if (status != Status::kSuccess)
+    if (status != Status::kSuccess && mpConnectCallback)
     {
-        mpConnectCallback = nullptr;
-        callback->OnResult(status, CharSpan(), 0);
-    }
-}
-
-CHIP_ERROR GetConfiguredNetwork(Network & network)
-{
-    return CHIP_NO_ERROR;
-}
-
-void NrfWiFiDriver::OnConnectWiFiNetwork()
-{
-    ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Enabled);
-
-    if (mpConnectCallback)
-    {
-        mpConnectCallback->OnResult(Status::kSuccess, CharSpan(), 0);
+        mpConnectCallback->OnResult(status, CharSpan(), 0);
         mpConnectCallback = nullptr;
     }
 }
 
-void NrfWiFiDriver::OnConnectWiFiNetworkFailed()
+void NrfWiFiDriver::LoadFromStorage()
 {
-    if (mpConnectCallback)
-    {
-        mpConnectCallback->OnResult(Status::kNetworkNotFound, CharSpan(), 0);
-        mpConnectCallback = nullptr;
-    }
+    WiFiManager::WiFiNetwork network;
+
+    mStagingNetwork = {};
+    ReturnOnFailure(KeyValueStoreMgr().Get(kSsidKey, network.ssid, sizeof(network.ssid), &network.ssidLen));
+    ReturnOnFailure(KeyValueStoreMgr().Get(kPassKey, network.pass, sizeof(network.pass), &network.passLen));
+    mStagingNetwork = network;
+}
+
+void NrfWiFiDriver::OnScanWiFiNetworkDone(WiFiManager::WiFiRequestStatus status)
+{
+    VerifyOrReturn(mScanCallback != nullptr);
+    mScanCallback->OnFinished(status == WiFiManager::WiFiRequestStatus::SUCCESS ? Status::kSuccess : Status::kUnknownError,
+                              CharSpan(), &mScanResponseIterator);
+    mScanCallback = nullptr;
+}
+
+void NrfWiFiDriver::OnScanWiFiNetworkResult(const WiFiScanResponse & response)
+{
+    mScanResponseIterator.Add(response);
 }
 
 void NrfWiFiDriver::ScanNetworks(ByteSpan ssid, WiFiDriver::ScanCallback * callback)
 {
     mScanCallback    = callback;
     CHIP_ERROR error = WiFiManager::Instance().Scan(
-        ssid, [](int status, WiFiScanResponse * response) { Instance().OnScanWiFiNetworkDone(status, response); });
+        ssid, [](const WiFiScanResponse & response) { Instance().OnScanWiFiNetworkResult(response); },
+        [](WiFiManager::WiFiRequestStatus status) { Instance().OnScanWiFiNetworkDone(status); });
 
     if (error != CHIP_NO_ERROR)
     {
@@ -251,34 +275,6 @@
     }
 }
 
-void NrfWiFiDriver::OnScanWiFiNetworkDone(int status, WiFiScanResponse * response)
-{
-    if (response != nullptr)
-    {
-        StackLock lock;
-        VerifyOrReturn(mScanCallback != nullptr);
-        mScanResponseIterator.Add(*response);
-        return;
-    }
-
-    // Scan complete
-    DeviceLayer::SystemLayer().ScheduleLambda([this, status]() {
-        VerifyOrReturn(mScanCallback != nullptr);
-        mScanCallback->OnFinished(status == 0 ? Status::kSuccess : Status::kUnknownError, CharSpan(), &mScanResponseIterator);
-        mScanCallback = nullptr;
-    });
-}
-
-void NrfWiFiDriver::LoadFromStorage()
-{
-    WiFiNetwork network;
-
-    mStagingNetwork = {};
-    ReturnOnFailure(KeyValueStoreMgr().Get(kSsidKey, network.ssid, sizeof(network.ssid), &network.ssidLen));
-    ReturnOnFailure(KeyValueStoreMgr().Get(kPassKey, network.pass, sizeof(network.pass), &network.passLen));
-    mStagingNetwork = network;
-}
-
 } // namespace NetworkCommissioning
 } // namespace DeviceLayer
 } // namespace chip
diff --git a/src/platform/nrfconnect/wifi/NrfWiFiDriver.h b/src/platform/nrfconnect/wifi/NrfWiFiDriver.h
index 880cce8..7b57607 100644
--- a/src/platform/nrfconnect/wifi/NrfWiFiDriver.h
+++ b/src/platform/nrfconnect/wifi/NrfWiFiDriver.h
@@ -16,6 +16,9 @@
  */
 
 #pragma once
+
+#include "WiFiManager.h"
+
 #include <platform/NetworkCommissioning.h>
 
 namespace chip {
@@ -24,7 +27,7 @@
 
 constexpr uint8_t kMaxWiFiNetworks                  = 1;
 constexpr uint8_t kWiFiScanNetworksTimeOutSeconds   = 10;
-constexpr uint8_t kWiFiConnectNetworkTimeoutSeconds = 120;
+constexpr uint8_t kWiFiConnectNetworkTimeoutSeconds = 35;
 
 class NrfWiFiScanResponseIterator : public Iterator<WiFiScanResponse>
 {
@@ -62,19 +65,6 @@
         bool mExhausted{ false };
     };
 
-    struct WiFiNetwork
-    {
-        uint8_t ssid[DeviceLayer::Internal::kMaxWiFiSSIDLength];
-        size_t ssidLen = 0;
-        uint8_t pass[DeviceLayer::Internal::kMaxWiFiKeyLength];
-        size_t passLen = 0;
-
-        bool IsConfigured() const { return ssidLen > 0; }
-        ByteSpan GetSsidSpan() const { return ByteSpan(ssid, ssidLen); }
-        ByteSpan GetPassSpan() const { return ByteSpan(pass, passLen); }
-        void Clear() { ssidLen = 0; }
-    };
-
     // BaseDriver
     NetworkIterator * GetNetworks() override { return new WiFiNetworkIterator(this); }
     CHIP_ERROR Init(NetworkStatusChangeCallback * networkStatusChangeCallback) override;
@@ -103,17 +93,16 @@
         return sInstance;
     }
 
-    void OnConnectWiFiNetwork();
-    void OnConnectWiFiNetworkFailed();
     void OnNetworkStatusChanged(Status status);
-    void OnScanWiFiNetworkDone(int status, WiFiScanResponse * result);
+    void OnScanWiFiNetworkResult(const WiFiScanResponse & result);
+    void OnScanWiFiNetworkDone(WiFiManager::WiFiRequestStatus status);
 
 private:
     void LoadFromStorage();
 
     ConnectCallback * mpConnectCallback{ nullptr };
     NetworkStatusChangeCallback * mpNetworkStatusChangeCallback{ nullptr };
-    WiFiNetwork mStagingNetwork;
+    WiFiManager::WiFiNetwork mStagingNetwork;
     NrfWiFiScanResponseIterator mScanResponseIterator;
     ScanCallback * mScanCallback{ nullptr };
 };
diff --git a/src/platform/nrfconnect/wifi/WiFiManager.cpp b/src/platform/nrfconnect/wifi/WiFiManager.cpp
index 7c2313f..a47655c 100644
--- a/src/platform/nrfconnect/wifi/WiFiManager.cpp
+++ b/src/platform/nrfconnect/wifi/WiFiManager.cpp
@@ -22,33 +22,35 @@
 
 #include "WiFiManager.h"
 
+#include <crypto/RandUtils.h>
 #include <inet/InetInterface.h>
 #include <inet/UDPEndPointImplSockets.h>
 #include <lib/support/logging/CHIPLogging.h>
 #include <platform/CHIPDeviceLayer.h>
 #include <platform/Zephyr/InetUtils.h>
 
-#include <net/net_stats.h>
-#include <zephyr.h>
+#include <zephyr/kernel.h>
+#include <zephyr/net/net_event.h>
+#include <zephyr/net/net_if.h>
+#include <zephyr/net/net_stats.h>
 
 extern "C" {
 #include <common/defs.h>
 #include <wpa_supplicant/config.h>
 #include <wpa_supplicant/driver_i.h>
 #include <wpa_supplicant/scan.h>
-#include <zephyr/net/wifi_mgmt.h>
+
+// extern function to obtain bssid from status buffer
+// It is defined in zephyr/subsys/net/ip/utils.c
+extern char * net_sprint_ll_addr_buf(const uint8_t * ll, uint8_t ll_len, char * buf, int buflen);
 }
 
-extern struct wpa_global * global;
-
-static struct wpa_supplicant * wpa_s;
-
 namespace chip {
 namespace DeviceLayer {
 
 namespace {
 
-NetworkCommissioning::WiFiScanResponse ToScanResponse(wifi_scan_result * result)
+NetworkCommissioning::WiFiScanResponse ToScanResponse(const wifi_scan_result * result)
 {
     NetworkCommissioning::WiFiScanResponse response = {};
 
@@ -73,49 +75,50 @@
 
 } // namespace
 
-// These enums shall reflect the overall ordered disconnected->connected flow
-const Map<wpa_states, WiFiManager::StationStatus, 10>
-    WiFiManager::sStatusMap({ { WPA_DISCONNECTED, WiFiManager::StationStatus::DISCONNECTED },
-                              { WPA_INTERFACE_DISABLED, WiFiManager::StationStatus::DISABLED },
-                              { WPA_INACTIVE, WiFiManager::StationStatus::DISABLED },
-                              { WPA_SCANNING, WiFiManager::StationStatus::SCANNING },
-                              { WPA_AUTHENTICATING, WiFiManager::StationStatus::CONNECTING },
-                              { WPA_ASSOCIATING, WiFiManager::StationStatus::CONNECTING },
-                              { WPA_ASSOCIATED, WiFiManager::StationStatus::CONNECTED },
-                              { WPA_4WAY_HANDSHAKE, WiFiManager::StationStatus::PROVISIONING },
-                              { WPA_GROUP_HANDSHAKE, WiFiManager::StationStatus::PROVISIONING },
-                              { WPA_COMPLETED, WiFiManager::StationStatus::FULLY_PROVISIONED } });
+const Map<wifi_iface_state, WiFiManager::StationStatus, 10>
+    WiFiManager::sStatusMap({ { WIFI_STATE_DISCONNECTED, WiFiManager::StationStatus::DISCONNECTED },
+                              { WIFI_STATE_INTERFACE_DISABLED, WiFiManager::StationStatus::DISABLED },
+                              { WIFI_STATE_INACTIVE, WiFiManager::StationStatus::DISABLED },
+                              { WIFI_STATE_SCANNING, WiFiManager::StationStatus::SCANNING },
+                              { WIFI_STATE_AUTHENTICATING, WiFiManager::StationStatus::CONNECTING },
+                              { WIFI_STATE_ASSOCIATING, WiFiManager::StationStatus::CONNECTING },
+                              { WIFI_STATE_ASSOCIATED, WiFiManager::StationStatus::CONNECTED },
+                              { WIFI_STATE_4WAY_HANDSHAKE, WiFiManager::StationStatus::PROVISIONING },
+                              { WIFI_STATE_GROUP_HANDSHAKE, WiFiManager::StationStatus::PROVISIONING },
+                              { WIFI_STATE_COMPLETED, WiFiManager::StationStatus::FULLY_PROVISIONED } });
 
-// Map WiFi center frequency to the corresponding channel number
-const Map<uint16_t, uint8_t, 42> WiFiManager::sFreqChannelMap(
-    { { 4915, 183 }, { 4920, 184 }, { 4925, 185 }, { 4935, 187 }, { 4940, 188 }, { 4945, 189 }, { 4960, 192 },
-      { 4980, 196 }, { 5035, 7 },   { 5040, 8 },   { 5045, 9 },   { 5055, 11 },  { 5060, 12 },  { 5080, 16 },
-      { 5170, 34 },  { 5180, 36 },  { 5190, 38 },  { 5200, 40 },  { 5210, 42 },  { 5220, 44 },  { 5230, 46 },
-      { 5240, 48 },  { 5260, 52 },  { 5280, 56 },  { 5300, 60 },  { 5320, 64 },  { 5500, 100 }, { 5520, 104 },
-      { 5540, 108 }, { 5560, 112 }, { 5580, 116 }, { 5600, 120 }, { 5620, 124 }, { 5640, 128 }, { 5660, 132 },
-      { 5680, 136 }, { 5700, 140 }, { 5745, 149 }, { 5765, 153 }, { 5785, 157 }, { 5805, 161 }, { 5825, 165 } });
+const Map<uint32_t, WiFiManager::NetEventHandler, 4>
+    WiFiManager::sEventHandlerMap({ { NET_EVENT_WIFI_SCAN_RESULT, WiFiManager::ScanResultHandler },
+                                    { NET_EVENT_WIFI_SCAN_DONE, WiFiManager::ScanDoneHandler },
+                                    { NET_EVENT_WIFI_CONNECT_RESULT, WiFiManager::ConnectHandler },
+                                    { NET_EVENT_WIFI_DISCONNECT_RESULT, WiFiManager::DisconnectHandler } });
+
+void WiFiManager::WifiMgmtEventHandler(net_mgmt_event_callback * cb, uint32_t mgmtEvent, net_if * iface)
+{
+    if (0 == strcmp(iface->if_dev->dev->name, "wlan0"))
+    {
+        Platform::UniquePtr<uint8_t> eventData(new uint8_t[cb->info_length]);
+        VerifyOrReturn(eventData);
+        memcpy(eventData.get(), cb->info, cb->info_length);
+        CHIP_ERROR status = SystemLayer().ScheduleLambda([data = eventData.get(), mgmtEvent]() {
+            if (data)
+            {
+                sEventHandlerMap[mgmtEvent](data);
+                // cleanup
+                delete[] data;
+            }
+        });
+
+        if (CHIP_NO_ERROR == status)
+        {
+            // the ownership has been transferred to the worker thread - release the buffer
+            eventData.release();
+        }
+    }
+}
 
 CHIP_ERROR WiFiManager::Init()
 {
-    // wpa_supplicant instance is initialized in dedicated supplicant thread, so wait until
-    // the initialization is completed.
-    // TODO: fix thread-safety of the solution.
-    constexpr size_t kInitTimeoutMs = 5000;
-    const int64_t initStartTime     = k_uptime_get();
-    // TODO: Handle multiple VIFs
-    const char * ifname = "wlan0";
-
-    while (!global || !(wpa_s = wpa_supplicant_get_iface(global, ifname)))
-    {
-        if (k_uptime_get() > initStartTime + kInitTimeoutMs)
-        {
-            ChipLogError(DeviceLayer, "wpa_supplicant is not initialized!");
-            return CHIP_ERROR_INTERNAL;
-        }
-
-        k_msleep(200);
-    }
-
     // TODO: consider moving these to ConnectivityManagerImpl to be prepared for handling multiple interfaces on a single device.
     Inet::UDPEndPointImplSockets::SetJoinMulticastGroupHandler([](Inet::InterfaceId interfaceId, const Inet::IPAddress & address) {
         const in6_addr addr = InetUtils::ToZephyrAddr(address);
@@ -145,234 +148,114 @@
         return CHIP_NO_ERROR;
     });
 
-    ChipLogDetail(DeviceLayer, "wpa_supplicant has been initialized");
+    net_mgmt_init_event_callback(&mWiFiMgmtClbk, WifiMgmtEventHandler, kWifiManagementEvents);
+    net_mgmt_add_event_callback(&mWiFiMgmtClbk);
+
+    ChipLogDetail(DeviceLayer, "WiFiManager has been initialized");
 
     return CHIP_NO_ERROR;
 }
-
-CHIP_ERROR WiFiManager::AddNetwork(const ByteSpan & ssid, const ByteSpan & credentials)
+CHIP_ERROR WiFiManager::Scan(const ByteSpan & ssid, ScanResultCallback resultCallback, ScanDoneCallback doneCallback,
+                             bool internalScan)
 {
-    ChipLogDetail(DeviceLayer, "Adding WiFi network");
-    mpWpaNetwork = wpa_supplicant_add_network(wpa_s);
-    if (mpWpaNetwork)
+    net_if * iface = InetUtils::GetInterface();
+    VerifyOrReturnError(nullptr != iface, CHIP_ERROR_INTERNAL);
+
+    mInternalScan       = internalScan;
+    mScanResultCallback = resultCallback;
+    mScanDoneCallback   = doneCallback;
+    mWiFiState          = WIFI_STATE_SCANNING;
+
+    if (net_mgmt(NET_REQUEST_WIFI_SCAN, iface, NULL, 0))
     {
-        static constexpr size_t kMaxSsidLen{ 32 };
-        mpWpaNetwork->ssid = (u8 *) k_malloc(kMaxSsidLen);
-
-        if (mpWpaNetwork->ssid)
-        {
-            memcpy(mpWpaNetwork->ssid, ssid.data(), ssid.size());
-            mpWpaNetwork->ssid_len    = ssid.size();
-            mpWpaNetwork->key_mgmt    = WPA_KEY_MGMT_NONE;
-            mpWpaNetwork->disabled    = 1;
-            wpa_s->conf->filter_ssids = 1;
-
-            return AddPsk(credentials);
-        }
+        ChipLogError(DeviceLayer, "Scan request failed");
+        return CHIP_ERROR_INTERNAL;
     }
 
-    return CHIP_ERROR_INTERNAL;
-}
-
-CHIP_ERROR WiFiManager::Scan(const ByteSpan & ssid, ScanCallback callback)
-{
-    const StationStatus stationStatus = GetStationStatus();
-    VerifyOrReturnError(stationStatus != StationStatus::DISABLED && stationStatus != StationStatus::SCANNING &&
-                            stationStatus != StationStatus::CONNECTING,
-                        CHIP_ERROR_INCORRECT_STATE);
-
-    net_if * const iface = InetUtils::GetInterface();
-    VerifyOrReturnError(iface != nullptr, CHIP_ERROR_INTERNAL);
-
-    const device * dev = net_if_get_device(iface);
-    VerifyOrReturnError(dev != nullptr, CHIP_ERROR_INTERNAL);
-
-    const net_wifi_mgmt_offload * ops = static_cast<const net_wifi_mgmt_offload *>(dev->api);
-    VerifyOrReturnError(ops != nullptr, CHIP_ERROR_INTERNAL);
-
-    mScanCallback = callback;
-
-    // TODO: Use saner API once such exists.
-    // TODO: Take 'ssid' into account.
-    VerifyOrReturnError(ops->scan(dev,
-                                  [](net_if *, int status, wifi_scan_result * result) {
-                                      VerifyOrReturn(Instance().mScanCallback != nullptr);
-                                      NetworkCommissioning::WiFiScanResponse response = ToScanResponse(result);
-                                      Instance().mScanCallback(status, result != nullptr ? &response : nullptr);
-                                  }) == 0,
-                        CHIP_ERROR_INTERNAL);
-
-    return CHIP_NO_ERROR;
-}
-
-CHIP_ERROR WiFiManager::Connect(const ByteSpan & ssid, const ByteSpan & credentials, const ConnectionHandling & handling)
-{
-    ChipLogDetail(DeviceLayer, "Connecting to WiFi network");
-
-    mConnectionSuccessClbk = handling.mOnConnectionSuccess;
-    mConnectionFailedClbk  = handling.mOnConnectionFailed;
-    mConnectionTimeoutMs   = handling.mConnectionTimeoutMs;
-
-    CHIP_ERROR err = AddNetwork(ssid, credentials);
-    if (CHIP_NO_ERROR == err)
-    {
-        EnableStation(true);
-        wpa_supplicant_select_network(wpa_s, mpWpaNetwork);
-        WaitForConnectionAsync();
-    }
-    else
-    {
-        OnConnectionFailed();
-    }
-    return err;
-}
-
-void WiFiManager::OnConnectionSuccess()
-{
-    if (mConnectionSuccessClbk)
-        mConnectionSuccessClbk();
-}
-
-void WiFiManager::OnConnectionFailed()
-{
-    if (mConnectionFailedClbk)
-        mConnectionFailedClbk();
-}
-
-CHIP_ERROR WiFiManager::AddPsk(const ByteSpan & credentials)
-{
-    mpWpaNetwork->key_mgmt = WPA_KEY_MGMT_PSK;
-    str_clear_free(mpWpaNetwork->passphrase);
-    mpWpaNetwork->passphrase = dup_binstr(credentials.data(), credentials.size());
-
-    if (mpWpaNetwork->passphrase)
-    {
-        wpa_config_update_psk(mpWpaNetwork);
-        return CHIP_NO_ERROR;
-    }
-
-    return CHIP_ERROR_INTERNAL;
-}
-
-WiFiManager::StationStatus WiFiManager::GetStationStatus() const
-{
-    if (wpa_s)
-    {
-        return StatusFromWpaStatus(wpa_s->wpa_state);
-    }
-    else
-    {
-        ChipLogError(DeviceLayer, "wpa_supplicant is not initialized!");
-        return StationStatus::NONE;
-    }
-}
-
-WiFiManager::StationStatus WiFiManager::StatusFromWpaStatus(const wpa_states & status)
-{
-    ChipLogDetail(DeviceLayer, "WPA internal status: %d", static_cast<int>(status));
-    return WiFiManager::sStatusMap[status];
-}
-
-CHIP_ERROR WiFiManager::EnableStation(bool enable)
-{
-    VerifyOrReturnError(nullptr != wpa_s && nullptr != mpWpaNetwork, CHIP_ERROR_INTERNAL);
-    if (enable)
-    {
-        wpa_supplicant_enable_network(wpa_s, mpWpaNetwork);
-    }
-    else
-    {
-        wpa_supplicant_disable_network(wpa_s, mpWpaNetwork);
-    }
+    ChipLogDetail(DeviceLayer, "WiFi scanning started...");
 
     return CHIP_NO_ERROR;
 }
 
 CHIP_ERROR WiFiManager::ClearStationProvisioningData()
 {
-    VerifyOrReturnError(nullptr != wpa_s && nullptr != mpWpaNetwork, CHIP_ERROR_INTERNAL);
-    wpa_supplicant_cancel_scan(wpa_s);
-    wpa_clear_keys(wpa_s, mpWpaNetwork->bssid);
-    str_clear_free(mpWpaNetwork->passphrase);
-    wpa_config_update_psk(mpWpaNetwork);
-    wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
-
+    mWiFiParams.mRssi = std::numeric_limits<int8_t>::min();
+    memset(&mWiFiParams.mParams, 0, sizeof(mWiFiParams.mParams));
     return CHIP_NO_ERROR;
 }
 
-CHIP_ERROR WiFiManager::DisconnectStation()
+CHIP_ERROR WiFiManager::Connect(const ByteSpan & ssid, const ByteSpan & credentials, const ConnectionHandling & handling)
 {
-    VerifyOrReturnError(nullptr != wpa_s, CHIP_ERROR_INTERNAL);
-    wpa_supplicant_cancel_scan(wpa_s);
-    wpas_request_disconnection(wpa_s);
+    ChipLogDetail(DeviceLayer, "Connecting to WiFi network: %*s", ssid.size(), ssid.data());
 
-    return CHIP_NO_ERROR;
+    mHandling.mOnConnectionSuccess = handling.mOnConnectionSuccess;
+    mHandling.mOnConnectionFailed  = handling.mOnConnectionFailed;
+    mHandling.mConnectionTimeout   = handling.mConnectionTimeout;
+
+    mWiFiState = WIFI_STATE_ASSOCIATING;
+
+    // Store SSID and credentials and perform the scan to detect the security mode supported by the AP.
+    // Zephyr WiFi connect request will be issued in the callback when we have the SSID match.
+    mWantedNetwork.Erase();
+    memcpy(mWantedNetwork.ssid, ssid.data(), ssid.size());
+    memcpy(mWantedNetwork.pass, credentials.data(), credentials.size());
+    mWantedNetwork.ssidLen = ssid.size();
+    mWantedNetwork.passLen = credentials.size();
+
+    return Scan(ssid, nullptr, nullptr, true /* internal scan */);
 }
 
-void WiFiManager::WaitForConnectionAsync()
+CHIP_ERROR WiFiManager::Disconnect()
 {
-    chip::DeviceLayer::SystemLayer().StartTimer(
-        static_cast<System::Clock::Timeout>(1000), [](System::Layer *, void *) { Instance().PollTimerCallback(); }, nullptr);
-}
+    net_if * iface = InetUtils::GetInterface();
+    VerifyOrReturnError(nullptr != iface, CHIP_ERROR_INTERNAL);
 
-void WiFiManager::PollTimerCallback()
-{
-    const uint32_t kMaxRetriesNumber{ mConnectionTimeoutMs.count() / 1000 };
-    static uint32_t retriesNumber{ 0 };
+    int status = net_mgmt(NET_REQUEST_WIFI_DISCONNECT, iface, NULL, 0);
 
-    if (WiFiManager::StationStatus::FULLY_PROVISIONED == GetStationStatus())
+    if (status)
     {
-        retriesNumber = 0;
-        OnConnectionSuccess();
-    }
-    else
-    {
-        if (retriesNumber++ < kMaxRetriesNumber)
+        if (status == -EALREADY)
         {
-            // wait more time
-            WaitForConnectionAsync();
+            ChipLogDetail(DeviceLayer, "Already disconnected");
         }
         else
         {
-            // connection timeout
-            retriesNumber = 0;
-            OnConnectionFailed();
+            ChipLogDetail(DeviceLayer, "Disconnect request failed");
+            return CHIP_ERROR_INTERNAL;
         }
     }
+    else
+    {
+        ChipLogDetail(DeviceLayer, "Disconnect requested");
+    }
+
+    return CHIP_NO_ERROR;
 }
 
 CHIP_ERROR WiFiManager::GetWiFiInfo(WiFiInfo & info) const
 {
-    VerifyOrReturnError(nullptr != wpa_s, CHIP_ERROR_INTERNAL);
-    VerifyOrReturnError(nullptr != mpWpaNetwork, CHIP_ERROR_INTERNAL);
+    net_if * iface = InetUtils::GetInterface();
+    VerifyOrReturnError(nullptr != iface, CHIP_ERROR_INTERNAL);
+    struct wifi_iface_status status = { 0 };
 
-    static uint8_t sBssid[ETH_ALEN];
-    if (WiFiManager::StationStatus::CONNECTED <= GetStationStatus())
+    if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &status, sizeof(struct wifi_iface_status)))
     {
-        memcpy(sBssid, wpa_s->bssid, ETH_ALEN);
-        info.mBssId        = ByteSpan(sBssid, ETH_ALEN);
-        info.mSecurityType = GetSecurityType();
-        // TODO: this should reflect the real connection compliance
-        // i.e. the AP might support WiFi 5 only even though the station
-        // is WiFi 6 ready (so the connection is WiFi 5 effectively).
-        // For now just return what the station supports.
-        info.mWiFiVersion = EMBER_ZCL_WI_FI_VERSION_TYPE_AX;
+        ChipLogError(DeviceLayer, "Status request failed");
+        return CHIP_ERROR_INTERNAL;
+    }
 
-        wpa_signal_info signalInfo{};
-        if (0 == wpa_drv_signal_poll(wpa_s, &signalInfo))
-        {
-            info.mRssi    = signalInfo.current_signal; // dBm
-            info.mChannel = FrequencyToChannel(signalInfo.frequency);
-        }
-        else
-        {
-            // this values should be nullable according to the Matter spec
-            info.mRssi    = std::numeric_limits<decltype(info.mRssi)>::min();
-            info.mChannel = std::numeric_limits<decltype(info.mChannel)>::min();
-        }
-
-        memcpy(info.mSsid, mpWpaNetwork->ssid, mpWpaNetwork->ssid_len);
-        info.mSsidLen = mpWpaNetwork->ssid_len;
+    if (status.state >= WIFI_STATE_ASSOCIATED)
+    {
+        uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")];
+        net_sprint_ll_addr_buf(reinterpret_cast<const uint8_t *>(status.bssid), WIFI_MAC_ADDR_LEN,
+                               reinterpret_cast<char *>(mac_string_buf), sizeof(mac_string_buf));
+        info.mBssId        = ByteSpan(mac_string_buf, sizeof(mac_string_buf));
+        info.mSecurityType = static_cast<uint8_t>(status.security);
+        info.mWiFiVersion  = static_cast<uint8_t>(status.link_mode);
+        info.mRssi         = status.rssi;
+        info.mChannel      = status.channel;
+        info.mSsidLen      = status.ssid_len;
+        memcpy(info.mSsid, status.ssid, status.ssid_len);
 
         return CHIP_NO_ERROR;
     }
@@ -380,53 +263,6 @@
     return CHIP_ERROR_INTERNAL;
 }
 
-uint8_t WiFiManager::GetSecurityType() const
-{
-    VerifyOrReturnValue(nullptr != mpWpaNetwork, EMBER_ZCL_SECURITY_TYPE_UNSPECIFIED);
-
-    if ((mpWpaNetwork->key_mgmt & WPA_KEY_MGMT_NONE) || !wpa_key_mgmt_wpa_any(mpWpaNetwork->key_mgmt))
-    {
-        return EMBER_ZCL_SECURITY_TYPE_NONE;
-    }
-    else if (wpa_key_mgmt_wpa_psk_no_sae(mpWpaNetwork->key_mgmt))
-    {
-        return (mpWpaNetwork->pairwise_cipher & (WPA_CIPHER_TKIP | WPA_CIPHER_CCMP)) ? EMBER_ZCL_SECURITY_TYPE_WPA2
-                                                                                     : EMBER_ZCL_SECURITY_TYPE_WPA3;
-    }
-    else if (wpa_key_mgmt_sae(mpWpaNetwork->key_mgmt))
-    {
-        return EMBER_ZCL_SECURITY_TYPE_WPA3;
-    }
-    else
-    {
-        return EMBER_ZCL_SECURITY_TYPE_WEP;
-    }
-
-    return EMBER_ZCL_SECURITY_TYPE_UNSPECIFIED;
-}
-
-uint8_t WiFiManager::FrequencyToChannel(uint16_t freq)
-{
-    static constexpr uint16_t k24MinFreq{ 2401 };
-    static constexpr uint16_t k24MaxFreq{ 2484 };
-    static constexpr uint8_t k24FreqConstDiff{ 5 };
-
-    if (freq >= k24MinFreq && freq < k24MaxFreq)
-    {
-        return static_cast<uint8_t>((freq - k24MinFreq) / k24FreqConstDiff + 1);
-    }
-    else if (freq == k24MaxFreq)
-    {
-        return 14;
-    }
-    else if (freq > k24MaxFreq)
-    {
-        // assume we are in 5GH band
-        return sFreqChannelMap[freq];
-    }
-    return 0;
-}
-
 CHIP_ERROR WiFiManager::GetNetworkStatistics(NetworkStatistics & stats) const
 {
     // TODO: below will not work (result will be all zeros) until
@@ -443,5 +279,159 @@
     return CHIP_NO_ERROR;
 }
 
+void WiFiManager::ScanResultHandler(uint8_t * data)
+{
+    const struct wifi_scan_result * scanResult = reinterpret_cast<const struct wifi_scan_result *>(data);
+
+    if (Instance().mInternalScan &&
+        Instance().mWantedNetwork.GetSsidSpan().data_equal(ByteSpan(scanResult->ssid, scanResult->ssid_length)))
+    {
+        // Prepare the connection parameters
+        // In case there are many networks with the same SSID choose the one with the best RSSI
+        if (scanResult->rssi > Instance().mWiFiParams.mRssi)
+        {
+            Instance().ClearStationProvisioningData();
+            Instance().mWiFiParams.mParams.ssid_length = Instance().mWantedNetwork.ssidLen;
+            Instance().mWiFiParams.mParams.ssid        = Instance().mWantedNetwork.ssid;
+            // Fallback to the WIFI_SECURITY_TYPE_PSK if the security is unknown
+            Instance().mWiFiParams.mParams.security =
+                scanResult->security <= WIFI_SECURITY_TYPE_MAX ? scanResult->security : WIFI_SECURITY_TYPE_PSK;
+            Instance().mWiFiParams.mParams.psk_length = Instance().mWantedNetwork.passLen;
+
+            // If the security is none, WiFi driver expects the psk to be nullptr
+            if (Instance().mWiFiParams.mParams.security == WIFI_SECURITY_TYPE_NONE)
+            {
+                Instance().mWiFiParams.mParams.psk = nullptr;
+            }
+            else
+            {
+                Instance().mWiFiParams.mParams.psk = Instance().mWantedNetwork.pass;
+            }
+
+            Instance().mWiFiParams.mParams.timeout = Instance().mHandling.mConnectionTimeout.count();
+            Instance().mWiFiParams.mParams.channel = scanResult->channel;
+            Instance().mWiFiParams.mRssi           = scanResult->rssi;
+        }
+    }
+
+    if (Instance().mScanResultCallback && !Instance().mInternalScan)
+    {
+        Instance().mScanResultCallback(ToScanResponse(scanResult));
+    }
+}
+
+void WiFiManager::ScanDoneHandler(uint8_t * data)
+{
+    const wifi_status * status      = reinterpret_cast<const wifi_status *>(data);
+    WiFiRequestStatus requestStatus = static_cast<WiFiRequestStatus>(status->status);
+
+    if (Instance().mScanDoneCallback && !Instance().mInternalScan)
+    {
+        Instance().mScanDoneCallback(requestStatus);
+    }
+
+    if (requestStatus == WiFiRequestStatus::FAILURE)
+    {
+        ChipLogDetail(DeviceLayer, "Scan request failed (%d)", status->status);
+    }
+    else
+    {
+        ChipLogDetail(DeviceLayer, "Scan request done (%d)", status->status);
+
+        // Internal scan is supposed to be followed by connection request
+        if (Instance().mInternalScan)
+        {
+            Instance().mWiFiState = WIFI_STATE_ASSOCIATING;
+            net_if * iface        = InetUtils::GetInterface();
+            VerifyOrReturn(nullptr != iface, CHIP_ERROR_INTERNAL);
+
+            if (net_mgmt(NET_REQUEST_WIFI_CONNECT, iface, &(Instance().mWiFiParams.mParams), sizeof(wifi_connect_req_params)))
+            {
+                ChipLogError(DeviceLayer, "Connection request failed");
+                if (Instance().mHandling.mOnConnectionFailed)
+                {
+                    Instance().mHandling.mOnConnectionFailed();
+                }
+                return;
+            }
+            ChipLogError(DeviceLayer, "Connection to %*s requested", Instance().mWiFiParams.mParams.ssid_length,
+                         Instance().mWiFiParams.mParams.ssid);
+            Instance().mInternalScan = false;
+        }
+    }
+}
+
+void WiFiManager::SendRouterSolicitation(System::Layer * layer, void * param)
+{
+    net_if * iface = InetUtils::GetInterface();
+    if (iface && iface->if_dev->link_addr.type == NET_LINK_ETHERNET)
+    {
+        net_if_start_rs(iface);
+        Instance().mRouterSolicitationCounter++;
+        if (Instance().mRouterSolicitationCounter < kRouterSolicitationMaxCount)
+        {
+            DeviceLayer::SystemLayer().StartTimer(System::Clock::Milliseconds32(kRouterSolicitationIntervalMs),
+                                                  SendRouterSolicitation, nullptr);
+        }
+        else
+        {
+            Instance().mRouterSolicitationCounter = 0;
+        }
+    }
+}
+
+void WiFiManager::ConnectHandler(uint8_t * data)
+{
+    const wifi_status * status      = reinterpret_cast<const wifi_status *>(data);
+    WiFiRequestStatus requestStatus = static_cast<WiFiRequestStatus>(status->status);
+
+    if (requestStatus == WiFiRequestStatus::FAILURE || requestStatus == WiFiRequestStatus::TERMINATED)
+    {
+        ChipLogDetail(DeviceLayer, "Connection to WiFi network failed or was terminated by another request");
+        Instance().mWiFiState = WIFI_STATE_DISCONNECTED;
+        if (Instance().mHandling.mOnConnectionFailed)
+        {
+            Instance().mHandling.mOnConnectionFailed();
+        }
+    }
+    else
+    {
+        // Workaround needed until sending Router Solicitation after connect will be done by the driver.
+        DeviceLayer::SystemLayer().StartTimer(
+            System::Clock::Milliseconds32(chip::Crypto::GetRandU16() % kMaxInitialRouterSolicitationDelayMs),
+            SendRouterSolicitation, nullptr);
+
+        ChipLogDetail(DeviceLayer, "Connected to WiFi network");
+        Instance().mWiFiState = WIFI_STATE_COMPLETED;
+        if (Instance().mHandling.mOnConnectionSuccess)
+        {
+            Instance().mHandling.mOnConnectionSuccess();
+        }
+        Instance().PostConnectivityStatusChange(kConnectivity_Established);
+    }
+    // cleanup the provisioning data as it is configured per each connect request
+    Instance().ClearStationProvisioningData();
+}
+
+void WiFiManager::DisconnectHandler(uint8_t * data)
+{
+    ChipLogDetail(DeviceLayer, "WiFi station disconnected");
+    Instance().mWiFiState = WIFI_STATE_DISCONNECTED;
+    Instance().PostConnectivityStatusChange(kConnectivity_Lost);
+}
+
+WiFiManager::StationStatus WiFiManager::GetStationStatus() const
+{
+    return WiFiManager::sStatusMap[mWiFiState];
+}
+
+void WiFiManager::PostConnectivityStatusChange(ConnectivityChange changeType)
+{
+    ChipDeviceEvent networkEvent{};
+    networkEvent.Type                          = DeviceEventType::kWiFiConnectivityChange;
+    networkEvent.WiFiConnectivityChange.Result = changeType;
+    PlatformMgr().PostEventOrDie(&networkEvent);
+}
+
 } // namespace DeviceLayer
 } // namespace chip
diff --git a/src/platform/nrfconnect/wifi/WiFiManager.h b/src/platform/nrfconnect/wifi/WiFiManager.h
index b068cd9..920df4d 100644
--- a/src/platform/nrfconnect/wifi/WiFiManager.h
+++ b/src/platform/nrfconnect/wifi/WiFiManager.h
@@ -24,10 +24,12 @@
 
 #include <lib/core/CHIPError.h>
 #include <lib/support/Span.h>
+#include <platform/CHIPDeviceLayer.h>
 #include <platform/NetworkCommissioning.h>
 #include <system/SystemLayer.h>
 
-#include <net/net_if.h>
+#include <zephyr/net/net_if.h>
+#include <zephyr/net/wifi_mgmt.h>
 
 extern "C" {
 #include <src/utils/common.h>
@@ -85,9 +87,18 @@
 
 class WiFiManager
 {
+public:
+    enum WiFiRequestStatus : int
+    {
+        SUCCESS    = 0,
+        FAILURE    = 1,
+        TERMINATED = 2
+    };
+
+    using ScanResultCallback = void (*)(const NetworkCommissioning::WiFiScanResponse &);
+    using ScanDoneCallback   = void (*)(WiFiRequestStatus);
     using ConnectionCallback = void (*)();
 
-public:
     enum class StationStatus : uint8_t
     {
         NONE,
@@ -97,7 +108,8 @@
         CONNECTING,
         CONNECTED,
         PROVISIONING,
-        FULLY_PROVISIONED
+        FULLY_PROVISIONED,
+        UNKNOWN
     };
 
     static WiFiManager & Instance()
@@ -106,13 +118,11 @@
         return sInstance;
     }
 
-    using ScanCallback = void (*)(int /* status */, NetworkCommissioning::WiFiScanResponse *);
-
     struct ConnectionHandling
     {
         ConnectionCallback mOnConnectionSuccess{};
         ConnectionCallback mOnConnectionFailed{};
-        System::Clock::Timeout mConnectionTimeoutMs{};
+        System::Clock::Seconds32 mConnectionTimeout{};
     };
 
     struct WiFiInfo
@@ -135,36 +145,72 @@
         uint32_t mOverruns{};
     };
 
+    struct WiFiNetwork
+    {
+        uint8_t ssid[DeviceLayer::Internal::kMaxWiFiSSIDLength];
+        size_t ssidLen = 0;
+        uint8_t pass[DeviceLayer::Internal::kMaxWiFiKeyLength];
+        size_t passLen = 0;
+
+        bool IsConfigured() const { return ssidLen > 0; }
+        ByteSpan GetSsidSpan() const { return ByteSpan(ssid, ssidLen); }
+        ByteSpan GetPassSpan() const { return ByteSpan(pass, passLen); }
+        void Clear() { ssidLen = 0; }
+        void Erase()
+        {
+            memset(ssid, 0, DeviceLayer::Internal::kMaxWiFiSSIDLength);
+            memset(pass, 0, DeviceLayer::Internal::kMaxWiFiKeyLength);
+            ssidLen = 0;
+            passLen = 0;
+        }
+    };
+
+    static constexpr uint16_t kRouterSolicitationIntervalMs        = 4000;
+    static constexpr uint16_t kMaxInitialRouterSolicitationDelayMs = 1000;
+    static constexpr uint8_t kRouterSolicitationMaxCount           = 3;
+
     CHIP_ERROR Init();
-    CHIP_ERROR Scan(const ByteSpan & ssid, ScanCallback callback);
+    CHIP_ERROR Scan(const ByteSpan & ssid, ScanResultCallback resultCallback, ScanDoneCallback doneCallback,
+                    bool internalScan = false);
     CHIP_ERROR Connect(const ByteSpan & ssid, const ByteSpan & credentials, const ConnectionHandling & handling);
     StationStatus GetStationStatus() const;
     CHIP_ERROR ClearStationProvisioningData();
-    CHIP_ERROR DisconnectStation();
+    CHIP_ERROR Disconnect();
     CHIP_ERROR GetWiFiInfo(WiFiInfo & info) const;
     CHIP_ERROR GetNetworkStatistics(NetworkStatistics & stats) const;
 
 private:
-    CHIP_ERROR AddPsk(const ByteSpan & credentials);
-    CHIP_ERROR EnableStation(bool enable);
-    CHIP_ERROR AddNetwork(const ByteSpan & ssid, const ByteSpan & credentials);
-    void PollTimerCallback();
-    void WaitForConnectionAsync();
-    void OnConnectionSuccess();
-    void OnConnectionFailed();
-    uint8_t GetSecurityType() const;
+    using NetEventHandler = void (*)(uint8_t *);
 
-    WpaNetwork * mpWpaNetwork{ nullptr };
-    ConnectionCallback mConnectionSuccessClbk;
-    ConnectionCallback mConnectionFailedClbk;
-    System::Clock::Timeout mConnectionTimeoutMs;
-    ScanCallback mScanCallback{ nullptr };
+    struct ConnectionParams
+    {
+        wifi_connect_req_params mParams;
+        int8_t mRssi{ std::numeric_limits<int8_t>::min() };
+    };
 
-    static uint8_t FrequencyToChannel(uint16_t freq);
-    static StationStatus StatusFromWpaStatus(const wpa_states & status);
+    constexpr static uint32_t kWifiManagementEvents = NET_EVENT_WIFI_SCAN_RESULT | NET_EVENT_WIFI_SCAN_DONE |
+        NET_EVENT_WIFI_CONNECT_RESULT | NET_EVENT_WIFI_DISCONNECT_RESULT | NET_EVENT_WIFI_IFACE_STATUS;
 
-    static const Map<wpa_states, StationStatus, 10> sStatusMap;
-    static const Map<uint16_t, uint8_t, 42> sFreqChannelMap;
+    // Event handling
+    static void WifiMgmtEventHandler(net_mgmt_event_callback * cb, uint32_t mgmtEvent, net_if * iface);
+    static void ScanResultHandler(uint8_t * data);
+    static void ScanDoneHandler(uint8_t * data);
+    static void ConnectHandler(uint8_t * data);
+    static void DisconnectHandler(uint8_t * data);
+    static void PostConnectivityStatusChange(ConnectivityChange changeType);
+    static void SendRouterSolicitation(System::Layer * layer, void * param);
+
+    ConnectionParams mWiFiParams{};
+    ConnectionHandling mHandling;
+    wifi_iface_state mWiFiState;
+    net_mgmt_event_callback mWiFiMgmtClbk{};
+    ScanResultCallback mScanResultCallback{ nullptr };
+    ScanDoneCallback mScanDoneCallback{ nullptr };
+    WiFiNetwork mWantedNetwork{};
+    bool mInternalScan{ false };
+    uint8_t mRouterSolicitationCounter = 0;
+    static const Map<wifi_iface_state, StationStatus, 10> sStatusMap;
+    static const Map<uint32_t, NetEventHandler, 4> sEventHandlerMap;
 };
 
 } // namespace DeviceLayer
diff --git a/src/test_driver/nrfconnect/main/runner.cpp b/src/test_driver/nrfconnect/main/runner.cpp
index b7654f7..a44e09a 100644
--- a/src/test_driver/nrfconnect/main/runner.cpp
+++ b/src/test_driver/nrfconnect/main/runner.cpp
@@ -19,8 +19,8 @@
 #include <lib/support/UnitTestRegistration.h>
 #include <platform/CHIPDeviceLayer.h>
 
-#include <logging/log.h>
-#include <settings/settings.h>
+#include <zephyr/logging/log.h>
+#include <zephyr/settings/settings.h>
 
 using namespace ::chip;
 using namespace ::chip::DeviceLayer;