aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
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;