[PATCH 13/23] P2PS: Process channels in PD request

Ilan Peer ilan.peer
Thu Sep 24 10:38:03 PDT 2015


In case that 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 GoN).

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 at intel.com>
---
 src/p2p/p2p_pd.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 72 insertions(+), 4 deletions(-)

diff --git a/src/p2p/p2p_pd.c b/src/p2p/p2p_pd.c
index d354f76..54db139 100644
--- a/src/p2p/p2p_pd.c
+++ b/src/p2p/p2p_pd.c
@@ -321,10 +321,6 @@ static struct wpabuf * p2p_build_prov_disc_resp(struct p2p_data *p2p,
 
 		/* Add Operating Channel if conncap indicates GO */
 		if (persist || (prov->conncap & P2PS_SETUP_GROUP_OWNER)) {
-			u8 tmp;
-
-			p2p_go_select_channel(p2p, dev, &tmp);
-
 			if (p2p->op_reg_class && p2p->op_channel)
 				p2p_buf_add_operating_channel(
 					buf, p2p->cfg->country,
@@ -740,6 +736,52 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
 			auto_accept = 0;
 		}
 
+		if ((remote_conncap & (P2PS_SETUP_NEW | P2PS_SETUP_CLIENT) ||
+		     msg.persistent_dev) &&
+		    msg.channel_list && msg.channel_list_len &&
+		    (p2p_peer_channels_check(p2p, &p2p->channels, dev,
+					     msg.channel_list,
+					     msg.channel_list_len) < 0) &&
+		    conncap != P2PS_SETUP_NEW) {
+			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 that only the operating channel is
+			 * provided. This requires saving the channel as the
+			 * support 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) {
 			struct p2ps_provision *tmp;
 
@@ -857,10 +899,36 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
 			"Incompatible P2PS feature capability CPT bitmask");
 		reject =
 			P2P_SC_FAIL_INCOMPATIBLE_PARAMS;
+	} else if ((remote_conncap & (P2PS_SETUP_NEW | P2PS_SETUP_CLIENT) ||
+		    msg.persistent_dev) &&
+		   msg.channel_list && msg.channel_list_len &&
+		   conncap != P2PS_SETUP_NEW &&
+		   (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 {
 		reject = P2P_SC_SUCCESS;
 	}
 
+	dev->oper_freq = 0;
+	if (reject == P2P_SC_SUCCESS ||
+	    reject == P2P_SC_SUCCESS_DEFERRED) {
+		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) {
+			u8 tmp;
+
+			if (p2p_go_select_channel(p2p, dev, &tmp) < 0)
+				reject = P2P_SC_FAIL_NO_COMMON_CHANNELS;
+		}
+	}
+
 	p2p->p2ps_prov->status = reject;
 	p2p->p2ps_prov->conncap = conncap;
 
-- 
1.9.1




More information about the Hostap mailing list