Cumulative patch from commit 848905b12abf2df650c43cb821d36a13246baacb

848905b Avoid undefined references with CONFIG_WPA_TRACE_BFD=y
9e38836 wpa_debug: Remove 2048 byte message length limit
f667e03 P2P: Address few issues seen with P2P SD
e9a6f18 TLS: Add tls_disable_tlsv1_1 and tls_disable_tlsv1_2 phase1 params
cb10c7d RADIUS DAS: Add support for NAS identification attributes
0d7c5e1 RADIUS DAS: Remove PMKSA entry on Disconnect-Request
d87a6ac WPS: Fix STA state validation when processing PutWLANResponse

Change-Id: I4799cad2fe661db567eb3a92af2b3eefb7c96dab
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index 2ecc547..7170e47 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -733,9 +733,6 @@
 
 	p2p_parse_free(&msg);
 
-	if (p2p_pending_sd_req(p2p, dev))
-		dev->flags |= P2P_DEV_SD_SCHEDULE;
-
 	if (dev->flags & P2P_DEV_REPORTED)
 		return 0;
 
@@ -2406,6 +2403,7 @@
 
 	p2p->go_timeout = 100;
 	p2p->client_timeout = 20;
+	p2p->num_p2p_sd_queries = 0;
 
 	p2p_dbg(p2p, "initialized");
 	p2p_channels_dump(p2p, "channels", &p2p->cfg->channels);
@@ -2641,13 +2639,16 @@
 	struct p2p_device *dev;
 	p2p_set_state(p2p, P2P_SEARCH);
 	dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
-		if (dev->flags & P2P_DEV_SD_SCHEDULE) {
-			if (p2p_start_sd(p2p, dev) == 0)
-				return;
-			else
-				break;
-		} else if (dev->req_config_methods &&
-			   !(dev->flags & P2P_DEV_PD_FOR_JOIN)) {
+		if (dev->sd_pending_bcast_queries == 0) {
+			/* Initialize with total number of registered broadcast
+			 * SD queries. */
+			dev->sd_pending_bcast_queries = p2p->num_p2p_sd_queries;
+		}
+
+		if (p2p_start_sd(p2p, dev) == 0)
+			return;
+		if (dev->req_config_methods &&
+		    !(dev->flags & P2P_DEV_PD_FOR_JOIN)) {
 			p2p_dbg(p2p, "Send pending Provision Discovery Request to "
 				MACSTR " (config methods 0x%x)",
 				MAC2STR(dev->info.p2p_device_addr),
@@ -2668,10 +2669,7 @@
 	p2p->pending_action_state = P2P_NO_PENDING_ACTION;
 
 	if (!success) {
-		if (p2p->sd_peer) {
-			p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE;
-			p2p->sd_peer = NULL;
-		}
+		p2p->sd_peer = NULL;
 		p2p_continue_find(p2p);
 		return;
 	}
@@ -3216,7 +3214,6 @@
 	p2p_dbg(p2p, "Service Discovery Query timeout");
 	if (p2p->sd_peer) {
 		p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
-		p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE;
 		p2p->sd_peer = NULL;
 	}
 	p2p_continue_find(p2p);
@@ -3487,7 +3484,7 @@
 			  "country=%c%c\n"
 			  "oper_freq=%d\n"
 			  "req_config_methods=0x%x\n"
-			  "flags=%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n"
+			  "flags=%s%s%s%s%s%s%s%s%s%s%s%s%s\n"
 			  "status=%d\n"
 			  "wait_count=%u\n"
 			  "invitation_reqs=%u\n",
@@ -3510,9 +3507,6 @@
 			  dev->flags & P2P_DEV_REPORTED ? "[REPORTED]" : "",
 			  dev->flags & P2P_DEV_NOT_YET_READY ?
 			  "[NOT_YET_READY]" : "",
-			  dev->flags & P2P_DEV_SD_INFO ? "[SD_INFO]" : "",
-			  dev->flags & P2P_DEV_SD_SCHEDULE ? "[SD_SCHEDULE]" :
-			  "",
 			  dev->flags & P2P_DEV_PD_PEER_DISPLAY ?
 			  "[PD_PEER_DISPLAY]" : "",
 			  dev->flags & P2P_DEV_PD_PEER_KEYPAD ?
diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h
index f105083..6de3461 100644
--- a/src/p2p/p2p_i.h
+++ b/src/p2p/p2p_i.h
@@ -81,8 +81,6 @@
 #define P2P_DEV_PROBE_REQ_ONLY BIT(0)
 #define P2P_DEV_REPORTED BIT(1)
 #define P2P_DEV_NOT_YET_READY BIT(2)
-#define P2P_DEV_SD_INFO BIT(3)
-#define P2P_DEV_SD_SCHEDULE BIT(4)
 #define P2P_DEV_PD_PEER_DISPLAY BIT(5)
 #define P2P_DEV_PD_PEER_KEYPAD BIT(6)
 #define P2P_DEV_USER_REJECTED BIT(7)
@@ -110,6 +108,7 @@
 
 	u8 go_timeout;
 	u8 client_timeout;
+	int sd_pending_bcast_queries;
 };
 
 struct p2p_sd_query {
@@ -256,6 +255,12 @@
 	 */
 	struct p2p_sd_query *sd_query;
 
+	/**
+	 * num_p2p_sd_queries - Total number of broadcast SD queries present in
+	 * the list
+	 */
+	int num_p2p_sd_queries;
+
 	/* GO Negotiation data */
 
 	/**
diff --git a/src/p2p/p2p_sd.c b/src/p2p/p2p_sd.c
index 0e0c7f1..26b9c2d 100644
--- a/src/p2p/p2p_sd.c
+++ b/src/p2p/p2p_sd.c
@@ -52,6 +52,7 @@
 {
 	struct p2p_sd_query *q;
 	int wsd = 0;
+	int count = 0;
 
 	if (!(dev->info.dev_capab & P2P_DEV_CAPAB_SERVICE_DISCOVERY))
 		return NULL; /* peer does not support SD */
@@ -64,8 +65,19 @@
 		/* Use WSD only if the peer indicates support or it */
 		if (q->wsd && !wsd)
 			continue;
-		if (q->for_all_peers && !(dev->flags & P2P_DEV_SD_INFO))
-			return q;
+		/* if the query is a broadcast query */
+		if (q->for_all_peers) {
+			/*
+			 * check if there are any broadcast queries pending for
+			 * this device
+			 */
+			if (dev->sd_pending_bcast_queries <= 0)
+				return NULL;
+			/* query number that needs to be send to the device */
+			if (count == dev->sd_pending_bcast_queries - 1)
+				return q;
+			count++;
+		}
 		if (!q->for_all_peers &&
 		    os_memcmp(q->peer, dev->info.p2p_device_addr, ETH_ALEN) ==
 		    0)
@@ -76,14 +88,37 @@
 }
 
 
+static void p2p_decrease_sd_bc_queries(struct p2p_data *p2p, int query_number)
+{
+	struct p2p_device *dev;
+
+	p2p->num_p2p_sd_queries--;
+	dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
+		if (query_number <= dev->sd_pending_bcast_queries - 1) {
+			/*
+			 * Query not yet sent to the device and it is to be
+			 * removed, so update the pending count.
+			*/
+			dev->sd_pending_bcast_queries--;
+		}
+	}
+}
+
+
 static int p2p_unlink_sd_query(struct p2p_data *p2p,
 			       struct p2p_sd_query *query)
 {
 	struct p2p_sd_query *q, *prev;
+	int query_number = 0;
+
 	q = p2p->sd_queries;
 	prev = NULL;
 	while (q) {
 		if (q == query) {
+			/* If the query is a broadcast query, decrease one from
+			 * all the devices */
+			if (query->for_all_peers)
+				p2p_decrease_sd_bc_queries(p2p, query_number);
 			if (prev)
 				prev->next = q->next;
 			else
@@ -92,6 +127,8 @@
 				p2p->sd_query = NULL;
 			return 1;
 		}
+		if (q->for_all_peers)
+			query_number++;
 		prev = q;
 		q = q->next;
 	}
@@ -118,6 +155,7 @@
 		q = q->next;
 		p2p_free_sd_query(prev);
 	}
+	p2p->num_p2p_sd_queries = 0;
 }
 
 
