blob: 9ae106645abbcccb11f568f85049d84aab0fbcba [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
2 * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
3 *
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 */
21
22/*
23 * */
24/** ------------------------------------------------------------------------- *
25 ------------------------------------------------------------------------- *
26
27
28 \file csrNeighborRoam.c
29
30 Implementation for the simple roaming algorithm for 802.11r Fast transitions and Legacy roaming for Android platform.
31
32 Copyright (C) 2010 Qualcomm, Incorporated
33
34
35 ========================================================================== */
36
37/*===========================================================================
38
39 EDIT HISTORY FOR FILE
40
41
42 This section contains comments describing changes made to the module.
43 Notice that changes are listed in reverse chronological order.
44
45
46
47 when who what, where, why
48---------- --- --------------------------------------------------------
4908/01/10 Murali Created
50
51===========================================================================*/
52#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING
53#include "wlan_qct_wda.h"
54#include "palApi.h"
55#include "csrInsideApi.h"
56#include "smsDebug.h"
57#include "logDump.h"
58#include "smeQosInternal.h"
59#include "wlan_qct_tl.h"
60#include "smeInside.h"
61#include "vos_diag_core_event.h"
62#include "vos_diag_core_log.h"
63#include "csrApi.h"
64#include "wlan_qct_tl.h"
65#include "sme_Api.h"
66#include "csrNeighborRoam.h"
67#ifdef FEATURE_WLAN_CCX
68#include "csrCcx.h"
69#endif
70
71#define WLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG 1
72#ifdef WLAN_FEATURE_NEIGHBOR_ROAMING_DEBUG
73#define NEIGHBOR_ROAM_DEBUG smsLog
74#else
75#define NEIGHBOR_ROAM_DEBUG(x...)
76#endif
77
78VOS_STATUS csrNeighborRoamNeighborLookupUPCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
79 v_PVOID_t pUserCtxt);
80VOS_STATUS csrNeighborRoamNeighborLookupDOWNCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
81 v_PVOID_t pUserCtxt);
82void csrNeighborRoamRRMNeighborReportResult(void *context, VOS_STATUS vosStatus);
83eHalStatus csrRoamCopyConnectedProfile(tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRoamProfile *pDstProfile );
84
85#ifdef WLAN_FEATURE_VOWIFI_11R
86static eHalStatus csrNeighborRoamIssuePreauthReq(tpAniSirGlobal pMac);
87VOS_STATUS csrNeighborRoamIssueNeighborRptRequest(tpAniSirGlobal pMac);
88#endif
89
90/* State Transition macro */
91#define CSR_NEIGHBOR_ROAM_STATE_TRANSITION(newState)\
92{\
93 pMac->roam.neighborRoamInfo.prevNeighborRoamState = pMac->roam.neighborRoamInfo.neighborRoamState;\
94 pMac->roam.neighborRoamInfo.neighborRoamState = newState;\
95 smsLog(pMac, LOGE, FL("Neighbor Roam Transition from state %d ==> %d"), pMac->roam.neighborRoamInfo.prevNeighborRoamState, newState);\
96}
97
98/* ---------------------------------------------------------------------------
99
100 \fn csrNeighborRoamFreeNeighborRoamBSSNode
101
102 \brief This function frees all the internal pointers CSR NeighborRoam BSS Info
103 and also frees the node itself
104
105 \param pMac - The handle returned by macOpen.
106 neighborRoamBSSNode - Neighbor Roam BSS Node to be freed
107
108 \return VOID
109
110---------------------------------------------------------------------------*/
111void csrNeighborRoamFreeNeighborRoamBSSNode(tpAniSirGlobal pMac, tpCsrNeighborRoamBSSInfo neighborRoamBSSNode)
112{
113 if (neighborRoamBSSNode)
114 {
115 if (neighborRoamBSSNode->pBssDescription)
116 {
117 vos_mem_free(neighborRoamBSSNode->pBssDescription);
118 neighborRoamBSSNode->pBssDescription = NULL;
119 }
120 vos_mem_free(neighborRoamBSSNode);
121 neighborRoamBSSNode = NULL;
122 }
123
124 return;
125}
126
127/* ---------------------------------------------------------------------------
128
129 \fn csrNeighborRoamRemoveRoamableAPListEntry
130
131 \brief This function removes a given entry from the given list
132
133 \param pMac - The handle returned by macOpen.
134 pList - The list from which the entry should be removed
135 pNeighborEntry - Neighbor Roam BSS Node to be removed
136
137 \return TRUE if successfully removed, else FALSE
138
139---------------------------------------------------------------------------*/
140tANI_BOOLEAN csrNeighborRoamRemoveRoamableAPListEntry(tpAniSirGlobal pMac,
141 tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry)
142{
143 if(pList)
144 {
145 return csrLLRemoveEntry(pList, &pNeighborEntry->List, LL_ACCESS_LOCK);
146 }
147
148 smsLog(pMac, LOGE, FL("Removing neighbor BSS node from list failed. Current count = %d\n"), csrLLCount(pList));
149
150 return eANI_BOOLEAN_FALSE;
151}
152
153/* ---------------------------------------------------------------------------
154
155 \fn csrNeighborRoamGetRoamableAPListNextEntry
156
157 \brief Gets the entry next to passed entry. If NULL is passed, return the entry in the head of the list
158
159 \param pMac - The handle returned by macOpen.
160 pList - The list from which the entry should be returned
161 pNeighborEntry - Neighbor Roam BSS Node whose next entry should be returned
162
163 \return Neighbor Roam BSS Node to be returned
164
165---------------------------------------------------------------------------*/
166tpCsrNeighborRoamBSSInfo csrNeighborRoamGetRoamableAPListNextEntry(tpAniSirGlobal pMac,
167 tDblLinkList *pList, tpCsrNeighborRoamBSSInfo pNeighborEntry)
168{
169 tListElem *pEntry = NULL;
170 tpCsrNeighborRoamBSSInfo pResult = NULL;
171
172 if(pList)
173 {
174 if(NULL == pNeighborEntry)
175 {
176 pEntry = csrLLPeekHead(pList, LL_ACCESS_LOCK);
177 }
178 else
179 {
180 pEntry = csrLLNext(pList, &pNeighborEntry->List, LL_ACCESS_LOCK);
181 }
182 if(pEntry)
183 {
184 pResult = GET_BASE_ADDR(pEntry, tCsrNeighborRoamBSSInfo, List);
185 }
186 }
187
188 return pResult;
189}
190
191/* ---------------------------------------------------------------------------
192
193 \fn csrNeighborRoamFreeRoamableBSSList
194
195 \brief Empties and frees all the nodes in the roamable AP list
196
197 \param pMac - The handle returned by macOpen.
198 pList - Neighbor Roam BSS List to be emptied
199
200 \return VOID
201
202---------------------------------------------------------------------------*/
203void csrNeighborRoamFreeRoamableBSSList(tpAniSirGlobal pMac, tDblLinkList *pList)
204{
205 tpCsrNeighborRoamBSSInfo pResult = NULL;
206
207 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Emptying the BSS list. Current count = %d\n"), csrLLCount(pList));
208
209 /* Pick up the head, remove and free the node till the list becomes empty */
210 while ((pResult = csrNeighborRoamGetRoamableAPListNextEntry(pMac, pList, NULL)) != NULL)
211 {
212 csrNeighborRoamRemoveRoamableAPListEntry(pMac, pList, pResult);
213 csrNeighborRoamFreeNeighborRoamBSSNode(pMac, pResult);
214 }
215 return;
216}
217
218/* ---------------------------------------------------------------------------
219
220 \fn csrNeighborRoamReassocIndCallback
221
222 \brief Reassoc callback invoked by TL on crossing the registered re-assoc threshold.
223 Directly triggere HO in case of non-11r association
224 In case of 11R association, triggers a pre-auth eventually followed by actual HO
225
226 \param pAdapter - VOS Context
227 trafficStatus - UP/DOWN indication from TL
228 pUserCtxt - Parameter for callback registered during callback registration. Should be pMac
229
230 \return VOID
231
232---------------------------------------------------------------------------*/
233VOS_STATUS csrNeighborRoamReassocIndCallback(v_PVOID_t pAdapter,
234 v_U8_t trafficStatus,
235 v_PVOID_t pUserCtxt)
236{
237 tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt );
238 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
239 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
240
241 smsLog(pMac, LOG1, FL("Reassoc indication callback called"));
242
243
244 //smsLog(pMac, LOGE, FL("Reassoc indication callback called at state %d"), pNeighborRoamInfo->neighborRoamState);
245
246 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
247
248
249 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
250 WLANTL_HO_THRESHOLD_DOWN,
251 csrNeighborRoamReassocIndCallback,
252 VOS_MODULE_ID_SME);
253
254 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
255 {
256 //err msg
257 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
258 }
259
260 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering UP event neighbor lookup callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1));
261 /* Deregister reassoc callback. Ignore return status */
262 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1),
263 WLANTL_HO_THRESHOLD_DOWN,
264 csrNeighborRoamNeighborLookupUPCallback,
265 VOS_MODULE_ID_SME);
266
267 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
268 {
269 //err msg
270 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
271 }
272
273 /* We dont need to run this timer any more. */
274 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
275
276#ifdef WLAN_FEATURE_VOWIFI_11R
277 if (pNeighborRoamInfo->is11rAssoc)
278 {
279 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
280 {
281 csrNeighborRoamIssuePreauthReq(pMac);
282 }
283 else
284 {
285 smsLog(pMac, LOGE, FL("11R Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
286 VOS_ASSERT(0);
287 }
288 }
289 else
290#endif
291
292#ifdef FEATURE_WLAN_CCX
293 if (pNeighborRoamInfo->isCCXAssoc)
294 {
295 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
296 {
297 csrNeighborRoamIssuePreauthReq(pMac);
298 }
299 else
300 {
301 smsLog(pMac, LOGE, FL("CCX Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
302 VOS_ASSERT(0);
303 }
304 }
305 else
306#endif
307 {
308 if (eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN == pNeighborRoamInfo->neighborRoamState)
309 {
310 csrNeighborRoamRequestHandoff(pMac);
311 }
312 else
313 {
314 smsLog(pMac, LOGE, FL("Non-11R Reassoc indication received in unexpected state %d"), pNeighborRoamInfo->neighborRoamState);
315 VOS_ASSERT(0);
316 }
317 }
318 return VOS_STATUS_SUCCESS;
319}
320
321/* ---------------------------------------------------------------------------
322
323 \fn csrNeighborRoamResetConnectedStateControlInfo
324
325 \brief This function will reset the neighbor roam control info data structures.
326 This function should be invoked whenever we move to CONNECTED state from
327 any state other than INIT state
328
329 \param pMac - The handle returned by macOpen.
330
331 \return VOID
332
333---------------------------------------------------------------------------*/
334void csrNeighborRoamResetConnectedStateControlInfo(tpAniSirGlobal pMac)
335{
336 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
337
338 /* Do not reset the currentNeighborLookup Threshold here. The threshold and multiplier will be set before calling this API */
339 if ((pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived == FALSE) &&
340 (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels))
341 {
342 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
343 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0;
344
345 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
346 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
347
348 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
349 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
350 }
351 else
352 {
353 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
354 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE;
355 }
356
357 csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList);
358
359 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
360
361 /* Abort any ongoing BG scans */
362 if (eANI_BOOLEAN_TRUE == pNeighborRoamInfo->scanRspPending)
363 csrScanAbortMacScan(pMac);
364
365 pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_FALSE;
366
367 /* We dont need to run this timer any more. */
368 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
369
370#ifdef WLAN_FEATURE_VOWIFI_11R
371 /* Do not free up the preauth done list here */
372 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
373 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE;
374 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
375 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
376 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = 0;
377 vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
378 palTimerStop(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer);
379#endif
380
381}
382
383/* ---------------------------------------------------------------------------
384
385 \fn csrNeighborRoamResetInitStateControlInfo
386
387 \brief This function will reset the neighbor roam control info data structures.
388 This function should be invoked whenever we move to CONNECTED state from
389 INIT state
390
391 \param pMac - The handle returned by macOpen.
392
393 \return VOID
394
395---------------------------------------------------------------------------*/
396void csrNeighborRoamResetInitStateControlInfo(tpAniSirGlobal pMac)
397{
398 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
399 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
400
401 csrNeighborRoamResetConnectedStateControlInfo(pMac);
402
403 /* In addition to the above resets, we should clear off the curAPBssId/Session ID in the timers */
404 pNeighborRoamInfo->csrSessionId = CSR_SESSION_ID_INVALID;
405 vos_mem_set(pNeighborRoamInfo->currAPbssid, sizeof(tCsrBssid), 0);
406 pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac;
407 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
408#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX)
409 pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_FALSE;
410 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.pMac = pMac;
411 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
412 csrNeighborRoamPurgePreauthFailedList(pMac);
413#endif
414#ifdef FEATURE_WLAN_CCX
415 pNeighborRoamInfo->isCCXAssoc = eANI_BOOLEAN_FALSE;
416 pNeighborRoamInfo->isVOAdmitted = eANI_BOOLEAN_FALSE;
417 pNeighborRoamInfo->MinQBssLoadRequired = 0;
418#endif
419
420 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
421 /* Deregister reassoc callback. Ignore return status */
422 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
423 WLANTL_HO_THRESHOLD_DOWN,
424 csrNeighborRoamReassocIndCallback,
425 VOS_MODULE_ID_SME);
426
427 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
428 {
429 //err msg
430 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
431 }
432
433 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event neighborLookup callback with TL. RSSI = %d"), pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
434 /* Deregister neighbor lookup callback. Ignore return status */
435 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
436 WLANTL_HO_THRESHOLD_DOWN,
437 csrNeighborRoamNeighborLookupDOWNCallback,
438 VOS_MODULE_ID_SME);
439
440 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
441 {
442 //err msg
443 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamNeighborLookupDOWNCallback with TL: Status = %d\n"), vosStatus);
444 }
445
446 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering UP event neighbor lookup callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1));
447 /* Deregister reassoc callback. Ignore return status */
448 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1),
449 WLANTL_HO_THRESHOLD_UP,
450 csrNeighborRoamNeighborLookupUPCallback,
451 VOS_MODULE_ID_SME);
452
453 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
454 {
455 //err msg
456 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
457 }
458
459 /* Reset currentNeighborLookupThreshold only after deregistering DOWN event from TL */
460 pNeighborRoamInfo->currentLookupIncrementMultiplier = 0;
461 pNeighborRoamInfo->currentNeighborLookupThreshold = pNeighborRoamInfo->cfgParams.neighborLookupThreshold;
462
463 return;
464}
465
466#ifdef WLAN_FEATURE_VOWIFI_11R
467/* ---------------------------------------------------------------------------
468
469 \fn csrNeighborRoamBssIdScanFilter
470
471 \brief This API is used to prepare a filter to obtain scan results when
472 we complete the scan in the REPORT_SCAN state after receiving a
473 valid neighbor report from AP. This filter includes BSSIDs received from
474 the neighbor report from the AP in addition to the other filter parameters
475 created from connected profile
476
477 \param pMac - The handle returned by macOpen.
478 pScanFilter - Scan filter to be filled and returned
479
480 \return eHAL_STATUS_SUCCESS on succesful filter creation, corresponding error
481 code otherwise
482
483---------------------------------------------------------------------------*/
484static eHalStatus csrNeighborRoamBssIdScanFilter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter)
485{
486 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
487 tANI_U8 i = 0;
488
489 VOS_ASSERT(pScanFilter != NULL);
490 vos_mem_zero(pScanFilter, sizeof(tCsrScanResultFilter));
491
492 pScanFilter->BSSIDs.numOfBSSIDs = pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport;
493 pScanFilter->BSSIDs.bssid = vos_mem_malloc(sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs);
494 if (NULL == pScanFilter->BSSIDs.bssid)
495 {
496 smsLog(pMac, LOGE, FL("Scan Filter BSSID mem alloc failed"));
497 return eHAL_STATUS_FAILED_ALLOC;
498 }
499
500 vos_mem_zero(pScanFilter->BSSIDs.bssid, sizeof(tSirMacAddr) * pScanFilter->BSSIDs.numOfBSSIDs);
501
502 /* Populate the BSSID from Neighbor BSS info received from neighbor report */
503 for (i = 0; i < pScanFilter->BSSIDs.numOfBSSIDs; i++)
504 {
505 vos_mem_copy(&pScanFilter->BSSIDs.bssid[i],
506 pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[i].neighborBssId, sizeof(tSirMacAddr));
507 }
508
509 /* Fill other general scan filter params */
510 return csrNeighborRoamPrepareScanProfileFilter(pMac, pScanFilter);
511}
512
513/* ---------------------------------------------------------------------------
514
515 \fn csrNeighborRoamPurgePreauthFailList
516
517 \brief This function empties the preauth fail list
518
519 \param pMac - The handle returned by macOpen.
520
521 \return VOID
522
523---------------------------------------------------------------------------*/
524void csrNeighborRoamPurgePreauthFailList(tpAniSirGlobal pMac)
525{
526 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
527
528 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Purging the preauth fail list"));
529 while (pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress)
530 {
531 vos_mem_zero(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress-1],
532 sizeof(tSirMacAddr));
533 pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress--;
534 }
535 return;
536}
537
538/* ---------------------------------------------------------------------------
539
540 \fn csrNeighborRoamAddBssIdToPreauthFailList
541
542 \brief This function adds the given BSSID to the Preauth fail list
543
544 \param pMac - The handle returned by macOpen.
545 bssId - BSSID to be added to the preauth fail list
546
547 \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
548
549---------------------------------------------------------------------------*/
550eHalStatus csrNeighborRoamAddBssIdToPreauthFailList(tpAniSirGlobal pMac, tSirMacAddr bssId)
551{
552 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
553
554 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL(" Added BSSID %02x:%02x:%02x:%02x:%02x:%02x to Preauth failed list\n"),
555 bssId[0], bssId[1], bssId[2], bssId[3], bssId[4], bssId[5]);
556
557
558 if ((pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress + 1) >
559 MAX_NUM_PREAUTH_FAIL_LIST_ADDRESS)
560 {
561 smsLog(pMac, LOGE, FL("Preauth fail list already full.. Cannot add new one"));
562 return eHAL_STATUS_FAILURE;
563 }
564 vos_mem_copy(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress],
565 bssId, sizeof(tSirMacAddr));
566 pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress++;
567
568 return eHAL_STATUS_SUCCESS;
569}
570
571/* ---------------------------------------------------------------------------
572
573 \fn csrNeighborRoamIsPreauthCandidate
574
575 \brief This function checks whether the given MAC address is already
576 present in the preauth fail list and returns TRUE/FALSE accordingly
577
578 \param pMac - The handle returned by macOpen.
579
580 \return eANI_BOOLEAN_TRUE if preauth candidate, eANI_BOOLEAN_FALSE otherwise
581
582---------------------------------------------------------------------------*/
583tANI_BOOLEAN csrNeighborRoamIsPreauthCandidate(tpAniSirGlobal pMac, tSirMacAddr bssId)
584{
585 tANI_U8 i = 0;
586 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
587
588 if (0 == pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress)
589 return eANI_BOOLEAN_TRUE;
590
591 for (i = 0; i < pNeighborRoamInfo->FTRoamInfo.preAuthFailList.numMACAddress; i++)
592 {
593 if (VOS_TRUE == vos_mem_compare(pNeighborRoamInfo->FTRoamInfo.preAuthFailList.macAddress[i],
594 bssId, sizeof(tSirMacAddr)))
595 {
596 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("BSSID %02x:%02x:%02x:%02x:%02x:%02x already present in preauth fail list"),
597 bssId[0], bssId[1], bssId[2], bssId[3], bssId[4], bssId[5]);
598 return eANI_BOOLEAN_FALSE;
599 }
600 }
601
602 return eANI_BOOLEAN_TRUE;
603}
604
605/* ---------------------------------------------------------------------------
606
607 \fn csrNeighborRoamIssuePreauthReq
608
609 \brief This function issues preauth request to PE with the 1st AP entry in the
610 roamable AP list
611
612 \param pMac - The handle returned by macOpen.
613
614 \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
615
616---------------------------------------------------------------------------*/
617static eHalStatus csrNeighborRoamIssuePreauthReq(tpAniSirGlobal pMac)
618{
619 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
620 eHalStatus status = eHAL_STATUS_SUCCESS;
621 tpCsrNeighborRoamBSSInfo pNeighborBssNode;
622
623 /* This must not be true here */
624 VOS_ASSERT(pNeighborRoamInfo->FTRoamInfo.preauthRspPending == eANI_BOOLEAN_FALSE);
625
626 /* Issue Preauth request to PE here */
627 /* Need to issue the preauth request with the BSSID that is there in the head of the roamable AP list */
628 /* Parameters that should be passed are BSSID, Channel number and the neighborScanPeriod(probably) */
629 /* If roamableAPList gets empty, should transition to REPORT_SCAN state */
630 pNeighborBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL);
631
632 if (NULL == pNeighborBssNode)
633 {
634 smsLog(pMac, LOG1, FL("Roamable AP list is empty.. "));
635 return eHAL_STATUS_FAILURE;
636 }
637 else
638 {
639 status = csrRoamIssueFTPreauthReq(pMac, pNeighborRoamInfo->csrSessionId, pNeighborBssNode->pBssDescription);
640 if (eHAL_STATUS_SUCCESS != status)
641 {
642 smsLog(pMac, LOGE, FL("Send Preauth request to PE failed with status %d\n"), status);
643 return status;
644 }
645 }
646
647 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_TRUE;
648
649 /* Increment the preauth retry count */
650 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries++;
651
652 /* Transition the state to preauthenticating */
653 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING)
654
655 /* Start the preauth rsp timer */
656 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer,
657 CSR_NEIGHBOR_ROAM_PREAUTH_RSP_WAIT_MULTIPLIER * pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
658 eANI_BOOLEAN_FALSE);
659 if (eHAL_STATUS_SUCCESS != status)
660 {
661 smsLog(pMac, LOGE, FL("Preauth response wait timer start failed with status %d\n"), status);
662 return status;
663 }
664
665
666 return status;
667}
668
669/* ---------------------------------------------------------------------------
670
671 \fn csrNeighborRoamPreauthRspHandler
672
673 \brief This function handle the Preauth response from PE
674 Every preauth is allowed max 3 tries if it fails. If a bssid failed
675 for more than MAX_TRIES, we will remove it from the list and try
676 with the next node in the roamable AP list and add the BSSID to pre-auth failed
677 list. If no more entries present in
678 roamable AP list, transition to REPORT_SCAN state
679
680 \param pMac - The handle returned by macOpen.
681 vosStatus - VOS_STATUS_SUCCESS/FAILURE/TIMEOUT status from PE
682
683 \return VOID
684
685---------------------------------------------------------------------------*/
686void csrNeighborRoamPreauthRspHandler(tpAniSirGlobal pMac, VOS_STATUS vosStatus)
687{
688 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
689 eHalStatus status = eHAL_STATUS_SUCCESS;
690 tpCsrNeighborRoamBSSInfo pPreauthRspNode = NULL;
691
692 // We can receive it in these 2 states.
693 VOS_ASSERT((pNeighborRoamInfo->neighborRoamState == eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING) ||
694 (pNeighborRoamInfo->neighborRoamState == eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN));
695
696 if ((pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING) &&
697 (pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN))
698 {
699 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Preauth response received in state %\n"),
700 pNeighborRoamInfo->neighborRoamState);
701 }
702
703 if (VOS_STATUS_E_TIMEOUT != vosStatus)
704 {
705 /* This means we got the response from PE. Hence stop the timer */
706 status = palTimerStop(pMac->hHdd, pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimer);
707 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE;
708 }
709
710 if (VOS_STATUS_SUCCESS == vosStatus)
711 {
712 pPreauthRspNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL);
713 }
714 if ((VOS_STATUS_SUCCESS == vosStatus) && (NULL != pPreauthRspNode))
715 {
716 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Preauth completed successfully after %d tries\n"), pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries);
717
718 /* Preauth competer successfully. Insert the preauthenticated node to tail of preAuthDoneList */
719 csrNeighborRoamRemoveRoamableAPListEntry(pMac, &pNeighborRoamInfo->roamableAPList, pPreauthRspNode);
720 csrLLInsertTail(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, &pPreauthRspNode->List, LL_ACCESS_LOCK);
721
722 /* Pre-auth completed successfully. Transition to PREAUTH Done state */
723 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE)
724 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
725
726 /* The caller of this function would start a timer and by the time it expires, supplicant should
727 have provided the updated FTIEs to SME. So, when it expires, handoff will be triggered then */
728 }
729 else
730 {
731 tpCsrNeighborRoamBSSInfo pNeighborBssNode = NULL;
732 tListElem *pEntry;
733
734 smsLog(pMac, LOGE, FL("Preauth failed retry number %d, status = %d\n"), pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries, vosStatus);
735
736 /* Preauth failed. Add the bssId to the preAuth failed list MAC Address. Also remove the AP from roamable AP list */
737 if (pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries >= CSR_NEIGHBOR_ROAM_MAX_NUM_PREAUTH_RETRIES)
738 {
739 /* We are going to remove the node as it fails for more than MAX tries. Reset this count to 0 */
740 pNeighborRoamInfo->FTRoamInfo.numPreAuthRetries = 0;
741
742 /* The one in the head of the list should be one with which we issued pre-auth and failed */
743 pEntry = csrLLRemoveHead(&pNeighborRoamInfo->roamableAPList, LL_ACCESS_LOCK);
744 if(pEntry)
745 {
746 pNeighborBssNode = GET_BASE_ADDR(pEntry, tCsrNeighborRoamBSSInfo, List);
747 /* Add the BSSID to pre-auth fail list */
748 status = csrNeighborRoamAddBssIdToPreauthFailList(pMac, pNeighborBssNode->pBssDescription->bssId);
749 /* Now we can free this node */
750 csrNeighborRoamFreeNeighborRoamBSSNode(pMac, pNeighborBssNode);
751 }
752 }
753
754 /* Issue preauth request for the same/next entry */
755 if (eHAL_STATUS_SUCCESS == csrNeighborRoamIssuePreauthReq(pMac))
756 return;
757
758 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
759
760 /* Start the neighbor results refresh timer and transition to REPORT_SCAN state to perform scan again */
761 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer,
762 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod * PAL_TIMER_TO_MS_UNIT,
763 eANI_BOOLEAN_FALSE);
764 if (eHAL_STATUS_SUCCESS != status)
765 {
766 smsLog(pMac, LOGE, FL("Neighbor results refresh timer start failed with status %d\n"), status);
767 return;
768 }
769 }
770}
771#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */
772
773/* ---------------------------------------------------------------------------
774
775 \fn csrNeighborRoamPrepareScanProfileFilter
776
777 \brief This function creates a scan filter based on the currently connected profile.
778 Based on this filter, scan results are obtained
779
780 \param pMac - The handle returned by macOpen.
781 pScanFilter - Populated scan filter based on the connected profile
782
783 \return eHAL_STATUS_SUCCESS on success, eHAL_STATUS_FAILURE otherwise
784
785---------------------------------------------------------------------------*/
786eHalStatus csrNeighborRoamPrepareScanProfileFilter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter)
787{
788 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
789 tANI_U8 sessionId = (tANI_U8)pNeighborRoamInfo->csrSessionId;
790 tCsrRoamConnectedProfile *pCurProfile = &pMac->roam.roamSession[sessionId].connectedProfile;
791 tANI_U8 i = 0;
792
793 VOS_ASSERT(pScanFilter != NULL);
794
795 vos_mem_zero(pScanFilter, sizeof(tCsrScanResultFilter));
796
797 /* We dont want to set BSSID based Filter */
798 pScanFilter->BSSIDs.numOfBSSIDs = 0;
799
800 /* Populate all the information from the connected profile */
801 pScanFilter->SSIDs.numOfSSIDs = 1;
802 pScanFilter->SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo));
803 if (NULL == pScanFilter->SSIDs.SSIDList)
804 {
805 smsLog(pMac, LOGE, FL("Scan Filter SSID mem alloc failed"));
806 return eHAL_STATUS_FAILED_ALLOC;
807 }
808 pScanFilter->SSIDs.SSIDList->handoffPermitted = 1;
809 pScanFilter->SSIDs.SSIDList->ssidHidden = 0;
810 pScanFilter->SSIDs.SSIDList->SSID.length = pCurProfile->SSID.length;
811 vos_mem_copy((void *)pScanFilter->SSIDs.SSIDList->SSID.ssId, (void *)pCurProfile->SSID.ssId, pCurProfile->SSID.length);
812
813 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Filtering for SSID %s from scan results.. SSID Length = %d\n"),
814 pScanFilter->SSIDs.SSIDList->SSID.ssId, pScanFilter->SSIDs.SSIDList->SSID.length);
815 pScanFilter->authType.numEntries = 1;
816 pScanFilter->authType.authType[0] = pCurProfile->AuthType;
817
818 pScanFilter->EncryptionType.numEntries = 1; //This must be 1
819 pScanFilter->EncryptionType.encryptionType[0] = pCurProfile->EncryptionType;
820
821 pScanFilter->mcEncryptionType.numEntries = 1;
822 pScanFilter->mcEncryptionType.encryptionType[0] = pCurProfile->mcEncryptionType;
823
824 pScanFilter->BSSType = pCurProfile->BSSType;
825
826 /* We are intrested only in the scan results on channels that we scanned */
827 pScanFilter->ChannelInfo.numOfChannels = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels;
828 pScanFilter->ChannelInfo.ChannelList = vos_mem_malloc(pScanFilter->ChannelInfo.numOfChannels * sizeof(tANI_U8));
829 if (NULL == pScanFilter->ChannelInfo.ChannelList)
830 {
831 smsLog(pMac, LOGE, FL("Scan Filter Channel list mem alloc failed"));
832 vos_mem_free(pScanFilter->SSIDs.SSIDList);
833 pScanFilter->SSIDs.SSIDList = NULL;
834 return eHAL_STATUS_FAILED_ALLOC;
835 }
836 for (i = 0; i < pScanFilter->ChannelInfo.numOfChannels; i++)
837 {
838 pScanFilter->ChannelInfo.ChannelList[i] = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i];
839 }
840
841#ifdef WLAN_FEATURE_VOWIFI_11R
842 if (pNeighborRoamInfo->is11rAssoc)
843 {
844 /* MDIE should be added as a part of profile. This should be added as a part of filter as well */
845 pScanFilter->MDID.mdiePresent = pCurProfile->MDID.mdiePresent;
846 pScanFilter->MDID.mobilityDomain = pCurProfile->MDID.mobilityDomain;
847 }
848#endif
849
850 return eHAL_STATUS_SUCCESS;
851}
852
853/* ---------------------------------------------------------------------------
854
855 \fn csrNeighborRoamProcessScanResults
856
857 \brief This function extracts scan results, sorts on the basis of neighbor score(todo).
858 Assumed that the results are already sorted by RSSI by csrScanGetResult
859
860 \param pMac - The handle returned by macOpen.
861 pScanResultList - Scan result result obtained from csrScanGetResult()
862
863 \return VOID
864
865---------------------------------------------------------------------------*/
866
867static void csrNeighborRoamProcessScanResults(tpAniSirGlobal pMac, tScanResultHandle *pScanResultList)
868{
869 tCsrScanResultInfo *pScanResult;
870 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
871 tpCsrNeighborRoamBSSInfo pBssInfo;
872
873 /* Expecting the scan result already to be in the sorted order based on the RSSI */
874 /* Based on the previous state we need to check whether the list should be sorted again taking neighbor score into consideration */
875 /* If previous state is CFG_CHAN_LIST_SCAN, there should not be any neighbor score associated with any of the BSS.
876 If the previous state is REPORT_QUERY, then there will be neighbor score for each of the APs */
877 /* For now, let us take the top of the list provided as it is by the CSR Scan result API. This means it is assumed that neighbor score
878 and rssi score are in the same order. This will be taken care later */
879
880 while (NULL != (pScanResult = csrScanResultGetNext(pMac, *pScanResultList)))
881 {
882 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Scan result: BSSID : %02x:%02x:%02x:%02x:%02x:%02x"),
883 pScanResult->BssDescriptor.bssId[0],
884 pScanResult->BssDescriptor.bssId[1],
885 pScanResult->BssDescriptor.bssId[2],
886 pScanResult->BssDescriptor.bssId[3],
887 pScanResult->BssDescriptor.bssId[4],
888 pScanResult->BssDescriptor.bssId[5]);
889
890 if (VOS_TRUE == vos_mem_compare(pScanResult->BssDescriptor.bssId,
891 pNeighborRoamInfo->currAPbssid, sizeof(tSirMacAddr)))
892 {
893 //currently associated AP. Do not have this in the roamable AP list
894 continue;
895 }
896
897 if (abs(pNeighborRoamInfo->cfgParams.neighborReassocThreshold) < abs(pScanResult->BssDescriptor.rssi))
898 {
899 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
900 "%s: [INFOLOG]Current reassoc threshold %d new ap rssi worse=%d\n", __func__,
901 (int)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
902 (int)pScanResult->BssDescriptor.rssi * (-1) );
903 continue;
904 }
905
906#ifdef WLAN_FEATURE_VOWIFI_11R
907 if (pNeighborRoamInfo->is11rAssoc)
908 {
909 if (!csrNeighborRoamIsPreauthCandidate(pMac, pScanResult->BssDescriptor.bssId))
910 {
911 smsLog(pMac, LOGE, FL("BSSID present in pre-auth fail list.. Ignoring"));
912 continue;
913 }
914 }
915#endif /* WLAN_FEATURE_VOWIFI_11R */
916
917#ifdef FEATURE_WLAN_CCX
918 if (pNeighborRoamInfo->isCCXAssoc)
919 {
920 if (!csrNeighborRoamIsPreauthCandidate(pMac, pScanResult->BssDescriptor.bssId))
921 {
922 smsLog(pMac, LOGE, FL("BSSID present in pre-auth fail list.. Ignoring"));
923 continue;
924 }
925 }
926 if ((pScanResult->BssDescriptor.QBSSLoad_present) &&
927 (pScanResult->BssDescriptor.QBSSLoad_avail))
928 {
929 if (pNeighborRoamInfo->isVOAdmitted)
930 {
931 smsLog(pMac, LOG1, FL("New AP has %x BW available\n"), (unsigned int)pScanResult->BssDescriptor.QBSSLoad_avail);
932 smsLog(pMac, LOG1, FL("We need %x BW available\n"),(unsigned int)pNeighborRoamInfo->MinQBssLoadRequired);
933 if (pScanResult->BssDescriptor.QBSSLoad_avail < pNeighborRoamInfo->MinQBssLoadRequired)
934 {
935 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
936 "[INFOLOG]BSSID : %02x:%02x:%02x:%02x:%02x:%02x has no bandwidth ignoring..not adding to roam list\n",
937 pScanResult->BssDescriptor.bssId[0],
938 pScanResult->BssDescriptor.bssId[1],
939 pScanResult->BssDescriptor.bssId[2],
940 pScanResult->BssDescriptor.bssId[3],
941 pScanResult->BssDescriptor.bssId[4],
942 pScanResult->BssDescriptor.bssId[5]);
943 continue;
944 }
945 }
946 }
947 else
948 {
949 smsLog(pMac, LOGE, FL("No QBss %x %x\n"), (unsigned int)pScanResult->BssDescriptor.QBSSLoad_avail, (unsigned int)pScanResult->BssDescriptor.QBSSLoad_present);
950 if (pNeighborRoamInfo->isVOAdmitted)
951 {
952 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
953 "[INFOLOG]BSSID : %02x:%02x:%02x:%02x:%02x:%02x has no QBSSLoad IE, ignoring..not adding to roam list\n",
954 pScanResult->BssDescriptor.bssId[0],
955 pScanResult->BssDescriptor.bssId[1],
956 pScanResult->BssDescriptor.bssId[2],
957 pScanResult->BssDescriptor.bssId[3],
958 pScanResult->BssDescriptor.bssId[4],
959 pScanResult->BssDescriptor.bssId[5]);
960 continue;
961 }
962 }
963#endif /* FEATURE_WLAN_CCX */
964
965 /* If the received timestamp in BSS description is earlier than the scan request timestamp, skip
966 * this result */
967 if (pNeighborRoamInfo->scanRequestTimeStamp >= pScanResult->BssDescriptor.nReceivedTime)
968 {
969 smsLog(pMac, LOGE, FL("Ignoring BSS as it is older than the scan request timestamp"));
970 continue;
971 }
972
973 pBssInfo = vos_mem_malloc(sizeof(tCsrNeighborRoamBSSInfo));
974 if (NULL == pBssInfo)
975 {
976 smsLog(pMac, LOGE, FL("Memory allocation for Neighbor Roam BSS Info failed.. Just ignoring"));
977 continue;
978 }
979
980 pBssInfo->pBssDescription = vos_mem_malloc(pScanResult->BssDescriptor.length + sizeof(pScanResult->BssDescriptor.length));
981 if (pBssInfo->pBssDescription != NULL)
982 {
983 vos_mem_copy(pBssInfo->pBssDescription, &pScanResult->BssDescriptor,
984 pScanResult->BssDescriptor.length + sizeof(pScanResult->BssDescriptor.length));
985 }
986 else
987 {
988 smsLog(pMac, LOGE, FL("Memory allocation for Neighbor Roam BSS Descriptor failed.. Just ignoring"));
989 vos_mem_free(pBssInfo);
990 continue;
991
992 }
993 pBssInfo->apPreferenceVal = 10; //some value for now. Need to calculate the actual score based on RSSI and neighbor AP score
994
995 /* Just add to the end of the list as it is already sorted by RSSI */
996 csrLLInsertTail(&pNeighborRoamInfo->roamableAPList, &pBssInfo->List, LL_ACCESS_LOCK);
997 }
998
999 /* Now we have all the scan results in our local list. Good time to free up the the list we got as a part of csrGetScanResult */
1000 csrScanResultPurge(pMac, *pScanResultList);
1001
1002 return;
1003}
1004
1005/* ---------------------------------------------------------------------------
1006
1007 \fn csrNeighborRoamHandleEmptyScanResult
1008
1009 \brief This function will be invoked in CFG_CHAN_LIST_SCAN state when
1010 there are no valid APs in the scan result for roaming. This means
1011 out AP is the best and no other AP is around. No point in scanning
1012 again and again. Performing the following here.
1013 1. Deregister the pre-auth callback from TL
1014 2. Stop the neighbor scan timer
1015 3. Re-register the neighbor lookup callback with increased pre-auth threshold
1016 4. Transition the state to CONNECTED state
1017
1018 \param pMac - The handle returned by macOpen.
1019
1020 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1021
1022---------------------------------------------------------------------------*/
1023static VOS_STATUS csrNeighborRoamHandleEmptyScanResult(tpAniSirGlobal pMac)
1024{
1025 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1026 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1027 eHalStatus status = eHAL_STATUS_SUCCESS;
1028
1029 /* Stop the neighbor scan timer now */
1030 status = palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
1031 if (eHAL_STATUS_SUCCESS != status)
1032 {
1033 smsLog(pMac, LOGW, FL(" palTimerStop failed with status %d\n"), status);
1034 }
1035
1036 /* Increase the neighbor lookup threshold by a constant factor or 1 */
1037 if ((pNeighborRoamInfo->currentNeighborLookupThreshold+3) < pNeighborRoamInfo->cfgParams.neighborReassocThreshold)
1038 {
1039 pNeighborRoamInfo->currentNeighborLookupThreshold += 3;
1040 }
1041
1042
1043#ifdef WLAN_FEATURE_VOWIFI_11R
1044 /* Clear off the old neighbor report details */
1045 vos_mem_zero(&pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo, sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
1046#endif
1047
1048 /* Reset all the necessary variables before transitioning to the CONNECTED state */
1049 csrNeighborRoamResetConnectedStateControlInfo(pMac);
1050
1051 /* Transition to CONNECTED state */
1052 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
1053 /* Re-register Neighbor Lookup threshold callback with TL */
1054 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering DOWN event neighbor lookup callback with TL for RSSI = %d"), pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
1055 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
1056 WLANTL_HO_THRESHOLD_DOWN,
1057 csrNeighborRoamNeighborLookupDOWNCallback,
1058 VOS_MODULE_ID_SME, pMac);
1059
1060 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1061 {
1062 //err msg
1063 smsLog(pMac, LOGW, FL(" Couldn't re-register csrNeighborRoamNeighborLookupDOWNCallback with TL: Status = %d\n"), status);
1064 }
1065 return vosStatus;
1066}
1067
1068/* ---------------------------------------------------------------------------
1069
1070 \fn csrNeighborRoamScanRequestCallback
1071
1072 \brief This function is the callback function registered in csrScanRequest() to
1073 indicate the completion of scan. If scan is completed for all the channels in
1074 the channel list, this function gets the scan result and starts the refresh results
1075 timer to avoid having stale results. If scan is not completed on all the channels,
1076 it restarts the neighbor scan timer which on expiry issues scan on the next
1077 channel
1078
1079 \param halHandle - The handle returned by macOpen.
1080 pContext - not used
1081 scanId - not used
1082 status - not used
1083
1084 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
1085
1086---------------------------------------------------------------------------*/
1087static eHalStatus csrNeighborRoamScanRequestCallback(tHalHandle halHandle, void *pContext,
1088 tANI_U32 scanId, eCsrScanStatus status)
1089{
1090 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
1091 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1092 tANI_U8 currentChanIndex;
1093 tCsrScanResultFilter scanFilter;
1094 tScanResultHandle scanResult;
1095 tANI_U32 tempVal = 0;
1096
1097 pMac->roam.neighborRoamInfo.scanRspPending = eANI_BOOLEAN_FALSE;
1098
1099 /* This can happen when we receive a UP event from TL in any of the scan states. Silently ignore it */
1100 if (eCSR_NEIGHBOR_ROAM_STATE_CONNECTED == pNeighborRoamInfo->neighborRoamState)
1101 {
1102 smsLog(pMac, LOGE, FL("Received in CONNECTED state. Must be because a UP event from TL after issuing scan request. Ignore it"));
1103 return eHAL_STATUS_SUCCESS;
1104 }
1105
1106 /* -1 is done because the chanIndex would have got incremented after issuing a successful scan request */
1107 currentChanIndex = (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex) ? (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex - 1) : 0;
1108
1109 /* Validate inputs */
1110 if (pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList) {
1111 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("csrNeighborRoamScanRequestCallback received for Channel = %d, ChanIndex = %d"),
1112 pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList[currentChanIndex], currentChanIndex);
1113 }
1114 else
1115 {
1116 smsLog(pMac, LOG1, FL("Received during clean-up. Silently ignore scan completion event."));
1117 return eHAL_STATUS_SUCCESS;
1118 }
1119
1120 if (eANI_BOOLEAN_FALSE == pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress)
1121 {
1122 /* Scan is completed in the CFG_CHAN_SCAN state. We can transition to REPORT_SCAN state
1123 just to get the results and perform PREAUTH */
1124 /* Now we have completed scanning the channel list. We have get the result by applying appropriate filter
1125 sort the results based on neighborScore and RSSI and select the best candidate out of the list */
1126 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("Channel list scan completed. Current chan index = %d"), currentChanIndex);
1127 VOS_ASSERT(pNeighborRoamInfo->roamChannelInfo.currentChanIndex == 0);
1128
1129#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX)
1130 /* If the state is REPORT_SCAN, then this must be the scan after the REPORT_QUERY state. So, we
1131 should use the BSSID filter made out of neighbor reports */
1132 if (eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN == pNeighborRoamInfo->neighborRoamState)
1133 {
1134 status = csrNeighborRoamBssIdScanFilter(pMac, &scanFilter);
1135 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("11R or CCX Association: Prepare scan filter status with neighbor AP = %d"), status);
1136 tempVal = 1;
1137 }
1138 else
1139#endif
1140 {
1141 status = csrNeighborRoamPrepareScanProfileFilter(pMac, &scanFilter);
1142 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, FL("11R/CCX/Other Association: Prepare scan to find neighbor AP filter status = %d"), status);
1143 }
1144 if (eHAL_STATUS_SUCCESS != status)
1145 {
1146 smsLog(pMac, LOGE, FL("Scan Filter preparation failed for Assoc type %d.. Bailing out.."), tempVal);
1147 return eHAL_STATUS_FAILURE;
1148 }
1149 status = csrScanGetResult(pMac, &scanFilter, &scanResult);
1150 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Get Scan Result status code %d"), status);
1151 /* Process the scan results and update roamable AP list */
1152 csrNeighborRoamProcessScanResults(pMac, &scanResult);
1153
1154 /* Free the scan filter */
1155 csrFreeScanFilter(pMac, &scanFilter);
1156
1157 tempVal = csrLLCount(&pNeighborRoamInfo->roamableAPList);
1158
1159 switch(pNeighborRoamInfo->neighborRoamState)
1160 {
1161 case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN:
1162 if (tempVal)
1163 {
1164#ifdef WLAN_FEATURE_VOWIFI_11R
1165 /* If this is a non-11r association, then we can register the reassoc callback here as we have some
1166 APs in the roamable AP list */
1167 if (pNeighborRoamInfo->is11rAssoc)
1168 {
1169 /* Valid APs are found after scan. Now we can initiate pre-authentication */
1170 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1171 }
1172 else
1173#endif
1174#ifdef FEATURE_WLAN_CCX
1175 /* If this is a non-11r association, then we can register the reassoc callback here as we have some
1176 APs in the roamable AP list */
1177 if (pNeighborRoamInfo->isCCXAssoc)
1178 {
1179 /* Valid APs are found after scan. Now we can initiate pre-authentication */
1180 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1181 }
1182 else
1183#endif
1184 {
1185
1186 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Completed scanning of CFG CHAN LIST in non-11r association. Registering reassoc callback"));
1187 /* Nothing much to do now. Will continue to remain in this state in case of non-11r association */
1188 /* Stop the timer. But how long the roamable AP list will be valid in here. At some point of time, we
1189 need to restart the CFG CHAN list scan procedure if reassoc callback is not invoked from TL
1190 within certain duration */
1191
1192// palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
1193 }
1194 }
1195 else
1196 {
1197 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("No candidate found after scanning in state %d.. "), pNeighborRoamInfo->neighborRoamState);
1198 /* Handle it appropriately */
1199 csrNeighborRoamHandleEmptyScanResult(pMac);
1200 }
1201 break;
1202#ifdef WLAN_FEATURE_VOWIFI_11R
1203 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
1204 if (!tempVal)
1205 {
1206 smsLog(pMac, LOGE, FL("No candidate found after scanning in state %d.. "), pNeighborRoamInfo->neighborRoamState);
1207 /* Stop the timer here as the same timer will be started again in CFG_CHAN_SCAN_STATE */
1208 csrNeighborRoamTransitToCFGChanScan(pMac);
1209 }
1210 break;
1211#endif /* WLAN_FEATURE_VOWIFI_11R */
1212 default:
1213 // Can come only in INIT state. Where in we are associated, we sent scan and user
1214 // in the meantime decides to disassoc, we will be in init state and still received call
1215 // back issued. Should not come here in any other state, printing just in case
1216 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1217 "%s: [INFOLOG] State %d\n", __func__, (pNeighborRoamInfo->neighborRoamState));
1218
1219 // Lets just exit out silently.
1220 return eHAL_STATUS_SUCCESS;
1221 }
1222
1223 if (tempVal)
1224 {
1225 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1226
1227 /* This timer should be started before registering the Reassoc callback with TL. This is because, it is very likely
1228 * that the callback getting called immediately and the timer would never be stopped when pre-auth is in progress */
1229 if (eHAL_STATUS_SUCCESS != palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer,
1230 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod * PAL_TIMER_TO_MS_UNIT,
1231 eANI_BOOLEAN_FALSE))
1232 {
1233 smsLog(pMac, LOGE, FL("Neighbor results refresh timer failed to start, status = %d"), status);
1234 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1235 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
1236 return VOS_STATUS_E_FAILURE;
1237 }
1238
1239 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering DOWN event Reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
1240 /* Register a reassoc Indication callback */
1241 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
1242 WLANTL_HO_THRESHOLD_DOWN,
1243 csrNeighborRoamReassocIndCallback,
1244 VOS_MODULE_ID_SME, pMac);
1245
1246 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1247 {
1248 //err msg
1249 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
1250 }
1251
1252 }
1253 }
1254 else
1255 {
1256
1257 /* Restart the timer for the next scan sequence as scanning is not over */
1258 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer,
1259 pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
1260 eANI_BOOLEAN_FALSE);
1261
1262 if (eHAL_STATUS_SUCCESS != status)
1263 {
1264 /* Timer start failed.. Should we ASSERT here??? */
1265 smsLog(pMac, LOGE, FL("Neighbor scan PAL Timer start failed, status = %d, Ignoring state transition"), status);
1266 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1267 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
1268 return VOS_STATUS_E_FAILURE;
1269 }
1270 }
1271 return eHAL_STATUS_SUCCESS;
1272}
1273
1274/* ---------------------------------------------------------------------------
1275
1276 \fn csrNeighborRoamIssueBgScanRequest
1277
1278 \brief This function issues CSR scan request after populating all the BG scan params
1279 passed
1280
1281 \param pMac - The handle returned by macOpen.
1282 pBgScanParams - Params that need to be populated into csr Scan request
1283
1284 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
1285
1286---------------------------------------------------------------------------*/
1287eHalStatus csrNeighborRoamIssueBgScanRequest(tpAniSirGlobal pMac, tCsrBGScanRequest *pBgScanParams)
1288{
1289 eHalStatus status = eHAL_STATUS_SUCCESS;
1290 tANI_U32 scanId;
1291 tCsrScanRequest scanReq;
1292 tANI_U8 channel;
1293
1294 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("csrNeighborRoamIssueBgScanRequest for Channel = %d, ChanIndex = %d"),
1295 pBgScanParams->ChannelInfo.ChannelList[0], pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex);
1296
1297
1298 //send down the scan req for 1 channel on the associated SSID
1299 palZeroMemory(pMac->hHdd, &scanReq, sizeof(tCsrScanRequest));
1300 /* Fill in the SSID Info */
1301 scanReq.SSIDs.numOfSSIDs = 1;
1302 scanReq.SSIDs.SSIDList = vos_mem_malloc(sizeof(tCsrSSIDInfo) * scanReq.SSIDs.numOfSSIDs);
1303 if(NULL == scanReq.SSIDs.SSIDList)
1304 {
1305 //err msg
1306 smsLog(pMac, LOGW, FL("Couldn't allocate memory for the SSID..Freeing memory allocated for Channel List\n"));
1307 return eHAL_STATUS_FAILURE;
1308 }
1309 vos_mem_zero(scanReq.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) * scanReq.SSIDs.numOfSSIDs);
1310
1311 scanReq.SSIDs.SSIDList[0].handoffPermitted = eANI_BOOLEAN_TRUE;
1312 scanReq.SSIDs.SSIDList[0].ssidHidden = eANI_BOOLEAN_TRUE;
1313 vos_mem_copy((void *)&scanReq.SSIDs.SSIDList[0].SSID, (void *)&pBgScanParams->SSID, sizeof(pBgScanParams->SSID));
1314
1315 scanReq.ChannelInfo.numOfChannels = pBgScanParams->ChannelInfo.numOfChannels;
1316
1317 channel = pBgScanParams->ChannelInfo.ChannelList[0];
1318 scanReq.ChannelInfo.ChannelList = &channel;
1319
1320 scanReq.BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
1321 scanReq.scanType = eSIR_ACTIVE_SCAN;
1322 scanReq.requestType = eCSR_SCAN_HO_BG_SCAN;
1323 scanReq.maxChnTime = pBgScanParams->maxChnTime;
1324 scanReq.minChnTime = pBgScanParams->minChnTime;
1325 status = csrScanRequest(pMac, CSR_SESSION_ID_INVALID, &scanReq,
1326 &scanId, csrNeighborRoamScanRequestCallback, NULL);
1327 if (eHAL_STATUS_SUCCESS != status)
1328 {
1329 smsLog(pMac, LOGE, FL("CSR Scan Request failed with status %d"), status);
1330 vos_mem_free(scanReq.SSIDs.SSIDList);
1331 return status;
1332 }
1333 pMac->roam.neighborRoamInfo.scanRspPending = eANI_BOOLEAN_TRUE;
1334
1335 vos_mem_free(scanReq.SSIDs.SSIDList);
1336 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List Address = %08x, Actual index = %d"),
1337 &pMac->roam.neighborRoamInfo.roamChannelInfo.currentChannelListInfo.ChannelList[0],
1338 pMac->roam.neighborRoamInfo.roamChannelInfo.currentChanIndex);
1339 return status;
1340}
1341
1342/* ---------------------------------------------------------------------------
1343
1344 \fn csrNeighborRoamPerformBgScan
1345
1346 \brief This function is invoked on every expiry of neighborScanTimer till all
1347 the channels in the channel list are scanned. It populates necessary
1348 parameters for BG scan and calls appropriate AP to invoke the CSR scan
1349 request
1350
1351 \param pMac - The handle returned by macOpen.
1352
1353 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
1354
1355---------------------------------------------------------------------------*/
1356eHalStatus csrNeighborRoamPerformBgScan(tpAniSirGlobal pMac)
1357{
1358 eHalStatus status = eHAL_STATUS_SUCCESS;
1359 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1360 tCsrBGScanRequest bgScanParams;
1361 tANI_U8 broadcastBssid[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
1362 tANI_U8 channel = 0;
1363
1364 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1365 {
1366 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List Address = %08x"), &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[0]);
1367 }
1368 else
1369 {
1370 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List Empty"));
1371 // Go back and restart. Mostly timer start failure has occured.
1372 // When timer start is declared a failure, then we delete the list.
1373 // Should not happen now as we stop and then only start the scan timer.
1374 // still handle the unlikely case.
1375 csrNeighborRoamHandleEmptyScanResult(pMac);
1376 return status;
1377 }
1378 /* Need to perform scan here before getting the list */
1379 vos_mem_copy(bgScanParams.bssid, broadcastBssid, sizeof(tCsrBssid));
1380 bgScanParams.SSID.length = pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length;
1381 vos_mem_copy(bgScanParams.SSID.ssId, pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.ssId,
1382 pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length);
1383
1384 channel = pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[pNeighborRoamInfo->roamChannelInfo.currentChanIndex];
1385 bgScanParams.ChannelInfo.numOfChannels = 1;
1386 bgScanParams.ChannelInfo.ChannelList = &channel;
1387
1388 bgScanParams.minChnTime = pNeighborRoamInfo->cfgParams.minChannelScanTime;
1389 bgScanParams.maxChnTime = pNeighborRoamInfo->cfgParams.maxChannelScanTime;
1390
1391 status = csrNeighborRoamIssueBgScanRequest(pMac, &bgScanParams);
1392 if (eHAL_STATUS_SUCCESS != status)
1393 {
1394 smsLog(pMac, LOGE, FL("Issue of BG Scan request failed: Status = %d"), status);
1395 return status;
1396 }
1397
1398 pNeighborRoamInfo->roamChannelInfo.currentChanIndex++;
1399 if (pNeighborRoamInfo->roamChannelInfo.currentChanIndex >=
1400 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels)
1401 {
1402 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Completed scanning channels in Channel List: CurrChanIndex = %d, Num Channels = %d"),
1403 pNeighborRoamInfo->roamChannelInfo.currentChanIndex,
1404 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels);
1405 /* We have completed scanning all the channels */
1406 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
1407 /* We are no longer scanning the channel list. Next timer firing should be used to get the scan results
1408 and select the best AP in the list */
1409 if (eANI_BOOLEAN_TRUE == pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress)
1410 {
1411 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
1412 }
1413 }
1414
1415 return status;
1416}
1417
1418/* ---------------------------------------------------------------------------
1419
1420 \fn csrNeighborRoamNeighborScanTimerCallback
1421
1422 \brief This function is the neighbor scan timer callback function. It invokes
1423 the BG scan request based on the current and previous states
1424
1425 \param pv - CSR timer context info which includes pMac and session ID
1426
1427 \return VOID
1428
1429---------------------------------------------------------------------------*/
1430void csrNeighborRoamNeighborScanTimerCallback(void *pv)
1431{
1432 tCsrTimerInfo *pInfo = (tCsrTimerInfo *)pv;
1433 tpAniSirGlobal pMac = pInfo->pMac;
1434 tANI_U32 sessionId = pInfo->sessionId;
1435 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1436
1437 // check if bg scan is on going, no need to send down the new params if true
1438 if(eANI_BOOLEAN_TRUE == pNeighborRoamInfo->scanRspPending)
1439 {
1440 //msg
1441 smsLog(pMac, LOGW, FL("Already BgScanRsp is Pending\n"));
1442 return;
1443 }
1444
1445 VOS_ASSERT(sessionId == pNeighborRoamInfo->csrSessionId);
1446
1447 switch (pNeighborRoamInfo->neighborRoamState)
1448 {
1449#ifdef WLAN_FEATURE_VOWIFI_11R
1450 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
1451 switch(pNeighborRoamInfo->prevNeighborRoamState)
1452 {
1453 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY:
1454 csrNeighborRoamPerformBgScan(pMac);
1455 break;
1456 default:
1457 smsLog(pMac, LOGE, FL("Neighbor scan callback received in state %d, prev state = %d"),
1458 pNeighborRoamInfo->neighborRoamState, pNeighborRoamInfo->prevNeighborRoamState);
1459 break;
1460 }
1461 break;
1462#endif /* WLAN_FEATURE_VOWIFI_11R */
1463 case eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN:
1464 csrNeighborRoamPerformBgScan(pMac);
1465 break;
1466 default:
1467 break;
1468 }
1469 return;
1470}
1471
1472/* ---------------------------------------------------------------------------
1473
1474 \fn csrNeighborRoamResultsRefreshTimerCallback
1475
1476 \brief This function is the timer callback function for results refresh timer.
1477 When this is invoked, it is as good as down event received from TL. So,
1478 clear off the roamable AP list and start the scan procedure based on 11R
1479 or non-11R association
1480
1481 \param context - CSR timer context info which includes pMac and session ID
1482
1483 \return VOID
1484
1485---------------------------------------------------------------------------*/
1486void csrNeighborRoamResultsRefreshTimerCallback(void *context)
1487{
1488 tCsrTimerInfo *pInfo = (tCsrTimerInfo *)context;
1489 tpAniSirGlobal pMac = pInfo->pMac;
1490 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1491 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1492
1493 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
1494
1495 /* Deregister reassoc callback. Ignore return status */
1496 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
1497 WLANTL_HO_THRESHOLD_DOWN,
1498 csrNeighborRoamReassocIndCallback,
1499 VOS_MODULE_ID_SME);
1500
1501 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1502 {
1503 //err msg
1504 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
1505 }
1506
1507 /* Reset all the variables just as no scan had happened before */
1508 csrNeighborRoamResetConnectedStateControlInfo(pMac);
1509
1510#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI
1511 if ((pNeighborRoamInfo->is11rAssoc) && (pMac->rrm.rrmSmeContext.rrmConfig.rrmEnabled))
1512 {
1513 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11R Association:Neighbor Lookup Down event received in CONNECTED state"));
1514 vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac);
1515 if (VOS_STATUS_SUCCESS != vosStatus)
1516 {
1517 smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d\n"), vosStatus);
1518 return;
1519 }
1520 /* Increment the neighbor report retry count after sending the neighbor request successfully */
1521 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++;
1522 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE;
1523 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY)
1524 }
1525 else
1526#endif
1527 {
1528 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Non 11R or CCX Association:Neighbor Lookup Down event received in CONNECTED state"));
1529 vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
1530 if (VOS_STATUS_SUCCESS != vosStatus)
1531 {
1532 return;
1533 }
1534 }
1535 return;
1536}
1537
1538#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI
1539/* ---------------------------------------------------------------------------
1540
1541 \fn csrNeighborRoamIssueNeighborRptRequest
1542
1543 \brief This function is invoked when TL issues a down event and the current assoc
1544 is a 11R association. It invokes SME RRM API to issue the neighbor request to
1545 the currently associated AP with the current SSID
1546
1547 \param pMac - The handle returned by macOpen.
1548
1549 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1550
1551---------------------------------------------------------------------------*/
1552VOS_STATUS csrNeighborRoamIssueNeighborRptRequest(tpAniSirGlobal pMac)
1553{
1554 tRrmNeighborRspCallbackInfo callbackInfo;
1555 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1556 tRrmNeighborReq neighborReq;
1557
1558
1559 neighborReq.no_ssid = 0;
1560
1561 /* Fill in the SSID */
1562 neighborReq.ssid.length = pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length;
1563 vos_mem_copy(neighborReq.ssid.ssId, pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.ssId,
1564 pMac->roam.roamSession[pNeighborRoamInfo->csrSessionId].connectedProfile.SSID.length);
1565
1566 callbackInfo.neighborRspCallback = csrNeighborRoamRRMNeighborReportResult;
1567 callbackInfo.neighborRspCallbackContext = pMac;
1568 callbackInfo.timeout = pNeighborRoamInfo->FTRoamInfo.neighborReportTimeout;
1569
1570 return sme_NeighborReportRequest(pMac,(tANI_U8) pNeighborRoamInfo->csrSessionId, &neighborReq, &callbackInfo);
1571}
1572
1573/* ---------------------------------------------------------------------------
1574
1575 \fn csrNeighborRoamCreateChanListFromNeighborReport
1576
1577 \brief This function is invoked when neighbor report is received for the
1578 neighbor request. Based on the channels present in the neighbor report,
1579 it generates channel list which will be used in REPORT_SCAN state to
1580 scan for these neighbor APs
1581
1582 \param pMac - The handle returned by macOpen.
1583
1584 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1585
1586---------------------------------------------------------------------------*/
1587VOS_STATUS csrNeighborRoamCreateChanListFromNeighborReport(tpAniSirGlobal pMac)
1588{
1589 tpRrmNeighborReportDesc pNeighborBssDesc;
1590 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1591 tANI_U8 numChannels = 0, i = 0, j=0;
1592 tANI_U8 channelList[MAX_BSS_IN_NEIGHBOR_RPT];
1593
1594 /* This should always start from 0 whenever we create a channel list out of neighbor AP list */
1595 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport = 0;
1596
1597 pNeighborBssDesc = smeRrmGetFirstBssEntryFromNeighborCache(pMac);
1598
1599 while (pNeighborBssDesc)
1600 {
1601 if (pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport >= MAX_BSS_IN_NEIGHBOR_RPT) break;
1602
1603 /* Update the neighbor BSS Info in the 11r FT Roam Info */
1604 pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].channelNum =
1605 pNeighborBssDesc->pNeighborBssDescription->channel;
1606 pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].neighborScore =
1607 (tANI_U8)pNeighborBssDesc->roamScore;
1608 vos_mem_copy(pNeighborRoamInfo->FTRoamInfo.neighboReportBssInfo[pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport].neighborBssId,
1609 pNeighborBssDesc->pNeighborBssDescription->bssId, sizeof(tSirMacAddr));
1610 pNeighborRoamInfo->FTRoamInfo.numBssFromNeighborReport++;
1611
1612 /* Saving the channel list non-redundantly */
1613 if (numChannels > 0)
1614 {
1615 for (i = 0; i < numChannels; i++)
1616 {
1617 if (pNeighborBssDesc->pNeighborBssDescription->channel == channelList[i])
1618 break;
1619 }
1620
1621 }
1622 if (i == numChannels)
1623 {
1624 if (pNeighborBssDesc->pNeighborBssDescription->channel)
1625 {
1626 // Make sure to add only if its the same band
1627 if ((pNeighborRoamInfo->currAPoperationChannel <= (RF_CHAN_14+1)) &&
1628 (pNeighborBssDesc->pNeighborBssDescription->channel <= (RF_CHAN_14+1)))
1629 {
1630 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1631 "%s: [INFOLOG] Adding %d to Neighbor channel list\n", __func__,
1632 pNeighborBssDesc->pNeighborBssDescription->channel);
1633 channelList[numChannels] = pNeighborBssDesc->pNeighborBssDescription->channel;
1634 numChannels++;
1635 }
1636 else if ((pNeighborRoamInfo->currAPoperationChannel >= RF_CHAN_128) &&
1637 (pNeighborBssDesc->pNeighborBssDescription->channel >= RF_CHAN_128))
1638 {
1639 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1640 "%s: [INFOLOG] Adding %d to Neighbor channel list\n", __func__,
1641 pNeighborBssDesc->pNeighborBssDescription->channel);
1642 channelList[numChannels] = pNeighborBssDesc->pNeighborBssDescription->channel;
1643 numChannels++;
1644 }
1645 }
1646 }
1647
1648 pNeighborBssDesc = smeRrmGetNextBssEntryFromNeighborCache(pMac, pNeighborBssDesc);
1649 }
1650
1651 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1652 {
1653 // Before we free the existing channel list for a safety net make sure
1654 // we have a union of the IAPP and the already existing list.
1655 for (i = 0; i < pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels; i++)
1656 {
1657 for (j = 0; j < numChannels; j++)
1658 {
1659 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i] == channelList[j])
1660 break;
1661 }
1662 if (j == numChannels)
1663 {
1664 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i])
1665 {
1666 // Make sure to add only if its the same band
1667 if ((pNeighborRoamInfo->currAPoperationChannel <= (RF_CHAN_14+1)) &&
1668 (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i] <= (RF_CHAN_14+1)))
1669 {
1670 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1671 "%s: [INFOLOG] Adding extra %d to Neighbor channel list\n", __func__,
1672 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i]);
1673 channelList[numChannels] =
1674 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i];
1675 numChannels++;
1676 }
1677 if ((pNeighborRoamInfo->currAPoperationChannel >= RF_CHAN_128) &&
1678 (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i] >= RF_CHAN_128))
1679 {
1680 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
1681 "%s: [INFOLOG] Adding extra %d to Neighbor channel list\n", __func__,
1682 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i]);
1683 channelList[numChannels] =
1684 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i];
1685 numChannels++;
1686 }
1687 }
1688 }
1689 }
1690 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1691 }
1692
1693 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
1694 /* Store the obtained channel list to the Neighbor Control data structure */
1695 if (numChannels)
1696 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = vos_mem_malloc((numChannels) * sizeof(tANI_U8));
1697 if (NULL == pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1698 {
1699 smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed.. TL event ignored"));
1700 return VOS_STATUS_E_RESOURCES;
1701 }
1702
1703 vos_mem_copy(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList,
1704 channelList, (numChannels) * sizeof(tANI_U8));
1705 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = numChannels;
1706 if (numChannels)
1707 {
1708 smsLog(pMac, LOG1, FL("IAPP Neighbor list callback received as expected in state %d."),
1709 pNeighborRoamInfo->neighborRoamState);
1710 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_TRUE;
1711 }
1712 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
1713 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE;
1714
1715 return VOS_STATUS_SUCCESS;
1716}
1717
1718/* ---------------------------------------------------------------------------
1719
1720 \fn csrNeighborRoamRRMNeighborReportResult
1721
1722 \brief This function is the neighbor report callback that will be invoked by
1723 SME RRM on receiving a neighbor report or of neighbor report is not
1724 received after timeout. On receiving a valid report, it generates a
1725 channel list from the neighbor report and starts the
1726 neighbor scan timer
1727
1728 \param context - The handle returned by macOpen.
1729 vosStatus - Status of the callback(SUCCESS/FAILURE)
1730
1731 \return VOID
1732
1733---------------------------------------------------------------------------*/
1734void csrNeighborRoamRRMNeighborReportResult(void *context, VOS_STATUS vosStatus)
1735{
1736 tpAniSirGlobal pMac = PMAC_STRUCT(context);
1737 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1738 eHalStatus status = eHAL_STATUS_SUCCESS;
1739
1740 smsLog(pMac, LOG1, FL("Neighbor report result callback with status = %d\n"), vosStatus);
1741 switch (pNeighborRoamInfo->neighborRoamState)
1742 {
1743 case eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY:
1744 /* Reset the report pending variable */
1745 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_FALSE;
1746 if (VOS_STATUS_SUCCESS == vosStatus)
1747 {
1748 /* Need to create channel list based on the neighbor AP list and transition to REPORT_SCAN state */
1749 vosStatus = csrNeighborRoamCreateChanListFromNeighborReport(pMac);
1750 if (VOS_STATUS_SUCCESS == vosStatus)
1751 {
1752 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Channel List created from Neighbor report, Transitioning to NEIGHBOR_SCAN state\n"));
1753 }
1754
1755 /* We are gonna scan now. Remember the time stamp to filter out results only after this timestamp */
1756 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
1757
1758 /* Now ready for neighbor scan based on the channel list created */
1759 /* Start Neighbor scan timer now. Multiplication by PAL_TIMER_TO_MS_UNIT is to convert ms to us which is
1760 what palTimerStart expects */
1761 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer,
1762 pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
1763 eANI_BOOLEAN_FALSE);
1764 if (eHAL_STATUS_SUCCESS != status)
1765 {
1766 /* Timer start failed.. Should we ASSERT here??? */
1767 smsLog(pMac, LOGE, FL("PAL Timer start for neighbor scan timer failed, status = %d, Ignoring state transition"), status);
1768 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1769 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
1770 return;
1771 }
1772 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
1773 /* Neighbor scan timer started. Transition to REPORT_SCAN state */
1774 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN)
1775 }
1776 else
1777 {
1778 /* Neighbor report timeout happened in SME RRM. We can try sending more neighbor requests until we
1779 reach the maxNeighborRetries or receiving a successful neighbor response */
1780 smsLog(pMac, LOGE, FL("Neighbor report result failed after %d retries, MAX RETRIES = %d\n"),
1781 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum, pNeighborRoamInfo->cfgParams.maxNeighborRetries);
1782 if (pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum >=
1783 pNeighborRoamInfo->cfgParams.maxNeighborRetries)
1784 {
1785 smsLog(pMac, LOGE, FL("Bailing out to CFG Channel list scan.. \n"));
1786 vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
1787 if (VOS_STATUS_SUCCESS != vosStatus)
1788 {
1789 smsLog(pMac, LOGE, FL("Transit to CFG Channel list scan state failed with status %d \n"), vosStatus);
1790 return;
1791 }
1792 /* We transitioned to different state now. Reset the Neighbor report retry count */
1793 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
1794 }
1795 else
1796 {
1797 vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac);
1798 if (VOS_STATUS_SUCCESS != vosStatus)
1799 {
1800 smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d\n"), vosStatus);
1801 return;
1802 }
1803 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE;
1804 /* Increment the neighbor report retry count after sending the neighbor request successfully */
1805 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++;
1806 }
1807 }
1808 break;
1809 default:
1810 smsLog(pMac, LOGE, FL("Neighbor result callback not expected in state %d, Ignoring.."), pNeighborRoamInfo->neighborRoamState);
1811 break;
1812 }
1813 return;
1814}
1815#endif /* WLAN_FEATURE_VOWIFI_11R */
1816
1817
1818/* ---------------------------------------------------------------------------
1819
1820 \fn csrNeighborRoamTransitToCFGChanScan
1821
1822 \brief This function is called whenever there is a transition to CFG chan scan
1823 state from any state. It frees up the current channel list and allocates
1824 a new memory for the channels received from CFG item. It then starts the
1825 neighbor scan timer to perform the scan on each channel one by one
1826
1827 \param pMac - The handle returned by macOpen.
1828
1829 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1830
1831---------------------------------------------------------------------------*/
1832VOS_STATUS csrNeighborRoamTransitToCFGChanScan(tpAniSirGlobal pMac)
1833{
1834 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1835 eHalStatus status = eHAL_STATUS_SUCCESS;
1836 int i = 0;
1837 int numOfChannels = 0;
1838 tANI_U8 channelList[MAX_BSS_IN_NEIGHBOR_RPT];
1839
1840 if (
1841#ifdef FEATURE_WLAN_CCX
1842 ((pNeighborRoamInfo->isCCXAssoc) &&
1843 (pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived == eANI_BOOLEAN_FALSE)) ||
1844 (pNeighborRoamInfo->isCCXAssoc == eANI_BOOLEAN_FALSE) ||
1845#endif // CCX
1846 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels == 0)
1847
1848 {
1849 smsLog(pMac, LOGW, FL("Falling back to CFG channel list"));
1850
1851
1852 /* Free up the channel list and allocate a new memory. This is because we dont know how much
1853 was allocated last time. If we directly copy more number of bytes than allocated earlier, this might
1854 result in memory corruption */
1855 if (NULL != pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1856 {
1857 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1858 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
1859 }
1860 // Find the right subset of the cfg list based on the current band we are on.
1861 for (i = 0; i < pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels; i++)
1862 {
1863 if (pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i])
1864 {
1865 // Make sure to add only if its the same band
1866 if ((pNeighborRoamInfo->currAPoperationChannel <= (RF_CHAN_14+1)) &&
1867 (pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i] <= (RF_CHAN_14+1)))
1868 {
1869 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1870 "%s: [INFOLOG] Adding %d to Neighbor channel list\n", __func__,
1871 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i]);
1872 channelList[numOfChannels] = pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i];
1873 numOfChannels++;
1874 }
1875 if ((pNeighborRoamInfo->currAPoperationChannel >= RF_CHAN_128) &&
1876 (pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i] >= RF_CHAN_128))
1877 {
1878 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1879 "%s: [INFOLOG] Adding %d to Neighbor channel list\n", __func__,
1880 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i]);
1881 channelList[numOfChannels] = pNeighborRoamInfo->cfgParams.channelInfo.ChannelList[i];
1882 numOfChannels++;
1883 }
1884 }
1885 }
1886
1887 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = numOfChannels;
1888 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
1889 if (numOfChannels)
1890 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = vos_mem_malloc(numOfChannels);
1891
1892 if (NULL == pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
1893 {
1894 smsLog(pMac, LOGE, FL("Memory allocation for Channel list failed.. TL event ignored"));
1895 return VOS_STATUS_E_RESOURCES;
1896 }
1897
1898 /* Since this is a legacy case, copy the channel list from CFG here */
1899 vos_mem_copy(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList,
1900 channelList, numOfChannels * sizeof(tANI_U8));
1901
1902 for (i = 0; i < pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels; i++)
1903 {
1904 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, "Channel List from CFG = %d\n",
1905 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList[i]);
1906 }
1907 }
1908
1909 /* We are gonna scan now. Remember the time stamp to filter out results only after this timestamp */
1910 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
1911
1912 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
1913 /* Start Neighbor scan timer now. Multiplication by PAL_TIMER_TO_MS_UNIT is to convert ms to us which is
1914 what palTimerStart expects */
1915 status = palTimerStart(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer,
1916 pNeighborRoamInfo->cfgParams.neighborScanPeriod * PAL_TIMER_TO_MS_UNIT,
1917 eANI_BOOLEAN_FALSE);
1918
1919 if (eHAL_STATUS_SUCCESS != status)
1920 {
1921 /* Timer start failed.. */
1922 smsLog(pMac, LOGE, FL("Neighbor scan PAL Timer start failed, status = %d, Ignoring state transition"), status);
1923 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
1924 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
1925 return VOS_STATUS_E_FAILURE;
1926 }
1927
1928 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = 0;
1929 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_TRUE;
1930
1931 /* Transition to CFG_CHAN_LIST_SCAN_STATE */
1932 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CFG_CHAN_LIST_SCAN)
1933
1934 return VOS_STATUS_SUCCESS;
1935}
1936
1937/* ---------------------------------------------------------------------------
1938
1939 \fn csrNeighborRoamNeighborLookupUpEvent
1940
1941 \brief This function is called as soon as TL indicates that the current AP's
1942 RSSI is better than the neighbor lookup threshold. Here, we transition to
1943 CONNECTED state and reset all the scan parameters
1944
1945 \param pMac - The handle returned by macOpen.
1946
1947 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
1948
1949---------------------------------------------------------------------------*/
1950VOS_STATUS csrNeighborRoamNeighborLookupUpEvent(tpAniSirGlobal pMac)
1951{
1952 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
1953 VOS_STATUS vosStatus;
1954
1955 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering UP event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1));
1956 /* Deregister the UP event now */
1957 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1),
1958 WLANTL_HO_THRESHOLD_UP,
1959 csrNeighborRoamNeighborLookupUPCallback,
1960 VOS_MODULE_ID_SME);
1961
1962 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1963 {
1964 //err msg
1965 smsLog(pMac, LOGW, FL(" Couldn't Deregister csrNeighborRoamNeighborLookupCallback UP event from TL: Status = %d\n"), vosStatus);
1966 }
1967
1968 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
1969 /* Deregister the UP event now */
1970 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
1971 WLANTL_HO_THRESHOLD_DOWN,
1972 csrNeighborRoamNeighborLookupDOWNCallback,
1973 VOS_MODULE_ID_SME);
1974
1975 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1976 {
1977 //err msg
1978 smsLog(pMac, LOGW, FL(" Couldn't Deregister csrNeighborRoamNeighborLookupCallback UP event from TL: Status = %d\n"), vosStatus);
1979 }
1980
1981 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event reassoc callback with TL. RSSI = %d"), pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1));
1982 /* Deregister reassoc callback. */
1983 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborReassocThreshold * (-1),
1984 WLANTL_HO_THRESHOLD_DOWN,
1985 csrNeighborRoamReassocIndCallback,
1986 VOS_MODULE_ID_SME);
1987
1988 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1989 {
1990 //err msg
1991 smsLog(pMac, LOGW, FL(" Couldn't deregister csrNeighborRoamReassocIndCallback with TL: Status = %d\n"), vosStatus);
1992 }
1993
1994
1995 /* RSSI got better than the CFG neighbor lookup threshold. Reset the threshold to older value and set the increment multiplier to 0 */
1996 pNeighborRoamInfo->currentLookupIncrementMultiplier = 0;
1997
1998 pNeighborRoamInfo->currentNeighborLookupThreshold = pNeighborRoamInfo->cfgParams.neighborLookupThreshold;
1999
2000 /* Reset all the neighbor roam info control variables. Free all the allocated memory. It is like we are just associated now */
2001 csrNeighborRoamResetConnectedStateControlInfo(pMac);
2002
2003 /* Recheck whether the below check is needed. */
2004 if (pNeighborRoamInfo->neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
2005 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
2006
2007 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering DOWN event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
2008 /* Register Neighbor Lookup threshold callback with TL for DOWN event now */
2009 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
2010 WLANTL_HO_THRESHOLD_DOWN,
2011 csrNeighborRoamNeighborLookupDOWNCallback,
2012 VOS_MODULE_ID_SME, pMac);
2013 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2014 {
2015 //err msg
2016 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback DOWN event with TL: Status = %d\n"), vosStatus);
2017 }
2018
2019
2020 return vosStatus;
2021}
2022
2023/* ---------------------------------------------------------------------------
2024
2025 \fn csrNeighborRoamNeighborLookupDownEvent
2026
2027 \brief This function is called as soon as TL indicates that the current AP's
2028 RSSI falls below the current eighbor lookup threshold. Here, we transition to
2029 REPORT_QUERY for 11r association and CFG_CHAN_LIST_SCAN state if the assoc is
2030 a non-11R association.
2031
2032 \param pMac - The handle returned by macOpen.
2033
2034 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2035
2036---------------------------------------------------------------------------*/
2037VOS_STATUS csrNeighborRoamNeighborLookupDownEvent(tpAniSirGlobal pMac)
2038{
2039 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2040 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
2041 eHalStatus status = eHAL_STATUS_SUCCESS;
2042
2043 switch (pNeighborRoamInfo->neighborRoamState)
2044 {
2045 case eCSR_NEIGHBOR_ROAM_STATE_CONNECTED:
2046
2047 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Deregistering DOWN event neighbor lookup callback with TL. RSSI = %d,"),
2048 pNeighborRoamInfo->currentNeighborLookupThreshold * (-1));
2049 /* De-register Neighbor Lookup threshold callback with TL */
2050 vosStatus = WLANTL_DeregRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
2051 WLANTL_HO_THRESHOLD_DOWN,
2052 csrNeighborRoamNeighborLookupDOWNCallback,
2053 VOS_MODULE_ID_SME);
2054
2055 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2056 {
2057 //err msg
2058 smsLog(pMac, LOGW, FL(" Couldn't Deregister csrNeighborRoamNeighborLookupCallback DOWN event from TL: Status = %d\n"), status);
2059 }
2060
2061
2062#if defined WLAN_FEATURE_VOWIFI_11R && defined WLAN_FEATURE_VOWIFI
2063 if ((pNeighborRoamInfo->is11rAssoc) && (pMac->rrm.rrmSmeContext.rrmConfig.rrmEnabled))
2064 {
2065
2066 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11R Association:Neighbor Lookup Down event received in CONNECTED state"));
2067 vosStatus = csrNeighborRoamIssueNeighborRptRequest(pMac);
2068 if (VOS_STATUS_SUCCESS != vosStatus)
2069 {
2070 smsLog(pMac, LOGE, FL("Neighbor report request failed. status = %d\n"), vosStatus);
2071 return vosStatus;
2072 }
2073 /* Increment the neighbor report retry count after sending the neighbor request successfully */
2074 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum++;
2075 pNeighborRoamInfo->FTRoamInfo.neighborRptPending = eANI_BOOLEAN_TRUE;
2076 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REPORT_QUERY)
2077 }
2078 else
2079#endif
2080 {
2081 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Non 11R or CCX Association:Neighbor Lookup Down event received in CONNECTED state"));
2082
2083 vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
2084 if (VOS_STATUS_SUCCESS != vosStatus)
2085 {
2086 return vosStatus;
2087 }
2088 }
2089 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering UP event neighbor lookup callback with TL. RSSI = %d,"), pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1));
2090 /* Register Neighbor Lookup threshold callback with TL for UP event now */
2091 vosStatus = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->cfgParams.neighborLookupThreshold * (-1),
2092 WLANTL_HO_THRESHOLD_UP,
2093 csrNeighborRoamNeighborLookupUPCallback,
2094 VOS_MODULE_ID_SME, pMac);
2095 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
2096 {
2097 //err msg
2098 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupCallback UP event with TL: Status = %d\n"), status);
2099 }
2100 break;
2101 default:
2102 smsLog(pMac, LOGE, FL("DOWN event received in invalid state %d..Ignoring..."), pNeighborRoamInfo->neighborRoamState);
2103 break;
2104
2105 }
2106 return vosStatus;
2107}
2108
2109/* ---------------------------------------------------------------------------
2110
2111 \fn csrNeighborRoamNeighborLookupUPCallback
2112
2113 \brief This function is registered with TL to indicate whenever the RSSI
2114 gets better than the neighborLookup RSSI Threshold
2115
2116 \param pAdapter - VOS Context
2117 trafficStatus - UP/DOWN indication from TL
2118 pUserCtxt - Parameter for callback registered during callback registration. Should be pMac
2119
2120 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2121
2122---------------------------------------------------------------------------*/
2123VOS_STATUS csrNeighborRoamNeighborLookupUPCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
2124 v_PVOID_t pUserCtxt)
2125{
2126 tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt );
2127 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2128 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2129
2130 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Neighbor Lookup UP indication callback called with notification %d"), rssiNotification);
2131
2132 if(!csrIsConnStateConnectedInfra(pMac, pNeighborRoamInfo->csrSessionId))
2133 {
2134 smsLog(pMac, LOGW, "Ignoring the indication as we are not connected\n");
2135 return VOS_STATUS_SUCCESS;
2136 }
2137
2138 VOS_ASSERT(WLANTL_HO_THRESHOLD_UP == rssiNotification);
2139 vosStatus = csrNeighborRoamNeighborLookupUpEvent(pMac);
2140 return vosStatus;
2141}
2142
2143/* ---------------------------------------------------------------------------
2144
2145 \fn csrNeighborRoamNeighborLookupDOWNCallback
2146
2147 \brief This function is registered with TL to indicate whenever the RSSI
2148 falls below the current neighborLookup RSSI Threshold
2149
2150 \param pAdapter - VOS Context
2151 trafficStatus - UP/DOWN indication from TL
2152 pUserCtxt - Parameter for callback registered during callback registration. Should be pMac
2153
2154 \return VOS_STATUS_SUCCESS on success, corresponding error code otherwise
2155
2156---------------------------------------------------------------------------*/
2157VOS_STATUS csrNeighborRoamNeighborLookupDOWNCallback (v_PVOID_t pAdapter, v_U8_t rssiNotification,
2158 v_PVOID_t pUserCtxt)
2159{
2160 tpAniSirGlobal pMac = PMAC_STRUCT( pUserCtxt );
2161 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2162 VOS_STATUS vosStatus = eHAL_STATUS_SUCCESS;
2163
2164 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Neighbor Lookup DOWN indication callback called with notification %d"), rssiNotification);
2165
2166 if(!csrIsConnStateConnectedInfra(pMac, pNeighborRoamInfo->csrSessionId))
2167 {
2168 smsLog(pMac, LOGW, "Ignoring the indication as we are not connected\n");
2169 return VOS_STATUS_SUCCESS;
2170 }
2171
2172 VOS_ASSERT(WLANTL_HO_THRESHOLD_DOWN == rssiNotification);
2173 vosStatus = csrNeighborRoamNeighborLookupDownEvent(pMac);
2174
2175 return vosStatus;
2176}
2177
2178#ifdef RSSI_HACK
2179extern int dumpCmdRSSI;
2180#endif
2181
2182/* ---------------------------------------------------------------------------
2183
2184 \fn csrNeighborRoamIndicateDisconnect
2185
2186 \brief This function is called by CSR as soon as the station disconnects from
2187 the AP. This function does the necessary cleanup of neighbor roam data
2188 structures. Neighbor roam state transitions to INIT state whenever this
2189 function is called except if the current state is REASSOCIATING
2190
2191 \param pMac - The handle returned by macOpen.
2192 sessionId - CSR session id that got disconnected
2193
2194 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2195
2196---------------------------------------------------------------------------*/
2197eHalStatus csrNeighborRoamIndicateDisconnect(tpAniSirGlobal pMac, tANI_U8 sessionId)
2198{
2199 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2200
2201 smsLog(pMac, LOGE, FL("Disconnect indication received with session id %d in state %d"), sessionId, pNeighborRoamInfo->neighborRoamState);
2202
2203#ifdef FEATURE_WLAN_CCX
2204 {
2205 tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId);
2206 if (pSession->connectedProfile.isCCXAssoc)
2207 {
2208 vos_mem_copy(&pSession->prevApSSID, &pSession->connectedProfile.SSID, sizeof(tSirMacSSid));
2209 vos_mem_copy(pSession->prevApBssid, pSession->connectedProfile.bssid, sizeof(tSirMacAddr));
2210 pSession->prevOpChannel = pSession->connectedProfile.operationChannel;
2211 pSession->isPrevApInfoValid = TRUE;
2212 pSession->roamTS1 = vos_timer_get_system_time();
2213
2214 }
2215 }
2216#endif
2217
2218#ifdef RSSI_HACK
2219 dumpCmdRSSI = -40;
2220#endif
2221 switch (pNeighborRoamInfo->neighborRoamState)
2222 {
2223 case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
2224 // Stop scan and neighbor refresh timers.
2225 // These are indeed not required when we are in reassociating
2226 // state.
2227 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2228 palTimerStop(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
2229 break;
2230
2231 case eCSR_NEIGHBOR_ROAM_STATE_INIT:
2232 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Ignoring disconnect event in INIT state"));
2233 csrNeighborRoamResetInitStateControlInfo(pMac);
2234 break;
2235
2236 default:
2237 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Received disconnect event in state %d"), pNeighborRoamInfo->neighborRoamState);
2238 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("Transitioning to INIT state"));
2239 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
2240 }
2241 return eHAL_STATUS_SUCCESS;
2242}
2243
2244/* ---------------------------------------------------------------------------
2245
2246 \fn csrNeighborRoamIndicateConnect
2247
2248 \brief This function is called by CSR as soon as the station connects to an AP.
2249 This initializes all the necessary data structures related to the
2250 associated AP and transitions the state to CONNECTED state
2251
2252 \param pMac - The handle returned by macOpen.
2253 sessionId - CSR session id that got connected
2254 vosStatus - connect status SUCCESS/FAILURE
2255
2256 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2257
2258---------------------------------------------------------------------------*/
2259eHalStatus csrNeighborRoamIndicateConnect(tpAniSirGlobal pMac, tANI_U8 sessionId, VOS_STATUS vosStatus)
2260{
2261 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2262 eHalStatus status = eHAL_STATUS_SUCCESS;
2263#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX)
2264 int init_ft_flag = FALSE;
2265#endif
2266
2267 smsLog(pMac, LOGE, FL("Connect indication received with session id %d in state %d"), sessionId, pNeighborRoamInfo->neighborRoamState);
2268
2269 switch (pNeighborRoamInfo->neighborRoamState)
2270 {
2271 case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
2272 if (VOS_STATUS_SUCCESS != vosStatus)
2273 {
2274 /* Just transition the state to INIT state. Rest of the clean up happens when we get next connect indication */
2275 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
2276 break;
2277 }
2278 /* Fall through if the status is SUCCESS */
2279 case eCSR_NEIGHBOR_ROAM_STATE_INIT:
2280 /* Reset all the data structures here */
2281 csrNeighborRoamResetInitStateControlInfo(pMac);
2282
2283 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CONNECTED)
2284
2285 pNeighborRoamInfo->csrSessionId = sessionId;
2286 vos_mem_copy(pNeighborRoamInfo->currAPbssid,
2287 pMac->roam.roamSession[sessionId].connectedProfile.bssid, sizeof(tCsrBssid));
2288 pNeighborRoamInfo->currAPoperationChannel = pMac->roam.roamSession[sessionId].connectedProfile.operationChannel;
2289 pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac;
2290 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = sessionId;
2291
2292#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX)
2293 /* Now we can clear the preauthDone that was saved as we are connected afresh */
2294 csrNeighborRoamFreeRoamableBSSList(pMac, &pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
2295#endif
2296
2297#ifdef WLAN_FEATURE_VOWIFI_11R
2298 // Based on the auth scheme tell if we are 11r
2299 if ( csrIsAuthType11r( pMac->roam.roamSession[sessionId].connectedProfile.AuthType ) )
2300 {
2301 if (pMac->roam.configParam.isFastTransitionEnabled)
2302 init_ft_flag = TRUE;
2303 pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_TRUE;
2304 }
2305 else
2306 pNeighborRoamInfo->is11rAssoc = eANI_BOOLEAN_FALSE;
2307 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("11rAssoc is = %d"), pNeighborRoamInfo->is11rAssoc);
2308#endif
2309
2310#ifdef FEATURE_WLAN_CCX
2311 // Based on the auth scheme tell if we are 11r
2312 if (pMac->roam.roamSession[sessionId].connectedProfile.isCCXAssoc)
2313 {
2314 if (pMac->roam.configParam.isFastTransitionEnabled)
2315 init_ft_flag = TRUE;
2316 pNeighborRoamInfo->isCCXAssoc = eANI_BOOLEAN_TRUE;
2317 }
2318 else
2319 pNeighborRoamInfo->isCCXAssoc = eANI_BOOLEAN_FALSE;
2320 NEIGHBOR_ROAM_DEBUG(pMac, LOGE, FL("isCCXAssoc is = %d"), pNeighborRoamInfo->isCCXAssoc);
2321 VOS_TRACE (VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
2322 "ccx=%d ft=%d\n", pNeighborRoamInfo->isCCXAssoc, init_ft_flag);
2323
2324#endif
2325
2326#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX)
2327 if ( init_ft_flag == TRUE )
2328 {
2329 /* Initialize all the data structures needed for the 11r FT Preauth */
2330 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.pMac = pMac;
2331 pNeighborRoamInfo->FTRoamInfo.preAuthRspWaitTimerInfo.sessionId = sessionId;
2332 pNeighborRoamInfo->FTRoamInfo.currentNeighborRptRetryNum = 0;
2333 csrNeighborRoamPurgePreauthFailedList(pMac);
2334
2335 NEIGHBOR_ROAM_DEBUG(pMac, LOG2, FL("Registering neighbor lookup DOWN event with TL, RSSI = %d"), pNeighborRoamInfo->currentNeighborLookupThreshold);
2336 /* Register Neighbor Lookup threshold callback with TL for DOWN event only */
2337 status = WLANTL_RegRSSIIndicationCB(pMac->roam.gVosContext, (v_S7_t)pNeighborRoamInfo->currentNeighborLookupThreshold * (-1),
2338 WLANTL_HO_THRESHOLD_DOWN,
2339 csrNeighborRoamNeighborLookupDOWNCallback,
2340 VOS_MODULE_ID_SME, pMac);
2341
2342 if(!VOS_IS_STATUS_SUCCESS( status))
2343 {
2344 //err msg
2345 smsLog(pMac, LOGW, FL(" Couldn't register csrNeighborRoamNeighborLookupDOWNCallback with TL: Status = %d\n"), status);
2346 }
2347 }
2348#endif
2349
2350
2351 break;
2352 default:
2353 smsLog(pMac, LOGE, FL("Connect event received in invalid state %d..Ignoring..."), pNeighborRoamInfo->neighborRoamState);
2354 break;
2355 }
2356 return status;
2357}
2358
2359
2360#ifdef WLAN_FEATURE_VOWIFI_11R
2361/* ---------------------------------------------------------------------------
2362
2363 \fn csrNeighborRoamPreAuthResponseWaitTimerHandler
2364
2365 \brief If this function is invoked, that means the preauthentication response
2366 is timed out from the PE. Preauth rsp handler is called with status as
2367 TIMEOUT
2368
2369 \param context - CSR Timer info which holds pMac and session ID
2370
2371 \return VOID
2372
2373---------------------------------------------------------------------------*/
2374void csrNeighborRoamPreAuthResponseWaitTimerHandler(void *context)
2375{
2376 tCsrTimerInfo *pTimerInfo = (tCsrTimerInfo *)context;
2377 tpAniSirGlobal pMac = (tpAniSirGlobal)pTimerInfo->pMac;
2378 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2379
2380 pNeighborRoamInfo->FTRoamInfo.preauthRspPending = eANI_BOOLEAN_FALSE;
2381
2382 csrNeighborRoamPreauthRspHandler(pMac, VOS_STATUS_E_TIMEOUT);
2383}
2384
2385/* ---------------------------------------------------------------------------
2386
2387 \fn csrNeighborRoamPurgePreauthFailedList
2388
2389 \brief This function purges all the MAC addresses in the pre-auth fail list
2390
2391 \param pMac - The handle returned by macOpen.
2392
2393 \return VOID
2394
2395---------------------------------------------------------------------------*/
2396void csrNeighborRoamPurgePreauthFailedList(tpAniSirGlobal pMac)
2397{
2398 tANI_U8 i;
2399
2400 for (i = 0; i < pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.numMACAddress; i++)
2401 {
2402 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.macAddress[i], sizeof(tSirMacAddr));
2403 }
2404 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthFailList.numMACAddress = 0;
2405
2406 return;
2407}
2408
2409/* ---------------------------------------------------------------------------
2410
2411 \fn csrNeighborRoamInit11rAssocInfo
2412
2413 \brief This function initializes 11r related neighbor roam data structures
2414
2415 \param pMac - The handle returned by macOpen.
2416
2417 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2418
2419---------------------------------------------------------------------------*/
2420eHalStatus csrNeighborRoamInit11rAssocInfo(tpAniSirGlobal pMac)
2421{
2422 eHalStatus status;
2423 tpCsr11rAssocNeighborInfo pFTRoamInfo = &pMac->roam.neighborRoamInfo.FTRoamInfo;
2424
2425 pMac->roam.neighborRoamInfo.is11rAssoc = eANI_BOOLEAN_FALSE;
2426 pMac->roam.neighborRoamInfo.cfgParams.maxNeighborRetries = pMac->roam.configParam.neighborRoamConfig.nMaxNeighborRetries;
2427 pFTRoamInfo->neighborReportTimeout = CSR_NEIGHBOR_ROAM_REPORT_QUERY_TIMEOUT;
2428 pFTRoamInfo->PEPreauthRespTimeout = CSR_NEIGHBOR_ROAM_PREAUTH_RSP_WAIT_MULTIPLIER * pMac->roam.neighborRoamInfo.cfgParams.neighborScanPeriod;
2429 pFTRoamInfo->neighborRptPending = eANI_BOOLEAN_FALSE;
2430 pFTRoamInfo->preauthRspPending = eANI_BOOLEAN_FALSE;
2431
2432 pFTRoamInfo->preAuthRspWaitTimerInfo.pMac = pMac;
2433 pFTRoamInfo->preAuthRspWaitTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
2434 status = palTimerAlloc(pMac->hHdd, &pFTRoamInfo->preAuthRspWaitTimer,
2435 csrNeighborRoamPreAuthResponseWaitTimerHandler, (void *)&pFTRoamInfo->preAuthRspWaitTimerInfo);
2436
2437 if (eHAL_STATUS_SUCCESS != status)
2438 {
2439 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
2440 return eHAL_STATUS_RESOURCES;
2441 }
2442
2443 pMac->roam.neighborRoamInfo.FTRoamInfo.currentNeighborRptRetryNum = 0;
2444 pMac->roam.neighborRoamInfo.FTRoamInfo.numBssFromNeighborReport = 0;
2445 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.neighboReportBssInfo,
2446 sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
2447
2448
2449 status = csrLLOpen(pMac->hHdd, &pFTRoamInfo->preAuthDoneList);
2450 if (eHAL_STATUS_SUCCESS != status)
2451 {
2452 smsLog(pMac, LOGE, FL("LL Open of preauth done AP List failed"));
2453 palTimerFree(pMac->hHdd, pFTRoamInfo->preAuthRspWaitTimer);
2454 return eHAL_STATUS_RESOURCES;
2455 }
2456 return status;
2457}
2458#endif /* WLAN_FEATURE_VOWIFI_11R */
2459
2460/* ---------------------------------------------------------------------------
2461
2462 \fn csrNeighborRoamInit
2463
2464 \brief This function initializes neighbor roam data structures
2465
2466 \param pMac - The handle returned by macOpen.
2467
2468 \return eHAL_STATUS_SUCCESS on success, corresponding error code otherwise
2469
2470---------------------------------------------------------------------------*/
2471eHalStatus csrNeighborRoamInit(tpAniSirGlobal pMac)
2472{
2473 eHalStatus status;
2474 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2475
2476 pNeighborRoamInfo->neighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED;
2477 pNeighborRoamInfo->prevNeighborRoamState = eCSR_NEIGHBOR_ROAM_STATE_CLOSED;
2478 pNeighborRoamInfo->csrSessionId = CSR_SESSION_ID_INVALID;
2479 pNeighborRoamInfo->cfgParams.maxChannelScanTime = pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime;
2480 pNeighborRoamInfo->cfgParams.minChannelScanTime = pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime;
2481 pNeighborRoamInfo->cfgParams.maxNeighborRetries = 0;
2482 pNeighborRoamInfo->cfgParams.neighborLookupThreshold = pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold;
2483 pNeighborRoamInfo->cfgParams.neighborReassocThreshold = pMac->roam.configParam.neighborRoamConfig.nNeighborReassocRssiThreshold;
2484 pNeighborRoamInfo->cfgParams.neighborScanPeriod = pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod;
2485 pNeighborRoamInfo->cfgParams.neighborResultsRefreshPeriod = pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod;
2486
2487 pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels =
2488 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels;
2489
2490 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList =
2491 vos_mem_malloc(pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels);
2492
2493 if (NULL == pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
2494 {
2495 smsLog(pMac, LOGE, FL("Memory Allocation for CFG Channel List failed"));
2496 return eHAL_STATUS_RESOURCES;
2497 }
2498
2499 /* Update the roam global structure from CFG */
2500 palCopyMemory(pMac->hHdd, pNeighborRoamInfo->cfgParams.channelInfo.ChannelList,
2501 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.channelList,
2502 pMac->roam.configParam.neighborRoamConfig.neighborScanChanList.numChannels);
2503
2504 vos_mem_set(pNeighborRoamInfo->currAPbssid, sizeof(tCsrBssid), 0);
2505 pNeighborRoamInfo->currentNeighborLookupThreshold = pMac->roam.neighborRoamInfo.cfgParams.neighborLookupThreshold;
2506 pNeighborRoamInfo->currentLookupIncrementMultiplier = 0;
2507 pNeighborRoamInfo->scanRspPending = eANI_BOOLEAN_FALSE;
2508
2509 pNeighborRoamInfo->neighborScanTimerInfo.pMac = pMac;
2510 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
2511 status = palTimerAlloc(pMac->hHdd, &pNeighborRoamInfo->neighborScanTimer,
2512 csrNeighborRoamNeighborScanTimerCallback, (void *)&pNeighborRoamInfo->neighborScanTimerInfo);
2513
2514 if (eHAL_STATUS_SUCCESS != status)
2515 {
2516 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
2517 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2518 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2519 return eHAL_STATUS_RESOURCES;
2520 }
2521
2522 status = palTimerAlloc(pMac->hHdd, &pNeighborRoamInfo->neighborResultsRefreshTimer,
2523 csrNeighborRoamResultsRefreshTimerCallback, (void *)&pNeighborRoamInfo->neighborScanTimerInfo);
2524
2525 if (eHAL_STATUS_SUCCESS != status)
2526 {
2527 smsLog(pMac, LOGE, FL("Response wait Timer allocation failed"));
2528 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
2529 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2530 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2531 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2532 return eHAL_STATUS_RESOURCES;
2533 }
2534
2535 status = csrLLOpen(pMac->hHdd, &pNeighborRoamInfo->roamableAPList);
2536 if (eHAL_STATUS_SUCCESS != status)
2537 {
2538 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
2539 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2540 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2541 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2542 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
2543 return eHAL_STATUS_RESOURCES;
2544 }
2545
2546 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
2547 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0;
2548 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2549 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
2550 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE;
2551
2552#ifdef WLAN_FEATURE_VOWIFI_11R
2553 status = csrNeighborRoamInit11rAssocInfo(pMac);
2554 if (eHAL_STATUS_SUCCESS != status)
2555 {
2556 smsLog(pMac, LOGE, FL("LL Open of roamable AP List failed"));
2557 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2558 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2559 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2560 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
2561 csrLLClose(&pNeighborRoamInfo->roamableAPList);
2562 return eHAL_STATUS_RESOURCES;
2563 }
2564#endif
2565 /* Initialize this with the current tick count */
2566 pNeighborRoamInfo->scanRequestTimeStamp = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
2567
2568 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
2569
2570 return eHAL_STATUS_SUCCESS;
2571}
2572
2573/* ---------------------------------------------------------------------------
2574
2575 \fn csrNeighborRoamClose
2576
2577 \brief This function closes/frees all the neighbor roam data structures
2578
2579 \param pMac - The handle returned by macOpen.
2580
2581 \return VOID
2582
2583---------------------------------------------------------------------------*/
2584void csrNeighborRoamClose(tpAniSirGlobal pMac)
2585{
2586 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2587
2588 if (eCSR_NEIGHBOR_ROAM_STATE_CLOSED == pNeighborRoamInfo->neighborRoamState)
2589 {
2590 smsLog(pMac, LOGE, FL("Neighbor Roam Algorithm Already Closed\n"));
2591 return;
2592 }
2593
2594 if (pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
2595 vos_mem_free(pNeighborRoamInfo->cfgParams.channelInfo.ChannelList);
2596
2597 pNeighborRoamInfo->cfgParams.channelInfo.ChannelList = NULL;
2598
2599 pNeighborRoamInfo->neighborScanTimerInfo.pMac = NULL;
2600 pNeighborRoamInfo->neighborScanTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
2601 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborScanTimer);
2602 palTimerFree(pMac->hHdd, pNeighborRoamInfo->neighborResultsRefreshTimer);
2603
2604 /* Should free up the nodes in the list before closing the double Linked list */
2605 csrNeighborRoamFreeRoamableBSSList(pMac, &pNeighborRoamInfo->roamableAPList);
2606 csrLLClose(&pNeighborRoamInfo->roamableAPList);
2607
2608 if (pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList)
2609 {
2610 vos_mem_free(pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList);
2611 }
2612
2613 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2614 pNeighborRoamInfo->roamChannelInfo.currentChanIndex = CSR_NEIGHBOR_ROAM_INVALID_CHANNEL_INDEX;
2615 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.numOfChannels = 0;
2616 pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo.ChannelList = NULL;
2617 pNeighborRoamInfo->roamChannelInfo.chanListScanInProgress = eANI_BOOLEAN_FALSE;
2618 pNeighborRoamInfo->roamChannelInfo.IAPPNeighborListReceived = eANI_BOOLEAN_FALSE;
2619
2620 /* Free the profile.. */
2621 csrReleaseProfile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile);
2622
2623#ifdef WLAN_FEATURE_VOWIFI_11R
2624 pMac->roam.neighborRoamInfo.FTRoamInfo.currentNeighborRptRetryNum = 0;
2625 palTimerFree(pMac->hHdd, pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimer);
2626 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimerInfo.pMac = NULL;
2627 pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthRspWaitTimerInfo.sessionId = CSR_SESSION_ID_INVALID;
2628 pMac->roam.neighborRoamInfo.FTRoamInfo.numBssFromNeighborReport = 0;
2629 vos_mem_zero(pMac->roam.neighborRoamInfo.FTRoamInfo.neighboReportBssInfo,
2630 sizeof(tCsrNeighborReportBssInfo) * MAX_BSS_IN_NEIGHBOR_RPT);
2631 csrNeighborRoamFreeRoamableBSSList(pMac, &pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
2632 csrLLClose(&pMac->roam.neighborRoamInfo.FTRoamInfo.preAuthDoneList);
2633#endif /* WLAN_FEATURE_VOWIFI_11R */
2634
2635 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_CLOSED)
2636
2637 return;
2638}
2639
2640/* ---------------------------------------------------------------------------
2641
2642 \fn csrNeighborRoamRequestHandoff
2643
2644 \brief This function triggers actual switching from one AP to the new AP.
2645 It issues disassociate with reason code as Handoff and CSR as a part of
2646 handling disassoc rsp, issues reassociate to the new AP
2647
2648 \param pMac - The handle returned by macOpen.
2649
2650 \return VOID
2651
2652---------------------------------------------------------------------------*/
2653void csrNeighborRoamRequestHandoff(tpAniSirGlobal pMac)
2654{
2655
2656 tCsrRoamInfo roamInfo;
2657 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2658 tANI_U32 sessionId = pNeighborRoamInfo->csrSessionId;
2659 tCsrNeighborRoamBSSInfo handoffNode;
2660 extern void csrRoamRoamingStateDisassocRspProcessor( tpAniSirGlobal pMac, tSirSmeDisassocRsp *pSmeDisassocRsp );
2661 tANI_U32 roamId = 0;
2662
2663 if (pMac->roam.neighborRoamInfo.neighborRoamState != eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE)
2664 {
2665 smsLog(pMac, LOGE, FL("Roam requested when Neighbor roam is in %d state"),
2666 pMac->roam.neighborRoamInfo.neighborRoamState);
2667 return;
2668 }
2669
2670 vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo));
2671 csrRoamCallCallback(pMac, pNeighborRoamInfo->csrSessionId, &roamInfo, roamId, eCSR_ROAM_FT_START,
2672 eSIR_SME_SUCCESS);
2673
2674 vos_mem_zero(&roamInfo, sizeof(tCsrRoamInfo));
2675 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING)
2676
2677 csrNeighborRoamGetHandoffAPInfo(pMac, &handoffNode);
2678 smsLog(pMac, LOGE, FL("HANDOFF CANDIDATE BSSID %02x:%02x:%02x:%02x:%02x:%02x"),
2679 handoffNode.pBssDescription->bssId[0],
2680 handoffNode.pBssDescription->bssId[1],
2681 handoffNode.pBssDescription->bssId[2],
2682 handoffNode.pBssDescription->bssId[3],
2683 handoffNode.pBssDescription->bssId[4],
2684 handoffNode.pBssDescription->bssId[5]);
2685
2686 /* Free the profile.. Just to make sure we dont leak memory here */
2687 csrReleaseProfile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile);
2688 /* Create the Handoff AP profile. Copy the currently connected profile and update only the BSSID and channel number
2689 This should happen before issuing disconnect */
2690 csrRoamCopyConnectedProfile(pMac, pNeighborRoamInfo->csrSessionId, &pNeighborRoamInfo->csrNeighborRoamProfile);
2691 vos_mem_copy(pNeighborRoamInfo->csrNeighborRoamProfile.BSSIDs.bssid, handoffNode.pBssDescription->bssId, sizeof(tSirMacAddr));
2692 pNeighborRoamInfo->csrNeighborRoamProfile.ChannelInfo.ChannelList[0] = handoffNode.pBssDescription->channelId;
2693
2694 NEIGHBOR_ROAM_DEBUG(pMac, LOGW, " csrRoamHandoffRequested: disassociating with current AP\n");
2695
2696 if(!HAL_STATUS_SUCCESS(csrRoamIssueDisassociateCmd(pMac, sessionId, eCSR_DISCONNECT_REASON_HANDOFF)))
2697 {
2698 smsLog(pMac, LOGW, "csrRoamHandoffRequested: fail to issue disassociate\n");
2699 return;
2700 }
2701
2702 //notify HDD for handoff, providing the BSSID too
2703 roamInfo.reasonCode = eCsrRoamReasonBetterAP;
2704
2705 vos_mem_copy(roamInfo.bssid,
2706 handoffNode.pBssDescription->bssId,
2707 sizeof( tCsrBssid ));
2708
2709 csrRoamCallCallback(pMac, sessionId, &roamInfo, 0, eCSR_ROAM_ROAMING_START, eCSR_ROAM_RESULT_NONE);
2710
2711
2712 return;
2713}
2714
2715/* ---------------------------------------------------------------------------
2716
2717 \fn csrNeighborRoamIsHandoffInProgress
2718
2719 \brief This function returns whether handoff is in progress or not based on
2720 the current neighbor roam state
2721
2722 \param pMac - The handle returned by macOpen.
2723 is11rReassoc - Return whether reassoc is of type 802.11r reassoc
2724
2725 \return eANI_BOOLEAN_TRUE if reassoc in progress, eANI_BOOLEAN_FALSE otherwise
2726
2727---------------------------------------------------------------------------*/
2728tANI_BOOLEAN csrNeighborRoamIsHandoffInProgress(tpAniSirGlobal pMac)
2729{
2730 if (eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING == pMac->roam.neighborRoamInfo.neighborRoamState)
2731 return eANI_BOOLEAN_TRUE;
2732
2733 return eANI_BOOLEAN_FALSE;
2734}
2735
2736#ifdef WLAN_FEATURE_VOWIFI_11R
2737/* ---------------------------------------------------------------------------
2738
2739 \fn csrNeighborRoamIs11rAssoc
2740
2741 \brief This function returns whether the current association is a 11r assoc or not
2742
2743 \param pMac - The handle returned by macOpen.
2744
2745 \return eANI_BOOLEAN_TRUE if current assoc is 11r, eANI_BOOLEAN_FALSE otherwise
2746
2747---------------------------------------------------------------------------*/
2748tANI_BOOLEAN csrNeighborRoamIs11rAssoc(tpAniSirGlobal pMac)
2749{
2750 return pMac->roam.neighborRoamInfo.is11rAssoc;
2751}
2752#endif /* WLAN_FEATURE_VOWIFI_11R */
2753
2754
2755/* ---------------------------------------------------------------------------
2756
2757 \fn csrNeighborRoamGetHandoffAPInfo
2758
2759 \brief This function returns the best possible AP for handoff. For 11R case, it
2760 returns the 1st entry from pre-auth done list. For non-11r case, it returns
2761 the 1st entry from roamable AP list
2762
2763 \param pMac - The handle returned by macOpen.
2764 pHandoffNode - AP node that is the handoff candidate returned
2765
2766 \return VOID
2767
2768---------------------------------------------------------------------------*/
2769void csrNeighborRoamGetHandoffAPInfo(tpAniSirGlobal pMac, tpCsrNeighborRoamBSSInfo pHandoffNode)
2770{
2771 tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
2772 tpCsrNeighborRoamBSSInfo pBssNode;
2773
2774 VOS_ASSERT(NULL != pHandoffNode);
2775
2776#ifdef WLAN_FEATURE_VOWIFI_11R
2777 if (pNeighborRoamInfo->is11rAssoc)
2778 {
2779 /* Always the BSS info in the head is the handoff candidate */
2780 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL);
2781 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList));
2782 }
2783 else
2784#endif
2785#ifdef FEATURE_WLAN_CCX
2786 if (pNeighborRoamInfo->isCCXAssoc)
2787 {
2788 /* Always the BSS info in the head is the handoff candidate */
2789 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->FTRoamInfo.preAuthDoneList, NULL);
2790 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList));
2791 }
2792 else
2793#endif
2794 {
2795 pBssNode = csrNeighborRoamGetRoamableAPListNextEntry(pMac, &pNeighborRoamInfo->roamableAPList, NULL);
2796 NEIGHBOR_ROAM_DEBUG(pMac, LOG1, FL("Number of Handoff candidates = %d"), csrLLCount(&pNeighborRoamInfo->roamableAPList));
2797 }
2798 vos_mem_copy(pHandoffNode, pBssNode, sizeof(tCsrNeighborRoamBSSInfo));
2799
2800 return;
2801}
2802
2803/* ---------------------------------------------------------------------------
2804 \brief This function returns TRUE if preauth is completed
2805
2806 \param pMac - The handle returned by macOpen.
2807
2808 \return boolean
2809
2810---------------------------------------------------------------------------*/
2811tANI_BOOLEAN csrNeighborRoamStatePreauthDone(tpAniSirGlobal pMac)
2812{
2813 return (pMac->roam.neighborRoamInfo.neighborRoamState ==
2814 eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE);
2815}
2816
2817/* ---------------------------------------------------------------------------
2818 \brief In the event that we are associated with AP1 and we have
2819 completed pre auth with AP2. Then we receive a deauth/disassoc from
2820 AP1.
2821 At this point neighbor roam is in pre auth done state, pre auth timer
2822 is running. We now handle this case by stopping timer and clearing
2823 the pre-auth state. We basically clear up and just go to disconnected
2824 state.
2825
2826 \param pMac - The handle returned by macOpen.
2827
2828 \return boolean
2829---------------------------------------------------------------------------*/
2830void csrNeighborRoamTranistionPreauthDoneToDisconnected(tpAniSirGlobal pMac)
2831{
2832 if (pMac->roam.neighborRoamInfo.neighborRoamState !=
2833 eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE) return;
2834
2835 // Stop timer
2836 palTimerStop(pMac->hHdd, pMac->ft.ftSmeContext.preAuthReassocIntvlTimer);
2837
2838 // Transition to init state
2839 CSR_NEIGHBOR_ROAM_STATE_TRANSITION(eCSR_NEIGHBOR_ROAM_STATE_INIT)
2840}
2841
2842#endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */