static void process_dfu_packet(void * p_event_data, uint16_t event_size) { uint32_t retval; uint32_t index; dfu_update_packet_t * packet; while (false == DATA_QUEUE_EMPTY()) { // Fetch the element to be processed. for (index = 0; index < MAX_BUFFERS ; index++) { packet = &m_data_queue.data_packet[index]; if (INVALID_PACKET != packet->packet_type) { switch (DATA_QUEUE_ELEMENT_GET_PTYPE(index)) { case DATA_PACKET: (void)dfu_data_pkt_handle(packet); break; case START_PACKET: packet->params.start_packet = (dfu_start_packet_t*)packet->params.data_packet.p_data_packet; retval = dfu_start_pkt_handle(packet); APP_ERROR_CHECK(retval); break; case STOP_DATA_PACKET: (void)dfu_image_validate(); (void)dfu_image_activate(); // Break the loop by returning. return; case INIT_PACKET: // Validate init packet. // We expect to receive the init packet in two rounds of 512 bytes. // If that fails, we abort, and boot the application. // @note: Current release doesn't handle an init packet. break; default: // No implementation needed. break; } // Free the processed element. retval = data_queue_element_free(index); APP_ERROR_CHECK(retval); } } } }
static void process_dfu_packet(void * p_event_data, uint16_t event_size) { uint32_t retval; uint32_t index; dfu_update_packet_t * packet; while (false == DATA_QUEUE_EMPTY()) { // Fetch the element to be processed. for (index = 0; index < MAX_BUFFERS ; index++) { packet = &m_data_queue.data_packet[index]; if (INVALID_PACKET != packet->packet_type) { switch (DATA_QUEUE_ELEMENT_GET_PTYPE(index)) { case DATA_PACKET: (void)dfu_data_pkt_handle(packet); break; case START_PACKET: packet->params.start_packet = (dfu_start_packet_t*)packet->params.data_packet.p_data_packet; retval = dfu_start_pkt_handle(packet); APP_ERROR_CHECK(retval); break; case INIT_PACKET: (void)dfu_init_pkt_handle(packet); retval = dfu_init_pkt_complete(); APP_ERROR_CHECK(retval); break; case STOP_DATA_PACKET: (void)dfu_image_validate(); (void)dfu_image_activate(); // Break the loop by returning. return; default: // No implementation needed. break; } // Free the processed element. retval = data_queue_element_free(index); APP_ERROR_CHECK(retval); } } } }
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 waiting for events. * * @details This function will place the chip in low power mode while waiting for events from * the BLE stack or other peripherals. When interrupted by an event, it will call the @ref * app_sched_execute function to process the received event. This function will return * when the final state of the firmware update is reached OR when a tear down is in * progress. */ static void wait_for_events(void) { for (;;) { // Wait in low power state for any events. uint32_t err_code = sd_app_event_wait(); APP_ERROR_CHECK(err_code); // Event received. Process it from the scheduler. app_sched_execute(); if (m_tear_down_in_progress) { // Wait until disconnected event is received. Once the disconnected event is received // from the stack, the macro IS_CONNECTED will return false. if (!IS_CONNECTED()) { err_code = sd_softdevice_disable(); APP_ERROR_CHECK(err_code); if (m_activate_img_after_tear_down) { // Start the currently valid application. (void)dfu_image_activate(); // Ignoring the error code returned by dfu_image_activate because if the // function fails, there is nothing that can be done to recover, other than // returning and letting the system go under reset. Also since the // tear down of the BLE Transport is already complete and the connection // with the DFU Controller is down. Hence the DFU Controller cannot be informed // about this failure. It is assumed that the DFU Controller is already // aware of a failed update procedure from errors returned by earlier // operations (eg. Validate operation would have returned a failure if there // was a failed image transfer). } return; } } } }
/**@brief Function for the Device Firmware Update Service event handler. * * @details This function will be called for all Device Firmware Update Service events which * are passed to the application. * * @param[in] p_dfu Device Firmware Update Service structure. * @param[in] p_evt Event received from the Device Firmware Update Service. */ static void on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt) { uint32_t err_code; switch (p_evt->ble_dfu_evt_type) { case BLE_DFU_VALIDATE: err_code = dfu_image_validate(); // Translate the err_code returned by the above function to DFU Response Value. ble_dfu_resp_val_t resp_val; resp_val = nrf_err_code_translate(err_code, BLE_DFU_VALIDATE_PROCEDURE); err_code = ble_dfu_response_send(p_dfu, BLE_DFU_VALIDATE_PROCEDURE, resp_val); APP_ERROR_CHECK(err_code); break; case BLE_DFU_ACTIVATE_N_RESET: err_code = dfu_transport_close(); APP_ERROR_CHECK(err_code); // With the S110 Flash API it is safe to initiate the activate before connection is // fully closed. err_code = dfu_image_activate(); if (err_code != NRF_SUCCESS) { dfu_reset(); } break; case BLE_DFU_SYS_RESET: err_code = dfu_transport_close(); APP_ERROR_CHECK(err_code); dfu_reset(); break; case BLE_DFU_START: m_pkt_type = PKT_TYPE_START; if (p_evt->evt.ble_dfu_pkt_write.len == 0) { m_update_mode = DFU_UPDATE_APP; } else { m_update_mode = (uint8_t)p_evt->evt.ble_dfu_pkt_write.p_data[0]; } break; case BLE_DFU_RECEIVE_INIT_DATA: m_pkt_type = PKT_TYPE_INIT; break; case BLE_DFU_RECEIVE_APP_DATA: m_pkt_type = PKT_TYPE_FIRMWARE_DATA; break; case BLE_DFU_PACKET_WRITE: on_dfu_pkt_write(p_dfu, p_evt); break; case BLE_DFU_PKT_RCPT_NOTIF_ENABLED: m_pkt_rcpt_notif_enabled = true; m_pkt_notif_target = p_evt->evt.pkt_rcpt_notif_req.num_of_pkts; m_pkt_notif_target_cnt = p_evt->evt.pkt_rcpt_notif_req.num_of_pkts; break; case BLE_DFU_PKT_RCPT_NOTIF_DISABLED: m_pkt_rcpt_notif_enabled = false; m_pkt_notif_target = 0; break; case BLE_DFU_BYTES_RECEIVED_SEND: err_code = ble_dfu_bytes_rcvd_report(p_dfu, m_num_of_firmware_bytes_rcvd); APP_ERROR_CHECK(err_code); break; default: // Unsupported event received from DFU Service. Ignore. break; } }