wpa_supplicant: Update to Version 0.8.26 from BRCM

- Add interface command
- Improve scan handling during P2P

BUG: b/6324527, b/6427094

Change-Id: I4425f44d2a15de0725ba4a1b42cc56e10954b314
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index caecf75..06b725b 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -3307,17 +3307,17 @@
 		return 0;
 	}
 #ifdef ANDROID_P2P
-	if (os_strcmp(cmd, "conc_priority") == 0) {
-		if(os_strncmp(cmd+strlen("conc_priority")+1, "sta", 3) == 0)
-			os_strncpy(wpa_s->global->conc_priority, "sta", 3);
-		else if(os_strncmp(cmd+strlen("conc_priority")+1, "p2p", 3) == 0)
-			os_strncpy(wpa_s->global->conc_priority, "p2p", 3);
+	if (os_strcmp(cmd, "conc_pref") == 0) {
+		if (os_strcmp(param, "sta") == 0)
+			wpa_s->global->conc_pref = WPA_CONC_PREF_STA;
+		else if (os_strcmp(param, "p2p") == 0)
+			wpa_s->global->conc_pref = WPA_CONC_PREF_P2P;
 		else {
-			wpa_printf(MSG_ERROR, " conc_priority arg should be either sta or p2p");
+			wpa_printf(MSG_INFO, "Invalid conc_pref value");
 			return -1;
 		}
-		wpa_printf(MSG_DEBUG, "Single Channel Concurrency: Prioritize %s",
-			   wpa_s->global->conc_priority);
+		wpa_printf(MSG_DEBUG, "Single channel concurrency preference: "
+			"%s", param);
 		return 0;
 	}
 #endif
diff --git a/wpa_supplicant/ctrl_iface_unix.c b/wpa_supplicant/ctrl_iface_unix.c
index 6513604..b4af793 100644
--- a/wpa_supplicant/ctrl_iface_unix.c
+++ b/wpa_supplicant/ctrl_iface_unix.c
@@ -164,6 +164,35 @@
 		else
 			reply_len = 2;
 	} else {
+#if defined(CONFIG_P2P) && defined(ANDROID_P2P)
+		char *ifname = NULL, *arg;
+		char cmd[256];
+		/* Skip the command name */
+		arg = os_strchr(buf, ' ');
+		if (arg) {
+			*arg++ = '\0';
+			os_strncpy(cmd, buf, sizeof(cmd));
+			/* Now search for interface= */
+			if (os_strncmp(arg, "interface=", 10) == 0) {
+				ifname = arg + 10;
+				arg = os_strchr(ifname, ' ');
+				if (arg)
+					*arg++ = '\0';
+				wpa_printf(MSG_DEBUG, "Found interface= in the arg %s ifname %s", arg, ifname);
+				for (wpa_s = wpa_s->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
+					if (os_strcmp(wpa_s->ifname, ifname) == 0)
+						break;
+				}
+				if (wpa_s == NULL) {
+					wpa_printf(MSG_ERROR, "P2P: interface=%s does not exist", ifname);
+					wpa_s = eloop_ctx;
+				}
+			}
+			if (arg)
+				os_snprintf(buf, sizeof(buf), "%s %s", cmd, arg);
+		}
+		wpa_printf(MSG_DEBUG, "wpa_s %p cmd %s", wpa_s, buf);
+#endif /* defined CONFIG_P2P && defined ANDROID_P2P */
 		reply = wpa_supplicant_ctrl_iface_process(wpa_s, buf,
 							  &reply_len);
 	}
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index c09245d..c6d91e8 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1017,7 +1017,11 @@
 	wpa_supplicant_notify_scanning(wpa_s, 0);
 
 #ifdef CONFIG_P2P
