Cumulative patch from commit 7ae7a84eefd43ed9385e2f8f520a918468f87178

7ae7a84 NFC: Workaround nfcpy message debug exception
6ceb95c Avoid NULL dereference in ieee802_1x_get_mib_sta() printf
97efe70 wpa_supplicant: Fix NULL dereference in tls_verify_cb()
c0c11af wpa_supplicant: Fix NULL dereference in eap_fast_parse_end()
93a1cae Remove unnecessary NULL check
1e2ffc6 Fix theoretical NULL dereference in debug printf
cbf21c7 P2P: Avoid compiler warning in p2p_supplicant.c
5479ff9 DFS: Avoid compiler warnings in src/ap/dfs.c
5e6aa04 wpa_supplicant: Fix memory leak in wfd_subelems error path
88853ae Fix CONFIG_WPS_NFC=y build without CONFIG_P2P=y
7ac7fd4 Add bssid/freq hint for driver-based BSS selection
92484e2 Start using unodified Developer Certificate of Origin v1.1
56ec49c Sync with wireless-testing.git include/uapi/linux/nl80211.h
b64afe2 Fix SAE state validation on AP
d6bfaaa NFC: Add summary and success file options for nfcpy scripts
25cfc6f P2P NFC: Add p2p-nfc.py --handover-only option
7bea076 P2P NFC: Clean up p2p-nfc.py error handling
b0d18bc WPS: Make UUID-from-MAC Address easily available
825fb6b P2P: Do not indicate P2P_FIND failure if p2p_scan is in progress
8c18fcc WPS: Add more debug information to M7 AP Settings
d7a15d5 WPS: Indicate current AP settings in M7 in unconfigurated state
d55fc03 P2P: Handle unexpected GO Neg Req reject message more cleanly
062a7c0 Fix persistent P2P connection failure in case channel list changes

Change-Id: I5c400a6503f9f00d259ff225999593958322a1ba
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index c0ad1c1..663f409 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -951,6 +951,7 @@
 }
 
 
+#ifdef CONFIG_P2P
 static int wpas_ctrl_nfc_get_handover_req_p2p(struct wpa_supplicant *wpa_s,
 					      char *reply, size_t max_len,
 					      int ndef)
@@ -973,6 +974,7 @@
 
 	return res;
 }
+#endif /* CONFIG_P2P */
 
 
 static int wpas_ctrl_nfc_get_handover_req(struct wpa_supplicant *wpa_s,
@@ -1001,10 +1003,12 @@
 			wpa_s, reply, max_len, ndef);
 	}
 
+#ifdef CONFIG_P2P
 	if (os_strcmp(pos, "P2P-CR") == 0) {
 		return wpas_ctrl_nfc_get_handover_req_p2p(
 			wpa_s, reply, max_len, ndef);
 	}
+#endif /* CONFIG_P2P */
 
 	return -1;
 }
@@ -1032,6 +1036,7 @@
 }
 
 
+#ifdef CONFIG_P2P
 static int wpas_ctrl_nfc_get_handover_sel_p2p(struct wpa_supplicant *wpa_s,
 					      char *reply, size_t max_len,
 					      int ndef, int tag)
@@ -1052,6 +1057,7 @@
 
 	return res;
 }
+#endif /* CONFIG_P2P */
 
 
 static int wpas_ctrl_nfc_get_handover_sel(struct wpa_supplicant *wpa_s,
@@ -1084,6 +1090,7 @@
 			os_strcmp(pos, "WPS-CR") == 0, pos2);
 	}
 
+#ifdef CONFIG_P2P
 	if (os_strcmp(pos, "P2P-CR") == 0) {
 		return wpas_ctrl_nfc_get_handover_sel_p2p(
 			wpa_s, reply, max_len, ndef, 0);
@@ -1093,6 +1100,7 @@
 		return wpas_ctrl_nfc_get_handover_sel_p2p(
 			wpa_s, reply, max_len, ndef, 1);
 	}
+#endif /* CONFIG_P2P */
 
 	return -1;
 }
@@ -1160,6 +1168,7 @@
 	struct wpabuf *req, *sel;
 	int ret;
 	char *pos, *role, *type, *pos2;
