⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 headset_callmanager.c

📁 bluelab的一个很好的例程
💻 C
字号:
/****************************************************************************
Copyright (C) Cambridge Silicon Radio Ltd. 2005

FILE NAME
    headset_callmanager.h      

DESCRIPTION
    This is the call manager for BC4-Headset
    

NOTES

*/
#include "headset_callmanager.h"
#include "headset_statemanager.h"
#include "headset_soundmanager.h"

#define DEFAULT_HSP_SEND_ACTIVE_CALL_SECS (6) 

#include "headset_private.h"

#include <connection.h>
#include <hfp.h>


static void headsetQueueEvent ( hsTaskData * pApp , headsetEvents_t pEvent) ;

#ifdef DEBUG_CALL_MAN
    #define CM_DEBUG(x) DEBUG(x)
#else
    #define CM_DEBUG(x) 
#endif


void headsetHandleCallSetupInd ( hsTaskData *pApp,  const HFP_CALL_SETUP_IND_T * pInd )  
{
    
    switch (pInd->call_setup)
    {
    case (hfp_no_call_setup): /*!< No call currently being established.*/

        	/* Spec says that this is a clear indicationn  that an incominc call has been interrupted
        	   and we can assume that the call is not going to continue....*/          
            if (stateManagerIsConnected() )
            {
                stateManagerEnterConnectedState ( pApp ) ;
            }
            /* However, we have come across phones that send this before a callind [1]
               on accepting a call - -interop issue*/
        break;
    case (hfp_incoming_call_setup): /*!< HFP device currently ringing.*/
            stateManagerEnterIncomingCallEstablishState ( pApp ) ;
        break;
    case (hfp_outgoing_call_setup): /*!< Call currently being dialed.*/
    case (hfp_outgoing_call_alerting_setup):/*!< Remote end currently ringing.*/
            stateManagerEnterOutgoingCallEstablishState ( pApp ) ;
        break;
    default:
        CM_DEBUG(("CM : ?cs[%d]\n",pInd->call_setup)) ;
        break;
        
    }
}

void headsetHandleCallInd ( hsTaskData *pApp,  const HFP_CALL_IND_T * pInd ) 
{
    
    switch (pInd->call)
    {
    case 0:
            if (stateManagerIsConnected() )
            {
                stateManagerEnterConnectedState ( pApp ) ;
            }    
      break ;
    case 1:
            stateManagerEnterActiveCallState ( pApp ) ;
        break;
        default:
        CM_DEBUG(("CM : ?ci[%d]\n",pInd->call)) ;
    break;
    }
}


/****************************************************************************
NAME    
    hfpHeadsetHandleRingInd
    
DESCRIPTION
    Received a RING indication from the AG.

RETURNS
    void
*/
void headsetHandleRingInd(hsTaskData *pApp, const HFP_RING_IND_T * pInd)
{
    pInd = pInd;
    
    /* If in HSP mode use rings as indication of incoming call */
    if ((pApp->profile_connected == hfp_headset_profile) && (stateManagerIsConnected() ))
    {        
        stateManagerEnterIncomingCallEstablishState ( pApp ) ;
            /*sends a message indicating that we have now entered incoming call state*/        
        MessageSendLater ( &pApp->task , 
                           EventHSPEnterActiveCallState , 
                           0 , 
                           D_SEC(DEFAULT_HSP_SEND_ACTIVE_CALL_SECS) ) ;
    }
    
    if ( ! pApp->RingInfo.InBandRingEnabled )
    {
        soundManagerOutOfBandRing ( pApp ) ;
    }    
    
}

/****************************************************************************
NAME    
    headsetAnswerCall
    
DESCRIPTION
    Answer an incoming call from the headset

RETURNS
    void
*/
void headsetAnswerCall(const hsTaskData *pApp)
{
    /* 
        Call the HFP lib function, this will determine the AT cmd to send
        depending on whether the profile instance is HSP or HFP compliant.
    */ 
    
    if ( pApp->profile_connected == hfp_handsfree_profile )
    {
        HfpAnswerCall(pApp->hfp);
    }
    else
    {
        HfpSendHsButtonPress ( pApp->hsp ) ;
    }
    
    
}


/****************************************************************************
NAME    
    headsetHandleAnswerCallCfm
    
DESCRIPTION
    Cfm from the HFP lib telling us whether the answer call response was
    accepted by the AG or not.

RETURNS
    void
*/

