void ConnectionSmIoCapabilityResponse(const bdaddr* bd_addr, cl_sm_io_capability io_capability, bool force_mitm, bool bonding, bool oob_data_present, uint8* oob_hash_c, uint8* oob_rand_r)
{
#ifdef CONNECTION_DEBUG_LIB
    if(bd_addr == NULL)
    {
       CL_DEBUG(("Out of range Bluetooth Address 0x%p\n", (void*)bd_addr)); 
    }
#endif
    {
        MAKE_CL_MESSAGE(CL_INTERNAL_SM_IO_CAPABILITY_REQUEST_RES);
		
        message->bd_addr = *bd_addr;
        message->io_capability = io_capability;
        message->bonding = bonding;
		message->mitm = force_mitm;
		
        if(oob_data_present)
        {
            message->oob_data_present = 1;
			message->oob_hash_c = PanicUnlessMalloc(CL_SIZE_OOB_DATA);
			message->oob_rand_r = PanicUnlessMalloc(CL_SIZE_OOB_DATA);
            memcpy(message->oob_hash_c, oob_hash_c, CL_SIZE_OOB_DATA);
            memcpy(message->oob_rand_r, oob_rand_r, CL_SIZE_OOB_DATA);
        }
        else
        {
            message->oob_data_present = 0;
            message->oob_hash_c = NULL;
            message->oob_rand_r = NULL;
        }
		
        MessageSend(connectionGetCmTask(), CL_INTERNAL_SM_IO_CAPABILITY_REQUEST_RES, message);
    }
}
/****************************************************************************
 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);
	}
}
void ConnectionSdpServiceSearchRequest(Task appTask, const bdaddr *bd_addr, uint16 max_num_recs, uint16 size_srch_pttrn, const uint8 *search_pattern)
{
#ifdef CONNECTION_DEBUG_LIB	
	if (size_srch_pttrn == 0)
		CL_DEBUG(("sdp - search pattern not supplied\n"));
	if (max_num_recs == 0)
		CL_DEBUG(("sdp - max number of records set to zero\n"));
    if(bd_addr == NULL)
       CL_DEBUG(("Out of range Bluetooth Address 0x%p\n", (void*)bd_addr)); 
#endif

	{
		/* Create an internal message and send it */
		MAKE_CL_MESSAGE(CL_INTERNAL_SDP_SERVICE_SEARCH_REQ);
		message->theAppTask = appTask;
		message->bd_addr = *bd_addr;
		message->max_responses = max_num_recs;
		message->length = size_srch_pttrn;

		if (size_srch_pttrn)
		{
			message->search_pattern = (uint8 *)PanicUnlessMalloc(size_srch_pttrn);
			memcpy(message->search_pattern, search_pattern, size_srch_pttrn);
		}
		else
			message->search_pattern = 0;
	
		MessageSend(connectionGetCmTask(), CL_INTERNAL_SDP_SERVICE_SEARCH_REQ, message);
	}
}
void CsrVoicePresencesPluginPlayPhrase (uint16 id , uint16 language, Task codec_task , uint16 prompt_volume , AudioPluginFeatures features, Task app_task)
{
    if(koovox_phrase_data != NULL)
        Panic();
    
    PRINT(("PRESENT: Play Phrase:\n"));
    
    /* Allocate the memory */
    koovox_phrase_data = (koovox_phrase_data_T *) PanicUnlessMalloc(sizeof(koovox_phrase_data_T));
    memset(koovox_phrase_data,0,sizeof(koovox_phrase_data_T));
    
    /* Set up params */
    koovox_phrase_data->language      = language;
    koovox_phrase_data->codec_task    = codec_task;
    koovox_phrase_data->prompt_volume = prompt_volume;
    koovox_phrase_data->features      = features;
    koovox_phrase_data->prompt_id     = id;
    koovox_phrase_data->mixing        = FALSE; /* currently unknown so set to false */
    koovox_phrase_data->tone          = NULL;  /* not a tone */
	koovox_phrase_data->app_task	  = app_task;
    
    MessageCancelAll((TaskData*) &csr_voice_presences_plugin, MESSAGE_STREAM_DISCONNECT );
    MessageCancelAll((TaskData*) &csr_voice_presences_plugin, MESSAGE_FROM_KALIMBA);
    
    CsrVoicePresencesPluginPlayDigit(); 
    
    SetVpPlaying(TRUE);
}
void ConnectionSdpAttributeSearchRequest(Task appTask, const bdaddr *bd_addr, uint16 max_num_recs, uint32 service_hdl, uint16 size_attribute_list, const uint8 *attribute_list)
{
#ifdef CONNECTION_DEBUG_LIB	
	if (size_attribute_list == 0)
		CL_DEBUG(("sdp - attribute search pattern not supplied\n"));
	if (max_num_recs == 0)
		CL_DEBUG(("sdp - max number of attribute bytes set to zero\n"));
    if(bd_addr == NULL)
       CL_DEBUG(("Out of range Bluetooth Address 0x%p\n", (void*)bd_addr)); 
#endif

	{
		MAKE_CL_MESSAGE(CL_INTERNAL_SDP_ATTRIBUTE_SEARCH_REQ);
		message->theAppTask = appTask;
		message->bd_addr = *bd_addr;
		message->service_handle = service_hdl;
		message->size_attribute_list = size_attribute_list;
	
		if (size_attribute_list)
		{
			message->attribute_list = (uint8 *)PanicUnlessMalloc(size_attribute_list);
			memcpy(message->attribute_list, attribute_list, size_attribute_list);
		}
		else
			message->attribute_list = 0;
	
		message->max_num_attr = max_num_recs;
		MessageSend(connectionGetCmTask(), CL_INTERNAL_SDP_ATTRIBUTE_SEARCH_REQ, message);
	}
}
uint16 *GattGetDatabase(uint16 *len)
{
    uint16 *rc = PanicUnlessMalloc(sizeof(gattDatabase));
    *len = sizeof(gattDatabase);
    memmove(rc, gattDatabase, sizeof(gattDatabase));
    return rc;
}
/*************************************************************************
NAME    
    gatt_find_by_type_value_req
    
DESCRIPTION
    Send ATT_FIND_BY_TYPE_VALUE_REQ to Bluestack.

    GATT uses this only for searching for UUID in value so the value
    parameter is UUID.

RETURNS
    
*/
void gatt_find_by_type_value_req(uint16 cid,
                                 uint16 start,
                                 uint16 end,
                                 uint16 type,
                                 gatt_uuid_type_t uuid_type,
                                 const gatt_uuid_t *uuid)
{
    uint32 u[4];
    uint32 *p;
    uint16 i;
    MAKE_ATT_PRIM(ATT_FIND_BY_TYPE_VALUE_REQ);
    
    prim->cid = cid;
    prim->start = start;
    prim->end = end;
    prim->uuid = type;

    if (uuid_type == gatt_uuid16)
    {
        prim->size_value = 2U; /* UUID16 = 2 bytes ( 16 / 8 )*/
        p = &u[0]; /* point to end of UUID16 */
    }
    else if (uuid_type == gatt_uuid32)
    {
        prim->size_value = 4U; /* UUID32 = 4 bytes ( 32 / 8 )*/
        p = &u[0]; /* point to end of UUID32 */
    }
    else
    {
        prim->size_value = 16U; /* UUID128 = 16 bytes ( 128 / 8 )*/
        p = &u[3]; /* point to end of UUID128 */
    }

    /* copy uuid */
    memmove(u, uuid, GATT_UUID_SIZE);
    
    /* allocate room for filter */
    prim->value = PanicUnlessMalloc(prim->size_value);
    
    /* copy pos bytes from the end to the beginning, i.e. swapping byte
     * order from big endian to little endian */
    for (i = 0; i < prim->size_value; i++)
    {
        prim->value[i] = *p & 0xff;

        /* jump to next index every time bit 2 changes position */
        if ((i & 0x3) == 0x03)
        {
            p--; /* move to the previous index */
        }
        else
        {
            *p >>= 8; /* shift to the next part of p */
        }
    }

    prim->value = VmGetHandleFromPointer(prim->value);

    VmSendAttPrim(prim);
}
Beispiel #8
0
/* Create a dynamic SDP record for HSP */
static const uint8* hfpSdpHspRecordCreate(uint8 channel)
{
    uint8* service_record = PanicUnlessMalloc(sizeof(hsp_service_record));
    memmove(service_record, hsp_service_record, sizeof(hsp_service_record));
    
    /* Insert RFCOMM channel */
    service_record[HSP_RFCOMM_IDX] = theHfp->busy_channel;
    return (const uint8*)service_record; 
}
void avrcpConnectReq(bdaddr addr, bool delay_request)
{
	APP_AVRCP_CONNECT_REQ_T *message = (APP_AVRCP_CONNECT_REQ_T*)PanicUnlessMalloc(sizeof(APP_AVRCP_CONNECT_REQ_T));
	message->addr = addr;
	if (delay_request)
		MessageSendLater(&theHeadset.task, APP_AVRCP_CONNECT_REQ, message, 3000);
	else
    	MessageSend(&theHeadset.task, APP_AVRCP_CONNECT_REQ, message);
}
/****************************************************************************
NAME
    connectionHandleWriteEirDataRequest

DESCRIPTION
    Handles request for Writing the Extended Inquiry Data. 

RETURNS
    void
*/
void connectionHandleWriteEirDataRequest(connectionReadInfoState *infoState, const CL_INTERNAL_DM_WRITE_EIR_DATA_REQ_T *req)
{
    uint8 i;
    uint8 *p;
    uint8 octets_copied = 0;
    uint8 remainder;
    uint8 eir_data_length;

    if(infoState->version >= bluetooth2_1)
        /* Extended Inquiry Response (EIR) is supported from version 2.1 onwards) */
	{
        MAKE_PRIM_C(DM_HCI_WRITE_EXTENDED_INQUIRY_RESPONSE_DATA_REQ);
    	prim->fec_required = req->fec_required;

   		eir_data_length = (req->size_eir_data <= HCI_EIR_DATA_LENGTH)? req->size_eir_data : HCI_EIR_DATA_LENGTH;  

    	for (i=0; i<(eir_data_length / HCI_EIR_DATA_BYTES_PER_PTR); i++)
    	{
			p = PanicUnlessMalloc(HCI_EIR_DATA_BYTES_PER_PTR);
            memmove(p, req->eir_data + octets_copied, HCI_EIR_DATA_BYTES_PER_PTR);
        	octets_copied += HCI_EIR_DATA_BYTES_PER_PTR;
			prim->eir_data_part[i] = VmGetHandleFromPointer(p);
    	}

    	remainder = eir_data_length % HCI_EIR_DATA_BYTES_PER_PTR;
    	if (remainder)
    	{
        	p = PanicUnlessMalloc(HCI_EIR_DATA_BYTES_PER_PTR);
            memmove(p, req->eir_data+octets_copied, remainder);
        	memset(p + remainder, 0, HCI_EIR_DATA_BYTES_PER_PTR - remainder);
			prim->eir_data_part[i] = VmGetHandleFromPointer(p);
        	i++;
    	}
    	for (; i < HCI_EIR_DATA_PACKET_PTRS; i++)
    	{
        	prim->eir_data_part[i] = NULL;
    	}

    	VmSendDmPrim(prim);
	}

    if(req->eir_data)
        free(req->eir_data);
}
void ConnectionAuthIsPriorityDeviceTestExtra(
        Task theAppTask,
        const bdaddr* bd_addr
        )
{
    CL_AUTH_IS_PRIORITY_DEVICE_IND_TEST_EXTRA_T *new_msg = 
                    PanicUnlessMalloc(sizeof(CL_AUTH_IS_PRIORITY_DEVICE_IND_TEST_EXTRA_T));

    new_msg->result = ConnectionAuthIsPriorityDevice(bd_addr);

    MessageSend(theAppTask, CL_AUTH_IS_PRIORITY_DEVICE_IND_TEST_EXTRA, new_msg);
}
void  sinkGattHidRcResetParser(void)
{
    GATT_HID_RC_DEBUG(("GattHIDRc:Entry sinkGattHidRcResetParser\n"));

    if (parser == NULL)
    {
        parser = PanicUnlessMalloc(sizeof (map_parser_t));
    }
    
    parser->size_fragment = 0;
    parser->usage_page = USB_USAGE_PAGE_UNKNOWN;
}
void CsrSubwooferPluginConnect(Sink audio_sink, Task codec_task, Task app_task, subwooferPluginConnectParams * params)
{
    FILE_INDEX index;
    
    /* Update the current DSP status */
    SetCurrentDspStatus(DSP_LOADING);
    
    /* Give Kalimba the plugin task so it knows where to send messages */
    (void) MessageCancelAll( (TaskData*)&csr_subwoofer_plugin, MESSAGE_FROM_KALIMBA);
    MessageKalimbaTask( (TaskData*)&csr_subwoofer_plugin );
    
    /* Load the Subwofoer DSP application - Panic if it could not be loaded */
    index = PanicFalse( FileFind(FILE_ROOT, kal, sizeof(kal) - 1) );
    PanicFalse( KalimbaLoad(index) );
    
    /* update current DSP status */
    SetCurrentDspStatus(DSP_LOADED_IDLE);
    
    /* Allocate memory to store the plugin data */
    plugin_data = (subwooferPluginData*)PanicUnlessMalloc(sizeof(subwooferPluginData));
    
    /* Initialise the plugin data based on parameters supplied by the application */
    plugin_data->audio_source           = StreamSourceFromSink(audio_sink);
    plugin_data->swat_system_volume_db  = params->swat_system_volume_db;
    plugin_data->swat_trim_gain_db      = params->swat_trim_gain_db;
    plugin_data->adc_volume_index       = params->adc_volume;
    plugin_data->input                  = params->input;
    plugin_data->output                 = params->output;
    plugin_data->sample_rate            = params->sample_rate;
    plugin_data->adc_sample_rate        = params->adc_sample_rate;
    plugin_data->codec_task             = codec_task;
    plugin_data->app_task               = app_task;
    plugin_data->dsp_set_sample_rate    = 0; /* set later in response to AUDIO_PLUGIN_SET_MODE_MSG */
    
    /* Zero the codecs output gain */
    CodecSetOutputGainNow(plugin_data->codec_task, 0, left_and_right_ch);
    CodecSetInputGainNow(plugin_data->codec_task, 0, left_and_right_ch);
    
    
    /* If using the ADC, set the ADC source */
    if (plugin_data->input == SUBWOOFER_INPUT_ADC)
    {
        /* Get the ADC source */
        plugin_data->audio_source = StreamAudioSource(AUDIO_HARDWARE_CODEC, AUDIO_INSTANCE_0, AUDIO_CHANNEL_A);
    }
    
    
    /* Disconnect the source in case it's currently being disposed */
    StreamDisconnect(StreamSourceFromSink(audio_sink), 0);
    
    PRINT(("[SW_PLUGIN] : CsrSubwooferPluginConnect - complete\n"));
}
void ConnectionAuthGetPriorityDeviceStatusTestExtra(
        Task theAppTask,
        const bdaddr* bd_addr, 
        bool *is_priority_device
        )
{
    CL_AUTH_GET_PRIORITY_DEVICE_STATUS_IND_TEST_EXTRA_T *new_msg = 
                    PanicUnlessMalloc(sizeof(CL_AUTH_GET_PRIORITY_DEVICE_STATUS_IND_TEST_EXTRA_T));

    new_msg->result = ConnectionAuthGetPriorityDeviceStatus(bd_addr, &(new_msg->is_priority_device));

    MessageSend(theAppTask, CL_AUTH_GET_PRIORITY_DEVICE_STATUS_IND_TEST_EXTRA, new_msg);
}
Beispiel #15
0
/* 
 *  B-134381
 */
