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 enter;
|
||||||
int intval = 0;
|
int intval = 0;
|
||||||
char *pos;
|
char *pos;
|
||||||
|
int ret;
|
||||||
|
struct wpabuf *tfs_req = NULL;
|
||||||
|
|
||||||
if (os_strncmp(cmd, "enter", 5) == 0)
|
if (os_strncmp(cmd, "enter", 5) == 0)
|
||||||
enter = 1;
|
enter = 1;
|
||||||
|
@ -4691,7 +4693,33 @@ static int wpas_ctrl_iface_wnm_sleep(struct wpa_supplicant *wpa_s, char *cmd)
|
||||||
if (pos)
|
if (pos)
|
||||||
intval = atoi(pos + 10);
|
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 */
|
#endif /* CONFIG_WNM */
|
||||||
|
|
|
@ -2150,7 +2150,7 @@ static void wpa_supplicant_event_wnm(struct wpa_supplicant *wpa_s,
|
||||||
"(action=%d, intval=%d)",
|
"(action=%d, intval=%d)",
|
||||||
data->wnm.sleep_action, data->wnm.sleep_intval);
|
data->wnm.sleep_action, data->wnm.sleep_intval);
|
||||||
ieee802_11_send_wnmsleep_req(wpa_s, data->wnm.sleep_action,
|
ieee802_11_send_wnmsleep_req(wpa_s, data->wnm.sleep_action,
|
||||||
data->wnm.sleep_intval);
|
data->wnm.sleep_intval, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ static int ieee80211_11_set_tfs_ie(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
/* MLME-SLEEPMODE.request */
|
/* MLME-SLEEPMODE.request */
|
||||||
int ieee802_11_send_wnmsleep_req(struct wpa_supplicant *wpa_s,
|
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;
|
struct ieee80211_mgmt *mgmt;
|
||||||
int res;
|
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 :
|
enum wnm_oper tfs_oper = action == 0 ? WNM_SLEEP_TFS_REQ_IE_ADD :
|
||||||
WNM_SLEEP_TFS_REQ_IE_NONE;
|
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 */
|
/* WNM-Sleep Mode IE */
|
||||||
wnmsleep_ie_len = sizeof(struct wnm_sleep_element);
|
wnmsleep_ie_len = sizeof(struct wnm_sleep_element);
|
||||||
wnmsleep_ie = os_zalloc(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->action_type = action;
|
||||||
wnmsleep_ie->status = WNM_STATUS_SLEEP_ACCEPT;
|
wnmsleep_ie->status = WNM_STATUS_SLEEP_ACCEPT;
|
||||||
wnmsleep_ie->intval = host_to_le16(intval);
|
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) */
|
/* TFS IE(s) */
|
||||||
wnmtfs_ie = os_zalloc(MAX_TFS_IE_LEN);
|
if (tfs_req) {
|
||||||
if (wnmtfs_ie == NULL) {
|
wnmtfs_ie_len = wpabuf_len(tfs_req);
|
||||||
os_free(wnmsleep_ie);
|
wnmtfs_ie = os_malloc(wnmtfs_ie_len);
|
||||||
return -1;
|
if (wnmtfs_ie == NULL) {
|
||||||
}
|
os_free(wnmsleep_ie);
|
||||||
if (ieee80211_11_get_tfs_ie(wpa_s, wnmtfs_ie, &wnmtfs_ie_len,
|
return -1;
|
||||||
tfs_oper)) {
|
}
|
||||||
wnmtfs_ie_len = 0;
|
os_memcpy(wnmtfs_ie, wpabuf_head(tfs_req), wnmtfs_ie_len);
|
||||||
os_free(wnmtfs_ie);
|
} else {
|
||||||
wnmtfs_ie = NULL;
|
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);
|
mgmt = os_zalloc(sizeof(*mgmt) + wnmsleep_ie_len + wnmtfs_ie_len);
|
||||||
if (mgmt == NULL) {
|
if (mgmt == NULL) {
|
||||||
|
|
|
@ -13,7 +13,7 @@ struct rx_action;
|
||||||
struct wpa_supplicant;
|
struct wpa_supplicant;
|
||||||
|
|
||||||
int ieee802_11_send_wnmsleep_req(struct wpa_supplicant *wpa_s,
|
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,
|
void ieee802_11_rx_wnm_action(struct wpa_supplicant *wpa_s,
|
||||||
struct rx_action *action);
|
struct rx_action *action);
|
||||||
|
|
Loading…
Reference in a new issue