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

📄 connect.c

📁 蓝牙HANDFREE软件源代码
💻 C
字号:
#include "handsfree_private.h"
#include "handsfree.h"


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


/* 
   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 = 0x40;
    sniff->min_intval = 0x20;
    sniff->attempt = 0x01;
    sniff->timeout = 0x00;
}


/*
  connectMaster 

  Internal function to request framework to connect as master using the
  specified parameters.
*/
static void connectMaster(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);        
    putMsg(msg) ;

    setLocalState(connectingAsMaster);
}



/*
  connectSlave 

  Internal function to request framework to connect as slave using the
  specified parameters.
*/
static void connectSlave(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 */            
    putMsg(msg) ;

    setLocalState(connectingAsSlave);
}


/*
  connectReqAction

  Attempt to connect to the device paired with as either master or
  slave.
*/
void connectReqAction(void)
{
    switch (HFstate.connectState)
    {
        /*
          Hands-free is idle, attempt to connect to the Audio
          Gateway which is the only paired device.  Initiating the
          connection means the hands-free is the master.
        */
    case idle :
			
        connectSlave(SLAVE_CONNECT_TIMEOUT, 0x800, 0x12, 0x400, 0x200) ; 

        break ;

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

        /* 
           If the hands-free is already attempting to connect as the
           slave, cancel the operation and attempt to connect as
           master.
        */
    case connectingAsSlave :
        HFstate.connectAsMasterPending = 1 ;
        cancelCurrentStateAction(); /* return to idle */
        break ;

        /* 
           If the hands-free is currently attempting to pair, reject
           the button press because it cannot do anything until it is
           paired with the Audio Gateway.
        */
    case pairing :
        /* CAnnot connect whilst pairing */            
        handleErrorInd(HfErrorConnectRequestWhenNotIdle);
        break ;

    default:
        PRINT(("connect.c - talkbutton() - invalid state: 0x%2x\n", 
               HFstate.connectState));
        handleErrorInd(HfErrorUnknownOrUnhandledState);
        break ;
    }
}


/*
  hfConnectCfm

  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 hfConnectCfm(const HS_CONNECT_CFM_T * cfm)
{
    /* reset the current role */
    HFstate.applicationRole = frameworkRoleUnset;

    /* Take action based on the outcome of the connection process. */
    switch (cfm->status)
    {
        /* The connection has been completed */
    case CmConnectComplete :
    {
        uint16 old_connect_state = HFstate.connectState;

        /* 
           Workaround, in case AG opens SCO before SLC is established 
           (out of HFP spec but it happens)
        */
        if (old_connect_state == scoConnected)
        {
            /* Set back to SCO connected since it was reset to idle above */
            setLocalState(scoConnected);

            /* Reset the pending flag, the AG has already opened the SCO */
            HFstate.audioTransferPending = 0;
        }
        else
        {
            /* Set the headset state to indicate it is connected */
            setLocalState(connected);
        }

        /* store and check the role we have connected as */
        HFstate.applicationRole = cfm->profile_role;

        if (HFstate.applicationRole == frameworkHandsFree)
        {
            /* Check if there is a dial request pending */
            hfCheckDialPendingFlags();

            /* Check if there was an audio transfer event pending */
            if (HFstate.audioTransferPending)
                callTransferReqAction(HFstate.SCOpktType);

            /* Check if voice dialling is pending */
            if (HFstate.voiceDialPending)
                startVoiceDialAction(1);

            /* TODO on exiting here none of the pending flags must be set 
                
            TODO above it should be an "else if" becuase only one
            pending flag should be set.
            */
        }
            
        /* Let the interface app do what it will */
        handleConnectComplete();
    }
    break ;
            
    /* If the connection was cancelled, maybe we are just switching roles */
    case CmConnectCancelled:
        /* Update the local state to idle */
        setLocalState(idle);

        /* Check if we are trying to switch from a slave to a master. */
        if (HFstate.connectAsMasterPending) 
        {
            /* 
               Reset the connect as slave pending flag to false
               because we are actually connecting now...no longer
               pending.
            */
            HFstate.connectAsMasterPending = 0 ;
                
            /* Resend the connect command with new values*/
            connectMaster(MASTER_CONNECT_TIMEOUT); 
        }
        else if (HFstate.pair_data)
        {
            /* Request to enter pairing mode */
            pairReqAction(HFstate.pair_data->pairing_timeout, HFstate.pair_data->pairing_role);

            /* If we had stored pairing data free it as its no longer needed */
            if (HFstate.pair_data)
                free(HFstate.pair_data);
            HFstate.pair_data = 0;
        }            
        else
        {                
            /* Default to slave connect mode */
            connectReqAction();
        }
        break ;
            
        /* For all other connection results, jump to idle state */
    case CmConnectTimeout:
    case CmConnectDisconnect:
    case CmConnectDisconnectAbnormal:
    case CmConnectRemoteRefusal:
    case CmConnectServiceNotSupported:
    case CmConnectFailed:
        /* Update the local state to idle */

        setLocalState(idle);

        /* Make sure we free any allocated memory */
        hfResetConnectionState();

        /* Default to slave connect mode */
        connectReqAction();
        break;

    default: 
        /* Update the local state to idle */
        setLocalState(idle);

        PRINT(("handleConnectCfm: unhandled connect state %d\n", cfm->status));
        handleErrorInd(HfErrorUnknownOrUnhandledState);
        break ;
    }
}


/*
  handleConnectStatusInd

  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 hfConnectStatusInd(HS_CONNECT_STATUS_IND_T * ind)
{
    ind = ind ; /* not using this right now.  Just avoiding warnings */
   
    /* 
       Since this function is only called when the RFCOMM connection is
       lost, indicate that there is no connection by setting the hands-free 
       state to idle
    */

    setLocalState(idle);

    /* Reset all state that may have been set during the connection */
    hfResetConnectionState();

    /* Default to slave connect mode */
    connectReqAction();
}


/*
  hfSendDisconnectMessage

  Create a disconnect message and send it
*/
void hfSendDisconnectMessage(hf_link_type_t link)
{
    MAKE_MSG(HANDSFREE_DISCONNECT_REQ);
    msg->connectionType = (link_type_t) link;
    putMsg(msg);
}


/*  
    disconnectReqAction

    Send a disconnect request to disconnect the SCO (if up) or the
    RFCOMM connection (this also releases the SCO if one exists.)
*/
void disconnectReqAction(hf_link_type_t link)
{    
    if (isLocalStateConnected())
    {
        /* Check which type of link to disconnect. */
        if (link == ScoLink)
            hfSendDisconnectMessage(ScoLink);
        else 
            hfSendDisconnectMessage(RfcommLink);
    }
    else
    {
        /* Not connected so send up an error */
        handleErrorInd(HfErrorDisconnectRequestWhenNotConnected);
    }
}

⌨️ 快捷键说明

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