Skip to content

Commit

Permalink
WiFi: Support for hidden networks and misc fixes.
Browse files Browse the repository at this point in the history
- Add support for connecting to hidden networks (issue #855).
- Implement `begin()` for WEP (issue #819).
- Add sanity checks to all functions accepting network index from the user.

Signed-off-by: iabdalkader <[email protected]>
  • Loading branch information
iabdalkader committed Apr 24, 2024
1 parent 59ec204 commit cfa61bc
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 30 deletions.
118 changes: 89 additions & 29 deletions libraries/WiFi/src/WiFi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,39 @@
#define SSID_MAX_LENGTH 32
#define SSID_MAX_COUNT 64

static uint8_t sec2enum(nsapi_security_t sec) {
switch (sec) {
case NSAPI_SECURITY_NONE:
return ENC_TYPE_NONE;
case NSAPI_SECURITY_WEP:
return ENC_TYPE_WEP;
case NSAPI_SECURITY_WPA:
return ENC_TYPE_TKIP;
case NSAPI_SECURITY_WPA2:
return ENC_TYPE_CCMP;
case NSAPI_SECURITY_WPA_WPA2:
return ENC_TYPE_CCMP;
case NSAPI_SECURITY_UNKNOWN:
default:
return ENC_TYPE_AUTO;
}
}

static nsapi_security_t enum2sec(wl_enc_type sec) {
switch (sec) {
case ENC_TYPE_NONE:
return NSAPI_SECURITY_NONE;
case ENC_TYPE_WEP:
return NSAPI_SECURITY_WEP;
case ENC_TYPE_TKIP:
return NSAPI_SECURITY_WPA;
case ENC_TYPE_CCMP:
return NSAPI_SECURITY_WPA_WPA2;
default:
return NSAPI_SECURITY_UNKNOWN;
}
}

bool arduino::WiFiClass::isVisible(const char* ssid) {
for (int i = 0; i < SSID_MAX_COUNT; i++) {
if (strncmp(ap_list[i].get_ssid(), ssid, SSID_MAX_LENGTH) == 0) {
Expand All @@ -13,18 +46,21 @@ bool arduino::WiFiClass::isVisible(const char* ssid) {
return false;
}

int arduino::WiFiClass::begin(const char* ssid, const char* passphrase) {
int arduino::WiFiClass::begin(const char* ssid, const char* passphrase, wl_enc_type security) {
if (wifi_if == nullptr) {
return 0;
}

wifi_if->attach(&arduino::WiFiClass::statusCallback);

scanNetworks();
// use scan result to populate security field
if (!isVisible(ssid)) {
_currentNetworkStatus = WL_CONNECT_FAILED;
return _currentNetworkStatus;

if (isVisible(ssid)) {
// Set the network security mode from the scan result.
_security = ap_list[connected_ap].get_security();
} else {
// For hidden networks, the security mode must be set explicitly.
_security = enum2sec(security);
}

wifi_if->set_dhcp(!_useStaticIP);
Expand All @@ -36,7 +72,7 @@ int arduino::WiFiClass::begin(const char* ssid, const char* passphrase) {
wifi_if->add_dns_server(_dnsServer1, if_name); // pushes dnsServer2 at index 1
}

nsapi_error_t result = wifi_if->connect(ssid, passphrase, ap_list[connected_ap].get_security());
nsapi_error_t result = wifi_if->connect(ssid, passphrase, _security);

if(result == NSAPI_ERROR_IS_CONNECTED) {
wifi_if->disconnect();
Expand All @@ -46,6 +82,23 @@ int arduino::WiFiClass::begin(const char* ssid, const char* passphrase) {
return _currentNetworkStatus;
}

int arduino::WiFiClass::begin(const char* ssid, uint8_t key_idx, const char* key) {
// The low-level driver expects all 4 keys to be passed in a buffer with the following format:
// <idx> <len> <key>, <idx> <len> <key>, etc..
uint8_t buf[(2 + 32) * 4] = { 0 };
size_t keylen = min(32, strlen(key));
size_t buflen = (keylen + 2) * 4;

// Repeat the key.
for (int i=0; i<buflen; i += (keylen + 2)) {
buf[i+0] = i / (keylen + 2);
buf[i+1] = keylen;
memcpy(&buf[i+2], key, keylen);
}

return begin(ssid, (const char *) buf, ENC_TYPE_WEP);
}

//Config Wifi to set Static IP && Disable DHCP
void arduino::WiFiClass::config(const char* localip, const char* netmask, const char* gateway){
SocketHelpers::config(IPAddress(localip), dnsIP(0), IPAddress(gateway), IPAddress(netmask));
Expand Down Expand Up @@ -161,25 +214,8 @@ int arduino::WiFiClass::setSSID(const char* ssid) {
return 1;
}

static uint8_t sec2enum(nsapi_security_t sec) {
switch (sec) {
case NSAPI_SECURITY_NONE:
return ENC_TYPE_NONE;
case NSAPI_SECURITY_WEP:
return ENC_TYPE_WEP;
case NSAPI_SECURITY_WPA:
return ENC_TYPE_TKIP;
case NSAPI_SECURITY_WPA2:
return ENC_TYPE_CCMP;
case NSAPI_SECURITY_WPA_WPA2:
return ENC_TYPE_CCMP;
case NSAPI_SECURITY_UNKNOWN:
default:
return ENC_TYPE_AUTO;
}
}

int8_t arduino::WiFiClass::scanNetworks() {
connected_ap = SSID_MAX_COUNT;
uint8_t count = SSID_MAX_COUNT;
if (ap_list != nullptr) {
free(ap_list);
Expand All @@ -189,23 +225,39 @@ int8_t arduino::WiFiClass::scanNetworks() {
}

char* arduino::WiFiClass::SSID(uint8_t networkItem) {
if (networkItem >= SSID_MAX_COUNT) {
return NULL;
}
return (char*)ap_list[networkItem].get_ssid();
}

int32_t arduino::WiFiClass::RSSI(uint8_t networkItem) {
if (networkItem >= SSID_MAX_COUNT) {
return 0;
}
return ap_list[networkItem].get_rssi();
}

uint8_t arduino::WiFiClass::encryptionType(uint8_t networkItem) {
if (networkItem >= SSID_MAX_COUNT) {
return ENC_TYPE_NONE;
}
return sec2enum(ap_list[networkItem].get_security());
}

uint8_t* arduino::WiFiClass::BSSID(uint8_t networkItem, uint8_t* bssid) {
memcpy(bssid, ap_list[networkItem].get_bssid(), 6);
if (networkItem >= SSID_MAX_COUNT) {
memset(bssid, 0, 6);
} else {
memcpy(bssid, ap_list[networkItem].get_bssid(), 6);
}
return bssid;
}

uint8_t arduino::WiFiClass::channel(uint8_t networkItem) {
if (networkItem >= SSID_MAX_COUNT) {
return -1;
}
return ap_list[networkItem].get_channel();
}

Expand All @@ -218,13 +270,21 @@ uint8_t arduino::WiFiClass::status() {
}

uint8_t arduino::WiFiClass::encryptionType() {
return sec2enum(ap_list[connected_ap].get_security());
if (connected_ap >= SSID_MAX_COUNT) {
return sec2enum(_security);
} else {
return sec2enum(ap_list[connected_ap].get_security());
}
}

uint8_t* arduino::WiFiClass::BSSID(unsigned char* bssid) {
const uint8_t* reverse_bssid = ap_list[connected_ap].get_bssid();
for (int b = 0; b < 6; b++) {
bssid[b] = reverse_bssid[5 - b];
if (connected_ap >= SSID_MAX_COUNT) {
memset(bssid, 0, 6);
} else {
const uint8_t* reverse_bssid = ap_list[connected_ap].get_bssid();
for (int b = 0; b < 6; b++) {
bssid[b] = reverse_bssid[5 - b];
}
}
return bssid;
}
Expand Down
3 changes: 2 additions & 1 deletion libraries/WiFi/src/WiFi.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class WiFiClass : public MbedSocketClass {
* param passphrase: Passphrase. Valid characters in a passphrase
* must be between ASCII 32-126 (decimal).
*/
int begin(const char* ssid, const char* passphrase);
int begin(const char* ssid, const char* passphrase, wl_enc_type security = ENC_TYPE_CCMP);

// Inherit config methods from the parent class
using MbedSocketClass::config;
Expand Down Expand Up @@ -201,6 +201,7 @@ class WiFiClass : public MbedSocketClass {
WiFiInterface* wifi_if = nullptr;
WiFiAccessPoint* ap_list = nullptr;
uint8_t connected_ap;
nsapi_security_t _security;
int setSSID(const char* ssid);
void ensureDefaultAPNetworkConfiguration();
static void* handleAPEvents(whd_interface_t ifp, const whd_event_header_t* event_header, const uint8_t* event_data, void* handler_user_data);
Expand Down

0 comments on commit cfa61bc

Please sign in to comment.