Add P2P support for BRCM CFG80211 driver

Change-Id: Iafec4bedbd33836d0a64e7ea054d8a46ef8ec204
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 5544925..0091064 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -215,11 +215,12 @@
 		return;
 	ie_len = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));
 
+#ifndef ANDROID_BRCM_P2P_PATCH
 	for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++)
 		if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
 					    mgmt->sa, ie, ie_len) > 0)
 			return;
-
+#endif
 	if (!hapd->iconf->send_probe_response)
 		return;
 
diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
index fc4bc31..10e3af9 100644
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -227,6 +227,11 @@
 	sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
 	wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR,
 		MAC2STR(sta->addr));
+#ifdef ANDROID_BRCM_P2P_PATCH
+	if(hapd->msg_ctx_parent)
+		wpa_msg(hapd->msg_ctx_parent, MSG_INFO, AP_STA_DISCONNECTED MACSTR,
+			MAC2STR(sta->addr));
+#endif /* ANDROID_BRCM_P2P_PATCH */
 	wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
 	sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
 	ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
index d4501a1..3764be4 100644
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -81,6 +81,10 @@
 				 struct sta_info *sta, int reassoc);
 
 	void *msg_ctx; /* ctx for wpa_msg() calls */
+#ifdef ANDROID_BRCM_P2P_PATCH
+	/* Sending the event to parent is required as SSL listens on parent ctrl iface */
+	void *msg_ctx_parent; /* ctx for wpa_msg() calls */
+#endif /*ANDROID_BRCM_P2P_PATCH*/
 
 	struct radius_client_data *radius;
 	u32 acct_session_id_hi, acct_session_id_lo;
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 4d8dd25..e0a3a36 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -1163,6 +1163,12 @@
 	sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK);
 	wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR,
 		MAC2STR(sta->addr));
+#ifdef ANDROID_BRCM_P2P_PATCH
+	if(hapd->msg_ctx_parent)
+		wpa_msg(hapd->msg_ctx_parent, MSG_INFO, AP_STA_DISCONNECTED MACSTR,
+			MAC2STR(sta->addr));
+#endif /* ANDROID_BRCM_P2P_PATCH */
+
 	wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
 		       HOSTAPD_LEVEL_INFO, "disassociated");
@@ -1214,6 +1220,11 @@
 			WLAN_STA_ASSOC_REQ_OK);
 	wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR,
 		MAC2STR(sta->addr));
+#ifdef ANDROID_BRCM_P2P_PATCH
+	if(hapd->msg_ctx_parent)
+		wpa_msg(hapd->msg_ctx_parent, MSG_INFO, AP_STA_DISCONNECTED MACSTR,
+			MAC2STR(sta->addr));
+#endif /* ANDROID_BRCM_P2P_PATCH */
 	wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
 		       HOSTAPD_LEVEL_DEBUG, "deauthenticated");
@@ -1679,6 +1690,12 @@
 		ap_sta_set_authorized(hapd, sta, 1);
 		wpa_msg(hapd->msg_ctx, MSG_INFO,
 			AP_STA_CONNECTED MACSTR, MAC2STR(sta->addr));