+#ifdef CONFIG_P2P
 	char *freq;
 	int forced_freq = 0;
 
@@ -1169,6 +1178,7 @@
 		freq += 6;
 		forced_freq = atoi(freq);
 	}
+#endif /* CONFIG_P2P */
 
 	role = cmd;
 	pos = os_strchr(role, ' ');
@@ -1237,11 +1247,14 @@
 
 	if (os_strcmp(role, "INIT") == 0 && os_strcmp(type, "WPS") == 0) {
 		ret = wpas_wps_nfc_report_handover(wpa_s, req, sel);
+#ifdef CONFIG_AP
 	} else if (os_strcmp(role, "RESP") == 0 && os_strcmp(type, "WPS") == 0)
 	{
 		ret = wpas_ap_wps_nfc_report_handover(wpa_s, req, sel);
 		if (ret < 0)
 			ret = wpas_er_wps_nfc_report_handover(wpa_s, req, sel);
+#endif /* CONFIG_AP */
+#ifdef CONFIG_P2P
 	} else if (os_strcmp(role, "INIT") == 0 && os_strcmp(type, "P2P") == 0)
 	{
 		ret = wpas_p2p_nfc_report_handover(wpa_s, 1, req, sel, 0);
@@ -1249,6 +1262,7 @@
 	{
 		ret = wpas_p2p_nfc_report_handover(wpa_s, 0, req, sel,
 						   forced_freq);
+#endif /* CONFIG_P2P */
 	} else {
 		wpa_printf(MSG_DEBUG, "NFC: Unsupported connection handover "
 			   "reported: role=%s type=%s", role, type);
@@ -3490,8 +3504,10 @@
 						  WFD_IE_VENDOR_TYPE);
 		if (wfd) {
 			ret = os_snprintf(pos, end - pos, "wfd_subelems=");
-			if (ret < 0 || ret >= end - pos)
+			if (ret < 0 || ret >= end - pos) {
+				wpabuf_free(wfd);
 				return 0;
+			}
 			pos += ret;
 
 			pos += wpa_snprintf_hex(pos, end - pos,
@@ -4391,7 +4407,7 @@
 		return -1;
 	}
 
-	return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, ht40, vht,
+	return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, ht40, vht,
 					     NULL, 0);
 }
 
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
index 5150a76..2b83637 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
@@ -346,7 +346,7 @@
 		if (ssid == NULL || ssid->disabled != 2)
 			goto inv_args;
 
