P2PS: Process channels in PD Request
In case the P2PS PD Request includes the P2P Channel List attribute, update the peer device supported channels and check if we have common channels with the peer that can be used for the connection establishment based on the connection capabilities: 1. In case of P2PS PD Request with no common channels, defer the flow unless auto accept equals true and the connection capabilities equals NEW (in which case the channels would be negotiated in the GO Negotiation). 2. In case of Follow up P2PS PD Request with no common channels, reject the request unless the connection capability is NEW. In addition, in case of a successful P2PS PD, save the device operating frequency (so it can be later used for join flow, etc.). Signed-off-by: Ilan Peer <ilan.peer@intel.com>
This commit is contained in:
parent
ebd32943cb
commit
23eef57018
1 changed files with 69 additions and 5 deletions
|
@ -329,11 +329,6 @@ static struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p,
|
||||||
|
|
||||||
/* Add Operating Channel if conncap indicates GO */
|
/* Add Operating Channel if conncap indicates GO */
|
||||||
if (persist || (prov->conncap & P2PS_SETUP_GROUP_OWNER)) {
|
if (persist || (prov->conncap & P2PS_SETUP_GROUP_OWNER)) {
|
||||||
u8 tmp;
|
|
||||||
|
|
||||||
if (dev)
|
|
||||||
p2p_go_select_channel(p2p, dev, &tmp);
|
|
||||||
|
|
||||||
if (p2p->op_reg_class && p2p->op_channel)
|
if (p2p->op_reg_class && p2p->op_channel)
|
||||||
p2p_buf_add_operating_channel(
|
p2p_buf_add_operating_channel(
|
||||||
buf, p2p->cfg->country,
|
buf, p2p->cfg->country,
|
||||||
|
@ -748,6 +743,52 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
|
||||||
auto_accept = 0;
|
auto_accept = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((remote_conncap & (P2PS_SETUP_NEW | P2PS_SETUP_CLIENT) ||
|
||||||
|
msg.persistent_dev) && conncap != P2PS_SETUP_NEW &&
|
||||||
|
msg.channel_list && msg.channel_list_len &&
|
||||||
|
p2p_peer_channels_check(p2p, &p2p->channels, dev,
|
||||||
|
msg.channel_list,
|
||||||
|
msg.channel_list_len) < 0) {
|
||||||
|
p2p_dbg(p2p,
|
||||||
|
"No common channels - force deferred flow");
|
||||||
|
auto_accept = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((remote_conncap & P2PS_SETUP_GROUP_OWNER) ||
|
||||||
|
msg.persistent_dev) && msg.operating_channel) {
|
||||||
|
struct p2p_channels intersect;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There are cases where only the operating channel is
|
||||||
|
* provided. This requires saving the channel as the
|
||||||
|
* supported channel list, and verifying that it is
|
||||||
|
* supported.
|
||||||
|
*/
|
||||||
|
if (dev->channels.reg_classes == 0 ||
|
||||||
|
!p2p_channels_includes(&dev->channels,
|
||||||
|
msg.operating_channel[3],
|
||||||
|
msg.operating_channel[4])) {
|
||||||
|
struct p2p_channels *ch = &dev->channels;
|
||||||
|
|
||||||
|
os_memset(ch, 0, sizeof(*ch));
|
||||||
|
ch->reg_class[0].reg_class =
|
||||||
|
msg.operating_channel[3];
|
||||||
|
ch->reg_class[0].channel[0] =
|
||||||
|
msg.operating_channel[4];
|
||||||
|
ch->reg_class[0].channels = 1;
|
||||||
|
ch->reg_classes = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p2p_channels_intersect(&p2p->channels, &dev->channels,
|
||||||
|
&intersect);
|
||||||
|
|
||||||
|
if (intersect.reg_classes == 0) {
|
||||||
|
p2p_dbg(p2p,
|
||||||
|
"No common channels - force deferred flow");
|
||||||
|
auto_accept = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (auto_accept || reject != P2P_SC_SUCCESS) {
|
if (auto_accept || reject != P2P_SC_SUCCESS) {
|
||||||
struct p2ps_provision *tmp;
|
struct p2ps_provision *tmp;
|
||||||
|
|
||||||
|
@ -855,10 +896,33 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
|
||||||
p2p_dbg(p2p,
|
p2p_dbg(p2p,
|
||||||
"Incompatible P2PS feature capability CPT bitmask");
|
"Incompatible P2PS feature capability CPT bitmask");
|
||||||
reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
|
reject = P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
|
||||||
|
} else if ((remote_conncap & (P2PS_SETUP_NEW | P2PS_SETUP_CLIENT) ||
|
||||||
|
msg.persistent_dev) && conncap != P2PS_SETUP_NEW &&
|
||||||
|
msg.channel_list && msg.channel_list_len &&
|
||||||
|
p2p_peer_channels_check(p2p, &p2p->channels, dev,
|
||||||
|
msg.channel_list,
|
||||||
|
msg.channel_list_len) < 0) {
|
||||||
|
p2p_dbg(p2p,
|
||||||
|
"No common channels in Follow-On Provision Discovery Request");
|
||||||
|
reject = P2P_SC_FAIL_NO_COMMON_CHANNELS;
|
||||||
} else {
|
} else {
|
||||||
reject = P2P_SC_SUCCESS;
|
reject = P2P_SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dev->oper_freq = 0;
|
||||||
|
if (reject == P2P_SC_SUCCESS || reject == P2P_SC_SUCCESS_DEFERRED) {
|
||||||
|
u8 tmp;
|
||||||
|
|
||||||
|
if (msg.operating_channel)
|
||||||
|
dev->oper_freq =
|
||||||
|
p2p_channel_to_freq(msg.operating_channel[3],
|
||||||
|
msg.operating_channel[4]);
|
||||||
|
|
||||||
|
if ((conncap & P2PS_SETUP_GROUP_OWNER) &&
|
||||||
|
p2p_go_select_channel(p2p, dev, &tmp) < 0)
|
||||||
|
reject = P2P_SC_FAIL_NO_COMMON_CHANNELS;
|
||||||
|
}
|
||||||
|
|
||||||
p2p->p2ps_prov->status = reject;
|
p2p->p2ps_prov->status = reject;
|
||||||
p2p->p2ps_prov->conncap = conncap;
|
p2p->p2ps_prov->conncap = conncap;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue