Add P2P support for BRCM CFG80211 driver

Change-Id: Iafec4bedbd33836d0a64e7ea054d8a46ef8ec204
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index d4fac56..7147e5c 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -464,6 +464,10 @@
 
 	if (msg->capability) {
 		dev->info.dev_capab = msg->capability[0];
+#ifdef ANDROID_BRCM_P2P_PATCH
+	if( dev->info.group_capab != msg->capability[1])
+		dev->flags &= ~P2P_DEV_REPORTED;
+#endif	
 		dev->info.group_capab = msg->capability[1];
 	}
 
@@ -574,6 +578,11 @@
 			freq, msg.ds_params ? *msg.ds_params : -1);
 	}
 	dev->listen_freq = freq;
+#ifdef ANDROID_BRCM_P2P_PATCH	
+	if(msg.group_info)
+		dev->go_state = REMOTE_GO;
+#endif
+
 	if (msg.group_info)
 		dev->oper_freq = freq;
 	dev->info.level = level;
@@ -625,8 +634,12 @@
 {
 	int i;
 
-	if (p2p->go_neg_peer == dev)
+	if (p2p->go_neg_peer == dev) {
+#ifdef ANDROID_BRCM_P2P_PATCH
+		p2p_go_neg_failed(p2p, dev, -1);
+#endif
 		p2p->go_neg_peer = NULL;
+	}
 	if (p2p->invite_peer == dev)
 		p2p->invite_peer = NULL;
 	if (p2p->sd_peer == dev)
@@ -2665,7 +2678,15 @@
 	 * state once per second to give other uses a chance to use the radio.
 	 */
 	p2p_set_state(p2p, P2P_WAIT_PEER_IDLE);
+#ifdef ANDROID_BRCM_P2P_PATCH
+	/*
+	 * We need to be back in Listen state soon enough so that we don't miss
+	 * the GO Nego req from the peer.
+	*/
+	p2p_set_timeout(p2p, 0, 0);
+#else
 	p2p_set_timeout(p2p, 1, 0);
+#endif
 }
 
 
diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h
index db816a6..81ebe9b 100644
--- a/src/p2p/p2p.h
+++ b/src/p2p/p2p.h
@@ -292,6 +292,17 @@
 	 */
 	u8 dev_addr[ETH_ALEN];
 
+#ifdef ANDROID_BRCM_P2P_PATCH
+	/**
+	 * p2p_dev_addr - P2P Device Address
+	 *
+	 * Holds the p2p device address. If the driver uses primary mac address
+	 * for p2p operations, then this will hold the same value as that of 
+	 * dev_addr.
+	 */
+	u8 p2p_dev_addr[ETH_ALEN];
+#endif
+
 	/**
 	 * dev_name - Device Name
 	 */
diff --git a/src/p2p/p2p_build.c b/src/p2p/p2p_build.c
index c34db91..d59e54b 100644
--- a/src/p2p/p2p_build.c
+++ b/src/p2p/p2p_build.c
@@ -164,7 +164,16 @@
 	len = wpabuf_put(buf, 2); /* IE length to be filled */
 
 	/* P2P Device address */
+#ifdef ANDROID_BRCM_P2P_PATCH
+	/* 
+	* P2P_ADDR: Supplicant uses primary mac addr for p2p and hence advertises that. To
+	* to make it compatible with solution using virtual interface for P2P, a new variable
+	* is added to hold the actual p2p device address.
+	*/
+	wpabuf_put_data(buf, p2p->cfg->p2p_dev_addr, ETH_ALEN);
+#else
 	wpabuf_put_data(buf, p2p->cfg->dev_addr, ETH_ALEN);
+#endif
 
 	/* Config Methods */
 	methods = 0;
diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c
index 1c96486..f5937b9 100644
--- a/src/p2p/p2p_go_neg.c
+++ b/src/p2p/p2p_go_neg.c
@@ -491,7 +491,15 @@
 		}
 
 		if (dev->go_neg_req_sent &&
+#ifdef ANDROID_BRCM_P2P_PATCH 
+		/* P2P_ADDR: compare against the p2p device address. The own mac 
+		address may not not be the actual p2p device address, if you 
+		are using a virtual interface.
+		*/
+		    os_memcmp(sa, p2p->cfg->p2p_dev_addr, ETH_ALEN) > 0) {
+#else
 		    os_memcmp(sa, p2p->cfg->dev_addr, ETH_ALEN) > 0) {
+#endif
 			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
 				"P2P: Do not reply since peer has higher "
 				"address and GO Neg Request already sent");
diff --git a/src/p2p/p2p_group.c b/src/p2p/p2p_group.c
index 14a475d..169985f 100644
--- a/src/p2p/p2p_group.c
+++ b/src/p2p/p2p_group.c
@@ -183,7 +183,12 @@
 
 	len = p2p_buf_add_ie_hdr(ie);
 	p2p_group_add_common_ies(group, ie);
+#ifdef ANDROID_BRCM_P2P_PATCH
+	/* P2P_ADDR: Use p2p_dev_addr instead of own mac addr*/
+	p2p_buf_add_device_id(ie, group->p2p->cfg->p2p_dev_addr);
+#else
 	p2p_buf_add_device_id(ie, group->p2p->cfg->dev_addr);
+#endif
 	p2p_group_add_noa(ie, group->noa);
 	p2p_buf_update_ie_hdr(ie, len);
 
diff --git a/src/p2p/p2p_invitation.c b/src/p2p/p2p_invitation.c
index bb2767d..42015ad 100644
--- a/src/p2p/p2p_invitation.c
+++ b/src/p2p/p2p_invitation.c
@@ -55,7 +55,11 @@
 	else if (p2p->inv_role == P2P_INVITE_ROLE_CLIENT)
 		dev_addr = peer->info.p2p_device_addr;
 	else
+#ifdef ANDROID_BRCM_P2P_PATCH
+		dev_addr = p2p->cfg->p2p_dev_addr;
+#else
 		dev_addr = p2p->cfg->dev_addr;
+#endif
 	p2p_buf_add_group_id(buf, dev_addr, p2p->inv_ssid, p2p->inv_ssid_len);
 	p2p_buf_add_device_info(buf, p2p, peer);
 	p2p_buf_update_ie_hdr(buf, len);
diff --git a/src/p2p/p2p_pd.c b/src/p2p/p2p_pd.c
index f7ff06c..32d82f6 100644
--- a/src/p2p/p2p_pd.c
+++ b/src/p2p/p2p_pd.c
@@ -283,8 +283,21 @@
 {
 	struct wpabuf *req;
 	int freq;
-
+#ifdef ANDROID_BRCM_P2P_PATCH
+	if(dev->go_state == REMOTE_GO) {
+		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
+			"P2P: GO Sending it to oper_freq %d", dev->oper_freq);
+		freq= dev->oper_freq;
+	}
+	else {
+		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
+			"P2P: NOT GO oper_freq %d listen_freq %d", dev->oper_freq, dev->listen_freq);
+		freq = dev->listen_freq > 0 ? dev->listen_freq : dev->oper_freq;
+	}
+#else
 	freq = dev->listen_freq > 0 ? dev->listen_freq : dev->oper_freq;
+#endif
+
 	if (freq <= 0) {
 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
 			"P2P: No Listen/Operating frequency known for the "