Ejemplo n.º 1
0
/*
 * 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;
    }
}
Ejemplo n.º 2
0
/**@brief Function for processing ANTFS upload request data event.
 *
 * @param[in] p_event The event extracted from the queue to be processed.
 */
static void antfs_event_upload_request_handle(const antfs_event_return_t * p_event)
{
    uint32_t    err_code = RESPONSE_MESSAGE_OK;
    uint8_t     new_request = false;

    if ((m_antfs_dfu_state == ANTFS_DFU_STATE_FLASH_ERASE) || (m_antfs_dfu_state == ANTFS_DFU_STATE_FLASH_PENDING))
    {
        return;
    }

    /*reset*/
    m_response_info.file_index.data           = p_event->file_index;
    m_response_info.max_burst_block_size.data = 0;
    m_response_info.max_file_size             = 0;
    m_response_info.file_size.data            = 0;
    m_response_info.file_crc                  = 0;

    // Evaluate File Index first
    if (m_current_file_index != p_event->file_index )
    {
        m_current_file_index = p_event->file_index;
        m_current_offset                        = 0;
        m_current_crc                           = 0;
    }

    if (p_event->offset == MAX_ULONG)
    {
        // This is a request to continue upload.
    }
    else if (p_event->offset == 0x00)
    {
        new_request = true;
    }
    else if(p_event->offset != m_current_offset)
    {
        // Something is wrong.
        UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_INVALID_OPERATION, &m_response_info));
        m_antfs_dfu_state = ANTFS_DFU_STATE_STALL;
    }
    else
    {
        // no implementation.
    }

    switch (m_current_file_index)
    {
#if !defined (S210_V3_STACK)
        case ANTFS_FILE_INDEX_UPDATE_STACK:
        case ANTFS_FILE_INDEX_UPDATE_BOOTLOADER:
        case ANTFS_FILE_INDEX_UPDATE_STACK_BOOTLOADER:
#endif // S210_V3_STACK
        case ANTFS_FILE_INDEX_UPDATE_APPLICATION:
        {
            // Current valid file size is the last offset written to the file.
            m_response_info.file_size.data            = m_current_offset;
            // Intentionally report maximum allowed upload file size as max writeable file size + header and crc.
            // Writeable size check will be performed by dfu_start_pkt_handle() after parsing uploaded header
            m_response_info.max_file_size             = ANTFS_FILE_SIZE_MAX_DFU_IMAGE + OTA_IMAGE_HEADER_SIZE_MAX;
            // Maximum burst block should be maximum allowable downloadable file size.
            m_response_info.max_burst_block_size.data = ANTFS_FILE_SIZE_MAX_DFU_IMAGE + OTA_IMAGE_HEADER_SIZE_MAX;
            // Last valid CRC.
            m_response_info.file_crc                  = m_current_crc;

            // Will only handle upload request while at ANTFS_DFU_STATE_READY
            if (m_antfs_dfu_state == ANTFS_DFU_STATE_VALIDATED)
            {
                if (new_request)
                {
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_NOT_AVAILABLE, &m_response_info));
                }
                else
                {
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_OK, &m_response_info));                 // To handle resume at end of data.
                }
                return;
            }
            else if (m_antfs_dfu_state != ANTFS_DFU_STATE_READY)
            {
                UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_NOT_AVAILABLE, &m_response_info));
                return;
            }

            // Check File Size if it can still fit. Uploaded file size may be larger than the total writeable space because it includes header
            // and CRC that do not get written to flash. Writeable size check will be performed by dfu_start_pk_handle() after
            // parsing uploaded header
            if ((p_event->offset + p_event->bytes) > (ANTFS_FILE_SIZE_MAX_DFU_IMAGE + OTA_IMAGE_HEADER_SIZE_MAX + OTA_IMAGE_CRC_SIZE_MAX))
            {
                UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_NOT_ENOUGH_SPACE, &m_response_info));
                return;
            }

            m_data_buffered         = 0;

            if (new_request)
            {
                m_current_offset    = 0;
                m_current_crc       = 0;
                m_pending_offset    = 0;

                antfs_ota_init();

                // Only supports offset starting at 0;
                if (p_event->offset != 0)
                {
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_FAIL, &m_response_info));
                    return;
                }

//                boot_return_set(PARAM_RETURN_BOOT_STATUS_Entered);

                // Store file size,
                m_current_file_size     = p_event->bytes;

                if (m_current_file_index == ANTFS_FILE_INDEX_UPDATE_STACK)
                {
                    m_update_mode = DFU_UPDATE_SD;
                }
                else if (m_current_file_index == ANTFS_FILE_INDEX_UPDATE_BOOTLOADER)
                {
                    m_update_mode = DFU_UPDATE_BL;
                }
                else if (m_current_file_index == ANTFS_FILE_INDEX_UPDATE_APPLICATION)
                {
                    m_update_mode = DFU_UPDATE_APP;
                }
                else if (m_current_file_index == ANTFS_FILE_INDEX_UPDATE_STACK_BOOTLOADER)
                {
                    m_update_mode = DFU_UPDATE_SD;
                    m_update_mode |= DFU_UPDATE_BL;//lint !e655 suppress Lint Warning 655: Bit-wise operations
                }

                m_dfu_pkt.packet_type = INIT_PACKET;

                if ((*ANT_BOOT_APP_SIZE > DFU_IMAGE_MAX_SIZE_BANKED)    ||
                    (*ANT_BOOT_APP_SIZE == 0xFFFFFFFF)                  ||
                    (*ANT_BOOT_APP_SIZE == 0x00000000)                  ||
                    (m_update_mode & DFU_UPDATE_SD))/*lint !e655 suppress Lint Warning 655: Bit-wise operations*/
                {
                    m_dfu_pkt.params.init_packet.total_image_size = DFU_IMAGE_MAX_SIZE_FULL;
                }
                else
                {
                    m_dfu_pkt.params.init_packet.total_image_size = m_current_file_size;
                }

                if (m_upload_swap_space_prepared == true)
                {
                    // Prepare no flash, except the states
                    m_dfu_pkt.params.init_packet.total_image_size = 0;
                }

                err_code = dfu_init_pkt_handle(&m_dfu_pkt);
                if (err_code)
                {
                    if (err_code == NRF_ERROR_INVALID_STATE)
                    {
                        UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_INVALID_OPERATION, &m_response_info));
                    }
                    else
                    {
                        UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_FAIL, &m_response_info));
                    }
                    return;
                }

                m_ota_image_header_parsed   = false;
                m_image_data_complete       = false;
                m_image_data_offset         = 0;

                m_data_buffered             = 0;

                // A flash erase is expected at this time. postpone response if there is.
                if (flash_busy())
                {
                    m_upload_request_in_progress = true;
                    m_antfs_dfu_state = ANTFS_DFU_STATE_FLASH_ERASE;
                    return;
                }
            }
            else
            {
                // Check if there are still pending writes scheduled in Flash.
                if (flash_busy())
                {
                    m_upload_request_in_progress = true;
                    m_antfs_dfu_state = ANTFS_DFU_STATE_FLASH_PENDING;
                    return;
                }
            }

            m_antfs_dfu_state = ANTFS_DFU_STATE_READY;
            UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_OK, &m_response_info));
        }
            break;
        default:
            m_antfs_dfu_state = ANTFS_DFU_STATE_READY;
            UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_NOT_EXIST, &m_response_info));
    }
}
Ejemplo n.º 3
0
/**@brief Function for processing ANTFS upload request data event.
 * 
 * @param[in] p_event The event extracted from the queue to be processed.
 */
static void event_upload_request_handle(const antfs_event_return_t * p_event)
{
    uint8_t response = RESPONSE_MESSAGE_OK;   

    if ((p_event->offset == MAX_ULONG))  
    {
        // Requesting to resume an upload.
        
        if (m_file_index != p_event->file_index)
        {
            // We do not have a save point for this file.
            m_file_offset = 0;
            m_current_crc = 0;
        }
    }
    else    
    {
        // This is a new upload.
        
        // Use requested offset and reset CRC.
        m_file_offset = p_event->offset;    
        m_current_crc = 0;                  
    }

    m_file_index = p_event->file_index;   

    // Read file information from directory.            
    if (mem_file_info_get(m_file_index, &m_temp_dir_structure))  
    {             
        // Check permissions.
        if (!(m_temp_dir_structure.general_flags & ANTFS_DIR_WRITE_MASK))    
        {
            response = RESPONSE_MESSAGE_NOT_AVAILABLE;
            printf("Upload request denied: file n/a for writing\n");
        }

        // Set response parameters.
        m_response_info.file_index.data           = m_file_index;   
        // Current valid file size is the last offset written to the file.
        m_response_info.file_size.data            = m_file_offset;   
        // Space available for writing is the file size, as specified on directory.
        m_response_info.max_file_size             = m_temp_dir_structure.file_size_in_bytes;          
        // Get the entire file in a single burst if possible.
        m_response_info.max_burst_block_size.data = m_temp_dir_structure.file_size_in_bytes;  
        // Last valid CRC.
        m_response_info.file_crc                  = m_current_crc;      
    }
    else    
    {
        // Index not found.
        
        response                                  = RESPONSE_MESSAGE_NOT_EXIST;  
        m_response_info.file_index.data           = m_file_index;
        m_response_info.file_size.data            = 0;   
        m_response_info.max_file_size             = 0;
        m_response_info.max_burst_block_size.data = 0;
        m_response_info.file_crc                  = 0;
        printf("Upload request denied: file does not exist\n");
    }

    m_upload_success = true;
    
    // @note: Suppress return value as no use case for handling it exists.
    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(response, &m_response_info));
}