diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index fa56d6203..454645162 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -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); diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index eb70dcfb1..a7d9839d8 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -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() diff --git a/src/p2p/p2p_build.c b/src/p2p/p2p_build.c index bd263381b..42acc67bc 100644 --- a/src/p2p/p2p_build.c +++ b/src/p2p/p2p_build.c @@ -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); diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 9d4b23db8..cfa651001 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -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,