Skip to content

Commit

Permalink
NFC Magic: gui fixes, code cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
Leptopt1los committed Jan 2, 2024
1 parent 25a1afe commit cc246d5
Show file tree
Hide file tree
Showing 11 changed files with 359 additions and 42 deletions.
30 changes: 26 additions & 4 deletions base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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,

Expand Down
1 change: 1 addition & 0 deletions base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ typedef enum {
Gen4PollerModeGetCfg,
Gen4PollerModeGetRevision,
Gen4PollerModeSetShadowMode,
Gen4PollerModeSetDirectWriteBlock0Mode
} Gen4PollerMode;

typedef struct {
Expand Down
82 changes: 67 additions & 15 deletions base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller_i.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
#include "gen4_poller_i.h"

#include "bit_buffer.h"
#include "core/log.h"
#include "protocols/gen4/gen4_poller.h"
#include <nfc/protocols/iso14443_3a/iso14443_3a_poller.h>
#include <nfc/helpers/nfc_util.h>
#include <stdint.h>

#define GEN4_CMD_PREFIX (0xCF)

Expand All @@ -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;
Expand All @@ -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);

Expand All @@ -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);

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
29 changes: 24 additions & 5 deletions base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -55,6 +66,7 @@ typedef enum {
Gen4PollerStateGetCurrentConfig,
Gen4PollerStateGetRevision,
Gen4PollerStateSetShadowMode,
Gen4PollerStateSetDirectWriteBlock0,

Gen4PollerStateSuccess,
Gen4PollerStateFail,
Expand All @@ -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;
Expand Down Expand Up @@ -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
}
Expand Down
2 changes: 2 additions & 0 deletions base_pack/nfc_magic/scenes/nfc_magic_scene_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
11 changes: 11 additions & 0 deletions base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ enum SubmenuIndex {
SubmenuIndexWrite,
SubmenuIndexChangePassword,
SubmenuIndexSetShadowMode,
SubmenuIndexSetDirectWriteBlock0Mode,
SubmenuIndexGetRevision,
SubmenuIndexGetConfig,
SubmenuIndexWipe,
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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);
Expand Down
Loading

0 comments on commit cc246d5

Please sign in to comment.