[PATCH v2 04/12] P2PS: Process channels in PD Request

Ilan Peer ilan.peer
Thu Oct 8 02:35:59 PDT 2015


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

diff --git a/src/p2p/p2p_pd.c b/src/p2p/p2p_pd.c
index ca8c70d..4505808 100644
--- a/src/p2p/p2p_pd.c
+++ b/src/p2p/p2p_pd.c
@@ -334,11 +334,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;
-
-			if (dev)
-				p2p_go_select_channel(p2p, dev, &tmp);
-
 			if (p2p->op_reg_class && p2p->op_channel)
 				p2p_buf_add_operating_channel(
 					buf, p2p->cfg->country,
@@ -753,6 +748,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;
 
@@ -862,10 +903,36 @@ void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
 		p2p_dbg(p2p,
 			"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