Example #1
0
/****************************************************************************
NAME    
    slcHandleLinkLossInd
    
DESCRIPTION
    Indication of change in link loss status.

RETURNS
    void
*/
void slcHandleLinkLossInd( const HFP_SLC_LINK_LOSS_IND_T *ind )
{
    typed_bdaddr ag_addr;

    Sink sink;
    /* Are we recovering or have we recovered? */
    if(ind->status == hfp_link_loss_recovery)
    {
        /* Send an event to notify the user */
        MessageCancelAll(&theSink.task , EventSysLinkLoss );
        MessageSend(&theSink.task , EventSysLinkLoss , 0);
        /* Go connectable if feature enabled */
        if(theSink.features.GoConnectableDuringLinkLoss)
            sinkEnableConnectable(); 
    }
    else if(ind->status == hfp_link_loss_none)
    {
        sink_attributes attributes;

        /* Get Sink and bdaddr for the link */
        HfpLinkGetSlcSink(ind->priority, &sink);
        SinkGetBdAddr(sink, &ag_addr);

            /* Carry out link setup */
        slcConnectionSetup(ind->priority, sink, &ag_addr.addr);
       
        /* Link loss recovered - disable connectable */
        if(theSink.features.GoConnectableDuringLinkLoss)
        {
#ifdef ENABLE_SUBWOOFER     
            if(SwatGetSignallingSink(theSink.rundata->subwoofer.dev_id))
            {
               sinkDisableConnectable();            
            }        
#else
        sinkDisableConnectable();            
#endif        
        }

        /* Reconnect A2DP if appropriate */
        if( theSink.features.EnableA2dpStreaming && 
            deviceManagerGetAttributes(&attributes, (const bdaddr *)&ag_addr.addr) && 
            (attributes.profiles & sink_a2dp) )
        {  
            SLC_DEBUG(("SLC: Reconnecting A2DP\n")) ;
            /* attempt reconnection to device supporting A2DP */
            A2dpSignallingConnectRequest((bdaddr *)&ag_addr.addr);
        }
    }
}
Example #2
0
/****************************************************************************
NAME
    deviceManagerDelayedUpdateAttributes
    
DESCRIPTION
    Store attributes contained in EVENT_UPDATE_ATTRIBUTES_T in PS

RETURNS
    void
*/
void deviceManagerDelayedUpdateAttributes(EVENT_UPDATE_ATTRIBUTES_T* update)
{
	sink_attributes attributes;
    sink_attributes new_attributes;

    /* zero settings */
    memset(&new_attributes,0,sizeof(sink_attributes));
    
    /* Get attributes from PS */
    deviceManagerGetDefaultAttributes(&attributes, FALSE);
    deviceManagerGetAttributes(&attributes, &update->bd_addr);

    if(update->attributes.profiles == sink_hfp)
    {
        /* Update with current attribute values */
        new_attributes = attributes;
        new_attributes.profiles |= sink_hfp;
        new_attributes.hfp.volume = update->attributes.hfp.volume;
    }
    else if(update->attributes.profiles == sink_a2dp)
    {
        /* Update with current attribute values */
        new_attributes = attributes;
        new_attributes.profiles |= sink_a2dp;
        new_attributes.a2dp.volume = update->attributes.a2dp.volume;
        new_attributes.a2dp.clock_mismatch = update->attributes.a2dp.clock_mismatch;
    }
#ifdef ENABLE_SUBWOOFER
    else if(update->attributes.profiles == sink_swat)
    {
        new_attributes.sub.sub_trim = update->attributes.sub.sub_trim;
        new_attributes.profiles = sink_swat;
    }
#endif    
    
    DEV_DEBUG(("DEV: UpdateAttributesOld - profiles %d, hfp_vol %d, a2dp_vol %d, clock_mismatch %d\n", attributes.profiles, attributes.hfp.volume,
                                                                                         attributes.a2dp.volume, attributes.a2dp.clock_mismatch));
    DEV_DEBUG(("DEV: UpdateAttributesNew - profiles %d, hfp_vol %d, a2dp_vol %d, clock_mismatch %d\n", new_attributes.profiles, new_attributes.hfp.volume,
                                                                                         new_attributes.a2dp.volume, new_attributes.a2dp.clock_mismatch));
    /* Write updated attributes to PS */
    if(!deviceManagerCompareAttributes(&attributes, &new_attributes))
        deviceManagerStoreAttributes(&new_attributes, &update->bd_addr);
}
Example #3
0
/****************************************************************************
NAME    
    sinkHandleSlcConnectCfm
    
DESCRIPTION
    Confirmation that the SLC has been established (or not).

RETURNS
    void
*/
bool sinkHandleSlcConnectCfm( const HFP_SLC_CONNECT_CFM_T *cfm )
{
    sink_attributes attributes;
    bool lResult = FALSE;
    
#ifdef ENABLE_PEER    
    inquiry_result_t* connecting_device = inquiryGetConnectingDevice();
#endif
    
    deviceManagerGetDefaultAttributes(&attributes, FALSE);
    (void)deviceManagerGetAttributes(&attributes, &cfm->bd_addr);
    
    /* cancel any link loss reminders */        
    MessageCancelAll(&theSink.task , EventSysLinkLoss );

    /* Check the status of the SLC attempt */
    if (cfm->status == hfp_connect_success)
    {
        SLC_DEBUG(("SLC: ConnCfm - Success\n")) ;
        lResult = TRUE ;

        /* update the profile volume level */
        theSink.profile_data[PROFILE_INDEX(cfm->priority)].audio.gSMVolumeLevel = attributes.hfp.volume;     
        /* Handle new connection setup */
        slcConnectionComplete(cfm->priority, cfm->sink, (bdaddr *)&cfm->bd_addr);
        /* Handle common setup for new SLC/link loss */
        slcConnectionSetup(cfm->priority, cfm->sink, (bdaddr *)&cfm->bd_addr);
        /* Record the position of the device in the PDL - prevents reconnection later */
        theSink.profile_data[PROFILE_INDEX(cfm->priority)].status.list_id = deviceManagerSetPriority((bdaddr *)&cfm->bd_addr);
        
#ifdef ENABLE_PEER
        /* If RSSI pairing, check inquiry results for A2DP support */
        if (theSink.inquiry.action == rssi_pairing)
        {
            if ((connecting_device != NULL) && BdaddrIsSame(&connecting_device->bd_addr, &cfm->bd_addr) && (connecting_device->remote_profiles & profile_a2dp))
            {
                attributes.profiles |= sink_a2dp;
            }
        }
#endif
        
        /* Make sure we store this device */
        attributes.profiles |= sink_hfp;
        deviceManagerStoreAttributes(&attributes, &cfm->bd_addr);
                
        /* if rssi pairing check to see if need to cancel rssi pairing or not */           
        if(theSink.inquiry.action == rssi_pairing)
        {   
            /* if rssi pairing has completed and the device being connected currently doesn't support A2DP, then stop it progressing further */            
            if(!((theSink.features.PairIfPDLLessThan) && ( ConnectionTrustedDeviceListSize() < theSink.features.PairIfPDLLessThan )))
            {
#ifdef ENABLE_PEER                
                if(!((connecting_device != NULL) && BdaddrIsSame(&connecting_device->bd_addr, &cfm->bd_addr) && (connecting_device->remote_profiles & profile_a2dp)))
#endif
                {
                    inquiryStop();
                }
            }
        }

        /* Disable A2dp link loss management if connected on remote device */
        if( theSink.a2dp_link_data && (theSink.a2dp_link_data->connected[a2dp_primary]) && BdaddrIsSame(&cfm->bd_addr, &theSink.a2dp_link_data->bd_addr[a2dp_primary]) )
        {
            A2dpDeviceManageLinkloss(theSink.a2dp_link_data->device_id[a2dp_primary], FALSE);
        }
        else if( theSink.a2dp_link_data && (theSink.a2dp_link_data->connected[a2dp_secondary]) && BdaddrIsSame(&cfm->bd_addr, &theSink.a2dp_link_data->bd_addr[a2dp_secondary]) )
        {
            A2dpDeviceManageLinkloss(theSink.a2dp_link_data->device_id[a2dp_secondary], FALSE);
        }

        /* Auto answer call if ringing - only answer the incoming call if its 
           on the connecting AG */
        if ( (theSink.features.AutoAnswerOnConnect) && (HfpLinkPriorityFromCallState(hfp_call_state_incoming) == cfm->priority) && (stateManagerGetState() < deviceActiveCallSCO) )
        {
            MessageSend (&theSink.task , EventUsrAnswer , 0 ) ;
            SLC_DEBUG(("SLC: AutoAnswer triggered\n")) ;
        }
    }
    else
    {
        SLC_DEBUG(("SLC: ConnCfm - Fail\n")) ;
        
        /* a connection timeout will arrive here, need to report fail for multipoint
           connections also such that a link loss retry will be performed */
        if(!stateManagerIsConnected() || theSink.MultipointEnable)
        {
            /* Update local state to reflect this */
            slcConnectFail();
        }
    }
 
    /* if using multipoint and both devices are connected disable connectable */
    if((theSink.MultipointEnable) && (deviceManagerNumConnectedDevs() == MAX_MULTIPOINT_CONNECTIONS))
    {
        SLC_DEBUG(("SLC: disable Conn \n" ));
        MessageCancelAll(&theSink.task, EventSysConnectableTimeout);

#ifdef ENABLE_SUBWOOFER     
        if(SwatGetSignallingSink(theSink.rundata->subwoofer.dev_id))
        {
           sinkDisableConnectable();            
        }        
#else
        sinkDisableConnectable();            
#endif        
    }
    
    SLC_DEBUG(("SLC: Connect A2DP? En=%d att=%d\n",theSink.features.EnableA2dpStreaming,attributes.profiles)) ;
    
    /* if the AG supports A2DP profile attempt to connect to it if auto reconnect is enabled */
    if ((theSink.features.EnableA2dpStreaming) && 
         ((!cfm->priority)||(cfm->status == hfp_connect_success) || (cfm->status == hfp_connect_sdp_fail) || (cfm->status == hfp_connect_rejected)) &&
         ((slcDetermineConnectAction() & AR_Rssi)||(attributes.profiles & sink_a2dp)) &&                         
         ((slcDetermineConnectAction() & AR_Rssi)||(stateManagerGetState()!=deviceConnDiscoverable)))                          
    {
        SLC_DEBUG(("SLC: Connecting A2DP Remote %x\n",gSlcData.gSlcConnectRemote)) ;
        /* attempt connection to device supporting A2DP */
        theSink.a2dp_link_data->remote_connection = gSlcData.gSlcConnectRemote;
        A2dpSignallingConnectRequest((bdaddr *)&cfm->bd_addr);
        MessageCancelFirst(&theSink.task, EventSysContinueSlcConnectRequest);
        /* if rssi pairing check to see if need to cancel rssi pairing or not */           
        if(theSink.inquiry.action == rssi_pairing)
        {
            /* if rssi pairing has completed then stop it progressing further */            
            if(!((theSink.features.PairIfPDLLessThan)&&( ConnectionTrustedDeviceListSize() < theSink.features.PairIfPDLLessThan )))
            {
#ifdef ENABLE_PEER                
                if(!((connecting_device != NULL) && BdaddrIsSame(&connecting_device->bd_addr, &cfm->bd_addr) && (connecting_device->remote_profiles & profile_a2dp)))
#endif                   
                {
                    inquiryStop();
                }
            }
        }
    }
    else
    {
        /* reset connection via remote ag instead of device flag */
        gSlcData.gSlcConnectRemote = FALSE;
    }

#ifdef ENABLE_MAPC
    mapcMasConnectRequest((bdaddr *)&cfm->bd_addr);    
#endif
    
    return lResult ;
}