]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Add more WPS attributes into Listen state Probe Response
authorJouni Malinen <jouni.malinen@atheros.com>
Mon, 28 Mar 2011 12:24:12 +0000 (15:24 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 28 Mar 2011 12:24:12 +0000 (15:24 +0300)
Configure more WPS attributes in the P2P module and use them
when generating WSC IE for Probe Response frames in Listen state.

src/p2p/p2p.c
src/p2p/p2p.h
src/p2p/p2p_build.c
wpa_supplicant/p2p_supplicant.c

index fa56d62036309c12d56559162d8928fb48e8a7de..454645162a9f642e4e531b28f86ea788911a4774 100644 (file)
@@ -1621,7 +1621,6 @@ struct wpabuf * p2p_build_probe_resp_ies(struct p2p_data *p2p)
        if (buf == NULL)
                return NULL;
 
-       /* TODO: add more info into WPS IE; maybe get from WPS module? */
        p2p_build_wps_ie(p2p, buf, DEV_PW_DEFAULT, 1);
 
        /* P2P IE */
@@ -1954,6 +1953,14 @@ struct p2p_data * p2p_init(const struct p2p_config *cfg)
        os_memcpy(p2p->cfg, cfg, sizeof(*cfg));
        if (cfg->dev_name)
                p2p->cfg->dev_name = os_strdup(cfg->dev_name);
+       if (cfg->manufacturer)
+               p2p->cfg->manufacturer = os_strdup(cfg->manufacturer);
+       if (cfg->model_name)
+               p2p->cfg->model_name = os_strdup(cfg->model_name);
+       if (cfg->model_number)
+               p2p->cfg->model_number = os_strdup(cfg->model_number);
+       if (cfg->serial_number)
+               p2p->cfg->serial_number = os_strdup(cfg->serial_number);
 
        p2p->min_disc_int = 1;
        p2p->max_disc_int = 3;
@@ -1984,6 +1991,10 @@ void p2p_deinit(struct p2p_data *p2p)
        p2p_flush(p2p);
        p2p_free_req_dev_types(p2p);
        os_free(p2p->cfg->dev_name);
+       os_free(p2p->cfg->manufacturer);
+       os_free(p2p->cfg->model_name);
+       os_free(p2p->cfg->model_number);
+       os_free(p2p->cfg->serial_number);
        os_free(p2p->groups);
        wpabuf_free(p2p->sd_resp);
        os_free(p2p->after_scan_tx);
@@ -2053,6 +2064,74 @@ int p2p_set_dev_name(struct p2p_data *p2p, const char *dev_name)
 }
 
 
