[pkg-wpa-devel] r1731 - in /wpa/trunk: debian/ debian/patches/ debian/patches/upstream/ hostapd/ src/ap/ src/common/ src/drivers/ src/eap_peer/ src/eap_server/ src/p2p/ src/radius/ src/utils/ src/wps/ wpa_supplicant/ wpa_supplicant/dbus/

slh-guest at users.alioth.debian.org slh-guest at users.alioth.debian.org
Tue Apr 17 11:03:58 UTC 2012


Author: slh-guest
Date: Tue Apr 17 11:03:56 2012
New Revision: 1731

URL: http://svn.debian.org/wsvn/pkg-wpa/?sc=1&rev=1731
Log:
import new upstream snapshot 1.0-rc3:

Removed:
    wpa/trunk/debian/patches/upstream/
Modified:
    wpa/trunk/debian/changelog
    wpa/trunk/debian/patches/series
    wpa/trunk/hostapd/defconfig
    wpa/trunk/src/ap/accounting.c
    wpa/trunk/src/ap/drv_callbacks.c
    wpa/trunk/src/ap/hostapd.c
    wpa/trunk/src/ap/hostapd.h
    wpa/trunk/src/ap/ieee802_11.c
    wpa/trunk/src/ap/ieee802_11_auth.c
    wpa/trunk/src/ap/ieee802_1x.c
    wpa/trunk/src/ap/sta_info.c
    wpa/trunk/src/ap/wps_hostapd.c
    wpa/trunk/src/common/version.h
    wpa/trunk/src/drivers/driver.h
    wpa/trunk/src/drivers/driver_nl80211.c
    wpa/trunk/src/drivers/driver_wext.c
    wpa/trunk/src/drivers/nl80211_copy.h
    wpa/trunk/src/eap_peer/eap_aka.c
    wpa/trunk/src/eap_peer/eap_sim.c
    wpa/trunk/src/eap_peer/eap_ttls.c
    wpa/trunk/src/eap_server/eap_server_aka.c
    wpa/trunk/src/eap_server/eap_server_sim.c
    wpa/trunk/src/p2p/p2p.c
    wpa/trunk/src/p2p/p2p.h
    wpa/trunk/src/p2p/p2p_go_neg.c
    wpa/trunk/src/p2p/p2p_i.h
    wpa/trunk/src/p2p/p2p_invitation.c
    wpa/trunk/src/p2p/p2p_pd.c
    wpa/trunk/src/radius/radius_client.c
    wpa/trunk/src/utils/wpa_debug.c
    wpa/trunk/src/wps/wps.h
    wpa/trunk/src/wps/wps_enrollee.c
    wpa/trunk/wpa_supplicant/Android.mk
    wpa/trunk/wpa_supplicant/Makefile
    wpa/trunk/wpa_supplicant/ap.c
    wpa/trunk/wpa_supplicant/bss.c
    wpa/trunk/wpa_supplicant/bss.h
    wpa/trunk/wpa_supplicant/config.c
    wpa/trunk/wpa_supplicant/config.h
    wpa/trunk/wpa_supplicant/config_file.c
    wpa/trunk/wpa_supplicant/config_ssid.h
    wpa/trunk/wpa_supplicant/ctrl_iface.c
    wpa/trunk/wpa_supplicant/dbus/Makefile
    wpa/trunk/wpa_supplicant/dbus/dbus_new.c
    wpa/trunk/wpa_supplicant/dbus/dbus_new_handlers.c
    wpa/trunk/wpa_supplicant/dbus/dbus_new_handlers.h
    wpa/trunk/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
    wpa/trunk/wpa_supplicant/dbus/dbus_new_handlers_p2p.h
    wpa/trunk/wpa_supplicant/defconfig
    wpa/trunk/wpa_supplicant/driver_i.h
    wpa/trunk/wpa_supplicant/eapol_test.c
    wpa/trunk/wpa_supplicant/events.c
    wpa/trunk/wpa_supplicant/interworking.c
    wpa/trunk/wpa_supplicant/notify.c
    wpa/trunk/wpa_supplicant/notify.h
    wpa/trunk/wpa_supplicant/p2p_supplicant.c
    wpa/trunk/wpa_supplicant/p2p_supplicant.h
    wpa/trunk/wpa_supplicant/scan.c
    wpa/trunk/wpa_supplicant/sme.c
    wpa/trunk/wpa_supplicant/wpa_supplicant.c
    wpa/trunk/wpa_supplicant/wpa_supplicant_i.h
    wpa/trunk/wpa_supplicant/wps_supplicant.c

Modified: wpa/trunk/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/debian/changelog?rev=1731&op=diff
==============================================================================
--- wpa/trunk/debian/changelog (original)
+++ wpa/trunk/debian/changelog Tue Apr 17 11:03:56 2012
@@ -1,14 +1,13 @@
-wpa (1:1.0~rc2-1) UNRELEASED; urgency=low
+wpa (1:1.0~rc3-1) UNRELEASED; urgency=low
+
+  * NOT RELEASED YET
 
   [ Stefan Lippers-Hollmann ]
-  * NOT RELEASED YET
-  * import new upstream snapshot 1.0-rc2:
+  * import new upstream snapshot 1.0-rc3:
     - fixes:
       - hostapd: Fails to authenticate on wpa2 password (Closes: #483924)
       - hostapd: EAPOL reauthentication/rekeying timeout loop when using WMM
         (Closes: #655129, #659059)
-    - import git patches up to hostap_0_7_2-1521-g1ca6871.
-    - temporarily disable conflicting patches.
     - rebase patches:
       - libnl3-includes
     - update hostapd configs.
@@ -60,7 +59,7 @@
   * Remove Faidon Liambotis <paravoid at debian.org> from Uploaders as per
     his request, many thanks for all past efforts Faidon.
 
- -- Stefan Lippers-Hollmann <s.l-h at gmx.de>  Tue, 17 Apr 2012 01:29:46 +0200
+ -- Stefan Lippers-Hollmann <s.l-h at gmx.de>  Tue, 17 Apr 2012 12:58:09 +0200
 
 wpasupplicant (0.7.3-6) unstable; urgency=low
 

Modified: wpa/trunk/debian/patches/series
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/debian/patches/series?rev=1731&op=diff
==============================================================================
--- wpa/trunk/debian/patches/series (original)
+++ wpa/trunk/debian/patches/series Tue Apr 17 11:03:56 2012
@@ -1,79 +1,3 @@
-upstream/0001-Fix-ap_sta_disconnect-to-clear-EAPOL-WPA-authenticat.patch
-upstream/0002-P2P-Fix-WSC-IE-inclusion-for-P2P-disabled-case.patch
-upstream/0003-WPS-Fix-an-interoperability-issue-with-mixed-mode-an.patch
-upstream/0004-dbus-Create-DBus-getter-setter-for-FastReauth.patch
-upstream/0005-dbus-Fix-endianness-bug-in-Frequency-and-Signal-prop.patch
-upstream/0006-wpa_debug-Support-outputting-hexdumps-into-syslog.patch
-upstream/0007-dbus-Remove-unused-D-Bus-version-defines.patch
-upstream/0008-build-Fix-install-target-parent-directory-prerequisi.patch
-upstream/0009-Install-only-the-binaries-into-BINDIR.patch
-upstream/0010-SME-Fix-processing-of-Authentication-timeout-and-fai.patch
-upstream/0011-WPS-Disable-AP-PIN-after-10-consecutive-failures.patch
-upstream/0012-Interworking-Fix-EAP-TTLS-MSCHAP-configuration.patch
-upstream/0013-Clear-EAPOL-authenticator-authFail-for-PMKSA-caching.patch
-upstream/0014-Delay-scan-request-on-select_network-if-disconnectin.patch
-upstream/0015-P2P-Fix-DBus-crash-and-return-additional-P2P-group-p.patch
-upstream/0016-P2P-Fix-the-setter-function-for-DBus-group-propertie.patch
-upstream/0017-Try-fallback-drivers-if-global-init-for-preferred-dr.patch
-upstream/0018-P2P-Remove-unneeded-go_neg_peer-check-from-PD.patch
-upstream/0019-P2P-Skip-event-notification-on-PD-Response-in-join-g.patch
-upstream/0020-P2P-Wait-for-PD-before-join-response.patch
-upstream/0021-Move-AP-events-for-STA-connected-disconnected-into-o.patch
-upstream/0022-P2P-Send-STA-connected-disconnected-events-to-parent.patch
-upstream/0023-P2P-Append-P2P-Device-Address-to-AP-STA-DISCONNECTED.patch
-upstream/0024-P2P-Maintain-a-list-of-P2P-Clients-for-persistent-gr.patch
-upstream/0025-P2P-Set-Invitation-Type-to-1-for-GO-inviting-to-a-pe.patch
-upstream/0026-P2P-Allow-BSS-entry-to-be-fetched-based-on-GO-P2P-De.patch
-upstream/0027-P2P-Move-p2p_add_device-prototype-to-correct-header-.patch
-upstream/0028-P2P-Fix-p2p_scan-error-processing-in-p2p_search.patch
-upstream/0029-P2P-Avoid-re-starting-p2p_search-in-some-corner-case.patch
-upstream/0030-P2P-Do-not-expire-GO-peer-entry-during-group-rekeyin.patch
-upstream/0031-EAP-pwd-Describe-build-option-for-EAP-pwd.patch
-upstream/0032-WPS-Fix-regression-in-post-WPS-scan-optimization.patch
-upstream/0033-Ignore-TX-status-for-Data-frames-from-not-associated.patch
-upstream/0034-EAP-SIM-AKA-server-Fix-re-authentication-not-to-upda.patch
-upstream/0035-Revert-nl80211-Fix-CONFIG_TDLS-y-build.patch
-upstream/0036-EAP-AKA-peer-Clean-up-forgetting-id-debug-prints.patch
-upstream/0037-EAP-AKA-peer-Append-realm-when-learning-the-pseudony.patch
-upstream/0038-EAP-SIM-peer-Append-realm-when-learning-the-pseudony.patch
-upstream/0039-P2P-Do-not-include-P2P-IE-in-association-request-to-.patch
-upstream/0040-nl80211-Filter-unexpected-interface-added-up-events.patch
-upstream/0041-Use-WPA_INTERFACE_DISABLED-with-interface-removed-ev.patch
-upstream/0042-wext-Filter-unexpected-interface-added-up-events.patch
-upstream/0043-dbus-Make-the-P2P-peer-s-properties-accessible-separ.patch
-upstream/0044-dbus-utility-to-create-dbus-message-from-wpabuf-arra.patch
-upstream/0045-dbus-revert-changes-to-some-peer-properties.patch
-upstream/0046-dbus-return-NULL-data-for-peer-IEs.patch
-upstream/0047-P2P-Fix-group-idle-timer-cancellation-on-group-remov.patch
-upstream/0048-Fix-processing-of-channel-list-update-events.patch
-upstream/0049-P2P-Skip-duplicated-provision-discovery-on-join.patch
-upstream/0050-P2P-Fix-provisioning-info-clearing-after-successful-.patch
-upstream/0051-P2P-Fix-remain-on-channel-use-with-PD-Invitation-Req.patch
-upstream/0052-P2P-Make-p2p_flush-stop-P2P-operations-consistently.patch
-upstream/0053-P2P-Fix-p2p_cancel-to-return-success-if-GO-Negotiati.patch
-upstream/0054-Fix-memory-leak-on-parsing-multiple-network-block-ea.patch
-upstream/0055-P2P-Filter-input-parameters-in-p2p_serv_disc_externa.patch
-upstream/0056-TTLS-Fix-peer-challenge-generation-for-TTLS-MSCHAPv2.patch
-upstream/0057-BSS-Fix-use-after-realloc.patch
-upstream/0058-dbus-Make-P2P-group-properties-accessible-individual.patch
-upstream/0059-P2P-Validate-p2p_oper_channel-in-p2p_group_add.patch
-upstream/0060-P2P-Do-not-use-group-idle-timeout-during-provisionin.patch
-upstream/0061-Sync-with-include-linux-nl80211.h-from-wireless-test.patch
-upstream/0062-P2P-Add-support-for-preferred-channel-list.patch
-upstream/0063-Clear-previous-BSSID-on-explicit-disconnection-reque.patch
-upstream/0064-P2P-Use-P2P-Device-ID-attribute-if-Device-Info-not-a.patch
-upstream/0065-Fix-potential-double-free-and-use-of-freed-memory-in.patch
-upstream/0066-Fix-memory-leaks-on-radius_client_send-error-paths.patch
-upstream/0067-P2P-Add-deinit_p2p_cli-op-to-clear-P2P-client-driver.patch
-upstream/0068-P2P-Notify-about-disconnection-only-when-needed.patch
-upstream/0069-Change-reason-code-for-AP-mode-BSS-termination-to-3.patch
-upstream/0070-Save-bgscan-parameter-into-configuration-file.patch
-upstream/0071-Clarify-comment-in-wpa_supplicant-defconfig.patch
-upstream/0072-P2P-Fix-crash-for-failure-case-when-WSC-PIN-is-enter.patch
-upstream/0073-P2P-Disconnect-P2P-group-on-supplicant-deinit.patch
-upstream/0074-Fix-EAP-WPS-to-PSK-transition-on-reassociation-in-au.patch
-upstream/0075-AP-Reset-STA-timeout_next-on-driver-based-SME-associ.patch
-
 01_use_pkg-config_for_pcsc-lite_module.patch
 02_dbus_group_policy.patch
 06_wpa_gui_menu_exec_path.patch

Modified: wpa/trunk/hostapd/defconfig
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/hostapd/defconfig?rev=1731&op=diff
==============================================================================
--- wpa/trunk/hostapd/defconfig (original)
+++ wpa/trunk/hostapd/defconfig Tue Apr 17 11:03:56 2012
@@ -83,6 +83,9 @@
 
 # EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK)
 #CONFIG_EAP_PSK=y
+
+# EAP-pwd for the integrated EAP server (secure authentication with a password)
+#CONFIG_EAP_PWD=y
 
 # EAP-SAKE for the integrated EAP server
 #CONFIG_EAP_SAKE=y

Modified: wpa/trunk/src/ap/accounting.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/ap/accounting.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/ap/accounting.c (original)
+++ wpa/trunk/src/ap/accounting.c Tue Apr 17 11:03:56 2012
@@ -265,8 +265,9 @@
 			       hapd, sta);
 
 	msg = accounting_msg(hapd, sta, RADIUS_ACCT_STATUS_TYPE_START);
-	if (msg)
-		radius_client_send(hapd->radius, msg, RADIUS_ACCT, sta->addr);
+	if (msg &&
+	    radius_client_send(hapd->radius, msg, RADIUS_ACCT, sta->addr) < 0)
+		radius_msg_free(msg);
 
 	sta->acct_session_started = 1;
 }
@@ -364,9 +365,10 @@
 		goto fail;
 	}
 
-	radius_client_send(hapd->radius, msg,
-			   stop ? RADIUS_ACCT : RADIUS_ACCT_INTERIM,
-			   sta->addr);
+	if (radius_client_send(hapd->radius, msg,
+			       stop ? RADIUS_ACCT : RADIUS_ACCT_INTERIM,
+			       sta->addr) < 0)
+		goto fail;
 	return;
 
  fail:
@@ -469,7 +471,8 @@
 		return;
 	}
 
-	radius_client_send(hapd->radius, msg, RADIUS_ACCT, NULL);
+	if (radius_client_send(hapd->radius, msg, RADIUS_ACCT, NULL) < 0)
+		radius_msg_free(msg);
 }
 
 

Modified: wpa/trunk/src/ap/drv_callbacks.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/ap/drv_callbacks.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/ap/drv_callbacks.c (original)
+++ wpa/trunk/src/ap/drv_callbacks.c Tue Apr 17 11:03:56 2012
@@ -87,6 +87,12 @@
 	sta = ap_get_sta(hapd, addr);
 	if (sta) {
 		accounting_sta_stop(hapd, sta);
+
+		/*
+		 * Make sure that the previously registered inactivity timer
+		 * will not remove the STA immediately.
+		 */
+		sta->timeout_next = STA_NULLFUNC;
 	} else {
 		sta = ap_sta_add(hapd, addr);
 		if (sta == NULL)
@@ -248,9 +254,8 @@
 		return;
 	}
 
+	ap_sta_set_authorized(hapd, sta, 0);
 	sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
-	wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR,
-		MAC2STR(sta->addr));
 	wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
 	sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
 	ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);

Modified: wpa/trunk/src/ap/hostapd.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/ap/hostapd.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/ap/hostapd.c (original)
+++ wpa/trunk/src/ap/hostapd.c Tue Apr 17 11:03:56 2012
@@ -38,7 +38,7 @@
 #include "p2p_hostapd.h"
 
 
-static int hostapd_flush_old_stations(struct hostapd_data *hapd);
+static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason);
 static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd);
 static int hostapd_broadcast_wep_clear(struct hostapd_data *hapd);
 
@@ -111,7 +111,8 @@
 	 * allow them to use the BSS anymore.
 	 */
 	for (j = 0; j < iface->num_bss; j++) {
-		hostapd_flush_old_stations(iface->bss[j]);
+		hostapd_flush_old_stations(iface->bss[j],
+					   WLAN_REASON_PREV_AUTH_NOT_VALID);
 		hostapd_broadcast_wep_clear(iface->bss[j]);
 
 #ifndef CONFIG_NO_RADIUS
@@ -337,7 +338,7 @@
 }
 
 
-static int hostapd_flush_old_stations(struct hostapd_data *hapd)
+static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason)
 {
 	int ret = 0;
 	u8 addr[ETH_ALEN];
@@ -352,7 +353,7 @@
 	}
 	wpa_printf(MSG_DEBUG, "Deauthenticate all stations");
 	os_memset(addr, 0xff, ETH_ALEN);
-	hostapd_drv_sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
+	hostapd_drv_sta_deauth(hapd, addr, reason);
 	hostapd_free_stas(hapd);
 
 	return ret;
@@ -522,7 +523,7 @@
 	if (conf->wmm_enabled < 0)
 		conf->wmm_enabled = hapd->iconf->ieee80211n;
 
-	hostapd_flush_old_stations(hapd);
+	hostapd_flush_old_stations(hapd, WLAN_REASON_PREV_AUTH_NOT_VALID);
 	hostapd_set_privacy(hapd, 0);
 
 	hostapd_broadcast_wep_clear(hapd);
@@ -876,7 +877,7 @@
 	for (j = 0; j < iface->num_bss; j++) {
 		struct hostapd_data *hapd = iface->bss[j];
 		hostapd_free_stas(hapd);
-		hostapd_flush_old_stations(hapd);
+		hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING);
 		hostapd_cleanup(hapd);
 	}
 }

Modified: wpa/trunk/src/ap/hostapd.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/ap/hostapd.h?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/ap/hostapd.h (original)
+++ wpa/trunk/src/ap/hostapd.h Tue Apr 17 11:03:56 2012
@@ -82,6 +82,7 @@
 				 struct sta_info *sta, int reassoc);
 
 	void *msg_ctx; /* ctx for wpa_msg() calls */
+	void *msg_ctx_parent; /* parent interface ctx for wpa_msg() calls */
 
 	struct radius_client_data *radius;
 	u32 acct_session_id_hi, acct_session_id_lo;
@@ -124,6 +125,7 @@
 	struct wpabuf *wps_probe_resp_ie;
 #ifdef CONFIG_WPS
 	unsigned int ap_pin_failures;
+	unsigned int ap_pin_failures_consecutive;
 	struct upnp_wps_device_sm *wps_upnp;
 	unsigned int ap_pin_lockout_time;
 #endif /* CONFIG_WPS */
@@ -148,7 +150,7 @@
 	void *wps_event_cb_ctx;
 
 	void (*sta_authorized_cb)(void *ctx, const u8 *mac_addr,
-				  int authorized);
+				  int authorized, const u8 *p2p_dev_addr);
 	void *sta_authorized_cb_ctx;
 
 	void (*setup_complete_cb)(void *ctx);

Modified: wpa/trunk/src/ap/ieee802_11.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/ap/ieee802_11.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/ap/ieee802_11.c (original)
+++ wpa/trunk/src/ap/ieee802_11.c Tue Apr 17 11:03:56 2012
@@ -1112,9 +1112,8 @@
 		return;
 	}
 
+	ap_sta_set_authorized(hapd, sta, 0);
 	sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK);
-	wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR,
-		MAC2STR(sta->addr));
 	wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
 		       HOSTAPD_LEVEL_INFO, "disassociated");
@@ -1162,10 +1161,9 @@
 		return;
 	}
 
+	ap_sta_set_authorized(hapd, sta, 0);
 	sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC |
 			WLAN_STA_ASSOC_REQ_OK);
-	wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR,
-		MAC2STR(sta->addr));
 	wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
 		       HOSTAPD_LEVEL_DEBUG, "deauthenticated");
@@ -1525,8 +1523,6 @@
 		 * step.
 		 */
 		ap_sta_set_authorized(hapd, sta, 1);
-		wpa_msg(hapd->msg_ctx, MSG_INFO,
-			AP_STA_CONNECTED MACSTR, MAC2STR(sta->addr));
 	}
 
 	if (reassoc)
@@ -1729,7 +1725,7 @@
 				break;
 		}
 	}
