]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
HS 2.0: Add advertisement of WAN Metrics
authorJay Katabathuni <jkatabat@qca.qualcomm.com>
Sat, 25 Aug 2012 13:09:01 +0000 (16:09 +0300)
committerJouni Malinen <j@w1.fi>
Sat, 25 Aug 2012 17:28:40 +0000 (20:28 +0300)
Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

hostapd/config_file.c
hostapd/hostapd.conf
src/ap/ap_config.c
src/ap/ap_config.h
src/ap/gas_serv.c
src/ap/gas_serv.h

index 8988bf9263fe184339208dd90514c9270ed711d9..9692251f671c7b48f28c228b392f681688f97213 100644 (file)
@@ -1441,6 +1441,71 @@ static int hs20_parse_conn_capab(struct hostapd_bss_config *bss, char *buf,
 
        return 0;
 }
+
+
+static int hs20_parse_wan_metrics(struct hostapd_bss_config *bss, char *buf,
+                                 int line)
+{
+       u8 *wan_metrics;
+       char *pos;
+
+       /* <WAN Info>:<DL Speed>:<UL Speed>:<DL Load>:<UL Load>:<LMD> */
+
+       wan_metrics = os_zalloc(13);
+       if (wan_metrics == NULL)
+               return -1;
+
+       pos = buf;
+       /* WAN Info */
+       if (hexstr2bin(pos, wan_metrics, 1) < 0)
+               goto fail;
+       pos += 2;
+       if (*pos != ':')
+               goto fail;
+       pos++;
+
+       /* Downlink Speed */
+       WPA_PUT_LE32(wan_metrics + 1, atoi(pos));
+       pos = os_strchr(pos, ':');
+       if (pos == NULL)
+               goto fail;
+       pos++;
+
+       /* Uplink Speed */
+       WPA_PUT_LE32(wan_metrics + 5, atoi(pos));
+       pos = os_strchr(pos, ':');
+       if (pos == NULL)
+               goto fail;
+       pos++;
+
+       /* Downlink Load */
+       wan_metrics[9] = atoi(pos);
+       pos = os_strchr(pos, ':');
+       if (pos == NULL)
+               goto fail;
+       pos++;
+
+       /* Uplink Load */
+       wan_metrics[10] = atoi(pos);
+       pos = os_strchr(pos, ':');
+       if (pos == NULL)
+               goto fail;
+       pos++;
+
+       /* LMD */
+       WPA_PUT_LE16(wan_metrics + 11, atoi(pos));
+
+       os_free(bss->hs20_wan_metrics);
+       bss->hs20_wan_metrics = wan_metrics;
+
+       return 0;
+
+fail:
+       wpa_printf(MSG_ERROR, "Line %d: Invalid hs20_wan_metrics '%s'",
+                  line, pos);
+       os_free(wan_metrics);
+       return -1;
+}
 #endif /* CONFIG_HS20 */
 
 
