diff --git a/SConstruct b/SConstruct index f404bd02e..722713a28 100644 --- a/SConstruct +++ b/SConstruct @@ -234,7 +234,7 @@ firmware_debug = distenv.PhonyTarget( ) distenv.Depends(firmware_debug, firmware_flash) -distenv.PhonyTarget( +firmware_blackmagic = distenv.PhonyTarget( "blackmagic", "${GDBPYCOM}", source=firmware_env["FW_ELF"], @@ -242,6 +242,7 @@ distenv.PhonyTarget( GDBREMOTE="${BLACKMAGIC_ADDR}", FBT_FAP_DEBUG_ELF_ROOT=firmware_env["FBT_FAP_DEBUG_ELF_ROOT"], ) +distenv.Depends(firmware_blackmagic, firmware_flash) # Debug alien elf debug_other_opts = [ diff --git a/applications/main/ibutton/scenes/ibutton_scene_rpc.c b/applications/main/ibutton/scenes/ibutton_scene_rpc.c index f4f193a47..87f51f2d8 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_rpc.c +++ b/applications/main/ibutton/scenes/ibutton_scene_rpc.c @@ -1,22 +1,26 @@ #include "../ibutton_i.h" void ibutton_scene_rpc_on_enter(void* context) { - iButton* ibutton = context; + UNUSED(context); +} + +static void ibutton_rpc_start_emulation(iButton* ibutton) { Popup* popup = ibutton->popup; popup_set_header(popup, "iButton", 82, 28, AlignCenter, AlignBottom); - popup_set_text(popup, "RPC mode", 82, 32, AlignCenter, AlignTop); - + popup_set_text(popup, ibutton->key_name, 82, 32, AlignCenter, AlignTop); popup_set_icon(popup, 2, 14, &I_iButtonKey_49x44); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); + ibutton_worker_emulate_start(ibutton->worker, ibutton->key); + + ibutton_notification_message(ibutton, iButtonNotificationMessageEmulateStart); notification_message(ibutton->notifications, &sequence_display_backlight_on); } bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) { iButton* ibutton = context; - Popup* popup = ibutton->popup; bool consumed = false; @@ -27,17 +31,13 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) { bool result = false; if(ibutton_load_key(ibutton, false)) { - popup_set_text(popup, ibutton->key_name, 82, 32, AlignCenter, AlignTop); - view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewPopup); - - ibutton_notification_message(ibutton, iButtonNotificationMessageEmulateStart); - ibutton_worker_emulate_start(ibutton->worker, ibutton->key); - + ibutton_rpc_start_emulation(ibutton); result = true; + } else { + rpc_system_app_set_error_code(ibutton->rpc, RpcAppSystemErrorCodeParseFile); + rpc_system_app_set_error_text(ibutton->rpc, "Cannot load key file"); } - rpc_system_app_confirm(ibutton->rpc, result); - } else if(event.event == iButtonCustomEventRpcExit) { rpc_system_app_confirm(ibutton->rpc, true); scene_manager_stop(ibutton->scene_manager); diff --git a/applications/main/infrared/infrared_app.c b/applications/main/infrared/infrared_app.c index 70a691f55..24110e024 100644 --- a/applications/main/infrared/infrared_app.c +++ b/applications/main/infrared/infrared_app.c @@ -373,17 +373,15 @@ void infrared_tx_start(InfraredApp* infrared) { infrared->app_state.is_transmitting = true; } -void infrared_tx_start_button_index(InfraredApp* infrared, size_t button_index) { +bool infrared_tx_start_button_index(InfraredApp* infrared, size_t button_index) { furi_assert(button_index < infrared_remote_get_signal_count(infrared->remote)); - if(infrared_remote_load_signal(infrared->remote, infrared->current_signal, button_index)) { + bool result = + infrared_remote_load_signal(infrared->remote, infrared->current_signal, button_index); + if(result) { infrared_tx_start(infrared); - } else { - infrared_show_error_message( - infrared, - "Failed to load\n\"%s\"", - infrared_remote_get_signal_name(infrared->remote, button_index)); } + return result; } void infrared_tx_stop(InfraredApp* infrared) { diff --git a/applications/main/infrared/infrared_app_i.h b/applications/main/infrared/infrared_app_i.h index 75d4e230d..002a8c2ee 100644 --- a/applications/main/infrared/infrared_app_i.h +++ b/applications/main/infrared/infrared_app_i.h @@ -208,7 +208,7 @@ void infrared_tx_start(InfraredApp* infrared); * @param[in] button_index index of the signal to be loaded. * @returns true if the signal could be loaded, false otherwise. */ -void infrared_tx_start_button_index(InfraredApp* infrared, size_t button_index); +bool infrared_tx_start_button_index(InfraredApp* infrared, size_t button_index); /** * @brief Stop transmission of the currently loaded signal. diff --git a/applications/main/infrared/resources/infrared/assets/ac.ir b/applications/main/infrared/resources/infrared/assets/ac.ir index 1041fb3c5..2dfcc4f56 100644 --- a/applications/main/infrared/resources/infrared/assets/ac.ir +++ b/applications/main/infrared/resources/infrared/assets/ac.ir @@ -1091,3 +1091,41 @@ type: raw frequency: 38000 duty_cycle: 0.330000 data: 4348 4439 520 1646 520 1646 520 1646 519 1646 520 561 520 561 520 1646 519 561 520 561 520 562 519 562 519 561 520 1646 520 1647 518 563 518 1646 519 562 519 561 520 561 520 562 519 562 519 561 520 1648 517 1647 519 1646 519 1647 519 1646 520 1646 520 1645 520 1647 519 561 520 561 520 562 519 562 519 562 519 562 519 561 520 562 519 561 520 1646 520 562 519 1647 518 1646 520 562 519 560 521 561 520 561 520 561 520 562 519 562 519 560 521 562 519 562 519 560 521 1646 520 1646 520 561 520 562 519 561 520 562 519 561 520 561 520 561 520 561 520 561 520 1647 518 1646 520 562 519 562 519 561 520 1646 520 561 520 5409 4348 4440 519 1645 521 1646 519 1645 521 1645 521 561 520 561 520 1644 522 561 520 561 520 561 520 560 521 562 519 1646 520 1646 520 562 519 1644 522 561 520 561 520 561 520 561 520 561 520 561 520 1646 520 1645 520 1646 520 1645 521 1646 520 1646 520 1644 522 1645 521 560 521 560 521 561 520 561 520 560 521 560 521 561 520 561 520 561 520 1645 521 562 519 1645 521 1645 520 561 520 562 519 561 520 561 520 561 520 560 521 560 521 560 521 560 521 561 520 560 521 1646 520 1646 520 561 520 560 521 559 522 560 521 561 520 561 520 560 521 560 521 560 521 1646 520 1645 520 561 520 560 521 560 521 1645 521 561 520 +# +# Model: Airwell AW-HKD012-N91 +# +name: Dh +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4387 4398 547 1609 547 530 547 1610 547 1611 545 530 547 530 547 1608 547 530 548 530 547 1611 545 532 546 532 547 1609 547 1610 547 531 547 1608 548 530 547 530 548 530 547 1610 546 1609 547 1610 547 1609 547 1609 547 1611 545 1609 548 1610 546 530 547 530 548 529 549 531 547 531 546 531 547 1608 548 1610 547 1608 548 533 545 1608 548 532 546 532 546 1611 545 532 547 532 545 530 548 1608 547 530 549 1608 547 1609 548 5203 4386 4398 547 1609 546 530 547 1609 546 1607 548 531 547 531 547 1609 547 530 548 531 547 1609 547 531 547 531 547 1608 547 1613 544 531 546 1609 547 531 547 531 547 532 546 1609 547 1609 546 1609 547 1609 547 1608 547 1608 548 1608 548 1609 547 530 547 530 547 530 547 532 546 530 547 530 548 1610 546 1608 547 1609 547 530 547 1609 547 530 547 530 548 1609 546 530 548 530 547 532 546 1610 546 531 546 1608 548 1608 548 +# +name: Cool_hi +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4388 4398 547 1608 548 531 546 1610 546 1609 547 530 547 529 548 1608 548 532 547 530 548 1612 544 529 549 530 548 1608 547 1609 547 531 546 1608 548 1607 549 529 549 1608 549 1609 548 1608 548 1608 548 1611 545 1608 548 530 548 1609 547 531 547 530 548 530 548 531 547 529 549 530 548 530 547 531 547 530 548 530 547 529 549 530 548 532 547 530 548 1609 547 1610 547 1608 548 1609 547 1608 548 1608 548 1608 548 1608 548 5203 4388 4396 549 1609 547 529 549 1610 546 1608 548 529 549 530 547 1609 547 530 548 529 549 1608 548 531 547 532 546 1609 547 1609 547 530 548 1609 548 1609 548 529 548 1608 548 1609 548 1609 547 1609 547 1608 548 1609 547 532 546 1608 548 531 548 531 548 530 548 530 548 531 547 530 548 531 548 531 547 530 548 530 548 530 548 531 547 529 549 529 549 1609 548 1608 548 1609 547 1608 548 1608 548 1608 548 1607 549 1607 549 +# +name: Cool_lo +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4384 4400 572 1585 571 505 572 1583 573 1584 572 508 570 503 575 1584 572 505 572 506 572 1583 573 504 573 506 571 1586 570 1585 572 532 546 1586 570 1585 571 506 571 1585 571 1583 573 1586 570 1583 573 1584 572 1589 569 505 572 1585 571 506 571 506 573 506 572 505 573 532 545 504 574 509 570 1611 545 506 572 1582 574 506 572 507 571 507 571 507 570 1584 572 507 571 1587 569 506 572 1584 572 1585 571 1583 573 1612 544 5179 4386 4400 570 1584 572 507 571 1583 572 1585 571 506 572 506 572 1584 572 505 572 504 574 1584 572 507 571 504 574 1583 573 1585 572 507 571 1584 572 1610 545 508 571 1587 569 1583 573 1583 573 1585 571 1585 572 1585 572 505 572 1584 572 505 573 507 572 506 571 504 574 505 573 505 574 508 571 1585 571 507 571 1585 571 506 571 506 572 504 574 505 572 1586 570 507 571 1586 570 505 573 1584 572 1585 571 1587 569 1584 573 +# +name: Heat_hi +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4386 4398 575 1582 574 503 575 1583 573 1582 574 505 573 504 574 1582 574 506 572 508 570 1583 573 504 574 505 573 1583 573 1584 573 505 573 1582 575 1583 574 504 574 1582 574 1583 573 1583 573 1583 573 1585 571 1586 572 504 573 1584 572 504 573 505 573 505 573 505 573 504 573 506 571 1583 574 505 573 1583 573 1583 573 1584 572 1583 573 505 572 505 573 504 574 1583 574 505 573 505 573 504 574 505 572 1584 572 1584 573 5178 4387 4400 571 1583 573 504 574 1584 572 1584 572 507 572 504 574 1582 574 505 572 505 573 1583 573 504 574 504 574 1582 574 1584 573 503 574 1583 573 1582 574 505 573 1583 573 1582 575 1583 573 1610 546 1584 572 1583 573 505 573 1610 546 506 572 505 573 504 574 504 574 505 573 505 573 1584 573 505 573 1582 574 1584 572 1583 573 1583 573 504 574 503 575 504 574 1585 571 507 571 504 573 506 572 505 572 1584 572 1585 571 +# +name: Heat_lo +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4388 4399 547 1608 548 530 548 1610 547 1610 547 529 549 529 548 1608 548 530 548 530 548 1607 549 533 545 531 548 1608 548 1610 546 531 547 1609 547 1608 548 529 549 1609 547 1609 547 1609 547 1609 547 1609 547 1608 548 529 548 1638 519 530 548 530 548 530 548 529 550 528 549 530 548 530 548 1608 548 530 548 1609 548 1610 547 1609 547 531 546 529 549 1608 548 530 548 1609 548 530 548 529 548 530 548 1609 548 1609 548 5205 4387 4398 547 1609 548 531 546 1609 547 1609 547 530 548 531 546 1609 547 531 548 530 573 1583 573 507 571 506 572 1583 573 1582 574 504 574 1581 575 1582 574 506 572 1583 574 1583 573 1583 573 1585 571 1584 572 1585 570 507 571 1582 574 505 574 532 545 505 573 505 572 506 571 505 573 505 573 1584 572 506 572 1583 573 1584 572 1583 573 505 572 504 573 1583 573 505 573 1586 571 506 572 505 573 507 572 1583 573 1584 572 +# +name: Off +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 4388 4399 572 1583 573 532 546 1585 571 1583 574 503 575 505 573 1584 572 504 574 505 573 1584 573 506 572 504 573 1584 573 1584 572 505 574 1611 545 506 573 1583 573 1585 571 1586 545 1609 547 531 547 1611 545 1608 548 1607 549 530 548 529 548 531 548 532 546 1610 546 533 545 530 547 1609 547 1610 547 1609 547 533 545 529 548 530 548 530 547 531 546 530 547 530 548 533 544 1608 548 1608 548 1610 546 1606 550 1609 547 5203 4388 4397 548 1609 547 531 547 1608 548 1608 548 530 548 530 548 1608 548 531 547 531 547 1610 546 531 547 530 548 1609 547 1611 546 532 547 1609 547 531 547 1608 548 1610 546 1609 547 1608 548 530 547 1609 547 1608 548 1609 547 531 546 530 548 530 547 530 547 1608 548 532 547 534 545 1608 548 1608 548 1609 547 530 548 531 547 531 547 532 546 531 546 531 547 532 546 530 548 1608 547 1608 548 1610 546 1608 548 1608 548 \ No newline at end of file diff --git a/applications/main/infrared/scenes/infrared_scene_remote.c b/applications/main/infrared/scenes/infrared_scene_remote.c index 6c1d1ec4e..e1195c516 100644 --- a/applications/main/infrared/scenes/infrared_scene_remote.c +++ b/applications/main/infrared/scenes/infrared_scene_remote.c @@ -85,7 +85,12 @@ bool infrared_scene_remote_on_event(void* context, SceneManagerEvent event) { if(custom_type == InfraredCustomEventTypeTransmitStarted) { furi_assert(button_index >= 0); - infrared_tx_start_button_index(infrared, button_index); + if(!infrared_tx_start_button_index(infrared, button_index)) { + infrared_show_error_message( + infrared, + "Failed to load\n\"%s\"", + infrared_remote_get_signal_name(infrared->remote, button_index)); + } consumed = true; } else if(custom_type == InfraredCustomEventTypeTransmitStopped) { infrared_tx_stop(infrared); diff --git a/applications/main/infrared/scenes/infrared_scene_rpc.c b/applications/main/infrared/scenes/infrared_scene_rpc.c index 4c263a117..167247668 100644 --- a/applications/main/infrared/scenes/infrared_scene_rpc.c +++ b/applications/main/infrared/scenes/infrared_scene_rpc.c @@ -20,18 +20,24 @@ static int32_t infrared_scene_rpc_task_callback(void* context) { void infrared_scene_rpc_on_enter(void* context) { InfraredApp* infrared = context; + scene_manager_set_scene_state(infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateIdle); +} + +static void infrared_scene_rpc_show(InfraredApp* infrared) { Popup* popup = infrared->popup; popup_set_header(popup, "Infrared", 89, 42, AlignCenter, AlignBottom); popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop); + popup_set_text(popup, infrared->text_store[0], 89, 44, AlignCenter, AlignTop); popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61); - popup_set_context(popup, context); + popup_set_context(popup, infrared); popup_set_callback(popup, infrared_popup_closed_callback); view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup); - scene_manager_set_scene_state(infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateIdle); + scene_manager_set_scene_state( + infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateSending); notification_message(infrared->notifications, &sequence_display_backlight_on); } @@ -52,24 +58,20 @@ bool infrared_scene_rpc_on_event(void* context, SceneManagerEvent event) { } else if(event.event == InfraredCustomEventTypeTaskFinished) { const bool task_success = infrared_blocking_task_finalize(infrared); - if(task_success) { - const char* remote_name = infrared_remote_get_name(infrared->remote); - infrared_text_store_set(infrared, 0, "loaded\n%s", remote_name); scene_manager_set_scene_state( infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateLoaded); - } else { - infrared_text_store_set( - infrared, 0, "failed to load\n%s", furi_string_get_cstr(infrared->file_path)); + FuriString* str = furi_string_alloc(); + furi_string_printf( + str, "Failed to load\n%s", furi_string_get_cstr(infrared->file_path)); + + rpc_system_app_set_error_code(infrared->rpc_ctx, RpcAppSystemErrorCodeParseFile); + rpc_system_app_set_error_text(infrared->rpc_ctx, furi_string_get_cstr(str)); + + furi_string_free(str); } - - popup_set_text( - infrared->popup, infrared->text_store[0], 89, 44, AlignCenter, AlignTop); - view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup); - rpc_system_app_confirm(infrared->rpc_ctx, task_success); - } else if( event.event == InfraredCustomEventTypeRpcButtonPressName || event.event == InfraredCustomEventTypeRpcButtonPressIndex) { @@ -88,10 +90,19 @@ bool infrared_scene_rpc_on_event(void* context, SceneManagerEvent event) { TAG, "Sending signal with index \"%ld\"", app_state->current_button_index); } if(infrared->app_state.current_button_index != InfraredButtonIndexNone) { - infrared_tx_start_button_index(infrared, app_state->current_button_index); - scene_manager_set_scene_state( - infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateSending); - result = true; + if(infrared_tx_start_button_index(infrared, app_state->current_button_index)) { + const char* remote_name = infrared_remote_get_name(infrared->remote); + infrared_text_store_set(infrared, 0, "emulating\n%s", remote_name); + + infrared_scene_rpc_show(infrared); + result = true; + } else { + rpc_system_app_set_error_code( + infrared->rpc_ctx, RpcAppSystemErrorCodeInternalParse); + rpc_system_app_set_error_text( + infrared->rpc_ctx, "Cannot load button data"); + result = false; + } } } rpc_system_app_confirm(infrared->rpc_ctx, result); diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c b/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c index 906218d74..65ffa1ef6 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_rpc.c @@ -2,23 +2,30 @@ void lfrfid_scene_rpc_on_enter(void* context) { LfRfid* app = context; + app->rpc_state = LfRfidRpcStateIdle; +} + +static void lfrfid_rpc_start_emulation(LfRfid* app) { Popup* popup = app->popup; + lfrfid_text_store_set(app, "emulating\n%s", furi_string_get_cstr(app->file_name)); + popup_set_header(popup, "LF RFID", 89, 42, AlignCenter, AlignBottom); - popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop); + popup_set_text(popup, app->text_store, 89, 44, AlignCenter, AlignTop); popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); - notification_message(app->notifications, &sequence_display_backlight_on); + lfrfid_worker_start_thread(app->lfworker); + lfrfid_worker_emulate_start(app->lfworker, (LFRFIDProtocol)app->protocol_id); - app->rpc_state = LfRfidRpcStateIdle; + notification_message(app->notifications, &sequence_display_backlight_on); + notification_message(app->notifications, &sequence_blink_start_magenta); + app->rpc_state = LfRfidRpcStateEmulating; } bool lfrfid_scene_rpc_on_event(void* context, SceneManagerEvent event) { LfRfid* app = context; - Popup* popup = app->popup; - UNUSED(event); bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { @@ -34,16 +41,11 @@ bool lfrfid_scene_rpc_on_event(void* context, SceneManagerEvent event) { bool result = false; if(app->rpc_state == LfRfidRpcStateIdle) { if(lfrfid_load_key_data(app, app->file_path, false)) { - lfrfid_worker_start_thread(app->lfworker); - lfrfid_worker_emulate_start(app->lfworker, (LFRFIDProtocol)app->protocol_id); - app->rpc_state = LfRfidRpcStateEmulating; - - lfrfid_text_store_set( - app, "emulating\n%s", furi_string_get_cstr(app->file_name)); - popup_set_text(popup, app->text_store, 89, 44, AlignCenter, AlignTop); - - notification_message(app->notifications, &sequence_blink_start_magenta); + lfrfid_rpc_start_emulation(app); result = true; + } else { + rpc_system_app_set_error_code(app->rpc_ctx, RpcAppSystemErrorCodeParseFile); + rpc_system_app_set_error_text(app->rpc_ctx, "Cannot load key file"); } } rpc_system_app_confirm(app->rpc_ctx, result); diff --git a/applications/main/nfc/helpers/protocol_support/nfc_protocol_support.c b/applications/main/nfc/helpers/protocol_support/nfc_protocol_support.c index 072e8d7ef..9772be1e7 100644 --- a/applications/main/nfc/helpers/protocol_support/nfc_protocol_support.c +++ b/applications/main/nfc/helpers/protocol_support/nfc_protocol_support.c @@ -731,6 +731,10 @@ static bool nfc_protocol_support_scene_rpc_on_event(NfcApp* instance, SceneManag if(nfc_load_file(instance, instance->file_path, false)) { nfc_protocol_support_scene_rpc_setup_ui_and_emulate(instance); success = true; + } else { + rpc_system_app_set_error_code( + instance->rpc_ctx, RpcAppSystemErrorCodeParseFile); + rpc_system_app_set_error_text(instance->rpc_ctx, "Cannot load key file"); } } rpc_system_app_confirm(instance->rpc_ctx, success); diff --git a/applications/main/nfc/nfc_app.c b/applications/main/nfc/nfc_app.c index e61e172f0..e563eacd1 100644 --- a/applications/main/nfc/nfc_app.c +++ b/applications/main/nfc/nfc_app.c @@ -496,7 +496,7 @@ int32_t nfc_app(void* p) { nfc->view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen); furi_string_set(nfc->file_path, args); - if(nfc_load_file(nfc, nfc->file_path, false)) { + if(nfc_load_file(nfc, nfc->file_path, true)) { nfc->fav_timeout = is_favorite; nfc_show_initial_scene_for_device(nfc); } else { diff --git a/applications/main/subghz/helpers/subghz_error_type.h b/applications/main/subghz/helpers/subghz_error_type.h deleted file mode 100644 index 0f86d6ea7..000000000 --- a/applications/main/subghz/helpers/subghz_error_type.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include -#include - -/** SubGhzErrorType */ -typedef enum { - SubGhzErrorTypeNoError = 0, /** There are no errors */ - SubGhzErrorTypeParseFile = - 1, /** File parsing error, or wrong file structure, or missing required parameters. more accurate data can be obtained through the debug port */ - SubGhzErrorTypeOnlyRX = - 2, /** Transmission on this frequency is blocked by regional settings */ - SubGhzErrorTypeParserOthers = 3, /** Error in protocol parameters description */ -} SubGhzErrorType; diff --git a/applications/main/subghz/scenes/subghz_scene_rpc.c b/applications/main/subghz/scenes/subghz_scene_rpc.c index 4675afaeb..f058821e0 100644 --- a/applications/main/subghz/scenes/subghz_scene_rpc.c +++ b/applications/main/subghz/scenes/subghz_scene_rpc.c @@ -10,23 +10,33 @@ typedef enum { void subghz_scene_rpc_on_enter(void* context) { SubGhz* subghz = context; + scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneRpc, SubGhzRpcStateIdle); +} + +static void subghz_format_file_name_tmp(SubGhz* subghz) { + FuriString* file_name; + file_name = furi_string_alloc(); + path_extract_filename(subghz->file_path, file_name, true); + snprintf( + subghz->file_name_tmp, SUBGHZ_MAX_LEN_NAME, "loaded\n%s", furi_string_get_cstr(file_name)); + furi_string_free(file_name); +} + +static void subghz_scene_rpc_emulation_show(SubGhz* subghz) { Popup* popup = subghz->popup; + subghz_format_file_name_tmp(subghz); popup_set_header(popup, "Sub-GHz", 89, 42, AlignCenter, AlignBottom); - popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61); + popup_set_text(popup, subghz->file_name_tmp, 89, 44, AlignCenter, AlignTop); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdPopup); - scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneRpc, SubGhzRpcStateIdle); - notification_message(subghz->notifications, &sequence_display_backlight_on); } bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; - Popup* popup = subghz->popup; bool consumed = false; SubGhzRpcState state = scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneRpc); @@ -45,13 +55,15 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { switch( subghz_txrx_tx_start(subghz->txrx, subghz_txrx_get_fff_data(subghz->txrx))) { case SubGhzTxRxStartTxStateErrorOnlyRx: - rpc_system_app_set_error_code(subghz->rpc_ctx, SubGhzErrorTypeOnlyRX); + rpc_system_app_set_error_code( + subghz->rpc_ctx, RpcAppSystemErrorCodeRegionLock); rpc_system_app_set_error_text( subghz->rpc_ctx, "Transmission on this frequency is restricted in your settings"); break; case SubGhzTxRxStartTxStateErrorParserOthers: - rpc_system_app_set_error_code(subghz->rpc_ctx, SubGhzErrorTypeParserOthers); + rpc_system_app_set_error_code( + subghz->rpc_ctx, RpcAppSystemErrorCodeInternalParse); rpc_system_app_set_error_text( subghz->rpc_ctx, "Error in protocol parameters description"); break; @@ -79,22 +91,12 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) { bool result = false; if(state == SubGhzRpcStateIdle) { if(subghz_key_load(subghz, furi_string_get_cstr(subghz->file_path), false)) { + subghz_scene_rpc_emulation_show(subghz); scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneRpc, SubGhzRpcStateLoaded); result = true; - FuriString* file_name = furi_string_alloc(); - path_extract_filename(subghz->file_path, file_name, true); - - snprintf( - subghz->file_name_tmp, - SUBGHZ_MAX_LEN_NAME, - "loaded\n%s", - furi_string_get_cstr(file_name)); - popup_set_text(popup, subghz->file_name_tmp, 89, 44, AlignCenter, AlignTop); - - furi_string_free(file_name); } else { - rpc_system_app_set_error_code(subghz->rpc_ctx, SubGhzErrorTypeParseFile); + rpc_system_app_set_error_code(subghz->rpc_ctx, RpcAppSystemErrorCodeParseFile); rpc_system_app_set_error_text(subghz->rpc_ctx, "Cannot parse file"); } } diff --git a/applications/main/subghz/subghz_i.h b/applications/main/subghz/subghz_i.h index 9f0eae6fa..b56fb4b1b 100644 --- a/applications/main/subghz/subghz_i.h +++ b/applications/main/subghz/subghz_i.h @@ -1,7 +1,6 @@ #pragma once #include "helpers/subghz_types.h" -#include "helpers/subghz_error_type.h" #include #include "subghz.h" #include "views/receiver.h" diff --git a/applications/services/gui/modules/dialog_ex.c b/applications/services/gui/modules/dialog_ex.c index 75209a408..d27de1242 100644 --- a/applications/services/gui/modules/dialog_ex.c +++ b/applications/services/gui/modules/dialog_ex.c @@ -222,7 +222,7 @@ void dialog_ex_set_header( dialog_ex->view, DialogExModel * model, { - furi_string_set(model->header.text, text); + furi_string_set(model->header.text, text ? text : ""); model->header.x = x; model->header.y = y; model->header.horizontal = horizontal; @@ -243,7 +243,7 @@ void dialog_ex_set_text( dialog_ex->view, DialogExModel * model, { - furi_string_set(model->text.text, text); + furi_string_set(model->text.text, text ? text : ""); model->text.x = x; model->text.y = y; model->text.horizontal = horizontal; @@ -268,7 +268,10 @@ void dialog_ex_set_icon(DialogEx* dialog_ex, uint8_t x, uint8_t y, const Icon* i void dialog_ex_set_left_button_text(DialogEx* dialog_ex, const char* text) { furi_check(dialog_ex); with_view_model( - dialog_ex->view, DialogExModel * model, { furi_string_set(model->left_text, text); }, true); + dialog_ex->view, + DialogExModel * model, + { furi_string_set(model->left_text, text ? text : ""); }, + true); } void dialog_ex_set_center_button_text(DialogEx* dialog_ex, const char* text) { @@ -276,7 +279,7 @@ void dialog_ex_set_center_button_text(DialogEx* dialog_ex, const char* text) { with_view_model( dialog_ex->view, DialogExModel * model, - { furi_string_set(model->center_text, text); }, + { furi_string_set(model->center_text, text ? text : ""); }, true); } @@ -285,7 +288,7 @@ void dialog_ex_set_right_button_text(DialogEx* dialog_ex, const char* text) { with_view_model( dialog_ex->view, DialogExModel * model, - { furi_string_set(model->right_text, text); }, + { furi_string_set(model->right_text, text ? text : ""); }, true); } diff --git a/applications/services/rpc/rpc_app.h b/applications/services/rpc/rpc_app.h index 4ee5a24d3..aa6fd81cc 100644 --- a/applications/services/rpc/rpc_app.h +++ b/applications/services/rpc/rpc_app.h @@ -13,6 +13,7 @@ #pragma once #include "rpc.h" +#include "rpc_app_error_codes.h" #ifdef __cplusplus extern "C" { diff --git a/applications/services/rpc/rpc_app_error_codes.h b/applications/services/rpc/rpc_app_error_codes.h new file mode 100644 index 000000000..fc0edd4d2 --- /dev/null +++ b/applications/services/rpc/rpc_app_error_codes.h @@ -0,0 +1,11 @@ +#pragma once + +/** + * @brief Enumeration of possible error codes for application which can be started through rpc + */ +typedef enum { + RpcAppSystemErrorCodeNone, /** There are no errors */ + RpcAppSystemErrorCodeParseFile, /** File parsing error, or wrong file structure, or missing required parameters. more accurate data can be obtained through the debug port */ + RpcAppSystemErrorCodeRegionLock, /** Requested function is blocked by regional settings */ + RpcAppSystemErrorCodeInternalParse, /** Error in protocol parameters description, or some data in opened file are unsupported */ +} RpcAppSystemErrorCode; diff --git a/applications/services/rpc/rpc_storage.c b/applications/services/rpc/rpc_storage.c index 1128b7ff0..dd2b40072 100644 --- a/applications/services/rpc/rpc_storage.c +++ b/applications/services/rpc/rpc_storage.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include @@ -656,7 +656,7 @@ static void rpc_system_storage_backup_create_process(const PB_Main* request, voi rpc_system_storage_reset_state(rpc_storage, session, true); - bool backup_ok = lfs_backup_create( + bool backup_ok = int_backup_create( rpc_storage->api, request->content.storage_backup_create_request.archive_path); rpc_send_and_release_empty( @@ -676,7 +676,7 @@ static void rpc_system_storage_backup_restore_process(const PB_Main* request, vo rpc_system_storage_reset_state(rpc_storage, session, true); - bool backup_ok = lfs_backup_unpack( + bool backup_ok = int_backup_unpack( rpc_storage->api, request->content.storage_backup_restore_request.archive_path); rpc_send_and_release_empty( diff --git a/applications/services/storage/storage.h b/applications/services/storage/storage.h index 4af3458d8..1fd99d30a 100644 --- a/applications/services/storage/storage.h +++ b/applications/services/storage/storage.h @@ -531,7 +531,7 @@ FS_Error storage_sd_info(Storage* storage, SDInfo* info); */ FS_Error storage_sd_status(Storage* storage); -/******************* Internal LFS Functions *******************/ +/************ Internal Storage Backup/Restore ************/ typedef void (*StorageNameConverter)(FuriString*); diff --git a/applications/system/updater/cli/updater_cli.c b/applications/system/updater/cli/updater_cli.c index 0b734c0f4..56a16bd9d 100644 --- a/applications/system/updater/cli/updater_cli.c +++ b/applications/system/updater/cli/updater_cli.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include typedef void (*cmd_handler)(FuriString* args); @@ -35,7 +35,7 @@ static void updater_cli_install(FuriString* manifest_path) { static void updater_cli_backup(FuriString* args) { printf("Backup /int to '%s'\r\n", furi_string_get_cstr(args)); Storage* storage = furi_record_open(RECORD_STORAGE); - bool success = lfs_backup_create(storage, furi_string_get_cstr(args)); + bool success = int_backup_create(storage, furi_string_get_cstr(args)); furi_record_close(RECORD_STORAGE); printf("Result: %s\r\n", success ? "OK" : "FAIL"); } @@ -43,7 +43,7 @@ static void updater_cli_backup(FuriString* args) { static void updater_cli_restore(FuriString* args) { printf("Restore /int from '%s'\r\n", furi_string_get_cstr(args)); Storage* storage = furi_record_open(RECORD_STORAGE); - bool success = lfs_backup_unpack(storage, furi_string_get_cstr(args)); + bool success = int_backup_unpack(storage, furi_string_get_cstr(args)); furi_record_close(RECORD_STORAGE); printf("Result: %s\r\n", success ? "OK" : "FAIL"); } diff --git a/applications/system/updater/util/update_task.c b/applications/system/updater/util/update_task.c index eaddbeeab..c0349c1cf 100644 --- a/applications/system/updater/util/update_task.c +++ b/applications/system/updater/util/update_task.c @@ -22,8 +22,8 @@ static const char* update_task_stage_descr[] = { [UpdateTaskStageRadioInstall] = "Installing radio FW", [UpdateTaskStageRadioBusy] = "Core 2 busy", [UpdateTaskStageOBValidation] = "Validating opt. bytes", - [UpdateTaskStageLfsBackup] = "Backing up LFS", - [UpdateTaskStageLfsRestore] = "Restoring LFS", + [UpdateTaskStageIntBackup] = "Backing up configuration", + [UpdateTaskStageIntRestore] = "Restoring configuration", [UpdateTaskStageResourcesFileCleanup] = "Cleaning up files", [UpdateTaskStageResourcesDirCleanup] = "Cleaning up directories", [UpdateTaskStageResourcesFileUnpack] = "Extracting resources", @@ -82,7 +82,7 @@ static const struct { }, #ifndef FURI_RAM_EXEC { - .stage = UpdateTaskStageLfsBackup, + .stage = UpdateTaskStageIntBackup, .percent_min = 0, .percent_max = 100, .descr = "FS R/W error", @@ -193,10 +193,10 @@ static const struct { #endif #ifndef FURI_RAM_EXEC { - .stage = UpdateTaskStageLfsRestore, + .stage = UpdateTaskStageIntRestore, .percent_min = 0, .percent_max = 100, - .descr = "LFS I/O error", + .descr = "SD card I/O error", }, { .stage = UpdateTaskStageResourcesFileCleanup, @@ -245,7 +245,7 @@ static const UpdateTaskStageGroupMap update_task_stage_progress[] = { [UpdateTaskStageProgress] = STAGE_DEF(UpdateTaskStageGroupMisc, 0), [UpdateTaskStageReadManifest] = STAGE_DEF(UpdateTaskStageGroupPreUpdate, 45), - [UpdateTaskStageLfsBackup] = STAGE_DEF(UpdateTaskStageGroupPreUpdate, 5), + [UpdateTaskStageIntBackup] = STAGE_DEF(UpdateTaskStageGroupPreUpdate, 5), [UpdateTaskStageRadioImageValidate] = STAGE_DEF(UpdateTaskStageGroupRadio, 15), [UpdateTaskStageRadioErase] = STAGE_DEF(UpdateTaskStageGroupRadio, 25), @@ -259,7 +259,7 @@ static const UpdateTaskStageGroupMap update_task_stage_progress[] = { [UpdateTaskStageFlashWrite] = STAGE_DEF(UpdateTaskStageGroupFirmware, 100), [UpdateTaskStageFlashValidate] = STAGE_DEF(UpdateTaskStageGroupFirmware, 20), - [UpdateTaskStageLfsRestore] = STAGE_DEF(UpdateTaskStageGroupPostUpdate, 5), + [UpdateTaskStageIntRestore] = STAGE_DEF(UpdateTaskStageGroupPostUpdate, 5), [UpdateTaskStageResourcesFileCleanup] = STAGE_DEF(UpdateTaskStageGroupResources, 100), [UpdateTaskStageResourcesDirCleanup] = STAGE_DEF(UpdateTaskStageGroupResources, 50), diff --git a/applications/system/updater/util/update_task.h b/applications/system/updater/util/update_task.h index 52bdfdbd2..c346c55fa 100644 --- a/applications/system/updater/util/update_task.h +++ b/applications/system/updater/util/update_task.h @@ -16,7 +16,7 @@ typedef enum { UpdateTaskStageProgress = 0, UpdateTaskStageReadManifest, - UpdateTaskStageLfsBackup, + UpdateTaskStageIntBackup, UpdateTaskStageRadioImageValidate, UpdateTaskStageRadioErase, @@ -30,7 +30,7 @@ typedef enum { UpdateTaskStageFlashWrite, UpdateTaskStageFlashValidate, - UpdateTaskStageLfsRestore, + UpdateTaskStageIntRestore, UpdateTaskStageResourcesFileCleanup, UpdateTaskStageResourcesDirCleanup, UpdateTaskStageResourcesFileUnpack, diff --git a/applications/system/updater/util/update_task_worker_backup.c b/applications/system/updater/util/update_task_worker_backup.c index bcf1fd141..0081de21d 100644 --- a/applications/system/updater/util/update_task_worker_backup.c +++ b/applications/system/updater/util/update_task_worker_backup.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include @@ -23,14 +23,14 @@ static bool update_task_pre_update(UpdateTask* update_task) { backup_file_path = furi_string_alloc(); path_concat( furi_string_get_cstr(update_task->update_path), - LFS_BACKUP_DEFAULT_FILENAME, + INT_BACKUP_DEFAULT_FILENAME, backup_file_path); - update_task_set_progress(update_task, UpdateTaskStageLfsBackup, 0); + update_task_set_progress(update_task, UpdateTaskStageIntBackup, 0); /* to avoid bootloops */ furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); if((success = - lfs_backup_create(update_task->storage, furi_string_get_cstr(backup_file_path)))) { + int_backup_create(update_task->storage, furi_string_get_cstr(backup_file_path)))) { furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeUpdate); } @@ -131,12 +131,12 @@ static bool update_task_post_update(UpdateTask* update_task) { do { path_concat( furi_string_get_cstr(update_task->update_path), - LFS_BACKUP_DEFAULT_FILENAME, + INT_BACKUP_DEFAULT_FILENAME, file_path); - update_task_set_progress(update_task, UpdateTaskStageLfsRestore, 0); + update_task_set_progress(update_task, UpdateTaskStageIntRestore, 0); - CHECK_RESULT(lfs_backup_unpack(update_task->storage, furi_string_get_cstr(file_path))); + CHECK_RESULT(int_backup_unpack(update_task->storage, furi_string_get_cstr(file_path))); // Fix flags for production / development #ifdef FURI_DEBUG diff --git a/applications/system/updater/util/update_task_worker_flasher.c b/applications/system/updater/util/update_task_worker_flasher.c index 6ff00959d..f587f7447 100644 --- a/applications/system/updater/util/update_task_worker_flasher.c +++ b/applications/system/updater/util/update_task_worker_flasher.c @@ -341,7 +341,7 @@ int32_t update_task_worker_flash_writer(void* context) { } furi_hal_rtc_set_boot_mode(FuriHalRtcBootModePostUpdate); - // Format LFS before restoring backup on next boot + // Clean up /int before restoring backup on next boot furi_hal_rtc_set_flag(FuriHalRtcFlagStorageFormatInternal); update_task_set_progress(update_task, UpdateTaskStageCompleted, 100); diff --git a/documentation/OTA.md b/documentation/OTA.md index 0456eab1f..9783a7047 100644 --- a/documentation/OTA.md +++ b/documentation/OTA.md @@ -83,7 +83,7 @@ Even if something goes wrong, updater allows you to retry failed operations and | | | **50** | Package has mismatching HW target | | | | **60** | Missing DFU file | | | | **80** | Missing radio firmware file | -| Backing up LFS | **2** | **0-100** | FS read/write error | +| Backing up configuration| **2** | **0-100** | FS read/write error | | Checking radio FW | **3** | **0-99** | Error reading radio firmware file | | | | **100** | CRC mismatch | | Uninstalling radio FW | **4** | **0** | SHCI Delete command error | @@ -101,7 +101,7 @@ Even if something goes wrong, updater allows you to retry failed operations and | | | **99-100** | Corrupted DFU file | | Writing flash | **10** | **0-100** | Block read/write error | | Validating flash | **11** | **0-100** | Block read/write error | -| Restoring LFS | **12** | **0-100** | FS read/write error | +| Restoring configuration | **12** | **0-100** | FS read/write error | | Updating resources | **13-15** | **0-100** | SD card read/write error | ## Building update packages diff --git a/lib/update_util/int_backup.c b/lib/update_util/int_backup.c new file mode 100644 index 000000000..a904db247 --- /dev/null +++ b/lib/update_util/int_backup.c @@ -0,0 +1,51 @@ +#include "int_backup.h" + +#include + +#include +#include +#include +#include +#include +#include + +#define INT_BACKUP_DEFAULT_LOCATION EXT_PATH(INT_BACKUP_DEFAULT_FILENAME) + +static void backup_name_converter(FuriString* filename) { + if(furi_string_empty(filename) || (furi_string_get_char(filename, 0) == '.')) { + return; + } + + /* Filenames are already prefixed with '.' */ + const char* const names[] = { + BT_SETTINGS_FILE_NAME, + BT_KEYS_STORAGE_FILE_NAME, + DESKTOP_SETTINGS_FILE_NAME, + NOTIFICATION_SETTINGS_FILE_NAME, + SLIDESHOW_FILE_NAME, + DOLPHIN_STATE_FILE_NAME, + }; + + for(size_t i = 0; i < COUNT_OF(names); i++) { + if(furi_string_equal(filename, &names[i][1])) { + furi_string_set(filename, names[i]); + return; + } + } +} + +bool int_backup_create(Storage* storage, const char* destination) { + const char* final_destination = + destination && strlen(destination) ? destination : INT_BACKUP_DEFAULT_LOCATION; + return storage_int_backup(storage, final_destination) == FSE_OK; +} + +bool int_backup_exists(Storage* storage, const char* source) { + const char* final_source = source && strlen(source) ? source : INT_BACKUP_DEFAULT_LOCATION; + return storage_common_stat(storage, final_source, NULL) == FSE_OK; +} + +bool int_backup_unpack(Storage* storage, const char* source) { + const char* final_source = source && strlen(source) ? source : INT_BACKUP_DEFAULT_LOCATION; + return storage_int_restore(storage, final_source, backup_name_converter) == FSE_OK; +} diff --git a/lib/update_util/int_backup.h b/lib/update_util/int_backup.h new file mode 100644 index 000000000..168efda50 --- /dev/null +++ b/lib/update_util/int_backup.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +#define INT_BACKUP_DEFAULT_FILENAME "backup.tar" + +#ifdef __cplusplus +extern "C" { +#endif + +bool int_backup_create(Storage* storage, const char* destination); +bool int_backup_exists(Storage* storage, const char* source); +bool int_backup_unpack(Storage* storage, const char* source); + +#ifdef __cplusplus +} +#endif diff --git a/lib/update_util/lfs_backup.c b/lib/update_util/lfs_backup.c deleted file mode 100644 index a441ccabd..000000000 --- a/lib/update_util/lfs_backup.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "lfs_backup.h" - -#include - -#define LFS_BACKUP_DEFAULT_LOCATION EXT_PATH(LFS_BACKUP_DEFAULT_FILENAME) - -bool lfs_backup_create(Storage* storage, const char* destination) { - const char* final_destination = - destination && strlen(destination) ? destination : LFS_BACKUP_DEFAULT_LOCATION; - return storage_int_backup(storage, final_destination) == FSE_OK; -} - -bool lfs_backup_exists(Storage* storage, const char* source) { - const char* final_source = source && strlen(source) ? source : LFS_BACKUP_DEFAULT_LOCATION; - return storage_common_stat(storage, final_source, NULL) == FSE_OK; -} - -bool lfs_backup_unpack(Storage* storage, const char* source) { - const char* final_source = source && strlen(source) ? source : LFS_BACKUP_DEFAULT_LOCATION; - return storage_int_restore(storage, final_source, NULL) == FSE_OK; -} diff --git a/lib/update_util/lfs_backup.h b/lib/update_util/lfs_backup.h deleted file mode 100644 index 5a7738c86..000000000 --- a/lib/update_util/lfs_backup.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include -#include - -#define LFS_BACKUP_DEFAULT_FILENAME "backup.tar" - -#ifdef __cplusplus -extern "C" { -#endif - -bool lfs_backup_create(Storage* storage, const char* destination); -bool lfs_backup_exists(Storage* storage, const char* source); -bool lfs_backup_unpack(Storage* storage, const char* source); - -#ifdef __cplusplus -} -#endif diff --git a/scripts/debug/flipperapps.py b/scripts/debug/flipperapps.py index 6dba89a56..81aa43c34 100644 --- a/scripts/debug/flipperapps.py +++ b/scripts/debug/flipperapps.py @@ -124,7 +124,7 @@ class SetFapDebugElfRoot(gdb.Command): print(f"Set '{arg}' as debug info lookup path for Flipper external apps") helper.attach_to_fw() gdb.events.stop.connect(helper.handle_stop) - gdb.events.exited.connect(helper.handle_exit) + gdb.events.gdb_exiting.connect(helper.handle_exit) except gdb.error as e: print(f"Support for Flipper external apps debug is not available: {e}") diff --git a/targets/f7/furi_hal/furi_hal_rtc.h b/targets/f7/furi_hal/furi_hal_rtc.h index 96c9f80de..9b7022eab 100644 --- a/targets/f7/furi_hal/furi_hal_rtc.h +++ b/targets/f7/furi_hal/furi_hal_rtc.h @@ -9,6 +9,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -44,7 +45,7 @@ typedef enum { FuriHalRtcRegisterHeader, /**< RTC structure header */ FuriHalRtcRegisterSystem, /**< Various system bits */ FuriHalRtcRegisterVersion, /**< Pointer to Version */ - FuriHalRtcRegisterLfsFingerprint, /**< LFS geometry fingerprint */ + FuriHalRtcRegisterLfsFingerprint FURI_DEPRECATED, /**< LFS geometry fingerprint */ FuriHalRtcRegisterFaultData, /**< Pointer to last fault message */ FuriHalRtcRegisterPinFails, /**< Failed PINs count */ /* Index of FS directory entry corresponding to FW update to be applied */