void ConnectionAuthSetPriorityDeviceTestExtra(
        Task theAppTask,
        const bdaddr *bd_addr,
        uint16 is_priority_device
        )
{
    CL_AUTH_SET_PRIORITY_DEVICE_IND_TEST_EXTRA_T *new_msg = 
                    PanicUnlessMalloc(sizeof(CL_AUTH_SET_PRIORITY_DEVICE_IND_TEST_EXTRA_T));

    new_msg->result = (uint16) ConnectionAuthSetPriorityDevice(bd_addr, is_priority_device);

    MessageSend(theAppTask, CL_AUTH_SET_PRIORITY_DEVICE_IND_TEST_EXTRA, new_msg);
}
/*************************************************************************
NAME    
    gatt_read_multi_req
    
DESCRIPTION
    Send ATT_READ_MULTI_REQ to Bluestack.
    
RETURNS
    
*/
void gatt_read_multi_req(uint16 cid,
                        uint16 size_handles,
                        uint16 *handles)
{
    MAKE_ATT_PRIM(ATT_READ_MULTI_REQ);
    
    prim->cid = cid;
    prim->size_handles = size_handles;
    
    prim->handles = PanicUnlessMalloc(size_handles);
    memmove(prim->handles, handles, size_handles);
    prim->handles = VmGetHandleFromPointer(prim->handles);

    VmSendAttPrim(prim);
}
/****************************************************************************
NAME
    scanWriteEirData

DESCRIPTION
    Write media dongle EIR data.
    
*/
void scanWriteEirData (CL_DM_LOCAL_NAME_COMPLETE_T *message)
{
#define SIZE_UUIDS (size_uuids ? size_uuids + 1 : 0)
    
/* Length of EIR data with all fields complete */
#define EIR_DATA_SIZE_FULL (message->size_local_name + 2 + SIZE_UUIDS + 1 + INQUIRY_TX_DATA_SIZE + 1)

/* Whether the EIR data is shortened or not. */
#define EIR_DATA_SHORTENED (EIR_DATA_SIZE_FULL > EIR_MAX_SIZE)

/* Maximum length the local name can be to fit EIR data into DH1 */
#define EIR_NAME_MAX_SIZE (EIR_MAX_SIZE - (2 + SIZE_UUIDS + 1 + INQUIRY_TX_DATA_SIZE + 1))

/* Actual length of the local name put into the EIR data */
#define EIR_NAME_SIZE (EIR_DATA_SHORTENED ? EIR_NAME_MAX_SIZE : message->size_local_name)

    uint8 size_uuids = mvdSizeUuids(the_app->supported_profiles);
    
    /* Determine length of EIR data */
    uint16 size = EIR_DATA_SHORTENED ? EIR_MAX_SIZE : EIR_DATA_SIZE_FULL;
    
    /* Just enough for the UUID16, Inquiry Tx and name fields and null termination */
    uint8 *const eir = (uint8 *)PanicUnlessMalloc(size * sizeof(uint8));
    uint8 *p = eir;    
    
    *p++ = EIR_NAME_SIZE + 1;  /* Device Name Length Field */
    *p++ = EIR_DATA_SHORTENED ? EIR_TYPE_LOCAL_NAME_SHORTENED : EIR_TYPE_LOCAL_NAME_COMPLETE;
    memcpy(p, message->local_name, EIR_NAME_SIZE);
    p += EIR_NAME_SIZE;
        
    *p++ = INQUIRY_TX_DATA_SIZE;      /* Inquiry Tx Length Field */
    *p++ = EIR_TYPE_INQUIRY_TX;
    *p++ = the_app->inquiry_tx;
       
    if (size_uuids)
    {
        *p++ = size_uuids; /* UUIDs length field */
        mvdSetUuids (p, the_app->supported_profiles);
        p += size_uuids;
    }
    
    *p++ = 0x00; /* Termination. p ends up pointing one off the end */
    
    ConnectionWriteEirData(FALSE, size, eir);
        
    /* Free the EIR data */
    free(eir);
}
Beispiel #18
0
/* Create a dynamic SDP record for HFP */
static const uint8* hfpSdpRecordCreate(uint8 channel, uint16 version, uint16 features)
{
    uint8* service_record = PanicUnlessMalloc(sizeof(hfp_service_record));
    memmove(service_record, hfp_service_record, sizeof(hfp_service_record));
    
    /* Insert RFCOMM channel */
    service_record[HFP_RFCOMM_IDX] = channel;

    /* Insert the profile version number */
    service_record[HFP_VERSION_MSB_IDX] = version >> 8;
    service_record[HFP_VERSION_LSB_IDX] = version &  0xFF;
    
    /* Insert the supported features into the service record. */
    service_record[HFP_FEATURES_MSB_IDX] = features >> 8;
    service_record[HFP_FEATURES_LSB_IDX] = features &  0xFF;
    
    return (const uint8*)service_record;
}
/*************************************************************************
NAME    
    gatt_write_req
    
DESCRIPTION
    Send ATT_WRITE_REQ to Bluestack.
    
RETURNS
    
*/
void gatt_prepare_write_req(uint16 cid,
                            uint16 handle,
                            uint16 offs,
                            uint16 size_value,
                            uint8 *value)
{
    MAKE_ATT_PRIM(ATT_PREPARE_WRITE_REQ);
    
    prim->cid = cid;
    prim->handle = handle;
    prim->offset = offs;
    prim->size_value = size_value;

    prim->value = PanicUnlessMalloc(size_value);
    memmove(prim->value, value, size_value);
    prim->value = VmGetHandleFromPointer(prim->value);

    VmSendAttPrim(prim);
}
Beispiel #20
0
/****************************************************************************
NAME
    StopHearingDSP
DESCRIPTION
    stops Hearing plugin and DSP and disconnects all relevant audio.

RETURNS
    void
*/
void StopHearingDSP(void)
{
    LMEndMessage_t * lLMEndMessage	= PanicUnlessMalloc(sizeof(LMEndMessage_t));
    lLMEndMessage->Event			= EventUsrSubwooferDisconnect;
    lLMEndMessage->PatternCompleted = TRUE;

    if (theSink.HearPhones_conf->Hearing.ActiveHearing)
    {
        AUD_DEBUG(("AUD: stop Hearing Mode\n")) ;
        SetAudioBusy(NULL);
        AudioDisconnect();
        theSink.HearPhones_conf->Hearing.ActiveHearing = 0;
        MessageSend(&theSink.task, EventSysCancelLedIndication, 0);/*EventSysCancelLedIndication*/
        MessageSend(&theSink.task, EventSysLEDEventComplete, lLMEndMessage);/*EventSysCancelLedIndication*/
#ifndef DSP_MY_FIRST_KALIMBA
        TonesPlayTone ( 50, TRUE , TRUE);
#endif
    }
}
void ConnectionChangeLocalName(uint16 size_local_name, const uint8 *local_name)
{
	/* Check params are within allowed values - debug build only */
#ifdef CONNECTION_DEBUG_LIB	
	if (size_local_name == 0 || size_local_name > MAX_NAME_LENGTH)
		CL_DEBUG(("Zero length name passed in\n"));

	if (!local_name)
		CL_DEBUG(("Zero length name passed in\n"));
#endif

    {
		/* All requests are sent through the internal state handler */
		MAKE_CL_MESSAGE(CL_INTERNAL_DM_CHANGE_LOCAL_NAME_REQ);

		/* Check local name length is valid and less than MAX_NAME_LENGTH chars */
		if (size_local_name && size_local_name <= MAX_NAME_LENGTH)
		{
			uint16 name_length = 0;

			/* Make sure the name is null terminated */
			if (local_name[size_local_name-1] != '\0')
				name_length = size_local_name + 1;
			else
				name_length = size_local_name;

			message->length_name = name_length;
			message->name = (uint8 *)PanicUnlessMalloc(name_length);
			memcpy(message->name, local_name, size_local_name);
			message->name[name_length-1] = '\0';
		}
		else
		{
			message->length_name = 0;
			message->name = 0;
		}
		
		MessageSend(connectionGetCmTask(), CL_INTERNAL_DM_CHANGE_LOCAL_NAME_REQ, message);
	}
}
/****************************************************************************
NAME	
	HfpDialMemoryLocation

DESCRIPTION
	This function issues a request to the AG to dial from the the supplied 
	memory_location (the HFP specification defines the command but it is 
	AG implementation dependent how this is implemented). The request is 
	issued on the SLC associated with the hfp profile instance passed in by 
	the application. 
	
	The length argument specifies the length in bytes of the memory_location 
	to be sent. 
	
	The memory_location is the location the AG must dial from. The message 
	returned indicates whether the command was recognised by the AG or not.
	
MESSAGE RETURNED
	HFP_DIAL_MEMORY_CFM

RETURNS
	void
*/
void HfpDialMemoryLocation(HFP *hfp, uint16 length, const uint8 *memory_location)
{
#ifdef HFP_DEBUG_LIB
	if (!hfp)
		HFP_DEBUG(("Null hfp task ptr passed in.\n"));

	if (!length)
		HFP_DEBUG(("Zero length passed in.\n"));

	if (!memory_location)
		HFP_DEBUG(("Null memory location ptr passed in.\n"));
#endif

	/* Send an internal message */
	{
		MAKE_HFP_MESSAGE(HFP_INTERNAL_AT_ATD_MEMORY_REQ);
		message->length = length;
		message->memory = (uint8 *) PanicUnlessMalloc(length);
		memmove(message->memory, memory_location, length);
		MessageSend(&hfp->task, HFP_INTERNAL_AT_ATD_MEMORY_REQ, message);
	}
}
/*****************************************************************************
NAME    
     headsetHandleUserConfirmationInd
    
DESCRIPTION
     This function is called on receipt on an CL_SM_USER_CONFIRMATION_REQ_IND

RETURNS
     void
*/
void headsetHandleUserConfirmationInd(const CL_SM_USER_CONFIRMATION_REQ_IND_T* ind)
{
    if (AuthCanHeadsetPair())
    {
#if 1  
        theHeadset.confirmation = TRUE;
        AUTH_DEBUG(("auth: can confirm %ld\n", ind->numeric_value));
        /* should use text to speech here */
        theHeadset.confirmation_addr = (bdaddr*)PanicUnlessMalloc(sizeof(bdaddr));
        *theHeadset.confirmation_addr = ind->bd_addr;
#else
        ConnectionSmUserConfirmationResponse(&ind->bd_addr, TRUE);
        /* infor ssp numeric_value */
        UartPrintf("\r\n+SSP=%ld\r\n",ind->numeric_value);
#endif        
    }
    else
    {
        /* reject the confirmation request */
        AUTH_DEBUG(("auth: rejecting confirmation req\n"));
        ConnectionSmUserConfirmationResponse(&ind->bd_addr, FALSE);
    }
}
/*************************************************************************
NAME    
    handleInternalWriteReqPrepare
    
DESCRIPTION
    This function is handler for GATT_INTERNAL_WRITE_REQ internal message
    during Reliable Write prepare.
    
RETURNS
    
*/
static void handleInternalWriteReqPrepare(cid_map_t *conn,
                                          GATT_INTERNAL_WRITE_REQ_T *m)
{
    STASH(conn, stash, RELIABLE_WRITE_PREPARE);
    gatt_write_reliable_t *data = &conn->data.req.write_reliable;
    
    gattSetConnState(conn, m->common.task, m->id);

    data->handle = m->handle;
    data->offs = m->offs;
    data->size_value = m->size_value;
    data->value = PanicUnlessMalloc(m->size_value);
    memmove(data->value, m->value, m->size_value);
    
    gatt_prepare_write_req(m->common.cid, m->handle, m->offs,
                           m->size_value, m->value);

    /* Create the response message */
    MAKE_STASH(conn, stash, WRITE_LONG_CHARACTERISTIC_VALUE);

    stash->cid = m->common.cid;
    stash->handle = m->handle;
    stash->status = gatt_status_success;
}
/****************************************************************************
NAME
    clMsgHandleLibMessage

DESCRIPTION
    Handles the CL library messages and calls the relevant function.

*/
void clMsgHandleLibMessage(MessageId id, Message message)
{
    switch(id)
    {
        case CL_INIT_CFM:
        {
            DEBUG_CL(("CL_INIT_CFM status = %u\n", ((CL_INIT_CFM_T *)message)->status));
            handleClInitCfm((CL_INIT_CFM_T *)message);    
            break;
        }    
        case CL_DM_WRITE_INQUIRY_MODE_CFM:
        {
            DEBUG_CL(("CL_DM_WRITE_INQUIRY_MODE_CFM\n"));
            /* Read the local name to put in our EIR data */
            ConnectionReadInquiryTx(&the_app->task);
            break;
        }    
        case CL_DM_READ_INQUIRY_TX_CFM:
        {
            the_app->inquiry_tx = ((CL_DM_READ_INQUIRY_TX_CFM_T*)message)->tx_power;
            ConnectionReadLocalName(&the_app->task);
            break;
        }    
        case CL_DM_LOCAL_NAME_COMPLETE:
        {
            DEBUG_CL(("CL_DM_LOCAL_NAME_COMPLETE\n"));
            /* Write EIR data and initialise the codec task */
            scanWriteEirData((CL_DM_LOCAL_NAME_COMPLETE_T*)message);
            break;
        }    
        case CL_DM_ACL_OPENED_IND:
        {
            DEBUG_CL(("CL_DM_ACL_OPENED_IND from: 0x%X 0x%X 0x%lX\n", ((CL_DM_ACL_OPENED_IND_T *)message)->bd_addr.nap, ((CL_DM_ACL_OPENED_IND_T *)message)->bd_addr.uap, ((CL_DM_ACL_OPENED_IND_T *)message)->bd_addr.lap));
            /* Ignore this message for now */
            DEBUG_CL((" - ignored\n"));
            break;
        }    
        case CL_DM_ACL_CLOSED_IND:
        {
            DEBUG_CL(("CL_DM_ACL_CLOSED_IND from: 0x%X 0x%X 0x%lX\n", ((CL_DM_ACL_CLOSED_IND_T *)message)->bd_addr.nap, ((CL_DM_ACL_CLOSED_IND_T *)message)->bd_addr.uap, ((CL_DM_ACL_CLOSED_IND_T *)message)->bd_addr.lap));
            /* Ignore this message for now */
            DEBUG_CL((" - ignored\n"));
            break;
        }
        case CL_SM_PIN_CODE_IND:
        {
            DEBUG_CL(("CL_SM_PIN_CODE_IND from: 0x%X 0x%X 0x%lX\n", (uint16)((CL_SM_PIN_CODE_IND_T *)message)->bd_addr.nap, (uint16)((CL_SM_PIN_CODE_IND_T *)message)->bd_addr.uap, (uint32)((CL_SM_PIN_CODE_IND_T *)message)->bd_addr.lap));
            handleClSmPinCodeInd((CL_SM_PIN_CODE_IND_T *)message);
            break;
        }
        case CL_SM_IO_CAPABILITY_REQ_IND:
        {
            DEBUG_CL(("CL_SM_IO_CAPABILITY_REQUEST_IND\n"));
            {
                CL_SM_IO_CAPABILITY_REQ_IND_T *prim = (CL_SM_IO_CAPABILITY_REQ_IND_T *)message;
                ConnectionSmIoCapabilityResponse(&prim->bd_addr, cl_sm_io_cap_no_input_no_output, FALSE, TRUE, FALSE, NULL, NULL);
            }
            break;
        }
        case CL_SM_USER_CONFIRMATION_REQ_IND:
        {
            DEBUG_CL(("CL_SM_USER_CONFIRMATION_REQ_IND\n"));
            /* Shouldn't get this so if we do reject it! */
            ConnectionSmUserConfirmationResponse(&((CL_SM_USER_CONFIRMATION_REQ_IND_T*)message)->bd_addr, FALSE);
            break;
        }
        case CL_SM_AUTHORISE_IND:
        {
            DEBUG_CL(("CL_SM_AUTHORISE_IND\n"));
            {    /* For now, blindly accept this request */
                CL_SM_AUTHORISE_IND_T *prim = (CL_SM_AUTHORISE_IND_T *)message;
                ConnectionSmAuthoriseResponse(&prim->bd_addr, prim->protocol_id, prim->channel, prim->incoming, TRUE);
            }    
            break;
        }
        case CL_SM_AUTHENTICATE_CFM:
        {
            DEBUG_CL(("CL_SM_AUTHENTICATE_CFM status = %u\n", ((CL_SM_AUTHENTICATE_CFM_T *)message)->status));
            if ( ((CL_SM_AUTHENTICATE_CFM_T *)message)->status == auth_status_success )
            {    /* Pin code will be stored on a successful SLC/A2DP connection */
            }
            break;
        }
        case CL_SM_SECURITY_LEVEL_CFM:
        {
            DEBUG_CL(("CL_SM_SECURITY_LEVEL_CFM success = %u\n", ((CL_SM_SECURITY_LEVEL_CFM_T *)message)->success));
            break;
        }
        case CL_DM_INQUIRE_RESULT:
        {
            DEBUG_CL(("CL_DM_INQUIRE_RESULT status = %u\n", ((CL_DM_INQUIRE_RESULT_T *)message)->status));
            handleClDmInquireResult((CL_DM_INQUIRE_RESULT_T *)message);        
            break;
        }
        case CL_SDP_OPEN_SEARCH_CFM:
        {   
            DEBUG_CL(("CL_SDP_OPEN_SEARCH_CFM status = %u\n", ((CL_SDP_OPEN_SEARCH_CFM_T *)message)->status)); 
            handleClSdpOpenSearchCfm((CL_SDP_OPEN_SEARCH_CFM_T *)message);       
            break;
        }    
        case CL_SDP_CLOSE_SEARCH_CFM:
        {
            DEBUG_CL(("CL_SDP_CLOSE_SEARCH_CFM status = %u\n", ((CL_SDP_CLOSE_SEARCH_CFM_T *)message)->status));
            handleClSdpCloseSearchCfm();      
            break;
        }    
        case CL_SDP_SERVICE_SEARCH_CFM:
        {
            DEBUG_CL(("CL_SDP_SERVICE_SEARCH_CFM status = %u\n", ((CL_SDP_SERVICE_SEARCH_CFM_T *)message)->status));
            handleClSdpServiceSearchCfm((CL_SDP_SERVICE_SEARCH_CFM_T *)message);          
            break;
        }    
        case CL_SM_SEC_MODE_CONFIG_CFM:
        {
            DEBUG_CL(("CL_SM_SEC_MODE_CONFIG_CFM\n"));
            DEBUG_CL((" - ignored\n"));
            break;
        }    
        case CL_SM_REMOTE_IO_CAPABILITY_IND:
        {
            DEBUG_CL(("CL_SM_REMOTE_IO_CAPABILITY_IND\n"));
            DEBUG_CL((" - ignored\n"));
            break;
        }
        case CL_DM_LINK_SUPERVISION_TIMEOUT_IND:
        {
            DEBUG_CL(("CL_DM_LINK_SUPERVISION_TIMEOUT_IND:\n"));
            DEBUG_CL(("    timeout:[0x%x] bdaddr:[0x%x%x%lx]\n", 
                        ((CL_DM_LINK_SUPERVISION_TIMEOUT_IND_T *)message)->timeout,
                        ((CL_DM_LINK_SUPERVISION_TIMEOUT_IND_T *)message)->bd_addr.nap,
                        ((CL_DM_LINK_SUPERVISION_TIMEOUT_IND_T *)message)->bd_addr.uap,
                        ((CL_DM_LINK_SUPERVISION_TIMEOUT_IND_T *)message)->bd_addr.lap));
            break;
        }
        case CL_DM_ROLE_IND:
        {
            DEBUG_CL(("CL_DM_ROLE_IND\n"));
            handleClRoleInd((CL_DM_ROLE_IND_T *)message);
            break;
        }
        case CL_DM_ROLE_CFM:
        {
            DEBUG_CL(("CL_DM_ROLE_CFM\n"));
            handleClRoleCfm((CL_DM_ROLE_CFM_T *)message);
            break;
        }
        case CL_DM_SNIFF_SUB_RATING_IND:
        {
            DEBUG_CL(("CL_DM_SNIFF_SUB_RATING_IND\n"));
            break;
        }
        case CL_DM_REMOTE_FEATURES_CFM:
        {
            DEBUG_CL(("CL_DM_REMOTE_FEATURES_CFM\n"));
            handleClDmRemoteFeaturesConfirm((CL_DM_REMOTE_FEATURES_CFM_T *)message);
            return;
        }

		case CL_DM_REMOTE_NAME_COMPLETE:
		{
			CL_DM_REMOTE_NAME_COMPLETE_T *name = (CL_DM_REMOTE_NAME_COMPLETE_T*)message;
			DEBUG_CL(("CL_DM_REMOTE_NAME_COMPLETE\n"));

			if(name->status == hci_success)
			{
				char *name_str = PanicUnlessMalloc(name->size_remote_name+1);
				memcpy(name_str,name->remote_name,name->size_remote_name);
				name_str[name->size_remote_name] = 0;
				UartPrintf("\r\n+RNM=%s\r\n",name_str);
				free(name_str);
			}
			else
				UartPrintf("\r\nERROR\r\n");
			
			break;
		}
		case CL_DM_RSSI_CFM:
		{
            DEBUG_CL(("CL_DM_RSSI_CFM_T %d (%d)\n",((CL_DM_RSSI_CFM_T*)message)->status,((CL_DM_RSSI_CFM_T*)message)->rssi));
			UartPrintf("\r\n+RSSI=%d\r\n",((CL_DM_RSSI_CFM_T*)message)->rssi);
            break;
		}
        default:
        {
            DEBUG_CL(("Unhandled CL message 0x%X\n", (uint16)id));    
            break;
        }
    }
}
Beispiel #26
0
/***************************************************************************
NAME
    UpgradeSendUpgradeStatusInd

DESCRIPTION
    Build and send an UPGRADE_STATUS_IND message to the VM application.
*/
static void UpgradeSendUpgradeStatusInd(Task task, upgrade_state_t state)
{
    UPGRADE_STATUS_IND_T *upgradeStatusInd = (UPGRADE_STATUS_IND_T *)PanicUnlessMalloc(sizeof(UPGRADE_STATUS_IND_T));
    upgradeStatusInd->state = state;
    MessageSend(task, UPGRADE_STATUS_IND, upgradeStatusInd);
}
Beispiel #27
0
static bool folderFillBuffer()
{
	bool lComplete = FALSE, lSent = TRUE, lEntry = TRUE;
	pbaSearchResult *lSrchRes;
	
	
	DEBUG(("folderFillBuffer\n"));
	
	lSrchRes = PanicUnlessMalloc(sizeof(pbaSearchResult));
	
	if (!the_app->folderData.sentCurrent)
	{
		DEBUG(("    Sending Current\n"));
		/* Get current entry */
		pbaGetCurrentEntry(lSrchRes);
		/* Add to buffer */
		lSent = folderAddToBuffer(lSrchRes->index,  lSrchRes->namePtr, lSrchRes->nameSize);
		if (!lSent)
		{
			DEBUG(("    Unable to add single entry\n"));
			Panic();
		}
		else
		{
			the_app->srchData.count++;
			the_app->srchData.maxList--;
			if (the_app->srchData.maxList == 0)
			{
				lEntry = FALSE;
			}
		}
	}
	
	if (the_app->folderData.sendFooter)
	{
		DEBUG(("    SENDING FOOTER\n"));
		memcpy(the_app->buffer.buffer, gVCardListFooter, sizeof(gVCardListFooter));
		the_app->buffer.freeSpace -= sizeof(gVCardListFooter);
		the_app->buffer.nextPos += sizeof(gVCardListFooter);
		the_app->buffer.used += sizeof(gVCardListFooter);
		lComplete = TRUE;
		the_app->folderData.sendFooter = FALSE;
	}
	else
	{	
		lSent = TRUE;
		/* Get next entry */
		if (lEntry)
		{
			lEntry = pbaFindNextEntry(lSrchRes);
		}
		while (lEntry && lSent)
		{
			lSent = folderAddToBuffer(lSrchRes->index,  lSrchRes->namePtr, lSrchRes->nameSize);
			if (lSent)
			{
				the_app->srchData.count++;
				the_app->srchData.maxList--;
				if (the_app->srchData.maxList == 0)
				{
					lEntry = FALSE;
				}
				else
				{
					/* Get next Entry */
					lEntry = pbaFindNextEntry(lSrchRes);
				}
			}
		}
		if (!lEntry)
		{ /* No more entries to read */
			DEBUG(("    Closing phonebook\n"));
			/* Close phonebook */
			pbaClosePhonebook();
			
			if (sizeof(gVCardListFooter) <= the_app->buffer.freeSpace)
			{ /* Add footer to buffer */
				memcpy(&the_app->buffer.buffer[the_app->buffer.nextPos], gVCardListFooter, sizeof(gVCardListFooter));
				the_app->buffer.freeSpace -= sizeof(gVCardListFooter);
				the_app->buffer.nextPos += sizeof(gVCardListFooter);
				the_app->buffer.used += sizeof(gVCardListFooter);
				lComplete = TRUE;
				the_app->folderData.sendFooter = FALSE;
			}
			else
			{ /* remember finished and not sent footer */
				the_app->folderData.sendFooter = TRUE;
			}
		}
	}
	
	free(lSrchRes);
	
	return lComplete;
}
/****************************************************************************
*NAME    
*    avrcpAvctpReceiveMessage    
*
*DESCRIPTION
*    This function is called to process the AVCTP message received. 
*    
*PARAMETERS
*   avrcp                  - Task
*   * ptr                  - Received Data
*   packet_size            - packet_size
*
*RETURN
*  bool - Return TRUE if the message is ready to process, otherwise return 
*         FALSE
*******************************************************************************/
bool avrcpAvctpReceiveMessage(  AVRCP          *avrcp,
                                const uint8*    ptr,
                                uint16          packet_size)
{
    bool    result = FALSE;
    uint16  packet_type = ptr[AVCTP_HEADER_START_OFFSET] & 
                          AVCTP0_PACKET_TYPE_MASK;
    uint16  pid_offset = AVCTP_SINGLE_PKT_PID_OFFSET; 
    uint8*  temp;
    uint8   cr_type= ptr[0] & AVCTP0_CR_MASK; 


    switch(packet_type)
    {
    case AVCTP0_PACKET_TYPE_START:
        if(packet_size < AVRCP_START_PKT_HEADER_SIZE)
        {
           break; 
        }

        /* Check remote device is planning to send a Message greater than 
           AV Size */     
        if((((ptr[AVCTP_NUM_PKT_OFFSET]-1) * avrcp->l2cap_mtu) > 
             AVRCP_AVC_MAX_PKT_SIZE) || (ptr[AVCTP_NUM_PKT_OFFSET] <= 1))
        {
            if(cr_type == AVCTP0_CR_COMMAND)
            {
                avrcp->av_msg = (uint8*)ptr;
                avrcpSendAvcResponse(avrcp, AVRCP_START_PKT_HEADER_SIZE, 
                                    avctp_response_rejected, 0, NULL);
            }
            break;   
        }

        pid_offset =  AVCTP_START_PKT_PID_OFFSET;
        
    case AVCTP0_PACKET_TYPE_SINGLE: /* Fall through */
        if(packet_size < AVRCP_TOTAL_HEADER_SIZE)
        {
            break;
        }

        /* Check if we have received any fragmented pkts before */
        if(avrcp->av_msg_len)
        {
            /* Silently drop it */
            free(avrcp->av_msg);
            avrcp->av_msg_len = 0;
        }

        /* Check the PID Values */
        if (ptr[pid_offset] != AVCTP1_PROFILE_AVRCP_HIGH)
        {
            avrcp->av_msg = (uint8*)ptr;
            avrcpSendAvcResponse(avrcp,0,avctp_response_bad_profile, 0, NULL);
            break;
        }

        if(ptr[pid_offset+1] != AVCTP2_PROFILE_AVRCP_REMOTECONTROL)
        {
            if(((avrcp->device_type == avrcp_target) && 
                (ptr[pid_offset+1] != AVCTP2_PROFILE_AVRCP_CONTROLTARGET)) ||
                ((avrcp->device_type == avrcp_controller) && 
                (ptr[pid_offset+1] != AVCTP2_PROFILE_AVRCP_REMOTECONTROLLER)))
            {
                avrcp->av_msg = (uint8*)ptr;
                avrcpSendAvcResponse(avrcp,0,avctp_response_bad_profile,0,NULL);
                break;
            }
        }

        if(packet_type == AVCTP0_PACKET_TYPE_SINGLE)
        {
            avrcp->av_msg = (uint8*)ptr;
            avrcp->av_msg_len = packet_size;
            result = TRUE;
        }
        else
        {
            /* 
             * Allocate memory and copy the fragmented packet for reassembling 
             * This allocated memory is freed in avrcpSourceProcessed() after 
             * processing the packet. Memory is freed after sending the response
             * for command packets and for response packets it is freed after
             * processing the response. This memory may be send to application
             * if it contains any data interested to the app. In this case, app
             * shall call AvrcpSourceProcessed() to free it. 
             */
            avrcp->av_msg= (uint8*)PanicUnlessMalloc(packet_size);
            avrcp->av_msg_len=packet_size;
            memmove(avrcp->av_msg, ptr, packet_size);
            avrcp->av_msg[AVCTP_NUM_PKT_OFFSET]--;
        }

        break;

    case AVCTP0_PACKET_TYPE_CONTINUE:
    case AVCTP0_PACKET_TYPE_END:  
        if((avrcp->av_msg_len == 0)||(packet_size < AVCTP_CONT_PKT_HEADER_SIZE)
                       || (avrcp->av_msg[AVCTP_NUM_PKT_OFFSET] == 0) )
        {
            /* Bad Packet. Just ignore */
            break;
        }

      /* Check the transaction ID */
       if((ptr[AVCTP_HEADER_START_OFFSET] & AVCTP_TRANSACTION_MASK) !=
           (avrcp->av_msg[AVCTP_HEADER_START_OFFSET] & AVCTP_TRANSACTION_MASK)) 
            
       {
            /* Send the Response and Drop the packet */
            avrcpSendAvcResponse(avrcp, AVRCP_START_PKT_HEADER_SIZE, 
                                    avctp_response_rejected, 0, NULL);
            break;
       }


        /* Reassemble the Continuation Packet */
        temp = (uint8*)realloc(avrcp->av_msg, avrcp->av_msg_len+packet_size-1);
        if(!temp)
        {
            /* We failed to allocate memory . Stop receiving  further packets 
               and give this to app for processing */
            avrcp->av_msg[AVCTP_NUM_PKT_OFFSET] = 0;

            /* Panic in Debug Mode */
            AVRCP_DEBUG(("Failed to realloc memory for the received fragment"));
        }
        else
        {
            /* Ignore the 1 byte Header */  
            packet_size--;
            memmove(temp+avrcp->av_msg_len, &ptr[1],packet_size);

            avrcp->av_msg=temp;
            avrcp->av_msg_len+= packet_size;

            /* Reduce the number of packets */
            avrcp->av_msg[AVCTP_NUM_PKT_OFFSET]--;

        }
        
        
       if((packet_type == AVCTP0_PACKET_TYPE_END) || 
          (avrcp->av_msg[AVCTP_NUM_PKT_OFFSET] == 0))
       {
            /* Last packet Received */
            result = TRUE;
       }

       break;
    }

    return result;
}
/****************************************************************************
NAME	
	connectionHandleSdpServiceSearchCfm

DESCRIPTION
	SDP service search results received so handle them here.

RETURNS
	void	
*/
void connectionHandleSdpServiceSearchCfm(connectionSdpState *state, const SDC_EX_SERVICE_SEARCH_CFM_T *cfm)
{
	if (state->sdpSearchLock == connectionGetCmTask())
	{
		/* Internal CFM means we're SDP Pinging */
		uint8* sdp_ptr = (uint8 *) SdpPingServiceRequest;
		
		/* Create next request */
		MAKE_CL_MESSAGE(CL_INTERNAL_SDP_SERVICE_SEARCH_REQ);
	
		message->theAppTask = connectionGetCmTask();
		message->bd_addr = state->sdpServerAddr;
		message->max_responses = 1;
		message->length = sizeof(SdpPingServiceRequest);				 
		message->search_pattern = (uint8*) PanicUnlessMalloc(sizeof(SdpPingServiceRequest));
		memcpy(message->search_pattern, sdp_ptr, sizeof(SdpPingServiceRequest));
		
		/* Send after 2 seconds to avoid thrashing the radio */
		MessageSendLater(connectionGetCmTask(), CL_INTERNAL_SDP_SERVICE_SEARCH_REQ, message, D_SEC(2));
		
		/* Tidy up memory in cfm */
		if (cfm->size_rec_list)
        {
            uint8 *record_list = VmGetPointerFromHandle(cfm->rec_list);
            free(record_list);
        }
        
		/* Free the lock so the next request can be handled */
		state->sdpSearchLock = 0;
	}
    else if (state->sdpSearchLock)
    {
        /* Send a cfm to the client task */
        MAKE_CL_MESSAGE_WITH_LEN(CL_SDP_SERVICE_SEARCH_CFM, cfm->size_rec_list);
        message->status = connectionConvertSdpSearchStatus(cfm->response);
        message->num_records = cfm->num_recs_ret;
        message->error_code = cfm->err_code;
        connectionConvertBdaddr(&message->bd_addr, &cfm->bd_addr);
        message->size_records = cfm->size_rec_list;
        
        if (cfm->size_rec_list)
        {
            uint8 *record_list = VmGetPointerFromHandle(cfm->rec_list);
            memcpy(message->records, record_list, cfm->size_rec_list);
            free(record_list);
        }
        else
            message->records[0] = 0;
        
        MessageSend(state->sdpSearchLock, CL_SDP_SERVICE_SEARCH_CFM, message);
        
        /* Reset the resource lock */
        state->sdpSearchLock = 0;
    }
    else
    {
        if (cfm->size_rec_list)
        {
            uint8 *record_list = VmGetPointerFromHandle(cfm->rec_list);
            free(record_list);
        }
    }
}
/****************************************************************************
DESCRIPTION
	This function connects a synchronous audio stream to the pcm subsystem
*/ 
void CsrSbcEncoderPluginConnect( Sink audio_sink , Task codec_task , uint16 volume , uint32 rate , bool stereo , AUDIO_MODE_T mode , const void * params ) 
{
	/* DSP Application loading and Transform starting is handled by a call to A2dpAudioCodecEnable
		in the application, so should not be done here. */

	typedef struct
	{
		unsigned source_type:4;
		unsigned reserved:4;
		uint8 content_protection;
		uint32 voice_rate;
		unsigned bitpool:8;
		unsigned format:8;
		uint16 packet_size;
		Sink media_sink_b;
	} sbc_codec_data_type;

	sbc_codec_data_type *sbc_codecData = (sbc_codec_data_type *) params;

	if (!sbc_codecData)
		Panic();

    SBC = (SBC_t*)PanicUnlessMalloc (sizeof (SBC_t) ) ;
    
    SBC->media_sink[0] = audio_sink ;
    SBC->codec_task = codec_task ;
	SBC->media_sink[1] = sbc_codecData->media_sink_b;
	SBC->packet_size = sbc_codecData->packet_size;
    
    StreamDisconnect(StreamKalimbaSource(2), 0);

	/* Initialise the RTP SBC encoder */
	SBC->t[0] = TransformRtpSbcEncode(StreamKalimbaSource(2), audio_sink);

	/* Configure the RTP transform to generate the selected packet size */
	TransformConfigure(SBC->t[0], VM_TRANSFORM_RTP_SBC_ENCODE_PACKET_SIZE, sbc_codecData->packet_size);

	/* Transform should not manage timings. */
	TransformConfigure(SBC->t[0], VM_TRANSFORM_RTP_SBC_ENCODE_MANAGE_TIMING, FALSE);

	/* Start the transform */
	(void) TransformStart(SBC->t[0]);
    
    PRINT(("Audio Plugin: TransformStart sink:0x%x\n",(uint16)audio_sink));
	
	if (SBC->media_sink[1])
	{
		/* There is a 2nd audio stream so initialise this transform */
        StreamDisconnect(StreamKalimbaSource(3), 0);
		
		/* Initialise the RTP SBC encoder */
		SBC->t[1] = TransformRtpSbcEncode(StreamKalimbaSource(3), SBC->media_sink[1]);

		/* Configure the RTP transform to generate the selected packet size */
		TransformConfigure(SBC->t[1], VM_TRANSFORM_RTP_SBC_ENCODE_PACKET_SIZE, sbc_codecData->packet_size);

		/* Transform should not manage timings. */
		TransformConfigure(SBC->t[1], VM_TRANSFORM_RTP_SBC_ENCODE_MANAGE_TIMING, FALSE);

		/* Start the transform */
		(void) TransformStart(SBC->t[1]);
        
        PRINT(("Audio Plugin: TransformStart sink:0x%x\n",(uint16)SBC->media_sink[1]));
	}

	/* Configure SBC encoding format */
	if (!KalimbaSendMessage(KALIMBA_MSG_SBCENC_SET_PARAMS, sbc_codecData->format, 0, 0, 0))
		/* If message fails to get through, abort */
		Panic();

	/* Pass bit pool value to DSP */
	if (!KalimbaSendMessage(KALIMBA_MSG_SBCENC_SET_BITPOOL, sbc_codecData->bitpool, 0, 0, 0))
		/* If message fails to get through, abort */
		Panic();

	/* disard any data sent by the SNK */
    StreamConnectDispose(StreamSourceFromSink(audio_sink));
	
	if (SBC->media_sink[1])
	{
		/* disard any data sent by the 2nd SNK */
	    StreamConnectDispose(StreamSourceFromSink(SBC->media_sink[1]));
	}
	
	/* select the source type */
	if(sbc_codecData->source_type == SourceUsb)
	{
		PRINT(("Audio Plugin: SourceUsb\n"));
		/* Select the source type */
		PanicFalse(KalimbaSendMessage(KALIMBA_ENCODER_SELECT, 0x0001, 0, 0, 0));
	}
	else
	{
		PRINT(("Audio Plugin: SourceAnalog\n"));
		/* For analogue input source */
		StreamDisconnect(StreamPcmSource(0), StreamPcmSink(0));
		StreamDisconnect(StreamPcmSource(1), StreamPcmSink(1));
        
		(void)PcmClearAllRouting();

		if (CodecGetCodecType(codec_task) == codec_wm8731)
		{
			PRINT(("Audio Plugin: codec_wm8731\n"));
			/* configure slot 0 and 1 to be left and right channel
			and synchronise the offsets for stereo playback */
			(void)PcmRateAndRoute(0, PCM_NO_SYNC, (uint32) rate, (uint32) rate, VM_PCM_EXTERNAL_I2S);
			(void)PcmRateAndRoute(1, 0, (uint32) rate, (uint32) rate, VM_PCM_EXTERNAL_I2S);
		}
		else
		{
			PRINT(("Audio Plugin: codec_internal\n"));
			/* configure slot 0 and 1 to be left and right channel
			and synchronise the offsets for stereo playback */
			(void)PcmRateAndRoute(0, PCM_NO_SYNC, (uint32) rate, (uint32) rate, VM_PCM_INTERNAL_A);
			(void)PcmRateAndRoute(1, 0, (uint32) rate, (uint32) rate, VM_PCM_INTERNAL_B);
		}
		        
		/* plug Left ADC into port 0 */
		(void)StreamConnect(StreamPcmSource(0),StreamKalimbaSink(0)); 

		/* plug Right ADC into port 1 */
		(void)StreamConnect(StreamPcmSource(1),StreamKalimbaSink(1)); 
		
		/* Select the source type */
		PanicFalse(KalimbaSendMessage(KALIMBA_ENCODER_SELECT, 0x0002, 0, 0, 0)); 
		
		if(!KalimbaSendMessage(KALIMBA_MSG_GO,0,0,0,0))
		{
			PRINT(("SBC: Message KALIMBA_MSG_GO failed!\n"));
			Panic();
		}
	}

	/* Select the source type */
	/*PanicFalse(KalimbaSendMessage(KALIMBA_SOURCE_SELECT, SOURCE_USB, 0, 0, 0)); */
	
    /*CsrSbcEncoderUsbPluginSetVolume(volume) ;*/
	
	/*(void) StreamConnect(PanicNull(StreamUsbEndPointSource(end_point_iso_in)), StreamKalimbaSink(0));
    */
	/* Start decode */
   /* if(!KalimbaSendMessage(KALIMBA_MSG_GO,0,0,0,0))
	{
		PRINT(("SBC: Message KALIMBA_MSG_GO failed!\n"));
		Panic();
	}
	*/
}