uint32_t hci_transport_rx_pkt_extract(uint8_t ** pp_buffer, uint16_t * p_length) { uint32_t err_code; if (pp_buffer != NULL && p_length != NULL) { uint32_t length = 0; if (m_is_slip_decode_ready) { m_is_slip_decode_ready = false; err_code = hci_mem_pool_rx_extract(pp_buffer, &length); length -= (PKT_HDR_SIZE + PKT_CRC_SIZE); *p_length = (uint16_t)length; *pp_buffer += PKT_HDR_SIZE; } else { err_code = NRF_ERROR_NO_MEM; } } else { err_code = NRF_ERROR_NULL; } return err_code; }
/**@brief Function for processing application data written by the peer to the DFU Packet * Characteristic. * * @param[in] p_dfu DFU Service Structure. * @param[in] p_evt Pointer to the event received from the S110 SoftDevice. */ static void app_data_process(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt) { uint32_t err_code; if ((p_evt->evt.ble_dfu_pkt_write.len & (sizeof(uint32_t) - 1)) != 0) { // Data length is not a multiple of 4 (word size). err_code = ble_dfu_response_send(p_dfu, BLE_DFU_RECEIVE_APP_PROCEDURE, BLE_DFU_RESP_VAL_NOT_SUPPORTED); APP_ERROR_CHECK(err_code); return; } uint32_t length = p_evt->evt.ble_dfu_pkt_write.len; err_code = hci_mem_pool_rx_produce(length, (void**) &mp_rx_buffer); if (err_code != NRF_SUCCESS) { dfu_error_notify(p_dfu, err_code); return; } uint8_t * p_data_packet = p_evt->evt.ble_dfu_pkt_write.p_data; memcpy(mp_rx_buffer, p_data_packet, length); err_code = hci_mem_pool_rx_data_size_set(length); if (err_code != NRF_SUCCESS) { dfu_error_notify(p_dfu, err_code); return; } err_code = hci_mem_pool_rx_extract(&mp_rx_buffer, &length); if (err_code != NRF_SUCCESS) { dfu_error_notify(p_dfu, err_code); return; } dfu_update_packet_t dfu_pkt; dfu_pkt.packet_type = DATA_PACKET; dfu_pkt.params.data_packet.packet_length = length / sizeof(uint32_t); dfu_pkt.params.data_packet.p_data_packet = (uint32_t*)mp_rx_buffer; err_code = dfu_data_pkt_handle(&dfu_pkt); if (err_code == NRF_SUCCESS) { // All the expected firmware data has been received and processed successfully. m_num_of_firmware_bytes_rcvd += p_evt->evt.ble_dfu_pkt_write.len; // Notify the DFU Controller about the success about the procedure. err_code = ble_dfu_response_send(p_dfu, BLE_DFU_RECEIVE_APP_PROCEDURE, BLE_DFU_RESP_VAL_SUCCESS); APP_ERROR_CHECK(err_code); } else if (err_code == NRF_ERROR_INVALID_LENGTH) { // Firmware data packet was handled successfully. And more firmware data is expected. m_num_of_firmware_bytes_rcvd += p_evt->evt.ble_dfu_pkt_write.len; // Check if a packet receipt notification is needed to be sent. if (m_pkt_rcpt_notif_enabled) { // Decrement the counter for the number firmware packets needed for sending the // next packet receipt notification. m_pkt_notif_target_cnt--; if (m_pkt_notif_target_cnt == 0) { err_code = ble_dfu_pkts_rcpt_notify(p_dfu, m_num_of_firmware_bytes_rcvd); APP_ERROR_CHECK(err_code); // Reset the counter for the number of firmware packets. m_pkt_notif_target_cnt = m_pkt_notif_target; } } } else { uint32_t hci_error = hci_mem_pool_rx_consume(mp_rx_buffer); if (hci_error != NRF_SUCCESS) { dfu_error_notify(p_dfu, hci_error); } dfu_error_notify(p_dfu, err_code); } }