[FL-1424] NFC emulate CLI command (#514)
* nfc: move cli commands to separate file * nfc: add nfc_emulate CLI command * nfc: rework nfc emulate call from gui * nfc: deactivate nfc state machine when exiting worker Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									4ad5245969
								
							
						
					
					
						commit
						3a2121bbb8
					
				| @ -159,44 +159,6 @@ void nfc_free(Nfc* nfc) { | ||||
|     free(nfc); | ||||
| } | ||||
| 
 | ||||
| void nfc_cli_detect(Cli* cli, string_t args, void* context) { | ||||
|     // Check if nfc worker is not busy
 | ||||
|     if(api_hal_nfc_is_busy()) { | ||||
|         printf("Nfc is busy"); | ||||
|         return; | ||||
|     } | ||||
|     rfalNfcDevice* dev_list; | ||||
|     uint8_t dev_cnt = 0; | ||||
|     bool cmd_exit = false; | ||||
|     api_hal_nfc_init(); | ||||
|     printf("Detecting nfc...\r\nPress Ctrl+C to abort\r\n"); | ||||
|     while(!cmd_exit) { | ||||
|         cmd_exit |= cli_cmd_interrupt_received(cli); | ||||
|         cmd_exit |= api_hal_nfc_detect(&dev_list, &dev_cnt, 100, true); | ||||
|         if(dev_cnt > 0) { | ||||
|             printf("Found %d devices\r\n", dev_cnt); | ||||
|             for(uint8_t i = 0; i < dev_cnt; i++) { | ||||
|                 printf("%d found: %s ", i, nfc_get_dev_type(dev_list[i].type)); | ||||
|                 if(dev_list[i].type == RFAL_NFC_LISTEN_TYPE_NFCA) { | ||||
|                     printf("type: %s, ", nfc_get_nfca_type(dev_list[i].dev.nfca.type)); | ||||
|                 } | ||||
|                 printf("UID length: %d, UID:", dev_list[i].nfcidLen); | ||||
|                 for(uint8_t j = 0; j < dev_list[i].nfcidLen; j++) { | ||||
|                     printf("%02X", dev_list[i].nfcid[j]); | ||||
|                 } | ||||
|                 printf("\r\n"); | ||||
|             } | ||||
|         } | ||||
|         osDelay(50); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void nfc_cli_init() { | ||||
|     Cli* cli = furi_record_open("cli"); | ||||
|     cli_add_command(cli, "nfc_detect", nfc_cli_detect, NULL); | ||||
|     furi_record_close("cli"); | ||||
| } | ||||
| 
 | ||||
| void nfc_start(Nfc* nfc, NfcView view_id, NfcWorkerState worker_state) { | ||||
|     NfcWorkerState state = nfc_worker_get_state(nfc->worker); | ||||
|     if(state == NfcWorkerStateBroken) { | ||||
|  | ||||
							
								
								
									
										67
									
								
								applications/nfc/nfc_cli.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										67
									
								
								applications/nfc/nfc_cli.c
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,67 @@ | ||||
| #include "nfc_cli.h" | ||||
| #include "nfc_types.h" | ||||
| #include <furi.h> | ||||
| #include <api-hal.h> | ||||
| 
 | ||||
| void nfc_cli_init() { | ||||
|     Cli* cli = furi_record_open("cli"); | ||||
|     cli_add_command(cli, "nfc_detect", nfc_cli_detect, NULL); | ||||
|     cli_add_command(cli, "nfc_emulate", nfc_cli_emulate, NULL); | ||||
|     furi_record_close("cli"); | ||||
| } | ||||
| 
 | ||||
| void nfc_cli_detect(Cli* cli, string_t args, void* context) { | ||||
|     // Check if nfc worker is not busy
 | ||||
|     if(api_hal_nfc_is_busy()) { | ||||
|         printf("Nfc is busy"); | ||||
|         return; | ||||
|     } | ||||
|     rfalNfcDevice* dev_list; | ||||
|     uint8_t dev_cnt = 0; | ||||
|     bool cmd_exit = false; | ||||
|     api_hal_nfc_init(); | ||||
|     api_hal_nfc_exit_sleep(); | ||||
|     printf("Detecting nfc...\r\nPress Ctrl+C to abort\r\n"); | ||||
|     while(!cmd_exit) { | ||||
|         cmd_exit |= cli_cmd_interrupt_received(cli); | ||||
|         cmd_exit |= api_hal_nfc_detect(&dev_list, &dev_cnt, 100, true); | ||||
|         if(dev_cnt > 0) { | ||||
|             printf("Found %d devices\r\n", dev_cnt); | ||||
|             for(uint8_t i = 0; i < dev_cnt; i++) { | ||||
|                 printf("%d found: %s ", i + 1, nfc_get_dev_type(dev_list[i].type)); | ||||
|                 if(dev_list[i].type == RFAL_NFC_LISTEN_TYPE_NFCA) { | ||||
|                     printf("type: %s, ", nfc_get_nfca_type(dev_list[i].dev.nfca.type)); | ||||
|                 } | ||||
|                 printf("UID length: %d, UID:", dev_list[i].nfcidLen); | ||||
|                 for(uint8_t j = 0; j < dev_list[i].nfcidLen; j++) { | ||||
|                     printf("%02X", dev_list[i].nfcid[j]); | ||||
|                 } | ||||
|                 printf("\r\n"); | ||||
|             } | ||||
|         } | ||||
|         osDelay(50); | ||||
|     } | ||||
|     api_hal_nfc_deactivate(); | ||||
| } | ||||
| 
 | ||||
| void nfc_cli_emulate(Cli* cli, string_t args, void* context) { | ||||
|     // Check if nfc worker is not busy
 | ||||
|     if(api_hal_nfc_is_busy()) { | ||||
|         printf("Nfc is busy"); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     api_hal_nfc_init(); | ||||
|     api_hal_nfc_exit_sleep(); | ||||
|     printf("Emulating NFC-A Type: T2T UID: CF72D440 SAK: 20 ATQA: 00/04\r\n"); | ||||
|     printf("Press Ctrl+C to abort\r\n"); | ||||
| 
 | ||||
|     while(!cli_cmd_interrupt_received(cli)) { | ||||
|         if(api_hal_nfc_listen(100)) { | ||||
|             printf("Reader detected\r\n"); | ||||
|             api_hal_nfc_deactivate(); | ||||
|         } | ||||
|         osDelay(50); | ||||
|     } | ||||
|     api_hal_nfc_deactivate(); | ||||
| } | ||||
							
								
								
									
										9
									
								
								applications/nfc/nfc_cli.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								applications/nfc/nfc_cli.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include <cli/cli.h> | ||||
| 
 | ||||
| void nfc_cli_init(); | ||||
| 
 | ||||
| void nfc_cli_detect(Cli* cli, string_t args, void* context); | ||||
| 
 | ||||
| void nfc_cli_emulate(Cli* cli, string_t args, void* context); | ||||
| @ -145,9 +145,9 @@ void nfc_view_emulate_draw(Canvas* canvas, void* model) { | ||||
|     canvas_draw_str(canvas, 0, 12, "Emulating NFC-A"); | ||||
|     canvas_set_font(canvas, FontSecondary); | ||||
|     canvas_draw_str(canvas, 2, 22, "Type: T2T"); | ||||
|     canvas_draw_str(canvas, 2, 32, "UID length: 7"); | ||||
|     canvas_draw_str(canvas, 2, 42, "UID: 00010203040506"); | ||||
|     canvas_draw_str(canvas, 2, 52, "SAK: 00 ATQA: 44/00"); | ||||
|     canvas_draw_str(canvas, 2, 32, "UID length: 4"); | ||||
|     canvas_draw_str(canvas, 2, 42, "UID: CF72D440"); | ||||
|     canvas_draw_str(canvas, 2, 52, "SAK: 20 ATQA: 00/04"); | ||||
| } | ||||
| 
 | ||||
| void nfc_view_field_draw(Canvas* canvas, void* model) { | ||||
|  | ||||
| @ -59,6 +59,7 @@ void nfc_worker_task(void* context) { | ||||
|     NfcWorker* nfc_worker = context; | ||||
| 
 | ||||
|     api_hal_power_insomnia_enter(); | ||||
|     api_hal_nfc_exit_sleep(); | ||||
| 
 | ||||
|     if(nfc_worker->state == NfcWorkerStatePoll) { | ||||
|         nfc_worker_poll(nfc_worker); | ||||
| @ -71,6 +72,7 @@ void nfc_worker_task(void* context) { | ||||
|     } else if(nfc_worker->state == NfcWorkerStateField) { | ||||
|         nfc_worker_field(nfc_worker); | ||||
|     } | ||||
|     api_hal_nfc_deactivate(); | ||||
|     nfc_worker_change_state(nfc_worker, NfcWorkerStateReady); | ||||
|     api_hal_power_insomnia_exit(); | ||||
|     osThreadExit(); | ||||
| @ -209,7 +211,6 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { | ||||
|         } | ||||
|         osDelay(20); | ||||
|     } | ||||
|     api_hal_nfc_deactivate(); | ||||
| } | ||||
| 
 | ||||
| void nfc_worker_emulate_emv(NfcWorker* nfc_worker) { | ||||
| @ -305,104 +306,14 @@ void nfc_worker_poll(NfcWorker* nfc_worker) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void nfc_worker_state_callback(rfalNfcState st) { | ||||
|     (void)st; | ||||
| } | ||||
| 
 | ||||
| ReturnCode nfc_worker_trx( | ||||
|     uint8_t* txBuf, | ||||
|     uint16_t txBufSize, | ||||
|     uint8_t** rxData, | ||||
|     uint16_t** rcvLen, | ||||
|     uint32_t fwt) { | ||||
|     ReturnCode err; | ||||
| 
 | ||||
|     err = rfalNfcDataExchangeStart(txBuf, txBufSize, rxData, rcvLen, fwt); | ||||
|     if(err == ERR_NONE) { | ||||
|         do { | ||||
|             rfalNfcWorker(); | ||||
|             err = rfalNfcDataExchangeGetStatus(); | ||||
|         } while(err == ERR_BUSY); | ||||
|     } | ||||
|     return err; | ||||
| } | ||||
| 
 | ||||
| void nfc_worker_exchange(NfcWorker* nfc_worker, rfalNfcDevice* nfc_device) { | ||||
|     ReturnCode err = ERR_NONE; | ||||
|     uint8_t* rxData; | ||||
|     uint16_t* rcvLen; | ||||
|     uint8_t txBuf[100]; | ||||
|     uint16_t txLen; | ||||
| 
 | ||||
|     do { | ||||
|         rfalNfcWorker(); | ||||
|         switch(rfalNfcGetState()) { | ||||
|         case RFAL_NFC_STATE_ACTIVATED: | ||||
|             err = nfc_worker_trx(NULL, 0, &rxData, &rcvLen, 0); | ||||
|             break; | ||||
|         case RFAL_NFC_STATE_DATAEXCHANGE: | ||||
|         case RFAL_NFC_STATE_DATAEXCHANGE_DONE: | ||||
|             // Not supported
 | ||||
|             txBuf[0] = ((char)0x68); | ||||
|             txBuf[1] = ((char)0x00); | ||||
|             txLen = 2; | ||||
|             err = nfc_worker_trx(txBuf, txLen, &rxData, &rcvLen, RFAL_FWT_NONE); | ||||
|             break; | ||||
|         case RFAL_NFC_STATE_START_DISCOVERY: | ||||
|             return; | ||||
|         case RFAL_NFC_STATE_LISTEN_SLEEP: | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|     } while((err == ERR_NONE) || (err == ERR_SLEEP_REQ)); | ||||
| } | ||||
| 
 | ||||
| void nfc_worker_emulate(NfcWorker* nfc_worker) { | ||||
|     rfalNfcDiscoverParam params; | ||||
|     params.compMode = RFAL_COMPLIANCE_MODE_NFC; | ||||
|     params.techs2Find = RFAL_NFC_LISTEN_TECH_A; | ||||
|     params.totalDuration = 1000U; | ||||
|     params.devLimit = 1; | ||||
|     params.wakeupEnabled = false; | ||||
|     params.wakeupConfigDefault = true; | ||||
|     params.nfcfBR = RFAL_BR_212; | ||||
|     params.ap2pBR = RFAL_BR_424; | ||||
|     params.maxBR = RFAL_BR_KEEP; | ||||
|     params.GBLen = RFAL_NFCDEP_GB_MAX_LEN; | ||||
|     params.notifyCb = nfc_worker_state_callback; | ||||
| 
 | ||||
|     params.lmConfigPA.nfcidLen = RFAL_LM_NFCID_LEN_07; | ||||
|     params.lmConfigPA.nfcid[0] = 0x00; | ||||
|     params.lmConfigPA.nfcid[1] = 0x01; | ||||
|     params.lmConfigPA.nfcid[2] = 0x02; | ||||
|     params.lmConfigPA.nfcid[3] = 0x03; | ||||
|     params.lmConfigPA.nfcid[4] = 0x04; | ||||
|     params.lmConfigPA.nfcid[5] = 0x05; | ||||
|     params.lmConfigPA.nfcid[6] = 0x06; | ||||
|     params.lmConfigPA.SENS_RES[0] = 0x44; | ||||
|     params.lmConfigPA.SENS_RES[1] = 0x00; | ||||
|     params.lmConfigPA.SEL_RES = 0x00; | ||||
|     api_hal_nfc_exit_sleep(); | ||||
| 
 | ||||
|     ReturnCode ret; | ||||
|     ret = rfalNfcDiscover(¶ms); | ||||
|     if(ret != ERR_NONE) { | ||||
|         asm("bkpt 1"); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     rfalNfcDevice* nfc_device; | ||||
|     while(nfc_worker->state == NfcWorkerStateEmulate) { | ||||
|         rfalNfcWorker(); | ||||
|         if(rfalNfcIsDevActivated(rfalNfcGetState())) { | ||||
|             rfalNfcGetActiveDevice(&nfc_device); | ||||
|             nfc_worker_exchange(nfc_worker, nfc_device); | ||||
|         if(api_hal_nfc_listen(100)) { | ||||
|             FURI_LOG_I(NFC_WORKER_TAG, "Reader detected"); | ||||
|             api_hal_nfc_deactivate(); | ||||
|         } | ||||
|         osDelay(10); | ||||
|         osDelay(5); | ||||
|     } | ||||
| 
 | ||||
|     rfalNfcDeactivate(false); | ||||
|     api_hal_nfc_start_sleep(); | ||||
| } | ||||
| 
 | ||||
| void nfc_worker_field(NfcWorker* nfc_worker) { | ||||
|  | ||||
| @ -89,7 +89,6 @@ bool api_hal_nfc_detect(rfalNfcDevice **dev_list, uint8_t* dev_cnt, uint32_t cyc | ||||
| 
 | ||||
| bool api_hal_nfc_listen(uint32_t timeout) { | ||||
|     api_hal_nfc_exit_sleep(); | ||||
|     rfalLowPowerModeStop(); | ||||
| 
 | ||||
|     rfalNfcState state = rfalNfcGetState(); | ||||
|     if(state == RFAL_NFC_STATE_NOTINIT) { | ||||
| @ -130,6 +129,7 @@ bool api_hal_nfc_listen(uint32_t timeout) { | ||||
|             return false; | ||||
|         } | ||||
|         if(state == RFAL_NFC_STATE_LISTEN_ACTIVATION) { | ||||
|             start = DWT->CYCCNT; | ||||
|             continue; | ||||
|         } | ||||
|         taskYIELD(); | ||||
|  | ||||
| @ -89,7 +89,6 @@ bool api_hal_nfc_detect(rfalNfcDevice **dev_list, uint8_t* dev_cnt, uint32_t cyc | ||||
| 
 | ||||
| bool api_hal_nfc_listen(uint32_t timeout) { | ||||
|     api_hal_nfc_exit_sleep(); | ||||
|     rfalLowPowerModeStop(); | ||||
| 
 | ||||
|     rfalNfcState state = rfalNfcGetState(); | ||||
|     if(state == RFAL_NFC_STATE_NOTINIT) { | ||||
| @ -130,6 +129,7 @@ bool api_hal_nfc_listen(uint32_t timeout) { | ||||
|             return false; | ||||
|         } | ||||
|         if(state == RFAL_NFC_STATE_LISTEN_ACTIVATION) { | ||||
|             start = DWT->CYCCNT; | ||||
|             continue; | ||||
|         } | ||||
|         taskYIELD(); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 gornekich
						gornekich