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:
parent
c7860beb52
commit
17b8995cf5
2 changed files with 21 additions and 3 deletions
|
@ -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,
|
wpa_printf(MSG_DEBUG, "Interworking: ANQP Query Request to " MACSTR,
|
||||||
MAC2STR(bss->bssid));
|
MAC2STR(bss->bssid));
|
||||||
|
wpa_s->interworking_gas_bss = bss;
|
||||||
|
|
||||||
info_ids[num_info_ids++] = ANQP_CAPABILITY_LIST;
|
info_ids[num_info_ids++] = ANQP_CAPABILITY_LIST;
|
||||||
if (all) {
|
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,
|
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 *data, size_t slen)
|
||||||
{
|
{
|
||||||
const u8 *pos = data;
|
const u8 *pos = data;
|
||||||
struct wpa_bss *bss = wpa_bss_get_bssid(wpa_s, sa);
|
|
||||||
struct wpa_bss_anqp *anqp = NULL;
|
struct wpa_bss_anqp *anqp = NULL;
|
||||||
#ifdef CONFIG_HS20
|
#ifdef CONFIG_HS20
|
||||||
u8 type;
|
u8 type;
|
||||||
|
@ -1949,6 +1950,7 @@ void anqp_resp_cb(void *ctx, const u8 *dst, u8 dialog_token,
|
||||||
const u8 *end;
|
const u8 *end;
|
||||||
u16 info_id;
|
u16 info_id;
|
||||||
u16 slen;
|
u16 slen;
|
||||||
|
struct wpa_bss *bss = NULL, *tmp;
|
||||||
|
|
||||||
if (result != GAS_QUERY_SUCCESS)
|
if (result != GAS_QUERY_SUCCESS)
|
||||||
return;
|
return;
|
||||||
|
@ -1961,6 +1963,21 @@ void anqp_resp_cb(void *ctx, const u8 *dst, u8 dialog_token,
|
||||||
return;
|
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);
|
pos = wpabuf_head(resp);
|
||||||
end = pos + wpabuf_len(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);
|
"for Info ID %u", info_id);
|
||||||
break;
|
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);
|
slen);
|
||||||
pos += slen;
|
pos += slen;
|
||||||
}
|
}
|
||||||
|
|
|
@ -659,6 +659,7 @@ struct wpa_supplicant {
|
||||||
unsigned int auto_select:1;
|
unsigned int auto_select:1;
|
||||||
unsigned int auto_network_select:1;
|
unsigned int auto_network_select:1;
|
||||||
unsigned int fetch_all_anqp:1;
|
unsigned int fetch_all_anqp:1;
|
||||||
|
struct wpa_bss *interworking_gas_bss;
|
||||||
#endif /* CONFIG_INTERWORKING */
|
#endif /* CONFIG_INTERWORKING */
|
||||||
unsigned int drv_capa_known;
|
unsigned int drv_capa_known;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue