Force card types in extra actions (#1961)
* Mifare Classic forced read * Add all the needed card types * nfc: remove unused scene * nfc: remove unused worker state * nfc: fix read card type scene state usage * nfc: move NfcReadMode to NfcDevData struct * nfc: fix bank card reading and scene navigation * nfc magic: fix magic deactifate function Co-authored-by: gornekich <n.gorbadey@gmail.com> Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									820afd2aec
								
							
						
					
					
						commit
						e7c4b40dbe
					
				| @ -60,3 +60,4 @@ ADD_SCENE(nfc, detect_reader, DetectReader) | ||||
| ADD_SCENE(nfc, mfkey_nonces_info, MfkeyNoncesInfo) | ||||
| ADD_SCENE(nfc, mfkey_complete, MfkeyComplete) | ||||
| ADD_SCENE(nfc, nfc_data_info, NfcDataInfo) | ||||
| ADD_SCENE(nfc, read_card_type, ReadCardType) | ||||
|  | ||||
| @ -29,8 +29,13 @@ bool nfc_scene_exit_confirm_on_event(void* context, SceneManagerEvent event) { | ||||
|         if(event.event == DialogExResultRight) { | ||||
|             consumed = scene_manager_previous_scene(nfc->scene_manager); | ||||
|         } else if(event.event == DialogExResultLeft) { | ||||
|             consumed = scene_manager_search_and_switch_to_previous_scene( | ||||
|                 nfc->scene_manager, NfcSceneStart); | ||||
|             if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneReadCardType)) { | ||||
|                 consumed = scene_manager_search_and_switch_to_previous_scene( | ||||
|                     nfc->scene_manager, NfcSceneReadCardType); | ||||
|             } else { | ||||
|                 consumed = scene_manager_search_and_switch_to_previous_scene( | ||||
|                     nfc->scene_manager, NfcSceneStart); | ||||
|             } | ||||
|         } | ||||
|     } else if(event.type == SceneManagerEventTypeBack) { | ||||
|         consumed = true; | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| #include "../nfc_i.h" | ||||
| 
 | ||||
| enum SubmenuIndex { | ||||
|     SubmenuIndexReadCardType, | ||||
|     SubmenuIndexMfClassicKeys, | ||||
|     SubmenuIndexMfUltralightUnlock, | ||||
| }; | ||||
| @ -15,6 +16,12 @@ void nfc_scene_extra_actions_on_enter(void* context) { | ||||
|     Nfc* nfc = context; | ||||
|     Submenu* submenu = nfc->submenu; | ||||
| 
 | ||||
|     submenu_add_item( | ||||
|         submenu, | ||||
|         "Read Specific Card Type", | ||||
|         SubmenuIndexReadCardType, | ||||
|         nfc_scene_extra_actions_submenu_callback, | ||||
|         nfc); | ||||
|     submenu_add_item( | ||||
|         submenu, | ||||
|         "Mifare Classic Keys", | ||||
| @ -44,9 +51,15 @@ bool nfc_scene_extra_actions_on_event(void* context, SceneManagerEvent event) { | ||||
|             consumed = true; | ||||
|         } else if(event.event == SubmenuIndexMfUltralightUnlock) { | ||||
|             scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightUnlockMenu); | ||||
|             consumed = true; | ||||
|         } else if(event.event == SubmenuIndexReadCardType) { | ||||
|             scene_manager_set_scene_state(nfc->scene_manager, NfcSceneReadCardType, 0); | ||||
|             scene_manager_next_scene(nfc->scene_manager, NfcSceneReadCardType); | ||||
|             consumed = true; | ||||
|         } | ||||
|         scene_manager_set_scene_state(nfc->scene_manager, NfcSceneExtraActions, event.event); | ||||
|     } | ||||
| 
 | ||||
|     return consumed; | ||||
| } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										97
									
								
								applications/main/nfc/scenes/nfc_scene_read_card_type.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								applications/main/nfc/scenes/nfc_scene_read_card_type.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,97 @@ | ||||
| #include "../nfc_i.h" | ||||
| #include "nfc_worker_i.h" | ||||
| 
 | ||||
| enum SubmenuIndex { | ||||
|     SubmenuIndexReadMifareClassic, | ||||
|     SubmenuIndexReadMifareDesfire, | ||||
|     SubmenuIndexReadMfUltralight, | ||||
|     SubmenuIndexReadEMV, | ||||
|     SubmenuIndexReadNFCA, | ||||
| }; | ||||
| 
 | ||||
