1 /*
2 * scanMngr.c
3 *
4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name Texas Instruments nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 /** \file scanMngr.c
35 * \brief This file include the scan manager module implementation
36 *
37 * \see scanMngr.h, scanMngrApi.h scanMngrTypes.h
38 */
39
40
41 #define __FILE_ID__ FILE_ID_9
42 #include "TWDriver.h"
43 #include "roamingMngrApi.h"
44 #include "osApi.h"
45 #include "timer.h"
46 #include "ScanCncn.h"
47 #include "report.h"
48 #include "regulatoryDomainApi.h"
49 #include "siteMgrApi.h"
50 #include "scanMngr.h"
51 #include "DrvMainModules.h"
52 #include "EvHandler.h"
53 #include "apConnApi.h"
54
55
56 /*
57 ***********************************************************************
58 * Internal functions
59 ***********************************************************************
60 */
61 /***************************************************************************
62 * reminder64 *
63 ****************************************************************************
64 DESCRIPTION: returns the reminder of a 64 bit number division by a 32
65 bit number.
66
67 INPUT: The dividee (64 bit number to divide)
68 The divider (32 bit number to divide by)
69
70 OUTPUT:
71
72
73 RETURN: The reminder
74 ****************************************************************************/
reminder64(TI_UINT64 dividee,TI_UINT32 divider)75 static TI_UINT32 reminder64( TI_UINT64 dividee, TI_UINT32 divider )
76 {
77 TI_UINT32 divideeHigh, divideeLow, partA, partB, mod28n, mod24n, mod16n, partA8n, mod8n, mod4n;
78
79 divideeHigh = INT64_HIGHER( dividee );
80 divideeLow = INT64_LOWER( dividee );
81
82 mod8n = 256 % divider;
83 mod4n = 16 % divider;
84
85 partA = (mod4n * (divideeHigh % divider)) % divider;
86 partA8n = (partA * mod4n) % divider;
87 mod16n = (partA8n * mod8n) % divider;
88 mod24n = (mod8n * mod16n) % divider;
89 mod28n = (mod4n * mod24n) % divider;
90
91 partB = (mod4n * mod28n) % divider;
92 return ( partB + (divideeLow % divider)) % divider;
93 }
94
95
96
scanMngr_setManualScanDefaultParams(TI_HANDLE hScanMngr)97 static void scanMngr_setManualScanDefaultParams(TI_HANDLE hScanMngr)
98 {
99 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
100
101 pScanMngr->manualScanParams.desiredSsid.len = 1; /* will be set by the scan concentrator */
102 pScanMngr->manualScanParams.scanType= SCAN_TYPE_NORMAL_ACTIVE;
103 pScanMngr->manualScanParams.band = RADIO_BAND_2_4_GHZ;
104 pScanMngr->manualScanParams.probeReqNumber = 3;
105 pScanMngr->manualScanParams.probeRequestRate = RATE_MASK_UNSPECIFIED;
106 }
107
108
scanMngr_reportContinuousScanResults(TI_HANDLE hScanMngr,EScanCncnResultStatus resultStatus)109 static void scanMngr_reportContinuousScanResults (TI_HANDLE hScanMngr, EScanCncnResultStatus resultStatus)
110 {
111 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
112 BssListEx_t BssListEx;
113
114
115 if (resultStatus == SCAN_CRS_SCAN_COMPLETE_OK)
116 {
117 BssListEx.pListOfAPs = scanMngr_getBSSList(hScanMngr);
118 BssListEx.scanIsRunning = pScanMngr->bContinuousScanStarted; /* false = stopped */
119 EvHandlerSendEvent(pScanMngr->hEvHandler, IPC_EVENT_CONTINUOUS_SCAN_REPORT, (TI_UINT8*)&BssListEx, sizeof(BssListEx_t));
120 }
121 else
122 {
123 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_ERROR, "scanMngr_reportContinuousScanResults failed. scan status %d\n", resultStatus);
124 }
125 }
126
127
128
129 /**
130 * \\n
131 * \date 01-Mar-2005\n
132 * \brief Frees scan manager resources.\n
133 *
134 * Function Scope \e Private.\n
135 * \param hScanMngr - handle to the scan manager object.\n
136 */
scanMngrFreeMem(TI_HANDLE hScanMngr)137 void scanMngrFreeMem (TI_HANDLE hScanMngr)
138 {
139 scanMngr_t* pScanMngr = hScanMngr;
140 TI_UINT8 i;
141
142 /* free frame storage space */
143 for (i = 0; i < MAX_SIZE_OF_BSS_TRACK_LIST; i++)
144 {
145 if (pScanMngr->BSSList.BSSList[i].pBuffer)
146 {
147 os_memoryFree (pScanMngr->hOS, pScanMngr->BSSList.BSSList[i].pBuffer, MAX_BEACON_BODY_LENGTH);
148 }
149 }
150
151 /* free the timer */
152 if (pScanMngr->hContinuousScanTimer)
153 {
154 tmr_DestroyTimer (pScanMngr->hContinuousScanTimer);
155 }
156
157 /* free the scan manager object */
158 os_memoryFree (pScanMngr->hOS, hScanMngr, sizeof(scanMngr_t));
159 }
160
161 /**
162 * \\n
163 * \date 01-Mar-2005\n
164 * \brief Callback used by the scan concentrator for immediate scan result.\n
165 *
166 * Function Scope \e Public.\n
167 * \param hScanMngr - handle to the scan manager object.\n
168 * \param resultStatus - reason for calling this function (frame received / scan complete).\n
169 * \param frameInfo - frame related information (in case of a frame reception).\n
170 * \param SPSStatus - bitmap indicating which channels were scan, in case of an SPS scan.\n
171 */
scanMngr_immedScanCB(TI_HANDLE hScanMngr,EScanCncnResultStatus resultStatus,TScanFrameInfo * frameInfo,TI_UINT16 SPSStatus)172 void scanMngr_immedScanCB( TI_HANDLE hScanMngr, EScanCncnResultStatus resultStatus,
173 TScanFrameInfo* frameInfo, TI_UINT16 SPSStatus )
174 {
175 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
176 TScanBandPolicy* aPolicy;
177 EScanCncnResultStatus nextResultStatus;
178
179 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_immedScanCB called, hScanMngr=0x%x, resultStatus=%d", hScanMngr, resultStatus);
180
181 switch (resultStatus)
182 {
183 /* if this function is called because a frame was received, update the BSS list accordingly */
184 case SCAN_CRS_RECEIVED_FRAME:
185 scanMngrUpdateReceivedFrame( hScanMngr, frameInfo );
186 break;
187
188 /* scan was completed successfuly */
189 case SCAN_CRS_SCAN_COMPLETE_OK:
190 /* act according to immediate scan state */
191 switch (pScanMngr->immedScanState)
192 {
193 /* immediate scan on G finished */
194 case SCAN_ISS_G_BAND:
195 #ifdef TI_DBG
196 pScanMngr->stats.ImmediateGByStatus[ resultStatus ]++;
197 #endif
198 /* check if another scan is needed (this time on A) */
199 aPolicy = scanMngrGetPolicyByBand( hScanMngr, RADIO_BAND_5_0_GHZ );
200 if ( (NULL != aPolicy) &&
201 (SCAN_TYPE_NO_SCAN != aPolicy->immediateScanMethod.scanType))
202 {
203 /* build scan command */
204 scanMngrBuildImmediateScanCommand( hScanMngr, aPolicy, pScanMngr->bImmedNeighborAPsOnly );
205
206 /* if no channels are available, report error */
207 if ( 0 < pScanMngr->scanParams.numOfChannels )
208 {
209 /* mark that immediate scan is running on band A */
210 pScanMngr->immedScanState = SCAN_ISS_A_BAND;
211
212 /* send scan command to scan concentrator */
213 nextResultStatus =
214 scanCncn_Start1ShotScan( pScanMngr->hScanCncn, SCAN_SCC_ROAMING_IMMED, &(pScanMngr->scanParams));
215 if ( SCAN_CRS_SCAN_RUNNING != nextResultStatus )
216 {
217 pScanMngr->immedScanState = SCAN_ISS_IDLE;
218 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Failed to start immediate scan on band A, return code %d.\n", resultStatus);
219 #ifdef TI_DBG
220 pScanMngr->stats.ImmediateAByStatus[ nextResultStatus ]++;
221 #endif
222 scanMngr_immediateScanComplete(hScanMngr,SCAN_MRS_SCAN_COMPLETE_OK);
223 }
224 }
225 else
226 {
227 /* mark that immediate scan is not running */
228 pScanMngr->immedScanState = SCAN_ISS_IDLE;
229
230 /* no channels are actually available for scan - notify the roaming manager of the scan complete */
231 scanMngr_immediateScanComplete(hScanMngr,SCAN_MRS_SCAN_COMPLETE_OK);
232 }
233 }
234 else
235 {
236 /* mark that immediate scan is not running */
237 pScanMngr->immedScanState = SCAN_ISS_IDLE;
238
239 /* otherwise, notify the roaming manager of the scan complete */
240 scanMngr_immediateScanComplete(hScanMngr,SCAN_MRS_SCAN_COMPLETE_OK);
241 }
242 break;
243
244 /* stop immediate scan was requested */
245 case SCAN_ISS_STOPPING:
246 /* mark that immediate scan is not running */
247 pScanMngr->immedScanState = SCAN_ISS_IDLE;
248
249 /* notify the roaming manager of the scan complete */
250 scanMngr_immediateScanComplete(hScanMngr,SCAN_MRS_SCAN_STOPPED);
251 break;
252
253 /* Scan completed on A band */
254 case SCAN_ISS_A_BAND:
255 /* mark that immediate scan is not running */
256 pScanMngr->immedScanState = SCAN_ISS_IDLE;
257 #ifdef TI_DBG
258 pScanMngr->stats.ImmediateAByStatus[ resultStatus ]++;
259 #endif
260 /* otherwise, notify the roaming manager of the scan complete */
261 scanMngr_immediateScanComplete(hScanMngr,SCAN_MRS_SCAN_COMPLETE_OK);
262 break;
263
264 default:
265 /* should not be at any other stage when CB is invoked */
266 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Immediate scan CB called with scan complete TI_OK reason in state:%d", pScanMngr->immedScanState);
267
268 /* reset continuous scan to idle */
269 pScanMngr->immedScanState = SCAN_ISS_IDLE;
270 break;
271 }
272 break;
273
274 /* scan was completed due to an error! */
275 default:
276 #ifdef TI_DBG
277 switch (pScanMngr->immedScanState)
278 {
279 case SCAN_ISS_G_BAND:
280 pScanMngr->stats.ImmediateGByStatus[ resultStatus ]++;
281 break;
282
283 case SCAN_ISS_A_BAND:
284 pScanMngr->stats.ImmediateAByStatus[ resultStatus ]++;
285 break;
286
287 default:
288 break;
289 }
290 #endif
291 /* mark that immediate scan is not running */
292 pScanMngr->immedScanState = SCAN_ISS_IDLE;
293 scanMngr_immediateScanComplete(hScanMngr,scanMngrConvertResultStatus(resultStatus));
294 break;
295 }
296 }
297
298 /**
299 * \\n
300 * \date 01-Mar-2005\n
301 * \brief Callback used by the scan concentrator for continuous scan result.\n
302 *
303 * Function Scope \e Public.\n
304 * \param hScanMngr - handle to the scan manager object.\n
305 * \param resultStatus - reason for calling this function (frame received / scan complete).\n
306 * \param frameInfo - frame related info (in case of a frame reception).\n
307 * \param SPSStatus - bitmap indicating which channels were scan, in case of an SPS scan.\n
308 */
scanMngr_contScanCB(TI_HANDLE hScanMngr,EScanCncnResultStatus resultStatus,TScanFrameInfo * frameInfo,TI_UINT16 SPSStatus)309 void scanMngr_contScanCB( TI_HANDLE hScanMngr, EScanCncnResultStatus resultStatus,
310 TScanFrameInfo* frameInfo, TI_UINT16 SPSStatus )
311 {
312 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
313 TScanBandPolicy *aPolicy;
314 EScanCncnResultStatus nextResultStatus;
315
316 TRACE3( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_contScanCB called, hScanMngr=0x%x, resultStatus=%d, SPSStatus=%d\n", hScanMngr, resultStatus, SPSStatus);
317
318 switch (resultStatus)
319 {
320 /* frame received - update BSS list accordingly */
321 case SCAN_CRS_RECEIVED_FRAME:
322 scanMngrUpdateReceivedFrame( hScanMngr, frameInfo );
323 break;
324
325 /* scan was completed successfully - either continue to next stage or simply finish this cycle */
326 case SCAN_CRS_SCAN_COMPLETE_OK:
327 #ifdef SCAN_MNGR_DBG
328 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Continuous scan completes successfuly.\n");
329 scanMngrDebugPrintBSSList( hScanMngr );
330 #endif
331 #ifdef TI_DBG
332 if ( SCAN_TYPE_SPS == pScanMngr->scanParams.scanType )
333 {
334 int i;
335
336 /*update SPS channels attendant statistics */
337 for ( i = 0; i < pScanMngr->scanParams.numOfChannels; i++ )
338 {
339 if ( TI_FALSE == WAS_SPS_CHANNEL_ATTENDED( SPSStatus, i ))
340 {
341 pScanMngr->stats.SPSChannelsNotAttended[ i ]++;
342 }
343 }
344 }
345 #endif
346
347 /* first, remove APs that were not tracked. Note that this function does NOT
348 increase the retry counter, and therefore there's no harm in calling it even if only
349 some of the APs were searched in the previous tracking command, or previous command was
350 discovery */
351 scanMngrPerformAging( hScanMngr );
352
353
354 /* if new BSS's were found (or enough scan iterations passed w/o finding any), notify the roaming manager */
355 if ( ((TI_TRUE == pScanMngr->bNewBSSFound) ||
356 (SCAN_MNGR_CONSEC_SCAN_ITER_FOR_PRE_AUTH < pScanMngr->consecNotFound)) &&
357 (pScanMngr->BSSList.numOfEntries > 0)) /* in case no AP was found for specified iterations number,
358 but no AP is present, and so is pre-auth */
359 {
360 pScanMngr->bNewBSSFound = TI_FALSE;
361 pScanMngr->consecNotFound = 0;
362 roamingMngr_updateNewBssList( pScanMngr->hRoamingMngr, (bssList_t*)&(pScanMngr->BSSList));
363
364 if (SCANNING_OPERATIONAL_MODE_MANUAL == pScanMngr->scanningOperationalMode)
365 {
366 scanMngr_reportContinuousScanResults(hScanMngr, resultStatus);
367 }
368 }
369
370 /* act according to continuous scan state */
371 switch (pScanMngr->contScanState)
372 {
373 case SCAN_CSS_TRACKING_G_BAND:
374 #ifdef TI_DBG
375 pScanMngr->stats.TrackingGByStatus[ resultStatus ]++;
376 #endif
377 TRACE0(pScanMngr->hReport , REPORT_SEVERITY_INFORMATION, "\n Starting SCAN_CSS_TRACKING_G_BAND \n");
378 /* if necessary, attempt tracking on A */
379 aPolicy = scanMngrGetPolicyByBand( hScanMngr, RADIO_BAND_5_0_GHZ );
380 /* if a policy is defined for A band tracking, attempt to perform it */
381 if ( (NULL != aPolicy) &&
382 (SCAN_TYPE_NO_SCAN != aPolicy->trackingMethod.scanType))
383 {
384 /* recalculate current TSF, to adjust the TSF read at the beginning of
385 the continuous scan process with the tracking on G duration */
386 pScanMngr->currentTSF +=
387 ((os_timeStampMs( pScanMngr->hOS ) - pScanMngr->currentHostTimeStamp) * 1000);
388
389 /* build scan command */
390 scanMngrBuildTrackScanCommand( hScanMngr, aPolicy, RADIO_BAND_5_0_GHZ );
391
392 /* if channels are available for tracking on A */
393 if ( 0 < pScanMngr->scanParams.numOfChannels )
394 {
395 /* mark that continuous scan is now tracking on A */
396 pScanMngr->contScanState = SCAN_CSS_TRACKING_A_BAND;
397
398 /* send scan command */
399 nextResultStatus =
400 scanCncn_Start1ShotScan( pScanMngr->hScanCncn, SCAN_SCC_ROAMING_CONT, &(pScanMngr->scanParams));
401 if ( SCAN_CRS_SCAN_RUNNING != nextResultStatus )
402 {
403 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Failed to start tracking continuous scan on band A, return code %d.\n", resultStatus);
404 #ifdef TI_DBG
405 pScanMngr->stats.TrackingAByStatus[ nextResultStatus ]++;
406 #endif
407 pScanMngr->contScanState = SCAN_CSS_IDLE;
408 }
409 #ifdef SCAN_MNGR_DBG
410 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Tracking on A started.\n");
411 #endif
412 return;
413 }
414 }
415 /* in case a TSF error was received on last continuous scan cycle, mark (now, that tracking
416 on both bands was attempted), that TSF values are synchronized */
417 pScanMngr->bSynchronized = TI_TRUE;
418
419 /* the break is missing on purpose: if tracking on A was not successful (or not needed), continue to discovery */
420
421 case SCAN_CSS_TRACKING_A_BAND:
422 #ifdef TI_DBG
423 /* update stats - since there's no break above, we must check that the state is indeed tracking on A */
424 if ( SCAN_CSS_TRACKING_A_BAND == pScanMngr->contScanState )
425 {
426 pScanMngr->stats.TrackingAByStatus[ resultStatus ]++;
427 }
428 #endif
429 TRACE0(pScanMngr->hReport , REPORT_SEVERITY_INFORMATION, "\n SCAN_CSS_TRACKING_A_BAND \n");
430 /* if necessary and possible, attempt discovery */
431 if ( (SCAN_SDP_NO_DISCOVERY != pScanMngr->currentDiscoveryPart) &&
432 (pScanMngr->BSSList.numOfEntries <= pScanMngr->scanPolicy.BSSNumberToStartDiscovery))
433 {
434 /* build scan command */
435 scanMngrBuildDiscoveryScanCommand( hScanMngr );
436
437 /* if channels are available for discovery */
438 if ( 0 < pScanMngr->scanParams.numOfChannels )
439 {
440 /* mark that continuous scan is now in discovery state */
441 pScanMngr->contScanState = SCAN_CSS_DISCOVERING;
442
443 /* mark that no new APs were discovered in this discovery operation */
444 pScanMngr->bNewBSSFound = TI_FALSE;
445
446 /* send scan command */
447 nextResultStatus =
448 scanCncn_Start1ShotScan( pScanMngr->hScanCncn, SCAN_SCC_ROAMING_CONT, &(pScanMngr->scanParams));
449 if ( SCAN_CRS_SCAN_RUNNING != nextResultStatus )
450 {
451 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Failed to start discovery continuous scan, nextResultStatus %d.\n", nextResultStatus);
452 pScanMngr->contScanState = SCAN_CSS_IDLE;
453 }
454 #ifdef SCAN_MNGR_DBG
455 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Disocvery started.\n");
456 #endif
457 return;
458 }
459 }
460
461 /* the break is missing on purpose: if discovery was not successful (or not needed), finish scan cycle */
462
463 case SCAN_CSS_DISCOVERING:
464 #ifdef TI_DBG
465 /* update stats - since there's no break above, we must check that the state is indeed discocery */
466 if ( SCAN_CSS_DISCOVERING == pScanMngr->contScanState )
467 {
468 if ( RADIO_BAND_2_4_GHZ == pScanMngr->statsLastDiscoveryBand )
469 {
470 pScanMngr->stats.DiscoveryGByStatus[ resultStatus ]++;
471 }
472 else
473 {
474 pScanMngr->stats.DiscoveryAByStatus[ resultStatus ]++;
475 }
476 }
477 #endif
478 /* continuous scan cycle is complete */
479 pScanMngr->contScanState = SCAN_CSS_IDLE;
480
481 break;
482
483 case SCAN_CSS_STOPPING:
484 /* continuous scan cycle is complete */
485 pScanMngr->contScanState = SCAN_CSS_IDLE;
486 break;
487
488 default:
489 /* should not be at any other stage when CB is invoked */
490 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Continuous scan CB called with scan complete TI_OK reason in state:%d\n", pScanMngr->contScanState);
491
492 /* reset continuous scan to idle */
493 pScanMngr->contScanState = SCAN_CSS_IDLE;
494 pScanMngr->bNewBSSFound = TI_FALSE;
495 break;
496 }
497 break;
498
499 /* SPS scan was completed with TSF error */
500 case SCAN_CRS_TSF_ERROR:
501 /* report the recovery event */
502 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Continuous scan callback called with TSF error indication\n");
503 /* mark that the TSF values are no longer valid */
504 pScanMngr->bSynchronized = TI_FALSE;
505 #ifdef TI_DBG
506 switch ( pScanMngr->contScanState )
507 {
508 case SCAN_CSS_TRACKING_G_BAND:
509 pScanMngr->stats.TrackingGByStatus[ resultStatus ]++;
510 break;
511
512 case SCAN_CSS_TRACKING_A_BAND:
513 pScanMngr->stats.TrackingAByStatus[ resultStatus ]++;
514 break;
515
516 default:
517 break;
518 }
519 #endif
520 /* stop continuous scan cycle for this time (to avoid tracking using discovery only on A, thus
521 having mixed results - some are synchronized, some are not */
522 pScanMngr->contScanState = SCAN_CSS_IDLE;
523 break;
524
525 default:
526 /* report the status received */
527 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Continuous scan CB called with status %d\n", resultStatus);
528
529 /* also perform aging (since it does not increase counter, no harm done if this was not tracking */
530 scanMngrPerformAging( hScanMngr );
531 #ifdef TI_DBG
532 switch ( pScanMngr->contScanState )
533 {
534 case SCAN_CSS_TRACKING_G_BAND:
535 pScanMngr->stats.TrackingGByStatus[ resultStatus ]++;
536 break;
537
538 case SCAN_CSS_TRACKING_A_BAND:
539 pScanMngr->stats.TrackingAByStatus[ resultStatus ]++;
540 break;
541
542 case SCAN_CSS_DISCOVERING:
543 if ( RADIO_BAND_2_4_GHZ == pScanMngr->statsLastDiscoveryBand )
544 {
545 pScanMngr->stats.DiscoveryGByStatus[ resultStatus ]++;
546 }
547 else
548 {
549 pScanMngr->stats.DiscoveryGByStatus[ resultStatus ]++;
550 }
551 default:
552 break;
553 }
554 #endif
555 /* finish scan for this iteration */
556 pScanMngr->contScanState = SCAN_CSS_IDLE;
557 break;
558 }
559 }
560
561 /**
562 * \\n
563 * \date 01-Mar-2005\n
564 * \brief Sets the scan policy.\n
565 *
566 * Function Scope \e Public.\n
567 * \param hScanMngr - handle to the scan manager object.\n
568 * \param scanPolicy - a pointer to the policy data.\n
569 */
scanMngr_setScanPolicy(TI_HANDLE hScanMngr,TScanPolicy * scanPolicy)570 void scanMngr_setScanPolicy( TI_HANDLE hScanMngr, TScanPolicy* scanPolicy )
571 {
572 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
573
574 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_setScanPolicy called, hScanMngr=0x%x.\n", hScanMngr);
575 #ifdef SCAN_MNGR_DBG
576 scanMngrTracePrintScanPolicy( scanPolicy );
577 #endif
578
579 /* if continuous or immediate scan are running, indicate that they shouldn't proceed to next scan (if any),
580 and stop the scan operation (in case a triggered scan was in progress and the voice was stopped, the scan
581 must be stopped or a recovery will occur */
582 if ( pScanMngr->contScanState != SCAN_CSS_IDLE )
583 {
584 pScanMngr->contScanState = SCAN_CSS_STOPPING;
585 scanCncn_StopScan( pScanMngr->hScanCncn, SCAN_SCC_ROAMING_CONT );
586 }
587 if ( pScanMngr->immedScanState != SCAN_ISS_IDLE )
588 {
589 pScanMngr->immedScanState = SCAN_ISS_STOPPING;
590 scanCncn_StopScan( pScanMngr->hScanCncn, SCAN_SCC_ROAMING_IMMED );
591 }
592
593 /* set new scan policy */
594 os_memoryCopy( pScanMngr->hOS, &(pScanMngr->scanPolicy), scanPolicy, sizeof(TScanPolicy));
595
596 /* remove all tracked APs that are not on a policy defined channel (neighbor APs haven't changed,
597 so there's no need to check them */
598 scanMngrUpdateBSSList( hScanMngr, TI_FALSE, TI_TRUE );
599
600 /* if continuous scan timer is running, stop it */
601 if (pScanMngr->bTimerRunning)
602 {
603 tmr_StopTimer (pScanMngr->hContinuousScanTimer);
604 pScanMngr->bTimerRunning = TI_FALSE;
605 }
606
607 /* if continuous scan was started, start the timer using the new intervals */
608 if (pScanMngr->bContinuousScanStarted)
609 {
610 TI_UINT32 uTimeout = pScanMngr->bLowQuality ?
611 pScanMngr->scanPolicy.deterioratingScanInterval :
612 pScanMngr->scanPolicy.normalScanInterval;
613
614 pScanMngr->bTimerRunning = TI_TRUE;
615
616 tmr_StartTimer (pScanMngr->hContinuousScanTimer,
617 scanMngr_GetUpdatedTsfDtimMibForScan,
618 (TI_HANDLE)pScanMngr,
619 uTimeout,
620 TI_TRUE);
621 }
622
623 /* reset discovery counters */
624 pScanMngr->neighborAPsDiscoveryIndex[ RADIO_BAND_2_4_GHZ ] = 0;
625 pScanMngr->neighborAPsDiscoveryIndex[ RADIO_BAND_5_0_GHZ ] = 0;
626 pScanMngr->channelDiscoveryIndex[ RADIO_BAND_2_4_GHZ ] = 0;
627 pScanMngr->channelDiscoveryIndex[ RADIO_BAND_5_0_GHZ ] = 0;
628 /* set current discovery part to first part */
629 pScanMngr->currentDiscoveryPart = SCAN_SDP_NEIGHBOR_G;
630 /* now advance discovery part to first valid part */
631 scanMngrSetNextDiscoveryPart( hScanMngr );
632 }
633
634 /**
635 * \\n
636 * \date 06-Feb-2006\n
637 * \brief CB function for current TSF and last beacon TSF and DTIM read.\n
638 *
639 * Function Scope \e Public.\n
640 * \param hScanMngr - handle to the scan manager object.\n
641 * \param status - read status (TI_OK / TI_NOK).\n
642 * \param CB_buf - a pointer to the data read.\n
643 */
scanMngrGetCurrentTsfDtimMibCB(TI_HANDLE hScanMngr,TI_STATUS status,TI_UINT8 * CB_buf)644 void scanMngrGetCurrentTsfDtimMibCB(TI_HANDLE hScanMngr, TI_STATUS status, TI_UINT8* CB_buf)
645 {
646 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
647
648 os_memoryCopy(pScanMngr->hOS, (TI_UINT8*)&(pScanMngr->currTsfDtimMib), CB_buf, sizeof(TTsfDtim));
649
650 /* set the current TSF and last beacon TSF and DTIM count */
651 INT64_HIGHER( pScanMngr->currentTSF ) = pScanMngr->currTsfDtimMib.CurrentTSFHigh;
652 INT64_LOWER( pScanMngr->currentTSF ) = pScanMngr->currTsfDtimMib.CurrentTSFLow;
653
654 INT64_HIGHER( pScanMngr->lastLocalBcnTSF ) = pScanMngr->currTsfDtimMib.lastTBTTHigh;
655 INT64_LOWER( pScanMngr->lastLocalBcnTSF ) = pScanMngr->currTsfDtimMib.lastTBTTLow;
656
657 pScanMngr->lastLocalBcnDTIMCount = pScanMngr->currTsfDtimMib.LastDTIMCount;
658
659 TRACE5( pScanMngr->hReport , REPORT_SEVERITY_INFORMATION, "\n currentTSF = %u-%u lastLocalBcnTSF = %u-%u lastDTIMCount = %d \n", INT64_HIGHER( pScanMngr->currentTSF ), INT64_LOWER( pScanMngr->currentTSF ), INT64_HIGHER( pScanMngr->lastLocalBcnTSF ), INT64_LOWER( pScanMngr->lastLocalBcnTSF ), pScanMngr->lastLocalBcnDTIMCount );
660
661 /* get the current host time stamp */
662 pScanMngr->currentHostTimeStamp = os_timeStampMs( pScanMngr->hOS );
663
664 /* now that the current TSF and last beacon TSF had been retrieved from the FW,
665 continuous scan may proceed */
666 scanMngrPerformContinuousScan(hScanMngr);
667 }
668
669 /**
670 * \\n
671 * \date 06-Feb-2006\n
672 * \brief requests current TSF and last beacon TSF and DTIM from the FW.\n
673 *
674 * Function Scope \e Public.\n
675 * \param hScanMngr - handle to the scan manager object.\n
676 * \param bTwdInitOccured - Indicates if TWDriver recovery occured since timer started.\n
677 */
scanMngr_GetUpdatedTsfDtimMibForScan(TI_HANDLE hScanMngr,TI_BOOL bTwdInitOccured)678 void scanMngr_GetUpdatedTsfDtimMibForScan (TI_HANDLE hScanMngr, TI_BOOL bTwdInitOccured)
679 {
680 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
681 TTwdParamInfo param;
682 TI_STATUS reqStatus = TI_OK;
683
684 TRACE0( pScanMngr->hReport , REPORT_SEVERITY_INFORMATION, "\nscanMngr_GetUpdatedTsfDtimMibForScan called\n");
685
686 /* Getting the current TSF and DTIM values */
687 param.paramType = TWD_TSF_DTIM_MIB_PARAM_ID;
688 param.content.interogateCmdCBParams.fCb = (void *)scanMngrGetCurrentTsfDtimMibCB;
689 param.content.interogateCmdCBParams.hCb = hScanMngr;
690 param.content.interogateCmdCBParams.pCb = (TI_UINT8*)&pScanMngr->currTsfDtimMib;
691 reqStatus = TWD_GetParam (pScanMngr->hTWD, ¶m);
692 if ( TI_OK != reqStatus )
693 {
694 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_ERROR, ": getParam from HAL CTRL failed wih status: %d\n", reqStatus);
695 }
696 }
697
698 /**
699 * \\n
700 * \date 01-Mar-2005\n
701 * \brief Starts a continuous scan operation.\n
702 *
703 * Function Scope \e Private.\n
704 * \param hScanMngr - handle to the scan manager object.\n
705 */
scanMngrPerformContinuousScan(TI_HANDLE hScanMngr)706 void scanMngrPerformContinuousScan( TI_HANDLE hScanMngr )
707 {
708
709 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
710 TScanBandPolicy *gPolicy, *aPolicy;
711 EScanCncnResultStatus resultStatus;
712 paramInfo_t param;
713
714 #ifdef SCAN_MNGR_DBG
715 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngrPerformContinuousScan called, hScanMngr=0x%x.\n", hScanMngr);
716 scanMngrDebugPrintBSSList( hScanMngr );
717 #endif
718
719 /* this function is called due to continuous scan timer expiry, to start a new continuous scan cycle.
720 If the continuous scan is anything but idle, a new cycle is not started. */
721 if ( SCAN_CSS_IDLE != pScanMngr->contScanState )
722 {
723 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Continuous scan timer expired and continuous scan state is:%d\n", pScanMngr->contScanState);
724 return;
725 }
726
727 /* retrieve the current BSS DTIM period and beacon interval, for SPS DTIM avoidance
728 calculations later. This is done before the continuous scan process is started,
729 to check that they are not zero (in case the STA disconnected and somehow the
730 scan manager was not notified of the event). If the STA disconnected, the continuous
731 scan process is aborted */
732 param.paramType = SITE_MGR_BEACON_INTERVAL_PARAM;
733 siteMgr_getParam( pScanMngr->hSiteMngr, ¶m );
734 pScanMngr->currentBSSBeaconInterval = param.content.beaconInterval;
735
736 param.paramType = SITE_MGR_DTIM_PERIOD_PARAM;
737 siteMgr_getParam( pScanMngr->hSiteMngr, ¶m );
738 pScanMngr->currentBSSDtimPeriod = param.content.siteMgrDtimPeriod;
739
740 /* now check that none of the above is zero */
741 if ( (0 == pScanMngr->currentBSSBeaconInterval) || (0 == pScanMngr->currentBSSDtimPeriod))
742 {
743 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_ERROR, "Trying to start continuous scan cycle but DTIM period=%d and beacon interval=%d\n", pScanMngr->currentBSSDtimPeriod, pScanMngr->currentBSSBeaconInterval);
744 return;
745 }
746
747 /* increase the consecutive not found counter */
748 pScanMngr->consecNotFound++;
749
750 /* first try tracking on G */
751 gPolicy = scanMngrGetPolicyByBand( hScanMngr, RADIO_BAND_2_4_GHZ );
752 /* if a policy is defined for G band tracking, attempt to perform it */
753 if ( (NULL != gPolicy) &&
754 (SCAN_TYPE_NO_SCAN != gPolicy->trackingMethod.scanType))
755 {
756 /* build scan command */
757 scanMngrBuildTrackScanCommand( hScanMngr, gPolicy, RADIO_BAND_2_4_GHZ );
758
759 /* if channels are available for tracking on G */
760 if ( 0 < pScanMngr->scanParams.numOfChannels )
761 {
762 /* mark that continuous scan is now tracking on G */
763 pScanMngr->contScanState = SCAN_CSS_TRACKING_G_BAND;
764
765 /* send scan command to scan concentrator with the required scan params according to scannig operational mode */
766 resultStatus = scanMngr_Start1ShotScan(hScanMngr, SCAN_SCC_ROAMING_CONT);
767 if ( SCAN_CRS_SCAN_RUNNING != resultStatus )
768 {
769 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Failed to start tracking continuous scan on G, return code %d.\n", resultStatus);
770 #ifdef TI_DBG
771 pScanMngr->stats.TrackingGByStatus[ resultStatus ]++;
772 #endif
773 pScanMngr->contScanState = SCAN_CSS_IDLE;
774 }
775 #ifdef SCAN_MNGR_DBG
776 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Tracking on G started.\n");
777 #endif
778 return;
779 }
780 }
781
782 /* if not, try tracking on A */
783 aPolicy = scanMngrGetPolicyByBand( hScanMngr, RADIO_BAND_5_0_GHZ );
784 /* if a policy is defined for A band tracking, attempt to perform it */
785 if ( (NULL != aPolicy) &&
786 (SCAN_TYPE_NO_SCAN != aPolicy->trackingMethod.scanType))
787 {
788 /* build scan command */
789 scanMngrBuildTrackScanCommand( hScanMngr, aPolicy, RADIO_BAND_5_0_GHZ );
790
791 /* if channels are available for tracking on A */
792 if ( 0 < pScanMngr->scanParams.numOfChannels )
793 {
794 /* mark that continuous scan is now tracking on A */
795 pScanMngr->contScanState = SCAN_CSS_TRACKING_A_BAND;
796
797 /* send scan command to scan concentrator with the required scan params according to scanning operational mode */
798 resultStatus = scanMngr_Start1ShotScan(hScanMngr, SCAN_SCC_ROAMING_CONT);
799 if ( SCAN_CRS_SCAN_RUNNING != resultStatus )
800 {
801 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Failed to start tracking continuous scan on A, return code %d.\n", resultStatus);
802 #ifdef TI_DBG
803 pScanMngr->stats.TrackingAByStatus[ resultStatus ]++;
804 #endif
805 pScanMngr->contScanState = SCAN_CSS_IDLE;
806 }
807 #ifdef SCAN_MNGR_DBG
808 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Tracking on A started.\n");
809 #endif
810 return;
811 }
812 }
813 /* in case a TSF error was received on last continuous scan cycle, mark (now, that tracking
814 on both bands was attempted), that TSF values are synchronized */
815 pScanMngr->bSynchronized = TI_TRUE;
816
817 /* if this does not work as well, try discovery */
818 /* discovery can be performed if discovery part is valid (this is maintained whenever a new policy or neighbor AP list
819 is set, a discovery scan command is built, and a new neighbor AP is discovered) */
820 if ( (SCAN_SDP_NO_DISCOVERY != pScanMngr->currentDiscoveryPart) &&
821 (pScanMngr->BSSList.numOfEntries <= pScanMngr->scanPolicy.BSSNumberToStartDiscovery))
822 {
823 /* build scan command */
824 scanMngrBuildDiscoveryScanCommand( hScanMngr );
825
826 /* if channels are available for discovery */
827 if ( 0 < pScanMngr->scanParams.numOfChannels )
828 {
829 /* mark that continuous scan is now in discovery state */
830 pScanMngr->contScanState = SCAN_CSS_DISCOVERING;
831
832 /* mark that no new BSS's were found (yet) */
833 pScanMngr->bNewBSSFound = TI_FALSE;
834
835 /* send scan command to scan concentrator with the required scan params according to scanning operational mode */
836 resultStatus = scanMngr_Start1ShotScan(hScanMngr, SCAN_SCC_ROAMING_CONT);
837 if ( SCAN_CRS_SCAN_RUNNING != resultStatus )
838 {
839 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Failed to start discovery continuous scan, resultStatus %d.\n", resultStatus);
840 #ifdef TI_DBG
841 if ( RADIO_BAND_2_4_GHZ == pScanMngr->statsLastDiscoveryBand )
842 {
843 pScanMngr->stats.DiscoveryGByStatus[ resultStatus ]++;
844 }
845 else
846 {
847 pScanMngr->stats.DiscoveryAByStatus[ resultStatus ]++;
848 }
849 #endif
850 pScanMngr->contScanState = SCAN_CSS_IDLE;
851 }
852 #ifdef SCAN_MNGR_DBG
853 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Discovery started.\n");
854 #endif
855 return;
856 }
857 }
858
859 /* if we got here, no scan had executed successfully - print a warning */
860 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Unable to perform continuous scan.\n");
861 }
862
863 /**
864 * \\n
865 * \date 01-Mar-2005\n
866 * \brief Perform aging on the BSS list.\n
867 *
868 * Function Scope \e Private.\n
869 * \param hScanMngr - handle to the scan manager object.\n
870 */
scanMngrPerformAging(TI_HANDLE hScanMngr)871 void scanMngrPerformAging( TI_HANDLE hScanMngr )
872 {
873 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
874 TI_UINT8 BSSEntryIndex;
875
876 #ifdef SCAN_MNGR_DBG
877 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Performing Aging.\n");
878 #endif
879 /* loop on all entries in the BSS list */
880 for ( BSSEntryIndex = 0; BSSEntryIndex < pScanMngr->BSSList.numOfEntries; )
881 {
882 /* if an entry failed enough consecutive track attempts - remove it */
883 if ( pScanMngr->BSSList.scanBSSList[ BSSEntryIndex ].trackFailCount >
884 pScanMngr->scanPolicy.maxTrackFailures )
885 {
886 /* will replace this entry with one further down the array, if any. Therefore, index is not increased
887 (because a new entry will be placed in the same index). If this is the last entry - the number of
888 BSSes will be decreased, and thus the loop will exit */
889 #ifdef SCAN_MNGR_DBG
890 TRACE7( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Aging: removing BSSID %2x:%2x:%2x:%2x:%2x:%2x from index: %d.\n", pScanMngr->BSSList.BSSList[ BSSEntryIndex ].BSSID[ 0 ], pScanMngr->BSSList.BSSList[ BSSEntryIndex ].BSSID[ 1 ], pScanMngr->BSSList.BSSList[ BSSEntryIndex ].BSSID[ 2 ], pScanMngr->BSSList.BSSList[ BSSEntryIndex ].BSSID[ 3 ], pScanMngr->BSSList.BSSList[ BSSEntryIndex ].BSSID[ 4 ], pScanMngr->BSSList.BSSList[ BSSEntryIndex ].BSSID[ 5 ], pScanMngr->BSSList.numOfEntries);
891 #endif
892 scanMngrRemoveBSSListEntry( hScanMngr, BSSEntryIndex );
893 }
894 else
895 {
896 BSSEntryIndex++;
897 }
898 }
899 }
900
901 /**
902 * \\n
903 * \date 01-Mar-2005\n
904 * \brief Updates object data according to a received frame.\n
905 *
906 * Function Scope \e Private.\n
907 * \param hScanMngr - handle to the scan manager object.\n
908 * \param frameInfo - pointer to frame related information.\n
909 */
scanMngrUpdateReceivedFrame(TI_HANDLE hScanMngr,TScanFrameInfo * frameInfo)910 void scanMngrUpdateReceivedFrame( TI_HANDLE hScanMngr, TScanFrameInfo* frameInfo )
911 {
912 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
913 int BSSListIndex, neighborAPIndex;
914 TScanBandPolicy* pBandPolicy;
915
916 #ifdef SCAN_MNGR_DBG
917 scanMngrDebugPrintReceivedFrame( hScanMngr, frameInfo );
918 #endif
919 #ifdef TI_DBG
920 pScanMngr->stats.receivedFrames++;
921 #endif
922 /* first check if the frame pass RSSI threshold. If not discard it and continue */
923 pBandPolicy = scanMngrGetPolicyByBand( hScanMngr, frameInfo->band );
924 if ( NULL == pBandPolicy ) /* sanity checking */
925 {
926 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_ERROR, "Recieved framed on band %d, for which policy is not defined!\n", frameInfo->band);
927 #ifdef TI_DBG
928 pScanMngr->stats.discardedFramesOther++;
929 #endif
930 return;
931 }
932
933 if ( frameInfo->rssi < pBandPolicy->rxRSSIThreshold )
934 {
935 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Discarding frame beacuse RSSI %d is lower than threshold %d\n", frameInfo->rssi, pBandPolicy->rxRSSIThreshold);
936 #ifdef TI_DBG
937 pScanMngr->stats.discardedFramesLowRSSI++;
938 #endif
939 return;
940 }
941
942 /* search for this AP in the tracking list */
943 BSSListIndex = scanMngrGetTrackIndexByBssid( hScanMngr, frameInfo->bssId );
944
945 /* if the frame received from an AP in the track list */
946 if ( -1 != BSSListIndex )
947 {
948 scanMngrUpdateBSSInfo( hScanMngr, BSSListIndex, frameInfo );
949 }
950 /* otherwise, if the list is not full and AP is either a neighbor AP or on a policy defined channel: */
951 else
952 {
953 neighborAPIndex = scanMngrGetNeighborAPIndex( hScanMngr, frameInfo->band, frameInfo->bssId );
954
955 if ( (pScanMngr->BSSList.numOfEntries < pScanMngr->scanPolicy.BSSListSize) &&
956 ((TI_TRUE == scanMngrIsPolicyChannel( hScanMngr, frameInfo->band, frameInfo->channel )) ||
957 (-1 != neighborAPIndex)))
958 {
959 /* insert the AP to the list */
960 scanMngrInsertNewBSSToTrackingList( hScanMngr, frameInfo );
961
962 /* if this is a neighbor AP */
963 if ( -1 != neighborAPIndex )
964 {
965 /* mark in the neighbor AP list that it's being tracked */
966 pScanMngr->neighborAPsDiscoveryList[ frameInfo->band ].trackStatusList[ neighborAPIndex ] = SCAN_NDS_DISCOVERED;
967
968 /* if the discovery index for this neighbor AP band points to this AP,
969 advance it and advance discovery part if needed */
970 if ( pScanMngr->neighborAPsDiscoveryIndex[ frameInfo->band ] == neighborAPIndex )
971 {
972 do {
973 pScanMngr->neighborAPsDiscoveryIndex[ frameInfo->band ]++; /* advance discovery index */
974 /* while discovery list is not exhausted and no AP for discovery is found */
975 } while ( (pScanMngr->neighborAPsDiscoveryIndex[ frameInfo->band ] < pScanMngr->neighborAPsDiscoveryList[ frameInfo->band ].numOfEntries) &&
976 (SCAN_NDS_NOT_DISCOVERED != pScanMngr->neighborAPsDiscoveryList[ frameInfo->band ].trackStatusList[ pScanMngr->neighborAPsDiscoveryIndex[ frameInfo->band ] ]));
977 /* if discovery list isexhausted */
978 if ( pScanMngr->neighborAPsDiscoveryIndex[ frameInfo->band ] == pScanMngr->neighborAPsDiscoveryList[ frameInfo->band ].numOfEntries )
979 {
980 /* restart discovery cycle for this band's neighbor APs */
981 pScanMngr->neighborAPsDiscoveryIndex[ frameInfo->band ] = 0;
982 /* set new discovery part (if needed) */
983 scanMngrSetNextDiscoveryPart( hScanMngr );
984 }
985 }
986 }
987 }
988 #ifdef TI_DBG
989 else
990 {
991 pScanMngr->stats.discardedFramesOther++;
992 }
993 #endif
994 }
995 }
996
997 /**
998 * \\n
999 * \date 17-Mar-2005\n
1000 * \brief Cerate a new tracking entry and store the newly discovered AP info in it.\n
1001 *
1002 * Function Scope \e Private.\n
1003 * \param hScanMngr - handle to the scan manager object.\n
1004 * \param frameInfo - a pointer to the information received from this AP.\n
1005 */
scanMngrInsertNewBSSToTrackingList(TI_HANDLE hScanMngr,TScanFrameInfo * frameInfo)1006 void scanMngrInsertNewBSSToTrackingList( TI_HANDLE hScanMngr, TScanFrameInfo* frameInfo )
1007 {
1008 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
1009 #ifdef SCAN_SPS_USE_DRIFT_COMPENSATION
1010 int i;
1011 #endif
1012
1013 /* mark that a new AP was discovered (for discovery stage) */
1014 pScanMngr->bNewBSSFound = TI_TRUE;
1015
1016 /* insert fields that are not update regulary */
1017 pScanMngr->BSSList.BSSList[ pScanMngr->BSSList.numOfEntries ].bNeighborAP =
1018 ( -1 == scanMngrGetNeighborAPIndex( hScanMngr, frameInfo->band, frameInfo->bssId ) ?
1019 TI_FALSE :
1020 TI_TRUE );
1021 MAC_COPY (pScanMngr->BSSList.BSSList[pScanMngr->BSSList.numOfEntries].BSSID, *(frameInfo->bssId));
1022
1023 /* initialize average RSSI value */
1024 pScanMngr->BSSList.BSSList[ pScanMngr->BSSList.numOfEntries ].RSSI = frameInfo->rssi;
1025 pScanMngr->BSSList.BSSList[ pScanMngr->BSSList.numOfEntries ].lastRSSI = frameInfo->rssi;
1026
1027 #ifdef SCAN_SPS_USE_DRIFT_COMPENSATION
1028 /* initialize previous delta change array (used for SPS drift compensation) */
1029 pScanMngr->BSSList.scanBSSList[ pScanMngr->BSSList.numOfEntries ].prevTSFDelta = 0;
1030 pScanMngr->BSSList.scanBSSList[ pScanMngr->BSSList.numOfEntries ].deltaChangeArrayIndex = 0;
1031 for ( i = 0; i < SCAN_SPS_NUM_OF_TSF_DELTA_ENTRIES; i++ )
1032 {
1033 pScanMngr->BSSList.scanBSSList[ pScanMngr->BSSList.numOfEntries ].deltaChangeArray[ i ] = 0;
1034 }
1035 #endif
1036
1037 /* update regular fields */
1038 pScanMngr->BSSList.scanBSSList[ pScanMngr->BSSList.numOfEntries ].trackFailCount = 0; /* for correct statistics update */
1039 scanMngrUpdateBSSInfo( hScanMngr, pScanMngr->BSSList.numOfEntries, frameInfo );
1040
1041 /* increase the number of tracked APs */
1042 pScanMngr->BSSList.numOfEntries++;
1043 }
1044
1045 /**
1046 * \\n
1047 * \date 17-Mar-2005\n
1048 * \brief Updates tracked AP information.\n
1049 *
1050 * Function Scope \e Private.\n
1051 * \param hScanMngr - handle to the scan manager object.\n
1052 * \param BSSListIndex - index to the BSS list where the AP information is stored.\n
1053 * \param frameInfo - a pointer to the information received from this AP.\n
1054 */
scanMngrUpdateBSSInfo(TI_HANDLE hScanMngr,TI_UINT8 BSSListIndex,TScanFrameInfo * frameInfo)1055 void scanMngrUpdateBSSInfo( TI_HANDLE hScanMngr, TI_UINT8 BSSListIndex, TScanFrameInfo* frameInfo )
1056 {
1057 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
1058
1059 /* update AP data */
1060 pScanMngr->BSSList.BSSList[ BSSListIndex ].lastRxHostTimestamp = os_timeStampMs( pScanMngr->hOS );
1061 pScanMngr->BSSList.BSSList[ BSSListIndex ].resultType = (frameInfo->parsedIEs->subType == BEACON) ? SCAN_RFT_BEACON : SCAN_RFT_PROBE_RESPONSE;
1062 pScanMngr->BSSList.BSSList[ BSSListIndex ].band = frameInfo->band;
1063 pScanMngr->BSSList.BSSList[ BSSListIndex ].channel = frameInfo->channel;
1064 /* if the received TSF (which is the lower 32 bits) is smaller than the lower 32 bits of the last beacon
1065 TSF, it means the higher 32 bits should be increased by 1 (TSF overflow to higher 32 bits occurred between
1066 last beacon of current AP and this frame). */
1067 if ( INT64_LOWER( (pScanMngr->currentTSF)) > frameInfo->staTSF )
1068 {
1069 INT64_HIGHER( (pScanMngr->BSSList.scanBSSList[ BSSListIndex ].localTSF)) =
1070 INT64_HIGHER( (pScanMngr->currentTSF)) + 1;
1071 }
1072 else
1073 {
1074 INT64_HIGHER( (pScanMngr->BSSList.scanBSSList[ BSSListIndex ].localTSF)) =
1075 INT64_HIGHER( (pScanMngr->currentTSF));
1076 }
1077 INT64_LOWER( (pScanMngr->BSSList.scanBSSList[ BSSListIndex ].localTSF)) = frameInfo->staTSF;
1078
1079 if ( BEACON == frameInfo->parsedIEs->subType )
1080 {
1081 os_memoryCopy( pScanMngr->hOS, &(pScanMngr->BSSList.BSSList[ BSSListIndex ].lastRxTSF),
1082 (void *)frameInfo->parsedIEs->content.iePacket.timestamp, TIME_STAMP_LEN );
1083 pScanMngr->BSSList.BSSList[ BSSListIndex ].beaconInterval =
1084 frameInfo->parsedIEs->content.iePacket.beaconInerval;
1085 pScanMngr->BSSList.BSSList[ BSSListIndex ].capabilities =
1086 frameInfo->parsedIEs->content.iePacket.capabilities;
1087 }
1088 else
1089 {
1090 os_memoryCopy( pScanMngr->hOS, &(pScanMngr->BSSList.BSSList[ BSSListIndex ].lastRxTSF),
1091 (void *)frameInfo->parsedIEs->content.iePacket.timestamp, TIME_STAMP_LEN );
1092 pScanMngr->BSSList.BSSList[ BSSListIndex ].beaconInterval =
1093 frameInfo->parsedIEs->content.iePacket.beaconInerval;
1094 pScanMngr->BSSList.BSSList[ BSSListIndex ].capabilities =
1095 frameInfo->parsedIEs->content.iePacket.capabilities;
1096 }
1097 #ifdef TI_DBG
1098 /*
1099 update track fail histogram:
1100 1. only done when tracking (to avoid updating due to "accidental re-discovery"
1101 2. only done for APs which have their track fail count larger than 0. The reason for that is because
1102 when tracking is started, the track fail count is increased, and thus if it is 0 tracking was not
1103 attempted for this AP, or more than one frame was received as a result of tracking operation for the AP.
1104 */
1105 if ( ((SCAN_CSS_TRACKING_A_BAND == pScanMngr->contScanState) ||
1106 (SCAN_CSS_TRACKING_G_BAND == pScanMngr->contScanState)) &&
1107 (0 < pScanMngr->BSSList.scanBSSList[ BSSListIndex ].trackFailCount))
1108 {
1109 if ( SCAN_MNGR_STAT_MAX_TRACK_FAILURE <=
1110 pScanMngr->BSSList.scanBSSList[ BSSListIndex ].trackFailCount )
1111 {
1112 pScanMngr->stats.ConsecutiveTrackFailCountHistogram[ SCAN_MNGR_STAT_MAX_TRACK_FAILURE - 1 ]++;
1113 }
1114 else
1115 {
1116 pScanMngr->stats.ConsecutiveTrackFailCountHistogram[ pScanMngr->BSSList.scanBSSList[ BSSListIndex ].trackFailCount - 1 ]++;
1117 }
1118 }
1119 #endif
1120 pScanMngr->BSSList.scanBSSList[ BSSListIndex ].trackFailCount = 0;
1121
1122 /* update RSSI value */
1123 {
1124 TI_INT8 rssiPrevVal = pScanMngr->BSSList.BSSList[ BSSListIndex ].RSSI;
1125 TI_INT8 tmpRssiAvg = ((RSSI_PREVIOUS_COEFFICIENT * rssiPrevVal) +
1126 ((10-RSSI_PREVIOUS_COEFFICIENT) * frameInfo->rssi)) / 10;
1127
1128 pScanMngr->BSSList.BSSList[ BSSListIndex ].lastRSSI = frameInfo->rssi;
1129
1130 if (rssiPrevVal!=0)
1131 {
1132 /* for faster convergence on RSSI changes use rounding error calculation with latest sample and not
1133 on latest average */
1134 if (frameInfo->rssi > tmpRssiAvg)
1135 tmpRssiAvg++;
1136 else
1137 if (frameInfo->rssi < tmpRssiAvg)
1138 tmpRssiAvg--;
1139
1140 pScanMngr->BSSList.BSSList[ BSSListIndex ].RSSI = tmpRssiAvg;
1141 }
1142 else
1143 {
1144 pScanMngr->BSSList.BSSList[ BSSListIndex ].RSSI = frameInfo->rssi;
1145 }
1146 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "given RSSI=%d, AVRG RSSI=%d\n", frameInfo->rssi, pScanMngr->BSSList.BSSList[ BSSListIndex ].RSSI);
1147
1148 }
1149
1150 pScanMngr->BSSList.BSSList[ BSSListIndex ].rxRate = frameInfo->rate;
1151 os_memoryCopy( pScanMngr->hOS, pScanMngr->BSSList.BSSList[ BSSListIndex ].pBuffer,
1152 frameInfo->buffer, frameInfo->bufferLength );
1153 pScanMngr->BSSList.BSSList[ BSSListIndex ].bufferLength = frameInfo->bufferLength;
1154 }
1155
1156 /**
1157 * \\n
1158 * \date 16-Mar-2005\n
1159 * \brief Search tracking list for an entry matching given BSSID.\n
1160 *
1161 * Function Scope \e Private.\n
1162 * \param hScanMngr - handle to the scan manager object.\n
1163 * \param bssId - the BSSID to search for.\n
1164 * \return entry index if found, -1 if no entry matching the BSSID was found.\n
1165 */
scanMngrGetTrackIndexByBssid(TI_HANDLE hScanMngr,TMacAddr * bssId)1166 TI_INT8 scanMngrGetTrackIndexByBssid( TI_HANDLE hScanMngr, TMacAddr* bssId )
1167 {
1168 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
1169 int i;
1170
1171 for ( i = 0; i < pScanMngr->BSSList.numOfEntries; i++ )
1172 {
1173 if (MAC_EQUAL(*bssId, pScanMngr->BSSList.BSSList[ i ].BSSID))
1174 {
1175 return i;
1176 }
1177 }
1178 return -1;
1179 }
1180
1181 /**
1182 * \\n
1183 * \date 02-Mar-2005\n
1184 * \brief Search current policy for band policy
1185 *
1186 * Function Scope \e Private.\n
1187 * \param hScanMngr - handle to the scan manager object.\n
1188 * \param band - the band to find policy for.\n
1189 * \return the policy structure if found, NULL if no policy configured for this band.\n
1190 */
scanMngrGetPolicyByBand(TI_HANDLE hScanMngr,ERadioBand band)1191 TScanBandPolicy* scanMngrGetPolicyByBand( TI_HANDLE hScanMngr, ERadioBand band )
1192 {
1193 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
1194 int i;
1195
1196 /* loop on all configured policies, and look for the requested band */
1197 for ( i = 0; i < pScanMngr->scanPolicy.numOfBands; i++ )
1198 {
1199 if ( band == pScanMngr->scanPolicy.bandScanPolicy[ i ].band )
1200 {
1201 return &(pScanMngr->scanPolicy.bandScanPolicy[ i ]);
1202 }
1203 }
1204
1205 /* if no policy was found, there's no policy configured for the requested band */
1206 return NULL;
1207 }
1208
1209 /**
1210 * \\n
1211 * \date 06-Mar-2005\n
1212 * \brief Sets the next discovery part according to current discovery part, policies and neighbor APs availability .\n
1213 *
1214 * Function Scope \e Private.\n
1215 * \param hScanMngr - handle to the scan manager object.\n
1216 */
scanMngrSetNextDiscoveryPart(TI_HANDLE hScanMngr)1217 void scanMngrSetNextDiscoveryPart( TI_HANDLE hScanMngr )
1218 {
1219 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
1220 scan_discoveryPart_e nextDiscoveryPart, originalDiscoveryPart;
1221
1222 /* sanity check - if discovery part is not valid, restart from first discovery part */
1223 if ( SCAN_SDP_NO_DISCOVERY <= pScanMngr->currentDiscoveryPart )
1224 {
1225 pScanMngr->currentDiscoveryPart = SCAN_SDP_NEIGHBOR_G;
1226 }
1227
1228 /* if current discovery part is valid, do nothing */
1229 if ( TI_TRUE == scanMngrIsDiscoveryValid( hScanMngr, pScanMngr->currentDiscoveryPart ))
1230 {
1231 return;
1232 }
1233
1234 /* next discovery part is found according to current part, in the following order:
1235 Neighbor APs on G, Neighbor APs on A, Channel list on G, Channel list on A */
1236 /* get next discovery part */
1237 nextDiscoveryPart = pScanMngr->currentDiscoveryPart;
1238 originalDiscoveryPart = pScanMngr->currentDiscoveryPart;
1239
1240 do
1241 {
1242 nextDiscoveryPart++;
1243 /* loop back to first discovery part if discovery list end had been reached */
1244 if ( SCAN_SDP_NO_DISCOVERY == nextDiscoveryPart )
1245 {
1246 nextDiscoveryPart = SCAN_SDP_NEIGHBOR_G;
1247 }
1248 /* try next discovery part until first one is reached again or a valid part is found */
1249 } while( (nextDiscoveryPart != originalDiscoveryPart) &&
1250 (TI_FALSE == scanMngrIsDiscoveryValid( hScanMngr, nextDiscoveryPart )));
1251
1252 /* if a discovery part for which discovery is valid was found, use it */
1253 if ( TI_TRUE == scanMngrIsDiscoveryValid( hScanMngr, nextDiscoveryPart ))
1254 {
1255 pScanMngr->currentDiscoveryPart = nextDiscoveryPart;
1256 }
1257 /* otherwise don't do discovery */
1258 else
1259 {
1260 pScanMngr->currentDiscoveryPart = SCAN_SDP_NO_DISCOVERY;
1261 }
1262 }
1263
1264 /**
1265 * \\n
1266 * \date 06-Mar-2005\n
1267 * \brief Checks whether discovery should be performed on the specified discovery part.\n
1268 *
1269 * Function Scope \e Private.\n
1270 * \param hScanMngr - handle to the scan manager object.\n
1271 * \param discoveryPart - the discovery part to check.\n
1272 */
scanMngrIsDiscoveryValid(TI_HANDLE hScanMngr,scan_discoveryPart_e discoveryPart)1273 TI_BOOL scanMngrIsDiscoveryValid( TI_HANDLE hScanMngr, scan_discoveryPart_e discoveryPart )
1274 {
1275 scanMngr_t* pScanMngr = (TI_HANDLE)hScanMngr;
1276 TScanBandPolicy *gPolicy, *aPolicy;
1277
1278 gPolicy = scanMngrGetPolicyByBand( hScanMngr, RADIO_BAND_2_4_GHZ );
1279 aPolicy = scanMngrGetPolicyByBand( hScanMngr, RADIO_BAND_5_0_GHZ );
1280
1281 switch (discoveryPart)
1282 {
1283 case SCAN_SDP_NEIGHBOR_G:
1284 /* for discovery on G neighbor APs, a policy must be defined for G, discovery scan type should be present,
1285 number of neighbor APs on G should be greater than zero, and at least one AP should be yet undiscovered */
1286 if ( (NULL != gPolicy) &&
1287 (SCAN_TYPE_NO_SCAN != gPolicy->discoveryMethod.scanType) &&
1288 (0 < pScanMngr->neighborAPsDiscoveryList[ RADIO_BAND_2_4_GHZ ].numOfEntries) &&
1289 (TI_TRUE == scanMngrNeighborAPsAvailableForDiscovery( hScanMngr, RADIO_BAND_2_4_GHZ )))
1290 {
1291 return TI_TRUE;
1292 }
1293 else
1294 {
1295 return TI_FALSE;
1296 }
1297
1298 case SCAN_SDP_NEIGHBOR_A:
1299 /* for discovery on A neighbor APs, a policy must be defined for A, discovery scan type should be present,
1300 number of neighbor APs on A should be greater than zero, and at least one AP should be yet undiscovered */
1301 if ( (NULL != aPolicy) &&
1302 (SCAN_TYPE_NO_SCAN != aPolicy->discoveryMethod.scanType) &&
1303 (0 < pScanMngr->neighborAPsDiscoveryList[ RADIO_BAND_5_0_GHZ ].numOfEntries) &&
1304 (TI_TRUE == scanMngrNeighborAPsAvailableForDiscovery( hScanMngr, RADIO_BAND_5_0_GHZ )))
1305 {
1306 return TI_TRUE;
1307 }
1308 else
1309 {
1310 return TI_FALSE;
1311 }
1312
1313 case SCAN_SDP_CHANNEL_LIST_G:
1314 /* for discovery on G channel list, a policy must be defined for G, discovery scan type should be present,
1315 and number of channels in G channel list should be greater than zero */
1316 if ( (NULL != gPolicy) &&
1317 (SCAN_TYPE_NO_SCAN != gPolicy->discoveryMethod.scanType) &&
1318 (0 < gPolicy->numOfChannles))
1319 {
1320 return TI_TRUE;
1321 }
1322 else
1323 {
1324 return TI_FALSE;
1325 }
1326 case SCAN_SDP_CHANNEL_LIST_A:
1327 /* for discovery on A channel list, a policy must be defined for A, discovery scan type should be present,
1328 and number of channels in A channel list should be greater than zero */
1329 if ( (NULL != aPolicy) &&
1330 (SCAN_TYPE_NO_SCAN != aPolicy->discoveryMethod.scanType) &&
1331 (0 < aPolicy->numOfChannles))
1332 {
1333 return TI_TRUE;
1334 }
1335 else
1336 {
1337 return TI_FALSE;
1338 }
1339 default:
1340 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Checking whather discovery is valid for discovery part %d", discoveryPart);
1341 return TI_FALSE;
1342 }
1343 }
1344
1345 /**
1346 * \\n
1347 * \date 07-Mar-2005\n
1348 * \brief Check whether there are neighbor APs to track on the given band.\n
1349 *
1350 * Function Scope \e Private.\n
1351 * \param hScanMngr - handle to the scan manager object.\n
1352 * \param bandPolicy - The scan policy for the requested band.\n
1353 * \param bNeighborAPsOnly - whether to scan for neighbor APs only or for all policy defined channels.\n
1354 */
scanMngrNeighborAPsAvailableForDiscovery(TI_HANDLE hScanMngr,ERadioBand band)1355 TI_BOOL scanMngrNeighborAPsAvailableForDiscovery( TI_HANDLE hScanMngr, ERadioBand band )
1356 {
1357 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
1358 int i;
1359
1360
1361 /* loop on all neighbor APs of the given band */
1362 for ( i = 0; i < pScanMngr->neighborAPsDiscoveryList[ band ].numOfEntries; i++ )
1363 {
1364 /* if a neighbor AP is not being tracked, meaning it yet has to be discovered, return TI_TRUE */
1365 if ( SCAN_NDS_NOT_DISCOVERED == pScanMngr->neighborAPsDiscoveryList[ band ].trackStatusList[ i ] )
1366 {
1367 return TI_TRUE;
1368 }
1369 }
1370 /* if all neighbor APs are being tracked (or no neighbor APs available) return TI_FALSE */
1371 return TI_FALSE;
1372 }
1373
1374 /**
1375 * \\n
1376 * \date 02-Mar-2005\n
1377 * \brief Builds a scan command on the object workspace for immediate scan.\n
1378 *
1379 * Function Scope \e Private.\n
1380 * \param hScanMngr - handle to the scan manager object.\n
1381 * \param bandPolicy - The scan policy for the requested band.\n
1382 * \param bNeighborAPsOnly - whether to scan for neighbor APs only or for all policy defined channels.\n
1383 */
scanMngrBuildImmediateScanCommand(TI_HANDLE hScanMngr,TScanBandPolicy * bandPolicy,TI_BOOL bNeighborAPsOnly)1384 void scanMngrBuildImmediateScanCommand( TI_HANDLE hScanMngr, TScanBandPolicy* bandPolicy, TI_BOOL bNeighborAPsOnly )
1385 {
1386 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
1387 int channelIndex;
1388 paramInfo_t param;
1389 TMacAddr broadcastAddress;
1390 int i;
1391
1392 /* first, build the command header */
1393 scanMngrBuildScanCommandHeader( hScanMngr, &(bandPolicy->immediateScanMethod), bandPolicy->band );
1394
1395 /* if requested to scan on neighbor APs only */
1396 if ( TI_TRUE == bNeighborAPsOnly )
1397 {
1398 /* loop on all neighbor APs */
1399 channelIndex = 0;
1400 while ( (channelIndex < pScanMngr->neighborAPsDiscoveryList[ bandPolicy->band ].numOfEntries) &&
1401 (pScanMngr->scanParams.numOfChannels < SCAN_MAX_NUM_OF_NORMAL_CHANNELS_PER_COMMAND))
1402 {
1403 /* verify channel with reg domain */
1404 param.paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES;
1405 param.content.channelCapabilityReq.band = bandPolicy->band;
1406 if ( (bandPolicy->immediateScanMethod.scanType == SCAN_TYPE_NORMAL_PASSIVE) ||
1407 (bandPolicy->immediateScanMethod.scanType == SCAN_TYPE_TRIGGERED_PASSIVE) ||
1408 (bandPolicy->immediateScanMethod.scanType == SCAN_TYPE_SPS))
1409 {
1410 param.content.channelCapabilityReq.scanOption = PASSIVE_SCANNING;
1411 }
1412 else
1413 {
1414 param.content.channelCapabilityReq.scanOption = ACTIVE_SCANNING;
1415 }
1416 param.content.channelCapabilityReq.channelNum =
1417 pScanMngr->neighborAPsDiscoveryList[ bandPolicy->band ].APListPtr[ channelIndex ].channel;
1418 regulatoryDomain_getParam( pScanMngr->hRegulatoryDomain, ¶m );
1419
1420 /* if the channel is allowed, insert it to the scan command */
1421 if (param.content.channelCapabilityRet.channelValidity)
1422 {
1423 scanMngrAddNormalChannel( hScanMngr, &(bandPolicy->immediateScanMethod),
1424 pScanMngr->neighborAPsDiscoveryList[ bandPolicy->band ].APListPtr[ channelIndex ].channel,
1425 &(pScanMngr->neighborAPsDiscoveryList[ bandPolicy->band ].APListPtr[ channelIndex ].BSSID),
1426 param.content.channelCapabilityRet.maxTxPowerDbm );
1427 }
1428 channelIndex++;
1429 }
1430 }
1431 else
1432 /* scan on all policy defined channels */
1433 {
1434 /* set the broadcast address */
1435 for ( i = 0; i < MAC_ADDR_LEN; i++ )
1436 {
1437 broadcastAddress[ i ] = 0xff;
1438 }
1439
1440 /* loop on all channels in the policy */
1441 channelIndex = 0;
1442 while ( (channelIndex < bandPolicy->numOfChannles) &&
1443 (pScanMngr->scanParams.numOfChannels < SCAN_MAX_NUM_OF_NORMAL_CHANNELS_PER_COMMAND))
1444 {
1445 /* verify channel with reg domain */
1446 param.paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES;
1447 param.content.channelCapabilityReq.band = bandPolicy->band;
1448 if ( (bandPolicy->immediateScanMethod.scanType == SCAN_TYPE_NORMAL_PASSIVE) ||
1449 (bandPolicy->immediateScanMethod.scanType == SCAN_TYPE_TRIGGERED_PASSIVE) ||
1450 (bandPolicy->immediateScanMethod.scanType == SCAN_TYPE_SPS))
1451 {
1452 param.content.channelCapabilityReq.scanOption = PASSIVE_SCANNING;
1453 }
1454 else
1455 {
1456 param.content.channelCapabilityReq.scanOption = ACTIVE_SCANNING;
1457 }
1458 param.content.channelCapabilityReq.channelNum = bandPolicy->channelList[ channelIndex ];
1459 regulatoryDomain_getParam( pScanMngr->hRegulatoryDomain, ¶m );
1460
1461 /* if the channel is allowed, insert it to the scan command */
1462 if (param.content.channelCapabilityRet.channelValidity)
1463 {
1464 scanMngrAddNormalChannel( hScanMngr, &(bandPolicy->immediateScanMethod),
1465 bandPolicy->channelList[ channelIndex ],
1466 &broadcastAddress,
1467 param.content.channelCapabilityRet.maxTxPowerDbm );
1468 }
1469 channelIndex++;
1470 }
1471 }
1472 }
1473
1474 /**
1475 * \\n
1476 * \date 03-Mar-2005\n
1477 * \brief Builds a scan command on the object workspace for tracking.\n
1478 *
1479 * Function Scope \e Private.\n
1480 * \param hScanMngr - handle to the scan manager object.\n
1481 * \param bandPolicy - The scan policy for the band to track on.\n
1482 * \param band - the band to scan.\n
1483 */
scanMngrBuildTrackScanCommand(TI_HANDLE hScanMngr,TScanBandPolicy * bandPolicy,ERadioBand band)1484 void scanMngrBuildTrackScanCommand( TI_HANDLE hScanMngr, TScanBandPolicy* bandPolicy, ERadioBand band )
1485 {
1486 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
1487 int BSSListIndex;
1488 paramInfo_t param;
1489 TScanMethod* scanMethod;
1490
1491 TRACE0(pScanMngr->hReport , REPORT_SEVERITY_INFORMATION, "\n scanMngrBuildTrackScanCommand \n");
1492
1493
1494 /* SPS is performed differently from all other scan types, and only if TSF error has not occured */
1495 if ( (SCAN_TYPE_SPS == bandPolicy->trackingMethod.scanType) && (TI_TRUE == pScanMngr->bSynchronized))
1496 {
1497 /* build the command header */
1498 TRACE0(pScanMngr->hReport , REPORT_SEVERITY_INFORMATION, "\nSPS invoked\n");
1499 scanMngrBuildScanCommandHeader( hScanMngr, &(bandPolicy->trackingMethod), band );
1500
1501 /* build the channel list */
1502 scanMngrAddSPSChannels( hScanMngr, &(bandPolicy->trackingMethod), band );
1503 return;
1504 }
1505
1506 /* the scan method to use is the method defined for tracking, unless this is SPS and TSF error occurred,
1507 in which case we use the discovery method this time. */
1508 if ( (SCAN_TYPE_SPS == bandPolicy->trackingMethod.scanType) && (TI_FALSE == pScanMngr->bSynchronized))
1509 {
1510 /* use discovery scan method */
1511 scanMethod = &(bandPolicy->discoveryMethod);
1512 }
1513 else
1514 {
1515 /* use tracking method */
1516 scanMethod = &(bandPolicy->trackingMethod);
1517 }
1518
1519 /* build the command header */
1520 scanMngrBuildScanCommandHeader( hScanMngr, scanMethod, band );
1521
1522 /* insert channels from tracking list according to requested band */
1523 BSSListIndex = 0;
1524 while ( (BSSListIndex < pScanMngr->BSSList.numOfEntries) &&
1525 (pScanMngr->scanParams.numOfChannels < SCAN_MAX_NUM_OF_NORMAL_CHANNELS_PER_COMMAND))
1526 {
1527 /* if BSS is on the right band */
1528 if ( band == pScanMngr->BSSList.BSSList[ BSSListIndex ].band )
1529 {
1530 /* verify the channel with the reg domain */
1531 param.paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES;
1532 param.content.channelCapabilityReq.band = band;
1533 if ( (scanMethod->scanType == SCAN_TYPE_NORMAL_PASSIVE) ||
1534 (scanMethod->scanType == SCAN_TYPE_TRIGGERED_PASSIVE))
1535 {
1536 param.content.channelCapabilityReq.scanOption = PASSIVE_SCANNING;
1537 }
1538 else
1539 {
1540 param.content.channelCapabilityReq.scanOption = ACTIVE_SCANNING;
1541 }
1542 param.content.channelCapabilityReq.channelNum = pScanMngr->BSSList.BSSList[ BSSListIndex ].channel;
1543 regulatoryDomain_getParam( pScanMngr->hRegulatoryDomain, ¶m );
1544
1545 /* if channel is verified for requested scan type */
1546 if ( param.content.channelCapabilityRet.channelValidity )
1547 {
1548 scanMngrAddNormalChannel( hScanMngr, scanMethod,
1549 pScanMngr->BSSList.BSSList[ BSSListIndex ].channel,
1550 &(pScanMngr->BSSList.BSSList[ BSSListIndex ].BSSID),
1551 param.content.channelCapabilityRet.maxTxPowerDbm );
1552
1553 /* increase AP track attempts counter */
1554 if ( (SCAN_TYPE_SPS == bandPolicy->trackingMethod.scanType) && (TI_FALSE == pScanMngr->bSynchronized))
1555 {
1556 pScanMngr->BSSList.scanBSSList[ BSSListIndex ].trackFailCount =
1557 pScanMngr->scanPolicy.maxTrackFailures + 1;
1558 }
1559 else
1560 {
1561 pScanMngr->BSSList.scanBSSList[ BSSListIndex ].trackFailCount++;
1562 }
1563 }
1564 /* if channel is not verified, there are two options:
1565 1. we are using the tracking method, and thus the AP should be removed (because we are unable
1566 to track it)
1567 2. we are using the discovery method (because a TSF error occurred and tracking method is SPS).
1568 In this case, it seems we do not have to remove the AP (because the channel may not be valid
1569 for active scan but it is valid for passive scan), but since we had a TSF error the AP would
1570 be removed anyhow if not re-discovered now, so no harm done in removing it as well. */
1571 else
1572 {
1573 /* removing an AP is done by increasing its track failure counter to maximum. Since it is
1574 not tracked, it would not be found, and thus would be removed by aging process performed
1575 at scan completion */
1576 pScanMngr->BSSList.scanBSSList[ BSSListIndex ].trackFailCount =
1577 pScanMngr->scanPolicy.maxTrackFailures + 1;
1578 #ifdef TI_DBG
1579 /* update statistics */
1580 pScanMngr->stats.APsRemovedInvalidChannel++;
1581 #endif
1582 }
1583 }
1584 BSSListIndex++;
1585 }
1586 }
1587
1588 /**
1589 * \\n
1590 * \date 03-Mar-2005\n
1591 * \brief Builds a scan command on the object workspace for discovery.\n
1592 *
1593 * Function Scope \e Private.\n
1594 * \param hScanMngr - handle to the scan manager object.\n
1595 */
scanMngrBuildDiscoveryScanCommand(TI_HANDLE hScanMngr)1596 void scanMngrBuildDiscoveryScanCommand( TI_HANDLE hScanMngr )
1597 {
1598 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
1599 ERadioBand band;
1600 TScanBandPolicy* bandPolicy;
1601
1602 /* find on which band to discover at current cycle */
1603 if ( (SCAN_SDP_NEIGHBOR_G == pScanMngr->currentDiscoveryPart) ||
1604 (SCAN_SDP_CHANNEL_LIST_G == pScanMngr->currentDiscoveryPart))
1605 {
1606 band = RADIO_BAND_2_4_GHZ;
1607 bandPolicy = scanMngrGetPolicyByBand( hScanMngr, band );
1608 }
1609 else
1610 {
1611 band = RADIO_BAND_5_0_GHZ;
1612 bandPolicy = scanMngrGetPolicyByBand( hScanMngr, band );
1613 }
1614
1615 if( NULL == bandPolicy)
1616 {
1617 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "scanMngrGetPolicyByBand() returned NULL.\n");
1618 return;
1619 }
1620
1621 /* first, build the command header */
1622 scanMngrBuildScanCommandHeader( hScanMngr, &(bandPolicy->discoveryMethod), band );
1623
1624 /* channels are added according to current discovery part */
1625 switch ( pScanMngr->currentDiscoveryPart )
1626 {
1627 case SCAN_SDP_NEIGHBOR_G:
1628 /* add channels from neighbor AP discovery list */
1629 scanMngrAddNeighborAPsForDiscovery( hScanMngr, bandPolicy );
1630
1631 /* if neighbor AP list is exhausted, proceed to next discovery part */
1632 if ( 0 == pScanMngr->neighborAPsDiscoveryIndex[ band ] )
1633 {
1634 pScanMngr->currentDiscoveryPart++;
1635 scanMngrSetNextDiscoveryPart( hScanMngr );
1636 }
1637
1638 /* if need to discover more APs, (not enough neighbor APs), proceed to G channel list */
1639 if ( pScanMngr->scanParams.numOfChannels < bandPolicy->numOfChannlesForDiscovery )
1640 {
1641 scanMngrAddChannelListForDiscovery( hScanMngr, bandPolicy );
1642 }
1643
1644 #ifdef TI_DBG
1645 pScanMngr->statsLastDiscoveryBand = RADIO_BAND_2_4_GHZ;
1646 #endif
1647 break;
1648
1649 case SCAN_SDP_NEIGHBOR_A:
1650 /* add channels from neighbor AP discovery list */
1651 scanMngrAddNeighborAPsForDiscovery( hScanMngr, bandPolicy );
1652
1653 /* if neighbor AP list is exhausted, proceed to next discovery part */
1654 if ( 0 == pScanMngr->neighborAPsDiscoveryIndex[ band ] )
1655 {
1656 pScanMngr->currentDiscoveryPart++;
1657 scanMngrSetNextDiscoveryPart( hScanMngr );
1658 }
1659
1660 /* if need to discover more APs, (not enough neighbor APs), proceed to A channel list */
1661 if ( pScanMngr->scanParams.numOfChannels < bandPolicy->numOfChannlesForDiscovery )
1662 {
1663 scanMngrAddChannelListForDiscovery( hScanMngr, bandPolicy );
1664 }
1665
1666 #ifdef TI_DBG
1667 pScanMngr->statsLastDiscoveryBand = RADIO_BAND_5_0_GHZ;
1668 #endif
1669 break;
1670
1671 case SCAN_SDP_CHANNEL_LIST_G:
1672 /* add channels from policy channel list */
1673 scanMngrAddChannelListForDiscovery( hScanMngr, bandPolicy );
1674
1675 /* if channel list is exhausted, proceed to next discovery part */
1676 if ( 0 == pScanMngr->channelDiscoveryIndex[ band ] )
1677 {
1678 pScanMngr->currentDiscoveryPart++;
1679 scanMngrSetNextDiscoveryPart( hScanMngr );
1680 }
1681
1682 /* if need to discover more APs (not enough channels on channel list), proceed to G neighbor APs */
1683 if ( pScanMngr->scanParams.numOfChannels < bandPolicy->numOfChannlesForDiscovery )
1684 {
1685 scanMngrAddNeighborAPsForDiscovery( hScanMngr, bandPolicy );
1686 }
1687
1688 #ifdef TI_DBG
1689 pScanMngr->statsLastDiscoveryBand = RADIO_BAND_2_4_GHZ;
1690 #endif
1691 break;
1692
1693 case SCAN_SDP_CHANNEL_LIST_A:
1694 /* add channels from policy channel list */
1695 scanMngrAddChannelListForDiscovery( hScanMngr, bandPolicy );
1696
1697 /* if channel list is exhausted, proceed to next discovery part */
1698 if ( 0 == pScanMngr->channelDiscoveryIndex[ band ] )
1699 {
1700 pScanMngr->currentDiscoveryPart++;
1701 scanMngrSetNextDiscoveryPart( hScanMngr );
1702 }
1703
1704 /* if need to discover more APs (not enough channels on channel list), proceed to A neighbor APs */
1705 if ( pScanMngr->scanParams.numOfChannels < bandPolicy->numOfChannlesForDiscovery )
1706 {
1707 scanMngrAddNeighborAPsForDiscovery( hScanMngr, bandPolicy );
1708 }
1709 #ifdef TI_DBG
1710 pScanMngr->statsLastDiscoveryBand = RADIO_BAND_5_0_GHZ;
1711 #endif
1712 break;
1713
1714 case SCAN_SDP_NO_DISCOVERY:
1715 default:
1716 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_ERROR, "scanMngrBuildDiscoveryScanCommand called and current discovery part is %d", pScanMngr->currentDiscoveryPart);
1717 break;
1718 }
1719 }
1720
1721 /**
1722 * \\n
1723 * \date 02-Mar-2005\n
1724 * \brief Builds the scan command header on the object workspace.\n
1725 *
1726 * Function Scope \e Private.\n
1727 * \param hScanMngr - handle to the scan manager object.\n
1728 * \param scanMethod - The scan method (and parameters) to use.\n
1729 * \param band - the band to scan.\n
1730 */
scanMngrBuildScanCommandHeader(TI_HANDLE hScanMngr,TScanMethod * scanMethod,ERadioBand band)1731 void scanMngrBuildScanCommandHeader( TI_HANDLE hScanMngr, TScanMethod* scanMethod, ERadioBand band )
1732 {
1733 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
1734
1735
1736 /* set general scan parameters */
1737 /* SSID is not set - scan concentrator will set it for the scan manager to current SSID */
1738 pScanMngr->scanParams.scanType = scanMethod->scanType;
1739 pScanMngr->scanParams.band = band;
1740
1741 switch (scanMethod->scanType)
1742 {
1743 case SCAN_TYPE_NORMAL_ACTIVE:
1744 /* In active scan, the desired SSID is set by the scan concentrator to the current SSID.
1745 Stting anything not zero triggers this in the scan concentrator */
1746 pScanMngr->scanParams.desiredSsid.len = 1;
1747 pScanMngr->scanParams.probeReqNumber = scanMethod->method.basicMethodParams.probReqParams.numOfProbeReqs;
1748 pScanMngr->scanParams.probeRequestRate = scanMethod->method.basicMethodParams.probReqParams.bitrate;
1749 break;
1750
1751 case SCAN_TYPE_TRIGGERED_ACTIVE:
1752 /* In active scan, the desired SSID is set by the scan concentrator to the current SSID.
1753 Stting anything not zero triggers this in the scan concentrator */
1754 pScanMngr->scanParams.desiredSsid.len = 1;
1755 pScanMngr->scanParams.probeReqNumber = scanMethod->method.TidTriggerdMethodParams.basicMethodParams.probReqParams.numOfProbeReqs;
1756 pScanMngr->scanParams.probeRequestRate = scanMethod->method.TidTriggerdMethodParams.basicMethodParams.probReqParams.bitrate;
1757 pScanMngr->scanParams.Tid = scanMethod->method.TidTriggerdMethodParams.triggeringTid;
1758 break;
1759
1760 case SCAN_TYPE_TRIGGERED_PASSIVE:
1761 pScanMngr->scanParams.Tid = scanMethod->method.TidTriggerdMethodParams.triggeringTid;
1762 /* In Passive scan, Desired SSID length is set to 0 so that the Scan concentrator won't replace
1763 it with the current SSID (to be able to receive beacons from AP's with multiple or hidden
1764 SSID) */
1765 pScanMngr->scanParams.desiredSsid.len = 0;
1766 break;
1767
1768 case SCAN_TYPE_NORMAL_PASSIVE:
1769 /* In Passive scan, Desired SSID length is set to 0 so that the Scan concentrator won't replace
1770 it with the current SSID (to be able to receive beacons from AP's with multiple or hidden
1771 SSID) */
1772 pScanMngr->scanParams.desiredSsid.len = 0;
1773 break;
1774
1775 case SCAN_TYPE_SPS:
1776 /* SPS doesn't have SSID filter, it only uses BSSID filter */
1777 break;
1778
1779 default:
1780 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Unrecognized scan type %d when building scan command", scanMethod->scanType);
1781 break;
1782 }
1783
1784 /* set 0 channels - actual channel will be added by caller */
1785 pScanMngr->scanParams.numOfChannels = 0;
1786 }
1787
1788 /**
1789 * \\n
1790 * \date 06-Mar-2005\n
1791 * \brief Add neighbor APs to scan command on the object workspace for discovery scan.\n
1792 *
1793 * Function Scope \e Private.\n
1794 * \param hScanMngr - handle to the scan manager object.\n
1795 * \param bandPolicy - the scan policy for the band to use.\n
1796 */
scanMngrAddNeighborAPsForDiscovery(TI_HANDLE hScanMngr,TScanBandPolicy * bandPolicy)1797 void scanMngrAddNeighborAPsForDiscovery( TI_HANDLE hScanMngr, TScanBandPolicy* bandPolicy )
1798 {
1799 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
1800 int neighborAPIndex = pScanMngr->neighborAPsDiscoveryIndex[ bandPolicy->band ];
1801 paramInfo_t param;
1802
1803 /* loop while neighbor AP list has not been exhausted, command is not full and not enough APs for discovery had been found */
1804 while ( (pScanMngr->scanParams.numOfChannels < bandPolicy->numOfChannlesForDiscovery) &&
1805 (pScanMngr->scanParams.numOfChannels < SCAN_MAX_NUM_OF_NORMAL_CHANNELS_PER_COMMAND) &&
1806 (neighborAPIndex < pScanMngr->neighborAPsDiscoveryList[ bandPolicy->band ].numOfEntries))
1807 {
1808 /* if the AP is not being tracked */
1809 if ( SCAN_NDS_NOT_DISCOVERED ==
1810 pScanMngr->neighborAPsDiscoveryList[ bandPolicy->band ].trackStatusList[ neighborAPIndex ] )
1811 {
1812 /* verify channel with reg domain */
1813 param.paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES;
1814 param.content.channelCapabilityReq.band = bandPolicy->band;
1815 if ( (bandPolicy->discoveryMethod.scanType == SCAN_TYPE_NORMAL_PASSIVE) ||
1816 (bandPolicy->discoveryMethod.scanType == SCAN_TYPE_TRIGGERED_PASSIVE) ||
1817 (bandPolicy->discoveryMethod.scanType == SCAN_TYPE_SPS))
1818 {
1819 param.content.channelCapabilityReq.scanOption = PASSIVE_SCANNING;
1820 }
1821 else
1822 {
1823 param.content.channelCapabilityReq.scanOption = ACTIVE_SCANNING;
1824 }
1825 param.content.channelCapabilityReq.channelNum =
1826 pScanMngr->neighborAPsDiscoveryList[ bandPolicy->band ].APListPtr[ neighborAPIndex ].channel;
1827 regulatoryDomain_getParam( pScanMngr->hRegulatoryDomain, ¶m );
1828
1829 /* if the channel is allowed, insert it to the scan command */
1830 if (param.content.channelCapabilityRet.channelValidity)
1831 {
1832 scanMngrAddNormalChannel( hScanMngr, &(bandPolicy->discoveryMethod),
1833 pScanMngr->neighborAPsDiscoveryList[ bandPolicy->band ].APListPtr[ neighborAPIndex ].channel,
1834 &(pScanMngr->neighborAPsDiscoveryList[ bandPolicy->band ].APListPtr[ neighborAPIndex ].BSSID),
1835 param.content.channelCapabilityRet.maxTxPowerDbm );
1836 }
1837 }
1838 neighborAPIndex++;
1839 }
1840
1841 /* if neighbor AP list has been exhuasted */
1842 if ( neighborAPIndex == pScanMngr->neighborAPsDiscoveryList[ bandPolicy->band ].numOfEntries )
1843 {
1844 /* reset discovery index */
1845 pScanMngr->neighborAPsDiscoveryIndex[ bandPolicy->band ] = 0;
1846 }
1847 else
1848 {
1849 /* just update neighbor APs discovery index */
1850 pScanMngr->neighborAPsDiscoveryIndex[ bandPolicy->band ] = neighborAPIndex;
1851 }
1852 }
1853
1854 /**
1855 * \\n
1856 * \date 06-Mar-2005\n
1857 * \brief Add channel from policy channels list to scan command on the object workspace for discovery scan.\n
1858 *
1859 * Function Scope \e Private.\n
1860 * \param hScanMngr - handle to the scan manager object.\n
1861 * \param bandPolicy - the scan policy for the band to use.\n
1862 */
scanMngrAddChannelListForDiscovery(TI_HANDLE hScanMngr,TScanBandPolicy * bandPolicy)1863 void scanMngrAddChannelListForDiscovery( TI_HANDLE hScanMngr, TScanBandPolicy* bandPolicy )
1864 {
1865 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
1866 paramInfo_t param;
1867 TMacAddr broadcastAddress;
1868 int i, channelListIndex = pScanMngr->channelDiscoveryIndex[ bandPolicy->band ];
1869
1870
1871 /* set broadcast MAC address */
1872 for ( i = 0; i < MAC_ADDR_LEN; i++ )
1873 {
1874 broadcastAddress[ i ] = 0xff;
1875 }
1876
1877 /* loop while channel list has not been exhausted, command is not full, and not enough APs for discovery had been found */
1878 while ( (pScanMngr->scanParams.numOfChannels < bandPolicy->numOfChannlesForDiscovery) &&
1879 (pScanMngr->scanParams.numOfChannels < SCAN_MAX_NUM_OF_NORMAL_CHANNELS_PER_COMMAND) &&
1880 (channelListIndex < bandPolicy->numOfChannles))
1881 {
1882 /* verify channel with reg domain */
1883 param.paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES;
1884 param.content.channelCapabilityReq.band = bandPolicy->band;
1885 if ( (bandPolicy->discoveryMethod.scanType == SCAN_TYPE_NORMAL_PASSIVE) ||
1886 (bandPolicy->discoveryMethod.scanType == SCAN_TYPE_TRIGGERED_PASSIVE) ||
1887 (bandPolicy->discoveryMethod.scanType == SCAN_TYPE_SPS))
1888 {
1889 param.content.channelCapabilityReq.scanOption = PASSIVE_SCANNING;
1890 }
1891 else
1892 {
1893 param.content.channelCapabilityReq.scanOption = ACTIVE_SCANNING;
1894 }
1895 param.content.channelCapabilityReq.channelNum =
1896 bandPolicy->channelList[ channelListIndex ];
1897 regulatoryDomain_getParam( pScanMngr->hRegulatoryDomain, ¶m );
1898
1899 /* if the channel is allowed, insert it to the scan command */
1900 if (param.content.channelCapabilityRet.channelValidity)
1901 {
1902 scanMngrAddNormalChannel( hScanMngr, &(bandPolicy->discoveryMethod),
1903 bandPolicy->channelList[ channelListIndex ],
1904 &broadcastAddress,
1905 param.content.channelCapabilityRet.maxTxPowerDbm );
1906 }
1907 channelListIndex++;
1908 }
1909
1910 /* if channel discovery list has been exhuasted */
1911 if ( channelListIndex == bandPolicy->numOfChannles )
1912 {
1913 /* reset discovery index */
1914 pScanMngr->channelDiscoveryIndex[ bandPolicy->band ] = 0;
1915 }
1916 else
1917 {
1918 /* just update channel list discovery index */
1919 pScanMngr->channelDiscoveryIndex[ bandPolicy->band ] = channelListIndex;
1920 }
1921 }
1922
1923 /**
1924 * \\n
1925 * \date 02-Mar-2005\n
1926 * \brief Add SPS channels to scan command on the object workspace.\n
1927 *
1928 * Function Scope \e Private.\n
1929 * \param hScanMngr - handle to the scan manager object.\n
1930 * \param scanMethod - The scan method (and parameters) to use.\n
1931 * \param band - the band to scan.\n
1932 */
scanMngrAddSPSChannels(TI_HANDLE hScanMngr,TScanMethod * scanMethod,ERadioBand band)1933 void scanMngrAddSPSChannels( TI_HANDLE hScanMngr, TScanMethod* scanMethod, ERadioBand band )
1934 {
1935 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
1936 TI_UINT64 EarliestTSFToInsert;
1937 TI_UINT32 timeToStartInAdvance = scanMethod->method.spsMethodParams.scanDuration /
1938 SCAN_SPS_DURATION_PART_IN_ADVANCE;
1939 scan_SPSHelper_t nextEventArray[ MAX_SIZE_OF_BSS_TRACK_LIST ];
1940 int BSSListIndex, i, j, nextEventArrayHead, nextEventArraySize;
1941 paramInfo_t param;
1942 #ifdef SCAN_MNGR_SPS_DBG
1943 TI_UINT32 highValue, lowValue, maxNextEventArraySize;
1944 #endif
1945
1946 TRACE1(pScanMngr->hReport , REPORT_SEVERITY_INFORMATION, "\nscanMngrAddSPSChannels invoked for band %d\n",band);
1947 /* initialize latest TSF value */
1948 pScanMngr->scanParams.latestTSFValue = 0;
1949
1950 /* initialize the next event arry */
1951 nextEventArrayHead = -1;
1952 nextEventArraySize = 0;
1953
1954 #ifdef SCAN_MNGR_SPS_DBG
1955 highValue = INT64_HIGHER( pScanMngr->currentTSF );
1956 lowValue = INT64_LOWER( pScanMngr->currentTSF );
1957 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "current TSF: %u-%u\n", highValue, lowValue);
1958 #endif
1959
1960 /* insert channels from tracking list to next event array according to requested band */
1961 for ( BSSListIndex = 0; BSSListIndex < pScanMngr->BSSList.numOfEntries; BSSListIndex++ )
1962 {
1963 /* if BSS is on the right band */
1964 if ( band == pScanMngr->BSSList.BSSList[ BSSListIndex ].band )
1965 {
1966 /* verify the channel with the reg domain */
1967 param.paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES;
1968 param.content.channelCapabilityReq.band = band;
1969 param.content.channelCapabilityReq.scanOption = PASSIVE_SCANNING;
1970 param.content.channelCapabilityReq.channelNum = pScanMngr->BSSList.BSSList[ BSSListIndex ].channel;
1971 regulatoryDomain_getParam( pScanMngr->hRegulatoryDomain, ¶m );
1972
1973 /* if channel is verified for requested scan type */
1974 if ( param.content.channelCapabilityRet.channelValidity )
1975 {
1976 /* if this AP local TSF value is greater that latest TSF value, change it */
1977 if ( pScanMngr->BSSList.scanBSSList[ BSSListIndex ].localTSF > pScanMngr->scanParams.latestTSFValue )
1978 {
1979 /* the latest TSF value is used by the FW to detect TSF error (an AP recovery). When a TSF
1980 error occurs, the latest TSF value should be in the future (because the AP TSF was
1981 reset). */
1982 pScanMngr->scanParams.latestTSFValue = pScanMngr->BSSList.scanBSSList[ BSSListIndex ].localTSF;
1983 }
1984
1985 /* calculate the TSF of the next event for tracked AP. Scan should start
1986 SCAN_SPS_DURATION_PART_IN_ADVANCE before the calculated event */
1987 nextEventArray[ nextEventArraySize ].nextEventTSF =
1988 scanMngrCalculateNextEventTSF( hScanMngr, &(pScanMngr->BSSList), BSSListIndex,
1989 pScanMngr->currentTSF + SCAN_SPS_GUARD_FROM_CURRENT_TSF +
1990 timeToStartInAdvance ) - timeToStartInAdvance;
1991 #ifdef SCAN_MNGR_SPS_DBG
1992 highValue = INT64_HIGHER( nextEventArray[ nextEventArraySize ].nextEventTSF );
1993 lowValue = INT64_LOWER( nextEventArray[ nextEventArraySize ].nextEventTSF );
1994 TRACE8( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "BSSID:%02x:%02x:%02x:%02x:%02x:%02x will send frame at TSF:%x-%x\n", pScanMngr->BSSList.BSSList[ BSSListIndex ].BSSID[ 0 ], pScanMngr->BSSList.BSSList[ BSSListIndex ].BSSID[ 1 ], pScanMngr->BSSList.BSSList[ BSSListIndex ].BSSID[ 2 ], pScanMngr->BSSList.BSSList[ BSSListIndex ].BSSID[ 3 ], pScanMngr->BSSList.BSSList[ BSSListIndex ].BSSID[ 4 ], pScanMngr->BSSList.BSSList[ BSSListIndex ].BSSID[ 5 ], highValue, lowValue);
1995 #endif
1996 nextEventArray[ nextEventArraySize ].trackListIndex = BSSListIndex;
1997
1998 /* insert it, sorted, to the next event array */
1999 /* if need to insert as head (either because list is empty or because it has earliest TSF) */
2000 if ( (-1 == nextEventArrayHead) ||
2001 (nextEventArray[ nextEventArraySize ].nextEventTSF < nextEventArray[ nextEventArrayHead ].nextEventTSF))
2002 {
2003 /* link the newly inserted AP to the current head */
2004 nextEventArray[ nextEventArraySize ].nextAPIndex = nextEventArrayHead;
2005 /* make current head point to newly inserted AP */
2006 nextEventArrayHead = nextEventArraySize;
2007 nextEventArraySize++;
2008 }
2009 /* insert into the list */
2010 else
2011 {
2012 /* start with list head */
2013 i = nextEventArrayHead;
2014 /* while the new AP TSF is larger and list end had not been reached */
2015 while ( (nextEventArray[ i ].nextAPIndex != -1) && /* list end had not been reached */
2016 (nextEventArray[ nextEventArray[ i ].nextAPIndex ].nextEventTSF < nextEventArray[ nextEventArraySize ].nextEventTSF)) /* next event TSF of the next AP in the list is smaller than that of the AP being inserted */
2017 {
2018 /* proceed to the next AP */
2019 i = nextEventArray[ i ].nextAPIndex;
2020 }
2021 /* insert this AP to the list, right after the next event entry found */
2022 nextEventArray[ nextEventArraySize ].nextAPIndex = nextEventArray[ i ].nextAPIndex;
2023 nextEventArray[ i ].nextAPIndex = nextEventArraySize;
2024 nextEventArraySize++;
2025 }
2026 }
2027 /* if for some reason a channel on which an AP was found is not valid for passive scan,
2028 the AP should be removed. */
2029 else
2030 {
2031 /* removing the AP is done by increasing its track count to maximum - and since it is
2032 not tracked it will not be discovered, and thus will be deleted when the scan is complete */
2033 pScanMngr->BSSList.scanBSSList[ BSSListIndex ].trackFailCount =
2034 pScanMngr->scanPolicy.maxTrackFailures + 1;
2035 #ifdef TI_DBG
2036 /*update statistics */
2037 pScanMngr->stats.APsRemovedInvalidChannel++;
2038 #endif
2039 }
2040 }
2041 }
2042
2043 #ifdef SCAN_MNGR_SPS_DBG
2044 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "SPS list after first stage:\n");
2045 scanMngrDebugPrintSPSHelperList( hScanMngr, nextEventArray, nextEventArrayHead, nextEventArraySize );
2046 maxNextEventArraySize = nextEventArraySize;
2047 #endif
2048
2049 /* insert channels from next event array to scan command */
2050 EarliestTSFToInsert = pScanMngr->currentTSF + SCAN_SPS_GUARD_FROM_CURRENT_TSF;
2051 /* insert all APs to scan command (as long as command is not full) */
2052 while ( (nextEventArraySize > 0) &&
2053 (pScanMngr->scanParams.numOfChannels < SCAN_MAX_NUM_OF_SPS_CHANNELS_PER_COMMAND))
2054 {
2055 /* if first list entry fits, and it doesn't collide with current AP DTIM */
2056 if ( EarliestTSFToInsert < nextEventArray[ nextEventArrayHead ].nextEventTSF )
2057 {
2058 if ( TI_FALSE == scanMngrDTIMInRange( hScanMngr, nextEventArray[ nextEventArrayHead ].nextEventTSF,
2059 nextEventArray[ nextEventArrayHead ].nextEventTSF + scanMethod->method.spsMethodParams.scanDuration ))
2060 {
2061 /* insert it to scan command */
2062 pScanMngr->scanParams.channelEntry[ pScanMngr->scanParams.numOfChannels ].SPSChannelEntry.scanStartTime =
2063 INT64_LOWER( (nextEventArray[ nextEventArrayHead ].nextEventTSF));
2064 pScanMngr->scanParams.channelEntry[ pScanMngr->scanParams.numOfChannels ].SPSChannelEntry.scanDuration =
2065 scanMethod->method.spsMethodParams.scanDuration;
2066 pScanMngr->scanParams.channelEntry[ pScanMngr->scanParams.numOfChannels ].SPSChannelEntry.ETMaxNumOfAPframes =
2067 scanMethod->method.spsMethodParams.ETMaxNumberOfApFrames;
2068 pScanMngr->scanParams.channelEntry[ pScanMngr->scanParams.numOfChannels ].SPSChannelEntry.earlyTerminationEvent =
2069 scanMethod->method.spsMethodParams.earlyTerminationEvent;
2070 pScanMngr->scanParams.channelEntry[ pScanMngr->scanParams.numOfChannels ].SPSChannelEntry.channel =
2071 pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].channel;
2072 MAC_COPY (pScanMngr->scanParams.channelEntry[ pScanMngr->scanParams.numOfChannels ].SPSChannelEntry.bssId,
2073 pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID);
2074 /* increase the AP track attempts counter */
2075 pScanMngr->BSSList.scanBSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].trackFailCount++;
2076 /* increase number of channels in scan command */
2077 pScanMngr->scanParams.numOfChannels++;
2078 /* set earliest TSF that would fit in scan command */
2079 EarliestTSFToInsert = nextEventArray[ nextEventArrayHead ].nextEventTSF +
2080 scanMethod->method.spsMethodParams.scanDuration +
2081 SCAN_SPS_GUARD_FROM_LAST_BSS;
2082 /* remove it from next event array */
2083 nextEventArrayHead = nextEventArray[ nextEventArrayHead ].nextAPIndex;
2084 nextEventArraySize--;
2085 }
2086 else
2087 {
2088 TI_UINT32 beaconIntervalUsec =
2089 pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].beaconInterval * 1024;
2090
2091 /* if the next beacon also collide with DTIM */
2092 if ( TI_TRUE == scanMngrDTIMInRange( hScanMngr, nextEventArray[ nextEventArrayHead ].nextEventTSF + beaconIntervalUsec,
2093 nextEventArray[ nextEventArrayHead ].nextEventTSF + scanMethod->method.spsMethodParams.scanDuration + beaconIntervalUsec ))
2094 {
2095 /* An AP whose two consecutive beacons collide with current AP DTIM is not trackable by SPS!!!
2096 Shouldn't happen at a normal setup, but checked to avoid endless loop.
2097 First, remove it from the tracking list (by increasing it's track count above the maximum) */
2098 pScanMngr->BSSList.scanBSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].trackFailCount =
2099 pScanMngr->scanPolicy.maxTrackFailures + 1;
2100
2101 /* and also remove it from the SPS list */
2102 nextEventArrayHead = nextEventArray[ nextEventArrayHead ].nextAPIndex;
2103 nextEventArraySize--;
2104
2105 #ifdef TI_DBG
2106 /* update statistics */
2107 pScanMngr->stats.APsRemovedDTIMOverlap++;
2108 #endif
2109 }
2110 else
2111 {
2112 /* calculate next event TSF - will get the next beacon, since timeToStartInAdvance is added to current beacon TSF */
2113 nextEventArray[ nextEventArrayHead ].nextEventTSF =
2114 scanMngrCalculateNextEventTSF( hScanMngr, &(pScanMngr->BSSList),
2115 nextEventArray[ nextEventArrayHead ].trackListIndex,
2116 nextEventArray[ nextEventArrayHead ].nextEventTSF + timeToStartInAdvance + 1)
2117 - timeToStartInAdvance;
2118
2119 #ifdef SCAN_MNGR_SPS_DBG
2120 highValue = INT64_HIGHER( nextEventArray[ nextEventArrayHead ].nextEventTSF );
2121 lowValue = INT64_LOWER( nextEventArray[ nextEventArrayHead ].nextEventTSF );
2122 TRACE8( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "reacalculating next frame for BSSID:%02x:%02x:%02x:%02x:%02x:%02x at TSF:%x-%x, bacause of DTIM collision\n", pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 0 ], pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 1 ], pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 2 ], pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 3 ], pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 4 ], pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 5 ], highValue, lowValue);
2123 #endif
2124
2125 /* reinsert to the next event array, sorted */
2126 /* if still needs to be head, do nothing (because it's still head). otherwise: */
2127 if ( (1 < nextEventArraySize) && /* list has more than one entry */
2128 (nextEventArray[ nextEventArrayHead ].nextEventTSF > nextEventArray[ nextEventArray[ nextEventArrayHead ].nextAPIndex ].nextEventTSF)) /* first event in list is earlier */
2129 {
2130 /* first remove the head from the list */
2131 j = nextEventArrayHead;
2132 nextEventArrayHead = nextEventArray[ nextEventArrayHead ].nextAPIndex;
2133
2134 /* start with list head */
2135 i = nextEventArrayHead;
2136 /* while the new AP TSF is larger and list end had not been reached */
2137 while ( (nextEventArray[ i ].nextAPIndex != -1) && /* list end had not been reached */
2138 (nextEventArray[ nextEventArray[ i ].nextAPIndex ].nextEventTSF < nextEventArray[ j ].nextEventTSF)) /* next event TSF of the next AP in the list is smaller than that of the AP being inserted */
2139 {
2140 /* proceed to the next AP */
2141 i = nextEventArray[ i ].nextAPIndex;
2142 }
2143 /* insert this AP to the list, right after the next event entry found */
2144 nextEventArray[ j ].nextAPIndex = nextEventArray[ i ].nextAPIndex;
2145 nextEventArray[ i ].nextAPIndex = j;
2146 }
2147
2148 #ifdef SCAN_MNGR_SPS_DBG
2149 scanMngrDebugPrintSPSHelperList( hScanMngr, nextEventArray, nextEventArrayHead, maxNextEventArraySize );
2150 #endif
2151 #ifdef TI_DBG
2152 /* update statistics */
2153 pScanMngr->stats.SPSSavedByDTIMCheck++;
2154 #endif
2155 }
2156 }
2157 }
2158 else
2159 {
2160 /* calculate next event TSF */
2161 nextEventArray[ nextEventArrayHead ].nextEventTSF =
2162 scanMngrCalculateNextEventTSF( hScanMngr, &(pScanMngr->BSSList),
2163 nextEventArray[ nextEventArrayHead ].trackListIndex,
2164 EarliestTSFToInsert + timeToStartInAdvance ) - timeToStartInAdvance;
2165
2166 #ifdef SCAN_MNGR_SPS_DBG
2167 highValue = INT64_HIGHER( nextEventArray[ nextEventArrayHead ].nextEventTSF );
2168 lowValue = INT64_LOWER( nextEventArray[ nextEventArrayHead ].nextEventTSF );
2169 TRACE8( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "reacalculating next frame for BSSID:%02x:%02x:%02x:%02x:%02x:%02x at TSF:%x-%x\n", pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 0 ], pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 1 ], pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 2 ], pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 3 ], pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 4 ], pScanMngr->BSSList.BSSList[ nextEventArray[ nextEventArrayHead ].trackListIndex ].BSSID[ 5 ], highValue, lowValue);
2170 #endif
2171
2172 /* reinsert to the next event array, sorted */
2173 /* if still needs to be head, do nothing (because it's still head). otherwise: */
2174 if ( (1 < nextEventArraySize) && /* list has more than one entry */
2175 (nextEventArray[ nextEventArrayHead ].nextEventTSF > nextEventArray[ nextEventArray[ nextEventArrayHead ].nextAPIndex ].nextEventTSF)) /* first event in list is earlier */
2176 {
2177 /* first remove the head from the list */
2178 j = nextEventArrayHead;
2179 nextEventArrayHead = nextEventArray[ nextEventArrayHead ].nextAPIndex;
2180
2181 /* start with list head */
2182 i = nextEventArrayHead;
2183 /* while the new AP TSF is larger and list end had not been reached */
2184 while ( (nextEventArray[ i ].nextAPIndex != -1) && /* list end had not been reached */
2185 (nextEventArray[ nextEventArray[ i ].nextAPIndex ].nextEventTSF < nextEventArray[ j ].nextEventTSF)) /* next event TSF of the next AP in the list is smaller than that of the AP being inserted */
2186 {
2187 /* proceed to the next AP */
2188 i = nextEventArray[ i ].nextAPIndex;
2189 }
2190 /* insert this AP to the list, right after the next event entry found */
2191 nextEventArray[ j ].nextAPIndex = nextEventArray[ i ].nextAPIndex;
2192 nextEventArray[ i ].nextAPIndex = j;
2193 }
2194
2195 #ifdef SCAN_MNGR_SPS_DBG
2196 scanMngrDebugPrintSPSHelperList( hScanMngr, nextEventArray, nextEventArrayHead, maxNextEventArraySize );
2197 #endif
2198 }
2199 }
2200 /* For SPS scan, the scan duration is added to the command, since later on current TSF cannot be
2201 reevaluated. The scan duration is TSF at end of scan minus current TSF, divided by 1000 (convert
2202 to milliseconds) plus 1 (for the division reminder). */
2203 pScanMngr->scanParams.SPSScanDuration =
2204 (((TI_UINT32)(EarliestTSFToInsert - SCAN_SPS_GUARD_FROM_LAST_BSS - pScanMngr->currentTSF)) / 1000) + 1;
2205 }
2206
2207 /**
2208 * \\n
2209 * \date 07-Mar-2005\n
2210 * \brief Calculates local TSF of the next event (beacon or GPR) of the given tracked AP.\n
2211 *
2212 * Function Scope \e Private.\n
2213 * \param hScanMngr - handle to the scan manager object.\n
2214 * \param BSSList - a pointer to the track list.\n
2215 * \param entryIndex - the index of the AP for which calculation is requires in the tracking list.\n
2216 * \param initialTSFValue - local TSF value AFTER which the next event is to found.\n
2217 * \return The approximate current TSF
2218 */
scanMngrCalculateNextEventTSF(TI_HANDLE hScanMngr,scan_BSSList_t * BSSList,TI_UINT8 entryIndex,TI_UINT64 initialTSFValue)2219 TI_UINT64 scanMngrCalculateNextEventTSF( TI_HANDLE hScanMngr, scan_BSSList_t* BSSList, TI_UINT8 entryIndex, TI_UINT64 initialTSFValue )
2220 {
2221 TI_UINT64 remoteBeaconTSF, localBeaconTSF;
2222 TI_INT64 localRemoteTSFDelta;
2223 TI_UINT32 reminder;
2224 TI_INT32 averageDeltaChange = 0;
2225 int i;
2226 #ifdef SCAN_MNGR_SPS_DBG
2227 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
2228 #endif /* SCAN_MNGR_SPS_DBG */
2229
2230 /* graphical representation:
2231 E E E E E E E E E
2232 Remote TSF Line: | | | | | | | | |
2233 0 remoteTSF | | | | | | | | | Returned value
2234 +-----------------------+------+------+------+------+------+------+------+------+------+------+----------------...
2235
2236 Local TSF Line:
2237 0 localTSF initialTSFValue
2238 +-------------------+---------------------------------------------------------------+-----+---------------...
2239
2240 note that:
2241 1. both lines Don't start at the same time!
2242 2. remoteTSF and localTSF were measured when last frame was received from the tracked AP. the difference between their
2243 values is the constant difference between the two lines.
2244 3. initialTSFValue is the local TSF the first event after which is requested.
2245 4. returned value is the TSF (in local scale!) of the next event of the tracked AP.
2246 5. an E represents an occurring event, which is a scheduled frame transmission (beacon or GPR) of the tracked AP.
2247 */
2248
2249 /*
2250 * The next event TSF is calculated as follows:
2251 * first, the difference between the local TSF (that of the AP the STA is currently connected to) and the
2252 * remote TSF (that of the AP being tracked) is calculated using the TSF values measured when last scan was
2253 * performed. Than, the initial TSF value is converted to remote TSF value, using the delta just calculated.
2254 * The next remote TSF is found (in remote TSF value) by subtracting the reminder of dividing the current
2255 * remote TSF value by the remote beacon interval (time passed from last beacon) from the current remote TSF
2256 * (hence amounting to the last beacon remote TSF), and than adding beacon interval. This is finally converted
2257 * back to local TSF, which is the requested value.
2258 *
2259 * After all this is done, clock drift between current AP and remote AP is compensated. This is done in thr
2260 * following way: the delte between local TSF and remote TSF is compared to this value at the last scan
2261 * (if they are equal, the clocks tick at the same rate). This difference is store in an array holding a
2262 * configured number of such previous differences (currenlty 4). The average value of these previous values
2263 * is then calculated, and added the the TSF value calculated before. This way, the average drift between
2264 * the local AP and the candidate AP is measured, and the next drift value can be estimated and thus
2265 * taken into account.
2266 */
2267
2268 #ifdef SCAN_MNGR_SPS_DBG
2269 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "initial TSF value:%x-%x\n", INT64_HIGHER( initialTSFValue ), INT64_LOWER( initialTSFValue ));
2270 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "local time stamp:%x-%x\n", INT64_HIGHER( BSSList->scanBSSList[ entryIndex ].localTSF ), INT64_LOWER( BSSList->scanBSSList[ entryIndex ].localTSF ));
2271 #endif
2272 /* calculate the delta between local and remote TSF */
2273 localRemoteTSFDelta = BSSList->scanBSSList[ entryIndex ].localTSF -
2274 BSSList->BSSList[ entryIndex ].lastRxTSF;
2275 /* convert initial TSF to remote timeline */
2276 remoteBeaconTSF = initialTSFValue - localRemoteTSFDelta;
2277 #ifdef SCAN_MNGR_SPS_DBG
2278 TRACE4( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Local TSF:%u-%u, Remote TSF: %u-%u\n", INT64_HIGHER(BSSList->scanBSSList[ entryIndex ].localTSF), INT64_LOWER(BSSList->scanBSSList[ entryIndex ].localTSF), INT64_HIGHER(BSSList->BSSList[ entryIndex ].lastRxTSF), INT64_LOWER(BSSList->BSSList[ entryIndex ].lastRxTSF)));
2279 TRACE4( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "TSF delta:%u-%u, current remote TSF:%u-%u\n", INT64_HIGHER(localRemoteTSFDelta), INT64_LOWER(localRemoteTSFDelta), INT64_HIGHER(remoteBeaconTSF ), INT64_LOWER(remoteBeaconTSF ));
2280 #endif
2281 /* find last remote beacon transmission by subtracting the reminder of current remote TSF divided
2282 by the beacon interval (indicating how much time passed since last beacon) from current remote
2283 TSF */
2284 reminder = reminder64( remoteBeaconTSF, BSSList->BSSList[ entryIndex ].beaconInterval * 1024 );
2285 remoteBeaconTSF -= reminder;
2286
2287 #ifdef SCAN_MNGR_SPS_DBG
2288 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "reminder=%d\n",reminder);
2289 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Last remote beacon TSF:%x-%x\n", INT64_HIGHER(remoteBeaconTSF), INT64_LOWER(remoteBeaconTSF));
2290 #endif
2291 /* advance from last beacon to next beacon */
2292 remoteBeaconTSF += BSSList->BSSList[ entryIndex ].beaconInterval * 1024;
2293 #ifdef SCAN_MNGR_SPS_DBG
2294 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Next remote beacon TSF:%x-%x\n", INT64_HIGHER(remoteBeaconTSF), INT64_LOWER(remoteBeaconTSF));
2295 #endif
2296
2297 #ifdef SCAN_SPS_USE_DRIFT_COMPENSATION
2298 /* update delta change array with the change between current and last delta (if last delta is valid) */
2299 if ( 0 != BSSList->scanBSSList[ entryIndex ].prevTSFDelta )
2300 {
2301 BSSList->scanBSSList[ entryIndex ].deltaChangeArray[ BSSList->scanBSSList[ entryIndex ].deltaChangeArrayIndex ] =
2302 (TI_INT32)(localRemoteTSFDelta - BSSList->scanBSSList[ entryIndex ].prevTSFDelta);
2303 #ifdef SCAN_MNGR_SPS_DBG
2304 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "current delta^2:%d\n", localRemoteTSFDelta - BSSList->scanBSSList[ entryIndex ].prevTSFDelta);
2305 #endif
2306 if ( SCAN_SPS_NUM_OF_TSF_DELTA_ENTRIES == ++BSSList->scanBSSList[ entryIndex ].deltaChangeArrayIndex )
2307 {
2308 BSSList->scanBSSList[ entryIndex ].deltaChangeArrayIndex = 0;
2309 }
2310 }
2311 BSSList->scanBSSList[ entryIndex ].prevTSFDelta = localRemoteTSFDelta;
2312
2313 /* calculate average delta change, and add (or subtract) it from beacon timing */
2314 for ( i = 0; i < SCAN_SPS_NUM_OF_TSF_DELTA_ENTRIES; i++ )
2315 {
2316 averageDeltaChange += BSSList->scanBSSList[ entryIndex ].deltaChangeArray[ i ];
2317 }
2318 averageDeltaChange /= SCAN_SPS_NUM_OF_TSF_DELTA_ENTRIES;
2319 #ifdef SCAN_MNGR_SPS_DBG
2320 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "average delta change: %d\n", averageDeltaChange);
2321 #endif /* SCAN_MNGR_SPS_DBG */
2322 remoteBeaconTSF += averageDeltaChange;
2323 #endif
2324
2325 /* convert to local TSF */
2326 localBeaconTSF = remoteBeaconTSF + localRemoteTSFDelta;
2327
2328 #ifdef SCAN_SPS_USE_DRIFT_COMPENSATION
2329 /* if beacon (in local TSF) is before initial TSF value (possible due to drift compensation),
2330 proceed to next beacon */
2331 if ( localBeaconTSF < initialTSFValue )
2332 {
2333 localBeaconTSF += (BSSList->BSSList[ entryIndex ].beaconInterval * 1024);
2334 }
2335 #endif
2336
2337 return localBeaconTSF;
2338 }
2339
2340 /**
2341 * \\n
2342 * \date 20-September-2005\n
2343 * \brief Check whether a time range collides with current AP DTIM
2344 *
2345 * Function Scope \e Private.\n
2346 * \param hScanMngr - handle to the scan manager object.\n
2347 * \param rangeStart - the time range start TSF.\n
2348 * \param rangeEnd - the time range end TSF.\n
2349 * \return Whether the event collides with a DTIM (TRUF if it does, TI_FALSE if it doesn't).\n
2350 */
scanMngrDTIMInRange(TI_HANDLE hScanMngr,TI_UINT64 rangeStart,TI_UINT64 rangeEnd)2351 TI_BOOL scanMngrDTIMInRange( TI_HANDLE hScanMngr, TI_UINT64 rangeStart, TI_UINT64 rangeEnd )
2352 {
2353 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
2354 TI_UINT64 DTIMEventStart, DTIMEventEnd;
2355 TI_UINT32 DTIMPeriodInUsec; /* DTIM period in micro seconds */
2356
2357 #ifdef SCAN_MNGR_DTIM_DBG
2358 TRACE4( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "DTIM check: SPS raneg start:%x-%x, end:%x-%x\n", INT64_HIGHER(rangeStart), INT64_LOWER(rangeStart), INT64_HIGHER(rangeEnd), INT64_LOWER(rangeEnd));
2359 #endif
2360
2361 /* calculate DTIM period */
2362 DTIMPeriodInUsec = pScanMngr->currentBSSBeaconInterval * 1024 * pScanMngr->currentBSSDtimPeriod;
2363
2364 #ifdef SCAN_MNGR_DTIM_DBG
2365 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "DTIM period in usec: %d\n", DTIMPeriodInUsec);
2366 #endif
2367
2368 /* calculate (from DTIM count) the first DTIM after the last seen beacon. The last seen beacon will always
2369 occur before the SPS - because it already happened, and the SPS is a future event. However, the next DTIM
2370 is not necessarily prior to the SPS - it is also a future event (if the last beacon was not a DTIM) */
2371 if ( 0 == pScanMngr->lastLocalBcnDTIMCount )
2372 { /* The last beacon was a DTIM */
2373 DTIMEventStart = pScanMngr->lastLocalBcnTSF;
2374 }
2375 else
2376 { /* The last beacon was not a DTIM - calculate the next beacon that will be a DTIM */
2377 DTIMEventStart = pScanMngr->lastLocalBcnTSF +
2378 ((pScanMngr->currentBSSDtimPeriod - pScanMngr->lastLocalBcnDTIMCount) * pScanMngr->currentBSSBeaconInterval);
2379 TRACE6(pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "\n Next DTIM TSF:%u-%u , last beacon TSF:%u-%u, last DTIM count: %d, beacon interval: %d\n", INT64_HIGHER(DTIMEventStart), INT64_LOWER(DTIMEventStart), INT64_HIGHER(pScanMngr->lastLocalBcnTSF), INT64_LOWER(pScanMngr->lastLocalBcnTSF), pScanMngr->lastLocalBcnDTIMCount, pScanMngr->currentBSSBeaconInterval);
2380 }
2381 #ifdef SCAN_MNGR_DTIM_DBG
2382 TRACE6( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Next DTIM TSF:%u-%u, last beacon TSF:%u-%u, last DTIM count: %d, beacon interval: %d\n", INT64_HIGHER(DTIMEventStart), INT64_LOWER(DTIMEventStart), INT64_HIGHER(pScanMngr->lastLocalBcnTSF), INT64_LOWER(pScanMngr->lastLocalBcnTSF), pScanMngr->lastLocalBcnDTIMCount, pScanMngr->currentBSSBeaconInterval);
2383 #endif
2384
2385 /* calculate the DTIM event end (add the DTIM length). Note that broadcast frames after the DTIM are not
2386 taken into consideration because their availability and length varies. Even if at some point SPS will be
2387 missed due to broadcast RX frames, it does not mean this AP cannot be tracked. */
2388 DTIMEventEnd = DTIMEventStart + SCAN_SPS_FW_DTIM_LENGTH;
2389
2390 /* if this DTIM is after the SPS end - than no collision will occur! */
2391 if ( DTIMEventStart > rangeEnd )
2392 {
2393 #ifdef SCAN_MNGR_DTIM_DBG
2394 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "no collision because DTIM is after SPS\n");
2395 #endif
2396 return TI_FALSE;
2397 }
2398 /* if this DTIM end is not before the SPS range start - it means the DTIM is colliding with the SPS, because
2399 it neither ends before the SPS nor starts after it */
2400 else if ( DTIMEventEnd >= rangeStart )
2401 {
2402 #ifdef SCAN_MNGR_DTIM_DBG
2403 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Collision beacuse DTIM is not before SPS\n");
2404 #endif
2405 return TI_TRUE;
2406 }
2407 /* the DTIM is before the SPS range - find the first DTIM after the SPS start (and check if it's colliding
2408 with the SPS range */
2409 else
2410 {
2411 /* get the usec difference from the SPS range start to the last DTIM */
2412 TI_UINT64 usecDiffFromRangeStartToLastDTIM = rangeStart - DTIMEventStart;
2413 /* get the reminder from the usec difference divided by the DTIM period - the time (in usec) from last DTIM
2414 to SPS start */
2415 TI_UINT32 reminder = reminder64( usecDiffFromRangeStartToLastDTIM, DTIMPeriodInUsec );
2416 /* get the next DTIM start time by adding DTIM period to the last DTIM before the SPS range start */
2417 DTIMEventStart = rangeStart - reminder + DTIMPeriodInUsec;
2418 /* get DTIM end time */
2419 DTIMEventEnd = DTIMEventStart + SCAN_SPS_FW_DTIM_LENGTH;
2420 #ifdef SCAN_MNGR_DTIM_DBG
2421 TRACE7( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Diff from range start to last DTIM: %x-%x, reminder:%d, DTIM start:%x-%x, DTIM end: %x-%x\n", INT64_HIGHER(usecDiffFromRangeStartToLastDTIM), INT64_LOWER(usecDiffFromRangeStartToLastDTIM), reminder, INT64_HIGHER(DTIMEventStart), INT64_LOWER(DTIMEventStart), INT64_HIGHER(DTIMEventEnd), INT64_LOWER(DTIMEventEnd));
2422 #endif
2423
2424 /* if the SPS starts after the DTIM ends or before the DTIM starts - no collision occurs */
2425 if ( (rangeStart > DTIMEventEnd) || (rangeEnd < DTIMEventStart))
2426 {
2427 #ifdef SCAN_MNGR_DTIM_DBG
2428 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "No collision will occur because DTIM is before or after SPS\n");
2429 #endif
2430 return TI_FALSE;
2431 }
2432 /* otherwise - a collision will occur! */
2433 {
2434 #ifdef SCAN_MNGR_DTIM_DBG
2435 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Collision will occur!\n");
2436 #endif
2437 return TI_TRUE;
2438 }
2439 }
2440 }
2441
2442 /**
2443 * \\n
2444 * \date 03-Mar-2005\n
2445 * \brief Add a normal channel entry to the object workspace scan command.\n
2446 *
2447 * Function Scope \e Private.\n
2448 * \param hScanMngr - handle to the scan manager object.\n
2449 * \param scanMethod - The scan method (and parameters) to use.\n
2450 * \param channel - the channel index.\n
2451 * \param BSSID - pointer to the BSSID to use (may be broadcast.\n
2452 * \param txPowerDbm - tx power to transmit probe requests.\n
2453 */
scanMngrAddNormalChannel(TI_HANDLE hScanMngr,TScanMethod * scanMethod,TI_UINT8 channel,TMacAddr * BSSID,TI_UINT8 txPowerDbm)2454 void scanMngrAddNormalChannel( TI_HANDLE hScanMngr, TScanMethod* scanMethod, TI_UINT8 channel,
2455 TMacAddr* BSSID, TI_UINT8 txPowerDbm )
2456 {
2457 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
2458 int commandChannelIndex;
2459 TScanBasicMethodParams* basicMethodParams;
2460
2461 /* get next channel in the object workspace */
2462 commandChannelIndex = pScanMngr->scanParams.numOfChannels;
2463 pScanMngr->scanParams.numOfChannels++;
2464
2465 /* get basic method params pointer according to scan type */
2466 switch ( scanMethod->scanType )
2467 {
2468 case SCAN_TYPE_NORMAL_PASSIVE:
2469 case SCAN_TYPE_NORMAL_ACTIVE:
2470 basicMethodParams = &(scanMethod->method.basicMethodParams);
2471 break;
2472
2473 case SCAN_TYPE_TRIGGERED_PASSIVE:
2474 case SCAN_TYPE_TRIGGERED_ACTIVE:
2475 basicMethodParams = &(scanMethod->method.TidTriggerdMethodParams.basicMethodParams);
2476 break;
2477
2478 default:
2479 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Unercognized scan type %d when adding normal channel to scan list.\n", scanMethod->scanType );
2480 basicMethodParams = NULL;
2481 return;
2482 }
2483
2484 /* set params */
2485 pScanMngr->scanParams.channelEntry[ commandChannelIndex ].normalChannelEntry.channel = channel;
2486 pScanMngr->scanParams.channelEntry[ commandChannelIndex ].normalChannelEntry.txPowerDbm =
2487 TI_MIN( txPowerDbm, basicMethodParams->probReqParams.txPowerDbm );
2488 pScanMngr->scanParams.channelEntry[ commandChannelIndex ].normalChannelEntry.maxChannelDwellTime =
2489 basicMethodParams->maxChannelDwellTime;
2490 pScanMngr->scanParams.channelEntry[ commandChannelIndex ].normalChannelEntry.minChannelDwellTime =
2491 basicMethodParams->minChannelDwellTime;
2492 pScanMngr->scanParams.channelEntry[ commandChannelIndex ].normalChannelEntry.earlyTerminationEvent =
2493 basicMethodParams->earlyTerminationEvent;
2494 pScanMngr->scanParams.channelEntry[ commandChannelIndex ].normalChannelEntry.ETMaxNumOfAPframes =
2495 basicMethodParams->ETMaxNumberOfApFrames;
2496
2497 MAC_COPY (pScanMngr->scanParams.channelEntry[ commandChannelIndex ].normalChannelEntry.bssId, *BSSID);
2498 }
2499
2500 /**
2501 * \\n
2502 * \date 02-Mar-2005\n
2503 * \brief Removes an entry from the BSS list (by replacing it with another entry, if any).
2504 *
2505 * Function Scope \e Private.\n
2506 * \param hScanMngr - handle to the scan manager object.\n
2507 * \param BSSEntryIndex - index of the entry to remove.\n
2508 */
scanMngrRemoveBSSListEntry(TI_HANDLE hScanMngr,TI_UINT8 BSSEntryIndex)2509 void scanMngrRemoveBSSListEntry( TI_HANDLE hScanMngr, TI_UINT8 BSSEntryIndex )
2510 {
2511 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
2512 TI_UINT8* tempResultBuffer;
2513
2514 #ifdef TI_DBG
2515 /*update statistics */
2516 if ( SCAN_MNGR_STAT_MAX_TRACK_FAILURE <= pScanMngr->BSSList.scanBSSList[ BSSEntryIndex ].trackFailCount )
2517 {
2518 pScanMngr->stats.ConsecutiveTrackFailCountHistogram[ SCAN_MNGR_STAT_MAX_TRACK_FAILURE - 1 ]++;
2519 }
2520 else
2521 {
2522 pScanMngr->stats.ConsecutiveTrackFailCountHistogram[ pScanMngr->BSSList.scanBSSList[ BSSEntryIndex ].trackFailCount ]++;
2523 }
2524 #endif
2525 /* if no more entries are available, simply reduce the number of entries.
2526 As this is the last entry, it won't be accessed any more. */
2527 if ( (pScanMngr->BSSList.numOfEntries-1) == BSSEntryIndex )
2528 {
2529
2530 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Removing last entry %d in BSS list\n", pScanMngr->BSSList.numOfEntries);
2531
2532 pScanMngr->BSSList.numOfEntries--;
2533 }
2534 else
2535 {
2536 #ifdef SCAN_MNGR_DBG
2537 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Removing entry %d of %d\n", BSSEntryIndex, pScanMngr->BSSList.numOfEntries);
2538 #endif
2539 /* keep the scan result buffer pointer */
2540 tempResultBuffer = pScanMngr->BSSList.BSSList[ BSSEntryIndex ].pBuffer;
2541 /* copy the last entry over this one */
2542 os_memoryCopy( pScanMngr->hOS, &(pScanMngr->BSSList.BSSList[ BSSEntryIndex ]),
2543 &(pScanMngr->BSSList.BSSList[ pScanMngr->BSSList.numOfEntries-1 ]),
2544 sizeof(bssEntry_t));
2545 os_memoryCopy( pScanMngr->hOS, &(pScanMngr->BSSList.scanBSSList[ BSSEntryIndex ]),
2546 &(pScanMngr->BSSList.scanBSSList[ pScanMngr->BSSList.numOfEntries-1 ]),
2547 sizeof(scan_BSSEntry_t));
2548 /* replace the scan result buffer of the last entry */
2549 pScanMngr->BSSList.BSSList[ pScanMngr->BSSList.numOfEntries-1 ].pBuffer = tempResultBuffer;
2550 /* decrease the number of BSS entries */
2551 pScanMngr->BSSList.numOfEntries--;
2552 }
2553 }
2554
2555 /**
2556 * \\n
2557 * \date 02-Mar-2005\n
2558 * \brief Removes all BSS list entries that are neither neighbor APs not on a policy defined channel.\n
2559 *
2560 * Function Scope \e Private.\n
2561 * \param hScanMngr - handle to the scan manager object.\n
2562 * \param bCheckNeighborAPs - whether to verify that APs marked as neighbor APs are really neighbor APs.\n
2563 * \param bCheckChannels - whether to verify that APs not marked as neighbor APs are on policy defined channel.\n
2564 */
scanMngrUpdateBSSList(TI_HANDLE hScanMngr,TI_BOOL bCheckNeighborAPs,TI_BOOL bCheckChannels)2565 void scanMngrUpdateBSSList( TI_HANDLE hScanMngr, TI_BOOL bCheckNeighborAPs, TI_BOOL bCheckChannels )
2566 {
2567 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
2568 int BSSEntryIndex;
2569
2570 /* loop on all BSS list entry */
2571 for ( BSSEntryIndex = 0; BSSEntryIndex < pScanMngr->BSSList.numOfEntries; BSSEntryIndex++ )
2572 {
2573 /* an AP can be in the BSS list either because it's a neighbor AP or, if not, because it's on a
2574 policy defined channel. When Neighbor AP list is changed, it is only necessary to check APs that
2575 are in the list because they are neighbor APs. When the policy is changed, it is only necessary
2576 to check APs that are in the list because they are on a policy defined channel. */
2577
2578 /* if a check for neighbor APs is requested, check only APs that are designated as neighbor APs,
2579 and only check if they still are neighbor APs */
2580 if ( (TI_TRUE == bCheckNeighborAPs) &&
2581 (TI_TRUE == pScanMngr->BSSList.BSSList[ BSSEntryIndex ].bNeighborAP) &&
2582 (-1 == scanMngrGetNeighborAPIndex( hScanMngr,
2583 pScanMngr->BSSList.BSSList[ BSSEntryIndex ].band,
2584 &(pScanMngr->BSSList.BSSList[ BSSEntryIndex ].BSSID))))
2585 {
2586 /* remove it */
2587 scanMngrRemoveBSSListEntry( hScanMngr, BSSEntryIndex );
2588 }
2589
2590 /* if a check for policy defined channels is requested, check only APs that are not designated as
2591 neighbor APs */
2592 if ( (TI_TRUE == bCheckChannels) &&
2593 (TI_FALSE == pScanMngr->BSSList.BSSList[ BSSEntryIndex ].bNeighborAP) &&
2594 (TI_FALSE == scanMngrIsPolicyChannel( hScanMngr,
2595 pScanMngr->BSSList.BSSList[ BSSEntryIndex ].band,
2596 pScanMngr->BSSList.BSSList[ BSSEntryIndex ].channel )))
2597 {
2598 /* remove it */
2599 scanMngrRemoveBSSListEntry( hScanMngr, BSSEntryIndex );
2600 }
2601 }
2602 }
2603
2604 /**
2605 * \\n
2606 * \date 02-Mar-2005\n
2607 * \brief returns the index of a neighbor AP.\n
2608 *
2609 * Function Scope \e Private.\n
2610 * \param hScanMngr - handle to the scan manager object.\n
2611 * \param band - the band on which the AP resides.\n
2612 * \param bssId - the AP's BSSID.\n
2613 * \return the index into the neighbor AP list for the given address, -1 if AP is not in list.\n
2614 */
scanMngrGetNeighborAPIndex(TI_HANDLE hScanMngr,ERadioBand band,TMacAddr * bssId)2615 TI_INT8 scanMngrGetNeighborAPIndex( TI_HANDLE hScanMngr, ERadioBand band, TMacAddr* bssId )
2616 {
2617 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
2618 int i;
2619
2620 /* loop on all neighbor APS for this AP's band, and compare BSSID's */
2621 for ( i = 0; i < pScanMngr->neighborAPsDiscoveryList[ band ].numOfEntries; i++ )
2622 {
2623 if (MAC_EQUAL (*bssId, pScanMngr->neighborAPsDiscoveryList[ band ].APListPtr[ i ].BSSID))
2624 {
2625 return i;
2626 }
2627 }
2628
2629 /* if the AP wasn't found in the list, it's not a neighbor AP... */
2630 return -1;
2631 }
2632
2633 /**
2634 * \\n
2635 * \date 02-Mar-2005\n
2636 * \brief Checks whether a channel is defined on a policy.\n
2637 *
2638 * Function Scope \e Private.\n
2639 * \param hScanMngr - handle to the scan manager object.\n
2640 * \param band - the band on which the channel is.\n
2641 * \param channel - the channel number.\n
2642 * \return TI_TRUE if channel is defined on policy, TI_FALSE otherwise.\n
2643 */
scanMngrIsPolicyChannel(TI_HANDLE hScanMngr,ERadioBand band,TI_UINT8 channel)2644 TI_BOOL scanMngrIsPolicyChannel( TI_HANDLE hScanMngr, ERadioBand band, TI_UINT8 channel )
2645 {
2646 int i;
2647 TScanBandPolicy* bandPolicy = scanMngrGetPolicyByBand( hScanMngr, band );
2648
2649
2650 /* check if the AP's band is defined in the policy */
2651 if ( NULL == bandPolicy )
2652 {
2653 return TI_FALSE;
2654 }
2655
2656 /* loop on all channels for the AP's band */
2657 for ( i = 0; i < bandPolicy->numOfChannles; i++ )
2658 {
2659 if ( bandPolicy->channelList[ i ] == channel )
2660 {
2661 return TI_TRUE;
2662 }
2663 }
2664
2665 /* if no channel was found, the AP is NOT on a policy configured channel */
2666 return TI_FALSE;
2667 }
2668
2669 /**
2670 * \\n
2671 * \date 18-Apr-2005\n
2672 * \brief Converts scan concentrator result status to scan manager result status, to be returned to roaming manager.\n
2673 *
2674 * Function Scope \e Private.\n
2675 * \param result status - scan concentrator result status.\n
2676 * \return appropriate scan manager status.\n
2677 */
scanMngrConvertResultStatus(EScanCncnResultStatus resultStatus)2678 scan_mngrResultStatus_e scanMngrConvertResultStatus( EScanCncnResultStatus resultStatus )
2679 {
2680 switch (resultStatus)
2681 {
2682 case SCAN_CRS_SCAN_COMPLETE_OK:
2683 return SCAN_MRS_SCAN_COMPLETE_OK;
2684 /* break; - unreachable */
2685
2686 case SCAN_CRS_SCAN_RUNNING:
2687 return SCAN_MRS_SCAN_RUNNING;
2688 /* break; - unreachable */
2689
2690 case SCAN_CRS_SCAN_FAILED:
2691 return SCAN_MRS_SCAN_FAILED;
2692 /* break; - unreachable */
2693
2694 case SCAN_CRS_SCAN_STOPPED:
2695 return SCAN_MRS_SCAN_STOPPED;
2696 /* break; - unreachable */
2697
2698 case SCAN_CRS_TSF_ERROR:
2699 return SCAN_MRS_SCAN_FAILED;
2700 /* break; - unreachable */
2701
2702 case SCAN_CRS_SCAN_ABORTED_FW_RESET:
2703 return SCAN_MRS_SCAN_ABORTED_FW_RESET;
2704 /* break; - unreachable */
2705
2706 case SCAN_CRS_SCAN_ABORTED_HIGHER_PRIORITY:
2707 return SCAN_MRS_SCAN_ABORTED_HIGHER_PRIORITY;
2708 /* break; - unreachable */
2709
2710 default:
2711 return SCAN_MRS_SCAN_FAILED;
2712 /* break; - unreachable */
2713 }
2714 }
2715
2716 /************************************************************************/
2717 /* Trace functions */
2718 /************************************************************************/
2719
2720 #ifdef REPORT_LOG
2721
2722 static char scanTypeDesc[ 6 ][ MAX_DESC_LENGTH ] =
2723 {
2724 "passive normal scan",
2725 "active normal scan",
2726 "SPS scan",
2727 "passive triggered scan",
2728 "active triggered scan",
2729 "no scan type"
2730 };
2731
2732 static char earlyTerminationConditionDesc[ 4 ][ MAX_DESC_LENGTH ] =
2733 {
2734 "Early termination disabled",
2735 "Early termination on beacon",
2736 "Early termination on probe response",
2737 "Early termination on both"
2738 };
2739
2740 #ifdef TI_DBG
2741 static char booleanDesc[ 2 ][ MAX_DESC_LENGTH ] =
2742 {
2743 "No",
2744 "Yes"
2745 };
2746
2747 static char contScanStatesDesc[ SCAN_CSS_NUM_OF_STATES ][ MAX_DESC_LENGTH ] =
2748 {
2749 "IDLE",
2750 "TRACKING ON G",
2751 "TRACKING ON A",
2752 "DISCOVERING",
2753 "STOPPING"
2754 };
2755
2756 static char immedScanStatesDesc[ SCAN_ISS_NUM_OF_STATES ][ MAX_DESC_LENGTH ] =
2757 {
2758 "IDLE",
2759 "IMMEDIATE ON G",
2760 "IMMEDIATE ON A",
2761 "STOPPING"
2762 };
2763
2764 static char discoveryPartDesc[ SCAN_SDP_NUMBER_OF_DISCOVERY_PARTS ][ MAX_DESC_LENGTH ] =
2765 {
2766 "G neighbor APs",
2767 "A neighbor APs",
2768 "G channels",
2769 "A Channels",
2770 "No discovery"
2771 };
2772
2773 static char neighborDiscovreyStateDesc[ SCAN_NDS_NUMBER_OF_NEIGHBOR_DISCOVERY_STATES ][ MAX_DESC_LENGTH ] =
2774 {
2775 "Discovered",
2776 "Not discovered",
2777 "Current AP"
2778 };
2779
2780 static char earlyTerminationDesc[ SCAN_ET_COND_NUM_OF_CONDS ][ MAX_DESC_LENGTH ] =
2781 {
2782 "None",
2783 "Beacon",
2784 "Prob. resp."
2785 "Bcn & prob. resp."
2786 };
2787 #endif
2788
2789 #endif
2790
2791 /**
2792 * \\n
2793 * \date 09-Mar-2005\n
2794 * \brief Print a neighbor AP list.\n
2795 *
2796 * Function Scope \e Private.\n
2797 * \param hScanMngr - handle to the scan manager object.\n
2798 * \param neighborAPList - the list of neighbor APs to print.\n
2799 */
scanMngrTracePrintNeighborAPsList(TI_HANDLE hScanMngr,neighborAPList_t * neighborAPList)2800 void scanMngrTracePrintNeighborAPsList( TI_HANDLE hScanMngr, neighborAPList_t *neighborAPList )
2801 {
2802 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
2803 int i;
2804
2805 /* print number of entries */
2806 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Neighbor AP list with %d entries.\n\n", neighborAPList->numOfEntries);
2807
2808 /* print all APs in list */
2809 for ( i = 0; i < neighborAPList->numOfEntries; i++ )
2810 {
2811 scanMngrTracePrintNeighborAP( hScanMngr, &(neighborAPList->APListPtr[ i ]));
2812 }
2813 }
2814
2815 /**
2816 * \\n
2817 * \date 09-Mar-2005\n
2818 * \brief Print a neighbor AP.\n
2819 *
2820 * Function Scope \e Private.\n
2821 * \param hScanMngr - handle to the scan manager object.\n
2822 * \param neighborAP - the neighbor AP to print.\n
2823 */
scanMngrTracePrintNeighborAP(TI_HANDLE hScanMngr,neighborAP_t * neighborAP)2824 void scanMngrTracePrintNeighborAP( TI_HANDLE hScanMngr, neighborAP_t* neighborAP )
2825 {
2826 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
2827
2828 /* print neighbor AP content */
2829 TRACE7( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Neighbor AP band: , channel: %d, MAC address (BSSID): %2x:%2x:%2x:%2x:%2x:%2xn", neighborAP->channel, neighborAP->BSSID[ 0 ], neighborAP->BSSID[ 1 ], neighborAP->BSSID[ 2 ], neighborAP->BSSID[ 3 ], neighborAP->BSSID[ 4 ], neighborAP->BSSID[ 5 ]);
2830 }
2831
2832 /**
2833 * \\n
2834 * \date 09-Mar-2005\n
2835 * \brief Print scan policy.\n
2836 *
2837 * Function Scope \e Private.\n
2838 * \param scanPolicy - scan policy to print.\n
2839 */
scanMngrTracePrintScanPolicy(TScanPolicy * scanPolicy)2840 void scanMngrTracePrintScanPolicy( TScanPolicy* scanPolicy )
2841 {
2842 int i;
2843
2844 /* print general policy parameters */
2845 WLAN_OS_REPORT(("Global policy parameters:\n"));
2846 WLAN_OS_REPORT(("Normal scan interval: %d, deteriorating scan interval: %d\n",
2847 scanPolicy->normalScanInterval, scanPolicy->deterioratingScanInterval));
2848 WLAN_OS_REPORT(("BSS list size: %d, numnber of tracked APs to start discovery: %d, "
2849 "Max track failures:% d\n", scanPolicy->BSSListSize,
2850 scanPolicy->BSSNumberToStartDiscovery, scanPolicy->maxTrackFailures));
2851
2852 /* print band policy parameters for all available bands */
2853 for ( i = 0; i < scanPolicy->numOfBands; i++ )
2854 {
2855 scanMngrTracePrintBandScanPolicy( &(scanPolicy->bandScanPolicy[ i ]));
2856 }
2857 }
2858
2859 /**
2860 * \\n
2861 * \date 09-Mar-2005\n
2862 * \brief Print a band scan policy AP.\n
2863 *
2864 * Function Scope \e Private.\n
2865 * \param bandPolicy - the band scan policy to print.\n
2866 */
scanMngrTracePrintBandScanPolicy(TScanBandPolicy * bandPolicy)2867 void scanMngrTracePrintBandScanPolicy( TScanBandPolicy* bandPolicy )
2868 {
2869 int i;
2870
2871 WLAN_OS_REPORT(("Band scan policy for band: %s\n",
2872 (RADIO_BAND_2_4_GHZ == bandPolicy->band ? "2.4 GHz (b/g)" : "5.0 GHz (a)")));
2873 WLAN_OS_REPORT(("Maximal number of channels to scan at each discovery interval %d:\n",
2874 bandPolicy->numOfChannlesForDiscovery));
2875 WLAN_OS_REPORT(("RSSI Threshold: %d\n", bandPolicy->rxRSSIThreshold));
2876 WLAN_OS_REPORT(("Tracking method:\n"));
2877 scanMngrTracePrintScanMethod( &(bandPolicy->trackingMethod));
2878 WLAN_OS_REPORT(("Discovery method:\n"));
2879 scanMngrTracePrintScanMethod( &(bandPolicy->discoveryMethod));
2880 WLAN_OS_REPORT(("Immediate scan method:\n"));
2881 scanMngrTracePrintScanMethod( &(bandPolicy->immediateScanMethod));
2882 WLAN_OS_REPORT(("Channels: "));
2883 for( i = 0; i < bandPolicy->numOfChannles; i++ )
2884 {
2885 WLAN_OS_REPORT(("%d ", bandPolicy->channelList[ i ]));
2886 }
2887 WLAN_OS_REPORT(("\n"));
2888 }
2889
2890 /**
2891 * \\n
2892 * \date 09-Mar-2005\n
2893 * \brief Print a scan method
2894 *
2895 * Function Scope \e Private.\n
2896 * \param scanMethod - the scan method to print.\n
2897 */
scanMngrTracePrintScanMethod(TScanMethod * scanMethod)2898 void scanMngrTracePrintScanMethod( TScanMethod* scanMethod )
2899 {
2900 WLAN_OS_REPORT(("Scan type: %s\n", scanTypeDesc[ scanMethod->scanType ]));
2901
2902 switch (scanMethod->scanType)
2903 {
2904 case SCAN_TYPE_NORMAL_ACTIVE:
2905 case SCAN_TYPE_NORMAL_PASSIVE:
2906 scanMngrTracePrintNormalScanMethod( &(scanMethod->method.basicMethodParams));
2907 break;
2908
2909 case SCAN_TYPE_TRIGGERED_ACTIVE:
2910 case SCAN_TYPE_TRIGGERED_PASSIVE:
2911 scanMngrTracePrintTriggeredScanMethod( &(scanMethod->method.TidTriggerdMethodParams));
2912 break;
2913
2914 case SCAN_TYPE_SPS:
2915 scanMngrTracePrintSPSScanMethod( &(scanMethod->method.spsMethodParams));
2916 break;
2917
2918 case SCAN_TYPE_NO_SCAN:
2919 default:
2920 WLAN_OS_REPORT(("No scan method defined\n"));
2921 break;
2922 }
2923 }
2924
2925 /**
2926 * \\n
2927 * \date 09-Mar-2005\n
2928 * \brief print a normal scan method
2929 *
2930 * Function Scope \e Private.\n
2931 * \param basicMethodParams - the basic method parameters to print.\n
2932 */
scanMngrTracePrintNormalScanMethod(TScanBasicMethodParams * basicMethodParams)2933 void scanMngrTracePrintNormalScanMethod( TScanBasicMethodParams* basicMethodParams )
2934 {
2935 WLAN_OS_REPORT(("Max channel dwell time: %d, min channel dwell time: %d\n",
2936 basicMethodParams->maxChannelDwellTime, basicMethodParams->minChannelDwellTime));
2937 WLAN_OS_REPORT(("Early termination condition: %s, frame number for early termination: %d\n",
2938 earlyTerminationConditionDesc[ basicMethodParams->earlyTerminationEvent >> 4 ],
2939 basicMethodParams->ETMaxNumberOfApFrames));
2940 WLAN_OS_REPORT(("Number of probe requests: %d, TX level: %d, probe request rate: %d\n",
2941 basicMethodParams->probReqParams.numOfProbeReqs,
2942 basicMethodParams->probReqParams.txPowerDbm,
2943 basicMethodParams->probReqParams.bitrate));
2944 }
2945
2946 /**
2947 * \\n
2948 * \date 09-Mar-2005\n
2949 * \brief print an AC triggered scan method
2950 *
2951 * Function Scope \e Private.\n
2952 * \param triggeredMethodParams - the AC-triggered method parameters to print.\n
2953 */
scanMngrTracePrintTriggeredScanMethod(TScanTidTriggeredMethodParams * triggeredMethodParams)2954 void scanMngrTracePrintTriggeredScanMethod( TScanTidTriggeredMethodParams* triggeredMethodParams )
2955 {
2956 WLAN_OS_REPORT(("Triggering Tid: %d\n", triggeredMethodParams->triggeringTid));
2957 scanMngrTracePrintNormalScanMethod( &(triggeredMethodParams->basicMethodParams));
2958 }
2959
2960 /**
2961 * \\n
2962 * \date 09-Mar-2005\n
2963 * \brief print a SPS scan method
2964 *
2965 * Function Scope \e Private.\n
2966 * \param SPSMethodParams - the SPS method parameters to print.\n
2967 */
scanMngrTracePrintSPSScanMethod(TScanSPSMethodParams * SPSMethodParams)2968 void scanMngrTracePrintSPSScanMethod( TScanSPSMethodParams* SPSMethodParams )
2969 {
2970 WLAN_OS_REPORT(("Early termination condition: %s, frame number for early termination: %d\n",
2971 earlyTerminationConditionDesc[ SPSMethodParams->earlyTerminationEvent ],
2972 SPSMethodParams->ETMaxNumberOfApFrames));
2973 WLAN_OS_REPORT(("Scan duration: %d\n", SPSMethodParams->scanDuration));
2974 }
2975
2976 /**
2977 * \\n
2978 * \date 31-Mar-2005\n
2979 * \brief print debug information for every received frame.\n
2980 *
2981 * Function Scope \e Private.\n
2982 * \param hScanMngr - handle to the scan manager object.\n
2983 * \param frameInfo - holding all frame related information.\n
2984 */
scanMngrDebugPrintReceivedFrame(TI_HANDLE hScanMngr,TScanFrameInfo * frameInfo)2985 void scanMngrDebugPrintReceivedFrame( TI_HANDLE hScanMngr, TScanFrameInfo *frameInfo )
2986 {
2987 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
2988
2989 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "Scan manager received the following frame:\n");
2990 TRACE8( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "from BSSID: %02x:%02x:%02x:%02x:%02x:%02x, band: %d, channel: %d\n", (*frameInfo->bssId)[ 0 ], (*frameInfo->bssId)[ 1 ], (*frameInfo->bssId)[ 2 ], (*frameInfo->bssId)[ 3 ], (*frameInfo->bssId)[ 4 ], (*frameInfo->bssId)[ 5 ], frameInfo->band, frameInfo->channel);
2991 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "rate: %d, received at TSF (lower 32 bits): %d\n", frameInfo->rate, frameInfo->staTSF);
2992 if ( BEACON == frameInfo->parsedIEs->subType )
2993 {
2994 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "remote TSF value: %x-%x\n", INT64_HIGHER( frameInfo->parsedIEs->content.iePacket.timestamp ), INT64_LOWER( frameInfo->parsedIEs->content.iePacket.timestamp ));
2995
2996 }
2997 else
2998 {
2999 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "remote TSF value: %x-%x\n", INT64_HIGHER( frameInfo->parsedIEs->content.iePacket.timestamp ), INT64_LOWER( frameInfo->parsedIEs->content.iePacket.timestamp ));
3000 }
3001 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "RSSI: %d\n", frameInfo->rssi);
3002 }
3003 #ifdef TI_DBG
3004 /**
3005 * \\n
3006 * \date 31-Mar-2005\n
3007 * \brief print BSS list.\n
3008 *
3009 * Function Scope \e Private.\n
3010 * \param hScanMngr - handle to the scan manager object.\n
3011 */
scanMngrDebugPrintBSSList(TI_HANDLE hScanMngr)3012 void scanMngrDebugPrintBSSList( TI_HANDLE hScanMngr )
3013 {
3014 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
3015 int i;
3016
3017 if ( 0 == pScanMngr->BSSList.numOfEntries )
3018 {
3019 WLAN_OS_REPORT(("BSS list is empty.\n"));
3020 return;
3021 }
3022
3023
3024 WLAN_OS_REPORT(("-------------------------------- BSS List--------------------------------\n"));
3025
3026 for ( i = 0; i < pScanMngr->BSSList.numOfEntries; i++ )
3027 {
3028 WLAN_OS_REPORT( ("Entry number: %d\n", i));
3029 scanMngrDebugPrintBSSEntry( hScanMngr, i );
3030 }
3031
3032 WLAN_OS_REPORT(("--------------------------------------------------------------------------\n"));
3033 }
3034 #endif/*TI_DBG*/
3035 /**
3036 * \\n
3037 * \date 31-Mar-2005\n
3038 * \brief print one entry in the BSS list.\n
3039 *
3040 * Function Scope \e Private.\n
3041 * \param hScanMngr - handle to the scan manager object.\n
3042 * \param entryIndex - the index of the entry to print.\n
3043 */
scanMngrDebugPrintBSSEntry(TI_HANDLE hScanMngr,TI_UINT8 entryIndex)3044 void scanMngrDebugPrintBSSEntry( TI_HANDLE hScanMngr, TI_UINT8 entryIndex )
3045 {
3046 #ifdef REPORT_LOG
3047
3048 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
3049 bssEntry_t* pBssEntry = &(pScanMngr->BSSList.BSSList[ entryIndex ]);
3050 scan_BSSEntry_t * pScanBssEntry = &(pScanMngr->BSSList.scanBSSList[ entryIndex ]);
3051
3052 WLAN_OS_REPORT( ("BSSID: %02x:%02x:%02x:%02x:%02x:%02x, band: %d\n", pBssEntry->BSSID[ 0 ],
3053 pBssEntry->BSSID[ 1 ], pBssEntry->BSSID[ 2 ],
3054 pBssEntry->BSSID[ 3 ], pBssEntry->BSSID[ 4 ],
3055 pBssEntry->BSSID[ 5 ], pBssEntry->band));
3056 WLAN_OS_REPORT( ("channel: %d, beacon interval: %d, average RSSI: %d dBm\n",
3057 pBssEntry->channel, pBssEntry->beaconInterval, pBssEntry->RSSI));
3058 WLAN_OS_REPORT( ("Neighbor AP: %s, track fail count: %d\n",
3059 (TI_TRUE == pBssEntry->bNeighborAP ? "YES" : "NO"),
3060 pScanBssEntry->trackFailCount));
3061 WLAN_OS_REPORT( ("local TSF: %d-%d, remote TSF: %x-%x\n",
3062 INT64_HIGHER( pScanBssEntry->localTSF ), INT64_LOWER( pScanBssEntry->localTSF ),
3063 INT64_HIGHER( pBssEntry->lastRxTSF ), INT64_LOWER( pBssEntry->lastRxTSF )));
3064 WLAN_OS_REPORT( ("Host Time Stamp: %d, last received rate: %d\n",
3065 pBssEntry->lastRxHostTimestamp, pBssEntry->rxRate));
3066
3067 #endif
3068 }
3069
3070 /**
3071 * \\n
3072 * \date 14-Apr-2005\n
3073 * \brief print SPS helper list
3074 *
3075 * Function Scope \e Private.\n
3076 * \param hScanMngr - handle to the scan manager object.\n
3077 * \param spsHelperList - the list to print.\n
3078 * \param arrayHead - the index of the first element in the list.\n
3079 * \param arraySize - the size of the array.\n
3080 */
scanMngrDebugPrintSPSHelperList(TI_HANDLE hScanMngr,scan_SPSHelper_t * spsHelperList,int arrayHead,int arraySize)3081 void scanMngrDebugPrintSPSHelperList( TI_HANDLE hScanMngr, scan_SPSHelper_t* spsHelperList, int arrayHead, int arraySize )
3082 {
3083 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
3084 int i;
3085
3086 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "SPS helper list size:%d, list head:%d\n", arraySize, arrayHead);
3087 for ( i = 0; i < arraySize; i++ )
3088 {
3089 TRACE7( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "track list index:%d, BSSID:%02x:%02x:%02x:%02x:%02x:%02x\n", spsHelperList[ i ].trackListIndex, pScanMngr->BSSList.BSSList[ spsHelperList[ i ].trackListIndex ].BSSID[ 0 ], pScanMngr->BSSList.BSSList[ spsHelperList[ i ].trackListIndex ].BSSID[ 1 ], pScanMngr->BSSList.BSSList[ spsHelperList[ i ].trackListIndex ].BSSID[ 2 ], pScanMngr->BSSList.BSSList[ spsHelperList[ i ].trackListIndex ].BSSID[ 3 ], pScanMngr->BSSList.BSSList[ spsHelperList[ i ].trackListIndex ].BSSID[ 4 ], pScanMngr->BSSList.BSSList[ spsHelperList[ i ].trackListIndex ].BSSID[ 5 ]);
3090 TRACE3( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "TSF:%x-%x, next entry index:%d\n", INT64_HIGHER(spsHelperList[ i ].nextEventTSF), INT64_LOWER(spsHelperList[ i ].nextEventTSF), spsHelperList[ i ].nextAPIndex);
3091 }
3092 }
3093
3094
3095 /*
3096 ***********************************************************************
3097 * API functions
3098 ***********************************************************************
3099 */
scanMngr_create(TI_HANDLE hOS)3100 TI_HANDLE scanMngr_create( TI_HANDLE hOS )
3101 {
3102 int i,j = 0;
3103 scanMngr_t* pScanMngr ;
3104
3105 /* allocate the scan manager object */
3106 pScanMngr = os_memoryAlloc( hOS, sizeof(scanMngr_t));
3107 if ( NULL == pScanMngr )
3108 {
3109 WLAN_OS_REPORT( ("scanMngr_create: Failed allocating scan manager object storage.\n"));
3110 return NULL;
3111 }
3112
3113 os_memoryZero( pScanMngr->hOS, pScanMngr, sizeof(scanMngr_t));
3114
3115 pScanMngr->hOS = hOS;
3116
3117 /* allocate frame storage space for BSS list */
3118 for (i = 0; i < MAX_SIZE_OF_BSS_TRACK_LIST; i++)
3119 {
3120 pScanMngr->BSSList.BSSList[i].pBuffer = os_memoryAlloc (hOS, MAX_BEACON_BODY_LENGTH);
3121 if (pScanMngr->BSSList.BSSList[i].pBuffer == NULL)
3122 {
3123 WLAN_OS_REPORT( ("scanMngr_create: Failed allocating scan result buffer for index %d.\n", i));
3124 /* failed to allocate a buffer - release all buffers that were allocated by now */
3125 for (j = i - 1; j >= 0; j--)
3126 {
3127 os_memoryFree (hOS, pScanMngr->BSSList.BSSList[j].pBuffer, MAX_BEACON_BODY_LENGTH);
3128 }
3129 /* release the rest of the module */
3130 scanMngrFreeMem ((TI_HANDLE)pScanMngr);
3131 return NULL;
3132 }
3133 }
3134
3135 return (TI_HANDLE)pScanMngr;
3136 }
3137
scanMngr_init(TStadHandlesList * pStadHandles)3138 void scanMngr_init (TStadHandlesList *pStadHandles)
3139 {
3140 scanMngr_t *pScanMngr = (scanMngr_t*)(pStadHandles->hScanMngr);
3141 int i;
3142
3143 /* store handles */
3144 pScanMngr->hReport = pStadHandles->hReport;
3145 pScanMngr->hRegulatoryDomain = pStadHandles->hRegulatoryDomain;
3146 pScanMngr->hScanCncn = pStadHandles->hScanCncn;
3147 pScanMngr->hRoamingMngr = pStadHandles->hRoamingMngr;
3148 pScanMngr->hSiteMngr = pStadHandles->hSiteMgr;
3149 pScanMngr->hTWD = pStadHandles->hTWD;
3150 pScanMngr->hTimer = pStadHandles->hTimer;
3151 pScanMngr->hAPConnection = pStadHandles->hAPConnection;
3152 pScanMngr->hEvHandler = pStadHandles->hEvHandler;
3153
3154 /* mark the scanning operational mode to be automatic by default */
3155 pScanMngr->scanningOperationalMode = SCANNING_OPERATIONAL_MODE_AUTO;
3156
3157 /* mark that continuous scan timer is not running */
3158 pScanMngr->bTimerRunning = TI_FALSE;
3159
3160 /* mark that continuous scan process is not running */
3161 pScanMngr->bContinuousScanStarted = TI_FALSE;
3162
3163 /* nullify scan policy */
3164 os_memoryZero( pScanMngr->hOS, &(pScanMngr->scanPolicy), sizeof(TScanPolicy));
3165
3166 /* initialize the BSS list to empty list */
3167 pScanMngr->BSSList.numOfEntries = 0;
3168
3169 /* mark no continuous and immediate scans are currently running */
3170 pScanMngr->contScanState = SCAN_CSS_IDLE;
3171 pScanMngr->immedScanState = SCAN_ISS_IDLE;
3172 pScanMngr->bNewBSSFound = TI_FALSE;
3173 pScanMngr->consecNotFound = 0;
3174
3175 /* mark no AP recovery occured */
3176 pScanMngr->bSynchronized = TI_TRUE;
3177
3178 /* mark no neighbor APs */
3179 pScanMngr->neighborAPsDiscoveryList[ RADIO_BAND_2_4_GHZ ].numOfEntries = 0;
3180 pScanMngr->neighborAPsDiscoveryList[ RADIO_BAND_5_0_GHZ ].numOfEntries = 0;
3181
3182 /* mark no discovery process */
3183 pScanMngr->currentDiscoveryPart = SCAN_SDP_NO_DISCOVERY;
3184
3185 /* initialize the low quality indication to indicate that normal quality interval should be used */
3186 pScanMngr->bLowQuality = TI_FALSE;
3187
3188 /* clear current BSS field (put broadcast MAC) */
3189 for (i = 0; i < MAC_ADDR_LEN; i++)
3190 {
3191 pScanMngr->currentBSS[i] = 0xff;
3192 }
3193 pScanMngr->currentBSSBand = RADIO_BAND_2_4_GHZ;
3194
3195 /* create timer */
3196 pScanMngr->hContinuousScanTimer = tmr_CreateTimer (pScanMngr->hTimer);
3197 if (pScanMngr->hContinuousScanTimer == NULL)
3198 {
3199 TRACE0(pScanMngr->hReport, REPORT_SEVERITY_ERROR, "scanMngr_init(): Failed to create hContinuousScanTimer!\n");
3200 }
3201
3202 /* register scan concentrator callbacks */
3203 scanCncn_RegisterScanResultCB( pScanMngr->hScanCncn, SCAN_SCC_ROAMING_CONT,
3204 scanMngr_contScanCB, pStadHandles->hScanMngr );
3205 scanCncn_RegisterScanResultCB( pScanMngr->hScanCncn, SCAN_SCC_ROAMING_IMMED,
3206 scanMngr_immedScanCB, pStadHandles->hScanMngr );
3207
3208 #ifdef TI_DBG
3209 /* nullify statistics */
3210 os_memoryZero( pScanMngr->hOS, &(pScanMngr->stats), sizeof(scan_mngrStat_t));
3211 /* nullify scan parameters - for debug prints before start */
3212 os_memoryZero( pScanMngr->hOS, &(pScanMngr->scanParams), sizeof(TScanParams));
3213 /* initialize other variables for debug print */
3214 pScanMngr->bImmedNeighborAPsOnly = TI_FALSE;
3215 pScanMngr->bNewBSSFound = TI_FALSE;
3216 #endif
3217 }
3218
scanMngr_unload(TI_HANDLE hScanMngr)3219 void scanMngr_unload (TI_HANDLE hScanMngr)
3220 {
3221 scanMngrFreeMem (hScanMngr);
3222 }
3223
scanMngr_startImmediateScan(TI_HANDLE hScanMngr,TI_BOOL bNeighborAPsOnly)3224 scan_mngrResultStatus_e scanMngr_startImmediateScan( TI_HANDLE hScanMngr, TI_BOOL bNeighborAPsOnly )
3225 {
3226 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
3227 TScanBandPolicy *gPolicy, *aPolicy;
3228 EScanCncnResultStatus resultStatus;
3229
3230 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_startImmediateScan called, hScanMngr=0x%x, bNeighborAPsOnly=.\n", hScanMngr);
3231
3232 /* sanity check - whether immediate scan is already running */
3233 if ( SCAN_ISS_IDLE != pScanMngr->immedScanState )
3234 {
3235 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Immediate scan attempted while it is already running, in state:%d.\n", pScanMngr->immedScanState);
3236 return SCAN_MRS_SCAN_NOT_ATTEMPTED_ALREADY_RUNNING;
3237 }
3238
3239 /* get policies by band */
3240 gPolicy = scanMngrGetPolicyByBand( hScanMngr, RADIO_BAND_2_4_GHZ );
3241 aPolicy = scanMngrGetPolicyByBand( hScanMngr, RADIO_BAND_5_0_GHZ );
3242
3243 /* check whether a policy is defined for at least one band */
3244 if ( ((NULL == gPolicy) || (SCAN_TYPE_NO_SCAN == gPolicy->immediateScanMethod.scanType)) && /* no policy for G band */
3245 ((NULL == aPolicy) || (SCAN_TYPE_NO_SCAN == aPolicy->immediateScanMethod.scanType))) /* no policy for A band */
3246 {
3247 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Immediatse scan attempted when no policy is defined.\n");
3248 return SCAN_MRS_SCAN_NOT_ATTEMPTED_EMPTY_POLICY;
3249 }
3250
3251 /* First try to scan on G band - if a policy is defined and channels are available */
3252 if ( (NULL != gPolicy) && /* policy is defined for G */
3253 (SCAN_TYPE_NO_SCAN != gPolicy->immediateScanMethod.scanType))
3254 {
3255 /* build scan command */
3256 scanMngrBuildImmediateScanCommand( hScanMngr, gPolicy, bNeighborAPsOnly );
3257
3258 /* if no channels are available, proceed to band A */
3259 if ( 0 < pScanMngr->scanParams.numOfChannels )
3260 {
3261 /* mark that immediate scan is running on band G */
3262 pScanMngr->immedScanState = SCAN_ISS_G_BAND;
3263 pScanMngr->bImmedNeighborAPsOnly = bNeighborAPsOnly;
3264
3265 /* if continuous scan is running, mark that it should quit */
3266 if ( SCAN_CSS_IDLE != pScanMngr->contScanState )
3267 {
3268 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_startImmediateScan called 1, switched to STOPPING state \n");
3269
3270 pScanMngr->contScanState = SCAN_CSS_STOPPING;
3271 }
3272
3273 /* send scan command to scan concentrator with the required scan params according to scanning operational mode */
3274 resultStatus = scanMngr_Start1ShotScan(hScanMngr, SCAN_SCC_ROAMING_IMMED);
3275
3276 if ( SCAN_CRS_SCAN_RUNNING != resultStatus )
3277 {
3278 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Failed to start immediate scan on band G, return code %d.\n", resultStatus);
3279 #ifdef TI_DBG
3280 pScanMngr->stats.ImmediateGByStatus[ resultStatus ]++;
3281 #endif
3282 return SCAN_MRS_SCAN_FAILED;
3283 }
3284 return SCAN_MRS_SCAN_RUNNING;
3285 }
3286 }
3287
3288 /* if G scan did not start (because no policy is configured or no channels are available, try A band */
3289 if ( (NULL != aPolicy) &&
3290 (SCAN_TYPE_NO_SCAN != aPolicy->immediateScanMethod.scanType))
3291 {
3292 /* build scan command */
3293 scanMngrBuildImmediateScanCommand( hScanMngr, aPolicy, bNeighborAPsOnly );
3294
3295 /* if no channels are available, report error */
3296 if ( 0 == pScanMngr->scanParams.numOfChannels )
3297 {
3298 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "No channels available for scan operation.\n");
3299 return SCAN_MRS_SCAN_NOT_ATTEMPTED_NO_CHANNLES_AVAILABLE;
3300 }
3301 else
3302 {
3303 /* mark that immediate scan is running on band A */
3304 pScanMngr->immedScanState = SCAN_ISS_A_BAND;
3305
3306 /* if continuous scan is running, mark that it should quit */
3307 if ( SCAN_CSS_IDLE != pScanMngr->contScanState )
3308 {
3309 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_startImmediateScan called 2, switched to STOPPING state \n");
3310
3311 pScanMngr->contScanState = SCAN_CSS_STOPPING;
3312 }
3313
3314 /* send scan command to scan concentrator with the required scan params according to scanning operational mode */
3315 resultStatus = scanMngr_Start1ShotScan(hScanMngr, SCAN_SCC_ROAMING_IMMED);
3316 if ( SCAN_CRS_SCAN_RUNNING != resultStatus )
3317 {
3318 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Failed to start immediate scan on band A, return code %d.\n", resultStatus);
3319 #ifdef TI_DBG
3320 pScanMngr->stats.ImmediateAByStatus[ resultStatus ]++;
3321 #endif
3322 return SCAN_MRS_SCAN_FAILED;
3323 }
3324 return SCAN_MRS_SCAN_RUNNING;
3325 }
3326 }
3327 else
3328 {
3329 /* since we passed the policy check, we arrived here because we didn't had channel on G and policy on A */
3330 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "No channels available for scan operation.\n");
3331 return SCAN_MRS_SCAN_NOT_ATTEMPTED_NO_CHANNLES_AVAILABLE;
3332 }
3333 }
3334
scanMngr_stopImmediateScan(TI_HANDLE hScanMngr)3335 void scanMngr_stopImmediateScan( TI_HANDLE hScanMngr )
3336 {
3337 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
3338
3339 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngrStopImmediateScan called, hScanMngr=0x%x", hScanMngr);
3340
3341 /* check that immediate scan is running */
3342 if ( (SCAN_ISS_A_BAND != pScanMngr->immedScanState) && (SCAN_ISS_G_BAND != pScanMngr->immedScanState))
3343 {
3344 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Immediate scan stop request when immediate scan is in state:%d", pScanMngr->immedScanState);
3345 return;
3346 }
3347
3348 #ifdef TI_DBG
3349 switch ( pScanMngr->immedScanState )
3350 {
3351 case SCAN_ISS_G_BAND:
3352 pScanMngr->stats.ImmediateGByStatus[ SCAN_CRS_SCAN_STOPPED ]++;
3353 break;
3354
3355 case SCAN_ISS_A_BAND:
3356 pScanMngr->stats.ImmediateAByStatus[ SCAN_CRS_SCAN_STOPPED ]++;
3357 break;
3358
3359 default:
3360 break;
3361 }
3362 #endif
3363 /* mark immediate scan status as stopping */
3364 pScanMngr->immedScanState = SCAN_ISS_STOPPING;
3365
3366 /* send a stop command to scan concentrator */
3367 scanCncn_StopScan( pScanMngr->hScanCncn, SCAN_SCC_ROAMING_IMMED );
3368 }
3369
scanMngr_startContScan(TI_HANDLE hScanMngr,TMacAddr * currentBSS,ERadioBand currentBSSBand)3370 void scanMngr_startContScan( TI_HANDLE hScanMngr, TMacAddr* currentBSS, ERadioBand currentBSSBand )
3371 {
3372 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
3373 int currentBSSNeighborIndex;
3374
3375 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_StartContScan called, hScanMngr=0x%x.\n", hScanMngr);
3376
3377 /* if continuous scan is already running, it means we get a start command w/o stop */
3378 if ( TI_TRUE == pScanMngr->bContinuousScanStarted )
3379 {
3380 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Start continuous scan requested when continuous scan is running.\n");
3381 return;
3382 }
3383
3384 /* mark that continuous scan was started */
3385 pScanMngr->bContinuousScanStarted = TI_TRUE;
3386
3387 /* before reading and marking the new BSS - make sure that the old one is marked as NOT DISCOVERED */
3388 currentBSSNeighborIndex = scanMngrGetNeighborAPIndex( hScanMngr, pScanMngr->currentBSSBand, &(pScanMngr->currentBSS));
3389 if ( -1 != currentBSSNeighborIndex )
3390 {
3391 pScanMngr->neighborAPsDiscoveryList[ pScanMngr->currentBSSBand ].trackStatusList[ currentBSSNeighborIndex ] =
3392 SCAN_NDS_NOT_DISCOVERED;
3393 }
3394
3395 /* Now copy current BSS - to be used when setting neighbor APs */
3396 pScanMngr->currentBSSBand = currentBSSBand;
3397 MAC_COPY (pScanMngr->currentBSS, *currentBSS);
3398
3399 /* if current BSS is in the neighbor AP list, mark it as current BSS */
3400 currentBSSNeighborIndex = scanMngrGetNeighborAPIndex( hScanMngr, currentBSSBand, currentBSS );
3401 if ( -1 != currentBSSNeighborIndex )
3402 {
3403 pScanMngr->neighborAPsDiscoveryList[ currentBSSBand ].trackStatusList[ currentBSSNeighborIndex ] =
3404 SCAN_NDS_CURRENT_AP;
3405 }
3406
3407 /* reset discovery cycle */
3408 pScanMngr->neighborAPsDiscoveryIndex[ RADIO_BAND_2_4_GHZ ] = 0;
3409 pScanMngr->neighborAPsDiscoveryIndex[ RADIO_BAND_5_0_GHZ ] = 0;
3410 pScanMngr->channelDiscoveryIndex[ RADIO_BAND_2_4_GHZ ] = 0;
3411 pScanMngr->channelDiscoveryIndex[ RADIO_BAND_5_0_GHZ ] = 0;
3412 pScanMngr->currentDiscoveryPart = SCAN_SDP_NEIGHBOR_G;
3413 scanMngrSetNextDiscoveryPart( hScanMngr );
3414
3415 /* clear the BSS tracking list */
3416 pScanMngr->BSSList.numOfEntries = 0;
3417
3418 /* start timer (if timeout is configured) */
3419 if ( ((TI_TRUE == pScanMngr->bLowQuality) && (0 < pScanMngr->scanPolicy.normalScanInterval)) ||
3420 ((TI_FALSE == pScanMngr->bLowQuality) && (0 < pScanMngr->scanPolicy.deterioratingScanInterval)))
3421 {
3422 TI_UINT32 uTimeout = pScanMngr->bLowQuality ?
3423 pScanMngr->scanPolicy.deterioratingScanInterval :
3424 pScanMngr->scanPolicy.normalScanInterval;
3425
3426 pScanMngr->bTimerRunning = TI_TRUE;
3427
3428 tmr_StartTimer (pScanMngr->hContinuousScanTimer,
3429 scanMngr_GetUpdatedTsfDtimMibForScan,
3430 (TI_HANDLE)pScanMngr,
3431 uTimeout,
3432 TI_TRUE);
3433 }
3434 }
3435
scanMngr_stopContScan(TI_HANDLE hScanMngr)3436 void scanMngr_stopContScan( TI_HANDLE hScanMngr )
3437 {
3438 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
3439 TI_UINT8 i;
3440
3441 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_stopContScan called, hScanMngr=0x%x, state =%d\n", hScanMngr, pScanMngr->contScanState);
3442
3443 /* if continuous scan is not running, it means we get a stop command w/o start */
3444 if ( TI_FALSE == pScanMngr->bContinuousScanStarted )
3445 {
3446 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Stop continuous scan when continuous scan is not running.\n");
3447 return;
3448 }
3449
3450 /* mark that continuous scan is not running */
3451 pScanMngr->bContinuousScanStarted = TI_FALSE;
3452
3453 /* stop timer */
3454 if ( TI_TRUE == pScanMngr->bTimerRunning )
3455 {
3456 tmr_StopTimer (pScanMngr->hContinuousScanTimer);
3457 pScanMngr->bTimerRunning = TI_FALSE;
3458 }
3459
3460 /* if continuous scan is currently running */
3461 if ( (SCAN_CSS_IDLE != pScanMngr->contScanState) &&
3462 (SCAN_CSS_STOPPING != pScanMngr->contScanState))
3463 {
3464 /* send a stop scan command to the scan concentartor */
3465 scanCncn_StopScan( pScanMngr->hScanCncn, SCAN_SCC_ROAMING_CONT );
3466 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_stopContScan called, switched to STOPPING state \n");
3467
3468 #ifdef TI_DBG
3469 switch ( pScanMngr->contScanState )
3470 {
3471 case SCAN_CSS_TRACKING_G_BAND:
3472 pScanMngr->stats.TrackingGByStatus[ SCAN_CRS_SCAN_STOPPED ]++;
3473 break;
3474
3475 case SCAN_CSS_TRACKING_A_BAND:
3476 pScanMngr->stats.TrackingAByStatus[ SCAN_CRS_SCAN_STOPPED ]++;
3477 break;
3478
3479 case SCAN_CSS_DISCOVERING:
3480 if ( RADIO_BAND_2_4_GHZ == pScanMngr->statsLastDiscoveryBand )
3481 {
3482 pScanMngr->stats.DiscoveryGByStatus[ SCAN_CRS_SCAN_STOPPED ]++;
3483 }
3484 else
3485 {
3486 pScanMngr->stats.DiscoveryAByStatus[ SCAN_CRS_SCAN_STOPPED ]++;
3487 }
3488 break;
3489
3490 default:
3491 break;
3492 }
3493 #endif
3494 /* mark that continuous scan is stopping */
3495 pScanMngr->contScanState = SCAN_CSS_STOPPING;
3496 }
3497
3498 /* clear current neighbor APs */
3499 pScanMngr->neighborAPsDiscoveryList[ RADIO_BAND_2_4_GHZ ].numOfEntries = 0;
3500 pScanMngr->neighborAPsDiscoveryList[ RADIO_BAND_5_0_GHZ ].numOfEntries = 0;
3501
3502 /* clear current BSS field .This is for the case that scanMngr_setNeighborAPs() is called before scanMngr_startcontScan() */
3503 for ( i = 0; i < MAC_ADDR_LEN; i++ )
3504 {
3505 pScanMngr->currentBSS[ i ] = 0xff;
3506 }
3507
3508 }
3509
scanMngr_getBSSList(TI_HANDLE hScanMngr)3510 bssList_t* scanMngr_getBSSList( TI_HANDLE hScanMngr )
3511 {
3512 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
3513 TI_UINT8 BSSIndex;
3514 paramInfo_t param;
3515
3516
3517 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_getBSSList called, hScanMngr=0x%x.\n", hScanMngr);
3518
3519 /* loop on all BSS'es */
3520 for ( BSSIndex = 0; BSSIndex < pScanMngr->BSSList.numOfEntries; )
3521 {
3522 /* verify channel validity with the reg domain - for active scan!
3523 (because connection will be attempted on the channel... */
3524 param.paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES;
3525 param.content.channelCapabilityReq.band = pScanMngr->BSSList.BSSList[ BSSIndex ].band;
3526 param.content.channelCapabilityReq.scanOption = ACTIVE_SCANNING;
3527 param.content.channelCapabilityReq.channelNum = pScanMngr->BSSList.BSSList[ BSSIndex ].channel;
3528 regulatoryDomain_getParam( pScanMngr->hRegulatoryDomain, ¶m );
3529
3530 /* if channel is not valid */
3531 if ( !param.content.channelCapabilityRet.channelValidity )
3532 {
3533 /* will replace this entry with one further down the array, if any. Therefore, index is not increased
3534 (because a new entry will be placed in the same index). If this is the last entry - the number of
3535 BSSes will be decreased, and thus the loop will exit */
3536 scanMngrRemoveBSSListEntry( hScanMngr, BSSIndex );
3537 }
3538 else
3539 {
3540 BSSIndex++;
3541 }
3542 }
3543
3544 /* return the BSS list */
3545 return (bssList_t*)&(pScanMngr->BSSList);
3546 }
3547
scanMngr_setNeighborAPs(TI_HANDLE hScanMngr,neighborAPList_t * neighborAPList)3548 void scanMngr_setNeighborAPs( TI_HANDLE hScanMngr, neighborAPList_t* neighborAPList )
3549 {
3550 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
3551 int neighborAPIndex, currentBSSNeighborIndex;
3552
3553 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_setNeighborAPs called, hScanMngr=0x%x.\n", hScanMngr);
3554 #ifdef TI_DBG
3555 scanMngrTracePrintNeighborAPsList( hScanMngr, neighborAPList );
3556 #endif
3557 /* if continuous scan is running, indicate that it shouldn't proceed to next scan (if any) */
3558 if ( pScanMngr->contScanState != SCAN_CSS_IDLE )
3559 {
3560 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_setNeighborAPs called, switched to STOPPING state \n");
3561
3562 pScanMngr->contScanState = SCAN_CSS_STOPPING;
3563 }
3564
3565 /* clear current neighbor APs */
3566 pScanMngr->neighborAPsDiscoveryList[ RADIO_BAND_2_4_GHZ ].numOfEntries = 0;
3567 pScanMngr->neighborAPsDiscoveryList[ RADIO_BAND_5_0_GHZ ].numOfEntries = 0;
3568
3569 /* copy new neighbor APs, according to band */
3570 for ( neighborAPIndex = 0; neighborAPIndex < neighborAPList->numOfEntries; neighborAPIndex++ )
3571 {
3572 /* insert to appropriate list */
3573 os_memoryCopy( pScanMngr->hOS,
3574 &(pScanMngr->neighborAPsDiscoveryList[ neighborAPList->APListPtr[ neighborAPIndex ].band ].APListPtr[ pScanMngr->neighborAPsDiscoveryList[ neighborAPList->APListPtr[ neighborAPIndex ].band ].numOfEntries ]),
3575 &(neighborAPList->APListPtr[ neighborAPIndex ]),
3576 sizeof(neighborAP_t));
3577
3578 /* if AP is in track list, mark as discovered. This is done only if continuous scan
3579 has already started, to ensure the roaming canidate list holds valid information */
3580 if ( TI_TRUE == pScanMngr->bContinuousScanStarted )
3581 {
3582 pScanMngr->neighborAPsDiscoveryList[ neighborAPList->APListPtr[ neighborAPIndex ].band ].trackStatusList[ pScanMngr->neighborAPsDiscoveryList[ neighborAPList->APListPtr[ neighborAPIndex ].band ].numOfEntries ] =
3583 ( -1 == scanMngrGetTrackIndexByBssid( hScanMngr, &(neighborAPList->APListPtr[ neighborAPIndex ].BSSID)) ?
3584 SCAN_NDS_NOT_DISCOVERED :
3585 SCAN_NDS_DISCOVERED );
3586 }
3587 else
3588 {
3589 /* if continuous scan has not yet started, all AP's are yet to be discovered... */
3590 pScanMngr->neighborAPsDiscoveryList[ neighborAPList->APListPtr[ neighborAPIndex ].band ].trackStatusList[ pScanMngr->neighborAPsDiscoveryList[ neighborAPList->APListPtr[ neighborAPIndex ].band ].numOfEntries ] =
3591 SCAN_NDS_NOT_DISCOVERED;
3592 }
3593
3594 /* increase neighbor AP count */
3595 pScanMngr->neighborAPsDiscoveryList[ neighborAPList->APListPtr[ neighborAPIndex ].band ].numOfEntries++;
3596 }
3597
3598 /* remove all tracked APs that are designated as neighbor APs, but are not anymore. Policy has not
3599 changed, so there's no need to check APs that are not neighbor APs and were inserted to the BSS
3600 list because they are on a policy defined channel. */
3601 scanMngrUpdateBSSList( hScanMngr, TI_TRUE, TI_FALSE );
3602
3603 /* if current BSS is a neighbor AP, mark it */
3604 currentBSSNeighborIndex = scanMngrGetNeighborAPIndex( hScanMngr,
3605 pScanMngr->currentBSSBand,
3606 &(pScanMngr->currentBSS));
3607 if ( -1 != currentBSSNeighborIndex )
3608 {
3609 pScanMngr->neighborAPsDiscoveryList[ pScanMngr->currentBSSBand ].trackStatusList[ currentBSSNeighborIndex ] =
3610 SCAN_NDS_CURRENT_AP;
3611 }
3612
3613 /* reset discovery counters */
3614 pScanMngr->neighborAPsDiscoveryIndex[ RADIO_BAND_2_4_GHZ ] = 0;
3615 pScanMngr->neighborAPsDiscoveryIndex[ RADIO_BAND_5_0_GHZ ] = 0;
3616 pScanMngr->channelDiscoveryIndex[ RADIO_BAND_2_4_GHZ ] = 0;
3617 pScanMngr->channelDiscoveryIndex[ RADIO_BAND_5_0_GHZ ] = 0;
3618 /* set current discovery part to first part (G neighbor APs) */
3619 pScanMngr->currentDiscoveryPart = SCAN_SDP_NEIGHBOR_G;
3620 /* now advance discovery part */
3621 scanMngrSetNextDiscoveryPart( hScanMngr );
3622 }
3623
scanMngr_qualityChangeTrigger(TI_HANDLE hScanMngr,TI_BOOL bLowQuality)3624 void scanMngr_qualityChangeTrigger( TI_HANDLE hScanMngr, TI_BOOL bLowQuality )
3625 {
3626 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
3627
3628 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_qualityChangeTrigger called, hScanMngr=0x%x, bLowQuality=.\n", hScanMngr);
3629
3630 /* remember the low quality trigger (in case policy changes, to know which timer interval to use) */
3631 pScanMngr->bLowQuality = bLowQuality;
3632
3633 /* This function shouldn't be called when continuous scan is not running */
3634 if ( TI_FALSE == pScanMngr->bContinuousScanStarted )
3635 {
3636 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_WARNING, "Quality change trigger when continuous scan is not running.\n");
3637 }
3638
3639 /* If the timer is running, stop it and start it again with the new interval */
3640 if (pScanMngr->bTimerRunning)
3641 {
3642 TI_UINT32 uTimeout = pScanMngr->bLowQuality ?
3643 pScanMngr->scanPolicy.deterioratingScanInterval :
3644 pScanMngr->scanPolicy.normalScanInterval;
3645
3646 tmr_StopTimer (pScanMngr->hContinuousScanTimer);
3647
3648 tmr_StartTimer (pScanMngr->hContinuousScanTimer,
3649 scanMngr_GetUpdatedTsfDtimMibForScan,
3650 (TI_HANDLE)pScanMngr,
3651 uTimeout,
3652 TI_TRUE);
3653 }
3654 }
3655
scanMngr_handoverDone(TI_HANDLE hScanMngr,TMacAddr * macAddress,ERadioBand band)3656 void scanMngr_handoverDone( TI_HANDLE hScanMngr, TMacAddr* macAddress, ERadioBand band )
3657 {
3658 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
3659 int i, currentBSSNeighborIndex;
3660
3661 /* mark that TSF values are not synchronized */
3662 pScanMngr->bSynchronized = TI_FALSE;
3663
3664 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_handoverDone called\n");
3665
3666 /* if previous AP is in neighbor AP list, mark it as not discoverd */
3667 currentBSSNeighborIndex = scanMngrGetNeighborAPIndex( hScanMngr,
3668 pScanMngr->currentBSSBand,
3669 &(pScanMngr->currentBSS));
3670 if ( -1 != currentBSSNeighborIndex )
3671 {
3672 pScanMngr->neighborAPsDiscoveryList[ pScanMngr->currentBSSBand ].trackStatusList[ currentBSSNeighborIndex ] =
3673 SCAN_NDS_NOT_DISCOVERED;
3674 }
3675
3676 /* copy new current AP info */
3677 pScanMngr->currentBSSBand = band;
3678 MAC_COPY (pScanMngr->currentBSS, *macAddress);
3679
3680 /* if new current AP is a neighbor AP, mark it */
3681 currentBSSNeighborIndex = scanMngrGetNeighborAPIndex( hScanMngr, band, macAddress );
3682 if ( -1 != currentBSSNeighborIndex )
3683 {
3684 pScanMngr->neighborAPsDiscoveryList[ band ].trackStatusList[ currentBSSNeighborIndex ] =
3685 SCAN_NDS_CURRENT_AP;
3686 /* note - no need to update discovery index - when adding neighbor APs the check (whether discovery should
3687 be attempted) is done for every channel! */
3688 }
3689
3690 /* if a continuous scan is running, mark that it should stop */
3691 if ( SCAN_CSS_IDLE != pScanMngr->contScanState )
3692 {
3693
3694 TRACE0( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_handoverDone called, switched to STOPPING state \n");
3695
3696 pScanMngr->contScanState = SCAN_CSS_STOPPING;
3697 scanCncn_StopScan( pScanMngr->hScanCncn, SCAN_SCC_ROAMING_CONT );
3698 }
3699
3700 /* if the new AP is in the track list */
3701 i = scanMngrGetTrackIndexByBssid( hScanMngr, macAddress );
3702 if ( i != -1 )
3703 {
3704 /* remove it */
3705 scanMngrRemoveBSSListEntry( hScanMngr, i );
3706 }
3707 }
3708
scanMngr_getParam(TI_HANDLE hScanMngr,paramInfo_t * pParam)3709 TI_STATUS scanMngr_getParam( TI_HANDLE hScanMngr, paramInfo_t *pParam )
3710 {
3711 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
3712
3713 TRACE2( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_getParam called, hScanMngr=0x%x, pParam=0x%x\n", hScanMngr, pParam);
3714
3715 /* act according to parameter type */
3716 switch ( pParam->paramType )
3717 {
3718 case SCAN_MNGR_BSS_LIST_GET:
3719 os_memoryCopy(pScanMngr->hOS, pParam->content.pScanBssList, scanMngr_getBSSList( hScanMngr ), sizeof(bssList_t));
3720 break;
3721
3722 default:
3723 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_ERROR, "Scan manager getParam called with param type %d.\n", pParam->paramType);
3724 return PARAM_NOT_SUPPORTED;
3725 /* break; - unreachable */
3726 }
3727
3728 return TI_OK;
3729 }
3730
3731
3732
3733
3734
3735
scanMngr_setParam(TI_HANDLE hScanMngr,paramInfo_t * pParam)3736 TI_STATUS scanMngr_setParam( TI_HANDLE hScanMngr, paramInfo_t *pParam )
3737 {
3738 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
3739
3740 TRACE3( pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_setParam called, hScanMngr=0x%x, pParam=0x%x, pParam->paramType=%d\n", hScanMngr, pParam, pParam->paramType);
3741
3742 /* act according to parameter type */
3743 switch ( pParam->paramType )
3744 {
3745 case SCAN_MNGR_SET_CONFIGURATION:
3746 scanMngr_setScanPolicy( hScanMngr, pParam->content.pScanPolicy);
3747 break;
3748
3749 default:
3750 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_ERROR, "Set param, Params is not supported:%d\n", pParam->paramType);
3751 return PARAM_NOT_SUPPORTED;
3752 }
3753
3754 return TI_OK;
3755 }
3756
3757
3758 /**
3759 * \fn scanMngr_SetDefaults
3760 * \brief Set default values to the Scan Manager
3761 *
3762 * \param hScanMngr - handle to the SME object
3763 * \param pInitParams - values read from registry / ini file
3764 * \return None
3765 */
scanMngr_SetDefaults(TI_HANDLE hScanMngr,TRoamScanMngrInitParams * pInitParams)3766 void scanMngr_SetDefaults (TI_HANDLE hScanMngr, TRoamScanMngrInitParams *pInitParams)
3767 {
3768 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
3769 TScanPolicy defaultScanPolicy;
3770 paramInfo_t *pParam;
3771 int i;
3772
3773 WLAN_OS_REPORT(("pInitParams->RoamingScanning_2_4G_enable %d \n",pInitParams->RoamingScanning_2_4G_enable ));
3774
3775 pParam = os_memoryAlloc(pScanMngr->hOS, sizeof(paramInfo_t));
3776 if (!pParam)
3777 return;
3778 if (pInitParams->RoamingScanning_2_4G_enable)
3779 {
3780 /* Configure default scan policy for 2.4G */
3781 defaultScanPolicy.normalScanInterval = 10000;
3782 defaultScanPolicy.deterioratingScanInterval = 5000;
3783 defaultScanPolicy.maxTrackFailures = 3;
3784 defaultScanPolicy.BSSListSize = 4;
3785 defaultScanPolicy.BSSNumberToStartDiscovery = 1;
3786 defaultScanPolicy.numOfBands = 1;
3787
3788 defaultScanPolicy.bandScanPolicy[0].band = RADIO_BAND_2_4_GHZ;
3789 defaultScanPolicy.bandScanPolicy[0].rxRSSIThreshold = -80;
3790 defaultScanPolicy.bandScanPolicy[0].numOfChannlesForDiscovery = 3;
3791 defaultScanPolicy.bandScanPolicy[0].numOfChannles = 14;
3792
3793 for ( i = 0; i < 14; i++ )
3794 {
3795 defaultScanPolicy.bandScanPolicy[0].channelList[ i ] = i + 1;
3796 }
3797
3798
3799
3800 defaultScanPolicy.bandScanPolicy[0].trackingMethod.scanType = SCAN_TYPE_NO_SCAN;
3801 defaultScanPolicy.bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.earlyTerminationEvent = SCAN_ET_COND_DISABLE;
3802 defaultScanPolicy.bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.ETMaxNumberOfApFrames = 0;
3803 defaultScanPolicy.bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.maxChannelDwellTime = 0;
3804 defaultScanPolicy.bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.minChannelDwellTime = 0;
3805
3806 defaultScanPolicy.bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.probReqParams.bitrate = RATE_MASK_UNSPECIFIED; /* Let the FW select */
3807 defaultScanPolicy.bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.probReqParams.numOfProbeReqs = 0;
3808 defaultScanPolicy.bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.probReqParams.txPowerDbm = 0;
3809
3810 defaultScanPolicy.bandScanPolicy[0].discoveryMethod.scanType = SCAN_TYPE_NO_SCAN;
3811 defaultScanPolicy.bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.earlyTerminationEvent = SCAN_ET_COND_DISABLE;
3812 defaultScanPolicy.bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.ETMaxNumberOfApFrames = 0;
3813 defaultScanPolicy.bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.maxChannelDwellTime = 0;
3814 defaultScanPolicy.bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.minChannelDwellTime = 0;
3815 defaultScanPolicy.bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.probReqParams.bitrate = RATE_MASK_UNSPECIFIED; /* Let the FW select */
3816 defaultScanPolicy.bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.probReqParams.numOfProbeReqs = 0;
3817 defaultScanPolicy.bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.probReqParams.txPowerDbm = 0;
3818
3819 defaultScanPolicy.bandScanPolicy[0].immediateScanMethod.scanType = SCAN_TYPE_NORMAL_ACTIVE;
3820 defaultScanPolicy.bandScanPolicy[0].immediateScanMethod.method.basicMethodParams.maxChannelDwellTime = 30000;
3821 defaultScanPolicy.bandScanPolicy[0].immediateScanMethod.method.basicMethodParams.minChannelDwellTime = 15000;
3822 defaultScanPolicy.bandScanPolicy[0].immediateScanMethod.method.basicMethodParams.earlyTerminationEvent = SCAN_ET_COND_DISABLE;
3823 defaultScanPolicy.bandScanPolicy[0].immediateScanMethod.method.basicMethodParams.ETMaxNumberOfApFrames = 0;
3824 defaultScanPolicy.bandScanPolicy[0].immediateScanMethod.method.basicMethodParams.probReqParams.numOfProbeReqs = 3;
3825 defaultScanPolicy.bandScanPolicy[0].immediateScanMethod.method.basicMethodParams.probReqParams.bitrate = 4;//RATE_MASK_UNSPECIFIED; /* Let the FW select */
3826 defaultScanPolicy.bandScanPolicy[0].immediateScanMethod.method.basicMethodParams.probReqParams.txPowerDbm = MAX_TX_POWER;
3827
3828
3829 pParam->paramType = SCAN_MNGR_SET_CONFIGURATION;
3830
3831 /* scanMngr_setParam() copy the content and not the pointer */
3832 pParam->content.pScanPolicy = &defaultScanPolicy;
3833 pParam->paramLength = sizeof(TScanPolicy);
3834
3835 scanMngr_setParam (hScanMngr, pParam);
3836
3837 }
3838 os_memoryFree(pScanMngr->hOS, pParam, sizeof(paramInfo_t));
3839 /* Configure default scan parameters - SHIRIT END */
3840 }
3841 /**
3842 *
3843 * scanMngr_startManual API
3844 *
3845 * Description:
3846 *
3847 * save the manual scan params later to be used upon the scan concentrator object
3848 * and change the conn status to connected
3849 *
3850 * ARGS:
3851 * hScanMngr - Scan manager handle \n
3852 *
3853 * RETURNS:
3854 * void
3855 */
scanMngr_startManual(TI_HANDLE hScanMngr)3856 void scanMngr_startManual(TI_HANDLE hScanMngr)
3857 {
3858 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
3859 TScanBandPolicy* gPolicy;
3860
3861 pScanMngr->scanningOperationalMode = SCANNING_OPERATIONAL_MODE_MANUAL;
3862 pScanMngr->connStatus = CONNECTION_STATUS_CONNECTED;
3863
3864 scanMngr_setManualScanDefaultParams(hScanMngr);
3865 TRACE0(pScanMngr->hReport,REPORT_SEVERITY_INFORMATION, "scanMngr_startManual() called. \n");
3866
3867 /* get policies by band */
3868 gPolicy = scanMngrGetPolicyByBand( hScanMngr, RADIO_BAND_2_4_GHZ ); /* TODO: check if neccessary!!!*/
3869 }
3870
3871 /**
3872 *
3873 * scanMngr_stopManual API
3874 *
3875 * Description:
3876 *
3877 * set the connection status to NOT_CONNECTED
3878 *
3879 * ARGS:
3880 * hScanMngr - Scan manager handle \n
3881 * pTargetAp - the target AP to connect with info.
3882 *
3883 * RETURNS:
3884 * void
3885 */
scanMngr_stopManual(TI_HANDLE hScanMngr)3886 void scanMngr_stopManual(TI_HANDLE hScanMngr)
3887 {
3888 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
3889 pScanMngr->connStatus = CONNECTION_STATUS_NOT_CONNECTED;
3890 }
3891
3892 /**
3893 *
3894 * scanMngr_setManualScanChannelList API
3895 *
3896 * Description:
3897 *
3898 * save the channel list received form the application.
3899 *
3900 * ARGS:
3901 * hScanMngr - Scan manager handle \n
3902 * pTargetAp - the target AP to connect with info.
3903 *
3904 * RETURNS:
3905 * TI_OK
3906 */
scanMngr_setManualScanChannelList(TI_HANDLE hScanMngr,channelList_t * pChannelList)3907 TI_STATUS scanMngr_setManualScanChannelList (TI_HANDLE hScanMngr, channelList_t* pChannelList)
3908 {
3909 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
3910
3911 pScanMngr->manualScanParams.numOfChannels = pChannelList->numOfChannels;
3912 os_memoryCopy(pScanMngr->hOS,
3913 (void*)&pScanMngr->manualScanParams.channelEntry[0],
3914 &pChannelList->channelEntry[0],
3915 pChannelList->numOfChannels * sizeof(TScanChannelEntry));
3916
3917 return TI_OK;
3918 }
3919
3920 /**
3921 *
3922 * scanMngr_Start1ShotScan API
3923 *
3924 * Description:
3925 *
3926 * send the required scan params to the scan concentartor module
3927 * according to the scanning manual mode.
3928 *
3929 * ARGS:
3930 * hScanMngr - scan manager handle \n
3931 * eClient - the client that requests this scan command.
3932 *
3933 * RETURNS:
3934 * EScanCncnResultStatus - the scan concentrator result
3935 */
scanMngr_Start1ShotScan(TI_HANDLE hScanMngr,EScanCncnClient eClient)3936 EScanCncnResultStatus scanMngr_Start1ShotScan (TI_HANDLE hScanMngr, EScanCncnClient eClient)
3937 {
3938 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
3939 TScanParams* pScanParams;
3940 EScanCncnResultStatus status;
3941
3942 TRACE2(pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_Start1ShotScan started... .Operational mode: %d, ScanClient=%d. \n",
3943 pScanMngr->scanningOperationalMode, eClient);
3944
3945 if(SCANNING_OPERATIONAL_MODE_AUTO == pScanMngr->scanningOperationalMode)
3946 {
3947 pScanParams = &(pScanMngr->scanParams);
3948 }
3949 else
3950 {
3951 pScanParams = &(pScanMngr->manualScanParams); /* the scan params that were previously saved in the scanMngr_startManual()*/
3952 }
3953
3954 status = scanCncn_Start1ShotScan(pScanMngr->hScanCncn, eClient, pScanParams);
3955 return status;
3956 }
3957
3958 /**
3959 *
3960 * scanMngr_immediateScanComplete API
3961 *
3962 * Description:
3963 *
3964 * called upon the immediate scan complete (manual or auto),
3965 and call the roaming manager to handle this callback.
3966 *
3967 * ARGS:
3968 * hScanMngr - Scan manager handle \n
3969 * scanCmpltStatus - the scan complete status
3970 *
3971 * RETURNS:
3972 * EScanCncnResultStatus - the scan concentrator result
3973 */
scanMngr_immediateScanComplete(TI_HANDLE hScanMngr,scan_mngrResultStatus_e scanCmpltStatus)3974 TI_STATUS scanMngr_immediateScanComplete(TI_HANDLE hScanMngr, scan_mngrResultStatus_e scanCmpltStatus)
3975 {
3976 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
3977
3978 if(SCANNING_OPERATIONAL_MODE_AUTO == pScanMngr->scanningOperationalMode)
3979 {
3980 roamingMngr_immediateScanComplete(pScanMngr->hRoamingMngr, scanCmpltStatus);
3981 }
3982 else
3983 {
3984 scanMngr_reportImmediateScanResults(hScanMngr, SCAN_MRS_SCAN_COMPLETE_OK);
3985 roamingMngr_immediateScanByAppComplete(pScanMngr->hRoamingMngr, scanCmpltStatus);
3986 }
3987 return TI_OK;
3988 }
3989
3990
3991 /**
3992 *
3993 * scanMngr_reportImmediateScanResults API
3994 *
3995 * Description:
3996 *
3997 * report the immediate scan results to the application
3998 *
3999 * ARGS:
4000 * hScanMngr - Scan manager handle \n
4001 * scanCmpltStatus - the scan complete status
4002 *
4003 * RETURNS:
4004 * EScanCncnResultStatus - the scan concentrator result
4005 */
scanMngr_reportImmediateScanResults(TI_HANDLE hScanMngr,scan_mngrResultStatus_e scanCmpltStatus)4006 TI_STATUS scanMngr_reportImmediateScanResults(TI_HANDLE hScanMngr, scan_mngrResultStatus_e scanCmpltStatus)
4007 {
4008 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
4009 bssList_t *pListOfAPs;
4010
4011
4012 if (scanCmpltStatus == SCAN_MRS_SCAN_COMPLETE_OK)
4013 {
4014 TRACE0(pScanMngr->hReport, REPORT_SEVERITY_INFORMATION ,"scanMngr_reportImmediateScanResults(): reporting scan results to App \n");
4015 pListOfAPs = scanMngr_getBSSList(hScanMngr);
4016 EvHandlerSendEvent(pScanMngr->hEvHandler, IPC_EVENT_IMMEDIATE_SCAN_REPORT, (TI_UINT8*)pListOfAPs, sizeof(bssList_t));
4017 }
4018 else
4019 {
4020 TRACE1(pScanMngr->hReport, REPORT_SEVERITY_ERROR, "scanMngr_reportImmediateScanResults was not completed successfully. status: %d\n", scanCmpltStatus);
4021 return TI_NOK;
4022 }
4023
4024 return TI_OK;
4025 }
4026
4027
4028 /**
4029 *
4030 * scanMngr_startContinuousScanByApp API
4031 *
4032 * Description:
4033 *
4034 * start continuous scan by application
4035 *
4036 * ARGS:
4037 * hScanMngr - Scan manager handle \n
4038 * pChannelList - the channel list to scan
4039 *
4040 * RETURNS:
4041 * TI_OK - if connected, if not returns TI_NOK
4042 */
scanMngr_startContinuousScanByApp(TI_HANDLE hScanMngr,channelList_t * pChannelList)4043 TI_STATUS scanMngr_startContinuousScanByApp (TI_HANDLE hScanMngr, channelList_t* pChannelList)
4044 {
4045 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
4046 bssEntry_t *pCurBssEntry;
4047
4048 scanMngr_setManualScanDefaultParams(hScanMngr);
4049
4050 TRACE1(pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_startContinuousScanByApp().pScanMngr->connStatus = %d \n", pScanMngr->connStatus);
4051
4052 if (CONN_STATUS_CONNECTED == pScanMngr->connStatus)
4053 {
4054 scanMngr_setManualScanChannelList(hScanMngr,pChannelList);
4055 pCurBssEntry = apConn_getBSSParams(pScanMngr->hAPConnection);
4056 scanMngr_startContScan(hScanMngr, &pCurBssEntry->BSSID, pCurBssEntry->band);
4057 }
4058 else
4059 {
4060 TRACE1( pScanMngr->hReport, REPORT_SEVERITY_ERROR, "scanMngr_startContinuousScanByApp failed. connection status %d\n", pScanMngr->connStatus);
4061 return TI_NOK;
4062 }
4063
4064 return TI_OK;
4065 }
4066
4067 /**
4068 *
4069 * scanMngr_stopContinuousScanByApp API
4070 *
4071 * Description:
4072 *
4073 * stop the continuous scan already started by and reoprt to application
4074 *
4075 * ARGS:
4076 * hScanMngr - Scan manager handle \n
4077 *
4078 * RETURNS:
4079 * TI_OK - always
4080 */
scanMngr_stopContinuousScanByApp(TI_HANDLE hScanMngr)4081 TI_STATUS scanMngr_stopContinuousScanByApp (TI_HANDLE hScanMngr)
4082 {
4083 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
4084
4085 TRACE0(pScanMngr->hReport, REPORT_SEVERITY_INFORMATION, "scanMngr_stopContinuousScanByApp(). call scanMngr_stopContScan() \n");
4086 scanMngr_stopContScan(hScanMngr);
4087 scanMngr_reportContinuousScanResults(hScanMngr,SCAN_CRS_SCAN_COMPLETE_OK);
4088 return TI_OK;
4089 }
4090
4091
4092
4093
4094
4095 #ifdef TI_DBG
4096 /**
4097 * \\n
4098 * \date 26-May-2005\n
4099 * \brief Print scan manager statistics.\n
4100 *
4101 * Function Scope \e Public.\n
4102 * \param hScanMngr - handle to the scan manager object.\n
4103 */
scanMngr_statsPrint(TI_HANDLE hScanMngr)4104 void scanMngr_statsPrint( TI_HANDLE hScanMngr )
4105 {
4106 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
4107
4108 WLAN_OS_REPORT(("-------------- Scan Manager Statistics ---------------\n"));
4109 WLAN_OS_REPORT(("Discovery scans on G result histogram:\n"));
4110 scanMngrStatsPrintScanResultHistogram( pScanMngr->stats.DiscoveryGByStatus );
4111 WLAN_OS_REPORT(("\nDiscovery scans on A result histogram:\n"));
4112 scanMngrStatsPrintScanResultHistogram( pScanMngr->stats.DiscoveryAByStatus );
4113 WLAN_OS_REPORT(("\nTracking scans on G result histogram:\n"));
4114 scanMngrStatsPrintScanResultHistogram( pScanMngr->stats.TrackingGByStatus );
4115 WLAN_OS_REPORT(("\nTracking scans on A result histogram:\n"));
4116 scanMngrStatsPrintScanResultHistogram( pScanMngr->stats.TrackingAByStatus );
4117 WLAN_OS_REPORT(("\nImmediate scans on G result histogram:\n"));
4118 scanMngrStatsPrintScanResultHistogram( pScanMngr->stats.ImmediateGByStatus );
4119 WLAN_OS_REPORT(("\nImmediate scans on A result histogram:\n"));
4120 scanMngrStatsPrintScanResultHistogram( pScanMngr->stats.ImmediateAByStatus );
4121 WLAN_OS_REPORT(("\nTrack fail count histogram:\n"));
4122 scanMngrStatsPrintTrackFailHistogrsm( pScanMngr->stats.ConsecutiveTrackFailCountHistogram );
4123 WLAN_OS_REPORT(("Frames received:%d, frames discarded low RSSI:%d, frames discarded other:%d\n",
4124 pScanMngr->stats.receivedFrames, pScanMngr->stats.discardedFramesLowRSSI,
4125 pScanMngr->stats.discardedFramesOther));
4126 WLAN_OS_REPORT(("\nSPS channels not attened histogram:\n"));
4127 scanMngrStatsPrintSPSChannelsHistogram( pScanMngr->stats.SPSChannelsNotAttended );
4128 WLAN_OS_REPORT(("\nSPS attempts changed due to DTIM collision:%d, APs removed due to DTIM overlap: %d\n",
4129 pScanMngr->stats.SPSSavedByDTIMCheck, pScanMngr->stats.APsRemovedDTIMOverlap));
4130 WLAN_OS_REPORT(("APs removed due to invalid channel: %d\n", pScanMngr->stats.APsRemovedInvalidChannel));
4131 }
4132
4133 /**
4134 * \\n
4135 * \date 26-May-2005\n
4136 * \brief Print scan result histogram statistics.\n
4137 *
4138 * Function Scope \e Private.\n
4139 * \param scanResultHistogram - Scan results histogram (by scan complete reason).\n
4140 */
scanMngrStatsPrintScanResultHistogram(TI_UINT32 scanResultHistogram[])4141 void scanMngrStatsPrintScanResultHistogram( TI_UINT32 scanResultHistogram[] )
4142 {
4143 WLAN_OS_REPORT(("Complete TI_OK failed stopped TSF error FW reset aborted\n"));
4144 WLAN_OS_REPORT(("%-6d %-5d %-5d %-5d %-5d %-5d\n",
4145 scanResultHistogram[ SCAN_CRS_SCAN_COMPLETE_OK ],
4146 scanResultHistogram[ SCAN_CRS_SCAN_FAILED ],
4147 scanResultHistogram[ SCAN_CRS_SCAN_STOPPED ],
4148 scanResultHistogram[ SCAN_CRS_TSF_ERROR ],
4149 scanResultHistogram[ SCAN_CRS_SCAN_ABORTED_FW_RESET ],
4150 scanResultHistogram[ SCAN_CRS_SCAN_ABORTED_HIGHER_PRIORITY ]));
4151 }
4152
4153 /**
4154 * \\n
4155 * \date 26-May-2005\n
4156 * \brief Print track fail count histogram statistics.\n
4157 *
4158 * Function Scope \e Private.\n
4159 * \param trackFailHistogram - tracking failure histogram (by tracking retry).\n
4160 */
scanMngrStatsPrintTrackFailHistogrsm(TI_UINT32 trackFailHistogram[])4161 void scanMngrStatsPrintTrackFailHistogrsm( TI_UINT32 trackFailHistogram[] )
4162 {
4163 WLAN_OS_REPORT(("Attempts: 0 1 2 3 4\n"));
4164 WLAN_OS_REPORT((" %-6d %-6d %-6d %-6d %-6d\n\n",
4165 trackFailHistogram[0], trackFailHistogram[1],trackFailHistogram[2],
4166 trackFailHistogram[3], trackFailHistogram[4]));
4167 WLAN_OS_REPORT(("Attempts: 5 6 7 8 9 or more\n"));
4168 WLAN_OS_REPORT((" %-6d %-6d %-6d %-6d %-6d\n\n",
4169 trackFailHistogram[5], trackFailHistogram[6],trackFailHistogram[7],
4170 trackFailHistogram[8],trackFailHistogram[9]));
4171 }
4172
4173 /**
4174 * \\n
4175 * \date 24-July-2005\n
4176 * \brief Print SPS attendant channel histogram statistics.\n
4177 *
4178 * Function Scope \e Private.\n
4179 * \param SPSChannelsNotAttendedHistogram - SPS channels attendant histogram.\n
4180 */
scanMngrStatsPrintSPSChannelsHistogram(TI_UINT32 SPSChannelsNotAttendedHistogram[])4181 void scanMngrStatsPrintSPSChannelsHistogram( TI_UINT32 SPSChannelsNotAttendedHistogram[] )
4182 {
4183 WLAN_OS_REPORT(("Channel index: 0 1 2 3\n"));
4184 WLAN_OS_REPORT((" %-6d %-6d %-6d %-6d\n\n",
4185 SPSChannelsNotAttendedHistogram[ 0 ], SPSChannelsNotAttendedHistogram[ 1 ],
4186 SPSChannelsNotAttendedHistogram[ 2 ], SPSChannelsNotAttendedHistogram[ 3 ]));
4187 WLAN_OS_REPORT(("Channel index: 4 5 6 7\n"));
4188 WLAN_OS_REPORT((" %-6d %-6d %-6d %-6d\n\n",
4189 SPSChannelsNotAttendedHistogram[ 4 ], SPSChannelsNotAttendedHistogram[ 5 ],
4190 SPSChannelsNotAttendedHistogram[ 6 ], SPSChannelsNotAttendedHistogram[ 7 ]));
4191 WLAN_OS_REPORT(("Channel index: 8 9 10 11\n"));
4192 WLAN_OS_REPORT((" %-6d %-6d %-6d %-6d\n\n",
4193 SPSChannelsNotAttendedHistogram[ 8 ], SPSChannelsNotAttendedHistogram[ 9 ],
4194 SPSChannelsNotAttendedHistogram[ 10 ], SPSChannelsNotAttendedHistogram[ 11 ]));
4195 WLAN_OS_REPORT(("Channel index: 12 13 14 15\n"));
4196 WLAN_OS_REPORT((" %-6d %-6d %-6d %-6d\n\n",
4197 SPSChannelsNotAttendedHistogram[ 12 ], SPSChannelsNotAttendedHistogram[ 13 ],
4198 SPSChannelsNotAttendedHistogram[ 14 ], SPSChannelsNotAttendedHistogram[ 15 ]));
4199 }
4200
4201 /**
4202 * \\n
4203 * \date 26-May-2005\n
4204 * \brief Reset scan manager statistics.\n
4205 *
4206 * Function Scope \e Public.\n
4207 * \param hScanMngr - handle to the scan manager object.\n
4208 */
scanMngr_statsReset(TI_HANDLE hScanMngr)4209 void scanMngr_statsReset( TI_HANDLE hScanMngr )
4210 {
4211 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
4212
4213 os_memoryZero( pScanMngr->hOS, &(pScanMngr->stats), sizeof(scan_mngrStat_t));
4214 }
4215
4216 /**
4217 * \\n
4218 * \date 25-July-2005\n
4219 * \brief Print Neighbor AP list.\n
4220 *
4221 * Function Scope \e Public.\n
4222 * \param hScanMngr - Handle to the scan manager object.\n
4223 */
scanMngrDebugPrintNeighborAPList(TI_HANDLE hScanMngr)4224 void scanMngrDebugPrintNeighborAPList( TI_HANDLE hScanMngr )
4225 {
4226 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
4227 int i,j;
4228
4229 WLAN_OS_REPORT(("-------------- Scan Manager Neighbor APs List ---------------\n"));
4230 for ( i = 0; i < RADIO_BAND_NUM_OF_BANDS; i++ )
4231 {
4232 WLAN_OS_REPORT(("Neighbor AP list for band:%d\n", i));
4233 if ( 0 == pScanMngr->neighborAPsDiscoveryList[ i ].numOfEntries )
4234 {
4235 WLAN_OS_REPORT(("Neighbor AP list is empty.\n"));
4236 continue; /* to next band */
4237 }
4238 WLAN_OS_REPORT(("%-17s %-4s %-7s %-30s\n", "BSSID", "Band", "Channel", "Discovery state"));
4239 WLAN_OS_REPORT(("------------------------------------------------------\n"));
4240 for ( j = 0; j < pScanMngr->neighborAPsDiscoveryList[ i ].numOfEntries; i++ )
4241 {
4242 scanMngrDebugPrintNeighborAP( &(pScanMngr->neighborAPsDiscoveryList[ i ].APListPtr[ j ]),
4243 pScanMngr->neighborAPsDiscoveryList[ i ].trackStatusList[ j ] );
4244 }
4245 }
4246 }
4247
4248 /**
4249 * \\n
4250 * \date 25-July-2005\n
4251 * \brief Print One neighbor AP entry.\n
4252 *
4253 * Function Scope \e Private.\n
4254 * \param pNeighborAp - pointer to the neighbor AP data.\n
4255 * \param discovery state - the discovery state of this neighbor AP.\n
4256 */
scanMngrDebugPrintNeighborAP(neighborAP_t * pNeighborAp,scan_neighborDiscoveryState_e discoveryState)4257 void scanMngrDebugPrintNeighborAP( neighborAP_t* pNeighborAp, scan_neighborDiscoveryState_e discoveryState )
4258 {
4259 WLAN_OS_REPORT(("%02x:%02x:%02x:%02x:%02x:%02x %-4d %-7d %-30s\n",
4260 pNeighborAp->BSSID[ 0 ], pNeighborAp->BSSID[ 1 ], pNeighborAp->BSSID[ 2 ],
4261 pNeighborAp->BSSID[ 3 ], pNeighborAp->BSSID[ 4 ], pNeighborAp->BSSID[ 5 ],
4262 pNeighborAp->band, pNeighborAp->channel, neighborDiscovreyStateDesc[ discoveryState ]));
4263 }
4264
4265 /**
4266 * \\n
4267 * \date 27-July-2005\n
4268 * \brief Prints a scan command.\n
4269 *
4270 * Function Scope \e Private.\n
4271 * \param pScanParams - a pointer to the scan parameters structure.\n
4272 */
scanMngrDebugPrintScanCommand(TScanParams * pScanParams)4273 void scanMngrDebugPrintScanCommand( TScanParams* pScanParams )
4274 {
4275 int i;
4276
4277 if ( 0 == pScanParams->numOfChannels )
4278 {
4279 WLAN_OS_REPORT(("Invalid scan command.\n"));
4280 return;
4281 }
4282
4283 WLAN_OS_REPORT(("Scan type: %s, band: %d\n", scanTypeDesc[ pScanParams->scanType ], pScanParams->band));
4284
4285 switch (pScanParams->scanType)
4286 {
4287 case SCAN_TYPE_NORMAL_ACTIVE:
4288 WLAN_OS_REPORT(("Probe request number:%d, rate:%x, TX level:%d\n",
4289 pScanParams->probeReqNumber, pScanParams->probeRequestRate));
4290 /* break is missing on purpose!!! */
4291
4292 case SCAN_TYPE_NORMAL_PASSIVE:
4293 WLAN_OS_REPORT(("SSID: %s\n", pScanParams->desiredSsid));
4294 WLAN_OS_REPORT(("%-4s %-17s %-17s %-20s %-8s %-14s %-14s\n", "Chnl", "BSSID", "Early ter. event",
4295 "Early ter. frame num", "TX level", "Max dwell time", "Min dwell time"));
4296 WLAN_OS_REPORT(("------------------------------------------------------------------------------------------------------\n"));
4297 for ( i = 0; i < pScanParams->numOfChannels; i++ )
4298 {
4299 scanMngrDebugPrintNormalChannelParam( &(pScanParams->channelEntry[ i ].normalChannelEntry));
4300 }
4301 break;
4302
4303 case SCAN_TYPE_TRIGGERED_ACTIVE:
4304 WLAN_OS_REPORT(("Probe request number:%d, rate:%x, TX level:%d\n",
4305 pScanParams->probeReqNumber, pScanParams->probeRequestRate ));
4306 /* break is missing on purpose!!! */
4307
4308 case SCAN_TYPE_TRIGGERED_PASSIVE:
4309 WLAN_OS_REPORT(("SSID: %s, Tid: %d\n", pScanParams->desiredSsid, pScanParams->Tid));
4310 WLAN_OS_REPORT(("%-4s %-17s %-17s %-20s %-8s %-14s %-14s\n", "Chnl", "BSSID", "Early ter. event",
4311 "Early ter. frame num", "TX level", "Max dwell time", " Min dwell time"));
4312 WLAN_OS_REPORT(("------------------------------------------------------------------------------------------------------\n"));
4313 for ( i = 0; i < pScanParams->numOfChannels; i++ )
4314 {
4315 scanMngrDebugPrintNormalChannelParam( &(pScanParams->channelEntry[ i ].normalChannelEntry));
4316 }
4317 break;
4318
4319 case SCAN_TYPE_SPS:
4320 WLAN_OS_REPORT(("Total scan duration (for scan timer): %d, latest TSF value: %x-%x\n",
4321 pScanParams->SPSScanDuration,
4322 INT64_HIGHER(pScanParams->latestTSFValue), INT64_LOWER(pScanParams->latestTSFValue)));
4323 WLAN_OS_REPORT(("%-4s %-17s %-17s %-7s %-16s %-20s\n", "Chnl", "BSSID", "Start time (TSF)", "Duration",
4324 "Early ter. event", "Early ter. frame num"));
4325 WLAN_OS_REPORT(("---------------------------------------------------------------------------------------\n"));
4326 for ( i = 0; i < pScanParams->numOfChannels; i++ )
4327 {
4328 scanMngrDebugPrintSPSChannelParam( &(pScanParams->channelEntry[ i ].SPSChannelEntry));
4329 }
4330 break;
4331
4332 case SCAN_TYPE_NO_SCAN:
4333 default:
4334 WLAN_OS_REPORT(("Invalid scan type: %d\n", pScanParams->scanType));
4335 break;
4336 }
4337
4338 }
4339
4340 /**
4341 * \\n
4342 * \date 27-July-2005\n
4343 * \brief Prints scan command single normal channel.\n
4344 *
4345 * Function Scope \e Private.\n
4346 * \param pNormalChannel - a pointer to the normal channel to print.\n
4347 */
scanMngrDebugPrintNormalChannelParam(TScanNormalChannelEntry * pNormalChannel)4348 void scanMngrDebugPrintNormalChannelParam( TScanNormalChannelEntry* pNormalChannel )
4349 {
4350 WLAN_OS_REPORT(("%-4d %02x:%02x:%02x:%02x:%02x:%02x %-17s %-20d %-8d %-14d %-14d\n", pNormalChannel->channel,
4351 pNormalChannel->bssId[ 0 ], pNormalChannel->bssId[ 1 ], pNormalChannel->bssId[ 2 ],
4352 pNormalChannel->bssId[ 3 ], pNormalChannel->bssId[ 4 ], pNormalChannel->bssId[ 5 ],
4353 earlyTerminationDesc[ pNormalChannel->earlyTerminationEvent >> 8 ],
4354 pNormalChannel->ETMaxNumOfAPframes, pNormalChannel->txPowerDbm,
4355 pNormalChannel->minChannelDwellTime, pNormalChannel->maxChannelDwellTime));
4356 }
4357
4358 /**
4359 * \\n
4360 * \date 27-July-2005\n
4361 * \brief Prints scan command single SPS channel.\n
4362 *
4363 * Function Scope \e Private.\n
4364 * \param pSPSChannel - a pointer to the SPS channel to print.\n
4365 */
scanMngrDebugPrintSPSChannelParam(TScanSpsChannelEntry * pSPSChannel)4366 void scanMngrDebugPrintSPSChannelParam( TScanSpsChannelEntry* pSPSChannel )
4367 {
4368 WLAN_OS_REPORT(("%-4d %02x:%02x:%02x:%02x:%02x:%02x %8x-%8x %-7d %-16s %-3d\n",
4369 pSPSChannel->channel, pSPSChannel->bssId[ 0 ], pSPSChannel->bssId[ 1 ],
4370 pSPSChannel->bssId[ 2 ], pSPSChannel->bssId[ 3 ], pSPSChannel->bssId[ 4 ],
4371 pSPSChannel->bssId[ 5 ], INT64_HIGHER(pSPSChannel->scanStartTime),
4372 INT64_LOWER(pSPSChannel->scanStartTime), pSPSChannel->scanDuration,
4373 earlyTerminationDesc[ pSPSChannel->earlyTerminationEvent >> 8 ], pSPSChannel->ETMaxNumOfAPframes));
4374 }
4375
4376 /**
4377 * \\n
4378 * \date 25-July-2005\n
4379 * \brief Prints all data in the scan manager object.\n
4380 *
4381 * Function Scope \e Public.\n
4382 * \param hScanMngr - handle to the scan manager object.\n
4383 */
scanMngrDebugPrintObject(TI_HANDLE hScanMngr)4384 void scanMngrDebugPrintObject( TI_HANDLE hScanMngr )
4385 {
4386 scanMngr_t* pScanMngr = (scanMngr_t*)hScanMngr;
4387
4388 WLAN_OS_REPORT(("-------------- Scan Manager Object Dump ---------------\n"));
4389 WLAN_OS_REPORT(("Continuous scan timer running: %s, Continuous scan started:%s\n",
4390 booleanDesc[ pScanMngr->bTimerRunning ], booleanDesc[ pScanMngr->bContinuousScanStarted ]));
4391 WLAN_OS_REPORT(("Current BSS in low quality: %s, AP TSF synchronized: %s\n",
4392 booleanDesc[ pScanMngr->bLowQuality ], booleanDesc[ pScanMngr->bSynchronized ]));
4393 WLAN_OS_REPORT(("Continuous scan state: %s, Immediate scan state: %s\n",
4394 contScanStatesDesc[ pScanMngr->contScanState ], immedScanStatesDesc[ pScanMngr->immedScanState ]));
4395 WLAN_OS_REPORT(("Discovery part: %s, G channels discovery Index: %d, A channels discovery index: %d\n",
4396 discoveryPartDesc[ pScanMngr->currentDiscoveryPart ],
4397 pScanMngr->channelDiscoveryIndex[ RADIO_BAND_2_4_GHZ ],
4398 pScanMngr->channelDiscoveryIndex[ RADIO_BAND_5_0_GHZ ]));
4399 WLAN_OS_REPORT(("G neighbor APs discovery index: %d, A neighbor APs discovery index: %d\n",
4400 pScanMngr->neighborAPsDiscoveryIndex[ RADIO_BAND_2_4_GHZ ],
4401 pScanMngr->neighborAPsDiscoveryIndex[ RADIO_BAND_5_0_GHZ ]));
4402 WLAN_OS_REPORT(("Current BSS MAC: %02x:%02x:%02x:%02x:%02x:%02x, Current BSS band: %d\n",
4403 pScanMngr->currentBSS[ 0 ], pScanMngr->currentBSS[ 1 ], pScanMngr->currentBSS[ 2 ],
4404 pScanMngr->currentBSS[ 3 ], pScanMngr->currentBSS[ 4 ], pScanMngr->currentBSS[ 5 ],
4405 pScanMngr->currentBSSBand));
4406 WLAN_OS_REPORT(("Last beacon DTIM count:%d, TSF:%x-%x\n",
4407 pScanMngr->lastLocalBcnDTIMCount,
4408 INT64_HIGHER(pScanMngr->currentTSF), INT64_LOWER(pScanMngr->currentTSF)));
4409 WLAN_OS_REPORT(("-------------- Scan Manager Policy ---------------\n"));
4410 scanMngrTracePrintScanPolicy( &(pScanMngr->scanPolicy));
4411 WLAN_OS_REPORT(("-------------- Scan Manager BSS List ---------------\n"));
4412 scanMngrDebugPrintBSSList( hScanMngr );
4413 scanMngrDebugPrintNeighborAPList( hScanMngr );
4414 scanMngr_statsPrint( hScanMngr );
4415 WLAN_OS_REPORT(("New BSS found during last discovery:%s, Number of scan cycles during which no new AP was found: %d\n",
4416 booleanDesc[ pScanMngr->bNewBSSFound ], pScanMngr->consecNotFound));
4417 WLAN_OS_REPORT(("Scan for neighbor APs only at last immediate scan: %s\n",
4418 booleanDesc[ pScanMngr->bImmedNeighborAPsOnly ]));
4419 WLAN_OS_REPORT(("-------------- Last issued scan command ---------------\n"));
4420 scanMngrDebugPrintScanCommand( &(pScanMngr->scanParams));
4421 WLAN_OS_REPORT(("-------------- Handles ---------------\n"));
4422 WLAN_OS_REPORT(("Continuous scan timer: %x, OS:% x, Reg. domain: %x\n",
4423 pScanMngr->hContinuousScanTimer, pScanMngr->hOS, pScanMngr->hRegulatoryDomain));
4424 WLAN_OS_REPORT(("Report: %x, Roaming manager: %x, Scan concentrator: %x\n",
4425 pScanMngr->hReport, pScanMngr->hRoamingMngr, pScanMngr->hScanCncn));
4426 }
4427
4428 #endif /* TI_DBG */
4429