diff options
author | gornekich <n.gorbadey@gmail.com> | 2021-07-08 23:41:34 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-08 23:41:34 +0300 |
commit | 20fe544b4f53e637667a17d25c3e4190405aefc9 (patch) | |
tree | d4d5fb6b97fe058263cd71d7f8d1b40039ac25b9 /applications/nfc | |
parent | 9f6e14d0054671135ce4319d001e9397ffeb3c3a (diff) |
[FL-1501] NFC: read Mifare Ultralight (#571)
* nfc: add scripts menu scene
* canvas: add glyph width api
* app_scene: add state to Scene template
* gui: introduce TextBox view
* nfc: add mifare ultralight read scenes
* nfc: add mifare ultralight menu scene
* nfc: fix scene functions declaration
* Gui: use size_t for sizes.
Co-authored-by: あく <alleteam@gmail.com>
Diffstat (limited to 'applications/nfc')
-rwxr-xr-x | applications/nfc/nfc.c | 19 | ||||
-rw-r--r-- | applications/nfc/nfc_device.h | 5 | ||||
-rwxr-xr-x[-rw-r--r--] | applications/nfc/nfc_i.h | 16 | ||||
-rwxr-xr-x | applications/nfc/nfc_worker.c | 5 | ||||
-rwxr-xr-x | applications/nfc/scenes/nfc_scene_mifare_ul_menu.c | 69 | ||||
-rw-r--r-- | applications/nfc/scenes/nfc_scene_mifare_ul_menu.h | 7 | ||||
-rwxr-xr-x | applications/nfc/scenes/nfc_scene_read_mifare_ul.c | 67 | ||||
-rw-r--r-- | applications/nfc/scenes/nfc_scene_read_mifare_ul.h | 7 | ||||
-rwxr-xr-x | applications/nfc/scenes/nfc_scene_read_mifare_ul_success.c | 152 | ||||
-rw-r--r-- | applications/nfc/scenes/nfc_scene_read_mifare_ul_success.h | 7 | ||||
-rwxr-xr-x | applications/nfc/scenes/nfc_scene_scripts_menu.c | 75 | ||||
-rw-r--r-- | applications/nfc/scenes/nfc_scene_scripts_menu.h | 7 | ||||
-rw-r--r-- | applications/nfc/scenes/nfc_scene_start.c | 2 |
13 files changed, 436 insertions, 2 deletions
diff --git a/applications/nfc/nfc.c b/applications/nfc/nfc.c index f41d6386..6bee68c2 100755 --- a/applications/nfc/nfc.c +++ b/applications/nfc/nfc.c @@ -43,6 +43,12 @@ Nfc* nfc_alloc() { view_dispatcher_add_view( nfc->nfc_common.view_dispatcher, NfcViewByteInput, byte_input_get_view(nfc->byte_input)); + // TextBox + nfc->text_box = text_box_alloc(); + view_dispatcher_add_view( + nfc->nfc_common.view_dispatcher, NfcViewTextBox, text_box_get_view(nfc->text_box)); + string_init(nfc->text_box_store); + // Detect nfc->nfc_detect = nfc_detect_alloc(&nfc->nfc_common); view_dispatcher_add_view( @@ -85,6 +91,10 @@ Nfc* nfc_alloc() { nfc->scene_set_sak = nfc_scene_set_sak_alloc(); nfc->scene_set_atqa = nfc_scene_set_atqa_alloc(); nfc->scene_set_uid = nfc_scene_set_uid_alloc(); + nfc->scene_scripts_menu = nfc_scene_scripts_menu_alloc(); + nfc->scene_read_mifare_ul = nfc_scene_read_mifare_ul_alloc(); + nfc->scene_read_mifare_ul_success = nfc_scene_read_mifare_ul_success_alloc(); + nfc->scene_mifare_ul_menu = nfc_scene_mifare_ul_menu_alloc(); view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_start); @@ -114,6 +124,11 @@ void nfc_free(Nfc* nfc) { view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewByteInput); byte_input_free(nfc->byte_input); + // TextBox + view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewTextBox); + text_box_free(nfc->text_box); + string_clear(nfc->text_box_store); + // Detect view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewDetect); nfc_detect_free(nfc->nfc_detect); @@ -154,6 +169,10 @@ void nfc_free(Nfc* nfc) { nfc_scene_set_sak_free(nfc->scene_set_sak); nfc_scene_set_atqa_free(nfc->scene_set_atqa); nfc_scene_set_uid_free(nfc->scene_set_uid); + nfc_scene_scripts_menu_free(nfc->scene_scripts_menu); + nfc_scene_read_mifare_ul_free(nfc->scene_read_mifare_ul); + nfc_scene_read_mifare_ul_success_free(nfc->scene_read_mifare_ul_success); + nfc_scene_mifare_ul_menu_free(nfc->scene_mifare_ul_menu); // View Dispatcher view_dispatcher_free(nfc->nfc_common.view_dispatcher); diff --git a/applications/nfc/nfc_device.h b/applications/nfc/nfc_device.h index 31147259..ac922320 100644 --- a/applications/nfc/nfc_device.h +++ b/applications/nfc/nfc_device.h @@ -6,6 +6,8 @@ #define NFC_DEV_NAME_MAX_LEN 22 #define NFC_FILE_NAME_MAX_LEN 120 +#define NFC_MIFARE_UL_MAX_SIZE 256 + typedef enum { NfcDeviceNfca, NfcDeviceNfcb, @@ -36,6 +38,9 @@ typedef struct { typedef struct { NfcDeviceData nfc_data; + uint8_t full_dump[NFC_MIFARE_UL_MAX_SIZE]; + uint16_t dump_size; + // TODO delete with debug view uint8_t man_block[12]; uint8_t otp[4]; } NfcMifareUlData; diff --git a/applications/nfc/nfc_i.h b/applications/nfc/nfc_i.h index 8d3d3e2b..861dde63 100644..100755 --- a/applications/nfc/nfc_i.h +++ b/applications/nfc/nfc_i.h @@ -18,6 +18,7 @@ #include <gui/modules/popup.h> #include <gui/modules/text_input.h> #include <gui/modules/byte_input.h> +#include <gui/modules/text_box.h> #include "views/nfc_detect.h" #include "views/nfc_emulate.h" @@ -38,6 +39,10 @@ #include "scenes/nfc_scene_set_sak.h" #include "scenes/nfc_scene_set_atqa.h" #include "scenes/nfc_scene_set_uid.h" +#include "scenes/nfc_scene_scripts_menu.h" +#include "scenes/nfc_scene_read_mifare_ul.h" +#include "scenes/nfc_scene_read_mifare_ul_success.h" +#include "scenes/nfc_scene_mifare_ul_menu.h" // TODO delete debug scenes #include "scenes/nfc_scene_debug_menu.h" @@ -55,6 +60,7 @@ struct Nfc { NfcDevice device; char text_store[NFC_TEXT_STORE_SIZE + 1]; + string_t text_box_store; // Nfc Views NfcDetect* nfc_detect; @@ -68,6 +74,7 @@ struct Nfc { Popup* popup; TextInput* text_input; ByteInput* byte_input; + TextBox* text_box; // Scenes AppScene* scene_start; @@ -84,6 +91,10 @@ struct Nfc { AppScene* scene_set_sak; AppScene* scene_set_atqa; AppScene* scene_set_uid; + AppScene* scene_scripts_menu; + AppScene* scene_read_mifare_ul; + AppScene* scene_read_mifare_ul_success; + AppScene* scene_mifare_ul_menu; // TODO delete debug scenes AppScene* scene_debug_menu; @@ -99,6 +110,7 @@ typedef enum { NfcViewPopup, NfcViewTextInput, NfcViewByteInput, + NfcViewTextBox, NfcViewDetect, NfcViewEmulate, NfcViewEmv, @@ -125,6 +137,10 @@ typedef enum { NfcSceneSetSak, NfcSceneSetAtqa, NfcSceneSetUid, + NfcSceneScriptsMenu, + NfcSceneReadMifareUl, + NfcSceneReadMifareUlSuccess, + NfcSceneReadMifareUlMenu, } NfcScene; Nfc* nfc_alloc(); diff --git a/applications/nfc/nfc_worker.c b/applications/nfc/nfc_worker.c index 18e0337a..b23caccc 100755 --- a/applications/nfc/nfc_worker.c +++ b/applications/nfc/nfc_worker.c @@ -383,7 +383,7 @@ void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) { mf_ul_set_default_version(&mf_ul_read); // Reinit device api_hal_nfc_deactivate(); - if(!api_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) { + if(!api_hal_nfc_detect(&dev_list, &dev_cnt, 300, false)) { FURI_LOG_E(NFC_WORKER_TAG, "Lost connection. Restarting search"); continue; } @@ -439,6 +439,9 @@ void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) { result->nfc_data.uid, dev_list[0].dev.nfca.nfcId1, result->nfc_data.uid_len); memcpy(result->man_block, mf_ul_read.dump, 4 * 3); memcpy(result->otp, &mf_ul_read.dump[4 * 3], 4); + result->dump_size = mf_ul_read.pages_readed * 4; + memcpy(result->full_dump, mf_ul_read.dump, result->dump_size); + for(uint8_t i = 0; i < mf_ul_read.pages_readed * 4; i += 4) { printf("Page %2d: ", i / 4); for(uint8_t j = 0; j < 4; j++) { diff --git a/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c b/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c new file mode 100755 index 00000000..298833ec --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c @@ -0,0 +1,69 @@ +#include "nfc_scene_mifare_ul_menu.h" +#include "../nfc_i.h" + +#include <furi.h> + +enum SubmenuIndex { + SubmenuIndexSave, + SubmenuIndexEmulate, +}; + +void nfc_scene_mifare_ul_menu_submenu_callback(void* context, uint32_t index) { + Nfc* nfc = (Nfc*)context; + + view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, index); +} + +const void nfc_scene_mifare_ul_menu_on_enter(void* context) { + Nfc* nfc = (Nfc*)context; + Submenu* submenu = nfc->submenu; + + submenu_add_item( + submenu, "Name and save", SubmenuIndexSave, nfc_scene_mifare_ul_menu_submenu_callback, nfc); + submenu_add_item( + submenu, "Emulate", SubmenuIndexEmulate, nfc_scene_mifare_ul_menu_submenu_callback, nfc); + + view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMenu); +} + +const bool nfc_scene_mifare_ul_menu_on_event(void* context, uint32_t event) { + Nfc* nfc = (Nfc*)context; + + if(event == SubmenuIndexSave) { + view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_not_implemented); + view_dispatcher_send_navigation_event( + nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); + return true; + } else if(event == SubmenuIndexEmulate) { + view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_not_implemented); + view_dispatcher_send_navigation_event( + nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); + return true; + } else if(event == ViewNavigatorEventBack) { + view_dispatcher_send_back_search_scene_event( + nfc->nfc_common.view_dispatcher, NfcSceneStart); + return true; + } + + return false; +} + +const void nfc_scene_mifare_ul_menu_on_exit(void* context) { + Nfc* nfc = (Nfc*)context; + + submenu_clean(nfc->submenu); +} + +AppScene* nfc_scene_mifare_ul_menu_alloc() { + AppScene* scene = furi_alloc(sizeof(AppScene)); + scene->id = NfcSceneReadMifareUlMenu; + scene->on_enter = nfc_scene_mifare_ul_menu_on_enter; + scene->on_event = nfc_scene_mifare_ul_menu_on_event; + scene->on_exit = nfc_scene_mifare_ul_menu_on_exit; + + return scene; +} + +void nfc_scene_mifare_ul_menu_free(AppScene* scene) { + free(scene); +}
\ No newline at end of file diff --git a/applications/nfc/scenes/nfc_scene_mifare_ul_menu.h b/applications/nfc/scenes/nfc_scene_mifare_ul_menu.h new file mode 100644 index 00000000..d757eeb8 --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_mifare_ul_menu.h @@ -0,0 +1,7 @@ +#pragma once + +#include "app_scene.h" + +AppScene* nfc_scene_mifare_ul_menu_alloc(); + +void nfc_scene_mifare_ul_menu_free(AppScene* scene); diff --git a/applications/nfc/scenes/nfc_scene_read_mifare_ul.c b/applications/nfc/scenes/nfc_scene_read_mifare_ul.c new file mode 100755 index 00000000..58763114 --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_read_mifare_ul.c @@ -0,0 +1,67 @@ +#include <nfc/scenes/nfc_scene_read_mifare_ul.h> +#include <furi.h> +#include "../nfc_i.h" + +void nfc_read_mifare_ul_worker_callback(void* context) { + Nfc* nfc = (Nfc*)context; + view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, NfcEventMifareUl); +} + +const void nfc_scene_read_mifare_ul_on_enter(void* context) { + Nfc* nfc = (Nfc*)context; + + // Setup view + Popup* popup = nfc->popup; + popup_set_header(popup, "Detecting\nultralight", 70, 34, AlignLeft, AlignTop); + popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61); + + // Start worker + nfc_worker_start( + nfc->nfc_common.worker, + NfcWorkerStateReadMfUltralight, + &nfc->nfc_common.worker_result, + nfc_read_mifare_ul_worker_callback, + nfc); + view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewPopup); +} + +const bool nfc_scene_read_mifare_ul_on_event(void* context, uint32_t event) { + Nfc* nfc = (Nfc*)context; + + if(event == NfcEventMifareUl) { + nfc->device.data = nfc->nfc_common.worker_result.nfc_detect_data; + view_dispatcher_add_scene( + nfc->nfc_common.view_dispatcher, nfc->scene_read_mifare_ul_success); + view_dispatcher_send_navigation_event( + nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); + return true; + } + return false; +} + +const void nfc_scene_read_mifare_ul_on_exit(void* context) { + Nfc* nfc = (Nfc*)context; + + // Stop worker + nfc_worker_stop(nfc->nfc_common.worker); + + // Clear view + Popup* popup = nfc->popup; + popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); + popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 0, NULL); +} + +AppScene* nfc_scene_read_mifare_ul_alloc() { + AppScene* scene = furi_alloc(sizeof(AppScene)); + scene->id = NfcSceneReadMifareUl; + scene->on_enter = nfc_scene_read_mifare_ul_on_enter; + scene->on_event = nfc_scene_read_mifare_ul_on_event; + scene->on_exit = nfc_scene_read_mifare_ul_on_exit; + + return scene; +} + +void nfc_scene_read_mifare_ul_free(AppScene* scene) { + free(scene); +} diff --git a/applications/nfc/scenes/nfc_scene_read_mifare_ul.h b/applications/nfc/scenes/nfc_scene_read_mifare_ul.h new file mode 100644 index 00000000..19b8e6cb --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_read_mifare_ul.h @@ -0,0 +1,7 @@ +#pragma once + +#include "app_scene.h" + +AppScene* nfc_scene_read_mifare_ul_alloc(); + +void nfc_scene_read_mifare_ul_free(AppScene* scene); diff --git a/applications/nfc/scenes/nfc_scene_read_mifare_ul_success.c b/applications/nfc/scenes/nfc_scene_read_mifare_ul_success.c new file mode 100755 index 00000000..621a45a4 --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_read_mifare_ul_success.c @@ -0,0 +1,152 @@ +#include "nfc_scene_read_mifare_ul_success.h" +#include "../nfc_i.h" + +#include <furi.h> +#include <gui/modules/dialog_ex.h> +#include <gui/view_dispatcher.h> + +#define NFC_SCENE_READ_SUCCESS_SHIFT " " +#define NFC_SCENE_READ_MF_UL_CUSTOM_EVENT (0UL) + +enum { + ReadMifareUlStateShowUID, + ReadMifareUlStateShowData, +}; + +void nfc_scene_read_mifare_ul_success_dialog_callback(DialogExResult result, void* context) { + Nfc* nfc = (Nfc*)context; + + view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, result); +} + +void nfc_scene_read_mifare_ul_success_text_box_callback(void* context) { + Nfc* nfc = (Nfc*)context; + + view_dispatcher_send_custom_event( + nfc->nfc_common.view_dispatcher, NFC_SCENE_READ_MF_UL_CUSTOM_EVENT); +} + +const void nfc_scene_read_mifare_ul_success_on_enter(void* context) { + Nfc* nfc = (Nfc*)context; + + // Clear device name + nfc_device_set_name(&nfc->device, ""); + + // Send notification + notification_message(nfc->notifications, &sequence_success); + + // Setup dialog view + NfcDeviceData* data = + (NfcDeviceData*)&nfc->nfc_common.worker_result.nfc_mifare_ul_data.nfc_data; + DialogEx* dialog_ex = nfc->dialog_ex; + dialog_ex_set_left_button_text(dialog_ex, "Retry"); + dialog_ex_set_right_button_text(dialog_ex, "More"); + dialog_ex_set_center_button_text(dialog_ex, "Data"); + dialog_ex_set_header(dialog_ex, "Mifare Ultralight", 22, 8, AlignLeft, AlignCenter); + dialog_ex_set_icon(dialog_ex, 8, 13, &I_Medium_chip_22x21); + // Display UID + nfc_set_text_store( + nfc, + NFC_SCENE_READ_SUCCESS_SHIFT "ATQA: %02X%02X\n" NFC_SCENE_READ_SUCCESS_SHIFT + "SAK: %02X\nUID: %02X %02X %02X %02X %02X %02X %02X", + data->atqa[0], + data->atqa[1], + data->sak, + data->uid[0], + data->uid[1], + data->uid[2], + data->uid[3], + data->uid[4], + data->uid[5], + data->uid[6]); + dialog_ex_set_text(dialog_ex, nfc->text_store, 8, 16, AlignLeft, AlignTop); + dialog_ex_set_context(dialog_ex, nfc); + dialog_ex_set_result_callback(dialog_ex, nfc_scene_read_mifare_ul_success_dialog_callback); + + // Setup TextBox view + NfcMifareUlData* mf_ul_data = + (NfcMifareUlData*)&nfc->nfc_common.worker_result.nfc_mifare_ul_data; + TextBox* text_box = nfc->text_box; + text_box_set_context(text_box, nfc); + text_box_set_exit_callback(text_box, nfc_scene_read_mifare_ul_success_text_box_callback); + text_box_set_font(text_box, TextBoxFontHex); + for(uint16_t i = 0; i < mf_ul_data->dump_size; i += 2) { + if(!(i % 8) && i) { + string_push_back(nfc->text_box_store, '\n'); + } + string_cat_printf( + nfc->text_box_store, + "%02X%02X ", + mf_ul_data->full_dump[i], + mf_ul_data->full_dump[i + 1]); + } + text_box_set_text(text_box, string_get_cstr(nfc->text_box_store)); + + nfc->scene_read_mifare_ul_success->state = ReadMifareUlStateShowUID; + view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewDialogEx); +} + +const bool nfc_scene_read_mifare_ul_success_on_event(void* context, uint32_t event) { + Nfc* nfc = (Nfc*)context; + + if((nfc->scene_read_mifare_ul_success->state == ReadMifareUlStateShowUID) && + (event == DialogExResultLeft)) { + view_dispatcher_send_navigation_event( + nfc->nfc_common.view_dispatcher, ViewNavigatorEventBack); + return true; + } else if( + (nfc->scene_read_mifare_ul_success->state == ReadMifareUlStateShowUID) && + (event == DialogExResultRight)) { + view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_mifare_ul_menu); + view_dispatcher_send_navigation_event( + nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); + return true; + } else if( + (nfc->scene_read_mifare_ul_success->state == ReadMifareUlStateShowUID) && + (event == DialogExResultCenter)) { + view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewTextBox); + nfc->scene_read_mifare_ul_success->state = ReadMifareUlStateShowData; + return true; + } else if( + (nfc->scene_read_mifare_ul_success->state == ReadMifareUlStateShowData) && + (event == NFC_SCENE_READ_MF_UL_CUSTOM_EVENT)) { + view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewDialogEx); + nfc->scene_read_mifare_ul_success->state = ReadMifareUlStateShowUID; + return true; + } + return false; +} + +const void nfc_scene_read_mifare_ul_success_on_exit(void* context) { + Nfc* nfc = (Nfc*)context; + + // Clean dialog + DialogEx* dialog_ex = nfc->dialog_ex; + dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); + dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); + dialog_ex_set_icon(dialog_ex, 0, 0, NULL); + dialog_ex_set_left_button_text(dialog_ex, NULL); + dialog_ex_set_right_button_text(dialog_ex, NULL); + dialog_ex_set_center_button_text(dialog_ex, NULL); + dialog_ex_set_result_callback(dialog_ex, NULL); + dialog_ex_set_context(dialog_ex, NULL); + + // Clean TextBox + TextBox* text_box = nfc->text_box; + text_box_clean(text_box); + string_clean(nfc->text_box_store); +} + +AppScene* nfc_scene_read_mifare_ul_success_alloc() { + AppScene* scene = furi_alloc(sizeof(AppScene)); + scene->id = NfcSceneReadMifareUlSuccess; + scene->on_enter = nfc_scene_read_mifare_ul_success_on_enter; + scene->on_event = nfc_scene_read_mifare_ul_success_on_event; + scene->on_exit = nfc_scene_read_mifare_ul_success_on_exit; + + return scene; +} + +void nfc_scene_read_mifare_ul_success_free(AppScene* scene) { + free(scene); +} diff --git a/applications/nfc/scenes/nfc_scene_read_mifare_ul_success.h b/applications/nfc/scenes/nfc_scene_read_mifare_ul_success.h new file mode 100644 index 00000000..a8f9e44b --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_read_mifare_ul_success.h @@ -0,0 +1,7 @@ +#pragma once + +#include "app_scene.h" + +AppScene* nfc_scene_read_mifare_ul_success_alloc(); + +void nfc_scene_read_mifare_ul_success_free(AppScene* scene); diff --git a/applications/nfc/scenes/nfc_scene_scripts_menu.c b/applications/nfc/scenes/nfc_scene_scripts_menu.c new file mode 100755 index 00000000..29086f12 --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_scripts_menu.c @@ -0,0 +1,75 @@ +#include "nfc_scene_scripts_menu.h" +#include "../nfc_i.h" + +#include <furi.h> +#include <gui/modules/submenu.h> +#include <gui/view_dispatcher.h> + +enum SubmenuIndex { + SubmenuIndexBankCard, + SubmenuIndexMifareUltralight, +}; + +void nfc_scene_scripts_menu_submenu_callback(void* context, uint32_t index) { + Nfc* nfc = (Nfc*)context; + + view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, index); +} + +const void nfc_scene_scripts_menu_on_enter(void* context) { + Nfc* nfc = (Nfc*)context; + Submenu* submenu = nfc->submenu; + + submenu_add_item( + submenu, + "Read bank card", + SubmenuIndexBankCard, + nfc_scene_scripts_menu_submenu_callback, + nfc); + submenu_add_item( + submenu, + "Read Mifare Ultralight", + SubmenuIndexMifareUltralight, + nfc_scene_scripts_menu_submenu_callback, + nfc); + + view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMenu); +} + +const bool nfc_scene_scripts_menu_on_event(void* context, uint32_t event) { + Nfc* nfc = (Nfc*)context; + + if(event == SubmenuIndexBankCard) { + view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_not_implemented); + view_dispatcher_send_navigation_event( + nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); + return true; + } else if(event == SubmenuIndexMifareUltralight) { + view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_read_mifare_ul); + view_dispatcher_send_navigation_event( + nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); + return true; + } + + return false; +} + +const void nfc_scene_scripts_menu_on_exit(void* context) { + Nfc* nfc = (Nfc*)context; + + submenu_clean(nfc->submenu); +} + +AppScene* nfc_scene_scripts_menu_alloc() { + AppScene* scene = furi_alloc(sizeof(AppScene)); + scene->id = NfcSceneScriptsMenu; + scene->on_enter = nfc_scene_scripts_menu_on_enter; + scene->on_event = nfc_scene_scripts_menu_on_event; + scene->on_exit = nfc_scene_scripts_menu_on_exit; + + return scene; +} + +void nfc_scene_scripts_menu_free(AppScene* scene) { + free(scene); +}
\ No newline at end of file diff --git a/applications/nfc/scenes/nfc_scene_scripts_menu.h b/applications/nfc/scenes/nfc_scene_scripts_menu.h new file mode 100644 index 00000000..8002e568 --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_scripts_menu.h @@ -0,0 +1,7 @@ +#pragma once + +#include "app_scene.h" + +AppScene* nfc_scene_scripts_menu_alloc(); + +void nfc_scene_scripts_menu_free(AppScene* scene); diff --git a/applications/nfc/scenes/nfc_scene_start.c b/applications/nfc/scenes/nfc_scene_start.c index 15c59266..80f497b8 100644 --- a/applications/nfc/scenes/nfc_scene_start.c +++ b/applications/nfc/scenes/nfc_scene_start.c @@ -49,7 +49,7 @@ const bool nfc_scene_start_on_event(void* context, uint32_t event) { nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); return true; } else if(event == SubmenuIndexRunScript) { - view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_not_implemented); + view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_scripts_menu); view_dispatcher_send_navigation_event( nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); return true; |