[FL-2843] NFC fixes (#1764)

* nfc: fix empty desfire card message
* nfc: limit total user keys to list
* nfc: increase popup timeout

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
gornekich 2022-09-21 18:53:25 +03:00 committed by GitHub
parent 432ff41d6a
commit e70121e20f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 127 additions and 76 deletions

View File

@ -1,49 +1,88 @@
#include "../nfc_i.h" #include "../nfc_i.h"
void nfc_scene_mf_classic_keys_list_submenu_callback(void* context, uint32_t index) { #define NFC_SCENE_MF_CLASSIC_KEYS_LIST_MAX (100)
Nfc* nfc = context;
void nfc_scene_mf_classic_keys_list_submenu_callback(void* context, uint32_t index) {
furi_assert(context);
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, index); view_dispatcher_send_custom_event(nfc->view_dispatcher, index);
} }
void nfc_scene_mf_classic_keys_list_on_enter(void* context) { void nfc_scene_mf_classic_keys_list_popup_callback(void* context) {
furi_assert(context);
Nfc* nfc = context; Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit);
}
void nfc_scene_mf_classic_keys_list_prepare(Nfc* nfc, MfClassicDict* dict) {
Submenu* submenu = nfc->submenu; Submenu* submenu = nfc->submenu;
MfClassicDict* dict = mf_classic_dict_alloc(MfClassicDictTypeUser);
uint32_t index = 0; uint32_t index = 0;
string_t temp_key; string_t temp_key;
MfClassicUserKeys_init(nfc->mfc_key_strs);
string_init(temp_key); string_init(temp_key);
if(dict) {
mf_classic_dict_rewind(dict); submenu_set_header(submenu, "Select key to delete:");
while(mf_classic_dict_get_next_key_str(dict, temp_key)) { while(mf_classic_dict_get_next_key_str(dict, temp_key)) {
char* current_key = (char*)malloc(sizeof(char) * 13); char* current_key = (char*)malloc(sizeof(char) * 13);
strncpy(current_key, string_get_cstr(temp_key), 12); strncpy(current_key, string_get_cstr(temp_key), 12);
MfClassicUserKeys_push_back(nfc->mfc_key_strs, current_key); MfClassicUserKeys_push_back(nfc->mfc_key_strs, current_key);
FURI_LOG_D("ListKeys", "Key %d: %s", index, current_key); FURI_LOG_D("ListKeys", "Key %d: %s", index, current_key);
submenu_add_item( submenu_add_item(
submenu, submenu, current_key, index++, nfc_scene_mf_classic_keys_list_submenu_callback, nfc);
current_key,
index++,
nfc_scene_mf_classic_keys_list_submenu_callback,
nfc);
} }
}
submenu_set_header(submenu, "Select key to delete:");
mf_classic_dict_free(dict);
string_clear(temp_key); string_clear(temp_key);
}
void nfc_scene_mf_classic_keys_list_on_enter(void* context) {
Nfc* nfc = context;
MfClassicDict* dict = mf_classic_dict_alloc(MfClassicDictTypeUser);
MfClassicUserKeys_init(nfc->mfc_key_strs);
if(dict) {
uint32_t total_user_keys = mf_classic_dict_get_total_keys(dict);
if(total_user_keys < NFC_SCENE_MF_CLASSIC_KEYS_LIST_MAX) {
nfc_scene_mf_classic_keys_list_prepare(nfc, dict);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu);
} else {
popup_set_header(nfc->popup, "Too many keys!", 64, 0, AlignCenter, AlignTop);
popup_set_text(
nfc->popup,
"Edit user dictionary\nwith file browser",
64,
12,
AlignCenter,
AlignTop);
popup_set_callback(nfc->popup, nfc_scene_mf_classic_keys_list_popup_callback);
popup_set_context(nfc->popup, nfc);
popup_set_timeout(nfc->popup, 3000);
popup_enable_timeout(nfc->popup);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
}
mf_classic_dict_free(dict);
} else {
popup_set_header(
nfc->popup, "Failed to load dictionary", 64, 32, AlignCenter, AlignCenter);
popup_set_callback(nfc->popup, nfc_scene_mf_classic_keys_list_popup_callback);
popup_set_context(nfc->popup, nfc);
popup_set_timeout(nfc->popup, 3000);
popup_enable_timeout(nfc->popup);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
}
} }
bool nfc_scene_mf_classic_keys_list_on_event(void* context, SceneManagerEvent event) { bool nfc_scene_mf_classic_keys_list_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = context; Nfc* nfc = context;
bool consumed = false; bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
if(event.event == NfcCustomEventViewExit) {
consumed = scene_manager_previous_scene(nfc->scene_manager);
} else {
scene_manager_set_scene_state( scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneMfClassicKeysDelete, event.event); nfc->scene_manager, NfcSceneMfClassicKeysDelete, event.event);
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicKeysDelete); scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicKeysDelete);
consumed = true; consumed = true;
} }
}
return consumed; return consumed;
} }
@ -57,4 +96,5 @@ void nfc_scene_mf_classic_keys_list_on_exit(void* context) {
} }
MfClassicUserKeys_clear(nfc->mfc_key_strs); MfClassicUserKeys_clear(nfc->mfc_key_strs);
submenu_reset(nfc->submenu); submenu_reset(nfc->submenu);
popup_reset(nfc->popup);
} }

