Cumulative patch from commit 21cb63fffd1e766c8b989125394ed0bfb05e5a4b

21cb63f OpenSSL: Fix client certificate chain building after PKCS#12 use
12a81b6 ACS: Remove unreachable case from a debug print
896607d Remove a pointer check that can never be true
a95cc47 ACS: Be more consistent with iface->current_mode checks
6014e59 P2P: Print find_start in debug log when ignoring old scan results
64845c1 l2_packet: Extend bridge workaround RX processing to cover two frames
4a539ab l2_packet: Improve bridge workaround RX processing
7a36f11 EAP-PAX: Check hmac_sha1_vector() return value
1d20c66 P2P: Clear groups first on FLUSH command
27446e4 mesh: Do not force another peering exchange on driver event
cc64fe7 mesh: Do not clear link state on driver event if exchange was started
b5f5c32 mesh: Add some more details to MPM debug messages
7d41907 nl80211: Add a missing space to a debug message
6174de6 mesh: Connection and group started/removed events into debug log
2da4a56 Add more hostapd.conf documentation for hw_mode with HT/VHT
acc3943 EAP-PEAP peer: Cryptobinding in fast-reconnect case with inner EAP
cba9ebf P2P: Try SD Query with each non-ACK peer only once per search iteration
e9ccfc3 Clear wpa_supplicant state to DISCONNECTED on FLUSH command
aeb408f HS 2.0: Add some documentation for OSEN and network block use
4f6cd3f Fix wpa_supplicant AP mode P2P IE handling if P2P is disabled
92acb40 Fix wpa_supplicant build with CONFIG_L2_PACKET=pcap
15c5606 Update copyright notices for the new year 2016
6e379c6 WPS: Testing mechanism to force auth/encr type flags
ea31912 WPS: Add a workaround for WPA2PSK missing from Enrollee auth flags
db671e0 WPS: Do not build Credential with unsupported encr combination on AP
d7c3347 HS 2.0: Postpone WNM-Notification sending by 100 ms
750f5d9 EAP-FAST: Enable AES256-based TLS cipher suites with OpenSSL
1ebb24b OpenSSL: Share a single openssl_tls_prf() implementation
dea2051 OpenSSL: Clean up function to fetch client/server random
9a42d85 OpenSSL: Drop support for OpenSSL 1.0.0
de213e8 OpenSSL: Drop support for OpenSSL 0.9.8
e79eb0c P2P: Fix P2P_FIND while waiting for listen ROC to start in the driver
944f693 P2P: Stop offchannel TX wait on P2P_STOP_FIND/P2P_LISTEN
8edd9f1 P2P: Add an option to specify group SSID in P2P_CONNECT join case
70e0cb3 P2P: Provide group SSID, if specified, to P2P Client join step
438be60 P2P: Do not accept any GO BSS entry if SSID is specified for join
35510d5 P2P: Use join SSID in the skip-PD cases
8b8d4f4 P2P: Do not accept any BSS entry for join if SSID is already known
b875276 P2P: Use group SSID, if known, for join operation even if no BSS entry
aa256cb P2PS: Add group SSID, if known, to the P2PS-PROV-DONE event
071e3bf FST: Fix handling of Rx FST Setup Request when session already exists

Change-Id: Ia48764e8663232291160fb24153fa367b9ed3015
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/README b/wpa_supplicant/README
index f9c65d2..61be543 100644
--- a/wpa_supplicant/README
+++ b/wpa_supplicant/README
@@ -1,7 +1,7 @@
 WPA Supplicant
 ==============
 
-Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi> and contributors
+Copyright (c) 2003-2016, Jouni Malinen <j@w1.fi> and contributors
 All Rights Reserved.
 
 This program is licensed under the BSD license (the one with
diff --git a/wpa_supplicant/README-HS20 b/wpa_supplicant/README-HS20
index 161dc06..e523b58 100644
--- a/wpa_supplicant/README-HS20
+++ b/wpa_supplicant/README-HS20
@@ -564,3 +564,68 @@
 <3>RX-ANQP 02:00:00:00:01:00 Roaming Consortium list
 <3>RX-HS20-ANQP 02:00:00:00:01:00 HS Capability List
 <3>ANQP fetch completed
+
+
+Hotspot 2.0 Rel 2 online signup and OSEN
+----------------------------------------
+
+Following parameters can be used to create a network profile for
+link-layer protected Hotspot 2.0 online signup connection with
+OSEN. Note that ssid and identify (NAI) values need to be set based on
+the information for the selected provider in the OSU Providers list
+ANQP-element.
+
+network={
+    ssid="HS 2.0 OSU"
+    proto=OSEN
+    key_mgmt=OSEN
+    pairwise=CCMP
+    group=GTK_NOT_USED
+    eap=WFA-UNAUTH-TLS
+    identity="anonymous@example.com"
+    ca_cert="osu-ca.pem"
+    ocsp=2
+}
+
+
+Hotspot 2.0 connection with external network selection
+------------------------------------------------------
+
+When an component controlling wpa_supplicant takes care of Interworking
+network selection, following configuration and network profile
+parameters can be used to configure a temporary network profile for a
+Hotspot 2.0 connection (e.g., with SET, ADD_NETWORK, SET_NETWORK, and
+SELECT_NETWORK control interface commands):
+
+interworking=1
+hs20=1
+auto_interworking=0
+
+network={
+    ssid="test-hs20"
+    proto=RSN
+    key_mgmt=WPA-EAP
+    pairwise=CCMP
+    anonymous_identity="anonymous@example.com"
+    identity="hs20-test@example.com"
+    password="password"
+    ca_cert="ca.pem"
+    eap=TTLS
+    phase2="auth=MSCHAPV2"
+    update_identifier=54321
+    #ocsp=2
+}
+
+
+These parameters are set based on the PPS MO credential and/or NAI Realm
+list ANQP-element:
+
+anonymous_identity: Credential/UsernamePassword/Username with username part
+		    replaced with "anonymous"
+identity: Credential/UsernamePassword/Username
+password: Credential/UsernamePassword/Password
+update_identifier: PPS/UpdateIdentifier
+ca_cert: from the downloaded trust root based on PPS information
+eap: Credential/UsernamePassword/EAPMethod or NAI Realm list
+phase2: Credential/UsernamePassword/EAPMethod or NAI Realm list
+ocsp: Credential/CheckAAAServerCertStatus
diff --git a/wpa_supplicant/README-P2P b/wpa_supplicant/README-P2P
index 6a5b032..19cf155 100644
--- a/wpa_supplicant/README-P2P
+++ b/wpa_supplicant/README-P2P
@@ -151,6 +151,7 @@
 p2p_connect <peer device address> <pbc|pin|PIN#|p2ps> [display|keypad|p2ps]
 	[persistent|persistent=<network id>] [join|auth]
 	[go_intent=<0..15>] [freq=<in MHz>] [ht40] [vht] [provdisc] [auto]
+	[ssid=<hexdump>]
 
 Start P2P group formation with a discovered P2P peer. This includes
 optional group owner negotiation, group interface setup, provisioning,
@@ -195,6 +196,12 @@
 out whether the peer device is operating as a GO and if so, use
 join-a-group operation rather than GO Negotiation.
 
+"ssid=<hexdump>" can be used to specify the Group SSID for join
+operations. This allows the P2P Client interface to filter scan results
+based on SSID to avoid selecting an incorrect BSS entry in case the same
+P2P Device or Interface address have been used in multiple groups
+recently.
+
 P2PS attribute changes to p2p_connect command:
 
 P2PS supports two WPS provisioning methods namely PIN method and P2PS default.
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index ecf8d2d..b3d6246 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -371,6 +371,20 @@
 		wps_corrupt_pkhash = atoi(value);
 		wpa_printf(MSG_DEBUG, "WPS: Testing - wps_corrupt_pkhash=%d",
 			   wps_corrupt_pkhash);
+	} else if (os_strcasecmp(cmd, "wps_force_auth_types") == 0) {
+		if (value[0] == '\0') {
+			wps_force_auth_types_in_use = 0;
+		} else {
+			wps_force_auth_types = strtol(value, NULL, 0);
+			wps_force_auth_types_in_use = 1;
+		}
+	} else if (os_strcasecmp(cmd, "wps_force_encr_types") == 0) {
+		if (value[0] == '\0') {
+			wps_force_encr_types_in_use = 0;
+		} else {
+			wps_force_encr_types = strtol(value, NULL, 0);
+			wps_force_encr_types_in_use = 1;
+		}
 #endif /* CONFIG_WPS_TESTING */
 	} else if (os_strcasecmp(cmd, "ampdu") == 0) {
 		if (wpa_drv_ampdu(wpa_s, atoi(value)) < 0)
@@ -4911,6 +4925,8 @@
 	int freq = 0;
 	int pd;
 	int ht40, vht, max_oper_chwidth, chwidth = 0, freq2 = 0;
+	u8 _group_ssid[SSID_MAX_LEN], *group_ssid = NULL;
+	size_t group_ssid_len = 0;
 
 	if (!wpa_s->global->p2p_init_wpa_s)
 		return -1;
@@ -4923,7 +4939,7 @@
 	/* <addr> <"pbc" | "pin" | PIN> [label|display|keypad|p2ps]
 	 * [persistent|persistent=<network id>]
 	 * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] [provdisc]
-	 * [ht40] [vht] [auto] */
+	 * [ht40] [vht] [auto] [ssid=<hexdump>] */
 
 	if (hwaddr_aton(cmd, addr))
 		return -1;
@@ -4983,6 +4999,22 @@
 	if (max_oper_chwidth < 0)
 		return -1;
 
+	pos2 = os_strstr(pos, " ssid=");
+	if (pos2) {
+		char *end;
+
+		pos2 += 6;
+		end = os_strchr(pos2, ' ');
+		if (!end)
+			group_ssid_len = os_strlen(pos2) / 2;
+		else
+			group_ssid_len = (end - pos2) / 2;
+		if (group_ssid_len == 0 || group_ssid_len > SSID_MAX_LEN ||
+		    hexstr2bin(pos2, _group_ssid, group_ssid_len) < 0)
+			return -1;
+		group_ssid = _group_ssid;
+	}
+
 	if (os_strncmp(pos, "pin", 3) == 0) {
 		/* Request random PIN (to be displayed) and enable the PIN */
 		wps_method = WPS_PIN_DISPLAY;
@@ -5008,7 +5040,8 @@
 	new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
 				   persistent_group, automatic, join,
 				   auth, go_intent, freq, freq2, persistent_id,
-				   pd, ht40, vht, max_oper_chwidth);
+				   pd, ht40, vht, max_oper_chwidth,
+				   group_ssid, group_ssid_len);
 	if (new_pin == -2) {
 		os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25);
 		return 25;
