X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=wpa_supplicant%2Fwpa_supplicant.c;h=61d1c87e48d82a2e48eef242257f1a62b704f045;hb=HEAD;hp=5d6769175a54b437df809985792850e1519fab0a;hpb=eb0a3c7f96a36ce9c7e4d9b8be049149e1f88423;p=libeap.git diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 5d67691..61d1c87 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -36,12 +36,14 @@ #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; @@ -628,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 && @@ -670,9 +680,13 @@ 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; } @@ -991,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; @@ -1002,7 +1016,8 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, int assoc_failed = 0; struct wpa_ssid *old_ssid; - if (ssid->mode == WPAS_MODE_AP) { + 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 " @@ -1024,6 +1039,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, return; } + os_memset(¶ms, 0, sizeof(params)); wpa_s->reassociate = 0; if (bss) { #ifdef CONFIG_IEEE80211R @@ -1131,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); @@ -1175,7 +1225,6 @@ 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) { params.bssid = bss->bssid; params.ssid = bss->ssid; @@ -1228,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 @@ -1296,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 @@ -1307,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)) { @@ -1317,16 +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_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_clear_connection(wpa_s, addr); } @@ -1341,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)) { @@ -1352,16 +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_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_clear_connection(wpa_s, addr); } @@ -1379,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; @@ -1392,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 @@ -1431,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); @@ -1480,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; @@ -1800,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)) { @@ -1869,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; } @@ -2033,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; @@ -2077,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; @@ -2205,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); @@ -2264,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; @@ -2377,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); @@ -2411,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; +}