diff -r 000000000000 -r 10c42ec6c05f TWD/MacServices/MeasurementSrvSM.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TWD/MacServices/MeasurementSrvSM.c Tue Jun 29 12:34:26 2010 +0100 @@ -0,0 +1,1068 @@ +/* + * MeasurementSrvSM.c + * + * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved. + * All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 or BSD License which accompanies + * this distribution. The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html and the BSD License is as below. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Texas Instruments nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** \file measurementSrv.c + * \brief This file include the measurement SRV state machine implementation. + * \author Ronen Kalish + * \date 13-November-2005 + */ + +#define __FILE_ID__ FILE_ID_112 +#include "osApi.h" +#include "report.h" +#include "MeasurementSrvSM.h" +#include "MeasurementSrv.h" +#include "PowerSrv_API.h" +#include "timer.h" +#include "fsm.h" +#include "TWDriverInternal.h" +#include "CmdBld.h" + + +TI_STATUS actionUnexpected( TI_HANDLE hMeasurementSrv ); +TI_STATUS actionNop( TI_HANDLE hMeasurementSrv ); +static void measurementSRVSM_requestMeasureStartResponseCB(TI_HANDLE hMeasurementSRV, TI_UINT16 uMboxStatus); + + +/** + * \author Ronen Kalish\n + * \date 08-November-2005\n + * \brief Initialize the measurement SRV SM.\n + * + * Function Scope \e Public.\n + * \param hMeasurementSrv - handle to the Measurement SRV object.\n + * \return TI_OK if successful, TI_NOK otherwise.\n + */ +TI_STATUS measurementSRVSM_init( TI_HANDLE hMeasurementSRV ) +{ + measurementSRV_t* pMeasurementSRV = (measurementSRV_t*)hMeasurementSRV; + + fsm_actionCell_t smMatrix[ MSR_SRV_NUM_OF_STATES ][ MSR_SRV_NUM_OF_EVENTS ] = + { + /* next state and actions for IDLE state */ + { + {MSR_SRV_STATE_WAIT_FOR_DRIVER_MODE, measurementSRVSM_requestDriverMode}, /*"MESSURE_START_REQUEST"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"DRIVER_MODE_SUCCESS"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"DRIVER_MODE_FAILURE"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"START_SUCCESS"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"START_FAILURE"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"ALL_TYPES_COMPLETE"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"STOP_COMPLETE"*/ + {MSR_SRV_STATE_IDLE, measurementSRVSRVSM_dummyStop} /*"MEASURE_STOP_REQUEST"*/ + }, + + + /* next state and actions for WAIT_FOR_DRIVER_MODE state */ + { + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"MESSURE_START_REQUEST"*/ + {MSR_SRV_STATE_WAIT_FOR_MEASURE_START, measurementSRVSM_requestMeasureStart}, /*"DRIVER_MODE_SUCCESS"*/ + {MSR_SRV_STATE_IDLE, measurementSRVSM_DriverModeFailure}, /*"DRIVER_MODE_FAILURE"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"START_SUCCESS"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"START_FAILURE"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"ALL_TYPES_COMPLETE"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"STOP_COMPLETE"*/ + {MSR_SRV_STATE_IDLE, measurementSRVSM_stopFromWaitForDriverMode} /*"MEASURE_STOP_REQUEST"*/ + }, + + /* next state and actions for WAIT_FOR_MEASURE_START state */ + { + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"MESSURE_START_REQUEST"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"DRIVER_MODE_SUCCESS"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"DRIVER_MODE_FAILURE"*/ + {MSR_SRV_STATE_MEASURE_IN_PROGRESS, measurementSRVSM_startMeasureTypes}, /*"START_SUCCESS"*/ + {MSR_SRV_STATE_IDLE, measurementSRVSM_measureStartFailure}, /*"START_FAILURE"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"ALL_TYPES_COMPLETE"*/ + {MSR_SRV_STATE_IDLE, measurementSRVSM_completeMeasure}, /*"STOP_COMPLETE"*/ + {MSR_SRV_STATE_WAIT_FOR_MEASURE_STOP, measurementSRVSM_stopFromWaitForMeasureStart} + /*"MEASURE_STOP_REQUEST"*/ + }, + + /* next state and actions for MEASURE_IN_PROGRESS state */ + { + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"MESSURE_START_REQUEST"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"DRIVER_MODE_SUCCESS"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"DRIVER_MODE_FAILURE"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"START_SUCCESS"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"START_FAILURE"*/ + {MSR_SRV_STATE_WAIT_FOR_MEASURE_STOP, measurementSRVSM_requestMeasureStop}, /*"ALL_TYPES_COMPLETE"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"STOP_COMPLETE"*/ + {MSR_SRV_STATE_WAIT_FOR_MEASURE_STOP, measurementSRVSM_stopFromMeasureInProgress} + /*"MEASURE_STOP_REQUEST"*/ + }, + + /* next state and actions for WAIT_FOR_MEASURE_STOP state */ + { + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"MESSURE_START_REQUEST"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"DRIVER_MODE_SUCCESS"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"DRIVER_MODE_FAILURE"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"START_SUCCESS"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"START_FAILURE"*/ + {MSR_SRV_STATE_IDLE, actionUnexpected}, /*"ALL_TYPES_COMPLETE"*/ + {MSR_SRV_STATE_IDLE, measurementSRVSM_completeMeasure}, /*"STOP_COMPLETE"*/ + {MSR_SRV_STATE_WAIT_FOR_MEASURE_STOP, measurementSRVSRVSM_dummyStop} /*"MEASURE_STOP_REQUEST"*/ + } + }; + + /* initialize current state */ + pMeasurementSRV->SMState = MSR_SRV_STATE_IDLE; + + /* configure the state machine */ + return fsm_Config( pMeasurementSRV->SM, (fsm_Matrix_t)smMatrix, + (TI_UINT8)MSR_SRV_NUM_OF_STATES, (TI_UINT8)MSR_SRV_NUM_OF_EVENTS, + (fsm_eventActivation_t)measurementSRVSM_SMEvent, pMeasurementSRV->hOS ); +} + +/** + * \author Ronen Kalish\n + * \date 08-November-2005\n + * \brief Processes an event.\n + * + * Function Scope \e Public.\n + * \param hMeasurementSrv - handle to the measurement SRV object.\n + * \param currentState - the current scan SRV SM state.\n + * \param event - the event to handle.\n + * \return TI_OK if successful, TI_NOK otherwise.\n + */ +TI_STATUS measurementSRVSM_SMEvent( TI_HANDLE hMeasurementSrv, measurements_SRVSMStates_e* currentState, + measurement_SRVSMEvents_e event ) +{ + measurementSRV_t *pMeasurementSRV = (measurementSRV_t *)hMeasurementSrv; + TI_STATUS status = TI_OK; + TI_UINT8 nextState; + + /* obtain the next state */ + status = fsm_GetNextState( pMeasurementSRV->SM, (TI_UINT8)*currentState, (TI_UINT8)event, &nextState ); + if ( status != TI_OK ) + { + TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, "measurementSRVSM_SMEvent: State machine error, failed getting next state\n"); + return TI_NOK; + } + + /* report the move */ + TRACE3( pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, "measurementSRVSM_SMEvent: --> nextState = %d\n", currentState, event, nextState); + + /* move */ + return fsm_Event( pMeasurementSRV->SM, (TI_UINT8*)currentState, (TI_UINT8)event, hMeasurementSrv ); +} + +/** + * \author Ronen Kalish\n + * \date 08-November-2005\n + * \brief Handle a MEASURE_START_REQUEST event by requesting driver mode.\n + * + * Function Scope \e Public.\n + * \param hMeasurementSrv - handle to the Measurement SRV object.\n + * \return always TI_OK.\n + */ +TI_STATUS measurementSRVSM_requestDriverMode( TI_HANDLE hMeasurementSRV ) +{ + measurementSRV_t *pMeasurementSRV = (measurementSRV_t*)hMeasurementSRV; + TI_STATUS PSStatus; + TTwdParamInfo paramInfo; + + /* get the current channel */ + paramInfo.paramType = TWD_CURRENT_CHANNEL_PARAM_ID; + cmdBld_GetParam (pMeasurementSRV->hCmdBld, ¶mInfo); + + /* check if the request is on the serving channel */ + if ( paramInfo.content.halCtrlCurrentChannel == pMeasurementSRV->msrRequest.channel ) + { + /* Switch Power Save SRV to driver mode w/o changing power save mode*/ + PSStatus = powerSrv_ReservePS( pMeasurementSRV->hPowerSaveSRV, POWER_SAVE_KEEP_CURRENT, + TI_TRUE, hMeasurementSRV, MacServices_measurementSRV_powerSaveCB ); + } + else + { + /* Switch Power Save SRV to driver mode with PS mode */ + PSStatus = powerSrv_ReservePS( pMeasurementSRV->hPowerSaveSRV, POWER_SAVE_ON, + TI_TRUE, hMeasurementSRV, MacServices_measurementSRV_powerSaveCB ); + } + + switch (PSStatus) + { + case POWER_SAVE_802_11_IS_CURRENT: + TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, ": Driver mode entered successfully\n"); + /* send a power save success event */ + return measurementSRVSM_SMEvent( hMeasurementSRV, &(pMeasurementSRV->SMState), + MSR_SRV_EVENT_DRIVER_MODE_SUCCESS ); + + case POWER_SAVE_802_11_PENDING: + case TI_OK: + TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, ": Driver mode pending\n"); + break; + + default: /* Error */ + TRACE1( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": Error %d when requesting driver mode\n",PSStatus); + + /* Set the return status to TI_NOK */ + pMeasurementSRV->returnStatus = PSStatus; + + /* send a power save failure event */ + measurementSRVSM_SMEvent( hMeasurementSRV, &(pMeasurementSRV->SMState), + MSR_SRV_EVENT_DRIVER_MODE_FAILURE ); + break; + } + + return TI_OK; +} + +/** + * \author Ronen Kalish\n + * \date 08-November-2005\n + * \brief Handle a DRIVER_MODE_SUCCESS event by sending start measure command to the FW.\n + * + * Function Scope \e Public.\n + * \param hMeasurementSrv - handle to the Measurement SRV object.\n + * \return always TI_OK.\n + */ +TI_STATUS measurementSRVSM_requestMeasureStart( TI_HANDLE hMeasurementSRV ) +{ + measurementSRV_t *pMeasurementSRV = (measurementSRV_t*)hMeasurementSRV; + TMeasurementParams pMeasurementCmd; + TI_STATUS status; + TI_UINT32 currentTime = os_timeStampMs( pMeasurementSRV->hOS ); + + /* check if request time has expired (note: timer wrap-around is also handled)*/ + if ( (pMeasurementSRV->requestRecptionTimeStampMs + pMeasurementSRV->timeToRequestExpiryMs) + < currentTime ) + { + TI_INT32 i; + + TRACE2( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": request time has expired, request expiry time:%d, current time:%d\n", pMeasurementSRV->requestRecptionTimeStampMs + pMeasurementSRV->timeToRequestExpiryMs, currentTime); + + /* mark that all measurement types has failed */ + for ( i = 0; i < pMeasurementSRV->msrRequest.numberOfTypes; i++ ) + { + pMeasurementSRV->msrReply.msrTypes[ i ].status = TI_NOK; + } + + /* send a measurement complete event */ + measurementSRVSM_SMEvent( hMeasurementSRV, &(pMeasurementSRV->SMState), + MSR_SRV_EVENT_STOP_COMPLETE ); + + return TI_OK; + } + + pMeasurementCmd.channel = pMeasurementSRV->msrRequest.channel; + pMeasurementCmd.band = pMeasurementSRV->msrRequest.band; + pMeasurementCmd.duration = 0; /* Infinite */ + pMeasurementCmd.eTag = pMeasurementSRV->msrRequest.eTag; + + if ( measurementSRVIsBeaconMeasureIncluded( hMeasurementSRV )) + { /* Beacon Measurement is one of the types */ + + /* get the current channel */ + TTwdParamInfo paramInfo; + + paramInfo.paramType = TWD_CURRENT_CHANNEL_PARAM_ID; + cmdBld_GetParam (pMeasurementSRV->hCmdBld, ¶mInfo); + + pMeasurementCmd.ConfigOptions = RX_CONFIG_OPTION_FOR_MEASUREMENT; + + /* check if the request is on the serving channel */ + if ( paramInfo.content.halCtrlCurrentChannel == pMeasurementSRV->msrRequest.channel ) + { + /* Set the RX Filter to the join one, so that any packets will + be received on the serving channel - beacons and probe requests for + the measurmenet, and also data (for normal operation) */ + pMeasurementCmd.FilterOptions = RX_FILTER_OPTION_JOIN; + } + else + { + /* not on the serving channle - only beacons and rpobe responses are required */ + pMeasurementCmd.FilterOptions = RX_FILTER_OPTION_DEF_PRSP_BCN; + } + } + else + { /* No beacon measurement - use the current RX Filter */ + pMeasurementCmd.ConfigOptions = 0xffffffff; + pMeasurementCmd.FilterOptions = 0xffffffff; + } + + /* Send start measurement command */ + status = cmdBld_CmdMeasurement (pMeasurementSRV->hCmdBld, + &pMeasurementCmd, + (void *)measurementSRVSM_requestMeasureStartResponseCB, + pMeasurementSRV); + + if ( TI_OK != status ) + { + TRACE1( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": Failed to send measurement start command, statud=%d,\n", status); + + /* keep the faulty return status */ + pMeasurementSRV->returnStatus = status; + + /* send a measurement start fail event */ + return measurementSRVSM_SMEvent( hMeasurementSRV, &(pMeasurementSRV->SMState), + MSR_SRV_EVENT_START_FAILURE ); + } + + TRACE6( pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, ": measure start command sent. Params:\n channel=%d, band=%d, duration=%d, \n configOptions=0x%x, filterOptions=0x%x, status=%d, \n", pMeasurementCmd.channel, pMeasurementCmd.band, pMeasurementCmd.duration, pMeasurementCmd.ConfigOptions, pMeasurementCmd.FilterOptions, status); + + /* start the FW guard timer */ + pMeasurementSRV->bStartStopTimerRunning = TI_TRUE; + tmr_StartTimer (pMeasurementSRV->hStartStopTimer, + MacServices_measurementSRV_startStopTimerExpired, + (TI_HANDLE)pMeasurementSRV, + MSR_FW_GUARD_TIME, + TI_FALSE); + + return TI_OK; +} + +/** + * \author Ronen Kalish\n + * \date 08-November-2005\n + * \brief Handle a START_SUCCESS event by starting different measure types and setting timers.\n + * + * Function Scope \e Public.\n + * \param hMeasurementSrv - handle to the Measurement SRV object.\n + * \return always TI_OK.\n + */ +TI_STATUS measurementSRVSM_startMeasureTypes( TI_HANDLE hMeasurementSRV ) +{ + measurementSRV_t *pMeasurementSRV = (measurementSRV_t*)hMeasurementSRV; + TI_UINT8 requestIndex, rangeIndex; + TI_INT8 rangeUpperBound; + TTwdParamInfo tTwdParam; + TI_STATUS status; + TNoiseHistogram pNoiseHistParams; + TApDiscoveryParams pApDiscoveryParams; + TI_UINT32 currentTime = os_timeStampMs( pMeasurementSRV->hOS ); + + /* check if request time has expired (note: timer wrap-around is also handled)*/ + if ( (pMeasurementSRV->requestRecptionTimeStampMs + pMeasurementSRV->timeToRequestExpiryMs) + < currentTime ) + { + TI_INT32 i; + + TRACE2( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": request time has expired, request expiry time:%d, current time:%d\n", pMeasurementSRV->requestRecptionTimeStampMs + pMeasurementSRV->timeToRequestExpiryMs, currentTime); + + /* mark that all measurement types has failed */ + for ( i = 0; i < pMeasurementSRV->msrRequest.numberOfTypes; i++ ) + { + pMeasurementSRV->msrReply.msrTypes[ i ].status = MSR_REJECT_MAX_DELAY_PASSED; + } + + /* send a measurement complete event */ + measurementSRVSM_SMEvent( hMeasurementSRV, &(pMeasurementSRV->SMState), + MSR_SRV_EVENT_ALL_TYPES_COMPLETE ); + + return TI_OK; + } + + /* Going over all request types that should be executed in parallel + to start their timers and execute the measurement */ + for ( requestIndex = 0; requestIndex < pMeasurementSRV->msrRequest.numberOfTypes ; requestIndex++ ) + { + switch (pMeasurementSRV->msrRequest.msrTypes[ requestIndex ].msrType) + { + case MSR_TYPE_CCA_LOAD_MEASUREMENT: + /* Clearing the Medium Occupancy Register */ + tTwdParam.paramType = TWD_MEDIUM_OCCUPANCY_PARAM_ID; + tTwdParam.content.interogateCmdCBParams.fCb = (void *)MacServices_measurementSRV_dummyChannelLoadParamCB; + tTwdParam.content.interogateCmdCBParams.hCb = hMeasurementSRV; + tTwdParam.content.interogateCmdCBParams.pCb = + (TI_UINT8*)&pMeasurementSRV->mediumOccupancyResults; + status = cmdBld_GetParam (pMeasurementSRV->hCmdBld, &tTwdParam); + if( TI_OK == status ) + { + TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, ": Medium Usage has been nullified, starting timer.\n"); + + /* Start Timer */ + tmr_StartTimer (pMeasurementSRV->hRequestTimer[requestIndex], + MacServices_measurementSRV_requestTimerExpired, + (TI_HANDLE)pMeasurementSRV, + pMeasurementSRV->msrRequest.msrTypes[requestIndex].duration, + TI_FALSE); + pMeasurementSRV->bRequestTimerRunning[requestIndex] = TI_TRUE; + } + else + { + TRACE1( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": TWD_GetParam (for channel load) returned status %d\n", status); + } + + break; + + case MSR_TYPE_NOISE_HISTOGRAM_MEASUREMENT: + /* Set Noise Histogram Cmd Params */ + pNoiseHistParams.cmd = START_NOISE_HIST; + pNoiseHistParams.sampleInterval = DEF_SAMPLE_INTERVAL; + os_memoryZero( pMeasurementSRV->hOS, &(pNoiseHistParams.ranges[0]), MEASUREMENT_NOISE_HISTOGRAM_NUM_OF_RANGES ); + + /* Set Ranges */ + /* (-87) - First Range's Upper Bound */ + rangeUpperBound = -87; + + /* Previously we converted from RxLevel to dBm - now this isn't necessary */ + /* rangeUpperBound = TWD_convertRSSIToRxLevel( pMeasurementSRV->hTWD, -87); */ + + for(rangeIndex = 0; rangeIndex < MEASUREMENT_NOISE_HISTOGRAM_NUM_OF_RANGES -1; rangeIndex++) + { + if(rangeUpperBound > 0) + { + pNoiseHistParams.ranges[rangeIndex] = 0; + } + else + { + pNoiseHistParams.ranges[rangeIndex] = rangeUpperBound; + } + rangeUpperBound += 5; + } + pNoiseHistParams.ranges[rangeIndex] = 0xFE; + + /* Print for Debug */ + TRACE8(pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, ":Noise histogram Measurement Ranges:\n%d %d %d %d %d %d %d %d\n", (TI_INT8) pNoiseHistParams.ranges[0], (TI_INT8) pNoiseHistParams.ranges[1], (TI_INT8) pNoiseHistParams.ranges[2], (TI_INT8) pNoiseHistParams.ranges[3], (TI_INT8) pNoiseHistParams.ranges[4], (TI_INT8) pNoiseHistParams.ranges[5], (TI_INT8) pNoiseHistParams.ranges[6], (TI_INT8) pNoiseHistParams.ranges[7]); + + /* Send a Start command to the FW */ + status = cmdBld_CmdNoiseHistogram (pMeasurementSRV->hCmdBld, &pNoiseHistParams, NULL, NULL); + + if ( TI_OK == status ) + { + /* Print for Debug */ + TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, ": Sent noise histogram command. Starting timer\n"); + + /* Start Timer */ + tmr_StartTimer (pMeasurementSRV->hRequestTimer[requestIndex], + MacServices_measurementSRV_requestTimerExpired, + (TI_HANDLE)pMeasurementSRV, + pMeasurementSRV->msrRequest.msrTypes[requestIndex].duration, + TI_FALSE); + pMeasurementSRV->bRequestTimerRunning[requestIndex] = TI_TRUE; + } + else + { + TRACE1( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": TWD_NoiseHistogramCmd returned status %d\n", status); + } + break; + + case MSR_TYPE_BEACON_MEASUREMENT: + /* set all parameters in the AP discovery command */ + pApDiscoveryParams.scanDuration = pMeasurementSRV->msrRequest.msrTypes[ requestIndex ].duration * 1000; + pApDiscoveryParams.numOfProbRqst = 1; + pApDiscoveryParams.txdRateSet = HW_BIT_RATE_1MBPS; + pApDiscoveryParams.ConfigOptions = RX_CONFIG_OPTION_FOR_MEASUREMENT; + pApDiscoveryParams.FilterOptions = RX_FILTER_OPTION_DEF_PRSP_BCN; + pApDiscoveryParams.txPowerDbm = pMeasurementSRV->msrRequest.txPowerDbm; + pApDiscoveryParams.scanOptions = SCAN_ACTIVE; /* both scan type and band are 0 for active and */ + /* 2.4 GHz, respectively, but 2.4 is not defined */ + + /* band determined at the initiate measurement command not at that structure */ + + /* scan mode go into the scan option field */ + if ( MSR_SCAN_MODE_PASSIVE == pMeasurementSRV->msrRequest.msrTypes[ requestIndex ].scanMode ) + { + pApDiscoveryParams.scanOptions |= SCAN_PASSIVE; + } + + /* Send AP Discovery command */ + status = cmdBld_CmdApDiscovery (pMeasurementSRV->hCmdBld, &pApDiscoveryParams, NULL, NULL); + + if ( TI_OK == status ) + { + TRACE7( pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, ": AP discovery command sent. Params:\n scanDuration=%d, scanOptions=%d, numOfProbRqst=%d, txdRateSet=%d, txPowerDbm=%d, configOptions=%d, filterOptions=%d\n Starting timer...\n", pApDiscoveryParams.scanDuration, pApDiscoveryParams.scanOptions, pApDiscoveryParams.numOfProbRqst, pApDiscoveryParams.txdRateSet, pApDiscoveryParams.txPowerDbm, pApDiscoveryParams.ConfigOptions, pApDiscoveryParams.FilterOptions); + + /* Start Timer */ + tmr_StartTimer (pMeasurementSRV->hRequestTimer[requestIndex], + MacServices_measurementSRV_requestTimerExpired, + (TI_HANDLE)pMeasurementSRV, + pMeasurementSRV->msrRequest.msrTypes[requestIndex].duration, + TI_FALSE); + pMeasurementSRV->bRequestTimerRunning[ requestIndex ] = TI_TRUE; + } + else + { + TRACE1( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": TWD_ApDiscoveryCmd returned status %d\n", status); + } + break; + + case MSR_TYPE_BASIC_MEASUREMENT: /* not supported in current implemntation */ + case MSR_TYPE_FRAME_MEASUREMENT: /* not supported in current implemntation */ + default: + TRACE1( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": Measurement type %d is not supported\n", pMeasurementSRV->msrRequest.msrTypes[ requestIndex ].msrType); + break; + } + } + + /* if no measurement types are running, sen al types complete event. + This can happen if all types failed to start */ + if ( TI_TRUE == measurementSRVIsMeasurementComplete( hMeasurementSRV )) + { + /* send the event */ + measurementSRVSM_SMEvent( hMeasurementSRV, &(pMeasurementSRV->SMState), + MSR_SRV_EVENT_ALL_TYPES_COMPLETE ); + } + + return TI_OK; +} + +/** + * \author Ronen Kalish\n + * \date 08-November-2005\n + * \brief Handle an ALL_TYPE_COMPLETE event by sending a stop measure command to the FW.\n + * + * Function Scope \e Public.\n + * \param hMeasurementSrv - handle to the Measurement SRV object.\n + * \return always TI_OK.\n + */ +TI_STATUS measurementSRVSM_requestMeasureStop( TI_HANDLE hMeasurementSRV ) +{ + measurementSRV_t* pMeasurementSRV = (measurementSRV_t*)hMeasurementSRV; + TI_STATUS status; + + /* since this function may also be called when stop is requested and start complete event + has not yet been received from the FW, we may need to stop the FW guard timer */ + if (pMeasurementSRV->bStartStopTimerRunning) + { + tmr_StopTimer (pMeasurementSRV->hStartStopTimer); + pMeasurementSRV->bStartStopTimerRunning = TI_FALSE; + } + + /* Send Measurement Stop command to the FW */ + status = cmdBld_CmdMeasurementStop (pMeasurementSRV->hCmdBld, + (void *)pMeasurementSRV->commandResponseCBFunc, + pMeasurementSRV->commandResponseCBObj); + + pMeasurementSRV->commandResponseCBFunc = NULL; + pMeasurementSRV->commandResponseCBObj = NULL; + + if ( TI_OK != status ) + { + TRACE1( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": Failed to send measurement stop command, statud=%d,\n", status); + + /* send a measurement complete event - since it can't be stopped */ + measurementSRVSM_SMEvent( hMeasurementSRV, &(pMeasurementSRV->SMState), MSR_SRV_EVENT_STOP_COMPLETE ); + return TI_OK; + } + + TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, ": measure stop command sent.\n"); + + /* start the FW guard timer */ + pMeasurementSRV->bStartStopTimerRunning = TI_TRUE; + tmr_StartTimer (pMeasurementSRV->hStartStopTimer, + MacServices_measurementSRV_startStopTimerExpired, + (TI_HANDLE)pMeasurementSRV, + MSR_FW_GUARD_TIME, + TI_FALSE); + + return TI_OK; +} + +/** + * \author Ronen Kalish\n + * \date 08-November-2005\n + * \brief Handle a STOP_COMPLETE event by exiting driver mode and calling the complete CB.\n + * + * Function Scope \e Public.\n + * \param hMeasurementSrv - handle to the Measurement SRV object.\n + * \return always TI_OK.\n + */ +TI_STATUS measurementSRVSM_completeMeasure( TI_HANDLE hMeasurementSRV ) +{ + measurementSRV_t *pMeasurementSRV = (measurementSRV_t *)hMeasurementSRV; + + /* Switch Power Save SRV back to user mode */ + powerSrv_ReleasePS( pMeasurementSRV->hPowerSaveSRV, pMeasurementSRV->bSendNullDataWhenExitPs, NULL, NULL ); + + /* if the response CB is still pending, call it (when requestExpiryTimeStamp was reached) */ + if ( NULL != pMeasurementSRV->commandResponseCBFunc ) + { + pMeasurementSRV->commandResponseCBFunc( pMeasurementSRV->commandResponseCBObj, TI_OK ); + } + + /* call the complete CB */ + if ( NULL != pMeasurementSRV->measurmentCompleteCBFunc ) + { + pMeasurementSRV->measurmentCompleteCBFunc( pMeasurementSRV->measurementCompleteCBObj, + &(pMeasurementSRV->msrReply)); + } + + return TI_OK; +} + +/** + * \author Ronen Kalish\n + * \date 08-November-2005\n + * \brief Handle a STOP_REQUEST event when in WAIT_FOR_DRIVER_MODE state by exiting driver mode. + * + * Function Scope \e Public.\n + * \param hMeasurementSrv - handle to the Measurement SRV object.\n + * \return always TI_OK.\n + */ +TI_STATUS measurementSRVSM_stopFromWaitForDriverMode( TI_HANDLE hMeasurementSRV ) +{ + measurementSRV_t* pMeasurementSRV = (measurementSRV_t*)hMeasurementSRV; + + /* Switch Power Save SRV back to user mode */ + powerSrv_ReleasePS( pMeasurementSRV->hPowerSaveSRV, pMeasurementSRV->bSendNullDataWhenExitPs, NULL, NULL ); + + /* if we are not running within a stop request context (shouldn't happen), call the CBs */ + if ( TI_FALSE == pMeasurementSRV->bInRequest ) + { + TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": stop from wait for driver mode: not within a request context?!? \n"); + + /* call the response CB - this shouldn't happen, as only GWSI has response CB, and it shouldn't call + stop before driver */ + if ( NULL != pMeasurementSRV->commandResponseCBFunc ) + { + TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": stop from wait for driver mode: command response CB is not NULL?!? \n"); + pMeasurementSRV->commandResponseCBFunc( pMeasurementSRV->commandResponseCBObj, TI_OK ); + + pMeasurementSRV->commandResponseCBFunc = NULL; + pMeasurementSRV->commandResponseCBObj = NULL; + } + /* call the complete CB */ + if ( NULL != pMeasurementSRV->measurmentCompleteCBFunc ) + { + /* mark that all types has failed */ + TI_INT32 i; + for ( i = 0; i < MAX_NUM_OF_MSR_TYPES_IN_PARALLEL; i++ ) + { + pMeasurementSRV->msrReply.msrTypes[ i ].status = TI_NOK; + } + /* call the complete CB */ + pMeasurementSRV->measurmentCompleteCBFunc( pMeasurementSRV->measurementCompleteCBObj, + &(pMeasurementSRV->msrReply)); + } + else + { + TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": stop from wait for driver mode and response CB is NULL!!!\n"); + } + } + /* we are within a stop request context */ + else + { + /* if the command response Cb is valid, send a measure stop command to the FW - + although it is not necessary, we need it to get a different context for the command response. + This shouldn't happen, as only GWSI has command response, and it shouldn't call stop measure + before it got the commadn response for start measure */ + if ( NULL != pMeasurementSRV->commandResponseCBFunc ) + { + /* shouldn't happen - a command response is valid (GWSI) and stop measure called + before measure start response was received (driver) */ + TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": stop from wait for driver mode - within request context and command response is not NULL?!?\n"); + + cmdBld_CmdMeasurementStop (pMeasurementSRV->hCmdBld, + (void *)pMeasurementSRV->commandResponseCBFunc, + pMeasurementSRV->commandResponseCBObj); + + pMeasurementSRV->commandResponseCBFunc = NULL; + pMeasurementSRV->commandResponseCBObj = NULL; + } + if ( NULL != pMeasurementSRV->measurmentCompleteCBFunc ) + { + /* Note: this is being called from request context, but there's npthing else that can be done */ + /* mark that all types has failed */ + TI_INT32 i; + for ( i = 0; i < MAX_NUM_OF_MSR_TYPES_IN_PARALLEL; i++ ) + { + pMeasurementSRV->msrReply.msrTypes[ i ].status = TI_NOK; + } + /* call the complete CB */ + pMeasurementSRV->measurmentCompleteCBFunc( pMeasurementSRV->measurementCompleteCBObj, + &(pMeasurementSRV->msrReply)); + } + } + + return TI_OK; +} + +/** + * \author Ronen Kalish\n + * \date 27-November-2005\n + * \brief handle a STOP_REQUEST event when in WAIT_FOR_DRIVER_MODE by marking negative result status + * \brief and calling the ordinary stop function + * + * Function Scope \e Public.\n + * \param hMeasurementSrv - handle to the Measurement SRV object.\n + * \return always TI_OK.\n + */ +TI_STATUS measurementSRVSM_stopFromWaitForMeasureStart( TI_HANDLE hMeasurementSRV ) +{ + measurementSRV_t* pMeasurementSRV = (measurementSRV_t*)hMeasurementSRV; + TI_INT32 i; + + /* mark that all types has failed */ + for ( i = 0; i < pMeasurementSRV->msrRequest.numberOfTypes; i++ ) + { + pMeasurementSRV->msrReply.msrTypes[ i ].status = TI_NOK; + } + + /* call the ordinary stop function (will send a measure stop command to FW) */ + measurementSRVSM_requestMeasureStop( hMeasurementSRV ); + + return TI_OK; +} + +/** + * \author Ronen Kalish\n + * \date 08-November-2005\n + * \brief handle a STOP_REQUEST event when in MEASURE_IN_PROGRESS by stopping all measure types and + * \brief requesting measure stop from the FW.\n + * + * Function Scope \e Public.\n + * \param hMeasurementSrv - handle to the Measurement SRV object.\n + * \return always TI_OK.\n + */ +TI_STATUS measurementSRVSM_stopFromMeasureInProgress( TI_HANDLE hMeasurementSRV ) +{ + measurementSRV_t* pMeasurementSRV = (measurementSRV_t*)hMeasurementSRV; + TNoiseHistogram pNoiseHistParams; + TI_STATUS status; + TI_INT32 i; + + /* stop all running measure types */ + for (i = 0; i < pMeasurementSRV->msrRequest.numberOfTypes; i++) + { + if (pMeasurementSRV->bRequestTimerRunning[i]) + { + /* stop timer */ + tmr_StopTimer (pMeasurementSRV->hRequestTimer[i]); + pMeasurementSRV->bRequestTimerRunning[i] = TI_FALSE; + + /* if necessary, stop measurement type */ + switch ( pMeasurementSRV->msrRequest.msrTypes[ i ].msrType ) + { + case MSR_TYPE_BEACON_MEASUREMENT: + /* send stop AP discovery command */ + status = cmdBld_CmdApDiscoveryStop (pMeasurementSRV->hCmdBld, NULL, NULL); + if ( TI_OK != status ) + { + TRACE1( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": TWD_ApDiscoveryStop returned status %d\n", status); + } + break; + + case MSR_TYPE_NOISE_HISTOGRAM_MEASUREMENT: + /* Set Noise Histogram Cmd Params */ + pNoiseHistParams.cmd = STOP_NOISE_HIST; + pNoiseHistParams.sampleInterval = 0; + os_memoryZero( pMeasurementSRV->hOS, &(pNoiseHistParams.ranges[ 0 ]), MEASUREMENT_NOISE_HISTOGRAM_NUM_OF_RANGES ); + + /* Send a Stop command to the FW */ + status = cmdBld_CmdNoiseHistogram (pMeasurementSRV->hCmdBld, &pNoiseHistParams, NULL, NULL); + + if ( TI_OK != status ) + { + TRACE1( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": TWD_NoiseHistogramCmd returned status %d\n", status); + } + break; + + /* These are just to avoid compilation warnings, nothing is actualy done here! */ + case MSR_TYPE_BASIC_MEASUREMENT: + case MSR_TYPE_CCA_LOAD_MEASUREMENT: + case MSR_TYPE_FRAME_MEASUREMENT: + case MSR_TYPE_MAX_NUM_OF_MEASURE_TYPES: + default: + TRACE1( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": unsupported measurement type: %d\n", pMeasurementSRV->msrRequest.msrTypes[ i ].msrType); + break; + } + + /* mark that measurement has failed */ + pMeasurementSRV->msrReply.msrTypes[ i ].status = TI_NOK; + } + } + + /* Send Measurement Stop command to the FW */ + status = cmdBld_CmdMeasurementStop (pMeasurementSRV->hCmdBld, + (void *)pMeasurementSRV->commandResponseCBFunc, + pMeasurementSRV->commandResponseCBObj); + + pMeasurementSRV->commandResponseCBFunc = NULL; + pMeasurementSRV->commandResponseCBObj = NULL; + + if ( TI_OK != status ) + { + TRACE1( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": Failed to send measurement stop command, statud=%d,\n", status); + + /* send a measurement complete event - since it can't be stopped */ + measurementSRVSM_SMEvent( hMeasurementSRV, &(pMeasurementSRV->SMState), + MSR_SRV_EVENT_STOP_COMPLETE ); + return TI_OK; + } + + TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, ": measure stop command sent.\n"); + + /* start the FW guard timer */ + pMeasurementSRV->bStartStopTimerRunning = TI_TRUE; + tmr_StartTimer (pMeasurementSRV->hStartStopTimer, + MacServices_measurementSRV_startStopTimerExpired, + (TI_HANDLE)pMeasurementSRV, + MSR_FW_GUARD_TIME, + TI_FALSE); + + return TI_OK; +} + +/** + * \author Ronen Kalish\n + * \date 08-November-2005\n + * \brief handle a DRIVER_MODE_FAILURE event by calling the response and complete CBs.\n + * + * Function Scope \e Public.\n + * \param hMeasurementSrv - handle to the Measurement SRV object.\n + * \return always TI_OK.\n + */ +TI_STATUS measurementSRVSM_DriverModeFailure( TI_HANDLE hMeasurementSRV ) +{ + measurementSRV_t* pMeasurementSRV = (measurementSRV_t*)hMeasurementSRV; + + /* this function can be called from within a request (when the power save SRV returned an immediate error), + or in a different context, when power save entry failed. The latter is a valid status, whereas the former + indicates a severe error. However, as there is nothing to do with the former (other than debug it), the same + failure indication is used for both of them, which will make the upper layer (Palau driver or TI measurement + manager) to return to idle state. Still, for the former the error is returned as the return status from the + measurement start API call whereas for the latter the error is indicated both by the command response and + measurement complete CBs status */ + + /* if we are running within a request context, don't call the CBs! The startMeasurement function + will return an invalid status instead */ + if ( TI_FALSE == pMeasurementSRV->bInRequest ) + { + /* if a response CB is available (GWSI) call it */ + if ( NULL != pMeasurementSRV->commandResponseCBFunc ) + { + pMeasurementSRV->commandResponseCBFunc( pMeasurementSRV->commandResponseCBObj, TI_NOK ); + } + + /* if a complete CB is available (both GWSI and TI driver), call it */ + if ( NULL != pMeasurementSRV->measurmentCompleteCBFunc ) + { + /* mark that all types has failed */ + TI_INT32 i; + for ( i = 0; i < MAX_NUM_OF_MSR_TYPES_IN_PARALLEL; i++ ) + { + pMeasurementSRV->msrReply.msrTypes[ i ].status = TI_NOK; + } + /* call the complete CB */ + pMeasurementSRV->measurmentCompleteCBFunc( pMeasurementSRV->measurementCompleteCBObj, + &(pMeasurementSRV->msrReply)); + } + else + { + TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": driver mode failure and complete CB is NULL!!!\n"); + } + } + + return TI_OK; +} + +/** + * \author Ronen Kalish\n + * \date 08-November-2005\n + * \brief handle a START_FAILURE event by exiting driver mode and calling the complete CB.\n + * + * Function Scope \e Public.\n + * \param hMeasurementSrv - handle to the Measurement SRV object.\n + * \return always TI_OK.\n + */ +TI_STATUS measurementSRVSM_measureStartFailure( TI_HANDLE hMeasurementSRV ) +{ + measurementSRV_t* pMeasurementSRV = (measurementSRV_t*)hMeasurementSRV; + + /* This function can be called from within a request context (if the driver mode entry process + was immediate), or from the driver mode CB context. Regardless of teh context in which it runs, + The error indicates that something is wrong in the HAL. There is no way to solve this (other than debug it). + The error is either indicating by the measurement start API return status (if still in the request context), + or by calling the response (if available, only in GWSI) and complete CBs with invalid status */ + + /* Switch Power save SRV back to user mode */ + powerSrv_ReleasePS( pMeasurementSRV->hPowerSaveSRV, pMeasurementSRV->bSendNullDataWhenExitPs, NULL, NULL ); + + /* if we are running within a request context, don't call the CB! The startMeasurement function + will return an invalid status instead */ + if ( TI_FALSE == pMeasurementSRV->bInRequest ) + { + /* if a response CB is available (GWSI) call it */ + if ( NULL != pMeasurementSRV->commandResponseCBFunc ) + { + pMeasurementSRV->commandResponseCBFunc( pMeasurementSRV->commandResponseCBObj, TI_NOK ); + } + + /* if a complete CB is available (both GWSI and TI driver), call it */ + if ( NULL != pMeasurementSRV->measurmentCompleteCBFunc ) + { + /* mark that all types has failed */ + TI_INT32 i; + for ( i = 0; i < MAX_NUM_OF_MSR_TYPES_IN_PARALLEL; i++ ) + { + pMeasurementSRV->msrReply.msrTypes[ i ].status = TI_NOK; + } + /* call the complete CB */ + pMeasurementSRV->measurmentCompleteCBFunc( pMeasurementSRV->measurementCompleteCBObj, + &(pMeasurementSRV->msrReply)); + } + else + { + TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_ERROR, ": Start measurement failure and response and complete CBs are NULL!!!\n"); + } + } + + return TI_OK; +} + + +static void measurementSRVSM_requestMeasureStartResponseCB(TI_HANDLE hMeasurementSRV, TI_UINT16 uMboxStatus) +{ + measurementSRV_t* pMeasurementSRV = (measurementSRV_t*)hMeasurementSRV; + TI_INT32 i; + +TRACE1( pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, ": FW has responded with CMD_STATUS = %d\n", uMboxStatus); + + if (uMboxStatus == TI_OK) + { +TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, ": FW has responded with CMD_STATUS_SUCCESS!\n"); + + if ( NULL != pMeasurementSRV->commandResponseCBFunc ) + { + pMeasurementSRV->commandResponseCBFunc( pMeasurementSRV->commandResponseCBObj, TI_OK ); + } + } + else + { + if (uMboxStatus == SG_REJECT_MEAS_SG_ACTIVE) + { +TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, ": FW has responded with CMD_STATUS_REJECT_MEAS_SG_ACTIVE!\n"); + } + +TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, ": FW has responded with CMD_STATUS NOK!!!\n"); + + + /* if a timer is running, stop it */ + if ( TI_TRUE == pMeasurementSRV->bStartStopTimerRunning ) + { +TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_INFORMATION, "***** STOP TIMER 8 *****\n"); + tmr_StopTimer( pMeasurementSRV->hStartStopTimer ); + pMeasurementSRV->bStartStopTimerRunning = TI_FALSE; + } + for ( i = 0; i < MAX_NUM_OF_MSR_TYPES_IN_PARALLEL; i++ ) + { + if ( TI_TRUE == pMeasurementSRV->bRequestTimerRunning[ i ] ) + { + tmr_StopTimer( pMeasurementSRV->hRequestTimer[ i ] ); + pMeasurementSRV->bRequestTimerRunning[ i ] = TI_FALSE; + } + } + + measurementSRVSM_SMEvent( hMeasurementSRV, &(pMeasurementSRV->SMState), + MSR_SRV_EVENT_START_FAILURE ); + } +} + + +/** + * \author Ronen Kalish\n + * \date 23-December-2005\n + * \brief Handles a stop request when no stop is needed (SM is either idle or already send stop command to FW.\n + * + * Function Scope \e Private.\n + * \param hMeasurementSrv - handle to the measurement SRV object.\n + * \return always TI_OK.\n + */ +TI_STATUS measurementSRVSRVSM_dummyStop( TI_HANDLE hMeasurementSrv ) +{ + measurementSRV_t *pMeasurementSRV = (measurementSRV_t*)hMeasurementSrv; + + TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_WARNING, ": sending unnecessary stop measurement command to FW...\n"); + + /* send a stop command to FW, to obtain a different context in ehich to cal the command response CB */ + cmdBld_CmdMeasurementStop (pMeasurementSRV->hCmdBld, + (void *)pMeasurementSRV->commandResponseCBFunc, + pMeasurementSRV->commandResponseCBObj); + + pMeasurementSRV->commandResponseCBFunc = NULL; + pMeasurementSRV->commandResponseCBObj = NULL; + + return TI_OK; +} + +/** + * \author Ronen Kalish\n + * \date 17-November-2005\n + * \brief Handles an unexpected event.\n + * + * Function Scope \e Private.\n + * \param hMeasurementSrv - handle to the measurement SRV object.\n + * \return always TI_OK.\n + */ +TI_STATUS actionUnexpected( TI_HANDLE hMeasurementSrv ) +{ + measurementSRV_t *pMeasurementSRV = (measurementSRV_t*)hMeasurementSrv; + TI_INT32 i; + + TRACE0( pMeasurementSRV->hReport, REPORT_SEVERITY_SM, ": measurement SRV state machine error, unexpected Event\n"); + + if (pMeasurementSRV->bStartStopTimerRunning) + { + tmr_StopTimer (pMeasurementSRV->hStartStopTimer); + pMeasurementSRV->bStartStopTimerRunning = TI_FALSE; + } + + for (i = 0; i < MAX_NUM_OF_MSR_TYPES_IN_PARALLEL; i++) + { + if (pMeasurementSRV->bRequestTimerRunning[i]) + { + tmr_StopTimer (pMeasurementSRV->hRequestTimer[i]); + pMeasurementSRV->bRequestTimerRunning[i] = TI_FALSE; + } + } + + /* we must clean the old command response CB since they are no longer relevant + since the state machine may be corrupted */ + pMeasurementSRV->commandResponseCBFunc = NULL; + pMeasurementSRV->commandResponseCBObj = NULL; + + /* indicate the unexpected event in the return status */ + pMeasurementSRV->returnStatus = TI_NOK; + + return TI_OK; +} + +/** + * \author Ronen Kalish\n + * \date 10-Jan-2005\n + * \brief Handles an event that doesn't require any action.\n + * + * Function Scope \e Private.\n + * \param hMeasurementSrv - handle to the measurement SRV object.\n + * \return always TI_OK.\n + */ +TI_STATUS actionNop( TI_HANDLE hMeasurementSrv ) +{ + return TI_OK; +} +