HS 2.0R2: Add WNM-Notification Request for Subscription Remediation
Subscription remediation notification WNM-Notification Request is now shown in the following way in wpa_supplicant control interface: <3>HS20-SUBSCRIPTION-REMEDIATION http://example.com/foo/ Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
f9cd147d6b
commit
95a3ea9426
9 changed files with 149 additions and 2 deletions
|
@ -914,6 +914,9 @@ enum {
|
|||
#define HS20_ANQP_DOMAIN_ID_PRESENT 0x04
|
||||
#define HS20_VERSION 0x10 /* Release 2 */
|
||||
|
||||
/* WNM-Notification WFA vendors specific subtypes */
|
||||
#define HS20_WNM_SUB_REM_NEEDED 0
|
||||
|
||||
/* Wi-Fi Direct (P2P) */
|
||||
|
||||
#define P2P_OUI_TYPE 9
|
||||
|
|
|
@ -168,6 +168,8 @@ extern "C" {
|
|||
/* parameters: <addr> <dialog_token> <freq> <status_code> <result> */
|
||||
#define GAS_QUERY_DONE "GAS-QUERY-DONE "
|
||||
|
||||
#define HS20_SUBSCRIPTION_REMEDIATION "HS20-SUBSCRIPTION-REMEDIATION "
|
||||
|
||||
#define EXT_RADIO_WORK_START "EXT-RADIO-WORK-START "
|
||||
#define EXT_RADIO_WORK_TIMEOUT "EXT-RADIO-WORK-TIMEOUT "
|
||||
|
||||
|
|
|
@ -4376,6 +4376,12 @@ static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
|
|||
if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x11", 2) < 0)
|
||||
ret = -1;
|
||||
|
||||
#ifdef CONFIG_HS20
|
||||
/* WNM-Notification */
|
||||
if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x1a", 2) < 0)
|
||||
return -1;
|
||||
#endif /* CONFIG_HS20 */
|
||||
|
||||
nl80211_mgmt_handle_register_eloop(bss);
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -235,3 +235,14 @@ void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void hs20_rx_subscription_remediation(struct wpa_supplicant *wpa_s,
|
||||
const char *url, u8 osu_method)
|
||||
{
|
||||
if (url)
|
||||
wpa_msg(wpa_s, MSG_INFO, HS20_SUBSCRIPTION_REMEDIATION "%u %s",
|
||||
osu_method, url);
|
||||
else
|
||||
wpa_msg(wpa_s, MSG_INFO, HS20_SUBSCRIPTION_REMEDIATION);
|
||||
}
|
||||
|
|
|
@ -20,4 +20,7 @@ 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);
|
||||
|
||||
void hs20_rx_subscription_remediation(struct wpa_supplicant *wpa_s,
|
||||
const char *url, u8 osu_method);
|
||||
|
||||
#endif /* HS20_SUPPLICANT_H */
|
||||
|
|
|
@ -365,11 +365,17 @@ static void wpas_add_interworking_elements(struct wpa_supplicant *wpa_s,
|
|||
return;
|
||||
|
||||
wpabuf_put_u8(buf, WLAN_EID_EXT_CAPAB);
|
||||
wpabuf_put_u8(buf, 4);
|
||||
wpabuf_put_u8(buf, 6);
|
||||
wpabuf_put_u8(buf, 0x00);
|
||||
wpabuf_put_u8(buf, 0x00);
|
||||
wpabuf_put_u8(buf, 0x00);
|
||||
wpabuf_put_u8(buf, 0x80); /* Bit 31 - Interworking */
|
||||
wpabuf_put_u8(buf, 0x00);
|
||||
#ifdef CONFIG_HS20
|
||||
wpabuf_put_u8(buf, 0x40); /* Bit 46 - WNM-Notification */
|
||||
#else /* CONFIG_HS20 */
|
||||
wpabuf_put_u8(buf, 0x00);
|
||||
#endif /* CONFIG_HS20 */
|
||||
|
||||
wpabuf_put_u8(buf, WLAN_EID_INTERWORKING);
|
||||
wpabuf_put_u8(buf, is_zero_ether_addr(wpa_s->conf->hessid) ? 1 :
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "ctrl_iface.h"
|
||||
#include "bss.h"
|
||||
#include "wnm_sta.h"
|
||||
#include "hs20_supplicant.h"
|
||||
|
||||
#define MAX_TFS_IE_LEN 1024
|
||||
#define WNM_MAX_NEIGHBOR_REPORT 10
|
||||
|
@ -751,6 +752,112 @@ int wnm_send_bss_transition_mgmt_query(struct wpa_supplicant *wpa_s,
|
|||
}
|
||||
|
||||
|
||||
static void ieee802_11_rx_wnm_notif_req_wfa(struct wpa_supplicant *wpa_s,
|
||||
const u8 *sa, const u8 *data,
|
||||
int len)
|
||||
{
|
||||
const u8 *pos, *end;
|
||||
u8 ie, ie_len;
|
||||
|
||||
pos = data;
|
||||
end = data + len;
|
||||
|
||||
while (pos + 1 < end) {
|
||||
ie = *pos++;
|
||||
ie_len = *pos++;
|
||||
wpa_printf(MSG_DEBUG, "WNM: WFA subelement %u len %u",
|
||||
ie, ie_len);
|
||||
if (ie_len > end - pos) {
|
||||
wpa_printf(MSG_DEBUG, "WNM: Not enough room for "
|
||||
"subelement");
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HS20
|
||||
if (ie == WLAN_EID_VENDOR_SPECIFIC && ie_len >= 5 &&
|
||||
WPA_GET_BE24(pos) == OUI_WFA &&
|
||||
pos[3] == HS20_WNM_SUB_REM_NEEDED) {
|
||||
/* Subscription Remediation subelement */
|
||||
const u8 *ie_end;
|
||||
u8 url_len;
|
||||
char *url;
|
||||
u8 osu_method;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "WNM: Subscription Remediation "
|
||||
"subelement");
|
||||
ie_end = pos + ie_len;
|
||||
pos += 4;
|
||||
url_len = *pos++;
|
||||
if (url_len == 0) {
|
||||
wpa_printf(MSG_DEBUG, "WNM: No Server URL included");
|
||||
url = NULL;
|
||||
osu_method = 1;
|
||||
} else {
|
||||
if (pos + url_len + 1 > ie_end) {
|
||||
wpa_printf(MSG_DEBUG, "WNM: Not enough room for Server URL (len=%u) and Server Method (left %d)",
|
||||
url_len,
|
||||
(int) (ie_end - pos));
|
||||
break;
|
||||
}
|
||||
url = os_malloc(url_len + 1);
|
||||
if (url == NULL)
|
||||
break;
|
||||
os_memcpy(url, pos, url_len);
|
||||
url[url_len] = '\0';
|
||||
osu_method = pos[url_len];
|
||||
}
|
||||
hs20_rx_subscription_remediation(wpa_s, url,
|
||||
osu_method);
|
||||
os_free(url);
|
||||
break;
|
||||
}
|
||||
#endif /* CONFIG_HS20 */
|
||||
|
||||
pos += ie_len;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void ieee802_11_rx_wnm_notif_req(struct wpa_supplicant *wpa_s,
|
||||
const u8 *sa, const u8 *frm, int len)
|
||||
{
|
||||
const u8 *pos, *end;
|
||||
u8 dialog_token, type;
|
||||
|
||||
/* Dialog Token [1] | Type [1] | Subelements */
|
||||
|
||||
if (len < 2 || sa == NULL)
|
||||
return;
|
||||
end = frm + len;
|
||||
pos = frm;
|
||||
dialog_token = *pos++;
|
||||
type = *pos++;
|
||||
|
||||
wpa_dbg(wpa_s, MSG_DEBUG, "WNM: Received WNM-Notification Request "
|
||||
"(dialog_token %u type %u sa " MACSTR ")",
|
||||
dialog_token, type, MAC2STR(sa));
|
||||
wpa_hexdump(MSG_DEBUG, "WNM-Notification Request subelements",
|
||||
pos, end - pos);
|
||||
|
||||
if (wpa_s->wpa_state != WPA_COMPLETED ||
|
||||
os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0) {
|
||||
wpa_dbg(wpa_s, MSG_DEBUG, "WNM: WNM-Notification frame not "
|
||||
"from our AP - ignore it");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 1:
|
||||
ieee802_11_rx_wnm_notif_req_wfa(wpa_s, sa, pos, end - pos);
|
||||
break;
|
||||
default:
|
||||
wpa_dbg(wpa_s, MSG_DEBUG, "WNM: Ignore unknown "
|
||||
"WNM-Notification type %u", type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ieee802_11_rx_wnm_action(struct wpa_supplicant *wpa_s,
|
||||
const struct ieee80211_mgmt *mgmt, size_t len)
|
||||
{
|
||||
|
@ -782,6 +889,9 @@ void ieee802_11_rx_wnm_action(struct wpa_supplicant *wpa_s,
|
|||
case WNM_SLEEP_MODE_RESP:
|
||||
ieee802_11_rx_wnmsleep_resp(wpa_s, pos, end - pos);
|
||||
break;
|
||||
case WNM_NOTIFICATION_REQ:
|
||||
ieee802_11_rx_wnm_notif_req(wpa_s, mgmt->sa, pos, end - pos);
|
||||
break;
|
||||
default:
|
||||
wpa_printf(MSG_ERROR, "WNM: Unknown request");
|
||||
break;
|
||||
|
|
|
@ -3181,6 +3181,8 @@ static void wpa_cli_action_process(const char *msg)
|
|||
wpa_cli_exec(action_file, ctrl_ifname, pos);
|
||||
} else if (str_match(pos, ESS_DISASSOC_IMMINENT)) {
|
||||
wpa_cli_exec(action_file, ctrl_ifname, pos);
|
||||
} else if (str_match(pos, HS20_SUBSCRIPTION_REMEDIATION)) {
|
||||
wpa_cli_exec(action_file, ctrl_ifname, pos);
|
||||
} else if (str_match(pos, WPA_EVENT_TERMINATING)) {
|
||||
printf("wpa_supplicant is terminating - stop monitoring\n");
|
||||
wpa_cli_quit = 1;
|
||||
|
|
|
@ -1208,6 +1208,10 @@ static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
|
|||
#endif /* CONFIG_INTERWORKING */
|
||||
break;
|
||||
case 5: /* Bits 40-47 */
|
||||
#ifdef CONFIG_HS20
|
||||
if (wpa_s->conf->hs20)
|
||||
*pos |= 0x40; /* Bit 46 - WNM-Notification */
|
||||
#endif /* CONFIG_HS20 */
|
||||
break;
|
||||
case 6: /* Bits 48-55 */
|
||||
break;
|
||||
|
@ -1218,7 +1222,7 @@ static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
|
|||
int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf)
|
||||
{
|
||||
u8 *pos = buf;
|
||||
u8 len = 4, i;
|
||||
u8 len = 6, i;
|
||||
|
||||
if (len < wpa_s->extended_capa_len)
|
||||
len = wpa_s->extended_capa_len;
|
||||
|
|
Loading…
Reference in a new issue