aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorEyal Shapira <eyal@wizery.com>2012-07-21 00:02:19 +0300
committerArik Nemtsov <arik@wizery.com>2012-08-02 13:04:01 +0300
commitaf943c964ead5eb6552013fbc1cbd56e6bb8d551 (patch)
treefaf5e0831afca5b31b9e9fe2ba1c946d9c8049d7 /wpa_supplicant
parentf7a1a0e0c350b461d222a2416934e3ce55d9b306 (diff)
downloadexternal_wpa_supplicant_8_ti-af943c964ead5eb6552013fbc1cbd56e6bb8d551.zip
external_wpa_supplicant_8_ti-af943c964ead5eb6552013fbc1cbd56e6bb8d551.tar.gz
external_wpa_supplicant_8_ti-af943c964ead5eb6552013fbc1cbd56e6bb8d551.tar.bz2
P2P: Resolve frequency conflicts between STA and P2P (BRCM)
Upon association check whether there's a a frequency conflict given that no support for multi channel. In case there's a freq conflict with an existing P2P_GO or P2P_CLI decide how to resolve it (which one to disable or disconnect) according to the priority configuration. Effectively on Android JB, STA is always prioritized over P2P so in case of a conflict P2P will be disconnected so that STA can associate on a different channel. Signed-off-by: Eyal Shapira <eyal@wizery.com>
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/p2p_supplicant.c47
-rw-r--r--wpa_supplicant/p2p_supplicant.h4
-rw-r--r--wpa_supplicant/wpa_supplicant.c24
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h5
4 files changed, 79 insertions, 1 deletions
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 0aac7e1..1d7f28d 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -266,6 +266,11 @@ static void wpas_p2p_group_delete(struct wpa_supplicant *wpa_s, int silent)
case P2P_GROUP_REMOVAL_GO_ENDING_SESSION:
reason = " reason=GO_ENDING_SESSION";
break;
+#ifdef ANDROID_P2P
+ case P2P_GROUP_REMOVAL_FREQ_CONFLICT:
+ reason = " reason=FREQ_CONFLICT";
+ break;
+#endif
default:
reason = "";
break;
@@ -4896,6 +4901,48 @@ void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
wpas_p2p_add_persistent_group_client(wpa_s, addr);
}
+#ifdef ANDROID_P2P
+int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s, int freq)
+{
+ struct wpa_supplicant *iface = NULL;
+ struct p2p_data *p2p = wpa_s->global->p2p;
+
+ 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(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, 0);
+ } else {
+ /* Existing connection has the priority. Disable the newly
+ * selected network and let the application know about it.
+ */
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+#endif
static void wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s,
int group_added)
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index e2fe259..24fb81e 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -26,6 +26,10 @@ 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);
+#ifdef ANDROID_P2P
+int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s,
+ int freq);
+#endif
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 46b7296..6494097 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1162,6 +1162,9 @@ 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 */
+#ifdef ANDROID_P2P
+ int freq = 0;
+#endif
if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
@@ -1490,6 +1493,27 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
#endif /* CONFIG_HT_OVERRIDES */
+#ifdef ANDROID_P2P
+ /* 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);
+ 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
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 5132ca3..9968386 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -529,7 +529,10 @@ 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,
+#ifdef ANDROID_P2P
+ P2P_GROUP_REMOVAL_FREQ_CONFLICT
+#endif
} removal_reason;
unsigned int p2p_cb_on_scan_complete:1;