32
32
#endif
33
33
34
34
#ifndef MGOS_WIFI_STA_AP_HISTORY_SIZE
35
- #define MGOS_WIFI_STA_AP_HISTORY_SIZE 20
35
+ #define MGOS_WIFI_STA_AP_HISTORY_SIZE 25
36
36
#endif
37
37
38
38
#ifndef MGOS_WIFI_STA_ROAM_RSSI_HYST
39
39
#define MGOS_WIFI_STA_ROAM_RSSI_HYST 5
40
40
#endif
41
41
42
42
#ifndef MGOS_WIFI_STA_MAX_AP_QUEUE_LEN
43
- #define MGOS_WIFI_STA_MAX_AP_QUEUE_LEN 5
43
+ #define MGOS_WIFI_STA_MAX_AP_QUEUE_LEN 10
44
44
#endif
45
45
46
46
void wifi_lock (void );
@@ -205,7 +205,7 @@ static bool check_ap(const struct mgos_wifi_scan_result *e,
205
205
break ;
206
206
}
207
207
if (* sta_cfg == NULL ) {
208
- * reason = "no matching config " ;
208
+ * reason = "no cfg " ;
209
209
return false;
210
210
}
211
211
if (e -> rssi < mgos_sys_config_get_wifi_sta_rssi_thr ()) {
@@ -216,7 +216,7 @@ static bool check_ap(const struct mgos_wifi_scan_result *e,
216
216
if ((* hape )-> num_attempts >= MGOS_WIFI_STA_AP_ATTEMPTS &&
217
217
(mgos_uptime_micros () - (* hape )-> last_attempt <
218
218
(MGOS_WIFI_STA_FAILING_AP_RETRY_SECONDS * 1000000LL ))) {
219
- * reason = "bad history " ;
219
+ * reason = "bad" ;
220
220
return false;
221
221
}
222
222
}
@@ -233,20 +233,32 @@ static int get_cfg_index(const struct mgos_config_wifi_sta *cfg) {
233
233
234
234
static void mgos_wifi_sta_build_queue (int num_res ,
235
235
struct mgos_wifi_scan_result * res ,
236
- bool check_history ) {
237
- int i ;
238
- for (i = 0 ; i < num_res ; i ++ ) {
236
+ bool check_history , uint32_t * seen_cfg ) {
237
+ for (int i = 0 ; i < num_res ; i ++ ) {
239
238
const struct mgos_wifi_scan_result * e = & res [i ];
240
239
const struct mgos_config_wifi_sta * cfg = NULL ;
241
- int cfg_index = 0 ;
242
- const char * reason = NULL ;
243
- struct wifi_ap_entry * eape = NULL ;
244
- bool ok ;
245
- while (
246
- (ok = check_ap (e , & cfg , & cfg_index , check_history , & eape , & reason ))) {
240
+ int cfg_index = -1 ;
241
+ bool first = true;
242
+ while (true) {
243
+ const char * reason = NULL ;
244
+ struct wifi_ap_entry * eape = NULL ;
245
+ bool ok = check_ap (e , & cfg , & cfg_index , check_history , & eape , & reason );
246
+ if (ok || first ) {
247
+ LOG (LL_DEBUG ,
248
+ (" %d: SSID: %-32s, BSSID: %02x:%02x:%02x:%02x:%02x:%02x "
249
+ "auth: %d, ch: %3d, RSSI: %2d - %s cfg %d att %d" ,
250
+ i , e -> ssid , e -> bssid [0 ], e -> bssid [1 ], e -> bssid [2 ], e -> bssid [3 ],
251
+ e -> bssid [4 ], e -> bssid [5 ], e -> auth_mode , e -> channel , e -> rssi ,
252
+ reason , cfg_index , (eape ? eape -> num_attempts : -1 )));
253
+ }
254
+ if (cfg_index != -1 ) {
255
+ * seen_cfg |= (1 << cfg_index );
256
+ }
257
+ if (!ok ) break ;
258
+ first = false;
247
259
int len = 0 ;
248
260
struct wifi_ap_entry * pape = NULL ;
249
- /* Find a position in the queue for this AP. */
261
+ // Find a position in the queue for this AP.
250
262
struct wifi_ap_entry * ape = NULL ;
251
263
SLIST_FOREACH (ape , & s_ap_queue , next ) {
252
264
if (memcmp (ape -> bssid , e -> bssid , sizeof (e -> bssid )) == 0 &&
@@ -255,18 +267,17 @@ static void mgos_wifi_sta_build_queue(int num_res,
255
267
reason = "dup" ;
256
268
break ;
257
269
}
258
- /* Config index indicates preference: lower index = higher preference.
259
- */
270
+ // Config index indicates preference: lower index = higher preference.
260
271
int ape_cfg_index = get_cfg_index (ape -> cfg );
261
272
if (cfg_index != ape_cfg_index ) {
262
273
if (cfg_index > ape_cfg_index ) {
263
274
pape = ape ;
264
275
}
265
276
continue ;
266
277
}
267
- /* Among bad ones, prefer those with fewer attempts.
268
- * This will have the effect of cycling through all available ones
269
- * even when there are more than the queue can hold. */
278
+ // Among bad ones, prefer those with fewer attempts.
279
+ // This will have the effect of cycling through all available ones
280
+ // even when there are more than the queue can hold.
270
281
if (ape -> num_attempts >= MGOS_WIFI_STA_AP_ATTEMPTS && eape != NULL &&
271
282
eape -> num_attempts >= MGOS_WIFI_STA_AP_ATTEMPTS &&
272
283
eape -> num_attempts != ape -> num_attempts ) {
@@ -322,12 +333,6 @@ static void mgos_wifi_sta_build_queue(int num_res,
322
333
}
323
334
}
324
335
}
325
- LOG (LL_DEBUG ,
326
- (" %d: SSID: %-32s, BSSID: %02x:%02x:%02x:%02x:%02x:%02x "
327
- "auth: %d, ch: %3d, RSSI: %2d att %d - %d %s cfg %d" ,
328
- i , e -> ssid , e -> bssid [0 ], e -> bssid [1 ], e -> bssid [2 ], e -> bssid [3 ],
329
- e -> bssid [4 ], e -> bssid [5 ], e -> auth_mode , e -> channel , e -> rssi ,
330
- (eape ? eape -> num_attempts : -1 ), ok , reason , cfg_index ));
331
336
(void ) reason ;
332
337
}
333
338
}
@@ -341,11 +346,49 @@ void mgos_wifi_sta_scan_cb(int num_res, struct mgos_wifi_scan_result *res,
341
346
s_state = WIFI_STA_SCAN ;
342
347
return ;
343
348
}
344
- mgos_wifi_sta_build_queue (num_res , res , true /* check_history */ );
349
+ uint32_t seen_cfg = 0 ;
350
+ mgos_wifi_sta_build_queue (num_res , res , true /* check_history */ , & seen_cfg );
345
351
if (SLIST_EMPTY (& s_ap_queue )) {
346
- /* No good quality APs left to try, keep trying bad ones. */
347
- LOG (LL_DEBUG , ("Second pass" ));
348
- mgos_wifi_sta_build_queue (num_res , res , false /* check_history */ );
352
+ // No good quality APs left to try, keep trying bad ones.
353
+ LOG (LL_INFO , ("Second pass" ));
354
+ mgos_wifi_sta_build_queue (num_res , res , false /* check_history */ ,
355
+ & seen_cfg );
356
+ }
357
+ // If we found absolutely no APs for a config that is enabled,
358
+ // insert a non-specific entry in case it's a hidden SSID.
359
+ for (int cfg_index = 0 ; cfg_index < s_num_cfgs ; cfg_index ++ ) {
360
+ const struct mgos_config_wifi_sta * cfg = s_cfgs [cfg_index ];
361
+ if (!cfg -> enable ) continue ;
362
+ if (seen_cfg & (1 << cfg_index )) continue ;
363
+ bool found = false;
364
+ struct wifi_ap_entry * ape = NULL , * pape = NULL ;
365
+ SLIST_FOREACH (ape , & s_ap_queue , next ) {
366
+ if (ape -> cfg == cfg ) {
367
+ found = true;
368
+ break ;
369
+ }
370
+ int ape_cfg_index = get_cfg_index (ape -> cfg );
371
+ if (ape_cfg_index < cfg_index ) {
372
+ pape = ape ;
373
+ } else {
374
+ break ;
375
+ }
376
+ }
377
+ if (found ) continue ;
378
+ uint8_t bssid [6 ] = {0 };
379
+ struct wifi_ap_entry * eape = mgos_wifi_sta_find_history_entry (bssid , cfg );
380
+ if (eape == NULL ) {
381
+ eape = calloc (1 , sizeof (* eape ));
382
+ eape -> cfg = cfg ;
383
+ } else {
384
+ mgos_wifi_sta_remove_history_entry (eape );
385
+ }
386
+ if (eape == NULL ) return ;
387
+ if (pape != NULL ) {
388
+ SLIST_INSERT_AFTER (pape , eape , next );
389
+ } else {
390
+ SLIST_INSERT_HEAD (& s_ap_queue , eape , next );
391
+ }
349
392
}
350
393
if (!SLIST_EMPTY (& s_ap_queue )) {
351
394
int i = 0 ;
@@ -418,7 +461,8 @@ static void mgos_wifi_sta_run(int wifi_ev, void *ev_data, bool timeout) {
418
461
/* If we are roaming and have no good candidate, go back. */
419
462
int cur_rssi = mgos_wifi_sta_get_rssi ();
420
463
bool ok = false;
421
- if (ape == NULL ) {
464
+ s_rssi_info .val <<= 8 ;
465
+ if (ape == NULL || ape -> rssi == 0 ) {
422
466
LOG (LL_INFO , ("No candidate APs" ));
423
467
} else if (s_cur_entry != NULL && memcmp (s_cur_entry -> bssid , ape -> bssid ,
424
468
sizeof (ape -> bssid )) == 0 ) {
@@ -472,10 +516,12 @@ static void mgos_wifi_sta_run(int wifi_ev, void *ev_data, bool timeout) {
472
516
ape -> cfg -> ssid , bssid [0 ], bssid [1 ], bssid [2 ], bssid [3 ], bssid [4 ],
473
517
bssid [5 ], ape -> rssi , get_cfg_index (ape -> cfg ), ape -> num_attempts ));
474
518
ape -> last_attempt = mgos_uptime_micros ();
475
- char bssid_s [20 ];
476
- mgos_wifi_sta_bssid_to_str (bssid , bssid_s );
477
519
struct mgos_config_wifi_sta sta_cfg = * ape -> cfg ;
478
- sta_cfg .bssid = bssid_s ;
520
+ char bssid_s [20 ];
521
+ if (ape -> rssi != 0 ) {
522
+ sta_cfg .bssid = bssid_s ;
523
+ mgos_wifi_sta_bssid_to_str (bssid , bssid_s );
524
+ }
479
525
mgos_wifi_dev_sta_setup (& sta_cfg );
480
526
mgos_wifi_dev_sta_connect ();
481
527
s_state = WIFI_STA_CONNECTING ;
0 commit comments