blob: 54b991c6b194ed0104d9e5bceccaebad91243ac8 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kanchanapally, Vidyullathaf9426e52013-12-24 17:28:54 +05302 * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
Srinivas Girigowdac03c5a82013-07-01 13:44:54 -07003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20*/
Gopichand Nakkala92f07d82013-01-08 21:16:34 -080021/*
Jeff Johnson295189b2012-06-20 16:38:30 -070022 * This file limProcessDisassocFrame.cc contains the code
23 * for processing Disassocation Frame.
24 * Author: Chandra Modumudi
25 * Date: 03/24/02
26 * History:-
27 * Date Modified by Modification Information
28 * --------------------------------------------------------------------
29 *
30 */
31#include "palTypes.h"
32#include "wniApi.h"
33#include "sirApi.h"
34#include "aniGlobal.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070035#include "wniCfgSta.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070036
37#include "utilsApi.h"
38#include "limTypes.h"
39#include "limUtils.h"
40#include "limAssocUtils.h"
41#include "limSecurityUtils.h"
42#include "limSerDesUtils.h"
43#include "limSendMessages.h"
44#include "schApi.h"
45
46
47/**
48 * limProcessDisassocFrame
49 *
50 *FUNCTION:
51 * This function is called by limProcessMessageQueue() upon
52 * Disassociation frame reception.
53 *
54 *LOGIC:
55 *
56 *ASSUMPTIONS:
57 * DPH drops packets for STA with 'valid' bit in pStaDs set to '0'.
58 *
59 *NOTE:
60 *
61 * @param pMac - Pointer to Global MAC structure
62 * @param *pRxPacketInfo - A pointer to Rx packet info structure
63 * @return None
64 */
65void
66limProcessDisassocFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession psessionEntry)
67{
68 tANI_U8 *pBody;
69 tANI_U16 aid, reasonCode;
70 tpSirMacMgmtHdr pHdr;
71 tpDphHashNode pStaDs;
72 tLimMlmDisassocInd mlmDisassocInd;
Chet Lanctot186b5732013-03-18 10:26:30 -070073#ifdef WLAN_FEATURE_11W
74 tANI_U32 frameLen;
75#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070076
77 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
78 pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
79
80
81 if (limIsGroupAddr(pHdr->sa))
82 {
83 // Received Disassoc frame from a BC/MC address
84 // Log error and ignore it
Abhishek Singh6f9d2c82013-12-24 15:29:53 +053085 PELOGE(limLog(pMac, LOGE,
Kiran Kumar Lokere531ca702013-04-01 13:24:23 -070086 FL("received Disassoc frame from a BC/MC address"));)
Jeff Johnson295189b2012-06-20 16:38:30 -070087
88 return;
89 }
90
91 if (limIsGroupAddr(pHdr->da) && !limIsAddrBC(pHdr->da))
92 {
93 // Received Disassoc frame for a MC address
94 // Log error and ignore it
Abhishek Singh6f9d2c82013-12-24 15:29:53 +053095 PELOGE(limLog(pMac, LOGE,
Kiran Kumar Lokere531ca702013-04-01 13:24:23 -070096 FL("received Disassoc frame for a MC address"));)
Jeff Johnson295189b2012-06-20 16:38:30 -070097
98 return;
99 }
100
Chet Lanctot186b5732013-03-18 10:26:30 -0700101#ifdef WLAN_FEATURE_11W
102 /* PMF: If this session is a PMF session, then ensure that this frame was protected */
103 if(psessionEntry->limRmfEnabled && (WDA_GET_RX_DPU_FEEDBACK(pRxPacketInfo) & DPU_FEEDBACK_UNPROTECTED_ERROR))
104 {
105 PELOGE(limLog(pMac, LOGE, FL("received an unprotected disassoc from AP"));)
106 // If the frame received is unprotected, forward it to the supplicant to initiate
107 // an SA query
108 frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
109 //send the unprotected frame indication to SME
110 limSendSmeUnprotectedMgmtFrameInd( pMac, pHdr->fc.subType,
111 (tANI_U8*)pHdr, (frameLen + sizeof(tSirMacMgmtHdr)),
112 psessionEntry->smeSessionId, psessionEntry);
113 return;
114 }
115#endif
116
Jeff Johnson295189b2012-06-20 16:38:30 -0700117 // Get reasonCode from Disassociation frame body
118 reasonCode = sirReadU16(pBody);
119
Kanchanapally, Vidyullathaf9426e52013-12-24 17:28:54 +0530120 PELOG2(limLog(pMac, LOGE,
121 FL("Received Disassoc frame for Addr: "MAC_ADDRESS_STR"(mlm state=%s, sme state=%d),"
122 "with reason code %d from "MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->da),
123 limMlmStateStr(psessionEntry->limMlmState), psessionEntry->limSmeState, reasonCode,
124 MAC_ADDR_ARRAY(pHdr->sa));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700125
126 /**
127 * Extract 'associated' context for STA, if any.
128 * This is maintained by DPH and created by LIM.
129 */
130 pStaDs = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable);
131
132 if (pStaDs == NULL)
133 {
134 /**
135 * Disassociating STA is not associated.
136 * Log error.
137 */
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530138 PELOGE(limLog(pMac, LOGE,
139 FL("received Disassoc frame from STA that does not have context "
140 "reasonCode=%d, addr "MAC_ADDRESS_STR),
141 reasonCode,MAC_ADDR_ARRAY(pHdr->sa));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700142
143 return;
144 }
145
Madan Mohan Koyyalamudi25b6f8b2012-12-04 16:17:31 -0800146 if (limCheckDisassocDeauthAckPending(pMac, (tANI_U8*)pHdr->sa))
147 {
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530148 PELOGE(limLog(pMac, LOGE,
149 FL("Ignore the DisAssoc received, while waiting "
150 "for ack of disassoc/deauth"));)
Madan Mohan Koyyalamudi25b6f8b2012-12-04 16:17:31 -0800151 limCleanUpDisassocDeauthReq(pMac,(tANI_U8*)pHdr->sa, 1);
152 return;
153 }
154
Jeff Johnson295189b2012-06-20 16:38:30 -0700155 /** If we are in the Wait for ReAssoc Rsp state */
156 if (limIsReassocInProgress(pMac,psessionEntry)) {
157 /** If we had received the DisAssoc from,
158 * a. the Current AP during ReAssociate to different AP in same ESS
159 * b. Unknown AP
160 * drop/ignore the DisAssoc received
161 */
162 if (!IS_REASSOC_BSSID(pMac,pHdr->sa,psessionEntry)) {
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530163 PELOGE(limLog(pMac, LOGE, FL("Ignore the DisAssoc received, while "
164 "Processing ReAssoc with different/unknown AP"));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700165 return;
166 }
167 /** If the Disassoc is received from the new AP to which we tried to ReAssociate
168 * Drop ReAssoc and Restore the Previous context( current connected AP).
169 */
170 if (!IS_CURRENT_BSSID(pMac, pHdr->sa,psessionEntry)) {
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530171 PELOGE(limLog(pMac, LOGE, FL("received Disassoc from the New AP to "
172 "which ReAssoc is sent "));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700173 limRestorePreReassocState(pMac,
174 eSIR_SME_REASSOC_REFUSED, reasonCode,psessionEntry);
175 return;
176 }
177 }
178
179 if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE) ||
180 (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) )
181 {
182 switch (reasonCode)
183 {
184 case eSIR_MAC_UNSPEC_FAILURE_REASON:
185 case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON:
186 case eSIR_MAC_DISASSOC_LEAVING_BSS_REASON:
187 case eSIR_MAC_MIC_FAILURE_REASON:
188 case eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON:
189 case eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON:
190 case eSIR_MAC_RSN_IE_MISMATCH_REASON:
191 case eSIR_MAC_1X_AUTH_FAILURE_REASON:
192 // Valid reasonCode in received Disassociation frame
193 break;
194
195 default:
196 // Invalid reasonCode in received Disassociation frame
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530197 PELOGE(limLog(pMac, LOGE,
198 FL("received Disassoc frame with invalid reasonCode "
199 "%d from "MAC_ADDRESS_STR),
200 reasonCode, MAC_ADDR_ARRAY(pHdr->sa));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700201 break;
202 }
203 }
204 else if ( ((psessionEntry->limSystemRole == eLIM_STA_ROLE) ||
205 (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) &&
206 ((psessionEntry->limSmeState != eLIM_SME_WT_JOIN_STATE) &&
207 (psessionEntry->limSmeState != eLIM_SME_WT_AUTH_STATE) &&
208 (psessionEntry->limSmeState != eLIM_SME_WT_ASSOC_STATE) &&
209 (psessionEntry->limSmeState != eLIM_SME_WT_REASSOC_STATE) ))
210 {
211 switch (reasonCode)
212 {
213 case eSIR_MAC_UNSPEC_FAILURE_REASON:
214 case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON:
215 case eSIR_MAC_DISASSOC_DUE_TO_DISABILITY_REASON:
216 case eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON:
217 case eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON:
218 case eSIR_MAC_MIC_FAILURE_REASON:
219 case eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON:
220 case eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON:
221 case eSIR_MAC_RSN_IE_MISMATCH_REASON:
222 case eSIR_MAC_1X_AUTH_FAILURE_REASON:
Chet Lanctot186b5732013-03-18 10:26:30 -0700223 case eSIR_MAC_PREV_AUTH_NOT_VALID_REASON:
Jeff Johnson295189b2012-06-20 16:38:30 -0700224 // Valid reasonCode in received Disassociation frame
225 break;
226
Srinivas Girigowdac03c5a82013-07-01 13:44:54 -0700227 case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON:
Jeff Johnson295189b2012-06-20 16:38:30 -0700228 case eSIR_MAC_DISASSOC_LEAVING_BSS_REASON:
229 // Valid reasonCode in received Disassociation frame
230 // as long as we're not about to channel switch
Jeff Johnsone7245742012-09-05 17:12:55 -0700231 if(psessionEntry->gLimChannelSwitch.state != eLIM_CHANNEL_SWITCH_IDLE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700232 {
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530233 limLog(pMac, LOGE,
Jeff Johnson295189b2012-06-20 16:38:30 -0700234 FL("Ignoring disassoc frame due to upcoming "
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530235 "channel switch, from "MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa));
Jeff Johnson295189b2012-06-20 16:38:30 -0700236 return;
237 }
238 break;
239
240 default:
241 // Invalid reasonCode in received Disassociation frame
242 // Log error and ignore the frame
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530243 PELOGE(limLog(pMac, LOGE,
244 FL("received Disassoc frame with invalid reasonCode "
245 "%d from "MAC_ADDRESS_STR), reasonCode,
246 MAC_ADDR_ARRAY(pHdr->sa));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700247 return;
248 }
249 }
250 else
251 {
252 // Received Disassociation frame in either IBSS
Srinivas Girigowdac03c5a82013-07-01 13:44:54 -0700253 // or un-known role. Log and ignore it
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530254 limLog(pMac, LOGE,
255 FL("received Disassoc frame with invalid reasonCode %d in role "
256 "%d in sme state %d from "MAC_ADDRESS_STR), reasonCode,
257 psessionEntry->limSystemRole, psessionEntry->limSmeState,
258 MAC_ADDR_ARRAY(pHdr->sa));
Jeff Johnson295189b2012-06-20 16:38:30 -0700259
260 return;
261 }
262
Jeff Johnson295189b2012-06-20 16:38:30 -0700263 if ((pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) ||
264 (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE))
265 {
266 /**
267 * Already in the process of deleting context for the peer
268 * and received Disassociation frame. Log and Ignore.
269 */
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530270 PELOGE(limLog(pMac, LOGE,
271 FL("received Disassoc frame in state %d from "MAC_ADDRESS_STR),
272 pStaDs->mlmStaContext.mlmState, MAC_ADDR_ARRAY(pHdr->sa));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700273
274 return;
275 }
276
277 if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE)
278 {
279 /**
280 * Requesting STA is in some 'transient' state?
281 * Log error.
282 */
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530283 PELOGE(limLog(pMac, LOGE,
284 FL("received Disassoc frame from peer that is in state %X, addr "
285 MAC_ADDRESS_STR),
286 pStaDs->mlmStaContext.mlmState, MAC_ADDR_ARRAY(pHdr->sa));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700287 } // if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE)
288
289 pStaDs->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DISASSOC;
290 pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes) reasonCode;
291
292 // Issue Disassoc Indication to SME.
Hema Aparna Medicharlaeef78fc2013-07-12 11:47:01 +0530293 vos_mem_copy((tANI_U8 *) &mlmDisassocInd.peerMacAddr,
294 (tANI_U8 *) pStaDs->staAddr,
295 sizeof(tSirMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -0700296 mlmDisassocInd.reasonCode =
297 (tANI_U8) pStaDs->mlmStaContext.disassocReason;
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 mlmDisassocInd.disassocTrigger = eLIM_PEER_ENTITY_DISASSOC;
299
300 /* Update PE session Id */
301 mlmDisassocInd.sessionId = psessionEntry->peSessionId;
302
303 if (limIsReassocInProgress(pMac,psessionEntry)) {
304
305 /* If we're in the middle of ReAssoc and received disassoc from
306 * the ReAssoc AP, then notify SME by sending REASSOC_RSP with
307 * failure result code. By design, SME will then issue "Disassoc"
308 * and cleanup will happen at that time.
309 */
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530310 PELOGE(limLog(pMac, LOGE, FL("received Disassoc from AP while waiting "
311 "for Reassoc Rsp"));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700312
313 if (psessionEntry->limAssocResponseData) {
Hema Aparna Medicharlaeef78fc2013-07-12 11:47:01 +0530314 vos_mem_free(psessionEntry->limAssocResponseData);
Jeff Johnson295189b2012-06-20 16:38:30 -0700315 psessionEntry->limAssocResponseData = NULL;
316 }
317
318 limRestorePreReassocState(pMac,eSIR_SME_REASSOC_REFUSED, reasonCode,psessionEntry);
319 return;
320 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700321
322 limPostSmeMessage(pMac, LIM_MLM_DISASSOC_IND,
323 (tANI_U32 *) &mlmDisassocInd);
324
325
326 // send eWNI_SME_DISASSOC_IND to SME
327 limSendSmeDisassocInd(pMac, pStaDs,psessionEntry);
328
329 return;
330} /*** end limProcessDisassocFrame() ***/
331