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

📄 headset_hfp_handler.c

📁 bc5_stereo:bluetooth stereo Headset CODE 支持A2DP HSP 和 HSP 。可作为车载免提。BlueLab 2007环境下编译
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
Copyright (C) Cambridge Silicon Radio Ltd. 2004-2007

FILE NAME
    headset_hfp_handler.c
    
DESCRIPTION
    Functions which handle the HFP library messages.
    
*/

#include "headset_a2dp_stream_control.h"
#include "headset_amp.h"
#include "headset_debug.h"
#include "headset_hfp_handler.h"
#include "headset_hfp_slc.h"
#include "headset_init.h"
#include "headset_LEDmanager.h"
#include "headset_statemanager.h"
#include "headset_tones.h"
#include "headset_volume.h"

#include <audio.h>
#include <csr_no_dsp_plugin.h>
#include <csr_cvc_plugin.h>
#include <hfp.h>
#include <panic.h>
#include <pio.h>
#include <stdlib.h>


#ifdef DEBUG_HFP
#define HFP_DEBUG(x) DEBUG(x)
#else
#define HFP_DEBUG(x) 
#endif


/****************************************************************************
    LOCAL FUNCTION PROTOTYPES
*/
static bool audioConnectSco ( hsTaskData *pApp );


/****************************************************************************
  HFP MESSAGE HANDLING FUNCTIONS
*/

/****************************************************************************/
void hfpHandlerInitCfm( hsTaskData * pApp , const HFP_INIT_CFM_T *cfm )
{
    /* Make sure the profile instance initialisation succeeded. */
    if (cfm->status == hfp_init_success)
    {
        /* Check for an hfp instance, that's registered first */
        if (!pApp->hfp)
        {
            /* This must be the hfp instance */ 
            pApp->hfp = cfm->hfp;
        }
        else
        {
            /* Its not HFP so must be HSP */
            pApp->hsp = cfm->hfp;
            /* HFP/HSP Library initialisation was a success, initailise the 
               A2DP library. */
            InitA2dp();
        }
    }
    else
        /* If the profile initialisation has failed then things are bad so panic. */
        Panic();
}


/****************************************************************************/
void hfpHandlerConnectInd( hsTaskData * pApp , const HFP_SLC_CONNECT_IND_T *ind )
{
    /* Don't handle this message if the headset is powered off */
    if (stateManagerGetHfpState() == headsetPoweringOn)      
        return;
    
    /* We support more than one HFP so check which one this request is for */   
    if (pApp->profile_connected == hfp_no_profile)
    {
        HfpSlcConnectResponse(ind->hfp, 1, &ind->addr, 0);
              
        /* See whether we are connecting as HSP or HFP */
        if (ind->hfp == pApp->hfp)
        {
            pApp->profile_connected = hfp_handsfree_profile;
        }
        else if (ind->hfp == pApp->hsp)
        {
            pApp->profile_connected = hfp_headset_profile;
        }
        else
            /* Something is wrong we should be either hfp or hsp */
            Panic();
    }
    else
    {
        /* Reject the connect attempt we're already connected */
        HfpSlcConnectResponse(ind->hfp, 0, &ind->addr, 0);
    }
}


