1 /** \file ScanCncnAppSM.c 2 * \brief This file include the scan concentrator application SM 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 "ScanCncnAppSM.h" 42 #include "MacServices_api.h" 43 #include "report.h" 44 #include "healthMonitor.h" 45 46 static TI_STATUS actionUnexpected( TI_HANDLE hScanCncn ); 47 static TI_STATUS actionNop( TI_HANDLE hScanCncn ); 48 49 /** 50 * \author Ronen Kalish\n 51 * \date 02-Jan-2005\n 52 * \brief Initialize the scan concentrator application SM. 53 * 54 * Function Scope \e Public.\n 55 * \param hScanCncn - handle to the scan concentrator object.\n 56 * \return OK if successful, NOK otherwise.\n 57 */ 58 TI_STATUS scanConcentratorAppSM_init( TI_HANDLE hScanCncn ) 59 { 60 scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn; 61 62 fsm_actionCell_t smMatrix[ APP_SCAN_NUM_OF_STATES ][ APP_SCAN_NUM_OF_EVENTS ] = 63 { 64 /* next state and actions for IDLE state */ 65 { 66 {APP_SCAN_STATE_SCR_REQUEST, scanConcentratorAppSM_requestSCR}, /*"START_SCAN",*/ 67 {APP_SCAN_STATE_IDLE, actionUnexpected}, /*"SCR_RUN",*/ 68 {APP_SCAN_STATE_IDLE, actionUnexpected}, /*"SCR_PEND", */ 69 {APP_SCAN_STATE_IDLE, actionNop}, /*"STOP_SCAN"*/ 70 {APP_SCAN_STATE_IDLE, actionUnexpected}, /*"ABORT_SCAN"*/ 71 {APP_SCAN_STATE_IDLE, actionUnexpected}, /*"FW_RESET"*/ 72 {APP_SCAN_STATE_IDLE, actionUnexpected} /*"SCAN_COMPLETE"*/ 73 }, 74 75 /* next state and actions for SCR_REQUEST state */ 76 { 77 {APP_SCAN_STATE_SCR_REQUEST, actionUnexpected}, /*"START_SCAN",*/ 78 {APP_SCAN_STATE_SCANNING, scanConcentratorAppSM_startScan}, /*"SCR_RUN",*/ 79 {APP_SCAN_STATE_IDLE, scanConcentratorAppSM_scanRejected}, /*"SCR_PEND", */ 80 {APP_SCAN_STATE_SCR_REQUEST, actionUnexpected}, /*"STOP_SCAN"*/ 81 {APP_SCAN_STATE_SCR_REQUEST, actionUnexpected}, /*"ABORT_SCAN"*/ 82 {APP_SCAN_STATE_SCR_REQUEST, actionUnexpected}, /*"FW_RESET"*/ 83 {APP_SCAN_STATE_SCR_REQUEST, actionUnexpected} /*"SCAN_COMPLETE"*/ 84 }, 85 86 /* next state and actions for SCANNING state */ 87 { 88 {APP_SCAN_STATE_SCANNING, actionUnexpected}, /*"START_SCAN",*/ 89 {APP_SCAN_STATE_SCANNING, actionUnexpected}, /*"SCR_RUN",*/ 90 {APP_SCAN_STATE_SCANNING, actionUnexpected}, /*"SCR_PEND", */ 91 {APP_SCAN_STATE_STOPPING, scanConcentratorAppSM_abortScan}, /*"STOP_SCAN"*/ 92 {APP_SCAN_STATE_STOPPING, scanConcentratorAppSM_abortScan}, /*"ABORT_SCAN"*/ 93 {APP_SCAN_STATE_SCANNING, scanConcentratorAppSM_recoveryDuringScan}, /*"FW_RESET"*/ 94 {APP_SCAN_STATE_IDLE, scanConcentratorAppSM_scanComplete} /*"SCAN_COMPLETE"*/ 95 }, 96 97 /* next state and actions for STOPPING state */ 98 { 99 {APP_SCAN_STATE_STOPPING, actionUnexpected}, /*"START_SCAN",*/ 100 {APP_SCAN_STATE_STOPPING, actionUnexpected}, /*"SCR_RUN",*/ 101 {APP_SCAN_STATE_STOPPING, actionUnexpected}, /*"SCR_PEND", */ 102 {APP_SCAN_STATE_STOPPING, actionNop}, /*"STOP_SCAN"*/ 103 {APP_SCAN_STATE_STOPPING, actionNop}, /*"ABORT_SCAN"*/ 104 {APP_SCAN_STATE_STOPPING, scanConcentratorAppSM_recoveryDuringScan}, /*"FW_RESET"*/ 105 {APP_SCAN_STATE_IDLE, scanConcentratorAppSM_scanComplete} /*"SCAN_COMPLETE"*/ 106 } 107 }; 108 109 /* initialize current state */ 110 pScanConcentrator->clientSMState[ SCAN_SCC_APP ] = APP_SCAN_STATE_IDLE; 111 112 /* configure the state machine */ 113 return fsm_Config( pScanConcentrator->clientSM[ SCAN_SCC_APP ], (fsm_Matrix_t)smMatrix, 114 APP_SCAN_NUM_OF_STATES, APP_SCAN_NUM_OF_EVENTS, 115 (fsm_eventActivation_t)scanConcentratorAppSM_SMEvent, pScanConcentrator->hOS ); 116 } 117 118 119 #ifdef REPORT_LOG 120 121 /* state descriptions, for state machine logging */ 122 static char stateDesc[ APP_SCAN_NUM_OF_STATES ][ MAX_DESC_STRING_LEN ] = 123 { 124 "STATE_IDLE", 125 "STATE_SCR_REQUEST", 126 "STATE_SCANNING", 127 "STATE_STOPPING" 128 }; 129 130 /* event descriptions, for state machine logging */ 131 static char eventDesc[ APP_SCAN_NUM_OF_EVENTS ][ MAX_DESC_STRING_LEN ] = 132 { 133 "EVENT_START_SCAN", 134 "EVENT_SCR_RUN", 135 "EVENT_SCR_PEND", 136 "EVENT_STOP_SCAN", 137 "EVENT_ABORT_SCAN", 138 "EVENT_FW_RESET", 139 "EVENT_SCAN_COMPLETE" 140 }; 141 142 #endif 143 144 /** 145 * \author Ronen Kalish\n 146 * \date 02-Jan-2005\n 147 * \brief Processes an event. 148 * 149 * Function Scope \e Public.\n 150 * \param hScanCncn - handle to the scan concentrator object.\n 151 * \param currentState - the current App SM state.\n 152 * \param event - the event to handle.\n 153 * \return OK if successful, NOK otherwise.\n 154 */ 155 TI_STATUS scanConcentratorAppSM_SMEvent( TI_HANDLE hScanCncn, scan_appSMStates_e* currentState, 156 scan_appSMEvents_e event ) 157 { 158 scanConcentrator_t *pScanConcentrator = (scanConcentrator_t *)hScanCncn; 159 TI_STATUS status = OK; 160 UINT8 nextState; 161 162 /* obtain the next state */ 163 status = fsm_GetNextState( pScanConcentrator->clientSM[ SCAN_SCC_APP ], *(UINT8*)currentState, 164 (UINT8)event, &nextState ); 165 if ( status != OK ) 166 { 167 WLAN_REPORT_SM( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, ("Failed getting application scan next state.\n") ); 168 return NOK; 169 } 170 171 /* report the move */ 172 WLAN_REPORT_SM( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, 173 ("APP SCAN: <%s, %s> --> %s\n\n", 174 stateDesc[*((UINT8*)currentState)], 175 eventDesc[(UINT8)event], 176 stateDesc[nextState]) ); 177 178 /* move */ 179 return fsm_Event( pScanConcentrator->clientSM[ SCAN_SCC_APP ], (UINT8*)currentState, (UINT8)event, hScanCncn ); 180 } 181 182 /** 183 * \author Ronen Kalish\n 184 * \date 02-Jan-2005\n 185 * \brief SM action - handles a start scan event (by requesting the SCR) 186 * 187 * Function Scope \e Public.\n 188 * \param hScanCncn - handle to the scan concentrator object.\n 189 * \return OK if successful, NOK otherwise.\n 190 */ 191 TI_STATUS scanConcentratorAppSM_requestSCR( TI_HANDLE hScanCncn ) 192 { 193 scr_clientRequestStatus_e scrReplyStatus; 194 scr_pendReason_e scrPendReason; 195 scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn; 196 197 WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, 198 ("APP SM: Requesting SCR.\n") ); 199 200 /* request the SCR as application scan client, and act according to return status */ 201 switch ( scrReplyStatus = scr_clientRequest( pScanConcentrator->hSCR, SCR_CID_APP_SCAN, &scrPendReason ) ) 202 { 203 case SCR_CRS_PEND: 204 /* send a pend event to the SM */ 205 WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, 206 ("APP SM: SCR pending, pend reason: %d.\n", scrPendReason) ); 207 pScanConcentrator->scanResult[ SCAN_SCC_APP ] = SCAN_CRS_SCAN_FAILED; 208 return scanConcentratorAppSM_SMEvent( hScanCncn, 209 (scan_appSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_APP ]), 210 APP_SCAN_EVENT_SCR_PEND ); 211 /* break; - unreachable */ 212 213 case SCR_CRS_RUN: 214 /* send a run event to the SM */ 215 WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, 216 ("APP SM: SCR acquired.\n") ); 217 return scanConcentratorAppSM_SMEvent( hScanCncn, 218 (scan_appSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_APP ]), 219 APP_SCAN_EVENT_SCR_RUN ); 220 /* break; - unreachable */ 221 222 default: 223 WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, 224 ("APP SM: SCR returned unrecognized status: %d.\n", scrReplyStatus) ); 225 /* Notify scan complete to recover from this error */ 226 pScanConcentrator->scanResult[ SCAN_SCC_APP ] = SCAN_CRS_SCAN_FAILED; 227 scanConcentratorAppSM_SMEvent( hScanCncn, 228 (scan_appSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_APP ]), 229 APP_SCAN_EVENT_SCAN_COMPLETE ); 230 231 return NOK; 232 /* break; - unreachable */ 233 } 234 235 /* return OK; - unreachable */ 236 } 237 238 /** 239 * \author Ronen Kalish\n 240 * \date 02-Jan-2005\n 241 * \brief SM action - handles a SCR run event (starts the actual scan) 242 * 243 * Function Scope \e Public.\n 244 * \param hScanCncn - handle to the scan concentrator object.\n 245 * \return OK if successful, NOK otherwise.\n 246 */ 247 TI_STATUS scanConcentratorAppSM_startScan( TI_HANDLE hScanCncn ) 248 { 249 scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn; 250 TI_STATUS status; 251 252 WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, 253 ("APP SM: Sending scan command to scan SRV.\n") ); 254 255 /* mark that this scan is currently running */ 256 pScanConcentrator->currentRunningScanClient = SCAN_SCC_APP; 257 258 /* register for scan results with the MLME parser */ 259 if ( OK != (status = mlmeParser_registerForBeaconAndProbeResp( pScanConcentrator->hMlme, 260 scanConcentrator_mlmeResultCB, 261 hScanCncn )) ) 262 { 263 WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, 264 ("APP SM: MLME result registration failed.\n") ); 265 266 /* mark the return status */ 267 pScanConcentrator->scanResult[ SCAN_SCC_APP ] = SCAN_CRS_SCAN_FAILED; 268 269 /* could not start scan, send a scan complete event */ 270 scanConcentratorAppSM_SMEvent( hScanCncn, 271 (scan_appSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_APP ]), 272 APP_SCAN_EVENT_SCAN_COMPLETE ); 273 274 return NOK; 275 } 276 277 /* stop built-in test timer, to avoid TX stuck due to heavy traffic and unknown scan result time originally at scanSrv*/ 278 healthMonitor_suspendPeriodicTest( pScanConcentrator->hHealthMonitor ); 279 280 /* call the scan SRV start scan - enter driver mode (PS) only if station is connected */ 281 if ( OK != (status = MacServices_scanSRV_scan( pScanConcentrator->hMacServices, 282 &(pScanConcentrator->clientScanParams[ SCAN_SCC_APP ]), 283 FALSE, 284 (STA_CONNECTED == pScanConcentrator->connectionStatus ? TRUE : FALSE), 285 FALSE, 286 POWER_SAVE_ON, /* this parameter is used only when driver mode requested */ 287 (STA_CONNECTED == pScanConcentrator->connectionStatus ? TRUE : FALSE), 288 NULL,NULL))) 289 { 290 WLAN_REPORT_WARNING( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, 291 ("APP SM: scan SRV returned status %d, quitting app scan.\n", status) ); 292 293 /* mark the return status */ 294 pScanConcentrator->scanResult[ SCAN_SCC_APP ] = SCAN_CRS_SCAN_FAILED; 295 296 /* unregister at the MLME for scan result frames */ 297 mlmeParser_unregisterForBeaconAndProbeResp( pScanConcentrator->hMlme ); 298 299 /* could not start scan, send a scan complete event */ 300 scanConcentratorAppSM_SMEvent( hScanCncn, 301 (scan_appSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_APP ]), 302 APP_SCAN_EVENT_SCAN_COMPLETE ); 303 304 return NOK; 305 } 306 307 return OK; 308 } 309 310 /** 311 * \author Ronen Kalish\n 312 * \date 02-Jan-2005\n 313 * \brief SM action - handles an abort scan event (call the scan SRV stop) 314 * 315 * Function Scope \e Public.\n 316 * \param hScanCncn - handle to the scan concentrator object.\n 317 * \return OK if successful, NOK otherwise.\n 318 */ 319 TI_STATUS scanConcentratorAppSM_abortScan( TI_HANDLE hScanCncn ) 320 { 321 scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn; 322 323 WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, 324 ("APP SM: aborting scan.\n") ); 325 326 /* call the scan SRV stop scan. Whether to exit driver mode depends on the connection status 327 (scan when not connected or in IBSS does not request PS) and on the flag set by the 328 scan concentrator API functions (abort or stop)*/ 329 if ( pScanConcentrator->connectionStatus != STA_CONNECTED ) 330 { 331 MacServices_scanSRV_stopScan( pScanConcentrator->hMacServices, FALSE , NULL , NULL ); 332 } 333 else 334 { 335 BOOLEAN bSendNullData = (pScanConcentrator->bAbortOrStop == SCAN_CNCN_STOP) ? TRUE : FALSE; 336 MacServices_scanSRV_stopScan( pScanConcentrator->hMacServices, bSendNullData, NULL , NULL ); 337 } 338 339 return OK; 340 } 341 342 /** 343 * \author Ronen Kalish\n 344 * \date 02-Jan-2005\n 345 * \brief SM action - handles a scan complete event (releases the SCR and call the scan complete CB) 346 * 347 * Function Scope \e Public.\n 348 * \param hScanCncn - handle to the scan concentrator object.\n 349 * \return OK if successful, NOK otherwise.\n 350 */ 351 TI_STATUS scanConcentratorAppSM_scanComplete( TI_HANDLE hScanCncn ) 352 { 353 scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn; 354 355 WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, 356 ("APP SM: Scan is complete.\n") ); 357 358 /* unregister at the MLME for scan result frames */ 359 mlmeParser_unregisterForBeaconAndProbeResp( pScanConcentrator->hMlme ); 360 361 /* mark that this scan is no longer running */ 362 pScanConcentrator->currentRunningScanClient = SCAN_SCC_NO_CLIENT; 363 364 /* release the SCR with the client ID used for request */ 365 scr_clientComplete( pScanConcentrator->hSCR, SCR_CID_APP_SCAN ); 366 367 /* notify the scan complete to the scan mngr */ 368 if ( FALSE == pScanConcentrator->bInRequest ) 369 { 370 pScanConcentrator->scanResultCB[ SCAN_SCC_APP ]( pScanConcentrator->scanResultCBObj[ SCAN_SCC_APP ], 371 pScanConcentrator->scanResult[ SCAN_SCC_APP ], 372 NULL, 0xffff ); 373 } 374 375 return OK; 376 } 377 378 /** 379 * \author Ronen Kalish\n 380 * \date 10-July-2005\n 381 * \brief SM action - handles a recovery event (calls the scan SRV abort on FW reset and than finishes scan) 382 * 383 * Function Scope \e Public.\n 384 * \param hScanCncn - handle to the scan concentrator object.\n 385 * \return OK if successful, NOK otherwise.\n 386 */ 387 TI_STATUS scanConcentratorAppSM_recoveryDuringScan( TI_HANDLE hScanCncn ) 388 { 389 scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn; 390 391 WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, 392 ("APP SM: Recovery occured!.\n") ); 393 394 /* reset the scan SRV */ 395 MacServices_scanSRV_stopOnFWReset( pScanConcentrator->hMacServices ); 396 397 /* send a scan complete event to the SM */ 398 return scanConcentratorAppSM_SMEvent( hScanCncn, 399 (scan_appSMStates_e*)&(pScanConcentrator->clientSMState[ SCAN_SCC_APP ]), 400 APP_SCAN_EVENT_SCAN_COMPLETE ); 401 } 402 403 /** 404 * \author Ronen Kalish\n 405 * \date 02-Jan-2005\n 406 * \brief SM action - handles a scan reject event (abort scan before scan actually started)\n 407 * 408 * Function Scope \e Public.\n 409 * \param hScanCncn - handle to the scan concentrator object.\n 410 * \return OK if successful, NOK otherwise.\n 411 */ 412 TI_STATUS scanConcentratorAppSM_scanRejected( TI_HANDLE hScanCncn ) 413 { 414 scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn; 415 416 WLAN_REPORT_INFORMATION( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, 417 ("APP SM: Scan is rejected.\n") ); 418 419 /* release the SCR with the client ID used for request */ 420 scr_clientComplete( pScanConcentrator->hSCR, SCR_CID_APP_SCAN ); 421 422 /* notify the scan complete to the scan mngr */ 423 if ( FALSE == pScanConcentrator->bInRequest ) 424 { 425 pScanConcentrator->scanResultCB[ SCAN_SCC_APP ]( pScanConcentrator->scanResultCBObj[ SCAN_SCC_APP ], 426 pScanConcentrator->scanResult[ SCAN_SCC_APP ], 427 NULL, 0xffff ); 428 } 429 430 return OK; 431 } 432 433 /** 434 * \author Ronen Kalish\n 435 * \date 11-Jan-2005\n 436 * \brief Handles an unexpected event.\n 437 * 438 * Function Scope \e Private.\n 439 * \param hScanCncn - handle to the scan concentrator object.\n 440 * \return always OK.\n 441 */ 442 TI_STATUS actionUnexpected( TI_HANDLE hScanCncn ) 443 { 444 scanConcentrator_t* pScanConcentrator = (scanConcentrator_t*)hScanCncn; 445 446 WLAN_REPORT_ERROR( pScanConcentrator->hReport, SCAN_CNCN_MODULE_LOG, 447 ("Application scan state machine error, unexpected Event, state=%d\n\n", 448 pScanConcentrator->clientSMState[SCAN_SCC_APP]) ); 449 450 return OK; 451 } 452 453 /** 454 * \author Ronen Kalish\n 455 * \date 10-Jan-2005\n 456 * \brief Handles an event that doesn't require any action.\n 457 * 458 * Function Scope \e Private.\n 459 * \param hScanCncn - handle to the scan concentrator object.\n 460 * \return always OK.\n 461 */ 462 TI_STATUS actionNop( TI_HANDLE hScanCncn ) 463 { 464 return OK; 465 } 466 467