P2PS: Add CPT parameter to P2P_SERVICE_ADD asp command
Add Coordination Transport Protocol parameter to P2P_SERVICE_ADD asp command. Extend p2ps_advertisement structure to contain CPT priorities and a supported CPT bitmask. The format of the new parameter: cpt=<cpt>[:<cpt>] where <cpt> is a name of the Coordination Protocol Transport. This implementation supports two CPT names: UDP and MAC. The order of specified CPTs defines their priorities where the first one has the highest priority. Signed-off-by: Max Stepanov <Max.Stepanov@intel.com> Reviewed-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com> Reviewed-by: Ilan Peer <ilan.peer@intel.com>
This commit is contained in:
parent
add5975751
commit
e2b7fbf2fb
6 changed files with 98 additions and 9 deletions
|
@ -1076,6 +1076,10 @@ enum p2p_attr_id {
|
||||||
#define P2P_GROUP_CAPAB_GROUP_FORMATION BIT(6)
|
#define P2P_GROUP_CAPAB_GROUP_FORMATION BIT(6)
|
||||||
#define P2P_GROUP_CAPAB_IP_ADDR_ALLOCATION BIT(7)
|
#define P2P_GROUP_CAPAB_IP_ADDR_ALLOCATION BIT(7)
|
||||||
|
|
||||||
|
/* P2PS Coordination Protocol Transport Bitmap */
|
||||||
|
#define P2PS_FEATURE_CAPAB_UDP_TRANSPORT BIT(0)
|
||||||
|
#define P2PS_FEATURE_CAPAB_MAC_TRANSPORT BIT(1)
|
||||||
|
|
||||||
/* Invitation Flags */
|
/* Invitation Flags */
|
||||||
#define P2P_INVITATION_FLAGS_TYPE BIT(0)
|
#define P2P_INVITATION_FLAGS_TYPE BIT(0)
|
||||||
|
|
||||||
|
|
|
@ -2679,13 +2679,14 @@ int p2p_service_del_asp(struct p2p_data *p2p, u32 adv_id)
|
||||||
|
|
||||||
int p2p_service_add_asp(struct p2p_data *p2p, int auto_accept, 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 *adv_str, u8 svc_state, u16 config_methods,
|
||||||
const char *svc_info)
|
const char *svc_info, const u8 *cpt_priority)
|
||||||
{
|
{
|
||||||
struct p2ps_advertisement *adv_data, *tmp, **prev;
|
struct p2ps_advertisement *adv_data, *tmp, **prev;
|
||||||
u8 buf[P2PS_HASH_LEN];
|
u8 buf[P2PS_HASH_LEN];
|
||||||
size_t adv_data_len, adv_len, info_len = 0;
|
size_t adv_data_len, adv_len, info_len = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (!p2p || !adv_str || !adv_str[0])
|
if (!p2p || !adv_str || !adv_str[0] || !cpt_priority)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!(config_methods & p2p->cfg->config_methods)) {
|
if (!(config_methods & p2p->cfg->config_methods)) {
|
||||||
|
@ -2714,6 +2715,11 @@ int p2p_service_add_asp(struct p2p_data *p2p, int auto_accept, u32 adv_id,
|
||||||
adv_data->auto_accept = (u8) auto_accept;
|
adv_data->auto_accept = (u8) auto_accept;
|
||||||
os_memcpy(adv_data->svc_name, adv_str, adv_len);
|
os_memcpy(adv_data->svc_name, adv_str, adv_len);
|
||||||
|
|
||||||
|
for (i = 0; cpt_priority[i] && i < P2PS_FEATURE_CAPAB_CPT_MAX; i++) {
|
||||||
|
adv_data->cpt_priority[i] = cpt_priority[i];
|
||||||
|
adv_data->cpt_mask |= cpt_priority[i];
|
||||||
|
}
|
||||||
|
|
||||||
if (svc_info && info_len) {
|
if (svc_info && info_len) {
|
||||||
adv_data->svc_info = &adv_data->svc_name[adv_len + 1];
|
adv_data->svc_info = &adv_data->svc_name[adv_len + 1];
|
||||||
os_memcpy(adv_data->svc_info, svc_info, info_len);
|
os_memcpy(adv_data->svc_info, svc_info, info_len);
|
||||||
|
@ -2752,8 +2758,9 @@ int p2p_service_add_asp(struct p2p_data *p2p, int auto_accept, u32 adv_id,
|
||||||
|
|
||||||
inserted:
|
inserted:
|
||||||
p2p_dbg(p2p,
|
p2p_dbg(p2p,
|
||||||
"Added ASP advertisement adv_id=0x%x config_methods=0x%x svc_state=0x%x adv_str='%s'",
|
"Added ASP advertisement adv_id=0x%x config_methods=0x%x svc_state=0x%x adv_str='%s' cpt_mask=0x%x",
|
||||||
adv_id, adv_data->config_methods, svc_state, adv_str);
|
adv_id, adv_data->config_methods, svc_state, adv_str,
|
||||||
|
adv_data->cpt_mask);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#define P2PS_WILD_HASH_STR "org.wi-fi.wfds"
|
#define P2PS_WILD_HASH_STR "org.wi-fi.wfds"
|
||||||
#define P2PS_HASH_LEN 6
|
#define P2PS_HASH_LEN 6
|
||||||
#define P2P_MAX_QUERY_HASH 6
|
#define P2P_MAX_QUERY_HASH 6
|
||||||
|
#define P2PS_FEATURE_CAPAB_CPT_MAX 2
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* P2P_MAX_REG_CLASSES - Maximum number of regulatory classes
|
* P2P_MAX_REG_CLASSES - Maximum number of regulatory classes
|
||||||
|
@ -234,6 +235,23 @@ struct p2ps_advertisement {
|
||||||
*/
|
*/
|
||||||
u8 hash[P2PS_HASH_LEN];
|
u8 hash[P2PS_HASH_LEN];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cpt_mask - supported Coordination Protocol Transport mask
|
||||||
|
*
|
||||||
|
* A bitwise mask of supported ASP Coordination Protocol Transports.
|
||||||
|
* This property is set together and corresponds with cpt_priority.
|
||||||
|
*/
|
||||||
|
u8 cpt_mask;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cpt_priority - Coordination Protocol Transport priority list
|
||||||
|
*
|
||||||
|
* Priorities of supported ASP Coordinatin Protocol Transports.
|
||||||
|
* This property is set together and corresponds with cpt_mask.
|
||||||
|
* The CPT priority list is 0 terminated.
|
||||||
|
*/
|
||||||
|
u8 cpt_priority[P2PS_FEATURE_CAPAB_CPT_MAX + 1];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* svc_name - NULL Terminated UTF-8 Service Name, and svc_info storage
|
* svc_name - NULL Terminated UTF-8 Service Name, and svc_info storage
|
||||||
*/
|
*/
|
||||||
|
@ -2251,7 +2269,8 @@ struct p2ps_advertisement *
|
||||||
p2p_service_p2ps_id(struct p2p_data *p2p, u32 adv_id);
|
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,
|
int p2p_service_add_asp(struct p2p_data *p2p, int auto_accept, u32 adv_id,
|
||||||
const char *adv_str, u8 svc_state,
|
const char *adv_str, u8 svc_state,
|
||||||
u16 config_methods, const char *svc_info);
|
u16 config_methods, const char *svc_info,
|
||||||
|
const u8 *cpt_priority);
|
||||||
int p2p_service_del_asp(struct p2p_data *p2p, u32 adv_id);
|
int p2p_service_del_asp(struct p2p_data *p2p, u32 adv_id);
|
||||||
void p2p_service_flush_asp(struct p2p_data *p2p);
|
void p2p_service_flush_asp(struct p2p_data *p2p);
|
||||||
struct p2ps_advertisement * p2p_get_p2ps_adv_list(struct p2p_data *p2p);
|
struct p2ps_advertisement * p2p_get_p2ps_adv_list(struct p2p_data *p2p);
|
||||||
|
|
|
@ -4652,6 +4652,48 @@ static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int p2ps_ctrl_parse_cpt_priority(const char *pos, u8 *cpt)
|
||||||
|
{
|
||||||
|
const char *last = NULL;
|
||||||
|
const char *token;
|
||||||
|
long int token_len;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
/* Expected predefined CPT names delimited by ':' */
|
||||||
|
for (i = 0; (token = cstr_token(pos, ": \t", &last)); i++) {
|
||||||
|
if (i >= P2PS_FEATURE_CAPAB_CPT_MAX) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"P2PS: CPT name list is too long, expected up to %d names",
|
||||||
|
P2PS_FEATURE_CAPAB_CPT_MAX);
|
||||||
|
cpt[0] = 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
token_len = last - token;
|
||||||
|
|
||||||
|
if (token_len == 3 &&
|
||||||
|
os_memcmp(token, "UDP", token_len) == 0) {
|
||||||
|
cpt[i] = P2PS_FEATURE_CAPAB_UDP_TRANSPORT;
|
||||||
|
} else if (token_len == 3 &&
|
||||||
|
os_memcmp(token, "MAC", token_len) == 0) {
|
||||||
|
cpt[i] = P2PS_FEATURE_CAPAB_MAC_TRANSPORT;
|
||||||
|
} else {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"P2PS: Unsupported CPT name '%s'", token);
|
||||||
|
cpt[0] = 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isblank(*last)) {
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cpt[i] = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct p2ps_provision * p2p_parse_asp_provision_cmd(const char *cmd)
|
static struct p2ps_provision * p2p_parse_asp_provision_cmd(const char *cmd)
|
||||||
{
|
{
|
||||||
struct p2ps_provision *p2ps_prov;
|
struct p2ps_provision *p2ps_prov;
|
||||||
|
@ -5213,6 +5255,8 @@ static int p2p_ctrl_service_add_asp(struct wpa_supplicant *wpa_s,
|
||||||
char *adv_str;
|
char *adv_str;
|
||||||
u32 auto_accept, adv_id, svc_state, config_methods;
|
u32 auto_accept, adv_id, svc_state, config_methods;
|
||||||
char *svc_info = NULL;
|
char *svc_info = NULL;
|
||||||
|
char *cpt_prio_str;
|
||||||
|
u8 cpt_prio[P2PS_FEATURE_CAPAB_CPT_MAX + 1];
|
||||||
|
|
||||||
pos = os_strchr(cmd, ' ');
|
pos = os_strchr(cmd, ' ');
|
||||||
if (pos == NULL)
|
if (pos == NULL)
|
||||||
|
@ -5285,6 +5329,19 @@ static int p2p_ctrl_service_add_asp(struct wpa_supplicant *wpa_s,
|
||||||
if (pos != NULL)
|
if (pos != NULL)
|
||||||
*pos++ = '\0';
|
*pos++ = '\0';
|
||||||
|
|
||||||
|
cpt_prio_str = (pos && pos[0]) ? os_strstr(pos, "cpt=") : NULL;
|
||||||
|
if (cpt_prio_str) {
|
||||||
|
pos = os_strchr(pos, ' ');
|
||||||
|
if (pos != NULL)
|
||||||
|
*pos++ = '\0';
|
||||||
|
|
||||||
|
if (p2ps_ctrl_parse_cpt_priority(cpt_prio_str + 4, cpt_prio))
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
cpt_prio[0] = P2PS_FEATURE_CAPAB_UDP_TRANSPORT;
|
||||||
|
cpt_prio[1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Service and Response Information are optional */
|
/* Service and Response Information are optional */
|
||||||
if (pos && pos[0]) {
|
if (pos && pos[0]) {
|
||||||
size_t len;
|
size_t len;
|
||||||
|
@ -5302,7 +5359,7 @@ static int p2p_ctrl_service_add_asp(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
return wpas_p2p_service_add_asp(wpa_s, auto_accept, adv_id, adv_str,
|
return wpas_p2p_service_add_asp(wpa_s, auto_accept, adv_id, adv_str,
|
||||||
(u8) svc_state, (u16) config_methods,
|
(u8) svc_state, (u16) config_methods,
|
||||||
svc_info);
|
svc_info, cpt_prio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,8 @@ int wpas_p2p_service_del_upnp(struct wpa_supplicant *wpa_s, u8 version,
|
||||||
const char *service);
|
const char *service);
|
||||||
int wpas_p2p_service_add_asp(struct wpa_supplicant *wpa_s, int auto_accept,
|
int wpas_p2p_service_add_asp(struct wpa_supplicant *wpa_s, int auto_accept,
|
||||||
u32 adv_id, const char *adv_str, u8 svc_state,
|
u32 adv_id, const char *adv_str, u8 svc_state,
|
||||||
u16 config_methods, const char *svc_info);
|
u16 config_methods, const char *svc_info,
|
||||||
|
const u8 *cpt_priority);
|
||||||
int wpas_p2p_service_del_asp(struct wpa_supplicant *wpa_s, u32 adv_id);
|
int wpas_p2p_service_del_asp(struct wpa_supplicant *wpa_s, u32 adv_id);
|
||||||
void wpas_p2p_service_flush_asp(struct wpa_supplicant *wpa_s);
|
void wpas_p2p_service_flush_asp(struct wpa_supplicant *wpa_s);
|
||||||
int wpas_p2p_service_p2ps_id_exists(struct wpa_supplicant *wpa_s, u32 adv_id);
|
int wpas_p2p_service_p2ps_id_exists(struct wpa_supplicant *wpa_s, u32 adv_id);
|
||||||
|
|
|
@ -1185,13 +1185,14 @@ int wpas_p2p_service_del_asp(struct wpa_supplicant *wpa_s, u32 adv_id)
|
||||||
int wpas_p2p_service_add_asp(struct wpa_supplicant *wpa_s,
|
int wpas_p2p_service_add_asp(struct wpa_supplicant *wpa_s,
|
||||||
int auto_accept, u32 adv_id,
|
int auto_accept, u32 adv_id,
|
||||||
const char *adv_str, u8 svc_state,
|
const char *adv_str, u8 svc_state,
|
||||||
u16 config_methods, const char *svc_info)
|
u16 config_methods, const char *svc_info,
|
||||||
|
const u8 *cpt_priority)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = p2p_service_add_asp(wpa_s->global->p2p, auto_accept, adv_id,
|
ret = p2p_service_add_asp(wpa_s->global->p2p, auto_accept, adv_id,
|
||||||
adv_str, svc_state, config_methods,
|
adv_str, svc_state, config_methods,
|
||||||
svc_info);
|
svc_info, cpt_priority);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
wpas_p2p_sd_service_update(wpa_s);
|
wpas_p2p_sd_service_update(wpa_s);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in a new issue