[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:
		
							parent
							
								
									432ff41d6a
								
							
						
					
					
						commit
						e70121e20f
					
				| @ -1,48 +1,87 @@ | |||||||
| #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_popup_callback(void* context) { | ||||||
|  |     furi_assert(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; | ||||||
|  |     uint32_t index = 0; | ||||||
|  |     string_t temp_key; | ||||||
|  |     string_init(temp_key); | ||||||
|  | 
 | ||||||
|  |     submenu_set_header(submenu, "Select key to delete:"); | ||||||
|  |     while(mf_classic_dict_get_next_key_str(dict, temp_key)) { | ||||||
|  |         char* current_key = (char*)malloc(sizeof(char) * 13); | ||||||
|  |         strncpy(current_key, string_get_cstr(temp_key), 12); | ||||||
|  |         MfClassicUserKeys_push_back(nfc->mfc_key_strs, current_key); | ||||||
|  |         FURI_LOG_D("ListKeys", "Key %d: %s", index, current_key); | ||||||
|  |         submenu_add_item( | ||||||
|  |             submenu, current_key, index++, nfc_scene_mf_classic_keys_list_submenu_callback, nfc); | ||||||
|  |     } | ||||||
|  |     string_clear(temp_key); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void nfc_scene_mf_classic_keys_list_on_enter(void* context) { | void nfc_scene_mf_classic_keys_list_on_enter(void* context) { | ||||||
|     Nfc* nfc = context; |     Nfc* nfc = context; | ||||||
|     Submenu* submenu = nfc->submenu; |  | ||||||
|     MfClassicDict* dict = mf_classic_dict_alloc(MfClassicDictTypeUser); |     MfClassicDict* dict = mf_classic_dict_alloc(MfClassicDictTypeUser); | ||||||
|     uint32_t index = 0; |  | ||||||
|     string_t temp_key; |  | ||||||
|     MfClassicUserKeys_init(nfc->mfc_key_strs); |     MfClassicUserKeys_init(nfc->mfc_key_strs); | ||||||
|     string_init(temp_key); |  | ||||||
|     if(dict) { |     if(dict) { | ||||||
|         mf_classic_dict_rewind(dict); |         uint32_t total_user_keys = mf_classic_dict_get_total_keys(dict); | ||||||
|         while(mf_classic_dict_get_next_key_str(dict, temp_key)) { |         if(total_user_keys < NFC_SCENE_MF_CLASSIC_KEYS_LIST_MAX) { | ||||||
|             char* current_key = (char*)malloc(sizeof(char) * 13); |             nfc_scene_mf_classic_keys_list_prepare(nfc, dict); | ||||||
|             strncpy(current_key, string_get_cstr(temp_key), 12); |             view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); | ||||||
|             MfClassicUserKeys_push_back(nfc->mfc_key_strs, current_key); |         } else { | ||||||
|             FURI_LOG_D("ListKeys", "Key %d: %s", index, current_key); |             popup_set_header(nfc->popup, "Too many keys!", 64, 0, AlignCenter, AlignTop); | ||||||
|             submenu_add_item( |             popup_set_text( | ||||||
|                 submenu, |                 nfc->popup, | ||||||
|                 current_key, |                 "Edit user dictionary\nwith file browser", | ||||||
|                 index++, |                 64, | ||||||
|                 nfc_scene_mf_classic_keys_list_submenu_callback, |                 12, | ||||||
|                 nfc); |                 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); | ||||||
|     } |     } | ||||||
|     submenu_set_header(submenu, "Select key to delete:"); |  | ||||||
|     mf_classic_dict_free(dict); |  | ||||||
|     string_clear(temp_key); |  | ||||||
|     view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 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) { | ||||||
|         scene_manager_set_scene_state( |         if(event.event == NfcCustomEventViewExit) { | ||||||
|             nfc->scene_manager, NfcSceneMfClassicKeysDelete, event.event); |             consumed = scene_manager_previous_scene(nfc->scene_manager); | ||||||
|         scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicKeysDelete); |         } else { | ||||||
|         consumed = true; |             scene_manager_set_scene_state( | ||||||
|  |                 nfc->scene_manager, NfcSceneMfClassicKeysDelete, event.event); | ||||||
|  |             scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicKeysDelete); | ||||||
|  |             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); | ||||||
| } | } | ||||||
|  | |||||||
| @ -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,46 +32,45 @@ 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); | ||||||
|     } |         submenu_add_item( | ||||||
|  |             nfc->submenu, | ||||||
|  |             "App info", | ||||||
|  |             SubmenuIndexAppInfo, | ||||||
|  |             nfc_scene_mf_desfire_app_submenu_callback, | ||||||
|  |             nfc); | ||||||
| 
 | 
 | ||||||
