[PATCH] AP: use QoS nullfunc for connection poll

Johannes Berg johannes at sipsolutions.net
Wed Sep 28 04:41:11 EDT 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