Skip to content

Add limit for returning the first 10 access points with high rssi #387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 95 additions & 49 deletions libraries/WiFiS3/src/WiFi.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "WiFi.h"

#define WIFI_MAX_BSSID_STRING_LENGTH 17

using namespace std;

/* -------------------------------------------------------------------------- */
Expand Down Expand Up @@ -256,6 +258,42 @@ uint8_t* CWifi::macAddress(uint8_t* _mac) {
return _mac;
}

/* -------------------------------------------------------------------------- */
void CWifi::_sortAPlist(uint8_t num) {
/* -------------------------------------------------------------------------- */
for(uint8_t i = 0; i < num; i++) {
for(uint8_t j = i+1; j < num; j++) {
if(access_points[j].rssi > access_points[i].rssi) {
CAccessPoint temp = access_points[i];
access_points[i] = access_points[j];
access_points[j] = temp;
}
}
}
}

static uint8_t Encr2wl_enc(string e) {
if (e == string("open")) {
return ENC_TYPE_NONE;
} else if (e == string("WEP")) {
return ENC_TYPE_WEP;
} else if (e == string("WPA")) {
return ENC_TYPE_WPA;
} else if (e == string("WPA2")) {
return ENC_TYPE_WPA2;
} else if (e == string("WPA+WPA2")) {
return ENC_TYPE_WPA2;
} else if (e == string("WPA2-EAP")) {
return ENC_TYPE_WPA2_ENTERPRISE;
} else if (e == string("WPA2+WPA3")) {
return ENC_TYPE_WPA3;
} else if (e == string("WPA3")) {
return ENC_TYPE_WPA3;
} else {
return ENC_TYPE_UNKNOWN;
}
}