@@ -6940,10 +6973,18 @@
 
 	wpas_abort_ongoing_scan(wpa_s);
 
+	if (wpa_s->wpa_state >= WPA_AUTHENTICATING) {
+		/*
+		 * Avoid possible auto connect re-connection on getting
+		 * disconnected due to state flush.
+		 */
+		wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
+	}
+
 #ifdef CONFIG_P2P
+	wpas_p2p_group_remove(p2p_wpa_s, "*");
 	wpas_p2p_cancel(p2p_wpa_s);
 	p2p_ctrl_flush(p2p_wpa_s);
-	wpas_p2p_group_remove(p2p_wpa_s, "*");
 	wpas_p2p_service_flush(p2p_wpa_s);
 	p2p_wpa_s->global->p2p_disabled = 0;
 	p2p_wpa_s->global->p2p_per_sta_psk = 0;
@@ -6960,6 +7001,8 @@
 	wps_version_number = 0x20;
 	wps_testing_dummy_cred = 0;
 	wps_corrupt_pkhash = 0;
+	wps_force_auth_types_in_use = 0;
+	wps_force_encr_types_in_use = 0;
 #endif /* CONFIG_WPS_TESTING */
 #ifdef CONFIG_WPS
 	wpa_s->wps_fragment_size = 0;
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
index a0c5ff7..e2f0afc 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
@@ -583,7 +583,7 @@
 
 	new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
 				   persistent_group, 0, join, authorize_only,
