TWD/MacServices/ScanSrvSM.c
changeset 0 10c42ec6c05f
equal deleted inserted replaced
-1:000000000000 0:10c42ec6c05f
       
     1 /*
       
     2  * ScanSrvSM.c
       
     3  *
       
     4  * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved.      
       
     5  * All rights reserved.      
       
     6  * 
       
     7  * This program and the accompanying materials are made available under the 
       
     8  * terms of the Eclipse Public License v1.0 or BSD License which accompanies
       
     9  * this distribution. The Eclipse Public License is available at
       
    10  * http://www.eclipse.org/legal/epl-v10.html and the BSD License is as below.                                   
       
    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 /** \file ScanSrvSM.c
       
    40  *  \brief This file include the scan SRV Sm implementation
       
    41  *  \author Ronen Kalish
       
    42  *  \date 10-Jan-2005 
       
    43  */
       
    44 
       
    45 #define __FILE_ID__  FILE_ID_116
       
    46 #include "ScanSrvSM.h"
       
    47 #include "ScanSrv.h"
       
    48 #include "report.h"
       
    49 #include "timer.h"
       
    50 #include "MacServices_api.h"
       
    51 #include "PowerSrv_API.h"
       
    52 #include "CmdBld.h"
       
    53 
       
    54 
       
    55 /********************************************************************************/
       
    56 /*                      Internal functions prototypes.                          */
       
    57 /********************************************************************************/
       
    58 
       
    59 static TI_STATUS scanSRVSM_PsFailWhileScanning( TI_HANDLE hScanSrv );
       
    60 static TI_STATUS actionNop( TI_HANDLE hScanSrv );
       
    61 static TI_STATUS actionUnexpected( TI_HANDLE hScanSrv );
       
    62 
       
    63 
       
    64 /********************************************************************************/
       
    65 /*                      Interface functions Implementation.                     */
       
    66 /********************************************************************************/
       
    67 
       
    68 
       
    69 /**
       
    70  * \author Ronen Kalish\n
       
    71  * \date 10-Jan-2005\n
       
    72  * \brief Initialize the scan SRV SM.
       
    73  *
       
    74  * Function Scope \e Public.\n
       
    75  * \param hScanSrv - handle to the scan SRV object.\n
       
    76  * \return TI_OK if successful, TI_NOK otherwise.\n
       
    77  */
       
    78 TI_STATUS scanSRVSM_init( TI_HANDLE hScanSrv )
       
    79 {
       
    80     scanSRV_t* pScanSRV = (scanSRV_t*)hScanSrv;
       
    81 
       
    82     fsm_actionCell_t    smMatrix[ SCAN_SRV_NUM_OF_STATES ][ SCAN_SRV_NUM_OF_EVENTS ] =
       
    83     {
       
    84         /* next state and actions for IDLE state */
       
    85         {   
       
    86             {SCAN_SRV_STATE_PS_WAIT, scanSRVSM_requestPS},                                /*"REQUEST_PS",*/
       
    87             {SCAN_SRV_STATE_IDLE, actionUnexpected},                                      /*"PS_FAIL",*/
       
    88             {SCAN_SRV_STATE_SCANNING, scanSRVSM_startActualScan},                         /*"PS_SUCCESS",  */
       
    89             {SCAN_SRV_STATE_IDLE, actionUnexpected},                                      /*"PS_PEND",*/
       
    90             {SCAN_SRV_STATE_IDLE, actionUnexpected},                                      /*"STOP_SCAN"*/
       
    91             {SCAN_SRV_STATE_IDLE, actionNop},                                             /*"FW_RESET"*/
       
    92             {SCAN_SRV_STATE_IDLE, actionUnexpected},                                      /*"TIMER_EXPIRED"*/
       
    93             {SCAN_SRV_STATE_IDLE, actionUnexpected},                                      /*"SCAN_COMPLETE"*/
       
    94         },
       
    95 
       
    96 
       
    97         /* next state and actions for PS_WAIT state */
       
    98         {   
       
    99             {SCAN_SRV_STATE_PS_WAIT, actionUnexpected},                                   /*"REQUEST_PS",*/
       
   100             {SCAN_SRV_STATE_PS_EXIT, scanSRVSM_releasePS},                                /*"PS_FAIL",*/
       
   101             {SCAN_SRV_STATE_SCANNING, scanSRVSM_startActualScan},                         /*"PS_SUCCESS",  */
       
   102             {SCAN_SRV_STATE_PS_WAIT, actionNop},                                          /*"PS_PEND",*/
       
   103             {SCAN_SRV_STATE_STOPPING, actionNop},                                         /*"STOP_SCAN"*/
       
   104             {SCAN_SRV_STATE_IDLE, scanSRVSM_handleRecovery},                              /*"FW_RESET"*/
       
   105             {SCAN_SRV_STATE_PS_WAIT, actionUnexpected},                                   /*"TIMER_EXPIRED"*/
       
   106             {SCAN_SRV_STATE_PS_WAIT, actionUnexpected},                                   /*"SCAN_COMPLETE"*/
       
   107         },
       
   108 
       
   109         /* next state and actions for SCANNING state */
       
   110         {    
       
   111             {SCAN_SRV_STATE_SCANNING, actionUnexpected},                                  /*"REQUEST_PS",*/
       
   112             {SCAN_SRV_STATE_SCANNING, scanSRVSM_PsFailWhileScanning},                     /*"PS_FAIL",*/
       
   113             {SCAN_SRV_STATE_SCANNING, actionUnexpected},                                  /*"PS_SUCCESS",  */
       
   114             {SCAN_SRV_STATE_SCANNING, actionUnexpected},                                  /*"PS_PEND",*/
       
   115             {SCAN_SRV_STATE_STOPPING, actionNop   },                                      /*"STOP_SCAN"*/
       
   116             {SCAN_SRV_STATE_IDLE, scanSRVSM_handleRecovery},                              /*"FW_RESET"*/
       
   117             {SCAN_SRV_STATE_SCANNING, scanSRVSM_handleTimerExpiry},                       /*"TIMER_EXPIRED"*/
       
   118             {SCAN_SRV_STATE_PS_EXIT, scanSRVSM_releasePS},                                /*"SCAN_COMPLETE"*/
       
   119 
       
   120         },
       
   121 
       
   122         /* next state and actions for STOPPING state */
       
   123         {   
       
   124             {SCAN_SRV_STATE_STOPPING, actionUnexpected},                                  /*"REQUEST_PS",*/
       
   125             {SCAN_SRV_STATE_PS_EXIT, scanSRVSM_releasePS},                                /*"PS_FAIL",*/
       
   126             {SCAN_SRV_STATE_PS_EXIT, scanSRVSM_releasePS},                                /*"PS_SUCCESS",  */
       
   127             {SCAN_SRV_STATE_STOPPING, actionUnexpected},                                  /*"PS_PEND",*/
       
   128             {SCAN_SRV_STATE_STOPPING, actionNop     },                                    /*"STOP_SCAN"*/
       
   129             {SCAN_SRV_STATE_IDLE, scanSRVSM_handleRecovery},                              /*"FW_RESET"*/
       
   130             {SCAN_SRV_STATE_STOPPING, scanSRVSM_handleTimerExpiry},                       /*"TIMER_EXPIRED"*/
       
   131             {SCAN_SRV_STATE_PS_EXIT, scanSRVSM_releasePS}                                 /*"SCAN_COMPLETE"*/
       
   132 
       
   133         } ,
       
   134 
       
   135         /* next state and actions for PS_EXIT state */
       
   136         {   
       
   137             {SCAN_SRV_STATE_PS_EXIT, actionUnexpected},                                   /*"REQUEST_PS",*/
       
   138             {SCAN_SRV_STATE_IDLE, scanSRVSM_notifyScanComplete},                          /*"PS_FAIL",*/
       
   139             {SCAN_SRV_STATE_IDLE, scanSRVSM_notifyScanComplete},                          /*"PS_SUCCESS",  */
       
   140             {SCAN_SRV_STATE_PS_EXIT, actionNop},                                          /*"PS_PEND",*/
       
   141             {SCAN_SRV_STATE_PS_EXIT, actionNop},                                          /*"STOP_SCAN"*/
       
   142             {SCAN_SRV_STATE_IDLE, scanSRVSM_handleRecovery},                              /*"FW_RESET"*/
       
   143             {SCAN_SRV_STATE_PS_EXIT, actionUnexpected},                                   /*"TIMER_EXPIRED"*/
       
   144             {SCAN_SRV_STATE_PS_EXIT, actionUnexpected},                                   /*"SCAN_COMPLETE"*/
       
   145         }
       
   146     };
       
   147 
       
   148     /* initialize current state */
       
   149     pScanSRV->SMState = SCAN_SRV_STATE_IDLE;
       
   150 
       
   151     /* configure the state machine */
       
   152     return fsm_Config( pScanSRV->SM, (fsm_Matrix_t)smMatrix, 
       
   153                        (TI_UINT8)SCAN_SRV_NUM_OF_STATES, (TI_UINT8)SCAN_SRV_NUM_OF_EVENTS, 
       
   154                        (fsm_eventActivation_t)scanSRVSM_SMEvent, pScanSRV->hOS );
       
   155 }
       
   156 
       
   157 /**
       
   158  * \author Ronen Kalish\n
       
   159  * \date 10-Jan-2005\n
       
   160  * \brief Processes an event.
       
   161  *
       
   162  * Function Scope \e Public.\n
       
   163  * \param hScanSrv - handle to the scan SRV object.\n
       
   164  * \param currentState - the current scan SRV SM state.\n
       
   165  * \param event - the event to handle.\n
       
   166  * \return TI_OK if successful, TI_NOK otherwise.\n
       
   167  */
       
   168 TI_STATUS scanSRVSM_SMEvent( TI_HANDLE hScanSrv, scan_SRVSMStates_e* currentState, 
       
   169                              scan_SRVSMEvents_e event )
       
   170 {
       
   171     scanSRV_t *pScanSRV = (scanSRV_t *)hScanSrv;
       
   172     TI_STATUS status = TI_OK;
       
   173     TI_UINT8 nextState;
       
   174 
       
   175     /* obtain the next state */
       
   176     status = fsm_GetNextState( pScanSRV->SM, *(TI_UINT8*)currentState, (TI_UINT8)event, &nextState );
       
   177     if ( status != TI_OK )
       
   178     {
       
   179         TRACE2(pScanSRV->hReport, REPORT_SEVERITY_ERROR, "Failed getting scan SRV next state. state = %d event = %d\n", (TI_UINT8)*currentState,(TI_UINT8)event);
       
   180         return TI_NOK;
       
   181     }
       
   182 
       
   183 	TRACE3(pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, "scanSRVSM_SMEvent: <currentState = %d, event = %d> --> nextState = %d\n", *currentState, event, nextState);
       
   184 
       
   185     /* move */
       
   186     return fsm_Event( pScanSRV->SM, (TI_UINT8*)currentState, (TI_UINT8)event, hScanSrv );
       
   187 }
       
   188 
       
   189 /**
       
   190  * \author Ronen Kalish\n
       
   191  * \date 10-Jan-2005\n
       
   192  * \brief Request to enter driver mode from the power manager module.\n
       
   193  *
       
   194  * Function Scope \e Private.\n
       
   195  * \param hScanSrv - handle to the scan SRV object.\n
       
   196  * \return TI_OK if successful, TI_NOK otherwise.\n
       
   197  */
       
   198 TI_STATUS scanSRVSM_requestPS( TI_HANDLE hScanSrv )
       
   199 {
       
   200     scanSRV_t *pScanSRV = (scanSRV_t*)hScanSrv;
       
   201     TI_STATUS psStatus;
       
   202 
       
   203     TRACE0( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, "Requesting Driver mode from PowerSave Srv.\n");
       
   204    
       
   205     psStatus = powerSrv_ReservePS(  pScanSRV->hPowerSrv,
       
   206                                     pScanSRV->psRequest,
       
   207                                     pScanSRV->bSendNullData,
       
   208                                     hScanSrv,
       
   209                                     MacServices_scanSRV_powerSaveCB);
       
   210 
       
   211     switch (psStatus)
       
   212     {
       
   213     /* if successful */
       
   214     case POWER_SAVE_802_11_IS_CURRENT:
       
   215         /* send a PS_SUCCESS event */
       
   216         TRACE0( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, "Driver mode successful, continuing to scan.\n");
       
   217         return scanSRVSM_SMEvent( hScanSrv, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_SUCCESS );
       
   218 
       
   219     /* if pending */
       
   220     case POWER_SAVE_802_11_PENDING:
       
   221     case TI_OK:
       
   222         /* send a PS_PEND event */
       
   223         TRACE0( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, "Driver mode pending, Waiting.\n");
       
   224         return scanSRVSM_SMEvent( hScanSrv, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_PEND );
       
   225 
       
   226     /* if not successful */
       
   227     default:
       
   228 
       
   229         /* mark not to exit from driver mode (no entry was performed) */
       
   230         pScanSRV->bExitFromDriverMode = TI_FALSE;
       
   231 
       
   232         /* if still wishing to scan */
       
   233         if ( pScanSRV->bScanOnDriverModeFailure )
       
   234         {
       
   235             /* send a PS_SUCCESS event - scan will proceed regardless of the error */
       
   236             TRACE0( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, "Driver mode failed, continuing to scan.\n");
       
   237             scanSRVSM_SMEvent( hScanSrv, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_SUCCESS );
       
   238         }
       
   239         /* otherwise, return */
       
   240         else
       
   241         {
       
   242             /* mark the return code */
       
   243             pScanSRV->returnStatus = TI_NOK;
       
   244             /* send a PS_FAIL event */
       
   245             TRACE0( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, "Driver mode failed, aborting scan.\n");
       
   246             scanSRVSM_SMEvent( hScanSrv, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_FAIL );
       
   247         }
       
   248         break;
       
   249     }
       
   250 
       
   251     return TI_OK;
       
   252 }
       
   253 
       
   254 /**
       
   255  * \date 6-Oct-2005\n
       
   256  * \brief Request to release PS mode from the PowerSRV , and wait for answer.\n\n
       
   257  *
       
   258  * Function Scope \e Private.\n
       
   259  * \param hScanSrv - handle to the scan SRV object.\n
       
   260  * \return TI_OK if successful, TI_NOK otherwise.\n
       
   261  */
       
   262 
       
   263 TI_STATUS scanSRVSM_releasePS( TI_HANDLE hScanSrv )
       
   264 {
       
   265       scanSRV_t *pScanSRV = (scanSRV_t*)hScanSrv;
       
   266       TI_STATUS psStatus;
       
   267     
       
   268      /* stop timer */
       
   269     if ( TI_TRUE == pScanSRV->bTimerRunning )
       
   270     {
       
   271         tmr_StopTimer (pScanSRV->hScanSrvTimer);
       
   272         pScanSRV->bTimerRunning = TI_FALSE;
       
   273     }
       
   274   
       
   275     /* if exit from driver mode requested, do so */
       
   276     if ( TI_TRUE == pScanSRV->bExitFromDriverMode )
       
   277     {
       
   278         /* here we need to get an answer if we succeeded to exit driver mode */
       
   279         TRACE0( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, ": Releasing Driver mode from Power Srv.\n");
       
   280  
       
   281         psStatus = powerSrv_ReleasePS(  pScanSRV->hPowerSrv,
       
   282                                 pScanSRV->bSendNullData,
       
   283                                 hScanSrv,
       
   284                                 MacServices_scanSRV_powerSaveCB);
       
   285 
       
   286 
       
   287     }
       
   288     else            /* no need to exit PS - send PS_SUCCESS */
       
   289     {
       
   290         return scanSRVSM_SMEvent( hScanSrv, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_SUCCESS );
       
   291     }
       
   292 
       
   293 
       
   294     switch (psStatus)
       
   295     {
       
   296         /* if successful */
       
   297     case POWER_SAVE_802_11_IS_CURRENT:
       
   298         /* send a PS_SUCCESS event */
       
   299         TRACE0( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, ": Driver mode exit successful, scan done.\n");
       
   300         return scanSRVSM_SMEvent( hScanSrv, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_SUCCESS );
       
   301         
       
   302         /* if pending */
       
   303     case POWER_SAVE_802_11_PENDING:
       
   304     case TI_OK:
       
   305         /* stay in the PS_EXIT state */
       
   306         TRACE0( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, ": Driver mode exit pending, Waiting.\n");
       
   307         break; 
       
   308         
       
   309         /* if not successful */
       
   310     default:
       
   311         
       
   312         /* send a PS_FAIL event */
       
   313         TRACE0( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, ": Driver mode exit failed, scan done.");
       
   314         return scanSRVSM_SMEvent( hScanSrv, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_PS_FAIL );
       
   315 
       
   316     }
       
   317 
       
   318     return TI_OK;
       
   319 }
       
   320 
       
   321 /**
       
   322  * \author Ronen Kalish\n
       
   323  * \date 10-Jan-2005\n
       
   324  * \brief Send the scan command to the firmware.\n
       
   325  *
       
   326  * Function Scope \e Private.\n
       
   327  * \param hScanSrv - handle to the scan SRV object.\n
       
   328  * \return TI_OK if successful, TI_NOK otherwise.\n
       
   329  */
       
   330 TI_STATUS scanSRVSM_startActualScan( TI_HANDLE hScanSrv )
       
   331 { 
       
   332     scanSRV_t *pScanSRV = (scanSRV_t*)hScanSrv;
       
   333 
       
   334  
       
   335     /* start the timer */
       
   336     pScanSRV->bTimerRunning = TI_TRUE;
       
   337     tmr_StartTimer (pScanSRV->hScanSrvTimer,
       
   338                     MacServices_scanSRV_scanTimerExpired,
       
   339                     (TI_HANDLE)pScanSRV,
       
   340                     MacServices_scanSRVcalculateScanTimeout (hScanSrv, pScanSRV->scanParams, !pScanSRV->bDtimOverlapping), 
       
   341                     TI_FALSE);
       
   342     
       
   343     TRACE1( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, "Sending scan , type: %x to HAL.\n",pScanSRV->scanParams->scanType);
       
   344     
       
   345     /* start the scan */
       
   346             /* we send the MacServices_scanSRVCommandMailBoxCB to be called when this command is recieved */
       
   347     if ( SCAN_TYPE_SPS == pScanSRV->scanParams->scanType )
       
   348     {
       
   349         pScanSRV->returnStatus = cmdBld_CmdStartSPSScan (pScanSRV->hCmdBld, pScanSRV->scanParams, pScanSRV->eScanTag,
       
   350                                                          (void *)MacServices_scanSRVCommandMailBoxCB, hScanSrv);
       
   351     }
       
   352     else
       
   353     {    
       
   354         pScanSRV->returnStatus = cmdBld_CmdStartScan (pScanSRV->hCmdBld, pScanSRV->scanParams, pScanSRV->eScanTag, 
       
   355                                                       pScanSRV->bHighPriority , (void *)MacServices_scanSRVCommandMailBoxCB, 
       
   356                                                       hScanSrv);
       
   357     }
       
   358     /* if scan request failed */
       
   359     if ( TI_OK != pScanSRV->returnStatus )
       
   360     {
       
   361         TRACE1( pScanSRV->hReport, REPORT_SEVERITY_ERROR, "HAL returned code %d for scan request, quitting scan.\n", pScanSRV->returnStatus);
       
   362 
       
   363         /* send a scan complete event. This will do all necessary clean-up (timer, power manager, notifying scan complete) */
       
   364         scanSRVSM_SMEvent( hScanSrv, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_SCAN_COMPLETE );
       
   365     }
       
   366     
       
   367     return TI_OK;
       
   368 }
       
   369 
       
   370 
       
   371 /**
       
   372  * \author Ronen Kalish\n
       
   373  * \date 10-Jan-2005\n
       
   374  * \brief Notifies scan complete to upper layer.\n
       
   375  *
       
   376  * Function Scope \e Private.\n
       
   377  * \param hScanSrv - handle to the scan SRV object.\n
       
   378  * \return TI_OK if successful, TI_NOK otherwise.\n
       
   379  */
       
   380 TI_STATUS scanSRVSM_notifyScanComplete( TI_HANDLE hScanSrv )
       
   381 {
       
   382     scanSRV_t *pScanSRV = (scanSRV_t*)hScanSrv;
       
   383     TCmdResponseCb CB_Func;
       
   384     TI_HANDLE  CB_Handle;
       
   385     TI_STATUS PSMode;
       
   386 
       
   387     /* call the scan complete CB - only if not currently running from within a request context! */
       
   388     if ( TI_FALSE == pScanSRV->bInRequest )
       
   389     {   
       
   390         /* this means that ResponseFunc was not called yet , so we call it before ScanComplete */
       
   391         if (pScanSRV->commandResponseFunc) 
       
   392         {
       
   393             /* must erase CB function before calling it to enable nested scans */
       
   394             CB_Func = pScanSRV->commandResponseFunc;
       
   395             CB_Handle = pScanSRV->commandResponseObj;
       
   396 
       
   397             pScanSRV->commandResponseFunc = NULL;
       
   398             pScanSRV->commandResponseObj = NULL;
       
   399             
       
   400             /* if we reached here than response status was TI_OK */
       
   401             CB_Func(CB_Handle, TI_OK);
       
   402              
       
   403         }
       
   404         /* if function returns TI_TRUE than we are in PS mode , else - not */
       
   405         PSMode = powerSrv_getPsStatus(pScanSRV->hPowerSrv) ? POWER_SAVE_802_11_SUCCESS : POWER_SAVE_802_11_FAIL;
       
   406 
       
   407         TRACE2( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, "scanSRVSM_notifyScanComplete status = 0x%x PSMode = 0x%x\n",pScanSRV->returnStatus,PSMode);
       
   408 
       
   409 
       
   410         TRACE0(pScanSRV->hReport, REPORT_SEVERITY_INFORMATION , "scanSRVSM_notifyScanComplete: call TWD_OWN_EVENT_SCAN_CMPLT CB. In std MacServices_scanSRV_scanCompleteCB()\n");
       
   411 
       
   412         pScanSRV->scanCompleteNotificationFunc( pScanSRV->scanCompleteNotificationObj,
       
   413                                     pScanSRV->eScanTag,
       
   414                                     pScanSRV->uResultCount,
       
   415                                     pScanSRV->SPSScanResult, 
       
   416                                     pScanSRV->bTSFError,
       
   417                                     pScanSRV->returnStatus, 
       
   418                                     PSMode );
       
   419     }
       
   420 
       
   421     return TI_OK;
       
   422 }
       
   423 
       
   424 
       
   425 /**
       
   426  * \author Ronen Kalish\n
       
   427  * \date 10-Jan-2005\n
       
   428  * \brief Handles a timer expiry event - starts a recovery process.
       
   429  *
       
   430  * Function Scope \e Private.\n
       
   431  * \param hScanSrv - handle to the scan SRV object.\n
       
   432  * \return TI_OK if successful, TI_NOK otherwise.\n
       
   433  */
       
   434 TI_STATUS scanSRVSM_handleTimerExpiry( TI_HANDLE hScanSrv )
       
   435 {
       
   436     scanSRV_t *pScanSRV = (scanSRV_t*)hScanSrv;
       
   437 
       
   438     /* 
       
   439      * No scan complete bug workaround:
       
   440      * Only after a consecutive configurable number of no scan complete events the recovery trigger
       
   441      * will be issued. This is done as a workaround for a bug in the FW where if a channel is too
       
   442      * loaded it wouldn't be able to send a probe request and will get stuck waiting for this channel
       
   443      */
       
   444 
       
   445     pScanSRV->currentNumberOfConsecutiveNoScanCompleteEvents++;
       
   446 
       
   447     if ( pScanSRV->currentNumberOfConsecutiveNoScanCompleteEvents >= 
       
   448          pScanSRV->numberOfNoScanCompleteToRecovery )
       
   449     {
       
   450         TRACE0( pScanSRV->hReport, REPORT_SEVERITY_ERROR, ": Timer expired. Starting recovery process.\n");
       
   451 
       
   452         pScanSRV->currentNumberOfConsecutiveNoScanCompleteEvents = 0;
       
   453 
       
   454         /* mark the return status */
       
   455         pScanSRV->returnStatus = TI_NOK;
       
   456 
       
   457         /* mark that the timer is no longer running */
       
   458         pScanSRV->bTimerRunning = TI_FALSE;
       
   459 
       
   460         /* call the recovery module */
       
   461         pScanSRV->failureEventFunc(pScanSRV->failureEventObj ,NO_SCAN_COMPLETE_FAILURE);
       
   462     }
       
   463     else
       
   464     {
       
   465         TRACE2( pScanSRV->hReport, REPORT_SEVERITY_ERROR, ": Timer expired. consecutive failures:%d, threshold:%d, still not calling recovery.\n", pScanSRV->currentNumberOfConsecutiveNoScanCompleteEvents, pScanSRV->numberOfNoScanCompleteToRecovery);
       
   466 
       
   467         /* send a top scan command, which can help solving the FW bug described above */
       
   468         if ( TI_FALSE == pScanSRV->bSPSScan )
       
   469         {
       
   470             cmdBld_CmdStopScan (pScanSRV->hCmdBld, pScanSRV->eScanTag, NULL, NULL);
       
   471         }
       
   472         else
       
   473         {
       
   474             cmdBld_CmdStopSPSScan (pScanSRV->hCmdBld, pScanSRV->eScanTag, NULL, NULL);
       
   475         }
       
   476 
       
   477         /* imitate a scan complete event to the SM */
       
   478         pScanSRV->bTSFError = TI_FALSE;
       
   479         pScanSRV->SPSScanResult = 0xffff;
       
   480         scanSRVSM_SMEvent( (TI_HANDLE)pScanSRV, (scan_SRVSMStates_e*)&pScanSRV->SMState, SCAN_SRV_EVENT_SCAN_COMPLETE );
       
   481     }
       
   482 
       
   483     return TI_OK;
       
   484 }
       
   485 
       
   486 /**
       
   487  * \author Shirit Brook\n
       
   488  * \date 10-Jan-2005\n
       
   489  * \brief Handles PS Fail event while in Scanning - Indicate not to Exit PS.
       
   490  * This event can be reached when Roaming is invoked while in Scanning state.
       
   491  * The PM Module is stopped and generates PS Fail to all its clients.
       
   492  *
       
   493  * Function Scope \e Private.\n
       
   494  * \param hScanSrv - handle to the scan SRV object.\n
       
   495  * \return TI_OK if successful, TI_NOK otherwise.\n
       
   496  */
       
   497 static TI_STATUS scanSRVSM_PsFailWhileScanning( TI_HANDLE hScanSrv )
       
   498 {
       
   499     scanSRV_t *pScanSRV = (scanSRV_t*)hScanSrv;
       
   500 
       
   501     TRACE0( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, "scanSRVSM_PsFailWhileScanning. Indicate not to Enter PS.\n");
       
   502 
       
   503     pScanSRV->bExitFromDriverMode = TI_FALSE;
       
   504 
       
   505     return TI_OK;
       
   506 }
       
   507 
       
   508 
       
   509 /**
       
   510  * \author Ronen Kalish\n
       
   511  * \date 17-Jan-2005\n
       
   512  * \brief Handles a FW reset event (one that was detected outside the scan SRV) by stopping the timer.
       
   513  *
       
   514  * Function Scope \e Private.\n
       
   515  * \param hScanSrv - handle to the scan SRV object.\n
       
   516  * \return TI_OK if successful, TI_NOK otherwise.\n
       
   517  */
       
   518 TI_STATUS scanSRVSM_handleRecovery( TI_HANDLE hScanSrv )
       
   519 {
       
   520     scanSRV_t *pScanSRV = (scanSRV_t*)hScanSrv;
       
   521 
       
   522     TRACE0( pScanSRV->hReport, REPORT_SEVERITY_INFORMATION, "FW reset event from outside.\n");
       
   523  
       
   524     /* The Power Manager is responsible to exit PS mode in recovery. Also, the scan CB is not called - 
       
   525        The SCR is responsible to notify scan concentrator of the event (which actually notifies scan SRV */
       
   526 
       
   527     /* if timer is running - stop it */
       
   528     if ( TI_TRUE == pScanSRV->bTimerRunning )
       
   529     {
       
   530         tmr_StopTimer (pScanSRV->hScanSrvTimer);
       
   531         pScanSRV->bTimerRunning = TI_FALSE;
       
   532     }
       
   533     else
       
   534     {
       
   535         /* shouldn't happen - only called if timer is supposedly running */
       
   536         TRACE1( pScanSRV->hReport, REPORT_SEVERITY_WARNING, "SM: External FW reset in state %d and timer is not running?", pScanSRV->SMState);
       
   537     }
       
   538 
       
   539     return TI_OK;
       
   540 }
       
   541 
       
   542 /**
       
   543  * \author Ronen Kalish\n
       
   544  * \date 11-Jan-2005\n
       
   545  * \brief Handles an unexpected event.\n
       
   546  *
       
   547  * Function Scope \e Private.\n
       
   548  * \param hScanSrv - handle to the scan SRV object.\n
       
   549  * \return always TI_OK.\n
       
   550  */
       
   551 static TI_STATUS actionUnexpected( TI_HANDLE hScanSrv ) 
       
   552 {
       
   553     scanSRV_t *pScanSRV = (scanSRV_t*)hScanSrv;
       
   554 
       
   555     TRACE1( pScanSRV->hReport, REPORT_SEVERITY_ERROR, "Scan SRV state machine error, unexpected Event, state=%d\n\n", pScanSRV->SMState);
       
   556 
       
   557     if ( pScanSRV->bTimerRunning )
       
   558     {
       
   559         tmr_StopTimer (pScanSRV->hScanSrvTimer);
       
   560         pScanSRV->bTimerRunning = TI_FALSE;
       
   561     }
       
   562 
       
   563     /* we must clean the old command response CB since they are no longer relevant 
       
   564       since the state machine may be corrupted */
       
   565     pScanSRV->commandResponseFunc = NULL;
       
   566     pScanSRV->commandResponseObj = NULL;
       
   567 
       
   568     /* indicate the unexpected event in the return status */
       
   569     pScanSRV->returnStatus = TI_NOK;
       
   570     
       
   571     return TI_OK;
       
   572 }
       
   573 
       
   574 /**
       
   575  * \author Ronen Kalish\n
       
   576  * \date 10-Jan-2005\n
       
   577  * \brief Handles an event that doesn't require any action.\n
       
   578  *
       
   579  * Function Scope \e Private.\n
       
   580  * \param hScanSrv - handle to the scan SRV object.\n
       
   581  * \return always TI_OK.\n
       
   582  */
       
   583 static TI_STATUS actionNop( TI_HANDLE hScanSrv )
       
   584 {   
       
   585     return TI_OK;
       
   586 }
       
   587 
       
   588