diff mbox

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

Message ID CAGCGobBKsntYm7N6aoDD9n-aLcHWNA4DM65WcMjzXautHWkYEQ@mail.gmail.com
State Superseded
Headers show

Commit Message

Jithu Jance March 6, 2012, 5:04 a.m. UTC
Single channel concurrency patch [4/4]

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.


[PATCH] Handle frequency conflicts, in single channel concurrency case
 Signed-hostap: Jithu Jance <jithu@broadcom.com>

---
 src/common/wpa_ctrl.h             |    2 +
 src/drivers/driver_nl80211.c      |    5 +++-
 wpa_supplicant/p2p_supplicant.c   |   40
+++++++++++++++++++++++++++++++++++++
 wpa_supplicant/p2p_supplicant.h   |    2 +
 wpa_supplicant/wpa_supplicant.c   |   22 ++++++++++++++++++++
 wpa_supplicant/wpa_supplicant_i.h |    3 +-
 6 files changed, 72 insertions(+), 2 deletions(-)
diff mbox

Patch

diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
index 5b4846f..96ac11b 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/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 184b26f..1e8c7fe 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -8398,7 +8398,10 @@  static int wpa_driver_nl80211_shared_freq(void *priv)
    MACSTR,
    driver->phyname, driver->first_bss.ifname,
    MAC2STR(driver->first_bss.addr));
- freq = nl80211_get_assoc_freq(driver);
+ if(is_ap_interface(driver->nlmode))
+ freq = driver->first_bss.freq;
+ else
+ freq = nl80211_get_assoc_freq(driver);
  wpa_printf(MSG_DEBUG, "nl80211: Shared freq for PHY %s: %d",
    drv->phyname, freq);
  }
diff --git a/wpa_supplicant/p2p_supplicant.c
b/wpa_supplicant/p2p_supplicant.c
index 486a551..9e80315 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -4496,3 +4496,43 @@  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)) {
+
+ 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_ERROR, "P2P: "
+ "GO Moved to freq(%d)", 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 cf46eaf..da7b9d9 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 fdee407..d41f47e 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) {
@@ -1403,6 +1404,27 @@  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);
+ }
+#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 0ba1935..283a342 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -495,7 +495,8 @@  struct wpa_supplicant {
  P2P_GROUP_REMOVAL_UNKNOWN,
  P2P_GROUP_REMOVAL_REQUESTED,
  P2P_GROUP_REMOVAL_IDLE_TIMEOUT,
- P2P_GROUP_REMOVAL_UNAVAILABLE
+ P2P_GROUP_REMOVAL_UNAVAILABLE,
+ P2P_GROUP_REMOVAL_FREQ_CONFLICT
  } removal_reason;

  unsigned int p2p_cb_on_scan_complete:1;