Skip to content

Commit a1965c7

Browse files
committed
Fixed solosky#270: add option to custom uid
1 parent 267783d commit a1965c7

20 files changed

+252
-69
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ fw/.settings
22
fw/_build
33
fw/.idea
44

5+
fw/application/.idea
6+
fw/bootloader/.idea
7+
58
fw/src/amiibo_private.c
69
fw/src/version.inc.h
710
fw/src/version.json

fw/application/src/amiibo_helper.c

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,31 @@ ret_code_t amiibo_helper_rand_amiibo_uuid(ntag_t *ntag) {
149149
return err_code;
150150
}
151151

152+
ret_code_t amiibo_helper_set_amiibo_uuid(ntag_t *ntag, uint8_t *uuid) {
153+
ret_code_t err_code;
154+
ntag_t ntag_new;
155+
ntag_t *ntag_current = ntag;
156+
157+
memcpy(&ntag_new, ntag_current, sizeof(ntag_t));
158+
159+
if (!is_valid_amiibo_ntag(ntag_current)) {
160+
return NRF_ERROR_INVALID_DATA;
161+
}
162+
163+
if (!amiibo_helper_is_key_loaded()) {
164+
return NRF_ERROR_INVALID_DATA;
165+
}
166+
167+
ntag_store_set_uuid(&ntag_new, uuid);
168+
169+
// sign new
170+
err_code = amiibo_helper_sign_new_ntag(ntag_current, &ntag_new);
171+
if (err_code == NRF_SUCCESS) {
172+
memcpy(ntag, &ntag_new, sizeof(ntag_t));
173+
}
174+
return err_code;
175+
}
176+
152177
ret_code_t amiibo_helper_generate_amiibo(uint32_t head, uint32_t tail, ntag_t *ntag) {
153178
if (!amiibo_helper_is_key_loaded()) {
154179
return NRF_ERROR_INVALID_DATA;
@@ -192,20 +217,18 @@ void amiibo_helper_try_load_amiibo_keys_from_vfs() {
192217
}
193218
}
194219

195-
uint32_t to_little_endian_int32(const uint8_t* data){
220+
uint32_t to_little_endian_int32(const uint8_t *data) {
196221
uint32_t val = 0;
197222
val += data[0];
198223
val <<= 8;
199224
val += data[1];
200225
val <<= 8;
201226
val += data[2];
202-
val <<=8;
227+
val <<= 8;
203228
val += data[3];
204229
return val;
205230
}
206231

207-
208-
209232
bool is_valid_amiibo_ntag(const ntag_t *ntag) {
210233
uint32_t head = to_little_endian_int32(&ntag->data[84]);
211234
uint32_t tail = to_little_endian_int32(&ntag->data[88]);
@@ -224,4 +247,3 @@ bool is_valid_amiibo_ntag(const ntag_t *ntag) {
224247

225248
return false;
226249
}
227-

fw/application/src/app/amiibo/app_amiibo.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ void app_amiibo_on_run(mini_app_inst_t *p_app_inst) {
4646
p_app_handle->p_msg_box = mui_msg_box_create();
4747
mui_msg_box_set_user_data(p_app_handle->p_msg_box, p_app_handle);
4848

49+
p_app_handle->p_toast_view = mui_toast_view_create();
50+
mui_toast_view_set_user_data(p_app_handle->p_toast_view, p_app_handle);
51+
4952
p_app_handle->p_scene_dispatcher = mui_scene_dispatcher_create();
5053

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

6871
mui_view_dispatcher_attach(p_app_handle->p_view_dispatcher, MUI_LAYER_FULLSCREEN);
6972

73+
p_app_handle->p_view_dispatcher_toast = mui_view_dispatcher_create();
74+
mui_view_dispatcher_add_view(p_app_handle->p_view_dispatcher_toast, AMIIBO_VIEW_ID_TOAST,
75+
mui_toast_view_get_view(p_app_handle->p_toast_view));
76+
mui_view_dispatcher_attach(p_app_handle->p_view_dispatcher_toast, MUI_LAYER_TOAST);
77+
mui_view_dispatcher_switch_to_view(p_app_handle->p_view_dispatcher_toast, AMIIBO_VIEW_ID_TOAST);
78+
7079
extern const ntag_t default_ntag215;
7180
APP_ERROR_CHECK(ntag_emu_init(&default_ntag215));
7281

@@ -133,6 +142,10 @@ void app_amiibo_on_kill(mini_app_inst_t *p_app_inst) {
133142
mui_scene_dispatcher_free(p_app_handle->p_scene_dispatcher);
134143
amiibo_detail_view_free(p_app_handle->p_amiibo_detail_view);
135144

145+
mui_view_dispatcher_detach(p_app_handle->p_view_dispatcher_toast, MUI_LAYER_TOAST);
146+
mui_view_dispatcher_free(p_app_handle->p_view_dispatcher_toast);
147+
mui_toast_view_free(p_app_handle->p_toast_view);
148+
136149
string_clear(p_app_handle->current_file);
137150
string_clear(p_app_handle->current_folder);
138151
string_array_clear(p_app_handle->amiibo_files);

fw/application/src/app/amiibo/app_amiibo.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,23 @@
77
#include "mui_msg_box.h"
88
#include "mui_scene_dispatcher.h"
99
#include "mui_text_input.h"
10+
#include "mui_toast_view.h"
1011
#include "ntag_def.h"
1112
#include "vfs.h"
1213

1314
#include "mlib_common.h"
1415

15-
1616
typedef struct {
1717
amiibo_detail_view_t *p_amiibo_detail_view;
1818
mui_list_view_t *p_list_view;
1919
mui_text_input_t *p_text_input;
2020
mui_msg_box_t *p_msg_box;
21+
mui_toast_view_t *p_toast_view;
2122
mui_view_dispatcher_t *p_view_dispatcher;
2223
mui_scene_dispatcher_t *p_scene_dispatcher;
24+
mui_view_dispatcher_t *p_view_dispatcher_toast;
2325
ntag_t ntag;
24-
26+
2527
/** file browser*/
2628
vfs_drive_t current_drive;
2729
string_t current_folder;
@@ -39,6 +41,7 @@ typedef enum {
3941
AMIIBO_VIEW_ID_DETAIL,
4042
AMIIBO_VIEW_ID_INPUT,
4143
AMIIBO_VIEW_ID_MSG_BOX,
44+
AMIIBO_VIEW_ID_TOAST
4245
} amiibo_view_id_t;
4346

4447
typedef struct {
@@ -50,7 +53,6 @@ typedef struct {
5053
uint32_t current_scene_id;
5154
} app_amiibo_cache_data_t;
5255

53-
5456
extern mini_app_t app_amiibo_info;
5557

5658
#endif

fw/application/src/app/amiibo/scene/amiibo_scene_amiibo_detail_menu.c

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ enum amiibo_detail_menu_t {
2121
AMIIBO_DETAIL_MENU_RAND_UID,
2222
AMIIBO_DETAIL_MENU_AUTO_RAND_UID,
2323
AMIIBO_DETAIL_MENU_READ_ONLY,
24+
AMIIBO_DETAIL_MENU_SET_CUSTOM_UID,
2425
AMIIBO_DETAIL_MENU_REMOVE_AMIIBO,
2526
AMIIBO_DETAIL_MENU_BACK_AMIIBO_DETAIL,
2627
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
3334
vfs_obj_t obj;
3435
uint8_t meta_buf[VFS_MAX_META_LEN];
3536

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

3939
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
112112
}
113113
}
114114

115+
static void amiibo_scene_amiibo_detail_menu_text_input_set_id_event_cb(mui_text_input_event_t event,
116+
mui_text_input_t *p_text_input) {
117+
app_amiibo_t *app = p_text_input->user_data;
118+
const char *input_text = mui_text_input_get_input_text(p_text_input);
119+
if (event == MUI_TEXT_INPUT_EVENT_CONFIRMED && strlen(input_text) > 0) {
120+
121+
int8_t uid[7];
122+
ret_code_t err_code;
123+
char path[VFS_MAX_PATH_LEN];
124+
125+
ntag_t *ntag = &app->ntag;
126+
127+
// read uid from input
128+
if (sscanf(input_text, "%02x.%02x.%02x.%02x.%02x.%02x.%02x", uid, uid + 1, uid + 2, uid + 3, uid + 4, uid + 5,
129+
uid + 6) != 7) {
130+
mui_toast_view_show(app->p_toast_view, _T(INAVLID_ID));
131+
return;
132+
}
133+
134+
// same uid as current tag
135+
uint8_t cur_uid[7];
136+
ntag_store_get_uuid(ntag, cur_uid);
137+
if (memcmp(cur_uid, uid, 7) == 0) {
138+
mui_scene_dispatcher_previous_scene(app->p_scene_dispatcher);
139+
return;
140+
}
141+
142+
// set current ntag uid
143+
err_code = amiibo_helper_set_amiibo_uuid(ntag, uid);
144+
if (err_code != NRF_SUCCESS) {
145+
mui_toast_view_show(app->p_toast_view, _T(FAILED));
146+
return;
147+
}
148+
149+
// set ntag emu to emulate new tag
150+
ntag_emu_set_tag(&app->ntag);
151+
152+
// save to file
153+
vfs_driver_t *p_driver = vfs_get_driver(app->current_drive);
154+
155+
cwalk_append_segment(path, string_get_cstr(app->current_folder), string_get_cstr(app->current_file));
156+
int32_t res = p_driver->write_file_data(path, ntag->data, sizeof(ntag->data));
157+
158+
if (res < 0) {
159+
mui_toast_view_show(app->p_toast_view, _T(FAILED));
160+
return;
161+
}
162+
163+
mui_scene_dispatcher_previous_scene(app->p_scene_dispatcher);
164+
} else {
165+
mui_scene_dispatcher_previous_scene(app->p_scene_dispatcher);
166+
}
167+
}
168+
115169
static void amiibo_scene_amiibo_detail_menu_on_selected(mui_list_view_event_t event, mui_list_view_t *p_list_view,
116170
mui_list_item_t *p_item) {
117171
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
168222
p_item, (p_settings->auto_gen_amiibo ? getLangString(_L_ON_F) : getLangString(_L_OFF_F)));
169223
} break;
170224

225+
case AMIIBO_DETAIL_MENU_SET_CUSTOM_UID: {
226+
char id_text[32];
227+
uint8_t id[7];
228+
ntag_t *ntag = &app->ntag;
229+
230+
if (!amiibo_helper_is_key_loaded()) {
231+
amiibo_scene_amiibo_detail_no_key_msg(app);
232+
return;
233+
}
234+
235+
ntag_store_get_uuid(ntag, id);
236+
237+
sprintf(id_text, "%02x.%02x.%02x.%02x.%02x.%02x.%02x", id[0], id[1], id[2], id[3], id[4], id[5], id[6]);
238+
239+
mui_text_input_set_header(app->p_text_input, getLangString(_L_INPUT_ID));
240+
mui_text_input_set_input_text(app->p_text_input, id_text);
241+
mui_text_input_set_event_cb(app->p_text_input, amiibo_scene_amiibo_detail_menu_text_input_set_id_event_cb);
242+
243+
mui_view_dispatcher_switch_to_view(app->p_view_dispatcher, AMIIBO_VIEW_ID_INPUT);
244+
} break;
245+
171246
case AMIIBO_DETAIL_MENU_READ_ONLY: {
172247
ret_code_t err_code = amiibo_scene_amiibo_detail_set_readonly(app, !app->ntag.read_only);
173248
if (err_code == NRF_SUCCESS) {
@@ -207,6 +282,9 @@ void amiibo_scene_amiibo_detail_menu_on_enter(void *user_data) {
207282
(p_settings->auto_gen_amiibo ? getLangString(_L_ON_F) : getLangString(_L_OFF_F)),
208283
(void *)AMIIBO_DETAIL_MENU_AUTO_RAND_UID);
209284

285+
mui_list_view_add_item(app->p_list_view, 0xe1c8, getLangString(_L_SET_CUSTOM_ID),
286+
(void *)AMIIBO_DETAIL_MENU_SET_CUSTOM_UID);
287+
210288
mui_list_view_add_item_ext(app->p_list_view, 0xe007, getLangString(_L_READ_ONLY),
211289
app->ntag.read_only ? getLangString(_L_ON_F) : getLangString(_L_OFF_F),
212290
(void *)AMIIBO_DETAIL_MENU_READ_ONLY);

fw/application/src/i18n/de_DE.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const char * const lang_de_DE[_L_COUNT] = {
77
[_L_BACK] = "Zurück",
88
[_L_ERR] = "Fehler",
99
[_L_ERR_CODE] = "Fehlercode",
10+
[_L_FAILED] = "",
1011
[_L_APP_AMIIBO] = "Amiibo Emulator",
1112
[_L_APP_AMIIBOLINK] = "AmiiboLink",
1213
[_L_APP_BLE] = "BLE Dateitransfer",
@@ -46,6 +47,9 @@ const char * const lang_de_DE[_L_COUNT] = {
4647
[_L_KNOW] = "Verstanden",
4748
[_L_RANDOM_GENERATION] = "Zufällige UUID",
4849
[_L_AUTO_RANDOM_GENERATION] = "Zufällige UUID (Automatisch)",
50+
[_L_SET_CUSTOM_ID] = "",
51+
[_L_INPUT_ID] = "",
52+
[_L_INAVLID_ID] = "",
4953
[_L_SHOW_QRCODE] = "QR Code",
5054
[_L_READ_ONLY] = "",
5155
[_L_DELETE_TAG] = "Tag löschen",

fw/application/src/i18n/en_US.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const char * const lang_en_US[_L_COUNT] = {
77
[_L_BACK] = "Back",
88
[_L_ERR] = "Error",
99
[_L_ERR_CODE] = "Error Code",
10+
[_L_FAILED] = "Failed",
1011
[_L_APP_AMIIBO] = "Amiibo Emulator",
1112
[_L_APP_AMIIBOLINK] = "AmiiboLink",
1213
[_L_APP_BLE] = "BLE File Transfer",
@@ -46,6 +47,9 @@ const char * const lang_en_US[_L_COUNT] = {
4647
[_L_KNOW] = "Got it",
4748
[_L_RANDOM_GENERATION] = "Rand. Tag",
4849
[_L_AUTO_RANDOM_GENERATION] = "Auto Rand.",
50+
[_L_SET_CUSTOM_ID] = "Set Custom ID",
51+
[_L_INPUT_ID] = "Input ID",
52+
[_L_INAVLID_ID] = "Invalid ID",
4953
[_L_SHOW_QRCODE] = "Display QR Code",
5054
[_L_READ_ONLY] = "Read-only",
5155
[_L_DELETE_TAG] = "Delete Tag",

fw/application/src/i18n/es_ES.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const char * const lang_es_ES[_L_COUNT] = {
77
[_L_BACK] = "[Atrás]",
88
[_L_ERR] = "Error",
99
[_L_ERR_CODE] = "Código error",
10+
[_L_FAILED] = "",
1011
[_L_APP_AMIIBO] = "Emulador de amiibo",
1112
[_L_APP_AMIIBOLINK] = "AmiiboLink",
1213
[_L_APP_BLE] = "Transferencia BLE",
@@ -46,6 +47,9 @@ const char * const lang_es_ES[_L_COUNT] = {
4647
[_L_KNOW] = "Entendido",
4748
[_L_RANDOM_GENERATION] = "Nuevo serial aleat.",
4849
[_L_AUTO_RANDOM_GENERATION] = "Serial alea. aut",
50+
[_L_SET_CUSTOM_ID] = "",
51+
[_L_INPUT_ID] = "",
52+
[_L_INAVLID_ID] = "",
4953
[_L_SHOW_QRCODE] = "Mostrar QR",
5054
[_L_READ_ONLY] = "",
5155
[_L_DELETE_TAG] = "Borrar amiibo...",

fw/application/src/i18n/fr_FR.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const char * const lang_fr_FR[_L_COUNT] = {
77
[_L_BACK] = "Retour",
88
[_L_ERR] = "Erreur",
99
[_L_ERR_CODE] = "Code d'Erreur",
10+
[_L_FAILED] = "",
1011
[_L_APP_AMIIBO] = "Emulateur Amiibo",
1112
[_L_APP_AMIIBOLINK] = "AmiiboLink",
1213
[_L_APP_BLE] = "Transfert de Fichiers BLE",
@@ -46,6 +47,9 @@ const char * const lang_fr_FR[_L_COUNT] = {
4647
[_L_KNOW] = "Compris",
4748
[_L_RANDOM_GENERATION] = "Randomiser la Balise",
4849
[_L_AUTO_RANDOM_GENERATION] = "Randomisation Automatique",
50+
[_L_SET_CUSTOM_ID] = "",
51+
[_L_INPUT_ID] = "",
52+
[_L_INAVLID_ID] = "",
4953
[_L_SHOW_QRCODE] = "Afficher le Code QR",
5054
[_L_READ_ONLY] = "",
5155
[_L_DELETE_TAG] = "Supprimer la Balise",

fw/application/src/i18n/hu_HU.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const char * const lang_hu_HU[_L_COUNT] = {
77
[_L_BACK] = "Vissza",
88
[_L_ERR] = "Hiba",
99
[_L_ERR_CODE] = "Hibakód",
10+
[_L_FAILED] = "",
1011
[_L_APP_AMIIBO] = "Amiibo Emulátor",
1112
[_L_APP_AMIIBOLINK] = "AmiiboLink",
1213
[_L_APP_BLE] = "BLE Fájltovábbítás",
@@ -46,6 +47,9 @@ const char * const lang_hu_HU[_L_COUNT] = {
4647
[_L_KNOW] = "Megvan",
4748
[_L_RANDOM_GENERATION] = "Véletlengenerátor",
4849
[_L_AUTO_RANDOM_GENERATION] = "Automat. Véletlengenerátor",
50+
[_L_SET_CUSTOM_ID] = "",
51+
[_L_INPUT_ID] = "",
52+
[_L_INAVLID_ID] = "",
4953
[_L_SHOW_QRCODE] = "QR-kód Megjelenítése",
5054
[_L_READ_ONLY] = "",
5155
[_L_DELETE_TAG] = "Címke Törlése",

0 commit comments

Comments
 (0)