Home | History | Annotate | Download | only in Application
      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 ****************************************************************************/
     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 
     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 
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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 
   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 
   3383 void scanMngr_unload (TI_HANDLE hScanMngr)
   3384 {
   3385     scanMngrFreeMem (hScanMngr);
   3386 }
   3387 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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  */
   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 */
   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 */
   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 */
   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 */
   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 */
   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 */
   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 */
   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 */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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  */
   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