-				   go_intent, freq, 0, -1, 0, 0, 0, 0);
+				   go_intent, freq, 0, -1, 0, 0, 0, 0, NULL, 0);
 
 	if (new_pin >= 0) {
 		char npin[9];
diff --git a/wpa_supplicant/doc/docbook/eapol_test.sgml b/wpa_supplicant/doc/docbook/eapol_test.sgml
index e9af6d9..3f22413 100644
--- a/wpa_supplicant/doc/docbook/eapol_test.sgml
+++ b/wpa_supplicant/doc/docbook/eapol_test.sgml
@@ -194,7 +194,7 @@
   </refsect1>
   <refsect1>
     <title>Legal</title>
-    <para>wpa_supplicant is copyright (c) 2003-2015,
+    <para>wpa_supplicant is copyright (c) 2003-2016,
     Jouni Malinen <email>j@w1.fi</email> and
     contributors.
     All Rights Reserved.</para>
diff --git a/wpa_supplicant/doc/docbook/wpa_background.sgml b/wpa_supplicant/doc/docbook/wpa_background.sgml
index afb8c3b..13c9f45 100644
--- a/wpa_supplicant/doc/docbook/wpa_background.sgml
+++ b/wpa_supplicant/doc/docbook/wpa_background.sgml
@@ -90,7 +90,7 @@
 
   <refsect1>
     <title>Legal</title>
-    <para>wpa_supplicant is copyright (c) 2003-2015,
+    <para>wpa_supplicant is copyright (c) 2003-2016,
     Jouni Malinen <email>j@w1.fi</email> and
     contributors.
     All Rights Reserved.</para>
diff --git a/wpa_supplicant/doc/docbook/wpa_cli.sgml b/wpa_supplicant/doc/docbook/wpa_cli.sgml
index 47947c1..15400f0 100644
--- a/wpa_supplicant/doc/docbook/wpa_cli.sgml
+++ b/wpa_supplicant/doc/docbook/wpa_cli.sgml
@@ -345,7 +345,7 @@
   </refsect1>
   <refsect1>
     <title>Legal</title>
-    <para>wpa_supplicant is copyright (c) 2003-2015,
+    <para>wpa_supplicant is copyright (c) 2003-2016,
     Jouni Malinen <email>j@w1.fi</email> and
     contributors.
     All Rights Reserved.</para>
diff --git a/wpa_supplicant/doc/docbook/wpa_gui.sgml b/wpa_supplicant/doc/docbook/wpa_gui.sgml
index 5f7b49d..352d3d2 100644
--- a/wpa_supplicant/doc/docbook/wpa_gui.sgml
+++ b/wpa_supplicant/doc/docbook/wpa_gui.sgml
@@ -91,7 +91,7 @@
   </refsect1>
   <refsect1>
     <title>Legal</title>
-    <para>wpa_supplicant is copyright (c) 2003-2015,
+    <para>wpa_supplicant is copyright (c) 2003-2016,
     Jouni Malinen <email>j@w1.fi</email> and
     contributors.
     All Rights Reserved.</para>
diff --git a/wpa_supplicant/doc/docbook/wpa_passphrase.sgml b/wpa_supplicant/doc/docbook/wpa_passphrase.sgml
index b381e40..faf1f27 100644
--- a/wpa_supplicant/doc/docbook/wpa_passphrase.sgml
+++ b/wpa_supplicant/doc/docbook/wpa_passphrase.sgml
@@ -62,7 +62,7 @@
   </refsect1>
   <refsect1>
     <title>Legal</title>
-    <para>wpa_supplicant is copyright (c) 2003-2015,
+    <para>wpa_supplicant is copyright (c) 2003-2016,
     Jouni Malinen <email>j@w1.fi</email> and
     contributors.
     All Rights Reserved.</para>
diff --git a/wpa_supplicant/doc/docbook/wpa_priv.sgml b/wpa_supplicant/doc/docbook/wpa_priv.sgml
index d13a5db..403c9b2 100644
--- a/wpa_supplicant/doc/docbook/wpa_priv.sgml
+++ b/wpa_supplicant/doc/docbook/wpa_priv.sgml
@@ -137,7 +137,7 @@
   </refsect1>
   <refsect1>
     <title>Legal</title>
-    <para>wpa_supplicant is copyright (c) 2003-2015,
+    <para>wpa_supplicant is copyright (c) 2003-2016,
     Jouni Malinen <email>j@w1.fi</email> and
     contributors.
     All Rights Reserved.</para>
diff --git a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
index 46c21b5..c8c1ac4 100644
--- a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
+++ b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
@@ -736,7 +736,7 @@
   </refsect1>
   <refsect1>
     <title>Legal</title>
-    <para>wpa_supplicant is copyright (c) 2003-2015,
+    <para>wpa_supplicant is copyright (c) 2003-2016,
     Jouni Malinen <email>j@w1.fi</email> and
     contributors.
     All Rights Reserved.</para>
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index 4caa55c..d509d7d 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -43,6 +43,7 @@
 };
 
 static const char * const mplstate[] = {
+	[0] = "UNINITIALIZED",
 	[PLINK_LISTEN] = "LISTEN",
 	[PLINK_OPEN_SENT] = "OPEN_SENT",
 	[PLINK_OPEN_RCVD] = "OPEN_RCVD",
@@ -360,6 +361,9 @@
 		goto fail;
 	}
 