void headsetHandleAnswerCallCfm(hsTaskData *pApp, HFP_ANSWER_CALL_CFM_T * pInd)
{
        /*if an answer call confirm arrivves - then we have established a call
    stateManagerEnterActiveCallState ( pApp ) ;*/
    
     CM_DEBUG(("CM: Answer call cfm\n")) ;  
    pApp = pApp ;
    pInd = pInd ;
}

/****************************************************************************
NAME    
    headsetRejectCall
    
DESCRIPTION
    Reject an incoming/ outgoing call from the headset

RETURNS
    void
*/
void headsetRejectCall(const hsTaskData *pApp)
{
    /* 
        Reject incoming call - only valid for instances of HFP in HSP mode
        send a button press.
    */
    if ( pApp->profile_connected == hfp_handsfree_profile )
    {
        HfpRejectCall(pApp->hfp);
    }
    else
    {
        HfpSendHsButtonPress ( pApp->hsp ) ;
    }
    
}


/****************************************************************************
NAME    
    headsetHandleRejectCallCfm
    
DESCRIPTION
    Cfm from the HFP lib telling us whether the reject call response was
    accepted by the AG or not.

RETURNS
    void
*/
void headsetHandleRejectCallCfm(hsTaskData *pApp, const HFP_REJECT_CALL_CFM_T *pCfm)
{
    pApp = pApp ;
    pCfm = pCfm ;
}


/****************************************************************************
NAME    
    hfpHeadsetHangUpCall
    
DESCRIPTION
    Hang up the call from the headset.

RETURNS
    void
*/
void headsetHangUpCall(const hsTaskData *pApp)
{
    /* Terminate the current ongoing call process */
    if ( pApp->profile_connected == hfp_handsfree_profile )
    {
        HfpTerminateCall(pApp->hfp);
    }
    else
    {
        HfpSendHsButtonPress ( pApp->hsp ) ;
    }    
}


/****************************************************************************
NAME    
    headsetHandleTerminateCallCfm
    
DESCRIPTION
    Cfm from the HFP lib telling us whether the hang up call response was 
    accepted  by the AG or not.

RETURNS
    void
*/
void headsetHandleTerminateCallCfm( hsTaskData *pApp, const HFP_TERMINATE_CALL_CFM_T *pCfm)
{
    pApp = pApp;
    pCfm = pCfm;
}


/****************************************************************************
NAME    
    headsetTransferAudio
    
DESCRIPTION
    If the audio is at the headset end transfer it back to the AG and
    vice versa.

RETURNS
    void
*/
void headsetTransferToggle(hsTaskData *pApp)
{
    hfp_audio_transfer_direction lTransferDirection = hfp_audio_to_ag ;

    
      /* Call the audio transfer function in the HFP lib */
      /* Transfer the audio to/ from the AG */ 
    if (!pApp->sco_sink)
    {
        lTransferDirection = hfp_audio_to_hfp ;
    }
    else
    {
        lTransferDirection = hfp_audio_to_ag ;
    }
    
    if ( pApp->profile_connected == hfp_handsfree_profile )
    {
        HfpAudioTransferConnection(pApp->hfp, lTransferDirection, audioGetSupportedPacketTypes( pApp ), 0 );
    }
    else
    { 
        /*this has been removed as a button press will cause the AG to hang up the call */
        /*HfpSendHsButtonPress ( pApp->hsp ) ;*/
    }

}


/****************************************************************************
NAME    
    headsetInitiateVoiceDial
    
DESCRIPTION
    If HFP and connected - issues command
    If HFP and not connected - connects and issues if not in call
    If HSP sends button press

RETURNS
    void
*/
void headsetInitiateLNR ( hsTaskData * pApp )
{

    CM_DEBUG(("CM: LNR\n")) ;

    if (!stateManagerIsConnected() )
    {
        MessageSend ( &pApp->task , EventEstablishSLC , 0 ) ;
        headsetQueueEvent(pApp , EventLastNumberRedial) ;
    }
    else
    {
        
        CM_DEBUG(("CM: LNR Connected\n")) ;
    
        if ( pApp->profile_connected == hfp_handsfree_profile )
        {
            HfpLastNumberRedial( pApp->hfp );    
        }
        else
        {
            HfpSendHsButtonPress ( pApp->hsp ) ;
        }
    }    
}


