From a1965c7e49e24965649e18dcd61fd317d4982475 Mon Sep 17 00:00:00 2001 From: solosky Date: Sun, 13 Oct 2024 14:28:06 +0800 Subject: [PATCH] Fixed #270: add option to custom uid --- .gitignore | 3 + fw/application/src/amiibo_helper.c | 32 ++++- fw/application/src/app/amiibo/app_amiibo.c | 13 ++ fw/application/src/app/amiibo/app_amiibo.h | 8 +- .../scene/amiibo_scene_amiibo_detail_menu.c | 80 +++++++++++- fw/application/src/i18n/de_DE.c | 4 + fw/application/src/i18n/en_US.c | 4 + fw/application/src/i18n/es_ES.c | 4 + fw/application/src/i18n/fr_FR.c | 4 + fw/application/src/i18n/hu_HU.c | 4 + fw/application/src/i18n/it_IT.c | 4 + fw/application/src/i18n/ja_JP.c | 4 + fw/application/src/i18n/nl_NL.c | 4 + fw/application/src/i18n/pt_BR.c | 4 + fw/application/src/i18n/ru_RU.c | 4 + fw/application/src/i18n/string_id.h | 4 + fw/application/src/i18n/zh_Hans.c | 4 + fw/application/src/i18n/zh_TW.c | 4 + fw/application/src/ntag/ntag_store.c | 118 ++++++++++-------- fw/application/src/ntag/ntag_store.h | 15 +-- 20 files changed, 252 insertions(+), 69 deletions(-) diff --git a/.gitignore b/.gitignore index 566d1df6..6d12761c 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/fw/application/src/amiibo_helper.c b/fw/application/src/amiibo_helper.c index aa1a1750..7ade328f 100644 --- a/fw/application/src/amiibo_helper.c +++ b/fw/application/src/amiibo_helper.c @@ -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; @@ -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]); @@ -224,4 +247,3 @@ bool is_valid_amiibo_ntag(const ntag_t *ntag) { return false; } - diff --git a/fw/application/src/app/amiibo/app_amiibo.c b/fw/application/src/app/amiibo/app_amiibo.c index 192015b0..38ee78cd 100644 --- a/fw/application/src/app/amiibo/app_amiibo.c +++ b/fw/application/src/app/amiibo/app_amiibo.c @@ -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); @@ -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)); @@ -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); diff --git a/fw/application/src/app/amiibo/app_amiibo.h b/fw/application/src/app/amiibo/app_amiibo.h index 921f5386..143c0b40 100644 --- a/fw/application/src/app/amiibo/app_amiibo.h +++ b/fw/application/src/app/amiibo/app_amiibo.h @@ -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; @@ -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 { @@ -50,7 +53,6 @@ typedef struct { uint32_t current_scene_id; } app_amiibo_cache_data_t; - extern mini_app_t app_amiibo_info; #endif \ No newline at end of file diff --git a/fw/application/src/app/amiibo/scene/amiibo_scene_amiibo_detail_menu.c b/fw/application/src/app/amiibo/scene/amiibo_scene_amiibo_detail_menu.c index a491febb..d4615318 100644 --- a/fw/application/src/app/amiibo/scene/amiibo_scene_amiibo_detail_menu.c +++ b/fw/application/src/app/amiibo/scene/amiibo_scene_amiibo_detail_menu.c @@ -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, @@ -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); @@ -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; @@ -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) { @@ -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); diff --git a/fw/application/src/i18n/de_DE.c b/fw/application/src/i18n/de_DE.c index 9fd7ad18..32c0cf50 100644 --- a/fw/application/src/i18n/de_DE.c +++ b/fw/application/src/i18n/de_DE.c @@ -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", @@ -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", diff --git a/fw/application/src/i18n/en_US.c b/fw/application/src/i18n/en_US.c index 658a74d0..2724fca9 100644 --- a/fw/application/src/i18n/en_US.c +++ b/fw/application/src/i18n/en_US.c @@ -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", @@ -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", diff --git a/fw/application/src/i18n/es_ES.c b/fw/application/src/i18n/es_ES.c index 977ba09b..00122a32 100644 --- a/fw/application/src/i18n/es_ES.c +++ b/fw/application/src/i18n/es_ES.c @@ -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", @@ -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...", diff --git a/fw/application/src/i18n/fr_FR.c b/fw/application/src/i18n/fr_FR.c index f6696005..b7cb3abe 100644 --- a/fw/application/src/i18n/fr_FR.c +++ b/fw/application/src/i18n/fr_FR.c @@ -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", @@ -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", diff --git a/fw/application/src/i18n/hu_HU.c b/fw/application/src/i18n/hu_HU.c index f66c057c..55f2dd42 100644 --- a/fw/application/src/i18n/hu_HU.c +++ b/fw/application/src/i18n/hu_HU.c @@ -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", @@ -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", diff --git a/fw/application/src/i18n/it_IT.c b/fw/application/src/i18n/it_IT.c index 34fa8f7b..a000d7ce 100644 --- a/fw/application/src/i18n/it_IT.c +++ b/fw/application/src/i18n/it_IT.c @@ -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", @@ -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", diff --git a/fw/application/src/i18n/ja_JP.c b/fw/application/src/i18n/ja_JP.c index b9db0380..2442be6e 100644 --- a/fw/application/src/i18n/ja_JP.c +++ b/fw/application/src/i18n/ja_JP.c @@ -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ファイル転送", @@ -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] = "タグの削除", diff --git a/fw/application/src/i18n/nl_NL.c b/fw/application/src/i18n/nl_NL.c index c199cc6e..ea115235 100644 --- a/fw/application/src/i18n/nl_NL.c +++ b/fw/application/src/i18n/nl_NL.c @@ -7,6 +7,7 @@ const char * const lang_nl_NL[_L_COUNT] = { [_L_BACK] = "Terug", [_L_ERR] = "Fout", [_L_ERR_CODE] = "Foutcode", + [_L_FAILED] = "", [_L_APP_AMIIBO] = "Amiibo-Emulator", [_L_APP_AMIIBOLINK] = "AmiiboLink", [_L_APP_BLE] = "BLE Bestandsoverdracht", @@ -46,6 +47,9 @@ const char * const lang_nl_NL[_L_COUNT] = { [_L_KNOW] = "Begrepen", [_L_RANDOM_GENERATION] = "Willekeurige Tag", [_L_AUTO_RANDOM_GENERATION] = "Automatische Randomisatie", + [_L_SET_CUSTOM_ID] = "", + [_L_INPUT_ID] = "", + [_L_INAVLID_ID] = "", [_L_SHOW_QRCODE] = "QR-Code Weergeven", [_L_READ_ONLY] = "", [_L_DELETE_TAG] = "Tag Verwijderen", diff --git a/fw/application/src/i18n/pt_BR.c b/fw/application/src/i18n/pt_BR.c index 94973874..cfde87a1 100644 --- a/fw/application/src/i18n/pt_BR.c +++ b/fw/application/src/i18n/pt_BR.c @@ -7,6 +7,7 @@ const char * const lang_pt_BR[_L_COUNT] = { [_L_BACK] = "Voltar", [_L_ERR] = "Erro", [_L_ERR_CODE] = "Código de Erro", + [_L_FAILED] = "", [_L_APP_AMIIBO] = "Emulador de Amiibo", [_L_APP_AMIIBOLINK] = "AmiiboLink", [_L_APP_BLE] = "Transferência de Arquivos BLE", @@ -46,6 +47,9 @@ const char * const lang_pt_BR[_L_COUNT] = { [_L_KNOW] = "Entendi", [_L_RANDOM_GENERATION] = "Randomizar Etiqueta", [_L_AUTO_RANDOM_GENERATION] = "Randomização Automática", + [_L_SET_CUSTOM_ID] = "", + [_L_INPUT_ID] = "", + [_L_INAVLID_ID] = "", [_L_SHOW_QRCODE] = "Exibir QR Code", [_L_READ_ONLY] = "", [_L_DELETE_TAG] = "Excluir Etiqueta", diff --git a/fw/application/src/i18n/ru_RU.c b/fw/application/src/i18n/ru_RU.c index ad09c9ba..0cf77478 100644 --- a/fw/application/src/i18n/ru_RU.c +++ b/fw/application/src/i18n/ru_RU.c @@ -7,6 +7,7 @@ const char * const lang_ru_RU[_L_COUNT] = { [_L_BACK] = "[Назад]", [_L_ERR] = "Ошибка", [_L_ERR_CODE] = "Код ошибки", + [_L_FAILED] = "", [_L_APP_AMIIBO] = "Эмулятор Amiibo", [_L_APP_AMIIBOLINK] = "AmiiboLink", [_L_APP_BLE] = "Передача файлов", @@ -46,6 +47,9 @@ const char * const lang_ru_RU[_L_COUNT] = { [_L_KNOW] = "[Понятно]", [_L_RANDOM_GENERATION] = "Сгенерировать UUID", [_L_AUTO_RANDOM_GENERATION] = "Автогенерация", + [_L_SET_CUSTOM_ID] = "", + [_L_INPUT_ID] = "", + [_L_INAVLID_ID] = "", [_L_SHOW_QRCODE] = "QR-код", [_L_READ_ONLY] = "Только чтение", [_L_DELETE_TAG] = "Удалить тег", diff --git a/fw/application/src/i18n/string_id.h b/fw/application/src/i18n/string_id.h index 0e77b56f..35954f1c 100644 --- a/fw/application/src/i18n/string_id.h +++ b/fw/application/src/i18n/string_id.h @@ -8,6 +8,7 @@ typedef enum { _L_BACK, _L_ERR, _L_ERR_CODE, + _L_FAILED, _L_APP_AMIIBO, _L_APP_AMIIBOLINK, _L_APP_BLE, @@ -47,6 +48,9 @@ typedef enum { _L_KNOW, _L_RANDOM_GENERATION, _L_AUTO_RANDOM_GENERATION, + _L_SET_CUSTOM_ID, + _L_INPUT_ID, + _L_INAVLID_ID, _L_SHOW_QRCODE, _L_READ_ONLY, _L_DELETE_TAG, diff --git a/fw/application/src/i18n/zh_Hans.c b/fw/application/src/i18n/zh_Hans.c index 719a6087..5bde367c 100644 --- a/fw/application/src/i18n/zh_Hans.c +++ b/fw/application/src/i18n/zh_Hans.c @@ -7,6 +7,7 @@ const char * const lang_zh_Hans[_L_COUNT] = { [_L_BACK] = "返回", [_L_ERR] = "错误", [_L_ERR_CODE] = "错误码", + [_L_FAILED] = "失败", [_L_APP_AMIIBO] = "Amiibo模拟器", [_L_APP_AMIIBOLINK] = "AmiiboLink", [_L_APP_BLE] = "蓝牙传输", @@ -46,6 +47,9 @@ const char * const lang_zh_Hans[_L_COUNT] = { [_L_KNOW] = "知道了", [_L_RANDOM_GENERATION] = "随机生成", [_L_AUTO_RANDOM_GENERATION] = "自动随机生成", + [_L_SET_CUSTOM_ID] = "自定义 ID", + [_L_INPUT_ID] = "输入 ID", + [_L_INAVLID_ID] = "无效的 ID", [_L_SHOW_QRCODE] = "显示二维码", [_L_READ_ONLY] = "禁止写入", [_L_DELETE_TAG] = "删除标签", diff --git a/fw/application/src/i18n/zh_TW.c b/fw/application/src/i18n/zh_TW.c index 6df779ee..8a2d29ea 100644 --- a/fw/application/src/i18n/zh_TW.c +++ b/fw/application/src/i18n/zh_TW.c @@ -7,6 +7,7 @@ const char * const lang_zh_TW[_L_COUNT] = { [_L_BACK] = "返回", [_L_ERR] = "錯誤", [_L_ERR_CODE] = "錯誤碼", + [_L_FAILED] = "失敗", [_L_APP_AMIIBO] = "Amiibo模擬器", [_L_APP_AMIIBOLINK] = "AmiiboLink", [_L_APP_BLE] = "藍牙傳送", @@ -46,6 +47,9 @@ const char * const lang_zh_TW[_L_COUNT] = { [_L_KNOW] = "知道了", [_L_RANDOM_GENERATION] = "隨機產生", [_L_AUTO_RANDOM_GENERATION] = "自動隨機產生", + [_L_SET_CUSTOM_ID] = "自定義 ID", + [_L_INPUT_ID] = "输入 ID", + [_L_INAVLID_ID] = "無效的 ID", [_L_SHOW_QRCODE] = "顯示二維碼", [_L_READ_ONLY] = "禁止寫入", [_L_DELETE_TAG] = "刪除標籤", diff --git a/fw/application/src/ntag/ntag_store.c b/fw/application/src/ntag/ntag_store.c index f8c197ff..36b9631a 100644 --- a/fw/application/src/ntag/ntag_store.c +++ b/fw/application/src/ntag/ntag_store.c @@ -6,69 +6,83 @@ */ #include "ntag_store.h" -//#include "fds.h" +// #include "fds.h" #include "nrf_log.h" #include "utils2.h" #include "vfs.h" const ntag_t default_ntag215 = { - .data = {0x04, 0x68, 0x95, 0x71, 0xfa, 0x5c, 0x64, 0x80, 0x42, 0x48, 0x00, 0x00, 0xe1, - 0x10, 0x3e, 0x00, 0x03, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xf1, 0x10, 0xff, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x10, 0xff, 0xee, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xbd, 0x04, 0x00, 0x00, 0xff, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - }; + .data = {0x04, 0x68, 0x95, 0x71, 0xfa, 0x5c, 0x64, 0x80, 0x42, 0x48, 0x00, 0x00, 0xe1, 0x10, 0x3e, 0x00, 0x03, + 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x10, 0xff, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf1, 0x10, 0xff, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x04, 0x00, 0x00, + 0xff, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +}; ret_code_t ntag_store_generate(uint8_t idx, ntag_t *ntag) { memcpy(ntag, &default_ntag215, sizeof(ntag_t)); ntag->data[7] = idx; - //ntag->index = idx; - // BCC 0 is always equal to UID0 ⊕ UID 1 ⊕ UID 2 ⊕ 0x88 - // ntag->data[3] = ntag->data[0] ^ ntag->data[1] ^ ntag->data[2] ^ 0x88; - // BCC 1 is always equal to UID3 ⊕ UID 4 ⊕ UID 5 ⊕ UID6 + // ntag->index = idx; + // BCC 0 is always equal to UID0 ⊕ UID 1 ⊕ UID 2 ⊕ 0x88 + // ntag->data[3] = ntag->data[0] ^ ntag->data[1] ^ ntag->data[2] ^ 0x88; + // BCC 1 is always equal to UID3 ⊕ UID 4 ⊕ UID 5 ⊕ UID6 ntag->data[8] = ntag->data[4] ^ ntag->data[5] ^ ntag->data[6] ^ ntag->data[7]; return NRF_SUCCESS; } +void ntag_store_set_uuid(ntag_t *ntag, uint8_t *uuid) { + + ntag->data[0] = uuid[0]; // fixed + ntag->data[1] = uuid[1]; + ntag->data[2] = uuid[2]; + // BCC 0 is always equal to UID0 ⊕ UID 1 ⊕ UID 2 ⊕ 0x88 + ntag->data[3] = ntag->data[0] ^ ntag->data[1] ^ ntag->data[2] ^ 0x88; + ntag->data[4] = uuid[3]; + ntag->data[5] = uuid[4]; + ntag->data[6] = uuid[5]; + ntag->data[7] = uuid[6]; + + // BCC 1 is always equal to UID3 ⊕ UID 4 ⊕ UID 5 ⊕ UID6 + ntag->data[8] = ntag->data[4] ^ ntag->data[5] ^ ntag->data[6] ^ ntag->data[7]; +} +void ntag_store_get_uuid(ntag_t *ntag, uint8_t *uuid) { + uuid[0] = ntag->data[0]; + uuid[1] = ntag->data[1]; + uuid[2] = ntag->data[2]; + uuid[3] = ntag->data[4]; + uuid[4] = ntag->data[5]; + uuid[5] = ntag->data[6]; + uuid[6] = ntag->data[7]; +} ret_code_t ntag_store_uuid_rand(ntag_t *ntag) { @@ -92,15 +106,14 @@ ret_code_t ntag_store_uuid_rand(ntag_t *ntag) { return NRF_SUCCESS; } -void ntag_store_new_rand(ntag_t* ntag){ +void ntag_store_new_rand(ntag_t *ntag) { memcpy(ntag, &default_ntag215, sizeof(ntag_t)); ntag_store_uuid_rand(ntag); } #ifdef INTERNAL_ENABLE -static volatile bool m_fds_ready = - false; /**< Flag used to indicate that FDS initialization is finished. */ +static volatile bool m_fds_ready = false; /**< Flag used to indicate that FDS initialization is finished. */ static volatile ret_code_t m_fs_op_retcode = NRF_SUCCESS; #define FILE_ID 0xAABB @@ -168,8 +181,7 @@ ret_code_t ntag_store_read(uint8_t idx, ntag_t *tag) { memcpy(tag->data, flash_record.p_data, NTAG_DATA_SIZE); // Print file length and raw message data. - NRF_LOG_DEBUG("NDEF file data length: %u bytes.", - flash_record.p_header->length_words * sizeof(uint32_t)); + NRF_LOG_DEBUG("NDEF file data length: %u bytes.", flash_record.p_header->length_words * sizeof(uint32_t)); // Close the record when done. err_code = fds_record_close(&m_record_desc); diff --git a/fw/application/src/ntag/ntag_store.h b/fw/application/src/ntag/ntag_store.h index 439fa1da..11907b01 100644 --- a/fw/application/src/ntag/ntag_store.h +++ b/fw/application/src/ntag/ntag_store.h @@ -8,20 +8,21 @@ #ifndef NTAG_STORE_H_ #define NTAG_STORE_H_ -#include -#include #include "compiler_abstraction.h" -#include "sdk_errors.h" #include "ntag_def.h" +#include "sdk_errors.h" +#include +#include -//填充默认ntag数据并随机uuid -void ntag_store_new_rand(ntag_t* ntag); -//随机uuid数据(不修改其他) +// 填充默认ntag数据并随机uuid +void ntag_store_new_rand(ntag_t *ntag); +// 随机uuid数据(不修改其他) ret_code_t ntag_store_uuid_rand(ntag_t *ntag); +void ntag_store_set_uuid(ntag_t *ntag, uint8_t *uuid); +void ntag_store_get_uuid(ntag_t *ntag, uint8_t *uuid); ret_code_t ntag_store_read(uint8_t idx, ntag_t *ntag); ret_code_t ntag_store_write(uint8_t idx, ntag_t *ntag); ret_code_t ntag_store_reset(uint8_t idx, ntag_t *ntag); - #endif /* NTAG_STORE_H_ */