Cumulative patch from commit 57e832de37ea0a82e650d8230457e0868a01b72e

57e832d GAS: Remove all radio works before calling gas_query_deinit()
661888b P2P: Fix persistent group profile on manual disabled=2 change
1a2f7ca D-Bus: Add WPS pbc-overlap Event
4f36965 P2P: Add ModelNumber and SerialNumber info into D-Bus peer interface
2899cba P2P: Add ModelName info into D-Bus peer interface
8bb5cfe doc: Add missing ListenChannel to P2P information
995a3a0 Document the wpa_msg_cb "global" parameter
e66bced Do not set own_disconnect_req flag if not connected
8d2ed87 wpa_gui: Port to Qt5
e1ede80 eapol_test: Support IPv6 for authentication server
e19c1d2 Fix pairwise cipher suite bitfields to the driver in mixed mode
ee120ff Remove [MU-BEAMFORMEE] option from hostapd vht_capab parameter
c5ee4dd Fix spelling of initialize in a comment and an error message
aa2b125 P2P: Add GO Intent of connecting device in GO Negotiation Request event
cf60962 doc: Fix a typo in D-Bus API document
f13e815 Set Acct-Session-Id from os_get_random() instead of os_get_time()
92f190a OpenSSL: Fix build iwth OpenSSL 0.9.8
a80651d Add support to request a scan with specific SSIDs
94687a0 WPS: Allow the priority for the WPS networks to be configured
09d57ce wpa_supplicant: Remove trailing whitespace
0980c7f hostapd: Make sure band selection does not result in NULL dereference

Change-Id: I32154fcf606169fc1e3e3a653e80c99f058f8e95
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index e1f4883..2fe032d 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -4225,6 +4225,7 @@
 	{ INT(key_mgmt_offload), 0},
 	{ INT(passive_scan), 0 },
 	{ INT(reassoc_same_bss_optim), 0 },
+	{ INT(wps_priority), 0},
 };
 
 #undef FUNC
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index 16681fd..545a4bd 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -1164,6 +1164,14 @@
 	 * reassoc_same_bss_optim - Whether to optimize reassoc-to-same-BSS
 	 */
 	int reassoc_same_bss_optim;
+
+	/**
+	 * wps_priority - Priority for the networks added through WPS
+	 *
+	 * This priority value will be set to each network profile that is added
+	 * by executing the WPS protocol.
+	 */
+	int wps_priority;
 };
 
 
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 781f5e5..2508ca9 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -1286,6 +1286,9 @@
 	if (config->reassoc_same_bss_optim)
 		fprintf(f, "reassoc_same_bss_optim=%d\n",
 			config->reassoc_same_bss_optim);
+
+	if (config->wps_priority)
+		fprintf(f, "wps_priority=%d\n", config->wps_priority);
 }
 
 #endif /* CONFIG_NO_CONFIG_WRITE */
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 4aa602d..f32b7c9 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -2876,7 +2876,8 @@
 #endif /* CONFIG_SME */
 			wpa_sm_set_config(wpa_s->wpa, NULL);
 			eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
-			wpa_s->own_disconnect_req = 1;
+			if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
+				wpa_s->own_disconnect_req = 1;
 			wpa_supplicant_deauthenticate(
 				wpa_s, WLAN_REASON_DEAUTH_LEAVING);
 		}
@@ -2923,7 +2924,8 @@
 		wpa_sm_set_config(wpa_s->wpa, NULL);
 		eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
 
-		wpa_s->own_disconnect_req = 1;
+		if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
+			wpa_s->own_disconnect_req = 1;
 		wpa_supplicant_deauthenticate(wpa_s,
 					      WLAN_REASON_DEAUTH_LEAVING);
 	}
@@ -6982,6 +6984,8 @@
 	void (*scan_res_handler)(struct wpa_supplicant *wpa_s,
 				 struct wpa_scan_results *scan_res);
 	int *manual_scan_freqs = NULL;
+	struct wpa_ssid_value *ssid = NULL, *ns;
+	unsigned int ssid_count = 0;
 
 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
 		*reply_len = -1;
@@ -7036,6 +7040,60 @@
 			*reply_len = -1;
 			goto done;
 		}
+
+		pos = params;
+		while (pos && *pos != '\0') {
+			if (os_strncmp(pos, "ssid ", 5) == 0) {
+				char *end;
+
+				pos += 5;
+				end = pos;
+				while (*end) {
+					if (*end == '\0' || *end == ' ')
+						break;
+					end++;
+				}
+
+				ns = os_realloc_array(
+					ssid, ssid_count + 1,
+					sizeof(struct wpa_ssid_value));
+				if (ns == NULL) {
+					*reply_len = -1;
+					goto done;
+				}
+				ssid = ns;
+
+				if ((end - pos) & 0x01 ||
+				    end - pos > 2 * SSID_MAX_LEN ||
+				    hexstr2bin(pos, ssid[ssid_count].ssid,
+					       (end - pos) / 2) < 0) {
+					wpa_printf(MSG_DEBUG,
+						   "Invalid SSID value '%s'",
+						   pos);
+					*reply_len = -1;
+					goto done;
+				}
+				ssid[ssid_count].ssid_len = (end - pos) / 2;
+				wpa_hexdump_ascii(MSG_DEBUG, "scan SSID",
+						  ssid[ssid_count].ssid,
+						  ssid[ssid_count].ssid_len);
+				ssid_count++;
+				pos = end;
+			}
+
+			pos = os_strchr(pos, ' ');
+			if (pos)
+				pos++;
+		}
+	}
+
+	wpa_s->num_ssids_from_scan_req = ssid_count;
+	os_free(wpa_s->ssids_from_scan_req);
+	if (ssid_count) {
+		wpa_s->ssids_from_scan_req = ssid;
+		ssid = NULL;
+	} else {
+		wpa_s->ssids_from_scan_req = NULL;
 	}
 
 	if (scan_only)
@@ -7099,6 +7157,7 @@
 
 done:
 	os_free(manual_scan_freqs);
+	os_free(ssid);
 }
 
 
diff --git a/wpa_supplicant/ctrl_iface_named_pipe.c b/wpa_supplicant/ctrl_iface_named_pipe.c
index dc02db2..54e0e2f 100644
--- a/wpa_supplicant/ctrl_iface_named_pipe.c
+++ b/wpa_supplicant/ctrl_iface_named_pipe.c
@@ -423,7 +423,8 @@
 }
 
 
-static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level, int global,
+static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level,
+					     enum wpa_msg_type type,
 					     const char *txt, size_t len)
 {
 	struct wpa_supplicant *wpa_s = ctx;
diff --git a/wpa_supplicant/ctrl_iface_udp.c b/wpa_supplicant/ctrl_iface_udp.c
index bf6a3df..76f69f2 100644
--- a/wpa_supplicant/ctrl_iface_udp.c
+++ b/wpa_supplicant/ctrl_iface_udp.c
@@ -322,7 +322,8 @@
 }
 
 
