diff --git a/applications/main/lfrfid/lfrfid.c b/applications/main/lfrfid/lfrfid.c index 85a00eea0..a2bcdcf52 100644 --- a/applications/main/lfrfid/lfrfid.c +++ b/applications/main/lfrfid/lfrfid.c @@ -243,6 +243,27 @@ bool lfrfid_load_key_from_file_select(LfRfid* app) { return result; } +bool lfrfid_load_raw_key_from_file_select(LfRfid* app) { + furi_assert(app); + + DialogsFileBrowserOptions browser_options; + dialog_file_browser_set_basic_options( + &browser_options, LFRFID_APP_RAW_ASK_EXTENSION, &I_125_10px); + browser_options.base_path = LFRFID_APP_FOLDER; + + // Input events and views are managed by file_browser + bool result = + dialog_file_browser_show(app->dialogs, app->file_path, app->file_path, &browser_options); + + if(result) { + // Extract .raw and then .ask + path_extract_filename(app->file_path, app->file_name, true); + path_extract_filename(app->file_name, app->file_name, true); + } + + return result; +} + bool lfrfid_delete_key(LfRfid* app) { furi_assert(app); diff --git a/applications/main/lfrfid/lfrfid_i.h b/applications/main/lfrfid/lfrfid_i.h index 72b061930..86929a14a 100644 --- a/applications/main/lfrfid/lfrfid_i.h +++ b/applications/main/lfrfid/lfrfid_i.h @@ -125,6 +125,8 @@ bool lfrfid_save_key(LfRfid* app); bool lfrfid_load_key_from_file_select(LfRfid* app); +bool lfrfid_load_raw_key_from_file_select(LfRfid* app); + bool lfrfid_delete_key(LfRfid* app); bool lfrfid_load_key_data(LfRfid* app, FuriString* path, bool show_dialog); diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_config.h b/applications/main/lfrfid/scenes/lfrfid_scene_config.h index 10dc46fe6..54b840844 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_config.h +++ b/applications/main/lfrfid/scenes/lfrfid_scene_config.h @@ -22,4 +22,6 @@ ADD_SCENE(lfrfid, raw_info, RawInfo) ADD_SCENE(lfrfid, raw_name, RawName) ADD_SCENE(lfrfid, raw_read, RawRead) ADD_SCENE(lfrfid, raw_success, RawSuccess) +ADD_SCENE(lfrfid, raw_emulate, RawEmulate) +ADD_SCENE(lfrfid, select_raw_key, SelectRawKey) ADD_SCENE(lfrfid, rpc, Rpc) diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c b/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c index efa319c1e..bf73eccd3 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c @@ -6,6 +6,7 @@ typedef enum { SubmenuIndexPSK, SubmenuIndexClearT5577, SubmenuIndexRAW, + SubmenuIndexRAWEmulate, } SubmenuIndex; static void lfrfid_scene_extra_actions_submenu_callback(void* context, uint32_t index) { @@ -44,6 +45,12 @@ void lfrfid_scene_extra_actions_on_enter(void* context) { SubmenuIndexRAW, lfrfid_scene_extra_actions_submenu_callback, app); + submenu_add_item( + submenu, + "Emulate RAW RFID data", + SubmenuIndexRAWEmulate, + lfrfid_scene_extra_actions_submenu_callback, + app); } submenu_set_selected_item( @@ -78,6 +85,9 @@ bool lfrfid_scene_extra_actions_on_event(void* context, SceneManagerEvent event) } else if(event.event == SubmenuIndexRAW) { scene_manager_next_scene(app->scene_manager, LfRfidSceneRawName); consumed = true; + } else if(event.event == SubmenuIndexRAWEmulate) { + scene_manager_next_scene(app->scene_manager, LfRfidSceneSelectRawKey); + consumed = true; } scene_manager_set_scene_state(app->scene_manager, LfRfidSceneExtraActions, event.event); } diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_raw_emulate.c b/applications/main/lfrfid/scenes/lfrfid_scene_raw_emulate.c new file mode 100644 index 000000000..c06a5eebf --- /dev/null +++ b/applications/main/lfrfid/scenes/lfrfid_scene_raw_emulate.c @@ -0,0 +1,86 @@ +#include "../lfrfid_i.h" + +#define TAG "ADC" + +typedef struct { + FuriString* string_file_name; + bool error; +} LfRfidEmulateRawState; + +static void lfrfid_raw_emulate_callback(LFRFIDWorkerEmulateRawResult result, void* context) { + LfRfid* app = context; + + if(result == LFRFIDWorkerEmulateRawFileError) { + view_dispatcher_send_custom_event(app->view_dispatcher, LfRfidEventReadError); + } else if(result == LFRFIDWorkerEmulateRawOverrun) { + view_dispatcher_send_custom_event(app->view_dispatcher, LfRfidEventReadOverrun); + } +} + +void lfrfid_scene_raw_emulate_on_enter(void* context) { + LfRfid* app = context; + Popup* popup = app->popup; + + LfRfidEmulateRawState* state = malloc(sizeof(LfRfidEmulateRawState)); + scene_manager_set_scene_state(app->scene_manager, LfRfidSceneRawEmulate, (uint32_t)state); + state->string_file_name = furi_string_alloc(); + + popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61); + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); + lfrfid_worker_start_thread(app->lfworker); + lfrfid_make_app_folder(app); + + furi_string_printf( + state->string_file_name, + "%s/%s%s", + LFRFID_SD_FOLDER, + furi_string_get_cstr(app->file_name), + LFRFID_APP_RAW_ASK_EXTENSION); + FURI_LOG_D(TAG, "raw_emulate->file_name=%s", furi_string_get_cstr(state->string_file_name)); + popup_set_header(popup, "Emulating\nRAW RFID\nASK", 89, 30, AlignCenter, AlignTop); + lfrfid_worker_emulate_raw_start( + app->lfworker, + furi_string_get_cstr(state->string_file_name), + lfrfid_raw_emulate_callback, + app); + + notification_message(app->notifications, &sequence_blink_start_cyan); + + state->error = false; +} + +bool lfrfid_scene_raw_emulate_on_event(void* context, SceneManagerEvent event) { + LfRfid* app = context; + Popup* popup = app->popup; + LfRfidEmulateRawState* state = (LfRfidEmulateRawState*)scene_manager_get_scene_state( + app->scene_manager, LfRfidSceneRawEmulate); + bool consumed = false; + + furi_assert(state); + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == LfRfidEventReadError) { + consumed = true; + state->error = true; + popup_set_header( + popup, "Reading\nRAW RFID\nFile error", 89, 30, AlignCenter, AlignTop); + notification_message(app->notifications, &sequence_blink_start_red); + } + } + + return consumed; +} + +void lfrfid_scene_raw_emulate_on_exit(void* context) { + LfRfid* app = context; + LfRfidEmulateRawState* state = (LfRfidEmulateRawState*)scene_manager_get_scene_state( + app->scene_manager, LfRfidSceneRawEmulate); + + notification_message(app->notifications, &sequence_blink_stop); + popup_reset(app->popup); + lfrfid_worker_stop(app->lfworker); + lfrfid_worker_stop_thread(app->lfworker); + + furi_string_free(state->string_file_name); + free(state); +} diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_select_raw_key.c b/applications/main/lfrfid/scenes/lfrfid_scene_select_raw_key.c new file mode 100644 index 000000000..f12d280aa --- /dev/null +++ b/applications/main/lfrfid/scenes/lfrfid_scene_select_raw_key.c @@ -0,0 +1,23 @@ +#include "../lfrfid_i.h" + +void lfrfid_scene_select_raw_key_on_enter(void* context) { + LfRfid* app = context; + + if(lfrfid_load_raw_key_from_file_select(app)) { + scene_manager_next_scene(app->scene_manager, LfRfidSceneRawEmulate); + + } else { + scene_manager_previous_scene(app->scene_manager); + } +} + +bool lfrfid_scene_select_raw_key_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + UNUSED(event); + bool consumed = false; + return consumed; +} + +void lfrfid_scene_select_raw_key_on_exit(void* context) { + UNUSED(context); +}