Patchwork [RFC,4/4] P2P: Handling single channel concurrency

login
register
mail settings
Submitter Jithu Jance
Date May 21, 2012, 6:44 a.m.
Message ID <25A448014331D04F82E3035BCF9620AF06E670@SJEXCHMB09.corp.ad.broadcom.com>
Download mbox | patch
Permalink /patch/160322/
State Superseded
Headers show

Comments

Jithu Jance - May 21, 2012, 6:44 a.m.
Hi Jouni,

My understanding was that you have agreed on the below patches. Is there something 
to be done on these patches? Else could we get the basic implementation of single 
channel concurrency checked in?

http://patchwork.ozlabs.org/patch/154020/
http://patchwork.ozlabs.org/patch/151368/
http://patchwork.ozlabs.org/patch/151369/
http://patchwork.ozlabs.org/patch/151368/

There are some works pending (DBUS events and GO channel switch). But these can 
be appended to the hooks provided. If you require them on priority, let me know.



Thanks,

Jithu Jance
Jouni Malinen - May 23, 2012, 4:46 a.m.
On Mon, May 21, 2012 at 06:44:50AM +0000, Jithu Jance wrote:
> My understanding was that you have agreed on the below patches. Is there something 
> to be done on these patches? Else could we get the basic implementation of single 
> channel concurrency checked in?
> 
> http://patchwork.ozlabs.org/patch/154020/
> http://patchwork.ozlabs.org/patch/151368/
> http://patchwork.ozlabs.org/patch/151369/
> http://patchwork.ozlabs.org/patch/151368/

Unfortunately these have fallen somewhat of a victim for other projects
and travel taking most of my time. We'll see if I can get to these over
the next weekend, but if not, this may need to wait until I get back
home in couple of weeks.

> There are some works pending (DBUS events and GO channel switch). But these can 
> be appended to the hooks provided. If you require them on priority, let me know.

I'm fine with the D-Bus mechanism being addressed separately, but I
would like to see the needed nl80211 interface changes discussed on
linux-wireless mailing list rather sooner than later. It is important to
make sure that the needed functionality gets accepted to the upstream
kernel to avoid issues in supporting this cleanly with drivers that use
cfg80211.

Patch

diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
index 2da58c9..8fced7a 100644
--- a/src/common/wpa_ctrl.h
+++ b/src/common/wpa_ctrl.h
@@ -56,6 +56,8 @@  extern "C" {
 #define WPA_EVENT_BSS_ADDED "CTRL-EVENT-BSS-ADDED "
 /** A BSS entry was removed (followed by BSS entry id and BSSID) */
 #define WPA_EVENT_BSS_REMOVED "CTRL-EVENT-BSS-REMOVED "
+/** Notify the Userspace about the freq conflict */
+#define WPA_EVENT_FREQ_CONFLICT "CTRL-EVENT-FREQ-CONFLICT "

 /** WPS overlap detected in PBC mode */
 #define WPS_EVENT_OVERLAP "WPS-OVERLAP-DETECTED "
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index d5c862c..53c3e9e 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -267,6 +267,9 @@  static void wpas_p2p_group_delete(struct wpa_supplicant *wpa_s)
        case P2P_GROUP_REMOVAL_GO_ENDING_SESSION:
                reason = " reason=GO_ENDING_SESSION";
                break;
+       case P2P_GROUP_REMOVAL_FREQ_CONFLICT:
+               reason = " reason=FREQ_CONFLICT";
+               break;
        default:
                reason = "";
                break;
@@ -4713,3 +4716,49 @@  void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
                return;
        wpas_p2p_add_persistent_group_client(wpa_s, addr);
 }
+
+int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s, int freq)
+{
+       struct wpa_supplicant *iface = NULL;
+
+       for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
+               if(!iface->p2p_group_interface || !iface->current_ssid ||
+                       iface->current_ssid->frequency == freq)
+                       continue;
+
+               if (iface->p2p_group_interface == P2P_GROUP_INTERFACE_GO) {
+                       /*
+                        * Try to see whether we can move the GO. If it
+                        * is not possible, remove the GO interface
+                        */
+                       if(wpa_drv_switch_channel(iface, freq) == 0) {
+                                       wpa_printf(MSG_INFO, "P2P: GO Moved to freq"
+                                       "(%d) MHz", freq);
+                                       iface->current_ssid->frequency = freq;
+                                       continue;
+                       }
+               }
+
+               /* If GO cannot be moved or if the conflicting interface is a
+                * P2P Client, remove the interface depending up on the connection
+                * priority
+                */
+               if(!wpas_is_p2p_prioritized(wpa_s)) {
+                       /*
+                        * STA connection has priority over existing
+                        * P2P connection. So remove the interface
+                        */
+                       wpa_printf(MSG_DEBUG, "P2P: Removing P2P connection due to "
+                               "Single channel concurrent mode frequency conflict");
+                       iface->removal_reason = P2P_GROUP_REMOVAL_FREQ_CONFLICT;
+                       wpas_p2p_group_delete(iface);
+               } else {
+                       /*
+                        * Existing connection has the priority. Disable the newly
+                        * selected network and let the application know about it.
+                        */
+                       return -1;
+               }
+       }
+       return 0;
+}
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index c15e42a..9b49b01 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -25,6 +25,8 @@  void wpas_p2p_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
                                   unsigned int freq, unsigned int duration);
 void wpas_p2p_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
                                          unsigned int freq);
