aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2012-12-16 10:31:16 (GMT)
committerJouni Malinen <j@w1.fi>2012-12-16 10:31:16 (GMT)
commitcd0ef65784232b26e516edf5a45bd810b59aaf99 (patch)
tree79e76ff5c19891d0163f52209e314982dbf05ac9 /wpa_supplicant
parent61c54976f51a29f0e87b230dbefbcf78b411a18a (diff)
downloadhostap-cd0ef65784232b26e516edf5a45bd810b59aaf99.zip
hostap-cd0ef65784232b26e516edf5a45bd810b59aaf99.tar.gz
hostap-cd0ef65784232b26e516edf5a45bd810b59aaf99.tar.bz2
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>
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/ctrl_iface.c30
-rw-r--r--wpa_supplicant/events.c2
-rw-r--r--wpa_supplicant/wnm_sta.c41
-rw-r--r--wpa_supplicant/wnm_sta.h2
4 files changed, 61 insertions, 14 deletions
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index b12d349..7a27abd 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -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 */
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 35ba8e4..4926746 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -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;
}
}
diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c
index e81ef31..bcd1d4a 100644
--- a/wpa_supplicant/wnm_sta.c
+++ b/wpa_supplicant/wnm_sta.c
@@ -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) {
diff --git a/wpa_supplicant/wnm_sta.h b/wpa_supplicant/wnm_sta.h
index 96fe0d9..3f9d88b 100644
--- a/wpa_supplicant/wnm_sta.h
+++ b/wpa_supplicant/wnm_sta.h
@@ -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);