-		if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, 0,
+		if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, 0, 0,
 						  NULL, 0)) {
 			reply = wpas_dbus_error_unknown_error(
 				message,
diff --git a/wpa_supplicant/examples/p2p-nfc.py b/wpa_supplicant/examples/p2p-nfc.py
index 848f79f..91eba28 100644
--- a/wpa_supplicant/examples/p2p-nfc.py
+++ b/wpa_supplicant/examples/p2p-nfc.py
@@ -33,6 +33,20 @@
 srv = None
 continue_loop = True
 terminate_now = False
+summary_file = None
+success_file = None
+
+def summary(txt):
+    print txt
+    if summary_file:
+        with open(summary_file, 'a') as f:
+            f.write(txt + "\n")
+
+def success_report(txt):
+    summary(txt)
+    if success_file:
+        with open(success_file, 'a') as f:
+            f.write(txt + "\n")
 
 def wpas_connect():
     ifaces = []
@@ -63,7 +77,7 @@
 def wpas_tag_read(message):
     wpas = wpas_connect()
     if (wpas == None):
-        return
+        return False
     cmd = "WPS_NFC_TAG_READ " + str(message).encode("hex")
     global force_freq
     if force_freq:
@@ -77,16 +91,19 @@
     wpas = wpas_connect()
     if (wpas == None):
         return None
-    res = wpas.request("NFC_GET_HANDOVER_REQ NDEF P2P-CR").rstrip().decode("hex")
+    res = wpas.request("NFC_GET_HANDOVER_REQ NDEF P2P-CR").rstrip()
     if "FAIL" in res:
         return None
-    return res
+    return res.decode("hex")
 
 def wpas_get_handover_req_wps():
     wpas = wpas_connect()
     if (wpas == None):
         return None
-    return wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR").rstrip().decode("hex")
+    res = wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR").rstrip()
+    if "FAIL" in res:
+        return None
+    return res.decode("hex")
 
 
 def wpas_get_handover_sel(tag=False):
@@ -94,8 +111,12 @@
     if (wpas == None):
         return None
     if tag:
-        return wpas.request("NFC_GET_HANDOVER_SEL NDEF P2P-CR-TAG").rstrip().decode("hex")
-    return wpas.request("NFC_GET_HANDOVER_SEL NDEF P2P-CR").rstrip().decode("hex")
+        res = wpas.request("NFC_GET_HANDOVER_SEL NDEF P2P-CR-TAG").rstrip()
+    else:
+	res = wpas.request("NFC_GET_HANDOVER_SEL NDEF P2P-CR").rstrip()
+    if "FAIL" in res:
+        return None
+    return res.decode("hex")
 
 
 def wpas_get_handover_sel_wps():
@@ -137,7 +158,7 @@
     if include_p2p_req:
         data = wpas_get_handover_req()
         if (data == None):
-            print "Could not get handover request carrier record from wpa_supplicant"
+            summary("Could not get handover request carrier record from wpa_supplicant")
             return
         print "Handover request carrier record from wpa_supplicant: " + data.encode("hex")
         datamsg = nfc.ndef.Message(data)
@@ -166,31 +187,33 @@
 
     client = nfc.handover.HandoverClient(llc)
     try:
-        print "Trying handover";
+        summary("Trying to initiate NFC connection handover")
         client.connect()
-        print "Connected for handover"
+        summary("Connected for handover")
     except nfc.llcp.ConnectRefused:
-        print "Handover connection refused"
+        summary("Handover connection refused")
         client.close()
         return
     except Exception, e:
-        print "Other exception: " + str(e)
+        summary("Other exception: " + str(e))
         client.close()
         return
 
-    print "Sending handover request"
+    summary("Sending handover request")
 
     if not client.send(message):
-        print "Failed to send handover request"
+        summary("Failed to send handover request")
+        client.close()
+        return
 
-    print "Receiving handover response"
+    summary("Receiving handover response")
     message = client._recv()
     if message is None:
-        print "No response received"
+        summary("No response received")
         client.close()
         return
     if message.type != "urn:nfc:wkt:Hs":
-        print "Response was not Hs - received: " + message.type
+        summary("Response was not Hs - received: " + message.type)
         client.close()
         return
 
@@ -201,7 +224,7 @@
         print e
     print str(message).encode("hex")
     message = nfc.ndef.HandoverSelectMessage(message)
-    print "Handover select received"
+    summary("Handover select received")
     try:
         print message.pretty()
     except Exception, e:
@@ -211,7 +234,10 @@
         print "Remote carrier type: " + carrier.type
         if carrier.type == "application/vnd.wfa.p2p":
             print "P2P carrier type match - send to wpa_supplicant"
-            wpas_report_handover(data, carrier.record, "INIT")
+            if "OK" in wpas_report_handover(data, carrier.record, "INIT"):
+                success_report("P2P handover reported successfully (initiator)")
+            else:
+                summary("P2P handover report rejected")
             break
 
     print "Remove peer"
@@ -237,6 +263,23 @@
         self.ho_server_processing = False
         self.success = False
 
+    # override to avoid parser error in request/response.pretty() in nfcpy
+    # due to new WSC handover format
+    def _process_request(self, request):
+        summary("received handover request {}".format(request.type))
+        response = nfc.ndef.Message("\xd1\x02\x01Hs\x12")
+        if not request.type == 'urn:nfc:wkt:Hr':
+            summary("not a handover request")
+        else:
+            try:
+                request = nfc.ndef.HandoverRequestMessage(request)
+            except nfc.ndef.DecodeError as e:
+                summary("error decoding 'Hr' message: {}".format(e))
+            else:
+                response = self.process_request(request)
+        summary("send handover response {}".format(response.type))
+        return response
+
     def process_request(self, request):
         self.ho_server_processing = True
         clear_raw_mode()
@@ -268,8 +311,11 @@
                 print "Handover select carrier record from wpa_supplicant:"
                 print data.encode("hex")
                 self.sent_carrier = data
-                wpas_report_handover(self.received_carrier, self.sent_carrier,
-                                     "RESP")
+                if "OK" in wpas_report_handover(self.received_carrier, self.sent_carrier, "RESP"):
+                    success_report("P2P handover reported successfully (responder)")
+                else:
+                    summary("P2P handover report rejected")
+                    break
 
                 message = nfc.ndef.Message(data);
                 sel.add_carrier(message[0], "active", message[1:])
@@ -295,8 +341,11 @@
                 print "Handover select carrier record from wpa_supplicant:"
                 print data.encode("hex")
                 self.sent_carrier = data
-                wpas_report_handover_wsc(self.received_carrier,
-                                         self.sent_carrier, "RESP")
+                if "OK" in wpas_report_handover_wsc(self.received_carrier, self.sent_carrier, "RESP"):
+                    success_report("WSC handover reported successfully")
+                else:
+                    summary("WSC handover report rejected")
+                    break
 
                 message = nfc.ndef.Message(data);
                 sel.add_carrier(message[0], "active", message[1:])
@@ -310,7 +359,7 @@
             print e
         print str(sel).encode("hex")
 
-        print "Sending handover select"
+        summary("Sending handover select")
         self.success = True
         return sel
 
@@ -349,23 +398,27 @@
         for record in tag.ndef.message:
             print "record type " + record.type
             if record.type == "application/vnd.wfa.wsc":
-                print "WPS tag - send to wpa_supplicant"
+                summary("WPS tag - send to wpa_supplicant")
                 success = wpas_tag_read(tag.ndef.message)
                 break
             if record.type == "application/vnd.wfa.p2p":
-                print "P2P tag - send to wpa_supplicant"
+                summary("P2P tag - send to wpa_supplicant")
                 success = wpas_tag_read(tag.ndef.message)
                 break
     else:
-        print "Empty tag"
+        summary("Empty tag")
+
+    if success:
+        success_report("Tag read succeeded")
 
     return success
 
 
 def rdwr_connected_p2p_write(tag):
-    print "Tag found - writing"
+    summary("Tag found - writing - " + str(tag))
     global p2p_sel_data
     tag.ndef.message = str(p2p_sel_data)
+    success_report("Tag write succeeded")
     print "Done - remove tag"
     global only_one
     if only_one:
@@ -378,7 +431,7 @@
     print "Write P2P handover select"
     data = wpas_get_handover_sel(tag=True)
     if (data == None):
-        print "Could not get P2P handover select from wpa_supplicant"
+        summary("Could not get P2P handover select from wpa_supplicant")
         return
 
     global p2p_sel_wait_remove
@@ -400,7 +453,7 @@
 
 def rdwr_connected(tag):
     global only_one, no_wait
-    print "Tag connected: " + str(tag)
+    summary("Tag connected: " + str(tag))
 
     if tag.ndef:
         print "NDEF tag: " + tag.type
@@ -413,7 +466,8 @@
             global continue_loop
             continue_loop = False
     else:
-        print "Not an NDEF tag - remove tag"
+        summary("Not an NDEF tag - remove tag")
+        return True
 
     return not no_wait
 
@@ -504,8 +558,14 @@
                         help='do not use stdout input to initiate handover')
     parser.add_argument('--tag-read-only', '-t', action='store_true',
                         help='tag read only (do not allow connection handover)')
+    parser.add_argument('--handover-only', action='store_true',
+                        help='connection handover only (do not allow tag read)')
     parser.add_argument('--freq', '-f',
                         help='forced frequency of operating channel in MHz')
+    parser.add_argument('--summary',
+                        help='summary file for writing status updates')
+    parser.add_argument('--success',
+                        help='success file for writing success update')
     parser.add_argument('command', choices=['write-p2p-sel'],
                         nargs='?')
     args = parser.parse_args()
@@ -533,6 +593,14 @@
         global include_wps_req
         include_wps_req = False
 
+    if args.summary:
+        global summary_file
+        summary_file = args.summary
+
+    if args.success:
+        global success_file
+        success_file = args.success
+
     if args.no_input:
         global no_input
         no_input = True
@@ -557,6 +625,11 @@
                 if args.tag_read_only:
                     if not clf.connect(rdwr={'on-connect': rdwr_connected}):
                         break
+                elif args.handover_only:
+                    if not clf.connect(llcp={'on-startup': llcp_startup,
+                                             'on-connect': llcp_connected},
+                                       terminate=terminate_loop):
+                        break
                 else:
                     if not clf.connect(rdwr={'on-connect': rdwr_connected},
                                        llcp={'on-startup': llcp_startup,
diff --git a/wpa_supplicant/examples/wps-nfc.py b/wpa_supplicant/examples/wps-nfc.py
index 35d1270..7459eb9 100755
--- a/wpa_supplicant/examples/wps-nfc.py
+++ b/wpa_supplicant/examples/wps-nfc.py
@@ -26,6 +26,20 @@
 srv = None
 continue_loop = True
 terminate_now = False
+summary_file = None
+success_file = None
+
+def summary(txt):
+    print txt
+    if summary_file:
+        with open(summary_file, 'a') as f:
+            f.write(txt + "\n")
+
+def success_report(txt):
+    summary(txt)
+    if success_file:
+        with open(success_file, 'a') as f:
+            f.write(txt + "\n")
 
 def wpas_connect():
     ifaces = []
@@ -84,14 +98,19 @@
     wpas = wpas_connect()
     if (wpas == None):
         return None
-    return wpas.request("WPS_NFC_TOKEN NDEF").rstrip().decode("hex")
-
+    ret = wpas.request("WPS_NFC_TOKEN NDEF")
+    if "FAIL" in ret:
+        return None
+    return ret.rstrip().decode("hex")
 
 def wpas_get_handover_req():
     wpas = wpas_connect()
     if (wpas == None):
         return None
-    return wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR").rstrip().decode("hex")
+    ret = wpas.request("NFC_GET_HANDOVER_REQ NDEF WPS-CR")
+    if "FAIL" in ret:
+        return None
+    return ret.rstrip().decode("hex")
 
 
 def wpas_get_handover_sel(uuid):
@@ -123,9 +142,26 @@
         self.ho_server_processing = False
         self.success = False
 
+    # override to avoid parser error in request/response.pretty() in nfcpy
+    # due to new WSC handover format
+    def _process_request(self, request):
+        summary("received handover request {}".format(request.type))
+        response = nfc.ndef.Message("\xd1\x02\x01Hs\x12")
+        if not request.type == 'urn:nfc:wkt:Hr':
+            summary("not a handover request")
+        else:
+            try:
+                request = nfc.ndef.HandoverRequestMessage(request)
+            except nfc.ndef.DecodeError as e:
+                summary("error decoding 'Hr' message: {}".format(e))
+            else:
+                response = self.process_request(request)
+        summary("send handover response {}".format(response.type))
+        return response
+
     def process_request(self, request):
         self.ho_server_processing = True
-        print "HandoverServer - request received"
+        summary("HandoverServer - request received")
         try:
             print "Parsed handover request: " + request.pretty()
         except Exception, e:
@@ -136,15 +172,18 @@
         for carrier in request.carriers:
             print "Remote carrier type: " + carrier.type
             if carrier.type == "application/vnd.wfa.wsc":
-                print "WPS carrier type match - add WPS carrier record"
+                summary("WPS carrier type match - add WPS carrier record")
                 data = wpas_get_handover_sel(self.uuid)
                 if data is None:
-                    print "Could not get handover select carrier record from wpa_supplicant"
+                    summary("Could not get handover select carrier record from wpa_supplicant")
                     continue
                 print "Handover select carrier record from wpa_supplicant:"
                 print data.encode("hex")
                 self.sent_carrier = data
-                wpas_report_handover(carrier.record, self.sent_carrier, "RESP")
+                if "OK" in wpas_report_handover(carrier.record, self.sent_carrier, "RESP"):
+                    success_report("Handover reported successfully (responder)")
+                else:
+                    summary("Handover report rejected (responder)")
 
                 message = nfc.ndef.Message(data);
                 sel.add_carrier(message[0], "active", message[1:])
@@ -156,17 +195,17 @@
             print e
         print str(sel).encode("hex")
 
-        print "Sending handover select"
+        summary("Sending handover select")
         self.success = True
         return sel
 
 
 def wps_handover_init(llc):
-    print "Trying to initiate WPS handover"
+    summary("Trying to initiate WPS handover")
 
     data = wpas_get_handover_req()
     if (data == None):
-        print "Could not get handover request carrier record from wpa_supplicant"
+        summary("Could not get handover request carrier record from wpa_supplicant")
         return
     print "Handover request carrier record from wpa_supplicant: " + data.encode("hex")
 
@@ -184,27 +223,33 @@
 
     client = nfc.handover.HandoverClient(llc)
     try:
-        print "Trying handover";
+        summary("Trying to initiate NFC connection handover")
         client.connect()
-        print "Connected for handover"
+        summary("Connected for handover")
     except nfc.llcp.ConnectRefused:
-        print "Handover connection refused"
+        summary("Handover connection refused")
+        client.close()
+        return
+    except Exception, e:
+        summary("Other exception: " + str(e))
         client.close()
         return
 
-    print "Sending handover request"
+    summary("Sending handover request")
 
     if not client.send(message):
-        print "Failed to send handover request"
+        summary("Failed to send handover request")
+        client.close()
+        return
 
-    print "Receiving handover response"
+    summary("Receiving handover response")
     message = client._recv()
     if message is None:
-        print "No response received"
+        summary("No response received")
         client.close()
         return
     if message.type != "urn:nfc:wkt:Hs":
-        print "Response was not Hs - received: " + message.type
+        summary("Response was not Hs - received: " + message.type)
         client.close()
         return
 
@@ -215,7 +260,7 @@
         print e
     print str(message).encode("hex")
     message = nfc.ndef.HandoverSelectMessage(message)
-    print "Handover select received"
+    summary("Handover select received")
     try:
         print message.pretty()
     except Exception, e:
@@ -225,7 +270,10 @@
         print "Remote carrier type: " + carrier.type
         if carrier.type == "application/vnd.wfa.wsc":
             print "WPS carrier type match - send to wpa_supplicant"
-            wpas_report_handover(data, carrier.record, "INIT")
+            if "OK" in wpas_report_handover(data, carrier.record, "INIT"):
+                success_report("Handover reported successfully (initiator)")
+            else:
+                summary("Handover report rejected (initiator)")
             # nfcpy does not support the new format..
             #wifi = nfc.ndef.WifiConfigRecord(carrier.record)
             #print wifi.pretty()
@@ -250,11 +298,14 @@
         for record in tag.ndef.message:
             print "record type " + record.type
             if record.type == "application/vnd.wfa.wsc":
-                print "WPS tag - send to wpa_supplicant"
+                summary("WPS tag - send to wpa_supplicant")
                 success = wpas_tag_read(tag.ndef.message)
                 break
     else:
-        print "Empty tag"
+        summary("Empty tag")
+
+    if success:
+        success_report("Tag read succeeded")
 
     if wait_remove:
         print "Remove tag"
@@ -265,9 +316,10 @@
 
 
 def rdwr_connected_write(tag):
-    print "Tag found - writing"
+    summary("Tag found - writing - " + str(tag))
     global write_data
     tag.ndef.message = str(write_data)
+    success_report("Tag write succeeded")
     print "Done - remove tag"
     global only_one
     if only_one:
@@ -318,7 +370,7 @@
 
 def rdwr_connected(tag):
     global only_one, no_wait
-    print "Tag connected: " + str(tag)
+    summary("Tag connected: " + str(tag))
 
     if tag.ndef:
         print "NDEF tag: " + tag.type
@@ -331,7 +383,8 @@
             global continue_loop
             continue_loop = False
     else:
-        print "Not an NDEF tag - remove tag"
+        summary("Not an NDEF tag - remove tag")
+        return True
 
     return not no_wait
 
@@ -398,6 +451,10 @@
                         help='UUID of an AP (used for WPS ER operations)')
     parser.add_argument('--id',
                         help='network id (used for WPS ER operations)')
+    parser.add_argument('--summary',
+                        help='summary file for writing status updates')
+    parser.add_argument('--success',
+                        help='success file for writing success update')
     parser.add_argument('command', choices=['write-config',
                                             'write-er-config',
                                             'write-password'],
@@ -413,6 +470,14 @@
     global no_wait
     no_wait = args.no_wait
 
+    if args.summary:
+        global summary_file
+        summary_file = args.summary
+
+    if args.success:
+        global success_file
+        success_file = args.success
+
     logging.basicConfig(level=args.loglevel)
 
     try:
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 2928b6f..1495ea4 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -3055,7 +3055,7 @@
 		if (s) {
 			int go = s->mode == WPAS_MODE_P2P_GO;
 			wpas_p2p_group_add_persistent(
-				wpa_s, s, go, go ? op_freq : 0, 0, 0, NULL,
+				wpa_s, s, go, 0, go ? op_freq : 0, 0, 0, NULL,
 				go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0);
 		} else if (bssid) {
 			wpa_s->user_initiated_pd = 0;
@@ -3168,7 +3168,6 @@
 {
 	struct wpa_supplicant *wpa_s = ctx;
 	struct wpa_ssid *ssid;
-	int freq;
 
 	if (bssid) {
 		wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RESULT
@@ -3224,17 +3223,10 @@
 		"starting persistent group");
 	os_sleep(0, 50000);
 
-	freq = wpa_s->p2p_persistent_go_freq;
-	if (neg_freq > 0 && ssid->mode == WPAS_MODE_P2P_GO &&
-	    freq_included(channels, neg_freq)) {
-		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use frequence %d MHz from invitation for GO mode",
-			neg_freq);
-		freq = neg_freq;
-	}
-
 	wpas_p2p_group_add_persistent(wpa_s, ssid,
 				      ssid->mode == WPAS_MODE_P2P_GO,
-				      freq,
+				      wpa_s->p2p_persistent_go_freq,
+				      neg_freq,
 				      wpa_s->p2p_go_ht40, wpa_s->p2p_go_vht,
 				      channels,
 				      ssid->mode == WPAS_MODE_P2P_GO ?
@@ -3469,7 +3461,7 @@
 						 struct hostapd_hw_modes *mode,
 						 u8 channel, u8 bw)
 {
-	int flag;
+	int flag = 0;
 	enum chan_allowed res, res2;
 
 	res2 = res = has_channel(wpa_s->global, mode, channel, &flag);
@@ -5174,12 +5166,12 @@
 
 int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
 				  struct wpa_ssid *ssid, int addr_allocated,
-				  int freq, int ht40, int vht,
-				  const struct p2p_channels *channels,
+				  int force_freq, int neg_freq, int ht40,
+				  int vht, const struct p2p_channels *channels,
 				  int connection_timeout)
 {
 	struct p2p_go_neg_results params;
-	int go = 0;
+	int go = 0, freq;
 
 	if (ssid->disabled != 2 || ssid->ssid == NULL)
 		return -1;
@@ -5205,9 +5197,15 @@
 	if (ssid->mode != WPAS_MODE_P2P_GO)
 		return -1;
 
-	freq = wpas_p2p_select_go_freq(wpa_s, freq);
-	if (freq < 0)
-		return -1;
+	if (force_freq > 0) {
+		freq = wpas_p2p_select_go_freq(wpa_s, force_freq);
+		if (freq < 0)
+			return -1;
+	} else {
+		freq = wpas_p2p_select_go_freq(wpa_s, neg_freq);
+		if (freq < 0 || (freq > 0 && !freq_included(channels, freq)))
+			freq = 0;
+	}
 
 	if (wpas_p2p_init_go_params(wpa_s, &params, freq, ht40, vht, channels))
 		return -1;
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index 685313c..d3d36b1 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -36,8 +36,8 @@
 		       int freq, int ht40, int vht);
 int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
 				  struct wpa_ssid *ssid, int addr_allocated,
-				  int freq, int ht40, int vht,
-				  const struct p2p_channels *channels,
+				  int force_freq, int neg_freq, int ht40,
+				  int vht, const struct p2p_channels *channels,
 				  int connection_timeout);
 struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
 				       struct wpa_ssid *ssid);
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 455b158..e21c653 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1656,6 +1656,8 @@
 			params.bssid = bss->bssid;
 			params.freq = bss->freq;
 		}
+		params.bssid_hint = bss->bssid;
+		params.freq_hint = bss->freq;
 	} else {
 		params.ssid = ssid->ssid;
 		params.ssid_len = ssid->ssid_len;