Пример #1
0
/****************************************************************************
 Outcome of the RFCOMM connect request or response.
*/
static void aghfpHandleRfcommConnectCfm(AGHFP *aghfp, rfcomm_connect_status status)
{
    /* Check the status of the rfcomm connect cfm */
    if (status == rfcomm_connect_success)
    {
        /* RFCOMM connection is up! Check which profile is supported by this task */
        if (supportedProfileIsHsp(aghfp->supported_profile))
        {
            /* HSP supported - SLC is up so tell the app */
   			aghfpSendSlcConnectCfmToApp(aghfp_connect_success, aghfp);
        }
        else if (supportedProfileIsHfp(aghfp->supported_profile))
        {
            /* HFP supported - RFCOMM is up, so just wait for HF to send us some AT commends */
        }
        else
        {
            /* This should never happen */
            AGHFP_DEBUG_PANIC(("Unhandled profile type 0x%x\n", aghfp->supported_profile));
        }

  		/* Check for data in the buffer */
  		aghfpHandleReceivedData(aghfp, StreamSourceFromSink(aghfp->rfcomm_sink));
    }
    else
    {
        /* RFCOMM connect failed - Tell the app. */
        aghfpSendSlcConnectCfmToApp(convertRfcommConnectStatus(status), aghfp);
    }
	
	aghfp->rfcomm_lock = FALSE;
}
Пример #2
0
/****************************************************************************
 Register the service record corresponding to the specified profile
*/
void aghfpRegisterServiceRecord(AGHFP *aghfp, aghfp_profile profile, uint8 chan)
{
	uint16 length;
	uint8 *service_record = 0;


	if (supportedProfileIsHsp(profile))
	{
		/* Create a copy of the service record that we can modify */
		length = sizeof(aghfp_hsp_service_record);
		service_record = (uint8 *)PanicUnlessMalloc(length);
		memcpy(service_record, aghfp_hsp_service_record, length);
	}
	else if (supportedProfileIsHfp(profile))
	{
		/* Create a copy of the service record that we can modify */
		length = sizeof(aghfp_hfp_service_record);
		service_record = (uint8 *)PanicUnlessMalloc(length);
		memcpy(service_record, aghfp_hfp_service_record, length);

		/* Insert the supported features into the service record */
		if (!insertHfpSupportedFeatures(service_record, service_record + length, aghfp->supported_profile))
		{
			/* Failed to insert the supported features into the service record */
			MAKE_AGHFP_MESSAGE(AGHFP_INTERNAL_SDP_REGISTER_CFM);
			message->status = aghfp_fail;
			MessageSend(&aghfp->task, AGHFP_INTERNAL_SDP_REGISTER_CFM, message);

			/* Free the allocated memory */
			free(service_record);
			return;
		}
	}
	else
	{
		/* Unknown profile, send an error */
		MAKE_AGHFP_MESSAGE(AGHFP_INTERNAL_SDP_REGISTER_CFM);
		message->status = aghfp_fail;
		MessageSend(&aghfp->task, AGHFP_INTERNAL_SDP_REGISTER_CFM, message);
		return;
	}

	if (!insertRfcommServerChannel(service_record, service_record + length, chan))
	{
		/* If we fail to insert the rfcomm channel return an error to the app */
		MAKE_AGHFP_MESSAGE(AGHFP_INTERNAL_SDP_REGISTER_CFM);
		message->status = aghfp_fail;
		MessageSend(&aghfp->task, AGHFP_INTERNAL_SDP_REGISTER_CFM, message);

		/* Free the allocated memory */
		free(service_record);
	}
	else
	{
		/* Send the service record to the connection lib to be registered with BlueStack */
		ConnectionRegisterServiceRecord(&aghfp->task, length, service_record);
	}
}
static bool usingHsp (AGHFP *aghfp)
{
	if ( supportedProfileIsHsp(aghfp->supported_profile) )
	{
		return TRUE;
	}

	return FALSE;
}
/****************************************************************************
NAME	
	aghfpHandleSyncDisconnectInd

DESCRIPTION
	Audio (Synchronous) connection has been disconnected 

RETURNS
	void
*/
void aghfpHandleSyncDisconnectInd(AGHFP *aghfp, const CL_DM_SYNC_DISCONNECT_IND_T *ind)
{
    /* If it's not our sink, silently ignore this indication */
    if ( ind->audio_sink == aghfp->audio_sink )
    {
        if ( aghfp->audio_connection_state==aghfp_audio_connected ||
             aghfp->audio_connection_state==aghfp_audio_disconnecting )
        { 
    	    /* Inform the app */ 
    	    if (ind->status == hci_success)
            {
		   	    resetAudioParams(aghfp);
		        aghfp->audio_connection_state = aghfp_audio_disconnected;
		        
				if ( aghfpCallManagerActiveNotComplete(aghfp) )
				{
					aghfpManageCall(aghfp, CallEventAudioDisconnected, CallFlagSuccess);
				}
				else
				{
					sendAudioDisconnectIndToApp(aghfp, aghfp_success);
				}
            }
    	    else
            {
                /* Disconnect has failed, we are still connected - inform the app */
				if ( aghfpCallManagerActiveNotComplete(aghfp) )
				{
					aghfpManageCall(aghfp, CallEventAudioDisconnected, CallFlagFail);
				}
				else
				{
					sendAudioDisconnectIndToApp(aghfp, aghfp_fail);
				}
            }
            
			/* Update the local state. Check current state in case SLC disconnect has beaten the SCO/eSCO disconnect */
			if (!aghfpCallManagerActive(aghfp) && supportedProfileIsHsp(aghfp->supported_profile) && (aghfp->state != aghfp_ready))
			{
				aghfpSetState(aghfp, aghfp_slc_connected);
			}
        }
        else
        {
            /* Should never get here */
            AGHFP_DEBUG(("aghfpHandleSyncDisconnectInd invalid state %d\n",aghfp->audio_connection_state));
        }
    }
}
Пример #5
0
/****************************************************************************
NAME	
	hfpHandleRfcommConnectCfm

DESCRIPTION
	Outcome of the RFCOMM connect request or response.

RETURNS
	void
*/
void hfpHandleRfcommConnectCfm(HFP *hfp, const CL_RFCOMM_CONNECT_CFM_T *cfm)
{
    /* Check the status of the rfcomm connect cfm */
    if (cfm->status == rfcomm_connect_success)
    {
		/* Store the sink */
		hfp->sink = cfm->sink;

        /* RFCOMM connection is up! Check which profile is supported by this task */
        if (supportedProfileIsHsp(hfp->hfpSupportedProfile))
        {
	        hfp->agSupportedProfile = hfp_headset_profile;
	        
            /* HSP supported - SLC is up so tell the app */
            hfpSendSlcConnectCfmToApp(hfp_connect_success, hfp);
        }
        else if (supportedProfileIsHfp(hfp->hfpSupportedProfile))
        {
            /* Initiate SLC establishment */
			MessageSend(&hfp->task, HFP_INTERNAL_AT_BRSF_REQ, 0);
        }
        else
        {
            /* This should never happen */
            HFP_DEBUG(("Unhandled profile type 0x%x\n", hfp->hfpSupportedProfile));
        }

		/* Check for data in the buffer */
		hfpHandleReceivedData(hfp, StreamSourceFromSink(cfm->sink));
    }
    else
    {
        /* RFCOMM connect failed - Tell the app. */
        hfpSendSlcConnectCfmToApp(convertRfcommConnectStatus(cfm->status), hfp);
    }
	
	/* Free the rfcomm lock */
	hfp->rfcomm_lock = FALSE;
}
Пример #6
0
/****************************************************************************
 Initiate a service search to get the rfcomm server channel of the
 required service on the remote device. We need this before we can
 initiate a service level connection.
*/
void aghfpGetProfileServerChannel(AGHFP *aghfp, const bdaddr *addr)
{
	uint16 sp_len;
	uint8 *sp_ptr;

	sp_len = 0;
	sp_ptr = 0;

	/* Check which profile we support so we can device which search to use */
	if (supportedProfileIsHsp(aghfp->supported_profile))
	{
		/* This task supports the HSP */
		sp_ptr = (uint8 *) HspServiceRequest;
		sp_len = sizeof(HspServiceRequest);
	}
	else if (supportedProfileIsHfp(aghfp->supported_profile))
	{
		/* This task supports the HFP */
		sp_ptr = (uint8 *)HfpServiceRequest;
		sp_len = sizeof(HfpServiceRequest);
	}
	else
	{
		/* This should never happen */
		Panic();
	}

	/*  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.
	*/
	ConnectionSdpServiceSearchAttributeRequest(
		&aghfp->task, addr, 0x32,
        sp_len, sp_ptr,
        sizeof(protocolAttributeRequest),
        protocolAttributeRequest);
}
Пример #7
0
/****************************************************************************
NAME    
    hfpRegisterServiceRecord

DESCRIPTION
    Register the service record corresponding to the specified service

RETURNS
    void
*/
void hfpRegisterServiceRecord(hfp_service_data* service)
{
    /* Ignore this silently if service is already registered */
    if(service->sdp_record_handle == 0 && !hfpGetVisibleServiceFromProfile(service->profile))
    {
        if(!theHfp->busy_channel)
        {
            const uint8* service_record      = NULL;
            uint16       size_service_record = 0;
            
            theHfp->busy_channel  = service->rfc_server_channel;
            
            /* Create a copy of the service record that we can modify */
            if (supportedProfileIsHsp(service->profile))
            {
                size_service_record = sizeof(hsp_service_record);
                
                /* If RFC channel matches use a constant record */
                if(service->rfc_server_channel == HSP_DEFAULT_CHANNEL)
                    service_record = hsp_service_record;
                else if(service->rfc_server_channel == HSP_DEFAULT_CHANNEL_2)
                    service_record = hsp_service_record_2;
                else
                    service_record = hfpSdpHspRecordCreate(service->rfc_server_channel);
            }
            else if (supportedProfileIsHfp(service->profile))
            {
                uint16 features = BRSF_BITMAP_TO_SDP_BITMAP(theHfp->hf_supported_features);
                uint16 version = supportedProfileIsHfp106(service->profile) ? HFP_1_6_VERSION_NUMBER : HFP_1_5_VERSION_NUMBER;
                
                size_service_record = sizeof(hfp_service_record);
                
                /* If features, version and RFC channel match use a constant record */
                if(features == HFP_DEFAULT_FEATURES && version == HFP_DEFAULT_VERSION)
                {
                    if(service->rfc_server_channel == HFP_DEFAULT_CHANNEL)
                        service_record = hfp_service_record;
                    else if(service->rfc_server_channel == HFP_DEFAULT_CHANNEL_2)
                        service_record = hfp_service_record_2;
                }
                
                /* Something didn't match, use a dynamic record */
                if(!service_record)
                    service_record = hfpSdpRecordCreate(service->rfc_server_channel, version, features);
            }
            else
            {
                /* If this is going to fail it will be during init, send init fail */
                hfpInitSdpRegisterComplete(hfp_fail);
                return;
            }
            
            /* Send the service record to the connection lib to be registered with BlueStack */
            ConnectionRegisterServiceRecord(&theHfp->task, size_service_record, service_record);
        }
        else
        {
            /* Queue registering this service */
            MAKE_HFP_MESSAGE(HFP_INTERNAL_SDP_REGISTER_REQ);
            message->service = service;
            MessageSendConditionally(&theHfp->task, HFP_INTERNAL_SDP_REGISTER_REQ, message, (uint16*)&theHfp->busy_channel);
        }
    }
    else if(!theHfp->initialised && service == HFP_SERVICE_TOP)
    {
        /* Make sure we complete init if we're not registering the top service */
        theHfp->busy_channel = service->rfc_server_channel;
        hfpInitSdpRegisterComplete(hfp_success);
    }
}
Пример #8
0
/****************************************************************************
NAME	
	hfpRegisterServiceRecord

DESCRIPTION
	Register the service record corresponding to the specified profile 

RETURNS
	void
*/
void hfpRegisterServiceRecord(HFP *hfp)
{
	uint8 *service_record = 0;
    hfp_profile profile = hfp->hfpSupportedProfile;
    uint8 chan = hfp->local_rfc_server_channel;

	if (!hfp->service_record)
	{
		if (supportedProfileIsHsp(profile))
        {
            hfp->size_service_record = sizeof(hsp_service_record);
			hfp->service_record = (uint8 *) hsp_service_record;
        }
		else if (supportedProfileIsHfp(profile))
        {
            hfp->size_service_record = sizeof(hfp_service_record);
			hfp->service_record = (uint8 *) hfp_service_record;
        }
		else
		{
			/* Unknown profile, send an error */
            sendInternalSdpRegisterCfmMessage(hfp, hfp_fail);
			return;
		}
	}

	/* Create a copy of the service record that we can modify */
	service_record = (uint8 *)PanicUnlessMalloc(hfp->size_service_record);
	memmove(service_record, hfp->service_record, hfp->size_service_record);
	
	if (supportedProfileIsHfp(profile))
	{
		/* Insert the supported features into the service record. */
		if (!insertHfpSupportedFeatures(service_record, service_record + hfp->size_service_record, hfp->hfpSupportedFeatures))
		{
			/* Failed to insert the supported features into the service record */
            sendInternalSdpRegisterCfmMessage(hfp, hfp_fail);

			/* Free the allocated memory */
			free(service_record);
			return;
		}

        /* Insert the profile version number */
        if (!insertHfpProfileVersion(service_record, service_record + hfp->size_service_record, profile))
        {
            /* SDP register failed */
            sendInternalSdpRegisterCfmMessage(hfp, hfp_fail);

			/* Free the allocated memory */
			free(service_record);
			return;
        }
	}
	
	if (!insertRfcommServerChannel(service_record, service_record + hfp->size_service_record, chan))
	{
		/* If we fail to insert the rfcomm channel return an error to the app */		
        sendInternalSdpRegisterCfmMessage(hfp, hfp_fail);
		
		/* Free the allocated memory */
		free(service_record);
	}
	else
	{
		/* Send the service record to the connection lib to be registered with BlueStack */
		ConnectionRegisterServiceRecord(&hfp->task, hfp->size_service_record, service_record);
	}
}