+int p2p_set_manufacturer(struct p2p_data *p2p, const char *manufacturer)
+{
+       os_free(p2p->cfg->manufacturer);
+       p2p->cfg->manufacturer = NULL;
+       if (manufacturer) {
+               p2p->cfg->manufacturer = os_strdup(manufacturer);
+               if (p2p->cfg->manufacturer == NULL)
+                       return -1;
+       }
+
+       return 0;
+}
+
+
+int p2p_set_model_name(struct p2p_data *p2p, const char *model_name)
+{
+       os_free(p2p->cfg->model_name);
+       p2p->cfg->model_name = NULL;
+       if (model_name) {
+               p2p->cfg->model_name = os_strdup(model_name);
+               if (p2p->cfg->model_name == NULL)
+                       return -1;
+       }
+
+       return 0;
+}
+
+
+int p2p_set_model_number(struct p2p_data *p2p, const char *model_number)
+{
+       os_free(p2p->cfg->model_number);
+       p2p->cfg->model_number = NULL;
+       if (model_number) {
+               p2p->cfg->model_number = os_strdup(model_number);
+               if (p2p->cfg->model_number == NULL)
+                       return -1;
+       }
+
+       return 0;
+}
+
+
+int p2p_set_serial_number(struct p2p_data *p2p, const char *serial_number)
+{
+       os_free(p2p->cfg->serial_number);
+       p2p->cfg->serial_number = NULL;
+       if (serial_number) {
+               p2p->cfg->serial_number = os_strdup(serial_number);
+               if (p2p->cfg->serial_number == NULL)
+                       return -1;
+       }
+
+       return 0;
+}
+
+
+void p2p_set_config_methods(struct p2p_data *p2p, u16 config_methods)
+{
+       p2p->cfg->config_methods = config_methods;
+}
+
+
+void p2p_set_uuid(struct p2p_data *p2p, const u8 *uuid)
+{
+       os_memcpy(p2p->cfg->uuid, uuid, 16);
+}
+
+
 int p2p_set_pri_dev_type(struct p2p_data *p2p, const u8 *pri_dev_type)
 {
        os_memcpy(p2p->cfg->pri_dev_type, pri_dev_type, 8);
index eb70dcfb14fe00cc486e4037ea74f2295dddc9b0..a7d9839d8a83d5ea4cdffafffad6cf2f8b51d8cb 100644 (file)
@@ -251,6 +251,11 @@ struct p2p_config {
         */
        u8 sec_dev_type[P2P_SEC_DEVICE_TYPES][8];
 
+       /**
+        * num_sec_dev_types - Number of sec_dev_type entries
+        */
+       size_t num_sec_dev_types;
+
        /**
         * dev_addr - P2P Device Address
         */
@@ -261,10 +266,13 @@ struct p2p_config {
         */
        char *dev_name;
 
-       /**
-        * num_sec_dev_types - Number of sec_dev_type entries
-        */
-       size_t num_sec_dev_types;
+       char *manufacturer;
+       char *model_name;
+       char *model_number;
+       char *serial_number;
+
+       u8 uuid[16];
+       u16 config_methods;
 
        /**
         * concurrent_operations - Whether concurrent operations are supported
@@ -700,6 +708,14 @@ int p2p_unauthorize(struct p2p_data *p2p, const u8 *addr);
  */
 int p2p_set_dev_name(struct p2p_data *p2p, const char *dev_name);
 
+int p2p_set_manufacturer(struct p2p_data *p2p, const char *manufacturer);
+int p2p_set_model_name(struct p2p_data *p2p, const char *model_name);
+int p2p_set_model_number(struct p2p_data *p2p, const char *model_number);
+int p2p_set_serial_number(struct p2p_data *p2p, const char *serial_number);
+
+void p2p_set_config_methods(struct p2p_data *p2p, u16 config_methods);
+void p2p_set_uuid(struct p2p_data *p2p, const u8 *uuid);
+
 /**
  * p2p_set_pri_dev_type - Set primary device type
  * @p2p: P2P module context from p2p_init()
index bd263381b74de03df741185cd07f572904514be2..42acc67bc05b777d0d60b38fc003b1b509abbbb7 100644 (file)
@@ -330,6 +330,30 @@ void p2p_buf_add_p2p_interface(struct wpabuf *buf, struct p2p_data *p2p)
 }
 
 
+static void p2p_add_wps_string(struct wpabuf *buf, enum wps_attribute attr,
+                              const char *val)
+{
+       size_t len;
+
+       wpabuf_put_be16(buf, attr);
+       len = val ? os_strlen(val) : 0;
+#ifndef CONFIG_WPS_STRICT
+       if (len == 0) {
+               /*
+                * Some deployed WPS implementations fail to parse zeor-length
+                * attributes. As a workaround, send a space character if the
+                * device attribute string is empty.
+                */
+               wpabuf_put_be16(buf, 1);
+               wpabuf_put_u8(buf, ' ');
+       }
+#endif /* CONFIG_WPS_STRICT */
+       wpabuf_put_be16(buf, len);
+       if (val)
+               wpabuf_put_data(buf, val, len);
+}
+
+
 void p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, u16 pw_id,
                      int all_attr)
 {
@@ -355,34 +379,28 @@ void p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, u16 pw_id,
        wpabuf_put_be16(buf, pw_id);
 
        if (all_attr) {
-               size_t nlen;
-
                wpabuf_put_be16(buf, ATTR_RESPONSE_TYPE);
                wpabuf_put_be16(buf, 1);
                wpabuf_put_u8(buf, WPS_RESP_ENROLLEE_INFO);
 
-#if 0
-               /* FIX */
-               wps_build_uuid_e(buf, reg->wps->uuid);
-               wps_build_manufacturer(dev, buf);
-               wps_build_model_name(dev, buf);
-               wps_build_model_number(dev, buf);
-               wps_build_serial_number(dev, buf);
-#endif
+               wps_build_uuid_e(buf, p2p->cfg->uuid);
+               p2p_add_wps_string(buf, ATTR_MANUFACTURER,
+                                  p2p->cfg->manufacturer);
+               p2p_add_wps_string(buf, ATTR_MODEL_NAME, p2p->cfg->model_name);
+               p2p_add_wps_string(buf, ATTR_MODEL_NUMBER,
+                                  p2p->cfg->model_number);
+               p2p_add_wps_string(buf, ATTR_SERIAL_NUMBER,
+                                  p2p->cfg->serial_number);
 
                wpabuf_put_be16(buf, ATTR_PRIMARY_DEV_TYPE);
                wpabuf_put_be16(buf, WPS_DEV_TYPE_LEN);
                wpabuf_put_data(buf, p2p->cfg->pri_dev_type, WPS_DEV_TYPE_LEN);
 
-               wpabuf_put_be16(buf, ATTR_DEV_NAME);
-               nlen = p2p->cfg->dev_name ? os_strlen(p2p->cfg->dev_name) : 0;
-               wpabuf_put_be16(buf, nlen);
-               if (p2p->cfg->dev_name)
-                       wpabuf_put_data(buf, p2p->cfg->dev_name, nlen);
+               p2p_add_wps_string(buf, ATTR_DEV_NAME, p2p->cfg->dev_name);
 
                wpabuf_put_be16(buf, ATTR_CONFIG_METHODS);
                wpabuf_put_be16(buf, 2);
-               wpabuf_put_be16(buf, 0); /* FIX: ? */
+               wpabuf_put_be16(buf, p2p->cfg->config_methods);
        }
 
        wps_build_wfa_ext(buf, 0, NULL, 0);
index 9d4b23db858daf38565f2d7f77814da0fdf6524d..cfa651001ba7956b942585e0d91f4bf87644b0a0 100644 (file)
@@ -2362,6 +2362,14 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
        os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN);
        os_memcpy(p2p.dev_addr, wpa_s->own_addr, ETH_ALEN);
        p2p.dev_name = wpa_s->conf->device_name;
