Skip to content

Commit

Permalink
[nrfconnect] Add checking of Wi-Fi supplicant and Interface
Browse files Browse the repository at this point in the history
We need to handle the Wi-Fi supplicant events to verify whether
the Wi-Fi supplicant and Interface are ready to use.
  • Loading branch information
ArekBalysNordic committed Feb 27, 2024
1 parent a2d98f8 commit b3fe9c5
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 2 deletions.
43 changes: 41 additions & 2 deletions src/platform/nrfconnect/wifi/WiFiManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,33 @@ const Map<uint32_t, WiFiManager::NetEventHandler, 5>
{ NET_EVENT_WIFI_DISCONNECT_RESULT, WiFiManager::DisconnectHandler },
{ NET_EVENT_WIFI_DISCONNECT_COMPLETE, WiFiManager::DisconnectHandler } });

void WiFiManager::WiFiSupplicantEventHandler(net_mgmt_event_callback * cb, uint32_t mgmtEvent, net_if * iface)
{
switch (mgmtEvent)
{
case NET_EVENT_WPA_SUPP_READY:
Instance().mSupplicantReady = true;
break;
case NET_EVENT_WPA_SUPP_NOT_READY:
Instance().mSupplicantReady = false;
break;
case NET_EVENT_WPA_SUPP_IFACE_ADDED:
Instance().mInterfaceUp = true;
break;
case NET_EVENT_WPA_SUPP_IFACE_REMOVED:
Instance().mInterfaceUp = false;
break;
default:
break;
}

if (Instance().mSupplicantReady && Instance().mInterfaceUp)
{
// In this case the Supplicant and Interface is fully ready.
DeviceLayer::SystemLayer().CancelTimer(SupplicantInitTimeout, nullptr);
}
}

void WiFiManager::WifiMgmtEventHandler(net_mgmt_event_callback * cb, uint32_t mgmtEvent, net_if * iface)
{
if (0 == strcmp(iface->if_dev->dev->name, "wlan0"))
Expand Down Expand Up @@ -183,14 +210,18 @@ CHIP_ERROR WiFiManager::Init()
{
return CHIP_ERROR_INVALID_ADDRESS;
}

return CHIP_NO_ERROR;
});

net_mgmt_init_event_callback(&mWiFiMgmtClbk, WifiMgmtEventHandler, kWifiManagementEvents);
net_mgmt_add_event_callback(&mWiFiMgmtClbk);
net_mgmt_init_event_callback(&mSuppMgmtClbk, WiFiSupplicantEventHandler, kSupplicantEvents);
net_mgmt_add_event_callback(&mSuppMgmtClbk);

ChipLogDetail(DeviceLayer, "WiFiManager has been initialized");
// Set the timer and wait for the WiFi supplicant and interface ready.
DeviceLayer::SystemLayer().StartTimer(System::Clock::Milliseconds32(kSupplicantReadyTimeoutMs), SupplicantInitTimeout, nullptr);

ChipLogDetail(DeviceLayer, "WiFiManager initialization requested");

return CHIP_NO_ERROR;
}
Expand Down Expand Up @@ -597,5 +628,13 @@ CHIP_ERROR WiFiManager::SetLowPowerMode(bool onoff)
return CHIP_NO_ERROR;
}

void WiFiManager::SupplicantInitTimeout(System::Layer * layer, void * param)
{
ChipLogError(DeviceLayer, "Wi-Fi supplicant and interface have not been initialized!");
// Wi-Fi driver must be initialized within the given timeout, when it is still not ready, do not to allow any further
// operations.
VerifyOrDie(Instance().mSupplicantReady && Instance().mInterfaceUp);
}

} // namespace DeviceLayer
} // namespace chip
12 changes: 12 additions & 0 deletions src/platform/nrfconnect/wifi/WiFiManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

extern "C" {
#include <src/utils/common.h>
#include <supp_events.h>
#include <wpa_supplicant/wpa_supplicant_i.h>
}

Expand Down Expand Up @@ -173,6 +174,7 @@ class WiFiManager
static constexpr uint32_t kConnectionRecoveryMaxIntervalMs = CONFIG_CHIP_WIFI_CONNECTION_RECOVERY_MAXIMUM_INTERVAL;
static constexpr uint32_t kConnectionRecoveryJitterMs = CONFIG_CHIP_WIFI_CONNECTION_RECOVERY_JITTER;
static constexpr uint32_t kConnectionRecoveryMaxRetries = CONFIG_CHIP_WIFI_CONNECTION_RECOVERY_MAX_RETRIES_NUMBER;
static constexpr uint32_t kSupplicantReadyTimeoutMs = 500;

CHIP_ERROR Init();
CHIP_ERROR Scan(const ByteSpan & ssid, ScanResultCallback resultCallback, ScanDoneCallback doneCallback,
Expand All @@ -198,8 +200,12 @@ class WiFiManager
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;

constexpr static uint32_t kSupplicantEvents = NET_EVENT_WPA_SUPP_READY | NET_EVENT_WPA_SUPP_CMD_NOT_READY |
NET_EVENT_WPA_SUPP_IFACE_ADDED | NET_EVENT_WPA_SUPP_IFACE_REMOVED;

// Event handling
static void WifiMgmtEventHandler(net_mgmt_event_callback * cb, uint32_t mgmtEvent, net_if * iface);
static void WiFiSupplicantEventHandler(net_mgmt_event_callback * cb, uint32_t mgmtEvent, net_if * iface);
static void ScanResultHandler(Platform::UniquePtr<uint8_t> data);
static void ScanDoneHandler(Platform::UniquePtr<uint8_t> data);
static void ConnectHandler(Platform::UniquePtr<uint8_t> data);
Expand All @@ -217,14 +223,20 @@ class WiFiManager
// To avoid frequent recovery attempts when the signal to an access point is poor quality
// The connection recovery interval will be cleared after the defined delay in kConnectionRecoveryDelayToReset.
static void Recover(System::Layer * layer, void * param);
static void SupplicantInitTimeout(System::Layer * layer, void * param);
void ResetRecoveryTime();
System::Clock::Milliseconds32 CalculateNextRecoveryTime();

bool mSupplicantReady{ false };
bool mInterfaceUp{ false };
bool mSupplicantInitTimeoutElapsed{ false };
net_if * mNetIf{ nullptr };
ConnectionParams mWiFiParams{};
ConnectionHandling mHandling;
wifi_iface_state mWiFiState;
wifi_iface_state mCachedWiFiState;
net_mgmt_event_callback mWiFiMgmtClbk{};
net_mgmt_event_callback mSuppMgmtClbk{};
ScanResultCallback mScanResultCallback{ nullptr };
ScanDoneCallback mScanDoneCallback{ nullptr };
WiFiNetwork mWantedNetwork{};
Expand Down

0 comments on commit b3fe9c5

Please sign in to comment.