OSDN Git Service

Add P2P support for BRCM CFG80211 driver
authorDmitry Shmidt <dimitrysh@google.com>
Thu, 21 Jul 2011 22:19:46 +0000 (15:19 -0700)
committerDmitry Shmidt <dimitrysh@google.com>
Fri, 22 Jul 2011 03:15:26 +0000 (20:15 -0700)
Change-Id: Iafec4bedbd33836d0a64e7ea054d8a46ef8ec204
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
24 files changed:
hostapd/.config
hostapd/Android.mk
src/ap/beacon.c
src/ap/drv_callbacks.c
src/ap/hostapd.h
src/ap/ieee802_11.c
src/ap/ieee802_1x.c
src/ap/wpa_auth_ie.c
src/common/wpa_ctrl.h
src/drivers/driver_nl80211.c
src/p2p/p2p.c
src/p2p/p2p.h
src/p2p/p2p_build.c
src/p2p/p2p_go_neg.c
src/p2p/p2p_group.c
src/p2p/p2p_invitation.c
src/p2p/p2p_pd.c
wpa_supplicant/.config
wpa_supplicant/Android.mk
wpa_supplicant/ap.c
wpa_supplicant/ctrl_iface.c
wpa_supplicant/events.c
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/p2p_supplicant.h

index e57aafe..8341d4b 100644 (file)
@@ -40,13 +40,13 @@ CONFIG_LIBNL20=y
 #CONFIG_DRIVER_NONE=y
 
 # IEEE 802.11F/IAPP
-CONFIG_IAPP=y
+#CONFIG_IAPP=y
 
 # WPA2/IEEE 802.11i RSN pre-authentication
-CONFIG_RSN_PREAUTH=y
+#CONFIG_RSN_PREAUTH=y
 
 # PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
-CONFIG_PEERKEY=y
+#CONFIG_PEERKEY=y
 
 # IEEE 802.11w (management frame protection)
 # This version is an experimental implementation based on IEEE 802.11w/D1.0
@@ -55,25 +55,25 @@ CONFIG_PEERKEY=y
 #CONFIG_IEEE80211W=y
 
 # Integrated EAP server
-CONFIG_EAP=y
+#CONFIG_EAP=y
 
 # EAP-MD5 for the integrated EAP server
-CONFIG_EAP_MD5=y
+#CONFIG_EAP_MD5=y
 
 # EAP-TLS for the integrated EAP server
-CONFIG_EAP_TLS=y
+#CONFIG_EAP_TLS=y
 
 # EAP-MSCHAPv2 for the integrated EAP server
-CONFIG_EAP_MSCHAPV2=y
+#CONFIG_EAP_MSCHAPV2=y
 
 # EAP-PEAP for the integrated EAP server
-CONFIG_EAP_PEAP=y
+#CONFIG_EAP_PEAP=y
 
 # EAP-GTC for the integrated EAP server
-CONFIG_EAP_GTC=y
+#CONFIG_EAP_GTC=y
 
 # EAP-TTLS for the integrated EAP server
-CONFIG_EAP_TTLS=y
+#CONFIG_EAP_TTLS=y
 
 # EAP-SIM for the integrated EAP server
 #CONFIG_EAP_SIM=y
@@ -109,7 +109,7 @@ CONFIG_EAP_TTLS=y
 # Wi-Fi Protected Setup (WPS)
 CONFIG_WPS=y
 # Enable WSC 2.0 support
-#CONFIG_WPS2=y
+CONFIG_WPS2=y
 # Enable UPnP support for external WPS Registrars
 #CONFIG_WPS_UPNP=y
 
@@ -152,7 +152,7 @@ CONFIG_ANDROID_LOG=y
 #CONFIG_NO_ACCOUNTING=y
 
 # Remove support for RADIUS
-#CONFIG_NO_RADIUS=y
+CONFIG_NO_RADIUS=y
 
 # Remove support for VLANs
 #CONFIG_NO_VLAN=y
@@ -185,3 +185,6 @@ CONFIG_OS=unix
 #LIBS += -lbfd -liberty -lz
 #LIBS_p += -lbfd -liberty -lz
 #LIBS_c += -lbfd -liberty -lz
+
+# Enable AP
+CONFIG_AP=y
index 51c1488..2dbd67d 100644 (file)
@@ -13,6 +13,10 @@ include $(LOCAL_PATH)/.config
 # To ignore possible wrong network configurations
 L_CFLAGS = -DWPA_IGNORE_CONFIG_ERRORS
 
