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:
parent
ea8e033e92
commit
ae9d45f329
7 changed files with 378 additions and 17 deletions
136
src/p2p/p2p.c
136
src/p2p/p2p.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue