[FL-3377] Update error code descriptions (#2875)
* updater: added update error code descriptions * updater: separate ram/flash messages * updater: extra pre-update checks * updater: fixed string comparison * updater: Additional logging Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									af64ae0e40
								
							
						
					
					
						commit
						f2324e4d1c
					
				@ -19,7 +19,7 @@ static const char* update_task_stage_descr[] = {
 | 
				
			|||||||
    [UpdateTaskStageRadioErase] = "Uninstalling radio FW",
 | 
					    [UpdateTaskStageRadioErase] = "Uninstalling radio FW",
 | 
				
			||||||
    [UpdateTaskStageRadioWrite] = "Writing radio FW",
 | 
					    [UpdateTaskStageRadioWrite] = "Writing radio FW",
 | 
				
			||||||
    [UpdateTaskStageRadioInstall] = "Installing radio FW",
 | 
					    [UpdateTaskStageRadioInstall] = "Installing radio FW",
 | 
				
			||||||
    [UpdateTaskStageRadioBusy] = "Radio is updating",
 | 
					    [UpdateTaskStageRadioBusy] = "Core 2 busy",
 | 
				
			||||||
    [UpdateTaskStageOBValidation] = "Validating opt. bytes",
 | 
					    [UpdateTaskStageOBValidation] = "Validating opt. bytes",
 | 
				
			||||||
    [UpdateTaskStageLfsBackup] = "Backing up LFS",
 | 
					    [UpdateTaskStageLfsBackup] = "Backing up LFS",
 | 
				
			||||||
    [UpdateTaskStageLfsRestore] = "Restoring LFS",
 | 
					    [UpdateTaskStageLfsRestore] = "Restoring LFS",
 | 
				
			||||||
@ -30,6 +30,191 @@ static const char* update_task_stage_descr[] = {
 | 
				
			|||||||
    [UpdateTaskStageOBError] = "OB, report",
 | 
					    [UpdateTaskStageOBError] = "OB, report",
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct {
 | 
				
			||||||
 | 
					    UpdateTaskStage stage;
 | 
				
			||||||
 | 
					    uint8_t percent_min, percent_max;
 | 
				
			||||||
 | 
					    const char* descr;
 | 
				
			||||||
 | 
					} update_task_error_detail[] = {
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageReadManifest,
 | 
				
			||||||
 | 
					        .percent_min = 0,
 | 
				
			||||||
 | 
					        .percent_max = 13,
 | 
				
			||||||
 | 
					        .descr = "Wrong Updater HW",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageReadManifest,
 | 
				
			||||||
 | 
					        .percent_min = 14,
 | 
				
			||||||
 | 
					        .percent_max = 20,
 | 
				
			||||||
 | 
					        .descr = "Manifest pointer error",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageReadManifest,
 | 
				
			||||||
 | 
					        .percent_min = 21,
 | 
				
			||||||
 | 
					        .percent_max = 30,
 | 
				
			||||||
 | 
					        .descr = "Manifest load error",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageReadManifest,
 | 
				
			||||||
 | 
					        .percent_min = 31,
 | 
				
			||||||
 | 
					        .percent_max = 40,
 | 
				
			||||||
 | 
					        .descr = "Wrong package version",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageReadManifest,
 | 
				
			||||||
 | 
					        .percent_min = 41,
 | 
				
			||||||
 | 
					        .percent_max = 50,
 | 
				
			||||||
 | 
					        .descr = "HW Target mismatch",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageReadManifest,
 | 
				
			||||||
 | 
					        .percent_min = 51,
 | 
				
			||||||
 | 
					        .percent_max = 60,
 | 
				
			||||||
 | 
					        .descr = "No DFU file",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageReadManifest,
 | 
				
			||||||
 | 
					        .percent_min = 61,
 | 
				
			||||||
 | 
					        .percent_max = 80,
 | 
				
			||||||
 | 
					        .descr = "No Radio file",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					#ifndef FURI_RAM_EXEC
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageLfsBackup,
 | 
				
			||||||
 | 
					        .percent_min = 0,
 | 
				
			||||||
 | 
					        .percent_max = 100,
 | 
				
			||||||
 | 
					        .descr = "FS R/W error",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageRadioImageValidate,
 | 
				
			||||||
 | 
					        .percent_min = 0,
 | 
				
			||||||
 | 
					        .percent_max = 98,
 | 
				
			||||||
 | 
					        .descr = "FS Read error",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageRadioImageValidate,
 | 
				
			||||||
 | 
					        .percent_min = 99,
 | 
				
			||||||
 | 
					        .percent_max = 100,
 | 
				
			||||||
 | 
					        .descr = "CRC mismatch",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageRadioErase,
 | 
				
			||||||
 | 
					        .percent_min = 0,
 | 
				
			||||||
 | 
					        .percent_max = 30,
 | 
				
			||||||
 | 
					        .descr = "Stack remove: cmd error",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageRadioErase,
 | 
				
			||||||
 | 
					        .percent_min = 31,
 | 
				
			||||||
 | 
					        .percent_max = 100,
 | 
				
			||||||
 | 
					        .descr = "Stack remove: wait failed",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageRadioWrite,
 | 
				
			||||||
 | 
					        .percent_min = 0,
 | 
				
			||||||
 | 
					        .percent_max = 100,
 | 
				
			||||||
 | 
					        .descr = "Stack write: error",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageRadioInstall,
 | 
				
			||||||
 | 
					        .percent_min = 0,
 | 
				
			||||||
 | 
					        .percent_max = 10,
 | 
				
			||||||
 | 
					        .descr = "Stack install: cmd error",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageRadioInstall,
 | 
				
			||||||
 | 
					        .percent_min = 11,
 | 
				
			||||||
 | 
					        .percent_max = 100,
 | 
				
			||||||
 | 
					        .descr = "Stack install: wait failed",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageRadioBusy,
 | 
				
			||||||
 | 
					        .percent_min = 0,
 | 
				
			||||||
 | 
					        .percent_max = 10,
 | 
				
			||||||
 | 
					        .descr = "Failed to start C2",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageRadioBusy,
 | 
				
			||||||
 | 
					        .percent_min = 11,
 | 
				
			||||||
 | 
					        .percent_max = 20,
 | 
				
			||||||
 | 
					        .descr = "C2 FUS swich failed",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageRadioBusy,
 | 
				
			||||||
 | 
					        .percent_min = 21,
 | 
				
			||||||
 | 
					        .percent_max = 30,
 | 
				
			||||||
 | 
					        .descr = "FUS operation failed",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageRadioBusy,
 | 
				
			||||||
 | 
					        .percent_min = 31,
 | 
				
			||||||
 | 
					        .percent_max = 100,
 | 
				
			||||||
 | 
					        .descr = "C2 Stach switch failed",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageOBValidation,
 | 
				
			||||||
 | 
					        .percent_min = 0,
 | 
				
			||||||
 | 
					        .percent_max = 100,
 | 
				
			||||||
 | 
					        .descr = "Uncorr. value mismatch",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageValidateDFUImage,
 | 
				
			||||||
 | 
					        .percent_min = 0,
 | 
				
			||||||
 | 
					        .percent_max = 1,
 | 
				
			||||||
 | 
					        .descr = "Failed to open DFU file",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageValidateDFUImage,
 | 
				
			||||||
 | 
					        .percent_min = 1,
 | 
				
			||||||
 | 
					        .percent_max = 97,
 | 
				
			||||||
 | 
					        .descr = "DFU file read error",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageValidateDFUImage,
 | 
				
			||||||
 | 
					        .percent_min = 98,
 | 
				
			||||||
 | 
					        .percent_max = 100,
 | 
				
			||||||
 | 
					        .descr = "DFU file CRC mismatch",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageFlashWrite,
 | 
				
			||||||
 | 
					        .percent_min = 0,
 | 
				
			||||||
 | 
					        .percent_max = 100,
 | 
				
			||||||
 | 
					        .descr = "Flash write error",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageFlashValidate,
 | 
				
			||||||
 | 
					        .percent_min = 0,
 | 
				
			||||||
 | 
					        .percent_max = 100,
 | 
				
			||||||
 | 
					        .descr = "Flash compare error",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef FURI_RAM_EXEC
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageLfsRestore,
 | 
				
			||||||
 | 
					        .percent_min = 0,
 | 
				
			||||||
 | 
					        .percent_max = 100,
 | 
				
			||||||
 | 
					        .descr = "LFS I/O error",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        .stage = UpdateTaskStageResourcesUpdate,
 | 
				
			||||||
 | 
					        .percent_min = 0,
 | 
				
			||||||
 | 
					        .percent_max = 100,
 | 
				
			||||||
 | 
					        .descr = "SD card I/O error",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char* update_task_get_error_message(UpdateTaskStage stage, uint8_t percent) {
 | 
				
			||||||
 | 
					    for(size_t i = 0; i < COUNT_OF(update_task_error_detail); i++) {
 | 
				
			||||||
 | 
					        if(update_task_error_detail[i].stage == stage &&
 | 
				
			||||||
 | 
					           percent >= update_task_error_detail[i].percent_min &&
 | 
				
			||||||
 | 
					           percent <= update_task_error_detail[i].percent_max) {
 | 
				
			||||||
 | 
					            return update_task_error_detail[i].descr;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return "Unknown error";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
    UpdateTaskStageGroup group;
 | 
					    UpdateTaskStageGroup group;
 | 
				
			||||||
    uint8_t weight;
 | 
					    uint8_t weight;
 | 
				
			||||||
@ -111,8 +296,9 @@ void update_task_set_progress(UpdateTask* update_task, UpdateTaskStage stage, ui
 | 
				
			|||||||
        if(stage >= UpdateTaskStageError) {
 | 
					        if(stage >= UpdateTaskStageError) {
 | 
				
			||||||
            furi_string_printf(
 | 
					            furi_string_printf(
 | 
				
			||||||
                update_task->state.status,
 | 
					                update_task->state.status,
 | 
				
			||||||
                "%s #[%d-%d]",
 | 
					                "%s\n#[%d-%d]",
 | 
				
			||||||
                update_task_stage_descr[stage],
 | 
					                update_task_get_error_message(
 | 
				
			||||||
 | 
					                    update_task->state.stage, update_task->state.stage_progress),
 | 
				
			||||||
                update_task->state.stage,
 | 
					                update_task->state.stage,
 | 
				
			||||||
                update_task->state.stage_progress);
 | 
					                update_task->state.stage_progress);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
 | 
				
			|||||||
@ -24,3 +24,8 @@ bool update_task_open_file(UpdateTask* update_task, FuriString* filename);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int32_t update_task_worker_flash_writer(void* context);
 | 
					int32_t update_task_worker_flash_writer(void* context);
 | 
				
			||||||
int32_t update_task_worker_backup_restore(void* context);
 | 
					int32_t update_task_worker_backup_restore(void* context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CHECK_RESULT(x) \
 | 
				
			||||||
 | 
					    if(!(x)) {          \
 | 
				
			||||||
 | 
					        break;          \
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -15,11 +15,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define TAG "UpdWorkerBackup"
 | 
					#define TAG "UpdWorkerBackup"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CHECK_RESULT(x) \
 | 
					 | 
				
			||||||
    if(!(x)) {          \
 | 
					 | 
				
			||||||
        break;          \
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool update_task_pre_update(UpdateTask* update_task) {
 | 
					static bool update_task_pre_update(UpdateTask* update_task) {
 | 
				
			||||||
    bool success = false;
 | 
					    bool success = false;
 | 
				
			||||||
    FuriString* backup_file_path;
 | 
					    FuriString* backup_file_path;
 | 
				
			||||||
 | 
				
			|||||||
@ -13,11 +13,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define TAG "UpdWorkerRAM"
 | 
					#define TAG "UpdWorkerRAM"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CHECK_RESULT(x) \
 | 
					 | 
				
			||||||
    if(!(x)) {          \
 | 
					 | 
				
			||||||
        break;          \
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define STM_DFU_VENDOR_ID 0x0483
 | 
					#define STM_DFU_VENDOR_ID 0x0483
 | 
				
			||||||
#define STM_DFU_PRODUCT_ID 0xDF11
 | 
					#define STM_DFU_PRODUCT_ID 0xDF11
 | 
				
			||||||
/* Written into DFU file by build pipeline */
 | 
					/* Written into DFU file by build pipeline */
 | 
				
			||||||
@ -137,7 +132,7 @@ static bool update_task_write_stack_data(UpdateTask* update_task) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void update_task_wait_for_restart(UpdateTask* update_task) {
 | 
					static void update_task_wait_for_restart(UpdateTask* update_task) {
 | 
				
			||||||
    update_task_set_progress(update_task, UpdateTaskStageRadioBusy, 10);
 | 
					    update_task_set_progress(update_task, UpdateTaskStageRadioBusy, 70);
 | 
				
			||||||
    furi_delay_ms(C2_MODE_SWITCH_TIMEOUT);
 | 
					    furi_delay_ms(C2_MODE_SWITCH_TIMEOUT);
 | 
				
			||||||
    furi_crash("C2 timeout");
 | 
					    furi_crash("C2 timeout");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -153,12 +148,12 @@ static bool update_task_write_stack(UpdateTask* update_task) {
 | 
				
			|||||||
            manifest->radio_crc);
 | 
					            manifest->radio_crc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        CHECK_RESULT(update_task_write_stack_data(update_task));
 | 
					        CHECK_RESULT(update_task_write_stack_data(update_task));
 | 
				
			||||||
        update_task_set_progress(update_task, UpdateTaskStageRadioInstall, 0);
 | 
					        update_task_set_progress(update_task, UpdateTaskStageRadioInstall, 10);
 | 
				
			||||||
        CHECK_RESULT(
 | 
					        CHECK_RESULT(
 | 
				
			||||||
            ble_glue_fus_stack_install(manifest->radio_address, 0) != BleGlueCommandResultError);
 | 
					            ble_glue_fus_stack_install(manifest->radio_address, 0) != BleGlueCommandResultError);
 | 
				
			||||||
        update_task_set_progress(update_task, UpdateTaskStageRadioInstall, 80);
 | 
					        update_task_set_progress(update_task, UpdateTaskStageProgress, 80);
 | 
				
			||||||
        CHECK_RESULT(ble_glue_fus_wait_operation() == BleGlueCommandResultOK);
 | 
					        CHECK_RESULT(ble_glue_fus_wait_operation() == BleGlueCommandResultOK);
 | 
				
			||||||
        update_task_set_progress(update_task, UpdateTaskStageRadioInstall, 100);
 | 
					        update_task_set_progress(update_task, UpdateTaskStageProgress, 100);
 | 
				
			||||||
        /* ...system will restart here. */
 | 
					        /* ...system will restart here. */
 | 
				
			||||||
        update_task_wait_for_restart(update_task);
 | 
					        update_task_wait_for_restart(update_task);
 | 
				
			||||||
    } while(false);
 | 
					    } while(false);
 | 
				
			||||||
@ -170,9 +165,9 @@ static bool update_task_remove_stack(UpdateTask* update_task) {
 | 
				
			|||||||
        FURI_LOG_W(TAG, "Removing stack");
 | 
					        FURI_LOG_W(TAG, "Removing stack");
 | 
				
			||||||
        update_task_set_progress(update_task, UpdateTaskStageRadioErase, 30);
 | 
					        update_task_set_progress(update_task, UpdateTaskStageRadioErase, 30);
 | 
				
			||||||
        CHECK_RESULT(ble_glue_fus_stack_delete() != BleGlueCommandResultError);
 | 
					        CHECK_RESULT(ble_glue_fus_stack_delete() != BleGlueCommandResultError);
 | 
				
			||||||
        update_task_set_progress(update_task, UpdateTaskStageRadioErase, 80);
 | 
					        update_task_set_progress(update_task, UpdateTaskStageProgress, 80);
 | 
				
			||||||
        CHECK_RESULT(ble_glue_fus_wait_operation() == BleGlueCommandResultOK);
 | 
					        CHECK_RESULT(ble_glue_fus_wait_operation() == BleGlueCommandResultOK);
 | 
				
			||||||
        update_task_set_progress(update_task, UpdateTaskStageRadioErase, 100);
 | 
					        update_task_set_progress(update_task, UpdateTaskStageProgress, 100);
 | 
				
			||||||
        /* ...system will restart here. */
 | 
					        /* ...system will restart here. */
 | 
				
			||||||
        update_task_wait_for_restart(update_task);
 | 
					        update_task_wait_for_restart(update_task);
 | 
				
			||||||
    } while(false);
 | 
					    } while(false);
 | 
				
			||||||
@ -180,6 +175,7 @@ static bool update_task_remove_stack(UpdateTask* update_task) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool update_task_manage_radiostack(UpdateTask* update_task) {
 | 
					static bool update_task_manage_radiostack(UpdateTask* update_task) {
 | 
				
			||||||
 | 
					    update_task_set_progress(update_task, UpdateTaskStageRadioBusy, 10);
 | 
				
			||||||
    bool success = false;
 | 
					    bool success = false;
 | 
				
			||||||
    do {
 | 
					    do {
 | 
				
			||||||
        CHECK_RESULT(ble_glue_wait_for_c2_start(FURI_HAL_BT_C2_START_TIMEOUT));
 | 
					        CHECK_RESULT(ble_glue_wait_for_c2_start(FURI_HAL_BT_C2_START_TIMEOUT));
 | 
				
			||||||
@ -208,15 +204,17 @@ static bool update_task_manage_radiostack(UpdateTask* update_task) {
 | 
				
			|||||||
                /* Version or type mismatch. Let's boot to FUS and start updating. */
 | 
					                /* Version or type mismatch. Let's boot to FUS and start updating. */
 | 
				
			||||||
                FURI_LOG_W(TAG, "Restarting to FUS");
 | 
					                FURI_LOG_W(TAG, "Restarting to FUS");
 | 
				
			||||||
                furi_hal_rtc_set_flag(FuriHalRtcFlagC2Update);
 | 
					                furi_hal_rtc_set_flag(FuriHalRtcFlagC2Update);
 | 
				
			||||||
 | 
					                update_task_set_progress(update_task, UpdateTaskStageProgress, 20);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                CHECK_RESULT(furi_hal_bt_ensure_c2_mode(BleGlueC2ModeFUS));
 | 
					                CHECK_RESULT(furi_hal_bt_ensure_c2_mode(BleGlueC2ModeFUS));
 | 
				
			||||||
                /* ...system will restart here. */
 | 
					                /* ...system will restart here. */
 | 
				
			||||||
                update_task_wait_for_restart(update_task);
 | 
					                update_task_wait_for_restart(update_task);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else if(c2_state->mode == BleGlueC2ModeFUS) {
 | 
					        } else if(c2_state->mode == BleGlueC2ModeFUS) {
 | 
				
			||||||
            /* OK, we're in FUS mode. */
 | 
					            /* OK, we're in FUS mode. */
 | 
				
			||||||
            update_task_set_progress(update_task, UpdateTaskStageRadioBusy, 10);
 | 
					 | 
				
			||||||
            FURI_LOG_W(TAG, "Waiting for FUS to settle");
 | 
					            FURI_LOG_W(TAG, "Waiting for FUS to settle");
 | 
				
			||||||
            ble_glue_fus_wait_operation();
 | 
					            update_task_set_progress(update_task, UpdateTaskStageProgress, 30);
 | 
				
			||||||
 | 
					            CHECK_RESULT(ble_glue_fus_wait_operation() == BleGlueCommandResultOK);
 | 
				
			||||||
            if(stack_version_match) {
 | 
					            if(stack_version_match) {
 | 
				
			||||||
                /* We can't check StackType with FUS, but partial version matches */
 | 
					                /* We can't check StackType with FUS, but partial version matches */
 | 
				
			||||||
                if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagC2Update)) {
 | 
					                if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagC2Update)) {
 | 
				
			||||||
@ -230,7 +228,7 @@ static bool update_task_manage_radiostack(UpdateTask* update_task) {
 | 
				
			|||||||
                    /* We might just had the stack installed.
 | 
					                    /* We might just had the stack installed.
 | 
				
			||||||
                     * Let's start it up to check its version */
 | 
					                     * Let's start it up to check its version */
 | 
				
			||||||
                    FURI_LOG_W(TAG, "Starting stack to check full version");
 | 
					                    FURI_LOG_W(TAG, "Starting stack to check full version");
 | 
				
			||||||
                    update_task_set_progress(update_task, UpdateTaskStageRadioBusy, 40);
 | 
					                    update_task_set_progress(update_task, UpdateTaskStageProgress, 50);
 | 
				
			||||||
                    CHECK_RESULT(furi_hal_bt_ensure_c2_mode(BleGlueC2ModeStack));
 | 
					                    CHECK_RESULT(furi_hal_bt_ensure_c2_mode(BleGlueC2ModeStack));
 | 
				
			||||||
                    /* ...system will restart here. */
 | 
					                    /* ...system will restart here. */
 | 
				
			||||||
                    update_task_wait_for_restart(update_task);
 | 
					                    update_task_wait_for_restart(update_task);
 | 
				
			||||||
 | 
				
			|||||||
@ -81,16 +81,17 @@ static void updater_main_draw_callback(Canvas* canvas, void* _model) {
 | 
				
			|||||||
    canvas_set_font(canvas, FontPrimary);
 | 
					    canvas_set_font(canvas, FontPrimary);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(model->failed) {
 | 
					    if(model->failed) {
 | 
				
			||||||
        canvas_draw_str_aligned(canvas, 42, 16, AlignLeft, AlignTop, "Update Failed!");
 | 
					        canvas_draw_icon(canvas, 2, 22, &I_Warning_30x23);
 | 
				
			||||||
 | 
					        canvas_draw_str_aligned(canvas, 40, 9, AlignLeft, AlignTop, "Update Failed!");
 | 
				
			||||||
        canvas_set_font(canvas, FontSecondary);
 | 
					        canvas_set_font(canvas, FontSecondary);
 | 
				
			||||||
        canvas_draw_str_aligned(
 | 
					 | 
				
			||||||
            canvas, 42, 32, AlignLeft, AlignTop, furi_string_get_cstr(model->status));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        canvas_draw_icon(canvas, 7, 16, &I_Warning_30x23);
 | 
					        elements_multiline_text_aligned(
 | 
				
			||||||
 | 
					            canvas, 75, 26, AlignCenter, AlignTop, furi_string_get_cstr(model->status));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        canvas_draw_str_aligned(
 | 
					        canvas_draw_str_aligned(
 | 
				
			||||||
            canvas, 18, 51, AlignLeft, AlignTop, "to retry, hold       to abort");
 | 
					            canvas, 18, 55, AlignLeft, AlignTop, "to retry, hold       to abort");
 | 
				
			||||||
        canvas_draw_icon(canvas, 7, 50, &I_Ok_btn_9x9);
 | 
					        canvas_draw_icon(canvas, 7, 54, &I_Ok_btn_9x9);
 | 
				
			||||||
        canvas_draw_icon(canvas, 75, 51, &I_Pin_back_arrow_10x8);
 | 
					        canvas_draw_icon(canvas, 75, 55, &I_Pin_back_arrow_10x8);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        canvas_draw_str_aligned(canvas, 55, 14, AlignLeft, AlignTop, "UPDATING");
 | 
					        canvas_draw_str_aligned(canvas, 55, 14, AlignLeft, AlignTop, "UPDATING");
 | 
				
			||||||
        canvas_set_font(canvas, FontSecondary);
 | 
					        canvas_set_font(canvas, FontSecondary);
 | 
				
			||||||
 | 
				
			|||||||
@ -87,9 +87,12 @@ Even if something goes wrong, updater allows you to retry failed operations and
 | 
				
			|||||||
|  Uninstalling radio FW  |  **4** | **0**      | SHCI Delete command error                  |
 | 
					|  Uninstalling radio FW  |  **4** | **0**      | SHCI Delete command error                  |
 | 
				
			||||||
|                         |        | **80**     | Error awaiting command status              |
 | 
					|                         |        | **80**     | Error awaiting command status              |
 | 
				
			||||||
|    Writing radio FW     |  **5** | **0-100**  | Block read/write error                     |
 | 
					|    Writing radio FW     |  **5** | **0-100**  | Block read/write error                     |
 | 
				
			||||||
|   Installing radio FW   |  **6** | **0**      | SHCI Install command error                 |
 | 
					|   Installing radio FW   |  **6** | **10**     | SHCI Install command error                 |
 | 
				
			||||||
|                         |        | **80**     | Error awaiting command status              |
 | 
					|                         |        | **80**     | Error awaiting command status              |
 | 
				
			||||||
|    Radio is updating    |  **7** | **10**     | Error waiting for operation completion     |
 | 
					|      Core2 is busy      |  **7** | **10**     | Couldn't start C2                          |
 | 
				
			||||||
 | 
					|                         |        | **20**     | Failed to switch C2 to FUS mode            |
 | 
				
			||||||
 | 
					|                         |        | **30**     | Error in FUS operation                     |
 | 
				
			||||||
 | 
					|                         |        | **50**     | Failed to switch C2 to stack mode          |
 | 
				
			||||||
|  Validating opt. bytes  |  **8** | **yy**     | Option byte code                           |
 | 
					|  Validating opt. bytes  |  **8** | **yy**     | Option byte code                           |
 | 
				
			||||||
|    Checking DFU file    |  **9** | **0**      | Error opening DFU file                     |
 | 
					|    Checking DFU file    |  **9** | **0**      | Error opening DFU file                     |
 | 
				
			||||||
|                         |        | **1-98**   | Error reading DFU file                     |
 | 
					|                         |        | **1-98**   | Error reading DFU file                     |
 | 
				
			||||||
 | 
				
			|||||||
@ -20,7 +20,8 @@ static const char* update_prepare_result_descr[] = {
 | 
				
			|||||||
    [UpdatePrepareResultManifestInvalid] = "Invalid manifest data",
 | 
					    [UpdatePrepareResultManifestInvalid] = "Invalid manifest data",
 | 
				
			||||||
    [UpdatePrepareResultStageMissing] = "Missing Stage2 loader",
 | 
					    [UpdatePrepareResultStageMissing] = "Missing Stage2 loader",
 | 
				
			||||||
    [UpdatePrepareResultStageIntegrityError] = "Corrupted Stage2 loader",
 | 
					    [UpdatePrepareResultStageIntegrityError] = "Corrupted Stage2 loader",
 | 
				
			||||||
    [UpdatePrepareResultManifestPointerError] = "Failed to create update pointer file",
 | 
					    [UpdatePrepareResultManifestPointerCreateError] = "Failed to create update pointer file",
 | 
				
			||||||
 | 
					    [UpdatePrepareResultManifestPointerCheckError] = "Update pointer file error (corrupted FS?)",
 | 
				
			||||||
    [UpdatePrepareResultTargetMismatch] = "Hardware target mismatch",
 | 
					    [UpdatePrepareResultTargetMismatch] = "Hardware target mismatch",
 | 
				
			||||||
    [UpdatePrepareResultOutdatedManifestVersion] = "Update package is too old",
 | 
					    [UpdatePrepareResultOutdatedManifestVersion] = "Update package is too old",
 | 
				
			||||||
    [UpdatePrepareResultIntFull] = "Need more free space in internal storage",
 | 
					    [UpdatePrepareResultIntFull] = "Need more free space in internal storage",
 | 
				
			||||||
@ -142,8 +143,8 @@ UpdatePrepareResult update_operation_prepare(const char* manifest_file_path) {
 | 
				
			|||||||
    File* file = storage_file_alloc(storage);
 | 
					    File* file = storage_file_alloc(storage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uint64_t free_int_space;
 | 
					    uint64_t free_int_space;
 | 
				
			||||||
    FuriString* stage_path;
 | 
					    FuriString* stage_path = furi_string_alloc();
 | 
				
			||||||
    stage_path = furi_string_alloc();
 | 
					    FuriString* manifest_path_check = furi_string_alloc();
 | 
				
			||||||
    do {
 | 
					    do {
 | 
				
			||||||
        if((storage_common_fs_info(storage, STORAGE_INT_PATH_PREFIX, NULL, &free_int_space) !=
 | 
					        if((storage_common_fs_info(storage, STORAGE_INT_PATH_PREFIX, NULL, &free_int_space) !=
 | 
				
			||||||
            FSE_OK) ||
 | 
					            FSE_OK) ||
 | 
				
			||||||
@ -188,7 +189,18 @@ UpdatePrepareResult update_operation_prepare(const char* manifest_file_path) {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(!update_operation_persist_manifest_path(storage, manifest_file_path)) {
 | 
					        if(!update_operation_persist_manifest_path(storage, manifest_file_path)) {
 | 
				
			||||||
            result = UpdatePrepareResultManifestPointerError;
 | 
					            result = UpdatePrepareResultManifestPointerCreateError;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(!update_operation_get_current_package_manifest_path(storage, manifest_path_check) ||
 | 
				
			||||||
 | 
					           (furi_string_cmpi_str(manifest_path_check, manifest_file_path) != 0)) {
 | 
				
			||||||
 | 
					            FURI_LOG_E(
 | 
				
			||||||
 | 
					                "update",
 | 
				
			||||||
 | 
					                "Manifest pointer check failed: '%s' != '%s'",
 | 
				
			||||||
 | 
					                furi_string_get_cstr(manifest_path_check),
 | 
				
			||||||
 | 
					                manifest_file_path);
 | 
				
			||||||
 | 
					            result = UpdatePrepareResultManifestPointerCheckError;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -197,6 +209,7 @@ UpdatePrepareResult update_operation_prepare(const char* manifest_file_path) {
 | 
				
			|||||||
    } while(false);
 | 
					    } while(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    furi_string_free(stage_path);
 | 
					    furi_string_free(stage_path);
 | 
				
			||||||
 | 
					    furi_string_free(manifest_path_check);
 | 
				
			||||||
    storage_file_free(file);
 | 
					    storage_file_free(file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    update_manifest_free(manifest);
 | 
					    update_manifest_free(manifest);
 | 
				
			||||||
 | 
				
			|||||||
@ -28,7 +28,8 @@ typedef enum {
 | 
				
			|||||||
    UpdatePrepareResultManifestInvalid,
 | 
					    UpdatePrepareResultManifestInvalid,
 | 
				
			||||||
    UpdatePrepareResultStageMissing,
 | 
					    UpdatePrepareResultStageMissing,
 | 
				
			||||||
    UpdatePrepareResultStageIntegrityError,
 | 
					    UpdatePrepareResultStageIntegrityError,
 | 
				
			||||||
    UpdatePrepareResultManifestPointerError,
 | 
					    UpdatePrepareResultManifestPointerCreateError,
 | 
				
			||||||
 | 
					    UpdatePrepareResultManifestPointerCheckError,
 | 
				
			||||||
    UpdatePrepareResultTargetMismatch,
 | 
					    UpdatePrepareResultTargetMismatch,
 | 
				
			||||||
    UpdatePrepareResultOutdatedManifestVersion,
 | 
					    UpdatePrepareResultOutdatedManifestVersion,
 | 
				
			||||||
    UpdatePrepareResultIntFull,
 | 
					    UpdatePrepareResultIntFull,
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user