@@ -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 );
0 commit comments