+ifdef CONFIG_DRIVER_NL80211
+L_CFLAGS += -DANDROID_BRCM_P2P_PATCH
+endif
+
 # To force sizeof(enum) = 4
 ifeq ($(TARGET_ARCH),arm)
 L_CFLAGS += -mabi=aapcs-linux
index 5544925..0091064 100644 (file)
@@ -215,11 +215,12 @@ void handle_probe_req(struct hostapd_data *hapd,
                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;
 
index fc4bc31..10e3af9 100644 (file)
@@ -227,6 +227,11 @@ void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr)
        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);
index d4501a1..3764be4 100644 (file)
@@ -81,6 +81,10 @@ struct hostapd_data {
                                 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;
index 4d8dd25..e0a3a36 100644 (file)
@@ -1163,6 +1163,12 @@ static void handle_disassoc(struct hostapd_data *hapd,
        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 @@ static void handle_deauth(struct hostapd_data *hapd,
                        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 @@ static void handle_assoc_cb(struct hostapd_data *hapd,
                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)
index 6b6fd4b..8737455 100644 (file)
@@ -89,18 +89,32 @@ void ieee802_1x_set_sta_authorized(struct hostapd_data *hapd,
                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,
index 5e8d134..9d4aa67 100644 (file)
@@ -253,10 +253,19 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
                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;
index 528cc16..35e5e3d 100644 (file)
@@ -99,6 +99,12 @@ extern "C" {
 
 /** 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 "
index b183749..ab20e8a 100644 (file)
@@ -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 @@ static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
        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 @@ static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
        }
 
        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 @@ static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
                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 @@ static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
                                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 @@ static int wpa_driver_nl80211_send_mlme(void *priv, const u8 *data,
 
        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 @@ static int wpa_driver_nl80211_set_beacon(void *priv,
        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 @@ static int wpa_driver_nl80211_set_beacon(void *priv,
        } 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 @@ static int wpa_driver_nl80211_set_freq(struct wpa_driver_nl80211_data *drv,
                                    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 @@ static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
                        }
                        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 @@ static int nl80211_send_frame_cmd(struct wpa_driver_nl80211_data *drv,
 
        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 @@ static int wpa_driver_nl80211_probe_req_report(void *priv, int report)
 {
        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 @@ static int wpa_driver_nl80211_probe_req_report(void *priv, int report)
                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);
index d4fac56..7147e5c 100644 (file)
@@ -464,6 +464,10 @@ static void p2p_copy_wps_info(struct p2p_device *dev, int probe_req,
 
        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 @@ int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, int level,
                        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 @@ static void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev)
 {
        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 @@ static void p2p_timeout_wait_peer_connect(struct p2p_data *p2p)
         * 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
 }
 
 
index db816a6..81ebe9b 100644 (file)
@@ -292,6 +292,17 @@ struct p2p_config {
         */
        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
         */
index c34db91..d59e54b 100644 (file)
@@ -164,7 +164,16 @@ void p2p_buf_add_device_info(struct wpabuf *buf, struct p2p_data *p2p,
        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;
index 1c96486..f5937b9 100644 (file)
@@ -491,7 +491,15 @@ void p2p_process_go_neg_req(struct p2p_data *p2p, const u8 *sa,
                }
 
                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");
index 14a475d..169985f 100644 (file)
@@ -183,7 +183,12 @@ static struct wpabuf * p2p_group_build_beacon_ie(struct p2p_group *group)
 
        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);
 
index bb2767d..42015ad 100644 (file)
@@ -55,7 +55,11 @@ static struct wpabuf * p2p_build_invitation_req(struct p2p_data *p2p,
        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);
index f7ff06c..32d82f6 100644 (file)
@@ -283,8 +283,21 @@ int p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev,
 {
        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 "
index 1b0ee97..b234de8 100644 (file)
@@ -393,3 +393,7 @@ CONFIG_ANDROID_LOG=y
 # Enable mitigation against certain attacks against TKIP by delaying Michael
 # MIC error reports by a random amount of time between 0 and 60 seconds
 #CONFIG_DELAYED_MIC_ERROR_REPORT=y
+
+# Enable P2P
+CONFIG_P2P=y
+CONFIG_AP=y
index b97c9a3..a59652d 100644 (file)
@@ -31,6 +31,10 @@ include $(LOCAL_PATH)/.config
 # To ignore possible wrong network configurations
 L_CFLAGS = -DWPA_IGNORE_CONFIG_ERRORS
 
+ifdef CONFIG_DRIVER_NL80211
+L_CFLAGS += -DANDROID_BRCM_P2P_PATCH
+endif
+
 # Use Android specific directory for control interface sockets
 L_CFLAGS += -DCONFIG_CTRL_IFACE_CLIENT_DIR=\"/data/misc/wifi/sockets\"
 L_CFLAGS += -DCONFIG_CTRL_IFACE_DIR=\"/data/system/wpa_supplicant\"
index 41dbe23..6d9037a 100644 (file)
@@ -23,7 +23,7 @@
 #include "ap/hostapd.h"
 #include "ap/ap_config.h"
 #include "ap/ap_drv_ops.h"
-#ifdef NEED_AP_MLME
+#if  defined (NEED_AP_MLME) || defined (ANDROID_BRCM_P2P_PATCH)
 #include "ap/ieee802_11.h"
 #endif /* NEED_AP_MLME */
 #include "ap/beacon.h"
@@ -451,6 +451,10 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
                }
 
                hapd_iface->bss[i]->msg_ctx = wpa_s;
+#ifdef ANDROID_BRCM_P2P_PATCH
+               /* Sending the event to parent is required as SSL listens on parent ctrl iface */
+               hapd_iface->bss[i]->msg_ctx_parent = wpa_s->parent;
+#endif
                hapd_iface->bss[i]->public_action_cb = ap_public_action_rx;
                hapd_iface->bss[i]->public_action_cb_ctx = wpa_s;
                hapd_iface->bss[i]->vendor_action_cb = ap_vendor_action_rx;
@@ -486,6 +490,14 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
                wpa_supplicant_ap_deinit(wpa_s);
                return -1;
        }
+       
+#ifdef ANDROID_BRCM_P2P_PATCH
+       if (wpa_drv_probe_req_report(wpa_s, 1) < 0) {
+               wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver to "
+                          "report received Probe Request frames");
+               return -1;
+       }
+#endif
 
        return 0;
 }
@@ -541,7 +553,7 @@ void ap_rx_from_unknown_sta(void *ctx, const u8 *frame, size_t len)
 
 void ap_mgmt_rx(void *ctx, struct rx_mgmt *rx_mgmt)
 {
-#ifdef NEED_AP_MLME
+#if  defined (NEED_AP_MLME) || defined (ANDROID_BRCM_P2P_PATCH)
        struct wpa_supplicant *wpa_s = ctx;
        struct hostapd_frame_info fi;
        os_memset(&fi, 0, sizeof(fi));
@@ -549,7 +561,7 @@ void ap_mgmt_rx(void *ctx, struct rx_mgmt *rx_mgmt)
        fi.ssi_signal = rx_mgmt->ssi_signal;
        ieee802_11_mgmt(wpa_s->ap_iface->bss[0], rx_mgmt->frame,
                        rx_mgmt->frame_len, &fi);
-#endif /* NEED_AP_MLME */
+#endif /* defined (NEED_AP_MLME) || defined (ANDROID_BRCM_P2P_PATCH) */
 }
 
 
index b071f76..1ad7d80 100644 (file)
@@ -303,7 +303,9 @@ static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
 #ifdef CONFIG_AP
        u8 *_p2p_dev_addr = NULL;
 #endif /* CONFIG_AP */
-
+#ifdef ANDROID_BRCM_P2P_PATCH  
+       struct wpa_supplicant *iface;
+#endif
        if (cmd == NULL || os_strcmp(cmd, "any") == 0) {
                _bssid = NULL;
 #ifdef CONFIG_P2P
@@ -322,7 +324,17 @@ static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
                return -1;
        }
 
-#ifdef CONFIG_AP
+#if defined(ANDROID_BRCM_P2P_PATCH) && defined(CONFIG_AP)
+       for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
+               if (iface->ap_iface){
+                       wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: iface 0x%08x wpa_s->ap_iface %p", iface, iface->ap_iface);
+                       wpa_supplicant_ap_wps_pbc(iface, _bssid, _p2p_dev_addr);
+                       return 0;
+               }
+               else
+                       wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: ap_iface is not set iface 0x%08x", iface);
+       }
+#elif defined CONFIG_AP
        if (wpa_s->ap_iface)
                return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid, _p2p_dev_addr);
 #endif /* CONFIG_AP */
@@ -339,6 +351,10 @@ static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
        char *pin;
        int ret;
 
+#if defined ANDROID_BRCM_P2P_PATCH && defined CONFIG_AP
+       struct wpa_supplicant *iface;
+#endif
+
        pin = os_strchr(cmd, ' ');
        if (pin)
                *pin++ = '\0';
@@ -351,7 +367,19 @@ static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
                return -1;
        }
 
-#ifdef CONFIG_AP
+#if defined ANDROID_BRCM_P2P_PATCH && defined CONFIG_AP
+       for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
+               if (iface->ap_iface){
+                       wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: iface 0x%08x wpa_s->ap_iface %p", iface, iface->ap_iface);
+                       /* Call the wps registrar for the main interface */
+                       wpa_supplicant_ap_wps_pin(iface, _bssid, pin,
+                                                        buf, buflen);
+                       return 0;
+               }
+               else
+                       wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: ap_iface is not set iface 0x%08x", iface);
+       }
+#elif defined CONFIG_AP
        if (wpa_s->ap_iface)
                return wpa_supplicant_ap_wps_pin(wpa_s, _bssid, pin,
                                                 buf, buflen);
@@ -2335,6 +2363,16 @@ static int p2p_get_passphrase(struct wpa_supplicant *wpa_s, char *buf,
 {
        struct wpa_ssid *ssid = wpa_s->current_ssid;
 
+#ifdef ANDROID_BRCM_P2P_PATCH
+       struct wpa_supplicant *ifs = NULL;
+       
+       for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
+               if((ifs->ap_iface) && 
+                       (ifs->p2p_group_interface == P2P_GROUP_INTERFACE_GO)) {
+                       ssid = ifs->current_ssid;
+               }
+       }
+#endif
        if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO ||
            ssid->passphrase == NULL)
                return -1;