+	wpa_msg(wpa_s, MSG_DEBUG, "Mesh MPM: Sending peering frame type %d to "
+		MACSTR " (my_lid=0x%x peer_lid=0x%x)",
+		type, MAC2STR(sta->addr), sta->my_lid, sta->peer_lid);
 	ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0,
 				  sta->addr, wpa_s->own_addr, wpa_s->own_addr,
 				  wpabuf_head(buf), wpabuf_len(buf), 0);
@@ -380,6 +384,9 @@
 	struct hostapd_sta_add_params params;
 	int ret;
 
+	wpa_msg(wpa_s, MSG_DEBUG, "MPM set " MACSTR " from %s into %s",
+		MAC2STR(sta->addr), mplstate[sta->plink_state],
+		mplstate[state]);
 	sta->plink_state = state;
 
 	os_memset(&params, 0, sizeof(params));
@@ -387,8 +394,6 @@
 	params.plink_state = state;
 	params.set = 1;
 
-	wpa_msg(wpa_s, MSG_DEBUG, "MPM set " MACSTR " into %s",
-		MAC2STR(sta->addr), mplstate[state]);
 	ret = wpa_drv_sta_add(wpa_s, &params);
 	if (ret) {
 		wpa_msg(wpa_s, MSG_ERROR, "Driver failed to set " MACSTR
@@ -571,7 +576,8 @@
 		return NULL;
 	}
 
-	mesh_mpm_init_link(wpa_s, sta);
+	if (!sta->my_lid)
+		mesh_mpm_init_link(wpa_s, sta);
 
 #ifdef CONFIG_IEEE80211N
 	copy_sta_ht_capab(data, sta, elems->ht_capabilities);
@@ -663,10 +669,13 @@
 		return;
 	}
 
-	if (conf->security == MESH_CONF_SEC_NONE)
-		mesh_mpm_plink_open(wpa_s, sta, PLINK_OPEN_SENT);
-	else
+	if (conf->security == MESH_CONF_SEC_NONE) {
+		if (sta->plink_state < PLINK_OPEN_SENT ||
+		    sta->plink_state > PLINK_ESTAB)
+			mesh_mpm_plink_open(wpa_s, sta, PLINK_OPEN_SENT);
+	} else {
 		mesh_rsn_auth_sae_sta(wpa_s, sta);
+	}
 }
 
 
@@ -715,8 +724,8 @@
 	eloop_cancel_timeout(plink_timer, wpa_s, sta);
 
 	/* Send ctrl event */
-	wpa_msg_ctrl(wpa_s, MSG_INFO, MESH_PEER_CONNECTED MACSTR,
-		     MAC2STR(sta->addr));
+	wpa_msg(wpa_s, MSG_INFO, MESH_PEER_CONNECTED MACSTR,
+		MAC2STR(sta->addr));
 }
 
 
@@ -854,9 +863,8 @@
 				" closed with reason %d",
 				MAC2STR(sta->addr), reason);
 
-			wpa_msg_ctrl(wpa_s, MSG_INFO,
-				     MESH_PEER_DISCONNECTED MACSTR,
-				     MAC2STR(sta->addr));
+			wpa_msg(wpa_s, MSG_INFO, MESH_PEER_DISCONNECTED MACSTR,
+				MAC2STR(sta->addr));
 
 			hapd->num_plinks--;
 
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index d6acbd0..9b36b63 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -3950,7 +3950,8 @@
 				    size_t persist_ssid_size, int response_done,
 				    int prov_start, const char *session_info,
 				    const u8 *feat_cap, size_t feat_cap_len,
