[FL-1479] New NFC app (#544)
* view: add custom event callback * nfc: rework nfc worker * gui: introduce view navigator * nfc_scences: introduce nfc scenes * nfc: add start scene * lib: add C application scene template * nfc: move nfc views to separate directory * view_dispatcher: add support for view_navigator * nfc views: rework nfc views * nfc scenes: add nfc application scenes * nfc: rework nfc main thread * view_dispatcher: add separate event for search back scene * nfc: set worker result address at worker start * nfc: update read nfc scenes * view_navigator: rework with M-LIB container * view_dispatcher: check that all views were freed * nfc: add debug menu with all functions * nfc read scene: add notification on success * api-hal-nfc: add API for UID emulation * nfc: add nfc emulation UID scene * assets: add NFC assets * nfc: update read and emulate scenes UI * nfc: fix memory leak * rfal: set custom analog configuration
This commit is contained in:
		
							parent
							
								
									7a13391b2b
								
							
						
					
					
						commit
						a0e1e42f2d
					
				| @ -24,6 +24,12 @@ void view_set_input_callback(View* view, ViewInputCallback callback) { | |||||||
|     view->input_callback = callback; |     view->input_callback = callback; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void view_set_custom_callback(View* view, ViewCustomCallback callback) { | ||||||
|  |     furi_assert(view); | ||||||
|  |     furi_assert(callback); | ||||||
|  |     view->custom_callback = callback; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void view_set_previous_callback(View* view, ViewNavigationCallback callback) { | void view_set_previous_callback(View* view, ViewNavigationCallback callback) { | ||||||
|     furi_assert(view); |     furi_assert(view); | ||||||
|     view->previous_callback = callback; |     view->previous_callback = callback; | ||||||
| @ -145,6 +151,15 @@ bool view_input(View* view, InputEvent* event) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool view_custom(View* view, uint32_t event) { | ||||||
|  |     furi_assert(view); | ||||||
|  |     if(view->custom_callback) { | ||||||
|  |         return view->custom_callback(event, view->context); | ||||||
|  |     } else { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| uint32_t view_previous(View* view) { | uint32_t view_previous(View* view) { | ||||||
|     furi_assert(view); |     furi_assert(view); | ||||||
|     if(view->previous_callback) { |     if(view->previous_callback) { | ||||||
|  | |||||||
| @ -43,6 +43,13 @@ typedef void (*ViewDrawCallback)(Canvas* canvas, void* model); | |||||||
|  */ |  */ | ||||||
| typedef bool (*ViewInputCallback)(InputEvent* event, void* context); | typedef bool (*ViewInputCallback)(InputEvent* event, void* context); | ||||||
| 
 | 
 | ||||||
|  | /* View Custom callback
 | ||||||
|  |  * @param event, number of custom event | ||||||
|  |  * @param context, pointer to context | ||||||
|  |  * @return true if event handled, false if event ignored | ||||||
|  |  */ | ||||||
|  | typedef bool (*ViewCustomCallback)(uint32_t event, void* context); | ||||||
|  | 
 | ||||||
| /* View navigation callback
 | /* View navigation callback
 | ||||||
|  * @param context, pointer to context |  * @param context, pointer to context | ||||||
|  * @return next view id |  * @return next view id | ||||||
| @ -94,12 +101,18 @@ void view_free(View* view); | |||||||
|  */ |  */ | ||||||
| void view_set_draw_callback(View* view, ViewDrawCallback callback); | void view_set_draw_callback(View* view, ViewDrawCallback callback); | ||||||
| 
 | 
 | ||||||
| /* Set View Draw callback
 | /* Set View Input callback
 | ||||||
|  * @param view, pointer to View |  * @param view, pointer to View | ||||||
|  * @param callback, input callback |  * @param callback, input callback | ||||||
|  */ |  */ | ||||||
| void view_set_input_callback(View* view, ViewInputCallback callback); | void view_set_input_callback(View* view, ViewInputCallback callback); | ||||||
| 
 | 
 | ||||||
|  | /* Set View Custom callback
 | ||||||
|  |  * @param view, pointer to View | ||||||
|  |  * @param callback, input callback | ||||||
|  |  */ | ||||||
|  | void view_set_custom_callback(View* view, ViewCustomCallback callback); | ||||||
|  | 
 | ||||||
| /* Set Navigation Previous callback
 | /* Set Navigation Previous callback
 | ||||||
|  * @param view, pointer to View |  * @param view, pointer to View | ||||||
|  * @param callback, input callback |  * @param callback, input callback | ||||||
|  | |||||||
							
								
								
									
										86
									
								
								applications/gui/view_dispatcher.c
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										86
									
								
								applications/gui/view_dispatcher.c
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							| @ -25,7 +25,8 @@ void view_dispatcher_free(ViewDispatcher* view_dispatcher) { | |||||||
|     ViewDict_it(it, view_dispatcher->views); |     ViewDict_it(it, view_dispatcher->views); | ||||||
|     while(!ViewDict_end_p(it)) { |     while(!ViewDict_end_p(it)) { | ||||||
|         ViewDict_itref_t* ref = ViewDict_ref(it); |         ViewDict_itref_t* ref = ViewDict_ref(it); | ||||||
|         view_free(ref->value); |         // Crash if view wasn't freed
 | ||||||
|  |         furi_assert(ref->value); | ||||||
|         ViewDict_next(it); |         ViewDict_next(it); | ||||||
|     } |     } | ||||||
|     ViewDict_clear(view_dispatcher->views); |     ViewDict_clear(view_dispatcher->views); | ||||||
| @ -35,6 +36,10 @@ void view_dispatcher_free(ViewDispatcher* view_dispatcher) { | |||||||
|     if(view_dispatcher->queue) { |     if(view_dispatcher->queue) { | ||||||
|         osMessageQueueDelete(view_dispatcher->queue); |         osMessageQueueDelete(view_dispatcher->queue); | ||||||
|     } |     } | ||||||
|  |     // Free View Navigator
 | ||||||
|  |     if(view_dispatcher->view_navigator) { | ||||||
|  |         view_navigator_free(view_dispatcher->view_navigator); | ||||||
|  |     } | ||||||
|     // Free dispatcher
 |     // Free dispatcher
 | ||||||
|     free(view_dispatcher); |     free(view_dispatcher); | ||||||
| } | } | ||||||
| @ -45,10 +50,26 @@ void view_dispatcher_enable_queue(ViewDispatcher* view_dispatcher) { | |||||||
|     view_dispatcher->queue = osMessageQueueNew(8, sizeof(ViewDispatcherMessage), NULL); |     view_dispatcher->queue = osMessageQueueNew(8, sizeof(ViewDispatcherMessage), NULL); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void view_dispatcher_enable_navigation(ViewDispatcher* view_dispatcher, void* context) { | ||||||
|  |     furi_assert(view_dispatcher); | ||||||
|  |     view_dispatcher->view_navigator = view_navigator_alloc(context); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void view_dispatcher_add_scene(ViewDispatcher* view_dispatcher, AppScene* scene) { | ||||||
|  |     furi_assert(view_dispatcher); | ||||||
|  |     furi_assert(view_dispatcher->view_navigator); | ||||||
|  |     furi_assert(scene); | ||||||
|  |     view_navigator_add_next_scene(view_dispatcher->view_navigator, scene); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void view_dispatcher_run(ViewDispatcher* view_dispatcher) { | void view_dispatcher_run(ViewDispatcher* view_dispatcher) { | ||||||
|     furi_assert(view_dispatcher); |     furi_assert(view_dispatcher); | ||||||
|     furi_assert(view_dispatcher->queue); |     furi_assert(view_dispatcher->queue); | ||||||
| 
 | 
 | ||||||
|  |     if(view_dispatcher->view_navigator) { | ||||||
|  |         view_navigator_start(view_dispatcher->view_navigator); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     ViewDispatcherMessage message; |     ViewDispatcherMessage message; | ||||||
|     while(osMessageQueueGet(view_dispatcher->queue, &message, NULL, osWaitForever) == osOK) { |     while(osMessageQueueGet(view_dispatcher->queue, &message, NULL, osWaitForever) == osOK) { | ||||||
|         if(message.type == ViewDispatcherMessageTypeStop) { |         if(message.type == ViewDispatcherMessageTypeStop) { | ||||||
| @ -57,6 +78,12 @@ void view_dispatcher_run(ViewDispatcher* view_dispatcher) { | |||||||
|             view_dispatcher_handle_input(view_dispatcher, &message.input); |             view_dispatcher_handle_input(view_dispatcher, &message.input); | ||||||
|         } else if(message.type == ViewDispatcherMessageTypeCustomEvent) { |         } else if(message.type == ViewDispatcherMessageTypeCustomEvent) { | ||||||
|             view_dispatcher_handle_custom_event(view_dispatcher, message.custom_event); |             view_dispatcher_handle_custom_event(view_dispatcher, message.custom_event); | ||||||
|  |         } else if(message.type == ViewDispatcherMessageTypeNavigationEvent) { | ||||||
|  |             view_navigator_handle_navigation_event( | ||||||
|  |                 view_dispatcher->view_navigator, message.navigator_event); | ||||||
|  |         } else if(message.type == ViewDispatcherMessageTypeBackSearchScene) { | ||||||
|  |             view_navigator_handle_back_search_scene_event( | ||||||
|  |                 view_dispatcher->view_navigator, message.navigator_event); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -175,30 +202,35 @@ void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* e | |||||||
|         is_consumed = view_input(view_dispatcher->current_view, event); |         is_consumed = view_input(view_dispatcher->current_view, event); | ||||||
|     } |     } | ||||||
|     if(!is_consumed && event->type == InputTypeShort) { |     if(!is_consumed && event->type == InputTypeShort) { | ||||||
|  |         // TODO remove view navigation handlers
 | ||||||
|         uint32_t view_id = VIEW_IGNORE; |         uint32_t view_id = VIEW_IGNORE; | ||||||
|         if(event->key == InputKeyBack) { |         if(event->key == InputKeyBack) { | ||||||
|             view_id = view_previous(view_dispatcher->current_view); |             view_id = view_previous(view_dispatcher->current_view); | ||||||
|  |             if((view_id == VIEW_IGNORE) && (view_dispatcher->view_navigator)) { | ||||||
|  |                 is_consumed = view_navigator_handle_navigation_event( | ||||||
|  |                     view_dispatcher->view_navigator, ViewNavigatorEventBack); | ||||||
|  |                 if(!is_consumed) { | ||||||
|  |                     view_dispatcher_stop(view_dispatcher); | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|         } else if(event->key == InputKeyOk) { |         } else if(event->key == InputKeyOk) { | ||||||
|             view_id = view_next(view_dispatcher->current_view); |             view_id = view_next(view_dispatcher->current_view); | ||||||
|         } |         } | ||||||
|         view_dispatcher_switch_to_view(view_dispatcher, view_id); |         if(!is_consumed) { | ||||||
|  |             view_dispatcher_switch_to_view(view_dispatcher, view_id); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void view_dispatcher_set_custom_callback( |  | ||||||
|     ViewDispatcher* view_dispatcher, |  | ||||||
|     CustomEventCallback callback, |  | ||||||
|     void* context) { |  | ||||||
|     furi_assert(view_dispatcher); |  | ||||||
|     furi_assert(callback); |  | ||||||
| 
 |  | ||||||
|     view_dispatcher->custom_event_cb = callback; |  | ||||||
|     view_dispatcher->custom_event_ctx = context; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void view_dispatcher_handle_custom_event(ViewDispatcher* view_dispatcher, uint32_t event) { | void view_dispatcher_handle_custom_event(ViewDispatcher* view_dispatcher, uint32_t event) { | ||||||
|     if(view_dispatcher->custom_event_cb) { |     bool is_consumed = false; | ||||||
|         view_dispatcher->custom_event_cb(event, view_dispatcher->custom_event_ctx); |     if(view_dispatcher->current_view) { | ||||||
|  |         is_consumed = view_custom(view_dispatcher->current_view, event); | ||||||
|  |     } | ||||||
|  |     // If custom event is not consumed in View, handle it in Scene
 | ||||||
|  |     if(!is_consumed) { | ||||||
|  |         is_consumed = view_navigator_handle_custom_event(view_dispatcher->view_navigator, event); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -213,6 +245,30 @@ void view_dispatcher_send_custom_event(ViewDispatcher* view_dispatcher, uint32_t | |||||||
|     furi_check(osMessageQueuePut(view_dispatcher->queue, &message, 0, osWaitForever) == osOK); |     furi_check(osMessageQueuePut(view_dispatcher->queue, &message, 0, osWaitForever) == osOK); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void view_dispatcher_send_navigation_event(ViewDispatcher* view_dispatcher, uint32_t event) { | ||||||
|  |     furi_assert(view_dispatcher); | ||||||
|  |     furi_assert(view_dispatcher->queue); | ||||||
|  |     furi_assert(view_dispatcher->view_navigator); | ||||||
|  | 
 | ||||||
|  |     ViewDispatcherMessage message; | ||||||
|  |     message.type = ViewDispatcherMessageTypeNavigationEvent; | ||||||
|  |     message.custom_event = event; | ||||||
|  | 
 | ||||||
|  |     furi_check(osMessageQueuePut(view_dispatcher->queue, &message, 0, osWaitForever) == osOK); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void view_dispatcher_send_back_search_scene_event(ViewDispatcher* view_dispatcher, uint32_t event) { | ||||||
|  |     furi_assert(view_dispatcher); | ||||||
|  |     furi_assert(view_dispatcher->queue); | ||||||
|  |     furi_assert(view_dispatcher->view_navigator); | ||||||
|  | 
 | ||||||
|  |     ViewDispatcherMessage message; | ||||||
|  |     message.type = ViewDispatcherMessageTypeBackSearchScene; | ||||||
|  |     message.custom_event = event; | ||||||
|  | 
 | ||||||
|  |     furi_check(osMessageQueuePut(view_dispatcher->queue, &message, 0, osWaitForever) == osOK); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void view_dispatcher_set_current_view(ViewDispatcher* view_dispatcher, View* view) { | void view_dispatcher_set_current_view(ViewDispatcher* view_dispatcher, View* view) { | ||||||
|     furi_assert(view_dispatcher); |     furi_assert(view_dispatcher); | ||||||
|     // Dispatch view exit event
 |     // Dispatch view exit event
 | ||||||
|  | |||||||
| @ -2,15 +2,12 @@ | |||||||
| 
 | 
 | ||||||
| #include "view.h" | #include "view.h" | ||||||
| #include "gui.h" | #include "gui.h" | ||||||
|  | #include "view_navigator.h" | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| /** Prototype for custom event callback
 |  | ||||||
|  */ |  | ||||||
| typedef void (*CustomEventCallback)(uint32_t custom_event, void* context); |  | ||||||
| 
 |  | ||||||
| /** ViewDispatcher view_port placement
 | /** ViewDispatcher view_port placement
 | ||||||
|  */ |  */ | ||||||
| typedef enum { | typedef enum { | ||||||
| @ -37,18 +34,36 @@ void view_dispatcher_free(ViewDispatcher* view_dispatcher); | |||||||
|  */ |  */ | ||||||
| void view_dispatcher_enable_queue(ViewDispatcher* view_dispatcher); | void view_dispatcher_enable_queue(ViewDispatcher* view_dispatcher); | ||||||
| 
 | 
 | ||||||
| /** Set custom event callback
 |  | ||||||
|  * Custom callback is called when custom event in internal queue received |  | ||||||
|  */ |  | ||||||
| void view_dispatcher_set_custom_callback( |  | ||||||
|     ViewDispatcher* view_dispatcher, |  | ||||||
|     CustomEventCallback callback, |  | ||||||
|     void* context); |  | ||||||
| 
 |  | ||||||
| /** Send custom event
 | /** Send custom event
 | ||||||
|  |  * @param view_dispatcher ViewDispatcher instance | ||||||
|  */ |  */ | ||||||
| void view_dispatcher_send_custom_event(ViewDispatcher* view_dispatcher, uint32_t event); | void view_dispatcher_send_custom_event(ViewDispatcher* view_dispatcher, uint32_t event); | ||||||
| 
 | 
 | ||||||
|  | /** Enable View Navigator to handle custom events and scene navigation
 | ||||||
|  |  * @param view_dispatcher ViewDispatcher instance | ||||||
|  |  * @param context  context for all scenes | ||||||
|  |  */ | ||||||
|  | void view_dispatcher_enable_navigation(ViewDispatcher* view_dispatcher, void* context); | ||||||
|  | 
 | ||||||
|  | /** Add Scene to view navigator
 | ||||||
|  |  * Use only after navigation enabled | ||||||
|  |  * @param view_dispatcher ViewDispatcher instance | ||||||
|  |  * @param scene AppScene instance | ||||||
|  |  */ | ||||||
|  | void view_dispatcher_add_scene(ViewDispatcher* view_dispatcher, AppScene* scene); | ||||||
|  | 
 | ||||||
|  | /** Send navigation event
 | ||||||
|  |  * @param view_dispatcher ViewDispatcher instance | ||||||
|  |  * @param event event | ||||||
|  |  */ | ||||||
|  | void view_dispatcher_send_navigation_event(ViewDispatcher* view_dispatcher, uint32_t event); | ||||||
|  | 
 | ||||||
|  | /** Send search scene event
 | ||||||
|  |  * @param view_dispatcher ViewDispatcher instance | ||||||
|  |  * @param event event | ||||||
|  |  */ | ||||||
|  | void view_dispatcher_send_back_search_scene_event(ViewDispatcher* view_dispatcher, uint32_t event); | ||||||
|  | 
 | ||||||
| /** Run ViewDispatcher
 | /** Run ViewDispatcher
 | ||||||
|  * Use only after queue enabled |  * Use only after queue enabled | ||||||
|  * @param view_dispatcher ViewDispatcher instance |  * @param view_dispatcher ViewDispatcher instance | ||||||
|  | |||||||
| @ -15,13 +15,14 @@ struct ViewDispatcher { | |||||||
|     ViewPort* view_port; |     ViewPort* view_port; | ||||||
|     ViewDict_t views; |     ViewDict_t views; | ||||||
|     View* current_view; |     View* current_view; | ||||||
|     CustomEventCallback custom_event_cb; |     ViewNavigator* view_navigator; | ||||||
|     void* custom_event_ctx; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
|     ViewDispatcherMessageTypeInput, |     ViewDispatcherMessageTypeInput, | ||||||
|     ViewDispatcherMessageTypeCustomEvent, |     ViewDispatcherMessageTypeCustomEvent, | ||||||
|  |     ViewDispatcherMessageTypeNavigationEvent, | ||||||
|  |     ViewDispatcherMessageTypeBackSearchScene, | ||||||
|     ViewDispatcherMessageTypeStop, |     ViewDispatcherMessageTypeStop, | ||||||
| } ViewDispatcherMessageType; | } ViewDispatcherMessageType; | ||||||
| 
 | 
 | ||||||
| @ -30,6 +31,8 @@ typedef struct { | |||||||
|     union { |     union { | ||||||
|         InputEvent input; |         InputEvent input; | ||||||
|         uint32_t custom_event; |         uint32_t custom_event; | ||||||
|  |         ViewNavigatorEvent navigator_event; | ||||||
|  |         uint32_t scene_id; | ||||||
|     }; |     }; | ||||||
| } ViewDispatcherMessage; | } ViewDispatcherMessage; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -11,6 +11,7 @@ typedef struct { | |||||||
| struct View { | struct View { | ||||||
|     ViewDrawCallback draw_callback; |     ViewDrawCallback draw_callback; | ||||||
|     ViewInputCallback input_callback; |     ViewInputCallback input_callback; | ||||||
|  |     ViewCustomCallback custom_callback; | ||||||
| 
 | 
 | ||||||
|     ViewModelType model_type; |     ViewModelType model_type; | ||||||
|     ViewNavigationCallback previous_callback; |     ViewNavigationCallback previous_callback; | ||||||
| @ -35,6 +36,9 @@ void view_draw(View* view, Canvas* canvas); | |||||||
| /* Input Callback for View dispatcher */ | /* Input Callback for View dispatcher */ | ||||||
| bool view_input(View* view, InputEvent* event); | bool view_input(View* view, InputEvent* event); | ||||||
| 
 | 
 | ||||||
|  | /* Custom Callback for View dispatcher */ | ||||||
|  | bool view_custom(View* view, uint32_t event); | ||||||
|  | 
 | ||||||
| /* Previous Callback for View dispatcher */ | /* Previous Callback for View dispatcher */ | ||||||
| uint32_t view_previous(View* view); | uint32_t view_previous(View* view); | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										109
									
								
								applications/gui/view_navigator.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										109
									
								
								applications/gui/view_navigator.c
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | #include "view_navigator_i.h" | ||||||
|  | 
 | ||||||
|  | ViewNavigator* view_navigator_alloc(void* context) { | ||||||
|  |     furi_assert(context); | ||||||
|  | 
 | ||||||
|  |     ViewNavigator* view_navigator = furi_alloc(sizeof(ViewNavigator)); | ||||||
|  |     view_navigator->context = context; | ||||||
|  |     ViewNavSceneArray_init(view_navigator->scene_array); | ||||||
|  | 
 | ||||||
|  |     return view_navigator; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void view_navigator_free(ViewNavigator* view_navigator) { | ||||||
|  |     furi_assert(view_navigator); | ||||||
|  |     ViewNavSceneArray_clear(view_navigator->scene_array); | ||||||
|  | 
 | ||||||
|  |     free(view_navigator); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool view_navigator_handle_custom_event(ViewNavigator* view_navigator, uint32_t event) { | ||||||
|  |     AppScene* scene = *ViewNavSceneArray_back(view_navigator->scene_array); | ||||||
|  |     return scene->on_event(view_navigator->context, event); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool view_navigator_handle_navigation_event(ViewNavigator* view_navigator, uint32_t event) { | ||||||
|  |     if(event == ViewNavigatorEventNext) { | ||||||
|  |         return view_navigator_next_scene(view_navigator); | ||||||
|  |     } else if(event == ViewNavigatorEventBack) { | ||||||
|  |         AppScene* scene = *ViewNavSceneArray_back(view_navigator->scene_array); | ||||||
|  |         if(scene->on_event(view_navigator->context, ViewNavigatorEventBack)) { | ||||||
|  |             return true; | ||||||
|  |         } else { | ||||||
|  |             return view_navigator_previous_scene(view_navigator); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool view_navigator_handle_back_search_scene_event(ViewNavigator* view_navigator, uint32_t event) { | ||||||
|  |     return view_navigator_search_previous_scene(view_navigator, event); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void view_navigator_add_next_scene(ViewNavigator* view_navigator, AppScene* scene) { | ||||||
|  |     furi_assert(view_navigator); | ||||||
|  |     furi_assert(scene); | ||||||
|  | 
 | ||||||
|  |     ViewNavSceneArray_push_back(view_navigator->scene_array, scene); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void view_navigator_start(ViewNavigator* view_navigator) { | ||||||
|  |     furi_assert(view_navigator); | ||||||
|  |     AppScene* scene = *ViewNavSceneArray_front(view_navigator->scene_array); | ||||||
|  |     furi_assert(scene); | ||||||
|  |     scene->on_enter(view_navigator->context); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool view_navigator_next_scene(ViewNavigator* view_navigator) { | ||||||
|  |     ViewNavSceneArray_it_t scene_it; | ||||||
|  |     ViewNavSceneArray_it_last(scene_it, view_navigator->scene_array); | ||||||
|  |     ViewNavSceneArray_previous(scene_it); | ||||||
|  |     AppScene* current_scene = *ViewNavSceneArray_ref(scene_it); | ||||||
|  |     AppScene* next_scene = *ViewNavSceneArray_back(view_navigator->scene_array); | ||||||
|  |     if(current_scene && next_scene) { | ||||||
|  |         current_scene->on_exit(view_navigator->context); | ||||||
|  |         next_scene->on_enter(view_navigator->context); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool view_navigator_previous_scene(ViewNavigator* view_navigator) { | ||||||
|  |     AppScene* current_scene = NULL; | ||||||
|  |     ViewNavSceneArray_pop_back(¤t_scene, view_navigator->scene_array); | ||||||
|  |     if(ViewNavSceneArray_size(view_navigator->scene_array) == 0) { | ||||||
|  |         // Handle exit from start scene separately
 | ||||||
|  |         current_scene->on_exit(view_navigator->context); | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |     AppScene* previous_scene = *ViewNavSceneArray_back(view_navigator->scene_array); | ||||||
|  |     if(current_scene && previous_scene) { | ||||||
|  |         current_scene->on_exit(view_navigator->context); | ||||||
|  |         previous_scene->on_enter(view_navigator->context); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool view_navigator_search_previous_scene(ViewNavigator* view_navigator, uint32_t scene_id) { | ||||||
|  |     AppScene* previous_scene = NULL; | ||||||
|  |     AppScene* current_scene = *ViewNavSceneArray_back(view_navigator->scene_array); | ||||||
|  |     ViewNavSceneArray_it_t scene_it; | ||||||
|  |     ViewNavSceneArray_it_last(scene_it, view_navigator->scene_array); | ||||||
|  |     bool scene_found = false; | ||||||
|  |     while(!scene_found) { | ||||||
|  |         ViewNavSceneArray_previous(scene_it); | ||||||
|  |         previous_scene = *ViewNavSceneArray_ref(scene_it); | ||||||
|  |         if(previous_scene == NULL) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         if(previous_scene->id == scene_id) { | ||||||
|  |             scene_found = true; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     ViewNavSceneArray_next(scene_it); | ||||||
|  |     ViewNavSceneArray_pop_until(view_navigator->scene_array, scene_it); | ||||||
|  |     current_scene->on_exit(view_navigator->context); | ||||||
|  |     previous_scene->on_enter(view_navigator->context); | ||||||
|  |     return true; | ||||||
|  | } | ||||||
							
								
								
									
										28
									
								
								applications/gui/view_navigator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								applications/gui/view_navigator.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "app_scene.h" | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | typedef enum { | ||||||
|  |     ViewNavigatorEventNext = 0x00000000UL, | ||||||
|  |     ViewNavigatorEventBack = 0xFFFFFFFFUL, | ||||||
|  | } ViewNavigatorEvent; | ||||||
|  | 
 | ||||||
|  | typedef struct ViewNavigator ViewNavigator; | ||||||
|  | 
 | ||||||
|  | ViewNavigator* view_navigator_alloc(void* context); | ||||||
|  | void view_navigator_free(ViewNavigator* view_navigator); | ||||||
|  | 
 | ||||||
|  | bool view_navigator_handle_custom_event(ViewNavigator* view_navigator, uint32_t event); | ||||||
|  | bool view_navigator_handle_navigation_event(ViewNavigator* view_navigator, uint32_t event); | ||||||
|  | bool view_navigator_handle_back_search_scene_event(ViewNavigator* view_navigator, uint32_t event); | ||||||
|  | 
 | ||||||
|  | void view_navigator_add_next_scene(ViewNavigator* view_navigator, AppScene* scene); | ||||||
|  | void view_navigator_start(ViewNavigator* view_navigator); | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
							
								
								
									
										16
									
								
								applications/gui/view_navigator_i.h
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										16
									
								
								applications/gui/view_navigator_i.h
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "view_navigator.h" | ||||||
|  | #include <furi.h> | ||||||
|  | #include <m-array.h> | ||||||
|  | 
 | ||||||
|  | ARRAY_DEF(ViewNavSceneArray, AppScene*, M_PTR_OPLIST); | ||||||
|  | 
 | ||||||
|  | struct ViewNavigator { | ||||||
|  |     ViewNavSceneArray_t scene_array; | ||||||
|  |     void* context; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | bool view_navigator_next_scene(ViewNavigator* view_navigator); | ||||||
|  | bool view_navigator_previous_scene(ViewNavigator* view_navigator); | ||||||
|  | bool view_navigator_search_previous_scene(ViewNavigator* view_navigator, uint32_t scene_id); | ||||||
| @ -1,64 +1,47 @@ | |||||||
| #include "nfc_i.h" | #include "nfc_i.h" | ||||||
| #include "api-hal-nfc.h" | #include "api-hal-nfc.h" | ||||||
| 
 | #include "app_scene.h" | ||||||
| uint32_t nfc_view_exit(void* context) { |  | ||||||
|     return VIEW_NONE; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void nfc_menu_callback(void* context, uint32_t index) { |  | ||||||
|     furi_assert(context); |  | ||||||
| 
 |  | ||||||
|     Nfc* nfc = (Nfc*)context; |  | ||||||
|     if(index == NfcSubmenuDetect) { |  | ||||||
|         view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewDetect); |  | ||||||
|     } else if(index == NfcSubmenuEmulate) { |  | ||||||
|         view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewEmulate); |  | ||||||
|     } else if(index == NfcSubmenuEMV) { |  | ||||||
|         view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewEmv); |  | ||||||
|     } else if(index == NfcSubmenuMifareUl) { |  | ||||||
|         view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMifareUl); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void nfc_view_dispatcher_callback(uint32_t event, void* context) { |  | ||||||
|     furi_assert(context); |  | ||||||
| 
 |  | ||||||
|     Nfc* nfc = (Nfc*)context; |  | ||||||
|     NfcMessage message; |  | ||||||
|     osMessageQueueGet(nfc->message_queue, &message, NULL, osWaitForever); |  | ||||||
|     if(event == NfcEventDetect) { |  | ||||||
|         nfc_detect_view_dispatcher_callback(nfc->nfc_detect, &message); |  | ||||||
|     } else if(event == NfcEventEmv) { |  | ||||||
|         nfc_emv_view_dispatcher_callback(nfc->nfc_emv, &message); |  | ||||||
|     } else if(event == NfcEventMifareUl) { |  | ||||||
|         nfc_mifare_ul_view_dispatcher_callback(nfc->nfc_mifare_ul, &message); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| Nfc* nfc_alloc() { | Nfc* nfc_alloc() { | ||||||
|     Nfc* nfc = furi_alloc(sizeof(Nfc)); |     Nfc* nfc = furi_alloc(sizeof(Nfc)); | ||||||
| 
 | 
 | ||||||
|     nfc->message_queue = osMessageQueueNew(8, sizeof(NfcMessage), NULL); |     nfc->nfc_common.worker = nfc_worker_alloc(); | ||||||
|     nfc->nfc_common.worker = nfc_worker_alloc(nfc->message_queue); |  | ||||||
|     nfc->nfc_common.view_dispatcher = view_dispatcher_alloc(); |     nfc->nfc_common.view_dispatcher = view_dispatcher_alloc(); | ||||||
|     view_dispatcher_enable_queue(nfc->nfc_common.view_dispatcher); |     view_dispatcher_enable_queue(nfc->nfc_common.view_dispatcher); | ||||||
|  |     view_dispatcher_enable_navigation(nfc->nfc_common.view_dispatcher, nfc); | ||||||
| 
 | 
 | ||||||
|     // Open GUI record
 |     // Open GUI record
 | ||||||
|     nfc->gui = furi_record_open("gui"); |     nfc->gui = furi_record_open("gui"); | ||||||
|     view_dispatcher_attach_to_gui( |     view_dispatcher_attach_to_gui( | ||||||
|         nfc->nfc_common.view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen); |         nfc->nfc_common.view_dispatcher, nfc->gui, ViewDispatcherTypeFullscreen); | ||||||
| 
 | 
 | ||||||
|     // Menu
 |     // Open Notification record
 | ||||||
|     nfc->submenu = submenu_alloc(); |     nfc->notifications = furi_record_open("notification"); | ||||||
|     submenu_add_item(nfc->submenu, "Detect", NfcSubmenuDetect, nfc_menu_callback, nfc); |  | ||||||
|     submenu_add_item(nfc->submenu, "Emulate", NfcSubmenuEmulate, nfc_menu_callback, nfc); |  | ||||||
|     submenu_add_item(nfc->submenu, "Read bank card", NfcSubmenuEMV, nfc_menu_callback, nfc); |  | ||||||
|     submenu_add_item( |  | ||||||
|         nfc->submenu, "Read Mifare Ultralight", NfcSubmenuMifareUl, nfc_menu_callback, nfc); |  | ||||||
| 
 | 
 | ||||||
|     View* submenu_view = submenu_get_view(nfc->submenu); |     // Submenu
 | ||||||
|     view_set_previous_callback(submenu_view, nfc_view_exit); |     nfc->submenu = submenu_alloc(); | ||||||
|     view_dispatcher_add_view(nfc->nfc_common.view_dispatcher, NfcViewMenu, submenu_view); |     view_dispatcher_add_view( | ||||||
|  |         nfc->nfc_common.view_dispatcher, NfcViewMenu, submenu_get_view(nfc->submenu)); | ||||||
|  | 
 | ||||||
|  |     // Dialog
 | ||||||
|  |     nfc->dialog_ex = dialog_ex_alloc(); | ||||||
|  |     view_dispatcher_add_view( | ||||||
|  |         nfc->nfc_common.view_dispatcher, NfcViewDialogEx, dialog_ex_get_view(nfc->dialog_ex)); | ||||||
|  | 
 | ||||||
|  |     // Popup
 | ||||||
|  |     nfc->popup = popup_alloc(); | ||||||
|  |     view_dispatcher_add_view( | ||||||
|  |         nfc->nfc_common.view_dispatcher, NfcViewPopup, popup_get_view(nfc->popup)); | ||||||
|  | 
 | ||||||
|  |     // Text Input
 | ||||||
|  |     nfc->text_input = text_input_alloc(); | ||||||
|  |     view_dispatcher_add_view( | ||||||
|  |         nfc->nfc_common.view_dispatcher, NfcViewTextInput, text_input_get_view(nfc->text_input)); | ||||||
|  | 
 | ||||||
|  |     // Byte Input
 | ||||||
|  |     nfc->byte_input = byte_input_alloc(); | ||||||
|  |     view_dispatcher_add_view( | ||||||
|  |         nfc->nfc_common.view_dispatcher, NfcViewByteInput, byte_input_get_view(nfc->byte_input)); | ||||||
| 
 | 
 | ||||||
|     // Detect
 |     // Detect
 | ||||||
|     nfc->nfc_detect = nfc_detect_alloc(&nfc->nfc_common); |     nfc->nfc_detect = nfc_detect_alloc(&nfc->nfc_common); | ||||||
| @ -82,12 +65,20 @@ Nfc* nfc_alloc() { | |||||||
|         NfcViewMifareUl, |         NfcViewMifareUl, | ||||||
|         nfc_mifare_ul_get_view(nfc->nfc_mifare_ul)); |         nfc_mifare_ul_get_view(nfc->nfc_mifare_ul)); | ||||||
| 
 | 
 | ||||||
|     // Set View Dispatcher custom event callback
 |     // Scene allocation
 | ||||||
|     view_dispatcher_set_custom_callback( |     nfc->scene_start = nfc_scene_start_alloc(); | ||||||
|         nfc->nfc_common.view_dispatcher, nfc_view_dispatcher_callback, nfc); |     nfc->scene_read_card = nfc_scene_read_card_alloc(); | ||||||
|  |     nfc->scene_read_card_success = nfc_scene_read_card_success_alloc(); | ||||||
|  |     nfc->scene_card_menu = nfc_scene_card_menu_alloc(); | ||||||
|  |     nfc->scene_not_implemented = nfc_scene_not_implemented_alloc(); | ||||||
|  |     nfc->scene_debug_menu = nfc_scene_debug_menu_alloc(); | ||||||
|  |     nfc->scene_debug_detect = nfc_scene_debug_detect_alloc(); | ||||||
|  |     nfc->scene_debug_emulate = nfc_scene_debug_emulate_alloc(); | ||||||
|  |     nfc->scene_debug_read_emv = nfc_scene_debug_read_emv_alloc(); | ||||||
|  |     nfc->scene_debug_read_mifare_ul = nfc_scene_debug_read_mifare_ul_alloc(); | ||||||
|  |     nfc->scene_emulate_uid = nfc_scene_emulate_uid_alloc(); | ||||||
| 
 | 
 | ||||||
|     // Switch to menu
 |     view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_start); | ||||||
|     view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMenu); |  | ||||||
| 
 | 
 | ||||||
|     return nfc; |     return nfc; | ||||||
| } | } | ||||||
| @ -99,6 +90,22 @@ void nfc_free(Nfc* nfc) { | |||||||
|     view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewMenu); |     view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewMenu); | ||||||
|     submenu_free(nfc->submenu); |     submenu_free(nfc->submenu); | ||||||
| 
 | 
 | ||||||
|  |     // DialogEx
 | ||||||
|  |     view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewDialogEx); | ||||||
|  |     dialog_ex_free(nfc->dialog_ex); | ||||||
|  | 
 | ||||||
|  |     // Popup
 | ||||||
|  |     view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewPopup); | ||||||
|  |     popup_free(nfc->popup); | ||||||
|  | 
 | ||||||
|  |     // TextInput
 | ||||||
|  |     view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewTextInput); | ||||||
|  |     text_input_free(nfc->text_input); | ||||||
|  | 
 | ||||||
|  |     // ByteInput
 | ||||||
|  |     view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewByteInput); | ||||||
|  |     byte_input_free(nfc->byte_input); | ||||||
|  | 
 | ||||||
|     // Detect
 |     // Detect
 | ||||||
|     view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewDetect); |     view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewDetect); | ||||||
|     nfc_detect_free(nfc->nfc_detect); |     nfc_detect_free(nfc->nfc_detect); | ||||||
| @ -111,7 +118,7 @@ void nfc_free(Nfc* nfc) { | |||||||
|     view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewEmv); |     view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewEmv); | ||||||
|     nfc_emv_free(nfc->nfc_emv); |     nfc_emv_free(nfc->nfc_emv); | ||||||
| 
 | 
 | ||||||
|     // Mifare ultralight
 |     // Mifare Ultralight
 | ||||||
|     view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewMifareUl); |     view_dispatcher_remove_view(nfc->nfc_common.view_dispatcher, NfcViewMifareUl); | ||||||
|     nfc_mifare_ul_free(nfc->nfc_mifare_ul); |     nfc_mifare_ul_free(nfc->nfc_mifare_ul); | ||||||
| 
 | 
 | ||||||
| @ -119,15 +126,30 @@ void nfc_free(Nfc* nfc) { | |||||||
|     nfc_worker_stop(nfc->nfc_common.worker); |     nfc_worker_stop(nfc->nfc_common.worker); | ||||||
|     nfc_worker_free(nfc->nfc_common.worker); |     nfc_worker_free(nfc->nfc_common.worker); | ||||||
| 
 | 
 | ||||||
|     // View dispatcher
 |     // Scenes
 | ||||||
|  |     nfc_scene_start_free(nfc->scene_start); | ||||||
|  |     nfc_scene_read_card_free(nfc->scene_read_card); | ||||||
|  |     nfc_scene_read_card_success_free(nfc->scene_read_card_success); | ||||||
|  |     nfc_scene_card_menu_free(nfc->scene_card_menu); | ||||||
|  |     nfc_scene_not_implemented_free(nfc->scene_not_implemented); | ||||||
|  |     nfc_scene_debug_menu_free(nfc->scene_debug_menu); | ||||||
|  |     nfc_scene_debug_detect_free(nfc->scene_debug_detect); | ||||||
|  |     nfc_scene_debug_emulate_free(nfc->scene_debug_emulate); | ||||||
|  |     nfc_scene_debug_read_emv_free(nfc->scene_debug_read_emv); | ||||||
|  |     nfc_scene_debug_read_mifare_ul_free(nfc->scene_debug_read_mifare_ul); | ||||||
|  |     nfc_scene_emulate_uid_free(nfc->scene_emulate_uid); | ||||||
|  | 
 | ||||||
|  |     // View Dispatcher
 | ||||||
|     view_dispatcher_free(nfc->nfc_common.view_dispatcher); |     view_dispatcher_free(nfc->nfc_common.view_dispatcher); | ||||||
| 
 | 
 | ||||||
|     // GUI
 |     // GUI
 | ||||||
|     furi_record_close("gui"); |     furi_record_close("gui"); | ||||||
|     nfc->gui = NULL; |     nfc->gui = NULL; | ||||||
| 
 | 
 | ||||||
|     // The rest
 |     // Notifications
 | ||||||
|     osMessageQueueDelete(nfc->message_queue); |     furi_record_close("notification"); | ||||||
|  |     nfc->notifications = NULL; | ||||||
|  | 
 | ||||||
|     free(nfc); |     free(nfc); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -140,3 +162,12 @@ int32_t nfc_task(void* p) { | |||||||
| 
 | 
 | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void nfc_set_text_store(Nfc* nfc, const char* text, ...) { | ||||||
|  |     va_list args; | ||||||
|  |     va_start(args, text); | ||||||
|  | 
 | ||||||
|  |     vsnprintf(nfc->text_store, sizeof(nfc->text_store), text, args); | ||||||
|  | 
 | ||||||
|  |     va_end(args); | ||||||
|  | } | ||||||
|  | |||||||
| @ -56,8 +56,17 @@ void nfc_cli_emulate(Cli* cli, string_t args, void* context) { | |||||||
|     printf("Emulating NFC-A Type: T2T UID: CF72D440 SAK: 20 ATQA: 00/04\r\n"); |     printf("Emulating NFC-A Type: T2T UID: CF72D440 SAK: 20 ATQA: 00/04\r\n"); | ||||||
|     printf("Press Ctrl+C to abort\r\n"); |     printf("Press Ctrl+C to abort\r\n"); | ||||||
| 
 | 
 | ||||||
|  |     NfcDeviceData params = { | ||||||
|  |         .uid = {0x36, 0x9C, 0xe7, 0xb1, 0x0A, 0xC1}, | ||||||
|  |         .uid_len = 7, | ||||||
|  |         .atqa = {0x44, 0x00}, | ||||||
|  |         .sak = 0x00, | ||||||
|  |         .device = NfcDeviceNfca, | ||||||
|  |         .protocol = NfcDeviceProtocolMfUltralight, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|     while(!cli_cmd_interrupt_received(cli)) { |     while(!cli_cmd_interrupt_received(cli)) { | ||||||
|         if(api_hal_nfc_listen(ApiHalNfcEmulateParamsMifare, 100)) { |         if(api_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, 100)) { | ||||||
|             printf("Reader detected\r\n"); |             printf("Reader detected\r\n"); | ||||||
|             api_hal_nfc_deactivate(); |             api_hal_nfc_deactivate(); | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -10,33 +10,99 @@ | |||||||
| #include <gui/view.h> | #include <gui/view.h> | ||||||
| #include <gui/view_dispatcher.h> | #include <gui/view_dispatcher.h> | ||||||
| #include <cli/cli.h> | #include <cli/cli.h> | ||||||
|  | #include <notification/notification-messages.h> | ||||||
| 
 | 
 | ||||||
| #include <gui/modules/submenu.h> | #include <gui/modules/submenu.h> | ||||||
|  | #include <gui/modules/dialog_ex.h> | ||||||
|  | #include <gui/modules/popup.h> | ||||||
|  | #include <gui/modules/text_input.h> | ||||||
|  | #include <gui/modules/byte_input.h> | ||||||
| 
 | 
 | ||||||
| #include "nfc_detect.h" | #include "views/nfc_detect.h" | ||||||
| #include "nfc_emulate.h" | #include "views/nfc_emulate.h" | ||||||
| #include "nfc_emv.h" | #include "views/nfc_emv.h" | ||||||
| #include "nfc_mifare_ul.h" | #include "views/nfc_mifare_ul.h" | ||||||
|  | 
 | ||||||
|  | #include "scenes/nfc_scene_start.h" | ||||||
|  | #include "scenes/nfc_scene_read_card.h" | ||||||
|  | #include "scenes/nfc_scene_read_card_success.h" | ||||||
|  | #include "scenes/nfc_scene_card_menu.h" | ||||||
|  | #include "scenes/nfc_scene_emulate_uid.h" | ||||||
|  | #include "scenes/nfc_scene_not_implemented.h" | ||||||
|  | 
 | ||||||
|  | // TODO delete debug scenes
 | ||||||
|  | #include "scenes/nfc_scene_debug_menu.h" | ||||||
|  | #include "scenes/nfc_scene_debug_detect.h" | ||||||
|  | #include "scenes/nfc_scene_debug_emulate.h" | ||||||
|  | #include "scenes/nfc_scene_debug_read_emv.h" | ||||||
|  | #include "scenes/nfc_scene_debug_read_mifare_ul.h" | ||||||
|  | 
 | ||||||
|  | #define NFC_TEXT_STORE_SIZE 128 | ||||||
| 
 | 
 | ||||||
| struct Nfc { | struct Nfc { | ||||||
|     NfcCommon nfc_common; |     NfcCommon nfc_common; | ||||||
|     osMessageQueueId_t message_queue; |  | ||||||
|     Gui* gui; |     Gui* gui; | ||||||
|     Submenu* submenu; |     NotificationApp* notifications; | ||||||
|  | 
 | ||||||
|  |     char text_store[NFC_TEXT_STORE_SIZE + 1]; | ||||||
|  | 
 | ||||||
|  |     // Nfc Views
 | ||||||
|     NfcDetect* nfc_detect; |     NfcDetect* nfc_detect; | ||||||
|     NfcEmulate* nfc_emulate; |     NfcEmulate* nfc_emulate; | ||||||
|     NfcEmv* nfc_emv; |     NfcEmv* nfc_emv; | ||||||
|     NfcMifareUl* nfc_mifare_ul; |     NfcMifareUl* nfc_mifare_ul; | ||||||
|  | 
 | ||||||
|  |     // Common Views
 | ||||||
|  |     Submenu* submenu; | ||||||
|  |     DialogEx* dialog_ex; | ||||||
|  |     Popup* popup; | ||||||
|  |     TextInput* text_input; | ||||||
|  |     ByteInput* byte_input; | ||||||
|  | 
 | ||||||
|  |     // Scenes
 | ||||||
|  |     AppScene* scene_start; | ||||||
|  |     AppScene* scene_read_card; | ||||||
|  |     AppScene* scene_read_card_success; | ||||||
|  |     AppScene* scene_card_menu; | ||||||
|  |     AppScene* scene_not_implemented; | ||||||
|  |     AppScene* scene_emulate_uid; | ||||||
|  | 
 | ||||||
|  |     // TODO delete debug scenes
 | ||||||
|  |     AppScene* scene_debug_menu; | ||||||
|  |     AppScene* scene_debug_detect; | ||||||
|  |     AppScene* scene_debug_emulate; | ||||||
|  |     AppScene* scene_debug_read_emv; | ||||||
|  |     AppScene* scene_debug_read_mifare_ul; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
|     NfcViewMenu, |     NfcViewMenu, | ||||||
|  |     NfcViewDialogEx, | ||||||
|  |     NfcViewPopup, | ||||||
|  |     NfcViewTextInput, | ||||||
|  |     NfcViewByteInput, | ||||||
|     NfcViewDetect, |     NfcViewDetect, | ||||||
|     NfcViewEmulate, |     NfcViewEmulate, | ||||||
|     NfcViewEmv, |     NfcViewEmv, | ||||||
|     NfcViewMifareUl, |     NfcViewMifareUl, | ||||||
| } NfcView; | } NfcView; | ||||||
| 
 | 
 | ||||||
|  | typedef enum { | ||||||
|  |     NfcSceneStart, | ||||||
|  |     NfcSceneReadCard, | ||||||
|  |     NfcSceneReadCardSuccess, | ||||||
|  |     NfcSceneCardMenu, | ||||||
|  |     NfcSceneEmulateUID, | ||||||
|  |     NfcSceneNotImplemented, | ||||||
|  |     NfcSceneDebugMenu, | ||||||
|  |     NfcSceneDebugDetect, | ||||||
|  |     NfcSceneDebugEmulate, | ||||||
|  |     NfcSceneDebugReadEmv, | ||||||
|  |     NfcSceneDebugReadMifareUl, | ||||||
|  | } NfcScene; | ||||||
|  | 
 | ||||||
| Nfc* nfc_alloc(); | Nfc* nfc_alloc(); | ||||||
| 
 | 
 | ||||||
| int32_t nfc_task(void* p); | int32_t nfc_task(void* p); | ||||||
|  | 
 | ||||||
|  | void nfc_set_text_store(Nfc* nfc, const char* text, ...); | ||||||
|  | |||||||
| @ -9,51 +9,9 @@ | |||||||
| typedef struct { | typedef struct { | ||||||
|     NfcWorker* worker; |     NfcWorker* worker; | ||||||
|     ViewDispatcher* view_dispatcher; |     ViewDispatcher* view_dispatcher; | ||||||
|  |     NfcWorkerResult worker_result; | ||||||
| } NfcCommon; | } NfcCommon; | ||||||
| 
 | 
 | ||||||
| typedef enum { |  | ||||||
|     NfcDeviceNfca, |  | ||||||
|     NfcDeviceNfcb, |  | ||||||
|     NfcDeviceNfcf, |  | ||||||
|     NfcDeviceNfcv, |  | ||||||
| } NfcDeviceType; |  | ||||||
| 
 |  | ||||||
| typedef enum { |  | ||||||
|     NfcDeviceProtocolUnknown, |  | ||||||
|     NfcDeviceProtocolEMV, |  | ||||||
|     NfcDeviceProtocolMfUltralight, |  | ||||||
| } NfcProtocol; |  | ||||||
| 
 |  | ||||||
| typedef struct { |  | ||||||
|     uint8_t uid_len; |  | ||||||
|     uint8_t uid[10]; |  | ||||||
|     uint8_t atqa[2]; |  | ||||||
|     uint8_t sak; |  | ||||||
|     NfcDeviceType device; |  | ||||||
|     NfcProtocol protocol; |  | ||||||
| } NfcDeviceData; |  | ||||||
| 
 |  | ||||||
| typedef struct { |  | ||||||
|     NfcDeviceData nfc_data; |  | ||||||
|     char name[32]; |  | ||||||
|     uint8_t number[8]; |  | ||||||
| } NfcEmvData; |  | ||||||
| 
 |  | ||||||
| typedef struct { |  | ||||||
|     NfcDeviceData nfc_data; |  | ||||||
|     uint8_t man_block[12]; |  | ||||||
|     uint8_t otp[4]; |  | ||||||
| } NfcMifareUlData; |  | ||||||
| 
 |  | ||||||
| typedef struct { |  | ||||||
|     bool found; |  | ||||||
|     union { |  | ||||||
|         NfcDeviceData nfc_detect_data; |  | ||||||
|         NfcEmvData nfc_emv_data; |  | ||||||
|         NfcMifareUlData nfc_mifare_ul_data; |  | ||||||
|     }; |  | ||||||
| } NfcMessage; |  | ||||||
| 
 |  | ||||||
| typedef enum { | typedef enum { | ||||||
|     NfcEventDetect, |     NfcEventDetect, | ||||||
|     NfcEventEmv, |     NfcEventEmv, | ||||||
| @ -69,19 +27,17 @@ typedef enum { | |||||||
| 
 | 
 | ||||||
| static inline const char* nfc_get_dev_type(rfalNfcDevType type) { | static inline const char* nfc_get_dev_type(rfalNfcDevType type) { | ||||||
|     if(type == RFAL_NFC_LISTEN_TYPE_NFCA) { |     if(type == RFAL_NFC_LISTEN_TYPE_NFCA) { | ||||||
|         return "NFC-A"; |         return "NFC-A may be:"; | ||||||
|     } else if(type == RFAL_NFC_LISTEN_TYPE_NFCB) { |     } else if(type == RFAL_NFC_LISTEN_TYPE_NFCB) { | ||||||
|         return "NFC-B"; |         return "NFC-B may be:"; | ||||||
|     } else if(type == RFAL_NFC_LISTEN_TYPE_NFCF) { |     } else if(type == RFAL_NFC_LISTEN_TYPE_NFCF) { | ||||||
|         return "NFC-F"; |         return "NFC-F may be:"; | ||||||
|     } else if(type == RFAL_NFC_LISTEN_TYPE_NFCB) { |  | ||||||
|         return "NFC-B"; |  | ||||||
|     } else if(type == RFAL_NFC_LISTEN_TYPE_NFCV) { |     } else if(type == RFAL_NFC_LISTEN_TYPE_NFCV) { | ||||||
|         return "NFC-V"; |         return "NFC-V may be:"; | ||||||
|     } else if(type == RFAL_NFC_LISTEN_TYPE_ST25TB) { |     } else if(type == RFAL_NFC_LISTEN_TYPE_ST25TB) { | ||||||
|         return "NFC-ST25TB"; |         return "NFC-ST25TB may be:"; | ||||||
|     } else if(type == RFAL_NFC_LISTEN_TYPE_AP2P) { |     } else if(type == RFAL_NFC_LISTEN_TYPE_AP2P) { | ||||||
|         return "NFC-AP2P"; |         return "NFC-AP2P may be:"; | ||||||
|     } else { |     } else { | ||||||
|         return "Unknown"; |         return "Unknown"; | ||||||
|     } |     } | ||||||
| @ -105,10 +61,10 @@ static inline const char* nfc_get_nfca_type(rfalNfcaListenDeviceType type) { | |||||||
| 
 | 
 | ||||||
| static inline const char* nfc_get_protocol(NfcProtocol protocol) { | static inline const char* nfc_get_protocol(NfcProtocol protocol) { | ||||||
|     if(protocol == NfcDeviceProtocolEMV) { |     if(protocol == NfcDeviceProtocolEMV) { | ||||||
|         return "EMV"; |         return "EMV bank card"; | ||||||
|     } else if(protocol == NfcDeviceProtocolMfUltralight) { |     } else if(protocol == NfcDeviceProtocolMfUltralight) { | ||||||
|         return "Mifare UL"; |         return "Mifare Ultralight"; | ||||||
|     } else { |     } else { | ||||||
|         return "Unknown"; |         return "Unrecognized"; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -7,9 +7,8 @@ | |||||||
| 
 | 
 | ||||||
| /***************************** NFC Worker API *******************************/ | /***************************** NFC Worker API *******************************/ | ||||||
| 
 | 
 | ||||||
| NfcWorker* nfc_worker_alloc(osMessageQueueId_t message_queue) { | NfcWorker* nfc_worker_alloc() { | ||||||
|     NfcWorker* nfc_worker = furi_alloc(sizeof(NfcWorker)); |     NfcWorker* nfc_worker = furi_alloc(sizeof(NfcWorker)); | ||||||
|     nfc_worker->message_queue = message_queue; |  | ||||||
|     // Worker thread attributes
 |     // Worker thread attributes
 | ||||||
|     nfc_worker->thread_attr.name = "nfc_worker"; |     nfc_worker->thread_attr.name = "nfc_worker"; | ||||||
|     nfc_worker->thread_attr.stack_size = 8192; |     nfc_worker->thread_attr.stack_size = 8192; | ||||||
| @ -40,23 +39,33 @@ ReturnCode nfc_worker_get_error(NfcWorker* nfc_worker) { | |||||||
|     return nfc_worker->error; |     return nfc_worker->error; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void nfc_worker_set_emulation_params(NfcWorker* nfc_worker, NfcDeviceData* data) { | ||||||
|  |     furi_assert(nfc_worker); | ||||||
|  |     furi_assert(data); | ||||||
|  | 
 | ||||||
|  |     nfc_worker->emulate_params = *data; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void nfc_worker_start( | void nfc_worker_start( | ||||||
|     NfcWorker* nfc_worker, |     NfcWorker* nfc_worker, | ||||||
|     NfcWorkerState state, |     NfcWorkerState state, | ||||||
|  |     NfcWorkerResult* result_dest, | ||||||
|     NfcWorkerCallback callback, |     NfcWorkerCallback callback, | ||||||
|     void* context) { |     void* context) { | ||||||
|     furi_assert(nfc_worker); |     furi_assert(nfc_worker); | ||||||
|     furi_assert(nfc_worker->state == NfcWorkerStateReady); |     furi_assert(nfc_worker->state == NfcWorkerStateReady); | ||||||
|  |     furi_assert(result_dest); | ||||||
| 
 | 
 | ||||||
|     nfc_worker->callback = callback; |     nfc_worker->callback = callback; | ||||||
|     nfc_worker->context = context; |     nfc_worker->context = context; | ||||||
|  |     nfc_worker->last_result = result_dest; | ||||||
|     nfc_worker_change_state(nfc_worker, state); |     nfc_worker_change_state(nfc_worker, state); | ||||||
|     nfc_worker->thread = osThreadNew(nfc_worker_task, nfc_worker, &nfc_worker->thread_attr); |     nfc_worker->thread = osThreadNew(nfc_worker_task, nfc_worker, &nfc_worker->thread_attr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nfc_worker_stop(NfcWorker* nfc_worker) { | void nfc_worker_stop(NfcWorker* nfc_worker) { | ||||||
|     furi_assert(nfc_worker); |     furi_assert(nfc_worker); | ||||||
|     if(nfc_worker->state == NfcWorkerStateBroken) { |     if(nfc_worker->state == NfcWorkerStateBroken || nfc_worker->state == NfcWorkerStateReady) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -82,11 +91,11 @@ void nfc_worker_task(void* context) { | |||||||
|     } else if(nfc_worker->state == NfcWorkerStateReadEMV) { |     } else if(nfc_worker->state == NfcWorkerStateReadEMV) { | ||||||
|         nfc_worker_read_emv(nfc_worker); |         nfc_worker_read_emv(nfc_worker); | ||||||
|     } else if(nfc_worker->state == NfcWorkerStateEmulateEMV) { |     } else if(nfc_worker->state == NfcWorkerStateEmulateEMV) { | ||||||
|         nfc_worker_field(nfc_worker); |         nfc_worker_emulate_emv(nfc_worker); | ||||||
|     } else if(nfc_worker->state == NfcWorkerStateReadMfUltralight) { |     } else if(nfc_worker->state == NfcWorkerStateReadMfUltralight) { | ||||||
|         nfc_worker_read_mf_ultralight(nfc_worker); |         nfc_worker_read_mf_ultralight(nfc_worker); | ||||||
|         nfc_worker_emulate_emv(nfc_worker); |  | ||||||
|     } else if(nfc_worker->state == NfcWorkerStateField) { |     } else if(nfc_worker->state == NfcWorkerStateField) { | ||||||
|  |         nfc_worker_field(nfc_worker); | ||||||
|     } |     } | ||||||
|     api_hal_nfc_deactivate(); |     api_hal_nfc_deactivate(); | ||||||
|     nfc_worker_change_state(nfc_worker, NfcWorkerStateReady); |     nfc_worker_change_state(nfc_worker, NfcWorkerStateReady); | ||||||
| @ -98,46 +107,50 @@ void nfc_worker_detect(NfcWorker* nfc_worker) { | |||||||
|     rfalNfcDevice* dev_list; |     rfalNfcDevice* dev_list; | ||||||
|     rfalNfcDevice* dev; |     rfalNfcDevice* dev; | ||||||
|     uint8_t dev_cnt; |     uint8_t dev_cnt; | ||||||
|     NfcMessage message; |     NfcDeviceData* result = &nfc_worker->last_result->nfc_detect_data; | ||||||
| 
 | 
 | ||||||
|     while(nfc_worker->state == NfcWorkerStateDetect) { |     while(nfc_worker->state == NfcWorkerStateDetect) { | ||||||
|         message.found = false; |  | ||||||
|         if(api_hal_nfc_detect(&dev_list, &dev_cnt, 1000, true)) { |         if(api_hal_nfc_detect(&dev_list, &dev_cnt, 1000, true)) { | ||||||
|             // Process first found device
 |             // Process first found device
 | ||||||
|             dev = &dev_list[0]; |             dev = &dev_list[0]; | ||||||
|             message.found = true; |             result->uid_len = dev->nfcidLen; | ||||||
|             message.nfc_detect_data.uid_len = dev->nfcidLen; |             memcpy(result->uid, dev->nfcid, dev->nfcidLen); | ||||||
|             memcpy(message.nfc_detect_data.uid, dev->nfcid, dev->nfcidLen); |  | ||||||
| 
 |  | ||||||
|             if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCA) { |             if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCA) { | ||||||
|                 message.nfc_detect_data.device = NfcDeviceNfca; |                 result->device = NfcDeviceNfca; | ||||||
|                 message.nfc_detect_data.atqa[0] = dev->dev.nfca.sensRes.anticollisionInfo; |                 result->atqa[0] = dev->dev.nfca.sensRes.anticollisionInfo; | ||||||
|                 message.nfc_detect_data.atqa[1] = dev->dev.nfca.sensRes.platformInfo; |                 result->atqa[1] = dev->dev.nfca.sensRes.platformInfo; | ||||||
|                 message.nfc_detect_data.sak = dev->dev.nfca.selRes.sak; |                 result->sak = dev->dev.nfca.selRes.sak; | ||||||
|                 // TODO check protocols
 |                 if(mf_ul_check_card_type( | ||||||
|  |                        dev->dev.nfca.sensRes.anticollisionInfo, | ||||||
|  |                        dev->dev.nfca.sensRes.platformInfo, | ||||||
|  |                        dev->dev.nfca.selRes.sak)) { | ||||||
|  |                     result->protocol = NfcDeviceProtocolMfUltralight; | ||||||
|  |                 } else { | ||||||
|  |                     result->protocol = NfcDeviceProtocolUnknown; | ||||||
|  |                 } | ||||||
| 
 | 
 | ||||||
|             } else if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCB) { |             } else if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCB) { | ||||||
|                 message.nfc_detect_data.device = NfcDeviceNfcb; |                 result->device = NfcDeviceNfcb; | ||||||
|             } else if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCF) { |             } else if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCF) { | ||||||
|                 message.nfc_detect_data.device = NfcDeviceNfcf; |                 result->device = NfcDeviceNfcf; | ||||||
|             } else if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCV) { |             } else if(dev->type == RFAL_NFC_LISTEN_TYPE_NFCV) { | ||||||
|                 message.nfc_detect_data.device = NfcDeviceNfcv; |                 result->device = NfcDeviceNfcv; | ||||||
|             } |             } | ||||||
|  |             // Notify caller and exit
 | ||||||
|  |             if(nfc_worker->callback) { | ||||||
|  |                 nfc_worker->callback(nfc_worker->context); | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|         } |         } | ||||||
|         if(nfc_worker->callback) { |  | ||||||
|             nfc_worker->callback(nfc_worker->context); |  | ||||||
|         } |  | ||||||
|         furi_check( |  | ||||||
|             osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK); |  | ||||||
|         osDelay(100); |         osDelay(100); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nfc_worker_emulate(NfcWorker* nfc_worker) { | void nfc_worker_emulate(NfcWorker* nfc_worker) { | ||||||
|  |     NfcDeviceData* param = &nfc_worker->emulate_params; | ||||||
|     while(nfc_worker->state == NfcWorkerStateEmulate) { |     while(nfc_worker->state == NfcWorkerStateEmulate) { | ||||||
|         if(api_hal_nfc_listen(ApiHalNfcEmulateParamsMifare, 100)) { |         if(api_hal_nfc_listen(param->uid, param->uid_len, param->atqa, param->sak, 100)) { | ||||||
|             FURI_LOG_I(NFC_WORKER_TAG, "Reader detected"); |             FURI_LOG_I(NFC_WORKER_TAG, "Reader detected"); | ||||||
|             api_hal_nfc_deactivate(); |  | ||||||
|         } |         } | ||||||
|         osDelay(10); |         osDelay(10); | ||||||
|     } |     } | ||||||
| @ -152,14 +165,9 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { | |||||||
|     uint16_t tx_len = 0; |     uint16_t tx_len = 0; | ||||||
|     uint8_t* rx_buff; |     uint8_t* rx_buff; | ||||||
|     uint16_t* rx_len; |     uint16_t* rx_len; | ||||||
|  |     NfcEmvData* result = &nfc_worker->last_result->nfc_emv_data; | ||||||
| 
 | 
 | ||||||
|     NfcMessage message = {.found = false}; |  | ||||||
|     while(nfc_worker->state == NfcWorkerStateReadEMV) { |     while(nfc_worker->state == NfcWorkerStateReadEMV) { | ||||||
|         if(nfc_worker->callback) { |  | ||||||
|             nfc_worker->callback(nfc_worker->context); |  | ||||||
|         } |  | ||||||
|         furi_check( |  | ||||||
|             osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK); |  | ||||||
|         memset(&emv_app, 0, sizeof(emv_app)); |         memset(&emv_app, 0, sizeof(emv_app)); | ||||||
|         if(api_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) { |         if(api_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) { | ||||||
|             // Card was found. Check that it supports EMV
 |             // Card was found. Check that it supports EMV
 | ||||||
| @ -169,7 +177,6 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { | |||||||
|                 err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); |                 err = api_hal_nfc_data_exchange(tx_buff, tx_len, &rx_buff, &rx_len, false); | ||||||
|                 if(err != ERR_NONE) { |                 if(err != ERR_NONE) { | ||||||
|                     FURI_LOG_E(NFC_WORKER_TAG, "Error during selection PPSE request: %d", err); |                     FURI_LOG_E(NFC_WORKER_TAG, "Error during selection PPSE request: %d", err); | ||||||
|                     message.found = false; |  | ||||||
|                     api_hal_nfc_deactivate(); |                     api_hal_nfc_deactivate(); | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
| @ -179,7 +186,6 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { | |||||||
|                     FURI_LOG_I(NFC_WORKER_TAG, "Select PPSE responce parced"); |                     FURI_LOG_I(NFC_WORKER_TAG, "Select PPSE responce parced"); | ||||||
|                 } else { |                 } else { | ||||||
|                     FURI_LOG_E(NFC_WORKER_TAG, "Can't find pay application"); |                     FURI_LOG_E(NFC_WORKER_TAG, "Can't find pay application"); | ||||||
|                     message.found = false; |  | ||||||
|                     api_hal_nfc_deactivate(); |                     api_hal_nfc_deactivate(); | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
| @ -189,7 +195,6 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { | |||||||
|                 if(err != ERR_NONE) { |                 if(err != ERR_NONE) { | ||||||
|                     FURI_LOG_E( |                     FURI_LOG_E( | ||||||
|                         NFC_WORKER_TAG, "Error during application selection request: %d", err); |                         NFC_WORKER_TAG, "Error during application selection request: %d", err); | ||||||
|                     message.found = false; |  | ||||||
|                     api_hal_nfc_deactivate(); |                     api_hal_nfc_deactivate(); | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
| @ -198,10 +203,9 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { | |||||||
|                     "Select application response received. Start parsing response"); |                     "Select application response received. Start parsing response"); | ||||||
|                 if(emv_decode_select_app_response(rx_buff, *rx_len, &emv_app)) { |                 if(emv_decode_select_app_response(rx_buff, *rx_len, &emv_app)) { | ||||||
|                     FURI_LOG_I(NFC_WORKER_TAG, "Card name: %s", emv_app.name); |                     FURI_LOG_I(NFC_WORKER_TAG, "Card name: %s", emv_app.name); | ||||||
|                     memcpy(message.nfc_emv_data.name, emv_app.name, sizeof(emv_app.name)); |                     memcpy(result->name, emv_app.name, sizeof(emv_app.name)); | ||||||
|                 } else { |                 } else { | ||||||
|                     FURI_LOG_E(NFC_WORKER_TAG, "Can't read card name"); |                     FURI_LOG_E(NFC_WORKER_TAG, "Can't read card name"); | ||||||
|                     message.found = false; |  | ||||||
|                     api_hal_nfc_deactivate(); |                     api_hal_nfc_deactivate(); | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
| @ -211,19 +215,17 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { | |||||||
|                 if(err != ERR_NONE) { |                 if(err != ERR_NONE) { | ||||||
|                     FURI_LOG_E( |                     FURI_LOG_E( | ||||||
|                         NFC_WORKER_TAG, "Error during Get Processing Options command: %d", err); |                         NFC_WORKER_TAG, "Error during Get Processing Options command: %d", err); | ||||||
|                     message.found = false; |  | ||||||
|                     api_hal_nfc_deactivate(); |                     api_hal_nfc_deactivate(); | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
|                 if(emv_decode_get_proc_opt(rx_buff, *rx_len, &emv_app)) { |                 if(emv_decode_get_proc_opt(rx_buff, *rx_len, &emv_app)) { | ||||||
|                     FURI_LOG_I(NFC_WORKER_TAG, "Card number parsed"); |                     FURI_LOG_I(NFC_WORKER_TAG, "Card number parsed"); | ||||||
|                     message.found = true; |                     memcpy(result->number, emv_app.card_number, sizeof(emv_app.card_number)); | ||||||
|                     memcpy( |                     // Notify caller and exit
 | ||||||
|                         message.nfc_emv_data.number, |                     if(nfc_worker->callback) { | ||||||
|                         emv_app.card_number, |                         nfc_worker->callback(nfc_worker->context); | ||||||
|                         sizeof(emv_app.card_number)); |                     } | ||||||
|                     api_hal_nfc_deactivate(); |                     break; | ||||||
|                     continue; |  | ||||||
|                 } else { |                 } else { | ||||||
|                     // Mastercard doesn't give PAN / card number as GPO response
 |                     // Mastercard doesn't give PAN / card number as GPO response
 | ||||||
|                     // Iterate over all files found in application
 |                     // Iterate over all files found in application
 | ||||||
| @ -253,27 +255,25 @@ void nfc_worker_read_emv(NfcWorker* nfc_worker) { | |||||||
|                     } |                     } | ||||||
|                     if(pan_found) { |                     if(pan_found) { | ||||||
|                         FURI_LOG_I(NFC_WORKER_TAG, "Card PAN found"); |                         FURI_LOG_I(NFC_WORKER_TAG, "Card PAN found"); | ||||||
|                         message.found = true; |                         memcpy(result->number, emv_app.card_number, sizeof(emv_app.card_number)); | ||||||
|                         memcpy( |                         // Notify caller and exit
 | ||||||
|                             message.nfc_emv_data.number, |                         if(nfc_worker->callback) { | ||||||
|                             emv_app.card_number, |                             nfc_worker->callback(nfc_worker->context); | ||||||
|                             sizeof(emv_app.card_number)); |                         } | ||||||
|  |                         break; | ||||||
|                     } else { |                     } else { | ||||||
|                         FURI_LOG_E(NFC_WORKER_TAG, "Can't read card number"); |                         FURI_LOG_E(NFC_WORKER_TAG, "Can't read card number"); | ||||||
|                         message.found = false; |  | ||||||
|                     } |                     } | ||||||
|                     api_hal_nfc_deactivate(); |                     api_hal_nfc_deactivate(); | ||||||
|                 } |                 } | ||||||
|             } else { |             } else { | ||||||
|                 // Can't find EMV card
 |                 // Can't find EMV card
 | ||||||
|                 FURI_LOG_W(NFC_WORKER_TAG, "Card doesn't support EMV"); |                 FURI_LOG_W(NFC_WORKER_TAG, "Card doesn't support EMV"); | ||||||
|                 message.found = false; |  | ||||||
|                 api_hal_nfc_deactivate(); |                 api_hal_nfc_deactivate(); | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             // Can't find EMV card
 |             // Can't find EMV card
 | ||||||
|             FURI_LOG_W(NFC_WORKER_TAG, "Can't find any cards"); |             FURI_LOG_W(NFC_WORKER_TAG, "Can't find any cards"); | ||||||
|             message.found = false; |  | ||||||
|             api_hal_nfc_deactivate(); |             api_hal_nfc_deactivate(); | ||||||
|         } |         } | ||||||
|         osDelay(20); |         osDelay(20); | ||||||
| @ -286,9 +286,17 @@ void nfc_worker_emulate_emv(NfcWorker* nfc_worker) { | |||||||
|     uint16_t tx_len = 0; |     uint16_t tx_len = 0; | ||||||
|     uint8_t* rx_buff; |     uint8_t* rx_buff; | ||||||
|     uint16_t* rx_len; |     uint16_t* rx_len; | ||||||
|  |     NfcDeviceData params = { | ||||||
|  |         .uid = {0xCF, 0x72, 0xd4, 0x40}, | ||||||
|  |         .uid_len = 4, | ||||||
|  |         .atqa = {0x00, 0x04}, | ||||||
|  |         .sak = 0x20, | ||||||
|  |         .device = NfcDeviceNfca, | ||||||
|  |         .protocol = NfcDeviceProtocolEMV, | ||||||
|  |     }; | ||||||
| 
 | 
 | ||||||
|     while(nfc_worker->state == NfcWorkerStateEmulateEMV) { |     while(nfc_worker->state == NfcWorkerStateEmulateEMV) { | ||||||
|         if(api_hal_nfc_listen(ApiHalNfcEmulateParamsEMV, 1000)) { |         if(api_hal_nfc_listen(params.uid, params.uid_len, params.atqa, params.sak, 100)) { | ||||||
|             FURI_LOG_I(NFC_WORKER_TAG, "POS terminal detected"); |             FURI_LOG_I(NFC_WORKER_TAG, "POS terminal detected"); | ||||||
|             // Read data from POS terminal
 |             // Read data from POS terminal
 | ||||||
|             err = api_hal_nfc_data_exchange(NULL, 0, &rx_buff, &rx_len, false); |             err = api_hal_nfc_data_exchange(NULL, 0, &rx_buff, &rx_len, false); | ||||||
| @ -344,15 +352,9 @@ void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) { | |||||||
|     uint8_t* rx_buff; |     uint8_t* rx_buff; | ||||||
|     uint16_t* rx_len; |     uint16_t* rx_len; | ||||||
|     MfUltralightRead mf_ul_read; |     MfUltralightRead mf_ul_read; | ||||||
|  |     NfcMifareUlData* result = &nfc_worker->last_result->nfc_mifare_ul_data; | ||||||
| 
 | 
 | ||||||
|     // Update screen before start searching
 |  | ||||||
|     NfcMessage message = {.found = false}; |  | ||||||
|     while(nfc_worker->state == NfcWorkerStateReadMfUltralight) { |     while(nfc_worker->state == NfcWorkerStateReadMfUltralight) { | ||||||
|         if(nfc_worker->callback) { |  | ||||||
|             nfc_worker->callback(nfc_worker->context); |  | ||||||
|         } |  | ||||||
|         furi_check( |  | ||||||
|             osMessageQueuePut(nfc_worker->message_queue, &message, 0, osWaitForever) == osOK); |  | ||||||
|         api_hal_nfc_deactivate(); |         api_hal_nfc_deactivate(); | ||||||
|         memset(&mf_ul_read, 0, sizeof(mf_ul_read)); |         memset(&mf_ul_read, 0, sizeof(mf_ul_read)); | ||||||
|         if(api_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) { |         if(api_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) { | ||||||
| @ -383,7 +385,6 @@ void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) { | |||||||
|                     api_hal_nfc_deactivate(); |                     api_hal_nfc_deactivate(); | ||||||
|                     if(!api_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) { |                     if(!api_hal_nfc_detect(&dev_list, &dev_cnt, 1000, false)) { | ||||||
|                         FURI_LOG_E(NFC_WORKER_TAG, "Lost connection. Restarting search"); |                         FURI_LOG_E(NFC_WORKER_TAG, "Lost connection. Restarting search"); | ||||||
|                         message.found = false; |  | ||||||
|                         continue; |                         continue; | ||||||
|                     } |                     } | ||||||
|                 } else { |                 } else { | ||||||
| @ -391,7 +392,6 @@ void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) { | |||||||
|                         NFC_WORKER_TAG, |                         NFC_WORKER_TAG, | ||||||
|                         "Error getting Mifare Ultralight version. Error code: %d", |                         "Error getting Mifare Ultralight version. Error code: %d", | ||||||
|                         err); |                         err); | ||||||
|                     message.found = false; |  | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
| @ -411,7 +411,6 @@ void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) { | |||||||
|                         mf_ul_read.pages_readed = mf_ul_read.pages_to_read; |                         mf_ul_read.pages_readed = mf_ul_read.pages_to_read; | ||||||
|                     } else { |                     } else { | ||||||
|                         FURI_LOG_E(NFC_WORKER_TAG, "Fast read failed"); |                         FURI_LOG_E(NFC_WORKER_TAG, "Fast read failed"); | ||||||
|                         message.found = false; |  | ||||||
|                         continue; |                         continue; | ||||||
|                     } |                     } | ||||||
|                 } else { |                 } else { | ||||||
| @ -431,20 +430,15 @@ void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) { | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 // Fill message for nfc application
 |                 // Fill result data
 | ||||||
|                 message.found = true; |                 result->nfc_data.uid_len = dev_list[0].dev.nfca.nfcId1Len; | ||||||
|                 message.nfc_mifare_ul_data.nfc_data.uid_len = dev_list[0].dev.nfca.nfcId1Len; |                 result->nfc_data.atqa[0] = dev_list[0].dev.nfca.sensRes.anticollisionInfo; | ||||||
|                 message.nfc_mifare_ul_data.nfc_data.atqa[0] = |                 result->nfc_data.atqa[1] = dev_list[0].dev.nfca.sensRes.platformInfo; | ||||||
|                     dev_list[0].dev.nfca.sensRes.anticollisionInfo; |                 result->nfc_data.sak = dev_list[0].dev.nfca.selRes.sak; | ||||||
|                 message.nfc_mifare_ul_data.nfc_data.atqa[1] = |  | ||||||
|                     dev_list[0].dev.nfca.sensRes.platformInfo; |  | ||||||
|                 message.nfc_mifare_ul_data.nfc_data.sak = dev_list[0].dev.nfca.selRes.sak; |  | ||||||
|                 memcpy( |                 memcpy( | ||||||
|                     message.nfc_mifare_ul_data.nfc_data.uid, |                     result->nfc_data.uid, dev_list[0].dev.nfca.nfcId1, result->nfc_data.uid_len); | ||||||
|                     dev_list[0].dev.nfca.nfcId1, |                 memcpy(result->man_block, mf_ul_read.dump, 4 * 3); | ||||||
|                     message.nfc_mifare_ul_data.nfc_data.uid_len); |                 memcpy(result->otp, &mf_ul_read.dump[4 * 3], 4); | ||||||
|                 memcpy(message.nfc_mifare_ul_data.man_block, mf_ul_read.dump, 4 * 3); |  | ||||||
|                 memcpy(message.nfc_mifare_ul_data.otp, &mf_ul_read.dump[4 * 3], 4); |  | ||||||
|                 for(uint8_t i = 0; i < mf_ul_read.pages_readed * 4; i += 4) { |                 for(uint8_t i = 0; i < mf_ul_read.pages_readed * 4; i += 4) { | ||||||
|                     printf("Page %2d: ", i / 4); |                     printf("Page %2d: ", i / 4); | ||||||
|                     for(uint8_t j = 0; j < 4; j++) { |                     for(uint8_t j = 0; j < 4; j++) { | ||||||
| @ -452,12 +446,15 @@ void nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker) { | |||||||
|                     } |                     } | ||||||
|                     printf("\r\n"); |                     printf("\r\n"); | ||||||
|                 } |                 } | ||||||
|  |                 // Notify caller and exit
 | ||||||
|  |                 if(nfc_worker->callback) { | ||||||
|  |                     nfc_worker->callback(nfc_worker->context); | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|             } else { |             } else { | ||||||
|                 message.found = false; |  | ||||||
|                 FURI_LOG_W(NFC_WORKER_TAG, "Tag does not support Mifare Ultralight"); |                 FURI_LOG_W(NFC_WORKER_TAG, "Tag does not support Mifare Ultralight"); | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             message.found = false; |  | ||||||
|             FURI_LOG_W(NFC_WORKER_TAG, "Can't find any tags"); |             FURI_LOG_W(NFC_WORKER_TAG, "Can't find any tags"); | ||||||
|         } |         } | ||||||
|         osDelay(100); |         osDelay(100); | ||||||
|  | |||||||
| @ -1,5 +1,47 @@ | |||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
|  | typedef enum { | ||||||
|  |     NfcDeviceNfca, | ||||||
|  |     NfcDeviceNfcb, | ||||||
|  |     NfcDeviceNfcf, | ||||||
|  |     NfcDeviceNfcv, | ||||||
|  | } NfcDeviceType; | ||||||
|  | 
 | ||||||
|  | typedef enum { | ||||||
|  |     NfcDeviceProtocolUnknown, | ||||||
|  |     NfcDeviceProtocolEMV, | ||||||
|  |     NfcDeviceProtocolMfUltralight, | ||||||
|  | } NfcProtocol; | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     uint8_t uid_len; | ||||||
|  |     uint8_t uid[10]; | ||||||
|  |     uint8_t atqa[2]; | ||||||
|  |     uint8_t sak; | ||||||
|  |     NfcDeviceType device; | ||||||
|  |     NfcProtocol protocol; | ||||||
|  | } NfcDeviceData; | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     NfcDeviceData nfc_data; | ||||||
|  |     char name[32]; | ||||||
|  |     uint8_t number[8]; | ||||||
|  | } NfcEmvData; | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     NfcDeviceData nfc_data; | ||||||
|  |     uint8_t man_block[12]; | ||||||
|  |     uint8_t otp[4]; | ||||||
|  | } NfcMifareUlData; | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     union { | ||||||
|  |         NfcDeviceData nfc_detect_data; | ||||||
|  |         NfcEmvData nfc_emv_data; | ||||||
|  |         NfcMifareUlData nfc_mifare_ul_data; | ||||||
|  |     }; | ||||||
|  | } NfcWorkerResult; | ||||||
|  | 
 | ||||||
| typedef struct NfcWorker NfcWorker; | typedef struct NfcWorker NfcWorker; | ||||||
| 
 | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
| @ -20,17 +62,20 @@ typedef enum { | |||||||
| 
 | 
 | ||||||
| typedef void (*NfcWorkerCallback)(void* context); | typedef void (*NfcWorkerCallback)(void* context); | ||||||
| 
 | 
 | ||||||
| NfcWorker* nfc_worker_alloc(osMessageQueueId_t message_queue); | NfcWorker* nfc_worker_alloc(); | ||||||
| 
 | 
 | ||||||
| NfcWorkerState nfc_worker_get_state(NfcWorker* nfc_worker); | NfcWorkerState nfc_worker_get_state(NfcWorker* nfc_worker); | ||||||
| 
 | 
 | ||||||
| ReturnCode nfc_worker_get_error(NfcWorker* nfc_worker); | ReturnCode nfc_worker_get_error(NfcWorker* nfc_worker); | ||||||
| 
 | 
 | ||||||
|  | void nfc_worker_set_emulation_params(NfcWorker* nfc_worker, NfcDeviceData* data); | ||||||
|  | 
 | ||||||
| void nfc_worker_free(NfcWorker* nfc_worker); | void nfc_worker_free(NfcWorker* nfc_worker); | ||||||
| 
 | 
 | ||||||
| void nfc_worker_start( | void nfc_worker_start( | ||||||
|     NfcWorker* nfc_worker, |     NfcWorker* nfc_worker, | ||||||
|     NfcWorkerState state, |     NfcWorkerState state, | ||||||
|  |     NfcWorkerResult* result_dest, | ||||||
|     NfcWorkerCallback callback, |     NfcWorkerCallback callback, | ||||||
|     void* context); |     void* context); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -20,9 +20,10 @@ struct NfcWorker { | |||||||
|     osThreadAttr_t thread_attr; |     osThreadAttr_t thread_attr; | ||||||
|     osThreadId_t thread; |     osThreadId_t thread; | ||||||
| 
 | 
 | ||||||
|     osMessageQueueId_t message_queue; |     NfcWorkerResult* last_result; | ||||||
|     NfcWorkerCallback callback; |     NfcWorkerCallback callback; | ||||||
|     void* context; |     void* context; | ||||||
|  |     NfcDeviceData emulate_params; | ||||||
| 
 | 
 | ||||||
|     NfcWorkerState state; |     NfcWorkerState state; | ||||||
|     ReturnCode error; |     ReturnCode error; | ||||||
|  | |||||||
							
								
								
									
										95
									
								
								applications/nfc/scenes/nfc_scene_card_menu.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										95
									
								
								applications/nfc/scenes/nfc_scene_card_menu.c
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,95 @@ | |||||||
|  | #include "nfc_scene_card_menu.h" | ||||||
|  | #include "../nfc_i.h" | ||||||
|  | 
 | ||||||
|  | #include <furi.h> | ||||||
|  | #include <gui/modules/submenu.h> | ||||||
|  | #include <gui/view_dispatcher.h> | ||||||
|  | 
 | ||||||
|  | typedef enum { | ||||||
|  |     SubmenuIndexRunApp, | ||||||
|  |     SubmenuIndexChooseScript, | ||||||
|  |     SubmenuIndexEmulate, | ||||||
|  |     SubmenuIndexSave, | ||||||
|  | } SubmenuIndex; | ||||||
|  | 
 | ||||||
|  | void nfc_scene_card_menu_submenu_callback(void* context, uint32_t index) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, index); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_card_menu_on_enter(void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  |     Submenu* submenu = nfc->submenu; | ||||||
|  | 
 | ||||||
|  |     submenu_add_item( | ||||||
|  |         submenu, | ||||||
|  |         "Run compatible app", | ||||||
|  |         SubmenuIndexRunApp, | ||||||
|  |         nfc_scene_card_menu_submenu_callback, | ||||||
|  |         nfc); | ||||||
|  |     submenu_add_item( | ||||||
|  |         submenu, | ||||||
|  |         "Additional reading scripts", | ||||||
|  |         SubmenuIndexChooseScript, | ||||||
|  |         nfc_scene_card_menu_submenu_callback, | ||||||
|  |         nfc); | ||||||
|  |     submenu_add_item( | ||||||
|  |         submenu, "Emulate UID", SubmenuIndexEmulate, nfc_scene_card_menu_submenu_callback, nfc); | ||||||
|  |     submenu_add_item( | ||||||
|  |         submenu, "Name and save UID", SubmenuIndexSave, nfc_scene_card_menu_submenu_callback, nfc); | ||||||
|  | 
 | ||||||
|  |     view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMenu); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const bool nfc_scene_card_menu_on_event(void* context, uint32_t event) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     if(event == SubmenuIndexRunApp) { | ||||||
|  |         view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_not_implemented); | ||||||
|  |         view_dispatcher_send_navigation_event( | ||||||
|  |             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); | ||||||
|  |         return true; | ||||||
|  |     } else if(event == SubmenuIndexChooseScript) { | ||||||
|  |         view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_not_implemented); | ||||||
|  |         view_dispatcher_send_navigation_event( | ||||||
|  |             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); | ||||||
|  |         return true; | ||||||
|  |     } else if(event == SubmenuIndexEmulate) { | ||||||
|  |         view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_emulate_uid); | ||||||
|  |         view_dispatcher_send_navigation_event( | ||||||
|  |             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); | ||||||
|  |         return true; | ||||||
|  |     } else if(event == SubmenuIndexSave) { | ||||||
|  |         view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_not_implemented); | ||||||
|  |         view_dispatcher_send_navigation_event( | ||||||
|  |             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); | ||||||
|  |         return true; | ||||||
|  |     } else if(event == ViewNavigatorEventBack) { | ||||||
|  |         view_dispatcher_send_back_search_scene_event( | ||||||
|  |             nfc->nfc_common.view_dispatcher, NfcSceneStart); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_card_menu_on_exit(void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     submenu_clean(nfc->submenu); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_card_menu_alloc() { | ||||||
|  |     AppScene* scene = furi_alloc(sizeof(AppScene)); | ||||||
|  |     scene->id = NfcSceneCardMenu; | ||||||
|  |     scene->on_enter = nfc_scene_card_menu_on_enter; | ||||||
|  |     scene->on_event = nfc_scene_card_menu_on_event; | ||||||
|  |     scene->on_exit = nfc_scene_card_menu_on_exit; | ||||||
|  | 
 | ||||||
|  |     return scene; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void nfc_scene_card_menu_free(AppScene* scene) { | ||||||
|  |     free(scene); | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								applications/nfc/scenes/nfc_scene_card_menu.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								applications/nfc/scenes/nfc_scene_card_menu.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "app_scene.h" | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_card_menu_alloc(); | ||||||
|  | 
 | ||||||
|  | void nfc_scene_card_menu_free(AppScene* scene); | ||||||
							
								
								
									
										31
									
								
								applications/nfc/scenes/nfc_scene_debug_detect.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										31
									
								
								applications/nfc/scenes/nfc_scene_debug_detect.c
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | #include "nfc_scene_debug_detect.h" | ||||||
|  | #include "../nfc_i.h" | ||||||
|  | 
 | ||||||
|  | #include <furi.h> | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_debug_detect_on_enter(void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewDetect); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const bool nfc_scene_debug_detect_on_event(void* context, uint32_t event) { | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_debug_detect_on_exit(void* context) { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_debug_detect_alloc() { | ||||||
|  |     AppScene* scene = furi_alloc(sizeof(AppScene)); | ||||||
|  |     scene->id = NfcSceneDebugDetect; | ||||||
|  |     scene->on_enter = nfc_scene_debug_detect_on_enter; | ||||||
|  |     scene->on_event = nfc_scene_debug_detect_on_event; | ||||||
|  |     scene->on_exit = nfc_scene_debug_detect_on_exit; | ||||||
|  | 
 | ||||||
|  |     return scene; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void nfc_scene_debug_detect_free(AppScene* scene) { | ||||||
|  |     free(scene); | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								applications/nfc/scenes/nfc_scene_debug_detect.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								applications/nfc/scenes/nfc_scene_debug_detect.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "app_scene.h" | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_debug_detect_alloc(); | ||||||
|  | 
 | ||||||
|  | void nfc_scene_debug_detect_free(AppScene* scene); | ||||||
							
								
								
									
										31
									
								
								applications/nfc/scenes/nfc_scene_debug_emulate.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										31
									
								
								applications/nfc/scenes/nfc_scene_debug_emulate.c
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | #include "nfc_scene_debug_emulate.h" | ||||||
|  | #include "../nfc_i.h" | ||||||
|  | 
 | ||||||
|  | #include <furi.h> | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_debug_emulate_on_enter(void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewEmulate); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const bool nfc_scene_debug_emulate_on_event(void* context, uint32_t event) { | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_debug_emulate_on_exit(void* context) { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_debug_emulate_alloc() { | ||||||
|  |     AppScene* scene = furi_alloc(sizeof(AppScene)); | ||||||
|  |     scene->id = NfcSceneDebugEmulate; | ||||||
|  |     scene->on_enter = nfc_scene_debug_emulate_on_enter; | ||||||
|  |     scene->on_event = nfc_scene_debug_emulate_on_event; | ||||||
|  |     scene->on_exit = nfc_scene_debug_emulate_on_exit; | ||||||
|  | 
 | ||||||
|  |     return scene; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void nfc_scene_debug_emulate_free(AppScene* scene) { | ||||||
|  |     free(scene); | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								applications/nfc/scenes/nfc_scene_debug_emulate.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								applications/nfc/scenes/nfc_scene_debug_emulate.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "app_scene.h" | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_debug_emulate_alloc(); | ||||||
|  | 
 | ||||||
|  | void nfc_scene_debug_emulate_free(AppScene* scene); | ||||||
							
								
								
									
										88
									
								
								applications/nfc/scenes/nfc_scene_debug_menu.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										88
									
								
								applications/nfc/scenes/nfc_scene_debug_menu.c
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,88 @@ | |||||||
|  | #include "nfc_scene_debug_menu.h" | ||||||
|  | #include "../nfc_i.h" | ||||||
|  | 
 | ||||||
|  | #include <furi.h> | ||||||
|  | #include <gui/modules/submenu.h> | ||||||
|  | #include <gui/view_dispatcher.h> | ||||||
|  | 
 | ||||||
|  | typedef enum { | ||||||
|  |     SubmenuIndexDetect, | ||||||
|  |     SubmenuIndexEmulate, | ||||||
|  |     SubmenuIndexReadEmv, | ||||||
|  |     SubmenuIndexReadMifareUl, | ||||||
|  | } SubmenuIndex; | ||||||
|  | 
 | ||||||
|  | void nfc_scene_debug_menu_submenu_callback(void* context, uint32_t index) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, index); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_debug_menu_on_enter(void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  |     Submenu* submenu = nfc->submenu; | ||||||
|  | 
 | ||||||
|  |     submenu_add_item( | ||||||
|  |         submenu, "Detect", SubmenuIndexDetect, nfc_scene_debug_menu_submenu_callback, nfc); | ||||||
|  |     submenu_add_item( | ||||||
|  |         submenu, "Emulate", SubmenuIndexEmulate, nfc_scene_debug_menu_submenu_callback, nfc); | ||||||
|  |     submenu_add_item( | ||||||
|  |         submenu, "Read EMV", SubmenuIndexReadEmv, nfc_scene_debug_menu_submenu_callback, nfc); | ||||||
|  |     submenu_add_item( | ||||||
|  |         submenu, | ||||||
|  |         "Read Mifare Ultralight", | ||||||
|  |         SubmenuIndexReadMifareUl, | ||||||
|  |         nfc_scene_debug_menu_submenu_callback, | ||||||
|  |         nfc); | ||||||
|  | 
 | ||||||
|  |     view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMenu); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const bool nfc_scene_debug_menu_on_event(void* context, uint32_t event) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     if(event == SubmenuIndexDetect) { | ||||||
|  |         view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_debug_detect); | ||||||
|  |         view_dispatcher_send_navigation_event( | ||||||
|  |             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); | ||||||
|  |         return true; | ||||||
|  |     } else if(event == SubmenuIndexEmulate) { | ||||||
|  |         view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_debug_emulate); | ||||||
|  |         view_dispatcher_send_navigation_event( | ||||||
|  |             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); | ||||||
|  |         return true; | ||||||
|  |     } else if(event == SubmenuIndexReadEmv) { | ||||||
|  |         view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_debug_read_emv); | ||||||
|  |         view_dispatcher_send_navigation_event( | ||||||
|  |             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); | ||||||
|  |         return true; | ||||||
|  |     } else if(event == SubmenuIndexReadMifareUl) { | ||||||
|  |         view_dispatcher_add_scene( | ||||||
|  |             nfc->nfc_common.view_dispatcher, nfc->scene_debug_read_mifare_ul); | ||||||
|  |         view_dispatcher_send_navigation_event( | ||||||
|  |             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_debug_menu_on_exit(void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     submenu_clean(nfc->submenu); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_debug_menu_alloc() { | ||||||
|  |     AppScene* scene = furi_alloc(sizeof(AppScene)); | ||||||
|  |     scene->id = NfcSceneDebugMenu; | ||||||
|  |     scene->on_enter = nfc_scene_debug_menu_on_enter; | ||||||
|  |     scene->on_event = nfc_scene_debug_menu_on_event; | ||||||
|  |     scene->on_exit = nfc_scene_debug_menu_on_exit; | ||||||
|  | 
 | ||||||
|  |     return scene; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void nfc_scene_debug_menu_free(AppScene* scene) { | ||||||
|  |     free(scene); | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								applications/nfc/scenes/nfc_scene_debug_menu.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								applications/nfc/scenes/nfc_scene_debug_menu.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "app_scene.h" | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_debug_menu_alloc(); | ||||||
|  | 
 | ||||||
|  | void nfc_scene_debug_menu_free(AppScene* scene); | ||||||
							
								
								
									
										31
									
								
								applications/nfc/scenes/nfc_scene_debug_read_emv.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										31
									
								
								applications/nfc/scenes/nfc_scene_debug_read_emv.c
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | #include "nfc_scene_debug_read_emv.h" | ||||||
|  | #include "../nfc_i.h" | ||||||
|  | 
 | ||||||
|  | #include <furi.h> | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_debug_read_emv_on_enter(void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewEmv); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const bool nfc_scene_debug_read_emv_on_event(void* context, uint32_t event) { | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_debug_read_emv_on_exit(void* context) { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_debug_read_emv_alloc() { | ||||||
|  |     AppScene* scene = furi_alloc(sizeof(AppScene)); | ||||||
|  |     scene->id = NfcSceneDebugReadEmv; | ||||||
|  |     scene->on_enter = nfc_scene_debug_read_emv_on_enter; | ||||||
|  |     scene->on_event = nfc_scene_debug_read_emv_on_event; | ||||||
|  |     scene->on_exit = nfc_scene_debug_read_emv_on_exit; | ||||||
|  | 
 | ||||||
|  |     return scene; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void nfc_scene_debug_read_emv_free(AppScene* scene) { | ||||||
|  |     free(scene); | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								applications/nfc/scenes/nfc_scene_debug_read_emv.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								applications/nfc/scenes/nfc_scene_debug_read_emv.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "app_scene.h" | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_debug_read_emv_alloc(); | ||||||
|  | 
 | ||||||
|  | void nfc_scene_debug_read_emv_free(AppScene* scene); | ||||||
							
								
								
									
										31
									
								
								applications/nfc/scenes/nfc_scene_debug_read_mifare_ul.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										31
									
								
								applications/nfc/scenes/nfc_scene_debug_read_mifare_ul.c
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | #include "nfc_scene_debug_read_mifare_ul.h" | ||||||
|  | #include "../nfc_i.h" | ||||||
|  | 
 | ||||||
|  | #include <furi.h> | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_debug_read_mifare_ul_on_enter(void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMifareUl); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const bool nfc_scene_debug_read_mifare_ul_on_event(void* context, uint32_t event) { | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_debug_read_mifare_ul_on_exit(void* context) { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_debug_read_mifare_ul_alloc() { | ||||||
|  |     AppScene* scene = furi_alloc(sizeof(AppScene)); | ||||||
|  |     scene->id = NfcSceneDebugReadMifareUl; | ||||||
|  |     scene->on_enter = nfc_scene_debug_read_mifare_ul_on_enter; | ||||||
|  |     scene->on_event = nfc_scene_debug_read_mifare_ul_on_event; | ||||||
|  |     scene->on_exit = nfc_scene_debug_read_mifare_ul_on_exit; | ||||||
|  | 
 | ||||||
|  |     return scene; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void nfc_scene_debug_read_mifare_ul_free(AppScene* scene) { | ||||||
|  |     free(scene); | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								applications/nfc/scenes/nfc_scene_debug_read_mifare_ul.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								applications/nfc/scenes/nfc_scene_debug_read_mifare_ul.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "app_scene.h" | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_debug_read_mifare_ul_alloc(); | ||||||
|  | 
 | ||||||
|  | void nfc_scene_debug_read_mifare_ul_free(AppScene* scene); | ||||||
							
								
								
									
										70
									
								
								applications/nfc/scenes/nfc_scene_emulate_uid.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										70
									
								
								applications/nfc/scenes/nfc_scene_emulate_uid.c
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,70 @@ | |||||||
|  | #include <nfc/scenes/nfc_scene_emulate_uid.h> | ||||||
|  | 
 | ||||||
|  | #include <furi.h> | ||||||
|  | 
 | ||||||
|  | #include "../nfc_i.h" | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_emulate_uid_on_enter(void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     // Setup view
 | ||||||
|  |     Popup* popup = nfc->popup; | ||||||
|  |     NfcDeviceData* data = &nfc->nfc_common.worker_result.nfc_detect_data; | ||||||
|  |     if(data->uid_len == 4) { | ||||||
|  |         nfc_set_text_store( | ||||||
|  |             nfc, "%02X %02X %02X %02X", data->uid[0], data->uid[1], data->uid[2], data->uid[3]); | ||||||
|  |     } else if(data->uid_len == 7) { | ||||||
|  |         nfc_set_text_store( | ||||||
|  |             nfc, | ||||||
|  |             "%02X %02X %02X %02X\n%02X %02X %02X", | ||||||
|  |             data->uid[0], | ||||||
|  |             data->uid[1], | ||||||
|  |             data->uid[2], | ||||||
|  |             data->uid[3], | ||||||
|  |             data->uid[4], | ||||||
|  |             data->uid[5], | ||||||
|  |             data->uid[6]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     popup_set_icon(popup, 0, 4, I_RFIDDolphinSend_98x60); | ||||||
|  |     popup_set_header(popup, "Emulating UID", 56, 31, AlignLeft, AlignTop); | ||||||
|  |     popup_set_text(popup, nfc->text_store, 56, 43, AlignLeft, AlignTop); | ||||||
|  | 
 | ||||||
|  |     // Setup and start worker
 | ||||||
|  |     nfc_worker_set_emulation_params( | ||||||
|  |         nfc->nfc_common.worker, &nfc->nfc_common.worker_result.nfc_detect_data); | ||||||
|  |     nfc_worker_start( | ||||||
|  |         nfc->nfc_common.worker, NfcWorkerStateEmulate, &nfc->nfc_common.worker_result, NULL, nfc); | ||||||
|  |     view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewPopup); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const bool nfc_scene_emulate_uid_on_event(void* context, uint32_t event) { | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_emulate_uid_on_exit(void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     // Stop worker
 | ||||||
|  |     nfc_worker_stop(nfc->nfc_common.worker); | ||||||
|  | 
 | ||||||
|  |     // Clear view
 | ||||||
|  |     Popup* popup = nfc->popup; | ||||||
|  |     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); | ||||||
|  |     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); | ||||||
|  |     popup_set_icon(popup, 0, 0, I_Empty_1x1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_emulate_uid_alloc() { | ||||||
|  |     AppScene* scene = furi_alloc(sizeof(AppScene)); | ||||||
|  |     scene->id = NfcSceneEmulateUID; | ||||||
|  |     scene->on_enter = nfc_scene_emulate_uid_on_enter; | ||||||
|  |     scene->on_event = nfc_scene_emulate_uid_on_event; | ||||||
|  |     scene->on_exit = nfc_scene_emulate_uid_on_exit; | ||||||
|  | 
 | ||||||
|  |     return scene; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void nfc_scene_emulate_uid_free(AppScene* scene) { | ||||||
|  |     free(scene); | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								applications/nfc/scenes/nfc_scene_emulate_uid.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								applications/nfc/scenes/nfc_scene_emulate_uid.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "app_scene.h" | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_emulate_uid_alloc(); | ||||||
|  | 
 | ||||||
|  | void nfc_scene_emulate_uid_free(AppScene* scene); | ||||||
							
								
								
									
										61
									
								
								applications/nfc/scenes/nfc_scene_not_implemented.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								applications/nfc/scenes/nfc_scene_not_implemented.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | |||||||
|  | #include "nfc_scene_not_implemented.h" | ||||||
|  | #include "../nfc_i.h" | ||||||
|  | 
 | ||||||
|  | #include <furi.h> | ||||||
|  | #include <gui/modules/dialog_ex.h> | ||||||
|  | #include <gui/view_dispatcher.h> | ||||||
|  | 
 | ||||||
|  | void nfc_scene_not_implemented_dialog_callback(DialogExResult result, void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, result); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_not_implemented_on_enter(void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     // TODO Set data from worker
 | ||||||
|  |     DialogEx* dialog_ex = nfc->dialog_ex; | ||||||
|  |     dialog_ex_set_left_button_text(dialog_ex, "Back"); | ||||||
|  |     dialog_ex_set_header(dialog_ex, "Not implemented", 60, 24, AlignCenter, AlignCenter); | ||||||
|  |     dialog_ex_set_context(dialog_ex, nfc); | ||||||
|  |     dialog_ex_set_result_callback(dialog_ex, nfc_scene_not_implemented_dialog_callback); | ||||||
|  | 
 | ||||||
|  |     view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewDialogEx); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const bool nfc_scene_not_implemented_on_event(void* context, uint32_t event) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     if(event == DialogExResultLeft) { | ||||||
|  |         view_dispatcher_send_navigation_event( | ||||||
|  |             nfc->nfc_common.view_dispatcher, ViewNavigatorEventBack); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_not_implemented_on_exit(void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     DialogEx* dialog_ex = nfc->dialog_ex; | ||||||
|  |     dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); | ||||||
|  |     dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); | ||||||
|  |     dialog_ex_set_left_button_text(dialog_ex, NULL); | ||||||
|  |     dialog_ex_set_result_callback(dialog_ex, NULL); | ||||||
|  |     dialog_ex_set_context(dialog_ex, NULL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_not_implemented_alloc() { | ||||||
|  |     AppScene* scene = furi_alloc(sizeof(AppScene)); | ||||||
|  |     scene->id = NfcSceneReadCardSuccess; | ||||||
|  |     scene->on_enter = nfc_scene_not_implemented_on_enter; | ||||||
|  |     scene->on_event = nfc_scene_not_implemented_on_event; | ||||||
|  |     scene->on_exit = nfc_scene_not_implemented_on_exit; | ||||||
|  | 
 | ||||||
|  |     return scene; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void nfc_scene_not_implemented_free(AppScene* scene) { | ||||||
|  |     free(scene); | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								applications/nfc/scenes/nfc_scene_not_implemented.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								applications/nfc/scenes/nfc_scene_not_implemented.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "app_scene.h" | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_not_implemented_alloc(); | ||||||
|  | 
 | ||||||
|  | void nfc_scene_not_implemented_free(AppScene* scene); | ||||||
							
								
								
									
										70
									
								
								applications/nfc/scenes/nfc_scene_read_card.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										70
									
								
								applications/nfc/scenes/nfc_scene_read_card.c
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,70 @@ | |||||||
|  | #include <nfc/scenes/nfc_scene_read_card.h> | ||||||
|  | 
 | ||||||
|  | #include <furi.h> | ||||||
|  | 
 | ||||||
|  | #include "../nfc_i.h" | ||||||
|  | #include "../views/nfc_detect.h" | ||||||
|  | 
 | ||||||
|  | #include <gui/view_dispatcher.h> | ||||||
|  | 
 | ||||||
|  | void nfc_read_card_worker_callback(void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  |     view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, NfcEventDetect); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_read_card_on_enter(void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     // Setup view
 | ||||||
|  |     Popup* popup = nfc->popup; | ||||||
|  |     popup_set_header(popup, "Detecting\nNFC card", 70, 34, AlignLeft, AlignTop); | ||||||
|  |     popup_set_icon(popup, 0, 4, I_RFIDDolphinReceive_98x60); | ||||||
|  | 
 | ||||||
|  |     // Start worker
 | ||||||
|  |     nfc_worker_start( | ||||||
|  |         nfc->nfc_common.worker, | ||||||
|  |         NfcWorkerStateDetect, | ||||||
|  |         &nfc->nfc_common.worker_result, | ||||||
|  |         nfc_read_card_worker_callback, | ||||||
|  |         nfc); | ||||||
|  |     view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewPopup); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const bool nfc_scene_read_card_on_event(void* context, uint32_t event) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     if(event == NfcEventDetect) { | ||||||
|  |         view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_read_card_success); | ||||||
|  |         view_dispatcher_send_navigation_event( | ||||||
|  |             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_read_card_on_exit(void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     // Stop worker
 | ||||||
|  |     nfc_worker_stop(nfc->nfc_common.worker); | ||||||
|  | 
 | ||||||
|  |     // Clear view
 | ||||||
|  |     Popup* popup = nfc->popup; | ||||||
|  |     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); | ||||||
|  |     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); | ||||||
|  |     popup_set_icon(popup, 0, 0, I_Empty_1x1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_read_card_alloc() { | ||||||
|  |     AppScene* scene = furi_alloc(sizeof(AppScene)); | ||||||
|  |     scene->id = NfcSceneReadCard; | ||||||
|  |     scene->on_enter = nfc_scene_read_card_on_enter; | ||||||
|  |     scene->on_event = nfc_scene_read_card_on_event; | ||||||
|  |     scene->on_exit = nfc_scene_read_card_on_exit; | ||||||
|  | 
 | ||||||
|  |     return scene; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void nfc_scene_read_card_free(AppScene* scene) { | ||||||
|  |     free(scene); | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								applications/nfc/scenes/nfc_scene_read_card.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								applications/nfc/scenes/nfc_scene_read_card.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "app_scene.h" | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_read_card_alloc(); | ||||||
|  | 
 | ||||||
|  | void nfc_scene_read_card_free(AppScene* scene); | ||||||
							
								
								
									
										109
									
								
								applications/nfc/scenes/nfc_scene_read_card_success.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										109
									
								
								applications/nfc/scenes/nfc_scene_read_card_success.c
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | #include "nfc_scene_read_card_success.h" | ||||||
|  | #include "../nfc_i.h" | ||||||
|  | 
 | ||||||
|  | #include <furi.h> | ||||||
|  | #include <gui/modules/dialog_ex.h> | ||||||
|  | #include <gui/view_dispatcher.h> | ||||||
|  | 
 | ||||||
|  | #define NFC_SCENE_READ_SUCCESS_SHIFT "              " | ||||||
|  | 
 | ||||||
|  | void nfc_scene_read_card_success_dialog_callback(DialogExResult result, void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, result); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_read_card_success_on_enter(void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     // Send notification
 | ||||||
|  |     notification_message(nfc->notifications, &sequence_success); | ||||||
|  | 
 | ||||||
|  |     // Setup view
 | ||||||
|  |     NfcDeviceData* data = (NfcDeviceData*)&nfc->nfc_common.worker_result; | ||||||
|  |     DialogEx* dialog_ex = nfc->dialog_ex; | ||||||
|  |     dialog_ex_set_left_button_text(dialog_ex, "Retry"); | ||||||
|  |     dialog_ex_set_right_button_text(dialog_ex, "More"); | ||||||
|  |     dialog_ex_set_header(dialog_ex, nfc_get_dev_type(data->device), 36, 8, AlignLeft, AlignCenter); | ||||||
|  |     dialog_ex_set_icon(dialog_ex, 8, 13, I_Medium_chip_22x21); | ||||||
|  |     // Display UID
 | ||||||
|  |     if(data->uid_len == 4) { | ||||||
|  |         nfc_set_text_store( | ||||||
|  |             nfc, | ||||||
|  |             NFC_SCENE_READ_SUCCESS_SHIFT "%s\n" NFC_SCENE_READ_SUCCESS_SHIFT | ||||||
|  |                                          "ATQA: %02X%02X SAK: %02X\nUID: %02X %02X %02X %02X", | ||||||
|  |             nfc_get_protocol(data->protocol), | ||||||
|  |             data->atqa[0], | ||||||
|  |             data->atqa[1], | ||||||
|  |             data->sak, | ||||||
|  |             data->uid[0], | ||||||
|  |             data->uid[1], | ||||||
|  |             data->uid[2], | ||||||
|  |             data->uid[3]); | ||||||
|  |     } else if(data->uid_len == 7) { | ||||||
|  |         nfc_set_text_store( | ||||||
|  |             nfc, | ||||||
|  |             NFC_SCENE_READ_SUCCESS_SHIFT | ||||||
|  |             "%s\n" NFC_SCENE_READ_SUCCESS_SHIFT | ||||||
|  |             "ATQA: %02X%02X SAK: %02X\nUID: %02X %02X %02X %02X %02X %02X %02X", | ||||||
|  |             nfc_get_protocol(data->protocol), | ||||||
|  |             data->atqa[0], | ||||||
|  |             data->atqa[1], | ||||||
|  |             data->sak, | ||||||
|  |             data->uid[0], | ||||||
|  |             data->uid[1], | ||||||
|  |             data->uid[2], | ||||||
|  |             data->uid[3], | ||||||
|  |             data->uid[4], | ||||||
|  |             data->uid[5], | ||||||
|  |             data->uid[6]); | ||||||
|  |     } | ||||||
|  |     dialog_ex_set_text(dialog_ex, nfc->text_store, 8, 16, AlignLeft, AlignTop); | ||||||
|  |     dialog_ex_set_context(dialog_ex, nfc); | ||||||
|  |     dialog_ex_set_result_callback(dialog_ex, nfc_scene_read_card_success_dialog_callback); | ||||||
|  | 
 | ||||||
|  |     view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewDialogEx); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const bool nfc_scene_read_card_success_on_event(void* context, uint32_t event) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     if(event == DialogExResultLeft) { | ||||||
|  |         view_dispatcher_send_navigation_event( | ||||||
|  |             nfc->nfc_common.view_dispatcher, ViewNavigatorEventBack); | ||||||
|  |         return true; | ||||||
|  |     } else if(event == DialogExResultRight) { | ||||||
|  |         view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_card_menu); | ||||||
|  |         view_dispatcher_send_navigation_event( | ||||||
|  |             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_read_card_success_on_exit(void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     DialogEx* dialog_ex = nfc->dialog_ex; | ||||||
|  |     dialog_ex_set_header(dialog_ex, NULL, 0, 0, AlignCenter, AlignCenter); | ||||||
|  |     dialog_ex_set_text(dialog_ex, NULL, 0, 0, AlignCenter, AlignTop); | ||||||
|  |     dialog_ex_set_icon(dialog_ex, 0, 0, I_Empty_1x1); | ||||||
|  |     dialog_ex_set_left_button_text(dialog_ex, NULL); | ||||||
|  |     dialog_ex_set_right_button_text(dialog_ex, NULL); | ||||||
|  |     dialog_ex_set_result_callback(dialog_ex, NULL); | ||||||
|  |     dialog_ex_set_context(dialog_ex, NULL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_read_card_success_alloc() { | ||||||
|  |     AppScene* scene = furi_alloc(sizeof(AppScene)); | ||||||
|  |     scene->id = NfcSceneReadCardSuccess; | ||||||
|  |     scene->on_enter = nfc_scene_read_card_success_on_enter; | ||||||
|  |     scene->on_event = nfc_scene_read_card_success_on_event; | ||||||
|  |     scene->on_exit = nfc_scene_read_card_success_on_exit; | ||||||
|  | 
 | ||||||
|  |     return scene; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void nfc_scene_read_card_success_free(AppScene* scene) { | ||||||
|  |     free(scene); | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								applications/nfc/scenes/nfc_scene_read_card_success.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								applications/nfc/scenes/nfc_scene_read_card_success.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "app_scene.h" | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_read_card_success_alloc(); | ||||||
|  | 
 | ||||||
|  | void nfc_scene_read_card_success_free(AppScene* scene); | ||||||
							
								
								
									
										92
									
								
								applications/nfc/scenes/nfc_scene_start.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								applications/nfc/scenes/nfc_scene_start.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,92 @@ | |||||||
|  | #include "nfc_scene_start.h" | ||||||
|  | #include "../nfc_i.h" | ||||||
|  | 
 | ||||||
|  | #include <furi.h> | ||||||
|  | #include <gui/modules/submenu.h> | ||||||
|  | #include <gui/view_dispatcher.h> | ||||||
|  | 
 | ||||||
|  | typedef enum { | ||||||
|  |     SubmenuIndexRead, | ||||||
|  |     SubmenuIndexRunScript, | ||||||
|  |     SubmenuIndexSaved, | ||||||
|  |     SubmenuIndexAddManualy, | ||||||
|  |     SubmenuIndexDebug, | ||||||
|  | } SubmenuIndex; | ||||||
|  | 
 | ||||||
|  | void nfc_scene_start_submenu_callback(void* context, uint32_t index) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     view_dispatcher_send_custom_event(nfc->nfc_common.view_dispatcher, index); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_start_on_enter(void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  |     Submenu* submenu = nfc->submenu; | ||||||
|  | 
 | ||||||
|  |     submenu_add_item( | ||||||
|  |         submenu, "Read card", SubmenuIndexRead, nfc_scene_start_submenu_callback, nfc); | ||||||
|  |     submenu_add_item( | ||||||
|  |         submenu, | ||||||
|  |         "Run special action", | ||||||
|  |         SubmenuIndexRunScript, | ||||||
|  |         nfc_scene_start_submenu_callback, | ||||||
|  |         nfc); | ||||||
|  |     submenu_add_item( | ||||||
|  |         submenu, "Saved cards", SubmenuIndexSaved, nfc_scene_start_submenu_callback, nfc); | ||||||
|  |     submenu_add_item( | ||||||
|  |         submenu, "Add manualy", SubmenuIndexAddManualy, nfc_scene_start_submenu_callback, nfc); | ||||||
|  |     submenu_add_item(submenu, "Debug", SubmenuIndexDebug, nfc_scene_start_submenu_callback, nfc); | ||||||
|  | 
 | ||||||
|  |     view_dispatcher_switch_to_view(nfc->nfc_common.view_dispatcher, NfcViewMenu); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const bool nfc_scene_start_on_event(void* context, uint32_t event) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     if(event == SubmenuIndexRead) { | ||||||
|  |         view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_read_card); | ||||||
|  |         view_dispatcher_send_navigation_event( | ||||||
|  |             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); | ||||||
|  |         return true; | ||||||
|  |     } else if(event == SubmenuIndexRunScript) { | ||||||
|  |         view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_not_implemented); | ||||||
|  |         view_dispatcher_send_navigation_event( | ||||||
|  |             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); | ||||||
|  |         return true; | ||||||
|  |     } else if(event == SubmenuIndexSaved) { | ||||||
|  |         view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_not_implemented); | ||||||
|  |         view_dispatcher_send_navigation_event( | ||||||
|  |             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); | ||||||
|  |         return true; | ||||||
|  |     } else if(event == SubmenuIndexAddManualy) { | ||||||
|  |         view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_not_implemented); | ||||||
|  |         view_dispatcher_send_navigation_event( | ||||||
|  |             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); | ||||||
|  |         return true; | ||||||
|  |     } else if(event == SubmenuIndexDebug) { | ||||||
|  |         view_dispatcher_add_scene(nfc->nfc_common.view_dispatcher, nfc->scene_debug_menu); | ||||||
|  |         view_dispatcher_send_navigation_event( | ||||||
|  |             nfc->nfc_common.view_dispatcher, ViewNavigatorEventNext); | ||||||
|  |     } | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const void nfc_scene_start_on_exit(void* context) { | ||||||
|  |     Nfc* nfc = (Nfc*)context; | ||||||
|  | 
 | ||||||
|  |     submenu_clean(nfc->submenu); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_start_alloc() { | ||||||
|  |     AppScene* scene = furi_alloc(sizeof(AppScene)); | ||||||
|  |     scene->id = NfcSceneStart; | ||||||
|  |     scene->on_enter = nfc_scene_start_on_enter; | ||||||
|  |     scene->on_event = nfc_scene_start_on_event; | ||||||
|  |     scene->on_exit = nfc_scene_start_on_exit; | ||||||
|  | 
 | ||||||
|  |     return scene; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void nfc_scene_start_free(AppScene* scene) { | ||||||
|  |     free(scene); | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								applications/nfc/scenes/nfc_scene_start.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								applications/nfc/scenes/nfc_scene_start.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "app_scene.h" | ||||||
|  | 
 | ||||||
|  | AppScene* nfc_scene_start_alloc(); | ||||||
|  | 
 | ||||||
|  | void nfc_scene_start_free(AppScene* scene); | ||||||
| @ -1,11 +1,11 @@ | |||||||
| #include "nfc_detect.h" | #include "nfc_detect.h" | ||||||
| 
 | 
 | ||||||
| #include "nfc_i.h" |  | ||||||
| #include "nfc_types.h" |  | ||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include <api-hal.h> | #include <api-hal.h> | ||||||
| #include <input/input.h> | #include <input/input.h> | ||||||
| 
 | 
 | ||||||
|  | #include "../nfc_i.h" | ||||||
|  | 
 | ||||||
| struct NfcDetect { | struct NfcDetect { | ||||||
|     NfcCommon* nfc_common; |     NfcCommon* nfc_common; | ||||||
|     View* view; |     View* view; | ||||||
| @ -64,24 +64,24 @@ void nfc_detect_worker_callback(void* context) { | |||||||
|     view_dispatcher_send_custom_event(nfc_detect->nfc_common->view_dispatcher, NfcEventDetect); |     view_dispatcher_send_custom_event(nfc_detect->nfc_common->view_dispatcher, NfcEventDetect); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nfc_detect_view_dispatcher_callback(NfcDetect* nfc_detect, NfcMessage* message) { | bool nfc_detect_view_custom(uint32_t event, void* context) { | ||||||
|     furi_assert(nfc_detect); |     furi_assert(context); | ||||||
|     furi_assert(message); | 
 | ||||||
|  |     NfcDetect* nfc_detect = (NfcDetect*)context; | ||||||
|  |     if(event == NfcEventDetect) { | ||||||
|  |         NfcDeviceData* data = (NfcDeviceData*)&nfc_detect->nfc_common->worker_result; | ||||||
| 
 | 
 | ||||||
|     if(message->found) { |  | ||||||
|         with_view_model( |         with_view_model( | ||||||
|             nfc_detect->view, (NfcDetectModel * model) { |             nfc_detect->view, (NfcDetectModel * model) { | ||||||
|                 model->found = true; |                 model->found = true; | ||||||
|                 model->data = message->nfc_detect_data; |                 model->data = *data; | ||||||
|                 return true; |  | ||||||
|             }); |  | ||||||
|     } else { |  | ||||||
|         with_view_model( |  | ||||||
|             nfc_detect->view, (NfcDetectModel * model) { |  | ||||||
|                 model->found = false; |  | ||||||
|                 return true; |                 return true; | ||||||
|             }); |             }); | ||||||
|  |         // TODO add and configure next view model
 | ||||||
|  |         return false; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nfc_detect_enter(void* context) { | void nfc_detect_enter(void* context) { | ||||||
| @ -97,6 +97,7 @@ void nfc_detect_enter(void* context) { | |||||||
|     nfc_worker_start( |     nfc_worker_start( | ||||||
|         nfc_detect->nfc_common->worker, |         nfc_detect->nfc_common->worker, | ||||||
|         NfcWorkerStateDetect, |         NfcWorkerStateDetect, | ||||||
|  |         &nfc_detect->nfc_common->worker_result, | ||||||
|         nfc_detect_worker_callback, |         nfc_detect_worker_callback, | ||||||
|         nfc_detect); |         nfc_detect); | ||||||
| } | } | ||||||
| @ -108,10 +109,6 @@ void nfc_detect_exit(void* context) { | |||||||
|     nfc_worker_stop(nfc_detect->nfc_common->worker); |     nfc_worker_stop(nfc_detect->nfc_common->worker); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint32_t nfc_detect_back(void* context) { |  | ||||||
|     return NfcViewMenu; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| NfcDetect* nfc_detect_alloc(NfcCommon* nfc_common) { | NfcDetect* nfc_detect_alloc(NfcCommon* nfc_common) { | ||||||
|     furi_assert(nfc_common); |     furi_assert(nfc_common); | ||||||
| 
 | 
 | ||||||
| @ -124,9 +121,9 @@ NfcDetect* nfc_detect_alloc(NfcCommon* nfc_common) { | |||||||
|     view_set_context(nfc_detect->view, nfc_detect); |     view_set_context(nfc_detect->view, nfc_detect); | ||||||
|     view_set_draw_callback(nfc_detect->view, (ViewDrawCallback)nfc_detect_draw); |     view_set_draw_callback(nfc_detect->view, (ViewDrawCallback)nfc_detect_draw); | ||||||
|     view_set_input_callback(nfc_detect->view, nfc_detect_input); |     view_set_input_callback(nfc_detect->view, nfc_detect_input); | ||||||
|  |     view_set_custom_callback(nfc_detect->view, nfc_detect_view_custom); | ||||||
|     view_set_enter_callback(nfc_detect->view, nfc_detect_enter); |     view_set_enter_callback(nfc_detect->view, nfc_detect_enter); | ||||||
|     view_set_exit_callback(nfc_detect->view, nfc_detect_exit); |     view_set_exit_callback(nfc_detect->view, nfc_detect_exit); | ||||||
|     view_set_previous_callback(nfc_detect->view, nfc_detect_back); |  | ||||||
| 
 | 
 | ||||||
|     return nfc_detect; |     return nfc_detect; | ||||||
| } | } | ||||||
| @ -1,7 +1,7 @@ | |||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <gui/view.h> | #include <gui/view.h> | ||||||
| #include "nfc_types.h" | #include "../nfc_types.h" | ||||||
| 
 | 
 | ||||||
| typedef struct NfcDetect NfcDetect; | typedef struct NfcDetect NfcDetect; | ||||||
| 
 | 
 | ||||||
| @ -10,5 +10,3 @@ NfcDetect* nfc_detect_alloc(NfcCommon* nfc_common); | |||||||
| void nfc_detect_free(NfcDetect* nfc_detect); | void nfc_detect_free(NfcDetect* nfc_detect); | ||||||
| 
 | 
 | ||||||
| View* nfc_detect_get_view(NfcDetect* nfc_detect); | View* nfc_detect_get_view(NfcDetect* nfc_detect); | ||||||
| 
 |  | ||||||
| void nfc_detect_view_dispatcher_callback(NfcDetect* nfc_detect, NfcMessage* message); |  | ||||||
							
								
								
									
										16
									
								
								applications/nfc/nfc_emulate.c → applications/nfc/views/nfc_emulate.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										16
									
								
								applications/nfc/nfc_emulate.c → applications/nfc/views/nfc_emulate.c
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @ -1,11 +1,11 @@ | |||||||
| #include "nfc_emulate.h" | #include "nfc_emulate.h" | ||||||
| 
 | 
 | ||||||
| #include "nfc_i.h" |  | ||||||
| #include "nfc_types.h" |  | ||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include <api-hal.h> | #include <api-hal.h> | ||||||
| #include <input/input.h> | #include <input/input.h> | ||||||
| 
 | 
 | ||||||
|  | #include "../nfc_i.h" | ||||||
|  | 
 | ||||||
| struct NfcEmulate { | struct NfcEmulate { | ||||||
|     NfcCommon* nfc_common; |     NfcCommon* nfc_common; | ||||||
|     View* view; |     View* view; | ||||||
| @ -33,7 +33,12 @@ void nfc_emulate_enter(void* context) { | |||||||
|     furi_assert(context); |     furi_assert(context); | ||||||
| 
 | 
 | ||||||
|     NfcEmulate* nfc_emulate = (NfcEmulate*)context; |     NfcEmulate* nfc_emulate = (NfcEmulate*)context; | ||||||
|     nfc_worker_start(nfc_emulate->nfc_common->worker, NfcWorkerStateEmulate, NULL, NULL); |     nfc_worker_start( | ||||||
|  |         nfc_emulate->nfc_common->worker, | ||||||
|  |         NfcWorkerStateEmulate, | ||||||
|  |         &nfc_emulate->nfc_common->worker_result, | ||||||
|  |         NULL, | ||||||
|  |         NULL); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nfc_emulate_exit(void* context) { | void nfc_emulate_exit(void* context) { | ||||||
| @ -43,10 +48,6 @@ void nfc_emulate_exit(void* context) { | |||||||
|     nfc_worker_stop(nfc_emulate->nfc_common->worker); |     nfc_worker_stop(nfc_emulate->nfc_common->worker); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint32_t nfc_emulate_back(void* context) { |  | ||||||
|     return NfcViewMenu; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| NfcEmulate* nfc_emulate_alloc(NfcCommon* nfc_common) { | NfcEmulate* nfc_emulate_alloc(NfcCommon* nfc_common) { | ||||||
|     furi_assert(nfc_common); |     furi_assert(nfc_common); | ||||||
| 
 | 
 | ||||||
| @ -60,7 +61,6 @@ NfcEmulate* nfc_emulate_alloc(NfcCommon* nfc_common) { | |||||||
|     view_set_input_callback(nfc_emulate->view, nfc_emulate_input); |     view_set_input_callback(nfc_emulate->view, nfc_emulate_input); | ||||||
|     view_set_enter_callback(nfc_emulate->view, nfc_emulate_enter); |     view_set_enter_callback(nfc_emulate->view, nfc_emulate_enter); | ||||||
|     view_set_exit_callback(nfc_emulate->view, nfc_emulate_exit); |     view_set_exit_callback(nfc_emulate->view, nfc_emulate_exit); | ||||||
|     view_set_previous_callback(nfc_emulate->view, nfc_emulate_back); |  | ||||||
| 
 | 
 | ||||||
|     return nfc_emulate; |     return nfc_emulate; | ||||||
| } | } | ||||||
| @ -1,7 +1,7 @@ | |||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <gui/view.h> | #include <gui/view.h> | ||||||
| #include "nfc_types.h" | #include "../nfc_types.h" | ||||||
| 
 | 
 | ||||||
| typedef struct NfcEmulate NfcEmulate; | typedef struct NfcEmulate NfcEmulate; | ||||||
| 
 | 
 | ||||||
| @ -1,11 +1,11 @@ | |||||||
| #include "nfc_emv.h" | #include "nfc_emv.h" | ||||||
| 
 | 
 | ||||||
| #include "nfc_i.h" |  | ||||||
| #include "nfc_types.h" |  | ||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include <api-hal.h> | #include <api-hal.h> | ||||||
| #include <input/input.h> | #include <input/input.h> | ||||||
| 
 | 
 | ||||||
|  | #include "../nfc_i.h" | ||||||
|  | 
 | ||||||
| struct NfcEmv { | struct NfcEmv { | ||||||
|     NfcCommon* nfc_common; |     NfcCommon* nfc_common; | ||||||
|     View* view; |     View* view; | ||||||
| @ -56,24 +56,24 @@ void nfc_emv_worker_callback(void* context) { | |||||||
|     view_dispatcher_send_custom_event(nfc_emv->nfc_common->view_dispatcher, NfcEventEmv); |     view_dispatcher_send_custom_event(nfc_emv->nfc_common->view_dispatcher, NfcEventEmv); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nfc_emv_view_dispatcher_callback(NfcEmv* nfc_emv, NfcMessage* message) { | bool nfc_emv_custom(uint32_t event, void* context) { | ||||||
|     furi_assert(nfc_emv); |     furi_assert(context); | ||||||
|     furi_assert(message); | 
 | ||||||
|  |     NfcEmv* nfc_emv = (NfcEmv*)context; | ||||||
|  |     if(event == NfcEventEmv) { | ||||||
|  |         NfcEmvData* data = (NfcEmvData*)&nfc_emv->nfc_common->worker_result; | ||||||
| 
 | 
 | ||||||
|     if(message->found) { |  | ||||||
|         with_view_model( |         with_view_model( | ||||||
|             nfc_emv->view, (NfcEmvModel * model) { |             nfc_emv->view, (NfcEmvModel * model) { | ||||||
|                 model->found = true; |                 model->found = true; | ||||||
|                 model->emv_data = message->nfc_emv_data; |                 model->emv_data = *data; | ||||||
|                 return true; |  | ||||||
|             }); |  | ||||||
|     } else { |  | ||||||
|         with_view_model( |  | ||||||
|             nfc_emv->view, (NfcEmvModel * model) { |  | ||||||
|                 model->found = false; |  | ||||||
|                 return true; |                 return true; | ||||||
|             }); |             }); | ||||||
|  |         // TODO add and configure next view model
 | ||||||
|  |         return true; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nfc_emv_enter(void* context) { | void nfc_emv_enter(void* context) { | ||||||
| @ -86,7 +86,11 @@ void nfc_emv_enter(void* context) { | |||||||
|             return true; |             return true; | ||||||
|         }); |         }); | ||||||
|     nfc_worker_start( |     nfc_worker_start( | ||||||
|         nfc_emv->nfc_common->worker, NfcWorkerStateReadEMV, nfc_emv_worker_callback, nfc_emv); |         nfc_emv->nfc_common->worker, | ||||||
|  |         NfcWorkerStateReadEMV, | ||||||
|  |         &nfc_emv->nfc_common->worker_result, | ||||||
|  |         nfc_emv_worker_callback, | ||||||
|  |         nfc_emv); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nfc_emv_exit(void* context) { | void nfc_emv_exit(void* context) { | ||||||
| @ -96,10 +100,6 @@ void nfc_emv_exit(void* context) { | |||||||
|     nfc_worker_stop(nfc_emv->nfc_common->worker); |     nfc_worker_stop(nfc_emv->nfc_common->worker); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint32_t nfc_emv_back(void* context) { |  | ||||||
|     return NfcViewMenu; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| NfcEmv* nfc_emv_alloc(NfcCommon* nfc_common) { | NfcEmv* nfc_emv_alloc(NfcCommon* nfc_common) { | ||||||
|     furi_assert(nfc_common); |     furi_assert(nfc_common); | ||||||
| 
 | 
 | ||||||
| @ -112,9 +112,9 @@ NfcEmv* nfc_emv_alloc(NfcCommon* nfc_common) { | |||||||
|     view_set_context(nfc_emv->view, nfc_emv); |     view_set_context(nfc_emv->view, nfc_emv); | ||||||
|     view_set_draw_callback(nfc_emv->view, (ViewDrawCallback)nfc_emv_draw); |     view_set_draw_callback(nfc_emv->view, (ViewDrawCallback)nfc_emv_draw); | ||||||
|     view_set_input_callback(nfc_emv->view, nfc_emv_input); |     view_set_input_callback(nfc_emv->view, nfc_emv_input); | ||||||
|  |     view_set_custom_callback(nfc_emv->view, nfc_emv_custom); | ||||||
|     view_set_enter_callback(nfc_emv->view, nfc_emv_enter); |     view_set_enter_callback(nfc_emv->view, nfc_emv_enter); | ||||||
|     view_set_exit_callback(nfc_emv->view, nfc_emv_exit); |     view_set_exit_callback(nfc_emv->view, nfc_emv_exit); | ||||||
|     view_set_previous_callback(nfc_emv->view, nfc_emv_back); |  | ||||||
| 
 | 
 | ||||||
|     return nfc_emv; |     return nfc_emv; | ||||||
| } | } | ||||||
| @ -1,7 +1,7 @@ | |||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <gui/view.h> | #include <gui/view.h> | ||||||
| #include "nfc_types.h" | #include "../nfc_types.h" | ||||||
| 
 | 
 | ||||||
| typedef struct NfcEmv NfcEmv; | typedef struct NfcEmv NfcEmv; | ||||||
| 
 | 
 | ||||||
| @ -10,5 +10,3 @@ NfcEmv* nfc_emv_alloc(NfcCommon* nfc_common); | |||||||
| void nfc_emv_free(NfcEmv* nfc_emv); | void nfc_emv_free(NfcEmv* nfc_emv); | ||||||
| 
 | 
 | ||||||
| View* nfc_emv_get_view(NfcEmv* nfc_emv); | View* nfc_emv_get_view(NfcEmv* nfc_emv); | ||||||
| 
 |  | ||||||
| void nfc_emv_view_dispatcher_callback(NfcEmv* nfc_emv, NfcMessage* message); |  | ||||||
| @ -1,11 +1,11 @@ | |||||||
| #include "nfc_mifare_ul.h" | #include "nfc_mifare_ul.h" | ||||||
| 
 | 
 | ||||||
| #include "nfc_i.h" |  | ||||||
| #include "nfc_types.h" |  | ||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include <api-hal.h> | #include <api-hal.h> | ||||||
| #include <input/input.h> | #include <input/input.h> | ||||||
| 
 | 
 | ||||||
|  | #include "../nfc_i.h" | ||||||
|  | 
 | ||||||
| struct NfcMifareUl { | struct NfcMifareUl { | ||||||
|     NfcCommon* nfc_common; |     NfcCommon* nfc_common; | ||||||
|     View* view; |     View* view; | ||||||
| @ -85,24 +85,24 @@ void nfc_mifare_ul_worker_callback(void* context) { | |||||||
|         nfc_mifare_ul->nfc_common->view_dispatcher, NfcEventMifareUl); |         nfc_mifare_ul->nfc_common->view_dispatcher, NfcEventMifareUl); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nfc_mifare_ul_view_dispatcher_callback(NfcMifareUl* nfc_mifare_ul, NfcMessage* message) { | bool nfc_mifare_ul_custom(uint32_t event, void* context) { | ||||||
|     furi_assert(nfc_mifare_ul); |     furi_assert(context); | ||||||
|     furi_assert(message); | 
 | ||||||
|  |     NfcMifareUl* nfc_mifare_ul = (NfcMifareUl*)context; | ||||||
|  |     if(event == NfcEventMifareUl) { | ||||||
|  |         NfcMifareUlData* data = (NfcMifareUlData*)&nfc_mifare_ul->nfc_common->worker_result; | ||||||
| 
 | 
 | ||||||
|     if(message->found) { |  | ||||||
|         with_view_model( |         with_view_model( | ||||||
|             nfc_mifare_ul->view, (NfcMifareUlModel * model) { |             nfc_mifare_ul->view, (NfcMifareUlModel * model) { | ||||||
|                 model->found = true; |                 model->found = true; | ||||||
|                 model->nfc_mf_ul_data = message->nfc_mifare_ul_data; |                 model->nfc_mf_ul_data = *data; | ||||||
|                 return true; |  | ||||||
|             }); |  | ||||||
|     } else { |  | ||||||
|         with_view_model( |  | ||||||
|             nfc_mifare_ul->view, (NfcMifareUlModel * model) { |  | ||||||
|                 model->found = false; |  | ||||||
|                 return true; |                 return true; | ||||||
|             }); |             }); | ||||||
|  |         // TODO add and configure next view model
 | ||||||
|  |         return true; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nfc_mifare_ul_enter(void* context) { | void nfc_mifare_ul_enter(void* context) { | ||||||
| @ -117,6 +117,7 @@ void nfc_mifare_ul_enter(void* context) { | |||||||
|     nfc_worker_start( |     nfc_worker_start( | ||||||
|         nfc_mifare_ul->nfc_common->worker, |         nfc_mifare_ul->nfc_common->worker, | ||||||
|         NfcWorkerStateReadMfUltralight, |         NfcWorkerStateReadMfUltralight, | ||||||
|  |         &nfc_mifare_ul->nfc_common->worker_result, | ||||||
|         nfc_mifare_ul_worker_callback, |         nfc_mifare_ul_worker_callback, | ||||||
|         nfc_mifare_ul); |         nfc_mifare_ul); | ||||||
| } | } | ||||||
| @ -128,10 +129,6 @@ void nfc_mifare_ul_exit(void* context) { | |||||||
|     nfc_worker_stop(nfc_mifare_ul->nfc_common->worker); |     nfc_worker_stop(nfc_mifare_ul->nfc_common->worker); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint32_t nfc_mifare_ul_back(void* context) { |  | ||||||
|     return NfcViewMenu; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| NfcMifareUl* nfc_mifare_ul_alloc(NfcCommon* nfc_common) { | NfcMifareUl* nfc_mifare_ul_alloc(NfcCommon* nfc_common) { | ||||||
|     furi_assert(nfc_common); |     furi_assert(nfc_common); | ||||||
| 
 | 
 | ||||||
| @ -144,9 +141,9 @@ NfcMifareUl* nfc_mifare_ul_alloc(NfcCommon* nfc_common) { | |||||||
|     view_set_context(nfc_mifare_ul->view, nfc_mifare_ul); |     view_set_context(nfc_mifare_ul->view, nfc_mifare_ul); | ||||||
|     view_set_draw_callback(nfc_mifare_ul->view, (ViewDrawCallback)nfc_mifare_ul_draw); |     view_set_draw_callback(nfc_mifare_ul->view, (ViewDrawCallback)nfc_mifare_ul_draw); | ||||||
|     view_set_input_callback(nfc_mifare_ul->view, nfc_mifare_ul_input); |     view_set_input_callback(nfc_mifare_ul->view, nfc_mifare_ul_input); | ||||||
|  |     view_set_custom_callback(nfc_mifare_ul->view, nfc_mifare_ul_custom); | ||||||
|     view_set_enter_callback(nfc_mifare_ul->view, nfc_mifare_ul_enter); |     view_set_enter_callback(nfc_mifare_ul->view, nfc_mifare_ul_enter); | ||||||
|     view_set_exit_callback(nfc_mifare_ul->view, nfc_mifare_ul_exit); |     view_set_exit_callback(nfc_mifare_ul->view, nfc_mifare_ul_exit); | ||||||
|     view_set_previous_callback(nfc_mifare_ul->view, nfc_mifare_ul_back); |  | ||||||
| 
 | 
 | ||||||
|     return nfc_mifare_ul; |     return nfc_mifare_ul; | ||||||
| } | } | ||||||
| @ -1,7 +1,7 @@ | |||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <gui/view.h> | #include <gui/view.h> | ||||||
| #include "nfc_types.h" | #include "../nfc_types.h" | ||||||
| 
 | 
 | ||||||
| typedef struct NfcMifareUl NfcMifareUl; | typedef struct NfcMifareUl NfcMifareUl; | ||||||
| 
 | 
 | ||||||
| @ -10,5 +10,3 @@ NfcMifareUl* nfc_mifare_ul_alloc(NfcCommon* nfc_common); | |||||||
| void nfc_mifare_ul_free(NfcMifareUl* nfc_mifare_ul); | void nfc_mifare_ul_free(NfcMifareUl* nfc_mifare_ul); | ||||||
| 
 | 
 | ||||||
| View* nfc_mifare_ul_get_view(NfcMifareUl* nfc_mifare_ul); | View* nfc_mifare_ul_get_view(NfcMifareUl* nfc_mifare_ul); | ||||||
| 
 |  | ||||||
| void nfc_mifare_ul_view_dispatcher_callback(NfcMifareUl* nfc_mifare_ul, NfcMessage* message); |  | ||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -3,148 +3,150 @@ | |||||||
| #include <gui/icon.h> | #include <gui/icon.h> | ||||||
| 
 | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
| 	A_FX_Sitting_40x27, |  | ||||||
| 	A_MDIB_32x32, |  | ||||||
| 	A_MDI_32x32, |  | ||||||
| 	A_MDWLB_32x32, |  | ||||||
| 	A_MDWL_32x32, |  | ||||||
| 	A_MDWRB_32x32, |  | ||||||
| 	A_MDWR_32x32, |  | ||||||
| 	A_WatchingTV_128x64, |  | ||||||
| 	A_Wink_128x64, |  | ||||||
| 	I_125_10px, |  | ||||||
| 	I_ble_10px, |  | ||||||
| 	I_dir_10px, |  | ||||||
| 	I_ibutt_10px, |  | ||||||
| 	I_ir_10px, |  | ||||||
| 	I_Nfc_10px, |  | ||||||
| 	I_sub1_10px, |  | ||||||
| 	I_unknown_10px, |  | ||||||
| 	I_ButtonCenter_7x7, |  | ||||||
| 	I_ButtonLeftSmall_3x5, |  | ||||||
| 	I_ButtonLeft_4x7, |  | ||||||
| 	I_ButtonRightSmall_3x5, |  | ||||||
| 	I_ButtonRight_4x7, |  | ||||||
| 	I_Empty_1x1, |  | ||||||
| 	I_BigBurger_24x24, |  | ||||||
| 	I_BigGames_24x24, |  | ||||||
| 	I_BigProfile_24x24, |  | ||||||
| 	I_DolphinFirstStart0_70x53, |  | ||||||
| 	I_DolphinFirstStart1_59x53, |  | ||||||
| 	I_DolphinFirstStart2_59x51, |  | ||||||
| 	I_DolphinFirstStart3_57x48, |  | ||||||
| 	I_DolphinFirstStart4_67x53, |  | ||||||
| 	I_DolphinFirstStart5_45x53, |  | ||||||
| 	I_DolphinFirstStart6_58x54, |  | ||||||
| 	I_DolphinFirstStart7_61x51, |  | ||||||
| 	I_DolphinFirstStart8_56x51, |  | ||||||
| 	I_DolphinOkay_41x43, |  | ||||||
| 	I_Flipper_young_80x60, |  | ||||||
| 	I_FX_Bang_32x6, |  | ||||||
| 	I_FX_SittingB_40x27, |  | ||||||
| 	I_DolphinExcited_64x63, |  | ||||||
| 	I_DolphinMafia_115x62, |  | ||||||
| 	I_DolphinNice_96x59, |  | ||||||
| 	I_DolphinWait_61x59, |  | ||||||
| 	I_iButtonDolphinSuccess_109x60, |  | ||||||
| 	I_iButtonDolphinVerySuccess_108x52, |  | ||||||
| 	I_iButtonKey_49x44, |  | ||||||
| 	I_DoorLeft_70x55, |  | ||||||
| 	I_DoorLeft_8x56, |  | ||||||
| 	I_DoorLocked_10x56, |  | ||||||
| 	I_DoorRight_70x55, |  | ||||||
| 	I_DoorRight_8x56, |  | ||||||
| 	I_LockPopup_100x49, |  | ||||||
| 	I_PassportBottom_128x17, |  | ||||||
| 	I_PassportLeft_6x47, |  | ||||||
| 	I_Back_15x10, |  | ||||||
| 	I_Down_25x27, |  | ||||||
| 	I_Down_hvr_25x27, |  | ||||||
| 	I_Fill_marker_7x7, |  | ||||||
| 	I_IrdaArrowDown_4x8, |  | ||||||
| 	I_IrdaArrowUp_4x8, |  | ||||||
| 	I_IrdaLearnShort_128x31, |  | ||||||
| 	I_IrdaLearn_128x64, |  | ||||||
| 	I_IrdaSendShort_128x34, |  | ||||||
| 	I_IrdaSend_128x64, |  | ||||||
| 	I_Mute_25x27, |  | ||||||
| 	I_Mute_hvr_25x27, |  | ||||||
| 	I_Power_25x27, |  | ||||||
| 	I_Power_hvr_25x27, |  | ||||||
| 	I_Up_25x27, |  | ||||||
| 	I_Up_hvr_25x27, |  | ||||||
| 	I_Vol_down_25x27, |  | ||||||
| 	I_Vol_down_hvr_25x27, |  | ||||||
| 	I_Vol_up_25x27, |  | ||||||
| 	I_Vol_up_hvr_25x27, |  | ||||||
| 	I_KeyBackspaceSelected_16x9, | 	I_KeyBackspaceSelected_16x9, | ||||||
| 	I_KeyBackspace_16x9, |  | ||||||
| 	I_KeySaveSelected_24x11, |  | ||||||
| 	I_KeySave_24x11, | 	I_KeySave_24x11, | ||||||
| 	A_125khz_14, | 	I_KeySaveSelected_24x11, | ||||||
| 	A_Bluetooth_14, | 	I_KeyBackspace_16x9, | ||||||
| 	A_FileManager_14, | 	I_Battery_26x8, | ||||||
| 	A_Games_14, | 	I_PlaceholderL_11x13, | ||||||
| 	A_GPIO_14, | 	I_Bluetooth_5x8, | ||||||
| 	A_iButton_14, | 	I_BadUsb_9x8, | ||||||
| 	A_Infrared_14, | 	I_PlaceholderR_30x13, | ||||||
| 	A_NFC_14, | 	I_USBConnected_15x8, | ||||||
| 	A_Passport_14, | 	I_Battery_19x8, | ||||||
| 	A_Plugins_14, | 	I_Lock_8x8, | ||||||
| 	A_Power_14, |  | ||||||
| 	A_Settings_14, |  | ||||||
| 	A_Sub1ghz_14, |  | ||||||
| 	A_Tamagotchi_14, |  | ||||||
| 	A_U2F_14, |  | ||||||
| 	I_passport_bad1_43x45, |  | ||||||
| 	I_passport_bad2_43x45, |  | ||||||
| 	I_passport_bad3_43x45, |  | ||||||
| 	I_passport_happy1_43x45, |  | ||||||
| 	I_passport_happy2_43x45, |  | ||||||
| 	I_passport_happy3_43x45, |  | ||||||
| 	I_passport_okay1_43x45, |  | ||||||
| 	I_passport_okay2_43x45, |  | ||||||
| 	I_passport_okay3_43x45, |  | ||||||
| 	I_BatteryBody_52x28, |  | ||||||
| 	I_Battery_16x16, |  | ||||||
| 	I_FaceCharging_29x14, |  | ||||||
| 	I_FaceConfused_29x14, |  | ||||||
| 	I_FaceNopower_29x14, |  | ||||||
| 	I_FaceNormal_29x14, |  | ||||||
| 	I_Health_16x16, |  | ||||||
| 	I_Temperature_16x16, |  | ||||||
| 	I_Voltage_16x16, |  | ||||||
| 	I_RFIDBigChip_37x36, |  | ||||||
| 	I_RFIDDolphinReceive_98x60, |  | ||||||
| 	I_RFIDDolphinSend_98x60, |  | ||||||
| 	I_RFIDDolphinSuccess_108x57, |  | ||||||
| 	I_Home_painting_17x20, |  | ||||||
| 	I_PC_22x29, |  | ||||||
| 	I_Sofa_40x13, |  | ||||||
| 	I_TV_20x20, |  | ||||||
| 	I_TV_20x24, |  | ||||||
| 	I_WalkL1_32x32, |  | ||||||
| 	I_WalkL2_32x32, |  | ||||||
| 	I_WalkLB1_32x32, |  | ||||||
| 	I_WalkLB2_32x32, |  | ||||||
| 	I_WalkR1_32x32, |  | ||||||
| 	I_WalkR2_32x32, |  | ||||||
| 	I_WalkRB1_32x32, |  | ||||||
| 	I_WalkRB2_32x32, |  | ||||||
| 	I_SDError_43x35, |  | ||||||
| 	I_SDQuestion_35x43, |  | ||||||
| 	I_Background_128x11, | 	I_Background_128x11, | ||||||
| 	I_Background_128x8, | 	I_Background_128x8, | ||||||
| 	I_BadUsb_9x8, |  | ||||||
| 	I_Battery_19x8, |  | ||||||
| 	I_Battery_26x8, |  | ||||||
| 	I_Bluetooth_5x8, |  | ||||||
| 	I_Lock_8x8, |  | ||||||
| 	I_PlaceholderL_11x13, |  | ||||||
| 	I_PlaceholderR_30x13, |  | ||||||
| 	I_SDcardFail_11x8, | 	I_SDcardFail_11x8, | ||||||
| 	I_SDcardMounted_11x8, | 	I_SDcardMounted_11x8, | ||||||
| 	I_USBConnected_15x8, | 	I_Nfc_10px, | ||||||
|  | 	I_ir_10px, | ||||||
|  | 	I_ble_10px, | ||||||
|  | 	I_sub1_10px, | ||||||
|  | 	I_dir_10px, | ||||||
|  | 	I_unknown_10px, | ||||||
|  | 	I_ibutt_10px, | ||||||
|  | 	I_125_10px, | ||||||
|  | 	A_iButton_14, | ||||||
|  | 	A_Plugins_14, | ||||||
|  | 	A_Bluetooth_14, | ||||||
|  | 	A_Games_14, | ||||||
|  | 	A_Infrared_14, | ||||||
|  | 	A_NFC_14, | ||||||
|  | 	A_FileManager_14, | ||||||
|  | 	A_Passport_14, | ||||||
|  | 	A_Settings_14, | ||||||
|  | 	A_Power_14, | ||||||
|  | 	A_125khz_14, | ||||||
|  | 	A_GPIO_14, | ||||||
|  | 	A_Tamagotchi_14, | ||||||
|  | 	A_U2F_14, | ||||||
|  | 	A_Sub1ghz_14, | ||||||
|  | 	I_ButtonLeft_4x7, | ||||||
|  | 	I_ButtonRight_4x7, | ||||||
|  | 	I_ButtonRightSmall_3x5, | ||||||
|  | 	I_Empty_1x1, | ||||||
|  | 	I_ButtonCenter_7x7, | ||||||
|  | 	I_ButtonLeftSmall_3x5, | ||||||
|  | 	I_Vol_up_25x27, | ||||||
|  | 	I_Fill_marker_7x7, | ||||||
|  | 	I_IrdaArrowUp_4x8, | ||||||
|  | 	I_Down_hvr_25x27, | ||||||
|  | 	I_Vol_up_hvr_25x27, | ||||||
|  | 	I_Power_25x27, | ||||||
|  | 	I_Vol_down_25x27, | ||||||
|  | 	I_IrdaSend_128x64, | ||||||
|  | 	I_Up_hvr_25x27, | ||||||
|  | 	I_Back_15x10, | ||||||
|  | 	I_IrdaSendShort_128x34, | ||||||
|  | 	I_Mute_hvr_25x27, | ||||||
|  | 	I_IrdaLearnShort_128x31, | ||||||
|  | 	I_Down_25x27, | ||||||
|  | 	I_Up_25x27, | ||||||
|  | 	I_Mute_25x27, | ||||||
|  | 	I_Vol_down_hvr_25x27, | ||||||
|  | 	I_Power_hvr_25x27, | ||||||
|  | 	I_IrdaLearn_128x64, | ||||||
|  | 	I_IrdaArrowDown_4x8, | ||||||
|  | 	A_MDWRB_32x32, | ||||||
|  | 	A_MDWL_32x32, | ||||||
|  | 	A_WatchingTV_128x64, | ||||||
|  | 	A_MDWR_32x32, | ||||||
|  | 	A_FX_Sitting_40x27, | ||||||
|  | 	A_MDI_32x32, | ||||||
|  | 	A_Wink_128x64, | ||||||
|  | 	A_MDIB_32x32, | ||||||
|  | 	A_MDWLB_32x32, | ||||||
|  | 	I_RFIDBigChip_37x36, | ||||||
|  | 	I_RFIDDolphinReceive_98x60, | ||||||
|  | 	I_RFIDDolphinSuccess_108x57, | ||||||
|  | 	I_RFIDDolphinSend_98x60, | ||||||
|  | 	I_DoorRight_70x55, | ||||||
|  | 	I_DoorLocked_10x56, | ||||||
|  | 	I_DoorLeft_70x55, | ||||||
|  | 	I_PassportLeft_6x47, | ||||||
|  | 	I_DoorRight_8x56, | ||||||
|  | 	I_DoorLeft_8x56, | ||||||
|  | 	I_LockPopup_100x49, | ||||||
|  | 	I_PassportBottom_128x17, | ||||||
|  | 	I_Medium_chip_22x21, | ||||||
|  | 	I_EMV_Chip_14x11, | ||||||
|  | 	I_iButtonDolphinVerySuccess_108x52, | ||||||
|  | 	I_DolphinMafia_115x62, | ||||||
|  | 	I_iButtonDolphinSuccess_109x60, | ||||||
|  | 	I_DolphinExcited_64x63, | ||||||
|  | 	I_DolphinNice_96x59, | ||||||
|  | 	I_iButtonKey_49x44, | ||||||
|  | 	I_DolphinWait_61x59, | ||||||
|  | 	I_passport_bad2_43x45, | ||||||
|  | 	I_passport_okay1_43x45, | ||||||
|  | 	I_passport_happy3_43x45, | ||||||
|  | 	I_passport_bad1_43x45, | ||||||
|  | 	I_passport_happy2_43x45, | ||||||
|  | 	I_passport_okay2_43x45, | ||||||
|  | 	I_passport_happy1_43x45, | ||||||
|  | 	I_passport_okay3_43x45, | ||||||
|  | 	I_passport_bad3_43x45, | ||||||
|  | 	I_SDQuestion_35x43, | ||||||
|  | 	I_SDError_43x35, | ||||||
|  | 	I_WalkLB1_32x32, | ||||||
|  | 	I_PC_22x29, | ||||||
|  | 	I_Home_painting_17x20, | ||||||
|  | 	I_Sofa_40x13, | ||||||
|  | 	I_WalkRB1_32x32, | ||||||
|  | 	I_WalkL1_32x32, | ||||||
|  | 	I_WalkR1_32x32, | ||||||
|  | 	I_WalkL2_32x32, | ||||||
|  | 	I_WalkR2_32x32, | ||||||
|  | 	I_TV_20x24, | ||||||
|  | 	I_WalkLB2_32x32, | ||||||
|  | 	I_TV_20x20, | ||||||
|  | 	I_WalkRB2_32x32, | ||||||
|  | 	I_Health_16x16, | ||||||
|  | 	I_FaceNopower_29x14, | ||||||
|  | 	I_Battery_16x16, | ||||||
|  | 	I_BatteryBody_52x28, | ||||||
|  | 	I_FaceConfused_29x14, | ||||||
|  | 	I_FaceCharging_29x14, | ||||||
|  | 	I_FaceNormal_29x14, | ||||||
|  | 	I_Voltage_16x16, | ||||||
|  | 	I_Temperature_16x16, | ||||||
|  | 	I_DolphinOkay_41x43, | ||||||
|  | 	I_DolphinFirstStart7_61x51, | ||||||
|  | 	I_DolphinFirstStart4_67x53, | ||||||
|  | 	I_DolphinFirstStart3_57x48, | ||||||
|  | 	I_FX_Bang_32x6, | ||||||
|  | 	I_Flipper_young_80x60, | ||||||
|  | 	I_DolphinFirstStart0_70x53, | ||||||
|  | 	I_DolphinFirstStart2_59x51, | ||||||
|  | 	I_DolphinFirstStart6_58x54, | ||||||
|  | 	I_FX_SittingB_40x27, | ||||||
|  | 	I_BigProfile_24x24, | ||||||
|  | 	I_DolphinFirstStart5_45x53, | ||||||
|  | 	I_BigGames_24x24, | ||||||
|  | 	I_DolphinFirstStart8_56x51, | ||||||
|  | 	I_BigBurger_24x24, | ||||||
|  | 	I_DolphinFirstStart1_59x53, | ||||||
| } IconName; | } IconName; | ||||||
| 
 | 
 | ||||||
| Icon * assets_icons_get(IconName name); | Icon * assets_icons_get(IconName name); | ||||||
|  | |||||||
							
								
								
									
										
											BIN
										
									
								
								assets/icons/NFC/EMV_Chip_14x11.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/icons/NFC/EMV_Chip_14x11.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 3.6 KiB | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/NFC/Medium-chip-22x21.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/icons/NFC/Medium-chip-22x21.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 3.7 KiB | 
| @ -9,11 +9,7 @@ | |||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| /** Nfc emulation parameters */ | #define API_HAL_NFC_UID_MAX_LEN 10 | ||||||
| typedef enum { |  | ||||||
|     ApiHalNfcEmulateParamsMifare, |  | ||||||
|     ApiHalNfcEmulateParamsEMV, |  | ||||||
| } ApiHalNfcEmulateParams; |  | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Init nfc |  * Init nfc | ||||||
| @ -53,7 +49,7 @@ bool api_hal_nfc_detect(rfalNfcDevice** dev_list, uint8_t* dev_cnt, uint32_t tim | |||||||
| /**
 | /**
 | ||||||
|  * NFC listen |  * NFC listen | ||||||
|  */ |  */ | ||||||
| bool api_hal_nfc_listen(ApiHalNfcEmulateParams params, uint32_t timeout); | bool api_hal_nfc_listen(uint8_t* uid, uint8_t uid_len, uint8_t* atqa, uint8_t sak, uint32_t timeout); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * NFC data exchange |  * NFC data exchange | ||||||
|  | |||||||
| @ -3,53 +3,6 @@ | |||||||
| 
 | 
 | ||||||
| static const uint32_t clocks_in_ms = 64 * 1000; | static const uint32_t clocks_in_ms = 64 * 1000; | ||||||
| 
 | 
 | ||||||
| static const rfalNfcDiscoverParam api_hal_nfc_emulate_params_mifare = { |  | ||||||
|     .compMode = RFAL_COMPLIANCE_MODE_NFC, |  | ||||||
|     .techs2Find = RFAL_NFC_LISTEN_TECH_A, |  | ||||||
|     .totalDuration = 1000, |  | ||||||
|     .devLimit = 1, |  | ||||||
|     .wakeupEnabled = false, |  | ||||||
|     .wakeupConfigDefault = true, |  | ||||||
|     .nfcfBR = RFAL_BR_212, |  | ||||||
|     .ap2pBR = RFAL_BR_424, |  | ||||||
|     .maxBR = RFAL_BR_KEEP, |  | ||||||
|     .GBLen = RFAL_NFCDEP_GB_MAX_LEN, |  | ||||||
|     .notifyCb = NULL, |  | ||||||
|     .lmConfigPA.nfcidLen = RFAL_LM_NFCID_LEN_07, |  | ||||||
|     .lmConfigPA.nfcid[0] = 0X36, |  | ||||||
|     .lmConfigPA.nfcid[1] = 0x9C, |  | ||||||
|     .lmConfigPA.nfcid[2] = 0xE7, |  | ||||||
|     .lmConfigPA.nfcid[3] = 0xB1, |  | ||||||
|     .lmConfigPA.nfcid[4] = 0x0A, |  | ||||||
|     .lmConfigPA.nfcid[5] = 0xC1, |  | ||||||
|     .lmConfigPA.nfcid[6] = 0x34, |  | ||||||
|     .lmConfigPA.SENS_RES[0] = 0x44, |  | ||||||
|     .lmConfigPA.SENS_RES[1] = 0x00, |  | ||||||
|     .lmConfigPA.SEL_RES = 0x00, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| static const rfalNfcDiscoverParam api_hal_nfc_emulate_params_emv = { |  | ||||||
|     .compMode = RFAL_COMPLIANCE_MODE_EMV, |  | ||||||
|     .techs2Find = RFAL_NFC_LISTEN_TECH_A, |  | ||||||
|     .totalDuration = 1000, |  | ||||||
|     .devLimit = 1, |  | ||||||
|     .wakeupEnabled = false, |  | ||||||
|     .wakeupConfigDefault = true, |  | ||||||
|     .nfcfBR = RFAL_BR_212, |  | ||||||
|     .ap2pBR = RFAL_BR_424, |  | ||||||
|     .maxBR = RFAL_BR_KEEP, |  | ||||||
|     .GBLen = RFAL_NFCDEP_GB_MAX_LEN, |  | ||||||
|     .notifyCb = NULL, |  | ||||||
|     .lmConfigPA.nfcidLen = RFAL_LM_NFCID_LEN_04, |  | ||||||
|     .lmConfigPA.nfcid[0] = 0XCF, |  | ||||||
|     .lmConfigPA.nfcid[1] = 0x72, |  | ||||||
|     .lmConfigPA.nfcid[2] = 0xD4, |  | ||||||
|     .lmConfigPA.nfcid[3] = 0x40, |  | ||||||
|     .lmConfigPA.SENS_RES[0] = 0x04, |  | ||||||
|     .lmConfigPA.SENS_RES[1] = 0x00, |  | ||||||
|     .lmConfigPA.SEL_RES = 0x20, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| ReturnCode api_hal_nfc_init() { | ReturnCode api_hal_nfc_init() { | ||||||
|     // Check if Nfc worker was started
 |     // Check if Nfc worker was started
 | ||||||
|     rfalNfcState state = rfalNfcGetState(); |     rfalNfcState state = rfalNfcGetState(); | ||||||
| @ -135,9 +88,7 @@ bool api_hal_nfc_detect(rfalNfcDevice **dev_list, uint8_t* dev_cnt, uint32_t tim | |||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool api_hal_nfc_listen(ApiHalNfcEmulateParams params, uint32_t timeout) { | bool api_hal_nfc_listen(uint8_t* uid, uint8_t uid_len, uint8_t* atqa, uint8_t sak, uint32_t timeout) { | ||||||
|     api_hal_nfc_exit_sleep(); |  | ||||||
| 
 |  | ||||||
|     rfalNfcState state = rfalNfcGetState(); |     rfalNfcState state = rfalNfcGetState(); | ||||||
|     if(state == RFAL_NFC_STATE_NOTINIT) { |     if(state == RFAL_NFC_STATE_NOTINIT) { | ||||||
|         rfalNfcInitialize(); |         rfalNfcInitialize(); | ||||||
| @ -145,11 +96,25 @@ bool api_hal_nfc_listen(ApiHalNfcEmulateParams params, uint32_t timeout) { | |||||||
|         rfalNfcDeactivate(false); |         rfalNfcDeactivate(false); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if(params == ApiHalNfcEmulateParamsMifare) { |     rfalNfcDiscoverParam params = { | ||||||
|         rfalNfcDiscover(&api_hal_nfc_emulate_params_mifare); |         .compMode = RFAL_COMPLIANCE_MODE_NFC, | ||||||
|     } else if(params == ApiHalNfcEmulateParamsEMV) { |         .techs2Find = RFAL_NFC_LISTEN_TECH_A, | ||||||
|         rfalNfcDiscover(&api_hal_nfc_emulate_params_emv); |         .totalDuration = 1000, | ||||||
|     } |         .devLimit = 1, | ||||||
|  |         .wakeupEnabled = false, | ||||||
|  |         .wakeupConfigDefault = true, | ||||||
|  |         .nfcfBR = RFAL_BR_212, | ||||||
|  |         .ap2pBR = RFAL_BR_424, | ||||||
|  |         .maxBR = RFAL_BR_KEEP, | ||||||
|  |         .GBLen = RFAL_NFCDEP_GB_MAX_LEN, | ||||||
|  |         .notifyCb = NULL, | ||||||
|  |     }; | ||||||
|  |     params.lmConfigPA.nfcidLen = uid_len; | ||||||
|  |     memcpy(params.lmConfigPA.nfcid, uid, uid_len); | ||||||
|  |     params.lmConfigPA.SENS_RES[0] = atqa[0]; | ||||||
|  |     params.lmConfigPA.SENS_RES[1] = atqa[1]; | ||||||
|  |     params.lmConfigPA.SEL_RES = sak; | ||||||
|  |     rfalNfcDiscover(¶ms); | ||||||
| 
 | 
 | ||||||
|     uint32_t start = DWT->CYCCNT; |     uint32_t start = DWT->CYCCNT; | ||||||
|     while(state != RFAL_NFC_STATE_ACTIVATED) { |     while(state != RFAL_NFC_STATE_ACTIVATED) { | ||||||
|  | |||||||
| @ -3,53 +3,6 @@ | |||||||
| 
 | 
 | ||||||
| static const uint32_t clocks_in_ms = 64 * 1000; | static const uint32_t clocks_in_ms = 64 * 1000; | ||||||
| 
 | 
 | ||||||
| static const rfalNfcDiscoverParam api_hal_nfc_emulate_params_mifare = { |  | ||||||
|     .compMode = RFAL_COMPLIANCE_MODE_NFC, |  | ||||||
|     .techs2Find = RFAL_NFC_LISTEN_TECH_A, |  | ||||||
|     .totalDuration = 1000, |  | ||||||
|     .devLimit = 1, |  | ||||||
|     .wakeupEnabled = false, |  | ||||||
|     .wakeupConfigDefault = true, |  | ||||||
|     .nfcfBR = RFAL_BR_212, |  | ||||||
|     .ap2pBR = RFAL_BR_424, |  | ||||||
|     .maxBR = RFAL_BR_KEEP, |  | ||||||
|     .GBLen = RFAL_NFCDEP_GB_MAX_LEN, |  | ||||||
|     .notifyCb = NULL, |  | ||||||
|     .lmConfigPA.nfcidLen = RFAL_LM_NFCID_LEN_07, |  | ||||||
|     .lmConfigPA.nfcid[0] = 0X36, |  | ||||||
|     .lmConfigPA.nfcid[1] = 0x9C, |  | ||||||
|     .lmConfigPA.nfcid[2] = 0xE7, |  | ||||||
|     .lmConfigPA.nfcid[3] = 0xB1, |  | ||||||
|     .lmConfigPA.nfcid[4] = 0x0A, |  | ||||||
|     .lmConfigPA.nfcid[5] = 0xC1, |  | ||||||
|     .lmConfigPA.nfcid[6] = 0x34, |  | ||||||
|     .lmConfigPA.SENS_RES[0] = 0x44, |  | ||||||
|     .lmConfigPA.SENS_RES[1] = 0x00, |  | ||||||
|     .lmConfigPA.SEL_RES = 0x00, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| static const rfalNfcDiscoverParam api_hal_nfc_emulate_params_emv = { |  | ||||||
|     .compMode = RFAL_COMPLIANCE_MODE_EMV, |  | ||||||
|     .techs2Find = RFAL_NFC_LISTEN_TECH_A, |  | ||||||
|     .totalDuration = 1000, |  | ||||||
|     .devLimit = 1, |  | ||||||
|     .wakeupEnabled = false, |  | ||||||
|     .wakeupConfigDefault = true, |  | ||||||
|     .nfcfBR = RFAL_BR_212, |  | ||||||
|     .ap2pBR = RFAL_BR_424, |  | ||||||
|     .maxBR = RFAL_BR_KEEP, |  | ||||||
|     .GBLen = RFAL_NFCDEP_GB_MAX_LEN, |  | ||||||
|     .notifyCb = NULL, |  | ||||||
|     .lmConfigPA.nfcidLen = RFAL_LM_NFCID_LEN_04, |  | ||||||
|     .lmConfigPA.nfcid[0] = 0XCF, |  | ||||||
|     .lmConfigPA.nfcid[1] = 0x72, |  | ||||||
|     .lmConfigPA.nfcid[2] = 0xD4, |  | ||||||
|     .lmConfigPA.nfcid[3] = 0x40, |  | ||||||
|     .lmConfigPA.SENS_RES[0] = 0x04, |  | ||||||
|     .lmConfigPA.SENS_RES[1] = 0x00, |  | ||||||
|     .lmConfigPA.SEL_RES = 0x20, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| ReturnCode api_hal_nfc_init() { | ReturnCode api_hal_nfc_init() { | ||||||
|     // Check if Nfc worker was started
 |     // Check if Nfc worker was started
 | ||||||
|     rfalNfcState state = rfalNfcGetState(); |     rfalNfcState state = rfalNfcGetState(); | ||||||
| @ -135,9 +88,7 @@ bool api_hal_nfc_detect(rfalNfcDevice **dev_list, uint8_t* dev_cnt, uint32_t tim | |||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool api_hal_nfc_listen(ApiHalNfcEmulateParams params, uint32_t timeout) { | bool api_hal_nfc_listen(uint8_t* uid, uint8_t uid_len, uint8_t* atqa, uint8_t sak, uint32_t timeout) { | ||||||
|     api_hal_nfc_exit_sleep(); |  | ||||||
| 
 |  | ||||||
|     rfalNfcState state = rfalNfcGetState(); |     rfalNfcState state = rfalNfcGetState(); | ||||||
|     if(state == RFAL_NFC_STATE_NOTINIT) { |     if(state == RFAL_NFC_STATE_NOTINIT) { | ||||||
|         rfalNfcInitialize(); |         rfalNfcInitialize(); | ||||||
| @ -145,11 +96,25 @@ bool api_hal_nfc_listen(ApiHalNfcEmulateParams params, uint32_t timeout) { | |||||||
|         rfalNfcDeactivate(false); |         rfalNfcDeactivate(false); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if(params == ApiHalNfcEmulateParamsMifare) { |     rfalNfcDiscoverParam params = { | ||||||
|         rfalNfcDiscover(&api_hal_nfc_emulate_params_mifare); |         .compMode = RFAL_COMPLIANCE_MODE_NFC, | ||||||
|     } else if(params == ApiHalNfcEmulateParamsEMV) { |         .techs2Find = RFAL_NFC_LISTEN_TECH_A, | ||||||
|         rfalNfcDiscover(&api_hal_nfc_emulate_params_emv); |         .totalDuration = 1000, | ||||||
|     } |         .devLimit = 1, | ||||||
|  |         .wakeupEnabled = false, | ||||||
|  |         .wakeupConfigDefault = true, | ||||||
|  |         .nfcfBR = RFAL_BR_212, | ||||||
|  |         .ap2pBR = RFAL_BR_424, | ||||||
|  |         .maxBR = RFAL_BR_KEEP, | ||||||
|  |         .GBLen = RFAL_NFCDEP_GB_MAX_LEN, | ||||||
|  |         .notifyCb = NULL, | ||||||
|  |     }; | ||||||
|  |     params.lmConfigPA.nfcidLen = uid_len; | ||||||
|  |     memcpy(params.lmConfigPA.nfcid, uid, uid_len); | ||||||
|  |     params.lmConfigPA.SENS_RES[0] = atqa[0]; | ||||||
|  |     params.lmConfigPA.SENS_RES[1] = atqa[1]; | ||||||
|  |     params.lmConfigPA.SEL_RES = sak; | ||||||
|  |     rfalNfcDiscover(¶ms); | ||||||
| 
 | 
 | ||||||
|     uint32_t start = DWT->CYCCNT; |     uint32_t start = DWT->CYCCNT; | ||||||
|     while(state != RFAL_NFC_STATE_ACTIVATED) { |     while(state != RFAL_NFC_STATE_ACTIVATED) { | ||||||
|  | |||||||
| @ -23,12 +23,15 @@ HAL_StatusTypeDef platformSpiTxRx(const uint8_t *txBuf, uint8_t *rxBuf, uint16_t | |||||||
| void platformProtectST25RComm(); | void platformProtectST25RComm(); | ||||||
| void platformUnprotectST25RComm(); | void platformUnprotectST25RComm(); | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| #define ST25R_SS_PIN NFC_CS_Pin | #define ST25R_SS_PIN NFC_CS_Pin | ||||||
| #define ST25R_SS_PORT NFC_CS_GPIO_Port | #define ST25R_SS_PORT NFC_CS_GPIO_Port | ||||||
| 
 | 
 | ||||||
| #define ST25R_INT_PIN NFC_IRQ_Pin | #define ST25R_INT_PIN NFC_IRQ_Pin | ||||||
| #define ST25R_INT_PORT NFC_IRQ_GPIO_Port | #define ST25R_INT_PORT NFC_IRQ_GPIO_Port | ||||||
| 
 | 
 | ||||||
|  | #define RFAL_ANALOG_CONFIG_CUSTOM              true       /*!< Enable/Disable RFAL custom analog configuration                           */ | ||||||
|  | 
 | ||||||
| #define RFAL_FEATURE_LISTEN_MODE               true       /*!< Enable/Disable RFAL support for Listen Mode                               */ | #define RFAL_FEATURE_LISTEN_MODE               true       /*!< Enable/Disable RFAL support for Listen Mode                               */ | ||||||
| #define RFAL_FEATURE_WAKEUP_MODE               true       /*!< Enable/Disable RFAL support for the Wake-Up mode                          */ | #define RFAL_FEATURE_WAKEUP_MODE               true       /*!< Enable/Disable RFAL support for the Wake-Up mode                          */ | ||||||
| #define RFAL_FEATURE_LOWPOWER_MODE             true       /*!< Enable/Disable RFAL support for the Low Power mode                        */ | #define RFAL_FEATURE_LOWPOWER_MODE             true       /*!< Enable/Disable RFAL support for the Low Power mode                        */ | ||||||
|  | |||||||
							
								
								
									
										309
									
								
								lib/ST25RFAL002/source/custom_analog_config.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										309
									
								
								lib/ST25RFAL002/source/custom_analog_config.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,309 @@ | |||||||
|  | #include "rfal_analogConfigTbl.h" | ||||||
|  | 
 | ||||||
|  | const uint8_t rfalAnalogConfigCustomSettings[] = { | ||||||
|  |     /****** Default Analog Configuration for Chip-Specific Reset ******/ | ||||||
|  |     MODE_ENTRY_16_REG( (RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_INIT) | ||||||
|  |                         , ST25R3916_REG_IO_CONF1, (ST25R3916_REG_IO_CONF1_out_cl_mask | ST25R3916_REG_IO_CONF1_lf_clk_off), 0x07                               /* Disable MCU_CLK */ | ||||||
|  |                         , ST25R3916_REG_IO_CONF2, (ST25R3916_REG_IO_CONF2_miso_pd1 | ST25R3916_REG_IO_CONF2_miso_pd2 ), 0x18                                   /* SPI Pull downs */ | ||||||
|  |                         // , ST25R3916_REG_IO_CONF2,  ST25R3916_REG_IO_CONF2_aat_en, ST25R3916_REG_IO_CONF2_aat_en                                                /* Enable AAT */
 | ||||||
|  |                         , ST25R3916_REG_TX_DRIVER, ST25R3916_REG_TX_DRIVER_d_res_mask, 0x00                                                                    /* Set RFO resistance Active Tx */ | ||||||
|  |                         , ST25R3916_REG_RES_AM_MOD, 0xFF, 0x80                                                                                                 /* Use minimum non-overlap */ | ||||||
|  |                         , ST25R3916_REG_FIELD_THRESHOLD_ACTV,   ST25R3916_REG_FIELD_THRESHOLD_ACTV_trg_mask, ST25R3916_REG_FIELD_THRESHOLD_ACTV_trg_105mV      /* Lower activation threshold (higher than deactivation)*/ | ||||||
|  |                         , ST25R3916_REG_FIELD_THRESHOLD_ACTV,   ST25R3916_REG_FIELD_THRESHOLD_ACTV_rfe_mask, ST25R3916_REG_FIELD_THRESHOLD_ACTV_rfe_105mV      /* Lower activation threshold (higher than deactivation)*/ | ||||||
|  |                         , ST25R3916_REG_FIELD_THRESHOLD_DEACTV, ST25R3916_REG_FIELD_THRESHOLD_DEACTV_trg_mask, ST25R3916_REG_FIELD_THRESHOLD_DEACTV_trg_75mV   /* Lower deactivation threshold */ | ||||||
|  |                         , ST25R3916_REG_FIELD_THRESHOLD_DEACTV, ST25R3916_REG_FIELD_THRESHOLD_DEACTV_rfe_mask, ST25R3916_REG_FIELD_THRESHOLD_DEACTV_rfe_75mV   /* Lower deactivation threshold */ | ||||||
|  |                         , ST25R3916_REG_AUX_MOD, ST25R3916_REG_AUX_MOD_lm_ext, 0x00                                                                            /* Disable External Load Modulation */ | ||||||
|  |                         , ST25R3916_REG_AUX_MOD, ST25R3916_REG_AUX_MOD_lm_dri, ST25R3916_REG_AUX_MOD_lm_dri                                                    /* Use internal Load Modulation */ | ||||||
|  |                         , ST25R3916_REG_PASSIVE_TARGET, ST25R3916_REG_PASSIVE_TARGET_fdel_mask, (5U<<ST25R3916_REG_PASSIVE_TARGET_fdel_shift)                  /* Adjust the FDT to be aligned with the bitgrid  */ | ||||||
|  |                         , ST25R3916_REG_PT_MOD, (ST25R3916_REG_PT_MOD_ptm_res_mask | ST25R3916_REG_PT_MOD_pt_res_mask), 0x5f                                   /* Reduce RFO resistance in Modulated state */ | ||||||
|  |                         , ST25R3916_REG_EMD_SUP_CONF, ST25R3916_REG_EMD_SUP_CONF_rx_start_emv, ST25R3916_REG_EMD_SUP_CONF_rx_start_emv_on                      /* Enable start on first 4 bits */ | ||||||
|  |                         , ST25R3916_REG_ANT_TUNE_A, 0xFF, 0x82                                                                                                 /* Set Antenna Tuning (Poller): ANTL */ | ||||||
|  |                         , ST25R3916_REG_ANT_TUNE_B, 0xFF, 0x82                                                                                                 /* Set Antenna Tuning (Poller): ANTL */ | ||||||
|  |                         , 0x84U, 0x10, 0x10                                                                                                                     /* Avoid chip internal overheat protection */ | ||||||
|  |                         ) | ||||||
|  |      | ||||||
|  |     /****** Default Analog Configuration for Chip-Specific Poll Common ******/ | ||||||
|  |     , MODE_ENTRY_9_REG( (RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_POLL_COMMON) | ||||||
|  |                         , ST25R3916_REG_MODE, ST25R3916_REG_MODE_tr_am  , ST25R3916_REG_MODE_tr_am_am                                           /* Use AM modulation */       | ||||||
|  |                         , ST25R3916_REG_TX_DRIVER, ST25R3916_REG_TX_DRIVER_am_mod_mask, ST25R3916_REG_TX_DRIVER_am_mod_12percent                /* Set Modulation index */ | ||||||
|  |                         , ST25R3916_REG_AUX_MOD, (ST25R3916_REG_AUX_MOD_dis_reg_am | ST25R3916_REG_AUX_MOD_res_am), 0x00                           /* Use AM via regulator */ | ||||||
|  |                         , ST25R3916_REG_ANT_TUNE_A, 0xFF, 0x82                                                                                  /* Set Antenna Tuning (Poller): ANTL */ | ||||||
|  |                         , ST25R3916_REG_ANT_TUNE_B, 0xFF, 0x82                                                                                  /* Set Antenna Tuning (Poller): ANTL */ | ||||||
|  |                         , ST25R3916_REG_OVERSHOOT_CONF1,  0xFF, 0x00                                                                            /* Disable Overshoot Protection  */ | ||||||
|  |                         , ST25R3916_REG_OVERSHOOT_CONF2,  0xFF, 0x00                                                                            /* Disable Overshoot Protection  */ | ||||||
|  |                         , ST25R3916_REG_UNDERSHOOT_CONF1, 0xFF, 0x00                                                                            /* Disable Undershoot Protection */ | ||||||
|  |                         , ST25R3916_REG_UNDERSHOOT_CONF2, 0xFF, 0x00                                                                            /* Disable Undershoot Protection */ | ||||||
|  |                         ) | ||||||
|  | 
 | ||||||
|  |                        | ||||||
|  |     /****** Default Analog Configuration for Poll NFC-A Rx Common ******/ | ||||||
|  |     , MODE_ENTRY_1_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX) | ||||||
|  |                       , ST25R3916_REG_AUX,  ST25R3916_REG_AUX_dis_corr, ST25R3916_REG_AUX_dis_corr_correlator                                   /* Use Correlator Receiver */ | ||||||
|  |                       ) | ||||||
|  |                        | ||||||
|  |     /****** Default Analog Configuration for Poll NFC-A Tx 106 ******/ | ||||||
|  |     , MODE_ENTRY_5_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA | RFAL_ANALOG_CONFIG_BITRATE_106 | RFAL_ANALOG_CONFIG_TX) | ||||||
|  |                       , ST25R3916_REG_MODE, ST25R3916_REG_MODE_tr_am, ST25R3916_REG_MODE_tr_am_ook                                              /* Use OOK */ | ||||||
|  |                       , ST25R3916_REG_OVERSHOOT_CONF1,  0xFF, 0x40                                                                              /* Set default Overshoot Protection */ | ||||||
|  |                       , ST25R3916_REG_OVERSHOOT_CONF2,  0xFF, 0x03                                                                              /* Set default Overshoot Protection */ | ||||||
|  |                       , ST25R3916_REG_UNDERSHOOT_CONF1, 0xFF, 0x40                                                                              /* Set default Undershoot Protection */ | ||||||
|  |                       , ST25R3916_REG_UNDERSHOOT_CONF2, 0xFF, 0x03                                                                              /* Set default Undershoot Protection */ | ||||||
|  |                       ) | ||||||
|  |                        | ||||||
|  |     /****** Default Analog Configuration for Poll NFC-A Rx 106 ******/ | ||||||
|  |     , MODE_ENTRY_6_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA | RFAL_ANALOG_CONFIG_BITRATE_106 | RFAL_ANALOG_CONFIG_RX) | ||||||
|  |                       , ST25R3916_REG_RX_CONF1,   0xFF, 0x08 | ||||||
|  |                       , ST25R3916_REG_RX_CONF2,   0xFF, 0x2D | ||||||
|  |                       , ST25R3916_REG_RX_CONF3,   0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_RX_CONF4,   0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF1, 0xFF, 0x51 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF2, 0xFF, 0x00 | ||||||
|  |                       ) | ||||||
|  | 
 | ||||||
|  |     /****** Default Analog Configuration for Poll NFC-A Tx 212 ******/ | ||||||
|  |     , MODE_ENTRY_7_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA | RFAL_ANALOG_CONFIG_BITRATE_212 | RFAL_ANALOG_CONFIG_TX) | ||||||
|  |                       , ST25R3916_REG_MODE, ST25R3916_REG_MODE_tr_am  , ST25R3916_REG_MODE_tr_am_am                                             /* Use AM modulation */ | ||||||
|  |                       , ST25R3916_REG_AUX_MOD, (ST25R3916_REG_AUX_MOD_dis_reg_am | ST25R3916_REG_AUX_MOD_res_am), 0x88                             /* Use Resistive AM */ | ||||||
|  |                       , ST25R3916_REG_RES_AM_MOD, ST25R3916_REG_RES_AM_MOD_md_res_mask, 0x7F                                      /* Set Resistive modulation */ | ||||||
|  |                       , ST25R3916_REG_OVERSHOOT_CONF1,  0xFF, 0x40                                                                              /* Set default Overshoot Protection  */ | ||||||
|  |                       , ST25R3916_REG_OVERSHOOT_CONF2,  0xFF, 0x03                                                                              /* Set default Overshoot Protection  */ | ||||||
|  |                       , ST25R3916_REG_UNDERSHOOT_CONF1, 0xFF, 0x40                                                                              /* Set default Undershoot Protection */ | ||||||
|  |                       , ST25R3916_REG_UNDERSHOOT_CONF2, 0xFF, 0x03                                                                              /* Set default Undershoot Protection */ | ||||||
|  |                       ) | ||||||
|  |                        | ||||||
|  |     /****** Default Analog Configuration for Poll NFC-A Rx 212 ******/ | ||||||
|  |     , MODE_ENTRY_6_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA | RFAL_ANALOG_CONFIG_BITRATE_212 | RFAL_ANALOG_CONFIG_RX) | ||||||
|  |                       , ST25R3916_REG_RX_CONF1,   0xFF, 0x02 | ||||||
|  |                       , ST25R3916_REG_RX_CONF2,   0xFF, 0x3D | ||||||
|  |                       , ST25R3916_REG_RX_CONF3,   0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_RX_CONF4,   0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF1, 0xFF, 0x14 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF2, 0xFF, 0x00 | ||||||
|  |                       ) | ||||||
|  |                        | ||||||
|  |     /****** Default Analog Configuration for Poll NFC-A Tx 424 ******/                       | ||||||
|  |     , MODE_ENTRY_7_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA | RFAL_ANALOG_CONFIG_BITRATE_424 | RFAL_ANALOG_CONFIG_TX) | ||||||
|  |                       , ST25R3916_REG_MODE, ST25R3916_REG_MODE_tr_am  , ST25R3916_REG_MODE_tr_am_am                                             /* Use AM modulation */ | ||||||
|  |                       , ST25R3916_REG_AUX_MOD, (ST25R3916_REG_AUX_MOD_dis_reg_am | ST25R3916_REG_AUX_MOD_res_am), 0x88                             /* Use Resistive AM */ | ||||||
|  |                       , ST25R3916_REG_RES_AM_MOD, ST25R3916_REG_RES_AM_MOD_md_res_mask, 0x7F                                                    /* Set Resistive modulation */ | ||||||
|  |                       , ST25R3916_REG_OVERSHOOT_CONF1,  0xFF, 0x40                                                                              /* Set default Overshoot Protection  */ | ||||||
|  |                       , ST25R3916_REG_OVERSHOOT_CONF2,  0xFF, 0x03                                                                              /* Set default Overshoot Protection  */ | ||||||
|  |                       , ST25R3916_REG_UNDERSHOOT_CONF1, 0xFF, 0x40                                                                              /* Set default Undershoot Protection */ | ||||||
|  |                       , ST25R3916_REG_UNDERSHOOT_CONF2, 0xFF, 0x03                                                                              /* Set default Undershoot Protection */ | ||||||
|  |                       ) | ||||||
|  | 
 | ||||||
|  |     /****** Default Analog Configuration for Poll NFC-A Rx 424 ******/ | ||||||
|  |     , MODE_ENTRY_6_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA | RFAL_ANALOG_CONFIG_BITRATE_424 | RFAL_ANALOG_CONFIG_RX) | ||||||
|  |                       , ST25R3916_REG_RX_CONF1,   0xFF, 0x42 | ||||||
|  |                       , ST25R3916_REG_RX_CONF2,   0xFF, 0x3D | ||||||
|  |                       , ST25R3916_REG_RX_CONF3,   0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_RX_CONF4,   0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF1, 0xFF, 0x54 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF2, 0xFF, 0x00 | ||||||
|  |                       ) | ||||||
|  | 
 | ||||||
|  |     /****** Default Analog Configuration for Poll NFC-A Tx 848 ******/ | ||||||
|  |     , MODE_ENTRY_7_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA | RFAL_ANALOG_CONFIG_BITRATE_848 | RFAL_ANALOG_CONFIG_TX) | ||||||
|  |                       , ST25R3916_REG_MODE, ST25R3916_REG_MODE_tr_am  , ST25R3916_REG_MODE_tr_am_am                                             /* Use AM modulation */ | ||||||
|  |                       , ST25R3916_REG_TX_DRIVER, ST25R3916_REG_TX_DRIVER_am_mod_mask, ST25R3916_REG_TX_DRIVER_am_mod_40percent                  /* Set Modulation index */ | ||||||
|  |                       , ST25R3916_REG_AUX_MOD, (ST25R3916_REG_AUX_MOD_dis_reg_am | ST25R3916_REG_AUX_MOD_res_am), 0x00                             /* Use AM via regulator */ | ||||||
|  |                       , ST25R3916_REG_OVERSHOOT_CONF1,  0xFF, 0x00                                                                              /* Disable Overshoot Protection  */ | ||||||
|  |                       , ST25R3916_REG_OVERSHOOT_CONF2,  0xFF, 0x00                                                                              /* Disable Overshoot Protection  */ | ||||||
|  |                       , ST25R3916_REG_UNDERSHOOT_CONF1, 0xFF, 0x00                                                                              /* Disable Undershoot Protection */ | ||||||
|  |                       , ST25R3916_REG_UNDERSHOOT_CONF2, 0xFF, 0x00                                                                              /* Disable Undershoot Protection */ | ||||||
|  |                       ) | ||||||
|  | 
 | ||||||
|  |     /****** Default Analog Configuration for Poll NFC-A Rx 848 ******/ | ||||||
|  |     , MODE_ENTRY_6_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA | RFAL_ANALOG_CONFIG_BITRATE_848 | RFAL_ANALOG_CONFIG_RX) | ||||||
|  |                       , ST25R3916_REG_RX_CONF1,   0xFF, 0x42 | ||||||
|  |                       , ST25R3916_REG_RX_CONF2,   0xFF, 0x3D | ||||||
|  |                       , ST25R3916_REG_RX_CONF3,   0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_RX_CONF4,   0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF1, 0xFF, 0x44 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF2, 0xFF, 0x00 | ||||||
|  |                       ) | ||||||
|  |                        | ||||||
|  |     /****** Default Analog Configuration for Poll NFC-A Anticolision setting ******/ | ||||||
|  |     , MODE_ENTRY_1_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCA | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_ANTICOL) | ||||||
|  |                       , ST25R3916_REG_CORR_CONF1, ST25R3916_REG_CORR_CONF1_corr_s6, 0x00                                                            /* Set collision detection level different from data */ | ||||||
|  |                       ) | ||||||
|  | 
 | ||||||
|  | #ifdef RFAL_USE_COHE | ||||||
|  |     /****** Default Analog Configuration for Poll NFC-B Rx Common ******/ | ||||||
|  |     , MODE_ENTRY_1_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX) | ||||||
|  |                       , ST25R3916_REG_AUX,  ST25R3916_REG_AUX_dis_corr, ST25R3916_REG_AUX_dis_corr_coherent                                     /* Use Coherent Receiver */ | ||||||
|  |                       ) | ||||||
|  | #else | ||||||
|  |     /****** Default Analog Configuration for Poll NFC-B Rx Common ******/ | ||||||
|  |     , MODE_ENTRY_1_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX) | ||||||
|  |                         , ST25R3916_REG_AUX,  ST25R3916_REG_AUX_dis_corr, ST25R3916_REG_AUX_dis_corr_correlator                                 /* Use Correlator Receiver */ | ||||||
|  |                         ) | ||||||
|  | #endif /*RFAL_USE_COHE*/ | ||||||
|  | 
 | ||||||
|  |       /****** Default Analog Configuration for Poll NFC-B Rx 106 ******/ | ||||||
|  |     , MODE_ENTRY_6_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB | RFAL_ANALOG_CONFIG_BITRATE_106 | RFAL_ANALOG_CONFIG_RX) | ||||||
|  |                       , ST25R3916_REG_RX_CONF1,   0xFF, 0x04 | ||||||
|  |                       , ST25R3916_REG_RX_CONF2,   0xFF, 0x3D | ||||||
|  |                       , ST25R3916_REG_RX_CONF3,   0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_RX_CONF4,   0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF1, 0xFF, 0x1B | ||||||
|  |                       , ST25R3916_REG_CORR_CONF2, 0xFF, 0x00 | ||||||
|  |                       ) | ||||||
|  | 
 | ||||||
|  |     /****** Default Analog Configuration for Poll NFC-B Rx 212 ******/ | ||||||
|  |     , MODE_ENTRY_6_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB | RFAL_ANALOG_CONFIG_BITRATE_212 | RFAL_ANALOG_CONFIG_RX) | ||||||
|  |                       , ST25R3916_REG_RX_CONF1,   0xFF, 0x02 | ||||||
|  |                       , ST25R3916_REG_RX_CONF2,   0xFF, 0x3D | ||||||
|  |                       , ST25R3916_REG_RX_CONF3,   0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_RX_CONF4,   0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF1, 0xFF, 0x14 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF2, 0xFF, 0x00 | ||||||
|  |                       ) | ||||||
|  | 
 | ||||||
|  |     /****** Default Analog Configuration for Poll NFC-B Rx 424 ******/ | ||||||
|  |     , MODE_ENTRY_6_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB | RFAL_ANALOG_CONFIG_BITRATE_424 | RFAL_ANALOG_CONFIG_RX) | ||||||
|  |                       , ST25R3916_REG_RX_CONF1, 0xFF, 0x42 | ||||||
|  |                       , ST25R3916_REG_RX_CONF2, 0xFF, 0x3D | ||||||
|  |                       , ST25R3916_REG_RX_CONF3, 0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_RX_CONF4, 0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF1, 0xFF, 0x54 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF2, 0xFF, 0x00 | ||||||
|  |                       ) | ||||||
|  | 
 | ||||||
|  |     /****** Default Analog Configuration for Poll NFC-B Rx 848 ******/ | ||||||
|  |     , MODE_ENTRY_6_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCB | RFAL_ANALOG_CONFIG_BITRATE_848 | RFAL_ANALOG_CONFIG_RX) | ||||||
|  |                       , ST25R3916_REG_RX_CONF1,   0xFF, 0x42 | ||||||
|  |                       , ST25R3916_REG_RX_CONF2,   0xFF, 0x3D | ||||||
|  |                       , ST25R3916_REG_RX_CONF3,   0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_RX_CONF4,   0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF1, 0xFF, 0x44 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF2, 0xFF, 0x00 | ||||||
|  |                       )     | ||||||
|  | #ifdef RFAL_USE_COHE | ||||||
|  | 
 | ||||||
|  |     /****** Default Analog Configuration for Poll NFC-F Rx Common ******/ | ||||||
|  |     , MODE_ENTRY_7_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCF | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX) | ||||||
|  |                       , ST25R3916_REG_AUX,  ST25R3916_REG_AUX_dis_corr, ST25R3916_REG_AUX_dis_corr_coherent      /* Use Pulse Receiver */ | ||||||
|  |                       , ST25R3916_REG_RX_CONF1, 0xFF, 0x13 | ||||||
|  |                       , ST25R3916_REG_RX_CONF2, 0xFF, 0x3D | ||||||
|  |                       , ST25R3916_REG_RX_CONF3, 0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_RX_CONF4, 0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF1, 0xFF, 0x54 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF2, 0xFF, 0x00 | ||||||
|  |                       ) | ||||||
|  | #else | ||||||
|  |     /****** Default Analog Configuration for Poll NFC-F Rx Common ******/ | ||||||
|  |     , MODE_ENTRY_7_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCF | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX) | ||||||
|  |                       , ST25R3916_REG_AUX,  ST25R3916_REG_AUX_dis_corr, ST25R3916_REG_AUX_dis_corr_correlator                                   /* Use Correlator Receiver */ | ||||||
|  |                       , ST25R3916_REG_RX_CONF1,   0xFF, 0x13 | ||||||
|  |                       , ST25R3916_REG_RX_CONF2,   0xFF, 0x3D | ||||||
|  |                       , ST25R3916_REG_RX_CONF3,   0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_RX_CONF4,   0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF1, 0xFF, 0x54 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF2, 0xFF, 0x00 | ||||||
|  |                       ) | ||||||
|  | #endif /*RFAL_USE_COHE*/ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     , MODE_ENTRY_1_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCV | RFAL_ANALOG_CONFIG_BITRATE_1OF4 | RFAL_ANALOG_CONFIG_TX) | ||||||
|  |                       , ST25R3916_REG_MODE, ST25R3916_REG_MODE_tr_am, ST25R3916_REG_MODE_tr_am_ook                                              /* Use OOK */ | ||||||
|  |                       ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifdef RFAL_USE_COHE | ||||||
|  |     /****** Default Analog Configuration for Poll NFC-V Rx Common ******/ | ||||||
|  |     , MODE_ENTRY_7_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCV | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX) | ||||||
|  |                       , ST25R3916_REG_AUX,  ST25R3916_REG_AUX_dis_corr, ST25R3916_REG_AUX_dis_corr_coherent                                     /* Use Pulse Receiver */ | ||||||
|  |                       , ST25R3916_REG_RX_CONF1,   0xFF, 0x13 | ||||||
|  |                       , ST25R3916_REG_RX_CONF2,   0xFF, 0x2D | ||||||
|  |                       , ST25R3916_REG_RX_CONF3,   0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_RX_CONF4,   0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF1, 0xFF, 0x13 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF2, 0xFF, 0x01 | ||||||
|  |                       ) | ||||||
|  | #else | ||||||
|  |     /****** Default Analog Configuration for Poll NFC-V Rx Common ******/ | ||||||
|  |     , MODE_ENTRY_7_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_NFCV | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX) | ||||||
|  |                       , ST25R3916_REG_AUX,  ST25R3916_REG_AUX_dis_corr, ST25R3916_REG_AUX_dis_corr_correlator                                   /* Use Correlator Receiver */ | ||||||
|  |                       , ST25R3916_REG_RX_CONF1,   0xFF, 0x13 | ||||||
|  |                       , ST25R3916_REG_RX_CONF2,   0xFF, 0x2D | ||||||
|  |                       , ST25R3916_REG_RX_CONF3,   0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_RX_CONF4,   0xFF, 0x00 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF1, 0xFF, 0x13 | ||||||
|  |                       , ST25R3916_REG_CORR_CONF2, 0xFF, 0x01 | ||||||
|  |                       ) | ||||||
|  | #endif /*RFAL_USE_COHE*/ | ||||||
|  | 
 | ||||||
|  |                        | ||||||
|  |     /****** Default Analog Configuration for Poll AP2P Tx 106 ******/ | ||||||
|  |     , MODE_ENTRY_5_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_AP2P | RFAL_ANALOG_CONFIG_BITRATE_106 | RFAL_ANALOG_CONFIG_TX) | ||||||
|  |                       , ST25R3916_REG_MODE, ST25R3916_REG_MODE_tr_am , ST25R3916_REG_MODE_tr_am_ook                                             /* Use OOK modulation */ | ||||||
|  |                       , ST25R3916_REG_OVERSHOOT_CONF1,  0xFF, 0x40                                                                              /* Set default Overshoot Protection  */ | ||||||
|  |                       , ST25R3916_REG_OVERSHOOT_CONF2,  0xFF, 0x03                                                                              /* Set default Overshoot Protection  */ | ||||||
|  |                       , ST25R3916_REG_UNDERSHOOT_CONF1, 0xFF, 0x40                                                                              /* Set default Undershoot Protection */ | ||||||
|  |                       , ST25R3916_REG_UNDERSHOOT_CONF2, 0xFF, 0x03                                                                              /* Set default Undershoot Protection */ | ||||||
|  |                       ) | ||||||
|  | 
 | ||||||
|  |     /****** Default Analog Configuration for Poll AP2P Tx 212 ******/     | ||||||
|  |     , MODE_ENTRY_1_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_AP2P | RFAL_ANALOG_CONFIG_BITRATE_212 | RFAL_ANALOG_CONFIG_TX) | ||||||
|  |                       , ST25R3916_REG_MODE, ST25R3916_REG_MODE_tr_am , ST25R3916_REG_MODE_tr_am_am                                              /* Use AM modulation */ | ||||||
|  |                       ) | ||||||
|  |                                                                                                                                                  | ||||||
|  |     /****** Default Analog Configuration for Poll AP2P Tx 424 ******/                                                                            | ||||||
|  |     , MODE_ENTRY_1_REG( (RFAL_ANALOG_CONFIG_POLL | RFAL_ANALOG_CONFIG_TECH_AP2P | RFAL_ANALOG_CONFIG_BITRATE_424 | RFAL_ANALOG_CONFIG_TX)        | ||||||
|  |                       , ST25R3916_REG_MODE, ST25R3916_REG_MODE_tr_am , ST25R3916_REG_MODE_tr_am_am                                              /* Use AM modulation */ | ||||||
|  |                       ) | ||||||
|  |                                                                                                                                                  | ||||||
|  |                                                                                                                                                  | ||||||
|  |     /****** Default Analog Configuration for Chip-Specific Listen On ******/ | ||||||
|  |     , MODE_ENTRY_6_REG( (RFAL_ANALOG_CONFIG_TECH_CHIP | RFAL_ANALOG_CONFIG_CHIP_LISTEN_ON) | ||||||
|  |                       , ST25R3916_REG_ANT_TUNE_A, 0xFF, 0x00                                                                                    /* Set Antenna Tuning (Listener): ANTL */ | ||||||
|  |                       , ST25R3916_REG_ANT_TUNE_B, 0xFF, 0xff                                                                                    /* Set Antenna Tuning (Listener): ANTL */ | ||||||
|  |                       , ST25R3916_REG_OVERSHOOT_CONF1,  0xFF, 0x00                                                                              /* Disable Overshoot Protection  */ | ||||||
|  |                       , ST25R3916_REG_OVERSHOOT_CONF2,  0xFF, 0x00                                                                              /* Disable Overshoot Protection  */ | ||||||
|  |                       , ST25R3916_REG_UNDERSHOOT_CONF1, 0xFF, 0x00                                                                              /* Disable Undershoot Protection */ | ||||||
|  |                       , ST25R3916_REG_UNDERSHOOT_CONF2, 0xFF, 0x00                                                                              /* Disable Undershoot Protection */ | ||||||
|  |                       ) | ||||||
|  |                                                                                                                                                  | ||||||
|  |                                                                                                                                                  | ||||||
|  |     /****** Default Analog Configuration for Listen AP2P Tx Common ******/ | ||||||
|  |     , MODE_ENTRY_7_REG( (RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_AP2P | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_TX) | ||||||
|  |                       , ST25R3916_REG_ANT_TUNE_A, 0xFF, 0x82                                                                                    /* Set Antenna Tuning (Poller): ANTL */ | ||||||
|  |                       , ST25R3916_REG_ANT_TUNE_B, 0xFF, 0x82                                                                                    /* Set Antenna Tuning (Poller): ANTL */ | ||||||
|  |                       , ST25R3916_REG_TX_DRIVER, ST25R3916_REG_TX_DRIVER_am_mod_mask, ST25R3916_REG_TX_DRIVER_am_mod_12percent                  /* Set Modulation index */ | ||||||
|  |                       , ST25R3916_REG_OVERSHOOT_CONF1,  0xFF, 0x00                                                                              /* Disable Overshoot Protection  */ | ||||||
|  |                       , ST25R3916_REG_OVERSHOOT_CONF2,  0xFF, 0x00                                                                              /* Disable Overshoot Protection  */ | ||||||
|  |                       , ST25R3916_REG_UNDERSHOOT_CONF1, 0xFF, 0x00                                                                              /* Disable Undershoot Protection */ | ||||||
|  |                       , ST25R3916_REG_UNDERSHOOT_CONF2, 0xFF, 0x00                                                                              /* Disable Undershoot Protection */ | ||||||
|  |                       ) | ||||||
|  |                                                                                                                                                  | ||||||
|  |                                                                                                                                                  | ||||||
|  |     /****** Default Analog Configuration for Listen AP2P Rx Common ******/ | ||||||
|  |     , MODE_ENTRY_3_REG( (RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_AP2P | RFAL_ANALOG_CONFIG_BITRATE_COMMON | RFAL_ANALOG_CONFIG_RX) | ||||||
|  |                       , ST25R3916_REG_RX_CONF1, ST25R3916_REG_RX_CONF1_lp_mask, ST25R3916_REG_RX_CONF1_lp_1200khz                               /* Set Rx filter configuration */ | ||||||
|  |                       , ST25R3916_REG_RX_CONF1, ST25R3916_REG_RX_CONF1_hz_mask, ST25R3916_REG_RX_CONF1_hz_12_200khz                             /* Set Rx filter configuration */ | ||||||
|  |                       , ST25R3916_REG_RX_CONF2, ST25R3916_REG_RX_CONF2_amd_sel, ST25R3916_REG_RX_CONF2_amd_sel_mixer                            /* AM demodulator: mixer */ | ||||||
|  |                       ) | ||||||
|  |                                                                                                                                                  | ||||||
|  |     /****** Default Analog Configuration for Listen AP2P Tx 106 ******/ | ||||||
|  |     , MODE_ENTRY_5_REG( (RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_AP2P | RFAL_ANALOG_CONFIG_BITRATE_106 | RFAL_ANALOG_CONFIG_TX) | ||||||
|  |                       , ST25R3916_REG_MODE, ST25R3916_REG_MODE_tr_am , ST25R3916_REG_MODE_tr_am_ook                                             /* Use OOK modulation */ | ||||||
|  |                       , ST25R3916_REG_OVERSHOOT_CONF1,  0xFF, 0x40                                                                              /* Set default Overshoot Protection  */ | ||||||
|  |                       , ST25R3916_REG_OVERSHOOT_CONF2,  0xFF, 0x03                                                                              /* Set default Overshoot Protection  */ | ||||||
|  |                       , ST25R3916_REG_UNDERSHOOT_CONF1, 0xFF, 0x40                                                                              /* Set default Undershoot Protection */ | ||||||
|  |                       , ST25R3916_REG_UNDERSHOOT_CONF2, 0xFF, 0x03                                                                              /* Set default Undershoot Protection */ | ||||||
|  |                       ) | ||||||
|  |                                                                                                                                                  | ||||||
|  |     /****** Default Analog Configuration for Listen AP2P Tx 212 ******/ | ||||||
|  |     , MODE_ENTRY_1_REG( (RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_AP2P | RFAL_ANALOG_CONFIG_BITRATE_212 | RFAL_ANALOG_CONFIG_TX) | ||||||
|  |                      , ST25R3916_REG_MODE, ST25R3916_REG_MODE_tr_am , ST25R3916_REG_MODE_tr_am_am                                               /* Use AM modulation */ | ||||||
|  |                      ) | ||||||
|  |                                                                                                                                                  | ||||||
|  |     /****** Default Analog Configuration for Listen AP2P Tx 424 ******/ | ||||||
|  |     , MODE_ENTRY_1_REG( (RFAL_ANALOG_CONFIG_LISTEN | RFAL_ANALOG_CONFIG_TECH_AP2P | RFAL_ANALOG_CONFIG_BITRATE_424 | RFAL_ANALOG_CONFIG_TX) | ||||||
|  |                      , ST25R3916_REG_MODE, ST25R3916_REG_MODE_tr_am , ST25R3916_REG_MODE_tr_am_am                                               /* Use AM modulation */ | ||||||
|  |                      ) | ||||||
|  | 
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const uint16_t rfalAnalogConfigCustomSettingsLength = sizeof(rfalAnalogConfigCustomSettings); | ||||||
							
								
								
									
										11
									
								
								lib/app_scene_template/app_scene.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								lib/app_scene_template/app_scene.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <stdbool.h> | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     uint32_t id; | ||||||
|  |     const void (*on_enter)(void* context); | ||||||
|  |     const bool (*on_event)(void* context, uint32_t event); | ||||||
|  |     const void (*on_exit)(void* context); | ||||||
|  | } AppScene; | ||||||
| @ -61,6 +61,9 @@ CFLAGS			+= -I$(LIB_DIR)/callback-connector | |||||||
| # app template library
 | # app template library
 | ||||||
| CFLAGS			+= -I$(LIB_DIR)/app-template | CFLAGS			+= -I$(LIB_DIR)/app-template | ||||||
| 
 | 
 | ||||||
|  | # add C scene template
 | ||||||
|  | CFLAGS			+= -I$(LIB_DIR)/app_scene_template | ||||||
|  | 
 | ||||||
| # fnv1a hash library
 | # fnv1a hash library
 | ||||||
| CFLAGS			+= -I$(LIB_DIR)/fnv1a-hash | CFLAGS			+= -I$(LIB_DIR)/fnv1a-hash | ||||||
| C_SOURCES		+= $(LIB_DIR)/fnv1a-hash/fnv1a-hash.c | C_SOURCES		+= $(LIB_DIR)/fnv1a-hash/fnv1a-hash.c | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 gornekich
						gornekich