index 8bccb6b..812cd52 100644 (file)
@@ -724,7 +724,12 @@ void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
         * reassociation is requested. If we are in process of associating with
         * the selected BSSID, do not trigger new attempt.
         */
-       if (wpa_s->reassociate ||
+       if ((wpa_s->reassociate
+#ifdef ANDROID_BRCM_P2P_PATCH
+               && (os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0)
+               && (wpa_s->wpa_state != WPA_COMPLETED)
+#endif
+               )||
            (os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0 &&
             ((wpa_s->wpa_state != WPA_ASSOCIATING &&
               wpa_s->wpa_state != WPA_AUTHENTICATING) ||
@@ -1851,6 +1856,11 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                }
 #endif /* CONFIG_AP */
                wpa_supplicant_event_disassoc(wpa_s, reason_code);
+
+#if defined(ANDROID_BRCM_P2P_PATCH) && defined(CONFIG_P2P)
+               wpas_p2p_group_remove_notif(wpa_s, reason_code);
+#endif
+
                break;
        case EVENT_MICHAEL_MIC_FAILURE:
                wpa_supplicant_event_michael_mic_failure(wpa_s, data);
@@ -1988,6 +1998,25 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                                size_t ie_len = data->rx_mgmt.frame_len -
                                        (mgmt->u.probe_req.variable -
                                         data->rx_mgmt.frame);
+                       #ifdef ANDROID_BRCM_P2P_PATCH
+                               wpa_printf(MSG_DEBUG, "Non-AP: Probe request frame ");
+                       {
+                               /* If we are Go or client, we need not reply the probe reqest on eth0 interface */
+                               struct wpa_supplicant* ifs;
+                               int ignore = 0;
+                               for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
+                                       if ( (ifs->p2p_group_interface == P2P_GROUP_INTERFACE_GO ) ||(ifs->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT )) {
+                                               wpa_printf(MSG_DEBUG, "Non-AP: NEERAJKG Ignoring Probe request");
+                                               ignore = 1;
+                                               break;
+                                       }
+                               }
+                               if(ignore)
+                                       break;
+                               else
+                                       wpa_printf(MSG_DEBUG, "Non-AP: Couln't Ignore Probe request %d", wpa_s->p2p_group_interface);
+                       }
+                       #endif
                                wpas_p2p_probe_req_rx(wpa_s, src, ie, ie_len);
                                break;
                        }
index c34a28c..9a9194a 100644 (file)
@@ -509,8 +509,15 @@ static void wpas_group_formation_completed(struct wpa_supplicant *wpa_s,
                client = ssid->mode == WPAS_MODE_INFRA;
                if (ssid->mode == WPAS_MODE_P2P_GO) {
                        persistent = ssid->p2p_persistent_group;
+#ifndef ANDROID_BRCM_P2P_PATCH
                        os_memcpy(go_dev_addr, wpa_s->parent->own_addr,
                                  ETH_ALEN);
+#else
+                       /* P2P_ADDR: Use p2p_dev_addr instead of own mac addr */
+                       os_memcpy(go_dev_addr, wpa_s->global->p2p_dev_addr,
+                                 ETH_ALEN);
+
+#endif
                } else
                        persistent = wpas_p2p_persistent_group(wpa_s,
                                                               go_dev_addr,
@@ -880,13 +887,22 @@ static void p2p_go_configured(void *ctx, void *data)
                        wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
                        ssid->frequency,
                        params->passphrase ? params->passphrase : "",
+#ifndef ANDROID_BRCM_P2P_PATCH
                        MAC2STR(wpa_s->parent->own_addr),
+#else
+                       /* P2P_ADDR: use p2p_dev_addr instead of own addr */
+                       MAC2STR(wpa_s->global->p2p_dev_addr),
+#endif
                        params->persistent_group ? " [PERSISTENT]" : "");
-
                if (params->persistent_group)
                        network_id = wpas_p2p_store_persistent_group(
                                wpa_s->parent, ssid,
+#ifndef ANDROID_BRCM_P2P_PATCH
                                wpa_s->parent->own_addr);
+#else
+                               /* P2P_ADDR: Use p2p device address */
+                               wpa_s->global->p2p_dev_addr);
+#endif
                if (network_id < 0)
                        network_id = ssid->id;
                wpas_notify_p2p_group_started(wpa_s, ssid, network_id, 0);
@@ -1204,7 +1220,10 @@ void wpas_dev_found(void *ctx, const u8 *addr,
 static void wpas_dev_lost(void *ctx, const u8 *dev_addr)
 {
        struct wpa_supplicant *wpa_s = ctx;
-
+#ifdef ANDROID_BRCM_P2P_PATCH
+       wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_LOST
+               "p2p_dev_addr=" MACSTR, MAC2STR(dev_addr));
+#endif
        wpas_notify_p2p_device_lost(wpa_s, dev_addr);
 }
 
@@ -2353,6 +2372,9 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
        struct p2p_config p2p;
        unsigned int r;
        int i;
+#ifdef ANDROID_BRCM_P2P_PATCH
+       char buf[200];
+#endif
 
        if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_CAPABLE))
                return 0;
