]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
HS 2.0: Allow configuration of operator icons
authorJouni Malinen <jouni@codeaurora.org>
Mon, 16 Apr 2018 10:18:57 +0000 (13:18 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 17 Apr 2018 13:40:47 +0000 (16:40 +0300)
This extends hostapd Hotspot 2.0 implementation to allow operator icons
to be made available. The existing hs20_icon parameter is used to define
the icons and the new operator_icon parameter (zero or more entries) is
used to specify which of the available icons are operator icons. The
operator icons are advertised in the Operator Icon Metadata ANQP-element
while the icon data can be fetched using the same mechanism (icon
request/binary file) that was added for the OSU Providers icons.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
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 90f30ddcd05a5d9b4846e56f4f59df5c191542ee..f327cff4520dee318aa218022c18d8c651d43f0a 100644 (file)
@@ -2023,6 +2023,25 @@ static int hs20_parse_osu_service_desc(struct hostapd_bss_config *bss,
        return 0;
 }
 
+
+static int hs20_parse_operator_icon(struct hostapd_bss_config *bss, char *pos,
+                                   int line)
+{
+       char **n;
+
+       n = os_realloc_array(bss->hs20_operator_icon,
+                            bss->hs20_operator_icon_count + 1, sizeof(char *));
+       if (!n)
+               return -1;
+       bss->hs20_operator_icon = n;
+       bss->hs20_operator_icon[bss->hs20_operator_icon_count] = os_strdup(pos);
+       if (!bss->hs20_operator_icon[bss->hs20_operator_icon_count])
+               return -1;
+       bss->hs20_operator_icon_count++;
+
+       return 0;
+}
+
 #endif /* CONFIG_HS20 */
 
 
@@ -3602,6 +3621,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
        } else if (os_strcmp(buf, "osu_service_desc") == 0) {
                if (hs20_parse_osu_service_desc(bss, pos, line) < 0)
                        return 1;
+       } else if (os_strcmp(buf, "operator_icon") == 0) {
+               if (hs20_parse_operator_icon(bss, pos, line) < 0)
+                       return 1;
        } else if (os_strcmp(buf, "subscr_remediation_url") == 0) {
                os_free(bss->subscr_remediation_url);
                bss->subscr_remediation_url = os_strdup(pos);
index eaae3fd1dc58489e7ed291731a8502d99fc1d835..220625651887d7c11235142b1eecae21af0e13d1 100644 (file)
@@ -2158,7 +2158,7 @@ own_ip_addr=127.0.0.1
 # channels 36-48):
 #hs20_operating_class=5173
 
-# OSU icons
+# OSU and Operator icons
 # <Icon Width>:<Icon Height>:<Language code>:<Icon Type>:<Name>:<file path>
 #hs20_icon=32:32:eng:image/png:icon32:/tmp/icon32.png
 #hs20_icon=64:64:eng:image/png:icon64:/tmp/icon64.png
@@ -2184,6 +2184,13 @@ own_ip_addr=127.0.0.1
 #
 #osu_server_uri=...
 
+# Operator Icons
+# Operator icons are specified using references to the hs20_icon entries
+# (Name subfield). This information, if present, is advertsised in the
+# Operator Icon Metadata ANQO-element.
+#operator_icon=icon32
+#operator_icon=icon64
+
 ##### Multiband Operation (MBO) ###############################################
 #
 # MBO enabled
index ad070c3d6bf614ba58d92678e68e901b7cb9dbda..6c0d57eeded6893fd6ac8da6bf219b552a93bc7e 100644 (file)
@@ -612,6 +612,13 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
                }
                os_free(conf->hs20_osu_providers);
        }
+       if (conf->hs20_operator_icon) {
+               size_t i;
+
+               for (i = 0; i < conf->hs20_operator_icon_count; i++)
+                       os_free(conf->hs20_operator_icon[i]);
+               os_free(conf->hs20_operator_icon);
+       }
        os_free(conf->subscr_remediation_url);
 #endif /* CONFIG_HS20 */
 
index 03ab80d43ab9f3bb4589ebb598b17ce561bfbf01..87d485c2cbd063fff86a240edcba668d735978df 100644 (file)
@@ -580,6 +580,8 @@ struct hostapd_bss_config {
                struct hostapd_lang_string *service_desc;
        } *hs20_osu_providers, *last_osu;
        size_t hs20_osu_providers_count;
+       char **hs20_operator_icon;
+       size_t hs20_operator_icon_count;
        unsigned int hs20_deauth_req_timeout;
        char *subscr_remediation_url;
        u8 subscr_remediation_method;
index 53702e0f2db4e5c490cdfcc3c0403a6960470d9f..04fb3e14602cfdef2ce2465fa8067e40dd0c12a0 100644 (file)
@@ -183,6 +183,8 @@ static void anqp_add_hs_capab_list(struct hostapd_data *hapd,
                wpabuf_put_u8(buf, HS20_STYPE_OSU_PROVIDERS_LIST);
        if (hapd->conf->hs20_icons_count)
                wpabuf_put_u8(buf, HS20_STYPE_ICON_REQUEST);
+       if (hapd->conf->hs20_operator_icon_count)
+               wpabuf_put_u8(buf, HS20_STYPE_OPERATOR_ICON_METADATA);
        gas_anqp_set_element_len(buf, len);
 }
 #endif /* CONFIG_HS20 */
