Accumulative patch from commit 52728dcd25b5074fb7c0493a8155f096089ad6d0

P2P: Stop P2P_PD_DURING_FIND wait on PD Response RX
P2P: Postpone P2P scan only if station mode scan is pending
Use special scan result processing steps only on requesting interface
P2P: Re-start P2P operation if station mode scanning is stopped
P2P: Use common function for re-starting P2P scan after station scan

Change-Id: I62bb738a912483647606de1a5bd5357346ebd8f9
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/p2p/p2p_pd.c b/src/p2p/p2p_pd.c
index 44db682..d8f33b1 100644
--- a/src/p2p/p2p_pd.c
+++ b/src/p2p/p2p_pd.c
@@ -346,6 +346,11 @@
 	if (success && p2p->cfg->prov_disc_resp)
 		p2p->cfg->prov_disc_resp(p2p->cfg->cb_ctx, sa,
 					 report_config_methods);
+
+	if (p2p->state == P2P_PD_DURING_FIND) {
+		p2p_clear_timeout(p2p);
+		p2p_continue_find(p2p);
+	}
 }
 
 
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 6b0b6f9..b117b62 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1091,13 +1091,9 @@
 
 /* Return != 0 if no scan results could be fetched or if scan results should not
  * be shared with other virtual interfaces. */
-#ifdef ANDROID_P2P
 static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