View File

@ -7,6 +7,13 @@ enum SubmenuIndex {
SubmenuIndexDynamic, // dynamic indexes start here SubmenuIndexDynamic, // dynamic indexes start here
}; };
void nfc_scene_mf_desfire_popup_callback(void* context) {
furi_assert(context);
Nfc* nfc = context;
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit);
}
MifareDesfireApplication* nfc_scene_mf_desfire_app_get_app(Nfc* nfc) { MifareDesfireApplication* nfc_scene_mf_desfire_app_get_app(Nfc* nfc) {
uint32_t app_idx = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfDesfireApp) >> uint32_t app_idx = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfDesfireApp) >>
1; 1;
@ -25,27 +32,24 @@ void nfc_scene_mf_desfire_app_submenu_callback(void* context, uint32_t index) {
void nfc_scene_mf_desfire_app_on_enter(void* context) { void nfc_scene_mf_desfire_app_on_enter(void* context) {
Nfc* nfc = context; Nfc* nfc = context;
Submenu* submenu = nfc->submenu;
MifareDesfireApplication* app = nfc_scene_mf_desfire_app_get_app(nfc); MifareDesfireApplication* app = nfc_scene_mf_desfire_app_get_app(nfc);
if(!app) { if(!app) {
popup_set_icon(nfc->popup, 5, 5, &I_WarningDolphin_45x42); popup_set_icon(nfc->popup, 5, 5, &I_WarningDolphin_45x42);
popup_set_header(nfc->popup, "Internal Error!", 55, 12, AlignLeft, AlignBottom); popup_set_header(nfc->popup, "Empty card!", 55, 12, AlignLeft, AlignBottom);
popup_set_text( popup_set_callback(nfc->popup, nfc_scene_mf_desfire_popup_callback);
nfc->popup, popup_set_context(nfc->popup, nfc);
"No app selected.\nThis should\nnever happen,\nplease file a bug.", popup_set_timeout(nfc->popup, 3000);
55, popup_enable_timeout(nfc->popup);
15, popup_set_text(nfc->popup, "No application\nfound.", 55, 15, AlignLeft, AlignTop);
AlignLeft,
AlignTop);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
FURI_LOG_E(TAG, "Bad state. No app selected?"); } else {
return;
}
text_box_set_font(nfc->text_box, TextBoxFontHex); text_box_set_font(nfc->text_box, TextBoxFontHex);
submenu_add_item( submenu_add_item(
submenu, "App info", SubmenuIndexAppInfo, nfc_scene_mf_desfire_app_submenu_callback, nfc); nfc->submenu,
"App info",
SubmenuIndexAppInfo,
nfc_scene_mf_desfire_app_submenu_callback,
nfc);
uint16_t cap = NFC_TEXT_STORE_SIZE; uint16_t cap = NFC_TEXT_STORE_SIZE;
char* buf = nfc->text_store; char* buf = nfc->text_store;
@ -61,10 +65,12 @@ void nfc_scene_mf_desfire_app_on_enter(void* context) {
char* label = buf; char* label = buf;
cap -= size + 1; cap -= size + 1;
buf += size + 1; buf += size + 1;
submenu_add_item(submenu, label, idx++, nfc_scene_mf_desfire_app_submenu_callback, nfc); submenu_add_item(
nfc->submenu, label, idx++, nfc_scene_mf_desfire_app_submenu_callback, nfc);
} }
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu);
}
} }
bool nfc_scene_mf_desfire_app_on_event(void* context, SceneManagerEvent event) { bool nfc_scene_mf_desfire_app_on_event(void* context, SceneManagerEvent event) {
@ -73,6 +79,9 @@ bool nfc_scene_mf_desfire_app_on_event(void* context, SceneManagerEvent event) {
uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfDesfireApp); uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfDesfireApp);
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
if(event.event == NfcCustomEventViewExit) {
consumed = scene_manager_previous_scene(nfc->scene_manager);
} else {
MifareDesfireApplication* app = nfc_scene_mf_desfire_app_get_app(nfc); MifareDesfireApplication* app = nfc_scene_mf_desfire_app_get_app(nfc);
TextBox* text_box = nfc->text_box; TextBox* text_box = nfc->text_box;
string_reset(nfc->text_box_store); string_reset(nfc->text_box_store);
@ -93,6 +102,7 @@ bool nfc_scene_mf_desfire_app_on_event(void* context, SceneManagerEvent event) {
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMfDesfireApp, state | 1); scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMfDesfireApp, state | 1);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox);
consumed = true; consumed = true;
}
} else if(event.type == SceneManagerEventTypeBack) { } else if(event.type == SceneManagerEventTypeBack) {
if(state & 1) { if(state & 1) {
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu);
@ -108,6 +118,7 @@ void nfc_scene_mf_desfire_app_on_exit(void* context) {
Nfc* nfc = context; Nfc* nfc = context;
// Clear views // Clear views
popup_reset(nfc->popup);
text_box_reset(nfc->text_box); text_box_reset(nfc->text_box);
string_reset(nfc->text_box_store); string_reset(nfc->text_box_store);
submenu_reset(nfc->submenu); submenu_reset(nfc->submenu);