static int bgscan_learn_load(struct bgscan_learn_data *data) { FILE *f; char buf[128]; struct bgscan_learn_bss *bss; if (data->fname == NULL) { return 0; } f = fopen(data->fname, "r"); if (f == NULL) { return 0; } wpa_printf(MSG_DEBUG, "bgscan learn: Loading data from %s", data->fname); if (fgets(buf, sizeof(buf), f) == NULL || os_strncmp(buf, "wpa_supplicant-bgscan-learn\n", 28) != 0) { wpa_printf(MSG_INFO, "bgscan learn: Invalid data file %s", data->fname); fclose(f); return -1; } while (fgets(buf, sizeof(buf), f)) { if (os_strncmp(buf, "BSS ", 4) == 0) { bss = os_zalloc(sizeof(*bss)); if (!bss) { continue; } if (hwaddr_aton(buf + 4, bss->bssid) < 0) { bss_free(bss); continue; } bss->freq = atoi(buf + 4 + 18); dl_list_add(&data->bss, &bss->list); wpa_printf(MSG_DEBUG, "bgscan learn: Loaded BSS " "entry: " MACSTR " freq=%d", MAC2STR(bss->bssid), bss->freq); } if (os_strncmp(buf, "NEIGHBOR ", 9) == 0) { u8 addr[ETH_ALEN]; if (hwaddr_aton(buf + 9, addr) < 0) { continue; } bss = bgscan_learn_get_bss(data, addr); if (bss == NULL) { continue; } if (hwaddr_aton(buf + 9 + 18, addr) < 0) { continue; } bgscan_learn_add_neighbor(bss, addr); } } fclose(f); return 0; }
static int bgscan_learn_notify_scan(void *priv, struct wpa_scan_results *scan_res) { struct bgscan_learn_data *data = priv; size_t i, j; #define MAX_BSS 50 u8 bssid[MAX_BSS * ETH_ALEN]; size_t num_bssid = 0; wpa_printf(MSG_DEBUG, "bgscan learn: scan result notification"); eloop_cancel_timeout(bgscan_learn_timeout, data, NULL); eloop_register_timeout(data->scan_interval, 0, bgscan_learn_timeout, data, NULL); for (i = 0; i < scan_res->num; i++) { struct wpa_scan_res *res = scan_res->res[i]; if (!bgscan_learn_bss_match(data, res)) continue; if (num_bssid < MAX_BSS) { os_memcpy(bssid + num_bssid * ETH_ALEN, res->bssid, ETH_ALEN); num_bssid++; } } wpa_printf(MSG_DEBUG, "bgscan learn: %u matching BSSes in scan " "results", (unsigned int) num_bssid); for (i = 0; i < scan_res->num; i++) { struct wpa_scan_res *res = scan_res->res[i]; struct bgscan_learn_bss *bss; if (!bgscan_learn_bss_match(data, res)) continue; bss = bgscan_learn_get_bss(data, res->bssid); if (bss && bss->freq != res->freq) { wpa_printf(MSG_DEBUG, "bgscan learn: Update BSS " MACSTR " freq %d -> %d", MAC2STR(res->bssid), bss->freq, res->freq); bss->freq = res->freq; } else if (!bss) { wpa_printf(MSG_DEBUG, "bgscan learn: Add BSS " MACSTR " freq=%d", MAC2STR(res->bssid), res->freq); bss = os_zalloc(sizeof(*bss)); if (!bss) continue; os_memcpy(bss->bssid, res->bssid, ETH_ALEN); bss->freq = res->freq; dl_list_add(&data->bss, &bss->list); } for (j = 0; j < num_bssid; j++) { u8 *addr = bssid + j * ETH_ALEN; bgscan_learn_add_neighbor(bss, addr); } } /* * A more advanced bgscan could process scan results internally, select * the BSS and request roam if needed. This sample uses the existing * BSS/ESS selection routine. Change this to return 1 if selection is * done inside the bgscan module. */ return 0; }