P2P: Allow the avoid channels for P2P discovery/negotiation

The avoid channels are notified through
QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY allow minimal traffic, so
enhance the P2P behavior accordingly by considering these avoid
frequencies for P2P discovery/negotiation as long as they are not in
disallowed frequencies list.

Additionally, do not return failure when none of social channels are
available as operation channel, rather, mark the op_channel/op_reg_class
to 0 as this would anyway get selected during the group formation in
p2p_prepare_channel.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Purushottam Kushwaha 2018-12-28 18:12:00 +05:30 committed by Jouni Malinen
parent 0c1e29fd30
commit 59fa205388
6 changed files with 45 additions and 15 deletions

View file

@ -1470,7 +1470,8 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p)
p2p->op_channel = p2p->cfg->op_channel;
} else if (p2p_channel_random_social(&p2p->cfg->channels,
&p2p->op_reg_class,
&p2p->op_channel) == 0) {
&p2p->op_channel,
NULL, NULL) == 0) {
p2p_dbg(p2p, "Select random available social channel (op_class %u channel %u) as operating channel preference",
p2p->op_reg_class, p2p->op_channel);
} else {
@ -4764,9 +4765,12 @@ void p2p_set_managed_oper(struct p2p_data *p2p, int enabled)
int p2p_config_get_random_social(struct p2p_config *p2p, u8 *op_class,
u8 *op_channel)
u8 *op_channel,
struct wpa_freq_range_list *avoid_list,
struct wpa_freq_range_list *disallow_list)
{
return p2p_channel_random_social(&p2p->channels, op_class, op_channel);
return p2p_channel_random_social(&p2p->channels, op_class, op_channel,
avoid_list, disallow_list);
}

View file

@ -2010,6 +2010,8 @@ void p2p_set_managed_oper(struct p2p_data *p2p, int enabled);
* @p2p: P2P config
* @op_class: Selected operating class
* @op_channel: Selected social channel
* @avoid_list: Channel ranges to try to avoid or %NULL
* @disallow_list: Channel ranges to discard or %NULL
* Returns: 0 on success, -1 on failure
*
* This function is used before p2p_init is called. A random social channel
@ -2017,7 +2019,9 @@ void p2p_set_managed_oper(struct p2p_data *p2p, int enabled);
* returned on success.
*/
int p2p_config_get_random_social(struct p2p_config *p2p, u8 *op_class,
u8 *op_channel);
u8 *op_channel,
struct wpa_freq_range_list *avoid_list,
struct wpa_freq_range_list *disallow_list);
int p2p_set_listen_channel(struct p2p_data *p2p, u8 reg_class, u8 channel,
u8 forced);

View file

@ -707,7 +707,9 @@ void p2p_channels_dump(struct p2p_data *p2p, const char *title,
int p2p_channel_select(struct p2p_channels *chans, const int *classes,
u8 *op_class, u8 *op_channel);
int p2p_channel_random_social(struct p2p_channels *chans, u8 *op_class,
u8 *op_channel);
u8 *op_channel,
struct wpa_freq_range_list *avoid_list,
struct wpa_freq_range_list *disallow_list);
/* p2p_parse.c */
void p2p_copy_filter_devname(char *dst, size_t dst_len,

View file

@ -488,7 +488,7 @@ void p2p_process_invitation_resp(struct p2p_data *p2p, const u8 *sa,
if (*msg.status == P2P_SC_FAIL_NO_COMMON_CHANNELS &&
p2p->retry_invite_req &&
p2p_channel_random_social(&p2p->cfg->channels, &p2p->op_reg_class,
&p2p->op_channel) == 0) {
&p2p->op_channel, NULL, NULL) == 0) {
p2p->retry_invite_req = 0;
p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
p2p->cfg->stop_listen(p2p->cfg->cb_ctx);

View file

@ -413,17 +413,30 @@ int p2p_channel_select(struct p2p_channels *chans, const int *classes,
int p2p_channel_random_social(struct p2p_channels *chans, u8 *op_class,
u8 *op_channel)
u8 *op_channel,
struct wpa_freq_range_list *avoid_list,
struct wpa_freq_range_list *disallow_list)
{
u8 chan[4];
unsigned int num_channels = 0;
/* Try to find available social channels from 2.4 GHz */
if (p2p_channels_includes(chans, 81, 1))
/* Try to find available social channels from 2.4 GHz.
* If the avoid_list includes any of the 2.4 GHz social channels, that
* channel is not allowed by p2p_channels_includes() rules. However, it
* is assumed to allow minimal traffic for P2P negotiation, so allow it
* here for social channel selection unless explicitly disallowed in the
* disallow_list. */
if (p2p_channels_includes(chans, 81, 1) ||
(freq_range_list_includes(avoid_list, 2412) &&
!freq_range_list_includes(disallow_list, 2412)))
chan[num_channels++] = 1;
if (p2p_channels_includes(chans, 81, 6))
if (p2p_channels_includes(chans, 81, 6) ||
(freq_range_list_includes(avoid_list, 2437) &&
!freq_range_list_includes(disallow_list, 2437)))
chan[num_channels++] = 6;
if (p2p_channels_includes(chans, 81, 11))
if (p2p_channels_includes(chans, 81, 11) ||
(freq_range_list_includes(avoid_list, 2462) &&
!freq_range_list_includes(disallow_list, 2462)))
chan[num_channels++] = 11;
/* Try to find available social channels from 60 GHz */

View file

@ -4498,7 +4498,10 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
* channel.
*/
if (p2p_config_get_random_social(&p2p, &p2p.reg_class,
&p2p.channel) != 0) {
&p2p.channel,
&global->p2p_go_avoid_freq,
&global->p2p_disallow_freq) !=
0) {
wpa_printf(MSG_INFO,
"P2P: No social channels supported by the driver - do not enable P2P");
return 0;
@ -4523,10 +4526,14 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
* other preference is indicated.
*/
if (p2p_config_get_random_social(&p2p, &p2p.op_reg_class,
&p2p.op_channel) != 0) {
wpa_printf(MSG_ERROR,
&p2p.op_channel, NULL,
NULL) != 0) {
wpa_printf(MSG_INFO,
"P2P: Failed to select random social channel as operation channel");
return -1;
p2p.op_reg_class = 0;
p2p.op_channel = 0;
/* This will be overridden during group setup in
* p2p_prepare_channel(), so allow setup to continue. */
}
p2p.cfg_op_channel = 0;
wpa_printf(MSG_DEBUG, "P2P: Random operating channel: "