www.pudn.com > headset.rar > connect.c


#include "demohs.h" 
#include "hal.h" 
 
#include  
#include  
 
#ifdef DEV_BOARD_HS 
#include  
#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 
}