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

📄 connect.c

📁 蓝牙耳机软件源代码
💻 C
字号:
#include "demohs.h"
#include "hal.h"

#include <message.h>
#include <print.h>

#ifdef DEV_BOARD_HS
#include <pio.h>
#endif


/* 
   Specify the park and sniff parameters. To disable either mode
   use zero as the value for the intervals.
*/
static void default_park(cm_park_config_t *park)
{
    /* Set the max park interval to 1.28s min to 100ms */
    park->max_intval = 0x800;
    park->min_intval = 0x100;
}

static void default_sniff(cm_sniff_config_t *sniff)
{
    /* Set the max sniff interval to 40ms and min to 20ms */
    sniff->max_intval = 0x44;
    sniff->min_intval = 0x20;
    sniff->attempt = 0x02;
    sniff->timeout = 0x00;
}

static void connect_as_master(Delay timeout)
{
    /* Create a headset connect message primitive */
    MAKE_MSG(HS_CONNECT_AS_MASTER_REQ) ;            
    msg->timeout = timeout ;
    default_park(&msg->park);
    default_sniff(&msg->sniff);        
    
    /* Put the message in the scheduler queue */
    putMsg(msg) ;

    /* update the headset state variable */
    updateHsConnectState(connectingAsMaster);
}

static void connect_as_slave(Delay timeout,     /* How long to attempt connection (paging) */
                             uint16_t psinterval, /* page scan interval */
                             uint16_t pswindow,   /* page scan window */
                             uint16_t isinterval, /* inquiry scan interval */
                             uint16_t iswindow)   /* inquiry scan window */
{
    MAKE_MSG(HS_CONNECT_AS_SLAVE_REQ) ;                
    msg->timeout = timeout ;
    default_park(&msg->park);
    default_sniff(&msg->sniff);    
    
    msg->ps_interval = psinterval ;      /* page scan interval */
    msg->ps_window = pswindow ;          /* page scan window */
    msg->is_interval = isinterval;       /* inquiry scan interval */
    msg->is_window = iswindow;           /* inquiry scan window */
        
    /* Put the message in the scheduler queue */
    putMsg(msg) ;

    /* update the headset state variable */
    updateHsConnectState(connectingAsSlave);
}


/*
    Ask the framework to send a button press
*/
static void sendButtonPress(void)
{
    /* create a headset message primitive */
    MAKE_MSG(HS_BUTTON_REQ) ;
    /* put the message on the scheduler queue */
    putMsg(msg);    
}


/*
    cancelOperation

    Request to cancel the current state of the headset
*/
void cancelOperation(void)
{
    MAKE_MSG(HS_CANCEL_REQ) ;
    putMsg(msg) ;
}


/*
    talkButton
    
    Create a connection to the AG we're paired with or send a button
    press if already connected.
*/
void talkButton(void)
{
    hsState.buttonPressPending = 0 ; /* we are processing the button press */

    switch (hsState.connectState)
    {
        /*
            Headset is idle, attempt to connect to the Audio Gateway
            which is the only paired device.  Initiating the
            connection means the headset is the master.  A
            master-slave switch procedure will be initiated upon
            connection.
        */
        case idle :
            hsState.buttonPressPending = 0;
            connect_as_slave(SLAVE_CONNECT_TIMEOUT, 0x800, 0x12, 0, 0); 
            break ;

        /* 
            If the headset is already attempting to connect as the
            master, cancel the operation and return to idle state.
        */
        case connectingAsMaster :
            cancelOperation() ;
            hsState.connectAsMasterPending = 0 ;
            break ;

        /* 
            If the headset is already attempting to connect as the
            slave, cancel the operation and attempt to connect as
            master.
        */
        case connectingAsSlave :
            hsState.buttonPressPending = 1 ;
            hsState.connectAsMasterPending = 1 ;
            cancelOperation() ;     /* return to idle */
            break ;

        /* 
            If the headset is already connected, send the button press
            to the headset framework task.
        */
        case connected :
            sendButtonPress() ;
            break;

        /* 
            If the headset is currently attempting to pair, reject the
            button press because the headset cannot do anything until
            it is paired with the Audio Gateway
        */
        case pairing :
            break ;

        default:
            PRINT(("headset\talkbutton.c - talkbutton() - invalid state: 0x%2x\n", 
                   hsState.connectState));
            break ;
    }
}


/*
    connectCfm

    After sending a connectReq, we expect to see a confirm.  If the
    connection was successful we may need to send a button press,
    otherwise we just return to idle.
*/

void connectCfm(const HS_CONNECT_CFM_T * cfm)
{    
    /* Take action based on the outcome of the connection process. */
    switch (cfm->status)
    {
        /* The connection has been completed */
        case CmConnectComplete :
            /* Set the headset state to indicate it is connected */
            updateHsConnectState(connected);
            
            /*  
                If the connection was the result of a user button
                press, send the user button press to the Audio
                Gateway.
            */            
            if (hsState.buttonPressPending) 
            {                
                sendButtonPress() ;
            }            
            break ;
            
        /* If the connection was cancelled, maybe we are just switching roles. */
        case CmConnectCancelled :
            /* 
                Check to see if we are now attempting to switch from a
                master role to a slave.
            */
#ifdef DEV_BOARD_HS
            /* if we're trying to deep sleep don't re-enter pairing mode */
            if (hsState.turnOffHs)
            {
                updateHsConnectState(idle);
                return;
            }
#endif
            if (hsState.connectAsMasterPending) 
            {
                /* 
                    Reset the connect as slave pending flag to false
                    because we are actually connecting now...no longer
                    pending
                */
                hsState.connectAsMasterPending = 0 ;
                
                /* resend the connect command with new values*/
                connect_as_master(MASTER_CONNECT_TIMEOUT); 
            }
            else if (hsState.pairingPending)
            {                
                updateHsConnectState(idle);
                pairButton();
            }
            else
            {
                /* 
                    If we are not switching roles to a slave, then
                    jump to idle state and await further input.
                */
                updateHsConnectState(idle);

#ifdef DEV_BOARD_HS
                talkButton(); /* Enable to be always connectable */
#endif
            }
            break ;
            
        /* For all other connection results, jump to idle state. */
        case CmConnectTimeout:
        case CmConnectDisconnect:
        case CmConnectDisconnectAbnormal:
        case CmConnectFailed:
        default: 
            PRINT(("connectCfm: unhandled connect state %d\n", cfm->status));
            updateHsConnectState(idle);

#ifdef DEV_BOARD_HS
            talkButton();  /* Enable to be always connectable */
#endif
            break ;
    }
}


/*
    HS_onConnectStatus
    
    Called by the headset framework to indicate that the RFCOMM connection has 
    changed state. At the moment, this can only ever be for rfcomm going down
*/
void connectStatusInd(HS_CONNECT_STATUS_IND_T * ind)
{
    /* not using this right now.  Just avoiding warnings */
    ind=ind;

#ifdef DEV_BOARD_HS
    /* 
        If rfcomm was disconnected abnormally the codec will still be powered 
        on so disable it here
    */
    if (ind->status == CmConnectDisconnectAbnormal)
    {
        /* disable the codec */
        PioSet(PIO_CODEC, CODEC_OFF);
    }    
#endif

    /* cannot have the SCO connected if we don't have an rfcomm connection */
    hsState.scoConnected = 0;

    /* 
        Since this function is only called when the RFCOMM connection is
        lost, indicate that there is no connection by setting the headset 
        state to idle
    */
    updateHsConnectState(idle);

#ifdef DEV_BOARD_HS
    talkButton();  /* Enable to be always connectable */
#endif
}

⌨️ 快捷键说明

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