X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=wpa_supplicant%2Fwpa_supplicant.c;h=61d1c87e48d82a2e48eef242257f1a62b704f045;hb=HEAD;hp=4811f4fdcf1a917e30a98b6e9edabd278124c65b;hpb=ec8d20187d1df7a1fcf450aa80671125d80ba878;p=libeap.git diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 4811f4f..61d1c87 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1,6 +1,6 @@ /* * WPA Supplicant - * Copyright (c) 2003-2009, Jouni Malinen + * Copyright (c) 2003-2010, Jouni Malinen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -22,7 +22,7 @@ #include "eapol_supp/eapol_supp_sm.h" #include "eap_peer/eap.h" #include "eap_server/eap_methods.h" -#include "wpa.h" +#include "rsn_supp/wpa.h" #include "eloop.h" #include "config.h" #include "l2_packet/l2_packet.h" @@ -30,24 +30,28 @@ #include "driver_i.h" #include "ctrl_iface.h" #include "pcsc_funcs.h" -#include "version.h" -#include "preauth.h" -#include "pmksa_cache.h" -#include "wpa_ctrl.h" +#include "common/version.h" +#include "rsn_supp/preauth.h" +#include "rsn_supp/pmksa_cache.h" +#include "common/wpa_ctrl.h" #include "mlme.h" -#include "ieee802_11_defs.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" +#include "scan.h" const char *wpa_supplicant_version = "wpa_supplicant v" VERSION_STR "\n" -"Copyright (c) 2003-2009, Jouni Malinen and contributors"; +"Copyright (c) 2003-2010, Jouni Malinen and contributors"; const char *wpa_supplicant_license = "This program is free software. You can distribute it and/or modify it\n" @@ -143,13 +147,13 @@ static int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s, { u8 key[32]; size_t keylen; - wpa_alg alg; + enum wpa_alg alg; u8 seq[6] = { 0 }; /* IBSS/WPA-None uses only one key (Group) for both receiving and * sending unicast and multicast packets. */ - if (ssid->mode != IEEE80211_MODE_IBSS) { + if (ssid->mode != WPAS_MODE_IBSS) { wpa_printf(MSG_INFO, "WPA: Invalid mode %d (not IBSS/ad-hoc) " "for WPA-None", ssid->mode); return -1; @@ -256,7 +260,7 @@ void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s) struct wpa_ssid *ssid = wpa_s->current_ssid; #ifdef CONFIG_IBSS_RSN - if (ssid->mode == IEEE80211_MODE_IBSS && + if (ssid->mode == WPAS_MODE_IBSS && wpa_s->key_mgmt != WPA_KEY_MGMT_NONE && wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) { /* @@ -378,6 +382,9 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s) wpa_s->ctrl_iface = NULL; } if (wpa_s->conf != NULL) { + struct wpa_ssid *ssid; + for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) + wpas_notify_network_removed(wpa_s, ssid); wpa_config_free(wpa_s->conf); wpa_s->conf = NULL; } @@ -396,8 +403,7 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s) wpa_s->wpa = NULL; wpa_blacklist_clear(wpa_s); - wpa_scan_results_free(wpa_s->scan_res); - wpa_s->scan_res = NULL; + wpa_bss_deinit(wpa_s); wpa_supplicant_cancel_scan(wpa_s); wpa_supplicant_cancel_auth_timeout(wpa_s); @@ -423,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 */ } @@ -478,13 +488,15 @@ void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr) * @state: State (wpa_state; WPA_*) * Returns: The state name as a printable text string */ -const char * wpa_supplicant_state_txt(int state) +const char * wpa_supplicant_state_txt(enum wpa_states state) { switch (state) { case WPA_DISCONNECTED: return "DISCONNECTED"; case WPA_INACTIVE: return "INACTIVE"; + case WPA_INTERFACE_DISABLED: + return "INTERFACE_DISABLED"; case WPA_SCANNING: return "SCANNING"; case WPA_AUTHENTICATING: @@ -513,8 +525,11 @@ const char * wpa_supplicant_state_txt(int state) * This function is called whenever the connection state changes, e.g., * association is completed for WPA/WPA2 4-Way Handshake is started. */ -void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, wpa_states state) +void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, + enum wpa_states state) { + enum wpa_states old_state = wpa_s->wpa_state; + wpa_printf(MSG_DEBUG, "State: %s -> %s", wpa_supplicant_state_txt(wpa_s->wpa_state), wpa_supplicant_state_txt(state)); @@ -522,8 +537,6 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, wpa_states state) if (state != WPA_SCANNING) wpa_supplicant_notify_scanning(wpa_s, 0); - wpas_notify_state_changed(wpa_s, state, wpa_s->wpa_state); - if (state == WPA_COMPLETED && wpa_s->new_connection) { #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) struct wpa_ssid *ssid = wpa_s->current_ssid; @@ -537,37 +550,64 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, wpa_states state) wpa_s->new_connection = 0; 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; wpa_drv_set_operstate(wpa_s, 0); } wpa_s->wpa_state = state; + + if (wpa_s->wpa_state != old_state) + wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state); +} + + +void wpa_supplicant_terminate_proc(struct wpa_global *global) +{ + int pending = 0; +#ifdef CONFIG_WPS + struct wpa_supplicant *wpa_s = global->ifaces; + while (wpa_s) { + if (wpas_wps_terminate_pending(wpa_s) == 1) + pending = 1; + wpa_s = wpa_s->next; + } +#endif /* CONFIG_WPS */ + if (pending) + return; + eloop_terminate(); } -static void wpa_supplicant_terminate(int sig, void *eloop_ctx, - void *signal_ctx) +static void wpa_supplicant_terminate(int sig, void *signal_ctx) { - struct wpa_global *global = eloop_ctx; + struct wpa_global *global = signal_ctx; struct wpa_supplicant *wpa_s; for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING "- signal %d " "received", sig); } - eloop_terminate(); + wpa_supplicant_terminate_proc(global); } -static void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s) +void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s) { - wpa_states old_state = wpa_s->wpa_state; + enum wpa_states old_state = wpa_s->wpa_state; + wpa_s->pairwise_cipher = 0; wpa_s->group_cipher = 0; wpa_s->mgmt_group_cipher = 0; wpa_s->key_mgmt = 0; - wpa_s->wpa_state = WPA_DISCONNECTED; - wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state); + if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED) + wpa_s->wpa_state = WPA_DISCONNECTED; + + if (wpa_s->wpa_state != old_state) + wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state); } @@ -597,6 +637,7 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s) "file '%s' - exiting", wpa_s->confname); return -1; } + conf->changed_parameters = (unsigned int) -1; reconf_ctrl = !!conf->ctrl_interface != !!wpa_s->conf->ctrl_interface || (conf->ctrl_interface && wpa_s->conf->ctrl_interface && @@ -639,29 +680,32 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s) if (reconf_ctrl) wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(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; } -static void wpa_supplicant_reconfig(int sig, void *eloop_ctx, - void *signal_ctx) +static void wpa_supplicant_reconfig(int sig, void *signal_ctx) { - struct wpa_global *global = eloop_ctx; + struct wpa_global *global = signal_ctx; struct wpa_supplicant *wpa_s; wpa_printf(MSG_DEBUG, "Signal %d received - reconfiguring", sig); for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { if (wpa_supplicant_reload_configuration(wpa_s) < 0) { - eloop_terminate(); + wpa_supplicant_terminate_proc(global); } } } -static wpa_cipher cipher_suite2driver(int cipher) +enum wpa_cipher cipher_suite2driver(int cipher) { switch (cipher) { case WPA_CIPHER_NONE: @@ -679,7 +723,7 @@ static wpa_cipher cipher_suite2driver(int cipher) } -static wpa_key_mgmt key_mgmt2driver(int key_mgmt) +enum wpa_key_mgmt key_mgmt2driver(int key_mgmt) { switch (key_mgmt) { case WPA_KEY_MGMT_NONE: @@ -743,7 +787,7 @@ static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s, #ifdef CONFIG_IEEE80211W if (!(ie->capabilities & WPA_CAPABILITY_MFPC) && - ssid->ieee80211w == IEEE80211W_REQUIRED) { + ssid->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) { wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP " "that does not support management frame protection - " "reject"); @@ -770,8 +814,7 @@ static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s, * available). */ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, - struct wpa_scan_res *bss, - struct wpa_ssid *ssid, + struct wpa_bss *bss, struct wpa_ssid *ssid, u8 *wpa_ie, size_t *wpa_ie_len) { struct wpa_ie_data ie; @@ -779,8 +822,8 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, const u8 *bss_wpa, *bss_rsn; if (bss) { - bss_wpa = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); - bss_rsn = wpa_scan_get_ie(bss, WLAN_EID_RSN); + bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); + bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN); } else bss_wpa = bss_rsn = NULL; @@ -813,7 +856,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, ie.key_mgmt = ssid->key_mgmt; #ifdef CONFIG_IEEE80211W ie.mgmt_group_cipher = - ssid->ieee80211w != NO_IEEE80211W ? + ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION ? WPA_CIPHER_AES_128_CMAC : 0; #endif /* CONFIG_IEEE80211W */ wpa_printf(MSG_DEBUG, "WPA: Set cipher suites based " @@ -920,7 +963,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, #ifdef CONFIG_IEEE80211W sel = ie.mgmt_group_cipher; - if (ssid->ieee80211w == NO_IEEE80211W || + if (ssid->ieee80211w == NO_MGMT_FRAME_PROTECTION || !(ie.capabilities & WPA_CAPABILITY_MFPC)) sel = 0; if (sel & WPA_CIPHER_AES_128_CMAC) { @@ -933,6 +976,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, } wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP, wpa_s->mgmt_group_cipher); + wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP, ssid->ieee80211w); #endif /* CONFIG_IEEE80211W */ if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) { @@ -959,20 +1003,21 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, * This function is used to request %wpa_supplicant to associate with a BSS. */ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, - struct wpa_scan_res *bss, struct wpa_ssid *ssid) + 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 = AUTH_ALG_OPEN_SYSTEM; - wpa_cipher cipher_pairwise, cipher_group; + int algs = WPA_AUTH_ALG_OPEN; + enum wpa_cipher cipher_pairwise, cipher_group; struct wpa_driver_associate_params params; int wep_keys_set = 0; struct wpa_driver_capa capa; int assoc_failed = 0; struct wpa_ssid *old_ssid; - if (ssid->mode == 2) { + if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO || + ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) { #ifdef CONFIG_AP if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) { wpa_printf(MSG_INFO, "Driver does not support AP " @@ -980,6 +1025,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, return; } wpa_supplicant_create_ap(wpa_s, ssid); + wpa_s->current_bss = bss; #else /* CONFIG_AP */ wpa_printf(MSG_ERROR, "AP mode support not included in the " "build"); @@ -987,33 +1033,34 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, return; } - if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) { + if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) && + ssid->mode == IEEE80211_MODE_INFRA) { sme_authenticate(wpa_s, bss, ssid); return; } + os_memset(¶ms, 0, sizeof(params)); wpa_s->reassociate = 0; if (bss) { #ifdef CONFIG_IEEE80211R - const u8 *md = NULL; + const u8 *ie, *md = NULL; #endif /* CONFIG_IEEE80211R */ - const u8 *ie = wpa_scan_get_ie(bss, WLAN_EID_SSID); wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid), - ie ? wpa_ssid_txt(ie + 2, ie[1]) : "", bss->freq); + wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq); bssid_changed = !is_zero_ether_addr(wpa_s->bssid); os_memset(wpa_s->bssid, 0, ETH_ALEN); os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN); if (bssid_changed) wpas_notify_bssid_changed(wpa_s); #ifdef CONFIG_IEEE80211R - ie = wpa_scan_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN); + ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN); if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN) md = ie + 2; - wpa_sm_set_ft_params(wpa_s->wpa, md, NULL, 0, NULL); + wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0); if (md) { /* Prepare for the next transition */ - wpa_ft_prepare_auth_request(wpa_s->wpa); + wpa_ft_prepare_auth_request(wpa_s->wpa, ie); } #endif /* CONFIG_IEEE80211R */ #ifdef CONFIG_WPS @@ -1042,27 +1089,21 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) { if (ssid->leap) { if (ssid->non_leap == 0) - algs = AUTH_ALG_LEAP; + algs = WPA_AUTH_ALG_LEAP; else - algs |= AUTH_ALG_LEAP; + algs |= WPA_AUTH_ALG_LEAP; } } #endif /* IEEE8021X_EAPOL */ wpa_printf(MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs); if (ssid->auth_alg) { - algs = 0; - if (ssid->auth_alg & WPA_AUTH_ALG_OPEN) - algs |= AUTH_ALG_OPEN_SYSTEM; - if (ssid->auth_alg & WPA_AUTH_ALG_SHARED) - algs |= AUTH_ALG_SHARED_KEY; - if (ssid->auth_alg & WPA_AUTH_ALG_LEAP) - algs |= AUTH_ALG_LEAP; + algs = ssid->auth_alg; wpa_printf(MSG_DEBUG, "Overriding auth_alg selection: 0x%x", algs); } - if (bss && (wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) || - wpa_scan_get_ie(bss, WLAN_EID_RSN)) && + if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) || + wpa_bss_get_ie(bss, WLAN_EID_RSN)) && (ssid->key_mgmt & (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_FT_PSK | @@ -1106,12 +1147,46 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, wpa_ie_len = 0; wpabuf_free(wps_ie); wpa_supplicant_set_non_wpa_policy(wpa_s, ssid); + if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY)) + params.wps = WPS_MODE_PRIVACY; + else + params.wps = WPS_MODE_OPEN; #endif /* CONFIG_WPS */ } else { wpa_supplicant_set_non_wpa_policy(wpa_s, ssid); 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); @@ -1150,18 +1225,17 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, } wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING); - os_memset(¶ms, 0, sizeof(params)); if (bss) { - const u8 *ie = wpa_scan_get_ie(bss, WLAN_EID_SSID); params.bssid = bss->bssid; - params.ssid = ie ? ie + 2 : (u8 *) ""; - params.ssid_len = ie ? ie[1] : 0; + params.ssid = bss->ssid; + params.ssid_len = bss->ssid_len; params.freq = bss->freq; } else { params.ssid = ssid->ssid; params.ssid_len = ssid->ssid_len; } - if (ssid->mode == 1 && ssid->frequency > 0 && params.freq == 0) + if (ssid->mode == WPAS_MODE_IBSS && ssid->frequency > 0 && + params.freq == 0) params.freq = ssid->frequency; /* Initial channel for IBSS */ params.wpa_ie = wpa_ie; params.wpa_ie_len = wpa_ie_len; @@ -1188,19 +1262,9 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, params.drop_unencrypted = use_crypt; #ifdef CONFIG_IEEE80211W - switch (ssid->ieee80211w) { - case NO_IEEE80211W: - params.mgmt_frame_protection = NO_MGMT_FRAME_PROTECTION; - break; - case IEEE80211W_OPTIONAL: - params.mgmt_frame_protection = MGMT_FRAME_PROTECTION_OPTIONAL; - break; - case IEEE80211W_REQUIRED: - params.mgmt_frame_protection = MGMT_FRAME_PROTECTION_REQUIRED; - break; - } - if (ssid->ieee80211w != NO_IEEE80211W && bss) { - const u8 *rsn = wpa_scan_get_ie(bss, WLAN_EID_RSN); + params.mgmt_frame_protection = ssid->ieee80211w; + if (ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION && bss) { + const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN); struct wpa_ie_data ie; if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 && ie.capabilities & @@ -1213,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, ¶ms); else @@ -1234,7 +1309,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, wpa_supplicant_cancel_auth_timeout(wpa_s); wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); #ifdef CONFIG_IBSS_RSN - } else if (ssid->mode == IEEE80211_MODE_IBSS && + } else if (ssid->mode == WPAS_MODE_IBSS && wpa_s->key_mgmt != WPA_KEY_MGMT_NONE && wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) { ibss_rsn_set_psk(wpa_s->ibss_rsn, ssid->psk); @@ -1243,7 +1318,6 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, * per-BSSID authentication. */ wpa_supplicant_cancel_auth_timeout(wpa_s); - wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); #endif /* CONFIG_IBSS_RSN */ } else { /* Timeout for IEEE 802.11 authentication and association */ @@ -1251,10 +1325,10 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, if (assoc_failed) { /* give IBSS a bit more time */ - timeout = ssid->mode ? 10 : 5; + timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5; } else if (wpa_s->conf->ap_scan == 1) { /* give IBSS a bit more time */ - timeout = ssid->mode ? 20 : 10; + timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10; } wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0); } @@ -1274,6 +1348,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, } old_ssid = wpa_s->current_ssid; wpa_s->current_ssid = ssid; + wpa_s->current_bss = bss; wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid); wpa_supplicant_initiate_eapol(wpa_s); if (old_ssid != wpa_s->current_ssid) @@ -1281,6 +1356,24 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, } +static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s, + const u8 *addr) +{ + struct wpa_ssid *old_ssid; + + wpa_clear_keys(wpa_s, addr); + wpa_supplicant_mark_disassoc(wpa_s); + old_ssid = wpa_s->current_ssid; + wpa_s->current_ssid = NULL; + wpa_s->current_bss = NULL; + wpa_sm_set_config(wpa_s->wpa, NULL); + eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); + if (old_ssid != wpa_s->current_ssid) + wpas_notify_network_changed(wpa_s); + eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL); +} + + /** * wpa_supplicant_disassociate - Disassociate the current connection * @wpa_s: Pointer to wpa_supplicant data @@ -1292,7 +1385,6 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, void wpa_supplicant_disassociate(struct wpa_supplicant *wpa_s, int reason_code) { - struct wpa_ssid *old_ssid; u8 *addr = NULL; if (!is_zero_ether_addr(wpa_s->bssid)) { @@ -1302,14 +1394,8 @@ void wpa_supplicant_disassociate(struct wpa_supplicant *wpa_s, wpa_drv_disassociate(wpa_s, wpa_s->bssid, reason_code); addr = wpa_s->bssid; } - wpa_clear_keys(wpa_s, addr); - wpa_supplicant_mark_disassoc(wpa_s); - old_ssid = wpa_s->current_ssid; - wpa_s->current_ssid = NULL; - wpa_sm_set_config(wpa_s->wpa, NULL); - eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); - if (old_ssid != wpa_s->current_ssid) - wpas_notify_network_changed(wpa_s); + + wpa_supplicant_clear_connection(wpa_s, addr); } @@ -1324,7 +1410,6 @@ void wpa_supplicant_disassociate(struct wpa_supplicant *wpa_s, void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s, int reason_code) { - struct wpa_ssid *old_ssid; u8 *addr = NULL; if (!is_zero_ether_addr(wpa_s->bssid)) { @@ -1335,14 +1420,8 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s, reason_code); addr = wpa_s->bssid; } - wpa_clear_keys(wpa_s, addr); - wpa_supplicant_mark_disassoc(wpa_s); - old_ssid = wpa_s->current_ssid; - wpa_s->current_ssid = NULL; - wpa_sm_set_config(wpa_s->wpa, NULL); - eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); - if (old_ssid != wpa_s->current_ssid) - wpas_notify_network_changed(wpa_s); + + wpa_supplicant_clear_connection(wpa_s, addr); } @@ -1360,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; @@ -1373,18 +1455,18 @@ 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 (wpa_s->current_ssid == NULL && ssid->disabled) { - /* - * Try to reassociate since there is no current configuration - * and a new network was made available. - */ - wpa_s->reassociate = 1; - wpa_supplicant_req_scan(wpa_s, 0, 0); + } else if (ssid->disabled && ssid->disabled != 2) { + if (wpa_s->current_ssid == NULL) { + /* + * Try to reassociate since there is no current + * configuration and a new network was made available. + */ + wpa_s->reassociate = 1; + wpa_supplicant_req_scan(wpa_s, 0, 0); + } was_disabled = ssid->disabled; @@ -1410,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); @@ -1459,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; @@ -1534,94 +1617,17 @@ int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level, wpa_debug_timestamp = debug_timestamp ? 1 : 0; wpa_debug_show_keys = debug_show_keys ? 1 : 0; - if (wpa_debug_level != old_level || - wpa_debug_timestamp != old_timestamp || - wpa_debug_show_keys != old_show_keys) - wpas_notify_debug_params_changed(global); + if (wpa_debug_level != old_level) + wpas_notify_debug_level_changed(global); + if (wpa_debug_timestamp != old_timestamp) + wpas_notify_debug_timestamp_changed(global); + if (wpa_debug_show_keys != old_show_keys) + wpas_notify_debug_show_keys_changed(global); return 0; } -static void notify_bss_changes(struct wpa_supplicant *wpa_s, - u8 (*prev_bssids)[ETH_ALEN], int prev_num, - struct wpa_scan_results *new) -{ - int new_num, i, j; - - new_num = new != NULL ? new->num : 0; - if (prev_bssids == NULL) - prev_num = 0; - - for (i = 0; i < prev_num; i++) { - for (j = 0; j < new_num; j++) { - if (!os_memcmp(prev_bssids[i], new->res[j]->bssid, - ETH_ALEN)) - break; - } - if (j == new_num) - wpas_notify_bss_removed(wpa_s, prev_bssids[i]); - } - for (i = 0; i < new_num; i++) { - for (j = 0; j < prev_num; j++) { - if (!os_memcmp(new->res[i]->bssid, prev_bssids[j], - ETH_ALEN)) - break; - } - if (j == prev_num) - wpas_notify_bss_added(wpa_s, new->res[i]->bssid); - } -} - - -/** - * wpa_supplicant_get_scan_results - Get scan results - * @wpa_s: Pointer to wpa_supplicant data - * Returns: 0 on success, -1 on failure - * - * This function is request the current scan results from the driver and stores - * a local copy of the results in wpa_s->scan_res. - */ -int wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s) -{ - int ret, i, prev_scan_res_num; - u8 (*prev_scan_bssids)[ETH_ALEN]; - - prev_scan_res_num = wpa_s->scan_res ? wpa_s->scan_res->num : 0; - prev_scan_bssids = os_malloc(prev_scan_res_num * ETH_ALEN); - - if (prev_scan_bssids) { - for (i = 0; i < prev_scan_res_num; i++) { - os_memcpy(prev_scan_bssids[i], - wpa_s->scan_res->res[i]->bssid, ETH_ALEN); - } - } else { - wpa_printf(MSG_WARNING, "Not enough memory for old scan " - "results list"); - prev_scan_res_num = 0; - } - - wpa_scan_results_free(wpa_s->scan_res); - if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) - wpa_s->scan_res = ieee80211_sta_get_scan_results(wpa_s); - else - wpa_s->scan_res = wpa_drv_get_scan_results2(wpa_s); - if (wpa_s->scan_res == NULL) { - wpa_printf(MSG_DEBUG, "Failed to get scan results"); - ret = -1; - } else { - ret = 0; - wpa_scan_sort_results(wpa_s->scan_res); - } - - notify_bss_changes(wpa_s, prev_scan_bssids, prev_scan_res_num, - wpa_s->scan_res); - os_free(prev_scan_bssids); - - return ret; -} - - /** * wpa_supplicant_get_ssid - Get a pointer to the current network structure * @wpa_s: Pointer to wpa_supplicant data @@ -1704,6 +1710,7 @@ static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s, if (name == NULL) { /* default to first driver in the list */ wpa_s->driver = wpa_drivers[0]; + wpa_s->global_drv_priv = wpa_s->global->drv_priv[0]; return 0; } @@ -1717,6 +1724,7 @@ static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s, os_strncmp(name, wpa_drivers[i]->name, len) == 0) { wpa_s->driver = wpa_drivers[i]; + wpa_s->global_drv_priv = wpa_s->global->drv_priv[i]; return 0; } } @@ -1726,6 +1734,20 @@ static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s, } +/** + * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant + * @ctx: Context pointer (wpa_s); this is the ctx variable registered + * with struct wpa_driver_ops::init() + * @src_addr: Source address of the EAPOL frame + * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header) + * @len: Length of the EAPOL data + * + * This function is called for each received EAPOL frame. Most driver + * interfaces rely on more generic OS mechanism for receiving frames through + * l2_packet, but if such a mechanism is not available, the driver wrapper may + * take care of received EAPOL frames and deliver them to the core supplicant + * code by calling this function. + */ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) { @@ -1771,7 +1793,9 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, if (wpa_s->eapol_received == 0 && (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) || !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || - wpa_s->wpa_state != WPA_COMPLETED)) { + wpa_s->wpa_state != WPA_COMPLETED) && + (wpa_s->current_ssid == NULL || + wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) { /* Timeout for completing IEEE 802.1X and WPA authentication */ wpa_supplicant_req_auth_timeout( wpa_s, @@ -1790,7 +1814,7 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, #ifdef CONFIG_IBSS_RSN if (wpa_s->current_ssid && - wpa_s->current_ssid->mode == IEEE80211_MODE_IBSS) { + wpa_s->current_ssid->mode == WPAS_MODE_IBSS) { ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len); return; } @@ -1821,14 +1845,6 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, } -void wpa_supplicant_sta_rx(void *ctx, const u8 *buf, size_t len, - struct ieee80211_rx_status *rx_status) -{ - struct wpa_supplicant *wpa_s = ctx; - ieee80211_sta_rx(wpa_s, buf, len, rx_status); -} - - /** * wpa_supplicant_driver_init - Initialize driver interface parameters * @wpa_s: Pointer to wpa_supplicant data @@ -1846,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)) { @@ -1889,8 +1910,11 @@ int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s) wpa_drv_flush_pmkid(wpa_s); wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN; - wpa_supplicant_req_scan(wpa_s, interface_count, 100000); - interface_count++; + if (wpa_supplicant_enabled_networks(wpa_s->conf)) { + wpa_supplicant_req_scan(wpa_s, interface_count, 100000); + interface_count++; + } else + wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); return 0; } @@ -1911,6 +1935,8 @@ static struct wpa_supplicant * wpa_supplicant_alloc(void) if (wpa_s == NULL) return NULL; wpa_s->scan_req = 1; + wpa_s->new_connection = 1; + wpa_s->parent = wpa_s; return wpa_s; } @@ -2012,7 +2038,7 @@ next_driver: wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname); if (wpa_s->drv_priv == NULL) { const char *pos; - pos = os_strchr(driver, ','); + pos = driver ? os_strchr(driver, ',') : NULL; if (pos) { wpa_printf(MSG_DEBUG, "Failed to initialize driver " "interface - try next driver wrapper"); @@ -2067,6 +2093,19 @@ next_driver: return -1; } + if (wpa_drv_get_capa(wpa_s, &capa) == 0) { + wpa_s->drv_flags = capa.flags; + if (capa.flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) { + if (ieee80211_sta_init(wpa_s)) + return -1; + } + 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; + if (wpa_supplicant_driver_init(wpa_s) < 0) return -1; @@ -2099,15 +2138,6 @@ next_driver: return -1; } - if (wpa_drv_get_capa(wpa_s, &capa) == 0) { - wpa_s->drv_flags = capa.flags; - if (capa.flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) { - if (ieee80211_sta_init(wpa_s)) - return -1; - } - wpa_s->max_scan_ssids = capa.max_scan_ssids; - } - #ifdef CONFIG_IBSS_RSN wpa_s->ibss_rsn = ibss_rsn_init(wpa_s); if (!wpa_s->ibss_rsn) { @@ -2116,11 +2146,22 @@ 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; + return 0; } -static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s) +static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s, + int notify) { if (wpa_s->drv_priv) { wpa_supplicant_deauthenticate(wpa_s, @@ -2130,10 +2171,11 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s) wpa_clear_keys(wpa_s, NULL); } - wpas_notify_iface_removed(wpa_s); - wpa_supplicant_cleanup(wpa_s); + if (notify) + wpas_notify_iface_removed(wpa_s); + if (wpa_s->drv_priv) wpa_drv_deinit(wpa_s); } @@ -2156,6 +2198,7 @@ struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global, { struct wpa_supplicant *wpa_s; struct wpa_interface t_iface; + struct wpa_ssid *ssid; if (global == NULL || iface == NULL) return NULL; @@ -2164,6 +2207,8 @@ struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global, if (wpa_s == NULL) return NULL; + wpa_s->global = global; + t_iface = *iface; if (global->params.override_driver) { wpa_printf(MSG_DEBUG, "Override interface parameter: driver " @@ -2182,20 +2227,21 @@ struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global, if (wpa_supplicant_init_iface(wpa_s, &t_iface)) { wpa_printf(MSG_DEBUG, "Failed to add interface %s", iface->ifname); - wpa_supplicant_deinit_iface(wpa_s); + wpa_supplicant_deinit_iface(wpa_s, 0); os_free(wpa_s); return NULL; } - wpa_s->global = global; - /* Notify the control interfaces about new iface */ if (wpas_notify_iface_added(wpa_s)) { - wpa_supplicant_deinit_iface(wpa_s); + wpa_supplicant_deinit_iface(wpa_s, 1); os_free(wpa_s); return NULL; } + for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) + wpas_notify_network_added(wpa_s, ssid); + wpa_s->next = global->ifaces; global->ifaces = wpa_s; @@ -2235,7 +2281,9 @@ int wpa_supplicant_remove_iface(struct wpa_global *global, wpa_printf(MSG_DEBUG, "Removing interface %s", wpa_s->ifname); - wpa_supplicant_deinit_iface(wpa_s); + if (global->p2p_group_formation == wpa_s) + global->p2p_group_formation = NULL; + wpa_supplicant_deinit_iface(wpa_s, 1); os_free(wpa_s); return 0; @@ -2282,7 +2330,7 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params) if (params->wpa_debug_syslog) wpa_debug_open_syslog(); - ret = eap_peer_register_methods(); + ret = eap_register_methods(); if (ret) { wpa_printf(MSG_ERROR, "Failed to register EAP methods"); if (ret == -2) @@ -2291,20 +2339,11 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params) return NULL; } -#ifdef CONFIG_AP - ret = eap_server_register_methods(); - if (ret) { - wpa_printf(MSG_ERROR, "Failed to register EAP server methods"); - if (ret == -2) - wpa_printf(MSG_ERROR, "Two or more EAP methods used " - "the same EAP type."); - return NULL; - } -#endif /* CONFIG_AP */ - 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; @@ -2326,7 +2365,7 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params) wpa_debug_timestamp = global->params.wpa_debug_timestamp = params->wpa_debug_timestamp; - if (eloop_init(global)) { + if (eloop_init()) { wpa_printf(MSG_ERROR, "Failed to initialize event loop"); wpa_supplicant_deinit(global); return NULL; @@ -2395,8 +2434,8 @@ int wpa_supplicant_run(struct wpa_global *global) wpa_s->ctrl_iface); } - eloop_register_signal_terminate(wpa_supplicant_terminate, NULL); - eloop_register_signal_reconfig(wpa_supplicant_reconfig, NULL); + eloop_register_signal_terminate(wpa_supplicant_terminate, global); + eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); eloop_run(); @@ -2418,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); @@ -2452,3 +2495,17 @@ void wpa_supplicant_deinit(struct wpa_global *global) wpa_debug_close_syslog(); wpa_debug_close_file(); } + + +void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s) +{ +#ifdef CONFIG_WPS + 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; +}