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