RRM: Enable beacon report with active/passive scan for all drivers

The requested behavior can be approximated for most use cases even if
the driver does not support reporting exact TSF values for frames.
Enable this capability for all drivers to make beacon report processing
more useful for a common use case.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2017-01-02 23:04:02 +02:00
parent 42b0982376
commit d734201435
5 changed files with 75 additions and 13 deletions

View file

@ -269,7 +269,7 @@ struct wpa_bss * wpa_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid,
} }
static void calculate_update_time(const struct os_reltime *fetch_time, void calculate_update_time(const struct os_reltime *fetch_time,
unsigned int age_ms, unsigned int age_ms,
struct os_reltime *update_time) struct os_reltime *update_time)
{ {

View file

@ -168,4 +168,8 @@ static inline void wpa_bss_update_level(struct wpa_bss *bss, int new_level)
bss->level = new_level; bss->level = new_level;
} }
void calculate_update_time(const struct os_reltime *fetch_time,
unsigned int age_ms,
struct os_reltime *update_time);
#endif /* BSS_H */ #endif /* BSS_H */

View file

@ -900,13 +900,22 @@ static void wpas_rrm_scan_timeout(void *eloop_ctx, void *timeout_ctx)
struct wpa_supplicant *wpa_s = eloop_ctx; struct wpa_supplicant *wpa_s = eloop_ctx;
struct wpa_driver_scan_params *params = struct wpa_driver_scan_params *params =
&wpa_s->beacon_rep_data.scan_params; &wpa_s->beacon_rep_data.scan_params;
u16 prev_duration = params->duration;
if (!wpa_s->current_bss) if (!wpa_s->current_bss)
return; return;
if (!(wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_SUPPORT_SET_SCAN_DWELL) &&
params->duration) {
wpa_printf(MSG_DEBUG,
"RRM: Cannot set scan duration due to missing driver support");
params->duration = 0;
}
os_get_reltime(&wpa_s->beacon_rep_scan);
if (wpa_s->scanning || wpas_p2p_in_progress(wpa_s) || if (wpa_s->scanning || wpas_p2p_in_progress(wpa_s) ||
wpa_supplicant_trigger_scan(wpa_s, params)) wpa_supplicant_trigger_scan(wpa_s, params))
wpas_rrm_refuse_request(wpa_s); wpas_rrm_refuse_request(wpa_s);
params->duration = prev_duration;
} }
@ -1033,8 +1042,9 @@ wpas_rm_handle_beacon_req(struct wpa_supplicant *wpa_s,
if (len < sizeof(*req)) if (len < sizeof(*req))
return -1; return -1;
if (req->mode != BEACON_REPORT_MODE_TABLE && if (req->mode != BEACON_REPORT_MODE_PASSIVE &&
!(wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_SUPPORT_BEACON_REPORT)) req->mode != BEACON_REPORT_MODE_ACTIVE &&
req->mode != BEACON_REPORT_MODE_TABLE)
return 0; return 0;
subelems = req->variable; subelems = req->variable;
@ -1142,6 +1152,13 @@ wpas_rrm_handle_msr_req_element(
case MEASURE_TYPE_LCI: case MEASURE_TYPE_LCI:
return wpas_rrm_build_lci_report(wpa_s, req, buf); return wpas_rrm_build_lci_report(wpa_s, req, buf);
case MEASURE_TYPE_BEACON: case MEASURE_TYPE_BEACON:
if (duration_mandatory &&
!(wpa_s->drv_rrm_flags &
WPA_DRIVER_FLAGS_SUPPORT_SET_SCAN_DWELL)) {
wpa_printf(MSG_DEBUG,
"RRM: Driver does not support dwell time configuration - reject beacon report with mandatory duration");
goto reject;
}
return wpas_rm_handle_beacon_req(wpa_s, req->token, return wpas_rm_handle_beacon_req(wpa_s, req->token,
duration_mandatory, duration_mandatory,
(const void *) req->variable, (const void *) req->variable,
@ -1341,9 +1358,13 @@ int wpas_beacon_rep_scan_process(struct wpa_supplicant *wpa_s,
wpa_printf(MSG_DEBUG, "RRM: TSF BSSID: " MACSTR " current BSS: " MACSTR, wpa_printf(MSG_DEBUG, "RRM: TSF BSSID: " MACSTR " current BSS: " MACSTR,
MAC2STR(info->scan_start_tsf_bssid), MAC2STR(info->scan_start_tsf_bssid),
MAC2STR(wpa_s->current_bss->bssid)); MAC2STR(wpa_s->current_bss->bssid));
if (os_memcmp(info->scan_start_tsf_bssid, wpa_s->current_bss->bssid, if ((wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_SUPPORT_BEACON_REPORT) &&
ETH_ALEN) != 0) os_memcmp(info->scan_start_tsf_bssid, wpa_s->current_bss->bssid,
ETH_ALEN) != 0) {
wpa_printf(MSG_DEBUG,
"RRM: Ignore scan results due to mismatching TSF BSSID");
goto out; goto out;
}
for (i = 0; i < scan_res->num; i++) { for (i = 0; i < scan_res->num; i++) {
struct wpa_bss *bss = struct wpa_bss *bss =
@ -1352,9 +1373,45 @@ int wpas_beacon_rep_scan_process(struct wpa_supplicant *wpa_s,
if (!bss) if (!bss)
continue; continue;
if (os_memcmp(scan_res->res[i]->tsf_bssid, if ((wpa_s->drv_rrm_flags &
wpa_s->current_bss->bssid, ETH_ALEN) != 0) WPA_DRIVER_FLAGS_SUPPORT_BEACON_REPORT) &&
os_memcmp(scan_res->res[i]->tsf_bssid,
wpa_s->current_bss->bssid, ETH_ALEN) != 0) {
wpa_printf(MSG_DEBUG,
"RRM: Ignore scan result for " MACSTR
" due to mismatching TSF BSSID" MACSTR,
MAC2STR(scan_res->res[i]->bssid),
MAC2STR(scan_res->res[i]->tsf_bssid));
continue; continue;
}
if (!(wpa_s->drv_rrm_flags &
WPA_DRIVER_FLAGS_SUPPORT_BEACON_REPORT)) {
struct os_reltime update_time, diff;
/* For now, allow 8 ms older results due to some
* unknown issue with cfg80211 BSS table updates during
* a scan with the current BSS.
* TODO: Fix this more properly to avoid having to have
* this type of hacks in place. */
calculate_update_time(&scan_res->fetch_time,
scan_res->res[i]->age,
&update_time);
os_reltime_sub(&wpa_s->beacon_rep_scan,
&update_time, &diff);
if (os_reltime_before(&update_time,
&wpa_s->beacon_rep_scan) &&
(diff.sec || diff.usec >= 8000)) {
wpa_printf(MSG_DEBUG,
"RRM: Ignore scan result for " MACSTR
" due to old update (age(ms) %u, calculated age %u.%06u seconds)",
MAC2STR(scan_res->res[i]->bssid),
scan_res->res[i]->age,
(unsigned int) diff.sec,
(unsigned int) diff.usec);
continue;
}
}
/* /*
* Don't report results that were not received during the * Don't report results that were not received during the

View file

@ -187,10 +187,9 @@ static void sme_auth_handle_rrm(struct wpa_supplicant *wpa_s,
if (wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_TX_POWER_INSERTION) if (wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_TX_POWER_INSERTION)
*pos |= WLAN_RRM_CAPS_LINK_MEASUREMENT; *pos |= WLAN_RRM_CAPS_LINK_MEASUREMENT;
if (wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_SUPPORT_BEACON_REPORT)
*pos |= WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE | *pos |= WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE |
WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE; WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE |
*pos |= WLAN_RRM_CAPS_BEACON_REPORT_TABLE; WLAN_RRM_CAPS_BEACON_REPORT_TABLE;
if (wpa_s->lci) if (wpa_s->lci)
pos[1] |= WLAN_RRM_CAPS_LCI_MEASUREMENT; pos[1] |= WLAN_RRM_CAPS_LCI_MEASUREMENT;

View file

@ -1092,6 +1092,8 @@ struct wpa_supplicant {
*/ */
struct wpabuf *lci; struct wpabuf *lci;
struct os_reltime lci_time; struct os_reltime lci_time;
struct os_reltime beacon_rep_scan;
}; };