/****************************************************************************
NAME    
    headsetInitiateLNR
    
DESCRIPTION
    If HFP and connected - issues command
    If HFP and not connected - connects and issues if not in call
    If HSP sends button press

RETURNS
    void
*/
void headsetInitiateVoiceDial ( hsTaskData* pApp )
{
    CM_DEBUG(("CM: VD\n")) ;
    if (!stateManagerIsConnected() )
    {
        MessageSend ( &pApp->task , EventEstablishSLC , 0 ) ;
        headsetQueueEvent( pApp , EventInitateVoiceDial ) ;
        
        pApp->VoiceRecognitionIsActive = FALSE ;
    }
    else
    {
    
    CM_DEBUG(("CM: VD Connected\n")) ;
    
        if ( pApp->profile_connected == hfp_handsfree_profile )
        {
            if (pApp->supp_features_local & HFP_VOICE_RECOGNITION ) 
            {
                HfpVoiceRecognitionEnable(pApp->hfp, TRUE);    
                
                pApp->VoiceRecognitionIsActive = TRUE ;
            }
        }
        else
        {
            HfpSendHsButtonPress ( pApp->hsp ) ;
        }	    
    }    
    		    
}
/****************************************************************************
NAME    
    headsetInitiateLNR
    
DESCRIPTION
    cancels a voice dial request
   
RETURNS
    void
*/
void headsetCancelVoiceDial ( hsTaskData * pApp)
{
    if ( pApp->profile_connected == hfp_handsfree_profile )
    {
            /*if we support voice dialing*/
        if (pApp->supp_features_local & HFP_VOICE_RECOGNITION ) 
        {
                /*if we believe voice dial is currently active*/
            if ( pApp->VoiceRecognitionIsActive)
            {
                HfpVoiceRecognitionEnable(pApp->hfp, FALSE);    
                
                pApp->VoiceRecognitionIsActive = FALSE ;
            }
        }
    }
}

headsetEvents_t gMessageQueued = EventInvalid ;

/****************************************************************************
NAME    
    headsetQueueEvent
    
DESCRIPTION
    Queues an event to be sent once the headset is connected

RETURNS
    void
*/
static void headsetQueueEvent ( hsTaskData * pApp , headsetEvents_t pEvent)
{
    CM_DEBUG(("CM: QQ Ev[%x]\n", pEvent)) ;
    gMessageQueued = pEvent ;
}

/****************************************************************************
NAME    
    headsetRecallQueuedEvent
    
DESCRIPTION
    Checks to see if an event was Queued and issues it

RETURNS
    void
*/
void headsetRecallQueuedEvent ( hsTaskData * pApp )
{
        /*this is currently only applicable to  LNR and voice Dial but does not care */
    if (gMessageQueued != EventInvalid)
    {
        switch (stateManagerGetState() )
        {
            case headsetIncomingCallEstablish:
            case headsetOutgoingCallEstablish:
            case headsetActiveCall:       
            case headsetThreeWayCallWaiting:
            case headsetThreeWayCallOnHold:
            case headsetThreeWayMulticall:
                /* Do Nothing Message Gets ignored*/
            break ;
            default:
                if ( pApp->profile_connected == hfp_handsfree_profile )
                {
                    MessageSend ( &pApp->task , gMessageQueued , 0 ) ; 
                
                    CM_DEBUG(("CM: Queued Message ? [%x] Sent\n" , gMessageQueued))    
                }
                else
                {
                    HfpSendHsButtonPress ( pApp->hsp ) ;
                    CM_DEBUG(("CM: Queued Msg - HSP Butt Sent\n"))    
                } 
            break;
        }
    }    
    
        /*reset the queued event*/
    gMessageQueued = EventInvalid ;
}


void headsetClearQueueudEvent ( hsTaskData * pApp )
{
        /*this resets the queue - on a conenction fail / power off etc*/
    gMessageQueued = EventInvalid ;
}


/****************************************************************************
NAME    
    headsethandleResponseHoldInd
    
DESCRIPTION
    Handles a response and hold indication

RETURNS
    void
*/
void headsethandleResponseHoldInd ( hsTaskData * pApp, HFP_RESPONSE_HOLD_STATUS_IND_T * pInd ) 
{
    CM_DEBUG(("CM: Res/Hold.Ind[%d]\n", pInd->state)) ;
    switch ( pInd->state )
    {
    case hfp_incoming_call_held:
        stateManagerEnterIncomingCallOnHoldState ( pApp ) ;
    break ;
    case hfp_held_call_rejected:                
        stateManagerEnterConnectedState ( pApp ) ;
    break ;
    case hfp_held_call_accepted:
        stateManagerEnterActiveCallState ( pApp ) ;
    break ;
    
    default:
    break ;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -