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