HS 2.0: Request and process OSU Providers NAI List ANQP-element

Extend wpa_supplicant to use a separate OSU_NAI information from OSU
Providers NAI List ANQP-element instead of the OSU_NAI information from
OSU Providers list ANQP-element when connecting to the shared BSS
(Single SSID) for OSU.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2018-10-05 20:51:51 +03:00 committed by Jouni Malinen
parent cad810a98f
commit baf4c86379
5 changed files with 49 additions and 1 deletions

View file

@ -103,6 +103,7 @@ static struct wpa_bss_anqp * wpa_bss_anqp_clone(struct wpa_bss_anqp *anqp)
ANQP_DUP(hs20_operating_class); ANQP_DUP(hs20_operating_class);
ANQP_DUP(hs20_osu_providers_list); ANQP_DUP(hs20_osu_providers_list);
ANQP_DUP(hs20_operator_icon_metadata); ANQP_DUP(hs20_operator_icon_metadata);
ANQP_DUP(hs20_osu_providers_nai_list);
#endif /* CONFIG_HS20 */ #endif /* CONFIG_HS20 */
#undef ANQP_DUP #undef ANQP_DUP
@ -187,6 +188,7 @@ static void wpa_bss_anqp_free(struct wpa_bss_anqp *anqp)
wpabuf_free(anqp->hs20_operating_class); wpabuf_free(anqp->hs20_operating_class);
wpabuf_free(anqp->hs20_osu_providers_list); wpabuf_free(anqp->hs20_osu_providers_list);
wpabuf_free(anqp->hs20_operator_icon_metadata); wpabuf_free(anqp->hs20_operator_icon_metadata);
wpabuf_free(anqp->hs20_osu_providers_nai_list);
#endif /* CONFIG_HS20 */ #endif /* CONFIG_HS20 */
os_free(anqp); os_free(anqp);

View file

@ -51,6 +51,7 @@ struct wpa_bss_anqp {
struct wpabuf *hs20_operating_class; struct wpabuf *hs20_operating_class;
struct wpabuf *hs20_osu_providers_list; struct wpabuf *hs20_osu_providers_list;
struct wpabuf *hs20_operator_icon_metadata; struct wpabuf *hs20_operator_icon_metadata;
struct wpabuf *hs20_osu_providers_nai_list;
#endif /* CONFIG_HS20 */ #endif /* CONFIG_HS20 */
}; };

View file

