Пример #1
0
// File callback to be used with vfs_add_file to return file contents
static uint32_t read_file_fail_txt(uint32_t sector_offset, uint8_t* data, uint32_t num_sectors)
{
    const char* contents = (const char*)error_get_string(fail_reason);
    uint32_t size = strlen(contents);
    if (sector_offset != 0) {
        return 0;
    }
    memcpy(data, contents, size);
    return size;
}
Пример #2
0
// Check if the current transfer is still in progress, done, or if an error has occurred
static void transfer_update_state(error_t status)
{
    bool transfer_timeout;
    bool transfer_started;
    bool transfer_can_be_finished;
    bool transfer_must_be_finished;
    bool out_of_order_sector;
    error_t local_status = status;
    util_assert((status != ERROR_SUCCESS_DONE) &&
                (status != ERROR_SUCCESS_DONE_OR_CONTINUE));

    if (TRASNFER_FINISHED == file_transfer_state.transfer_state) {
        util_assert(0);
        return;
    }

    // Update file info status.  The end of a file is never known for sure since
    // what looks like a complete file could be part of a file getting flushed to disk.
    // The criteria for an successful optional finish is
    // 1. A file has been detected
    // 2. The size of the file indicated in the root dir has been transferred
    // 3. The file size is greater than zero
    file_transfer_state.file_info_optional_finish =
        (file_transfer_state.file_to_program != VFS_FILE_INVALID) &&
        (file_transfer_state.size_transferred >= file_transfer_state.file_size) &&
        (file_transfer_state.file_size > 0);
    transfer_timeout = file_transfer_state.transfer_timeout;
    transfer_started = (VFS_FILE_INVALID != file_transfer_state.file_to_program) ||
                       (STREAM_TYPE_NONE != file_transfer_state.stream);
    // The transfer can be finished if both file and stream processing
    // can be considered complete
    transfer_can_be_finished = file_transfer_state.file_info_optional_finish &&
                               file_transfer_state.stream_optional_finish;
    // The transfer must be fnished if stream processing is for sure complete
    // and file processing can be considered complete
    transfer_must_be_finished = file_transfer_state.stream_finished &&
                                file_transfer_state.file_info_optional_finish;
    out_of_order_sector = false;

    if (file_transfer_state.last_ooo_sector != VFS_INVALID_SECTOR) {
        util_assert(file_transfer_state.start_sector != VFS_INVALID_SECTOR);
        uint32_t sector_offset = (file_transfer_state.last_ooo_sector -
                                  file_transfer_state.start_sector) * VFS_SECTOR_SIZE;

        if (sector_offset < file_transfer_state.size_processed) {
            // The out of order sector was within the range of data already
            // processed.
            out_of_order_sector = true;
        }
    }

    // Set the transfer state and set the status if necessary
    if (local_status != ERROR_SUCCESS) {
        file_transfer_state.transfer_state = TRASNFER_FINISHED;
    } else if (transfer_timeout) {
        if (out_of_order_sector) {
            local_status = ERROR_OOO_SECTOR;
        } else if (!transfer_started) {
            local_status = ERROR_SUCCESS;
        } else if (transfer_can_be_finished) {
            local_status = ERROR_SUCCESS;
        } else {
            local_status = ERROR_TRANSFER_TIMEOUT;
        }

        file_transfer_state.transfer_state = TRASNFER_FINISHED;
    } else if (transfer_must_be_finished) {
        file_transfer_state.transfer_state = TRASNFER_FINISHED;
    } else if (transfer_can_be_finished) {
        file_transfer_state.transfer_state = TRANSFER_CAN_BE_FINISHED;
    } else if (transfer_started) {
        file_transfer_state.transfer_state = TRANSFER_IN_PROGRESS;
    }

    if (TRASNFER_FINISHED == file_transfer_state.transfer_state) {
        vfs_mngr_printf("vfs_manager transfer_update_state(status=%i)\r\n", status);
        vfs_mngr_printf("    file=%p, start_sect= %i, size=%i\r\n",
                        file_transfer_state.file_to_program, file_transfer_state.start_sector,
                        file_transfer_state.file_size);
        vfs_mngr_printf("    stream=%i, size_processed=%i, opt_finish=%i, timeout=%i\r\n",
                        file_transfer_state.stream, file_transfer_state.size_processed,
                        file_transfer_state.file_info_optional_finish, transfer_timeout);

        // Close the file stream if it is open
        if (file_transfer_state.stream_open) {
            error_t close_status;
            close_status = stream_close();
            vfs_mngr_printf("    stream closed ret=%i\r\n", close_status);
            file_transfer_state.stream_open = false;

            if (ERROR_SUCCESS == local_status) {
                local_status = close_status;
            }
        }

        // Set the fail reason
        fail_reason = local_status;
        vfs_mngr_printf("    Transfer finished, status: %i=%s\r\n", fail_reason, error_get_string(fail_reason));
    }

    // If this state change is not from aborting a transfer
    // due to a remount then trigger a remount
    if (!transfer_timeout) {
        vfs_mngr_fs_remount();
    }
}