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,¶m ); 665 is_801_11d_enabled = param.content.regulatoryDomainEnabled; 666 667 param.paramType = REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM; 668 regulatoryDomain_getParam( pScanConcentrator->hRegulatoryDomain,¶m ); 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,¶m); 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,¶m); 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