]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Allow connection on 6 GHz channels if requested
authorSreeramya Soratkal <ssramya@codeaurora.org>
Tue, 4 May 2021 07:31:49 +0000 (13:01 +0530)
committerJouni Malinen <j@w1.fi>
Mon, 14 Jun 2021 17:24:37 +0000 (20:24 +0300)
Previously, 6 GHz channels were disabled for P2P operations. Use the new
allow_6ghz parameter with P2P_CONNECT, P2P_GROUP_ADD, and P2P_INVITE
commands for P2P connection on the 6 GHz channels when Wi-Fi Display is
enabled on both the devices.

However, the p2p_6ghz_disable parameter in the configuration takes a
higher precedence.

Indicate P2P 6 GHz band capable information in Device Capability Bitmap
of P2P Capability attribute to indicate the P2P Device is capable of P2P
operation in the 6 GHz band.

Signed-off-by: Sreeramya Soratkal <ssramya@codeaurora.org>
src/p2p/p2p.c
src/p2p/p2p.h
src/p2p/p2p_invitation.c
src/p2p/p2p_utils.c
wpa_supplicant/p2p_supplicant.c

index 88cdd4eab4a2a1a200392b472f3f582b63da5a30..9ac505735cbbd04422f701d4fdd6fa1f374476de 100644 (file)
@@ -1412,6 +1412,7 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p)
        const int op_classes_ht40[] = { 126, 127, 116, 117, 0 };
        const int op_classes_vht[] = { 128, 0 };
        const int op_classes_edmg[] = { 181, 182, 183, 0 };
+       const int op_classes_6ghz[] = { 131, 0 };
 
        p2p_dbg(p2p, "Prepare channel best");
 
@@ -1448,6 +1449,12 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p)
                   0) {
                p2p_dbg(p2p, "Select possible EDMG channel (op_class %u channel %u) as operating channel preference",
                        p2p->op_reg_class, p2p->op_channel);
+       } else if (p2p->allow_6ghz &&
+                  (p2p_channel_select(&p2p->cfg->channels, op_classes_6ghz,
+                                      &p2p->op_reg_class, &p2p->op_channel) ==
+                   0)) {
+               p2p_dbg(p2p, "Select possible 6 GHz channel (op_class %u channel %u) as operating channel preference",
+                       p2p->op_reg_class, p2p->op_channel);
        } else if (p2p_channel_select(&p2p->cfg->channels, op_classes_vht,
                                      &p2p->op_reg_class, &p2p->op_channel) ==
                   0) {
@@ -1568,9 +1575,10 @@ int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr,
        p2p_dbg(p2p, "Request to start group negotiation - peer=" MACSTR
                "  GO Intent=%d  Intended Interface Address=" MACSTR
                " wps_method=%d persistent_group=%d pd_before_go_neg=%d "
-               "oob_pw_id=%u",
+               "oob_pw_id=%u allow_6ghz=%d",
                MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr),
-               wps_method, persistent_group, pd_before_go_neg, oob_pw_id);
+               wps_method, persistent_group, pd_before_go_neg, oob_pw_id,
+               p2p->allow_6ghz);
 
        dev = p2p_get_device(p2p, peer_addr);
        if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
@@ -1668,9 +1676,9 @@ int p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr,
 
        p2p_dbg(p2p, "Request to authorize group negotiation - peer=" MACSTR
                "  GO Intent=%d  Intended Interface Address=" MACSTR
-               " wps_method=%d  persistent_group=%d oob_pw_id=%u",
+               " wps_method=%d  persistent_group=%d oob_pw_id=%u allow_6ghz=%d",
                MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr),