-				    unsigned int freq)
+				    unsigned int freq,
+				    const u8 *group_ssid, size_t group_ssid_len)
 {
 	struct wpa_supplicant *wpa_s = ctx;
 	u8 mac[ETH_ALEN];
@@ -4124,7 +4125,8 @@
 					wpa_s, P2P_SC_FAIL_UNKNOWN_GROUP,
 					dev, adv_mac, ses_mac,
 					grp_mac, adv_id, ses_id, 0, 0,
-					NULL, 0, 0, 0, NULL, NULL, 0, 0);
+					NULL, 0, 0, 0, NULL, NULL, 0, 0,
+					NULL, 0);
 				return;
 			}
 
@@ -4191,16 +4193,24 @@
 	}
 
 	if (conncap == P2PS_SETUP_CLIENT) {
+		char ssid_hex[32 * 2 + 1];
+
+		if (group_ssid)
+			wpa_snprintf_hex(ssid_hex, sizeof(ssid_hex),
+					 group_ssid, group_ssid_len);
+		else
+			ssid_hex[0] = '\0';
 		wpa_msg_global(wpa_s, MSG_INFO,
 			       P2P_EVENT_P2PS_PROVISION_DONE MACSTR
 			       " status=%d conncap=%x"
 			       " adv_id=%x adv_mac=" MACSTR
 			       " session=%x mac=" MACSTR
-			       " dev_passwd_id=%d join=" MACSTR "%s",
+			       " dev_passwd_id=%d join=" MACSTR "%s%s%s",
 			       MAC2STR(dev), status, conncap,
 			       adv_id, MAC2STR(adv_mac),
 			       ses_id, MAC2STR(ses_mac),
-			       passwd_id, MAC2STR(grp_mac), feat_cap_str);
+			       passwd_id, MAC2STR(grp_mac), feat_cap_str,
+			       group_ssid ? " group_ssid=" : "", ssid_hex);
 	} else {
 		wpa_msg_global(wpa_s, MSG_INFO,
 			       P2P_EVENT_P2PS_PROVISION_DONE MACSTR
@@ -4769,7 +4779,8 @@
 					 wpa_s->p2p_pd_before_go_neg,
 					 wpa_s->p2p_go_ht40,
 					 wpa_s->p2p_go_vht,
-					 wpa_s->p2p_go_max_oper_chwidth);
+					 wpa_s->p2p_go_max_oper_chwidth,
+					 NULL, 0);
 			return;
 		}
 
@@ -4815,8 +4826,7 @@
 		bss = wpa_bss_get(wpa_s, wpa_s->pending_join_iface_addr,
 				  wpa_s->p2p_join_ssid,
 				  wpa_s->p2p_join_ssid_len);
-	}
-	if (!bss) {
+	} else if (!bss) {
 		wpa_printf(MSG_DEBUG, "P2P: Trying to find target GO BSS entry based on BSSID "
 			   MACSTR, MAC2STR(wpa_s->pending_join_iface_addr));
 		bss = wpa_bss_get_bssid_latest(wpa_s,
@@ -4915,7 +4925,8 @@
 
 start:
 	/* Start join operation immediately */
-	wpas_p2p_join_start(wpa_s, 0, NULL, 0);
+	wpas_p2p_join_start(wpa_s, 0, wpa_s->p2p_join_ssid,
+			    wpa_s->p2p_join_ssid_len);
 }
 
 
@@ -5081,8 +5092,13 @@
 		res.ssid_len = ssid_len;
 		os_memcpy(res.ssid, ssid, ssid_len);
 	} else {
-		bss = wpa_bss_get_bssid_latest(wpa_s,
-					       wpa_s->pending_join_iface_addr);
+		if (ssid && ssid_len) {
+			bss = wpa_bss_get(wpa_s, wpa_s->pending_join_iface_addr,
+					  ssid, ssid_len);
+		} else {
+			bss = wpa_bss_get_bssid_latest(
+				wpa_s, wpa_s->pending_join_iface_addr);
+		}
 		if (bss) {
 			res.freq = bss->freq;
 			res.ssid_len = bss->ssid_len;
@@ -5090,6 +5106,11 @@
 			wpa_printf(MSG_DEBUG, "P2P: Join target GO operating frequency from BSS table: %d MHz (SSID %s)",
 				   bss->freq,
 				   wpa_ssid_txt(bss->ssid, bss->ssid_len));
+		} else if (ssid && ssid_len) {
+			res.ssid_len = ssid_len;
+			os_memcpy(res.ssid, ssid, ssid_len);
+			wpa_printf(MSG_DEBUG, "P2P: Join target GO (SSID %s)",
+				   wpa_ssid_txt(ssid, ssid_len));
 		}
 	}
 
