Skip to content

Commit

Permalink
upd nfc magic
Browse files Browse the repository at this point in the history
- UI / Scenes - by @xMasterX
- Poller functions, minor UI fixes - by @Leptopt1los
  • Loading branch information
xMasterX committed Dec 10, 2023
1 parent 25a1579 commit d70f146
Show file tree
Hide file tree
Showing 17 changed files with 776 additions and 10 deletions.
2 changes: 1 addition & 1 deletion base_pack/nfc_magic/application.fam
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ App(
],
stack_size=4 * 1024,
fap_description="Application for writing to NFC tags with modifiable sector 0",
fap_version="1.3",
fap_version="1.4",
fap_icon="assets/Nfc_10px.png",
fap_category="NFC",
fap_private_libs=[
Expand Down
74 changes: 74 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,3 +1,4 @@
#include "core/log.h"
#include "gen4_poller_i.h"
#include <nfc/protocols/iso14443_3a/iso14443_3a.h>
#include <nfc/protocols/iso14443_3a/iso14443_3a_poller.h>
Expand Down Expand Up @@ -170,6 +171,12 @@ NfcCommand gen4_poller_request_mode_handler(Gen4Poller* instance) {
instance->state = Gen4PollerStateRequestWriteData;
} else if(instance->gen4_event_data.request_mode.mode == Gen4PollerModeSetPassword) {
instance->state = Gen4PollerStateChangePassword;
} else if(instance->gen4_event_data.request_mode.mode == Gen4PollerModeSetDefaultCFG) {
instance->state = Gen4PollerStateSetDefaultConfig;
} else if(instance->gen4_event_data.request_mode.mode == Gen4PollerModeGetCFG) {
instance->state = Gen4PollerStateGetCurrentConfig;
} else if(instance->gen4_event_data.request_mode.mode == Gen4PollerModeGetRevision) {
instance->state = Gen4PollerStateGetRevision;
} else {
instance->state = Gen4PollerStateFail;
}
Expand Down Expand Up @@ -463,6 +470,70 @@ NfcCommand gen4_poller_change_password_handler(Gen4Poller* instance) {
return command;
}

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

do {
Gen4PollerError error = gen4_poller_set_config(
instance,
instance->password,
gen4_poller_default_config,
sizeof(gen4_poller_default_config),
false);
if(error != Gen4PollerErrorNone) {
FURI_LOG_E(TAG, "Failed to set default config: %d", error);
instance->state = Gen4PollerStateFail;
break;
}

instance->state = Gen4PollerStateSuccess;
} while(false);

return command;
}

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

do {
uint8_t the_config[32] = {};

Gen4PollerError error = gen4_poller_get_config(instance, instance->password, the_config);
if(error != Gen4PollerErrorNone) {
FURI_LOG_E(TAG, "Failed to get current config: %d", error);
instance->state = Gen4PollerStateFail;
break;
}
// Copy config data to event data buffer
memcpy(instance->gen4_event_data.display_config, the_config, sizeof(the_config));

instance->state = Gen4PollerStateSuccess;
} while(false);

return command;
}

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

do {
uint8_t the_revision[5] = {0};
Gen4PollerError error =
gen4_poller_get_revision(instance, instance->password, the_revision);
if(error != Gen4PollerErrorNone) {
FURI_LOG_E(TAG, "Failed to get revision: %d", error);
instance->state = Gen4PollerStateFail;
break;
}
// Copy revision data to event data buffer
memcpy(instance->gen4_event_data.revision_data, the_revision, sizeof(the_revision));

instance->state = Gen4PollerStateSuccess;
} while(false);

return command;
}

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

