@@ -36,6 +36,7 @@ struct wpa_scan_res;
* @level: signal level
* @tsf: Timestamp of last Beacon/Probe Response frame
* @last_update: Time of the last update (i.e., Beacon or Probe Response RX)
+ * @obss_scan_int: OBSS scan interval in seconds (host byte order)
* @ie_len: length of the following IE field in octets (from Probe Response)
* @beacon_ie_len: length of the following Beacon IE field in octets
*
@@ -69,6 +70,8 @@ struct wpa_bss {
struct wpabuf *anqp_3gpp;
struct wpabuf *anqp_domain_name;
#endif /* CONFIG_INTERWORKING */
+ u8 sched_obss_scan;
+ u16 obss_scan_int;
size_t ie_len;
size_t beacon_ie_len;
/* followed by ie_len octets of IEs */
@@ -1096,11 +1096,10 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
selected = wpa_supplicant_pick_network(wpa_s, scan_res, &ssid);
- /*
- * TODO: This should be done at the completion of OBSS scan operations
- * which may or may not be identical to other scans..
- */
- sme_proc_40mhz_intolerant(wpa_s);
+ if (wpa_s->current_bss && wpa_s->current_bss->sched_obss_scan) {
+ wpa_s->current_bss->sched_obss_scan = 0;
+ sme_proc_40mhz_intolerant(wpa_s);
+ }
if (selected) {
int skip;
@@ -760,6 +760,46 @@ void sme_proc_40mhz_intolerant(struct wpa_supplicant *wpa_s)
num_channels, num_intol);
}
+static void sme_obss_scan_timeout(void *eloop_ctx, void *timeout_ctx)
+{
+ struct wpa_supplicant *wpa_s = eloop_ctx;
+ struct wpa_driver_scan_params params;
+
+ if (!wpa_s->current_bss) {
+ wpa_printf(MSG_DEBUG, "SME OBSS: Ignore Scan Request\n");
+ return;
+ }
+
+ os_memset(¶ms, 0, sizeof(params));
+ wpa_printf(MSG_DEBUG, "SME OBSS: Request a OBSS scan");
+
+ if (wpa_supplicant_trigger_scan(wpa_s, ¶ms))
+ wpa_printf(MSG_DEBUG, "SME OBSS: Failed to trigger scan");
+ else
+ wpa_s->current_bss->sched_obss_scan = 1;
+
+ eloop_register_timeout(wpa_s->current_bss->obss_scan_int, 0,
+ sme_obss_scan_timeout, wpa_s, NULL);
+}
+
+void sme_sched_obss_scan(struct wpa_supplicant *wpa_s)
+{
+ const u8 *ie;
+
+ if (wpa_s->wpa_state != WPA_COMPLETED)
+ return;
+
+ ie = wpa_bss_get_ie(wpa_s->current_bss,
+ WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS);
+ if (!ie || (ie[1] != 14))
+ return;
+
+ wpa_s->current_bss->obss_scan_int = WPA_GET_LE16(ie + 6);
+ wpa_printf(MSG_DEBUG, "SME: OBSS Scan Interval %d\n",
+ wpa_s->current_bss->obss_scan_int);
+ eloop_register_timeout(wpa_s->current_bss->obss_scan_int, 0,
+ sme_obss_scan_timeout, wpa_s, NULL);
+}
#ifdef CONFIG_IEEE80211W
static const unsigned int sa_query_max_timeout = 1000;
@@ -37,6 +37,7 @@ void sme_deinit(struct wpa_supplicant *wpa_s);
void sme_proc_40mhz_intolerant(struct wpa_supplicant *wpa_s);
+void sme_sched_obss_scan(struct wpa_supplicant *wpa_s);
#else /* CONFIG_SME */
static inline void sme_authenticate(struct wpa_supplicant *wpa_s,
@@ -101,6 +102,9 @@ static inline void sme_proc_40mhz_intolerant(struct wpa_supplicant *wpa_s)
{
}
+static inline void sme_sched_obss_scan(struct wpa_supplicant *wpa_s)
+{
+}
#endif /* CONFIG_SME */
#endif /* SME_H */
@@ -624,6 +624,8 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
wpa_supplicant_stop_bgscan(wpa_s);
#endif /* CONFIG_BGSCAN */
+ sme_sched_obss_scan(wpa_s);
+
if (wpa_s->wpa_state != old_state) {
wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
Parse the OBSS scan parameter from beacon IE and schedule periodic scan to generate 2040 coexistence channel report. This patch decodes Scan Interval alone from the OBSS Scan parameter IE and triggers scan on timeout. Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com> --- wpa_supplicant/bss.h | 3 +++ wpa_supplicant/events.c | 9 ++++----- wpa_supplicant/sme.c | 40 +++++++++++++++++++++++++++++++++++++++ wpa_supplicant/sme.h | 4 ++++ wpa_supplicant/wpa_supplicant.c | 2 ++ 5 files changed, 53 insertions(+), 5 deletions(-)