Skip to content

Commit

Permalink
Update network scan to sort by RSSI
Browse files Browse the repository at this point in the history
  • Loading branch information
tyeth committed Nov 13, 2024
1 parent 270344d commit f234c27
Show file tree
Hide file tree
Showing 5 changed files with 224 additions and 75 deletions.
66 changes: 47 additions & 19 deletions src/network_interfaces/Wippersnapper_AIRLIFT.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#include "Arduino.h"
#include <vector>
#include <algorithm>
#include "SPI.h"
#include "WiFiNINA.h"
#include "Wippersnapper.h"
Expand Down Expand Up @@ -101,45 +103,71 @@ class Wippersnapper_AIRLIFT : public Wippersnapper {
_pass = WS._config.network.pass;
}

/***********************************************************/
/*!
// Define a structure to hold network information
struct WiFiNetwork {
char ssid[33]; // Maximum SSID length is 32 characters + null terminator
int rssi;
};

// Comparison function to sort by RSSI in descending order
bool static compareByRSSI(const WiFiNetwork &a, const WiFiNetwork &b) {
return a.rssi > b.rssi;
}

/***********************************************************/
/*!
@brief Performs a scan of local WiFi networks.
@returns True if `_network_ssid` is found, False otherwise.
*/
/***********************************************************/
bool check_valid_ssid() {
*/
/***********************************************************/
bool check_valid_ssid() {
// Disconnect WiFi from an AP if it was previously connected
WiFi.disconnect();
delay(100);

// Perform a network scan
int n = WiFi.scanNetworks();
if (n == 0) {
WS_DEBUG_PRINTLN("ERROR: No WiFi networks found!");
return false;
WS_DEBUG_PRINTLN("ERROR: No WiFi networks found!");
return false;
}

// Was the network within secrets.json found?
// Dynamically allocate memory for the network list
std::vector<WiFiNetwork> networks(n);

// Store the scanned networks in the vector
for (int i = 0; i < n; ++i) {
if (strcmp(_ssid, WiFi.SSID(i)) == 0) {
WS_DEBUG_PRINT("SSID found! RSSI: ");
WS_DEBUG_PRINTLN(WiFi.RSSI(i));
return true;
}
strncpy(networks[i].ssid, WiFi.SSID(i).c_str(), sizeof(networks[i].ssid) - 1);
networks[i].ssid[sizeof(networks[i].ssid) - 1] = '\0'; // Ensure null termination
networks[i].rssi = WiFi.RSSI(i);
}

// Sort the networks by RSSI in descending order
std::sort(networks.begin(), networks.end(), compareByRSSI);

// Was the network within secrets.json found?
for (const auto &network : networks) {
if (strcmp(_ssid, network.ssid) == 0) {
WS_DEBUG_PRINT("SSID (");
WS_DEBUG_PRINT(_ssid);
WS_DEBUG_PRINT(") found! RSSI: ");
WS_DEBUG_PRINTLN(network.rssi);
return true;
}
}

// User-set network not found, print scan results to serial console
WS_DEBUG_PRINTLN("ERROR: Your requested WiFi network was not found!");
WS_DEBUG_PRINTLN("WipperSnapper found these WiFi networks: ");
for (int i = 0; i < n; ++i) {
WS_DEBUG_PRINT(WiFi.SSID(i));
WS_DEBUG_PRINT(" ");
WS_DEBUG_PRINT(WiFi.RSSI(i));
WS_DEBUG_PRINTLN("dB");
for (const auto &network : networks) {
WS_DEBUG_PRINT(network.ssid);
WS_DEBUG_PRINT(" ");
WS_DEBUG_PRINT(network.rssi);
WS_DEBUG_PRINTLN("dB");
}

return false;
}
}

/********************************************************/
/*!
Expand Down
72 changes: 49 additions & 23 deletions src/network_interfaces/Wippersnapper_ESP32.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#include "Arduino.h"
#include <vector>
#include <algorithm>
#include "WiFi.h"
#include "WiFiMulti.h"
#include <NetworkClient.h>
Expand Down Expand Up @@ -90,6 +92,17 @@ class Wippersnapper_ESP32 : public Wippersnapper {
_pass = WS._config.network.pass;
}

// Define a structure to hold network information
struct WiFiNetwork {
char ssid[33]; // Maximum SSID length is 32 characters + null terminator
int rssi;
};

// Comparison function to sort by RSSI in descending order
bool static compareByRSSI(const WiFiNetwork &a, const WiFiNetwork &b) {
return a.rssi > b.rssi;
}

/***********************************************************/
/*!
@brief Performs a scan of local WiFi networks.
Expand All @@ -116,41 +129,54 @@ class Wippersnapper_ESP32 : public Wippersnapper {
// Perform a network scan
int n = WiFi.scanNetworks();
if (n == 0) {
WS_DEBUG_PRINTLN("ERROR: No WiFi networks found!");
return false;
WS_DEBUG_PRINTLN("ERROR: No WiFi networks found!");
return false;
}

// Was the network within secrets.json found?
// Dynamically allocate memory for the network list
std::vector<WiFiNetwork> networks(n);

// Store the scanned networks in the vector
for (int i = 0; i < n; ++i) {
if (strcmp(_ssid, WiFi.SSID(i).c_str()) == 0) {
WS_DEBUG_PRINT("SSID (");
WS_DEBUG_PRINT(_ssid);
WS_DEBUG_PRINT(") found! RSSI: ");
WS_DEBUG_PRINTLN(WiFi.RSSI(i));
return true;
}
if (WS._isWiFiMulti) {
// multi network mode
for (int j = 0; j < WS_MAX_ALT_WIFI_NETWORKS; j++) {
if (strcmp(WS._multiNetworks[j].ssid, WiFi.SSID(i).c_str()) == 0) {
strncpy(networks[i].ssid, WiFi.SSID(i).c_str(), sizeof(networks[i].ssid) - 1);
networks[i].ssid[sizeof(networks[i].ssid) - 1] = '\0'; // Ensure null termination
networks[i].rssi = WiFi.RSSI(i);
}

// Sort the networks by RSSI in descending order
std::sort(networks.begin(), networks.end(), compareByRSSI);

// Was the network within secrets.json found?
for (const auto &network : networks) {
if (strcmp(_ssid, network.ssid) == 0) {
WS_DEBUG_PRINT("SSID (");
WS_DEBUG_PRINT(WS._multiNetworks[j].ssid);
WS_DEBUG_PRINT(_ssid);
WS_DEBUG_PRINT(") found! RSSI: ");
WS_DEBUG_PRINTLN(WiFi.RSSI(i));
WS_DEBUG_PRINTLN(network.rssi);
return true;
}
}
}
if (WS._isWiFiMulti) {
// multi network mode
for (int j = 0; j < WS_MAX_ALT_WIFI_NETWORKS; j++) {
if (strcmp(WS._multiNetworks[j].ssid, network.ssid) == 0) {
WS_DEBUG_PRINT("SSID (");
WS_DEBUG_PRINT(WS._multiNetworks[j].ssid);
WS_DEBUG_PRINT(") found! RSSI: ");
WS_DEBUG_PRINTLN(network.rssi);
return true;
}
}
}
}

// User-set network not found, print scan results to serial console
WS_DEBUG_PRINTLN("ERROR: Your requested WiFi network was not found!");
WS_DEBUG_PRINTLN("WipperSnapper found these WiFi networks: ");
for (int i = 0; i < n; ++i) {
WS_DEBUG_PRINT(WiFi.SSID(i));
WS_DEBUG_PRINT(" ");
WS_DEBUG_PRINT(WiFi.RSSI(i));
WS_DEBUG_PRINTLN("dB");
for (const auto &network : networks) {
WS_DEBUG_PRINT(network.ssid);
WS_DEBUG_PRINT(" ");
WS_DEBUG_PRINT(network.rssi);
WS_DEBUG_PRINTLN("dB");
}

return false;
Expand Down
45 changes: 37 additions & 8 deletions src/network_interfaces/Wippersnapper_ESP8266.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#define WIPPERSNAPPER_ESP8266_H

#ifdef ARDUINO_ARCH_ESP8266
#include <vector>
#include <algorithm>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#include "ESP8266WiFi.h"
Expand Down Expand Up @@ -113,6 +115,19 @@ class Wippersnapper_ESP8266 : public Wippersnapper {
_pass = WS._config.network.pass;
}

// Define a structure to hold network information
struct WiFiNetwork
{
char ssid[33]; // Maximum SSID length is 32 characters + null terminator
int rssi;
};

// Comparison function to sort by RSSI in descending order
bool static compareByRSSI(const WiFiNetwork &a, const WiFiNetwork &b)
{
return a.rssi > b.rssi;
}

/***********************************************************/
/*!
@brief Performs a scan of local WiFi networks.
Expand All @@ -133,23 +148,36 @@ class Wippersnapper_ESP8266 : public Wippersnapper {
return false;
}

// Was the network within secrets.json found?
// Dynamically allocate memory for the network list
std::vector<WiFiNetwork> networks(n);

// Store the scanned networks in the vector
for (int i = 0; i < n; ++i) {
if (strcmp(_ssid, WiFi.SSID(i).c_str()) == 0) {
strncpy(networks[i].ssid, WiFi.SSID(i).c_str(), sizeof(networks[i].ssid) - 1);
networks[i].ssid[sizeof(networks[i].ssid) - 1] = '\0'; // Ensure null termination
networks[i].rssi = WiFi.RSSI(i);
}

// Sort the networks by RSSI in descending order
std::sort(networks.begin(), networks.end(), compareByRSSI);

// Was the network within secrets.json found?
for (const auto &network : networks) {
if (strcmp(_ssid, network.ssid) == 0) {
WS_DEBUG_PRINT("SSID (");
WS_DEBUG_PRINT(_ssid);
WS_DEBUG_PRINT(") found! RSSI: ");
WS_DEBUG_PRINTLN(WiFi.RSSI(i));
WS_DEBUG_PRINTLN(network.rssi);
return true;
}
if (WS._isWiFiMulti) {
// multi network mode
for (int j = 0; j < WS_MAX_ALT_WIFI_NETWORKS; j++) {
if (strcmp(WS._multiNetworks[j].ssid, WiFi.SSID(i).c_str()) == 0) {
if (strcmp(WS._multiNetworks[j].ssid, network.ssid) == 0) {
WS_DEBUG_PRINT("SSID (");
WS_DEBUG_PRINT(WS._multiNetworks[j].ssid);
WS_DEBUG_PRINT(") found! RSSI: ");
WS_DEBUG_PRINTLN(WiFi.RSSI(i));
WS_DEBUG_PRINTLN(network.rssi);
return true;
}
}
Expand All @@ -159,10 +187,11 @@ class Wippersnapper_ESP8266 : public Wippersnapper {
// User-set network not found, print scan results to serial console
WS_DEBUG_PRINTLN("ERROR: Your requested WiFi network was not found!");
WS_DEBUG_PRINTLN("WipperSnapper found these WiFi networks: ");
for (int i = 0; i < n; ++i) {
WS_DEBUG_PRINT(WiFi.SSID(i));
for (const auto &network : networks)
{
WS_DEBUG_PRINT(network.ssid);
WS_DEBUG_PRINT(" ");
WS_DEBUG_PRINT(WiFi.RSSI(i));
WS_DEBUG_PRINT(network.rssi);
WS_DEBUG_PRINTLN("dB");
}

Expand Down
61 changes: 46 additions & 15 deletions src/network_interfaces/Wippersnapper_WIFININA.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#include <Adafruit_MQTT.h>
#include <Adafruit_MQTT_Client.h>
#include <Arduino.h>
#include <vector>
#include <algorithm>
#include <SPI.h>
#include <WiFiNINA.h>

Expand Down Expand Up @@ -109,10 +111,24 @@ class Wippersnapper_WIFININA : public Wippersnapper {
strlcpy(WS._config.network.pass, _pass, sizeof(WS._config.network.pass));
}


// Define a structure to hold network information
struct WiFiNetwork
{
char ssid[33]; // Maximum SSID length is 32 characters + null terminator
int rssi;
};

// Comparison function to sort by RSSI in descending order
bool static compareByRSSI(const WiFiNetwork &a, const WiFiNetwork &b)
{
return a.rssi > b.rssi;
}

/***********************************************************/
/*!
@brief Performs a scan of local WiFi networks.
@returns True if `_network_ssid` is found, False otherwise.
@brief Performs a scan of local WiFi networks.
@returns True if `_network_ssid` is found, False otherwise.
*/
/***********************************************************/
bool check_valid_ssid() {
Expand All @@ -124,27 +140,42 @@ class Wippersnapper_WIFININA : public Wippersnapper {
// Perform a network scan
int n = WiFi.scanNetworks();
if (n == 0) {
WS_DEBUG_PRINTLN("ERROR: No WiFi networks found!");
return false;
WS_DEBUG_PRINTLN("ERROR: No WiFi networks found!");
return false;
}

// Was the network within secrets.json found?
// Dynamically allocate memory for the network list
std::vector<WiFiNetwork> networks(n);

// Store the scanned networks in the vector
for (int i = 0; i < n; ++i) {
if (strcmp(_ssid, WiFi.SSID(i)) == 0) {
WS_DEBUG_PRINT("SSID found! RSSI: ");
WS_DEBUG_PRINTLN(WiFi.RSSI(i));
return true;
}
strncpy(networks[i].ssid, WiFi.SSID(i).c_str(), sizeof(networks[i].ssid) - 1);
networks[i].ssid[sizeof(networks[i].ssid) - 1] = '\0'; // Ensure null termination
networks[i].rssi = WiFi.RSSI(i);
}

// Sort the networks by RSSI in descending order
std::sort(networks.begin(), networks.end(), compareByRSSI);

// Was the network within secrets.json found?
for (const auto &network : networks) {
if (strcmp(_ssid, network.ssid) == 0) {
WS_DEBUG_PRINT("SSID (");
WS_DEBUG_PRINT(_ssid);
WS_DEBUG_PRINT(") found! RSSI: ");
WS_DEBUG_PRINTLN(network.rssi);
return true;
}
}

// User-set network not found, print scan results to serial console
WS_DEBUG_PRINTLN("ERROR: Your requested WiFi network was not found!");
WS_DEBUG_PRINTLN("WipperSnapper found these WiFi networks: ");
for (int i = 0; i < n; ++i) {
WS_DEBUG_PRINT(WiFi.SSID(i));
WS_DEBUG_PRINT(" ");
WS_DEBUG_PRINT(WiFi.RSSI(i));
WS_DEBUG_PRINTLN("dB");
for (const auto &network : networks) {
WS_DEBUG_PRINT(network.ssid);
WS_DEBUG_PRINT(" ");
WS_DEBUG_PRINT(network.rssi);
WS_DEBUG_PRINTLN("dB");
}

return false;
Expand Down
Loading

0 comments on commit f234c27

Please sign in to comment.