-	if (sta == NULL)
+	if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))
 		return;
 	if (sta->flags & WLAN_STA_PENDING_POLL) {
 		wpa_printf(MSG_DEBUG, "STA " MACSTR " %s pending "

Modified: wpa/trunk/src/ap/ieee802_11_auth.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/ap/ieee802_11_auth.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/ap/ieee802_11_auth.c (original)
+++ wpa/trunk/src/ap/ieee802_11_auth.c Tue Apr 17 11:03:56 2012
@@ -191,7 +191,8 @@
 		goto fail;
 	}
 
-	radius_client_send(hapd->radius, msg, RADIUS_AUTH, addr);
+	if (radius_client_send(hapd->radius, msg, RADIUS_AUTH, addr) < 0)
+		goto fail;
 	return 0;
 
  fail:

Modified: wpa/trunk/src/ap/ieee802_1x.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/ap/ieee802_1x.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/ap/ieee802_1x.c (original)
+++ wpa/trunk/src/ap/ieee802_1x.c Tue Apr 17 11:03:56 2012
@@ -1,6 +1,6 @@
 /*
  * hostapd / IEEE 802.1X-2004 Authenticator
- * Copyright (c) 2002-2011, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2002-2012, Jouni Malinen <j at w1.fi>
  *
  * 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
@@ -90,32 +90,11 @@
 		return;
 
 	if (authorized) {
-		if (!ap_sta_is_authorized(sta)) {
-			const u8 *dev_addr = NULL;
-#ifdef CONFIG_P2P
-			dev_addr = p2p_group_get_dev_addr(hapd->p2p_group,
-							  sta->addr);
-#endif /* CONFIG_P2P */
-
-			if (dev_addr)
-				wpa_msg(hapd->msg_ctx, MSG_INFO,
-					AP_STA_CONNECTED MACSTR
-					" dev_addr=" MACSTR,
-					MAC2STR(sta->addr), MAC2STR(dev_addr));
-			else
-				wpa_msg(hapd->msg_ctx, MSG_INFO,
-					AP_STA_CONNECTED MACSTR,
-					MAC2STR(sta->addr));
-		}
 		ap_sta_set_authorized(hapd, sta, 1);
 		res = hostapd_set_authorized(hapd, sta, 1);
 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
 			       HOSTAPD_LEVEL_DEBUG, "authorizing port");
 	} else {
-		if (ap_sta_is_authorized(sta) && (sta->flags & WLAN_STA_ASSOC))
-			wpa_msg(hapd->msg_ctx, MSG_INFO,
-				AP_STA_DISCONNECTED MACSTR,
-				MAC2STR(sta->addr));
 		ap_sta_set_authorized(hapd, sta, 0);
 		res = hostapd_set_authorized(hapd, sta, 0);
 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
@@ -889,12 +868,22 @@
 	if (!force_1x && !hapd->conf->ieee802_1x) {
 		wpa_printf(MSG_DEBUG, "IEEE 802.1X: Ignore STA - "
 			   "802.1X not enabled or forced for WPS");
+		/*
+		 * Clear any possible EAPOL authenticator state to support
+		 * reassociation change from WPS to PSK.
+		 */
+		ieee802_1x_free_station(sta);
 		return;
 	}
 
 	key_mgmt = wpa_auth_sta_key_mgmt(sta->wpa_sm);
 	if (key_mgmt != -1 && wpa_key_mgmt_wpa_psk(key_mgmt)) {
 		wpa_printf(MSG_DEBUG, "IEEE 802.1X: Ignore STA - using PSK");
+		/*
+		 * Clear any possible EAPOL authenticator state to support
+		 * reassociation change from WPA-EAP to PSK.
+		 */
+		ieee802_1x_free_station(sta);
 		return;
 	}
 
@@ -940,6 +929,7 @@
 		sta->eapol_sm->auth_pae_state = AUTH_PAE_AUTHENTICATING;
 		sta->eapol_sm->be_auth_state = BE_AUTH_SUCCESS;
 		sta->eapol_sm->authSuccess = TRUE;
+		sta->eapol_sm->authFail = FALSE;
 		if (sta->eapol_sm->eap)
 			eap_sm_notify_cached(sta->eapol_sm->eap);
 		/* TODO: get vlan_id from R0KH using RRB message */
@@ -961,6 +951,7 @@
 		sta->eapol_sm->auth_pae_state = AUTH_PAE_AUTHENTICATING;
 		sta->eapol_sm->be_auth_state = BE_AUTH_SUCCESS;
 		sta->eapol_sm->authSuccess = TRUE;
+		sta->eapol_sm->authFail = FALSE;
 		if (sta->eapol_sm->eap)
 			eap_sm_notify_cached(sta->eapol_sm->eap);
 		old_vlanid = sta->vlan_id;

Modified: wpa/trunk/src/ap/sta_info.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/ap/sta_info.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/ap/sta_info.c (original)
+++ wpa/trunk/src/ap/sta_info.c Tue Apr 17 11:03:56 2012
@@ -357,6 +357,7 @@
 				       hapd, sta);
 		break;
 	case STA_DISASSOC:
+		ap_sta_set_authorized(hapd, sta, 0);
 		sta->flags &= ~WLAN_STA_ASSOC;
 		ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
 		if (!sta->acct_terminate_cause)
@@ -384,9 +385,6 @@
 		mlme_deauthenticate_indication(
 			hapd, sta,
 			WLAN_REASON_PREV_AUTH_NOT_VALID);
-
-		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR,
-			MAC2STR(sta->addr));
 		ap_free_sta(hapd, sta);
 		break;
 	}
@@ -779,17 +777,58 @@
 void ap_sta_set_authorized(struct hostapd_data *hapd, struct sta_info *sta,
 			   int authorized)
 {
+	const u8 *dev_addr = NULL;
 	if (!!authorized == !!(sta->flags & WLAN_STA_AUTHORIZED))
 		return;
 
-	if (authorized)
+#ifdef CONFIG_P2P
+	dev_addr = p2p_group_get_dev_addr(hapd->p2p_group, sta->addr);
+#endif /* CONFIG_P2P */
+
+	if (authorized) {
+		if (dev_addr)
+			wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED
+				MACSTR " p2p_dev_addr=" MACSTR,
+				MAC2STR(sta->addr), MAC2STR(dev_addr));
+		else
+			wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED
+				MACSTR, MAC2STR(sta->addr));
+		if (hapd->msg_ctx_parent &&
+		    hapd->msg_ctx_parent != hapd->msg_ctx && dev_addr)
+			wpa_msg(hapd->msg_ctx_parent, MSG_INFO,
+				AP_STA_CONNECTED MACSTR " p2p_dev_addr="
+				MACSTR,
+				MAC2STR(sta->addr), MAC2STR(dev_addr));
+		else if (hapd->msg_ctx_parent &&
+			 hapd->msg_ctx_parent != hapd->msg_ctx)
+			wpa_msg(hapd->msg_ctx_parent, MSG_INFO,
+				AP_STA_CONNECTED MACSTR, MAC2STR(sta->addr));
+
 		sta->flags |= WLAN_STA_AUTHORIZED;
-	else
+	} else {
+		if (dev_addr)
+			wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED
+				MACSTR " p2p_dev_addr=" MACSTR,
+				MAC2STR(sta->addr), MAC2STR(dev_addr));
+		else
+			wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED
+				MACSTR, MAC2STR(sta->addr));
+		if (hapd->msg_ctx_parent &&
+		    hapd->msg_ctx_parent != hapd->msg_ctx && dev_addr)
+			wpa_msg(hapd->msg_ctx_parent, MSG_INFO,
+				AP_STA_DISCONNECTED MACSTR " p2p_dev_addr="
+				MACSTR, MAC2STR(sta->addr), MAC2STR(dev_addr));
+		else if (hapd->msg_ctx_parent &&
+			 hapd->msg_ctx_parent != hapd->msg_ctx)
+			wpa_msg(hapd->msg_ctx_parent, MSG_INFO,
+				AP_STA_DISCONNECTED MACSTR,
+				MAC2STR(sta->addr));
 		sta->flags &= ~WLAN_STA_AUTHORIZED;
+	}
 
 	if (hapd->sta_authorized_cb)
 		hapd->sta_authorized_cb(hapd->sta_authorized_cb_ctx,
-					sta->addr, authorized);
+					sta->addr, authorized, dev_addr);
 }
 
 
@@ -806,6 +845,8 @@
 	if (sta == NULL)
 		return;
 	ap_sta_set_authorized(hapd, sta, 0);
+	wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
+	ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
 	sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
 	eloop_cancel_timeout(ap_handle_timer, hapd, sta);
 	eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DEAUTH, 0,

Modified: wpa/trunk/src/ap/wps_hostapd.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/ap/wps_hostapd.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/ap/wps_hostapd.c (original)
+++ wpa/trunk/src/ap/wps_hostapd.c Tue Apr 17 11:03:56 2012
@@ -512,6 +512,8 @@
 
 	if (hapd->conf->ap_setup_locked)
 		return;
+	if (hapd->ap_pin_failures_consecutive >= 10)
+		return;
 
 	wpa_printf(MSG_DEBUG, "WPS: Re-enable AP PIN");
 	wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_UNLOCKED);
@@ -533,8 +535,10 @@
 	 * force attacks.
 	 */
 	hapd->ap_pin_failures++;
-	wpa_printf(MSG_DEBUG, "WPS: AP PIN authentication failure number %u",
-		   hapd->ap_pin_failures);
+	hapd->ap_pin_failures_consecutive++;
+	wpa_printf(MSG_DEBUG, "WPS: AP PIN authentication failure number %u "
+		   "(%u consecutive)",
+		   hapd->ap_pin_failures, hapd->ap_pin_failures_consecutive);
 	if (hapd->ap_pin_failures < 3)
 		return 0;
 
@@ -543,7 +547,15 @@
 
 	wps_registrar_update_ie(hapd->wps->registrar);
 
-	if (!hapd->conf->ap_setup_locked) {
+	if (!hapd->conf->ap_setup_locked &&
+	    hapd->ap_pin_failures_consecutive >= 10) {
+		/*
+		 * In indefinite lockdown - disable automatic AP PIN
+		 * reenablement.
+		 */
+		eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL);
+		wpa_printf(MSG_DEBUG, "WPS: AP PIN disabled indefinitely");
+	} else if (!hapd->conf->ap_setup_locked) {
 		if (hapd->ap_pin_lockout_time == 0)
 			hapd->ap_pin_lockout_time = 60;
 		else if (hapd->ap_pin_lockout_time < 365 * 24 * 60 * 60 &&
@@ -566,6 +578,29 @@
 				  struct wps_event_pwd_auth_fail *data)
 {
 	hostapd_wps_for_each(hapd, wps_pwd_auth_fail, data);
+}
+
+
+static int wps_ap_pin_success(struct hostapd_data *hapd, void *ctx)
+{
+	if (hapd->conf->ap_pin == NULL || hapd->wps == NULL)
+		return 0;
+
+	if (hapd->ap_pin_failures_consecutive == 0)
+		return 0;
+
+	wpa_printf(MSG_DEBUG, "WPS: Clear consecutive AP PIN failure counter "
+		   "- total validation failures %u (%u consecutive)",
+		   hapd->ap_pin_failures, hapd->ap_pin_failures_consecutive);
+	hapd->ap_pin_failures_consecutive = 0;
+
+	return 0;
+}
+
+
+static void hostapd_wps_ap_pin_success(struct hostapd_data *hapd)
+{
+	hostapd_wps_for_each(hapd, wps_ap_pin_success, NULL);
 }
 
 
@@ -628,6 +663,9 @@
 		break;
 	case WPS_EV_ER_SET_SELECTED_REGISTRAR:
 		break;
+	case WPS_EV_AP_PIN_SUCCESS:
+		hostapd_wps_ap_pin_success(hapd);
+		break;
 	}
 	if (hapd->wps_event_cb)
 		hapd->wps_event_cb(hapd->wps_event_cb_ctx, event, data);
@@ -1287,6 +1325,7 @@
 {
 	wpa_printf(MSG_DEBUG, "WPS: Enabling AP PIN (timeout=%d)", timeout);
 	hapd->ap_pin_failures = 0;
+	hapd->ap_pin_failures_consecutive = 0;
 	hapd->conf->ap_setup_locked = 0;
 	if (hapd->wps->ap_setup_locked) {
 		wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_UNLOCKED);

Modified: wpa/trunk/src/common/version.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/common/version.h?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/common/version.h (original)
+++ wpa/trunk/src/common/version.h Tue Apr 17 11:03:56 2012
@@ -5,6 +5,6 @@
 #define VERSION_STR_POSTFIX ""
 #endif /* VERSION_STR_POSTFIX */
 
-#define VERSION_STR "1.0-rc2" VERSION_STR_POSTFIX
+#define VERSION_STR "1.0-rc3" VERSION_STR_POSTFIX
 
 #endif /* VERSION_H */

Modified: wpa/trunk/src/drivers/driver.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/drivers/driver.h?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/drivers/driver.h (original)
+++ wpa/trunk/src/drivers/driver.h Tue Apr 17 11:03:56 2012
@@ -1958,6 +1958,16 @@
 	int (*deinit_ap)(void *priv);
 
 	/**
+	 * deinit_p2p_cli - Deinitialize P2P client mode
+	 * @priv: Private driver interface data
+	 * Returns: 0 on success, -1 on failure (or if not supported)
+	 *
+	 * This optional function can be used to disable P2P client mode. It
+	 * can be used to change the interface type back to station mode.
+	 */
+	int (*deinit_p2p_cli)(void *priv);
+
+	/**
 	 * suspend - Notification on system suspend/hibernate event
 	 * @priv: Private driver interface data
 	 */

Modified: wpa/trunk/src/drivers/driver_nl80211.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/drivers/driver_nl80211.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/drivers/driver_nl80211.c (original)
+++ wpa/trunk/src/drivers/driver_nl80211.c Tue Apr 17 11:03:56 2012
@@ -516,10 +516,28 @@
 		   del ? "removed" : "added");
 
 	if (os_strcmp(drv->first_bss.ifname, event.interface_status.ifname) == 0) {
-		if (del)
+		if (del) {
+			if (drv->if_removed) {
+				wpa_printf(MSG_DEBUG, "nl80211: if_removed "
+					   "already set - ignore event");
+				return;
+			}
 			drv->if_removed = 1;
-		else
+		} else {
+			if (if_nametoindex(drv->first_bss.ifname) == 0) {
+				wpa_printf(MSG_DEBUG, "nl80211: Interface %s "
+					   "does not exist - ignore "
+					   "RTM_NEWLINK",
+					   drv->first_bss.ifname);
+				return;
+			}
+			if (!drv->if_removed) {
+				wpa_printf(MSG_DEBUG, "nl80211: if_removed "
+					   "already cleared - ignore event");
+				return;
+			}
 			drv->if_removed = 0;
+		}
 	}
 
 	wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
@@ -636,6 +654,14 @@
 			wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
 				   "event since interface %s is down",
 				   namebuf);
+		} else if (if_nametoindex(drv->first_bss.ifname) == 0) {
+			wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
+				   "event since interface %s does not exist",
+				   drv->first_bss.ifname);
+		} else if (drv->if_removed) {
+			wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
+				   "event since interface %s is marked "
+				   "removed", drv->first_bss.ifname);
 		} else {
 			wpa_printf(MSG_DEBUG, "nl80211: Interface up");
 			drv->if_disabled = 0;
@@ -2465,7 +2491,7 @@
 #ifdef CONFIG_TDLS
 	if ((drv->capa.flags & WPA_DRIVER_FLAGS_TDLS_SUPPORT)) {
 		/* TDLS Discovery Response */
-		if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0e", 2) <
+		if (nl80211_register_action_frame(drv, (u8 *) "\x04\x0e", 2) <
 		    0)
 			return -1;
 	}
@@ -7214,6 +7240,16 @@
 	if (!is_ap_interface(drv->nlmode))
 		return -1;
 	wpa_driver_nl80211_del_beacon(drv);
+	return wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_STATION);
+}
+
+
+static int wpa_driver_nl80211_deinit_p2p_cli(void *priv)
+{
+	struct i802_bss *bss = priv;
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	if (drv->nlmode != NL80211_IFTYPE_P2P_CLIENT)
+		return -1;
 	return wpa_driver_nl80211_set_mode(priv, NL80211_IFTYPE_STATION);
 }
 
@@ -7707,6 +7743,7 @@
 	wpa_driver_nl80211_cancel_remain_on_channel,
 	.probe_req_report = wpa_driver_nl80211_probe_req_report,
 	.deinit_ap = wpa_driver_nl80211_deinit_ap,
+	.deinit_p2p_cli = wpa_driver_nl80211_deinit_p2p_cli,
 	.resume = wpa_driver_nl80211_resume,
 	.send_ft_action = nl80211_send_ft_action,
 	.signal_monitor = nl80211_signal_monitor,

Modified: wpa/trunk/src/drivers/driver_wext.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/drivers/driver_wext.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/drivers/driver_wext.c (original)
+++ wpa/trunk/src/drivers/driver_wext.c Tue Apr 17 11:03:56 2012
@@ -564,10 +564,28 @@
 		   del ? "removed" : "added");
 
 	if (os_strcmp(drv->ifname, event.interface_status.ifname) == 0) {
-		if (del)
+		if (del) {
+			if (drv->if_removed) {
+				wpa_printf(MSG_DEBUG, "WEXT: if_removed "
+					   "already set - ignore event");
+				return;
+			}
 			drv->if_removed = 1;
-		else
+		} else {
+			if (if_nametoindex(drv->ifname) == 0) {
+				wpa_printf(MSG_DEBUG, "WEXT: Interface %s "
+					   "does not exist - ignore "
+					   "RTM_NEWLINK",
+					   drv->ifname);
+				return;
+			}
+			if (!drv->if_removed) {
+				wpa_printf(MSG_DEBUG, "WEXT: if_removed "
+					   "already cleared - ignore event");
+				return;
+			}
 			drv->if_removed = 0;
+		}
 	}
 
 	wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
@@ -623,6 +641,7 @@
 	struct wpa_driver_wext_data *drv = ctx;
 	int attrlen, rta_len;
 	struct rtattr *attr;
