Ejemplo n.º 1
0
/****************************************************************************
NAME	
	linkPolicyPhonebookAccessComplete

DESCRIPTION
	set the link policy requirements back after phonebook access, based on current device audio state 
	
RETURNS
	void
*/
void linkPolicyPhonebookAccessComplete(Sink sink)
{
    typed_bdaddr taddr;
    uint16 DeviceId;
    uint16 StreamId;
    uint8 i;
    bool  a2dpSetting = FALSE;
        
    /* If device is in the stream a2dp state, use a2dp link policy */
    for_all_a2dp(i)
    {
        DeviceId = theSink.a2dp_link_data->device_id[i];
        StreamId = theSink.a2dp_link_data->stream_id[i];
           
        if( SinkGetBdAddr(sink, &taddr) &&
            BdaddrIsSame(&theSink.a2dp_link_data->bd_addr[i], &taddr.addr) )
        {
            a2dpSetting = TRUE;
            if(A2dpMediaGetState(DeviceId, StreamId)== a2dp_stream_streaming)
                linkPolicyUseA2dpSettings(DeviceId, StreamId, A2dpMediaGetSink(DeviceId, StreamId));
            else
                linkPolicyUseHfpSettings(hfp_primary_link, sink);
        }
    }
        
    /* Otherwise, use hfp link policy */
    if(!a2dpSetting)
    {
        linkPolicyUseHfpSettings(hfp_primary_link, sink); 
    }
}
Ejemplo n.º 2
0
void A2dpOpen(A2DP *a2dp, uint16 size_local_seids, uint8 *local_seids)
{
	bdaddr addr;

#ifdef A2DP_DEBUG_LIB
	if (!a2dp)
		A2DP_DEBUG(("A2dpOpen NULL instance\n"));
#endif

	if (!local_seids || !size_local_seids)
    {
        /* If the user failed to supply connect params go no further. */
        a2dpSendOpenCfm(a2dp, a2dp->clientTask, a2dp_invalid_parameters);
		return;
    }

	if ((a2dp->signal_conn.connection_state != avdtp_connection_connected) || !SinkGetBdAddr(a2dp->signal_conn.sink, &addr))
	{
		/* There must be a signalling channel open first. */
        a2dpSendOpenCfm(a2dp, a2dp->clientTask, a2dp_no_signalling_connection);
		return;
	}

	a2dpFreeSeidListMemory(a2dp);

	a2dp->signal_conn.connect_then_open_media = FALSE;

	initiateOpen(a2dp, a2dp->clientTask, &addr, size_local_seids, local_seids);
}
Ejemplo n.º 3
0
/****************************************************************************
NAME	
    connectionHandleReadRemoteSupportedFeaturesRequest

DESCRIPTION
    Request to read the supported features of a remote device.

RETURNS
    void
*/
void connectionHandleReadRemoteSupportedFeaturesRequest(connectionReadInfoState *state, const CL_INTERNAL_DM_READ_REMOTE_SUPP_FEAT_REQ_T *req)
{
	/* Check the resource lock */
	if (!state->stateInfoLock)
	{
		bdaddr addr;

		/* Check we got a valid addr */
		if (!SinkGetBdAddr(req->sink, &addr))
		{
			/* Send an error to the app as it didn't pass in a valid sink */
			sendRemoteSupportedFeaturesCfm(req->theAppTask, hci_error_no_connection, 0, req->sink);		
		}
		else
		{
			/* Response not outstanding so issue request */
			MAKE_PRIM_C(DM_HCI_READ_REMOTE_FEATURES);
			connectionConvertBdaddr_t(&prim->bd_addr, &addr);
			VmSendDmPrim(prim);

			/* Set the lock */
			state->stateInfoLock = req->theAppTask;
			state->sink = req->sink;
		}		
	}
	else
	{
		/* Lock set so queue up the request */
		MAKE_CL_MESSAGE(CL_INTERNAL_DM_READ_REMOTE_SUPP_FEAT_REQ);
		COPY_CL_MESSAGE(req, message);
		MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_DM_READ_REMOTE_SUPP_FEAT_REQ, message, &state->stateInfoLock);
	}
}
/****************************************************************************
NAME
    handleClRoleCfm

DESCRIPTION
    Handles the role switch result.

*/
static void handleClRoleCfm(const CL_DM_ROLE_CFM_T *cfm)
{
    bdaddr addr;
    devInstanceTaskData *inst = NULL;
 
    if (SinkGetBdAddr(cfm->sink, &addr))
        inst = devInstanceFindFromBddr(&addr, FALSE);               
    
    if (inst != NULL)
    {
        handleClRole(inst, cfm->role, cfm->status, TRUE);   
    }
}
Ejemplo n.º 5
0
void AvrcpGetProfileExtensions(AVRCP *avrcp)
{
	bdaddr my_addr;

	if (SinkGetBdAddr(avrcp->sink, &my_addr))
	{
		MessageSendConditionally(&avrcp->task, AVRCP_INTERNAL_GET_EXTENSIONS, 0, &avrcp->sdp_search_mode);
	}
	else
	{
		avrcpSendGetExtensionsCfm(avrcp, avrcp_device_not_connected, 0);	
	}
}
Ejemplo n.º 6
0
void AvrcpGetSupportedFeatures(AVRCP *avrcp)
{
	bdaddr my_addr;

	if (SinkGetBdAddr(avrcp->sink, &my_addr))
	{
		MessageSendConditionally(&avrcp->task, AVRCP_INTERNAL_GET_FEATURES, 0, &avrcp->sdp_search_mode);
	}
	else
	{
		avrcpSendGetSupportedFeaturesCfm(avrcp, avrcp_device_not_connected, 0);
	}
}
Ejemplo n.º 7
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);
        }
    }
}
/****************************************************************************
NAME	
    connectionHandleWriteFlushTimeoutRequest

DESCRIPTION
    Set the flush timeout for a particular ACL.

RETURNS
    void
*/
void connectionHandleWriteFlushTimeoutRequest(const CL_INTERNAL_DM_WRITE_FLUSH_TIMEOUT_REQ_T *req)
{
	bdaddr addr;

	/* 
		Convert the sink to the address of the underlying ACL and 
		only issue this if we have an ACL  
	*/
	if (SinkGetBdAddr(req->sink, &addr))
	{
		/* Send the request to BlueStack */
		MAKE_PRIM_C(DM_HCI_WRITE_AUTO_FLUSH_TIMEOUT);
		connectionConvertBdaddr_t(&prim->bd_addr, &addr);
		prim->timeout = req->flush_timeout;
		VmSendDmPrim(prim);
	}
}
void ConnectionSmEncryptionKeyRefreshSink(Sink sink)
{
#ifdef CONNECTION_DEBUG_LIB
    if(!sink)
    {
		CL_DEBUG(("Null sink passed in\n")); 
    }
#endif
	
	{
		bdaddr addr;
		if(SinkGetBdAddr(sink, &addr))
		{
			MAKE_CL_MESSAGE(CL_INTERNAL_SM_ENCRYPTION_KEY_REFRESH_REQ);
			message->bd_addr = addr;
			MessageSend(connectionGetCmTask(), CL_INTERNAL_SM_ENCRYPTION_KEY_REFRESH_REQ, message); 
		}
	}
}
static void handleA2DPOpenInd(Sink sink, uint8 seid)
{
    bdaddr bdaddr_ind;
    
    SendEvent(EVT_A2DP_OPEN_IND,0);

	if (SinkGetBdAddr(sink, &bdaddr_ind))
	{
		uint8 lAttributes[ATTRIBUTE_SIZE];
		
		avrcpConnectReq(bdaddr_ind, FALSE);
					
		/* Retrieve attributes for this device */
    	if (ConnectionSmGetAttributeNow(PSKEY_ATTRIBUTE_BASE, &bdaddr_ind, ATTRIBUTE_SIZE, lAttributes))
		{
			bool write_params = FALSE;
			if (lAttributes[attribute_seid] != seid)
			{
				lAttributes[attribute_seid] = seid;
				write_params = TRUE;
			}
			if (lAttributes[attribute_a2dp_volume] != theHeadset.gAvVolumeLevel)
			{
				lAttributes[attribute_a2dp_volume] = theHeadset.gAvVolumeLevel;
				write_params = TRUE;
			}
			if (write_params)
			{
				/* Write params to PS */
				ConnectionSmPutAttribute(PSKEY_ATTRIBUTE_BASE, &bdaddr_ind, ATTRIBUTE_SIZE, lAttributes); 
				A2DP_MSG_DEBUG(("A2DP: Store A2DP attributes [%d][%d][%d][%d][%d][%d]\n",lAttributes[0],
			   		lAttributes[1],lAttributes[2],lAttributes[3],lAttributes[4],lAttributes[5])) ;
			}
		}
	    
		theHeadset.seid = seid;
		theHeadset.last_used_seid = seid;
		A2DP_MSG_DEBUG(("    Selected SEID = %d\n", seid));
		stateManagerEnterA2dpConnectedState();
		PROFILE_MEMORY(("A2DPOpen"))
	}
Ejemplo n.º 11
0
/****************************************************************************
NAME	
	hfpGetAgProfileVersion

DESCRIPTION
	Requests HFP profile version supported by the AG.
	
RETURNS
	void
*/
void hfpGetAgProfileVersion(HFP *hfp)
{
	bdaddr my_addr;

	if (SinkGetBdAddr(hfp->sink, &my_addr))
	{
		/* 
			Issue the search request to the connection lib. The max number of attribute bytes
			is set to an arbitrary number, however the aim is to set it to a value so that
			if the remote end returns this many bytes we still have a block big enough to
			copy the data into. 
		*/
		hfp->sdp_search_mode = hfp_sdp_search_profile_version;
		ConnectionSdpServiceSearchAttributeRequest(&hfp->task, &my_addr, 0x32, sizeof(HfpServiceRequest), (uint8 *) HfpServiceRequest, sizeof(profileDescriptorRequest), profileDescriptorRequest);
	}
	else
	{
		/* Something has gone wrong - panic */
		HFP_DEBUG(("SinkGetBdAddr failed\n"));
	}
}
Ejemplo n.º 12
0
static void handlePbapConnectCfm(PBAPC_CONNECT_CFM_T *pMsg)
{	
	PBAP_DEBUG(("PBAPC_CONNECT_CFM, Status : %d, packet size:[%d]\n", pMsg->status, pMsg->packetSize));
	
    if(pMsg->status == pbapc_success)
    {
        /* If the Pbap of primary HFP device has been connected, save its device_id as the active link */
        bdaddr ag_addr;
        Sink sink;
            
        if( HfpLinkGetSlcSink(hfp_primary_link, &sink) && SinkGetBdAddr(sink, &ag_addr) )
        {
            if(BdaddrIsSame(&ag_addr, &(pMsg->bdAddr)))
            {
                theHeadset.pbap_active_link = pMsg->device_id;
                PBAP_DEBUG(("PBAPC_CONNECT_CFM, Set the active Pbap link as [%d]\n", theHeadset.pbap_active_link));
		#ifdef BHC612
		PBAP_DEBUG(("[BT Addr: nap %04x uap %02x lap %08lx]\n",ag_addr.nap,ag_addr.uap,ag_addr.lap));
		#endif
            }
        }

        /* if we are making Pbapc dialing now */
        if(theHeadset.pbap_dial_state == pbapc_dialling)
        {
            PBAP_DEBUG(("PBAPC_CONNECT_CFM, Pbap dialling, set the phonebook\n"));
            /* Set required phonebook */
            PbapcSetPhonebook(pMsg->device_id, pbap_local, theHeadset.pbap_active_pb); 
        }
    }
    else    
    {
        /* pbapc profile connection failure */
        if(theHeadset.pbap_dial_state == pbapc_dialling)
        {
            MessageSend ( &theHeadset.task , EventPbapDialFail , 0 ) ;
            theHeadset.pbap_dial_state = pbapc_no_dial;
        }            
    }
}
Ejemplo n.º 13
0
/****************************************************************************
NAME	
    connectionHandleReadRemoteVersionRequest

DESCRIPTION
    Request to read the version information of a remote device.
  
RETURNS
    void
*/
void connectionHandleReadRemoteVersionRequest(connectionReadInfoState *state, const CL_INTERNAL_DM_READ_REMOTE_VERSION_REQ_T *req)
{
 	/* Check the resource lock */
 	if (!state->stateInfoLock)
 	{
		bdaddr addr;
		
		/* Check we got a valid addr */
		if (!SinkGetBdAddr(req->sink, &addr))
		{
			/* Create and send the message */
			MAKE_CL_MESSAGE(CL_DM_REMOTE_VERSION_CFM);
			message->status = hci_error_no_connection;	
			message->lmpVersion       = 0;
			message->manufacturerName = 0;
			message->lmpSubVersion    = 0;
         
			MessageSend(req->theAppTask, CL_DM_REMOTE_VERSION_CFM, message);	
		}
		else
		{
 			/* Response not outstanding so issue request */
 			MAKE_PRIM_C(DM_HCI_READ_REMOTE_VERSION);
 			connectionConvertBdaddr_t(&prim->bd_addr, &addr);
 			VmSendDmPrim(prim);
 
 			/* Set the lock */
 			state->stateInfoLock = req->theAppTask;
		}
 	}
 	else
 	{
 		/* Lock set so queue up the request */
		MAKE_CL_MESSAGE(CL_INTERNAL_DM_READ_REMOTE_VERSION_REQ);
		COPY_CL_MESSAGE(req, message);
		MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_DM_READ_REMOTE_VERSION_REQ, message, &state->stateInfoLock);
	}
}
Ejemplo n.º 14
0
/****************************************************************************
NAME	
    connectionHandleWriteFlushTimeoutRequest

DESCRIPTION
    Set the flush timeout for a particular ACL.

RETURNS
    void
*/
void connectionHandleWriteFlushTimeoutRequest(const CL_INTERNAL_DM_WRITE_FLUSH_TIMEOUT_REQ_T *req)
{
	typed_bdaddr taddr;

	/* 
		Convert the sink to the address of the underlying ACL and 
		only issue this if we have an ACL  
	*/
	if (SinkGetBdAddr(req->sink, &taddr))
	{
	    if (taddr.type == TYPED_BDADDR_PUBLIC)
        {
            /* Send the request to BlueStack */
            MAKE_PRIM_C(DM_HCI_WRITE_AUTO_FLUSH_TIMEOUT_REQ);
            BdaddrConvertVmToBluestack(&prim->bd_addr, &taddr.addr);
            prim->timeout = req->flush_timeout;
            VmSendDmPrim(prim);
        }
	    else
	    {
            CL_DEBUG(("SinkGetBdAddr returned non-public type\n"));
        }
    }
}
Ejemplo n.º 15
0
/*
	Dial the first entry in the specified phonebook
*/
static void pbapDial(uint8 phonebook)
{  
    /* attempt to dial the first entry in the AG missed call history */
    if(theHeadset.pbap_ready)
    {
        if(theHeadset.pbap_active_link != pbapc_invalid_link)
        {
            /* the Pbap profile of the primary HFP device has been connected */ 
            /* set the phonebook and dial */
            PBAP_DEBUG(("Pbap dial, set the phonebook first\n"));
            PbapcSetPhonebook(theHeadset.pbap_active_link, pbap_local, phonebook);
        }
        else
        {
            /* Otherwise, try to connect Pbap profile of the primary HFP device before dialling */ 
            bdaddr ag_addr;
            Sink sink;
            
            if( HfpLinkGetSlcSink(hfp_primary_link, &sink) && SinkGetBdAddr(sink, &ag_addr) )
            {
                PBAP_DEBUG(("Pbap dial, connect the Pbap profile first\n"));
                pbapConnect(ag_addr);
            }
        }        
        
        theHeadset.pbap_active_pb = phonebook;
    }
    else
    {
        PBAP_DEBUG(("PBAPC profile was not initialised\n"));
        
        MessageSend ( &theHeadset.task , EventPbapDialFail , 0 ) ;
        
        theHeadset.pbap_dial_state = pbapc_no_dial;
    }
}
Ejemplo n.º 16
0
/* Accept/reject an incoming audio connect request */
static void audioConnectResponse(AGHFP *aghfp, bool response, sync_pkt_type packet_type, const aghfp_audio_params *audio_params)
{    
    tp_bdaddr tpaddr;
    sync_config_params config_params;
    
    AGHFP_DEBUG(("audioConnectResponse\n"));
    
    /* If connection request is being rejected, don't worry about validating params being returned */
    if ( !response )
    {
        AGHFP_DEBUG(("if !response\n"));
    
        /* To send the response we need the bd addr of the underlying connection. */
        if(SinkGetBdAddr(aghfp->rfcomm_sink, &tpaddr))
        {
            AGHFP_DEBUG(("SinkGetBdAddr\n"));
    
            ConnectionSyncConnectResponse(&aghfp->task, &tpaddr.taddr.addr, FALSE, 0);
        }
        /* 
            If we can't get the addr from the sink then quietly don't respond. 
            If the underlying ACL has gone down there's not much we can do. 
        */
    }
    else
    {
        AGHFP_DEBUG(("setting audio params\n"));
        
        if((aghfp->use_wbs) && !(aghfp->hf_supported_features & aghfp_hf_codec_negotiation))
        {
            AGHFP_DEBUG(("using default CVSD Sco parameters \n"));
            config_params.tx_bandwidth = 8000;
            config_params.rx_bandwidth = 8000;
            config_params.max_latency = 16;
            config_params.voice_settings = 0;
            config_params.retx_effort = sync_retx_power_usage;
            config_params.packet_type = 0x2BF;
        }
        
        else
        {
            config_params.tx_bandwidth = audio_params->bandwidth;
            config_params.rx_bandwidth = audio_params->bandwidth;
            config_params.max_latency = audio_params->max_latency;
            config_params.voice_settings = audio_params->voice_settings;
            config_params.retx_effort = audio_params->retx_effort;
            config_params.packet_type = packet_type;
        }

        /* 
            To send the response we need the bd addr of the underlying connection. 
            If we can't get the addr from the sink then quietly don't respond. 
            If the underlying ACL has gone down there's not much we can do.
        */
        if(SinkGetBdAddr(aghfp->rfcomm_sink, &tpaddr))
        {
            AGHFP_DEBUG(("ConnectionSyncConnectResponse\n"));
            ConnectionSyncConnectResponse(&aghfp->task, &tpaddr.taddr.addr, TRUE, &config_params);
        }
    }
}