]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Interworking: Try to use same BSS entry for storing GAS results
authorJouni Malinen <j@w1.fi>
Mon, 1 Apr 2013 08:44:04 +0000 (11:44 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 1 Apr 2013 08:44:04 +0000 (11:44 +0300)
There may be cases where multiple BSS entries for a single BSSID are in
the table. This is mostly in automated test cases due to the AP
configuration changes, but something similar could potentially happen as
a corner case in more realistic networks, too, e.g., when an AP changes
its operating channel. Make network selection more robust by trying to
find the exact BSS entry instead of any BSS entry with a matching BSSID
when storing GAS/ANQP response.

Signed-hostap: Jouni Malinen <j@w1.fi>

wpa_supplicant/interworking.c
wpa_supplicant/wpa_supplicant_i.h

index 6fe762f01c17b98ad750ac0dde80bd1fe6bfe29a..b59dd6aba0cae936547081b2628a008a4d07de86 100644 (file)
@@ -187,6 +187,7 @@ static int interworking_anqp_send_req(struct wpa_supplicant *wpa_s,
 
        wpa_printf(MSG_DEBUG, "Interworking: ANQP Query Request to " MACSTR,
                   MAC2STR(bss->bssid));
+       wpa_s->interworking_gas_bss = bss;
 
        info_ids[num_info_ids++] = ANQP_CAPABILITY_LIST;
        if (all) {
@@ -1809,11 +1810,11 @@ int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst,
 
 
 static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s,
-                                           const u8 *sa, u16 info_id,
+                                           struct wpa_bss *bss, const u8 *sa,
+                                           u16 info_id,
                                            const u8 *data, size_t slen)
 {
        const u8 *pos = data;
-       struct wpa_bss *bss = wpa_bss_get_bssid(wpa_s, sa);
        struct wpa_bss_anqp *anqp = NULL;
 #ifdef CONFIG_HS20
        u8 type;
@@ -1949,6 +1950,7 @@ void anqp_resp_cb(void *ctx, const u8 *dst, u8 dialog_token,
        const u8 *end;
        u16 info_id;
        u16 slen;
+       struct wpa_bss *bss = NULL, *tmp;
 
        if (result != GAS_QUERY_SUCCESS)
                return;
@@ -1961,6 +1963,21 @@ void anqp_resp_cb(void *ctx, const u8 *dst, u8 dialog_token,
                return;
        }
 
+       /*
+        * If possible, select the BSS entry based on which BSS entry was used
+        * for the request. This can help in cases where multiple BSS entries
+        * may exist for the same AP.
+        */
+       dl_list_for_each_reverse(tmp, &wpa_s->bss, struct wpa_bss, list) {
+               if (tmp == wpa_s->interworking_gas_bss &&
+                   os_memcmp(tmp->bssid, dst, ETH_ALEN) == 0) {
+                       bss = tmp;
+                       break;
+               }
+       }
+       if (bss == NULL)
+               bss = wpa_bss_get_bssid(wpa_s, dst);
+
        pos = wpabuf_head(resp);
        end = pos + wpabuf_len(resp);
 
@@ -1978,7 +1995,7 @@ void anqp_resp_cb(void *ctx, const u8 *dst, u8 dialog_token,
                                   "for Info ID %u", info_id);
                        break;
                }
-               interworking_parse_rx_anqp_resp(wpa_s, dst, info_id, pos,
+               interworking_parse_rx_anqp_resp(wpa_s, bss, dst, info_id, pos,
                                                slen);
                pos += slen;
        }
index 982fb655bf943a90d367dfd1139e6155d7bc5d57..030880627f683be576b2f7dafe1e736a2accd1f1 100644 (file)
@@ -659,6 +659,7 @@ struct wpa_supplicant {
        unsigned int auto_select:1;
        unsigned int auto_network_select:1;
        unsigned int fetch_all_anqp:1;
+       struct wpa_bss *interworking_gas_bss;
 #endif /* CONFIG_INTERWORKING */
        unsigned int drv_capa_known;