/****************************************************************************
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	
    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);
	}
}
Esempio n. 3
0
/****************************************************************************
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
    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);
	}
}
Esempio n. 5
0
/****************************************************************************
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	
    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);
	}
}
Esempio n. 7
0
/****************************************************************************
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);
    }
}
Esempio n. 8
0
/****************************************************************************
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	
    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	
    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;
}
Esempio n. 11
0
/****************************************************************************
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);
	}
}
Esempio n. 15
0
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);
}
/****************************************************************************
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);
	}
}
/****************************************************************************
NAME	
    connectionHandleWriteIacLapRequest

DESCRIPTION
    Write IAC

RETURNS
    void
*/
void connectionHandleWriteIacLapRequest(connectionInquiryState *state, const CL_INTERNAL_DM_WRITE_IAC_LAP_REQ_T *req)
{
	/* Check the state of the task lock before doing anything */
	if (!state->iacLock)
	{
		uint16 index;
		uint24_t *ptr;
        MAKE_PRIM_C(DM_HCI_WRITE_CURRENT_IAC_LAP_REQ);

		/* One request at a time */
		state->iacLock = req->theAppTask;

		/* Store number of IACs */
		prim->num_current_iac = req->num_iac;
	
		/* Zero the entries */
		memset(prim->iac_lap, 0, sizeof(uint24_t *) * HCI_IAC_LAP_PTRS);

		/* Allocate memory block */
		prim->iac_lap[0] = (uint24_t *)malloc(sizeof(uint24_t) * prim->num_current_iac);
		ptr = prim->iac_lap[0];

		/* Copy IACs */
		for (index = 0; index < req->num_iac; index++)
			ptr[index] = req->iac[index];
	
		/* Vm friendly */
		prim->iac_lap[0] = VmGetHandleFromPointer(prim->iac_lap[0]);

		/* Send request */
		VmSendDmPrim(prim);
	}
	else
	{
		/* Inquiry currently being performed, queue up the request */
		MAKE_CL_MESSAGE_WITH_LEN(CL_INTERNAL_DM_WRITE_IAC_LAP_REQ, sizeof(uint32) * req->num_iac);
		COPY_CL_MESSAGE_WITH_LEN(CL_INTERNAL_DM_WRITE_IAC_LAP_REQ, sizeof(uint32) * req->num_iac, req, message);
		MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_DM_WRITE_IAC_LAP_REQ, message, &state->iacLock);
	}
}
/****************************************************************************
NAME	
    connectionHandleReadAddrRequest

DESCRIPTION
    Handle an internal request to read the local bluetooth address

RETURNS
    void
*/
void connectionHandleReadAddrRequest(connectionReadInfoState *state, const CL_INTERNAL_DM_READ_BD_ADDR_REQ_T *req)
{
	if (!state->stateInfoLock)
	{
		/* Set the lock */
		state->stateInfoLock = req->theAppTask;
        state->sink = 0;

		/* Response not outstanding so issue request */
		{
			MAKE_PRIM_C(DM_HCI_READ_BD_ADDR);
			VmSendDmPrim(prim);
		}
	}
	else
	{
		/* Lock set so queue up the request */
		MAKE_CL_MESSAGE(CL_INTERNAL_DM_READ_BD_ADDR_REQ);
		COPY_CL_MESSAGE(req, message);
		MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_DM_READ_BD_ADDR_REQ, message, &state->stateInfoLock);
	}
}
/****************************************************************************
NAME    
    connectionHandleReadLocalName

DESCRIPTION
    This function will initiate a read of the local name of the device

RETURNS
    void
*/
void connectionHandleReadLocalName(connectionInquiryState *state, const CL_INTERNAL_DM_READ_LOCAL_NAME_REQ_T *req)
{
    /* Check the state of the task lock before doing anything */
    if (!state->nameLock)
    {
        /* One request at a time */
        state->nameLock = req->theAppTask;
        
        /* Issue request to read the remote name */
        {
            MAKE_PRIM_C(DM_HCI_READ_LOCAL_NAME_REQ);
            VmSendDmPrim(prim);
        }
    }
    else
    {
        /* Remote name request currently being performed, queue up the request */
        MAKE_CL_MESSAGE(CL_INTERNAL_DM_READ_LOCAL_NAME_REQ);
        COPY_CL_MESSAGE(req, message);
        MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_DM_READ_LOCAL_NAME_REQ, message, &state->nameLock);
    }
}
/****************************************************************************
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);
	}
}
Esempio n. 25
0
/****************************************************************************
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)
{
	/* Check the lock */
	if (!state->stateInfoLock)
	{
		/* Not currently processing one of these so set the lock */
		state->stateInfoLock = req->theAppTask;
        state->sink = 0;

		{
			/* Issue the request to BlueStack */
			MAKE_PRIM_C(DM_HCI_READ_CLASS_OF_DEVICE_REQ);
			VmSendDmPrim(prim);
		}
	}
	else
	{
		/* Currently busy processing a read cod request so queue this up */
		MAKE_CL_MESSAGE(CL_INTERNAL_DM_READ_CLASS_OF_DEVICE_REQ);
		COPY_CL_MESSAGE(req, message);
		MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_DM_READ_CLASS_OF_DEVICE_REQ, message, &state->stateInfoLock);
	}
}
Esempio n. 26
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"));
        }
    }
}
Esempio n. 27
0
/****************************************************************************
NAME	
    connectionHandleWriteCodRequest

DESCRIPTION
    Handles the internal message requesting a write class of device

RETURNS
    void
*/
void connectionHandleWriteCodRequest(const CL_INTERNAL_DM_WRITE_CLASS_OF_DEVICE_REQ_T *req)
{
	MAKE_PRIM_C(DM_HCI_WRITE_CLASS_OF_DEVICE_REQ);
	prim->dev_class = req->class_of_device;
	VmSendDmPrim(prim);
}
Esempio n. 28
0
/****************************************************************************
NAME	
    connectionHandleWriteScanEnableRequset

DESCRIPTION
    Handles the internal message requesting a write scan enable

RETURNS
    void
*/
void connectionHandleWriteScanEnableRequest(const CL_INTERNAL_DM_WRITE_SCAN_ENABLE_REQ_T *req)
{
	MAKE_PRIM_C(DM_HCI_WRITE_SCAN_ENABLE_REQ);
	prim->scan_enable = connectionConvertHciScanEnable(req->mode);
	VmSendDmPrim(prim);
}
/****************************************************************************
  NAME	
      connectionStartInquiry
  
  DESCRIPTION
      This function actually kicks off an inquiry message to BlueStack.
  
  RETURNS
      void
*/
void connectionHandleInquiryStart(connectionInquiryState *state, const CL_INTERNAL_DM_INQUIRY_REQ_T *inquiry_req)
{
	/* Check the state of the task lock before doing anything */
	if (!state->inquiryLock)
	{
		state->inquiryLock = inquiry_req->theAppTask;

		/* 
			If the class of device field is set, set an event filter so we 
			only receive inquiry results with devices with this class of 
			device. By default we filter in all devices so if class of 
			device mask set to zero we don't have to set the event filter.
		*/
		if (inquiry_req->class_of_device)
		{
            MAKE_PRIM_C(DM_HCI_SET_EVENT_FILTER_REQ);
			prim->filter_type = INQUIRY_RESULT_FILTER;
			prim->filter_condition_type = CLASS_OF_DEVICE_RESPONDED;
			prim->condition.class_mask.class_of_device = inquiry_req->class_of_device;

	        /* 
				We don't care what the bits other than the specific class 
				of device are set to so set them to zero 
			*/
			prim->condition.class_mask.mask = inquiry_req->class_of_device;
			VmSendDmPrim(prim);
		}

	    {
    if (inquiry_req->min_period)
    {
        /* Start an periodic inquiry with the supplied parameters */
        MAKE_PRIM_C(DM_HCI_PERIODIC_INQUIRY_MODE_REQ);
        prim->lap = inquiry_req->inquiry_lap;
        prim->inquiry_length = inquiry_req->timeout;
        prim->num_responses = inquiry_req->max_responses;
        prim->max_period_length = inquiry_req->max_period;
        prim->min_period_length = inquiry_req->min_period;                
        VmSendDmPrim(prim);
        state->periodic_inquiry = TRUE;
    }
    else
    {
		    /* Start an inquiry with the supplied parameters */
            MAKE_PRIM_C(DM_HCI_INQUIRY_REQ);
			prim->lap = inquiry_req->inquiry_lap;
			prim->inquiry_length = inquiry_req->timeout;
			prim->num_responses = inquiry_req->max_responses;
			VmSendDmPrim(prim);
        state->periodic_inquiry = FALSE;
		}
	}
    }
	else
	{
		/* Inquiry currently being performed, queue up the request */
		MAKE_CL_MESSAGE(CL_INTERNAL_DM_INQUIRY_REQ);
		COPY_CL_MESSAGE(inquiry_req, message);
		MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_DM_INQUIRY_REQ, message, &state->inquiryLock);
	}
}