-static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level, int global,
+static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level,
+					     enum wpa_msg_type type,
 					     const char *txt, size_t len)
 {
 	struct wpa_supplicant *wpa_s = ctx;
diff --git a/wpa_supplicant/ctrl_iface_unix.c b/wpa_supplicant/ctrl_iface_unix.c
index b1ac766..22001cf 100644
--- a/wpa_supplicant/ctrl_iface_unix.c
+++ b/wpa_supplicant/ctrl_iface_unix.c
@@ -295,7 +295,8 @@
 }
 
 
-static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level, int global,
+static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level,
+					     enum wpa_msg_type type,
 					     const char *txt, size_t len)
 {
 	struct wpa_supplicant *wpa_s = ctx;
@@ -303,15 +304,14 @@
 	if (wpa_s == NULL)
 		return;
 
-	if (global != 2 && wpa_s->global->ctrl_iface) {
+	if (type != WPA_MSG_NO_GLOBAL && wpa_s->global->ctrl_iface) {
 		struct ctrl_iface_global_priv *priv = wpa_s->global->ctrl_iface;
 		if (!dl_list_empty(&priv->ctrl_dst)) {
-			wpa_supplicant_ctrl_iface_send(wpa_s, global ? NULL :
-						       wpa_s->ifname,
-						       priv->sock,
-						       &priv->ctrl_dst,
-						       level, txt, len, NULL,
-						       priv);
+			wpa_supplicant_ctrl_iface_send(
+				wpa_s,
+				type == WPA_MSG_GLOBAL ? NULL : wpa_s->ifname,
+				priv->sock, &priv->ctrl_dst, level, txt, len,
+				NULL, priv);
 		}
 	}
 
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index 6382d77..fb674d4 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -525,6 +525,44 @@
 #ifdef CONFIG_WPS
 
 /**
+ * wpas_dbus_signal_wps_event_pbc_overlap - Signals PBC overlap WPS event
+ * @wpa_s: %wpa_supplicant network interface data
+ *
+ * Sends Event dbus signal with name "pbc-overlap" and empty dict as arguments
+ */
+void wpas_dbus_signal_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s)
+{
+
+	DBusMessage *msg;
+	DBusMessageIter iter, dict_iter;
+	struct wpas_dbus_priv *iface;
+	char *key = "pbc-overlap";
+
+	iface = wpa_s->global->dbus;
+
+	/* Do nothing if the control interface is not turned on */
+	if (iface == NULL || !wpa_s->dbus_new_path)
+		return;
+
+	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+				      WPAS_DBUS_NEW_IFACE_WPS, "Event");
+	if (msg == NULL)
+		return;
+
+	dbus_message_iter_init_append(msg, &iter);
+
+	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
+	    !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
+	    !wpa_dbus_dict_close_write(&iter, &dict_iter))
+		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
+	else
+		dbus_connection_send(iface->con, msg, NULL);
+
+	dbus_message_unref(msg);
+}
+
+
+/**
  * wpas_dbus_signal_wps_event_success - Signals Success WPS event
  * @wpa_s: %wpa_supplicant network interface data
  *
@@ -1063,7 +1101,8 @@
 
 
 void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
-				     const u8 *src, u16 dev_passwd_id)
+				     const u8 *src, u16 dev_passwd_id,
+				     u8 go_intent)
 {
 	DBusMessage *msg;
 	DBusMessageIter iter;
@@ -1097,7 +1136,9 @@
 	if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
 					    &path) ||
 	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
-					    &dev_passwd_id))
+					    &dev_passwd_id) ||
+	    !dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE,
+					    &go_intent))
 		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
 	else
 		dbus_connection_send(iface->con, msg, NULL);
@@ -3123,6 +3164,7 @@
 	  {
 		  { "path", "o", ARG_OUT },
 		  { "dev_passwd_id", "i", ARG_OUT },
+		  { "device_go_intent", "y", ARG_OUT },
 		  END_ARGS
 	  }
 	},
@@ -3311,6 +3353,18 @@
 	  wpas_dbus_getter_p2p_peer_manufacturer,
 	  NULL
 	},
+	{ "ModelName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
+	  wpas_dbus_getter_p2p_peer_modelname,
+	  NULL
+	},
+	{ "ModelNumber", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
+	  wpas_dbus_getter_p2p_peer_modelnumber,
+	  NULL
+	},
+	{ "SerialNumber", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
+	  wpas_dbus_getter_p2p_peer_serialnumber,
+	  NULL
+	},
 	{ "PrimaryDeviceType", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
 	  wpas_dbus_getter_p2p_peer_primary_device_type,
 	  NULL
diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h
index 31db8d4..7503348 100644
--- a/wpa_supplicant/dbus/dbus_new.h
+++ b/wpa_supplicant/dbus/dbus_new.h
@@ -152,6 +152,7 @@
 void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
 				     struct wps_event_fail *fail);
 void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s);
+void wpas_dbus_signal_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s);
 int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
 			       struct wpa_ssid *ssid);
 int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid);
@@ -185,7 +186,8 @@
 					      u16 config_methods,
 					      unsigned int generated_pin);
 void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
-				     const u8 *src, u16 dev_passwd_id);
+				     const u8 *src, u16 dev_passwd_id,
+				     u8 go_intent);
 void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s,
 					const struct wpa_ssid *ssid,
 					int client, int network_id);
@@ -296,6 +298,11 @@
 {
 }
 
+static inline void wpas_dbus_signal_wps_event_pbc_overlap(
+	struct wpa_supplicant *wpa_s)
+{
+}
+
 static inline int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
 					     struct wpa_ssid *ssid)
 {
@@ -378,10 +385,10 @@
 {
 }
 
-static inline void wpas_dbus_signal_p2p_go_neg_req(
-				struct wpa_supplicant *wpa_s,
-				const u8 *src,
-				u16 dev_passwd_id)
+static inline void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
+						   const u8 *src,
+						   u16 dev_passwd_id,
+						   u8 go_intent)
 {
 }
 
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
index c8dd67b..56e9033 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
@@ -1288,6 +1288,117 @@
 }
 
 
+dbus_bool_t wpas_dbus_getter_p2p_peer_modelname(DBusMessageIter *iter,
+						DBusError *error,
+						void *user_data)
+{
+	struct peer_handler_args *peer_args = user_data;
+	const struct p2p_peer_info *info;
+	char *tmp;
+
+	if (!wpa_dbus_p2p_check_enabled(peer_args->wpa_s, NULL, NULL, error))
+		return FALSE;
+
+	/* get the peer 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;
+	}
+
+	tmp = os_strdup(info->model_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_modelnumber(DBusMessageIter *iter,
+						  DBusError *error,
+						  void *user_data)
+{
+	struct peer_handler_args *peer_args = user_data;
+	const struct p2p_peer_info *info;
+	char *tmp;
+
+	if (!wpa_dbus_p2p_check_enabled(peer_args->wpa_s, NULL, NULL, error))
+		return FALSE;
+
+	/* get the peer 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;
+	}
+
+	tmp = os_strdup(info->model_number);
+	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_serialnumber(DBusMessageIter *iter,
+						   DBusError *error,
+						   void *user_data)
+{
+	struct peer_handler_args *peer_args = user_data;
+	const struct p2p_peer_info *info;
+	char *tmp;
+
+	if (!wpa_dbus_p2p_check_enabled(peer_args->wpa_s, NULL, NULL, error))
+		return FALSE;
+
+	/* get the peer 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;
+	}
+
+	tmp = os_strdup(info->serial_number);
+	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)
 {
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.h b/wpa_supplicant/dbus/dbus_new_handlers_p2p.h
index a84fc4a..d0953f1 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.h
@@ -119,6 +119,18 @@
 						   DBusError *error,
 						   void *user_data);
 
+dbus_bool_t wpas_dbus_getter_p2p_peer_modelname(DBusMessageIter *iter,
+						DBusError *error,
+						void *user_data);
+
+dbus_bool_t wpas_dbus_getter_p2p_peer_modelnumber(DBusMessageIter *iter,
+						  DBusError *error,
+						  void *user_data);
+
+dbus_bool_t wpas_dbus_getter_p2p_peer_serialnumber(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);
 
diff --git a/wpa_supplicant/eapol_test.c b/wpa_supplicant/eapol_test.c
index 983bbcd..bde7508 100644
--- a/wpa_supplicant/eapol_test.c
+++ b/wpa_supplicant/eapol_test.c
@@ -938,13 +938,12 @@
 		*pos++ = a[3];
 	}
 #else /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */
