aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMoshe Benji <Moshe.Benji@intel.com>2014-10-22 12:03:54 (GMT)
committerJouni Malinen <j@w1.fi>2014-11-16 18:47:34 (GMT)
commita0413b17340a18ed905edc804ee2aab09b2c3186 (patch)
tree8c597b9a58bb67a23abf2d671c8646b11bf9ef7d
parent7e0e10693a5e38d527b14af06cd76c863aeeff58 (diff)
downloadhostap-a0413b17340a18ed905edc804ee2aab09b2c3186.zip
hostap-a0413b17340a18ed905edc804ee2aab09b2c3186.tar.gz
hostap-a0413b17340a18ed905edc804ee2aab09b2c3186.tar.bz2
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>
-rw-r--r--src/common/ieee802_11_defs.h7
-rw-r--r--wpa_supplicant/Android.mk1
-rw-r--r--wpa_supplicant/Makefile1
-rw-r--r--wpa_supplicant/events.c9
-rw-r--r--wpa_supplicant/wmm_ac.c128
-rw-r--r--wpa_supplicant/wmm_ac.h51
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h3
7 files changed, 198 insertions, 2 deletions
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index 8bcd109..14a0ddc 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -884,6 +884,8 @@ struct wmm_information_element {
} STRUCT_PACKED;
+#define WMM_QOSINFO_AP_UAPSD 0x80
+
#define WMM_QOSINFO_STA_AC_MASK 0x0f
#define WMM_QOSINFO_STA_SP_MASK 0x03
#define WMM_QOSINFO_STA_SP_SHIFT 5
@@ -951,11 +953,12 @@ struct wmm_tspec_element {
/* Access Categories / ACI to AC coding */
-enum {
+enum wmm_ac {
WMM_AC_BE = 0 /* Best Effort */,
WMM_AC_BK = 1 /* Background */,
WMM_AC_VI = 2 /* Video */,
- WMM_AC_VO = 3 /* Voice */
+ WMM_AC_VO = 3 /* Voice */,
+ WMM_AC_NUM = 4
};
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 5e6a88f..5ab2996 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -83,6 +83,7 @@ OBJS += eap_register.c
OBJS += src/utils/common.c
OBJS += src/utils/wpa_debug.c
OBJS += src/utils/wpabuf.c
+OBJS += wmm_ac.c
OBJS_p = wpa_passphrase.c
OBJS_p += src/utils/common.c
OBJS_p += src/utils/wpa_debug.c
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index 16c2830..470a85d 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -80,6 +80,7 @@ OBJS_p += ../src/utils/wpabuf.o
OBJS_c = wpa_cli.o ../src/common/wpa_ctrl.o
OBJS_c += ../src/utils/wpa_debug.o
OBJS_c += ../src/utils/common.o
+OBJS += wmm_ac.o
ifndef CONFIG_OS
ifdef CONFIG_NATIVE_WINDOWS
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index c1684bf..e078c70 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -44,6 +44,7 @@
#include "interworking.h"
#include "mesh.h"
#include "mesh_mpm.h"
+#include "wmm_ac.h"
#ifndef CONFIG_NO_SCAN_PROCESSING
@@ -2037,6 +2038,12 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
#endif /* CONFIG_IBSS_RSN */
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;
}
+ wmm_ac_notify_disassoc(wpa_s);
+
if (could_be_psk_mismatch(wpa_s, reason_code, locally_generated)) {
wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - "
"pre-shared key may be incorrect");
diff --git a/wpa_supplicant/wmm_ac.c b/wpa_supplicant/wmm_ac.c
new file mode 100644
index 0000000..13bf7a3
--- /dev/null
+++ b/wpa_supplicant/wmm_ac.c
@@ -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");
+}
diff --git a/wpa_supplicant/wmm_ac.h b/wpa_supplicant/wmm_ac.h
new file mode 100644
index 0000000..dd37617
--- /dev/null
+++ b/wpa_supplicant/wmm_ac.h
@@ -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 */
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 73e2628..334bf71 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -15,6 +15,7 @@
#include "common/wpa_ctrl.h"
#include "wps/wps_defs.h"
#include "config_ssid.h"
+#include "wmm_ac.h"
extern const char *wpa_supplicant_version;
extern const char *wpa_supplicant_license;
@@ -888,6 +889,8 @@ struct wpa_supplicant {
struct l2_packet_data *l2_test;
unsigned int extra_roc_dur;
#endif /* CONFIG_TESTING_OPTIONS */
+
+ struct wmm_ac_assoc_data *wmm_ac_assoc_info;
};