aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant/wmm_ac.c
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2014-12-29 02:15:01 (GMT)
committerJouni Malinen <j@w1.fi>2015-01-04 16:41:00 (GMT)
commit8c42b36902ad3f248f5bafb91ffcdf16f7ef76bf (patch)
tree094083ffd5ab34fa9fe6f591f15860335bc91ad9 /wpa_supplicant/wmm_ac.c
parent677e7a95826fe9f6d93832511b7f082b899a8f3c (diff)
downloadhostap-8c42b36902ad3f248f5bafb91ffcdf16f7ef76bf.zip
hostap-8c42b36902ad3f248f5bafb91ffcdf16f7ef76bf.tar.gz
hostap-8c42b36902ad3f248f5bafb91ffcdf16f7ef76bf.tar.bz2
WMM AC: Reconfigure tspecs on reassociation to the same BSS
The specification requires the tspecs to be kept upon reassociation to the same BSS. Save the last tspecs before such reassociation, and reconfigure on the association notification. Note that the current flow is not transparent to the user (it is notified about deauth/reassoc and tspec removal/addition). Signed-off-by: Eliad Peller <eliadx.peller@intel.com>
Diffstat (limited to 'wpa_supplicant/wmm_ac.c')
-rw-r--r--wpa_supplicant/wmm_ac.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/wpa_supplicant/wmm_ac.c b/wpa_supplicant/wmm_ac.c
index 47d7436..5625d36 100644
--- a/wpa_supplicant/wmm_ac.c
+++ b/wpa_supplicant/wmm_ac.c
@@ -910,3 +910,86 @@ int wpas_wmm_ac_status(struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
return pos;
}
+
+
+static u8 wmm_ac_get_tspecs_count(struct wpa_supplicant *wpa_s)
+{
+ int ac, dir, tspecs_count = 0;
+
+ for (ac = 0; ac < WMM_AC_NUM; ac++) {
+ for (dir = 0; dir < TS_DIR_IDX_COUNT; dir++) {
+ if (wpa_s->tspecs[ac][dir])
+ tspecs_count++;
+ }
+ }
+
+ return tspecs_count;
+}
+
+
+void wmm_ac_save_tspecs(struct wpa_supplicant *wpa_s)
+{
+ int ac, dir, tspecs_count;
+
+ wpa_printf(MSG_DEBUG, "WMM AC: Save last configured tspecs");
+
+ if (!wpa_s->wmm_ac_assoc_info)
+ return;
+
+ tspecs_count = wmm_ac_get_tspecs_count(wpa_s);
+ if (!tspecs_count) {
+ wpa_printf(MSG_DEBUG, "WMM AC: No configured TSPECs");
+ return;
+ }
+
+ wpa_printf(MSG_DEBUG, "WMM AC: Saving tspecs");
+
+ wmm_ac_clear_saved_tspecs(wpa_s);
+ wpa_s->last_tspecs = os_calloc(tspecs_count,
+ sizeof(*wpa_s->last_tspecs));
+ if (!wpa_s->last_tspecs) {
+ wpa_printf(MSG_ERROR, "WMM AC: Failed to save tspecs!");
+ return;
+ }
+
+ for (ac = 0; ac < WMM_AC_NUM; ac++) {
+ for (dir = 0; dir < TS_DIR_IDX_COUNT; dir++) {
+ if (!wpa_s->tspecs[ac][dir])
+ continue;
+
+ wpa_s->last_tspecs[wpa_s->last_tspecs_count++] =
+ *wpa_s->tspecs[ac][dir];
+ }
+ }
+
+ wpa_printf(MSG_DEBUG, "WMM AC: Successfully saved %d TSPECs",
+ wpa_s->last_tspecs_count);
+}
+
+
+void wmm_ac_clear_saved_tspecs(struct wpa_supplicant *wpa_s)
+{
+ if (wpa_s->last_tspecs) {
+ wpa_printf(MSG_DEBUG, "WMM AC: Clear saved tspecs");
+ os_free(wpa_s->last_tspecs);
+ wpa_s->last_tspecs = NULL;
+ wpa_s->last_tspecs_count = 0;
+ }
+}
+
+
+int wmm_ac_restore_tspecs(struct wpa_supplicant *wpa_s)
+{
+ unsigned int i;
+
+ if (!wpa_s->wmm_ac_assoc_info || !wpa_s->last_tspecs_count)
+ return 0;
+
+ wpa_printf(MSG_DEBUG, "WMM AC: Restore %u saved tspecs",
+ wpa_s->last_tspecs_count);
+
+ for (i = 0; i < wpa_s->last_tspecs_count; i++)
+ wmm_ac_add_ts(wpa_s, wpa_s->bssid, &wpa_s->last_tspecs[i]);
+
+ return 0;
+}