@@ -2414,7 +2436,19 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
        p2p.invitation_result = wpas_invitation_result;
        p2p.get_noa = wpas_get_noa;
 
+#ifdef ANDROID_BRCM_P2P_PATCH
+       /* P2P_ADDR: Using p2p_dev_addr to hold the actual p2p device address incase if
+        * we are not using the primary interface for p2p operations.
+        */
+       wpa_drv_driver_cmd(wpa_s,  "P2P_DEV_ADDR", buf, sizeof(buf));   
+       os_memcpy(p2p.p2p_dev_addr, buf, ETH_ALEN);
+       os_memcpy(wpa_s->global->p2p_dev_addr, buf, ETH_ALEN);
+       os_memcpy(p2p.dev_addr, buf, ETH_ALEN);
+       wpa_printf(MSG_DEBUG, "P2P: Device address ("MACSTR")", MAC2STR(p2p.p2p_dev_addr));
+#else
        os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN);
+#endif
+
        os_memcpy(p2p.dev_addr, wpa_s->own_addr, ETH_ALEN);
        p2p.dev_name = wpa_s->conf->device_name;
        p2p.manufacturer = wpa_s->conf->manufacturer;
@@ -3643,6 +3677,9 @@ int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
                return -1;
 
        p2p_ie = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
+#ifdef ANDROID_BRCM_P2P_PATCH 
+       if (p2p_ie == NULL) return -1;
+#endif
        ret = p2p_assoc_req_ie(wpa_s->global->p2p, bss->bssid, buf, len,
                               p2p_group, p2p_ie);
        wpabuf_free(p2p_ie);
@@ -3715,6 +3752,9 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
 {
        enum p2p_invite_role role;
        u8 *bssid = NULL;
+#ifdef ANDROID_BRCM_P2P_PATCH
+       int go;
+#endif
 
        if (ssid->mode == WPAS_MODE_P2P_GO) {
                role = P2P_INVITE_ROLE_GO;
@@ -3723,6 +3763,19 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
                                   "address in invitation command");
                        return -1;
                }
