P2PS: Add feature capability to PD events
Report the feature capability on P2PS-PROV-START and P2PS-PROV-DONE ctrl-iface events. A feature capability value is specified as 'feature_cap=<hex>' event parameter, where <val> is a hexadecimal string of feature capability bytes in a PD Response frame. 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
c3ddf2c798
commit
88f3d7c980
3 changed files with 70 additions and 26 deletions
|
@ -1045,7 +1045,8 @@ struct p2p_config {
|
||||||
u8 conncap, int passwd_id,
|
u8 conncap, int passwd_id,
|
||||||
const u8 *persist_ssid,
|
const u8 *persist_ssid,
|
||||||
size_t persist_ssid_size, int response_done,
|
size_t persist_ssid_size, int response_done,
|
||||||
int prov_start, const char *session_info);
|
int prov_start, const char *session_info,
|
||||||
|
const u8 *feat_cap, size_t feat_cap_len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* prov_disc_resp_cb - Callback for indicating completion of PD Response
|
* prov_disc_resp_cb - Callback for indicating completion of PD Response
|
||||||
|
|
|
@ -774,7 +774,7 @@ out:
|
||||||
NULL, adv_id, session_id,
|
NULL, adv_id, session_id,
|
||||||
0, 0, msg.persistent_ssid,
|
0, 0, msg.persistent_ssid,
|
||||||
msg.persistent_ssid_len,
|
msg.persistent_ssid_len,
|
||||||
0, 0, NULL);
|
0, 0, NULL, NULL, 0);
|
||||||
} else if (msg.status && *msg.status == P2P_SC_SUCCESS_DEFERRED &&
|
} else if (msg.status && *msg.status == P2P_SC_SUCCESS_DEFERRED &&
|
||||||
p2p->p2ps_prov) {
|
p2p->p2ps_prov) {
|
||||||
p2p->p2ps_prov->status = reject;
|
p2p->p2ps_prov->status = reject;
|
||||||
|
@ -787,7 +787,7 @@ out:
|
||||||
session_id, conncap, 0,
|
session_id, conncap, 0,
|
||||||
msg.persistent_ssid,
|
msg.persistent_ssid,
|
||||||
msg.persistent_ssid_len, 0,
|
msg.persistent_ssid_len, 0,
|
||||||
0, NULL);
|
0, NULL, NULL, 0);
|
||||||
else
|
else
|
||||||
p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx,
|
p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx,
|
||||||
*msg.status,
|
*msg.status,
|
||||||
|
@ -797,7 +797,9 @@ out:
|
||||||
passwd_id,
|
passwd_id,
|
||||||
msg.persistent_ssid,
|
msg.persistent_ssid,
|
||||||
msg.persistent_ssid_len, 0,
|
msg.persistent_ssid_len, 0,
|
||||||
0, NULL);
|
0, NULL,
|
||||||
|
(const u8 *) &resp_fcap,
|
||||||
|
sizeof(resp_fcap));
|
||||||
} else if (msg.status && p2p->p2ps_prov) {
|
} else if (msg.status && p2p->p2ps_prov) {
|
||||||
p2p->p2ps_prov->status = P2P_SC_SUCCESS;
|
p2p->p2ps_prov->status = P2P_SC_SUCCESS;
|
||||||
p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, *msg.status, sa,
|
p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, *msg.status, sa,
|
||||||
|
@ -806,7 +808,9 @@ out:
|
||||||
passwd_id,
|
passwd_id,
|
||||||
msg.persistent_ssid,
|
msg.persistent_ssid,
|
||||||
msg.persistent_ssid_len,
|
msg.persistent_ssid_len,
|
||||||
0, 0, NULL);
|
0, 0, NULL,
|
||||||
|
(const u8 *) &resp_fcap,
|
||||||
|
sizeof(resp_fcap));
|
||||||
} else if (msg.status) {
|
} else if (msg.status) {
|
||||||
} else if (auto_accept && reject == P2P_SC_SUCCESS) {
|
} else if (auto_accept && reject == P2P_SC_SUCCESS) {
|
||||||
p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS,
|
p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS,
|
||||||
|
@ -815,7 +819,9 @@ out:
|
||||||
conncap, passwd_id,
|
conncap, passwd_id,
|
||||||
msg.persistent_ssid,
|
msg.persistent_ssid,
|
||||||
msg.persistent_ssid_len,
|
msg.persistent_ssid_len,
|
||||||
0, 0, NULL);
|
0, 0, NULL,
|
||||||
|
(const u8 *) &resp_fcap,
|
||||||
|
sizeof(resp_fcap));
|
||||||
} else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
|
} else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE &&
|
||||||
(!msg.session_info || !msg.session_info_len)) {
|
(!msg.session_info || !msg.session_info_len)) {
|
||||||
p2p->p2ps_prov->method = msg.wps_config_methods;
|
p2p->p2ps_prov->method = msg.wps_config_methods;
|
||||||
|
@ -826,7 +832,9 @@ out:
|
||||||
conncap, passwd_id,
|
conncap, passwd_id,
|
||||||
msg.persistent_ssid,
|
msg.persistent_ssid,
|
||||||
msg.persistent_ssid_len,
|
msg.persistent_ssid_len,
|
||||||
0, 1, NULL);
|
0, 1, NULL,
|
||||||
|
(const u8 *) &resp_fcap,
|
||||||
|
sizeof(resp_fcap));
|
||||||
} else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
|
} else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) {
|
||||||
size_t buf_len = msg.session_info_len;
|
size_t buf_len = msg.session_info_len;
|
||||||
char *buf = os_malloc(2 * buf_len + 1);
|
char *buf = os_malloc(2 * buf_len + 1);
|
||||||
|
@ -842,7 +850,8 @@ out:
|
||||||
adv_mac, session_mac, group_mac, adv_id,
|
adv_mac, session_mac, group_mac, adv_id,
|
||||||
session_id, conncap, passwd_id,
|
session_id, conncap, passwd_id,
|
||||||
msg.persistent_ssid, msg.persistent_ssid_len,
|
msg.persistent_ssid, msg.persistent_ssid_len,
|
||||||
0, 1, buf);
|
0, 1, buf,
|
||||||
|
(const u8 *) &resp_fcap, sizeof(resp_fcap));
|
||||||
|
|
||||||
os_free(buf);
|
os_free(buf);
|
||||||
}
|
}
|
||||||
|
@ -1122,7 +1131,8 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
|
||||||
p2p->p2ps_prov->session_mac,
|
p2p->p2ps_prov->session_mac,
|
||||||
group_mac, adv_id, p2p->p2ps_prov->session_id,
|
group_mac, adv_id, p2p->p2ps_prov->session_id,
|
||||||
conncap, passwd_id, msg.persistent_ssid,
|
conncap, passwd_id, msg.persistent_ssid,
|
||||||
msg.persistent_ssid_len, 1, 0, NULL);
|
msg.persistent_ssid_len, 1, 0, NULL,
|
||||||
|
msg.feature_cap, msg.feature_cap_len);
|
||||||
}
|
}
|
||||||
p2ps_prov_free(p2p);
|
p2ps_prov_free(p2p);
|
||||||
} else if (status != P2P_SC_SUCCESS &&
|
} else if (status != P2P_SC_SUCCESS &&
|
||||||
|
@ -1133,7 +1143,7 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
|
||||||
p2p->cfg->cb_ctx, status, sa, adv_mac,
|
p2p->cfg->cb_ctx, status, sa, adv_mac,
|
||||||
p2p->p2ps_prov->session_mac,
|
p2p->p2ps_prov->session_mac,
|
||||||
group_mac, adv_id, p2p->p2ps_prov->session_id,
|
group_mac, adv_id, p2p->p2ps_prov->session_id,
|
||||||
0, 0, NULL, 0, 1, 0, NULL);
|
0, 0, NULL, 0, 1, 0, NULL, NULL, 0);
|
||||||
p2ps_prov_free(p2p);
|
p2ps_prov_free(p2p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3617,19 +3617,49 @@ static int wpas_remove_stale_groups(void *ctx, const u8 *peer, const u8 *go,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void wpas_p2ps_get_feat_cap_str(char *buf, size_t buf_len,
|
||||||
|
const u8 *feat_cap, size_t feat_cap_len)
|
||||||
|
{
|
||||||
|
static const char pref[] = " feature_cap=";
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
buf[0] = '\0';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We expect a feature capability to contain at least one byte to be
|
||||||
|
* reported. The string buffer provided by the caller function is
|
||||||
|
* expected to be big enough to contain all bytes of the attribute for
|
||||||
|
* known specifications. This function truncates the reported bytes if
|
||||||
|
* the feature capability data exceeds the string buffer size.
|
||||||
|
*/
|
||||||
|
if (!feat_cap || !feat_cap_len || buf_len < sizeof(pref) + 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
os_memcpy(buf, pref, sizeof(pref));
|
||||||
|
ret = wpa_snprintf_hex(&buf[sizeof(pref) - 1],
|
||||||
|
buf_len - sizeof(pref) + 1,
|
||||||
|
feat_cap, feat_cap_len);
|
||||||
|
|
||||||
|
if (ret != (2 * (int) feat_cap_len))
|
||||||
|
wpa_printf(MSG_WARNING, "P2PS feature_cap bytes truncated");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
|
static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
|
||||||
const u8 *adv_mac, const u8 *ses_mac,
|
const u8 *adv_mac, const u8 *ses_mac,
|
||||||
const u8 *grp_mac, u32 adv_id, u32 ses_id,
|
const u8 *grp_mac, u32 adv_id, u32 ses_id,
|
||||||
u8 conncap, int passwd_id,
|
u8 conncap, int passwd_id,
|
||||||
const u8 *persist_ssid,
|
const u8 *persist_ssid,
|
||||||
size_t persist_ssid_size, int response_done,
|
size_t persist_ssid_size, int response_done,
|
||||||
int prov_start, const char *session_info)
|
int prov_start, const char *session_info,
|
||||||
|
const u8 *feat_cap, size_t feat_cap_len)
|
||||||
{
|
{
|
||||||
struct wpa_supplicant *wpa_s = ctx;
|
struct wpa_supplicant *wpa_s = ctx;
|
||||||
u8 mac[ETH_ALEN];
|
u8 mac[ETH_ALEN];
|
||||||
struct wpa_ssid *persistent_go, *stale, *s;
|
struct wpa_ssid *persistent_go, *stale, *s;
|
||||||
int save_config = 0;
|
int save_config = 0;
|
||||||
struct wpa_supplicant *go_wpa_s;
|
struct wpa_supplicant *go_wpa_s;
|
||||||
|
char feat_cap_str[256];
|
||||||
|
|
||||||
if (!dev)
|
if (!dev)
|
||||||
return;
|
return;
|
||||||
|
@ -3642,6 +3672,9 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
|
||||||
if (!grp_mac)
|
if (!grp_mac)
|
||||||
grp_mac = mac;
|
grp_mac = mac;
|
||||||
|
|
||||||
|
wpas_p2ps_get_feat_cap_str(feat_cap_str, sizeof(feat_cap_str),
|
||||||
|
feat_cap, feat_cap_len);
|
||||||
|
|
||||||
if (prov_start) {
|
if (prov_start) {
|
||||||
if (session_info == NULL) {
|
if (session_info == NULL) {
|
||||||
wpa_msg_global(wpa_s, MSG_INFO,
|
wpa_msg_global(wpa_s, MSG_INFO,
|
||||||
|
@ -3649,22 +3682,22 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
|
||||||
" adv_id=%x conncap=%x"
|
" adv_id=%x conncap=%x"
|
||||||
" adv_mac=" MACSTR
|
" adv_mac=" MACSTR
|
||||||
" session=%x mac=" MACSTR
|
" session=%x mac=" MACSTR
|
||||||
" dev_passwd_id=%d",
|
" dev_passwd_id=%d%s",
|
||||||
MAC2STR(dev), adv_id, conncap,
|
MAC2STR(dev), adv_id, conncap,
|
||||||
MAC2STR(adv_mac),
|
MAC2STR(adv_mac),
|
||||||
ses_id, MAC2STR(ses_mac),
|
ses_id, MAC2STR(ses_mac),
|
||||||
passwd_id);
|
passwd_id, feat_cap_str);
|
||||||
} else {
|
} else {
|
||||||
wpa_msg_global(wpa_s, MSG_INFO,
|
wpa_msg_global(wpa_s, MSG_INFO,
|
||||||
P2P_EVENT_P2PS_PROVISION_START MACSTR
|
P2P_EVENT_P2PS_PROVISION_START MACSTR
|
||||||
" adv_id=%x conncap=%x"
|
" adv_id=%x conncap=%x"
|
||||||
" adv_mac=" MACSTR
|
" adv_mac=" MACSTR
|
||||||
" session=%x mac=" MACSTR
|
" session=%x mac=" MACSTR
|
||||||
" dev_passwd_id=%d info='%s'",
|
" dev_passwd_id=%d info='%s'%s",
|
||||||
MAC2STR(dev), adv_id, conncap,
|
MAC2STR(dev), adv_id, conncap,
|
||||||
MAC2STR(adv_mac),
|
MAC2STR(adv_mac),
|
||||||
ses_id, MAC2STR(ses_mac),
|
ses_id, MAC2STR(ses_mac),
|
||||||
passwd_id, session_info);
|
passwd_id, session_info, feat_cap_str);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3686,10 +3719,10 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
|
||||||
P2P_EVENT_P2PS_PROVISION_DONE MACSTR
|
P2P_EVENT_P2PS_PROVISION_DONE MACSTR
|
||||||
" status=%d"
|
" status=%d"
|
||||||
" adv_id=%x adv_mac=" MACSTR
|
" adv_id=%x adv_mac=" MACSTR
|
||||||
" session=%x mac=" MACSTR,
|
" session=%x mac=" MACSTR "%s",
|
||||||
MAC2STR(dev), status,
|
MAC2STR(dev), status,
|
||||||
adv_id, MAC2STR(adv_mac),
|
adv_id, MAC2STR(adv_mac),
|
||||||
ses_id, MAC2STR(ses_mac));
|
ses_id, MAC2STR(ses_mac), feat_cap_str);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3759,10 +3792,10 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
|
||||||
" status=%d"
|
" status=%d"
|
||||||
" adv_id=%x adv_mac=" MACSTR
|
" adv_id=%x adv_mac=" MACSTR
|
||||||
" session=%x mac=" MACSTR
|
" session=%x mac=" MACSTR
|
||||||
" persist=%d",
|
" persist=%d%s",
|
||||||
MAC2STR(dev), status,
|
MAC2STR(dev), status,
|
||||||
adv_id, MAC2STR(adv_mac),
|
adv_id, MAC2STR(adv_mac),
|
||||||
ses_id, MAC2STR(ses_mac), s->id);
|
ses_id, MAC2STR(ses_mac), s->id, feat_cap_str);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3791,7 +3824,7 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
|
||||||
wpa_s, P2P_SC_FAIL_UNKNOWN_GROUP,
|
wpa_s, P2P_SC_FAIL_UNKNOWN_GROUP,
|
||||||
dev, adv_mac, ses_mac,
|
dev, adv_mac, ses_mac,
|
||||||
NULL, adv_id, ses_id, 0, 0,
|
NULL, adv_id, ses_id, 0, 0,
|
||||||
NULL, 0, 0, 0, NULL);
|
NULL, 0, 0, 0, NULL, NULL, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3835,11 +3868,11 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
|
||||||
" status=%d conncap=%x"
|
" status=%d conncap=%x"
|
||||||
" adv_id=%x adv_mac=" MACSTR
|
" adv_id=%x adv_mac=" MACSTR
|
||||||
" session=%x mac=" MACSTR
|
" session=%x mac=" MACSTR
|
||||||
" dev_passwd_id=%d go=%s",
|
" dev_passwd_id=%d go=%s%s",
|
||||||
MAC2STR(dev), status, conncap,
|
MAC2STR(dev), status, conncap,
|
||||||
adv_id, MAC2STR(adv_mac),
|
adv_id, MAC2STR(adv_mac),
|
||||||
ses_id, MAC2STR(ses_mac),
|
ses_id, MAC2STR(ses_mac),
|
||||||
passwd_id, go_ifname);
|
passwd_id, go_ifname, feat_cap_str);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3857,22 +3890,22 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
|
||||||
" status=%d conncap=%x"
|
" status=%d conncap=%x"
|
||||||
" adv_id=%x adv_mac=" MACSTR
|
" adv_id=%x adv_mac=" MACSTR
|
||||||
" session=%x mac=" MACSTR
|
" session=%x mac=" MACSTR
|
||||||
" dev_passwd_id=%d join=" MACSTR,
|
" dev_passwd_id=%d join=" MACSTR "%s",
|
||||||
MAC2STR(dev), status, conncap,
|
MAC2STR(dev), status, conncap,
|
||||||
adv_id, MAC2STR(adv_mac),
|
adv_id, MAC2STR(adv_mac),
|
||||||
ses_id, MAC2STR(ses_mac),
|
ses_id, MAC2STR(ses_mac),
|
||||||
passwd_id, MAC2STR(grp_mac));
|
passwd_id, MAC2STR(grp_mac), feat_cap_str);
|
||||||
} else {
|
} else {
|
||||||
wpa_msg_global(wpa_s, MSG_INFO,
|
wpa_msg_global(wpa_s, MSG_INFO,
|
||||||
P2P_EVENT_P2PS_PROVISION_DONE MACSTR
|
P2P_EVENT_P2PS_PROVISION_DONE MACSTR
|
||||||
" status=%d conncap=%x"
|
" status=%d conncap=%x"
|
||||||
" adv_id=%x adv_mac=" MACSTR
|
" adv_id=%x adv_mac=" MACSTR
|
||||||
" session=%x mac=" MACSTR
|
" session=%x mac=" MACSTR
|
||||||
" dev_passwd_id=%d",
|
" dev_passwd_id=%d%s",
|
||||||
MAC2STR(dev), status, conncap,
|
MAC2STR(dev), status, conncap,
|
||||||
adv_id, MAC2STR(adv_mac),
|
adv_id, MAC2STR(adv_mac),
|
||||||
ses_id, MAC2STR(ses_mac),
|
ses_id, MAC2STR(ses_mac),
|
||||||
passwd_id);
|
passwd_id, feat_cap_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue