Skip to content

Commit

Permalink
Fixed #270: add option to custom uid
Browse files Browse the repository at this point in the history
  • Loading branch information
solosky committed Oct 13, 2024
1 parent 267783d commit a1965c7
Show file tree
Hide file tree
Showing 20 changed files with 252 additions and 69 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ fw/.settings
fw/_build
fw/.idea

fw/application/.idea
fw/bootloader/.idea

fw/src/amiibo_private.c
fw/src/version.inc.h
fw/src/version.json
Expand Down
32 changes: 27 additions & 5 deletions fw/application/src/amiibo_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,31 @@ ret_code_t amiibo_helper_rand_amiibo_uuid(ntag_t *ntag) {
return err_code;
}

ret_code_t amiibo_helper_set_amiibo_uuid(ntag_t *ntag, uint8_t *uuid) {
ret_code_t err_code;
ntag_t ntag_new;
ntag_t *ntag_current = ntag;

memcpy(&ntag_new, ntag_current, sizeof(ntag_t));

if (!is_valid_amiibo_ntag(ntag_current)) {
return NRF_ERROR_INVALID_DATA;
}

if (!amiibo_helper_is_key_loaded()) {
return NRF_ERROR_INVALID_DATA;
}

ntag_store_set_uuid(&ntag_new, uuid);

// sign new
err_code = amiibo_helper_sign_new_ntag(ntag_current, &ntag_new);
if (err_code == NRF_SUCCESS) {
memcpy(ntag, &ntag_new, sizeof(ntag_t));
}
return err_code;
}

ret_code_t amiibo_helper_generate_amiibo(uint32_t head, uint32_t tail, ntag_t *ntag) {
if (!amiibo_helper_is_key_loaded()) {
return NRF_ERROR_INVALID_DATA;
Expand Down Expand Up @@ -192,20 +217,18 @@ void amiibo_helper_try_load_amiibo_keys_from_vfs() {
}
}

uint32_t to_little_endian_int32(const uint8_t* data){
uint32_t to_little_endian_int32(const uint8_t *data) {
uint32_t val = 0;
val += data[0];
val <<= 8;
val += data[1];
val <<= 8;
val += data[2];
val <<=8;
val <<= 8;
val += data[3];
return val;
}



bool is_valid_amiibo_ntag(const ntag_t *ntag) {
uint32_t head = to_little_endian_int32(&ntag->data[84]);
uint32_t tail = to_little_endian_int32(&ntag->data[88]);
Expand All @@ -224,4 +247,3 @@ bool is_valid_amiibo_ntag(const ntag_t *ntag) {

return false;
}

13 changes: 13 additions & 0 deletions fw/application/src/app/amiibo/app_amiibo.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ void app_amiibo_on_run(mini_app_inst_t *p_app_inst) {
p_app_handle->p_msg_box = mui_msg_box_create();
mui_msg_box_set_user_data(p_app_handle->p_msg_box, p_app_handle);

p_app_handle->p_toast_view = mui_toast_view_create();
mui_toast_view_set_user_data(p_app_handle->p_toast_view, p_app_handle);

p_app_handle->p_scene_dispatcher = mui_scene_dispatcher_create();

string_init(p_app_handle->current_file);
Expand All @@ -67,6 +70,12 @@ void app_amiibo_on_run(mini_app_inst_t *p_app_inst) {

mui_view_dispatcher_attach(p_app_handle->p_view_dispatcher, MUI_LAYER_FULLSCREEN);

p_app_handle->p_view_dispatcher_toast = mui_view_dispatcher_create();
mui_view_dispatcher_add_view(p_app_handle->p_view_dispatcher_toast, AMIIBO_VIEW_ID_TOAST,
mui_toast_view_get_view(p_app_handle->p_toast_view));
mui_view_dispatcher_attach(p_app_handle->p_view_dispatcher_toast, MUI_LAYER_TOAST);
mui_view_dispatcher_switch_to_view(p_app_handle->p_view_dispatcher_toast, AMIIBO_VIEW_ID_TOAST);

extern const ntag_t default_ntag215;
APP_ERROR_CHECK(ntag_emu_init(&default_ntag215));

Expand Down Expand Up @@ -133,6 +142,10 @@ void app_amiibo_on_kill(mini_app_inst_t *p_app_inst) {
mui_scene_dispatcher_free(p_app_handle->p_scene_dispatcher);
amiibo_detail_view_free(p_app_handle->p_amiibo_detail_view);

mui_view_dispatcher_detach(p_app_handle->p_view_dispatcher_toast, MUI_LAYER_TOAST);
mui_view_dispatcher_free(p_app_handle->p_view_dispatcher_toast);
mui_toast_view_free(p_app_handle->p_toast_view);

string_clear(p_app_handle->current_file);
string_clear(p_app_handle->current_folder);
string_array_clear(p_app_handle->amiibo_files);
Expand Down
8 changes: 5 additions & 3 deletions fw/application/src/app/amiibo/app_amiibo.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,23 @@
#include "mui_msg_box.h"
#include "mui_scene_dispatcher.h"
#include "mui_text_input.h"
#include "mui_toast_view.h"
#include "ntag_def.h"
#include "vfs.h"

#include "mlib_common.h"


typedef struct {
amiibo_detail_view_t *p_amiibo_detail_view;
mui_list_view_t *p_list_view;
mui_text_input_t *p_text_input;
mui_msg_box_t *p_msg_box;
mui_toast_view_t *p_toast_view;
mui_view_dispatcher_t *p_view_dispatcher;
mui_scene_dispatcher_t *p_scene_dispatcher;
mui_view_dispatcher_t *p_view_dispatcher_toast;
ntag_t ntag;

/** file browser*/
vfs_drive_t current_drive;
string_t current_folder;
Expand All @@ -39,6 +41,7 @@ typedef enum {
AMIIBO_VIEW_ID_DETAIL,
AMIIBO_VIEW_ID_INPUT,
AMIIBO_VIEW_ID_MSG_BOX,
AMIIBO_VIEW_ID_TOAST
} amiibo_view_id_t;

typedef struct {
Expand All @@ -50,7 +53,6 @@ typedef struct {
uint32_t current_scene_id;
} app_amiibo_cache_data_t;


extern mini_app_t app_amiibo_info;

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ enum amiibo_detail_menu_t {
AMIIBO_DETAIL_MENU_RAND_UID,
AMIIBO_DETAIL_MENU_AUTO_RAND_UID,
AMIIBO_DETAIL_MENU_READ_ONLY,
AMIIBO_DETAIL_MENU_SET_CUSTOM_UID,
AMIIBO_DETAIL_MENU_REMOVE_AMIIBO,
AMIIBO_DETAIL_MENU_BACK_AMIIBO_DETAIL,
AMIIBO_DETAIL_MENU_BACK_FILE_BROWSER,
Expand All @@ -33,7 +34,6 @@ static ret_code_t amiibo_scene_amiibo_detail_set_readonly(app_amiibo_t *app, boo
vfs_obj_t obj;
uint8_t meta_buf[VFS_MAX_META_LEN];


cwalk_append_segment(path, string_get_cstr(app->current_folder), string_get_cstr(app->current_file));

vfs_driver_t *p_vfs_driver = vfs_get_driver(VFS_DRIVE_EXT);
Expand Down Expand Up @@ -112,6 +112,60 @@ static void amiibo_scene_amiibo_detail_delete_tag_confirmed(mui_msg_box_event_t
}
}

static void amiibo_scene_amiibo_detail_menu_text_input_set_id_event_cb(mui_text_input_event_t event,
mui_text_input_t *p_text_input) {
app_amiibo_t *app = p_text_input->user_data;
const char *input_text = mui_text_input_get_input_text(p_text_input);
if (event == MUI_TEXT_INPUT_EVENT_CONFIRMED && strlen(input_text) > 0) {

int8_t uid[7];
ret_code_t err_code;
char path[VFS_MAX_PATH_LEN];

ntag_t *ntag = &app->ntag;

// read uid from input
if (sscanf(input_text, "%02x.%02x.%02x.%02x.%02x.%02x.%02x", uid, uid + 1, uid + 2, uid + 3, uid + 4, uid + 5,
uid + 6) != 7) {
mui_toast_view_show(app->p_toast_view, _T(INAVLID_ID));
return;
}

// same uid as current tag
uint8_t cur_uid[7];
ntag_store_get_uuid(ntag, cur_uid);
if (memcmp(cur_uid, uid, 7) == 0) {
mui_scene_dispatcher_previous_scene(app->p_scene_dispatcher);
return;
}

// set current ntag uid
err_code = amiibo_helper_set_amiibo_uuid(ntag, uid);
if (err_code != NRF_SUCCESS) {
mui_toast_view_show(app->p_toast_view, _T(FAILED));
return;
}

// set ntag emu to emulate new tag
ntag_emu_set_tag(&app->ntag);

// save to file
vfs_driver_t *p_driver = vfs_get_driver(app->current_drive);

cwalk_append_segment(path, string_get_cstr(app->current_folder), string_get_cstr(app->current_file));
int32_t res = p_driver->write_file_data(path, ntag->data, sizeof(ntag->data));

if (res < 0) {
mui_toast_view_show(app->p_toast_view, _T(FAILED));
return;
}

mui_scene_dispatcher_previous_scene(app->p_scene_dispatcher);
} else {
mui_scene_dispatcher_previous_scene(app->p_scene_dispatcher);
}
}

static void amiibo_scene_amiibo_detail_menu_on_selected(mui_list_view_event_t event, mui_list_view_t *p_list_view,
mui_list_item_t *p_item) {
app_amiibo_t *app = p_list_view->user_data;
Expand Down Expand Up @@ -168,6 +222,27 @@ static void amiibo_scene_amiibo_detail_menu_on_selected(mui_list_view_event_t ev
p_item, (p_settings->auto_gen_amiibo ? getLangString(_L_ON_F) : getLangString(_L_OFF_F)));
} break;

case AMIIBO_DETAIL_MENU_SET_CUSTOM_UID: {
char id_text[32];
uint8_t id[7];
ntag_t *ntag = &app->ntag;

if (!amiibo_helper_is_key_loaded()) {
amiibo_scene_amiibo_detail_no_key_msg(app);
return;
}

ntag_store_get_uuid(ntag, id);

sprintf(id_text, "%02x.%02x.%02x.%02x.%02x.%02x.%02x", id[0], id[1], id[2], id[3], id[4], id[5], id[6]);

mui_text_input_set_header(app->p_text_input, getLangString(_L_INPUT_ID));
mui_text_input_set_input_text(app->p_text_input, id_text);
mui_text_input_set_event_cb(app->p_text_input, amiibo_scene_amiibo_detail_menu_text_input_set_id_event_cb);

mui_view_dispatcher_switch_to_view(app->p_view_dispatcher, AMIIBO_VIEW_ID_INPUT);
} break;

case AMIIBO_DETAIL_MENU_READ_ONLY: {
ret_code_t err_code = amiibo_scene_amiibo_detail_set_readonly(app, !app->ntag.read_only);
if (err_code == NRF_SUCCESS) {
Expand Down Expand Up @@ -207,6 +282,9 @@ void amiibo_scene_amiibo_detail_menu_on_enter(void *user_data) {
(p_settings->auto_gen_amiibo ? getLangString(_L_ON_F) : getLangString(_L_OFF_F)),
(void *)AMIIBO_DETAIL_MENU_AUTO_RAND_UID);

mui_list_view_add_item(app->p_list_view, 0xe1c8, getLangString(_L_SET_CUSTOM_ID),
(void *)AMIIBO_DETAIL_MENU_SET_CUSTOM_UID);

mui_list_view_add_item_ext(app->p_list_view, 0xe007, getLangString(_L_READ_ONLY),
app->ntag.read_only ? getLangString(_L_ON_F) : getLangString(_L_OFF_F),
(void *)AMIIBO_DETAIL_MENU_READ_ONLY);
Expand Down
4 changes: 4 additions & 0 deletions fw/application/src/i18n/de_DE.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const char * const lang_de_DE[_L_COUNT] = {
[_L_BACK] = "Zurück",
[_L_ERR] = "Fehler",
[_L_ERR_CODE] = "Fehlercode",
[_L_FAILED] = "",
[_L_APP_AMIIBO] = "Amiibo Emulator",
[_L_APP_AMIIBOLINK] = "AmiiboLink",
[_L_APP_BLE] = "BLE Dateitransfer",
Expand Down Expand Up @@ -46,6 +47,9 @@ const char * const lang_de_DE[_L_COUNT] = {
[_L_KNOW] = "Verstanden",
[_L_RANDOM_GENERATION] = "Zufällige UUID",
[_L_AUTO_RANDOM_GENERATION] = "Zufällige UUID (Automatisch)",
[_L_SET_CUSTOM_ID] = "",
[_L_INPUT_ID] = "",
[_L_INAVLID_ID] = "",
[_L_SHOW_QRCODE] = "QR Code",
[_L_READ_ONLY] = "",
[_L_DELETE_TAG] = "Tag löschen",
Expand Down
4 changes: 4 additions & 0 deletions fw/application/src/i18n/en_US.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const char * const lang_en_US[_L_COUNT] = {
[_L_BACK] = "Back",
[_L_ERR] = "Error",
[_L_ERR_CODE] = "Error Code",
[_L_FAILED] = "Failed",
[_L_APP_AMIIBO] = "Amiibo Emulator",
[_L_APP_AMIIBOLINK] = "AmiiboLink",
[_L_APP_BLE] = "BLE File Transfer",
Expand Down Expand Up @@ -46,6 +47,9 @@ const char * const lang_en_US[_L_COUNT] = {
[_L_KNOW] = "Got it",
[_L_RANDOM_GENERATION] = "Rand. Tag",
[_L_AUTO_RANDOM_GENERATION] = "Auto Rand.",
[_L_SET_CUSTOM_ID] = "Set Custom ID",
[_L_INPUT_ID] = "Input ID",
[_L_INAVLID_ID] = "Invalid ID",
[_L_SHOW_QRCODE] = "Display QR Code",
[_L_READ_ONLY] = "Read-only",
[_L_DELETE_TAG] = "Delete Tag",
Expand Down
4 changes: 4 additions & 0 deletions fw/application/src/i18n/es_ES.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const char * const lang_es_ES[_L_COUNT] = {
[_L_BACK] = "[Atrás]",
[_L_ERR] = "Error",
[_L_ERR_CODE] = "Código error",
[_L_FAILED] = "",
[_L_APP_AMIIBO] = "Emulador de amiibo",
[_L_APP_AMIIBOLINK] = "AmiiboLink",
[_L_APP_BLE] = "Transferencia BLE",
Expand Down Expand Up @@ -46,6 +47,9 @@ const char * const lang_es_ES[_L_COUNT] = {
[_L_KNOW] = "Entendido",
[_L_RANDOM_GENERATION] = "Nuevo serial aleat.",
[_L_AUTO_RANDOM_GENERATION] = "Serial alea. aut",
[_L_SET_CUSTOM_ID] = "",
[_L_INPUT_ID] = "",
[_L_INAVLID_ID] = "",
[_L_SHOW_QRCODE] = "Mostrar QR",
[_L_READ_ONLY] = "",
[_L_DELETE_TAG] = "Borrar amiibo...",
Expand Down
4 changes: 4 additions & 0 deletions fw/application/src/i18n/fr_FR.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const char * const lang_fr_FR[_L_COUNT] = {
[_L_BACK] = "Retour",
[_L_ERR] = "Erreur",
[_L_ERR_CODE] = "Code d'Erreur",
[_L_FAILED] = "",
[_L_APP_AMIIBO] = "Emulateur Amiibo",
[_L_APP_AMIIBOLINK] = "AmiiboLink",
[_L_APP_BLE] = "Transfert de Fichiers BLE",
Expand Down Expand Up @@ -46,6 +47,9 @@ const char * const lang_fr_FR[_L_COUNT] = {
[_L_KNOW] = "Compris",
[_L_RANDOM_GENERATION] = "Randomiser la Balise",
[_L_AUTO_RANDOM_GENERATION] = "Randomisation Automatique",
[_L_SET_CUSTOM_ID] = "",
[_L_INPUT_ID] = "",
[_L_INAVLID_ID] = "",
[_L_SHOW_QRCODE] = "Afficher le Code QR",
[_L_READ_ONLY] = "",
[_L_DELETE_TAG] = "Supprimer la Balise",
Expand Down
4 changes: 4 additions & 0 deletions fw/application/src/i18n/hu_HU.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const char * const lang_hu_HU[_L_COUNT] = {
[_L_BACK] = "Vissza",
[_L_ERR] = "Hiba",
[_L_ERR_CODE] = "Hibakód",
[_L_FAILED] = "",
[_L_APP_AMIIBO] = "Amiibo Emulátor",
[_L_APP_AMIIBOLINK] = "AmiiboLink",
[_L_APP_BLE] = "BLE Fájltovábbítás",
Expand Down Expand Up @@ -46,6 +47,9 @@ const char * const lang_hu_HU[_L_COUNT] = {
[_L_KNOW] = "Megvan",
[_L_RANDOM_GENERATION] = "Véletlengenerátor",
[_L_AUTO_RANDOM_GENERATION] = "Automat. Véletlengenerátor",
[_L_SET_CUSTOM_ID] = "",
[_L_INPUT_ID] = "",
[_L_INAVLID_ID] = "",
[_L_SHOW_QRCODE] = "QR-kód Megjelenítése",
[_L_READ_ONLY] = "",
[_L_DELETE_TAG] = "Címke Törlése",
Expand Down
4 changes: 4 additions & 0 deletions fw/application/src/i18n/it_IT.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const char * const lang_it_IT[_L_COUNT] = {
[_L_BACK] = "Indietro",
[_L_ERR] = "Errore",
[_L_ERR_CODE] = "Codice errore",
[_L_FAILED] = "",
[_L_APP_AMIIBO] = "Emulatore Amiibo",
[_L_APP_AMIIBOLINK] = "AmiiboLink",
[_L_APP_BLE] = "Trasferimento file BLE",
Expand Down Expand Up @@ -46,6 +47,9 @@ const char * const lang_it_IT[_L_COUNT] = {
[_L_KNOW] = "Ho Capito",
[_L_RANDOM_GENERATION] = "Tag casuale",
[_L_AUTO_RANDOM_GENERATION] = "Casuale automatico",
[_L_SET_CUSTOM_ID] = "",
[_L_INPUT_ID] = "",
[_L_INAVLID_ID] = "",
[_L_SHOW_QRCODE] = "Mostra codice QR",
[_L_READ_ONLY] = "",
[_L_DELETE_TAG] = "Elimina tag",
Expand Down
4 changes: 4 additions & 0 deletions fw/application/src/i18n/ja_JP.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const char * const lang_ja_JP[_L_COUNT] = {
[_L_BACK] = "戻る",
[_L_ERR] = "エラー",
[_L_ERR_CODE] = "エラーコード",
[_L_FAILED] = "",
[_L_APP_AMIIBO] = "Amiiboエミュレータ",
[_L_APP_AMIIBOLINK] = "AmiiboLink",
[_L_APP_BLE] = "BLEファイル転送",
Expand Down Expand Up @@ -46,6 +47,9 @@ const char * const lang_ja_JP[_L_COUNT] = {
[_L_KNOW] = "了解",
[_L_RANDOM_GENERATION] = "タグのランダム化",
[_L_AUTO_RANDOM_GENERATION] = "自動ランダム化",
[_L_SET_CUSTOM_ID] = "",
[_L_INPUT_ID] = "",
[_L_INAVLID_ID] = "",
[_L_SHOW_QRCODE] = "QRコード表示",
[_L_READ_ONLY] = "",
[_L_DELETE_TAG] = "タグの削除",
Expand Down
Loading

0 comments on commit a1965c7

Please sign in to comment.