-					      union wpa_event_data *data, int suppress_event)
-#else
-static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
-					      union wpa_event_data *data)
-#endif
+					      union wpa_event_data *data,
+					      int own_request)
 {
 	struct wpa_scan_results *scan_res;
 	int ap = 0;
@@ -1113,7 +1109,7 @@
 	wpa_supplicant_notify_scanning(wpa_s, 0);
 
 #ifdef CONFIG_P2P
-	if (wpa_s->global->p2p_cb_on_scan_complete &&
+	if (own_request && wpa_s->global->p2p_cb_on_scan_complete &&
 	    !wpa_s->global->p2p_disabled &&
 	    wpa_s->global->p2p != NULL && !wpa_s->sta_scan_pending &&
 	    !wpa_s->scan_res_handler) {
@@ -1136,6 +1132,8 @@
 		if (wpa_s->conf->ap_scan == 2 || ap ||
 		    wpa_s->scan_res_handler == scan_only_handler)
 			return -1;
+		if (!own_request)
+			return -1;
 		wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results - try "
 			"scanning again");
 		wpa_supplicant_req_new_scan(wpa_s, 1, 0);
@@ -1158,7 +1156,7 @@
 	}
 #endif /* CONFIG_NO_RANDOM_POOL */
 
-	if (wpa_s->scan_res_handler) {
+	if (own_request && wpa_s->scan_res_handler) {
 		void (*scan_res_handler)(struct wpa_supplicant *wpa_s,
 					 struct wpa_scan_results *scan_res);
 
@@ -1179,18 +1177,10 @@
 		wpa_scan_results_free(scan_res);
 		return 0;
 	}
-#ifdef ANDROID_P2P
-	if(!suppress_event)
-	{
-		wpa_dbg(wpa_s, MSG_DEBUG, "New scan results available");
-		wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
-		wpas_notify_scan_results(wpa_s);
-	}
-#else
+
 	wpa_dbg(wpa_s, MSG_DEBUG, "New scan results available");
 	wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
 	wpas_notify_scan_results(wpa_s);
-#endif
 
 	wpas_notify_scan_done(wpa_s, 1);
 
@@ -1307,11 +1297,8 @@
 {
 	const char *rn, *rn2;
 	struct wpa_supplicant *ifs;
-#ifdef ANDROID_P2P
-	if (_wpa_supplicant_event_scan_results(wpa_s, data, 0) != 0) {
-#else
-	if (_wpa_supplicant_event_scan_results(wpa_s, data) != 0) {
-#endif
+
+	if (_wpa_supplicant_event_scan_results(wpa_s, data, 1) != 0) {
 		/*
 		 * If no scan results could be fetched, then no need to
 		 * notify those interfaces that did not actually request
@@ -1344,27 +1331,7 @@
 		if (rn2 && os_strcmp(rn, rn2) == 0) {
 			wpa_printf(MSG_DEBUG, "%s: Updating scan results from "
 				   "sibling", ifs->ifname);
-#ifdef ANDROID_P2P
-			if ( (ifs->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE) || (ifs->p2p_group_interface != NOT_P2P_GROUP_INTERFACE)) {
-				/* Do not update the scan results from STA interface to p2p interfaces */
-				wpa_printf(MSG_DEBUG, "Not Updating scan results on interface %s from "
-					   "sibling %s", ifs->ifname, wpa_s->ifname);
-				continue;
-			}
-			else {
-				/* P2P_FIND will result in too many SCAN_RESULT_EVENTS within
-				 * no time. Avoid announcing it to application as it may not
-				 * be that useful (since results will be that of only 1,6,11).
-				 * over to any other interface as it
-				 */
-				if(p2p_search_in_progress(wpa_s->global->p2p))
-					_wpa_supplicant_event_scan_results(ifs, data, 1);
-				else
-					_wpa_supplicant_event_scan_results(ifs, data, 0);
-			}
-#else
-			_wpa_supplicant_event_scan_results(ifs, data);
-#endif
+			_wpa_supplicant_event_scan_results(ifs, data, 0);
 		}
 	}
 }
@@ -2552,18 +2519,9 @@
 #ifndef CONFIG_NO_SCAN_PROCESSING
 	case EVENT_SCAN_RESULTS:
 		wpa_supplicant_event_scan_results(wpa_s, data);
-#ifdef CONFIG_P2P
-	if (wpa_s->global->p2p_cb_on_scan_complete && !wpa_s->global->p2p_disabled &&
-	    wpa_s->global->p2p != NULL &&
-	    wpa_s->wpa_state != WPA_AUTHENTICATING &&
-	    wpa_s->wpa_state != WPA_ASSOCIATING) {
-		wpa_s->global->p2p_cb_on_scan_complete = 0;
-		if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) {
-			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Pending P2P operation "
-				"continued after scan result processing");
-		}
-	}
-#endif /* CONFIG_P2P */
+		if (wpa_s->wpa_state != WPA_AUTHENTICATING &&
+		    wpa_s->wpa_state != WPA_ASSOCIATING)
+			wpas_p2p_continue_after_scan(wpa_s);
 		break;
 #endif /* CONFIG_NO_SCAN_PROCESSING */
 	case EVENT_ASSOCINFO:
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 6246dc0..c6856e2 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -158,6 +158,7 @@
 
 	for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
 		if (ifs->sta_scan_pending &&
+		    (wpas_scan_scheduled(ifs) || ifs->scanning) &&
 		    wpas_p2p_in_progress(wpa_s) == 2) {
 			wpa_printf(MSG_DEBUG, "Delaying P2P scan to allow "
 				   "pending station mode scan to be "
@@ -5052,17 +5053,7 @@
 	wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 1);
 
 done:
-	if (wpa_s->global->p2p_cb_on_scan_complete && !wpa_s->global->p2p_disabled &&
-	    wpa_s->global->p2p != NULL) {
-		wpa_s->global->p2p_cb_on_scan_complete = 0;
-		if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) {
-			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Pending P2P operation "
-				"continued after successful connection");
-			p2p_increase_search_delay(
-				wpa_s->global->p2p,
-				wpas_p2p_search_delay(wpa_s));
-		}
-	}
+	wpas_p2p_continue_after_scan(wpa_s);
 }
 
 
@@ -5838,6 +5829,30 @@
 	return 0;
 }
 
+
+void wpas_p2p_continue_after_scan(struct wpa_supplicant *wpa_s)
+{
+	wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Station mode scan operation not "
+		"pending anymore (sta_scan_pending=%d "
+		"p2p_cb_on_scan_complete=%d)", wpa_s->sta_scan_pending,
+		wpa_s->global->p2p_cb_on_scan_complete);
+	wpa_s->sta_scan_pending = 0;
+
+	if (!wpa_s->global->p2p_cb_on_scan_complete)
+		return;
+	wpa_s->global->p2p_cb_on_scan_complete = 0;
+
+	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
+		return;
+
+	if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) {
+		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Pending P2P operation "
+			"continued after successful connection");
+		p2p_increase_search_delay(wpa_s->global->p2p,
+					  wpas_p2p_search_delay(wpa_s));
+	}
+}
+
 #ifdef ANDROID_P2P
 int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s, int freq,
 	struct wpa_ssid *ssid)
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index 7690e56..04ba9b2 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -158,4 +158,12 @@
 			   struct hostapd_hw_modes *mode, u8 channel);
 unsigned int wpas_p2p_search_delay(struct wpa_supplicant *wpa_s);
 
