Skip to content

Commit 634841f

Browse files
committed
Support connecting to hidden networks
If no APs found, add a non-specific entry and let the library handle connection to a hidden SSID.
1 parent eb4e9d6 commit 634841f

File tree

1 file changed

+79
-33
lines changed

1 file changed

+79
-33
lines changed

src/mgos_wifi_sta.c

+79-33
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@
3232
#endif
3333

3434
#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
3636
#endif
3737

3838
#ifndef MGOS_WIFI_STA_ROAM_RSSI_HYST
3939
#define MGOS_WIFI_STA_ROAM_RSSI_HYST 5
4040
#endif
4141

4242
#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
4444
#endif
4545

4646
void wifi_lock(void);
@@ -205,7 +205,7 @@ static bool check_ap(const struct mgos_wifi_scan_result *e,
205205
break;
206206
}
207207
if (*sta_cfg == NULL) {
208-
*reason = "no matching config";
208+
*reason = "no cfg";
209209
return false;
210210
}
211211
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,
216216
if ((*hape)->num_attempts >= MGOS_WIFI_STA_AP_ATTEMPTS &&
217217
(mgos_uptime_micros() - (*hape)->last_attempt <
218218
(MGOS_WIFI_STA_FAILING_AP_RETRY_SECONDS * 1000000LL))) {
219-
*reason = "bad history";
219+
*reason = "bad";
220220
return false;
221221
}
222222
}
@@ -233,20 +233,32 @@ static int get_cfg_index(const struct mgos_config_wifi_sta *cfg) {
233233

234234
static void mgos_wifi_sta_build_queue(int num_res,
235235
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++) {
239238
const struct mgos_wifi_scan_result *e = &res[i];
240239
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;
247259
int len = 0;
248260
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.
250262
struct wifi_ap_entry *ape = NULL;
251263
SLIST_FOREACH(ape, &s_ap_queue, next) {
252264
if (memcmp(ape->bssid, e->bssid, sizeof(e->bssid)) == 0 &&
@@ -255,18 +267,17 @@ static void mgos_wifi_sta_build_queue(int num_res,
255267
reason = "dup";
256268
break;
257269
}
258-
/* Config index indicates preference: lower index = higher preference.
259-
*/
270+
// Config index indicates preference: lower index = higher preference.
260271
int ape_cfg_index = get_cfg_index(ape->cfg);
261272
if (cfg_index != ape_cfg_index) {
262273
if (cfg_index > ape_cfg_index) {
263274
pape = ape;
264275
}
265276
continue;
266277
}
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.
270281
if (ape->num_attempts >= MGOS_WIFI_STA_AP_ATTEMPTS && eape != NULL &&
271282
eape->num_attempts >= MGOS_WIFI_STA_AP_ATTEMPTS &&
272283
eape->num_attempts != ape->num_attempts) {
@@ -322,12 +333,6 @@ static void mgos_wifi_sta_build_queue(int num_res,
322333
}
323334
}
324335
}
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));
331336
(void) reason;
332337
}
333338
}
@@ -341,11 +346,49 @@ void mgos_wifi_sta_scan_cb(int num_res, struct mgos_wifi_scan_result *res,
341346
s_state = WIFI_STA_SCAN;
342347
return;
343348
}
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);
345351
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+
}
349392
}
350393
if (!SLIST_EMPTY(&s_ap_queue)) {
351394
int i = 0;
@@ -418,7 +461,8 @@ static void mgos_wifi_sta_run(int wifi_ev, void *ev_data, bool timeout) {
418461
/* If we are roaming and have no good candidate, go back. */
419462
int cur_rssi = mgos_wifi_sta_get_rssi();
420463
bool ok = false;
421-
if (ape == NULL) {
464+
s_rssi_info.val <<= 8;
465+
if (ape == NULL || ape->rssi == 0) {
422466
LOG(LL_INFO, ("No candidate APs"));
423467
} else if (s_cur_entry != NULL && memcmp(s_cur_entry->bssid, ape->bssid,
424468
sizeof(ape->bssid)) == 0) {
@@ -472,10 +516,12 @@ static void mgos_wifi_sta_run(int wifi_ev, void *ev_data, bool timeout) {
472516
ape->cfg->ssid, bssid[0], bssid[1], bssid[2], bssid[3], bssid[4],
473517
bssid[5], ape->rssi, get_cfg_index(ape->cfg), ape->num_attempts));
474518
ape->last_attempt = mgos_uptime_micros();
475-
char bssid_s[20];
476-
mgos_wifi_sta_bssid_to_str(bssid, bssid_s);
477519
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+
}
479525
mgos_wifi_dev_sta_setup(&sta_cfg);
480526
mgos_wifi_dev_sta_connect();
481527
s_state = WIFI_STA_CONNECTING;

0 commit comments

Comments
 (0)