Interworking: Add support for configuring Roaming Consortium List
authorJouni Malinen <jouni@qca.qualcomm.com>
Mon, 17 Oct 2011 20:55:50 +0000 (23:55 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 17 Oct 2011 20:55:50 +0000 (23:55 +0300)
hostapd/config_file.c
hostapd/hostapd.conf
src/ap/ap_config.c
src/ap/ap_config.h
src/ap/ap_drv_ops.c
src/ap/beacon.c
src/ap/ieee802_11.h
src/ap/ieee802_11_shared.c
src/common/ieee802_11_defs.h

index a148e39..b84545d 100644 (file)
@@ -1142,6 +1142,40 @@ static int hostapd_config_check(struct hostapd_config *conf)
 }
 
 
+#ifdef CONFIG_INTERWORKING
+static int parse_roaming_consortium(struct hostapd_bss_config *bss, char *pos,
+                                   int line)
+{
+       size_t len = os_strlen(pos);
+       u8 oi[MAX_ROAMING_CONSORTIUM_LEN];
+
+       struct hostapd_roaming_consortium *rc;
+
+       if ((len & 1) || len < 2 * 3 || len / 2 > MAX_ROAMING_CONSORTIUM_LEN ||
+           hexstr2bin(pos, oi, len / 2)) {
+               wpa_printf(MSG_ERROR, "Line %d: invalid roaming_consortium "
+                          "'%s'", line, pos);
+               return -1;
+       }
+       len /= 2;
+
+       rc = os_realloc(bss->roaming_consortium,
+                       sizeof(struct hostapd_roaming_consortium) *
+                       (bss->roaming_consortium_count + 1));
+       if (rc == NULL)
+               return -1;
+
+       os_memcpy(rc[bss->roaming_consortium_count].oi, oi, len);
+       rc[bss->roaming_consortium_count].len = len;
+
+       bss->roaming_consortium = rc;
+       bss->roaming_consortium_count++;
+
+       return 0;
+}
+#endif /* CONFIG_INTERWORKING */
+
+
 /**
  * hostapd_config_read - Read and parse a configuration file
  * @fname: Configuration file name (including path, if needed)
@@ -2089,6 +2123,9 @@ struct hostapd_config * hostapd_config_read(const char *fname)
                                           "hessid", line);
                                errors++;
                        }
+               } else if (os_strcmp(buf, "roaming_consortium") == 0) {
+                       if (parse_roaming_consortium(bss, pos, line) < 0)
+                               errors++;
 #endif /* CONFIG_INTERWORKING */
                } else {
                        wpa_printf(MSG_ERROR, "Line %d: unknown configuration "
index be02720..d5ab422 100644 (file)
@@ -1072,6 +1072,15 @@ own_ip_addr=127.0.0.1
 # ESS.
 #hessid=02:03:04:05:06:07
 
+# Roaming Consortium List
+# Arbitrary number of Roaming Consortium OIs can be configured with each line
+# adding a new OI to the list. The first three entries are available through
+# Beacon and Probe Response frames. Any additional entry will be available only
+# through ANQP queries. Each OI is between 3 and 15 octets and is configured a
+# a hexstring.
+#roaming_consortium=021122
+#roaming_consortium=2233445566
+
 ##### Multiple BSSID support ##################################################
 #
 # Above configuration is using the default interface (wlan#, or multi-SSID VLAN
index e77716b..0e6f476 100644 (file)
@@ -467,6 +467,8 @@ static void hostapd_config_free_bss(struct hostapd_bss_config *conf)
        os_free(conf->model_url);
        os_free(conf->upc);
 #endif /* CONFIG_WPS */
+
+       os_free(conf->roaming_consortium);
 }
 
 
index 46975f7..ce63a10 100644 (file)
@@ -142,6 +142,13 @@ struct hostapd_wmm_ac_params {
 };
 
 
+#define MAX_ROAMING_CONSORTIUM_LEN 15
+
+struct hostapd_roaming_consortium {
+       u8 len;
+       u8 oi[MAX_ROAMING_CONSORTIUM_LEN];
+};
+
 /**
  * struct hostapd_bss_config - Per-BSS configuration
  */
@@ -346,6 +353,10 @@ struct hostapd_bss_config {
        u8 venue_group;
        u8 venue_type;
        u8 hessid[ETH_ALEN];
+
+       /* IEEE 802.11u - Roaming Consortium list */
+       unsigned int roaming_consortium_count;
+       struct hostapd_roaming_consortium *roaming_consortium;
 };
 
 
index e09c3d8..b585650 100644 (file)
@@ -47,7 +47,7 @@ int hostapd_build_ap_extra_ies(struct hostapd_data *hapd,
                               struct wpabuf **assocresp_ret)
 {
        struct wpabuf *beacon = NULL, *proberesp = NULL, *assocresp = NULL;
-       u8 buf[100], *pos;
+       u8 buf[200], *pos;
 
        *beacon_ret = *proberesp_ret = *assocresp_ret = NULL;
 
@@ -60,6 +60,7 @@ int hostapd_build_ap_extra_ies(struct hostapd_data *hapd,
        }
        pos = hostapd_eid_interworking(hapd, pos);
        pos = hostapd_eid_adv_proto(hapd, pos);
+       pos = hostapd_eid_roaming_consortium(hapd, pos);
        if (pos != buf) {
                if (wpabuf_resize(&beacon, pos - buf) != 0)
                        goto fail;
index 67dbb06..696d5e4 100644 (file)
@@ -359,6 +359,7 @@ void handle_probe_req(struct hostapd_data *hapd,
 
        pos = hostapd_eid_interworking(hapd, pos);
        pos = hostapd_eid_adv_proto(hapd, pos);
+       pos = hostapd_eid_roaming_consortium(hapd, pos);
 
        /* Wi-Fi Alliance WMM */
        pos = hostapd_eid_wmm(hapd, pos);
@@ -495,6 +496,7 @@ void ieee802_11_set_beacon(struct hostapd_data *hapd)
 
        tailpos = hostapd_eid_interworking(hapd, tailpos);
        tailpos = hostapd_eid_adv_proto(hapd, tailpos);
+       tailpos = hostapd_eid_roaming_consortium(hapd, tailpos);
 
        /* Wi-Fi Alliance WMM */
        tailpos = hostapd_eid_wmm(hapd, tailpos);
index 76fb841..1c2c367 100644 (file)
@@ -71,5 +71,6 @@ void ieee802_11_sa_query_action(struct hostapd_data *hapd,
                                const u8 *trans_id);
 u8 * hostapd_eid_interworking(struct hostapd_data *hapd, u8 *eid);
 u8 * hostapd_eid_adv_proto(struct hostapd_data *hapd, u8 *eid);
+u8 * hostapd_eid_roaming_consortium(struct hostapd_data *hapd, u8 *eid);
 
 #endif /* IEEE802_11_H */
index 1597462..6b17bc6 100644 (file)
@@ -262,3 +262,50 @@ u8 * hostapd_eid_adv_proto(struct hostapd_data *hapd, u8 *eid)
 
        return pos;
 }
+
+
+u8 * hostapd_eid_roaming_consortium(struct hostapd_data *hapd, u8 *eid)
+{
+       u8 *pos = eid;
+#ifdef CONFIG_INTERWORKING
+       u8 *len;
+       unsigned int i, count;
+
+       if (!hapd->conf->interworking ||
+           hapd->conf->roaming_consortium == NULL ||
+           hapd->conf->roaming_consortium_count == 0)
+               return eid;
+
+       *pos++ = WLAN_EID_ROAMING_CONSORTIUM;
+       len = pos++;
+
+       /* Number of ANQP OIs (in addition to the max 3 listed here) */
+       if (hapd->conf->roaming_consortium_count > 3 + 255)
+               *pos++ = 255;
+       else if (hapd->conf->roaming_consortium_count > 3)
+               *pos++ = hapd->conf->roaming_consortium_count - 3;
+       else
+               *pos++ = 0;
+
+       /* OU #1 and #2 Lengths */
+       *pos = hapd->conf->roaming_consortium[0].len;
+       if (hapd->conf->roaming_consortium_count > 1)
+               *pos |= hapd->conf->roaming_consortium[1].len << 4;
+       pos++;
+
+       if (hapd->conf->roaming_consortium_count > 3)
+               count = 3;
+       else
+               count = hapd->conf->roaming_consortium_count;
+
+       for (i = 0; i < count; i++) {
+               os_memcpy(pos, hapd->conf->roaming_consortium[i].oi,
+                         hapd->conf->roaming_consortium[i].len);
+               pos += hapd->conf->roaming_consortium[i].len;
+       }
+
+       *len = pos - len - 1;
+#endif /* CONFIG_INTERWORKING */
+
+       return pos;
+}
index 056e90f..5a8ee5f 100644 (file)
 #define WLAN_EID_LINK_ID 101
 #define WLAN_EID_INTERWORKING 107
 #define WLAN_EID_ADV_PROTO 108
+#define WLAN_EID_ROAMING_CONSORTIUM 111
 #define WLAN_EID_EXT_CAPAB 127
 #define WLAN_EID_VENDOR_SPECIFIC 221