From 184e110caff3339643a303ab3a2f32642623a0c4 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 20 Dec 2012 21:15:05 +0200 Subject: [PATCH] HS 2.0R2: Add Icon Request and Icon binary File ANQP elements wpa_supplicant can request OSU icon data with "hs20_icon_request ". This transmits an Icon Request ANQP element and processes the response in Icon Binary File ANQP elements. Signed-hostap: Jouni Malinen --- src/common/ieee802_11_defs.h | 2 ++ wpa_supplicant/ctrl_iface.c | 22 +++++++++++++++ wpa_supplicant/hs20_supplicant.c | 46 ++++++++++++++++++++++++++++++++ wpa_supplicant/wpa_cli.c | 21 +++++++++++++++ 4 files changed, 91 insertions(+) diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index 68804bb08..7f2d77407 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -908,6 +908,8 @@ enum { #define HS20_STYPE_CONNECTION_CAPABILITY 5 #define HS20_STYPE_NAI_HOME_REALM_QUERY 6 #define HS20_STYPE_OPERATING_CLASS 7 +#define HS20_STYPE_ICON_REQUEST 10 +#define HS20_STYPE_ICON_BINARY_FILE 11 #define HS20_DGAF_DISABLED 0x01 #define HS20_PPS_MO_ID_PRESENT 0x02 diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 0df37108e..ffc76f67f 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -5178,6 +5178,25 @@ static int hs20_get_nai_home_realm_list(struct wpa_supplicant *wpa_s, return ret; } + +static int hs20_icon_request(struct wpa_supplicant *wpa_s, char *cmd) +{ + u8 dst_addr[ETH_ALEN]; + int used; + char *icon; + + used = hwaddr_aton2(cmd, dst_addr); + if (used < 0) + return -1; + + while (cmd[used] == ' ') + used++; + icon = &cmd[used]; + + return hs20_anqp_send_req(wpa_s, dst_addr, BIT(HS20_STYPE_ICON_REQUEST), + (u8 *) icon, os_strlen(icon)); +} + #endif /* CONFIG_HS20 */ @@ -6103,6 +6122,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, } else if (os_strncmp(buf, "HS20_GET_NAI_HOME_REALM_LIST ", 29) == 0) { if (hs20_get_nai_home_realm_list(wpa_s, buf + 29) < 0) reply_len = -1; + } else if (os_strncmp(buf, "HS20_ICON_REQUEST ", 18) == 0) { + if (hs20_icon_request(wpa_s, buf + 18) < 0) + reply_len = -1; #endif /* CONFIG_HS20 */ } else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0) { diff --git a/wpa_supplicant/hs20_supplicant.c b/wpa_supplicant/hs20_supplicant.c index 456ba61ff..ceafc731e 100644 --- a/wpa_supplicant/hs20_supplicant.c +++ b/wpa_supplicant/hs20_supplicant.c @@ -105,6 +105,11 @@ struct wpabuf * hs20_build_anqp_req(u32 stypes, const u8 *payload, wpabuf_put_u8(buf, 0); /* Reserved */ if (payload) wpabuf_put_data(buf, payload, payload_len); + } else if (stypes == BIT(HS20_STYPE_ICON_REQUEST)) { + wpabuf_put_u8(buf, HS20_STYPE_ICON_REQUEST); + wpabuf_put_u8(buf, 0); /* Reserved */ + if (payload) + wpabuf_put_data(buf, payload, payload_len); } else { u8 i; wpabuf_put_u8(buf, HS20_STYPE_QUERY_LIST); @@ -167,6 +172,7 @@ void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s, u8 subtype; struct wpa_bss *bss = wpa_bss_get_bssid(wpa_s, sa); struct wpa_bss_anqp *anqp = NULL; + u16 data_len; if (slen < 2) return; @@ -232,6 +238,46 @@ void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s, wpabuf_alloc_copy(pos, slen); } break; + case HS20_STYPE_ICON_BINARY_FILE: + wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR + " Icon Binary File", MAC2STR(sa)); + + if (slen < 4) { + wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short Icon " + "Binary File value from " MACSTR, MAC2STR(sa)); + break; + } + + wpa_printf(MSG_DEBUG, "HS 2.0: Download Status Code %u", *pos); + pos++; + slen--; + + if ((size_t) 1 + pos[0] > slen) { + wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short Icon " + "Binary File value from " MACSTR, MAC2STR(sa)); + break; + } + wpa_hexdump_ascii(MSG_DEBUG, "Icon Type", pos + 1, pos[0]); + slen -= 1 + pos[0]; + pos += 1 + pos[0]; + + if (slen < 2) { + wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short Icon " + "Binary File value from " MACSTR, MAC2STR(sa)); + break; + } + data_len = WPA_GET_BE16(pos); + pos += 2; + slen -= 2; + + if (data_len > slen) { + wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short Icon " + "Binary File value from " MACSTR, MAC2STR(sa)); + break; + } + + wpa_printf(MSG_DEBUG, "Icon Binary Data: %u bytes", data_len); + break; default: wpa_printf(MSG_DEBUG, "HS20: Unsupported subtype %u", subtype); break; diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 1871a2802..fd7f92fa3 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -2298,6 +2298,24 @@ static int wpa_cli_cmd_get_nai_home_realm_list(struct wpa_ctrl *ctrl, int argc, return wpa_ctrl_command(ctrl, cmd); } + +static int wpa_cli_cmd_hs20_icon_request(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + char cmd[512]; + + if (argc < 2) { + printf("Command needs two arguments (dst mac addr and " + "icon name)\n"); + return -1; + } + + if (write_cmd(cmd, sizeof(cmd), "HS20_ICON_REQUEST", argc, argv) < 0) + return -1; + + return wpa_ctrl_command(ctrl, cmd); +} + #endif /* CONFIG_HS20 */ @@ -2831,6 +2849,9 @@ static struct wpa_cli_cmd wpa_cli_commands[] = { { "nai_home_realm_list", wpa_cli_cmd_get_nai_home_realm_list, wpa_cli_complete_bss, cli_cmd_flag_none, " = get HS20 nai home realm list" }, + { "hs20_icon_request", wpa_cli_cmd_hs20_icon_request, + wpa_cli_complete_bss, cli_cmd_flag_none, + " = get Hotspot 2.0 OSU icon" }, #endif /* CONFIG_HS20 */ { "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, NULL, cli_cmd_flag_none, -- 2.39.2