11#include " WiFi.h"
22
3+ #define WIFI_MAX_BSSID_STRING_LENGTH 17
4+
35using namespace std ;
46
57/* -------------------------------------------------------------------------- */
@@ -256,6 +258,42 @@ uint8_t* CWifi::macAddress(uint8_t* _mac) {
256258 return _mac;
257259}
258260
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+
259297/* -------------------------------------------------------------------------- */
260298int8_t CWifi::scanNetworks () {
261299/* -------------------------------------------------------------------------- */
@@ -264,30 +302,60 @@ int8_t CWifi::scanNetworks() {
264302 modem.avoid_trim_results ();
265303 modem.read_using_size ();
266304
267- access_points.clear ();
305+ memset (access_points,0x00 ,sizeof (access_points));
306+ _apsFound = 0 ;
268307 string res;
269-
270- vector<string> aps;
271308 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+ }
272336
273- split (aps, res, string (" \r\n " ));
274- for (uint16_t i = 0 ; i < aps.size (); i++) {
275337 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+ }
286354 }
287355 }
288356 }
289357
290- return ( int8_t )access_points. size () ;
358+ return _apsFound ;
291359}
292360
293361/* -------------------------------------------------------------------------- */
@@ -376,51 +444,29 @@ IPAddress CWifi::gatewayIP() {
376444/* -------------------------------------------------------------------------- */
377445const char * CWifi::SSID (uint8_t networkItem) {
378446/* -------------------------------------------------------------------------- */
379- if (networkItem < access_points. size () ) {
380- return access_points[networkItem].ssid . c_str () ;
447+ if (networkItem < _apsFound ) {
448+ return access_points[networkItem].ssid ;
381449 }
382450 return nullptr ;
383451}
384452
385453/* -------------------------------------------------------------------------- */
386454int32_t CWifi::RSSI (uint8_t networkItem) {
387455/* -------------------------------------------------------------------------- */
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 ;
390458 }
391459 return -1000 ;
392460}
393461
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-
416462/* -------------------------------------------------------------------------- */
417463uint8_t CWifi::encryptionType () {
418464/* -------------------------------------------------------------------------- */
419465 scanNetworks ();
420466 string myssid (SSID ());
421- for (unsigned int i = 0 ; i < access_points. size () ; i++) {
467+ for (unsigned int i = 0 ; i < _apsFound ; i++) {
422468 if (myssid == access_points[i].ssid ) {
423- return Encr2wl_enc ( access_points[i].encryption_mode ) ;
469+ return access_points[i].encryption_mode ;
424470 }
425471 }
426472 return ENC_TYPE_UNKNOWN;
@@ -429,16 +475,16 @@ uint8_t CWifi::encryptionType() {
429475/* -------------------------------------------------------------------------- */
430476uint8_t CWifi::encryptionType (uint8_t networkItem) {
431477/* -------------------------------------------------------------------------- */
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 ;
434480 }
435481 return 0 ;
436482}
437483
438484/* -------------------------------------------------------------------------- */
439485uint8_t * CWifi::BSSID (uint8_t networkItem, uint8_t * bssid) {
440486/* -------------------------------------------------------------------------- */
441- if (networkItem < access_points. size () ) {
487+ if (networkItem < _apsFound ) {
442488 for (int i = 0 ; i < 6 ; i++) {
443489 *(bssid + i) = access_points[networkItem].uint_bssid [i];
444490 }
@@ -450,8 +496,8 @@ uint8_t* CWifi::BSSID(uint8_t networkItem, uint8_t* bssid) {
450496/* -------------------------------------------------------------------------- */
451497uint8_t CWifi::channel (uint8_t networkItem) {
452498/* -------------------------------------------------------------------------- */
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 ;
455501 }
456502 return 0 ;
457503}
0 commit comments