Skip to content

Commit e6c1d47

Browse files
committed
WiFi: Support for hidden networks and misc fixes.
- 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]>
1 parent 59ec204 commit e6c1d47

File tree

2 files changed

+93
-30
lines changed

2 files changed

+93
-30
lines changed

Diff for: libraries/WiFi/src/WiFi.cpp

+91-29
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,39 @@
33
#define SSID_MAX_LENGTH 32
44
#define SSID_MAX_COUNT 64
55

6+
static uint8_t sec2enum(nsapi_security_t sec) {
7+
switch (sec) {
8+
case NSAPI_SECURITY_NONE:
9+
return ENC_TYPE_NONE;
10+
case NSAPI_SECURITY_WEP:
11+
return ENC_TYPE_WEP;
12+
case NSAPI_SECURITY_WPA:
13+
return ENC_TYPE_TKIP;
14+
case NSAPI_SECURITY_WPA2:
15+
return ENC_TYPE_CCMP;
16+
case NSAPI_SECURITY_WPA_WPA2:
17+
return ENC_TYPE_CCMP;
18+
case NSAPI_SECURITY_UNKNOWN:
19+
default:
20+
return ENC_TYPE_AUTO;
21+
}
22+
}
23+
24+
static nsapi_security_t enum2sec(wl_enc_type sec) {
25+
switch (sec) {
26+
case ENC_TYPE_NONE:
27+
return NSAPI_SECURITY_NONE;
28+
case ENC_TYPE_WEP:
29+
return NSAPI_SECURITY_WEP;
30+
case ENC_TYPE_TKIP:
31+
return NSAPI_SECURITY_WPA;
32+
case ENC_TYPE_CCMP:
33+
return NSAPI_SECURITY_WPA_WPA2;
34+
default:
35+
return NSAPI_SECURITY_UNKNOWN;
36+
}
37+
}
38+
639
bool arduino::WiFiClass::isVisible(const char* ssid) {
740
for (int i = 0; i < SSID_MAX_COUNT; i++) {
841
if (strncmp(ap_list[i].get_ssid(), ssid, SSID_MAX_LENGTH) == 0) {
@@ -13,18 +46,21 @@ bool arduino::WiFiClass::isVisible(const char* ssid) {
1346
return false;
1447
}
1548

16-
int arduino::WiFiClass::begin(const char* ssid, const char* passphrase) {
49+
int arduino::WiFiClass::begin(const char* ssid, const char* passphrase, wl_enc_type security) {
1750
if (wifi_if == nullptr) {
1851
return 0;
1952
}
2053

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

2356
scanNetworks();
24-
// use scan result to populate security field
25-
if (!isVisible(ssid)) {
26-
_currentNetworkStatus = WL_CONNECT_FAILED;
27-
return _currentNetworkStatus;
57+
58+
if (isVisible(ssid)) {
59+
// Set the network security mode from the scan result.
60+
_security = ap_list[connected_ap].get_security();
61+
} else {
62+
// For hidden networks, the security mode must be set explicitly.
63+
_security = enum2sec(security);
2864
}
2965

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

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

4177
if(result == NSAPI_ERROR_IS_CONNECTED) {
4278
wifi_if->disconnect();
@@ -46,6 +82,25 @@ int arduino::WiFiClass::begin(const char* ssid, const char* passphrase) {
4682
return _currentNetworkStatus;
4783
}
4884

85+
int arduino::WiFiClass::begin(const char* ssid, uint8_t key_idx, const char* key) {
86+
// The low-level driver expects all 4 keys to be passed in a buffer with the following format:
87+
// uint8_t index; // WEP key index [0/1/2/3]
88+
// uint8_t length; // WEP key length. Either 5 bytes (40-bits) or 13-bytes (104-bits)
89+
// uint8_t data[32]; // WEP key.
90+
uint8_t buf[(2 + 32) * 4] = { 0 };
91+
size_t keylen = min(32, strlen(key));
92+
size_t buflen = (keylen + 2) * 4;
93+
94+
// Repeat the key.
95+
for (int i=0; i<buflen; i += (keylen + 2)) {
96+
buf[i+0] = i / (keylen + 2);
97+
buf[i+1] = keylen;
98+
memcpy(&buf[i+2], key, keylen);
99+
}
100+
101+
return begin(ssid, (const char *) buf, ENC_TYPE_WEP);
102+
}
103+
49104
//Config Wifi to set Static IP && Disable DHCP
50105
void arduino::WiFiClass::config(const char* localip, const char* netmask, const char* gateway){
51106
SocketHelpers::config(IPAddress(localip), dnsIP(0), IPAddress(gateway), IPAddress(netmask));
@@ -161,25 +216,8 @@ int arduino::WiFiClass::setSSID(const char* ssid) {
161216
return 1;
162217
}
163218

164-
static uint8_t sec2enum(nsapi_security_t sec) {
165-
switch (sec) {
166-
case NSAPI_SECURITY_NONE:
167-
return ENC_TYPE_NONE;
168-
case NSAPI_SECURITY_WEP:
169-
return ENC_TYPE_WEP;
170-
case NSAPI_SECURITY_WPA:
171-
return ENC_TYPE_TKIP;
172-
case NSAPI_SECURITY_WPA2:
173-
return ENC_TYPE_CCMP;
174-
case NSAPI_SECURITY_WPA_WPA2:
175-
return ENC_TYPE_CCMP;
176-
case NSAPI_SECURITY_UNKNOWN:
177-
default:
178-
return ENC_TYPE_AUTO;
179-
}
180-
}
181-
182219
int8_t arduino::WiFiClass::scanNetworks() {
220+
connected_ap = SSID_MAX_COUNT;
183221
uint8_t count = SSID_MAX_COUNT;
184222
if (ap_list != nullptr) {
185223
free(ap_list);
@@ -189,23 +227,39 @@ int8_t arduino::WiFiClass::scanNetworks() {
189227
}
190228

191229
char* arduino::WiFiClass::SSID(uint8_t networkItem) {
230+
if (networkItem >= SSID_MAX_COUNT) {
231+
return NULL;
232+
}
192233
return (char*)ap_list[networkItem].get_ssid();
193234
}
194235

195236
int32_t arduino::WiFiClass::RSSI(uint8_t networkItem) {
237+
if (networkItem >= SSID_MAX_COUNT) {
238+
return 0;
239+
}
196240
return ap_list[networkItem].get_rssi();
197241
}
198242

199243
uint8_t arduino::WiFiClass::encryptionType(uint8_t networkItem) {
244+
if (networkItem >= SSID_MAX_COUNT) {
245+
return ENC_TYPE_NONE;
246+
}
200247
return sec2enum(ap_list[networkItem].get_security());
201248
}
202249

203250
uint8_t* arduino::WiFiClass::BSSID(uint8_t networkItem, uint8_t* bssid) {
204-
memcpy(bssid, ap_list[networkItem].get_bssid(), 6);
251+
if (networkItem >= SSID_MAX_COUNT) {
252+
memset(bssid, 0, 6);
253+
} else {
254+
memcpy(bssid, ap_list[networkItem].get_bssid(), 6);
255+
}
205256
return bssid;
206257
}
207258

208259
uint8_t arduino::WiFiClass::channel(uint8_t networkItem) {
260+
if (networkItem >= SSID_MAX_COUNT) {
261+
return -1;
262+
}
209263
return ap_list[networkItem].get_channel();
210264
}
211265

@@ -218,13 +272,21 @@ uint8_t arduino::WiFiClass::status() {
218272
}
219273

220274
uint8_t arduino::WiFiClass::encryptionType() {
221-
return sec2enum(ap_list[connected_ap].get_security());
275+
if (connected_ap >= SSID_MAX_COUNT) {
276+
return sec2enum(_security);
277+
} else {
278+
return sec2enum(ap_list[connected_ap].get_security());
279+
}
222280
}
223281

224282
uint8_t* arduino::WiFiClass::BSSID(unsigned char* bssid) {
225-
const uint8_t* reverse_bssid = ap_list[connected_ap].get_bssid();
226-
for (int b = 0; b < 6; b++) {
227-
bssid[b] = reverse_bssid[5 - b];
283+
if (connected_ap >= SSID_MAX_COUNT) {
284+
memset(bssid, 0, 6);
285+
} else {
286+
const uint8_t* reverse_bssid = ap_list[connected_ap].get_bssid();
287+
for (int b = 0; b < 6; b++) {
288+
bssid[b] = reverse_bssid[5 - b];
289+
}
228290
}
229291
return bssid;
230292
}

Diff for: libraries/WiFi/src/WiFi.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class WiFiClass : public MbedSocketClass {
8686
* param passphrase: Passphrase. Valid characters in a passphrase
8787
* must be between ASCII 32-126 (decimal).
8888
*/
89-
int begin(const char* ssid, const char* passphrase);
89+
int begin(const char* ssid, const char* passphrase, wl_enc_type security = ENC_TYPE_CCMP);
9090

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

0 commit comments

Comments
 (0)