aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Dodd <atd7@cornell.edu>2012-12-13 00:37:26 -0500
committerAndrew Dodd <atd7@cornell.edu>2012-12-15 01:20:58 -0500
commit261a70c1fedbfe818956f78aae9c677f4e0fbe7b (patch)
tree1fae8263cd5017277e87a588c865d16bb877a3e4
parent279731e733c27fd8dfb24d740c05f9ba1b4f8db0 (diff)
downloadexternal_wpa_supplicant_8-261a70c1fedbfe818956f78aae9c677f4e0fbe7b.zip
external_wpa_supplicant_8-261a70c1fedbfe818956f78aae9c677f4e0fbe7b.tar.gz
external_wpa_supplicant_8-261a70c1fedbfe818956f78aae9c677f4e0fbe7b.tar.bz2
Use legacy NL80211 STA events for older drivers
This allows tethering on devices with older bcmdhd drivers to be fixed. It conditionally reverts b638fe75d3cb9d21c67386173f10afe65053cc4d "nl80211: Use native cfg80211 sta events" for these boards. Use BOARD_LEGACY_NL80211_STA_EVENTS to enable this conditional revert. Forward-port to JB MR1, squashed in Steve Kondik's commit to handle additional changes. Change-Id: I4e436c57819944515455725cfd7ac7eeb31552ca
-rw-r--r--hostapd/Android.mk4
-rw-r--r--src/drivers/driver_nl80211.c121
-rw-r--r--wpa_supplicant/Android.mk4
-rw-r--r--wpa_supplicant/config_ssid.h2
-rw-r--r--wpa_supplicant/events.c20
-rw-r--r--wpa_supplicant/wpa_supplicant.c5
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h4
7 files changed, 154 insertions, 6 deletions
diff --git a/hostapd/Android.mk b/hostapd/Android.mk
index ee153d0..fefc40b 100644
--- a/hostapd/Android.mk
+++ b/hostapd/Android.mk
@@ -28,6 +28,10 @@ ifeq ($(BOARD_WLAN_DEVICE), bcmdhd)
L_CFLAGS += -DANDROID_P2P
endif
+ifeq ($(BOARD_LEGACY_NL80211_STA_EVENTS),true)
+L_CFLAGS += -DLEGACY_STA_EVENTS
+endif
+
ifeq ($(BOARD_WLAN_DEVICE), qcwcn)
L_CFLAGS += -DANDROID_QCOM_WCN
L_CFLAGS += -DANDROID_P2P
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 4574938..5be2d48 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -306,6 +306,11 @@ static int android_pno_start(struct i802_bss *bss,
static int android_pno_stop(struct i802_bss *bss);
#endif /* ANDROID */
#ifdef ANDROID_P2P
+#ifdef LEGACY_STA_EVENTS
+static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
+ enum wpa_event_type type,
+ const u8 *frame, size_t len);
+#endif /* LEGACY_STA_EVENTS */
int wpa_driver_set_p2p_noa(void *priv, u8 count, int start, int duration);
int wpa_driver_get_p2p_noa(void *priv, u8 *buf, size_t len);
int wpa_driver_set_p2p_ps(void *priv, int legacy_ps, int opp_ps, int ctwindow);
@@ -1098,6 +1103,20 @@ static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
u16 status;
mgmt = (const struct ieee80211_mgmt *) frame;
+#if (defined (CONFIG_AP) || defined (HOSTAPD) ) && defined (LEGACY_STA_EVENTS)
+ 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");
@@ -1132,6 +1151,10 @@ 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 (LEGACY_STA_EVENTS)
+ }
+#endif
+
wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
}
@@ -1304,6 +1327,14 @@ static void mlme_event_mgmt(struct wpa_driver_nl80211_data *drv,
event.rx_action.data = &mgmt->u.action.category + 1;
event.rx_action.len = frame + len - event.rx_action.data;
wpa_supplicant_event(drv->ctx, EVENT_RX_ACTION, &event);
+#if defined (LEGACY_STA_EVENTS)
+ } else if (stype == WLAN_FC_STYPE_ASSOC_REQ) {
+ mlme_event_assoc(drv, frame, len);
+ } else if (stype == WLAN_FC_STYPE_DISASSOC) {
+ mlme_event_deauth_disassoc(drv, EVENT_DISASSOC, frame, len);
+ } else if (stype == WLAN_FC_STYPE_DEAUTH) {
+ mlme_event_deauth_disassoc(drv, EVENT_DEAUTH, frame, len);
+#endif
} else {
event.rx_mgmt.frame = frame;
event.rx_mgmt.frame_len = len;
@@ -1389,6 +1420,13 @@ static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
if (type == EVENT_DISASSOC) {
event.disassoc_info.locally_generated =
!os_memcmp(mgmt->sa, drv->first_bss.addr, ETH_ALEN);
+
+#if defined (LEGACY_STA_EVENTS)
+ 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) {
@@ -1399,6 +1437,13 @@ static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
} else {
event.deauth_info.locally_generated =
!os_memcmp(mgmt->sa, drv->first_bss.addr, ETH_ALEN);
+
+#if defined (LEGACY_STA_EVENTS)
+ 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) {
@@ -2669,7 +2714,7 @@ static int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
drv->poll_command_supported = info.poll_command_supported;
drv->data_tx_status = info.data_tx_status;
-#ifdef ANDROID_P2P
+#if defined(ANDROID_P2P) && !defined(LEGACY_STA_EVENTS)
if(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) {
/* Driver is new enough to support monitorless mode*/
wpa_printf(MSG_DEBUG, "nl80211: Driver is new "
@@ -5328,6 +5373,14 @@ static int wpa_driver_nl80211_send_mlme_freq(struct i802_bss *bss,
data, data_len, NULL, 1, noack,
1);
}
+#if defined (LEGACY_STA_EVENTS)
+ if (freq == 0)
+ freq = bss->freq;
+ if ( is_ap_interface(drv->nlmode)) {
+ return nl80211_send_frame_cmd(bss, freq, 0,
+ data, data_len, &drv->send_action_cookie, 0, noack, 1);
+ }
+#else
if (drv->device_ap_sme && is_ap_interface(drv->nlmode)) {
if (freq == 0)
@@ -5339,7 +5392,7 @@ static int wpa_driver_nl80211_send_mlme_freq(struct i802_bss *bss,
&drv->send_action_cookie,
no_cck, noack, offchanok);
}
-
+#endif
if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) {
/*
@@ -5567,6 +5620,9 @@ static int wpa_driver_nl80211_set_ap(void *priv,
params->short_slot_time, params->ht_opmode,
params->isolate, params->basic_rates);
}
+#if defined(HOSTAPD) && defined(LEGACY_STA_EVENTS)
+ wpa_driver_nl80211_probe_req_report(priv, 1);
+#endif
return ret;
nla_put_failure:
nlmsg_free(msg);
@@ -5604,8 +5660,14 @@ static int wpa_driver_nl80211_set_freq(struct i802_bss *bss,
NL80211_CHAN_HT40PLUS);
break;
default:
+#if !(defined (ANDROID_P2P) || defined (LEGACY_STA_EVENTS))
+/* 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;
}
}
@@ -6329,6 +6391,14 @@ static int nl80211_setup_ap(struct i802_bss *bss)
/* Try to survive without this */
}
+#if defined (LEGACY_STA_EVENTS)
+ /* For AP mode, enable probe req report even if device_ap_sme
+ * is not enabled
+ */
+ wpa_printf(MSG_DEBUG, "nl80211: Enabling probe req report");
+ wpa_driver_nl80211_probe_req_report(bss, 1);
+#endif
+
return 0;
}
@@ -6391,7 +6461,8 @@ static int wpa_driver_nl80211_hapd_send_eapol(
u8 *pos;
int res;
int qos = flags & WPA_STA_WMM;
-#ifndef ANDROID_P2P
+
+#if defined (LEGACY_STA_EVENTS) || !defined (ANDROID_P2P)
if (drv->device_ap_sme || !drv->use_monitor)
#else
if (drv->device_ap_sme && !drv->use_monitor)
@@ -8402,7 +8473,51 @@ static int wpa_driver_nl80211_probe_req_report(void *priv, int report)
(WLAN_FC_STYPE_PROBE_REQ << 4),
NULL, 0) < 0)
goto out_err;
+#if defined (LEGACY_STA_EVENTS)
+ 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(bss, bss->nl_preq,
+ (WLAN_FC_TYPE_MGMT << 2) |
+ (WLAN_FC_STYPE_ASSOC_REQ << 4),
+ NULL, 0) < 0) {
+ goto out_err;
+ }
+ if (nl80211_register_frame(bss, bss->nl_preq,
+ (WLAN_FC_TYPE_MGMT << 2) |
+ (WLAN_FC_STYPE_REASSOC_REQ << 4),
+ NULL, 0) < 0) {
+ goto out_err;
+ }
+
+ if (nl80211_register_frame(bss, bss->nl_preq,
+ (WLAN_FC_TYPE_MGMT << 2) |
+ (WLAN_FC_STYPE_DISASSOC << 4),
+ NULL, 0) < 0) {
+ goto out_err;
+ }
+
+ if (nl80211_register_frame(bss, bss->nl_preq,
+ (WLAN_FC_TYPE_MGMT << 2) |
+ (WLAN_FC_STYPE_DEAUTH << 4),
+ NULL, 0) < 0) {
+ goto out_err;
+ }
+
+ if (nl80211_register_frame(bss, bss->nl_preq,
+ (WLAN_FC_TYPE_MGMT << 2) |
+ (WLAN_FC_STYPE_ACTION << 4),
+ NULL, 0) < 0) {
+ goto out_err;
+ }
+
+done:
+#endif /* ANDROID_P2P */
eloop_register_read_sock(nl_socket_get_fd(bss->nl_preq),
wpa_driver_nl80211_event_receive, bss->nl_cb,
bss->nl_preq);
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 4f58a92..6d94cb2 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -38,6 +38,10 @@ L_CFLAGS += -DANDROID_QCOM_WCN
L_CFLAGS += -DANDROID_P2P
endif
+ifeq ($(BOARD_LEGACY_NL80211_STA_EVENTS),true)
+L_CFLAGS += -DLEGACY_STA_EVENTS
+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\"
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index ff97379..3c4f3ef 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -458,7 +458,7 @@ struct wpa_ssid {
*/
int export_keys;
-#ifdef ANDROID_P2P
+#if defined(ANDROID_P2P) && !defined(LEGACY_STA_EVENTS)
/**
* assoc_retry - Number of times association should be retried.
*/
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 4b1d992..40aee44 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -2531,7 +2531,25 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
sme_event_assoc_reject(wpa_s, data);
#ifdef ANDROID_P2P
-#ifdef CONFIG_P2P
+#if defined(LEGACY_STA_EVENTS)
+ /* If assoc reject is reported by the driver, then avoid
+ * waiting for the authentication timeout. Cancel the
+ * authentication timeout and retry the assoc.
+ */
+ if(wpa_s->assoc_retries++ < 5) {
+ wpa_printf(MSG_ERROR, "Retrying assoc "
+ "Iteration:%d", wpa_s->assoc_retries);
+ wpa_supplicant_cancel_auth_timeout(wpa_s);
+
+ /* Clear the states */
+ wpa_sm_notify_disassoc(wpa_s->wpa);
+ wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
+
+ wpa_s->reassociate = 1;
+ wpa_supplicant_req_scan(wpa_s, 1, 0);
+ } else
+ wpa_s->assoc_retries = 0;
+#else if defined(CONFIG_P2P)
else {
if(!wpa_s->current_ssid) {
wpa_printf(MSG_ERROR, "current_ssid == NULL");
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index d8f3c44..a54239f 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -647,9 +647,14 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
wpa_supplicant_state_txt(state));
#ifdef ANDROID_P2P
+#ifdef LEGACY_STA_EVENTS
+ if(state == WPA_ASSOCIATED || (state <= WPA_INACTIVE))
+ wpa_s->assoc_retries = 0;
+#else
if(state == WPA_ASSOCIATED && wpa_s->current_ssid) {
wpa_s->current_ssid->assoc_retry = 0;
}
+#endif
#endif /* ANDROID_P2P */
if (state != WPA_SCANNING)
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 55f3d88..aa97684 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -309,7 +309,9 @@ struct wpa_supplicant {
struct wpa_bss *current_bss;
int ap_ies_from_associnfo;
unsigned int assoc_freq;
-
+#ifdef LEGACY_STA_EVENTS
+ unsigned int assoc_retries;
+#endif
/* Selected configuration (based on Beacon/ProbeResp WPA IE) */
int pairwise_cipher;
int group_cipher;