+
+#ifdef ANDROID_BRCM_P2P_PATCH
+       wpa_printf(MSG_DEBUG, "P2P: Check to see if already runnig persistent wpa_s %p grp ssid %s ssid_len %d", wpa_s, ssid->ssid, ssid->ssid_len);
+       if(wpas_get_p2p_group(wpa_s, ssid->ssid, ssid->ssid_len, &go)) {
+               wpa_printf(MSG_DEBUG, "P2P: We are already running persistent group");
+               if (go)
+                       bssid = wpa_s->own_addr;
+               else
+                       wpa_printf(MSG_DEBUG, "P2P: We are running persistent group but go is not set");
+       } else {
+               wpa_printf(MSG_DEBUG, "P2P: We are NOT already running persistent group");
+#endif
+
                if (wpas_p2p_create_iface(wpa_s)) {
                        if (wpas_p2p_add_group_interface(wpa_s,
                                                         WPA_IF_P2P_GO) < 0) {
@@ -3734,6 +3787,9 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
                        bssid = wpa_s->pending_interface_addr;
                } else
                        bssid = wpa_s->own_addr;
+#ifdef ANDROID_BRCM_P2P_PATCH
+       }
+#endif
        } else {
                role = P2P_INVITE_ROLE_CLIENT;
                peer_addr = ssid->bssid;
@@ -3841,14 +3897,22 @@ void wpas_p2p_completed(struct wpa_supplicant *wpa_s)
                wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED
                        "%s client ssid=\"%s\" freq=%d psk=%s go_dev_addr="
                        MACSTR "%s",
+               #ifdef ANDROID_BRCM_P2P_PATCH
+                       wpa_s->ifname, ssid_txt, wpa_s->current_bss->freq, psk,
+               #else
                        wpa_s->ifname, ssid_txt, ssid->frequency, psk,
+               #endif
                        MAC2STR(go_dev_addr),
                        persistent ? " [PERSISTENT]" : "");
        } else {
                wpa_msg(wpa_s->parent, MSG_INFO, P2P_EVENT_GROUP_STARTED
                        "%s client ssid=\"%s\" freq=%d passphrase=\"%s\" "
                        "go_dev_addr=" MACSTR "%s",
+               #ifdef ANDROID_BRCM_P2P_PATCH
+                       wpa_s->ifname, ssid_txt, wpa_s->current_bss->freq,
+               #else
                        wpa_s->ifname, ssid_txt, ssid->frequency,
+               #endif
                        ssid->passphrase ? ssid->passphrase : "",
                        MAC2STR(go_dev_addr),
                        persistent ? " [PERSISTENT]" : "");
@@ -3939,6 +4003,22 @@ void wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
        p2p_deauth_notif(wpa_s->global->p2p, bssid, reason_code, ie, ie_len);
 }
 
+#ifdef ANDROID_BRCM_P2P_PATCH
+void wpas_p2p_group_remove_notif(struct wpa_supplicant *wpa_s, u16 reason_code)
+{
+       if(wpa_s->global->p2p_disabled)
+               return;
+
+       /* If we are running a P2P Client and we received a Deauth/Disassoc from the Go, then remove 
+          the virutal interface on which the client is running. */
+       if((wpa_s != wpa_s->parent) && (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT) && (wpa_s->key_mgmt != WPA_KEY_MGMT_WPS)) {
+
+               wpa_printf(MSG_DEBUG, "P2P: [EVENT_DEAUTH] Removing P2P_CLIENT virtual intf.");
+               wpa_supplicant_cancel_scan(wpa_s);
+               wpas_p2p_interface_unavailable(wpa_s);
+       }
+}
+#endif
 
 void wpas_p2p_disassoc_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
                             u16 reason_code, const u8 *ie, size_t ie_len)
index b1080a5..93a5afd 100644 (file)
@@ -108,6 +108,10 @@ int wpas_p2p_ext_listen(struct wpa_supplicant *wpa_s, unsigned int period,
                        unsigned int interval);
 void wpas_p2p_deauth_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
                           u16 reason_code, const u8 *ie, size_t ie_len);
+#ifdef ANDROID_BRCM_P2P_PATCH
+void wpas_p2p_group_remove_notif(struct wpa_supplicant *wpa_s,
+                               u16 reason_code);
+#endif /* ANDROID_BRCM_P2P_PATCH */
 void wpas_p2p_disassoc_notif(struct wpa_supplicant *wpa_s, const u8 *bssid,
                             u16 reason_code, const u8 *ie, size_t ie_len);
 void wpas_p2p_update_config(struct wpa_supplicant *wpa_s);