New LF-RFID app (#534)
* Hal lfrfid: add read timer pulse and period config fns * New debug application for lfrfid subsystem * New lfrfid: app, fix naming * App lfrfid: assets * Container view module * App ibutton: remove unused header * App lfrfid scenes * App notification, add yield to blocking operations, add speaker volume control * App lfrfid: reading key scene * Assets: placeholder icon * App lfrfid: reworked container view module * App lfrfid: new scenes * App lfrfid: write scene * App lfrfid: write hid * App lfrfid: emulate scene * App lfrfid: save name scene * App lfrfid: add missing file
This commit is contained in:
		
							parent
							
								
									5d746234e9
								
							
						
					
					
						commit
						22e1ecb642
					
				| @ -16,7 +16,6 @@ int32_t gui_task(void* p); | |||||||
| int32_t backlight_control(void* p); | int32_t backlight_control(void* p); | ||||||
| int32_t irda(void* p); | int32_t irda(void* p); | ||||||
| int32_t app_loader(void* p); | int32_t app_loader(void* p); | ||||||
| int32_t app_lfrfid(void* p); |  | ||||||
| int32_t nfc_task(void* p); | int32_t nfc_task(void* p); | ||||||
| int32_t dolphin_task(void* p); | int32_t dolphin_task(void* p); | ||||||
| int32_t power_task(void* p); | int32_t power_task(void* p); | ||||||
| @ -40,6 +39,8 @@ int32_t internal_storage_task(void* p); | |||||||
| int32_t app_archive(void* p); | int32_t app_archive(void* p); | ||||||
| int32_t notification_app(void* p); | int32_t notification_app(void* p); | ||||||
| int32_t scened_app(void* p); | int32_t scened_app(void* p); | ||||||
|  | int32_t lfrfid_app(void* p); | ||||||
|  | int32_t lfrfid_debug_app(void* p); | ||||||
| 
 | 
 | ||||||
| // On system start hooks declaration
 | // On system start hooks declaration
 | ||||||
| void irda_cli_init(); | void irda_cli_init(); | ||||||
| @ -104,7 +105,8 @@ const FlipperApplication FLIPPER_SERVICES[] = { | |||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef SRV_LF_RFID | #ifdef SRV_LF_RFID | ||||||
|     {.app = app_lfrfid, .name = "125 kHz RFID", .stack_size = 1024, .icon = A_Plugins_14}, |     // TODO: fix stack size when sd api will be in separate thread
 | ||||||
|  |     {.app = lfrfid_app, .name = "125 kHz RFID", .stack_size = 4096, .icon = A_Plugins_14}, | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef SRV_IRDA | #ifdef SRV_IRDA | ||||||
| @ -186,7 +188,8 @@ const FlipperApplication FLIPPER_APPS[] = { | |||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef APP_LF_RFID | #ifdef APP_LF_RFID | ||||||
|     {.app = app_lfrfid, .name = "125 kHz RFID", .stack_size = 1024, .icon = A_125khz_14}, |     // TODO: fix stack size when sd api will be in separate thread
 | ||||||
|  |     {.app = lfrfid_app, .name = "125 kHz RFID", .stack_size = 4096, .icon = A_125khz_14}, | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef APP_IRDA | #ifdef APP_IRDA | ||||||
| @ -302,6 +305,10 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { | |||||||
| #ifdef APP_SCENED | #ifdef APP_SCENED | ||||||
|     {.app = scened_app, .name = "Templated Scene", .stack_size = 1024, .icon = A_Plugins_14}, |     {.app = scened_app, .name = "Templated Scene", .stack_size = 1024, .icon = A_Plugins_14}, | ||||||
| #endif | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef APP_LF_RFID | ||||||
|  |     {.app = lfrfid_debug_app, .name = "LF-RFID Debug", .stack_size = 1024, .icon = A_125khz_14}, | ||||||
|  | #endif | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const size_t FLIPPER_DEBUG_APPS_COUNT = sizeof(FLIPPER_DEBUG_APPS) / sizeof(FlipperApplication); | const size_t FLIPPER_DEBUG_APPS_COUNT = sizeof(FLIPPER_DEBUG_APPS) / sizeof(FlipperApplication); | ||||||
|  | |||||||
| @ -39,8 +39,7 @@ static void dialog_ex_view_draw_callback(Canvas* canvas, void* _model) { | |||||||
|     canvas_clear(canvas); |     canvas_clear(canvas); | ||||||
|     canvas_set_color(canvas, ColorBlack); |     canvas_set_color(canvas, ColorBlack); | ||||||
| 
 | 
 | ||||||
|     // TODO other criteria for the draw
 |     if(model->icon.name != I_Empty_1x1) { | ||||||
|     if(model->icon.x >= 0 && model->icon.y >= 0) { |  | ||||||
|         canvas_draw_icon_name(canvas, model->icon.x, model->icon.y, model->icon.name); |         canvas_draw_icon_name(canvas, model->icon.x, model->icon.y, model->icon.name); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -135,10 +134,9 @@ DialogEx* dialog_ex_alloc() { | |||||||
|             model->text.horizontal = AlignLeft; |             model->text.horizontal = AlignLeft; | ||||||
|             model->text.vertical = AlignBottom; |             model->text.vertical = AlignBottom; | ||||||
| 
 | 
 | ||||||
|             // TODO other criteria for the draw
 |             model->icon.x = 0; | ||||||
|             model->icon.x = -1; |             model->icon.y = 0; | ||||||
|             model->icon.y = -1; |             model->icon.name = I_Empty_1x1; | ||||||
|             model->icon.name = I_ButtonCenter_7x7; |  | ||||||
| 
 | 
 | ||||||
|             model->left_text = NULL; |             model->left_text = NULL; | ||||||
|             model->center_text = NULL; |             model->center_text = NULL; | ||||||
| @ -208,7 +206,7 @@ void dialog_ex_set_text( | |||||||
|         }); |         }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void dialog_ex_set_icon(DialogEx* dialog_ex, int8_t x, int8_t y, IconName name) { | void dialog_ex_set_icon(DialogEx* dialog_ex, uint8_t x, uint8_t y, IconName name) { | ||||||
|     furi_assert(dialog_ex); |     furi_assert(dialog_ex); | ||||||
|     with_view_model( |     with_view_model( | ||||||
|         dialog_ex->view, (DialogExModel * model) { |         dialog_ex->view, (DialogExModel * model) { | ||||||
|  | |||||||
| @ -84,7 +84,7 @@ void dialog_ex_set_text( | |||||||
|  * @param x, y - icon position |  * @param x, y - icon position | ||||||
|  * @param name - icon to be shown |  * @param name - icon to be shown | ||||||
|  */ |  */ | ||||||
| void dialog_ex_set_icon(DialogEx* dialog_ex, int8_t x, int8_t y, IconName name); | void dialog_ex_set_icon(DialogEx* dialog_ex, uint8_t x, uint8_t y, IconName name); | ||||||
| 
 | 
 | ||||||
| /* Set left button text
 | /* Set left button text
 | ||||||
|  * If text is null, left button will not be rendered and processed |  * If text is null, left button will not be rendered and processed | ||||||
|  | |||||||
| @ -21,8 +21,8 @@ typedef struct { | |||||||
| } TextElement; | } TextElement; | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|     int8_t x; |     uint8_t x; | ||||||
|     int8_t y; |     uint8_t y; | ||||||
|     IconName name; |     IconName name; | ||||||
| } IconElement; | } IconElement; | ||||||
| 
 | 
 | ||||||
| @ -39,8 +39,7 @@ static void popup_view_draw_callback(Canvas* canvas, void* _model) { | |||||||
|     canvas_clear(canvas); |     canvas_clear(canvas); | ||||||
|     canvas_set_color(canvas, ColorBlack); |     canvas_set_color(canvas, ColorBlack); | ||||||
| 
 | 
 | ||||||
|     // TODO other criteria for the draw
 |     if(model->icon.name != I_Empty_1x1) { | ||||||
|     if(model->icon.x >= 0 && model->icon.y >= 0) { |  | ||||||
|         canvas_draw_icon_name(canvas, model->icon.x, model->icon.y, model->icon.name); |         canvas_draw_icon_name(canvas, model->icon.x, model->icon.y, model->icon.name); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -137,10 +136,9 @@ Popup* popup_alloc() { | |||||||
|             model->text.horizontal = AlignLeft; |             model->text.horizontal = AlignLeft; | ||||||
|             model->text.vertical = AlignBottom; |             model->text.vertical = AlignBottom; | ||||||
| 
 | 
 | ||||||
|             // TODO other criteria for the draw
 |             model->icon.x = 0; | ||||||
|             model->icon.x = -1; |             model->icon.y = 0; | ||||||
|             model->icon.y = -1; |             model->icon.name = I_Empty_1x1; | ||||||
|             model->icon.name = I_ButtonCenter_7x7; |  | ||||||
|             return true; |             return true; | ||||||
|         }); |         }); | ||||||
|     return popup; |     return popup; | ||||||
| @ -206,7 +204,7 @@ void popup_set_text( | |||||||
|         }); |         }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void popup_set_icon(Popup* popup, int8_t x, int8_t y, IconName name) { | void popup_set_icon(Popup* popup, uint8_t x, uint8_t y, IconName name) { | ||||||
|     furi_assert(popup); |     furi_assert(popup); | ||||||
|     with_view_model( |     with_view_model( | ||||||
|         popup->view, (PopupModel * model) { |         popup->view, (PopupModel * model) { | ||||||
|  | |||||||
| @ -77,7 +77,7 @@ void popup_set_text( | |||||||
|  * @param x, y - icon position |  * @param x, y - icon position | ||||||
|  * @param name - icon to be shown |  * @param name - icon to be shown | ||||||
|  */ |  */ | ||||||
| void popup_set_icon(Popup* popup, int8_t x, int8_t y, IconName name); | void popup_set_icon(Popup* popup, uint8_t x, uint8_t y, IconName name); | ||||||
| 
 | 
 | ||||||
| /* Set popup timeout
 | /* Set popup timeout
 | ||||||
|  * @param popup - Popup instance |  * @param popup - Popup instance | ||||||
|  | |||||||
| @ -27,7 +27,6 @@ | |||||||
| 
 | 
 | ||||||
| #include <sd-card-api.h> | #include <sd-card-api.h> | ||||||
| #include <filesystem-api.h> | #include <filesystem-api.h> | ||||||
| #include "../cli/cli.h" |  | ||||||
| 
 | 
 | ||||||
| #include "one_wire_master.h" | #include "one_wire_master.h" | ||||||
| #include "maxim_crc.h" | #include "maxim_crc.h" | ||||||
|  | |||||||
| @ -36,7 +36,7 @@ void iButtonSceneDeleteSuccess::on_exit(iButtonApp* app) { | |||||||
|     Popup* popup = app->get_view_manager()->get_popup(); |     Popup* popup = app->get_view_manager()->get_popup(); | ||||||
| 
 | 
 | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); | ||||||
|     popup_set_icon(popup, -1, -1, I_DolphinWait_61x59); |     popup_set_icon(popup, 0, 0, I_Empty_1x1); | ||||||
| 
 | 
 | ||||||
|     popup_disable_timeout(popup); |     popup_disable_timeout(popup); | ||||||
|     popup_set_context(popup, NULL); |     popup_set_context(popup, NULL); | ||||||
|  | |||||||
| @ -89,5 +89,5 @@ void iButtonSceneEmulate::on_exit(iButtonApp* app) { | |||||||
| 
 | 
 | ||||||
|     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); |     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); | ||||||
|     popup_set_icon(popup, -1, -1, I_DolphinWait_61x59); |     popup_set_icon(popup, 0, 0, I_Empty_1x1); | ||||||
| } | } | ||||||
| @ -74,7 +74,7 @@ void iButtonSceneReadSuccess::on_exit(iButtonApp* app) { | |||||||
|     dialog_ex_set_right_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_result_callback(dialog_ex, NULL); | ||||||
|     dialog_ex_set_context(dialog_ex, NULL); |     dialog_ex_set_context(dialog_ex, NULL); | ||||||
|     dialog_ex_set_icon(dialog_ex, -1, -1, I_ButtonCenter_7x7); |     dialog_ex_set_icon(dialog_ex, 0, 0, I_Empty_1x1); | ||||||
| 
 | 
 | ||||||
|     app->notify_green_off(); |     app->notify_green_off(); | ||||||
| } | } | ||||||
|  | |||||||
| @ -49,5 +49,5 @@ void iButtonSceneRead::on_exit(iButtonApp* app) { | |||||||
| 
 | 
 | ||||||
|     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); |     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); | ||||||
|     popup_set_icon(popup, -1, -1, I_DolphinWait_61x59); |     popup_set_icon(popup, 0, 0, I_Empty_1x1); | ||||||
| } | } | ||||||
| @ -39,7 +39,7 @@ void iButtonSceneSaveSuccess::on_exit(iButtonApp* app) { | |||||||
|     Popup* popup = app->get_view_manager()->get_popup(); |     Popup* popup = app->get_view_manager()->get_popup(); | ||||||
| 
 | 
 | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); | ||||||
|     popup_set_icon(popup, -1, -1, I_DolphinWait_61x59); |     popup_set_icon(popup, 0, 0, I_Empty_1x1); | ||||||
| 
 | 
 | ||||||
|     popup_disable_timeout(popup); |     popup_disable_timeout(popup); | ||||||
|     popup_set_context(popup, NULL); |     popup_set_context(popup, NULL); | ||||||
|  | |||||||
| @ -40,7 +40,7 @@ void iButtonSceneWriteSuccess::on_exit(iButtonApp* app) { | |||||||
|     Popup* popup = app->get_view_manager()->get_popup(); |     Popup* popup = app->get_view_manager()->get_popup(); | ||||||
| 
 | 
 | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); | ||||||
|     popup_set_icon(popup, -1, -1, I_DolphinWait_61x59); |     popup_set_icon(popup, 0, 0, I_Empty_1x1); | ||||||
| 
 | 
 | ||||||
|     popup_disable_timeout(popup); |     popup_disable_timeout(popup); | ||||||
|     popup_set_context(popup, NULL); |     popup_set_context(popup, NULL); | ||||||
|  | |||||||
| @ -92,7 +92,7 @@ void iButtonSceneWrite::on_exit(iButtonApp* app) { | |||||||
| 
 | 
 | ||||||
|     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); |     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); | ||||||
|     popup_set_icon(popup, -1, -1, I_DolphinWait_61x59); |     popup_set_icon(popup, 0, 0, I_Empty_1x1); | ||||||
| 
 | 
 | ||||||
|     app->get_key_worker()->stop_write(); |     app->get_key_worker()->stop_write(); | ||||||
| } | } | ||||||
| @ -41,7 +41,7 @@ void IrdaAppSceneEditDelete::on_enter(IrdaApp* app) { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     dialog_ex_set_text(dialog_ex, app->get_text_store(0), 64, 32, AlignCenter, AlignCenter); |     dialog_ex_set_text(dialog_ex, app->get_text_store(0), 64, 32, AlignCenter, AlignCenter); | ||||||
|     dialog_ex_set_icon(dialog_ex, -1, -1, I_ButtonCenter_7x7); |     dialog_ex_set_icon(dialog_ex, 0, 0, I_Empty_1x1); | ||||||
|     dialog_ex_set_left_button_text(dialog_ex, "Back"); |     dialog_ex_set_left_button_text(dialog_ex, "Back"); | ||||||
|     dialog_ex_set_right_button_text(dialog_ex, "Delete"); |     dialog_ex_set_right_button_text(dialog_ex, "Delete"); | ||||||
|     dialog_ex_set_result_callback(dialog_ex, dialog_result_callback); |     dialog_ex_set_result_callback(dialog_ex, dialog_result_callback); | ||||||
|  | |||||||
| @ -1,140 +0,0 @@ | |||||||
| #include "lf-rfid-app.h" |  | ||||||
| #include <furi.h> |  | ||||||
| #include <api-hal.h> |  | ||||||
| #include <stdarg.h> |  | ||||||
| 
 |  | ||||||
| void LfrfidApp::run(void) { |  | ||||||
|     LfrfidEvent event; |  | ||||||
|     bool consumed; |  | ||||||
|     bool exit = false; |  | ||||||
| 
 |  | ||||||
|     scenes[current_scene]->on_enter(this); |  | ||||||
| 
 |  | ||||||
|     while(!exit) { |  | ||||||
|         view.receive_event(&event); |  | ||||||
| 
 |  | ||||||
|         consumed = scenes[current_scene]->on_event(this, &event); |  | ||||||
| 
 |  | ||||||
|         if(!consumed) { |  | ||||||
|             if(event.type == LfrfidEvent::Type::Back) { |  | ||||||
|                 exit = switch_to_previous_scene(); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     scenes[current_scene]->on_exit(this); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| LfrfidApp::LfrfidApp() { |  | ||||||
|     api_hal_power_insomnia_enter(); |  | ||||||
|     notification = static_cast<NotificationApp*>(furi_record_open("notification")); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| LfrfidApp::~LfrfidApp() { |  | ||||||
|     for(std::map<Scene, LfrfidScene*>::iterator it = scenes.begin(); it != scenes.end(); ++it) { |  | ||||||
|         delete it->second; |  | ||||||
|         scenes.erase(it); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     furi_record_close("notification"); |  | ||||||
| 
 |  | ||||||
|     api_hal_power_insomnia_exit(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| LfrfidAppViewManager* LfrfidApp::get_view_manager() { |  | ||||||
|     return &view; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void LfrfidApp::switch_to_next_scene(Scene next_scene) { |  | ||||||
|     previous_scenes_list.push_front(current_scene); |  | ||||||
| 
 |  | ||||||
|     if(next_scene != Scene::Exit) { |  | ||||||
|         scenes[current_scene]->on_exit(this); |  | ||||||
|         current_scene = next_scene; |  | ||||||
|         scenes[current_scene]->on_enter(this); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void LfrfidApp::search_and_switch_to_previous_scene(std::initializer_list<Scene> scenes_list) { |  | ||||||
|     Scene previous_scene = Scene::Start; |  | ||||||
|     bool scene_found = false; |  | ||||||
| 
 |  | ||||||
|     while(!scene_found) { |  | ||||||
|         previous_scene = get_previous_scene(); |  | ||||||
|         for(Scene element : scenes_list) { |  | ||||||
|             if(previous_scene == element || previous_scene == Scene::Start) { |  | ||||||
|                 scene_found = true; |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     scenes[current_scene]->on_exit(this); |  | ||||||
|     current_scene = previous_scene; |  | ||||||
|     scenes[current_scene]->on_enter(this); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool LfrfidApp::switch_to_previous_scene(uint8_t count) { |  | ||||||
|     Scene previous_scene = Scene::Start; |  | ||||||
| 
 |  | ||||||
|     for(uint8_t i = 0; i < count; i++) { |  | ||||||
|         previous_scene = get_previous_scene(); |  | ||||||
|         if(previous_scene == Scene::Exit) break; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if(previous_scene == Scene::Exit) { |  | ||||||
|         return true; |  | ||||||
|     } else { |  | ||||||
|         scenes[current_scene]->on_exit(this); |  | ||||||
|         current_scene = previous_scene; |  | ||||||
|         scenes[current_scene]->on_enter(this); |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| LfrfidApp::Scene LfrfidApp::get_previous_scene() { |  | ||||||
|     Scene scene = previous_scenes_list.front(); |  | ||||||
|     previous_scenes_list.pop_front(); |  | ||||||
|     return scene; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /***************************** NOTIFY *******************************/ |  | ||||||
| 
 |  | ||||||
| void LfrfidApp::notify_green_blink() { |  | ||||||
|     notification_message(notification, &sequence_blink_green_10); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void LfrfidApp::notify_success() { |  | ||||||
|     notification_message(notification, &sequence_success); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /*************************** TEXT STORE *****************************/ |  | ||||||
| 
 |  | ||||||
| char* LfrfidApp::get_text_store() { |  | ||||||
|     return text_store; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| uint8_t LfrfidApp::get_text_store_size() { |  | ||||||
|     return text_store_size; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void LfrfidApp::set_text_store(const char* text...) { |  | ||||||
|     va_list args; |  | ||||||
|     va_start(args, text); |  | ||||||
| 
 |  | ||||||
|     vsnprintf(text_store, text_store_size, text, args); |  | ||||||
| 
 |  | ||||||
|     va_end(args); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| RfidReader* LfrfidApp::get_reader() { |  | ||||||
|     return &reader; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| RfidTimerEmulator* LfrfidApp::get_emulator() { |  | ||||||
|     return &emulator; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| RfidWriter* LfrfidApp::get_writer() { |  | ||||||
|     return &writer; |  | ||||||
| } |  | ||||||
| @ -1,79 +0,0 @@ | |||||||
| #pragma once |  | ||||||
| #include <map> |  | ||||||
| #include <list> |  | ||||||
| #include "lf-rfid-view-manager.h" |  | ||||||
| 
 |  | ||||||
| #include "scene/lf-rfid-scene-start.h" |  | ||||||
| #include "scene/lf-rfid-scene-emulate-indala.h" |  | ||||||
| #include "scene/lf-rfid-scene-emulate-hid.h" |  | ||||||
| #include "scene/lf-rfid-scene-emulate-emmarine.h" |  | ||||||
| #include "scene/lf-rfid-scene-read-normal.h" |  | ||||||
| #include "scene/lf-rfid-scene-read-indala.h" |  | ||||||
| #include "scene/lf-rfid-scene-tune.h" |  | ||||||
| #include "scene/lf-rfid-scene-write.h" |  | ||||||
| 
 |  | ||||||
| #include "helpers/rfid-reader.h" |  | ||||||
| #include "helpers/rfid-timer-emulator.h" |  | ||||||
| 
 |  | ||||||
| #include <notification/notification-messages.h> |  | ||||||
| 
 |  | ||||||
| class LfrfidApp { |  | ||||||
| public: |  | ||||||
|     void run(void); |  | ||||||
| 
 |  | ||||||
|     LfrfidApp(); |  | ||||||
|     ~LfrfidApp(); |  | ||||||
| 
 |  | ||||||
|     enum class Scene : uint8_t { |  | ||||||
|         Exit, |  | ||||||
|         Start, |  | ||||||
|         ReadNormal, |  | ||||||
|         ReadIndala, |  | ||||||
|         EmulateIndala, |  | ||||||
|         EmulateHID, |  | ||||||
|         EmulateEM, |  | ||||||
|         Tune, |  | ||||||
|         Write, |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     LfrfidAppViewManager* get_view_manager(); |  | ||||||
|     void switch_to_next_scene(Scene index); |  | ||||||
|     void search_and_switch_to_previous_scene(std::initializer_list<Scene> scenes_list); |  | ||||||
|     bool switch_to_previous_scene(uint8_t count = 1); |  | ||||||
|     Scene get_previous_scene(); |  | ||||||
| 
 |  | ||||||
|     void notify_green_blink(); |  | ||||||
|     void notify_success(); |  | ||||||
| 
 |  | ||||||
|     char* get_text_store(); |  | ||||||
|     uint8_t get_text_store_size(); |  | ||||||
|     void set_text_store(const char* text...); |  | ||||||
| 
 |  | ||||||
|     RfidReader* get_reader(); |  | ||||||
|     RfidTimerEmulator* get_emulator(); |  | ||||||
|     RfidWriter* get_writer(); |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     std::list<Scene> previous_scenes_list = {Scene::Exit}; |  | ||||||
|     Scene current_scene = Scene::Start; |  | ||||||
|     LfrfidAppViewManager view; |  | ||||||
| 
 |  | ||||||
|     std::map<Scene, LfrfidScene*> scenes = { |  | ||||||
|         {Scene::Start, new LfrfidSceneStart()}, |  | ||||||
|         {Scene::ReadNormal, new LfrfidSceneReadNormal()}, |  | ||||||
|         {Scene::ReadIndala, new LfrfidSceneReadIndala()}, |  | ||||||
|         {Scene::EmulateIndala, new LfrfidSceneEmulateIndala()}, |  | ||||||
|         {Scene::EmulateHID, new LfrfidSceneEmulateHID()}, |  | ||||||
|         {Scene::EmulateEM, new LfrfidSceneEmulateEMMarine()}, |  | ||||||
|         {Scene::Tune, new LfrfidSceneTune()}, |  | ||||||
|         {Scene::Write, new LfrfidSceneWrite()}, |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     static const uint8_t text_store_size = 128; |  | ||||||
|     char text_store[text_store_size + 1]; |  | ||||||
| 
 |  | ||||||
|     NotificationApp* notification; |  | ||||||
|     RfidReader reader; |  | ||||||
|     RfidTimerEmulator emulator; |  | ||||||
|     RfidWriter writer; |  | ||||||
| }; |  | ||||||
| @ -1,21 +0,0 @@ | |||||||
| #pragma once |  | ||||||
| #include <stdint.h> |  | ||||||
| 
 |  | ||||||
| class LfrfidEvent { |  | ||||||
| public: |  | ||||||
|     // events enum
 |  | ||||||
|     enum class Type : uint8_t { |  | ||||||
|         Tick, |  | ||||||
|         Back, |  | ||||||
|         MenuSelected, |  | ||||||
|         NextScene, |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     // payload
 |  | ||||||
|     union { |  | ||||||
|         uint32_t menu_index; |  | ||||||
|     } payload; |  | ||||||
| 
 |  | ||||||
|     // event type
 |  | ||||||
|     Type type; |  | ||||||
| }; |  | ||||||
| @ -1,90 +0,0 @@ | |||||||
| #include "lf-rfid-view-manager.h" |  | ||||||
| #include "lf-rfid-event.h" |  | ||||||
| #include <callback-connector.h> |  | ||||||
| 
 |  | ||||||
| LfrfidAppViewManager::LfrfidAppViewManager() { |  | ||||||
|     event_queue = osMessageQueueNew(10, sizeof(LfrfidEvent), NULL); |  | ||||||
| 
 |  | ||||||
|     view_dispatcher = view_dispatcher_alloc(); |  | ||||||
|     auto callback = cbc::obtain_connector(this, &LfrfidAppViewManager::previous_view_callback); |  | ||||||
| 
 |  | ||||||
|     // allocate views
 |  | ||||||
|     submenu = submenu_alloc(); |  | ||||||
|     add_view(ViewType::Submenu, submenu_get_view(submenu)); |  | ||||||
| 
 |  | ||||||
|     popup = popup_alloc(); |  | ||||||
|     add_view(ViewType::Popup, popup_get_view(popup)); |  | ||||||
| 
 |  | ||||||
|     tune = new LfRfidViewTune(); |  | ||||||
|     add_view(ViewType::Tune, tune->get_view()); |  | ||||||
| 
 |  | ||||||
|     gui = static_cast<Gui*>(furi_record_open("gui")); |  | ||||||
|     view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen); |  | ||||||
| 
 |  | ||||||
|     // set previous view callback for all views
 |  | ||||||
|     view_set_previous_callback(submenu_get_view(submenu), callback); |  | ||||||
|     view_set_previous_callback(popup_get_view(popup), callback); |  | ||||||
|     view_set_previous_callback(tune->get_view(), callback); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| LfrfidAppViewManager::~LfrfidAppViewManager() { |  | ||||||
|     // remove views
 |  | ||||||
|     view_dispatcher_remove_view( |  | ||||||
|         view_dispatcher, static_cast<uint32_t>(LfrfidAppViewManager::ViewType::Submenu)); |  | ||||||
|     view_dispatcher_remove_view( |  | ||||||
|         view_dispatcher, static_cast<uint32_t>(LfrfidAppViewManager::ViewType::Popup)); |  | ||||||
|     view_dispatcher_remove_view( |  | ||||||
|         view_dispatcher, static_cast<uint32_t>(LfrfidAppViewManager::ViewType::Tune)); |  | ||||||
| 
 |  | ||||||
|     // free view modules
 |  | ||||||
|     submenu_free(submenu); |  | ||||||
|     popup_free(popup); |  | ||||||
|     delete tune; |  | ||||||
| 
 |  | ||||||
|     // free dispatcher
 |  | ||||||
|     view_dispatcher_free(view_dispatcher); |  | ||||||
| 
 |  | ||||||
|     // free event queue
 |  | ||||||
|     osMessageQueueDelete(event_queue); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void LfrfidAppViewManager::switch_to(ViewType type) { |  | ||||||
|     view_dispatcher_switch_to_view(view_dispatcher, static_cast<uint32_t>(type)); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Submenu* LfrfidAppViewManager::get_submenu() { |  | ||||||
|     return submenu; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| Popup* LfrfidAppViewManager::get_popup() { |  | ||||||
|     return popup; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| LfRfidViewTune* LfrfidAppViewManager::get_tune() { |  | ||||||
|     return tune; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void LfrfidAppViewManager::receive_event(LfrfidEvent* event) { |  | ||||||
|     if(osMessageQueueGet(event_queue, event, NULL, 100) != osOK) { |  | ||||||
|         event->type = LfrfidEvent::Type::Tick; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void LfrfidAppViewManager::send_event(LfrfidEvent* event) { |  | ||||||
|     osStatus_t result = osMessageQueuePut(event_queue, event, 0, 0); |  | ||||||
|     furi_check(result == osOK); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| uint32_t LfrfidAppViewManager::previous_view_callback(void* context) { |  | ||||||
|     if(event_queue != NULL) { |  | ||||||
|         LfrfidEvent event; |  | ||||||
|         event.type = LfrfidEvent::Type::Back; |  | ||||||
|         send_event(&event); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return VIEW_IGNORE; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void LfrfidAppViewManager::add_view(ViewType view_type, View* view) { |  | ||||||
|     view_dispatcher_add_view(view_dispatcher, static_cast<uint32_t>(view_type), view); |  | ||||||
| } |  | ||||||
| @ -1,42 +0,0 @@ | |||||||
| #pragma once |  | ||||||
| #include <furi.h> |  | ||||||
| #include <gui/view_dispatcher.h> |  | ||||||
| #include <gui/modules/submenu.h> |  | ||||||
| #include <gui/modules/popup.h> |  | ||||||
| #include "lf-rfid-event.h" |  | ||||||
| #include "view/lf-rfid-view-tune.h" |  | ||||||
| 
 |  | ||||||
| class LfrfidAppViewManager { |  | ||||||
| public: |  | ||||||
|     enum class ViewType : uint8_t { |  | ||||||
|         Submenu, |  | ||||||
|         Popup, |  | ||||||
|         Tune, |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     osMessageQueueId_t event_queue; |  | ||||||
| 
 |  | ||||||
|     LfrfidAppViewManager(); |  | ||||||
|     ~LfrfidAppViewManager(); |  | ||||||
| 
 |  | ||||||
|     void switch_to(ViewType type); |  | ||||||
| 
 |  | ||||||
|     void receive_event(LfrfidEvent* event); |  | ||||||
|     void send_event(LfrfidEvent* event); |  | ||||||
| 
 |  | ||||||
|     Submenu* get_submenu(); |  | ||||||
|     Popup* get_popup(); |  | ||||||
|     LfRfidViewTune* get_tune(); |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     ViewDispatcher* view_dispatcher; |  | ||||||
|     Gui* gui; |  | ||||||
| 
 |  | ||||||
|     uint32_t previous_view_callback(void* context); |  | ||||||
|     void add_view(ViewType view_type, View* view); |  | ||||||
| 
 |  | ||||||
|     // view elements
 |  | ||||||
|     Submenu* submenu; |  | ||||||
|     Popup* popup; |  | ||||||
|     LfRfidViewTune* tune; |  | ||||||
| }; |  | ||||||
| @ -1,10 +0,0 @@ | |||||||
| #include "lf-rfid-app.h" |  | ||||||
| 
 |  | ||||||
| // app enter function
 |  | ||||||
| extern "C" int32_t app_lfrfid(void* p) { |  | ||||||
|     LfrfidApp* app = new LfrfidApp(); |  | ||||||
|     app->run(); |  | ||||||
|     delete app; |  | ||||||
| 
 |  | ||||||
|     return 255; |  | ||||||
| } |  | ||||||
| @ -1,34 +0,0 @@ | |||||||
| #include "lf-rfid-scene-emulate-emmarine.h" |  | ||||||
| 
 |  | ||||||
| #include "../lf-rfid-app.h" |  | ||||||
| #include "../lf-rfid-view-manager.h" |  | ||||||
| #include "../lf-rfid-event.h" |  | ||||||
| #include "../helpers/key-info.h" |  | ||||||
| 
 |  | ||||||
| void LfrfidSceneEmulateEMMarine::on_enter(LfrfidApp* app) { |  | ||||||
|     LfrfidAppViewManager* view_manager = app->get_view_manager(); |  | ||||||
| 
 |  | ||||||
|     Popup* popup = view_manager->get_popup(); |  | ||||||
|     popup_set_header(popup, "LF-RFID", 64, 16, AlignCenter, AlignBottom); |  | ||||||
|     app->set_text_store("EM emulation"); |  | ||||||
|     popup_set_text(popup, app->get_text_store(), 64, 22, AlignCenter, AlignTop); |  | ||||||
| 
 |  | ||||||
|     view_manager->switch_to(LfrfidAppViewManager::ViewType::Popup); |  | ||||||
|     app->get_emulator()->start(LfrfidKeyType::KeyEM4100, data, 5); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool LfrfidSceneEmulateEMMarine::on_event(LfrfidApp* app, LfrfidEvent* event) { |  | ||||||
|     bool consumed = false; |  | ||||||
| 
 |  | ||||||
|     return consumed; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void LfrfidSceneEmulateEMMarine::on_exit(LfrfidApp* app) { |  | ||||||
|     LfrfidAppViewManager* view_manager = app->get_view_manager(); |  | ||||||
| 
 |  | ||||||
|     Popup* popup = view_manager->get_popup(); |  | ||||||
|     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); |  | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |  | ||||||
| 
 |  | ||||||
|     app->get_emulator()->stop(); |  | ||||||
| } |  | ||||||
| @ -1,13 +0,0 @@ | |||||||
| #pragma once |  | ||||||
| #include "lf-rfid-scene-generic.h" |  | ||||||
| #include "../helpers/key-info.h" |  | ||||||
| 
 |  | ||||||
| class LfrfidSceneEmulateEMMarine : public LfrfidScene { |  | ||||||
| public: |  | ||||||
|     void on_enter(LfrfidApp* app) final; |  | ||||||
|     bool on_event(LfrfidApp* app, LfrfidEvent* event) final; |  | ||||||
|     void on_exit(LfrfidApp* app) final; |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     const uint8_t data[5] = {0x53, 0x00, 0x5F, 0xB3, 0xC2}; |  | ||||||
| }; |  | ||||||
| @ -1,34 +0,0 @@ | |||||||
| #include "lf-rfid-scene-emulate-hid.h" |  | ||||||
| 
 |  | ||||||
| #include "../lf-rfid-app.h" |  | ||||||
| #include "../lf-rfid-view-manager.h" |  | ||||||
| #include "../lf-rfid-event.h" |  | ||||||
| #include "../helpers/key-info.h" |  | ||||||
| 
 |  | ||||||
| void LfrfidSceneEmulateHID::on_enter(LfrfidApp* app) { |  | ||||||
|     LfrfidAppViewManager* view_manager = app->get_view_manager(); |  | ||||||
| 
 |  | ||||||
|     Popup* popup = view_manager->get_popup(); |  | ||||||
|     popup_set_header(popup, "LF-RFID", 64, 16, AlignCenter, AlignBottom); |  | ||||||
|     app->set_text_store("HID H10301 emulation"); |  | ||||||
|     popup_set_text(popup, app->get_text_store(), 64, 22, AlignCenter, AlignTop); |  | ||||||
| 
 |  | ||||||
|     view_manager->switch_to(LfrfidAppViewManager::ViewType::Popup); |  | ||||||
|     app->get_emulator()->start(LfrfidKeyType::KeyH10301, data, 3); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool LfrfidSceneEmulateHID::on_event(LfrfidApp* app, LfrfidEvent* event) { |  | ||||||
|     bool consumed = false; |  | ||||||
| 
 |  | ||||||
|     return consumed; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void LfrfidSceneEmulateHID::on_exit(LfrfidApp* app) { |  | ||||||
|     LfrfidAppViewManager* view_manager = app->get_view_manager(); |  | ||||||
| 
 |  | ||||||
|     Popup* popup = view_manager->get_popup(); |  | ||||||
|     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); |  | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |  | ||||||
| 
 |  | ||||||
|     app->get_emulator()->stop(); |  | ||||||
| } |  | ||||||
| @ -1,13 +0,0 @@ | |||||||
| #pragma once |  | ||||||
| #include "lf-rfid-scene-generic.h" |  | ||||||
| #include "../helpers/key-info.h" |  | ||||||
| 
 |  | ||||||
| class LfrfidSceneEmulateHID : public LfrfidScene { |  | ||||||
| public: |  | ||||||
|     void on_enter(LfrfidApp* app) final; |  | ||||||
|     bool on_event(LfrfidApp* app, LfrfidEvent* event) final; |  | ||||||
|     void on_exit(LfrfidApp* app) final; |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     const uint8_t data[3] = {0xED, 0x87, 0x70}; |  | ||||||
| }; |  | ||||||
| @ -1,34 +0,0 @@ | |||||||
| #include "lf-rfid-scene-emulate-indala.h" |  | ||||||
| 
 |  | ||||||
| #include "../lf-rfid-app.h" |  | ||||||
| #include "../lf-rfid-view-manager.h" |  | ||||||
| #include "../lf-rfid-event.h" |  | ||||||
| #include "../helpers/key-info.h" |  | ||||||
| 
 |  | ||||||
| void LfrfidSceneEmulateIndala::on_enter(LfrfidApp* app) { |  | ||||||
|     LfrfidAppViewManager* view_manager = app->get_view_manager(); |  | ||||||
| 
 |  | ||||||
|     Popup* popup = view_manager->get_popup(); |  | ||||||
|     popup_set_header(popup, "LF-RFID", 64, 16, AlignCenter, AlignBottom); |  | ||||||
|     app->set_text_store("Indala 40134 emulation"); |  | ||||||
|     popup_set_text(popup, app->get_text_store(), 64, 22, AlignCenter, AlignTop); |  | ||||||
| 
 |  | ||||||
|     view_manager->switch_to(LfrfidAppViewManager::ViewType::Popup); |  | ||||||
|     app->get_emulator()->start(LfrfidKeyType::KeyI40134, data, 3); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool LfrfidSceneEmulateIndala::on_event(LfrfidApp* app, LfrfidEvent* event) { |  | ||||||
|     bool consumed = false; |  | ||||||
| 
 |  | ||||||
|     return consumed; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void LfrfidSceneEmulateIndala::on_exit(LfrfidApp* app) { |  | ||||||
|     LfrfidAppViewManager* view_manager = app->get_view_manager(); |  | ||||||
| 
 |  | ||||||
|     Popup* popup = view_manager->get_popup(); |  | ||||||
|     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); |  | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |  | ||||||
| 
 |  | ||||||
|     app->get_emulator()->stop(); |  | ||||||
| } |  | ||||||
| @ -1,13 +0,0 @@ | |||||||
| #pragma once |  | ||||||
| #include "lf-rfid-scene-generic.h" |  | ||||||
| #include "../helpers/key-info.h" |  | ||||||
| 
 |  | ||||||
| class LfrfidSceneEmulateIndala : public LfrfidScene { |  | ||||||
| public: |  | ||||||
|     void on_enter(LfrfidApp* app) final; |  | ||||||
|     bool on_event(LfrfidApp* app, LfrfidEvent* event) final; |  | ||||||
|     void on_exit(LfrfidApp* app) final; |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     const uint8_t data[3] = {0x1F, 0x2E, 0x3D}; |  | ||||||
| }; |  | ||||||
| @ -1,14 +0,0 @@ | |||||||
| #pragma once |  | ||||||
| #include "../lf-rfid-event.h" |  | ||||||
| 
 |  | ||||||
| class LfrfidApp; |  | ||||||
| 
 |  | ||||||
| class LfrfidScene { |  | ||||||
| public: |  | ||||||
|     virtual void on_enter(LfrfidApp* app) = 0; |  | ||||||
|     virtual bool on_event(LfrfidApp* app, LfrfidEvent* event) = 0; |  | ||||||
|     virtual void on_exit(LfrfidApp* app) = 0; |  | ||||||
|     virtual ~LfrfidScene(){}; |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
| }; |  | ||||||
| @ -1,34 +0,0 @@ | |||||||
| #include "lf-rfid-scene-read-indala.h" |  | ||||||
| 
 |  | ||||||
| #include "../lf-rfid-app.h" |  | ||||||
| #include "../lf-rfid-view-manager.h" |  | ||||||
| #include "../lf-rfid-event.h" |  | ||||||
| #include "../helpers/key-info.h" |  | ||||||
| 
 |  | ||||||
| void LfrfidSceneReadIndala::on_enter(LfrfidApp* app) { |  | ||||||
|     LfrfidAppViewManager* view_manager = app->get_view_manager(); |  | ||||||
| 
 |  | ||||||
|     Popup* popup = view_manager->get_popup(); |  | ||||||
|     popup_set_header(popup, "LF-RFID read Indala", 64, 16, AlignCenter, AlignBottom); |  | ||||||
|     app->set_text_store("[decoder not implemented]"); |  | ||||||
|     popup_set_text(popup, app->get_text_store(), 64, 22, AlignCenter, AlignTop); |  | ||||||
| 
 |  | ||||||
|     view_manager->switch_to(LfrfidAppViewManager::ViewType::Popup); |  | ||||||
|     app->get_reader()->start(RfidReader::Type::Indala); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool LfrfidSceneReadIndala::on_event(LfrfidApp* app, LfrfidEvent* event) { |  | ||||||
|     bool consumed = false; |  | ||||||
| 
 |  | ||||||
|     return consumed; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void LfrfidSceneReadIndala::on_exit(LfrfidApp* app) { |  | ||||||
|     LfrfidAppViewManager* view_manager = app->get_view_manager(); |  | ||||||
| 
 |  | ||||||
|     Popup* popup = view_manager->get_popup(); |  | ||||||
|     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); |  | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |  | ||||||
| 
 |  | ||||||
|     app->get_reader()->stop(); |  | ||||||
| } |  | ||||||
| @ -1,15 +0,0 @@ | |||||||
| #pragma once |  | ||||||
| #include "lf-rfid-scene-generic.h" |  | ||||||
| #include "../helpers/key-info.h" |  | ||||||
| 
 |  | ||||||
| class LfrfidSceneReadIndala : public LfrfidScene { |  | ||||||
| public: |  | ||||||
|     void on_enter(LfrfidApp* app) final; |  | ||||||
|     bool on_event(LfrfidApp* app, LfrfidEvent* event) final; |  | ||||||
|     void on_exit(LfrfidApp* app) final; |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     uint32_t success_reads = 0; |  | ||||||
|     static const uint8_t data_size = LFRFID_KEY_SIZE; |  | ||||||
|     uint8_t last_data[data_size] = {0}; |  | ||||||
| }; |  | ||||||
| @ -1,89 +0,0 @@ | |||||||
| #include "lf-rfid-scene-read-normal.h" |  | ||||||
| 
 |  | ||||||
| #include "../lf-rfid-app.h" |  | ||||||
| #include "../lf-rfid-view-manager.h" |  | ||||||
| #include "../lf-rfid-event.h" |  | ||||||
| #include "../helpers/key-info.h" |  | ||||||
| 
 |  | ||||||
| void LfrfidSceneReadNormal::on_enter(LfrfidApp* app) { |  | ||||||
|     LfrfidAppViewManager* view_manager = app->get_view_manager(); |  | ||||||
| 
 |  | ||||||
|     Popup* popup = view_manager->get_popup(); |  | ||||||
|     popup_set_header(popup, "LF-RFID read EM & HID", 64, 16, AlignCenter, AlignBottom); |  | ||||||
|     app->set_text_store("waiting..."); |  | ||||||
|     popup_set_text(popup, app->get_text_store(), 64, 22, AlignCenter, AlignTop); |  | ||||||
| 
 |  | ||||||
|     view_manager->switch_to(LfrfidAppViewManager::ViewType::Popup); |  | ||||||
|     app->get_reader()->start(RfidReader::Type::Normal); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool LfrfidSceneReadNormal::on_event(LfrfidApp* app, LfrfidEvent* event) { |  | ||||||
|     bool consumed = false; |  | ||||||
| 
 |  | ||||||
|     if(event->type == LfrfidEvent::Type::Tick) { |  | ||||||
|         uint8_t data[data_size]; |  | ||||||
|         LfrfidKeyType type; |  | ||||||
| 
 |  | ||||||
|         if(app->get_reader()->read(&type, data, data_size)) { |  | ||||||
|             if(memcmp(last_data, data, data_size) == 0) { |  | ||||||
|                 success_reads++; |  | ||||||
|                 app->notify_green_blink(); |  | ||||||
|             } else { |  | ||||||
|                 success_reads = 1; |  | ||||||
|                 memcpy(last_data, data, data_size); |  | ||||||
|                 app->notify_success(); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             switch(type) { |  | ||||||
|             case LfrfidKeyType::KeyEM4100: |  | ||||||
|                 app->set_text_store( |  | ||||||
|                     "[EM] %02X %02X %02X %02X %02X\n" |  | ||||||
|                     "count: %u", |  | ||||||
|                     data[0], |  | ||||||
|                     data[1], |  | ||||||
|                     data[2], |  | ||||||
|                     data[3], |  | ||||||
|                     data[4], |  | ||||||
|                     success_reads); |  | ||||||
|                 break; |  | ||||||
|             case LfrfidKeyType::KeyH10301: |  | ||||||
|                 app->set_text_store( |  | ||||||
|                     "[HID26] %02X %02X %02X\n" |  | ||||||
|                     "count: %u", |  | ||||||
|                     data[0], |  | ||||||
|                     data[1], |  | ||||||
|                     data[2], |  | ||||||
|                     success_reads); |  | ||||||
|                 break; |  | ||||||
|             case LfrfidKeyType::KeyI40134: |  | ||||||
|                 app->set_text_store( |  | ||||||
|                     "[IND] %02X %02X %02X\n" |  | ||||||
|                     "count: %u", |  | ||||||
|                     data[0], |  | ||||||
|                     data[1], |  | ||||||
|                     data[2], |  | ||||||
|                     success_reads); |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|             popup_set_text( |  | ||||||
|                 app->get_view_manager()->get_popup(), |  | ||||||
|                 app->get_text_store(), |  | ||||||
|                 64, |  | ||||||
|                 22, |  | ||||||
|                 AlignCenter, |  | ||||||
|                 AlignTop); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return consumed; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void LfrfidSceneReadNormal::on_exit(LfrfidApp* app) { |  | ||||||
|     LfrfidAppViewManager* view_manager = app->get_view_manager(); |  | ||||||
| 
 |  | ||||||
|     Popup* popup = view_manager->get_popup(); |  | ||||||
|     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); |  | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |  | ||||||
| 
 |  | ||||||
|     app->get_reader()->stop(); |  | ||||||
| } |  | ||||||
| @ -1,15 +0,0 @@ | |||||||
| #pragma once |  | ||||||
| #include "lf-rfid-scene-generic.h" |  | ||||||
| #include "../helpers/key-info.h" |  | ||||||
| 
 |  | ||||||
| class LfrfidSceneReadNormal : public LfrfidScene { |  | ||||||
| public: |  | ||||||
|     void on_enter(LfrfidApp* app) final; |  | ||||||
|     bool on_event(LfrfidApp* app, LfrfidEvent* event) final; |  | ||||||
|     void on_exit(LfrfidApp* app) final; |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     uint32_t success_reads = 0; |  | ||||||
|     static const uint8_t data_size = LFRFID_KEY_SIZE; |  | ||||||
|     uint8_t last_data[data_size] = {0}; |  | ||||||
| }; |  | ||||||
| @ -1,82 +0,0 @@ | |||||||
| #include "lf-rfid-scene-start.h" |  | ||||||
| #include "../lf-rfid-app.h" |  | ||||||
| #include "../lf-rfid-view-manager.h" |  | ||||||
| #include "../lf-rfid-event.h" |  | ||||||
| #include <callback-connector.h> |  | ||||||
| 
 |  | ||||||
| typedef enum { |  | ||||||
|     SubmenuIndexWrite, |  | ||||||
|     SubmenuIndexReadNormal, |  | ||||||
|     SubmenuIndexReadIndala, |  | ||||||
|     SubmenuIndexEmulateEM, |  | ||||||
|     SubmenuIndexEmulateHID, |  | ||||||
|     SubmenuIndexEmulateIndala, |  | ||||||
|     SubmenuIndexTune |  | ||||||
| } SubmenuIndex; |  | ||||||
| 
 |  | ||||||
| void LfrfidSceneStart::on_enter(LfrfidApp* app) { |  | ||||||
|     LfrfidAppViewManager* view_manager = app->get_view_manager(); |  | ||||||
|     Submenu* submenu = view_manager->get_submenu(); |  | ||||||
|     auto callback = cbc::obtain_connector(this, &LfrfidSceneStart::submenu_callback); |  | ||||||
| 
 |  | ||||||
|     submenu_add_item(submenu, "Write T5577", SubmenuIndexWrite, callback, app); |  | ||||||
|     submenu_add_item(submenu, "Read Normal", SubmenuIndexReadNormal, callback, app); |  | ||||||
|     submenu_add_item(submenu, "Read Indala", SubmenuIndexReadIndala, callback, app); |  | ||||||
|     submenu_add_item(submenu, "Emulate EM", SubmenuIndexEmulateEM, callback, app); |  | ||||||
|     submenu_add_item(submenu, "Emulate HID", SubmenuIndexEmulateHID, callback, app); |  | ||||||
|     submenu_add_item(submenu, "Emulate Indala", SubmenuIndexEmulateIndala, callback, app); |  | ||||||
|     submenu_add_item(submenu, "Tune", SubmenuIndexTune, callback, app); |  | ||||||
| 
 |  | ||||||
|     view_manager->switch_to(LfrfidAppViewManager::ViewType::Submenu); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool LfrfidSceneStart::on_event(LfrfidApp* app, LfrfidEvent* event) { |  | ||||||
|     bool consumed = false; |  | ||||||
| 
 |  | ||||||
|     if(event->type == LfrfidEvent::Type::MenuSelected) { |  | ||||||
|         switch(event->payload.menu_index) { |  | ||||||
|         case SubmenuIndexWrite: |  | ||||||
|             app->switch_to_next_scene(LfrfidApp::Scene::Write); |  | ||||||
|             break; |  | ||||||
|         case SubmenuIndexReadNormal: |  | ||||||
|             app->switch_to_next_scene(LfrfidApp::Scene::ReadNormal); |  | ||||||
|             break; |  | ||||||
|         case SubmenuIndexReadIndala: |  | ||||||
|             app->switch_to_next_scene(LfrfidApp::Scene::ReadIndala); |  | ||||||
|             break; |  | ||||||
|         case SubmenuIndexEmulateEM: |  | ||||||
|             app->switch_to_next_scene(LfrfidApp::Scene::EmulateEM); |  | ||||||
|             break; |  | ||||||
|             break; |  | ||||||
|         case SubmenuIndexEmulateHID: |  | ||||||
|             app->switch_to_next_scene(LfrfidApp::Scene::EmulateHID); |  | ||||||
|             break; |  | ||||||
|         case SubmenuIndexEmulateIndala: |  | ||||||
|             app->switch_to_next_scene(LfrfidApp::Scene::EmulateIndala); |  | ||||||
|             break; |  | ||||||
|         case SubmenuIndexTune: |  | ||||||
|             app->switch_to_next_scene(LfrfidApp::Scene::Tune); |  | ||||||
|             break; |  | ||||||
|         } |  | ||||||
|         consumed = true; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return consumed; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void LfrfidSceneStart::on_exit(LfrfidApp* app) { |  | ||||||
|     LfrfidAppViewManager* view_manager = app->get_view_manager(); |  | ||||||
|     Submenu* submenu = view_manager->get_submenu(); |  | ||||||
| 
 |  | ||||||
|     submenu_clean(submenu); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void LfrfidSceneStart::submenu_callback(void* context, uint32_t index) { |  | ||||||
|     LfrfidApp* app = static_cast<LfrfidApp*>(context); |  | ||||||
|     LfrfidEvent event; |  | ||||||
| 
 |  | ||||||
|     event.type = LfrfidEvent::Type::MenuSelected; |  | ||||||
|     event.payload.menu_index = index; |  | ||||||
| 
 |  | ||||||
|     app->get_view_manager()->send_event(&event); |  | ||||||
| } |  | ||||||
| @ -1,13 +0,0 @@ | |||||||
| #pragma once |  | ||||||
| #include "lf-rfid-scene-generic.h" |  | ||||||
| #include "../helpers/rfid-timer-emulator.h" |  | ||||||
| 
 |  | ||||||
| class LfrfidSceneStart : public LfrfidScene { |  | ||||||
| public: |  | ||||||
|     void on_enter(LfrfidApp* app) final; |  | ||||||
|     bool on_event(LfrfidApp* app, LfrfidEvent* event) final; |  | ||||||
|     void on_exit(LfrfidApp* app) final; |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     void submenu_callback(void* context, uint32_t index); |  | ||||||
| }; |  | ||||||
| @ -1,35 +0,0 @@ | |||||||
| #include "lf-rfid-scene-tune.h" |  | ||||||
| #include "../lf-rfid-app.h" |  | ||||||
| #include "../lf-rfid-view-manager.h" |  | ||||||
| #include "../lf-rfid-event.h" |  | ||||||
| #include <callback-connector.h> |  | ||||||
| 
 |  | ||||||
| void LfrfidSceneTune::on_enter(LfrfidApp* app) { |  | ||||||
|     LfrfidAppViewManager* view_manager = app->get_view_manager(); |  | ||||||
|     //LfRfidViewTune* tune = view_manager->get_tune();
 |  | ||||||
| 
 |  | ||||||
|     view_manager->switch_to(LfrfidAppViewManager::ViewType::Tune); |  | ||||||
| 
 |  | ||||||
|     reader.start(RfidReader::Type::Indala); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool LfrfidSceneTune::on_event(LfrfidApp* app, LfrfidEvent* event) { |  | ||||||
|     bool consumed = false; |  | ||||||
| 
 |  | ||||||
|     if(event->type == LfrfidEvent::Type::Tick) { |  | ||||||
|         LfRfidViewTune* tune = app->get_view_manager()->get_tune(); |  | ||||||
| 
 |  | ||||||
|         if(tune->is_dirty()) { |  | ||||||
|             LFRFID_TIM.Instance->ARR = tune->get_ARR(); |  | ||||||
|             LFRFID_TIM.Instance->CCR1 = tune->get_CCR(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return consumed; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void LfrfidSceneTune::on_exit(LfrfidApp* app) { |  | ||||||
|     //LfRfidViewTune* tune = app->get_view_manager()->get_tune();
 |  | ||||||
| 
 |  | ||||||
|     reader.stop(); |  | ||||||
| } |  | ||||||
| @ -1,13 +0,0 @@ | |||||||
| #pragma once |  | ||||||
| #include "lf-rfid-scene-generic.h" |  | ||||||
| #include "../helpers/rfid-reader.h" |  | ||||||
| 
 |  | ||||||
| class LfrfidSceneTune : public LfrfidScene { |  | ||||||
| public: |  | ||||||
|     void on_enter(LfrfidApp* app) final; |  | ||||||
|     bool on_event(LfrfidApp* app, LfrfidEvent* event) final; |  | ||||||
|     void on_exit(LfrfidApp* app) final; |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     RfidReader reader; |  | ||||||
| }; |  | ||||||
| @ -1,70 +0,0 @@ | |||||||
| #include "lf-rfid-scene-write.h" |  | ||||||
| 
 |  | ||||||
| #include "../lf-rfid-app.h" |  | ||||||
| #include "../lf-rfid-view-manager.h" |  | ||||||
| #include "../lf-rfid-event.h" |  | ||||||
| #include "../helpers/key-info.h" |  | ||||||
| 
 |  | ||||||
| void LfrfidSceneWrite::on_enter(LfrfidApp* app) { |  | ||||||
|     LfrfidAppViewManager* view_manager = app->get_view_manager(); |  | ||||||
| 
 |  | ||||||
|     Popup* popup = view_manager->get_popup(); |  | ||||||
|     popup_set_header(popup, "LF-RFID", 64, 16, AlignCenter, AlignBottom); |  | ||||||
|     app->set_text_store("Writing..."); |  | ||||||
|     popup_set_text(popup, app->get_text_store(), 64, 22, AlignCenter, AlignTop); |  | ||||||
| 
 |  | ||||||
|     view_manager->switch_to(LfrfidAppViewManager::ViewType::Popup); |  | ||||||
| 
 |  | ||||||
|     timing_index = 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool LfrfidSceneWrite::on_event(LfrfidApp* app, LfrfidEvent* event) { |  | ||||||
|     bool consumed = false; |  | ||||||
| 
 |  | ||||||
|     // TODO move read\write logic to key worker
 |  | ||||||
| 
 |  | ||||||
|     bool readed = false; |  | ||||||
|     uint8_t em_data[5] = {0x1A, 0x2B, 0xC3, 0xD4, 0xE5}; |  | ||||||
| 
 |  | ||||||
|     if(timing_index == 0) { |  | ||||||
|         app->get_reader()->stop(); |  | ||||||
|         app->get_writer()->start(); |  | ||||||
|         app->get_writer()->write_em(em_data); |  | ||||||
|         app->get_writer()->stop(); |  | ||||||
|         delay(200); |  | ||||||
|         app->get_reader()->start(RfidReader::Type::Normal); |  | ||||||
|     } else { |  | ||||||
|         uint8_t data[LFRFID_KEY_SIZE]; |  | ||||||
|         LfrfidKeyType type; |  | ||||||
| 
 |  | ||||||
|         app->get_reader()->read(&type, data, LFRFID_KEY_SIZE); |  | ||||||
|         if(type == LfrfidKeyType::KeyEM4100) { |  | ||||||
|             if(memcmp(em_data, data, 5) == 0) { |  | ||||||
|                 readed = true; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if(readed) { |  | ||||||
|         app->set_text_store("Writed!"); |  | ||||||
|         app->notify_green_blink(); |  | ||||||
|     } else { |  | ||||||
|         app->set_text_store("Writing [1A 2B C3 D4 E5]"); |  | ||||||
|         timing_index++; |  | ||||||
|         if(timing_index == 4) { |  | ||||||
|             timing_index = 0; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     popup_set_text( |  | ||||||
|         app->get_view_manager()->get_popup(), app->get_text_store(), 64, 22, AlignCenter, AlignTop); |  | ||||||
| 
 |  | ||||||
|     return consumed; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void LfrfidSceneWrite::on_exit(LfrfidApp* app) { |  | ||||||
|     LfrfidAppViewManager* view_manager = app->get_view_manager(); |  | ||||||
| 
 |  | ||||||
|     Popup* popup = view_manager->get_popup(); |  | ||||||
|     popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); |  | ||||||
|     popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); |  | ||||||
| } |  | ||||||
| @ -1,14 +0,0 @@ | |||||||
| #pragma once |  | ||||||
| #include "lf-rfid-scene-generic.h" |  | ||||||
| #include "../helpers/key-info.h" |  | ||||||
| #include "../helpers/rfid-writer.h" |  | ||||||
| 
 |  | ||||||
| class LfrfidSceneWrite : public LfrfidScene { |  | ||||||
| public: |  | ||||||
|     void on_enter(LfrfidApp* app) final; |  | ||||||
|     bool on_event(LfrfidApp* app, LfrfidEvent* event) final; |  | ||||||
|     void on_exit(LfrfidApp* app) final; |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     uint8_t timing_index; |  | ||||||
| }; |  | ||||||
							
								
								
									
										10
									
								
								applications/lfrfid-debug/lfrfid-debug-app-launcher.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								applications/lfrfid-debug/lfrfid-debug-app-launcher.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | #include "lfrfid-debug-app.h" | ||||||
|  | 
 | ||||||
|  | // app enter function
 | ||||||
|  | extern "C" int32_t lfrfid_debug_app(void* p) { | ||||||
|  |     LfRfidDebugApp* app = new LfRfidDebugApp(); | ||||||
|  |     app->run(); | ||||||
|  |     delete app; | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								applications/lfrfid-debug/lfrfid-debug-app.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								applications/lfrfid-debug/lfrfid-debug-app.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | #include "lfrfid-debug-app.h" | ||||||
|  | #include "scene/lfrfid-debug-app-scene-start.h" | ||||||
|  | #include "scene/lfrfid-debug-app-scene-tune.h" | ||||||
|  | 
 | ||||||
|  | LfRfidDebugApp::LfRfidDebugApp() | ||||||
|  |     : scene_controller{this} { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | LfRfidDebugApp::~LfRfidDebugApp() { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void LfRfidDebugApp::run() { | ||||||
|  |     scene_controller.add_scene(SceneType::Start, new LfRfidDebugAppSceneStart()); | ||||||
|  |     scene_controller.add_scene(SceneType::TuneScene, new LfRfidDebugAppSceneTune()); | ||||||
|  |     scene_controller.process(100); | ||||||
|  | } | ||||||
							
								
								
									
										40
									
								
								applications/lfrfid-debug/lfrfid-debug-app.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								applications/lfrfid-debug/lfrfid-debug-app.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | |||||||
|  | #pragma once | ||||||
|  | #include <furi.h> | ||||||
|  | #include <api-hal.h> | ||||||
|  | 
 | ||||||
|  | #include <generic-scene.hpp> | ||||||
|  | #include <scene-controller.hpp> | ||||||
|  | #include <view-controller.hpp> | ||||||
|  | 
 | ||||||
|  | #include <view-modules/submenu-vm.h> | ||||||
|  | #include "view-modules/lfrfid-view-tune-vm.h" | ||||||
|  | 
 | ||||||
|  | class LfRfidDebugApp { | ||||||
|  | public: | ||||||
|  |     enum class EventType : uint8_t { | ||||||
|  |         GENERIC_EVENT_ENUM_VALUES, | ||||||
|  |         MenuSelected, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     enum class SceneType : uint8_t { | ||||||
|  |         GENERIC_SCENE_ENUM_VALUES, | ||||||
|  |         TuneScene, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     class Event { | ||||||
|  |     public: | ||||||
|  |         union { | ||||||
|  |             int32_t menu_index; | ||||||
|  |         } payload; | ||||||
|  | 
 | ||||||
|  |         EventType type; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     SceneController<GenericScene<LfRfidDebugApp>, LfRfidDebugApp> scene_controller; | ||||||
|  |     ViewController<LfRfidDebugApp, SubmenuVM, LfRfidViewTuneVM> view_controller; | ||||||
|  | 
 | ||||||
|  |     ~LfRfidDebugApp(); | ||||||
|  |     LfRfidDebugApp(); | ||||||
|  | 
 | ||||||
|  |     void run(); | ||||||
|  | }; | ||||||
| @ -0,0 +1,47 @@ | |||||||
|  | #include "lfrfid-debug-app-scene-start.h" | ||||||
|  | 
 | ||||||
|  | typedef enum { | ||||||
|  |     SubmenuTune, | ||||||
|  | } SubmenuIndex; | ||||||
|  | 
 | ||||||
|  | void LfRfidDebugAppSceneStart::on_enter(LfRfidDebugApp* app, bool need_restore) { | ||||||
|  |     auto submenu = app->view_controller.get<SubmenuVM>(); | ||||||
|  |     auto callback = cbc::obtain_connector(this, &LfRfidDebugAppSceneStart::submenu_callback); | ||||||
|  | 
 | ||||||
|  |     submenu->add_item("Tune", SubmenuTune, callback, app); | ||||||
|  | 
 | ||||||
|  |     if(need_restore) { | ||||||
|  |         submenu->set_selected_item(submenu_item_selected); | ||||||
|  |     } | ||||||
|  |     app->view_controller.switch_to<SubmenuVM>(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool LfRfidDebugAppSceneStart::on_event(LfRfidDebugApp* app, LfRfidDebugApp::Event* event) { | ||||||
|  |     bool consumed = false; | ||||||
|  | 
 | ||||||
|  |     if(event->type == LfRfidDebugApp::EventType::MenuSelected) { | ||||||
|  |         submenu_item_selected = event->payload.menu_index; | ||||||
|  |         switch(event->payload.menu_index) { | ||||||
|  |         case SubmenuTune: | ||||||
|  |             app->scene_controller.switch_to_next_scene(LfRfidDebugApp::SceneType::TuneScene); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         consumed = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return consumed; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void LfRfidDebugAppSceneStart::on_exit(LfRfidDebugApp* app) { | ||||||
|  |     app->view_controller.get<SubmenuVM>()->clean(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void LfRfidDebugAppSceneStart::submenu_callback(void* context, uint32_t index) { | ||||||
|  |     LfRfidDebugApp* app = static_cast<LfRfidDebugApp*>(context); | ||||||
|  |     LfRfidDebugApp::Event event; | ||||||
|  | 
 | ||||||
|  |     event.type = LfRfidDebugApp::EventType::MenuSelected; | ||||||
|  |     event.payload.menu_index = index; | ||||||
|  | 
 | ||||||
|  |     app->view_controller.send_event(&event); | ||||||
|  | } | ||||||
| @ -0,0 +1,13 @@ | |||||||
|  | #pragma once | ||||||
|  | #include "../lfrfid-debug-app.h" | ||||||
|  | 
 | ||||||
|  | class LfRfidDebugAppSceneStart : public GenericScene<LfRfidDebugApp> { | ||||||
|  | public: | ||||||
|  |     void on_enter(LfRfidDebugApp* app, bool need_restore) final; | ||||||
|  |     bool on_event(LfRfidDebugApp* app, LfRfidDebugApp::Event* event) final; | ||||||
|  |     void on_exit(LfRfidDebugApp* app) final; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     void submenu_callback(void* context, uint32_t index); | ||||||
|  |     uint32_t submenu_item_selected = 0; | ||||||
|  | }; | ||||||
| @ -0,0 +1,28 @@ | |||||||
|  | #include "lfrfid-debug-app-scene-tune.h" | ||||||
|  | 
 | ||||||
|  | void LfRfidDebugAppSceneTune::on_enter(LfRfidDebugApp* app, bool need_restore) { | ||||||
|  |     app->view_controller.switch_to<LfRfidViewTuneVM>(); | ||||||
|  | 
 | ||||||
|  |     api_hal_rfid_pins_read(); | ||||||
|  |     api_hal_rfid_tim_read(125000, 0.5); | ||||||
|  |     api_hal_rfid_tim_read_start(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool LfRfidDebugAppSceneTune::on_event(LfRfidDebugApp* app, LfRfidDebugApp::Event* event) { | ||||||
|  |     bool consumed = false; | ||||||
|  | 
 | ||||||
|  |     LfRfidViewTuneVM* tune = app->view_controller; | ||||||
|  | 
 | ||||||
|  |     if(tune->is_dirty()) { | ||||||
|  |         api_hal_rfid_set_read_period(tune->get_ARR()); | ||||||
|  |         api_hal_rfid_set_read_pulse(tune->get_CCR()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return consumed; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void LfRfidDebugAppSceneTune::on_exit(LfRfidDebugApp* app) { | ||||||
|  |     api_hal_rfid_tim_read_stop(); | ||||||
|  |     api_hal_rfid_tim_reset(); | ||||||
|  |     api_hal_rfid_pins_reset(); | ||||||
|  | } | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | #pragma once | ||||||
|  | #include "../lfrfid-debug-app.h" | ||||||
|  | 
 | ||||||
|  | class LfRfidDebugAppSceneTune : public GenericScene<LfRfidDebugApp> { | ||||||
|  | public: | ||||||
|  |     void on_enter(LfRfidDebugApp* app, bool need_restore) final; | ||||||
|  |     bool on_event(LfRfidDebugApp* app, LfRfidDebugApp::Event* event) final; | ||||||
|  |     void on_exit(LfRfidDebugApp* app) final; | ||||||
|  | }; | ||||||
| @ -1,10 +1,8 @@ | |||||||
| #include "lf-rfid-view-tune.h" | #include "lfrfid-view-tune-vm.h" | ||||||
| #include <callback-connector.h> | #include <callback-connector.h> | ||||||
| #include <gui/elements.h> | #include <gui/elements.h> | ||||||
| #include <variant> |  | ||||||
| #include <list> |  | ||||||
| 
 | 
 | ||||||
| struct LfRfidViewTuneModel { | struct LfRfidViewTuneVMModel { | ||||||
|     bool dirty; |     bool dirty; | ||||||
|     bool fine; |     bool fine; | ||||||
|     uint32_t ARR; |     uint32_t ARR; | ||||||
| @ -12,8 +10,8 @@ struct LfRfidViewTuneModel { | |||||||
|     int pos; |     int pos; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| void LfRfidViewTune::view_draw_callback(Canvas* canvas, void* _model) { | void LfRfidViewTuneVM::view_draw_callback(Canvas* canvas, void* _model) { | ||||||
|     LfRfidViewTuneModel* model = reinterpret_cast<LfRfidViewTuneModel*>(_model); |     LfRfidViewTuneVMModel* model = reinterpret_cast<LfRfidViewTuneVMModel*>(_model); | ||||||
|     canvas_clear(canvas); |     canvas_clear(canvas); | ||||||
|     canvas_set_color(canvas, ColorBlack); |     canvas_set_color(canvas, ColorBlack); | ||||||
| 
 | 
 | ||||||
| @ -47,8 +45,8 @@ void LfRfidViewTune::view_draw_callback(Canvas* canvas, void* _model) { | |||||||
|     elements_multiline_text_aligned(canvas, 2, 2, AlignLeft, AlignTop, buffer); |     elements_multiline_text_aligned(canvas, 2, 2, AlignLeft, AlignTop, buffer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool LfRfidViewTune::view_input_callback(InputEvent* event, void* context) { | bool LfRfidViewTuneVM::view_input_callback(InputEvent* event, void* context) { | ||||||
|     LfRfidViewTune* _this = reinterpret_cast<LfRfidViewTune*>(context); |     LfRfidViewTuneVM* _this = reinterpret_cast<LfRfidViewTuneVM*>(context); | ||||||
|     bool consumed = false; |     bool consumed = false; | ||||||
| 
 | 
 | ||||||
|     // Process key presses only
 |     // Process key presses only
 | ||||||
| @ -80,22 +78,22 @@ bool LfRfidViewTune::view_input_callback(InputEvent* event, void* context) { | |||||||
|     return consumed; |     return consumed; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void LfRfidViewTune::button_up() { | void LfRfidViewTuneVM::button_up() { | ||||||
|     with_view_model_cpp(view, LfRfidViewTuneModel, model, { |     with_view_model_cpp(view, LfRfidViewTuneVMModel, model, { | ||||||
|         if(model->pos > 0) model->pos--; |         if(model->pos > 0) model->pos--; | ||||||
|         return true; |         return true; | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void LfRfidViewTune::button_down() { | void LfRfidViewTuneVM::button_down() { | ||||||
|     with_view_model_cpp(view, LfRfidViewTuneModel, model, { |     with_view_model_cpp(view, LfRfidViewTuneVMModel, model, { | ||||||
|         if(model->pos < 1) model->pos++; |         if(model->pos < 1) model->pos++; | ||||||
|         return true; |         return true; | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void LfRfidViewTune::button_left() { | void LfRfidViewTuneVM::button_left() { | ||||||
|     with_view_model_cpp(view, LfRfidViewTuneModel, model, { |     with_view_model_cpp(view, LfRfidViewTuneVMModel, model, { | ||||||
|         if(model->pos == 0) { |         if(model->pos == 0) { | ||||||
|             if(model->fine) { |             if(model->fine) { | ||||||
|                 model->ARR -= 1; |                 model->ARR -= 1; | ||||||
| @ -115,8 +113,8 @@ void LfRfidViewTune::button_left() { | |||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void LfRfidViewTune::button_right() { | void LfRfidViewTuneVM::button_right() { | ||||||
|     with_view_model_cpp(view, LfRfidViewTuneModel, model, { |     with_view_model_cpp(view, LfRfidViewTuneVMModel, model, { | ||||||
|         if(model->pos == 0) { |         if(model->pos == 0) { | ||||||
|             if(model->fine) { |             if(model->fine) { | ||||||
|                 model->ARR += 1; |                 model->ARR += 1; | ||||||
| @ -136,19 +134,19 @@ void LfRfidViewTune::button_right() { | |||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void LfRfidViewTune::button_ok() { | void LfRfidViewTuneVM::button_ok() { | ||||||
|     with_view_model_cpp(view, LfRfidViewTuneModel, model, { |     with_view_model_cpp(view, LfRfidViewTuneVMModel, model, { | ||||||
|         model->fine = !model->fine; |         model->fine = !model->fine; | ||||||
|         return true; |         return true; | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| LfRfidViewTune::LfRfidViewTune() { | LfRfidViewTuneVM::LfRfidViewTuneVM() { | ||||||
|     view = view_alloc(); |     view = view_alloc(); | ||||||
|     view_set_context(view, this); |     view_set_context(view, this); | ||||||
|     view_allocate_model(view, ViewModelTypeLocking, sizeof(LfRfidViewTuneModel)); |     view_allocate_model(view, ViewModelTypeLocking, sizeof(LfRfidViewTuneVMModel)); | ||||||
| 
 | 
 | ||||||
|     with_view_model_cpp(view, LfRfidViewTuneModel, model, { |     with_view_model_cpp(view, LfRfidViewTuneVMModel, model, { | ||||||
|         model->dirty = true; |         model->dirty = true; | ||||||
|         model->fine = false; |         model->fine = false; | ||||||
|         model->ARR = 511; |         model->ARR = 511; | ||||||
| @ -157,22 +155,34 @@ LfRfidViewTune::LfRfidViewTune() { | |||||||
|         return true; |         return true; | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     view_set_draw_callback(view, cbc::obtain_connector(this, &LfRfidViewTune::view_draw_callback)); |     view_set_draw_callback( | ||||||
|  |         view, cbc::obtain_connector(this, &LfRfidViewTuneVM::view_draw_callback)); | ||||||
|     view_set_input_callback( |     view_set_input_callback( | ||||||
|         view, cbc::obtain_connector(this, &LfRfidViewTune::view_input_callback)); |         view, cbc::obtain_connector(this, &LfRfidViewTuneVM::view_input_callback)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| LfRfidViewTune::~LfRfidViewTune() { | LfRfidViewTuneVM::~LfRfidViewTuneVM() { | ||||||
|     view_free(view); |     view_free(view); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| View* LfRfidViewTune::get_view() { | View* LfRfidViewTuneVM::get_view() { | ||||||
|     return view; |     return view; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool LfRfidViewTune::is_dirty() { | void LfRfidViewTuneVM::clean() { | ||||||
|  |     with_view_model_cpp(view, LfRfidViewTuneVMModel, model, { | ||||||
|  |         model->dirty = true; | ||||||
|  |         model->fine = false; | ||||||
|  |         model->ARR = 511; | ||||||
|  |         model->CCR = 255; | ||||||
|  |         model->pos = 0; | ||||||
|  |         return true; | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool LfRfidViewTuneVM::is_dirty() { | ||||||
|     bool result; |     bool result; | ||||||
|     with_view_model_cpp(view, LfRfidViewTuneModel, model, { |     with_view_model_cpp(view, LfRfidViewTuneVMModel, model, { | ||||||
|         result = model->dirty; |         result = model->dirty; | ||||||
|         model->dirty = false; |         model->dirty = false; | ||||||
|         return false; |         return false; | ||||||
| @ -181,9 +191,9 @@ bool LfRfidViewTune::is_dirty() { | |||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint32_t LfRfidViewTune::get_ARR() { | uint32_t LfRfidViewTuneVM::get_ARR() { | ||||||
|     uint32_t result; |     uint32_t result; | ||||||
|     with_view_model_cpp(view, LfRfidViewTuneModel, model, { |     with_view_model_cpp(view, LfRfidViewTuneVMModel, model, { | ||||||
|         result = model->ARR; |         result = model->ARR; | ||||||
|         return false; |         return false; | ||||||
|     }); |     }); | ||||||
| @ -191,9 +201,9 @@ uint32_t LfRfidViewTune::get_ARR() { | |||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint32_t LfRfidViewTune::get_CCR() { | uint32_t LfRfidViewTuneVM::get_CCR() { | ||||||
|     uint32_t result; |     uint32_t result; | ||||||
|     with_view_model_cpp(view, LfRfidViewTuneModel, model, { |     with_view_model_cpp(view, LfRfidViewTuneVMModel, model, { | ||||||
|         result = model->CCR; |         result = model->CCR; | ||||||
|         return false; |         return false; | ||||||
|     }); |     }); | ||||||
| @ -1,12 +1,13 @@ | |||||||
| #pragma once | #pragma once | ||||||
| #include <gui/view.h> | #include <gui/view.h> | ||||||
|  | #include <view-modules/generic-view-module.h> | ||||||
| 
 | 
 | ||||||
| class LfRfidViewTune { | class LfRfidViewTuneVM : public GenericViewModule { | ||||||
| public: | public: | ||||||
|     LfRfidViewTune(); |     LfRfidViewTuneVM(); | ||||||
|     ~LfRfidViewTune(); |     ~LfRfidViewTuneVM() final; | ||||||
| 
 |     View* get_view() final; | ||||||
|     View* get_view(); |     void clean() final; | ||||||
| 
 | 
 | ||||||
|     bool is_dirty(); |     bool is_dirty(); | ||||||
|     uint32_t get_ARR(); |     uint32_t get_ARR(); | ||||||
| @ -2,6 +2,7 @@ | |||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| 
 | 
 | ||||||
| static const uint8_t LFRFID_KEY_SIZE = 8; | static const uint8_t LFRFID_KEY_SIZE = 8; | ||||||
|  | static const uint8_t LFRFID_KEY_NAME_SIZE = 22; | ||||||
| 
 | 
 | ||||||
| enum class LfrfidKeyType : uint8_t { | enum class LfrfidKeyType : uint8_t { | ||||||
|     KeyEM4100, |     KeyEM4100, | ||||||
							
								
								
									
										44
									
								
								applications/lfrfid/helpers/rfid-key.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								applications/lfrfid/helpers/rfid-key.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | |||||||
|  | #include "rfid-key.h" | ||||||
|  | #include <furi/check.h> | ||||||
|  | 
 | ||||||
|  | RfidKey::RfidKey() { | ||||||
|  |     data.fill(0); | ||||||
|  | 
 | ||||||
|  |     for(uint8_t i = 0; i < (LFRFID_KEY_NAME_SIZE + 1); i++) { | ||||||
|  |         name[i] = 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | RfidKey::~RfidKey() { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RfidKey::set_type(LfrfidKeyType _type) { | ||||||
|  |     type = _type; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RfidKey::set_data(uint8_t* _data, const uint8_t _data_size) { | ||||||
|  |     furi_assert(_data_size <= data.size()); | ||||||
|  |     for(uint8_t i = 0; i < _data_size; i++) { | ||||||
|  |         data[i] = _data[i]; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | LfrfidKeyType RfidKey::get_type() { | ||||||
|  |     return type; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t* RfidKey::get_data() { | ||||||
|  |     return &data[0]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const char* RfidKey::get_type_text() { | ||||||
|  |     return lfrfid_key_get_type_string(type); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const uint8_t RfidKey::get_type_data_count() { | ||||||
|  |     return lfrfid_key_get_type_data_count(type); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char* RfidKey::get_name() { | ||||||
|  |     return name; | ||||||
|  | } | ||||||
							
								
								
									
										25
									
								
								applications/lfrfid/helpers/rfid-key.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								applications/lfrfid/helpers/rfid-key.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  | #pragma once | ||||||
|  | #include "key-info.h" | ||||||
|  | #include <array> | ||||||
|  | 
 | ||||||
|  | class RfidKey { | ||||||
|  | public: | ||||||
|  |     RfidKey(); | ||||||
|  |     ~RfidKey(); | ||||||
|  | 
 | ||||||
|  |     void set_type(LfrfidKeyType type); | ||||||
|  |     void set_data(uint8_t* data, const uint8_t data_size); | ||||||
|  | 
 | ||||||
|  |     LfrfidKeyType get_type(); | ||||||
|  |     uint8_t* get_data(); | ||||||
|  | 
 | ||||||
|  |     const char* get_type_text(); | ||||||
|  |     const uint8_t get_type_data_count(); | ||||||
|  | 
 | ||||||
|  |     char* get_name(); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     std::array<uint8_t, LFRFID_KEY_SIZE> data; | ||||||
|  |     LfrfidKeyType type; | ||||||
|  |     char name[LFRFID_KEY_NAME_SIZE + 1]; | ||||||
|  | }; | ||||||
							
								
								
									
										35
									
								
								applications/lfrfid/helpers/rfid-name-generator.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								applications/lfrfid/helpers/rfid-name-generator.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | #include "rfid-name-generator.h" | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | 
 | ||||||
|  | void rfid_generate_random_name(char* name, uint8_t max_name_size) { | ||||||
|  |     const uint8_t prefix_size = 9; | ||||||
|  |     const char* prefix[prefix_size] = { | ||||||
|  |         "good", | ||||||
|  |         "nice", | ||||||
|  |         "best", | ||||||
|  |         "some", | ||||||
|  |         "strange", | ||||||
|  |         "working", | ||||||
|  |         "that", | ||||||
|  |         "forgettable", | ||||||
|  |         "easy", | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     const uint8_t suffix_size = 7; | ||||||
|  |     const char* suffix[suffix_size] = { | ||||||
|  |         "pass", | ||||||
|  |         "card", | ||||||
|  |         "key", | ||||||
|  |         "fob", | ||||||
|  |         "permit", | ||||||
|  |         "pass", | ||||||
|  |         "one", | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     sniprintf( | ||||||
|  |         name, max_name_size, "%s_%s", prefix[rand() % prefix_size], suffix[rand() % suffix_size]); | ||||||
|  | 
 | ||||||
|  |     // to upper
 | ||||||
|  |     name[0] = name[0] - ('a' - 'A'); | ||||||
|  | } | ||||||
							
								
								
									
										4
									
								
								applications/lfrfid/helpers/rfid-name-generator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								applications/lfrfid/helpers/rfid-name-generator.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | #pragma once | ||||||
|  | #include "stdint.h" | ||||||
|  | 
 | ||||||
|  | void rfid_generate_random_name(char* name, uint8_t max_name_size); | ||||||
| @ -18,7 +18,7 @@ void RfidTimerEmulator::start(LfrfidKeyType type, const uint8_t* data, uint8_t d | |||||||
|     if(encoders.count(type)) { |     if(encoders.count(type)) { | ||||||
|         current_encoder = encoders.find(type)->second; |         current_encoder = encoders.find(type)->second; | ||||||
| 
 | 
 | ||||||
|         if(lfrfid_key_get_type_data_count(type) == data_size) { |         if(data_size >= lfrfid_key_get_type_data_count(type)) { | ||||||
|             current_encoder->init(data, data_size); |             current_encoder->init(data, data_size); | ||||||
| 
 | 
 | ||||||
|             api_hal_rfid_tim_emulate(125000); |             api_hal_rfid_tim_emulate(125000); | ||||||
| @ -26,14 +26,6 @@ void RfidTimerEmulator::start(LfrfidKeyType type, const uint8_t* data, uint8_t d | |||||||
| 
 | 
 | ||||||
|             api_interrupt_add(timer_update_callback, InterruptTypeTimerUpdate, this); |             api_interrupt_add(timer_update_callback, InterruptTypeTimerUpdate, this); | ||||||
| 
 | 
 | ||||||
|             // TODO make api for interrupts priority
 |  | ||||||
|             for(size_t i = WWDG_IRQn; i <= DMAMUX1_OVR_IRQn; i++) { |  | ||||||
|                 HAL_NVIC_SetPriority(static_cast<IRQn_Type>(i), 15, 0); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             HAL_NVIC_SetPriority(TIM1_UP_TIM16_IRQn, 5, 0); |  | ||||||
|             HAL_NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn); |  | ||||||
| 
 |  | ||||||
|             api_hal_rfid_tim_emulate_start(); |             api_hal_rfid_tim_emulate_start(); | ||||||
|         } |         } | ||||||
|     } else { |     } else { | ||||||
							
								
								
									
										111
									
								
								applications/lfrfid/helpers/rfid-worker.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								applications/lfrfid/helpers/rfid-worker.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,111 @@ | |||||||
|  | #include "rfid-worker.h" | ||||||
|  | 
 | ||||||
|  | RfidWorker::RfidWorker() { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | RfidWorker::~RfidWorker() { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RfidWorker::start_read() { | ||||||
|  |     reader.start(RfidReader::Type::Normal); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool RfidWorker::read() { | ||||||
|  |     static const uint8_t data_size = LFRFID_KEY_SIZE; | ||||||
|  |     uint8_t data[data_size] = {0}; | ||||||
|  |     LfrfidKeyType type; | ||||||
|  | 
 | ||||||
|  |     bool result = reader.read(&type, data, data_size); | ||||||
|  | 
 | ||||||
|  |     if(result) { | ||||||
|  |         key.set_type(type); | ||||||
|  |         key.set_data(data, data_size); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RfidWorker::stop_read() { | ||||||
|  |     reader.stop(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RfidWorker::start_write() { | ||||||
|  |     write_result = WriteResult::Nothing; | ||||||
|  |     write_sequence = new TickSequencer(); | ||||||
|  |     validate_counts = 0; | ||||||
|  | 
 | ||||||
|  |     write_sequence->do_every_tick(1, std::bind(&RfidWorker::sq_write, this)); | ||||||
|  |     write_sequence->do_after_tick(2, std::bind(&RfidWorker::sq_write_start_validate, this)); | ||||||
|  |     write_sequence->do_after_tick(15, std::bind(&RfidWorker::sq_write_validate, this)); | ||||||
|  |     write_sequence->do_every_tick(1, std::bind(&RfidWorker::sq_write_stop_validate, this)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | RfidWorker::WriteResult RfidWorker::write() { | ||||||
|  |     write_sequence->tick(); | ||||||
|  |     return write_result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RfidWorker::stop_write() { | ||||||
|  |     delete write_sequence; | ||||||
|  |     reader.stop(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RfidWorker::start_emulate() { | ||||||
|  |     emulator.start(key.get_type(), key.get_data(), key.get_type_data_count()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RfidWorker::stop_emulate() { | ||||||
|  |     emulator.stop(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RfidWorker::sq_write() { | ||||||
|  |     // TODO expand this
 | ||||||
|  |     switch(key.get_type()) { | ||||||
|  |     case LfrfidKeyType::KeyEM4100: | ||||||
|  |         writer.start(); | ||||||
|  |         writer.write_em(key.get_data()); | ||||||
|  |         writer.stop(); | ||||||
|  |         break; | ||||||
|  |     case LfrfidKeyType::KeyH10301: | ||||||
|  |         writer.start(); | ||||||
|  |         writer.write_hid(key.get_data()); | ||||||
|  |         writer.stop(); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |     default: | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RfidWorker::sq_write_start_validate() { | ||||||
|  |     reader.start(RfidReader::Type::Normal); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RfidWorker::sq_write_validate() { | ||||||
|  |     static const uint8_t data_size = LFRFID_KEY_SIZE; | ||||||
|  |     uint8_t data[data_size] = {0}; | ||||||
|  |     LfrfidKeyType type; | ||||||
|  | 
 | ||||||
|  |     bool result = reader.read(&type, data, data_size); | ||||||
|  | 
 | ||||||
|  |     if(result) { | ||||||
|  |         if(type == key.get_type()) { | ||||||
|  |             if(memcmp(data, key.get_data(), key.get_type_data_count()) == 0) { | ||||||
|  |                 write_result = WriteResult::Ok; | ||||||
|  |                 validate_counts = 0; | ||||||
|  |             } else { | ||||||
|  |                 validate_counts++; | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             validate_counts++; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if(validate_counts > 5) { | ||||||
|  |             write_result = WriteResult::NotWritable; | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RfidWorker::sq_write_stop_validate() { | ||||||
|  |     reader.stop(); | ||||||
|  | } | ||||||
							
								
								
									
										46
									
								
								applications/lfrfid/helpers/rfid-worker.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								applications/lfrfid/helpers/rfid-worker.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | |||||||
|  | #pragma once | ||||||
|  | #include "key-info.h" | ||||||
|  | #include "rfid-reader.h" | ||||||
|  | #include "rfid-writer.h" | ||||||
|  | #include "rfid-timer-emulator.h" | ||||||
|  | #include "rfid-key.h" | ||||||
|  | #include "state-sequencer.h" | ||||||
|  | 
 | ||||||
|  | class RfidWorker { | ||||||
|  | public: | ||||||
|  |     RfidWorker(); | ||||||
|  |     ~RfidWorker(); | ||||||
|  | 
 | ||||||
|  |     void start_read(); | ||||||
|  |     bool read(); | ||||||
|  |     void stop_read(); | ||||||
|  | 
 | ||||||
|  |     enum class WriteResult : uint8_t { | ||||||
|  |         Ok, | ||||||
|  |         NotWritable, | ||||||
|  |         Nothing, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     void start_write(); | ||||||
|  |     WriteResult write(); | ||||||
|  |     void stop_write(); | ||||||
|  | 
 | ||||||
|  |     void start_emulate(); | ||||||
|  |     void stop_emulate(); | ||||||
|  | 
 | ||||||
|  |     RfidKey key; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     RfidWriter writer; | ||||||
|  |     RfidReader reader; | ||||||
|  |     RfidTimerEmulator emulator; | ||||||
|  | 
 | ||||||
|  |     WriteResult write_result; | ||||||
|  |     TickSequencer* write_sequence; | ||||||
|  | 
 | ||||||
|  |     void sq_write(); | ||||||
|  |     void sq_write_start_validate(); | ||||||
|  |     void sq_write_validate(); | ||||||
|  |     uint8_t validate_counts; | ||||||
|  |     void sq_write_stop_validate(); | ||||||
|  | }; | ||||||
| @ -1,6 +1,7 @@ | |||||||
| #include "rfid-writer.h" | #include "rfid-writer.h" | ||||||
| #include <api-hal.h> | #include <api-hal.h> | ||||||
| #include "protocols/protocol-emmarin.h" | #include "protocols/protocol-emmarin.h" | ||||||
|  | #include "protocols/protocol-hid-h10301.h" | ||||||
| 
 | 
 | ||||||
| extern COMP_HandleTypeDef hcomp1; | extern COMP_HandleTypeDef hcomp1; | ||||||
| 
 | 
 | ||||||
| @ -11,8 +12,8 @@ extern COMP_HandleTypeDef hcomp1; | |||||||
| class T55xxTiming { | class T55xxTiming { | ||||||
| public: | public: | ||||||
|     constexpr static const uint16_t wait_time = 400; |     constexpr static const uint16_t wait_time = 400; | ||||||
|     constexpr static const uint8_t start_gap = 15; |     constexpr static const uint8_t start_gap = 30; | ||||||
|     constexpr static const uint8_t write_gap = 10; |     constexpr static const uint8_t write_gap = 18; | ||||||
|     constexpr static const uint8_t data_0 = 24; |     constexpr static const uint8_t data_0 = 24; | ||||||
|     constexpr static const uint8_t data_1 = 56; |     constexpr static const uint8_t data_1 = 56; | ||||||
|     constexpr static const uint16_t program = 700; |     constexpr static const uint16_t program = 700; | ||||||
| @ -34,6 +35,7 @@ RfidWriter::~RfidWriter() { | |||||||
| void RfidWriter::start() { | void RfidWriter::start() { | ||||||
|     api_hal_rfid_tim_read(125000, 0.5); |     api_hal_rfid_tim_read(125000, 0.5); | ||||||
|     api_hal_rfid_pins_read(); |     api_hal_rfid_pins_read(); | ||||||
|  |     api_hal_rfid_tim_read_start(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RfidWriter::stop() { | void RfidWriter::stop() { | ||||||
| @ -64,8 +66,6 @@ void RfidWriter::write_byte(uint8_t value) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RfidWriter::write_block(uint8_t page, uint8_t block, bool lock_bit, uint32_t data) { | void RfidWriter::write_block(uint8_t page, uint8_t block, bool lock_bit, uint32_t data) { | ||||||
|     // wait to power card
 |  | ||||||
|     api_hal_rfid_tim_read_start(); |  | ||||||
|     delay_us(T55xxTiming::wait_time * 8); |     delay_us(T55xxTiming::wait_time * 8); | ||||||
| 
 | 
 | ||||||
|     // start gap
 |     // start gap
 | ||||||
| @ -101,18 +101,42 @@ void RfidWriter::write_block(uint8_t page, uint8_t block, bool lock_bit, uint32_ | |||||||
| 
 | 
 | ||||||
|     delay_us(T55xxTiming::program * 8); |     delay_us(T55xxTiming::program * 8); | ||||||
| 
 | 
 | ||||||
|     api_hal_rfid_tim_read_stop(); |     delay_us(T55xxTiming::wait_time * 8); | ||||||
|  |     write_reset(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RfidWriter::write_reset() { | ||||||
|  |     write_gap(T55xxTiming::start_gap); | ||||||
|  |     write_bit(1); | ||||||
|  |     write_bit(0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RfidWriter::write_em(uint8_t em_data[5]) { | void RfidWriter::write_em(uint8_t em_data[5]) { | ||||||
|     ProtocolEMMarin em_card; |     ProtocolEMMarin em_card; | ||||||
|     uint64_t em_encoded_data; |     uint64_t em_encoded_data; | ||||||
|     em_card.encode(em_data, 5, reinterpret_cast<uint8_t*>(&em_encoded_data), sizeof(uint64_t)); |     em_card.encode(em_data, 5, reinterpret_cast<uint8_t*>(&em_encoded_data), sizeof(uint64_t)); | ||||||
|     uint32_t em_config_block_data = 0b01100000000101001000000001000000; |     const uint32_t em_config_block_data = 0b01100000000101001000000001000000; | ||||||
| 
 | 
 | ||||||
|     __disable_irq(); |     __disable_irq(); | ||||||
|     write_block(0, 0, false, em_config_block_data); |     write_block(0, 0, false, em_config_block_data); | ||||||
|     write_block(0, 1, false, em_encoded_data); |     write_block(0, 1, false, em_encoded_data); | ||||||
|     write_block(0, 2, false, em_encoded_data >> 32); |     write_block(0, 2, false, em_encoded_data >> 32); | ||||||
|  |     write_reset(); | ||||||
|  |     __enable_irq(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void RfidWriter::write_hid(uint8_t hid_data[3]) { | ||||||
|  |     ProtocolHID10301 hid_card; | ||||||
|  |     uint32_t card_data[3]; | ||||||
|  |     hid_card.encode(hid_data, 3, reinterpret_cast<uint8_t*>(&card_data), sizeof(card_data) * 3); | ||||||
|  | 
 | ||||||
|  |     const uint32_t hid_config_block_data = 0b00000000000100000111000001100000; | ||||||
|  | 
 | ||||||
|  |     __disable_irq(); | ||||||
|  |     write_block(0, 0, false, hid_config_block_data); | ||||||
|  |     write_block(0, 1, false, card_data[0]); | ||||||
|  |     write_block(0, 2, false, card_data[1]); | ||||||
|  |     write_block(0, 3, false, card_data[2]); | ||||||
|  |     write_reset(); | ||||||
|     __enable_irq(); |     __enable_irq(); | ||||||
| } | } | ||||||
| @ -8,10 +8,12 @@ public: | |||||||
|     void start(); |     void start(); | ||||||
|     void stop(); |     void stop(); | ||||||
|     void write_em(uint8_t em_data[5]); |     void write_em(uint8_t em_data[5]); | ||||||
|  |     void write_hid(uint8_t hid_data[3]); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     void write_gap(uint32_t gap_time); |     void write_gap(uint32_t gap_time); | ||||||
|     void write_bit(bool value); |     void write_bit(bool value); | ||||||
|     void write_byte(uint8_t value); |     void write_byte(uint8_t value); | ||||||
|     void write_block(uint8_t page, uint8_t block, bool lock_bit, uint32_t data); |     void write_block(uint8_t page, uint8_t block, bool lock_bit, uint32_t data); | ||||||
|  |     void write_reset(); | ||||||
| }; | }; | ||||||
							
								
								
									
										50
									
								
								applications/lfrfid/helpers/state-sequencer.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								applications/lfrfid/helpers/state-sequencer.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | |||||||
|  | #include "state-sequencer.h" | ||||||
|  | #include "stdio.h" | ||||||
|  | 
 | ||||||
|  | TickSequencer::TickSequencer() { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TickSequencer::~TickSequencer() { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void TickSequencer::tick() { | ||||||
|  |     if(tick_count == list_it->first) { | ||||||
|  |         tick_count = 0; | ||||||
|  | 
 | ||||||
|  |         list_it++; | ||||||
|  |         if(list_it == list.end()) { | ||||||
|  |             list_it = list.begin(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     list_it->second(); | ||||||
|  |     tick_count++; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void TickSequencer::reset() { | ||||||
|  |     list_it = list.begin(); | ||||||
|  |     tick_count = 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void TickSequencer::clear() { | ||||||
|  |     list.clear(); | ||||||
|  |     reset(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void TickSequencer::do_every_tick(uint32_t tick_count, std::function<void(void)> fn) { | ||||||
|  |     list.push_back(std::make_pair(tick_count, fn)); | ||||||
|  |     reset(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void TickSequencer::do_after_tick(uint32_t tick_count, std::function<void(void)> fn) { | ||||||
|  |     if(tick_count > 1) { | ||||||
|  |         list.push_back( | ||||||
|  |             std::make_pair(tick_count - 1, std::bind(&TickSequencer::do_nothing, this))); | ||||||
|  |     } | ||||||
|  |     list.push_back(std::make_pair(1, fn)); | ||||||
|  | 
 | ||||||
|  |     reset(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void TickSequencer::do_nothing() { | ||||||
|  | } | ||||||
							
								
								
									
										25
									
								
								applications/lfrfid/helpers/state-sequencer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								applications/lfrfid/helpers/state-sequencer.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | |||||||
|  | #pragma once | ||||||
|  | #include "stdint.h" | ||||||
|  | #include <list> | ||||||
|  | #include <functional> | ||||||
|  | 
 | ||||||
|  | class TickSequencer { | ||||||
|  | public: | ||||||
|  |     TickSequencer(); | ||||||
|  |     ~TickSequencer(); | ||||||
|  | 
 | ||||||
|  |     void tick(); | ||||||
|  |     void reset(); | ||||||
|  |     void clear(); | ||||||
|  | 
 | ||||||
|  |     void do_every_tick(uint32_t tick_count, std::function<void(void)> fn); | ||||||
|  |     void do_after_tick(uint32_t tick_count, std::function<void(void)> fn); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     std::list<std::pair<uint32_t, std::function<void(void)> > > list; | ||||||
|  |     std::list<std::pair<uint32_t, std::function<void(void)> > >::iterator list_it; | ||||||
|  | 
 | ||||||
|  |     uint32_t tick_count; | ||||||
|  | 
 | ||||||
|  |     void do_nothing(); | ||||||
|  | }; | ||||||
							
								
								
									
										10
									
								
								applications/lfrfid/lfrfid-app-launcher.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								applications/lfrfid/lfrfid-app-launcher.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | #include "lfrfid-app.h" | ||||||
|  | 
 | ||||||
|  | // app enter function
 | ||||||
|  | extern "C" int32_t lfrfid_app(void* p) { | ||||||
|  |     LfRfidApp* app = new LfRfidApp(); | ||||||
|  |     app->run(); | ||||||
|  |     delete app; | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
							
								
								
									
										37
									
								
								applications/lfrfid/lfrfid-app.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								applications/lfrfid/lfrfid-app.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | |||||||
|  | #include "lfrfid-app.h" | ||||||
|  | #include "scene/lfrfid-app-scene-start.h" | ||||||
|  | #include "scene/lfrfid-app-scene-read.h" | ||||||
|  | #include "scene/lfrfid-app-scene-read-success.h" | ||||||
|  | #include "scene/lfrfid-app-scene-readed-menu.h" | ||||||
|  | #include "scene/lfrfid-app-scene-write.h" | ||||||
|  | #include "scene/lfrfid-app-scene-write-success.h" | ||||||
|  | #include "scene/lfrfid-app-scene-emulate.h" | ||||||
|  | #include "scene/lfrfid-app-scene-save-name.h" | ||||||
|  | 
 | ||||||
|  | LfRfidApp::LfRfidApp() | ||||||
|  |     : scene_controller{this} | ||||||
|  |     , fs_api{"sdcard"} | ||||||
|  |     , sd_ex_api{"sdcard-ex"} | ||||||
|  |     , notification{"notification"} | ||||||
|  |     , text_store(40) { | ||||||
|  |     api_hal_power_insomnia_enter(); | ||||||
|  | 
 | ||||||
|  |     // we need random
 | ||||||
|  |     srand(DWT->CYCCNT); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | LfRfidApp::~LfRfidApp() { | ||||||
|  |     api_hal_power_insomnia_exit(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void LfRfidApp::run() { | ||||||
|  |     scene_controller.add_scene(SceneType::Start, new LfRfidAppSceneStart()); | ||||||
|  |     scene_controller.add_scene(SceneType::Read, new LfRfidAppSceneRead()); | ||||||
|  |     scene_controller.add_scene(SceneType::ReadSuccess, new LfRfidAppSceneReadSuccess()); | ||||||
|  |     scene_controller.add_scene(SceneType::ReadedMenu, new LfRfidAppSceneReadedMenu()); | ||||||
|  |     scene_controller.add_scene(SceneType::Write, new LfRfidAppSceneWrite()); | ||||||
|  |     scene_controller.add_scene(SceneType::WriteSuccess, new LfRfidAppSceneWriteSuccess()); | ||||||
|  |     scene_controller.add_scene(SceneType::Emulate, new LfRfidAppSceneEmulate()); | ||||||
|  |     scene_controller.add_scene(SceneType::SaveName, new LfRfidAppSceneSaveName()); | ||||||
|  |     scene_controller.process(100); | ||||||
|  | } | ||||||
							
								
								
									
										67
									
								
								applications/lfrfid/lfrfid-app.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								applications/lfrfid/lfrfid-app.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,67 @@ | |||||||
|  | #pragma once | ||||||
|  | #include <furi.h> | ||||||
|  | #include <api-hal.h> | ||||||
|  | 
 | ||||||
|  | #include <generic-scene.hpp> | ||||||
|  | #include <scene-controller.hpp> | ||||||
|  | #include <view-controller.hpp> | ||||||
|  | #include <record-controller.hpp> | ||||||
|  | #include <text-store.h> | ||||||
|  | 
 | ||||||
|  | #include <view-modules/submenu-vm.h> | ||||||
|  | #include <view-modules/popup-vm.h> | ||||||
|  | #include <view-modules/dialog-ex-vm.h> | ||||||
|  | #include <view-modules/text-input-vm.h> | ||||||
|  | #include <view-modules/byte-input-vm.h> | ||||||
|  | #include "view/container-vm.h" | ||||||
|  | 
 | ||||||
|  | #include <sd-card-api.h> | ||||||
|  | #include <filesystem-api.h> | ||||||
|  | #include <notification/notification-messages.h> | ||||||
|  | 
 | ||||||
|  | #include "helpers/rfid-worker.h" | ||||||
|  | 
 | ||||||
|  | class LfRfidApp { | ||||||
|  | public: | ||||||
|  |     enum class EventType : uint8_t { | ||||||
|  |         GENERIC_EVENT_ENUM_VALUES, | ||||||
|  |         Next, | ||||||
|  |         MenuSelected, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     enum class SceneType : uint8_t { | ||||||
|  |         GENERIC_SCENE_ENUM_VALUES, | ||||||
|  |         Read, | ||||||
|  |         ReadSuccess, | ||||||
|  |         ReadedMenu, | ||||||
|  |         Write, | ||||||
|  |         WriteSuccess, | ||||||
|  |         Emulate, | ||||||
|  |         SaveName, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     class Event { | ||||||
|  |     public: | ||||||
|  |         union { | ||||||
|  |             int32_t menu_index; | ||||||
|  |         } payload; | ||||||
|  | 
 | ||||||
|  |         EventType type; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     SceneController<GenericScene<LfRfidApp>, LfRfidApp> scene_controller; | ||||||
|  |     ViewController<LfRfidApp, SubmenuVM, PopupVM, DialogExVM, TextInputVM, ByteInputVM, ContainerVM> | ||||||
|  |         view_controller; | ||||||
|  | 
 | ||||||
|  |     ~LfRfidApp(); | ||||||
|  |     LfRfidApp(); | ||||||
|  | 
 | ||||||
|  |     RecordController<FS_Api> fs_api; | ||||||
|  |     RecordController<SdCard_Api> sd_ex_api; | ||||||
|  |     RecordController<NotificationApp> notification; | ||||||
|  | 
 | ||||||
|  |     RfidWorker worker; | ||||||
|  | 
 | ||||||
|  |     TextStore text_store; | ||||||
|  |     void run(); | ||||||
|  | }; | ||||||
							
								
								
									
										36
									
								
								applications/lfrfid/scene/lfrfid-app-scene-emulate.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								applications/lfrfid/scene/lfrfid-app-scene-emulate.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | |||||||
|  | #include "lfrfid-app-scene-emulate.h" | ||||||
|  | 
 | ||||||
|  | void LfRfidAppSceneEmulate::on_enter(LfRfidApp* app, bool need_restore) { | ||||||
|  |     string_init(data_string); | ||||||
|  | 
 | ||||||
|  |     uint8_t* data = app->worker.key.get_data(); | ||||||
|  | 
 | ||||||
|  |     for(uint8_t i = 0; i < app->worker.key.get_type_data_count(); i++) { | ||||||
|  |         string_cat_printf(data_string, "%02X", data[i]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     auto popup = app->view_controller.get<PopupVM>(); | ||||||
|  | 
 | ||||||
|  |     popup->set_header("Emulating", 90, 34, AlignCenter, AlignTop); | ||||||
|  |     popup->set_text(string_get_cstr(data_string), 90, 48, AlignCenter, AlignTop); | ||||||
|  |     popup->set_icon(0, 4, I_RFIDDolphinSend_98x60); | ||||||
|  | 
 | ||||||
|  |     app->view_controller.switch_to<PopupVM>(); | ||||||
|  |     app->worker.start_emulate(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool LfRfidAppSceneEmulate::on_event(LfRfidApp* app, LfRfidApp::Event* event) { | ||||||
|  |     bool consumed = false; | ||||||
|  | 
 | ||||||
|  |     if(event->type == LfRfidApp::EventType::Tick) { | ||||||
|  |         notification_message(app->notification, &sequence_blink_cyan_10); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return consumed; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void LfRfidAppSceneEmulate::on_exit(LfRfidApp* app) { | ||||||
|  |     app->view_controller.get<PopupVM>()->clean(); | ||||||
|  |     app->worker.stop_emulate(); | ||||||
|  |     string_clear(data_string); | ||||||
|  | } | ||||||
							
								
								
									
										12
									
								
								applications/lfrfid/scene/lfrfid-app-scene-emulate.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								applications/lfrfid/scene/lfrfid-app-scene-emulate.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | #pragma once | ||||||
|  | #include "../lfrfid-app.h" | ||||||
|  | 
 | ||||||
|  | class LfRfidAppSceneEmulate : public GenericScene<LfRfidApp> { | ||||||
|  | public: | ||||||
|  |     void on_enter(LfRfidApp* app, bool need_restore) final; | ||||||
|  |     bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; | ||||||
|  |     void on_exit(LfRfidApp* app) final; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     string_t data_string; | ||||||
|  | }; | ||||||
							
								
								
									
										117
									
								
								applications/lfrfid/scene/lfrfid-app-scene-read-success.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								applications/lfrfid/scene/lfrfid-app-scene-read-success.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,117 @@ | |||||||
|  | #include "lfrfid-app-scene-read-success.h" | ||||||
|  | #include "../view/elements/button-element.h" | ||||||
|  | #include "../view/elements/icon-element.h" | ||||||
|  | #include "../view/elements/string-element.h" | ||||||
|  | 
 | ||||||
|  | void LfRfidAppSceneReadSuccess::on_enter(LfRfidApp* app, bool need_restore) { | ||||||
|  |     string_init(string[0]); | ||||||
|  |     string_init(string[1]); | ||||||
|  |     string_init(string[2]); | ||||||
|  | 
 | ||||||
|  |     auto container = app->view_controller.get<ContainerVM>(); | ||||||
|  | 
 | ||||||
|  |     auto button = container->add<ButtonElement>(); | ||||||
|  |     button->set_type(ButtonElement::Type::Left, "Retry"); | ||||||
|  |     button->set_callback(app, LfRfidAppSceneReadSuccess::back_callback); | ||||||
|  | 
 | ||||||
|  |     button = container->add<ButtonElement>(); | ||||||
|  |     button->set_type(ButtonElement::Type::Right, "More"); | ||||||
|  |     button->set_callback(app, LfRfidAppSceneReadSuccess::more_callback); | ||||||
|  | 
 | ||||||
|  |     auto icon = container->add<IconElement>(); | ||||||
|  |     icon->set_icon(3, 12, I_RFIDBigChip_37x36); | ||||||
|  | 
 | ||||||
|  |     auto header = container->add<StringElement>(); | ||||||
|  |     header->set_text(app->worker.key.get_type_text(), 89, 3, AlignCenter); | ||||||
|  | 
 | ||||||
|  |     auto line_1_text = container->add<StringElement>(); | ||||||
|  |     auto line_2_text = container->add<StringElement>(); | ||||||
|  |     auto line_3_text = container->add<StringElement>(); | ||||||
|  | 
 | ||||||
|  |     auto line_1_value = container->add<StringElement>(); | ||||||
|  |     auto line_2_value = container->add<StringElement>(); | ||||||
|  |     auto line_3_value = container->add<StringElement>(); | ||||||
|  | 
 | ||||||
|  |     uint8_t* data = app->worker.key.get_data(); | ||||||
|  | 
 | ||||||
|  |     switch(app->worker.key.get_type()) { | ||||||
|  |     case LfrfidKeyType::KeyEM4100: | ||||||
|  |         line_1_text->set_text("HEX:", 65, 23, AlignRight, AlignBottom, FontSecondary); | ||||||
|  |         line_2_text->set_text("Mod:", 65, 35, AlignRight, AlignBottom, FontSecondary); | ||||||
|  |         line_3_text->set_text("ID:", 65, 47, AlignRight, AlignBottom, FontSecondary); | ||||||
|  | 
 | ||||||
|  |         for(uint8_t i = 0; i < app->worker.key.get_type_data_count(); i++) { | ||||||
|  |             string_cat_printf(string[0], "%02X", data[i]); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         string_printf(string[1], "Manchester"); | ||||||
|  |         string_printf(string[2], "%03u,%05u", data[2], (uint16_t)((data[3] << 8) | (data[4]))); | ||||||
|  | 
 | ||||||
|  |         line_1_value->set_text( | ||||||
|  |             string_get_cstr(string[0]), 68, 23, AlignLeft, AlignBottom, FontSecondary); | ||||||
|  |         line_2_value->set_text( | ||||||
|  |             string_get_cstr(string[1]), 68, 35, AlignLeft, AlignBottom, FontSecondary); | ||||||
|  |         line_3_value->set_text( | ||||||
|  |             string_get_cstr(string[2]), 68, 47, AlignLeft, AlignBottom, FontSecondary); | ||||||
|  |         break; | ||||||
|  |     case LfrfidKeyType::KeyH10301: | ||||||
|  |         line_1_text->set_text("HEX:", 65, 23, AlignRight, AlignBottom, FontSecondary); | ||||||
|  |         line_2_text->set_text("FC:", 65, 35, AlignRight, AlignBottom, FontSecondary); | ||||||
|  |         line_3_text->set_text("Card:", 65, 47, AlignRight, AlignBottom, FontSecondary); | ||||||
|  | 
 | ||||||
|  |         for(uint8_t i = 0; i < app->worker.key.get_type_data_count(); i++) { | ||||||
|  |             string_cat_printf(string[0], "%02X", data[i]); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         string_printf(string[1], "%u", data[0]); | ||||||
|  |         string_printf(string[2], "%u", (uint16_t)((data[1] << 8) | (data[2]))); | ||||||
|  | 
 | ||||||
|  |         line_1_value->set_text( | ||||||
|  |             string_get_cstr(string[0]), 68, 23, AlignLeft, AlignBottom, FontSecondary); | ||||||
|  |         line_2_value->set_text( | ||||||
|  |             string_get_cstr(string[1]), 68, 35, AlignLeft, AlignBottom, FontSecondary); | ||||||
|  |         line_3_value->set_text( | ||||||
|  |             string_get_cstr(string[2]), 68, 47, AlignLeft, AlignBottom, FontSecondary); | ||||||
|  |         break; | ||||||
|  |     case LfrfidKeyType::KeyI40134: | ||||||
|  |         //TODO implement when we can read Indala
 | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     app->view_controller.switch_to<ContainerVM>(); | ||||||
|  | 
 | ||||||
|  |     notification_message_block(app->notification, &sequence_set_green_255); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool LfRfidAppSceneReadSuccess::on_event(LfRfidApp* app, LfRfidApp::Event* event) { | ||||||
|  |     bool consumed = false; | ||||||
|  | 
 | ||||||
|  |     if(event->type == LfRfidApp::EventType::Next) { | ||||||
|  |         app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::ReadedMenu); | ||||||
|  |         consumed = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return consumed; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void LfRfidAppSceneReadSuccess::on_exit(LfRfidApp* app) { | ||||||
|  |     notification_message_block(app->notification, &sequence_reset_green); | ||||||
|  |     app->view_controller.get<ContainerVM>()->clean(); | ||||||
|  |     string_clear(string[0]); | ||||||
|  |     string_clear(string[1]); | ||||||
|  |     string_clear(string[2]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void LfRfidAppSceneReadSuccess::back_callback(void* context) { | ||||||
|  |     LfRfidApp* app = static_cast<LfRfidApp*>(context); | ||||||
|  |     LfRfidApp::Event event; | ||||||
|  |     event.type = LfRfidApp::EventType::Back; | ||||||
|  |     app->view_controller.send_event(&event); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void LfRfidAppSceneReadSuccess::more_callback(void* context) { | ||||||
|  |     LfRfidApp* app = static_cast<LfRfidApp*>(context); | ||||||
|  |     LfRfidApp::Event event; | ||||||
|  |     event.type = LfRfidApp::EventType::Next; | ||||||
|  |     app->view_controller.send_event(&event); | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								applications/lfrfid/scene/lfrfid-app-scene-read-success.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								applications/lfrfid/scene/lfrfid-app-scene-read-success.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | #pragma once | ||||||
|  | #include "../lfrfid-app.h" | ||||||
|  | 
 | ||||||
|  | class LfRfidAppSceneReadSuccess : public GenericScene<LfRfidApp> { | ||||||
|  | public: | ||||||
|  |     void on_enter(LfRfidApp* app, bool need_restore) final; | ||||||
|  |     bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; | ||||||
|  |     void on_exit(LfRfidApp* app) final; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     static void back_callback(void* context); | ||||||
|  |     static void more_callback(void* context); | ||||||
|  | 
 | ||||||
|  |     string_t string[3]; | ||||||
|  | }; | ||||||
							
								
								
									
										31
									
								
								applications/lfrfid/scene/lfrfid-app-scene-read.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								applications/lfrfid/scene/lfrfid-app-scene-read.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | #include "lfrfid-app-scene-read.h" | ||||||
|  | 
 | ||||||
|  | void LfRfidAppSceneRead::on_enter(LfRfidApp* app, bool need_restore) { | ||||||
|  |     auto popup = app->view_controller.get<PopupVM>(); | ||||||
|  | 
 | ||||||
|  |     popup->set_header("Reading\nLF RFID", 70, 34, AlignLeft, AlignTop); | ||||||
|  |     popup->set_icon(0, 4, I_RFIDDolphinReceive_98x60); | ||||||
|  | 
 | ||||||
|  |     app->view_controller.switch_to<PopupVM>(); | ||||||
|  |     app->worker.start_read(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool LfRfidAppSceneRead::on_event(LfRfidApp* app, LfRfidApp::Event* event) { | ||||||
|  |     bool consumed = false; | ||||||
|  | 
 | ||||||
|  |     if(event->type == LfRfidApp::EventType::Tick) { | ||||||
|  |         if(app->worker.read()) { | ||||||
|  |             notification_message(app->notification, &sequence_success); | ||||||
|  |             app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::ReadSuccess); | ||||||
|  |         } else { | ||||||
|  |             notification_message(app->notification, &sequence_blink_red_10); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return consumed; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void LfRfidAppSceneRead::on_exit(LfRfidApp* app) { | ||||||
|  |     app->view_controller.get<PopupVM>()->clean(); | ||||||
|  |     app->worker.stop_read(); | ||||||
|  | } | ||||||
							
								
								
									
										9
									
								
								applications/lfrfid/scene/lfrfid-app-scene-read.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								applications/lfrfid/scene/lfrfid-app-scene-read.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | #pragma once | ||||||
|  | #include "../lfrfid-app.h" | ||||||
|  | 
 | ||||||
|  | class LfRfidAppSceneRead : public GenericScene<LfRfidApp> { | ||||||
|  | public: | ||||||
|  |     void on_enter(LfRfidApp* app, bool need_restore) final; | ||||||
|  |     bool on_event(LfRfidApp* app, LfRfidApp::Event* event) final; | ||||||
|  |     void on_exit(LfRfidApp* app) final; | ||||||
|  | }; | ||||||
							
								
								
									
										60
									
								
								applications/lfrfid/scene/lfrfid-app-scene-readed-menu.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								applications/lfrfid/scene/lfrfid-app-scene-readed-menu.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,60 @@ | |||||||
|  | #include "lfrfid-app-scene-readed-menu.h" | ||||||
|  | 
 | ||||||
|  | typedef enum { | ||||||
|  |     SubmenuWrite, | ||||||
|  |     SubmenuNameAndSave, | ||||||
|  |     SubmenuEmulate, | ||||||
|  | } SubmenuIndex; | ||||||
|  | 
 | ||||||
|  | void LfRfidAppSceneReadedMenu::on_enter(LfRfidApp* app, bool need_restore) { | ||||||
|  |     auto submenu = app->view_controller.get<SubmenuVM>(); | ||||||
|  | 
 | ||||||
|  |     submenu->add_item("Write", SubmenuWrite, submenu_callback, app); | ||||||
|  |     submenu->add_item("Name and Save", SubmenuNameAndSave, submenu_callback, app); | ||||||
|  |     submenu->add_item("Emulate", SubmenuEmulate, submenu_callback, app); | ||||||
|  | 
 | ||||||
|  |     if(need_restore) { | ||||||
|  |         submenu->set_selected_item(submenu_item_selected); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     app->view_controller.switch_to<SubmenuVM>(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool LfRfidAppSceneReadedMenu::on_event(LfRfidApp* app, LfRfidApp::Event* event) { | ||||||
|  |     bool consumed = false; | ||||||
|  | 
 | ||||||
|  |     if(event->type == LfRfidApp::EventType::MenuSelected) { | ||||||
|  |         submenu_item_selected = event->payload.menu_index; | ||||||
|  |         switch(event->payload.menu_index) { | ||||||
|  |         case SubmenuWrite: | ||||||
|  |             app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::Write); | ||||||
|  |             break; | ||||||
|  |         case SubmenuNameAndSave: | ||||||
|  |             app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::SaveName); | ||||||
|  |             break; | ||||||
|  |         case SubmenuEmulate: | ||||||
|  |             app->scene_controller.switch_to_next_scene(LfRfidApp::SceneType::Emulate); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         consumed = true; | ||||||
|  |     } else if(event->type == LfRfidApp::EventType::Back) { | ||||||
|  |         app->scene_controller.search_and_switch_to_previous_scene({LfRfidApp::SceneType::Start}); | ||||||
|  |         consumed = true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return consumed; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void LfRfidAppSceneReadedMenu::on_exit(LfRfidApp* app) { | ||||||
|  |     app->view_controller.get<SubmenuVM>()->clean(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void LfRfidAppSceneReadedMenu::submenu_callback(void* context, uint32_t index) { | ||||||
|  |     LfRfidApp* app = static_cast<LfRfidApp*>(context); | ||||||
|  |     LfRfidApp::Event event; | ||||||
|  | 
 | ||||||
|  |     event.type = LfRfidApp::EventType::MenuSelected; | ||||||
|  |     event.payload.menu_index = index; | ||||||
|  | 
 | ||||||
|  |     app->view_controller.send_event(&event); | ||||||
|  | } | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 SG
						SG