]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Allow all channels in case of multi channel concurrency
authorDeepthi Gowri <deepthi@codeaurora.org>
Mon, 25 Feb 2013 16:41:32 +0000 (18:41 +0200)
committerJouni Malinen <j@w1.fi>
Fri, 1 Mar 2013 16:40:39 +0000 (18:40 +0200)
If multi channel concurrency is supported, we have to populate the
p2p_channels with list of channels that we support. Use the same design
that was previously added for GO Negotiation.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

src/p2p/p2p.c
src/p2p/p2p.h
src/p2p/p2p_i.h
src/p2p/p2p_invitation.c
wpa_supplicant/p2p_supplicant.c

index 15df215e3465ca0d554b3660284b17974096a79c..ec62836eea037fde8c6030f81a18dc72d54a2881 100644 (file)
@@ -1259,8 +1259,8 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p)
  * may be further optimized in p2p_reselect_channel() once the peer information
  * is available.
  */
-static int p2p_prepare_channel(struct p2p_data *p2p, struct p2p_device *dev,
-                              unsigned int force_freq, unsigned int pref_freq)
+int p2p_prepare_channel(struct p2p_data *p2p, struct p2p_device *dev,
+                       unsigned int force_freq, unsigned int pref_freq)
 {
        if (force_freq || pref_freq) {
                if (p2p_prepare_channel_pref(p2p, force_freq, pref_freq) < 0)
index 4a35d52565b6bfca08e490da14a029f43bce9235..3a724bee3c13c8dc76ed398efc188c11c9c1e873 100644 (file)
@@ -1042,12 +1042,14 @@ enum p2p_invite_role {
  * @force_freq: The only allowed channel frequency in MHz or 0
  * @go_dev_addr: Forced GO Device Address or %NULL if none
  * @persistent_group: Whether this is to reinvoke a persistent group
+ * @pref_freq: Preferred operating frequency in MHz or 0 (this is only used if
+ *     force_freq == 0)
  * Returns: 0 on success, -1 on failure
  */
 int p2p_invite(struct p2p_data *p2p, const u8 *peer, enum p2p_invite_role role,
               const u8 *bssid, const u8 *ssid, size_t ssid_len,
               unsigned int force_freq, const u8 *go_dev_addr,
-              int persistent_group);
+              int persistent_group, unsigned int pref_freq);
 
 /**
  * p2p_presence_req - Request GO presence
index e91959f824fed94ea82515f9732ea0433ad3f8fc..856f78f524531a127d7dcfa2ac42f2bdfbda6268 100644 (file)
@@ -713,5 +713,7 @@ int p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst,
                    const u8 *src, const u8 *bssid, const u8 *buf,
                    size_t len, unsigned int wait_time);
 void p2p_stop_listen_for_freq(struct p2p_data *p2p, int freq);
+int p2p_prepare_channel(struct p2p_data *p2p, struct p2p_device *dev,
+                       unsigned int force_freq, unsigned int pref_freq);
 
 #endif /* P2P_I_H */
index 10aa61684acfc534a63128627b622ae7ac25be7f..918fd4bf1c7c01ea7bc59ebbf60d4cfd7e56a8ed 100644 (file)
@@ -531,7 +531,7 @@ void p2p_invitation_resp_cb(struct p2p_data *p2p, int success)
 int p2p_invite(struct p2p_data *p2p, const u8 *peer, enum p2p_invite_role role,
               const u8 *bssid, const u8 *ssid, size_t ssid_len,
               unsigned int force_freq, const u8 *go_dev_addr,
-              int persistent_group)
+              int persistent_group, unsigned int pref_freq)
 {
        struct p2p_device *dev;
 
@@ -561,6 +561,9 @@ int p2p_invite(struct p2p_data *p2p, const u8 *peer, enum p2p_invite_role role,
                return -1;
        }
 
+       if (p2p_prepare_channel(p2p, dev, force_freq, pref_freq) < 0)
+               return -1;
+
        if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) {
                if (!(dev->info.dev_capab &
                      P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) {
@@ -574,26 +577,6 @@ int p2p_invite(struct p2p_data *p2p, const u8 *peer, enum p2p_invite_role role,
 
        dev->invitation_reqs = 0;
 
-       if (force_freq) {
-               if (p2p_freq_to_channel(p2p->cfg->country, force_freq,
-                                       &p2p->op_reg_class, &p2p->op_channel) <
-                   0) {
-                       wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
-                               "P2P: Unsupported frequency %u MHz",
-                               force_freq);
-                       return -1;
-               }
-               p2p->channels.reg_classes = 1;
-               p2p->channels.reg_class[0].channels = 1;
-               p2p->channels.reg_class[0].reg_class = p2p->op_reg_class;
-               p2p->channels.reg_class[0].channel[0] = p2p->op_channel;
-       } else {
-               p2p->op_reg_class = p2p->cfg->op_reg_class;
-               p2p->op_channel = p2p->cfg->op_channel;
-               os_memcpy(&p2p->channels, &p2p->cfg->channels,
-                         sizeof(struct p2p_channels));
-       }
-
        if (p2p->state != P2P_IDLE)
                p2p_stop_find(p2p);
 
index d6015b9eb0e91d36a7b64aa517ecb19a56e1265c..dd86caa17aba09576ceefb56b8c68df4f043a58c 100644 (file)
@@ -4573,7 +4573,8 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
                    int ht40)
 {
        enum p2p_invite_role role;
-       u8 *bssid = NULL;
+       u8 *bssid = NULL, bssid_buf[ETH_ALEN];
+       int force_freq = 0, pref_freq = 0, oper_freq = 0;
 
        wpa_s->p2p_persistent_go_freq = freq;
        wpa_s->p2p_go_ht40 = !!ht40;
@@ -4601,6 +4602,63 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
        }
        wpa_s->pending_invite_ssid_id = ssid->id;
 
+       if (wpa_s->current_ssid && wpa_drv_get_bssid(wpa_s, bssid_buf) == 0 &&
+           wpa_s->assoc_freq) {
+               oper_freq = wpa_s->assoc_freq;
+               if (bssid == NULL)
+                       bssid = bssid_buf;
+       } else {
+               oper_freq = wpa_drv_shared_freq(wpa_s);
+               if (oper_freq < 0)
+                       oper_freq = 0;
+       }
+
+       if (freq > 0) {
+               if (!p2p_supported_freq(wpa_s->global->p2p, freq)) {
+                       wpa_printf(MSG_DEBUG, "P2P: The forced channel "
+                                  "(%u MHz) is not supported for P2P uses",
+                                  freq);
+                       return -3;
+               }
+
+               if (oper_freq > 0 && freq != oper_freq &&
+                   !(wpa_s->drv_flags &
+                     WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) {
+                       wpa_printf(MSG_DEBUG, "P2P: Cannot start P2P group "
+                                  "on %u MHz while connected on another "
+                                  "channel (%u MHz)", freq, oper_freq);
+                       return -2;
+               }
+               wpa_printf(MSG_DEBUG, "P2P: Trying to force us to use the "
+                          "requested channel (%u MHz)", freq);
+               force_freq = freq;
+       } else if (oper_freq > 0 &&
+                  !p2p_supported_freq(wpa_s->global->p2p, oper_freq)) {
+               if (!(wpa_s->drv_flags &
+                     WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) {
+                       wpa_printf(MSG_DEBUG, "P2P: Cannot start P2P group "
+                                  "while connected on non-P2P supported "
+                                  "channel (%u MHz)", oper_freq);
+                       return -2;
+               }
+               wpa_printf(MSG_DEBUG, "P2P: Current operating channel "
+                          "(%u MHz) not available for P2P - try to use "
+                          "another channel", oper_freq);
+               force_freq = 0;
+       } else if (oper_freq > 0 &&
+                  (wpa_s->drv_flags &
+                   WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) {
+               wpa_printf(MSG_DEBUG, "P2P: Trying to prefer the channel we "
+                          "are already using (%u MHz) on another interface",
+                          oper_freq);
+               pref_freq = oper_freq;
+       } else if (oper_freq > 0) {
+               wpa_printf(MSG_DEBUG, "P2P: Trying to force us to use the "
+                          "channel we are already using (%u MHz) on another "
+                          "interface", oper_freq);
+               force_freq = oper_freq;
+       }
+
        if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)
                return wpa_drv_p2p_invite(wpa_s, peer_addr, role, bssid,
                                          ssid->ssid, ssid->ssid_len,
@@ -4610,7 +4668,8 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
                return -1;
 
        return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid,
-                         ssid->ssid, ssid->ssid_len, freq, go_dev_addr, 1);
+                         ssid->ssid, ssid->ssid_len, force_freq, go_dev_addr,
+                         1, pref_freq);
 }
 
 
@@ -4620,9 +4679,10 @@ int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
 {
        struct wpa_global *global = wpa_s->global;
        enum p2p_invite_role role;
-       u8 *bssid = NULL;
+       u8 *bssid = NULL, bssid_buf[ETH_ALEN];
        struct wpa_ssid *ssid;
        int persistent;
+       int force_freq = 0, oper_freq = 0, pref_freq = 0;
 
        wpa_s->p2p_persistent_go_freq = 0;
        wpa_s->p2p_go_ht40 = 0;
@@ -4674,9 +4734,47 @@ 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 (wpa_s->current_ssid && wpa_drv_get_bssid(wpa_s, bssid_buf) == 0 &&
+           wpa_s->assoc_freq) {
+               oper_freq = wpa_s->assoc_freq;
+               if (bssid == NULL)
+                       bssid = bssid_buf;
+       } else {
+               oper_freq = wpa_drv_shared_freq(wpa_s);
+               if (oper_freq < 0)
+                       oper_freq = 0;
+       }
+
+       if (oper_freq > 0 &&
+           !p2p_supported_freq(wpa_s->global->p2p, oper_freq)) {
+               if (!(wpa_s->drv_flags &
+                       WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) {
+                       wpa_printf(MSG_DEBUG, "P2P: Cannot start P2P group "
+                               "while connected on non-P2P supported "
+                               "channel (%u MHz)", oper_freq);
+                        return -2;
+               }
+               wpa_printf(MSG_DEBUG, "P2P: Current operating channel "
+                       "(%u MHz) not available for P2P - try to use "
+                       "another channel", oper_freq);
+               force_freq = 0;
+       } else if (oper_freq > 0 &&
+                  (wpa_s->drv_flags &
+                   WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) {
+               wpa_printf(MSG_DEBUG, "P2P: Trying to prefer the channel we "
+                          "are already using (%u MHz) on another interface",
+                          oper_freq);
+               pref_freq = oper_freq;
+       } else if (oper_freq > 0) {
+               wpa_printf(MSG_DEBUG, "P2P: Trying to force us to use the "
+                          "channel we are already using (%u MHz) on another "
+                          "interface", oper_freq);
+               force_freq = oper_freq;
+       }
+
        return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid,
-                         ssid->ssid, ssid->ssid_len, wpa_s->assoc_freq,
-                         go_dev_addr, persistent);
+                         ssid->ssid, ssid->ssid_len, force_freq,
+                         go_dev_addr, persistent, pref_freq);
 }