-	if (inet_aton(authsrv, &as->addr.u.v4) < 0) {
+	if (hostapd_parse_ip_addr(authsrv, &as->addr) < 0) {
 		wpa_printf(MSG_ERROR, "Invalid IP address '%s'",
 			   authsrv);
 		assert(0);
 	}
 #endif /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */
-	as->addr.af = AF_INET;
 	as->port = port;
 	as->shared_secret = (u8 *) os_strdup(secret);
 	as->shared_secret_len = os_strlen(secret);
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 49faadc..80045e7 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1179,6 +1179,7 @@
 	if (wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) {
 		wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP
 			"PBC session overlap");
+		wpas_notify_wps_event_pbc_overlap(wpa_s);
 #ifdef CONFIG_P2P
 		if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT ||
 		    wpa_s->p2p_in_provisioning) {
diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c
index 2282747..9f5a198 100644
--- a/wpa_supplicant/main.c
+++ b/wpa_supplicant/main.c
@@ -288,7 +288,7 @@
 			if (iface == NULL)
 				goto out;
 			ifaces = iface;
-			iface = &ifaces[iface_count - 1]; 
+			iface = &ifaces[iface_count - 1];
 			os_memset(iface, 0, sizeof(*iface));
 			break;
 		default:
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 4df9d90..822db74 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -268,6 +268,16 @@
 #endif /* CONFIG_WPS */
 }
 
+void wpas_notify_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s)
+{
+	if (wpa_s->p2p_mgmt)
+		return;
+
+#ifdef CONFIG_WPS
+	wpas_dbus_signal_wps_event_pbc_overlap(wpa_s);
+#endif /* CONFIG_WPS */
+}
+
 
 void wpas_notify_network_added(struct wpa_supplicant *wpa_s,
 			       struct wpa_ssid *ssid)
@@ -561,9 +571,9 @@
 
 
 void wpas_notify_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
-				const u8 *src, u16 dev_passwd_id)
+				const u8 *src, u16 dev_passwd_id, u8 go_intent)
 {
-	wpas_dbus_signal_p2p_go_neg_req(wpa_s, src, dev_passwd_id);
+	wpas_dbus_signal_p2p_go_neg_req(wpa_s, src, dev_passwd_id, go_intent);
 }
 
 
@@ -780,10 +790,12 @@
 		ssid->disabled = 0;
 		wpas_dbus_unregister_network(wpa_s, ssid->id);
 		ssid->disabled = 2;
+		ssid->p2p_persistent_group = 1;
 		wpas_dbus_register_persistent_group(wpa_s, ssid);
 	} else {
 		/* Changed from persistent group to normal network profile */
 		wpas_dbus_unregister_persistent_group(wpa_s, ssid->id);
+		ssid->p2p_persistent_group = 0;
 		wpas_dbus_register_network(wpa_s, ssid);
 	}
 #endif /* CONFIG_P2P */
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index 1025ca8..1aeec47 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -45,6 +45,7 @@
 void wpas_notify_wps_event_fail(struct wpa_supplicant *wpa_s,
 				struct wps_event_fail *fail);
 void wpas_notify_wps_event_success(struct wpa_supplicant *wpa_s);
+void wpas_notify_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s);
 void wpas_notify_network_added(struct wpa_supplicant *wpa_s,
 			       struct wpa_ssid *ssid);
 void wpas_notify_network_removed(struct wpa_supplicant *wpa_s,
@@ -93,7 +94,7 @@
 				   const struct wpa_ssid *ssid,
 				   const char *role);
 void wpas_notify_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
-				const u8 *src, u16 dev_passwd_id);
+				const u8 *src, u16 dev_passwd_id, u8 go_intent);
 void wpas_notify_p2p_go_neg_completed(struct wpa_supplicant *wpa_s,
 				      struct p2p_go_neg_results *res);
 void wpas_notify_p2p_invitation_result(struct wpa_supplicant *wpa_s,
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index e7a4db3..5c8a3b2 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -2146,13 +2146,15 @@
 }
 
 
-static void wpas_go_neg_req_rx(void *ctx, const u8 *src, u16 dev_passwd_id)
+static void wpas_go_neg_req_rx(void *ctx, const u8 *src, u16 dev_passwd_id,
+			       u8 go_intent)
 {
 	struct wpa_supplicant *wpa_s = ctx;
 	wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_REQUEST MACSTR
-		       " dev_passwd_id=%u", MAC2STR(src), dev_passwd_id);
+		       " dev_passwd_id=%u go_intent=%u", MAC2STR(src),
+		       dev_passwd_id, go_intent);
 
-	wpas_notify_p2p_go_neg_req(wpa_s, src, dev_passwd_id);
+	wpas_notify_p2p_go_neg_req(wpa_s, src, dev_passwd_id, go_intent);
 }
 
 
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 3c6b2c7..e81465c 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -614,6 +614,37 @@
 }
 
 
