/**************************************************************************** NAME inquirySendResult DESCRIPTION Send a CL_DM_INQUIRE_RESULT message to the client RETURNS void */ static void inquirySendResult(Task theAppTask, inquiry_status status, const bdaddr *addr, uint32 dev_class, uint16 clock_offset, page_scan_rep_mode_t ps_rep_mode, page_scan_mode_t ps_mode, int16 rssi, uint8 size_eir_data, uint8* eir_data) { if (theAppTask) { /* Create an inquiry result message and populate it with the supplied args */ MAKE_CL_MESSAGE_WITH_LEN(CL_DM_INQUIRE_RESULT,size_eir_data); message->status = status; /* Check the address has been set */ if (addr) message->bd_addr = *addr; else BdaddrSetZero(&message->bd_addr); message->dev_class = dev_class; message->clock_offset = clock_offset; message->page_scan_rep_mode = connectionConvertPageScanRepMode_t(ps_rep_mode); message->page_scan_mode = connectionConvertPageScanMode_t(ps_mode); message->rssi = rssi; message->size_eir_data = size_eir_data; if(size_eir_data) { memmove(message->eir_data, eir_data, size_eir_data); } else { message->eir_data[0] = 0; } MessageSend(theAppTask, CL_DM_INQUIRE_RESULT, message); } }
/**************************************************************************** NAME connectionHandleSdpAttributeSearchCfm DESCRIPTION A confirm to the attribute search has been received, handle it here. RETURNS void */ void connectionHandleSdpAttributeSearchCfm(connectionSdpState *state, const SDC_EX_SERVICE_ATTRIBUTE_CFM_T *cfm) { if (state->sdpSearchLock) { /* Send a cfm to the client task */ MAKE_CL_MESSAGE_WITH_LEN(CL_SDP_ATTRIBUTE_SEARCH_CFM, cfm->size_attr_list); message->status = connectionConvertSdpSearchStatus(cfm->response); message->error_code = cfm->err_code; connectionConvertBdaddr(&message->bd_addr, &cfm->bd_addr); message->size_attributes = cfm->size_attr_list; if (cfm->size_attr_list) { uint8 *attribute_list = VmGetPointerFromHandle(cfm->attr_list); memcpy(message->attributes, attribute_list, cfm->size_attr_list); free(attribute_list); } else message->attributes[0] = 0; MessageSend(state->sdpSearchLock, CL_SDP_ATTRIBUTE_SEARCH_CFM, message); /* Reset the resource lock */ state->sdpSearchLock = 0; } else { if (cfm->size_attr_list) { uint8 *attribute_list = VmGetPointerFromHandle(cfm->attr_list); free(attribute_list); } } }
/**************************************************************************** NAME localNameComplete DESCRIPTION Send a CL_DM_LOCAL_NAME_COMPLETE message to the client RETURNS void */ static void localNameComplete(Task theAppTask, hci_status status, char* name, uint16 length) { if (theAppTask) { MAKE_CL_MESSAGE_WITH_LEN(CL_DM_LOCAL_NAME_COMPLETE, length); message->status = status; message->size_local_name = length; /* Populate local name fields */ if (length) { memmove(message->local_name, name, length); free(name); } else message->local_name[0] = 0; /* Send onto Client */ MessageSend(theAppTask, CL_DM_LOCAL_NAME_COMPLETE, message); } else { if (length) free(name); } }
/**************************************************************************** NAME connectionAuthGetAttribute FUNCTION This function is called to read the specified data from the specified persistent store key. The persistent store key is calulated from the specified base + the index of the specified device in TDL. RETURNS */ void connectionAuthGetAttribute(Task appTask, uint16 ps_base, const bdaddr* bd_addr, uint16 size_psdata) { /* Find device in the TDL */ uint16 index = find_trusted_device(bd_addr); if (appTask) { /* Send a message back to the application task */ MAKE_CL_MESSAGE_WITH_LEN(CL_SM_GET_ATTRIBUTE_CFM, size_psdata); message->status = fail; message->size_psdata = size_psdata; message->psdata[0] = 0; /* If an entry exists in the TDL for the specified device */ if(index) { index--; if(size_psdata) { /* Read attribute data */ if(PsRetrieve(ps_base + index, message->psdata, size_psdata)) { message->status = success; } } } MessageSend(appTask, CL_SM_GET_ATTRIBUTE_CFM, message); } }
void ConnectionWriteInquiryAccessCode(Task theAppTask, const uint32 *iac, uint16 num_iac) { /* Check params are within allowed values - debug build only */ #ifdef CONNECTION_DEBUG_LIB if ((num_iac < MIN_WRITE_IAC_LAP) || (num_iac > MAX_WRITE_IAC_LAP)) { CL_DEBUG(("Out of range num_iac 0x%x\n", num_iac)); } #endif { MAKE_CL_MESSAGE_WITH_LEN(CL_INTERNAL_DM_WRITE_IAC_LAP_REQ, sizeof(uint32) * num_iac); message->theAppTask = theAppTask; message->num_iac = num_iac; memmove(&message->iac, iac, sizeof(uint32) * num_iac); MessageSendConditionally(connectionGetCmTask(), CL_INTERNAL_DM_WRITE_IAC_LAP_REQ, message, (const uint16 *)&theCm.inqState.inquiryLock); } }
/**************************************************************************** NAME connectionHandleReadEirDataComplete DESCRIPTION Handles result from Reading the Extended Inquiry Data. RETURNS void */ void connectionHandleReadEirDataComplete(connectionInquiryState *state, const DM_HCI_READ_EXTENDED_INQUIRY_RESPONSE_DATA_CFM_T *cfm) { if(state->inquiryLock) { uint8 size_eir_data = 0; uint8* eir_data = inquiryParseEir(&size_eir_data, (uint8**)cfm->eir_data_part, FALSE); MAKE_CL_MESSAGE_WITH_LEN(CL_DM_READ_EIR_DATA_CFM, size_eir_data); message->status = connectionConvertHciStatus(cfm->status); message->fec_required = cfm->fec_required; message->size_eir_data = size_eir_data; memmove(message->eir_data, eir_data, size_eir_data); MessageSend(state->inquiryLock, CL_DM_READ_EIR_DATA_CFM, message); free(eir_data); } state->inquiryLock = 0; }
/**************************************************************************** NAME connectionAuthGetAttribute FUNCTION This function is called to read the specified data from the specified persistent store key. The persistent store key is calulated from the specified base + the index of the specified device in TDL. RETURNS */ void connectionAuthGetIndexedAttribute(Task appTask, uint16 ps_base, uint16 mru_index, uint16 size_psdata) { TrustedDeviceIndexType tdi; TrustedDeviceRecordType record; { /* Send a message back to the application task */ MAKE_CL_MESSAGE_WITH_LEN(CL_SM_GET_INDEXED_ATTRIBUTE_CFM, size_psdata); message->status = fail; message->size_psdata = size_psdata; message->psdata[0] = 0; /* Read Trusted Device Index from Persistent store */ if ((mru_index < MAX_TRUSTED_DEVICES) && PsRetrieve(TRUSTED_DEVICE_INDEX, &tdi, sizeof(tdi))) { /* Read the device record from the Trusted Device List */ if (tdi.order[mru_index] && PsRetrieve((TRUSTED_DEVICE_LIST_BASE + tdi.order[mru_index] - 1), &record, sizeof(TrustedDeviceRecordType))) { /* Get Bluetooth address of device */ message->bd_addr = record.bd_addr; /* Check if application wants attribute data */ if (size_psdata != 0) { /* Read attribute data */ if(PsRetrieve(ps_base + tdi.order[mru_index]-1, message->psdata, size_psdata)) message->status = success; } else { /* No attribute data required, so just indicate success */ message->status = success; } } } /* Send confirmation back to application */ MessageSend(appTask, CL_SM_GET_INDEXED_ATTRIBUTE_CFM, message); } }
/**************************************************************************** NAME remoteNameComplete DESCRIPTION Send a CL_DM_REMOTE_NAME_COMPLETE message to the client RETURNS void */ static void remoteNameComplete(Task theAppTask, const bdaddr *addr, hci_status status, char* name, uint16 length) { if (theAppTask) { MAKE_CL_MESSAGE_WITH_LEN(CL_DM_REMOTE_NAME_COMPLETE, length); message->status = status; /* Check the address has been set */ if (addr) { message->bd_addr = *addr; } else { BdaddrSetZero(&message->bd_addr); } message->size_remote_name = length; /* Populate remote name fields */ if (length) { memmove(message->remote_name, name, length); } else { message->remote_name[0] = 0; } free(name); /* Send onto Client */ MessageSend(theAppTask, CL_DM_REMOTE_NAME_COMPLETE, message); } else { if (length) free(name); } }
/**************************************************************************** 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); } }
/*****************************************************************************/ #define REF_FLAG 0x8000 /* Pass result as a reference instead of a value */ void ConnectionSdpServiceSearchAttributeRequest(Task appTask, const bdaddr *addr, uint16 max_attributes, uint16 size_search_pattern, const uint8 *search_pattern, uint16 size_attr_list, const uint8 *attr_list) { #ifdef CONNECTION_DEBUG_LIB if (size_search_pattern == 0) CL_DEBUG(("sdp - search pattern not supplied\n")); if (size_attr_list == 0) CL_DEBUG(("sdp - attribute search pattern not supplied\n")); if (max_attributes == 0) CL_DEBUG(("sdp - max number of attribute bytes set to zero\n")); #endif { MAKE_CL_MESSAGE_WITH_LEN( CL_INTERNAL_SDP_SERVICE_SEARCH_ATTRIBUTE_REQ , size_search_pattern + size_attr_list ); /* Get reference flag from max_attributes */ if (max_attributes & REF_FLAG) { message->flags = CONNECTION_FLAG_SDP_REFERENCE; max_attributes &= ~REF_FLAG; } else { message->flags = 0; } message->theAppTask = appTask; message->bd_addr = *addr; message->max_num_attributes = max_attributes; message->size_search_pattern = size_search_pattern; message->size_attribute_list = size_attr_list; memmove(message->search_attr,search_pattern, size_search_pattern ); memmove(message->search_attr + size_search_pattern, attr_list, size_attr_list ); MessageSend(connectionGetCmTask(), CL_INTERNAL_SDP_SERVICE_SEARCH_ATTRIBUTE_REQ, message); } }
/**************************************************************************** NAME connectionHandleSdpServiceSearchCfm DESCRIPTION SDP service search results received so handle them here. RETURNS void */ void connectionHandleSdpServiceSearchCfm(connectionSdpState *state, const SDC_EX_SERVICE_SEARCH_CFM_T *cfm) { if (state->sdpSearchLock == connectionGetCmTask()) { /* Internal CFM means we're SDP Pinging */ uint8* sdp_ptr = (uint8 *) SdpPingServiceRequest; /* Create next request */ MAKE_CL_MESSAGE(CL_INTERNAL_SDP_SERVICE_SEARCH_REQ); message->theAppTask = connectionGetCmTask(); message->bd_addr = state->sdpServerAddr; message->max_responses = 1; message->length = sizeof(SdpPingServiceRequest); message->search_pattern = (uint8*) PanicUnlessMalloc(sizeof(SdpPingServiceRequest)); memcpy(message->search_pattern, sdp_ptr, sizeof(SdpPingServiceRequest)); /* Send after 2 seconds to avoid thrashing the radio */ MessageSendLater(connectionGetCmTask(), CL_INTERNAL_SDP_SERVICE_SEARCH_REQ, message, D_SEC(2)); /* Tidy up memory in cfm */ if (cfm->size_rec_list) { uint8 *record_list = VmGetPointerFromHandle(cfm->rec_list); free(record_list); } /* Free the lock so the next request can be handled */ state->sdpSearchLock = 0; } else if (state->sdpSearchLock) { /* Send a cfm to the client task */ MAKE_CL_MESSAGE_WITH_LEN(CL_SDP_SERVICE_SEARCH_CFM, cfm->size_rec_list); message->status = connectionConvertSdpSearchStatus(cfm->response); message->num_records = cfm->num_recs_ret; message->error_code = cfm->err_code; connectionConvertBdaddr(&message->bd_addr, &cfm->bd_addr); message->size_records = cfm->size_rec_list; if (cfm->size_rec_list) { uint8 *record_list = VmGetPointerFromHandle(cfm->rec_list); memcpy(message->records, record_list, cfm->size_rec_list); free(record_list); } else message->records[0] = 0; MessageSend(state->sdpSearchLock, CL_SDP_SERVICE_SEARCH_CFM, message); /* Reset the resource lock */ state->sdpSearchLock = 0; } else { if (cfm->size_rec_list) { uint8 *record_list = VmGetPointerFromHandle(cfm->rec_list); free(record_list); } } }