diff --git a/base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller.c b/base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller.c index 865e51ef..bb724369 100644 --- a/base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller.c +++ b/base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller.c @@ -181,6 +181,8 @@ NfcCommand gen4_poller_request_mode_handler(Gen4Poller* instance) { instance->state = Gen4PollerStateGetRevision; } else if(instance->gen4_event_data.request_mode.mode == Gen4PollerModeSetShadowMode) { instance->state = Gen4PollerStateSetShadowMode; + } else if(instance->gen4_event_data.request_mode.mode == Gen4PollerModeSetDirectWriteBlock0Mode) { + instance->state = Gen4PollerStateSetDirectWriteBlock0; } else { instance->state = Gen4PollerStateFail; } @@ -273,13 +275,13 @@ static NfcCommand gen4_poller_write_mf_classic(Gen4Poller* instance) { break; } - instance->config[6] = Gen4PollerShadowModeIgnore; + instance->config[6] = Gen4PollerShadowModeDisabled; instance->config[24] = iso3_data->atqa[0]; instance->config[25] = iso3_data->atqa[1]; instance->config[26] = iso3_data->sak; instance->config[27] = 0x00; instance->config[28] = instance->total_blocks; - instance->config[29] = 0x01; + instance->config[29] = Gen4PollerDirectWriteBlock0ModeDisabled; Gen4PollerError error = gen4_poller_set_config( instance, instance->password, instance->config, sizeof(instance->config), false); @@ -352,13 +354,13 @@ static NfcCommand gen4_poller_write_mf_ultralight(Gen4Poller* instance) { break; } - instance->config[6] = Gen4PollerShadowModeHighSpeedIgnore; + instance->config[6] = Gen4PollerShadowModeHighSpeedDisabled; instance->config[24] = iso3_data->atqa[0]; instance->config[25] = iso3_data->atqa[1]; instance->config[26] = iso3_data->sak; instance->config[27] = 0x00; instance->config[28] = instance->total_blocks; - instance->config[29] = 0x01; + instance->config[29] = Gen4PollerDirectWriteBlock0ModeDisabled; Gen4PollerError error = gen4_poller_set_config( instance, instance->password, instance->config, sizeof(instance->config), false); @@ -557,6 +559,25 @@ NfcCommand gen4_poller_set_shadow_mode_handler(Gen4Poller* instance) { return command; } +NfcCommand gen4_poller_set_direct_write_block_0_mode_handler(Gen4Poller* instance) { + NfcCommand command = NfcCommandContinue; + + do { + Gen4PollerError error = gen4_poller_set_direct_write_block_0_mode( + instance, instance->password, instance->direct_write_block_0_mode); + + if(error != Gen4PollerErrorNone) { + FURI_LOG_E(TAG, "Failed to set direct write to block 0 mode: %d", error); + instance->state = Gen4PollerStateFail; + break; + } + + instance->state = Gen4PollerStateSuccess; + } while(false); + + return command; +} + NfcCommand gen4_poller_success_handler(Gen4Poller* instance) { NfcCommand command = NfcCommandContinue; @@ -592,6 +613,7 @@ static const Gen4PollerStateHandler gen4_poller_state_handlers[Gen4PollerStateNu [Gen4PollerStateGetCurrentConfig] = gen4_poller_get_current_cfg_handler, [Gen4PollerStateGetRevision] = gen4_poller_get_revision_handler, [Gen4PollerStateSetShadowMode] = gen4_poller_set_shadow_mode_handler, + [Gen4PollerStateSetDirectWriteBlock0] = gen4_poller_set_direct_write_block_0_mode_handler, [Gen4PollerStateSuccess] = gen4_poller_success_handler, [Gen4PollerStateFail] = gen4_poller_fail_handler, diff --git a/base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller.h b/base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller.h index c5bd79a5..94c0c56d 100644 --- a/base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller.h +++ b/base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller.h @@ -42,6 +42,7 @@ typedef enum { Gen4PollerModeGetCfg, Gen4PollerModeGetRevision, Gen4PollerModeSetShadowMode, + Gen4PollerModeSetDirectWriteBlock0Mode } Gen4PollerMode; typedef struct { diff --git a/base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller_i.c b/base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller_i.c index f365cba5..22f77f75 100644 --- a/base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller_i.c +++ b/base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller_i.c @@ -1,10 +1,9 @@ #include "gen4_poller_i.h" #include "bit_buffer.h" -#include "core/log.h" +#include "protocols/gen4/gen4_poller.h" #include #include -#include #define GEN4_CMD_PREFIX (0xCF) @@ -13,13 +12,16 @@ #define GEN4_CMD_GET_REVISION (0xCC) #define GEN4_CMD_WRITE (0xCD) #define GEN4_CMD_READ (0xCE) +#define GEN4_CMD_SET_DW_BLOCK_0 (0xCF) #define GEN4_CMD_SET_CFG (0xF0) #define GEN4_CMD_FUSE_CFG (0xF1) #define GEN4_CMD_SET_PWD (0xFE) -#define CONFIG_SIZE (32) +#define GEM4_RESPONSE_SUCCESS (0x02) + +#define CONFIG_SIZE_MAX (32) +#define CONFIG_SIZE_MIN (30) #define REVISION_SIZE (5) -#define SHD_MODE_RESPONSE_SIZE (2) static Gen4PollerError gen4_poller_process_error(Iso14443_3aError error) { Gen4PollerError ret = Gen4PollerErrorNone; @@ -33,8 +35,10 @@ static Gen4PollerError gen4_poller_process_error(Iso14443_3aError error) { return ret; } -Gen4PollerError - gen4_poller_set_shadow_mode(Gen4Poller* instance, uint32_t password, uint8_t mode) { +Gen4PollerError gen4_poller_set_shadow_mode( + Gen4Poller* instance, + uint32_t password, + Gen4PollerShadowMode mode) { Gen4PollerError ret = Gen4PollerErrorNone; bit_buffer_reset(instance->tx_buffer); @@ -54,14 +58,51 @@ Gen4PollerError break; } - size_t rx_bytes = bit_buffer_get_size_bytes(instance->rx_buffer); - if(rx_bytes != SHD_MODE_RESPONSE_SIZE) { + uint16_t response = bit_buffer_get_size_bytes(instance->rx_buffer); + + FURI_LOG_D(TAG, "Card response: 0x%02X, Shadow mode set: 0x%02X", response, mode); + + if(response != GEM4_RESPONSE_SUCCESS) { ret = Gen4PollerErrorProtocol; break; } + + } while(false); + + return ret; +} + +Gen4PollerError gen4_poller_set_direct_write_block_0_mode( + Gen4Poller* instance, + uint32_t password, + Gen4PollerDirectWriteBlock0Mode mode) { + Gen4PollerError ret = Gen4PollerErrorNone; + bit_buffer_reset(instance->tx_buffer); + + do { + uint8_t password_arr[4] = {}; + nfc_util_num2bytes(password, COUNT_OF(password_arr), password_arr); + bit_buffer_append_byte(instance->tx_buffer, GEN4_CMD_PREFIX); + bit_buffer_append_bytes(instance->tx_buffer, password_arr, COUNT_OF(password_arr)); + bit_buffer_append_byte(instance->tx_buffer, GEN4_CMD_SET_DW_BLOCK_0); + bit_buffer_append_byte(instance->tx_buffer, mode); + + Iso14443_3aError error = iso14443_3a_poller_send_standard_frame( + instance->iso3_poller, instance->tx_buffer, instance->rx_buffer, GEN4_POLLER_MAX_FWT); + + if(error != Iso14443_3aErrorNone) { + ret = gen4_poller_process_error(error); + break; + } uint16_t response = bit_buffer_get_size_bytes(instance->rx_buffer); - FURI_LOG_D(TAG, "Card response: %X, Shadow mode set: %u", response, mode); + FURI_LOG_D( + TAG, "Card response: 0x%02X, Direct write to block 0 mode set: 0x%02X", response, mode); + + if(response != GEM4_RESPONSE_SUCCESS) { + ret = Gen4PollerErrorProtocol; + break; + } } while(false); @@ -90,11 +131,11 @@ Gen4PollerError size_t rx_bytes = bit_buffer_get_size_bytes(instance->rx_buffer); - if(rx_bytes != CONFIG_SIZE) { + if(rx_bytes != CONFIG_SIZE_MAX || rx_bytes != CONFIG_SIZE_MIN) { ret = Gen4PollerErrorProtocol; break; } - bit_buffer_write_bytes(instance->rx_buffer, config_result, CONFIG_SIZE); + bit_buffer_write_bytes(instance->rx_buffer, config_result, CONFIG_SIZE_MAX); } while(false); return ret; @@ -157,8 +198,11 @@ Gen4PollerError gen4_poller_set_config( break; } - size_t rx_bytes = bit_buffer_get_size_bytes(instance->rx_buffer); - if(rx_bytes != 2) { + uint16_t response = bit_buffer_get_size_bytes(instance->rx_buffer); + + FURI_LOG_D(TAG, "Card response to set default config command: 0x%02X", response); + + if(response != GEM4_RESPONSE_SUCCESS) { ret = Gen4PollerErrorProtocol; break; } @@ -225,8 +269,16 @@ Gen4PollerError break; } - size_t rx_bytes = bit_buffer_get_size_bytes(instance->rx_buffer); - if(rx_bytes != 2) { + uint16_t response = bit_buffer_get_size_bytes(instance->rx_buffer); + + FURI_LOG_D( + TAG, + "Trying to change password from 0x%08lX to 0x%08lX. Card response: 0x%02X", + pwd_current, + pwd_new, + response); + + if(response != GEM4_RESPONSE_SUCCESS) { ret = Gen4PollerErrorProtocol; break; } diff --git a/base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller_i.h b/base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller_i.h index a217558e..03326b7a 100644 --- a/base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller_i.h +++ b/base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller_i.h @@ -37,12 +37,23 @@ typedef enum { Gen4PollerShadowModePreWrite = 0x00, // written data can be read once before restored to original Gen4PollerShadowModeRestore = 0x01, - // written data is discarded - Gen4PollerShadowModeIgnore = 0x02, + // shadow mode disabled + Gen4PollerShadowModeDisabled = 0x02, // apparently for UL? - Gen4PollerShadowModeHighSpeedIgnore = 0x03 + Gen4PollerShadowModeHighSpeedDisabled = 0x03, + // work with new UMC. With old UMC is untested + Gen4PollerShadowModeSplit = 0x04, } Gen4PollerShadowMode; +typedef enum { + // gen2 card behavour + Gen4PollerDirectWriteBlock0ModeEnabled = 0x00, + // common card behavour + Gen4PollerDirectWriteBlock0ModeDisabled = 0x01, + // default mode. same behavour as Gen4PollerDirectWriteBlock0ModeActivate + Gen4PollerDirectWriteBlock0ModeDefault = 0x02, +} Gen4PollerDirectWriteBlock0Mode; + typedef enum { Gen4PollerStateIdle, Gen4PollerStateRequestMode, @@ -55,6 +66,7 @@ typedef enum { Gen4PollerStateGetCurrentConfig, Gen4PollerStateGetRevision, Gen4PollerStateSetShadowMode, + Gen4PollerStateSetDirectWriteBlock0, Gen4PollerStateSuccess, Gen4PollerStateFail, @@ -80,7 +92,8 @@ struct Gen4Poller { uint8_t config[GEN4_POLLER_CONFIG_SIZE_MAX]; - uint8_t shadow_mode; + Gen4PollerShadowMode shadow_mode; + Gen4PollerDirectWriteBlock0Mode direct_write_block_0_mode; Gen4PollerEvent gen4_event; Gen4PollerEventData gen4_event_data; @@ -111,7 +124,13 @@ Gen4PollerError Gen4PollerError gen4_poller_get_config(Gen4Poller* instance, uint32_t password, uint8_t* config_result); -Gen4PollerError gen4_poller_set_shadow_mode(Gen4Poller* instance, uint32_t password, uint8_t mode); +Gen4PollerError + gen4_poller_set_shadow_mode(Gen4Poller* instance, uint32_t password, Gen4PollerShadowMode mode); + +Gen4PollerError gen4_poller_set_direct_write_block_0_mode( + Gen4Poller* instance, + uint32_t password, + Gen4PollerDirectWriteBlock0Mode mode); #ifdef __cplusplus } diff --git a/base_pack/nfc_magic/scenes/nfc_magic_scene_config.h b/base_pack/nfc_magic/scenes/nfc_magic_scene_config.h index ea1de967..a9e1f80c 100644 --- a/base_pack/nfc_magic/scenes/nfc_magic_scene_config.h +++ b/base_pack/nfc_magic/scenes/nfc_magic_scene_config.h @@ -12,6 +12,8 @@ ADD_SCENE(nfc_magic, gen4_show_rev, Gen4ShowRev) ADD_SCENE(nfc_magic, gen4_show_cfg, Gen4ShowCfg) ADD_SCENE(nfc_magic, gen4_select_shd_mode, Gen4SelectShdMode) ADD_SCENE(nfc_magic, gen4_set_shd_mode, Gen4SetShdMode) +ADD_SCENE(nfc_magic, gen4_select_direct_write_block_0_mode, Gen4SelectDirectWriteBlock0Mode) +ADD_SCENE(nfc_magic, gen4_set_direct_write_block_0_mode, Gen4SetDirectWriteBlock0Mode) ADD_SCENE(nfc_magic, gen4_fail, Gen4Fail) ADD_SCENE(nfc_magic, wipe, Wipe) ADD_SCENE(nfc_magic, wipe_fail, WipeFail) diff --git a/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_menu.c b/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_menu.c index 9f9957d5..2ac97a6a 100644 --- a/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_menu.c +++ b/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_menu.c @@ -5,6 +5,7 @@ enum SubmenuIndex { SubmenuIndexWrite, SubmenuIndexChangePassword, SubmenuIndexSetShadowMode, + SubmenuIndexSetDirectWriteBlock0Mode, SubmenuIndexGetRevision, SubmenuIndexGetConfig, SubmenuIndexWipe, @@ -34,6 +35,12 @@ void nfc_magic_scene_gen4_menu_on_enter(void* context) { SubmenuIndexSetShadowMode, nfc_magic_scene_gen4_menu_submenu_callback, instance); + submenu_add_item( + submenu, + "Set Gen2 Mode", + SubmenuIndexSetDirectWriteBlock0Mode, + nfc_magic_scene_gen4_menu_submenu_callback, + instance); submenu_add_item( submenu, "Get Revision", @@ -79,6 +86,10 @@ bool nfc_magic_scene_gen4_menu_on_event(void* context, SceneManagerEvent event) } else if(event.event == SubmenuIndexSetShadowMode) { scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen4SelectShdMode); consumed = true; + } else if(event.event == SubmenuIndexSetDirectWriteBlock0Mode) { + scene_manager_next_scene( + instance->scene_manager, NfcMagicSceneGen4SelectDirectWriteBlock0Mode); + consumed = true; } scene_manager_set_scene_state(instance->scene_manager, NfcMagicSceneGen4Menu, event.event); diff --git a/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_select_direct_write_block_0_mode.c b/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_select_direct_write_block_0_mode.c new file mode 100644 index 00000000..bf45401f --- /dev/null +++ b/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_select_direct_write_block_0_mode.c @@ -0,0 +1,96 @@ +#include "../nfc_magic_app_i.h" +#include "furi_hal_rtc.h" +#include "protocols/gen4/gen4_poller_i.h" + +enum SubmenuIndex { + SubmenuIndexEnable, + SubmenuIndexDisable, + SubmenuIndexDefault, +}; + +void nfc_magic_scene_gen4_select_direct_write_block_0_mode_submenu_callback( + void* context, + uint32_t index) { + NfcMagicApp* instance = context; + + view_dispatcher_send_custom_event(instance->view_dispatcher, index); +} + +void nfc_magic_scene_gen4_select_direct_write_block_0_mode_on_enter(void* context) { + NfcMagicApp* instance = context; + + Submenu* submenu = instance->submenu; + submenu_add_item( + submenu, + "Enable", + SubmenuIndexEnable, + nfc_magic_scene_gen4_select_direct_write_block_0_mode_submenu_callback, + instance); + submenu_add_item( + submenu, + "Disable", + SubmenuIndexDisable, + nfc_magic_scene_gen4_select_direct_write_block_0_mode_submenu_callback, + instance); + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { + submenu_add_item( + submenu, + "Default", + SubmenuIndexDefault, + nfc_magic_scene_gen4_select_direct_write_block_0_mode_submenu_callback, + instance); + } + submenu_set_selected_item( + submenu, + scene_manager_get_scene_state( + instance->scene_manager, NfcMagicSceneGen4SelectDirectWriteBlock0Mode)); + view_dispatcher_switch_to_view(instance->view_dispatcher, NfcMagicAppViewMenu); +} + +bool nfc_magic_scene_gen4_select_direct_write_block_0_mode_on_event( + void* context, + SceneManagerEvent event) { + NfcMagicApp* instance = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuIndexEnable) { + scene_manager_set_scene_state( + instance->scene_manager, + NfcMagicSceneGen4SetDirectWriteBlock0Mode, + Gen4PollerDirectWriteBlock0ModeEnabled); + scene_manager_next_scene( + instance->scene_manager, NfcMagicSceneGen4SetDirectWriteBlock0Mode); + consumed = true; + } else if(event.event == SubmenuIndexDisable) { + scene_manager_set_scene_state( + instance->scene_manager, + NfcMagicSceneGen4SetDirectWriteBlock0Mode, + Gen4PollerDirectWriteBlock0ModeDisabled); + scene_manager_next_scene( + instance->scene_manager, NfcMagicSceneGen4SetDirectWriteBlock0Mode); + consumed = true; + } else if(event.event == SubmenuIndexDefault) { + scene_manager_set_scene_state( + instance->scene_manager, + NfcMagicSceneGen4SetDirectWriteBlock0Mode, + Gen4PollerDirectWriteBlock0ModeDefault); + scene_manager_next_scene( + instance->scene_manager, NfcMagicSceneGen4SetDirectWriteBlock0Mode); + consumed = true; + } + scene_manager_set_scene_state( + instance->scene_manager, NfcMagicSceneGen4SelectDirectWriteBlock0Mode, event.event); + } else if(event.type == SceneManagerEventTypeBack) { + consumed = scene_manager_search_and_switch_to_previous_scene( + instance->scene_manager, NfcMagicSceneGen4ActionsMenu); + } + + return consumed; +} + +void nfc_magic_scene_gen4_select_direct_write_block_0_mode_on_exit(void* context) { + NfcMagicApp* instance = context; + + submenu_reset(instance->submenu); +} diff --git a/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_select_shd_mode.c b/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_select_shd_mode.c index a322a1d0..b4049237 100644 --- a/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_select_shd_mode.c +++ b/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_select_shd_mode.c @@ -1,13 +1,6 @@ #include "../nfc_magic_app_i.h" +#include "protocols/gen4/gen4_poller_i.h" -/* SHADOW MODES DESCRIPTION: - 00: pre-write, shadow data can be written - 01: restore mode - WARNING: new UMC (06a0) cards return garbage data when using 01 - 02: disabled - 03: disabled, high speed R/W mode for Ultralight? - 04: split mode, work with new UMC. With old UMC is untested. -*/ enum SubmenuIndex { SubmenuIndexPreWriteMode, SubmenuIndexRestoreMode, @@ -70,29 +63,33 @@ bool nfc_magic_scene_gen4_select_shd_mode_on_event(void* context, SceneManagerEv if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubmenuIndexPreWriteMode) { scene_manager_set_scene_state( - instance->scene_manager, NfcMagicSceneGen4SetShdMode, SubmenuIndexPreWriteMode); + instance->scene_manager, + NfcMagicSceneGen4SetShdMode, + Gen4PollerShadowModePreWrite); scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen4SetShdMode); consumed = true; } else if(event.event == SubmenuIndexRestoreMode) { scene_manager_set_scene_state( - instance->scene_manager, NfcMagicSceneGen4SetShdMode, SubmenuIndexRestoreMode); + instance->scene_manager, NfcMagicSceneGen4SetShdMode, Gen4PollerShadowModeRestore); scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen4SetShdMode); consumed = true; } else if(event.event == SubmenuIndexDisable) { scene_manager_set_scene_state( - instance->scene_manager, NfcMagicSceneGen4SetShdMode, SubmenuIndexDisable); + instance->scene_manager, + NfcMagicSceneGen4SetShdMode, + Gen4PollerShadowModeDisabled); scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen4SetShdMode); consumed = true; } else if(event.event == SubmenuIndexDisableHighSpeed) { scene_manager_set_scene_state( instance->scene_manager, NfcMagicSceneGen4SetShdMode, - SubmenuIndexDisableHighSpeed); + Gen4PollerShadowModeHighSpeedDisabled); scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen4SetShdMode); consumed = true; } else if(event.event == SubmenuIndexSplitMode) { scene_manager_set_scene_state( - instance->scene_manager, NfcMagicSceneGen4SetShdMode, SubmenuIndexSplitMode); + instance->scene_manager, NfcMagicSceneGen4SetShdMode, Gen4PollerShadowModeSplit); scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen4SetShdMode); consumed = true; } diff --git a/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_set_direct_write_block_0_mode.c b/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_set_direct_write_block_0_mode.c new file mode 100644 index 00000000..ccf8cf30 --- /dev/null +++ b/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_set_direct_write_block_0_mode.c @@ -0,0 +1,122 @@ +#include "../nfc_magic_app_i.h" +#include "applications_user/nfc_magic/lib/magic/protocols/gen4/gen4_poller_i.h" + +enum { + NfcMagicSceneGen4SetDirectWriteBlock0ModeStateCardSearch, + NfcMagicSceneGen4SetDirectWriteBlock0ModeStateCardFound, +}; + +NfcCommand nfc_magic_scene_gen4_set_direct_write_block_0_mode_poller_callback( + Gen4PollerEvent event, + void* context) { + NfcMagicApp* instance = context; + furi_assert(event.data); + + NfcCommand command = NfcCommandContinue; + if(event.type == Gen4PollerEventTypeCardDetected) { + view_dispatcher_send_custom_event( + instance->view_dispatcher, NfcMagicCustomEventCardDetected); + } else if(event.type == Gen4PollerEventTypeRequestMode) { + event.data->request_mode.mode = Gen4PollerModeSetDirectWriteBlock0Mode; + } else if(event.type == Gen4PollerEventTypeSuccess) { + view_dispatcher_send_custom_event( + instance->view_dispatcher, NfcMagicCustomEventWorkerSuccess); + command = NfcCommandStop; + } else if(event.type == Gen4PollerEventTypeFail) { + view_dispatcher_send_custom_event( + instance->view_dispatcher, NfcMagicCustomEventWorkerFail); + command = NfcCommandStop; + } + + return command; +} + +static void nfc_magic_scene_gen4_set_direct_write_block_0_mode_setup_view(NfcMagicApp* instance) { + Popup* popup = instance->popup; + popup_reset(popup); + uint32_t state = scene_manager_get_scene_state( + instance->scene_manager, NfcMagicSceneGen4SetDirectWriteBlock0Mode); + + if(state == NfcMagicSceneGen4SetDirectWriteBlock0ModeStateCardSearch) { + popup_set_icon(instance->popup, 0, 8, &I_NFC_manual_60x50); + popup_set_text( + instance->popup, "Apply the\ncard\nto the back", 128, 32, AlignRight, AlignCenter); + } else { + popup_set_icon(popup, 12, 23, &I_Loading_24); + popup_set_header(popup, "Writing\nDon't move...", 52, 32, AlignLeft, AlignCenter); + } + + view_dispatcher_switch_to_view(instance->view_dispatcher, NfcMagicAppViewPopup); +} + +void nfc_magic_scene_gen4_set_direct_write_block_0_mode_on_enter(void* context) { + NfcMagicApp* instance = context; + + uint8_t direct_write_block_0_mode = scene_manager_get_scene_state( + instance->scene_manager, NfcMagicSceneGen4SetDirectWriteBlock0Mode); + + scene_manager_set_scene_state( + instance->scene_manager, + NfcMagicSceneGen4SetDirectWriteBlock0Mode, + NfcMagicSceneGen4SetDirectWriteBlock0ModeStateCardSearch); + nfc_magic_scene_gen4_set_direct_write_block_0_mode_setup_view(instance); + + nfc_magic_app_blink_start(instance); + + instance->gen4_poller = gen4_poller_alloc(instance->nfc); + gen4_poller_set_password(instance->gen4_poller, instance->gen4_password); + instance->gen4_poller->direct_write_block_0_mode = direct_write_block_0_mode; + + gen4_poller_start( + instance->gen4_poller, + nfc_magic_scene_gen4_set_direct_write_block_0_mode_poller_callback, + instance); +} + +bool nfc_magic_scene_gen4_set_direct_write_block_0_mode_on_event( + void* context, + SceneManagerEvent event) { + NfcMagicApp* instance = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == NfcMagicCustomEventCardDetected) { + scene_manager_set_scene_state( + instance->scene_manager, + NfcMagicSceneGen4SetDirectWriteBlock0Mode, + NfcMagicSceneGen4SetDirectWriteBlock0ModeStateCardFound); + nfc_magic_scene_gen4_set_direct_write_block_0_mode_setup_view(instance); + consumed = true; + } else if(event.event == NfcMagicCustomEventCardLost) { + scene_manager_set_scene_state( + instance->scene_manager, + NfcMagicSceneGen4SetDirectWriteBlock0Mode, + NfcMagicSceneGen4SetDirectWriteBlock0ModeStateCardSearch); + nfc_magic_scene_gen4_set_direct_write_block_0_mode_setup_view(instance); + consumed = true; + } else if(event.event == NfcMagicCustomEventWorkerSuccess) { + scene_manager_next_scene(instance->scene_manager, NfcMagicSceneSuccess); + consumed = true; + } else if(event.event == NfcMagicCustomEventWorkerFail) { + scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen4Fail); + consumed = true; + } + } + + return consumed; +} + +void nfc_magic_scene_gen4_set_direct_write_block_0_mode_on_exit(void* context) { + NfcMagicApp* instance = context; + + gen4_poller_stop(instance->gen4_poller); + gen4_poller_free(instance->gen4_poller); + scene_manager_set_scene_state( + instance->scene_manager, + NfcMagicSceneGen4SetDirectWriteBlock0Mode, + NfcMagicSceneGen4SetDirectWriteBlock0ModeStateCardSearch); + // Clear view + popup_reset(instance->popup); + + nfc_magic_app_blink_stop(instance); +} \ No newline at end of file diff --git a/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_set_shd_mode.c b/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_set_shd_mode.c index 15a357ed..d7ab4c29 100644 --- a/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_set_shd_mode.c +++ b/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_set_shd_mode.c @@ -1,9 +1,5 @@ #include "../nfc_magic_app_i.h" -#include "applications_user/nfc_magic/lib/magic/protocols/gen4/gen4_poller.h" #include "applications_user/nfc_magic/lib/magic/protocols/gen4/gen4_poller_i.h" -#include "core/log.h" -#include -#include enum { NfcMagicSceneGen4SetShadowModeStateCardSearch, diff --git a/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_show_cfg.c b/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_show_cfg.c index 636b5068..2a821228 100644 --- a/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_show_cfg.c +++ b/base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_show_cfg.c @@ -1,5 +1,4 @@ #include "../nfc_magic_app_i.h" -#include "gui/scene_manager.h" #define CONFIG_SIZE (32)