/**************************************************************************** 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); } }
void gattHandleAttRegisterCfm(gattState *theGatt, ATT_REGISTER_CFM_T *cfm) { if (cfm->result) { GATT_DEBUG_INFO(("GATT_INIT_CFM status %0x02X\n", cfm->result)); theGatt->state = gatt_state_uninitialised; gattSendInitCfm(theGatt->theAppTask, gatt_status_att_reg_failure); if (!(theGatt->flags & GATT_FLAGS_CONST_DB)) if (theGatt->u.database.size) free(theGatt->u.database.ptr); } else { if (theGatt->u.database.size) { MAKE_ATT_PRIM(ATT_ADD_DB_REQ); prim->size_db = theGatt->u.database.size; prim->db = VmGetHandleFromPointer(theGatt->u.database.ptr); prim->flags = 0; /* Not applicable for only DB. */ VmSendAttPrim(prim); } else { theGatt->state = gatt_state_initialised; gattSendInitCfm(theGatt->theAppTask, gatt_status_success); gattInitCidTaskMap(); } } }
/************************************************************************* NAME gatt_find_by_type_value_req DESCRIPTION Send ATT_FIND_BY_TYPE_VALUE_REQ to Bluestack. GATT uses this only for searching for UUID in value so the value parameter is UUID. RETURNS */ void gatt_find_by_type_value_req(uint16 cid, uint16 start, uint16 end, uint16 type, gatt_uuid_type_t uuid_type, const gatt_uuid_t *uuid) { uint32 u[4]; uint32 *p; uint16 i; MAKE_ATT_PRIM(ATT_FIND_BY_TYPE_VALUE_REQ); prim->cid = cid; prim->start = start; prim->end = end; prim->uuid = type; if (uuid_type == gatt_uuid16) { prim->size_value = 2U; /* UUID16 = 2 bytes ( 16 / 8 )*/ p = &u[0]; /* point to end of UUID16 */ } else if (uuid_type == gatt_uuid32) { prim->size_value = 4U; /* UUID32 = 4 bytes ( 32 / 8 )*/ p = &u[0]; /* point to end of UUID32 */ } else { prim->size_value = 16U; /* UUID128 = 16 bytes ( 128 / 8 )*/ p = &u[3]; /* point to end of UUID128 */ } /* copy uuid */ memmove(u, uuid, GATT_UUID_SIZE); /* allocate room for filter */ prim->value = PanicUnlessMalloc(prim->size_value); /* copy pos bytes from the end to the beginning, i.e. swapping byte * order from big endian to little endian */ for (i = 0; i < prim->size_value; i++) { prim->value[i] = *p & 0xff; /* jump to next index every time bit 2 changes position */ if ((i & 0x3) == 0x03) { p--; /* move to the previous index */ } else { *p >>= 8; /* shift to the next part of p */ } } prim->value = VmGetHandleFromPointer(prim->value); VmSendAttPrim(prim); }
/**************************************************************************** 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 gatt_read_multi_req DESCRIPTION Send ATT_READ_MULTI_REQ to Bluestack. RETURNS */ void gatt_read_multi_req(uint16 cid, uint16 size_handles, uint16 *handles) { MAKE_ATT_PRIM(ATT_READ_MULTI_REQ); prim->cid = cid; prim->size_handles = size_handles; prim->handles = PanicUnlessMalloc(size_handles); memmove(prim->handles, handles, size_handles); prim->handles = VmGetHandleFromPointer(prim->handles); VmSendAttPrim(prim); }
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 gatt_write_req DESCRIPTION Send ATT_WRITE_REQ to Bluestack. RETURNS */ void gatt_prepare_write_req(uint16 cid, uint16 handle, uint16 offs, uint16 size_value, uint8 *value) { MAKE_ATT_PRIM(ATT_PREPARE_WRITE_REQ); prim->cid = cid; prim->handle = handle; prim->offset = offs; prim->size_value = size_value; prim->value = PanicUnlessMalloc(size_value); memmove(prim->value, value, size_value); prim->value = VmGetHandleFromPointer(prim->value); VmSendAttPrim(prim); }
/**************************************************************************** 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 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); } }
/**************************************************************************** NAME connectionAuthSendSspLinkKey FUNCTION This function is called to send the link key of the specified device to the Bluestack Security Manager in mode 4. In addition to the link key this also sends the link key type */ bool connectionAuthSendSspLinkKey(const bdaddr* peer_bd_addr, bool authenticated) { uint16 rec; TrustedDeviceRecordType record; bool success; uint8* link_key; MAKE_PRIM_T(DM_SM_SSP_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)); /* Handle old records with no key type stored */ if(record.link_key_type == 0) record.link_key_type = cl_sm_link_key_legacy; if(authenticated) { if(record.link_key_type == cl_sm_link_key_authenticated) { prim->key_type = connectionConvertLinkKeyType_t(record.link_key_type); link_key = (uint8*) PanicUnlessMalloc(SIZE_LINK_KEY); memcpy(link_key, record.link_key, SIZE_LINK_KEY); prim->key = VmGetHandleFromPointer(link_key); success = TRUE; } else { prim->key_type = connectionConvertLinkKeyType_t(cl_sm_link_key_none); prim->key = NULL; success = FALSE; } } else { prim->key_type = connectionConvertLinkKeyType_t(record.link_key_type); link_key = (uint8*) PanicUnlessMalloc(SIZE_LINK_KEY); memcpy(link_key, record.link_key, SIZE_LINK_KEY); prim->key = VmGetHandleFromPointer(link_key); success = TRUE; } } else { /* Reject the request for a link key */ prim->key_type = connectionConvertLinkKeyType_t(cl_sm_link_key_none); prim->key = NULL; success = FALSE; } /* Send message to the Connection Manager */ VmSendDmPrim(prim); return success; }