P2PS: Extend add/del services logic to support ASP

In addition, add a new P2P_SERVICE_REP command that can be used to
replace existing ASP advertisements.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Krishna Vamsi 2014-12-09 19:32:50 +05:30 committed by Jouni Malinen
parent ea8e033e92
commit ae9d45f329
7 changed files with 378 additions and 17 deletions

View file

@ -2475,6 +2475,132 @@ int p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, char *end)
}
struct p2ps_advertisement *
p2p_service_p2ps_id(struct p2p_data *p2p, u32 adv_id)
{
struct p2ps_advertisement *adv_data;
if (!p2p)
return NULL;
adv_data = p2p->p2ps_adv_list;
while (adv_data) {
if (adv_data->id == adv_id)
return adv_data;
adv_data = adv_data->next;
}
return NULL;
}
int p2p_service_del_asp(struct p2p_data *p2p, u32 adv_id)
{
struct p2ps_advertisement *adv_data;
struct p2ps_advertisement **prior;
if (!p2p)
return -1;
adv_data = p2p->p2ps_adv_list;
prior = &p2p->p2ps_adv_list;
while (adv_data) {
if (adv_data->id == adv_id) {
p2p_dbg(p2p, "Delete ASP adv_id=0x%x", adv_id);
*prior = adv_data->next;
os_free(adv_data);
return 0;
}
prior = &adv_data->next;
adv_data = adv_data->next;
}
return -1;
}
int p2p_service_add_asp(struct p2p_data *p2p, int auto_accept, u32 adv_id,
const char *adv_str, u8 svc_state, u16 config_methods,
const char *svc_info)
{
struct p2ps_advertisement *adv_data, *tmp, **prev;
u8 buf[P2PS_HASH_LEN];
size_t adv_data_len, adv_len, info_len = 0;
if (!p2p || !adv_str || !adv_str[0])
return -1;
if (!(config_methods & p2p->cfg->config_methods)) {
p2p_dbg(p2p, "Config methods not supported svc: 0x%x dev: 0x%x",
config_methods, p2p->cfg->config_methods);
return -1;
}
if (!p2ps_gen_hash(p2p, adv_str, buf))
return -1;
if (svc_info)
info_len = os_strlen(svc_info);
adv_len = os_strlen(adv_str);
adv_data_len = sizeof(struct p2ps_advertisement) + adv_len + 1 +
info_len + 1;
adv_data = os_zalloc(adv_data_len);
if (!adv_data)
return -1;
os_memcpy(adv_data->hash, buf, P2PS_HASH_LEN);
adv_data->id = adv_id;
adv_data->state = svc_state;
adv_data->config_methods = config_methods & p2p->cfg->config_methods;
adv_data->auto_accept = (u8) auto_accept;
os_memcpy(adv_data->svc_name, adv_str, adv_len);
if (svc_info && info_len) {
adv_data->svc_info = &adv_data->svc_name[adv_len + 1];
os_memcpy(adv_data->svc_info, svc_info, info_len);
}
/*
* Group Advertisements by service string. They do not need to be
* sorted, but groups allow easier Probe Response instance grouping
*/
tmp = p2p->p2ps_adv_list;
prev = &p2p->p2ps_adv_list;
while (tmp) {
if (tmp->id == adv_data->id) {
if (os_strcmp(tmp->svc_name, adv_data->svc_name) != 0) {
os_free(adv_data);
return -1;
}
adv_data->next = tmp->next;
*prev = adv_data;
os_free(tmp);
goto inserted;
} else {
if (os_strcmp(tmp->svc_name, adv_data->svc_name) == 0) {
adv_data->next = tmp->next;
tmp->next = adv_data;
goto inserted;
}
}
prev = &tmp->next;
tmp = tmp->next;
}
/* No svc_name match found */
adv_data->next = p2p->p2ps_adv_list;
p2p->p2ps_adv_list = adv_data;
inserted:
p2p_dbg(p2p,
"Added ASP advertisement adv_id=0x%x config_methods=0x%x svc_state=0x%x adv_str='%s'",
adv_id, adv_data->config_methods, svc_state, adv_str);
return 0;
}
int p2p_parse_dev_addr_in_p2p_ie(struct wpabuf *p2p_ie, u8 *dev_addr)
{
struct p2p_message msg;
@ -2623,6 +2749,8 @@ struct p2p_data * p2p_init(const struct p2p_config *cfg)
void p2p_deinit(struct p2p_data *p2p)
{
struct p2ps_advertisement *adv, *prev;
#ifdef CONFIG_WIFI_DISPLAY
wpabuf_free(p2p->wfd_ie_beacon);
wpabuf_free(p2p->wfd_ie_probe_req);
@ -2655,6 +2783,14 @@ void p2p_deinit(struct p2p_data *p2p)
os_free(p2p->after_scan_tx);
p2p_remove_wps_vendor_extensions(p2p);
os_free(p2p->no_go_freq.range);
adv = p2p->p2ps_adv_list;
while (adv) {
prev = adv;
adv = adv->next;
os_free(prev);
}
os_free(p2p);
}

View file

@ -11,6 +11,12 @@
#include "wps/wps_defs.h"
/* P2P ASP Setup Capability */
#define P2PS_SETUP_NONE 0
#define P2PS_SETUP_NEW BIT(0)
#define P2PS_SETUP_CLIENT BIT(1)
#define P2PS_SETUP_GROUP_OWNER BIT(2)
#define P2PS_WILD_HASH_STR "org.wi-fi.wfds"
#define P2PS_HASH_LEN 6
#define P2P_MAX_QUERY_HASH 6
@ -147,6 +153,46 @@ struct p2p_go_neg_results {
unsigned int peer_config_timeout;
};
struct p2ps_advertisement {
struct p2ps_advertisement *next;
/**
* svc_info - Pointer to (internal) Service defined information
*/
char *svc_info;
/**
* id - P2PS Advertisement ID
*/
u32 id;
/**
* config_methods - WPS Methods which are allowed for this service
*/
u16 config_methods;
/**
* state - Current state of the service: 0 - Out Of Service, 1-255 Vendor defined
*/
u8 state;
/**
* auto_accept - Automatically Accept provisioning request if possible.
*/
u8 auto_accept;
/**
* hash - 6 octet Service Name has to match against incoming Probe Requests
*/
u8 hash[P2PS_HASH_LEN];
/**
* svc_name - NULL Terminated UTF-8 Service Name, and svc_info storage
*/
char svc_name[0];
};
struct p2p_data;
enum p2p_scan_type {
@ -2038,4 +2084,11 @@ void p2p_loop_on_known_peers(struct p2p_data *p2p,
void p2p_set_vendor_elems(struct p2p_data *p2p, struct wpabuf **vendor_elem);
struct p2ps_advertisement *
p2p_service_p2ps_id(struct p2p_data *p2p, u32 adv_id);
int p2p_service_add_asp(struct p2p_data *p2p, int auto_accept, u32 adv_id,
const char *adv_str, u8 svc_state,
u16 config_methods, const char *svc_info);
int p2p_service_del_asp(struct p2p_data *p2p, u32 adv_id);
#endif /* P2P_H */

View file

@ -493,6 +493,7 @@ struct p2p_data {
u8 pending_channel_forced;
/* ASP Support */
struct p2ps_advertisement *p2ps_adv_list;
u8 wild_card_hash[P2PS_HASH_LEN];
u8 query_hash[P2P_MAX_QUERY_HASH * P2PS_HASH_LEN];
u8 p2ps_seek;