diff options
Diffstat (limited to 'src/drivers')
| -rw-r--r-- | src/drivers/driver.h | 5 | ||||
| -rw-r--r-- | src/drivers/driver_nl80211.c | 11 | ||||
| -rw-r--r-- | src/drivers/driver_nl80211.h | 7 | ||||
| -rw-r--r-- | src/drivers/driver_nl80211_event.c | 64 | ||||
| -rw-r--r-- | src/drivers/driver_nl80211_scan.c | 2 |
5 files changed, 71 insertions, 18 deletions
diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 5f3c6ffd..31cb23f1 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -4387,6 +4387,9 @@ union wpa_event_data { * @ssids: Scanned SSIDs (%NULL or zero-length SSID indicates wildcard * SSID) * @num_ssids: Number of entries in ssids array + * @external_scan: Whether the scan info is for an external scan + * @nl_scan_event: 1 if the source of this scan event is a normal scan, + * 0 if the source of the scan event is a vendor scan */ struct scan_info { int aborted; @@ -4394,6 +4397,8 @@ union wpa_event_data { size_t num_freqs; struct wpa_driver_scan_ssid ssids[WPAS_MAX_SCAN_SSIDS]; size_t num_ssids; + int external_scan; + int nl_scan_event; } scan_info; /** diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 9d7d7e57..ded7950f 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -7260,6 +7260,17 @@ static int driver_nl80211_scan2(void *priv, struct wpa_driver_scan_params *params) { struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = bss->drv; + + /* + * Do a vendor specific scan if possible. If only_new_results is + * set, do a normal scan since a kernel (cfg80211) BSS cache flush + * cannot be achieved through a vendor scan. The below condition may + * need to be modified if new scan flags are added in the future whose + * functionality can only be achieved through a normal scan. + */ + if (drv->scan_vendor_cmd_avail && !params->only_new_results) + return wpa_driver_nl80211_vendor_scan(bss, params); return wpa_driver_nl80211_scan(bss, params); } diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h index d1cbaeff..e2df8b43 100644 --- a/src/drivers/driver_nl80211.h +++ b/src/drivers/driver_nl80211.h @@ -187,6 +187,13 @@ struct wpa_driver_nl80211_data { int auth_wep_tx_keyidx; int auth_local_state_change; int auth_p2p; + + /* + * Tells whether the last scan issued from wpa_supplicant was a normal + * scan (NL80211_CMD_TRIGGER_SCAN) or a vendor scan + * (NL80211_CMD_VENDOR). 0 if no pending scan request. + */ + int last_scan_cmd; }; struct nl_msg; diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c index 647280c8..5f2811ce 100644 --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c @@ -968,7 +968,7 @@ static void mlme_event_ft_event(struct wpa_driver_nl80211_data *drv, static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted, - struct nlattr *tb[]) + struct nlattr *tb[], int external_scan) { union wpa_event_data event; struct nlattr *nl; @@ -978,7 +978,7 @@ static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted, int freqs[MAX_REPORT_FREQS]; int num_freqs = 0; - if (drv->scan_for_auth) { + if (!external_scan && drv->scan_for_auth) { drv->scan_for_auth = 0; wpa_printf(MSG_DEBUG, "nl80211: Scan results for missing " "cfg80211 BSS entry"); @@ -989,6 +989,8 @@ static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted, os_memset(&event, 0, sizeof(event)); info = &event.scan_info; info->aborted = aborted; + info->external_scan = external_scan; + info->nl_scan_event = 1; if (tb[NL80211_ATTR_SCAN_SSIDS]) { nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_SSIDS], rem) { @@ -1691,6 +1693,8 @@ static void qca_nl80211_scan_trigger_event(struct wpa_driver_nl80211_data *drv, { struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1]; u64 cookie = 0; + union wpa_event_data event; + struct scan_info *info; if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX, (struct nlattr *) data, len, NULL) || @@ -1703,13 +1707,20 @@ static void qca_nl80211_scan_trigger_event(struct wpa_driver_nl80211_data *drv, return; } + /* Cookie match, own scan */ + os_memset(&event, 0, sizeof(event)); + info = &event.scan_info; + info->external_scan = 0; + info->nl_scan_event = 0; + drv->scan_state = SCAN_STARTED; - wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, NULL); + wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, &event); } static void send_vendor_scan_event(struct wpa_driver_nl80211_data *drv, - int aborted, struct nlattr *tb[]) + int aborted, struct nlattr *tb[], + int external_scan) { union wpa_event_data event; struct nlattr *nl; @@ -1721,6 +1732,7 @@ static void send_vendor_scan_event(struct wpa_driver_nl80211_data *drv, os_memset(&event, 0, sizeof(event)); info = &event.scan_info; info->aborted = aborted; + info->external_scan = external_scan; if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS]) { nla_for_each_nested(nl, @@ -1774,6 +1786,7 @@ static void qca_nl80211_scan_done_event(struct wpa_driver_nl80211_data *drv, struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1]; u64 cookie = 0; enum scan_status status; + int external_scan; if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX, (struct nlattr *) data, len, NULL) || @@ -1788,7 +1801,9 @@ static void qca_nl80211_scan_done_event(struct wpa_driver_nl80211_data *drv, cookie = nla_get_u64(tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]); if (cookie != drv->vendor_scan_cookie) { /* Event from an external scan, get scan results */ + external_scan = 1; } else { + external_scan = 0; if (status == VENDOR_SCAN_STATUS_NEW_RESULTS) drv->scan_state = SCAN_COMPLETED; else @@ -1797,9 +1812,11 @@ static void qca_nl80211_scan_done_event(struct wpa_driver_nl80211_data *drv, eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx); drv->vendor_scan_cookie = 0; + drv->last_scan_cmd = 0; } - send_vendor_scan_event(drv, (status == VENDOR_SCAN_STATUS_ABORTED), tb); + send_vendor_scan_event(drv, (status == VENDOR_SCAN_STATUS_ABORTED), tb, + external_scan); } @@ -1954,6 +1971,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, { struct wpa_driver_nl80211_data *drv = bss->drv; union wpa_event_data data; + int external_scan_event = 0; wpa_printf(MSG_DEBUG, "nl80211: Drv Event %d (%s) received for %s", cmd, nl80211_command_to_string(cmd), bss->ifname); @@ -2006,28 +2024,38 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, case NL80211_CMD_NEW_SCAN_RESULTS: wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: New scan results available"); - drv->scan_state = SCAN_COMPLETED; drv->scan_complete_events = 1; - eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, - drv->ctx); - send_scan_event(drv, 0, tb); + if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) { + drv->scan_state = SCAN_COMPLETED; + eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, + drv, drv->ctx); + drv->last_scan_cmd = 0; + } else { + external_scan_event = 1; + } + send_scan_event(drv, 0, tb, external_scan_event); break; case NL80211_CMD_SCHED_SCAN_RESULTS: wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: New sched scan results available"); drv->scan_state = SCHED_SCAN_RESULTS; - send_scan_event(drv, 0, tb); + send_scan_event(drv, 0, tb, 0); break; case NL80211_CMD_SCAN_ABORTED: wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan aborted"); - drv->scan_state = SCAN_ABORTED; - /* - * Need to indicate that scan results are available in order - * not to make wpa_supplicant stop its scanning. - */ - eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, - drv->ctx); - send_scan_event(drv, 1, tb); + if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) { + drv->scan_state = SCAN_ABORTED; + /* + * Need to indicate that scan results are available in + * order not to make wpa_supplicant stop its scanning. + */ + eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, + drv, drv->ctx); + drv->last_scan_cmd = 0; + } else { + external_scan_event = 1; + } + send_scan_event(drv, 1, tb, external_scan_event); break; case NL80211_CMD_AUTHENTICATE: case NL80211_CMD_ASSOCIATE: diff --git a/src/drivers/driver_nl80211_scan.c b/src/drivers/driver_nl80211_scan.c index 99e12e74..a8ce7ea8 100644 --- a/src/drivers/driver_nl80211_scan.c +++ b/src/drivers/driver_nl80211_scan.c @@ -295,6 +295,7 @@ int wpa_driver_nl80211_scan(struct i802_bss *bss, eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx); eloop_register_timeout(timeout, 0, wpa_driver_nl80211_scan_timeout, drv, drv->ctx); + drv->last_scan_cmd = NL80211_CMD_TRIGGER_SCAN; fail: nlmsg_free(msg); @@ -979,6 +980,7 @@ int wpa_driver_nl80211_vendor_scan(struct i802_bss *bss, eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx); eloop_register_timeout(30, 0, wpa_driver_nl80211_scan_timeout, drv, drv->ctx); + drv->last_scan_cmd = NL80211_CMD_VENDOR; fail: nlmsg_free(msg); |
