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

📄 headset_hfp_slc.c

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

FILE NAME
    headset_hfp_slc.c
    
DESCRIPTION
    Handle HFP SLC.
    
*/

#include "headset_a2dp_connection.h"
#include "headset_a2dp_stream_control.h"
#include "headset_configmanager.h"
#include "headset_debug.h"
#include "headset_hfp_call.h"
#include "headset_hfp_slc.h"
#include "headset_statemanager.h"
#include "headset_volume.h"

#include <bdaddr.h>
#include <hfp.h>
#include <panic.h>
#include <ps.h>


#ifdef DEBUG_HFP_SLC
#define HFP_SLC_DEBUG(x) DEBUG(x)
#else
#define HFP_SLC_DEBUG(x) 
#endif


/****************************************************************************
  FUNCTIONS
*/


/****************************************************************************/
void hfpSlcReset( hsTaskData * pApp )
{
    HFP_SLC_DEBUG(("SLC: reset\n")) ;

	pApp->slcConnecting = FALSE;
	pApp->slcConnectFromPowerOn = FALSE;	
}  


/****************************************************************************/
bool hfpSlcIsConnecting ( hsTaskData * pApp )
{
	return pApp->slcConnecting;	
}


/*****************************************************************************/
void hfpSlcConnectSuccess ( hsTaskData * pApp , HFP * pProfile, Sink sink )
{
    bdaddr ag_addr;
    
	HFP_SLC_DEBUG(("HFP: Connected[%x]\n", (uint16)sink)) ;
    
    pApp->slcConnecting = FALSE;
	pApp->slc_sink = sink;
	
	/* Enter connected state if not already connected */
	if (!stateManagerIsHfpConnected())
	{
	    stateManagerEnterHfpConnectedState( pApp );	
	}
	
	/* Resume A2DP streaming if any existed before connection attempt */
	streamControlResumeA2dpStreaming( pApp, 0);
 
	if (pProfile == pApp->hfp)
    {
        pApp->profile_connected = hfp_handsfree_profile;
    }
    else if (pProfile == pApp->hsp)
    {
        pApp->profile_connected = hfp_headset_profile;
    }    
    
    if ( SinkGetBdAddr ( sink, &ag_addr ) )
        hfpSlcStoreBdaddr ( &ag_addr );

	/* Reinitialise HFP Volume level with stored values */
	VolumeInitHfp(pApp);
	
	/* Send retrieved volumes to AG */
	VolumeSendSettingsToAG(pApp, TRUE, TRUE);
    
    /* Ensure the underlying ACL is encrypted */       
    ConnectionSmEncrypt( &pApp->task , sink , TRUE );
	
	/* Disable NR/EC on AG if it's supported */
    if (pApp->profile_connected == hfp_handsfree_profile)
        HfpDisableNrEc(pApp->hfp);
    
    /* Send a user event to the app for indication purposes */
    MessageSend ( &pApp->task , EventSLCConnected , 0 );
	
	/* Send an event to connect to last used A2DP source if this connection was from power on */
	if (pApp->slcConnectFromPowerOn)
	{
    	MessageSend ( &pApp->task , EventEstablishA2dp , 0 );
	}
	
	PROFILE_MEMORY(("HFPConnect"))
}


/*****************************************************************************/
void hfpSlcConnectFail( hsTaskData *pApp )
{
	bool connecting_a2dp = FALSE;
    /* Update the app state */  
    HFP_SLC_DEBUG(("SLC : Connect Fail \n")) ; 
	
	/* Send an event to connect to last used A2DP source if this connection was from power on, 
	   and it's not the same device as the last used AG. */
	if (pApp->slcConnectFromPowerOn)
	{
		bdaddr ag_addr, a2dp_addr;
		a2dp_sep_type sep_type;
		
		if (a2dpGetLastUsedSource(&a2dp_addr, &sep_type))
		{
			if (hfpSlcGetLastConnectedAG(&ag_addr))
			{
				if (!BdaddrIsSame(&a2dp_addr, &ag_addr))
				{
					connecting_a2dp = TRUE;
    				MessageSend ( &pApp->task , EventEstablishA2dp , 0 );
				}
			}
			else
			{
				connecting_a2dp = TRUE;
				MessageSend ( &pApp->task , EventEstablishA2dp , 0 );	
			}
		}
	}

    pApp->slcConnecting = FALSE; /*reset the connecting flag*/ 
	
	if (!connecting_a2dp)
		pApp->slcConnectFromPowerOn = FALSE;
	
	/* Resume A2DP streaming if any existed before connection attempt */
	streamControlResumeA2dpStreaming( pApp, 0);

    /* No connection */
    pApp->profile_connected = hfp_no_profile;
    
    /* Send event to signify that all reconnection attempts failed */
	MessageSend(&pApp->task, EventHfpReconnectFailed, 0);
    
    /* Clear the queue */
    hfpCallClearQueuedEvent ( pApp ) ;
    
    PROFILE_MEMORY(("HFPConnectFail"))
}