@@ -262,6 +300,16 @@
 		ret = -1;
 	}
 
+	/* Update the pending broadcast SD query count for this device */
+	dev->sd_pending_bcast_queries--;
+
+	/*
+	 * If there are no pending broadcast queries for this device, mark it as
+	 * done (-1).
+	 */
+	if (dev->sd_pending_bcast_queries == 0)
+		dev->sd_pending_bcast_queries = -1;
+
 	wpabuf_free(req);
 
 	return ret;
@@ -541,8 +589,6 @@
 	p2p_dbg(p2p, "Service Update Indicator: %u", update_indic);
 	pos += 2;
 
-	p2p->sd_peer->flags |= P2P_DEV_SD_INFO;
-	p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE;
 	p2p->sd_peer = NULL;
 
 	if (p2p->sd_query) {
@@ -787,8 +833,6 @@
 		return;
 	}
 
-	p2p->sd_peer->flags |= P2P_DEV_SD_INFO;
-	p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE;
 	p2p->sd_peer = NULL;
 
 	if (p2p->sd_query) {
@@ -841,8 +885,16 @@
 
 	if (dst == NULL) {
 		struct p2p_device *dev;
-		dl_list_for_each(dev, &p2p->devices, struct p2p_device, list)
-			dev->flags &= ~P2P_DEV_SD_INFO;
+
+		p2p->num_p2p_sd_queries++;
+
+		/* Update all the devices for the newly added broadcast query */
+		dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
+			if (dev->sd_pending_bcast_queries <= 0)
+				dev->sd_pending_bcast_queries = 1;
+			else
+				dev->sd_pending_bcast_queries++;
+		}
 	}
 
 	return q;