+	char namebuf[IFNAMSIZ];
 
 	if (!wpa_driver_wext_own_ifindex(drv, ifi->ifi_index, buf, len)) {
 		wpa_printf(MSG_DEBUG, "Ignore event for foreign ifindex %d",
@@ -645,9 +664,25 @@
 	}
 
 	if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) {
-		wpa_printf(MSG_DEBUG, "WEXT: Interface up");
-		drv->if_disabled = 0;
-		wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED, NULL);
+		if (if_indextoname(ifi->ifi_index, namebuf) &&
+		    linux_iface_up(drv->ioctl_sock, drv->ifname) == 0) {
+			wpa_printf(MSG_DEBUG, "WEXT: Ignore interface up "
+				   "event since interface %s is down",
+				   namebuf);
+		} else if (if_nametoindex(drv->ifname) == 0) {
+			wpa_printf(MSG_DEBUG, "WEXT: Ignore interface up "
+				   "event since interface %s does not exist",
+				   drv->ifname);
+		} else if (drv->if_removed) {
+			wpa_printf(MSG_DEBUG, "WEXT: Ignore interface up "
+				   "event since interface %s is marked "
+				   "removed", drv->ifname);
+		} else {
+			wpa_printf(MSG_DEBUG, "WEXT: Interface up");
+			drv->if_disabled = 0;
+			wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
+					     NULL);
+		}
 	}
 
 	/*

Modified: wpa/trunk/src/drivers/nl80211_copy.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/drivers/nl80211_copy.h?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/drivers/nl80211_copy.h (original)
+++ wpa/trunk/src/drivers/nl80211_copy.h Tue Apr 17 11:03:56 2012
@@ -156,21 +156,23 @@
  * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX
  *	or %NL80211_ATTR_MAC.
  *
- * @NL80211_CMD_GET_BEACON: retrieve beacon information (returned in a
- *	%NL80222_CMD_NEW_BEACON message)
- * @NL80211_CMD_SET_BEACON: set the beacon on an access point interface
- *	using the %NL80211_ATTR_BEACON_INTERVAL, %NL80211_ATTR_DTIM_PERIOD,
- *	%NL80211_ATTR_BEACON_HEAD and %NL80211_ATTR_BEACON_TAIL attributes.
- *	Following attributes are provided for drivers that generate full Beacon
- *	and Probe Response frames internally: %NL80211_ATTR_SSID,
+ * @NL80211_CMD_GET_BEACON: (not used)
+ * @NL80211_CMD_SET_BEACON: change the beacon on an access point interface
+ *	using the %NL80211_ATTR_BEACON_HEAD and %NL80211_ATTR_BEACON_TAIL
+ *	attributes. For drivers that generate the beacon and probe responses
+ *	internally, the following attributes must be provided: %NL80211_ATTR_IE,
+ *	%NL80211_ATTR_IE_PROBE_RESP and %NL80211_ATTR_IE_ASSOC_RESP.
+ * @NL80211_CMD_START_AP: Start AP operation on an AP interface, parameters
+ *	are like for %NL80211_CMD_SET_BEACON, and additionally parameters that
+ *	do not change are used, these include %NL80211_ATTR_BEACON_INTERVAL,
+ *	%NL80211_ATTR_DTIM_PERIOD, %NL80211_ATTR_SSID,
  *	%NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHERS_PAIRWISE,
  *	%NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS,
  *	%NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY,
- *	%NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_IE, %NL80211_ATTR_IE_PROBE_RESP,
- *	%NL80211_ATTR_IE_ASSOC_RESP.
- * @NL80211_CMD_NEW_BEACON: add a new beacon to an access point interface,
- *	parameters are like for %NL80211_CMD_SET_BEACON.
- * @NL80211_CMD_DEL_BEACON: remove the beacon, stop sending it
+ *	%NL80211_ATTR_AUTH_TYPE and %NL80211_ATTR_INACTIVITY_TIMEOUT.
+ * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP
+ * @NL80211_CMD_STOP_AP: Stop AP operation on the given interface
+ * @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP
  *
  * @NL80211_CMD_GET_STATION: Get station attributes for station identified by
  *	%NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX.
@@ -367,6 +369,11 @@
  *	%NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT,
  *	%NL80211_ATTR_CONTROL_PORT_ETHERTYPE and
  *	%NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT.
+ *	Background scan period can optionally be
+ *	specified in %NL80211_ATTR_BG_SCAN_PERIOD,
+ *	if not specified default background scan configuration
+ *	in driver is used and if period value is 0, bg scan will be disabled.
+ *	This attribute is ignored if driver does not support roam scan.
  *	It is also sent as an event, with the BSSID and response IEs when the
  *	connection is established or failed to be established. This can be
  *	determined by the STATUS_CODE attribute.
@@ -533,8 +540,10 @@
 
 	NL80211_CMD_GET_BEACON,
 	NL80211_CMD_SET_BEACON,
-	NL80211_CMD_NEW_BEACON,
-	NL80211_CMD_DEL_BEACON,
+	NL80211_CMD_START_AP,
+	NL80211_CMD_NEW_BEACON = NL80211_CMD_START_AP,
+	NL80211_CMD_STOP_AP,
+	NL80211_CMD_DEL_BEACON = NL80211_CMD_STOP_AP,
 
 	NL80211_CMD_GET_STATION,
 	NL80211_CMD_SET_STATION,
@@ -1109,6 +1118,59 @@
  *	%NL80211_CMD_TDLS_MGMT. Otherwise %NL80211_CMD_TDLS_OPER should be
  *	used for asking the driver to perform a TDLS operation.
  *
+ * @NL80211_ATTR_DEVICE_AP_SME: This u32 attribute may be listed for devices
+ *	that have AP support to indicate that they have the AP SME integrated
+ *	with support for the features listed in this attribute, see
+ *	&enum nl80211_ap_sme_features.
+ *
+ * @NL80211_ATTR_DONT_WAIT_FOR_ACK: Used with %NL80211_CMD_FRAME, this tells
+ *	the driver to not wait for an acknowledgement. Note that due to this,
+ *	it will also not give a status callback nor return a cookie. This is
+ *	mostly useful for probe responses to save airtime.
+ *
+ * @NL80211_ATTR_FEATURE_FLAGS: This u32 attribute contains flags from
+ *	&enum nl80211_feature_flags and is advertised in wiphy information.
+ * @NL80211_ATTR_PROBE_RESP_OFFLOAD: Indicates that the HW responds to probe
+ *
+ *	requests while operating in AP-mode.
+ *	This attribute holds a bitmap of the supported protocols for
+ *	offloading (see &enum nl80211_probe_resp_offload_support_attr).
+ *
+ * @NL80211_ATTR_PROBE_RESP: Probe Response template data. Contains the entire
+ *	probe-response frame. The DA field in the 802.11 header is zero-ed out,
+ *	to be filled by the FW.
+ * @NL80211_ATTR_DISABLE_HT:  Force HT capable interfaces to disable
+ *      this feature.  Currently, only supported in mac80211 drivers.
+ * @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the
+ *      ATTR_HT_CAPABILITY to which attention should be paid.
+ *      Currently, only mac80211 NICs support this feature.
+ *      The values that may be configured are:
+ *       MCS rates, MAX-AMSDU, HT-20-40 and HT_CAP_SGI_40
+ *       AMPDU density and AMPDU factor.
+ *      All values are treated as suggestions and may be ignored
+ *      by the driver as required.  The actual values may be seen in
+ *      the station debugfs ht_caps file.
+ *
+ * @NL80211_ATTR_DFS_REGION: region for regulatory rules which this country
+ *    abides to when initiating radiation on DFS channels. A country maps
+ *    to one DFS region.
+ *
+ * @NL80211_ATTR_NOACK_MAP: This u16 bitmap contains the No Ack Policy of
+ *      up to 16 TIDs.
+ *
+ * @NL80211_ATTR_INACTIVITY_TIMEOUT: timeout value in seconds, this can be
+ *	used by the drivers which has MLME in firmware and does not have support
+ *	to report per station tx/rx activity to free up the staion entry from
+ *	the list. This needs to be used when the driver advertises the
+ *	capability to timeout the stations.
+ *
+ * @NL80211_ATTR_RX_SIGNAL_DBM: signal strength in dBm (as a 32-bit int);
+ *	this attribute is (depending on the driver capabilities) added to
+ *	received frames indicated with %NL80211_CMD_FRAME.
+ *
+ * @NL80211_ATTR_BG_SCAN_PERIOD: Background scan period in seconds
+ *      or 0 to disable background scan.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1336,6 +1398,29 @@
 	NL80211_ATTR_TDLS_OPERATION,
 	NL80211_ATTR_TDLS_SUPPORT,
 	NL80211_ATTR_TDLS_EXTERNAL_SETUP,
+
+	NL80211_ATTR_DEVICE_AP_SME,
+
+	NL80211_ATTR_DONT_WAIT_FOR_ACK,
+
+	NL80211_ATTR_FEATURE_FLAGS,
+
+	NL80211_ATTR_PROBE_RESP_OFFLOAD,
+
+	NL80211_ATTR_PROBE_RESP,
+
+	NL80211_ATTR_DFS_REGION,
+
+	NL80211_ATTR_DISABLE_HT,
+	NL80211_ATTR_HT_CAPABILITY_MASK,
+
+	NL80211_ATTR_NOACK_MAP,
+
+	NL80211_ATTR_INACTIVITY_TIMEOUT,
+
+	NL80211_ATTR_RX_SIGNAL_DBM,
+
+	NL80211_ATTR_BG_SCAN_PERIOD,
 
 	/* add attributes here, update the policy in nl80211.c */
 
@@ -1373,6 +1458,7 @@
 #define NL80211_ATTR_KEYS NL80211_ATTR_KEYS
 
 #define NL80211_MAX_SUPP_RATES			32
+#define NL80211_MAX_SUPP_HT_RATES		77
 #define NL80211_MAX_SUPP_REG_RULES		32
 #define NL80211_TKIP_DATA_OFFSET_ENCR_KEY	0
 #define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY	16
@@ -1975,6 +2061,17 @@
  * access to a broader network beyond the MBSS.  This is done via Root
  * Announcement frames.
  *
+ * @NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL: The minimum interval of time (in
+ * TUs) during which a mesh STA can send only one Action frame containing a
+ * PERR element.
+ *
+ * @NL80211_MESHCONF_FORWARDING: set Mesh STA as forwarding or non-forwarding
+ * or forwarding entity (default is TRUE - forwarding entity)
+ *
+ * @NL80211_MESHCONF_RSSI_THRESHOLD: RSSI threshold in dBm. This specifies the
+ * threshold for average signal strength of candidate station to establish
+ * a peer link.
+ *
  * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
  *
  * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
@@ -1998,6 +2095,9 @@
 	NL80211_MESHCONF_ELEMENT_TTL,
 	NL80211_MESHCONF_HWMP_RANN_INTERVAL,
 	NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
+	NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
+	NL80211_MESHCONF_FORWARDING,
+	NL80211_MESHCONF_RSSI_THRESHOLD,
 
 	/* keep last */
 	__NL80211_MESHCONF_ATTR_AFTER_LAST,
@@ -2271,12 +2371,15 @@
  *	in an array of rates as defined in IEEE 802.11 7.3.2.2 (u8 values with
  *	1 = 500 kbps) but without the IE length restriction (at most
  *	%NL80211_MAX_SUPP_RATES in a single array).
+ * @NL80211_TXRATE_MCS: HT (MCS) rates allowed for TX rate selection
+ *	in an array of MCS numbers.
  * @__NL80211_TXRATE_AFTER_LAST: internal
  * @NL80211_TXRATE_MAX: highest TX rate attribute
  */
 enum nl80211_tx_rate_attributes {
 	__NL80211_TXRATE_INVALID,
 	NL80211_TXRATE_LEGACY,
+	NL80211_TXRATE_MCS,
 
 	/* keep last */
 	__NL80211_TXRATE_AFTER_LAST,
@@ -2648,4 +2751,48 @@
 	NL80211_TDLS_DISABLE_LINK,
 };
 
+/*
+ * enum nl80211_ap_sme_features - device-integrated AP features
+ * Reserved for future use, no bits are defined in
+ * NL80211_ATTR_DEVICE_AP_SME yet.
+enum nl80211_ap_sme_features {
+};
+ */
+
+/**
+ * enum nl80211_feature_flags - device/driver features
+ * @NL80211_FEATURE_SK_TX_STATUS: This driver supports reflecting back
+ *	TX status to the socket error queue when requested with the
+ *	socket option.
+ * @NL80211_FEATURE_HT_IBSS: This driver supports IBSS with HT datarates.
+ * @NL80211_FEATURE_INACTIVITY_TIMER: This driver takes care of freeing up
+ *	the connected inactive stations in AP mode.
+ */
+enum nl80211_feature_flags {
+	NL80211_FEATURE_SK_TX_STATUS	= 1 << 0,
+	NL80211_FEATURE_HT_IBSS		= 1 << 1,
+	NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2,
+};
+
+/**
+ * enum nl80211_probe_resp_offload_support_attr - optional supported
+ *	protocols for probe-response offloading by the driver/FW.
+ *	To be used with the %NL80211_ATTR_PROBE_RESP_OFFLOAD attribute.
+ *	Each enum value represents a bit in the bitmap of supported
+ *	protocols. Typically a subset of probe-requests belonging to a
+ *	supported protocol will be excluded from offload and uploaded
+ *	to the host.
+ *
+ * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS: Support for WPS ver. 1
+ * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2: Support for WPS ver. 2
+ * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P: Support for P2P
+ * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U: Support for 802.11u
+ */
+enum nl80211_probe_resp_offload_support_attr {
+	NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS =	1<<0,
+	NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 =	1<<1,
+	NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P =	1<<2,
+	NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U =	1<<3,
+};
+
 #endif /* __LINUX_NL80211_H */

Modified: wpa/trunk/src/eap_peer/eap_aka.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/eap_peer/eap_aka.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/eap_peer/eap_aka.c (original)
+++ wpa/trunk/src/eap_peer/eap_aka.c Tue Apr 17 11:03:56 2012
@@ -235,19 +235,19 @@
 
 static void eap_aka_clear_identities(struct eap_aka_data *data, int id)
 {
-	if (id & CLEAR_PSEUDONYM) {
+	if ((id & CLEAR_PSEUDONYM) && data->pseudonym) {
 		wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old pseudonym");
 		os_free(data->pseudonym);
 		data->pseudonym = NULL;
 		data->pseudonym_len = 0;
 	}
-	if (id & CLEAR_REAUTH_ID) {
+	if ((id & CLEAR_REAUTH_ID) && data->reauth_id) {
 		wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old reauth_id");
 		os_free(data->reauth_id);
 		data->reauth_id = NULL;
 		data->reauth_id_len = 0;
 	}
-	if (id & CLEAR_EAP_ID) {
+	if ((id & CLEAR_EAP_ID) && data->last_eap_identity) {
 		wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old eap_id");
 		os_free(data->last_eap_identity);
 		data->last_eap_identity = NULL;
@@ -256,24 +256,44 @@
 }
 
 
-static int eap_aka_learn_ids(struct eap_aka_data *data,
+static int eap_aka_learn_ids(struct eap_sm *sm, struct eap_aka_data *data,
 			     struct eap_sim_attrs *attr)
 {
 	if (attr->next_pseudonym) {
+		const u8 *identity = NULL;
+		size_t identity_len = 0;
+		const u8 *realm = NULL;
+		size_t realm_len = 0;
+
+		wpa_hexdump_ascii(MSG_DEBUG,
+				  "EAP-AKA: (encr) AT_NEXT_PSEUDONYM",
+				  attr->next_pseudonym,
+				  attr->next_pseudonym_len);
 		os_free(data->pseudonym);
-		data->pseudonym = os_malloc(attr->next_pseudonym_len);
+		/* Look for the realm of the permanent identity */
+		identity = eap_get_config_identity(sm, &identity_len);
+		if (identity) {
+			for (realm = identity, realm_len = identity_len;
+			     realm_len > 0; realm_len--, realm++) {
+				if (*realm == '@')
+					break;
+			}
+		}
+		data->pseudonym = os_malloc(attr->next_pseudonym_len +
+					    realm_len);
 		if (data->pseudonym == NULL) {
 			wpa_printf(MSG_INFO, "EAP-AKA: (encr) No memory for "
 				   "next pseudonym");
+			data->pseudonym_len = 0;
 			return -1;
 		}
 		os_memcpy(data->pseudonym, attr->next_pseudonym,
 			  attr->next_pseudonym_len);
-		data->pseudonym_len = attr->next_pseudonym_len;
-		wpa_hexdump_ascii(MSG_DEBUG,
-				  "EAP-AKA: (encr) AT_NEXT_PSEUDONYM",
-				  data->pseudonym,
-				  data->pseudonym_len);
+		if (realm_len) {
+			os_memcpy(data->pseudonym + attr->next_pseudonym_len,
+				  realm, realm_len);
+		}
+		data->pseudonym_len = attr->next_pseudonym_len + realm_len;
 	}
 
 	if (attr->next_reauth_id) {
@@ -282,6 +302,7 @@
 		if (data->reauth_id == NULL) {
 			wpa_printf(MSG_INFO, "EAP-AKA: (encr) No memory for "
 				   "next reauth_id");
+			data->reauth_id_len = 0;
 			return -1;
 		}
 		os_memcpy(data->reauth_id, attr->next_reauth_id,
@@ -894,7 +915,7 @@
 			return eap_aka_client_error(
 				data, id, EAP_AKA_UNABLE_TO_PROCESS_PACKET);
 		}
-		eap_aka_learn_ids(data, &eattr);
+		eap_aka_learn_ids(sm, data, &eattr);
 		os_free(decrypted);
 	}
 
@@ -1112,7 +1133,7 @@
 					   data->msk, data->emsk);
 	}
 	eap_aka_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
-	eap_aka_learn_ids(data, &eattr);
+	eap_aka_learn_ids(sm, data, &eattr);
 
 	if (data->result_ind && attr->result_ind)
 		data->use_result_ind = 1;

Modified: wpa/trunk/src/eap_peer/eap_sim.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/eap_peer/eap_sim.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/eap_peer/eap_sim.c (original)
+++ wpa/trunk/src/eap_peer/eap_sim.c Tue Apr 17 11:03:56 2012
@@ -287,24 +287,44 @@
 }
 
 
-static int eap_sim_learn_ids(struct eap_sim_data *data,
+static int eap_sim_learn_ids(struct eap_sm *sm, struct eap_sim_data *data,
 			     struct eap_sim_attrs *attr)
 {
 	if (attr->next_pseudonym) {
+		const u8 *identity = NULL;
+		size_t identity_len = 0;
+		const u8 *realm = NULL;
+		size_t realm_len = 0;
+
+		wpa_hexdump_ascii(MSG_DEBUG,
+				  "EAP-SIM: (encr) AT_NEXT_PSEUDONYM",
+				  attr->next_pseudonym,
+				  attr->next_pseudonym_len);
 		os_free(data->pseudonym);
-		data->pseudonym = os_malloc(attr->next_pseudonym_len);
+		/* Look for the realm of the permanent identity */
+		identity = eap_get_config_identity(sm, &identity_len);
+		if (identity) {
+			for (realm = identity, realm_len = identity_len;
+			     realm_len > 0; realm_len--, realm++) {
+				if (*realm == '@')
+					break;
+			}
+		}
+		data->pseudonym = os_malloc(attr->next_pseudonym_len +
+					    realm_len);
 		if (data->pseudonym == NULL) {
 			wpa_printf(MSG_INFO, "EAP-SIM: (encr) No memory for "
 				   "next pseudonym");
+			data->pseudonym_len = 0;
 			return -1;
 		}
 		os_memcpy(data->pseudonym, attr->next_pseudonym,
 			  attr->next_pseudonym_len);
-		data->pseudonym_len = attr->next_pseudonym_len;
-		wpa_hexdump_ascii(MSG_DEBUG,
-				  "EAP-SIM: (encr) AT_NEXT_PSEUDONYM",
-				  data->pseudonym,
-				  data->pseudonym_len);
+		if (realm_len) {
+			os_memcpy(data->pseudonym + attr->next_pseudonym_len,
+				  realm, realm_len);
+		}
+		data->pseudonym_len = attr->next_pseudonym_len + realm_len;
 	}
 
 	if (attr->next_reauth_id) {
@@ -313,6 +333,7 @@
 		if (data->reauth_id == NULL) {
 			wpa_printf(MSG_INFO, "EAP-SIM: (encr) No memory for "
 				   "next reauth_id");
+			data->reauth_id_len = 0;
 			return -1;
 		}
 		os_memcpy(data->reauth_id, attr->next_reauth_id,
@@ -663,7 +684,7 @@
 			return eap_sim_client_error(
 				data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET);
 		}
-		eap_sim_learn_ids(data, &eattr);
+		eap_sim_learn_ids(sm, data, &eattr);
 		os_free(decrypted);
 	}
 
@@ -861,7 +882,7 @@
 				   data->nonce_s, data->mk, data->msk,
 				   data->emsk);
 	eap_sim_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
-	eap_sim_learn_ids(data, &eattr);
+	eap_sim_learn_ids(sm, data, &eattr);
 
 	if (data->result_ind && attr->result_ind)
 		data->use_result_ind = 1;

Modified: wpa/trunk/src/eap_peer/eap_ttls.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/eap_peer/eap_ttls.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/eap_peer/eap_ttls.c (original)
+++ wpa/trunk/src/eap_peer/eap_ttls.c Tue Apr 17 11:03:56 2012
@@ -441,7 +441,6 @@
 			   "implicit challenge");
 		return -1;
 	}
-	peer_challenge = challenge + 1 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN;
 
 	pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_MS_CHAP_CHALLENGE,
 			       RADIUS_VENDOR_ID_MICROSOFT, 1,
@@ -454,7 +453,14 @@
 	data->ident = challenge[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN];
 	*pos++ = data->ident;
 	*pos++ = 0; /* Flags */
-	os_memcpy(pos, peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
+	if (os_get_random(pos, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) < 0) {
+		os_free(challenge);
+		wpabuf_free(msg);
+		wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to get "
+			   "random data for peer challenge");
+		return -1;
+	}
+	peer_challenge = pos;
 	pos += EAP_TTLS_MSCHAPV2_CHALLENGE_LEN;
 	os_memset(pos, 0, 8); /* Reserved, must be zero */
 	pos += 8;
@@ -462,6 +468,7 @@
 				     password_len, pwhash, challenge,
 				     peer_challenge, pos, data->auth_response,
 				     data->master_key)) {
+		os_free(challenge);
 		wpabuf_free(msg);
 		wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to derive "
 			   "response");

