Merge branch 'moonshot' of ssh://moonshot.suchdamage.org:822/srv/git/libeap into...
[libeap.git] / wpa_supplicant / wpa_supplicant.c
index d6b12e8..61d1c87 100644 (file)
 #include "common/wpa_ctrl.h"
 #include "mlme.h"
 #include "common/ieee802_11_defs.h"
+#include "p2p/p2p.h"
 #include "blacklist.h"
 #include "wpas_glue.h"
 #include "wps_supplicant.h"
 #include "ibss_rsn.h"
 #include "sme.h"
 #include "ap.h"
+#include "p2p_supplicant.h"
 #include "notify.h"
 #include "bgscan.h"
 #include "bss.h"
@@ -427,6 +429,10 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
 #ifdef CONFIG_AP
        wpa_supplicant_ap_deinit(wpa_s);
 #endif /* CONFIG_AP */
+
+#ifdef CONFIG_P2P
+       wpas_p2p_deinit(wpa_s);
+#endif /* CONFIG_P2P */
 }
 
 
@@ -545,6 +551,9 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
                wpa_s->reassociated_connection = 1;
                wpa_drv_set_operstate(wpa_s, 1);
                wpa_s->after_wps = 0;
+#ifdef CONFIG_P2P
+               wpas_p2p_completed(wpa_s);
+#endif /* CONFIG_P2P */
        } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
                   state == WPA_ASSOCIATED) {
                wpa_s->new_connection = 1;
@@ -586,7 +595,7 @@ static void wpa_supplicant_terminate(int sig, void *signal_ctx)
 }
 
 
-static void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
+void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
 {
        enum wpa_states old_state = wpa_s->wpa_state;
 
@@ -674,8 +683,10 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
        wpa_supplicant_update_config(wpa_s);
 
        wpa_supplicant_clear_status(wpa_s);
-       wpa_s->reassociate = 1;
-       wpa_supplicant_req_scan(wpa_s, 0, 0);
+       if (wpa_supplicant_enabled_networks(wpa_s->conf)) {
+               wpa_s->reassociate = 1;
+               wpa_supplicant_req_scan(wpa_s, 0, 0);
+       }
        wpa_msg(wpa_s, MSG_DEBUG, "Reconfiguration completed");
        return 0;
 }
@@ -994,7 +1005,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
 void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
                              struct wpa_bss *bss, struct wpa_ssid *ssid)
 {
-       u8 wpa_ie[80];
+       u8 wpa_ie[200];
        size_t wpa_ie_len;
        int use_crypt, ret, i, bssid_changed;
        int algs = WPA_AUTH_ALG_OPEN;
@@ -1146,6 +1157,36 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
                wpa_ie_len = 0;
        }
 
+#ifdef CONFIG_P2P
+       if (wpa_s->global->p2p) {
+               u8 *pos;
+               size_t len;
+               int res;
+               int p2p_group;
+               p2p_group = wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE;
+               pos = wpa_ie + wpa_ie_len;
+               len = sizeof(wpa_ie) - wpa_ie_len;
+               res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len, p2p_group);
+               if (res >= 0)
+                       wpa_ie_len += res;
+       }
+
+       wpa_s->cross_connect_disallowed = 0;
+       if (bss) {
+               struct wpabuf *p2p;
+               p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
+               if (p2p) {
+                       wpa_s->cross_connect_disallowed =
+                               p2p_get_cross_connect_disallowed(p2p);
+                       wpabuf_free(p2p);
+                       wpa_printf(MSG_DEBUG, "P2P: WLAN AP %s cross "
+                                  "connection",
+                                  wpa_s->cross_connect_disallowed ?
+                                  "disallows" : "allows");
+               }
+       }
+#endif /* CONFIG_P2P */
+
        wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
        use_crypt = 1;
        cipher_pairwise = cipher_suite2driver(wpa_s->pairwise_cipher);
@@ -1236,6 +1277,17 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
        }
 #endif /* CONFIG_IEEE80211W */
 
+#ifdef CONFIG_P2P
+       if (wpa_s->global->p2p &&
+           (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE))
+               params.p2p = 1;
+#endif /* CONFIG_P2P */
+
+       if (wpa_s->parent->set_sta_uapsd)
+               params.uapsd = wpa_s->parent->sta_uapsd;
+       else
+               params.uapsd = -1;
+
        if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME)
                ret = ieee80211_sta_associate(wpa_s, &params);
        else
@@ -1884,6 +1936,7 @@ static struct wpa_supplicant * wpa_supplicant_alloc(void)
                return NULL;
        wpa_s->scan_req = 1;
        wpa_s->new_connection = 1;
+       wpa_s->parent = wpa_s;
 
        return wpa_s;
 }
@@ -2048,6 +2101,7 @@ next_driver:
                }
                wpa_s->max_scan_ssids = capa.max_scan_ssids;
                wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
+               wpa_s->max_stations = capa.max_stations;
        }
        if (wpa_s->max_remain_on_chan == 0)
                wpa_s->max_remain_on_chan = 1000;
@@ -2092,6 +2146,13 @@ next_driver:
        }
 #endif /* CONFIG_IBSS_RSN */
 
+#ifdef CONFIG_P2P
+       if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
+               wpa_printf(MSG_ERROR, "Failed to init P2P");
+               return -1;
+       }
+#endif /* CONFIG_P2P */
+
        if (wpa_bss_init(wpa_s) < 0)
                return -1;
 
@@ -2220,6 +2281,8 @@ int wpa_supplicant_remove_iface(struct wpa_global *global,
 
        wpa_printf(MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
 
+       if (global->p2p_group_formation == wpa_s)
+               global->p2p_group_formation = NULL;
        wpa_supplicant_deinit_iface(wpa_s, 1);
        os_free(wpa_s);
 
@@ -2279,6 +2342,8 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
        global = os_zalloc(sizeof(*global));
        if (global == NULL)
                return NULL;
+       dl_list_init(&global->p2p_srv_bonjour);
+       dl_list_init(&global->p2p_srv_upnp);
        global->params.daemonize = params->daemonize;
        global->params.wait_for_monitor = params->wait_for_monitor;
        global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
@@ -2392,6 +2457,10 @@ void wpa_supplicant_deinit(struct wpa_global *global)
        if (global == NULL)
                return;
 
+#ifdef CONFIG_P2P
+       wpas_p2p_deinit_global(global);
+#endif /* CONFIG_P2P */
+
        while (global->ifaces)
                wpa_supplicant_remove_iface(global, global->ifaces);
 
@@ -2434,5 +2503,9 @@ void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
        wpas_wps_update_config(wpa_s);
 #endif /* CONFIG_WPS */
 
+#ifdef CONFIG_P2P
+       wpas_p2p_update_config(wpa_s);
+#endif /* CONFIG_P2P */
+
        wpa_s->conf->changed_parameters = 0;
 }