Accumulative patch from commit 1075b2957169d8f9d6dddd7679339c751dc9515b

1075b29 P2P: Report group formation failure on error to start GO mode
b62b29e Do not block on ctrl_iface monitor events
eb7ddbf WPS: Stop SSDP service before freeing the pending entries
98cbc0a Remove forgotten Xcode defines
0b9d3b2 Interworking: Relax 3GPP info PLMN matching for MNC
c7a67a7 WPS: Disconnect when removing existing WPS network block
fe65847 EAP-EKE: Add server implementation
7e7610d EAP-EKE: Add peer implementation
489202d EAP-SAKE: Use configured server identity
a607b42 EAP-PSK: Use configured server identity
15b042b EAP-MSCHAPv2: Use configured server identity
162865b EAP-IKEv2 server: Use configured server identity
8f89d82 EAP-GPSK server: Use configured server identity
67fe933 Add server identity configuration for EAP server
06aeff5 dbus: Register the AutoScan method call at the right place
78f79fe P2P: Do not add ctrl interface for P2P_DEVICE (p2p-dev-*)
1c42b42 P2P: Fix TDLS and l2_packet init without P2P Device interface
9e6a321 Fix non-P2P build after the P2P_DEVICE changes
d53d259 Fix build with older OpenSSL versions
54d4ba4 nl80211: Silence a compiler warning with older gcc versions
2e5ba4b P2P: Derive group interface name bit more sensibly
c68f620 P2P: Create P2P Device interface if supported
851b0c5 nl80211: Do not indicate P2P_DEVICE support by default
bb4028f P2P: Ignore p2p_no_group_iface when driver advertizes P2P_DEVICE support
7940c79 nl80211: Use wdev id when cancelling wait for frame using P2P_DEVICE
f608081 nl80211: Verify P2P GO/client address with all interface addresses
5fbcb45 nl80211: Fix determining phy name for P2P Device
27ce1d6 nl80211: Fix nl80211_get_wiphy_index() for P2P Device
080585c Add support for OCSP stapling to validate server certificate
72950ed P2P: Remove a call to wpas_p2p_deinit_global()
ab7a1ad nl80211: Fix P2P group interface creating using P2P Device
fa93de4 nl80211: Use wdev_id in nl80211_create_iface_once()
fdc554b nl80211: Use wdev id to obtain P2P Device scan results
597b94f nl80211: Add .get_mac_addr() callback for P2P Device
8e12685 nl80211: Rework setting interface mode
91724d6 nl80211: Introduce i802_set_iface_flags()
eb4582f nl80211: Remove P2P Device interface upon .deinit()
f632e48 nl80211: Fix P2P Device interface initialization
e472e1b nl80211: Handle creation of P2P Device interface
01517c8 nl80211: Allow Android P2P functionality
6bae92e nl80211: Add support for P2P Device in add interface
d6dcfcd nl80211: Add a handler to create_interface
d3aaef8 nl80211: Hold wdev identification for P2P Device
7aad838 nl80211: Identify if nl80211 is capable of P2P Device abstraction
6a71413 nl80211: Rename is_p2p_interface
8393e1a nl80211: Print interface name on set_key()
80ebfd9 VLAN: Avoid access to non-existing interfaces
4345fe9 bridge: Track inter-BSS usage
459eee9 bridge: Use safe default bridge interface
2aaeedf bridge: Give bridge name in per-bss configuration
8a901d7 D-Bus: Emit signal when a station is authorized or deauthorized
9578329 Add AVG_RSSI report in signal_poll
2cc8d8f Add bandwidth and center freq info to signal_poll
1e0e943 Remove 802.11b rates only in case of P2P group operation
2090a0b nl80211: Add prints for kernel events
8743676 TDLS: Validate ext_supp_rates in copy_supp_rates
85b4eac P2P: Do not reply to 802.11b-only Probe Request frames as GO
ec7b97a Interworking: Add support for using eap_proxy offload
4331263 Fix session timeout after ANQP dummy STA entry with SME-in-driver
56cb4e1 wpadebug: Add option to ignore SSL errors
aa20e1a Remove CONFIG_NO_WPA2 build parameter
5d5c4ee Remove compiler warnings with CONFIG_NO_SCAN_PROCESSING
9aaa695 Remove compiler warnings if TDLS is enabled without WPA2
84ae1d4 Fix WNM build without WPA2
c33d5eb Fix build without WPA2 or EAP
1aef400 IBSS RSN: Implement disconnect() callback using sta_deauth()

Change-Id: I4593be5b1478f6532da917423b1d2afa95fb8020
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index f9193ae..37f5ad3 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -65,6 +65,8 @@
 #define P2P_CONCURRENT_SEARCH_DELAY 500
 #endif /* P2P_CONCURRENT_SEARCH_DELAY */
 
+#define P2P_MGMT_DEVICE_PREFIX		"p2p-dev-"
+
 enum p2p_group_removal_reason {
 	P2P_GROUP_REMOVAL_UNKNOWN,
 	P2P_GROUP_REMOVAL_SILENT,
@@ -1013,6 +1015,26 @@
 }
 
 