@@ -703,6 +705,29 @@ static void anqp_add_operating_class(struct hostapd_data *hapd,
 }
 
 
+static void anqp_add_icon(struct wpabuf *buf, struct hostapd_bss_config *bss,
+                         const char *name)
+{
+       size_t j;
+       struct hs20_icon *icon = NULL;
+
+       for (j = 0; j < bss->hs20_icons_count && !icon; j++) {
+               if (os_strcmp(name, bss->hs20_icons[j].name) == 0)
+                       icon = &bss->hs20_icons[j];
+       }
+       if (!icon)
+               return; /* icon info not found */
+
+       wpabuf_put_le16(buf, icon->width);
+       wpabuf_put_le16(buf, icon->height);
+       wpabuf_put_data(buf, icon->language, 3);
+       wpabuf_put_u8(buf, os_strlen(icon->type));
+       wpabuf_put_str(buf, icon->type);
+       wpabuf_put_u8(buf, os_strlen(icon->name));
+       wpabuf_put_str(buf, icon->name);
+}
+
+
 static void anqp_add_osu_provider(struct wpabuf *buf,
                                  struct hostapd_bss_config *bss,
                                  struct hs20_osu_provider *p)
@@ -737,26 +762,8 @@ static void anqp_add_osu_provider(struct wpabuf *buf,
 
        /* Icons Available */
        len2 = wpabuf_put(buf, 2);
-       for (i = 0; i < p->icons_count; i++) {
-               size_t j;
-               struct hs20_icon *icon = NULL;
-
-               for (j = 0; j < bss->hs20_icons_count && !icon; j++) {
-                       if (os_strcmp(p->icons[i], bss->hs20_icons[j].name) ==
-                           0)
-                               icon = &bss->hs20_icons[j];
-               }
-               if (!icon)
-                       continue; /* icon info not found */
-
-               wpabuf_put_le16(buf, icon->width);
-               wpabuf_put_le16(buf, icon->height);
-               wpabuf_put_data(buf, icon->language, 3);
-               wpabuf_put_u8(buf, os_strlen(icon->type));
-               wpabuf_put_str(buf, icon->type);
-               wpabuf_put_u8(buf, os_strlen(icon->name));
-               wpabuf_put_str(buf, icon->name);
-       }
+       for (i = 0; i < p->icons_count; i++)
+               anqp_add_icon(buf, bss, p->icons[i]);
        WPA_PUT_LE16(len2, (u8 *) wpabuf_put(buf, 0) - len2 - 2);
 
        /* OSU_NAI */
@@ -865,6 +872,30 @@ static void anqp_add_icon_binary_file(struct hostapd_data *hapd,
        gas_anqp_set_element_len(buf, len);
 }
 
+
+static void anqp_add_operator_icon_metadata(struct hostapd_data *hapd,
+                                           struct wpabuf *buf)
+{
+       struct hostapd_bss_config *bss = hapd->conf;
+       size_t i;
+       u8 *len;
+
+       if (!bss->hs20_operator_icon_count)
+               return;
+
+       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_OPERATOR_ICON_METADATA);
+       wpabuf_put_u8(buf, 0); /* Reserved */
+
+       for (i = 0; i < bss->hs20_operator_icon_count; i++)
+               anqp_add_icon(buf, bss, bss->hs20_operator_icon[i]);
+
+       gas_anqp_set_element_len(buf, len);
+}
+
 #endif /* CONFIG_HS20 */
 
 
@@ -991,6 +1022,8 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd,
                anqp_add_osu_providers_list(hapd, buf);
        if (request & ANQP_REQ_ICON_REQUEST)
                anqp_add_icon_binary_file(hapd, buf, icon_name, icon_name_len);
+       if (request & ANQP_REQ_OPERATOR_ICON_METADATA)
+               anqp_add_operator_icon_metadata(hapd, buf);
 #endif /* CONFIG_HS20 */
 
 #ifdef CONFIG_MBO
@@ -1178,6 +1211,11 @@ static void rx_anqp_hs_query_list(struct hostapd_data *hapd, u8 subtype,
                set_anqp_req(ANQP_REQ_OSU_PROVIDERS_LIST, "OSU Providers list",
                             hapd->conf->hs20_osu_providers_count, qi);
                break;
+       case HS20_STYPE_OPERATOR_ICON_METADATA:
+               set_anqp_req(ANQP_REQ_OPERATOR_ICON_METADATA,
+                            "Operator Icon Metadata",
+                            hapd->conf->hs20_operator_icon_count, qi);
+               break;
        default:
                wpa_printf(MSG_DEBUG, "ANQP: Unsupported HS 2.0 subtype %u",
                           subtype);
index 3a30298136c9609ea0cdcb789f818bc49dfe68b2..0afdcb1414951b83fb97228edc876ced31e883f0 100644 (file)
@@ -60,6 +60,8 @@
        (0x10000 << HS20_STYPE_OSU_PROVIDERS_LIST)
 #define ANQP_REQ_ICON_REQUEST \
        (0x10000 << HS20_STYPE_ICON_REQUEST)
+#define ANQP_REQ_OPERATOR_ICON_METADATA \
+       (0x10000 << HS20_STYPE_OPERATOR_ICON_METADATA)
 /* The first MBO ANQP-element can be included in the optimized bitmap. */
 #define ANQP_REQ_MBO_CELL_DATA_CONN_PREF \
        (BIT(29) << MBO_ANQP_SUBTYPE_CELL_CONN_PREF)