Home | History | Annotate | Download | only in scanCncn
      1 /** \file ScanCncnDrvSM.c
      2  *  \brief This file include the scan concentrator driver state machine 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 "ScanCncnDrvSM.h"
     42 #include "MacServices_api.h"
     43 #include "report.h"
     44 #include "siteMgrApi.h"
     45 #include "utils.h"
     46 #include "regulatoryDomainApi.h"
     47 #include "healthMonitor.h"
     48 
     49 
     50 static TI_STATUS actionUnexpected( TI_HANDLE hScanCncn );
     51 static TI_STATUS actionNop( TI_HANDLE hScanCncn );
     52 
     53 
     54 /**
     55  * \author Ronen Kalish\n
     56  * \date 02-Jan-2005\n
     57  * \brief Initialize the scan concentrator driver SM.
     58  *
     59  * Function Scope \e Public.\n
     60  * \param hScanCncn - handle to the scan concentrator object.\n
     61  * \return OK if successful, NOK otherwise.\n
     62  */
     63 TI_STATUS scanConcentratorDrvSM_init( TI_HANDLE hScanCncn )
     64 {
     65     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
     66 
     67     fsm_actionCell_t    smMatrix[ DRV_SCAN_NUM_OF_STATES ][ DRV_SCAN_NUM_OF_EVENTS ] =
     68 	{
     69 		/* next state and actions for IDLE state */
     70 		{
     71             {DRV_SCAN_STATE_SCR_REQUEST, scanConcentratorDrvSM_requestSCR},              /*"START_SCAN",*/
     72 			{DRV_SCAN_STATE_IDLE, actionUnexpected},                                     /*"SCR_PEND",  */
     73 			{DRV_SCAN_STATE_IDLE, actionUnexpected},                                     /*"SCR_REJECT",*/
     74             {DRV_SCAN_STATE_IDLE, actionUnexpected},                                     /*"PASSIVE_SCAN"*/
     75             {DRV_SCAN_STATE_IDLE, actionUnexpected},                                     /*"ACTIVE_SCAN"*/
     76             {DRV_SCAN_STATE_IDLE, actionUnexpected},                                     /*"ABORT_SCAN"*/
     77             {DRV_SCAN_STATE_IDLE, actionUnexpected},                                     /*"FW_RESET"*/
     78             {DRV_SCAN_STATE_IDLE, actionNop},                                            /*"STOP_SCAN"*/
     79             {DRV_SCAN_STATE_IDLE, actionUnexpected}                                      /*"SCAN_COMPLETE"*/
     80 		},
     81 
     82 		/* next state and actions for SCR_REQUEST state */
     83 		{
     84             {DRV_SCAN_STATE_SCR_REQUEST, actionUnexpected},                              /*"START_SCAN",*/
     85 			{DRV_SCAN_STATE_SCR_WAIT, actionNop},                                        /*"SCR_PEND",  */
     86 			{DRV_SCAN_STATE_IDLE, scanConcentratorDrvSM_scanRejected},                   /*"SCR_REJECT",*/
     87             {DRV_SCAN_STATE_PASSIVE_SCANNING, scanConcentratorDrvSM_passiveScan},        /*"PASSIVE_SCAN"*/
     88             {DRV_SCAN_STATE_ACTIVE_SCANNING, scanConcentratorDrvSM_activeScan},          /*"ACTIVE_SCAN"*/
     89             {DRV_SCAN_STATE_SCR_REQUEST, actionUnexpected},                              /*"ABORT_SCAN"*/
     90             {DRV_SCAN_STATE_SCR_REQUEST, actionUnexpected},                              /*"FW_RESET"*/
     91             {DRV_SCAN_STATE_SCR_REQUEST, actionUnexpected},                              /*"STOP_SCAN"*/
     92             {DRV_SCAN_STATE_SCR_REQUEST, actionUnexpected}                               /*"SCAN_COMPLETE"*/
     93 		},
     94 
     95 		/* next state and actions for SCR_WAIT state */
     96 		{
     97             {DRV_SCAN_STATE_SCR_WAIT, actionUnexpected},                                 /*"START_SCAN",*/
     98 			{DRV_SCAN_STATE_SCR_WAIT, actionNop},                                        /*"SCR_PEND",  */
     99 			{DRV_SCAN_STATE_IDLE, scanConcentratorDrvSM_scanRejected},                   /*"SCR_REJECT",*/
    100             {DRV_SCAN_STATE_PASSIVE_SCANNING, scanConcentratorDrvSM_passiveScan},        /*"PASSIVE_SCAN"*/
    101             {DRV_SCAN_STATE_ACTIVE_SCANNING, scanConcentratorDrvSM_activeScan},          /*"ACTIVE_SCAN"*/
    102             {DRV_SCAN_STATE_SCR_WAIT, actionUnexpected},                                 /*"ABORT_SCAN"*/
    103             {DRV_SCAN_STATE_SCR_WAIT, actionUnexpected},                                 /*"FW_RESET"*/
    104             {DRV_SCAN_STATE_IDLE, scanConcentratorDrvSM_scanRejected},                   /*"STOP_SCAN"*/
    105             {DRV_SCAN_STATE_SCR_WAIT, actionUnexpected}                                  /*"SCAN_COMPLETE"*/
    106 		},
    107 
    108         /* next state and actions for PASSIVE_SCANNING state */
    109 		{
    110             {DRV_SCAN_STATE_PASSIVE_SCANNING, actionUnexpected},                               /*"START_SCAN",*/
    111 			{DRV_SCAN_STATE_PASSIVE_SCANNING, actionUnexpected},                               /*"SCR_PEND",  */
    112 			{DRV_SCAN_STATE_PASSIVE_SCANNING, actionUnexpected},                               /*"SCR_REJECT",*/
    113             {DRV_SCAN_STATE_PASSIVE_SCANNING, actionUnexpected},                               /*"PASSIVE_SCAN"*/
    114             {DRV_SCAN_STATE_ACTIVE_SCANNING, scanConcentratorDrvSM_activeScan},          /*"ACTIVE_SCAN"*/
    115             {DRV_SCAN_STATE_STOPPING, scanConcentratorDrvSM_abortScan},                  /*"ABORT_SCAN"*/
    116             {DRV_SCAN_STATE_PASSIVE_SCANNING, scanConcentratorDrvSM_recoveryDuringScan}, /*"FW_RESET"*/
    117             {DRV_SCAN_STATE_STOPPING, scanConcentratorDrvSM_abortScan},                  /*"STOP_SCAN"*/
    118             {DRV_SCAN_STATE_IDLE, scanConcentratorDrvSM_scanComplete}                    /*"SCAN_COMPLETE"*/
    119 		},
    120 
    121         /* next state and actions for ACTIVE_SCANNING state */
    122 		{
    123             {DRV_SCAN_STATE_ACTIVE_SCANNING, actionUnexpected},                                     /*"START_SCAN",*/
    124 			{DRV_SCAN_STATE_ACTIVE_SCANNING, actionUnexpected},                                     /*"SCR_PEND",  */
    125 			{DRV_SCAN_STATE_ACTIVE_SCANNING, actionUnexpected},                                     /*"SCR_REJECT",*/
    126             {DRV_SCAN_STATE_ACTIVE_SCANNING, actionUnexpected},                                     /*"PASSIVE_SCAN"*/
    127             {DRV_SCAN_STATE_ACTIVE_SCANNING, actionUnexpected},                                     /*"ACTIVE_SCAN"*/
    128             {DRV_SCAN_STATE_STOPPING, scanConcentratorDrvSM_abortScan},                  /*"ABORT_SCAN"*/
    129             {DRV_SCAN_STATE_ACTIVE_SCANNING, scanConcentratorDrvSM_recoveryDuringScan},  /*"FW_RESET"*/
    130             {DRV_SCAN_STATE_STOPPING, scanConcentratorDrvSM_abortScan},                  /*"STOP_SCAN"*/
    131             {DRV_SCAN_STATE_IDLE, scanConcentratorDrvSM_scanComplete}                    /*"SCAN_COMPLETE"*/
    132 
    133 		},
    134 
    135         /* next state and actions for STOPPING state */
    136 		{
    137             {DRV_SCAN_STATE_STOPPING, actionUnexpected},                                     /*"START_SCAN",*/
    138 			{DRV_SCAN_STATE_STOPPING, actionUnexpected},                                     /*"SCR_PEND",  */
    139 			{DRV_SCAN_STATE_STOPPING, actionUnexpected},                                     /*"SCR_REJECT",*/
    140             {DRV_SCAN_STATE_STOPPING, actionUnexpected},                                     /*"PASSIVE_SCAN"*/
    141             {DRV_SCAN_STATE_STOPPING, actionUnexpected},                                     /*"ACTIVE_SCAN"*/
    142             {DRV_SCAN_STATE_STOPPING, actionNop},                                        /*"ABORT_SCAN"*/
    143             {DRV_SCAN_STATE_STOPPING, scanConcentratorDrvSM_recoveryDuringScan},         /*"FW_RESET"*/
    144             {DRV_SCAN_STATE_STOPPING, actionNop},                                        /*"STOP_SCAN"*/
    145             {DRV_SCAN_STATE_IDLE, scanConcentratorDrvSM_scanComplete}                    /*"SCAN_COMPLETE"*/
    146 		}
    147     };
    148 
    149     /* initialize current state */
    150     pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ] = DRV_SCAN_STATE_IDLE;
    151 
    152     /* configure the state machine */
    153 	return fsm_Config( pScanConcentrator->clientSM[ SCAN_SCC_DRIVER ], (fsm_Matrix_t)smMatrix,
    154                        DRV_SCAN_NUM_OF_STATES, DRV_SCAN_NUM_OF_EVENTS,
    155                        (fsm_eventActivation_t)scanConcentratorDrvSM_SMEvent, pScanConcentrator->hOS );
    156 }
    157 
    158 
    159 #ifdef REPORT_LOG
    160 
    161 /* state descriptions, for state machine logging */
    162 static char stateDesc[ DRV_SCAN_NUM_OF_STATES ][ MAX_DESC_STRING_LEN ] =
    163 {
    164     "STATE_IDLE",
    165     "STATE_SCR_REQUEST",
    166     "STATE_SCR_WAIT",
    167     "STATE_PASSIVE_SCANNING",
    168     "STATE_ACTIVE_SCANNING",
    169     "STATE_STOPPING"
    170 };
    171 
    172 /* event descriptions, for state machine logging */
    173 static char eventDesc[ DRV_SCAN_NUM_OF_EVENTS ][ MAX_DESC_STRING_LEN ] =
    174 {
    175     "EVENT_START_SCAN",
    176     "EVENT_SCR_PEND",
    177     "EVENT_SCR_REJECT",
    178     "EVENT_PASSIVE_SCAN",
    179     "EVENT_ACTIVE_SCAN",
    180     "EVENT_ABORT_SCAN",
    181     "EVENT_FW_RESET",
    182     "EVENT_STOP_SCAN",
    183     "EVENT_SCAN_COMPLETE"
    184 };
    185 
    186 #endif
    187 
    188 /**
    189  * \author Ronen Kalish\n
    190  * \date 02-Jan-2005\n
    191  * \brief Processes an event.
    192  *
    193  * Function Scope \e Public.\n
    194  * \param hScanCncn - handle to the scan concentrator object.\n
    195  * \param currentState - the current driver SM state.\n
    196  * \param event - the event to handle.\n
    197  * \return OK if successful, NOK otherwise.\n
    198  */
    199 TI_STATUS scanConcentratorDrvSM_SMEvent( TI_HANDLE hScanCncn, scan_drvSMStates_e* currentState,
    200                                          scan_drvSMEvents_e event )
    201 {
    202     scanConcentrator_t *pScanConcentrator = (scanConcentrator_t *)hScanCncn;
    203 	TI_STATUS status = OK;
    204 	UINT8 nextState;
    205 
    206     /* obtain the next state */
    207 	status = fsm_GetNextState( pScanConcentrator->clientSM[ SCAN_SCC_DRIVER ], *(UINT8*)currentState,
    208                                (UINT8)event, &nextState );
    209 	if ( status != OK )
    210 	{
    211 		WLAN_REPORT_SM( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, ("Failed getting driver scan next state.\n") );
    212 		return NOK;
    213 	}
    214 
    215     /* report the move */
    216     WLAN_REPORT_SM( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    217                     ("DRIVER SCAN: <%s, %s> --> %s\n\n",
    218                     stateDesc[*((UINT8*)currentState)],
    219                     eventDesc[(UINT8)event],
    220                     stateDesc[nextState]) );
    221 
    222     /* move */
    223     return fsm_Event( pScanConcentrator->clientSM[ SCAN_SCC_DRIVER ], (UINT8*)currentState, (UINT8)event, hScanCncn );
    224 }
    225 
    226 /**
    227  * \author Ronen Kalish\n
    228  * \date 02-Jan-2005\n
    229  * \brief SM action - handles a start scan event (by requesting the SCR)
    230  *
    231  * Function Scope \e Public.\n
    232  * \param hScanCncn - handle to the scan concentrator object.\n
    233  * \return OK if successful, NOK otherwise.\n
    234  */
    235 TI_STATUS scanConcentratorDrvSM_requestSCR( TI_HANDLE hScanCncn )
    236 {
    237     scr_clientRequestStatus_e scrReplyStatus;
    238     scr_pendReason_e scrPendReason;
    239 	scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
    240 
    241     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    242                              ("DRV SM: Requesting SCR.\n") );
    243 
    244     /* request the SCR as driver client, and act according to return status */
    245     switch (  scrReplyStatus = scr_clientRequest( pScanConcentrator->hSCR, SCR_CID_DRIVER_FG_SCAN, &scrPendReason ) )
    246     {
    247     case SCR_CRS_PEND:
    248         WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    249                                  ("DRV SM: SCR pending, pend reason: %d.\n", scrPendReason) );
    250 
    251         /* check the pending reason */
    252         if ( SCR_PR_DIFFERENT_GROUP_RUNNING == scrPendReason )
    253         {
    254             /* send a reject event to the SM - would not scan if not in connecting mode! */
    255             pScanConcentrator->scanResult[ SCAN_SCC_DRIVER ] = SCAN_CRS_SCAN_FAILED;
    256             return scanConcentratorDrvSM_SMEvent( hScanCncn,
    257                                                   (scan_drvSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]),
    258                                                   DRV_SCAN_EVENT_SCR_REJECT );
    259         }
    260         else
    261         {
    262             /* send a pend event to the SM */
    263             return scanConcentratorDrvSM_SMEvent( hScanCncn,
    264                                                   (scan_drvSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]),
    265                                                    DRV_SCAN_EVENT_SCR_PEND );
    266         }
    267  /*       break; - unreachable */
    268 
    269     case SCR_CRS_RUN:
    270         /* send an event to the SM */
    271         WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    272                                  ("DRV SM: SCR acquired.\n") );
    273         return scanConcentratorDrvSM_SMEvent( hScanCncn,
    274                                               (scan_drvSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]),
    275                                               scanConcentrator_getNextDriverEvent( hScanCncn ) );
    276 /*        break; - unreachable */
    277 
    278     default:
    279         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    280                              ("DRV SM: SCR returned unrecognized status: %d.\n", scrReplyStatus) );
    281 		pScanConcentrator->scanResult[ SCAN_SCC_DRIVER ] = SCAN_CRS_SCAN_FAILED;
    282         scanConcentratorDrvSM_SMEvent( hScanCncn,
    283                                        (scan_drvSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]),
    284                                        DRV_SCAN_EVENT_SCAN_COMPLETE );
    285         return NOK;
    286 /*        break; - unreachable */
    287     }
    288 
    289  /*   return OK; - unreachable */
    290 }
    291 
    292 /**
    293  * \author Ronen Kalish\n
    294  * \date 02-Jan-2005\n
    295  * \brief SM action - handles a FW reset event (by calling the complete CB)
    296  *
    297  * Function Scope \e Public.\n
    298  * \param hScanCncn - handle to the scan concentrator object.\n
    299  * \return OK if successful, NOK otherwise.\n
    300  */
    301 TI_STATUS scanConcentratorDrvSM_callCompleteCB( TI_HANDLE hScanCncn )
    302 {
    303     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
    304 
    305     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    306                              ("DRV SM: calling complete CB.\n") );
    307 
    308     /* mark that no scan is currently running */
    309     pScanConcentrator->currentRunningScanClient = SCAN_SCC_NO_CLIENT;
    310 
    311     /* notify scan complete to scan mngr */
    312     if ( FALSE == pScanConcentrator->bInRequest )
    313     {
    314         pScanConcentrator->scanResultCB[ SCAN_SCC_DRIVER ]( pScanConcentrator->scanResultCBObj[ SCAN_SCC_DRIVER ],
    315                                                         pScanConcentrator->scanResult[ SCAN_SCC_DRIVER ],
    316                                                         NULL, 0xffff );
    317     }
    318 
    319     return OK;
    320 }
    321 
    322 /**
    323  * \author Ronen Kalish\n
    324  * \date 02-Jan-2005\n
    325  * \brief SM action - handles a passive scan event (by starting a passive scan)
    326  *
    327  * Function Scope \e Public.\n
    328  * \param hScanCncn - handle to the scan concentrator object.\n
    329  * \return OK if successful, NOK otherwise.\n
    330  */
    331 TI_STATUS scanConcentratorDrvSM_passiveScan( TI_HANDLE hScanCncn )
    332 {
    333     TI_STATUS status;
    334     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
    335     int i;
    336 
    337     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    338                              ("DRV SM: Sending passive scan command to scan SRV.\n") );
    339 
    340     /* mark that this scan is currently running */
    341     pScanConcentrator->currentRunningScanClient = SCAN_SCC_DRIVER;
    342 
    343     /* if the requested scan type is not passive in the first place, change it to passive */
    344     pScanConcentrator->drvScanRequestType = pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType;
    345     if ( (SCAN_TYPE_NORMAL_ACTIVE == pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType) ||
    346          (SCAN_TYPE_TRIGGERED_ACTIVE == pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType) )
    347     {
    348         pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType = SCAN_TYPE_NORMAL_PASSIVE;
    349 
    350         /* save requested SSID, and write broadcast SSID instead. This is done to find ANY beacon for .11d
    351            and .11h, in case the desired SSID is not being broadcast in beacons */
    352         os_memoryCopy( pScanConcentrator->hOS, &(pScanConcentrator->drvScanSsid),
    353                        &(pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].desiredSsid), sizeof(ssid_t) );
    354         pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].desiredSsid.len = 0;
    355 
    356         /* save max and min dwell time for all channels, and replace them with default values */
    357         for ( i = 0; i < pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].numOfChannels; i++ )
    358         {
    359             pScanConcentrator->drvScanMaxDwellTime[ i ] =
    360                 pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.maxChannelDwellTime;
    361             pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.maxChannelDwellTime =
    362                 pScanConcentrator->initParams.passiveScanDwellTime;
    363             pScanConcentrator->drvScanMinDwellTime[ i ] =
    364                 pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.minChannelDwellTime;
    365             pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.minChannelDwellTime =
    366                 pScanConcentrator->initParams.passiveScanDwellTime;
    367 			if (pScanConcentrator->bUseSGParams)
    368 			{
    369 				/* increasing dwell time in case BT is active to compensate loss of dwelling time */
    370 				pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.minChannelDwellTime =
    371 					(pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.minChannelDwellTime *
    372 					(100 + pScanConcentrator->SGcompensationPercent)) / 100;
    373 				pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.maxChannelDwellTime =
    374 					(pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.maxChannelDwellTime *
    375 					(100 + pScanConcentrator->SGcompensationPercent)) / 100;
    376 				WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    377                              ("SoftGemini compensation time for channel %d : min = %d, max = %d  .\n",
    378 							 i,pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.minChannelDwellTime,
    379 							 pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.maxChannelDwellTime) );
    380 
    381 			}
    382         }
    383     }
    384 
    385     /* ask the reg domain which channels are allowed for the requested scan type */
    386     scanConcentrator_verifyChannelsWithRegDomain( hScanCncn, &(pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ]) );
    387 
    388     /* if no channels are available for scan, return negative result */
    389     if ( 0 == pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].numOfChannels )
    390     {
    391         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    392                              ("DRV SM: No cahnnels available for passive scan, quitting.\n") );
    393         scanConcentratorDrvSM_handleScanError( hScanCncn );
    394         return NOK;
    395     }
    396 
    397     /* register for scan results with the MLME parser */
    398     if ( OK != (status = mlmeParser_registerForBeaconAndProbeResp( pScanConcentrator->hMlme,
    399                                                                    scanConcentrator_mlmeResultCB,
    400                                                                    hScanCncn )) )
    401     {
    402         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    403                              ("DRV SM: MLME result registration failed.\n") );
    404         scanConcentratorDrvSM_handleScanError( hScanCncn );
    405         return NOK;
    406     }
    407 
    408 	 /* stop built-in test timer, to avoid TX stuck due to heavy traffic and unknown scan result time originally at scanSrv*/
    409 	healthMonitor_suspendPeriodicTest( pScanConcentrator->hHealthMonitor );
    410 
    411     /* call the scan SRV start scan */
    412     if ( OK != (status = MacServices_scanSRV_scan( pScanConcentrator->hMacServices,
    413                                               &(pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ]),
    414                                               FALSE,
    415                                               FALSE,
    416                                               FALSE,
    417                                               POWER_SAVE_KEEP_CURRENT,
    418                                               FALSE ,
    419 											  NULL,NULL)) )
    420     {
    421         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    422                              ("DRV SM: scan SRV returned status %d, quitting driver passive scan.\n", status) );
    423 
    424         /* unregister at the MLME for scan result frames */
    425         mlmeParser_unregisterForBeaconAndProbeResp( pScanConcentrator->hMlme );
    426         scanConcentratorDrvSM_handleScanError( hScanCncn );
    427         return NOK;
    428     }
    429 
    430     return OK;
    431 }
    432 
    433 /**
    434  * \author Ronen Kalish\n
    435  * \date 02-Jan-2005\n
    436  * \brief SM action - handles an active scan event (by starting an active scan)
    437  *
    438  * Function Scope \e Public.\n
    439  * \param hScanCncn - handle to the scan concentrator object.\n
    440  * \return OK if successful, NOK otherwise.\n
    441  */
    442 TI_STATUS scanConcentratorDrvSM_activeScan( TI_HANDLE hScanCncn )
    443 {
    444     TI_STATUS status;
    445     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
    446 
    447     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    448                              ("DRV SM: Sending active scan command to scan SRV.\n") );
    449 
    450     /* mark that this scan is currently running */
    451     pScanConcentrator->currentRunningScanClient = SCAN_SCC_DRIVER;
    452 
    453     /* ask the reg domain which channels are allowed for the requested scan type */
    454     scanConcentrator_verifyChannelsWithRegDomain( hScanCncn, &(pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ]) );
    455 
    456     /* if no channels are available for scan, return negative result */
    457     if ( 0 == pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].numOfChannels )
    458     {
    459         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    460                              ("DRV SM: No cahnnels available for active scan, quitting.\n") );
    461         scanConcentratorDrvSM_handleScanError( hScanCncn );
    462         return NOK;
    463     }
    464 
    465 
    466     /* register for scan results with the MLME parser */
    467     if ( OK != mlmeParser_registerForBeaconAndProbeResp( pScanConcentrator->hMlme,
    468                                                          scanConcentrator_mlmeResultCB,
    469                                                          hScanCncn ) )
    470     {
    471         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    472                              ("DRV SM: MLME result registration failed.\n") );
    473         scanConcentratorDrvSM_handleScanError( hScanCncn );
    474         return NOK;
    475     }
    476 
    477 	/* stop built-in test timer, to avoid TX stuck due to heavy traffic and unknown scan result time originally at scanSrv*/
    478 	healthMonitor_suspendPeriodicTest( pScanConcentrator->hHealthMonitor );
    479 
    480     if ( OK != (status = MacServices_scanSRV_scan( pScanConcentrator->hMacServices,
    481                                        &(pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ]),
    482                                        FALSE,
    483                                        FALSE,
    484                                        FALSE,
    485                                        POWER_SAVE_KEEP_CURRENT,
    486                                        FALSE ,
    487 									   NULL,NULL)) )
    488     {
    489         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    490                              ("DRV SM: scan SRV returned status %d, quitting driver active scan.\n", status) );
    491 	    /* unregister at the MLME for scan result frames */
    492         mlmeParser_unregisterForBeaconAndProbeResp( pScanConcentrator->hMlme );
    493         scanConcentratorDrvSM_handleScanError( hScanCncn );
    494         return NOK;
    495     }
    496 
    497     return OK;
    498 }
    499 
    500 /**
    501  * \author Ronen Kalish\n
    502  * \date 02-Jan-2005\n
    503  * \brief SM action - handles an abort scan or stop scan event (by stopping the actual scan)
    504  *
    505  * Function Scope \e Public.\n
    506  * \param hScanCncn - handle to the scan concentrator object.\n
    507  * \return OK if successful, NOK otherwise.\n
    508  */
    509 TI_STATUS scanConcentratorDrvSM_abortScan( TI_HANDLE hScanCncn )
    510 {
    511     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
    512 
    513     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    514                              ("DRV SM: aborting scan.\n") );
    515 
    516     /* call the scan SRV stop scan (don't exit driver mode, as it wasn't entered for driver scan */
    517     MacServices_scanSRV_stopScan( pScanConcentrator->hMacServices, FALSE , NULL , NULL );
    518 
    519     return OK;
    520 }
    521 
    522 /**
    523  * \author Ronen Kalish\n
    524  * \date 10-July-2005\n
    525  * \brief SM action - handles a recovery event (calls the scan SRV abort on FW reset and than finishes scan)
    526  *
    527  * Function Scope \e Public.\n
    528  * \param hScanCncn - handle to the scan concentrator object.\n
    529  * \return OK if successful, NOK otherwise.\n
    530  */
    531 TI_STATUS scanConcentratorDrvSM_recoveryDuringScan( TI_HANDLE hScanCncn )
    532 {
    533     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
    534 
    535     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    536                              ("DRV SM: Recovery occured!.\n") );
    537 
    538     /* reset the scan SRV */
    539     MacServices_scanSRV_stopOnFWReset( pScanConcentrator->hMacServices );
    540 
    541     /* send a scan complete event to the SM */
    542     return scanConcentratorDrvSM_SMEvent( hScanCncn,
    543                                           (scan_drvSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]),
    544                                           DRV_SCAN_EVENT_SCAN_COMPLETE );
    545 }
    546 
    547 /**
    548  * \author Ronen Kalish\n
    549  * \date 02-Jan-2005\n
    550  * \brief SM action - handles a scan complete event (by releasing the SCR and calling the scan complete CB)
    551  *
    552  * Function Scope \e Public.\n
    553  * \param hScanCncn - handle to the scan concentrator object.\n
    554  * \return OK if successful, NOK otherwise.\n
    555  */
    556 TI_STATUS scanConcentratorDrvSM_scanComplete( TI_HANDLE hScanCncn )
    557 {
    558     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
    559 
    560     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    561                              ("DRV SM: Scan is complete.\n") );
    562 
    563 	/* unregister at the MLME for scan result frames */
    564     mlmeParser_unregisterForBeaconAndProbeResp( pScanConcentrator->hMlme );
    565 
    566     /* mark that this scan is no longer running */
    567     pScanConcentrator->currentRunningScanClient = SCAN_SCC_NO_CLIENT;
    568 
    569     /* release the SCR */
    570     scr_clientComplete( pScanConcentrator->hSCR, SCR_CID_DRIVER_FG_SCAN );
    571 
    572     /* notify the scan complete to the scan mngr */
    573     if ( FALSE == pScanConcentrator->bInRequest )
    574     {
    575         pScanConcentrator->scanResultCB[ SCAN_SCC_DRIVER ]( pScanConcentrator->scanResultCBObj[ SCAN_SCC_DRIVER ],
    576                                                             pScanConcentrator->scanResult[ SCAN_SCC_DRIVER ],
    577                                                             NULL, 0xffff );
    578     }
    579 
    580     return OK;
    581 }
    582 
    583 /**
    584  * \author Ronen Kalish\n
    585  * \date 02-Jan-2005\n
    586  * \brief SM action - handles a scan reject event (abort scan before scan actually started)\n
    587  *
    588  * Function Scope \e Public.\n
    589  * \param hScanCncn - handle to the scan concentrator object.\n
    590  * \return OK if successful, NOK otherwise.\n
    591  */
    592 TI_STATUS scanConcentratorDrvSM_scanRejected( TI_HANDLE hScanCncn )
    593 {
    594     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
    595 
    596     WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    597                              ("DRV SM: Scan is Rejected.\n") );
    598 
    599     /* release the SCR */
    600     scr_clientComplete( pScanConcentrator->hSCR, SCR_CID_DRIVER_FG_SCAN );
    601 
    602     /* notify the scan complete to the scan mngr */
    603     if ( FALSE == pScanConcentrator->bInRequest )
    604     {
    605         pScanConcentrator->scanResultCB[ SCAN_SCC_DRIVER ]( pScanConcentrator->scanResultCBObj[ SCAN_SCC_DRIVER ],
    606                                                             pScanConcentrator->scanResult[ SCAN_SCC_DRIVER ],
    607                                                             NULL, 0xffff );
    608     }
    609 
    610     return OK;
    611 }
    612 
    613 /**
    614  * \author Ronen Kalish\n
    615  * \date 11-Jan-2005\n
    616  * \brief Handles an unexpected event.\n
    617  *
    618  * Function Scope \e Private.\n
    619  * \param hScanCncn - handle to the scan concentrator object.\n
    620  * \return always OK.\n
    621  */
    622 TI_STATUS actionUnexpected( TI_HANDLE hScanCncn )
    623 {
    624     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
    625 
    626     WLAN_REPORT_ERROR( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, ("Driver scan state machine error, unexpected Event, state=%d\n\n",
    627 																	  pScanConcentrator->clientSMState[SCAN_SCC_DRIVER] ) );
    628 
    629     return OK;
    630 }
    631 
    632 /**
    633  * \author Ronen Kalish\n
    634  * \date 10-Jan-2005\n
    635  * \brief Handles an event that doesn't require any action.\n
    636  *
    637  * Function Scope \e Private.\n
    638  * \param hScanCncn - handle to the scan concentrator object.\n
    639  * \return always OK.\n
    640  */
    641 TI_STATUS actionNop( TI_HANDLE hScanCncn )
    642 {
    643     return OK;
    644 }
    645 
    646 /**
    647  * \author Ronen Kalish\n
    648  * \date 09-Jan-2005\n
    649  * \brief Determines the next event to send to the driver SM (when a scan can be run)\n
    650  *
    651  * Function Scope \e Private.\n
    652  * \param hScanCncn - handle to the scan concentrator object.\n
    653  * \return the next event to use with the driver SM.\n
    654  */
    655 scan_drvSMEvents_e scanConcentrator_getNextDriverEvent( TI_HANDLE hScanCncn )
    656 {
    657     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
    658     paramInfo_t         param;
    659     BOOL                is_801_11d_enabled, is_801_11h_enabled;
    660     int					i;
    661 
    662     /* getting regulatory Domain status - is 802.11d enabled ? */
    663     param.paramType = REGULATORY_DOMAIN_ENABLED_PARAM;
    664     regulatoryDomain_getParam( pScanConcentrator->hRegulatoryDomain,&param );
    665     is_801_11d_enabled = param.content.regulatoryDomainEnabled;
    666 
    667     param.paramType = REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM;
    668     regulatoryDomain_getParam( pScanConcentrator->hRegulatoryDomain,&param );
    669 	is_801_11h_enabled = param.content.spectrumManagementEnabled;
    670 
    671     /* The next event (or rather, scan type) is determined according to the driver SM state.
    672        The order is passive-active, when either the active or passive scan can be eliminated (but the order is kept).
    673      */
    674     switch (pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ])
    675     {
    676     /* active scan already performed, send a scan complete event */
    677     case DRV_SCAN_STATE_ACTIVE_SCANNING:
    678     /* Stop or abort is in progress, also send a scan complete event */
    679     case DRV_SCAN_STATE_STOPPING:
    680         return DRV_SCAN_EVENT_SCAN_COMPLETE;
    681 /*        break; - unreachable */
    682 
    683     /* passive scan already performed, check if active scan is needed. */
    684     case DRV_SCAN_STATE_PASSIVE_SCANNING:
    685         /* first, restore the user requested scan type, */
    686         pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType = pScanConcentrator->drvScanRequestType;
    687         /* the user desired SSID */
    688         os_memoryCopy( pScanConcentrator->hOS, &(pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].desiredSsid),
    689                        &(pScanConcentrator->drvScanSsid), sizeof(ssid_t) );
    690         /* and dwell times for all channels */
    691         for ( i = 0; i < pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].numOfChannels; i++ )
    692         {
    693             pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.maxChannelDwellTime =
    694                 pScanConcentrator->drvScanMaxDwellTime[ i ];
    695             pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].channelEntry[ i ].normalChannelEntry.minChannelDwellTime =
    696                 pScanConcentrator->drvScanMinDwellTime[ i ];
    697         }
    698 
    699         /* send scan complete event if:
    700            1. The requested scan type is passive
    701            2. .11d is enabled and no country IE is available
    702          */
    703 
    704 		/* Get country code status */
    705 		param.paramType			 = REGULATORY_DOMAIN_IS_COUNTRY_FOUND;
    706 		param.content.eRadioBand = pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].band;
    707 		regulatoryDomain_getParam(pScanConcentrator->hRegulatoryDomain,&param);
    708 
    709         if ( (pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType == SCAN_TYPE_NORMAL_PASSIVE) ||
    710              (pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType == SCAN_TYPE_TRIGGERED_PASSIVE) ||
    711              (pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType == SCAN_TYPE_SPS) ||
    712              ((TRUE == is_801_11d_enabled) &&
    713               ( !param.content.bIsCountryFound )) )
    714         {
    715             return DRV_SCAN_EVENT_SCAN_COMPLETE;
    716         }
    717         /* otherwise, send active scan event */
    718         else
    719         {
    720             /* Very ugly - but nowhere better to do it...
    721                If we continue to active scan after passive scan, we are already registered
    722                in the MLME parser. We MUST unregister here, or else the registration at
    723                the active scan call will fail */
    724             mlmeParser_unregisterForBeaconAndProbeResp( pScanConcentrator->hMlme );
    725             return DRV_SCAN_EVENT_ACTIVE_SCAN;
    726         }
    727 /*        break; - unreachable */
    728 
    729     /* no scan already performed, any scan can be issued */
    730     case DRV_SCAN_STATE_SCR_WAIT:
    731     case DRV_SCAN_STATE_SCR_REQUEST:
    732         /* do a passive scan if:
    733            1. it was requested
    734            2. .11d is enabled and country is unknown
    735            3. .11h is enabled and the scan is on A band (always perform passive before active, to validate channels)
    736          */
    737 
    738 		/* Get country code status */
    739 		param.paramType			 = REGULATORY_DOMAIN_IS_COUNTRY_FOUND;
    740 		param.content.eRadioBand = pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].band ;
    741 		regulatoryDomain_getParam(pScanConcentrator->hRegulatoryDomain,&param);
    742 
    743         if ( (pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType == SCAN_TYPE_NORMAL_PASSIVE) ||
    744              (pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType == SCAN_TYPE_TRIGGERED_PASSIVE) ||
    745              (pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].scanType == SCAN_TYPE_SPS) ||
    746              ((TRUE == is_801_11d_enabled) &&
    747               (!param.content.bIsCountryFound)) ||
    748              ((TRUE == is_801_11h_enabled) &&
    749               (RADIO_BAND_5_0_GHZ == pScanConcentrator->clientScanParams[ SCAN_SCC_DRIVER ].band)) )
    750         {
    751             return DRV_SCAN_EVENT_PASSIVE_SCAN;
    752         }
    753         /* else, do an active scan if
    754          */
    755         else
    756         {
    757             return DRV_SCAN_EVENT_ACTIVE_SCAN;
    758         }
    759 /*        break; - unreachable */
    760 
    761     default:
    762         WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG,
    763                              ("DRV SM: State %d is invalid to obtain next event", pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]) );
    764         break;
    765     }
    766 
    767     return DRV_SCAN_EVENT_SCAN_COMPLETE;
    768 }
    769 
    770 /**
    771  * \author Ronen Kalish\n
    772  * \date 07-Feb-2005\n
    773  * \brief Handles an error during scan operation
    774  *
    775  * Function Scope \e Private.\n
    776  * \param hScanCncn - handle to the scan concentrator object.\n
    777  */
    778 void scanConcentratorDrvSM_handleScanError( TI_HANDLE hScanCncn )
    779 {
    780     scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn;
    781 
    782     /* mark the return status */
    783     pScanConcentrator->scanResult[ SCAN_SCC_DRIVER ] = SCAN_CRS_SCAN_FAILED;
    784 
    785     /* send a scan complete event */
    786     scanConcentratorDrvSM_SMEvent( hScanCncn,
    787                                    (scan_drvSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_DRIVER ]),
    788                                    DRV_SCAN_EVENT_SCAN_COMPLETE );
    789 }
    790