+#ifdef ANDROID_P2P
+	if (p2p_search_pending(wpa_s->global->p2p) && !wpa_s->global->p2p_disabled &&
+#else
 	if (wpa_s->p2p_cb_on_scan_complete && !wpa_s->global->p2p_disabled &&
+#endif
 	    wpa_s->global->p2p != NULL) {
 		wpa_s->p2p_cb_on_scan_complete = 0;
 		if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) {
@@ -1196,18 +1200,26 @@
 		if (rn2 && os_strcmp(rn, rn2) == 0) {
 			wpa_printf(MSG_DEBUG, "%s: Updating scan results from "
 				   "sibling", ifs->ifname);
-#ifndef ANDROID_P2P
-			_wpa_supplicant_event_scan_results(ifs, data);
+#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
-			/* 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((wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE) && 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);
+			_wpa_supplicant_event_scan_results(ifs, data);
 #endif
 		}
 	}
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 5e7edc8..f9317a8 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -47,7 +47,6 @@
 #define P2P_MAX_CLIENT_IDLE 10
 #endif /* P2P_MAX_CLIENT_IDLE */
 
-
 static void wpas_p2p_long_listen_timeout(void *eloop_ctx, void *timeout_ctx);
 static struct wpa_supplicant *
 wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated,
@@ -63,6 +62,22 @@
 static void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx);
 static void wpas_p2p_set_group_idle_timeout(struct wpa_supplicant *wpa_s);
 
+#ifdef ANDROID_P2P
+static int wpas_global_scan_in_progress(struct wpa_supplicant *wpa_s)
+{
+	struct wpa_supplicant *iface = NULL;
+
+	for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
+		if(iface->scanning  || iface->wpa_state == WPA_SCANNING) {
+			wpa_printf(MSG_DEBUG, "P2P: Scan in progress on %s,"
+			"defer P2P SEARCH", iface->ifname);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+#endif
 
 static void wpas_p2p_scan_res_handler(struct wpa_supplicant *wpa_s,
 				      struct wpa_scan_results *scan_res)
@@ -157,7 +172,11 @@
 
 	if (ret) {
 		wpa_s->scan_res_handler = NULL;
+#ifdef ANDROID_P2P
+		if (wpa_s->scanning || was_in_p2p_scan || wpas_global_scan_in_progress(wpa_s)) {
+#else
 		if (wpa_s->scanning || was_in_p2p_scan) {
+#endif
 			wpa_s->p2p_cb_on_scan_complete = 1;
 			ret = 1;
 		}
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index 43bcc55..4685970 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -80,6 +80,9 @@
 static const char *action_file = NULL;
 static int ping_interval = 5;
 static int interactive = 0;
+#if defined(CONFIG_P2P) && defined(ANDROID_P2P)
+static char* redirect_interface = NULL;
+#endif
 
 struct cli_txt_entry {
 	struct dl_list list;
@@ -400,6 +403,9 @@
 #else		
 	char buf[2048];
 #endif	
+#if defined(CONFIG_P2P) && defined(ANDROID_P2P)
+	char _cmd[256];
+#endif
 	size_t len;
 	int ret;
 
@@ -407,6 +413,22 @@
 		printf("Not connected to wpa_supplicant - command dropped.\n");
 		return -1;
 	}
+#if defined(CONFIG_P2P) && defined(ANDROID_P2P)
+	if (redirect_interface) {
+		char *arg;
+		arg = os_strchr(cmd, ' ');
+		if (arg) {
+			*arg++ = '\0';
+			ret = os_snprintf(_cmd, sizeof(_cmd), "%s %s %s", cmd, redirect_interface, arg);
+		}
+		else {
+			ret = os_snprintf(_cmd, sizeof(_cmd), "%s %s", cmd, redirect_interface);
+		}
+		cmd = _cmd;
+		os_free(redirect_interface);
+		redirect_interface = NULL;
+	}
+#endif
 	len = sizeof(buf) - 1;
 	ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
 			       wpa_cli_msg_cb);
@@ -3192,6 +3214,13 @@
 		printf("Unknown command '%s'\n", argv[0]);
 		ret = 1;
 	} else {
+#if defined(CONFIG_P2P) && defined(ANDROID_P2P)
+		if ( (argc >= 2) && (os_strncmp(argv[1], "interface=", 10) == 0)) {
+			redirect_interface = os_strdup(argv[1]);
+			ret = match->handler(ctrl, argc - 2, &argv[2]);
+		}
+		else
+#endif
 		ret = match->handler(ctrl, argc - 1, &argv[1]);
 	}
 
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 81d00f3..3b184fd 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -3126,9 +3126,9 @@
 #ifdef ANDROID_P2P
 int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
 {
-	if(os_strncmp(wpa_s->global->conc_priority, "p2p", 3) == 0)
+	if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
 		return 1;
-	else if(os_strncmp(wpa_s->global->conc_priority, "sta", 3) == 0)
+	if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
 		return 0;
 
 	/* IF conc_priority is not set, return -1 */
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 74a0dde..21fe5cc 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -220,7 +220,11 @@
 	struct dl_list p2p_srv_upnp; /* struct p2p_srv_upnp */
 	int p2p_disabled;
 #ifdef ANDROID_P2P
-	char conc_priority[5]; /* "sta" or "p2p" */
+	enum wpa_conc_pref {
+		WPA_CONC_PREF_NOT_SET,
+		WPA_CONC_PREF_STA,
+		WPA_CONC_PREF_P2P
+	} conc_pref;
 #endif
 	int cross_connection;
 };