[FL-2578] Updater fixes related to /int handling (#1359)
* Updater fixes related to /int handling updater: performing factory reset on update, checking for LFS free space before updating, fixed improper error handling on backup/restore operations, rebalanced update stage weights for better progress visuals scripts: added CLI output validation for selfupdate.py storage: added pointer validation in storage_int_common_fs_info desktop: fixed crash on rendering invalid slideshows * Typo fix * rpc: Updated protobuf to 0.9 * rpc: removed updater status conversion Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
struct Slideshow {
|
||||
Icon icon;
|
||||
uint32_t current_frame;
|
||||
bool loaded;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
@@ -34,6 +35,7 @@ _Static_assert(sizeof(SlideshowFrameHeader) == 2, "Incorrect SlideshowFrameHeade
|
||||
|
||||
Slideshow* slideshow_alloc() {
|
||||
Slideshow* ret = malloc(sizeof(Slideshow));
|
||||
ret->loaded = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -52,7 +54,7 @@ void slideshow_free(Slideshow* slideshow) {
|
||||
bool slideshow_load(Slideshow* slideshow, const char* fspath) {
|
||||
Storage* storage = furi_record_open("storage");
|
||||
File* slideshow_file = storage_file_alloc(storage);
|
||||
bool load_success = false;
|
||||
slideshow->loaded = false;
|
||||
do {
|
||||
if(!storage_file_open(slideshow_file, fspath, FSAM_READ, FSOM_OPEN_EXISTING)) {
|
||||
break;
|
||||
@@ -80,12 +82,16 @@ bool slideshow_load(Slideshow* slideshow, const char* fspath) {
|
||||
frame_header.size) {
|
||||
break;
|
||||
}
|
||||
load_success = (frame_idx + 1) == header.frame_count;
|
||||
slideshow->loaded = (frame_idx + 1) == header.frame_count;
|
||||
}
|
||||
} while(false);
|
||||
storage_file_free(slideshow_file);
|
||||
furi_record_close("storage");
|
||||
return load_success;
|
||||
return slideshow->loaded;
|
||||
}
|
||||
|
||||
bool slideshow_is_loaded(Slideshow* slideshow) {
|
||||
return slideshow->loaded;
|
||||
}
|
||||
|
||||
bool slideshow_advance(Slideshow* slideshow) {
|
||||
|
@@ -8,6 +8,7 @@ Slideshow* slideshow_alloc();
|
||||
|
||||
void slideshow_free(Slideshow* slideshow);
|
||||
bool slideshow_load(Slideshow* slideshow, const char* fspath);
|
||||
bool slideshow_is_loaded(Slideshow* slideshow);
|
||||
void slideshow_goback(Slideshow* slideshow);
|
||||
bool slideshow_advance(Slideshow* slideshow);
|
||||
void slideshow_draw(Slideshow* slideshow, Canvas* canvas, uint8_t x, uint8_t y);
|
||||
|
@@ -21,7 +21,9 @@ static void desktop_view_slideshow_draw(Canvas* canvas, void* model) {
|
||||
DesktopSlideshowViewModel* m = model;
|
||||
|
||||
canvas_clear(canvas);
|
||||
slideshow_draw(m->slideshow, canvas, 0, 0);
|
||||
if(slideshow_is_loaded(m->slideshow)) {
|
||||
slideshow_draw(m->slideshow, canvas, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static bool desktop_view_slideshow_input(InputEvent* event, void* context) {
|
||||
|
@@ -277,10 +277,6 @@ static void rpc_system_system_update_request_process(const PB_Main* request, voi
|
||||
|
||||
UpdatePrepareResult update_prepare_result =
|
||||
update_operation_prepare(request->content.system_update_request.update_manifest);
|
||||
/* RPC enum does not have such entry; setting to closest one */
|
||||
if(update_prepare_result == UpdatePrepareResultOutdatedManifestVersion) {
|
||||
update_prepare_result = UpdatePrepareResultManifestInvalid;
|
||||
}
|
||||
|
||||
PB_Main* response = malloc(sizeof(PB_Main));
|
||||
response->command_id = request->command_id;
|
||||
|
@@ -655,11 +655,13 @@ static FS_Error storage_int_common_fs_info(
|
||||
lfs_t* lfs = lfs_get_from_storage(storage);
|
||||
LFSData* lfs_data = lfs_data_get_from_storage(storage);
|
||||
|
||||
*total_space = lfs_data->config.block_size * lfs_data->config.block_count;
|
||||
if(total_space) {
|
||||
*total_space = lfs_data->config.block_size * lfs_data->config.block_count;
|
||||
}
|
||||
|
||||
lfs_ssize_t result = lfs_fs_size(lfs);
|
||||
if(result >= 0) {
|
||||
*free_space = *total_space - (result * lfs_data->config.block_size);
|
||||
if(free_space && (result >= 0)) {
|
||||
*free_space = (lfs_data->config.block_count - result) * lfs_data->config.block_size;
|
||||
}
|
||||
|
||||
return storage_int_parse_error(result);
|
||||
|
@@ -44,17 +44,17 @@ static const UpdateTaskStageGroupMap update_task_stage_progress[] = {
|
||||
[UpdateTaskStageReadManifest] = STAGE_DEF(UpdateTaskStageGroupPreUpdate, 5),
|
||||
[UpdateTaskStageLfsBackup] = STAGE_DEF(UpdateTaskStageGroupPreUpdate, 15),
|
||||
|
||||
[UpdateTaskStageRadioImageValidate] = STAGE_DEF(UpdateTaskStageGroupRadio, 10),
|
||||
[UpdateTaskStageRadioErase] = STAGE_DEF(UpdateTaskStageGroupRadio, 50),
|
||||
[UpdateTaskStageRadioWrite] = STAGE_DEF(UpdateTaskStageGroupRadio, 90),
|
||||
[UpdateTaskStageRadioInstall] = STAGE_DEF(UpdateTaskStageGroupRadio, 15),
|
||||
[UpdateTaskStageRadioBusy] = STAGE_DEF(UpdateTaskStageGroupRadio, 60),
|
||||
[UpdateTaskStageRadioImageValidate] = STAGE_DEF(UpdateTaskStageGroupRadio, 15),
|
||||
[UpdateTaskStageRadioErase] = STAGE_DEF(UpdateTaskStageGroupRadio, 60),
|
||||
[UpdateTaskStageRadioWrite] = STAGE_DEF(UpdateTaskStageGroupRadio, 80),
|
||||
[UpdateTaskStageRadioInstall] = STAGE_DEF(UpdateTaskStageGroupRadio, 60),
|
||||
[UpdateTaskStageRadioBusy] = STAGE_DEF(UpdateTaskStageGroupRadio, 80),
|
||||
|
||||
[UpdateTaskStageOBValidation] = STAGE_DEF(UpdateTaskStageGroupOptionBytes, 10),
|
||||
|
||||
[UpdateTaskStageValidateDFUImage] = STAGE_DEF(UpdateTaskStageGroupFirmware, 100),
|
||||
[UpdateTaskStageValidateDFUImage] = STAGE_DEF(UpdateTaskStageGroupFirmware, 50),
|
||||
[UpdateTaskStageFlashWrite] = STAGE_DEF(UpdateTaskStageGroupFirmware, 200),
|
||||
[UpdateTaskStageFlashValidate] = STAGE_DEF(UpdateTaskStageGroupFirmware, 50),
|
||||
[UpdateTaskStageFlashValidate] = STAGE_DEF(UpdateTaskStageGroupFirmware, 30),
|
||||
|
||||
[UpdateTaskStageLfsRestore] = STAGE_DEF(UpdateTaskStageGroupPostUpdate, 30),
|
||||
|
||||
@@ -214,6 +214,7 @@ UpdateTask* update_task_alloc() {
|
||||
update_task->storage = furi_record_open("storage");
|
||||
update_task->file = storage_file_alloc(update_task->storage);
|
||||
update_task->status_change_cb = NULL;
|
||||
update_task->boot_mode = furi_hal_rtc_get_boot_mode();
|
||||
string_init(update_task->update_path);
|
||||
|
||||
FuriThread* thread = update_task->thread = furi_thread_alloc();
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <storage/storage.h>
|
||||
#include <furi_hal.h>
|
||||
|
||||
#define UPDATE_TASK_NOERR 0
|
||||
#define UPDATE_TASK_FAILED -1
|
||||
@@ -14,6 +15,7 @@ typedef struct UpdateTask {
|
||||
File* file;
|
||||
updateProgressCb status_change_cb;
|
||||
void* status_change_cb_state;
|
||||
FuriHalRtcBootMode boot_mode;
|
||||
} UpdateTask;
|
||||
|
||||
void update_task_set_progress(UpdateTask* update_task, UpdateTaskStage stage, uint8_t progress);
|
||||
|
@@ -67,7 +67,6 @@ static bool update_task_post_update(UpdateTask* update_task) {
|
||||
string_get_cstr(update_task->update_path), LFS_BACKUP_DEFAULT_FILENAME, file_path);
|
||||
|
||||
update_task_set_progress(update_task, UpdateTaskStageLfsRestore, 0);
|
||||
update_operation_disarm();
|
||||
|
||||
CHECK_RESULT(lfs_backup_unpack(update_task->storage, string_get_cstr(file_path)));
|
||||
|
||||
@@ -117,28 +116,32 @@ static bool update_task_post_update(UpdateTask* update_task) {
|
||||
int32_t update_task_worker_backup_restore(void* context) {
|
||||
furi_assert(context);
|
||||
UpdateTask* update_task = context;
|
||||
bool success = false;
|
||||
|
||||
FuriHalRtcBootMode boot_mode = furi_hal_rtc_get_boot_mode();
|
||||
FuriHalRtcBootMode boot_mode = update_task->boot_mode;
|
||||
if((boot_mode != FuriHalRtcBootModePreUpdate) && (boot_mode != FuriHalRtcBootModePostUpdate)) {
|
||||
/* no idea how we got here. Clear to normal boot */
|
||||
update_operation_disarm();
|
||||
/* no idea how we got here. Do nothing */
|
||||
return UPDATE_TASK_NOERR;
|
||||
}
|
||||
|
||||
if(!update_task_parse_manifest(update_task)) {
|
||||
return UPDATE_TASK_FAILED;
|
||||
}
|
||||
bool success = false;
|
||||
do {
|
||||
if(!update_task_parse_manifest(update_task)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Waiting for BT service to 'start', so we don't race for boot mode flag */
|
||||
furi_record_open("bt");
|
||||
furi_record_close("bt");
|
||||
/* Waiting for BT service to 'start', so we don't race for boot mode flag */
|
||||
furi_record_open("bt");
|
||||
furi_record_close("bt");
|
||||
|
||||
if(boot_mode == FuriHalRtcBootModePreUpdate) {
|
||||
success = update_task_pre_update(update_task);
|
||||
} else if(boot_mode == FuriHalRtcBootModePostUpdate) {
|
||||
success = update_task_post_update(update_task);
|
||||
}
|
||||
if(boot_mode == FuriHalRtcBootModePreUpdate) {
|
||||
success = update_task_pre_update(update_task);
|
||||
} else if(boot_mode == FuriHalRtcBootModePostUpdate) {
|
||||
success = update_task_post_update(update_task);
|
||||
if(success) {
|
||||
update_operation_disarm();
|
||||
}
|
||||
}
|
||||
} while(false);
|
||||
|
||||
if(!success) {
|
||||
update_task_set_progress(update_task, UpdateTaskStageError, 0);
|
||||
|
@@ -340,6 +340,8 @@ int32_t update_task_worker_flash_writer(void* context) {
|
||||
}
|
||||
|
||||
furi_hal_rtc_set_boot_mode(FuriHalRtcBootModePostUpdate);
|
||||
// Format LFS before restoring backup on next boot
|
||||
furi_hal_rtc_set_flag(FuriHalRtcFlagFactoryReset);
|
||||
|
||||
update_task_set_progress(update_task, UpdateTaskStageCompleted, 100);
|
||||
success = true;
|
||||
|
Reference in New Issue
Block a user