static void antfs_event_trans_handle(const antfs_event_return_t * p_event) { if (m_antfs_dfu_state == ANTFS_DFU_STATE_STALL) // Needs restart { dfu_error_notify(NRF_ERROR_INTERNAL, 11); } }
static void antfs_event_link_handle(const antfs_event_return_t * p_event) { uint32_t err_code; if (m_antfs_dfu_state == ANTFS_DFU_STATE_VALIDATED) { // We can stop ANT right here. err_code = sd_ant_stack_reset(); APP_ERROR_CHECK(err_code); err_code = dfu_image_activate(); if (err_code == NRF_SUCCESS) { m_antfs_dfu_state = ANTFS_DFU_STATE_COMPLETED; } else { dfu_error_notify(err_code, 10); } } }
/**@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); } }
/**@brief Function for processing ANTFS upload data event. * * @param[in] p_event The event extracted from the queue to be processed. */ static void antfs_event_upload_data_handle(const antfs_event_return_t * p_event) { static uint8_t * p_rxd_data; static uint32_t rxd_data_size; uint32_t err_code = NRF_SUCCESS; ota_image_header_t * p_ota_image_header; // Allocate a memory pool for upload buffering. if (m_data_buffered == 0) { // Check which pool is empty. if (m_mem_pool_1.size == 0) { mp_buffering_handle = &m_mem_pool_1; } else if (m_mem_pool_2.size == 0) { mp_buffering_handle = &m_mem_pool_2; } else { // something is wrong. dfu_error_notify(err_code, 6); } mp_rx_buffer = &mp_buffering_handle->a_mem_pool[0]; } if ((p_event->bytes + m_data_buffered) < ANTFS_UPLOAD_DATA_BUFFER_MAX_SIZE) { // Copy over the buffer the rx'd 8 byte data memcpy(mp_rx_buffer + m_data_buffered, p_event->data, p_event->bytes); // Advance buffered count m_data_buffered += p_event->bytes; // Advance current over all data count. } else { // something is wrong. dfu_error_notify(err_code, 7); } if ((m_data_buffered >= ANTFS_UPLOAD_DATA_BUFFER_MIN_SIZE) || ((m_pending_offset + m_data_buffered) >= m_current_file_size)) { /* If any of the pool is still pending process and we are running out of space * The ANTFS_UPLOAD_DATA_BUFFER_MIN_SIZE should be enough delay to get the previous buffer be processed, including flashing*/ if (((m_mem_pool_1.size != 0) || (m_mem_pool_2.size != 0)) && ((m_pending_offset + m_data_buffered) < m_current_file_size)) { if (m_data_buffered < ANTFS_UPLOAD_DATA_BUFFER_MAX_SIZE) { // We can wait for a bit. return; } else { // Something is wrong. the device is not flashing. upload_data_response_fail_reset(); return; } } mp_buffering_handle->size = m_data_buffered; // Set the size and consider this pool closed and ready for processing. m_data_buffered = 0; // Reset buffered data count // Decide what to do with the data in the buffer. switch (m_current_file_index) { case ANTFS_FILE_INDEX_UPDATE_STACK: case ANTFS_FILE_INDEX_UPDATE_BOOTLOADER: case ANTFS_FILE_INDEX_UPDATE_APPLICATION: case ANTFS_FILE_INDEX_UPDATE_STACK_BOOTLOADER: // Not in the right state if (m_antfs_dfu_state != ANTFS_DFU_STATE_READY) { // Throw it away. mp_buffering_handle->size = 0; mp_buffering_handle = NULL; upload_data_response_fail_reset(); return; } p_rxd_data = mp_buffering_handle->a_mem_pool; rxd_data_size = mp_buffering_handle->size; // pre calculate pending offset m_pending_offset = m_pending_offset + rxd_data_size; /*********** * Header Section */ if (!m_ota_image_header_parsed) { // Parse the Header if (antfs_ota_image_header_parsing(&p_rxd_data, &rxd_data_size)) { m_ota_image_header_parsed = true; p_ota_image_header = antfs_ota_image_header_get(); } else { return; // Get more } if ((p_ota_image_header == NULL) || // Make sure it is a valid header (p_ota_image_header->architecture_identifier != OTA_IMAGE_ARCH_IDENTIFIER_ST_BL_AP) || // Make sure it is SD BL and AP arch (p_ota_image_header->image_format != OTA_IMAGE_IMAGE_FORMAT_BINARY)) // Make sure it is in Binary format { // Invalid header, fail now. upload_data_response_fail_reset(); return; } // Fill in DFU parameters m_dfu_pkt.params.start_packet.dfu_update_mode = m_update_mode; m_dfu_pkt.params.start_packet.sd_image_size = p_ota_image_header->wireless_stack_size; m_dfu_pkt.params.start_packet.bl_image_size = p_ota_image_header->bootloader_size; m_dfu_pkt.params.start_packet.app_image_size = p_ota_image_header->application_size; m_dfu_pkt.params.start_packet.info_bytes_size = OTA_IMAGE_CRC_SIZE_MAX; err_code = dfu_start_pkt_handle(&m_dfu_pkt); // reinitializing dfu pkt if (err_code) { upload_data_response_fail_reset(); return; } m_image_data_max = p_ota_image_header->wireless_stack_size + p_ota_image_header->bootloader_size + p_ota_image_header->application_size + OTA_IMAGE_CRC_SIZE_MAX; m_header_crc_seed = antfs_ota_image_header_crc_get(); m_current_crc = m_header_crc_seed; m_current_offset = p_ota_image_header->header_size; } /*********** * Image Section */ if (!m_image_data_complete) { m_upload_swap_space_prepared = false; m_dfu_pkt.params.data_packet.p_data_packet = (uint32_t*) p_rxd_data; m_dfu_pkt.params.data_packet.packet_length = rxd_data_size / sizeof(uint32_t); // store flushed information for flash write verification. mp_buffering_handle->size = rxd_data_size; mp_buffering_handle->crc = crc_crc16_update(0, p_rxd_data, rxd_data_size); // Pass the image to dfu. m_dfu_pkt.packet_type = DATA_PACKET; err_code = dfu_data_pkt_handle(&m_dfu_pkt); if (err_code == NRF_SUCCESS) { // All the expected firmware image has been received and processed successfully. m_image_data_complete = true; } else if (err_code == NRF_ERROR_INVALID_LENGTH) { // The image is still partially completed. We need more. //do nothing; } // Unmanaged return code. Something is wrong need to abort. else { //TODO Need to figure out what to do on unmanaged returns. Maybe reset dfu_error_notify(err_code, 9); } } m_antfs_dfu_state = ANTFS_DFU_STATE_READY; break; default: mp_buffering_handle->size = 0; break; } } }