Fix hostapd_cli get_config not to show key when WPA is disabled
[libeap.git] / wpa_supplicant / wpa_supplicant.c
index df11814..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
@@ -1387,8 +1439,11 @@ void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
        int was_disabled;
 
        if (ssid == NULL) {
-               other_ssid = wpa_s->conf->ssid;
-               while (other_ssid) {
+               for (other_ssid = wpa_s->conf->ssid; other_ssid;
+                    other_ssid = other_ssid->next) {
+                       if (other_ssid->disabled == 2)
+                               continue; /* do not change persistent P2P group
+                                          * data */
                        if (other_ssid == wpa_s->current_ssid &&
                            other_ssid->disabled)
                                wpa_s->reassociate = 1;
@@ -1400,12 +1455,10 @@ void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
                        if (was_disabled != other_ssid->disabled)
                                wpas_notify_network_enabled_changed(
                                        wpa_s, other_ssid);
-
-                       other_ssid = other_ssid->next;
                }
                if (wpa_s->reassociate)
                        wpa_supplicant_req_scan(wpa_s, 0, 0);
-       } else if (ssid->disabled) {
+       } else if (ssid->disabled && ssid->disabled != 2) {
                if (wpa_s->current_ssid == NULL) {
                        /*
                         * Try to reassociate since there is no current
@@ -1439,22 +1492,23 @@ void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
        int was_disabled;
 
        if (ssid == NULL) {
-               other_ssid = wpa_s->conf->ssid;
-               while (other_ssid) {
+               for (other_ssid = wpa_s->conf->ssid; other_ssid;
+                    other_ssid = other_ssid->next) {
                        was_disabled = other_ssid->disabled;
+                       if (was_disabled == 2)
+                               continue; /* do not change persistent P2P group
+                                          * data */
 
                        other_ssid->disabled = 1;
 
                        if (was_disabled != other_ssid->disabled)
                                wpas_notify_network_enabled_changed(
                                        wpa_s, other_ssid);
-
-                       other_ssid = other_ssid->next;
                }
                if (wpa_s->current_ssid)
                        wpa_supplicant_disassociate(
                                wpa_s, WLAN_REASON_DEAUTH_LEAVING);
-       } else {
+       } else if (ssid->disabled != 2) {
                if (ssid == wpa_s->current_ssid)
                        wpa_supplicant_disassociate(
                                wpa_s, WLAN_REASON_DEAUTH_LEAVING);
@@ -1488,16 +1542,16 @@ void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
         * Mark all other networks disabled or mark all networks enabled if no
         * network specified.
         */
-       other_ssid = wpa_s->conf->ssid;
-       while (other_ssid) {
+       for (other_ssid = wpa_s->conf->ssid; other_ssid;
+            other_ssid = other_ssid->next) {
                int was_disabled = other_ssid->disabled;
+               if (was_disabled == 2)
+                       continue; /* do not change persistent P2P group data */
 
                other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
 
                if (was_disabled != other_ssid->disabled)
                        wpas_notify_network_enabled_changed(wpa_s, other_ssid);
-
-               other_ssid = other_ssid->next;
        }
        wpa_s->disconnected = 0;
        wpa_s->reassociate = 1;
@@ -1808,13 +1862,18 @@ int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
                const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
                if (addr)
                        os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
-       } else {
+       } else if (!(wpa_s->drv_flags &
+                    WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
                wpa_s->l2 = l2_packet_init(wpa_s->ifname,
                                           wpa_drv_get_mac_addr(wpa_s),
                                           ETH_P_EAPOL,
                                           wpa_supplicant_rx_eapol, wpa_s, 0);
                if (wpa_s->l2 == NULL)
                        return -1;
+       } else {
+               const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
+               if (addr)
+                       os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
        }
 
        if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
@@ -1877,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;
 }
@@ -2041,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;
@@ -2085,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;
 
@@ -2213,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);
 
@@ -2272,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;
@@ -2385,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);
 
@@ -2427,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;
 }