From f33bc035824a39017a25bedd7017a3ddf6bec866 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Sat, 16 Jun 2012 20:17:39 +0300
Subject: [PATCH] P2P: Fix P2P Client Discoverability bit updates

The P2P Client Discoverability bit is reserved in most frames and its
value in the local P2P peer table should only be updated based on P2P
Group Info attribute from a GO. Fix this by avoiding changes to this
dev_capab bit based on other P2P frames. It would be more correct to
track this separately for each group in which the peer is a member, but
since we do not do that for the other group specific information either,
this can do for now.

It should be noted that prior to commit
18485b5469c5eeea6a552264fbfaabb089a0a557 wpa_supplicant set this bit in
all P2P frames. However, that commit changed this to match the
specification, i.e., the bit is not set in frames which are received
from P2P Device role. As such, this fix is needed to be able to figure
out that a peer supports client discoverability capability after that
commit.

Signed-hostap: Jouni Malinen <j@w1.fi>
intended-for: hostap-1
---
 src/p2p/p2p.c | 30 ++++++++++++++++++++++++------
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index 295e8f27c..f7915bd50 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -437,13 +437,25 @@ static int p2p_add_group_clients(struct p2p_data *p2p, const u8 *go_dev_addr,
 			continue; /* ignore our own entry */
 		dev = p2p_get_device(p2p, cli->p2p_device_addr);
 		if (dev) {
-			/*
-			 * Update information only if we have not received this
-			 * directly from the client.
-			 */
 			if (dev->flags & (P2P_DEV_GROUP_CLIENT_ONLY |
-					  P2P_DEV_PROBE_REQ_ONLY))
+					  P2P_DEV_PROBE_REQ_ONLY)) {
+				/*
+				 * Update information since we have not
+				 * received this directly from the client.
+				 */
 				p2p_copy_client_info(dev, cli);
+			} else {
+				/*
+				 * Need to update P2P Client Discoverability
+				 * flag since it is valid only in P2P Group
+				 * Info attribute.
+				 */
+				dev->info.dev_capab &=
+					~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
+				dev->info.dev_capab |=
+					cli->dev_capab &
+					P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
+			}
 			if (dev->flags & P2P_DEV_PROBE_REQ_ONLY) {
 				dev->flags &= ~P2P_DEV_PROBE_REQ_ONLY;
 			}
@@ -526,7 +538,13 @@ static void p2p_copy_wps_info(struct p2p_device *dev, int probe_req,
 	}
 
 	if (msg->capability) {
-		dev->info.dev_capab = msg->capability[0];
+		/*
+		 * P2P Client Discoverability bit is reserved in all frames
+		 * that use this function, so do not change its value here.
+		 */
+		dev->info.dev_capab &= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
+		dev->info.dev_capab |= msg->capability[0] &
+			~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
 		dev->info.group_capab = msg->capability[1];
 	}