@@ -5283,6 +5304,8 @@
  * @vht:  Start GO with VHT support
  * @vht_chwidth: Channel width supported by GO operating with VHT support
  *	(VHT_CHANWIDTH_*).
+ * @group_ssid: Specific Group SSID for join or %NULL if not set
+ * @group_ssid_len: Length of @group_ssid in octets
  * Returns: 0 or new PIN (if pin was %NULL) on success, -1 on unspecified
  *	failure, -2 on failure due to channel not currently available,
  *	-3 if forced channel is not supported
@@ -5292,7 +5315,8 @@
 		     int persistent_group, int auto_join, int join, int auth,
 		     int go_intent, int freq, unsigned int vht_center_freq2,
 		     int persistent_id, int pd, int ht40, int vht,
-		     unsigned int vht_chwidth)
+		     unsigned int vht_chwidth, const u8 *group_ssid,
+		     size_t group_ssid_len)
 {
 	int force_freq = 0, pref_freq = 0;
 	int ret = 0, res;
@@ -5375,7 +5399,8 @@
 		}
 		wpa_s->user_initiated_pd = 1;
 		if (wpas_p2p_join(wpa_s, iface_addr, dev_addr, wps_method,
-				  auto_join, freq, NULL, 0) < 0)
+				  auto_join, freq,
+				  group_ssid, group_ssid_len) < 0)
 			return -1;
 		return ret;
 	}
@@ -6480,8 +6505,12 @@
 	if (!offchannel_pending_action_tx(wpa_s))
 		return;
 
-	if (wpa_s->p2p_send_action_work)
+	if (wpa_s->p2p_send_action_work) {
 		wpas_p2p_free_send_action_work(wpa_s);
+		eloop_cancel_timeout(wpas_p2p_send_action_work_timeout,
+				     wpa_s, NULL);
+		offchannel_send_action_done(wpa_s);
+	}
 
 	wpa_printf(MSG_DEBUG, "P2P: Drop pending Action TX due to new "
 		   "operation request");
@@ -7753,7 +7782,7 @@
 			 wpa_s->p2p_pd_before_go_neg,
 			 wpa_s->p2p_go_ht40,
 			 wpa_s->p2p_go_vht,
-			 wpa_s->p2p_go_max_oper_chwidth);
+			 wpa_s->p2p_go_max_oper_chwidth, NULL, 0);
 	return ret;
 }
 
@@ -8288,7 +8317,9 @@
 	return wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL,
 				WPS_NFC, 0, 0, 1, 0, wpa_s->conf->p2p_go_intent,
 				params->go_freq, wpa_s->p2p_go_vht_center_freq2,
-				-1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth);
+				-1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth,
+				params->go_ssid_len ? params->go_ssid : NULL,
+				params->go_ssid_len);
 }
 
 
@@ -8365,7 +8396,8 @@
 	return wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL,
 				WPS_NFC, 0, 0, 0, 0, wpa_s->conf->p2p_go_intent,
 				forced_freq, wpa_s->p2p_go_vht_center_freq2,
-				-1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth);
+				-1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth,
+				NULL, 0);
 }
 
 
@@ -8380,7 +8412,8 @@
 	res = wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL,
 			       WPS_NFC, 0, 0, 0, 1, wpa_s->conf->p2p_go_intent,
 			       forced_freq, wpa_s->p2p_go_vht_center_freq2,