Expand Down Expand Up @@ -494,6 +565,9 @@ static const Gen4PollerStateHandler gen4_poller_state_handlers[Gen4PollerStateNu
[Gen4PollerStateWrite] = gen4_poller_write_handler,
[Gen4PollerStateWipe] = gen4_poller_wipe_handler,
[Gen4PollerStateChangePassword] = gen4_poller_change_password_handler,
[Gen4PollerStateSetDefaultConfig] = gen4_poller_set_default_cfg_handler,
[Gen4PollerStateGetCurrentConfig] = gen4_poller_get_current_cfg_handler,
[Gen4PollerStateGetRevision] = gen4_poller_get_revision_handler,
[Gen4PollerStateSuccess] = gen4_poller_success_handler,
[Gen4PollerStateFail] = gen4_poller_fail_handler,

Expand Down
7 changes: 7 additions & 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 @@ -37,6 +37,10 @@ typedef enum {
Gen4PollerModeWipe,
Gen4PollerModeWrite,
Gen4PollerModeSetPassword,

Gen4PollerModeSetDefaultCFG,
Gen4PollerModeGetCFG,
Gen4PollerModeGetRevision,
} Gen4PollerMode;

typedef struct {
Expand All @@ -56,6 +60,9 @@ typedef union {
Gen4PollerEventDataRequestMode request_mode;
Gen4PollerEventDataRequestDataToWrite request_data;
Gen4PollerEventDataRequestNewPassword request_password;

uint8_t display_config[32];
uint8_t revision_data[5];
} Gen4PollerEventData;

typedef struct {
Expand Down
69 changes: 69 additions & 0 deletions base_pack/nfc_magic/lib/magic/protocols/gen4/gen4_poller_i.c
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
#include "gen4_poller_i.h"

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

#define GEN4_CMD_PREFIX (0xCF)

#define GEN4_CMD_GET_CFG (0xC6)
#define GEN4_CMD_GET_REVISION (0xCC)
#define GEN4_CMD_WRITE (0xCD)
#define GEN4_CMD_READ (0xCE)
#define GEN4_CMD_SET_CFG (0xF0)
#define GEN4_CMD_FUSE_CFG (0xF1)
#define GEN4_CMD_SET_PWD (0xFE)

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

static Gen4PollerError gen4_poller_process_error(Iso14443_3aError error) {
Gen4PollerError ret = Gen4PollerErrorNone;

Expand All @@ -24,6 +30,69 @@ static Gen4PollerError gen4_poller_process_error(Iso14443_3aError error) {
return ret;
}

Gen4PollerError
gen4_poller_get_config(Gen4Poller* instance, uint32_t password, uint8_t* config_result) {
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_GET_CFG);

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 != CONFIG_SIZE) {
ret = Gen4PollerErrorProtocol;
break;
}
bit_buffer_write_bytes(instance->rx_buffer, config_result, CONFIG_SIZE);
} while(false);

return ret;
}

Gen4PollerError
gen4_poller_get_revision(Gen4Poller* instance, uint32_t password, uint8_t* revision_result) {
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_GET_REVISION);

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 != 5) {
ret = Gen4PollerErrorProtocol;
break;
}
bit_buffer_write_bytes(instance->rx_buffer, revision_result, REVISION_SIZE);
} while(false);

return ret;
}

