Accumulative patch from commit 3a2a7c3da64563bfff7a0f46e3654f54a1eacbd1

P2P: Fix regression in GO Negotiation
P2P: Skip Listen phase when peer is expected to be waiting
P2P: Increase GO Negotiation timeouts

Change-Id: I77c8512067f49b46aea79d4bf394a0a24f4d0725
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index 6de50f2..ab917dc 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -240,8 +240,10 @@
 	struct p2p_go_neg_results res;
 	p2p_clear_timeout(p2p);
 	p2p_set_state(p2p, P2P_IDLE);
-	if (p2p->go_neg_peer)
+	if (p2p->go_neg_peer) {
+		p2p->go_neg_peer->flags &= ~P2P_DEV_PEER_WAITING_RESPONSE;
 		p2p->go_neg_peer->wps_method = WPS_NOT_READY;
+	}
 	p2p->go_neg_peer = NULL;
 
 	os_memset(&res, 0, sizeof(res));
@@ -1195,6 +1197,8 @@
 	p2p_set_state(p2p, P2P_IDLE);
 	p2p_free_req_dev_types(p2p);
 	p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
+	if (p2p->go_neg_peer)
+		p2p->go_neg_peer->flags &= ~P2P_DEV_PEER_WAITING_RESPONSE;
 	p2p->go_neg_peer = NULL;
 	p2p->sd_peer = NULL;
 	p2p->invite_peer = NULL;
@@ -3024,6 +3028,7 @@
 static void p2p_go_neg_req_cb(struct p2p_data *p2p, int success)
 {
 	struct p2p_device *dev = p2p->go_neg_peer;
+	int timeout;
 
 	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
 		"P2P: GO Negotiation Request TX callback: success=%d",
@@ -3062,11 +3067,20 @@
 	 * channel.
 	 */
 	p2p_set_state(p2p, P2P_CONNECT);
-#ifdef ANDROID_P2P
-	p2p_set_timeout(p2p, 0, 350000);
-#else
-	p2p_set_timeout(p2p, 0, success ? 200000 : 100000);
-#endif
+	timeout = success ? 500000 : 100000;
+	if (!success && p2p->go_neg_peer &&
+	    (p2p->go_neg_peer->flags & P2P_DEV_PEER_WAITING_RESPONSE)) {
+		unsigned int r;
+		/*
+		 * Peer is expected to wait our response and we will skip the
+		 * listen phase. Add some randomness to the wait time here to
+		 * make it less likely to hit cases where we could end up in
+		 * sync with peer not listening.
+		 */
+		os_get_random((u8 *) &r, sizeof(r));
+		timeout += r % 100000;
+	}
+	p2p_set_timeout(p2p, 0, timeout);
 }
 
 
@@ -3082,11 +3096,7 @@
 		return;
 	}
 	p2p_set_state(p2p, P2P_CONNECT);
-#ifdef ANDROID_P2P
-	p2p_set_timeout(p2p, 0, 350000);
-#else
-	p2p_set_timeout(p2p, 0, 250000);
-#endif
+	p2p_set_timeout(p2p, 0, 500000);
 }
 
 
@@ -3308,6 +3318,15 @@
 		p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1);
 		return;
 	}
+	if (p2p->go_neg_peer &&
+	    (p2p->go_neg_peer->flags & P2P_DEV_PEER_WAITING_RESPONSE) &&
+	    p2p->go_neg_peer->connect_reqs < 120) {
+		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer expected to "
+			"wait our response - skip listen");
+		p2p_connect_send(p2p, p2p->go_neg_peer);
+		return;
+	}
+
 	p2p_set_state(p2p, P2P_CONNECT_LISTEN);
 	p2p_listen_in_find(p2p, 0);
 }
diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c
index bc27e6e..61153d4 100644
--- a/src/p2p/p2p_go_neg.c
+++ b/src/p2p/p2p_go_neg.c
@@ -230,7 +230,7 @@
 	dev->connect_reqs++;
 	if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr,
 			    p2p->cfg->dev_addr, dev->info.p2p_device_addr,
-			    wpabuf_head(req), wpabuf_len(req), 200) < 0) {
+			    wpabuf_head(req), wpabuf_len(req), 500) < 0) {
 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
 			"P2P: Failed to send Action frame");
 		/* Use P2P find to recover and retry */
@@ -777,7 +777,7 @@
 			P2P_PENDING_GO_NEG_RESPONSE_FAILURE;
 	if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
 			    p2p->cfg->dev_addr,
-			    wpabuf_head(resp), wpabuf_len(resp), 250) < 0) {
+			    wpabuf_head(resp), wpabuf_len(resp), 500) < 0) {
 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
 			"P2P: Failed to send Action frame");
 	}