📄 headset_slc.c
字号:
/****************************************************************************Copyright (C) Cambridge Silicon Radio Ltd. 2004-2006Part of BlueLab 3.5.2-releaseFILE NAME headset_slc.cDESCRIPTION NOTES*//**************************************************************************** Header files*/#include "headset_private.h"#include "headset_scan.h"#include "headset_slc.h"#include "headset_statemanager.h"#include "headset_configmanager.h"#include "headset_soundmanager.h"#include "headset_callmanager.h"#include <connection.h>#include <hfp.h>#include <panic.h>#include <ps.h>#include <bdaddr.h>#ifdef DEBUG_SLC #define SLC_DEBUG(x) DEBUG(x) #ifdef DEBUG_PRINT_ENABLED static const char * const gDebugReconStrings[7] = { "AR_LastConnected", "AR_Last", "AR_Default", "AR_LastThenDefault", "AR_DefaultThenLast", "AR_Swap", "AR_SwapSwap" }; #endif#else #define SLC_DEBUG(x) #endif typedef enum NextPagingTag { PageUnknown , PageLastAG , PageDefaultAG , PageComplete}NextPage_t;typedef enum CurrPagingTag { PagingLast , PagingDefault }CurrPaging_t ;typedef enum LastConnectedTag{ LastNone , LastDefault , LastLast}LastConnected_t ;typedef struct slcDataTag{ unsigned gNextPage:2; unsigned gLastConnected:2; unsigned gCurrPaging:1; unsigned gCallTransferInProgress:1 ; unsigned gLinkLossOccured:10;}slcData_t;static slcData_t gSlcData = {PageUnknown, LastNone, PagingLast , FALSE, FALSE} ;static void slcAttemptConnect ( hsTaskData *pApp, hfp_profile pProfile , bdaddr * pAddr) ;static void slcConnectDefaultAG ( hsTaskData * pApp , hfp_profile pProfile ) ;static void slcConnectLastAG ( hsTaskData * pApp , hfp_profile pProfile ) ;static void slcConnectLastConnectedAG( hsTaskData * pApp , hfp_profile pProfile ) ;static void slcProfileConnected (hsTaskData * pApp , HFP * pProfile, Sink sink ) ;static void slcHandleSlcConnectRequest(hsTaskData *app, hfp_profile profile , ARAction_t pAction );#define SLC_LINK_LOSS_RETRY_TIME_SECS 10/****************************************************************************NAME slcConnectFail DESCRIPTION SLC failed to connectRETURNS void*/static void slcConnectFail(hsTaskData *app){ /* Update the app state */ SLC_DEBUG(("SLC : det Pairing Fail \n")) ; headsetClearQueueudEvent ( app ) ;/* stateManagerEnterConnectableState( app ) ;*/ /* No connection */ app->profile_connected = hfp_no_profile; if (gSlcData.gLinkLossOccured) { SLC_DEBUG(("SLC: LinkLoss [%x]\n" , gSlcData.gLinkLossOccured)) ; MessageSendLater (&app->task , EventLinkLoss, 0 , D_SEC(SLC_LINK_LOSS_RETRY_TIME_SECS) ) ; /*attempts for n attempts until = 0 */ gSlcData.gLinkLossOccured-- ; } else { if ( (gSlcData.gNextPage == PageComplete ) || (gSlcData.gNextPage == PageUnknown) ) { /*then we have completed our PSKEY defined page routine unsuccessfully so reset for next time round*/ /*or we are in the unknown state as we were attempting to reconnect after a link loss - leave reset*/ gSlcData.gNextPage = PageUnknown ; /* As we have failed to conenct to an AG - its as if we have just powered on*/ /* JM01 - However, power on action maybe different to disconnect action */#if 0 gSlcData.gLastConnected = LastNone;#endif } else { /*then page something else */ MessageSend ( &app->task , EventEstablishSLC , 0 ) ; } } }/****************************************************************************NAME headsetHandleSlcConnectInd DESCRIPTION Handle a request to establish an SLC from the AG.RETURNS void*/void headsetHandleSlcConnectInd(hsTaskData *app, const HFP_SLC_CONNECT_IND_T *ind){ /* We support more than one HFP so check which one this request is for */ if (app->profile_connected == hfp_no_profile) { HfpSlcConnectResponse(ind->hfp, 1, &ind->addr, 0); /* See whether we are connecting as HSP or HFP */ if (ind->hfp == app->hfp) app->profile_connected = hfp_handsfree_profile; else if (ind->hfp == app->hsp) app->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); } gSlcData.gLinkLossOccured = 0 ; }/****************************************************************************NAME headsetHandleSlcConnectCfm DESCRIPTION Confirmation that the SLC has been established (or not).RETURNS void*/bool headsetHandleSlcConnectCfm(hsTaskData *app, const HFP_SLC_CONNECT_CFM_T *cfm){ bool lResult = FALSE ; /* Check the status of the SLC attempt */ if (cfm->status == hfp_connect_success) { slcProfileConnected(app, cfm->hfp, cfm->sink); lResult = TRUE ; gSlcData.gLinkLossOccured = 0 ; } else if (cfm->status == hfp_connect_sdp_fail) { /* We failed to find the hfp profile */ if (cfm->hfp == app->hfp) { /* Didn't find HFP so try HSP */ SLC_DEBUG(("SLC: CFM HFP Fail - Try HSP\n")) ; if ( gSlcData.gCurrPaging == PagingLast ) { slcConnectLastAG ( app , hfp_headset_profile ) ; } else { slcConnectDefaultAG ( app , hfp_headset_profile ) ; } } else if (cfm->hfp == app->hsp) { SLC_DEBUG(("SLC: CFP HSP Fail\n")) ; /* We try the HSP after we've tried HFP so this AG supports neither, give up */ slcConnectFail(app); } else /* Unknown profile instance */ Panic(); } else { /* Update local state to reflect this */ slcConnectFail(app); } return lResult ;}/****************************************************************************NAME slcHandleSlcConnectRequest DESCRIPTION Request to create a connection to a remote AG. This could have occured for several reasons - if we have just powerered on and are configured to auto connect - if we have failed to reconnect to the first device that we tried to connect to - if we have had a button event requesting connection - if we have had a link loss and wish to recover the last AG connected RETURNS void*/static void slcHandleSlcConnectRequest(hsTaskData *pApp, hfp_profile pProfile , ARAction_t pAction ){ if ( pAction == AR_LastConnected) { slcConnectLastConnectedAG (pApp, hfp_handsfree_profile); } else { switch (gSlcData.gNextPage) { case ( PageUnknown ): /* we are at the start of the pattern*/ { switch ( pAction ) { case AR_Last: gSlcData.gNextPage = PageComplete ; slcConnectLastAG ( pApp , pProfile ) ; SLC_DEBUG(("SLC: Page Last Only\n")) ; break ; case AR_Default: gSlcData.gNextPage = PageComplete ; slcConnectDefaultAG ( pApp , pProfile ) ; SLC_DEBUG(("SLC: Page Def Only\n")) ; break ; case AR_LastThenDefault: gSlcData.gNextPage = PageDefaultAG ; slcConnectLastAG ( pApp , pProfile ) ; SLC_DEBUG(("SLC: Page1 Last\n")) ; break ; case AR_DefaultThenLast: gSlcData.gNextPage = PageLastAG ; slcConnectDefaultAG ( pApp , pProfile ) ; SLC_DEBUG(("SLC: Page1 Def\n")) ; break ; default: break ; } } break ; case (PageDefaultAG ): { gSlcData.gNextPage = PageComplete ; slcConnectDefaultAG ( pApp , pProfile ) ; SLC_DEBUG(("SLC:Page2 Def\n")) ; } break ; case (PageLastAG ): { gSlcData.gNextPage = PageComplete ; slcConnectLastAG ( pApp , pProfile ) ; SLC_DEBUG(("SLC:Page1 Last\n")) ; } break; default: /*Paging attempts as per PSKEY's complete*/ break ; } }} /* Methods to connect to the last or default AG's*/ static void slcConnectDefaultAG ( hsTaskData * pApp , hfp_profile pProfile ){ bdaddr lDefaultAddr ; /* Retrieve the address of the default AG from PS */ if ( sizeof(bdaddr) == PsRetrieve(PSKEY_DEFAULT_AG, &lDefaultAddr, sizeof(bdaddr) ) ) { SLC_DEBUG(("SLC: Att Def[%x]\n" , pProfile)) ; slcAttemptConnect ( pApp , pProfile , &lDefaultAddr ) ; gSlcData.gCurrPaging = PagingDefault ; } else { /* we have failed to connect as we don't have a valid address */ SLC_DEBUG(("SLC: No Default Addr \n")) ; slcConnectFail (pApp); }}static void slcConnectLastAG ( hsTaskData * pApp , hfp_profile pProfile ){ bdaddr lLastAddr ; /* Retrieve the address of the last used AG from PS */ if (sizeof(bdaddr) == PsRetrieve(PSKEY_LAST_USED_AG, &lLastAddr, sizeof(bdaddr))) { SLC_DEBUG(("SLC: Att Last[%x]\n" , pProfile)) ; slcAttemptConnect ( pApp , pProfile , &lLastAddr ) ; gSlcData.gCurrPaging = PagingLast ; } else { /* we have failed to connect as we don't have a valid address */ SLC_DEBUG(("SLC: No Last Addr \n")) ; slcConnectFail (pApp); }}static void slcConnectLastConnectedAG( hsTaskData * pApp , hfp_profile pProfile ) { switch (gSlcData.gLastConnected) { case LastDefault: slcConnectDefaultAG( pApp , pProfile) ; break; case LastLast:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -