1
1
#include " WiFi.h"
2
2
3
+ #define WIFI_MAX_BSSID_STRING_LENGTH 17
4
+
3
5
using namespace std ;
4
6
5
7
/* -------------------------------------------------------------------------- */
@@ -256,6 +258,42 @@ uint8_t* CWifi::macAddress(uint8_t* _mac) {
256
258
return _mac;
257
259
}
258
260
261
+ /* -------------------------------------------------------------------------- */
262
+ void CWifi::_sortAPlist (uint8_t num) {
263
+ /* -------------------------------------------------------------------------- */
264
+ for (uint8_t i = 0 ; i < num; i++) {
265
+ for (uint8_t j = i+1 ; j < num; j++) {
266
+ if (access_points[j].rssi > access_points[i].rssi ) {
267
+ CAccessPoint temp = access_points[i];
268
+ access_points[i] = access_points[j];
269
+ access_points[j] = temp;
270
+ }
271
+ }
272
+ }
273
+ }
274
+
275
+ static uint8_t Encr2wl_enc (string e) {
276
+ if (e == string (" open" )) {
277
+ return ENC_TYPE_NONE;
278
+ } else if (e == string (" WEP" )) {
279
+ return ENC_TYPE_WEP;
280
+ } else if (e == string (" WPA" )) {
281
+ return ENC_TYPE_WPA;
282
+ } else if (e == string (" WPA2" )) {
283
+ return ENC_TYPE_WPA2;
284
+ } else if (e == string (" WPA+WPA2" )) {
285
+ return ENC_TYPE_WPA2;
286
+ } else if (e == string (" WPA2-EAP" )) {
287
+ return ENC_TYPE_WPA2_ENTERPRISE;
288
+ } else if (e == string (" WPA2+WPA3" )) {
289
+ return ENC_TYPE_WPA3;
290
+ } else if (e == string (" WPA3" )) {
291
+ return ENC_TYPE_WPA3;
292
+ } else {
293
+ return ENC_TYPE_UNKNOWN;
294
+ }
295
+ }
296
+
259
297
/* -------------------------------------------------------------------------- */
260
298
int8_t CWifi::scanNetworks () {
261
299
/* -------------------------------------------------------------------------- */
@@ -264,30 +302,60 @@ int8_t CWifi::scanNetworks() {
264
302
modem.avoid_trim_results ();
265
303
modem.read_using_size ();
266
304
267
- access_points.clear ();
305
+ memset (access_points,0x00 ,sizeof (access_points));
306
+ _apsFound = 0 ;
268
307
string res;
269
-
270
- vector<string> aps;
271
308
if (modem.write (string (PROMPT (_WIFISCAN)),res,CMD (_WIFISCAN))) {
309
+ char *startAp = (char *)res.c_str ();
310
+ char *endAP = strstr (startAp, " \r\n " );
311
+ for (; endAP != NULL ; startAp = endAP + 2 , endAP = strstr (startAp, " \r\n " )) {
312
+ /* split the modem response in multiple lines and parse once at time.
313
+ * The output will be something like:
314
+ * SSID | BSSID | RSSI | CHANNEL | SECURITY
315
+ */
316
+ *endAP = ' \0 ' ; // Replace \r with \0
317
+
318
+ char *token[5 ];
319
+ uint8_t i = 1 ;
320
+ token[0 ] = startAp;
321
+ for (; i < 5 ; i++){
322
+ char *endToken = strstr (token[i-1 ], " | " );
323
+ if (endToken == NULL ){
324
+ break ;
325
+ }
326
+ memset (endToken, ' \0 ' , 3 );
327
+ token[i] = endToken + 3 ;
328
+ }
329
+
330
+ if (i < 5 || strlen (token[0 ]) == 0 || strlen (token[0 ]) > WL_SSID_MAX_LENGTH ||
331
+ strlen (token[1 ]) != WIFI_MAX_BSSID_STRING_LENGTH ||
332
+ strlen (token[2 ]) == 0 || strlen (token[3 ]) == 0 || strlen (token[4 ]) == 0 ){
333
+ /* Skip the row and process the next one */
334
+ continue ;
335
+ }
272
336
273
- split (aps, res, string (" \r\n " ));
274
- for (uint16_t i = 0 ; i < aps.size (); i++) {
275
337
CAccessPoint ap;
276
- vector<string> tokens;
277
- split (tokens, aps[i], string (" |" ));
278
- if (tokens.size () >= 5 ) {
279
- ap.ssid = tokens[0 ];
280
- ap.bssid = tokens[1 ];
281
- macStr2macArray (ap.uint_bssid , ap.bssid .c_str ());
282
- ap.rssi = tokens[2 ];
283
- ap.channel = tokens[3 ];
284
- ap.encryption_mode = tokens[4 ];
285
- access_points.push_back (ap);
338
+ strcpy (ap.ssid , token[0 ]);
339
+ macStr2macArray (ap.uint_bssid , token[1 ]);
340
+ ap.rssi = atoi (token[2 ]);
341
+ ap.channel = atoi (token[3 ]);
342
+ ap.encryption_mode = Encr2wl_enc (token[4 ]);
343
+
344
+ // insert in list
345
+ if ( _apsFound < WIFI_MAX_SSID_COUNT ){
346
+ access_points[_apsFound] = ap;
347
+ _apsFound++;
348
+ _sortAPlist (_apsFound);
349
+ }else {
350
+ if (ap.rssi > access_points[WIFI_MAX_SSID_COUNT-1 ].rssi ){
351
+ access_points[WIFI_MAX_SSID_COUNT-1 ] = ap;
352
+ _sortAPlist (WIFI_MAX_SSID_COUNT);
353
+ }
286
354
}
287
355
}
288
356
}
289
357
290
- return ( int8_t )access_points. size () ;
358
+ return _apsFound ;
291
359
}
292
360
293
361
/* -------------------------------------------------------------------------- */
@@ -376,51 +444,29 @@ IPAddress CWifi::gatewayIP() {
376
444
/* -------------------------------------------------------------------------- */
377
445
const char * CWifi::SSID (uint8_t networkItem) {
378
446
/* -------------------------------------------------------------------------- */
379
- if (networkItem < access_points. size () ) {
380
- return access_points[networkItem].ssid . c_str () ;
447
+ if (networkItem < _apsFound ) {
448
+ return access_points[networkItem].ssid ;
381
449
}
382
450
return nullptr ;
383
451
}
384
452
385
453
/* -------------------------------------------------------------------------- */
386
454
int32_t CWifi::RSSI (uint8_t networkItem) {
387
455
/* -------------------------------------------------------------------------- */
388
- if (networkItem < access_points. size () ) {
389
- return atoi ( access_points[networkItem].rssi . c_str ()) ;
456
+ if (networkItem < _apsFound ) {
457
+ return access_points[networkItem].rssi ;
390
458
}
391
459
return -1000 ;
392
460
}
393
461
394
- static uint8_t Encr2wl_enc (string e) {
395
- if (e == string (" open" )) {
396
- return ENC_TYPE_NONE;
397
- } else if (e == string (" WEP" )) {
398
- return ENC_TYPE_WEP;
399
- } else if (e == string (" WPA" )) {
400
- return ENC_TYPE_WPA;
401
- } else if (e == string (" WPA2" )) {
402
- return ENC_TYPE_WPA2;
403
- } else if (e == string (" WPA+WPA2" )) {
404
- return ENC_TYPE_WPA2;
405
- } else if (e == string (" WPA2-EAP" )) {
406
- return ENC_TYPE_WPA2_ENTERPRISE;
407
- } else if (e == string (" WPA2+WPA3" )) {
408
- return ENC_TYPE_WPA3;
409
- } else if (e == string (" WPA3" )) {
410
- return ENC_TYPE_WPA3;
411
- } else {
412
- return ENC_TYPE_UNKNOWN;
413
- }
414
- }
415
-
416
462
/* -------------------------------------------------------------------------- */
417
463
uint8_t CWifi::encryptionType () {
418
464
/* -------------------------------------------------------------------------- */
419
465
scanNetworks ();
420
466
string myssid (SSID ());
421
- for (unsigned int i = 0 ; i < access_points. size () ; i++) {
467
+ for (unsigned int i = 0 ; i < _apsFound ; i++) {
422
468
if (myssid == access_points[i].ssid ) {
423
- return Encr2wl_enc ( access_points[i].encryption_mode ) ;
469
+ return access_points[i].encryption_mode ;
424
470
}
425
471
}
426
472
return ENC_TYPE_UNKNOWN;
@@ -429,16 +475,16 @@ uint8_t CWifi::encryptionType() {
429
475
/* -------------------------------------------------------------------------- */
430
476
uint8_t CWifi::encryptionType (uint8_t networkItem) {
431
477
/* -------------------------------------------------------------------------- */
432
- if (networkItem < access_points. size () ) {
433
- return Encr2wl_enc ( access_points[networkItem].encryption_mode ) ;
478
+ if (networkItem < _apsFound ) {
479
+ return access_points[networkItem].encryption_mode ;
434
480
}
435
481
return 0 ;
436
482
}
437
483
438
484
/* -------------------------------------------------------------------------- */
439
485
uint8_t * CWifi::BSSID (uint8_t networkItem, uint8_t * bssid) {
440
486
/* -------------------------------------------------------------------------- */
441
- if (networkItem < access_points. size () ) {
487
+ if (networkItem < _apsFound ) {
442
488
for (int i = 0 ; i < 6 ; i++) {
443
489
*(bssid + i) = access_points[networkItem].uint_bssid [i];
444
490
}
@@ -450,8 +496,8 @@ uint8_t* CWifi::BSSID(uint8_t networkItem, uint8_t* bssid) {
450
496
/* -------------------------------------------------------------------------- */
451
497
uint8_t CWifi::channel (uint8_t networkItem) {
452
498
/* -------------------------------------------------------------------------- */
453
- if (networkItem < access_points. size () ) {
454
- return atoi ( access_points[networkItem].channel . c_str ()) ;
499
+ if (networkItem < _apsFound ) {
500
+ return access_points[networkItem].channel ;
455
501
}
456
502
return 0 ;
457
503
}
0 commit comments