Gen4PollerError gen4_poller_set_config(
Gen4Poller* instance,
uint32_t password,
Expand Down
11 changes: 11 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 @@ -49,6 +49,11 @@ typedef enum {
Gen4PollerStateWrite,
Gen4PollerStateWipe,
Gen4PollerStateChangePassword,

Gen4PollerStateSetDefaultConfig,
Gen4PollerStateGetCurrentConfig,
Gen4PollerStateGetRevision,

Gen4PollerStateSuccess,
Gen4PollerStateFail,

Expand Down Expand Up @@ -96,6 +101,12 @@ Gen4PollerError gen4_poller_write_block(
Gen4PollerError
gen4_poller_change_password(Gen4Poller* instance, uint32_t pwd_current, uint32_t pwd_new);

Gen4PollerError
gen4_poller_get_revision(Gen4Poller* instance, uint32_t password, uint8_t* revision_result);

Gen4PollerError
gen4_poller_get_config(Gen4Poller* instance, uint32_t password, uint8_t* config_result);

#ifdef __cplusplus
}
#endif
3 changes: 3 additions & 0 deletions base_pack/nfc_magic/nfc_magic_app_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ struct NfcMagicApp {
uint32_t gen4_password;
uint32_t gen4_password_new;

uint8_t gen4_config_display[32];
uint8_t gen4_revision_display[5];

FuriString* text_box_store;
uint8_t byte_input_store[NFC_MAGIC_APP_BYTE_INPUT_STORE_SIZE];

Expand Down
7 changes: 7 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 @@ -4,6 +4,13 @@ ADD_SCENE(nfc_magic, key_input, KeyInput)
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_revision, Gen4Revision)
ADD_SCENE(nfc_magic, gen4_show_rev, Gen4ShowRev)
ADD_SCENE(nfc_magic, gen4_show_cfg, Gen4ShowCFG)
ADD_SCENE(nfc_magic, gen4_fail, Gen4Fail)
ADD_SCENE(nfc_magic, wipe, Wipe)
ADD_SCENE(nfc_magic, wipe_fail, WipeFail)
ADD_SCENE(nfc_magic, success, Success)
Expand Down
4 changes: 2 additions & 2 deletions base_pack/nfc_magic/scenes/nfc_magic_scene_gen1_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ void nfc_magic_scene_gen1_menu_on_enter(void* context) {
submenu, "Wipe", SubmenuIndexWipe, nfc_magic_scene_gen1_menu_submenu_callback, instance);

submenu_set_selected_item(
submenu, scene_manager_get_scene_state(instance->scene_manager, NfcMagicSceneGen4Menu));
submenu, scene_manager_get_scene_state(instance->scene_manager, NfcMagicSceneGen1Menu));
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcMagicAppViewMenu);
}

Expand All @@ -37,7 +37,7 @@ bool nfc_magic_scene_gen1_menu_on_event(void* context, SceneManagerEvent event)
scene_manager_next_scene(instance->scene_manager, NfcMagicSceneWipe);
consumed = true;
}
scene_manager_set_scene_state(instance->scene_manager, NfcMagicSceneGen4Menu, event.event);
scene_manager_set_scene_state(instance->scene_manager, NfcMagicSceneGen1Menu, event.event);
} else if(event.type == SceneManagerEventTypeBack) {
consumed = scene_manager_search_and_switch_to_previous_scene(
instance->scene_manager, NfcMagicSceneStart);
Expand Down
86 changes: 86 additions & 0 deletions base_pack/nfc_magic/scenes/nfc_magic_scene_gen4_actions_menu.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#include "../nfc_magic_app_i.h"
#include "furi_hal_rtc.h"

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

void nfc_magic_scene_gen4_actions_menu_submenu_callback(void* context, uint32_t index) {
NfcMagicApp* instance = context;

view_dispatcher_send_custom_event(instance->view_dispatcher, index);
}

void nfc_magic_scene_gen4_actions_menu_on_enter(void* context) {
NfcMagicApp* instance = context;

Submenu* submenu = instance->submenu;
submenu_add_item(
submenu,
"Auth With Password",
SubmenuIndexAuthenticate,
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);
submenu_add_item(
submenu,
"Get Revision",
SubmenuIndexGetRevision,
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,
scene_manager_get_scene_state(instance->scene_manager, NfcMagicSceneGen4ActionsMenu));
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcMagicAppViewMenu);
}

bool nfc_magic_scene_gen4_actions_menu_on_event(void* context, SceneManagerEvent event) {
NfcMagicApp* instance = context;
bool consumed = false;

if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubmenuIndexAuthenticate) {
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 == SubmenuIndexGetRevision) {
scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen4Revision);
consumed = true;
} else if(event.event == SubmenuIndexGetConfig) {
scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen4GetCFG);
consumed = true;
}
scene_manager_set_scene_state(
instance->scene_manager, NfcMagicSceneGen4ActionsMenu, event.event);
} else if(event.type == SceneManagerEventTypeBack) {
consumed = scene_manager_search_and_switch_to_previous_scene(
instance->scene_manager, NfcMagicSceneStart);
}

return consumed;
}

void nfc_magic_scene_gen4_actions_menu_on_exit(void* context) {
NfcMagicApp* instance = context;

submenu_reset(instance->submenu);
}
Loading

0 comments on commit d70f146

Please sign in to comment.