Beispiel #1
0
/****************************************************************************
NAME
    deviceManagerStoreDefaultAttributes
    
DESCRIPTION
    Stores the default attributes against a given device in PS.

RETURNS
    void
*/
void deviceManagerStoreDefaultAttributes(const bdaddr* dev_addr, bool is_subwoofer)
{
    sink_attributes attributes;
    
#ifdef ENABLE_SUBWOOFER
    if (is_subwoofer)
    {
        /* Setup and store attributes for the subwoofer device */
        sink_attributes attributes;
        deviceManagerGetDefaultAttributes(&attributes, TRUE);
        deviceManagerStoreAttributes(&attributes, dev_addr);
        return;
    }
#endif
    
    deviceManagerGetDefaultAttributes(&attributes, FALSE);
    DEV_DEBUG(("DEV: StoreDefaultAttribs   - profiles %d, hfp_vol %d, a2dp_vol %d\n", attributes.profiles, attributes.hfp.volume,attributes.a2dp.volume));
    deviceManagerStoreAttributes(&attributes, dev_addr);
}
Beispiel #2
0
/****************************************************************************
NAME    
    handleGetAuthDeviceCfm
    
DESCRIPTION
    Called in response to CL_SM_GET_AUTH_DEVICE_CFM message, which is generated
    due to calling updatePermanentPairing.
    Both the BDADDR and linkkey contained in CL_SM_GET_AUTH_DEVICE_CFM are used to
    update CONFIG_PERMANENT_PAIRING to retain this as the permanently paired device
    
RETURNS
    void
*/
void handleGetAuthDeviceCfm (CL_SM_GET_AUTH_DEVICE_CFM_T *cfm)
{
    AUTH_DEBUG(("handleGetAuthDeviceCfm\n"));
    AUTH_DEBUG(("   status = %u\n",cfm->status));
    AUTH_DEBUG(("   ps bd_addr = [%x:%x:%lx]\n", cfm->bd_addr.uap, cfm->bd_addr.nap, cfm->bd_addr.lap));
    AUTH_DEBUG(("   trusted = %u\n",cfm->trusted));
    AUTH_DEBUG(("   link key type = %u",cfm->link_key_type));
    AUTH_DEBUG(("   link key size = %u\n",cfm->size_link_key));
    
    if ( cfm->status == success )
    {   /* Device exists in CL PDL */
        sink_attributes attributes;
        uint16 link_key_status = ((cfm->trusted & 0xF)<<8) | ((cfm->link_key_type & 0xF)<<4) | (cfm->size_link_key & 0xF);
        
        /* Update permanent pairing info */
        writePsPermanentPairing(&cfm->bd_addr, cfm->link_key, link_key_status, 0);
        
        /* Update attributes */
        readPsPermanentPairing(0, 0, 0, &attributes);
        deviceManagerStoreAttributes(&attributes, (const bdaddr *)&cfm->bd_addr);
        
        /* Mark the device as trusted and push it to the top of the PDL */
        ConnectionSmUpdateMruDevice((const bdaddr *)&cfm->bd_addr);
#ifdef ENABLE_SOUNDBAR
        /* ensure priority devices are shifted back to top of PDL */
        ConnectionAuthSetPriorityDevice((const bdaddr *)&cfm->bd_addr, FALSE);            
#endif            
    }
    else
    {   /* Device *does not* exist in CL PDL */ 
        bdaddr ps_bd_addr;
        uint16 ps_link_key_status;
        uint16 ps_link_key[LINK_KEY_SIZE];
    
        readPsPermanentPairing(&ps_bd_addr, ps_link_key, &ps_link_key_status, 0);
    
        if ( !BdaddrIsZero(&ps_bd_addr) )
        {   /* We have permanently paired device, add it to CL PDL */
            bool trusted = (bool)((ps_link_key_status>>8) & 0xF);
            cl_sm_link_key_type key_type = (cl_sm_link_key_type)((ps_link_key_status>>4) & 0xF);
            uint16 size_link_key = ps_link_key_status & 0xF;
        
            ConnectionSmAddAuthDevice(&theSink.task, (const bdaddr *)&ps_bd_addr, trusted, TRUE, key_type, size_link_key, (const uint16 *)ps_link_key);
        }
    }
Beispiel #3
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);
}
Beispiel #4
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 ;
}