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>
This commit is contained in:
Jouni Malinen 2017-02-15 16:07:13 +02:00 committed by Jouni Malinen
parent 1123bd4834
commit 3a7819f0ad
5 changed files with 36 additions and 1 deletions

View file

@ -3034,6 +3034,8 @@ void p2p_flush(struct p2p_data *p2p)
p2p->ssid_set = 0; p2p->ssid_set = 0;
p2ps_prov_free(p2p); p2ps_prov_free(p2p);
p2p_reset_pending_pd(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, struct wpabuf * p2p_build_probe_resp_template(struct p2p_data *p2p,
unsigned int freq) unsigned int freq)
{ {

View file

@ -2373,6 +2373,8 @@ void p2p_expire_peers(struct p2p_data *p2p);
void p2p_set_own_pref_freq_list(struct p2p_data *p2p, void p2p_set_own_pref_freq_list(struct p2p_data *p2p,
const unsigned int *pref_freq_list, const unsigned int *pref_freq_list,
unsigned int size); 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 * p2p_group_get_common_freqs - Get the group common frequencies

View file

@ -315,7 +315,12 @@ static struct wpabuf * p2p_build_go_neg_resp(struct p2p_data *p2p,
group_capab); group_capab);
p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) | tie_breaker); p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) | tie_breaker);
p2p_buf_add_config_timeout(buf, p2p->go_timeout, p2p->client_timeout); 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"); p2p_dbg(p2p, "Omit Operating Channel attribute");
} else { } else {
p2p_buf_add_operating_channel(buf, p2p->cfg->country, p2p_buf_add_operating_channel(buf, p2p->cfg->country,

View file

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

View file

@ -6457,6 +6457,20 @@ static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
return 0; 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'", wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
cmd); cmd);