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* nfc = furi_alloc(sizeof(Nfc)); | ||||||
| 
 | 
 | ||||||
|     nfc->message_queue = osMessageQueueNew(8, sizeof(NfcMessage), NULL); |     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->worker = nfc_worker_alloc(nfc->message_queue); | ||||||
| 
 | 
 | ||||||
|     nfc->icon = assets_icons_get(A_NFC_14); |     nfc->icon = assets_icons_get(A_NFC_14); | ||||||
| @ -39,6 +40,9 @@ Nfc* nfc_alloc() { | |||||||
|     view_set_context(nfc->view_field, nfc); |     view_set_context(nfc->view_field, nfc); | ||||||
|     view_set_draw_callback(nfc->view_field, nfc_view_field_draw); |     view_set_draw_callback(nfc->view_field, nfc_view_field_draw); | ||||||
|     view_set_previous_callback(nfc->view_field, nfc_view_exit); |     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(); |     nfc->view_error = view_alloc(); | ||||||
|     view_set_context(nfc->view_error, nfc); |     view_set_context(nfc->view_error, nfc); | ||||||
|     view_set_draw_callback(nfc->view_error, nfc_view_error_draw); |     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, NfcViewRead, nfc->view_detect); | ||||||
|     view_dispatcher_add_view(nfc->view_dispatcher, NfcViewEmulate, nfc->view_emulate); |     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, 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); |     view_dispatcher_add_view(nfc->view_dispatcher, NfcViewError, nfc->view_error); | ||||||
| 
 | 
 | ||||||
