]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Allow the avoid channels for P2P discovery/negotiation
authorPurushottam Kushwaha <pkushwah@codeaurora.org>
Fri, 28 Dec 2018 12:42:00 +0000 (18:12 +0530)
committerJouni Malinen <j@w1.fi>
Wed, 30 Jan 2019 10:15:19 +0000 (12:15 +0200)
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>
src/p2p/p2p.c
src/p2p/p2p.h
src/p2p/p2p_i.h
src/p2p/p2p_invitation.c
src/p2p/p2p_utils.c
wpa_supplicant/p2p_supplicant.c

index b4660c4f9616e6b06817769280e7e03a136f8aee..19fa7b78b2664a8fdc60804d940f94e13d9ba8cf 100644 (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);
 }
 
 
index dd2c25d34805eb8218d318334fbf65a72cf0aebe..f2969ee1323731ab6188527764f29b5e3f482cb5 100644 (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);
index 6a4d751c090ab3c452129bbcfbc36044052bf8ef..d2c55c9976c2ea028faa066f69b02dc42c6021ce 100644 (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,
index bbba001a7c93035842144acf7e5c49e5e4d04748..77d662a47ae2439c9b023c2f5f2abb494083568b 100644 (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);
index 2e2aa8ad06f080e716404e2934962ea78892f0e3..1a62a44a2df395f95f0aeb97069747fda55c34f8 100644 (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 */
index 848299d541a753a8db8d3bd9fc068c6ddc16a500..e265128b7a9153479797abfd58d2956841e7be66 100644 (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: "