diff --git a/CHANGELOG.md b/CHANGELOG.md
index cb6c16159..88ad7cdba 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,10 @@
### New changes
-* Fix qFlipper and other apps causes flipper crash while trying to interact with files - see commit `b2bd13`
-* NRF24 Sniffer update
-* Other fixes
+* Wifi Marauder app update (by @0xchocolate)
+* Updated Universal remote assets (by @Amec0e)
+* Fixed music player
+* Fixed typos in subghz encoders
+* OFW: New NFC info screens
+* OFW: U2F fixes
**Note: Prefer installing using web updater or by self update package, all needed assets will be installed**
diff --git a/ReadMe.md b/ReadMe.md
index eaee36f12..927369e07 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -83,6 +83,8 @@ See changelog in releases for latest updates!
## [- BadUSB: how to add new keyboard layouts](https://github.com/dummy-decoy/flipperzero_badusb_kl)
+## [- How to change Flipper name](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/CustomFlipperName.md)
+
### **Plugins**
## [- Configure UniversalRF Remix App](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/UniRFRemix.md)
@@ -121,7 +123,7 @@ See changelog in releases for latest updates!
# Where I can find IR, SubGhz, ... files, DBs, and other stuff?
## [Awesome Flipper Zero - Github](https://github.com/djsime1/awesome-flipperzero)
## [UberGuidoZ Playground - Large collection of files - Github](https://github.com/UberGuidoZ/Flipper)
-## [CAME, NICE, PT-2240, PT-2262 - SubGHz fixed code bruteforce](https://github.com/tobiabocchi/flipperzero-bruteforce)
+## [CAME-12bit, NICE-12bit, Linear-10bit, PT-2240 - SubGHz fixed code bruteforce](https://github.com/tobiabocchi/flipperzero-bruteforce)
diff --git a/applications/about/about.c b/applications/about/about.c
index 092d5566d..cb500a467 100644
--- a/applications/about/about.c
+++ b/applications/about/about.c
@@ -5,6 +5,7 @@
#include
#include
#include
+#include
#include
typedef DialogMessageButton (*AboutDialogScreen)(DialogsApp* dialogs, DialogMessage* message);
@@ -114,12 +115,13 @@ static DialogMessageButton hw_version_screen(DialogsApp* dialogs, DialogMessage*
string_cat_printf(
buffer,
- "%d.F%dB%dC%d %s %s\n",
+ "%d.F%dB%dC%d %s:%s %s\n",
furi_hal_version_get_hw_version(),
furi_hal_version_get_hw_target(),
furi_hal_version_get_hw_body(),
furi_hal_version_get_hw_connect(),
furi_hal_version_get_hw_region_name(),
+ furi_hal_region_get_name(),
my_name ? my_name : "Unknown");
string_cat_printf(buffer, "Serial Number:\n");
diff --git a/applications/accessor/accessor_app.cpp b/applications/accessor/accessor_app.cpp
index f021a816e..2e3e27ec4 100644
--- a/applications/accessor/accessor_app.cpp
+++ b/applications/accessor/accessor_app.cpp
@@ -32,14 +32,14 @@ void AccessorApp::run(void) {
}
AccessorApp::AccessorApp() {
- notification = static_cast(furi_record_open("notification"));
+ notification = static_cast(furi_record_open(RECORD_NOTIFICATION));
onewire_host = onewire_host_alloc();
furi_hal_power_enable_otg();
}
AccessorApp::~AccessorApp() {
furi_hal_power_disable_otg();
- furi_record_close("notification");
+ furi_record_close(RECORD_NOTIFICATION);
onewire_host_free(onewire_host);
}
diff --git a/applications/accessor/accessor_view_manager.cpp b/applications/accessor/accessor_view_manager.cpp
index 7c681cbba..db723d68c 100644
--- a/applications/accessor/accessor_view_manager.cpp
+++ b/applications/accessor/accessor_view_manager.cpp
@@ -15,7 +15,7 @@ AccessorAppViewManager::AccessorAppViewManager() {
popup = popup_alloc();
add_view(ViewType::Popup, popup_get_view(popup));
- gui = static_cast(furi_record_open("gui"));
+ gui = static_cast(furi_record_open(RECORD_GUI));
view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen);
// set previous view callback for all views
@@ -31,6 +31,7 @@ AccessorAppViewManager::~AccessorAppViewManager() {
view_dispatcher, static_cast(AccessorAppViewManager::ViewType::Popup));
// free view modules
+ furi_record_close(RECORD_GUI);
submenu_free(submenu);
popup_free(popup);
diff --git a/applications/applications.h b/applications/applications.h
index 72eaf9135..bc13f1b3e 100644
--- a/applications/applications.h
+++ b/applications/applications.h
@@ -18,6 +18,8 @@ typedef struct {
typedef void (*FlipperOnStartHook)(void);
+extern const char* FLIPPER_AUTORUN_APP_NAME;
+
/* Services list
* Spawned on startup
*/
diff --git a/applications/archive/helpers/archive_favorites.c b/applications/archive/helpers/archive_favorites.c
index fc0cad575..35199242e 100644
--- a/applications/archive/helpers/archive_favorites.c
+++ b/applications/archive/helpers/archive_favorites.c
@@ -64,7 +64,7 @@ uint16_t archive_favorites_count(void* context) {
break;
}
if(!string_size(buffer)) {
- break;
+ continue; // Skip empty lines
}
++lines;
}
@@ -93,7 +93,7 @@ static bool archive_favourites_rescan() {
break;
}
if(!string_size(buffer)) {
- break;
+ continue;
}
if(string_search(buffer, "/app:") == 0) {
@@ -152,7 +152,7 @@ bool archive_favorites_read(void* context) {
break;
}
if(!string_size(buffer)) {
- break;
+ continue;
}
if(string_search(buffer, "/app:") == 0) {
@@ -215,7 +215,7 @@ bool archive_favorites_delete(const char* format, ...) {
break;
}
if(!string_size(buffer)) {
- break;
+ continue;
}
if(string_search(buffer, filename)) {
@@ -259,7 +259,7 @@ bool archive_is_favorite(const char* format, ...) {
break;
}
if(!string_size(buffer)) {
- break;
+ continue;
}
if(!string_search(buffer, filename)) {
found = true;
@@ -299,7 +299,7 @@ bool archive_favorites_rename(const char* src, const char* dst) {
break;
}
if(!string_size(buffer)) {
- break;
+ continue;
}
archive_file_append(
diff --git a/applications/barcode_generator/barcode_generator.c b/applications/barcode_generator/barcode_generator.c
index 59d5d6ddf..d03d45495 100644
--- a/applications/barcode_generator/barcode_generator.c
+++ b/applications/barcode_generator/barcode_generator.c
@@ -423,7 +423,7 @@ int32_t barcode_UPCA_generator_app(void* p) {
view_port_input_callback_set(view_port, input_callback, event_queue);
// Open GUI and register view_port
- Gui* gui = furi_record_open("gui");
+ Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
PluginEvent event;
@@ -537,7 +537,7 @@ int32_t barcode_UPCA_generator_app(void* p) {
view_port_enabled_set(view_port, false);
gui_remove_view_port(gui, view_port);
- furi_record_close("gui");
+ furi_record_close(RECORD_GUI);
view_port_free(view_port);
furi_message_queue_free(event_queue);
diff --git a/applications/cli/cli_commands.c b/applications/cli/cli_commands.c
index 198877962..177a274a1 100644
--- a/applications/cli/cli_commands.c
+++ b/applications/cli/cli_commands.c
@@ -15,7 +15,7 @@
void cli_command_device_info_callback(const char* key, const char* value, bool last, void* context) {
UNUSED(context);
UNUSED(last);
- printf("%-24s: %s\r\n", key, value);
+ printf("%-30s: %s\r\n", key, value);
}
/*
diff --git a/applications/clock_app/clock_app.c b/applications/clock_app/clock_app.c
index 2931fac72..3614b8429 100644
--- a/applications/clock_app/clock_app.c
+++ b/applications/clock_app/clock_app.c
@@ -96,7 +96,7 @@ int32_t clock_app(void* p) {
furi_timer_start(timer, furi_kernel_get_tick_frequency());
// Open GUI and register view_port
- Gui* gui = furi_record_open("gui");
+ Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
// Main loop
@@ -137,7 +137,7 @@ int32_t clock_app(void* p) {
furi_timer_free(timer);
view_port_enabled_set(view_port, false);
gui_remove_view_port(gui, view_port);
- furi_record_close("gui");
+ furi_record_close(RECORD_GUI);
view_port_free(view_port);
furi_message_queue_free(event_queue);
delete_mutex(&state_mutex);
diff --git a/applications/dec_hex_converter/dec_hex_converter.c b/applications/dec_hex_converter/dec_hex_converter.c
index 1661dbd16..98a090a82 100644
--- a/applications/dec_hex_converter/dec_hex_converter.c
+++ b/applications/dec_hex_converter/dec_hex_converter.c
@@ -333,7 +333,7 @@ int32_t dec_hex_converter_app(void* p) {
view_port_input_callback_set(view_port, dec_hex_converter_input_callback, event_queue);
// open GUI and register view_port
- Gui* gui = furi_record_open("gui");
+ Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
dec_hex_converter_init(dec_hex_converter_state);
@@ -394,7 +394,7 @@ int32_t dec_hex_converter_app(void* p) {
view_port_enabled_set(view_port, false);
gui_remove_view_port(gui, view_port);
- furi_record_close("gui");
+ furi_record_close(RECORD_GUI);
view_port_free(view_port);
furi_message_queue_free(event_queue);
delete_mutex(&state_mutex);
diff --git a/applications/desktop/views/desktop_view_debug.c b/applications/desktop/views/desktop_view_debug.c
index e26411932..69c82bdbe 100644
--- a/applications/desktop/views/desktop_view_debug.c
+++ b/applications/desktop/views/desktop_view_debug.c
@@ -36,12 +36,13 @@ void desktop_debug_render(Canvas* canvas, void* model) {
snprintf(
buffer,
sizeof(buffer),
- "%d.F%dB%dC%d %s %s",
+ "%d.F%dB%dC%d %s:%s %s",
furi_hal_version_get_hw_version(),
furi_hal_version_get_hw_target(),
furi_hal_version_get_hw_body(),
furi_hal_version_get_hw_connect(),
furi_hal_version_get_hw_region_name(),
+ furi_hal_region_get_name(),
my_name ? my_name : "Unknown");
canvas_draw_str(canvas, 5, 19 + STATUS_BAR_Y_SHIFT, buffer);
diff --git a/applications/esp8266_deauth/esp8266_deauth.c b/applications/esp8266_deauth/esp8266_deauth.c
index 10bcd2af9..253ad650f 100644
--- a/applications/esp8266_deauth/esp8266_deauth.c
+++ b/applications/esp8266_deauth/esp8266_deauth.c
@@ -377,7 +377,7 @@ int32_t esp8266_deauth_app(void* p) {
view_port_input_callback_set(view_port, esp8266_deauth_module_input_callback, event_queue);
// Open GUI and register view_port
- Gui* gui = furi_record_open("gui");
+ Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
//notification_message(app->notification, &sequence_set_only_blue_255);
@@ -511,7 +511,7 @@ int32_t esp8266_deauth_app(void* p) {
gui_remove_view_port(gui, view_port);
// Close gui record
- furi_record_close("gui");
+ furi_record_close(RECORD_GUI);
furi_record_close("notification");
app->m_gui = NULL;
diff --git a/applications/gui/modules/widget.c b/applications/gui/modules/widget.c
index 8d7acb013..b37a64701 100644
--- a/applications/gui/modules/widget.c
+++ b/applications/gui/modules/widget.c
@@ -162,6 +162,19 @@ void widget_add_text_box_element(
widget_add_element(widget, text_box_element);
}
+void widget_add_text_scroll_element(
+ Widget* widget,
+ uint8_t x,
+ uint8_t y,
+ uint8_t width,
+ uint8_t height,
+ const char* text) {
+ furi_assert(widget);
+ WidgetElement* text_scroll_element =
+ widget_element_text_scroll_create(x, y, width, height, text);
+ widget_add_element(widget, text_scroll_element);
+}
+
void widget_add_button_element(
Widget* widget,
GuiButtonType button_type,
diff --git a/applications/gui/modules/widget.h b/applications/gui/modules/widget.h
index 55af59d7c..587fa3c65 100755
--- a/applications/gui/modules/widget.h
+++ b/applications/gui/modules/widget.h
@@ -105,6 +105,27 @@ void widget_add_text_box_element(
const char* text,
bool strip_to_dots);
+/** Add Text Scroll Element
+ *
+ * @param widget Widget instance
+ * @param x x coordinate
+ * @param y y coordinate
+ * @param width width to fit text
+ * @param height height to fit text
+ * @param[in] text Formatted text. Default format: align left, Secondary font.
+ * The following formats are available:
+ * "\e#Bold text" - sets bold font before until next '\n' symbol
+ * "\ecBold text" - sets center horizontal align before until next '\n' symbol
+ * "\erBold text" - sets right horizontal align before until next '\n' symbol
+ */
+void widget_add_text_scroll_element(
+ Widget* widget,
+ uint8_t x,
+ uint8_t y,
+ uint8_t width,
+ uint8_t height,
+ const char* text);
+
/** Add Button Element
*
* @param widget Widget instance
diff --git a/applications/gui/modules/widget_elements/widget_element_i.h b/applications/gui/modules/widget_elements/widget_element_i.h
index bcbd4afdb..316ed7400 100755
--- a/applications/gui/modules/widget_elements/widget_element_i.h
+++ b/applications/gui/modules/widget_elements/widget_element_i.h
@@ -29,6 +29,7 @@ struct WidgetElement {
// generic model holder
void* model;
+ FuriMutex* model_mutex;
// pointer to widget that hold our element
Widget* parent;
@@ -80,3 +81,10 @@ WidgetElement* widget_element_frame_create(
uint8_t width,
uint8_t height,
uint8_t radius);
+
+WidgetElement* widget_element_text_scroll_create(
+ uint8_t x,
+ uint8_t y,
+ uint8_t width,
+ uint8_t height,
+ const char* text);
diff --git a/applications/gui/modules/widget_elements/widget_element_text_scroll.c b/applications/gui/modules/widget_elements/widget_element_text_scroll.c
new file mode 100644
index 000000000..6682b106a
--- /dev/null
+++ b/applications/gui/modules/widget_elements/widget_element_text_scroll.c
@@ -0,0 +1,245 @@
+#include "widget_element_i.h"
+#include
+#include
+#include
+
+#define WIDGET_ELEMENT_TEXT_SCROLL_BAR_OFFSET (4)
+
+typedef struct {
+ Font font;
+ Align horizontal;
+ string_t text;
+} TextScrollLineArray;
+
+ARRAY_DEF(TextScrollLineArray, TextScrollLineArray, M_POD_OPLIST)
+
+typedef struct {
+ TextScrollLineArray_t line_array;
+ uint8_t x;
+ uint8_t y;
+ uint8_t width;
+ uint8_t height;
+ string_t text;
+ uint8_t scroll_pos_total;
+ uint8_t scroll_pos_current;
+ bool text_formatted;
+} WidgetElementTextScrollModel;
+
+static bool
+ widget_element_text_scroll_process_ctrl_symbols(TextScrollLineArray* line, string_t text) {
+ bool processed = false;
+
+ do {
+ if(string_get_char(text, 0) != '\e') break;
+ char ctrl_symbol = string_get_char(text, 1);
+ if(ctrl_symbol == 'c') {
+ line->horizontal = AlignCenter;
+ } else if(ctrl_symbol == 'r') {
+ line->horizontal = AlignRight;
+ } else if(ctrl_symbol == '#') {
+ line->font = FontPrimary;
+ }
+ string_right(text, 2);
+ processed = true;
+ } while(false);
+
+ return processed;
+}
+
+void widget_element_text_scroll_add_line(WidgetElement* element, TextScrollLineArray* line) {
+ WidgetElementTextScrollModel* model = element->model;
+ TextScrollLineArray new_line;
+ new_line.font = line->font;
+ new_line.horizontal = line->horizontal;
+ string_init_set(new_line.text, line->text);
+ TextScrollLineArray_push_back(model->line_array, new_line);
+}
+
+static void widget_element_text_scroll_fill_lines(Canvas* canvas, WidgetElement* element) {
+ WidgetElementTextScrollModel* model = element->model;
+ TextScrollLineArray line_tmp;
+ bool all_text_processed = false;
+ string_init(line_tmp.text);
+ bool reached_new_line = true;
+ uint16_t total_height = 0;
+
+ while(!all_text_processed) {
+ if(reached_new_line) {
+ // Set default line properties
+ line_tmp.font = FontSecondary;
+ line_tmp.horizontal = AlignLeft;
+ string_reset(line_tmp.text);
+ // Process control symbols
+ while(widget_element_text_scroll_process_ctrl_symbols(&line_tmp, model->text))
+ ;
+ }
+ // Set canvas font
+ canvas_set_font(canvas, line_tmp.font);
+ CanvasFontParameters* params = canvas_get_font_params(canvas, line_tmp.font);
+ total_height += params->height;
+ if(total_height > model->height) {
+ model->scroll_pos_total++;
+ }
+
+ uint8_t line_width = 0;
+ uint16_t char_i = 0;
+ while(true) {
+ char next_char = string_get_char(model->text, char_i++);
+ if(next_char == '\0') {
+ string_push_back(line_tmp.text, '\0');
+ widget_element_text_scroll_add_line(element, &line_tmp);
+ total_height += params->leading_default - params->height;
+ all_text_processed = true;
+ break;
+ } else if(next_char == '\n') {
+ string_push_back(line_tmp.text, '\0');
+ widget_element_text_scroll_add_line(element, &line_tmp);
+ string_right(model->text, char_i);
+ total_height += params->leading_default - params->height;
+ reached_new_line = true;
+ break;
+ } else {
+ line_width += canvas_glyph_width(canvas, next_char);
+ if(line_width > model->width) {
+ string_push_back(line_tmp.text, '\0');
+ widget_element_text_scroll_add_line(element, &line_tmp);
+ string_right(model->text, char_i - 1);
+ string_reset(line_tmp.text);
+ total_height += params->leading_default - params->height;
+ reached_new_line = false;
+ break;
+ } else {
+ string_push_back(line_tmp.text, next_char);
+ }
+ }
+ }
+ }
+
+ string_clear(line_tmp.text);
+}
+
+static void widget_element_text_scroll_draw(Canvas* canvas, WidgetElement* element) {
+ furi_assert(canvas);
+ furi_assert(element);
+
+ furi_mutex_acquire(element->model_mutex, FuriWaitForever);
+
+ WidgetElementTextScrollModel* model = element->model;
+ if(!model->text_formatted) {
+ widget_element_text_scroll_fill_lines(canvas, element);
+ model->text_formatted = true;
+ }
+
+ uint8_t y = model->y;
+ uint8_t x = model->x;
+ uint16_t curr_line = 0;
+ if(TextScrollLineArray_size(model->line_array)) {
+ TextScrollLineArray_it_t it;
+ for(TextScrollLineArray_it(it, model->line_array); !TextScrollLineArray_end_p(it);
+ TextScrollLineArray_next(it), curr_line++) {
+ if(curr_line < model->scroll_pos_current) continue;
+ TextScrollLineArray* line = TextScrollLineArray_ref(it);
+ CanvasFontParameters* params = canvas_get_font_params(canvas, line->font);
+ if(y + params->descender > model->y + model->height) break;
+ canvas_set_font(canvas, line->font);
+ if(line->horizontal == AlignLeft) {
+ x = model->x;
+ } else if(line->horizontal == AlignCenter) {
+ x = (model->x + model->width) / 2;
+ } else if(line->horizontal == AlignRight) {
+ x = model->x + model->width;
+ }
+ canvas_draw_str_aligned(
+ canvas, x, y, line->horizontal, AlignTop, string_get_cstr(line->text));
+ y += params->leading_default;
+ }
+ // Draw scroll bar
+ if(model->scroll_pos_total > 1) {
+ elements_scrollbar_pos(
+ canvas,
+ model->x + model->width + WIDGET_ELEMENT_TEXT_SCROLL_BAR_OFFSET,
+ model->y,
+ model->height,
+ model->scroll_pos_current,
+ model->scroll_pos_total);
+ }
+ }
+
+ furi_mutex_release(element->model_mutex);
+}
+
+static bool widget_element_text_scroll_input(InputEvent* event, WidgetElement* element) {
+ furi_assert(event);
+ furi_assert(element);
+
+ furi_mutex_acquire(element->model_mutex, FuriWaitForever);
+
+ WidgetElementTextScrollModel* model = element->model;
+ bool consumed = false;
+
+ if((event->type == InputTypeShort) || (event->type == InputTypeRepeat)) {
+ if(event->key == InputKeyUp) {
+ if(model->scroll_pos_current > 0) {
+ model->scroll_pos_current--;
+ }
+ consumed = true;
+ } else if(event->key == InputKeyDown) {
+ if((model->scroll_pos_total > 1) &&
+ (model->scroll_pos_current < model->scroll_pos_total - 1)) {
+ model->scroll_pos_current++;
+ }
+ consumed = true;
+ }
+ }
+
+ furi_mutex_release(element->model_mutex);
+
+ return consumed;
+}
+
+static void widget_element_text_scroll_free(WidgetElement* text_scroll) {
+ furi_assert(text_scroll);
+
+ WidgetElementTextScrollModel* model = text_scroll->model;
+ TextScrollLineArray_it_t it;
+ for(TextScrollLineArray_it(it, model->line_array); !TextScrollLineArray_end_p(it);
+ TextScrollLineArray_next(it)) {
+ TextScrollLineArray* line = TextScrollLineArray_ref(it);
+ string_clear(line->text);
+ }
+ TextScrollLineArray_clear(model->line_array);
+ string_clear(model->text);
+ free(text_scroll->model);
+ furi_mutex_free(text_scroll->model_mutex);
+ free(text_scroll);
+}
+
+WidgetElement* widget_element_text_scroll_create(
+ uint8_t x,
+ uint8_t y,
+ uint8_t width,
+ uint8_t height,
+ const char* text) {
+ furi_assert(text);
+
+ // Allocate and init model
+ WidgetElementTextScrollModel* model = malloc(sizeof(WidgetElementTextScrollModel));
+ model->x = x;
+ model->y = y;
+ model->width = width - WIDGET_ELEMENT_TEXT_SCROLL_BAR_OFFSET;
+ model->height = height;
+ model->scroll_pos_current = 0;
+ model->scroll_pos_total = 1;
+ TextScrollLineArray_init(model->line_array);
+ string_init_set_str(model->text, text);
+
+ WidgetElement* text_scroll = malloc(sizeof(WidgetElement));
+ text_scroll->parent = NULL;
+ text_scroll->draw = widget_element_text_scroll_draw;
+ text_scroll->input = widget_element_text_scroll_input;
+ text_scroll->free = widget_element_text_scroll_free;
+ text_scroll->model = model;
+ text_scroll->model_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
+
+ return text_scroll;
+}
diff --git a/applications/hid_analyzer/hid_analyzer_app.cpp b/applications/hid_analyzer/hid_analyzer_app.cpp
index 7c3ce76bc..e8d7fd541 100644
--- a/applications/hid_analyzer/hid_analyzer_app.cpp
+++ b/applications/hid_analyzer/hid_analyzer_app.cpp
@@ -16,6 +16,7 @@ HIDApp::~HIDApp() {
void HIDApp::run(void* _args) {
UNUSED(_args);
+ view_controller.attach_to_gui(ViewDispatcherTypeFullscreen);
scene_controller.add_scene(SceneType::Read, new HIDAppSceneRead());
scene_controller.add_scene(SceneType::ReadSuccess, new HIDAppSceneReadSuccess());
scene_controller.process(100, SceneType::Read);
diff --git a/applications/ibutton/ibutton.c b/applications/ibutton/ibutton.c
index b30a4c61f..7ee1110e1 100644
--- a/applications/ibutton/ibutton.c
+++ b/applications/ibutton/ibutton.c
@@ -87,6 +87,8 @@ static void ibutton_rpc_command_callback(RpcAppSystemEvent event, void* context)
if(event == RpcAppEventSessionClose) {
view_dispatcher_send_custom_event(
ibutton->view_dispatcher, iButtonCustomEventRpcSessionClose);
+ rpc_system_app_set_callback(ibutton->rpc_ctx, NULL, NULL);
+ ibutton->rpc_ctx = NULL;
} else if(event == RpcAppEventAppExit) {
view_dispatcher_send_custom_event(ibutton->view_dispatcher, iButtonCustomEventRpcExit);
} else if(event == RpcAppEventLoadFile) {
diff --git a/applications/ibutton/scenes/ibutton_scene_rpc.c b/applications/ibutton/scenes/ibutton_scene_rpc.c
index a3f5eeee4..0755c8ff8 100644
--- a/applications/ibutton/scenes/ibutton_scene_rpc.c
+++ b/applications/ibutton/scenes/ibutton_scene_rpc.c
@@ -29,7 +29,7 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) {
if(event.event == iButtonCustomEventRpcLoad) {
const char* arg = rpc_system_app_get_data(ibutton->rpc_ctx);
bool result = false;
- if(arg) {
+ if(arg && (string_empty_p(ibutton->file_path))) {
string_set_str(ibutton->file_path, arg);
if(ibutton_load_key_data(ibutton, ibutton->file_path, false)) {
ibutton_worker_emulate_start(ibutton->key_worker, ibutton->key);
@@ -51,17 +51,17 @@ bool ibutton_scene_rpc_on_event(void* context, SceneManagerEvent event) {
string_clear(key_name);
result = true;
+ } else {
+ string_reset(ibutton->file_path);
}
}
rpc_system_app_confirm(ibutton->rpc_ctx, RpcAppEventLoadFile, result);
} else if(event.event == iButtonCustomEventRpcExit) {
rpc_system_app_confirm(ibutton->rpc_ctx, RpcAppEventAppExit, true);
- ibutton_notification_message(ibutton, iButtonNotificationMessageBlinkStop);
+ scene_manager_stop(ibutton->scene_manager);
view_dispatcher_stop(ibutton->view_dispatcher);
} else if(event.event == iButtonCustomEventRpcSessionClose) {
- rpc_system_app_set_callback(ibutton->rpc_ctx, NULL, NULL);
- ibutton->rpc_ctx = NULL;
- ibutton_notification_message(ibutton, iButtonNotificationMessageBlinkStop);
+ scene_manager_stop(ibutton->scene_manager);
view_dispatcher_stop(ibutton->view_dispatcher);
}
}
diff --git a/applications/infrared/infrared.c b/applications/infrared/infrared.c
index aef14f9b8..60809e787 100644
--- a/applications/infrared/infrared.c
+++ b/applications/infrared/infrared.c
@@ -46,6 +46,8 @@ static void infrared_rpc_command_callback(RpcAppSystemEvent event, void* context
if(event == RpcAppEventSessionClose) {
view_dispatcher_send_custom_event(
infrared->view_dispatcher, InfraredCustomEventTypeRpcSessionClose);
+ rpc_system_app_set_callback(infrared->rpc_ctx, NULL, NULL);
+ infrared->rpc_ctx = NULL;
} else if(event == RpcAppEventAppExit) {
view_dispatcher_send_custom_event(
infrared->view_dispatcher, InfraredCustomEventTypeRpcExit);
@@ -293,6 +295,13 @@ bool infrared_rename_current_remote(Infrared* infrared, const char* name) {
}
void infrared_tx_start_signal(Infrared* infrared, InfraredSignal* signal) {
+ if(infrared->app_state.is_transmitting) {
+ FURI_LOG_D(INFRARED_LOG_TAG, "Transmitter is already active");
+ return;
+ } else {
+ infrared->app_state.is_transmitting = true;
+ }
+
if(infrared_signal_is_raw(signal)) {
InfraredRawSignal* raw = infrared_signal_get_raw_signal(signal);
infrared_worker_set_raw_signal(infrared->worker, raw->timings, raw->timings_size);
@@ -302,8 +311,11 @@ void infrared_tx_start_signal(Infrared* infrared, InfraredSignal* signal) {
}
DOLPHIN_DEED(DolphinDeedIrSend);
- infrared_worker_tx_start(infrared->worker);
infrared_play_notification_message(infrared, InfraredNotificationMessageBlinkStartSend);
+
+ infrared_worker_tx_set_get_signal_callback(
+ infrared->worker, infrared_worker_tx_get_signal_steady_callback, infrared);
+ infrared_worker_tx_start(infrared->worker);
}
void infrared_tx_start_button_index(Infrared* infrared, size_t button_index) {
@@ -322,7 +334,16 @@ void infrared_tx_start_received(Infrared* infrared) {
}
void infrared_tx_stop(Infrared* infrared) {
+ if(!infrared->app_state.is_transmitting) {
+ FURI_LOG_D(INFRARED_LOG_TAG, "Transmitter is already stopped");
+ return;
+ } else {
+ infrared->app_state.is_transmitting = false;
+ }
+
infrared_worker_tx_stop(infrared->worker);
+ infrared_worker_tx_set_get_signal_callback(infrared->worker, NULL, NULL);
+
infrared_play_notification_message(infrared, InfraredNotificationMessageBlinkStop);
}
diff --git a/applications/infrared/infrared_i.h b/applications/infrared/infrared_i.h
index 4e9c79d51..952152587 100644
--- a/applications/infrared/infrared_i.h
+++ b/applications/infrared/infrared_i.h
@@ -43,6 +43,7 @@
#define INFRARED_APP_EXTENSION ".ir"
#define INFRARED_DEFAULT_REMOTE_NAME "Remote"
+#define INFRARED_LOG_TAG "InfraredApp"
typedef enum {
InfraredButtonIndexNone = -1,
@@ -63,6 +64,7 @@ typedef enum {
typedef struct {
bool is_learning_new_remote;
bool is_debug_enabled;
+ bool is_transmitting;
InfraredEditTarget edit_target : 8;
InfraredEditMode edit_mode : 8;
int32_t current_button_index;
diff --git a/applications/infrared/scenes/infrared_scene_learn_success.c b/applications/infrared/scenes/infrared_scene_learn_success.c
index 49e2f45f0..466627144 100644
--- a/applications/infrared/scenes/infrared_scene_learn_success.c
+++ b/applications/infrared/scenes/infrared_scene_learn_success.c
@@ -2,11 +2,6 @@
#include
-typedef enum {
- InfraredSceneLearnSuccessStateIdle = 0,
- InfraredSceneLearnSuccessStateSending = 1,
-} InfraredSceneLearnSuccessState;
-
static void
infrared_scene_learn_success_dialog_result_callback(DialogExResult result, void* context) {
Infrared* infrared = context;
@@ -21,9 +16,6 @@ void infrared_scene_learn_success_on_enter(void* context) {
DOLPHIN_DEED(DolphinDeedIrLearnSuccess);
infrared_play_notification_message(infrared, InfraredNotificationMessageGreenOn);
- infrared_worker_tx_set_get_signal_callback(
- infrared->worker, infrared_worker_tx_get_signal_steady_callback, context);
-
if(infrared_signal_is_raw(signal)) {
InfraredRawSignal* raw = infrared_signal_get_raw_signal(signal);
dialog_ex_set_header(dialog_ex, "Unknown", 95, 10, AlignCenter, AlignCenter);
@@ -63,57 +55,42 @@ void infrared_scene_learn_success_on_enter(void* context) {
dialog_ex_set_context(dialog_ex, context);
dialog_ex_enable_extended_events(dialog_ex);
- scene_manager_set_scene_state(
- infrared->scene_manager, InfraredSceneLearnSuccess, InfraredSceneLearnSuccessStateIdle);
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewDialogEx);
}
bool infrared_scene_learn_success_on_event(void* context, SceneManagerEvent event) {
Infrared* infrared = context;
SceneManager* scene_manager = infrared->scene_manager;
- uint32_t scene_state = scene_manager_get_scene_state(scene_manager, InfraredSceneLearnSuccess);
+ const bool is_transmitter_idle = !infrared->app_state.is_transmitting;
bool consumed = false;
if(event.type == SceneManagerEventTypeTick) {
- if(scene_state == InfraredSceneLearnSuccessStateIdle) {
+ if(is_transmitter_idle) {
infrared_play_notification_message(infrared, InfraredNotificationMessageGreenOn);
}
consumed = true;
} else if(event.type == SceneManagerEventTypeBack) {
- if(scene_state == InfraredSceneLearnSuccessStateIdle) {
+ if(is_transmitter_idle) {
scene_manager_next_scene(scene_manager, InfraredSceneAskBack);
}
consumed = true;
} else if(event.type == SceneManagerEventTypeCustom) {
if(event.event == DialogExResultLeft) {
- if(scene_state == InfraredSceneLearnSuccessStateIdle) {
+ if(is_transmitter_idle) {
scene_manager_next_scene(scene_manager, InfraredSceneAskRetry);
}
consumed = true;
} else if(event.event == DialogExResultRight) {
- if(scene_state == InfraredSceneLearnSuccessStateIdle) {
+ if(is_transmitter_idle) {
scene_manager_next_scene(scene_manager, InfraredSceneLearnEnterName);
}
consumed = true;
} else if(event.event == DialogExPressCenter) {
- if(scene_state == InfraredSceneLearnSuccessStateIdle) {
- scene_manager_set_scene_state(
- scene_manager,
- InfraredSceneLearnSuccess,
- InfraredSceneLearnSuccessStateSending);
- infrared_tx_start_received(infrared);
- infrared_play_notification_message(
- infrared, InfraredNotificationMessageBlinkStartSend);
- }
+ infrared_play_notification_message(infrared, InfraredNotificationMessageGreenOff);
+ infrared_tx_start_received(infrared);
consumed = true;
} else if(event.event == DialogExReleaseCenter) {
- if(scene_state == InfraredSceneLearnSuccessStateSending) {
- scene_manager_set_scene_state(
- scene_manager, InfraredSceneLearnSuccess, InfraredSceneLearnSuccessStateIdle);
- infrared_tx_stop(infrared);
- infrared_play_notification_message(infrared, InfraredNotificationMessageBlinkStop);
- infrared_play_notification_message(infrared, InfraredNotificationMessageGreenOff);
- }
+ infrared_tx_stop(infrared);
consumed = true;
}
}
@@ -123,9 +100,6 @@ bool infrared_scene_learn_success_on_event(void* context, SceneManagerEvent even
void infrared_scene_learn_success_on_exit(void* context) {
Infrared* infrared = context;
- InfraredWorker* worker = infrared->worker;
dialog_ex_reset(infrared->dialog_ex);
- infrared_play_notification_message(infrared, InfraredNotificationMessageBlinkStop);
infrared_play_notification_message(infrared, InfraredNotificationMessageGreenOff);
- infrared_worker_tx_set_get_signal_callback(worker, NULL, NULL);
}
diff --git a/applications/infrared/scenes/infrared_scene_remote.c b/applications/infrared/scenes/infrared_scene_remote.c
index bcac58819..c1f5b6627 100644
--- a/applications/infrared/scenes/infrared_scene_remote.c
+++ b/applications/infrared/scenes/infrared_scene_remote.c
@@ -31,9 +31,6 @@ void infrared_scene_remote_on_enter(void* context) {
ButtonMenu* button_menu = infrared->button_menu;
SceneManager* scene_manager = infrared->scene_manager;
- infrared_worker_tx_set_get_signal_callback(
- infrared->worker, infrared_worker_tx_get_signal_steady_callback, infrared);
-
size_t button_count = infrared_remote_get_button_count(remote);
for(size_t i = 0; i < button_count; ++i) {
InfraredRemoteButton* button = infrared_remote_get_button(remote, i);
@@ -73,12 +70,17 @@ void infrared_scene_remote_on_enter(void* context) {
bool infrared_scene_remote_on_event(void* context, SceneManagerEvent event) {
Infrared* infrared = context;
SceneManager* scene_manager = infrared->scene_manager;
+ const bool is_transmitter_idle = !infrared->app_state.is_transmitting;
bool consumed = false;
if(event.type == SceneManagerEventTypeBack) {
- const uint32_t possible_scenes[] = {InfraredSceneRemoteList, InfraredSceneStart};
- consumed = scene_manager_search_and_switch_to_previous_scene_one_of(
- scene_manager, possible_scenes, COUNT_OF(possible_scenes));
+ if(is_transmitter_idle) {
+ const uint32_t possible_scenes[] = {InfraredSceneRemoteList, InfraredSceneStart};
+ consumed = scene_manager_search_and_switch_to_previous_scene_one_of(
+ scene_manager, possible_scenes, COUNT_OF(possible_scenes));
+ } else {
+ consumed = true;
+ }
} else if(event.type == SceneManagerEventTypeCustom) {
const uint16_t custom_type = infrared_custom_event_get_type(event.event);
const int16_t button_index = infrared_custom_event_get_value(event.event);
@@ -92,14 +94,19 @@ bool infrared_scene_remote_on_event(void* context, SceneManagerEvent event) {
consumed = true;
} else if(custom_type == InfraredCustomEventTypeMenuSelected) {
furi_assert(button_index < 0);
- scene_manager_set_scene_state(
- scene_manager, InfraredSceneRemote, (unsigned)button_index);
- if(button_index == ButtonIndexPlus) {
- infrared->app_state.is_learning_new_remote = false;
- scene_manager_next_scene(scene_manager, InfraredSceneLearn);
- consumed = true;
- } else if(button_index == ButtonIndexEdit) {
- scene_manager_next_scene(scene_manager, InfraredSceneEdit);
+ if(is_transmitter_idle) {
+ scene_manager_set_scene_state(
+ scene_manager, InfraredSceneRemote, (unsigned)button_index);
+ if(button_index == ButtonIndexPlus) {
+ infrared->app_state.is_learning_new_remote = false;
+ scene_manager_next_scene(scene_manager, InfraredSceneLearn);
+ consumed = true;
+ } else if(button_index == ButtonIndexEdit) {
+ scene_manager_next_scene(scene_manager, InfraredSceneEdit);
+ consumed = true;
+ }
+
+ } else {
consumed = true;
}
}
@@ -110,7 +117,5 @@ bool infrared_scene_remote_on_event(void* context, SceneManagerEvent event) {
void infrared_scene_remote_on_exit(void* context) {
Infrared* infrared = context;
- infrared_tx_stop(infrared);
- infrared_worker_tx_set_get_signal_callback(infrared->worker, NULL, NULL);
button_menu_reset(infrared->button_menu);
}
diff --git a/applications/infrared/scenes/infrared_scene_rpc.c b/applications/infrared/scenes/infrared_scene_rpc.c
index bc9c8652f..ca7bbd8df 100644
--- a/applications/infrared/scenes/infrared_scene_rpc.c
+++ b/applications/infrared/scenes/infrared_scene_rpc.c
@@ -1,20 +1,28 @@
#include "../infrared_i.h"
#include "gui/canvas.h"
+typedef enum {
+ InfraredRpcStateIdle,
+ InfraredRpcStateLoaded,
+ InfraredRpcStateSending,
+} InfraredRpcState;
+
void infrared_scene_rpc_on_enter(void* context) {
Infrared* infrared = context;
Popup* popup = infrared->popup;
- popup_set_header(popup, "Infrared", 82, 28, AlignCenter, AlignBottom);
- popup_set_text(popup, "RPC mode", 82, 32, AlignCenter, AlignTop);
+ popup_set_header(popup, "Infrared", 89, 42, AlignCenter, AlignBottom);
+ popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop);
- popup_set_icon(popup, 2, 14, &I_Warning_30x23); // TODO: icon
+ popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61);
popup_set_context(popup, context);
popup_set_callback(popup, infrared_popup_closed_callback);
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup);
+ scene_manager_set_scene_state(infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateIdle);
+
notification_message(infrared->notifications, &sequence_display_backlight_on);
}
@@ -24,6 +32,8 @@ bool infrared_scene_rpc_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
consumed = true;
+ InfraredRpcState state =
+ scene_manager_get_scene_state(infrared->scene_manager, InfraredSceneRpc);
if(event.event == InfraredCustomEventTypeBackPressed) {
view_dispatcher_stop(infrared->view_dispatcher);
} else if(event.event == InfraredCustomEventTypePopupClosed) {
@@ -31,39 +41,49 @@ bool infrared_scene_rpc_on_event(void* context, SceneManagerEvent event) {
} else if(event.event == InfraredCustomEventTypeRpcLoad) {
bool result = false;
const char* arg = rpc_system_app_get_data(infrared->rpc_ctx);
- if(arg) {
+ if(arg && (state == InfraredRpcStateIdle)) {
string_set_str(infrared->file_path, arg);
result = infrared_remote_load(infrared->remote, infrared->file_path);
- infrared_worker_tx_set_get_signal_callback(
- infrared->worker, infrared_worker_tx_get_signal_steady_callback, infrared);
+ if(result) {
+ scene_manager_set_scene_state(
+ infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateLoaded);
+ }
}
const char* remote_name = infrared_remote_get_name(infrared->remote);
infrared_text_store_set(infrared, 0, "loaded\n%s", remote_name);
popup_set_text(
- infrared->popup, infrared->text_store[0], 82, 32, AlignCenter, AlignTop);
+ infrared->popup, infrared->text_store[0], 89, 44, AlignCenter, AlignTop);
rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventLoadFile, result);
} else if(event.event == InfraredCustomEventTypeRpcButtonPress) {
bool result = false;
const char* arg = rpc_system_app_get_data(infrared->rpc_ctx);
- if(arg) {
+ if(arg && (state == InfraredRpcStateLoaded)) {
size_t button_index = 0;
if(infrared_remote_find_button_by_name(infrared->remote, arg, &button_index)) {
infrared_tx_start_button_index(infrared, button_index);
result = true;
+ scene_manager_set_scene_state(
+ infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateSending);
}
}
rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventButtonRelease, result);
} else if(event.event == InfraredCustomEventTypeRpcButtonRelease) {
- infrared_tx_stop(infrared);
- rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventButtonRelease, true);
+ bool result = false;
+ if(state == InfraredRpcStateSending) {
+ infrared_tx_stop(infrared);
+ result = true;
+ scene_manager_set_scene_state(
+ infrared->scene_manager, InfraredSceneRpc, InfraredRpcStateLoaded);
+ }
+ rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventButtonRelease, result);
} else if(event.event == InfraredCustomEventTypeRpcExit) {
+ scene_manager_stop(infrared->scene_manager);
view_dispatcher_stop(infrared->view_dispatcher);
rpc_system_app_confirm(infrared->rpc_ctx, RpcAppEventAppExit, true);
} else if(event.event == InfraredCustomEventTypeRpcSessionClose) {
- rpc_system_app_set_callback(infrared->rpc_ctx, NULL, NULL);
- infrared->rpc_ctx = NULL;
+ scene_manager_stop(infrared->scene_manager);
view_dispatcher_stop(infrared->view_dispatcher);
}
}
@@ -72,6 +92,9 @@ bool infrared_scene_rpc_on_event(void* context, SceneManagerEvent event) {
void infrared_scene_rpc_on_exit(void* context) {
Infrared* infrared = context;
- infrared_tx_stop(infrared);
+ if(scene_manager_get_scene_state(infrared->scene_manager, InfraredSceneRpc) ==
+ InfraredRpcStateSending) {
+ infrared_tx_stop(infrared);
+ }
popup_reset(infrared->popup);
}
diff --git a/applications/infrared/scenes/infrared_scene_universal_audio.c b/applications/infrared/scenes/infrared_scene_universal_audio.c
index 3003794f9..d3b7e083b 100644
--- a/applications/infrared/scenes/infrared_scene_universal_audio.c
+++ b/applications/infrared/scenes/infrared_scene_universal_audio.c
@@ -11,7 +11,7 @@ void infrared_scene_universal_audio_on_enter(void* context) {
infrared_brute_force_set_db_filename(brute_force, EXT_PATH("infrared/assets/audio.ir"));
//TODO Improve Audio universal remote
- button_panel_reserve(button_panel, 2, 1);
+ button_panel_reserve(button_panel, 2, 2);
uint32_t i = 0;
button_panel_add_item(
button_panel,
@@ -37,8 +37,33 @@ void infrared_scene_universal_audio_on_enter(void* context) {
infrared_scene_universal_common_item_callback,
context);
infrared_brute_force_add_record(brute_force, i++, "MUTE");
+ button_panel_add_item(
+ button_panel,
+ i,
+ 0,
+ 1,
+ 3,
+ 64,
+ &I_Vol_up_25x27,
+ &I_Vol_up_hvr_25x27,
+ infrared_scene_universal_common_item_callback,
+ context);
+ infrared_brute_force_add_record(brute_force, i++, "VOL+");
+ button_panel_add_item(
+ button_panel,
+ i,
+ 1,
+ 1,
+ 36,
+ 64,
+ &I_Vol_down_25x27,
+ &I_Vol_down_hvr_25x27,
+ infrared_scene_universal_common_item_callback,
+ context);
+ infrared_brute_force_add_record(brute_force, i++, "VOL-");
- button_panel_add_label(button_panel, 4, 11, FontSecondary, "Audio remote");
+ button_panel_add_label(button_panel, 5, 11, FontSecondary, "Audio remote");
+ button_panel_add_label(button_panel, 17, 60, FontSecondary, "Volume");
view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical);
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack);
diff --git a/applications/lfrfid/lfrfid_app.cpp b/applications/lfrfid/lfrfid_app.cpp
index 5b762ae1d..f1a575de5 100644
--- a/applications/lfrfid/lfrfid_app.cpp
+++ b/applications/lfrfid/lfrfid_app.cpp
@@ -56,6 +56,9 @@ static void rpc_command_callback(RpcAppSystemEvent rpc_event, void* context) {
LfRfidApp::Event event;
event.type = LfRfidApp::EventType::RpcSessionClose;
app->view_controller.send_event(&event);
+ // Detach RPC
+ rpc_system_app_set_callback(app->rpc_ctx, NULL, NULL);
+ app->rpc_ctx = NULL;
} else if(rpc_event == RpcAppEventAppExit) {
LfRfidApp::Event event;
event.type = LfRfidApp::EventType::Exit;
@@ -80,16 +83,19 @@ void LfRfidApp::run(void* _args) {
rpc_ctx = (RpcAppSystem*)rpc_ctx_ptr;
rpc_system_app_set_callback(rpc_ctx, rpc_command_callback, this);
rpc_system_app_send_started(rpc_ctx);
+ view_controller.attach_to_gui(ViewDispatcherTypeDesktop);
scene_controller.add_scene(SceneType::Rpc, new LfRfidAppSceneRpc());
scene_controller.process(100, SceneType::Rpc);
} else {
string_set_str(file_path, args);
load_key_data(file_path, &worker.key, true);
+ view_controller.attach_to_gui(ViewDispatcherTypeFullscreen);
scene_controller.add_scene(SceneType::Emulate, new LfRfidAppSceneEmulate());
scene_controller.process(100, SceneType::Emulate);
}
} else {
+ view_controller.attach_to_gui(ViewDispatcherTypeFullscreen);
scene_controller.add_scene(SceneType::Start, new LfRfidAppSceneStart());
scene_controller.add_scene(SceneType::Read, new LfRfidAppSceneRead());
scene_controller.add_scene(SceneType::RetryConfirm, new LfRfidAppSceneRetryConfirm());
diff --git a/applications/lfrfid/lfrfid_app.h b/applications/lfrfid/lfrfid_app.h
index b0d4c5898..db022c9aa 100644
--- a/applications/lfrfid/lfrfid_app.h
+++ b/applications/lfrfid/lfrfid_app.h
@@ -101,5 +101,4 @@ public:
bool save_key_data(string_t path, RfidKey* key);
void make_app_folder();
- //bool rpc_command_callback(RpcAppSystemEvent event, const char* arg, void* context);
};
diff --git a/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp b/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp
index 43b236286..54a57c9a2 100644
--- a/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp
+++ b/applications/lfrfid/scene/lfrfid_app_scene_rpc.cpp
@@ -6,9 +6,9 @@
void LfRfidAppSceneRpc::on_enter(LfRfidApp* app, bool /* need_restore */) {
auto popup = app->view_controller.get();
- popup->set_header("LF RFID", 89, 30, AlignCenter, AlignTop);
- popup->set_text("RPC mode", 89, 43, AlignCenter, AlignTop);
- popup->set_icon(0, 3, &I_RFIDDolphinSend_97x61);
+ popup->set_header("LF RFID", 89, 42, AlignCenter, AlignBottom);
+ popup->set_text("RPC mode", 89, 44, AlignCenter, AlignTop);
+ popup->set_icon(0, 12, &I_RFIDDolphinSend_97x61);
app->view_controller.switch_to();
@@ -27,33 +27,25 @@ bool LfRfidAppSceneRpc::on_event(LfRfidApp* app, LfRfidApp::Event* event) {
app->view_controller.send_event(&view_event);
rpc_system_app_confirm(app->rpc_ctx, RpcAppEventAppExit, true);
} else if(event->type == LfRfidApp::EventType::RpcSessionClose) {
- // Detach RPC
- rpc_system_app_set_callback(app->rpc_ctx, NULL, NULL);
- app->rpc_ctx = NULL;
-
consumed = true;
LfRfidApp::Event view_event;
view_event.type = LfRfidApp::EventType::Back;
app->view_controller.send_event(&view_event);
- } else if(event->type == LfRfidApp::EventType::EmulateStart) {
- auto popup = app->view_controller.get();
- consumed = true;
- emulating = true;
-
- app->text_store.set("emulating\n%s", app->worker.key.get_name());
- popup->set_text(app->text_store.text, 89, 43, AlignCenter, AlignTop);
-
- notification_message(app->notification, &sequence_blink_start_magenta);
} else if(event->type == LfRfidApp::EventType::RpcLoadFile) {
const char* arg = rpc_system_app_get_data(app->rpc_ctx);
+ consumed = true;
bool result = false;
- if(arg) {
+ if(arg && !emulating) {
string_set_str(app->file_path, arg);
if(app->load_key_data(app->file_path, &(app->worker.key), false)) {
- LfRfidApp::Event event;
- event.type = LfRfidApp::EventType::EmulateStart;
- app->view_controller.send_event(&event);
app->worker.start_emulate();
+ emulating = true;
+
+ auto popup = app->view_controller.get();
+ app->text_store.set("emulating\n%s", app->worker.key.get_name());
+ popup->set_text(app->text_store.text, 89, 44, AlignCenter, AlignTop);
+
+ notification_message(app->notification, &sequence_blink_start_magenta);
result = true;
}
}
diff --git a/applications/lfrfid/scene/lfrfid_app_scene_write.cpp b/applications/lfrfid/scene/lfrfid_app_scene_write.cpp
index ff7b49a4d..274ba3158 100644
--- a/applications/lfrfid/scene/lfrfid_app_scene_write.cpp
+++ b/applications/lfrfid/scene/lfrfid_app_scene_write.cpp
@@ -41,7 +41,7 @@ bool LfRfidAppSceneWrite::on_event(LfRfidApp* app, LfRfidApp::Event* event) {
case RfidWorker::WriteResult::NotWritable:
if(!card_not_supported) {
auto popup = app->view_controller.get();
- popup->set_icon(72, 14, &I_DolphinFirstStart8_56x51);
+ popup->set_icon(72, 17, &I_DolphinCommon_56x48);
popup->set_header("Still trying to write...", 64, 3, AlignCenter, AlignTop);
popup->set_text(
"Make sure this\ncard is writable\nand not\nprotected.",
diff --git a/applications/lfrfid_debug/lfrfid_debug_app.cpp b/applications/lfrfid_debug/lfrfid_debug_app.cpp
index 9cd9dcad8..ef970e361 100644
--- a/applications/lfrfid_debug/lfrfid_debug_app.cpp
+++ b/applications/lfrfid_debug/lfrfid_debug_app.cpp
@@ -10,6 +10,7 @@ LfRfidDebugApp::~LfRfidDebugApp() {
}
void LfRfidDebugApp::run() {
+ view_controller.attach_to_gui(ViewDispatcherTypeFullscreen);
scene_controller.add_scene(SceneType::Start, new LfRfidDebugAppSceneStart());
scene_controller.add_scene(SceneType::TuneScene, new LfRfidDebugAppSceneTune());
scene_controller.process(100);
diff --git a/applications/loader/application.fam b/applications/loader/application.fam
index 16351f8d1..c1ba4e549 100644
--- a/applications/loader/application.fam
+++ b/applications/loader/application.fam
@@ -5,6 +5,6 @@ App(
entry_point="loader_srv",
cdefines=["SRV_LOADER"],
requires=["gui"],
- stack_size=1 * 1024,
+ stack_size=2 * 1024,
order=90,
)
diff --git a/applications/loader/loader.c b/applications/loader/loader.c
index 7135a53cc..564a58a5d 100644
--- a/applications/loader/loader.c
+++ b/applications/loader/loader.c
@@ -503,9 +503,9 @@ int32_t loader_srv(void* p) {
furi_record_create(RECORD_LOADER, loader_instance);
-#ifdef LOADER_AUTOSTART
- loader_start(loader_instance, LOADER_AUTOSTART, NULL);
-#endif
+ if(FLIPPER_AUTORUN_APP_NAME && strlen(FLIPPER_AUTORUN_APP_NAME)) {
+ loader_start(loader_instance, FLIPPER_AUTORUN_APP_NAME, NULL);
+ }
while(1) {
uint32_t flags =
diff --git a/applications/mousejacker/mousejacker.c b/applications/mousejacker/mousejacker.c
index 4e0094ab0..d651496f7 100644
--- a/applications/mousejacker/mousejacker.c
+++ b/applications/mousejacker/mousejacker.c
@@ -240,10 +240,10 @@ int32_t mousejacker_app(void* p) {
view_port_input_callback_set(view_port, input_callback, event_queue);
// Open GUI and register view_port
- Gui* gui = furi_record_open("gui");
+ Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
- Storage* storage = furi_record_open("storage");
+ Storage* storage = furi_record_open(RECORD_STORAGE);
storage_common_mkdir(storage, MOUSEJACKER_APP_PATH_FOLDER);
Stream* file_stream = file_stream_alloc(storage);
@@ -329,8 +329,8 @@ int32_t mousejacker_app(void* p) {
furi_hal_spi_release(nrf24_HANDLE);
view_port_enabled_set(view_port, false);
gui_remove_view_port(gui, view_port);
- furi_record_close("gui");
- furi_record_close("storage");
+ furi_record_close(RECORD_GUI);
+ furi_record_close(RECORD_STORAGE);
view_port_free(view_port);
furi_message_queue_free(event_queue);
diff --git a/applications/music_player/music_player.c b/applications/music_player/music_player.c
index 073b9d00f..121efa0f9 100644
--- a/applications/music_player/music_player.c
+++ b/applications/music_player/music_player.c
@@ -30,7 +30,7 @@ typedef struct {
typedef struct {
MusicPlayerModel* model;
- FuriMutex* model_mutex;
+ FuriMutex** model_mutex;
FuriMessageQueue* input_queue;
@@ -256,7 +256,7 @@ MusicPlayer* music_player_alloc() {
instance->model = malloc(sizeof(MusicPlayerModel));
memset(instance->model->duration_history, 0xff, MUSIC_PLAYER_SEMITONE_HISTORY_SIZE);
memset(instance->model->semitone_history, 0xff, MUSIC_PLAYER_SEMITONE_HISTORY_SIZE);
- instance->model->volume = 1;
+ instance->model->volume = 3;
instance->model_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
diff --git a/applications/music_player/music_player_worker.c b/applications/music_player/music_player_worker.c
index 439092ea3..ca4f1d8c9 100644
--- a/applications/music_player/music_player_worker.c
+++ b/applications/music_player/music_player_worker.c
@@ -79,7 +79,7 @@ static int32_t music_player_worker_thread_callback(void* context) {
furi_hal_speaker_stop();
furi_hal_speaker_start(frequency, volume);
while(instance->should_work && furi_get_tick() < next_tick) {
- volume *= 1.0000000;
+ volume *= 0.9945679;
furi_hal_speaker_set_volume(volume);
furi_delay_ms(2);
}
diff --git a/applications/nfc/nfc.c b/applications/nfc/nfc.c
index 9d32e8713..3422e91af 100644
--- a/applications/nfc/nfc.c
+++ b/applications/nfc/nfc.c
@@ -21,6 +21,8 @@ static void nfc_rpc_command_callback(RpcAppSystemEvent event, void* context) {
if(event == RpcAppEventSessionClose) {
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventRpcSessionClose);
+ rpc_system_app_set_callback(nfc->rpc_ctx, NULL, NULL);
+ nfc->rpc_ctx = NULL;
} else if(event == RpcAppEventAppExit) {
view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit);
} else if(event == RpcAppEventLoadFile) {
@@ -87,11 +89,6 @@ Nfc* nfc_alloc() {
nfc->widget = widget_alloc();
view_dispatcher_add_view(nfc->view_dispatcher, NfcViewWidget, widget_get_view(nfc->widget));
- // Bank Card
- nfc->bank_card = bank_card_alloc();
- view_dispatcher_add_view(
- nfc->view_dispatcher, NfcViewBankCard, bank_card_get_view(nfc->bank_card));
-
// Mifare Classic Dict Attack
nfc->dict_attack = dict_attack_alloc();
view_dispatcher_add_view(
@@ -157,10 +154,6 @@ void nfc_free(Nfc* nfc) {
view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewWidget);
widget_free(nfc->widget);
- // Bank Card
- view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewBankCard);
- bank_card_free(nfc->bank_card);
-
// Mifare Classic Dict Attack
view_dispatcher_remove_view(nfc->view_dispatcher, NfcViewDictAttack);
dict_attack_free(nfc->dict_attack);
diff --git a/applications/nfc/nfc_i.h b/applications/nfc/nfc_i.h
index 5a916e803..bcfe4a219 100644
--- a/applications/nfc/nfc_i.h
+++ b/applications/nfc/nfc_i.h
@@ -25,8 +25,8 @@
#include
#include
#include
+#include
-#include "views/bank_card.h"
#include "views/dict_attack.h"
#include
@@ -70,7 +70,6 @@ struct Nfc {
ByteInput* byte_input;
TextBox* text_box;
Widget* widget;
- BankCard* bank_card;
DictAttack* dict_attack;
const NfcGenerator* generator;
@@ -85,7 +84,6 @@ typedef enum {
NfcViewByteInput,
NfcViewTextBox,
NfcViewWidget,
- NfcViewBankCard,
NfcViewDictAttack,
} NfcView;
diff --git a/applications/nfc/scenes/nfc_scene_config.h b/applications/nfc/scenes/nfc_scene_config.h
index 2b5cb5cf1..ff34a11d8 100755
--- a/applications/nfc/scenes/nfc_scene_config.h
+++ b/applications/nfc/scenes/nfc_scene_config.h
@@ -12,7 +12,10 @@ ADD_SCENE(nfc, save_name, SaveName)
ADD_SCENE(nfc, save_success, SaveSuccess)
ADD_SCENE(nfc, file_select, FileSelect)
ADD_SCENE(nfc, emulate_uid, EmulateUid)
+ADD_SCENE(nfc, nfca_read_success, NfcaReadSuccess)
+ADD_SCENE(nfc, nfca_menu, NfcaMenu)
ADD_SCENE(nfc, mf_ultralight_read_success, MfUltralightReadSuccess)
+ADD_SCENE(nfc, mf_ultralight_data, MfUltralightData)
ADD_SCENE(nfc, mf_ultralight_menu, MfUltralightMenu)
ADD_SCENE(nfc, mf_ultralight_emulate, MfUltralightEmulate)
ADD_SCENE(nfc, mf_ultralight_read_auth, MfUltralightReadAuth)
@@ -25,13 +28,13 @@ ADD_SCENE(nfc, mf_desfire_menu, MfDesfireMenu)
ADD_SCENE(nfc, mf_desfire_data, MfDesfireData)
ADD_SCENE(nfc, mf_desfire_app, MfDesfireApp)
ADD_SCENE(nfc, mf_classic_read_success, MfClassicReadSuccess)
-ADD_SCENE(nfc, mf_classic_info, MfClassicInfo)
ADD_SCENE(nfc, mf_classic_menu, MfClassicMenu)
ADD_SCENE(nfc, mf_classic_emulate, MfClassicEmulate)
ADD_SCENE(nfc, mf_classic_keys, MfClassicKeys)
ADD_SCENE(nfc, mf_classic_keys_add, MfClassicKeysAdd)
ADD_SCENE(nfc, mf_classic_dict_attack, MfClassicDictAttack)
ADD_SCENE(nfc, emv_read_success, EmvReadSuccess)
+ADD_SCENE(nfc, emv_menu, EmvMenu)
ADD_SCENE(nfc, emulate_apdu_sequence, EmulateApduSequence)
ADD_SCENE(nfc, device_info, DeviceInfo)
ADD_SCENE(nfc, delete, Delete)
@@ -45,3 +48,4 @@ ADD_SCENE(nfc, rpc, Rpc)
ADD_SCENE(nfc, exit_confirm, ExitConfirm)
ADD_SCENE(nfc, retry_confirm, RetryConfirm)
ADD_SCENE(nfc, detect_reader, DetectReader)
+ADD_SCENE(nfc, nfc_data_info, NfcDataInfo)
diff --git a/applications/nfc/scenes/nfc_scene_delete.c b/applications/nfc/scenes/nfc_scene_delete.c
index 1946b9290..987927e19 100755
--- a/applications/nfc/scenes/nfc_scene_delete.c
+++ b/applications/nfc/scenes/nfc_scene_delete.c
@@ -9,58 +9,43 @@ void nfc_scene_delete_widget_callback(GuiButtonType result, InputType type, void
void nfc_scene_delete_on_enter(void* context) {
Nfc* nfc = context;
+ FuriHalNfcDevData* nfc_data = &nfc->dev->dev_data.nfc_data;
// Setup Custom Widget view
- char temp_str[64];
- snprintf(temp_str, sizeof(temp_str), "\e#Delete %s?\e#", nfc->dev->dev_name);
+ string_t temp_str;
+ string_init(temp_str);
+
+ string_printf(temp_str, "\e#Delete %s?\e#", nfc->dev->dev_name);
widget_add_text_box_element(
- nfc->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, temp_str, false);
+ nfc->widget, 0, 0, 128, 23, AlignCenter, AlignCenter, string_get_cstr(temp_str), false);
widget_add_button_element(
- nfc->widget, GuiButtonTypeLeft, "Back", nfc_scene_delete_widget_callback, nfc);
+ nfc->widget, GuiButtonTypeLeft, "Cancel", nfc_scene_delete_widget_callback, nfc);
widget_add_button_element(
nfc->widget, GuiButtonTypeRight, "Delete", nfc_scene_delete_widget_callback, nfc);
- FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data;
- if(data->uid_len == 4) {
- snprintf(
- temp_str,
- sizeof(temp_str),
- "UID: %02X %02X %02X %02X",
- data->uid[0],
- data->uid[1],
- data->uid[2],
- data->uid[3]);
- } else if(data->uid_len == 7) {
- snprintf(
- temp_str,
- sizeof(temp_str),
- "UID: %02X %02X %02X %02X %02X %02X %02X",
- data->uid[0],
- data->uid[1],
- data->uid[2],
- data->uid[3],
- data->uid[4],
- data->uid[5],
- data->uid[6]);
- }
- widget_add_string_element(nfc->widget, 64, 23, AlignCenter, AlignTop, FontSecondary, temp_str);
- const char* protocol_name = NULL;
+ string_set_str(temp_str, "UID:");
+ for(size_t i = 0; i < nfc_data->uid_len; i++) {
+ string_cat_printf(temp_str, " %02X", nfc_data->uid[i]);
+ }
+ widget_add_string_element(
+ nfc->widget, 64, 24, AlignCenter, AlignTop, FontSecondary, string_get_cstr(temp_str));
+
NfcProtocol protocol = nfc->dev->dev_data.protocol;
if(protocol == NfcDeviceProtocolEMV) {
- protocol_name = nfc_guess_protocol(protocol);
+ string_set_str(temp_str, "EMV bank card");
} else if(protocol == NfcDeviceProtocolMifareUl) {
- protocol_name = nfc_mf_ul_type(nfc->dev->dev_data.mf_ul_data.type, false);
+ string_set_str(temp_str, nfc_mf_ul_type(nfc->dev->dev_data.mf_ul_data.type, true));
+ } else if(protocol == NfcDeviceProtocolMifareClassic) {
+ string_set_str(temp_str, nfc_mf_classic_type(nfc->dev->dev_data.mf_classic_data.type));
+ } else if(protocol == NfcDeviceProtocolMifareDesfire) {
+ string_set_str(temp_str, "MIFARE DESFire");
+ } else {
+ string_set_str(temp_str, "Unknown ISO tag");
}
- if(protocol_name) {
- widget_add_string_element(
- nfc->widget, 10, 33, AlignLeft, AlignTop, FontSecondary, protocol_name);
- }
- // TODO change dinamically
- widget_add_string_element(nfc->widget, 118, 33, AlignRight, AlignTop, FontSecondary, "NFC-A");
- snprintf(temp_str, sizeof(temp_str), "SAK: %02X", data->sak);
- widget_add_string_element(nfc->widget, 10, 43, AlignLeft, AlignTop, FontSecondary, temp_str);
- snprintf(temp_str, sizeof(temp_str), "ATQA: %02X%02X", data->atqa[0], data->atqa[1]);
- widget_add_string_element(nfc->widget, 118, 43, AlignRight, AlignTop, FontSecondary, temp_str);
+ widget_add_string_element(
+ nfc->widget, 64, 34, AlignCenter, AlignTop, FontSecondary, string_get_cstr(temp_str));
+ widget_add_string_element(nfc->widget, 64, 44, AlignCenter, AlignTop, FontSecondary, "NFC-A");
+ string_clear(temp_str);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
}
@@ -71,7 +56,7 @@ bool nfc_scene_delete_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == GuiButtonTypeLeft) {
- return scene_manager_previous_scene(nfc->scene_manager);
+ consumed = scene_manager_previous_scene(nfc->scene_manager);
} else if(event.event == GuiButtonTypeRight) {
if(nfc_device_delete(nfc->dev, true)) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneDeleteSuccess);
diff --git a/applications/nfc/scenes/nfc_scene_delete_success.c b/applications/nfc/scenes/nfc_scene_delete_success.c
index 547aeab7e..713b99ebf 100755
--- a/applications/nfc/scenes/nfc_scene_delete_success.c
+++ b/applications/nfc/scenes/nfc_scene_delete_success.c
@@ -26,7 +26,7 @@ bool nfc_scene_delete_success_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == NfcCustomEventViewExit) {
consumed = scene_manager_search_and_switch_to_previous_scene(
- nfc->scene_manager, NfcSceneStart);
+ nfc->scene_manager, NfcSceneFileSelect);
}
}
return consumed;
diff --git a/applications/nfc/scenes/nfc_scene_device_info.c b/applications/nfc/scenes/nfc_scene_device_info.c
index b79c51046..8228c7ea3 100644
--- a/applications/nfc/scenes/nfc_scene_device_info.c
+++ b/applications/nfc/scenes/nfc_scene_device_info.c
@@ -1,11 +1,6 @@
#include "../nfc_i.h"
#include "../helpers/nfc_emv_parser.h"
-enum {
- NfcSceneDeviceInfoUid,
- NfcSceneDeviceInfoData,
-};
-
void nfc_scene_device_info_widget_callback(GuiButtonType result, InputType type, void* context) {
Nfc* nfc = context;
if(type == InputTypeShort) {
@@ -13,197 +8,65 @@ void nfc_scene_device_info_widget_callback(GuiButtonType result, InputType type,
}
}
-void nfc_scene_device_info_dialog_callback(DialogExResult result, void* context) {
- Nfc* nfc = context;
- if(result == DialogExResultLeft) {
- view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit);
- }
-}
-
-void nfc_scene_device_info_bank_card_callback(GuiButtonType result, InputType type, void* context) {
- UNUSED(result);
- Nfc* nfc = context;
- if(type == InputTypeShort) {
- view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventViewExit);
- }
-}
-
void nfc_scene_device_info_on_enter(void* context) {
Nfc* nfc = context;
+ NfcDeviceData* dev_data = &nfc->dev->dev_data;
- bool data_display_supported = (nfc->dev->format == NfcDeviceSaveFormatUid) ||
- (nfc->dev->format == NfcDeviceSaveFormatMifareUl) ||
- (nfc->dev->format == NfcDeviceSaveFormatMifareDesfire) ||
- (nfc->dev->format == NfcDeviceSaveFormatBankCard);
- // Setup Custom Widget view
- widget_add_text_box_element(
- nfc->widget, 0, 0, 128, 22, AlignCenter, AlignTop, nfc->dev->dev_name, false);
- widget_add_button_element(
- nfc->widget, GuiButtonTypeLeft, "Back", nfc_scene_device_info_widget_callback, nfc);
- if(data_display_supported) {
- widget_add_button_element(
- nfc->widget, GuiButtonTypeRight, "Data", nfc_scene_device_info_widget_callback, nfc);
- }
- char temp_str[32];
- FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data;
- if(data->uid_len == 4) {
- snprintf(
- temp_str,
- sizeof(temp_str),
- "UID: %02X %02X %02X %02X",
- data->uid[0],
- data->uid[1],
- data->uid[2],
- data->uid[3]);
- } else if(data->uid_len == 7) {
- snprintf(
- temp_str,
- sizeof(temp_str),
- "UID: %02X %02X %02X %02X %02X %02X %02X",
- data->uid[0],
- data->uid[1],
- data->uid[2],
- data->uid[3],
- data->uid[4],
- data->uid[5],
- data->uid[6]);
- }
- widget_add_string_element(nfc->widget, 64, 21, AlignCenter, AlignTop, FontSecondary, temp_str);
+ string_t temp_str;
+ string_init(temp_str);
- const char* protocol_name = NULL;
- NfcProtocol protocol = nfc->dev->dev_data.protocol;
- if(protocol == NfcDeviceProtocolEMV || protocol == NfcDeviceProtocolMifareDesfire) {
- protocol_name = nfc_guess_protocol(protocol);
- } else if(protocol == NfcDeviceProtocolMifareUl) {
- protocol_name = nfc_mf_ul_type(nfc->dev->dev_data.mf_ul_data.type, false);
- } else if(protocol == NfcDeviceProtocolMifareClassic) {
- protocol_name = nfc_mf_classic_type(nfc->dev->dev_data.mf_classic_data.type);
- }
- if(protocol_name) {
- widget_add_string_element(
- nfc->widget, 10, 32, AlignLeft, AlignTop, FontSecondary, protocol_name);
- }
- // TODO change dinamically
- widget_add_string_element(nfc->widget, 118, 32, AlignRight, AlignTop, FontSecondary, "NFC-A");
- snprintf(temp_str, sizeof(temp_str), "SAK: %02X", data->sak);
- widget_add_string_element(nfc->widget, 10, 42, AlignLeft, AlignTop, FontSecondary, temp_str);
- snprintf(temp_str, sizeof(temp_str), "ATQA: %02X%02X", data->atqa[0], data->atqa[1]);
- widget_add_string_element(nfc->widget, 118, 42, AlignRight, AlignTop, FontSecondary, temp_str);
-
- // Setup Data View
- if(nfc->dev->format == NfcDeviceSaveFormatUid) {
- DialogEx* dialog_ex = nfc->dialog_ex;
- dialog_ex_set_left_button_text(dialog_ex, "Back");
- dialog_ex_set_text(dialog_ex, "No data", 64, 32, AlignCenter, AlignCenter);
- dialog_ex_set_context(dialog_ex, nfc);
- dialog_ex_set_result_callback(dialog_ex, nfc_scene_device_info_dialog_callback);
- } else if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) {
- MfUltralightData* mf_ul_data = &nfc->dev->dev_data.mf_ul_data;
- TextBox* text_box = nfc->text_box;
- text_box_set_font(text_box, TextBoxFontHex);
- for(uint16_t i = 0; i < mf_ul_data->data_size; i += 2) {
- if(!(i % 8) && i) {
- string_push_back(nfc->text_box_store, '\n');
- }
- string_cat_printf(
- nfc->text_box_store, "%02X%02X ", mf_ul_data->data[i], mf_ul_data->data[i + 1]);
+ if(dev_data->protocol == NfcDeviceProtocolEMV) {
+ EmvData* emv_data = &dev_data->emv_data;
+ string_printf(temp_str, "\e#%s\n", emv_data->name);
+ for(uint8_t i = 0; i < emv_data->number_len; i += 2) {
+ string_cat_printf(temp_str, "%02X%02X ", emv_data->number[i], emv_data->number[i + 1]);
}
- text_box_set_text(text_box, string_get_cstr(nfc->text_box_store));
- } else if(nfc->dev->format == NfcDeviceSaveFormatMifareDesfire) {
- MifareDesfireData* mf_df_data = &nfc->dev->dev_data.mf_df_data;
- uint16_t n_apps = 0;
- uint16_t n_files = 0;
- for(MifareDesfireApplication* app = mf_df_data->app_head; app; app = app->next) {
- n_apps++;
- for(MifareDesfireFile* file = app->file_head; file; file = file->next) {
- n_files++;
- }
- }
- nfc_text_store_set(
- nfc,
- "%d application%s, %d file%s",
- n_apps,
- n_apps == 1 ? "" : "s",
- n_files,
- n_files == 1 ? "" : "s");
- widget_add_string_element(
- nfc->widget, 64, 17, AlignCenter, AlignBottom, FontSecondary, nfc->text_store);
- } else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) {
- EmvData* emv_data = &nfc->dev->dev_data.emv_data;
- BankCard* bank_card = nfc->bank_card;
- bank_card_set_name(bank_card, emv_data->name);
- bank_card_set_number(bank_card, emv_data->number, emv_data->number_len);
- bank_card_set_back_callback(bank_card, nfc_scene_device_info_bank_card_callback, nfc);
+ string_strim(temp_str);
+
+ // Add expiration date
if(emv_data->exp_mon) {
- bank_card_set_exp_date(bank_card, emv_data->exp_mon, emv_data->exp_year);
+ string_cat_printf(temp_str, "\nExp: %02X/%02X", emv_data->exp_mon, emv_data->exp_year);
}
- string_t display_str;
- string_init(display_str);
- if(emv_data->country_code) {
+ // Parse currency code
+ if((emv_data->currency_code)) {
+ string_t currency_name;
+ string_init(currency_name);
+ if(nfc_emv_parser_get_currency_name(
+ nfc->dev->storage, emv_data->currency_code, currency_name)) {
+ string_cat_printf(temp_str, "\nCur: %s ", string_get_cstr(currency_name));
+ }
+ string_clear(currency_name);
+ }
+ // Parse country code
+ if((emv_data->country_code)) {
string_t country_name;
string_init(country_name);
if(nfc_emv_parser_get_country_name(
nfc->dev->storage, emv_data->country_code, country_name)) {
- string_printf(display_str, "Reg:%s", string_get_cstr(country_name));
- bank_card_set_country_name(bank_card, string_get_cstr(display_str));
+ string_cat_printf(temp_str, "Reg: %s", string_get_cstr(country_name));
}
string_clear(country_name);
}
- if(emv_data->currency_code) {
- string_t currency_name;
- string_init(currency_name);
- if(nfc_emv_parser_get_currency_name(
- nfc->dev->storage, emv_data->country_code, currency_name)) {
- string_printf(display_str, "Cur:%s", string_get_cstr(currency_name));
- bank_card_set_currency_name(bank_card, string_get_cstr(display_str));
- }
- string_clear(currency_name);
- }
- string_clear(display_str);
+ } else if(dev_data->protocol == NfcDeviceProtocolMifareClassic) {
+ string_set(temp_str, nfc->dev->dev_data.parsed_data);
}
- scene_manager_set_scene_state(nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoUid);
+
+ widget_add_text_scroll_element(nfc->widget, 0, 0, 128, 52, string_get_cstr(temp_str));
+ string_clear(temp_str);
+
+ widget_add_button_element(
+ nfc->widget, GuiButtonTypeRight, "More", nfc_scene_device_info_widget_callback, nfc);
+
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
}
bool nfc_scene_device_info_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = context;
bool consumed = false;
- uint32_t state = scene_manager_get_scene_state(nfc->scene_manager, NfcSceneDeviceInfo);
if(event.type == SceneManagerEventTypeCustom) {
- if((state == NfcSceneDeviceInfoUid) && (event.event == GuiButtonTypeLeft)) {
- consumed = scene_manager_previous_scene(nfc->scene_manager);
- } else if((state == NfcSceneDeviceInfoUid) && (event.event == GuiButtonTypeRight)) {
- if(nfc->dev->format == NfcDeviceSaveFormatUid) {
- scene_manager_set_scene_state(
- nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoData);
- view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx);
- consumed = true;
- } else if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) {
- scene_manager_set_scene_state(
- nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoData);
- view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox);
- consumed = true;
- } else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) {
- scene_manager_set_scene_state(
- nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoData);
- view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewBankCard);
- consumed = true;
- } else if(nfc->dev->format == NfcDeviceSaveFormatMifareDesfire) {
- scene_manager_next_scene(nfc->scene_manager, NfcSceneMfDesfireData);
- consumed = true;
- }
- } else if(state == NfcSceneDeviceInfoData && event.event == NfcCustomEventViewExit) {
- scene_manager_set_scene_state(
- nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoUid);
- view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
- consumed = true;
- }
- } else if(event.type == SceneManagerEventTypeBack) {
- if(state == NfcSceneDeviceInfoData) {
- scene_manager_set_scene_state(
- nfc->scene_manager, NfcSceneDeviceInfo, NfcSceneDeviceInfoUid);
- view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
+ if(event.event == GuiButtonTypeRight) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcDataInfo);
consumed = true;
}
}
@@ -215,12 +78,4 @@ void nfc_scene_device_info_on_exit(void* context) {
// Clear views
widget_reset(nfc->widget);
- if(nfc->dev->format == NfcDeviceSaveFormatUid) {
- dialog_ex_reset(nfc->dialog_ex);
- } else if(nfc->dev->format == NfcDeviceSaveFormatMifareUl) {
- text_box_reset(nfc->text_box);
- string_reset(nfc->text_box_store);
- } else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) {
- bank_card_clear(nfc->bank_card);
- }
}
diff --git a/applications/nfc/scenes/nfc_scene_emv_menu.c b/applications/nfc/scenes/nfc_scene_emv_menu.c
new file mode 100644
index 000000000..1da630fcf
--- /dev/null
+++ b/applications/nfc/scenes/nfc_scene_emv_menu.c
@@ -0,0 +1,54 @@
+#include "../nfc_i.h"
+
+enum SubmenuIndex {
+ SubmenuIndexSave,
+ SubmenuIndexInfo,
+};
+
+void nfc_scene_emv_menu_submenu_callback(void* context, uint32_t index) {
+ Nfc* nfc = context;
+
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, index);
+}
+
+void nfc_scene_emv_menu_on_enter(void* context) {
+ Nfc* nfc = context;
+ Submenu* submenu = nfc->submenu;
+
+ submenu_add_item(submenu, "Save", SubmenuIndexSave, nfc_scene_emv_menu_submenu_callback, nfc);
+ submenu_add_item(submenu, "Info", SubmenuIndexInfo, nfc_scene_emv_menu_submenu_callback, nfc);
+ submenu_set_selected_item(
+ nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneEmvMenu));
+
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu);
+}
+
+bool nfc_scene_emv_menu_on_event(void* context, SceneManagerEvent event) {
+ Nfc* nfc = context;
+ bool consumed = false;
+
+ if(event.type == SceneManagerEventTypeCustom) {
+ if(event.event == SubmenuIndexSave) {
+ nfc->dev->format = NfcDeviceSaveFormatBankCard;
+ // Clear device name
+ nfc_device_set_name(nfc->dev, "");
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
+ consumed = true;
+ } else if(event.event == SubmenuIndexInfo) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcDataInfo);
+ consumed = true;
+ }
+ scene_manager_set_scene_state(nfc->scene_manager, NfcSceneEmvMenu, event.event);
+ } else if(event.type == SceneManagerEventTypeBack) {
+ consumed = scene_manager_previous_scene(nfc->scene_manager);
+ }
+
+ return consumed;
+}
+
+void nfc_scene_emv_menu_on_exit(void* context) {
+ Nfc* nfc = context;
+
+ // Clear view
+ submenu_reset(nfc->submenu);
+}
diff --git a/applications/nfc/scenes/nfc_scene_emv_read_success.c b/applications/nfc/scenes/nfc_scene_emv_read_success.c
index eefe560e3..9cf7ff9e9 100644
--- a/applications/nfc/scenes/nfc_scene_emv_read_success.c
+++ b/applications/nfc/scenes/nfc_scene_emv_read_success.c
@@ -15,85 +15,48 @@ void nfc_scene_emv_read_success_widget_callback(
void nfc_scene_emv_read_success_on_enter(void* context) {
Nfc* nfc = context;
EmvData* emv_data = &nfc->dev->dev_data.emv_data;
- FuriHalNfcDevData* nfc_data = &nfc->dev->dev_data.nfc_data;
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
// Setup Custom Widget view
- // Add frame
- widget_add_frame_element(nfc->widget, 0, 0, 128, 64, 6);
- // Add buttons
widget_add_button_element(
nfc->widget, GuiButtonTypeLeft, "Retry", nfc_scene_emv_read_success_widget_callback, nfc);
widget_add_button_element(
- nfc->widget, GuiButtonTypeRight, "Save", nfc_scene_emv_read_success_widget_callback, nfc);
- // Add card name
- widget_add_string_element(
- nfc->widget, 64, 3, AlignCenter, AlignTop, FontSecondary, nfc->dev->dev_data.emv_data.name);
- // Add card number
- string_t pan_str;
- string_init(pan_str);
+ nfc->widget, GuiButtonTypeRight, "More", nfc_scene_emv_read_success_widget_callback, nfc);
+
+ string_t temp_str;
+ string_init_printf(temp_str, "\e#%s\n", emv_data->name);
for(uint8_t i = 0; i < emv_data->number_len; i += 2) {
- string_cat_printf(pan_str, "%02X%02X ", emv_data->number[i], emv_data->number[i + 1]);
+ string_cat_printf(temp_str, "%02X%02X ", emv_data->number[i], emv_data->number[i + 1]);
}
- string_strim(pan_str);
- widget_add_string_element(
- nfc->widget, 64, 13, AlignCenter, AlignTop, FontSecondary, string_get_cstr(pan_str));
- string_clear(pan_str);
- // Parse country code
- string_t country_name;
- string_init(country_name);
- if((emv_data->country_code) &&
- nfc_emv_parser_get_country_name(nfc->dev->storage, emv_data->country_code, country_name)) {
- string_t disp_country;
- string_init_printf(disp_country, "Reg:%s", country_name);
- widget_add_string_element(
- nfc->widget, 7, 23, AlignLeft, AlignTop, FontSecondary, string_get_cstr(disp_country));
- string_clear(disp_country);
- }
- string_clear(country_name);
- // Parse currency code
- string_t currency_name;
- string_init(currency_name);
- if((emv_data->currency_code) &&
- nfc_emv_parser_get_currency_name(
- nfc->dev->storage, emv_data->currency_code, currency_name)) {
- string_t disp_currency;
- string_init_printf(disp_currency, "Cur:%s", currency_name);
- widget_add_string_element(
- nfc->widget,
- 121,
- 23,
- AlignRight,
- AlignTop,
- FontSecondary,
- string_get_cstr(disp_currency));
- string_clear(disp_currency);
- }
- string_clear(currency_name);
- char temp_str[32];
- // Add ATQA
- snprintf(temp_str, sizeof(temp_str), "ATQA: %02X%02X", nfc_data->atqa[0], nfc_data->atqa[1]);
- widget_add_string_element(nfc->widget, 121, 32, AlignRight, AlignTop, FontSecondary, temp_str);
- // Add UID
- snprintf(
- temp_str,
- sizeof(temp_str),
- "UID: %02X %02X %02X %02X",
- nfc_data->uid[0],
- nfc_data->uid[1],
- nfc_data->uid[2],
- nfc_data->uid[3]);
- widget_add_string_element(nfc->widget, 7, 42, AlignLeft, AlignTop, FontSecondary, temp_str);
- // Add SAK
- snprintf(temp_str, sizeof(temp_str), "SAK: %02X", nfc_data->sak);
- widget_add_string_element(nfc->widget, 121, 42, AlignRight, AlignTop, FontSecondary, temp_str);
+ string_strim(temp_str);
+
// Add expiration date
if(emv_data->exp_mon) {
- char exp_str[16];
- snprintf(
- exp_str, sizeof(exp_str), "Exp: %02X/%02X", emv_data->exp_mon, emv_data->exp_year);
- widget_add_string_element(nfc->widget, 7, 32, AlignLeft, AlignTop, FontSecondary, exp_str);
+ string_cat_printf(temp_str, "\nExp: %02X/%02X", emv_data->exp_mon, emv_data->exp_year);
}
+ // Parse currency code
+ if((emv_data->currency_code)) {
+ string_t currency_name;
+ string_init(currency_name);
+ if(nfc_emv_parser_get_currency_name(
+ nfc->dev->storage, emv_data->currency_code, currency_name)) {
+ string_cat_printf(temp_str, "\nCur: %s ", string_get_cstr(currency_name));
+ }
+ string_clear(currency_name);
+ }
+ // Parse country code
+ if((emv_data->country_code)) {
+ string_t country_name;
+ string_init(country_name);
+ if(nfc_emv_parser_get_country_name(
+ nfc->dev->storage, emv_data->country_code, country_name)) {
+ string_cat_printf(temp_str, "Reg: %s", string_get_cstr(country_name));
+ }
+ string_clear(country_name);
+ }
+
+ widget_add_text_scroll_element(nfc->widget, 0, 0, 128, 52, string_get_cstr(temp_str));
+ string_clear(temp_str);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
}
@@ -107,10 +70,7 @@ bool nfc_scene_emv_read_success_on_event(void* context, SceneManagerEvent event)
scene_manager_next_scene(nfc->scene_manager, NfcSceneRetryConfirm);
consumed = true;
} else if(event.event == GuiButtonTypeRight) {
- // Clear device name
- nfc_device_set_name(nfc->dev, "");
- nfc->dev->format = NfcDeviceSaveFormatBankCard;
- scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneEmvMenu);
consumed = true;
}
} else if(event.type == SceneManagerEventTypeBack) {
diff --git a/applications/nfc/scenes/nfc_scene_file_select.c b/applications/nfc/scenes/nfc_scene_file_select.c
index 0278c3b9c..693fdec20 100755
--- a/applications/nfc/scenes/nfc_scene_file_select.c
+++ b/applications/nfc/scenes/nfc_scene_file_select.c
@@ -6,6 +6,7 @@ void nfc_scene_file_select_on_enter(void* context) {
// Process file_select return
nfc_device_set_loading_callback(nfc->dev, nfc_show_loading_popup, nfc);
if(nfc_file_select(nfc->dev)) {
+ scene_manager_set_scene_state(nfc->scene_manager, NfcSceneSavedMenu, 0);
scene_manager_next_scene(nfc->scene_manager, NfcSceneSavedMenu);
} else {
scene_manager_search_and_switch_to_previous_scene(nfc->scene_manager, NfcSceneStart);
diff --git a/applications/nfc/scenes/nfc_scene_mf_classic_info.c b/applications/nfc/scenes/nfc_scene_mf_classic_info.c
deleted file mode 100644
index b658dfa48..000000000
--- a/applications/nfc/scenes/nfc_scene_mf_classic_info.c
+++ /dev/null
@@ -1,72 +0,0 @@
-#include "../nfc_i.h"
-
-void nfc_scene_mf_classic_info_widget_callback(GuiButtonType result, InputType type, void* context) {
- furi_assert(context);
- Nfc* nfc = context;
-
- if(type == InputTypeShort) {
- view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
- }
-}
-
-void nfc_scene_mf_classic_info_on_enter(void* context) {
- Nfc* nfc = context;
- NfcDeviceData* dev_data = &nfc->dev->dev_data;
- MfClassicData* mf_data = &dev_data->mf_classic_data;
- string_t str_tmp;
- string_init(str_tmp);
-
- // Setup view
- Widget* widget = nfc->widget;
-
- widget_add_string_element(
- widget, 0, 0, AlignLeft, AlignTop, FontSecondary, mf_classic_get_type_str(mf_data->type));
- widget_add_string_element(
- widget, 0, 11, AlignLeft, AlignTop, FontSecondary, "ISO 14443-3 (Type A)");
- string_printf(str_tmp, "UID:");
- for(size_t i = 0; i < dev_data->nfc_data.uid_len; i++) {
- string_cat_printf(str_tmp, " %02X", dev_data->nfc_data.uid[i]);
- }
- widget_add_string_element(
- widget, 0, 22, AlignLeft, AlignTop, FontSecondary, string_get_cstr(str_tmp));
- string_printf(
- str_tmp,
- "ATQA: %02X %02X SAK: %02X",
- dev_data->nfc_data.atqa[0],
- dev_data->nfc_data.atqa[1],
- dev_data->nfc_data.sak);
- widget_add_string_element(
- widget, 0, 33, AlignLeft, AlignTop, FontSecondary, string_get_cstr(str_tmp));
- uint8_t sectors_total = mf_classic_get_total_sectors_num(mf_data->type);
- uint8_t keys_total = sectors_total * 2;
- uint8_t keys_found = 0;
- uint8_t sectors_read = 0;
- mf_classic_get_read_sectors_and_keys(mf_data, §ors_read, &keys_found);
- string_printf(str_tmp, "Keys Found: %d/%d", keys_found, keys_total);
- widget_add_string_element(
- widget, 0, 44, AlignLeft, AlignTop, FontSecondary, string_get_cstr(str_tmp));
- string_printf(str_tmp, "Sectors Read: %d/%d", sectors_read, sectors_total);
- widget_add_string_element(
- widget, 0, 55, AlignLeft, AlignTop, FontSecondary, string_get_cstr(str_tmp));
-
- string_clear(str_tmp);
- view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
-}
-
-bool nfc_scene_mf_classic_info_on_event(void* context, SceneManagerEvent event) {
- Nfc* nfc = context;
- bool consumed = false;
-
- if(event.type == SceneManagerEventTypeBack) {
- consumed = scene_manager_previous_scene(nfc->scene_manager);
- }
-
- return consumed;
-}
-
-void nfc_scene_mf_classic_info_on_exit(void* context) {
- Nfc* nfc = context;
-
- // Clear view
- widget_reset(nfc->widget);
-}
diff --git a/applications/nfc/scenes/nfc_scene_mf_classic_keys.c b/applications/nfc/scenes/nfc_scene_mf_classic_keys.c
index 0faa73673..fcb8bc189 100644
--- a/applications/nfc/scenes/nfc_scene_mf_classic_keys.c
+++ b/applications/nfc/scenes/nfc_scene_mf_classic_keys.c
@@ -34,6 +34,7 @@ void nfc_scene_mf_classic_keys_on_enter(void* context) {
widget_add_string_element(nfc->widget, 0, 32, AlignLeft, AlignTop, FontSecondary, temp_str);
widget_add_button_element(
nfc->widget, GuiButtonTypeCenter, "Add", nfc_scene_mf_classic_keys_widget_callback, nfc);
+ widget_add_icon_element(nfc->widget, 90, 12, &I_Keychain);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
}
diff --git a/applications/nfc/scenes/nfc_scene_mf_classic_menu.c b/applications/nfc/scenes/nfc_scene_mf_classic_menu.c
index 6ee0ad868..76d02e01e 100644
--- a/applications/nfc/scenes/nfc_scene_mf_classic_menu.c
+++ b/applications/nfc/scenes/nfc_scene_mf_classic_menu.c
@@ -50,7 +50,7 @@ bool nfc_scene_mf_classic_menu_on_event(void* context, SceneManagerEvent event)
} else if(event.event == SubmenuIndexInfo) {
scene_manager_set_scene_state(
nfc->scene_manager, NfcSceneMfClassicMenu, SubmenuIndexInfo);
- scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicInfo);
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcDataInfo);
consumed = true;
}
} else if(event.type == SceneManagerEventTypeBack) {
diff --git a/applications/nfc/scenes/nfc_scene_mf_classic_read_success.c b/applications/nfc/scenes/nfc_scene_mf_classic_read_success.c
index bd782305c..efe676706 100644
--- a/applications/nfc/scenes/nfc_scene_mf_classic_read_success.c
+++ b/applications/nfc/scenes/nfc_scene_mf_classic_read_success.c
@@ -17,8 +17,6 @@ void nfc_scene_mf_classic_read_success_on_enter(void* context) {
Nfc* nfc = context;
NfcDeviceData* dev_data = &nfc->dev->dev_data;
MfClassicData* mf_data = &dev_data->mf_classic_data;
- string_t str_tmp;
- string_init(str_tmp);
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
@@ -29,48 +27,27 @@ void nfc_scene_mf_classic_read_success_on_enter(void* context) {
widget_add_button_element(
widget, GuiButtonTypeRight, "More", nfc_scene_mf_classic_read_success_widget_callback, nfc);
+ string_t temp_str;
if(string_size(nfc->dev->dev_data.parsed_data)) {
- widget_add_text_box_element(
- nfc->widget,
- 0,
- 0,
- 128,
- 32,
- AlignLeft,
- AlignTop,
- string_get_cstr(nfc->dev->dev_data.parsed_data),
- true);
+ string_init_set(temp_str, nfc->dev->dev_data.parsed_data);
} else {
- widget_add_string_element(
- widget,
- 0,
- 0,
- AlignLeft,
- AlignTop,
- FontSecondary,
- mf_classic_get_type_str(mf_data->type));
- widget_add_string_element(
- widget, 0, 11, AlignLeft, AlignTop, FontSecondary, "ISO 14443-3 (Type A)");
- string_printf(str_tmp, "UID:");
+ string_init_printf(temp_str, "\e#%s\n", nfc_mf_classic_type(mf_data->type));
+ string_cat_printf(temp_str, "UID:");
for(size_t i = 0; i < dev_data->nfc_data.uid_len; i++) {
- string_cat_printf(str_tmp, " %02X", dev_data->nfc_data.uid[i]);
+ string_cat_printf(temp_str, " %02X", dev_data->nfc_data.uid[i]);
}
- widget_add_string_element(
- widget, 0, 22, AlignLeft, AlignTop, FontSecondary, string_get_cstr(str_tmp));
uint8_t sectors_total = mf_classic_get_total_sectors_num(mf_data->type);
uint8_t keys_total = sectors_total * 2;
uint8_t keys_found = 0;
uint8_t sectors_read = 0;
mf_classic_get_read_sectors_and_keys(mf_data, §ors_read, &keys_found);
- string_printf(str_tmp, "Keys Found: %d/%d", keys_found, keys_total);
- widget_add_string_element(
- widget, 0, 33, AlignLeft, AlignTop, FontSecondary, string_get_cstr(str_tmp));
- string_printf(str_tmp, "Sectors Read: %d/%d", sectors_read, sectors_total);
- widget_add_string_element(
- widget, 0, 44, AlignLeft, AlignTop, FontSecondary, string_get_cstr(str_tmp));
+ string_cat_printf(temp_str, "\nKeys Found: %d/%d", keys_found, keys_total);
+ string_cat_printf(temp_str, "\nSectors Read: %d/%d", sectors_read, sectors_total);
}
- string_clear(str_tmp);
+ widget_add_text_scroll_element(widget, 0, 0, 128, 52, string_get_cstr(temp_str));
+ string_clear(temp_str);
+
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
}
diff --git a/applications/nfc/scenes/nfc_scene_mf_desfire_menu.c b/applications/nfc/scenes/nfc_scene_mf_desfire_menu.c
index f15251143..1e2f2d2f2 100644
--- a/applications/nfc/scenes/nfc_scene_mf_desfire_menu.c
+++ b/applications/nfc/scenes/nfc_scene_mf_desfire_menu.c
@@ -2,6 +2,8 @@
enum SubmenuIndex {
SubmenuIndexSave,
+ SubmenuIndexEmulateUid,
+ SubmenuIndexInfo,
};
void nfc_scene_mf_desfire_menu_submenu_callback(void* context, uint32_t index) {
@@ -16,6 +18,15 @@ void nfc_scene_mf_desfire_menu_on_enter(void* context) {
submenu_add_item(
submenu, "Save", SubmenuIndexSave, nfc_scene_mf_desfire_menu_submenu_callback, nfc);
+ submenu_add_item(
+ submenu,
+ "Emulate UID",
+ SubmenuIndexEmulateUid,
+ nfc_scene_mf_desfire_menu_submenu_callback,
+ nfc);
+ submenu_add_item(
+ submenu, "Info", SubmenuIndexInfo, nfc_scene_mf_desfire_menu_submenu_callback, nfc);
+
submenu_set_selected_item(
nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfDesfireMenu));
@@ -35,6 +46,12 @@ bool nfc_scene_mf_desfire_menu_on_event(void* context, SceneManagerEvent event)
nfc_device_set_name(nfc->dev, "");
scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
consumed = true;
+ } else if(event.event == SubmenuIndexEmulateUid) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
+ consumed = true;
+ } else if(event.event == SubmenuIndexInfo) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcDataInfo);
+ consumed = true;
}
}
diff --git a/applications/nfc/scenes/nfc_scene_mf_desfire_read_success.c b/applications/nfc/scenes/nfc_scene_mf_desfire_read_success.c
index a04f4e55c..4827c2851 100644
--- a/applications/nfc/scenes/nfc_scene_mf_desfire_read_success.c
+++ b/applications/nfc/scenes/nfc_scene_mf_desfire_read_success.c
@@ -1,90 +1,85 @@
#include "../nfc_i.h"
#include
-#define NFC_SCENE_READ_SUCCESS_SHIFT " "
-
-enum {
- MfDesfireReadSuccessStateShowUID,
- MfDesfireReadSuccessStateShowData,
-};
-
-void nfc_scene_mf_desfire_read_success_dialog_callback(DialogExResult result, void* context) {
+void nfc_scene_mf_desfire_read_success_widget_callback(
+ GuiButtonType result,
+ InputType type,
+ void* context) {
Nfc* nfc = context;
- view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
+ if(type == InputTypeShort) {
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
+ }
}
void nfc_scene_mf_desfire_read_success_on_enter(void* context) {
Nfc* nfc = context;
+ FuriHalNfcDevData* nfc_data = &nfc->dev->dev_data.nfc_data;
MifareDesfireData* data = &nfc->dev->dev_data.mf_df_data;
- DialogEx* dialog_ex = nfc->dialog_ex;
- dialog_ex_set_left_button_text(dialog_ex, "Retry");
- dialog_ex_set_center_button_text(dialog_ex, "Data");
- dialog_ex_set_right_button_text(dialog_ex, "More");
- dialog_ex_set_icon(dialog_ex, 8, 16, &I_Medium_chip_22x21);
+ Widget* widget = nfc->widget;
+
+ // Prepare string for data display
+ string_t temp_str;
+ string_init_printf(temp_str, "\e#MIFARE DESfire\n");
+ string_cat_printf(temp_str, "UID:");
+ for(size_t i = 0; i < nfc_data->uid_len; i++) {
+ string_cat_printf(temp_str, " %02X", nfc_data->uid[i]);
+ }
+
+ uint32_t bytes_total = 1 << (data->version.sw_storage >> 1);
+ uint32_t bytes_free = data->free_memory ? data->free_memory->bytes : 0;
+ string_cat_printf(temp_str, "\n%d", bytes_total);
+ if(data->version.sw_storage & 1) {
+ string_push_back(temp_str, '+');
+ }
+ string_cat_printf(temp_str, " bytes, %d bytes free\n", bytes_free);
uint16_t n_apps = 0;
uint16_t n_files = 0;
-
for(MifareDesfireApplication* app = data->app_head; app; app = app->next) {
n_apps++;
for(MifareDesfireFile* file = app->file_head; file; file = file->next) {
n_files++;
}
}
+ string_cat_printf(temp_str, "%d Application", n_apps);
+ if(n_apps != 1) {
+ string_push_back(temp_str, 's');
+ }
+ string_cat_printf(temp_str, ", %d file", n_files);
+ if(n_files != 1) {
+ string_push_back(temp_str, 's');
+ }
- // TODO rework info view
- nfc_text_store_set(
- nfc,
- NFC_SCENE_READ_SUCCESS_SHIFT "Mifare DESFire\n" NFC_SCENE_READ_SUCCESS_SHIFT
- "%d%s bytes\n" NFC_SCENE_READ_SUCCESS_SHIFT "%d bytes free\n"
- "%d application%s, %d file%s",
- 1 << (data->version.sw_storage >> 1),
- (data->version.sw_storage & 1) ? "+" : "",
- data->free_memory ? data->free_memory->bytes : 0,
- n_apps,
- n_apps == 1 ? "" : "s",
- n_files,
- n_files == 1 ? "" : "s");
- dialog_ex_set_text(dialog_ex, nfc->text_store, 8, 6, AlignLeft, AlignTop);
- dialog_ex_set_context(dialog_ex, nfc);
- dialog_ex_set_result_callback(dialog_ex, nfc_scene_mf_desfire_read_success_dialog_callback);
+ // Add text scroll element
+ widget_add_text_scroll_element(widget, 0, 0, 128, 52, string_get_cstr(temp_str));
+ string_clear(temp_str);
- scene_manager_set_scene_state(
- nfc->scene_manager, NfcSceneMfDesfireReadSuccess, MfDesfireReadSuccessStateShowUID);
- view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx);
+ // Add button elements
+ widget_add_button_element(
+ widget, GuiButtonTypeLeft, "Retry", nfc_scene_mf_desfire_read_success_widget_callback, nfc);
+ widget_add_button_element(
+ widget, GuiButtonTypeRight, "More", nfc_scene_mf_desfire_read_success_widget_callback, nfc);
+
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
}
bool nfc_scene_mf_desfire_read_success_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = context;
bool consumed = false;
- uint32_t state =
- scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfDesfireReadSuccess);
if(event.type == SceneManagerEventTypeCustom) {
- if(state == MfDesfireReadSuccessStateShowUID && event.event == DialogExResultLeft) {
+ if(event.event == GuiButtonTypeLeft) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneRetryConfirm);
consumed = true;
- } else if(state == MfDesfireReadSuccessStateShowUID && event.event == DialogExResultCenter) {
- scene_manager_next_scene(nfc->scene_manager, NfcSceneMfDesfireData);
- consumed = true;
- } else if(state == MfDesfireReadSuccessStateShowUID && event.event == DialogExResultRight) {
+ } else if(event.event == GuiButtonTypeRight) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfDesfireMenu);
consumed = true;
}
} else if(event.type == SceneManagerEventTypeBack) {
- if(state == MfDesfireReadSuccessStateShowData) {
- view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx);
- scene_manager_set_scene_state(
- nfc->scene_manager,
- NfcSceneMfDesfireReadSuccess,
- MfDesfireReadSuccessStateShowUID);
- consumed = true;
- } else {
- scene_manager_next_scene(nfc->scene_manager, NfcSceneExitConfirm);
- consumed = true;
- }
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneExitConfirm);
+ consumed = true;
}
return consumed;
@@ -94,5 +89,5 @@ void nfc_scene_mf_desfire_read_success_on_exit(void* context) {
Nfc* nfc = context;
// Clean dialog
- dialog_ex_reset(nfc->dialog_ex);
+ widget_reset(nfc->widget);
}
diff --git a/applications/nfc/scenes/nfc_scene_mf_ultralight_data.c b/applications/nfc/scenes/nfc_scene_mf_ultralight_data.c
new file mode 100644
index 000000000..d4184a6b4
--- /dev/null
+++ b/applications/nfc/scenes/nfc_scene_mf_ultralight_data.c
@@ -0,0 +1,32 @@
+#include "../nfc_i.h"
+
+void nfc_scene_mf_ultralight_data_on_enter(void* context) {
+ Nfc* nfc = context;
+ MfUltralightData* data = &nfc->dev->dev_data.mf_ul_data;
+ TextBox* text_box = nfc->text_box;
+
+ text_box_set_font(text_box, TextBoxFontHex);
+ for(uint16_t i = 0; i < data->data_size; i += 2) {
+ if(!(i % 8) && i) {
+ string_push_back(nfc->text_box_store, '\n');
+ }
+ string_cat_printf(nfc->text_box_store, "%02X%02X ", data->data[i], data->data[i + 1]);
+ }
+ text_box_set_text(text_box, string_get_cstr(nfc->text_box_store));
+
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox);
+}
+
+bool nfc_scene_mf_ultralight_data_on_event(void* context, SceneManagerEvent event) {
+ UNUSED(context);
+ UNUSED(event);
+ return false;
+}
+
+void nfc_scene_mf_ultralight_data_on_exit(void* context) {
+ Nfc* nfc = context;
+
+ // Clean view
+ text_box_reset(nfc->text_box);
+ string_reset(nfc->text_box_store);
+}
\ No newline at end of file
diff --git a/applications/nfc/scenes/nfc_scene_mf_ultralight_menu.c b/applications/nfc/scenes/nfc_scene_mf_ultralight_menu.c
index 9174a8b19..ba9f22338 100644
--- a/applications/nfc/scenes/nfc_scene_mf_ultralight_menu.c
+++ b/applications/nfc/scenes/nfc_scene_mf_ultralight_menu.c
@@ -4,6 +4,7 @@ enum SubmenuIndex {
SubmenuIndexUnlock,
SubmenuIndexSave,
SubmenuIndexEmulate,
+ SubmenuIndexInfo,
};
void nfc_scene_mf_ultralight_menu_submenu_callback(void* context, uint32_t index) {
@@ -33,6 +34,9 @@ void nfc_scene_mf_ultralight_menu_on_enter(void* context) {
SubmenuIndexEmulate,
nfc_scene_mf_ultralight_menu_submenu_callback,
nfc);
+ submenu_add_item(
+ submenu, "Info", SubmenuIndexInfo, nfc_scene_mf_ultralight_menu_submenu_callback, nfc);
+
submenu_set_selected_item(
nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfUltralightMenu));
@@ -56,6 +60,9 @@ bool nfc_scene_mf_ultralight_menu_on_event(void* context, SceneManagerEvent even
} else if(event.event == SubmenuIndexUnlock) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightUnlockMenu);
consumed = true;
+ } else if(event.event == SubmenuIndexInfo) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcDataInfo);
+ consumed = true;
}
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMfUltralightMenu, event.event);
diff --git a/applications/nfc/scenes/nfc_scene_mf_ultralight_read_auth.c b/applications/nfc/scenes/nfc_scene_mf_ultralight_read_auth.c
index 968157bdb..853ccb055 100644
--- a/applications/nfc/scenes/nfc_scene_mf_ultralight_read_auth.c
+++ b/applications/nfc/scenes/nfc_scene_mf_ultralight_read_auth.c
@@ -43,7 +43,7 @@ void nfc_scene_mf_ultralight_read_auth_set_state(Nfc* nfc, NfcSceneMfUlReadState
22,
AlignLeft,
AlignTop);
- popup_set_icon(nfc->popup, 73, 17, &I_DolphinFirstStart8_56x51);
+ popup_set_icon(nfc->popup, 73, 20, &I_DolphinCommon_56x48);
}
scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMfUltralightReadAuth, state);
}
diff --git a/applications/nfc/scenes/nfc_scene_mf_ultralight_read_success.c b/applications/nfc/scenes/nfc_scene_mf_ultralight_read_success.c
index 65750b963..d775bb71d 100644
--- a/applications/nfc/scenes/nfc_scene_mf_ultralight_read_success.c
+++ b/applications/nfc/scenes/nfc_scene_mf_ultralight_read_success.c
@@ -1,11 +1,6 @@
#include "../nfc_i.h"
#include
-enum {
- ReadMifareUlStateShowInfo,
- ReadMifareUlStateShowData,
-};
-
void nfc_scene_mf_ultralight_read_success_widget_callback(
GuiButtonType result,
InputType type,
@@ -31,12 +26,6 @@ void nfc_scene_mf_ultralight_read_success_on_enter(void* context) {
"Retry",
nfc_scene_mf_ultralight_read_success_widget_callback,
nfc);
- widget_add_button_element(
- widget,
- GuiButtonTypeCenter,
- "Data",
- nfc_scene_mf_ultralight_read_success_widget_callback,
- nfc);
widget_add_button_element(
widget,
GuiButtonTypeRight,
@@ -44,71 +33,38 @@ void nfc_scene_mf_ultralight_read_success_on_enter(void* context) {
nfc_scene_mf_ultralight_read_success_widget_callback,
nfc);
- widget_add_string_element(
- widget, 0, 0, AlignLeft, AlignTop, FontSecondary, nfc_mf_ul_type(mf_ul_data->type, true));
- string_t data_str;
- string_init_printf(data_str, "UID:");
+ string_t temp_str;
+ string_init_printf(temp_str, "\e#%s\n", nfc_mf_ul_type(mf_ul_data->type, true));
+ string_cat_printf(temp_str, "UID:");
for(size_t i = 0; i < data->uid_len; i++) {
- string_cat_printf(data_str, " %02X", data->uid[i]);
+ string_cat_printf(temp_str, " %02X", data->uid[i]);
}
- widget_add_string_element(
- widget, 0, 13, AlignLeft, AlignTop, FontSecondary, string_get_cstr(data_str));
- string_printf(
- data_str, "Pages Read: %d/%d", mf_ul_data->data_read / 4, mf_ul_data->data_size / 4);
- widget_add_string_element(
- widget, 0, 24, AlignLeft, AlignTop, FontSecondary, string_get_cstr(data_str));
+ string_cat_printf(
+ temp_str, "\nPages Read: %d/%d", mf_ul_data->data_read / 4, mf_ul_data->data_size / 4);
if(mf_ul_data->data_read != mf_ul_data->data_size) {
- widget_add_string_element(
- widget, 0, 35, AlignLeft, AlignTop, FontSecondary, "Password-protected pages!");
+ string_cat_printf(temp_str, "\nPassword-protected pages!");
}
- string_clear(data_str);
+ widget_add_text_scroll_element(widget, 0, 0, 128, 52, string_get_cstr(temp_str));
+ string_clear(temp_str);
- // Setup TextBox view
- TextBox* text_box = nfc->text_box;
- text_box_set_font(text_box, TextBoxFontHex);
- for(uint16_t i = 0; i < mf_ul_data->data_size; i += 2) {
- if(!(i % 8) && i) {
- string_push_back(nfc->text_box_store, '\n');
- }
- string_cat_printf(
- nfc->text_box_store, "%02X%02X ", mf_ul_data->data[i], mf_ul_data->data[i + 1]);
- }
- text_box_set_text(text_box, string_get_cstr(nfc->text_box_store));
-
- scene_manager_set_scene_state(
- nfc->scene_manager, NfcSceneMfUltralightReadSuccess, ReadMifareUlStateShowInfo);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
}
bool nfc_scene_mf_ultralight_read_success_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = context;
bool consumed = false;
- uint32_t state =
- scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfUltralightReadSuccess);
if(event.type == SceneManagerEventTypeCustom) {
- if(state == ReadMifareUlStateShowInfo && event.event == GuiButtonTypeLeft) {
+ if(event.event == GuiButtonTypeLeft) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneRetryConfirm);
consumed = true;
- } else if(state == ReadMifareUlStateShowInfo && event.event == GuiButtonTypeRight) {
+ } else if(event.event == GuiButtonTypeRight) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightMenu);
consumed = true;
- } else if(state == ReadMifareUlStateShowInfo && event.event == GuiButtonTypeCenter) {
- view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextBox);
- scene_manager_set_scene_state(
- nfc->scene_manager, NfcSceneMfUltralightReadSuccess, ReadMifareUlStateShowData);
- consumed = true;
}
} else if(event.type == SceneManagerEventTypeBack) {
- if(state == ReadMifareUlStateShowData) {
- view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
- scene_manager_set_scene_state(
- nfc->scene_manager, NfcSceneMfUltralightReadSuccess, ReadMifareUlStateShowInfo);
- consumed = true;
- } else {
- scene_manager_next_scene(nfc->scene_manager, NfcSceneExitConfirm);
- consumed = true;
- }
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneExitConfirm);
+ consumed = true;
}
return consumed;
@@ -117,8 +73,6 @@ bool nfc_scene_mf_ultralight_read_success_on_event(void* context, SceneManagerEv
void nfc_scene_mf_ultralight_read_success_on_exit(void* context) {
Nfc* nfc = context;
- // Clean views
+ // Clean view
widget_reset(nfc->widget);
- text_box_reset(nfc->text_box);
- string_reset(nfc->text_box_store);
}
diff --git a/applications/nfc/scenes/nfc_scene_mf_ultralight_unlock_warn.c b/applications/nfc/scenes/nfc_scene_mf_ultralight_unlock_warn.c
index 00df98e75..58e081db9 100644
--- a/applications/nfc/scenes/nfc_scene_mf_ultralight_unlock_warn.c
+++ b/applications/nfc/scenes/nfc_scene_mf_ultralight_unlock_warn.c
@@ -16,7 +16,7 @@ void nfc_scene_mf_ultralight_unlock_warn_on_enter(void* context) {
dialog_ex_set_header(dialog_ex, "Risky function!", 64, 4, AlignCenter, AlignTop);
dialog_ex_set_text(
dialog_ex, "Wrong password\ncan block your\ncard.", 4, 18, AlignLeft, AlignTop);
- dialog_ex_set_icon(dialog_ex, 73, 17, &I_DolphinFirstStart8_56x51);
+ dialog_ex_set_icon(dialog_ex, 73, 20, &I_DolphinCommon_56x48);
dialog_ex_set_center_button_text(dialog_ex, "OK");
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDialogEx);
diff --git a/applications/nfc/scenes/nfc_scene_nfc_data_info.c b/applications/nfc/scenes/nfc_scene_nfc_data_info.c
new file mode 100644
index 000000000..33f5e44af
--- /dev/null
+++ b/applications/nfc/scenes/nfc_scene_nfc_data_info.c
@@ -0,0 +1,133 @@
+#include "../nfc_i.h"
+
+void nfc_scene_nfc_data_info_widget_callback(GuiButtonType result, InputType type, void* context) {
+ Nfc* nfc = context;
+ if(type == InputTypeShort) {
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
+ }
+}
+
+void nfc_scene_nfc_data_info_on_enter(void* context) {
+ Nfc* nfc = context;
+ Widget* widget = nfc->widget;
+ FuriHalNfcDevData* nfc_data = &nfc->dev->dev_data.nfc_data;
+ NfcDeviceData* dev_data = &nfc->dev->dev_data;
+ NfcProtocol protocol = dev_data->protocol;
+ uint8_t text_scroll_height = 0;
+ if((protocol == NfcDeviceProtocolMifareDesfire) || (protocol == NfcDeviceProtocolMifareUl)) {
+ widget_add_button_element(
+ widget, GuiButtonTypeRight, "More", nfc_scene_nfc_data_info_widget_callback, nfc);
+ text_scroll_height = 52;
+ } else {
+ text_scroll_height = 64;
+ }
+
+ string_t temp_str;
+ string_init(temp_str);
+ // Set name if present
+ if(nfc->dev->dev_name[0] != '\0') {
+ string_printf(temp_str, "\ec%s\n", nfc->dev->dev_name);
+ }
+
+ // Set tag type
+ if(protocol == NfcDeviceProtocolEMV) {
+ string_cat_printf(temp_str, "\e#EMV Bank Card\n");
+ } else if(protocol == NfcDeviceProtocolMifareUl) {
+ string_cat_printf(temp_str, "\e#%s\n", nfc_mf_ul_type(dev_data->mf_ul_data.type, true));
+ } else if(protocol == NfcDeviceProtocolMifareClassic) {
+ string_cat_printf(
+ temp_str, "\e#%s\n", nfc_mf_classic_type(dev_data->mf_classic_data.type));
+ } else if(protocol == NfcDeviceProtocolMifareDesfire) {
+ string_cat_printf(temp_str, "\e#MIFARE DESfire\n");
+ } else {
+ string_cat_printf(temp_str, "\e#Unknown ISO tag\n");
+ }
+
+ // Set tag iso data
+ char iso_type = FURI_BIT(nfc_data->sak, 5) ? '4' : '3';
+ string_cat_printf(temp_str, "ISO 14443-%c (NFC-A)\n", iso_type);
+ string_cat_printf(temp_str, "UID:");
+ for(size_t i = 0; i < nfc_data->uid_len; i++) {
+ string_cat_printf(temp_str, " %02X", nfc_data->uid[i]);
+ }
+ string_cat_printf(temp_str, "\nATQA: %02X %02X ", nfc_data->atqa[1], nfc_data->atqa[0]);
+ string_cat_printf(temp_str, " SAK: %02X", nfc_data->sak);
+
+ // Set application specific data
+ if(protocol == NfcDeviceProtocolMifareDesfire) {
+ MifareDesfireData* data = &dev_data->mf_df_data;
+ uint32_t bytes_total = 1 << (data->version.sw_storage >> 1);
+ uint32_t bytes_free = data->free_memory ? data->free_memory->bytes : 0;
+ string_cat_printf(temp_str, "\n%d", bytes_total);
+ if(data->version.sw_storage & 1) {
+ string_push_back(temp_str, '+');
+ }
+ string_cat_printf(temp_str, " bytes, %d bytes free\n", bytes_free);
+
+ uint16_t n_apps = 0;
+ uint16_t n_files = 0;
+ for(MifareDesfireApplication* app = data->app_head; app; app = app->next) {
+ n_apps++;
+ for(MifareDesfireFile* file = app->file_head; file; file = file->next) {
+ n_files++;
+ }
+ }
+ string_cat_printf(temp_str, "%d Application", n_apps);
+ if(n_apps != 1) {
+ string_push_back(temp_str, 's');
+ }
+ string_cat_printf(temp_str, ", %d file", n_files);
+ if(n_files != 1) {
+ string_push_back(temp_str, 's');
+ }
+ } else if(protocol == NfcDeviceProtocolMifareUl) {
+ MfUltralightData* data = &dev_data->mf_ul_data;
+ string_cat_printf(
+ temp_str, "\nPages Read %d/%d", data->data_read / 4, data->data_size / 4);
+ if(data->data_size > data->data_read) {
+ string_cat_printf(temp_str, "\nPassword-protected");
+ }
+ } else if(protocol == NfcDeviceProtocolMifareClassic) {
+ MfClassicData* data = &dev_data->mf_classic_data;
+ uint8_t sectors_total = mf_classic_get_total_sectors_num(data->type);
+ uint8_t keys_total = sectors_total * 2;
+ uint8_t keys_found = 0;
+ uint8_t sectors_read = 0;
+ mf_classic_get_read_sectors_and_keys(data, §ors_read, &keys_found);
+ string_cat_printf(temp_str, "\nKeys Found %d/%d", keys_found, keys_total);
+ string_cat_printf(temp_str, "\nSectors Read %d/%d", sectors_read, sectors_total);
+ }
+
+ // Add text scroll widget
+ widget_add_text_scroll_element(
+ widget, 0, 0, 128, text_scroll_height, string_get_cstr(temp_str));
+ string_clear(temp_str);
+
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
+}
+
+bool nfc_scene_nfc_data_info_on_event(void* context, SceneManagerEvent event) {
+ Nfc* nfc = context;
+ NfcProtocol protocol = nfc->dev->dev_data.protocol;
+ bool consumed = false;
+
+ if(event.type == SceneManagerEventTypeCustom) {
+ if(event.event == GuiButtonTypeRight) {
+ if(protocol == NfcDeviceProtocolMifareDesfire) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneMfDesfireApp);
+ consumed = true;
+ } else if(protocol == NfcDeviceProtocolMifareUl) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightData);
+ consumed = true;
+ }
+ }
+ }
+
+ return consumed;
+}
+
+void nfc_scene_nfc_data_info_on_exit(void* context) {
+ Nfc* nfc = context;
+
+ widget_reset(nfc->widget);
+}
\ No newline at end of file
diff --git a/applications/nfc/scenes/nfc_scene_nfca_menu.c b/applications/nfc/scenes/nfc_scene_nfca_menu.c
new file mode 100644
index 000000000..00d0d943d
--- /dev/null
+++ b/applications/nfc/scenes/nfc_scene_nfca_menu.c
@@ -0,0 +1,62 @@
+#include "../nfc_i.h"
+
+enum SubmenuIndex {
+ SubmenuIndexSaveUid,
+ SubmenuIndexEmulateUid,
+ SubmenuIndexInfo,
+};
+
+void nfc_scene_nfca_menu_submenu_callback(void* context, uint32_t index) {
+ Nfc* nfc = context;
+
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, index);
+}
+
+void nfc_scene_nfca_menu_on_enter(void* context) {
+ Nfc* nfc = context;
+ Submenu* submenu = nfc->submenu;
+
+ submenu_add_item(
+ submenu, "Save UID", SubmenuIndexSaveUid, nfc_scene_nfca_menu_submenu_callback, nfc);
+ submenu_add_item(
+ submenu, "Emulate UID", SubmenuIndexEmulateUid, nfc_scene_nfca_menu_submenu_callback, nfc);
+ submenu_add_item(submenu, "Info", SubmenuIndexInfo, nfc_scene_nfca_menu_submenu_callback, nfc);
+
+ submenu_set_selected_item(
+ nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneNfcaMenu));
+
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu);
+}
+
+bool nfc_scene_nfca_menu_on_event(void* context, SceneManagerEvent event) {
+ Nfc* nfc = context;
+ bool consumed = false;
+
+ if(event.type == SceneManagerEventTypeCustom) {
+ if(event.event == SubmenuIndexSaveUid) {
+ nfc->dev->format = NfcDeviceSaveFormatUid;
+ // Clear device name
+ nfc_device_set_name(nfc->dev, "");
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
+ consumed = true;
+ } else if(event.event == SubmenuIndexEmulateUid) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid);
+ consumed = true;
+ } else if(event.event == SubmenuIndexInfo) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcDataInfo);
+ consumed = true;
+ }
+ scene_manager_set_scene_state(nfc->scene_manager, NfcSceneNfcaMenu, event.event);
+ } else if(event.type == SceneManagerEventTypeBack) {
+ consumed = scene_manager_previous_scene(nfc->scene_manager);
+ }
+
+ return consumed;
+}
+
+void nfc_scene_nfca_menu_on_exit(void* context) {
+ Nfc* nfc = context;
+
+ // Clear view
+ submenu_reset(nfc->submenu);
+}
diff --git a/applications/nfc/scenes/nfc_scene_nfca_read_success.c b/applications/nfc/scenes/nfc_scene_nfca_read_success.c
new file mode 100644
index 000000000..3467a03b6
--- /dev/null
+++ b/applications/nfc/scenes/nfc_scene_nfca_read_success.c
@@ -0,0 +1,72 @@
+#include "../nfc_i.h"
+#include
+
+void nfc_scene_nfca_read_success_widget_callback(
+ GuiButtonType result,
+ InputType type,
+ void* context) {
+ furi_assert(context);
+ Nfc* nfc = context;
+
+ if(type == InputTypeShort) {
+ view_dispatcher_send_custom_event(nfc->view_dispatcher, result);
+ }
+}
+
+void nfc_scene_nfca_read_success_on_enter(void* context) {
+ Nfc* nfc = context;
+
+ DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
+
+ // Setup view
+ FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data;
+ Widget* widget = nfc->widget;
+
+ string_t temp_str;
+ string_init_set_str(temp_str, "\e#Unknown ISO tag\n");
+
+ char iso_type = FURI_BIT(data->sak, 5) ? '4' : '3';
+ string_cat_printf(temp_str, "ISO 14443-%c (NFC-A)\n", iso_type);
+ string_cat_printf(temp_str, "UID:");
+ for(size_t i = 0; i < data->uid_len; i++) {
+ string_cat_printf(temp_str, " %02X", data->uid[i]);
+ }
+ string_cat_printf(temp_str, "\nATQA: %02X %02X ", data->atqa[1], data->atqa[0]);
+ string_cat_printf(temp_str, " SAK: %02X", data->sak);
+
+ widget_add_text_scroll_element(widget, 0, 0, 128, 52, string_get_cstr(temp_str));
+ string_clear(temp_str);
+
+ widget_add_button_element(
+ widget, GuiButtonTypeLeft, "Retry", nfc_scene_nfca_read_success_widget_callback, nfc);
+ widget_add_button_element(
+ widget, GuiButtonTypeRight, "More", nfc_scene_nfca_read_success_widget_callback, nfc);
+
+ view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
+}
+
+bool nfc_scene_nfca_read_success_on_event(void* context, SceneManagerEvent event) {
+ Nfc* nfc = context;
+ bool consumed = false;
+
+ if(event.type == SceneManagerEventTypeCustom) {
+ if(event.event == GuiButtonTypeLeft) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneRetryConfirm);
+ consumed = true;
+ } else if(event.event == GuiButtonTypeRight) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcaMenu);
+ consumed = true;
+ }
+ } else if(event.type == SceneManagerEventTypeBack) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneExitConfirm);
+ consumed = true;
+ }
+ return consumed;
+}
+
+void nfc_scene_nfca_read_success_on_exit(void* context) {
+ Nfc* nfc = context;
+
+ // Clear view
+ widget_reset(nfc->widget);
+}
diff --git a/applications/nfc/scenes/nfc_scene_read.c b/applications/nfc/scenes/nfc_scene_read.c
index 491b419ef..00b7c8fac 100644
--- a/applications/nfc/scenes/nfc_scene_read.c
+++ b/applications/nfc/scenes/nfc_scene_read.c
@@ -59,11 +59,14 @@ bool nfc_scene_read_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
if((event.event == NfcWorkerEventReadUidNfcB) ||
(event.event == NfcWorkerEventReadUidNfcF) ||
- (event.event == NfcWorkerEventReadUidNfcV) ||
- (event.event == NfcWorkerEventReadUidNfcA)) {
+ (event.event == NfcWorkerEventReadUidNfcV)) {
notification_message(nfc->notifications, &sequence_success);
scene_manager_next_scene(nfc->scene_manager, NfcSceneReadCardSuccess);
consumed = true;
+ } else if(event.event == NfcWorkerEventReadUidNfcA) {
+ notification_message(nfc->notifications, &sequence_success);
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcaReadSuccess);
+ consumed = true;
} else if(event.event == NfcWorkerEventReadMfUltralight) {
notification_message(nfc->notifications, &sequence_success);
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightReadSuccess);
diff --git a/applications/nfc/scenes/nfc_scene_read_card_success.c b/applications/nfc/scenes/nfc_scene_read_card_success.c
index b889ce08d..0cb38cbdf 100755
--- a/applications/nfc/scenes/nfc_scene_read_card_success.c
+++ b/applications/nfc/scenes/nfc_scene_read_card_success.c
@@ -16,44 +16,26 @@ void nfc_scene_read_card_success_widget_callback(
void nfc_scene_read_card_success_on_enter(void* context) {
Nfc* nfc = context;
- string_t data_str;
- string_t uid_str;
- string_init(data_str);
- string_init(uid_str);
+ string_t temp_str;
+ string_init(temp_str);
DOLPHIN_DEED(DolphinDeedNfcReadSuccess);
// Setup view
FuriHalNfcDevData* data = &nfc->dev->dev_data.nfc_data;
Widget* widget = nfc->widget;
- string_set_str(data_str, nfc_get_dev_type(data->type));
- string_set_str(uid_str, "UID:");
+ string_set_str(temp_str, nfc_get_dev_type(data->type));
+ widget_add_string_element(
+ widget, 64, 12, AlignCenter, AlignBottom, FontPrimary, string_get_cstr(temp_str));
+ string_set_str(temp_str, "UID:");
for(uint8_t i = 0; i < data->uid_len; i++) {
- string_cat_printf(uid_str, " %02X", data->uid[i]);
+ string_cat_printf(temp_str, " %02X", data->uid[i]);
}
-
+ widget_add_string_element(
+ widget, 64, 32, AlignCenter, AlignCenter, FontSecondary, string_get_cstr(temp_str));
widget_add_button_element(
widget, GuiButtonTypeLeft, "Retry", nfc_scene_read_card_success_widget_callback, nfc);
- if(data->type == FuriHalNfcTypeA) {
- widget_add_button_element(
- widget, GuiButtonTypeRight, "Save", nfc_scene_read_card_success_widget_callback, nfc);
- widget_add_icon_element(widget, 8, 13, &I_Medium_chip_22x21);
- widget_add_string_element(
- widget, 37, 12, AlignLeft, AlignBottom, FontPrimary, string_get_cstr(data_str));
- string_printf(
- data_str, "ATQA: %02X%02X\nSAK: %02X", data->atqa[0], data->atqa[1], data->sak);
- widget_add_string_multiline_element(
- widget, 37, 16, AlignLeft, AlignTop, FontSecondary, string_get_cstr(data_str));
- widget_add_string_element(
- widget, 64, 46, AlignCenter, AlignBottom, FontSecondary, string_get_cstr(uid_str));
- } else {
- widget_add_string_element(
- widget, 64, 12, AlignCenter, AlignBottom, FontPrimary, string_get_cstr(data_str));
- widget_add_string_element(
- widget, 64, 32, AlignCenter, AlignCenter, FontSecondary, string_get_cstr(uid_str));
- }
- string_clear(data_str);
- string_clear(uid_str);
+ string_clear(temp_str);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewWidget);
}
@@ -65,11 +47,6 @@ bool nfc_scene_read_card_success_on_event(void* context, SceneManagerEvent event
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == GuiButtonTypeLeft) {
consumed = scene_manager_previous_scene(nfc->scene_manager);
- } else if(event.event == GuiButtonTypeRight) {
- nfc->dev->format = NfcDeviceSaveFormatUid;
- nfc_device_set_name(nfc->dev, "");
- scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName);
- consumed = true;
}
}
return consumed;
diff --git a/applications/nfc/scenes/nfc_scene_rpc.c b/applications/nfc/scenes/nfc_scene_rpc.c
index 94beccc6b..7a9eb4503 100644
--- a/applications/nfc/scenes/nfc_scene_rpc.c
+++ b/applications/nfc/scenes/nfc_scene_rpc.c
@@ -4,10 +4,10 @@ void nfc_scene_rpc_on_enter(void* context) {
Nfc* nfc = context;
Popup* popup = nfc->popup;
- popup_set_header(popup, "NFC", 82, 28, AlignCenter, AlignBottom);
- popup_set_text(popup, "RPC mode", 82, 32, AlignCenter, AlignTop);
+ popup_set_header(popup, "NFC", 89, 42, AlignCenter, AlignBottom);
+ popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop);
- popup_set_icon(popup, 2, 14, &I_Warning_30x23); // TODO: icon
+ popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61);
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewPopup);
@@ -31,13 +31,11 @@ bool nfc_scene_rpc_on_event(void* context, SceneManagerEvent event) {
consumed = true;
if(event.event == NfcCustomEventViewExit) {
rpc_system_app_confirm(nfc->rpc_ctx, RpcAppEventAppExit, true);
+ scene_manager_stop(nfc->scene_manager);
view_dispatcher_stop(nfc->view_dispatcher);
- nfc_blink_stop(nfc);
} else if(event.event == NfcCustomEventRpcSessionClose) {
- rpc_system_app_set_callback(nfc->rpc_ctx, NULL, NULL);
- nfc->rpc_ctx = NULL;
+ scene_manager_stop(nfc->scene_manager);
view_dispatcher_stop(nfc->view_dispatcher);
- nfc_blink_stop(nfc);
} else if(event.event == NfcCustomEventRpcLoad) {
bool result = false;
const char* arg = rpc_system_app_get_data(nfc->rpc_ctx);
@@ -66,7 +64,7 @@ bool nfc_scene_rpc_on_event(void* context, SceneManagerEvent event) {
nfc_blink_start(nfc);
nfc_text_store_set(nfc, "emulating\n%s", nfc->dev->dev_name);
- popup_set_text(popup, nfc->text_store, 82, 32, AlignCenter, AlignTop);
+ popup_set_text(popup, nfc->text_store, 89, 44, AlignCenter, AlignTop);
}
}
diff --git a/applications/nfc/scenes/nfc_scene_saved_menu.c b/applications/nfc/scenes/nfc_scene_saved_menu.c
index e6b08e71b..c7aec5d87 100644
--- a/applications/nfc/scenes/nfc_scene_saved_menu.c
+++ b/applications/nfc/scenes/nfc_scene_saved_menu.c
@@ -44,8 +44,6 @@ void nfc_scene_saved_menu_on_enter(void* context) {
}
submenu_add_item(
submenu, "Info", SubmenuIndexInfo, nfc_scene_saved_menu_submenu_callback, nfc);
- submenu_set_selected_item(
- nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneSavedMenu));
if(nfc->dev->shadow_file_exist) {
submenu_add_item(
submenu,
@@ -58,12 +56,15 @@ void nfc_scene_saved_menu_on_enter(void* context) {
submenu, "Rename", SubmenuIndexRename, nfc_scene_saved_menu_submenu_callback, nfc);
submenu_add_item(
submenu, "Delete", SubmenuIndexDelete, nfc_scene_saved_menu_submenu_callback, nfc);
+ submenu_set_selected_item(
+ nfc->submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneSavedMenu));
view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewMenu);
}
bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) {
Nfc* nfc = context;
+ NfcDeviceData* dev_data = &nfc->dev->dev_data;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
@@ -87,7 +88,18 @@ bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneDelete);
consumed = true;
} else if(event.event == SubmenuIndexInfo) {
- scene_manager_next_scene(nfc->scene_manager, NfcSceneDeviceInfo);
+ bool application_info_present = false;
+ if(dev_data->protocol == NfcDeviceProtocolEMV) {
+ application_info_present = true;
+ } else if(dev_data->protocol == NfcDeviceProtocolMifareClassic) {
+ application_info_present = nfc_supported_card_verify_and_parse(dev_data);
+ }
+
+ if(application_info_present) {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneDeviceInfo);
+ } else {
+ scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcDataInfo);
+ }
consumed = true;
} else if(event.event == SubmenuIndexRestoreOriginal) {
scene_manager_next_scene(nfc->scene_manager, NfcSceneRestoreOriginalConfirm);
diff --git a/applications/nfc/views/bank_card.c b/applications/nfc/views/bank_card.c
deleted file mode 100755
index 31cc56ee8..000000000
--- a/applications/nfc/views/bank_card.c
+++ /dev/null
@@ -1,80 +0,0 @@
-#include "bank_card.h"
-#include "../helpers/nfc_emv_parser.h"
-#include
-
-struct BankCard {
- Widget* widget;
-};
-
-BankCard* bank_card_alloc() {
- BankCard* bank_card = malloc(sizeof(BankCard));
- bank_card->widget = widget_alloc();
- return bank_card;
-}
-
-void bank_card_free(BankCard* bank_card) {
- furi_assert(bank_card);
- widget_free(bank_card->widget);
- free(bank_card);
-}
-
-View* bank_card_get_view(BankCard* bank_card) {
- furi_assert(bank_card);
- return widget_get_view(bank_card->widget);
-}
-
-void bank_card_clear(BankCard* bank_card) {
- furi_assert(bank_card);
- widget_reset(bank_card->widget);
-}
-
-void bank_card_set_name(BankCard* bank_card, char* name) {
- furi_assert(bank_card);
- furi_assert(name);
- widget_add_string_element(
- bank_card->widget, 64, 6, AlignCenter, AlignTop, FontSecondary, name);
-}
-
-void bank_card_set_number(BankCard* bank_card, uint8_t* number, uint8_t len) {
- furi_assert(bank_card);
- furi_assert(number);
- string_t num_str;
- string_init(num_str);
- for(uint8_t i = 0; i < len; i += 2) {
- string_cat_printf(num_str, "%02X%02X ", number[i], number[i + 1]);
- }
- // Add number
- widget_add_string_element(
- bank_card->widget, 64, 32, AlignCenter, AlignTop, FontSecondary, string_get_cstr(num_str));
- string_clear(num_str);
- // Add icon
- widget_add_icon_element(bank_card->widget, 8, 15, &I_Detailed_chip_17x13);
- // Add frame
- widget_add_frame_element(bank_card->widget, 0, 0, 128, 64, 6);
-}
-
-void bank_card_set_back_callback(BankCard* bank_card, ButtonCallback callback, void* context) {
- furi_assert(bank_card);
- furi_assert(callback);
- widget_add_button_element(bank_card->widget, GuiButtonTypeLeft, "Back", callback, context);
-}
-
-void bank_card_set_exp_date(BankCard* bank_card, uint8_t mon, uint8_t year) {
- furi_assert(bank_card);
- char exp_date_str[16];
- snprintf(exp_date_str, sizeof(exp_date_str), "Exp: %02X/%02X", mon, year);
- widget_add_string_element(
- bank_card->widget, 122, 54, AlignRight, AlignBottom, FontSecondary, exp_date_str);
-}
-
-void bank_card_set_country_name(BankCard* bank_card, const char* country_name) {
- furi_assert(bank_card);
- widget_add_string_element(
- bank_card->widget, 120, 18, AlignRight, AlignTop, FontSecondary, country_name);
-}
-
-void bank_card_set_currency_name(BankCard* bank_card, const char* currency_name) {
- furi_assert(bank_card);
- widget_add_string_element(
- bank_card->widget, 31, 18, AlignLeft, AlignTop, FontSecondary, currency_name);
-}
diff --git a/applications/nfc/views/bank_card.h b/applications/nfc/views/bank_card.h
deleted file mode 100644
index 628d9deb8..000000000
--- a/applications/nfc/views/bank_card.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-#include
-#include
-#include
-
-typedef struct BankCard BankCard;
-
-BankCard* bank_card_alloc();
-
-void bank_card_free(BankCard* bank_card);
-
-void bank_card_clear(BankCard* bank_card);
-
-View* bank_card_get_view(BankCard* bank_card);
-
-void bank_card_set_back_callback(BankCard* bank_card, ButtonCallback callback, void* context);
-
-void bank_card_set_name(BankCard* bank_card, char* name);
-
-void bank_card_set_number(BankCard* bank_card, uint8_t* number, uint8_t len);
-
-void bank_card_set_exp_date(BankCard* bank_card, uint8_t mon, uint8_t year);
-
-void bank_card_set_country_name(BankCard* bank_card, const char* country_name);
-
-void bank_card_set_currency_name(BankCard* bank_card, const char* currency_name);
diff --git a/applications/rpc/rpc_storage.c b/applications/rpc/rpc_storage.c
index 1e2920f5b..ad6191b2f 100644
--- a/applications/rpc/rpc_storage.c
+++ b/applications/rpc/rpc_storage.c
@@ -297,36 +297,44 @@ static void rpc_system_storage_read_process(const PB_Main* request, void* contex
const char* path = request->content.storage_read_request.path;
Storage* fs_api = furi_record_open(RECORD_STORAGE);
File* file = storage_file_alloc(fs_api);
- bool result = false;
+ bool fs_operation_success = storage_file_open(file, path, FSAM_READ, FSOM_OPEN_EXISTING);
- if(storage_file_open(file, path, FSAM_READ, FSOM_OPEN_EXISTING)) {
+ if(fs_operation_success) {
size_t size_left = storage_file_size(file);
do {
response->command_id = request->command_id;
response->which_content = PB_Main_storage_read_response_tag;
response->command_status = PB_CommandStatus_OK;
- response->content.storage_read_response.has_file = true;
- response->content.storage_read_response.file.data =
- malloc(PB_BYTES_ARRAY_T_ALLOCSIZE(MIN(size_left, MAX_DATA_SIZE)));
- uint8_t* buffer = response->content.storage_read_response.file.data->bytes;
- uint16_t* read_size_msg = &response->content.storage_read_response.file.data->size;
size_t read_size = MIN(size_left, MAX_DATA_SIZE);
- *read_size_msg = storage_file_read(file, buffer, read_size);
- size_left -= read_size;
- result = (*read_size_msg == read_size);
+ if(read_size) {
+ response->content.storage_read_response.has_file = true;
+ response->content.storage_read_response.file.data =
+ malloc(PB_BYTES_ARRAY_T_ALLOCSIZE(read_size));
+ uint8_t* buffer = &response->content.storage_read_response.file.data->bytes[0];
+ uint16_t* read_size_msg = &response->content.storage_read_response.file.data->size;
- if(result) {
- response->has_next = (size_left > 0);
+ *read_size_msg = storage_file_read(file, buffer, read_size);
+ size_left -= *read_size_msg;
+ fs_operation_success = (*read_size_msg == read_size);
+
+ response->has_next = fs_operation_success && (size_left > 0);
+ } else {
+ response->content.storage_read_response.file.data =
+ malloc(PB_BYTES_ARRAY_T_ALLOCSIZE(0));
+ response->content.storage_read_response.file.data->size = 0;
+ response->content.storage_read_response.has_file = true;
+ response->has_next = false;
+ fs_operation_success = true;
+ }
+
+ if(fs_operation_success) {
rpc_send_and_release(session, response);
}
- } while((size_left != 0) && result);
+ } while((size_left != 0) && fs_operation_success);
+ }
- if(!result) {
- rpc_send_and_release_empty(
- session, request->command_id, rpc_system_storage_get_file_error(file));
- }
- } else {
+ if(!fs_operation_success) {
rpc_send_and_release_empty(
session, request->command_id, rpc_system_storage_get_file_error(file));
}
@@ -349,7 +357,7 @@ static void rpc_system_storage_write_process(const PB_Main* request, void* conte
RpcSession* session = rpc_storage->session;
furi_assert(session);
- bool result = true;
+ bool fs_operation_success = true;
if(!path_contains_only_ascii(request->content.storage_write_request.path)) {
rpc_storage->current_command_id = request->command_id;
@@ -370,28 +378,34 @@ static void rpc_system_storage_write_process(const PB_Main* request, void* conte
rpc_storage->current_command_id = request->command_id;
rpc_storage->state = RpcStorageStateWriting;
const char* path = request->content.storage_write_request.path;
- result = storage_file_open(rpc_storage->file, path, FSAM_WRITE, FSOM_CREATE_ALWAYS);
+ fs_operation_success =
+ storage_file_open(rpc_storage->file, path, FSAM_WRITE, FSOM_CREATE_ALWAYS);
}
File* file = rpc_storage->file;
+ bool send_response = false;
- if(result) {
- uint8_t* buffer = request->content.storage_write_request.file.data->bytes;
- size_t buffer_size = request->content.storage_write_request.file.data->size;
-
- uint16_t written_size = storage_file_write(file, buffer, buffer_size);
- result = (written_size == buffer_size);
-
- if(result && !request->has_next) {
- rpc_send_and_release_empty(
- session, rpc_storage->current_command_id, PB_CommandStatus_OK);
- rpc_system_storage_reset_state(rpc_storage, session, false);
+ if(fs_operation_success) {
+ if(request->content.storage_write_request.has_file &&
+ request->content.storage_write_request.file.data &&
+ request->content.storage_write_request.file.data->size) {
+ uint8_t* buffer = request->content.storage_write_request.file.data->bytes;
+ size_t buffer_size = request->content.storage_write_request.file.data->size;
+ uint16_t written_size = storage_file_write(file, buffer, buffer_size);
+ fs_operation_success = (written_size == buffer_size);
}
+
+ send_response = !request->has_next;
}
- if(!result) {
- rpc_send_and_release_empty(
- session, rpc_storage->current_command_id, rpc_system_storage_get_file_error(file));
+ PB_CommandStatus command_status = PB_CommandStatus_OK;
+ if(!fs_operation_success) {
+ send_response = true;
+ command_status = rpc_system_storage_get_file_error(file);
+ }
+
+ if(send_response) {
+ rpc_send_and_release_empty(session, rpc_storage->current_command_id, command_status);
rpc_system_storage_reset_state(rpc_storage, session, false);
}
}
diff --git a/applications/sentry_safe/sentry_safe.c b/applications/sentry_safe/sentry_safe.c
index 328b53f03..d36e4a63a 100644
--- a/applications/sentry_safe/sentry_safe.c
+++ b/applications/sentry_safe/sentry_safe.c
@@ -102,7 +102,7 @@ int32_t sentry_safe_app(void* p) {
view_port_input_callback_set(view_port, sentry_safe_input_callback, event_queue);
// Open GUI and register view_port
- Gui* gui = furi_record_open("gui");
+ Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
Event event;
@@ -156,7 +156,7 @@ int32_t sentry_safe_app(void* p) {
view_port_enabled_set(view_port, false);
gui_remove_view_port(gui, view_port);
- furi_record_close("gui");
+ furi_record_close(RECORD_GUI);
view_port_free(view_port);
furi_message_queue_free(event_queue);
delete_mutex(&state_mutex);
diff --git a/applications/spectrum_analyzer/spectrum_analyzer.c b/applications/spectrum_analyzer/spectrum_analyzer.c
index e7047763f..503870ed8 100644
--- a/applications/spectrum_analyzer/spectrum_analyzer.c
+++ b/applications/spectrum_analyzer/spectrum_analyzer.c
@@ -369,7 +369,7 @@ SpectrumAnalyzer* spectrum_analyzer_alloc() {
view_port_input_callback_set(instance->view_port, spectrum_analyzer_input_callback, instance);
// Open GUI and register view_port
- instance->gui = furi_record_open("gui");
+ instance->gui = furi_record_open(RECORD_GUI);
gui_add_view_port(instance->gui, instance->view_port, GuiLayerFullscreen);
return instance;
@@ -378,7 +378,7 @@ SpectrumAnalyzer* spectrum_analyzer_alloc() {
void spectrum_analyzer_free(SpectrumAnalyzer* instance) {
// view_port_enabled_set(view_port, false);
gui_remove_view_port(instance->gui, instance->view_port);
- furi_record_close("gui");
+ furi_record_close(RECORD_GUI);
view_port_free(instance->view_port);
spectrum_analyzer_worker_free(instance->worker);
diff --git a/applications/storage/storage_cli.c b/applications/storage/storage_cli.c
index fd988da76..802ebd548 100644
--- a/applications/storage/storage_cli.c
+++ b/applications/storage/storage_cli.c
@@ -274,24 +274,26 @@ static void storage_cli_read_chunks(Cli* cli, string_t path, string_t args) {
if(parsed_count == EOF || parsed_count != 1) {
storage_cli_print_usage();
} else if(storage_file_open(file, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
- uint8_t* data = malloc(buffer_size);
uint64_t file_size = storage_file_size(file);
printf("Size: %lu\r\n", (uint32_t)file_size);
- while(file_size > 0) {
- printf("\r\nReady?\r\n");
- cli_getc(cli);
+ if(buffer_size) {
+ uint8_t* data = malloc(buffer_size);
+ while(file_size > 0) {
+ printf("\r\nReady?\r\n");
+ cli_getc(cli);
- uint16_t read_size = storage_file_read(file, data, buffer_size);
- for(uint16_t i = 0; i < read_size; i++) {
- putchar(data[i]);
+ uint16_t read_size = storage_file_read(file, data, buffer_size);
+ for(uint16_t i = 0; i < read_size; i++) {
+ putchar(data[i]);
+ }
+ file_size -= read_size;
}
- file_size -= read_size;
+ free(data);
}
printf("\r\n");
- free(data);
} else {
storage_cli_print_error(storage_file_get_error(file));
}
@@ -315,19 +317,21 @@ static void storage_cli_write_chunk(Cli* cli, string_t path, string_t args) {
if(storage_file_open(file, string_get_cstr(path), FSAM_WRITE, FSOM_OPEN_APPEND)) {
printf("Ready\r\n");
- uint8_t* buffer = malloc(buffer_size);
+ if(buffer_size) {
+ uint8_t* buffer = malloc(buffer_size);
- for(uint32_t i = 0; i < buffer_size; i++) {
- buffer[i] = cli_getc(cli);
+ for(uint32_t i = 0; i < buffer_size; i++) {
+ buffer[i] = cli_getc(cli);
+ }
+
+ uint16_t written_size = storage_file_write(file, buffer, buffer_size);
+
+ if(written_size != buffer_size) {
+ storage_cli_print_error(storage_file_get_error(file));
+ }
+
+ free(buffer);
}
-
- uint16_t written_size = storage_file_write(file, buffer, buffer_size);
-
- if(written_size != buffer_size) {
- storage_cli_print_error(storage_file_get_error(file));
- }
-
- free(buffer);
} else {
storage_cli_print_error(storage_file_get_error(file));
}
diff --git a/applications/storage_settings/scenes/storage_settings_scene_benchmark.c b/applications/storage_settings/scenes/storage_settings_scene_benchmark.c
index 615e07f8b..ddeea4eba 100644
--- a/applications/storage_settings/scenes/storage_settings_scene_benchmark.c
+++ b/applications/storage_settings/scenes/storage_settings_scene_benchmark.c
@@ -122,7 +122,7 @@ void storage_settings_scene_benchmark_on_enter(void* context) {
view_dispatcher_switch_to_view(app->view_dispatcher, StorageSettingsViewDialogEx);
if(sd_status != FSE_OK) {
- dialog_ex_set_icon(dialog_ex, 72, 14, &I_DolphinFirstStart8_56x51);
+ dialog_ex_set_icon(dialog_ex, 72, 17, &I_DolphinCommon_56x48);
dialog_ex_set_header(dialog_ex, "SD Card Not Mounted", 64, 3, AlignCenter, AlignTop);
dialog_ex_set_text(
dialog_ex, "Try to reinsert\nor format SD\ncard.", 3, 19, AlignLeft, AlignTop);
diff --git a/applications/storage_settings/scenes/storage_settings_scene_format_confirm.c b/applications/storage_settings/scenes/storage_settings_scene_format_confirm.c
index ebf7dece4..261ef1997 100644
--- a/applications/storage_settings/scenes/storage_settings_scene_format_confirm.c
+++ b/applications/storage_settings/scenes/storage_settings_scene_format_confirm.c
@@ -14,7 +14,7 @@ void storage_settings_scene_format_confirm_on_enter(void* context) {
FS_Error sd_status = storage_sd_status(app->fs_api);
if(sd_status == FSE_NOT_READY) {
- dialog_ex_set_icon(dialog_ex, 72, 14, &I_DolphinFirstStart8_56x51);
+ dialog_ex_set_icon(dialog_ex, 72, 17, &I_DolphinCommon_56x48);
dialog_ex_set_header(dialog_ex, "SD Card Not Mounted", 64, 3, AlignCenter, AlignTop);
dialog_ex_set_text(
dialog_ex, "Try to reinsert\nor format SD\ncard.", 3, 19, AlignLeft, AlignTop);
diff --git a/applications/storage_settings/scenes/storage_settings_scene_formatting.c b/applications/storage_settings/scenes/storage_settings_scene_formatting.c
index e0d8dfca8..df5e3cc17 100755
--- a/applications/storage_settings/scenes/storage_settings_scene_formatting.c
+++ b/applications/storage_settings/scenes/storage_settings_scene_formatting.c
@@ -47,7 +47,7 @@ void storage_settings_scene_formatting_on_enter(void* context) {
dialog_ex_set_text(
dialog_ex, storage_error_get_desc(error), 64, 32, AlignCenter, AlignCenter);
} else {
- dialog_ex_set_icon(dialog_ex, 72, 14, &I_DolphinFirstStart8_56x51);
+ dialog_ex_set_icon(dialog_ex, 72, 17, &I_DolphinCommon_56x48);
dialog_ex_set_header(dialog_ex, "Format\ncomplete!", 14, 15, AlignLeft, AlignTop);
}
dialog_ex_set_center_button_text(dialog_ex, "OK");
diff --git a/applications/storage_settings/scenes/storage_settings_scene_sd_info.c b/applications/storage_settings/scenes/storage_settings_scene_sd_info.c
index 485368c55..cfb4f310d 100644
--- a/applications/storage_settings/scenes/storage_settings_scene_sd_info.c
+++ b/applications/storage_settings/scenes/storage_settings_scene_sd_info.c
@@ -18,7 +18,7 @@ void storage_settings_scene_sd_info_on_enter(void* context) {
dialog_ex_set_result_callback(dialog_ex, storage_settings_scene_sd_info_dialog_callback);
if(sd_status != FSE_OK) {
- dialog_ex_set_icon(dialog_ex, 72, 14, &I_DolphinFirstStart8_56x51);
+ dialog_ex_set_icon(dialog_ex, 72, 17, &I_DolphinCommon_56x48);
dialog_ex_set_header(dialog_ex, "SD Card Not Mounted", 64, 3, AlignCenter, AlignTop);
dialog_ex_set_text(
dialog_ex, "Try to reinsert\nor format SD\ncard.", 3, 19, AlignLeft, AlignTop);
diff --git a/applications/storage_settings/scenes/storage_settings_scene_unmount_confirm.c b/applications/storage_settings/scenes/storage_settings_scene_unmount_confirm.c
index 971870715..2b485b7f7 100644
--- a/applications/storage_settings/scenes/storage_settings_scene_unmount_confirm.c
+++ b/applications/storage_settings/scenes/storage_settings_scene_unmount_confirm.c
@@ -14,7 +14,7 @@ void storage_settings_scene_unmount_confirm_on_enter(void* context) {
FS_Error sd_status = storage_sd_status(app->fs_api);
if(sd_status == FSE_NOT_READY) {
- dialog_ex_set_icon(dialog_ex, 72, 14, &I_DolphinFirstStart8_56x51);
+ dialog_ex_set_icon(dialog_ex, 72, 17, &I_DolphinCommon_56x48);
dialog_ex_set_header(dialog_ex, "SD Card Not Mounted", 64, 3, AlignCenter, AlignTop);
dialog_ex_set_text(
dialog_ex, "Try to reinsert\nor format SD\ncard.", 3, 19, AlignLeft, AlignTop);
diff --git a/applications/storage_settings/scenes/storage_settings_scene_unmounted.c b/applications/storage_settings/scenes/storage_settings_scene_unmounted.c
index 43f44583d..486f07603 100644
--- a/applications/storage_settings/scenes/storage_settings_scene_unmounted.c
+++ b/applications/storage_settings/scenes/storage_settings_scene_unmounted.c
@@ -13,7 +13,7 @@ void storage_settings_scene_unmounted_on_enter(void* context) {
DialogEx* dialog_ex = app->dialog_ex;
dialog_ex_set_center_button_text(dialog_ex, "OK");
- dialog_ex_set_icon(dialog_ex, 72, 14, &I_DolphinFirstStart8_56x51);
+ dialog_ex_set_icon(dialog_ex, 72, 17, &I_DolphinCommon_56x48);
if(error == FSE_OK) {
dialog_ex_set_header(dialog_ex, "SD Card Unmounted", 64, 3, AlignCenter, AlignTop);
diff --git a/applications/subghz/scenes/subghz_scene_need_saving.c b/applications/subghz/scenes/subghz_scene_need_saving.c
index eb70223a7..53bffedc8 100644
--- a/applications/subghz/scenes/subghz_scene_need_saving.c
+++ b/applications/subghz/scenes/subghz_scene_need_saving.c
@@ -16,7 +16,7 @@ void subghz_scene_need_saving_on_enter(void* context) {
SubGhz* subghz = context;
widget_add_string_multiline_element(
- subghz->widget, 64, 13, AlignCenter, AlignCenter, FontPrimary, "Exit to Sub-Ghz menu?");
+ subghz->widget, 64, 13, AlignCenter, AlignCenter, FontPrimary, "Exit to Sub-GHz menu?");
widget_add_string_multiline_element(
subghz->widget,
64,
diff --git a/applications/subghz/scenes/subghz_scene_receiver_config.c b/applications/subghz/scenes/subghz_scene_receiver_config.c
index bf2f0cdba..c59630f7e 100644
--- a/applications/subghz/scenes/subghz_scene_receiver_config.c
+++ b/applications/subghz/scenes/subghz_scene_receiver_config.c
@@ -100,7 +100,7 @@ static void subghz_scene_receiver_config_set_preset(VariableItem* item) {
subghz_setting_get_preset_data_size(subghz->setting, index));
}
-static void subghz_scene_receiver_config_set_hopping_runing(VariableItem* item) {
+static void subghz_scene_receiver_config_set_hopping_running(VariableItem* item) {
SubGhz* subghz = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item);
@@ -176,7 +176,7 @@ void subghz_scene_receiver_config_on_enter(void* context) {
subghz->variable_item_list,
"Hopping:",
HOPPING_COUNT,
- subghz_scene_receiver_config_set_hopping_runing,
+ subghz_scene_receiver_config_set_hopping_running,
subghz);
value_index = subghz_scene_receiver_config_hopper_value_index(
subghz->txrx->hopper_state, hopping_value, HOPPING_COUNT, subghz);
diff --git a/applications/subghz/scenes/subghz_scene_receiver_info.c b/applications/subghz/scenes/subghz_scene_receiver_info.c
index 0e973870c..c25d6ef8b 100644
--- a/applications/subghz/scenes/subghz_scene_receiver_info.c
+++ b/applications/subghz/scenes/subghz_scene_receiver_info.c
@@ -101,7 +101,7 @@ void subghz_scene_receiver_info_draw_widget(SubGhz* subghz) {
subghz);
}
} else {
- widget_add_icon_element(subghz->widget, 32, 12, &I_DolphinFirstStart7_61x51);
+ widget_add_icon_element(subghz->widget, 37, 15, &I_DolphinCommon_56x48);
widget_add_string_element(
subghz->widget, 13, 8, AlignLeft, AlignBottom, FontSecondary, "Error history parse.");
}
diff --git a/applications/subghz/scenes/subghz_scene_rpc.c b/applications/subghz/scenes/subghz_scene_rpc.c
index c6f7df268..652499d05 100644
--- a/applications/subghz/scenes/subghz_scene_rpc.c
+++ b/applications/subghz/scenes/subghz_scene_rpc.c
@@ -1,16 +1,23 @@
#include "../subghz_i.h"
+typedef enum {
+ SubGhzRpcStateIdle,
+ SubGhzRpcStateLoaded,
+} SubGhzRpcState;
+
void subghz_scene_rpc_on_enter(void* context) {
SubGhz* subghz = context;
Popup* popup = subghz->popup;
- popup_set_header(popup, "Sub-GHz", 82, 28, AlignCenter, AlignBottom);
- popup_set_text(popup, "RPC mode", 82, 32, AlignCenter, AlignTop);
+ popup_set_header(popup, "Sub-GHz", 89, 42, AlignCenter, AlignBottom);
+ popup_set_text(popup, "RPC mode", 89, 44, AlignCenter, AlignTop);
- popup_set_icon(popup, 2, 14, &I_Warning_30x23); // TODO: icon
+ popup_set_icon(popup, 0, 12, &I_RFIDDolphinSend_97x61);
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdPopup);
+ scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneRpc, SubGhzRpcStateIdle);
+
notification_message(subghz->notifications, &sequence_display_backlight_on);
}
@@ -18,28 +25,21 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) {
SubGhz* subghz = context;
Popup* popup = subghz->popup;
bool consumed = false;
+ SubGhzRpcState state = scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneRpc);
if(event.type == SceneManagerEventTypeCustom) {
consumed = true;
if(event.event == SubGhzCustomEventSceneExit) {
- if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) {
- subghz_tx_stop(subghz);
- subghz_sleep(subghz);
- }
+ scene_manager_stop(subghz->scene_manager);
view_dispatcher_stop(subghz->view_dispatcher);
rpc_system_app_confirm(subghz->rpc_ctx, RpcAppEventAppExit, true);
} else if(event.event == SubGhzCustomEventSceneRpcSessionClose) {
- rpc_system_app_set_callback(subghz->rpc_ctx, NULL, NULL);
- subghz->rpc_ctx = NULL;
- subghz_blink_stop(subghz);
- if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) {
- subghz_tx_stop(subghz);
- subghz_sleep(subghz);
- }
- view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventSceneExit);
+ scene_manager_stop(subghz->scene_manager);
+ view_dispatcher_stop(subghz->view_dispatcher);
} else if(event.event == SubGhzCustomEventSceneRpcButtonPress) {
bool result = false;
- if(subghz->txrx->txrx_state == SubGhzTxRxStateSleep) {
+ if((subghz->txrx->txrx_state == SubGhzTxRxStateSleep) &&
+ (state == SubGhzRpcStateLoaded)) {
subghz_blink_start(subghz);
result = subghz_tx_start(subghz, subghz->txrx->fff_data);
result = true;
@@ -57,8 +57,10 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) {
} else if(event.event == SubGhzCustomEventSceneRpcLoad) {
bool result = false;
const char* arg = rpc_system_app_get_data(subghz->rpc_ctx);
- if(arg) {
+ if(arg && (state == SubGhzRpcStateIdle)) {
if(subghz_key_load(subghz, arg, false)) {
+ scene_manager_set_scene_state(
+ subghz->scene_manager, SubGhzSceneRpc, SubGhzRpcStateLoaded);
string_set_str(subghz->file_path, arg);
result = true;
string_t file_name;
@@ -70,7 +72,7 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) {
SUBGHZ_MAX_LEN_NAME,
"loaded\n%s",
string_get_cstr(file_name));
- popup_set_text(popup, subghz->file_name_tmp, 82, 32, AlignCenter, AlignTop);
+ popup_set_text(popup, subghz->file_name_tmp, 89, 44, AlignCenter, AlignTop);
string_clear(file_name);
}
@@ -83,6 +85,13 @@ bool subghz_scene_rpc_on_event(void* context, SceneManagerEvent event) {
void subghz_scene_rpc_on_exit(void* context) {
SubGhz* subghz = context;
+
+ if(subghz->txrx->txrx_state == SubGhzTxRxStateTx) {
+ subghz_tx_stop(subghz);
+ subghz_sleep(subghz);
+ subghz_blink_stop(subghz);
+ }
+
Popup* popup = subghz->popup;
popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
diff --git a/applications/subghz/scenes/subghz_scene_show_error_sub.c b/applications/subghz/scenes/subghz_scene_show_error_sub.c
index 697588d0e..74e034323 100644
--- a/applications/subghz/scenes/subghz_scene_show_error_sub.c
+++ b/applications/subghz/scenes/subghz_scene_show_error_sub.c
@@ -11,7 +11,7 @@ void subghz_scene_show_error_sub_on_enter(void* context) {
// Setup view
Popup* popup = subghz->popup;
- popup_set_icon(popup, 72, 14, &I_DolphinFirstStart8_56x51);
+ popup_set_icon(popup, 72, 17, &I_DolphinCommon_56x48);
popup_set_header(popup, string_get_cstr(subghz->error_str), 14, 15, AlignLeft, AlignTop);
popup_set_timeout(popup, 1500);
popup_set_context(popup, subghz);
diff --git a/applications/subghz/scenes/subghz_scene_show_only_rx.c b/applications/subghz/scenes/subghz_scene_show_only_rx.c
index 039540e6f..18608dc5b 100644
--- a/applications/subghz/scenes/subghz_scene_show_only_rx.c
+++ b/applications/subghz/scenes/subghz_scene_show_only_rx.c
@@ -11,9 +11,14 @@ void subghz_scene_show_only_rx_on_enter(void* context) {
// Setup view
Popup* popup = subghz->popup;
- popup_set_icon(popup, 67, 12, &I_DolphinFirstStart7_61x51);
- popup_set_text(
- popup, "This frequency is\noutside of default\nrange", 38, 40, AlignCenter, AlignBottom);
+
+ const char* header_text = "Transmission is blocked";
+ const char* message_text = "This frequency is\noutside of default\nrange";
+
+ popup_set_header(popup, header_text, 63, 3, AlignCenter, AlignTop);
+ popup_set_text(popup, message_text, 0, 17, AlignLeft, AlignTop);
+ popup_set_icon(popup, 72, 17, &I_DolphinCommon_56x48);
+
popup_set_timeout(popup, 1500);
popup_set_context(popup, subghz);
popup_set_callback(popup, subghz_scene_show_only_rx_popup_callback);
diff --git a/applications/subghz/subghz.c b/applications/subghz/subghz.c
index 47af16c0c..fab68fb4d 100644
--- a/applications/subghz/subghz.c
+++ b/applications/subghz/subghz.c
@@ -32,6 +32,8 @@ static void subghz_rpc_command_callback(RpcAppSystemEvent event, void* context)
if(event == RpcAppEventSessionClose) {
view_dispatcher_send_custom_event(
subghz->view_dispatcher, SubGhzCustomEventSceneRpcSessionClose);
+ rpc_system_app_set_callback(subghz->rpc_ctx, NULL, NULL);
+ subghz->rpc_ctx = NULL;
} else if(event == RpcAppEventAppExit) {
view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventSceneExit);
} else if(event == RpcAppEventLoadFile) {
diff --git a/applications/subghz/subghz_i.c b/applications/subghz/subghz_i.c
index 9f3153d69..f78ac39e0 100644
--- a/applications/subghz/subghz_i.c
+++ b/applications/subghz/subghz_i.c
@@ -219,17 +219,13 @@ void subghz_dialog_message_show_only_rx(SubGhz* subghz) {
DialogsApp* dialogs = subghz->dialogs;
DialogMessage* message = dialog_message_alloc();
- dialog_message_set_header(message, "Transmission is blocked", 63, 3, AlignCenter, AlignTop);
+ const char* header_text = "Transmission is blocked";
+ const char* message_text = "Frequency\nis outside of\ndefault range.\nCheck docs.";
- dialog_message_set_text(
- message,
- "Frequency\nis outside of\ndefault range.\nCheck docs.",
- 3,
- 17,
- AlignLeft,
- AlignTop);
+ dialog_message_set_header(message, header_text, 63, 3, AlignCenter, AlignTop);
+ dialog_message_set_text(message, message_text, 0, 17, AlignLeft, AlignTop);
- dialog_message_set_icon(message, &I_DolphinFirstStart8_56x51, 72, 14);
+ dialog_message_set_icon(message, &I_DolphinCommon_56x48, 72, 17);
dialog_message_show(dialogs, message);
dialog_message_free(message);
@@ -296,7 +292,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path, bool show_dialog) {
if(!strcmp(string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) {
//Todo add Custom_preset_module
- //delete peset if it already exists
+ //delete preset if it already exists
subghz_setting_delete_custom_preset(
subghz->setting, string_get_cstr(subghz->txrx->preset->name));
//load custom preset from file
diff --git a/applications/tetris_game/tetris_game.c b/applications/tetris_game/tetris_game.c
index 678c9de31..29b61cd2a 100644
--- a/applications/tetris_game/tetris_game.c
+++ b/applications/tetris_game/tetris_game.c
@@ -373,7 +373,7 @@ int32_t tetris_game_app() {
view_port_input_callback_set(view_port, tetris_game_input_callback, event_queue);
// Open GUI and register view_port
- Gui* gui = furi_record_open("gui");
+ Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
tetris_state->timer =
@@ -460,7 +460,7 @@ int32_t tetris_game_app() {
furi_timer_free(tetris_state->timer);
view_port_enabled_set(view_port, false);
gui_remove_view_port(gui, view_port);
- furi_record_close("gui");
+ furi_record_close(RECORD_GUI);
view_port_free(view_port);
furi_message_queue_free(event_queue);
delete_mutex(&state_mutex);
diff --git a/applications/tictactoe_game/tictactoe_game.c b/applications/tictactoe_game/tictactoe_game.c
index 769eaeb38..b3a0d5c84 100644
--- a/applications/tictactoe_game/tictactoe_game.c
+++ b/applications/tictactoe_game/tictactoe_game.c
@@ -327,7 +327,7 @@ int32_t tictactoe_game_app(void* p) {
tictactoe_state_init(tictactoe_state);
// Open GUI and register view_port
- Gui* gui = furi_record_open("gui");
+ Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
GameEvent event;
@@ -373,7 +373,7 @@ int32_t tictactoe_game_app(void* p) {
furi_timer_free(tictactoe_state->timer);
view_port_enabled_set(view_port, false);
gui_remove_view_port(gui, view_port);
- furi_record_close("gui");
+ furi_record_close(RECORD_GUI);
view_port_free(view_port);
furi_message_queue_free(event_queue);
delete_mutex(&state_mutex);
diff --git a/applications/u2f/u2f.c b/applications/u2f/u2f.c
index 051dca696..767733ce6 100644
--- a/applications/u2f/u2f.c
+++ b/applications/u2f/u2f.c
@@ -4,6 +4,7 @@
#include "u2f_data.h"
#include
#include
+#include // for lfs_tobe32
#include "toolbox/sha256.h"
#include "toolbox/hmac_sha256.h"
@@ -256,6 +257,7 @@ static uint16_t u2f_authenticate(U2fData* U2F, uint8_t* buf) {
uint8_t flags = 0;
uint8_t hash[32];
uint8_t signature[64];
+ uint32_t be_u2f_counter;
if(u2f_data_check(false) == false) {
U2F->ready = false;
@@ -275,11 +277,14 @@ static uint16_t u2f_authenticate(U2fData* U2F, uint8_t* buf) {
}
U2F->user_present = false;
+ // The 4 byte counter is represented in big endian. Increment it before use
+ be_u2f_counter = lfs_tobe32(U2F->counter + 1);
+
// Generate hash
sha256_start(&sha_ctx);
sha256_update(&sha_ctx, req->app_id, 32);
sha256_update(&sha_ctx, &flags, 1);
- sha256_update(&sha_ctx, (uint8_t*)&(U2F->counter), 4);
+ sha256_update(&sha_ctx, (uint8_t*)&(be_u2f_counter), 4);
sha256_update(&sha_ctx, req->challenge, 32);
sha256_finish(&sha_ctx, hash);
@@ -309,12 +314,12 @@ static uint16_t u2f_authenticate(U2fData* U2F, uint8_t* buf) {
uECC_sign(priv_key, hash, 32, signature, U2F->p_curve);
resp->user_present = flags;
- resp->counter = U2F->counter;
+ resp->counter = be_u2f_counter;
uint8_t signature_len = u2f_der_encode_signature(resp->signature, signature);
memcpy(resp->signature + signature_len, state_no_error, 2);
- FURI_LOG_D(TAG, "Counter: %lu", U2F->counter);
U2F->counter++;
+ FURI_LOG_D(TAG, "Counter: %lu", U2F->counter);
u2f_data_cnt_write(U2F->counter);
if(U2F->callback != NULL) U2F->callback(U2fNotifyAuthSuccess, U2F->context);
diff --git a/applications/u2f/u2f_data.c b/applications/u2f/u2f_data.c
index 0419fc7e1..117fbdbe3 100644
--- a/applications/u2f/u2f_data.c
+++ b/applications/u2f/u2f_data.c
@@ -1,5 +1,5 @@
#include
-#include "u2f_hid.h"
+#include "u2f_data.h"
#include
#include
#include
@@ -28,7 +28,8 @@
#define U2F_DEVICE_KEY_VERSION 1
#define U2F_COUNTER_FILE_TYPE "Flipper U2F Counter File"
-#define U2F_COUNTER_VERSION 1
+#define U2F_COUNTER_VERSION 2
+#define U2F_COUNTER_VERSION_OLD 1
#define U2F_COUNTER_CONTROL_VAL 0xAA5500FF
@@ -359,6 +360,7 @@ bool u2f_data_cnt_read(uint32_t* cnt_val) {
furi_assert(cnt_val);
bool state = false;
+ bool old_counter = false;
uint8_t iv[16];
U2fCounterData cnt;
uint8_t cnt_encr[48];
@@ -376,9 +378,16 @@ bool u2f_data_cnt_read(uint32_t* cnt_val) {
FURI_LOG_E(TAG, "Missing or incorrect header");
break;
}
- if(strcmp(string_get_cstr(filetype), U2F_COUNTER_FILE_TYPE) != 0 ||
- version != U2F_COUNTER_VERSION) {
- FURI_LOG_E(TAG, "Type or version mismatch");
+ if(strcmp(string_get_cstr(filetype), U2F_COUNTER_FILE_TYPE) != 0) {
+ FURI_LOG_E(TAG, "Type mismatch");
+ break;
+ }
+ if(version == U2F_COUNTER_VERSION_OLD) {
+ // Counter is from previous U2F app version with endianness bug
+ FURI_LOG_W(TAG, "Counter from old version");
+ old_counter = true;
+ } else if(version != U2F_COUNTER_VERSION) {
+ FURI_LOG_E(TAG, "Version mismatch");
break;
}
if(!flipper_format_read_hex(flipper_format, "IV", iv, 16)) {
@@ -409,6 +418,13 @@ bool u2f_data_cnt_read(uint32_t* cnt_val) {
flipper_format_free(flipper_format);
furi_record_close(RECORD_STORAGE);
string_clear(filetype);
+
+ if(old_counter && state) {
+ // Change counter endianness and rewrite counter file
+ *cnt_val = __REV(cnt.counter);
+ state = u2f_data_cnt_write(*cnt_val);
+ }
+
return state;
}
diff --git a/applications/unit_tests/subghz/subghz_test.c b/applications/unit_tests/subghz/subghz_test.c
index fb3c7a4eb..f91d27234 100644
--- a/applications/unit_tests/subghz/subghz_test.c
+++ b/applications/unit_tests/subghz/subghz_test.c
@@ -13,7 +13,7 @@
#define CAME_ATOMO_DIR_NAME EXT_PATH("subghz/assets/came_atomo")
#define NICE_FLOR_S_DIR_NAME EXT_PATH("subghz/assets/nice_flor_s")
#define TEST_RANDOM_DIR_NAME EXT_PATH("unit_tests/subghz/test_random_raw.sub")
-#define TEST_RANDOM_COUNT_PARSE 158
+#define TEST_RANDOM_COUNT_PARSE 188
#define TEST_TIMEOUT 10000
static SubGhzEnvironment* environment_handler;
@@ -404,6 +404,14 @@ MU_TEST(subghz_decoder_phoenix_v2_test) {
"Test decoder " SUBGHZ_PROTOCOL_PHOENIX_V2_NAME " error\r\n");
}
+MU_TEST(subghz_decoder_honeywell_wdb_test) {
+ mu_assert(
+ subghz_decoder_test(
+ EXT_PATH("unit_tests/subghz/honeywell_wdb_raw.sub"),
+ SUBGHZ_PROTOCOL_HONEYWELL_WDB_NAME),
+ "Test decoder " SUBGHZ_PROTOCOL_HONEYWELL_WDB_NAME " error\r\n");
+}
+
//test encoders
MU_TEST(subghz_encoder_princeton_test) {
mu_assert(
@@ -501,6 +509,12 @@ MU_TEST(subghz_encoder_phoenix_v2_test) {
"Test encoder " SUBGHZ_PROTOCOL_PHOENIX_V2_NAME " error\r\n");
}
+MU_TEST(subghz_encoder_honeywell_wdb_test) {
+ mu_assert(
+ subghz_encoder_test(EXT_PATH("unit_tests/subghz/honeywell_wdb.sub")),
+ "Test encoder " SUBGHZ_PROTOCOL_HONEYWELL_WDB_NAME " error\r\n");
+}
+
MU_TEST(subghz_random_test) {
mu_assert(subghz_decode_random_test(TEST_RANDOM_DIR_NAME), "Random test error\r\n");
}
@@ -537,6 +551,7 @@ MU_TEST_SUITE(subghz) {
MU_RUN_TEST(subghz_decoder_bett_test);
MU_RUN_TEST(subghz_decoder_doitrand_test);
MU_RUN_TEST(subghz_decoder_phoenix_v2_test);
+ MU_RUN_TEST(subghz_decoder_honeywell_wdb_test);
MU_RUN_TEST(subghz_encoder_princeton_test);
MU_RUN_TEST(subghz_encoder_came_test);
@@ -554,6 +569,7 @@ MU_TEST_SUITE(subghz) {
MU_RUN_TEST(subghz_encoder_bett_test);
MU_RUN_TEST(subghz_encoder_doitrand_test);
MU_RUN_TEST(subghz_encoder_phoenix_v2_test);
+ MU_RUN_TEST(subghz_encoder_honeywell_wdb_test);
MU_RUN_TEST(subghz_random_test);
subghz_test_deinit();
diff --git a/applications/wav_player/wav_player.c b/applications/wav_player/wav_player.c
index dc8069fb0..2f9c58cd7 100644
--- a/applications/wav_player/wav_player.c
+++ b/applications/wav_player/wav_player.c
@@ -96,7 +96,7 @@ static WavPlayerApp* app_alloc() {
WavPlayerApp* app = malloc(sizeof(WavPlayerApp));
app->samples_count_half = 1024 * 4;
app->samples_count = app->samples_count_half * 2;
- app->storage = furi_record_open("storage");
+ app->storage = furi_record_open(RECORD_STORAGE);
app->stream = file_stream_alloc(app->storage);
app->parser = wav_parser_alloc();
app->sample_buffer = malloc(sizeof(uint16_t) * app->samples_count);
@@ -106,7 +106,7 @@ static WavPlayerApp* app_alloc() {
app->volume = 10.0f;
app->play = true;
- app->gui = furi_record_open("gui");
+ app->gui = furi_record_open(RECORD_GUI);
app->view_dispatcher = view_dispatcher_alloc();
app->view = wav_player_view_alloc();
@@ -124,14 +124,14 @@ static void app_free(WavPlayerApp* app) {
view_dispatcher_remove_view(app->view_dispatcher, 0);
view_dispatcher_free(app->view_dispatcher);
wav_player_view_free(app->view);
- furi_record_close("gui");
+ furi_record_close(RECORD_GUI);
furi_message_queue_free(app->queue);
free(app->tmp_buffer);
free(app->sample_buffer);
wav_parser_free(app->parser);
stream_free(app->stream);
- furi_record_close("storage");
+ furi_record_close(RECORD_STORAGE);
notification_message(app->notification, &sequence_display_backlight_enforce_auto);
furi_record_close("notification");
@@ -296,11 +296,11 @@ int32_t wav_player_app(void* p) {
UNUSED(p);
WavPlayerApp* app = app_alloc();
- Storage* storage = furi_record_open("storage");
+ Storage* storage = furi_record_open(RECORD_STORAGE);
if(!storage_simply_mkdir(storage, WAVPLAYER_FOLDER)) {
FURI_LOG_E(TAG, "Could not create folder %s", WAVPLAYER_FOLDER);
}
- furi_record_close("storage");
+ furi_record_close(RECORD_STORAGE);
app_run(app);
app_free(app);
diff --git a/applications/wifi_marauder_companion/scenes/wifi_marauder_scene_console_output.c b/applications/wifi_marauder_companion/scenes/wifi_marauder_scene_console_output.c
index 2aba66306..be6c25fd4 100644
--- a/applications/wifi_marauder_companion/scenes/wifi_marauder_scene_console_output.c
+++ b/applications/wifi_marauder_companion/scenes/wifi_marauder_scene_console_output.c
@@ -8,7 +8,7 @@ void wifi_marauder_console_output_handle_rx_data_cb(uint8_t* buf, size_t len, vo
app->text_box_store_strlen += len;
if(app->text_box_store_strlen >= WIFI_MARAUDER_TEXT_BOX_STORE_SIZE - 1) {
string_right(app->text_box_store, app->text_box_store_strlen / 2);
- app->text_box_store_strlen = string_size(app->text_box_store);
+ app->text_box_store_strlen = string_size(app->text_box_store) + len;
}
// Null-terminate buf and append to text box store
@@ -32,10 +32,23 @@ void wifi_marauder_scene_console_output_on_enter(void* context) {
if(app->is_command) {
string_reset(app->text_box_store);
app->text_box_store_strlen = 0;
- } else { // "View Log" menu action
- text_box_set_text(app->text_box, string_get_cstr(app->text_box_store));
+ if(0 == strncmp("help", app->selected_tx_string, strlen("help"))) {
+ const char* help_msg =
+ "For app support/feedback,\nreach out to me:\n@cococode#6011 (discord)\n0xchocolate (github)\n";
+ string_cat_str(app->text_box_store, help_msg);
+ app->text_box_store_strlen += strlen(help_msg);
+ }
+
+ if(app->show_stopscan_tip) {
+ const char* help_msg = "Press BACK to send stopscan\n";
+ string_cat_str(app->text_box_store, help_msg);
+ app->text_box_store_strlen += strlen(help_msg);
+ }
}
+ // Set starting text - for "View Log", this will just be what was already in the text box store
+ text_box_set_text(app->text_box, string_get_cstr(app->text_box_store));
+
scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneConsoleOutput, 0);
view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewConsoleOutput);
diff --git a/applications/wifi_marauder_companion/scenes/wifi_marauder_scene_start.c b/applications/wifi_marauder_companion/scenes/wifi_marauder_scene_start.c
index 03d463462..b5072417b 100644
--- a/applications/wifi_marauder_companion/scenes/wifi_marauder_scene_start.c
+++ b/applications/wifi_marauder_companion/scenes/wifi_marauder_scene_start.c
@@ -1,67 +1,138 @@
#include "../wifi_marauder_app_i.h"
-#define NUM_MENU_ITEMS (29)
-
// For each command, define whether additional arguments are needed
// (enabling text input to fill them out), and whether the console
// text box should focus at the start of the output or the end
-#define INPUT_ARGS (true)
-#define NO_ARGS (false)
-#define FOCUS_CONSOLE_START (true)
-#define FOCUS_CONSOLE_END (false)
-struct WifiMarauderItem {
- const char* item_string;
- bool needs_keyboard;
- bool focus_console_start;
-};
+typedef enum { NO_ARGS = 0, INPUT_ARGS, TOGGLE_ARGS } InputArgs;
-const struct WifiMarauderItem items[NUM_MENU_ITEMS] = {
- {"View Log (start)", NO_ARGS, FOCUS_CONSOLE_START},
- {"View Log (end)", NO_ARGS, FOCUS_CONSOLE_END},
- {"attack -t beacon -l", NO_ARGS, FOCUS_CONSOLE_END},
- {"attack -t beacon -r", NO_ARGS, FOCUS_CONSOLE_END},
- {"attack -t beacon -a", NO_ARGS, FOCUS_CONSOLE_END},
- {"attack -t deauth", NO_ARGS, FOCUS_CONSOLE_END},
- {"attack -t probe", NO_ARGS, FOCUS_CONSOLE_END},
- {"attack -t rickroll", NO_ARGS, FOCUS_CONSOLE_END},
- {"channel", NO_ARGS, FOCUS_CONSOLE_END},
- {"channel -s", INPUT_ARGS, FOCUS_CONSOLE_END},
- {"clearlist -a", NO_ARGS, FOCUS_CONSOLE_END},
- {"clearlist -s", NO_ARGS, FOCUS_CONSOLE_END},
- {"help", NO_ARGS, FOCUS_CONSOLE_START},
- {"list -a", NO_ARGS, FOCUS_CONSOLE_START},
- {"list -s", NO_ARGS, FOCUS_CONSOLE_START},
- {"reboot", NO_ARGS, FOCUS_CONSOLE_END},
- {"scanap", NO_ARGS, FOCUS_CONSOLE_END},
- {"select -a", INPUT_ARGS, FOCUS_CONSOLE_END},
- {"select -s", INPUT_ARGS, FOCUS_CONSOLE_END},
- {"sniffbeacon", NO_ARGS, FOCUS_CONSOLE_END},
- {"sniffdeauth", NO_ARGS, FOCUS_CONSOLE_END},
- {"sniffesp", NO_ARGS, FOCUS_CONSOLE_END},
- {"sniffpmkid", NO_ARGS, FOCUS_CONSOLE_END},
- {"sniffpmkid -c", INPUT_ARGS, FOCUS_CONSOLE_END},
- {"sniffpwn", NO_ARGS, FOCUS_CONSOLE_END},
- {"ssid -a -g", INPUT_ARGS, FOCUS_CONSOLE_END},
- {"ssid -a -n", INPUT_ARGS, FOCUS_CONSOLE_END},
- {"ssid -r", INPUT_ARGS, FOCUS_CONSOLE_END},
- {"update -w", NO_ARGS, FOCUS_CONSOLE_END},
+typedef enum { FOCUS_CONSOLE_END = 0, FOCUS_CONSOLE_START, FOCUS_CONSOLE_TOGGLE } FocusConsole;
+
+#define SHOW_STOPSCAN_TIP (true)
+#define NO_TIP (false)
+
+#define MAX_OPTIONS (6)
+typedef struct {
+ const char* item_string;
+ const char* options_menu[MAX_OPTIONS];
+ int num_options_menu;
+ const char* actual_commands[MAX_OPTIONS];
+ InputArgs needs_keyboard;
+ FocusConsole focus_console;
+ bool show_stopscan_tip;
+} WifiMarauderItem;
+
+// NUM_MENU_ITEMS defined in wifi_marauder_app_i.h - if you add an entry here, increment it!
+const WifiMarauderItem items[NUM_MENU_ITEMS] = {
+ {"View Log from", {"start", "end"}, 2, {"", ""}, NO_ARGS, FOCUS_CONSOLE_TOGGLE, NO_TIP},
+ {"Scan AP", {""}, 1, {"scanap"}, NO_ARGS, FOCUS_CONSOLE_END, SHOW_STOPSCAN_TIP},
+ {"SSID",
+ {"add random", "add name", "remove"},
+ 3,
+ {"ssid -a -g", "ssid -a -n", "ssid -r"},
+ INPUT_ARGS,
+ FOCUS_CONSOLE_START,
+ NO_TIP},
+ {"List", {"ap", "ssid"}, 2, {"list -a", "list -s"}, NO_ARGS, FOCUS_CONSOLE_START, NO_TIP},
+ {"Select", {"ap", "ssid"}, 2, {"select -a", "select -s"}, INPUT_ARGS, FOCUS_CONSOLE_END, NO_TIP},
+ {"Clear List",
+ {"ap", "ssid"},
+ 2,
+ {"clearlist -a", "clearlist -s"},
+ NO_ARGS,
+ FOCUS_CONSOLE_END,
+ NO_TIP},
+ {"Attack",
+ {"deauth", "probe", "rickroll"},
+ 3,
+ {"attack -t deauth", "attack -t probe", "attack -t rickroll"},
+ NO_ARGS,
+ FOCUS_CONSOLE_END,
+ SHOW_STOPSCAN_TIP},
+ {"Beacon Spam",
+ {"ap list", "ssid list", "random"},
+ 3,
+ {"attack -t beacon -a", "attack -t beacon -l", "attack -t beacon -r"},
+ NO_ARGS,
+ FOCUS_CONSOLE_END,
+ SHOW_STOPSCAN_TIP},
+ {"Sniff",
+ {"beacon", "deauth", "esp", "pmkid", "pwn"},
+ 5,
+ {"sniffbeacon", "sniffdeauth", "sniffesp", "sniffpmkid", "sniffpwn"},
+ NO_ARGS,
+ FOCUS_CONSOLE_END,
+ SHOW_STOPSCAN_TIP},
+ {"Sniff PMKID on channel",
+ {""},
+ 1,
+ {"sniffpmkid -c"},
+ INPUT_ARGS,
+ FOCUS_CONSOLE_END,
+ SHOW_STOPSCAN_TIP},
+ {"Channel",
+ {"get", "set"},
+ 2,
+ {"channel", "channel -s"},
+ TOGGLE_ARGS,
+ FOCUS_CONSOLE_END,
+ NO_TIP},
+ {"Settings",
+ {"display", "restore", "ForcePMKID", "ForceProbe", "SavePCAP", "other"},
+ 6,
+ {"settings",
+ "settings -r",
+ "settings -s ForcePMKID enable",
+ "settings -s ForceProbe enable",
+ "settings -s SavePCAP enable",
+ "settings -s"},
+ TOGGLE_ARGS,
+ FOCUS_CONSOLE_START,
+ NO_TIP},
+ {"Update", {""}, 1, {"update -w"}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP},
+ {"Reboot", {""}, 1, {"reboot"}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP},
+ {"Help", {""}, 1, {"help"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
};
static void wifi_marauder_scene_start_var_list_enter_callback(void* context, uint32_t index) {
furi_assert(context);
WifiMarauderApp* app = context;
- app->selected_tx_string = items[index].item_string;
- app->is_command = (2 <= index);
+
+ furi_assert(index < NUM_MENU_ITEMS);
+ const WifiMarauderItem* item = &items[index];
+
+ const int selected_option_index = app->selected_option_index[index];
+ furi_assert(selected_option_index < item->num_options_menu);
+ app->selected_tx_string = item->actual_commands[selected_option_index];
+ app->is_command = (1 <= index);
app->is_custom_tx_string = false;
app->selected_menu_index = index;
- app->focus_console_start = items[index].focus_console_start;
- if(items[index].needs_keyboard) {
+ app->focus_console_start = (item->focus_console == FOCUS_CONSOLE_TOGGLE) ?
+ (selected_option_index == 0) :
+ item->focus_console;
+ app->show_stopscan_tip = item->show_stopscan_tip;
+
+ bool needs_keyboard = (item->needs_keyboard == TOGGLE_ARGS) ? (selected_option_index != 0) :
+ item->needs_keyboard;
+ if(needs_keyboard) {
view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventStartKeyboard);
} else {
view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventStartConsole);
}
}
+static void wifi_marauder_scene_start_var_list_change_callback(VariableItem* item) {
+ furi_assert(item);
+
+ WifiMarauderApp* app = variable_item_get_context(item);
+ furi_assert(app);
+
+ const WifiMarauderItem* menu_item = &items[app->selected_menu_index];
+ uint8_t item_index = variable_item_get_current_value_index(item);
+ furi_assert(item_index < menu_item->num_options_menu);
+ variable_item_set_current_value_text(item, menu_item->options_menu[item_index]);
+ app->selected_option_index[app->selected_menu_index] = item_index;
+}
+
void wifi_marauder_scene_start_on_enter(void* context) {
WifiMarauderApp* app = context;
VariableItemList* var_item_list = app->var_item_list;
@@ -69,9 +140,17 @@ void wifi_marauder_scene_start_on_enter(void* context) {
variable_item_list_set_enter_callback(
var_item_list, wifi_marauder_scene_start_var_list_enter_callback, app);
- // TODO: organize menu
+ VariableItem* item;
for(int i = 0; i < NUM_MENU_ITEMS; ++i) {
- variable_item_list_add(var_item_list, items[i].item_string, 0, NULL, NULL);
+ item = variable_item_list_add(
+ var_item_list,
+ items[i].item_string,
+ items[i].num_options_menu,
+ wifi_marauder_scene_start_var_list_change_callback,
+ app);
+ variable_item_set_current_value_index(item, app->selected_option_index[i]);
+ variable_item_set_current_value_text(
+ item, items[i].options_menu[app->selected_option_index[i]]);
}
variable_item_list_set_selected_item(
@@ -96,6 +175,9 @@ bool wifi_marauder_scene_start_on_event(void* context, SceneManagerEvent event)
scene_manager_next_scene(app->scene_manager, WifiMarauderAppViewConsoleOutput);
}
consumed = true;
+ } else if(event.type == SceneManagerEventTypeTick) {
+ app->selected_menu_index = variable_item_list_get_selected_item_index(app->var_item_list);
+ consumed = true;
}
return consumed;
diff --git a/applications/wifi_marauder_companion/scenes/wifi_marauder_scene_text_input.c b/applications/wifi_marauder_companion/scenes/wifi_marauder_scene_text_input.c
index d4e7020d7..061e9c5fe 100644
--- a/applications/wifi_marauder_companion/scenes/wifi_marauder_scene_text_input.c
+++ b/applications/wifi_marauder_companion/scenes/wifi_marauder_scene_text_input.c
@@ -24,7 +24,20 @@ void wifi_marauder_scene_text_input_on_enter(void* context) {
// Setup view
TextInput* text_input = app->text_input;
- text_input_set_header_text(text_input, "Add command arguments");
+ // Add help message to header
+ if(0 == strncmp("ssid -a -g", app->selected_tx_string, strlen("ssid -a -g"))) {
+ text_input_set_header_text(text_input, "Enter # SSIDs to generate");
+ } else if(0 == strncmp("ssid -a -n", app->selected_tx_string, strlen("ssid -a -n"))) {
+ text_input_set_header_text(text_input, "Enter SSID name to add");
+ } else if(0 == strncmp("ssid -r", app->selected_tx_string, strlen("ssid -r"))) {
+ text_input_set_header_text(text_input, "Remove target from SSID list");
+ } else if(0 == strncmp("select -a", app->selected_tx_string, strlen("select -a"))) {
+ text_input_set_header_text(text_input, "Add target from AP list");
+ } else if(0 == strncmp("select -s", app->selected_tx_string, strlen("select -s"))) {
+ text_input_set_header_text(text_input, "Add target from SSID list");
+ } else {
+ text_input_set_header_text(text_input, "Add command arguments");
+ }
text_input_set_result_callback(
text_input,
wifi_marauder_scene_text_input_callback,
diff --git a/applications/wifi_marauder_companion/wifi_marauder_app.c b/applications/wifi_marauder_companion/wifi_marauder_app.c
index 76a802d8a..59ca9edbe 100644
--- a/applications/wifi_marauder_companion/wifi_marauder_app.c
+++ b/applications/wifi_marauder_companion/wifi_marauder_app.c
@@ -24,7 +24,7 @@ static void wifi_marauder_app_tick_event_callback(void* context) {
WifiMarauderApp* wifi_marauder_app_alloc() {
WifiMarauderApp* app = malloc(sizeof(WifiMarauderApp));
- app->gui = furi_record_open("gui");
+ app->gui = furi_record_open(RECORD_GUI);
app->view_dispatcher = view_dispatcher_alloc();
app->scene_manager = scene_manager_alloc(&wifi_marauder_scene_handlers, app);
@@ -46,6 +46,10 @@ WifiMarauderApp* wifi_marauder_app_alloc() {
WifiMarauderAppViewVarItemList,
variable_item_list_get_view(app->var_item_list));
+ for(int i = 0; i < NUM_MENU_ITEMS; ++i) {
+ app->selected_option_index[i] = 0;
+ }
+
app->text_box = text_box_alloc();
view_dispatcher_add_view(
app->view_dispatcher, WifiMarauderAppViewConsoleOutput, text_box_get_view(app->text_box));
@@ -79,7 +83,7 @@ void wifi_marauder_app_free(WifiMarauderApp* app) {
wifi_marauder_uart_free(app->uart);
// Close records
- furi_record_close("gui");
+ furi_record_close(RECORD_GUI);
free(app);
}
diff --git a/applications/wifi_marauder_companion/wifi_marauder_app_i.h b/applications/wifi_marauder_companion/wifi_marauder_app_i.h
index b5832c914..a438e7fad 100644
--- a/applications/wifi_marauder_companion/wifi_marauder_app_i.h
+++ b/applications/wifi_marauder_companion/wifi_marauder_app_i.h
@@ -12,6 +12,8 @@
#include
#include
+#define NUM_MENU_ITEMS (15)
+
#define WIFI_MARAUDER_TEXT_BOX_STORE_SIZE (4096)
#define WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE (512)
@@ -31,10 +33,12 @@ struct WifiMarauderApp {
WifiMarauderUart* uart;
int selected_menu_index;
+ int selected_option_index[NUM_MENU_ITEMS];
const char* selected_tx_string;
bool is_command;
bool is_custom_tx_string;
bool focus_console_start;
+ bool show_stopscan_tip;
};
// Supported commands:
diff --git a/applications/wifi_scanner/wifi_scanner.c b/applications/wifi_scanner/wifi_scanner.c
index 8421c9ea4..118bc5005 100644
--- a/applications/wifi_scanner/wifi_scanner.c
+++ b/applications/wifi_scanner/wifi_scanner.c
@@ -685,7 +685,7 @@ int32_t wifi_scanner_app(void* p) {
view_port_input_callback_set(view_port, wifi_module_input_callback, event_queue);
// Open GUI and register view_port
- Gui* gui = furi_record_open("gui");
+ Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
//notification_message(app->notification, &sequence_set_only_blue_255);
@@ -831,7 +831,7 @@ int32_t wifi_scanner_app(void* p) {
gui_remove_view_port(gui, view_port);
// Close gui record
- furi_record_close("gui");
+ furi_record_close(RECORD_GUI);
furi_record_close("notification");
app->m_gui = NULL;
diff --git a/assets/icons/Dolphin/DolphinCommon_56x48.png b/assets/icons/Dolphin/DolphinCommon_56x48.png
new file mode 100644
index 000000000..089aaed83
Binary files /dev/null and b/assets/icons/Dolphin/DolphinCommon_56x48.png differ
diff --git a/assets/icons/Dolphin/DolphinFirstStart7_61x51.png b/assets/icons/Dolphin/DolphinFirstStart7_61x51.png
deleted file mode 100644
index a6dd02d26..000000000
Binary files a/assets/icons/Dolphin/DolphinFirstStart7_61x51.png and /dev/null differ
diff --git a/assets/icons/Dolphin/DolphinFirstStart8_56x51.png b/assets/icons/Dolphin/DolphinFirstStart8_56x51.png
deleted file mode 100644
index 36009998c..000000000
Binary files a/assets/icons/Dolphin/DolphinFirstStart8_56x51.png and /dev/null differ
diff --git a/assets/icons/NFC/Keychain.png b/assets/icons/NFC/Keychain.png
new file mode 100644
index 000000000..7ba1b11da
Binary files /dev/null and b/assets/icons/NFC/Keychain.png differ
diff --git a/assets/protobuf b/assets/protobuf
index cc5918dc4..6727eaf28 160000
--- a/assets/protobuf
+++ b/assets/protobuf
@@ -1 +1 @@
-Subproject commit cc5918dc488ac3617012ce5377114e086b447324
+Subproject commit 6727eaf287db077dcd28719cd764f5804712223e
diff --git a/assets/resources/Manifest b/assets/resources/Manifest
index 0f62b1ae9..adac70b34 100644
--- a/assets/resources/Manifest
+++ b/assets/resources/Manifest
@@ -1,5 +1,5 @@
V:0
-T:1660152040
+T:1660773536
D:badusb
D:dolphin
D:infrared
@@ -10,7 +10,7 @@ D:u2f
D:unirf
D:badusb/layouts
F:0e41ba26498b7511d7c9e6e6b5e3b149:1592:badusb/demo_macos.txt
-F:e538ad2ce5a06ec45e1b5b24824901b1:1552:badusb/demo_windows.txt
+F:46a332993ca94b9aa692030ebaa19c70:1552:badusb/demo_windows.txt
F:1139810f61ec7f8c8fe0398d92578b31:256:badusb/layouts/da-DA.kl
F:13504463372b269bd102c68725921d90:256:badusb/layouts/de-CH.kl
F:f392e25a23f50691b5a37e67845dec76:256:badusb/layouts/de-DE.kl
@@ -241,22 +241,22 @@ F:33b8fde22f34ef556b64b77164bc19b0:578:dolphin/L3_Lab_research_128x54/frame_8.bm
F:f267f0654781049ca323b11bb4375519:581:dolphin/L3_Lab_research_128x54/frame_9.bm
F:41106c0cbc5144f151b2b2d3daaa0527:727:dolphin/L3_Lab_research_128x54/meta.txt
D:infrared/assets
-F:0620df2adc5e12f2a9d9c3ac29826ce3:60950:infrared/assets/ac.ir
-F:19f64b475c0f07b11fe6745fae540956:25521:infrared/assets/audio.ir
-F:291a966df726aee2164a4f1068eaf8c5:130988:infrared/assets/tv.ir
+F:cedef6d481ec8a10072168bfe82b9ec4:60995:infrared/assets/ac.ir
+F:92f0d9326b08834472e04b4748eb19b3:47287:infrared/assets/audio.ir
+F:005cd139f858369893c0008f7abbad43:127677:infrared/assets/tv.ir
F:a157a80f5a668700403d870c23b9567d:470:music_player/Marble_Machine.fmf
D:nfc/assets
F:81dc04c7b181f94b644079a71476dff4:4742:nfc/assets/aid.nfc
F:86efbebdf41bb6bf15cc51ef88f069d5:2565:nfc/assets/country_code.nfc
F:41b4f08774249014cb8d3dffa5f5c07d:1757:nfc/assets/currency_code.nfc
-F:12674515290ad9edcabc82f7695350f8:50737:nfc/assets/mf_classic_dict.nfc
+F:5f57e2ecfc850efb74c7d2677eb75a2e:51832:nfc/assets/mf_classic_dict.nfc
D:subghz/assets
F:dda1ef895b8a25fde57c874feaaef997:650:subghz/assets/came_atomo
F:50cf77ba8b935ee6cb3b6f111cf2d93d:286:subghz/assets/dangerous_settings
F:111d2b8df83e27fd889fc5e270297865:3231:subghz/assets/keeloq_mfcodes
F:bb48d7d7db4f6e849436d0e1a9b7a1a7:633:subghz/assets/keeloq_mfcodes_user_example
F:653bd8d349055a41e1152e557d4a52d3:202:subghz/assets/nice_flor_s
-F:470919d764538023a7f73ebae2853797:2106:subghz/assets/setting_user
+F:9f7dea8ec70b2ce34eb57f009bd62033:2795:subghz/assets/setting_user
D:u2f/assets
F:7e11e688e39034bbb9d88410044795e1:365:u2f/assets/cert.der
F:f60b88c20ed479ed9684e249f7134618:264:u2f/assets/cert_key.u2f
diff --git a/assets/resources/badusb/demo_windows.txt b/assets/resources/badusb/demo_windows.txt
index 013e99e21..df4353510 100644
--- a/assets/resources/badusb/demo_windows.txt
+++ b/assets/resources/badusb/demo_windows.txt
@@ -13,7 +13,7 @@ STRING Hello World!
ENTER
DEFAULT_DELAY 50
-REM Copy-Paste previuos string
+REM Copy-Paste previous string
UP
HOME
SHIFT DOWN
diff --git a/assets/resources/infrared/assets/ac.ir b/assets/resources/infrared/assets/ac.ir
index 2ff00a8fb..fece63b33 100644
--- a/assets/resources/infrared/assets/ac.ir
+++ b/assets/resources/infrared/assets/ac.ir
@@ -1,8 +1,10 @@
Filetype: IR signals file
Version: 1
#
-# Universal AC IR codes - Brute force updated by jaroslavmraz and fixed by MX
-# BETA version
+# Universal AC IR codes - Brute force updated by jaroslavmraz
+# Fixes and tweaks provided by MX (MasterX)
+#
+# BETA version - Aug 14, 2022
#
# Old SAMSUNG AC
#
diff --git a/assets/resources/infrared/assets/audio.ir b/assets/resources/infrared/assets/audio.ir
index f57d8e185..3d4621871 100644
--- a/assets/resources/infrared/assets/audio.ir
+++ b/assets/resources/infrared/assets/audio.ir
@@ -5,8 +5,11 @@ Version: 1
# from https://github.com/UberGuidoZ/Flipper-IRDB
# Some Buttons was labeled PowerToggle,Pwr, Sleep or Off. These was assumed to be POWER functions.
# While Care was taken to remove all possible duplicates, some may still be lurking.
+#####################################################
+# HUGE thank you to Amec0e for continued maintenance!
+#####################################################
#
-# Last Updated: 10th August 2022
+# Updated 15th August 2022
#
# | SPEAKERS |
#
@@ -24,6 +27,18 @@ protocol: NECext
address: 00 FD 00 00
command: 03 FC 00 00
#
+name: VOL+
+type: parsed
+protocol: NECext
+address: 00 FD 00 00
+command: 09 F6 00 00
+#
+name: VOL-
+type: parsed
+protocol: NECext
+address: 00 FD 00 00
+command: 07 F8 00 00
+#
# BOSE
#
name: POWER
@@ -50,6 +65,42 @@ frequency: 38000
duty_cycle: 0.330000
data: 1010 1479 517 1474 512 509 484 512 491 505 488 507 486 510 483 512 491 505 488 508 485 1505 491 1474 512 1478 508 1483 513 1477 509 1482 514 1475 511 50713 1005 1483 513 1475 511 511 482 513 490 505 488 507 486 483 510 511 482 487 516 505 488 1501 485 1478 508 1483 513 1476 510 1479 507 1483 513 1474 512 50707 1012 1501 485 1479 506 513 490 505 488 507 486 509 484 511 482 487 516 505 488 508 485 1504 482 1482 514 1476 592 1396 590 1400 513 1476 510 1478 508 50715 1015 1473 513 1476 510 484 508 513 490 504 489 480 513 508 485 483 510 511 482 488 515 1473 513 1477 509 1480 516 1474 512 1477 591 1397 516 1472 514
#
+name: VOL+
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 1041 1462 538 1462 538 485 515 481 519 478 512 484 516 1458 542 1458 542 1459 541 481 519 1481 519 1455 545 1482 518 1456 544 479 511 486 514 474 516 50532 1039 1464 536 1490 510 487 513 483 517 480 510 486 514 1460 540 1486 514 1460 540 483 517 1457 543 1484 516 1458 542 1458 542 481 519 477 513 476 513 50534 1036 1467 543 1457 543 480 509 460 540 483 517 479 511 1463 537 1463 537 1464 536 486 514 1487 513 1461 539 1461 539 1462 538 484 516 481 519 469 510
+#
+name: VOL-
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 1042 1461 539 457 543 1458 542 1458 542 1458 542 1458 542 454 536 461 539 457 543 1457 543 453 537 460 540 456 544 452 538 1463 537 1463 537 1456 544 50530 1065 1438 572 424 566 1434 566 1435 565 1435 565 1436 544 452 537 459 572 424 545 1456 544 451 539 458 542 454 536 460 540 1461 539 1461 539 1454 536 50538 1036 1467 543 452 537 1464 536 1464 536 1464 536 1465 545 450 540 456 544 452 537 1464 536 460 540 455 545 452 538 458 542 1459 541 1460 540 1452 538
+#
+name: VOL+
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 1044 1456 544 455 545 455 534 1464 536 1462 538 1460 540 1458 542 1456 544 1455 545 1453 537 1461 539 460 540 459 541 459 561 437 542 457 543 456 544 50915 1016 1483 517 482 518 482 518 1481 509 1489 511 1487 513 1486 514 1485 515 1483 517 1482 508 1490 510 489 511 488 512 487 513 487 513 486 514 485 515 50956 1047 1452 538 462 538 462 538 1461 539 1460 540 1458 542 1457 543 1456 544 1454 546 1453 547 1451 539 461 539 460 540 460 540 459 541 459 541 457 543
+#
+name: VOL-
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 1017 1484 516 1482 518 481 519 1480 510 1489 511 1487 513 1486 514 1485 515 1483 517 482 518 1480 510 490 510 489 511 489 511 488 512 488 512 486 514 50956 1015 1486 514 1484 516 484 516 1483 517 1482 518 1480 510 1489 511 1488 512 1486 514 486 514 1485 515 484 516 484 516 483 517 483 517 482 518 481 509 50960 1011 1488 512 1486 514 486 514 1485 515 1483 517 1482 518 1480 510 1488 512 1486 514 486 514 1484 516 483 517 483 517 482 518 481 519 481 508 489 511 50961 1040 1461 539 1459 541 459 541 1458 542 1456 544 1455 545 1454 546 1452 538 1460 540 460 540 1458 542 457 543 456 544 456 544 455 545 455 545 453 547
+#
+name: VOL+
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 1006 1485 511 1479 517 1473 513 509 484 511 482 514 489 506 487 508 485 511 482 513 490 505 488 1477 509 1481 515 1475 511 1480 516 1474 512 1477 509 50734 1007 1483 513 1477 509 1482 514 507 486 509 484 511 492 503 490 506 487 508 485 510 483 513 490 1474 512 1479 517 1473 513 1477 509 1481 515 1474 512 50729 1012 1477 509 1481 515 1474 512 509 484 512 491 504 489 506 487 508 485 511 482 513 490 506 487 1477 509 1481 515 1475 511 1479 517 1473 513 1476 510
+#
+name: VOL-
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 1012 1503 483 514 489 1475 511 483 510 486 517 478 515 481 512 483 510 486 517 1473 513 508 485 1480 516 1475 511 1479 507 1483 513 1477 509 1480 588 50646 1012 1476 510 512 491 1473 513 508 485 485 508 488 515 480 513 482 511 512 481 1482 514 482 511 1480 516 1473 513 1478 508 1482 514 1476 510 1479 590 50651 1007 1507 489 507 485 1478 508 514 489 506 487 509 484 485 508 488 515 506 487 1503 483 513 490 1474 512 1478 508 1483 513 1477 509 1481 515 1473 513 50721 1009 1505 491 478 515 1475 511 510 483 486 517 478 515 507 486 483 510 512 491 1472 514 508 485 1505 491 1473 513 1477 509 1481 587 1403 510 1478 508 50733 1008 1506 490 479 514 1477 509 512 481 514 489 506 487 508 485 484 509 513 490 1473 513 509 483 1481 515 1474 512 1479 507 1482 514 1476 510 1478 590 50642 1006 1508 488 508 485 1478 508 487 516 479 514 481 512 510 483 486 517 504 489 1474 512 510 483 1482 514 1475 511 1479 507 1483 513 1477 509 1480 516
+#
# Craig
#
name: POWER
@@ -64,6 +115,30 @@ protocol: NEC
address: 20 00 00 00
command: 1F 00 00 00
#
+name: VOL+
+type: parsed
+protocol: NEC
+address: 20 00 00 00
+command: 0E 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: NEC
+address: 20 00 00 00
+command: 1A 00 00 00
+#
+name: VOL+
+type: parsed
+protocol: NEC
+address: 20 00 00 00
+command: 02 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: NEC
+address: 20 00 00 00
+command: 05 00 00 00
+#
name: POWER
type: parsed
protocol: NEC
@@ -88,6 +163,30 @@ protocol: NEC
address: 00 00 00 00
command: 1E 00 00 00
#
+name: VOL+
+type: parsed
+protocol: NEC
+address: 00 00 00 00
+command: 03 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: NEC
+address: 00 00 00 00
+command: 01 00 00 00
+#
+name: VOL+
+type: parsed
+protocol: NEC
+address: 00 00 00 00
+command: 1F 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: NEC
+address: 00 00 00 00
+command: 09 00 00 00
+#
# EDIFIER
#
name: POWER
@@ -113,9 +212,79 @@ type: parsed
protocol: NECext
address: 78 0E 00 00
command: 09 F6 00 00
+#
+name: VOL+
+type: parsed
+protocol: NECext
+address: 78 0E 00 00
+command: 01 FE 00 00
+#
+name: VOL-
+type: parsed
+protocol: NECext
+address: 78 0E 00 00
+command: 02 FD 00 00
+#
+# GENEVA
+#
+name: VOL-
+type: parsed
+protocol: NEC
+address: 00 00 00 00
+command: 06 00 00 00
+#
+# KLIPSCH
+#
+name: POWER
+type: parsed
+protocol: NEC
+address: 02 00 00 00
+command: 0A 00 00 00
+#
+name: MUTE
+type: parsed
+protocol: NEC
+address: 02 00 00 00
+command: 0D 00 00 00
+#
+name: VOL+
+type: parsed
+protocol: NEC
+address: 02 00 00 00
+command: 1C 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: NEC
+address: 02 00 00 00
+command: 07 00 00 00
#
# JBL
-#
+#
+name: VOL+
+type: parsed
+protocol: NEC
+address: 00 00 00 00
+command: 14 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: NEC
+address: 00 00 00 00
+command: 08 00 00 00
+#
+name: VOL+
+type: parsed
+protocol: NECext
+address: 86 FF 00 00
+command: 14 EB 00 00
+#
+name: VOL-
+type: parsed
+protocol: NECext
+address: 86 FF 00 00
+command: 13 EC 00 00
+#
name: POWER
type: parsed
protocol: NECext
@@ -148,6 +317,18 @@ command: 19 E6 00 00
#
# JVC
#
+name: VOL+
+type: parsed
+protocol: NECext
+address: 02 BD 00 00
+command: 26 D9 00 00
+#
+name: VOL-
+type: parsed
+protocol: NECext
+address: 02 BD 00 00
+command: 28 D7 00 00
+#
name: POWER
type: parsed
protocol: NECext
@@ -161,12 +342,6 @@ address: 02 BD 00 00
command: AD 52 00 00
#
# SONY
-#
-name: POWER
-type: parsed
-protocol: SIRC
-address: 10 00 00 00
-command: 15 00 00 00
#
name: POWER
type: parsed
@@ -174,6 +349,19 @@ protocol: SIRC
address: 10 00 00 00
command: 2F 00 00 00
#
+name: VOL+
+type: parsed
+protocol: SIRC
+address: 10 00 00 00
+command: 12 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: SIRC
+address: 10 00 00 00
+command: 13 00 00 00
+#
+#
# STEJES
#
name: POWER
@@ -188,6 +376,19 @@ protocol: NECext
address: 85 23 00 00
command: 97 68 00 00
#
+name: VOL+
+type: parsed
+protocol: NECext
+address: 85 23 00 00
+command: 57 A8 00 00
+#
+name: VOL-
+type: parsed
+protocol: NECext
+address: 85 23 00 00
+command: 47 B8 00 00
+#
+#
# CREATIVE
#
name: POWER
@@ -204,9 +405,58 @@ command: 16 00 00 00
#
# | SOUNDBARS |
#
+# Audac
+#
+name: VOL+
+type: parsed
+protocol: NECext
+address: 86 FF 00 00
+command: 21 DE 00 00
+#
+name: VOL-
+type: parsed
+protocol: NECext
+address: 86 FF 00 00
+command: 2B D4 00 00
#
# BOSE
#
+name: VOL+
+type: parsed
+protocol: NECext
+address: BA 4B 00 00
+command: 03 FC 00 00
+#
+name: VOL-
+type: parsed
+protocol: NECext
+address: BA 4B 00 00
+command: 02 FD 00 00
+#
+name: VOL+
+type: parsed
+protocol: NECext
+address: BA A0 00 00
+command: 03 FC 00 00
+#
+name: VOL-
+type: parsed
+protocol: NECext
+address: BA A0 00 00
+command: 02 FD 00 00
+#
+name: VOL+
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 1014 1477 517 478 514 509 483 487 515 480 512 484 508 488 514 1479 515 1476 508 1483 511 1481 513 1478 516 1475 509 1482 512 1479 515 480 512 483 509 50775 1014 1477 517 504 488 508 484 513 489 506 486 510 482 514 488 1478 516 1475 509 1483 511 1480 514 1477 517 1474 510 1482 512 1478 516 505 487 509 483 50770 1009 1481 513 508 484 512 490 506 486 510 482 514 488 508 484 1481 513 1478 516 1475 509 1483 511 1480 514 1477 517 1475 509 1482 512 509 483 513 489
+#
+name: VOL-
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 1010 1508 486 509 483 513 489 507 485 512 490 505 487 510 482 1509 485 511 491 1501 483 1509 485 1507 487 1504 490 1502 482 1509 485 511 491 1500 484 50779 1010 1506 488 508 484 512 490 505 487 509 483 513 489 506 486 1506 488 507 485 1506 488 1503 481 1510 484 1508 486 1505 489 1503 481 514 488 1503 491
+#
name: POWER
type: parsed
protocol: NECext
@@ -245,6 +495,30 @@ command: 01 FE 00 00
#
# BRAND UNKNOWN
#
+name: VOL+
+type: parsed
+protocol: NECext
+address: 83 22 00 00
+command: 0A F5 00 00
+#
+name: VOL-
+type: parsed
+protocol: NECext
+address: 83 22 00 00
+command: 01 FE 00 00
+#
+name: VOL+
+type: parsed
+protocol: NEC
+address: 35 00 00 00
+command: 45 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: NEC
+address: 35 00 00 00
+command: 1B 00 00 00
+#
name: POWER
type: parsed
protocol: NEC
@@ -262,6 +536,32 @@ type: parsed
protocol: NECext
address: 83 22 00 00
command: 08 F7 00 00
+#
+# COMHEAR
+#
+name: VOL+
+type: parsed
+protocol: NECext
+address: 0A 1D 00 00
+command: 08 F7 00 00
+#
+name: VOL-
+type: parsed
+protocol: NECext
+address: 0A 1D 00 00
+command: 0A F5 00 00
+#
+name: MUTE
+type: parsed
+protocol: NECext
+address: 0A 1D 00 00
+command: 03 FC 00 00
+#
+name: POWER
+type: parsed
+protocol: NECext
+address: 0A 1D 00 00
+command: 01 FE 00 00
#
# KLIPSCH
#
@@ -271,9 +571,46 @@ protocol: NEC
address: 80 00 00 00
command: 01 00 00 00
#
+name: VOL+
+type: parsed
+protocol: NEC
+address: 80 00 00 00
+command: 03 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: NEC
+address: 80 00 00 00
+command: 06 00 00 00
+#
+# LG
+#
+name: VOL+
+type: parsed
+protocol: Samsung32
+address: 2C 00 00 00
+command: 17 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: Samsung32
+address: 2C 00 00 00
+command: 16 00 00 00
#
# ONN
#
+name: VOL+
+type: parsed
+protocol: NECext
+address: 83 22 00 00
+command: 16 E9 00 00
+#
+name: VOL-
+type: parsed
+protocol: NECext
+address: 83 22 00 00
+command: 0F F0 00 00
+#
name: POWER
type: parsed
protocol: NECext
@@ -288,6 +625,18 @@ command: 15 EA 00 00
#
# PANASONIC
#
+name: VOL+
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 3492 1750 416 454 425 1313 424 446 422 447 421 448 420 450 418 451 417 452 416 453 415 455 424 445 423 446 422 447 421 1290 447 450 418 451 417 452 416 453 415 455 424 445 423 447 421 1290 447 422 446 1319 418 452 416 426 442 454 425 445 423 446 422 447 421 421 447 449 419 450 418 451 417 452 416 453 415 454 425 1314 423 446 422 447 421 448 420 449 419 450 418 451 417 452 416 454 425 444 424 1315 422 74926 3488 1754 422 447 421 1317 420 422 446 451 417 452 416 453 415 454 425 444 424 445 423 446 422 447 421 448 420 449 419 1292 445 452 416 453 415 454 425 445 423 446 422 447 421 448 420 1318 419 450 418 1293 444 453 415 454 425 445 423 446 422 447 421 448 420 449 419 450 418 451 417 452 416 453 415 455 424 445 423 1315 422 448 420 449 419 450 418 424 444 452 416 453 415 454 425 445 423 446 422 1289 448
+#
+name: VOL-
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 3486 1756 420 449 419 1291 446 424 444 452 416 453 415 454 425 444 424 445 423 446 422 446 422 447 421 448 420 449 419 1319 418 452 416 453 415 426 453 444 424 445 423 446 422 447 421 1290 447 422 446 1319 418 451 417 452 416 454 425 444 424 445 423 446 422 447 421 420 448 1317 420 449 419 450 418 452 416 453 415 1322 425 417 451 445 423 1315 422 447 421 448 420 449 419 450 418 451 417 452 416 1322 415 74922 3492 1722 444 452 416 1321 416 426 453 444 424 445 423 446 422 447 421 447 421 448 420 449 419 450 418 451 417 452 416 1294 443 453 415 454 425 445 423 445 423 446 422 447 421 448 420 1317 420 450 418 1319 418 451 417 425 443 453 415 454 425 444 424 418 450 446 422 447 421 1317 420 449 419 450 418 451 417 452 416 1322 425 444 424 445 423 1315 422 420 448 448 420 448 420 422 446 450 418 451 417 1321 416
+#
name: POWER
type: raw
frequency: 38000
@@ -300,8 +649,45 @@ frequency: 38000
duty_cycle: 0.330000
data: 3486 1728 448 448 420 1318 419 423 445 451 417 452 416 454 425 444 424 445 423 446 422 447 421 448 420 421 447 449 419 1319 418 451 417 453 415 453 426 444 424 445 423 446 422 447 421 1317 420 449 419 1319 418 451 417 452 416 453 415 454 425 445 423 446 422 447 421 447 421 421 447 1291 446 423 445 425 443 1322 415 1322 425 444 424 445 423 446 422 1289 448 448 420 422 446 1292 445 451 417 452 416 1322 415 74924 3486 1755 421 447 421 1317 420 449 419 450 418 451 417 452 416 453 415 454 425 417 451 445 423 446 422 420 448 448 420 1317 420 450 418 451 417 452 416 426 442 427 452 444 424 445 423 1315 422 447 421 1317 420 449 419 450 418 451 417 425 443 453 415 454 425 444 424 418 450 446 422 1315 422 448 420 421 447 1291 446 1319 418 451 417 452 416 454 414 1323 424 445 423 419 449 1316 421 422 446 450 418 1293 444 74912 3487 1755 421 448 420 1290 447 423 445 451 417 452 416 453 415 454 425 445 423 446 422 446 422 447 421 421 447 449 419 1319 418 452 416 426 442 454 425 444 424 445 423 446 422 447 421 1290 447 449 419 1319 418 452 416 452 416 453 415 427 451 445 423 446 422 447 421 448 420 449 419 1319 418 424 444 452 416 1322 415 1323 424 444 424 445 423 446 422 1317 420 449 419 423 445 1320 417 453 415 427 452 1313 424
#
+# POLK AUDIO
+#
+name: POWER
+type: parsed
+protocol: NECext
+address: C8 91 00 00
+command: 00 FF 00 00
+#
+name: MUTE
+type: parsed
+protocol: NECext
+address: C8 91 00 00
+command: 20 DF 00 00
+#
+name: VOL+
+type: parsed
+protocol: NECext
+address: C8 91 00 00
+command: 1E E1 00 00
+#
+name: VOL-
+type: parsed
+protocol: NECext
+address: C8 91 00 00
+command: 1F E0 00 00
+#
# PHILLIPS
#
+name: VOL+
+type: parsed
+protocol: RC6
+address: 10 00 00 00
+command: 10 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: RC6
+address: 10 00 00 00
+command: 11 00 00 00
name: POWER
type: parsed
protocol: RC6
@@ -310,6 +696,54 @@ command: 0C 00 00 00
#
# SAMSUNG
#
+name: VOL+
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 4559 4461 546 490 515 495 521 490 515 495 489 1484 516 1482 550 486 519 491 493 1480 520 1478 522 1477 523 1475 546 490 515 495 521 490 515 495 489 4493 545 491 525 486 519 491 514 496 488 1484 516 1483 517 1481 551 486 488 1485 515 1483 517 1482 550 486 519 491 525 486 519 491 493 1479 542 494 522 489 516 467 517 1482 550
+#
+name: VOL-
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 4550 4469 548 462 543 467 549 461 544 466 518 1481 520 1479 542 468 548 462 522 1477 523 1476 514 1485 515 1483 549 461 544 466 550 461 544 466 518 4491 547 463 542 468 548 462 543 467 549 462 543 467 549 461 523 1476 514 1485 515 1484 516 1482 550 461 513 1486 514 1485 515 1483 549 461 544 466 550 461 544 493 491 1481 540
+#
+name: VOL+
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 4496 4442 513 503 488 502 489 501 490 500 491 1505 487 1508 484 505 486 504 487 1508 484 1511 492 1503 489 1499 514 484 486 504 487 502 489 501 490 4449 517 499 492 499 492 497 483 507 484 1511 492 1504 488 1499 514 483 487 1509 483 1512 491 1504 488 503 488 501 490 500 491 499 492 1504 488 501 490 500 491 492 509 1494 488 55126 4496 4446 541 482 488 502 489 501 490 500 491 1505 487 1508 484 505 486 504 487 1508 484 1503 510 1493 489 1480 512 504 487 503 488 502 489 500 491 4449 517 498 493 497 483 507 484 505 486 1502 511 1492 490 1504 488 502 489 1507 485 1509 483 1512 491 473 518 498 493 496 484 505 486 1510 483 499 512 484 486 504 487 1508 484
+#
+name: VOL-
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 4492 4434 510 505 486 505 486 504 487 503 488 1481 511 1484 518 499 492 498 493 1476 516 1479 513 1483 519 1469 596 402 516 500 491 499 492 498 493 4447 518 498 493 497 483 507 484 506 485 504 487 503 488 494 517 1485 486 1483 519 1476 516 1480 512 504 486 1508 484 1486 517 1479 565 425 513 502 488 501 490 492 509 1467 515
+#
+name: VOL+
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 4500 4436 516 504 486 510 490 505 485 510 490 1500 491 1474 517 505 485 484 516 1501 490 1501 490 1501 490 1501 490 505 485 511 489 506 484 485 515 4449 513 482 508 513 487 508 482 514 486 1504 487 1504 487 1504 487 482 508 1509 482 1509 492 1499 492 504 486 509 491 504 486 509 491 1500 491 504 486 510 490 478 512 1505 486 55017 4492 4444 508 512 488 508 482 513 487 508 482 1508 483 1482 509 513 487 508 482 1509 482 1509 482 1483 508 1483 508 513 487 508 482 514 486 509 481 4457 515 506 484 511 489 506 484 511 489 1501 490 1475 516 1501 490 506 484 1480 511 1507 484 1480 511 511 489 506 484 512 488 507 483 1507 484 512 488 507 483 512 488 1503 488
+#
+name: VOL-
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 4493 4443 509 512 488 507 483 512 488 507 483 1482 509 1482 509 512 488 507 483 1482 509 1482 509 1482 509 1482 509 512 488 507 483 513 487 508 482 4457 516 505 485 510 490 505 485 510 490 505 485 511 489 505 485 1480 511 1480 511 1480 511 1481 510 484 516 1476 515 1476 515 1476 515 481 509 486 514 481 509 486 514 1476 515 55014 4498 4438 514 482 508 487 513 482 508 488 512 1477 514 1477 514 482 508 487 513 1477 514 1477 514 1477 514 1477 514 482 518 477 513 482 518 477 513 4451 511 485 515 479 511 485 515 480 510 485 515 480 510 485 515 1475 516 1475 516 1476 515 1476 515 480 510 1481 510 1481 510 1481 510 486 514 481 509 486 514 481 509 1482 509
+#
+name: VOL+
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 4524 4473 512 516 491 511 486 516 491 511 496 1482 522 1482 522 506 491 512 495 1483 521 1483 521 1483 521 1483 521 506 491 512 495 507 490 512 495 4475 521 507 490 513 494 508 489 513 494 1484 520 1484 520 1483 521 507 490 1488 516 1488 516 1488 516 511 496 506 491 511 496 506 491 1488 516 511 496 506 491 512 495 1483 521 55356 4533 4463 512 516 491 511 486 516 491 511 496 1507 487 1492 512 515 492 510 487 1492 512 1492 512 1491 513 1491 513 515 492 510 487 515 492 510 487 4484 512 516 491 511 496 506 491 512 495 1483 521 1482 522 1482 522 506 491 1488 516 1487 517 1487 517 511 496 506 491 512 495 506 491 1488 516 512 495 507 490 512 495 1483 521
+#
+name: VOL-
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 4533 4464 521 507 490 512 495 507 490 513 494 1484 520 1484 520 508 489 513 494 1484 520 1484 520 1483 521 1483 521 506 491 511 496 506 491 512 495 4475 521 507 490 512 495 507 490 513 494 508 489 513 494 508 489 1490 514 1490 514 1490 514 1490 514 514 493 1485 519 1485 519 1485 519 509 488 515 492 510 487 516 491 1487 517 55369 4531 4465 520 508 489 514 493 509 488 515 492 1486 518 1486 518 509 488 514 493 1486 518 1485 519 1485 519 1485 519 509 488 514 493 509 488 515 492 4478 518 511 486 516 491 511 496 506 491 512 495 507 490 512 495 1483 521 1483 521 1483 521 1483 521 507 490 1488 516 1488 516 1488 516 512 495 507 490 513 494 508 489 1490 514
+#
name: POWER
type: raw
frequency: 38000
@@ -371,7 +805,19 @@ duty_cycle: 0.330000
data: 4555 4483 516 516 488 519 495 512 492 515 489 1525 493 1519 489 518 496 511 493 1521 487 1525 493 1520 488 1524 494 513 491 517 487 520 494 514 490 4501 519 513 491 516 488 520 494 513 491 517 487 521 493 514 490 518 486 1527 491 1522 496 1517 491 516 488 1525 493 1520 488 1525 493 1520 488 519 495 512 492 516 488 1525 493
#
# SENNHEISER
-#
+#
+name: VOL+
+type: parsed
+protocol: RC5
+address: 13 00 00 00
+command: 0D 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: RC5
+address: 13 00 00 00
+command: 0E 00 00 00
+#
name: POWER
type: parsed
protocol: RC5
@@ -385,7 +831,31 @@ address: 13 00 00 00
command: 0C 00 00 00
#
# SONY
-#
+#
+name: VOL+
+type: parsed
+protocol: SIRC
+address: 01 00 00 00
+command: 12 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: SIRC
+address: 01 00 00 00
+command: 13 00 00 00
+#
+name: VOL+
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 4552 4468 574 436 566 444 568 442 570 441 540 1458 546 1453 572 439 573 437 544 1455 539 1460 544 1456 548 1450 575 436 566 444 568 442 570 440 541 4468 594 416 565 445 567 443 569 441 540 1459 545 1453 541 1459 566 444 547 1452 542 1457 547 1452 593 417 564 446 566 444 568 442 539 1460 565 446 566 444 568 442 539 1460 565 55957 4581 4437 543 467 545 466 546 464 538 472 519 1480 514 1485 540 471 541 469 512 1486 518 1481 513 1486 518 1481 575 436 566 444 568 442 570 440 541 4468 543 468 544 465 547 464 538 472 519 1480 514 1485 519 1479 546 465 516 1483 511 1488 516 1483 542 468 544 466 546 464 538 473 519 1480 545 466 546 464 538 472 519 1480 545
+#
+name: VOL-
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 4546 4473 538 473 539 470 542 469 543 467 514 1484 520 1479 545 465 547 463 518 1481 513 1486 518 1481 513 1487 538 472 540 470 542 469 543 466 515 4495 546 463 539 472 540 470 542 468 544 466 546 491 521 462 519 1480 513 1485 519 1480 514 1486 539 472 519 1479 515 1484 520 1479 546 464 548 463 539 471 541 469 512 1487 548
+#
name: POWER
type: raw
frequency: 38000
@@ -450,6 +920,18 @@ command: 1D E2 00 00
#
# TAOTRONICS
#
+name: VOL+
+type: parsed
+protocol: NEC
+address: 80 00 00 00
+command: 0D 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: NEC
+address: 80 00 00 00
+command: 08 00 00 00
+#
name: POWER
type: parsed
protocol: NEC
@@ -472,6 +954,18 @@ command: 40 00 00 00
#
# XIAOMI
#
+name: VOL+
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 1048 580 597 1165 596 582 595 1167 594 875 599 578 599 1455 593 585 592 1171 600 577 600 576 601 13191 1042 586 591 1170 601 576 601 1161 600 869 595 582 595 1459 599 578 599 1163 598 580 597 579 598 13195 1048 580 597 1165 596 581 596 1167 594 875 599 578 599 1456 592 585 592 1171 600 577 600 577 600 13192 1052 576 601 1162 599 578 599 1163 598 871 593 584 593 1462 596 581 596 1166 595 582 595 582 595
+#
+name: VOL-
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 1048 553 624 1138 623 554 623 1139 622 848 626 551 626 1427 621 556 652 1403 655 522 655 814 650 12579 1050 552 656 1106 624 553 624 1138 623 847 627 550 627 1427 621 556 621 1434 624 553 624 845 619 12612 1079 523 623 1139 622 555 622 1139 622 848 626 550 627 1427 621 556 621 1434 624 553 624 845 619 12613 1047 556 621 1141 620 556 621 1141 620 850 624 552 625 1429 619 558 619 1435 623 554 623 846 628 12600 1050 552 625 1137 624 553 624 1137 624 846 618 558 619 1435 623 554 623 1431 627 550 627 842 622 12609 1051 551 626 1136 625 551 626 1136 625 844 620 557 620 1434 624 554 623 1431 627 550 627 843 621
+#
name: POWER
type: raw
frequency: 38000
@@ -526,6 +1020,18 @@ frequency: 38000
duty_cycle: 0.330000
data: 270 793 250 1795 272 818 246 791 252 809 244 766 277 1795 282 781 272 790 253 809 224 1822 275 1797 280 1820 277 785 248 788 245 43889 273 790 274 1799 278 785 248 788 276 787 246 1826 271 792 251 1794 273 1827 270 1802 275 788 245 791 273 790 253 1819 278 1794 273 43889 274 789 254 1818 269 767 276 786 247 789 275 788 245 1827 270 792 251 785 248 814 250 1796 281 1819 248 1825 272 790 253 783 271 43889 245 791 273 1799 278 786 278 784 249 787 246 1827 281 781 252 1821 276 1796 281 1792 274 814 250 786 247 789 244 1829 279 1793 274 43888 275 815 218 1828 280 783 250 786 278 785 248 788 245 1827 280 782 251 785 268 794 249 1797 280 1819 278 1794 272 791 252 810 254
#
+name: VOL+
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 277 759 274 1799 278 784 280 783 250 812 242 1804 273 816 227 808 246 791 252 1819 248 1825 273 1826 251 1822 276 786 247 789 244 43888 274 815 249 1797 280 783 250 812 252 784 249 813 241 1805 272 1827 250 1822 275 787 246 816 217 819 255 807 226 1820 278 1795 272 43888 273 789 254 1817 270 793 251 785 248 814 250 1795 282 807 247 790 253 783 250 1822 276 1796 281 1818 249 1824 274 814 229 807 247
+#
+name: VOL-
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 275 762 271 1800 277 786 278 784 249 813 241 795 248 1824 253 784 270 792 251 1821 246 1826 272 1801 276 1823 275 762 271 790 243 43889 274 789 275 1797 280 783 250 812 252 784 249 1823 275 762 271 1827 250 1822 276 787 246 816 217 818 246 790 253 1819 268 1804 273 43886 277 786 247 1825 273 764 280 783 250 811 253 784 249 1822 276 761 272 816 228 1819 279 1794 273 1826 251 1821 277 786 247 815 249
+#
name: MUTE
type: raw
frequency: 38000
@@ -540,6 +1046,18 @@ frequency: 39105
duty_cycle: 0.330000
data: 5396 53113 8899 4450 563 1662 563 1662 563 1662 563 563 563 563 563 563 563 563 563 1662 563 563 563 563 563 1662 563 1662 563 1662 563 1662 563 1662 563 563 563 563 563 563 563 563 563 563 563 563 563 563 563 563 563 1662 563 1662 563 1662 563 1662 563 1662 563 1662 563 1662 563 1662 563 563 563 38358 8899 2225 563 95052
#
+name: VOL+
+type: raw
+frequency: 39105
+duty_cycle: 0.330000
+data: 5472 53216 8899 4450 563 1662 563 1662 563 1662 563 563 563 563 563 563 563 563 563 1662 563 563 563 563 563 1662 563 1662 563 1662 563 1662 563 1662 563 563 563 563 563 563 563 563 563 1662 563 563 563 563 563 563 563 1662 563 1662 563 1662 563 1662 563 563 563 1662 563 1662 563 1662 563 563 563 38358 8899 2199 563 95052
+#
+name: VOL-
+type: raw
+frequency: 39105
+duty_cycle: 0.330000
+data: 5472 53344 8899 4424 563 1662 563 1662 563 1662 563 563 563 563 563 563 563 563 563 1662 563 563 563 563 563 1662 563 1662 563 1662 563 1662 563 1662 563 563 563 563 563 563 563 1662 563 1662 563 563 563 563 563 563 563 1662 563 1662 563 1662 563 563 563 563 563 1662 563 1662 563 1662 563 563 563 38358 8899 2225 563 95052
+#
name: MUTE
type: raw
frequency: 39105
@@ -554,6 +1072,18 @@ protocol: NECext
address: D2 6C 00 00
command: CB 34 00 00
#
+name: VOL+
+type: parsed
+protocol: NECext
+address: D2 6D 00 00
+command: 02 FD 00 00
+#
+name: VOL-
+type: parsed
+protocol: NECext
+address: D2 6D 00 00
+command: 03 FC 00 00
+#
name: MUTE
type: parsed
protocol: NECext
@@ -566,6 +1096,18 @@ protocol: NECext
address: D2 03 00 00
command: 04 FB 00 00
#
+name: VOL+
+type: parsed
+protocol: NECext
+address: D2 03 00 00
+command: 02 FD 00 00
+#
+name: VOL-
+type: parsed
+protocol: NECext
+address: D2 03 00 00
+command: 03 FC 00 00
+#
name: MUTE
type: parsed
protocol: NECext
@@ -580,6 +1122,18 @@ protocol: RC5
address: 10 00 00 00
command: 0D 00 00 00
#
+name: VOL+
+type: parsed
+protocol: RC5
+address: 10 00 00 00
+command: 10 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: RC5
+address: 10 00 00 00
+command: 11 00 00 00
+#
# SONY
#
name: POWER
@@ -588,6 +1142,30 @@ protocol: SIRC15
address: 10 00 00 00
command: 60 00 00 00
#
+name: VOL+
+type: parsed
+protocol: SIRC15
+address: 30 00 00 00
+command: 12 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: SIRC15
+address: 30 00 00 00
+command: 13 00 00 00
+#
+name: VOL+
+type: parsed
+protocol: SIRC15
+address: 10 00 00 00
+command: 12 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: SIRC15
+address: 10 00 00 00
+command: 13 00 00 00
+#
# YAMAHA
#
name: POWER
@@ -613,3 +1191,39 @@ type: parsed
protocol: NEC
address: 78 00 00 00
command: 4F 00 00 00
+#
+name: VOL+
+type: parsed
+protocol: NEC
+address: 7A 00 00 00
+command: 1A 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: NEC
+address: 7A 00 00 00
+command: 1B 00 00 00
+#
+name: VOL+
+type: parsed
+protocol: NECext
+address: 7A 85 00 00
+command: 1A E4 00 00
+#
+name: VOL-
+type: parsed
+protocol: NECext
+address: 7A 85 00 00
+command: 1B E5 00 00
+#
+name: VOL+
+type: parsed
+protocol: NEC
+address: 78 00 00 00
+command: 1E 00 00 00
+#
+name: VOL-
+type: parsed
+protocol: NEC
+address: 78 00 00 00
+command: 1F 00 00 00
diff --git a/assets/resources/infrared/assets/tv.ir b/assets/resources/infrared/assets/tv.ir
index f79906b29..e2d819782 100755
--- a/assets/resources/infrared/assets/tv.ir
+++ b/assets/resources/infrared/assets/tv.ir
@@ -7,8 +7,11 @@ Version: 1
# Compiled by Hyper_Mash
# Support/testing/additions from UberGuidoZ
# Thank you to ChaoticDynamic aka c-nagy for cleanup
+############################################################
+# Also a HUGE thank you to Amec0e for continued maintenance!
+############################################################
#
-# Updated on 10th August 2022
+# Updated on 17th August 2022
#
name: POWER
type: parsed
@@ -106,12 +109,16 @@ protocol: Samsung32
address: 0e 00 00 00
command: 0d 00 00 00
#
+# Keep an eye on this, it could be power.
+#
name: VOL+
type: parsed
protocol: Samsung32
address: 0e 00 00 00
command: 14 00 00 00
#
+#
+#
name: VOL-
type: parsed
protocol: Samsung32
@@ -240,12 +247,6 @@ command: 13 00 00 00
#
name: POWER
type: parsed
-protocol: Samsung32
-address: 0e 00 00 00
-command: 14 00 00 00
-#
-name: POWER
-type: parsed
protocol: NECext
address: 80 7e 00 00
command: 18 00 00 00
@@ -304,7 +305,6 @@ protocol: NEC
address: 00 00 00 00
command: 01 00 00 00
#
-#
name: POWER
type: parsed
protocol: Samsung32
@@ -1757,17 +1757,15 @@ protocol: NECext
address: 02 7D 00 00
command: 57 A8 00 00
#
+# Keep an eye on this it might be volume down
+#
name: VOL+
type: parsed
protocol: NECext
address: 02 7D 00 00
command: 15 EA 00 00
#
-name: VOL-
-type: parsed
-protocol: NECext
-address: 02 7D 00 00
-command: 15 EA 00 00
+#
#
name: POWER
type: parsed
@@ -2069,42 +2067,6 @@ protocol: NECext
address: EA C7 00 00
command: 20 DF 00 00
#
-name: POWER
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 3477 1735 448 424 445 1301 448 425 444 429 450 422 447 426 443 430 449 423 446 427 452 421 448 424 445 428 451 422 447 1299 450 422 447 426 443 430 449 423 446 427 452 420 449 424 445 428 451 421 448 1298 451 422 447 425 444 429 450 423 446 426 443 430 449 423 446 427 452 1294 444 428 451 1295 443 1303 446 1300 449 1297 452 421 500 373 444 1302 447 426 443 1303 446 1300 449 1297 452 1294 444 428 451 1295 443 74431 3476 1736 448 425 444 1302 447 426 453 419 450 423 446 427 452 420 449 424 445 427 452 421 448 425 444 428 451 422 447 1299 450 422 447 426 453 420 449 423 446 427 452 420 449 424 445 428 451 421 448 1298 451 422 447 425 454 419 450 423 446 454 425 447 422 451 418 427 452 1294 444 428 451 1295 443 1302 447 1300 449 1297 452 420 449 451 418 1301 448 424 445 1302 447 1299 450 1296 442 1304 445 454 425 1294 444 74431 3475 1737 446 425 454 1293 445 426 453 420 449 424 445 427 452 421 448 424 445 428 451 422 447 425 454 419 450 422 447 1300 449 424 445 427 452 421 448 424 445 428 451 421 448 425 454 418 451 422 447 1300 449 424 445 454 425 420 449 424 445 428 451 421 448 425 444 429 450 1296 453 419 450 1297 452 1294 444 1301 448 1298 451 422 509 364 453 1293 445 427 452 1294 444 1301 448 1298 451 1296 453 420 449 1296 453
-#
-name: VOL+
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 3474 1765 418 455 424 1323 415 458 421 451 418 456 423 422 447 454 415 458 421 452 417 456 423 450 419 454 425 448 421 1325 423 423 446 454 425 448 421 452 417 456 423 450 419 454 425 448 421 452 417 1330 418 455 424 448 421 453 416 457 422 451 418 455 424 449 420 453 416 457 422 451 418 455 424 449 420 453 416 1331 417 455 424 449 420 453 416 458 421 452 417 456 423 450 419 1327 421 424 445 1329 419
-#
-name: VOL-
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 3475 1737 446 427 452 1294 444 456 423 423 446 454 425 421 448 452 417 456 423 423 446 455 424 449 420 425 444 457 422 1297 451 421 448 453 416 457 422 451 418 428 451 449 420 426 443 457 422 424 445 1301 447 426 443 458 421 451 418 456 423 449 420 454 415 458 421 452 417 1302 446 427 452 448 421 452 417 456 423 1296 452 448 421 453 416 1303 445 455 424 449 420 453 416 430 449 1297 451 421 448 1299 449
-#
-name: CH+
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 3476 1764 419 454 425 1321 417 456 423 450 419 455 424 449 420 453 416 457 422 451 418 455 424 449 420 453 416 458 421 1325 423 450 419 454 414 458 421 452 417 456 423 450 419 455 424 449 420 453 416 1330 418 455 424 449 420 453 416 457 422 451 418 456 423 450 419 454 415 458 421 452 417 1330 418 454 425 1321 417 1330 418 455 424 449 420 453 416 458 421 1325 423 450 419 1327 421 1325 423 450 419 1327 421
-#
-name: CH-
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 3480 1759 424 450 419 1300 448 452 417 456 423 450 419 454 425 448 421 452 417 457 422 451 418 455 424 449 420 453 416 1331 417 455 424 449 420 454 415 458 421 452 417 456 423 450 419 454 425 448 421 1325 423 450 419 455 424 448 421 453 416 457 422 451 418 455 424 449 420 1326 422 424 445 1329 419 426 443 1331 417 1302 446 454 425 420 449 1298 450 450 419 1328 420 452 417 1330 418 1301 447 425 444 1330 418
-#
-name: MUTE
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 3477 1763 420 453 416 1330 418 455 424 449 420 453 415 458 421 452 417 456 423 450 419 454 425 448 421 452 417 456 423 1324 424 448 421 453 416 457 422 451 418 455 424 449 420 453 416 457 422 451 418 1329 419 454 415 458 421 452 417 456 423 450 419 427 452 448 421 452 417 456 423 1324 424 449 420 453 416 1330 418 1328 420 453 416 457 422 451 418 1329 419 454 415 458 421 1298 450 1323 425 448 421 1326 422
-#
name: CH-
type: raw
frequency: 38000
@@ -2153,30 +2115,6 @@ frequency: 38000
duty_cycle: 0.330000
data: 182 7827 172 2332 177 2328 181 2323 176 2330 179 1309 175 1331 174 2331 178 1328 177 2328 181 1307 177 2327 182 1325 180 1326 179 1309 176 1331 174 1332 173 2333 176 2310 178 1328 177 2328 181 1325 180 2306 182 1325 180 2325 174 8340 183 7825 175 2330 179 2326 173 2333 176 2310 178 1328 177 1329 176 2329 180 1308 176 2329 180 1326 179 2326 173 1334 182 1306 179 1328 177 1329 176 1312 183 2322 177 2329 180 1326 179 2325 174 1315 180 2326 173 1333 183 2323 176 8339 183 7824 175 2330 179 2307 181 2324 175 2331 178 1328 177 1330 175 2311 177 1329 176 2329 180 1326 179 2327 182 1305 179 1328 177 1328 177 1311 173 1334 182 2323 176 2330 179 1326 571 1916 180 1327 178 2325 587 920 575 1930 579
#
-name: VOL+
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 179 7828 182 2323 176 2328 181 2323 176 2329 180 1308 176 1330 175 2329 180 1326 179 2307 181 2323 176 2329 180 2325 174 1332 173 1315 180 1327 179 1328 177 2327 182 2322 177 1311 173 2332 177 1329 176 1330 175 1312 183 1324 181 8332 180 7826 174 2331 178 2326 173 2313 176 2330 179 1327 178 1328 177 2327 182 1306 179 2326 183 2322 177 2328 181 2323 176 1312 183 1324 181 1325 180 1325 180 2307 181 2323 176 1331 174 2330 179 1327 178 1310 175 1331 174 1332 173 8323 179 7845 176 2311 177 2327 182 2322 177 2328 181 1325 180 1308 177 2328 181 1325 180 2325 174 2330 179 2326 173 2314 174 1332 173 1332 173 1333 183 1306 178 2326 183 2322 177 1329 176 2328 181 1307 177 1329 176 1330 175 1313 182
-#
-name: VOL-
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 183 7824 176 2329 180 2324 175 2329 180 2324 175 1314 181 1325 180 2324 175 1331 174 2331 178 2307 181 2324 175 1331 174 1331 174 1314 181 1326 179 1326 179 2325 174 2332 177 1310 174 2330 179 1327 178 1328 177 1310 174 2330 179 8334 178 7827 173 2332 177 2327 182 2323 176 2310 178 1328 177 1328 177 2327 182 1306 179 2326 183 2322 177 2327 182 1324 181 1307 177 1329 176 1330 176 1331 174 2311 177 2328 181 1325 180 2324 175 1332 173 1313 182 1325 180 2324 175 8339 173 1383 2522 3925 179 2325 576 1909 590 1915 594 1910 589 918 588 919 576 1911 175 1332 173 2330 592 1912 587 1918 581 907 588 918 598 908 587 920 575 913 592 1914 182 2320 592 914 581 1927 180 1307 178 1327 592 915 580 1925 574
-#
-name: CH+
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 176 7830 180 2324 175 2329 180 2324 175 2329 180 1308 176 1329 176 2328 181 1325 180 2305 183 2321 178 1329 177 2327 182 1324 181 1306 178 1328 177 1329 176 2327 182 2304 174 1332 173 2332 177 1328 177 1310 174 2330 179 1327 178 8333 179 7826 174 2330 179 2325 174 2313 175 2329 180 1326 179 1326 179 2325 174 1315 180 2324 175 2329 180 1326 179 2325 174 1314 181 1325 180 1326 179 1308 177 2328 181 2323 176 1330 175 2329 180 1308 176 1330 175 2328 181 1325 180 8314 177 7845 176 2310 178 2327 182 2322 177 2327 182 1323 182 1306 179 2326 173 1333 183 2322 177 2327 182 1305 179 2326 173 1333 183 1323 182 1305 179 1327 178 2326 173 2331 178 1327 178 2308 180 1326 179 1327 178 2325 174 1315 180
-#
-name: CH-
-type: raw
-frequency: 38000
-duty_cycle: 0.330000
-data: 182 7824 176 2328 181 2323 176 2328 181 2324 175 1312 183 1323 182 2322 177 1330 175 2309 179 2325 174 1332 173 1333 183 1305 179 1327 178 1328 177 1328 177 2308 180 262 177 1885 175 295 175 861 174 2330 179 99 313 911 573 915 590 1916 180 64 349 1910 176 265 174 7896 177 3081 835 3912 182 2322 177 207 179 1942 180 2304 174 268 181 1881 179 263 176 889 177 264 175 886 583 1925 182 271 178 855 180 240 178 1907 174 2331 178 1327 178 1309 176 1329 590 916 589 919 173 306 175 833 181 317 174 1832 175 2329 180 1325 180 309 182 1833 174 1313 182 1325 180 289 181 1853 175 2329 180 8313 178 7845 176 2309 179 2325 174 2331 178 2326 173 1333 183 1304 180 2324 175 1332 173 2330 179 2325 174 1314 181 1325 180 1326 179 1327 178 1308 177 1330 175 2329 180 2324 175 1312 183 2322 177 1329 176 1329 176 2329 180 2304 174 8339 173 351 3575 3902 594 1911 588 1916 593 1911 588 1916 583 904 591 916 589 1915 594 911 584 1920 579 1907 592 915 590 915 591 916 579 908 597 909 596 909 586 1919 580 1907 179 1326 592 1912 597 908 587 901 594 1911 588 1916 593
-#
name: MUTE
type: raw
frequency: 38000
@@ -3081,6 +3019,39 @@ frequency: 38000
duty_cycle: 0.330000
data: 332 601 314 290 646 286 307 594 321 282 644 590 648 582 323 281 645 586 641 290 313 583 644
#
+# THOMSON
+#
+name: POWER
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 3997 3984 515 1987 518 1984 521 1980 514 2013 492 982 521 980 512 1989 516 984 519 1983 522 979 513 1987 518 983 520 981 522 979 513 1014 489 1012 491 1984 521 1981 513 987 516 1986 519 981 522 1980 515 986 517 1985 520 9037 4000 3982 516 1984 521 1981 513 1988 517 1984 521 979 513 988 515 1986 519 982 521 1981 513 987 516 1985 520 981 522 979 513 988 515 986 517 984 519 1983 511 1989 516 985 518 1983 522 979 513 1988 517 984 519 1983 522 9036 3991 3990 519 1983 511 1990 515 1986 519 1982 512 988 515 1012 491 1985 520 981 522 1979 515 985 518 1984 521 980 512 988 515 986 517 984 519 983 520 1981 513 1988 517 983 520 1982 512 988 515 1986 519 982 521 1981 513
+#
+name: VOL+
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 3993 3987 521 1980 514 1987 517 1984 520 1981 513 987 515 985 517 1984 520 980 522 1979 515 1987 517 1983 521 1980 514 986 516 984 518 982 520 980 512 1989 515 1986 518 982 520 1981 513 987 515 985 517 983 519 982 520 9036 3999 3981 517 1984 520 1981 513 1988 516 1985 519 980 512 989 513 1987 517 983 519 1982 512 1990 514 1986 518 1982 512 988 514 987 515 985 517 983 519 1981 513 1988 516 984 518 1983 521 979 513 987 515 985 517 983 519 9037 4019 3962 515 1986 518 1982 512 1990 514 1986 518 982 520 980 512 1989 515 985 517 1984 520 1981 513 1989 515 1985 571 929 521 979 513 988 514 986 516 1985 519 1981 565 936 514 1986 570 930 520 981 521 979 513 988 515
+#
+name: VOL-
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 3999 3982 516 1985 519 1982 512 1990 514 1986 518 982 520 980 512 1989 515 986 516 2010 494 1981 513 1989 515 984 518 982 520 981 521 979 513 1014 488 1986 518 1983 511 989 513 1988 516 984 518 982 520 980 512 1989 515 9040 4026 3954 512 1989 515 1985 519 1982 512 1989 515 985 517 983 519 1981 513 988 514 1987 517 1983 521 1980 514 986 516 984 518 982 520 980 522 979 513 1987 517 1985 519 980 522 1980 514 985 517 984 518 982 520 2007 487 9043 4023 3956 521 1980 514 1987 517 1984 520 1980 514 986 516 984 518 1982 522 979 513 1988 516 1985 519 1981 513 987 515 985 517 983 519 982 520 980 512 1989 515 1986 518 981 521 1980 514 986 516 985 517 983 519 1981 513
+#
+name: CH+
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 3997 3983 515 1987 517 1983 521 1980 514 1987 517 983 519 981 521 1980 514 986 516 1985 519 2007 487 987 515 1986 518 982 520 980 512 989 513 987 515 1985 519 1982 512 988 514 1987 517 983 519 981 521 1979 515 986 516 9040 3994 3985 512 1989 515 1985 519 1982 512 1989 515 984 518 982 520 1981 513 987 515 1986 518 1983 521 979 513 2014 490 984 518 982 520 980 522 979 513 1987 517 1984 520 980 512 1989 515 985 517 983 519 1981 513 988 514 9042 3992 3987 521 1980 514 1987 517 1984 520 1981 513 987 515 985 517 1983 521 980 512 1989 515 1986 518 981 521 1980 514 986 516 984 518 983 519 981 521 1979 515 1987 517 982 520 1981 513 987 515 985 517 1983 521 980 512
+#
+name: CH-
+type: raw
+frequency: 38000
+duty_cycle: 0.330000
+data: 3994 3986 512 1989 515 1986 518 1982 512 1989 515 985 517 983 519 2008 486 988 514 1987 517 1983 521 979 513 987 515 986 516 984 518 982 520 980 512 1988 516 1985 519 981 521 1980 514 986 516 984 518 2009 485 1990 514 9041 3994 3986 511 1989 515 1985 519 1982 512 1989 515 984 518 982 520 1981 513 987 515 1986 518 1982 512 988 514 986 516 984 518 983 519 981 521 979 513 1987 517 1984 520 980 512 1989 515 984 518 982 520 2007 487 1988 516 9038 4028 3952 514 1986 518 1982 512 1989 515 1985 519 980 512 989 513 2013 491 983 519 1982 512 1989 515 984 519 982 520 980 522 979 513 987 515 985 517 1983 521 1980 514 986 516 1985 519 980 512 989 513 2013 491 1984 520
+#
+#
# WBOX
#
name: POWER
diff --git a/assets/resources/nfc/assets/mf_classic_dict.nfc b/assets/resources/nfc/assets/mf_classic_dict.nfc
index 6007c2664..097643749 100644
--- a/assets/resources/nfc/assets/mf_classic_dict.nfc
+++ b/assets/resources/nfc/assets/mf_classic_dict.nfc
@@ -1,4 +1,8 @@
-# Last update July 5, 2022
+###########################
+# Do not edit, this file will be overwritten after firmware update
+# Use the user_dict file for user keys
+###########################
+# Last update 15th August, 2022
# -------------------------
# MIFARE DEFAULT KEYS
# -- ICEMAN FORK VERSION --
@@ -101,9 +105,6 @@ A00000000000
A053A292A4AF
A94133013401
AAAAAAAAAAAA
-# FOOD REPUBLIC
-30C1DC9DD040
-A9B9C1D0E3F1
# KEYFROMLADYADA.NET
B00000000000
B127C6F41436
@@ -600,7 +601,6 @@ F7A39753D018
EC0A9B1A9E06
6C94E1CED026
0F230695923F
-0000014B5C31
BEDB604CC9D1
B8A1F613CF3D
B578F38A5C61
@@ -3634,19 +3634,75 @@ FFD46FF6C5EE
# The Westin Jakarta Indonesia from D4DB0D
# Peppers Hotel Unknown location from D4DB0D
6E0DD4136B0A
-A0A1A2A3A4A5
-B578F38A5C61
141940E9B71B
-0000014B5C31
3B1D3AAC866E
95E9EE4CCF8F
0000014B5C31
FEA6B332F04A
-B578F38A5C61
BE0EC5155806
0500D6BFCC4F
FC5AC7678BE3
F09BB8DD142D
B4B3FFEDBE0A
-B578F38A5C61
540E0D2D1D08
+# Schlage 9691T Keyfob
+7579B671051A
+4F4553746B41
+# FOOD REPUBLIC
+30C1DC9DD040
+A9B9C1D0E3F1
+# iGuard Simple (and reverse) keys
+AAAAAAFFFFFF
+FFFFFFAAAAAA
+# Vigik verified by quantum-x
+# https://github.com/RfidResearchGroup/proxmark3/pull/1742#issuecomment-1206113976
+A00027000099
+A00016000028
+A00003000028
+A0000F000345
+A00001000030
+A00002000086
+A00002000036
+A00002000088
+A00000000058
+A00000000096
+A00000000008
+A00000043D79
+A00000000064
+A00025000030
+A00003000057
+#
+# BH USA 2013 conference
+012279BAD3E5
+# Vigik ScanBadge App (fr.badgevigik.scanbadge)
+# Website https://badge-vigik.fr/ - By Alex`
+0000A2B3C86F
+021200c20307
+021209197507
+1E34B127AF9C
+303041534956
+4143532D494E
+41454E521985
+43412d627400
+455249524345
+456666456666
+45B722C63319
+484585414354
+4D414C414741
+536563644C65
+57D27B730760
+593DD8FE167A
+6472616E7265
+65626F726369
+680E95F3C287
+709BA7D4F920
+8829DAD9AF76
+92D0A0999CBA
+948EE7CFC9DB
+9EB7C8A6D4E3
+A22AE12C9013
+AFC984A3576E
+# Spackular A/B
+# data from http://www.proxmark.org/forum/viewtopic.php?pid=45100#p45100
+7CB033257498
+1153AABAFF6C
diff --git a/assets/resources/subghz/assets/setting_user b/assets/resources/subghz/assets/setting_user
index 6d0102d6c..32051d45d 100644
--- a/assets/resources/subghz/assets/setting_user
+++ b/assets/resources/subghz/assets/setting_user
@@ -32,8 +32,10 @@ Frequency: 418000000
Frequency: 433075000
Frequency: 433220000
Frequency: 433420000
+Frequency: 433657070
Frequency: 433889000
Frequency: 433920000
+Frequency: 434176948
Frequency: 434420000
Frequency: 434775000
Frequency: 438900000
@@ -65,3 +67,13 @@ Hopper_frequency: 868350000
#Custom_preset_name: AM_2
#Custom_preset_module: CC1101
#Custom_preset_data: 02 0D 03 07 08 32 0B 06 14 00 13 00 12 30 11 32 10 17 18 18 19 18 1D 91 1C 00 1B 07 20 FB 22 11 21 B6 00 00 00 C0 00 00 00 00 00 00
+
+Custom_preset_name: HND_1
+Custom_preset_module: CC1101
+# G2 G3 G4 D L0 L1 L2
+Custom_preset_data: 02 0D 0B 06 08 32 07 04 14 00 13 02 12 04 11 36 10 69 15 32 18 18 19 16 1D 91 1C 00 1B 07 20 FB 22 10 21 56 00 00 C0 00 00 00 00 00 00 00
+
+Custom_preset_name: HND_2
+Custom_preset_module: CC1101
+# G2 G3 G4 D L0 L1 L2
+Custom_preset_data: 02 0D 0B 06 08 32 07 04 14 00 13 02 12 07 11 36 10 E9 15 32 18 18 19 16 1D 92 1C 40 1B 03 20 FB 22 10 21 56 00 00 C0 00 00 00 00 00 00 00
\ No newline at end of file
diff --git a/assets/unit_tests/subghz/honeywell_wdb.sub b/assets/unit_tests/subghz/honeywell_wdb.sub
new file mode 100644
index 000000000..bce11cd0d
--- /dev/null
+++ b/assets/unit_tests/subghz/honeywell_wdb.sub
@@ -0,0 +1,7 @@
+Filetype: Flipper SubGhz Key File
+Version: 1
+Frequency: 868350000
+Preset: FuriHalSubGhzPreset2FSKDev476Async
+Protocol: Honeywell
+Bit: 48
+Key: 00 00 0E DB 70 20 00 01
diff --git a/assets/unit_tests/subghz/honeywell_wdb_raw.sub b/assets/unit_tests/subghz/honeywell_wdb_raw.sub
new file mode 100644
index 000000000..0fbd6d23e
--- /dev/null
+++ b/assets/unit_tests/subghz/honeywell_wdb_raw.sub
@@ -0,0 +1,22 @@
+Filetype: Flipper SubGhz RAW File
+Version: 1
+Frequency: 868250000
+Preset: FuriHalSubGhzPreset2FSKDev476Async
+Protocol: RAW
+RAW_Data: 414 -1374 51 -108 79 -216 189 -584 53 -214 53 -400 215 -264 129 -322 77 -288 79 -54 107 -184 51 -446 53 -160 161 -305 263 -104 264 -134 53 -806 267 -80 187 -314 53 -158 83 -1172 243 -833 79 -188 345 -208 77 -182 225 -100 107 -106 187 -190 105 -432 176 -174 119 -328 79 -432 79 -102 99 -514 127 -218 79 -184 77 -52 101 -356 53 -615 243 -266 181 -102 212 -138 81 -486 205 -574 77 -256 155 -152 217 -78 75 -1010 393 -346 79 -488 107 -284 121 -72 215 -174 183 -54 257 -332 179 -52 79 -238 53 -636 161 -80 227 -950 346 -160 109 -564 295 -160 299 -160 435 -487 312 -52 105 -292 77 -246 137 -498 366 -104 255 -362 97 -210 53 -555 374 -206 129 -96 303 -280 179 -172 75 -102 99 -76 353 -228 131 -252 147 -130 79 -304 103 -82 139 -52 103 -183 77 -284 75 -454 55 -188 77 -222 161 -128 107 -136 187 -270 53 -371 184 -364 103 -284 129 -52 103 -321 81 -554 261 -1048 107 -106 243 -280 103 -478 215 -530 53 -108 53 -236 203 -180 51 -78 77 -338 81 -82 53 -231 75 -124 256 -232 227 -448 131 -340 131 -266 107 -346 51 -254 75 -134 210 -182 103 -280 127 -122 305 -310 255 -528 77 -513 79 -214 209 -102 53 -80 133 -1727 237 -78 79 -242 53 -296 133 -532 53 -513 53 -54 131 -190 53 -661 129 -218 107 -394 103 -554 157 -112 343 -314 103 -283 79 -304 135 -56 111 -272 189 -370 271 -270 105 -956 79 -184 77 -868 307 -156 129 -731 51 -200 161 -84 81 -326 51 -54 157 -168 369 -152 101 -188 81 -398 239 -132 215 -54 105 -182 317 -206 99 -198 97 -274 157 -271 121 -268 200 -330 499 -184 55 -434 133 -646 283 -152 255 -428 101 -350 199 -124 145 -304 308 -102 75 -386 107 -186 129 -534 101 -180 175 -100 151 -98 53 -78 133 -794 183 -150 83 -220 185 -280 83 -537 107 -308 55 -138 79 -714 79 -538 77 -106 133 -242 263 -236 75 -884 215 -136 81 -270 133 -624 105 -132 79 -848 291 -373 79 -244 55 -619 203 -202 77 -156 103 -176 99 -408 107 -318 77 -316 79 -500 55 -691 51 -340 129 -266 53 -486 103 -376 103 -185 51 -156 81 -106 77 -104 79 -502 208 -292 133 -432 105 -52 105 -80 51 -158 317 -372 181 -844 51 -270 107 -312 79 -302 83 -444 53 -640 77 -268 183 -138 85 -192 79 -158 131 -132 155 -220 81 -245 127 -386 185 -296 53 -608 77 -308 51 -822 105 -832 51 -850 155 -242 105 -422 79 -270 155 -76 77 -162 55 -414
+RAW_Data: 109 -630 77 -190 53 -52 131 -860 53 -1300 83 -1122 99 -432 53 -724 81 -390 159 -106 81 -2607 79 -474 75 -694 151 -146 73 -104 53 -380 77 -278 77 -128 73 -148 73 -248 99 -314 75 -154 97 -2225 51 -952 183 -970 77 -1210 51 -326 103 -368 151 -252 121 -784 51 -108 187 -256 227 -242 105 -104 150 -128 77 -1287 173 -2513 77 -1144 105 -1268 111 -3964 101 -1348 81 -2718 81 -302 79 -1999 55 -1268 57 -7269 53 -424 83 -3736 105 -1552 51 -8460 57 -5224 101 -244 121 -4124 103 -10775 133 -1858 73 -20679 51 -5532 97 -1718 103 -3764 51 -6496 79 -792 53 -13269 81 -18787 57 -9140 83 -3302 53 -11039 55 -26162 79 -1713 103 -5860 53 -9589 55 -8389 81 -254 85 -16287 73 -8336 53 -6237 75 -828 55 -19389 73 -8028 79 -6284 83 -3460 77 -13504 75 -3198 75 -1280 51 -1948 51 -758 79 -22076 75 -1681 73 -21693 57 -8106 53 -838 51 -10074 51 -4760 55 -492 79 -6558 79 -22996 75 -13904 53 -5564 55 -16578 83 -25603 77 -410 75 -16694 81 -606 53 -2987 53 -3898 107 -3248 79 -5168 55 -754 81 -20662 53 -11066 51 -8624 79 -26384 79 -2214 81 -7442 79 -12488 53 -1656 71 -4508 55 -15680 57 -6669 51 -5410 71 -6411 53 -6082 79 -13772 53 -5945 55 -574 73 -11921 51 -3472 55 -2323 55 -10414 51 -16069 81 -2678 77 -10775 53 -2106 110 -11794 55 -17082 51 -6184 71 -8376 79 -7152 77 -2691 53 -6332 53 -2074 57 -6804 51 -166 53 -2254 53 -452 51 -6771 53 -42749 53 -6658 73 -2034 111 -3440 109 -626 53 -7291 85 -2546 53 -5287 51 -9902 53 -10040 53 -366 79 -13848 51 -3739 77 -47536 51 -354 77 -228 77 -712 53 -530 53 -162 55 -12640 71 -1708 51 -1034 77 -12891 79 -3334 51 -7644 79 -12676 81 -3036 53 -2038 53 -180 57 -818 55 -21459 71 -3009 51 -6572 53 -4015 105 -642 77 -23618 53 -4921 83 -3026 73 -3672 53 -12654 81 -8632 51 -9419 171 -19195 105 -13041 55 -21910 51 -1051 77 -10292 51 -12884 51 -6589 53 -8718 51 -2510 103 -15406 55 -6014 99 -966 73 -2725 53 -12715 51 -4228 55 -3192 57 -8672 51 -14740 51 -17032 75 -11111 1761 -182 399 -106 215 -270 355 -132 329 -150 177 -312 315 -170 169 -290 331 -162 173 -286 187 -312 163 -300 329 -164 311 -162 171 -316 289 -176 297 -194 311 -164 143 -324 167 -314 163 -310 161 -312 163 -300 175 -300 331 -162 173 -312 161 -312 163 -314 161 -298 189 -300 165 -312 161 -312 189 -276 173 -316 193 -310 163 -312 161 -310 163 -300 175 -296 193 -284 191 -284 187 -310 163 -300 175 -300 169 -320 177 -314 485 -464 177 -292 353 -134
+RAW_Data: 171 -316 311 -154 187 -292 343 -134 337 -136 199 -286 311 -182 157 -294 327 -160 171 -316 161 -312 159 -314 333 -170 311 -164 141 -324 305 -164 299 -176 301 -170 167 -340 133 -338 163 -312 159 -294 189 -298 165 -314 311 -180 155 -294 189 -300 165 -312 187 -284 189 -312 159 -294 189 -296 167 -314 161 -310 189 -312 159 -292 189 -296 167 -312 161 -312 159 -314 193 -268 175 -304 193 -314 163 -312 159 -312 193 -294 495 -458 161 -338 301 -168 165 -304 331 -134 199 -286 309 -184 309 -170 141 -318 331 -162 143 -316 309 -182 157 -294 189 -302 163 -312 309 -184 311 -170 141 -318 331 -162 299 -150 319 -196 139 -314 165 -334 137 -340 159 -312 161 -302 149 -318 331 -162 173 -312 161 -312 163 -300 175 -296 195 -310 163 -312 159 -312 163 -312 159 -296 189 -300 193 -284 187 -284 189 -312 159 -292 189 -298 167 -312 161 -312 189 -300 173 -294 195 -282 191 -310 485 -472 167 -300 331 -134 171 -312 333 -170 169 -290 331 -162 299 -176 155 -300 333 -162 171 -300 323 -150 145 -340 159 -320 167 -302 319 -150 319 -166 169 -312 331 -162 299 -150 319 -194 139 -314 165 -308 163 -340 133 -338 163 -312 157 -296 327 -160 171 -316 163 -310 161 -312 163 -298 177 -302 193 -314 163 -310 161 -312 163 -300 173 -300 169 -318 177 -290 189 -300 165 -312 161 -312 189 -284 185 -292 189 -300 191 -286 187 -284 191 -312 471 -486 167 -314 313 -152 159 -300 335 -162 169 -308 319 -150 319 -166 169 -312 331 -162 143 -314 311 -180 157 -294 189 -300 165 -314 309 -182 311 -168 141 -318 333 -162 299 -174 295 -194 141 -314 165 -336 137 -338 135 -338 161 -312 159 -294 327 -160 171 -316 161 -312 159 -314 191 -270 201 -278 193 -314 163 -310 161 -312 163 -300 175 -300 169 -316 177 -292 189 -300 165 -312 161 -312 189 -284 183 -294 189 -298 193 -284 187 -312 163 -312 497 -460 145 -320 325 -168 171 -290 333 -162 171 -314 305 -160 317 -168 169 -290 333 -162 173 -312 283 -182 159 -294 189 -302 165 -312 309 -182 313 -168 143 -318 331 -162 301 -148 321 -194 141 -312 167 -334 135 -340 161 -310 163 -312 159 -294 327 -160 171 -316 163 -310 161 -312 163 -300 175 -302 195 -312 163 -312 159 -312 163 -300 175 -298 169 -318 177 -290 191 -300 165 -312 161 -310 189 -284 185 -292 189 -300 191 -286 187 -312 161 -300 487 -484 151 -318 335 -138 169 -322 305 -164 171 -314 305 -190 295 -166 171 -290 333 -162 173 -312 283 -182 159 -296 191 -300
+RAW_Data: 165 -312 333 -160 311 -170 141 -318 331 -164 299 -148 321 -194 139 -316 165 -336 135 -340 133 -338 163 -300 149 -320 329 -164 171 -314 159 -312 163 -300 175 -298 193 -310 163 -312 159 -312 163 -300 175 -296 193 -312 163 -312 159 -312 163 -300 175 -298 167 -320 175 -290 191 -296 193 -286 187 -310 163 -300 175 -296 501 -458 187 -288 347 -154 151 -316 325 -162 171 -316 313 -152 301 -194 141 -316 331 -162 143 -314 311 -182 155 -294 189 -302 163 -314 309 -182 311 -168 143 -318 331 -162 301 -174 295 -194 141 -314 165 -336 135 -340 133 -338 163 -312 159 -294 327 -158 173 -314 163 -312 159 -306 173 -314 165 -306 191 -284 189 -284 189 -312 157 -294 191 -300 163 -314 187 -284 189 -284 187 -292 189 -296 165 -314 161 -312 189 -284 185 -294 189 -298 193 -286 485 -492 167 -298 323 -150 175 -302 331 -164 171 -300 321 -150 317 -166 167 -308 331 -134 171 -316 309 -182 129 -318 189 -302 163 -314 309 -182 311 -170 141 -318 331 -162 301 -148 321 -194 139 -314 167 -334 137 -338 161 -310 163 -312 159 -294 327 -160 171 -316 161 -312 159 -312 193 -270 175 -304 193 -314 163 -312 159 -312 161 -314 161 -296 189 -304 165 -312 187 -284 189 -276 173 -318 195 -278 193 -284 187 -312 163 -300 175 -298 169 -318 511 -460 147 -318 327 -168 169 -292 331 -164 171 -314 305 -160 315 -168 171 -290 333 -162 171 -314 283 -182 159 -294 189 -300 165 -314 307 -184 311 -170 141 -318 333 -162 299 -150 319 -194 141 -314 165 -336 135 -340 133 -338 163 -312 157 -294 327 -160 171 -316 163 -310 161 -304 175 -314 167 -304 191 -286 187 -284 189 -284 187 -292 189 -300 165 -312 189 -284 187 -286 185 -294 189 -296 165 -314 161 -312 187 -286 185 -294 189 -298 193 -284 485 -494 167 -298 321 -150 177 -312 313 -168 171 -292 331 -164 299 -174 151 -316 325 -162 171 -316 289 -176 151 -316 187 -296 167 -312 311 -180 307 -170 141 -318 331 -162 299 -150 319 -196 139 -314 165 -334 137 -340 159 -312 161 -302 149 -320 329 -164 171 -314 159 -312 163 -300 175 -298 193 -310 163 -312 161 -310 163 -312 161 -296 189 -302 191 -286 187 -284 189 -312 159 -292 189 -296 167 -314 161 -310 189 -284 187 -292 189 -300 193 -284 485 -494 167 -296 323 -150 175 -312 313 -170 169 -292 333 -162 299 -176 151 -314 327 -160 171 -316 291 -176 149 -316 189 -296 165 -314 309 -182 307 -168 141 -318 331 -164 299 -148 321 -194 141 -314 165 -334 137 -338 161 -312
+RAW_Data: 161 -302 147 -320 331 -162 171 -314 161 -312 163 -300 175 -296 195 -310 163 -312 159 -312 163 -300 173 -296 193 -312 163 -312 159 -312 163 -300 175 -298 169 -318 177 -290 191 -296 195 -284 189 -284 189 -312 159 -296 513 -468 159 -300 333 -162 171 -300 323 -150 171 -314 325 -162 311 -164 171 -314 305 -160 159 -296 327 -160 171 -316 161 -312 161 -312 335 -170 311 -164 141 -324 321 -154 299 -194 309 -164 143 -326 167 -314 161 -312 159 -312 163 -302 173 -300 331 -162 173 -312 161 -312 163 -300 175 -300 167 -320 153 -312 191 -296 167 -312 161 -312 189 -312 159 -292 189 -298 167 -312 161 -312 159 -314 193 -268 177 -302 193 -316 161 -312 159 -312 193 -294 497 -456 187 -312 303 -166 165 -306 331 -132 201 -286 309 -182 313 -168 143 -318 331 -162 143 -314 311 -182 157 -294 189 -302 165 -312 309 -182 311 -170 141 -318 333 -162 299 -150 319 -194 141 -314 165 -334 137 -338 161 -312 161 -300 149 -320 331 -162 171 -314 161 -310 163 -302 173 -298 193 -310 165 -310 161 -310 163 -312 161 -296 189 -300 193 -286 187 -284 189 -312 157 -294 189 -298 165 -314 161 -310 189 -284 187 -292 189 -300 193 -284 485 -494 167 -298 321 -150 171 -318 323 -162 171 -314 289 -176 297 -194 141 -314 331 -162 143 -316 309 -182 155 -294 189 -302 163 -314 309 -182 311 -168 143 -318 331 -162 301 -148 321 -194 139 -314 167 -334 137 -338 161 -310 163 -300 149 -320 331 -162 171 -314 161 -312 163 -300 173 -298 193 -310 163 -312 159 -312 163 -300 175 -296 193 -312 163 -312 159 -312 163 -300 175 -298 167 -320 175 -290 191 -296 193 -286 187 -310 163 -312 161 -296 513 -468 159 -300 333 -162 171 -302 321 -150 175 -300 333 -162 311 -162 171 -316 289 -176 153 -314 327 -160 171 -316 163 -312 159 -312 307 -168 335 -138 169 -320 307 -164 297 -176 301 -194 141 -318 165 -336 137 -338 133 -338 163 -312 159 -294 327 -160 171 -316 161 -312 161 -312 163 -298 177 -302 169 -318 177 -292 189 -298 167 -312 189 -284 189 -312 157 -294 189 -298 167 -312 161 -312 159 -312 193 -270 203 -302 169 -314 161 -312 189 -310 467 -484 145 -318 327 -168 143 -316 331 -162 173 -312 307 -160 313 -170 141 -318 331 -164 143 -342 281 -184 157 -294 189 -302 165 -312 307 -184 313 -168 141 -320 331 -162 299 -150 319 -194 141 -314 165 -336 137 -338 135 -338 161 -312 159 -294 327 -158 173 -314 163 -310 161 -312 165 -298 175 -304 193 -312 163 -312 159 -312
+RAW_Data: 163 -300 175 -298 169 -318 177 -290 191 -298 165 -314 161 -310 189 -284 185 -292 189 -298 193 -284 189 -310 163 -312 497 -460 145 -320 325 -170 169 -290 333 -162 171 -314 307 -158 317 -168 169 -290 333 -162 171 -314 281 -182 159 -296 189 -300 165 -312 309 -182 313 -168 143 -318 331 -162 301 -148 319 -196 139 -314 165 -336 137 -338 135 -338 161 -312 159 -294 327 -160 173 -314 163 -312 159 -312 163 -300 175 -302 195 -312 163 -312 159 -312 163 -300 175 -298 169 -318 175 -292 189 -300 165 -312 161 -312 187 -284 185 -292 189 -300 193 -284 187 -312 161 -314 471 -486 167 -314 313 -152 159 -300 335 -162 169 -308 321 -156 329 -170 127 -318 321 -176 155 -300 333 -164 169 -302 165 -314 161 -310 329 -168 299 -166 151 -328 311 -154 331 -168 299 -178 143 -318 153 -322 167 -332 149 -320 151 -318 165 -304 321 -156 181 -290 189 -300 173 -294 177 -294 189 -302 173 -294 177 -294 189 -302 173 -294 177 -318 193 -278 173 -294 179 -292 191 -302 173 -294 177 -294 189 -302 173 -320 177 -294 195 -278 175 -318 491 -460 163 -314 333 -158 159 -294 327 -160 171 -316 311 -180 307 -170 141 -318 331 -162 143 -316 309 -182 157 -294 189 -302 165 -312 309 -182 313 -168 141 -318 331 -164 299 -148 321 -194 141 -314 165 -334 137 -338 135 -338 161 -312 159 -294 329 -158 173 -314 163 -310 161 -306 173 -314 165 -304 193 -284 187 -286 189 -276 197 -294 193 -310 163 -312 161 -310 163 -300 175 -296 193 -310 165 -284 187 -310 163 -300 175 -300 169 -318 177 -316 483 -466 187 -292 341 -134 171 -308 319 -150 179 -300 333 -164 309 -162 171 -316 313 -152 153 -316 327 -160 171 -316 163 -310 161 -312 307 -166 337 -136 171 -322 305 -164 299 -174 301 -194 141 -318 165 -336 137 -338 161 -310 163 -300 149 -320 331 -162 171 -314 161 -312 163 -300 173 -296 195 -310 163 -312 159 -312 163 -312 159 -296 189 -302 165 -312 189 -284 189 -284 185 -294 189 -296 165 -314 161 -310 189 -284 187 -294 189 -298 193 -284 485 -494 167 -298 321 -150 177 -312 313 -168 171 -290 333 -162 299 -176 151 -316 325 -162 171 -316 289 -176 151 -314 189 -296 165 -314 309 -182 305 -170 141 -318 333 -162 299 -150 319 -194 141 -314 165 -334 137 -340 133 -338 161 -302 149 -320 329 -164 171 -286 187 -312 163 -300 173 -298 193 -310 163 -312 159 -312 163 -312 159 -296 189 -302 191 -286 187 -284 189 -312 159 -292 191 -296 165 -314 161 -310 189 -284 187 -292
+RAW_Data: 189 -300 193 -284 485 -494 167 -298 321 -150 177 -300 327 -150 167 -328 305 -160 319 -168 171 -290 333 -162 171 -314 281 -184 159 -296 189 -300 165 -314 307 -184 311 -170 141 -318 333 -162 299 -150 319 -194 139 -314 167 -334 135 -340 133 -338 163 -312 159 -294 327 -158 173 -314 163 -312 159 -312 165 -298 177 -302 193 -314 163 -310 161 -312 163 -300 173 -300 167 -318 177 -292 189 -300 165 -312 161 -312 187 -284 185 -292 189 -300 191 -286 187 -284 189 -300 487 -484 149 -320 333 -138 171 -322 321 -154 151 -316 327 -160 311 -164 173 -312 307 -160 161 -298 355 -132 173 -314 163 -310 161 -312 335 -170 311 -164 143 -322 307 -164 323 -150 301 -196 141 -318 165 -334 137 -338 161 -312 161 -302 147 -320 331 -162 173 -312 161 -312 163 -300 173 -298 195 -310 163 -312 159 -312 163 -312 159 -296 189 -300 193 -284 189 -284 189 -284 185 -294 189 -296 165 -314 161 -312 189 -284 185 -294 189 -298 193 -286 485 -468 193 -296 323 -150 147 -340 313 -168 171 -292 331 -164 299 -174 151 -316 325 -160 173 -316 289 -176 149 -316 189 -294 165 -314 309 -182 307 -170 141 -318 331 -164 299 -148 321 -194 139 -314 167 -306 165 -338 133 -338 163 -312 159 -294 327 -160 173 -314 163 -312 161 -310 165 -300 175 -300 169 -318 177 -290 189 -298 165 -314 187 -284 189 -312 159 -294 189 -298 165 -314 161 -310 161 -306 173 -316 193 -280 191 -312 159 -312 163 -300 515 -460 161 -312 305 -190 135 -328 329 -134 201 -286 309 -182 311 -168 143 -318 331 -162 143 -316 309 -182 157 -294 189 -300 165 -312 309 -184 311 -168 143 -318 331 -162 301 -148 319 -196 139 -314 165 -334 137 -340 159 -312 163 -300 149 -318 331 -162 173 -312 161 -312 163 -300 175 -296 195 -310 163 -312 159 -312 163 -300 173 -296 193 -312 163 -312 159 -312 163 -312 161 -298 189 -300 165 -312 161 -312 189 -312 159 -292 191 -300 191 -286 485 -468 193 -298 323 -148 147 -342 323 -160 173 -314 289 -176 297 -196 139 -314 331 -162 143 -314 311 -180 157 -292 191 -300 165 -312 311 -182 309 -170 141 -318 333 -162 299 -150 319 -194 141 -314 165 -334 137 -338 161 -312 161 -312 159 -294 329 -158 173 -314 163 -310 161 -312 165 -298 175 -304 193 -312 163 -310 161 -310 163 -302 173 -300 169 -318 175 -292 189 -300 165 -312 161 -310 189 -278 173 -316 195 -280 191 -312 159 -312 163 -300 515 -460 163 -310 305 -190 137 -328 329 -134 199 -288 309 -182 311 -168 143 -318
+RAW_Data: 331 -162 143 -316 309 -182 157 -292 191 -300 165 -312 309 -182 313 -168 141 -318 331 -164 299 -174 295 -194 141 -314 165 -334 137 -340 133 -338 163 -312 159 -292 327 -160 171 -316 163 -310 161 -312 165 -298 175 -304 193 -312 163 -312 159 -312 163 -300 175 -300 169 -316 177 -292 189 -298 167 -312 161 -310 189 -278 173 -316 193 -282 191 -312 159 -312 163 -300 515 -460 163 -310 305 -190 137 -326 331 -132 201 -286 309 -184 309 -170 141 -318 333 -162 143 -314 311 -180 159 -294 189 -300 165 -312 309 -184 311 -168 143 -318 331 -162 301 -148 319 -196 139 -314 165 -336 135 -340 159 -312 163 -300 149 -320 329 -164 171 -314 159 -312 163 -300 175 -296 195 -310 163 -312 159 -312 163 -300 175 -294 195 -310 163 -312 161 -310 163 -300 175 -298 169 -318 153 -314 191 -296 193 -286 187 -284 189 -312 161 -294 509 -468 159 -298 335 -162 169 -304 323 -150 175 -300 335 -162 311 -160 173 -316 313 -152 151 -316 327 -160 171 -316 163 -312 159 -312 307 -168 335 -138 169 -322 305 -164 299 -176 299 -194 141 -316 167 -334 137 -340 159 -312 161 -302 147 -320 331 -162 173 -312 161 -312 163 -300 175 -296 193 -310 165 -310 161 -312 161 -302 173 -296 195 -310 163 -312 161 -310 163 -300 175 -298 169 -318 177 -290 189 -296 193 -286 187 -310 163 -300 175 -296 501 -484 161 -288 347 -154 151 -316 325 -160 173 -314 313 -152 301 -196 141 -314 331 -162 143 -316 309 -182 157 -294 189 -300 165 -314 309 -182 311 -168 143 -318 331 -162 301 -148 319 -196 139 -314 165 -336 137 -338 133 -338 163 -312 159 -294 327 -158 173 -316 161 -312 159 -312 163 -298 177 -302 193 -314 163 -312 159 -312 163 -300 175 -298 169 -318 177 -290 191 -298 165 -314 161 -310 189 -284 193 -292 179 -308 167 -314 161 -312 189 -302 481 -460 173 -320 303 -168 169 -294 331 -164 171 -314 307 -160 319 -168 169 -292 331 -162 143 -342 283 -182 159 -294 189 -302 165 -312 309 -184 311 -168 143 -318 331 -162 299 -150 319 -194 141 -314 165 -336 135 -340 133 -338 163 -312 159 -294 327 -158 173 -316 161 -312 159 -312 165 -298 177 -302 193 -312 163 -312 161 -310 163 -314 161 -296 189 -302 165 -312 187 -284 189 -284 185 -294 189 -296 165 -314 187 -284 189 -302 173 -294 195 -310 491 -458 163 -318 319 -156 153 -314 327 -160 171 -316 311 -152 327 -170 141 -316 331 -164 143 -314 309 -182 157 -294 189 -300 165 -314 309 -182 311 -168 143 -316 333 -162 299 -150
+RAW_Data: 319 -194 141 -314 165 -336 135 -340 133 -338 163 -312 159 -294 327 -160 171 -316 161 -312 159 -314 163 -300 175 -302 193 -314 163 -310 161 -310 163 -300 175 -300 167 -318 177 -290 191 -300 165 -312 161 -312 187 -284 185 -292 189 -300 191 -286 187 -310 163 -300 487 -484 149 -320 335 -138 169 -322 305 -164 171 -314 305 -190 293 -168 169 -292 333 -162 171 -314 281 -184 159 -296 189 -300 165 -312 309 -184 311 -170 141 -318 331 -162 299 -150 319 -196 139 -314 165 -336 137 -338 133 -338 163 -312 159 -294 327 -160 171 -316 161 -312 159 -312 165 -298 177 -302 193 -314 163 -310 161 -310 163 -314 161 -296 189 -302 165 -312 187 -286 189 -276 173 -318 193 -280 191 -284 189 -310 163 -300 175 -300 167 -318 513 -460 167 -314 311 -152 161 -324 311 -162 169 -310 329 -160 293 -190 137 -330 329 -132 173 -316 311 -180 129 -318 189 -300 165 -312 309 -182 311 -168 141 -320 329 -164 299 -174 295 -194 141 -314 167 -334 137 -340 133 -338 161 -312 159 -294 329 -158 173 -314 163 -310 161 -312 163 -300 175 -302 195 -312 163 -312 159 -312 163 -300 175 -298 169 -318 177 -290 189 -300 165 -312 161 -312 189 -284 183 -292 189 -300 193 -284 187 -284 189 -314 471 -486 145 -318 327 -168 171 -290 331 -162 173 -312 307 -158 317 -168 169 -290 333 -162 143 -342 283 -182 159 -294 189 -300 165 -312 309 -182 313 -168 143 -318 331 -162 299 -176 293 -196 139 -314 167 -334 137 -338 161 -310 163 -300 149 -320 331 -162 171 -314 161 -312 163 -300 173 -296 195 -310 163 -312 159 -312 163 -312 159 -296 189 -302 193 -284 187 -284 189 -302 149 -318 193 -280 191 -284 189 -284 189 -300 173 -300 169 -316 177 -316 483 -476 153 -320 329 -134 201 -286 309 -182 157 -294 355 -132 339 -136 169 -320 315 -162 171 -302 323 -148 171 -318 159 -318 147 -318 327 -168 313 -164 169 -302 321 -150 317 -166 305 -164 169 -324 169 -314 163 -310 161 -310 163 -300 175 -296 331 -164 171 -314 161 -312 163 -300 175 -298 195 -310 163 -312 159 -312 163 -300 173 -296 193 -312 163 -312 159 -312 163 -300 175 -298 169 -318 177 -290 189 -298 195 -284 187 -284 189 -314 159 -294 513 -470 159 -300 333 -162 171 -300 323 -150 169 -316 325 -160 311 -164 173 -312 307 -158 161 -294 329 -158 173 -314 163 -312 159 -312 335 -170 311 -164 141 -324 305 -164 323 -152 301 -194 141 -318 165 -336 137 -338 161 -312 161 -312 159 -294 329 -158 173 -314 163 -310 161 -312
+RAW_Data: 165 -298 175 -304 169 -318 175 -290 191 -298 165 -314 187 -284 189 -312 159 -294 191 -296 167 -312 161 -312 159 -314 193 -270 201 -304 167 -314 163 -312 159 -312 493 -486 145 -318 325 -170 141 -316 331 -162 173 -314 305 -160 313 -170 141 -318 331 -162 143 -342 283 -182 159 -294 189 -302 165 -312 309 -182 313 -168 141 -318 331 -162 301 -148 321 -194 141 -314 165 -334 137 -340 159 -312 161 -302 147 -320 331 -162 173 -312 161 -312 163 -300 175 -296 193 -310 165 -310 161 -310 163 -302 173 -296 193 -312 161 -312 159 -312 163 -300 175 -300 167 -320 177 -290 189 -298 193 -286 187 -284 189 -312 161 -294 513 -468 159 -300 333 -162 171 -302 321 -150 171 -316 323 -162 311 -164 171 -314 307 -158 159 -296 327 -160 171 -316 163 -310 161 -306 321 -168 339 -134 171 -306 321 -150 317 -166 337 -164 143 -324 167 -314 163 -312 159 -312 163 -300 175 -298 331 -162 173 -312 161 -312 163 -300 175 -300 193 -310 163 -312 161 -310 163 -312 161 -296 189 -300 193 -284 189 -284 189 -284 185 -294 189 -296 165 -314 161 -312 187 -286 185 -292 191 -298 193 -284 485 -494 167 -298 321 -150 177 -312 313 -146 167 -344 305 -158 315 -168 143 -318 331 -162 143 -342 283 -182 159 -294 189 -302 163 -314 307 -184 311 -168 141 -318 333 -162 299 -174 295 -194 141 -314 167 -334 137 -338 161 -312 161 -312 159 -294 329 -160 171 -316 163 -310 161 -312 163 -300 175 -302 169 -318 175 -290 191 -298 165 -312 189 -284 189 -312 159 -292 189 -298 165 -314 161 -312 189 -282 195 -268 203 -304 169 -312 163 -312 187 -278 507 -460 173 -320 303 -166 171 -294 331 -164 171 -314 305 -160 319 -168 169 -292 331 -164 171 -314 281 -182 159 -294 191 -300 165 -312 309 -182 313 -168 143 -318 331 -162 301 -148 319 -196 139 -314 165 -336 135 -340 133 -338 163 -312 159 -294 327 -160 171 -316 161 -312 159 -314 163 -300 175 -302 193 -312 163 -312 159 -312 163 -300 175 -298 169 -318 177 -292 189 -300 165 -312 161 -310 189 -284 193 -292 179 -308 167 -314 161 -312 189 -302 483 -458 173 -320 303 -168 169 -294 331 -164 171 -314 307 -158 319 -168 169 -292 331 -164 171 -314 283 -182 159 -294 191 -300 165 -312 309 -182 313 -168 143 -316 331 -164 299 -150 319 -194 141 -314 165 -334 137 -340 133 -338 161 -312 159 -294 327 -160 171 -316 161 -312 159 -314 163 -298 177 -304 193 -312 163 -312 161 -310 163 -314 161 -296 189 -302 163 -314 161 -310 189 -284
+RAW_Data: 185 -294 189 -296 165 -314 189 -284 189 -312 157 -294 189 -300 497 -456 189 -284 345 -154 153 -316 325 -160 173 -314 315 -150 325 -170 141 -314 331 -164 143 -314 309 -182 157 -294 189 -302 163 -314 307 -184 311 -168 141 -318 333 -162 299 -174 295 -194 141 -314 165 -334 137 -340 159 -312 163 -300 149 -318 331 -164 171 -314 159 -312 163 -300 175 -298 193 -310 163 -312 159 -312 163 -312 159 -296 189 -300 165 -314 187 -284 189 -312 157 -294 189 -298 165 -314 161 -310 189 -284 187 -292 189 -300 193 -284 485 -468 193 -296 323 -150 175 -312 313 -168 171 -292 331 -164 299 -176 149 -316 325 -162 171 -316 289 -176 151 -314 189 -296 165 -314 309 -182 307 -168 143 -316 331 -164 299 -150 319 -194 141 -312 167 -334 137 -338 161 -310 163 -300 149 -320 331 -162 171 -314 161 -312 163 -300 173 -298 193 -310 163 -312 159 -312 163 -300 173 -296 169 -318 177 -292 189 -300 165 -312 161 -312 189 -284 183 -294 189 -294 195 -284 187 -284 191 -300 173 -296 499 -482 163 -314 321 -154 153 -316 325 -160 173 -314 313 -152 301 -196 139 -316 331 -162 143 -314 311 -182 155 -294 189 -302 163 -314 309 -182 311 -168 143 -318 331 -162 301 -148 319 -196 139 -314 165 -336 135 -340 159 -312 163 -300 149 -320 329 -164 171 -314 159 -312 163 -300 175 -296 193 -310 165 -310 161 -312 161 -302 173 -296 169 -316 177 -292 189 -300 165 -314 161 -310 189 -284 185 -292 189 -296 193 -286 187 -284 189 -300 175 -294 499 -482 163 -314 321 -154 153 -316 325 -160 171 -316 313 -152 325 -170 141 -314 331 -164 143 -314 311 -180 157 -294 191 -300 165 -312 309 -182 311 -168 141 -320 329 -164 299 -174 295 -194 141 -314 165 -336 135 -340 133 -338 163 -312 159 -294 327 -160 173 -314 163 -312 159 -312 163 -300 175 -302 195 -310 163 -312 159 -312 163 -300 175 -298 169 -318 177 -292 189 -298 165 -314 161 -310 189 -284 185 -292 189 -298 193 -284 187 -286 189 -312 471 -486 145 -320 325 -168 171 -290 331 -162 173 -312 307 -160 315 -168 169 -292 331 -162 143 -342 283 -182 159 -294 189 -302 165 -312 309 -182 311 -170 141 -318 331 -164 299 -148 319 -196 139 -314 167 -334 135 -340 161 -310 163 -300 149 -320 331 -162 171 -314 161 -310 163 -314 161 -296 189 -296 165 -314 161 -310 189 -284 185 -292 189 -298 165 -312 161 -312 189 -276 173 -318 193 -278 191 -286 187 -284 189 -300 175 -298 169 -318 177 -314 483 -466 187 -294 339 -136 169 -306
+RAW_Data: 321 -150 177 -300 333 -164 311 -160 173 -314 313 -152 155 -314 327 -160 171 -316 163 -312 159 -312 307 -166 337 -138 169 -322 305 -164 299 -176 301 -194 141 -316 165 -336 137 -338 161 -310 163 -300 149 -320 331 -162 171 -314 161 -312 163 -300 173 -298 193 -310 163 -312 159 -312 163 -300 175 -294 169 -318 177 -292 189 -300 165 -312 161 -312 189 -284 183 -292 189 -296 193 -286 187 -284 189 -302 173 -296 499 -458 187 -312 321 -154 153 -316 325 -162 171 -316 313 -152 301 -194 141 -314 331 -162 143 -316 309 -182 157 -292 189 -302 163 -314 309 -182 311 -170 141 -318 331 -162 311 -160 295 -190 163 -302 165 -304 165 -312 161 -338 163 -312 157 -294 327 -160 171 -316 161 -312 159 -312 165 -298 177 -302 193 -312 163 -312 159 -312 163 -300 175 -298 169 -318 177 -290 191 -298 165 -314 159 -312 189 -284 185 -290 189 -300 193 -284 189 -284 189 -312 471 -460 483 -2128 125 -52 75 -102 75 -154 101 -100 147 -272 149 -328 75 -228 511 -441 77 -212 87 -114 189 -54 263 -156 171 -393 127 -102 183 -110 293 -242 395 -320 107 -52 81 -346 53 -572 155 -381 305 -234 101 -126 228 -156 195 -102 281 -126 518 -52 313 -240 187 -54 79 -316 133 -136 213 -108 79 -80 185 -464 181 -76 379 -80 81 -506 233 -318 103 -78 53 -559 51 -240 53 -106 207 -136 163 -136 81 -218 187 -104 349 -266 51 -266 129 -80 107 -450 131 -331 127 -359 641 -108 472 -100 547 -82 79 -246 107 -560 567 -130 403 -389 149 -179 77 -526 235 -108 81 -78 51 -455 75 -106 105 -240 101 -557 183 -184 255 -102 311 -130 147 -174 457 -354 75 -442 81 -344 331 -76 51 -106 133 -54 161 -560 77 -130 77 -294 257 -52 99 -126 73 -565 51 -242 131 -497 55 -354 347 -404 81 -108 540 -286 185 -465 219 -264 296 -106 77 -294 193 -110 567 -52 287 -134 53 -106 55 -330 263 -210 83 -86 109 -134 349 -80 221 -80 207 -260 279 -76 75 -74 75 -76 99 -130 443 -78 77 -338 129 -226 179 -280 129 -228 75 -617 185 -324 423 -160 259 -673 159 -188 362 -212 205 -383 151 -316 235 -240 183 -188 79 -56 107 -80 53 -154 417 -158 211 -238 109 -80 79 -218 215 -108 105 -354 215 -112 191 -56 103 -132 77 -236 605 -152 51 -78 185 -78 127 -126 551 -156 135 -186 127 -724 131 -56 81 -378 345 -182 109 -316 107 -316 337 -128 151 -294 101 -1002 101 -52 335 -256 51 -330 81 -448 153 -158 127 -272 131 -160 105 -220 767 -132
+RAW_Data: 75 -210 131 -78 181 -243 345 -108 107 -80 105 -160 107 -218 127 -82 537 -266 239 -340 181 -76 105 -78 421 -482 53 -132 321 -134 51 -262 77 -480 103 -271 475 -154 159 -80 313 -132 79 -282 235 -126 75 -202 175 -226 151 -198 901 -210 51 -78 235 -348 79 -130 103 -584 107 -456 105 -54 431 -54 79 -106 133 -242 105 -486 155 -104 129 -228 147 -100 77 -618 357 -154 531 -104 51 -160 105 -136 109 -140 269 -366 51 -832 53 -270 135 -108 51 -186 51 -160 535 -130 77 -296 51 -182 131 -106 341 -56 135 -194 530 -294 181 -562 75 -179 127 -364 207 -74 125 -332 149 -76 129 -102 103 -102 51 -128 173 -122 482 -474 229 -200 97 -790 105 -104 79 -104 341 -262 101 -110 111 -82 109 -433 271 -210 51 -346 245 -54 209 -284 157 -106 293 -234 77 -826 157 -52 127 -228 299 -490 159 -140 137 -164 247 -294 135 -52 131 -266 77 -128 385 -158 81 -276 356 -476 53 -170 55 -463 79 -190 53 -808 51 -80 159 -106 161 -162 83 -225 187 -341 101 -520 159 -54 428 -182 341 -108 79 -274 77 -108 431 -392 77 -132 131 -138 83 -58 135 -274 305 -300 83 -398 79 -534 131 -528 263 -52 261 -264 437 -342 77 -102 389 -332 103 -130 131 -322 105 -106 53 -134 183 -188 79 -82 81 -104 53 -316 269 -56 347 -286 341 -270 161 -52 131 -136 223 -110 341 -318 469 -138 143 -110 83 -80 53 -54 183 -346 385 -906 51 -382 75 -154 51 -52 207 -186 53 -78 51 -106 293 -52 155 -126 306 -130 412 -416 187 -82 339 -160 135 -194 163 -136 81 -78 281 -426 229 -76 227 -532 177 -528 51 -244 269 -616 75 -52 418 -136 53 -82 51 -154 97 -126 233 -52 51 -740 77 -162 81 -304 263 -162 217 -448 275 -164 185 -138 139 -54 277 -348 531 -642 376 -274 267 -182 75 -126 103 -615 103 -236 81 -380 77 -52 241 -80 105 -438 111 -192 181 -54 135 -186 113 -58 243 -140 57 -385 189 -158 133 -675 231 -80 241 -236 131 -106 109 -108 55 -136 555 -132 303 -494 341 -316 135 -112 302 -366 97 -98 101 -310 177 -78 427 -297 151 -579 163 -314 129 -78 51 -233 105 -210 103 -202 217 -180 121 -229 125 -302 221 -52 235 -158 187 -110 135 -162 51 -108 105 -398 221 -82 297 -110 53 -1400 213 -106 51 -454 723 -368 79 -104 79 -134 81 -323 51 -372 79 -80 235 -132 549 -164 81 -104 129 -602 371 -160 129 -536 179 -234 133 -210 236 -489 159 -52 237 -210 129 -264 53 -242 105 -106 53 -114
+RAW_Data: 193 -290 191 -436 343 -311 207 -322 53 -400 51 -882 135 -678 375 -244 317 -192 380 -558 260 -154 710 -80 237 -218 109 -250 81 -372 107 -160 646 -286 125 -178 269 -726 51 -106 79 -298 523 -682 159 -498 265 -465 127 -592 177 -100 149 -687 103 -78 357 -102 53 -158 105 -240 79 -618 105 -130 79 -478 77 -154 450 -186 53 -192 137 -1038 105 -160 266 -136 51 -345 53 -80 157 -108 235 -102 483 -54 109 -234 327 -376 51 -462 366 -289 163 -108 75 -262 261 -134 81 -78 105 -136 81 -378 105 -272 139 -106 209 -80 205 -184 101 -76 101 -180 229 -427 99 -430 125 -100 103 -469 125 -102 221 -130 209 -106 105 -104 201 -274 332 -232 105 -166 161 -104 275 -80 131 -1000 321 -156 189 -166 81 -130 367 -262 153 -258 75 -260 127 -542 127 -464 107 -80 107 -108 303 -240 77 -238 181 -282 77 -76 224 -104 75 -74 225 -554 131 -56 55 -164 51 -318 247 -130 159 -158 77 -76 285 -354 133 -52 135 -420 155 -256 129 -78 265 -831 103 -231 107 -674 285 -653 337 -102 257 -182 101 -146 147 -303 75 -206 365 -268 157 -54 81 -504 133 -472 107 -82 161 -80 133 -461 81 -825 79 -798 101 -206 207 -80 185 -980 209 -56 247 -246 51 -106 131 -78 79 -236 53 -106 51 -98 101 -206 127 -78 151 -98 279 -155 157 -468 131 -72 173 -372 329 -212 79 -52 101 -375 77 -286 51 -188 185 -308 191 -56 555 -320 179 -86 193 -490 105 -214 81 -138 53 -216 211 -112 57 -134 213 -212 131 -714 73 -128 155 -590 51 -452 189 -261 247 -162 105 -404 167 -56 77 -354 81 -56 215 -316 129 -372 366 -288 133 -56 295 -294 51 -822 53 -482 295 -340 321 -188 459 -631 147 -212 201 -100 173 -258 305 -261 51 -208 97 -124 103 -598 159 -206 77 -710 213 -190 241 -158 133 -186 385 -266 219 -350 133 -52 157 -78 51 -156 403 -162 189 -300 259 -202 103 -760 179 -258 173 -82 431 -164 161 -373 133 -208 191 -82 237 -52 135 -384 131 -192 55 -52 285 -52 79 -274 57 -140 109 -306 53 -132 133 -240 53 -104 51 -214 79 -158 123 -98 99 -126 77 -178 173 -334 178 -518 129 -236 337 -206 230 -100 225 -52 152 -102 103 -308 51 -52 203 -114 139 -318 211 -396 183 -78 51 -106 77 -164 83 -380 133 -234 237 -54 79 -158 83 -84 137 -136 323 -158 365 -128 157 -108 81 -194 109 -618 155 -363 191 -190 109 -110 55 -80 163 -224 79 -82 105 -270 133 -314 159 -106 153 -356 77 -76 75 -458 149 -74
+RAW_Data: 101 -128 53 -130 153 -212 447 -230 171 -636 75 -98 324 -362 51 -160 217 -218 51 -310 101 -152 379 -280 151 -176 203 -210 51 -130 336 -232 179 -596 629 -298 55 -1302 261 -108 109 -80 77 -162 237 -52 125 -52 75 -100 125 -148 297 -426 107 -110 133 -238 155 -228 123 -100 247 -74 179 -126 99 -148 99 -134 81 -194 81 -248 53 -164 135 -82 109 -717 53 -220 81 -234 79 -344 53 -474 79 -154 51 -618 109 -142 83 -593 135 -134 105 -136 81 -243 413 -228 121 -174 125 -328 53 -658 361 -74 401 -280 131 -132 85 -56 139 -298 157 -481 51 -52 129 -76 75 -152 127 -507 321 -486 185 -264 103 -54 325 -76 183 -104 53 -246 81 -78 185 -210 155 -112 55 -80 77 -720 103 -54 51 -450 51 -104 107 -246 185 -78 267 -482 221 -580 113 -222 365 -80 135 -138 199 -296 261 -164 107 -80 131 -134 107 -272 323 -1120 51 -476 81 -106 211 -132 107 -352 183 -134 133 -108 215 -220 55 -666 131 -218 79 -82 253 -56 103 -52 235 -106 103 -134 185 -532 111 -188 361 -399 183 -693 238 -104 567 -106 113 -280 107 -52 287 -106 161 -908 103 -376 339 -180 73 -200 101 -330 209 -54 107 -220 315 -132 216 -138 159 -438 135 -190 73 -130 510 -244 53 -294 81 -84 171 -138 53 -460 515 -82 219 -315 291 -54 107 -270 107 -54 53 -160 79 -374 209 -154 97 -74 233 -454 125 -144 119 -96 99 -542 75 -1200 103 -204 99 -172 95 -98 127 -78 75 -102 103 -320 241 -820 77 -78 105 -326 135 -264 53 -216 133 -517 211 -228 103 -52 257 -455 127 -74 77 -78 235 -436 151 -102 75 -152 75 -76 75 -303 51 -254 177 -284 103 -152 207 -156 79 -302 53 -610 79 -214 133 -80 243 -110 107 -108 185 -286 155 -212 187 -384 75 -128 77 -80 129 -130 99 -76 156 -104 185 -82 81 -242 217 -380 81 -294 157 -182 161 -134 131 -104 77 -52 181 -150 75 -98 147 -230 129 -760 161 -273 137 -84 111 -674 53 -80 127 -317 265 -210 79 -242 297 -238 75 -328 105 -244 345 -342 131 -254 151 -378 103 -335 101 -288 75 -154 275 -498 75 -224 372 -80 157 -190 395 -268 81 -52 105 -160 277 -510 107 -262 105 -192 109 -188 81 -586 105 -78 123 -98 201 -182 55 -614 101 -170 175 -285 79 -222 191 -658 161 -194 135 -532 107 -810 77 -134 241 -128 147 -150 276 -200 97 -230 157 -104 171 -282 77 -212 77 -80 406 -714 259 -182 131 -128 161 -112 81 -380 79 -290 135 -777 345 -370 385 -178 51 -364
+RAW_Data: 215 -189 53 -108 83 -320 209 -530 51 -265 51 -54 109 -242 351 -362 51 -102 51 -156 173 -247 255 -100 99 -176 99 -52 224 -262 53 -80 279 -356 51 -76 379 -176 75 -220 77 -52 129 -208 129 -304 101 -378 157 -52 53 -102 179 -228 255 -311 131 -192 235 -52 51 -126 273 -721 53 -294 161 -170 55 -376 81 -268 131 -98 129 -268 81 -158 107 -80 161 -214 129 -110 501 -220 185 -688 79 -132 325 -212 53 -295 105 -104 51 -106 79 -372 153 -106 137 -84 193 -741 51 -561 51 -402 390 -126 149 -250 327 -338 177 -202 177 -931 105 -271 423 -768 53 -430 159 -110 217 -104 161 -460 249 -82 79 -186 79 -104 53 -132 79 -218 55 -298 53 -214 81 -354 51 -108 107 -196 273 -80 79 -104 153 -100 175 -76 131 -220 81 -56 131 -368 217 -116 137 -82 169 -342 209 -106 319 -396 75 -104 253 -130 149 -430 127 -130 81 -196 55 -404 105 -726 181 -224 199 -106 79 -220 159 -180 75 -126 201 -128 75 -833 127 -128 125 -230 249 -184 51 -218 79 -240 163 -222 135 -82 103 -80 159 -765 107 -276 237 -438 207 -162 133 -128 135 -316 105 -312 137 -486 181 -158 77 -769 183 -764 533 -186 77 -100 173 -128 202 -174 174 -102 185 -52 51 -128 177 -358 101 -96 145 -126 75 -184 135 -558 51 -186 211 -241 237 -154 203 -508 103 -562 171 -320 99 -148 127 -212 53 -472 77 -128 147 -100 105 -136 111 -322 206 -238 79 -162 51 -559 109 -198 113 -461 53 -849 159 -230 51 -306 121 -316 105 -78 105 -182 153 -234 131 -226 83 -800 105 -104 215 -52 185 -572 235 -660 97 -922 53 -517 53 -80 133 -302 53 -134 345 -78 111 -374 133 -80 157 -106 185 -184 373 -110 55 -292 129 -140 247 -240 347 -130 73 -227 75 -648 153 -128 75 -1002 155 -335 169 -404 101 -76 175 -126 103 -373 79 -402 217 -218 101 -171 301 -158 204 -76 123 -100 51 -148 251 -334 77 -211 103 -304 359 -78 105 -52 99 -560 101 -288 303 -436 131 -234 179 -252 131 -656 51 -260 129 -160 79 -106 51 -184 203 -152 103 -234 155 -200 235 -52 133 -164 324 -106 107 -82 107 -348 313 -188 79 -372 79 -549 185 -82 79 -246 265 -720 107 -788 77 -585 79 -128 75 -130 203 -76 75 -206 228 -234 79 -180 101 -532 210 -282 229 -412 103 -140 55 -54 77 -316 151 -356 51 -102 75 -272 51 -506 51 -744 329 -340 129 -104 135 -300 167 -1318 107 -186 51 -136 107 -603 107 -338 105 -492 131 -250 107 -80 109 -170 79 -162
+RAW_Data: 101 -102 109 -306 181 -330 209 -76 101 -286 79 -126 51 -156 103 -78 357 -248 77 -260 51 -76 99 -320 323 -76 99 -124 199 -632 105 -220 290 -260 125 -234 75 -272 103 -252 423 -623 81 -80 105 -264 77 -1040 51 -106 107 -1561 81 -732 107 -82 167 -327 159 -626 53 -162 53 -162 107 -238 235 -106 163 -108 105 -104 105 -136 133 -306 51 -430 129 -152 109 -86 111 -56 81 -616 161 -130 51 -514 107 -236 208 -110 193 -638 133 -82 109 -543 216 -457 111 -84 169 -1168 201 -52 75 -78 289 -284 103 -874 105 -166 81 -244 129 -54 214 -398 81 -56 137 -410 81 -268 159 -372 103 -106 83 -814 207 -230 177 -280 75 -966 51 -823 77 -102 105 -394 139 -112 81 -1292 75 -727 183 -734 51 -590 83 -242 77 -1674 105 -562 107 -484 103 -104 107 -2114 77 -2326 51 -1052 207 -594 129 -232 177 -895 51 -506 203 -671 75 -206 101 -328 77 -104 105 -132 77 -370 186 -82 79 -846 77 -1272 53 -1609 177 -406 51 -226 121 -330 51 -280 73 -3094 75 -802 236 -3347 53 -2218 51 -1176 107 -212 75 -1460 51 -714 81 -1643 105 -4782 55 -5096 51 -7167 53 -17412 53 -6530 51 -20019 51 -12370 71 -442 103 -10796 55 -1320 105 -660 51 -1854 135 -16801 77 -5863 87 -12342 119 -24656 81 -7111 101 -15641 79 -3617 75 -10578 127 -5573 77 -16152 53 -5624 51 -13975 71 -7720 79 -3760 51 -9739 77 -1892 73 -2638 153 -4570 51 -5265 53 -3429 79 -1982 53 -2154 51 -7158 53 -12468 161 -12934 79 -14244 77 -3871 105 -2482 79 -4568 99 -218 79 -17125 53 -2368 53 -10101 55 -15958 81 -2358 109 -3584 51 -6886 85 -6834 51 -4154 53 -218 53 -826 55 -7583 51 -11429 216 -1346 71 -1856 79 -982 55 -2072 51 -4033 105 -7186 79 -1506 81 -8082 53 -6530 83 -6380 109 -192 135 -6058 51 -3274 79 -6105 57 -18103 53 -1142 55 -4687 57 -12931 99 -344 53 -9300 79 -7717 75 -3774 81 -3691 105 -2780 51 -2764 75 -1030 79 -29043 79 -3611 53 -1934 79 -4819 75 -6538 53 -7104 53 -3542 55 -1969 53 -2426 105 -7239 81 -516 79 -14563 123 -2246 53 -3012 71 -900 55 -1196 51 -7049 51 -1790 53 -10358 53 -3988 81 -1214 107
diff --git a/assets/unit_tests/subghz/test_random_raw.sub b/assets/unit_tests/subghz/test_random_raw.sub
index 4759ed4db..0a7d529ce 100644
--- a/assets/unit_tests/subghz/test_random_raw.sub
+++ b/assets/unit_tests/subghz/test_random_raw.sub
@@ -122,4 +122,9 @@ RAW_Data: -130 84629 -16530 199 -594 163 -562 65 -164 65 -230 1383 -100 1031 -66
RAW_Data: 12477 16271 -64 12623 -102 40819 -98 3729 -66 14371 -66 14943 -64 5931 -66 11147 -68 74641 -102 54299 -70 18441 -66 82993 -100 66161 -68 61869 -66 6627 -66 12987 -68 30427 -68 25761 -98 6305 -66 5019 -64 30857 -132 23929 -68 25129 -39378 317 -2020 311 -2010 2033 -312 2017 -282 325 -2018 291 -2024 2035 -316 2023 -276 319 -2028 297 -2032 2029 -284 2023 -314 321 -2016 319 -2012 2003 -310 2015 -318 321 -1984 327 -16000 351 -1974 321 -2020 2041 -276 2047 -288 327 -1992 327 -2000 2055 -282 2053 -274 305 -2022 301 -2014 2049 -286 2055 -274 319 -1992 329 -2006 2065 -282 2023 -316 323 -1988 303 -16008 323 -2014 315 -1990 2053 -284 2061 -274 319 -1988 319 -2038 2033 -286 2055 -264 339 -2008 289 -2034 2035 -284 2061 -262 339 -2008 287 -2040 2037 -286 2035 -268 347 -2006 317 -15988 311 -2014 343 -2014 2027 -300 2031 -258 311 -2024 323 -2028 2023 -280 2051 -318 285 -2024 309 -2002 2039 -312 2017 -318 289 -2020 293 -2028 2035 -316 2023 -276 321 -2030 299 -15982 345 -1988 345 -2014 2029 -268 2069 -258 337 -1998 321 -2024 2025 -320 2025 -276 321 -1994 331 -2000 2057 -282 2043 -282 305 -2034 291 -2024 2039 -320 2019 -278 323 -1992 333 -15976 389 -1978 321 -1986 2069 -276 2053 -288 303 -2020 315 -1980 2067 -258 2075 -258 337 -1996 321 -2030 2027 -284 2059 -274 319 -2004 319 -2016 2033 -282 2059 -264 345 -2006 289 -16006 355 -1984 315 -2018 2033 -312 2015 -284 327 -2000 329 -2000 2063 -282 2049 -284 327 -1984 319 -2018 2035 -284 2057 -264 343 -2004 289 -2032 2059 -280 2019 -316 323 -1984 321 -15968 387 -1978 321 -1984 2069 -276 2049 -288 325 -1996 303 -2004 2055 -284 2049 -278 325 -2018 321 -1984 2075 -276 2049 -288 327 -1990 325 -1996 2031 -318 2025 -278 323 -2018 289 -16010 357 -1982 315 -2018 2035 -278 2053 -288 307 -2022 321 -2000 2049 -274 2045 -284 327 -2022 311 -2014 2033 -276 2053 -286 327 -2000 323 -2000 2061 -282 2015 -316 325 -2002 289 -15994 353 -1980 357 -1990 2035 -312 2015 -286 327 -2020 289 -2022 2033 -318 2019 -278 323 -2004 319 -2016 2059 -282 2023 -316 327 -1970 321 -2018 2059 -280 2019 -318 325 -1972 321 -15988 353 -1982 357 -1972 2071 -276 2051 -288 327 -1988 323 -1996 2061 -280 2053 -284 325 -1984 321 -2014 2031 -282 2059 -276 321 -2018 289 -2036 2031 -282 2059 -276 321 -2018 319 -15984 341 -1984 343 -2016 2029 -298 2033 -258 309 -2028 321 -2032 2035 -284 2017 -298 337 -2008 289 -2034 2027 -314 2023 -310 285 -2016 321 -2014 2035 -282 2027 -308 317 -2026 297 -15982 357 -1984 345 -1982 2067 -264 2057 -258 341 -1996 317 -2026 2057 -282 2017 -318 325 -1972 319 -2018 2059 -280 2029 -302 315 -2006 319 -2006 2059 -274 2047 -276 307
RAW_Data: -2024 311 -15984 349 -2004 317 -2012 2029 -276 2047 -312 305 -2018 311 -2018 2037 -258 2077 -258 337 -1998 321 -2026 2031 -278 2043 -284 327 -2020 311 -2018 2031 -278 2051 -288 325 -2004 323 -15962 353 -2018 317 -2014 2007 -308 2019 -320 287 -2024 325 -1998 2035 -314 2025 -302 311 -2004 319 -2010 2027 -312 2011 -310 309 -2028 303 -2018 2027 -304 2007 -294 309 -2024 323 -16002 361 -1946 347 -2008 2027 -286 2045 -312 325 -1978 319 -2024 2043 -276 2049 -286 325 -1988 341 -1978 2061 -278 2049 -284 327 -1990 321 -2020 2029 -318 2021 -278 323 -2008 321 -15990 355 -1982 355 -1984 2031 -284 2049 -278 325 -2018 321 -2000 2047 -276 2049 -286 327 -1994 341 -1976 2067 -274 2043 -284 303 -2018 341 -1982 2061 -266 2069 -258 339 -1998 321 -16002 311 -2014 329 -2012 2027 -318 1999 -298 339 -2008 287 -2042 2031 -282 2027 -306 317 -2012 291 -2044 2037 -284 2033 -302 315 -2004 321 -2012 2037 -282 2027 -306 317 -2028 297 -15980 345 -2018 285 -2026 2037 -320 2017 -278 323 -2024 299 -2002 2069 -278 2055 -286 325 -2002 289 -2024 2037 -282 2063 -276 321 -2016 287 -2036 2025 -320 2023 -278 323 -2018 287 -16006 355 -1982 355 -1986 2033 -302 2039 -282 307 -2032 309 -2014 2043 -264 2057 -258 341 -1992 319 -2036 2033 -284 2029 -306 319 -2000 319 -2014 2035 -282 2061 -266 343 -2006 289 -16018 331 -2010 313 -2014 2021 -320 2017 -278 323 -2010 321 -2016 2037 -284 2033 -304 317 -2018 287 -2036 2037 -284 2025 -296 339 -1978 321 -2028 2057 -282 2021 -278 359 -1972 321 -15990 355 -1978 355 -1990 2035 -300 2015 -312 305 -2016 315 -2016 2053 -290 2013 -316 277 -2020 353 -1980 2059 -256 2077 -276 307 -2020 311 -2012 2047 -258 2073 -256 341 -1998 321 -15976 369 -1976 313 -2018 2051 -280 2043 -290 317 -2004 321 -2024 2023 -282 2053 -282 327 -2020 313 -2020 2035 -278 2055 -284 325 -1986 321 -2016 2033 -280 2049 -282 325 -2020 313 -15986 315 -2026 319 -2028 2003 -318 2013 -294 339 -2008 289 -2032 2027 -316 2019 -302 311 -2004 321 -2014 2033 -314 1995 -308 317 -2028 297 -2032 2035 -276 2023 -316 321 -2014 289 -15998 347 -2014 283 -2020 2035 -292 2031 -288 311 -2024 321 -2036 2001 -310 2027 -318 275 -2054 277 -2026 2029 -296 2027 -292 311 -2024 321 -2030 2031 -282 2033 -304 313 -2004 321 -15992 329 -2010 349 -1980 2037 -292 2051 -256 339 -1998 319 -2034 2029 -286 2055 -264 339 -1978 321 -2030 2027 -280 2043 -316 327 -1984 315 -2016 2063 -278 2041 -288 327 -1990 325 -15964 389 -1978 319 -1984 2063 -256 2055 -292 307 -2016 323 -2028 2027 -286 2057 -274 319 -2010 319 -2010 2033 -282 2061 -276 321 -2018 289 -2032 2027 -318 2021 -278 321 -2020 319 -15974 355 -1980 357 -2000 2035
RAW_Data: -254 2079 -276 309 -2016 309 -2012 2035 -296 2063 -258 337 -1992 321 -2030 2037 -286 2027 -294 333 -1978 321 -2034 2029 -286 2031 -306 315 -2008 321 -15972 355 -1984 315 -2014 2037 -310 2011 -318 323 -1984 329 -2002 2033 -316 2029 -278 323 -2026 299 -2030 2035 -278 2019 -316 325 -1980 323 -2018 2053 -252 2075 -280 327 -1984 355 -15954 345 -2008 309 -2016 2045 -266 2065 -258 341 -235740 101 -202 65 -734 133 -372 401 -68 269 -236 505 -68 235 -234 875 -68 13969 -100 14297 -70 3863 -96 59337 -104 11859 -68 17409 -68 7317 -66 11443 -64 15589 -66 4381 -98 32297 -168 45445 -100 59295 -100 41417 -66 1539 -66 23001
-
+RAW_Data: 171 -316 311 -154 187 -292 343 -134 337 -136 199 -286 311 -182 157 -294 327 -160 171 -316 161 -312 159 -314 333 -170 311 -164 141 -324 305 -164 299 -176 301 -170 167 -340 133 -338 163 -312 159 -294 189 -298 165 -314 311 -180 155 -294 189 -300 165 -312 187 -284 189 -312 159 -294 189 -296 167 -314 161 -310 189 -312 159 -292 189 -296 167 -312 161 -312 159 -314 193 -268 175 -304 193 -314 163 -312 159 -312 193 -294 495 -458 161 -338 301 -168 165 -304 331 -134 199 -286 309 -184 309 -170 141 -318 331 -162 143 -316 309 -182 157 -294 189 -302 163 -312 309 -184 311 -170 141 -318 331 -162 299 -150 319 -196 139 -314 165 -334 137 -340 159 -312 161 -302 149 -318 331 -162 173 -312 161 -312 163 -300 175 -296 195 -310 163 -312 159 -312 163 -312 159 -296 189 -300 193 -284 187 -284 189 -312 159 -292 189 -298 167 -312 161 -312 189 -300 173 -294 195 -282 191 -310 485 -472 167 -300 331 -134 171 -312 333 -170 169 -290 331 -162 299 -176 155 -300 333 -162 171 -300 323 -150 145 -340 159 -320 167 -302 319 -150 319 -166 169 -312 331 -162 299 -150 319 -194 139 -314 165 -308 163 -340 133 -338 163 -312 157 -296 327 -160 171 -316 163 -310 161 -312 163 -298 177 -302 193 -314 163 -310 161 -312 163 -300 173 -300 169 -318 177 -290 189 -300 165 -312 161 -312 189 -284 185 -292 189 -300 191 -286 187 -284 191 -312 471 -486 167 -314 313 -152 159 -300 335 -162 169 -308 319 -150 319 -166 169 -312 331 -162 143 -314 311 -180 157 -294 189 -300 165 -314 309 -182 311 -168 141 -318 333 -162 299 -174 295 -194 141 -314 165 -336 137 -338 135 -338 161 -312 159 -294 327 -160 171 -316 161 -312 159 -314 191 -270 201 -278 193 -314 163 -310 161 -312 163 -300 175 -300 169 -316 177 -292 189 -300 165 -312 161 -312 189 -284 183 -294 189 -298 193 -284 187 -312 163 -312 497 -460 145 -320 325 -168 171 -290 333 -162 171 -314 305 -160 317 -168 169 -290 333 -162 173 -312 283 -182 159 -294 189 -302 165 -312 309 -182 313 -168 143 -318 331 -162 301 -148 321 -194 141 -312 167 -334 135 -340 161 -310 163 -312 159 -294 327 -160 171 -316 163 -310 161 -312 163 -300 175 -302 195 -312 163 -312 159 -312 163 -300 175 -298 169 -318 177 -290 191 -300 165 -312 161 -310 189 -284 185 -292 189 -300 191 -286 187 -312 161 -300 487 -484 151 -318 335 -138 169 -322 305 -164 171 -314 305 -190 295 -166 171 -290 333 -162 173 -312 283 -182 159 -296 191 -300
+RAW_Data: 165 -312 333 -160 311 -170 141 -318 331 -164 299 -148 321 -194 139 -316 165 -336 135 -340 133 -338 163 -300 149 -320 329 -164 171 -314 159 -312 163 -300 175 -298 193 -310 163 -312 159 -312 163 -300 175 -296 193 -312 163 -312 159 -312 163 -300 175 -298 167 -320 175 -290 191 -296 193 -286 187 -310 163 -300 175 -296 501 -458 187 -288 347 -154 151 -316 325 -162 171 -316 313 -152 301 -194 141 -316 331 -162 143 -314 311 -182 155 -294 189 -302 163 -314 309 -182 311 -168 143 -318 331 -162 301 -174 295 -194 141 -314 165 -336 135 -340 133 -338 163 -312 159 -294 327 -158 173 -314 163 -312 159 -306 173 -314 165 -306 191 -284 189 -284 189 -312 157 -294 191 -300 163 -314 187 -284 189 -284 187 -292 189 -296 165 -314 161 -312 189 -284 185 -294 189 -298 193 -286 485 -492 167 -298 323 -150 175 -302 331 -164 171 -300 321 -150 317 -166 167 -308 331 -134 171 -316 309 -182 129 -318 189 -302 163 -314 309 -182 311 -170 141 -318 331 -162 301 -148 321 -194 139 -314 167 -334 137 -338 161 -310 163 -312 159 -294 327 -160 171 -316 161 -312 159 -312 193 -270 175 -304 193 -314 163 -312 159 -312 161 -314 161 -296 189 -304 165 -312 187 -284 189 -276 173 -318 195 -278 193 -284 187 -312 163 -300 175 -298 169 -318 511 -460 147 -318 327 -168 169 -292 331 -164 171 -314 305 -160 315 -168 171 -290 333 -162 171 -314 283 -182 159 -294 189 -300 165 -314 307 -184 311 -170 141 -318 333 -162 299 -150 319 -194 141 -314 165 -336 135 -340 133 -338 163 -312 157 -294 327 -160 171 -316 163 -310 161 -304 175 -314 167 -304 191 -286 187 -284 189 -284 187 -292 189 -300 165 -312 189 -284 187 -286 185 -294 189 -296 165 -314 161 -312 187 -286 185 -294 189 -298 193 -284 485 -494 167 -298 321 -150 177 -312 313 -168 171 -292 331 -164 299 -174 151 -316 325 -162 171 -316 289 -176 151 -316 187 -296 167 -312 311 -180 307 -170 141 -318 331 -162 299 -150 319 -196 139 -314 165 -334 137 -340 159 -312 161 -302 149 -320 329 -164 171 -314 159 -312 163 -300 175 -298 193 -310 163 -312 161 -310 163 -312 161 -296 189 -302 191 -286 187 -284 189 -312 159 -292 189 -296 167 -314 161 -310 189 -284 187 -292 189 -300 193 -284 485 -494 167 -296 323 -150 175 -312 313 -170 169 -292 333 -162 299 -176 151 -314 327 -160 171 -316 291 -176 149 -316 189 -296 165 -314 309 -182 307 -168 141 -318 331 -164 299 -148 321 -194 141 -314 165 -334 137 -338 161 -312
+RAW_Data: 161 -302 147 -320 331 -162 171 -314 161 -312 163 -300 175 -296 195 -310 163 -312 159 -312 163 -300 173 -296 193 -312 163 -312 159 -312 163 -300 175 -298 169 -318 177 -290 191 -296 195 -284 189 -284 189 -312 159 -296 513 -468 159 -300 333 -162 171 -300 323 -150 171 -314 325 -162 311 -164 171 -314 305 -160 159 -296 327 -160 171 -316 161 -312 161 -312 335 -170 311 -164 141 -324 321 -154 299 -194 309 -164 143 -326 167 -314 161 -312 159 -312 163 -302 173 -300 331 -162 173 -312 161 -312 163 -300 175 -300 167 -320 153 -312 191 -296 167 -312 161 -312 189 -312 159 -292 189 -298 167 -312 161 -312 159 -314 193 -268 177 -302 193 -316 161 -312 159 -312 193 -294 497 -456 187 -312 303 -166 165 -306 331 -132 201 -286 309 -182 313 -168 143 -318 331 -162 143 -314 311 -182 157 -294 189 -302 165 -312 309 -182 311 -170 141 -318 333 -162 299 -150 319 -194 141 -314 165 -334 137 -338 161 -312 161 -300 149 -320 331 -162 171 -314 161 -310 163 -302 173 -298 193 -310 165 -310 161 -310 163 -312 161 -296 189 -300 193 -286 187 -284 189 -312 157 -294 189 -298 165 -314 161 -310 189 -284 187 -292 189 -300 193 -284 485 -494 167 -298 321 -150 171 -318 323 -162 171 -314 289 -176 297 -194 141 -314 331 -162 143 -316 309 -182 155 -294 189 -302 163 -314 309 -182 311 -168 143 -318 331 -162 301 -148 321 -194 139 -314 167 -334 137 -338 161 -310 163 -300 149 -320 331 -162 171 -314 161 -312 163 -300 173 -298 193 -310 163 -312 159 -312 163 -300 175 -296 193 -312 163 -312 159 -312 163 -300 175 -298 167 -320 175 -290 191 -296 193 -286 187 -310 163 -312 161 -296 513 -468 159 -300 333 -162 171 -302 321 -150 175 -300 333 -162 311 -162 171 -316 289 -176 153 -314 327 -160 171 -316 163 -312 159 -312 307 -168 335 -138 169 -320 307 -164 297 -176 301 -194 141 -318 165 -336 137 -338 133 -338 163 -312 159 -294 327 -160 171 -316 161 -312 161 -312 163 -298 177 -302 169 -318 177 -292 189 -298 167 -312 189 -284 189 -312 157 -294 189 -298 167 -312 161 -312 159 -312 193 -270 203 -302 169 -314 161 -312 189 -310 467 -484 145 -318 327 -168 143 -316 331 -162 173 -312 307 -160 313 -170 141 -318 331 -164 143 -342 281 -184 157 -294 189 -302 165 -312 307 -184 313 -168 141 -320 331 -162 299 -150 319 -194 141 -314 165 -336 137 -338 135 -338 161 -312 159 -294 327 -158 173 -314 163 -310 161 -312 165 -298 175 -304 193 -312 163 -312 159 -312
+RAW_Data: 163 -300 175 -298 169 -318 177 -290 191 -298 165 -314 161 -310 189 -284 185 -292 189 -298 193 -284 189 -310 163 -312 497 -460 145 -320 325 -170 169 -290 333 -162 171 -314 307 -158 317 -168 169 -290 333 -162 171 -314 281 -182 159 -296 189 -300 165 -312 309 -182 313 -168 143 -318 331 -162 301 -148 319 -196 139 -314 165 -336 137 -338 135 -338 161 -312 159 -294 327 -160 173 -314 163 -312 159 -312 163 -300 175 -302 195 -312 163 -312 159 -312 163 -300 175 -298 169 -318 175 -292 189 -300 165 -312 161 -312 187 -284 185 -292 189 -300 193 -284 187 -312 161 -314 471 -486 167 -314 313 -152 159 -300 335 -162 169 -308 321 -156 329 -170 127 -318 321 -176 155 -300 333 -164 169 -302 165 -314 161 -310 329 -168 299 -166 151 -328 311 -154 331 -168 299 -178 143 -318 153 -322 167 -332 149 -320 151 -318 165 -304 321 -156 181 -290 189 -300 173 -294 177 -294 189 -302 173 -294 177 -294 189 -302 173 -294 177 -318 193 -278 173 -294 179 -292 191 -302 173 -294 177 -294 189 -302 173 -320 177 -294 195 -278 175 -318 491 -460 163 -314 333 -158 159 -294 327 -160 171 -316 311 -180 307 -170 141 -318 331 -162 143 -316 309 -182 157 -294 189 -302 165 -312 309 -182 313 -168 141 -318 331 -164 299 -148 321 -194 141 -314 165 -334 137 -338 135 -338 161 -312 159 -294 329 -158 173 -314 163 -310 161 -306 173 -314 165 -304 193 -284 187 -286 189 -276 197 -294 193 -310 163 -312 161 -310 163 -300 175 -296 193 -310 165 -284 187 -310 163 -300 175 -300 169 -318 177 -316 483 -466 187 -292 341 -134 171 -308 319 -150 179 -300 333 -164 309 -162 171 -316 313 -152 153 -316 327 -160 171 -316 163 -310 161 -312 307 -166 337 -136 171 -322 305 -164 299 -174 301 -194 141 -318 165 -336 137 -338 161 -310 163 -300 149 -320 331 -162 171 -314 161 -312 163 -300 173 -296 195 -310 163 -312 159 -312 163 -312 159 -296 189 -302 165 -312 189 -284 189 -284 185 -294 189 -296 165 -314 161 -310 189 -284 187 -294 189 -298 193 -284 485 -494 167 -298 321 -150 177 -312 313 -168 171 -290 333 -162 299 -176 151 -316 325 -162 171 -316 289 -176 151 -314 189 -296 165 -314 309 -182 305 -170 141 -318 333 -162 299 -150 319 -194 141 -314 165 -334 137 -340 133 -338 161 -302 149 -320 329 -164 171 -286 187 -312 163 -300 173 -298 193 -310 163 -312 159 -312 163 -312 159 -296 189 -302 191 -286 187 -284 189 -312 159 -292 191 -296 165 -314 161 -310 189 -284 187 -292
+RAW_Data: 189 -300 193 -284 485 -494 167 -298 321 -150 177 -300 327 -150 167 -328 305 -160 319 -168 171 -290 333 -162 171 -314 281 -184 159 -296 189 -300 165 -314 307 -184 311 -170 141 -318 333 -162 299 -150 319 -194 139 -314 167 -334 135 -340 133 -338 163 -312 159 -294 327 -158 173 -314 163 -312 159 -312 165 -298 177 -302 193 -314 163 -310 161 -312 163 -300 173 -300 167 -318 177 -292 189 -300 165 -312 161 -312 187 -284 185 -292 189 -300 191 -286 187 -284 189 -300 487 -484 149 -320 333 -138 171 -322 321 -154 151 -316 327 -160 311 -164 173 -312 307 -160 161 -298 355 -132 173 -314 163 -310 161 -312 335 -170 311 -164 143 -322 307 -164 323 -150 301 -196 141 -318 165 -334 137 -338 161 -312 161 -302 147 -320 331 -162 173 -312 161 -312 163 -300 173 -298 195 -310 163 -312 159 -312 163 -312 159 -296 189 -300 193 -284 189 -284 189 -284 185 -294 189 -296 165 -314 161 -312 189 -284 185 -294 189 -298 193 -286 485 -468 193 -296 323 -150 147 -340 313 -168 171 -292 331 -164 299 -174 151 -316 325 -160 173 -316 289 -176 149 -316 189 -294 165 -314 309 -182 307 -170 141 -318 331 -164 299 -148 321 -194 139 -314 167 -306 165 -338 133 -338 163 -312 159 -294 327 -160 173 -314 163 -312 161 -310 165 -300 175 -300 169 -318 177 -290 189 -298 165 -314 187 -284 189 -312 159 -294 189 -298 165 -314 161 -310 161 -306 173 -316 193 -280 191 -312 159 -312 163 -300 515 -460 161 -312 305 -190 135 -328 329 -134 201 -286 309 -182 311 -168 143 -318 331 -162 143 -316 309 -182 157 -294 189 -300 165 -312 309 -184 311 -168 143 -318 331 -162 301 -148 319 -196 139 -314 165 -334 137 -340 159 -312 163 -300 149 -318 331 -162 173 -312 161 -312 163 -300 175 -296 195 -310 163 -312 159 -312 163 -300 173 -296 193 -312 163 -312 159 -312 163 -312 161 -298 189 -300 165 -312 161 -312 189 -312 159 -292 191 -300 191 -286 485 -468 193 -298 323 -148 147 -342 323 -160 173 -314 289 -176 297 -196 139 -314 331 -162 143 -314 311 -180 157 -292 191 -300 165 -312 311 -182 309 -170 141 -318 333 -162 299 -150 319 -194 141 -314 165 -334 137 -338 161 -312 161 -312 159 -294 329 -158 173 -314 163 -310 161 -312 165 -298 175 -304 193 -312 163 -310 161 -310 163 -302 173 -300 169 -318 175 -292 189 -300 165 -312 161 -310 189 -278 173 -316 195 -280 191 -312 159 -312 163 -300 515 -460 163 -310 305 -190 137 -328 329 -134 199 -288 309 -182 311 -168 143 -318
+RAW_Data: 331 -162 143 -316 309 -182 157 -292 191 -300 165 -312 309 -182 313 -168 141 -318 331 -164 299 -174 295 -194 141 -314 165 -334 137 -340 133 -338 163 -312 159 -292 327 -160 171 -316 163 -310 161 -312 165 -298 175 -304 193 -312 163 -312 159 -312 163 -300 175 -300 169 -316 177 -292 189 -298 167 -312 161 -310 189 -278 173 -316 193 -282 191 -312 159 -312 163 -300 515 -460 163 -310 305 -190 137 -326 331 -132 201 -286 309 -184 309 -170 141 -318 333 -162 143 -314 311 -180 159 -294 189 -300 165 -312 309 -184 311 -168 143 -318 331 -162 301 -148 319 -196 139 -314 165 -336 135 -340 159 -312 163 -300 149 -320 329 -164 171 -314 159 -312 163 -300 175 -296 195 -310 163 -312 159 -312 163 -300 175 -294 195 -310 163 -312 161 -310 163 -300 175 -298 169 -318 153 -314 191 -296 193 -286 187 -284 189 -312 161 -294 509 -468 159 -298 335 -162 169 -304 323 -150 175 -300 335 -162 311 -160 173 -316 313 -152 151 -316 327 -160 171 -316 163 -312 159 -312 307 -168 335 -138 169 -322 305 -164 299 -176 299 -194 141 -316 167 -334 137 -340 159 -312 161 -302 147 -320 331 -162 173 -312 161 -312 163 -300 175 -296 193 -310 165 -310 161 -312 161 -302 173 -296 195 -310 163 -312 161 -310 163 -300 175 -298 169 -318 177 -290 189 -296 193 -286 187 -310 163 -300 175 -296 501 -484 161 -288 347 -154 151 -316 325 -160 173 -314 313 -152 301 -196 141 -314 331 -162 143 -316 309 -182 157 -294 189 -300 165 -314 309 -182 311 -168 143 -318 331 -162 301 -148 319 -196 139 -314 165 -336 137 -338 133 -338 163 -312 159 -294 327 -158 173 -316 161 -312 159 -312 163 -298 177 -302 193 -314 163 -312 159 -312 163 -300 175 -298 169 -318 177 -290 191 -298 165 -314 161 -310 189 -284 193 -292 179 -308 167 -314 161 -312 189 -302 481 -460 173 -320 303 -168 169 -294 331 -164 171 -314 307 -160 319 -168 169 -292 331 -162 143 -342 283 -182 159 -294 189 -302 165 -312 309 -184 311 -168 143 -318 331 -162 299 -150 319 -194 141 -314 165 -336 135 -340 133 -338 163 -312 159 -294 327 -158 173 -316 161 -312 159 -312 165 -298 177 -302 193 -312 163 -312 161 -310 163 -314 161 -296 189 -302 165 -312 187 -284 189 -284 185 -294 189 -296 165 -314 187 -284 189 -302 173 -294 195 -310 491 -458 163 -318 319 -156 153 -314 327 -160 171 -316 311 -152 327 -170 141 -316 331 -164 143 -314 309 -182 157 -294 189 -300 165 -314 309 -182 311 -168 143 -316 333 -162 299 -150
diff --git a/documentation/CustomFlipperName.md b/documentation/CustomFlipperName.md
new file mode 100644
index 000000000..4b7889065
--- /dev/null
+++ b/documentation/CustomFlipperName.md
@@ -0,0 +1,34 @@
+# How to change Flipper name:
+
+## Instruction
+1. Read [How to build](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/HowToBuild.md) and [How to install](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/HowToInstall.md) to know how to build and install firmware
+2. Follow how to build instructions to prepare all things before continuing
+3. Run release build to verify all is ok - `./fbt COMPACT=1 DEBUG=0 updater_package`
+4. Clear build files - `./fbt COMPACT=1 DEBUG=0 updater_package -c`
+5. Run command with extra enviroment var before `./fbt` that variable should contain your custom name in alphanumeric characters - max length 8 chars
+ `CUSTOM_FLIPPER_NAME=Name ./fbt COMPACT=1 DEBUG=0 updater_package` - where `Name` write your custom name
+6. Copy `dist/f7-C/f7-update-local` folder to microSD `update/myfw/` and run `update` file on flipper from file manager app (Archive)
+7. Flash from microSD card only, .dfu update from qFlipper will not work properly since name and serial number will be changed
+8. Done, you will have custom name, serial number and bluetooth mac address
+
+
+
+## Troubleshooting
+### I'm using Windows and name changing / building firmware doesn't work
+- Use PowerShell or VSCode terminal(powershell by default)
+- Clear build files - `.\fbt.cmd COMPACT=1 DEBUG=0 updater_package -c`
+- Enter this in same terminal `$Env:CUSTOM_FLIPPER_NAME="Name"`
+- Run release build - `.\fbt.cmd COMPACT=1 DEBUG=0 updater_package`
+- Flash as described before (see 6.)
+- If something still not work - Run powershell or VSCode as Admin
+### Name stays same for every new build
+- Clear build files - `./fbt COMPACT=1 DEBUG=0 updater_package -c`
+- Try again
+### I want to return my original name and serial number
+- Flash stock FW or any CFW using microSD card offline update method
+
+Or
+- Clear build files - `./fbt COMPACT=1 DEBUG=0 updater_package -c`
+- Run release build - `./fbt COMPACT=1 DEBUG=0 updater_package`
+- Copy `dist/f7-C/f7-update-local` folder to microSD `update/myfw/` and run `update` file on flipper from file manager app (Archive)
+- Flash from microSD card only, .dfu update from qFlipper will not work properly since name and serial number will be changed
\ No newline at end of file
diff --git a/documentation/HowToBuild.md b/documentation/HowToBuild.md
index a6b5b5b4e..4a23e97cd 100644
--- a/documentation/HowToBuild.md
+++ b/documentation/HowToBuild.md
@@ -1,6 +1,15 @@
# How to Build by yourself:
+## Install required software
+
+- Git - [Download](https://git-scm.com/downloads) for Windows, on Linux/Mac install via package manager (`brew`, `apt`, ...)
+
+For development:
+- Git
+- Python3
+- VSCode
+
## Clone the Repository
You should clone with
@@ -8,6 +17,47 @@ You should clone with
$ git clone --recursive https://github.com/Eng1n33r/flipperzero-firmware.git
```
+# Build on Linux/macOS
+
+Check out `documentation/fbt.md` for details on building and flashing firmware.
+
+### Compile everything for development
+
+```sh
+./fbt
+```
+
+### Compile everything for release + get updater package to update from microSD card
+
+```sh
+./fbt COMPACT=1 DEBUG=0 updater_package
+```
+
+Check `dist/` for build outputs.
+
+Use **`flipper-z-{target}-full-{suffix}.dfu`** to flash your device.
+
+
+# Build on Windows
+
+Check out `documentation/fbt.md` for details on building and flashing firmware.
+
+### Compile everything for development
+
+```sh
+.\fbt.cmd
+```
+
+### Compile everything for release + get updater package to update from microSD card
+
+```sh
+.\fbt.cmd COMPACT=1 DEBUG=0 updater_package
+```
+
+Check `dist/` for build outputs.
+
+Use **`flipper-z-{target}-full-{suffix}.dfu`** to flash your device.
+
## Build with Docker
### Prerequisites
@@ -28,7 +78,7 @@ docker-compose exec dev ./fbt
### Compile everything for release + get updater package to update from microSD card
```sh
-docker-compose exec dev ./fbt --with-updater COMPACT=1 DEBUG=0 updater_package
+docker-compose exec dev ./fbt COMPACT=1 DEBUG=0 updater_package
```
Check `dist/` for build outputs.
@@ -36,44 +86,3 @@ Check `dist/` for build outputs.
Use **`flipper-z-{target}-full-{suffix}.dfu`** to flash your device.
If compilation fails, make sure all submodules are all initialized. Either clone with `--recursive` or use `git submodule update --init --recursive`.
-
-# Build on Linux/macOS
-
-Check out `documentation/fbt.md` for details on building and flashing firmware.
-
-### Compile everything for development
-
-```sh
-./fbt
-```
-
-### Compile everything for release + get updater package to update from microSD card
-
-```sh
-./fbt --with-updater COMPACT=1 DEBUG=0 updater_package
-```
-
-Check `dist/` for build outputs.
-
-Use **`flipper-z-{target}-full-{suffix}.dfu`** to flash your device.
-
-
-# Build on Windows
-
-Check out `documentation/fbt.md` for details on building and flashing firmware.
-
-### Compile everything for development
-
-```sh
-.\fbt.cmd
-```
-
-### Compile everything for release + get updater package to update from microSD card
-
-```sh
-.\fbt.cmd --with-updater COMPACT=1 DEBUG=0 updater_package
-```
-
-Check `dist/` for build outputs.
-
-Use **`flipper-z-{target}-full-{suffix}.dfu`** to flash your device.
diff --git a/fbt_options.py b/fbt_options.py
index 66785bff4..73f5d191b 100644
--- a/fbt_options.py
+++ b/fbt_options.py
@@ -1,5 +1,7 @@
import posixpath
+# For more details on these options, run 'fbt -h'
+
# Default hardware target
TARGET_HW = 7
@@ -59,6 +61,9 @@ SVD_FILE = "debug/STM32WB55_CM4.svd"
# Look for blackmagic probe on serial ports and local network
BLACKMAGIC = "auto"
+# Application to start on boot
+LOADER_AUTOSTART = ""
+
FIRMWARE_APPS = {
"default": [
"crypto_start",
diff --git a/firmware.scons b/firmware.scons
index 064e0ddab..863b35fca 100644
--- a/firmware.scons
+++ b/firmware.scons
@@ -139,7 +139,7 @@ fwenv.AppendUnique(
# Depends on virtual value-only node, so it only gets rebuilt when set of apps changes
apps_c = fwenv.ApplicationsC(
"applications/applications.c",
- Value(fwenv["APPS"]),
+ [Value(fwenv["APPS"]), Value(fwenv["LOADER_AUTOSTART"])],
)
# Adding dependency on manifest files so apps.c is rebuilt when any manifest is changed
fwenv.Depends(apps_c, fwenv.GlobRecursive("*.fam", "#/applications"))
@@ -210,11 +210,19 @@ fwelf = fwenv["FW_ELF"] = fwenv.Program(
Depends(fwelf, lib_targets)
# Output extra details after building firmware
AddPostAction(fwelf, fwenv["APPBUILD_DUMP"])
-AddPostAction(fwelf, Action("@$SIZECOM"))
+AddPostAction(
+ fwelf,
+ Action('${PYTHON3} "${ROOT_DIR}/scripts/fwsize.py" elf ${TARGET}', "Firmware size"),
+)
# Produce extra firmware files
fwhex = fwenv["FW_HEX"] = fwenv.HEXBuilder("${FIRMWARE_BUILD_CFG}")
fwbin = fwenv["FW_BIN"] = fwenv.BINBuilder("${FIRMWARE_BUILD_CFG}")
+AddPostAction(
+ fwbin,
+ Action('@${PYTHON3} "${ROOT_DIR}/scripts/fwsize.py" bin ${TARGET}'),
+)
+
fwdfu = fwenv["FW_DFU"] = fwenv.DFUBuilder("${FIRMWARE_BUILD_CFG}")
Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_dfu", fwdfu)
diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.c b/firmware/targets/f7/furi_hal/furi_hal_clock.c
index 09efe76dd..a7c9b4d03 100644
--- a/firmware/targets/f7/furi_hal/furi_hal_clock.c
+++ b/firmware/targets/f7/furi_hal/furi_hal_clock.c
@@ -75,7 +75,10 @@ void furi_hal_clock_init() {
LL_EXTI_LINE_18); /* Why? Because that's why. See RM0434, Table 61. CPU1 vector table. */
LL_EXTI_EnableRisingTrig_0_31(LL_EXTI_LINE_18);
LL_RCC_EnableIT_LSECSS();
- LL_RCC_LSE_EnableCSS();
+ /* ES0394, extended case of 2.2.2 */
+ if(!LL_RCC_IsActiveFlag_BORRST()) {
+ LL_RCC_LSE_EnableCSS();
+ }
/* Main PLL configuration and activation */
LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_2, 8, LL_RCC_PLLR_DIV_2);
diff --git a/firmware/targets/f7/furi_hal/furi_hal_info.c b/firmware/targets/f7/furi_hal/furi_hal_info.c
index cf7140eb4..1f75ea331 100644
--- a/firmware/targets/f7/furi_hal/furi_hal_info.c
+++ b/firmware/targets/f7/furi_hal/furi_hal_info.c
@@ -1,6 +1,11 @@
#include
-#include
+#include
+#include
+#include
+#include
+
#include
+#include
#include
void furi_hal_info_get(FuriHalInfoValueCallback out, void* context) {
@@ -45,6 +50,7 @@ void furi_hal_info_get(FuriHalInfoValueCallback out, void* context) {
out("hardware_color", string_get_cstr(value), false, context);
string_printf(value, "%d", furi_hal_version_get_hw_region());
out("hardware_region", string_get_cstr(value), false, context);
+ out("hardware_region_provisioned", furi_hal_region_get_name(), false, context);
const char* name = furi_hal_version_get_name_ptr();
if(name) {
out("hardware_name", name, false, context);
diff --git a/firmware/targets/f7/furi_hal/furi_hal_region.c b/firmware/targets/f7/furi_hal/furi_hal_region.c
new file mode 100644
index 000000000..2fdee0983
--- /dev/null
+++ b/firmware/targets/f7/furi_hal/furi_hal_region.c
@@ -0,0 +1,9 @@
+#include
+
+bool furi_hal_region_is_provisioned() {
+ return true;
+}
+
+const char* furi_hal_region_get_name() {
+ return "00";
+}
diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.c b/firmware/targets/f7/furi_hal/furi_hal_subghz.c
index 0e2810141..9db44933d 100644
--- a/firmware/targets/f7/furi_hal/furi_hal_subghz.c
+++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.c
@@ -320,7 +320,7 @@ bool furi_hal_subghz_is_tx_allowed(uint32_t value) {
bool is_extended = false;
// TODO: !!! Move file check to another place
- Storage* storage = furi_record_open("storage");
+ Storage* storage = furi_record_open(RECORD_STORAGE);
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
if(flipper_format_file_open_existing(fff_data_file, "/ext/subghz/assets/dangerous_settings")) {
@@ -329,7 +329,7 @@ bool furi_hal_subghz_is_tx_allowed(uint32_t value) {
}
flipper_format_free(fff_data_file);
- furi_record_close("storage");
+ furi_record_close(RECORD_STORAGE);
if(!(value >= 299999755 && value <= 348000335) &&
!(value >= 386999938 && value <= 464000000) &&
diff --git a/firmware/targets/f7/furi_hal/furi_hal_version.c b/firmware/targets/f7/furi_hal/furi_hal_version.c
index 7abee281f..ab635be54 100644
--- a/firmware/targets/f7/furi_hal/furi_hal_version.c
+++ b/firmware/targets/f7/furi_hal/furi_hal_version.c
@@ -106,6 +106,10 @@ static void furi_hal_version_set_name(const char* name) {
// BLE Mac address
uint32_t udn = LL_FLASH_GetUDN();
+ if(version_get_custom_name(NULL) != NULL) {
+ udn = (uint32_t)*version_get_custom_name(NULL);
+ }
+
uint32_t company_id = LL_FLASH_GetSTCompanyID();
uint32_t device_id = LL_FLASH_GetDeviceID();
furi_hal_version.ble_mac[0] = (uint8_t)(udn & 0x000000FF);
@@ -129,7 +133,11 @@ static void furi_hal_version_load_otp_v0() {
furi_hal_version.board_body = otp->board_body;
furi_hal_version.board_connect = otp->board_connect;
- furi_hal_version_set_name(otp->name);
+ if(version_get_custom_name(NULL) != NULL) {
+ furi_hal_version_set_name(version_get_custom_name(NULL));
+ } else {
+ furi_hal_version_set_name(otp->name);
+ }
}
static void furi_hal_version_load_otp_v1() {
@@ -143,7 +151,11 @@ static void furi_hal_version_load_otp_v1() {
furi_hal_version.board_color = otp->board_color;
furi_hal_version.board_region = otp->board_region;
- furi_hal_version_set_name(otp->name);
+ if(version_get_custom_name(NULL) != NULL) {
+ furi_hal_version_set_name(version_get_custom_name(NULL));
+ } else {
+ furi_hal_version_set_name(otp->name);
+ }
}
static void furi_hal_version_load_otp_v2() {
@@ -163,7 +175,11 @@ static void furi_hal_version_load_otp_v2() {
if(otp->board_color != 0xFF) {
furi_hal_version.board_color = otp->board_color;
furi_hal_version.board_region = otp->board_region;
- furi_hal_version_set_name(otp->name);
+ if(version_get_custom_name(NULL) != NULL) {
+ furi_hal_version_set_name(version_get_custom_name(NULL));
+ } else {
+ furi_hal_version_set_name(otp->name);
+ }
} else {
furi_hal_version.board_color = 0;
furi_hal_version.board_region = 0;
@@ -262,6 +278,8 @@ const char* furi_hal_version_get_hw_region_name() {
return "R02";
case FuriHalVersionRegionJp:
return "R03";
+ case FuriHalVersionRegionWorld:
+ return "R04";
}
return "R??";
}
@@ -299,5 +317,8 @@ size_t furi_hal_version_uid_size() {
}
const uint8_t* furi_hal_version_uid() {
+ if(version_get_custom_name(NULL) != NULL) {
+ return (const uint8_t*)((uint32_t)*version_get_custom_name(NULL));
+ }
return (const uint8_t*)UID64_BASE;
}
diff --git a/firmware/targets/furi_hal_include/furi_hal.h b/firmware/targets/furi_hal_include/furi_hal.h
index 4d1fc9704..2a372a6c3 100644
--- a/firmware/targets/furi_hal_include/furi_hal.h
+++ b/firmware/targets/furi_hal_include/furi_hal.h
@@ -18,6 +18,7 @@ template struct STOP_EXTERNING_ME {};
#include "furi_hal_sd.h"
#include "furi_hal_i2c.h"
#include "furi_hal_resources.h"
+#include "furi_hal_region.h"
#include "furi_hal_rtc.h"
#include "furi_hal_speaker.h"
#include "furi_hal_gpio.h"
diff --git a/firmware/targets/furi_hal_include/furi_hal_region.h b/firmware/targets/furi_hal_include/furi_hal_region.h
new file mode 100644
index 000000000..a7ebac32c
--- /dev/null
+++ b/firmware/targets/furi_hal_include/furi_hal_region.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include
+#include
+
+/** Check if region data provisioned
+ *
+ * @return true if provisioned, false otherwise
+ */
+bool furi_hal_region_is_provisioned();
+
+/** Get region name
+ *
+ * 2 letter Region code according to iso 3166 standard
+ * There are 2 extra values that we use in special cases:
+ * RM, whats the reason you not doing a release?
+ * Waiting for my commits?
+ * - "00" - developer edition, unlocked
+ * - "WW" - world wide, region provisioned by default
+ * - "--" - no provisioned region
+ *
+ * @return Pointer to string
+ */
+const char* furi_hal_region_get_name();
diff --git a/firmware/targets/furi_hal_include/furi_hal_version.h b/firmware/targets/furi_hal_include/furi_hal_version.h
index 500e0d813..720fdfd17 100644
--- a/firmware/targets/furi_hal_include/furi_hal_version.h
+++ b/firmware/targets/furi_hal_include/furi_hal_version.h
@@ -41,6 +41,7 @@ typedef enum {
FuriHalVersionRegionEuRu = 0x01,
FuriHalVersionRegionUsCaAu = 0x02,
FuriHalVersionRegionJp = 0x03,
+ FuriHalVersionRegionWorld = 0x04,
} FuriHalVersionRegion;
/** Device Display */
diff --git a/lib/app-scened-template/view_controller.hpp b/lib/app-scened-template/view_controller.hpp
index d08751c58..15028f533 100644
--- a/lib/app-scened-template/view_controller.hpp
+++ b/lib/app-scened-template/view_controller.hpp
@@ -26,7 +26,6 @@ public:
0)...);
gui = static_cast(furi_record_open("gui"));
- view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen);
};
~ViewController() {
@@ -96,6 +95,10 @@ public:
furi_check(result == FuriStatusOk);
}
+ void attach_to_gui(ViewDispatcherType type) {
+ view_dispatcher_attach_to_gui(view_dispatcher, gui, type);
+ }
+
private:
/**
* @brief ViewModulesHolder
diff --git a/lib/nfc/nfc_device.c b/lib/nfc/nfc_device.c
index 9da891327..0bfdb3dac 100644
--- a/lib/nfc/nfc_device.c
+++ b/lib/nfc/nfc_device.c
@@ -1217,6 +1217,7 @@ void nfc_device_data_clear(NfcDeviceData* dev_data) {
void nfc_device_clear(NfcDevice* dev) {
furi_assert(dev);
+ nfc_device_set_name(dev, "");
nfc_device_data_clear(&dev->dev_data);
dev->format = NfcDeviceSaveFormatUid;
string_reset(dev->load_path);
diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c
index a92f148a2..45bbc5f41 100644
--- a/lib/nfc/nfc_worker.c
+++ b/lib/nfc/nfc_worker.c
@@ -143,7 +143,7 @@ static bool nfc_worker_read_mf_classic(NfcWorker* nfc_worker, FuriHalNfcTxRxCont
if(nfc_supported_card[i].verify(nfc_worker, tx_rx)) {
if(nfc_supported_card[i].read(nfc_worker, tx_rx)) {
read_success = true;
- nfc_supported_card[i].parse(nfc_worker);
+ nfc_supported_card[i].parse(nfc_worker->dev_data);
}
}
}
diff --git a/lib/nfc/parsers/nfc_supported_card.c b/lib/nfc/parsers/nfc_supported_card.c
index 59482a123..480c970e7 100644
--- a/lib/nfc/parsers/nfc_supported_card.c
+++ b/lib/nfc/parsers/nfc_supported_card.c
@@ -11,3 +11,17 @@ NfcSupportedCard nfc_supported_card[NfcSupportedCardTypeEnd] = {
.parse = troyka_parser_parse,
},
};
+
+bool nfc_supported_card_verify_and_parse(NfcDeviceData* dev_data) {
+ furi_assert(dev_data);
+
+ bool card_parsed = false;
+ for(size_t i = 0; i < COUNT_OF(nfc_supported_card); i++) {
+ if(nfc_supported_card[i].parse(dev_data)) {
+ card_parsed = true;
+ break;
+ }
+ }
+
+ return card_parsed;
+}
diff --git a/lib/nfc/parsers/nfc_supported_card.h b/lib/nfc/parsers/nfc_supported_card.h
index 5c94c78cd..9b5d1c053 100644
--- a/lib/nfc/parsers/nfc_supported_card.h
+++ b/lib/nfc/parsers/nfc_supported_card.h
@@ -2,6 +2,7 @@
#include
#include "../nfc_worker.h"
+#include "../nfc_device.h"
#include
@@ -15,7 +16,7 @@ typedef bool (*NfcSupportedCardVerify)(NfcWorker* nfc_worker, FuriHalNfcTxRxCont
typedef bool (*NfcSupportedCardRead)(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx);
-typedef bool (*NfcSupportedCardParse)(NfcWorker* nfc_worker);
+typedef bool (*NfcSupportedCardParse)(NfcDeviceData* dev_data);
typedef struct {
NfcProtocol protocol;
@@ -25,3 +26,5 @@ typedef struct {
} NfcSupportedCard;
extern NfcSupportedCard nfc_supported_card[NfcSupportedCardTypeEnd];
+
+bool nfc_supported_card_verify_and_parse(NfcDeviceData* dev_data);
diff --git a/lib/nfc/parsers/troyka_parser.c b/lib/nfc/parsers/troyka_parser.c
index 3167b5181..51ffa42e1 100644
--- a/lib/nfc/parsers/troyka_parser.c
+++ b/lib/nfc/parsers/troyka_parser.c
@@ -49,23 +49,31 @@ bool troyka_parser_read(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) {
return mf_classic_read_card(tx_rx, &reader, &nfc_worker->dev_data->mf_classic_data) == 16;
}
-bool troyka_parser_parse(NfcWorker* nfc_worker) {
- MfClassicData* data = &nfc_worker->dev_data->mf_classic_data;
- uint8_t* temp_ptr = &data->block[8 * 4 + 1].value[5];
- uint16_t balance = ((temp_ptr[0] << 8) | temp_ptr[1]) / 25;
- temp_ptr = &data->block[8 * 4].value[3];
- uint32_t number = 0;
- for(size_t i = 0; i < 4; i++) {
- number <<= 8;
- number |= temp_ptr[i];
- }
- number >>= 4;
+bool troyka_parser_parse(NfcDeviceData* dev_data) {
+ MfClassicData* data = &dev_data->mf_classic_data;
+ bool troyka_parsed = false;
- string_printf(
- nfc_worker->dev_data->parsed_data,
- "Troyka Transport card\nNumber: %ld\nBalance: %d rub",
- number,
- balance);
+ do {
+ // Verify key
+ MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, 8);
+ uint64_t key = nfc_util_bytes2num(sec_tr->key_a, 6);
+ if(key != troyka_keys[8].key_a) break;
- return true;
+ // Parse data
+ uint8_t* temp_ptr = &data->block[8 * 4 + 1].value[5];
+ uint16_t balance = ((temp_ptr[0] << 8) | temp_ptr[1]) / 25;
+ temp_ptr = &data->block[8 * 4].value[3];
+ uint32_t number = 0;
+ for(size_t i = 0; i < 4; i++) {
+ number <<= 8;
+ number |= temp_ptr[i];
+ }
+ number >>= 4;
+
+ string_printf(
+ dev_data->parsed_data, "\e#Troyka\nNum: %ld\nBalance: %d rur.", number, balance);
+ troyka_parsed = true;
+ } while(false);
+
+ return troyka_parsed;
}
diff --git a/lib/nfc/parsers/troyka_parser.h b/lib/nfc/parsers/troyka_parser.h
index 0d5cee233..445fe40e5 100644
--- a/lib/nfc/parsers/troyka_parser.h
+++ b/lib/nfc/parsers/troyka_parser.h
@@ -6,4 +6,4 @@ bool troyka_parser_verify(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx);
bool troyka_parser_read(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx);
-bool troyka_parser_parse(NfcWorker* nfc_worker);
+bool troyka_parser_parse(NfcDeviceData* dev_data);
diff --git a/lib/nfc/protocols/mifare_ultralight.c b/lib/nfc/protocols/mifare_ultralight.c
index c043f2069..f637d378a 100644
--- a/lib/nfc/protocols/mifare_ultralight.c
+++ b/lib/nfc/protocols/mifare_ultralight.c
@@ -191,7 +191,7 @@ bool mf_ultralight_authenticate(FuriHalNfcTxRxContext* tx_rx, uint32_t key, uint
}
if(pack != NULL) {
- *pack = (tx_rx->rx_data[0] << 8) | tx_rx->rx_data[1];
+ *pack = (tx_rx->rx_data[1] << 8) | tx_rx->rx_data[0];
}
FURI_LOG_I(TAG, "Auth success. Password: %08X. PACK: %04X", key, *pack);
@@ -697,48 +697,6 @@ bool mf_ultralight_read_counters(FuriHalNfcTxRxContext* tx_rx, MfUltralightData*
return counter_read == (is_single_counter ? 1 : 3);
}
-int16_t mf_ultralight_get_authlim(
- FuriHalNfcTxRxContext* tx_rx,
- MfUltralightReader* reader,
- MfUltralightData* data) {
- mf_ultralight_read_version(tx_rx, reader, data);
- if(!(reader->supported_features & MfUltralightSupportAuth)) {
- // No authentication
- return -2;
- }
-
- uint8_t config_pages_index;
- if(data->type >= MfUltralightTypeUL11 && data->type <= MfUltralightTypeNTAG216) {
- config_pages_index = reader->pages_to_read - 4;
- } else if(
- data->type >= MfUltralightTypeNTAGI2CPlus1K &&
- data->type <= MfUltralightTypeNTAGI2CPlus1K) {
- config_pages_index = 0xe3;
- } else {
- // No config pages
- return -2;
- }
-
- if(!mf_ultralight_read_pages_direct(tx_rx, config_pages_index, data->data)) {
- // Config pages are not readable due to protection
- return -1;
- }
-
- MfUltralightConfigPages* config_pages = (MfUltralightConfigPages*)&data->data;
- if(config_pages->auth0 >= reader->pages_to_read) {
- // Authentication is not configured
- return -2;
- }
-
- int16_t authlim = config_pages->access.authlim;
- if(authlim > 0 && data->type >= MfUltralightTypeNTAGI2CPlus1K &&
- data->type <= MfUltralightTypeNTAGI2CPlus2K) {
- authlim = 1 << authlim;
- }
-
- return authlim;
-}
-
bool mf_ultralight_read_tearing_flags(FuriHalNfcTxRxContext* tx_rx, MfUltralightData* data) {
uint8_t flag_read = 0;
diff --git a/lib/nfc/protocols/mifare_ultralight.h b/lib/nfc/protocols/mifare_ultralight.h
index 727bffab2..9642824f7 100644
--- a/lib/nfc/protocols/mifare_ultralight.h
+++ b/lib/nfc/protocols/mifare_ultralight.h
@@ -56,13 +56,6 @@ typedef enum {
MfUltralightTypeNum,
} MfUltralightType;
-typedef enum {
- MfUltralightAuthLimitUnknown,
- MfUltralightAuthLimitNotSupported,
- MfUltralightAuthLimitConfigured,
- MfUltralightAuthLimitNotConfigured,
-} MfUltralightAuthLimit;
-
typedef enum {
MfUltralightSupportNone = 0,
MfUltralightSupportFastRead = 1 << 0,
@@ -245,11 +238,6 @@ bool mf_ul_prepare_emulation_response(
uint32_t* data_type,
void* context);
-int16_t mf_ultralight_get_authlim(
- FuriHalNfcTxRxContext* tx_rx,
- MfUltralightReader* reader,
- MfUltralightData* data);
-
uint32_t mf_ul_pwdgen_amiibo(FuriHalNfcDevData* data);
uint32_t mf_ul_pwdgen_xiaomi(FuriHalNfcDevData* data);
diff --git a/lib/subghz/blocks/encoder.h b/lib/subghz/blocks/encoder.h
index 80ffe4900..6ad734cbd 100644
--- a/lib/subghz/blocks/encoder.h
+++ b/lib/subghz/blocks/encoder.h
@@ -7,7 +7,7 @@
#include
typedef struct {
- bool is_runing;
+ bool is_running;
size_t repeat;
size_t front;
size_t size_upload;
diff --git a/lib/subghz/blocks/math.c b/lib/subghz/blocks/math.c
index 55ad7cc80..fca50c8f8 100644
--- a/lib/subghz/blocks/math.c
+++ b/lib/subghz/blocks/math.c
@@ -7,3 +7,11 @@ uint64_t subghz_protocol_blocks_reverse_key(uint64_t key, uint8_t count_bit) {
}
return key_reverse;
}
+
+uint8_t subghz_protocol_blocks_get_parity(uint64_t key, uint8_t count_bit) {
+ uint8_t parity = 0;
+ for(uint8_t i = 0; i < count_bit; i++) {
+ parity += bit_read(key, i);
+ }
+ return parity & 0x01;
+}
\ No newline at end of file
diff --git a/lib/subghz/blocks/math.h b/lib/subghz/blocks/math.h
index fde5191bd..85b146ebc 100644
--- a/lib/subghz/blocks/math.h
+++ b/lib/subghz/blocks/math.h
@@ -17,3 +17,11 @@
* @return Reverse data
*/
uint64_t subghz_protocol_blocks_reverse_key(uint64_t key, uint8_t count_bit);
+
+/**
+ * Get parity the data bitwise.
+ * @param key In data
+ * @param count_bit number of data bits
+ * @return parity
+ */
+uint8_t subghz_protocol_blocks_get_parity(uint64_t key, uint8_t count_bit);
diff --git a/lib/subghz/protocols/bett.c b/lib/subghz/protocols/bett.c
index e32679d27..aca8b8c4f 100644
--- a/lib/subghz/protocols/bett.c
+++ b/lib/subghz/protocols/bett.c
@@ -94,7 +94,7 @@ void* subghz_protocol_encoder_bett_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 10;
instance->encoder.size_upload = 52; //max 24bit*2 + 2 (start, stop)
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -174,7 +174,7 @@ bool subghz_protocol_encoder_bett_deserialize(void* context, FlipperFormat* flip
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
subghz_protocol_encoder_bett_get_upload(instance);
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -184,14 +184,14 @@ bool subghz_protocol_encoder_bett_deserialize(void* context, FlipperFormat* flip
void subghz_protocol_encoder_bett_stop(void* context) {
SubGhzProtocolEncoderBETT* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_bett_yield(void* context) {
SubGhzProtocolEncoderBETT* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
@@ -231,16 +231,16 @@ void subghz_protocol_decoder_bett_feed(void* context, bool level, uint32_t durat
switch(instance->decoder.parser_step) {
case BETTDecoderStepReset:
- if((!level) && (DURATION_DIFF(duration, subghz_protocol_bett_const.te_short * 42) <
- subghz_protocol_bett_const.te_delta * 21)) {
+ if((!level) && (DURATION_DIFF(duration, subghz_protocol_bett_const.te_short * 44) <
+ (subghz_protocol_bett_const.te_delta * 15))) {
//Found Preambula
instance->decoder.parser_step = BETTDecoderStepCheckDuration;
}
break;
case BETTDecoderStepSaveDuration:
if(!level) {
- if(duration >= ((uint32_t)subghz_protocol_bett_const.te_short * 10 +
- subghz_protocol_bett_const.te_delta)) {
+ if(DURATION_DIFF(duration, subghz_protocol_bett_const.te_short * 44) <
+ (subghz_protocol_bett_const.te_delta * 15)) {
instance->decoder.parser_step = BETTDecoderStepSaveDuration;
if(instance->decoder.decode_count_bit ==
subghz_protocol_bett_const.min_count_bit_for_found) {
diff --git a/lib/subghz/protocols/came.c b/lib/subghz/protocols/came.c
index d28b735c5..37048017e 100644
--- a/lib/subghz/protocols/came.c
+++ b/lib/subghz/protocols/came.c
@@ -85,7 +85,7 @@ void* subghz_protocol_encoder_came_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 10;
instance->encoder.size_upload = 52; //max 24bit*2 + 2 (start, stop)
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -157,7 +157,7 @@ bool subghz_protocol_encoder_came_deserialize(void* context, FlipperFormat* flip
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
subghz_protocol_encoder_came_get_upload(instance);
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -167,14 +167,14 @@ bool subghz_protocol_encoder_came_deserialize(void* context, FlipperFormat* flip
void subghz_protocol_encoder_came_stop(void* context) {
SubGhzProtocolEncoderCame* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_came_yield(void* context) {
SubGhzProtocolEncoderCame* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/came_atomo.c b/lib/subghz/protocols/came_atomo.c
index a20ebeaf4..57f2d3b4c 100644
--- a/lib/subghz/protocols/came_atomo.c
+++ b/lib/subghz/protocols/came_atomo.c
@@ -81,7 +81,7 @@ void* subghz_protocol_encoder_came_atomo_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 10;
instance->encoder.size_upload = 4096; //approx max buffer size
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -245,7 +245,7 @@ bool subghz_protocol_encoder_came_atomo_deserialize(void* context, FlipperFormat
break;
}
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -255,14 +255,14 @@ bool subghz_protocol_encoder_came_atomo_deserialize(void* context, FlipperFormat
void subghz_protocol_encoder_came_atomo_stop(void* context) {
SubGhzProtocolEncoderCameAtomo* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_came_atomo_yield(void* context) {
SubGhzProtocolEncoderCameAtomo* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/came_twee.c b/lib/subghz/protocols/came_twee.c
index ef352bf60..b5b409c59 100644
--- a/lib/subghz/protocols/came_twee.c
+++ b/lib/subghz/protocols/came_twee.c
@@ -112,7 +112,7 @@ void* subghz_protocol_encoder_came_twee_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 10;
instance->encoder.size_upload = 1536; //max upload 92*14 = 1288 !!!!
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -261,7 +261,7 @@ bool subghz_protocol_encoder_came_twee_deserialize(void* context, FlipperFormat*
subghz_protocol_came_twee_remote_controller(&instance->generic);
subghz_protocol_encoder_came_twee_get_upload(instance);
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -271,14 +271,14 @@ bool subghz_protocol_encoder_came_twee_deserialize(void* context, FlipperFormat*
void subghz_protocol_encoder_came_twee_stop(void* context) {
SubGhzProtocolEncoderCameTwee* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_came_twee_yield(void* context) {
SubGhzProtocolEncoderCameTwee* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
@@ -455,7 +455,7 @@ void subghz_protocol_decoder_came_twee_get_string(void* context, string_t output
string_cat_printf(
output,
- "%s %dbit\r\n"
+ "%s %db\r\n"
"Key:0x%lX%08lX\r\n"
"Btn:%lX\r\n"
"DIP:" DIP_PATTERN "\r\n",
diff --git a/lib/subghz/protocols/chamberlain_code.c b/lib/subghz/protocols/chamberlain_code.c
index 3128b71ec..6c99d8451 100644
--- a/lib/subghz/protocols/chamberlain_code.c
+++ b/lib/subghz/protocols/chamberlain_code.c
@@ -108,7 +108,7 @@ void* subghz_protocol_encoder_chamb_code_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 10;
instance->encoder.size_upload = 24;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -225,7 +225,7 @@ bool subghz_protocol_encoder_chamb_code_deserialize(void* context, FlipperFormat
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
subghz_protocol_encoder_chamb_code_get_upload(instance);
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -235,14 +235,14 @@ bool subghz_protocol_encoder_chamb_code_deserialize(void* context, FlipperFormat
void subghz_protocol_encoder_chamb_code_stop(void* context) {
SubGhzProtocolEncoderChamb_Code* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_chamb_code_yield(void* context) {
SubGhzProtocolEncoderChamb_Code* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/doitrand.c b/lib/subghz/protocols/doitrand.c
index c26cbc5b6..9a0a58190 100644
--- a/lib/subghz/protocols/doitrand.c
+++ b/lib/subghz/protocols/doitrand.c
@@ -85,7 +85,7 @@ void* subghz_protocol_encoder_doitrand_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 10;
instance->encoder.size_upload = 128;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -155,7 +155,7 @@ bool subghz_protocol_encoder_doitrand_deserialize(void* context, FlipperFormat*
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
subghz_protocol_encoder_doitrand_get_upload(instance);
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -165,14 +165,14 @@ bool subghz_protocol_encoder_doitrand_deserialize(void* context, FlipperFormat*
void subghz_protocol_encoder_doitrand_stop(void* context) {
SubGhzProtocolEncoderDoitrand* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_doitrand_yield(void* context) {
SubGhzProtocolEncoderDoitrand* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c
index 03c2786bf..3927ed68f 100644
--- a/lib/subghz/protocols/faac_slh.c
+++ b/lib/subghz/protocols/faac_slh.c
@@ -99,7 +99,7 @@ void* subghz_protocol_encoder_faac_slh_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 10;
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -260,7 +260,7 @@ bool subghz_protocol_encoder_faac_slh_deserialize(void* context, FlipperFormat*
break;
}
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -270,14 +270,14 @@ bool subghz_protocol_encoder_faac_slh_deserialize(void* context, FlipperFormat*
void subghz_protocol_encoder_faac_slh_stop(void* context) {
SubGhzProtocolEncoderFaacSLH* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_faac_slh_yield(void* context) {
SubGhzProtocolEncoderFaacSLH* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/gate_tx.c b/lib/subghz/protocols/gate_tx.c
index 66174d011..d7efb3862 100644
--- a/lib/subghz/protocols/gate_tx.c
+++ b/lib/subghz/protocols/gate_tx.c
@@ -78,7 +78,7 @@ void* subghz_protocol_encoder_gate_tx_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 10;
instance->encoder.size_upload = 52; //max 24bit*2 + 2 (start, stop)
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -148,7 +148,7 @@ bool subghz_protocol_encoder_gate_tx_deserialize(void* context, FlipperFormat* f
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
subghz_protocol_encoder_gate_tx_get_upload(instance);
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -158,14 +158,14 @@ bool subghz_protocol_encoder_gate_tx_deserialize(void* context, FlipperFormat* f
void subghz_protocol_encoder_gate_tx_stop(void* context) {
SubGhzProtocolEncoderGateTx* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_gate_tx_yield(void* context) {
SubGhzProtocolEncoderGateTx* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/holtek.c b/lib/subghz/protocols/holtek.c
index ed5e4fb54..137ba85d3 100644
--- a/lib/subghz/protocols/holtek.c
+++ b/lib/subghz/protocols/holtek.c
@@ -89,7 +89,7 @@ void* subghz_protocol_encoder_holtek_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 10;
instance->encoder.size_upload = 128;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -161,7 +161,7 @@ bool subghz_protocol_encoder_holtek_deserialize(void* context, FlipperFormat* fl
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
subghz_protocol_encoder_holtek_get_upload(instance);
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -171,14 +171,14 @@ bool subghz_protocol_encoder_holtek_deserialize(void* context, FlipperFormat* fl
void subghz_protocol_encoder_holtek_stop(void* context) {
SubGhzProtocolEncoderHoltek* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_holtek_yield(void* context) {
SubGhzProtocolEncoderHoltek* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/honeywell_wdb.c b/lib/subghz/protocols/honeywell_wdb.c
new file mode 100644
index 000000000..e1e21426d
--- /dev/null
+++ b/lib/subghz/protocols/honeywell_wdb.c
@@ -0,0 +1,399 @@
+#include "honeywell_wdb.h"
+
+#include "../blocks/const.h"
+#include "../blocks/decoder.h"
+#include "../blocks/encoder.h"
+#include "../blocks/generic.h"
+#include "../blocks/math.h"
+
+#define TAG "SubGhzProtocolHoneywellWDB"
+
+/*
+ *
+ * https://github.com/klohner/honeywell-wireless-doorbell
+ *
+ */
+
+static const SubGhzBlockConst subghz_protocol_honeywell_wdb_const = {
+ .te_short = 160,
+ .te_long = 320,
+ .te_delta = 60,
+ .min_count_bit_for_found = 48,
+};
+
+struct SubGhzProtocolDecoderHoneywell_WDB {
+ SubGhzProtocolDecoderBase base;
+
+ SubGhzBlockDecoder decoder;
+ SubGhzBlockGeneric generic;
+ const char* device_type;
+ const char* alert;
+ uint8_t secret_knock;
+ uint8_t relay;
+ uint8_t lowbat;
+};
+
+struct SubGhzProtocolEncoderHoneywell_WDB {
+ SubGhzProtocolEncoderBase base;
+
+ SubGhzProtocolBlockEncoder encoder;
+ SubGhzBlockGeneric generic;
+};
+
+typedef enum {
+ Honeywell_WDBDecoderStepReset = 0,
+ Honeywell_WDBDecoderStepFoundStartBit,
+ Honeywell_WDBDecoderStepSaveDuration,
+ Honeywell_WDBDecoderStepCheckDuration,
+} Honeywell_WDBDecoderStep;
+
+const SubGhzProtocolDecoder subghz_protocol_honeywell_wdb_decoder = {
+ .alloc = subghz_protocol_decoder_honeywell_wdb_alloc,
+ .free = subghz_protocol_decoder_honeywell_wdb_free,
+
+ .feed = subghz_protocol_decoder_honeywell_wdb_feed,
+ .reset = subghz_protocol_decoder_honeywell_wdb_reset,
+
+ .get_hash_data = subghz_protocol_decoder_honeywell_wdb_get_hash_data,
+ .serialize = subghz_protocol_decoder_honeywell_wdb_serialize,
+ .deserialize = subghz_protocol_decoder_honeywell_wdb_deserialize,
+ .get_string = subghz_protocol_decoder_honeywell_wdb_get_string,
+};
+
+const SubGhzProtocolEncoder subghz_protocol_honeywell_wdb_encoder = {
+ .alloc = subghz_protocol_encoder_honeywell_wdb_alloc,
+ .free = subghz_protocol_encoder_honeywell_wdb_free,
+
+ .deserialize = subghz_protocol_encoder_honeywell_wdb_deserialize,
+ .stop = subghz_protocol_encoder_honeywell_wdb_stop,
+ .yield = subghz_protocol_encoder_honeywell_wdb_yield,
+};
+
+const SubGhzProtocol subghz_protocol_honeywell_wdb = {
+ .name = SUBGHZ_PROTOCOL_HONEYWELL_WDB_NAME,
+ .type = SubGhzProtocolTypeStatic,
+ .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_AM |
+ SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save |
+ SubGhzProtocolFlag_Send,
+
+ .decoder = &subghz_protocol_honeywell_wdb_decoder,
+ .encoder = &subghz_protocol_honeywell_wdb_encoder,
+};
+
+void* subghz_protocol_encoder_honeywell_wdb_alloc(SubGhzEnvironment* environment) {
+ UNUSED(environment);
+ SubGhzProtocolEncoderHoneywell_WDB* instance =
+ malloc(sizeof(SubGhzProtocolEncoderHoneywell_WDB));
+
+ instance->base.protocol = &subghz_protocol_honeywell_wdb;
+ instance->generic.protocol_name = instance->base.protocol->name;
+
+ instance->encoder.repeat = 10;
+ instance->encoder.size_upload = 128;
+ instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
+ instance->encoder.is_running = false;
+ return instance;
+}
+
+void subghz_protocol_encoder_honeywell_wdb_free(void* context) {
+ furi_assert(context);
+ SubGhzProtocolEncoderHoneywell_WDB* instance = context;
+ free(instance->encoder.upload);
+ free(instance);
+}
+
+/**
+ * Generating an upload from data.
+ * @param instance Pointer to a SubGhzProtocolEncoderHoneywell_WDB instance
+ * @return true On success
+ */
+static bool subghz_protocol_encoder_honeywell_wdb_get_upload(
+ SubGhzProtocolEncoderHoneywell_WDB* instance) {
+ furi_assert(instance);
+ size_t index = 0;
+ size_t size_upload = (instance->generic.data_count_bit * 2) + 2;
+ if(size_upload > instance->encoder.size_upload) {
+ FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer.");
+ return false;
+ } else {
+ instance->encoder.size_upload = size_upload;
+ }
+ //Send header
+ instance->encoder.upload[index++] =
+ level_duration_make(false, (uint32_t)subghz_protocol_honeywell_wdb_const.te_short * 3);
+ //Send key data
+ for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) {
+ if(bit_read(instance->generic.data, i - 1)) {
+ //send bit 1
+ instance->encoder.upload[index++] =
+ level_duration_make(true, (uint32_t)subghz_protocol_honeywell_wdb_const.te_long);
+ instance->encoder.upload[index++] =
+ level_duration_make(false, (uint32_t)subghz_protocol_honeywell_wdb_const.te_short);
+ } else {
+ //send bit 0
+ instance->encoder.upload[index++] =
+ level_duration_make(true, (uint32_t)subghz_protocol_honeywell_wdb_const.te_short);
+ instance->encoder.upload[index++] =
+ level_duration_make(false, (uint32_t)subghz_protocol_honeywell_wdb_const.te_long);
+ }
+ }
+ instance->encoder.upload[index++] =
+ level_duration_make(true, (uint32_t)subghz_protocol_honeywell_wdb_const.te_short * 3);
+ return true;
+}
+
+bool subghz_protocol_encoder_honeywell_wdb_deserialize(
+ void* context,
+ FlipperFormat* flipper_format) {
+ furi_assert(context);
+ SubGhzProtocolEncoderHoneywell_WDB* instance = context;
+ bool res = false;
+ do {
+ if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
+ FURI_LOG_E(TAG, "Deserialize error");
+ break;
+ }
+ if(instance->generic.data_count_bit !=
+ subghz_protocol_honeywell_wdb_const.min_count_bit_for_found) {
+ FURI_LOG_E(TAG, "Wrong number of bits in key");
+ break;
+ }
+ //optional parameter parameter
+ flipper_format_read_uint32(
+ flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
+
+ subghz_protocol_encoder_honeywell_wdb_get_upload(instance);
+ instance->encoder.is_running = true;
+
+ res = true;
+ } while(false);
+
+ return res;
+}
+
+void subghz_protocol_encoder_honeywell_wdb_stop(void* context) {
+ SubGhzProtocolEncoderHoneywell_WDB* instance = context;
+ instance->encoder.is_running = false;
+}
+
+LevelDuration subghz_protocol_encoder_honeywell_wdb_yield(void* context) {
+ SubGhzProtocolEncoderHoneywell_WDB* instance = context;
+
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
+ return level_duration_reset();
+ }
+
+ LevelDuration ret = instance->encoder.upload[instance->encoder.front];
+
+ if(++instance->encoder.front == instance->encoder.size_upload) {
+ instance->encoder.repeat--;
+ instance->encoder.front = 0;
+ }
+
+ return ret;
+}
+
+void* subghz_protocol_decoder_honeywell_wdb_alloc(SubGhzEnvironment* environment) {
+ UNUSED(environment);
+ SubGhzProtocolDecoderHoneywell_WDB* instance =
+ malloc(sizeof(SubGhzProtocolDecoderHoneywell_WDB));
+ instance->base.protocol = &subghz_protocol_honeywell_wdb;
+ instance->generic.protocol_name = instance->base.protocol->name;
+ return instance;
+}
+
+void subghz_protocol_decoder_honeywell_wdb_free(void* context) {
+ furi_assert(context);
+ SubGhzProtocolDecoderHoneywell_WDB* instance = context;
+ free(instance);
+}
+
+void subghz_protocol_decoder_honeywell_wdb_reset(void* context) {
+ furi_assert(context);
+ SubGhzProtocolDecoderHoneywell_WDB* instance = context;
+ instance->decoder.parser_step = Honeywell_WDBDecoderStepReset;
+}
+
+void subghz_protocol_decoder_honeywell_wdb_feed(void* context, bool level, uint32_t duration) {
+ furi_assert(context);
+ SubGhzProtocolDecoderHoneywell_WDB* instance = context;
+ switch(instance->decoder.parser_step) {
+ case Honeywell_WDBDecoderStepReset:
+ if((!level) && (DURATION_DIFF(duration, subghz_protocol_honeywell_wdb_const.te_short * 3) <
+ subghz_protocol_honeywell_wdb_const.te_delta)) {
+ //Found header Honeywell_WDB
+ instance->decoder.decode_count_bit = 0;
+ instance->decoder.decode_data = 0;
+ instance->decoder.parser_step = Honeywell_WDBDecoderStepSaveDuration;
+ }
+ break;
+ case Honeywell_WDBDecoderStepSaveDuration:
+ if(level) { //save interval
+ if(DURATION_DIFF(duration, subghz_protocol_honeywell_wdb_const.te_short * 3) <
+ subghz_protocol_honeywell_wdb_const.te_delta) {
+ if((instance->decoder.decode_count_bit ==
+ subghz_protocol_honeywell_wdb_const.min_count_bit_for_found) &&
+ ((instance->decoder.decode_data & 0x01) ==
+ subghz_protocol_blocks_get_parity(
+ instance->decoder.decode_data >> 1,
+ subghz_protocol_honeywell_wdb_const.min_count_bit_for_found - 1))) {
+ instance->generic.data = instance->decoder.decode_data;
+ instance->generic.data_count_bit = instance->decoder.decode_count_bit;
+
+ if(instance->base.callback)
+ instance->base.callback(&instance->base, instance->base.context);
+ }
+ instance->decoder.parser_step = Honeywell_WDBDecoderStepReset;
+ break;
+ }
+ instance->decoder.te_last = duration;
+ instance->decoder.parser_step = Honeywell_WDBDecoderStepCheckDuration;
+ } else {
+ instance->decoder.parser_step = Honeywell_WDBDecoderStepReset;
+ }
+ break;
+ case Honeywell_WDBDecoderStepCheckDuration:
+ if(!level) {
+ if((DURATION_DIFF(
+ instance->decoder.te_last, subghz_protocol_honeywell_wdb_const.te_short) <
+ subghz_protocol_honeywell_wdb_const.te_delta) &&
+ (DURATION_DIFF(duration, subghz_protocol_honeywell_wdb_const.te_long) <
+ subghz_protocol_honeywell_wdb_const.te_delta)) {
+ subghz_protocol_blocks_add_bit(&instance->decoder, 0);
+ instance->decoder.parser_step = Honeywell_WDBDecoderStepSaveDuration;
+ } else if(
+ (DURATION_DIFF(
+ instance->decoder.te_last, subghz_protocol_honeywell_wdb_const.te_long) <
+ subghz_protocol_honeywell_wdb_const.te_delta) &&
+ (DURATION_DIFF(duration, subghz_protocol_honeywell_wdb_const.te_short) <
+ subghz_protocol_honeywell_wdb_const.te_delta)) {
+ subghz_protocol_blocks_add_bit(&instance->decoder, 1);
+ instance->decoder.parser_step = Honeywell_WDBDecoderStepSaveDuration;
+ } else
+ instance->decoder.parser_step = Honeywell_WDBDecoderStepReset;
+ } else {
+ instance->decoder.parser_step = Honeywell_WDBDecoderStepReset;
+ }
+ break;
+ }
+}
+
+/**
+ * Analysis of received data
+ * @param instance Pointer to a SubGhzProtocolDecoderHoneywell_WDB* instance
+ */
+static void subghz_protocol_honeywell_wdb_check_remote_controller(
+ SubGhzProtocolDecoderHoneywell_WDB* instance) {
+ /*
+ *
+ * Frame bits used in Honeywell RCWL300A, RCWL330A, Series 3, 5, 9 and all Decor Series Wireless Chimes
+ * 0000 0000 1111 1111 2222 2222 3333 3333 4444 4444 5555 5555
+ * 7654 3210 7654 3210 7654 3210 7654 3210 7654 3210 7654 3210
+ * XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XX.. XXX. .... KEY DATA (any change and receiver doesn't seem to recognize signal)
+ * XXXX XXXX XXXX XXXX XXXX .... .... .... .... .... .... .... KEY ID (different for each transmitter)
+ * .... .... .... .... .... 0000 00.. 0000 0000 00.. 000. .... KEY UNKNOWN 0 (always 0 in devices I've tested)
+ * .... .... .... .... .... .... ..XX .... .... .... .... .... DEVICE TYPE (10 = doorbell, 01 = PIR Motion sensor)
+ * .... .... .... .... .... .... .... .... .... ..XX ...X XXX. FLAG DATA (may be modified for possible effects on receiver)
+ * .... .... .... .... .... .... .... .... .... ..XX .... .... ALERT (00 = normal, 01 or 10 = right-left halo light pattern, 11 = full volume alarm)
+ * .... .... .... .... .... .... .... .... .... .... ...X .... SECRET KNOCK (0 = default, 1 if doorbell is pressed 3x rapidly)
+ * .... .... .... .... .... .... .... .... .... .... .... X... RELAY (1 if signal is a retransmission of a received transmission, only some models)
+ * .... .... .... .... .... .... .... .... .... .... .... .X.. FLAG UNKNOWN (0 = default, but 1 is accepted and I don't observe any effects)
+ * .... .... .... .... .... .... .... .... .... .... .... ..X. LOWBAT (1 if battery is low, receiver gives low battery alert)
+ * .... .... .... .... .... .... .... .... .... .... .... ...X PARITY (LSB of count of set bits in previous 47 bits)
+ *
+ */
+
+ instance->generic.serial = (instance->generic.data >> 28) & 0xFFFFF;
+ switch((instance->generic.data >> 20) & 0x3) {
+ case 0x02:
+ instance->device_type = "Doorbell";
+ break;
+ case 0x01:
+ instance->device_type = "PIR-Motion";
+ break;
+ default:
+ instance->device_type = "Unknown";
+ break;
+ }
+
+ switch((instance->generic.data >> 16) & 0x3) {
+ case 0x00:
+ instance->alert = "Normal";
+ break;
+ case 0x01:
+ case 0x02:
+ instance->alert = "High";
+ break;
+ case 0x03:
+ instance->alert = "Full";
+ break;
+ default:
+ instance->alert = "Unknown";
+ break;
+ }
+
+ instance->secret_knock = (uint8_t)((instance->generic.data >> 4) & 0x1);
+ instance->relay = (uint8_t)((instance->generic.data >> 3) & 0x1);
+ instance->lowbat = (uint8_t)((instance->generic.data >> 1) & 0x1);
+}
+
+uint8_t subghz_protocol_decoder_honeywell_wdb_get_hash_data(void* context) {
+ furi_assert(context);
+ SubGhzProtocolDecoderHoneywell_WDB* instance = context;
+ return subghz_protocol_blocks_get_hash_data(
+ &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
+}
+
+bool subghz_protocol_decoder_honeywell_wdb_serialize(
+ void* context,
+ FlipperFormat* flipper_format,
+ SubGhzPresetDefinition* preset) {
+ furi_assert(context);
+ SubGhzProtocolDecoderHoneywell_WDB* instance = context;
+ return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
+}
+
+bool subghz_protocol_decoder_honeywell_wdb_deserialize(
+ void* context,
+ FlipperFormat* flipper_format) {
+ furi_assert(context);
+ SubGhzProtocolDecoderHoneywell_WDB* instance = context;
+ bool ret = false;
+ do {
+ if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
+ break;
+ }
+ if(instance->generic.data_count_bit !=
+ subghz_protocol_honeywell_wdb_const.min_count_bit_for_found) {
+ FURI_LOG_E(TAG, "Wrong number of bits in key");
+ break;
+ }
+ ret = true;
+ } while(false);
+ return ret;
+}
+
+void subghz_protocol_decoder_honeywell_wdb_get_string(void* context, string_t output) {
+ furi_assert(context);
+ SubGhzProtocolDecoderHoneywell_WDB* instance = context;
+ subghz_protocol_honeywell_wdb_check_remote_controller(instance);
+
+ string_cat_printf(
+ output,
+ "%s %dbit\r\n"
+ "Key:0x%lX%08lX\r\n"
+ "Sn:0x%05lX\r\n"
+ "DT:%s Al:%s\r\n"
+ "SK:%01lX R:%01lX LBat:%01lX\r\n",
+ instance->generic.protocol_name,
+ instance->generic.data_count_bit,
+ (uint32_t)((instance->generic.data >> 32) & 0xFFFFFFFF),
+ (uint32_t)(instance->generic.data & 0xFFFFFFFF),
+ instance->generic.serial,
+ instance->device_type,
+ instance->alert,
+ instance->secret_knock,
+ instance->relay,
+ instance->lowbat);
+}
diff --git a/lib/subghz/protocols/honeywell_wdb.h b/lib/subghz/protocols/honeywell_wdb.h
new file mode 100644
index 000000000..012b36996
--- /dev/null
+++ b/lib/subghz/protocols/honeywell_wdb.h
@@ -0,0 +1,111 @@
+#pragma once
+
+#include "base.h"
+
+#define SUBGHZ_PROTOCOL_HONEYWELL_WDB_NAME "Honeywell"
+
+typedef struct SubGhzProtocolDecoderHoneywell_WDB SubGhzProtocolDecoderHoneywell_WDB;
+typedef struct SubGhzProtocolEncoderHoneywell_WDB SubGhzProtocolEncoderHoneywell_WDB;
+
+extern const SubGhzProtocolDecoder subghz_protocol_honeywell_wdb_decoder;
+extern const SubGhzProtocolEncoder subghz_protocol_honeywell_wdb_encoder;
+extern const SubGhzProtocol subghz_protocol_honeywell_wdb;
+
+/**
+ * Allocate SubGhzProtocolEncoderHoneywell_WDB.
+ * @param environment Pointer to a SubGhzEnvironment instance
+ * @return SubGhzProtocolEncoderHoneywell_WDB* pointer to a SubGhzProtocolEncoderHoneywell_WDB instance
+ */
+void* subghz_protocol_encoder_honeywell_wdb_alloc(SubGhzEnvironment* environment);
+
+/**
+ * Free SubGhzProtocolEncoderHoneywell_WDB.
+ * @param context Pointer to a SubGhzProtocolEncoderHoneywell_WDB instance
+ */
+void subghz_protocol_encoder_honeywell_wdb_free(void* context);
+
+/**
+ * Deserialize and generating an upload to send.
+ * @param context Pointer to a SubGhzProtocolEncoderHoneywell_WDB instance
+ * @param flipper_format Pointer to a FlipperFormat instance
+ * @return true On success
+ */
+bool subghz_protocol_encoder_honeywell_wdb_deserialize(
+ void* context,
+ FlipperFormat* flipper_format);
+
+/**
+ * Forced transmission stop.
+ * @param context Pointer to a SubGhzProtocolEncoderHoneywell_WDB instance
+ */
+void subghz_protocol_encoder_honeywell_wdb_stop(void* context);
+
+/**
+ * Getting the level and duration of the upload to be loaded into DMA.
+ * @param context Pointer to a SubGhzProtocolEncoderHoneywell_WDB instance
+ * @return LevelDuration
+ */
+LevelDuration subghz_protocol_encoder_honeywell_wdb_yield(void* context);
+
+/**
+ * Allocate SubGhzProtocolDecoderHoneywell_WDB.
+ * @param environment Pointer to a SubGhzEnvironment instance
+ * @return SubGhzProtocolDecoderHoneywell_WDB* pointer to a SubGhzProtocolDecoderHoneywell_WDB instance
+ */
+void* subghz_protocol_decoder_honeywell_wdb_alloc(SubGhzEnvironment* environment);
+
+/**
+ * Free SubGhzProtocolDecoderHoneywell_WDB.
+ * @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance
+ */
+void subghz_protocol_decoder_honeywell_wdb_free(void* context);
+
+/**
+ * Reset decoder SubGhzProtocolDecoderHoneywell_WDB.
+ * @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance
+ */
+void subghz_protocol_decoder_honeywell_wdb_reset(void* context);
+
+/**
+ * Parse a raw sequence of levels and durations received from the air.
+ * @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance
+ * @param level Signal level true-high false-low
+ * @param duration Duration of this level in, us
+ */
+void subghz_protocol_decoder_honeywell_wdb_feed(void* context, bool level, uint32_t duration);
+
+/**
+ * Getting the hash sum of the last randomly received parcel.
+ * @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance
+ * @return hash Hash sum
+ */
+uint8_t subghz_protocol_decoder_honeywell_wdb_get_hash_data(void* context);
+
+/**
+ * Serialize data SubGhzProtocolDecoderHoneywell_WDB.
+ * @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance
+ * @param flipper_format Pointer to a FlipperFormat instance
+ * @param preset The modulation on which the signal was received, SubGhzPresetDefinition
+ * @return true On success
+ */
+bool subghz_protocol_decoder_honeywell_wdb_serialize(
+ void* context,
+ FlipperFormat* flipper_format,
+ SubGhzPresetDefinition* preset);
+
+/**
+ * Deserialize data SubGhzProtocolDecoderHoneywell_WDB.
+ * @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance
+ * @param flipper_format Pointer to a FlipperFormat instance
+ * @return true On success
+ */
+bool subghz_protocol_decoder_honeywell_wdb_deserialize(
+ void* context,
+ FlipperFormat* flipper_format);
+
+/**
+ * Getting a textual representation of the received data.
+ * @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance
+ * @param output Resulting text
+ */
+void subghz_protocol_decoder_honeywell_wdb_get_string(void* context, string_t output);
diff --git a/lib/subghz/protocols/hormann.c b/lib/subghz/protocols/hormann.c
index ac6312511..0197f59e6 100644
--- a/lib/subghz/protocols/hormann.c
+++ b/lib/subghz/protocols/hormann.c
@@ -81,7 +81,7 @@ void* subghz_protocol_encoder_hormann_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 10;
instance->encoder.size_upload = 2048;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -164,7 +164,7 @@ bool subghz_protocol_encoder_hormann_deserialize(void* context, FlipperFormat* f
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
subghz_protocol_encoder_hormann_get_upload(instance);
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -174,14 +174,14 @@ bool subghz_protocol_encoder_hormann_deserialize(void* context, FlipperFormat* f
void subghz_protocol_encoder_hormann_stop(void* context) {
SubGhzProtocolEncoderHormann* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_hormann_yield(void* context) {
SubGhzProtocolEncoderHormann* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c
index 1d3ae74bd..32582faf9 100644
--- a/lib/subghz/protocols/keeloq.c
+++ b/lib/subghz/protocols/keeloq.c
@@ -113,7 +113,7 @@ void* subghz_protocol_encoder_keeloq_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 100;
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -371,7 +371,7 @@ bool subghz_protocol_encoder_keeloq_deserialize(void* context, FlipperFormat* fl
break;
}
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -381,14 +381,14 @@ bool subghz_protocol_encoder_keeloq_deserialize(void* context, FlipperFormat* fl
void subghz_protocol_encoder_keeloq_stop(void* context) {
SubGhzProtocolEncoderKeeloq* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_keeloq_yield(void* context) {
SubGhzProtocolEncoderKeeloq* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/linear.c b/lib/subghz/protocols/linear.c
index c989a6183..92ba02a8f 100644
--- a/lib/subghz/protocols/linear.c
+++ b/lib/subghz/protocols/linear.c
@@ -84,7 +84,7 @@ void* subghz_protocol_encoder_linear_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 10;
instance->encoder.size_upload = 28; //max 10bit*2 + 2 (start, stop)
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -166,7 +166,7 @@ bool subghz_protocol_encoder_linear_deserialize(void* context, FlipperFormat* fl
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
subghz_protocol_encoder_linear_get_upload(instance);
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -176,14 +176,14 @@ bool subghz_protocol_encoder_linear_deserialize(void* context, FlipperFormat* fl
void subghz_protocol_encoder_linear_stop(void* context) {
SubGhzProtocolEncoderLinear* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_linear_yield(void* context) {
SubGhzProtocolEncoderLinear* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/marantec.c b/lib/subghz/protocols/marantec.c
index d46927246..bdce6593d 100644
--- a/lib/subghz/protocols/marantec.c
+++ b/lib/subghz/protocols/marantec.c
@@ -80,7 +80,7 @@ void* subghz_protocol_encoder_marantec_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 10;
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -208,7 +208,7 @@ bool subghz_protocol_encoder_marantec_deserialize(void* context, FlipperFormat*
subghz_protocol_marantec_remote_controller(&instance->generic);
subghz_protocol_encoder_marantec_get_upload(instance);
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -218,14 +218,14 @@ bool subghz_protocol_encoder_marantec_deserialize(void* context, FlipperFormat*
void subghz_protocol_encoder_marantec_stop(void* context) {
SubGhzProtocolEncoderMarantec* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_marantec_yield(void* context) {
SubGhzProtocolEncoderMarantec* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/megacode.c b/lib/subghz/protocols/megacode.c
index bfe1a76b9..909e72171 100644
--- a/lib/subghz/protocols/megacode.c
+++ b/lib/subghz/protocols/megacode.c
@@ -90,7 +90,7 @@ void* subghz_protocol_encoder_megacode_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 10;
instance->encoder.size_upload = 52;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -194,7 +194,7 @@ bool subghz_protocol_encoder_megacode_deserialize(void* context, FlipperFormat*
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
subghz_protocol_encoder_megacode_get_upload(instance);
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -204,14 +204,14 @@ bool subghz_protocol_encoder_megacode_deserialize(void* context, FlipperFormat*
void subghz_protocol_encoder_megacode_stop(void* context) {
SubGhzProtocolEncoderMegaCode* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_megacode_yield(void* context) {
SubGhzProtocolEncoderMegaCode* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/nero_radio.c b/lib/subghz/protocols/nero_radio.c
index b6b1587ff..69326f5a0 100644
--- a/lib/subghz/protocols/nero_radio.c
+++ b/lib/subghz/protocols/nero_radio.c
@@ -80,7 +80,7 @@ void* subghz_protocol_encoder_nero_radio_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 10;
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -173,7 +173,7 @@ bool subghz_protocol_encoder_nero_radio_deserialize(void* context, FlipperFormat
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
subghz_protocol_encoder_nero_radio_get_upload(instance);
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -183,14 +183,14 @@ bool subghz_protocol_encoder_nero_radio_deserialize(void* context, FlipperFormat
void subghz_protocol_encoder_nero_radio_stop(void* context) {
SubGhzProtocolEncoderNeroRadio* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_nero_radio_yield(void* context) {
SubGhzProtocolEncoderNeroRadio* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/nero_sketch.c b/lib/subghz/protocols/nero_sketch.c
index 0b87ec11b..c93b36a53 100644
--- a/lib/subghz/protocols/nero_sketch.c
+++ b/lib/subghz/protocols/nero_sketch.c
@@ -79,7 +79,7 @@ void* subghz_protocol_encoder_nero_sketch_alloc(SubGhzEnvironment* environment)
instance->encoder.repeat = 10;
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -167,7 +167,7 @@ bool subghz_protocol_encoder_nero_sketch_deserialize(void* context, FlipperForma
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
subghz_protocol_encoder_nero_sketch_get_upload(instance);
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -177,14 +177,14 @@ bool subghz_protocol_encoder_nero_sketch_deserialize(void* context, FlipperForma
void subghz_protocol_encoder_nero_sketch_stop(void* context) {
SubGhzProtocolEncoderNeroSketch* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_nero_sketch_yield(void* context) {
SubGhzProtocolEncoderNeroSketch* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/nice_flo.c b/lib/subghz/protocols/nice_flo.c
index 236b42223..07b18e3ea 100644
--- a/lib/subghz/protocols/nice_flo.c
+++ b/lib/subghz/protocols/nice_flo.c
@@ -78,7 +78,7 @@ void* subghz_protocol_encoder_nice_flo_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 10;
instance->encoder.size_upload = 52; //max 24bit*2 + 2 (start, stop)
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -150,7 +150,7 @@ bool subghz_protocol_encoder_nice_flo_deserialize(void* context, FlipperFormat*
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
subghz_protocol_encoder_nice_flo_get_upload(instance);
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -160,14 +160,14 @@ bool subghz_protocol_encoder_nice_flo_deserialize(void* context, FlipperFormat*
void subghz_protocol_encoder_nice_flo_stop(void* context) {
SubGhzProtocolEncoderNiceFlo* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_nice_flo_yield(void* context) {
SubGhzProtocolEncoderNiceFlo* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/nice_flor_s.c b/lib/subghz/protocols/nice_flor_s.c
index 7893fe379..d5c3cd665 100644
--- a/lib/subghz/protocols/nice_flor_s.c
+++ b/lib/subghz/protocols/nice_flor_s.c
@@ -98,7 +98,7 @@ void* subghz_protocol_encoder_nice_flor_s_alloc(SubGhzEnvironment* environment)
instance->encoder.repeat = 10;
instance->encoder.size_upload = 2976; //max upload 186*16 = 2976
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -208,7 +208,7 @@ bool subghz_protocol_encoder_nice_flor_s_deserialize(void* context, FlipperForma
break;
}
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -218,14 +218,14 @@ bool subghz_protocol_encoder_nice_flor_s_deserialize(void* context, FlipperForma
void subghz_protocol_encoder_nice_flor_s_stop(void* context) {
SubGhzProtocolEncoderNiceFlorS* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_nice_flor_s_yield(void* context) {
SubGhzProtocolEncoderNiceFlorS* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/phoenix_v2.c b/lib/subghz/protocols/phoenix_v2.c
index e71e28349..3d2796e44 100644
--- a/lib/subghz/protocols/phoenix_v2.c
+++ b/lib/subghz/protocols/phoenix_v2.c
@@ -80,7 +80,7 @@ void* subghz_protocol_encoder_phoenix_v2_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 10;
instance->encoder.size_upload = 128;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -151,7 +151,7 @@ bool subghz_protocol_encoder_phoenix_v2_deserialize(void* context, FlipperFormat
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
subghz_protocol_encoder_phoenix_v2_get_upload(instance);
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -161,14 +161,14 @@ bool subghz_protocol_encoder_phoenix_v2_deserialize(void* context, FlipperFormat
void subghz_protocol_encoder_phoenix_v2_stop(void* context) {
SubGhzProtocolEncoderPhoenix_V2* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_phoenix_v2_yield(void* context) {
SubGhzProtocolEncoderPhoenix_V2* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/power_smart.c b/lib/subghz/protocols/power_smart.c
index 53e9f3380..bd009d887 100644
--- a/lib/subghz/protocols/power_smart.c
+++ b/lib/subghz/protocols/power_smart.c
@@ -87,7 +87,7 @@ void* subghz_protocol_encoder_power_smart_alloc(SubGhzEnvironment* environment)
instance->encoder.repeat = 10;
instance->encoder.size_upload = 1024;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -212,7 +212,7 @@ bool subghz_protocol_encoder_power_smart_deserialize(void* context, FlipperForma
subghz_protocol_power_smart_remote_controller(&instance->generic);
subghz_protocol_encoder_power_smart_get_upload(instance);
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -222,14 +222,14 @@ bool subghz_protocol_encoder_power_smart_deserialize(void* context, FlipperForma
void subghz_protocol_encoder_power_smart_stop(void* context) {
SubGhzProtocolEncoderPowerSmart* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_power_smart_yield(void* context) {
SubGhzProtocolEncoderPowerSmart* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/princeton.c b/lib/subghz/protocols/princeton.c
index 3fdeaae94..2ddfa2cb6 100644
--- a/lib/subghz/protocols/princeton.c
+++ b/lib/subghz/protocols/princeton.c
@@ -89,7 +89,7 @@ void* subghz_protocol_encoder_princeton_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 10;
instance->encoder.size_upload = 52; //max 24bit*2 + 2 (start, stop)
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -168,7 +168,7 @@ bool subghz_protocol_encoder_princeton_deserialize(void* context, FlipperFormat*
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
subghz_protocol_encoder_princeton_get_upload(instance);
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -178,14 +178,14 @@ bool subghz_protocol_encoder_princeton_deserialize(void* context, FlipperFormat*
void subghz_protocol_encoder_princeton_stop(void* context) {
SubGhzProtocolEncoderPrinceton* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_princeton_yield(void* context) {
SubGhzProtocolEncoderPrinceton* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/raw.c b/lib/subghz/protocols/raw.c
index 9ab649a7b..0419a39a0 100644
--- a/lib/subghz/protocols/raw.c
+++ b/lib/subghz/protocols/raw.c
@@ -37,7 +37,7 @@ struct SubGhzProtocolDecoderRAW {
struct SubGhzProtocolEncoderRAW {
SubGhzProtocolEncoderBase base;
- bool is_runing;
+ bool is_running;
string_t file_name;
SubGhzFileEncoderWorker* file_worker_encoder;
};
@@ -269,13 +269,13 @@ void* subghz_protocol_encoder_raw_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_raw;
string_init(instance->file_name);
- instance->is_runing = false;
+ instance->is_running = false;
return instance;
}
void subghz_protocol_encoder_raw_stop(void* context) {
SubGhzProtocolEncoderRAW* instance = context;
- instance->is_runing = false;
+ instance->is_running = false;
if(subghz_file_encoder_worker_is_running(instance->file_worker_encoder)) {
subghz_file_encoder_worker_stop(instance->file_worker_encoder);
subghz_file_encoder_worker_free(instance->file_worker_encoder);
@@ -308,11 +308,11 @@ static bool subghz_protocol_encoder_raw_worker_init(SubGhzProtocolEncoderRAW* in
instance->file_worker_encoder, string_get_cstr(instance->file_name))) {
//the worker needs a file in order to open and read part of the file
furi_delay_ms(100);
- instance->is_runing = true;
+ instance->is_running = true;
} else {
subghz_protocol_encoder_raw_stop(instance);
}
- return instance->is_runing;
+ return instance->is_running;
}
void subghz_protocol_raw_gen_fff_data(FlipperFormat* flipper_format, const char* file_path) {
@@ -357,6 +357,6 @@ bool subghz_protocol_encoder_raw_deserialize(void* context, FlipperFormat* flipp
LevelDuration subghz_protocol_encoder_raw_yield(void* context) {
SubGhzProtocolEncoderRAW* instance = context;
- if(!instance->is_runing) return level_duration_reset();
+ if(!instance->is_running) return level_duration_reset();
return subghz_file_encoder_worker_get_level_duration(instance->file_worker_encoder);
}
diff --git a/lib/subghz/protocols/registry.c b/lib/subghz/protocols/registry.c
index 893947304..19b03cebc 100644
--- a/lib/subghz/protocols/registry.c
+++ b/lib/subghz/protocols/registry.c
@@ -1,16 +1,17 @@
#include "registry.h"
const SubGhzProtocol* subghz_protocol_registry[] = {
- &subghz_protocol_gate_tx, &subghz_protocol_keeloq, &subghz_protocol_star_line,
- &subghz_protocol_nice_flo, &subghz_protocol_came, &subghz_protocol_faac_slh,
- &subghz_protocol_nice_flor_s, &subghz_protocol_came_twee, &subghz_protocol_came_atomo,
- &subghz_protocol_nero_sketch, &subghz_protocol_ido, &subghz_protocol_kia,
- &subghz_protocol_hormann, &subghz_protocol_nero_radio, &subghz_protocol_somfy_telis,
- &subghz_protocol_somfy_keytis, &subghz_protocol_scher_khan, &subghz_protocol_princeton,
- &subghz_protocol_raw, &subghz_protocol_linear, &subghz_protocol_secplus_v2,
- &subghz_protocol_secplus_v1, &subghz_protocol_megacode, &subghz_protocol_holtek,
- &subghz_protocol_chamb_code, &subghz_protocol_power_smart, &subghz_protocol_marantec,
- &subghz_protocol_bett, &subghz_protocol_doitrand, &subghz_protocol_phoenix_v2,
+ &subghz_protocol_gate_tx, &subghz_protocol_keeloq, &subghz_protocol_star_line,
+ &subghz_protocol_nice_flo, &subghz_protocol_came, &subghz_protocol_faac_slh,
+ &subghz_protocol_nice_flor_s, &subghz_protocol_came_twee, &subghz_protocol_came_atomo,
+ &subghz_protocol_nero_sketch, &subghz_protocol_ido, &subghz_protocol_kia,
+ &subghz_protocol_hormann, &subghz_protocol_nero_radio, &subghz_protocol_somfy_telis,
+ &subghz_protocol_somfy_keytis, &subghz_protocol_scher_khan, &subghz_protocol_princeton,
+ &subghz_protocol_raw, &subghz_protocol_linear, &subghz_protocol_secplus_v2,
+ &subghz_protocol_secplus_v1, &subghz_protocol_megacode, &subghz_protocol_holtek,
+ &subghz_protocol_chamb_code, &subghz_protocol_power_smart, &subghz_protocol_marantec,
+ &subghz_protocol_bett, &subghz_protocol_doitrand, &subghz_protocol_phoenix_v2,
+ &subghz_protocol_honeywell_wdb,
};
diff --git a/lib/subghz/protocols/registry.h b/lib/subghz/protocols/registry.h
index 97a1376d6..d75695132 100644
--- a/lib/subghz/protocols/registry.h
+++ b/lib/subghz/protocols/registry.h
@@ -32,6 +32,7 @@
#include "bett.h"
#include "doitrand.h"
#include "phoenix_v2.h"
+#include "honeywell_wdb.h"
/**
* Registration by name SubGhzProtocol.
diff --git a/lib/subghz/protocols/secplus_v1.c b/lib/subghz/protocols/secplus_v1.c
index a9798a502..04dc5d729 100644
--- a/lib/subghz/protocols/secplus_v1.c
+++ b/lib/subghz/protocols/secplus_v1.c
@@ -101,7 +101,7 @@ void* subghz_protocol_encoder_secplus_v1_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 10;
instance->encoder.size_upload = 128;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -298,7 +298,7 @@ bool subghz_protocol_encoder_secplus_v1_deserialize(void* context, FlipperFormat
break;
}
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -308,14 +308,14 @@ bool subghz_protocol_encoder_secplus_v1_deserialize(void* context, FlipperFormat
void subghz_protocol_encoder_secplus_v1_stop(void* context) {
SubGhzProtocolEncoderSecPlus_v1* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_secplus_v1_yield(void* context) {
SubGhzProtocolEncoderSecPlus_v1* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/secplus_v2.c b/lib/subghz/protocols/secplus_v2.c
index 954e8c817..1ba255652 100644
--- a/lib/subghz/protocols/secplus_v2.c
+++ b/lib/subghz/protocols/secplus_v2.c
@@ -93,7 +93,7 @@ void* subghz_protocol_encoder_secplus_v2_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 10;
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -555,7 +555,7 @@ bool subghz_protocol_encoder_secplus_v2_deserialize(void* context, FlipperFormat
break;
}
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -565,14 +565,14 @@ bool subghz_protocol_encoder_secplus_v2_deserialize(void* context, FlipperFormat
void subghz_protocol_encoder_secplus_v2_stop(void* context) {
SubGhzProtocolEncoderSecPlus_v2* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_secplus_v2_yield(void* context) {
SubGhzProtocolEncoderSecPlus_v2* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/subghz/protocols/star_line.c b/lib/subghz/protocols/star_line.c
index 7db549111..44f157bd5 100644
--- a/lib/subghz/protocols/star_line.c
+++ b/lib/subghz/protocols/star_line.c
@@ -113,7 +113,7 @@ void* subghz_protocol_encoder_star_line_alloc(SubGhzEnvironment* environment) {
instance->encoder.repeat = 10;
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
return instance;
}
@@ -293,7 +293,7 @@ bool subghz_protocol_encoder_star_line_deserialize(void* context, FlipperFormat*
break;
}
- instance->encoder.is_runing = true;
+ instance->encoder.is_running = true;
res = true;
} while(false);
@@ -303,14 +303,14 @@ bool subghz_protocol_encoder_star_line_deserialize(void* context, FlipperFormat*
void subghz_protocol_encoder_star_line_stop(void* context) {
SubGhzProtocolEncoderStarLine* instance = context;
- instance->encoder.is_runing = false;
+ instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_star_line_yield(void* context) {
SubGhzProtocolEncoderStarLine* instance = context;
- if(instance->encoder.repeat == 0 || !instance->encoder.is_runing) {
- instance->encoder.is_runing = false;
+ if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
+ instance->encoder.is_running = false;
return level_duration_reset();
}
diff --git a/lib/toolbox/path.c b/lib/toolbox/path.c
index 38af1efe5..1262362ef 100644
--- a/lib/toolbox/path.c
+++ b/lib/toolbox/path.c
@@ -85,6 +85,10 @@ void path_concat(const char* path, const char* suffix, string_t out_path) {
}
bool path_contains_only_ascii(const char* path) {
+ if(!path) {
+ return false;
+ }
+
const char* name_pos = strrchr(path, '/');
if(name_pos == NULL) {
name_pos = path;
diff --git a/lib/toolbox/version.c b/lib/toolbox/version.c
index c6c10b410..ae4ef2e3f 100644
--- a/lib/toolbox/version.c
+++ b/lib/toolbox/version.c
@@ -8,6 +8,7 @@ struct Version {
const char* git_branch;
const char* git_branch_num;
const char* build_date;
+ const char* custom_flipper_name;
const char* version;
const uint8_t target;
const bool build_is_dirty;
@@ -19,6 +20,11 @@ static const Version version = {
.git_branch = GIT_BRANCH,
.git_branch_num = GIT_BRANCH_NUM,
.build_date = BUILD_DATE,
+#ifdef FURI_CUSTOM_FLIPPER_NAME
+ .custom_flipper_name = FURI_CUSTOM_FLIPPER_NAME,
+#else
+ .custom_flipper_name = NULL,
+#endif
.version = VERSION
#ifdef FURI_RAM_EXEC
" (RAM)"
@@ -52,6 +58,10 @@ const char* version_get_version(const Version* v) {
return v ? v->version : version.version;
}
+const char* version_get_custom_name(const Version* v) {
+ return v ? v->custom_flipper_name : version.custom_flipper_name;
+}
+
uint8_t version_get_target(const Version* v) {
return v ? v->target : version.target;
}
diff --git a/lib/toolbox/version.h b/lib/toolbox/version.h
index 652ff3fea..ed54631b3 100644
--- a/lib/toolbox/version.h
+++ b/lib/toolbox/version.h
@@ -2,6 +2,7 @@
#include
#include
+#include
#ifdef __cplusplus
extern "C" {
@@ -64,6 +65,15 @@ const char* version_get_builddate(const Version* v);
*/
const char* version_get_version(const Version* v);
+/** Get custom flipper name if set in ENV
+ *
+ * @param v pointer to Version data. NULL for currently running
+ * software.
+ *
+ * @return custom name or NULL
+ */
+const char* version_get_custom_name(const Version* v);
+
/** Get hardware target this firmware was built for
*
* @param v pointer to Version data. NULL for currently running
diff --git a/scripts/fwsize.py b/scripts/fwsize.py
new file mode 100644
index 000000000..b381f6e9a
--- /dev/null
+++ b/scripts/fwsize.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python3
+
+from flipper.app import App
+import subprocess
+import os
+import math
+
+
+class Main(App):
+ def init(self):
+ self.subparsers = self.parser.add_subparsers(help="sub-command help")
+
+ self.parser_elfsize = self.subparsers.add_parser("elf", help="Dump elf stats")
+ self.parser_elfsize.add_argument("elfname", action="store")
+ self.parser_elfsize.set_defaults(func=self.process_elf)
+
+ self.parser_binsize = self.subparsers.add_parser("bin", help="Dump bin stats")
+ self.parser_binsize.add_argument("binname", action="store")
+ self.parser_binsize.set_defaults(func=self.process_bin)
+
+ def process_elf(self):
+ all_sizes = subprocess.check_output(
+ ["arm-none-eabi-size", "-A", self.args.elfname], shell=False
+ )
+ all_sizes = all_sizes.splitlines()
+
+ sections_to_keep = (".text", ".rodata", ".data", ".bss", ".free_flash")
+ for line in all_sizes:
+ line = line.decode("utf-8")
+ parts = line.split()
+ if len(parts) != 3:
+ continue
+ section, size, _ = parts
+ if section not in sections_to_keep:
+ continue
+ print(f"{section:<11} {size:>8} ({(int(size)/1024):6.2f} K)")
+
+ return 0
+
+ def process_bin(self):
+ PAGE_SIZE = 4096
+ binsize = os.path.getsize(self.args.binname)
+ pages = math.ceil(binsize / PAGE_SIZE)
+ last_page_state = (binsize % PAGE_SIZE) * 100 / PAGE_SIZE
+ print(
+ f"{os.path.basename(self.args.binname):<11}: {pages:>4} flash pages (last page {last_page_state:.02f}% full)"
+ )
+ return 0
+
+
+if __name__ == "__main__":
+ Main()()
diff --git a/scripts/otp.py b/scripts/otp.py
index 7b2378d12..48056fd2a 100755
--- a/scripts/otp.py
+++ b/scripts/otp.py
@@ -24,6 +24,7 @@ OTP_REGIONS = {
"eu_ru": 0x01,
"us_ca_au": 0x02,
"jp": 0x03,
+ "world": 0x04,
}
OTP_DISPLAYS = {
diff --git a/scripts/sconsdist.py b/scripts/sconsdist.py
index 1e95ee2f2..f5eaf0e3b 100644
--- a/scripts/sconsdist.py
+++ b/scripts/sconsdist.py
@@ -2,7 +2,7 @@
from flipper.app import App
from os.path import join, exists
-from os import makedirs
+from os import makedirs, environ
from update import Main as UpdateMain
import shutil
@@ -134,6 +134,15 @@ class Main(App):
self.logger.info(
f"Use this directory to self-update your Flipper:\n\t{bundle_dir}"
)
+ log_custom_fz_name = (
+ environ.get("CUSTOM_FLIPPER_NAME", None)
+ or ""
+ )
+ if (log_custom_fz_name != "") and (len(log_custom_fz_name) <= 8) and (log_custom_fz_name.isalnum()) and (log_custom_fz_name.isascii()):
+ self.logger.info(
+ f"Flipper Custom Name is set:\n\tName: {log_custom_fz_name} : length - {len(log_custom_fz_name)} chars"
+ )
+
return UpdateMain(no_exit=True)(bundle_args)
return 0
diff --git a/scripts/toolchain/fbtenv.cmd b/scripts/toolchain/fbtenv.cmd
index 471ce835c..aac2a3309 100644
--- a/scripts/toolchain/fbtenv.cmd
+++ b/scripts/toolchain/fbtenv.cmd
@@ -31,6 +31,7 @@ if not "%REAL_TOOLCHAIN_VERSION%" == "%FLIPPER_TOOLCHAIN_VERSION%" (
set "HOME=%USERPROFILE%"
set "PYTHONHOME=%FBT_TOOLCHAIN_ROOT%\python"
+set "PYTHONPATH="
set "PATH=%FBT_TOOLCHAIN_ROOT%\python;%FBT_TOOLCHAIN_ROOT%\bin;%FBT_TOOLCHAIN_ROOT%\protoc\bin;%FBT_TOOLCHAIN_ROOT%\openocd\bin;%PATH%"
set "PROMPT=(fbt) %PROMPT%"
diff --git a/scripts/version.py b/scripts/version.py
index 8abb5bbd2..a51909233 100644
--- a/scripts/version.py
+++ b/scripts/version.py
@@ -37,13 +37,28 @@ class GitVersion:
or "unknown"
)
- return {
- "GIT_COMMIT": commit,
- "GIT_BRANCH": branch,
- "GIT_BRANCH_NUM": branch_num,
- "VERSION": version,
- "BUILD_DIRTY": dirty and 1 or 0,
- }
+ custom_fz_name = (
+ os.environ.get("CUSTOM_FLIPPER_NAME", None)
+ or ""
+ )
+
+ if (custom_fz_name != "") and (len(custom_fz_name) <= 8) and (custom_fz_name.isalnum()) and (custom_fz_name.isascii()):
+ return {
+ "GIT_COMMIT": commit,
+ "GIT_BRANCH": branch,
+ "GIT_BRANCH_NUM": branch_num,
+ "FURI_CUSTOM_FLIPPER_NAME": custom_fz_name,
+ "VERSION": version,
+ "BUILD_DIRTY": dirty and 1 or 0,
+ }
+ else:
+ return {
+ "GIT_COMMIT": commit,
+ "GIT_BRANCH": branch,
+ "GIT_BRANCH_NUM": branch_num,
+ "VERSION": version,
+ "BUILD_DIRTY": dirty and 1 or 0,
+ }
def _exec_git(self, args):
cmd = ["git"]
diff --git a/site_scons/commandline.scons b/site_scons/commandline.scons
index 5a7a0dd2d..bb9a04d4f 100644
--- a/site_scons/commandline.scons
+++ b/site_scons/commandline.scons
@@ -76,6 +76,12 @@ vars.Add(
default="local",
)
+vars.Add(
+ "CUSTOM_FLIPPER_NAME",
+ help="Replaces OTP flipper name with custom string of 8 chars",
+ default="",
+)
+
vars.Add(
"UPDATE_VERSION_STRING",
help="Version string for updater package",
@@ -174,6 +180,12 @@ vars.Add(
default="update_default",
)
+vars.Add(
+ "LOADER_AUTOSTART",
+ help="Application name to automatically run on Flipper boot",
+ default="",
+)
+
vars.Add(
"FIRMWARE_APPS",
diff --git a/site_scons/environ.scons b/site_scons/environ.scons
index 99d4cc0b5..f1668ab16 100644
--- a/site_scons/environ.scons
+++ b/site_scons/environ.scons
@@ -12,7 +12,7 @@ forward_os_env = {
"PATH": os.environ["PATH"],
}
# Proxying CI environment to child processes & scripts
-for env_value_name in ("WORKFLOW_BRANCH_OR_TAG", "DIST_SUFFIX", "HOME", "APPDATA"):
+for env_value_name in ("WORKFLOW_BRANCH_OR_TAG", "DIST_SUFFIX", "CUSTOM_FLIPPER_NAME", "HOME", "APPDATA"):
if environ_value := os.environ.get(env_value_name, None):
forward_os_env[env_value_name] = environ_value
diff --git a/site_scons/fbt/appmanifest.py b/site_scons/fbt/appmanifest.py
index 977c90662..f330f3f91 100644
--- a/site_scons/fbt/appmanifest.py
+++ b/site_scons/fbt/appmanifest.py
@@ -203,8 +203,9 @@ class ApplicationsCGenerator:
FlipperAppType.STARTUP: ("FlipperOnStartHook", "FLIPPER_ON_SYSTEM_START"),
}
- def __init__(self, buildset: AppBuildset):
+ def __init__(self, buildset: AppBuildset, autorun_app: str = ""):
self.buildset = buildset
+ self.autorun = autorun_app
def get_app_ep_forward(self, app: FlipperApplication):
if app.apptype == FlipperAppType.STARTUP:
@@ -222,7 +223,11 @@ class ApplicationsCGenerator:
.flags = {'|'.join(f"FlipperApplicationFlag{flag}" for flag in app.flags)} }}"""
def generate(self):
- contents = ['#include "applications.h"', "#include "]
+ contents = [
+ '#include "applications.h"',
+ "#include ",
+ f'const char* FLIPPER_AUTORUN_APP_NAME = "{self.autorun}";',
+ ]
for apptype in self.APP_TYPE_MAP:
contents.extend(
map(self.get_app_ep_forward, self.buildset.get_apps_of_type(apptype))
diff --git a/site_scons/site_tools/crosscc.py b/site_scons/site_tools/crosscc.py
index dbedf5c07..aacda58c6 100644
--- a/site_scons/site_tools/crosscc.py
+++ b/site_scons/site_tools/crosscc.py
@@ -7,7 +7,6 @@ from SCons.Tool import gnulink
import strip
import gdb
import objdump
-import size
from SCons.Action import _subproc
import subprocess
@@ -38,7 +37,7 @@ def _get_tool_version(env, tool):
def generate(env, **kw):
- for orig_tool in (asm, gcc, gxx, ar, gnulink, strip, gdb, objdump, size):
+ for orig_tool in (asm, gcc, gxx, ar, gnulink, strip, gdb, objdump):
orig_tool.generate(env)
env.SetDefault(
TOOLCHAIN_PREFIX=kw.get("toolchain_prefix"),
@@ -57,7 +56,6 @@ def generate(env, **kw):
"GDB",
"GDBPY",
"OBJDUMP",
- "SIZE",
],
)
# Call CC to check version
diff --git a/site_scons/site_tools/fbt_apps.py b/site_scons/site_tools/fbt_apps.py
index 2cd63b70b..3dc35049b 100644
--- a/site_scons/site_tools/fbt_apps.py
+++ b/site_scons/site_tools/fbt_apps.py
@@ -51,7 +51,7 @@ def DumpApplicationConfig(target, source, env):
def build_apps_c(target, source, env):
target_file_name = target[0].path
- gen = ApplicationsCGenerator(env["APPBUILD"])
+ gen = ApplicationsCGenerator(env["APPBUILD"], env.subst("$LOADER_AUTOSTART"))
with open(target_file_name, "w") as file:
file.write(gen.generate())
diff --git a/site_scons/site_tools/size.py b/site_scons/site_tools/size.py
deleted file mode 100644
index 56d4f3c9e..000000000
--- a/site_scons/site_tools/size.py
+++ /dev/null
@@ -1,24 +0,0 @@
-from SCons.Builder import Builder
-from SCons.Action import Action
-
-
-def generate(env):
- env.SetDefault(
- SIZE="size",
- SIZEFLAGS=[],
- SIZECOM="$SIZE $SIZEFLAGS $TARGETS",
- )
- env.Append(
- BUILDERS={
- "ELFSize": Builder(
- action=Action(
- "${SIZECOM}",
- "${SIZECOMSTR}",
- ),
- ),
- }
- )
-
-
-def exists(env):
- return True