Esempio n. 1
0
/****************************************************************************
NAME    
    deviceManagerNumConnectedDevs
    
DESCRIPTION
   determines the number of different connected devices, a device may connected
   both hfp and a2dp or only one of each
RETURNS
    number of connected devices
*/
uint8 deviceManagerNumConnectedDevs(void)
{
    conn_mask mask;
    bdaddr dev_addr;
    uint8 no_devices = 0;
    /* Go through all profiles */
    for(mask = conn_hfp_pri; mask <= conn_a2dp_sec; mask <<=1)
    {
        /* Get bluetooth address for profile if connected */
        if(deviceManagerGetProfileAddr(mask, &dev_addr))
        {
            /* If HFP connection, or A2DP connection on device with no HFP... */
            if( (mask & conn_hfp) || (!(conn_hfp & deviceManagerProfilesConnected(&dev_addr))) )
                no_devices++;
        }
    }
    DEV_DEBUG(("DEV: Conn Count %d\n", no_devices));
    return no_devices;
}
Esempio n. 2
0
/****************************************************************************
NAME
    deviceManagerSetPriority
    
DESCRIPTION
    Set a device's priority in the PDL

RETURNS
    new pdl listId of passed in src addr
*/
uint8 deviceManagerSetPriority(const bdaddr* dev_addr)
{
    conn_mask mask = deviceManagerProfilesConnected(dev_addr);
    uint8 ListId = 0;
    
    DEV_DEBUG(("DEV: Update PDL/MRU\n")) ;

    
    /* more than 1 connected device ? */
    if(deviceManagerNumConnectedDevs() > 1)
    {
        typed_bdaddr  typed_ag_addr;
        bdaddr ag_addr;
        sink_attributes attributes;      
 

        DEV_DEBUG(("DEV: Update MRU - two devices connected\n")) ;
        
        /* is this a connection of a2dp or hfp to the already connected primary device ? */            
        deviceManagerGetIndexedAttributes(0, &attributes, &typed_ag_addr);
        /* extract bluetooth address from packed structure */
        ag_addr = typed_ag_addr.addr;
        /* check if this is the primary device? */
        if(BdaddrIsSame(&ag_addr,dev_addr))
        {
            DEV_DEBUG(("DEV: Update MRU - two devices two profiles connected - primary device\n")) ;
            ListId = 0;
        }
        else
        {
            DEV_DEBUG(("DEV: Update MRU - two devices two profiles connected - secondary device\n")) ;
            /* Move the second device to top of the PDL */
            ConnectionSmUpdateMruDevice(dev_addr);      
            /* get bdaddr of the device that was previously the primary device but is
               now the secondary device */
            deviceManagerGetIndexedAttributes(1, &attributes, &typed_ag_addr);
            /* extract bluetooth address from packed structure */
            ag_addr = typed_ag_addr.addr;
            /* then move the what is now 'secondary device' back to the top of the PDL */                
            ConnectionSmUpdateMruDevice(&ag_addr);              
            /* this is the secondary device */
            ListId = 1;
            /* send connected event if not already done so */
            if(mask && !((mask & conn_hfp)&&(mask & conn_a2dp)))
            {
               MessageSend (&theSink.task , EventSecondaryDeviceConnected , NULL );        
            }
        }        
    }
    /* only 1 device so must be primary */
    else
    {
        /* Move device to top of the PDL */
        DEV_DEBUG(("DEV: Update MRU - primary device\n")) ;
        ConnectionSmUpdateMruDevice(dev_addr);    
        /* if this is the first profile for the device to be connected then send
           the primary device connected event */
        if(mask && !((mask & conn_hfp)&&(mask & conn_a2dp)))
        {
           MessageSend (&theSink.task , EventPrimaryDeviceConnected , NULL );        
        }
    }
   
    /* return current pdl list position of this device which is 0, top of list */        
    DEV_DEBUG(("DEV: Update MRU - ListId = %x\n",ListId)) ;
    return ListId;
}
Esempio n. 3
0
/****************************************************************************
NAME    
    sinkHandleSlcDisconnectInd
    
DESCRIPTION
    Indication that the SLC has been released.

RETURNS
    void
*/
void sinkHandleSlcDisconnectInd( const HFP_SLC_DISCONNECT_IND_T *ind )
{	    
    conn_mask mask = deviceManagerProfilesConnected(&ind->bd_addr);

    SLC_DEBUG(("SLC: slc DiscInd for index %d, status = %d\n",ind->priority, ind->status)) ;     
        
    if(ind->status == hfp_disconnect_success || ind->status == hfp_disconnect_link_loss || ind->status == hfp_disconnect_abnormally)
    {
        /* store volume info */
        deviceManagerUpdateAttributes(&ind->bd_addr, sink_hfp, ind->priority, 0); 

        /* Sends the indication to the device manager to send an event out if a device has disconnected*/
        deviceManagerDeviceDisconnectedInd(&ind->bd_addr);
	
        /*if the device is off then this is disconnect as part of the power off cycle - dont re-enable connectable*/	
    	if ( stateManagerGetState() != deviceLimbo)
        {
            /* Enable A2dp link loss management if connected on remote device */
            if( theSink.a2dp_link_data && (theSink.a2dp_link_data->connected[a2dp_primary]) && BdaddrIsSame(&ind->bd_addr, &theSink.a2dp_link_data->bd_addr[a2dp_primary]) )
            {
                A2dpDeviceManageLinkloss(theSink.a2dp_link_data->device_id[a2dp_primary], TRUE);
            }
            else if( theSink.a2dp_link_data && (theSink.a2dp_link_data->connected[a2dp_secondary]) && BdaddrIsSame(&ind->bd_addr, &theSink.a2dp_link_data->bd_addr[a2dp_secondary]) )
            {
                A2dpDeviceManageLinkloss(theSink.a2dp_link_data->device_id[a2dp_secondary], TRUE);
            }

            /* Kick role checking now a device has disconnected */
            linkPolicyCheckRoles();

            /* at least one device disconnected, re-enable connectable for another 60 seconds */
            sinkEnableMultipointConnectable();
        }
    
        /*a disconnect in active call state is a call transfer*/
        if ( (stateManagerGetState() == deviceActiveCallSCO) || 
             (stateManagerGetState() == deviceActiveCallNoSCO) )
        {
		    gSlcData.gCallTransferInProgress = TRUE ;           
        }
        else
        {
		    gSlcData.gCallTransferInProgress = FALSE ;	
        }
    
        /* if not a link loss reset the last outgoing AG as AG1 will no longer exist now */        
        theSink.last_outgoing_ag = hfp_primary_link;

        /* reset the list id of the device just dropped */              
        theSink.profile_data[PROFILE_INDEX(ind->priority)].status.list_id = INVALID_LIST_ID;

        /* if device has now disconnected all profiles, mark as disconnected */
        if((ind->status != hfp_disconnect_link_loss)&&(!(mask & conn_hfp)))
            theSink.profile_data[PROFILE_INDEX(ind->priority)].status.connected = FALSE;
        
        /* If primary disconnected */
        if(ind->priority == hfp_primary_link)
        {
            /* ...and we have a secondary link it will be promoted to primary */
            if(theSink.profile_data[PROFILE_INDEX(hfp_secondary_link)].status.list_id != INVALID_LIST_ID)
            {
                /* Block copy secondary data to primary location */
                theSink.profile_data[PROFILE_INDEX(hfp_primary_link)] = theSink.profile_data[PROFILE_INDEX(hfp_secondary_link)];
                /* Secondary link no longer exists, set it to invalid */
                theSink.profile_data[PROFILE_INDEX(hfp_secondary_link)].status.list_id = INVALID_LIST_ID;
            }
        }
        /* send event slc disconnected only if the status of the indication is success or link loss indication */
        MessageSend(&theSink.task , ((ind->status == hfp_disconnect_link_loss) ? EventSysReconnectFailed : EventSysSLCDisconnected) , 0) ;
    }
    

    /*if the device is off then this is disconnect as part of the power off cycle, otherwise check
      whether device needs to be made connectable */	
	if ( stateManagerGetState() != deviceLimbo)
    {
	    /* if the device state still shows connected and there are no profiles currently
           connected then update the device state to reflect the change of connections */
	    if ((stateManagerIsConnected()) && (!deviceManagerNumConnectedDevs()))
	    {
	        stateManagerEnterConnectableState( FALSE ) ;
	    }
    }
    
}