wnm_sta.c revision 61d9df3e62aaa0e87ad05452fcb95142159a17b6
161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/* 261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * wpa_supplicant - WNM 361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * Copyright (c) 2011-2012, Qualcomm Atheros, Inc. 461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * 561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * See README for more details. 761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "utils/includes.h" 1061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "utils/common.h" 1261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "common/ieee802_11_defs.h" 1361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "rsn_supp/wpa.h" 1461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "../wpa_supplicant/wpa_supplicant_i.h" 1561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "../wpa_supplicant/driver_i.h" 1661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#define MAX_TFS_IE_LEN 1024 1861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_IEEE80211V 2061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/* get the TFS IE from driver */ 2261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int ieee80211_11_get_tfs_ie(struct wpa_supplicant *wpa_s, u8 *buf, 2361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u16 *buf_len, enum wnm_oper oper) 2461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 2561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: TFS get operation %d", __func__, oper); 2661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return wpa_drv_wnm_oper(wpa_s, oper, wpa_s->bssid, buf, buf_len); 2861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 2961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 3061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 3161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/* set the TFS IE to driver */ 3261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int ieee80211_11_set_tfs_ie(struct wpa_supplicant *wpa_s, 3361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *addr, u8 *buf, u16 *buf_len, 3461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt enum wnm_oper oper) 3561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 3661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: TFS set operation %d", __func__, oper); 3761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 3861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return wpa_drv_wnm_oper(wpa_s, oper, addr, buf, buf_len); 3961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 4061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 4161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 4261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt/* MLME-SLEEPMODE.request */ 4361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint ieee802_11_send_wnmsleep_req(struct wpa_supplicant *wpa_s, 4461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 action, u8 intval) 4561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 4661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct ieee80211_mgmt *mgmt; 4761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int res; 4861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t len; 4961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wnm_sleep_element *wnmsleep_ie; 5061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *wnmtfs_ie; 5161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 wnmsleep_ie_len; 5261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u16 wnmtfs_ie_len; /* possibly multiple IE(s) */ 5361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt enum wnm_oper tfs_oper = action == 0 ? WNM_SLEEP_TFS_REQ_IE_ADD : 5461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt WNM_SLEEP_TFS_REQ_IE_NONE; 5561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 5661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* WNM-Sleep Mode IE */ 5761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wnmsleep_ie_len = sizeof(struct wnm_sleep_element); 5861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wnmsleep_ie = os_zalloc(sizeof(struct wnm_sleep_element)); 5961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wnmsleep_ie == NULL) 6061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 6161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wnmsleep_ie->eid = WLAN_EID_WNMSLEEP; 6261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wnmsleep_ie->len = wnmsleep_ie_len - 2; 6361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wnmsleep_ie->action_type = action; 6461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wnmsleep_ie->status = WNM_STATUS_SLEEP_ACCEPT; 6561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wnmsleep_ie->intval = intval; 6661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 6761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* TFS IE(s) */ 6861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wnmtfs_ie = os_zalloc(MAX_TFS_IE_LEN); 6961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wnmtfs_ie == NULL) { 7061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(wnmsleep_ie); 7161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 7261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 7361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ieee80211_11_get_tfs_ie(wpa_s, wnmtfs_ie, &wnmtfs_ie_len, 7461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tfs_oper)) { 7561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wnmtfs_ie_len = 0; 7661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(wnmtfs_ie); 7761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wnmtfs_ie = NULL; 7861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 7961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 8061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt mgmt = os_zalloc(sizeof(*mgmt) + wnmsleep_ie_len + wnmtfs_ie_len); 8161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (mgmt == NULL) { 8261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "MLME: Failed to allocate buffer for " 8361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "WNM-Sleep Request action frame"); 8461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 8561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 8661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 8761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(mgmt->da, wpa_s->bssid, ETH_ALEN); 8861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(mgmt->sa, wpa_s->own_addr, ETH_ALEN); 8961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN); 9061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 9161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt WLAN_FC_STYPE_ACTION); 9261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt mgmt->u.action.category = WLAN_ACTION_WNM; 9361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt mgmt->u.action.u.wnm_sleep_req.action = WNM_SLEEP_MODE_REQ; 9461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(mgmt->u.action.u.wnm_sleep_req.variable, wnmsleep_ie, 9561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wnmsleep_ie_len); 9661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* copy TFS IE here */ 9761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wnmtfs_ie_len > 0) { 9861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memcpy(mgmt->u.action.u.wnm_sleep_req.variable + 9961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wnmsleep_ie_len, wnmtfs_ie, wnmtfs_ie_len); 10061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 10161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 10261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt len = 1 + sizeof(mgmt->u.action.u.wnm_sleep_req) + wnmsleep_ie_len + 10361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wnmtfs_ie_len; 10461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 10561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt res = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid, 10661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->own_addr, wpa_s->bssid, 10761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt &mgmt->u.action.category, len, 0); 10861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (res < 0) 10961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to send WNM-Sleep Request " 11061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "(action=%d, intval=%d)", action, intval); 11161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 11261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(wnmsleep_ie); 11361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(wnmtfs_ie); 11461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(mgmt); 11561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 11661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return res; 11761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 11861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 11961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 12061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic void ieee802_11_rx_wnmsleep_resp(struct wpa_supplicant *wpa_s, 12161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const u8 *frm, int len) 12261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 12361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* 12461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * Action [1] | Diaglog Token [1] | Key Data Len [2] | Key Data | 12561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * WNM-Sleep Mode IE | TFS Response IE 12661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 12761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *pos = (u8 *) frm; /* point to action field */ 12861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u16 key_len_total = le_to_host16(*((u16 *)(frm+2))); 12961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 gtk_len; 13061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_IEEE80211W 13161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 igtk_len; 13261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 13361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct wnm_sleep_element *wnmsleep_ie = NULL; 13461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* multiple TFS Resp IE (assuming consecutive) */ 13561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *tfsresp_ie_start = NULL; 13661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *tfsresp_ie_end = NULL; 13761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u16 tfsresp_ie_len = 0; 13861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 13961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "action=%d token = %d key_len_total = %d", 14061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt frm[0], frm[1], key_len_total); 14161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += 4 + key_len_total; 14261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt while (pos - frm < len) { 14361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 ie_len = *(pos + 1); 14461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (*pos == WLAN_EID_WNMSLEEP) 14561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wnmsleep_ie = (struct wnm_sleep_element *) pos; 14661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt else if (*pos == WLAN_EID_TFS_RESP) { 14761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!tfsresp_ie_start) 14861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tfsresp_ie_start = pos; 14961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tfsresp_ie_end = pos; 15061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else 15161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "EID %d not recognized", *pos); 15261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += ie_len + 2; 15361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 15461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 15561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!wnmsleep_ie) { 15661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "No WNM-Sleep IE found"); 15761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 15861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 15961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 16061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wnmsleep_ie->status == WNM_STATUS_SLEEP_ACCEPT) { 16161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "Successfully recv WNM-Sleep Response " 16261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "frame (action=%d, intval=%d)", 16361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wnmsleep_ie->action_type, wnmsleep_ie->intval); 16461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wnmsleep_ie->action_type == 0) { 16561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_drv_wnm_oper(wpa_s, WNM_SLEEP_ENTER_CONFIRM, 16661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->bssid, NULL, NULL); 16761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* remove GTK/IGTK ?? */ 16861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 16961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* set the TFS Resp IE(s) */ 17061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (tfsresp_ie_start && tfsresp_ie_end && 17161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tfsresp_ie_end - tfsresp_ie_start >= 0) { 17261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tfsresp_ie_len = (tfsresp_ie_end + 17361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tfsresp_ie_end[1] + 2) - 17461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tfsresp_ie_start; 17561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "TFS Resp IE(s) found"); 17661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* 17761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * pass the TFS Resp IE(s) to driver for 17861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * processing 17961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 18061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ieee80211_11_set_tfs_ie( 18161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s, wpa_s->bssid, 18261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt tfsresp_ie_start, 18361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt &tfsresp_ie_len, 18461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt WNM_SLEEP_TFS_RESP_IE_SET)) 18561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "Fail to set " 18661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "TFS Resp IE"); 18761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 18861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (wnmsleep_ie->action_type == 1) { 18961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_drv_wnm_oper(wpa_s, WNM_SLEEP_EXIT_CONFIRM, 19061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->bssid, NULL, NULL); 19161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Install GTK/IGTK */ 19261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt do { 19361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* point to key data field */ 19461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *ptr = (u8 *) frm + 1 + 1 + 2; 19561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt while (ptr < (u8 *) frm + 4 + key_len_total) { 19661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (*ptr == WNM_SLEEP_SUBELEM_GTK) { 19761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt gtk_len = *(ptr + 4); 19861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_wnmsleep_install_key( 19961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->wpa, 20061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt WNM_SLEEP_SUBELEM_GTK, 20161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ptr); 20261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ptr += 13 + gtk_len; 20361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_IEEE80211W 20461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (*ptr == 20561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt WNM_SLEEP_SUBELEM_IGTK) { 20661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt igtk_len = WPA_IGTK_LEN; 20761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_wnmsleep_install_key( 20861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->wpa, 20961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt WNM_SLEEP_SUBELEM_IGTK, 21061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ptr); 21161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ptr += 10 + WPA_IGTK_LEN; 21261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 21361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else 21461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; /* skip the loop */ 21561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 21661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } while(0); 21761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 21861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else { 21961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "Reject recv WNM-Sleep Response frame " 22061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "(action=%d, intval=%d)", 22161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wnmsleep_ie->action_type, wnmsleep_ie->intval); 22261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (wnmsleep_ie->action_type == 0) 22361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_drv_wnm_oper(wpa_s, WNM_SLEEP_ENTER_FAIL, 22461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->bssid, NULL, NULL); 22561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt else if (wnmsleep_ie->action_type == 1) 22661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_drv_wnm_oper(wpa_s, WNM_SLEEP_EXIT_FAIL, 22761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->bssid, NULL, NULL); 22861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 22961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 23061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 23161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 23261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid ieee802_11_rx_wnm_action(struct wpa_supplicant *wpa_s, 23361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct rx_action *action) 23461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 23561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 *pos = (u8 *) action->data; /* point to action field */ 23661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 act = *pos++; 23761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* u8 dialog_token = *pos++; */ 23861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 23961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt switch (act) { 24061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case WNM_SLEEP_MODE_RESP: 24161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ieee802_11_rx_wnmsleep_resp(wpa_s, action->data, action->len); 24261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 24361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt default: 24461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 24561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 24661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 24761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 24861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_IEEE80211V */ 249