void GattReliableWriteExecuteRequest(Task theAppTask, uint16 cid, bool execute) { cid_map_t *conn; if ((conn = gattFindConn(cid)) && !conn->closing) { MAKE_GATT_MESSAGE(GATT_INTERNAL_EXECUTE_WRITE_REQ); message->common.task = theAppTask; message->common.cid = cid; message->flags = execute ? ATT_EXECUTE_WRITE : ATT_EXECUTE_CANCEL; MessageSendConditionallyOnTask( gattGetTask(), GATT_INTERNAL_EXECUTE_WRITE_REQ, message, &conn->data.app); } else { sendReliableWriteExecuteCfm(theAppTask, cid, 0 /* handle */, gatt_status_invalid_cid); } }
void GattDiscoverAllCharacteristicsRequest(Task theAppTask, uint16 cid, uint16 start, uint16 end) { cid_map_t *conn; if ((conn = gattFindConn(cid)) && !conn->closing) { MAKE_GATT_MESSAGE(GATT_INTERNAL_DISCOVER_ALL_CHARACTERISTICS_REQ); message->common.task = theAppTask; message->common.cid = cid; message->start = start; message->end = end; MessageSendConditionallyOnTask( gattGetTask(), GATT_INTERNAL_DISCOVER_ALL_CHARACTERISTICS_REQ, message, &conn->data.app); } else { MAKE_GATT_MESSAGE(GATT_DISCOVER_ALL_CHARACTERISTICS_CFM); memset(message, 0, sizeof(GATT_DISCOVER_ALL_CHARACTERISTICS_CFM_T)); message->cid = cid; message->status = gatt_status_invalid_cid; MessageSend(theAppTask, GATT_DISCOVER_ALL_CHARACTERISTICS_CFM, message); } }
/**************************************************************************** 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 connectionHandleSdpOpenSearchRequest DESCRIPTION Send a request to BlueSTack to open an SDP search session RETURNS void */ void connectionHandleSdpOpenSearchRequest(connectionSdpState *state, const CL_INTERNAL_SDP_OPEN_SEARCH_REQ_T *req) { /* Check the state of the resource lock */ if (!state->sdpLock) { /* Resource free, set the lock */ state->sdpLock = req->theAppTask; /* Store the address of the device we're opening the search to */ state->sdpServerAddr = req->bd_addr; /* Send the request to BlueStack */ { MAKE_PRIM_T(SDC_OPEN_SEARCH_REQ); connectionConvertBdaddr_t(&prim->bd_addr, &req->bd_addr); VmSendSdpPrim(prim); } } else if(req->theAppTask != connectionGetCmTask()) { /* Resource busy so queue up the request */ MAKE_CL_MESSAGE(CL_INTERNAL_SDP_OPEN_SEARCH_REQ); COPY_CL_MESSAGE(req, message); MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_SDP_OPEN_SEARCH_REQ, message, &state->sdpLock); } }
/**************************************************************************** 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 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); } }
void ConnectionReadBtVersion(Task theAppTask) { /* All requests are sent through the internal state handler */ MAKE_CL_MESSAGE(CL_INTERNAL_DM_SET_BT_VERSION_REQ); message->theAppTask = theAppTask; message->version = BT_VERSION_CURRENT; MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_DM_SET_BT_VERSION_REQ, message, &theCm.infoState.stateInfoLock); }
void ConnectionReadRemoteVersion(Task theAppTask, Sink sink) { /* All requests are sent through the internal state handler */ MAKE_CL_MESSAGE(CL_INTERNAL_DM_READ_REMOTE_VERSION_REQ); message->theAppTask = theAppTask; message->sink = sink; MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_DM_READ_REMOTE_VERSION_REQ, message, &theCm.infoState.stateInfoLock); }
void ConnectionGetLinkQuality(Task theAppTask, Sink sink) { /* All requests are sent through the internal state handler */ MAKE_CL_MESSAGE(CL_INTERNAL_DM_READ_LINK_QUALITY_REQ); message->theAppTask = theAppTask; message->sink = sink; MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_DM_READ_LINK_QUALITY_REQ, message, &theCm.infoState.stateInfoLock); }
/**************************************************************************** NAME connectionHandleSdpServiceSearchAttrRequest DESCRIPTION Handle a request to perfor a service/ attribute search. If allowed, send request to BlueStack otherwise queue it up until it can be sent. RETURNS void */ void connectionHandleSdpServiceSearchAttrRequest(connectionSdpState *state, const CL_INTERNAL_SDP_SERVICE_SEARCH_ATTRIBUTE_REQ_T *req) { sdp_search_req res = sendSearchRequest(req->theAppTask, state, &req->bd_addr); if (res == sdp_start_search) { /* Send the request to BlueStack */ MAKE_PRIM_T(SDC_SERVICE_SEARCH_ATTRIBUTE_REQ); prim->phandle = 0; connectionConvertBdaddr_t(&prim->bd_addr, &req->bd_addr); prim->size_srch_pttrn = req->size_search_pattern; if (req->size_search_pattern) prim->srch_pttrn = VmGetHandleFromPointer(req->search_pattern); else prim->srch_pttrn = 0; prim->size_attr_list = req->size_attribute_list; if (req->size_attribute_list) prim->attr_list = VmGetHandleFromPointer(req->attribute_list); else prim->attr_list = 0; prim->max_num_attr = req->max_num_attributes; VmSendSdpPrim(prim); /* Lock the resource */ state->sdpSearchLock = req->theAppTask; } else { Task *c = 0; /* Queue up the search request */ MAKE_CL_MESSAGE(CL_INTERNAL_SDP_SERVICE_SEARCH_ATTRIBUTE_REQ); COPY_CL_MESSAGE(req, message); /* Use the return value from searchRequest function to decide which resource to wait on */ if (res == sdp_lock_set) c = &state->sdpLock; else if (res == sdp_search_lock_set) c = &state->sdpSearchLock; else if (res == sdp_session_open_other_dev) c = &state->sdpLock; else /* Should not get here but if we do panic */ Panic(); /* Queus up message with condition determined above */ MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_SDP_SERVICE_SEARCH_ATTRIBUTE_REQ, message, c); } }
/**************************************************************************** NAME gattHandleAttDisonnectInd DESCRIPTION Handles the ATT_DISCONNECT_IND from BlueStack. RETURNS */ void gattHandleAttDisconnectInd(gattState *theGatt, ATT_DISCONNECT_IND_T *ind) { cid_map_t *conn; if ((conn = gattFindConn(ind->cid))) { MAKE_GATT_MESSAGE(GATT_INTERNAL_DELETE_CONN); message->cid = ind->cid; message->theAppTask = conn->task; switch (ind->reason) { case L2CA_DISCONNECT_NORMAL: message->status = gatt_status_success; break; case L2CA_DISCONNECT_LINK_LOSS: message->status = gatt_status_link_loss; break; default: message->status = gatt_status_abnornal_disconnection; GATT_DEBUG_INFO(( "Disconnect Ind Reason: 0x%04x\n", ind->reason )); break; } /* stop using this connection */ conn->closing = TRUE; /* send message to ourself telling to delete the connection, but * queue the message after any pending scenario are completed. */ MessageSendConditionallyOnTask( gattGetTask(), GATT_INTERNAL_DELETE_CONN, message, &conn->data.app); } else { GATT_DEBUG_INFO(( "gattHandleAttDisconnectInd: cid 0x%04x not found\n", ind->cid )); } }
/**************************************************************************** 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 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 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 connectionHandleSdpClientConfigMtu DESCRIPTION Send a request to BlueStack to configure the SDP client MTU size RETURNS void */ void connectionHandleSdpClientConfigMtu(const connectionSdpState *state, const CL_INTERNAL_SDP_CONFIG_CLIENT_MTU_REQ_T *req) { /* We don't get a response from this so send it without setting the lock. Still have to make sure the lock isn't set though so check it before sending the prim */ if (!state->sdpLock) { MAKE_PRIM_T(SDC_CONFIG_REQ); prim->mtu = req->mtu; VmSendSdpPrim(prim); } else { /* Resource is locked, queue up the request for later */ MAKE_CL_MESSAGE(CL_INTERNAL_SDP_CONFIG_CLIENT_MTU_REQ); COPY_CL_MESSAGE(req, message); MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_SDP_CONFIG_CLIENT_MTU_REQ, message, &state->sdpLock); } }
/**************************************************************************** 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); } }
/**************************************************************************** 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); } }
/**************************************************************************** NAME connectionHandleSdpUnregisterRequest DESCRIPTION Handle the request to unregister a particular service record RETURNS void */ void connectionHandleSdpUnregisterRequest(connectionSdpState *state, const CL_INTERNAL_SDP_UNREGISTER_RECORD_REQ_T *req) { /* Check the resource lock */ if (!state->sdpLock) { /* Set lock */ state->sdpLock = req->theAppTask; /* Resource free so send request down to BlueStack */ { MAKE_PRIM_T(SDS_UNREGISTER_REQ); prim->phandle = 0; prim->svc_rec_hndl = req->service_handle; VmSendSdpPrim(prim); } } else { /* Resource is locked, queue up the request for later */ MAKE_CL_MESSAGE(CL_INTERNAL_SDP_UNREGISTER_RECORD_REQ); COPY_CL_MESSAGE(req, message); MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_SDP_UNREGISTER_RECORD_REQ, message, &state->sdpLock); } }
/**************************************************************************** NAME connectionHandleSdpRegisterRequest DESCRIPTION Sends a register request to the SDP server RETURNS void */ void connectionHandleSdpRegisterRequest(connectionSdpState *state, const CL_INTERNAL_SDP_REGISTER_RECORD_REQ_T *req) { /* If the resource is not locked, send downt he request */ if (!state->sdpLock) { /* Set the lock */ state->sdpLock = req->theAppTask; { MAKE_PRIM_T(SDS_REGISTER_REQ); prim->phandle = 0; prim->num_rec_bytes = req->record_length; prim->service_rec = VmGetHandleFromPointer(req->record); VmSendSdpPrim(prim); } } else { /* Resource locked, queue up the request */ MAKE_CL_MESSAGE(CL_INTERNAL_SDP_REGISTER_RECORD_REQ); COPY_CL_MESSAGE(req, message); MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_SDP_REGISTER_RECORD_REQ, message, &state->sdpLock); } }
void ConnectionSmReadLocalOobData(Task theAppTask) { MAKE_CL_MESSAGE(CL_INTERNAL_SM_READ_LOCAL_OOB_DATA_REQ); message->task = theAppTask; MessageSendConditionallyOnTask(connectionGetCmTask(), CL_INTERNAL_SM_READ_LOCAL_OOB_DATA_REQ, message, &theCm.smState.authReqLock); }
/**************************************************************************** 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); } }
/**************************************************************************** NAME gattHandleInternalConnectReq DESCRIPTION Handle the internal connection request. Queue message if a connection is already being processed. RETURN */ void gattHandleInternalConnectReq( gattState *theGatt, GATT_INTERNAL_CONNECT_REQ_T *req ) { /* Reject this if there are already the maximum number of ATT connections.*/ if (gattMaxConnections()) { gattSendConnectionCfm( req->theAppTask, gatt_status_max_connections, 0, /* TYPED_BD_ADDR */ 0, /* flags */ 0, /* mtu */ 0 /* cid */ ); } /* Check the scenario state - proceed if there is no connect_req already * in progress. */ else if (!theGatt->conn_req_task) { MAKE_ATT_PRIM(ATT_CONNECT_REQ); /* Set the scenario state. */ theGatt->conn_req_task = req->theAppTask; BdaddrConvertTypedVmToBluestack(&prim->addrt, &req->taddr); switch(req->connection) { case gatt_connection_bredr_master: prim->flags = L2CA_CONFLAG_ENUM(L2CA_CONNECTION_BR_EDR); break; case gatt_connection_ble_master_directed: prim->flags = L2CA_CONFLAG_ENUM(L2CA_CONNECTION_LE_MASTER_DIRECTED); break; case gatt_connection_ble_master_whitelist: prim->flags = L2CA_CONFLAG_ENUM(L2CA_CONNECTION_LE_MASTER_WHITELIST); break; case gatt_connection_ble_slave_directed_high_duty: prim->flags = L2CA_CONFLAG_ENUM( L2CA_CONNECTION_LE_SLAVE_DIRECTED_HIGH_DUTY ); break; case gatt_connection_ble_slave_whitelist: prim->flags = L2CA_CONFLAG_ENUM(L2CA_CONNECTION_LE_SLAVE_WHITELIST); break; case gatt_connection_ble_slave_undirected: prim->flags = L2CA_CONFLAG_ENUM(L2CA_CONNECTION_LE_SLAVE_UNDIRECTED); break; case gatt_connection_ble_slave_directed_low_duty: prim->flags = L2CA_CONFLAG_ENUM( L2CA_CONNECTION_LE_SLAVE_DIRECTED_LOW_DUTY ); break; } if (req->connection_timeout) prim->flags |= L2CA_CONFLAG_PAGE_TIMEOUT; VmSendAttPrim(prim); } /* Otherwise, queue this request to try again later. */ else { MAKE_GATT_MESSAGE(GATT_INTERNAL_CONNECT_REQ); *(message) = *(req); MessageSendConditionallyOnTask( gattGetTask(), GATT_INTERNAL_CONNECT_REQ, message, &theGatt->conn_req_task ); } }
static void internalWriteReq(Task theAppTask, uint16 id, uint16 cid, uint16 handle, uint16 offs, uint16 size_value, uint8 *value) { cid_map_t *conn; if ((conn = gattFindConn(cid)) && !conn->closing) { MAKE_GATT_MESSAGE_WITH_VALUE(GATT_INTERNAL_WRITE_REQ, size_value, value); message->common.task = theAppTask; message->common.cid = cid; message->handle = handle; message->offs = offs; message->id = id; MessageSendConditionallyOnTask( gattGetTask(), GATT_INTERNAL_WRITE_REQ, message, &conn->data.app); } else { MAKE_GATT_MESSAGE(GATT_WRITE_CHARACTERISTIC_VALUE_CFM); message->cid = cid; message->handle = handle; message->status = gatt_status_invalid_cid; switch (id) { #if (GATT_FEATURES & GATT_WRITE_COMMAND) case gatt_ms_write_without_response: id = GATT_WRITE_WITHOUT_RESPONSE_CFM; break; #endif #if (GATT_FEATURES & GATT_WRITE_SIGNED) case gatt_ms_signed_write_without_response: id = GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CFM; break; #endif #if (GATT_FEATURES & GATT_WRITE) case gatt_ms_write_characteristic_value: id = GATT_WRITE_CHARACTERISTIC_VALUE_CFM; break; #endif #if (GATT_FEATURES & GATT_WRITE_LONG) case gatt_ms_write_long_characteristic_value: id = GATT_WRITE_LONG_CHARACTERISTIC_VALUE_CFM; break; #endif #if (GATT_FEATURES & GATT_WRITE_RELIABLE) case gatt_ms_prepare_write: id = GATT_RELIABLE_WRITE_PREPARE_CFM; break; #endif default: /* horror error which can't happen, ever. */ Panic(); } MessageSend(theAppTask, id, message); } }