]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Add support for 60 GHz social channel
authorAhmad Masri <qca_amasri@qca.qualcomm.com>
Thu, 25 Sep 2014 09:42:07 +0000 (12:42 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 29 Sep 2014 09:01:46 +0000 (12:01 +0300)
Support 60 GHz band in P2P module by selecting random social channel
from all supported social channels in 2.4 GHz and 60 GHz bands.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/p2p/p2p.c
src/p2p/p2p.h
src/p2p/p2p_utils.c
wpa_supplicant/p2p_supplicant.c

index f0eba1a1bc94f47badb8f29a1837a425651a08c4..9985e4f2583416bfbc10cc0a5e94f3483a8538a1 100644 (file)
@@ -1287,8 +1287,8 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p)
        } else if (p2p_channel_random_social(&p2p->cfg->channels,
                                             &p2p->op_reg_class,
                                             &p2p->op_channel) == 0) {
-               p2p_dbg(p2p, "Select random available social channel %d from 2.4 GHz band as operating channel preference",
-                       p2p->op_channel);
+               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 {
                /* Select any random available channel from the first available
                 * operating class */
@@ -4095,6 +4095,13 @@ 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)
+{
+       return p2p_channel_random_social(&p2p->channels, op_class, op_channel);
+}
+
+
 int p2p_set_listen_channel(struct p2p_data *p2p, u8 reg_class, u8 channel,
                           u8 forced)
 {
index dee79dfb53bfb87b1874e4a1c44dbba1af7a7421..076a2ac1a9b3988e93795228e6285e0e8bed38f2 100644 (file)
@@ -1691,6 +1691,20 @@ void p2p_set_client_discoverability(struct p2p_data *p2p, int enabled);
  */
 void p2p_set_managed_oper(struct p2p_data *p2p, int enabled);
 
+/**
+ * p2p_config_get_random_social - Return a random social channel
+ * @p2p: P2P config
+ * @op_class: Selected operating class
+ * @op_channel: Selected social channel
+ * Returns: 0 on success, -1 on failure
+ *
+ * This function is used before p2p_init is called. A random social channel
+ * from supports bands 2.4 GHz (channels 1,6,11) and 60 GHz (channel 2) is
+ * returned on success.
+ */
+int p2p_config_get_random_social(struct p2p_config *p2p, u8 *op_class,
+                                u8 *op_channel);
+
 int p2p_set_listen_channel(struct p2p_data *p2p, u8 reg_class, u8 channel,
                           u8 forced);
 
index 508a609432e30162f67fe9c166c67cfb3cf14668..23acce7615f6553d6479b9478ea4bee87b9359c6 100644 (file)
@@ -149,6 +149,15 @@ int p2p_freq_to_channel(unsigned int freq, u8 *op_class, u8 *channel)
                return 0;
        }
 
+       if (freq >= 58320 && freq <= 64800) {
+               if ((freq - 58320) % 2160)
+                       return -1;
+
+               *op_class = 180; /* 60 GHz, channels 1..4 */
+               *channel = (freq - 56160) / 2160;
+               return 0;
+       }
+
        return -1;
 }
 
@@ -482,7 +491,7 @@ 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 chan[3];
+       u8 chan[4];
        unsigned int num_channels = 0;
 
        /* Try to find available social channels from 2.4 GHz */
@@ -493,11 +502,18 @@ int p2p_channel_random_social(struct p2p_channels *chans, u8 *op_class,
        if (p2p_channels_includes(chans, 81, 11))
                chan[num_channels++] = 11;
 
+       /* Try to find available social channels from 60 GHz */
+       if (p2p_channels_includes(chans, 180, 2))
+               chan[num_channels++] = 2;
+
        if (num_channels == 0)
                return -1;
 
-       *op_class = 81;
        *op_channel = p2p_channel_pick_random(chan, num_channels);
+       if (*op_channel == 2)
+               *op_class = 180;
+       else
+               *op_class = 81;
 
        return 0;
 }
