From: Max Stepanov Date: Thu, 2 Jul 2015 13:21:20 +0000 (+0300) Subject: P2PS: Add CPT parameter to P2P_SERVICE_ADD asp command X-Git-Tag: hostap_2_5~289 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=mech_eap.git;a=commitdiff_plain;h=e2b7fbf2fb3491ce828da7079244196ce03c3fd4 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=[:] where 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 Reviewed-by: Andrei Otcheretianski Reviewed-by: Ilan Peer --- diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index f33f914..92a2f8b 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -1076,6 +1076,10 @@ enum p2p_attr_id { #define P2P_GROUP_CAPAB_GROUP_FORMATION BIT(6) #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 */ #define P2P_INVITATION_FLAGS_TYPE BIT(0) diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 49c35d6..b106fcf 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -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, 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; u8 buf[P2PS_HASH_LEN]; 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; 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; 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) { adv_data->svc_info = &adv_data->svc_name[adv_len + 1]; 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: 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); + "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_data->cpt_mask); return 0; } diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 6812cda..b195687 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -21,6 +21,7 @@ #define P2PS_WILD_HASH_STR "org.wi-fi.wfds" #define P2PS_HASH_LEN 6 #define P2P_MAX_QUERY_HASH 6 +#define P2PS_FEATURE_CAPAB_CPT_MAX 2 /** * P2P_MAX_REG_CLASSES - Maximum number of regulatory classes @@ -235,6 +236,23 @@ struct p2ps_advertisement { 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 */ char svc_name[0]; @@ -2251,7 +2269,8 @@ 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); + u16 config_methods, const char *svc_info, + const u8 *cpt_priority); int p2p_service_del_asp(struct p2p_data *p2p, u32 adv_id); void p2p_service_flush_asp(struct p2p_data *p2p); struct p2ps_advertisement * p2p_get_p2ps_adv_list(struct p2p_data *p2p); diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index aad69ec..16fb811 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -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) { struct p2ps_provision *p2ps_prov; @@ -5213,6 +5255,8 @@ static int p2p_ctrl_service_add_asp(struct wpa_supplicant *wpa_s, char *adv_str; u32 auto_accept, adv_id, svc_state, config_methods; char *svc_info = NULL; + char *cpt_prio_str; + u8 cpt_prio[P2PS_FEATURE_CAPAB_CPT_MAX + 1]; pos = os_strchr(cmd, ' '); if (pos == NULL) @@ -5285,6 +5329,19 @@ static int p2p_ctrl_service_add_asp(struct wpa_supplicant *wpa_s, if (pos != NULL) *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 */ if (pos && pos[0]) { 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, (u8) svc_state, (u16) config_methods, - svc_info); + svc_info, cpt_prio); } diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index 1df34d0..b02f924 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -90,7 +90,8 @@ int wpas_p2p_service_del_upnp(struct wpa_supplicant *wpa_s, u8 version, const char *service); int wpas_p2p_service_add_asp(struct wpa_supplicant *wpa_s, int auto_accept, 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); 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); diff --git a/wpa_supplicant/p2p_supplicant_sd.c b/wpa_supplicant/p2p_supplicant_sd.c index f4aa3e0..fc07b07 100644 --- a/wpa_supplicant/p2p_supplicant_sd.c +++ b/wpa_supplicant/p2p_supplicant_sd.c @@ -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 auto_accept, 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 ret; ret = p2p_service_add_asp(wpa_s->global->p2p, auto_accept, adv_id, adv_str, svc_state, config_methods, - svc_info); + svc_info, cpt_priority); if (ret == 0) wpas_p2p_sd_service_update(wpa_s); return ret;