P2P: Add more WPS attributes into Listen state Probe Response

Configure more WPS attributes in the P2P module and use them
when generating WSC IE for Probe Response frames in Listen state.
This commit is contained in:
Jouni Malinen 2011-03-28 15:24:12 +03:00 committed by Jouni Malinen
parent b8f64582e3
commit b6e0180035
4 changed files with 156 additions and 21 deletions

View file

@ -1621,7 +1621,6 @@ struct wpabuf * p2p_build_probe_resp_ies(struct p2p_data *p2p)
if (buf == NULL) if (buf == NULL)
return 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_build_wps_ie(p2p, buf, DEV_PW_DEFAULT, 1);
/* P2P IE */ /* P2P IE */
@ -1954,6 +1953,14 @@ struct p2p_data * p2p_init(const struct p2p_config *cfg)
os_memcpy(p2p->cfg, cfg, sizeof(*cfg)); os_memcpy(p2p->cfg, cfg, sizeof(*cfg));
if (cfg->dev_name) if (cfg->dev_name)
p2p->cfg->dev_name = os_strdup(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->min_disc_int = 1;
p2p->max_disc_int = 3; p2p->max_disc_int = 3;
@ -1984,6 +1991,10 @@ void p2p_deinit(struct p2p_data *p2p)
p2p_flush(p2p); p2p_flush(p2p);
p2p_free_req_dev_types(p2p); p2p_free_req_dev_types(p2p);
os_free(p2p->cfg->dev_name); 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); os_free(p2p->groups);
wpabuf_free(p2p->sd_resp); wpabuf_free(p2p->sd_resp);
os_free(p2p->after_scan_tx); 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) 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); os_memcpy(p2p->cfg->pri_dev_type, pri_dev_type, 8);

View file

@ -251,6 +251,11 @@ struct p2p_config {
*/ */
u8 sec_dev_type[P2P_SEC_DEVICE_TYPES][8]; 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 * dev_addr - P2P Device Address
*/ */
@ -261,10 +266,13 @@ struct p2p_config {
*/ */
char *dev_name; char *dev_name;
/** char *manufacturer;
* num_sec_dev_types - Number of sec_dev_type entries char *model_name;
*/ char *model_number;
size_t num_sec_dev_types; char *serial_number;
u8 uuid[16];
u16 config_methods;
/** /**
* concurrent_operations - Whether concurrent operations are supported * 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_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_set_pri_dev_type - Set primary device type
* @p2p: P2P module context from p2p_init() * @p2p: P2P module context from p2p_init()

View 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, void p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, u16 pw_id,
int all_attr) 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); wpabuf_put_be16(buf, pw_id);
if (all_attr) { if (all_attr) {
size_t nlen;
wpabuf_put_be16(buf, ATTR_RESPONSE_TYPE); wpabuf_put_be16(buf, ATTR_RESPONSE_TYPE);
wpabuf_put_be16(buf, 1); wpabuf_put_be16(buf, 1);
wpabuf_put_u8(buf, WPS_RESP_ENROLLEE_INFO); wpabuf_put_u8(buf, WPS_RESP_ENROLLEE_INFO);
#if 0 wps_build_uuid_e(buf, p2p->cfg->uuid);
/* FIX */ p2p_add_wps_string(buf, ATTR_MANUFACTURER,
wps_build_uuid_e(buf, reg->wps->uuid); p2p->cfg->manufacturer);
wps_build_manufacturer(dev, buf); p2p_add_wps_string(buf, ATTR_MODEL_NAME, p2p->cfg->model_name);
wps_build_model_name(dev, buf); p2p_add_wps_string(buf, ATTR_MODEL_NUMBER,
wps_build_model_number(dev, buf); p2p->cfg->model_number);
wps_build_serial_number(dev, buf); p2p_add_wps_string(buf, ATTR_SERIAL_NUMBER,
#endif p2p->cfg->serial_number);
wpabuf_put_be16(buf, ATTR_PRIMARY_DEV_TYPE); wpabuf_put_be16(buf, ATTR_PRIMARY_DEV_TYPE);
wpabuf_put_be16(buf, WPS_DEV_TYPE_LEN); wpabuf_put_be16(buf, WPS_DEV_TYPE_LEN);
wpabuf_put_data(buf, p2p->cfg->pri_dev_type, WPS_DEV_TYPE_LEN); wpabuf_put_data(buf, p2p->cfg->pri_dev_type, WPS_DEV_TYPE_LEN);
wpabuf_put_be16(buf, ATTR_DEV_NAME); p2p_add_wps_string(buf, ATTR_DEV_NAME, p2p->cfg->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);
wpabuf_put_be16(buf, ATTR_CONFIG_METHODS); wpabuf_put_be16(buf, ATTR_CONFIG_METHODS);
wpabuf_put_be16(buf, 2); 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); wps_build_wfa_ext(buf, 0, NULL, 0);

View 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(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN);
os_memcpy(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.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 && if (wpa_s->conf->p2p_listen_reg_class &&
wpa_s->conf->p2p_listen_channel) { 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) if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE)
p2p_set_pri_dev_type(p2p, wpa_s->conf->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) if (wpa_s->conf->changed_parameters & CFG_CHANGED_SEC_DEVICE_TYPE)
p2p_set_sec_dev_types(p2p, p2p_set_sec_dev_types(p2p,
(void *) wpa_s->conf->sec_device_type, (void *) wpa_s->conf->sec_device_type,