Modified: wpa/trunk/src/eap_server/eap_server_aka.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/eap_server/eap_server_aka.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/eap_server/eap_server_aka.c (original)
+++ wpa/trunk/src/eap_server/eap_server_aka.c Tue Apr 17 11:03:56 2012
@@ -298,8 +298,13 @@
 			      const u8 *nonce_s)
 {
 	os_free(data->next_pseudonym);
-	data->next_pseudonym =
-		eap_sim_db_get_next_pseudonym(sm->eap_sim_db_priv, 1);
+	if (nonce_s == NULL) {
+		data->next_pseudonym =
+			eap_sim_db_get_next_pseudonym(sm->eap_sim_db_priv, 1);
+	} else {
+		/* Do not update pseudonym during re-authentication */
+		data->next_pseudonym = NULL;
+	}
 	os_free(data->next_reauth_id);
 	if (data->counter <= EAP_AKA_MAX_FAST_REAUTHS) {
 		data->next_reauth_id =
@@ -1023,11 +1028,6 @@
 		identity_len = id2_len;
 	}
 
-	if (data->next_pseudonym) {
-		eap_sim_db_add_pseudonym(sm->eap_sim_db_priv, identity,
-					 identity_len, data->next_pseudonym);
-		data->next_pseudonym = NULL;
-	}
 	if (data->next_reauth_id) {
 		if (data->eap_method == EAP_TYPE_AKA_PRIME) {
 #ifdef EAP_SERVER_AKA_PRIME

Modified: wpa/trunk/src/eap_server/eap_server_sim.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/eap_server/eap_server_sim.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/eap_server/eap_server_sim.c (original)
+++ wpa/trunk/src/eap_server/eap_server_sim.c Tue Apr 17 11:03:56 2012
@@ -137,8 +137,13 @@
 			      const u8 *nonce_s)
 {
 	os_free(data->next_pseudonym);
-	data->next_pseudonym =
-		eap_sim_db_get_next_pseudonym(sm->eap_sim_db_priv, 0);
+	if (nonce_s == NULL) {
+		data->next_pseudonym =
+			eap_sim_db_get_next_pseudonym(sm->eap_sim_db_priv, 0);
+	} else {
+		/* Do not update pseudonym during re-authentication */
+		data->next_pseudonym = NULL;
+	}
 	os_free(data->next_reauth_id);
 	if (data->counter <= EAP_SIM_MAX_FAST_REAUTHS) {
 		data->next_reauth_id =
@@ -622,11 +627,6 @@
 		identity_len = id2_len;
 	}
 
-	if (data->next_pseudonym) {
-		eap_sim_db_add_pseudonym(sm->eap_sim_db_priv, identity,
-					 identity_len, data->next_pseudonym);
-		data->next_pseudonym = NULL;
-	}
 	if (data->next_reauth_id) {
 		eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,
 				      identity_len, data->next_reauth_id,

Modified: wpa/trunk/src/p2p/p2p.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/p2p/p2p.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/p2p/p2p.c (original)
+++ wpa/trunk/src/p2p/p2p.c Tue Apr 17 11:03:56 2012
@@ -142,6 +142,34 @@
 }
 
 
+u16 p2p_get_provisioning_info(struct p2p_data *p2p, const u8 *addr)
+{
+	struct p2p_device *dev = NULL;
+
+	if (!addr || !p2p)
+		return 0;
+
+	dev = p2p_get_device(p2p, addr);
+	if (dev)
+		return dev->wps_prov_info;
+	else
+		return 0;
+}
+
+
+void p2p_clear_provisioning_info(struct p2p_data *p2p, const u8 *addr)
+{
+	struct p2p_device *dev = NULL;
+
+	if (!addr || !p2p)
+		return;
+
+	dev = p2p_get_device(p2p, addr);
+	if (dev)
+		dev->wps_prov_info = 0;
+}
+
+
 void p2p_set_state(struct p2p_data *p2p, int new_state)
 {
 	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: State %s -> %s",
@@ -796,7 +824,7 @@
 
 	if (p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, type, freq,
 			       p2p->num_req_dev_types, p2p->req_dev_types,
-			       p2p->find_dev_id) < 0) {
+			       p2p->find_dev_id)) {
 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
 			"P2P: Scan request failed");
 		p2p_continue_find(p2p);
@@ -1002,10 +1030,20 @@
 	p2p->go_neg_peer = NULL;
 	p2p->sd_peer = NULL;
 	p2p->invite_peer = NULL;
+	p2p_stop_listen_for_freq(p2p, freq);
+}
+
+
+void p2p_stop_listen_for_freq(struct p2p_data *p2p, int freq)
+{
 	if (freq > 0 && p2p->drv_in_listen == freq && p2p->in_listen) {
 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Skip stop_listen "
 			"since we are on correct channel for response");
 		return;
+	}
+	if (p2p->in_listen) {
+		p2p->in_listen = 0;
+		p2p_clear_timeout(p2p);
 	}
 	if (p2p->drv_in_listen) {
 		/*
@@ -2068,6 +2106,35 @@
 }
 
 
+int p2p_parse_dev_addr(const u8 *ies, size_t ies_len, u8 *dev_addr)
+{
+	struct wpabuf *p2p_ie;
+	struct p2p_message msg;
+	int ret = -1;
+
+	p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
+					     P2P_IE_VENDOR_TYPE);
+	if (p2p_ie == NULL)
+		return -1;
+	os_memset(&msg, 0, sizeof(msg));
+	if (p2p_parse_p2p_ie(p2p_ie, &msg)) {
+		wpabuf_free(p2p_ie);
+		return -1;
+	}
+
+	if (msg.p2p_device_addr) {
+		os_memcpy(dev_addr, msg.p2p_device_addr, ETH_ALEN);
+		ret = 0;
+	} else if (msg.device_id) {
+		os_memcpy(dev_addr, msg.device_id, ETH_ALEN);
+		ret = 0;
+	}
+
+	wpabuf_free(p2p_ie);
+	return ret;
+}
+
+
 static void p2p_clear_go_neg(struct p2p_data *p2p)
 {
 	p2p->go_neg_peer = NULL;
@@ -2142,6 +2209,16 @@
 		p2p->cfg->model_number = os_strdup(cfg->model_number);
 	if (cfg->serial_number)
 		p2p->cfg->serial_number = os_strdup(cfg->serial_number);
+	if (cfg->pref_chan) {
+		p2p->cfg->pref_chan = os_malloc(cfg->num_pref_chan *
+						sizeof(struct p2p_channel));
+		if (p2p->cfg->pref_chan) {
+			os_memcpy(p2p->cfg->pref_chan, cfg->pref_chan,
+				  cfg->num_pref_chan *
+				  sizeof(struct p2p_channel));
+		} else
+			p2p->cfg->num_pref_chan = 0;
+	}
 
 	p2p->min_disc_int = 1;
 	p2p->max_disc_int = 3;
@@ -2176,6 +2253,7 @@
 	os_free(p2p->cfg->model_name);
 	os_free(p2p->cfg->model_number);
 	os_free(p2p->cfg->serial_number);
+	os_free(p2p->cfg->pref_chan);
 	os_free(p2p->groups);
 	wpabuf_free(p2p->sd_resp);
 	os_free(p2p->after_scan_tx);
@@ -2187,11 +2265,7 @@
 void p2p_flush(struct p2p_data *p2p)
 {
 	struct p2p_device *dev, *prev;
-	p2p_clear_timeout(p2p);
-	p2p_set_state(p2p, P2P_IDLE);
-	p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
-	p2p->go_neg_peer = NULL;
-	eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
+	p2p_stop_find(p2p);
 	dl_list_for_each_safe(dev, prev, &p2p->devices, struct p2p_device,
 			      list) {
 		dl_list_del(&dev->list);
@@ -2797,6 +2871,20 @@
 		p2p_connect_send(p2p, p2p->go_neg_peer);
 		return 1;
 	} else if (p2p->state == P2P_SEARCH) {
+		if (p2p->p2p_scan_running) {
+			 /*
+			  * Search is already in progress. This can happen if
+			  * an Action frame RX is reported immediately after
+			  * the end of a remain-on-channel operation and the
+			  * response frame to that is sent using an offchannel
+			  * operation while in p2p_find. Avoid an attempt to
+			  * restart a scan here.
+			  */
+			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: p2p_scan "
+				"already in progress - do not try to start a "
+				"new one");
+			return 1;
+		}
 		p2p_search(p2p);
 		return 1;
 	}
@@ -3621,6 +3709,28 @@
 }
 
 
+int p2p_set_pref_chan(struct p2p_data *p2p, unsigned int num_pref_chan,
+		      const struct p2p_channel *pref_chan)
+{
+	struct p2p_channel *n;
+
+	if (pref_chan) {
+		n = os_malloc(num_pref_chan * sizeof(struct p2p_channel));
+		if (n == NULL)
+			return -1;
+		os_memcpy(n, pref_chan,
+			  num_pref_chan * sizeof(struct p2p_channel));
+	} else
+		n = NULL;
+
+	os_free(p2p->cfg->pref_chan);
+	p2p->cfg->pref_chan = n;
+	p2p->cfg->num_pref_chan = num_pref_chan;
+
+	return 0;
+}
+
+
 int p2p_get_interface_addr(struct p2p_data *p2p, const u8 *dev_addr,
 			   u8 *iface_addr)
 {

Modified: wpa/trunk/src/p2p/p2p.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/p2p/p2p.h?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/p2p/p2p.h (original)
+++ wpa/trunk/src/p2p/p2p.h Tue Apr 17 11:03:56 2012
@@ -224,6 +224,11 @@
 	P2P_PROV_DISC_REJECTED,
 };
 
+struct p2p_channel {
+	u8 op_class;
+	u8 chan;
+};
+
 /**
  * struct p2p_config - P2P configuration
  *
@@ -269,6 +274,16 @@
 	 * numbering of the clases depends on the configured country code.
 	 */
 	struct p2p_channels channels;
+
+	/**
+	 * num_pref_chan - Number of pref_chan entries
+	 */
+	unsigned int num_pref_chan;
+
+	/**
+	 * pref_chan - Preferred channels for GO Negotiation
+	 */
+	struct p2p_channel *pref_chan;
 
 	/**
 	 * pri_dev_type - Primary Device Type (see WPS)
@@ -1051,6 +1066,28 @@
  */
 void p2p_group_formation_failed(struct p2p_data *p2p);
 
+/**
+ * p2p_get_provisioning_info - Get any stored provisioning info
+ * @p2p: P2P module context from p2p_init()
+ * @addr: Peer P2P Device Address
+ * Returns: WPS provisioning information (WPS config method) or 0 if no
+ * information is available
+ *
+ * This function is used to retrieve stored WPS provisioning info for the given
+ * peer.
+ */
+u16 p2p_get_provisioning_info(struct p2p_data *p2p, const u8 *addr);
+
+/**
+ * p2p_clear_provisioning_info - Clear any stored provisioning info
+ * @p2p: P2P module context from p2p_init()
+ * @iface_addr: Peer P2P Device Address
+ *
+ * This function is used to clear stored WPS provisioning info for the given
+ * peer.
+ */
+void p2p_clear_provisioning_info(struct p2p_data *p2p, const u8 *addr);
+
 
 /* Event notifications from lower layer driver operations */
 
@@ -1355,6 +1392,15 @@
 int p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, char *end);
 
 /**
+ * p2p_parse_dev_addr - Parse P2P Device Address from P2P IE(s)
+ * @ies: Information elements from scan results
+ * @ies_len: ies buffer length in octets
+ * @dev_addr: Buffer for returning P2P Device Address
+ * Returns: 0 on success or -1 if P2P Device Address could not be parsed
+ */
+int p2p_parse_dev_addr(const u8 *ies, size_t ies_len, u8 *dev_addr);
+
+/**
  * p2p_assoc_req_ie - Build P2P IE for (Re)Association Request frame
  * @p2p: P2P module context from p2p_init()
  * @bssid: BSSID
@@ -1481,9 +1527,6 @@
 
 int p2p_get_oper_freq(struct p2p_data *p2p, const u8 *iface_addr);
 
-int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, int level,
-		   const u8 *ies, size_t ies_len);
-
 /**
  * p2p_set_intra_bss_dist - Set intra BSS distribution
  * @p2p: P2P module context from p2p_init()
@@ -1586,6 +1629,16 @@
 			 int cfg_op_channel);
 
 /**
+ * p2p_set_pref_chan - Set P2P preferred channel list
+ * @p2p: P2P module context from p2p_init()
+ * @num_pref_chan: Number of entries in pref_chan list
+ * @pref_chan: Preferred channels or %NULL to remove preferences
+ * Returns: 0 on success, -1 on failure
+ */
+int p2p_set_pref_chan(struct p2p_data *p2p, unsigned int num_pref_chan,
+		      const struct p2p_channel *pref_chan);
+
+/**
  * p2p_in_progress - Check whether a P2P operation is progress
  * @p2p: P2P module context from p2p_init()
  * Returns: 0 if P2P module is idle or 1 if an operation is in progress

Modified: wpa/trunk/src/p2p/p2p_go_neg.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/p2p/p2p_go_neg.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/p2p/p2p_go_neg.c (original)
+++ wpa/trunk/src/p2p/p2p_go_neg.c Tue Apr 17 11:03:56 2012
@@ -302,6 +302,7 @@
 	struct p2p_reg_class *cl;
 	int freq;
 	u8 op_reg_class, op_channel;
+	unsigned int i;
 
 	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Selected operating "
 		"channel (reg_class %u channel %u) not acceptable to the "
@@ -332,6 +333,21 @@
 		p2p->op_reg_class = op_reg_class;
 		p2p->op_channel = op_channel;
 		return;
+	}
+
+	/* Select channel with highest preference if the peer supports it */
+	for (i = 0; p2p->cfg->pref_chan && i < p2p->cfg->num_pref_chan; i++) {
+		if (p2p_channels_includes(intersection,
+					  p2p->cfg->pref_chan[i].op_class,
+					  p2p->cfg->pref_chan[i].chan)) {
+			p2p->op_reg_class = p2p->cfg->pref_chan[i].op_class;
+			p2p->op_channel = p2p->cfg->pref_chan[i].chan;
+			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Pick "
+				"highest preferred chnnel (op_class %u "
+				"channel %u) from intersection",
+				p2p->op_reg_class, p2p->op_channel);
+			return;
+		}
 	}
 
 	/*

Modified: wpa/trunk/src/p2p/p2p_i.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/p2p/p2p_i.h?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/p2p/p2p_i.h (original)
+++ wpa/trunk/src/p2p/p2p_i.h Tue Apr 17 11:03:56 2012
@@ -70,6 +70,14 @@
 	 * req_config_methods - Pending provisioning discovery methods
 	 */
 	u16 req_config_methods;
+
+	/**
+	 * wps_prov_info - Stored provisioning WPS config method
+	 *
+	 * This is used to store pending WPS config method between Provisioning
+	 * Discovery and connection to a running group.
+	 */
+	u16 wps_prov_info;
 
 #define P2P_DEV_PROBE_REQ_ONLY BIT(0)
 #define P2P_DEV_REPORTED BIT(1)
@@ -649,6 +657,8 @@
 						struct p2p_message *msg);
 void p2p_add_dev_info(struct p2p_data *p2p, const u8 *addr,
 		      struct p2p_device *dev, struct p2p_message *msg);
+int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, int level,
+		   const u8 *ies, size_t ies_len);
 struct p2p_device * p2p_get_device(struct p2p_data *p2p, const u8 *addr);
 struct p2p_device * p2p_get_device_interface(struct p2p_data *p2p,
 					     const u8 *addr);
@@ -663,5 +673,6 @@
 int p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst,
 		    const u8 *src, const u8 *bssid, const u8 *buf,
 		    size_t len, unsigned int wait_time);
+void p2p_stop_listen_for_freq(struct p2p_data *p2p, int freq);
 
 #endif /* P2P_I_H */

Modified: wpa/trunk/src/p2p/p2p_invitation.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/p2p/p2p_invitation.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/p2p/p2p_invitation.c (original)
+++ wpa/trunk/src/p2p/p2p_invitation.c Tue Apr 17 11:03:56 2012
@@ -350,6 +350,8 @@
 	req = p2p_build_invitation_req(p2p, dev, go_dev_addr);
 	if (req == NULL)
 		return -1;
+	if (p2p->state != P2P_IDLE)
+		p2p_stop_listen_for_freq(p2p, freq);
 	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
 		"P2P: Sending Invitation Request");
 	p2p_set_state(p2p, P2P_INVITE);

Modified: wpa/trunk/src/p2p/p2p_pd.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/p2p/p2p_pd.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/p2p/p2p_pd.c (original)
+++ wpa/trunk/src/p2p/p2p_pd.c Tue Apr 17 11:03:56 2012
@@ -267,6 +267,10 @@
 			MAC2STR(sa));
 		dev->flags |= P2P_DEV_PD_PEER_KEYPAD;
 	}
+
+	/* Store the provisioning info */
+	dev->wps_prov_info = msg.wps_config_methods;
+
 	p2p_parse_free(&msg);
 
 out:
@@ -318,6 +322,8 @@
 	if (req == NULL)
 		return -1;
 
+	if (p2p->state != P2P_IDLE)
+		p2p_stop_listen_for_freq(p2p, freq);
 	p2p->pending_action_state = P2P_PENDING_PD;
 	if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr,
 			    p2p->cfg->dev_addr, dev->info.p2p_device_addr,
@@ -356,15 +362,17 @@
 	if (config_methods == 0)
 		return -1;
 
+	/* Reset provisioning info */
+	dev->wps_prov_info = 0;
+
 	dev->req_config_methods = config_methods;
 	if (join)
 		dev->flags |= P2P_DEV_PD_FOR_JOIN;
 	else
 		dev->flags &= ~P2P_DEV_PD_FOR_JOIN;
 
-	if (p2p->go_neg_peer ||
-	    (p2p->state != P2P_IDLE && p2p->state != P2P_SEARCH &&
-	     p2p->state != P2P_LISTEN_ONLY)) {
+	if (p2p->state != P2P_IDLE && p2p->state != P2P_SEARCH &&
+	    p2p->state != P2P_LISTEN_ONLY) {
 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Busy with other "
 			"operations; postpone Provision Discovery Request "
 			"with " MACSTR " (config methods 0x%x)",

Modified: wpa/trunk/src/radius/radius_client.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/radius/radius_client.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/radius/radius_client.c (original)
+++ wpa/trunk/src/radius/radius_client.c Tue Apr 17 11:03:56 2012
@@ -684,7 +684,7 @@
 	radius_client_list_add(radius, msg, msg_type, shared_secret,
 			       shared_secret_len, addr);
 
-	return res;
+	return 0;
 }
 
 

Modified: wpa/trunk/src/utils/wpa_debug.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/utils/wpa_debug.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/utils/wpa_debug.c (original)
+++ wpa/trunk/src/utils/wpa_debug.c Tue Apr 17 11:03:56 2012
@@ -166,6 +166,38 @@
 	size_t i;
 	if (level < wpa_debug_level)
 		return;
+#ifdef CONFIG_DEBUG_SYSLOG
+	if (wpa_debug_syslog) {
+		const char *display;
+		char *strbuf = NULL;
+
+		if (buf == NULL) {
+			display = " [NULL]";
+		} else if (len == 0) {
+			display = "";
+		} else if (show && len) {
+			strbuf = os_malloc(1 + 3 * len);
+			if (strbuf == NULL) {
+				wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to "
+					   "allocate message buffer");
+				return;
+			}
+
+			for (i = 0; i < len; i++)
+				os_snprintf(&strbuf[i * 3], 4, " %02x",
+					    buf[i]);
+
+			display = strbuf;
+		} else {
+			display = " [REMOVED]";
+		}
+
+		syslog(syslog_priority(level), "%s - hexdump(len=%lu):%s",
+		       title, len, display);
+		os_free(strbuf);
+		return;
+	}
+#endif /* CONFIG_DEBUG_SYSLOG */
 	wpa_debug_print_timestamp();
 #ifdef CONFIG_DEBUG_FILE
 	if (out_file) {

Modified: wpa/trunk/src/wps/wps.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/wps/wps.h?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/wps/wps.h (original)
+++ wpa/trunk/src/wps/wps.h Tue Apr 17 11:03:56 2012
@@ -457,7 +457,12 @@
 	/**
 	 * WPS_EV_ER_SET_SELECTED_REGISTRAR - ER: SetSelectedRegistrar event
 	 */
-	WPS_EV_ER_SET_SELECTED_REGISTRAR
+	WPS_EV_ER_SET_SELECTED_REGISTRAR,
+
+	/**
+	 * WPS_EV_AP_PIN_SUCCESS - External Registrar used correct AP PIN
+	 */
+	WPS_EV_AP_PIN_SUCCESS
 };
 
 /**

Modified: wpa/trunk/src/wps/wps_enrollee.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/src/wps/wps_enrollee.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/src/wps/wps_enrollee.c (original)
+++ wpa/trunk/src/wps/wps_enrollee.c Tue Apr 17 11:03:56 2012
@@ -257,20 +257,47 @@
 
 static int wps_build_cred_auth_type(struct wps_data *wps, struct wpabuf *msg)
 {
-	wpa_printf(MSG_DEBUG, "WPS:  * Authentication Type");
+	u16 auth_type = wps->wps->auth_types;
+
+	/* Select the best authentication type */
+	if (auth_type & WPS_AUTH_WPA2PSK)
+		auth_type = WPS_AUTH_WPA2PSK;
+	else if (auth_type & WPS_AUTH_WPAPSK)
+		auth_type = WPS_AUTH_WPAPSK;
+	else if (auth_type & WPS_AUTH_OPEN)
+		auth_type = WPS_AUTH_OPEN;
+	else if (auth_type & WPS_AUTH_SHARED)
+		auth_type = WPS_AUTH_SHARED;
+
+	wpa_printf(MSG_DEBUG, "WPS:  * Authentication Type (0x%x)", auth_type);
 	wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
 	wpabuf_put_be16(msg, 2);
-	wpabuf_put_be16(msg, wps->wps->auth_types);
+	wpabuf_put_be16(msg, auth_type);
 	return 0;
 }
 
 
 static int wps_build_cred_encr_type(struct wps_data *wps, struct wpabuf *msg)
 {
-	wpa_printf(MSG_DEBUG, "WPS:  * Encryption Type");
+	u16 encr_type = wps->wps->encr_types;
+
+	/* Select the best encryption type */
+	if (wps->wps->auth_types & (WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK)) {
+		if (encr_type & WPS_ENCR_AES)
+			encr_type = WPS_ENCR_AES;
+		else if (encr_type & WPS_ENCR_TKIP)
+			encr_type = WPS_ENCR_TKIP;
+	} else {
+		if (encr_type & WPS_ENCR_WEP)
+			encr_type = WPS_ENCR_WEP;
+		else if (encr_type & WPS_ENCR_NONE)
+			encr_type = WPS_ENCR_NONE;
+	}
+
+	wpa_printf(MSG_DEBUG, "WPS:  * Encryption Type (0x%x)", encr_type);
 	wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
 	wpabuf_put_be16(msg, 2);
-	wpabuf_put_be16(msg, wps->wps->encr_types);
+	wpabuf_put_be16(msg, encr_type);
 	return 0;
 }
 
@@ -1037,6 +1064,10 @@
 	}
 	wpabuf_free(decrypted);
 
+	if (wps->wps->ap)
+		wps->wps->event_cb(wps->wps->cb_ctx, WPS_EV_AP_PIN_SUCCESS,
+				   NULL);
+
 	wps->state = SEND_M7;
 	return WPS_CONTINUE;
 }

Modified: wpa/trunk/wpa_supplicant/Android.mk
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/Android.mk?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/Android.mk (original)
+++ wpa/trunk/wpa_supplicant/Android.mk Tue Apr 17 11:03:56 2012
@@ -1171,17 +1171,6 @@
 ifndef DBUS_INCLUDE
 DBUS_INCLUDE := $(shell $(PKG_CONFIG) --cflags dbus-1)
 endif
-dbus_version=$(subst ., ,$(shell $(PKG_CONFIG) --modversion dbus-1))
-DBUS_VERSION_MAJOR=$(word 1,$(dbus_version))
-DBUS_VERSION_MINOR=$(word 2,$(dbus_version))
-ifeq ($(DBUS_VERSION_MAJOR),)
-DBUS_VERSION_MAJOR=0
-endif
-ifeq ($(DBUS_VERSION_MINOR),)
-DBUS_VERSION_MINOR=0
-endif
-DBUS_INCLUDE += -DDBUS_VERSION_MAJOR=$(DBUS_VERSION_MAJOR)
-DBUS_INCLUDE += -DDBUS_VERSION_MINOR=$(DBUS_VERSION_MINOR)
 DBUS_CFLAGS += $(DBUS_INCLUDE)
 endif
 

Modified: wpa/trunk/wpa_supplicant/Makefile
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/Makefile?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/Makefile (original)
+++ wpa/trunk/wpa_supplicant/Makefile Tue Apr 17 11:03:56 2012
@@ -15,12 +15,13 @@
 
 -include .config
 
-ALL=wpa_supplicant wpa_cli
+BINALL=wpa_supplicant wpa_cli
 
 ifndef CONFIG_NO_WPA_PASSPHRASE
-ALL += wpa_passphrase
-endif
-
+BINALL += wpa_passphrase
+endif
+
+ALL = $(BINALL)
 ALL += systemd/wpa_supplicant.service
 ALL += systemd/wpa_supplicant at .service
 ALL += systemd/wpa_supplicant-nl80211 at .service
@@ -48,9 +49,10 @@
 	echo CONFIG_DRIVER_HOSTAP=y >> .config
 	echo CONFIG_DRIVER_WEXT=y >> .config
 
-install: all
-	mkdir -p $(DESTDIR)$(BINDIR)
-	for i in $(ALL); do cp $$i $(DESTDIR)$(BINDIR)/$$i; done
+$(DESTDIR)$(BINDIR)/%: %
+	install -D $(<) $(@)
+
+install: $(addprefix $(DESTDIR)$(BINDIR)/,$(BINALL))
 	$(MAKE) -C ../src install
 
 OBJS = config.o
