/**@brief Function for freeing an element. * * @param[in] element_index index of the element. */ static uint32_t data_queue_element_free(uint8_t element_index) { uint8_t * p_data; uint32_t retval; retval = NRF_ERROR_INVALID_PARAM; if (MAX_BUFFERS > element_index) { p_data = (uint8_t *)DATA_QUEUE_ELEMENT_GET_PDATA(element_index); if (INVALID_PACKET != DATA_QUEUE_ELEMENT_GET_PTYPE(element_index)) { m_data_queue.count--; data_queue_element_init (element_index); retval = hci_transport_rx_pkt_consume((p_data - 4)); APP_ERROR_CHECK(retval); } } else { return NRF_ERROR_INVALID_PARAM; } return NRF_SUCCESS; }
uint32_t sd_ble_gap_address_set(ble_gap_addr_t const * const p_addr) { uint32_t index = 0; g_cmd_buffer[index++] = BLE_RPC_PKT_CMD; g_cmd_buffer[index++] = SD_BLE_GAP_ADDRESS_SET; if (p_addr != NULL) { g_cmd_buffer[index++] = RPC_BLE_FIELD_PRESENT; g_cmd_buffer[index++] = p_addr->addr_type; memcpy(&g_cmd_buffer[index], p_addr->addr, BLE_GAP_ADDR_LEN); index += BLE_GAP_ADDR_LEN; } else { g_cmd_buffer[index++] = RPC_BLE_FIELD_NOT_PRESENT; } uint32_t err_code = hci_transport_pkt_write(g_cmd_buffer, index); if (err_code != NRF_SUCCESS) { return err_code; } err_code = ble_rpc_cmd_resp_wait(SD_BLE_GAP_ADDRESS_SET); UNUSED_VARIABLE(hci_transport_rx_pkt_consume(g_cmd_response_buf)); return err_code; }
uint32_t sd_ble_gap_appearance_get(uint16_t * const p_appearance) { uint32_t index = 0; g_cmd_buffer[index++] = BLE_RPC_PKT_CMD; g_cmd_buffer[index++] = SD_BLE_GAP_APPEARANCE_GET; if (p_appearance != NULL) { g_cmd_buffer[index++] = RPC_BLE_FIELD_PRESENT; } else { g_cmd_buffer[index++] = RPC_BLE_FIELD_NOT_PRESENT; } uint32_t err_code = hci_transport_pkt_write(g_cmd_buffer, index); if (err_code != NRF_SUCCESS) { return err_code; } err_code = ble_rpc_cmd_resp_wait(SD_BLE_GAP_APPEARANCE_GET); if (p_appearance != NULL) { *p_appearance = uint16_decode(&(g_cmd_response_buf[BLE_OP_CODE_SIZE + BLE_PKT_TYPE_SIZE + RPC_ERR_CODE_SIZE])); } UNUSED_VARIABLE(hci_transport_rx_pkt_consume(g_cmd_response_buf)); return err_code; }
uint32_t sd_ble_gap_adv_data_set(uint8_t const * const p_data, uint8_t dlen, uint8_t const * const p_sr_data, uint8_t srdlen) { uint32_t i; uint32_t index = 0; g_cmd_buffer[index++] = BLE_RPC_PKT_CMD; g_cmd_buffer[index++] = SD_BLE_GAP_ADV_DATA_SET; g_cmd_buffer[index++] = dlen; for (i = 0; i < dlen; i++) { g_cmd_buffer[index++] = p_data[i]; } g_cmd_buffer[index++] = srdlen; for (i = 0; i < srdlen; i++) { g_cmd_buffer[index++] = p_sr_data[i]; } uint32_t err_code = hci_transport_pkt_write(g_cmd_buffer, index); if (err_code != NRF_SUCCESS) { return err_code; } err_code = ble_rpc_cmd_resp_wait(SD_BLE_GAP_ADV_DATA_SET); UNUSED_VARIABLE(hci_transport_rx_pkt_consume(g_cmd_response_buf)); return err_code; }
uint32_t sd_ble_gap_ppcp_get(ble_gap_conn_params_t * const p_conn_params) { uint32_t err_code; uint32_t index = 0; g_cmd_buffer[index++] = BLE_RPC_PKT_CMD; g_cmd_buffer[index++] = SD_BLE_GAP_PPCP_GET; if (p_conn_params != NULL) { g_cmd_buffer[index++] = RPC_BLE_FIELD_PRESENT; } else { g_cmd_buffer[index++] = RPC_BLE_FIELD_NOT_PRESENT; } err_code = hci_transport_pkt_write(g_cmd_buffer, index); if (err_code != NRF_SUCCESS) { return err_code; } err_code = ble_rpc_cmd_resp_wait(SD_BLE_GAP_PPCP_GET); if (p_conn_params != NULL) { memcpy(p_conn_params, &(g_cmd_response_buf[BLE_OP_CODE_SIZE + BLE_PKT_TYPE_SIZE + RPC_ERR_CODE_SIZE]), sizeof(*p_conn_params)); } UNUSED_VARIABLE(hci_transport_rx_pkt_consume(g_cmd_response_buf)); return err_code; }
uint32_t sd_ble_gap_ppcp_set(ble_gap_conn_params_t const * const p_conn_params) { uint32_t index = 0; g_cmd_buffer[index++] = BLE_RPC_PKT_CMD; g_cmd_buffer[index++] = SD_BLE_GAP_PPCP_SET; if (p_conn_params != NULL) { g_cmd_buffer[index++] = RPC_BLE_FIELD_PRESENT; index += uint16_encode(p_conn_params->min_conn_interval, &g_cmd_buffer[index]); index += uint16_encode(p_conn_params->max_conn_interval, &g_cmd_buffer[index]); index += uint16_encode(p_conn_params->slave_latency , &g_cmd_buffer[index]); index += uint16_encode(p_conn_params->conn_sup_timeout, &g_cmd_buffer[index]); } else { g_cmd_buffer[index++] = RPC_BLE_FIELD_NOT_PRESENT; } uint32_t err_code = hci_transport_pkt_write(g_cmd_buffer, index); if (err_code != NRF_SUCCESS) { return err_code; } err_code = ble_rpc_cmd_resp_wait(SD_BLE_GAP_PPCP_SET); UNUSED_VARIABLE(hci_transport_rx_pkt_consume(g_cmd_response_buf)); return err_code; }
void rpc_transport_event_handler(hci_transport_evt_t event) { uint32_t retval; uint16_t rpc_cmd_length_read; uint8_t * p_rpc_cmd_buffer; uint8_t element_index; retval = hci_transport_rx_pkt_extract(&p_rpc_cmd_buffer, &rpc_cmd_length_read); if (NRF_SUCCESS == retval) { // Verify if the data queue can buffer the packet. retval = data_queue_element_alloc(&element_index, p_rpc_cmd_buffer[0]); if (NRF_SUCCESS == retval) { //subtract 1 since we are interested in payload length and not the type field. DATA_QUEUE_ELEMENT_SET_PLEN(element_index,(rpc_cmd_length_read / sizeof(uint32_t)) - 1); DATA_QUEUE_ELEMENT_COPY_PDATA(element_index, &p_rpc_cmd_buffer[4]); retval = app_sched_event_put(NULL, 0, process_dfu_packet); } } if (NRF_SUCCESS != retval) { // Free the packet that could not be processed. retval = hci_transport_rx_pkt_consume(p_rpc_cmd_buffer); APP_ERROR_CHECK(retval); } }
void ble_rpc_cmd_handle(void * p_event_data, uint16_t event_size) { uint32_t err_code; uint32_t rpc_cmd_length_read; uint8_t * p_rpc_cmd_buffer; err_code = hci_transport_rx_pkt_extract(&p_rpc_cmd_buffer, &rpc_cmd_length_read); APP_ERROR_CHECK(err_code); err_code = command_process(&p_rpc_cmd_buffer[RPC_CMD_RESP_OP_CODE_POS], rpc_cmd_length_read); APP_ERROR_CHECK(err_code); err_code = hci_transport_rx_pkt_consume(p_rpc_cmd_buffer); APP_ERROR_CHECK(err_code); }
uint32_t sd_ble_gap_device_name_get(uint8_t * const p_dev_name, uint16_t * const p_len) { uint32_t index = 0; g_cmd_buffer[index++] = BLE_RPC_PKT_CMD; g_cmd_buffer[index++] = SD_BLE_GAP_DEVICE_NAME_GET; if (p_len != NULL) { g_cmd_buffer[index++] = RPC_BLE_FIELD_PRESENT; index += uint16_encode(*p_len, &g_cmd_buffer[index]); } else { g_cmd_buffer[index++] = RPC_BLE_FIELD_NOT_PRESENT; } g_cmd_buffer[index++] = (p_dev_name != NULL) ? RPC_BLE_FIELD_PRESENT : RPC_BLE_FIELD_NOT_PRESENT; uint32_t err_code = hci_transport_pkt_write(g_cmd_buffer, index); if (err_code != NRF_SUCCESS) { return err_code; } err_code = ble_rpc_cmd_resp_wait(SD_BLE_GAP_DEVICE_NAME_GET); if (p_len != NULL) { *p_len = uint16_decode(&(g_cmd_response_buf[BLE_OP_CODE_SIZE + BLE_PKT_TYPE_SIZE + RPC_ERR_CODE_SIZE])); if (p_dev_name != NULL) { memcpy(p_dev_name, &(g_cmd_response_buf[BLE_OP_CODE_SIZE + BLE_PKT_TYPE_SIZE + RPC_ERR_CODE_SIZE + sizeof(*p_len)]), *p_len); } } UNUSED_VARIABLE(hci_transport_rx_pkt_consume(g_cmd_response_buf)); return err_code; }
uint32_t sd_ble_gap_adv_stop(void) { uint32_t index = 0; g_cmd_buffer[index++] = BLE_RPC_PKT_CMD; g_cmd_buffer[index++] = SD_BLE_GAP_ADV_STOP; uint32_t err_code = hci_transport_pkt_write(g_cmd_buffer, index); if (err_code != NRF_SUCCESS) { return err_code; } err_code = ble_rpc_cmd_resp_wait(SD_BLE_GAP_ADV_STOP); UNUSED_VARIABLE(hci_transport_rx_pkt_consume(g_cmd_response_buf)); return err_code; }
uint32_t sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const * const p_write_perm, uint8_t const * const p_dev_name, uint16_t len) { uint32_t i; uint32_t index = 0; g_cmd_buffer[index++] = BLE_RPC_PKT_CMD; g_cmd_buffer[index++] = SD_BLE_GAP_DEVICE_NAME_SET; if (p_write_perm != NULL) { g_cmd_buffer[index++] = RPC_BLE_FIELD_PRESENT; g_cmd_buffer[index++] = (uint8_t) ((p_write_perm->sm) | (p_write_perm->lv << 4)); } else { g_cmd_buffer[index++] = RPC_BLE_FIELD_NOT_PRESENT; } index += uint16_encode(len, &g_cmd_buffer[index]); if (p_dev_name != NULL) { g_cmd_buffer[index++] = RPC_BLE_FIELD_PRESENT; for (i = 0; i < len; i++) { g_cmd_buffer[index++] = p_dev_name[i]; } } else { g_cmd_buffer[index++] = RPC_BLE_FIELD_NOT_PRESENT; } uint32_t err_code = hci_transport_pkt_write(g_cmd_buffer, index); if (err_code != NRF_SUCCESS) { return err_code; } err_code = ble_rpc_cmd_resp_wait(SD_BLE_GAP_DEVICE_NAME_SET); UNUSED_VARIABLE(hci_transport_rx_pkt_consume(g_cmd_response_buf)); return err_code; }
uint32_t sd_ble_gap_appearance_set(uint16_t appearance) { uint32_t index = 0; g_cmd_buffer[index++] = BLE_RPC_PKT_CMD; g_cmd_buffer[index++] = SD_BLE_GAP_APPEARANCE_SET; index += uint16_encode(appearance, &g_cmd_buffer[index]); uint32_t err_code = hci_transport_pkt_write(g_cmd_buffer, index); if (err_code != NRF_SUCCESS) { return err_code; } err_code = ble_rpc_cmd_resp_wait(SD_BLE_GAP_APPEARANCE_SET); UNUSED_VARIABLE(hci_transport_rx_pkt_consume(g_cmd_response_buf)); return err_code; }
uint32_t ble_rpc_event_pkt_received(uint8_t * p_event_packet, uint16_t event_packet_length) { if (m_packet_queue[m_packet_queue_write_index].p_packet != NULL) { UNUSED_VARIABLE(hci_transport_rx_pkt_consume(p_event_packet)); return NRF_ERROR_NO_MEM; } m_packet_queue[m_packet_queue_write_index].p_packet = p_event_packet; m_packet_queue[m_packet_queue_write_index].packet_length = event_packet_length; if (++m_packet_queue_write_index >= EVENT_QUEUE_SIZE) { m_packet_queue_write_index = 0; } return NRF_SUCCESS; }
uint32_t sd_ble_gap_sec_info_reply(uint16_t conn_handle, ble_gap_enc_info_t const * const p_enc_info, ble_gap_sign_info_t const * const p_sign_info) { uint32_t index = 0; g_cmd_buffer[index++] = BLE_RPC_PKT_CMD; g_cmd_buffer[index++] = SD_BLE_GAP_SEC_INFO_REPLY; index += uint16_encode(conn_handle, &g_cmd_buffer[index]); if (p_enc_info != NULL) { g_cmd_buffer[index++] = RPC_BLE_FIELD_PRESENT; index += uint16_encode(p_enc_info->div, &g_cmd_buffer[index]); memcpy(&g_cmd_buffer[index], p_enc_info->ltk, BLE_GAP_SEC_KEY_LEN); index += BLE_GAP_SEC_KEY_LEN; g_cmd_buffer[index++] = (p_enc_info->auth | (p_enc_info->ltk_len << 1)); } else { g_cmd_buffer[index++] = RPC_BLE_FIELD_NOT_PRESENT; } if (p_sign_info != NULL) { g_cmd_buffer[index++] = RPC_BLE_FIELD_PRESENT; memcpy(&g_cmd_buffer[index], p_sign_info->csrk, BLE_GAP_SEC_KEY_LEN); index += BLE_GAP_SEC_KEY_LEN; } else { g_cmd_buffer[index++] = RPC_BLE_FIELD_NOT_PRESENT; } uint32_t err_code = hci_transport_pkt_write(g_cmd_buffer, index); if (err_code != NRF_SUCCESS) { return err_code; } err_code = ble_rpc_cmd_resp_wait(SD_BLE_GAP_SEC_INFO_REPLY); UNUSED_VARIABLE(hci_transport_rx_pkt_consume(g_cmd_response_buf)); return err_code; }
uint32_t sd_ble_gap_adv_start(ble_gap_adv_params_t const * const p_adv_params) { uint32_t index = 0; g_cmd_buffer[index++] = BLE_RPC_PKT_CMD; g_cmd_buffer[index++] = SD_BLE_GAP_ADV_START; g_cmd_buffer[index++] = p_adv_params->type; if (p_adv_params->p_peer_addr == NULL) { g_cmd_buffer[index++] = RPC_BLE_FIELD_NOT_PRESENT; } else { g_cmd_buffer[index++] = RPC_BLE_FIELD_PRESENT; index += peer_address_encode(&g_cmd_buffer[index], p_adv_params->p_peer_addr); } g_cmd_buffer[index++] = p_adv_params->fp; if (p_adv_params->p_whitelist == NULL) { g_cmd_buffer[index++] = RPC_BLE_FIELD_NOT_PRESENT; } else { g_cmd_buffer[index++] = RPC_BLE_FIELD_PRESENT; index += whitelist_encode(&g_cmd_buffer[index], p_adv_params->p_whitelist); } index += uint16_encode(p_adv_params->interval, &g_cmd_buffer[index]); index += uint16_encode(p_adv_params->timeout, &g_cmd_buffer[index]); uint32_t err_code = hci_transport_pkt_write(g_cmd_buffer, index); if (err_code != NRF_SUCCESS) { return err_code; } err_code = ble_rpc_cmd_resp_wait(SD_BLE_GAP_ADV_START); UNUSED_VARIABLE(hci_transport_rx_pkt_consume(g_cmd_response_buf)); return err_code; }
uint32_t sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code) { uint32_t index = 0; g_cmd_buffer[index++] = BLE_RPC_PKT_CMD; g_cmd_buffer[index++] = SD_BLE_GAP_DISCONNECT; index += uint16_encode(conn_handle, &g_cmd_buffer[index]); g_cmd_buffer[index++] = hci_status_code; uint32_t err_code = hci_transport_pkt_write(g_cmd_buffer, index); if (err_code != NRF_SUCCESS) { return err_code; } err_code = ble_rpc_cmd_resp_wait(SD_BLE_GAP_DISCONNECT); UNUSED_VARIABLE(hci_transport_rx_pkt_consume(g_cmd_response_buf)); return err_code; }
uint32_t sd_ble_gap_sec_params_reply(uint16_t conn_handle, uint8_t sec_status, ble_gap_sec_params_t const * const p_sec_params) { uint32_t index = 0; g_cmd_buffer[index++] = BLE_RPC_PKT_CMD; g_cmd_buffer[index++] = SD_BLE_GAP_SEC_PARAMS_REPLY; index += uint16_encode(conn_handle, &g_cmd_buffer[index]); g_cmd_buffer[index++] = sec_status; if (p_sec_params != NULL) { g_cmd_buffer[index++] = RPC_BLE_FIELD_PRESENT; index += uint16_encode(p_sec_params->timeout, &g_cmd_buffer[index]); g_cmd_buffer[index++] = ( (p_sec_params->oob << 5) | (p_sec_params->io_caps << 2) | (p_sec_params->mitm << 1) | (p_sec_params->bond << 0) ); g_cmd_buffer[index++] = p_sec_params->min_key_size; g_cmd_buffer[index++] = p_sec_params->max_key_size; } else { g_cmd_buffer[index++] = RPC_BLE_FIELD_NOT_PRESENT; } uint32_t err_code = hci_transport_pkt_write(g_cmd_buffer, index); if (err_code != NRF_SUCCESS) { return err_code; } err_code = ble_rpc_cmd_resp_wait(SD_BLE_GAP_SEC_PARAMS_REPLY); UNUSED_VARIABLE(hci_transport_rx_pkt_consume(g_cmd_response_buf)); return err_code; }
uint32_t sd_ble_evt_get(uint8_t * p_dest, uint16_t * p_len) { ble_evt_t * p_ble_evt = (ble_evt_t *)p_dest; uint16_t evt_length; uint8_t pop_index; uint8_t * p_packet; uint16_t packet_length; if (p_len == NULL) { return NRF_ERROR_INVALID_ADDR; } // Check pointer alignment. if (!IS_ALIGNED((uint32_t) p_dest, BLE_EVTS_PTR_ALIGNMENT)) { return NRF_ERROR_INVALID_ADDR; } pop_index = m_packet_queue_read_index; p_packet = m_packet_queue[pop_index].p_packet; packet_length = m_packet_queue[pop_index].packet_length; // Check if there is any event received. if (p_packet == NULL) { // No event received. *p_len = 0; return NRF_ERROR_NOT_FOUND; } if (p_packet[0] != BLE_RPC_PKT_EVT) { // No event received. *p_len = 0; return NRF_ERROR_NOT_FOUND; } evt_length_decode(&evt_length, p_packet, packet_length); if (evt_length == 0) { // Unsupported/Invalid event received - put packet pointer to NULL. UNUSED_VARIABLE(hci_transport_rx_pkt_consume(p_packet)); m_packet_queue[pop_index].p_packet = NULL; if (++m_packet_queue_read_index >= EVENT_QUEUE_SIZE) { m_packet_queue_read_index = 0; } *p_len = 0; return NRF_ERROR_NOT_FOUND; } uint16_t ble_evt_len = evt_length + sizeof(ble_evt_hdr_t); // Check that the provided buffer is large enough. if ((p_dest != NULL) && (*p_len < ble_evt_len)) { // Not enough memory provided to fit the event. *p_len = 0; return NRF_ERROR_DATA_SIZE; } // Set the calculated length of the event as output. *p_len = ble_evt_len; if (p_dest != NULL) { // Decode the encoded event data. p_ble_evt->header.evt_len = evt_length; evt_packet_decode(p_ble_evt, p_packet, packet_length); // Clear the encoded packet to invalidate it. UNUSED_VARIABLE(hci_transport_rx_pkt_consume(p_packet)); m_packet_queue[pop_index].p_packet = NULL; if (++m_packet_queue_read_index >= EVENT_QUEUE_SIZE) { m_packet_queue_read_index = 0; } } return NRF_SUCCESS; }
uint32_t sd_ble_uuid_encode(ble_uuid_t const * const p_uuid, uint8_t * const p_uuid_le_len, uint8_t * const p_uuid_le) { uint32_t err_code; uint32_t index = 0; g_cmd_buffer[index++] = BLE_RPC_PKT_CMD; g_cmd_buffer[index++] = SD_BLE_UUID_ENCODE; if (p_uuid != NULL) { g_cmd_buffer[index++] = RPC_BLE_FIELD_PRESENT; index += uint16_encode(p_uuid->uuid, &g_cmd_buffer[index]); g_cmd_buffer[index++] = p_uuid->type; } else { g_cmd_buffer[index++] = RPC_BLE_FIELD_NOT_PRESENT; } if (p_uuid_le_len != NULL) { g_cmd_buffer[index++] = RPC_BLE_FIELD_PRESENT; } else { g_cmd_buffer[index++] = RPC_BLE_FIELD_NOT_PRESENT; } if (p_uuid_le != NULL) { g_cmd_buffer[index++] = RPC_BLE_FIELD_PRESENT; } else { g_cmd_buffer[index++] = RPC_BLE_FIELD_NOT_PRESENT; } err_code = hci_transport_pkt_write(g_cmd_buffer, index); if (err_code != NRF_SUCCESS) { return err_code; } err_code = ble_rpc_cmd_resp_wait(SD_BLE_UUID_ENCODE); if (p_uuid_le_len != NULL) { *p_uuid_le_len = g_cmd_response_buf[BLE_OP_CODE_SIZE + BLE_PKT_TYPE_SIZE + RPC_ERR_CODE_SIZE]; } if ((p_uuid_le != NULL) && (p_uuid_le_len != NULL)) { memcpy(p_uuid_le, &(g_cmd_response_buf[BLE_OP_CODE_SIZE + BLE_PKT_TYPE_SIZE + RPC_ERR_CODE_SIZE + sizeof(*p_uuid_le_len)]), *p_uuid_le_len); } UNUSED_VARIABLE(hci_transport_rx_pkt_consume(g_cmd_response_buf)); return err_code; }