Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions libraries/WiFi/examples/WiFiWebClient/WiFiWebClient.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
66 changes: 52 additions & 14 deletions libraries/WiFi/src/WiFi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

WiFiClass WiFi;

WiFiClass *WiFiClass::instance = nullptr;

String WiFiClass::firmwareVersion() {
#if defined(ARDUINO_PORTENTA_C33)
return "v1.5.0";
Expand All @@ -10,29 +12,54 @@ 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;
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;

// 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;
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);

// 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();
}

Expand Down Expand Up @@ -79,7 +106,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() {
Expand Down
70 changes: 68 additions & 2 deletions libraries/WiFi/src/WiFi.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
#include "utility/wl_definitions.h"
#include <zephyr/net/wifi_mgmt.h>

// 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 | \
Expand All @@ -17,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);

Expand All @@ -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<const struct wifi_scan_result *>(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;
Expand All @@ -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;
1 change: 1 addition & 0 deletions loader/llext_exports.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down