/****************************************************************************

DESCRIPTION
	This function creates and populates a DM_SM_SSP_ADD_DEVICE_REQ primitive 
    and sends it to Bluestack to register a device with the Bluestack 
    Security Manager
*/
static void register_device(cl_dm_bt_version version, const TrustedDeviceRecordType* p_dev_record)
{	
	if(version != bluetooth_unknown)
	{
		/* If we have a known bluetooth version firmware must support latest DM prims */
		MAKE_PRIM_T(DM_SM_SSP_ADD_DEVICE_REQ);
		connectionConvertBdaddr_t(&prim->bd_addr, &p_dev_record->bd_addr);
    	prim->update_trust_level = TRUE;
    	prim->trusted = p_dev_record->trusted;
    	prim->update_link_key = TRUE;
    	memcpy(prim->link_key, p_dev_record->link_key, SIZE_LINK_KEY);
		prim->link_key_type = connectionConvertLinkKeyType_t(p_dev_record->link_key_type);
		VmSendDmPrim(prim);
	}
	else
	{
		/* Old firmware, use old prims */
		MAKE_PRIM_T(DM_SM_ADD_DEVICE_REQ);
		connectionConvertBdaddr_t(&prim->bd_addr, &p_dev_record->bd_addr);
    	prim->update_trust_level = TRUE;
    	prim->trusted = p_dev_record->trusted;
    	prim->update_link_key = TRUE;
    	memcpy(prim->link_key, p_dev_record->link_key, SIZE_LINK_KEY);
		VmSendDmPrim(prim);
	}
}
/****************************************************************************
NAME	
    connectionHandleInquiryCancel

DESCRIPTION
    This function cancels an ongoing inquiry

RETURNS
    void
*/
void connectionHandleInquiryCancel(const connectionInquiryState *state, const CL_INTERNAL_DM_INQUIRY_CANCEL_REQ_T *cancel_req)
{
    /* Check if we have an inquiry in progress */
    if (state->inquiryLock)
    {
        if (state->inquiryLock == cancel_req->theAppTask)
        {
            if (state->periodic_inquiry)
    {
                /* We have an periodic inquiry so issue the exit */
                MAKE_PRIM_C(DM_HCI_EXIT_PERIODIC_INQUIRY_MODE_REQ);
                VmSendDmPrim(prim);
		}
	else
	{
                /* We have an inquiry so issue the cancel */
                MAKE_PRIM_C(DM_HCI_INQUIRY_CANCEL_REQ);
			VmSendDmPrim(prim);
		}
	}
	}
        else
    {
        /* Send an inquiry complete to the app telling it we're ready */
        inquirySendResult(cancel_req->theAppTask, inquiry_status_ready, 0, (uint32) 0, 0, 0, 0, CL_RSSI_UNKNOWN, 0, NULL);
	}
}
/****************************************************************************
NAME
	connectionAuthSendLinkKey

FUNCTION
	This function is called to send the link key of the specified device to the
	Bluestack Security Manager

*/
void connectionAuthSendLinkKey(const bdaddr* peer_bd_addr)
{
	uint16						rec;
    TrustedDeviceRecordType     record;
	
    MAKE_PRIM_T(DM_SM_LINK_KEY_REQUEST_RES);
	connectionConvertBdaddr_t(&prim->bd_addr, peer_bd_addr);

	/* Search for the device in the TDL */
	rec = find_trusted_device(peer_bd_addr);
	
    /* If the device is in the TDL */
	if(rec)
	{
		rec--;
		/* Get the link key */
		(void)PsRetrieve(TRUSTED_DEVICE_LIST_BASE + rec, &record, sizeof(TrustedDeviceRecordType));

		prim->valid = 1;
		memcpy(prim->key, record.link_key, SIZE_LINK_KEY);
	}
	else
	{
		/* Reject the request for a link key */
		prim->valid = 0;        
		memset(prim->key, 0, SIZE_LINK_KEY);
	}

	
	/* Send message to the Connection Manager */
	VmSendDmPrim(prim);
}
/****************************************************************************
NAME    
    ConnectionDmBleAddDeviceToWhiteListReq

DESCRIPTION
    Add a single device to the BLE White List stored in the controller.

RETURNS
   void
*/
void ConnectionDmBleAddDeviceToWhiteListReq(
        uint8 bd_addr_type, 
        const bdaddr *bd_addr
        )
{
#ifdef CONNECTION_DEBUG_LIB
    if (bd_addr_type > TYPED_BDADDR_RANDOM)
    {
        CL_DEBUG(("'bd_addr_type' must be TYPED_BDADDR_PUBLIC or _RANDOM\n"));
    }
    if (!bd_addr)
    {
        CL_DEBUG(("'addr' cannot be NULL\n"));
    }
#endif
    if (connectionGetBtVersion() < bluetooth4_0)
    {
        CL_DEBUG(("Bluestack does not support low energy (BT 4.0)\n"));
    }
    else
    {
        MAKE_PRIM_C(DM_HCI_ULP_ADD_DEVICE_TO_WHITE_LIST_REQ);
        prim->address_type = bd_addr_type;
        BdaddrConvertVmToBluestack(&prim->address, bd_addr);
        VmSendDmPrim(prim);
    }
}
/****************************************************************************
NAME	
    connectionHandleClearParamCacheRequest

DESCRIPTION
    Handles the internal message requesting to clear the parameter cache for 
	a given device

RETURNS
    void
*/
void connectionHandleClearParamCacheRequest(const CL_INTERNAL_DM_CLEAR_PARAM_CACHE_REQ_T *req)
{
	/* Send the request to BlueStack */
	MAKE_PRIM_T(DM_CLEAR_PARAM_CACHE_REQ);
	BdaddrConvertVmToBluestack(&prim->bd_addr, &req->bd_addr);
	VmSendDmPrim(prim);
}
/****************************************************************************
NAME	
    connectionHandleWriteInquiryScanActivityRequset

DESCRIPTION
    Handles the internal message requesting a inquiry scan activity write

RETURNS
    void
*/
void connectionHandleWriteInquiryScanActivityRequest(const CL_INTERNAL_DM_WRITE_INQSCAN_ACTIVITY_REQ_T *req)
{
	MAKE_PRIM_C(DM_HCI_WRITE_INQUIRYSCAN_ACTIVITY_REQ);
	prim->inqscan_interval = req->is_interval;
	prim->inqscan_window = req->is_window;
	VmSendDmPrim(prim);
}
/****************************************************************************
NAME
    connectionHandleReadEirDataRequest

DESCRIPTION
    Handles request for Reading the Extended Inquiry Data.

RETURNS
    void
*/
void connectionHandleReadEirDataRequest(connectionReadInfoState *infoState, connectionInquiryState *state, const CL_INTERNAL_DM_READ_EIR_DATA_REQ_T *req)
{
    if(infoState->version >= bluetooth2_1)
	{
		/* Check the state of the task lock before doing anything */
		if (!state->inquiryLock)
		{
			state->inquiryLock = req->task;
			{
                MAKE_PRIM_C(DM_HCI_READ_EXTENDED_INQUIRY_RESPONSE_DATA_REQ);
				VmSendDmPrim(prim);
			}
		}
		else
		{
			/* Inquiry currently being performed, queue up the request */
			MAKE_CL_MESSAGE(CL_INTERNAL_DM_READ_EIR_DATA_REQ);
			COPY_CL_MESSAGE(req, message);
			MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_DM_READ_EIR_DATA_REQ, message, &state->inquiryLock);
		}
	}
	else
	{
		/* Not supported, tell the app */
		MAKE_CL_MESSAGE(CL_DM_READ_EIR_DATA_CFM);
		message->status = hci_error_unsupported_feature;
		message->fec_required = FALSE;
		message->size_eir_data = 0;
		message->eir_data[0] = 0;
    	MessageSend(state->inquiryLock, CL_DM_READ_EIR_DATA_CFM, message);
	}
}
/****************************************************************************
NAME	
    connectionHandleWritePageScanActivityRequest

DESCRIPTION
    Handles the internal message requesting a page scan activity write

RETURNS
    void
*/
void connectionHandleWritePageScanActivityRequest(const CL_INTERNAL_DM_WRITE_PAGESCAN_ACTIVITY_REQ_T *req)
{
	MAKE_PRIM_C(DM_HCI_WRITE_PAGESCAN_ACTIVITY_REQ);
	prim->pagescan_interval = req->ps_interval;
	prim->pagescan_window = req->ps_window;
	VmSendDmPrim(prim);
}
/****************************************************************************
NAME	
    connectionHandleReadInquiryTx

DESCRIPTION
    This function will initiate a read of the inquiry tx power of the device

RETURNS
    void
*/
void connectionHandleReadInquiryTx(connectionReadInfoState* infoState, connectionInquiryState *state, const CL_INTERNAL_DM_READ_INQUIRY_TX_REQ_T *req)
{
	/* Check command supported by firmware */
	if(infoState->version != bluetooth_unknown)
	{
		/* Check the state of the task lock before doing anything */
		if (!state->inquiryLock)
		{
			/* One request at a time */
			state->inquiryLock = req->theAppTask;
		
			/* Issue request to read the inquiry tx */
			{
				MAKE_PRIM_C(DM_HCI_READ_INQUIRY_RESPONSE_TX_POWER_LEVEL_REQ);
				VmSendDmPrim(prim);
			}
		}
		else
		{
			/* Remote name request currently being performed, queue up the request */
			MAKE_CL_MESSAGE(CL_INTERNAL_DM_READ_INQUIRY_TX_REQ);
			COPY_CL_MESSAGE(req, message);
			MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_DM_READ_INQUIRY_TX_REQ, message, &state->inquiryLock);
		}
	}
	else
	{
		/* Tell the app this is unsupported */
		MAKE_CL_MESSAGE(CL_DM_READ_INQUIRY_TX_CFM);
		message->status = hci_error_unsupported_feature;
		message->tx_power = 0;
		MessageSend(req->theAppTask, CL_DM_READ_INQUIRY_TX_CFM, message);
	}
}
/****************************************************************************
NAME
setDefaultLinkPolicy

DESCRIPTION
This Function is called to set the default link policy.  This saves having
to set the link policy for every ACL connection

RETURNS

*/
static void setDefaultLinkPolicy(uint16_t in, uint16 out)
{
	MAKE_PRIM_T(DM_SET_DEFAULT_LINK_POLICY);
	prim->link_policy_settings_in = in;
	prim->link_policy_settings_out = out;
	VmSendDmPrim(prim);
}
/****************************************************************************
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	
    connectionHandleWritePageScanTypeRequset

DESCRIPTION
    Handles the internal message requesting a write page scan type

RETURNS
    void
*/
void connectionHandleWritePageScanTypeRequest(const CL_INTERNAL_DM_WRITE_PAGE_SCAN_TYPE_REQ_T *req)
{
    MAKE_PRIM_C(DM_HCI_WRITE_PAGE_SCAN_TYPE_REQ);

    prim->mode = req->type;

    VmSendDmPrim(prim);
}
/****************************************************************************
NAME	
    connectionHandleWriteCachedClkOffsetRequest

DESCRIPTION
    Handles the internal message requesting a to store the clock offset for 
	a given device

RETURNS
    void
*/
void connectionHandleWriteCachedClkOffsetRequest(const CL_INTERNAL_DM_WRITE_CACHED_CLK_OFFSET_REQ_T *req)
{
	/* Send the request to BlueStack */
	MAKE_PRIM_T(DM_WRITE_CACHED_CLOCK_OFFSET_REQ);
	BdaddrConvertVmToBluestack(&prim->bd_addr, &req->bd_addr);
	prim->clock_offset = req->clock_offset;
	VmSendDmPrim(prim);
}
/****************************************************************************
NAME	
    connectionHandleWriteCachedPageModeRequest

DESCRIPTION
    Handles the internal message requesting a to store the page mode for a given device

RETURNS
    void
*/
void connectionHandleWriteCachedPageModeRequest(const CL_INTERNAL_DM_WRITE_CACHED_PAGE_MODE_REQ_T *req)
{
	MAKE_PRIM_T(DM_WRITE_CACHED_PAGE_MODE_REQ);
	BdaddrConvertVmToBluestack(&prim->bd_addr, &req->bd_addr);
    prim->page_scan_mode = connectionConvertPageScanMode(req->ps_mode);
    prim->page_scan_rep_mode = connectionConvertPageScanRepMode(req->ps_rep_mode);
	VmSendDmPrim(prim);
}
/****************************************************************************
NAME
connectionDmInit

DESCRIPTION
This Function is called to register the Connection Manager with Bluestack.  
The Bluestack message DM_AM_REGISTER_REQ is sent to the Bluestack Device
Manager (DM)

RETURNS

*/
void connectionDmInit(void)
{
     MAKE_PRIM_T(DM_AM_REGISTER_REQ);
     prim->phandle = 0;
     VmSendDmPrim(prim);
	 
	 /* Configure all SCOs to be streams */
	 StreamConfigure(VM_STREAM_SCO_ENABLED, 1);
}
/****************************************************************************
NAME	
    connectionHandleReadClassOfDeviceRequest

DESCRIPTION
    Handles the internal message that initiates the read class of device

RETURNS
    void
*/
void connectionHandleReadClassOfDeviceRequest(connectionReadInfoState *state, const CL_INTERNAL_DM_READ_CLASS_OF_DEVICE_REQ_T *req)
{
	/* Issue the request to BlueStack */
	MAKE_PRIM_C(DM_HCI_READ_CLASS_OF_DEVICE);
	VmSendDmPrim(prim);

	/* Not currently processing one of these so set the lock */
	state->stateInfoLock = req->theAppTask;
    state->sink = 0;
}
/****************************************************************************
NAME	
    connectionHandleWriteInquiryTx

DESCRIPTION
    This function will initiate a write of the inquiry tx power of the device

RETURNS
    void
*/
void connectionHandleWriteInquiryTx(connectionReadInfoState* infoState, connectionInquiryState *state, const CL_INTERNAL_DM_WRITE_INQUIRY_TX_REQ_T *req)
{
	/* Check command supported by firmware */
	if(infoState->version != bluetooth_unknown)
	{
		MAKE_PRIM_C(DM_HCI_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_REQ);
		prim->tx_power = req->tx_power;
		VmSendDmPrim(prim);
	}
}
/****************************************************************************
NAME    
    ConnectionDmBleReadWhiteListSizeReq

DESCRIPTION
    Clear all devices in the BLE White List stored in the controller.

RETURNS
   void
*/
void ConnectionDmBleClearWhiteListReq(void)
{
    if (connectionGetBtVersion() < bluetooth4_0)
    {
        CL_DEBUG(("Bluestack does not support low energy (BT 4.0)\n"));
    }
    else
    {
        MAKE_PRIM_C(DM_HCI_ULP_CLEAR_WHITE_LIST_REQ);
        VmSendDmPrim(prim);
    }
}
/****************************************************************************
NAME    
    connectionHandleReadRemoteNameCancel

DESCRIPTION
    This function will cancel the ongoing RNR

RETURNS
    void
*/
void connectionHandleReadRemoteNameCancel(connectionInquiryState *state,
                   const CL_INTERNAL_DM_READ_REMOTE_NAME_CANCEL_REQ_T *req)
{
    /* Check a remote name request is already on process */
    if ( state->nameLock && ( state->nameLock == req->theAppTask ) )
    {
        /* Issue request to cancel read the remote name */
        MAKE_PRIM_C(DM_HCI_REMOTE_NAME_REQ_CANCEL_REQ);
        BdaddrConvertVmToBluestack(&prim->bd_addr, &req->bd_addr);
        VmSendDmPrim(prim);
    }

/* else ignore the request since RNR must have completed or already cancelled */
}
/****************************************************************************
NAME	
    connectionHandleExitPeriodicInquiryComplete

DESCRIPTION
    This function handles an exit periodic inquiry complete indication from
    BlueStack.

RETURNS
    void
*/
void connectionHandleExitPeriodicInquiryComplete(connectionInquiryState *state)
{
    /* Clear lock and reset event filter if not periodic inquiry */
    if (state->periodic_inquiry)
	{
        /* Reset the event filter so its not longer filtering on cod */
        MAKE_PRIM_C(DM_HCI_SET_EVENT_FILTER_REQ);
        prim->filter_type = INQUIRY_RESULT_FILTER;
        prim->filter_condition_type = NEW_DEVICE_RESPONDED;
			VmSendDmPrim(prim);

        /* Reset the lock */
        state->inquiryLock = 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)
{
	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 connectionHandleChangeLocalName(const CL_INTERNAL_DM_CHANGE_LOCAL_NAME_REQ_T *req)
{
	uint16 i;
	MAKE_PRIM_C(DM_HCI_CHANGE_LOCAL_NAME_REQ); 
	prim->common.length = sizeof(DM_HCI_CHANGE_LOCAL_NAME_REQ_T) + req->length_name;

	if (req->length_name)
		prim->name_part[0] = VmGetHandleFromPointer(req->name);
	else
		prim->name_part[0] = 0;

	/* Set all the other ptrs in the message to null */
	for (i = 1; i < HCI_LOCAL_NAME_BYTE_PACKET_PTRS; i++)
		prim->name_part[i] = 0;

	VmSendDmPrim(prim);
}
/****************************************************************************
NAME	
    connectionHandleInquiryComplete

DESCRIPTION
    This function handles an inquiry complete indication fromBlueStack.

RETURNS
    void
*/
void connectionHandleInquiryComplete(connectionInquiryState *state)
{
	/* Tell the client the inquiry has completed */
    inquirySendResult(state->inquiryLock, inquiry_status_ready, 0, (uint32) 0, 0, 0, 0, CL_RSSI_UNKNOWN, 0, NULL);

    /* Clear lock and reset event filter if not periodic inquiry */
    if (!state->periodic_inquiry)
	{
		/* Reset the event filter so its not longer filtering on cod */
        MAKE_PRIM_C(DM_HCI_SET_EVENT_FILTER_REQ);
		prim->filter_type = INQUIRY_RESULT_FILTER;
		prim->filter_condition_type = NEW_DEVICE_RESPONDED;
		VmSendDmPrim(prim);

        /* Reset the lock */
        state->inquiryLock = 0;
	}
}
/****************************************************************************
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 ConnectionDmBleSetConnectionParametersReq(
    const ble_connection_params *params)
{
    MAKE_PRIM_T(DM_SET_BLE_CONNECTION_PARAMETERS_REQ);

    prim->scan_interval = params->scan_interval;
    prim->scan_window = params->scan_window;
    prim->conn_interval_min = params->conn_interval_min;
    prim->conn_interval_max = params->conn_interval_max;
    prim->conn_latency = params->conn_latency;
    prim->supervision_timeout = params->supervision_timeout;
    prim->conn_attempt_timeout = params->conn_attempt_timeout;
    prim->conn_latency_max = params->conn_latency_max;
    prim->supervision_timeout_min = params->supervision_timeout_min;
    prim->supervision_timeout_max = params->supervision_timeout_max;
    prim->own_address_type = params->own_address_type;

    VmSendDmPrim(prim);    
}
void connectionDmInfoInit(void)
{
    /* Set default link policy */
    setDefaultLinkPolicy(ENABLE_MS_SWITCH | ENABLE_SNIFF, ENABLE_MS_SWITCH | ENABLE_SNIFF);

    /* 
        Enable enhanced ACL indications by default 
    
        NOTE: If you see a VM panic at this point please refer to B-10816 in the 
        BlueLab documentation. To avoid this panic either upgrade to firmware that
        supports the BlueStack enhancements primitives or do not use the application
        under xIDE. 
    */
    {
        MAKE_PRIM_T(DM_EN_ENABLE_ENHANCEMENTS_REQ);
	    prim->enhancements = ENHANCEMENT_ACL_INDICATION;
	    VmSendDmPrim(prim);
    }
}
/****************************************************************************
NAME	
    connectionHandleSetBtVersionReq

DESCRIPTION
    Handle setting BT Version

RETURNS
    void
*/
void connectionHandleSetBtVersionReq(connectionReadInfoState *state, const CL_INTERNAL_DM_SET_BT_VERSION_REQ_T *req)
{
	if(!state->stateInfoLock)
	{
		state->stateInfoLock = req->theAppTask;
		{
		MAKE_PRIM_T(DM_SET_BT_VERSION_REQ);
		prim->version = req->version;
		VmSendDmPrim(prim);
		}
	}
	else
	{
		/* Lock set so queue up the request */
		MAKE_CL_MESSAGE(CL_INTERNAL_DM_SET_BT_VERSION_REQ);
		COPY_CL_MESSAGE(req, message);
		MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_DM_SET_BT_VERSION_REQ, message, &state->stateInfoLock);
	}
}
/****************************************************************************
NAME	
    connectionHandleReadLocalVersionRequest

DESCRIPTION
    Request to read the version information of the local device.
  
RETURNS
    void
*/
void connectionHandleReadLocalVersionRequest(connectionReadInfoState *state, const CL_INTERNAL_DM_READ_LOCAL_VERSION_REQ_T *req)
{
 	/* Check the resource lock */
 	if (!state->stateInfoLock)
 	{
		/* Response not outstanding so issue request */
 		MAKE_PRIM_C(DM_HCI_READ_LOCAL_VERSION);
 		VmSendDmPrim(prim);
 
 		/* Set the lock */
 		state->stateInfoLock = req->theAppTask;
 	}
 	else
 	{
 		/* Lock set so queue up the request */
		MAKE_CL_MESSAGE(CL_INTERNAL_DM_READ_LOCAL_VERSION_REQ);
		COPY_CL_MESSAGE(req, message);
		MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_DM_READ_LOCAL_VERSION_REQ, message, &state->stateInfoLock);
	}
}
/****************************************************************************
NAME	
    connectionHandleReadInquiryModeRequest

DESCRIPTION
    Read inquiry mode

RETURNS
    void
*/
void connectionHandleReadInquiryModeRequest(connectionInquiryState *state, const CL_INTERNAL_DM_READ_INQUIRY_MODE_REQ_T *req)
{
	/* Check the state of the task lock before doing anything */
	if (!state->inquiryLock)
	{
		state->inquiryLock = req->theAppTask;

	    {   /* Issue inquiry mode read */
            MAKE_PRIM_C(DM_HCI_READ_INQUIRY_MODE_REQ);
			VmSendDmPrim(prim);
		}
	}
	else
	{
		/* Inquiry currently being performed, queue up the request */
		MAKE_CL_MESSAGE(CL_INTERNAL_DM_READ_INQUIRY_MODE_REQ);
		COPY_CL_MESSAGE(req, message);
		MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_DM_READ_INQUIRY_MODE_REQ, message, &state->inquiryLock);
	}
}
/****************************************************************************
NAME	
    connectionHandleWriteInquiryModeRequest

DESCRIPTION
    Write inquiry mode

RETURNS
    void
*/
void connectionHandleWriteInquiryModeRequest(connectionInquiryState *state, const CL_INTERNAL_DM_WRITE_INQUIRY_MODE_REQ_T *req)
{
	/* Check the state of the task lock before doing anything */
	if (!state->inquiryLock)
	{
		state->inquiryLock = req->theAppTask;

	    {   /* Issue inquiry mode change with the supplied parameter */
            MAKE_PRIM_C(DM_HCI_WRITE_INQUIRY_MODE_REQ);
			prim->mode = connectionConvertInquiryMode_t(req->mode);
			VmSendDmPrim(prim);
		}
	}
	else
	{
		/* Inquiry currently being performed, queue up the request */
		MAKE_CL_MESSAGE(CL_INTERNAL_DM_WRITE_INQUIRY_MODE_REQ);
		COPY_CL_MESSAGE(req, message);
		MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_DM_WRITE_INQUIRY_MODE_REQ, message, &state->inquiryLock);
	}
}