/****************************************************************************/
void hfpHandlerConnectCfm( hsTaskData * pApp , const HFP_SLC_CONNECT_CFM_T *cfm )
{
    if (stateManagerGetHfpState() == headsetPoweringOn)
    {
        if ( cfm->status == hfp_connect_success )
        {
            /* A connection has been made and we are now logically off */
            hfpSlcDisconnect( pApp ); 
        }
		pApp->slcConnecting = FALSE;
		pApp->slcConnectFromPowerOn = FALSE;
        return;
    }
    
    if (cfm->status == hfp_connect_success)
    {      
        hfpSlcConnectSuccess(pApp, cfm->hfp, cfm->sink);
    }
    else if (cfm->status == hfp_connect_sdp_fail)
    {
        if ( !stateManagerIsHfpConnected() )  /*only continue if not already connected*/
        {
            if (cfm->hfp == pApp->hfp)
            {
                /* Didn't find HFP so try HSP */
                hfpSlcConnectRequest ( pApp , hfp_headset_profile );
            }
            else if (cfm->hfp == pApp->hsp)
            {
                HFP_DEBUG(("SLC: CFM HSP Fail\n")) ;
                /* We try the HSP after we've tried HFP so this AG supports neither, give up */
                hfpSlcConnectFail(pApp);
            }
            else
            {
                Panic();/* Unknown profile instance */
            }
        } 
		else
		{
			pApp->slcConnecting = FALSE;
			pApp->slcConnectFromPowerOn = FALSE;
		}
    }
    else
    {
        if ( !stateManagerIsHfpConnected() )  /*only continue if not already connected*/
        {    /* Failed to connect */    
            hfpSlcConnectFail(pApp);     
        }
		else
		{
			pApp->slcConnecting = FALSE;
			pApp->slcConnectFromPowerOn = FALSE;
		}
    }       
}


/*****************************************************************************/
void hfpHandlerDisconnectInd(hsTaskData * pApp, const HFP_SLC_DISCONNECT_IND_T *ind)
{
	pApp->slc_sink = 0;
	
	/* Store current volume levels to ensure correct values on next SLC connect */
	VolumeStoreLevels(pApp);
	
	/* Check if this was the result of an abnormal link loss */
    if (ind->status == hfp_disconnect_link_loss ) 
    {
        HFP_DEBUG(("HFP: Link Loss Detect\n")) ;
               
        MessageSend( &pApp->task , EventLinkLoss , 0 ) ;
		
		if (!stateManagerIsA2dpStreaming())
			/* A Link Loss has occured - attempt reconnect */
        	hfpSlcConnectRequest( pApp , hfp_handsfree_profile ) ;
    }
    else
    {
        /* A disconnect in active call state is a call transfer */
        if ( (stateManagerGetHfpState() == headsetActiveCall) )
        {
            /*slcCallTransferInProgress( app) ;             */
        }
        else
        {
            /*slcCallTransferNotInProgress( app) ;*/
        }
    }
	
	/*	
        Handle the case where an incoming call is rejected using the headset profile.
		As we get no indicator info, the AV must be restarted on a SLC disconnect.
	*/
    if ((pApp->profile_connected == hfp_headset_profile))
    {
        streamControlResumeA2dpStreaming(pApp, 0);
    }
    
    /* Update the app state if we are connected */
    if ( stateManagerIsHfpConnected() )
    {
        stateManagerEnterHfpConnectableState( pApp, FALSE ) ;
    }
    
    MessageSend(&pApp->task , EventSLCDisconnected , 0) ;
    
        /* Connection disconnected */
    pApp->profile_connected = hfp_no_profile;

	/* Reset in-band ring tone support flag */
	pApp->InBandRingEnabled = FALSE;
	
    PROFILE_MEMORY(("HFPDisco"))

}


/*****************************************************************************/
void hfpHandlerInbandRingInd( hsTaskData * pApp, const HFP_IN_BAND_RING_IND_T * ind )
{    
    pApp->InBandRingEnabled = ind->ring_enabled;        
}


/*****************************************************************************/
void hfpHandlerCallInd ( hsTaskData *pApp,  const HFP_CALL_IND_T * pInd ) 
{
    switch (pInd->call)
    {
    case 0:
		if ( stateManagerGetHfpState() == headsetActiveCall )
        {		
            stateManagerEnterHfpConnectedState ( pApp ) ;
        }    
      	break;

    case 1:
        stateManagerEnterActiveCallState ( pApp ) ;      
        break;

    default:
        break;
    }
}


/*****************************************************************************/
void hfpHandlerCallSetupInd ( 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 indication that an incoming call has been interrupted
       	   and we can assume that the call is not going to continue....*/          

⌨️ 快捷键说明

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