@@ -1150,17 +1152,6 @@
 ifndef DBUS_INCLUDE
 DBUS_INCLUDE := $(shell $(PKG_CONFIG) --cflags dbus-1)
 endif
-dbus_version=$(subst ., ,$(shell $(PKG_CONFIG) --modversion dbus-1))
-DBUS_VERSION_MAJOR=$(word 1,$(dbus_version))
-DBUS_VERSION_MINOR=$(word 2,$(dbus_version))
-ifeq ($(DBUS_VERSION_MAJOR),)
-DBUS_VERSION_MAJOR=0
-endif
-ifeq ($(DBUS_VERSION_MINOR),)
-DBUS_VERSION_MINOR=0
-endif
-DBUS_INCLUDE += -DDBUS_VERSION_MAJOR=$(DBUS_VERSION_MAJOR)
-DBUS_INCLUDE += -DDBUS_VERSION_MINOR=$(DBUS_VERSION_MINOR)
 DBUS_CFLAGS += $(DBUS_INCLUDE)
 endif
 

Modified: wpa/trunk/wpa_supplicant/ap.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/ap.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/ap.c (original)
+++ wpa/trunk/wpa_supplicant/ap.c Tue Apr 17 11:03:56 2012
@@ -317,9 +317,9 @@
 
 
 static void ap_sta_authorized_cb(void *ctx, const u8 *mac_addr,
-				 int authorized)
-{
-	wpas_notify_sta_authorized(ctx, mac_addr, authorized);
+				 int authorized, const u8 *p2p_dev_addr)
+{
+	wpas_notify_sta_authorized(ctx, mac_addr, authorized, p2p_dev_addr);
 }
 
 
@@ -499,6 +499,7 @@
 		}
 
 		hapd_iface->bss[i]->msg_ctx = wpa_s;
+		hapd_iface->bss[i]->msg_ctx_parent = wpa_s->parent;
 		hapd_iface->bss[i]->public_action_cb = ap_public_action_rx;
 		hapd_iface->bss[i]->public_action_cb_ctx = wpa_s;
 		hapd_iface->bss[i]->vendor_action_cb = ap_vendor_action_rx;

Modified: wpa/trunk/wpa_supplicant/bss.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/bss.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/bss.c (original)
+++ wpa/trunk/wpa_supplicant/bss.c Tue Apr 17 11:03:56 2012
@@ -332,6 +332,8 @@
 		nbss = os_realloc(bss, sizeof(*bss) + res->ie_len +
 				  res->beacon_ie_len);
 		if (nbss) {
+			if (wpa_s->current_bss == bss)
+				wpa_s->current_bss = nbss;
 			bss = nbss;
 			os_memcpy(bss + 1, res + 1,
 				  res->ie_len + res->beacon_ie_len);
@@ -540,6 +542,23 @@
 }
 
 
+#ifdef CONFIG_P2P
+struct wpa_bss * wpa_bss_get_p2p_dev_addr(struct wpa_supplicant *wpa_s,
+					  const u8 *dev_addr)
+{
+	struct wpa_bss *bss;
+	dl_list_for_each_reverse(bss, &wpa_s->bss, struct wpa_bss, list) {
+		u8 addr[ETH_ALEN];
+		if (p2p_parse_dev_addr((const u8 *) (bss + 1), bss->ie_len,
+				       addr) == 0 &&
+		    os_memcmp(addr, dev_addr, ETH_ALEN) == 0)
+			return bss;
+	}
+	return NULL;
+}
+#endif /* CONFIG_P2P */
+
+
 struct wpa_bss * wpa_bss_get_id(struct wpa_supplicant *wpa_s, unsigned int id)
 {
 	struct wpa_bss *bss;

Modified: wpa/trunk/wpa_supplicant/bss.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/bss.h?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/bss.h (original)
+++ wpa/trunk/wpa_supplicant/bss.h Tue Apr 17 11:03:56 2012
@@ -94,6 +94,8 @@
 			     const u8 *ssid, size_t ssid_len);
 struct wpa_bss * wpa_bss_get_bssid(struct wpa_supplicant *wpa_s,
 				   const u8 *bssid);
+struct wpa_bss * wpa_bss_get_p2p_dev_addr(struct wpa_supplicant *wpa_s,
+					  const u8 *dev_addr);
 struct wpa_bss * wpa_bss_get_id(struct wpa_supplicant *wpa_s, unsigned int id);
 const u8 * wpa_bss_get_ie(const struct wpa_bss *bss, u8 ie);
 const u8 * wpa_bss_get_vendor_ie(const struct wpa_bss *bss, u32 vendor_type);

Modified: wpa/trunk/wpa_supplicant/config.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/config.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/config.c (original)
+++ wpa/trunk/wpa_supplicant/config.c Tue Apr 17 11:03:56 2012
@@ -19,6 +19,7 @@
 #include "crypto/sha1.h"
 #include "rsn_supp/wpa.h"
 #include "eap_peer/eap.h"
+#include "p2p/p2p.h"
 #include "config.h"
 
 
@@ -1116,6 +1117,7 @@
 
 	wpa_hexdump(MSG_MSGDUMP, "eap methods",
 		    (u8 *) methods, num_methods * sizeof(*methods));
+	os_free(ssid->eap.eap_methods);
 	ssid->eap.eap_methods = methods;
 	return errors ? -1 : 0;
 }
@@ -1350,6 +1352,90 @@
 }
 #endif /* NO_CONFIG_WRITE */
 
+
+#ifdef CONFIG_P2P
+
+static int wpa_config_parse_p2p_client_list(const struct parse_data *data,
+					    struct wpa_ssid *ssid, int line,
+					    const char *value)
+{
+	const char *pos;
+	u8 *buf, *n, addr[ETH_ALEN];
+	size_t count;
+
+	buf = NULL;
+	count = 0;
+
+	pos = value;
+	while (pos && *pos) {
+		while (*pos == ' ')
+			pos++;
+
+		if (hwaddr_aton(pos, addr)) {
+			wpa_printf(MSG_ERROR, "Line %d: Invalid "
+				   "p2p_client_list address '%s'.",
+				   line, value);
+			/* continue anyway */
+		} else {
+			n = os_realloc(buf, (count + 1) * ETH_ALEN);
+			if (n == NULL) {
+				os_free(buf);
+				return -1;
+			}
+			buf = n;
+			os_memcpy(buf + count * ETH_ALEN, addr, ETH_ALEN);
+			count++;
+			wpa_hexdump(MSG_MSGDUMP, "p2p_client_list",
+				    addr, ETH_ALEN);
+		}
+
+		pos = os_strchr(pos, ' ');
+	}
+
+	os_free(ssid->p2p_client_list);
+	ssid->p2p_client_list = buf;
+	ssid->num_p2p_clients = count;
+
+	return 0;
+}
+
+
+#ifndef NO_CONFIG_WRITE
+static char * wpa_config_write_p2p_client_list(const struct parse_data *data,
+					       struct wpa_ssid *ssid)
+{
+	char *value, *end, *pos;
+	int res;
+	size_t i;
+
+	if (ssid->p2p_client_list == NULL || ssid->num_p2p_clients == 0)
+		return NULL;
+
+	value = os_malloc(20 * ssid->num_p2p_clients);
+	if (value == NULL)
+		return NULL;
+	pos = value;
+	end = value + 20 * ssid->num_p2p_clients;
+
+	for (i = 0; i < ssid->num_p2p_clients; i++) {
+		res = os_snprintf(pos, end - pos, MACSTR " ",
+				  MAC2STR(ssid->p2p_client_list +
+					  i * ETH_ALEN));
+		if (res < 0 || res >= end - pos) {
+			os_free(value);
+			return NULL;
+		}
+		pos += res;
+	}
+
+	if (pos > value)
+		pos[-1] = '\0';
+
+	return value;
+}
+#endif /* NO_CONFIG_WRITE */
+
+#endif /* CONFIG_P2P */
 
 /* Helper macros for network block parser */
 
@@ -1511,6 +1597,9 @@
 	{ INT_RANGE(frequency, 0, 10000) },
 	{ INT(wpa_ptk_rekey) },
 	{ STR(bgscan) },
+#ifdef CONFIG_P2P
+	{ FUNC(p2p_client_list) },
+#endif /* CONFIG_P2P */
 };
 
 #undef OFFSET
@@ -1677,6 +1766,7 @@
 	os_free(ssid->scan_freq);
 	os_free(ssid->freq_list);
 	os_free(ssid->bgscan);
+	os_free(ssid->p2p_client_list);
 	os_free(ssid);
 }
 
@@ -1732,6 +1822,7 @@
 	os_free(config->home_ca_cert);
 	os_free(config->home_imsi);
 	os_free(config->home_milenage);
+	os_free(config->p2p_pref_chan);
 	os_free(config);
 }
 
@@ -2405,6 +2496,55 @@
 
 	config->num_sec_device_types++;
 	return 0;
+}
+
+
+static int wpa_config_process_p2p_pref_chan(
+	const struct global_parse_data *data,
+	struct wpa_config *config, int line, const char *pos)
+{
+	struct p2p_channel *pref = NULL, *n;
+	unsigned int num = 0;
+	const char *pos2;
+	u8 op_class, chan;
+
+	/* format: class:chan,class:chan,... */
+
+	while (*pos) {
+		op_class = atoi(pos);
+		pos2 = os_strchr(pos, ':');
+		if (pos2 == NULL)
+			goto fail;
+		pos2++;
+		chan = atoi(pos2);
+
+		n = os_realloc(pref, (num + 1) * sizeof(struct p2p_channel));
+		if (n == NULL)
+			goto fail;
+		pref = n;
+		pref[num].op_class = op_class;
+		pref[num].chan = chan;
+		num++;
+
+		pos = os_strchr(pos2, ',');
+		if (pos == NULL)
+			break;
+		pos++;
+	}
+
+	os_free(config->p2p_pref_chan);
+	config->p2p_pref_chan = pref;
+	config->num_p2p_pref_chan = num;
+	wpa_hexdump(MSG_DEBUG, "P2P: Preferred class/channel pairs",
+		    (u8 *) config->p2p_pref_chan,
+		    config->num_p2p_pref_chan * sizeof(struct p2p_channel));
+
+	return 0;
+
+fail:
+	os_free(pref);
+	wpa_printf(MSG_ERROR, "Line %d: Invalid p2p_pref_chan list", line);
+	return -1;
 }
 #endif /* CONFIG_P2P */
 
@@ -2480,6 +2620,7 @@
 	{ INT_RANGE(persistent_reconnect, 0, 1), 0 },
 	{ INT_RANGE(p2p_intra_bss, 0, 1), CFG_CHANGED_P2P_INTRA_BSS },
 	{ INT(p2p_group_idle), 0 },
+	{ FUNC(p2p_pref_chan), CFG_CHANGED_P2P_PREF_CHAN },
 #endif /* CONFIG_P2P */
 	{ FUNC(country), CFG_CHANGED_COUNTRY },
 	{ INT(bss_max_count), 0 },

Modified: wpa/trunk/wpa_supplicant/config.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/config.h?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/config.h (original)
+++ wpa/trunk/wpa_supplicant/config.h Tue Apr 17 11:03:56 2012
@@ -47,6 +47,7 @@
 #define CFG_CHANGED_VENDOR_EXTENSION BIT(10)
 #define CFG_CHANGED_P2P_LISTEN_CHANNEL BIT(11)
 #define CFG_CHANGED_P2P_OPER_CHANNEL BIT(12)