+#ifdef ANDROID_BRCM_P2P_PATCH
+		/* Sending the event to parent is required as SSL listens on parent ctrl iface */
+		if(hapd->msg_ctx_parent)
+			wpa_msg(hapd->msg_ctx_parent, MSG_INFO,
+				AP_STA_CONNECTED MACSTR, MAC2STR(sta->addr));
+#endif /* ANDROID_BRCM_P2P_PATCH */
 	}
 
 	if (reassoc)
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index 6b6fd4b..8737455 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -89,18 +89,32 @@
 		return;
 
 	if (authorized) {
-		if (!ap_sta_is_authorized(sta))
+		if (!ap_sta_is_authorized(sta)) {
 			wpa_msg(hapd->msg_ctx, MSG_INFO,
 				AP_STA_CONNECTED MACSTR, MAC2STR(sta->addr));
+#ifdef ANDROID_BRCM_P2P_PATCH
+			/* Sending the event to parent is required as SSL listens on parent ctrl iface */
+			if(hapd->msg_ctx_parent)
+				wpa_msg(hapd->msg_ctx_parent, MSG_INFO,
+					AP_STA_CONNECTED MACSTR, MAC2STR(sta->addr));
+#endif /* ANDROID_BRCM_P2P_PATCH */
+		}
 		ap_sta_set_authorized(hapd, sta, 1);
 		res = hostapd_set_authorized(hapd, sta, 1);
 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
 			       HOSTAPD_LEVEL_DEBUG, "authorizing port");
 	} else {
-		if (ap_sta_is_authorized(sta) && (sta->flags & WLAN_STA_ASSOC))
+		if (ap_sta_is_authorized(sta) && (sta->flags & WLAN_STA_ASSOC)) {
 			wpa_msg(hapd->msg_ctx, MSG_INFO,
 				AP_STA_DISCONNECTED MACSTR,
 				MAC2STR(sta->addr));
+#ifdef ANDROID_BRCM_P2P_PATCH
+			if(hapd->msg_ctx_parent)
+				wpa_msg(hapd->msg_ctx_parent, MSG_INFO,
+					AP_STA_DISCONNECTED MACSTR,
+					MAC2STR(sta->addr));
+#endif /* ANDROID_BRCM_P2P_PATCH */
+		}
 		ap_sta_set_authorized(hapd, sta, 0);
 		res = hostapd_set_authorized(hapd, sta, 0);
 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
diff --git a/src/ap/wpa_auth_ie.c b/src/ap/wpa_auth_ie.c
index 5e8d134..9d4aa67 100644
--- a/src/ap/wpa_auth_ie.c
+++ b/src/ap/wpa_auth_ie.c
@@ -253,10 +253,19 @@
 		capab |= WPA_CAPABILITY_PREAUTH;
 	if (conf->peerkey)
 		capab |= WPA_CAPABILITY_PEERKEY_ENABLED;
+#ifdef ANDROID_BRCM_P2P_PATCH 
+    /* WAR: we should make an get_wpa_rsnie_cap() to get the cap of peer supp 
+	 * Temporally we force tp set replay counter tp 0x3 
+	 * as if wmm is enable in all of supp device
+     */
+    capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2); 
+#else
 	if (conf->wmm_enabled) {
 		/* 4 PTKSA replay counters when using WMM */
 		capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2);
 	}
+#endif /* ANDROID_BRCM_P2P_PATCH */
+
 #ifdef CONFIG_IEEE80211W
 	if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
 		capab |= WPA_CAPABILITY_MFPC;
diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h
index 528cc16..35e5e3d 100644
--- a/src/common/wpa_ctrl.h
+++ b/src/common/wpa_ctrl.h
@@ -99,6 +99,12 @@
 
 /** P2P device found */
 #define P2P_EVENT_DEVICE_FOUND "P2P-DEVICE-FOUND "
+
+#ifdef ANDROID_BRCM_P2P_PATCH
+/** P2P device lost */
+#define P2P_EVENT_DEVICE_LOST "P2P-DEVICE-LOST "
+#endif
+
 /** A P2P device requested GO negotiation, but we were not ready to start the
  * negotiation */
 #define P2P_EVENT_GO_NEG_REQUEST "P2P-GO-NEG-REQUEST "
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index b183749..ab20e8a 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -40,7 +40,9 @@
 #include "radiotap_iter.h"
 #include "rfkill.h"
 #include "driver.h"
-
+#if defined(ANDROID_BRCM_P2P_PATCH) && !defined(HOSTAPD)
+#include "wpa_supplicant_i.h"
+#endif
 #ifdef CONFIG_LIBNL20
 /* libnl 2.0 compatibility code */
 #define nl_handle nl_sock
@@ -642,8 +644,25 @@
 	const struct ieee80211_mgmt *mgmt;
 	union wpa_event_data event;
 	u16 status;
