diff --git a/applications/nfc/nfc_cli.c b/applications/nfc/nfc_cli.c index a2f816e4..0dd212a6 100755 --- a/applications/nfc/nfc_cli.c +++ b/applications/nfc/nfc_cli.c @@ -11,6 +11,9 @@ static void nfc_cli_print_usage() { printf("Cmd list:\r\n"); printf("\tdetect\t - detect nfc device\r\n"); printf("\temulate\t - emulate predefined nfca card\r\n"); + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { + printf("\tfield\t - turn field on\r\n"); + } } void nfc_cli_detect(Cli* cli, string_t args) { @@ -76,6 +79,27 @@ void nfc_cli_emulate(Cli* cli, string_t args) { furi_hal_nfc_deactivate(); } +void nfc_cli_field(Cli* cli, string_t args) { + // Check if nfc worker is not busy + if(furi_hal_nfc_is_busy()) { + printf("Nfc is busy\r\n"); + return; + } + + furi_hal_nfc_exit_sleep(); + furi_hal_nfc_field_on(); + + printf("Field is on. Don't leave device in this mode for too long.\r\n"); + printf("Press Ctrl+C to abort\r\n"); + + while(!cli_cmd_interrupt_received(cli)) { + osDelay(50); + } + + furi_hal_nfc_field_off(); + furi_hal_nfc_deactivate(); +} + static void nfc_cli(Cli* cli, string_t args, void* context) { string_t cmd; string_init(cmd); @@ -94,6 +118,13 @@ static void nfc_cli(Cli* cli, string_t args, void* context) { break; } + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { + if(string_cmp_str(cmd, "field") == 0) { + nfc_cli_field(cli, args); + break; + } + } + nfc_cli_print_usage(); } while(false); diff --git a/applications/nfc/scenes/nfc_scene_config.h b/applications/nfc/scenes/nfc_scene_config.h index 97072ead..f4ccdf0c 100755 --- a/applications/nfc/scenes/nfc_scene_config.h +++ b/applications/nfc/scenes/nfc_scene_config.h @@ -27,3 +27,5 @@ 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) +ADD_SCENE(nfc, debug, Debug) +ADD_SCENE(nfc, field, Field) diff --git a/applications/nfc/scenes/nfc_scene_debug.c b/applications/nfc/scenes/nfc_scene_debug.c new file mode 100644 index 00000000..a8f1e686 --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_debug.c @@ -0,0 +1,54 @@ +#include "../nfc_i.h" + +enum SubmenuDebugIndex { + SubmenuDebugIndexField, + SubmenuDebugIndexApdu, +}; + +void nfc_scene_debug_submenu_callback(void* context, uint32_t index) { + Nfc* nfc = (Nfc*)context; + + view_dispatcher_send_custom_event(nfc->view_dispatcher, index); +} + +void nfc_scene_debug_on_enter(void* context) { + Nfc* nfc = (Nfc*)context; + Submenu* submenu = nfc->submenu; + + submenu_add_item( + submenu, "Field", SubmenuDebugIndexField, nfc_scene_debug_submenu_callback, nfc); + submenu_add_item( + submenu, "Apdu", SubmenuDebugIndexApdu, nfc_scene_debug_submenu_callback, nfc); + + submenu_set_selected_item( + submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneDebug)); + + nfc_device_clear(nfc->dev); + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); +} + +bool nfc_scene_debug_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = (Nfc*)context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuDebugIndexField) { + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneDebug, SubmenuDebugIndexField); + scene_manager_next_scene(nfc->scene_manager, NfcSceneField); + consumed = true; + } else if(event.event == SubmenuDebugIndexApdu) { + scene_manager_set_scene_state( + nfc->scene_manager, NfcSceneDebug, SubmenuDebugIndexApdu); + scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateApduSequence); + consumed = true; + } + } + return consumed; +} + +void nfc_scene_debug_on_exit(void* context) { + Nfc* nfc = (Nfc*)context; + + submenu_reset(nfc->submenu); +} diff --git a/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c b/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c index c9e822e2..1a87ea58 100644 --- a/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c +++ b/applications/nfc/scenes/nfc_scene_emulate_apdu_sequence.c @@ -32,7 +32,5 @@ void nfc_scene_emulate_apdu_sequence_on_exit(void* 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_reset(popup); } diff --git a/applications/nfc/scenes/nfc_scene_field.c b/applications/nfc/scenes/nfc_scene_field.c new file mode 100644 index 00000000..36670387 --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_field.c @@ -0,0 +1,34 @@ +#include "../nfc_i.h" + +void nfc_scene_field_on_enter(void* context) { + Nfc* nfc = (Nfc*)context; + + furi_hal_nfc_field_on(); + + Popup* popup = nfc->popup; + popup_set_header( + popup, + "Field is on\nDon't leave device\nin this mode for too long.", + 64, + 11, + AlignCenter, + AlignTop); + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); + + notification_internal_message(nfc->notifications, &sequence_set_blue_255); +} + +bool nfc_scene_field_on_event(void* context, SceneManagerEvent event) { + return false; +} + +void nfc_scene_field_on_exit(void* context) { + Nfc* nfc = (Nfc*)context; + + notification_internal_message(nfc->notifications, &sequence_reset_blue); + + Popup* popup = nfc->popup; + popup_reset(popup); + + furi_hal_nfc_field_off(); +} diff --git a/applications/nfc/scenes/nfc_scene_start.c b/applications/nfc/scenes/nfc_scene_start.c index 40f3a12e..4c4f1e64 100644 --- a/applications/nfc/scenes/nfc_scene_start.c +++ b/applications/nfc/scenes/nfc_scene_start.c @@ -68,7 +68,7 @@ bool nfc_scene_start_on_event(void* context, SceneManagerEvent event) { consumed = true; } else if(event.event == SubmenuIndexDebug) { scene_manager_set_scene_state(nfc->scene_manager, NfcSceneStart, SubmenuIndexDebug); - scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateApduSequence); + scene_manager_next_scene(nfc->scene_manager, NfcSceneDebug); consumed = true; } }