diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 65dd1a32d..14d627998 100644 --- a/src/p2p/p2p.c +++ b/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) { diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 7b18dcfc3..70d3a907e 100644 --- a/src/p2p/p2p.h +++ b/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 diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c index 9f0b3f3d3..67c4b0d3f 100644 --- a/src/p2p/p2p_go_neg.c +++ b/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, diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h index 47524d499..ce699329c 100644 --- a/src/p2p/p2p_i.h +++ b/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; }; /** diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 40380fa18..f91631696 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/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);