+#ifdef ANDROID_BRCM_P2P_PATCH	
+	struct wpa_supplicant *wpa_s = drv->ctx;
+#endif
 
 	mgmt = (const struct ieee80211_mgmt *) frame;
+#if (defined (CONFIG_AP) || defined (HOSTAPD) ) && defined (ANDROID_BRCM_P2P_PATCH)	
+	if (drv->nlmode == NL80211_IFTYPE_AP || drv->nlmode == NL80211_IFTYPE_P2P_GO) {
+		if (len < 24 + sizeof(mgmt->u.assoc_req)) {
+			wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
+			   "frame");
+			return;
+		}
+		os_memset(&event, 0, sizeof(event));
+		event.assoc_info.freq = drv->assoc_freq;
+		event.assoc_info.req_ies = (u8 *) mgmt->u.assoc_req.variable;
+		event.assoc_info.req_ies_len = len - 24 - sizeof(mgmt->u.assoc_req);
+		event.assoc_info.addr = mgmt->sa;
+	} else {
+#endif	
 	if (len < 24 + sizeof(mgmt->u.assoc_resp)) {
 		wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
 			   "frame");
@@ -677,7 +696,9 @@
 	}
 
 	event.assoc_info.freq = drv->assoc_freq;
-
+#if (defined (CONFIG_AP) || defined(HOSTAPD)) && defined (ANDROID_BRCM_P2P_PATCH)	
+	}
+#endif
 	wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
 }
 
@@ -865,6 +886,12 @@
 		reason_code = le_to_host16(mgmt->u.deauth.reason_code);
 
 	if (type == EVENT_DISASSOC) {
+#ifdef ANDROID_BRCM_P2P_PATCH 
+		if (drv->nlmode == NL80211_IFTYPE_AP ||
+			drv->nlmode == NL80211_IFTYPE_P2P_GO) {
+			event.disassoc_info.addr = mgmt->sa;
+		} else
+#endif
 		event.disassoc_info.addr = bssid;
 		event.disassoc_info.reason_code = reason_code;
 		if (frame + len > mgmt->u.disassoc.variable) {
@@ -873,6 +900,12 @@
 				mgmt->u.disassoc.variable;
 		}
 	} else {
+#ifdef ANDROID_BRCM_P2P_PATCH 		
+		if (drv->nlmode == NL80211_IFTYPE_AP ||
+			drv->nlmode == NL80211_IFTYPE_P2P_GO) {
+		event.deauth_info.addr = mgmt->sa;
+		} else
+#endif
 		event.deauth_info.addr = bssid;
 		event.deauth_info.reason_code = reason_code;
 		if (frame + len > mgmt->u.deauth.variable) {
@@ -3688,8 +3721,11 @@
 
 	mgmt = (struct ieee80211_mgmt *) data;
 	fc = le_to_host16(mgmt->frame_control);
-
+#ifndef ANDROID_BRCM_P2P_PATCH
 	if (drv->nlmode == NL80211_IFTYPE_STATION &&
+#else
+	if (
+#endif
 	    WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
 	    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP) {
 		/*
@@ -3731,8 +3767,11 @@
 	int ret;
 	int beacon_set;
 	int ifindex = if_nametoindex(bss->ifname);
-
-	beacon_set = bss->beacon_set;
+#ifdef ANDROID_BRCM_P2P_PATCH 		
+		beacon_set = 1;
+#else
+		beacon_set = bss->beacon_set;
+#endif
 
 	msg = nlmsg_alloc();
 	if (!msg)
@@ -3758,6 +3797,9 @@
 	} else {
 		bss->beacon_set = 1;
 	}
+#if defined(ANDROID_BRCM_P2P_PATCH) && defined(HOSTAPD)
+	wpa_driver_nl80211_probe_req_report(priv, 1);
+#endif
 	return ret;
  nla_put_failure:
 	return -ENOBUFS;
@@ -3791,8 +3833,14 @@
 				    NL80211_CHAN_HT40PLUS);
 			break;
 		default:
+#ifndef ANDROID_BRCM_P2P_PATCH 
+/* Should be change to HT20 as a default value because P2P firmware does not support 11n for BCM4329 */
 			NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
 				    NL80211_CHAN_HT20);
+#else
+			NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
+				    NL80211_CHAN_NO_HT);
+#endif
 			break;
 		}
 	}
