/**************************************************************************** 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); } }