[FL-2627] Flipper applications: SDK, build and debug system (#1387)
* Added support for running applications from SD card (FAPs - Flipper Application Packages) * Added plugin_dist target for fbt to build FAPs * All apps of type FlipperAppType.EXTERNAL and FlipperAppType.PLUGIN are built as FAPs by default * Updated VSCode configuration for new fbt features - re-deploy stock configuration to use them * Added debugging support for FAPs with fbt debug & VSCode * Added public firmware API with automated versioning Co-authored-by: hedger <hedger@users.noreply.github.com> Co-authored-by: SG <who.just.the.doctor@gmail.com> Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
30
applications/main/lfrfid/scenes/lfrfid_scene.c
Normal file
30
applications/main/lfrfid/scenes/lfrfid_scene.c
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "lfrfid_scene.h"
|
||||
|
||||
// Generate scene on_enter handlers array
|
||||
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
|
||||
void (*const lfrfid_on_enter_handlers[])(void*) = {
|
||||
#include "lfrfid_scene_config.h"
|
||||
};
|
||||
#undef ADD_SCENE
|
||||
|
||||
// Generate scene on_event handlers array
|
||||
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event,
|
||||
bool (*const lfrfid_on_event_handlers[])(void* context, SceneManagerEvent event) = {
|
||||
#include "lfrfid_scene_config.h"
|
||||
};
|
||||
#undef ADD_SCENE
|
||||
|
||||
// Generate scene on_exit handlers array
|
||||
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit,
|
||||
void (*const lfrfid_on_exit_handlers[])(void* context) = {
|
||||
#include "lfrfid_scene_config.h"
|
||||
};
|
||||
#undef ADD_SCENE
|
||||
|
||||
// Initialize scene handlers configuration structure
|
||||
const SceneManagerHandlers lfrfid_scene_handlers = {
|
||||
.on_enter_handlers = lfrfid_on_enter_handlers,
|
||||
.on_event_handlers = lfrfid_on_event_handlers,
|
||||
.on_exit_handlers = lfrfid_on_exit_handlers,
|
||||
.scene_num = LfRfidSceneNum,
|
||||
};
|
29
applications/main/lfrfid/scenes/lfrfid_scene.h
Normal file
29
applications/main/lfrfid/scenes/lfrfid_scene.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/scene_manager.h>
|
||||
|
||||
// Generate scene id and total number
|
||||
#define ADD_SCENE(prefix, name, id) LfRfidScene##id,
|
||||
typedef enum {
|
||||
#include "lfrfid_scene_config.h"
|
||||
LfRfidSceneNum,
|
||||
} LfRfidScene;
|
||||
#undef ADD_SCENE
|
||||
|
||||
extern const SceneManagerHandlers lfrfid_scene_handlers;
|
||||
|
||||
// Generate scene on_enter handlers declaration
|
||||
#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
|
||||
#include "lfrfid_scene_config.h"
|
||||
#undef ADD_SCENE
|
||||
|
||||
// Generate scene on_event handlers declaration
|
||||
#define ADD_SCENE(prefix, name, id) \
|
||||
bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event);
|
||||
#include "lfrfid_scene_config.h"
|
||||
#undef ADD_SCENE
|
||||
|
||||
// Generate scene on_exit handlers declaration
|
||||
#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context);
|
||||
#include "lfrfid_scene_config.h"
|
||||
#undef ADD_SCENE
|
24
applications/main/lfrfid/scenes/lfrfid_scene_config.h
Normal file
24
applications/main/lfrfid/scenes/lfrfid_scene_config.h
Normal file
@@ -0,0 +1,24 @@
|
||||
ADD_SCENE(lfrfid, start, Start)
|
||||
ADD_SCENE(lfrfid, read, Read)
|
||||
ADD_SCENE(lfrfid, read_success, ReadSuccess)
|
||||
ADD_SCENE(lfrfid, retry_confirm, RetryConfirm)
|
||||
ADD_SCENE(lfrfid, exit_confirm, ExitConfirm)
|
||||
ADD_SCENE(lfrfid, delete_confirm, DeleteConfirm)
|
||||
ADD_SCENE(lfrfid, read_key_menu, ReadKeyMenu)
|
||||
ADD_SCENE(lfrfid, write, Write)
|
||||
ADD_SCENE(lfrfid, write_success, WriteSuccess)
|
||||
ADD_SCENE(lfrfid, emulate, Emulate)
|
||||
ADD_SCENE(lfrfid, save_name, SaveName)
|
||||
ADD_SCENE(lfrfid, save_success, SaveSuccess)
|
||||
ADD_SCENE(lfrfid, select_key, SelectKey)
|
||||
ADD_SCENE(lfrfid, saved_key_menu, SavedKeyMenu)
|
||||
ADD_SCENE(lfrfid, save_data, SaveData)
|
||||
ADD_SCENE(lfrfid, save_type, SaveType)
|
||||
ADD_SCENE(lfrfid, saved_info, SavedInfo)
|
||||
ADD_SCENE(lfrfid, delete_success, DeleteSuccess)
|
||||
ADD_SCENE(lfrfid, extra_actions, ExtraActions)
|
||||
ADD_SCENE(lfrfid, raw_info, RawInfo)
|
||||
ADD_SCENE(lfrfid, raw_name, RawName)
|
||||
ADD_SCENE(lfrfid, raw_read, RawRead)
|
||||
ADD_SCENE(lfrfid, raw_success, RawSuccess)
|
||||
ADD_SCENE(lfrfid, rpc, Rpc)
|
@@ -0,0 +1,68 @@
|
||||
#include "../lfrfid_i.h"
|
||||
|
||||
void lfrfid_scene_delete_confirm_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
Widget* widget = app->widget;
|
||||
|
||||
string_t tmp_string;
|
||||
string_init(tmp_string);
|
||||
|
||||
widget_add_button_element(widget, GuiButtonTypeLeft, "Back", lfrfid_widget_callback, app);
|
||||
widget_add_button_element(widget, GuiButtonTypeRight, "Delete", lfrfid_widget_callback, app);
|
||||
|
||||
string_printf(tmp_string, "Delete %s?", string_get_cstr(app->file_name));
|
||||
widget_add_string_element(
|
||||
widget, 64, 0, AlignCenter, AlignTop, FontPrimary, string_get_cstr(tmp_string));
|
||||
|
||||
string_reset(tmp_string);
|
||||
size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id);
|
||||
uint8_t* data = (uint8_t*)malloc(size);
|
||||
protocol_dict_get_data(app->dict, app->protocol_id, data, size);
|
||||
for(uint8_t i = 0; i < MIN(size, (size_t)8); i++) {
|
||||
if(i != 0) {
|
||||
string_cat_printf(tmp_string, " ");
|
||||
}
|
||||
|
||||
string_cat_printf(tmp_string, "%02X", data[i]);
|
||||
}
|
||||
free(data);
|
||||
|
||||
widget_add_string_element(
|
||||
widget, 64, 19, AlignCenter, AlignTop, FontSecondary, string_get_cstr(tmp_string));
|
||||
widget_add_string_element(
|
||||
widget,
|
||||
64,
|
||||
49,
|
||||
AlignCenter,
|
||||
AlignBottom,
|
||||
FontSecondary,
|
||||
protocol_dict_get_name(app->dict, app->protocol_id));
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget);
|
||||
string_clear(tmp_string);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_delete_confirm_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
SceneManager* scene_manager = app->scene_manager;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
consumed = true; // Ignore Back button presses
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
consumed = true;
|
||||
if(event.event == GuiButtonTypeLeft) {
|
||||
scene_manager_previous_scene(scene_manager);
|
||||
} else if(event.event == GuiButtonTypeRight) {
|
||||
lfrfid_delete_key(app);
|
||||
scene_manager_next_scene(scene_manager, LfRfidSceneDeleteSuccess);
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_delete_confirm_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
widget_reset(app->widget);
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
#include "../lfrfid_i.h"
|
||||
|
||||
void lfrfid_scene_delete_success_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
Popup* popup = app->popup;
|
||||
|
||||
popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62);
|
||||
popup_set_header(popup, "Deleted", 83, 19, AlignLeft, AlignBottom);
|
||||
popup_set_context(popup, app);
|
||||
popup_set_callback(popup, lfrfid_popup_timeout_callback);
|
||||
popup_set_timeout(popup, 1500);
|
||||
popup_enable_timeout(popup);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_delete_success_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
if((event.type == SceneManagerEventTypeBack) ||
|
||||
((event.type == SceneManagerEventTypeCustom) && (event.event == LfRfidEventPopupClosed))) {
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
app->scene_manager, LfRfidSceneSelectKey);
|
||||
consumed = true;
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_delete_success_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
|
||||
popup_reset(app->popup);
|
||||
}
|
44
applications/main/lfrfid/scenes/lfrfid_scene_emulate.c
Normal file
44
applications/main/lfrfid/scenes/lfrfid_scene_emulate.c
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "../lfrfid_i.h"
|
||||
#include <dolphin/dolphin.h>
|
||||
|
||||
void lfrfid_scene_emulate_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
Popup* popup = app->popup;
|
||||
|
||||
DOLPHIN_DEED(DolphinDeedRfidEmulate);
|
||||
|
||||
popup_set_header(popup, "Emulating", 89, 30, AlignCenter, AlignTop);
|
||||
if(!string_empty_p(app->file_name)) {
|
||||
popup_set_text(popup, string_get_cstr(app->file_name), 89, 43, AlignCenter, AlignTop);
|
||||
} else {
|
||||
popup_set_text(
|
||||
popup,
|
||||
protocol_dict_get_name(app->dict, app->protocol_id),
|
||||
89,
|
||||
43,
|
||||
AlignCenter,
|
||||
AlignTop);
|
||||
}
|
||||
popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61);
|
||||
|
||||
lfrfid_worker_start_thread(app->lfworker);
|
||||
lfrfid_worker_emulate_start(app->lfworker, (LFRFIDProtocol)app->protocol_id);
|
||||
notification_message(app->notifications, &sequence_blink_start_magenta);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_emulate_on_event(void* context, SceneManagerEvent event) {
|
||||
UNUSED(context);
|
||||
UNUSED(event);
|
||||
bool consumed = false;
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_emulate_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
notification_message(app->notifications, &sequence_blink_stop);
|
||||
popup_reset(app->popup);
|
||||
lfrfid_worker_stop(app->lfworker);
|
||||
lfrfid_worker_stop_thread(app->lfworker);
|
||||
}
|
39
applications/main/lfrfid/scenes/lfrfid_scene_exit_confirm.c
Normal file
39
applications/main/lfrfid/scenes/lfrfid_scene_exit_confirm.c
Normal file
@@ -0,0 +1,39 @@
|
||||
#include "../lfrfid_i.h"
|
||||
|
||||
void lfrfid_scene_exit_confirm_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
Widget* widget = app->widget;
|
||||
|
||||
widget_add_button_element(widget, GuiButtonTypeLeft, "Exit", lfrfid_widget_callback, app);
|
||||
widget_add_button_element(widget, GuiButtonTypeRight, "Stay", lfrfid_widget_callback, app);
|
||||
widget_add_string_element(
|
||||
widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Exit to RFID Menu?");
|
||||
widget_add_string_element(
|
||||
widget, 64, 31, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost!");
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_exit_confirm_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
SceneManager* scene_manager = app->scene_manager;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
consumed = true; // Ignore Back button presses
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
consumed = true;
|
||||
if(event.event == GuiButtonTypeLeft) {
|
||||
scene_manager_search_and_switch_to_previous_scene(scene_manager, LfRfidSceneStart);
|
||||
} else if(event.event == GuiButtonTypeRight) {
|
||||
scene_manager_previous_scene(scene_manager);
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_exit_confirm_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
widget_reset(app->widget);
|
||||
}
|
79
applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c
Normal file
79
applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c
Normal file
@@ -0,0 +1,79 @@
|
||||
#include "../lfrfid_i.h"
|
||||
|
||||
typedef enum {
|
||||
SubmenuIndexASK,
|
||||
SubmenuIndexPSK,
|
||||
SubmenuIndexRAW,
|
||||
} SubmenuIndex;
|
||||
|
||||
static void lfrfid_scene_extra_actions_submenu_callback(void* context, uint32_t index) {
|
||||
LfRfid* app = context;
|
||||
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, index);
|
||||
}
|
||||
|
||||
void lfrfid_scene_extra_actions_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
Submenu* submenu = app->submenu;
|
||||
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Read ASK (Animal, Ordinary Card)",
|
||||
SubmenuIndexASK,
|
||||
lfrfid_scene_extra_actions_submenu_callback,
|
||||
app);
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Read PSK (Indala)",
|
||||
SubmenuIndexPSK,
|
||||
lfrfid_scene_extra_actions_submenu_callback,
|
||||
app);
|
||||
|
||||
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Read RAW RFID data",
|
||||
SubmenuIndexRAW,
|
||||
lfrfid_scene_extra_actions_submenu_callback,
|
||||
app);
|
||||
}
|
||||
|
||||
submenu_set_selected_item(
|
||||
submenu, scene_manager_get_scene_state(app->scene_manager, LfRfidSceneExtraActions));
|
||||
|
||||
// clear key
|
||||
string_reset(app->file_name);
|
||||
app->protocol_id = PROTOCOL_NO;
|
||||
app->read_type = LFRFIDWorkerReadTypeAuto;
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewSubmenu);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_extra_actions_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == SubmenuIndexASK) {
|
||||
app->read_type = LFRFIDWorkerReadTypeASKOnly;
|
||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneRead);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexPSK) {
|
||||
app->read_type = LFRFIDWorkerReadTypePSKOnly;
|
||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneRead);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexRAW) {
|
||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneRawName);
|
||||
consumed = true;
|
||||
}
|
||||
scene_manager_set_scene_state(app->scene_manager, LfRfidSceneExtraActions, event.event);
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_extra_actions_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
|
||||
submenu_reset(app->submenu);
|
||||
}
|
64
applications/main/lfrfid/scenes/lfrfid_scene_raw_info.c
Normal file
64
applications/main/lfrfid/scenes/lfrfid_scene_raw_info.c
Normal file
@@ -0,0 +1,64 @@
|
||||
#include "../lfrfid_i.h"
|
||||
|
||||
void lfrfid_scene_raw_info_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
Widget* widget = app->widget;
|
||||
|
||||
// string_t tmp_string;
|
||||
// string_init(tmp_string);
|
||||
|
||||
bool sd_exist = storage_sd_status(app->storage) == FSE_OK;
|
||||
if(!sd_exist) {
|
||||
widget_add_icon_element(widget, 0, 0, &I_SDQuestion_35x43);
|
||||
widget_add_string_multiline_element(
|
||||
widget,
|
||||
81,
|
||||
4,
|
||||
AlignCenter,
|
||||
AlignTop,
|
||||
FontSecondary,
|
||||
"No SD card found.\nThis function will not\nwork without\nSD card.");
|
||||
|
||||
widget_add_button_element(widget, GuiButtonTypeLeft, "Back", lfrfid_widget_callback, app);
|
||||
} else {
|
||||
widget_add_string_multiline_element(
|
||||
widget,
|
||||
0,
|
||||
1,
|
||||
AlignLeft,
|
||||
AlignTop,
|
||||
FontSecondary,
|
||||
"RAW RFID data reader\n1) Put the Flipper on your card\n2) Press OK\n3) Wait until data is read");
|
||||
|
||||
widget_add_button_element(widget, GuiButtonTypeCenter, "OK", lfrfid_widget_callback, app);
|
||||
}
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget);
|
||||
//string_clear(tmp_string);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_raw_info_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
SceneManager* scene_manager = app->scene_manager;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
consumed = true;
|
||||
scene_manager_search_and_switch_to_previous_scene(scene_manager, LfRfidSceneExtraActions);
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
consumed = true;
|
||||
if(event.event == GuiButtonTypeCenter) {
|
||||
scene_manager_next_scene(scene_manager, LfRfidSceneRawRead);
|
||||
} else if(event.event == GuiButtonTypeLeft) {
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
scene_manager, LfRfidSceneExtraActions);
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_raw_info_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
widget_reset(app->widget);
|
||||
}
|
58
applications/main/lfrfid/scenes/lfrfid_scene_raw_name.c
Normal file
58
applications/main/lfrfid/scenes/lfrfid_scene_raw_name.c
Normal file
@@ -0,0 +1,58 @@
|
||||
#include "../lfrfid_i.h"
|
||||
|
||||
void lfrfid_scene_raw_name_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
TextInput* text_input = app->text_input;
|
||||
|
||||
const char* key_name = string_get_cstr(app->raw_file_name);
|
||||
|
||||
bool key_name_is_empty = string_empty_p(app->file_name);
|
||||
if(key_name_is_empty) {
|
||||
lfrfid_text_store_set(app, "RfidRecord");
|
||||
} else {
|
||||
lfrfid_text_store_set(app, "%s", key_name);
|
||||
}
|
||||
|
||||
text_input_set_header_text(text_input, "Name the raw file");
|
||||
|
||||
text_input_set_result_callback(
|
||||
text_input,
|
||||
lfrfid_text_input_callback,
|
||||
app,
|
||||
app->text_store,
|
||||
LFRFID_KEY_NAME_SIZE,
|
||||
key_name_is_empty);
|
||||
|
||||
ValidatorIsFile* validator_is_file =
|
||||
validator_is_file_alloc_init(LFRFID_SD_FOLDER, LFRFID_APP_RAW_ASK_EXTENSION, NULL);
|
||||
text_input_set_validator(text_input, validator_is_file_callback, validator_is_file);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewTextInput);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_raw_name_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
SceneManager* scene_manager = app->scene_manager;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == LfRfidEventNext) {
|
||||
consumed = true;
|
||||
string_set_str(app->raw_file_name, app->text_store);
|
||||
scene_manager_next_scene(scene_manager, LfRfidSceneRawInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_raw_name_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
TextInput* text_input = app->text_input;
|
||||
|
||||
void* validator_context = text_input_get_validator_callback_context(text_input);
|
||||
text_input_set_validator(text_input, NULL, NULL);
|
||||
validator_is_file_free((ValidatorIsFile*)validator_context);
|
||||
|
||||
text_input_reset(text_input);
|
||||
}
|
126
applications/main/lfrfid/scenes/lfrfid_scene_raw_read.c
Normal file
126
applications/main/lfrfid/scenes/lfrfid_scene_raw_read.c
Normal file
@@ -0,0 +1,126 @@
|
||||
#include "../lfrfid_i.h"
|
||||
|
||||
#define RAW_READ_TIME 5000
|
||||
|
||||
typedef struct {
|
||||
string_t string_file_name;
|
||||
FuriTimer* timer;
|
||||
bool is_psk;
|
||||
bool error;
|
||||
} LfRfidReadRawState;
|
||||
|
||||
static void lfrfid_read_callback(LFRFIDWorkerReadRawResult result, void* context) {
|
||||
LfRfid* app = context;
|
||||
|
||||
if(result == LFRFIDWorkerReadRawFileError) {
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, LfRfidEventReadError);
|
||||
} else if(result == LFRFIDWorkerReadRawOverrun) {
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, LfRfidEventReadOverrun);
|
||||
}
|
||||
}
|
||||
|
||||
static void timer_callback(void* context) {
|
||||
LfRfid* app = context;
|
||||
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, LfRfidEventReadDone);
|
||||
}
|
||||
|
||||
void lfrfid_scene_raw_read_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
Popup* popup = app->popup;
|
||||
|
||||
LfRfidReadRawState* state = malloc(sizeof(LfRfidReadRawState));
|
||||
scene_manager_set_scene_state(app->scene_manager, LfRfidSceneRawRead, (uint32_t)state);
|
||||
string_init(state->string_file_name);
|
||||
|
||||
popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup);
|
||||
lfrfid_worker_start_thread(app->lfworker);
|
||||
lfrfid_make_app_folder(app);
|
||||
|
||||
state->timer = furi_timer_alloc(timer_callback, FuriTimerTypeOnce, app);
|
||||
furi_timer_start(state->timer, RAW_READ_TIME);
|
||||
string_printf(
|
||||
state->string_file_name,
|
||||
"%s/%s%s",
|
||||
LFRFID_SD_FOLDER,
|
||||
string_get_cstr(app->raw_file_name),
|
||||
LFRFID_APP_RAW_ASK_EXTENSION);
|
||||
popup_set_header(popup, "Reading\nRAW RFID\nASK", 89, 30, AlignCenter, AlignTop);
|
||||
lfrfid_worker_read_raw_start(
|
||||
app->lfworker,
|
||||
string_get_cstr(state->string_file_name),
|
||||
LFRFIDWorkerReadTypeASKOnly,
|
||||
lfrfid_read_callback,
|
||||
app);
|
||||
|
||||
notification_message(app->notifications, &sequence_blink_start_cyan);
|
||||
|
||||
state->is_psk = false;
|
||||
state->error = false;
|
||||
}
|
||||
|
||||
bool lfrfid_scene_raw_read_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
Popup* popup = app->popup;
|
||||
LfRfidReadRawState* state =
|
||||
(LfRfidReadRawState*)scene_manager_get_scene_state(app->scene_manager, LfRfidSceneRawRead);
|
||||
bool consumed = false;
|
||||
|
||||
furi_assert(state);
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == LfRfidEventReadError) {
|
||||
consumed = true;
|
||||
state->error = true;
|
||||
popup_set_header(
|
||||
popup, "Reading\nRAW RFID\nFile error", 89, 30, AlignCenter, AlignTop);
|
||||
notification_message(app->notifications, &sequence_blink_start_red);
|
||||
furi_timer_stop(state->timer);
|
||||
} else if(event.event == LfRfidEventReadDone) {
|
||||
consumed = true;
|
||||
if(!state->error) {
|
||||
if(state->is_psk) {
|
||||
notification_message(app->notifications, &sequence_success);
|
||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneRawSuccess);
|
||||
} else {
|
||||
popup_set_header(
|
||||
popup, "Reading\nRAW RFID\nPSK", 89, 30, AlignCenter, AlignTop);
|
||||
notification_message(app->notifications, &sequence_blink_start_yellow);
|
||||
lfrfid_worker_stop(app->lfworker);
|
||||
string_printf(
|
||||
state->string_file_name,
|
||||
"%s/%s%s",
|
||||
LFRFID_SD_FOLDER,
|
||||
string_get_cstr(app->raw_file_name),
|
||||
LFRFID_APP_RAW_PSK_EXTENSION);
|
||||
lfrfid_worker_read_raw_start(
|
||||
app->lfworker,
|
||||
string_get_cstr(state->string_file_name),
|
||||
LFRFIDWorkerReadTypePSKOnly,
|
||||
lfrfid_read_callback,
|
||||
app);
|
||||
furi_timer_start(state->timer, RAW_READ_TIME);
|
||||
state->is_psk = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_raw_read_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
LfRfidReadRawState* state =
|
||||
(LfRfidReadRawState*)scene_manager_get_scene_state(app->scene_manager, LfRfidSceneRawRead);
|
||||
|
||||
notification_message(app->notifications, &sequence_blink_stop);
|
||||
popup_reset(app->popup);
|
||||
lfrfid_worker_stop(app->lfworker);
|
||||
lfrfid_worker_stop_thread(app->lfworker);
|
||||
furi_timer_free(state->timer);
|
||||
|
||||
string_clear(state->string_file_name);
|
||||
free(state);
|
||||
}
|
39
applications/main/lfrfid/scenes/lfrfid_scene_raw_success.c
Normal file
39
applications/main/lfrfid/scenes/lfrfid_scene_raw_success.c
Normal file
@@ -0,0 +1,39 @@
|
||||
#include "../lfrfid_i.h"
|
||||
|
||||
void lfrfid_scene_raw_success_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
Widget* widget = app->widget;
|
||||
|
||||
widget_add_button_element(widget, GuiButtonTypeCenter, "OK", lfrfid_widget_callback, app);
|
||||
|
||||
widget_add_string_multiline_element(
|
||||
widget,
|
||||
0,
|
||||
1,
|
||||
AlignLeft,
|
||||
AlignTop,
|
||||
FontSecondary,
|
||||
"RAW RFID read success!\nNow you can analyze files\nOr send them to developers");
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_raw_success_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
SceneManager* scene_manager = app->scene_manager;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
consumed = true;
|
||||
if(event.event == GuiButtonTypeCenter) {
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
scene_manager, LfRfidSceneExtraActions);
|
||||
}
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_raw_success_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
widget_reset(app->widget);
|
||||
}
|
109
applications/main/lfrfid/scenes/lfrfid_scene_read.c
Normal file
109
applications/main/lfrfid/scenes/lfrfid_scene_read.c
Normal file
@@ -0,0 +1,109 @@
|
||||
#include "../lfrfid_i.h"
|
||||
#include <dolphin/dolphin.h>
|
||||
|
||||
static const NotificationSequence sequence_blink_set_yellow = {
|
||||
&message_blink_set_color_yellow,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const NotificationSequence sequence_blink_set_green = {
|
||||
&message_blink_set_color_green,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const NotificationSequence sequence_blink_set_cyan = {
|
||||
&message_blink_set_color_cyan,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static void
|
||||
lfrfid_read_callback(LFRFIDWorkerReadResult result, ProtocolId protocol, void* context) {
|
||||
LfRfid* app = context;
|
||||
uint32_t event = 0;
|
||||
|
||||
if(result == LFRFIDWorkerReadSenseStart) {
|
||||
event = LfRfidEventReadSenseStart;
|
||||
} else if(result == LFRFIDWorkerReadSenseEnd) {
|
||||
event = LfRfidEventReadSenseEnd;
|
||||
} else if(result == LFRFIDWorkerReadSenseCardStart) {
|
||||
event = LfRfidEventReadSenseCardStart;
|
||||
} else if(result == LFRFIDWorkerReadSenseCardEnd) {
|
||||
event = LfRfidEventReadSenseCardEnd;
|
||||
} else if(result == LFRFIDWorkerReadDone) {
|
||||
event = LfRfidEventReadDone;
|
||||
app->protocol_id_next = protocol;
|
||||
} else if(result == LFRFIDWorkerReadStartASK) {
|
||||
event = LfRfidEventReadStartASK;
|
||||
} else if(result == LFRFIDWorkerReadStartPSK) {
|
||||
event = LfRfidEventReadStartPSK;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, event);
|
||||
}
|
||||
|
||||
void lfrfid_scene_read_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
|
||||
DOLPHIN_DEED(DolphinDeedRfidRead);
|
||||
if(app->read_type == LFRFIDWorkerReadTypePSKOnly) {
|
||||
lfrfid_view_read_set_read_mode(app->read_view, LfRfidReadPskOnly);
|
||||
} else if(app->read_type == LFRFIDWorkerReadTypeASKOnly) {
|
||||
lfrfid_view_read_set_read_mode(app->read_view, LfRfidReadAskOnly);
|
||||
}
|
||||
|
||||
lfrfid_worker_start_thread(app->lfworker);
|
||||
lfrfid_worker_read_start(app->lfworker, app->read_type, lfrfid_read_callback, app);
|
||||
|
||||
notification_message(app->notifications, &sequence_blink_start_cyan);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewRead);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_read_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == LfRfidEventReadSenseStart) {
|
||||
notification_message(app->notifications, &sequence_blink_set_yellow);
|
||||
consumed = true;
|
||||
} else if(event.event == LfRfidEventReadSenseCardStart) {
|
||||
notification_message(app->notifications, &sequence_blink_set_green);
|
||||
consumed = true;
|
||||
} else if(
|
||||
(event.event == LfRfidEventReadSenseEnd) ||
|
||||
(event.event == LfRfidEventReadSenseCardEnd)) {
|
||||
notification_message(app->notifications, &sequence_blink_set_cyan);
|
||||
consumed = true;
|
||||
} else if(event.event == LfRfidEventReadDone) {
|
||||
app->protocol_id = app->protocol_id_next;
|
||||
DOLPHIN_DEED(DolphinDeedRfidReadSuccess);
|
||||
notification_message(app->notifications, &sequence_success);
|
||||
string_reset(app->file_name);
|
||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneReadSuccess);
|
||||
consumed = true;
|
||||
} else if(event.event == LfRfidEventReadStartPSK) {
|
||||
if(app->read_type == LFRFIDWorkerReadTypeAuto) {
|
||||
lfrfid_view_read_set_read_mode(app->read_view, LfRfidReadPsk);
|
||||
}
|
||||
consumed = true;
|
||||
} else if(event.event == LfRfidEventReadStartASK) {
|
||||
if(app->read_type == LFRFIDWorkerReadTypeAuto) {
|
||||
lfrfid_view_read_set_read_mode(app->read_view, LfRfidReadAsk);
|
||||
}
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_read_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
notification_message(app->notifications, &sequence_blink_stop);
|
||||
popup_reset(app->popup);
|
||||
lfrfid_worker_stop(app->lfworker);
|
||||
lfrfid_worker_stop_thread(app->lfworker);
|
||||
}
|
58
applications/main/lfrfid/scenes/lfrfid_scene_read_key_menu.c
Normal file
58
applications/main/lfrfid/scenes/lfrfid_scene_read_key_menu.c
Normal file
@@ -0,0 +1,58 @@
|
||||
#include "../lfrfid_i.h"
|
||||
|
||||
typedef enum {
|
||||
SubmenuIndexSave,
|
||||
SubmenuIndexEmulate,
|
||||
SubmenuIndexWrite,
|
||||
} SubmenuIndex;
|
||||
|
||||
void lfrfid_scene_read_key_menu_submenu_callback(void* context, uint32_t index) {
|
||||
LfRfid* app = context;
|
||||
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, index);
|
||||
}
|
||||
|
||||
void lfrfid_scene_read_key_menu_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
Submenu* submenu = app->submenu;
|
||||
|
||||
submenu_add_item(
|
||||
submenu, "Save", SubmenuIndexSave, lfrfid_scene_read_key_menu_submenu_callback, app);
|
||||
submenu_add_item(
|
||||
submenu, "Emulate", SubmenuIndexEmulate, lfrfid_scene_read_key_menu_submenu_callback, app);
|
||||
submenu_add_item(
|
||||
submenu, "Write", SubmenuIndexWrite, lfrfid_scene_read_key_menu_submenu_callback, app);
|
||||
|
||||
submenu_set_selected_item(
|
||||
submenu, scene_manager_get_scene_state(app->scene_manager, LfRfidSceneReadKeyMenu));
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewSubmenu);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_read_key_menu_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == SubmenuIndexWrite) {
|
||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneWrite);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexSave) {
|
||||
string_reset(app->file_name);
|
||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneSaveName);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexEmulate) {
|
||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneEmulate);
|
||||
consumed = true;
|
||||
}
|
||||
scene_manager_set_scene_state(app->scene_manager, LfRfidSceneReadKeyMenu, event.event);
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_read_key_menu_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
|
||||
submenu_reset(app->submenu);
|
||||
}
|
79
applications/main/lfrfid/scenes/lfrfid_scene_read_success.c
Normal file
79
applications/main/lfrfid/scenes/lfrfid_scene_read_success.c
Normal file
@@ -0,0 +1,79 @@
|
||||
#include "../lfrfid_i.h"
|
||||
|
||||
void lfrfid_scene_read_success_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
Widget* widget = app->widget;
|
||||
|
||||
string_t tmp_string;
|
||||
string_init(tmp_string);
|
||||
|
||||
widget_add_button_element(widget, GuiButtonTypeLeft, "Retry", lfrfid_widget_callback, app);
|
||||
widget_add_button_element(widget, GuiButtonTypeRight, "More", lfrfid_widget_callback, app);
|
||||
|
||||
string_printf(
|
||||
tmp_string,
|
||||
"%s[%s]",
|
||||
protocol_dict_get_name(app->dict, app->protocol_id),
|
||||
protocol_dict_get_manufacturer(app->dict, app->protocol_id));
|
||||
|
||||
widget_add_string_element(
|
||||
widget, 0, 2, AlignLeft, AlignTop, FontPrimary, string_get_cstr(tmp_string));
|
||||
|
||||
string_reset(tmp_string);
|
||||
size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id);
|
||||
uint8_t* data = (uint8_t*)malloc(size);
|
||||
protocol_dict_get_data(app->dict, app->protocol_id, data, size);
|
||||
for(uint8_t i = 0; i < size; i++) {
|
||||
if(i != 0) {
|
||||
string_cat_printf(tmp_string, " ");
|
||||
}
|
||||
|
||||
if(i >= 9) {
|
||||
string_cat_printf(tmp_string, "...");
|
||||
break;
|
||||
} else {
|
||||
string_cat_printf(tmp_string, "%02X", data[i]);
|
||||
}
|
||||
}
|
||||
free(data);
|
||||
|
||||
string_t render_data;
|
||||
string_init(render_data);
|
||||
protocol_dict_render_brief_data(app->dict, render_data, app->protocol_id);
|
||||
string_cat_printf(tmp_string, "\r\n%s", string_get_cstr(render_data));
|
||||
string_clear(render_data);
|
||||
|
||||
widget_add_string_element(
|
||||
widget, 0, 16, AlignLeft, AlignTop, FontSecondary, string_get_cstr(tmp_string));
|
||||
|
||||
notification_message_block(app->notifications, &sequence_set_green_255);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget);
|
||||
string_clear(tmp_string);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_read_success_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
SceneManager* scene_manager = app->scene_manager;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
scene_manager_next_scene(scene_manager, LfRfidSceneExitConfirm);
|
||||
consumed = true;
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
consumed = true;
|
||||
if(event.event == GuiButtonTypeLeft) {
|
||||
scene_manager_next_scene(scene_manager, LfRfidSceneRetryConfirm);
|
||||
} else if(event.event == GuiButtonTypeRight) {
|
||||
scene_manager_next_scene(scene_manager, LfRfidSceneReadKeyMenu);
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_read_success_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
notification_message_block(app->notifications, &sequence_reset_green);
|
||||
widget_reset(app->widget);
|
||||
}
|
39
applications/main/lfrfid/scenes/lfrfid_scene_retry_confirm.c
Normal file
39
applications/main/lfrfid/scenes/lfrfid_scene_retry_confirm.c
Normal file
@@ -0,0 +1,39 @@
|
||||
#include "../lfrfid_i.h"
|
||||
|
||||
void lfrfid_scene_retry_confirm_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
Widget* widget = app->widget;
|
||||
|
||||
widget_add_button_element(widget, GuiButtonTypeLeft, "Exit", lfrfid_widget_callback, app);
|
||||
widget_add_button_element(widget, GuiButtonTypeRight, "Stay", lfrfid_widget_callback, app);
|
||||
widget_add_string_element(
|
||||
widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Return to reading?");
|
||||
widget_add_string_element(
|
||||
widget, 64, 29, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost!");
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_retry_confirm_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
SceneManager* scene_manager = app->scene_manager;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeBack) {
|
||||
consumed = true; // Ignore Back button presses
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
consumed = true;
|
||||
if(event.event == GuiButtonTypeLeft) {
|
||||
scene_manager_search_and_switch_to_previous_scene(scene_manager, LfRfidSceneRead);
|
||||
} else if(event.event == GuiButtonTypeRight) {
|
||||
scene_manager_previous_scene(scene_manager);
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_retry_confirm_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
widget_reset(app->widget);
|
||||
}
|
67
applications/main/lfrfid/scenes/lfrfid_scene_rpc.c
Normal file
67
applications/main/lfrfid/scenes/lfrfid_scene_rpc.c
Normal file
@@ -0,0 +1,67 @@
|
||||
#include "../lfrfid_i.h"
|
||||
|
||||
void lfrfid_scene_rpc_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
Popup* popup = app->popup;
|
||||
|
||||
popup_set_header(popup, "LF RFID", 89, 42, AlignCenter, AlignBottom);
|
||||
popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop);
|
||||
popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup);
|
||||
|
||||
notification_message(app->notifications, &sequence_display_backlight_on);
|
||||
|
||||
app->rpc_state = LfRfidRpcStateIdle;
|
||||
}
|
||||
|
||||
bool lfrfid_scene_rpc_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
Popup* popup = app->popup;
|
||||
UNUSED(event);
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
consumed = true;
|
||||
if(event.event == LfRfidEventExit) {
|
||||
rpc_system_app_confirm(app->rpc_ctx, RpcAppEventAppExit, true);
|
||||
scene_manager_stop(app->scene_manager);
|
||||
view_dispatcher_stop(app->view_dispatcher);
|
||||
} else if(event.event == LfRfidEventRpcSessionClose) {
|
||||
scene_manager_stop(app->scene_manager);
|
||||
view_dispatcher_stop(app->view_dispatcher);
|
||||
} else if(event.event == LfRfidEventRpcLoadFile) {
|
||||
const char* arg = rpc_system_app_get_data(app->rpc_ctx);
|
||||
bool result = false;
|
||||
if(arg && (app->rpc_state == LfRfidRpcStateIdle)) {
|
||||
string_set_str(app->file_path, arg);
|
||||
if(lfrfid_load_key_data(app, app->file_path, false)) {
|
||||
lfrfid_worker_start_thread(app->lfworker);
|
||||
lfrfid_worker_emulate_start(app->lfworker, (LFRFIDProtocol)app->protocol_id);
|
||||
app->rpc_state = LfRfidRpcStateEmulating;
|
||||
|
||||
lfrfid_text_store_set(app, "emulating\n%s", string_get_cstr(app->file_name));
|
||||
popup_set_text(popup, app->text_store, 89, 44, AlignCenter, AlignTop);
|
||||
|
||||
notification_message(app->notifications, &sequence_blink_start_magenta);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
rpc_system_app_confirm(app->rpc_ctx, RpcAppEventLoadFile, result);
|
||||
}
|
||||
}
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_rpc_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
Popup* popup = app->popup;
|
||||
|
||||
if(app->rpc_state == LfRfidRpcStateEmulating) {
|
||||
lfrfid_worker_stop(app->lfworker);
|
||||
lfrfid_worker_stop_thread(app->lfworker);
|
||||
notification_message(app->notifications, &sequence_blink_stop);
|
||||
}
|
||||
|
||||
popup_reset(popup);
|
||||
}
|
51
applications/main/lfrfid/scenes/lfrfid_scene_save_data.c
Normal file
51
applications/main/lfrfid/scenes/lfrfid_scene_save_data.c
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "../lfrfid_i.h"
|
||||
#include <dolphin/dolphin.h>
|
||||
|
||||
void lfrfid_scene_save_data_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
ByteInput* byte_input = app->byte_input;
|
||||
|
||||
size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id);
|
||||
|
||||
bool need_restore = scene_manager_get_scene_state(app->scene_manager, LfRfidSceneSaveData);
|
||||
|
||||
if(need_restore) {
|
||||
protocol_dict_set_data(app->dict, app->protocol_id, app->old_key_data, size);
|
||||
} else {
|
||||
protocol_dict_get_data(app->dict, app->protocol_id, app->old_key_data, size);
|
||||
}
|
||||
|
||||
protocol_dict_get_data(app->dict, app->protocol_id, app->new_key_data, size);
|
||||
|
||||
byte_input_set_header_text(byte_input, "Enter the data in hex");
|
||||
|
||||
byte_input_set_result_callback(
|
||||
byte_input, lfrfid_text_input_callback, NULL, app, app->new_key_data, size);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewByteInput);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_save_data_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
SceneManager* scene_manager = app->scene_manager;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == LfRfidEventNext) {
|
||||
consumed = true;
|
||||
size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id);
|
||||
protocol_dict_set_data(app->dict, app->protocol_id, app->new_key_data, size);
|
||||
DOLPHIN_DEED(DolphinDeedRfidAdd);
|
||||
scene_manager_next_scene(scene_manager, LfRfidSceneSaveName);
|
||||
scene_manager_set_scene_state(scene_manager, LfRfidSceneSaveData, 1);
|
||||
}
|
||||
} else if(event.type == SceneManagerEventTypeBack) {
|
||||
scene_manager_set_scene_state(scene_manager, LfRfidSceneSaveData, 0);
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_save_data_on_exit(void* context) {
|
||||
UNUSED(context);
|
||||
}
|
76
applications/main/lfrfid/scenes/lfrfid_scene_save_name.c
Normal file
76
applications/main/lfrfid/scenes/lfrfid_scene_save_name.c
Normal file
@@ -0,0 +1,76 @@
|
||||
#include "m-string.h"
|
||||
#include <lib/toolbox/random_name.h>
|
||||
#include "../lfrfid_i.h"
|
||||
|
||||
void lfrfid_scene_save_name_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
TextInput* text_input = app->text_input;
|
||||
string_t folder_path;
|
||||
string_init(folder_path);
|
||||
|
||||
bool key_name_is_empty = string_empty_p(app->file_name);
|
||||
if(key_name_is_empty) {
|
||||
string_set_str(app->file_path, LFRFID_APP_FOLDER);
|
||||
set_random_name(app->text_store, LFRFID_TEXT_STORE_SIZE);
|
||||
string_set_str(folder_path, LFRFID_APP_FOLDER);
|
||||
} else {
|
||||
lfrfid_text_store_set(app, "%s", string_get_cstr(app->file_name));
|
||||
path_extract_dirname(string_get_cstr(app->file_path), folder_path);
|
||||
}
|
||||
|
||||
text_input_set_header_text(text_input, "Name the card");
|
||||
text_input_set_result_callback(
|
||||
text_input,
|
||||
lfrfid_text_input_callback,
|
||||
app,
|
||||
app->text_store,
|
||||
LFRFID_KEY_NAME_SIZE,
|
||||
key_name_is_empty);
|
||||
|
||||
FURI_LOG_I("", "%s %s", string_get_cstr(folder_path), app->text_store);
|
||||
|
||||
ValidatorIsFile* validator_is_file = validator_is_file_alloc_init(
|
||||
string_get_cstr(folder_path), LFRFID_APP_EXTENSION, string_get_cstr(app->file_name));
|
||||
text_input_set_validator(text_input, validator_is_file_callback, validator_is_file);
|
||||
|
||||
string_clear(folder_path);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewTextInput);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_save_name_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
SceneManager* scene_manager = app->scene_manager;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == LfRfidEventNext) {
|
||||
consumed = true;
|
||||
if(!string_empty_p(app->file_name)) {
|
||||
lfrfid_delete_key(app);
|
||||
}
|
||||
|
||||
string_set_str(app->file_name, app->text_store);
|
||||
|
||||
if(lfrfid_save_key(app)) {
|
||||
scene_manager_next_scene(scene_manager, LfRfidSceneSaveSuccess);
|
||||
} else {
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
scene_manager, LfRfidSceneReadKeyMenu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_save_name_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
TextInput* text_input = app->text_input;
|
||||
|
||||
void* validator_context = text_input_get_validator_callback_context(text_input);
|
||||
text_input_set_validator(text_input, NULL, NULL);
|
||||
validator_is_file_free((ValidatorIsFile*)validator_context);
|
||||
|
||||
text_input_reset(text_input);
|
||||
}
|
43
applications/main/lfrfid/scenes/lfrfid_scene_save_success.c
Normal file
43
applications/main/lfrfid/scenes/lfrfid_scene_save_success.c
Normal file
@@ -0,0 +1,43 @@
|
||||
#include "../lfrfid_i.h"
|
||||
#include <dolphin/dolphin.h>
|
||||
|
||||
void lfrfid_scene_save_success_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
Popup* popup = app->popup;
|
||||
|
||||
DOLPHIN_DEED(DolphinDeedRfidSave);
|
||||
popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59);
|
||||
popup_set_header(popup, "Saved!", 5, 7, AlignLeft, AlignTop);
|
||||
popup_set_context(popup, app);
|
||||
popup_set_callback(popup, lfrfid_popup_timeout_callback);
|
||||
popup_set_timeout(popup, 1500);
|
||||
popup_enable_timeout(popup);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_save_success_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
const uint32_t prev_scenes[] = {LfRfidSceneReadKeyMenu, LfRfidSceneSelectKey};
|
||||
|
||||
if((event.type == SceneManagerEventTypeBack) ||
|
||||
((event.type == SceneManagerEventTypeCustom) && (event.event == LfRfidEventPopupClosed))) {
|
||||
bool result = scene_manager_search_and_switch_to_previous_scene_one_of(
|
||||
app->scene_manager, prev_scenes, COUNT_OF(prev_scenes));
|
||||
if(!result) {
|
||||
scene_manager_search_and_switch_to_another_scene(
|
||||
app->scene_manager, LfRfidSceneSelectKey);
|
||||
}
|
||||
consumed = true;
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_save_success_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
|
||||
popup_reset(app->popup);
|
||||
}
|
86
applications/main/lfrfid/scenes/lfrfid_scene_save_type.c
Normal file
86
applications/main/lfrfid/scenes/lfrfid_scene_save_type.c
Normal file
@@ -0,0 +1,86 @@
|
||||
#include "../lfrfid_i.h"
|
||||
|
||||
typedef struct {
|
||||
string_t menu_item_name[LFRFIDProtocolMax];
|
||||
uint32_t line_sel;
|
||||
} SaveTypeCtx;
|
||||
|
||||
static void lfrfid_scene_save_type_submenu_callback(void* context, uint32_t index) {
|
||||
LfRfid* app = context;
|
||||
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, index);
|
||||
}
|
||||
|
||||
void lfrfid_scene_save_type_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
Submenu* submenu = app->submenu;
|
||||
|
||||
SaveTypeCtx* state = malloc(sizeof(SaveTypeCtx));
|
||||
for(uint8_t i = 0; i < LFRFIDProtocolMax; i++) {
|
||||
if(strcmp(
|
||||
protocol_dict_get_manufacturer(app->dict, i),
|
||||
protocol_dict_get_name(app->dict, i)) != 0) {
|
||||
string_init_printf(
|
||||
state->menu_item_name[i],
|
||||
"%s %s",
|
||||
protocol_dict_get_manufacturer(app->dict, i),
|
||||
protocol_dict_get_name(app->dict, i));
|
||||
} else {
|
||||
string_init_printf(
|
||||
state->menu_item_name[i], "%s", protocol_dict_get_name(app->dict, i));
|
||||
}
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
string_get_cstr(state->menu_item_name[i]),
|
||||
i,
|
||||
lfrfid_scene_save_type_submenu_callback,
|
||||
app);
|
||||
}
|
||||
|
||||
submenu_set_selected_item(
|
||||
submenu, scene_manager_get_scene_state(app->scene_manager, LfRfidSceneSaveType));
|
||||
|
||||
scene_manager_set_scene_state(app->scene_manager, LfRfidSceneSaveType, (uint32_t)state);
|
||||
|
||||
// clear key name
|
||||
string_reset(app->file_name);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewSubmenu);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_save_type_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
SaveTypeCtx* state =
|
||||
(SaveTypeCtx*)scene_manager_get_scene_state(app->scene_manager, LfRfidSceneSaveType);
|
||||
furi_check(state);
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
app->protocol_id = event.event;
|
||||
state->line_sel = event.event;
|
||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneSaveData);
|
||||
consumed = true;
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_save_type_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
SaveTypeCtx* state =
|
||||
(SaveTypeCtx*)scene_manager_get_scene_state(app->scene_manager, LfRfidSceneSaveType);
|
||||
furi_check(state);
|
||||
|
||||
submenu_reset(app->submenu);
|
||||
|
||||
for(uint8_t i = 0; i < LFRFIDProtocolMax; i++) {
|
||||
string_clear(state->menu_item_name[i]);
|
||||
}
|
||||
|
||||
uint32_t line_sel = state->line_sel;
|
||||
|
||||
free(state);
|
||||
|
||||
scene_manager_set_scene_state(app->scene_manager, LfRfidSceneSaveType, line_sel);
|
||||
}
|
51
applications/main/lfrfid/scenes/lfrfid_scene_saved_info.c
Normal file
51
applications/main/lfrfid/scenes/lfrfid_scene_saved_info.c
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "../lfrfid_i.h"
|
||||
|
||||
void lfrfid_scene_saved_info_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
Widget* widget = app->widget;
|
||||
|
||||
string_t tmp_string;
|
||||
string_init(tmp_string);
|
||||
|
||||
string_printf(
|
||||
tmp_string,
|
||||
"%s [%s]\r\n",
|
||||
string_get_cstr(app->file_name),
|
||||
protocol_dict_get_name(app->dict, app->protocol_id));
|
||||
|
||||
size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id);
|
||||
uint8_t* data = (uint8_t*)malloc(size);
|
||||
protocol_dict_get_data(app->dict, app->protocol_id, data, size);
|
||||
for(uint8_t i = 0; i < size; i++) {
|
||||
if(i != 0) {
|
||||
string_cat_printf(tmp_string, " ");
|
||||
}
|
||||
|
||||
string_cat_printf(tmp_string, "%02X", data[i]);
|
||||
}
|
||||
free(data);
|
||||
|
||||
string_t render_data;
|
||||
string_init(render_data);
|
||||
protocol_dict_render_data(app->dict, render_data, app->protocol_id);
|
||||
string_cat_printf(tmp_string, "\r\n%s", string_get_cstr(render_data));
|
||||
string_clear(render_data);
|
||||
|
||||
widget_add_string_multiline_element(
|
||||
widget, 0, 1, AlignLeft, AlignTop, FontSecondary, string_get_cstr(tmp_string));
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget);
|
||||
string_clear(tmp_string);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_saved_info_on_event(void* context, SceneManagerEvent event) {
|
||||
UNUSED(context);
|
||||
UNUSED(event);
|
||||
bool consumed = false;
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_saved_info_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
widget_reset(app->widget);
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
#include "../lfrfid_i.h"
|
||||
|
||||
typedef enum {
|
||||
SubmenuIndexEmulate,
|
||||
SubmenuIndexWrite,
|
||||
SubmenuIndexEdit,
|
||||
SubmenuIndexDelete,
|
||||
SubmenuIndexInfo,
|
||||
} SubmenuIndex;
|
||||
|
||||
static void lfrfid_scene_saved_key_menu_submenu_callback(void* context, uint32_t index) {
|
||||
LfRfid* app = context;
|
||||
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, index);
|
||||
}
|
||||
|
||||
void lfrfid_scene_saved_key_menu_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
Submenu* submenu = app->submenu;
|
||||
|
||||
submenu_add_item(
|
||||
submenu, "Emulate", SubmenuIndexEmulate, lfrfid_scene_saved_key_menu_submenu_callback, app);
|
||||
submenu_add_item(
|
||||
submenu, "Write", SubmenuIndexWrite, lfrfid_scene_saved_key_menu_submenu_callback, app);
|
||||
submenu_add_item(
|
||||
submenu, "Edit", SubmenuIndexEdit, lfrfid_scene_saved_key_menu_submenu_callback, app);
|
||||
submenu_add_item(
|
||||
submenu, "Delete", SubmenuIndexDelete, lfrfid_scene_saved_key_menu_submenu_callback, app);
|
||||
submenu_add_item(
|
||||
submenu, "Info", SubmenuIndexInfo, lfrfid_scene_saved_key_menu_submenu_callback, app);
|
||||
|
||||
submenu_set_selected_item(
|
||||
submenu, scene_manager_get_scene_state(app->scene_manager, LfRfidSceneSavedKeyMenu));
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewSubmenu);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_saved_key_menu_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == SubmenuIndexEmulate) {
|
||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneEmulate);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexWrite) {
|
||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneWrite);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexEdit) {
|
||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneSaveData);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexDelete) {
|
||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneDeleteConfirm);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexInfo) {
|
||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneSavedInfo);
|
||||
consumed = true;
|
||||
}
|
||||
scene_manager_set_scene_state(app->scene_manager, LfRfidSceneSavedKeyMenu, event.event);
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_saved_key_menu_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
|
||||
submenu_reset(app->submenu);
|
||||
}
|
22
applications/main/lfrfid/scenes/lfrfid_scene_select_key.c
Normal file
22
applications/main/lfrfid/scenes/lfrfid_scene_select_key.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "../lfrfid_i.h"
|
||||
|
||||
void lfrfid_scene_select_key_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
|
||||
if(lfrfid_load_key_from_file_select(app)) {
|
||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneSavedKeyMenu);
|
||||
} else {
|
||||
scene_manager_previous_scene(app->scene_manager);
|
||||
}
|
||||
}
|
||||
|
||||
bool lfrfid_scene_select_key_on_event(void* context, SceneManagerEvent event) {
|
||||
UNUSED(context);
|
||||
UNUSED(event);
|
||||
bool consumed = false;
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_select_key_on_exit(void* context) {
|
||||
UNUSED(context);
|
||||
}
|
72
applications/main/lfrfid/scenes/lfrfid_scene_start.c
Normal file
72
applications/main/lfrfid/scenes/lfrfid_scene_start.c
Normal file
@@ -0,0 +1,72 @@
|
||||
#include "../lfrfid_i.h"
|
||||
|
||||
typedef enum {
|
||||
SubmenuIndexRead,
|
||||
SubmenuIndexSaved,
|
||||
SubmenuIndexAddManually,
|
||||
SubmenuIndexExtraActions,
|
||||
} SubmenuIndex;
|
||||
|
||||
static void lfrfid_scene_start_submenu_callback(void* context, uint32_t index) {
|
||||
LfRfid* app = context;
|
||||
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, index);
|
||||
}
|
||||
|
||||
void lfrfid_scene_start_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
Submenu* submenu = app->submenu;
|
||||
|
||||
submenu_add_item(submenu, "Read", SubmenuIndexRead, lfrfid_scene_start_submenu_callback, app);
|
||||
submenu_add_item(
|
||||
submenu, "Saved", SubmenuIndexSaved, lfrfid_scene_start_submenu_callback, app);
|
||||
submenu_add_item(
|
||||
submenu, "Add Manually", SubmenuIndexAddManually, lfrfid_scene_start_submenu_callback, app);
|
||||
submenu_add_item(
|
||||
submenu,
|
||||
"Extra Actions",
|
||||
SubmenuIndexExtraActions,
|
||||
lfrfid_scene_start_submenu_callback,
|
||||
app);
|
||||
|
||||
submenu_set_selected_item(
|
||||
submenu, scene_manager_get_scene_state(app->scene_manager, LfRfidSceneStart));
|
||||
|
||||
// clear key
|
||||
string_reset(app->file_name);
|
||||
app->protocol_id = PROTOCOL_NO;
|
||||
app->read_type = LFRFIDWorkerReadTypeAuto;
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewSubmenu);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_start_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == SubmenuIndexRead) {
|
||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneRead);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexSaved) {
|
||||
string_set_str(app->file_path, LFRFID_APP_FOLDER);
|
||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneSelectKey);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexAddManually) {
|
||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneSaveType);
|
||||
consumed = true;
|
||||
} else if(event.event == SubmenuIndexExtraActions) {
|
||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneExtraActions);
|
||||
consumed = true;
|
||||
}
|
||||
scene_manager_set_scene_state(app->scene_manager, LfRfidSceneStart, event.event);
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_start_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
|
||||
submenu_reset(app->submenu);
|
||||
}
|
96
applications/main/lfrfid/scenes/lfrfid_scene_write.c
Normal file
96
applications/main/lfrfid/scenes/lfrfid_scene_write.c
Normal file
@@ -0,0 +1,96 @@
|
||||
#include "../lfrfid_i.h"
|
||||
|
||||
static void lfrfid_write_callback(LFRFIDWorkerWriteResult result, void* context) {
|
||||
LfRfid* app = context;
|
||||
uint32_t event = 0;
|
||||
|
||||
if(result == LFRFIDWorkerWriteOK) {
|
||||
event = LfRfidEventWriteOK;
|
||||
} else if(result == LFRFIDWorkerWriteProtocolCannotBeWritten) {
|
||||
event = LfRfidEventWriteProtocolCannotBeWritten;
|
||||
} else if(result == LFRFIDWorkerWriteFobCannotBeWritten) {
|
||||
event = LfRfidEventWriteFobCannotBeWritten;
|
||||
} else if(result == LFRFIDWorkerWriteTooLongToWrite) {
|
||||
event = LfRfidEventWriteTooLongToWrite;
|
||||
}
|
||||
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, event);
|
||||
}
|
||||
|
||||
void lfrfid_scene_write_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
Popup* popup = app->popup;
|
||||
|
||||
popup_set_header(popup, "Writing", 89, 30, AlignCenter, AlignTop);
|
||||
if(!string_empty_p(app->file_name)) {
|
||||
popup_set_text(popup, string_get_cstr(app->file_name), 89, 43, AlignCenter, AlignTop);
|
||||
} else {
|
||||
popup_set_text(
|
||||
popup,
|
||||
protocol_dict_get_name(app->dict, app->protocol_id),
|
||||
89,
|
||||
43,
|
||||
AlignCenter,
|
||||
AlignTop);
|
||||
}
|
||||
popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup);
|
||||
|
||||
size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id);
|
||||
app->old_key_data = (uint8_t*)malloc(size);
|
||||
protocol_dict_get_data(app->dict, app->protocol_id, app->old_key_data, size);
|
||||
|
||||
lfrfid_worker_start_thread(app->lfworker);
|
||||
lfrfid_worker_write_start(
|
||||
app->lfworker, (LFRFIDProtocol)app->protocol_id, lfrfid_write_callback, app);
|
||||
notification_message(app->notifications, &sequence_blink_start_magenta);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_write_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
Popup* popup = app->popup;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == LfRfidEventWriteOK) {
|
||||
notification_message(app->notifications, &sequence_success);
|
||||
scene_manager_next_scene(app->scene_manager, LfRfidSceneWriteSuccess);
|
||||
consumed = true;
|
||||
} else if(event.event == LfRfidEventWriteProtocolCannotBeWritten) {
|
||||
popup_set_icon(popup, 72, 17, &I_DolphinCommon_56x48);
|
||||
popup_set_header(popup, "Error", 64, 3, AlignCenter, AlignTop);
|
||||
popup_set_text(popup, "This protocol\ncannot be written", 3, 17, AlignLeft, AlignTop);
|
||||
notification_message(app->notifications, &sequence_blink_start_red);
|
||||
consumed = true;
|
||||
} else if(
|
||||
(event.event == LfRfidEventWriteFobCannotBeWritten) ||
|
||||
(event.event == LfRfidEventWriteTooLongToWrite)) {
|
||||
popup_set_icon(popup, 72, 17, &I_DolphinCommon_56x48);
|
||||
popup_set_header(popup, "Still trying to write...", 64, 3, AlignCenter, AlignTop);
|
||||
popup_set_text(
|
||||
popup,
|
||||
"Make sure this\ncard is writable\nand not\nprotected.",
|
||||
3,
|
||||
17,
|
||||
AlignLeft,
|
||||
AlignTop);
|
||||
notification_message(app->notifications, &sequence_blink_start_yellow);
|
||||
consumed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_write_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
notification_message(app->notifications, &sequence_blink_stop);
|
||||
popup_reset(app->popup);
|
||||
lfrfid_worker_stop(app->lfworker);
|
||||
lfrfid_worker_stop_thread(app->lfworker);
|
||||
|
||||
size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id);
|
||||
protocol_dict_set_data(app->dict, app->protocol_id, app->old_key_data, size);
|
||||
free(app->old_key_data);
|
||||
}
|
38
applications/main/lfrfid/scenes/lfrfid_scene_write_success.c
Normal file
38
applications/main/lfrfid/scenes/lfrfid_scene_write_success.c
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "../lfrfid_i.h"
|
||||
|
||||
void lfrfid_scene_write_success_on_enter(void* context) {
|
||||
LfRfid* app = context;
|
||||
Popup* popup = app->popup;
|
||||
|
||||
popup_set_header(popup, "Successfully\nwritten!", 94, 3, AlignCenter, AlignTop);
|
||||
popup_set_icon(popup, 0, 6, &I_RFIDDolphinSuccess_108x57);
|
||||
popup_set_context(popup, app);
|
||||
popup_set_callback(popup, lfrfid_popup_timeout_callback);
|
||||
popup_set_timeout(popup, 1500);
|
||||
popup_enable_timeout(popup);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup);
|
||||
notification_message_block(app->notifications, &sequence_set_green_255);
|
||||
}
|
||||
|
||||
bool lfrfid_scene_write_success_on_event(void* context, SceneManagerEvent event) {
|
||||
LfRfid* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
const uint32_t prev_scenes[] = {LfRfidSceneReadKeyMenu, LfRfidSceneSelectKey};
|
||||
|
||||
if((event.type == SceneManagerEventTypeBack) ||
|
||||
((event.type == SceneManagerEventTypeCustom) && (event.event == LfRfidEventPopupClosed))) {
|
||||
scene_manager_search_and_switch_to_previous_scene_one_of(
|
||||
app->scene_manager, prev_scenes, COUNT_OF(prev_scenes));
|
||||
consumed = true;
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void lfrfid_scene_write_success_on_exit(void* context) {
|
||||
LfRfid* app = context;
|
||||
notification_message_block(app->notifications, &sequence_reset_green);
|
||||
popup_reset(app->popup);
|
||||
}
|
Reference in New Issue
Block a user