@@ -5961,6 +6009,15 @@
 			}
 			os_memcpy(if_addr, new_addr, ETH_ALEN);
 		}
+#ifdef ANDROID_BRCM_P2P_PATCH
+		 else {
+			/* P2P_ADDR: Driver uses a different mac address than the primary mac */
+			wpa_printf(MSG_DEBUG, "nl80211: Driver uses a "
+				   "different mac address for the Virtual I/F. Get that and store it locally");
+			os_memcpy(if_addr, new_addr, ETH_ALEN);
+
+		}
+#endif
 	}
 #endif /* CONFIG_P2P */
 
@@ -6081,7 +6138,9 @@
 
 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
 	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
+#ifndef ANDROID_BRCM_P2P_PATCH	
 	NLA_PUT_U32(msg, NL80211_ATTR_DURATION, wait);
+#endif	
 	NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
 	NLA_PUT(msg, NL80211_ATTR_FRAME, buf_len, buf);
 
@@ -6249,14 +6308,14 @@
 {
 	struct i802_bss *bss = priv;
 	struct wpa_driver_nl80211_data *drv = bss->drv;
-
+#ifndef ANDROID_BRCM_P2P_PATCH
 	if (drv->nlmode != NL80211_IFTYPE_STATION) {
 		wpa_printf(MSG_DEBUG, "nl80211: probe_req_report control only "
 			   "allowed in station mode (iftype=%d)",
 			   drv->nlmode);
 		return -1;
 	}
-
+#endif
 	if (!report) {
 		if (drv->nl_handle_preq) {
 			eloop_unregister_read_sock(
@@ -6311,6 +6370,45 @@
 		goto out_err3;
 	}
 
+#ifdef ANDROID_BRCM_P2P_PATCH 
+	if (drv->nlmode != NL80211_IFTYPE_AP &&
+		drv->nlmode != NL80211_IFTYPE_P2P_GO) {
+		wpa_printf(MSG_DEBUG, "nl80211: probe_req_report control only "
+			   "allowed in AP or P2P GO mode (iftype=%d)",
+			   drv->nlmode);
+		goto done;
+	}
+	
+	if (nl80211_register_frame(drv, drv->nl_handle_preq,
+			   (WLAN_FC_TYPE_MGMT << 2) |
+			   (WLAN_FC_STYPE_ASSOC_REQ << 4),
+			   NULL, 0) < 0) {
+		goto out_err3;
+	}
+
+	if (nl80211_register_frame(drv, drv->nl_handle_preq,
+			   (WLAN_FC_TYPE_MGMT << 2) |
+			   (WLAN_FC_STYPE_REASSOC_REQ << 4),
+			   NULL, 0) < 0) {
+		goto out_err3;
+	}
+
+	if (nl80211_register_frame(drv, drv->nl_handle_preq,
+			   (WLAN_FC_TYPE_MGMT << 2) |
+			   (WLAN_FC_STYPE_DISASSOC << 4),
+			   NULL, 0) < 0) {
+		goto out_err3;
+	}
+	
+	if (nl80211_register_frame(drv, drv->nl_handle_preq,
+					   (WLAN_FC_TYPE_MGMT << 2) |
+					   (WLAN_FC_STYPE_DEAUTH << 4),
+					   NULL, 0) < 0) {
+		goto out_err3;
+	}
+
+done:
+#endif
 	eloop_register_read_sock(nl_socket_get_fd(drv->nl_handle_preq),
 				 wpa_driver_nl80211_event_receive, drv,
 				 drv->nl_handle_preq);
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 "