DSCP: Parse WFA Capabilities element in (Re)Association Response frame
Add support to parse WFA Capabilities element from the (Re)Association Response frame. Also register a timeout for the station to wait before sending a new DSCP query if requested by AP. Signed-off-by: Veerendranath Jakkam <vjakkam@codeaurora.org>
This commit is contained in:
parent
a4aae9f9b8
commit
c903257fb1
4 changed files with 85 additions and 0 deletions
|
@ -1136,6 +1136,17 @@ is as shown below:
|
||||||
- External applications shall clear active DSCP policies upon receiving
|
- External applications shall clear active DSCP policies upon receiving
|
||||||
"CTRL-EVENT-DISCONNECTED" or "CTRL-EVENT-DSCP-POLICY clear_all" events.
|
"CTRL-EVENT-DISCONNECTED" or "CTRL-EVENT-DSCP-POLICY clear_all" events.
|
||||||
|
|
||||||
|
- Control interface event message format to indicate wpa_supplicant started
|
||||||
|
a timer to wait until the unsolicited DSCP request from the AP.
|
||||||
|
|
||||||
|
<3>CTRL-EVENT-DSCP-POLICY request_wait start
|
||||||
|
|
||||||
|
- Control interface event message format to indicate timeout to receive the
|
||||||
|
unsolicited DSCP request. This event is expected only when an unsolicited
|
||||||
|
DSCP request is not received from the AP before timeout.
|
||||||
|
|
||||||
|
<3>CTRL-EVENT-DSCP-POLICY request_wait end
|
||||||
|
|
||||||
DSCP Response:
|
DSCP Response:
|
||||||
A QoS Management STA that enables DSCP Policy capability shall respond
|
A QoS Management STA that enables DSCP Policy capability shall respond
|
||||||
with DSCP response on receipt of a successful DSCP request from its
|
with DSCP response on receipt of a successful DSCP request from its
|
||||||
|
|
|
@ -2977,6 +2977,9 @@ no_pfs:
|
||||||
|
|
||||||
wpa_s->assoc_freq = data->assoc_info.freq;
|
wpa_s->assoc_freq = data->assoc_info.freq;
|
||||||
|
|
||||||
|
wpas_handle_assoc_resp_qos_mgmt(wpa_s, data->assoc_info.resp_ies,
|
||||||
|
data->assoc_info.resp_ies_len);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
|
|
||||||
#define SCS_RESP_TIMEOUT 1
|
#define SCS_RESP_TIMEOUT 1
|
||||||
|
#define DSCP_REQ_TIMEOUT 5
|
||||||
|
|
||||||
|
|
||||||
void wpas_populate_mscs_descriptor_ie(struct robust_av_data *robust_av,
|
void wpas_populate_mscs_descriptor_ie(struct robust_av_data *robust_av,
|
||||||
|
@ -550,6 +551,48 @@ void wpas_handle_assoc_resp_mscs(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void wpas_wait_for_dscp_req_timer(void *eloop_ctx, void *timeout_ctx)
|
||||||
|
{
|
||||||
|
struct wpa_supplicant *wpa_s = eloop_ctx;
|
||||||
|
|
||||||
|
/* Once timeout is over, reset wait flag and allow sending DSCP query */
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"QM: Wait time over for sending DSCP request - allow DSCP query");
|
||||||
|
wpa_s->wait_for_dscp_req = 0;
|
||||||
|
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_wait end");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void wpas_handle_assoc_resp_qos_mgmt(struct wpa_supplicant *wpa_s,
|
||||||
|
const u8 *ies, size_t ies_len)
|
||||||
|
{
|
||||||
|
const u8 *wfa_capa;
|
||||||
|
|
||||||
|
wpa_s->connection_dscp = 0;
|
||||||
|
if (wpa_s->wait_for_dscp_req)
|
||||||
|
eloop_cancel_timeout(wpas_wait_for_dscp_req_timer, wpa_s, NULL);
|
||||||
|
|
||||||
|
if (!ies || ies_len == 0 || !wpa_s->enable_dscp_policy_capa)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wfa_capa = get_vendor_ie(ies, ies_len, WFA_CAPA_IE_VENDOR_TYPE);
|
||||||
|
if (!wfa_capa || wfa_capa[1] < 6 || wfa_capa[6] < 1 ||
|
||||||
|
!(wfa_capa[7] & WFA_CAPA_QM_DSCP_POLICY))
|
||||||
|
return; /* AP does not enable QM DSCP Policy */
|
||||||
|
|
||||||
|
wpa_s->connection_dscp = 1;
|
||||||
|
wpa_s->wait_for_dscp_req = !!(wfa_capa[7] &
|
||||||
|
WFA_CAPA_QM_UNSOLIC_DSCP);
|
||||||
|
if (!wpa_s->wait_for_dscp_req)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Register a timeout after which dscp query can be sent to AP. */
|
||||||
|
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "request_wait start");
|
||||||
|
eloop_register_timeout(DSCP_REQ_TIMEOUT, 0,
|
||||||
|
wpas_wait_for_dscp_req_timer, wpa_s, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void wpas_handle_robust_av_scs_recv_action(struct wpa_supplicant *wpa_s,
|
void wpas_handle_robust_av_scs_recv_action(struct wpa_supplicant *wpa_s,
|
||||||
const u8 *src, const u8 *buf,
|
const u8 *src, const u8 *buf,
|
||||||
size_t len)
|
size_t len)
|
||||||
|
@ -1116,6 +1159,11 @@ void wpas_dscp_deinit(struct wpa_supplicant *wpa_s)
|
||||||
wpa_printf(MSG_DEBUG, "QM: Clear all active DSCP policies");
|
wpa_printf(MSG_DEBUG, "QM: Clear all active DSCP policies");
|
||||||
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "clear_all");
|
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DSCP_POLICY "clear_all");
|
||||||
wpa_s->dscp_req_dialog_token = 0;
|
wpa_s->dscp_req_dialog_token = 0;
|
||||||
|
wpa_s->connection_dscp = 0;
|
||||||
|
if (wpa_s->wait_for_dscp_req) {
|
||||||
|
wpa_s->wait_for_dscp_req = 0;
|
||||||
|
eloop_cancel_timeout(wpas_wait_for_dscp_req_timer, wpa_s, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1194,6 +1242,12 @@ void wpas_handle_qos_mgmt_recv_action(struct wpa_supplicant *wpa_s,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!wpa_s->connection_dscp) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"QM: DSCP Policy capability not enabled for the current association - ignore QoS Management Action frames");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (len < 1)
|
if (len < 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1211,6 +1265,12 @@ void wpas_handle_qos_mgmt_recv_action(struct wpa_supplicant *wpa_s,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear wait_for_dscp_req on receiving first DSCP request from AP */
|
||||||
|
if (wpa_s->wait_for_dscp_req) {
|
||||||
|
wpa_s->wait_for_dscp_req = 0;
|
||||||
|
eloop_cancel_timeout(wpas_wait_for_dscp_req_timer, wpa_s, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
wpa_s->dscp_req_dialog_token = buf[1];
|
wpa_s->dscp_req_dialog_token = buf[1];
|
||||||
more = buf[2] & DSCP_POLICY_CTRL_MORE;
|
more = buf[2] & DSCP_POLICY_CTRL_MORE;
|
||||||
reset = buf[2] & DSCP_POLICY_CTRL_RESET;
|
reset = buf[2] & DSCP_POLICY_CTRL_RESET;
|
||||||
|
@ -1289,6 +1349,13 @@ int wpas_send_dscp_response(struct wpa_supplicant *wpa_s,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!wpa_s->connection_dscp) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"QM: Failed to send DSCP response - DSCP capability not enabled for the current association");
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
buf_len = 1 + /* Category */
|
buf_len = 1 + /* Category */
|
||||||
3 + /* OUI */
|
3 + /* OUI */
|
||||||
1 + /* OUI Type */
|
1 + /* OUI Type */
|
||||||
|
|
|
@ -1515,6 +1515,8 @@ struct wpa_supplicant {
|
||||||
bool ongoing_scs_req;
|
bool ongoing_scs_req;
|
||||||
u8 dscp_req_dialog_token;
|
u8 dscp_req_dialog_token;
|
||||||
unsigned int enable_dscp_policy_capa:1;
|
unsigned int enable_dscp_policy_capa:1;
|
||||||
|
unsigned int connection_dscp:1;
|
||||||
|
unsigned int wait_for_dscp_req:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1861,6 +1863,8 @@ void wpas_handle_qos_mgmt_recv_action(struct wpa_supplicant *wpa_s,
|
||||||
void wpas_dscp_deinit(struct wpa_supplicant *wpa_s);
|
void wpas_dscp_deinit(struct wpa_supplicant *wpa_s);
|
||||||
int wpas_send_dscp_response(struct wpa_supplicant *wpa_s,
|
int wpas_send_dscp_response(struct wpa_supplicant *wpa_s,
|
||||||
struct dscp_resp_data *resp_data);
|
struct dscp_resp_data *resp_data);
|
||||||
|
void wpas_handle_assoc_resp_qos_mgmt(struct wpa_supplicant *wpa_s,
|
||||||
|
const u8 *ies, size_t ies_len);
|
||||||
|
|
||||||
int wpas_pasn_auth_start(struct wpa_supplicant *wpa_s,
|
int wpas_pasn_auth_start(struct wpa_supplicant *wpa_s,
|
||||||
const u8 *bssid, int akmp, int cipher,
|
const u8 *bssid, int akmp, int cipher,
|
||||||
|
|
Loading…
Reference in a new issue