+int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s,
+                                          int freq);
 int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname);
 int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
                       int freq);
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index c5a7115..2c7ec09 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1100,6 +1100,7 @@  void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
        ibss_rsn_deinit(wpa_s->ibss_rsn);
        wpa_s->ibss_rsn = NULL;
 #endif /* CONFIG_IBSS_RSN */
+       int freq = 0;

        if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
            ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
@@ -1404,6 +1405,33 @@  void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
        wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
 #endif /* CONFIG_HT_OVERRIDES */

+       /*
+        * If multichannel concurrency is not supported, check for any frequency
+        * conflict and take appropriate action.
+        */
+       if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) &&
+               ((freq = wpa_drv_shared_freq(wpa_s)) > 0) && (freq != params.freq)) {
+               wpa_printf(MSG_DEBUG, "Shared interface with conflicting frequency"
+                       "found (%d != %d)", freq, params.freq);
+#ifdef CONFIG_P2P
+               if (wpas_p2p_handle_frequency_conflicts(wpa_s, params.freq) <
+                       0) {
+                       /*
+                        * Handling conflicts failed. Disable the current
+                        * connect req and notify the userspace to take
+                        * appropriate action.
+                        */
+                       wpa_printf(MSG_DEBUG, "proiritize is not set."
+                               "Notifying user space to handle the case");
+                       wpa_supplicant_disable_network(wpa_s, ssid);
+                       wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_FREQ_CONFLICT
+                               " id=%d", ssid->id);
+                       os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
+                       return;
+               }
+#endif /* CONFIG_P2P */
+       }
+
        ret = wpa_drv_associate(wpa_s, &params);
        if (ret < 0) {
                wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index b25116e..a28fa5a 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -504,7 +504,8 @@  struct wpa_supplicant {
                P2P_GROUP_REMOVAL_REQUESTED,
                P2P_GROUP_REMOVAL_IDLE_TIMEOUT,
                P2P_GROUP_REMOVAL_UNAVAILABLE,
-               P2P_GROUP_REMOVAL_GO_ENDING_SESSION
+               P2P_GROUP_REMOVAL_GO_ENDING_SESSION,
+               P2P_GROUP_REMOVAL_FREQ_CONFLICT
        } removal_reason;

        unsigned int p2p_cb_on_scan_complete:1;
--
1.7.4.1






- Jithu Jance

________________________________________
From: hostap-bounces@lists.shmoo.com [hostap-bounces@lists.shmoo.com] on behalf of Jouni Malinen [j@w1.fi]
Sent: Monday, April 09, 2012 12:08 AM
To: hostap@lists.shmoo.com
Subject: Re: [RFC 4/4] P2P: Handling single channel concurrency

On Tue, Mar 06, 2012 at 10:34:38AM +0530, Jithu Jance wrote:
> This patch handles cases where a STA connection is attempted after a P2P
> connection and the new sta connection detects a freq
> conflict with the existing P2P connection. Now based on the priority of the
> connection (either sta or p2p), either one of the connection
> will be terminated.

I applied the driver_nl80211.c part and below is a cleaned up version of
the rest. Though, I did not go through all the details yet.


[PATCH 3/3] P2P: Handle single channel concurrency

This patch handles cases where a STA connection is attempted after a P2P
connection and the new sta connection detects a freq conflict with the
existing P2P connection. Now based on the priority of the connection
(either sta or p2p), either one of the connection will be terminated.

Signed-hostap: Jithu Jance <jithu@broadcom.com>
---
 src/common/wpa_ctrl.h             |    2 +
 wpa_supplicant/p2p_supplicant.c   |   50 +++++++++++++++++++++++++++++++++++++
 wpa_supplicant/p2p_supplicant.h   |    2 +
 wpa_supplicant/wpa_supplicant.c   |   27 ++++++++++++++++++++
 wpa_supplicant/wpa_supplicant_i.h |    3 +-
 5 files changed, 83 insertions(+), 1 deletions(-)

diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
index 35012e8..2e35e9c 100644
--- a/src/common/wpa_ctrl.h
+++ b/src/common/wpa_ctrl.h
@@ -56,6 +56,8 @@  extern "C" {
 #define WPA_EVENT_BSS_ADDED "CTRL-EVENT-BSS-ADDED "
 /** A BSS entry was removed (followed by BSS entry id and BSSID) */
 #define WPA_EVENT_BSS_REMOVED "CTRL-EVENT-BSS-REMOVED "
+/** Notify the Userspace about the freq conflict */
+#define WPA_EVENT_FREQ_CONFLICT "CTRL-EVENT-FREQ-CONFLICT "

 /** WPS overlap detected in PBC mode */
 #define WPS_EVENT_OVERLAP "WPS-OVERLAP-DETECTED "
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 9d31fdb..3abcee7 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -4609,3 +4609,53 @@  void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
                return;
        wpas_p2p_add_persistent_group_client(wpa_s, addr);
 }
+
+
+int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s, int freq)
+{
+       struct wpa_supplicant *iface;
+
+       for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
+               if (!iface->p2p_group_interface || !iface->current_ssid ||
+                   iface->current_ssid->frequency == freq)
+                       continue;
+
+               if (iface->p2p_group_interface == P2P_GROUP_INTERFACE_GO) {
+                       /*
+                        * Try to see whether we can move the GO. If it is not
+                        * possible, remove the GO interface.
+                        */
+                       if (wpa_drv_switch_channel(iface, freq) == 0) {
+                               wpa_printf(MSG_INFO, "P2P: GO Moved to freq "
+                                          "%d MHz", freq);
+                               iface->current_ssid->frequency = freq;
+                               continue;
+                       }
+               }
+
+               /*
+                * If GO cannot be moved or if the conflicting interface is a
+                * P2P Client, remove the interface depending up on the
+                * connection priority.
+                */
+               if (!wpas_is_p2p_prioritized(iface)) {
+                       /*
+                        * STA connection has priority over existing P2P
+                        * connection, so remove the interface.
+                        */
+                       wpas_p2p_disconnect(iface);
+                       iface->removal_reason =
+                               P2P_GROUP_REMOVAL_FREQ_CONFLICT;
+                       wpas_p2p_group_delete(iface);
+               } else {
+                       /*
+                        * Existing connection has the priority. Disable the
+                        * newly selected network and let the application know
+                        * about it.
+                        */
+                       return -1;
+               }
+       }
+
+       return 0;
+}
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index 8f8e635..fb0522b 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -25,6 +25,8 @@  void wpas_p2p_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
                                   unsigned int freq, unsigned int duration);
 void wpas_p2p_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
                                          unsigned int freq);