+static int wpa_set_ssids_from_scan_req(struct wpa_supplicant *wpa_s,
+				       struct wpa_driver_scan_params *params,
+				       size_t max_ssids)
+{
+	unsigned int i;
+
+	if (wpa_s->ssids_from_scan_req == NULL ||
+	    wpa_s->num_ssids_from_scan_req == 0)
+		return 0;
+
+	if (wpa_s->num_ssids_from_scan_req > max_ssids) {
+		wpa_s->num_ssids_from_scan_req = max_ssids;
+		wpa_printf(MSG_DEBUG, "Over max scan SSIDs from scan req: %u",
+			   (unsigned int) max_ssids);
+	}
+
+	for (i = 0; i < wpa_s->num_ssids_from_scan_req; i++) {
+		params->ssids[i].ssid = wpa_s->ssids_from_scan_req[i].ssid;
+		params->ssids[i].ssid_len =
+			wpa_s->ssids_from_scan_req[i].ssid_len;
+		wpa_hexdump_ascii(MSG_DEBUG, "specific SSID",
+				  params->ssids[i].ssid,
+				  params->ssids[i].ssid_len);
+	}
+
+	params->num_ssids = wpa_s->num_ssids_from_scan_req;
+	wpa_s->num_ssids_from_scan_req = 0;
+	return 1;
+}
+
+
 static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
 {
 	struct wpa_supplicant *wpa_s = eloop_ctx;
@@ -726,6 +757,12 @@
 		goto scan;
 	}
 
+	if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
+	    wpa_set_ssids_from_scan_req(wpa_s, &params, max_ssids)) {
+		wpa_printf(MSG_DEBUG, "Use specific SSIDs from SCAN command");
+		goto ssid_list_set;
+	}
+
 #ifdef CONFIG_P2P
 	if ((wpa_s->p2p_in_provisioning || wpa_s->show_group_started) &&
 	    wpa_s->go_params && !wpa_s->conf->passive_scan) {
@@ -891,10 +928,8 @@
 		wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for wildcard "
 			"SSID");
 	}
-#ifdef CONFIG_P2P
-ssid_list_set:
-#endif /* CONFIG_P2P */
 
+ssid_list_set:
 	wpa_supplicant_optimize_freqs(wpa_s, &params);
 	extra_ie = wpa_supplicant_extra_ies(wpa_s);
 
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index bd5846b..97e575c 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -662,7 +662,7 @@
 		"tdls_external_control", "osu_dir", "wowlan_triggers",
 		"p2p_search_delay", "mac_addr", "rand_addr_lifetime",
 		"preassoc_mac_addr", "key_mgmt_offload", "passive_scan",
-		"reassoc_same_bss_optim"
+		"reassoc_same_bss_optim", "wps_priority"
 	};
 	int i, num_fields = ARRAY_SIZE(fields);
 
diff --git a/wpa_supplicant/wpa_gui-qt4/addinterface.cpp b/wpa_supplicant/wpa_gui-qt4/addinterface.cpp
index 27cbdd6..7d92f63 100644
--- a/wpa_supplicant/wpa_gui-qt4/addinterface.cpp
+++ b/wpa_supplicant/wpa_gui-qt4/addinterface.cpp
@@ -41,8 +41,8 @@
 	interfaceWidget->headerItem()->setText(0, tr("driver"));
 	interfaceWidget->headerItem()->setText(1, tr("interface"));
 	interfaceWidget->headerItem()->setText(2, tr("description"));
-	interfaceWidget->setItemsExpandable(FALSE);
-	interfaceWidget->setRootIsDecorated(FALSE);
+	interfaceWidget->setItemsExpandable(false);
+	interfaceWidget->setRootIsDecorated(false);
 	vboxLayout->addWidget(interfaceWidget);
 
 	connect(interfaceWidget,
@@ -196,9 +196,9 @@
 	 */
 	snprintf(cmd, sizeof(cmd),
 		 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
-		 sel->text(1).toAscii().constData(),
+		 sel->text(1).toLocal8Bit().constData(),
 		 "default",
-		 sel->text(0).toAscii().constData(),
+		 sel->text(0).toLocal8Bit().constData(),
 		 "yes", "", "");
 	cmd[sizeof(cmd) - 1] = '\0';
 
diff --git a/wpa_supplicant/wpa_gui-qt4/addinterface.h b/wpa_supplicant/wpa_gui-qt4/addinterface.h
index 1b4c98d..332fc71 100644
--- a/wpa_supplicant/wpa_gui-qt4/addinterface.h
+++ b/wpa_supplicant/wpa_gui-qt4/addinterface.h
@@ -11,9 +11,9 @@
 
 #include <QObject>
 
-#include <QtGui/QDialog>
-#include <QtGui/QTreeWidget>
-#include <QtGui/QVBoxLayout>
+#include <QDialog>
+#include <QTreeWidget>
+#include <QVBoxLayout>
 
 class WpaGui;
 
diff --git a/wpa_supplicant/wpa_gui-qt4/eventhistory.cpp b/wpa_supplicant/wpa_gui-qt4/eventhistory.cpp
index a36085d..09145cd 100644
--- a/wpa_supplicant/wpa_gui-qt4/eventhistory.cpp
+++ b/wpa_supplicant/wpa_gui-qt4/eventhistory.cpp
@@ -73,15 +73,15 @@
 }
 
 
-EventHistory::EventHistory(QWidget *parent, const char *, bool, Qt::WFlags)
+EventHistory::EventHistory(QWidget *parent, const char *, bool, Qt::WindowFlags)
 	: QDialog(parent)
 {
 	setupUi(this);
 
 	connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
 
-	eventListView->setItemsExpandable(FALSE);
-	eventListView->setRootIsDecorated(FALSE);
+	eventListView->setItemsExpandable(false);
+	eventListView->setRootIsDecorated(false);
 	elm = new EventListModel(parent);
 	eventListView->setModel(elm);
 }
diff --git a/wpa_supplicant/wpa_gui-qt4/eventhistory.h b/wpa_supplicant/wpa_gui-qt4/eventhistory.h
index 3c01aa8..afd7b63 100644
--- a/wpa_supplicant/wpa_gui-qt4/eventhistory.h
+++ b/wpa_supplicant/wpa_gui-qt4/eventhistory.h
@@ -40,7 +40,7 @@
 
 public:
 	EventHistory(QWidget *parent = 0, const char *name = 0,
-		     bool modal = false, Qt::WFlags fl = 0);
+		     bool modal = false, Qt::WindowFlags fl = 0);
 	~EventHistory();
 
 public slots:
diff --git a/wpa_supplicant/wpa_gui-qt4/main.cpp b/wpa_supplicant/wpa_gui-qt4/main.cpp
index 73d677c..39e01bf 100644
--- a/wpa_supplicant/wpa_gui-qt4/main.cpp
+++ b/wpa_supplicant/wpa_gui-qt4/main.cpp
@@ -14,24 +14,14 @@
 #include <QtCore/QTranslator>
 #include "wpagui.h"
 
-
-class WpaGuiApp : public QApplication
-{
-public:
-	WpaGuiApp(int &argc, char **argv);
-
-#ifndef QT_NO_SESSIONMANAGER
-	virtual void saveState(QSessionManager &manager);
-#endif
-
-	WpaGui *w;
-};
-
-WpaGuiApp::WpaGuiApp(int &argc, char **argv) : QApplication(argc, argv)
+WpaGuiApp::WpaGuiApp(int &argc, char **argv) :
+	QApplication(argc, argv),
+	argc(argc),
+	argv(argv)
 {
 }
 