+#define CFG_CHANGED_P2P_PREF_CHAN BIT(13)
 
 /**
  * struct wpa_config - wpa_supplicant configuration data
@@ -362,6 +363,8 @@
 	char *p2p_ssid_postfix;
 	int persistent_reconnect;
 	int p2p_intra_bss;
+	unsigned int num_p2p_pref_chan;
+	struct p2p_channel *p2p_pref_chan;
 
 #define MAX_WPS_VENDOR_EXT 10
 	/**

Modified: wpa/trunk/wpa_supplicant/config_file.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/config_file.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/config_file.c (original)
+++ wpa/trunk/wpa_supplicant/config_file.c Tue Apr 17 11:03:56 2012
@@ -22,6 +22,7 @@
 #include "config.h"
 #include "base64.h"
 #include "uuid.h"
+#include "p2p/p2p.h"
 
 
 /**
@@ -495,6 +496,18 @@
 }
 
 
+#ifdef CONFIG_P2P
+static void write_p2p_client_list(FILE *f, struct wpa_ssid *ssid)
+{
+	char *value = wpa_config_get(ssid, "p2p_client_list");
+	if (value == NULL)
+		return;
+	fprintf(f, "\tp2p_client_list=%s\n", value);
+	os_free(value);
+}
+#endif /* CONFIG_P2P */
+
+
 static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
 {
 	int i;
@@ -514,6 +527,7 @@
 	write_pairwise(f, ssid);
 	write_group(f, ssid);
 	write_auth_alg(f, ssid);
+	STR(bgscan);
 #ifdef IEEE8021X_EAPOL
 	write_eap(f, ssid);
 	STR(identity);
@@ -569,6 +583,9 @@
 	INT(ieee80211w);
 #endif /* CONFIG_IEEE80211W */
 	STR(id_str);
+#ifdef CONFIG_P2P
+	write_p2p_client_list(f, ssid);
+#endif /* CONFIG_P2P */
 
 #undef STR
 #undef INT
@@ -684,6 +701,16 @@
 		fprintf(f, "p2p_intra_bss=%u\n", config->p2p_intra_bss);
 	if (config->p2p_group_idle)
 		fprintf(f, "p2p_group_idle=%u\n", config->p2p_group_idle);
+	if (config->p2p_pref_chan) {
+		unsigned int i;
+		fprintf(f, "p2p_pref_chan=");
+		for (i = 0; i < config->num_p2p_pref_chan; i++) {
+			fprintf(f, "%s%u:%u", i > 0 ? "," : "",
+				config->p2p_pref_chan[i].op_class,
+				config->p2p_pref_chan[i].chan);
+		}
+		fprintf(f, "\n");
+	}
 #endif /* CONFIG_P2P */
 	if (config->country[0] && config->country[1]) {
 		fprintf(f, "country=%c%c\n",

Modified: wpa/trunk/wpa_supplicant/config_ssid.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/config_ssid.h?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/config_ssid.h (original)
+++ wpa/trunk/wpa_supplicant/config_ssid.h Tue Apr 17 11:03:56 2012
@@ -387,6 +387,20 @@
 	int *freq_list;
 
 	/**
+	 * p2p_client_list - List of P2P Clients in a persistent group (GO)
+	 *
+	 * This is a list of P2P Clients (P2P Device Address) that have joined
+	 * the persistent group. This is maintained on the GO for persistent
+	 * group entries (disabled == 2).
+	 */
+	u8 *p2p_client_list;
+
+	/**
+	 * num_p2p_clients - Number of entries in p2p_client_list
+	 */
+	size_t num_p2p_clients;
+
+	/**
 	 * p2p_group - Network generated as a P2P group (used internally)
 	 */
 	int p2p_group;

Modified: wpa/trunk/wpa_supplicant/ctrl_iface.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/ctrl_iface.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/ctrl_iface.c (original)
+++ wpa/trunk/wpa_supplicant/ctrl_iface.c Tue Apr 17 11:03:56 2012
@@ -1584,6 +1584,9 @@
 		}
 		eapol_sm_invalidate_cached_session(wpa_s->eapol);
 		if (wpa_s->current_ssid) {
+#ifdef CONFIG_SME
+			wpa_s->sme.prev_bssid_set = 0;
+#endif /* CONFIG_SME */
 			wpa_sm_set_config(wpa_s->wpa, NULL);
 			eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
 			wpa_supplicant_disassociate(wpa_s,
@@ -1606,6 +1609,9 @@
 	}
 
 	if (ssid == wpa_s->current_ssid || wpa_s->current_ssid == NULL) {
+#ifdef CONFIG_SME
+		wpa_s->sme.prev_bssid_set = 0;
+#endif /* CONFIG_SME */
 		/*
 		 * Invalidate the EAP session cache if the current or
 		 * previously used network is removed.
@@ -2119,6 +2125,13 @@
 				bss = dl_list_entry(next, struct wpa_bss,
 						    list_id);
 		}
+#ifdef CONFIG_P2P
+	} else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) {
+		if (hwaddr_aton(cmd + 13, bssid) == 0)
+			bss = wpa_bss_get_p2p_dev_addr(wpa_s, bssid);
+		else
+			bss = NULL;
+#endif /* CONFIG_P2P */
 	} else if (hwaddr_aton(cmd, bssid) == 0)
 		bss = wpa_bss_get_bssid(wpa_s, bssid);
 	else {
@@ -2626,6 +2639,8 @@
 static int p2p_ctrl_serv_disc_external(struct wpa_supplicant *wpa_s,
 				       char *cmd)
 {
+	if (os_strcmp(cmd, "0") && os_strcmp(cmd, "1"))
+		return -1;
 	wpa_s->p2p_sd_over_ctrl_iface = atoi(cmd);
 	return 0;
 }
@@ -2961,7 +2976,7 @@
 		return pos - buf;
 	pos += res;
 
-	ssid = wpas_p2p_get_persistent(wpa_s, info->p2p_device_addr);
+	ssid = wpas_p2p_get_persistent(wpa_s, info->p2p_device_addr, NULL, 0);
 	if (ssid) {
 		res = os_snprintf(pos, end - pos, "persistent=%d\n", ssid->id);
 		if (res < 0 || res >= end - pos)
@@ -3570,6 +3585,9 @@
 		reply_len = wpa_supplicant_ctrl_iface_list_networks(
 			wpa_s, reply, reply_size);
 	} else if (os_strcmp(buf, "DISCONNECT") == 0) {
+#ifdef CONFIG_SME
+		wpa_s->sme.prev_bssid_set = 0;
+#endif /* CONFIG_SME */
 		wpa_s->reassociate = 0;
 		wpa_s->disconnected = 1;
 		wpa_supplicant_deauthenticate(wpa_s,

Modified: wpa/trunk/wpa_supplicant/dbus/Makefile
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/dbus/Makefile?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/dbus/Makefile (original)
+++ wpa/trunk/wpa_supplicant/dbus/Makefile Tue Apr 17 11:03:56 2012
@@ -50,18 +50,6 @@
 DBUS_LIBS += $(shell xml2-config --libs)
 endif
 
-dbus_version=$(subst ., ,$(shell $(PKG_CONFIG) --modversion dbus-1))
-DBUS_VERSION_MAJOR=$(word 1,$(dbus_version))
-DBUS_VERSION_MINOR=$(word 2,$(dbus_version))
-ifeq ($(DBUS_VERSION_MAJOR),)
-DBUS_VERSION_MAJOR=0
-endif
-ifeq ($(DBUS_VERSION_MINOR),)
-DBUS_VERSION_MINOR=0
-endif
-DBUS_INCLUDE += -DDBUS_VERSION_MAJOR=$(DBUS_VERSION_MAJOR)
-DBUS_INCLUDE += -DDBUS_VERSION_MINOR=$(DBUS_VERSION_MINOR)
-
 CFLAGS += $(DBUS_INCLUDE)
 
 LIB_OBJS= \

Modified: wpa/trunk/wpa_supplicant/dbus/dbus_new.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/dbus/dbus_new.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/dbus/dbus_new.c (original)
+++ wpa/trunk/wpa_supplicant/dbus/dbus_new.c Tue Apr 17 11:03:56 2012
@@ -2556,6 +2556,10 @@
 	  wpas_dbus_getter_networks,
 	  NULL
 	},
+	{ "FastReauth", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
+	  wpas_dbus_getter_fast_reauth,
+	  wpas_dbus_setter_fast_reauth
+	},
 #ifdef CONFIG_WPS
 	{ "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
 	  wpas_dbus_getter_process_credentials,
@@ -2563,9 +2567,9 @@
 	},
 #endif /* CONFIG_WPS */
 #ifdef CONFIG_P2P
-	{ "P2PDeviceProperties", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
-	  wpas_dbus_getter_p2p_device_properties,
-	  wpas_dbus_setter_p2p_device_properties
+	{ "P2PDeviceConfig", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
+	  wpas_dbus_getter_p2p_device_config,
+	  wpas_dbus_setter_p2p_device_config
 	},
 	{ "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
 	  wpas_dbus_getter_p2p_peers,
@@ -2894,8 +2898,36 @@
 #ifdef CONFIG_P2P
 
 static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = {
-	{ "Properties", WPAS_DBUS_NEW_IFACE_P2P_PEER, "a{sv}",
-	  wpas_dbus_getter_p2p_peer_properties,
+	{ "DeviceName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
+	  wpas_dbus_getter_p2p_peer_device_name,
+	  NULL
+	},
+	{ "PrimaryDeviceType", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
+	  wpas_dbus_getter_p2p_peer_primary_device_type,
+	  NULL
+	},
+	{ "config_method", WPAS_DBUS_NEW_IFACE_P2P_PEER, "q",
+	  wpas_dbus_getter_p2p_peer_config_method,
+	  NULL
+	},
+	{ "level", WPAS_DBUS_NEW_IFACE_P2P_PEER, "i",
+	  wpas_dbus_getter_p2p_peer_level,
+	  NULL
+	},
+	{ "devicecapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
+	  wpas_dbus_getter_p2p_peer_device_capability,
+	  NULL
+	},
+	{ "groupcapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
+	  wpas_dbus_getter_p2p_peer_group_capability,
+	  NULL
+	},
+	{ "SecondaryDeviceTypes", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
+	  wpas_dbus_getter_p2p_peer_secondary_device_types,
+	  NULL
+	},
+	{ "VendorExtension", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
+	  wpas_dbus_getter_p2p_peer_vendor_extension,
 	  NULL
 	},
 	{ "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
@@ -3095,10 +3127,37 @@
 	  wpas_dbus_getter_p2p_group_members,
 	  NULL
 	},
-	{ "Properties",
-	  WPAS_DBUS_NEW_IFACE_P2P_GROUP, "a{sv}",
-	  wpas_dbus_getter_p2p_group_properties,
-	  wpas_dbus_setter_p2p_group_properties
+	{ "Group", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "o",
+	  wpas_dbus_getter_p2p_group,
+	  NULL
+	},
+	{ "Role", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
+	  wpas_dbus_getter_p2p_role,
+	  NULL
+	},
+	{ "SSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
+	  wpas_dbus_getter_p2p_group_ssid,
+	  NULL
+	},
+	{ "BSSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
+	  wpas_dbus_getter_p2p_group_bssid,
+	  NULL
+	},
+	{ "Frequency", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "q",
+	  wpas_dbus_getter_p2p_group_frequency,
+	  NULL
+	},
+	{ "Passphrase", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
+	  wpas_dbus_getter_p2p_group_passphrase,
+	  NULL
+	},
+	{ "PSK", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
+	  wpas_dbus_getter_p2p_group_psk,
+	  NULL
+	},
+	{ "WPSVendorExtensions", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "aay",
+	  wpas_dbus_getter_p2p_group_vendor_ext,
+	  wpas_dbus_setter_p2p_group_vendor_ext
 	},
 	{ NULL, NULL, NULL, NULL, NULL }
 };
@@ -3220,10 +3279,6 @@
 
 static const struct wpa_dbus_property_desc
 wpas_dbus_p2p_groupmember_properties[] = {
-	{ "Properties", WPAS_DBUS_NEW_IFACE_P2P_GROUPMEMBER, "a{sv}",
-	  wpas_dbus_getter_p2p_group_properties,
-	  NULL
-	},
 	{ NULL, NULL, NULL, NULL, NULL }
 };
 

Modified: wpa/trunk/wpa_supplicant/dbus/dbus_new_handlers.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/dbus/dbus_new_handlers.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/dbus/dbus_new_handlers.c (original)
+++ wpa/trunk/wpa_supplicant/dbus/dbus_new_handlers.c Tue Apr 17 11:03:56 2012
@@ -441,6 +441,76 @@
 	if (!dbus_message_iter_close_container(iter, &variant_iter)) {
 		dbus_set_error(error, DBUS_ERROR_FAILED,
 		               "%s: failed to construct message 4", __func__);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+/**
+ * wpas_dbus_simple_array_array_property_getter - Get array array type property
+ * @iter: Pointer to incoming dbus message iterator
+ * @type: DBus type of property array elements (must be basic type)
+ * @array: pointer to array of elements to put into response message
+ * @array_len: length of above array
+ * @error: a pointer to an error to fill on failure
+ * Returns: TRUE if the request succeeded, FALSE if it failed
+ *
+ * Generic getter for array type properties. Array elements type is
+ * required to be basic.
+ */
+dbus_bool_t wpas_dbus_simple_array_array_property_getter(DBusMessageIter *iter,
+							 const int type,
+							 struct wpabuf **array,
+							 size_t array_len,
+							 DBusError *error)
+{
+	DBusMessageIter variant_iter, array_iter;
+	char type_str[] = "aa?";
+	char inner_type_str[] = "a?";
+	const char *sub_type_str;
+	size_t i;
+
+	if (!dbus_type_is_basic(type)) {
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+			       "%s: given type is not basic", __func__);
+		return FALSE;
+	}
+
+	sub_type_str = wpa_dbus_type_as_string(type);
+	type_str[2] = sub_type_str[0];
+	inner_type_str[1] = sub_type_str[0];
+
+	if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
+					      type_str, &variant_iter)) {
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+			       "%s: failed to construct message 1", __func__);
+		return FALSE;
+	}
+	if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
+					      inner_type_str, &array_iter)) {
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+			       "%s: failed to construct message 2", __func__);
+		return FALSE;
+	}
+
+	for (i = 0; i < array_len; i++) {
+		wpa_dbus_dict_bin_array_add_element(&array_iter,
+						    wpabuf_head(array[i]),
+						    wpabuf_len(array[i]));
+
+	}
+
+	if (!dbus_message_iter_close_container(&variant_iter, &array_iter)) {
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+			       "%s: failed to close message 2", __func__);
+		return FALSE;
+	}
+
+	if (!dbus_message_iter_close_container(iter, &variant_iter)) {
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+			       "%s: failed to close message 1", __func__);
 		return FALSE;
 	}
 
@@ -2182,6 +2252,54 @@
 
 
 /**
+ * wpas_dbus_getter_fast_reauth - Control fast
+ * reauthentication (TLS session resumption)
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
+ *
+ * Getter function for "FastReauth" property.
+ */
+dbus_bool_t wpas_dbus_getter_fast_reauth(DBusMessageIter *iter,
+					 DBusError *error,
+					 void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	dbus_bool_t fast_reauth = wpa_s->conf->fast_reauth ? TRUE : FALSE;
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BOOLEAN,
+						&fast_reauth, error);
+}
+
+
+/**
+ * wpas_dbus_setter_fast_reauth - Control fast
+ * reauthentication (TLS session resumption)
+ * @iter: Pointer to incoming dbus message iter
+ * @error: Location to store error on failure
+ * @user_data: Function specific data
+ * Returns: TRUE on success, FALSE on failure
+ *
+ * Setter function for "FastReauth" property.
+ */
+dbus_bool_t wpas_dbus_setter_fast_reauth(DBusMessageIter *iter,
+				     DBusError *error,
+				     void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	dbus_bool_t fast_reauth;
+
+	if (!wpas_dbus_simple_property_setter(iter, error, DBUS_TYPE_BOOLEAN,
+					      &fast_reauth))
+		return FALSE;
+
+	wpa_s->conf->fast_reauth = fast_reauth;
+	return TRUE;
+}
+
+
+/**
  * wpas_dbus_getter_bss_expire_age - Get BSS entry expiration age
  * @iter: Pointer to incoming dbus message iter
  * @error: Location to store error on failure
@@ -2822,13 +2940,15 @@
 {
 	struct bss_handler_args *args = user_data;
 	struct wpa_bss *res;
+	s16 level;
 
 	res = get_bss_helper(args, error, __func__);
 	if (!res)
 		return FALSE;
 
+	level = (s16) res->level;
 	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT16,
-						&res->level, error);
+						&level, error);
 }
 
 
@@ -2846,13 +2966,15 @@
 {
 	struct bss_handler_args *args = user_data;
 	struct wpa_bss *res;
+	u16 freq;
 
 	res = get_bss_helper(args, error, __func__);
 	if (!res)
 		return FALSE;
 
+	freq = (u16) res->freq;
 	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16,
-						&res->freq, error);
+						&freq, error);
 }
 
 

Modified: wpa/trunk/wpa_supplicant/dbus/dbus_new_handlers.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/dbus/dbus_new_handlers.h?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/dbus/dbus_new_handlers.h (original)
+++ wpa/trunk/wpa_supplicant/dbus/dbus_new_handlers.h Tue Apr 17 11:03:56 2012
@@ -41,6 +41,12 @@
 						   size_t array_len,
 						   DBusError *error);
 
+dbus_bool_t wpas_dbus_simple_array_array_property_getter(DBusMessageIter *iter,
+							 const int type,
+							 struct wpabuf **array,
+							 size_t array_len,
+							 DBusError *error);
+
 DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message,
 						 struct wpa_global *global);
 
@@ -133,6 +139,14 @@
 dbus_bool_t wpas_dbus_setter_ap_scan(DBusMessageIter *iter, DBusError *error,
 				     void *user_data);
 
+dbus_bool_t wpas_dbus_getter_fast_reauth(DBusMessageIter *iter,
+					 DBusError *error,
+					 void *user_data);
+
+dbus_bool_t wpas_dbus_setter_fast_reauth(DBusMessageIter *iter,
+					 DBusError *error,
+					 void *user_data);
+
 dbus_bool_t wpas_dbus_getter_bss_expire_age(DBusMessageIter *iter,
 					    DBusError *error, void *user_data);
 

Modified: wpa/trunk/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/dbus/dbus_new_handlers_p2p.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/dbus/dbus_new_handlers_p2p.c (original)
+++ wpa/trunk/wpa_supplicant/dbus/dbus_new_handlers_p2p.c Tue Apr 17 11:03:56 2012
@@ -704,9 +704,9 @@
  * P2P Device property accessor methods.
  */
 
-dbus_bool_t wpas_dbus_getter_p2p_device_properties(DBusMessageIter *iter,
-						   DBusError *error,
-						   void *user_data)
+dbus_bool_t wpas_dbus_getter_p2p_device_config(DBusMessageIter *iter,
+					       DBusError *error,
+					       void *user_data)
 {
 	struct wpa_supplicant *wpa_s = user_data;
 	DBusMessageIter variant_iter, dict_iter;
@@ -782,7 +782,7 @@
 		goto err_no_mem;
 
 	/* Persistent Reconnect */
-	if (!wpa_dbus_dict_append_bool(&dict_iter, "PersistantReconnect",
+	if (!wpa_dbus_dict_append_bool(&dict_iter, "PersistentReconnect",
 				       wpa_s->conf->persistent_reconnect))
 		goto err_no_mem;
 
@@ -839,9 +839,9 @@
 }
 
 
-dbus_bool_t wpas_dbus_setter_p2p_device_properties(DBusMessageIter *iter,
-						   DBusError *error,
-						   void *user_data)
+dbus_bool_t wpas_dbus_setter_p2p_device_config(DBusMessageIter *iter,
+					       DBusError *error,
+					       void *user_data)
 {
 	struct wpa_supplicant *wpa_s = user_data;
 	DBusMessageIter variant_iter, iter_dict;
@@ -927,7 +927,7 @@
 			   (entry.type == DBUS_TYPE_UINT32) &&
 			   (entry.uint32_value <= 15))
 			wpa_s->conf->p2p_go_intent = entry.uint32_value;
-		else if ((os_strcmp(entry.key, "PersistantReconnect") == 0) &&
+		else if ((os_strcmp(entry.key, "PersistentReconnect") == 0) &&
 			 (entry.type == DBUS_TYPE_BOOLEAN))
 			wpa_s->conf->persistent_reconnect = entry.bool_value;
 		else if ((os_strcmp(entry.key, "ListenRegClass") == 0) &&
@@ -1140,13 +1140,18 @@
 				       void *user_data)
 {
 	struct wpa_supplicant *wpa_s = user_data;
+	char path_buf[WPAS_DBUS_OBJECT_PATH_MAX];
+	char *dbus_groupobj_path = path_buf;
 
 	if (wpa_s->dbus_groupobj_path == NULL)
-		return FALSE;
+		os_snprintf(dbus_groupobj_path, WPAS_DBUS_OBJECT_PATH_MAX,
+			    "/");
+	else
+		os_snprintf(dbus_groupobj_path, WPAS_DBUS_OBJECT_PATH_MAX,
+			    "%s", wpa_s->dbus_groupobj_path);
 
 	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
-						&wpa_s->dbus_groupobj_path,
-						error);
+						&dbus_groupobj_path, error);
 }
 
 
@@ -1157,11 +1162,13 @@
 	char go_peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
 
 	if (wpas_get_p2p_role(wpa_s) != WPAS_P2P_ROLE_CLIENT)
-		return FALSE;
-
-	os_snprintf(go_peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
-		    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
-		    wpa_s->dbus_new_path, MAC2STR(wpa_s->go_dev_addr));
+		os_snprintf(go_peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX, "/");
+	else
+		os_snprintf(go_peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
+			    "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
+			    COMPACT_MACSTR,
+			    wpa_s->dbus_new_path, MAC2STR(wpa_s->go_dev_addr));
+
 	path = go_peer_obj_path;
 	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_OBJECT_PATH,
 						&path, error);
@@ -1172,14 +1179,13 @@
  * Peer object properties accessor methods
  */
 
-dbus_bool_t wpas_dbus_getter_p2p_peer_properties(DBusMessageIter *iter,
-	DBusError *error, void *user_data)
+dbus_bool_t wpas_dbus_getter_p2p_peer_device_name(DBusMessageIter *iter,
+						  DBusError *error,
+						  void *user_data)
 {
 	struct peer_handler_args *peer_args = user_data;
-	DBusMessageIter variant_iter, dict_iter;
-	const struct p2p_peer_info *info = NULL;
-	const struct wpabuf *vendor_extension[P2P_MAX_WPS_VENDOR_EXT];
-	int i, num;
+	const struct p2p_peer_info *info;
+	char *tmp;
 
 	if (!wpa_dbus_p2p_check_enabled(peer_args->wpa_s, NULL, NULL, error))
 		return FALSE;
@@ -1188,66 +1194,262 @@
 	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
 				  peer_args->p2p_device_addr, 0);
 	if (info == NULL) {
-		dbus_set_error(error, DBUS_ERROR_FAILED, "failed to find peer");
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+			       "failed to find peer");
+		return FALSE;
+	}
+
+	tmp = os_strdup(info->device_name);
+	if (!tmp) {
+		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+		return FALSE;
+	}
+
+	if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING, &tmp,
+					      error)) {
+		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+		os_free(tmp);
+		return FALSE;
+	}
+
+	os_free(tmp);
+	return TRUE;
+}
+
+
+dbus_bool_t wpas_dbus_getter_p2p_peer_primary_device_type(
+	DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+	struct peer_handler_args *peer_args = user_data;
+	const struct p2p_peer_info *info;
+
+	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
+				  peer_args->p2p_device_addr, 0);
+	if (info == NULL) {
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+			       "failed to find peer");
+		return FALSE;
+	}
+
+	if (!wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
+						    (char *)
+						    info->pri_dev_type,
+						    WPS_DEV_TYPE_LEN, error)) {
+		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+dbus_bool_t wpas_dbus_getter_p2p_peer_config_method(DBusMessageIter *iter,
+                                                    DBusError *error,
+                                                    void *user_data)
+{
+	struct peer_handler_args *peer_args = user_data;
+	const struct p2p_peer_info *info;
+
+	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
+				  peer_args->p2p_device_addr, 0);
+	if (info == NULL) {
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+			       "failed to find peer");
+		return FALSE;
+	}
+
+	if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16,
+					      &info->config_methods, error)) {
+		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+dbus_bool_t wpas_dbus_getter_p2p_peer_level(DBusMessageIter *iter,
+                                            DBusError *error,
+                                            void *user_data)
+{
+	struct peer_handler_args *peer_args = user_data;
+	const struct p2p_peer_info *info;
+
+	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
+				  peer_args->p2p_device_addr, 0);
+	if (info == NULL) {
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+			       "failed to find peer");
+		return FALSE;
+	}
+
+	if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_INT32,
+					      &info->level, error)) {
+		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+dbus_bool_t wpas_dbus_getter_p2p_peer_device_capability(DBusMessageIter *iter,
+                                                        DBusError *error,
+                                                        void *user_data)
+{
+	struct peer_handler_args *peer_args = user_data;
+	const struct p2p_peer_info *info;
+
+	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
+				  peer_args->p2p_device_addr, 0);
+	if (info == NULL) {
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+			       "failed to find peer");
+		return FALSE;
+	}
+
+	if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BYTE,
+					      &info->dev_capab, error)) {
+		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+dbus_bool_t wpas_dbus_getter_p2p_peer_group_capability(DBusMessageIter *iter,
+						       DBusError *error,
+						       void *user_data)
+{
+	struct peer_handler_args *peer_args = user_data;
+	const struct p2p_peer_info *info;
+
+	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
+				  peer_args->p2p_device_addr, 0);
+	if (info == NULL) {
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+			       "failed to find peer");
+		return FALSE;
+	}
+
+	if (!wpas_dbus_simple_property_getter(iter, DBUS_TYPE_BYTE,
+					      &info->group_capab, error)) {
+		dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+dbus_bool_t wpas_dbus_getter_p2p_peer_secondary_device_types(
+	DBusMessageIter *iter, DBusError *error, void *user_data)
+{
+	struct peer_handler_args *peer_args = user_data;
+	const struct p2p_peer_info *info;
+	DBusMessageIter variant_iter, array_iter;
+
+	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
+				  peer_args->p2p_device_addr, 0);
+	if (info == NULL) {
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+			       "failed to find peer");
 		return FALSE;
 	}
 
 	if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
-					      "a{sv}", &variant_iter) ||
-	    !wpa_dbus_dict_open_write(&variant_iter, &dict_iter))
-		goto err_no_mem;
-
-	/* Fill out the dictionary */
-	if (!wpa_dbus_dict_append_string(&dict_iter, "DeviceName",
-					 info->device_name))
-		goto err_no_mem;
-	if (!wpa_dbus_dict_append_byte_array(&dict_iter, "PrimaryDeviceType",
-					     (char *)info->pri_dev_type,
-					     WPS_DEV_TYPE_LEN))
-		goto err_no_mem;
-	if (!wpa_dbus_dict_append_uint16(&dict_iter, "config_method",
-					 info->config_methods))
-		goto err_no_mem;
-	if (!wpa_dbus_dict_append_int32(&dict_iter, "level",
-					info->level))
-		goto err_no_mem;
-	if (!wpa_dbus_dict_append_byte(&dict_iter, "devicecapability",
-				       info->dev_capab))
-		goto err_no_mem;
-	if (!wpa_dbus_dict_append_byte(&dict_iter, "groupcapability",
-				       info->group_capab))
-		goto err_no_mem;
+					      DBUS_TYPE_ARRAY_AS_STRING
+					      DBUS_TYPE_ARRAY_AS_STRING
+					      DBUS_TYPE_BYTE_AS_STRING,
+					      &variant_iter)) {
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+		               "%s: failed to construct message 1", __func__);
+		return FALSE;
+	}
+
+	if (!dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY,
+					      DBUS_TYPE_ARRAY_AS_STRING
+					      DBUS_TYPE_BYTE_AS_STRING,
+					      &array_iter)) {
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+		               "%s: failed to construct message 2", __func__);
+		return FALSE;
+	}
 
 	if (info->wps_sec_dev_type_list_len) {
 		const u8 *sec_dev_type_list = info->wps_sec_dev_type_list;
-		int num_sec_dev_types =
+		int num_sec_device_types =
 			info->wps_sec_dev_type_list_len / WPS_DEV_TYPE_LEN;
-		DBusMessageIter iter_secdev_dict_entry, iter_secdev_dict_val,
-				iter_secdev_dict_array;
-
-		if (num_sec_dev_types) {
-			if (!wpa_dbus_dict_begin_array(&dict_iter,
-						"SecondaryDeviceTypes",
-						DBUS_TYPE_ARRAY_AS_STRING
-						DBUS_TYPE_BYTE_AS_STRING,
-						&iter_secdev_dict_entry,
-						&iter_secdev_dict_val,
-						&iter_secdev_dict_array))
-				goto err_no_mem;
-			for (i = 0; i < num_sec_dev_types; i++) {
-				wpa_dbus_dict_bin_array_add_element(
-						&iter_secdev_dict_array,
-						sec_dev_type_list,
-						WPS_DEV_TYPE_LEN);
-				sec_dev_type_list += WPS_DEV_TYPE_LEN;
+		int i;
+		DBusMessageIter inner_array_iter;
+
+		for (i = 0; i < num_sec_device_types; i++) {
+			if (!dbus_message_iter_open_container(
+				    &array_iter, DBUS_TYPE_ARRAY,
+				    DBUS_TYPE_BYTE_AS_STRING,
+				    &inner_array_iter)) {
+				dbus_set_error(error, DBUS_ERROR_FAILED,
+					       "%s: failed to construct "
+					       "message 3 (%d)",
+					       __func__, i);
+				return FALSE;
 			}
 
-			if (!wpa_dbus_dict_end_array(&dict_iter,
-						&iter_secdev_dict_entry,
-						&iter_secdev_dict_val,
-						&iter_secdev_dict_array))
-				goto err_no_mem;
+			if (!dbus_message_iter_append_fixed_array(
+				    &inner_array_iter, DBUS_TYPE_BYTE,
+				    &sec_dev_type_list, WPS_DEV_TYPE_LEN)) {
+				dbus_set_error(error, DBUS_ERROR_FAILED,
+					       "%s: failed to construct "
+					       "message 4 (%d)",
+					       __func__, i);
+				return FALSE;
+			}
+
+			if (!dbus_message_iter_close_container(
+				    &array_iter, &inner_array_iter)) {
+				dbus_set_error(error, DBUS_ERROR_FAILED,
+					       "%s: failed to construct "
+					       "message 5 (%d)",
+					       __func__, i);
+				return FALSE;
+			}
+
+			sec_dev_type_list += WPS_DEV_TYPE_LEN;
 		}
+	}
+
+	if (!dbus_message_iter_close_container(&variant_iter, &array_iter)) {
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+		               "%s: failed to construct message 6", __func__);
+		return FALSE;
+	}
+
+	if (!dbus_message_iter_close_container(iter, &variant_iter)) {
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+		               "%s: failed to construct message 7", __func__);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+dbus_bool_t wpas_dbus_getter_p2p_peer_vendor_extension(DBusMessageIter *iter,
+						       DBusError *error,
+						       void *user_data)
+{
+	struct wpabuf *vendor_extension[P2P_MAX_WPS_VENDOR_EXT];
+	int i, num;
+	struct peer_handler_args *peer_args = user_data;
+	const struct p2p_peer_info *info;
+
+	info = p2p_get_peer_found(peer_args->wpa_s->global->p2p,
+				  peer_args->p2p_device_addr, 0);
+	if (info == NULL) {
+		dbus_set_error(error, DBUS_ERROR_FAILED,
+			       "failed to find peer");
+		return FALSE;
 	}
 
 	/* Add WPS vendor extensions attribute */
@@ -1258,29 +1460,24 @@
 		num++;
 	}
 
-	if (!wpa_dbus_dict_append_wpabuf_array(&dict_iter, "VendorExtension",
-					       vendor_extension, num))
-		goto err_no_mem;
-
-	if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) ||
-	    !dbus_message_iter_close_container(iter, &variant_iter))
-		goto err_no_mem;
+	if (!wpas_dbus_simple_array_array_property_getter(iter, DBUS_TYPE_BYTE,
+							  vendor_extension,
+							  num, error))
+		return FALSE;
 
 	return TRUE;
