Skip to content

Commit

Permalink
NFC Magic update to 1.5
Browse files Browse the repository at this point in the history
  • Loading branch information
Leptopt1los committed Dec 30, 2023
1 parent e4c6137 commit 0b7aebd
Show file tree
Hide file tree
Showing 15 changed files with 388 additions and 55 deletions.
6 changes: 3 additions & 3 deletions base_pack/nfc_magic/application.fam
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
App(
appid="nfc_magic",
name="NFC Magic",
name="Nfc Magic",
apptype=FlipperAppType.EXTERNAL,
targets=["f7"],
entry_point="nfc_magic_app",
Expand All @@ -10,8 +10,8 @@ App(
],
stack_size=4 * 1024,
fap_description="Application for writing to NFC tags with modifiable sector 0",
fap_version="1.4",
fap_icon="assets/Nfc_10px.png",
fap_version="1.5",
fap_icon="assets/125_10px.png",
fap_category="NFC",
fap_private_libs=[
Lib(
Expand Down
24 changes: 24 additions & 0 deletions base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "core/check.h"
#include "core/log.h"
#include "gen4_poller_i.h"
#include "protocols/gen4/gen4_poller.h"
#include <nfc/protocols/iso14443_3a/iso14443_3a.h>
#include <nfc/protocols/iso14443_3a/iso14443_3a_poller.h>
#include <nfc/helpers/nfc_util.h>
Expand Down Expand Up @@ -177,6 +179,8 @@ NfcCommand gen4_poller_request_mode_handler(Gen4Poller* instance) {
instance->state = Gen4PollerStateGetCurrentConfig;
} else if(instance->gen4_event_data.request_mode.mode == Gen4PollerModeGetRevision) {
instance->state = Gen4PollerStateGetRevision;
} else if(instance->gen4_event_data.request_mode.mode == Gen4PollerModeSetShadowMode) {
instance->state = Gen4PollerStateSetShadowMode;
} else {
instance->state = Gen4PollerStateFail;
}
Expand Down Expand Up @@ -534,6 +538,25 @@ NfcCommand gen4_poller_get_revision_handler(Gen4Poller* instance) {
return command;
}

NfcCommand gen4_poller_set_shadow_mode_handler(Gen4Poller* instance) {
NfcCommand command = NfcCommandContinue;

do {
Gen4PollerError error =
gen4_poller_set_shadow_mode(instance, instance->password, instance->shadow_mode);

if(error != Gen4PollerErrorNone) {
FURI_LOG_E(TAG, "Failed to set shadow 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 @@ -568,6 +591,7 @@ static const Gen4PollerStateHandler gen4_poller_state_handlers[Gen4PollerStateNu
[Gen4PollerStateSetDefaultConfig] = gen4_poller_set_default_cfg_handler,
[Gen4PollerStateGetCurrentConfig] = gen4_poller_get_current_cfg_handler,
[Gen4PollerStateGetRevision] = gen4_poller_get_revision_handler,
[Gen4PollerStateSetShadowMode] = gen4_poller_set_shadow_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 @@ -41,6 +41,7 @@ typedef enum {
Gen4PollerModeSetDefaultCFG,
Gen4PollerModeGetCFG,
Gen4PollerModeGetRevision,
Gen4PollerModeSetShadowMode,
} Gen4PollerMode;

typedef struct {
Expand Down
40 changes: 39 additions & 1 deletion base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller_i.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
#include "core/log.h"
#include <nfc/protocols/iso14443_3a/iso14443_3a_poller.h>
#include <nfc/helpers/nfc_util.h>
#include <stdint.h>

#define GEN4_CMD_PREFIX (0xCF)

#define GEN4_CMD_SET_SHD_MODE (0x32)
#define GEN4_CMD_GET_CFG (0xC6)
#define GEN4_CMD_GET_REVISION (0xCC)
#define GEN4_CMD_WRITE (0xCD)
Expand All @@ -17,6 +19,7 @@

#define CONFIG_SIZE (32)
#define REVISION_SIZE (5)
#define SHD_MODE_RESPONSE_SIZE (2)

static Gen4PollerError gen4_poller_process_error(Iso14443_3aError error) {
Gen4PollerError ret = Gen4PollerErrorNone;
Expand All @@ -30,6 +33,41 @@ 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 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_SHD_MODE);
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;
}

size_t rx_bytes = bit_buffer_get_size_bytes(instance->rx_buffer);
if(rx_bytes != SHD_MODE_RESPONSE_SIZE) {
ret = Gen4PollerErrorProtocol;
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);

} while(false);

return ret;
}

Gen4PollerError
gen4_poller_get_config(Gen4Poller* instance, uint32_t password, uint8_t* config_result) {
Gen4PollerError ret = Gen4PollerErrorNone;
Expand Down Expand Up @@ -83,7 +121,7 @@ Gen4PollerError
}

size_t rx_bytes = bit_buffer_get_size_bytes(instance->rx_buffer);
if(rx_bytes != 5) {
if(rx_bytes != REVISION_SIZE) {
ret = Gen4PollerErrorProtocol;
break;
}
Expand Down
6 changes: 6 additions & 0 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 @@ -3,6 +3,7 @@
#include "gen4_poller.h"
#include <nfc/nfc_poller.h>
#include <nfc/protocols/iso14443_3a/iso14443_3a_poller.h>
#include <stdint.h>

#define TAG "Gen4Poller"

Expand Down Expand Up @@ -53,6 +54,7 @@ typedef enum {
Gen4PollerStateSetDefaultConfig,
Gen4PollerStateGetCurrentConfig,
Gen4PollerStateGetRevision,
Gen4PollerStateSetShadowMode,

Gen4PollerStateSuccess,
Gen4PollerStateFail,
Expand All @@ -78,6 +80,8 @@ struct Gen4Poller {

uint8_t config[GEN4_POLLER_CONFIG_SIZE_MAX];

uint8_t shadow_mode;

Gen4PollerEvent gen4_event;
Gen4PollerEventData gen4_event_data;

Expand Down Expand Up @@ -107,6 +111,8 @@ 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);

#ifdef __cplusplus
}
#endif
8 changes: 5 additions & 3 deletions base_pack/nfc_magic/scenes/nfc_magic_scene_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ ADD_SCENE(nfc_magic, magic_info, MagicInfo)
ADD_SCENE(nfc_magic, gen1_menu, Gen1Menu)
ADD_SCENE(nfc_magic, gen4_menu, Gen4Menu)
ADD_SCENE(nfc_magic, gen4_actions_menu, Gen4ActionsMenu)
ADD_SCENE(nfc_magic, gen4_get_cfg, Gen4GetCFG)
ADD_SCENE(nfc_magic, gen4_set_cfg, Gen4SetCFG)
ADD_SCENE(nfc_magic, gen4_get_cfg, Gen4GetCfg)
ADD_SCENE(nfc_magic, gen4_set_cfg, Gen4SetCfg)
ADD_SCENE(nfc_magic, gen4_revision, Gen4Revision)
ADD_SCENE(nfc_magic, gen4_show_rev, Gen4ShowRev)
ADD_SCENE(nfc_magic, gen4_show_cfg, Gen4ShowCFG)
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_fail, Gen4Fail)
ADD_SCENE(nfc_magic, wipe, Wipe)
ADD_SCENE(nfc_magic, wipe_fail, WipeFail)
Expand Down
26 changes: 2 additions & 24 deletions base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_actions_menu.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
#include "../nfc_magic_app_i.h"
#include "furi_hal_rtc.h"

enum SubmenuIndex {
SubmenuIndexAuthenticate,
SubmenuIndexSetStandartConfig,
SubmenuIndexGetConfig,
SubmenuIndexGetRevision
};

void nfc_magic_scene_gen4_actions_menu_submenu_callback(void* context, uint32_t index) {
Expand All @@ -24,26 +21,12 @@ void nfc_magic_scene_gen4_actions_menu_on_enter(void* context) {
SubmenuIndexAuthenticate,
nfc_magic_scene_gen4_actions_menu_submenu_callback,
instance);
submenu_add_item(
submenu,
"Get Revision",
SubmenuIndexGetRevision,
nfc_magic_scene_gen4_actions_menu_submenu_callback,
instance);
submenu_add_item(
submenu,
"Set Standart Config",
SubmenuIndexSetStandartConfig,
nfc_magic_scene_gen4_actions_menu_submenu_callback,
instance);
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
submenu_add_item(
submenu,
"Get Config",
SubmenuIndexGetConfig,
nfc_magic_scene_gen4_actions_menu_submenu_callback,
instance);
}

submenu_set_selected_item(
submenu,
Expand All @@ -60,15 +43,10 @@ bool nfc_magic_scene_gen4_actions_menu_on_event(void* context, SceneManagerEvent
scene_manager_next_scene(instance->scene_manager, NfcMagicSceneKeyInput);
consumed = true;
} else if(event.event == SubmenuIndexSetStandartConfig) {
scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen4SetCFG);
consumed = true;
} else if(event.event == SubmenuIndexGetConfig) {
scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen4GetCFG);
consumed = true;
} else if(event.event == SubmenuIndexGetRevision) {
scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen4Revision);
scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen4SetCfg);
consumed = true;
}

scene_manager_set_scene_state(
instance->scene_manager, NfcMagicSceneGen4ActionsMenu, event.event);
} else if(event.type == SceneManagerEventTypeBack) {
Expand Down
12 changes: 6 additions & 6 deletions base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_get_cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static void nfc_magic_scene_gen4_get_cfg_setup_view(NfcMagicApp* instance) {
Popup* popup = instance->popup;
popup_reset(popup);
uint32_t state =
scene_manager_get_scene_state(instance->scene_manager, NfcMagicSceneGen4GetCFG);
scene_manager_get_scene_state(instance->scene_manager, NfcMagicSceneGen4GetCfg);

if(state == NfcMagicSceneGen4GetCFGStateCardSearch) {
popup_set_icon(instance->popup, 0, 8, &I_NFC_manual_60x50);
Expand All @@ -57,7 +57,7 @@ void nfc_magic_scene_gen4_get_cfg_on_enter(void* context) {
NfcMagicApp* instance = context;

scene_manager_set_scene_state(
instance->scene_manager, NfcMagicSceneGen4GetCFG, NfcMagicSceneGen4GetCFGStateCardSearch);
instance->scene_manager, NfcMagicSceneGen4GetCfg, NfcMagicSceneGen4GetCFGStateCardSearch);
nfc_magic_scene_gen4_get_cfg_setup_view(instance);

nfc_magic_app_blink_start(instance);
Expand All @@ -76,19 +76,19 @@ bool nfc_magic_scene_gen4_get_cfg_on_event(void* context, SceneManagerEvent even
if(event.event == NfcMagicCustomEventCardDetected) {
scene_manager_set_scene_state(
instance->scene_manager,
NfcMagicSceneGen4GetCFG,
NfcMagicSceneGen4GetCfg,
NfcMagicSceneGen4GetCFGStateCardFound);
nfc_magic_scene_gen4_get_cfg_setup_view(instance);
consumed = true;
} else if(event.event == NfcMagicCustomEventCardLost) {
scene_manager_set_scene_state(
instance->scene_manager,
NfcMagicSceneGen4GetCFG,
NfcMagicSceneGen4GetCfg,
NfcMagicSceneGen4GetCFGStateCardSearch);
nfc_magic_scene_gen4_get_cfg_setup_view(instance);
consumed = true;
} else if(event.event == NfcMagicCustomEventWorkerSuccess) {
scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen4ShowCFG);
scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen4ShowCfg);
consumed = true;
} else if(event.event == NfcMagicCustomEventWorkerFail) {
scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen4Fail);
Expand All @@ -105,7 +105,7 @@ void nfc_magic_scene_gen4_get_cfg_on_exit(void* context) {
gen4_poller_stop(instance->gen4_poller);
gen4_poller_free(instance->gen4_poller);
scene_manager_set_scene_state(
instance->scene_manager, NfcMagicSceneGen4GetCFG, NfcMagicSceneGen4GetCFGStateCardSearch);
instance->scene_manager, NfcMagicSceneGen4GetCfg, NfcMagicSceneGen4GetCFGStateCardSearch);
// Clear view
popup_reset(instance->popup);

Expand Down
34 changes: 34 additions & 0 deletions base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_menu.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#include "../nfc_magic_app_i.h"
#include "furi_hal_rtc.h"

enum SubmenuIndex {
SubmenuIndexWrite,
SubmenuIndexChangePassword,
SubmenuIndexSetShadowMode,
SubmenuIndexGetRevision,
SubmenuIndexGetConfig,
SubmenuIndexWipe,
};

Expand All @@ -24,8 +28,28 @@ void nfc_magic_scene_gen4_menu_on_enter(void* context) {
SubmenuIndexChangePassword,
nfc_magic_scene_gen4_menu_submenu_callback,
instance);
submenu_add_item(
submenu,
"Set Shadow Mode",
SubmenuIndexSetShadowMode,
nfc_magic_scene_gen4_menu_submenu_callback,
instance);
submenu_add_item(
submenu,
"Get Revision",
SubmenuIndexGetRevision,
nfc_magic_scene_gen4_menu_submenu_callback,
instance);
submenu_add_item(
submenu, "Wipe", SubmenuIndexWipe, nfc_magic_scene_gen4_menu_submenu_callback, instance);
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
submenu_add_item(
submenu,
"Get Config",
SubmenuIndexGetConfig,
nfc_magic_scene_gen4_menu_submenu_callback,
instance);
}

submenu_set_selected_item(
submenu, scene_manager_get_scene_state(instance->scene_manager, NfcMagicSceneGen4Menu));
Expand All @@ -46,7 +70,17 @@ bool nfc_magic_scene_gen4_menu_on_event(void* context, SceneManagerEvent event)
} else if(event.event == SubmenuIndexWipe) {
scene_manager_next_scene(instance->scene_manager, NfcMagicSceneWipe);
consumed = true;
} else if(event.event == SubmenuIndexGetConfig) {
scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen4GetCfg);
consumed = true;
} else if(event.event == SubmenuIndexGetRevision) {
scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen4Revision);
consumed = true;
} else if(event.event == SubmenuIndexSetShadowMode) {
scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen4SelectShdMode);
consumed = true;
}

scene_manager_set_scene_state(instance->scene_manager, NfcMagicSceneGen4Menu, event.event);
} else if(event.type == SceneManagerEventTypeBack) {
if(instance->gen4_password != 0) {
Expand Down
Loading

0 comments on commit 0b7aebd

Please sign in to comment.