@@ -2609,6 +2674,11 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                        bss->hs20 = atoi(pos);
                } else if (os_strcmp(buf, "disable_dgaf") == 0) {
                        bss->disable_dgaf = atoi(pos);
+               } else if (os_strcmp(buf, "hs20_wan_metrics") == 0) {
+                       if (hs20_parse_wan_metrics(bss, pos, line) < 0) {
+                               errors++;
+                               return errors;
+                       }
                } else if (os_strcmp(buf, "hs20_conn_capab") == 0) {
                        if (hs20_parse_conn_capab(bss, pos, line) < 0) {
                                errors++;
index aa90d78bbb28517b0b8688e1182d0ab291efa8cb..95a9835e92147cc1676b8c1dee16a1c03396857c 100644 (file)
@@ -1412,6 +1412,20 @@ own_ip_addr=127.0.0.1
 #hs20_conn_capab=6:22:1
 #hs20_conn_capab=17:5060:0
 
+# WAN Metrics
+# format: <WAN Info>:<DL Speed>:<UL Speed>:<DL Load>:<UL Load>:<LMD>
+# WAN Info: B0-B1: Link Status, B2: Symmetric Link, B3: At Capabity
+#    (encoded as two hex digits)
+#    Link Status: 1 = Link up, 2 = Link down, 3 = Link in test state
+# Downlink Speed: Estimate of WAN backhaul link current downlink speed in kbps;
+#      1..4294967295; 0 = unknown
+# Uplink Speed: Estimate of WAN backhaul link current uplink speed in kbps
+#      1..4294967295; 0 = unknown
+# Downlink Load: Current load of downlink WAN connection (scaled to 255 = 100%)
+# Uplink Load: Current load of uplink WAN connection (scaled to 255 = 100%)
+# Load Measurement Duration: Duration for measuring downlink/uplink load in
+# tenths of a second (1..65535); 0 if load cannot be determined
+#hs20_wan_metrics=01:8000:1000:80:240:3000
 
 # Operating Class Indication
 # List of operating classes the BSSes in this ESS use. The Global operating
index c4aabdad4ce385bdcfc65c29941db589d70b109e..a2f226e2f9d85af06b6d387399298c5ebc9e6ad3 100644 (file)
@@ -507,6 +507,7 @@ static void hostapd_config_free_bss(struct hostapd_bss_config *conf)
 #endif /* CONFIG_RADIUS_TEST */
 
 #ifdef CONFIG_HS20
+       os_free(conf->hs20_wan_metrics);
        os_free(conf->hs20_connection_capability);
        os_free(conf->hs20_operating_class);
 #endif /* CONFIG_HS20 */
index ebc1b95998c30c3b52b4479c594dc707aef64dc9..5dfc8a615960abae9f4c2c19d7c3c0c86a293538 100644 (file)
@@ -410,6 +410,7 @@ struct hostapd_bss_config {
 #ifdef CONFIG_HS20
        int hs20;
        int disable_dgaf;
+       u8 *hs20_wan_metrics;
        u8 *hs20_connection_capability;
        size_t hs20_connection_capability_len;
        u8 *hs20_operating_class;
index f914eefefa083f846a038c7469330588357d18f7..5572c073fe972e716cfbb1204bc9dad26e4d7b72 100644 (file)
@@ -139,6 +139,8 @@ static void anqp_add_hs_capab_list(struct hostapd_data *hapd,
        wpabuf_put_u8(buf, HS20_STYPE_CAPABILITY_LIST);
        wpabuf_put_u8(buf, 0); /* Reserved */
        wpabuf_put_u8(buf, HS20_STYPE_CAPABILITY_LIST);
+       if (hapd->conf->hs20_wan_metrics)
+               wpabuf_put_u8(buf, HS20_STYPE_WAN_METRICS);
        if (hapd->conf->hs20_connection_capability)
                wpabuf_put_u8(buf, HS20_STYPE_CONNECTION_CAPABILITY);
        if (hapd->conf->hs20_operating_class)
@@ -255,6 +257,21 @@ static void anqp_add_domain_name(struct hostapd_data *hapd, struct wpabuf *buf)
 }
 
 
+static void anqp_add_wan_metrics(struct hostapd_data *hapd,
+                                struct wpabuf *buf)
+{
+       if (hapd->conf->hs20_wan_metrics) {
+               u8 *len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
+               wpabuf_put_be24(buf, OUI_WFA);
+               wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
+               wpabuf_put_u8(buf, HS20_STYPE_WAN_METRICS);
+               wpabuf_put_u8(buf, 0); /* Reserved */
+               wpabuf_put_data(buf, hapd->conf->hs20_wan_metrics, 13);
+               gas_anqp_set_element_len(buf, len);
+       }
+}
+
+
 static void anqp_add_connection_capability(struct hostapd_data *hapd,
                                           struct wpabuf *buf)
 {
@@ -315,6 +332,8 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd,
 
        if (request & ANQP_REQ_HS_CAPABILITY_LIST)
                anqp_add_hs_capab_list(hapd, buf);
+       if (request & ANQP_REQ_WAN_METRICS)
+               anqp_add_wan_metrics(hapd, buf);
        if (request & ANQP_REQ_CONNECTION_CAPABILITY)
                anqp_add_connection_capability(hapd, buf);
        if (request & ANQP_REQ_OPERATING_CLASS)
@@ -430,6 +449,11 @@ static void rx_anqp_hs_query_list(struct hostapd_data *hapd, u8 subtype,
                set_anqp_req(ANQP_REQ_HS_CAPABILITY_LIST, "HS Capability List",
                             1, 0, 0, qi);
                break;
+       case HS20_STYPE_WAN_METRICS:
+               set_anqp_req(ANQP_REQ_WAN_METRICS, "WAN Metrics",
+                            hapd->conf->hs20_wan_metrics != NULL,
+                            0, 0, qi);
+               break;
        case HS20_STYPE_CONNECTION_CAPABILITY:
                set_anqp_req(ANQP_REQ_CONNECTION_CAPABILITY,
                             "Connection Capability",
index e6e373995b0541821a4c313f5aa58779cbdc8191..3902525289ffd4f3f04a0fb7fcbb37282bb76bd0 100644 (file)
@@ -25,6 +25,8 @@
        (1 << (ANQP_DOMAIN_NAME - ANQP_QUERY_LIST))
 #define ANQP_REQ_HS_CAPABILITY_LIST \
        (0x10000 << HS20_STYPE_CAPABILITY_LIST)
+#define ANQP_REQ_WAN_METRICS \
+       (0x10000 << HS20_STYPE_WAN_METRICS)
 #define ANQP_REQ_CONNECTION_CAPABILITY \
        (0x10000 << HS20_STYPE_CONNECTION_CAPABILITY)
 #define ANQP_REQ_OPERATING_CLASS \