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