-#ifndef QT_NO_SESSIONMANAGER
+#if !defined(QT_NO_SESSIONMANAGER) && QT_VERSION < 0x050000
 void WpaGuiApp::saveState(QSessionManager &manager)
 {
 	QApplication::saveState(manager);
diff --git a/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp b/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp
index 737c41c..2727318 100644
--- a/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp
+++ b/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp
@@ -26,7 +26,8 @@
 #define WPA_GUI_KEY_DATA "[key is configured]"
 
 
-NetworkConfig::NetworkConfig(QWidget *parent, const char *, bool, Qt::WFlags)
+NetworkConfig::NetworkConfig(QWidget *parent, const char *, bool,
+			     Qt::WindowFlags)
 	: QDialog(parent)
 {
 	setupUi(this);
@@ -237,7 +238,7 @@
 	} else
 		id = edit_network_id;
 
-	setNetworkParam(id, "ssid", ssidEdit->text().toAscii().constData(),
+	setNetworkParam(id, "ssid", ssidEdit->text().toLocal8Bit().constData(),
 			true);
 
 	const char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
@@ -291,14 +292,14 @@
 		setNetworkParam(id, "group", "TKIP CCMP WEP104 WEP40", false);
 	}
 	if (pskEdit->isEnabled() &&
-	    strcmp(pskEdit->text().toAscii().constData(),
+	    strcmp(pskEdit->text().toLocal8Bit().constData(),
 		   WPA_GUI_KEY_DATA) != 0)
 		setNetworkParam(id, "psk",
-				pskEdit->text().toAscii().constData(),
+				pskEdit->text().toLocal8Bit().constData(),
 				psklen != 64);
 	if (eapSelect->isEnabled()) {
 		const char *eap =
-			eapSelect->currentText().toAscii().constData();
+			eapSelect->currentText().toLocal8Bit().constData();
 		setNetworkParam(id, "eap", eap, false);
 		if (strcmp(eap, "SIM") == 0 || strcmp(eap, "AKA") == 0)
 			setNetworkParam(id, "pcsc", "", true);
@@ -314,21 +315,21 @@
 			if (inner.startsWith("EAP-"))
 				snprintf(phase2, sizeof(phase2), "auth=%s",
 					 inner.right(inner.size() - 4).
-					 toAscii().constData());
+					 toLocal8Bit().constData());
 		} else if (eap.compare("TTLS") == 0) {
 			if (inner.startsWith("EAP-"))
 				snprintf(phase2, sizeof(phase2), "autheap=%s",
 					 inner.right(inner.size() - 4).
-					 toAscii().constData());
+					 toLocal8Bit().constData());
 			else
 				snprintf(phase2, sizeof(phase2), "auth=%s",
-					 inner.toAscii().constData());
+					 inner.toLocal8Bit().constData());
 		} else if (eap.compare("FAST") == 0) {
 			const char *provisioning = NULL;
 			if (inner.startsWith("EAP-")) {
 				snprintf(phase2, sizeof(phase2), "auth=%s",
 					 inner.right(inner.size() - 4).
-					 toAscii().constData());
+					 toLocal8Bit().constData());
 				provisioning = "fast_provisioning=2";
 			} else if (inner.compare("GTC(auth) + MSCHAPv2(prov)")
 				   == 0) {
@@ -354,21 +355,21 @@
 		setNetworkParam(id, "phase2", "NULL", false);
 	if (identityEdit->isEnabled() && identityEdit->text().length() > 0)
 		setNetworkParam(id, "identity",
-				identityEdit->text().toAscii().constData(),
+				identityEdit->text().toLocal8Bit().constData(),
 				true);
 	else
 		setNetworkParam(id, "identity", "NULL", false);
 	if (passwordEdit->isEnabled() && passwordEdit->text().length() > 0 &&
-	    strcmp(passwordEdit->text().toAscii().constData(),
+	    strcmp(passwordEdit->text().toLocal8Bit().constData(),
 		   WPA_GUI_KEY_DATA) != 0)
 		setNetworkParam(id, "password",
-				passwordEdit->text().toAscii().constData(),
+				passwordEdit->text().toLocal8Bit().constData(),
 				true);
 	else if (passwordEdit->text().length() == 0)
 		setNetworkParam(id, "password", "NULL", false);
 	if (cacertEdit->isEnabled() && cacertEdit->text().length() > 0)
 		setNetworkParam(id, "ca_cert",
-				cacertEdit->text().toAscii().constData(),
+				cacertEdit->text().toLocal8Bit().constData(),
 				true);
 	else
 		setNetworkParam(id, "ca_cert", "NULL", false);
@@ -388,7 +389,7 @@
 
 	if (idstrEdit->isEnabled() && idstrEdit->text().length() > 0)
 		setNetworkParam(id, "id_str",
-				idstrEdit->text().toAscii().constData(),
+				idstrEdit->text().toLocal8Bit().constData(),
 				true);
 	else
 		setNetworkParam(id, "id_str", "NULL", false);
@@ -396,7 +397,7 @@
 	if (prioritySpinBox->isEnabled()) {
 		QString prio;
 		prio = prio.setNum(prioritySpinBox->value());
-		setNetworkParam(id, "priority", prio.toAscii().constData(),
+		setNetworkParam(id, "priority", prio.toLocal8Bit().constData(),
 				false);
 	}
 
@@ -468,7 +469,7 @@
 	 * Assume hex key if only hex characters are present and length matches
 	 * with 40, 104, or 128-bit key
 	 */
-	txt = edit->text().toAscii().constData();
+	txt = edit->text().toLocal8Bit().constData();
 	if (strcmp(txt, WPA_GUI_KEY_DATA) == 0)
 		return;
 	len = strlen(txt);
diff --git a/wpa_supplicant/wpa_gui-qt4/networkconfig.h b/wpa_supplicant/wpa_gui-qt4/networkconfig.h
index 429b648..fd09dec 100644
--- a/wpa_supplicant/wpa_gui-qt4/networkconfig.h
+++ b/wpa_supplicant/wpa_gui-qt4/networkconfig.h
@@ -20,7 +20,7 @@
 
 public:
 	NetworkConfig(QWidget *parent = 0, const char *name = 0,
-		      bool modal = false, Qt::WFlags fl = 0);
+		      bool modal = false, Qt::WindowFlags fl = 0);
 	~NetworkConfig();
 
 	virtual void paramsFromScanResults(QTreeWidgetItem *sel);
diff --git a/wpa_supplicant/wpa_gui-qt4/peers.cpp b/wpa_supplicant/wpa_gui-qt4/peers.cpp
index f5aa9f7..3bcf2f5 100644
--- a/wpa_supplicant/wpa_gui-qt4/peers.cpp
+++ b/wpa_supplicant/wpa_gui-qt4/peers.cpp
@@ -62,7 +62,7 @@
 };
 
 
-Peers::Peers(QWidget *parent, const char *, bool, Qt::WFlags)
+Peers::Peers(QWidget *parent, const char *, bool, Qt::WindowFlags)
 	: QDialog(parent)
 {
 	setupUi(this);
@@ -323,13 +323,13 @@
 
 	if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE) {
 		snprintf(cmd, sizeof(cmd), "WPS_ER_PIN %s %s %s",
-			 uuid.toAscii().constData(),
-			 input.get_string().toAscii().constData(),
-			 addr.toAscii().constData());
+			 uuid.toLocal8Bit().constData(),
+			 input.get_string().toLocal8Bit().constData(),
+			 addr.toLocal8Bit().constData());
 	} else {
 		snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s",
-			 addr.toAscii().constData(),
-			 input.get_string().toAscii().constData());
+			 addr.toLocal8Bit().constData(),
+			 input.get_string().toLocal8Bit().constData());
 	}
 	reply_len = sizeof(reply) - 1;
 	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
