Interworking: Try to use same BSS entry for storing GAS results

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>
This commit is contained in:
Jouni Malinen 2013-04-01 11:44:04 +03:00
parent c7860beb52
commit 17b8995cf5
2 changed files with 21 additions and 3 deletions

View 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;
}

View 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;