diff mbox

[07/19] P2P: Prefer direct probe responses over GO's client list.

Message ID 1433925829-8019-8-git-send-email-ilan.peer@intel.com
State Accepted
Headers show

Commit Message

Peer, Ilan June 10, 2015, 8:43 a.m. UTC
From: Andrei Otcheretianski <andrei.otcheretianski@intel.com>

A P2P client may be discoverable and reply to probe requests, while at
the same time the P2P GO would also be discoverable and include the
P2P client information in the group info element of the replied probe
responses. If a seeker constantly hears the probe responses from a client
and then from the GO, but handles them in the opposite order (due to scan
results ordering), the more valuable probe response from the client will
be ignored.
Fix this by defining a threshold (1 second) during which the direct probe
response will be preferred over the information acquired from the GO and
will not be considered as old.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Reviewed-by: Ilan Peer <ilan.peer@intel.com>
---
 src/p2p/p2p.c   | 19 +++++++++++++------
 src/p2p/p2p_i.h |  8 ++++++++
 2 files changed, 21 insertions(+), 6 deletions(-)
diff mbox

Patch

diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index 39c8f9b..562a7b1 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -541,6 +541,7 @@  static int p2p_add_group_clients(struct p2p_data *p2p, const u8 *go_dev_addr,
 		os_memcpy(dev->member_in_go_dev, go_dev_addr, ETH_ALEN);
 		os_memcpy(dev->member_in_go_iface, go_interface_addr,
 			  ETH_ALEN);
+		dev->flags |= P2P_DEV_LAST_SEEN_AS_GROUP_CLIENT;
 	}
 
 	return 0;
@@ -759,23 +760,29 @@  int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq,
 
 	/*
 	 * Update the device entry only if the new peer
-	 * entry is newer than the one previously stored.
+	 * entry is newer than the one previously stored, or if
+	 * the device was previously seen as client in a group
+	 * and the new entry isn't older than a threshold.
 	 */
 	if (dev->last_seen.sec > 0 &&
-	    os_reltime_before(rx_time, &dev->last_seen)) {
-		p2p_dbg(p2p, "Do not update peer entry based on old frame (rx_time=%u.%06u last_seen=%u.%06u)",
+	    os_reltime_before(rx_time, &dev->last_seen) &&
+	    (!(dev->flags & P2P_DEV_LAST_SEEN_AS_GROUP_CLIENT) ||
+	       os_reltime_expired(&dev->last_seen, rx_time,
+				  P2P_DEV_GROUP_CLIENT_RESP_THRESHOLD))) {
+		p2p_dbg(p2p, "Do not update peer entry based on old frame (rx_time=%u.%06u last_seen=%u.%06u flags=%x)",
 			(unsigned int) rx_time->sec,
 			(unsigned int) rx_time->usec,
 			(unsigned int) dev->last_seen.sec,
-			(unsigned int) dev->last_seen.usec);
+			(unsigned int) dev->last_seen.usec,
+			dev->flags);
 		p2p_parse_free(&msg);
 		return -1;
 	}
 
 	os_memcpy(&dev->last_seen, rx_time, sizeof(struct os_reltime));
 
-	dev->flags &= ~(P2P_DEV_PROBE_REQ_ONLY | P2P_DEV_GROUP_CLIENT_ONLY);
-
+	dev->flags &= ~(P2P_DEV_PROBE_REQ_ONLY | P2P_DEV_GROUP_CLIENT_ONLY |
+			P2P_DEV_LAST_SEEN_AS_GROUP_CLIENT);
 	if (os_memcmp(addr, p2p_dev_addr, ETH_ALEN) != 0)
 		os_memcpy(dev->interface_addr, addr, ETH_ALEN);
 	if (msg.ssid &&
diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h
index 289a62d..fa3ad85 100644
--- a/src/p2p/p2p_i.h
+++ b/src/p2p/p2p_i.h
@@ -14,6 +14,12 @@ 
 
 #define P2P_GO_NEG_CNF_MAX_RETRY_COUNT 1
 
+/*
+ * A threshold (in seconds) to prefer direct probe response over the client
+ * info recevied from GO
+ */
+#define P2P_DEV_GROUP_CLIENT_RESP_THRESHOLD 1
+
 enum p2p_role_indication;
 
 /*
@@ -107,6 +113,8 @@  struct p2p_device {
 #define P2P_DEV_WAIT_INV_REQ_ACK BIT(19)
 #define P2P_DEV_P2PS_REPORTED BIT(20)
 #define P2P_DEV_PD_PEER_P2PS BIT(21)
+#define P2P_DEV_LAST_SEEN_AS_GROUP_CLIENT BIT(22)
+
 	unsigned int flags;
 
 	int status; /* enum p2p_status_code */