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