-
-err_no_mem:
-	dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
-	return FALSE;
 }
 
 
 dbus_bool_t wpas_dbus_getter_p2p_peer_ies(DBusMessageIter *iter,
 					  DBusError *error, void *user_data)
 {
+	dbus_bool_t success;
 	/* struct peer_handler_args *peer_args = user_data; */
 
-	dbus_set_error_const(error, DBUS_ERROR_FAILED, "not implemented");
-	return FALSE;
+	success = wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
+							 NULL, 0, error);
+	return success;
 }
 
 
@@ -1608,9 +1805,11 @@
 	const u8 *addr;
 	dbus_bool_t success = FALSE;
 
-	/* Ensure we are a GO */
-	if (wpa_s->wpa_state != WPA_COMPLETED)
-		return FALSE;
+	/* Verify correct role for this property */
+	if (wpas_get_p2p_role(wpa_s) != WPAS_P2P_ROLE_GO) {
+		return wpas_dbus_simple_array_property_getter(
+			iter, DBUS_TYPE_OBJECT_PATH, NULL, 0, error);
+	}
 
 	ssid = wpa_s->conf->ssid;
 	/* At present WPAS P2P_GO mode only applicable for p2p_go */
@@ -1658,53 +1857,145 @@
 }
 
 
-dbus_bool_t wpas_dbus_getter_p2p_group_properties(DBusMessageIter *iter,
+dbus_bool_t wpas_dbus_getter_p2p_group_ssid(DBusMessageIter *iter,
+					    DBusError *error, void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	if (wpa_s->current_ssid == NULL)
+		return FALSE;
+	return wpas_dbus_simple_array_property_getter(
+		iter, DBUS_TYPE_BYTE, wpa_s->current_ssid->ssid,
+		wpa_s->current_ssid->ssid_len, error);
+}
+
+
+dbus_bool_t wpas_dbus_getter_p2p_group_bssid(DBusMessageIter *iter,
+					     DBusError *error,
+					     void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	u8 role = wpas_get_p2p_role(wpa_s);
+	u8 *p_bssid;
+
+	if (role == WPAS_P2P_ROLE_CLIENT) {
+		if (wpa_s->current_ssid == NULL)
+			return FALSE;
+		p_bssid = wpa_s->current_ssid->bssid;
+	} else {
+		if (wpa_s->ap_iface == NULL)
+			return FALSE;
+		p_bssid = wpa_s->ap_iface->bss[0]->own_addr;
+	}
+
+	return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
+						      p_bssid, ETH_ALEN,
+						      error);
+}
+
+
+dbus_bool_t wpas_dbus_getter_p2p_group_frequency(DBusMessageIter *iter,
+						 DBusError *error,
+						 void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	u16 op_freq;
+	u8 role = wpas_get_p2p_role(wpa_s);
+
+	if (role == WPAS_P2P_ROLE_CLIENT) {
+		if (wpa_s->go_params == NULL)
+			return FALSE;
+		op_freq = wpa_s->go_params->freq;
+	} else {
+		if (wpa_s->ap_iface == NULL)
+			return FALSE;
+		op_freq = wpa_s->ap_iface->freq;
+	}
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_UINT16,
+						&op_freq, error);
+}
+
+
+dbus_bool_t wpas_dbus_getter_p2p_group_passphrase(DBusMessageIter *iter,
 						  DBusError *error,
 						  void *user_data)
 {
 	struct wpa_supplicant *wpa_s = user_data;
-	DBusMessageIter variant_iter, dict_iter;
-	struct hostapd_data *hapd = wpa_s->ap_iface->bss[0];
-	const struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
+	u8 role = wpas_get_p2p_role(wpa_s);
+	char *p_pass = NULL;
+
+	/* Verify correct role for this property */
+	if (role == WPAS_P2P_ROLE_GO) {
+		if (wpa_s->current_ssid == NULL)
+			return FALSE;
+		p_pass = wpa_s->current_ssid->passphrase;
+	} else
+		p_pass = "";
+
+	return wpas_dbus_simple_property_getter(iter, DBUS_TYPE_STRING,
+						&p_pass, error);
+
+}
+
+
+dbus_bool_t wpas_dbus_getter_p2p_group_psk(DBusMessageIter *iter,
+					   DBusError *error, void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	u8 role = wpas_get_p2p_role(wpa_s);
+	u8 *p_psk = NULL;
+	u8 psk_len = 0;
+
+	/* Verify correct role for this property */
+	if (role == WPAS_P2P_ROLE_CLIENT) {
+		if (wpa_s->current_ssid == NULL)
+			return FALSE;
+		p_psk = wpa_s->current_ssid->psk;
+		psk_len = 32;
+	}
+
+	return wpas_dbus_simple_array_property_getter(iter, DBUS_TYPE_BYTE,
+						      &p_psk, psk_len, error);
+}
+
+
+dbus_bool_t wpas_dbus_getter_p2p_group_vendor_ext(DBusMessageIter *iter,
+						  DBusError *error,
+						  void *user_data)
+{
+	struct wpa_supplicant *wpa_s = user_data;
+	struct hostapd_data *hapd;
+	struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
 	int num_vendor_ext = 0;
 	int i;
 
-	if (!hapd) {
-		dbus_set_error_const(error, DBUS_ERROR_FAILED,
-				     "internal error");
-		return FALSE;
-	}
-
-	if (!dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
-					      "a{sv}", &variant_iter) ||
-	    !wpa_dbus_dict_open_write(&variant_iter, &dict_iter))
-		goto err_no_mem;
-
-	/* Parse WPS Vendor Extensions sent in Beacon/Probe Response */
-	for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
-		if (hapd->conf->wps_vendor_ext[i] == NULL)
-			continue;
-		vendor_ext[num_vendor_ext++] = hapd->conf->wps_vendor_ext[i];
-	}
-
-	if (!wpa_dbus_dict_append_wpabuf_array(&dict_iter,
-					       "WPSVendorExtensions",
-					       vendor_ext, num_vendor_ext))
-		goto err_no_mem;
-
-	if (!wpa_dbus_dict_close_write(&variant_iter, &dict_iter) ||
-	    !dbus_message_iter_close_container(iter, &variant_iter))
-		goto err_no_mem;
-
-	return TRUE;
-
-err_no_mem:
-	dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, "no memory");
-	return FALSE;
-}
-
-
-dbus_bool_t wpas_dbus_setter_p2p_group_properties(DBusMessageIter *iter,
+	/* Verify correct role for this property */
+	if (wpas_get_p2p_role(wpa_s) == WPAS_P2P_ROLE_GO) {
+		if (wpa_s->ap_iface == NULL)
+			return FALSE;
+		hapd = wpa_s->ap_iface->bss[0];
+
+		/* Parse WPS Vendor Extensions sent in Beacon/Probe Response */
+		for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
+			if (hapd->conf->wps_vendor_ext[i] == NULL)
+				vendor_ext[i] = NULL;
+			else {
+				vendor_ext[num_vendor_ext++] =
+					hapd->conf->wps_vendor_ext[i];
+			}
+		}
+	}
+
+	/* Return vendor extensions or no data */
+	return wpas_dbus_simple_array_array_property_getter(iter,
+							    DBUS_TYPE_BYTE,
+							    vendor_ext,
+							    num_vendor_ext,
+						 error);
+}
+
+
+dbus_bool_t wpas_dbus_setter_p2p_group_vendor_ext(DBusMessageIter *iter,
 						  DBusError *error,
 						  void *user_data)
 {
@@ -1712,13 +2003,13 @@
 	DBusMessageIter variant_iter, iter_dict;
 	struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
 	unsigned int i;
-	struct hostapd_data *hapd = wpa_s->ap_iface->bss[0];
-
-	if (!hapd) {
-		dbus_set_error_const(error, DBUS_ERROR_FAILED,
-				     "internal error");
-		return FALSE;
-	}
+	struct hostapd_data *hapd = NULL;
+
+	if (wpas_get_p2p_role(wpa_s) == WPAS_P2P_ROLE_GO &&
+	    wpa_s->ap_iface != NULL)
+		hapd = wpa_s->ap_iface->bss[0];
+	else
+		return FALSE;
 
 	dbus_message_iter_recurse(iter, &variant_iter);
 	if (!wpa_dbus_dict_open_read(&variant_iter, &iter_dict, error))
@@ -1974,7 +2265,7 @@
 	struct wpabuf *tlv = NULL;
 	u8 version = 0;
 	u64 ref = 0;
-	u8 addr[ETH_ALEN];
+	u8 addr_buf[ETH_ALEN], *addr;
 
 	dbus_message_iter_init(message, &iter);
 
@@ -2011,10 +2302,15 @@
 		wpa_dbus_dict_entry_clear(&entry);
 	}
 
-	if (!peer_object_path ||
-	    (parse_peer_object_path(peer_object_path, addr) < 0) ||
-	    !p2p_peer_known(wpa_s->global->p2p, addr))
-		goto error;
+	if (!peer_object_path) {
+		addr = NULL;
+	} else {
+		if (parse_peer_object_path(peer_object_path, addr_buf) < 0 ||
+		    !p2p_peer_known(wpa_s->global->p2p, addr_buf))
+			goto error;
+
+		addr = addr_buf;
+	}
 
 	if (upnp == 1) {
 		if (version <= 0 || service == NULL)

Modified: wpa/trunk/wpa_supplicant/dbus/dbus_new_handlers_p2p.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/dbus/dbus_new_handlers_p2p.h?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/dbus/dbus_new_handlers_p2p.h (original)
+++ wpa/trunk/wpa_supplicant/dbus/dbus_new_handlers_p2p.h Tue Apr 17 11:03:56 2012
@@ -94,13 +94,13 @@
 /*
  * P2P Device property accessor methods.
  */
-dbus_bool_t wpas_dbus_setter_p2p_device_properties(DBusMessageIter *iter,
-						   DBusError *error,
-						   void *user_data);
-
-dbus_bool_t wpas_dbus_getter_p2p_device_properties(DBusMessageIter *iter,
-						   DBusError *error,
-						   void *user_data);
+dbus_bool_t wpas_dbus_setter_p2p_device_config(DBusMessageIter *iter,
+					       DBusError *error,
+					       void *user_data);
+
+dbus_bool_t wpas_dbus_getter_p2p_device_config(DBusMessageIter *iter,
+					       DBusError *error,
+					       void *user_data);
 
 dbus_bool_t wpas_dbus_getter_p2p_peers(DBusMessageIter *iter, DBusError *error,
 				       void *user_data);
@@ -118,9 +118,36 @@
 /*
  * P2P Peer properties.
  */
-dbus_bool_t wpas_dbus_getter_p2p_peer_properties(DBusMessageIter *iter,
-						 DBusError *error,
-						 void *user_data);
+
+dbus_bool_t wpas_dbus_getter_p2p_peer_device_name(DBusMessageIter *iter,
+                                                  DBusError *error,
+                                                  void *user_data);
+
+dbus_bool_t wpas_dbus_getter_p2p_peer_primary_device_type(
+	DBusMessageIter *iter, DBusError *error, void *user_data);
+
+dbus_bool_t wpas_dbus_getter_p2p_peer_config_method(DBusMessageIter *iter,
+                                                    DBusError *error,
+                                                    void *user_data);
+
+dbus_bool_t wpas_dbus_getter_p2p_peer_level(DBusMessageIter *iter,
+                                            DBusError *error,
+                                            void *user_data);
+
+dbus_bool_t wpas_dbus_getter_p2p_peer_device_capability(DBusMessageIter *iter,
+                                                        DBusError *error,
+                                                        void *user_data);
+
+dbus_bool_t wpas_dbus_getter_p2p_peer_group_capability(DBusMessageIter *iter,
+                                                       DBusError *error,
+                                                       void *user_data);
+
+dbus_bool_t wpas_dbus_getter_p2p_peer_secondary_device_types(
+	DBusMessageIter *iter, DBusError *error, void *user_data);
+
+dbus_bool_t wpas_dbus_getter_p2p_peer_vendor_extension(DBusMessageIter *iter,
+                                                       DBusError *error,
+                                                       void *user_data);
 
 dbus_bool_t wpas_dbus_getter_p2p_peer_ies(DBusMessageIter *iter,
 					  DBusError *error,
@@ -134,11 +161,31 @@
 					       DBusError *error,
 					       void *user_data);
 
-dbus_bool_t wpas_dbus_getter_p2p_group_properties(DBusMessageIter *iter,
+dbus_bool_t wpas_dbus_getter_p2p_group_ssid(DBusMessageIter *iter,
+					    DBusError *error,
+					    void *user_data);
+
+dbus_bool_t wpas_dbus_getter_p2p_group_bssid(DBusMessageIter *iter,
+					     DBusError *error,
+					     void *user_data);
+
+dbus_bool_t wpas_dbus_getter_p2p_group_frequency(DBusMessageIter *iter,
+						 DBusError *error,
+						 void *user_data);
+
+dbus_bool_t wpas_dbus_getter_p2p_group_passphrase(DBusMessageIter *iter,
 						  DBusError *error,
 						  void *user_data);
 
-dbus_bool_t wpas_dbus_setter_p2p_group_properties(DBusMessageIter *iter,
+dbus_bool_t wpas_dbus_getter_p2p_group_psk(DBusMessageIter *iter,
+					   DBusError *error,
+					   void *user_data);
+
+dbus_bool_t wpas_dbus_getter_p2p_group_vendor_ext(DBusMessageIter *iter,
+						  DBusError *error,
+						  void *user_data);
+
+dbus_bool_t wpas_dbus_setter_p2p_group_vendor_ext(DBusMessageIter *iter,
 						  DBusError *error,
 						  void *user_data);
 

Modified: wpa/trunk/wpa_supplicant/defconfig
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/defconfig?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/defconfig (original)
+++ wpa/trunk/wpa_supplicant/defconfig Tue Apr 17 11:03:56 2012
@@ -165,6 +165,9 @@
 # EAP-PSK (experimental; this is _not_ needed for WPA-PSK)
 #CONFIG_EAP_PSK=y
 
+# EAP-pwd (secure authentication using only a password)
+#CONFIG_EAP_PWD=y
+
 # EAP-PAX
 #CONFIG_EAP_PAX=y
 
@@ -408,7 +411,7 @@
 # This tracks use of memory allocations and other registrations and reports
 # incorrect use with a backtrace of call (or allocation) location.
 #CONFIG_WPA_TRACE=y
-# For BSD, comment out these.
+# For BSD, uncomment these.
 #LIBS += -lexecinfo
 #LIBS_p += -lexecinfo
 #LIBS_c += -lexecinfo
@@ -417,7 +420,7 @@
 # This enables use of libbfd to get more detailed symbols for the backtraces
 # generated by CONFIG_WPA_TRACE=y.
 #CONFIG_WPA_TRACE_BFD=y
-# For BSD, comment out these.
+# For BSD, uncomment these.
 #LIBS += -lbfd -liberty -lz
 #LIBS_p += -lbfd -liberty -lz
 #LIBS_c += -lbfd -liberty -lz

Modified: wpa/trunk/wpa_supplicant/driver_i.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/driver_i.h?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/driver_i.h (original)
+++ wpa/trunk/wpa_supplicant/driver_i.h Tue Apr 17 11:03:56 2012
@@ -433,6 +433,13 @@
 	return 0;
 }
 
+static inline int wpa_drv_deinit_p2p_cli(struct wpa_supplicant *wpa_s)
+{
+	if (wpa_s->driver->deinit_p2p_cli)
+		return wpa_s->driver->deinit_p2p_cli(wpa_s->drv_priv);
+	return 0;
+}
+
 static inline void wpa_drv_suspend(struct wpa_supplicant *wpa_s)
 {
 	if (wpa_s->driver->suspend)

Modified: wpa/trunk/wpa_supplicant/eapol_test.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/eapol_test.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/eapol_test.c (original)
+++ wpa/trunk/wpa_supplicant/eapol_test.c Tue Apr 17 11:03:56 2012
@@ -284,7 +284,9 @@
 		}
 	}
 
-	radius_client_send(e->radius, msg, RADIUS_AUTH, e->wpa_s->own_addr);
+	if (radius_client_send(e->radius, msg, RADIUS_AUTH, e->wpa_s->own_addr)
+	    < 0)
+		goto fail;
 	return;
 
  fail:

Modified: wpa/trunk/wpa_supplicant/events.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/events.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/events.c (original)
+++ wpa/trunk/wpa_supplicant/events.c Tue Apr 17 11:03:56 2012
@@ -1736,11 +1736,13 @@
 			wpa_msg(wpa_s, MSG_INFO, "Failed to initialize the "
 				"driver after interface was added");
 		}
+		wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
 		break;
 	case EVENT_INTERFACE_REMOVED:
 		wpa_dbg(wpa_s, MSG_DEBUG, "Configured interface was removed");
 		wpa_s->interface_removed = 1;
 		wpa_supplicant_mark_disassoc(wpa_s);
+		wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
 		l2_packet_deinit(wpa_s->l2);
 		wpa_s->l2 = NULL;
 #ifdef CONFIG_IBSS_RSN
@@ -2411,6 +2413,11 @@
 	case EVENT_CHANNEL_LIST_CHANGED:
 		if (wpa_s->drv_priv == NULL)
 			break; /* Ignore event during drv initialization */
+
+		free_hw_features(wpa_s);
+		wpa_s->hw.modes = wpa_drv_get_hw_feature_data(
+			wpa_s, &wpa_s->hw.num_modes, &wpa_s->hw.flags);
+
 #ifdef CONFIG_P2P
 		wpas_p2p_update_channel_list(wpa_s);
 #endif /* CONFIG_P2P */

Modified: wpa/trunk/wpa_supplicant/interworking.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/interworking.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/interworking.c (original)
+++ wpa/trunk/wpa_supplicant/interworking.c Tue Apr 17 11:03:56 2012
@@ -726,8 +726,8 @@
 				goto fail;
 			break;
 		case NAI_REALM_INNER_NON_EAP_MSCHAP:
-			if (wpa_config_set(ssid, "phase2", "\"auth=CHAP\"", 0)
-			    < 0)
+			if (wpa_config_set(ssid, "phase2", "\"auth=MSCHAP\"",
+					   0) < 0)
 				goto fail;
 			break;
 		case NAI_REALM_INNER_NON_EAP_MSCHAPV2:

Modified: wpa/trunk/wpa_supplicant/notify.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/notify.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/notify.c (original)
+++ wpa/trunk/wpa_supplicant/notify.c Tue Apr 17 11:03:56 2012
@@ -88,7 +88,7 @@
 #ifdef CONFIG_P2P
 	if (new_state == WPA_COMPLETED)
 		wpas_p2p_notif_connected(wpa_s);
-	else if (new_state < WPA_ASSOCIATED)
+	else if (old_state >= WPA_ASSOCIATED && new_state < WPA_ASSOCIATED)
 		wpas_p2p_notif_disconnected(wpa_s);
 #endif /* CONFIG_P2P */
 
@@ -525,9 +525,12 @@
 
 
 static void wpas_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
-					  const u8 *sta)
+					  const u8 *sta,
+					  const u8 *p2p_dev_addr)
 {
 #ifdef CONFIG_P2P
+	wpas_p2p_notify_ap_sta_authorized(wpa_s, p2p_dev_addr);
+
 	/*
 	 * Register a group member object corresponding to this peer and
 	 * emit a PeerJoined signal. This will check if it really is a
@@ -564,10 +567,11 @@
 
 
 void wpas_notify_sta_authorized(struct wpa_supplicant *wpa_s,
-				const u8 *mac_addr, int authorized)
+				const u8 *mac_addr, int authorized,
+				const u8 *p2p_dev_addr)
 {
 	if (authorized)
-		wpas_notify_ap_sta_authorized(wpa_s, mac_addr);
+		wpas_notify_ap_sta_authorized(wpa_s, mac_addr, p2p_dev_addr);
 	else
 		wpas_notify_ap_sta_deauthorized(wpa_s, mac_addr);
 }

Modified: wpa/trunk/wpa_supplicant/notify.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/notify.h?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/notify.h (original)
+++ wpa/trunk/wpa_supplicant/notify.h Tue Apr 17 11:03:56 2012
@@ -86,7 +86,8 @@
 void wpas_notify_resume(struct wpa_global *global);
 
 void wpas_notify_sta_authorized(struct wpa_supplicant *wpa_s,
-				const u8 *mac_addr, int authorized);
+				const u8 *mac_addr, int authorized,
+				const u8 *p2p_dev_addr);
 void wpas_notify_p2p_device_found(struct wpa_supplicant *wpa_s,
 				  const u8 *dev_addr, int new_device);
 void wpas_notify_p2p_device_lost(struct wpa_supplicant *wpa_s,

Modified: wpa/trunk/wpa_supplicant/p2p_supplicant.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/p2p_supplicant.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/p2p_supplicant.c (original)
+++ wpa/trunk/wpa_supplicant/p2p_supplicant.c Tue Apr 17 11:03:56 2012
@@ -62,6 +62,8 @@
 static void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx);
 static int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr,
 			 const u8 *dev_addr, enum p2p_wps_method wps_method);
+static void wpas_p2p_pd_before_join_timeout(void *eloop_ctx,
+					    void *timeout_ctx);
 static int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s);
 static void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s);
 static void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx);
@@ -216,8 +218,6 @@
 	struct wpa_ssid *ssid;
 	char *gtype;
 	const char *reason;
-
-	eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL);
 
 	ssid = wpa_s->current_ssid;
 	if (ssid == NULL) {
@@ -267,6 +267,8 @@
 	}
 	wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_REMOVED "%s %s%s",
 		wpa_s->ifname, gtype, reason);
+
+	eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL);
 
 	if (ssid)
 		wpas_notify_p2p_group_removed(wpa_s, ssid, gtype);
@@ -314,7 +316,10 @@
 		wpa_printf(MSG_DEBUG, "P2P: Temporary group network not "
 			   "found");
 	}
-	wpa_supplicant_ap_deinit(wpa_s);
+	if (wpa_s->ap_iface)
+		wpa_supplicant_ap_deinit(wpa_s);
+	else
+		wpa_drv_deinit_p2p_cli(wpa_s);
 }
 
 
@@ -463,6 +468,52 @@
 #endif /* CONFIG_NO_CONFIG_WRITE */
 
 	return s->id;
+}
+
+
+static void wpas_p2p_add_persistent_group_client(struct wpa_supplicant *wpa_s,
+						 const u8 *addr)
+{
+	struct wpa_ssid *ssid, *s;
+	u8 *n;
+	size_t i;
+
+	ssid = wpa_s->current_ssid;
+	if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
+	    !ssid->p2p_persistent_group)
+		return;
+
+	for (s = wpa_s->parent->conf->ssid; s; s = s->next) {
+		if (s->disabled != 2 || s->mode != WPAS_MODE_P2P_GO)
+			continue;
+
+		if (s->ssid_len == ssid->ssid_len &&
+		    os_memcmp(s->ssid, ssid->ssid, s->ssid_len) == 0)
+			break;
+	}
+
+	if (s == NULL)
+		return;
+
+	for (i = 0; s->p2p_client_list && i < s->num_p2p_clients; i++) {
+		if (os_memcmp(s->p2p_client_list + i * ETH_ALEN, addr,
+			      ETH_ALEN) == 0)
+			return; /* already in list */
+	}
+
+	n = os_realloc(s->p2p_client_list,
+		       (s->num_p2p_clients + 1) * ETH_ALEN);
+	if (n == NULL)
+		return;
+	os_memcpy(n + s->num_p2p_clients * ETH_ALEN, addr, ETH_ALEN);
+	s->p2p_client_list = n;
+	s->num_p2p_clients++;
+
+#ifndef CONFIG_NO_CONFIG_WRITE
+	if (wpa_s->parent->conf->update_config &&
+	    wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf))
+		wpa_printf(MSG_DEBUG, "P2P: Failed to update configuration");
+#endif /* CONFIG_NO_CONFIG_WRITE */
 }
 
 