-               wps_method, persistent_group, oob_pw_id);
+               wps_method, persistent_group, oob_pw_id, p2p->allow_6ghz);
 
        dev = p2p_get_device(p2p, peer_addr);
        if (dev == NULL) {
index 4c6e8afef0ce5b4fc32e937546cef6fdee10383c..f606fbb14a815392d98e7a8e37107efb11774d5a 100644 (file)
@@ -2422,5 +2422,6 @@ bool p2p_peer_wfd_enabled(struct p2p_data *p2p, const u8 *peer_addr);
 bool p2p_wfd_enabled(struct p2p_data *p2p);
 bool is_p2p_allow_6ghz(struct p2p_data *p2p);
 void set_p2p_allow_6ghz(struct p2p_data *p2p, bool value);
+int p2p_remove_6ghz_channels(unsigned int *pref_freq_list, int size);
 
 #endif /* P2P_H */
index 77d662a47ae2439c9b023c2f5f2abb494083568b..ab0072219d2e16422bf3f6733664e4cbbe983c29 100644 (file)
@@ -653,8 +653,9 @@ int p2p_invite(struct p2p_data *p2p, const u8 *peer, enum p2p_invite_role role,
        struct p2p_device *dev;
 
        p2p_dbg(p2p, "Request to invite peer " MACSTR " role=%d persistent=%d "
-               "force_freq=%u",
-               MAC2STR(peer), role, persistent_group, force_freq);
+               "force_freq=%u allow_6ghz=%d",
+               MAC2STR(peer), role, persistent_group, force_freq,
+               p2p->allow_6ghz);
        if (bssid)
                p2p_dbg(p2p, "Invitation for BSSID " MACSTR, MAC2STR(bssid));
        if (go_dev_addr) {
index 06ab799204b1af29c169c6ac0f45aca0db597899..7d21f68819c732efdb8ac2c72081ecf8c9cfda25 100644 (file)
@@ -517,3 +517,21 @@ void p2p_copy_channels(struct p2p_channels *dst,
        }
        dst->reg_classes = j;
 }
+
+
+int p2p_remove_6ghz_channels(unsigned int *pref_freq_list, int size)
+{
+       int i;
+
+       for (i = 0; i < size; i++) {
+               if (is_6ghz_freq(pref_freq_list[i])) {
+                       wpa_printf(MSG_DEBUG, "P2P: Remove 6 GHz channel %d",
+                                  pref_freq_list[i]);
+                       size--;
+                       os_memmove(&pref_freq_list[i], &pref_freq_list[i + 1],
+                                  (size - i) * sizeof(pref_freq_list[0]));
+                       i--;
+               }
+       }
+       return i;
+}
index b950a648e6404f11f5a22b783723202af6bf0d22..74acb1d436fc125367b4c3f3f36434ef2675e810 100644 (file)
@@ -5424,7 +5424,8 @@ static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq,
        if (freq > 0) {
                freqs[0] = freq;
                params.freqs = freqs;
-       } else if (wpa_s->conf->p2p_6ghz_disable) {
+       } else if (wpa_s->conf->p2p_6ghz_disable ||
+                  !is_p2p_allow_6ghz(wpa_s->global->p2p)) {
                wpa_printf(MSG_DEBUG,
                           "P2P: 6 GHz disabled - update the scan frequency list");
                wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G, &params,
@@ -5461,7 +5462,7 @@ static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq,
         * the new scan results become available.
         */
        ret = wpa_drv_scan(wpa_s, &params);
-       if (wpa_s->conf->p2p_6ghz_disable && params.freqs != freqs)
+       if (params.freqs != freqs)
                os_free(params.freqs);
        if (!ret) {
                os_get_reltime(&wpa_s->scan_trigger_time);
@@ -5691,6 +5692,10 @@ static int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq,
                res = wpa_drv_get_pref_freq_list(wpa_s, iface_type,
                                                 &max_pref_freq,
                                                 pref_freq_list);
+               if (!is_p2p_allow_6ghz(wpa_s->global->p2p))
+                       max_pref_freq = p2p_remove_6ghz_channels(pref_freq_list,
+                                                                max_pref_freq);
+
                if (!res && max_pref_freq > 0) {
                        *num_pref_freq = max_pref_freq;
                        i = 0;
@@ -5750,6 +5755,40 @@ exit_free:
 }
 
 
+static bool is_p2p_6ghz_supported(struct wpa_supplicant *wpa_s,
+                                 const u8 *peer_addr)
+{
+       if (wpa_s->conf->p2p_6ghz_disable ||
+           !get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
+                     HOSTAPD_MODE_IEEE80211A, true))
+               return false;
+
+       if (!p2p_wfd_enabled(wpa_s->global->p2p))
+               return false;
+       if (peer_addr && !p2p_peer_wfd_enabled(wpa_s->global->p2p, peer_addr))
+               return false;
+
+       return true;
+}
+
+
+static int wpas_p2p_check_6ghz(struct wpa_supplicant *wpa_s,
+                              const u8 *peer_addr, bool allow_6ghz, int freq)
+{
+       if (allow_6ghz && is_p2p_6ghz_supported(wpa_s, peer_addr)) {
+               wpa_printf(MSG_DEBUG,
+                          "P2P: Allow connection on 6 GHz channels");
+               p2p_set_6ghz_dev_capab(wpa_s->global->p2p, true);
+       } else {
+               if (is_6ghz_freq(freq))
+                       return -2;
+               p2p_set_6ghz_dev_capab(wpa_s->global->p2p, false);
+       }
+
+       return 0;
+}
+
+
 /**
  * wpas_p2p_connect - Request P2P Group Formation to be started
  * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
@@ -5805,7 +5844,7 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
                        return -1;
        }
 
-       if (is_6ghz_freq(freq) && wpa_s->conf->p2p_6ghz_disable)
+       if (wpas_p2p_check_6ghz(wpa_s, peer_addr, allow_6ghz, freq))
                return -2;
 
        os_free(wpa_s->global->add_psk);
@@ -6083,6 +6122,9 @@ static int wpas_p2p_select_go_freq(struct wpa_supplicant *wpa_s, int freq)
 
                res = wpa_drv_get_pref_freq_list(wpa_s, WPA_IF_P2P_GO,
                                                 &size, pref_freq_list);
+               if (!is_p2p_allow_6ghz(wpa_s->global->p2p))
+                       size = p2p_remove_6ghz_channels(pref_freq_list, size);
+
                if (!res && size > 0) {
                        i = 0;
                        while (i < size &&
@@ -6711,6 +6753,8 @@ int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
 
        if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
                return -1;
+       if (wpas_p2p_check_6ghz(wpa_s, NULL, allow_6ghz, freq))
+               return -1;
 
        os_free(wpa_s->global->add_psk);
        wpa_s->global->add_psk = NULL;
@@ -7448,6 +7492,9 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
        int no_pref_freq_given = pref_freq == 0;
        unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS], size;
 
+       if (wpas_p2p_check_6ghz(wpa_s, NULL, allow_6ghz, freq))
+               return -1;
+
        wpa_s->global->p2p_invite_group = NULL;
        if (peer_addr)
                os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN);
@@ -7586,6 +7633,8 @@ int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
 
        if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
                return -1;
+       if (wpas_p2p_check_6ghz(wpa_s, peer_addr, allow_6ghz, freq))
+               return -1;
 
        size = P2P_MAX_PREF_CHANNELS;
        res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,