From c40e8811d68e9f4b8f603ae5d5826b814521014d Mon Sep 17 00:00:00 2001 From: gornekich Date: Thu, 28 Jul 2022 15:34:28 +0300 Subject: [PATCH] [FL-2701], [FL-2702], [FL-2699] NFC fixes (#1478) * nfc: change read scene views * nfc: rework return after save success * nfc: add fallback to read UID of unrecognized iso14443-3 * nfc: show mifare desfire on read success * nfc: add restore original confirm scene * nfc: fix icon name * nfc: clear 6 bit in SAK to emulate 14443-4 uids * nfc: don't change original sak --- applications/nfc/scenes/nfc_scene_config.h | 1 + .../nfc_scene_mf_desfire_read_success.c | 14 ++--- applications/nfc/scenes/nfc_scene_read.c | 9 ++- .../nfc/scenes/nfc_scene_restore_original.c | 8 ++- .../nfc_scene_restore_original_confirm.c | 53 ++++++++++++++++++ .../nfc/scenes/nfc_scene_save_success.c | 8 +-- .../nfc/scenes/nfc_scene_saved_menu.c | 23 +++----- assets/icons/NFC/NFC_manual.png | Bin 3785 -> 3804 bytes assets/icons/NFC/Restoring.png | Bin 0 -> 3794 bytes furi/core/common_defines.h | 4 ++ lib/nfc/nfc_worker.c | 11 +++- 11 files changed, 98 insertions(+), 33 deletions(-) create mode 100644 applications/nfc/scenes/nfc_scene_restore_original_confirm.c create mode 100644 assets/icons/NFC/Restoring.png diff --git a/applications/nfc/scenes/nfc_scene_config.h b/applications/nfc/scenes/nfc_scene_config.h index 6e2369fd6..de8de6b40 100755 --- a/applications/nfc/scenes/nfc_scene_config.h +++ b/applications/nfc/scenes/nfc_scene_config.h @@ -30,6 +30,7 @@ ADD_SCENE(nfc, emulate_apdu_sequence, EmulateApduSequence) ADD_SCENE(nfc, device_info, DeviceInfo) ADD_SCENE(nfc, delete, Delete) ADD_SCENE(nfc, delete_success, DeleteSuccess) +ADD_SCENE(nfc, restore_original_confirm, RestoreOriginalConfirm) ADD_SCENE(nfc, restore_original, RestoreOriginal) ADD_SCENE(nfc, debug, Debug) ADD_SCENE(nfc, field, Field) diff --git a/applications/nfc/scenes/nfc_scene_mf_desfire_read_success.c b/applications/nfc/scenes/nfc_scene_mf_desfire_read_success.c index 673b316b4..a04f4e55c 100644 --- a/applications/nfc/scenes/nfc_scene_mf_desfire_read_success.c +++ b/applications/nfc/scenes/nfc_scene_mf_desfire_read_success.c @@ -34,18 +34,12 @@ void nfc_scene_mf_desfire_read_success_on_enter(void* context) { } } + // TODO rework info view nfc_text_store_set( nfc, - "UID: %02X %02X %02X %02X %02X %02X %02X\n" NFC_SCENE_READ_SUCCESS_SHIFT - "%d%s bytes\n" NFC_SCENE_READ_SUCCESS_SHIFT "%d bytes free\n" - "%d application%s, %d file%s", - data->version.uid[0], - data->version.uid[1], - data->version.uid[2], - data->version.uid[3], - data->version.uid[4], - data->version.uid[5], - data->version.uid[6], + NFC_SCENE_READ_SUCCESS_SHIFT "Mifare DESFire\n" NFC_SCENE_READ_SUCCESS_SHIFT + "%d%s bytes\n" NFC_SCENE_READ_SUCCESS_SHIFT "%d bytes free\n" + "%d application%s, %d file%s", 1 << (data->version.sw_storage >> 1), (data->version.sw_storage & 1) ? "+" : "", data->free_memory ? data->free_memory->bytes : 0, diff --git a/applications/nfc/scenes/nfc_scene_read.c b/applications/nfc/scenes/nfc_scene_read.c index 9e1c0109c..491b419ef 100644 --- a/applications/nfc/scenes/nfc_scene_read.c +++ b/applications/nfc/scenes/nfc_scene_read.c @@ -23,12 +23,15 @@ void nfc_scene_read_set_state(Nfc* nfc, NfcSceneReadState state) { uint32_t curr_state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneRead); if(curr_state != state) { if(state == NfcSceneReadStateDetecting) { - popup_set_header(nfc->popup, "Detecting\nNFC card", 90, 24, AlignCenter, AlignTop); - popup_set_icon(nfc->popup, 5, 7, &I_NFC_manual); + popup_reset(nfc->popup); + popup_set_text( + nfc->popup, "Apply card to\nFlipper's back", 97, 24, AlignCenter, AlignTop); + popup_set_icon(nfc->popup, 0, 8, &I_NFC_manual); } else if(state == NfcSceneReadStateReading) { + popup_reset(nfc->popup); popup_set_header( nfc->popup, "Reading card\nDon't move...", 85, 24, AlignCenter, AlignTop); - popup_set_icon(nfc->popup, 19, 23, &A_Loading_24); + popup_set_icon(nfc->popup, 12, 23, &A_Loading_24); } scene_manager_set_scene_state(nfc->scene_manager, NfcSceneRead, state); } diff --git a/applications/nfc/scenes/nfc_scene_restore_original.c b/applications/nfc/scenes/nfc_scene_restore_original.c index 40b59b9eb..3ecf5c048 100644 --- a/applications/nfc/scenes/nfc_scene_restore_original.c +++ b/applications/nfc/scenes/nfc_scene_restore_original.c @@ -25,7 +25,13 @@ bool nfc_scene_restore_original_on_event(void* context, SceneManagerEvent event) if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventViewExit) { - consumed = scene_manager_previous_scene(nfc->scene_manager); + if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSavedMenu)) { + consumed = scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcSceneSavedMenu); + } else { + consumed = scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcSceneStart); + } } } return consumed; diff --git a/applications/nfc/scenes/nfc_scene_restore_original_confirm.c b/applications/nfc/scenes/nfc_scene_restore_original_confirm.c new file mode 100644 index 000000000..70d161dd1 --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_restore_original_confirm.c @@ -0,0 +1,53 @@ +#include "../nfc_i.h" + +void nfc_scene_restore_original_confirm_dialog_callback(DialogExResult result, void* context) { + Nfc* nfc = context; + + view_dispatcher_send_custom_event(nfc->view_dispatcher, result); +} + +void nfc_scene_restore_original_confirm_on_enter(void* context) { + Nfc* nfc = context; + DialogEx* dialog_ex = nfc->dialog_ex; + + dialog_ex_set_header(dialog_ex, "Restore card data?", 64, 0, AlignCenter, AlignTop); + dialog_ex_set_icon(dialog_ex, 5, 15, &I_Restoring); + dialog_ex_set_text( + dialog_ex, "It will be returned\nto its original state.", 47, 21, AlignLeft, AlignTop); + dialog_ex_set_left_button_text(dialog_ex, "Cancel"); + dialog_ex_set_right_button_text(dialog_ex, "Restore"); + dialog_ex_set_context(dialog_ex, nfc); + dialog_ex_set_result_callback(dialog_ex, nfc_scene_restore_original_confirm_dialog_callback); + + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx); +} + +bool nfc_scene_restore_original_confirm_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == DialogExResultRight) { + if(!nfc_device_restore(nfc->dev, true)) { + scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcSceneStart); + } else { + scene_manager_next_scene(nfc->scene_manager, NfcSceneRestoreOriginal); + } + consumed = true; + } else if(event.event == DialogExResultLeft) { + consumed = scene_manager_previous_scene(nfc->scene_manager); + } + } else if(event.type == SceneManagerEventTypeBack) { + consumed = true; + } + + return consumed; +} + +void nfc_scene_restore_original_confirm_on_exit(void* context) { + Nfc* nfc = context; + + // Clean view + dialog_ex_reset(nfc->dialog_ex); +} diff --git a/applications/nfc/scenes/nfc_scene_save_success.c b/applications/nfc/scenes/nfc_scene_save_success.c index 355f4a80e..a3b17451f 100644 --- a/applications/nfc/scenes/nfc_scene_save_success.c +++ b/applications/nfc/scenes/nfc_scene_save_success.c @@ -27,12 +27,12 @@ bool nfc_scene_save_success_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == NfcCustomEventViewExit) { - if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneMfDesfireMenu)) { + if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSavedMenu)) { consumed = scene_manager_search_and_switch_to_previous_scene( - nfc->scene_manager, NfcSceneMfDesfireMenu); + nfc->scene_manager, NfcSceneSavedMenu); } else { - consumed = scene_manager_search_and_switch_to_previous_scene( - nfc->scene_manager, NfcSceneStart); + consumed = scene_manager_search_and_switch_to_another_scene( + nfc->scene_manager, NfcSceneFileSelect); } } } diff --git a/applications/nfc/scenes/nfc_scene_saved_menu.c b/applications/nfc/scenes/nfc_scene_saved_menu.c index 269864ca8..7c390f0b9 100644 --- a/applications/nfc/scenes/nfc_scene_saved_menu.c +++ b/applications/nfc/scenes/nfc_scene_saved_menu.c @@ -2,7 +2,7 @@ enum SubmenuIndex { SubmenuIndexEmulate, - SubmenuIndexEdit, + SubmenuIndexRename, SubmenuIndexDelete, SubmenuIndexInfo, SubmenuIndexRestoreOriginal, @@ -33,10 +33,6 @@ void nfc_scene_saved_menu_on_enter(void* context) { submenu_add_item( submenu, "Emulate", SubmenuIndexEmulate, nfc_scene_saved_menu_submenu_callback, nfc); } - submenu_add_item( - submenu, "Edit UID and Name", SubmenuIndexEdit, nfc_scene_saved_menu_submenu_callback, nfc); - submenu_add_item( - submenu, "Delete", SubmenuIndexDelete, nfc_scene_saved_menu_submenu_callback, nfc); submenu_add_item( submenu, "Info", SubmenuIndexInfo, nfc_scene_saved_menu_submenu_callback, nfc); submenu_set_selected_item( @@ -44,11 +40,15 @@ void nfc_scene_saved_menu_on_enter(void* context) { if(nfc->dev->shadow_file_exist) { submenu_add_item( submenu, - "Restore original", + "Restore to original", SubmenuIndexRestoreOriginal, nfc_scene_saved_menu_submenu_callback, nfc); } + submenu_add_item( + submenu, "Rename", SubmenuIndexRename, nfc_scene_saved_menu_submenu_callback, nfc); + submenu_add_item( + submenu, "Delete", SubmenuIndexDelete, nfc_scene_saved_menu_submenu_callback, nfc); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); } @@ -68,8 +68,8 @@ bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid); } consumed = true; - } else if(event.event == SubmenuIndexEdit) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneSetUid); + } else if(event.event == SubmenuIndexRename) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); consumed = true; } else if(event.event == SubmenuIndexDelete) { scene_manager_next_scene(nfc->scene_manager, NfcSceneDelete); @@ -78,12 +78,7 @@ bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(nfc->scene_manager, NfcSceneDeviceInfo); consumed = true; } else if(event.event == SubmenuIndexRestoreOriginal) { - if(!nfc_device_restore(nfc->dev, true)) { - scene_manager_search_and_switch_to_previous_scene( - nfc->scene_manager, NfcSceneStart); - } else { - scene_manager_next_scene(nfc->scene_manager, NfcSceneRestoreOriginal); - } + scene_manager_next_scene(nfc->scene_manager, NfcSceneRestoreOriginalConfirm); consumed = true; } } diff --git a/assets/icons/NFC/NFC_manual.png b/assets/icons/NFC/NFC_manual.png index d142f0fcf6c043f990efad9cfa7eca1417499b2f..787c0bcfe01755f4dcadcdce004a1a0fcfb06f41 100644 GIT binary patch delta 3207 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 D>k-yK delta 3165 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 QihzabiEAb`My~h%2Me9y#Q*>R diff --git a/assets/icons/NFC/Restoring.png b/assets/icons/NFC/Restoring.png new file mode 100644 index 0000000000000000000000000000000000000000..9e058869f103361416a78a8a8ba614fe12cbfbb5 GIT binary patch literal 3794 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 = NfcDeviceProtocolUnknown; } card_read = true; + } else { + nfc_worker->dev_data->protocol = NfcDeviceProtocolUnknown; + card_read = true; } return card_read; @@ -321,8 +324,14 @@ void nfc_worker_emulate_uid(NfcWorker* nfc_worker) { FuriHalNfcDevData* data = &nfc_worker->dev_data->nfc_data; NfcReaderRequestData* reader_data = &nfc_worker->dev_data->reader_data; + // TODO add support for RATS + // Now remove bit 6 in SAK to support ISO-14443A-3 emulation + // Need to save ATS to support ISO-14443A-4 emulation + uint8_t sak = data->sak; + FURI_BIT_CLEAR(sak, 5); + while(nfc_worker->state == NfcWorkerStateUidEmulate) { - if(furi_hal_nfc_listen(data->uid, data->uid_len, data->atqa, data->sak, true, 100)) { + if(furi_hal_nfc_listen(data->uid, data->uid_len, data->atqa, sak, true, 100)) { if(furi_hal_nfc_tx_rx(&tx_rx, 100)) { reader_data->size = tx_rx.rx_bits / 8; if(reader_data->size > 0) {