@@ -868,7 +868,7 @@
 		QStandardItem *item = find_addr(addr);
 		if (item == NULL || item->data(peer_role_type).toInt() !=
 		    PEER_TYPE_ASSOCIATED_STATION)
-			add_single_station(addr.toAscii().constData());
+			add_single_station(addr.toLocal8Bit().constData());
 		return;
 	}
 
@@ -1350,8 +1350,8 @@
 		char reply[100];
 		size_t reply_len;
 		snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s display",
-			 addr.toAscii().constData(),
-			 arg.toAscii().constData());
+			 addr.toLocal8Bit().constData(),
+			 arg.toLocal8Bit().constData());
 		reply_len = sizeof(reply) - 1;
 		if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
 			QMessageBox msg;
@@ -1384,8 +1384,8 @@
 	char reply[100];
 	size_t reply_len;
 	snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s",
-		 addr.toAscii().constData(),
-		 arg.toAscii().constData());
+		 addr.toLocal8Bit().constData(),
+		 arg.toLocal8Bit().constData());
 	reply_len = sizeof(reply) - 1;
 	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
 		QMessageBox msg;
@@ -1408,7 +1408,7 @@
 	char reply[100];
 	size_t reply_len;
 	snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s display",
-		 addr.toAscii().constData());
+		 addr.toLocal8Bit().constData());
 	reply_len = sizeof(reply) - 1;
 	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
 		QMessageBox msg;
@@ -1431,7 +1431,7 @@
 	char reply[100];
 	size_t reply_len;
 	snprintf(cmd, sizeof(cmd), "P2P_PROV_DISC %s keypad",
-		 addr.toAscii().constData());
+		 addr.toLocal8Bit().constData());
 	reply_len = sizeof(reply) - 1;
 	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
 		QMessageBox msg;
@@ -1452,7 +1452,7 @@
 	char reply[100];
 	size_t reply_len;
 	snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s pin",
-		 addr.toAscii().constData());
+		 addr.toLocal8Bit().constData());
 	reply_len = sizeof(reply) - 1;
 	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
 		QMessageBox msg;
@@ -1480,8 +1480,8 @@
 	char reply[100];
 	size_t reply_len;
 	snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s display",
-		 addr.toAscii().constData(),
-		 arg.toAscii().constData());
+		 addr.toLocal8Bit().constData(),
+		 arg.toLocal8Bit().constData());
 	reply_len = sizeof(reply) - 1;
 	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
 		QMessageBox msg;
@@ -1515,8 +1515,8 @@
 	char reply[100];
 	size_t reply_len;
 	snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s %s keypad",
-		 addr.toAscii().constData(),
-		 arg.toAscii().constData());
+		 addr.toLocal8Bit().constData(),
+		 arg.toLocal8Bit().constData());
 	reply_len = sizeof(reply) - 1;
 	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
 		QMessageBox msg;
@@ -1535,7 +1535,7 @@
 	char reply[100];
 	size_t reply_len;
 	snprintf(cmd, sizeof(cmd), "P2P_GROUP_REMOVE %s",
-		 ctx_item->data(peer_role_ifname).toString().toAscii().
+		 ctx_item->data(peer_role_ifname).toString().toLocal8Bit().
 		 constData());
 	reply_len = sizeof(reply) - 1;
 	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
@@ -1713,13 +1713,13 @@
 	int peer_type = ctx_item->data(peer_role_type).toInt();
 	if (peer_type == PEER_TYPE_WPS_ER_ENROLLEE) {
 		snprintf(cmd, sizeof(cmd), "WPS_ER_PBC %s",
-			 ctx_item->data(peer_role_uuid).toString().toAscii().
+			 ctx_item->data(peer_role_uuid).toString().toLocal8Bit().
 			 constData());
 	} else if (peer_type == PEER_TYPE_P2P ||
 		   peer_type == PEER_TYPE_P2P_CLIENT) {
 		snprintf(cmd, sizeof(cmd), "P2P_CONNECT %s pbc",
 			 ctx_item->data(peer_role_address).toString().
-			 toAscii().constData());
+			 toLocal8Bit().constData());
 	} else {
 		snprintf(cmd, sizeof(cmd), "WPS_PBC");
 	}
@@ -1750,8 +1750,8 @@
 	size_t reply_len;
 
 	snprintf(cmd, sizeof(cmd), "WPS_ER_LEARN %s %s",
-		 uuid.toAscii().constData(),
-		 input.get_string().toAscii().constData());
+		 uuid.toLocal8Bit().constData(),
+		 input.get_string().toLocal8Bit().constData());
 	reply_len = sizeof(reply) - 1;
 	if (wpagui->ctrlRequest(cmd, reply, &reply_len) < 0) {
 		QMessageBox msg;
diff --git a/wpa_supplicant/wpa_gui-qt4/peers.h b/wpa_supplicant/wpa_gui-qt4/peers.h
index bac77dc..bb73737 100644
--- a/wpa_supplicant/wpa_gui-qt4/peers.h
+++ b/wpa_supplicant/wpa_gui-qt4/peers.h
@@ -22,7 +22,7 @@
 
 public:
 	Peers(QWidget *parent = 0, const char *name = 0,
-		    bool modal = false, Qt::WFlags fl = 0);
+		    bool modal = false, Qt::WindowFlags fl = 0);
 	~Peers();
 	void setWpaGui(WpaGui *_wpagui);
 	void event_notify(WpaMsg msg);
diff --git a/wpa_supplicant/wpa_gui-qt4/scanresults.cpp b/wpa_supplicant/wpa_gui-qt4/scanresults.cpp
index ae0c240..a2e3072 100644
--- a/wpa_supplicant/wpa_gui-qt4/scanresults.cpp
+++ b/wpa_supplicant/wpa_gui-qt4/scanresults.cpp
@@ -15,7 +15,7 @@
 #include "scanresultsitem.h"
 
 
