[PATCH 04/23] P2PS: Send follow-on PD response only if status is 12

Ilan Peer ilan.peer at intel.com
Thu Sep 24 13:37:54 EDT 2015


From: Max Stepanov <Max.Stepanov at intel.com>

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). Currently the supplicant
implementation behaves 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 at intel.com>
---
 src/p2p/p2p.c    | 37 ++++++++++++++++++++++++++++++
 src/p2p/p2p_pd.c | 68 +++++++++++++++++++++++++++++++-------------------------
 2 files changed, 75 insertions(+), 30 deletions(-)

diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index c876f19..53527f4 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -3327,6 +3327,43 @@ static void p2p_prov_disc_cb(struct p2p_data *p2p, int success)
 	}
 
 	/*
+	 * If after PD request the peer doesn't expect to receive PD response
+	 * the PD request ACK indicates a completion of the current PD.
+	 * It 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, 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.
 	 */
diff --git a/src/p2p/p2p_pd.c b/src/p2p/p2p_pd.c
index 8900945..9a22538 100644
--- a/src/p2p/p2p_pd.c
+++ b/src/p2p/p2p_pd.c
@@ -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");
+
+	/*
+	 * 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);
-		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 */
-- 
1.9.1



More information about the HostAP mailing list