|     return nfc; |     return nfc; | ||||||
| @ -85,6 +90,54 @@ void nfc_menu_field_off_callback(void* context) { | |||||||
|     furi_check(osMessageQueuePut(nfc->message_queue, &message, 0, osWaitForever) == osOK); |     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) { | void nfc_start(Nfc* nfc, NfcView view_id, NfcWorkerState worker_state) { | ||||||
|     NfcWorkerState state = nfc_worker_get_state(nfc->worker); |     NfcWorkerState state = nfc_worker_get_state(nfc->worker); | ||||||
|     if(state == NfcWorkerStateBroken) { |     if(state == NfcWorkerStateBroken) { | ||||||
| @ -106,6 +159,11 @@ int32_t nfc_task(void* p) { | |||||||
|     Gui* gui = furi_record_open("gui"); |     Gui* gui = furi_record_open("gui"); | ||||||
|     view_dispatcher_attach_to_gui(nfc->view_dispatcher, gui, ViewDispatcherTypeFullscreen); |     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( |     with_value_mutex( | ||||||
|         nfc->menu_vm, (Menu * menu) { menu_item_add(menu, nfc->menu); }); |         nfc->menu_vm, (Menu * menu) { menu_item_add(menu, nfc->menu); }); | ||||||
| 
 | 
 | ||||||
| @ -121,6 +179,8 @@ int32_t nfc_task(void* p) { | |||||||
|                     return true; |                     return true; | ||||||
|                 }); |                 }); | ||||||
|             nfc_start(nfc, NfcViewRead, NfcWorkerStatePoll); |             nfc_start(nfc, NfcViewRead, NfcWorkerStatePoll); | ||||||
|  |         } else if(message.type == NfcMessageTypeDetectCliCmd) { | ||||||
|  |             nfc_start(nfc, NfcViewCli, NfcWorkerStatePollOnce); | ||||||
|         } else if(message.type == NfcMessageTypeEmulate) { |         } else if(message.type == NfcMessageTypeEmulate) { | ||||||
|             nfc_start(nfc, NfcViewEmulate, NfcWorkerStateEmulate); |             nfc_start(nfc, NfcViewEmulate, NfcWorkerStateEmulate); | ||||||
|         } else if(message.type == NfcMessageTypeField) { |         } else if(message.type == NfcMessageTypeField) { | ||||||
| @ -128,18 +188,34 @@ int32_t nfc_task(void* p) { | |||||||
|         } else if(message.type == NfcMessageTypeStop) { |         } else if(message.type == NfcMessageTypeStop) { | ||||||
|             nfc_worker_stop(nfc->worker); |             nfc_worker_stop(nfc->worker); | ||||||
|         } else if(message.type == NfcMessageTypeDeviceFound) { |         } else if(message.type == NfcMessageTypeDeviceFound) { | ||||||
|             with_view_model( |             NfcWorkerState state = nfc_worker_get_state(nfc->worker); | ||||||
|                 nfc->view_detect, (NfcViewReadModel * model) { |             if(state == NfcWorkerStatePollOnce) { | ||||||
|                     model->found = true; |                 view_dispatcher_switch_to_view(nfc->view_dispatcher, VIEW_NONE); | ||||||
|                     model->device = message.device; |                 furi_check( | ||||||
|                     return true; |                     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) { |         } else if(message.type == NfcMessageTypeDeviceNotFound) { | ||||||
|             with_view_model( |             NfcWorkerState state = nfc_worker_get_state(nfc->worker); | ||||||
|                 nfc->view_detect, (NfcViewReadModel * model) { |             if(state == NfcWorkerStatePollOnce) { | ||||||
|                     model->found = false; |                 view_dispatcher_switch_to_view(nfc->view_dispatcher, VIEW_NONE); | ||||||
|                     return true; |                 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; | ||||||
|  |                         return true; | ||||||
|  |                     }); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -11,22 +11,26 @@ | |||||||
| #include <gui/view.h> | #include <gui/view.h> | ||||||
| #include <gui/view_dispatcher.h> | #include <gui/view_dispatcher.h> | ||||||
| #include <assets_icons.h> | #include <assets_icons.h> | ||||||
|  | #include <cli/cli.h> | ||||||
| 
 | 
 | ||||||
| #include <menu/menu.h> | #include <menu/menu.h> | ||||||
| #include <menu/menu_item.h> | #include <menu/menu_item.h> | ||||||
| 
 | 
 | ||||||
| struct Nfc { | struct Nfc { | ||||||
|     osMessageQueueId_t message_queue; |     osMessageQueueId_t message_queue; | ||||||
|  |     osMessageQueueId_t cli_message_queue; | ||||||
| 
 | 
 | ||||||
|     NfcWorker* worker; |     NfcWorker* worker; | ||||||
| 
 | 
 | ||||||
|     ValueMutex* menu_vm; |     ValueMutex* menu_vm; | ||||||
|     MenuItem* menu; |     MenuItem* menu; | ||||||
|     Icon* icon; |     Icon* icon; | ||||||
|  |     Cli* cli; | ||||||
| 
 | 
 | ||||||
|     View* view_detect; |     View* view_detect; | ||||||
|     View* view_emulate; |     View* view_emulate; | ||||||
|     View* view_field; |     View* view_field; | ||||||
|  |     View* view_cli; | ||||||
|     View* view_error; |     View* view_error; | ||||||
|     ViewDispatcher* view_dispatcher; |     ViewDispatcher* view_dispatcher; | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -44,6 +44,7 @@ typedef enum { | |||||||
|     NfcWorkerStateReady, |     NfcWorkerStateReady, | ||||||
|     // Main worker states
 |     // Main worker states
 | ||||||
|     NfcWorkerStatePoll, |     NfcWorkerStatePoll, | ||||||
|  |     NfcWorkerStatePollOnce, | ||||||
|     NfcWorkerStateEmulate, |     NfcWorkerStateEmulate, | ||||||
|     NfcWorkerStateField, |     NfcWorkerStateField, | ||||||
|     // Transition
 |     // Transition
 | ||||||
| @ -52,6 +53,7 @@ typedef enum { | |||||||
| 
 | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
|     NfcMessageTypeDetect, |     NfcMessageTypeDetect, | ||||||
|  |     NfcMessageTypeDetectCliCmd, | ||||||
|     NfcMessageTypeEmulate, |     NfcMessageTypeEmulate, | ||||||
|     NfcMessageTypeField, |     NfcMessageTypeField, | ||||||
|     NfcMessageTypeStop, |     NfcMessageTypeStop, | ||||||
|  | |||||||
| @ -123,6 +123,14 @@ void nfc_view_field_draw(Canvas* canvas, void* model) { | |||||||
|     canvas_draw_str(canvas, 2, 22, "TX/RX is disabled"); |     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) { | void nfc_view_error_draw(Canvas* canvas, void* model) { | ||||||
|     NfcViewErrorModel* m = model; |     NfcViewErrorModel* m = model; | ||||||
|     char buffer[32]; |     char buffer[32]; | ||||||
|  | |||||||
| @ -11,6 +11,7 @@ typedef enum { | |||||||
|     NfcViewRead, |     NfcViewRead, | ||||||
|     NfcViewEmulate, |     NfcViewEmulate, | ||||||
|     NfcViewField, |     NfcViewField, | ||||||
|  |     NfcViewCli, | ||||||
|     NfcViewError, |     NfcViewError, | ||||||
| } NfcView; | } 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_field_draw(Canvas* canvas, void* model); | ||||||
| 
 | 
 | ||||||
|  | void nfc_view_cli_draw(Canvas* canvas, void* model); | ||||||
|  | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|     ReturnCode error; |     ReturnCode error; | ||||||
| } NfcViewErrorModel; | } NfcViewErrorModel; | ||||||
|  | |||||||
| @ -59,7 +59,9 @@ void nfc_worker_task(void* context) { | |||||||
| 
 | 
 | ||||||
|     rfalLowPowerModeStop(); |     rfalLowPowerModeStop(); | ||||||
|     if(nfc_worker->state == NfcWorkerStatePoll) { |     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) { |     } else if(nfc_worker->state == NfcWorkerStateEmulate) { | ||||||
|         nfc_worker_emulate(nfc_worker); |         nfc_worker_emulate(nfc_worker); | ||||||
|     } else if(nfc_worker->state == NfcWorkerStateField) { |     } else if(nfc_worker->state == NfcWorkerStateField) { | ||||||
| @ -73,15 +75,17 @@ void nfc_worker_task(void* context) { | |||||||
|     osThreadExit(); |     osThreadExit(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nfc_worker_poll(NfcWorker* nfc_worker) { | void nfc_worker_poll(NfcWorker* nfc_worker, uint8_t cycles) { | ||||||
|     while(nfc_worker->state == NfcWorkerStatePoll) { |     while((nfc_worker->state == NfcWorkerStatePoll) || | ||||||
|  |           ((nfc_worker->state == NfcWorkerStatePollOnce) && cycles)) { | ||||||
|         bool is_found = false; |         bool is_found = false; | ||||||
|         is_found |= nfc_worker_nfca_poll(nfc_worker); |         is_found |= nfc_worker_nfca_poll(nfc_worker); | ||||||
|         is_found |= nfc_worker_nfcb_poll(nfc_worker); |         is_found |= nfc_worker_nfcb_poll(nfc_worker); | ||||||
|         is_found |= nfc_worker_nfcf_poll(nfc_worker); |         is_found |= nfc_worker_nfcf_poll(nfc_worker); | ||||||
|         is_found |= nfc_worker_nfcv_poll(nfc_worker); |         is_found |= nfc_worker_nfcv_poll(nfc_worker); | ||||||
|         rfalFieldOff(); |         rfalFieldOff(); | ||||||
|         if(!is_found) { |         cycles--; | ||||||
|  |         if((!is_found) && (!cycles)) { | ||||||
|             NfcMessage message; |             NfcMessage message; | ||||||
|             message.type = NfcMessageTypeDeviceNotFound; |             message.type = NfcMessageTypeDeviceNotFound; | ||||||
|             furi_check( |             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_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_nfca_poll(NfcWorker* nfc_worker); | ||||||
| bool nfc_worker_nfcb_poll(NfcWorker* nfc_worker); | bool nfc_worker_nfcb_poll(NfcWorker* nfc_worker); | ||||||
| bool nfc_worker_nfcf_poll(NfcWorker* nfc_worker); | bool nfc_worker_nfcf_poll(NfcWorker* nfc_worker); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 gornekich
						gornekich