[PATCH 5/7] WMM AC: reconfigure tspecs on reassociation

Ilan Peer ilan.peer at intel.com
Sun Dec 28 21:15:01 EST 2014


From: Eliad Peller <eliad at wizery.com>

The spec requires the tspecs to be kept upon reassociation
(to the same bss) and the wmm ac certification verifies it.

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 at intel.com>
---
 wpa_supplicant/events.c           |  3 ++
 wpa_supplicant/wmm_ac.c           | 74 +++++++++++++++++++++++++++++++++++++++
 wpa_supplicant/wmm_ac.h           |  3 ++
 wpa_supplicant/wpa_supplicant.c   |  8 +++++
 wpa_supplicant/wpa_supplicant_i.h |  3 ++
 5 files changed, 91 insertions(+)

diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 8d8fcec..d9689a9 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -2048,6 +2048,9 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
 		wmm_ac_notify_assoc(wpa_s, data->assoc_info.resp_ies,
 				    data->assoc_info.resp_ies_len,
 				    &data->assoc_info.wmm_params);
+
+		if (wpa_s->reassoc_same_bss)
+			wmm_ac_restore_tspecs(wpa_s);
 	}
 }
 
diff --git a/wpa_supplicant/wmm_ac.c b/wpa_supplicant/wmm_ac.c
index 47d7436..f2e9cde 100644
--- a/wpa_supplicant/wmm_ac.c
+++ b/wpa_supplicant/wmm_ac.c
@@ -910,3 +910,77 @@ 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(sizeof(*wpa_s->last_tspecs),
+				       tspecs_count);
+	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)
+{
+	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)
+{
+	int i;
+
+	if (!wpa_s->wmm_ac_assoc_info || !wpa_s->last_tspecs_count)
+		return 0;
+
+	wpa_printf(MSG_DEBUG, "WMM AC: Restore %d 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;
+}
diff --git a/wpa_supplicant/wmm_ac.h b/wpa_supplicant/wmm_ac.h
index 2b02025..5171b16 100644
--- a/wpa_supplicant/wmm_ac.h
+++ b/wpa_supplicant/wmm_ac.h
@@ -169,5 +169,8 @@ int wpas_wmm_ac_delts(struct wpa_supplicant *wpa_s, u8 tsid);
 void wmm_ac_rx_action(struct wpa_supplicant *wpa_s, const u8 *da,
 			const u8 *sa, const u8 *data, size_t len);
 int wpas_wmm_ac_status(struct wpa_supplicant *wpa_s, char *buf, size_t buflen);
+void wmm_ac_save_tspecs(struct wpa_supplicant *wpa_s);
+void wmm_ac_clear_saved_tspecs(struct wpa_supplicant *wpa_s);
+int wmm_ac_restore_tspecs(struct wpa_supplicant *wpa_s);
 
 #endif /* WMM_AC_H */
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index e8d7edb..c5b86c7 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -435,6 +435,7 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
 	wpa_tdls_deinit(wpa_s->wpa);
 #endif /* CONFIG_TDLS */
 
+	wmm_ac_clear_saved_tspecs(wpa_s);
 	pmksa_candidate_free(wpa_s->wpa);
 	wpa_sm_deinit(wpa_s->wpa);
 	wpa_s->wpa = NULL;
@@ -1489,8 +1490,15 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
 	else
 		rand_style = ssid->mac_addr;
 
+	wmm_ac_clear_saved_tspecs(wpa_s);
+	wpa_s->reassoc_same_bss = 0;
+
 	if (wpa_s->last_ssid == ssid) {
 		wpa_dbg(wpa_s, MSG_DEBUG, "Re-association to the same ESS");
+		if (wpa_s->current_bss && wpa_s->current_bss == bss) {
+			wmm_ac_save_tspecs(wpa_s);
+			wpa_s->reassoc_same_bss = 1;
+		}
 	} else if (rand_style > 0) {
 		if (wpas_update_random_addr(wpa_s, rand_style) < 0)
 			return;
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index b0f3866..6f12660 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -444,6 +444,7 @@ struct wpa_supplicant {
 	u8 pending_bssid[ETH_ALEN]; /* If wpa_state == WPA_ASSOCIATING, this
 				     * field contains the target BSSID. */
 	int reassociate; /* reassociation requested */
+	int reassoc_same_bss; /* reassociating to the same bss */
 	int disconnected; /* all connections disabled; i.e., do no reassociate
 			   * before this has been cleared */
 	struct wpa_ssid *current_ssid;
@@ -926,6 +927,8 @@ struct wpa_supplicant {
 	struct wmm_tspec_element *tspecs[WMM_AC_NUM][TS_DIR_IDX_COUNT];
 	struct wmm_ac_addts_request *addts_request;
 	u8 wmm_ac_last_dialog_token;
+	struct wmm_tspec_element *last_tspecs;
+	u8 last_tspecs_count;
 
 	struct rrm_data rrm;
 };
-- 
1.8.3.2



More information about the HostAP mailing list