Home | History | Annotate | Download | only in scanCncn
      1 /** \file ScanCncn.c
      2  *  \brief This file include the scan concentrator module implementation
      3  *  \author Ronen Kalish
      4  *  \date 03-Jan-2005
      5  */
      6 /****************************************************************************
      7 **+-----------------------------------------------------------------------+**
      8 **|                                                                       |**
      9 **| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved.      |**
     10 **| All rights reserved.                                                  |**
     11 **|                                                                       |**
     12 **| Redistribution and use in source and binary forms, with or without    |**
     13 **| modification, are permitted provided that the following conditions    |**
     14 **| are met:                                                              |**
     15 **|                                                                       |**
     16 **|  * Redistributions of source code must retain the above copyright     |**
     17 **|    notice, this list of conditions and the following disclaimer.      |**
     18 **|  * Redistributions in binary form must reproduce the above copyright  |**
     19 **|    notice, this list of conditions and the following disclaimer in    |**
     20 **|    the documentation and/or other materials provided with the         |**
     21 **|    distribution.                                                      |**
     22 **|  * Neither the name Texas Instruments nor the names of its            |**
     23 **|    contributors may be used to endorse or promote products derived    |**
     24 **|    from this software without specific prior written permission.      |**
     25 **|                                                                       |**
     26 **| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |**
     27 **| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |**
     28 **| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
     29 **| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |**
     30 **| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
     31 **| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |**
     32 **| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
     33 **| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
     34 **| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |**
     35 **| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
     36 **| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |**
     37 **|                                                                       |**
     38 **+-----------------------------------------------------------------------+**
     39 ****************************************************************************/
     40 
     41 #include "ScanCncn.h"
     42 #include "ScanCncnAppSM.h"
     43 #include "ScanCncnDrvSM.h"
     44 #include "ScanCncnRoamingContSM.h"
     45 #include "ScanCncnRoamingImmedSM.h"
     46 #include "ScanCncnAppApi.h"
     47 #include "ScanCncnOidSM.h"
     48 #include "report.h"
     49 #include "fsm.h"
     50 #include "scrApi.h"
     51 #include "paramIn.h"
     52 #include "regulatoryDomainApi.h"
     53 #include "siteMgrApi.h"
     54 #include "siteHash.h"
     55 #include "utils.h"
     56 #include "healthMonitor.h"
     57 
     58 /* static functions */
     59 static void scanConcentrator_SGupdateScanParams( TI_HANDLE hScanCncn, scan_Params_t* pScanParams );
     60 
     61 /**
     62  * \author Ronen Kalish\n
     63  * \date 02-Jan-2005\n
     64  * \brief Creates the scan concentrator object
     65  *
     66  * Function Scope \e Public.\n
     67  * \param hOS - handle to the OS object.\n
     68  * \return a handle to the scan SRV object, NULL if an error occurred.\n
     69  */
     70 TI_HANDLE scanConcentrator_create( TI_HANDLE hOS )
     71 {
     72     UINT16   initVector = 0;
     73 
     74     /* allocate the scan concentrator object */
     75     scanConcentrator_t *pScanConcentrator = os_memoryAlloc( hOS, sizeof(scanConcentrator_t) );
     76     if ( NULL == pScanConcentrator )
     77     {
     78         WLAN_OS_REPORT( ("ERROR: Failed to create scan concnetrator module\n") );
     79         return NULL;
     80     }
     81     initVector |= (1 << SCAN_ALLOC_OBJECT);
     82 
     83     /* store the OS handle */
     84     pScanConcentrator->hOS = hOS;
     85 
     86     /* create state machines */
     87     if ( OK != fsm_Create( hOS, &(pScanConcentrator->clientSM[ SCAN_SCC_APP ]),
     88                            APP_SCAN_NUM_OF_STATES, APP_SCAN_NUM_OF_EVENTS ) )
     89     {
     90         WLAN_OS_REPORT( ("ERROR: Failed to allocate application scan state machine\n") );
     91         scanConcentrator_freeMem( pScanConcentrator, initVector );
     92         return NULL;
     93     }
     94     initVector |= (1 << SCAN_ALLOC_APP_SM);
     95 
     96     if ( OK != fsm_Create( hOS, &(pScanConcentrator->clientSM[ SCAN_SCC_DRIVER ]),
     97                            DRV_SCAN_NUM_OF_STATES, DRV_SCAN_NUM_OF_EVENTS ) )
     98     {
     99         WLAN_OS_REPORT( ("ERROR: Failed to allocate driver scan state machine\n") );
    100         scanConcentrator_freeMem( pScanConcentrator, initVector );
    101         return NULL;
    102     }
    103     initVector |= (1 << SCAN_ALLOC_DRV_SM);
    104 
    105     if ( OK != fsm_Create( hOS, &(pScanConcentrator->clientSM[ SCAN_SCC_ROAMING_CONT ]),
    106                            CONT_SCAN_NUM_OF_STATES, CONT_SCAN_NUM_OF_EVENTS ) )
    107     {
    108         WLAN_OS_REPORT( ("ERROR: Failed to allocate continuous scan for roaming state machine\n") );
    109         scanConcentrator_freeMem( pScanConcentrator, initVector );
    110         return NULL;
    111     }
    112     initVector |= (1 << SCAN_ALLOC_CONT_SM);
    113 
    114     if ( OK != fsm_Create( hOS, &(pScanConcentrator->clientSM[ SCAN_SCC_ROAMING_IMMED ]),
    115                            IMMED_SCAN_NUM_OF_STATES, IMMED_SCAN_NUM_OF_EVENTS ) )
    116     {
    117         WLAN_OS_REPORT( ("ERROR: Failed to allocate immediate scan for roaming state machine\n") );
    118         scanConcentrator_freeMem( pScanConcentrator, initVector );
    119         return NULL;
    120     }
    121     initVector |= (1 << SCAN_ALLOC_IMMED_SM);
    122 	if ( OK != fsm_Create( hOS, &(pScanConcentrator->hOidSM), OID_SCAN_NUM_OF_STATES, OID_SCAN_NUM_OF_EVENTS) )
    123 	{
    124         WLAN_OS_REPORT( ("ERROR: Failed to allocate OID scan state machine\n") );
    125         scanConcentrator_freeMem( pScanConcentrator, initVector );
    126         return NULL;
    127 	}
    128     return pScanConcentrator;
    129 }
    130 
    131 /**
    132  * \author Ronen Kalish\n
    133  * \date 02-Jan-2005\n
    134  * \brief Finalizes the scan concentrator object (freeing system resources)
    135  *
    136  * Function Scope \e Public.\n
    137  * \param hScanCncn - handle to the scan concentrator object.\n
    138  */
    139 void scanConcentrator_release( TI_HANDLE hScanCncn )
    140 {
    141     scanConcentrator_freeMem( hScanCncn, 0xffff );
    142 }
    143 
    144 /**
    145  * \author Ronen Kalish\n
    146  * \date 05-Jan-2005\n
    147  * \brief Frees the scan concentrator memory, according to the init vector.
    148  *
    149  * Function Scope \e Public.\n
    150  * \param hScanCncn - handle to the scan concentrator object.\n
    151  * \param initVec - a vector holding on bits for allocated components and off bits for non allocated components
    152  */
    153 void scanConcentrator_freeMem( TI_HANDLE hScanCncn, UINT16 initVec )
    154 {
    155     scanConcentrator_t *pScanConcentrator= (scanConcentrator_t*)hScanCncn;
    156 
    157     /* free state machines */
    158     if ( initVec & (1<<SCAN_ALLOC_APP_SM) )
    159     {
    160         fsm_Unload( pScanConcentrator->hOS, pScanConcentrator->clientSM[ SCAN_SCC_APP ] );
    161     }
    162     if ( initVec & (1 << SCAN_ALLOC_DRV_SM) )
    163     {
    164         fsm_Unload( pScanConcentrator->hOS, pScanConcentrator->clientSM[ SCAN_SCC_DRIVER ] );
    165     }
    166     if ( initVec & (1 << SCAN_ALLOC_CONT_SM) )
    167     {
    168         fsm_Unload( pScanConcentrator->hOS, pScanConcentrator->clientSM[ SCAN_SCC_ROAMING_CONT ] );
    169     }
    170     if ( initVec & (1 << SCAN_ALLOC_IMMED_SM) )
    171     {
    172         fsm_Unload( pScanConcentrator->hOS, pScanConcentrator->clientSM[ SCAN_SCC_ROAMING_IMMED ] );
    173     }
    174 	if ( initVec & (1 << SCAN_ALLOC_OID_SM) )
    175 	{
    176 		fsm_Unload( pScanConcentrator->hOS, pScanConcentrator->hOidSM );
    177 	}
    178     /* free scan concentrator object */
    179     if ( initVec & (1 << SCAN_ALLOC_OBJECT) )
    180     {
    181         os_memoryFree( pScanConcentrator->hOS, pScanConcentrator, sizeof(scanConcentrator_t) );
    182     }
    183 }
    184 
    185 /**
    186  * \author Ronen Kalish\n
    187  * \date 02-Jan-2005\n
    188  * \brief Initialize the scan concentrator object.
    189  *
    190  * Function Scope \e Public.\n
    191  * \param hScanCncn - handle to the scan concentrator object.\n
    192  * \param hHalCtrl - handle to the Hal Ctrl object.\n
    193  * \param hReport - handle to the Report object.\n
    194  * \param hRegDomain - handle to the regulatory domain object.\n
    195  * \param hSiteMngr - handle to the site manager object.\n
    196  * \param hSCR - handle to the SCR object.\n
    197  * \param hMacServices - handle to the MacServices object.\n
    198  * \param hAPConn - handle to the AP connection object.\n
    199  * \param hEventSRV - handle to the event SRV object.\n
    200  * \param hMlme - handle to the MLME object.\n
    201  * \param hHealthMonitor - handle to the health monitor object.\n
    202  * \param pScanConcentratorInitParams - pointer to the init parameters structure.\n
    203  */
    204 void scanConcentrator_init( TI_HANDLE hScanCncn,
    205                             TI_HANDLE hHalCtrl,
    206                             TI_HANDLE hReport,
    207                             TI_HANDLE hRegDomain,
    208                             TI_HANDLE hSiteMngr,
    209                             TI_HANDLE hSCR,
    210                             TI_HANDLE hMacServices,
    211                             TI_HANDLE hAPConn,
    212                             TI_HANDLE hEventSRV,
    213                             TI_HANDLE hMlme,
    214                             TI_HANDLE hCtrlData,
    215                             TI_HANDLE hHealthMonitor,
    216                             scanConcentratorInitParams_t* pScanConcentratorInitParams )
    217 {
    218     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
    219 
    220     /* copy handles */
    221     pScanConcentrator->hReport = hReport;
    222     pScanConcentrator->hHalCtrl = hHalCtrl;
    223     pScanConcentrator->hRegulatoryDomain = hRegDomain;
    224     pScanConcentrator->hSiteManager = hSiteMngr;
    225     pScanConcentrator->hSCR = hSCR;
    226     pScanConcentrator->hMacServices = hMacServices;
    227     pScanConcentrator->hAPConn = hAPConn;
    228     pScanConcentrator->hEventSrv = hEventSRV;
    229     pScanConcentrator->hMlme = hMlme;
    230     pScanConcentrator->hCtrlData = hCtrlData;
    231     pScanConcentrator->hHealthMonitor = hHealthMonitor;
    232 
    233     /* copy registry values */
    234     os_memoryCopy( pScanConcentrator->hOS, &(pScanConcentrator->initParams), pScanConcentratorInitParams,
    235                    sizeof( scanConcentratorInitParams_t ) );
    236 
    237     /* initialize state machines */
    238     if ( OK != scanConcentratorAppSM_init( hScanCncn ) )
    239     {
    240         WLAN_REPORT_ERROR( hReport, SCAN_CNCN_MODULE_LOG, ("Error: application SM initialization failed.\n") );
    241         return;
    242     }
    243 
    244     if ( OK != scanConcentratorDrvSM_init( hScanCncn ) )
    245     {
    246         WLAN_REPORT_ERROR( hReport, SCAN_CNCN_MODULE_LOG, ("Error: driver SM initialization failed.\n") );
    247         return;
    248     }
    249 
    250     if ( OK != scanConcentratorRoamingContSM_init( hScanCncn ) )
    251     {
    252         WLAN_REPORT_ERROR( hReport, SCAN_CNCN_MODULE_LOG, ("Error: continuous scan for roaming SM initialization failed.\n") );
    253         return;
    254     }
    255 
    256     if ( OK != scanConcentratorRoamingImmedSM_init( hScanCncn ) )
    257     {
    258         WLAN_REPORT_ERROR( hReport, SCAN_CNCN_MODULE_LOG, ("Error: immediate scan for roaming SM initialization failed.\n") );
    259         return;
    260     }
    261 	if ( OK != scanConcentratorOidSM_init( hScanCncn ) )
    262 	{
    263         WLAN_REPORT_ERROR( hReport, SCAN_CNCN_MODULE_LOG, ("Error: OID scan SM initialization failed.\n") );
    264         return;
    265 	}
    266     /* register SCR callbacks */
    267     scr_registerClientCB( pScanConcentrator->hSCR, SCR_CID_APP_SCAN, scanConcentrator_scrAppCB, hScanCncn );
    268     scr_registerClientCB( pScanConcentrator->hSCR, SCR_CID_DRIVER_FG_SCAN, scanConcentrator_scrDriverCB, hScanCncn );
    269     scr_registerClientCB( pScanConcentrator->hSCR, SCR_CID_CONT_SCAN, scanConcentrator_scrRoamingContCB, hScanCncn );
    270     scr_registerClientCB( pScanConcentrator->hSCR, SCR_CID_IMMED_SCAN, scanConcentrator_scrRoamingImmedCB, hScanCncn );
    271 
    272     /* register scan SRV scan complete CB */
    273     MacServices_scanSRV_registerScanCompleteCB( hMacServices, scanConcentrator_scanCompleteNotificationCB, hScanCncn );
    274 
    275     /* nullify other parameters */
    276     pScanConcentrator->currentRunningScanClient = SCAN_SCC_NO_CLIENT;
    277     pScanConcentrator->connectionStatus = STA_NOT_CONNECTED;
    278 
    279     /* bUseSGParams is TRUE only when SG module is enabled */
    280     pScanConcentrator->bUseSGParams = FALSE;
    281 
    282     /* "register" the application scan result callback */
    283     scanConcentrator_registerScanResultCB( hScanCncn, SCAN_SCC_APP, scanConcentrator_appScanResultCB, hScanCncn );
    284 
    285     WLAN_REPORT_INIT( hReport, SCAN_CNCN_MODULE_LOG,  (".....Scan concentrator configured successfully.\n"));
    286 }
    287 
    288 /**
    289  * \author Ronen Kalish\n
    290  * \date 02-Jan-2005\n
    291  * \brief switch the connection mode to connected (infrastructure BSS)
    292  *
    293  * Function Scope \e Public.\n
    294  * \param hScanCncn - handle to the scan concentrator object.\n
    295  */
    296 void scanConcentrator_switchToConnected( TI_HANDLE hScanCncn )
    297 {
    298     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
    299 
    300     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, ("Switching to connected state.\n") );
    301 
    302     /* change connection status to connected */
    303     pScanConcentrator->connectionStatus = STA_CONNECTED;
    304 
    305     /* Any running scans in other modes will be aborted (if needed) by the SCR (or have already been) */
    306 }
    307 
    308 /**
    309  * \author Ronen Kalish\n
    310  * \date 02-Jan-2005\n
    311  * \brief switch the connection mode to not connected
    312  *
    313  * Function Scope \e Public.\n
    314  * \param hScanCncn - handle to the scan concentrator object.\n
    315  */
    316 void scanConcentrator_switchToNotConnected( TI_HANDLE hScanCncn )
    317 {
    318     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
    319 
    320     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, ("Switching to not connected state.\n") );
    321 
    322     /* change connection status to connected */
    323     pScanConcentrator->connectionStatus = STA_NOT_CONNECTED;
    324 
    325     /* Any running scans in other modes will be aborted (if needed) by the SCR (or have already been) */
    326 }
    327 
    328 /**
    329  * \author Ronen Kalish\n
    330  * \date 02-Jan-2005\n
    331  * \brief switch the connection mode to IBSS participation
    332  *
    333  * Function Scope \e Public.\n
    334  * \param hScanCncn - handle to the scan concentrator object.\n
    335  */
    336 void scanConcentrator_switchToIBSS( TI_HANDLE hScanCncn )
    337 {
    338     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
    339 
    340     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, ("Switching to IBSS state.\n") );
    341 
    342     /* change connection status to connected */
    343     pScanConcentrator->connectionStatus = STA_IBSS;
    344 
    345     /* Any running scans in other modes will be aborted (if needed) by the SCR (or have already been) */
    346 }
    347 
    348 /**
    349  * \author Ronen Kalish\n
    350  * \date 02-Jan-2005\n
    351  * \brief Called by a client to request a scan.
    352  *
    353  * Function Scope \e Public.\n
    354  * \param hScanCncn - handle to the scan concentrator object.\n
    355  * \param client - the client ID.\n
    356  * \return scan operation detailed result status.\n
    357  * \retval SCAN_CRS_SCAN_RUNNING - scan started successfully and is now running.\n
    358  * \retval SCAN_CRS_SCAN_FAILED - scan failed to start due to an unexpected error.\n
    359  */
    360 scan_cncnResultStatus_e scanConcentrator_scan( TI_HANDLE hScanCncn,
    361                                                scan_CncnClient_e client,
    362                                                scan_Params_t* pScanParams )
    363 {
    364     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
    365     whalCtrl_setTemplate_t  templateStruct;
    366     probeReqTemplate_t      probeReqTemplate;
    367     paramInfo_t             param;
    368 
    369     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    370                              ("Received scan request from client %d\n", client) );
    371 
    372     /* sanity check verify that this is a known client */
    373     if ( client >= SCAN_SCC_NUM_OF_CLIENTS)
    374     {
    375         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    376                              ("Scan request with illegal client %d, aborting request.\n", client) );
    377         return SCAN_CRS_SCAN_FAILED;
    378     }
    379 
    380     /* scan requests with junk SSID (other than application scans) are rejected */
    381     if ( (client == SCAN_SCC_DRIVER) &&
    382          utils_isJunkSSID( &(pScanParams->desiredSsid) ) )
    383     {
    384         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    385                              ("Scan request with junk SSID from client %d.\n", client) );
    386         return SCAN_CRS_SCAN_FAILED;
    387     }
    388 
    389 #ifndef TI_DBG
    390     /* in release mode, no channel expansion is done */
    391     if ( 0 == pScanParams->numOfChannels )
    392     {
    393         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    394                              ("Scan request with 0 channels from client:%d\n", client) );
    395         return SCAN_CRS_SCAN_FAILED;
    396     }
    397 #endif
    398 
    399 	/* Validate dwell times */
    400 	if ( pScanParams->scanType != SCAN_TYPE_SPS )
    401 	{
    402 		int channel;
    403 
    404 		for (channel = 0; channel < pScanParams->numOfChannels; ++channel)
    405 		{
    406 			if (pScanParams->channelEntry[channel].normalChannelEntry.maxChannelDwellTime <
    407 				pScanParams->channelEntry[channel].normalChannelEntry.minChannelDwellTime)
    408 			{
    409 				WLAN_REPORT_ERROR( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    410 					("%s: MaxChannelDwellTime must not be smaller than MinChannelDwellTime on channel %d!\n", __FUNCTION__, channel));
    411 
    412 				return SCAN_CRS_SCAN_FAILED;
    413 			}
    414 		}
    415 	}
    416 
    417     /* Check if country code should be reset in RegDomain. This is done here in order to detect if country should be updated
    418        before the next scan. RegDomain will decide if country code should be deleted or remain the same. */
    419     param.paramType = REGULATORY_DOMAIN_CHECK_COUNTRY_PARAM;
    420     regulatoryDomain_setParam(pScanConcentrator->hRegulatoryDomain,&param);
    421 
    422 	WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,("SG=%d, scan band = %d \n",
    423 																			   pScanConcentrator->bUseSGParams,
    424 																			   pScanParams->band));
    425     /* act according to client */
    426     switch ( client )
    427     {
    428     case SCAN_SCC_APP:
    429         /* check that the application state machine is in IDLE state
    430            (no more than one scan at a time per client is allowed). */
    431         if ( APP_SCAN_STATE_IDLE != pScanConcentrator->clientSMState[ SCAN_SCC_APP ] )
    432         {
    433             return SCAN_CRS_SCAN_FAILED;
    434         }
    435         else
    436         {
    437             /* copy scan parameters to local buffer */
    438             os_memoryCopy( pScanConcentrator->hOS, &(pScanConcentrator->clientScanParams[ SCAN_SCC_APP ]),
    439                            pScanParams, sizeof(scan_Params_t) );
    440 
    441             /* ask the reg domain which channels are allowed for the requested scan type */
    442             scanConcentrator_verifyChannelsWithRegDomain( hScanCncn, &(pScanConcentrator->clientScanParams[ SCAN_SCC_APP ]) );
    443 
    444             /* if no channels are available for scan, return negative result */
    445             if ( 0 == pScanConcentrator->clientScanParams[ SCAN_SCC_APP ].numOfChannels )
    446             {
    447                 return SCAN_CRS_SCAN_FAILED;
    448             }
    449 
    450             if ((pScanConcentrator->bUseSGParams) && (pScanConcentrator->clientScanParams[ SCAN_SCC_APP ].band == RADIO_BAND_2_4_GHZ))
    451             {
    452 				WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,("SG is pn && RADIO_BAND_2_4_GHZ \n"));
    453                 scanConcentrator_SGupdateScanParams(hScanCncn,&(pScanConcentrator->clientScanParams[ SCAN_SCC_APP ]));
    454             }
    455 
    456             /* mark that a scan request is in progress (to avoid client re-entrance if the scan fail) */
    457             pScanConcentrator->bInRequest = TRUE;
    458 
    459             /* mark the scan result as OK (until other status will replace it) */
    460             pScanConcentrator->scanResult[ SCAN_SCC_APP ] = SCAN_CRS_SCAN_COMPLETE_OK;
    461 
    462             /* send probe request template */
    463             if ( (SCAN_TYPE_NORMAL_ACTIVE == pScanParams->scanType) ||
    464                  (SCAN_TYPE_TRIGGERED_ACTIVE == pScanParams->scanType) )
    465             {
    466 
    467                 templateStruct.pTemplate = (UINT8 *)&probeReqTemplate;
    468                 templateStruct.templateType = PROBE_REQUEST_TEMPLATE;
    469                 buildProbeReqTemplate( pScanConcentrator->hSiteManager, &templateStruct,
    470 					&(pScanConcentrator->clientScanParams[ SCAN_SCC_APP ].desiredSsid),
    471 					  pScanConcentrator->clientScanParams[ SCAN_SCC_APP ].band);
    472                 whalCtrl_SetTemplate( pScanConcentrator->hHalCtrl, &templateStruct);
    473             }
    474 
    475             /* send a start scan event to the SM */
    476             scanConcentratorAppSM_SMEvent( hScanCncn,
    477                                            (scan_appSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_APP ]),
    478                                            APP_SCAN_EVENT_START_SCAN );
    479 
    480             /* mark that the scan request is no longer in progress */
    481             pScanConcentrator->bInRequest = FALSE;
    482 
    483             /* return scan result */
    484             if ( SCAN_CRS_SCAN_COMPLETE_OK == pScanConcentrator->scanResult[ SCAN_SCC_APP ] )
    485             {
    486                 return SCAN_CRS_SCAN_RUNNING;
    487             }
    488             else
    489             {
    490                 return pScanConcentrator->scanResult[ SCAN_SCC_APP ];
    491             }
    492         }
    493 /*        break; - unreachable */
    494 
    495     case SCAN_SCC_DRIVER:
    496         /* check that the driver state machine is in IDLE state
    497            (no more than one scan at a time per client is allowed)*/
    498         if ( DRV_SCAN_STATE_IDLE != pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ] )
    499         {
    500             return SCAN_CRS_SCAN_FAILED;
    501         }
    502         else
    503         {
    504             /* copy scan parameters to local buffer */
    505             os_memoryCopy( pScanConcentrator->hOS, &(pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ]),
    506                            pScanParams, sizeof(scan_Params_t) );
    507 
    508             if ((pScanConcentrator->bUseSGParams) && (pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].band == RADIO_BAND_2_4_GHZ))
    509             {
    510 				WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,("SG is pn && RADIO_BAND_2_4_GHZ \n"));
    511                 scanConcentrator_SGupdateScanParams(hScanCncn,&(pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ]));
    512             }
    513 
    514             /* mark that a scan request is in progress (to avoid client re-entrance if the scan fail) */
    515             pScanConcentrator->bInRequest = TRUE;
    516 
    517             /* mark the scan result as OK (until other status will replace it) */
    518             pScanConcentrator->scanResult[ SCAN_SCC_DRIVER ] = SCAN_CRS_SCAN_COMPLETE_OK;
    519 
    520             /* send probe request template */
    521             if ( (SCAN_TYPE_NORMAL_ACTIVE == pScanParams->scanType) ||
    522                  (SCAN_TYPE_TRIGGERED_ACTIVE == pScanParams->scanType) )
    523             {
    524 
    525                 templateStruct.pTemplate = (UINT8 *)&probeReqTemplate;
    526                 templateStruct.templateType = PROBE_REQUEST_TEMPLATE;
    527                 buildProbeReqTemplate( pScanConcentrator->hSiteManager, &templateStruct,
    528 					&(pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].desiredSsid),
    529 					  pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].band);
    530                 whalCtrl_SetTemplate( pScanConcentrator->hHalCtrl, &templateStruct);
    531             }
    532             /* send a start scan event to the SM */
    533             scanConcentratorDrvSM_SMEvent( hScanCncn,
    534                                            (scan_drvSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]),
    535                                            DRV_SCAN_EVENT_START_SCAN );
    536 
    537             /* mark that the scan request is no longer in progress */
    538             pScanConcentrator->bInRequest = FALSE;
    539 
    540             /* return scan result */
    541             if ( SCAN_CRS_SCAN_COMPLETE_OK == pScanConcentrator->scanResult[ SCAN_SCC_DRIVER ] )
    542             {
    543                 return SCAN_CRS_SCAN_RUNNING;
    544             }
    545             else
    546             {
    547                 return pScanConcentrator->scanResult[ SCAN_SCC_DRIVER ];
    548             }
    549         }
    550 /*        break; - unreachable */
    551 
    552     case SCAN_SCC_ROAMING_CONT:
    553         /* check that the continuous roaming state machine is in IDLE state
    554            (no more than one scan at a time per client is allowed)*/
    555         if ( CONT_SCAN_STATE_IDLE != pScanConcentrator->clientSMState[ SCAN_SCC_ROAMING_CONT ] )
    556         {
    557             return SCAN_CRS_SCAN_FAILED;
    558         }
    559         else
    560         {
    561             /* copy scan parameters to local buffer */
    562             os_memoryCopy( pScanConcentrator->hOS, &(pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_CONT ]),
    563                            pScanParams, sizeof(scan_Params_t) );
    564 
    565             if ((pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_CONT ].desiredSsid.len!=0) &&
    566                 ((pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_CONT ].scanType == SCAN_TYPE_NORMAL_ACTIVE) ||
    567                  (pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_CONT ].scanType == SCAN_TYPE_TRIGGERED_ACTIVE)))
    568             {
    569                 /* set the SSID of the current AP */
    570                 param.paramType = SITE_MGR_DESIRED_SSID_PARAM;
    571                 siteMgr_getParam( pScanConcentrator->hSiteManager, &param );
    572                 os_memoryCopy( pScanConcentrator->hOS,
    573                                &(pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_CONT ].desiredSsid),
    574                                &(param.content.siteMgrDesiredSSID),
    575                                sizeof(ssid_t) );
    576 
    577             }
    578             WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    579                                      ("CONT Scan: The scan SSID is %s\n", pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_CONT ].desiredSsid.ssidString) );
    580 
    581             /* ask the reg domain which channels are allowed for the requested scan type */
    582             scanConcentrator_verifyChannelsWithRegDomain( hScanCncn, &(pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_CONT ]) );
    583 
    584             /* if no channels are available for scan, return negative result */
    585             if ( 0 == pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_CONT ].numOfChannels )
    586             {
    587                 return SCAN_CRS_SCAN_FAILED;
    588             }
    589 
    590             if ((pScanConcentrator->bUseSGParams) && (pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_CONT ].band == RADIO_BAND_2_4_GHZ))
    591             {
    592 				WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,("SG is pn && RADIO_BAND_2_4_GHZ \n"));
    593                 scanConcentrator_SGupdateScanParams(hScanCncn,&(pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_CONT ]));
    594             }
    595 
    596             /* mark that a scan request is in progress (to avoid client re-entrance if the scan fail) */
    597             pScanConcentrator->bInRequest = TRUE;
    598 
    599             /* mark the scan result as OK (until other status will replace it) */
    600             pScanConcentrator->scanResult[ SCAN_SCC_ROAMING_CONT ] = SCAN_CRS_SCAN_COMPLETE_OK;
    601 
    602             /* send probe request template */
    603             if ( (SCAN_TYPE_NORMAL_ACTIVE == pScanParams->scanType) ||
    604                  (SCAN_TYPE_TRIGGERED_ACTIVE == pScanParams->scanType) )
    605             {
    606 
    607                 templateStruct.pTemplate = (UINT8 *)&probeReqTemplate;
    608                 templateStruct.templateType = PROBE_REQUEST_TEMPLATE;
    609                 buildProbeReqTemplate( pScanConcentrator->hSiteManager, &templateStruct,
    610 					&(pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_CONT ].desiredSsid),
    611 					  pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_CONT ].band);
    612                 whalCtrl_SetTemplate( pScanConcentrator->hHalCtrl, &templateStruct);
    613             }
    614 
    615             /* send a start scan event to the SM */
    616             scanConcentratorRoamingContSM_SMEvent( hScanCncn,
    617                                                    (scan_contSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_ROAMING_CONT ]),
    618                                                    CONT_SCAN_EVENT_START_SCAN );
    619 
    620             /* mark that the scan request is no longer in progress */
    621             pScanConcentrator->bInRequest = FALSE;
    622 
    623             /* return scan result */
    624             if ( SCAN_CRS_SCAN_COMPLETE_OK == pScanConcentrator->scanResult[ SCAN_SCC_ROAMING_CONT ] )
    625             {
    626                 return SCAN_CRS_SCAN_RUNNING;
    627             }
    628             else
    629             {
    630                 return pScanConcentrator->scanResult[ SCAN_SCC_ROAMING_CONT ];
    631             }
    632         }
    633 /*        break; - unreachable */
    634 
    635     case SCAN_SCC_ROAMING_IMMED:
    636         /* check that the immediate roaming state machine is in IDLE state
    637            (no more than one scan at a time per client is allowed)*/
    638         if ( IMMED_SCAN_STATE_IDLE != pScanConcentrator->clientSMState[ SCAN_SCC_ROAMING_IMMED ] )
    639         {
    640             return SCAN_CRS_SCAN_FAILED;
    641         }
    642         else
    643         {
    644 
    645             /* copy scan parameters to local buffer */
    646             os_memoryCopy( pScanConcentrator->hOS, &(pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_IMMED ]),
    647                      pScanParams, sizeof(scan_Params_t) );
    648 
    649             /* set the SSID of the current AP */
    650             param.paramType = SITE_MGR_DESIRED_SSID_PARAM;
    651             siteMgr_getParam( pScanConcentrator->hSiteManager, &param );
    652             os_memoryCopy( pScanConcentrator->hOS,
    653                    &(pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_IMMED ].desiredSsid),
    654                    &(param.content.siteMgrDesiredSSID),
    655                    sizeof(ssid_t) );
    656 
    657             /* ask the reg domain which channels are allowed for the requested scan type */
    658             scanConcentrator_verifyChannelsWithRegDomain( hScanCncn, &(pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_IMMED ]) );
    659 
    660             /* if no channels are available for scan, return negative result */
    661             if ( 0 == pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_IMMED ].numOfChannels )
    662             {
    663                 return SCAN_CRS_SCAN_FAILED;
    664             }
    665 
    666             if ((pScanConcentrator->bUseSGParams) && (pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_IMMED ].band == RADIO_BAND_2_4_GHZ))
    667             {
    668 				WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,("SG is pn && RADIO_BAND_2_4_GHZ \n"));
    669                 scanConcentrator_SGupdateScanParams(hScanCncn,&(pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_IMMED ]));
    670             }
    671 
    672             /* mark that a scan request is in progress (to avoid client re-entrance if the scan fail) */
    673             pScanConcentrator->bInRequest = TRUE;
    674 
    675             /* mark the scan result as OK (until other status will replace it) */
    676             pScanConcentrator->scanResult[ SCAN_SCC_ROAMING_IMMED ] = SCAN_CRS_SCAN_COMPLETE_OK;
    677 
    678             /* send probe request template */
    679             if ( (SCAN_TYPE_NORMAL_ACTIVE == pScanParams->scanType) ||
    680                  (SCAN_TYPE_TRIGGERED_ACTIVE == pScanParams->scanType) )
    681             {
    682 
    683                 templateStruct.pTemplate = (UINT8 *)&probeReqTemplate;
    684                 templateStruct.templateType = PROBE_REQUEST_TEMPLATE;
    685                 buildProbeReqTemplate( pScanConcentrator->hSiteManager, &templateStruct,
    686 					&(pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_IMMED ].desiredSsid),
    687 					  pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_IMMED ].band);
    688                 whalCtrl_SetTemplate( pScanConcentrator->hHalCtrl, &templateStruct);
    689             }
    690 
    691             /* send a start scan event to the SM */
    692             scanConcentratorRoamingImmedSM_SMEvent( hScanCncn,
    693                                                     (scan_immedSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_ROAMING_IMMED ]),
    694                                                     IMMED_SCAN_EVENT_START_SCAN );
    695 
    696             /* mark that the scan request is no longer in progress */
    697             pScanConcentrator->bInRequest = FALSE;
    698 
    699             /* return scan result */
    700             if ( SCAN_CRS_SCAN_COMPLETE_OK == pScanConcentrator->scanResult[ SCAN_SCC_ROAMING_IMMED ] )
    701             {
    702                 return SCAN_CRS_SCAN_RUNNING;
    703             }
    704             else
    705             {
    706                 return pScanConcentrator->scanResult[ SCAN_SCC_ROAMING_IMMED ];
    707             }
    708         }
    709 /*        break; - unreachable */
    710 
    711     default:
    712         WLAN_REPORT_ERROR( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    713                              ("Scan request from unknown client:%d\n", client) );
    714         return SCAN_CRS_SCAN_FAILED;
    715 /*        break; - unreachable */
    716 
    717     }
    718 
    719 /*    return SCAN_CRS_SCAN_RUNNING; - unreachable */
    720 }
    721 
    722 /**
    723  * \author Ronen Kalish\n
    724  * \date 02-Jan-2005\n
    725  * \brief Called by a client to stop a scan request in process. A client should ONLY stop its own request!
    726  *
    727  * Function Scope \e Public.\n
    728  * \param hScanCncn - handle to the scan concentrator object.\n
    729  * \param client - the client ID.\n
    730  */
    731 void scanConcentrator_stopScan( TI_HANDLE hScanCncn, scan_CncnClient_e client )
    732 {
    733     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
    734 
    735     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    736                              ("Received stop scan request from client %d\n", client) );
    737 
    738     /* act according to client */
    739     switch ( client )
    740     {
    741     case SCAN_SCC_APP:
    742         /* if no previous error has occurred, change the state to stopped */
    743         if ( SCAN_CRS_SCAN_COMPLETE_OK == pScanConcentrator->scanResult[ SCAN_SCC_APP ] )
    744         {
    745             pScanConcentrator->scanResult[ SCAN_SCC_APP ] = SCAN_CRS_SCAN_STOPPED;
    746             /* set the abort or stop flag (to identify when to exit driver mode (stop) and
    747             when not (abort due to higher priority client) */
    748             pScanConcentrator->bAbortOrStop = SCAN_CNCN_STOP;
    749         }
    750         else if (SCAN_CRS_SCAN_ABORTED_HIGHER_PRIORITY != pScanConcentrator->scanResult[ SCAN_SCC_APP ])
    751         {   /* In all scan failures, besides abort, indicate the flag as STOP */
    752             /* set the abort or stop flag (to identify when to exit driver mode (stop) and
    753             when not (abort due to higher priority client) */
    754             pScanConcentrator->bAbortOrStop = SCAN_CNCN_STOP;
    755         }
    756 
    757         /* send a stop scan event to the SM */
    758         scanConcentratorAppSM_SMEvent( hScanCncn,
    759                                        (scan_appSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_APP ]),
    760                                        APP_SCAN_EVENT_STOP_SCAN );
    761         break;
    762 
    763     case SCAN_SCC_DRIVER:
    764         /* if no previous error has occurred, change the state to stopped */
    765         if ( SCAN_CRS_SCAN_COMPLETE_OK == pScanConcentrator->scanResult[ SCAN_SCC_DRIVER ] )
    766         {
    767             pScanConcentrator->scanResult[ SCAN_SCC_DRIVER ] = SCAN_CRS_SCAN_STOPPED;
    768         }
    769 
    770         /* send a stop scan event to the SM */
    771         scanConcentratorDrvSM_SMEvent( hScanCncn,
    772                                        (scan_drvSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]),
    773                                        DRV_SCAN_EVENT_STOP_SCAN );
    774         break;
    775 
    776     case SCAN_SCC_ROAMING_CONT:
    777         /* if no previous error has occurred, change the state to stopped */
    778         if ( SCAN_CRS_SCAN_COMPLETE_OK == pScanConcentrator->scanResult[ SCAN_SCC_ROAMING_CONT ] )
    779         {
    780             pScanConcentrator->scanResult[ SCAN_SCC_ROAMING_CONT ] = SCAN_CRS_SCAN_STOPPED;
    781 
    782             /* set the abort or stop flag (to identify when to exit driver mode (stop) and
    783             when not (abort due to higher priority client) */
    784             pScanConcentrator->bAbortOrStop = SCAN_CNCN_STOP;
    785         }
    786         else if (SCAN_CRS_SCAN_ABORTED_HIGHER_PRIORITY != pScanConcentrator->scanResult[ SCAN_SCC_ROAMING_CONT ])
    787         {   /* In all scan failures, besides abort, indicate the flag as STOP */
    788             /* set the abort or stop flag (to identify when to exit driver mode (stop) and
    789             when not (abort due to higher priority client) */
    790             pScanConcentrator->bAbortOrStop = SCAN_CNCN_STOP;
    791         }
    792 
    793         /* send a stop scan event to the SM */
    794         scanConcentratorRoamingContSM_SMEvent( hScanCncn,
    795                                                (scan_contSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_ROAMING_CONT ]),
    796                                                CONT_SCAN_EVENT_STOP_SCAN );
    797         break;
    798 
    799     case SCAN_SCC_ROAMING_IMMED:
    800         /* if no previous error has occurred, change the state to stopped */
    801         if ( SCAN_CRS_SCAN_COMPLETE_OK == pScanConcentrator->scanResult[ SCAN_SCC_ROAMING_IMMED ] )
    802         {
    803             pScanConcentrator->scanResult[ SCAN_SCC_ROAMING_IMMED ] = SCAN_CRS_SCAN_STOPPED;
    804 
    805             /* set the abort or stop flag (to identify when to exit driver mode (stop) and
    806             when not (abort due to higher priority client) */
    807             pScanConcentrator->bAbortOrStop = SCAN_CNCN_STOP;
    808         }
    809         else if (SCAN_CRS_SCAN_ABORTED_HIGHER_PRIORITY != pScanConcentrator->scanResult[ SCAN_SCC_ROAMING_IMMED ])
    810         {   /* In all scan failures, besides abort, indicate the flag as STOP */
    811             /* set the abort or stop flag (to identify when to exit driver mode (stop) and
    812             when not (abort due to higher priority client) */
    813             pScanConcentrator->bAbortOrStop = SCAN_CNCN_STOP;
    814         }
    815 
    816         /* send a stop scan event to the SM */
    817         scanConcentratorRoamingImmedSM_SMEvent( hScanCncn,
    818                                                 (scan_immedSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_ROAMING_IMMED ]),
    819                                                 IMMED_SCAN_EVENT_STOP_SCAN );
    820         break;
    821 
    822     default:
    823         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    824                              ("Stop scan request with illegal client %d, aborting request.\n", client) );
    825         break;
    826     }
    827 }
    828 
    829 /**
    830  * \author Ronen Kalish\n
    831  * \date 02-Jan-2005\n
    832  * \brief Registers a scan result function for a specific client.
    833  *
    834  * Function Scope \e Public.\n
    835  * \param hScanCncn - handle to the scan concentrator object.\n
    836  * \param client - the client ID.\n
    837  * \param scanResultCBFunc - the function to use.\n
    838  * \param scanresultCBObj - the object to pass to the scan result CB function.\n
    839  */
    840 void scanConcentrator_registerScanResultCB( TI_HANDLE hScanCncn, scan_CncnClient_e client,
    841                                             scan_resultCB_t scanResultCBFunc, TI_HANDLE scanResultCBObj )
    842 {
    843     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
    844 
    845     /* save the function and object pointers */
    846     pScanConcentrator->scanResultCB[ client ] = scanResultCBFunc;
    847     pScanConcentrator->scanResultCBObj[ client ] = scanResultCBObj;
    848 }
    849 
    850 /**
    851  * \author Ronen Kalish\n
    852  * \date 02-Jan-2005\n
    853  * \brief Called by the scan SRV (after registration) to notify of a scan complete event.
    854  *
    855  * Function Scope \e Public.\n
    856  * \param hScanCncn - handle to the scan concentrator object.\n
    857  * \param SPSStatus - which channels were attempted (if SPS scan).\n
    858  * \param bTSFError - whether a TSF error occurred (if SPS scan).\n
    859  * \param  ScanStatus - return the status of the scan . \n
    860  */
    861 void scanConcentrator_scanCompleteNotificationCB( TI_HANDLE hScanCncn, UINT16 SPSStatus, BOOLEAN bTSFError , TI_STATUS ScanStatus , TI_STATUS PSMode )
    862 {
    863     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
    864 
    865      /* start built-in test timer */
    866     healthMonitor_resumePeriodicTest( pScanConcentrator->hHealthMonitor );
    867 
    868 #ifdef TI_DBG
    869     /* check that current running client is valid */
    870     if ( SCAN_SCC_NO_CLIENT == pScanConcentrator->currentRunningScanClient )
    871     {
    872         WLAN_REPORT_ERROR( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    873                            ("Scan complete called when current running client is invalid: %d\n",
    874                             pScanConcentrator->currentRunningScanClient) );
    875         return;
    876     }
    877 #endif
    878     /* send a scan complete event to the running client (according to its type) */
    879     switch ( pScanConcentrator->currentRunningScanClient )
    880     {
    881     case SCAN_SCC_APP:
    882         scanConcentratorAppSM_SMEvent( hScanCncn,
    883                                        (scan_appSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_APP ]),
    884                                        APP_SCAN_EVENT_SCAN_COMPLETE );
    885         break;
    886 
    887     case SCAN_SCC_DRIVER:
    888         scanConcentratorDrvSM_SMEvent( hScanCncn,
    889                                        (scan_drvSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]),
    890                                        scanConcentrator_getNextDriverEvent( hScanCncn ) );
    891         break;
    892 
    893     case SCAN_SCC_ROAMING_CONT:
    894         /* copy the SPS scan result (in case this was an SPS scan) */
    895         pScanConcentrator->SPSScanResult = SPSStatus;
    896 
    897         /* if A TSF error occurred (for non-SPS scans this value is always FALSE!), and no previous error occurred,
    898            mark this error */
    899         if ( (SCAN_CRS_SCAN_COMPLETE_OK ==
    900                 pScanConcentrator->scanResult[ pScanConcentrator->currentRunningScanClient ]) &&
    901               (TRUE == bTSFError) )
    902         {
    903             pScanConcentrator->scanResult[ pScanConcentrator->currentRunningScanClient ] = SCAN_CRS_TSF_ERROR;
    904         }
    905         scanConcentratorRoamingContSM_SMEvent( hScanCncn,
    906                                                (scan_contSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_ROAMING_CONT ]),
    907                                                CONT_SCAN_EVENT_SCAN_COMPLETE );
    908         break;
    909 
    910     case SCAN_SCC_ROAMING_IMMED:
    911         scanConcentratorRoamingImmedSM_SMEvent( hScanCncn,
    912                                                 (scan_immedSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_ROAMING_IMMED ]),
    913                                                 IMMED_SCAN_EVENT_SCAN_COMPLETE );
    914         break;
    915 
    916     default:
    917         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    918                              ("Scan complete notification with illegal client %d, aborting request.\n", pScanConcentrator->currentRunningScanClient) );
    919         break;
    920     }
    921 }
    922 
    923 /**
    924  * \author Ronen Kalish\n
    925  * \date 02-Jan-2005\n
    926  * \brief Called by the MLME parser to pass information received on a beacon or probe response.
    927  *
    928  * Function Scope \e Public.\n
    929  * \param hScanCncn - handle to the scan concentrator object.\n
    930  * \param bssid - a pointer to the address of the AP sending this frame.\n
    931  * \param frameInfo - the IE in the frame.\n
    932  * \param pRxAttr - a pointer to TNET RX attributes struct.\n
    933  * \param buffer - a pointer to the frame body.\n
    934  * \param byfferLength - the frame body length.\n
    935  */
    936 void scanConcentrator_mlmeResultCB( TI_HANDLE hScanCncn, macAddress_t* bssid, mlmeFrameInfo_t* frameInfo,
    937                                     Rx_attr_t* pRxAttr, UINT8* buffer, UINT16 bufferLength )
    938 {
    939     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
    940     paramInfo_t param;
    941     scan_frameInfo_t scanFrameInfo;
    942 
    943     /* verify that there is a running client (in case the result arrived after the scan complete event) */
    944     switch (pScanConcentrator->currentRunningScanClient)
    945     {
    946     case SCAN_SCC_APP:
    947         if ( APP_SCAN_STATE_IDLE == pScanConcentrator->clientSMState[ SCAN_SCC_APP ] )
    948         {
    949             return;
    950         }
    951         break;
    952 
    953     case SCAN_SCC_DRIVER:
    954         if ( DRV_SCAN_STATE_IDLE == pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ] )
    955         {
    956             return;
    957         }
    958         break;
    959 
    960     case SCAN_SCC_ROAMING_CONT:
    961         if ( CONT_SCAN_STATE_IDLE == pScanConcentrator->clientSMState[ SCAN_SCC_ROAMING_CONT ] )
    962         {
    963             return;
    964         }
    965         /* check that the SSID IE exists in the frame received */
    966         if (frameInfo->content.iePacket.pSsid==NULL)
    967         {
    968             /* Discard sites with no SID IE */
    969             return;
    970         }
    971         /* check that scan results are not from current BSS */
    972         param.paramType = CTRL_DATA_CURRENT_BSSID_PARAM;
    973         ctrlData_getParam( pScanConcentrator->hCtrlData, &param );
    974         if (( 0 == os_memoryCompare( pScanConcentrator->hOS,
    975                                     (void *)&(bssid->addr[ 0 ]),
    976                                     (void *)&(param.content.ctrlDataCurrentBSSID.addr[ 0 ]),
    977                                     MAC_ADDR_LEN ) ) ||
    978             (( os_memoryCompare( pScanConcentrator->hOS,
    979                                 (PUINT8)frameInfo->content.iePacket.pSsid->serviceSetId,
    980                                 (PUINT8)pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_CONT ].desiredSsid.ssidString,
    981                                     pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_CONT ].desiredSsid.len )) &&
    982              pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_CONT ].scanType != SCAN_TYPE_SPS) )
    983         {
    984             /* reply from current site - discard it (by returning w/o notifying the scan manager */
    985             /* Also discard sites with different SSID than the desired */
    986             WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    987                                      ("Cont scan: discarding frame from SSID: %s, BSSID: %2x:%2x:%2x:%2x:%2x:%2x, because SSID different from desired or from current AP!\n",
    988                                       frameInfo->content.iePacket.pSsid->serviceSetId, bssid->addr[ 0 ],
    989                                       bssid->addr[ 1 ], bssid->addr[ 2 ], bssid->addr[ 3 ],
    990                                       bssid->addr[ 4 ], bssid->addr[ 5 ]) );
    991             return;
    992         }
    993 
    994         break;
    995 
    996     case SCAN_SCC_ROAMING_IMMED:
    997         if ( IMMED_SCAN_STATE_IDLE == pScanConcentrator->clientSMState[ SCAN_SCC_ROAMING_IMMED ] )
    998         {
    999             return;
   1000         }
   1001         /* check that the SSID IE exists in the frame received */
   1002         if (frameInfo->content.iePacket.pSsid==NULL)
   1003         {
   1004             /* Discard sites with no SID IE */
   1005             return;
   1006         }
   1007         /* check that scan results are not from current BSS */
   1008         param.paramType = CTRL_DATA_CURRENT_BSSID_PARAM;
   1009         ctrlData_getParam( pScanConcentrator->hCtrlData, &param );
   1010         if (( 0 == os_memoryCompare( pScanConcentrator->hOS,
   1011                                     (PUINT8)&(bssid->addr[ 0 ]),
   1012                                     (PUINT8)&(param.content.ctrlDataCurrentBSSID.addr[ 0 ]),
   1013                                     MAC_ADDR_LEN ) ) ||
   1014             ( os_memoryCompare( pScanConcentrator->hOS,
   1015                                 (PUINT8)frameInfo->content.iePacket.pSsid->serviceSetId,
   1016                                 (PUINT8)pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_IMMED ].desiredSsid.ssidString,
   1017                                     pScanConcentrator->clientScanParams[ SCAN_SCC_ROAMING_IMMED ].desiredSsid.len )))
   1018 
   1019         {
   1020             /* reply from current site - discard it (by returning w/o notifying the scan manager */
   1021             /* Also discard sites with different SSID than the desired */
   1022             WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
   1023                                      ("Immed scan: discarding frame from SSID: %s, BSSID: %2x:%2x:%2x:%2x:%2x:%2x, because SSID different from desired or from current AP!\n",
   1024                                       frameInfo->content.iePacket.pSsid->serviceSetId, bssid->addr[ 0 ],
   1025                                       bssid->addr[ 1 ], bssid->addr[ 2 ], bssid->addr[ 3 ],
   1026                                       bssid->addr[ 4 ], bssid->addr[ 5 ]) );
   1027             return;
   1028         }
   1029         break;
   1030 
   1031     default:
   1032         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
   1033                              ("Scan result with illegal client %d, aborting request.\n", pScanConcentrator->currentRunningScanClient) );
   1034         return;
   1035 /*        break; - unreachable */
   1036     }
   1037 
   1038     /* build the scan frame info object */
   1039     scanFrameInfo.bssId = bssid;
   1040     scanFrameInfo.band = (radioBand_e)pRxAttr->band;
   1041     scanFrameInfo.channel = pRxAttr->channel;
   1042     scanFrameInfo.parsedIEs = frameInfo;
   1043     scanFrameInfo.rate = pRxAttr->Rate;
   1044     scanFrameInfo.rssi = pRxAttr->Rssi;
   1045     scanFrameInfo.staTSF = pRxAttr->TimeStamp;
   1046     scanFrameInfo.buffer = buffer;
   1047     scanFrameInfo.bufferLength = bufferLength;
   1048 
   1049     /* call the client result CB, according to the running client type */
   1050     if ( NULL != pScanConcentrator->scanResultCB[ pScanConcentrator->currentRunningScanClient ] )
   1051     {
   1052         pScanConcentrator->scanResultCB[ pScanConcentrator->currentRunningScanClient ](
   1053             pScanConcentrator->scanResultCBObj[ pScanConcentrator->currentRunningScanClient ],
   1054             SCAN_CRS_RECEIVED_FRAME,
   1055             &scanFrameInfo,
   1056             0xffff ); /* SPS status is only valid on SPS scan complete */
   1057     }
   1058 }
   1059 
   1060 /**
   1061  * \author Ronen Kalish\n
   1062  * \date 02-Jan-2005\n
   1063  * \brief Called by the SCR (after registration) to notify the scan concentrator of a status change
   1064  * \brief for the immediate scan for roaming client.
   1065  *
   1066  * Function Scope \e Public.\n
   1067  * \param hScanCncn - handle to the scan concentrator object.\n
   1068  * \param requestStatus - the continuous scan for roaming client status.\n
   1069  */
   1070 void scanConcentrator_scrRoamingImmedCB( TI_HANDLE hScanCncn, scr_clientRequestStatus_e requestStatus,
   1071                                          scr_pendReason_e pendReason )
   1072 {
   1073     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
   1074 
   1075     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
   1076                              ("Immed. romaing CB called by SCR. Status is: %d, pend reason: %d.\n",
   1077                               requestStatus, pendReason) );
   1078 
   1079     /* act according to the request staus */
   1080     switch ( requestStatus )
   1081     {
   1082     case SCR_CRS_RUN:
   1083         /* send an SCR run event to the SM */
   1084         scanConcentratorRoamingImmedSM_SMEvent( hScanCncn,
   1085                                                 (scan_immedSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_ROAMING_IMMED ]),
   1086                                                 IMMED_SCAN_EVENT_SCR_RUN );
   1087         break;
   1088 
   1089     case SCR_CRS_PEND:
   1090         /* if pending reason has changed to different group - send a reject event
   1091            (should only happen when pending) */
   1092         if ( SCR_PR_DIFFERENT_GROUP_RUNNING == pendReason )
   1093         {
   1094             /* send an SCR reject event to the SM - would not scan when not performing roaming */
   1095             pScanConcentrator->scanResult[ SCAN_SCC_ROAMING_IMMED ] = SCAN_CRS_SCAN_FAILED;
   1096             scanConcentratorRoamingImmedSM_SMEvent( hScanCncn,
   1097                                                     (scan_immedSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_ROAMING_IMMED ]),
   1098                                                     IMMED_SCAN_EVENT_SCR_REJECT );
   1099         }
   1100         else
   1101         {
   1102             /* send an SCR pend event to the SM */
   1103             scanConcentratorRoamingImmedSM_SMEvent( hScanCncn,
   1104                                                     (scan_immedSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_ROAMING_IMMED ]),
   1105                                                     IMMED_SCAN_EVENT_SCR_PEND );
   1106         }
   1107         break;
   1108 
   1109     case SCR_CRS_FW_RESET:
   1110         /* if no previous error has occurred, change the state to FW reset */
   1111         if ( SCAN_CRS_SCAN_COMPLETE_OK == pScanConcentrator->scanResult[ SCAN_SCC_ROAMING_IMMED ] )
   1112         {
   1113             pScanConcentrator->scanResult[ SCAN_SCC_ROAMING_IMMED ] = SCAN_CRS_SCAN_ABORTED_FW_RESET;
   1114         }
   1115 
   1116          /* start built-in test timer */
   1117         healthMonitor_resumePeriodicTest( pScanConcentrator->hHealthMonitor );
   1118 
   1119         /* send a FW reset event to the SM */
   1120         scanConcentratorRoamingImmedSM_SMEvent( hScanCncn,
   1121                                                 (scan_immedSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_ROAMING_IMMED ]),
   1122                                                 IMMED_SCAN_EVENT_FW_RESET );
   1123         break;
   1124 
   1125     case SCR_CRS_ABORT:
   1126         /* This should never happen, report error */
   1127     default:
   1128         WLAN_REPORT_ERROR( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
   1129                              ("Illegal SCR request status: %d.\n", requestStatus) );
   1130         break;
   1131     }
   1132 }
   1133 
   1134 /**
   1135  * \author Ronen Kalish\n
   1136  * \date 02-Jan-2005\n
   1137  * \brief Called by the SCR (after registration) to notify the scan concentrator of a status change
   1138  * \brief for the continuous scan for roaming client.
   1139  *
   1140  * Function Scope \e Public.\n
   1141  * \param hScanCncn - handle to the scan concentrator object.\n
   1142  * \param requestStatus - the continuous scan for roaming client status.\n
   1143  */
   1144 void scanConcentrator_scrRoamingContCB( TI_HANDLE hScanCncn, scr_clientRequestStatus_e requestStatus,
   1145                                         scr_pendReason_e pendReason )
   1146 {
   1147     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
   1148 
   1149     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
   1150                              ("Cont. romaing CB called by SCR. Status is: %d, pend reason: %d.\n",
   1151                               requestStatus, pendReason) );
   1152 
   1153     /* act according to the request staus */
   1154     switch ( requestStatus )
   1155     {
   1156     case SCR_CRS_RUN:
   1157         /* send an SCR run event to the SM */
   1158         scanConcentratorRoamingContSM_SMEvent( hScanCncn,
   1159                                                (scan_contSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_ROAMING_CONT ]),
   1160                                                CONT_SCAN_EVENT_SCR_RUN );
   1161         break;
   1162 
   1163     case SCR_CRS_PEND:
   1164         /* if pending reason has changed to different group - send a reject event
   1165            (should only happen when pending) */
   1166         if ( SCR_PR_DIFFERENT_GROUP_RUNNING == pendReason )
   1167         {
   1168             pScanConcentrator->scanResult[ SCAN_SCC_ROAMING_CONT ] = SCAN_CRS_SCAN_FAILED;
   1169             /* send an SCR reject event to the SM - would not scan when not connected */
   1170         scanConcentratorRoamingContSM_SMEvent( hScanCncn,
   1171                                                (scan_contSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_ROAMING_CONT ]),
   1172                                                CONT_SCAN_EVENT_SCR_REJECT );
   1173         }
   1174         else
   1175         {
   1176             /* send an SCR pend event to the SM */
   1177             scanConcentratorRoamingContSM_SMEvent( hScanCncn,
   1178                                                    (scan_contSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_ROAMING_CONT ]),
   1179                                                    CONT_SCAN_EVENT_SCR_PEND );
   1180         }
   1181         break;
   1182 
   1183     case SCR_CRS_FW_RESET:
   1184         /* if no previous error has occurred, change the state to FW reset */
   1185         if ( SCAN_CRS_SCAN_COMPLETE_OK == pScanConcentrator->scanResult[ SCAN_SCC_ROAMING_CONT ] )
   1186         {
   1187             pScanConcentrator->scanResult[ SCAN_SCC_ROAMING_CONT ] = SCAN_CRS_SCAN_ABORTED_FW_RESET;
   1188         }
   1189 
   1190          /* start built-in test timer */
   1191         healthMonitor_resumePeriodicTest( pScanConcentrator->hHealthMonitor );
   1192 
   1193         /* send a FW reset event to the SM */
   1194         scanConcentratorRoamingContSM_SMEvent( hScanCncn,
   1195                                                (scan_contSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_ROAMING_CONT ]),
   1196                                                CONT_SCAN_EVENT_FW_RESET );
   1197         break;
   1198 
   1199     case SCR_CRS_ABORT:
   1200         /* set the abort or stop flag (to identify when to exit driver mode (stop) and
   1201            when not (abort due to higher priority client) */
   1202 
   1203         pScanConcentrator->bAbortOrStop = SCAN_CNCN_ABORT;
   1204 
   1205         /* if no previous error has occurred, change the state to abort (according to reason) */
   1206         if ( SCAN_CRS_SCAN_COMPLETE_OK == pScanConcentrator->scanResult[ SCAN_SCC_ROAMING_CONT ] )
   1207         {
   1208             pScanConcentrator->scanResult[ SCAN_SCC_ROAMING_CONT ] = SCAN_CRS_SCAN_ABORTED_HIGHER_PRIORITY;
   1209         }
   1210 
   1211         /* send an abort scan event to the SM */
   1212         scanConcentratorRoamingContSM_SMEvent( hScanCncn,
   1213                                                (scan_contSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_ROAMING_CONT ]),
   1214                                                CONT_SCAN_EVENT_ABORT_SCAN );
   1215         break;
   1216 
   1217     default:
   1218         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
   1219                              ("Illegal SCR request status: %d.\n", requestStatus) );
   1220         break;
   1221     }
   1222 }
   1223 
   1224 /**
   1225  * \author Ronen Kalish\n
   1226  * \date 02-Jan-2005\n
   1227  * \brief Called by the SCR (after registration) to notify the scan concentrator of a status change
   1228  * \brief for the Application scan client.
   1229  *
   1230  * Function Scope \e Public.\n
   1231  * \param hScanCncn - handle to the scan concentrator object.\n
   1232  * \param requestStatus - the application scan status.\n
   1233  * \param pendReason - the reason for pend status, if the status is pend.\n
   1234  */
   1235 void scanConcentrator_scrAppCB( TI_HANDLE hScanCncn, scr_clientRequestStatus_e requestStatus,
   1236                                 scr_pendReason_e pendReason )
   1237 {
   1238     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
   1239 
   1240     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
   1241                              ("App. CB called by SCR. Status is: %d, pend reason: %d.\n",
   1242                               requestStatus, pendReason) );
   1243 
   1244     /* act according to the request staus */
   1245     switch ( requestStatus )
   1246     {
   1247     /* Note: pend is not handled because application scan cancel its scan request when it receives pend
   1248        as the SCR request result, and thus it is assumed that the application scan request will never be
   1249        pending */
   1250 
   1251     case SCR_CRS_RUN:
   1252         /* send an SCR run event to the SM */
   1253         scanConcentratorAppSM_SMEvent( hScanCncn,
   1254                                        (scan_appSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_APP ]),
   1255                                        APP_SCAN_EVENT_SCR_RUN );
   1256         break;
   1257 
   1258     case SCR_CRS_FW_RESET:
   1259         /* if no previous error has occurred, change the state to FW reset */
   1260         if ( SCAN_CRS_SCAN_COMPLETE_OK == pScanConcentrator->scanResult[ SCAN_SCC_APP ] )
   1261         {
   1262             pScanConcentrator->scanResult[ SCAN_SCC_APP ] = SCAN_CRS_SCAN_ABORTED_FW_RESET;
   1263         }
   1264 
   1265          /* start built-in test timer */
   1266         healthMonitor_resumePeriodicTest( pScanConcentrator->hHealthMonitor );
   1267 
   1268         /* send a FW reset event to the SM */
   1269         scanConcentratorAppSM_SMEvent( hScanCncn,
   1270                                        (scan_appSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_APP ]),
   1271                                        APP_SCAN_EVENT_FW_RESET );
   1272         break;
   1273 
   1274     case SCR_CRS_ABORT:
   1275         /* set the abort or stop flag (to identify when to exit driver mode (stop) and
   1276            when not (abort due to higher priority client) */
   1277 
   1278         pScanConcentrator->bAbortOrStop = SCAN_CNCN_ABORT;
   1279 
   1280         /* if no previous error has occurred, change the state to abort (according to reason) */
   1281         if ( SCAN_CRS_SCAN_COMPLETE_OK == pScanConcentrator->scanResult[ SCAN_SCC_APP ] )
   1282         {
   1283             pScanConcentrator->scanResult[ SCAN_SCC_APP ] = SCAN_CRS_SCAN_ABORTED_HIGHER_PRIORITY;
   1284         }
   1285 
   1286         /* send an abort scan event to the SM */
   1287         scanConcentratorAppSM_SMEvent( hScanCncn,
   1288                                        (scan_appSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_APP ]),
   1289                                        APP_SCAN_EVENT_ABORT_SCAN );
   1290         break;
   1291 
   1292     default:
   1293         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
   1294                              ("Illegal SCR request status: %d.\n", requestStatus) );
   1295         break;
   1296     }
   1297 }
   1298 
   1299 /**
   1300  * \author Ronen Kalish\n
   1301  * \date 02-Jan-2005\n
   1302  * \brief Called by the SCR (after registration) to notify the scan concentrator of a status change
   1303  * \brief for the driver scan client.
   1304  *
   1305  * Function Scope \e Public.\n
   1306  * \param hScanCncn - handle to the scan concentrator object.\n
   1307  * \param requestStatus - the driver scan status.\n
   1308  * \param pendReason - the reason for pend status, if the status is pend.\n
   1309  */
   1310 void scanConcentrator_scrDriverCB( TI_HANDLE hScanCncn, scr_clientRequestStatus_e requestStatus,
   1311                                    scr_pendReason_e pendReason )
   1312 {
   1313     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
   1314 
   1315     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
   1316                              ("Driver CB called by SCR. Status is: %d, pend reason: %d.\n",
   1317                               requestStatus, pendReason) );
   1318 
   1319     /* act according to the request staus */
   1320     switch ( requestStatus )
   1321     {
   1322     case SCR_CRS_RUN:
   1323         /* send the next event to the SM */
   1324         scanConcentratorDrvSM_SMEvent( hScanCncn,
   1325                                        (scan_drvSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]),
   1326                                        scanConcentrator_getNextDriverEvent( hScanCncn ) );
   1327         break;
   1328 
   1329     case SCR_CRS_PEND:
   1330         /* a pend event should only be sent when the SM is waiting for the SCR */
   1331         if ( pendReason == SCR_PR_DIFFERENT_GROUP_RUNNING )
   1332         {
   1333             /* send a reject event - should not perform scan if not in connecting mode */
   1334             pScanConcentrator->scanResult[ SCAN_SCC_DRIVER ] = SCAN_CRS_SCAN_FAILED;
   1335         scanConcentratorDrvSM_SMEvent( hScanCncn,
   1336                                        (scan_drvSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]),
   1337                                        DRV_SCAN_EVENT_SCR_REJECT );
   1338         }
   1339         else
   1340         {
   1341             /* send a pend event */
   1342             scanConcentratorDrvSM_SMEvent( hScanCncn,
   1343                                            (scan_drvSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]),
   1344                                            DRV_SCAN_EVENT_SCR_PEND );
   1345         }
   1346         break;
   1347 
   1348     case SCR_CRS_FW_RESET:
   1349         /* if no previous error has occurred, change the state to FW reset */
   1350         if ( SCAN_CRS_SCAN_COMPLETE_OK == pScanConcentrator->scanResult[ SCAN_SCC_DRIVER ] )
   1351         {
   1352             pScanConcentrator->scanResult[ SCAN_SCC_DRIVER ] = SCAN_CRS_SCAN_ABORTED_FW_RESET;
   1353         }
   1354 
   1355         /* start built-in test timer */
   1356         healthMonitor_resumePeriodicTest( pScanConcentrator->hHealthMonitor );
   1357 
   1358         /* send a FW reset event to the SM */
   1359         scanConcentratorDrvSM_SMEvent( hScanCncn,
   1360                                        (scan_drvSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]),
   1361                                        DRV_SCAN_EVENT_FW_RESET );
   1362         break;
   1363 
   1364     case SCR_CRS_ABORT:
   1365     /* This should never happen, report error */
   1366     default:
   1367         WLAN_REPORT_ERROR( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
   1368                              ("Illegal SCR request status: %d.\n", requestStatus) );
   1369         break;
   1370     }
   1371 }
   1372 
   1373 /**
   1374  * \author Ronen Kalish\n
   1375  * \date 09-Jan-2005\n
   1376  * \brief Verifies that specified channels are allowed for the specified scan type, and removes those that are not.\n
   1377  *
   1378  * Function Scope \e Private.\n
   1379  * \param hScanCncn - handle to the scan concentrator object.\n
   1380  * \param pScanParams - a pointer to the structure holding the scan params (inc. channels and scan type).\n
   1381  */
   1382 void scanConcentrator_verifyChannelsWithRegDomain( TI_HANDLE hScanCncn, scan_Params_t* pScanParams )
   1383 {
   1384     paramInfo_t     param;
   1385     UINT8           i,j,k;
   1386     UINT8           tempChannelList[ SCAN_MAX_NUM_OF_NORMAL_CHANNELS_PER_COMMAND ];
   1387     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
   1388 
   1389     /* if no channels were given by the user, get all channels from reg domain */
   1390     if ( 0 == pScanParams->numOfChannels )
   1391     {
   1392         /* SPS cannot be performed when the user does not define the channels! */
   1393         if ( SCAN_TYPE_SPS != pScanParams->scanType )
   1394         {
   1395             UINT validChannelsCnt=0;
   1396 
   1397             /* extract the channel list (channel numbers) from the bitmap */
   1398             i = SCAN_MAX_NUM_OF_NORMAL_CHANNELS_PER_COMMAND;
   1399             /*scanConcentrator_ExtractBitmapToList( pScanParams->band, &(tmpChannelBitmap[0]), &(tempChannelList[0]), &i );*/
   1400 
   1401             param.paramType = REGULATORY_DOMAIN_ALL_SUPPORTED_CHANNELS;
   1402             param.content.siteMgrRadioBand = pScanParams->band;
   1403             /*param.content.supportedChannels.listOfChannels = tempChannelList;*/
   1404             regulatoryDomain_getParam( pScanConcentrator->hRegulatoryDomain, &param );
   1405             i = param.content.supportedChannels.sizeOfList;
   1406             if (i > SCAN_MAX_NUM_OF_NORMAL_CHANNELS_PER_COMMAND)
   1407             {
   1408                 i = SCAN_MAX_NUM_OF_NORMAL_CHANNELS_PER_COMMAND;
   1409             }
   1410             os_memoryCopy(pScanConcentrator->hOS, tempChannelList, param.content.supportedChannels.listOfChannels, i);
   1411             /* add default values to channels extracted from the bitmap */
   1412             for ( j = 0; j < i; j++ )
   1413             {
   1414 
   1415                 param.paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES;
   1416                 param.content.channelCapabilityReq.band = pScanParams->band;
   1417                 if ( (pScanParams->scanType == SCAN_TYPE_NORMAL_PASSIVE) ||
   1418                      (pScanParams->scanType == SCAN_TYPE_TRIGGERED_PASSIVE) ||
   1419                      (pScanParams->scanType == SCAN_TYPE_SPS) )
   1420                 {
   1421                     param.content.channelCapabilityReq.scanOption = PASSIVE_SCANNING;
   1422                 }
   1423                 else
   1424                 {
   1425                     param.content.channelCapabilityReq.scanOption = ACTIVE_SCANNING;
   1426                 }
   1427                 param.content.channelCapabilityReq.channelNum = tempChannelList[ j ];
   1428                 regulatoryDomain_getParam( pScanConcentrator->hRegulatoryDomain, &param );
   1429                 if (param.content.channelCapabilityRet.channelValidity == TRUE)
   1430                 {
   1431                     /* add the channel ID */
   1432                     pScanParams->channelEntry[ j ].normalChannelEntry.channel = tempChannelList[ j ];
   1433                     /* add other default parameters */
   1434                     pScanParams->channelEntry[ j ].normalChannelEntry.minChannelDwellTime =
   1435                         SCAN_DEFAULT_MIN_CHANNEL_DWELL_TIME;
   1436                     pScanParams->channelEntry[ j ].normalChannelEntry.maxChannelDwellTime =
   1437                         SCAN_DEFAULT_MAX_CHANNEL_DWELL_TIME;
   1438                     pScanParams->channelEntry[ j ].normalChannelEntry.earlyTerminationEvent =
   1439                         SCAN_DEFAULT_EARLY_TERMINATION_EVENT;
   1440                     pScanParams->channelEntry[ j ].normalChannelEntry.ETMaxNumOfAPframes =
   1441                         SCAN_DEFAULT_EARLY_TERMINATION_NUM_OF_FRAMES;
   1442                     pScanParams->channelEntry[ j ].normalChannelEntry.txPowerDbm = param.content.channelCapabilityRet.maxTxPowerDbm;
   1443 
   1444                     /* Fill broadcast BSSID */
   1445                     for ( k = 0; k < 6; k++ )
   1446                     {
   1447                         pScanParams->channelEntry[ j ].normalChannelEntry.bssId.addr[ k ] = 0xff;
   1448                     }
   1449 
   1450                     validChannelsCnt++;
   1451                 }
   1452             }
   1453             pScanParams->numOfChannels = validChannelsCnt;
   1454         }
   1455     }
   1456     /* channels were supplied by user - must verify that all of them are allowed */
   1457     else
   1458     {
   1459         /* check channels */
   1460         for ( i = 0; i < pScanParams->numOfChannels; )
   1461         { /* Note that i is only increased when channel is valid - if channel is invalid, another
   1462              channel is copied in its place, and thus the same index should be checked again. However,
   1463              since the number of channels is decreased, the loop end condition is getting nearer! */
   1464 
   1465             param.paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES;
   1466             param.content.channelCapabilityReq.band = pScanParams->band;
   1467             if ( (pScanParams->scanType == SCAN_TYPE_NORMAL_PASSIVE) ||
   1468                  (pScanParams->scanType == SCAN_TYPE_TRIGGERED_PASSIVE) ||
   1469                  (pScanParams->scanType == SCAN_TYPE_SPS) )
   1470             {
   1471                 param.content.channelCapabilityReq.scanOption = PASSIVE_SCANNING;
   1472             }
   1473             else
   1474             {
   1475                 param.content.channelCapabilityReq.scanOption = ACTIVE_SCANNING;
   1476             }
   1477 
   1478             /* SPS scan */
   1479             if ( SCAN_TYPE_SPS == pScanParams->scanType )
   1480             {
   1481                 param.content.channelCapabilityReq.channelNum = pScanParams->channelEntry[ i ].SPSChannelEntry.channel;
   1482                 regulatoryDomain_getParam( pScanConcentrator->hRegulatoryDomain, &param );
   1483                 if (!param.content.channelCapabilityRet.channelValidity)
   1484                 {   /* channel not allowed - copy the rest of the channel in its place */
   1485                     os_memoryCopy( pScanConcentrator->hOS, &(pScanParams->channelEntry[ i ]),
   1486                                    &(pScanParams->channelEntry[ i + 1 ]), sizeof(scan_SPSChannelEntry_t) *
   1487                                                                           (pScanParams->numOfChannels - i - 1) );
   1488                     pScanParams->numOfChannels--;
   1489                 }
   1490                 else
   1491                 {
   1492                     i += 1;
   1493                 }
   1494 
   1495             }
   1496             /* all other scan types */
   1497             else
   1498             {
   1499                 param.content.channelCapabilityReq.channelNum = pScanParams->channelEntry[ i ].normalChannelEntry.channel;
   1500                 regulatoryDomain_getParam( pScanConcentrator->hRegulatoryDomain, &param );
   1501                 if (!param.content.channelCapabilityRet.channelValidity)
   1502                 {   /* channel not allowed - copy the rest of the channel in its place */
   1503                     os_memoryCopy( pScanConcentrator->hOS, &(pScanParams->channelEntry[ i ]),
   1504                                    &(pScanParams->channelEntry[ i + 1 ]), sizeof(scan_normalChannelEntry_t) *
   1505                                                                           (pScanParams->numOfChannels - i - 1) );
   1506                     pScanParams->numOfChannels--;
   1507                 }
   1508                 else
   1509                 {
   1510                     pScanParams->channelEntry[i].normalChannelEntry.txPowerDbm =
   1511 							MIN( param.content.channelCapabilityRet.maxTxPowerDbm,
   1512 								pScanParams->channelEntry[i].normalChannelEntry.txPowerDbm );
   1513 
   1514                     i += 1;
   1515                 }
   1516             }
   1517         }
   1518     }
   1519 }
   1520 
   1521 /**
   1522  * \author Yuval Adler\n
   1523  * \date 26-Jan-2006\n
   1524  * \brief enable/disable the use of SG parameters , and update parameters of next scans
   1525  *      requests for minDwellTime,MaxDwellTime,numProbeReq  .\n
   1526  *          this function is called when SG is enabled or disabled from the SoftGemini module
   1527  *          The compensation is needed since BT Activity holds the antenna and over-ride Scan activity
   1528  *
   1529  * Function Scope \e Private.\n
   1530  * \param hScanCncn - handle to the scan concentrator object.\n
   1531  * \param bUseSGParams - whether to use the new parameters (TRUE when SG is enabled)
   1532  * \param probeReqNumber -
   1533  * \param SGcompensationMaxTime - max value from which we won't increase dwelling time
   1534  * \param SGcompensationPercent - increasing dwell time in that percentage
   1535  */
   1536 void scanConcentrator_SGconfigureScanParams( TI_HANDLE hScanCncn, BOOL bUseSGParams ,
   1537                                              UINT8 probeReqNumber , UINT32 SGcompensationMaxTime,
   1538                                              UINT32 SGcompensationPercent)
   1539 {
   1540     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
   1541 
   1542     pScanConcentrator->bUseSGParams            = bUseSGParams;
   1543     pScanConcentrator->SGnumOfProbeRequest     = probeReqNumber;
   1544     pScanConcentrator->SGcompensationMaxTime   = SGcompensationMaxTime;
   1545     pScanConcentrator->SGcompensationPercent   = SGcompensationPercent;
   1546 
   1547     WLAN_REPORT_INFORMATION(pScanConcentrator->hReport,SCAN_CNCN_MODULE_LOG,
   1548             ("%s: bUseSGParams = %d, numOfProbeRequest = %d, compensationMaxTime = %d, SGcompensationPercent = %d\n "
   1549             ,__FUNCTION__,pScanConcentrator->bUseSGParams,pScanConcentrator->SGnumOfProbeRequest,
   1550             pScanConcentrator->SGcompensationMaxTime,pScanConcentrator->SGcompensationPercent));
   1551 }
   1552 
   1553 /**
   1554  * \author Yuval Adler\n
   1555  * \date 26-Jan-2006\n
   1556  * \brief update minDwellTime,MaxDwellTime,numProbeReq according to SG module request .\n
   1557  *          this function is called when SG is enabled.
   1558  * Function Scope \e Private.\n
   1559  * \param hScanCncn - handle to the scan concentrator object.\n
   1560  * \param pScanParams - a pointer to the structure holding the scan params .\n
   1561  */
   1562 void scanConcentrator_SGupdateScanParams( TI_HANDLE hScanCncn, scan_Params_t* pScanParams )
   1563 {
   1564     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
   1565     UINT8 i;
   1566     UINT32 tempTime;
   1567 
   1568     /* for each channel increase the min and max dwell time */
   1569     for ( i = 0 ; i < pScanParams->numOfChannels ; i++)
   1570     {
   1571         if (pScanConcentrator->SGcompensationMaxTime >
   1572             pScanParams->channelEntry[i].normalChannelEntry.minChannelDwellTime)
   1573         {
   1574             tempTime = ((pScanParams->channelEntry[i].normalChannelEntry.minChannelDwellTime) *
   1575                 ( 100 + pScanConcentrator->SGcompensationPercent)) / 100 ;
   1576 
   1577             if (tempTime > pScanConcentrator->SGcompensationMaxTime)
   1578             {
   1579                 tempTime = pScanConcentrator->SGcompensationMaxTime;
   1580             }
   1581             pScanParams->channelEntry[i].normalChannelEntry.minChannelDwellTime = tempTime;
   1582         }
   1583 
   1584         if (pScanConcentrator->SGcompensationMaxTime >
   1585                 pScanParams->channelEntry[i].normalChannelEntry.maxChannelDwellTime)
   1586         {
   1587             tempTime = ((pScanParams->channelEntry[i].normalChannelEntry.maxChannelDwellTime) *
   1588                 ( 100 + pScanConcentrator->SGcompensationPercent)) / 100 ;
   1589 
   1590             if (tempTime > pScanConcentrator->SGcompensationMaxTime)
   1591             {
   1592                 tempTime = pScanConcentrator->SGcompensationMaxTime;
   1593             }
   1594             pScanParams->channelEntry[i].normalChannelEntry.maxChannelDwellTime = tempTime;
   1595         }
   1596         WLAN_REPORT_INFORMATION(pScanConcentrator->hReport,SCAN_CNCN_MODULE_LOG,
   1597                 ("%s new parmas : channel = %d  MaxDwellTime = %d MinDwellTime = %d\n"
   1598                 ,__FUNCTION__,i,pScanParams->channelEntry[i].normalChannelEntry.maxChannelDwellTime,
   1599                 pScanParams->channelEntry[i].normalChannelEntry.minChannelDwellTime));
   1600     }
   1601 
   1602     /* update ProbeReqNumber only if it is larger than 0 and smaller than the new value */
   1603     if ((pScanParams->probeReqNumber > 0) &&
   1604         (pScanConcentrator->SGnumOfProbeRequest > pScanParams->probeReqNumber))
   1605     {
   1606         pScanParams->probeReqNumber = pScanConcentrator->SGnumOfProbeRequest;
   1607     }
   1608 
   1609     WLAN_REPORT_INFORMATION(pScanConcentrator->hReport,SCAN_CNCN_MODULE_LOG,
   1610         ("%s number of Probe requests = %d\n",__FUNCTION__,pScanParams->probeReqNumber));
   1611 }
   1612 
   1613 
   1614