Nfc: add nfc detection cli command (#379)
Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									1daef3d025
								
							
						
					
					
						commit
						ca9862ef6c
					
				| @ -13,6 +13,7 @@ Nfc* nfc_alloc() { | ||||
|     Nfc* nfc = furi_alloc(sizeof(Nfc)); | ||||
| 
 | ||||
|     nfc->message_queue = osMessageQueueNew(8, sizeof(NfcMessage), NULL); | ||||
|     nfc->cli_message_queue = osMessageQueueNew(1, sizeof(NfcMessage), NULL); | ||||
|     nfc->worker = nfc_worker_alloc(nfc->message_queue); | ||||
| 
 | ||||
|     nfc->icon = assets_icons_get(A_NFC_14); | ||||
| @ -39,6 +40,9 @@ Nfc* nfc_alloc() { | ||||
|     view_set_context(nfc->view_field, nfc); | ||||
|     view_set_draw_callback(nfc->view_field, nfc_view_field_draw); | ||||
|     view_set_previous_callback(nfc->view_field, nfc_view_exit); | ||||
|     nfc->view_cli = view_alloc(); | ||||
|     view_set_context(nfc->view_cli, nfc); | ||||
|     view_set_draw_callback(nfc->view_cli, nfc_view_cli_draw); | ||||
|     nfc->view_error = view_alloc(); | ||||
|     view_set_context(nfc->view_error, nfc); | ||||
|     view_set_draw_callback(nfc->view_error, nfc_view_error_draw); | ||||
| @ -48,6 +52,7 @@ Nfc* nfc_alloc() { | ||||
|     view_dispatcher_add_view(nfc->view_dispatcher, NfcViewRead, nfc->view_detect); | ||||
|     view_dispatcher_add_view(nfc->view_dispatcher, NfcViewEmulate, nfc->view_emulate); | ||||
|     view_dispatcher_add_view(nfc->view_dispatcher, NfcViewField, nfc->view_field); | ||||
|     view_dispatcher_add_view(nfc->view_dispatcher, NfcViewCli, nfc->view_cli); | ||||
|     view_dispatcher_add_view(nfc->view_dispatcher, NfcViewError, nfc->view_error); | ||||
| 
 | ||||
|     return nfc; | ||||
| @ -85,6 +90,54 @@ void nfc_menu_field_off_callback(void* context) { | ||||
|     furi_check(osMessageQueuePut(nfc->message_queue, &message, 0, osWaitForever) == osOK); | ||||
| } | ||||
| 
 | ||||
| void nfc_cli_detect(string_t args, void* context) { | ||||
|     furi_assert(context); | ||||
|     Nfc* nfc = context; | ||||
|     NfcWorkerState state = nfc_worker_get_state(nfc->worker); | ||||
|     if(state != NfcWorkerStateReady) { | ||||
|         printf("Nfc is busy"); | ||||
|         return; | ||||
|     } | ||||
|     NfcMessage message; | ||||
|     message.type = NfcMessageTypeDetectCliCmd; | ||||
|     furi_check(osMessageQueuePut(nfc->message_queue, &message, 0, osWaitForever) == osOK); | ||||
|     // Wait until nfc task send response
 | ||||
|     furi_check(osMessageQueueGet(nfc->cli_message_queue, &message, NULL, osWaitForever) == osOK); | ||||
|     if(message.type == NfcMessageTypeDeviceFound) { | ||||
|         if(message.device.type == NfcDeviceTypeNfca) { | ||||
|             printf( | ||||
|                 "Found NFC-A, type: %s, UID length: %d, UID:", | ||||
|                 nfc_get_nfca_type(message.device.nfca.type), | ||||
|                 message.device.nfca.nfcId1Len); | ||||
|             for(uint8_t i = 0; i < message.device.nfca.nfcId1Len; i++) { | ||||
|                 printf("%02X", message.device.nfca.nfcId1[i]); | ||||
|             } | ||||
|             printf( | ||||
|                 " SAK: %02X ATQA: %02X/%02X", | ||||
|                 message.device.nfca.selRes.sak, | ||||
|                 message.device.nfca.sensRes.anticollisionInfo, | ||||
|                 message.device.nfca.sensRes.platformInfo); | ||||
|         } else if(message.device.type == NfcDeviceTypeNfcb) { | ||||
|             printf("Found NFC-B, UID length: %d, UID:", RFAL_NFCB_NFCID0_LEN); | ||||
|             for(uint8_t i = 0; i < RFAL_NFCB_NFCID0_LEN; i++) { | ||||
|                 printf("%02X", message.device.nfcb.sensbRes.nfcid0[i]); | ||||
|             } | ||||
|         } else if(message.device.type == NfcDeviceTypeNfcv) { | ||||
|             printf("Found NFC-V, UID length: %d, UID:", RFAL_NFCV_UID_LEN); | ||||
|             for(uint8_t i = 0; i < RFAL_NFCV_UID_LEN; i++) { | ||||
|                 printf("%02X", message.device.nfcv.InvRes.UID[i]); | ||||
|             } | ||||
|         } else if(message.device.type == NfcDeviceTypeNfcf) { | ||||
|             printf("Found NFC-F, UID length: %d, UID:", RFAL_NFCF_NFCID2_LEN); | ||||
|             for(uint8_t i = 0; i < RFAL_NFCF_NFCID2_LEN; i++) { | ||||
|                 printf("%02X", message.device.nfcf.sensfRes.NFCID2[i]); | ||||
|             } | ||||
|         } | ||||
|     } else { | ||||
|         printf("Device not found"); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void nfc_start(Nfc* nfc, NfcView view_id, NfcWorkerState worker_state) { | ||||
|     NfcWorkerState state = nfc_worker_get_state(nfc->worker); | ||||
|     if(state == NfcWorkerStateBroken) { | ||||
| @ -106,6 +159,11 @@ int32_t nfc_task(void* p) { | ||||
|     Gui* gui = furi_record_open("gui"); | ||||
|     view_dispatcher_attach_to_gui(nfc->view_dispatcher, gui, ViewDispatcherTypeFullscreen); | ||||
| 
 | ||||
|     nfc->cli = furi_record_open("cli"); | ||||
|     if(nfc->cli) { | ||||
|         cli_add_command(nfc->cli, "nfc_detect", nfc_cli_detect, nfc); | ||||
|     } | ||||
| 
 | ||||
|     with_value_mutex( | ||||
|         nfc->menu_vm, (Menu * menu) { menu_item_add(menu, nfc->menu); }); | ||||
| 
 | ||||
| @ -121,6 +179,8 @@ int32_t nfc_task(void* p) { | ||||
|                     return true; | ||||
|                 }); | ||||
|             nfc_start(nfc, NfcViewRead, NfcWorkerStatePoll); | ||||
|         } else if(message.type == NfcMessageTypeDetectCliCmd) { | ||||
|             nfc_start(nfc, NfcViewCli, NfcWorkerStatePollOnce); | ||||
|         } else if(message.type == NfcMessageTypeEmulate) { | ||||
|             nfc_start(nfc, NfcViewEmulate, NfcWorkerStateEmulate); | ||||
|         } else if(message.type == NfcMessageTypeField) { | ||||
| @ -128,13 +188,28 @@ int32_t nfc_task(void* p) { | ||||
|         } else if(message.type == NfcMessageTypeStop) { | ||||
|             nfc_worker_stop(nfc->worker); | ||||
|         } else if(message.type == NfcMessageTypeDeviceFound) { | ||||
|             NfcWorkerState state = nfc_worker_get_state(nfc->worker); | ||||
|             if(state == NfcWorkerStatePollOnce) { | ||||
|                 view_dispatcher_switch_to_view(nfc->view_dispatcher, VIEW_NONE); | ||||
|                 furi_check( | ||||
|                     osMessageQueuePut(nfc->cli_message_queue, &message, 0, osWaitForever) == osOK); | ||||
|                 nfc_worker_stop(nfc->worker); | ||||
|             } else { | ||||
|                 with_view_model( | ||||
|                     nfc->view_detect, (NfcViewReadModel * model) { | ||||
|                         model->found = true; | ||||
|                         model->device = message.device; | ||||
|                         return true; | ||||
|                     }); | ||||
|             } | ||||
|         } else if(message.type == NfcMessageTypeDeviceNotFound) { | ||||
|             NfcWorkerState state = nfc_worker_get_state(nfc->worker); | ||||
|             if(state == NfcWorkerStatePollOnce) { | ||||
|                 view_dispatcher_switch_to_view(nfc->view_dispatcher, VIEW_NONE); | ||||
|                 furi_check( | ||||
|                     osMessageQueuePut(nfc->cli_message_queue, &message, 0, osWaitForever) == osOK); | ||||
|                 nfc_worker_stop(nfc->worker); | ||||
|             } else { | ||||
|                 with_view_model( | ||||
|                     nfc->view_detect, (NfcViewReadModel * model) { | ||||
|                         model->found = false; | ||||
| @ -142,6 +217,7 @@ int32_t nfc_task(void* p) { | ||||
|                     }); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| @ -11,22 +11,26 @@ | ||||
| #include <gui/view.h> | ||||
| #include <gui/view_dispatcher.h> | ||||
| #include <assets_icons.h> | ||||
| #include <cli/cli.h> | ||||
| 
 | ||||
| #include <menu/menu.h> | ||||
| #include <menu/menu_item.h> | ||||
| 
 | ||||
| struct Nfc { | ||||
|     osMessageQueueId_t message_queue; | ||||
|     osMessageQueueId_t cli_message_queue; | ||||
| 
 | ||||
|     NfcWorker* worker; | ||||
| 
 | ||||
|     ValueMutex* menu_vm; | ||||
|     MenuItem* menu; | ||||
|     Icon* icon; | ||||
|     Cli* cli; | ||||
| 
 | ||||
|     View* view_detect; | ||||
|     View* view_emulate; | ||||
|     View* view_field; | ||||
|     View* view_cli; | ||||
|     View* view_error; | ||||
|     ViewDispatcher* view_dispatcher; | ||||
| }; | ||||
|  | ||||
| @ -44,6 +44,7 @@ typedef enum { | ||||
|     NfcWorkerStateReady, | ||||
|     // Main worker states
 | ||||
|     NfcWorkerStatePoll, | ||||
|     NfcWorkerStatePollOnce, | ||||
|     NfcWorkerStateEmulate, | ||||
|     NfcWorkerStateField, | ||||
|     // Transition
 | ||||
| @ -52,6 +53,7 @@ typedef enum { | ||||
| 
 | ||||
| typedef enum { | ||||
|     NfcMessageTypeDetect, | ||||
|     NfcMessageTypeDetectCliCmd, | ||||
|     NfcMessageTypeEmulate, | ||||
|     NfcMessageTypeField, | ||||
|     NfcMessageTypeStop, | ||||
|  | ||||
| @ -123,6 +123,14 @@ void nfc_view_field_draw(Canvas* canvas, void* model) { | ||||
|     canvas_draw_str(canvas, 2, 22, "TX/RX is disabled"); | ||||
| } | ||||
| 
 | ||||
| void nfc_view_cli_draw(Canvas* canvas, void* model) { | ||||
|     canvas_clear(canvas); | ||||
|     canvas_set_font(canvas, FontPrimary); | ||||
|     canvas_draw_str(canvas, 0, 12, "USB connected"); | ||||
|     canvas_set_font(canvas, FontSecondary); | ||||
|     canvas_draw_str(canvas, 2, 22, "Cli command in process..."); | ||||
| } | ||||
| 
 | ||||
| void nfc_view_error_draw(Canvas* canvas, void* model) { | ||||
|     NfcViewErrorModel* m = model; | ||||
|     char buffer[32]; | ||||
|  | ||||
| @ -11,6 +11,7 @@ typedef enum { | ||||
|     NfcViewRead, | ||||
|     NfcViewEmulate, | ||||
|     NfcViewField, | ||||
|     NfcViewCli, | ||||
|     NfcViewError, | ||||
| } NfcView; | ||||
| 
 | ||||
| @ -29,6 +30,8 @@ void nfc_view_emulate_draw(Canvas* canvas, void* model); | ||||
| 
 | ||||
| void nfc_view_field_draw(Canvas* canvas, void* model); | ||||
| 
 | ||||
| void nfc_view_cli_draw(Canvas* canvas, void* model); | ||||
| 
 | ||||
| typedef struct { | ||||
|     ReturnCode error; | ||||
| } NfcViewErrorModel; | ||||
|  | ||||
| @ -59,7 +59,9 @@ void nfc_worker_task(void* context) { | ||||
| 
 | ||||
|     rfalLowPowerModeStop(); | ||||
|     if(nfc_worker->state == NfcWorkerStatePoll) { | ||||
|         nfc_worker_poll(nfc_worker); | ||||
|         nfc_worker_poll(nfc_worker, 0); | ||||
|     } else if(nfc_worker->state == NfcWorkerStatePollOnce) { | ||||
|         nfc_worker_poll(nfc_worker, 5); | ||||
|     } else if(nfc_worker->state == NfcWorkerStateEmulate) { | ||||
|         nfc_worker_emulate(nfc_worker); | ||||
|     } else if(nfc_worker->state == NfcWorkerStateField) { | ||||
| @ -73,15 +75,17 @@ void nfc_worker_task(void* context) { | ||||
|     osThreadExit(); | ||||
| } | ||||
| 
 | ||||
| void nfc_worker_poll(NfcWorker* nfc_worker) { | ||||
|     while(nfc_worker->state == NfcWorkerStatePoll) { | ||||
| void nfc_worker_poll(NfcWorker* nfc_worker, uint8_t cycles) { | ||||
|     while((nfc_worker->state == NfcWorkerStatePoll) || | ||||
|           ((nfc_worker->state == NfcWorkerStatePollOnce) && cycles)) { | ||||
|         bool is_found = false; | ||||
|         is_found |= nfc_worker_nfca_poll(nfc_worker); | ||||
|         is_found |= nfc_worker_nfcb_poll(nfc_worker); | ||||
|         is_found |= nfc_worker_nfcf_poll(nfc_worker); | ||||
|         is_found |= nfc_worker_nfcv_poll(nfc_worker); | ||||
|         rfalFieldOff(); | ||||
|         if(!is_found) { | ||||
|         cycles--; | ||||
|         if((!is_found) && (!cycles)) { | ||||
|             NfcMessage message; | ||||
|             message.type = NfcMessageTypeDeviceNotFound; | ||||
|             furi_check( | ||||
|  | ||||
| @ -29,7 +29,7 @@ void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state); | ||||
| 
 | ||||
| void nfc_worker_task(void* context); | ||||
| 
 | ||||
| void nfc_worker_poll(NfcWorker* nfc_worker); | ||||
| void nfc_worker_poll(NfcWorker* nfc_worker, uint8_t cycles); | ||||
| bool nfc_worker_nfca_poll(NfcWorker* nfc_worker); | ||||
| bool nfc_worker_nfcb_poll(NfcWorker* nfc_worker); | ||||
| bool nfc_worker_nfcf_poll(NfcWorker* nfc_worker); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 gornekich
						gornekich