From 96c21a3f34bc5e79112b2924419f5788322f505b Mon Sep 17 00:00:00 2001 From: Bogdan Ivanus Date: Wed, 10 Sep 2025 17:59:17 +0300 Subject: [PATCH 1/3] ZEP-55: Implemented WiFi.scan() functionality. --- libraries/WiFi/src/WiFi.cpp | 52 ++++++++++++++++++++--------- libraries/WiFi/src/WiFi.h | 66 +++++++++++++++++++++++++++++++++++++ loader/llext_exports.c | 1 + 3 files changed, 104 insertions(+), 15 deletions(-) diff --git a/libraries/WiFi/src/WiFi.cpp b/libraries/WiFi/src/WiFi.cpp index 5a6d2912..23781709 100644 --- a/libraries/WiFi/src/WiFi.cpp +++ b/libraries/WiFi/src/WiFi.cpp @@ -2,6 +2,8 @@ WiFiClass WiFi; +WiFiClass *WiFiClass::instance = nullptr; + String WiFiClass::firmwareVersion() { #if defined(ARDUINO_PORTENTA_C33) return "v1.5.0"; @@ -18,21 +20,30 @@ int WiFiClass::begin(const char *ssid, const char *passphrase, wl_enc_type secur sta_config.ssid_length = strlen(ssid); sta_config.psk = (const uint8_t *)passphrase; sta_config.psk_length = strlen(passphrase); - // TODO: change these fields with scan() results - sta_config.security = WIFI_SECURITY_TYPE_PSK; - sta_config.channel = WIFI_CHANNEL_ANY; - sta_config.band = WIFI_FREQ_BAND_2_4_GHZ; - sta_config.bandwidth = WIFI_FREQ_BANDWIDTH_20MHZ; - int ret = net_mgmt(NET_REQUEST_WIFI_CONNECT, sta_iface, &sta_config, - sizeof(struct wifi_connect_req_params)); - if (ret) { - return false; - } - NetworkInterface::begin(false, NET_EVENT_WIFI_MASK); - if (blocking) { - net_mgmt_event_wait_on_iface(sta_iface, NET_EVENT_WIFI_CONNECT_RESULT, NULL, NULL, NULL, - K_FOREVER); + + // Register the Wi-Fi event callback + net_mgmt_init_event_callback(&wifiCb, scanEventDispatcher, + NET_EVENT_WIFI_SCAN_RESULT | NET_EVENT_WIFI_SCAN_DONE); + + net_mgmt_add_event_callback(&wifiCb); + + (void)scanNetworks(); + + // Check if the network we were seekin was found and attempt to connect to it + if (getSoughtNetworkFound() != true) { + int ret = net_mgmt(NET_REQUEST_WIFI_CONNECT, sta_iface, &sta_config, + sizeof(struct wifi_connect_req_params)); + if (ret) { + return false; + } + + NetworkInterface::begin(false, NET_EVENT_WIFI_MASK); + if (blocking) { + net_mgmt_event_wait_on_iface(sta_iface, NET_EVENT_WIFI_CONNECT_RESULT, NULL, NULL, NULL, + K_FOREVER); + } } + return status(); } @@ -79,7 +90,18 @@ int WiFiClass::status() { } int8_t WiFiClass::scanNetworks() { - // TODO: borrow code from mbed core for scan results handling + resultCount = 0u; + setScanSequenceFinished(false); + setSoughtNetworkFound(false); + + // Trigger a new scan + net_mgmt(NET_REQUEST_WIFI_SCAN, sta_iface, nullptr, 0u); + + // Wait for the scan to finish. This is by design a blocking call + while (getScanSequenceFinished() != true) + ; + + return resultCount; } char *WiFiClass::SSID() { diff --git a/libraries/WiFi/src/WiFi.h b/libraries/WiFi/src/WiFi.h index 739b5bb3..bfd5abc4 100644 --- a/libraries/WiFi/src/WiFi.h +++ b/libraries/WiFi/src/WiFi.h @@ -3,6 +3,9 @@ #include "utility/wl_definitions.h" #include +// Max number of scan results to store +#define MAX_SCAN_RESULTS 20 + #define NET_EVENT_WIFI_MASK \ (NET_EVENT_WIFI_CONNECT_RESULT | NET_EVENT_WIFI_DISCONNECT_RESULT | \ NET_EVENT_WIFI_AP_ENABLE_RESULT | NET_EVENT_WIFI_AP_DISABLE_RESULT | \ @@ -31,6 +34,62 @@ class WiFiClass : public NetworkInterface { String firmwareVersion(); + static void scanEventDispatcher(struct net_mgmt_event_callback *cb, uint64_t mgmt_event, + struct net_if *iface) { + if (instance != nullptr) { + instance->handleScanEvent(cb, mgmt_event, iface); + } + } + + void handleScanEvent(struct net_mgmt_event_callback *cb, uint64_t mgmt_event, + struct net_if *iface) { + if (mgmt_event == NET_EVENT_WIFI_SCAN_RESULT) { + const struct wifi_scan_result *entry = + reinterpret_cast(cb->info); + if (resultCount < MAX_SCAN_RESULTS) { + memcpy(&scanResults[resultCount], entry, sizeof(struct wifi_scan_result)); + resultCount++; + + // for each new result found, compare network name with desired one + if (!memcmp(entry->ssid, sta_config.ssid, entry->ssid_length)) { + // if a match is found, add missing info to config before attempting to connect + sta_config.security = entry->security; + sta_config.channel = entry->channel; + sta_config.band = entry->band; + sta_config.bandwidth = WIFI_FREQ_BANDWIDTH_20MHZ; + + setSoughtNetworkFound(true); + } + } + } + + if (mgmt_event == NET_EVENT_WIFI_SCAN_DONE) { + setScanSequenceFinished(true); + + if (resultCount = 0) { + printk("No networks found.\n"); + } + } + } + + void setScanSequenceFinished(bool scanFinished) { + scanSequenceFinished = scanFinished; + } + + void setSoughtNetworkFound(bool networkFound) { + soughtNetworkFound = networkFound; + } + + bool getScanSequenceFinished(void) { + return scanSequenceFinished; + } + + bool getSoughtNetworkFound(void) { + return soughtNetworkFound; + } + + static WiFiClass *instance; + private: struct net_if *sta_iface = nullptr; struct net_if *ap_iface = nullptr; @@ -39,6 +98,13 @@ class WiFiClass : public NetworkInterface { struct wifi_connect_req_params sta_config; struct wifi_iface_status sta_state = {0}; + + struct wifi_scan_result scanResults[MAX_SCAN_RESULTS]; + uint8_t resultCount; + struct net_mgmt_event_callback wifiCb; + + bool soughtNetworkFound = false; + bool scanSequenceFinished = false; }; extern WiFiClass WiFi; diff --git a/loader/llext_exports.c b/loader/llext_exports.c index 7941a00b..607052dd 100644 --- a/loader/llext_exports.c +++ b/loader/llext_exports.c @@ -113,6 +113,7 @@ FORCE_EXPORT_SYM(tls_credential_add); FORCE_EXPORT_SYM(net_if_get_wifi_sta); FORCE_EXPORT_SYM(net_if_get_wifi_sap); FORCE_EXPORT_SYM(net_mgmt_NET_REQUEST_WIFI_CONNECT); +FORCE_EXPORT_SYM(net_mgmt_NET_REQUEST_WIFI_SCAN); FORCE_EXPORT_SYM(net_mgmt_NET_REQUEST_WIFI_IFACE_STATUS); FORCE_EXPORT_SYM(net_mgmt_NET_REQUEST_WIFI_AP_ENABLE); #endif From d93ba64c10142963897408a0256b8c1bfc75ce2c Mon Sep 17 00:00:00 2001 From: Bogdan Ivanus Date: Tue, 16 Sep 2025 17:23:00 +0300 Subject: [PATCH 2/3] ZEP-55: WiFi: try to connect using default connection parameters Device will try to connect using default connection parameters, if an SSID and a password were provided, even if the scan was unsuccessful. --- .../examples/WiFiWebClient/WiFiWebClient.ino | 4 +-- libraries/WiFi/src/WiFi.cpp | 26 +++++++++++++++---- libraries/WiFi/src/WiFi.h | 4 +-- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/libraries/WiFi/examples/WiFiWebClient/WiFiWebClient.ino b/libraries/WiFi/examples/WiFiWebClient/WiFiWebClient.ino index 0231e88c..b9d7c82e 100644 --- a/libraries/WiFi/examples/WiFiWebClient/WiFiWebClient.ino +++ b/libraries/WiFi/examples/WiFiWebClient/WiFiWebClient.ino @@ -50,8 +50,8 @@ void setup() { Serial.println(ssid); // Connect to WPA/WPA2 network. Change this line if using open or WEP network: status = WiFi.begin(ssid, pass); - // wait 3 seconds for connection: - delay(3000); + // wait 6 seconds for connection: + delay(6000); } Serial.println("Connected to wifi"); printWifiStatus(); diff --git a/libraries/WiFi/src/WiFi.cpp b/libraries/WiFi/src/WiFi.cpp index 23781709..8eafaae0 100644 --- a/libraries/WiFi/src/WiFi.cpp +++ b/libraries/WiFi/src/WiFi.cpp @@ -12,8 +12,8 @@ String WiFiClass::firmwareVersion() { #endif } -int WiFiClass::begin(const char *ssid, const char *passphrase, wl_enc_type security, - bool blocking) { +int begin(const char *ssid, const char *passphrase, + wifi_security_type security = WIFI_SECURITY_TYPE_NONE, bool blocking = true) { sta_iface = net_if_get_wifi_sta(); netif = sta_iface; sta_config.ssid = (const uint8_t *)ssid; @@ -21,16 +21,32 @@ int WiFiClass::begin(const char *ssid, const char *passphrase, wl_enc_type secur sta_config.psk = (const uint8_t *)passphrase; sta_config.psk_length = strlen(passphrase); + // The user might provide the security type as well + if (security != WIFI_SECURITY_TYPE_NONE) { + sta_config.security = security; + } else { + sta_config.security = WIFI_SECURITY_TYPE_PSK; + } + sta_config.channel = WIFI_CHANNEL_ANY; + sta_config.band = WIFI_FREQ_BAND_2_4_GHZ; + sta_config.bandwidth = WIFI_FREQ_BANDWIDTH_20MHZ; + // Register the Wi-Fi event callback net_mgmt_init_event_callback(&wifiCb, scanEventDispatcher, NET_EVENT_WIFI_SCAN_RESULT | NET_EVENT_WIFI_SCAN_DONE); net_mgmt_add_event_callback(&wifiCb); - (void)scanNetworks(); + // If the network we are scanning for is found, the connection parameters will be updated + // automatically; + (void)scanNetworks(); // This is a blocking function call + + // Attempt to connect with either default parameters, or the updated ones after the scan + // completed + if ((sta_config.ssid != NULL) && (sta_config.ssid_length != 0u) && (sta_config.psk != NULL) && + (sta_config.psk_length != 0u)) - // Check if the network we were seekin was found and attempt to connect to it - if (getSoughtNetworkFound() != true) { + { int ret = net_mgmt(NET_REQUEST_WIFI_CONNECT, sta_iface, &sta_config, sizeof(struct wifi_connect_req_params)); if (ret) { diff --git a/libraries/WiFi/src/WiFi.h b/libraries/WiFi/src/WiFi.h index bfd5abc4..b5bd052f 100644 --- a/libraries/WiFi/src/WiFi.h +++ b/libraries/WiFi/src/WiFi.h @@ -20,8 +20,8 @@ class WiFiClass : public NetworkInterface { ~WiFiClass() { } - int begin(const char *ssid, const char *passphrase, wl_enc_type security = ENC_TYPE_UNKNOWN, - bool blocking = true); + int begin(const char *ssid, const char *passphrase, + wifi_security_type security = WIFI_SECURITY_TYPE_NONE, bool blocking = true); bool beginAP(char *ssid, char *passphrase, int channel = WIFI_CHANNEL_ANY, bool blocking = false); From 503fd43e33fff8b99b16722d75c5e76c6feb9efd Mon Sep 17 00:00:00 2001 From: Bogdan Ivanus Date: Thu, 30 Oct 2025 18:38:15 +0200 Subject: [PATCH 3/3] Removed getters and setters from the library; changed to static struct for handling data transfer from callback to object. --- libraries/WiFi/src/WiFi.cpp | 303 ++++++++++++++++++++++-------------- libraries/WiFi/src/WiFi.h | 119 ++++---------- 2 files changed, 217 insertions(+), 205 deletions(-) diff --git a/libraries/WiFi/src/WiFi.cpp b/libraries/WiFi/src/WiFi.cpp index 8eafaae0..f8696d33 100644 --- a/libraries/WiFi/src/WiFi.cpp +++ b/libraries/WiFi/src/WiFi.cpp @@ -1,135 +1,210 @@ #include "WiFi.h" -WiFiClass WiFi; - -WiFiClass *WiFiClass::instance = nullptr; - -String WiFiClass::firmwareVersion() { -#if defined(ARDUINO_PORTENTA_C33) - return "v1.5.0"; -#else - return "v0.0.0"; -#endif -} - -int begin(const char *ssid, const char *passphrase, - wifi_security_type security = WIFI_SECURITY_TYPE_NONE, bool blocking = true) { - sta_iface = net_if_get_wifi_sta(); - netif = sta_iface; - sta_config.ssid = (const uint8_t *)ssid; - sta_config.ssid_length = strlen(ssid); - sta_config.psk = (const uint8_t *)passphrase; - sta_config.psk_length = strlen(passphrase); - - // The user might provide the security type as well - if (security != WIFI_SECURITY_TYPE_NONE) { - sta_config.security = security; - } else { - sta_config.security = WIFI_SECURITY_TYPE_PSK; - } - sta_config.channel = WIFI_CHANNEL_ANY; - sta_config.band = WIFI_FREQ_BAND_2_4_GHZ; - sta_config.bandwidth = WIFI_FREQ_BANDWIDTH_20MHZ; - - // Register the Wi-Fi event callback - net_mgmt_init_event_callback(&wifiCb, scanEventDispatcher, - NET_EVENT_WIFI_SCAN_RESULT | NET_EVENT_WIFI_SCAN_DONE); - - net_mgmt_add_event_callback(&wifiCb); - - // If the network we are scanning for is found, the connection parameters will be updated - // automatically; - (void)scanNetworks(); // This is a blocking function call - - // Attempt to connect with either default parameters, or the updated ones after the scan - // completed - if ((sta_config.ssid != NULL) && (sta_config.ssid_length != 0u) && (sta_config.psk != NULL) && - (sta_config.psk_length != 0u)) - - { - int ret = net_mgmt(NET_REQUEST_WIFI_CONNECT, sta_iface, &sta_config, - sizeof(struct wifi_connect_req_params)); - if (ret) { - return false; - } - - NetworkInterface::begin(false, NET_EVENT_WIFI_MASK); - if (blocking) { - net_mgmt_event_wait_on_iface(sta_iface, NET_EVENT_WIFI_CONNECT_RESULT, NULL, NULL, NULL, - K_FOREVER); - } - } - - return status(); +// Static Wi-Fi state instance +struct WiFiState { + struct net_if *sta_iface = nullptr; + struct net_if *ap_iface = nullptr; + struct wifi_connect_req_params ap_config; + struct wifi_connect_req_params sta_config; + struct wifi_iface_status sta_state = {0}; + struct wifi_scan_result scanResults[MAX_SCAN_RESULTS]; + uint8_t resultCount = 0; + struct net_mgmt_event_callback wifiCb; + bool soughtNetworkFound = false; + bool scanSequenceFinished = false; +}; + +WiFiClass::WiFiClass() {} +WiFiClass::~WiFiClass() {} + +// Static instance of Wi-Fi state +struct WiFiState WiFiClass::wifiState; + +int WiFiClass::begin(const char *ssid, const char *passphrase, + wl_enc_type security, bool blocking) { + wifi_security_type wifi_security = convert_enc_type_to_security_type(security); + + wifiState.sta_iface = net_if_get_wifi_sta(); + netif = wifiState.sta_iface; + wifiState.sta_config.ssid = (const uint8_t *)ssid; + wifiState.sta_config.ssid_length = strlen(ssid); + wifiState.sta_config.psk = (const uint8_t *)passphrase; + wifiState.sta_config.psk_length = strlen(passphrase); + + // Set Wi-Fi security type if specified + if (wifi_security != WIFI_SECURITY_TYPE_NONE) { + wifiState.sta_config.security = wifi_security; + } else { + wifiState.sta_config.security = WIFI_SECURITY_TYPE_PSK; + } + + wifiState.sta_config.channel = WIFI_CHANNEL_ANY; + wifiState.sta_config.band = WIFI_FREQ_BAND_2_4_GHZ; + wifiState.sta_config.bandwidth = WIFI_FREQ_BANDWIDTH_20MHZ; + + // Register the Wi-Fi event callback + net_mgmt_init_event_callback(&wifiState.wifiCb, scanEventDispatcher, + NET_EVENT_WIFI_SCAN_RESULT | NET_EVENT_WIFI_SCAN_DONE); + net_mgmt_add_event_callback(&wifiState.wifiCb); + + // Trigger a network scan + (void)scanNetworks(); // Blocking call + + // Attempt to connect to the network if configuration is valid + if (wifiState.sta_config.ssid && wifiState.sta_config.psk) { + int ret = net_mgmt(NET_REQUEST_WIFI_CONNECT, wifiState.sta_iface, &wifiState.sta_config, + sizeof(struct wifi_connect_req_params)); + if (ret) { + return false; + } + + NetworkInterface::begin(false, NET_EVENT_WIFI_MASK); + if (blocking) { + net_mgmt_event_wait_on_iface(wifiState.sta_iface, NET_EVENT_WIFI_CONNECT_RESULT, NULL, NULL, NULL, K_FOREVER); + } + } + + return status(); } bool WiFiClass::beginAP(char *ssid, char *passphrase, int channel, bool blocking) { - if (ap_iface != NULL) { - return false; - } - ap_iface = net_if_get_wifi_sap(); - netif = ap_iface; - ap_config.ssid = (const uint8_t *)ssid; - ap_config.ssid_length = strlen(ssid); - ap_config.psk = (const uint8_t *)passphrase; - ap_config.psk_length = strlen(passphrase); - ap_config.security = WIFI_SECURITY_TYPE_PSK; - ap_config.channel = channel; - ap_config.band = WIFI_FREQ_BAND_2_4_GHZ; - ap_config.bandwidth = WIFI_FREQ_BANDWIDTH_20MHZ; - int ret = net_mgmt(NET_REQUEST_WIFI_AP_ENABLE, ap_iface, &ap_config, - sizeof(struct wifi_connect_req_params)); - if (ret) { - return false; - } - enable_dhcpv4_server(ap_iface); - if (blocking) { - net_mgmt_event_wait_on_iface(ap_iface, NET_EVENT_WIFI_AP_ENABLE_RESULT, NULL, NULL, NULL, - K_FOREVER); - } - return true; + if (wifiState.ap_iface != nullptr) { + return false; // AP already initialized + } + + wifiState.ap_iface = net_if_get_wifi_sap(); + netif = wifiState.ap_iface; + wifiState.ap_config.ssid = (const uint8_t *)ssid; + wifiState.ap_config.ssid_length = strlen(ssid); + wifiState.ap_config.psk = (const uint8_t *)passphrase; + wifiState.ap_config.psk_length = strlen(passphrase); + wifiState.ap_config.security = WIFI_SECURITY_TYPE_PSK; + wifiState.ap_config.channel = channel; + wifiState.ap_config.band = WIFI_FREQ_BAND_2_4_GHZ; + wifiState.ap_config.bandwidth = WIFI_FREQ_BANDWIDTH_20MHZ; + + int ret = net_mgmt(NET_REQUEST_WIFI_AP_ENABLE, wifiState.ap_iface, &wifiState.ap_config, + sizeof(struct wifi_connect_req_params)); + if (ret) { + return false; + } + + enable_dhcpv4_server(wifiState.ap_iface); + + if (blocking) { + net_mgmt_event_wait_on_iface(wifiState.ap_iface, NET_EVENT_WIFI_AP_ENABLE_RESULT, NULL, NULL, NULL, K_FOREVER); + } + + return true; } int WiFiClass::status() { - sta_iface = net_if_get_wifi_sta(); - netif = sta_iface; - if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, netif, &sta_state, - sizeof(struct wifi_iface_status))) { - return WL_NO_SHIELD; - } - if (sta_state.state >= WIFI_STATE_ASSOCIATED) { - return WL_CONNECTED; - } else { - return WL_DISCONNECTED; - } - return WL_NO_SHIELD; + wifiState.sta_iface = net_if_get_wifi_sta(); + netif = wifiState.sta_iface; + if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, netif, &wifiState.sta_state, + sizeof(struct wifi_iface_status))) { + return WL_NO_SHIELD; + } + if (wifiState.sta_state.state >= WIFI_STATE_ASSOCIATED) { + return WL_CONNECTED; + } else { + return WL_DISCONNECTED; + } } int8_t WiFiClass::scanNetworks() { - resultCount = 0u; - setScanSequenceFinished(false); - setSoughtNetworkFound(false); + wifiState.resultCount = 0u; + wifiState.soughtNetworkFound = false; + wifiState.scanSequenceFinished = false; - // Trigger a new scan - net_mgmt(NET_REQUEST_WIFI_SCAN, sta_iface, nullptr, 0u); + // Trigger a new scan + net_mgmt(NET_REQUEST_WIFI_SCAN, wifiState.sta_iface, nullptr, 0u); - // Wait for the scan to finish. This is by design a blocking call - while (getScanSequenceFinished() != true) - ; + // Wait for the scan to finish (this is a blocking call) + while (!wifiState.scanSequenceFinished) + ; - return resultCount; + return wifiState.resultCount; +} + +void WiFiClass::scanEventDispatcher(struct net_mgmt_event_callback *cb, uint64_t mgmt_event, + struct net_if *iface) { + // Use the global Wi-Fi state instance to handle the event + if (wifiState.sta_iface != nullptr) { + WiFi.handleScanEvent(cb, mgmt_event, iface); + } +} + +void WiFiClass::handleScanEvent(struct net_mgmt_event_callback *cb, uint64_t mgmt_event, + struct net_if *iface) { + if (mgmt_event == NET_EVENT_WIFI_SCAN_RESULT) { + const struct wifi_scan_result *entry = reinterpret_cast(cb->info); + if (wifiState.resultCount < MAX_SCAN_RESULTS) { + memcpy(&wifiState.scanResults[wifiState.resultCount], entry, sizeof(struct wifi_scan_result)); + wifiState.resultCount++; + + // Compare SSID of the scanned network with the desired network SSID + if (!memcmp(entry->ssid, wifiState.sta_config.ssid, entry->ssid_length)) { + wifiState.sta_config.security = entry->security; + wifiState.sta_config.channel = entry->channel; + wifiState.sta_config.band = entry->band; + wifiState.sta_config.bandwidth = WIFI_FREQ_BANDWIDTH_20MHZ; + + wifiState.soughtNetworkFound = true; + } + } + } + + if (mgmt_event == NET_EVENT_WIFI_SCAN_DONE) { + wifiState.scanSequenceFinished = true; + + if (wifiState.resultCount == 0) { + printk("No networks found.\n"); + } + } } char *WiFiClass::SSID() { - if (status() == WL_CONNECTED) { - return (char *)sta_state.ssid; - } - return nullptr; + if (status() == WL_CONNECTED) { + return (char *)wifiState.sta_state.ssid; + } + return nullptr; } int32_t WiFiClass::RSSI() { - if (status() == WL_CONNECTED) { - return sta_state.rssi; - } - return 0; + if (status() == WL_CONNECTED) { + return wifiState.sta_state.rssi; + } + return 0; } + +String WiFiClass::firmwareVersion() { +#if defined(ARDUINO_PORTENTA_C33) + return "v1.5.0"; +#else + return "v0.0.0"; +#endif +} + +wifi_security_type WiFiClass::convert_enc_type_to_security_type(wl_enc_type enc_type) { + switch (enc_type) { + case ENC_TYPE_WEP: + return WIFI_SECURITY_TYPE_WEP; + case ENC_TYPE_WPA: + return WIFI_SECURITY_TYPE_WPA_PSK; // Could also map to WPA_AUTO_PERSONAL + case ENC_TYPE_WPA2: + return WIFI_SECURITY_TYPE_PSK; // Could also map to WPA_AUTO_PERSONAL + case ENC_TYPE_WPA3: + return WIFI_SECURITY_TYPE_SAE; // Could also map to SAE_AUTO + case ENC_TYPE_NONE: + return WIFI_SECURITY_TYPE_NONE; + case ENC_TYPE_UNKNOWN: + case ENC_TYPE_AUTO: + return WIFI_SECURITY_TYPE_UNKNOWN; + default: + return WIFI_SECURITY_TYPE_UNKNOWN; // Default case for any undefined or unexpected values + } +} + +// Global Wi-Fi object, uses the static wifiState struct +WiFiClass WiFi; diff --git a/libraries/WiFi/src/WiFi.h b/libraries/WiFi/src/WiFi.h index b5bd052f..01df0343 100644 --- a/libraries/WiFi/src/WiFi.h +++ b/libraries/WiFi/src/WiFi.h @@ -1,110 +1,47 @@ -#include "SocketHelpers.h" +#ifndef WIFI_H +#define WIFI_H +#include "SocketHelpers.h" #include "utility/wl_definitions.h" #include // Max number of scan results to store #define MAX_SCAN_RESULTS 20 +// Wi-Fi event mask for the various events #define NET_EVENT_WIFI_MASK \ - (NET_EVENT_WIFI_CONNECT_RESULT | NET_EVENT_WIFI_DISCONNECT_RESULT | \ - NET_EVENT_WIFI_AP_ENABLE_RESULT | NET_EVENT_WIFI_AP_DISABLE_RESULT | \ - NET_EVENT_WIFI_AP_STA_CONNECTED | NET_EVENT_WIFI_AP_STA_DISCONNECTED | \ - NET_EVENT_WIFI_SCAN_RESULT) + (NET_EVENT_WIFI_CONNECT_RESULT | NET_EVENT_WIFI_DISCONNECT_RESULT | \ + NET_EVENT_WIFI_AP_ENABLE_RESULT | NET_EVENT_WIFI_AP_DISABLE_RESULT | \ + NET_EVENT_WIFI_AP_STA_CONNECTED | NET_EVENT_WIFI_AP_STA_DISCONNECTED | \ + NET_EVENT_WIFI_SCAN_RESULT) class WiFiClass : public NetworkInterface { public: - WiFiClass() { - } - - ~WiFiClass() { - } - - int begin(const char *ssid, const char *passphrase, - wifi_security_type security = WIFI_SECURITY_TYPE_NONE, bool blocking = true); - bool beginAP(char *ssid, char *passphrase, int channel = WIFI_CHANNEL_ANY, - bool blocking = false); - - int status(); - - int8_t scanNetworks(); - - char *SSID(); - int32_t RSSI(); - - String firmwareVersion(); - - static void scanEventDispatcher(struct net_mgmt_event_callback *cb, uint64_t mgmt_event, - struct net_if *iface) { - if (instance != nullptr) { - instance->handleScanEvent(cb, mgmt_event, iface); - } - } - - void handleScanEvent(struct net_mgmt_event_callback *cb, uint64_t mgmt_event, - struct net_if *iface) { - if (mgmt_event == NET_EVENT_WIFI_SCAN_RESULT) { - const struct wifi_scan_result *entry = - reinterpret_cast(cb->info); - if (resultCount < MAX_SCAN_RESULTS) { - memcpy(&scanResults[resultCount], entry, sizeof(struct wifi_scan_result)); - resultCount++; + WiFiClass(); + ~WiFiClass(); - // for each new result found, compare network name with desired one - if (!memcmp(entry->ssid, sta_config.ssid, entry->ssid_length)) { - // if a match is found, add missing info to config before attempting to connect - sta_config.security = entry->security; - sta_config.channel = entry->channel; - sta_config.band = entry->band; - sta_config.bandwidth = WIFI_FREQ_BANDWIDTH_20MHZ; + int begin(const char *ssid, const char *passphrase, + wl_enc_type security = ENC_TYPE_WPA, bool blocking = true); - setSoughtNetworkFound(true); - } - } - } + bool beginAP(char *ssid, char *passphrase, int channel = WIFI_CHANNEL_ANY, + bool blocking = false); - if (mgmt_event == NET_EVENT_WIFI_SCAN_DONE) { - setScanSequenceFinished(true); + int status(); + int8_t scanNetworks(); + char *SSID(); + int32_t RSSI(); + String firmwareVersion(); + wifi_security_type convert_enc_type_to_security_type(wl_enc_type enc_type); - if (resultCount = 0) { - printk("No networks found.\n"); - } - } - } - - void setScanSequenceFinished(bool scanFinished) { - scanSequenceFinished = scanFinished; - } - - void setSoughtNetworkFound(bool networkFound) { - soughtNetworkFound = networkFound; - } - - bool getScanSequenceFinished(void) { - return scanSequenceFinished; - } - - bool getSoughtNetworkFound(void) { - return soughtNetworkFound; - } - - static WiFiClass *instance; + static struct WiFiState wifiState; // Static instance to hold Wi-Fi state private: - struct net_if *sta_iface = nullptr; - struct net_if *ap_iface = nullptr; - - struct wifi_connect_req_params ap_config; - struct wifi_connect_req_params sta_config; - - struct wifi_iface_status sta_state = {0}; - - struct wifi_scan_result scanResults[MAX_SCAN_RESULTS]; - uint8_t resultCount; - struct net_mgmt_event_callback wifiCb; - - bool soughtNetworkFound = false; - bool scanSequenceFinished = false; + static void scanEventDispatcher(struct net_mgmt_event_callback *cb, uint64_t mgmt_event, + struct net_if *iface); + void handleScanEvent(struct net_mgmt_event_callback *cb, uint64_t mgmt_event, + struct net_if *iface); }; -extern WiFiClass WiFi; +extern WiFiClass WiFi; // Global Wi-Fi object + +#endif // WIFI_H