-ScanResults::ScanResults(QWidget *parent, const char *, bool, Qt::WFlags)
+ScanResults::ScanResults(QWidget *parent, const char *, bool, Qt::WindowFlags)
 	: QDialog(parent)
 {
 	setupUi(this);
@@ -27,8 +27,8 @@
 		SLOT(bssSelected(QTreeWidgetItem *)));
 
 	wpagui = NULL;
-	scanResultsWidget->setItemsExpandable(FALSE);
-	scanResultsWidget->setRootIsDecorated(FALSE);
+	scanResultsWidget->setItemsExpandable(false);
+	scanResultsWidget->setRootIsDecorated(false);
 	scanResultsWidget->setItemDelegate(new SignalBar(scanResultsWidget));
 }
 
diff --git a/wpa_supplicant/wpa_gui-qt4/scanresults.h b/wpa_supplicant/wpa_gui-qt4/scanresults.h
index 4a5842c..2cddd13 100644
--- a/wpa_supplicant/wpa_gui-qt4/scanresults.h
+++ b/wpa_supplicant/wpa_gui-qt4/scanresults.h
@@ -20,7 +20,7 @@
 
 public:
 	ScanResults(QWidget *parent = 0, const char *name = 0,
-		    bool modal = false, Qt::WFlags fl = 0);
+		    bool modal = false, Qt::WindowFlags fl = 0);
 	~ScanResults();
 
 public slots:
diff --git a/wpa_supplicant/wpa_gui-qt4/scanresultsitem.h b/wpa_supplicant/wpa_gui-qt4/scanresultsitem.h
index 835b7c0..74887ee 100644
--- a/wpa_supplicant/wpa_gui-qt4/scanresultsitem.h
+++ b/wpa_supplicant/wpa_gui-qt4/scanresultsitem.h
@@ -9,7 +9,7 @@
 #ifndef SCANRESULTSITEM_H
 #define SCANRESULTSITEM_H
 
-#include <QtGui>
+#include <QTreeWidgetItem>
 
 class ScanResultsItem : public QTreeWidgetItem
 {
diff --git a/wpa_supplicant/wpa_gui-qt4/userdatarequest.cpp b/wpa_supplicant/wpa_gui-qt4/userdatarequest.cpp
index ba4c9f4..9d933b0 100644
--- a/wpa_supplicant/wpa_gui-qt4/userdatarequest.cpp
+++ b/wpa_supplicant/wpa_gui-qt4/userdatarequest.cpp
@@ -12,7 +12,7 @@
 
 
 UserDataRequest::UserDataRequest(QWidget *parent, const char *, bool,
-				 Qt::WFlags)
+				 Qt::WindowFlags)
 	: QDialog(parent)
 {
 	setupUi(this);
@@ -89,6 +89,6 @@
 	QString cmd = QString(WPA_CTRL_RSP) + field + '-' +
 		QString::number(networkid) + ':' +
 		queryEdit->text();
-	wpagui->ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
+	wpagui->ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len);
 	accept();
 }
diff --git a/wpa_supplicant/wpa_gui-qt4/userdatarequest.h b/wpa_supplicant/wpa_gui-qt4/userdatarequest.h
index 0d9dbfc..b6d1ad2 100644
--- a/wpa_supplicant/wpa_gui-qt4/userdatarequest.h
+++ b/wpa_supplicant/wpa_gui-qt4/userdatarequest.h
@@ -20,7 +20,7 @@
 
 public:
 	UserDataRequest(QWidget *parent = 0, const char *name = 0,
-			bool modal = false, Qt::WFlags fl = 0);
+			bool modal = false, Qt::WindowFlags fl = 0);
 	~UserDataRequest();
 
 	int setParams(WpaGui *_wpagui, const char *reqMsg);
diff --git a/wpa_supplicant/wpa_gui-qt4/wpa_gui.pro b/wpa_supplicant/wpa_gui-qt4/wpa_gui.pro
index 69bc0f6..3fa734b 100644
--- a/wpa_supplicant/wpa_gui-qt4/wpa_gui.pro
+++ b/wpa_supplicant/wpa_gui-qt4/wpa_gui.pro
@@ -1,6 +1,7 @@
 TEMPLATE	= app
 LANGUAGE	= C++
 TRANSLATIONS	= lang/wpa_gui_de.ts
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
 
 CONFIG	+= qt warn_on release
 
diff --git a/wpa_supplicant/wpa_gui-qt4/wpagui.cpp b/wpa_supplicant/wpa_gui-qt4/wpagui.cpp
index d2d76f1..3bd3a9c 100644
--- a/wpa_supplicant/wpa_gui-qt4/wpagui.cpp
+++ b/wpa_supplicant/wpa_gui-qt4/wpagui.cpp
@@ -31,7 +31,8 @@
 #endif
 
 
-WpaGui::WpaGui(QApplication *_app, QWidget *parent, const char *, Qt::WFlags)
+WpaGui::WpaGui(QApplication *_app, QWidget *parent, const char *,
+	       Qt::WindowFlags)
 	: QMainWindow(parent), app(_app)
 {
 	setupUi(this);
@@ -159,7 +160,7 @@
 	textStatus->setText(tr("connecting to wpa_supplicant"));
 	timer = new QTimer(this);
 	connect(timer, SIGNAL(timeout()), SLOT(ping()));
-	timer->setSingleShot(FALSE);
+	timer->setSingleShot(false);
 	timer->start(1000);
 
 	signalMeterTimer = new QTimer(this);
@@ -238,8 +239,9 @@
 void WpaGui::parse_argv()
 {
 	int c;
+	WpaGuiApp *app = qobject_cast<WpaGuiApp*>(qApp);
 	for (;;) {
-		c = getopt(qApp->argc(), qApp->argv(), "i:m:p:tq");
+		c = getopt(app->argc, app->argv, "i:m:p:tq");
 		if (c < 0)
 			break;
 		switch (c) {
@@ -750,7 +752,7 @@
 void WpaGui::helpAbout()
 {
 	QMessageBox::about(this, "wpa_gui for wpa_supplicant",
-			   "Copyright (c) 2003-2013,\n"
+			   "Copyright (c) 2003-2015,\n"
 			   "Jouni Malinen <j@w1.fi>\n"
 			   "and contributors.\n"
 			   "\n"
@@ -1066,7 +1068,7 @@
 	else
 		cmd = "any";
 	cmd.prepend("SELECT_NETWORK ");
-	ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
+	ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len);
 	triggerUpdate();
 	stopWpsRun(false);
 }
@@ -1082,11 +1084,11 @@
 		cmd.truncate(cmd.indexOf(':'));
 	else if (!cmd.startsWith("all")) {
 		debug("Invalid editNetwork '%s'",
-		      cmd.toAscii().constData());
+		      cmd.toLocal8Bit().constData());
 		return;
 	}
 	cmd.prepend("ENABLE_NETWORK ");
-	ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
+	ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len);
 	triggerUpdate();
 }
 
@@ -1101,11 +1103,11 @@
 		cmd.truncate(cmd.indexOf(':'));
 	else if (!cmd.startsWith("all")) {
 		debug("Invalid editNetwork '%s'",
-		      cmd.toAscii().constData());
+		      cmd.toLocal8Bit().constData());
 		return;
 	}
 	cmd.prepend("DISABLE_NETWORK ");