|     text_box_set_font(nfc->text_box, TextBoxFontHex); |         uint16_t cap = NFC_TEXT_STORE_SIZE; | ||||||
| 
 |         char* buf = nfc->text_store; | ||||||
|     submenu_add_item( |         int idx = SubmenuIndexDynamic; | ||||||
|         submenu, "App info", SubmenuIndexAppInfo, nfc_scene_mf_desfire_app_submenu_callback, nfc); |         for(MifareDesfireFile* file = app->file_head; file; file = file->next) { | ||||||
| 
 |             int size = snprintf(buf, cap, "File %d", file->id); | ||||||
|     uint16_t cap = NFC_TEXT_STORE_SIZE; |             if(size < 0 || size >= cap) { | ||||||
|     char* buf = nfc->text_store; |                 FURI_LOG_W( | ||||||
|     int idx = SubmenuIndexDynamic; |                     TAG, | ||||||
|     for(MifareDesfireFile* file = app->file_head; file; file = file->next) { |                     "Exceeded NFC_TEXT_STORE_SIZE when preparing file id strings; menu truncated"); | ||||||
|         int size = snprintf(buf, cap, "File %d", file->id); |                 break; | ||||||
|         if(size < 0 || size >= cap) { |             } | ||||||
|             FURI_LOG_W( |             char* label = buf; | ||||||
|                 TAG, |             cap -= size + 1; | ||||||
|                 "Exceeded NFC_TEXT_STORE_SIZE when preparing file id strings; menu truncated"); |             buf += size + 1; | ||||||
|             break; |             submenu_add_item( | ||||||
|  |                 nfc->submenu, label, idx++, nfc_scene_mf_desfire_app_submenu_callback, nfc); | ||||||
|         } |         } | ||||||
|         char* label = buf; |  | ||||||
|         cap -= size + 1; |  | ||||||
|         buf += size + 1; |  | ||||||
|         submenu_add_item(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,26 +79,30 @@ 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) { | ||||||
|         MifareDesfireApplication* app = nfc_scene_mf_desfire_app_get_app(nfc); |         if(event.event == NfcCustomEventViewExit) { | ||||||
|         TextBox* text_box = nfc->text_box; |             consumed = scene_manager_previous_scene(nfc->scene_manager); | ||||||
|         string_reset(nfc->text_box_store); |  | ||||||
|         if(event.event == SubmenuIndexAppInfo) { |  | ||||||
|             mf_df_cat_application_info(app, nfc->text_box_store); |  | ||||||
|         } else { |         } else { | ||||||
|             uint16_t index = event.event - SubmenuIndexDynamic; |             MifareDesfireApplication* app = nfc_scene_mf_desfire_app_get_app(nfc); | ||||||
|             MifareDesfireFile* file = app->file_head; |             TextBox* text_box = nfc->text_box; | ||||||
|             for(int i = 0; file && i < index; i++) { |             string_reset(nfc->text_box_store); | ||||||
|                 file = file->next; |             if(event.event == SubmenuIndexAppInfo) { | ||||||
|  |                 mf_df_cat_application_info(app, nfc->text_box_store); | ||||||
|  |             } else { | ||||||
|  |                 uint16_t index = event.event - SubmenuIndexDynamic; | ||||||
|  |                 MifareDesfireFile* file = app->file_head; | ||||||
|  |                 for(int i = 0; file && i < index; i++) { | ||||||
|  |                     file = file->next; | ||||||
|  |                 } | ||||||
|  |                 if(!file) { | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  |                 mf_df_cat_file(file, nfc->text_box_store); | ||||||
|             } |             } | ||||||
|             if(!file) { |             text_box_set_text(text_box, string_get_cstr(nfc->text_box_store)); | ||||||
|                 return false; |             scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMfDesfireApp, state | 1); | ||||||
|             } |             view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); | ||||||
|             mf_df_cat_file(file, nfc->text_box_store); |             consumed = true; | ||||||
|         } |         } | ||||||
|         text_box_set_text(text_box, string_get_cstr(nfc->text_box_store)); |  | ||||||
|         scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMfDesfireApp, state | 1); |  | ||||||
|         view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox); |  | ||||||
|         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); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 gornekich
						gornekich