Skip to content

Commit f234c27

Browse files
committed
Update network scan to sort by RSSI
1 parent 270344d commit f234c27

File tree

5 files changed

+224
-75
lines changed

5 files changed

+224
-75
lines changed

Diff for: src/network_interfaces/Wippersnapper_AIRLIFT.h

+47-19
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include "Adafruit_MQTT.h"
2424
#include "Adafruit_MQTT_Client.h"
2525
#include "Arduino.h"
26+
#include <vector>
27+
#include <algorithm>
2628
#include "SPI.h"
2729
#include "WiFiNINA.h"
2830
#include "Wippersnapper.h"
@@ -101,45 +103,71 @@ class Wippersnapper_AIRLIFT : public Wippersnapper {
101103
_pass = WS._config.network.pass;
102104
}
103105

104-
/***********************************************************/
105-
/*!
106+
// Define a structure to hold network information
107+
struct WiFiNetwork {
108+
char ssid[33]; // Maximum SSID length is 32 characters + null terminator
109+
int rssi;
110+
};
111+
112+
// Comparison function to sort by RSSI in descending order
113+
bool static compareByRSSI(const WiFiNetwork &a, const WiFiNetwork &b) {
114+
return a.rssi > b.rssi;
115+
}
116+
117+
/***********************************************************/
118+
/*!
106119
@brief Performs a scan of local WiFi networks.
107120
@returns True if `_network_ssid` is found, False otherwise.
108-
*/
109-
/***********************************************************/
110-
bool check_valid_ssid() {
121+
*/
122+
/***********************************************************/
123+
bool check_valid_ssid() {
111124
// Disconnect WiFi from an AP if it was previously connected
112125
WiFi.disconnect();
113126
delay(100);
114127

115128
// Perform a network scan
116129
int n = WiFi.scanNetworks();
117130
if (n == 0) {
118-
WS_DEBUG_PRINTLN("ERROR: No WiFi networks found!");
119-
return false;
131+
WS_DEBUG_PRINTLN("ERROR: No WiFi networks found!");
132+
return false;
120133
}
121134

122-
// Was the network within secrets.json found?
135+
// Dynamically allocate memory for the network list
136+
std::vector<WiFiNetwork> networks(n);
137+
138+
// Store the scanned networks in the vector
123139
for (int i = 0; i < n; ++i) {
124-
if (strcmp(_ssid, WiFi.SSID(i)) == 0) {
125-
WS_DEBUG_PRINT("SSID found! RSSI: ");
126-
WS_DEBUG_PRINTLN(WiFi.RSSI(i));
127-
return true;
128-
}
140+
strncpy(networks[i].ssid, WiFi.SSID(i).c_str(), sizeof(networks[i].ssid) - 1);
141+
networks[i].ssid[sizeof(networks[i].ssid) - 1] = '\0'; // Ensure null termination
142+
networks[i].rssi = WiFi.RSSI(i);
143+
}
144+
145+
// Sort the networks by RSSI in descending order
146+
std::sort(networks.begin(), networks.end(), compareByRSSI);
147+
148+
// Was the network within secrets.json found?
149+
for (const auto &network : networks) {
150+
if (strcmp(_ssid, network.ssid) == 0) {
151+
WS_DEBUG_PRINT("SSID (");
152+
WS_DEBUG_PRINT(_ssid);
153+
WS_DEBUG_PRINT(") found! RSSI: ");
154+
WS_DEBUG_PRINTLN(network.rssi);
155+
return true;
156+
}
129157
}
130158

131159
// User-set network not found, print scan results to serial console
132160
WS_DEBUG_PRINTLN("ERROR: Your requested WiFi network was not found!");
133161
WS_DEBUG_PRINTLN("WipperSnapper found these WiFi networks: ");
134-
for (int i = 0; i < n; ++i) {
135-
WS_DEBUG_PRINT(WiFi.SSID(i));
136-
WS_DEBUG_PRINT(" ");
137-
WS_DEBUG_PRINT(WiFi.RSSI(i));
138-
WS_DEBUG_PRINTLN("dB");
162+
for (const auto &network : networks) {
163+
WS_DEBUG_PRINT(network.ssid);
164+
WS_DEBUG_PRINT(" ");
165+
WS_DEBUG_PRINT(network.rssi);
166+
WS_DEBUG_PRINTLN("dB");
139167
}
140168

141169
return false;
142-
}
170+
}
143171

144172
/********************************************************/
145173
/*!

Diff for: src/network_interfaces/Wippersnapper_ESP32.h

+49-23
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include "Adafruit_MQTT.h"
2424
#include "Adafruit_MQTT_Client.h"
2525
#include "Arduino.h"
26+
#include <vector>
27+
#include <algorithm>
2628
#include "WiFi.h"
2729
#include "WiFiMulti.h"
2830
#include <NetworkClient.h>
@@ -90,6 +92,17 @@ class Wippersnapper_ESP32 : public Wippersnapper {
9092
_pass = WS._config.network.pass;
9193
}
9294

95+
// Define a structure to hold network information
96+
struct WiFiNetwork {
97+
char ssid[33]; // Maximum SSID length is 32 characters + null terminator
98+
int rssi;
99+
};
100+
101+
// Comparison function to sort by RSSI in descending order
102+
bool static compareByRSSI(const WiFiNetwork &a, const WiFiNetwork &b) {
103+
return a.rssi > b.rssi;
104+
}
105+
93106
/***********************************************************/
94107
/*!
95108
@brief Performs a scan of local WiFi networks.
@@ -116,41 +129,54 @@ class Wippersnapper_ESP32 : public Wippersnapper {
116129
// Perform a network scan
117130
int n = WiFi.scanNetworks();
118131
if (n == 0) {
119-
WS_DEBUG_PRINTLN("ERROR: No WiFi networks found!");
120-
return false;
132+
WS_DEBUG_PRINTLN("ERROR: No WiFi networks found!");
133+
return false;
121134
}
122135

123-
// Was the network within secrets.json found?
136+
// Dynamically allocate memory for the network list
137+
std::vector<WiFiNetwork> networks(n);
138+
139+
// Store the scanned networks in the vector
124140
for (int i = 0; i < n; ++i) {
125-
if (strcmp(_ssid, WiFi.SSID(i).c_str()) == 0) {
126-
WS_DEBUG_PRINT("SSID (");
127-
WS_DEBUG_PRINT(_ssid);
128-
WS_DEBUG_PRINT(") found! RSSI: ");
129-
WS_DEBUG_PRINTLN(WiFi.RSSI(i));
130-
return true;
131-
}
132-
if (WS._isWiFiMulti) {
133-
// multi network mode
134-
for (int j = 0; j < WS_MAX_ALT_WIFI_NETWORKS; j++) {
135-
if (strcmp(WS._multiNetworks[j].ssid, WiFi.SSID(i).c_str()) == 0) {
141+
strncpy(networks[i].ssid, WiFi.SSID(i).c_str(), sizeof(networks[i].ssid) - 1);
142+
networks[i].ssid[sizeof(networks[i].ssid) - 1] = '\0'; // Ensure null termination
143+
networks[i].rssi = WiFi.RSSI(i);
144+
}
145+
146+
// Sort the networks by RSSI in descending order
147+
std::sort(networks.begin(), networks.end(), compareByRSSI);
148+
149+
// Was the network within secrets.json found?
150+
for (const auto &network : networks) {
151+
if (strcmp(_ssid, network.ssid) == 0) {
136152
WS_DEBUG_PRINT("SSID (");
137-
WS_DEBUG_PRINT(WS._multiNetworks[j].ssid);
153+
WS_DEBUG_PRINT(_ssid);
138154
WS_DEBUG_PRINT(") found! RSSI: ");
139-
WS_DEBUG_PRINTLN(WiFi.RSSI(i));
155+
WS_DEBUG_PRINTLN(network.rssi);
140156
return true;
141-
}
142157
}
143-
}
158+
if (WS._isWiFiMulti) {
159+
// multi network mode
160+
for (int j = 0; j < WS_MAX_ALT_WIFI_NETWORKS; j++) {
161+
if (strcmp(WS._multiNetworks[j].ssid, network.ssid) == 0) {
162+
WS_DEBUG_PRINT("SSID (");
163+
WS_DEBUG_PRINT(WS._multiNetworks[j].ssid);
164+
WS_DEBUG_PRINT(") found! RSSI: ");
165+
WS_DEBUG_PRINTLN(network.rssi);
166+
return true;
167+
}
168+
}
169+
}
144170
}
145171

146172
// User-set network not found, print scan results to serial console
147173
WS_DEBUG_PRINTLN("ERROR: Your requested WiFi network was not found!");
148174
WS_DEBUG_PRINTLN("WipperSnapper found these WiFi networks: ");
149-
for (int i = 0; i < n; ++i) {
150-
WS_DEBUG_PRINT(WiFi.SSID(i));
151-
WS_DEBUG_PRINT(" ");
152-
WS_DEBUG_PRINT(WiFi.RSSI(i));
153-
WS_DEBUG_PRINTLN("dB");
175+
for (const auto &network : networks) {
176+
WS_DEBUG_PRINT(network.ssid);
177+
WS_DEBUG_PRINT(" ");
178+
WS_DEBUG_PRINT(network.rssi);
179+
WS_DEBUG_PRINTLN("dB");
154180
}
155181

156182
return false;

Diff for: src/network_interfaces/Wippersnapper_ESP8266.h

+37-8
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#define WIPPERSNAPPER_ESP8266_H
1919

2020
#ifdef ARDUINO_ARCH_ESP8266
21+
#include <vector>
22+
#include <algorithm>
2123
#include "Adafruit_MQTT.h"
2224
#include "Adafruit_MQTT_Client.h"
2325
#include "ESP8266WiFi.h"
@@ -113,6 +115,19 @@ class Wippersnapper_ESP8266 : public Wippersnapper {
113115
_pass = WS._config.network.pass;
114116
}
115117

118+
// Define a structure to hold network information
119+
struct WiFiNetwork
120+
{
121+
char ssid[33]; // Maximum SSID length is 32 characters + null terminator
122+
int rssi;
123+
};
124+
125+
// Comparison function to sort by RSSI in descending order
126+
bool static compareByRSSI(const WiFiNetwork &a, const WiFiNetwork &b)
127+
{
128+
return a.rssi > b.rssi;
129+
}
130+
116131
/***********************************************************/
117132
/*!
118133
@brief Performs a scan of local WiFi networks.
@@ -133,23 +148,36 @@ class Wippersnapper_ESP8266 : public Wippersnapper {
133148
return false;
134149
}
135150

136-
// Was the network within secrets.json found?
151+
// Dynamically allocate memory for the network list
152+
std::vector<WiFiNetwork> networks(n);
153+
154+
// Store the scanned networks in the vector
137155
for (int i = 0; i < n; ++i) {
138-
if (strcmp(_ssid, WiFi.SSID(i).c_str()) == 0) {
156+
strncpy(networks[i].ssid, WiFi.SSID(i).c_str(), sizeof(networks[i].ssid) - 1);
157+
networks[i].ssid[sizeof(networks[i].ssid) - 1] = '\0'; // Ensure null termination
158+
networks[i].rssi = WiFi.RSSI(i);
159+
}
160+
161+
// Sort the networks by RSSI in descending order
162+
std::sort(networks.begin(), networks.end(), compareByRSSI);
163+
164+
// Was the network within secrets.json found?
165+
for (const auto &network : networks) {
166+
if (strcmp(_ssid, network.ssid) == 0) {
139167
WS_DEBUG_PRINT("SSID (");
140168
WS_DEBUG_PRINT(_ssid);
141169
WS_DEBUG_PRINT(") found! RSSI: ");
142-
WS_DEBUG_PRINTLN(WiFi.RSSI(i));
170+
WS_DEBUG_PRINTLN(network.rssi);
143171
return true;
144172
}
145173
if (WS._isWiFiMulti) {
146174
// multi network mode
147175
for (int j = 0; j < WS_MAX_ALT_WIFI_NETWORKS; j++) {
148-
if (strcmp(WS._multiNetworks[j].ssid, WiFi.SSID(i).c_str()) == 0) {
176+
if (strcmp(WS._multiNetworks[j].ssid, network.ssid) == 0) {
149177
WS_DEBUG_PRINT("SSID (");
150178
WS_DEBUG_PRINT(WS._multiNetworks[j].ssid);
151179
WS_DEBUG_PRINT(") found! RSSI: ");
152-
WS_DEBUG_PRINTLN(WiFi.RSSI(i));
180+
WS_DEBUG_PRINTLN(network.rssi);
153181
return true;
154182
}
155183
}
@@ -159,10 +187,11 @@ class Wippersnapper_ESP8266 : public Wippersnapper {
159187
// User-set network not found, print scan results to serial console
160188
WS_DEBUG_PRINTLN("ERROR: Your requested WiFi network was not found!");
161189
WS_DEBUG_PRINTLN("WipperSnapper found these WiFi networks: ");
162-
for (int i = 0; i < n; ++i) {
163-
WS_DEBUG_PRINT(WiFi.SSID(i));
190+
for (const auto &network : networks)
191+
{
192+
WS_DEBUG_PRINT(network.ssid);
164193
WS_DEBUG_PRINT(" ");
165-
WS_DEBUG_PRINT(WiFi.RSSI(i));
194+
WS_DEBUG_PRINT(network.rssi);
166195
WS_DEBUG_PRINTLN("dB");
167196
}
168197

Diff for: src/network_interfaces/Wippersnapper_WIFININA.h

+46-15
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include <Adafruit_MQTT.h>
2020
#include <Adafruit_MQTT_Client.h>
2121
#include <Arduino.h>
22+
#include <vector>
23+
#include <algorithm>
2224
#include <SPI.h>
2325
#include <WiFiNINA.h>
2426

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

114+
115+
// Define a structure to hold network information
116+
struct WiFiNetwork
117+
{
118+
char ssid[33]; // Maximum SSID length is 32 characters + null terminator
119+
int rssi;
120+
};
121+
122+
// Comparison function to sort by RSSI in descending order
123+
bool static compareByRSSI(const WiFiNetwork &a, const WiFiNetwork &b)
124+
{
125+
return a.rssi > b.rssi;
126+
}
127+
112128
/***********************************************************/
113129
/*!
114-
@brief Performs a scan of local WiFi networks.
115-
@returns True if `_network_ssid` is found, False otherwise.
130+
@brief Performs a scan of local WiFi networks.
131+
@returns True if `_network_ssid` is found, False otherwise.
116132
*/
117133
/***********************************************************/
118134
bool check_valid_ssid() {
@@ -124,27 +140,42 @@ class Wippersnapper_WIFININA : public Wippersnapper {
124140
// Perform a network scan
125141
int n = WiFi.scanNetworks();
126142
if (n == 0) {
127-
WS_DEBUG_PRINTLN("ERROR: No WiFi networks found!");
128-
return false;
143+
WS_DEBUG_PRINTLN("ERROR: No WiFi networks found!");
144+
return false;
129145
}
130146

131-
// Was the network within secrets.json found?
147+
// Dynamically allocate memory for the network list
148+
std::vector<WiFiNetwork> networks(n);
149+
150+
// Store the scanned networks in the vector
132151
for (int i = 0; i < n; ++i) {
133-
if (strcmp(_ssid, WiFi.SSID(i)) == 0) {
134-
WS_DEBUG_PRINT("SSID found! RSSI: ");
135-
WS_DEBUG_PRINTLN(WiFi.RSSI(i));
136-
return true;
137-
}
152+
strncpy(networks[i].ssid, WiFi.SSID(i).c_str(), sizeof(networks[i].ssid) - 1);
153+
networks[i].ssid[sizeof(networks[i].ssid) - 1] = '\0'; // Ensure null termination
154+
networks[i].rssi = WiFi.RSSI(i);
155+
}
156+
157+
// Sort the networks by RSSI in descending order
158+
std::sort(networks.begin(), networks.end(), compareByRSSI);
159+
160+
// Was the network within secrets.json found?
161+
for (const auto &network : networks) {
162+
if (strcmp(_ssid, network.ssid) == 0) {
163+
WS_DEBUG_PRINT("SSID (");
164+
WS_DEBUG_PRINT(_ssid);
165+
WS_DEBUG_PRINT(") found! RSSI: ");
166+
WS_DEBUG_PRINTLN(network.rssi);
167+
return true;
168+
}
138169
}
139170

140171
// User-set network not found, print scan results to serial console
141172
WS_DEBUG_PRINTLN("ERROR: Your requested WiFi network was not found!");
142173
WS_DEBUG_PRINTLN("WipperSnapper found these WiFi networks: ");
143-
for (int i = 0; i < n; ++i) {
144-
WS_DEBUG_PRINT(WiFi.SSID(i));
145-
WS_DEBUG_PRINT(" ");
146-
WS_DEBUG_PRINT(WiFi.RSSI(i));
147-
WS_DEBUG_PRINTLN("dB");
174+
for (const auto &network : networks) {
175+
WS_DEBUG_PRINT(network.ssid);
176+
WS_DEBUG_PRINT(" ");
177+
WS_DEBUG_PRINT(network.rssi);
178+
WS_DEBUG_PRINTLN("dB");
148179
}
149180

150181
return false;

0 commit comments

Comments
 (0)