📄 headset_hfp_slc.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 + -