Browse Source

P2P: Add P2P_SET override_pref_op_chan to allow overriding preference

This new P2P_SET parameter uses <op_class>:<channel> format and is used
mainly for testing purposes to allow overriding the value of the GO
Negotiation Response frame Operating Channel attribute.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Jouni Malinen 8 years ago
parent
commit
3a7819f0ad
5 changed files with 36 additions and 1 deletions
  1. 10 0
      src/p2p/p2p.c
  2. 2 0
      src/p2p/p2p.h
  3. 6 1
      src/p2p/p2p_go_neg.c
  4. 4 0
      src/p2p/p2p_i.h
  5. 14 0
      wpa_supplicant/ctrl_iface.c

+ 10 - 0
src/p2p/p2p.c

@@ -3034,6 +3034,8 @@ void p2p_flush(struct p2p_data *p2p)
 	p2p->ssid_set = 0;
 	p2ps_prov_free(p2p);
 	p2p_reset_pending_pd(p2p);
+	p2p->override_pref_op_class = 0;
+	p2p->override_pref_channel = 0;
 }
 
 
@@ -5522,6 +5524,14 @@ void p2p_set_own_pref_freq_list(struct p2p_data *p2p,
 }
 
 
+void p2p_set_override_pref_op_chan(struct p2p_data *p2p, u8 op_class,
+				   u8 chan)
+{
+	p2p->override_pref_op_class = op_class;
+	p2p->override_pref_channel = chan;
+}
+
+
 struct wpabuf * p2p_build_probe_resp_template(struct p2p_data *p2p,
 					      unsigned int freq)
 {

+ 2 - 0
src/p2p/p2p.h

@@ -2373,6 +2373,8 @@ void p2p_expire_peers(struct p2p_data *p2p);
 void p2p_set_own_pref_freq_list(struct p2p_data *p2p,
 				const unsigned int *pref_freq_list,
 				unsigned int size);
+void p2p_set_override_pref_op_chan(struct p2p_data *p2p, u8 op_class,
+				   u8 chan);
 
 /**
  * p2p_group_get_common_freqs - Get the group common frequencies

+ 6 - 1
src/p2p/p2p_go_neg.c

@@ -315,7 +315,12 @@ static struct wpabuf * p2p_build_go_neg_resp(struct p2p_data *p2p,
 			       group_capab);
 	p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) | tie_breaker);
 	p2p_buf_add_config_timeout(buf, p2p->go_timeout, p2p->client_timeout);
-	if (peer && peer->go_state == REMOTE_GO && !p2p->num_pref_freq) {
+	if (p2p->override_pref_op_class) {
+		p2p_dbg(p2p, "Override operating channel preference");
+		p2p_buf_add_operating_channel(buf, p2p->cfg->country,
+					      p2p->override_pref_op_class,
+					      p2p->override_pref_channel);
+	} else if (peer && peer->go_state == REMOTE_GO && !p2p->num_pref_freq) {
 		p2p_dbg(p2p, "Omit Operating Channel attribute");
 	} else {
 		p2p_buf_add_operating_channel(buf, p2p->cfg->country,

+ 4 - 0
src/p2p/p2p_i.h

@@ -553,6 +553,10 @@ struct p2p_data {
 
 	unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS];
 	unsigned int num_pref_freq;
+
+	/* Override option for preferred operating channel in GO Negotiation */
+	u8 override_pref_op_class;
+	u8 override_pref_channel;
 };
 
 /**

+ 14 - 0
wpa_supplicant/ctrl_iface.c

@@ -6457,6 +6457,20 @@ static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
 		return 0;
 	}
 
+	if (os_strcmp(cmd, "override_pref_op_chan") == 0) {
+		int op_class, chan;
+
+		op_class = atoi(param);
+		param = os_strchr(param, ':');
+		if (!param)
+			return -1;
+		param++;
+		chan = atoi(param);
+		p2p_set_override_pref_op_chan(wpa_s->global->p2p, op_class,
+					      chan);
+		return 0;
+	}
+
 	wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
 		   cmd);