• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &param);
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, &param );
743     pScanMngr->currentBSSBeaconInterval = param.content.beaconInterval;
744 
745     param.paramType = SITE_MGR_DTIM_PERIOD_PARAM;
746     siteMgr_getParam( pScanMngr->hSiteMngr, &param );
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, &param );
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, &param );
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, &param );
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, &param );
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, &param );
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, &param );
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, &param );
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