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

📄 headset_slc.c

📁 bluelab的一个很好的例程
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
Copyright (C) Cambridge Silicon Radio Ltd. 2004

FILE NAME
    headset_slc.c

DESCRIPTION
    

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 connect
RETURNS
    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:
            slcConnectLastAG( pApp , pProfile) ;

⌨️ 快捷键说明

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