+int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s,
+                                       int freq);
 int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname);
 int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
                       int freq);
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 1c88949..7b4e178 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1091,6 +1091,7 @@  void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
        struct wpa_driver_capa capa;
        int assoc_failed = 0;
        struct wpa_ssid *old_ssid;
+       int freq;
 #ifdef CONFIG_HT_OVERRIDES
        struct ieee80211_ht_capabilities htcaps;
        struct ieee80211_ht_capabilities htcaps_mask;
@@ -1404,6 +1405,32 @@  void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
        wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
 #endif /* CONFIG_HT_OVERRIDES */

+       /*
+        * If multichannel concurrency is not supported, check for any
+        * frequency conflict and take appropriate action.
+        */
+       if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) &&
+           ((freq = wpa_drv_shared_freq(wpa_s)) > 0) && freq != params.freq) {
+               wpa_printf(MSG_DEBUG, "Shared interface with conflicting "
+                          "frequency found (%d != %d)", freq, params.freq);
+#ifdef CONFIG_P2P
+               if (wpas_p2p_handle_frequency_conflicts(wpa_s, params.freq) <
+                   0) {
+                       /*
+                        * Handling conflicts failed. Disable the current
+                        * connect req and notify the userspace to take
+                        * appropriate action.
+                        */
+                       wpa_printf(MSG_DEBUG, "prioritize is not set. "
+                                  "Notifying user space to handle the case.");
+                       wpa_supplicant_disable_network(wpa_s, ssid);
+                       wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_FREQ_CONFLICT
+                               " id=%d", ssid->id);
+                       os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
+               }
+#endif /* CONFIG_P2P */
+       }
+
        ret = wpa_drv_associate(wpa_s, &params);
        if (ret < 0) {
                wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 3f1f589..3c86857 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -509,7 +509,8 @@  struct wpa_supplicant {
                P2P_GROUP_REMOVAL_REQUESTED,
                P2P_GROUP_REMOVAL_IDLE_TIMEOUT,
                P2P_GROUP_REMOVAL_UNAVAILABLE,
-               P2P_GROUP_REMOVAL_GO_ENDING_SESSION
+               P2P_GROUP_REMOVAL_GO_ENDING_SESSION,
+               P2P_GROUP_REMOVAL_FREQ_CONFLICT
        } removal_reason;

        unsigned int p2p_cb_on_scan_complete:1;