HS 2.0R2: Update Indication element to Release 2
The HS 2.0 Indication element from wpa_supplicant now includes the release number field and wpa_supplicant shows the release number of the AP in STATUS command (hs20=1 replaced with hs20=<release>). The new update_identifier field in the cred block can now be used to configure the PPS MO ID so that wpa_supplicant adds it to the Indication element in Association Request frames. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
bc00053c9d
commit
f9cd147d6b
12 changed files with 64 additions and 9 deletions
|
@ -909,6 +909,11 @@ enum {
|
||||||
#define HS20_STYPE_NAI_HOME_REALM_QUERY 6
|
#define HS20_STYPE_NAI_HOME_REALM_QUERY 6
|
||||||
#define HS20_STYPE_OPERATING_CLASS 7
|
#define HS20_STYPE_OPERATING_CLASS 7
|
||||||
|
|
||||||
|
#define HS20_DGAF_DISABLED 0x01
|
||||||
|
#define HS20_PPS_MO_ID_PRESENT 0x02
|
||||||
|
#define HS20_ANQP_DOMAIN_ID_PRESENT 0x04
|
||||||
|
#define HS20_VERSION 0x10 /* Release 2 */
|
||||||
|
|
||||||
/* Wi-Fi Direct (P2P) */
|
/* Wi-Fi Direct (P2P) */
|
||||||
|
|
||||||
#define P2P_OUI_TYPE 9
|
#define P2P_OUI_TYPE 9
|
||||||
|
|
|
@ -220,6 +220,9 @@ Credentials can be pre-configured for automatic network selection:
|
||||||
# (non-exact match means any subdomain matches the entry; priority is in
|
# (non-exact match means any subdomain matches the entry; priority is in
|
||||||
# 0..255 range with 0 being the highest priority)
|
# 0..255 range with 0 being the highest priority)
|
||||||
#
|
#
|
||||||
|
# update_identifier: PPS MO ID
|
||||||
|
# (Hotspot 2.0 PerProviderSubscription/UpdateIdentifier)
|
||||||
|
#
|
||||||
# for example:
|
# for example:
|
||||||
#
|
#
|
||||||
#cred={
|
#cred={
|
||||||
|
|
|
@ -2440,6 +2440,11 @@ int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (os_strcmp(var, "update_identifier") == 0) {
|
||||||
|
cred->update_identifier = atoi(value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
val = wpa_config_parse_string(value, &len);
|
val = wpa_config_parse_string(value, &len);
|
||||||
if (val == NULL) {
|
if (val == NULL) {
|
||||||
wpa_printf(MSG_ERROR, "Line %d: invalid field '%s' string "
|
wpa_printf(MSG_ERROR, "Line %d: invalid field '%s' string "
|
||||||
|
|
|
@ -244,6 +244,8 @@ struct wpa_cred {
|
||||||
char country[3];
|
char country[3];
|
||||||
} *roaming_partner;
|
} *roaming_partner;
|
||||||
size_t num_roaming_partner;
|
size_t num_roaming_partner;
|
||||||
|
|
||||||
|
int update_identifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -804,6 +804,8 @@ static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred)
|
||||||
p->country);
|
p->country);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (cred->update_identifier)
|
||||||
|
fprintf(f, "\tupdate_identifier=%d\n", cred->update_identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1554,6 +1554,9 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
|
||||||
{
|
{
|
||||||
char *pos, *end, tmp[30];
|
char *pos, *end, tmp[30];
|
||||||
int res, verbose, wps, ret;
|
int res, verbose, wps, ret;
|
||||||
|
#ifdef CONFIG_HS20
|
||||||
|
const u8 *hs20;
|
||||||
|
#endif /* CONFIG_HS20 */
|
||||||
|
|
||||||
if (os_strcmp(params, "-DRIVER") == 0)
|
if (os_strcmp(params, "-DRIVER") == 0)
|
||||||
return wpa_drv_status(wpa_s, buf, buflen);
|
return wpa_drv_status(wpa_s, buf, buflen);
|
||||||
|
@ -1692,10 +1695,16 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
#ifdef CONFIG_HS20
|
#ifdef CONFIG_HS20
|
||||||
if (wpa_s->current_bss &&
|
if (wpa_s->current_bss &&
|
||||||
wpa_bss_get_vendor_ie(wpa_s->current_bss, HS20_IE_VENDOR_TYPE) &&
|
(hs20 = wpa_bss_get_vendor_ie(wpa_s->current_bss,
|
||||||
|
HS20_IE_VENDOR_TYPE)) &&
|
||||||
wpa_s->wpa_proto == WPA_PROTO_RSN &&
|
wpa_s->wpa_proto == WPA_PROTO_RSN &&
|
||||||
wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
|
wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
|
||||||
ret = os_snprintf(pos, end - pos, "hs20=1\n");
|
int release = 1;
|
||||||
|
if (hs20[1] >= 5) {
|
||||||
|
u8 rel_num = (hs20[6] & 0xf0) >> 4;
|
||||||
|
release = rel_num + 1;
|
||||||
|
}
|
||||||
|
ret = os_snprintf(pos, end - pos, "hs20=%d\n", release);
|
||||||
if (ret < 0 || ret >= end - pos)
|
if (ret < 0 || ret >= end - pos)
|
||||||
return pos - buf;
|
return pos - buf;
|
||||||
pos += ret;
|
pos += ret;
|
||||||
|
|
|
@ -23,13 +23,20 @@
|
||||||
#include "hs20_supplicant.h"
|
#include "hs20_supplicant.h"
|
||||||
|
|
||||||
|
|
||||||
void wpas_hs20_add_indication(struct wpabuf *buf)
|
void wpas_hs20_add_indication(struct wpabuf *buf, int pps_mo_id)
|
||||||
{
|
{
|
||||||
|
u8 conf;
|
||||||
|
|
||||||
wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
|
wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
|
||||||
wpabuf_put_u8(buf, 5);
|
wpabuf_put_u8(buf, pps_mo_id >= 0 ? 7 : 5);
|
||||||
wpabuf_put_be24(buf, OUI_WFA);
|
wpabuf_put_be24(buf, OUI_WFA);
|
||||||
wpabuf_put_u8(buf, HS20_INDICATION_OUI_TYPE);
|
wpabuf_put_u8(buf, HS20_INDICATION_OUI_TYPE);
|
||||||
wpabuf_put_u8(buf, 0x00); /* Hotspot Configuration */
|
conf = HS20_VERSION;
|
||||||
|
if (pps_mo_id >= 0)
|
||||||
|
conf |= HS20_PPS_MO_ID_PRESENT;
|
||||||
|
wpabuf_put_u8(buf, conf);
|
||||||
|
if (pps_mo_id >= 0)
|
||||||
|
wpabuf_put_le16(buf, pps_mo_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,6 +69,22 @@ int is_hs20_network(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int hs20_get_pps_mo_id(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
|
||||||
|
{
|
||||||
|
struct wpa_cred *cred;
|
||||||
|
|
||||||
|
if (ssid == NULL || ssid->parent_cred == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
|
||||||
|
if (ssid->parent_cred == cred)
|
||||||
|
return cred->update_identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct wpabuf * hs20_build_anqp_req(u32 stypes, const u8 *payload,
|
struct wpabuf * hs20_build_anqp_req(u32 stypes, const u8 *payload,
|
||||||
size_t payload_len)
|
size_t payload_len)
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#ifndef HS20_SUPPLICANT_H
|
#ifndef HS20_SUPPLICANT_H
|
||||||
#define HS20_SUPPLICANT_H
|
#define HS20_SUPPLICANT_H
|
||||||
|
|
||||||
void wpas_hs20_add_indication(struct wpabuf *buf);
|
void wpas_hs20_add_indication(struct wpabuf *buf, int pps_mo_id);
|
||||||
|
|
||||||
int hs20_anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, u32 stypes,
|
int hs20_anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst, u32 stypes,
|
||||||
const u8 *payload, size_t payload_len);
|
const u8 *payload, size_t payload_len);
|
||||||
|
@ -18,5 +18,6 @@ void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s,
|
||||||
const u8 *sa, const u8 *data, size_t slen);
|
const u8 *sa, const u8 *data, size_t slen);
|
||||||
int is_hs20_network(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
|
int is_hs20_network(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
|
||||||
struct wpa_bss *bss);
|
struct wpa_bss *bss);
|
||||||
|
int hs20_get_pps_mo_id(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
|
||||||
|
|
||||||
#endif /* HS20_SUPPLICANT_H */
|
#endif /* HS20_SUPPLICANT_H */
|
||||||
|
|
|
@ -425,7 +425,7 @@ static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s)
|
||||||
|
|
||||||
#ifdef CONFIG_HS20
|
#ifdef CONFIG_HS20
|
||||||
if (wpa_s->conf->hs20 && wpabuf_resize(&extra_ie, 7) == 0)
|
if (wpa_s->conf->hs20 && wpabuf_resize(&extra_ie, 7) == 0)
|
||||||
wpas_hs20_add_indication(extra_ie);
|
wpas_hs20_add_indication(extra_ie, -1);
|
||||||
#endif /* CONFIG_HS20 */
|
#endif /* CONFIG_HS20 */
|
||||||
|
|
||||||
return extra_ie;
|
return extra_ie;
|
||||||
|
|
|
@ -360,7 +360,8 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
|
||||||
struct wpabuf *hs20;
|
struct wpabuf *hs20;
|
||||||
hs20 = wpabuf_alloc(20);
|
hs20 = wpabuf_alloc(20);
|
||||||
if (hs20) {
|
if (hs20) {
|
||||||
wpas_hs20_add_indication(hs20);
|
int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid);
|
||||||
|
wpas_hs20_add_indication(hs20, pps_mo_id);
|
||||||
os_memcpy(wpa_s->sme.assoc_req_ie +
|
os_memcpy(wpa_s->sme.assoc_req_ie +
|
||||||
wpa_s->sme.assoc_req_ie_len,
|
wpa_s->sme.assoc_req_ie_len,
|
||||||
wpabuf_head(hs20), wpabuf_len(hs20));
|
wpabuf_head(hs20), wpabuf_len(hs20));
|
||||||
|
|
|
@ -1586,7 +1586,8 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
|
||||||
struct wpabuf *hs20;
|
struct wpabuf *hs20;
|
||||||
hs20 = wpabuf_alloc(20);
|
hs20 = wpabuf_alloc(20);
|
||||||
if (hs20) {
|
if (hs20) {
|
||||||
wpas_hs20_add_indication(hs20);
|
int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid);
|
||||||
|
wpas_hs20_add_indication(hs20, pps_mo_id);
|
||||||
os_memcpy(wpa_ie + wpa_ie_len, wpabuf_head(hs20),
|
os_memcpy(wpa_ie + wpa_ie_len, wpabuf_head(hs20),
|
||||||
wpabuf_len(hs20));
|
wpabuf_len(hs20));
|
||||||
wpa_ie_len += wpabuf_len(hs20);
|
wpa_ie_len += wpabuf_len(hs20);
|
||||||
|
|
|
@ -439,6 +439,9 @@ fast_reauth=1
|
||||||
# (non-exact match means any subdomain matches the entry; priority is in
|
# (non-exact match means any subdomain matches the entry; priority is in
|
||||||
# 0..255 range with 0 being the highest priority)
|
# 0..255 range with 0 being the highest priority)
|
||||||
#
|
#
|
||||||
|
# update_identifier: PPS MO ID
|
||||||
|
# (Hotspot 2.0 PerProviderSubscription/UpdateIdentifier)
|
||||||
|
#
|
||||||
# for example:
|
# for example:
|
||||||
#
|
#
|
||||||
#cred={
|
#cred={
|
||||||
|
|
Loading…
Reference in a new issue