Skip to content

Commit a38606b

Browse files
authored
Merge pull request #387 from fabik111/add-limit-on-discovered-ap
Add limit for returning the first 10 access points with high rssi
2 parents b83b15c + ec15716 commit a38606b

File tree

2 files changed

+122
-57
lines changed

2 files changed

+122
-57
lines changed

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

+95-49
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "WiFi.h"
22

3+
#define WIFI_MAX_BSSID_STRING_LENGTH 17
4+
35
using 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
/* -------------------------------------------------------------------------- */
260298
int8_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
/* -------------------------------------------------------------------------- */
377445
const 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
/* -------------------------------------------------------------------------- */
386454
int32_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
/* -------------------------------------------------------------------------- */
417463
uint8_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
/* -------------------------------------------------------------------------- */
430476
uint8_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
/* -------------------------------------------------------------------------- */
439485
uint8_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
/* -------------------------------------------------------------------------- */
451497
uint8_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
}

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

+27-8
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,43 @@
1919

2020
#define WIFI_FIRMWARE_LATEST_VERSION "0.5.2"
2121

22+
#ifndef WIFI_MAX_SSID_COUNT
23+
#define WIFI_MAX_SSID_COUNT 10
24+
#endif
25+
2226
class CAccessPoint {
2327
public:
24-
std::string ssid;
25-
std::string bssid;
28+
CAccessPoint() {}
29+
CAccessPoint(const CAccessPoint &obj)
30+
{
31+
strcpy(ssid, obj.ssid);
32+
rssi = obj.rssi;
33+
channel = obj.channel;
34+
encryption_mode = obj.encryption_mode;
35+
memcpy(uint_bssid, obj.uint_bssid, sizeof(uint_bssid));
36+
}
37+
CAccessPoint &operator=(const CAccessPoint &obj) {
38+
strcpy(ssid, obj.ssid);
39+
rssi = obj.rssi;
40+
channel = obj.channel;
41+
encryption_mode = obj.encryption_mode;
42+
memcpy(uint_bssid, obj.uint_bssid, sizeof(uint_bssid));
43+
}
44+
char ssid[WL_SSID_MAX_LENGTH + 1]; // +1 for null terminator
2645
uint8_t uint_bssid[6];
27-
std::string rssi;
28-
std::string channel;
29-
std::string encryption_mode;
46+
int rssi;
47+
uint8_t channel;
48+
uint8_t encryption_mode;
3049
};
3150

3251

33-
34-
3552
class CWifi {
3653
private:
3754
void _config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2);
55+
void _sortAPlist(uint8_t num);
3856
unsigned long _timeout;
39-
std::vector<CAccessPoint> access_points;
57+
CAccessPoint access_points[WIFI_MAX_SSID_COUNT];
58+
uint8_t _apsFound = 0;
4059
std::string ssid;
4160
std::string apssid;
4261

0 commit comments

Comments
 (0)