add support for setting the STA WME fields from WMM

This commit is contained in:
Andreas Schultz 2016-03-03 16:44:15 +01:00
parent 4d56938321
commit 2b489947c2
6 changed files with 67 additions and 0 deletions

View File

@ -193,6 +193,19 @@ int ieee80211_retrieve_information_elements_position(struct ieee80211_ie_items*
case IEEE80211_IE_SSID_LIST:
items->ssid_list = (struct ieee80211_ie_ssid_list *)data;
break;
case IEEE80211_IE_VENDOR_SPECIFIC: {
struct ieee80211_ie_vendor_specific *vs =
(struct ieee80211_ie_vendor_specific *)data;
uint32_t oui = vs->oui[0] << 16 | vs->oui[1] << 8 | vs->oui[2];
if (oui == MICROSOFT_OUI &&
vs->oui_type == WMM_TYPE &&
vs->oui_subtype == WMM_INFORMATION_ELEMENT) {
items->wmm_ie = (struct ieee80211_ie_wmm_information_element *)data;
break;
}
}
}
/* Next Information Element */

View File

@ -474,6 +474,32 @@ struct ieee80211_ie_ssid_list {
uint8_t lists[0];
} STRUCT_PACKED;
/* 802.11 Vendor Specific */
#define IEEE80211_IE_VENDOR_SPECIFIC 221
#define MICROSOFT_OUI 0x0050F2
struct ieee80211_ie_vendor_specific {
uint8_t id;
uint8_t len;
uint8_t oui[3];
uint8_t oui_type;
int8_t oui_subtype;
} STRUCT_PACKED;
#define WMM_TYPE 2
#define WMM_INFORMATION_ELEMENT 0
#define WMM_PARAMETER_ELEMENT 1
struct ieee80211_ie_wmm_information_element {
uint8_t id;
uint8_t len;
uint8_t oui[3];
uint8_t oui_type;
uint8_t oui_subtype;
uint8_t version;
uint8_t qos_info;
} STRUCT_PACKED;
/* 802.11 All information elements */
struct ieee80211_ie_items {
struct ieee80211_ie_ssid *ssid;
@ -487,6 +513,7 @@ struct ieee80211_ie_items {
struct ieee80211_ie_qos_capability *qos_capability;
struct ieee80211_ie_power_constraint *power_constraint;
struct ieee80211_ie_ssid_list *ssid_list;
struct ieee80211_ie_wmm_information_element *wmm_ie;
};
/* IEEE 802.11 functions */

View File

@ -694,6 +694,11 @@ static void wifi_wlan_receive_station_mgmt_association_request(struct wifi_wlan*
/* */
capwap_logging_info("Receive IEEE802.11 Association Request from %s station", station->addrtext);
if (ieitems.wmm_ie != NULL && ieitems.wmm_ie->version == 1) {
station->flags |= WIFI_STATION_FLAGS_WMM;
station->qosinfo = ieitems.wmm_ie->qos_info;
}
/* */
if (wlan->macmode == CAPWAP_ADD_WLAN_MACMODE_LOCAL) {
/* Verify SSID */

View File

@ -360,6 +360,8 @@ struct wifi_station {
/* Authentication */
uint16_t authalgorithm;
uint8_t qosinfo;
};
/* */

View File

@ -1045,8 +1045,24 @@ int nl80211_station_authorize(struct wifi_wlan* wlan, struct wifi_station* stati
memset(&flagstation, 0, sizeof(struct nl80211_sta_flag_update));
flagstation.mask = nl80211_station_get_flags(station);
flagstation.set = flagstation.mask;
log_printf(LOG_DEBUG, " * flags set=0x%x mask=0x%x",
flagstation.set, flagstation.mask);
nla_put(msg, NL80211_ATTR_STA_FLAGS2, sizeof(struct nl80211_sta_flag_update), &flagstation);
if (station->flags & WIFI_STATION_FLAGS_WMM) {
struct nlattr *wme;
log_printf(LOG_DEBUG, " * qosinfo=0x%x", station->qosinfo);
wme = nla_nest_start(msg, NL80211_ATTR_STA_WME);
nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES,
station->qosinfo & WMM_QOSINFO_STA_AC_MASK);
nla_put_u8(msg, NL80211_STA_WME_MAX_SP,
(station->qosinfo >> WMM_QOSINFO_STA_SP_SHIFT) &
WMM_QOSINFO_STA_SP_MASK);
nla_nest_end(msg, wme);
}
/* */
result = nl80211_send_and_recv_msg(wlanhandle->devicehandle->globalhandle, msg, NULL, NULL);
if (result) {

View File

@ -9,6 +9,10 @@
#define nl_sock nl_handle
#endif
#define WMM_QOSINFO_STA_AC_MASK 0x0f
#define WMM_QOSINFO_STA_SP_MASK 0x03
#define WMM_QOSINFO_STA_SP_SHIFT 5
/* */
typedef int (*nl_valid_cb)(struct nl_msg* msg, void* data);