WMM AC: Parse WMM IE on association

Initialize WMM AC data structures upon successful association
with an AP that publishes WMM support, and deinitialize the data
structure when the association is no longer valid.

Signed-off-by: Moshe Benji <moshe.benji@intel.com>
Signed-off-by: Eliad Peller <eliadx.peller@intel.com>
This commit is contained in:
Moshe Benji 2014-10-22 08:03:54 -04:00 committed by Jouni Malinen
parent 7e0e10693a
commit a0413b1734
7 changed files with 198 additions and 2 deletions

View file

@ -884,6 +884,8 @@ struct wmm_information_element {
} STRUCT_PACKED; } STRUCT_PACKED;
#define WMM_QOSINFO_AP_UAPSD 0x80
#define WMM_QOSINFO_STA_AC_MASK 0x0f #define WMM_QOSINFO_STA_AC_MASK 0x0f
#define WMM_QOSINFO_STA_SP_MASK 0x03 #define WMM_QOSINFO_STA_SP_MASK 0x03
#define WMM_QOSINFO_STA_SP_SHIFT 5 #define WMM_QOSINFO_STA_SP_SHIFT 5
@ -951,11 +953,12 @@ struct wmm_tspec_element {
/* Access Categories / ACI to AC coding */ /* Access Categories / ACI to AC coding */
enum { enum wmm_ac {
WMM_AC_BE = 0 /* Best Effort */, WMM_AC_BE = 0 /* Best Effort */,
WMM_AC_BK = 1 /* Background */, WMM_AC_BK = 1 /* Background */,
WMM_AC_VI = 2 /* Video */, WMM_AC_VI = 2 /* Video */,
WMM_AC_VO = 3 /* Voice */ WMM_AC_VO = 3 /* Voice */,
WMM_AC_NUM = 4
}; };

View file

@ -83,6 +83,7 @@ OBJS += eap_register.c
OBJS += src/utils/common.c OBJS += src/utils/common.c
OBJS += src/utils/wpa_debug.c OBJS += src/utils/wpa_debug.c
OBJS += src/utils/wpabuf.c OBJS += src/utils/wpabuf.c
OBJS += wmm_ac.c
OBJS_p = wpa_passphrase.c OBJS_p = wpa_passphrase.c
OBJS_p += src/utils/common.c OBJS_p += src/utils/common.c
OBJS_p += src/utils/wpa_debug.c OBJS_p += src/utils/wpa_debug.c

View file

@ -80,6 +80,7 @@ OBJS_p += ../src/utils/wpabuf.o
OBJS_c = wpa_cli.o ../src/common/wpa_ctrl.o OBJS_c = wpa_cli.o ../src/common/wpa_ctrl.o
OBJS_c += ../src/utils/wpa_debug.o OBJS_c += ../src/utils/wpa_debug.o
OBJS_c += ../src/utils/common.o OBJS_c += ../src/utils/common.o
OBJS += wmm_ac.o
ifndef CONFIG_OS ifndef CONFIG_OS
ifdef CONFIG_NATIVE_WINDOWS ifdef CONFIG_NATIVE_WINDOWS

View file

@ -44,6 +44,7 @@
#include "interworking.h" #include "interworking.h"
#include "mesh.h" #include "mesh.h"
#include "mesh_mpm.h" #include "mesh_mpm.h"
#include "wmm_ac.h"
#ifndef CONFIG_NO_SCAN_PROCESSING #ifndef CONFIG_NO_SCAN_PROCESSING
@ -2037,6 +2038,12 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
#endif /* CONFIG_IBSS_RSN */ #endif /* CONFIG_IBSS_RSN */
wpas_wps_notify_assoc(wpa_s, bssid); wpas_wps_notify_assoc(wpa_s, bssid);
if (data) {
wmm_ac_notify_assoc(wpa_s, data->assoc_info.resp_ies,
data->assoc_info.resp_ies_len,
&data->assoc_info.wmm_params);
}
} }
@ -2124,6 +2131,8 @@ static void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s,
return; return;
} }
wmm_ac_notify_disassoc(wpa_s);
if (could_be_psk_mismatch(wpa_s, reason_code, locally_generated)) { if (could_be_psk_mismatch(wpa_s, reason_code, locally_generated)) {
wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - " wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - "
"pre-shared key may be incorrect"); "pre-shared key may be incorrect");

128
wpa_supplicant/wmm_ac.c Normal file
View file

