]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
AOSP: freq conflict
authorJouni Malinen <j@w1.fi>
Thu, 9 Aug 2012 19:08:50 +0000 (22:08 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 9 Aug 2012 20:18:31 +0000 (23:18 +0300)
src/common/wpa_ctrl.h
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/p2p_supplicant.h
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index 35012e86b5399ff86c4f002bef211ee1f013257a..a799edf24c177b794b0517d65ef79f4e866622a3 100644 (file)
@@ -56,6 +56,10 @@ 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 "
+#ifdef ANDROID_P2P
+/** Notify the Userspace about the freq conflict */
+#define WPA_EVENT_FREQ_CONFLICT "CTRL-EVENT-FREQ-CONFLICT "
+#endif
 
 /** WPS overlap detected in PBC mode */
 #define WPS_EVENT_OVERLAP "WPS-OVERLAP-DETECTED "
index e870e45fd589ec66b08bcfd01eab37d13393069f..5e7edc8cf3f59eea1677ecc219d517bc9adeeb80 100644 (file)
@@ -257,6 +257,11 @@ static void wpas_p2p_group_delete(struct wpa_supplicant *wpa_s)
        case P2P_GROUP_REMOVAL_UNAVAILABLE:
                reason = " reason=UNAVAILABLE";
                break;
+#ifdef ANDROID_P2P
+       case P2P_GROUP_REMOVAL_FREQ_CONFLICT:
+               reason = " reason=FREQ_CONFLICT";
+               break;
+#endif
        default:
                reason = "";
                break;
@@ -2563,7 +2568,9 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
        struct wpa_bss *bss;
        int freq;
        u8 iface_addr[ETH_ALEN];
-
+#ifdef ANDROID_P2P     
+       int shared_freq = 0;
+#endif
        eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
 
        if (wpa_s->global->p2p_disabled)
@@ -2598,6 +2605,16 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
                wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency "
                           "from P2P peer table: %d MHz", freq);
        }
+
+#ifdef ANDROID_P2P
+       if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) && 
+               ((shared_freq = wpa_drv_shared_freq(wpa_s)) > 0) && (shared_freq != freq)) {
+               wpa_msg(wpa_s->parent, MSG_INFO,
+                                       P2P_EVENT_GROUP_FORMATION_FAILURE "reason=FREQ_CONFLICT");
+               return;
+       }
+#endif
+
        bss = wpa_bss_get_bssid(wpa_s, wpa_s->pending_join_iface_addr);
        if (bss) {
                freq = bss->freq;
@@ -4418,3 +4435,46 @@ void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
                return;
        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);
+                       } else {
+                               /* Existing connection has the priority. Disable the newly
+                 * selected network and let the application know about it.
+                                */
+                               return -1;
+                       }
+               }
+       }
+       return 0;
+}
+#endif
index cf46eaf1b90de8175a0d4f35ed3dafa7ea41087a..05c648a6924d6dca15bc3c65f827278b7779fe4c 100644 (file)
@@ -25,6 +25,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);
index cbdeb208701621ef6a75922cfc5824cd54086c84..23c1ec252fb93a5abaa8104315954ad1516d8e10 100644 (file)
@@ -1102,6 +1102,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) {
@@ -1406,6 +1409,26 @@ 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 "
index f0d73894c5e3d78a631ef4a06dbfb53bb3b05485..9d16bb6cdaa9c5ea1673a24e313f9f849af44033 100644 (file)
@@ -488,7 +488,10 @@ struct wpa_supplicant {
                P2P_GROUP_REMOVAL_UNKNOWN,
                P2P_GROUP_REMOVAL_REQUESTED,
                P2P_GROUP_REMOVAL_IDLE_TIMEOUT,
-               P2P_GROUP_REMOVAL_UNAVAILABLE
+               P2P_GROUP_REMOVAL_UNAVAILABLE,
+#ifdef ANDROID_P2P
+               P2P_GROUP_REMOVAL_FREQ_CONFLICT
+#endif
        } removal_reason;
 
        unsigned int p2p_cb_on_scan_complete:1;