@@ -592,12 +643,14 @@
 
 	p2p_send_action_cb(wpa_s->global->p2p, freq, dst, src, bssid, res);
 
-	if (wpa_s->pending_pd_before_join &&
+	if (result != OFFCHANNEL_SEND_ACTION_SUCCESS &&
+	    wpa_s->pending_pd_before_join &&
 	    (os_memcmp(dst, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 ||
 	     os_memcmp(dst, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0)) {
 		wpa_s->pending_pd_before_join = 0;
 		wpa_printf(MSG_DEBUG, "P2P: Starting pending "
-			   "join-existing-group operation");
+			   "join-existing-group operation (no ACK for PD "
+			   "Req)");
 		wpas_p2p_join_start(wpa_s);
 	}
 }
@@ -1759,6 +1812,16 @@
 	struct wpa_supplicant *wpa_s = ctx;
 	unsigned int generated_pin = 0;
 
+	if (wpa_s->pending_pd_before_join &&
+	    (os_memcmp(peer, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 ||
+	     os_memcmp(peer, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0)) {
+		wpa_s->pending_pd_before_join = 0;
+		wpa_printf(MSG_DEBUG, "P2P: Starting pending "
+			   "join-existing-group operation");
+		wpas_p2p_join_start(wpa_s);
+		return;
+	}
+
 	if (config_methods & WPS_CONFIG_DISPLAY)
 		wpas_prov_disc_local_keypad(wpa_s, peer, "");
 	else if (config_methods & WPS_CONFIG_KEYPAD) {
@@ -1771,15 +1834,6 @@
 	wpas_notify_p2p_provision_discovery(wpa_s, peer, 0 /* response */,
 					    P2P_PROV_DISC_SUCCESS,
 					    config_methods, generated_pin);
-
-	if (wpa_s->pending_pd_before_join &&
-	    (os_memcmp(peer, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 ||
-	     os_memcmp(peer, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0)) {
-		wpa_s->pending_pd_before_join = 0;
-		wpa_printf(MSG_DEBUG, "P2P: Starting pending "
-			   "join-existing-group operation");
-		wpas_p2p_join_start(wpa_s);
-	}
 }
 
 
@@ -2168,7 +2222,8 @@
 			continue;
 		if (ssid->mode != WPAS_MODE_INFRA)
 			continue;
-		if (wpa_s->wpa_state != WPA_COMPLETED)
+		if (wpa_s->wpa_state != WPA_COMPLETED &&
+		    wpa_s->wpa_state != WPA_GROUP_HANDSHAKE)
 			continue;
 		if (os_memcmp(wpa_s->go_dev_addr, dev_addr, ETH_ALEN) == 0)
 			return 1;
@@ -2346,10 +2401,19 @@
 {
 	if (wpa_s->driver && wpa_s->drv_priv)
 		wpa_drv_probe_req_report(wpa_s, 0);
+
+	if (wpa_s->go_params) {
+		/* Clear any stored provisioning info */
+		p2p_clear_provisioning_info(
+			wpa_s->global->p2p,
+			wpa_s->go_params->peer_device_addr);
+	}
+
 	os_free(wpa_s->go_params);
 	wpa_s->go_params = NULL;
 	eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
 	eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
+	eloop_cancel_timeout(wpas_p2p_pd_before_join_timeout, wpa_s, NULL);
 	wpa_s->p2p_long_listen = 0;
 	eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
 	eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL);
@@ -2369,7 +2433,6 @@
 void wpas_p2p_deinit_global(struct wpa_global *global)
 {
 	struct wpa_supplicant *wpa_s, *tmp;
-	char *ifname;
 
 	if (global->p2p == NULL)
 		return;
@@ -2390,12 +2453,9 @@
 		}
 		if (tmp == NULL)
 			break;
-		ifname = os_strdup(tmp->ifname);
 		type = wpas_p2p_if_type(tmp->p2p_group_interface);
-		wpa_supplicant_remove_iface(global, tmp);
-		if (ifname)
-			wpa_drv_if_remove(wpa_s, type, ifname);
-		os_free(ifname);
+		/* Disconnect from the P2P group and deinit the interface */
+		wpas_p2p_disconnect(tmp);
 	}
 
 	/*
@@ -2481,6 +2541,21 @@
 		wpa_msg(wpa_s->parent, MSG_INFO,
 			P2P_EVENT_GROUP_FORMATION_FAILURE);
 	}
+}
+
+
+static void wpas_p2p_pd_before_join_timeout(void *eloop_ctx, void *timeout_ctx)
+{
+	struct wpa_supplicant *wpa_s = eloop_ctx;
+	if (!wpa_s->pending_pd_before_join)
+		return;
+	/*
+	 * Provision Discovery Response may have been lost - try to connect
+	 * anyway since we do not need any information from this PD.
+	 */
+	wpa_printf(MSG_DEBUG, "P2P: PD timeout for join-existing-group - "
+		   "try to connect anyway");
+	wpas_p2p_join_start(wpa_s);
 }
 
 
@@ -2555,6 +2630,21 @@
 			break;
 		}
 
+		if ((p2p_get_provisioning_info(wpa_s->global->p2p,
+					       wpa_s->pending_join_dev_addr) ==
+		     method)) {
+			/*
+			 * We have already performed provision discovery for
+			 * joining the group. Proceed directly to join
+			 * operation without duplicated provision discovery. */
+			wpa_printf(MSG_DEBUG, "P2P: Provisioning discovery "
+				   "with " MACSTR " already done - proceed to "
+				   "join",
+				   MAC2STR(wpa_s->pending_join_dev_addr));
+			wpa_s->pending_pd_before_join = 0;
+			goto start;
+		}
+
 		if (p2p_prov_disc_req(wpa_s->global->p2p,
 				      wpa_s->pending_join_dev_addr, method, 1,
 				      freq) < 0) {
@@ -2567,8 +2657,15 @@
 
 		/*
 		 * Actual join operation will be started from the Action frame
-		 * TX status callback.
+		 * TX status callback (if no ACK is received) or when the
+		 * Provision Discovery Response is received. Use a short
+		 * timeout as a backup mechanism should the Provision Discovery
+		 * Response be lost for any reason.
 		 */
+		eloop_cancel_timeout(wpas_p2p_pd_before_join_timeout, wpa_s,
+				     NULL);
+		eloop_register_timeout(2, 0, wpas_p2p_pd_before_join_timeout,
+				       wpa_s, NULL);
 		return;
 	}
 
@@ -2667,6 +2764,7 @@
 	struct wpa_supplicant *group;
 	struct p2p_go_neg_results res;
 
+	eloop_cancel_timeout(wpas_p2p_pd_before_join_timeout, wpa_s, NULL);
 	group = wpas_p2p_get_group_iface(wpa_s, 0, 0);
 	if (group == NULL)
 		return -1;
@@ -3140,6 +3238,13 @@
 
 	if (wpas_p2p_init_go_params(wpa_s, &params, freq))
 		return -1;
+	if (params.freq &&
+	    !p2p_supported_freq(wpa_s->global->p2p, params.freq)) {
+		wpa_printf(MSG_DEBUG, "P2P: The selected channel for GO "
+			   "(%u MHz) is not supported for P2P uses",
+			   params.freq);
+		return -1;
+	}
 	p2p_go_params(wpa_s->global->p2p, &params);
 	params.persistent_group = persistent_group;
 
@@ -3329,10 +3434,21 @@
 void wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
 			  int registrar)
 {
+	struct wpa_ssid *ssid = wpa_s->current_ssid;
+
 	if (!wpa_s->p2p_in_provisioning) {
 		wpa_printf(MSG_DEBUG, "P2P: Ignore WPS success event - P2P "
 			   "provisioning not in progress");
 		return;
+	}
+
+	if (ssid && ssid->mode == WPAS_MODE_INFRA) {
+		u8 go_dev_addr[ETH_ALEN];
+		os_memcpy(go_dev_addr, wpa_s->bssid, ETH_ALEN);
+		wpas_p2p_persistent_group(wpa_s, go_dev_addr, ssid->ssid,
+					  ssid->ssid_len);
+		/* Clear any stored provisioning info */
+		p2p_clear_provisioning_info(wpa_s->global->p2p, go_dev_addr);
 	}
 
 	eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s->parent,
@@ -3353,6 +3469,13 @@
 			   "provisioning not in progress");
 		return;
 	}
+
+	if (wpa_s->go_params) {
+		p2p_clear_provisioning_info(
+			wpa_s->global->p2p,
+			wpa_s->go_params->peer_device_addr);
+	}
+
 	wpas_notify_p2p_wps_failed(wpa_s, fail);
 }
 
@@ -3634,6 +3757,7 @@
 	enum p2p_invite_role role;
 	u8 *bssid = NULL;
 	struct wpa_ssid *ssid;
+	int persistent;
 
 	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
 		if (os_strcmp(wpa_s->ifname, ifname) == 0)
@@ -3650,6 +3774,10 @@
 			   "invitation");
 		return -1;
 	}
+
+	persistent = ssid->p2p_persistent_group &&
+		wpas_p2p_get_persistent(wpa_s->parent, peer_addr,
+					ssid->ssid, ssid->ssid_len);
 
 	if (ssid->mode == WPAS_MODE_P2P_GO) {
 		role = P2P_INVITE_ROLE_ACTIVE_GO;
@@ -3673,14 +3801,14 @@
 	if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)
 		return wpa_drv_p2p_invite(wpa_s, peer_addr, role, bssid,
 					  ssid->ssid, ssid->ssid_len,
-					  go_dev_addr, 0);
+					  go_dev_addr, persistent);
 
 	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
 		return -1;
 
 	return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid,
 			  ssid->ssid, ssid->ssid_len, wpa_s->assoc_freq,
-			  go_dev_addr, 0);
+			  go_dev_addr, persistent);
 }
 
 
@@ -3811,6 +3939,17 @@
 
 	if (timeout == 0)
 		return;
+
+	if (wpa_s->p2p_in_provisioning) {
+		/*
+		 * Use the normal group formation timeout during the
+		 * provisioning phase to avoid terminating this process too
+		 * early due to group idle timeout.
+		 */
+		wpa_printf(MSG_DEBUG, "P2P: Do not use P2P group idle timeout "
+			   "during provisioning");
+		return;
+	}
 
 	wpa_printf(MSG_DEBUG, "P2P: Set P2P group idle timeout to %u seconds",
 		   timeout);
@@ -3955,6 +4094,14 @@
 			wpa_printf(MSG_ERROR, "P2P: Own oper channel update "
 				   "failed: %d", ret);
 	}
+
+	if (wpa_s->conf->changed_parameters & CFG_CHANGED_P2P_PREF_CHAN) {
+		if (p2p_set_pref_chan(p2p, wpa_s->conf->num_p2p_pref_chan,
+				      wpa_s->conf->p2p_pref_chan) < 0) {
+			wpa_printf(MSG_ERROR, "P2P: Preferred channel list "
+				   "update failed");
+		}
+	}
 }
 
 
@@ -4166,6 +4313,7 @@
 		wpa_printf(MSG_DEBUG, "P2P: Unauthorize pending GO Neg peer "
 			   MACSTR, MAC2STR(peer));
 		p2p_unauthorize(global->p2p, peer);
+		found = 1;
 	}
 
 	wpas_p2p_stop_find(wpa_s);
@@ -4267,28 +4415,60 @@
 
 void wpas_p2p_network_removed(struct wpa_supplicant *wpa_s,
 			      struct wpa_ssid *ssid)
-
 {
 	if (wpa_s->p2p_in_provisioning && ssid->p2p_group &&
 	    eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
 				 wpa_s->parent, NULL) > 0) {
+		/**
+		 * Remove the network by scheduling the group formation
+		 * timeout to happen immediately. The teardown code
+		 * needs to be scheduled to run asynch later so that we
+		 * don't delete data from under ourselves unexpectedly.
+		 * Calling wpas_p2p_group_formation_timeout directly
+		 * causes a series of crashes in WPS failure scenarios.
+		 */
 		wpa_printf(MSG_DEBUG, "P2P: Canceled group formation due to "
 			   "P2P group network getting removed");
-		wpas_p2p_group_formation_timeout(wpa_s->parent, NULL);
+		eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout,
+				       wpa_s->parent, NULL);
 	}
 }
 
 
 struct wpa_ssid * wpas_p2p_get_persistent(struct wpa_supplicant *wpa_s,
-					  const u8 *addr)
+					  const u8 *addr, const u8 *ssid,
+					  size_t ssid_len)
 {
 	struct wpa_ssid *s;
+	size_t i;
 
 	for (s = wpa_s->conf->ssid; s; s = s->next) {
-		if (s->disabled == 2 &&
-		    os_memcmp(s->bssid, addr, ETH_ALEN) == 0)
-			return s;
+		if (s->disabled != 2)
+			continue;
+		if (ssid &&
+		    (ssid_len != s->ssid_len ||
+		     os_memcmp(ssid, s->ssid, ssid_len) != 0))
+			continue;
+		if (os_memcmp(s->bssid, addr, ETH_ALEN) == 0)
+			return s; /* peer is GO in the persistent group */
+		if (s->mode != WPAS_MODE_P2P_GO || s->p2p_client_list == NULL)
+			continue;
+		for (i = 0; i < s->num_p2p_clients; i++) {
+			if (os_memcmp(s->p2p_client_list + i * ETH_ALEN,
+				      addr, ETH_ALEN) == 0)
+				return s; /* peer is P2P client in persistent
+					   * group */
+		}
 	}
 
 	return NULL;
 }
+
+
+void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
+				       const u8 *addr)
+{
+	if (addr == NULL)
+		return;
+	wpas_p2p_add_persistent_group_client(wpa_s, addr);
+}

Modified: wpa/trunk/wpa_supplicant/p2p_supplicant.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/p2p_supplicant.h?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/p2p_supplicant.h (original)
+++ wpa/trunk/wpa_supplicant/p2p_supplicant.h Tue Apr 17 11:03:56 2012
@@ -133,6 +133,9 @@
 void wpas_p2p_network_removed(struct wpa_supplicant *wpa_s,
 			      struct wpa_ssid *ssid);
 struct wpa_ssid * wpas_p2p_get_persistent(struct wpa_supplicant *wpa_s,
-					  const u8 *addr);
+					  const u8 *addr, const u8 *ssid,
+					  size_t ssid_len);
+void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
+				       const u8 *addr);
 
 #endif /* P2P_SUPPLICANT_H */

Modified: wpa/trunk/wpa_supplicant/scan.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/scan.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/scan.c (original)
+++ wpa/trunk/wpa_supplicant/scan.c Tue Apr 17 11:03:56 2012
@@ -71,10 +71,12 @@
 	}
 
 #ifdef CONFIG_P2P
-	wpa_s->wps->dev.p2p = 1;
-	if (!wps) {
-		wps = 1;
-		*req_type = WPS_REQ_ENROLLEE_INFO;
+	if (!wpa_s->global->p2p_disabled && wpa_s->global->p2p) {
+		wpa_s->wps->dev.p2p = 1;
+		if (!wps) {
+			wps = 1;
+			*req_type = WPS_REQ_ENROLLEE_INFO;
+		}
 	}
 #endif /* CONFIG_P2P */
 

Modified: wpa/trunk/wpa_supplicant/sme.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/sme.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/sme.c (original)
+++ wpa/trunk/wpa_supplicant/sme.c Tue Apr 17 11:03:56 2012
@@ -275,8 +275,8 @@
 	if (wpa_drv_authenticate(wpa_s, &params) < 0) {
 		wpa_msg(wpa_s, MSG_INFO, "SME: Authentication request to the "
 			"driver failed");
-		wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
 		wpas_connection_failed(wpa_s, bss->bssid);
+		wpa_supplicant_mark_disassoc(wpa_s);
 		return;
 	}
 
@@ -514,6 +514,7 @@
 {
 	wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication timed out");
 	wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
+	wpa_supplicant_mark_disassoc(wpa_s);
 }
 
 

Modified: wpa/trunk/wpa_supplicant/wpa_supplicant.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/wpa_supplicant.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/wpa_supplicant.c (original)
+++ wpa/trunk/wpa_supplicant/wpa_supplicant.c Tue Apr 17 11:03:56 2012
@@ -1,6 +1,6 @@
 /*
  * WPA Supplicant
- * Copyright (c) 2003-2011, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2003-2012, Jouni Malinen <j at w1.fi>
  *
  * 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
@@ -370,7 +370,7 @@
 }
 
 
-static void free_hw_features(struct wpa_supplicant *wpa_s)
+void free_hw_features(struct wpa_supplicant *wpa_s)
 {
 	int i;
 	if (wpa_s->hw.modes == NULL)
@@ -1284,11 +1284,10 @@
 		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);
+		res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
+					    ssid->p2p_group);
 		if (res >= 0)
 			wpa_ie_len += res;
 	}
@@ -1669,10 +1668,13 @@
 {
 
 	struct wpa_ssid *other_ssid;
-
-	if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid)
+	int disconnected = 0;
+
+	if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
 		wpa_supplicant_disassociate(
 			wpa_s, WLAN_REASON_DEAUTH_LEAVING);
+		disconnected = 1;
+	}
 
 	/*
 	 * Mark all other networks disabled or mark all networks enabled if no
@@ -1700,7 +1702,7 @@
 	wpa_s->connect_without_scan = NULL;
 	wpa_s->disconnected = 0;
 	wpa_s->reassociate = 1;
-	wpa_supplicant_req_scan(wpa_s, 0, 0);
+	wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
 
 	if (ssid)
 		wpas_notify_network_selected(wpa_s, ssid);
@@ -1941,8 +1943,11 @@
 		for (i = 0; wpa_drivers[i]; i++) {
 			if (os_strlen(wpa_drivers[i]->name) == len &&
 			    os_strncmp(driver, wpa_drivers[i]->name, len) ==
-			    0)
-				return select_driver(wpa_s, i);
+			    0) {
+				/* First driver that succeeds wins */
+				if (select_driver(wpa_s, i) == 0)
+					return 0;
+			}
 		}
 
 		driver = pos + 1;

Modified: wpa/trunk/wpa_supplicant/wpa_supplicant_i.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/wpa_supplicant_i.h?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/wpa_supplicant_i.h (original)
+++ wpa/trunk/wpa_supplicant/wpa_supplicant_i.h Tue Apr 17 11:03:56 2012
@@ -558,6 +558,7 @@
 int wpa_supplicant_set_debug_params(struct wpa_global *global,
 				    int debug_level, int debug_timestamp,
 				    int debug_show_keys);
+void free_hw_features(struct wpa_supplicant *wpa_s);
 
 void wpa_show_license(void);
 

Modified: wpa/trunk/wpa_supplicant/wps_supplicant.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpa/trunk/wpa_supplicant/wps_supplicant.c?rev=1731&op=diff
==============================================================================
--- wpa/trunk/wpa_supplicant/wps_supplicant.c (original)
+++ wpa/trunk/wpa_supplicant/wps_supplicant.c Tue Apr 17 11:03:56 2012
@@ -77,8 +77,10 @@
 	if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && wpa_s->current_ssid &&
 	    !(wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
 		int disabled = wpa_s->current_ssid->disabled;
+		unsigned int freq = wpa_s->assoc_freq;
 		wpa_printf(MSG_DEBUG, "WPS: Network configuration replaced - "
-			   "try to associate with the received credential");
+			   "try to associate with the received credential "
+			   "(freq=%u)", freq);
 		wpa_supplicant_deauthenticate(wpa_s,
 					      WLAN_REASON_DEAUTH_LEAVING);
 		if (disabled) {
@@ -87,7 +89,7 @@
 			return 1;
 		}
 		wpa_s->after_wps = 5;
-		wpa_s->wps_freq = wpa_s->assoc_freq;
+		wpa_s->wps_freq = freq;
 		wpa_s->reassociate = 1;
 		wpa_supplicant_req_scan(wpa_s, 0, 0);
 		return 1;
@@ -663,6 +665,8 @@
 		wpa_supplicant_wps_event_er_set_sel_reg(wpa_s,
 							&data->set_sel_reg);
 		break;
+	case WPS_EV_AP_PIN_SUCCESS:
+		break;
 	}
 }
 




More information about the Pkg-wpa-devel mailing list