-			       -1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth);
+			       -1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth,
+			       NULL, 0);
 	if (res)
 		return res;
 
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index 21ee41f..6a770d2 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -34,10 +34,11 @@
 						  const u8 *peer_dev_addr);
 int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
 		     const char *pin, enum p2p_wps_method wps_method,
-		     int persistent_group, int auto_join, int join,
-		     int auth, int go_intent, int freq,
-		     unsigned int vht_center_freq2, int persistent_id,
-		     int pd, int ht40, int vht, unsigned int max_oper_chwidth);
+		     int persistent_group, int auto_join, int join, int auth,
+		     int go_intent, int freq, unsigned int vht_center_freq2,
+		     int persistent_id, int pd, int ht40, int vht,
+		     unsigned int vht_chwidth, const u8 *group_ssid,
+		     size_t group_ssid_len);
 int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s,
                                           int freq, struct wpa_ssid *ssid);
 int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index aedd61a..1aea0a6 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -1,6 +1,6 @@
 /*
  * WPA Supplicant - command line interface for wpa_supplicant daemon
- * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -28,7 +28,7 @@
 
 static const char *const wpa_cli_version =
 "wpa_cli v" VERSION_STR "\n"
-"Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi> and contributors";
+"Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi> and contributors";
 
 
 static const char *const wpa_cli_license =
diff --git a/wpa_supplicant/wpa_priv.c b/wpa_supplicant/wpa_priv.c
index 850ec40..fa5a6de 100644
--- a/wpa_supplicant/wpa_priv.c
+++ b/wpa_supplicant/wpa_priv.c
@@ -1060,7 +1060,7 @@
 static void usage(void)
 {
 	printf("wpa_priv v" VERSION_STR "\n"
-	       "Copyright (c) 2007-2009, Jouni Malinen <j@w1.fi> and "
+	       "Copyright (c) 2007-2016, Jouni Malinen <j@w1.fi> and "
 	       "contributors\n"
 	       "\n"
 	       "usage:\n"
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index e588992..03b1353 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1,6 +1,6 @@
 /*
  * WPA Supplicant
- * Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2016, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -58,7 +58,7 @@
 
 const char *const wpa_supplicant_version =
 "wpa_supplicant v" VERSION_STR "\n"
-"Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi> and contributors";
+"Copyright (c) 2003-2016, Jouni Malinen <j@w1.fi> and contributors";
 
 const char *const wpa_supplicant_license =
 "This software may be distributed under the terms of the BSD license.\n"
@@ -1684,10 +1684,9 @@
 			return;
 		}
 		wpa_s->current_bss = bss;
-		wpa_msg_ctrl(wpa_s, MSG_INFO, MESH_GROUP_STARTED
-			     "ssid=\"%s\" id=%d",
-			     wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
-			     ssid->id);
+		wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_STARTED "ssid=\"%s\" id=%d",
+			wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
+			ssid->id);
 #else /* CONFIG_MESH */
 		wpa_msg(wpa_s, MSG_ERROR,
 			"mesh mode support not included in the build");
@@ -2610,8 +2609,8 @@
 
 #ifdef CONFIG_MESH
 	if (wpa_s->ifmsh) {
-		wpa_msg_ctrl(wpa_s, MSG_INFO, MESH_GROUP_REMOVED "%s",
-			     wpa_s->ifname);
+		wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_REMOVED "%s",
+			wpa_s->ifname);
 		wpa_supplicant_leave_mesh(wpa_s);
 	}
 #endif /* CONFIG_MESH */
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index e204061..f3e913a 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -762,6 +762,7 @@
 # FT-SAE = SAE with FT
 # WPA-EAP-SUITE-B = Suite B 128-bit level
 # WPA-EAP-SUITE-B-192 = Suite B 192-bit level
+# OSEN = Hotspot 2.0 Rel 2 online signup connection
 # If not set, this defaults to: WPA-PSK WPA-EAP
 #
 # ieee80211w: whether management frame protection is enabled
@@ -1121,6 +1122,9 @@
 # number of authentication servers. Strict EAP conformance mode can be
 # configured by disabling workarounds with eap_workaround=0.
 
+# update_identifier: PPS MO ID
+#	(Hotspot 2.0 PerProviderSubscription/UpdateIdentifier)
+
 # Station inactivity limit
 #
 # If a station does not send anything in ap_max_inactivity seconds, an