Browse Source

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 <jouni@qca.qualcomm.com>
Jouni Malinen 13 years ago
parent
commit
648cc711a5
6 changed files with 96 additions and 0 deletions
  1. 46 0
      hostapd/config_file.c
  2. 9 0
      hostapd/hostapd.conf
  3. 1 0
      src/ap/ap_config.c
  4. 10 0
      src/ap/ap_config.h
  5. 28 0
      src/ap/gas_serv.c
  6. 2 0
      src/ap/gas_serv.h

+ 46 - 0
hostapd/config_file.c

@@ -1175,6 +1175,49 @@ static int parse_roaming_consortium(struct hostapd_bss_config *bss, char *pos,
 
 
 	return 0;
 	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 */
 #endif /* CONFIG_INTERWORKING */
 
 
 
 
@@ -2113,6 +2156,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
 		} else if (os_strcmp(buf, "roaming_consortium") == 0) {
 		} else if (os_strcmp(buf, "roaming_consortium") == 0) {
 			if (parse_roaming_consortium(bss, pos, line) < 0)
 			if (parse_roaming_consortium(bss, pos, line) < 0)
 				errors++;
 				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) {
 		} else if (os_strcmp(buf, "gas_frag_limit") == 0) {
 			bss->gas_frag_limit = atoi(pos);
 			bss->gas_frag_limit = atoi(pos);
 		} else if (os_strcmp(buf, "gas_comeback_delay") == 0) {
 		} else if (os_strcmp(buf, "gas_comeback_delay") == 0) {

+ 9 - 0
hostapd/hostapd.conf

@@ -1118,6 +1118,15 @@ own_ip_addr=127.0.0.1
 #roaming_consortium=021122
 #roaming_consortium=021122
 #roaming_consortium=2233445566
 #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 ##################################################
 ##### Multiple BSSID support ##################################################
 #
 #
 # Above configuration is using the default interface (wlan#, or multi-SSID VLAN
 # Above configuration is using the default interface (wlan#, or multi-SSID VLAN

+ 1 - 0
src/ap/ap_config.c

@@ -465,6 +465,7 @@ static void hostapd_config_free_bss(struct hostapd_bss_config *conf)
 #endif /* CONFIG_WPS */
 #endif /* CONFIG_WPS */
 
 
 	os_free(conf->roaming_consortium);
 	os_free(conf->roaming_consortium);
+	os_free(conf->venue_name);
 
 
 #ifdef CONFIG_RADIUS_TEST
 #ifdef CONFIG_RADIUS_TEST
 	os_free(conf->dump_msk_file);
 	os_free(conf->dump_msk_file);

+ 10 - 0
src/ap/ap_config.h

@@ -142,6 +142,12 @@ struct hostapd_roaming_consortium {
 	u8 oi[MAX_ROAMING_CONSORTIUM_LEN];
 	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
  * struct hostapd_bss_config - Per-BSS configuration
  */
  */
@@ -361,6 +367,10 @@ struct hostapd_bss_config {
 	unsigned int roaming_consortium_count;
 	unsigned int roaming_consortium_count;
 	struct hostapd_roaming_consortium *roaming_consortium;
 	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;
 	u16 gas_comeback_delay;
 	int gas_frag_limit;
 	int gas_frag_limit;
 
 

+ 28 - 0
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);
 	len = gas_anqp_add_element(buf, ANQP_CAPABILITY_LIST);
 	wpabuf_put_le16(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)
 	if (hapd->conf->roaming_consortium)
 		wpabuf_put_le16(buf, ANQP_ROAMING_CONSORTIUM);
 		wpabuf_put_le16(buf, ANQP_ROAMING_CONSORTIUM);
 	gas_anqp_set_element_len(buf, len);
 	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,
 static void anqp_add_roaming_consortium(struct hostapd_data *hapd,
 					struct wpabuf *buf)
 					struct wpabuf *buf)
 {
 {
@@ -171,6 +193,8 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd,
 
 
 	if (request & ANQP_REQ_CAPABILITY_LIST)
 	if (request & ANQP_REQ_CAPABILITY_LIST)
 		anqp_add_capab_list(hapd, buf);
 		anqp_add_capab_list(hapd, buf);
+	if (request & ANQP_REQ_VENUE_NAME)
+		anqp_add_venue_name(hapd, buf);
 	if (request & ANQP_REQ_ROAMING_CONSORTIUM)
 	if (request & ANQP_REQ_ROAMING_CONSORTIUM)
 		anqp_add_roaming_consortium(hapd, buf);
 		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,
 		set_anqp_req(ANQP_REQ_CAPABILITY_LIST, "Capability List", 1, 0,
 			     0, qi);
 			     0, qi);
 		break;
 		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:
 	case ANQP_ROAMING_CONSORTIUM:
 		set_anqp_req(ANQP_REQ_ROAMING_CONSORTIUM, "Roaming Consortium",
 		set_anqp_req(ANQP_REQ_ROAMING_CONSORTIUM, "Roaming Consortium",
 			     hapd->conf->roaming_consortium != NULL, 0, 0, qi);
 			     hapd->conf->roaming_consortium != NULL, 0, 0, qi);

+ 2 - 0
src/ap/gas_serv.h

@@ -11,6 +11,8 @@
 
 
 #define ANQP_REQ_CAPABILITY_LIST \
 #define ANQP_REQ_CAPABILITY_LIST \
 	(1 << (ANQP_CAPABILITY_LIST - ANQP_QUERY_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 \
 #define ANQP_REQ_ROAMING_CONSORTIUM \
 	(1 << (ANQP_ROAMING_CONSORTIUM - ANQP_QUERY_LIST))
 	(1 << (ANQP_ROAMING_CONSORTIUM - ANQP_QUERY_LIST))