[FL-3902] NFC app now can launch MFKey32 (#4117)

* feat: app chaining

* add `launch_current_app_after_deferred`, remove `get_referring_application`

* fix naming

* new api

* fix f18

* Added new function which enqueues external app from nfc app

* Added path to MFKey32 app

* Button "Crack nonces in MFKey32" added to ReadMenu scene

* SaveConfirm scene adjusted to move to different scenes depending on state

* SaveSuccess scene now moves to different scenes depending on SaveConfirm scene state

* MfKeyComplete scene shows different text when MFKey.fap present on the device

* Now MfKeyClassic scene can run external app

* fix deferred launches after errors

Co-authored-by: Anna Antonenko <portasynthinca3@gmail.com>
Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
Co-authored-by: hedger <hedger@nanode.su>
This commit is contained in:
RebornedBrain
2025-04-07 00:49:22 +03:00
committed by GitHub
parent 6b5d006690
commit f07048d1b0
6 changed files with 118 additions and 20 deletions

View File

@@ -1,4 +1,10 @@
#include "../nfc_app_i.h"
#include "loader/loader.h"
typedef enum {
NfcSceneMfClassicMfKeyCompleteStateAppMissing,
NfcSceneMfClassicMfKeyCompleteStateAppPresent,
} NfcSceneMfClassicMfKeyCompleteState;
void nfc_scene_mf_classic_mfkey_complete_callback(
GuiButtonType result,
@@ -15,22 +21,47 @@ void nfc_scene_mf_classic_mfkey_complete_on_enter(void* context) {
widget_add_string_element(
instance->widget, 64, 0, AlignCenter, AlignTop, FontPrimary, "Completed!");
widget_add_string_multiline_element(
instance->widget,
64,
13,
AlignCenter,
AlignTop,
FontSecondary,
"Now use Mfkey32 to extract \nkeys: r.flipper.net/nfc-tools");
widget_add_icon_element(instance->widget, 50, 39, &I_MFKey_qr_25x25);
widget_add_button_element(
instance->widget,
GuiButtonTypeRight,
"Finish",
nfc_scene_mf_classic_mfkey_complete_callback,
instance);
NfcSceneMfClassicMfKeyCompleteState scene_state =
storage_common_exists(instance->storage, NFC_MFKEY32_APP_PATH) ?
NfcSceneMfClassicMfKeyCompleteStateAppPresent :
NfcSceneMfClassicMfKeyCompleteStateAppMissing;
scene_manager_set_scene_state(
instance->scene_manager, NfcSceneMfClassicMfkeyComplete, scene_state);
if(scene_state == NfcSceneMfClassicMfKeyCompleteStateAppMissing) {
widget_add_string_multiline_element(
instance->widget,
64,
13,
AlignCenter,
AlignTop,
FontSecondary,
"Now use Mfkey32 to extract \nkeys: r.flipper.net/nfc-tools");
widget_add_icon_element(instance->widget, 50, 39, &I_MFKey_qr_25x25);
widget_add_button_element(
instance->widget,
GuiButtonTypeRight,
"Finish",
nfc_scene_mf_classic_mfkey_complete_callback,
instance);
} else {
widget_add_string_multiline_element(
instance->widget,
60,
16,
AlignLeft,
AlignTop,
FontSecondary,
"Now run Mfkey32\n to extract \nkeys");
widget_add_icon_element(instance->widget, 5, 18, &I_WarningDolphin_45x42);
widget_add_button_element(
instance->widget,
GuiButtonTypeRight,
"Run",
nfc_scene_mf_classic_mfkey_complete_callback,
instance);
}
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewWidget);
}
@@ -40,8 +71,14 @@ bool nfc_scene_mf_classic_mfkey_complete_on_event(void* context, SceneManagerEve
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == GuiButtonTypeRight) {
consumed = scene_manager_search_and_switch_to_previous_scene(
instance->scene_manager, NfcSceneStart);
NfcSceneMfClassicMfKeyCompleteState scene_state = scene_manager_get_scene_state(
instance->scene_manager, NfcSceneMfClassicMfkeyComplete);
if(scene_state == NfcSceneMfClassicMfKeyCompleteStateAppMissing) {
consumed = scene_manager_search_and_switch_to_previous_scene(
instance->scene_manager, NfcSceneStart);
} else {
nfc_app_run_external(instance, NFC_MFKEY32_APP_PATH);
}
}
} else if(event.type == SceneManagerEventTypeBack) {
const uint32_t prev_scenes[] = {NfcSceneSavedMenu, NfcSceneStart};

View File

@@ -29,7 +29,14 @@ bool nfc_scene_save_confirm_on_event(void* context, SceneManagerEvent event) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
consumed = true;
} else if(event.event == DialogExResultLeft) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicDetectReader);
NfcSceneSaveConfirmState scene_state =
scene_manager_get_scene_state(nfc->scene_manager, NfcSceneSaveConfirm);
NfcScene scene = scene_state == NfcSceneSaveConfirmStateCrackNonces ?
NfcSceneMfClassicMfkeyComplete :
NfcSceneMfClassicDetectReader;
scene_manager_next_scene(nfc->scene_manager, scene);
consumed = true;
}
}

View File

@@ -29,7 +29,13 @@ bool nfc_scene_save_success_on_event(void* context, SceneManagerEvent event) {
consumed = scene_manager_search_and_switch_to_previous_scene(
nfc->scene_manager, NfcSceneMfClassicKeys);
} else if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSaveConfirm)) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicDetectReader);
NfcSceneSaveConfirmState scene_state =
scene_manager_get_scene_state(nfc->scene_manager, NfcSceneSaveConfirm);
NfcScene scene = scene_state == NfcSceneSaveConfirmStateCrackNonces ?
NfcSceneMfClassicMfkeyComplete :
NfcSceneMfClassicDetectReader;
scene_manager_next_scene(nfc->scene_manager, scene);
consumed = true;
} else if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetType)) {
consumed = scene_manager_search_and_switch_to_another_scene(