index e206def7a7a018cb624b08f3432ac94b5581ab9c..1189a6d4b27730f55526715950978fae82fe8879 100644 (file)
@@ -286,8 +286,10 @@ static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
        struct wpa_supplicant *wpa_s = ctx;
        struct wpa_driver_scan_params *params = NULL;
        struct wpabuf *wps_ie, *ies;
+       unsigned int num_channels = 0;
+       int social_channels_freq[] = { 2412, 2437, 2462, 60480 };
        size_t ielen;
-       u8 *n;
+       u8 *n, i;
 
        if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
                return -1;
@@ -341,25 +343,34 @@ static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
 
        switch (type) {
        case P2P_SCAN_SOCIAL:
-               params->freqs = os_malloc(4 * sizeof(int));
+               params->freqs = os_calloc(ARRAY_SIZE(social_channels_freq) + 1,
+                                         sizeof(int));
                if (params->freqs == NULL)
                        goto fail;
-               params->freqs[0] = 2412;
-               params->freqs[1] = 2437;
-               params->freqs[2] = 2462;
-               params->freqs[3] = 0;
+               for (i = 0; i < ARRAY_SIZE(social_channels_freq); i++) {
+                       if (p2p_supported_freq(wpa_s->global->p2p,
+                                              social_channels_freq[i]))
+                               params->freqs[num_channels++] =
+                                       social_channels_freq[i];
+               }
+               params->freqs[num_channels++] = 0;
                break;
        case P2P_SCAN_FULL:
                break;
        case P2P_SCAN_SOCIAL_PLUS_ONE:
-               params->freqs = os_malloc(5 * sizeof(int));
+               params->freqs = os_calloc(ARRAY_SIZE(social_channels_freq) + 2,
+                                         sizeof(int));
                if (params->freqs == NULL)
                        goto fail;
-               params->freqs[0] = 2412;
-               params->freqs[1] = 2437;
-               params->freqs[2] = 2462;
-               params->freqs[3] = freq;
-               params->freqs[4] = 0;
+               for (i = 0; i < ARRAY_SIZE(social_channels_freq); i++) {
+                       if (p2p_supported_freq(wpa_s->global->p2p,
+                                              social_channels_freq[i]))
+                               params->freqs[num_channels++] =
+                                       social_channels_freq[i];
+               }
+               if (p2p_supported_freq(wpa_s->global->p2p, freq))
+                       params->freqs[num_channels++] = freq;
+               params->freqs[num_channels++] = 0;
                break;
        }
 
