WNM: Add option for passing TFS request from external programs
The optional tfs_req=<hex dump> parameter can be added for the wnm_sleep command to specify the TFS request element to use in the WNM-Sleep Mode Request frame. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
61c54976f5
commit
cd0ef65784
4 changed files with 61 additions and 14 deletions
|
@ -4679,6 +4679,8 @@ static int wpas_ctrl_iface_wnm_sleep(struct wpa_supplicant *wpa_s, char *cmd)
|
|||
int enter;
|
||||
int intval = 0;
|
||||
char *pos;
|
||||
int ret;
|
||||
struct wpabuf *tfs_req = NULL;
|
||||
|
||||
if (os_strncmp(cmd, "enter", 5) == 0)
|
||||
enter = 1;
|
||||
|
@ -4691,7 +4693,33 @@ static int wpas_ctrl_iface_wnm_sleep(struct wpa_supplicant *wpa_s, char *cmd)
|
|||
if (pos)
|
||||
intval = atoi(pos + 10);
|
||||
|
||||
return ieee802_11_send_wnmsleep_req(wpa_s, enter ? 0 : 1, intval);
|
||||
pos = os_strstr(cmd, " tfs_req=");
|
||||
if (pos) {
|
||||
char *end;
|
||||
size_t len;
|
||||
pos += 9;
|
||||
end = os_strchr(pos, ' ');
|
||||
if (end)
|
||||
len = end - pos;
|
||||
else
|
||||
len = os_strlen(pos);
|
||||
if (len & 1)
|
||||
return -1;
|
||||
len /= 2;
|
||||
tfs_req = wpabuf_alloc(len);
|
||||
if (tfs_req == NULL)
|
||||
return -1;
|
||||
if (hexstr2bin(pos, wpabuf_put(tfs_req, len), len) < 0) {
|
||||
wpabuf_free(tfs_req);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ret = ieee802_11_send_wnmsleep_req(wpa_s, enter ? 0 : 1, intval,
|
||||
tfs_req);
|
||||
wpabuf_free(tfs_req);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_WNM */
|
||||
|
|
|
@ -2150,7 +2150,7 @@ static void wpa_supplicant_event_wnm(struct wpa_supplicant *wpa_s,
|
|||
"(action=%d, intval=%d)",
|
||||
data->wnm.sleep_action, data->wnm.sleep_intval);
|
||||
ieee802_11_send_wnmsleep_req(wpa_s, data->wnm.sleep_action,
|
||||
data->wnm.sleep_intval);
|
||||
data->wnm.sleep_intval, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ static int ieee80211_11_set_tfs_ie(struct wpa_supplicant *wpa_s,
|
|||
|
||||
/* MLME-SLEEPMODE.request */
|
||||
int ieee802_11_send_wnmsleep_req(struct wpa_supplicant *wpa_s,
|
||||
u8 action, u16 intval)
|
||||
u8 action, u16 intval, struct wpabuf *tfs_req)
|
||||
{
|
||||
struct ieee80211_mgmt *mgmt;
|
||||
int res;
|
||||
|
@ -53,6 +53,11 @@ int ieee802_11_send_wnmsleep_req(struct wpa_supplicant *wpa_s,
|
|||
enum wnm_oper tfs_oper = action == 0 ? WNM_SLEEP_TFS_REQ_IE_ADD :
|
||||
WNM_SLEEP_TFS_REQ_IE_NONE;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "WNM: Request to send WNM-Sleep Mode Request "
|
||||
"action=%s to " MACSTR,
|
||||
action == 0 ? "enter" : "exit",
|
||||
MAC2STR(wpa_s->bssid));
|
||||
|
||||
/* WNM-Sleep Mode IE */
|
||||
wnmsleep_ie_len = sizeof(struct wnm_sleep_element);
|
||||
wnmsleep_ie = os_zalloc(sizeof(struct wnm_sleep_element));
|
||||
|
@ -63,19 +68,33 @@ int ieee802_11_send_wnmsleep_req(struct wpa_supplicant *wpa_s,
|
|||
wnmsleep_ie->action_type = action;
|
||||
wnmsleep_ie->status = WNM_STATUS_SLEEP_ACCEPT;
|
||||
wnmsleep_ie->intval = host_to_le16(intval);
|
||||
wpa_hexdump(MSG_DEBUG, "WNM: WNM-Sleep Mode element",
|
||||
(u8 *) wnmsleep_ie, wnmsleep_ie_len);
|
||||
|
||||
/* TFS IE(s) */
|
||||
wnmtfs_ie = os_zalloc(MAX_TFS_IE_LEN);
|
||||
if (wnmtfs_ie == NULL) {
|
||||
os_free(wnmsleep_ie);
|
||||
return -1;
|
||||
}
|
||||
if (ieee80211_11_get_tfs_ie(wpa_s, wnmtfs_ie, &wnmtfs_ie_len,
|
||||
tfs_oper)) {
|
||||
wnmtfs_ie_len = 0;
|
||||
os_free(wnmtfs_ie);
|
||||
wnmtfs_ie = NULL;
|
||||
if (tfs_req) {
|
||||
wnmtfs_ie_len = wpabuf_len(tfs_req);
|
||||
wnmtfs_ie = os_malloc(wnmtfs_ie_len);
|
||||
if (wnmtfs_ie == NULL) {
|
||||
os_free(wnmsleep_ie);
|
||||
return -1;
|
||||
}
|
||||
os_memcpy(wnmtfs_ie, wpabuf_head(tfs_req), wnmtfs_ie_len);
|
||||
} else {
|
||||
wnmtfs_ie = os_zalloc(MAX_TFS_IE_LEN);
|
||||
if (wnmtfs_ie == NULL) {
|
||||
os_free(wnmsleep_ie);
|
||||
return -1;
|
||||
}
|
||||
if (ieee80211_11_get_tfs_ie(wpa_s, wnmtfs_ie, &wnmtfs_ie_len,
|
||||
tfs_oper)) {
|
||||
wnmtfs_ie_len = 0;
|
||||
os_free(wnmtfs_ie);
|
||||
wnmtfs_ie = NULL;
|
||||
}
|
||||
}
|
||||
wpa_hexdump(MSG_DEBUG, "WNM: TFS Request element",
|
||||
(u8 *) wnmtfs_ie, wnmtfs_ie_len);
|
||||
|
||||
mgmt = os_zalloc(sizeof(*mgmt) + wnmsleep_ie_len + wnmtfs_ie_len);
|
||||
if (mgmt == NULL) {
|
||||
|
|
|
@ -13,7 +13,7 @@ struct rx_action;
|
|||
struct wpa_supplicant;
|
||||
|
||||
int ieee802_11_send_wnmsleep_req(struct wpa_supplicant *wpa_s,
|
||||
u8 action, u16 intval);
|
||||
u8 action, u16 intval, struct wpabuf *tfs_req);
|
||||
|
||||
void ieee802_11_rx_wnm_action(struct wpa_supplicant *wpa_s,
|
||||
struct rx_action *action);
|
||||
|
|
Loading…
Reference in a new issue