-	ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
+	ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len);
 	triggerUpdate();
 }
 
@@ -1191,11 +1193,11 @@
 		cmd.truncate(cmd.indexOf(':'));
 	else if (!cmd.startsWith("all")) {
 		debug("Invalid editNetwork '%s'",
-		      cmd.toAscii().constData());
+		      cmd.toLocal8Bit().constData());
 		return;
 	}
 	cmd.prepend("REMOVE_NETWORK ");
-	ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
+	ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len);
 	triggerUpdate();
 }
 
@@ -1255,14 +1257,14 @@
 	int pos = cmd.indexOf(':');
 	if (pos < 0) {
 		debug("Invalid getNetworkDisabled '%s'",
-		      cmd.toAscii().constData());
+		      cmd.toLocal8Bit().constData());
 		return -1;
 	}
 	cmd.truncate(pos);
 	cmd.prepend("GET_NETWORK ");
 	cmd.append(" disabled");
 
-	if (ctrlRequest(cmd.toAscii().constData(), reply, &reply_len) >= 0
+	if (ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len) >= 0
 	    && reply_len >= 1) {
 		reply[reply_len] = '\0';
 		if (!str_match(reply, "FAIL"))
@@ -1345,7 +1347,7 @@
 
 void WpaGui::selectAdapter( const QString & sel )
 {
-	if (openCtrlConnection(sel.toAscii().constData()) < 0)
+	if (openCtrlConnection(sel.toLocal8Bit().constData()) < 0)
 		debug("Failed to open control connection to "
 		      "wpa_supplicant.");
 	updateStatus();
@@ -1719,7 +1721,7 @@
 	size_t reply_len = sizeof(reply);
 
 	QString cmd("WPS_REG " + bssFromScan + " " + wpsApPinEdit->text());
-	if (ctrlRequest(cmd.toAscii().constData(), reply, &reply_len) < 0)
+	if (ctrlRequest(cmd.toLocal8Bit().constData(), reply, &reply_len) < 0)
 		return;
 
 	wpsStatusText->setText(tr("Waiting for AP/Enrollee"));
diff --git a/wpa_supplicant/wpa_gui-qt4/wpagui.h b/wpa_supplicant/wpa_gui-qt4/wpagui.h
index 58c655d..f0a34c9 100644
--- a/wpa_supplicant/wpa_gui-qt4/wpagui.h
+++ b/wpa_supplicant/wpa_gui-qt4/wpagui.h
@@ -16,6 +16,20 @@
 
 class UserDataRequest;
 
+class WpaGuiApp : public QApplication
+{
+	Q_OBJECT
+public:
+	WpaGuiApp(int &argc, char **argv);
+
+#if !defined(QT_NO_SESSIONMANAGER) && QT_VERSION < 0x050000
+	virtual void saveState(QSessionManager &manager);
+#endif
+
+	WpaGui *w;
+	int argc;
+	char **argv;
+};
 
 class WpaGui : public QMainWindow, public Ui::WpaGui
 {
@@ -35,7 +49,7 @@
 	};
 
 	WpaGui(QApplication *app, QWidget *parent = 0, const char *name = 0,
-	       Qt::WFlags fl = 0);
+	       Qt::WindowFlags fl = 0);
 	~WpaGui();
 
 	virtual int ctrlRequest(const char *cmd, char *buf, size_t *buflen);
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 48bded6..e833c3a 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -493,6 +493,16 @@
 
 	wpas_mac_addr_rand_scan_clear(wpa_s, MAC_ADDR_RAND_ALL);
 
+	/*
+	 * Need to remove any pending gas-query radio work before the
+	 * gas_query_deinit() call because gas_query::work has not yet been set
+	 * for works that have not been started. gas_query_free() will be unable
+	 * to cancel such pending radio works and once the pending gas-query
+	 * radio work eventually gets removed, the deinit notification call to
+	 * gas_query_start_cb() would result in dereferencing freed memory.
+	 */
+	if (wpa_s->radio)
+		radio_remove_works(wpa_s, "gas-query", 0);
 	gas_query_deinit(wpa_s->gas);
 	wpa_s->gas = NULL;
 
@@ -873,7 +883,8 @@
 
 	eapol_sm_invalidate_cached_session(wpa_s->eapol);
 	if (wpa_s->current_ssid) {
-		wpa_s->own_disconnect_req = 1;
+		if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
+			wpa_s->own_disconnect_req = 1;
 		wpa_supplicant_deauthenticate(wpa_s,
 					      WLAN_REASON_DEAUTH_LEAVING);
 	}
@@ -2604,7 +2615,8 @@
 	int disconnected = 0;
 
 	if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
-		wpa_s->own_disconnect_req = 1;
+		if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
+			wpa_s->own_disconnect_req = 1;
 		wpa_supplicant_deauthenticate(
 			wpa_s, WLAN_REASON_DEAUTH_LEAVING);
 		disconnected = 1;
@@ -4336,6 +4348,8 @@
 		wpa_s->conf = NULL;
 	}
 
+	os_free(wpa_s->ssids_from_scan_req);
+
 	os_free(wpa_s);
 }
 
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index c1bcbd4..d380965 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -268,6 +268,11 @@
 #wps_nfc_dh_privkey: Hexdump of DH Private Key
 #wps_nfc_dev_pw: Hexdump of Device Password
 
+# Priority for the networks added through WPS
+# This priority value will be set to each network profile that is added
+# by executing the WPS protocol.
+#wps_priority=0
+
 # Maximum number of BSS entries to keep in memory
 # Default: 200
 # This can be used to limit memory use on the BSS entries (cached scan
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index ffda53d..bc6425d 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -609,6 +609,9 @@
 	int scan_id[MAX_SCAN_ID];
 	unsigned int scan_id_count;
 
+	struct wpa_ssid_value *ssids_from_scan_req;
+	unsigned int num_ssids_from_scan_req;
+
 	u64 drv_flags;
 	unsigned int drv_enc;
 	unsigned int drv_smps_modes;
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index 61a8587..a97c2a8 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -547,6 +547,7 @@
 			return -1;
 		}
 	}
+	ssid->priority = wpa_s->conf->wps_priority;
 
 	wpas_wps_security_workaround(wpa_s, ssid, cred);
 
@@ -560,6 +561,9 @@
 	}
 #endif /* CONFIG_NO_CONFIG_WRITE */
 
+	if (ssid->priority)
+		wpa_config_update_prio_list(wpa_s->conf);
+
 	/*
 	 * Optimize the post-WPS scan based on the channel used during
 	 * the provisioning in case EAP-Failure is not received.