+static void wpas_p2p_get_group_ifname(struct wpa_supplicant *wpa_s,
+				      char *ifname, size_t len)
+{
+	char *ifname_ptr = wpa_s->ifname;
+
+	if (os_strncmp(wpa_s->ifname, P2P_MGMT_DEVICE_PREFIX,
+		       os_strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
+		ifname_ptr = os_strrchr(wpa_s->ifname, '-') + 1;
+	}
+
+	os_snprintf(ifname, len, "p2p-%s-%d", ifname_ptr, wpa_s->p2p_group_idx);
+	if (os_strlen(ifname) >= IFNAMSIZ &&
+	    os_strlen(wpa_s->ifname) < IFNAMSIZ) {
+		/* Try to avoid going over the IFNAMSIZ length limit */
+		os_snprintf(ifname, sizeof(ifname), "p2p-%d",
+			    wpa_s->p2p_group_idx);
+	}
+}
+
+
 static int wpas_p2p_add_group_interface(struct wpa_supplicant *wpa_s,
 					enum wpa_driver_if_type type)
 {
@@ -1030,14 +1052,7 @@
 		return 0;
 	}
 
-	os_snprintf(ifname, sizeof(ifname), "p2p-%s-%d", wpa_s->ifname,
-		    wpa_s->p2p_group_idx);
-	if (os_strlen(ifname) >= IFNAMSIZ &&
-	    os_strlen(wpa_s->ifname) < IFNAMSIZ) {
-		/* Try to avoid going over the IFNAMSIZ length limit */
-		os_snprintf(ifname, sizeof(ifname), "p2p-%d",
-			    wpa_s->p2p_group_idx);
-	}
+	wpas_p2p_get_group_ifname(wpa_s, ifname, sizeof(ifname));
 	force_ifname[0] = '\0';
 
 	wpa_printf(MSG_DEBUG, "P2P: Create a new interface %s for the group",
@@ -1107,7 +1122,13 @@
 	os_memset(&iface, 0, sizeof(iface));
 	iface.ifname = wpa_s->pending_interface_name;
 	iface.driver = wpa_s->driver->name;
-	iface.ctrl_interface = wpa_s->conf->ctrl_interface;
+	if (wpa_s->conf->ctrl_interface == NULL &&
+	    wpa_s->parent != wpa_s &&
+	    wpa_s->p2p_mgmt &&
+	    (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE))
+		iface.ctrl_interface = wpa_s->parent->conf->ctrl_interface;
+	else
+		iface.ctrl_interface = wpa_s->conf->ctrl_interface;
 	iface.driver_param = wpa_s->conf->driver_param;
 	group_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface);
 	if (group_wpa_s == NULL) {
@@ -1132,6 +1153,14 @@
 {
 	struct wpa_supplicant *wpa_s = eloop_ctx;
 	wpa_printf(MSG_DEBUG, "P2P: Group Formation timed out");
+	wpas_p2p_group_formation_failed(wpa_s);
+}
+
+
+void wpas_p2p_group_formation_failed(struct wpa_supplicant *wpa_s)
+{
+	eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
+			     wpa_s->parent, NULL);
 	if (wpa_s->global->p2p)
 		p2p_group_formation_failed(wpa_s->global->p2p);
 	else if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)
@@ -3048,6 +3077,45 @@
 }
 
 
+int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s)
+{
+	struct wpa_interface iface;
+	struct wpa_supplicant *p2pdev_wpa_s;
+	char ifname[100];
+	char force_name[100];
+	int ret;
+
+	os_snprintf(ifname, sizeof(ifname), P2P_MGMT_DEVICE_PREFIX "%s",
+		    wpa_s->ifname);
+	force_name[0] = '\0';
+	wpa_s->pending_interface_type = WPA_IF_P2P_DEVICE;
+	ret = wpa_drv_if_add(wpa_s, WPA_IF_P2P_DEVICE, ifname, NULL, NULL,
+			     force_name, wpa_s->pending_interface_addr, NULL);
+	if (ret < 0) {
+		wpa_printf(MSG_DEBUG, "P2P: Failed to create P2P Device interface");
+		return ret;
+	}
+	os_strlcpy(wpa_s->pending_interface_name, ifname,
+		   sizeof(wpa_s->pending_interface_name));
+
+	os_memset(&iface, 0, sizeof(iface));
+	iface.p2p_mgmt = 1;
+	iface.ifname = wpa_s->pending_interface_name;
+	iface.driver = wpa_s->driver->name;
+	iface.driver_param = wpa_s->conf->driver_param;
+	iface.confname = wpa_s->confname;
+	p2pdev_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface);
+	if (!p2pdev_wpa_s) {
+		wpa_printf(MSG_DEBUG, "P2P: Failed to add P2P Device interface");
+		return -1;
+	}
+	p2pdev_wpa_s->parent = wpa_s;
+
+	wpa_s->pending_interface_name[0] = '\0';
+	return 0;
+}
+
+
 /**
  * wpas_p2p_init - Initialize P2P module for %wpa_supplicant
  * @global: Pointer to global data from wpa_supplicant_init()
@@ -3312,7 +3380,8 @@
 
 static int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s)
 {
-	if (wpa_s->conf->p2p_no_group_iface)
+	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
+	    wpa_s->conf->p2p_no_group_iface)
 		return 0; /* separate interface disabled per configuration */
 	if (wpa_s->drv_flags &
 	    (WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE |
@@ -5595,14 +5664,7 @@
 		   "session overlap");
 	if (wpa_s != wpa_s->parent)
 		wpa_msg_ctrl(wpa_s->parent, MSG_INFO, WPS_EVENT_OVERLAP);
-
-	if (wpa_s->global->p2p)
-		p2p_group_formation_failed(wpa_s->global->p2p);
-
-	eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
-			     wpa_s->parent, NULL);
-
-	wpas_group_formation_completed(wpa_s, 0);
+	wpas_p2p_group_formation_failed(wpa_s);
 	return 1;
 }