@ -4809,6 +4809,8 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
anqp->hs20_osu_providers_list); anqp->hs20_osu_providers_list);
pos = anqp_add_hex(pos, end, "hs20_operator_icon_metadata", pos = anqp_add_hex(pos, end, "hs20_operator_icon_metadata",
anqp->hs20_operator_icon_metadata); anqp->hs20_operator_icon_metadata);
pos = anqp_add_hex(pos, end, "hs20_osu_providers_nai_list",
anqp->hs20_osu_providers_nai_list);
#endif /* CONFIG_HS20 */ #endif /* CONFIG_HS20 */
dl_list_for_each(elem, &anqp->anqp_elems, dl_list_for_each(elem, &anqp->anqp_elems,

View file

@ -54,6 +54,7 @@ struct osu_provider {
char server_uri[256]; char server_uri[256];
u32 osu_methods; /* bit 0 = OMA-DM, bit 1 = SOAP-XML SPP */ u32 osu_methods; /* bit 0 = OMA-DM, bit 1 = SOAP-XML SPP */
char osu_nai[256]; char osu_nai[256];
char osu_nai2[256];
struct osu_lang_string friendly_name[OSU_MAX_ITEMS]; struct osu_lang_string friendly_name[OSU_MAX_ITEMS];
size_t friendly_name_count; size_t friendly_name_count;
struct osu_lang_string serv_desc[OSU_MAX_ITEMS]; struct osu_lang_string serv_desc[OSU_MAX_ITEMS];
@ -673,6 +674,15 @@ void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s,
wpabuf_alloc_copy(pos, slen); wpabuf_alloc_copy(pos, slen);
} }
break; break;
case HS20_STYPE_OSU_PROVIDERS_NAI_LIST:
wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR
" OSU Providers NAI List", MAC2STR(sa));
if (anqp) {
wpabuf_free(anqp->hs20_osu_providers_nai_list);
anqp->hs20_osu_providers_nai_list =
wpabuf_alloc_copy(pos, slen);
}
break;
default: default:
wpa_printf(MSG_DEBUG, "HS20: Unsupported subtype %u", subtype); wpa_printf(MSG_DEBUG, "HS20: Unsupported subtype %u", subtype);
break; break;
@ -759,6 +769,8 @@ static void hs20_osu_fetch_done(struct wpa_supplicant *wpa_s)
} }
if (osu->osu_nai[0]) if (osu->osu_nai[0])
fprintf(f, "osu_nai=%s\n", osu->osu_nai); fprintf(f, "osu_nai=%s\n", osu->osu_nai);
if (osu->osu_nai2[0])
fprintf(f, "osu_nai2=%s\n", osu->osu_nai2);
for (j = 0; j < osu->friendly_name_count; j++) { for (j = 0; j < osu->friendly_name_count; j++) {
fprintf(f, "friendly_name=%s:%s\n", fprintf(f, "friendly_name=%s:%s\n",
osu->friendly_name[j].lang, osu->friendly_name[j].lang,
@ -1103,6 +1115,35 @@ void hs20_osu_icon_fetch(struct wpa_supplicant *wpa_s)
"extra data after OSU Providers", "extra data after OSU Providers",
(int) (end - pos)); (int) (end - pos));
} }
prov_anqp = bss->anqp->hs20_osu_providers_nai_list;
if (!prov_anqp)
continue;
wpa_printf(MSG_DEBUG,
"HS 2.0: Parsing OSU Providers NAI List from "
MACSTR, MAC2STR(bss->bssid));
wpa_hexdump_buf(MSG_DEBUG, "HS 2.0: OSU Providers NAI List",
prov_anqp);
pos = wpabuf_head(prov_anqp);
end = pos + wpabuf_len(prov_anqp);
num_providers = 0;
while (end - pos > 0) {
len = *pos++;
if (end - pos < len) {
wpa_printf(MSG_DEBUG,
"HS 2.0: Not enough room for OSU_NAI");
break;
}
if (num_providers >= wpa_s->osu_prov_count) {
wpa_printf(MSG_DEBUG,
"HS 2.0: Ignore unexpected OSU Provider NAI List entries");
break;
}
os_memcpy(wpa_s->osu_prov[num_providers].osu_nai2,
pos, len);
pos += len;
num_providers++;
}
} }
wpa_s->fetch_osu_icon_in_progress = 1; wpa_s->fetch_osu_icon_in_progress = 1;

View file

@ -303,8 +303,10 @@ static int interworking_anqp_send_req(struct wpa_supplicant *wpa_s,
wpabuf_put_u8(extra, HS20_STYPE_CONNECTION_CAPABILITY); wpabuf_put_u8(extra, HS20_STYPE_CONNECTION_CAPABILITY);
if (all) if (all)
wpabuf_put_u8(extra, HS20_STYPE_OPERATING_CLASS); wpabuf_put_u8(extra, HS20_STYPE_OPERATING_CLASS);
if (all) if (all) {
wpabuf_put_u8(extra, HS20_STYPE_OSU_PROVIDERS_LIST); wpabuf_put_u8(extra, HS20_STYPE_OSU_PROVIDERS_LIST);
wpabuf_put_u8(extra, HS20_STYPE_OSU_PROVIDERS_NAI_LIST);
}
gas_anqp_set_element_len(extra, len_pos); gas_anqp_set_element_len(extra, len_pos);
} }
#endif /* CONFIG_HS20 */ #endif /* CONFIG_HS20 */