blob: 3115e2a5c12efa15cee55ac8d008f9892c221479 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08002 * Copyright (c) 2012-2013, The Linux Foundation. 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/*
Jeff Johnson32d95a32012-09-10 13:15:23 -070022 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070023 *
24 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
25 *
26 *
27 * Permission to use, copy, modify, and/or distribute this software for
28 * any purpose with or without fee is hereby granted, provided that the
29 * above copyright notice and this permission notice appear in all
30 * copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
33 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
35 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
38 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39 * PERFORMANCE OF THIS SOFTWARE.
40 */
41
42/*
43 * */
44/**=========================================================================
45
46 \file sme_Rrm.c
47
48 \brief implementation for SME RRM APIs
49
50 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
51
52 Qualcomm Confidential and Proprietary.
53
54 ========================================================================*/
55
56/* $Header$ */
57
58#if defined WLAN_FEATURE_VOWIFI
59/*--------------------------------------------------------------------------
60 Include Files
61 ------------------------------------------------------------------------*/
62#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
63#include "halInternal.h"
64#endif
65#include "aniGlobal.h"
66#include "smeInside.h"
67#include "sme_Api.h"
68#include "smsDebug.h"
69#include "cfgApi.h"
70
71#ifdef FEATURE_WLAN_DIAG_SUPPORT
72#include "vos_diag_core_event.h"
73#include "vos_diag_core_log.h"
74#endif /* FEATURE_WLAN_DIAG_SUPPORT */
75
76#include "csrInsideApi.h"
77
78#include "rrmGlobal.h"
79
80#ifdef FEATURE_WLAN_CCX
81#include "csrCcx.h"
82#endif
83
84/* Roam score for a neighbor AP will be calculated based on the below definitions.
85 The calculated roam score will be used to select the roamable candidate from neighbor AP list */
86#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_REACHABILITY 0 /* When we support 11r over the DS, this should have a non-zero value */
87#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_SECURITY 10
88#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_KEY_SCOPE 20
89#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_SPECTRUM_MGMT 0 /* Not used */
90#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_QOS 5
91#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_APSD 3
92#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_RRM 8
93#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_DELAYED_BA 0 /* We dont support delayed BA */
94#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_IMMEDIATE_BA 3
95#define RRM_ROAM_SCORE_NEIGHBOR_REPORT_MOBILITY_DOMAIN 30
96
97#ifdef FEATURE_WLAN_CCX
98#define RRM_ROAM_SCORE_NEIGHBOR_IAPP_LIST 30
99#endif
100/**---------------------------------------------------------------------------
101
102 \brief rrmLLPurgeNeighborCache() -
103 This function purges all the entries in the neighbor cache and frees up all the internal nodes
104
105 \param - pMac - Pointer to the Hal Handle.
106 - pList - Pointer the List that should be purged.
107 \return - void
108
109 --------------------------------------------------------------------------*/
110static void rrmLLPurgeNeighborCache(tpAniSirGlobal pMac, tDblLinkList *pList)
111{
112 tListElem *pEntry;
113 tRrmNeighborReportDesc *pNeighborReportDesc;
114
115 csrLLLock(pList);
116
117 while((pEntry = csrLLRemoveHead(pList, LL_ACCESS_NOLOCK)) != NULL)
118 {
119 pNeighborReportDesc = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List );
120 vos_mem_free(pNeighborReportDesc->pNeighborBssDescription);
121 vos_mem_free(pNeighborReportDesc);
122 }
123
124 csrLLUnlock(pList);
125
126 return;
127}
128
129/**---------------------------------------------------------------------------
130
131 \brief rrmIndicateNeighborReportResult() -
132 This function calls the callback register by the caller while requesting for
133 neighbor report. This function gets invoked if a neighbor report is received from an AP
134 or neighbor response wait timer expires.
135
136 \param - pMac - Pointer to the Hal Handle.
137 - vosStatus - VOS_STATUS_SUCCESS/VOS_STATUS_FAILURE based on whether a valid report is
138 received or neighbor timer expired
139 \return - void
140
141 --------------------------------------------------------------------------*/
142void rrmIndicateNeighborReportResult(tpAniSirGlobal pMac, VOS_STATUS vosStatus)
143{
144 NeighborReportRspCallback callback;
145 void *callbackContext;
146
147 /* Reset the neighbor response pending status */
148 pMac->rrm.rrmSmeContext.neighborReqControlInfo.isNeighborRspPending = eANI_BOOLEAN_FALSE;
149
150 /* Stop the timer if it is already running. The timer should be running only in the SUCCESS case. */
151 if (VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState(&pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspWaitTimer))
152 {
153 VOS_ASSERT(VOS_STATUS_SUCCESS == vosStatus);
154 vos_timer_stop(&pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspWaitTimer);
155 }
156 callback = pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallback;
157 callbackContext = pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallbackContext;
158
159 /* Reset the callback and the callback context before calling the callback. It is very likely that there may be a registration in
160 callback itself. */
161 pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallback = NULL;
162 pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallbackContext = NULL;
163
164 /* Call the callback with the status received from caller */
165 if (callback)
166 callback(callbackContext, vosStatus);
167#ifdef FEATURE_WLAN_CCX
168 // We came here with IAPP AP List
169 // Make sure we inform CSR of the neighbor list
170 // for CCX Associations. First clear the cache.
171 else
172 if (csrNeighborRoamIsCCXAssoc(pMac))
173 {
174 ProcessIAPPNeighborAPList(pMac);
175 }
176#endif
177
178 return;
179
180}
181
182/**---------------------------------------------------------------------------
183
184 \brief sme_RrmBeaconReportXmitInd() -
185
186 Create and send the beacon report Xmit ind message to PE.
187
188 \param - pMac - Pointer to the Hal Handle.
189 - pResult - scan result.
190 - measurementDone - flag to indicate that the measurement is done.
191 \return - 0 for success, non zero for failure
192
193 --------------------------------------------------------------------------*/
194static eHalStatus sme_RrmSendBeaconReportXmitInd( tpAniSirGlobal pMac, tCsrScanResultInfo **pResultArr, tANI_U8 measurementDone )
195{
196 tpSirBssDescription pBssDesc = NULL;
197 tpSirBeaconReportXmitInd pBeaconRep;
198 tANI_U16 length, ie_len;
199 tANI_U8 bssCounter=0, msgCounter=0;
200 tCsrScanResultInfo *pCurResult=NULL;
201 eHalStatus status = eHAL_STATUS_FAILURE;
202 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
203
204
205#if defined WLAN_VOWIFI_DEBUG
206 smsLog( pMac, LOGE, "Beacon report xmit Ind to PE\n");
207#endif
208
209 if( NULL == pResultArr && !measurementDone )
210 {
211 smsLog( pMac, LOGE, "Beacon report xmit Ind to PE Failed\n");
212 return eHAL_STATUS_FAILURE;
213 }
214
215 if (pResultArr)
216 pCurResult=pResultArr[bssCounter];
217
218 do
219 {
220 length = sizeof(tSirBeaconReportXmitInd);
221 pBeaconRep = vos_mem_malloc ( length );
222 if ( NULL == pBeaconRep )
223 {
224 smsLog( pMac, LOGP, "Unable to allocate memory for beacon report");
225 return eHAL_STATUS_FAILED_ALLOC;
226 }
227 vos_mem_zero( pBeaconRep, length );
228#if defined WLAN_VOWIFI_DEBUG
229 smsLog( pMac, LOGE, FL("Allocated memory for pBeaconRep\n"));
230#endif
231 pBeaconRep->messageType = eWNI_SME_BEACON_REPORT_RESP_XMIT_IND;
232 pBeaconRep->length = length;
233 pBeaconRep->uDialogToken = pSmeRrmContext->token;
234 pBeaconRep->duration = pSmeRrmContext->duration;
235 pBeaconRep->regClass = pSmeRrmContext->regClass;
236 vos_mem_copy( pBeaconRep->bssId, pSmeRrmContext->sessionBssId, sizeof(tSirMacAddr) );
237
238 msgCounter=0;
239 while (pCurResult)
240 {
241 pBssDesc = &pCurResult->BssDescriptor;
242 ie_len = GET_IE_LEN_IN_BSS( pBssDesc->length );
243 pBeaconRep->pBssDescription[msgCounter] = vos_mem_malloc ( ie_len+sizeof(tSirBssDescription) );
244 vos_mem_copy( pBeaconRep->pBssDescription[msgCounter], pBssDesc, sizeof(tSirBssDescription) );
245 vos_mem_copy( &pBeaconRep->pBssDescription[msgCounter]->ieFields[0], pBssDesc->ieFields, ie_len );
246
247 pBeaconRep->numBssDesc++;
248
249 if (++msgCounter >= SIR_BCN_REPORT_MAX_BSS_DESC)
250 break;
251
252 if (csrRoamIs11rAssoc(pMac)) {
253 break;
254 }
255
256 pCurResult = pResultArr[msgCounter];
257 }
258
259 bssCounter+=msgCounter;
260 if (!pResultArr || !pCurResult || (bssCounter>=SIR_BCN_REPORT_MAX_BSS_DESC))
261 pCurResult = NULL;
262 else
263 pCurResult = pResultArr[bssCounter];
264
265 pBeaconRep->fMeasureDone = (pCurResult)?false:measurementDone;
266
267 status = palSendMBMessage(pMac->hHdd, pBeaconRep);
268
269 smsLog( pMac, LOGW, "SME Sent BcnRepXmit to PE numBss %d\n", pBeaconRep->numBssDesc);
270
271 } while (pCurResult);
272
273 return status;
274}
275
276/**---------------------------------------------------------------------------
277
278 \brief sme_RrmSendScanRequest() -
279
280 This function is called to get the scan result from CSR and send the beacon report
281 xmit ind message to PE.
282
283 \param - pMac - Pointer to the Hal Handle.
284 - num_chan - number of channels.
285 - channel list - list of channels to fetch the result from.
286 - measurementDone - flag to indicate that the measurement is done.
287 \return - 0 for success, non zero for failure
288
289 --------------------------------------------------------------------------*/
290static eHalStatus sme_RrmSendScanResult( tpAniSirGlobal pMac, tANI_U8 num_chan, tANI_U8* chanList, tANI_U8 measurementDone )
291{
292 tCsrScanResultFilter filter;
293 tScanResultHandle pResult;
294 tCsrScanResultInfo *pScanResult, *pNextResult;
295 tCsrScanResultInfo *pScanResultsArr[SIR_BCN_REPORT_MAX_BSS_DESC];
296 eHalStatus status;
297 tANI_U8 counter=0;
298 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
299 tANI_U32 sessionId;
300
301#if defined WLAN_VOWIFI_DEBUG
302 smsLog( pMac, LOGE, "Send scan result to PE \n");
303#endif
304
305 vos_mem_zero( &filter, sizeof(filter) );
306 vos_mem_zero( pScanResultsArr, sizeof(pNextResult)*SIR_BCN_REPORT_MAX_BSS_DESC );
307
308 filter.BSSIDs.numOfBSSIDs = 1;
309 filter.BSSIDs.bssid = &pSmeRrmContext->bssId;
310
311 if( pSmeRrmContext->ssId.length )
312 {
313 filter.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo));
314 if( filter.SSIDs.SSIDList == NULL )
315 {
316 smsLog( pMac, LOGP, FL("vos_mem_malloc failed:") );
317 return eHAL_STATUS_FAILURE;
318 }
319#if defined WLAN_VOWIFI_DEBUG
320 smsLog( pMac, LOGE, FL("Allocated memory for SSIDList\n"));
321#endif
322 vos_mem_zero( filter.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) );
323
324 filter.SSIDs.SSIDList->SSID.length = pSmeRrmContext->ssId.length;
325 vos_mem_copy(filter.SSIDs.SSIDList->SSID.ssId, pSmeRrmContext->ssId.ssId, pSmeRrmContext->ssId.length);
326 filter.SSIDs.numOfSSIDs = 1;
327 }
328 else
329 {
330 filter.SSIDs.numOfSSIDs = 0;
331 }
332
333 filter.ChannelInfo.numOfChannels = num_chan;
334 filter.ChannelInfo.ChannelList = chanList;
335
336 filter.fMeasurement = TRUE;
337
338 csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid*)pSmeRrmContext->sessionBssId, &sessionId );
339 status = sme_ScanGetResult(pMac, (tANI_U8)sessionId, &filter, &pResult);
340
341 if( filter.SSIDs.SSIDList )
342 {
343 //Free the memory allocated for SSIDList.
344 vos_mem_free( filter.SSIDs.SSIDList );
345#if defined WLAN_VOWIFI_DEBUG
346 smsLog( pMac, LOGE, FL("Free memory for SSIDList\n") );
347#endif
348 }
349
350 if (NULL == pResult)
351 {
352 // no scan results
353 //
354 // Spec. doesnt say anything about such condition.
355 // Since section 7.4.6.2 (IEEE802.11k-2008) says-rrm report frame should contain
356 // one or more report IEs. It probably means dont send any respose if no matching
357 // BSS found. Moreover, there is no flag or field in measurement report IE(7.3.2.22)
358 // OR beacon report IE(7.3.2.22.6) that can be set to indicate no BSS found on a given channel.
359 //
360 // If we finished measurement on all the channels, we still need to
361 // send a xmit indication with moreToFollow set to MEASURMENT_DONE
362 // so that PE can clean any context allocated.
363 if( measurementDone )
364 status = sme_RrmSendBeaconReportXmitInd( pMac, NULL, measurementDone );
365 return status;
366 }
367
368 pScanResult = sme_ScanResultGetFirst(pMac, pResult);
369
370 if( NULL == pScanResult && measurementDone )
371 status = sme_RrmSendBeaconReportXmitInd( pMac, NULL, measurementDone );
372
373 counter=0;
374 while (pScanResult)
375 {
376 pNextResult = sme_ScanResultGetNext(pMac, pResult);
377 pScanResultsArr[counter++] = pScanResult;
378 pScanResult = pNextResult; //sme_ScanResultGetNext(hHal, pResult);
379 if (counter >= SIR_BCN_REPORT_MAX_BSS_DESC)
380 break;
381 }
382
383 if (counter)
384 status = sme_RrmSendBeaconReportXmitInd( pMac, pScanResultsArr, measurementDone);
385
386 sme_ScanResultPurge(pMac, pResult);
387
388 return status;
389}
390/**---------------------------------------------------------------------------
391
392 \brief sme_RrmScanRequestCallback() -
393
394 The sme module calls this callback function once it finish the scan request
395 and this function send the beacon report xmit to PE and starts a timer of
396 random interval to issue next request.
397
398 \param - halHandle - Pointer to the Hal Handle.
399 - pContext - Pointer to the data context.
400 - scanId - Scan ID.
401 - status - CSR Status.
402 \return - 0 for success, non zero for failure
403
404 --------------------------------------------------------------------------*/
405
406static eHalStatus sme_RrmScanRequestCallback(tHalHandle halHandle, void *pContext,
407 tANI_U32 scanId, eCsrScanStatus status)
408{
409
410 tANI_U16 interval;
411 tpAniSirGlobal pMac = (tpAniSirGlobal) halHandle;
412 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
413 tANI_U32 time_tick;
414
415
416
417#if defined WLAN_VOWIFI_DEBUG
418 smsLog( pMac, LOGE, "Scan Request callback \n");
419#endif
420 //if any more channels are pending, start a timer of a random value within randomization interval.
421 //
422 //
423 if( (pSmeRrmContext->currentIndex + 1) < pSmeRrmContext->channelList.numOfChannels )
424 {
425 sme_RrmSendScanResult( pMac, 1, &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex], false );
426
427 pSmeRrmContext->currentIndex++; //Advance the current index.
428 //start the timer to issue next request.
429 //From timer tick get a random number within 10ms and max randmization interval.
430 time_tick = vos_timer_get_system_ticks();
431 interval = time_tick % (pSmeRrmContext->randnIntvl - 10 + 1) + 10;
432
433#if defined WLAN_VOWIFI_DEBUG
434 smsLog( pMac, LOGE, "Set timer for interval %d \n", interval);
435#endif
436 vos_timer_start( &pSmeRrmContext->IterMeasTimer, interval );
437
438 }
439 else
440 {
441 //Done with the measurement. Clean up all context and send a message to PE with measurement done flag set.
442 sme_RrmSendScanResult( pMac, 1, &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex], true );
443 vos_mem_free( pSmeRrmContext->channelList.ChannelList );
444#if defined WLAN_VOWIFI_DEBUG
445 smsLog( pMac, LOGE, FL("Free memory for ChannelList\n") );
446#endif
447 }
448
449 return eHAL_STATUS_SUCCESS;
450}
451
452/*--------------------------------------------------------------------------
453 \brief sme_RrmIssueScanReq() - This is called to send a scan request as part
454 of beacon report request .
455
456 \param
457
458 \return eHAL_STATUS_SUCCESS - Validation is successful.
459
460 \sa
461
462 --------------------------------------------------------------------------*/
463eHalStatus sme_RrmIssueScanReq( tpAniSirGlobal pMac )
464{
465 //Issue scan request.
466 tCsrScanRequest scanRequest;
467 v_U32_t scanId = 0;
468 eHalStatus status = eHAL_STATUS_SUCCESS;
469 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
470 tANI_U32 sessionId;
471
472#if defined WLAN_VOWIFI_DEBUG
473 smsLog( pMac, LOGE, "Issue scan request \n" );
474#endif
475
476 vos_mem_zero( &scanRequest, sizeof(scanRequest));
477
478 /* set scanType, active or passive */
479
480 scanRequest.scanType = pSmeRrmContext->measMode;
481
482 vos_mem_copy(scanRequest.bssid,
483 pSmeRrmContext->bssId, sizeof(scanRequest.bssid) );
484
485 if( pSmeRrmContext->ssId.length )
486 {
487 scanRequest.SSIDs.numOfSSIDs = 1;
488 scanRequest.SSIDs.SSIDList =( tCsrSSIDInfo *)vos_mem_malloc(sizeof(tCsrSSIDInfo));
489 if( scanRequest.SSIDs.SSIDList == NULL )
490 {
491 smsLog( pMac, LOGP, FL("vos_mem_malloc failed:") );
492 return eHAL_STATUS_FAILURE;
493 }
494#if defined WLAN_VOWIFI_DEBUG
495 smsLog( pMac, LOGE, FL("Allocated memory for pSSIDList\n"));
496#endif
497 vos_mem_zero( scanRequest.SSIDs.SSIDList, sizeof(tCsrSSIDInfo) );
498 scanRequest.SSIDs.SSIDList->SSID.length = pSmeRrmContext->ssId.length;
499 vos_mem_copy(scanRequest.SSIDs.SSIDList->SSID.ssId, pSmeRrmContext->ssId.ssId, pSmeRrmContext->ssId.length);
500 }
501
502 /* set min and max channel time */
503 scanRequest.minChnTime = 0; //pSmeRrmContext->duration; Dont use min timeout.
504 scanRequest.maxChnTime = pSmeRrmContext->duration;
505#if defined WLAN_VOWIFI_DEBUG
506 smsLog( pMac, LOGE, "For Duration %d \n", pSmeRrmContext->duration );
507#endif
508
509 /* set BSSType to default type */
510 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
511
512 /*Scan all the channels */
513 scanRequest.ChannelInfo.numOfChannels = 1;
514
515 scanRequest.ChannelInfo.ChannelList = &pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex];
516#if defined WLAN_VOWIFI_DEBUG
517 smsLog( pMac, LOGE, "On channel %d \n", pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->currentIndex] );
518#endif
519
520 /* set requestType to full scan */
521 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
522
523 csrRoamGetSessionIdFromBSSID( pMac, (tCsrBssid*)pSmeRrmContext->sessionBssId, &sessionId );
524 status = sme_ScanRequest( pMac, (tANI_U8)sessionId, &scanRequest, &scanId, &sme_RrmScanRequestCallback, NULL );
525
526 if ( pSmeRrmContext->ssId.length )
527 {
528 vos_mem_free(scanRequest.SSIDs.SSIDList);
529#if defined WLAN_VOWIFI_DEBUG
530 smsLog( pMac, LOGE, FL("Free memory for SSIDList\n"));
531#endif
532 }
533
534 return status;
535}
536
537/*--------------------------------------------------------------------------
538 \brief sme_RrmProcessBeaconReportReqInd() - This is called to process the Beacon
539 report request from peer AP forwarded through PE .
540
541 \param pMsgBuf - a pointer to a buffer that maps to various structures base
542 on the message type.
543 The beginning of the buffer can always map to tSirSmeRsp.
544
545 \return eHAL_STATUS_SUCCESS - Validation is successful.
546
547 \sa
548
549 --------------------------------------------------------------------------*/
550void sme_RrmProcessBeaconReportReqInd(tpAniSirGlobal pMac, void *pMsgBuf)
551{
552 tpSirBeaconReportReqInd pBeaconReq = (tpSirBeaconReportReqInd) pMsgBuf;
553 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
554 tANI_U32 len,i;
555
556#if defined WLAN_VOWIFI_DEBUG
557 smsLog( pMac, LOGE, "Received Beacon report request ind Channel = %d\n", pBeaconReq->channelInfo.channelNum );
558#endif
559 //section 11.10.8.1 (IEEE Std 802.11k-2008)
560 //channel 0 and 255 has special meaning.
561 if( (pBeaconReq->channelInfo.channelNum == 0) ||
562 ((pBeaconReq->channelInfo.channelNum == 255) && (pBeaconReq->channelList.numChannels == 0) ) )
563 {
564 //Add all the channel in the regulatory domain.
565 wlan_cfgGetStrLen( pMac, WNI_CFG_VALID_CHANNEL_LIST, &len );
566 pSmeRrmContext->channelList.ChannelList = vos_mem_malloc( len );
567 if( pSmeRrmContext->channelList.ChannelList == NULL )
568 {
569 smsLog( pMac, LOGP, FL("vos_mem_malloc failed:") );
570 return;
571 }
572#if defined WLAN_VOWIFI_DEBUG
573 smsLog( pMac, LOGE, FL("Allocated memory for ChannelList\n") );
574#endif
575 csrGetCfgValidChannels( pMac, pSmeRrmContext->channelList.ChannelList, &len );
576 pSmeRrmContext->channelList.numOfChannels = (tANI_U8)len;
577#if defined WLAN_VOWIFI_DEBUG
578 smsLog( pMac, LOGE, "channel == 0 perfoming on all channels \n");
579#endif
580 }
581 else
582 {
583 len = 0;
584 pSmeRrmContext->channelList.numOfChannels = 0;
585
586 //If valid channel is present. We firt Measure on the given channel. and
587 //if there are additional channels present in APchannelreport, measure on these also.
588 if ( pBeaconReq->channelInfo.channelNum != 255 )
589 len = 1;
590#if defined WLAN_VOWIFI_DEBUG
591 else
592 smsLog( pMac, LOGE, "channel == 255 \n");
593#endif
594
595 len += pBeaconReq->channelList.numChannels;
596
597 pSmeRrmContext->channelList.ChannelList = vos_mem_malloc( len );
598 if( pSmeRrmContext->channelList.ChannelList == NULL )
599 {
600 smsLog( pMac, LOGP, FL("vos_mem_malloc failed") );
601 return;
602 }
603#if defined WLAN_VOWIFI_DEBUG
604 smsLog( pMac, LOGE, FL("Allocated memory for ChannelList\n") );
605#endif
606
607 if ( pBeaconReq->channelInfo.channelNum != 255 )
608 {
609#if defined WLAN_VOWIFI_DEBUG
610 smsLog( pMac, LOGE, "channel == %d \n", pBeaconReq->channelInfo.channelNum );
611#endif
612 if(csrRoamIsChannelValid( pMac, pBeaconReq->channelInfo.channelNum ))
613 pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->channelList.numOfChannels++] = pBeaconReq->channelInfo.channelNum;
614#if defined WLAN_VOWIFI_DEBUG
615 else
616 smsLog( pMac, LOGE, "is Invalid channel, Ignoring this channel\n" );
617#endif
618 }
619
620 for ( i = 0 ; i < pBeaconReq->channelList.numChannels; i++ )
621 {
622 if(csrRoamIsChannelValid( pMac, pBeaconReq->channelList.channelNumber[i] ))
623 {
624 pSmeRrmContext->channelList.ChannelList[pSmeRrmContext->channelList.numOfChannels] = pBeaconReq->channelList.channelNumber[i];
625 pSmeRrmContext->channelList.numOfChannels++;
626 }
627 }
628 }
629
630 //Copy session bssid
631 vos_mem_copy( pSmeRrmContext->sessionBssId, pBeaconReq->bssId, sizeof(tSirMacAddr) );
632
633 //copy measurement bssid
634 vos_mem_copy( pSmeRrmContext->bssId, pBeaconReq->macaddrBssid, sizeof(tSirMacAddr) );
635
636 //Copy ssid
637 vos_mem_copy( &pSmeRrmContext->ssId, &pBeaconReq->ssId, sizeof(tAniSSID) );
638
639 pSmeRrmContext->token = pBeaconReq->uDialogToken;
640 pSmeRrmContext->regClass = pBeaconReq->channelInfo.regulatoryClass;
641
642 switch( pBeaconReq->fMeasurementtype )
643 {
644 case 0: //Passive
645 case 1: //Active
646 pSmeRrmContext->measMode = pBeaconReq->fMeasurementtype? eSIR_ACTIVE_SCAN : eSIR_PASSIVE_SCAN ;
647 pSmeRrmContext->duration = pBeaconReq->measurementDuration;
648 pSmeRrmContext->randnIntvl = VOS_MAX( pBeaconReq->randomizationInterval, pSmeRrmContext->rrmConfig.maxRandnInterval );
649 pSmeRrmContext->currentIndex = 0;
650#if defined WLAN_VOWIFI_DEBUG
651 smsLog( pMac, LOGE, "Send beacon report after scan \n" );
652#endif
653 sme_RrmIssueScanReq( pMac );
654 break;
655 case 2: //Table
656 //Get the current scan results for the given channel and send it.
657#if defined WLAN_VOWIFI_DEBUG
658 smsLog( pMac, LOGE, "Send beacon report from table \n" );
659#endif
660 sme_RrmSendScanResult( pMac, pSmeRrmContext->channelList.numOfChannels, pSmeRrmContext->channelList.ChannelList, true );
661 vos_mem_free( pSmeRrmContext->channelList.ChannelList );
662#if defined WLAN_VOWIFI_DEBUG
663 smsLog( pMac, LOGE, FL("Free memory for ChannelList\n") );
664#endif
665 break;
666 default:
667#if defined WLAN_VOWIFI_DEBUG
668 smsLog( pMac, LOGE, "Unknown beacon report request mode\n");
669#endif
670 /* Indicate measurement completion to PE */
671 /* If this is not done, pCurrentReq pointer will not be freed and
672 PE will not handle subsequent Beacon requests */
673 sme_RrmSendBeaconReportXmitInd(pMac, NULL, true);
674 break;
675
676 }
677
678 return;
679}
680
681/*--------------------------------------------------------------------------
682 \brief sme_RrmNeighborReportRequest() - This is API can be used to trigger a
683 Neighbor report from the peer.
684
685 \param sessionId - session identifier on which the request should be made.
686 \param pNeighborReq - a pointer to a neighbor report request.
687
688 \return eHAL_STATUS_SUCCESS - Validation is successful.
689
690 \sa
691
692 --------------------------------------------------------------------------*/
693VOS_STATUS sme_RrmNeighborReportRequest(tpAniSirGlobal pMac, tANI_U8 sessionId,
694 tpRrmNeighborReq pNeighborReq, tpRrmNeighborRspCallbackInfo callbackInfo)
695{
696 eHalStatus status = eHAL_STATUS_SUCCESS;
697 tpSirNeighborReportReqInd pMsg;
698 tCsrRoamSession *pSession;
699
700#if defined WLAN_VOWIFI_DEBUG
701 smsLog( pMac, LOGE, FL("Request to send Neighbor report request received \n"));
702#endif
703 if( !CSR_IS_SESSION_VALID( pMac, sessionId ) )
704 {
705 smsLog( pMac, LOGE, FL("Invalid session %d\n"), sessionId );
706 return VOS_STATUS_E_INVAL;
707 }
708 pSession = CSR_GET_SESSION( pMac, sessionId );
709
710 /* If already a report is pending, return failure */
711 if (eANI_BOOLEAN_TRUE == pMac->rrm.rrmSmeContext.neighborReqControlInfo.isNeighborRspPending)
712 {
713 smsLog( pMac, LOGE, FL("Neighbor request already pending.. Not allowed"));
714 return VOS_STATUS_E_AGAIN;
715 }
716
717 pMsg = vos_mem_malloc ( sizeof(tSirNeighborReportReqInd) );
718 if ( NULL == pMsg )
719 {
720 smsLog( pMac, LOGE, "Unable to allocate memory for Neighbor request");
721 return VOS_STATUS_E_NOMEM;
722 }
723
724
725 vos_mem_zero( pMsg, sizeof(tSirNeighborReportReqInd) );
726#if defined WLAN_VOWIFI_DEBUG
727 smsLog( pMac, LOGE, FL(" Allocated memory for Neighbor request\n") );
728#endif
729
730 rrmLLPurgeNeighborCache(pMac, &pMac->rrm.rrmSmeContext.neighborReportCache);
731
732#if defined WLAN_VOWIFI_DEBUG
733 smsLog( pMac, LOGE, FL("Purged the neighbor cache before sending Neighbor request: Status = %d\n"), status );
734#endif
735
736 pMsg->messageType = eWNI_SME_NEIGHBOR_REPORT_REQ_IND;
737 pMsg->length = sizeof( tSirNeighborReportReqInd );
738 vos_mem_copy( &pMsg->bssId, &pSession->connectedProfile.bssid, sizeof(tSirMacAddr) );
739 pMsg->noSSID = pNeighborReq->no_ssid;
740 vos_mem_copy( &pMsg->ucSSID, &pNeighborReq->ssid, sizeof(tSirMacSSid));
741
742 status = palSendMBMessage(pMac->hHdd, pMsg);
743 if( status != eHAL_STATUS_SUCCESS )
744 return VOS_STATUS_E_FAILURE;
745
746 /* Neighbor report request message sent successfully to PE. Now register the callbacks */
747 pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallback =
748 callbackInfo->neighborRspCallback;
749 pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspCallbackInfo.neighborRspCallbackContext =
750 callbackInfo->neighborRspCallbackContext;
751 pMac->rrm.rrmSmeContext.neighborReqControlInfo.isNeighborRspPending = eANI_BOOLEAN_TRUE;
752
753 /* Start neighbor response wait timer now */
754 vos_timer_start(&pMac->rrm.rrmSmeContext.neighborReqControlInfo.neighborRspWaitTimer, callbackInfo->timeout);
755
756 return VOS_STATUS_SUCCESS;
757}
758
759/*--------------------------------------------------------------------------
760 \brief rrmCalculateNeighborAPRoamScore() - This API is called while handling
761 individual neighbor reports from the APs neighbor AP report to
762 calculate the cumulative roam score before storing it in neighbor
763 cache.
764
765 \param pNeighborReportDesc - Neighbor BSS Descriptor node for which roam score
766 should be calculated
767
768 \return void.
769--------------------------------------------------------------------------*/
770static void rrmCalculateNeighborAPRoamScore(tpAniSirGlobal pMac, tpRrmNeighborReportDesc pNeighborReportDesc)
771{
772 tpSirNeighborBssDescripton pNeighborBssDesc;
773 tANI_U32 roamScore = 0;
774
775 VOS_ASSERT(pNeighborReportDesc != NULL);
776 VOS_ASSERT(pNeighborReportDesc->pNeighborBssDescription != NULL);
777
778 pNeighborBssDesc = pNeighborReportDesc->pNeighborBssDescription;
779
780 if (pNeighborBssDesc->bssidInfo.rrmInfo.fMobilityDomain)
781 {
782 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_MOBILITY_DOMAIN;
783 if (pNeighborBssDesc->bssidInfo.rrmInfo.fSameSecurityMode)
784 {
785 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_SECURITY;
786 if (pNeighborBssDesc->bssidInfo.rrmInfo.fSameAuthenticator)
787 {
788 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_KEY_SCOPE;
789 if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapRadioMeasurement)
790 {
791 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_RRM;
792 if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapSpectrumMeasurement)
793 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_SPECTRUM_MGMT;
794 if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapQos)
795 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_QOS;
796 if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapApsd)
797 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_APSD;
798 if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapDelayedBlockAck)
799 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_DELAYED_BA;
800 if (pNeighborBssDesc->bssidInfo.rrmInfo.fCapImmediateBlockAck)
801 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_CAPABILITY_IMMEDIATE_BA;
802 if (pNeighborBssDesc->bssidInfo.rrmInfo.fApPreauthReachable)
803 roamScore += RRM_ROAM_SCORE_NEIGHBOR_REPORT_REACHABILITY;
804 }
805 }
806 }
807 }
808#ifdef FEATURE_WLAN_CCX
809 // It has come in the report so its the best score
810 if (csrNeighborRoamIs11rAssoc(pMac) == FALSE)
811 {
812 // IAPP Route so lets make use of this info
813 // save all AP, as the list does not come all the time
814 // Save and reuse till the next AP List comes to us.
815 // Even save our own MAC address. Will be useful next time around.
816 roamScore += RRM_ROAM_SCORE_NEIGHBOR_IAPP_LIST;
817 }
818#endif
819 pNeighborReportDesc->roamScore = roamScore;
820
821 return;
822}
823
824/*--------------------------------------------------------------------------
825 \brief rrmStoreNeighborRptByRoamScore() - This API is called to store a given
826 Neighbor BSS descriptor to the neighbor cache. This function
827 stores the neighbor BSS descriptors in such a way that descriptors
828 are sorted by roamScore in descending order
829
830 \param pNeighborReportDesc - Neighbor BSS Descriptor node to be stored in cache
831
832 \return void.
833--------------------------------------------------------------------------*/
834void rrmStoreNeighborRptByRoamScore(tpAniSirGlobal pMac, tpRrmNeighborReportDesc pNeighborReportDesc)
835{
836 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
837 tListElem *pEntry;
838 tRrmNeighborReportDesc *pTempNeighborReportDesc;
839
840 VOS_ASSERT(pNeighborReportDesc != NULL);
841 VOS_ASSERT(pNeighborReportDesc->pNeighborBssDescription != NULL);
842
843 if (csrLLIsListEmpty(&pSmeRrmContext->neighborReportCache, LL_ACCESS_LOCK))
844 {
845 smsLog(pMac, LOGE, FL("Neighbor report cache is empty.. Adding a entry now\n"));
846 /* Neighbor list cache is empty. Insert this entry in the tail */
847 csrLLInsertTail(&pSmeRrmContext->neighborReportCache, &pNeighborReportDesc->List, LL_ACCESS_LOCK);
848 return;
849 }
850 else
851 {
852 /* Should store the neighbor BSS description in the order sorted by roamScore in descending
853 order. APs with highest roamScore should be the 1st entry in the list */
854 pEntry = csrLLPeekHead(&pSmeRrmContext->neighborReportCache, LL_ACCESS_LOCK);
855 while (pEntry != NULL)
856 {
857 pTempNeighborReportDesc = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List );
858 if (pTempNeighborReportDesc->roamScore < pNeighborReportDesc->roamScore)
859 break;
860 pEntry = csrLLNext(&pSmeRrmContext->neighborReportCache, pEntry, LL_ACCESS_LOCK);
861 }
862
863 if (pEntry)
864 /* This BSS roamscore is better than something in the list. Insert this before that one */
865 csrLLInsertEntry(&pSmeRrmContext->neighborReportCache, pEntry, &pNeighborReportDesc->List, LL_ACCESS_LOCK);
866 else
867 /* All the entries in the list has a better roam Score than this one. Insert this at the last */
868 csrLLInsertTail(&pSmeRrmContext->neighborReportCache, &pNeighborReportDesc->List, LL_ACCESS_LOCK);
869 }
870 return;
871}
872
873/*--------------------------------------------------------------------------
874 \brief sme_RrmProcessNeighborReport() - This is called to process the Neighbor
875 report received from PE.
876
877 \param pMsgBuf - a pointer to a buffer that maps to various structures base
878 on the message type.
879 The beginning of the buffer can always map to tSirSmeRsp.
880
881 \return eHAL_STATUS_SUCCESS - Validation is successful.
882
883 \sa
884
885 --------------------------------------------------------------------------*/
886eHalStatus sme_RrmProcessNeighborReport(tpAniSirGlobal pMac, void *pMsgBuf)
887{
888 eHalStatus status = eHAL_STATUS_SUCCESS;
889 tpSirNeighborReportInd pNeighborRpt = (tpSirNeighborReportInd) pMsgBuf;
890 tpRrmNeighborReportDesc pNeighborReportDesc;
891 tANI_U8 i = 0;
892 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
893
894#ifdef FEATURE_WLAN_CCX
895 // Clear the cache for CCX.
896 if (csrNeighborRoamIsCCXAssoc(pMac))
897 {
898 rrmLLPurgeNeighborCache(pMac,
899 &pMac->rrm.rrmSmeContext.neighborReportCache);
900 }
901#endif
902
903 for (i = 0; i < pNeighborRpt->numNeighborReports; i++)
904 {
905 pNeighborReportDesc = vos_mem_malloc(sizeof(tRrmNeighborReportDesc));
906 if (NULL == pNeighborReportDesc)
907 {
908 smsLog( pMac, LOGE, "Failed to allocate memory for RRM Neighbor report desc\n");
909 status = eHAL_STATUS_FAILED_ALLOC;
910 goto end;
911
912 }
913
914 vos_mem_zero(pNeighborReportDesc, sizeof(tRrmNeighborReportDesc));
915 pNeighborReportDesc->pNeighborBssDescription = vos_mem_malloc(sizeof(tSirNeighborBssDescription));
916 if (NULL == pNeighborReportDesc->pNeighborBssDescription)
917 {
918 smsLog( pMac, LOGE, "Failed to allocate memory for RRM Neighbor report BSS Description\n");
919 status = eHAL_STATUS_FAILED_ALLOC;
920 goto end;
921 }
922 vos_mem_zero(pNeighborReportDesc->pNeighborBssDescription, sizeof(tSirNeighborBssDescription));
923 vos_mem_copy(pNeighborReportDesc->pNeighborBssDescription, &pNeighborRpt->sNeighborBssDescription[i],
924 sizeof(tSirNeighborBssDescription));
925
926#if defined WLAN_VOWIFI_DEBUG
927 smsLog( pMac, LOGE, "Received neighbor report with Neighbor BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n",
928 pNeighborRpt->sNeighborBssDescription[i].bssId[0],
929 pNeighborRpt->sNeighborBssDescription[i].bssId[1],
930 pNeighborRpt->sNeighborBssDescription[i].bssId[2],
931 pNeighborRpt->sNeighborBssDescription[i].bssId[3],
932 pNeighborRpt->sNeighborBssDescription[i].bssId[4],
933 pNeighborRpt->sNeighborBssDescription[i].bssId[5]);
934#endif
935
936 /* Calculate the roam score based on the BSS Capability in the BSSID Information and store it in Neighbor report Desc */
937 rrmCalculateNeighborAPRoamScore(pMac, pNeighborReportDesc);
938
939 /* Store the Neighbor report Desc in the cache based on the roam score */
940 if ( pNeighborReportDesc->roamScore > 0)
941 {
942 rrmStoreNeighborRptByRoamScore(pMac, pNeighborReportDesc);
943 }
944 else
945 {
946 smsLog(pMac, LOGE, FL("Roam score of BSSID %02x:%02x:%02x:%02x:%02x:%02x is 0, Ignoring.."),
947 pNeighborRpt->sNeighborBssDescription[i].bssId[0],
948 pNeighborRpt->sNeighborBssDescription[i].bssId[1],
949 pNeighborRpt->sNeighborBssDescription[i].bssId[2],
950 pNeighborRpt->sNeighborBssDescription[i].bssId[3],
951 pNeighborRpt->sNeighborBssDescription[i].bssId[4],
952 pNeighborRpt->sNeighborBssDescription[i].bssId[5]);
953
954 vos_mem_free(pNeighborReportDesc->pNeighborBssDescription);
955 vos_mem_free(pNeighborReportDesc);
956 }
957 }
958end:
959
960 if (!csrLLCount(&pMac->rrm.rrmSmeContext.neighborReportCache))
961 vosStatus = VOS_STATUS_E_FAILURE;
962
963 /* Received a report from AP. Indicate SUCCESS to the caller if there are some valid reports */
964 rrmIndicateNeighborReportResult(pMac, vosStatus);
965
966 return status;
967}
968/*--------------------------------------------------------------------------
969 \brief sme_RrmMsgProcessor() - sme_ProcessMsg() calls this function for the
970 messages that are handled by SME RRM module.
971
972 \param pMac - Pointer to the global MAC parameter structure.
973 \param msg_type - the type of msg passed by PE as defined in wniApi.h
974 \param pMsgBuf - a pointer to a buffer that maps to various structures base
975 on the message type.
976 The beginning of the buffer can always map to tSirSmeRsp.
977
978 \return eHAL_STATUS_SUCCESS - Validation is successful.
979
980 \sa
981
982 --------------------------------------------------------------------------*/
983eHalStatus sme_RrmMsgProcessor( tpAniSirGlobal pMac, v_U16_t msg_type,
984 void *pMsgBuf)
985{
986 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO_HIGH,
987 FL(" Msg = %d for RRM measurement\n") , msg_type );
988
989 //switch on the msg type & make the state transition accordingly
990 switch(msg_type)
991 {
992 case eWNI_SME_NEIGHBOR_REPORT_IND:
993 sme_RrmProcessNeighborReport( pMac, pMsgBuf );
994 break;
995
996 case eWNI_SME_BEACON_REPORT_REQ_IND:
997 sme_RrmProcessBeaconReportReqInd( pMac, pMsgBuf );
998 break;
999
1000 default:
1001 //err msg
1002 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
1003 FL("sme_RrmMsgProcessor:unknown msg type = %d\n"), msg_type);
1004
1005 break;
1006 }
1007
1008 return eHAL_STATUS_SUCCESS;
1009}
1010
1011/* ---------------------------------------------------------------------------
1012
1013 \fn rrmIterMeasTimerHandle
1014
1015 \brief Timer handler to handlet the timeout condition when a specific BT
1016
1017 stop event does not come back, in which case to restore back the
1018
1019 heartbeat timer.
1020
1021 \param pMac - The handle returned by macOpen.
1022
1023 \return VOID
1024
1025 ---------------------------------------------------------------------------*/
1026
1027void rrmIterMeasTimerHandle( v_PVOID_t userData )
1028{
1029 tpAniSirGlobal pMac = (tpAniSirGlobal) userData;
1030#if defined WLAN_VOWIFI_DEBUG
1031 smsLog( pMac, LOGE, "Randomization timer expired...send on next channel \n");
1032#endif
1033 //Issue a scan req for next channel.
1034 sme_RrmIssueScanReq( pMac );
1035}
1036
1037/* ---------------------------------------------------------------------------
1038
1039 \fn rrmNeighborRspTimeoutHandler
1040
1041 \brief Timer handler to handle the timeout condition when a neighbor request is sent
1042 and no neighbor response is received from the AP
1043
1044 \param pMac - The handle returned by macOpen.
1045
1046 \return VOID
1047
1048---------------------------------------------------------------------------*/
1049
1050void rrmNeighborRspTimeoutHandler
1051( v_PVOID_t userData )
1052{
1053 tpAniSirGlobal pMac = (tpAniSirGlobal) userData;
1054#if defined WLAN_VOWIFI_DEBUG
1055 smsLog( pMac, LOGE, "Neighbor Response timed out \n");
1056#endif
1057 rrmIndicateNeighborReportResult(pMac, VOS_STATUS_E_FAILURE);
1058 return;
1059}
1060
1061/* ---------------------------------------------------------------------------
1062
1063 \fn rrmOpen
1064
1065 \brief
1066
1067 \param pMac - The handle returned by macOpen.
1068
1069 \return VOS_STATUS
1070
1071 VOS_STATUS_E_FAILURE success
1072
1073 VOS_STATUS_SUCCESS failure
1074
1075 ---------------------------------------------------------------------------*/
1076
1077VOS_STATUS rrmOpen (tpAniSirGlobal pMac)
1078
1079{
1080
1081 VOS_STATUS vosStatus;
1082 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
1083 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
1084
1085 pSmeRrmContext->rrmConfig.maxRandnInterval = 50; //ms
1086
1087 vosStatus = vos_timer_init( &pSmeRrmContext->IterMeasTimer,
1088
1089 VOS_TIMER_TYPE_SW,
1090
1091 rrmIterMeasTimerHandle,
1092
1093 (void*) pMac);
1094
1095 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
1096
1097 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "rrmOpen: Fail to init timer");
1098
1099 return VOS_STATUS_E_FAILURE;
1100 }
1101
1102 vosStatus = vos_timer_init( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer,
1103
1104 VOS_TIMER_TYPE_SW,
1105
1106 rrmNeighborRspTimeoutHandler,
1107
1108 (void*) pMac);
1109
1110 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
1111
1112 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "rrmOpen: Fail to init timer");
1113
1114 return VOS_STATUS_E_FAILURE;
1115 }
1116
1117 pSmeRrmContext->neighborReqControlInfo.isNeighborRspPending = eANI_BOOLEAN_FALSE;
1118
1119 halStatus = csrLLOpen(pMac->hHdd, &pSmeRrmContext->neighborReportCache);
1120 if (eHAL_STATUS_SUCCESS != halStatus)
1121 {
1122 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "rrmOpen: Fail to open neighbor cache result");
1123 return VOS_STATUS_E_FAILURE;
1124 }
1125
1126 return VOS_STATUS_SUCCESS;
1127}
1128
1129
1130/* ---------------------------------------------------------------------------
1131
1132 \fn rrmClose
1133
1134 \brief
1135
1136 \param pMac - The handle returned by macOpen.
1137
1138 \return VOS_STATUS
1139
1140 VOS_STATUS_E_FAILURE success
1141
1142 VOS_STATUS_SUCCESS failure
1143
1144 ---------------------------------------------------------------------------*/
1145
1146VOS_STATUS rrmClose (tpAniSirGlobal pMac)
1147
1148{
1149
1150 VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
1151 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
1152
1153 if( VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState( &pSmeRrmContext->IterMeasTimer ) )
1154 {
1155 vosStatus = vos_timer_stop( &pSmeRrmContext->IterMeasTimer );
1156 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001157 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001158 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, FL("Timer stop fail") );
1159 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001160 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001161
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001162 vosStatus = vos_timer_destroy( &pSmeRrmContext->IterMeasTimer );
1163 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1164 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001165
1166 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, FL("Fail to destroy timer") );
1167
1168 }
1169
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001170 if( VOS_TIMER_STATE_RUNNING ==
1171 vos_timer_getCurrentState( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer ) )
1172 {
1173 vosStatus = vos_timer_stop( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer );
1174 if(!VOS_IS_STATUS_SUCCESS(vosStatus))
1175 {
1176 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, FL("Timer stop fail") );
1177 }
1178 }
1179
1180 vosStatus = vos_timer_destroy( &pSmeRrmContext->neighborReqControlInfo.neighborRspWaitTimer );
1181 if (!VOS_IS_STATUS_SUCCESS(vosStatus))
1182 {
1183 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, FL("Fail to destroy timer") );
1184
1185 }
1186
Jeff Johnson295189b2012-06-20 16:38:30 -07001187 rrmLLPurgeNeighborCache(pMac, &pSmeRrmContext->neighborReportCache);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001188
Jeff Johnson295189b2012-06-20 16:38:30 -07001189 csrLLClose(&pSmeRrmContext->neighborReportCache);
1190
1191 return vosStatus;
1192
1193}
1194
1195
1196
1197
1198/* ---------------------------------------------------------------------------
1199
1200 \fn rrmReady
1201
1202 \brief fn
1203
1204 \param pMac - The handle returned by macOpen.
1205
1206 \return VOS_STATUS
1207
1208 ---------------------------------------------------------------------------*/
1209
1210VOS_STATUS rrmReady (tpAniSirGlobal pMac)
1211
1212{
1213
1214 return VOS_STATUS_SUCCESS;
1215}
1216
1217/* ---------------------------------------------------------------------------
1218
1219 \fn rrmChangeDefaultConfigParam
1220 \brief fn
1221
1222 \param pMac - The handle returned by macOpen.
1223 \param pRrmConfig - pointer to new rrm configs.
1224
1225 \return VOS_STATUS
1226
1227 ---------------------------------------------------------------------------*/
1228VOS_STATUS rrmChangeDefaultConfigParam(tpAniSirGlobal pMac, tpRrmConfigParam pRrmConfig)
1229{
1230 vos_mem_copy( &pMac->rrm.rrmSmeContext.rrmConfig, pRrmConfig, sizeof( tRrmConfigParam ) );
1231
1232 return VOS_STATUS_SUCCESS;
1233}
1234
1235/* ---------------------------------------------------------------------------
1236
1237 \fn smeRrmGetFirstBssEntryFromNeighborCache()
1238
1239 \brief This function returns the first entry from the neighbor cache to the caller
1240
1241 \param pMac - The handle returned by macOpen.
1242
1243 \return VOID
1244
1245---------------------------------------------------------------------------*/
1246tRrmNeighborReportDesc* smeRrmGetFirstBssEntryFromNeighborCache( tpAniSirGlobal pMac)
1247{
1248 tListElem *pEntry;
1249 tRrmNeighborReportDesc *pTempBssEntry = NULL;
1250 tpRrmSMEContext pSmeRrmContext = &pMac->rrm.rrmSmeContext;
1251
1252
1253 pEntry = csrLLPeekHead( &pSmeRrmContext->neighborReportCache, LL_ACCESS_LOCK );
1254
1255 if(!pEntry || !csrLLCount(&pSmeRrmContext->neighborReportCache))
1256 {
1257 //list empty
1258 smsLog(pMac, LOGW, FL("List empty\n"));
1259 return NULL;
1260 }
1261
1262 pTempBssEntry = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List );
1263
1264 return pTempBssEntry;
1265}
1266
1267/* ---------------------------------------------------------------------------
1268
1269 \fn smeRrmGetNextBssEntryFromNeighborCache()
1270
1271 \brief This function returns the entry next to the given entry from the
1272 neighbor cache to the caller
1273
1274 \param pMac - The handle returned by macOpen.
1275
1276 \return VOID
1277
1278---------------------------------------------------------------------------*/
1279tRrmNeighborReportDesc* smeRrmGetNextBssEntryFromNeighborCache( tpAniSirGlobal pMac,
1280 tpRrmNeighborReportDesc pBssEntry)
1281{
1282 tListElem *pEntry;
1283 tRrmNeighborReportDesc *pTempBssEntry = NULL;
1284
1285 pEntry = csrLLNext(&pMac->rrm.rrmSmeContext.neighborReportCache, &pBssEntry->List, LL_ACCESS_LOCK);
1286
1287 if(!pEntry)
1288 {
1289 //list empty
1290 smsLog(pMac, LOGW, FL("List empty\n"));
1291 return NULL;
1292 }
1293
1294 pTempBssEntry = GET_BASE_ADDR( pEntry, tRrmNeighborReportDesc, List );
1295
1296 return pTempBssEntry;
1297}
1298
1299#ifdef FEATURE_WLAN_CCX
1300void csrCcxSendAdjacentApRepMsg(tpAniSirGlobal pMac, tCsrRoamSession *pSession)
1301{
1302 tpSirAdjacentApRepInd pAdjRep;
1303 tANI_U16 length;
1304 tANI_U32 roamTS2;
1305
1306 smsLog( pMac, LOG1, "Adjacent AP Report Msg to PE\n");
1307
1308 length = sizeof(tSirAdjacentApRepInd );
1309 pAdjRep = vos_mem_malloc ( length );
1310
1311 if ( NULL == pAdjRep )
1312 {
1313 smsLog( pMac, LOGP, "Unable to allocate memory for Adjacent AP report");
1314 return;
1315 }
1316
1317 vos_mem_zero( pAdjRep, length );
1318 pAdjRep->messageType = eWNI_SME_CCX_ADJACENT_AP_REPORT;
1319 pAdjRep->length = length;
1320 pAdjRep->channelNum = pSession->prevOpChannel;
1321 vos_mem_copy( pAdjRep->bssid, &pSession->connectedProfile.bssid, sizeof(tSirMacAddr) );
1322 vos_mem_copy( pAdjRep->prevApMacAddr, &pSession->prevApBssid, sizeof(tSirMacAddr) );
1323 vos_mem_copy( &pAdjRep->prevApSSID, &pSession->prevApSSID, sizeof(tSirMacSSid) );
1324 roamTS2 = vos_timer_get_system_time();
1325 pAdjRep->tsmRoamdelay = roamTS2 - pSession->roamTS1;
1326 pAdjRep->roamReason =SIR_CCX_ASSOC_REASON_UNSPECIFIED;
1327 pAdjRep->clientDissSecs =(pAdjRep->tsmRoamdelay/1000);
1328
1329 palSendMBMessage(pMac->hHdd, pAdjRep);
1330
1331 return;
1332}
1333#endif /* FEATURE_WLAN_CCX */
1334#endif