@ -0,0 +1,128 @@
/*
* Wi-Fi Multimedia Admission Control (WMM-AC)
* Copyright(c) 2014, Intel Mobile Communication GmbH.
* Copyright(c) 2014, Intel Corporation. All rights reserved.
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "includes.h"
#include "utils/common.h"
#include "common/ieee802_11_common.h"
#include "wpa_supplicant_i.h"
#include "driver_i.h"
#include "wmm_ac.h"
static struct wmm_ac_assoc_data *
wmm_ac_process_param_elem(struct wpa_supplicant *wpa_s, const u8 *ies,
size_t ies_len)
{
struct ieee802_11_elems elems;
struct wmm_parameter_element *wmm_params;
struct wmm_ac_assoc_data *assoc_data;
int i;
/* Parsing WMM Parameter Element */
if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) != ParseOK) {
wpa_printf(MSG_DEBUG, "WMM AC: could not parse assoc ies");
return NULL;
}
if (!elems.wmm) {
wpa_printf(MSG_DEBUG, "WMM AC: No WMM IE");
return NULL;
}
if (elems.wmm_len != sizeof(*wmm_params)) {
wpa_printf(MSG_WARNING, "WMM AC: Invalid WMM ie length");
return NULL;
}
wmm_params = (struct wmm_parameter_element *)(elems.wmm);
assoc_data = os_zalloc(sizeof(*assoc_data));
if (!assoc_data)
return NULL;
for (i = 0; i < WMM_AC_NUM; i++)
assoc_data->ac_params[i].acm =
!!(wmm_params->ac[i].aci_aifsn & WMM_AC_ACM);
wpa_printf(MSG_DEBUG,
"WMM AC: AC mandatory: AC_BE=%u AC_BK=%u AC_VI=%u AC_VO=%u",
assoc_data->ac_params[WMM_AC_BE].acm,
assoc_data->ac_params[WMM_AC_BK].acm,
assoc_data->ac_params[WMM_AC_VI].acm,
assoc_data->ac_params[WMM_AC_VO].acm);
return assoc_data;
}
static int wmm_ac_init(struct wpa_supplicant *wpa_s, const u8 *ies,
size_t ies_len, const struct wmm_params *wmm_params)
{
struct wmm_ac_assoc_data *assoc_data;
u8 ac;
if (wpa_s->wmm_ac_assoc_info) {
wpa_printf(MSG_ERROR, "WMM AC: Already initialized");
return -1;
}
if (!ies) {
wpa_printf(MSG_ERROR, "WMM AC: Missing IEs");
return -1;
}
if (!(wmm_params->info_bitmap & WMM_PARAMS_UAPSD_QUEUES_INFO)) {
wpa_printf(MSG_DEBUG, "WMM AC: Missing U-APSD configuration");
return -1;
}
assoc_data = wmm_ac_process_param_elem(wpa_s, ies, ies_len);
if (!assoc_data)
return -1;
wpa_printf(MSG_DEBUG, "WMM AC: U-APSD queues=0x%x",
wmm_params->uapsd_queues);
for (ac = 0; ac < WMM_AC_NUM; ac++) {
assoc_data->ac_params[ac].uapsd =
!!(wmm_params->uapsd_queues & BIT(ac));
}
wpa_s->wmm_ac_assoc_info = assoc_data;
return 0;
}
static void wmm_ac_deinit(struct wpa_supplicant *wpa_s)
{
os_free(wpa_s->wmm_ac_assoc_info);
wpa_s->wmm_ac_assoc_info = NULL;
}
void wmm_ac_notify_assoc(struct wpa_supplicant *wpa_s, const u8 *ies,
size_t ies_len, const struct wmm_params *wmm_params)
{
if (wmm_ac_init(wpa_s, ies, ies_len, wmm_params))
return;
wpa_printf(MSG_DEBUG,
"WMM AC: Valid WMM association, WMM AC is enabled");
}
void wmm_ac_notify_disassoc(struct wpa_supplicant *wpa_s)
{
if (!wpa_s->wmm_ac_assoc_info)
return;
wmm_ac_deinit(wpa_s);
wpa_printf(MSG_DEBUG, "WMM AC: WMM AC is disabled");
}

51
wpa_supplicant/wmm_ac.h Normal file
View file

@ -0,0 +1,51 @@
/*
* Wi-Fi Multimedia Admission Control (WMM-AC)
* Copyright(c) 2014, Intel Mobile Communication GmbH.
* Copyright(c) 2014, Intel Corporation. All rights reserved.
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef WMM_AC_H
#define WMM_AC_H
#include "common/ieee802_11_defs.h"
#include "drivers/driver.h"
struct wpa_supplicant;
/**
* struct wmm_ac_assoc_data - WMM Admission Control Association Data
*
* This struct will store any relevant WMM association data needed by WMM AC.
* In case there is a valid WMM association, an instance of this struct will be
* created. In case there is no instance of this struct, the station is not
* associated to a valid WMM BSS and hence, WMM AC will not be used.
*/
struct wmm_ac_assoc_data {
struct {
/*
* acm - Admission Control Mandatory
* In case an access category is ACM, the traffic will have
* to be admitted by WMM-AC's admission mechanism before use.
*/
unsigned int acm:1;
/*
* uapsd_queues - Unscheduled Automatic Power Save Delivery
* queues.
* Indicates whether ACs are configured for U-APSD (or legacy
* PS). Storing this value is necessary in order to set the
* Power Save Bit (PSB) in ADDTS request Action frames (if not
* given).
*/
unsigned int uapsd:1;
} ac_params[WMM_AC_NUM];
};
void wmm_ac_notify_assoc(struct wpa_supplicant *wpa_s, const u8 *ies,
size_t ies_len, const struct wmm_params *wmm_params);
void wmm_ac_notify_disassoc(struct wpa_supplicant *wpa_s);
#endif /* WMM_AC_H */

View file

@ -15,6 +15,7 @@
#include "common/wpa_ctrl.h" #include "common/wpa_ctrl.h"
#include "wps/wps_defs.h" #include "wps/wps_defs.h"
#include "config_ssid.h" #include "config_ssid.h"
#include "wmm_ac.h"
extern const char *wpa_supplicant_version; extern const char *wpa_supplicant_version;
extern const char *wpa_supplicant_license; extern const char *wpa_supplicant_license;
@ -888,6 +889,8 @@ struct wpa_supplicant {
struct l2_packet_data *l2_test; struct l2_packet_data *l2_test;
unsigned int extra_roc_dur; unsigned int extra_roc_dur;
#endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_TESTING_OPTIONS */
struct wmm_ac_assoc_data *wmm_ac_assoc_info;
}; };