+#ifdef CONFIG_P2P
+void wpas_p2p_continue_after_scan(struct wpa_supplicant *wpa_s);
+#else /* CONFIG_P2P */
+static inline void wpas_p2p_continue_after_scan(struct wpa_supplicant *wpa_s)
+{
+}
+#endif /* CONFIG_P2P */
+
 #endif /* P2P_SUPPLICANT_H */
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 54afd01..825e90b 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -536,12 +536,14 @@
 
 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
 		wpa_dbg(wpa_s, MSG_DEBUG, "Skip scan - interface disabled");
+		wpas_p2p_continue_after_scan(wpa_s);
 		return;
 	}
 
 	if (wpa_s->disconnected && wpa_s->scan_req == NORMAL_SCAN_REQ) {
 		wpa_dbg(wpa_s, MSG_DEBUG, "Disconnected - do not scan");
 		wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
+		wpas_p2p_continue_after_scan(wpa_s);
 		return;
 	}
 #ifdef ANDROID
@@ -555,9 +557,7 @@
 	    wpa_s->scan_req == NORMAL_SCAN_REQ) {
 		wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks - do not scan");
 		wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
-#ifdef CONFIG_P2P
-		wpa_s->sta_scan_pending = 0;
-#endif /* CONFIG_P2P */
+		wpas_p2p_continue_after_scan(wpa_s);
 		return;
 	}
 
@@ -1159,6 +1159,7 @@
 {
 	wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling scan request");
 	eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
+	wpas_p2p_continue_after_scan(wpa_s);
 #ifdef ANDROID
 	wpa_supplicant_notify_scanning(wpa_s, 0);
 #endif
@@ -1636,3 +1637,9 @@
 	wpas_notify_scan_results(wpa_s);
 	wpas_notify_scan_done(wpa_s, 1);
 }
+
+
+int wpas_scan_scheduled(struct wpa_supplicant *wpa_s)
+{
+	return eloop_is_timeout_registered(wpa_supplicant_scan, wpa_s, NULL);
+}
diff --git a/wpa_supplicant/scan.h b/wpa_supplicant/scan.h
index 5ecfa00..e892479 100644
--- a/wpa_supplicant/scan.h
+++ b/wpa_supplicant/scan.h
@@ -35,5 +35,6 @@
 void wpa_supplicant_update_scan_int(struct wpa_supplicant *wpa_s, int sec);
 void scan_only_handler(struct wpa_supplicant *wpa_s,
 		       struct wpa_scan_results *scan_res);
+int wpas_scan_scheduled(struct wpa_supplicant *wpa_s);
 
 #endif /* SCAN_H */
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 7a93716..6fb1cae 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -199,16 +199,7 @@
 	 */
 	wpa_supplicant_req_scan(wpa_s, 1, 0);
 
-#ifdef CONFIG_P2P
-	if (wpa_s->global->p2p_cb_on_scan_complete && !wpa_s->global->p2p_disabled &&
-	    wpa_s->global->p2p != NULL) {
-		wpa_s->global->p2p_cb_on_scan_complete = 0;
-		if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) {
-			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Pending P2P operation "
-				"continued after timed out authentication");
-		}
-	}
-#endif /* CONFIG_P2P */
+	wpas_p2p_continue_after_scan(wpa_s);
 }
 
 
@@ -3575,16 +3566,7 @@
 	wpa_supplicant_req_scan(wpa_s, timeout / 1000,
 				1000 * (timeout % 1000));
 
-#ifdef CONFIG_P2P
-	if (wpa_s->global->p2p_cb_on_scan_complete && !wpa_s->global->p2p_disabled &&
-	    wpa_s->global->p2p != NULL) {
-		wpa_s->global->p2p_cb_on_scan_complete = 0;
-		if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) {
-			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Pending P2P operation "
-				"continued after failed association");
-		}
-	}
-#endif /* CONFIG_P2P */
+	wpas_p2p_continue_after_scan(wpa_s);
 }