Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/flipperzero-firmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgornekich <n.gorbadey@gmail.com>2021-08-17 00:45:04 +0300
committerGitHub <noreply@github.com>2021-08-17 00:45:04 +0300
commitc1223174681f8fa96caee376f502d49886db0355 (patch)
tree632c5d6539e2d91562800c0b67a83b5c67cd43eb /applications/nfc
parente1d80d5402d8b19de7e5a448dc20bc83a50e7bfc (diff)
[FL-1526] Mifare Ultralight emulation (#645)
* rfal: add discovery parameter for passing listen activation * nfc: add discovery parameter to furi_hal_nfc_listen * mifare_ul: add emulation parsing commands * nfc: add mifare ul emulation * nfc: switch to mifare ultralight emulation form menu * furi-hal-nfc: add first frame reception in emulation mode * nfc: change argument check * nfc: rework nfc worker and mifare ul lib * mifare_ul: add write and cnt increment commands * nfc: add card modification check * mifare_ul: add data changed flag * nfc: add shodow files * nfc: add restore original file Co-authored-by: あく <alleteam@gmail.com>
Diffstat (limited to 'applications/nfc')
-rwxr-xr-xapplications/nfc/nfc.c3
-rwxr-xr-xapplications/nfc/nfc_cli.c2
-rwxr-xr-xapplications/nfc/nfc_device.c93
-rw-r--r--applications/nfc/nfc_device.h5
-rwxr-xr-xapplications/nfc/nfc_worker.c55
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_config.h1
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_emulate_mifare_ul.c51
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_mifare_ul_menu.c2
-rw-r--r--applications/nfc/scenes/nfc_scene_restore_original.c48
-rwxr-xr-xapplications/nfc/scenes/nfc_scene_saved_menu.c41
10 files changed, 237 insertions, 64 deletions
diff --git a/applications/nfc/nfc.c b/applications/nfc/nfc.c
index a1f4a19e..5bf788b9 100755
--- a/applications/nfc/nfc.c
+++ b/applications/nfc/nfc.c
@@ -151,9 +151,10 @@ void nfc_text_store_clear(Nfc* nfc) {
int32_t nfc_app(void* p) {
Nfc* nfc = nfc_alloc();
+ char* args = p;
// Check argument and run corresponding scene
- if(p && nfc_device_load(&nfc->dev, p)) {
+ if((*args != '\0') && nfc_device_load(&nfc->dev, p)) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
} else {
scene_manager_next_scene(nfc->scene_manager, NfcSceneStart);
diff --git a/applications/nfc/nfc_cli.c b/applications/nfc/nfc_cli.c
index 8adf5761..e2ddb5ed 100755
--- a/applications/nfc/nfc_cli.c
+++ b/applications/nfc/nfc_cli.c
@@ -64,7 +64,7 @@ void nfc_cli_emulate(Cli* cli, string_t args, void* context) {
};
while(!cli_cmd_interrupt_received(cli)) {
- if(furi_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, 100)) {
+ if(furi_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, false, 100)) {
printf("Reader detected\r\n");
furi_hal_nfc_deactivate();
}
diff --git a/applications/nfc/nfc_device.c b/applications/nfc/nfc_device.c
index bfe0e877..bdb3d547 100755
--- a/applications/nfc/nfc_device.c
+++ b/applications/nfc/nfc_device.c
@@ -8,6 +8,7 @@
static const char* nfc_app_folder = "/any/nfc";
static const char* nfc_app_extension = ".nfc";
+static const char* nfc_app_shadow_extension = ".shd";
static bool nfc_device_read_hex(string_t str, uint8_t* buff, uint16_t len) {
string_strim(str);
@@ -259,7 +260,11 @@ void nfc_device_set_name(NfcDevice* dev, const char* name) {
strlcpy(dev->dev_name, name, NFC_DEV_NAME_MAX_LEN);
}
-bool nfc_device_save(NfcDevice* dev, const char* dev_name) {
+static bool nfc_device_save_file(
+ NfcDevice* dev,
+ const char* dev_name,
+ const char* folder,
+ const char* extension) {
furi_assert(dev);
FileWorker* file_worker = file_worker_alloc(false);
@@ -275,7 +280,7 @@ bool nfc_device_save(NfcDevice* dev, const char* dev_name) {
break;
};
// First remove nfc device file if it was saved
- string_printf(dev_file_name, "%s/%s%s", nfc_app_folder, dev_name, nfc_app_extension);
+ string_printf(dev_file_name, "%s/%s%s", folder, dev_name, extension);
if(!file_worker_remove(file_worker, string_get_cstr(dev_file_name))) {
break;
};
@@ -316,16 +321,42 @@ bool nfc_device_save(NfcDevice* dev, const char* dev_name) {
return true;
}
+bool nfc_device_save(NfcDevice* dev, const char* dev_name) {
+ return nfc_device_save_file(dev, dev_name, nfc_app_folder, nfc_app_extension);
+}
+
+bool nfc_device_save_shadow(NfcDevice* dev, const char* dev_name) {
+ dev->shadow_file_exist = true;
+ return nfc_device_save_file(dev, dev_name, nfc_app_folder, nfc_app_shadow_extension);
+}
+
static bool nfc_device_load_data(FileWorker* file_worker, string_t path, NfcDevice* dev) {
string_t temp_string;
string_init(temp_string);
bool parsed = false;
do {
- // Open key file
- if(!file_worker_open(file_worker, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
+ // Check existance of shadow file
+ size_t ext_start = string_search_str(path, nfc_app_extension);
+ string_set_n(temp_string, path, 0, ext_start);
+ string_cat_printf(temp_string, "%s", nfc_app_shadow_extension);
+ if(!file_worker_is_file_exist(
+ file_worker, string_get_cstr(temp_string), &dev->shadow_file_exist)) {
break;
}
+ // Open shadow file if it exists. If not - open original
+ if(dev->shadow_file_exist) {
+ if(!file_worker_open(
+ file_worker, string_get_cstr(temp_string), FSAM_READ, FSOM_OPEN_EXISTING)) {
+ break;
+ }
+ } else {
+ if(!file_worker_open(
+ file_worker, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
+ break;
+ }
+ }
+
// Read and parse format from 1st line
if(!file_worker_read_until(file_worker, temp_string, '\n')) {
break;
@@ -427,13 +458,61 @@ void nfc_device_clear(NfcDevice* dev) {
bool nfc_device_delete(NfcDevice* dev) {
furi_assert(dev);
- bool result = false;
+ bool result = true;
FileWorker* file_worker = file_worker_alloc(false);
string_t file_path;
- string_init_printf(file_path, "%s/%s%s", nfc_app_folder, dev->dev_name, nfc_app_extension);
- result = file_worker_remove(file_worker, string_get_cstr(file_path));
+
+ do {
+ // Delete original file
+ string_init_printf(file_path, "%s/%s%s", nfc_app_folder, dev->dev_name, nfc_app_extension);
+ if(!file_worker_remove(file_worker, string_get_cstr(file_path))) {
+ result = false;
+ break;
+ }
+ // Delete shadow file if it exists
+ if(dev->shadow_file_exist) {
+ string_clean(file_path);
+ string_printf(
+ file_path, "%s/%s%s", nfc_app_folder, dev->dev_name, nfc_app_shadow_extension);
+ if(!file_worker_remove(file_worker, string_get_cstr(file_path))) {
+ result = false;
+ break;
+ }
+ }
+ } while(0);
+
string_clear(file_path);
file_worker_close(file_worker);
file_worker_free(file_worker);
return result;
}
+
+bool nfc_device_restore(NfcDevice* dev) {
+ furi_assert(dev);
+ furi_assert(dev->shadow_file_exist);
+
+ bool result = true;
+ FileWorker* file_worker = file_worker_alloc(false);
+ string_t path;
+
+ do {
+ string_init_printf(
+ path, "%s/%s%s", nfc_app_folder, dev->dev_name, nfc_app_shadow_extension);
+ if(!file_worker_remove(file_worker, string_get_cstr(path))) {
+ result = false;
+ break;
+ }
+ dev->shadow_file_exist = false;
+ string_clean(path);
+ string_printf(path, "%s/%s%s", nfc_app_folder, dev->dev_name, nfc_app_extension);
+ if(!nfc_device_load_data(file_worker, path, dev)) {
+ result = false;
+ break;
+ }
+ } while(0);
+
+ string_clear(path);
+ file_worker_close(file_worker);
+ file_worker_free(file_worker);
+ return result;
+}
diff --git a/applications/nfc/nfc_device.h b/applications/nfc/nfc_device.h
index c2de3120..25f0e42f 100644
--- a/applications/nfc/nfc_device.h
+++ b/applications/nfc/nfc_device.h
@@ -59,12 +59,15 @@ typedef struct {
char dev_name[NFC_DEV_NAME_MAX_LEN];
char file_name[NFC_FILE_NAME_MAX_LEN];
NfcDeviceSaveFormat format;
+ bool shadow_file_exist;
} NfcDevice;
void nfc_device_set_name(NfcDevice* dev, const char* name);
bool nfc_device_save(NfcDevice* dev, const char* dev_name);
+bool nfc_device_save_shadow(NfcDevice* dev, const char* dev_name);
+
bool nfc_device_load(NfcDevice* dev, const char* file_path);
bool nfc_file_select(NfcDevice* dev);
@@ -72,3 +75,5 @@ bool nfc_file_select(NfcDevice* dev);
void nfc_device_clear(NfcDevice* dev);
bool nfc_device_delete(NfcDevice* dev);
+
+bool nfc_device_restore(NfcDevice* dev);
diff --git a/applications/nfc/nfc_worker.c b/applications/nfc/nfc_worker.c
index 334e6d7b..9fd6dc64 100755
--- a/applications/nfc/nfc_worker.c
+++ b/applications/nfc/nfc_worker.c
@@ -143,7 +143,7 @@ void nfc_worker_detect(NfcWorker* nfc_worker) {
void nfc_worker_emulate(NfcWorker* nfc_worker) {
NfcDeviceCommomData* data = &nfc_worker->dev_data->nfc_data;
while(nfc_worker->state == NfcWorkerStateEmulate) {
- if(furi_hal_nfc_listen(data->uid, data->uid_len, data->atqa, data->sak, 100)) {
+ if(furi_hal_nfc_listen(data->uid, data->uid_len, data->atqa, data->sak, false, 100)) {
FURI_LOG_I(NFC_WORKER_TAG, "Reader detected");
}
osDelay(10);
@@ -406,7 +406,7 @@ void nfc_worker_emulate_apdu(NfcWorker* nfc_worker) {
0x00, 0x00};
while(nfc_worker->state == NfcWorkerStateEmulateApdu) {
- if(furi_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, 300)) {
+ if(furi_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, false, 300)) {
FURI_LOG_I(NFC_WORKER_TAG, "POS terminal detected");
// Read data from POS terminal
err = furi_hal_nfc_data_exchange(NULL, 0, &rx_buff, &rx_len, false);
@@ -608,33 +608,52 @@ void nfc_worker_emulate_mifare_ul(NfcWorker* nfc_worker) {
uint8_t* rx_buff;
uint16_t* rx_len;
NfcDeviceData* data = nfc_worker->dev_data;
-
+ MifareUlDevice mf_ul_emulate;
+ // Setup emulation parameters from mifare ultralight data structure
+ mf_ul_prepare_emulation(&mf_ul_emulate, &data->mf_ul_data);
while(nfc_worker->state == NfcWorkerStateEmulateMifareUl) {
if(furi_hal_nfc_listen(
data->nfc_data.uid,
data->nfc_data.uid_len,
data->nfc_data.atqa,
data->nfc_data.sak,
- 1000)) {
- FURI_LOG_I(NFC_WORKER_TAG, "Hello my dudes");
- // Prepare version answer
- tx_len = sizeof(data->mf_ul_data.version);
- memcpy(tx_buff, &data->mf_ul_data.version, tx_len);
- err = furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
- if(err == ERR_NONE) {
- FURI_LOG_I(NFC_WORKER_TAG, "Received 1st message:");
- for(uint16_t i = 0; i < *rx_len; i++) {
- printf("%02X ", rx_buff[i]);
+ true,
+ 200)) {
+ FURI_LOG_D(NFC_WORKER_TAG, "Anticollision passed");
+ if(furi_hal_nfc_get_first_frame(&rx_buff, &rx_len)) {
+ // Data exchange loop
+ while(nfc_worker->state == NfcWorkerStateEmulateMifareUl) {
+ tx_len = mf_ul_prepare_emulation_response(
+ rx_buff, *rx_len, tx_buff, &mf_ul_emulate);
+ if(tx_len > 0) {
+ err =
+ furi_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false);
+ if(err == ERR_NONE) {
+ continue;
+ } else {
+ FURI_LOG_E(NFC_WORKER_TAG, "Communication error: %d", err);
+ break;
+ }
+ } else {
+ FURI_LOG_W(NFC_WORKER_TAG, "Not valid command: %02X", rx_buff[0]);
+ furi_hal_nfc_deactivate();
+ break;
+ }
}
- printf("\r\n");
} else {
- FURI_LOG_E(NFC_WORKER_TAG, "Error in 1st data exchange: select PPSE");
+ FURI_LOG_W(NFC_WORKER_TAG, "Error in 1st data exchange");
furi_hal_nfc_deactivate();
- continue;
}
}
- FURI_LOG_W(NFC_WORKER_TAG, "Hello my dudes");
- osDelay(10);
+ // Check if data was modified
+ if(mf_ul_emulate.data_changed) {
+ nfc_worker->dev_data->mf_ul_data = mf_ul_emulate.data;
+ if(nfc_worker->callback) {
+ nfc_worker->callback(nfc_worker->context);
+ }
+ }
+ FURI_LOG_W(NFC_WORKER_TAG, "Can't find reader");
+ osThreadYield();
}
}
diff --git a/applications/nfc/scenes/nfc_scene_config.h b/applications/nfc/scenes/nfc_scene_config.h
index 149b4d7f..97072ead 100755
--- a/applications/nfc/scenes/nfc_scene_config.h
+++ b/applications/nfc/scenes/nfc_scene_config.h
@@ -26,3 +26,4 @@ ADD_SCENE(nfc, run_emv_app_confirm, RunEmvAppConfirm)
ADD_SCENE(nfc, read_emv_data, ReadEmvData)
ADD_SCENE(nfc, read_emv_data_success, ReadEmvDataSuccess)
ADD_SCENE(nfc, emulate_apdu_sequence, EmulateApduSequence)
+ADD_SCENE(nfc, restore_original, RestoreOriginal)
diff --git a/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c b/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c
index 7286b7ac..d1d52bef 100755
--- a/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c
+++ b/applications/nfc/scenes/nfc_scene_emulate_mifare_ul.c
@@ -1,38 +1,33 @@
#include "../nfc_i.h"
+#define NFC_MF_UL_DATA_NOT_CHANGED (0UL)
+#define NFC_MF_UL_DATA_CHANGED (1UL)
+
+void nfc_emulate_mifare_ul_worker_callback(void* context) {
+ Nfc* nfc = (Nfc*)context;
+ scene_manager_set_scene_state(
+ nfc->scene_manager, NfcSceneEmulateMifareUl, NFC_MF_UL_DATA_CHANGED);
+}
+
const void nfc_scene_emulate_mifare_ul_on_enter(void* context) {
Nfc* nfc = (Nfc*)context;
// Setup view
Popup* popup = nfc->popup;
- NfcDeviceCommomData* data = &nfc->dev.dev_data.nfc_data;
-
if(strcmp(nfc->dev.dev_name, "")) {
nfc_text_store_set(nfc, "%s", nfc->dev.dev_name);
- } else if(data->uid_len == 4) {
- nfc_text_store_set(
- nfc, "%02X %02X %02X %02X", data->uid[0], data->uid[1], data->uid[2], data->uid[3]);
- } else if(data->uid_len == 7) {
- nfc_text_store_set(
- nfc,
- "%02X %02X %02X %02X\n%02X %02X %02X",
- data->uid[0],
- data->uid[1],
- data->uid[2],
- data->uid[3],
- data->uid[4],
- data->uid[5],
- data->uid[6]);
}
-
popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61);
- popup_set_header(popup, "Emulating Mf Ul", 56, 31, AlignLeft, AlignTop);
- popup_set_text(popup, nfc->text_store, 56, 43, AlignLeft, AlignTop);
+ popup_set_header(popup, "Emulating\nMf Ultralight", 56, 31, AlignLeft, AlignTop);
// Setup and start worker
-
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
- nfc_worker_start(nfc->worker, NfcWorkerStateEmulateMifareUl, &nfc->dev.dev_data, NULL, nfc);
+ nfc_worker_start(
+ nfc->worker,
+ NfcWorkerStateEmulateMifareUl,
+ &nfc->dev.dev_data,
+ nfc_emulate_mifare_ul_worker_callback,
+ nfc);
}
const bool nfc_scene_emulate_mifare_ul_on_event(void* context, SceneManagerEvent event) {
@@ -42,6 +37,17 @@ const bool nfc_scene_emulate_mifare_ul_on_event(void* context, SceneManagerEvent
if(event.type == SceneManagerEventTypeTick) {
notification_message(nfc->notifications, &sequence_blink_blue_10);
consumed = true;
+ } else if(event.type == SceneManagerEventTypeBack) {
+ // Stop worker
+ nfc_worker_stop(nfc->worker);
+ // Check if data changed and save in shadow file
+ if(scene_manager_get_scene_state(nfc->scene_manager, NfcSceneEmulateMifareUl) ==
+ NFC_MF_UL_DATA_CHANGED) {
+ scene_manager_set_scene_state(
+ nfc->scene_manager, NfcSceneEmulateMifareUl, NFC_MF_UL_DATA_NOT_CHANGED);
+ nfc_device_save_shadow(&nfc->dev, nfc->dev.dev_name);
+ }
+ consumed = false;
}
return consumed;
}
@@ -49,9 +55,6 @@ const bool nfc_scene_emulate_mifare_ul_on_event(void* context, SceneManagerEvent
const void nfc_scene_emulate_mifare_ul_on_exit(void* context) {
Nfc* nfc = (Nfc*)context;
- // Stop worker
- nfc_worker_stop(nfc->worker);
-
// Clear view
Popup* popup = nfc->popup;
popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
diff --git a/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c b/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c
index 396c393b..70716618 100755
--- a/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c
+++ b/applications/nfc/scenes/nfc_scene_mifare_ul_menu.c
@@ -38,7 +38,7 @@ const bool nfc_scene_mifare_ul_menu_on_event(void* context, SceneManagerEvent ev
} else if(event.event == SubmenuIndexEmulate) {
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneMifareUlMenu, SubmenuIndexEmulate);
- scene_manager_next_scene(nfc->scene_manager, NfcSceneNotImplemented);
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareUl);
return true;
}
} else if(event.type == SceneManagerEventTypeBack) {
diff --git a/applications/nfc/scenes/nfc_scene_restore_original.c b/applications/nfc/scenes/nfc_scene_restore_original.c
new file mode 100644
index 00000000..3229d023
--- /dev/null
+++ b/applications/nfc/scenes/nfc_scene_restore_original.c
@@ -0,0 +1,48 @@
+#include "../nfc_i.h"
+
+#define SCENE_RESTORE_ORIGINAL_CUSTOM_EVENT (0UL)
+
+void nfc_scene_restore_original_popup_callback(void* context) {
+ Nfc* nfc = (Nfc*)context;
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, SCENE_RESTORE_ORIGINAL_CUSTOM_EVENT);
+}
+
+const void nfc_scene_restore_original_on_enter(void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ // Setup view
+ Popup* popup = nfc->popup;
+ popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
+ popup_set_header(popup, "Original file\nrestored", 13, 22, AlignLeft, AlignBottom);
+ popup_set_timeout(popup, 1500);
+ popup_set_context(popup, nfc);
+ popup_set_callback(popup, nfc_scene_restore_original_popup_callback);
+ popup_enable_timeout(popup);
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
+}
+
+const bool nfc_scene_restore_original_on_event(void* context, SceneManagerEvent event) {
+ Nfc* nfc = (Nfc*)context;
+ bool consumed = false;
+
+ if(event.type == SceneManagerEventTypeCustom) {
+ if(event.event == SCENE_RESTORE_ORIGINAL_CUSTOM_EVENT) {
+ consumed = scene_manager_previous_scene(nfc->scene_manager);
+ }
+ }
+ return consumed;
+}
+
+const void nfc_scene_restore_original_on_exit(void* context) {
+ Nfc* nfc = (Nfc*)context;
+
+ // 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);
+ popup_set_callback(popup, NULL);
+ popup_set_context(popup, NULL);
+ popup_set_timeout(popup, 0);
+ popup_disable_timeout(popup);
+}
diff --git a/applications/nfc/scenes/nfc_scene_saved_menu.c b/applications/nfc/scenes/nfc_scene_saved_menu.c
index 24d03fbc..cd682783 100755
--- a/applications/nfc/scenes/nfc_scene_saved_menu.c
+++ b/applications/nfc/scenes/nfc_scene_saved_menu.c
@@ -5,6 +5,7 @@ enum SubmenuIndex {
SubmenuIndexEdit,
SubmenuIndexDelete,
SubmenuIndexInfo,
+ SubmenuIndexRestoreOriginal,
};
void nfc_scene_saved_menu_submenu_callback(void* context, uint32_t index) {
@@ -29,36 +30,52 @@ const void nfc_scene_saved_menu_on_enter(void* context) {
submenu, "Info", SubmenuIndexInfo, nfc_scene_saved_menu_submenu_callback, nfc);
submenu_set_selected_item(
nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneSavedMenu));
+ if(nfc->dev.shadow_file_exist) {
+ submenu_add_item(
+ submenu,
+ "Restore original",
+ SubmenuIndexRestoreOriginal,
+ nfc_scene_saved_menu_submenu_callback,
+ nfc);
+ }
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu);
}
const bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = (Nfc*)context;
+ bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
+ scene_manager_set_scene_state(nfc->scene_manager, NfcSceneSavedMenu, event.event);
if(event.event == SubmenuIndexEmulate) {
- scene_manager_set_scene_state(
- nfc->scene_manager, NfcSceneSavedMenu, SubmenuIndexEmulate);
- scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
- return true;
+ if(nfc->dev.format == NfcDeviceSaveFormatMifareUl) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateMifareUl);
+ } else {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
+ }
+ consumed = true;
} else if(event.event == SubmenuIndexEdit) {
- scene_manager_set_scene_state(nfc->scene_manager, NfcSceneSavedMenu, SubmenuIndexEdit);
scene_manager_next_scene(nfc->scene_manager, NfcSceneSetUid);
- return true;
+ consumed = true;
} else if(event.event == SubmenuIndexDelete) {
- scene_manager_set_scene_state(
- nfc->scene_manager, NfcSceneSavedMenu, SubmenuIndexDelete);
scene_manager_next_scene(nfc->scene_manager, NfcSceneDelete);
- return true;
+ consumed = true;
} else if(event.event == SubmenuIndexInfo) {
- scene_manager_set_scene_state(nfc->scene_manager, NfcSceneSavedMenu, SubmenuIndexInfo);
scene_manager_next_scene(nfc->scene_manager, NfcSceneDeviceInfo);
- return true;
+ consumed = true;
+ } else if(event.event == SubmenuIndexRestoreOriginal) {
+ if(!nfc_device_restore(&nfc->dev)) {
+ scene_manager_search_and_switch_to_previous_scene(
+ nfc->scene_manager, NfcSceneStart);
+ } else {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneRestoreOriginal);
+ }
+ consumed = true;
}
}
- return false;
+ return consumed;
}
const void nfc_scene_saved_menu_on_exit(void* context) {