Skip to content

Commit 4cbce10

Browse files
authored
Add support for hidden networks in WiFiMulti (#9202)
* Add support for hidden networks in WiFiMulti * Update WiFiMulti.cpp * Update WiFiMulti.cpp
1 parent d14873a commit 4cbce10

File tree

2 files changed

+65
-13
lines changed

2 files changed

+65
-13
lines changed

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

+64-12
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,10 @@ bool WiFiMulti::addAP(const char* ssid, const char *passphrase)
9090
return true;
9191
}
9292

93-
uint8_t WiFiMulti::run(uint32_t connectTimeout)
93+
uint8_t WiFiMulti::run(uint32_t connectTimeout, bool scanHidden)
9494
{
9595
int8_t scanResult;
96+
unsigned long startTime;
9697
uint8_t status = WiFi.status();
9798
if(status == WL_CONNECTED) {
9899
if (!_bWFMInit && _connectionTestCBFunc != NULL){
@@ -116,13 +117,13 @@ uint8_t WiFiMulti::run(uint32_t connectTimeout)
116117
status = WiFi.status();
117118
}
118119

119-
scanResult = WiFi.scanNetworks();
120+
scanResult = WiFi.scanNetworks(false, scanHidden);
120121
if (scanResult == WIFI_SCAN_RUNNING) {
121122
// scan is running
122123
return WL_NO_SSID_AVAIL;
123124
} else if (scanResult >= 0) {
124125
// scan done analyze
125-
int32_t bestIndex = 0;
126+
int32_t bestIndex = -1;
126127
WifiAPlist_t bestNetwork { NULL, NULL, false };
127128
int bestNetworkDb = INT_MIN;
128129
int bestNetworkSec = WIFI_AUTH_MAX;
@@ -145,8 +146,10 @@ uint8_t WiFiMulti::run(uint32_t connectTimeout)
145146
uint8_t sec_scan;
146147
uint8_t* BSSID_scan;
147148
int32_t chan_scan;
149+
bool hidden_scan;
148150

149151
WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan);
152+
hidden_scan = (ssid_scan.length() == 0) && scanHidden;
150153
// add any Open WiFi AP to the list, if allowed with setAllowOpenAP(true)
151154
if (_bAllowOpenAP && sec_scan == WIFI_AUTH_OPEN){
152155
bool found = false;
@@ -163,14 +166,49 @@ uint8_t WiFiMulti::run(uint32_t connectTimeout)
163166
}
164167
}
165168

169+
if (hidden_scan) {
170+
log_v("hidden ssid on channel %d found, trying to connect with known credentials...", chan_scan);
171+
}
172+
166173
bool known = false;
167174
for(uint32_t x = 0; x < APlist.size(); x++) {
168175
WifiAPlist_t entry = APlist[x];
169176

170-
if(ssid_scan == entry.ssid) { // SSID match
171-
log_v("known ssid: %s, has failed: %s", entry.ssid, entry.hasFailed ? "yes" : "no");
172-
foundCount++;
173-
if (!entry.hasFailed){
177+
if(ssid_scan == entry.ssid || hidden_scan) { // SSID match or hidden network found
178+
if (!hidden_scan) {
179+
log_v("known ssid: %s, has failed: %s", entry.ssid, entry.hasFailed ? "yes" : "no");
180+
foundCount++;
181+
}
182+
if (!entry.hasFailed) {
183+
if (hidden_scan) {
184+
WiFi.begin(entry.ssid, entry.passphrase, chan_scan, BSSID_scan);
185+
186+
// If the ssid returned from the scan is empty, it is a hidden SSID
187+
// it appears that the WiFi.begin() function is asynchronous and takes
188+
// additional time to connect to a hidden SSID. Therefore a delay of 1000ms
189+
// is added for hidden SSIDs before calling WiFi.status()
190+
delay(1000);
191+
192+
status = WiFi.status();
193+
startTime = millis();
194+
195+
while (status != WL_CONNECTED && (millis() - startTime) <= connectTimeout)
196+
{
197+
delay(10);
198+
status = WiFi.status();
199+
}
200+
201+
WiFi.disconnect();
202+
delay(10);
203+
204+
if (status == WL_CONNECTED) {
205+
log_v("hidden ssid %s found", entry.ssid);
206+
ssid_scan = entry.ssid;
207+
foundCount++;
208+
} else {
209+
continue;
210+
}
211+
}
174212
known = true;
175213
log_v("rssi_scan: %d, bestNetworkDb: %d", rssi_scan, bestNetworkDb);
176214
if(rssi_scan > bestNetworkDb) { // best network
@@ -191,10 +229,24 @@ uint8_t WiFiMulti::run(uint32_t connectTimeout)
191229
}
192230
}
193231

194-
if(known) {
195-
log_d(" ---> %d: [%d][%02X:%02X:%02X:%02X:%02X:%02X] %s (%d) %c", i, chan_scan, BSSID_scan[0], BSSID_scan[1], BSSID_scan[2], BSSID_scan[3], BSSID_scan[4], BSSID_scan[5], ssid_scan.c_str(), rssi_scan, (sec_scan == WIFI_AUTH_OPEN) ? ' ' : '*');
232+
if (known) {
233+
log_d(" ---> %d: [%d][%02X:%02X:%02X:%02X:%02X:%02X] %s (%d) (%c) (%s)",
234+
i,
235+
chan_scan,
236+
BSSID_scan[0], BSSID_scan[1], BSSID_scan[2], BSSID_scan[3], BSSID_scan[4], BSSID_scan[5],
237+
ssid_scan.c_str(),
238+
rssi_scan,
239+
(sec_scan == WIFI_AUTH_OPEN) ? ' ' : '*',
240+
(hidden_scan) ? "hidden" : "visible");
196241
} else {
197-
log_d(" %d: [%d][%02X:%02X:%02X:%02X:%02X:%02X] %s (%d) %c", i, chan_scan, BSSID_scan[0], BSSID_scan[1], BSSID_scan[2], BSSID_scan[3], BSSID_scan[4], BSSID_scan[5], ssid_scan.c_str(), rssi_scan, (sec_scan == WIFI_AUTH_OPEN) ? ' ' : '*');
242+
log_d(" %d: [%d][%02X:%02X:%02X:%02X:%02X:%02X] %s (%d) (%c) (%s)",
243+
i,
244+
chan_scan,
245+
BSSID_scan[0], BSSID_scan[1], BSSID_scan[2], BSSID_scan[3], BSSID_scan[4], BSSID_scan[5],
246+
ssid_scan.c_str(),
247+
rssi_scan,
248+
(sec_scan == WIFI_AUTH_OPEN) ? ' ' : '*',
249+
(hidden_scan) ? "hidden" : "visible");
198250
}
199251
}
200252
log_v("foundCount = %d, failCount = %d", foundCount, failCount);
@@ -206,7 +258,7 @@ uint8_t WiFiMulti::run(uint32_t connectTimeout)
206258
// clean up ram
207259
WiFi.scanDelete();
208260

209-
if(bestNetwork.ssid) {
261+
if(bestIndex >= 0) {
210262
log_i("[WIFI] Connecting BSSID: %02X:%02X:%02X:%02X:%02X:%02X SSID: %s Channel: %d (%d)", bestBSSID[0], bestBSSID[1], bestBSSID[2], bestBSSID[3], bestBSSID[4], bestBSSID[5], bestNetwork.ssid, bestChannel, bestNetworkDb);
211263

212264
if (ipv6_support == true) {
@@ -218,7 +270,7 @@ uint8_t WiFiMulti::run(uint32_t connectTimeout)
218270
status = WiFi.status();
219271
_bWFMInit = true;
220272

221-
auto startTime = millis();
273+
startTime = millis();
222274
// wait for connection, fail, or timeout
223275
while(status != WL_CONNECTED && (millis() - startTime) <= connectTimeout) { // && status != WL_NO_SSID_AVAIL && status != WL_CONNECT_FAILED
224276
delay(10);

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class WiFiMulti
4444
~WiFiMulti();
4545

4646
bool addAP(const char* ssid, const char *passphrase = NULL);
47-
uint8_t run(uint32_t connectTimeout=5000);
47+
uint8_t run(uint32_t connectTimeout=5000, bool scanHidden=false);
4848
void enableIPv6(bool state);
4949

5050
// Force (default: true) to only keep connected or to connect to an AP from the provided WiFiMulti list.

0 commit comments

Comments
 (0)