コード例 #1
0
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);                    
                }
            }
        }
}
コード例 #2
0
ファイル: dfu_transport_serial.c プロジェクト: tkadom/TWBLE
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);
                }
            }
        }
}
コード例 #3
0
ファイル: dfu_transport_ant.c プロジェクト: IOIOI/nRF51
static void antfs_event_upload_complete_handle(const antfs_event_return_t * p_event)
{
    uint32_t err_code;

    if (m_antfs_dfu_state == ANTFS_DFU_STATE_VALIDATED)
    {
       // only send this response if we have validated the upload
       UNUSED_VARIABLE(antfs_upload_data_resp_transmit(true));
    }
    else if (m_antfs_dfu_state == ANTFS_DFU_STATE_READY)
    {
        if (flash_busy())
        {
            m_antfs_dfu_state = ANTFS_DFU_STATE_FLASH_PENDING;                  //  Image completed but still busy writing, postpone it on flash call back.
            return;
        }

        if (m_image_data_complete == true)
        {
            err_code = dfu_image_validate(m_header_crc_seed);
            if (err_code == NRF_SUCCESS)
            {
                m_antfs_dfu_state = ANTFS_DFU_STATE_VALIDATED;
                UNUSED_VARIABLE(antfs_upload_data_resp_transmit(true));
            }
            else
            {
                upload_data_response_fail_reset();
            }
        }
        else
        {
            UNUSED_VARIABLE(antfs_upload_data_resp_transmit(true));             // This is expected on block transfers.
        }
    }
    else
    {
        // no implementation
    }
}
コード例 #4
0
/**@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;
    }
}
コード例 #5
0
ファイル: dfu_transport_ant.c プロジェクト: IOIOI/nRF51
/*
 * NOTE: This callback is only called by the following
 *  - Storing done operation by dfu_data_pkt_handle
 *  - And all clearing done operation.
 */
static void dfu_cb_handler(uint32_t result, uint8_t * p_data)
{
    uint32_t err_code;
    uint16_t rxd_buffer_len = 0;
    uint16_t ram_crc        = 0;
    uint16_t flash_crc      = 0;

#if defined (DBG_DFU_UART_OUT_PIN)
    DEBUG_UART_OUT(0xFF);
    DEBUG_UART_OUT(m_antfs_dfu_state);
#endif

    switch (m_antfs_dfu_state)
    {
        case ANTFS_DFU_STATE_INIT_DELAYED:
            // This is when upon initialization, a pre-erase operation have occured i.e. bank1 pre clearing.
            services_init();
            break;

        case ANTFS_DFU_STATE_FLASH_ERASE:
            // Handles upload and download request response delay when there is ongoing flash activities
            // Generally we need to avoid flash activities and burst activities to happen at the same time.
            // ANTFS request response are delayed and when flash is done response are handled here.
            if (m_upload_request_in_progress)
            {
                m_upload_request_in_progress    = false;
                // Make sure we got all the latest values.
                m_response_info.file_size.data  = m_current_offset;
                m_response_info.file_crc        = m_current_crc;
                if (result == NRF_SUCCESS)
                {
                    m_upload_swap_space_prepared = true;
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_OK, &m_response_info));
                }
                else
                {
                    /* Not ready */
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_UPLOAD_NOT_READY, &m_response_info));
                }
            }

            if (m_download_request_in_progress)
            {
                m_download_request_in_progress = false;

                UNUSED_VARIABLE(antfs_download_req_resp_prepare(RESPONSE_MESSAGE_OK, &m_response_info));
            }

            m_antfs_dfu_state = ANTFS_DFU_STATE_READY;
            break;


        case ANTFS_DFU_STATE_FLASH_PENDING:
        case ANTFS_DFU_STATE_READY:
            // Handles Flash write call back queued by Upload Data.
            if (result != NRF_SUCCESS)
            {
                upload_data_response_fail_reset();
                return;
            }

            if ((m_mem_pool_1.a_mem_pool <= p_data) && (p_data <= (m_mem_pool_1.a_mem_pool + ANTFS_UPLOAD_DATA_BUFFER_MAX_SIZE)))
            {
                rxd_buffer_len = m_mem_pool_1.size;
                ram_crc = m_mem_pool_1.crc;
                m_mem_pool_1.size = 0;
            }
            else if ((m_mem_pool_2.a_mem_pool <= p_data) && (p_data <= (m_mem_pool_2.a_mem_pool + ANTFS_UPLOAD_DATA_BUFFER_MAX_SIZE)))
            {
                rxd_buffer_len = m_mem_pool_2.size;
                ram_crc = m_mem_pool_2.crc;
                m_mem_pool_2.size = 0;
            }
            else
            {
                upload_data_response_fail_reset();
                return;
            }

            // Verify the data written to flash.
            flash_crc = crc_crc16_update(0, (uint8_t*)(dfu_storage_start_address_get() + m_image_data_offset), rxd_buffer_len);
            if (flash_crc != ram_crc)
            {
                upload_data_response_fail_reset();
                return;
            }

            //update current offsets and crc
            m_current_offset    += rxd_buffer_len;
            m_current_crc       = crc_crc16_update(m_current_crc, (uint8_t*)(dfu_storage_start_address_get() + m_image_data_offset), rxd_buffer_len);

            m_image_data_offset += rxd_buffer_len;

            if (m_antfs_dfu_state == ANTFS_DFU_STATE_FLASH_PENDING)
            {
                m_antfs_dfu_state = ANTFS_DFU_STATE_READY;
                // Update it with the latest values;
                m_response_info.file_size.data            = m_current_offset;
                m_response_info.file_crc                  = m_current_crc;
                if (m_upload_request_in_progress)
                {
                    m_upload_request_in_progress = false;
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_OK, &m_response_info));
                }
                else    // data response
                {
                    if (m_image_data_complete == true)
                    {
                        if (m_image_data_max == m_image_data_offset)
                        {
                            err_code = dfu_image_validate(m_header_crc_seed);
                            if (err_code == NRF_SUCCESS)
                            {
                                UNUSED_VARIABLE(antfs_upload_data_resp_transmit(true));
                                m_antfs_dfu_state = ANTFS_DFU_STATE_VALIDATED;
                                return;
                            }
                            else
                            {
                                upload_data_response_fail_reset();
                            }
                        }

                        if ((m_mem_pool_1.size != 0) || (m_mem_pool_2.size != 0))
                        {
                            m_antfs_dfu_state = ANTFS_DFU_STATE_FLASH_PENDING;
                        }
                    }
                    else //m_image_data_complete == false
                    {
                        if ((m_mem_pool_1.size == 0) && (m_mem_pool_2.size == 0))
                        {
                            UNUSED_VARIABLE(antfs_upload_data_resp_transmit(true));                 // Handles block transfers
                        }
                        else
                        {
                            m_antfs_dfu_state = ANTFS_DFU_STATE_FLASH_PENDING;
                        }
                    }
                }
            }

            break;

        default:
            break;
    }
}
コード例 #6
0
ファイル: dfu_transport_ble.c プロジェクト: 1072258106/duband
/**@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_error_to_dfu_resp_val(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:
            // Final state of DFU is reached.
            m_activate_img_after_tear_down = true;
        
            err_code = dfu_transport_close();
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_DFU_SYS_RESET:
            err_code = dfu_transport_close();
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_DFU_START:
            m_pkt_type = PKT_TYPE_START;
            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;
    }
}