/* -------------------------------------------------------------------------- */
int8_t CWifi::scanNetworks() {
/* -------------------------------------------------------------------------- */
Expand All @@ -264,30 +302,60 @@ int8_t CWifi::scanNetworks() {
modem.avoid_trim_results();
modem.read_using_size();

access_points.clear();
memset(access_points,0x00,sizeof(access_points));
_apsFound = 0;
string res;

vector<string> aps;
if(modem.write(string(PROMPT(_WIFISCAN)),res,CMD(_WIFISCAN))) {
char *startAp = (char*)res.c_str();
char *endAP = strstr(startAp, "\r\n");
for(; endAP != NULL; startAp = endAP + 2, endAP = strstr(startAp, "\r\n")) {
/* split the modem response in multiple lines and parse once at time.
* The output will be something like:
* SSID | BSSID | RSSI | CHANNEL | SECURITY
*/
*endAP = '\0'; // Replace \r with \0

char *token[5];
uint8_t i = 1;
token[0] = startAp;
for(; i < 5; i++){
char *endToken = strstr(token[i-1], " | ");
if(endToken == NULL){
break;
}
memset(endToken, '\0', 3);
token[i] = endToken + 3;
}

if(i < 5 || strlen(token[0]) == 0 || strlen(token[0]) > WL_SSID_MAX_LENGTH ||
strlen(token[1]) != WIFI_MAX_BSSID_STRING_LENGTH ||
strlen(token[2]) == 0 || strlen(token[3]) == 0 || strlen(token[4]) == 0){
/* Skip the row and process the next one */
continue;
}

split(aps, res, string("\r\n"));
for(uint16_t i = 0; i < aps.size(); i++) {
CAccessPoint ap;
vector<string> tokens;
split(tokens, aps[i], string("|"));
if(tokens.size() >= 5) {
ap.ssid = tokens[0];
ap.bssid = tokens[1];
macStr2macArray(ap.uint_bssid, ap.bssid.c_str());
ap.rssi = tokens[2];
ap.channel = tokens[3];
ap.encryption_mode = tokens[4];
access_points.push_back(ap);
strcpy(ap.ssid, token[0]);
macStr2macArray(ap.uint_bssid, token[1]);
ap.rssi = atoi(token[2]);
ap.channel = atoi(token[3]);
ap.encryption_mode = Encr2wl_enc(token[4]);

// insert in list
if( _apsFound < WIFI_MAX_SSID_COUNT ){
access_points[_apsFound] = ap;
_apsFound++;
_sortAPlist(_apsFound);
}else{
if (ap.rssi > access_points[WIFI_MAX_SSID_COUNT-1].rssi){
access_points[WIFI_MAX_SSID_COUNT-1] = ap;
_sortAPlist(WIFI_MAX_SSID_COUNT);
}
}
}
}

return (int8_t)access_points.size();
return _apsFound;
}

/* -------------------------------------------------------------------------- */
Expand Down Expand Up @@ -376,51 +444,29 @@ IPAddress CWifi::gatewayIP() {
/* -------------------------------------------------------------------------- */
const char* CWifi::SSID(uint8_t networkItem) {
/* -------------------------------------------------------------------------- */
if(networkItem < access_points.size()) {
return access_points[networkItem].ssid.c_str();
if(networkItem < _apsFound) {
return access_points[networkItem].ssid;
}
return nullptr;
}

/* -------------------------------------------------------------------------- */
int32_t CWifi::RSSI(uint8_t networkItem) {
/* -------------------------------------------------------------------------- */
if(networkItem < access_points.size()) {
return atoi(access_points[networkItem].rssi.c_str());
if(networkItem < _apsFound) {
return access_points[networkItem].rssi;
}
return -1000;
}

static uint8_t Encr2wl_enc(string e) {
if (e == string("open")) {
return ENC_TYPE_NONE;
} else if (e == string("WEP")) {
return ENC_TYPE_WEP;
} else if (e == string("WPA")) {
return ENC_TYPE_WPA;
} else if (e == string("WPA2")) {
return ENC_TYPE_WPA2;
} else if (e == string("WPA+WPA2")) {
return ENC_TYPE_WPA2;
} else if (e == string("WPA2-EAP")) {
return ENC_TYPE_WPA2_ENTERPRISE;
} else if (e == string("WPA2+WPA3")) {
return ENC_TYPE_WPA3;
} else if (e == string("WPA3")) {
return ENC_TYPE_WPA3;
} else {
return ENC_TYPE_UNKNOWN;
}
}

/* -------------------------------------------------------------------------- */
uint8_t CWifi::encryptionType() {
/* -------------------------------------------------------------------------- */
scanNetworks();
string myssid(SSID());
for(unsigned int i = 0; i < access_points.size(); i++) {
for(unsigned int i = 0; i < _apsFound; i++) {
if(myssid == access_points[i].ssid) {
return Encr2wl_enc(access_points[i].encryption_mode);
return access_points[i].encryption_mode;
}
}
return ENC_TYPE_UNKNOWN;
Expand All @@ -429,16 +475,16 @@ uint8_t CWifi::encryptionType() {
/* -------------------------------------------------------------------------- */
uint8_t CWifi::encryptionType(uint8_t networkItem) {
/* -------------------------------------------------------------------------- */
if(networkItem < access_points.size()) {
return Encr2wl_enc(access_points[networkItem].encryption_mode);
if(networkItem < _apsFound) {
return access_points[networkItem].encryption_mode;
}
return 0;
}

/* -------------------------------------------------------------------------- */
uint8_t* CWifi::BSSID(uint8_t networkItem, uint8_t* bssid) {
/* -------------------------------------------------------------------------- */
if(networkItem < access_points.size()) {
if(networkItem < _apsFound) {
for(int i = 0; i < 6; i++) {
*(bssid + i) = access_points[networkItem].uint_bssid[i];
}
Expand All @@ -450,8 +496,8 @@ uint8_t* CWifi::BSSID(uint8_t networkItem, uint8_t* bssid) {
/* -------------------------------------------------------------------------- */
uint8_t CWifi::channel(uint8_t networkItem) {
/* -------------------------------------------------------------------------- */
if(networkItem < access_points.size()) {
return atoi(access_points[networkItem].channel.c_str());
if(networkItem < _apsFound) {
return access_points[networkItem].channel;
}
return 0;
}
Expand Down
35 changes: 27 additions & 8 deletions libraries/WiFiS3/src/WiFi.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,43 @@

#define WIFI_FIRMWARE_LATEST_VERSION "0.5.2"

#ifndef WIFI_MAX_SSID_COUNT
#define WIFI_MAX_SSID_COUNT 10
#endif

class CAccessPoint {
public:
std::string ssid;
std::string bssid;
CAccessPoint() {}
CAccessPoint(const CAccessPoint &obj)
{
strcpy(ssid, obj.ssid);
rssi = obj.rssi;
channel = obj.channel;
encryption_mode = obj.encryption_mode;
memcpy(uint_bssid, obj.uint_bssid, sizeof(uint_bssid));
}
CAccessPoint &operator=(const CAccessPoint &obj) {
strcpy(ssid, obj.ssid);
rssi = obj.rssi;
channel = obj.channel;
encryption_mode = obj.encryption_mode;
memcpy(uint_bssid, obj.uint_bssid, sizeof(uint_bssid));
}
char ssid[WL_SSID_MAX_LENGTH + 1]; // +1 for null terminator
uint8_t uint_bssid[6];
std::string rssi;
std::string channel;
std::string encryption_mode;
int rssi;
uint8_t channel;
uint8_t encryption_mode;
};




class CWifi {
private:
void _config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2);
void _sortAPlist(uint8_t num);
unsigned long _timeout;
std::vector<CAccessPoint> access_points;
CAccessPoint access_points[WIFI_MAX_SSID_COUNT];
uint8_t _apsFound = 0;
std::string ssid;
std::string apssid;

Expand Down
Loading