mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-12-12 12:42:30 +04:00
[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:
@@ -14,7 +14,8 @@ enum {
|
|||||||
SubmenuIndexDetectReader = SubmenuIndexCommonMax,
|
SubmenuIndexDetectReader = SubmenuIndexCommonMax,
|
||||||
SubmenuIndexWrite,
|
SubmenuIndexWrite,
|
||||||
SubmenuIndexUpdate,
|
SubmenuIndexUpdate,
|
||||||
SubmenuIndexDictAttack
|
SubmenuIndexDictAttack,
|
||||||
|
SubmenuIndexCrackNonces,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void nfc_scene_info_on_enter_mf_classic(NfcApp* instance) {
|
static void nfc_scene_info_on_enter_mf_classic(NfcApp* instance) {
|
||||||
@@ -128,6 +129,13 @@ static void nfc_scene_read_menu_on_enter_mf_classic(NfcApp* instance) {
|
|||||||
SubmenuIndexDictAttack,
|
SubmenuIndexDictAttack,
|
||||||
nfc_protocol_support_common_submenu_callback,
|
nfc_protocol_support_common_submenu_callback,
|
||||||
instance);
|
instance);
|
||||||
|
|
||||||
|
submenu_add_item(
|
||||||
|
submenu,
|
||||||
|
"Crack nonces in MFKey32",
|
||||||
|
SubmenuIndexCrackNonces,
|
||||||
|
nfc_protocol_support_common_submenu_callback,
|
||||||
|
instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,6 +201,11 @@ static bool nfc_scene_read_menu_on_event_mf_classic(NfcApp* instance, SceneManag
|
|||||||
|
|
||||||
if(event.type == SceneManagerEventTypeCustom) {
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
if(event.event == SubmenuIndexDetectReader) {
|
if(event.event == SubmenuIndexDetectReader) {
|
||||||
|
scene_manager_set_scene_state(
|
||||||
|
instance->scene_manager,
|
||||||
|
NfcSceneSaveConfirm,
|
||||||
|
NfcSceneSaveConfirmStateDetectReader);
|
||||||
|
|
||||||
scene_manager_next_scene(instance->scene_manager, NfcSceneSaveConfirm);
|
scene_manager_next_scene(instance->scene_manager, NfcSceneSaveConfirm);
|
||||||
dolphin_deed(DolphinDeedNfcDetectReader);
|
dolphin_deed(DolphinDeedNfcDetectReader);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
@@ -205,6 +218,11 @@ static bool nfc_scene_read_menu_on_event_mf_classic(NfcApp* instance, SceneManag
|
|||||||
} else if(event.event == SubmenuIndexCommonEdit) {
|
} else if(event.event == SubmenuIndexCommonEdit) {
|
||||||
scene_manager_next_scene(instance->scene_manager, NfcSceneSetUid);
|
scene_manager_next_scene(instance->scene_manager, NfcSceneSetUid);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
|
} else if(event.event == SubmenuIndexCrackNonces) {
|
||||||
|
scene_manager_set_scene_state(
|
||||||
|
instance->scene_manager, NfcSceneSaveConfirm, NfcSceneSaveConfirmStateCrackNonces);
|
||||||
|
scene_manager_next_scene(instance->scene_manager, NfcSceneSaveConfirm);
|
||||||
|
consumed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -470,6 +470,26 @@ static void nfc_show_initial_scene_for_device(NfcApp* nfc) {
|
|||||||
scene_manager_next_scene(nfc->scene_manager, scene);
|
scene_manager_next_scene(nfc->scene_manager, scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nfc_app_run_external(NfcApp* nfc, const char* app_path) {
|
||||||
|
furi_assert(nfc);
|
||||||
|
furi_assert(app_path);
|
||||||
|
|
||||||
|
Loader* loader = furi_record_open(RECORD_LOADER);
|
||||||
|
|
||||||
|
loader_enqueue_launch(loader, app_path, NULL, LoaderDeferredLaunchFlagGui);
|
||||||
|
|
||||||
|
FuriString* self_path = furi_string_alloc();
|
||||||
|
furi_check(loader_get_application_launch_path(loader, self_path));
|
||||||
|
|
||||||
|
loader_enqueue_launch(
|
||||||
|
loader, furi_string_get_cstr(self_path), NULL, LoaderDeferredLaunchFlagGui);
|
||||||
|
furi_string_free(self_path);
|
||||||
|
|
||||||
|
furi_record_close(RECORD_LOADER);
|
||||||
|
|
||||||
|
view_dispatcher_stop(nfc->view_dispatcher);
|
||||||
|
}
|
||||||
|
|
||||||
int32_t nfc_app(void* p) {
|
int32_t nfc_app(void* p) {
|
||||||
if(!nfc_is_hal_ready()) return 0;
|
if(!nfc_is_hal_ready()) return 0;
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include "helpers/felica_auth.h"
|
#include "helpers/felica_auth.h"
|
||||||
#include "helpers/slix_unlock.h"
|
#include "helpers/slix_unlock.h"
|
||||||
|
|
||||||
|
#include <loader/loader.h>
|
||||||
#include <dialogs/dialogs.h>
|
#include <dialogs/dialogs.h>
|
||||||
#include <storage/storage.h>
|
#include <storage/storage.h>
|
||||||
#include <toolbox/path.h>
|
#include <toolbox/path.h>
|
||||||
@@ -80,6 +81,8 @@
|
|||||||
#define NFC_APP_MF_CLASSIC_DICT_SYSTEM_NESTED_PATH \
|
#define NFC_APP_MF_CLASSIC_DICT_SYSTEM_NESTED_PATH \
|
||||||
(NFC_APP_FOLDER "/assets/mf_classic_dict_nested.nfc")
|
(NFC_APP_FOLDER "/assets/mf_classic_dict_nested.nfc")
|
||||||
|
|
||||||
|
#define NFC_MFKEY32_APP_PATH (EXT_PATH("apps/NFC/mfkey.fap"))
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NfcRpcStateIdle,
|
NfcRpcStateIdle,
|
||||||
NfcRpcStateEmulating,
|
NfcRpcStateEmulating,
|
||||||
@@ -167,6 +170,11 @@ typedef enum {
|
|||||||
NfcViewDetectReader,
|
NfcViewDetectReader,
|
||||||
} NfcView;
|
} NfcView;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NfcSceneSaveConfirmStateDetectReader,
|
||||||
|
NfcSceneSaveConfirmStateCrackNonces,
|
||||||
|
} NfcSceneSaveConfirmState;
|
||||||
|
|
||||||
int32_t nfc_task(void* p);
|
int32_t nfc_task(void* p);
|
||||||
|
|
||||||
void nfc_text_store_set(NfcApp* nfc, const char* text, ...);
|
void nfc_text_store_set(NfcApp* nfc, const char* text, ...);
|
||||||
@@ -202,3 +210,5 @@ bool nfc_save_file(NfcApp* instance, FuriString* path);
|
|||||||
void nfc_make_app_folder(NfcApp* instance);
|
void nfc_make_app_folder(NfcApp* instance);
|
||||||
|
|
||||||
void nfc_append_filename_string_when_present(NfcApp* instance, FuriString* string);
|
void nfc_append_filename_string_when_present(NfcApp* instance, FuriString* string);
|
||||||
|
|
||||||
|
void nfc_app_run_external(NfcApp* nfc, const char* app_path);
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
#include "../nfc_app_i.h"
|
#include "../nfc_app_i.h"
|
||||||
|
#include "loader/loader.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NfcSceneMfClassicMfKeyCompleteStateAppMissing,
|
||||||
|
NfcSceneMfClassicMfKeyCompleteStateAppPresent,
|
||||||
|
} NfcSceneMfClassicMfKeyCompleteState;
|
||||||
|
|
||||||
void nfc_scene_mf_classic_mfkey_complete_callback(
|
void nfc_scene_mf_classic_mfkey_complete_callback(
|
||||||
GuiButtonType result,
|
GuiButtonType result,
|
||||||
@@ -15,6 +21,15 @@ void nfc_scene_mf_classic_mfkey_complete_on_enter(void* context) {
|
|||||||
|
|
||||||
widget_add_string_element(
|
widget_add_string_element(
|
||||||
instance->widget, 64, 0, AlignCenter, AlignTop, FontPrimary, "Completed!");
|
instance->widget, 64, 0, AlignCenter, AlignTop, FontPrimary, "Completed!");
|
||||||
|
|
||||||
|
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(
|
widget_add_string_multiline_element(
|
||||||
instance->widget,
|
instance->widget,
|
||||||
64,
|
64,
|
||||||
@@ -30,7 +45,23 @@ void nfc_scene_mf_classic_mfkey_complete_on_enter(void* context) {
|
|||||||
"Finish",
|
"Finish",
|
||||||
nfc_scene_mf_classic_mfkey_complete_callback,
|
nfc_scene_mf_classic_mfkey_complete_callback,
|
||||||
instance);
|
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);
|
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.type == SceneManagerEventTypeCustom) {
|
||||||
if(event.event == GuiButtonTypeRight) {
|
if(event.event == GuiButtonTypeRight) {
|
||||||
|
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(
|
consumed = scene_manager_search_and_switch_to_previous_scene(
|
||||||
instance->scene_manager, NfcSceneStart);
|
instance->scene_manager, NfcSceneStart);
|
||||||
|
} else {
|
||||||
|
nfc_app_run_external(instance, NFC_MFKEY32_APP_PATH);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if(event.type == SceneManagerEventTypeBack) {
|
} else if(event.type == SceneManagerEventTypeBack) {
|
||||||
const uint32_t prev_scenes[] = {NfcSceneSavedMenu, NfcSceneStart};
|
const uint32_t prev_scenes[] = {NfcSceneSavedMenu, NfcSceneStart};
|
||||||
|
|||||||
@@ -29,7 +29,14 @@ bool nfc_scene_save_confirm_on_event(void* context, SceneManagerEvent event) {
|
|||||||
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event.event == DialogExResultLeft) {
|
} 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;
|
consumed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,13 @@ bool nfc_scene_save_success_on_event(void* context, SceneManagerEvent event) {
|
|||||||
consumed = scene_manager_search_and_switch_to_previous_scene(
|
consumed = scene_manager_search_and_switch_to_previous_scene(
|
||||||
nfc->scene_manager, NfcSceneMfClassicKeys);
|
nfc->scene_manager, NfcSceneMfClassicKeys);
|
||||||
} else if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSaveConfirm)) {
|
} 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;
|
consumed = true;
|
||||||
} else if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetType)) {
|
} else if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSetType)) {
|
||||||
consumed = scene_manager_search_and_switch_to_another_scene(
|
consumed = scene_manager_search_and_switch_to_another_scene(
|
||||||
|
|||||||
Reference in New Issue
Block a user