[PATCH] AP: use QoS nullfunc for connection poll
Johannes Berg
johannes
Wed Sep 28 01:41:11 PDT 2011
From: Johannes Berg <johannes.berg at intel.com>
When polling a station that has been inactive for a while, hostapd currently
always uses a null data frame. This is a bit strange with uAPSD clients
(though it seems to mostly work) since the EOSP bit can never be set in a
non-QoS frame. Make hostapd use QoS null data frames for probing when the
station is a QoS STA.
Signed-off-by: Johannes Berg <johannes.berg at intel.com>
---
src/ap/sta_info.c | 32 +++++++++++++++++++++-----------
1 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index ef90bf9..ff849ca 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -322,12 +322,16 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
#ifndef CONFIG_NATIVE_WINDOWS
/* send data frame to poll STA and check whether this frame
* is ACKed */
- struct ieee80211_hdr hdr;
+ struct {
+ struct ieee80211_hdr hdr;
+ u16 qos_ctl;
+ } STRUCT_PACKED nulldata;
+ int size = sizeof(struct ieee80211_hdr);
wpa_printf(MSG_DEBUG, " Polling STA with data frame");
sta->flags |= WLAN_STA_PENDING_POLL;
- os_memset(&hdr, 0, sizeof(hdr));
+ os_memset(&nulldata, 0, sizeof(nulldata));
if (hapd->driver &&
os_strcmp(hapd->driver->name, "hostap") == 0) {
/*
@@ -335,22 +339,28 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
* but it is apparently not retried so TX Exc events
* are not received for it.
*/
- hdr.frame_control =
+ nulldata.hdr.frame_control =
IEEE80211_FC(WLAN_FC_TYPE_DATA,
WLAN_FC_STYPE_DATA);
} else {
- hdr.frame_control =
- IEEE80211_FC(WLAN_FC_TYPE_DATA,
- WLAN_FC_STYPE_NULLFUNC);
+ if (sta->flags & WLAN_STA_WMM) {
+ nulldata.hdr.frame_control =
+ IEEE80211_FC(WLAN_FC_TYPE_DATA,
+ WLAN_FC_STYPE_QOS_NULL);
+ size = sizeof(nulldata);
+ } else
+ nulldata.hdr.frame_control =
+ IEEE80211_FC(WLAN_FC_TYPE_DATA,
+ WLAN_FC_STYPE_NULLFUNC);
}
- hdr.frame_control |= host_to_le16(WLAN_FC_FROMDS);
- os_memcpy(hdr.IEEE80211_DA_FROMDS, sta->addr, ETH_ALEN);
- os_memcpy(hdr.IEEE80211_BSSID_FROMDS, hapd->own_addr,
+ nulldata.hdr.frame_control |= host_to_le16(WLAN_FC_FROMDS);
+ os_memcpy(nulldata.hdr.IEEE80211_DA_FROMDS, sta->addr, ETH_ALEN);
+ os_memcpy(nulldata.hdr.IEEE80211_BSSID_FROMDS, hapd->own_addr,
ETH_ALEN);
- os_memcpy(hdr.IEEE80211_SA_FROMDS, hapd->own_addr, ETH_ALEN);
+ os_memcpy(nulldata.hdr.IEEE80211_SA_FROMDS, hapd->own_addr, ETH_ALEN);
- if (hostapd_drv_send_mlme(hapd, &hdr, sizeof(hdr)) < 0)
+ if (hostapd_drv_send_mlme(hapd, &nulldata, size) < 0)
perror("ap_handle_timer: send");
#endif /* CONFIG_NATIVE_WINDOWS */
} else if (sta->timeout_next != STA_REMOVE) {
--
1.7.6.3
More information about the Hostap
mailing list