📄 headset_statemanager.c
字号:
/****************************************************************************
Copyright (C) Cambridge Silicon Radio Ltd. 2004-2007
FILE NAME
headset_statemanager.h
DESCRIPTION
State machine helper functions used for state changes etc - provide single
state change points etc for the headset app.
*/
#include "headset_a2dp_connection.h"
#include "headset_a2dp_stream_control.h"
#include "headset_buttonmanager.h"
#include "headset_debug.h"
#include "headset_hfp_slc.h"
#include "headset_LEDmanager.h"
#include "headset_scan.h"
#include "headset_statemanager.h"
#include "headset_volume.h"
#include <audio.h>
#include <ps.h>
#include <stdlib.h>
#ifdef DEBUG_STATES
#include <panic.h>
#define SM_DEBUG(x) DEBUG(x)
#define SM_ASSERT(c, x) { if (!(c)) { DEBUG(x); Panic();} }
const char * const gHSStateStrings [ 8 ] = {
"Limbo",
"ConnDisc",
"Connectable",
"Connected",
"Out",
"Inc",
"ActiveCall",
"TESTMODE"} ;
const char * const gA2DPStateStrings [HEADSET_NUM_A2DP_STATES] = {
"Connectable",
"Connected",
"Streaming",
"Paused"} ;
#else
#define SM_DEBUG(x)
#define SM_ASSERT(c, x)
#endif
#define SM_LIMBO_TIMEOUT_SECS (5)
typedef struct
{
/* The hfp headset state variable - accessed only from below fns */
headsetHfpState gTheHfpState:4;
/* The a2dp headset state variable - accessed only from below fns */
headsetA2dpState gTheA2dpState:3 ;
/* The avrcp headset state variable - accessed only from below fns */
headsetAvrcpState gTheAvrcpState:3 ;
} headsetAppStates;
static headsetAppStates appStates;
/****************************************************************************
LOCAL FUNCTION PROTOTYPES
*/
static void stateManagerSetHfpState ( hsTaskData * pApp , headsetHfpState pNewState ) ;
static void stateManagerSetA2dpState ( hsTaskData * pApp , headsetA2dpState pNewState ) ;
/****************************************************************************
FUNCTIONS
*/
/*****************************************************************************/
headsetHfpState stateManagerGetHfpState ( void )
{
return appStates.gTheHfpState ;
}
/*****************************************************************************/
headsetA2dpState stateManagerGetA2dpState ( void )
{
return appStates.gTheA2dpState ;
}
/*****************************************************************************/
uint16 stateManagerGetCombinedState ( void )
{
return (appStates.gTheHfpState + (HEADSET_NUM_HFP_STATES * appStates.gTheA2dpState));
}
/*****************************************************************************/
void stateManagerEnterHfpConnectableState ( hsTaskData *pApp, bool req_disc )
{
headsetHfpState lOldHfpState = stateManagerGetHfpState() ;
if ( stateManagerIsHfpConnected() && req_disc )
{ /*then we have an SLC active*/
hfpSlcDisconnect( pApp );
}
/* Make the headset connectable */
headsetEnableConnectable(pApp);
stateManagerSetHfpState ( pApp , headsetHfpConnectable) ;
/*determine if we have got here after a DiscoverableTimeoutEvent*/
if ( lOldHfpState == headsetConnDiscoverable )
{
/*disable the discoverable mode*/
headsetDisableDiscoverable ( pApp) ;
MessageCancelAll ( &pApp->task , EventPairingFail ) ;
}
}
/*****************************************************************************/
void stateManagerEnterA2dpConnectableState ( hsTaskData *pApp, bool req_disc )
{
if ( stateManagerIsA2dpConnected() && req_disc )
{
a2dpDisconnectRequest( pApp );
}
if ( stateManagerIsA2dpStreaming() && stateManagerIsAvrcpConnected() )
{
/* Store the current playing status of the media, so the playing status
can now be tracked independently of the A2DP state. This is because
AVRCP commands can be sent from the headset while not in the streaming state.
*/
if (stateManagerGetA2dpState() == headsetA2dpStreaming)
pApp->PlayingState = 1;
else
pApp->PlayingState = 0;
}
/* Make the headset connectable */
headsetEnableConnectable(pApp);
stateManagerSetA2dpState(pApp , headsetA2dpConnectable);
}
void stateManagerEnterA2dpConnectedState(hsTaskData * pApp)
{
if ( stateManagerIsA2dpSignallingActive ( pApp ) )
{
stateManagerSetA2dpState(pApp , headsetA2dpConnected);
if ( stateManagerIsHfpConnected() )
headsetDisableConnectable ( pApp ) ;
}
if ( stateManagerIsA2dpStreaming() && stateManagerIsAvrcpConnected() )
{
/* Store the current playing status of the media, so the playing status
can now be tracked independently of the A2DP state. This is because
AVRCP commands can be sent from the headset while not in the streaming state.
*/
if (stateManagerGetA2dpState() == headsetA2dpStreaming)
pApp->PlayingState = 1;
else
pApp->PlayingState = 0;
}
}
/*****************************************************************************/
void stateManagerEnterA2dpStreamingState(hsTaskData * pApp)
{
stateManagerSetA2dpState(pApp , headsetA2dpStreaming);
}
/*****************************************************************************/
void stateManagerEnterA2dpPausedState(hsTaskData * pApp)
{
stateManagerSetA2dpState(pApp , headsetA2dpPaused);
}
/*****************************************************************************/
void stateManagerEnterConnDiscoverableState ( hsTaskData *pApp )
{
if ( stateManagerIsHfpConnected() )
{
hfpSlcDisconnect( pApp );
}
if ( stateManagerIsA2dpConnected() )
{
a2dpDisconnectRequest( pApp );
}
/* Make the headset connectable */
headsetEnableConnectable ( pApp );
/* Make the headset discoverable */
headsetEnableDiscoverable ( pApp );
/* The headset is now in the connectable/discoverable state */
stateManagerSetHfpState (pApp , headsetConnDiscoverable ) ;
/* Cancel Pairing mode after a configurable number of secs */
MessageSendLater ( &pApp->task , EventPairingFail , 0 , D_SEC(pApp->Timeouts.PairModeTimeout_s) ) ;
}
/*****************************************************************************/
void stateManagerEnterHfpConnectedState ( hsTaskData *pApp )
{
headsetHfpState hfpState = stateManagerGetHfpState ();
if (hfpState != headsetHfpConnected )
{
headsetDisableDiscoverable ( pApp ) ;
if ( stateManagerIsA2dpSignallingActive ( pApp ) )
headsetDisableConnectable ( pApp ) ;
if ( (hfpState == headsetActiveCall) && (pApp->dsp_process == dsp_process_sco) && pApp->cvcEnabled )
{
AudioSetMode (AUDIO_MODE_MUTE_SPEAKER , NULL) ;
}
/* If we are muted - then un mute after call has ended */
if ( (hfpState == headsetActiveCall) && pApp->audioData.gMuted )
{
MessageSend(&pApp->task , EventMuteOff , 0) ;
}
switch ( hfpState )
{
case headsetActiveCall:
case headsetOutgoingCallEstablish:
case headsetIncomingCallEstablish:
/* We have just ended a call */
streamControlResumeA2dpStreaming(pApp, 0);
MessageSend ( &pApp->task , EventEndOfCall , 0 ) ;
break;
default:
break;
}
MessageCancelAll ( &pApp->task , EventPairingFail ) ;
stateManagerSetHfpState ( pApp , headsetHfpConnected ) ;
}
}
/*****************************************************************************/
void stateManagerEnterIncomingCallEstablishState ( hsTaskData * pApp )
{
/*headsetHfpState lState = stateManagerGetHfpState() ;*/
stateManagerSetHfpState ( pApp , headsetIncomingCallEstablish ) ;
}
/*****************************************************************************/
void stateManagerEnterOutgoingCallEstablishState ( hsTaskData * pApp )
{
stateManagerSetHfpState ( pApp , headsetOutgoingCallEstablish ) ;
}
/*****************************************************************************/
void stateManagerEnterActiveCallState ( hsTaskData * pApp )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -