diff --git a/wpa_supplicant/hs20_supplicant.c b/wpa_supplicant/hs20_supplicant.c index f4187900e..030b5aa99 100644 --- a/wpa_supplicant/hs20_supplicant.c +++ b/wpa_supplicant/hs20_supplicant.c @@ -104,15 +104,22 @@ void hs20_configure_frame_filters(struct wpa_supplicant *wpa_s) } -void wpas_hs20_add_indication(struct wpabuf *buf, int pps_mo_id) +void wpas_hs20_add_indication(struct wpabuf *buf, int pps_mo_id, int ap_release) { + int release; u8 conf; + release = (HS20_VERSION >> 4) + 1; + if (ap_release > 0 && release > ap_release) + release = ap_release; + if (release < 2) + pps_mo_id = -1; + wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); wpabuf_put_u8(buf, pps_mo_id >= 0 ? 7 : 5); wpabuf_put_be24(buf, OUI_WFA); wpabuf_put_u8(buf, HS20_INDICATION_OUI_TYPE); - conf = HS20_VERSION; + conf = (release - 1) << 4; if (pps_mo_id >= 0) conf |= HS20_PPS_MO_ID_PRESENT; wpabuf_put_u8(buf, conf); @@ -137,6 +144,21 @@ void wpas_hs20_add_roam_cons_sel(struct wpabuf *buf, } +int get_hs20_version(struct wpa_bss *bss) +{ + const u8 *ie; + + if (!bss) + return 0; + + ie = wpa_bss_get_vendor_ie(bss, HS20_IE_VENDOR_TYPE); + if (!ie || ie[1] < 5) + return 0; + + return ((ie[6] >> 4) & 0x0f) + 1; +} + + int is_hs20_network(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct wpa_bss *bss) { diff --git a/wpa_supplicant/hs20_supplicant.h b/wpa_supplicant/hs20_supplicant.h index 66fc540be..e43414bc6 100644 --- a/wpa_supplicant/hs20_supplicant.h +++ b/wpa_supplicant/hs20_supplicant.h @@ -9,7 +9,8 @@ #define HS20_SUPPLICANT_H void hs20_configure_frame_filters(struct wpa_supplicant *wpa_s); -void wpas_hs20_add_indication(struct wpabuf *buf, int pps_mo_id); +void wpas_hs20_add_indication(struct wpabuf *buf, int pps_mo_id, + int ap_release); void wpas_hs20_add_roam_cons_sel(struct wpabuf *buf, const struct wpa_ssid *ssid); @@ -20,6 +21,7 @@ void hs20_put_anqp_req(u32 stypes, const u8 *payload, size_t payload_len, void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, const u8 *sa, const u8 *data, size_t slen, u8 dialog_token); +int get_hs20_version(struct wpa_bss *bss); int is_hs20_network(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct wpa_bss *bss); int hs20_get_pps_mo_id(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index ee39e0c92..be328dedb 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -582,7 +582,7 @@ static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s) #ifdef CONFIG_HS20 if (wpa_s->conf->hs20 && wpabuf_resize(&extra_ie, 7) == 0) - wpas_hs20_add_indication(extra_ie, -1); + wpas_hs20_add_indication(extra_ie, -1, 0); #endif /* CONFIG_HS20 */ #ifdef CONFIG_FST diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index f77f75177..becc4fa28 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -550,7 +550,8 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid); size_t len; - wpas_hs20_add_indication(hs20, pps_mo_id); + wpas_hs20_add_indication(hs20, pps_mo_id, + get_hs20_version(bss)); wpas_hs20_add_roam_cons_sel(hs20, ssid); len = sizeof(wpa_s->sme.assoc_req_ie) - wpa_s->sme.assoc_req_ie_len; diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index e587d7e3c..59fb47c95 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -2678,7 +2678,8 @@ static u8 * wpas_populate_assoc_ies( int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid); size_t len; - wpas_hs20_add_indication(hs20, pps_mo_id); + wpas_hs20_add_indication(hs20, pps_mo_id, + get_hs20_version(bss)); wpas_hs20_add_roam_cons_sel(hs20, ssid); len = max_wpa_ie_len - wpa_ie_len; if (wpabuf_len(hs20) <= len) {