blob: 511c1f17313a43b1a59a13195707fd3737fb6125 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Jeff Johnson32d95a32012-09-10 13:15:23 -07002 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -07003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * Airgo Networks, Inc proprietary. All rights reserved.
24 * This file limScanResultUtils.cc contains the utility functions
25 * LIM uses for maintaining and accessing scan results on STA.
26 * Author: Chandra Modumudi
27 * Date: 02/13/02
28 * History:-
29 * Date Modified by Modification Information
30 * --------------------------------------------------------------------
31 */
32
33#include "limTypes.h"
34#include "limUtils.h"
35#include "limSerDesUtils.h"
36#include "limApi.h"
37#include "limSession.h"
38#if defined WLAN_FEATURE_VOWIFI
39#include "rrmApi.h"
40#endif
41
42
43
44/**
45 * limDeactiveMinChannelTimerDuringScan()
46 *
47 *FUNCTION:
48 * This function is called during scan upon receiving
49 * Beacon/Probe Response frame to deactivate MIN channel
50 * timer if running.
51 *
52 * This function should be called only when pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE
53 *
54 *LOGIC:
55 *
56 *ASSUMPTIONS:
57 * NA
58 *
59 *NOTE:
60 * NA
61 *
62 * @param pMac - Pointer to Global MAC structure
63 *
64 * @return eSIR_SUCCESS in case of success
65 */
66
67tANI_U32
68limDeactivateMinChannelTimerDuringScan(tpAniSirGlobal pMac)
69{
70 if ((pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE) && (pMac->lim.gLimHalScanState == eLIM_HAL_SCANNING_STATE))
71 {
72 /**
73 * Beacon/Probe Response is received during active scanning.
74 * Deactivate MIN channel timer if running.
75 */
76
77 limDeactivateAndChangeTimer(pMac,eLIM_MIN_CHANNEL_TIMER);
Jeff Johnsone7245742012-09-05 17:12:55 -070078 MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, NO_SESSION, eLIM_MAX_CHANNEL_TIMER));
Jeff Johnson295189b2012-06-20 16:38:30 -070079 if (tx_timer_activate(&pMac->lim.limTimers.gLimMaxChannelTimer)
80 == TX_TIMER_ERROR)
81 {
82 /// Could not activate max channel timer.
83 // Log error
84 limLog(pMac,LOGP, FL("could not activate max channel timer\n"));
85
86 limCompleteMlmScan(pMac, eSIR_SME_RESOURCES_UNAVAILABLE);
87 return TX_TIMER_ERROR;
88 }
89 }
90 return eSIR_SUCCESS;
91} /*** end limDeactivateMinChannelTimerDuringScan() ***/
92
93
94
95/**
96 * limCollectBssDescription()
97 *
98 *FUNCTION:
99 * This function is called during scan upon receiving
100 * Beacon/Probe Response frame to check if the received
101 * frame matches scan criteria, collect BSS description
102 * and add it to cached scan results.
103 *
104 *LOGIC:
105 *
106 *ASSUMPTIONS:
107 * NA
108 *
109 *NOTE:
110 * NA
111 *
112 * @param pMac - Pointer to Global MAC structure
113 * @param pBPR - Pointer to parsed Beacon/Probe Response structure
114 * @param pRxPacketInfo - Pointer to Received frame's BD
115 * ---------if defined WLAN_FEATURE_VOWIFI------
116 * @param fScanning - flag to indicate if it is during scan.
117 * ---------------------------------------------
118 *
119 * @return None
120 */
121#if defined WLAN_FEATURE_VOWIFI
122void
123limCollectBssDescription(tpAniSirGlobal pMac,
124 tSirBssDescription *pBssDescr,
125 tpSirProbeRespBeacon pBPR,
126 tANI_U8 *pRxPacketInfo,
127 tANI_U8 fScanning)
128#else
129void
130limCollectBssDescription(tpAniSirGlobal pMac,
131 tSirBssDescription *pBssDescr,
132 tpSirProbeRespBeacon pBPR,
133 tANI_U8 *pRxPacketInfo)
134#endif
135{
136 tANI_U8 *pBody;
137 tANI_U32 ieLen = 0;
138 tpSirMacMgmtHdr pHdr;
139 tANI_U8 channelNum;
140 tANI_U8 rxChannel;
141
142 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
143 ieLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) - SIR_MAC_B_PR_SSID_OFFSET;
144 rxChannel = WDA_GET_RX_CH(pRxPacketInfo);
145 pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
146
147
148 /**
149 * Length of BSS desription is without length of
150 * length itself and length of pointer
151 * that holds the next BSS description
152 */
153 pBssDescr->length = (tANI_U16)(
154 sizeof(tSirBssDescription) - sizeof(tANI_U16) -
155 sizeof(tANI_U32) + ieLen);
156
157 // Copy BSS Id
158 palCopyMemory( pMac->hHdd, (tANI_U8 *) &pBssDescr->bssId,
159 (tANI_U8 *) pHdr->bssId,
160 sizeof(tSirMacAddr));
161
162 // Copy Timestamp, Beacon Interval and Capability Info
163 pBssDescr->scanSysTimeMsec = vos_timer_get_system_time();
164
165 pBssDescr->timeStamp[0] = pBPR->timeStamp[0];
166 pBssDescr->timeStamp[1] = pBPR->timeStamp[1];
167 pBssDescr->beaconInterval = pBPR->beaconInterval;
168 pBssDescr->capabilityInfo = limGetU16((tANI_U8 *) &pBPR->capabilityInfo);
169
170
171 /*
172 * There is a narrow window after Channel Switch msg is sent to HAL and before the AGC is shut
173 * down and beacons/Probe Rsps can trickle in and we may report the incorrect channel in 5Ghz
174 * band, so not relying on the 'last Scanned Channel' stored in LIM.
175 * Instead use the value returned by RXP in BD. This the the same value which HAL programs into
176 * RXP before every channel switch.
177 * Right now there is a problem in 5Ghz, where we are receiving beacons from a channel different from
178 * the currently scanned channel. so incorrect channel is reported to CSR and association does not happen.
179 * So for now we keep on looking for the channel info in the beacon (DSParamSet IE OR HT Info IE), and only if it
180 * is not present in the beacon, we go for the channel info present in RXP.
181 * This fix will work for 5Ghz 11n devices, but for 11a devices, we have to rely on RXP routing flag to get the correct channel.
182 * So The problem of incorrect channel reporting in 5Ghz will still remain for 11a devices.
183 */
184 pBssDescr->channelId = limGetChannelFromBeacon(pMac, pBPR);
185
186 if (pBssDescr->channelId == 0)
187 {
188 /* If the channel Id is not retrieved from Beacon, extract the channel from BD */
189 /* Unmapped the channel.This We have to do since we have done mapping in the hal to
190 overcome the limitation of RXBD of not able to accomodate the bigger channel number.*/
191 if (!( rxChannel = limUnmapChannel(rxChannel)))
192 {
193 rxChannel = pMac->lim.gLimCurrentScanChannelId;
194 }
195 pBssDescr->channelId = rxChannel;
196 }
197
198 pBssDescr->channelIdSelf = rxChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -0700199 //set the network type in bss description
200 channelNum = pBssDescr->channelId;
201 pBssDescr->nwType = limGetNwType(pMac, channelNum, SIR_MAC_MGMT_FRAME, pBPR);
202
203 pBssDescr->aniIndicator = pBPR->propIEinfo.aniIndicator;
204
205 // Copy RSSI & SINR from BD
206
207 PELOG4(limLog(pMac, LOG4, "***********BSS Description for BSSID:*********** ");
208 sirDumpBuf(pMac, SIR_LIM_MODULE_ID, LOG4, pBssDescr->bssId, 6 );
209 sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOG4, (tANI_U8*)pRxPacketInfo, 36 );)
210
211 pBssDescr->rssi = (tANI_S8)WDA_GET_RX_RSSI_DB(pRxPacketInfo);
212
213 //SINR no longer reported by HW
214 pBssDescr->sinr = 0;
215
216 pBssDescr->nReceivedTime = (tANI_TIMESTAMP)palGetTickCount(pMac->hHdd);
217
218#if defined WLAN_FEATURE_VOWIFI
219 if( fScanning )
220 {
221 rrmGetStartTSF( pMac, pBssDescr->startTSF );
222 pBssDescr->parentTSF = WDA_GET_RX_TIMESTAMP(pRxPacketInfo);
223 }
224#endif
225
226#ifdef WLAN_FEATURE_VOWIFI_11R
227 // MobilityDomain
228 pBssDescr->mdie[0] = 0;
229 pBssDescr->mdie[1] = 0;
230 pBssDescr->mdie[2] = 0;
231 pBssDescr->mdiePresent = FALSE;
232 // If mdie is present in the probe resp we
233 // fill it in the bss description
234 if( pBPR->mdiePresent)
235 {
236 pBssDescr->mdiePresent = TRUE;
237 pBssDescr->mdie[0] = pBPR->mdie[0];
238 pBssDescr->mdie[1] = pBPR->mdie[1];
239 pBssDescr->mdie[2] = pBPR->mdie[2];
240 }
241#endif
242
243#ifdef FEATURE_WLAN_CCX
244 pBssDescr->QBSSLoad_present = FALSE;
245 pBssDescr->QBSSLoad_avail = 0;
246 if( pBPR->QBSSLoad.present)
247 {
248 pBssDescr->QBSSLoad_present = TRUE;
249 pBssDescr->QBSSLoad_avail = pBPR->QBSSLoad.avail;
250 }
251#endif
252 // Copy IE fields
253 palCopyMemory( pMac->hHdd, (tANI_U8 *) &pBssDescr->ieFields,
254 pBody + SIR_MAC_B_PR_SSID_OFFSET,
255 ieLen);
256
257 //sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOGW, (tANI_U8 *) pBssDescr, pBssDescr->length + 2 );
258 limLog( pMac, LOG3,
259 FL("Collected BSS Description for Channel(%1d), length(%u), aniIndicator(%d), IE Fields(%u)\n"),
260 pBssDescr->channelId,
261 pBssDescr->length,
262 pBssDescr->aniIndicator,
263 ieLen );
264
265 return;
266} /*** end limCollectBssDescription() ***/
267
268/**
269 * limIsScanRequestedSSID()
270 *
271 *FUNCTION:
272 * This function is called during scan upon receiving
273 * Beacon/Probe Response frame to check if the received
274 * SSID is present in the list of requested SSIDs in scan
275 *
276 *LOGIC:
277 *
278 *ASSUMPTIONS:
279 * NA
280 *
281 *NOTE:
282 * NA
283 *
284 * @param pMac - Pointer to Global MAC structure
285 * @param ssId - SSID Received in beacons/Probe responses that is compared against the
286 requeusted SSID in scan list
287 * ---------------------------------------------
288 *
289 * @return boolean - TRUE if SSID is present in requested list, FALSE otherwise
290 */
291
292tANI_BOOLEAN limIsScanRequestedSSID(tpAniSirGlobal pMac, tSirMacSSid *ssId)
293{
294 tANI_U8 i = 0;
295
296 for (i = 0; i < pMac->lim.gpLimMlmScanReq->numSsid; i++)
297 {
298 if ( eANI_BOOLEAN_TRUE == palEqualMemory( pMac->hHdd,(tANI_U8 *) ssId,
299 (tANI_U8 *) &pMac->lim.gpLimMlmScanReq->ssId[i],
300 (tANI_U8) (pMac->lim.gpLimMlmScanReq->ssId[i].length + 1)))
301 {
302 return eANI_BOOLEAN_TRUE;
303 }
304 }
305 return eANI_BOOLEAN_FALSE;
306}
307
308/**
309 * limCheckAndAddBssDescription()
310 *
311 *FUNCTION:
312 * This function is called during scan upon receiving
313 * Beacon/Probe Response frame to check if the received
314 * frame matches scan criteria, collect BSS description
315 * and add it to cached scan results.
316 *
317 *LOGIC:
318 *
319 *ASSUMPTIONS:
320 * NA
321 *
322 *NOTE:
323 * NA
324 *
325 * @param pMac - Pointer to Global MAC structure
326 * @param pBPR - Pointer to parsed Beacon/Probe Response structure
327 * @param pRxPacketInfo - Pointer to Received frame's BD
328 * @param fScanning - boolean to indicate whether the BSS is from current scan or just happen to receive a beacon
329 *
330 * @return None
331 */
332
333void
334limCheckAndAddBssDescription(tpAniSirGlobal pMac,
335 tpSirProbeRespBeacon pBPR,
336 tANI_U8 *pRxPacketInfo,
337 tANI_BOOLEAN fScanning,
338 tANI_U8 fProbeRsp)
339{
340 tLimScanResultNode *pBssDescr;
341 tANI_U32 frameLen, ieLen = 0;
342 tANI_U8 rxChannelInBeacon = 0;
343 eHalStatus status;
344
345#ifdef WLAN_FEATURE_P2P
346 tSirMacAddr bssid = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
347 tANI_BOOLEAN fFound = FALSE;
348 tpSirMacDataHdr3a pHdr;
349
350 pHdr = WDA_GET_RX_MPDUHEADER3A((tANI_U8 *)pRxPacketInfo);
351
352 //Checking if scanning for a particular BSSID
353 if ((fScanning) && (pMac->lim.gpLimMlmScanReq))
354 {
355 fFound = palEqualMemory(pMac->hHdd, pHdr->addr3, &pMac->lim.gpLimMlmScanReq->bssId, 6);
356 if (!fFound)
357 {
358 if ((pMac->lim.gpLimMlmScanReq->p2pSearch) &&
359 (palEqualMemory(pMac->hHdd, pBPR->P2PProbeRes.P2PDeviceInfo.P2PDeviceAddress,
360 &pMac->lim.gpLimMlmScanReq->bssId, 6)))
361 {
362 fFound = eANI_BOOLEAN_TRUE;
363 }
364 }
365 }
366#endif
367
368 /**
369 * Compare SSID with the one sent in
370 * Probe Request frame, if any.
371 * If they don't match, ignore the
372 * Beacon frame.
373 * pMac->lim.gLimMlmScanReq->ssId.length == 0
374 * indicates Broadcast SSID.
375 * When gLimReturnAfterFirstMatch is set, it means the scan has to match
376 * a SSID (if it is also set). Ignore the other BSS in that case.
377 */
378
379 if (((fScanning) && ( pMac->lim.gLimReturnAfterFirstMatch & 0x01 )
380 && (pMac->lim.gpLimMlmScanReq->numSsid) &&
381 !limIsScanRequestedSSID(pMac, &pBPR->ssId))
382 || (!fFound && (pMac->lim.gpLimMlmScanReq && pMac->lim.gpLimMlmScanReq->bssId) &&
383 !palEqualMemory(pMac->hHdd, bssid, &pMac->lim.gpLimMlmScanReq->bssId, 6))
384 )
385 {
386 /**
387 * Received SSID does not match with
388 * the one we're scanning for.
389 * Ignore received Beacon frame
390 */
391
392 return;
393 }
394
395 /* There is no point in caching & reporting the scan results for APs
396 * which are in the process of switching the channel. So, we are not
397 * caching the scan results for APs which are adverzing the channel-switch
398 * element in their beacons and probe responses.
399 */
400 if(pBPR->channelSwitchPresent)
401 {
402 return;
403 }
404
405 /* If beacon/probe resp DS param channel does not match with
406 * RX BD channel then don't save the results. It might be a beacon
407 * from another channel heard as noise on the current scanning channel
408 */
409
410 if (pBPR->dsParamsPresent)
411 {
412 /* This means that we are in 2.4GHz mode or 5GHz 11n mode */
413 rxChannelInBeacon = limGetChannelFromBeacon(pMac, pBPR);
414 if (rxChannelInBeacon < 15)
415 {
416 /* This means that we are in 2.4GHz mode */
417 if(WDA_GET_RX_CH(pRxPacketInfo) != rxChannelInBeacon)
418 {
419 limLog(pMac, LOG3, FL("Beacon/Probe Rsp dropped. Channel in BD %d. "
420 "Channel in beacon" " %d\n"),
421 WDA_GET_RX_CH(pRxPacketInfo),limGetChannelFromBeacon(pMac, pBPR));
422 return;
423 }
424 }
425 }
426
427 /**
428 * Allocate buffer to hold BSS description from
429 * received Beacon frame.
430 * Include size of fixed fields and IEs length
431 */
432
433 ieLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo) - SIR_MAC_B_PR_SSID_OFFSET;
434 frameLen = sizeof(tLimScanResultNode) + ieLen - sizeof(tANI_U32); // Sizeof(tANI_U32) is for ieFields[1]
435
436 if( eHAL_STATUS_SUCCESS != palAllocateMemory( pMac->hHdd, (void **)&pBssDescr, frameLen))
437 {
438 // Log error
439 limLog(pMac, LOGP,
440 FL("call for palAllocateMemory failed for storing BSS description\n"));
441
442 return;
443 }
444
445 // In scan state, store scan result.
446#if defined WLAN_FEATURE_VOWIFI
447 limCollectBssDescription(pMac, &pBssDescr->bssDescription,
448 pBPR, pRxPacketInfo, fScanning);
449#else
450 limCollectBssDescription(pMac, &pBssDescr->bssDescription,
451 pBPR, pRxPacketInfo);
452#endif
453
454 pBssDescr->bssDescription.fProbeRsp = fProbeRsp;
455
456 pBssDescr->next = NULL;
457
458 /**
459 * Depending on whether to store unique or all
460 * scan results, pass hash update/add parameter
461 */
462
463 //If it is not scanning, only save unique results
464 if (pMac->lim.gLimReturnUniqueResults || (!fScanning))
465 {
466 status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_UPDATE);
467 }
468 else
469 {
470 status = limLookupNaddHashEntry(pMac, pBssDescr, LIM_HASH_ADD);
471 }
472
473 if(fScanning)
474 {
475 if ((pBssDescr->bssDescription.channelId <= 14) &&
476 (pMac->lim.gLimReturnAfterFirstMatch & 0x40) &&
477 pBPR->countryInfoPresent)
478 pMac->lim.gLim24Band11dScanDone = 1;
479
480 if ((pBssDescr->bssDescription.channelId > 14) &&
481 (pMac->lim.gLimReturnAfterFirstMatch & 0x80) &&
482 pBPR->countryInfoPresent)
483 pMac->lim.gLim50Band11dScanDone = 1;
484
485 if ( ( pMac->lim.gLimReturnAfterFirstMatch & 0x01 ) ||
486 ( pMac->lim.gLim24Band11dScanDone && ( pMac->lim.gLimReturnAfterFirstMatch & 0x40 ) ) ||
487 ( pMac->lim.gLim50Band11dScanDone && ( pMac->lim.gLimReturnAfterFirstMatch & 0x80 ) )
488#ifdef WLAN_FEATURE_P2P
489 || fFound
490#endif
491 )
492/*
493 if ((pMac->lim.gLimReturnAfterFirstMatch & 0x01) ||
494 (pMac->lim.gLim24Band11dScanDone &&
495 !(pMac->lim.gLimReturnAfterFirstMatch & 0xC0)) ||
496 (pMac->lim.gLim50Band11dScanDone &&
497 !(pMac->lim.gLimReturnAfterFirstMatch & 0xC0)) ||
498 (pMac->lim.gLim24Band11dScanDone &&
499 pMac->lim.gLim50Band11dScanDone &&
500 pMac->lim.gLimReturnAfterFirstMatch & 0xC0))
501*/
502 {
503 /**
504 * Stop scanning and return the BSS description(s)
505 * collected so far.
506 */
507 limLog(pMac,
508 LOGW,
509 FL("Completed scan: 24Band11dScan = %d, 50Band11dScan = %d BSS id\n"),
510 pMac->lim.gLim24Band11dScanDone,
511 pMac->lim.gLim50Band11dScanDone);
512
513 //Need to disable the timers. If they fire, they will send END_SCAN
514 //while we already send FINISH_SCAN here. This may mess up the gLimHalScanState
515 limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER);
516 limDeactivateAndChangeTimer(pMac, eLIM_MAX_CHANNEL_TIMER);
517 //Set the resume channel to Any valid channel (invalid).
518 //This will instruct HAL to set it to any previous valid channel.
519 peSetResumeChannel(pMac, 0, 0);
520 limSendHalFinishScanReq( pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE );
521 //limSendHalFinishScanReq( pMac, eLIM_HAL_FINISH_SCAN_WAIT_STATE );
522 }
523 }//(eANI_BOOLEAN_TRUE == fScanning)
524
525 if( eHAL_STATUS_SUCCESS != status )
526 {
527 palFreeMemory( pMac->hHdd, pBssDescr );
528 }
529} /****** end limCheckAndAddBssDescription() ******/
530
531
532
533/**
534 * limScanHashFunction()
535 *
536 *FUNCTION:
537 * This function is called during scan hash entry operations
538 *
539 *LOGIC:
540 *
541 *ASSUMPTIONS:
542 * NA
543 *
544 *NOTE:
545 * NA
546 *
547 * @param bssId - Received BSSid
548 *
549 * @return Hash index
550 */
551
552tANI_U8
553limScanHashFunction(tSirMacAddr bssId)
554{
555 tANI_U16 i, hash = 0;
556
557 for (i = 0; i < sizeof(tSirMacAddr); i++)
558 hash += bssId[i];
559
560 return hash % LIM_MAX_NUM_OF_SCAN_RESULTS;
561} /****** end limScanHashFunction() ******/
562
563
564
565/**
566 * limInitHashTable()
567 *
568 *FUNCTION:
569 * This function is called upon receiving SME_START_REQ
570 * to initialize global cached scan hash table
571 *
572 *LOGIC:
573 *
574 *ASSUMPTIONS:
575 * NA
576 *
577 *NOTE:
578 * NA
579 *
580 * @param pMac - Pointer to Global MAC structure
581 * @return None
582 */
583
584void
585limInitHashTable(tpAniSirGlobal pMac)
586{
587 tANI_U16 i;
588 for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++)
589 pMac->lim.gLimCachedScanHashTable[i] = NULL;
590} /****** end limInitHashTable() ******/
591
592
593
594/**
595 * limLookupNaddHashEntry()
596 *
597 *FUNCTION:
598 * This function is called upon receiving a Beacon or
599 * Probe Response frame during scan phase to store
600 * received BSS description into scan result hash table.
601 *
602 *LOGIC:
603 *
604 *ASSUMPTIONS:
605 * NA
606 *
607 *NOTE:
608 * NA
609 *
610 * @param pMac - Pointer to Global MAC structure
611 * @param pBssDescr - Pointer to BSS description to be
612 * added to the scan result hash table.
613 * @param action - Indicates action to be performed
614 * when same BSS description is found. This is
615 * dependent on whether unique scan result to
616 * be stored or not.
617 *
618 * @return None
619 */
620
621eHalStatus
622limLookupNaddHashEntry(tpAniSirGlobal pMac,
623 tLimScanResultNode *pBssDescr, tANI_U8 action)
624{
Madan Mohan Koyyalamudica43cdf2012-09-24 13:15:49 -0700625 tANI_U8 index, ssidLen = 0;
626 tANI_U8 found = false;
Jeff Johnson295189b2012-06-20 16:38:30 -0700627 tLimScanResultNode *ptemp, *pprev;
628 tSirMacCapabilityInfo *pSirCap, *pSirCapTemp;
629 int idx, len;
630 tANI_U8 *pbIe;
631
632 index = limScanHashFunction(pBssDescr->bssDescription.bssId);
633 ptemp = pMac->lim.gLimCachedScanHashTable[index];
634
635 //ieFields start with TLV of SSID IE
636 ssidLen = * ((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1);
637 pSirCap = (tSirMacCapabilityInfo *)&pBssDescr->bssDescription.capabilityInfo;
638
639 for (pprev = ptemp; ptemp; pprev = ptemp, ptemp = ptemp->next)
640 {
Jeff Johnsone7245742012-09-05 17:12:55 -0700641 //For infrastructure, check BSSID and SSID. For IBSS, check more
Jeff Johnson295189b2012-06-20 16:38:30 -0700642 pSirCapTemp = (tSirMacCapabilityInfo *)&ptemp->bssDescription.capabilityInfo;
643 if((pSirCapTemp->ess == pSirCap->ess) && //matching ESS type first
644 (palEqualMemory( pMac->hHdd,(tANI_U8 *) pBssDescr->bssDescription.bssId,
645 (tANI_U8 *) ptemp->bssDescription.bssId,
646 sizeof(tSirMacAddr))) && //matching BSSID
Jeff Johnsone7245742012-09-05 17:12:55 -0700647 (pBssDescr->bssDescription.channelId ==
648 ptemp->bssDescription.channelId) &&
649 palEqualMemory( pMac->hHdd,((tANI_U8 *) &pBssDescr->bssDescription.ieFields + 1),
Jeff Johnson295189b2012-06-20 16:38:30 -0700650 ((tANI_U8 *) &ptemp->bssDescription.ieFields + 1),
651 (tANI_U8) (ssidLen + 1)) &&
Jeff Johnsone7245742012-09-05 17:12:55 -0700652 ((pSirCapTemp->ess) || //we are done for infrastructure
653 //For IBSS, nwType and channelId
654 (((pBssDescr->bssDescription.nwType ==
Jeff Johnson295189b2012-06-20 16:38:30 -0700655 ptemp->bssDescription.nwType) &&
656 (pBssDescr->bssDescription.channelId ==
657 ptemp->bssDescription.channelId))))
658 )
659 {
660 // Found the same BSS description
661 if (action == LIM_HASH_UPDATE)
662 {
663 if(pBssDescr->bssDescription.fProbeRsp != ptemp->bssDescription.fProbeRsp)
664 {
665 //We get a different, save the old frame WSC IE if it is there
666 idx = 0;
667 len = ptemp->bssDescription.length - sizeof(tSirBssDescription) +
668 sizeof(tANI_U16) + sizeof(tANI_U32) - DOT11F_IE_WSCPROBERES_MIN_LEN - 2;
669 pbIe = (tANI_U8 *)ptemp->bssDescription.ieFields;
670 //Save WPS IE if it exists
671 pBssDescr->bssDescription.WscIeLen = 0;
672 while(idx < len)
673 {
674 if((DOT11F_EID_WSCPROBERES == pbIe[0]) &&
675 (0x00 == pbIe[2]) && (0x50 == pbIe[3]) && (0xf2 == pbIe[4]) && (0x04 == pbIe[5]))
676 {
677 //Found it
678 if((DOT11F_IE_WSCPROBERES_MAX_LEN - 2) >= pbIe[1])
679 {
680 palCopyMemory(pMac->hHdd, pBssDescr->bssDescription.WscIeProbeRsp,
681 pbIe, pbIe[1] + 2);
682 pBssDescr->bssDescription.WscIeLen = pbIe[1] + 2;
683 }
684 break;
685 }
686 idx += pbIe[1] + 2;
687 pbIe += pbIe[1] + 2;
688 }
689 }
690
691
692 if(NULL != pMac->lim.gpLimMlmScanReq)
693 {
694 if((pMac->lim.gpLimMlmScanReq->numSsid)&&
695 ( limIsNullSsid((tSirMacSSid *)((tANI_U8 *)
696 &pBssDescr->bssDescription.ieFields + 1))))
697 return eHAL_STATUS_FAILURE;
698 }
699
700 // Delete this entry
Madan Mohan Koyyalamudica43cdf2012-09-24 13:15:49 -0700701 if (ptemp == pMac->lim.gLimCachedScanHashTable[index])
702 pprev = pMac->lim.gLimCachedScanHashTable[index] = ptemp->next;
Jeff Johnson295189b2012-06-20 16:38:30 -0700703 else
Madan Mohan Koyyalamudica43cdf2012-09-24 13:15:49 -0700704 pprev->next = ptemp->next;
Jeff Johnson295189b2012-06-20 16:38:30 -0700705
Madan Mohan Koyyalamudica43cdf2012-09-24 13:15:49 -0700706 pMac->lim.gLimMlmScanResultLength -=
707 ptemp->bssDescription.length + sizeof(tANI_U16);
Jeff Johnson295189b2012-06-20 16:38:30 -0700708
Madan Mohan Koyyalamudica43cdf2012-09-24 13:15:49 -0700709 palFreeMemory( pMac->hHdd, (tANI_U8 *) ptemp);
Jeff Johnson295189b2012-06-20 16:38:30 -0700710 }
Madan Mohan Koyyalamudica43cdf2012-09-24 13:15:49 -0700711 found = true;
712 break;
Jeff Johnson295189b2012-06-20 16:38:30 -0700713 }
714 }
715
716 // Add this BSS description at same index
717 if (pprev == pMac->lim.gLimCachedScanHashTable[index])
718 {
719 pBssDescr->next = pMac->lim.gLimCachedScanHashTable[index];
720 pMac->lim.gLimCachedScanHashTable[index] = pBssDescr;
721 }
722 else
723 {
724 pBssDescr->next = pprev->next;
725 pprev->next = pBssDescr;
726 }
727 pMac->lim.gLimMlmScanResultLength +=
728 pBssDescr->bssDescription.length + sizeof(tANI_U16);
729
730 PELOG2(limLog(pMac, LOG2, FL("Added new BSS description size %d TOT %d BSS id\n"),
731 pBssDescr->bssDescription.length,
732 pMac->lim.gLimMlmScanResultLength);
733 limPrintMacAddr(pMac, pBssDescr->bssDescription.bssId, LOG2);)
734
735 // Send new BSS found indication to HDD if CFG option is set
736 if (!found) limSendSmeNeighborBssInd(pMac, pBssDescr);
737
738 //
739 // TODO: IF applicable, do we need to send:
740 // Mesg - eWNI_SME_WM_STATUS_CHANGE_NTF
741 // Status change code - eSIR_SME_CB_LEGACY_BSS_FOUND_BY_AP
742 //
743 return eHAL_STATUS_SUCCESS;
744}
745
746
747
748/**
749 * limDeleteHashEntry()
750 *
751 *FUNCTION:
752 * This function is called upon to delete
753 * a BSS description from scan result hash table.
754 *
755 *LOGIC:
756 *
757 *ASSUMPTIONS:
758 * NA
759 *
760 *NOTE:
761 * Yet to find the utility of the function
762 *
763 * @param pBssDescr - Pointer to BSS description to be
764 * deleted from the scan result hash table.
765 *
766 * @return None
767 */
768
769void limDeleteHashEntry(tLimScanResultNode *pBssDescr)
770{
771} /****** end limDeleteHashEntry() ******/
772
773
774
775/**
776 * limCopyScanResult()
777 *
778 *FUNCTION:
779 * This function is called by limProcessSmeMessages() while
780 * sending SME_SCAN_RSP with scan result to HDD.
781 *
782 *LOGIC:
783 * This function traverses the scan list stored in scan hash table
784 *
785 *ASSUMPTIONS:
786 * NA
787 *
788 *NOTE:
789 * NA
790 *
791 * @param pMac - Pointer to Global MAC structure
792 * @param pDest - Destination pointer
793 *
794 * @return None
795 */
796
797void
798limCopyScanResult(tpAniSirGlobal pMac, tANI_U8 *pDest)
799{
800 tLimScanResultNode *ptemp;
801 tANI_U16 i;
802 for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++)
803 {
804 if ((ptemp = pMac->lim.gLimCachedScanHashTable[i]) != NULL)
805 {
806 while(ptemp)
807 {
808 /// Copy entire BSS description including length
809 palCopyMemory( pMac->hHdd, pDest,
810 (tANI_U8 *) &ptemp->bssDescription,
811 ptemp->bssDescription.length + 2);
812 pDest += ptemp->bssDescription.length + 2;
813 ptemp = ptemp->next;
814 }
815 }
816 }
817} /****** end limCopyScanResult() ******/
818
819
820
821/**
822 * limDeleteCachedScanResults()
823 *
824 *FUNCTION:
825 * This function is called by limProcessSmeMessages() upon receiving
826 * SME_SCAN_REQ with fresh scan result flag set.
827 *
828 *LOGIC:
829 * This function traverses the scan list stored in scan hash table
830 * and deletes the entries if any
831 *
832 *ASSUMPTIONS:
833 * NA
834 *
835 *NOTE:
836 * NA
837 *
838 * @param pMac - Pointer to Global MAC structure
839 * @return None
840 */
841
842void
843limDeleteCachedScanResults(tpAniSirGlobal pMac)
844{
845 tLimScanResultNode *pNode, *pNextNode;
846 tANI_U16 i;
847 for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++)
848 {
849 if ((pNode = pMac->lim.gLimCachedScanHashTable[i]) != NULL)
850 {
851 while (pNode)
852 {
853 pNextNode = pNode->next;
854
855 // Delete the current node
856 palFreeMemory( pMac->hHdd, (tANI_U8 *) pNode);
857
858 pNode = pNextNode;
859 }
860 }
861 }
862
863 pMac->lim.gLimSmeScanResultLength = 0;
864} /****** end limDeleteCachedScanResults() ******/
865
866
867
868/**
869 * limReInitScanResults()
870 *
871 *FUNCTION:
872 * This function is called delete exisiting scan results
873 * and initialize the scan hash table
874 *
875 *LOGIC:
876 *
877 *ASSUMPTIONS:
878 * NA
879 *
880 *NOTE:
881 * NA
882 *
883 * @param pMac - Pointer to Global MAC structure
884 * @return None
885 */
886
887void
888limReInitScanResults(tpAniSirGlobal pMac)
889{
890 limDeleteCachedScanResults(pMac);
891 limInitHashTable(pMac);
892
893 // !!LAC - need to clear out the global scan result length
894 // since the list was just purged from the hash table.
895 pMac->lim.gLimMlmScanResultLength = 0;
896
897} /****** end limReInitScanResults() ******/