From 648cc711a5d86f10f40b369a7eaa8e8aa97db256 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 26 Feb 2012 22:34:21 +0200 Subject: [PATCH] GAS server: Add support for ANQP Venue Name element The new venue_name configuration parameter can now be used to configure the ANQP Venue Name values that stations can request through GAS. Signed-hostap: Jouni Malinen --- hostapd/config_file.c | 46 +++++++++++++++++++++++++++++++++++++++++++ hostapd/hostapd.conf | 9 +++++++++ src/ap/ap_config.c | 1 + src/ap/ap_config.h | 10 ++++++++++ src/ap/gas_serv.c | 28 ++++++++++++++++++++++++++ src/ap/gas_serv.h | 2 ++ 6 files changed, 96 insertions(+) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index d20496a49..638adcc40 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -1175,6 +1175,49 @@ static int parse_roaming_consortium(struct hostapd_bss_config *bss, char *pos, return 0; } + + +static int parse_venue_name(struct hostapd_bss_config *bss, char *pos, + int line) +{ + char *sep; + size_t clen, nlen; + struct hostapd_venue_name *vn; + + sep = os_strchr(pos, ':'); + if (sep == NULL) + goto fail; + *sep++ = '\0'; + + clen = os_strlen(pos); + if (clen < 2) + goto fail; + nlen = os_strlen(sep); + if (nlen > 252) + goto fail; + + vn = os_realloc(bss->venue_name, + sizeof(struct hostapd_venue_name) * + (bss->venue_name_count + 1)); + if (vn == NULL) + return -1; + + bss->venue_name = vn; + vn = &bss->venue_name[bss->venue_name_count]; + bss->venue_name_count++; + + os_memset(vn->lang, 0, sizeof(vn->lang)); + os_memcpy(vn->lang, pos, clen); + vn->name_len = nlen; + os_memcpy(vn->name, sep, nlen); + + return 0; + +fail: + wpa_printf(MSG_ERROR, "Line %d: Invalid venue_name '%s'", + line, pos); + return -1; +} #endif /* CONFIG_INTERWORKING */ @@ -2113,6 +2156,9 @@ static int hostapd_config_fill(struct hostapd_config *conf, } else if (os_strcmp(buf, "roaming_consortium") == 0) { if (parse_roaming_consortium(bss, pos, line) < 0) errors++; + } else if (os_strcmp(buf, "venue_name") == 0) { + if (parse_venue_name(bss, pos, line) < 0) + errors++; } else if (os_strcmp(buf, "gas_frag_limit") == 0) { bss->gas_frag_limit = atoi(pos); } else if (os_strcmp(buf, "gas_comeback_delay") == 0) { diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 4e6202b2e..ceae0659b 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -1118,6 +1118,15 @@ own_ip_addr=127.0.0.1 #roaming_consortium=021122 #roaming_consortium=2233445566 +# Venue Name information +# This parameter can be used to configure one or more Venue Name Duples for +# Venue Name ANQP information. Each entry has a two or three character language +# code (ISO-639) separated by colon from the venue name string. +# Note that venue_group and venue_type have to be set for Venue Name +# information to be complete. +#venue_name=eng:Example venue +#venue_name=fin:Esimerkkipaikka + ##### Multiple BSSID support ################################################## # # Above configuration is using the default interface (wlan#, or multi-SSID VLAN diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c index 64ea690f2..303448b21 100644 --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c @@ -465,6 +465,7 @@ static void hostapd_config_free_bss(struct hostapd_bss_config *conf) #endif /* CONFIG_WPS */ os_free(conf->roaming_consortium); + os_free(conf->venue_name); #ifdef CONFIG_RADIUS_TEST os_free(conf->dump_msk_file); diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 308af7b9f..914ff1453 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -142,6 +142,12 @@ struct hostapd_roaming_consortium { u8 oi[MAX_ROAMING_CONSORTIUM_LEN]; }; +struct hostapd_venue_name { + u8 lang[3]; + u8 name_len; + u8 name[252]; +}; + /** * struct hostapd_bss_config - Per-BSS configuration */ @@ -361,6 +367,10 @@ struct hostapd_bss_config { unsigned int roaming_consortium_count; struct hostapd_roaming_consortium *roaming_consortium; + /* IEEE 802.11u - Venue Name duples */ + unsigned int venue_name_count; + struct hostapd_venue_name *venue_name; + u16 gas_comeback_delay; int gas_frag_limit; diff --git a/src/ap/gas_serv.c b/src/ap/gas_serv.c index 187513ad6..a2827e269 100644 --- a/src/ap/gas_serv.c +++ b/src/ap/gas_serv.c @@ -135,12 +135,34 @@ static void anqp_add_capab_list(struct hostapd_data *hapd, len = gas_anqp_add_element(buf, ANQP_CAPABILITY_LIST); wpabuf_put_le16(buf, ANQP_CAPABILITY_LIST); + if (hapd->conf->venue_name) + wpabuf_put_le16(buf, ANQP_VENUE_NAME); if (hapd->conf->roaming_consortium) wpabuf_put_le16(buf, ANQP_ROAMING_CONSORTIUM); gas_anqp_set_element_len(buf, len); } +static void anqp_add_venue_name(struct hostapd_data *hapd, struct wpabuf *buf) +{ + if (hapd->conf->venue_name) { + u8 *len; + unsigned int i; + len = gas_anqp_add_element(buf, ANQP_VENUE_NAME); + wpabuf_put_u8(buf, hapd->conf->venue_group); + wpabuf_put_u8(buf, hapd->conf->venue_type); + for (i = 0; i < hapd->conf->venue_name_count; i++) { + struct hostapd_venue_name *vn; + vn = &hapd->conf->venue_name[i]; + wpabuf_put_u8(buf, 3 + vn->name_len); + wpabuf_put_data(buf, vn->lang, 3); + wpabuf_put_data(buf, vn->name, vn->name_len); + } + gas_anqp_set_element_len(buf, len); + } +} + + static void anqp_add_roaming_consortium(struct hostapd_data *hapd, struct wpabuf *buf) { @@ -171,6 +193,8 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd, if (request & ANQP_REQ_CAPABILITY_LIST) anqp_add_capab_list(hapd, buf); + if (request & ANQP_REQ_VENUE_NAME) + anqp_add_venue_name(hapd, buf); if (request & ANQP_REQ_ROAMING_CONSORTIUM) anqp_add_roaming_consortium(hapd, buf); @@ -224,6 +248,10 @@ static void rx_anqp_query_list_id(struct hostapd_data *hapd, u16 info_id, set_anqp_req(ANQP_REQ_CAPABILITY_LIST, "Capability List", 1, 0, 0, qi); break; + case ANQP_VENUE_NAME: + set_anqp_req(ANQP_REQ_VENUE_NAME, "Venue Name", + hapd->conf->venue_name != NULL, 0, 0, qi); + break; case ANQP_ROAMING_CONSORTIUM: set_anqp_req(ANQP_REQ_ROAMING_CONSORTIUM, "Roaming Consortium", hapd->conf->roaming_consortium != NULL, 0, 0, qi); diff --git a/src/ap/gas_serv.h b/src/ap/gas_serv.h index 7116e7922..0e2eaf66d 100644 --- a/src/ap/gas_serv.h +++ b/src/ap/gas_serv.h @@ -11,6 +11,8 @@ #define ANQP_REQ_CAPABILITY_LIST \ (1 << (ANQP_CAPABILITY_LIST - ANQP_QUERY_LIST)) +#define ANQP_REQ_VENUE_NAME \ + (1 << (ANQP_VENUE_NAME - ANQP_QUERY_LIST)) #define ANQP_REQ_ROAMING_CONSORTIUM \ (1 << (ANQP_ROAMING_CONSORTIUM - ANQP_QUERY_LIST))