| void nfc_scene_read_card_type_submenu_callback(void* context, uint32_t index) { | ||||
|     Nfc* nfc = context; | ||||
| 
 | ||||
|     view_dispatcher_send_custom_event(nfc->view_dispatcher, index); | ||||
| } | ||||
| 
 | ||||
| void nfc_scene_read_card_type_on_enter(void* context) { | ||||
|     Nfc* nfc = context; | ||||
|     Submenu* submenu = nfc->submenu; | ||||
| 
 | ||||
|     submenu_add_item( | ||||
|         submenu, | ||||
|         "Read Mifare Classic", | ||||
|         SubmenuIndexReadMifareClassic, | ||||
|         nfc_scene_read_card_type_submenu_callback, | ||||
|         nfc); | ||||
|     submenu_add_item( | ||||
|         submenu, | ||||
|         "Read Mifare DESFire", | ||||
|         SubmenuIndexReadMifareDesfire, | ||||
|         nfc_scene_read_card_type_submenu_callback, | ||||
|         nfc); | ||||
|     submenu_add_item( | ||||
|         submenu, | ||||
|         "Read NTAG/Ultralight", | ||||
|         SubmenuIndexReadMfUltralight, | ||||
|         nfc_scene_read_card_type_submenu_callback, | ||||
|         nfc); | ||||
|     submenu_add_item( | ||||
|         submenu, | ||||
|         "Read EMV card", | ||||
|         SubmenuIndexReadEMV, | ||||
|         nfc_scene_read_card_type_submenu_callback, | ||||
|         nfc); | ||||
|     submenu_add_item( | ||||
|         submenu, | ||||
|         "Read NFC-A data", | ||||
|         SubmenuIndexReadNFCA, | ||||
|         nfc_scene_read_card_type_submenu_callback, | ||||
|         nfc); | ||||
|     uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneReadCardType); | ||||
|     submenu_set_selected_item(submenu, state); | ||||
| 
 | ||||
|     view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu); | ||||
| } | ||||
| 
 | ||||
| bool nfc_scene_read_card_type_on_event(void* context, SceneManagerEvent event) { | ||||
|     Nfc* nfc = context; | ||||
|     bool consumed = false; | ||||
| 
 | ||||
|     if(event.type == SceneManagerEventTypeCustom) { | ||||
|         if(event.event == SubmenuIndexReadMifareClassic) { | ||||
|             nfc->dev->dev_data.read_mode = NfcReadModeMfClassic; | ||||
|             scene_manager_next_scene(nfc->scene_manager, NfcSceneRead); | ||||
|             consumed = true; | ||||
|         } | ||||
|         if(event.event == SubmenuIndexReadMifareDesfire) { | ||||
|             nfc->dev->dev_data.read_mode = NfcReadModeMfDesfire; | ||||
|             scene_manager_next_scene(nfc->scene_manager, NfcSceneRead); | ||||
|             consumed = true; | ||||
|         } | ||||
|         if(event.event == SubmenuIndexReadMfUltralight) { | ||||
|             nfc->dev->dev_data.read_mode = NfcReadModeMfUltralight; | ||||
|             scene_manager_next_scene(nfc->scene_manager, NfcSceneRead); | ||||
|             consumed = true; | ||||
|         } | ||||
|         if(event.event == SubmenuIndexReadEMV) { | ||||
|             nfc->dev->dev_data.read_mode = NfcReadModeEMV; | ||||
|             scene_manager_next_scene(nfc->scene_manager, NfcSceneRead); | ||||
|             consumed = true; | ||||
|         } | ||||
|         if(event.event == SubmenuIndexReadNFCA) { | ||||
|             nfc->dev->dev_data.read_mode = NfcReadModeNFCA; | ||||
|             scene_manager_next_scene(nfc->scene_manager, NfcSceneRead); | ||||
|             consumed = true; | ||||
|         } | ||||
|         scene_manager_set_scene_state(nfc->scene_manager, NfcSceneReadCardType, event.event); | ||||
|     } | ||||
|     return consumed; | ||||
| } | ||||
| 
 | ||||
