P2PS: Send follow-on PD response only if status is 12
When a follow-on PD request is received, peer should not send a follow-on PD response except the case when the PD request status value is 12 (Success: accepted by user). Previously, the wpa_supplicant implementation behaved differently sending the follow-on PD Response on any follow-on PD Request. Fix the issue by adding the following changes: 1. Don't send PD Response if the follow-on PD Request status is different than 12 (seeker side). 2. Don't wait for the follow-on PD Response if the follow-on PD Request was sent with the status different than 12 (advertiser side). 3. If the follow-on PD Request was sent with the status different than 12 use the follow-on PD Request ACK as PD completion event (advertiser side). 4. Notify ASP about the PD completion by sending P2PS-PROV-DONE with the PD Request status (advertiser side). Signed-off-by: Max Stepanov <Max.Stepanov@intel.com>
This commit is contained in:
parent
9773ea38cf
commit
f94e4c20e4
2 changed files with 76 additions and 31 deletions
|
@ -3326,6 +3326,43 @@ static void p2p_prov_disc_cb(struct p2p_data *p2p, int success)
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If after PD Request the peer doesn't expect to receive PD Response
|
||||
* the PD Request ACK indicates a completion of the current PD. This
|
||||
* happens only on the advertiser side sending the follow-on PD Request
|
||||
* with the status different than 12 (Success: accepted by user).
|
||||
*/
|
||||
if (p2p->p2ps_prov && !p2p->p2ps_prov->pd_seeker &&
|
||||
p2p->p2ps_prov->status != P2P_SC_SUCCESS_DEFERRED) {
|
||||
p2p_dbg(p2p, "P2PS PD completion on Follow-on PD Request ACK");
|
||||
|
||||
if (p2p->send_action_in_progress) {
|
||||
p2p->send_action_in_progress = 0;
|
||||
p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
|
||||
}
|
||||
|
||||
p2p->pending_action_state = P2P_NO_PENDING_ACTION;
|
||||
|
||||
if (p2p->cfg->p2ps_prov_complete) {
|
||||
p2p->cfg->p2ps_prov_complete(
|
||||
p2p->cfg->cb_ctx,
|
||||
p2p->p2ps_prov->status,
|
||||
p2p->p2ps_prov->adv_mac,
|
||||
p2p->p2ps_prov->adv_mac,
|
||||
p2p->p2ps_prov->session_mac,
|
||||
NULL, p2p->p2ps_prov->adv_id,
|
||||
p2p->p2ps_prov->session_id,
|
||||
0, 0, NULL, 0, 0, 0,
|
||||
NULL, NULL, 0);
|
||||
}
|
||||
|
||||
if (p2p->user_initiated_pd)
|
||||
p2p_reset_pending_pd(p2p);
|
||||
|
||||
p2ps_prov_free(p2p);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* This postponing, of resetting pending_action_state, needs to be
|
||||
* done only for user initiated PD requests and not internal ones.
|
||||
|
|
|
@ -728,38 +728,46 @@ out:
|
|||
config_methods = msg.wps_config_methods;
|
||||
else
|
||||
config_methods = 0;
|
||||
resp = p2p_build_prov_disc_resp(p2p, dev, msg.dialog_token, reject,
|
||||
config_methods, adv_id,
|
||||
msg.group_id, msg.group_id_len,
|
||||
msg.persistent_ssid,
|
||||
msg.persistent_ssid_len,
|
||||
(const u8 *) &resp_fcap,
|
||||
sizeof(resp_fcap));
|
||||
if (resp == NULL) {
|
||||
p2p_parse_free(&msg);
|
||||
return;
|
||||
}
|
||||
p2p_dbg(p2p, "Sending Provision Discovery Response");
|
||||
if (rx_freq > 0)
|
||||
freq = rx_freq;
|
||||
else
|
||||
freq = p2p_channel_to_freq(p2p->cfg->reg_class,
|
||||
p2p->cfg->channel);
|
||||
if (freq < 0) {
|
||||
p2p_dbg(p2p, "Unknown regulatory class/channel");
|
||||
wpabuf_free(resp);
|
||||
p2p_parse_free(&msg);
|
||||
return;
|
||||
}
|
||||
p2p->pending_action_state = P2P_PENDING_PD_RESPONSE;
|
||||
if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
|
||||
p2p->cfg->dev_addr,
|
||||
wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
|
||||
p2p_dbg(p2p, "Failed to send Action frame");
|
||||
} else
|
||||
p2p->send_action_in_progress = 1;
|
||||
|
||||
wpabuf_free(resp);
|
||||
/*
|
||||
* Send PD Response for an initial PD Request or for follow-on
|
||||
* PD Request with P2P_SC_SUCCESS_DEFERRED status.
|
||||
*/
|
||||
if (!msg.status || *msg.status == P2P_SC_SUCCESS_DEFERRED) {
|
||||
resp = p2p_build_prov_disc_resp(p2p, dev, msg.dialog_token,
|
||||
reject, config_methods, adv_id,
|
||||
msg.group_id, msg.group_id_len,
|
||||
msg.persistent_ssid,
|
||||
msg.persistent_ssid_len,
|
||||
(const u8 *) &resp_fcap,
|
||||
sizeof(resp_fcap));
|
||||
if (!resp) {
|
||||
p2p_parse_free(&msg);
|
||||
return;
|
||||
}
|
||||
p2p_dbg(p2p, "Sending Provision Discovery Response");
|
||||
if (rx_freq > 0)
|
||||
freq = rx_freq;
|
||||
else
|
||||
freq = p2p_channel_to_freq(p2p->cfg->reg_class,
|
||||
p2p->cfg->channel);
|
||||
if (freq < 0) {
|
||||
p2p_dbg(p2p, "Unknown regulatory class/channel");
|
||||
wpabuf_free(resp);
|
||||
p2p_parse_free(&msg);
|
||||
return;
|
||||
}
|
||||
p2p->pending_action_state = P2P_PENDING_PD_RESPONSE;
|
||||
if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
|
||||
p2p->cfg->dev_addr,
|
||||
wpabuf_head(resp), wpabuf_len(resp),
|
||||
200) < 0)
|
||||
p2p_dbg(p2p, "Failed to send Action frame");
|
||||
else
|
||||
p2p->send_action_in_progress = 1;
|
||||
|
||||
wpabuf_free(resp);
|
||||
}
|
||||
|
||||
if (!p2p->cfg->p2ps_prov_complete) {
|
||||
/* Don't emit anything */
|
||||
|
|
Loading…
Reference in a new issue