@@ -3468,7 +3479,7 @@ struct p2p_oper_class_map {
        u8 min_chan;
        u8 max_chan;
        u8 inc;
-       enum { BW20, BW40PLUS, BW40MINUS, BW80 } bw;
+       enum { BW20, BW40PLUS, BW40MINUS, BW80, BW2160 } bw;
 };
 
 static struct p2p_oper_class_map op_class[] = {
@@ -3493,6 +3504,7 @@ static struct p2p_oper_class_map op_class[] = {
         * removing invalid channels.
         */
        { HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80 },
+       { HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160 },
        { -1, 0, 0, 0, 0, BW20 }
 };
 
@@ -3864,7 +3876,6 @@ static int _wpas_p2p_in_progress(void *ctx)
 int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
 {
        struct p2p_config p2p;
-       unsigned int r;
        int i;
 
        if (wpa_s->conf->p2p_disabled)
@@ -3916,23 +3927,32 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
                p2p.config_methods = wpa_s->wps->config_methods;
        }
 
+       if (wpas_p2p_setup_channels(wpa_s, &p2p.channels, &p2p.cli_channels)) {
+               wpa_printf(MSG_ERROR,
+                          "P2P: Failed to configure supported channel list");
+               return -1;
+       }
+
        if (wpa_s->conf->p2p_listen_reg_class &&
            wpa_s->conf->p2p_listen_channel) {
                p2p.reg_class = wpa_s->conf->p2p_listen_reg_class;
                p2p.channel = wpa_s->conf->p2p_listen_channel;
                p2p.channel_forced = 1;
        } else {
-               p2p.reg_class = 81;
                /*
                 * Pick one of the social channels randomly as the listen
                 * channel.
                 */
-               if (os_get_random((u8 *) &r, sizeof(r)) < 0)
+               if (p2p_config_get_random_social(&p2p, &p2p.reg_class,
+                                                &p2p.channel) != 0) {
+                       wpa_printf(MSG_ERROR,
+                                  "P2P: Failed to select random social channel as listen channel");
                        return -1;
-               p2p.channel = 1 + (r % 3) * 5;
+               }
                p2p.channel_forced = 0;
        }
-       wpa_printf(MSG_DEBUG, "P2P: Own listen channel: %d", p2p.channel);
+       wpa_printf(MSG_DEBUG, "P2P: Own listen channel: %d:%d",
+                  p2p.reg_class, p2p.channel);
 
        if (wpa_s->conf->p2p_oper_reg_class &&
            wpa_s->conf->p2p_oper_channel) {
@@ -3943,14 +3963,17 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
                           "%d:%d", p2p.op_reg_class, p2p.op_channel);
 
        } else {
-               p2p.op_reg_class = 81;
                /*
-                * Use random operation channel from (1, 6, 11) if no other
-                * preference is indicated.
+                * Use random operation channel from 2.4 GHz band social
+                * channels (1, 6, 11) or band 60 GHz social channel (2) if no
+                * other preference is indicated.
                 */
-               if (os_get_random((u8 *) &r, sizeof(r)) < 0)
+               if (p2p_config_get_random_social(&p2p, &p2p.op_reg_class,
+                                                &p2p.op_channel) != 0) {
+                       wpa_printf(MSG_ERROR,
+                                  "P2P: Failed to select random social channel as operation channel");
                        return -1;
-               p2p.op_channel = 1 + (r % 3) * 5;
+               }
                p2p.cfg_op_channel = 0;
                wpa_printf(MSG_DEBUG, "P2P: Random operating channel: "
                           "%d:%d", p2p.op_reg_class, p2p.op_channel);
@@ -3967,12 +3990,6 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
        } else
                os_memcpy(p2p.country, "XX\x04", 3);
 
-       if (wpas_p2p_setup_channels(wpa_s, &p2p.channels, &p2p.cli_channels)) {
-               wpa_printf(MSG_ERROR, "P2P: Failed to configure supported "
-                          "channel list");
-               return -1;
-       }
-
        os_memcpy(p2p.pri_dev_type, wpa_s->conf->device_type,
                  WPS_DEV_TYPE_LEN);
 
@@ -5084,7 +5101,8 @@ static int wpas_p2p_select_freq_no_pref(struct wpa_supplicant *wpa_s,
        for (i = 0; i < 3; i++) {
                params->freq = 2412 + ((r + i) % 3) * 25;
                if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
-                   freq_included(channels, params->freq))
+                   freq_included(channels, params->freq) &&
+                   p2p_supported_freq(wpa_s->global->p2p, params->freq))
                        goto out;
        }
 
@@ -5092,11 +5110,28 @@ static int wpas_p2p_select_freq_no_pref(struct wpa_supplicant *wpa_s,
        for (i = 0; i < 11; i++) {
                params->freq = 2412 + i * 5;
                if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
-                   freq_included(channels, params->freq))
+                   freq_included(channels, params->freq) &&
+                   p2p_supported_freq(wpa_s->global->p2p, params->freq))
+                       goto out;
+       }
+
+       /* try social channel class 180 channel 2 */
+       params->freq = 58320 + 1 * 2160;
+       if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
+           freq_included(channels, params->freq) &&
+           p2p_supported_freq(wpa_s->global->p2p, params->freq))
+               goto out;
+
+       /* try all channels in reg. class 180 */
+       for (i = 0; i < 4; i++) {
+               params->freq = 58320 + i * 2160;
+               if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
+                   freq_included(channels, params->freq) &&
+                   p2p_supported_freq(wpa_s->global->p2p, params->freq))
                        goto out;
        }
 
-       wpa_printf(MSG_DEBUG, "P2P: No 2.4 GHz channel allowed");
+       wpa_printf(MSG_DEBUG, "P2P: No 2.4 and 60 GHz channel allowed");
        return -1;
 out:
        wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz (no preference known)",