/****************************************************************************/
void hfpSlcConnectRequest( hsTaskData *pApp, hfp_profile pProfile )
{
    bdaddr lLastAddr ;   
    
    pApp->slcConnecting = TRUE;    
    
    /* Retrieve the address of the last used AG from PS */
	if (!hfpSlcGetLastUsedAG(&lLastAddr))
	{
		/* We have failed to connect as we don't have a valid address */
        HFP_SLC_DEBUG(("SLC: No Last Addr \n"));
		hfpSlcConnectFail ( pApp );
		return;
	}
   
	HFP_SLC_DEBUG(("SLC: Connect Req [%x]\n" , pProfile));
    hfpSlcAttemptConnect ( pApp , pProfile , &lLastAddr );
}


/****************************************************************************/
void hfpSlcAttemptConnect( hsTaskData *pApp, hfp_profile pProfile , bdaddr * pAddr )
{
	
	/* Pause A2DP streaming if any */
	streamControlCeaseA2dpStreaming(pApp, TRUE);
	
    switch ( pProfile )
    {
        case (hfp_handsfree_profile) :
        {
            pApp->profile_connected = hfp_handsfree_profile;
           
            HFP_SLC_DEBUG(("SLC: Attempt HFP\n")) ;                    
            /* Issue a connect request for HFP */
            HfpSlcConnect(pApp->hfp, pAddr, 0);
        }    
        break;
        case (hfp_headset_profile) :
        {
            pApp->profile_connected = hfp_headset_profile;
            HFP_SLC_DEBUG(("SLC: Attempt HSP\n")) ;                    
            /* Issue a connect request for HFP */
            HfpSlcConnect(pApp->hsp, pAddr, 0);
        }   
        break;
        default:
            Panic();
            break;
    }
}


/****************************************************************************/
void hfpSlcConnectAfterLinkLoss( hsTaskData *pApp )
{
    
}


/****************************************************************************/
void hfpSlcDisconnect( hsTaskData *pApp )
{
    /* Issue the disconnect request and let the HFP lib do the rest */
	if(pApp->profile_connected == hfp_no_profile)
		return;
	else if(pApp->profile_connected == hfp_handsfree_profile)
    	HfpSlcDisconnect(pApp->hfp);
	else
		HfpSlcDisconnect(pApp->hsp);
}


/****************************************************************************/
void hfpSlcStoreBdaddr ( const bdaddr * pAddr ) 
{
    (void) PsStore(PSKEY_LAST_USED_AG, pAddr, sizeof(bdaddr));
}


/****************************************************************************/
bool hfpSlcGetLastUsedAG(bdaddr *addr)
{
	bool ret = TRUE;
	
  	if (!PsRetrieve(PSKEY_LAST_USED_AG, addr, sizeof(bdaddr)))
	{
		if (!PsRetrieve(PSKEY_LAST_PAIRED_DEVICE, addr, sizeof(bdaddr)))
		{ 
			ret = FALSE;
		}
	}
	
	return ret;
}


/****************************************************************************/
bool hfpSlcGetLastConnectedAG(bdaddr *addr)
{
	bool ret = TRUE;
	
  	if (!PsRetrieve(PSKEY_LAST_USED_AG, addr, sizeof(bdaddr)))
	{
	
		ret = FALSE;
	}
	
	return ret;
}

⌨️ 快捷键说明

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