| void nfc_scene_read_card_type_on_exit(void* context) { | ||||
|     Nfc* nfc = context; | ||||
| 
 | ||||
|     submenu_reset(nfc->submenu); | ||||
| } | ||||
| @ -1,4 +1,5 @@ | ||||
| #include "../nfc_i.h" | ||||
| #include "nfc_worker_i.h" | ||||
| #include <dolphin/dolphin.h> | ||||
| 
 | ||||
| enum SubmenuIndex { | ||||
| @ -47,6 +48,7 @@ bool nfc_scene_start_on_event(void* context, SceneManagerEvent event) { | ||||
| 
 | ||||
|     if(event.type == SceneManagerEventTypeCustom) { | ||||
|         if(event.event == SubmenuIndexRead) { | ||||
|             nfc->dev->dev_data.read_mode = NfcReadModeAuto; | ||||
|             scene_manager_next_scene(nfc->scene_manager, NfcSceneRead); | ||||
|             DOLPHIN_DEED(DolphinDeedNfcRead); | ||||
|             consumed = true; | ||||
|  | ||||
| @ -210,5 +210,5 @@ bool magic_wipe() { | ||||
| 
 | ||||
| void magic_deactivate() { | ||||
|     furi_hal_nfc_ll_txrx_off(); | ||||
|     furi_hal_nfc_start_sleep(); | ||||
|     furi_hal_nfc_sleep(); | ||||
| } | ||||
|  | ||||
| @ -167,7 +167,6 @@ void nfc_magic_worker_wipe(NfcMagicWorker* nfc_magic_worker) { | ||||
|         if(!magic_data_access_cmd()) continue; | ||||
|         if(!magic_write_blk(0, &block)) continue; | ||||
|         nfc_magic_worker->callback(NfcMagicWorkerEventSuccess, nfc_magic_worker->context); | ||||
|         magic_deactivate(); | ||||
|         break; | ||||
|     } | ||||
|     magic_deactivate(); | ||||
|  | ||||
| @ -51,9 +51,19 @@ typedef struct { | ||||
|     MfClassicDict* dict; | ||||
| } NfcMfClassicDictAttackData; | ||||
| 
 | ||||
| typedef enum { | ||||
|     NfcReadModeAuto, | ||||
|     NfcReadModeMfClassic, | ||||
|     NfcReadModeMfUltralight, | ||||
|     NfcReadModeMfDesfire, | ||||
|     NfcReadModeEMV, | ||||
|     NfcReadModeNFCA, | ||||
| } NfcReadMode; | ||||
| 
 | ||||
| typedef struct { | ||||
|     FuriHalNfcDevData nfc_data; | ||||
|     NfcProtocol protocol; | ||||
|     NfcReadMode read_mode; | ||||
|     union { | ||||
|         NfcReaderRequestData reader_data; | ||||
|         NfcMfClassicDictAttackData mf_classic_dict_attack_data; | ||||
|  | ||||
| @ -90,7 +90,11 @@ int32_t nfc_worker_task(void* context) { | ||||
|     furi_hal_nfc_exit_sleep(); | ||||
| 
 | ||||
|     if(nfc_worker->state == NfcWorkerStateRead) { | ||||
|         nfc_worker_read(nfc_worker); | ||||
|         if(nfc_worker->dev_data->read_mode == NfcReadModeAuto) { | ||||
|             nfc_worker_read(nfc_worker); | ||||
|         } else { | ||||
|             nfc_worker_read_type(nfc_worker); | ||||
|         } | ||||
|     } else if(nfc_worker->state == NfcWorkerStateUidEmulate) { | ||||
|         nfc_worker_emulate_uid(nfc_worker); | ||||
|     } else if(nfc_worker->state == NfcWorkerStateEmulateApdu) { | ||||
| @ -394,6 +398,81 @@ void nfc_worker_read(NfcWorker* nfc_worker) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void nfc_worker_read_type(NfcWorker* nfc_worker) { | ||||
|     furi_assert(nfc_worker); | ||||
|     furi_assert(nfc_worker->callback); | ||||
| 
 | ||||
|     NfcReadMode read_mode = nfc_worker->dev_data->read_mode; | ||||
|     nfc_device_data_clear(nfc_worker->dev_data); | ||||
|     NfcDeviceData* dev_data = nfc_worker->dev_data; | ||||
|     FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; | ||||
|     FuriHalNfcTxRxContext tx_rx = {}; | ||||
|     NfcWorkerEvent event = 0; | ||||
|     bool card_not_detected_notified = false; | ||||
| 
 | ||||
|     while(nfc_worker->state == NfcWorkerStateRead) { | ||||
|         if(furi_hal_nfc_detect(nfc_data, 300)) { | ||||
|             FURI_LOG_D(TAG, "Card detected"); | ||||
|             furi_hal_nfc_sleep(); | ||||
|             // Process first found device
 | ||||
|             nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context); | ||||
|             card_not_detected_notified = false; | ||||
|             if(nfc_data->type == FuriHalNfcTypeA) { | ||||
|                 if(read_mode == NfcReadModeMfClassic) { | ||||
|                     nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareClassic; | ||||
|                     nfc_worker->dev_data->mf_classic_data.type = mf_classic_get_classic_type( | ||||
|                         nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak); | ||||
|                     if(nfc_worker_read_mf_classic(nfc_worker, &tx_rx)) { | ||||
|                         FURI_LOG_D(TAG, "Card read"); | ||||
|                         dev_data->protocol = NfcDeviceProtocolMifareClassic; | ||||
|                         event = NfcWorkerEventReadMfClassicDone; | ||||
|                         break; | ||||
|                     } else { | ||||
|                         FURI_LOG_D(TAG, "Card read failed"); | ||||
|                         dev_data->protocol = NfcDeviceProtocolMifareClassic; | ||||
|                         event = NfcWorkerEventReadMfClassicDictAttackRequired; | ||||
|                         break; | ||||
|                     } | ||||
|                 } else if(read_mode == NfcReadModeMfUltralight) { | ||||
|                     FURI_LOG_I(TAG, "Mifare Ultralight / NTAG"); | ||||
|                     nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareUl; | ||||
|                     if(nfc_worker_read_mf_ultralight(nfc_worker, &tx_rx)) { | ||||
|                         event = NfcWorkerEventReadMfUltralight; | ||||
|                         break; | ||||
|                     } | ||||
|                 } else if(read_mode == NfcReadModeMfDesfire) { | ||||
|                     nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareDesfire; | ||||
|                     if(nfc_worker_read_mf_desfire(nfc_worker, &tx_rx)) { | ||||
|                         event = NfcWorkerEventReadMfDesfire; | ||||
|                         break; | ||||
|                     } | ||||
|                 } else if(read_mode == NfcReadModeEMV) { | ||||
|                     nfc_worker->dev_data->protocol = NfcDeviceProtocolEMV; | ||||
|                     if(nfc_worker_read_bank_card(nfc_worker, &tx_rx)) { | ||||
|                         event = NfcWorkerEventReadBankCard; | ||||
|                         break; | ||||
|                     } | ||||
|                 } else if(read_mode == NfcReadModeNFCA) { | ||||
|                     nfc_worker->dev_data->protocol = NfcDeviceProtocolUnknown; | ||||
|                     event = NfcWorkerEventReadUidNfcA; | ||||
|                     break; | ||||
|                 } | ||||
|             } else { | ||||
|                 if(!card_not_detected_notified) { | ||||
|                     nfc_worker->callback(NfcWorkerEventNoCardDetected, nfc_worker->context); | ||||
|                     card_not_detected_notified = true; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         furi_hal_nfc_sleep(); | ||||
|         furi_delay_ms(100); | ||||
|     } | ||||
|     // Notify caller and exit
 | ||||
|     if(event > NfcWorkerEventReserved) { | ||||
|         nfc_worker->callback(event, nfc_worker->context); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void nfc_worker_emulate_uid(NfcWorker* nfc_worker) { | ||||
|     FuriHalNfcTxRxContext tx_rx = {}; | ||||
|     FuriHalNfcDevData* data = &nfc_worker->dev_data->nfc_data; | ||||
|  | ||||
| @ -35,6 +35,8 @@ int32_t nfc_worker_task(void* context); | ||||
| 
 | ||||
| void nfc_worker_read(NfcWorker* nfc_worker); | ||||
| 
 | ||||
| void nfc_worker_read_type(NfcWorker* nfc_worker); | ||||
| 
 | ||||
| void nfc_worker_emulate_uid(NfcWorker* nfc_worker); | ||||
| 
 | ||||
| void nfc_worker_emulate_mf_ultralight(NfcWorker* nfc_worker); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Astra
						Astra