+       p2p.manufacturer = wpa_s->conf->manufacturer;
+       p2p.model_name = wpa_s->conf->model_name;
+       p2p.model_number = wpa_s->conf->model_number;
+       p2p.serial_number = wpa_s->conf->serial_number;
+       if (wpa_s->wps) {
+               os_memcpy(p2p.uuid, wpa_s->wps->uuid, 16);
+               p2p.config_methods = wpa_s->wps->config_methods;
+       }
 
        if (wpa_s->conf->p2p_listen_reg_class &&
            wpa_s->conf->p2p_listen_channel) {
@@ -3891,6 +3899,20 @@ void wpas_p2p_update_config(struct wpa_supplicant *wpa_s)
        if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE)
                p2p_set_pri_dev_type(p2p, wpa_s->conf->device_type);
 
+       if (wpa_s->wps &&
+           (wpa_s->conf->changed_parameters & CFG_CHANGED_CONFIG_METHODS))
+               p2p_set_config_methods(p2p, wpa_s->wps->config_methods);
+
+       if (wpa_s->wps && (wpa_s->conf->changed_parameters & CFG_CHANGED_UUID))
+               p2p_set_uuid(p2p, wpa_s->wps->uuid);
+
+       if (wpa_s->conf->changed_parameters & CFG_CHANGED_WPS_STRING) {
+               p2p_set_manufacturer(p2p, wpa_s->conf->manufacturer);
+               p2p_set_model_name(p2p, wpa_s->conf->model_name);
+               p2p_set_model_number(p2p, wpa_s->conf->model_number);
+               p2p_set_serial_number(p2p, wpa_s->conf->serial_number);
+       }
+
        if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE)
                p2p_set_sec_dev_types(p2p,
                                      (void *) wpa_s->conf->sec_device_type,