Merge branch 'fz-dev' into dev

This commit is contained in:
MX 2022-08-23 11:11:11 +03:00
commit 56907f0c9f
No known key found for this signature in database
GPG key ID: 6C4C311DFD4B4AB5
68 changed files with 1545 additions and 482 deletions

4
.gitignore vendored
View file

@ -51,3 +51,7 @@ build/
# openocd output file
openocd.log
# PVS Studio temporary files
.PVS-Studio/
PVS-Studio.log

22
.pvsconfig Normal file
View file

@ -0,0 +1,22 @@
# MLib macros we can't do much about.
//-V:M_EACH:1048,1044
//-V:ARRAY_DEF:760,747,568,776,729,712,654
//-V:LIST_DEF:760,747,568,712,729,654,776
//-V:BPTREE_DEF2:779,1086,557,773,512
//-V:DICT_DEF2:779,524,776,760,1044,1001,729,590,568,747,685
//-V:ALGO_DEF:1048,747,1044
# Non-severe malloc/null pointer deref warnings
//-V::522:2,3
# Warning about headers with copyleft license
//-V::1042
# Potentially null argument warnings
//-V:memset:575
//-V:memcpy:575
//-V:strcpy:575
//-V:strchr:575
# For loop warning on M_FOREACH
//-V:for:1044

1
.pvsoptions Normal file
View file

@ -0,0 +1 @@
--rules-config .pvsconfig -e lib/fatfs -e lib/fnv1a-hash -e lib/FreeRTOS-Kernel -e lib/heatshrink -e lib/libusb_stm32 -e lib/littlefs -e lib/mbedtls -e lib/micro-ecc -e lib/microtar -e lib/mlib -e lib/qrcode -e lib/ST25RFAL002 -e lib/STM32CubeWB -e lib/u8g2 -e toolchain/

View file

@ -77,14 +77,24 @@ static void archive_long_load_cb(void* context) {
});
}
void archive_file_browser_set_callbacks(ArchiveBrowserView* browser) {
static void archive_file_browser_set_path(
ArchiveBrowserView* browser,
string_t path,
const char* filter_ext,
bool skip_assets) {
furi_assert(browser);
file_browser_worker_set_callback_context(browser->worker, browser);
file_browser_worker_set_folder_callback(browser->worker, archive_folder_open_cb);
file_browser_worker_set_list_callback(browser->worker, archive_list_load_cb);
file_browser_worker_set_item_callback(browser->worker, archive_list_item_cb);
file_browser_worker_set_long_load_callback(browser->worker, archive_long_load_cb);
if(!browser->worker_running) {
browser->worker = file_browser_worker_alloc(path, filter_ext, skip_assets);
file_browser_worker_set_callback_context(browser->worker, browser);
file_browser_worker_set_folder_callback(browser->worker, archive_folder_open_cb);
file_browser_worker_set_list_callback(browser->worker, archive_list_load_cb);
file_browser_worker_set_item_callback(browser->worker, archive_list_item_cb);
file_browser_worker_set_long_load_callback(browser->worker, archive_long_load_cb);
browser->worker_running = true;
} else {
furi_assert(browser->worker);
file_browser_worker_set_config(browser->worker, path, filter_ext, skip_assets);
}
}
bool archive_is_item_in_array(ArchiveBrowserViewModel* model, uint32_t idx) {
@ -438,8 +448,8 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) {
tab = archive_get_tab(browser);
if(archive_is_dir_exists(browser->path)) {
bool skip_assets = (strcmp(archive_get_tab_ext(tab), "*") == 0) ? false : true;
file_browser_worker_set_config(
browser->worker, browser->path, archive_get_tab_ext(tab), skip_assets);
archive_file_browser_set_path(
browser, browser->path, archive_get_tab_ext(tab), skip_assets);
tab_empty = false; // Empty check will be performed later
} else {
tab_empty = true;

View file

@ -87,4 +87,3 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key);
void archive_enter_dir(ArchiveBrowserView* browser, string_t name);
void archive_leave_dir(ArchiveBrowserView* browser);
void archive_refresh_dir(ArchiveBrowserView* browser);
void archive_file_browser_set_callbacks(ArchiveBrowserView* browser);

View file

@ -370,18 +370,15 @@ ArchiveBrowserView* browser_alloc() {
return true;
});
browser->worker = file_browser_worker_alloc(browser->path, "*", false);
archive_file_browser_set_callbacks(browser);
file_browser_worker_set_callback_context(browser->worker, browser);
return browser;
}
void browser_free(ArchiveBrowserView* browser) {
furi_assert(browser);
file_browser_worker_free(browser->worker);
if(browser->worker_running) {
file_browser_worker_free(browser->worker);
}
with_view_model(
browser->view, (ArchiveBrowserViewModel * model) {

View file

@ -74,6 +74,7 @@ typedef enum {
struct ArchiveBrowserView {
View* view;
BrowserWorker* worker;
bool worker_running;
ArchiveBrowserViewCallback callback;
void* context;
string_t path;

View file

@ -3,7 +3,7 @@
#include <applications/cli/cli.h>
#include <lib/toolbox/args.h>
#include "ble.h"
#include <ble/ble.h>
#include "bt_settings.h"
#include "bt_service/bt.h"

6
applications/bt/bt_hid_app/bt_hid.c Executable file → Normal file
View file

@ -89,8 +89,7 @@ BtHid* bt_hid_app_alloc() {
app->submenu, "Keynote", BtHidSubmenuIndexKeynote, bt_hid_submenu_callback, app);
submenu_add_item(
app->submenu, "Keyboard", BtHidSubmenuIndexKeyboard, bt_hid_submenu_callback, app);
submenu_add_item(
app->submenu, "Media Player", BtHidSubmenuIndexMedia, bt_hid_submenu_callback, app);
submenu_add_item(app->submenu, "Media", BtHidSubmenuIndexMedia, bt_hid_submenu_callback, app);
submenu_add_item(app->submenu, "Mouse", BtHidSubmenuIndexMouse, bt_hid_submenu_callback, app);
view_set_previous_callback(submenu_get_view(app->submenu), bt_hid_exit);
view_dispatcher_add_view(
@ -134,7 +133,8 @@ BtHid* bt_hid_app_alloc() {
app->view_dispatcher, BtHidViewMouse, bt_hid_mouse_get_view(app->bt_hid_mouse));
// TODO switch to menu after Media is done
view_dispatcher_switch_to_view(app->view_dispatcher, BtHidViewKeynote);
app->view_id = BtHidViewSubmenu;
view_dispatcher_switch_to_view(app->view_dispatcher, app->view_id);
return app;
}

View file

@ -43,7 +43,10 @@ static void bt_hid_keynote_draw_callback(Canvas* canvas, void* context) {
}
canvas_set_font(canvas, FontPrimary);
elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "Keynote");
canvas_draw_icon(canvas, 68, 2, &I_Pin_back_arrow_10x8);
canvas_set_font(canvas, FontSecondary);
elements_multiline_text_aligned(canvas, 127, 3, AlignRight, AlignTop, "Hold to exit");
// Up
canvas_draw_icon(canvas, 21, 24, &I_Button_18x18);
@ -97,8 +100,8 @@ static void bt_hid_keynote_draw_callback(Canvas* canvas, void* context) {
elements_slightly_rounded_box(canvas, 66, 47, 60, 13);
canvas_set_color(canvas, ColorWhite);
}
canvas_draw_icon(canvas, 110, 49, &I_Ok_btn_9x9);
elements_multiline_text_aligned(canvas, 76, 56, AlignLeft, AlignBottom, "Back");
canvas_draw_icon(canvas, 74, 49, &I_Pin_back_arrow_10x8);
elements_multiline_text_aligned(canvas, 91, 57, AlignLeft, AlignBottom, "Back");
}
static void bt_hid_keynote_process(BtHidKeynote* bt_hid_keynote, InputEvent* event) {

View file

@ -49,7 +49,9 @@ static void bt_hid_media_draw_callback(Canvas* canvas, void* context) {
// Up
if(model->up_pressed) {
canvas_set_bitmap_mode(canvas, 1);
canvas_draw_icon(canvas, 93, 9, &I_Pressed_Button_13x13);
canvas_set_bitmap_mode(canvas, 0);
canvas_set_color(canvas, ColorWhite);
}
canvas_draw_icon(canvas, 96, 12, &I_Volup_8x6);
@ -57,7 +59,9 @@ static void bt_hid_media_draw_callback(Canvas* canvas, void* context) {
// Down
if(model->down_pressed) {
canvas_set_bitmap_mode(canvas, 1);
canvas_draw_icon(canvas, 93, 41, &I_Pressed_Button_13x13);
canvas_set_bitmap_mode(canvas, 0);
canvas_set_color(canvas, ColorWhite);
}
canvas_draw_icon(canvas, 96, 45, &I_Voldwn_6x6);
@ -65,7 +69,9 @@ static void bt_hid_media_draw_callback(Canvas* canvas, void* context) {
// Left
if(model->left_pressed) {
canvas_set_bitmap_mode(canvas, 1);
canvas_draw_icon(canvas, 77, 25, &I_Pressed_Button_13x13);
canvas_set_bitmap_mode(canvas, 0);
canvas_set_color(canvas, ColorWhite);
}
bt_hid_media_draw_arrow(canvas, 82, 31, CanvasDirectionRightToLeft);
@ -74,7 +80,9 @@ static void bt_hid_media_draw_callback(Canvas* canvas, void* context) {
// Right
if(model->right_pressed) {
canvas_set_bitmap_mode(canvas, 1);
canvas_draw_icon(canvas, 109, 25, &I_Pressed_Button_13x13);
canvas_set_bitmap_mode(canvas, 0);
canvas_set_color(canvas, ColorWhite);
}
bt_hid_media_draw_arrow(canvas, 112, 31, CanvasDirectionLeftToRight);
@ -89,6 +97,12 @@ static void bt_hid_media_draw_callback(Canvas* canvas, void* context) {
bt_hid_media_draw_arrow(canvas, 96, 31, CanvasDirectionLeftToRight);
canvas_draw_line(canvas, 100, 29, 100, 33);
canvas_draw_line(canvas, 102, 29, 102, 33);
canvas_set_color(canvas, ColorBlack);
// Exit
canvas_draw_icon(canvas, 0, 54, &I_Pin_back_arrow_10x8);
canvas_set_font(canvas, FontSecondary);
elements_multiline_text_aligned(canvas, 13, 62, AlignLeft, AlignBottom, "Hold to exit");
}
static void bt_hid_media_process_press(BtHidMedia* bt_hid_media, InputEvent* event) {

View file

@ -36,7 +36,11 @@ static void bt_hid_mouse_draw_callback(Canvas* canvas, void* context) {
canvas_set_font(canvas, FontSecondary);
if(model->left_mouse_held == true) {
elements_multiline_text_aligned(canvas, 0, 60, AlignLeft, AlignBottom, "Selecting...");
elements_multiline_text_aligned(canvas, 0, 62, AlignLeft, AlignBottom, "Selecting...");
} else {
canvas_draw_icon(canvas, 0, 54, &I_Pin_back_arrow_10x8);
canvas_set_font(canvas, FontSecondary);
elements_multiline_text_aligned(canvas, 13, 62, AlignLeft, AlignBottom, "Hold to exit");
}
// Keypad circles
@ -44,7 +48,9 @@ static void bt_hid_mouse_draw_callback(Canvas* canvas, void* context) {
// Up
if(model->up_pressed) {
canvas_set_bitmap_mode(canvas, 1);
canvas_draw_icon(canvas, 81, 9, &I_Pressed_Button_13x13);
canvas_set_bitmap_mode(canvas, 0);
canvas_set_color(canvas, ColorWhite);
}
canvas_draw_icon(canvas, 84, 10, &I_Pin_arrow_up7x9);
@ -52,7 +58,9 @@ static void bt_hid_mouse_draw_callback(Canvas* canvas, void* context) {
// Down
if(model->down_pressed) {
canvas_set_bitmap_mode(canvas, 1);
canvas_draw_icon(canvas, 81, 41, &I_Pressed_Button_13x13);
canvas_set_bitmap_mode(canvas, 0);
canvas_set_color(canvas, ColorWhite);
}
canvas_draw_icon(canvas, 84, 43, &I_Pin_arrow_down_7x9);
@ -60,7 +68,9 @@ static void bt_hid_mouse_draw_callback(Canvas* canvas, void* context) {
// Left
if(model->left_pressed) {
canvas_set_bitmap_mode(canvas, 1);
canvas_draw_icon(canvas, 65, 25, &I_Pressed_Button_13x13);
canvas_set_bitmap_mode(canvas, 0);
canvas_set_color(canvas, ColorWhite);
}
canvas_draw_icon(canvas, 67, 28, &I_Pin_arrow_left_9x7);
@ -68,7 +78,9 @@ static void bt_hid_mouse_draw_callback(Canvas* canvas, void* context) {
// Right
if(model->right_pressed) {
canvas_set_bitmap_mode(canvas, 1);
canvas_draw_icon(canvas, 97, 25, &I_Pressed_Button_13x13);
canvas_set_bitmap_mode(canvas, 0);
canvas_set_color(canvas, ColorWhite);
}
canvas_draw_icon(canvas, 99, 28, &I_Pin_arrow_right_9x7);
@ -76,18 +88,17 @@ static void bt_hid_mouse_draw_callback(Canvas* canvas, void* context) {
// Ok
if(model->left_mouse_pressed) {
canvas_draw_icon(canvas, 81, 25, &I_Pressed_Button_13x13);
canvas_set_color(canvas, ColorWhite);
canvas_draw_icon(canvas, 81, 25, &I_Ok_btn_pressed_13x13);
} else {
canvas_draw_icon(canvas, 83, 27, &I_Left_mouse_icon_9x9);
}
canvas_draw_icon(canvas, 83, 27, &I_Ok_btn_9x9);
canvas_set_color(canvas, ColorBlack);
// Back
if(model->right_mouse_pressed) {
canvas_draw_icon(canvas, 108, 48, &I_Pressed_Button_13x13);
canvas_set_color(canvas, ColorWhite);
canvas_draw_icon(canvas, 108, 48, &I_Ok_btn_pressed_13x13);
} else {
canvas_draw_icon(canvas, 110, 50, &I_Right_mouse_icon_9x9);
}
canvas_draw_icon(canvas, 110, 50, &I_Ok_btn_9x9);
}
static void bt_hid_mouse_process(BtHidMouse* bt_hid_mouse, InputEvent* event) {

View file

@ -14,8 +14,8 @@
#define DOLPHIN_STATE_PATH INT_PATH(DOLPHIN_STATE_FILE_NAME)
#define DOLPHIN_STATE_HEADER_MAGIC 0xD0
#define DOLPHIN_STATE_HEADER_VERSION 0x01
#define LEVEL2_THRESHOLD 735
#define LEVEL3_THRESHOLD 2940
#define LEVEL2_THRESHOLD 300
#define LEVEL3_THRESHOLD 1800
#define BUTTHURT_MAX 14
#define BUTTHURT_MIN 0

View file

@ -55,13 +55,14 @@ Power* power_alloc() {
// Gui
power->view_dispatcher = view_dispatcher_alloc();
power->popup = popup_alloc();
popup_set_header(
power->popup, "Disconnect USB for safe\nshutdown", 64, 26, AlignCenter, AlignTop);
view_dispatcher_add_view(power->view_dispatcher, PowerViewPopup, popup_get_view(power->popup));
power->power_off = power_off_alloc();
view_dispatcher_add_view(
power->view_dispatcher, PowerViewOff, power_off_get_view(power->power_off));
power->power_unplug_usb = power_unplug_usb_alloc();
view_dispatcher_add_view(
power->view_dispatcher,
PowerViewUnplugUsb,
power_unplug_usb_get_view(power->power_unplug_usb));
view_dispatcher_attach_to_gui(
power->view_dispatcher, power->gui, ViewDispatcherTypeFullscreen);
@ -78,8 +79,9 @@ void power_free(Power* power) {
// Gui
view_dispatcher_remove_view(power->view_dispatcher, PowerViewOff);
power_off_free(power->power_off);
view_dispatcher_remove_view(power->view_dispatcher, PowerViewPopup);
popup_free(power->popup);
view_dispatcher_remove_view(power->view_dispatcher, PowerViewUnplugUsb);
power_unplug_usb_free(power->power_unplug_usb);
view_port_free(power->battery_view_port);
// State

View file

@ -8,8 +8,8 @@ void power_off(Power* power) {
furi_hal_power_off();
// Notify user if USB is plugged
view_dispatcher_send_to_front(power->view_dispatcher);
view_dispatcher_switch_to_view(power->view_dispatcher, PowerViewPopup);
furi_delay_ms(10);
view_dispatcher_switch_to_view(power->view_dispatcher, PowerViewUnplugUsb);
furi_delay_ms(100);
furi_halt("Disconnect USB for safe shutdown");
}

View file

@ -8,6 +8,7 @@
#include <gui/modules/popup.h>
#include "views/power_off.h"
#include "views/power_unplug_usb.h"
#include <notification/notification_messages.h>
@ -21,8 +22,8 @@ typedef enum {
struct Power {
ViewDispatcher* view_dispatcher;
Popup* popup;
PowerOff* power_off;
PowerUnplugUsb* power_unplug_usb;
ViewPort* battery_view_port;
Gui* gui;
@ -42,6 +43,6 @@ struct Power {
};
typedef enum {
PowerViewPopup,
PowerViewOff,
PowerViewUnplugUsb,
} PowerView;

View file

@ -0,0 +1,43 @@
#include "power_unplug_usb.h"
#include <furi.h>
#include <gui/elements.h>
struct PowerUnplugUsb {
View* view;
};
static void power_unplug_usb_draw_callback(Canvas* canvas, void* _model) {
UNUSED(_model);
canvas_set_color(canvas, ColorBlack);
canvas_draw_icon(canvas, 0, 0, &I_Unplug_bg_top_128x14);
canvas_draw_box(canvas, 0, 14, 128, (64 - 10 - 14));
canvas_draw_icon(canvas, 0, (64 - 10), &I_Unplug_bg_bottom_128x10);
canvas_set_color(canvas, ColorWhite);
canvas_set_font(canvas, FontPrimary);
elements_multiline_text_aligned(
canvas, 64, 32, AlignCenter, AlignCenter, "It's now safe to unplug\nUSB cable");
}
PowerUnplugUsb* power_unplug_usb_alloc() {
PowerUnplugUsb* power_unplug_usb = malloc(sizeof(PowerUnplugUsb));
power_unplug_usb->view = view_alloc();
view_set_context(power_unplug_usb->view, power_unplug_usb);
view_set_draw_callback(power_unplug_usb->view, power_unplug_usb_draw_callback);
view_set_input_callback(power_unplug_usb->view, NULL);
return power_unplug_usb;
}
void power_unplug_usb_free(PowerUnplugUsb* power_unplug_usb) {
furi_assert(power_unplug_usb);
view_free(power_unplug_usb->view);
free(power_unplug_usb);
}
View* power_unplug_usb_get_view(PowerUnplugUsb* power_unplug_usb) {
furi_assert(power_unplug_usb);
return power_unplug_usb->view;
}

View file

@ -0,0 +1,11 @@
#pragma once
typedef struct PowerUnplugUsb PowerUnplugUsb;
#include <gui/view.h>
PowerUnplugUsb* power_unplug_usb_alloc();
void power_unplug_usb_free(PowerUnplugUsb* power_unplug_usb);
View* power_unplug_usb_get_view(PowerUnplugUsb* power_unplug_usb);

View file

@ -80,13 +80,11 @@ struct Rpc {
FuriMutex* busy_mutex;
};
static bool content_callback(pb_istream_t* stream, const pb_field_t* field, void** arg);
static void rpc_close_session_process(const PB_Main* request, void* context) {
furi_assert(request);
furi_assert(context);
RpcSession* session = (RpcSession*)context;
furi_assert(session);
rpc_send_and_release_empty(session, request->command_id, PB_CommandStatus_OK);
furi_mutex_acquire(session->callbacks_mutex, FuriWaitForever);
@ -98,264 +96,6 @@ static void rpc_close_session_process(const PB_Main* request, void* context) {
furi_mutex_release(session->callbacks_mutex);
}
static size_t rpc_sprintf_msg_file(
string_t str,
const char* prefix,
const PB_Storage_File* msg_file,
size_t msg_files_size) {
size_t cnt = 0;
for(size_t i = 0; i < msg_files_size; ++i, ++msg_file) {
string_cat_printf(
str,
"%s[%c] size: %5ld",
prefix,
msg_file->type == PB_Storage_File_FileType_DIR ? 'd' : 'f',
msg_file->size);
if(msg_file->name) {
string_cat_printf(str, " \'%s\'", msg_file->name);
}
if(msg_file->data && msg_file->data->size) {
string_cat_printf(
str,
" (%d):\'%.*s%s\'",
msg_file->data->size,
MIN(msg_file->data->size, 30),
msg_file->data->bytes,
msg_file->data->size > 30 ? "..." : "");
}
string_cat_printf(str, "\r\n");
}
return cnt;
}
void rpc_print_data(const char* prefix, uint8_t* buffer, size_t size) {
string_t str;
string_init(str);
string_reserve(str, 100 + size * 5);
string_cat_printf(str, "\r\n%s DEC(%d): {", prefix, size);
for(size_t i = 0; i < size; ++i) {
string_cat_printf(str, "%d, ", buffer[i]);
}
string_cat_printf(str, "}\r\n");
printf("%s", string_get_cstr(str));
string_reset(str);
string_reserve(str, 100 + size * 3);
string_cat_printf(str, "%s HEX(%d): {", prefix, size);
for(size_t i = 0; i < size; ++i) {
string_cat_printf(str, "%02X", buffer[i]);
}
string_cat_printf(str, "}\r\n\r\n");
printf("%s", string_get_cstr(str));
string_clear(str);
}
void rpc_print_message(const PB_Main* message) {
string_t str;
string_init(str);
string_cat_printf(
str,
"PB_Main: {\r\n\tresult: %d cmd_id: %ld (%s)\r\n",
message->command_status,
message->command_id,
message->has_next ? "has_next" : "last");
switch(message->which_content) {
default:
/* not implemented yet */
string_cat_printf(str, "\tNOT_IMPLEMENTED (%d) {\r\n", message->which_content);
break;
case PB_Main_stop_session_tag:
string_cat_printf(str, "\tstop_session {\r\n");
break;
case PB_Main_app_start_request_tag: {
string_cat_printf(str, "\tapp_start {\r\n");
const char* name = message->content.app_start_request.name;
const char* args = message->content.app_start_request.args;
if(name) {
string_cat_printf(str, "\t\tname: %s\r\n", name);
}
if(args) {
string_cat_printf(str, "\t\targs: %s\r\n", args);
}
break;
}
case PB_Main_app_lock_status_request_tag: {
string_cat_printf(str, "\tapp_lock_status_request {\r\n");
break;
}
case PB_Main_app_lock_status_response_tag: {
string_cat_printf(str, "\tapp_lock_status_response {\r\n");
bool lock_status = message->content.app_lock_status_response.locked;
string_cat_printf(str, "\t\tlocked: %s\r\n", lock_status ? "true" : "false");
break;
}
case PB_Main_storage_md5sum_request_tag: {
string_cat_printf(str, "\tmd5sum_request {\r\n");
const char* path = message->content.storage_md5sum_request.path;
if(path) {
string_cat_printf(str, "\t\tpath: %s\r\n", path);
}
break;
}
case PB_Main_storage_md5sum_response_tag: {
string_cat_printf(str, "\tmd5sum_response {\r\n");
const char* path = message->content.storage_md5sum_response.md5sum;
if(path) {
string_cat_printf(str, "\t\tmd5sum: %s\r\n", path);
}
break;
}
case PB_Main_system_ping_request_tag:
string_cat_printf(str, "\tping_request {\r\n");
break;
case PB_Main_system_ping_response_tag:
string_cat_printf(str, "\tping_response {\r\n");
break;
case PB_Main_system_device_info_request_tag:
string_cat_printf(str, "\tdevice_info_request {\r\n");
break;
case PB_Main_system_device_info_response_tag:
string_cat_printf(str, "\tdevice_info_response {\r\n");
string_cat_printf(
str,
"\t\t%s: %s\r\n",
message->content.system_device_info_response.key,
message->content.system_device_info_response.value);
break;
case PB_Main_storage_mkdir_request_tag:
string_cat_printf(str, "\tmkdir {\r\n");
break;
case PB_Main_storage_delete_request_tag: {
string_cat_printf(str, "\tdelete {\r\n");
const char* path = message->content.storage_delete_request.path;
if(path) {
string_cat_printf(str, "\t\tpath: %s\r\n", path);
}
break;
}
case PB_Main_empty_tag:
string_cat_printf(str, "\tempty {\r\n");
break;
case PB_Main_storage_info_request_tag: {
string_cat_printf(str, "\tinfo_request {\r\n");
const char* path = message->content.storage_info_request.path;
if(path) {
string_cat_printf(str, "\t\tpath: %s\r\n", path);
}
break;
}
case PB_Main_storage_info_response_tag: {
string_cat_printf(str, "\tinfo_response {\r\n");
string_cat_printf(
str, "\t\ttotal_space: %lu\r\n", message->content.storage_info_response.total_space);
string_cat_printf(
str, "\t\tfree_space: %lu\r\n", message->content.storage_info_response.free_space);
break;
}
case PB_Main_storage_stat_request_tag: {
string_cat_printf(str, "\tstat_request {\r\n");
const char* path = message->content.storage_stat_request.path;
if(path) {
string_cat_printf(str, "\t\tpath: %s\r\n", path);
}
break;
}
case PB_Main_storage_stat_response_tag: {
string_cat_printf(str, "\tstat_response {\r\n");
if(message->content.storage_stat_response.has_file) {
const PB_Storage_File* msg_file = &message->content.storage_stat_response.file;
rpc_sprintf_msg_file(str, "\t\t\t", msg_file, 1);
}
break;
}
case PB_Main_storage_list_request_tag: {
string_cat_printf(str, "\tlist_request {\r\n");
const char* path = message->content.storage_list_request.path;
if(path) {
string_cat_printf(str, "\t\tpath: %s\r\n", path);
}
break;
}
case PB_Main_storage_read_request_tag: {
string_cat_printf(str, "\tread_request {\r\n");
const char* path = message->content.storage_read_request.path;
if(path) {
string_cat_printf(str, "\t\tpath: %s\r\n", path);
}
break;
}
case PB_Main_storage_write_request_tag: {
string_cat_printf(str, "\twrite_request {\r\n");
const char* path = message->content.storage_write_request.path;
if(path) {
string_cat_printf(str, "\t\tpath: %s\r\n", path);
}
if(message->content.storage_write_request.has_file) {
const PB_Storage_File* msg_file = &message->content.storage_write_request.file;
rpc_sprintf_msg_file(str, "\t\t\t", msg_file, 1);
}
break;
}
case PB_Main_storage_read_response_tag:
string_cat_printf(str, "\tread_response {\r\n");
if(message->content.storage_read_response.has_file) {
const PB_Storage_File* msg_file = &message->content.storage_read_response.file;
rpc_sprintf_msg_file(str, "\t\t\t", msg_file, 1);
}
break;
case PB_Main_storage_list_response_tag: {
const PB_Storage_File* msg_file = message->content.storage_list_response.file;
size_t msg_file_count = message->content.storage_list_response.file_count;
string_cat_printf(str, "\tlist_response {\r\n");
rpc_sprintf_msg_file(str, "\t\t", msg_file, msg_file_count);
break;
}
case PB_Main_storage_rename_request_tag: {
string_cat_printf(str, "\trename_request {\r\n");
string_cat_printf(
str, "\t\told_path: %s\r\n", message->content.storage_rename_request.old_path);
string_cat_printf(
str, "\t\tnew_path: %s\r\n", message->content.storage_rename_request.new_path);
break;
}
case PB_Main_gui_start_screen_stream_request_tag:
string_cat_printf(str, "\tstart_screen_stream {\r\n");
break;
case PB_Main_gui_stop_screen_stream_request_tag:
string_cat_printf(str, "\tstop_screen_stream {\r\n");
break;
case PB_Main_gui_screen_frame_tag:
string_cat_printf(str, "\tscreen_frame {\r\n");
break;
case PB_Main_gui_send_input_event_request_tag:
string_cat_printf(str, "\tsend_input_event {\r\n");
string_cat_printf(
str, "\t\tkey: %d\r\n", message->content.gui_send_input_event_request.key);
string_cat_printf(
str, "\t\type: %d\r\n", message->content.gui_send_input_event_request.type);
break;
case PB_Main_gui_start_virtual_display_request_tag:
string_cat_printf(str, "\tstart_virtual_display {\r\n");
break;
case PB_Main_gui_stop_virtual_display_request_tag:
string_cat_printf(str, "\tstop_virtual_display {\r\n");
break;
}
string_cat_printf(str, "\t}\r\n}\r\n");
printf("%s", string_get_cstr(str));
string_clear(str);
}
void rpc_session_set_context(RpcSession* session, void* context) {
furi_assert(session);
@ -409,6 +149,9 @@ void rpc_session_set_terminated_callback(
size_t
rpc_session_feed(RpcSession* session, uint8_t* encoded_bytes, size_t size, TickType_t timeout) {
furi_assert(session);
furi_assert(encoded_bytes);
furi_assert(size > 0);
size_t bytes_sent = xStreamBufferSend(session->stream, encoded_bytes, size, timeout);
furi_thread_flags_set(furi_thread_get_id(session->thread), RpcEvtNewData);
@ -422,6 +165,8 @@ size_t rpc_session_get_available_size(RpcSession* session) {
}
bool rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) {
furi_assert(istream);
furi_assert(buf);
RpcSession* session = istream->state;
furi_assert(session);
furi_assert(istream->bytes_left);
@ -462,16 +207,17 @@ bool rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_t count) {
}
#if SRV_RPC_DEBUG
rpc_print_data("INPUT", buf, bytes_received);
rpc_debug_print_data("INPUT", buf, bytes_received);
#endif
return (count == bytes_received);
}
static bool content_callback(pb_istream_t* stream, const pb_field_t* field, void** arg) {
static bool rpc_pb_content_callback(pb_istream_t* stream, const pb_field_t* field, void** arg) {
furi_assert(stream);
RpcSession* session = stream->state;
furi_assert(session);
furi_assert(field);
RpcHandler* handler = RpcHandlerDict_get(session->handlers, field->tag);
@ -502,7 +248,7 @@ static int32_t rpc_session_worker(void* context) {
if(pb_decode_ex(&istream, &PB_Main_msg, session->decoded_message, PB_DECODE_DELIMITED)) {
#if SRV_RPC_DEBUG
FURI_LOG_I(TAG, "INPUT:");
rpc_print_message(session->decoded_message);
rpc_debug_print_message(session->decoded_message);
#endif
RpcHandler* handler =
RpcHandlerDict_get(session->handlers, session->decoded_message->which_content);
@ -610,7 +356,7 @@ RpcSession* rpc_session_open(Rpc* rpc) {
RpcHandlerDict_init(session->handlers);
session->decoded_message = malloc(sizeof(PB_Main));
session->decoded_message->cb_content.funcs.decode = content_callback;
session->decoded_message->cb_content.funcs.decode = rpc_pb_content_callback;
session->decoded_message->cb_content.arg = session;
session->system_contexts = malloc(COUNT_OF(rpc_systems) * sizeof(void*));
@ -678,7 +424,7 @@ void rpc_send(RpcSession* session, PB_Main* message) {
#if SRV_RPC_DEBUG
FURI_LOG_I(TAG, "OUTPUT:");
rpc_print_message(message);
rpc_debug_print_message(message);
#endif
bool result = pb_encode_ex(&ostream, &PB_Main_msg, message, PB_ENCODE_DELIMITED);
@ -690,7 +436,7 @@ void rpc_send(RpcSession* session, PB_Main* message) {
pb_encode_ex(&ostream, &PB_Main_msg, message, PB_ENCODE_DELIMITED);
#if SRV_RPC_DEBUG
rpc_print_data("OUTPUT", buffer, ostream.bytes_written);
rpc_debug_print_data("OUTPUT", buffer, ostream.bytes_written);
#endif
furi_mutex_acquire(session->callbacks_mutex, FuriWaitForever);

View file

@ -299,6 +299,7 @@ void* rpc_system_app_alloc(RpcSession* session) {
void rpc_system_app_free(void* context) {
RpcAppSystem* rpc_app = context;
furi_assert(rpc_app);
RpcSession* session = rpc_app->session;
furi_assert(session);

View file

@ -14,23 +14,23 @@ typedef struct {
#define CLI_READ_BUFFER_SIZE 64
static void rpc_send_bytes_callback(void* context, uint8_t* bytes, size_t bytes_len) {
static void rpc_cli_send_bytes_callback(void* context, uint8_t* bytes, size_t bytes_len) {
furi_assert(context);
furi_assert(bytes);
furi_assert(bytes_len);
furi_assert(bytes_len > 0);
CliRpc* cli_rpc = context;
cli_write(cli_rpc->cli, bytes, bytes_len);
}
static void rpc_session_close_callback(void* context) {
static void rpc_cli_session_close_callback(void* context) {
furi_assert(context);
CliRpc* cli_rpc = context;
cli_rpc->session_close_request = true;
}
static void rpc_session_terminated_callback(void* context) {
static void rpc_cli_session_terminated_callback(void* context) {
furi_check(context);
CliRpc* cli_rpc = context;
@ -39,6 +39,8 @@ static void rpc_session_terminated_callback(void* context) {
void rpc_cli_command_start_session(Cli* cli, string_t args, void* context) {
UNUSED(args);
furi_assert(cli);
furi_assert(context);
Rpc* rpc = context;
uint32_t mem_before = memmgr_get_free_heap();
@ -55,9 +57,9 @@ void rpc_cli_command_start_session(Cli* cli, string_t args, void* context) {
CliRpc cli_rpc = {.cli = cli, .session_close_request = false};
cli_rpc.terminate_semaphore = furi_semaphore_alloc(1, 0);
rpc_session_set_context(rpc_session, &cli_rpc);
rpc_session_set_send_bytes_callback(rpc_session, rpc_send_bytes_callback);
rpc_session_set_close_callback(rpc_session, rpc_session_close_callback);
rpc_session_set_terminated_callback(rpc_session, rpc_session_terminated_callback);
rpc_session_set_send_bytes_callback(rpc_session, rpc_cli_send_bytes_callback);
rpc_session_set_close_callback(rpc_session, rpc_cli_session_close_callback);
rpc_session_set_terminated_callback(rpc_session, rpc_cli_session_terminated_callback);
uint8_t* buffer = malloc(CLI_READ_BUFFER_SIZE);
size_t size_received = 0;

View file

@ -0,0 +1,260 @@
#include "rpc_i.h"
#include <m-string.h>
static size_t rpc_debug_print_file_msg(
string_t str,
const char* prefix,
const PB_Storage_File* msg_file,
size_t msg_files_size) {
size_t cnt = 0;
for(size_t i = 0; i < msg_files_size; ++i, ++msg_file) {
string_cat_printf(
str,
"%s[%c] size: %5ld",
prefix,
msg_file->type == PB_Storage_File_FileType_DIR ? 'd' : 'f',
msg_file->size);
if(msg_file->name) {
string_cat_printf(str, " \'%s\'", msg_file->name);
}
if(msg_file->data && msg_file->data->size) {
string_cat_printf(
str,
" (%d):\'%.*s%s\'",
msg_file->data->size,
MIN(msg_file->data->size, 30),
msg_file->data->bytes,
msg_file->data->size > 30 ? "..." : "");
}
string_cat_printf(str, "\r\n");
}
return cnt;
}
void rpc_debug_print_data(const char* prefix, uint8_t* buffer, size_t size) {
string_t str;
string_init(str);
string_reserve(str, 100 + size * 5);
string_cat_printf(str, "\r\n%s DEC(%d): {", prefix, size);
for(size_t i = 0; i < size; ++i) {
string_cat_printf(str, "%d, ", buffer[i]);
}
string_cat_printf(str, "}\r\n");
printf("%s", string_get_cstr(str));
string_reset(str);
string_reserve(str, 100 + size * 3);
string_cat_printf(str, "%s HEX(%d): {", prefix, size);
for(size_t i = 0; i < size; ++i) {
string_cat_printf(str, "%02X", buffer[i]);
}
string_cat_printf(str, "}\r\n\r\n");
printf("%s", string_get_cstr(str));
string_clear(str);
}
void rpc_debug_print_message(const PB_Main* message) {
string_t str;
string_init(str);
string_cat_printf(
str,
"PB_Main: {\r\n\tresult: %d cmd_id: %ld (%s)\r\n",
message->command_status,
message->command_id,
message->has_next ? "has_next" : "last");
switch(message->which_content) {
default:
/* not implemented yet */
string_cat_printf(str, "\tNOT_IMPLEMENTED (%d) {\r\n", message->which_content);
break;
case PB_Main_stop_session_tag:
string_cat_printf(str, "\tstop_session {\r\n");
break;
case PB_Main_app_start_request_tag: {
string_cat_printf(str, "\tapp_start {\r\n");
const char* name = message->content.app_start_request.name;
const char* args = message->content.app_start_request.args;
if(name) {
string_cat_printf(str, "\t\tname: %s\r\n", name);
}
if(args) {
string_cat_printf(str, "\t\targs: %s\r\n", args);
}
break;
}
case PB_Main_app_lock_status_request_tag: {
string_cat_printf(str, "\tapp_lock_status_request {\r\n");
break;
}
case PB_Main_app_lock_status_response_tag: {
string_cat_printf(str, "\tapp_lock_status_response {\r\n");
bool lock_status = message->content.app_lock_status_response.locked;
string_cat_printf(str, "\t\tlocked: %s\r\n", lock_status ? "true" : "false");
break;
}
case PB_Main_storage_md5sum_request_tag: {
string_cat_printf(str, "\tmd5sum_request {\r\n");
const char* path = message->content.storage_md5sum_request.path;
if(path) {
string_cat_printf(str, "\t\tpath: %s\r\n", path);
}
break;
}
case PB_Main_storage_md5sum_response_tag: {
string_cat_printf(str, "\tmd5sum_response {\r\n");
const char* path = message->content.storage_md5sum_response.md5sum;
if(path) {
string_cat_printf(str, "\t\tmd5sum: %s\r\n", path);
}
break;
}
case PB_Main_system_ping_request_tag:
string_cat_printf(str, "\tping_request {\r\n");
break;
case PB_Main_system_ping_response_tag:
string_cat_printf(str, "\tping_response {\r\n");
break;
case PB_Main_system_device_info_request_tag:
string_cat_printf(str, "\tdevice_info_request {\r\n");
break;
case PB_Main_system_device_info_response_tag:
string_cat_printf(str, "\tdevice_info_response {\r\n");
string_cat_printf(
str,
"\t\t%s: %s\r\n",
message->content.system_device_info_response.key,
message->content.system_device_info_response.value);
break;
case PB_Main_storage_mkdir_request_tag:
string_cat_printf(str, "\tmkdir {\r\n");
break;
case PB_Main_storage_delete_request_tag: {
string_cat_printf(str, "\tdelete {\r\n");
const char* path = message->content.storage_delete_request.path;
if(path) {
string_cat_printf(str, "\t\tpath: %s\r\n", path);
}
break;
}
case PB_Main_empty_tag:
string_cat_printf(str, "\tempty {\r\n");
break;
case PB_Main_storage_info_request_tag: {
string_cat_printf(str, "\tinfo_request {\r\n");
const char* path = message->content.storage_info_request.path;
if(path) {
string_cat_printf(str, "\t\tpath: %s\r\n", path);
}
break;
}
case PB_Main_storage_info_response_tag: {
string_cat_printf(str, "\tinfo_response {\r\n");
string_cat_printf(
str, "\t\ttotal_space: %lu\r\n", message->content.storage_info_response.total_space);
string_cat_printf(
str, "\t\tfree_space: %lu\r\n", message->content.storage_info_response.free_space);
break;
}
case PB_Main_storage_stat_request_tag: {
string_cat_printf(str, "\tstat_request {\r\n");
const char* path = message->content.storage_stat_request.path;
if(path) {
string_cat_printf(str, "\t\tpath: %s\r\n", path);
}
break;
}
case PB_Main_storage_stat_response_tag: {
string_cat_printf(str, "\tstat_response {\r\n");
if(message->content.storage_stat_response.has_file) {
const PB_Storage_File* msg_file = &message->content.storage_stat_response.file;
rpc_debug_print_file_msg(str, "\t\t\t", msg_file, 1);
}
break;
}
case PB_Main_storage_list_request_tag: {
string_cat_printf(str, "\tlist_request {\r\n");
const char* path = message->content.storage_list_request.path;
if(path) {
string_cat_printf(str, "\t\tpath: %s\r\n", path);
}
break;
}
case PB_Main_storage_read_request_tag: {
string_cat_printf(str, "\tread_request {\r\n");
const char* path = message->content.storage_read_request.path;
if(path) {
string_cat_printf(str, "\t\tpath: %s\r\n", path);
}
break;
}
case PB_Main_storage_write_request_tag: {
string_cat_printf(str, "\twrite_request {\r\n");
const char* path = message->content.storage_write_request.path;
if(path) {
string_cat_printf(str, "\t\tpath: %s\r\n", path);
}
if(message->content.storage_write_request.has_file) {
const PB_Storage_File* msg_file = &message->content.storage_write_request.file;
rpc_debug_print_file_msg(str, "\t\t\t", msg_file, 1);
}
break;
}
case PB_Main_storage_read_response_tag:
string_cat_printf(str, "\tread_response {\r\n");
if(message->content.storage_read_response.has_file) {
const PB_Storage_File* msg_file = &message->content.storage_read_response.file;
rpc_debug_print_file_msg(str, "\t\t\t", msg_file, 1);
}
break;
case PB_Main_storage_list_response_tag: {
const PB_Storage_File* msg_file = message->content.storage_list_response.file;
size_t msg_file_count = message->content.storage_list_response.file_count;
string_cat_printf(str, "\tlist_response {\r\n");
rpc_debug_print_file_msg(str, "\t\t", msg_file, msg_file_count);
break;
}
case PB_Main_storage_rename_request_tag: {
string_cat_printf(str, "\trename_request {\r\n");
string_cat_printf(
str, "\t\told_path: %s\r\n", message->content.storage_rename_request.old_path);
string_cat_printf(
str, "\t\tnew_path: %s\r\n", message->content.storage_rename_request.new_path);
break;
}
case PB_Main_gui_start_screen_stream_request_tag:
string_cat_printf(str, "\tstart_screen_stream {\r\n");
break;
case PB_Main_gui_stop_screen_stream_request_tag:
string_cat_printf(str, "\tstop_screen_stream {\r\n");
break;
case PB_Main_gui_screen_frame_tag:
string_cat_printf(str, "\tscreen_frame {\r\n");
break;
case PB_Main_gui_send_input_event_request_tag:
string_cat_printf(str, "\tsend_input_event {\r\n");
string_cat_printf(
str, "\t\tkey: %d\r\n", message->content.gui_send_input_event_request.key);
string_cat_printf(
str, "\t\type: %d\r\n", message->content.gui_send_input_event_request.type);
break;
case PB_Main_gui_start_virtual_display_request_tag:
string_cat_printf(str, "\tstart_virtual_display {\r\n");
break;
case PB_Main_gui_stop_virtual_display_request_tag:
string_cat_printf(str, "\tstop_virtual_display {\r\n");
break;
}
string_cat_printf(str, "\t}\r\n}\r\n");
printf("%s", string_get_cstr(str));
string_clear(str);
}

View file

@ -57,7 +57,6 @@ static void rpc_system_gpio_set_pin_mode(const PB_Main* request, void* context)
furi_assert(request->which_content == PB_Main_gpio_set_pin_mode_tag);
RpcSession* session = context;
furi_assert(session);
PB_Gpio_SetPinMode cmd = request->content.gpio_set_pin_mode;
const GpioPin* pin = rpc_pin_to_hal_pin(cmd.pin);
@ -77,7 +76,6 @@ static void rpc_system_gpio_write_pin(const PB_Main* request, void* context) {
furi_assert(request->which_content == PB_Main_gpio_write_pin_tag);
RpcSession* session = context;
furi_assert(session);
PB_Gpio_WritePin cmd = request->content.gpio_write_pin;
const GpioPin* pin = rpc_pin_to_hal_pin(cmd.pin);
@ -105,7 +103,6 @@ static void rpc_system_gpio_read_pin(const PB_Main* request, void* context) {
furi_assert(request->which_content == PB_Main_gpio_read_pin_tag);
RpcSession* session = context;
furi_assert(session);
PB_Gpio_ReadPin cmd = request->content.gpio_read_pin;
const GpioPin* pin = rpc_pin_to_hal_pin(cmd.pin);
@ -133,7 +130,6 @@ void rpc_system_gpio_get_pin_mode(const PB_Main* request, void* context) {
furi_assert(request->which_content == PB_Main_gpio_get_pin_mode_tag);
RpcSession* session = context;
furi_assert(session);
PB_Gpio_GetPinMode cmd = request->content.gpio_get_pin_mode;
const GpioPin* pin = rpc_pin_to_hal_pin(cmd.pin);
@ -170,7 +166,6 @@ void rpc_system_gpio_set_input_pull(const PB_Main* request, void* context) {
furi_assert(request->which_content == PB_Main_gpio_set_input_pull_tag);
RpcSession* session = context;
furi_assert(session);
PB_Gpio_SetInputPull cmd = request->content.gpio_set_input_pull;
const GpioPin* pin = rpc_pin_to_hal_pin(cmd.pin);

View file

@ -35,7 +35,9 @@ void rpc_system_gui_free(void* ctx);
void* rpc_system_gpio_alloc(RpcSession* session);
void rpc_system_gpio_free(void* ctx);
void rpc_print_message(const PB_Main* message);
void rpc_debug_print_message(const PB_Main* message);
void rpc_debug_print_data(const char* prefix, uint8_t* buffer, size_t size);
void rpc_cli_command_start_session(Cli* cli, string_t args, void* context);
PB_CommandStatus rpc_system_storage_get_error(FS_Error fs_error);

View file

@ -37,6 +37,7 @@ static void rpc_system_storage_reset_state(
RpcSession* session,
bool send_error) {
furi_assert(rpc_storage);
furi_assert(session);
if(rpc_storage->state != RpcStorageStateIdle) {
if(send_error) {
@ -177,6 +178,8 @@ static void rpc_system_storage_stat_process(const PB_Main* request, void* contex
}
static void rpc_system_storage_list_root(const PB_Main* request, void* context) {
furi_assert(request);
furi_assert(context);
RpcStorageSystem* rpc_storage = context;
RpcSession* session = rpc_storage->session;
furi_assert(session);
@ -411,6 +414,8 @@ static void rpc_system_storage_write_process(const PB_Main* request, void* conte
}
static bool rpc_system_storage_is_dir_is_empty(Storage* fs_api, const char* path) {
furi_assert(fs_api);
furi_assert(path);
FileInfo fileinfo;
bool is_dir_is_empty = true;
FS_Error error = storage_common_stat(fs_api, path, &fileinfo);
@ -605,6 +610,7 @@ static void rpc_system_storage_rename_process(const PB_Main* request, void* cont
static void rpc_system_storage_backup_create_process(const PB_Main* request, void* context) {
furi_assert(request);
furi_assert(request->which_content == PB_Main_storage_backup_create_request_tag);
furi_assert(context);
FURI_LOG_D(TAG, "BackupCreate");
@ -626,6 +632,7 @@ static void rpc_system_storage_backup_create_process(const PB_Main* request, voi
static void rpc_system_storage_backup_restore_process(const PB_Main* request, void* context) {
furi_assert(request);
furi_assert(request->which_content == PB_Main_storage_backup_restore_request_tag);
furi_assert(context);
FURI_LOG_D(TAG, "BackupRestore");
@ -695,6 +702,7 @@ void* rpc_system_storage_alloc(RpcSession* session) {
}
void rpc_system_storage_free(void* context) {
furi_assert(context);
RpcStorageSystem* rpc_storage = context;
RpcSession* session = rpc_storage->session;
furi_assert(session);

View file

@ -77,6 +77,7 @@ static void rpc_system_system_device_info_callback(
furi_assert(key);
furi_assert(value);
RpcSystemContext* ctx = context;
furi_assert(ctx);
furi_assert(key);
furi_assert(value);
@ -233,6 +234,7 @@ static void rpc_system_system_power_info_callback(
furi_assert(key);
furi_assert(value);
RpcSystemContext* ctx = context;
furi_assert(ctx);
furi_assert(key);
furi_assert(value);
@ -297,6 +299,8 @@ static void rpc_system_system_update_request_process(const PB_Main* request, voi
#endif
void* rpc_system_system_alloc(RpcSession* session) {
furi_assert(session);
RpcHandler rpc_handler = {
.message_handler = NULL,
.decode_submessage = NULL,

View file

@ -215,7 +215,7 @@ static void test_rpc_print_message_list(MsgList_t msg_list) {
MsgList_reverse(msg_list);
for
M_EACH(msg, msg_list, MsgList_t) {
rpc_print_message(msg);
rpc_debug_print_message(msg);
}
MsgList_reverse(msg_list);
#else

View file

@ -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 188
#define TEST_RANDOM_COUNT_PARSE 196
#define TEST_TIMEOUT 10000
static SubGhzEnvironment* environment_handler;
@ -412,6 +412,13 @@ MU_TEST(subghz_decoder_honeywell_wdb_test) {
"Test decoder " SUBGHZ_PROTOCOL_HONEYWELL_WDB_NAME " error\r\n");
}
MU_TEST(subghz_decoder_magellen_test) {
mu_assert(
subghz_decoder_test(
EXT_PATH("unit_tests/subghz/magellen_raw.sub"), SUBGHZ_PROTOCOL_MAGELLEN_NAME),
"Test decoder " SUBGHZ_PROTOCOL_MAGELLEN_NAME " error\r\n");
}
//test encoders
MU_TEST(subghz_encoder_princeton_test) {
mu_assert(
@ -515,6 +522,12 @@ MU_TEST(subghz_encoder_honeywell_wdb_test) {
"Test encoder " SUBGHZ_PROTOCOL_HONEYWELL_WDB_NAME " error\r\n");
}
MU_TEST(subghz_encoder_magellen_test) {
mu_assert(
subghz_encoder_test(EXT_PATH("unit_tests/subghz/magellen.sub")),
"Test encoder " SUBGHZ_PROTOCOL_MAGELLEN_NAME " error\r\n");
}
MU_TEST(subghz_random_test) {
mu_assert(subghz_decode_random_test(TEST_RANDOM_DIR_NAME), "Random test error\r\n");
}
@ -552,6 +565,7 @@ MU_TEST_SUITE(subghz) {
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_decoder_magellen_test);
MU_RUN_TEST(subghz_encoder_princeton_test);
MU_RUN_TEST(subghz_encoder_came_test);
@ -570,6 +584,7 @@ MU_TEST_SUITE(subghz) {
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_encoder_magellen_test);
MU_RUN_TEST(subghz_random_test);
subghz_test_deinit();

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

View file

@ -0,0 +1,7 @@
Filetype: Flipper SubGhz Key File
Version: 1
Frequency: 433920000
Preset: FuriHalSubGhzPresetOok650Async
Protocol: Magellen
Bit: 32
Key: 00 00 00 00 37 AE 48 28

View file

@ -0,0 +1,8 @@
Filetype: Flipper SubGhz RAW File
Version: 1
Frequency: 433920000
Preset: FuriHalSubGhzPresetOok650Async
Protocol: RAW
RAW_Data: 29262 361 -68 2635 -66 24113 -66 1131 -100 4157 -66 26253 -130 621 -18438 99 -298 231 -66 197 -496 753 -230 7503 -16526 65 -396 65 -296 99 -196 293 -64 429 -132 397 -66 329 -66 37701 -66 13475 -100 54967 -64 18209 -18340 97 -462 197 -98 587 -232 97 -100 259 -98 197 -262 297 -64 557 -100 599 -100 333 -234 42493 -13212 6449 -206 173 -214 217 -176 195 -218 181 -218 181 -182 217 -182 217 -176 187 -214 215 -180 217 -182 217 -182 217 -178 185 -424 1177 -388 387 -240 381 -214 181 -398 211 -380 419 -176 217 -394 203 -394 205 -380 189 -402 421 -168 219 -398 393 -190 191 -398 205 -406 185 -402 381 -212 215 -362 241 -378 421 -176 377 -218 197 -378 427 -210 393 -172 429 -172 397 -212 217 -362 389 -228 197 -372 417 -204 395 -210 181 -398 391 -192 201 -216888 761 -200 299 -166 695 -132 15435 -66 5611 -66 21049 -66 4947 -66 2355 -66 1921 -100 2223 -100 2107 -100 397 -98 3643 -66 5301 -98 14205 -66 37371 -246 175 -216 179 -216 177 -224 149 -246 159 -228 181 -212 201 -204 159 -244 151 -254 169 -214 181 -210 197 -182 181 -454 1141 -444 357 -228 361 -246 177 -396 209 -412 367 -188 187 -434 201 -394 185 -406 193 -402 377 -238 181 -386 381 -234 153 -424 205 -412 157 -412 383 -240 181 -398 203 -392 385 -236 371 -212 179 -400 383 -240 359 -210 375 -220 381 -246 175 -394 383 -240 181 -398 363 -222 379 -246 175 -394 383 -204 217 -182856 99 -66 99 -300 133 -402 65 -198 99 -328 65 -100 491 -164 593 -100 3547 -64 361 -66 789 -68 2521 -66 22883 -66 2659 -98 3309 -130 3789 -100 9689 -17178 99 -1388 65 -266 197 -100 131 -134 99 -232 627 -130 233 -66 1949 -100 14567 -198 165 -256 181 -208 159 -214 183 -220 163 -244 149 -246 159 -236 181 -254 141 -226 151 -246 157 -228 181 -212 201 -400 1163 -428 379 -230 355 -244 177 -396 207 -412 367 -222 157 -418 189 -410 207 -412 171 -430 357 -226 165 -404 413 -204 181 -428 173 -428 169 -426 353 -236 173 -414 173 -408 381 -244 337 -222 201 -408 397 -208 393 -204 395 -208 359 -246 177 -394 387 -200 205 -380 415 -202 395 -208 181 -432 357 -226 169 -195084 65 -300 763 -66 297 -364 593 -68 2883 -66 1357 -68 363 -98 3841 -66 3119 -66 5153 -66 4023 -268 143 -246 133 -290 141 -250 139 -254 141 -226 181 -248 137 -254 143 -252 139 -252 143 -230 181 -250 139 -254 145 -436 1135 -448 349 -240 347 -254 157 -434 167 -426 377 -226 157 -434 167 -426 155 -440 163 -434 375 -206 215 -380 381 -234 153
RAW_Data: -424 205 -412 159 -412 381 -240 181 -398 203 -392 387 -236 369 -212 179 -400 383 -240 359 -244 339 -222 381 -246 175 -394 383 -240 181 -398 363 -222 381 -244 175 -392 383 -240 181 -184002 99 -360 63 -330 65 -132 129 -232 97 -198 295 -328 6031 -66 831 -132 3417 -66 2187 -64 2183 -100 6535 -66 1127 -66 2569 -66 2031 -66 2271 -66 2183 -66 3815 -66 3803 -66 493 -66 1909 -66 1627 -98 4805 -17512 67 -2164 131 -498 265 -430 163 -98 97 -64 99 -230 99 -100 229 -230 165 -196 63 -132 99 -66 927 -66 14955 -66 19621 -68 2627 -66 14305 -68 23247 -66 2891 -66 3941 -66 3021 -212 173 -242 181 -218 181 -214 181 -208 157 -250 141 -248 181 -218 179 -214 179 -210 159 -250 179 -214 181 -218 181 -404 1153 -404 389 -244 375 -192 181 -436 161 -414 383 -240 181 -398 205 -392 201 -394 205 -394 365 -246 177 -396 383 -204 217 -398 171 -426 167 -428 353 -242 173 -420 173 -408 373 -220 403 -208 175 -422 381 -194 399 -228 357 -246 355 -210 215 -400 387 -208 181 -398 391 -226 353 -246 177 -398 383 -204 217 -185098 163 -166 525 -98 293 -100 63 -66 229 -66 1183 -66 1507 -66 3089 -98 30187 -66 2847 -19112 133 -364 131 -394 97 -166 295 -66 229 -164 227 -66 263 -130 623 -98 2071 -66 493 -66 787 -98 691 -64 10249 -132 3879 -66 1949 -66 3453 -198 23157 -66 2845 -100 1193 -66 1587 -100 3797 -98 3187 -100 3319 -66 22119 -98 5513 -226 155 -244 153 -256 131 -248 151 -246 159 -262 121 -274 133 -272 127 -244 153 -254 167 -248 145 -244 133 -252 177 -398 1169 -418 381 -238 359 -242 141 -430 169 -426 357 -274 139 -422 171 -442 173 -428 167 -426 353 -236 171 -416 379 -226 149 -436 161 -438 173 -406 381 -234 153 -424 205 -380 389 -244 359 -206 215 -384 381 -246 335 -224 383 -246 355 -244 179 -404 385 -206 181 -432 359 -226 355 -246 175 -398 383 -240 181 -179760 97 -168 727 -66 97 -332 1389 -66 2793 -66 4955 -100 12453 -100 2425 -66 21965 -66 3809 -68 1683 -66 3095 -66 2153 -64 999 -208 173 -220 181 -214 191 -196 181 -212 183 -220 191 -212 181 -214 191 -198 181 -212 181 -222 191 -212 181 -214 191 -416 1167 -424 369 -220 373 -210 209 -390 207 -376 403 -190 187 -418 189 -408 209 -412 173 -428 357 -226 169 -404 399 -208 179 -412 209 -396 169 -428 355 -230 201 -378 205 -406 381 -244 339 -222 193 -400 413 -204 393 -208 347 -220 401 -210 175 -422 383 -202 217 -398 365 -222 377 -246 175 -390 385 -204 217 -179890 165 -1552 131 -164 65
RAW_Data: -1448 361 -17056 131 -134 233 -1462 131 -166 953 -100 261 -164 5077 -272 137 -268 143 -252 141 -248 143 -246 159 -252 141 -244 143 -290 107 -276 145 -244 131 -250 179 -248 143 -252 141 -414 1165 -424 373 -236 359 -242 145 -434 169 -428 355 -230 169 -442 173 -434 157 -406 193 -402 379 -238 181 -422 335 -252 157 -434 167 -428 185 -406 381 -208 211 -390 207 -410 381 -200 373 -236 171 -414 383 -202 393 -210 379 -220 373 -208 211 -390 383 -204 217 -398 365 -220 379 -244 175 -394 381 -240 181 -161030 97 -166 167 -930 593 -2670 1091 -132 229 -98 461 -164 1649 -66 6311 -100 44723 -16832 67 -2656 131 -132 99 -132 263 -100 399 -68 893 -18950 99 -164 165 -198 525 -998 335 -66 565 -66 1057 -17880 97 -360 195 -262 131 -332 625 -98 197 -230 455 -98 9343 -16498 67 -368 131 -598 65 -1066 333 -300 789 -130 757 -66 87207 -16554 97 -3520 97 -786 591 -64 461 -98 21495 -66 24811 -18448 131 -296 491 -134 163 -760 1091 -230 893 -66 927 -68 4581 -68 32965 -64 45217 -17292 131 -1684 231 -132 327 -64 163 -330 263 -230 25751

View file

@ -128,3 +128,14 @@ RAW_Data: 161 -302 147 -320 331 -162 171 -314 161 -312 163 -300 175 -296 195 -31
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: 15041 -66 15883 -66 12643 -66 12681 -66 3413 -68 2713 -68 33389 -66 1445 -66 1279 -68 1027 -66 6911 -98 25229 -66 3967 -100 3019 -100 6131 -66 955 -66 3605 -66 12411 -98 1419 -66 3593 -68 2753 -66 2457 -66 6007 -66 627 -100 1597 -66 3071 -98 22749 -66 333 -66 12829 -66 4313 -132 855 -66 44097 -64 20391 -98 29999 -66 3539 -98 557 -66 1489 -100 4081 -100 3857 -64 2895 -132 2261 -166 3089 -66 2429 -68 34467 -66 3585 -66 3087 -66 3329 -132 5287 -66 1063 -98 15259 -100 2535 -66 995 -66 13057 -100 24233 -68 531 -100 26415 -66 1761 -100 2717 -66 4071 -100 12191 -66 23367 -68 2323 -66 19809 -248 245 -1388 255 -242 275 -1358 273 -1370 277 -246 277 -1368 275 -246 275 -1362 275 -244 275 -1364 275 -244 275 -1362 275 -244 275 -1328 273 -278 273 -1358 275 -246 275 -238 263 -1384 275 -246 273 -1358 275 -244 273 -1358 275 -246 275 -1360 275 -1344 277 -246 275 -1358 275 -244 275 -234 263 -1382 277 -1344 277 -246 279 -1362 275 -246 271 -234 261 -1380 275 -246 273 -1360 275 -246 275 -1366 277 -1340 277 -248 279 -238 263 -1382 275 -1344 277 -246 279 -1364 277 -244 275 -234 263 -1382 277 -244 273 -1358 275 -1344 277 -248 279 -1368 275 -244 273 -1360 239 -280 271 -1358 275 -244 275 -1358 275 -174 269 -10298 289 -2660 267 -238 299 -1356 275 -244 275 -1356 275 -1344 277 -248 277 -1360 275 -246 275 -1328 309 -244 273 -1358 277 -244 275 -1356 275 -246 273 -1326 309 -244 275 -1356 275 -246 273 -234 263 -1380 277 -246 273 -1326 309 -244 273 -1356 277 -246 277 -1358 275 -1338 279 -248 279 -1364 275 -246 273 -234 261 -1380 277 -1344 279 -250 277 -1330 309 -244 273 -232 261 -1384 275 -246 273 -1356 275 -248 275 -1360 275 -1340 279 -248 277 -236 263 -1380 277 -1342 279 -248 279 -1366 275 -246 273 -234 263 -1380 275 -246 275 -1358 275 -1340 279 -248 281 -1336 309 -244 273 -1358 275 -246 273 -1360 275 -244 273 -1358 275 -176 267 -10306 257 -2646 299 -234 301 -1354 277 -246 275 -1356 277 -1340 279 -250 279 -1332 309 -244 275 -1358 275 -248 273 -1326 309 -246 273 -1326 309 -244 275 -1356 277 -248 275 -1328 309 -246 273 -234 261 -1382 277 -246 277 -1326 309 -244 275 -1358 277 -246 277 -1356 277 -1346 277 -250 277 -1358 277 -246 275 -234 263 -1382 279 -1346 279 -248 281 -1330 307 -246 273 -236 261 -1380 277 -246 277 -1360 277 -246 277 -1360 275 -1344 279 -248 279 -236 263 -1384 277 -1340 279 -250 281 -1338 307 -246 271 -234 261 -1384 277 -246 275 -1356 277 -1340 279 -250 283 -1336 309 -246 273 -1356 277 -246 273 -1360 277 -246
RAW_Data: 275 -1328 309 -174 269 -10296 289 -2648 267 -238 299 -1356 277 -246 275 -1324 307 -1342 279 -250 277 -1330 309 -244 275 -1362 277 -244 275 -1356 275 -248 273 -1328 309 -244 273 -1328 309 -244 275 -1360 277 -246 275 -234 259 -1384 277 -246 275 -1360 275 -246 273 -1358 277 -248 277 -1362 275 -1344 277 -248 277 -1328 307 -246 273 -236 261 -1384 277 -1348 279 -248 279 -1360 277 -246 273 -234 263 -1388 275 -246 275 -1360 277 -248 279 -1368 277 -1344 279 -248 279 -240 265 -1386 275 -1342 279 -286 247 -1372 275 -248 275 -238 265 -1386 277 -248 275 -1360 275 -1344 277 -286 247 -1374 275 -246 275 -1362 277 -246 275 -1360 277 -248 275 -1326 307 -174 269 -10290 287 -2654 269 -236 301 -1352 275 -248 273 -1326 311 -1340 277 -248 277 -1328 309 -244 273 -1358 275 -244 275 -1326 309 -244 273 -1356 277 -244 273 -1356 275 -246 275 -1358 275 -244 275 -234 261 -1382 277 -246 273 -1358 275 -246 273 -1360 277 -246 273 -1324 309 -1340 277 -248 277 -1328 307 -246 271 -234 259 -1382 277 -1346 279 -248 277 -1330 309 -244 271 -232 259 -1382 277 -244 275 -1356 277 -248 273 -1354 277 -1342 277 -248 275 -236 261 -1380 277 -1344 277 -248 279 -1330 307 -246 273 -234 261 -1378 277 -246 273 -1356 277 -1342 277 -248 277 -1330 309 -244 273 -1322 307 -246 273 -1326 309 -244 273 -1322 309 -176 267 -10298 257 -2682 265 -236 299 -1324 309 -248 273 -1324 311 -1342 277 -246 279 -1360 277 -244 275 -1362 275 -244 275 -1358 275 -244 275 -1360 275 -246 273 -1360 275 -244 277 -1360 275 -246 273 -234 263 -1384 275 -246 273 -1358 275 -246 275 -1360 277 -246 277 -1356 277 -1342 279 -248 277 -1364 275 -244 275 -234 261 -1384 275 -1344 277 -250 279 -1366 275 -246 273 -236 263 -1384 277 -246 275 -1358 277 -246 277 -1362 277 -1342 279 -248 279 -236 265 -1382 277 -1346 277 -248 281 -1366 275 -246 275 -234 265 -1384 275 -246 273 -1358 277 -1344 279 -248 279 -1364 275 -244 275 -1324 309 -246 273 -1324 307 -246 273 -1326 309 -174 267 -118796 133 -100 131 -892 329 -166 199 -132 131 -166 99 -100 265 -264 4663 -134 4889 -100 365 -98 5921 -100 5903 -68 4877 -98 2953 -98 1645 -64 1687 -66 981 -98 10769 -66 18319 -66 4831 -66 13301 -66 893 -132 5967 -100 15949 -66 3749 -66 497 -100 625 -66 1147 -66 469 -66 1261 -66 3651 -100 265 -100 26741 -68 6873 -66 4485 -100 2667 -68 3159 -68 2857 -132 2655 -66 12903 -66 1277 -66 1711 -66 787 -100 1327 -198 727 -64 1677 -100 1187 -66 1019 -66 891 -66 4303 -100 11297 -66 3923 -254 253 -1380 247 -292 253 -1344
RAW_Data: 277 -1346 277 -250 279 -1364 275 -244 275 -1362 275 -244 275 -1356 275 -246 273 -1358 241 -278 273 -1356 275 -246 273 -1360 275 -246 273 -234 263 -1382 275 -244 273 -1358 275 -246 273 -1360 275 -246 273 -1358 275 -1340 277 -248 277 -1362 275 -246 273 -234 261 -1380 277 -1344 277 -248 279 -1362 275 -244 273 -236 261 -1380 275 -244 275 -1360 275 -246 275 -1358 275 -1346 277 -246 275 -236 263 -1384 275 -1342 277 -248 277 -1364 277 -244 273 -234 261 -1378 277 -246 273 -1356 277 -1340 277 -248 281 -1334 307 -246 271 -1356 275 -246 273 -1358 275 -244 273 -1326 309 -174 267 -10296 257 -2650 297 -232 263 -1384 277 -244 273 -1358 275 -1340 279 -248 279 -1328 309 -244 275 -1328 307 -244 273 -1356 275 -244 275 -1358 275 -246 273 -1324 309 -244 275 -1328 307 -244 273 -234 261 -1382 275 -246 273 -1326 309 -244 273 -1358 275 -246 273 -1358 275 -1338 279 -248 279 -1330 309 -244 273 -232 261 -1380 277 -1344 279 -248 279 -1330 309 -244 271 -234 261 -1382 275 -246 273 -1358 277 -244 275 -1330 309 -1338 277 -246 277 -236 263 -1380 277 -1342 277 -248 279 -1364 275 -246 273 -232 261 -1380 275 -248 275 -1328 307 -1338 277 -248 279 -1334 309 -244 271 -1358 275 -244 275 -1324 307 -246 271 -1328 309 -174 265 -10270 291 -2640 297 -232 297 -1350 277 -248 275 -1326 309 -1340 277 -248 277 -1328 309 -244 273 -1358 275 -246 273 -1326 309 -244 273 -1354 275 -246 273 -1330 307 -244 273 -1358 275 -246 273 -234 263 -1380 275 -246 273 -1358 275 -246 273 -1360 275 -244 273 -1358 275 -1340 277 -248 279 -1364 275 -244 273 -232 261 -1380 277 -1342 279 -250 279 -1332 307 -244 271 -234 261 -1378 277 -246 273 -1358 275 -248 275 -1360 275 -1340 277 -248 275 -236 263 -1382 277 -1344 277 -246 277 -1364 275 -246 273 -234 259 -1380 275 -246 273 -1362 275 -1342 275 -248 277 -1334 309 -244 271 -1356 275 -244 275 -1326 307 -244 273 -1356 275 -176 267 -10290 289 -2644 267 -238 301 -1320 309 -246 273 -1324 309 -1340 277 -248 277 -1328 307 -246 273 -1326 307 -246 273 -1324 309 -246 273 -1322 309 -246 273 -1322 307 -246 275 -1326 309 -246 273 -234 259 -1382 275 -246 275 -1322 309 -246 273 -1326 309 -246 273 -1326 309 -1340 277 -248 275 -1326 309 -246 273 -232 261 -1380 279 -1346 277 -250 277 -1328 309 -244 271 -232 261 -1380 277 -246 273 -1358 275 -248 273 -1328 307 -1340 277 -248 277 -236 261 -1380 277 -1344 277 -248 279 -1328 309 -244 275 -232 261 -1378 277 -248 273 -1326 309 -1344 277 -248 277 -1358 277 -246 273 -1328 307 -244 271 -1324 309 -244
RAW_Data: 273 -1324 309 -174 267 -10270 289 -2638 297 -234 297 -1352 275 -248 275 -1328 307 -1340 277 -248 275 -1330 309 -244 273 -1358 275 -244 275 -1326 309 -244 271 -1356 275 -244 275 -1326 307 -246 273 -1326 309 -244 273 -234 261 -1378 275 -248 275 -1326 309 -244 271 -1356 277 -248 273 -1328 309 -1338 277 -248 277 -1328 309 -244 271 -232 261 -1380 277 -1348 279 -248 277 -1328 307 -246 271 -234 259 -1384 275 -244 275 -1356 277 -246 275 -1326 309 -1344 275 -248 275 -236 261 -1378 277 -1342 277 -250 279 -1334 309 -244 271 -232 261 -1380 277 -246 273 -1326 307 -1344 277 -248 277 -1328 309 -246 273 -1326 309 -244 271 -1324 309 -244 273 -1324 307 -176 267 -10288 287 -2618 299 -236 299 -1354 277 -244 273 -1326 307 -1340 279 -248 275 -1328 309 -244 275 -1326 309 -246 273 -1324 307 -246 273 -1322 309 -244 273 -1322 309 -244 275 -1328 309 -246 273 -232 261 -1380 277 -246 275 -1324 309 -244 273 -1356 277 -246 275 -1324 309 -1340 279 -246 277 -1328 309 -244 273 -232 261 -1382 277 -1344 279 -250 277 -1324 309 -246 273 -234 261 -1380 277 -246 273 -1358 277 -246 273 -1328 309 -1340 277 -248 275 -236 261 -1380 275 -1344 279 -248 279 -1360 277 -244 273 -234 261 -1380 277 -246 275 -1354 277 -1344 277 -248 277 -1328 311 -246 273 -1324 307 -244 273 -1324 309 -244 273 -1320 309 -176 269 -118210 761 -168 267 -66 563 -132 99 -132 3543 -66 5345 -100 4355 -66 4617 -68 20503 -166 2379 -132 293 -98 4117 -66 1151 -98 3353 -66 3485 -66 2491 -66 6133 -66 233 -68 16307 -68 16959 -98 357 -66 5419 -134 799 -100 327 -100 791 -66 2481 -66 963 -100 3481 -98 1679 -134 2473 -100 227 -68 3087 -66 11527 -130 4305 -98 435 -66 563 -100 2887 -100 267 -66 1787 -66 9655 -66 4793 -100 2119 -66 359 -98 1313 -132 3393 -234 995 -66 2681 -98 99 -130 1379 -100 3757 -100 21695 -132 5135 -100 693 -98 4631 -100 2325 -68 4937 -66 10409 -98 897 -100 1287 -66 2565 -66 3753 -66 4055 -66 2023 -68 1961 -68 629 -66 431 -66 5039 -66 2155 -100 2673 -66 1163 -98 6539 -100 825 -66 1197 -100 3053 -66 13973 -68 15515 -100 1861 -66 1027 -66 797 -98 959 -98 787 -132 787 -64 3811 -132 1747 -66 6683 -66 1033 -68 24927 -66 1259 -100 1125 -68 663 -66 1687 -66 4357 -132 4567 -66 3969 -98 3317 -132 433 -134 6043 -66 3249 -100 431 -98 2367 -100 11265 -66 5085 -68 2355 -64 1815 -66 1395 -274 241 -1366 275 -244 275 -1362 275 -1338 277 -284 243 -1368 239 -278 275 -1362 275 -244 275 -1360 241 -278 273 -1356 275 -246 275 -1360 239 -280 275 -1360
RAW_Data: 275 -244 275 -234 263 -1386 239 -280 273 -1356 275 -244 273 -1360 275 -244 277 -1364 275 -1336 277 -248 277 -1366 275 -244 273 -234 263 -1386 275 -1340 277 -248 279 -1364 275 -244 275 -234 263 -1384 273 -244 275 -1358 275 -244 275 -1364 275 -1342 275 -248 277 -236 265 -1384 275 -1340 277 -282 243 -1366 275 -246 273 -236 263 -1382 277 -244 275 -1358 275 -1342 277 -248 277 -1364 275 -246 275 -1360 239 -280 273 -1358 241 -278 275 -1356 275 -210 233 -10302 257 -2652 297 -232 297 -1354 277 -244 275 -1358 275 -1340 279 -248 279 -1360 275 -246 275 -1360 275 -246 273 -1360 275 -244 275 -1328 309 -242 273 -1324 309 -244 275 -1360 275 -246 273 -234 261 -1384 275 -246 273 -1358 275 -244 275 -1358 277 -248 273 -1358 275 -1340 279 -248 277 -1334 307 -242 273 -232 261 -1380 277 -1348 277 -250 277 -1364 275 -244 275 -234 261 -1380 277 -244 275 -1358 277 -246 277 -1360 277 -1342 275 -248 275 -236 263 -1380 277 -1344 277 -248 279 -1368 275 -244 275 -232 261 -1382 277 -244 275 -1356 275 -1344 277 -248 279 -1362 275 -246 275 -1360 275 -246 273 -1356 275 -246 273 -1356 275 -176 267 -10302 257 -2648 299 -234 297 -1352 277 -246 275 -1326 309 -1340 279 -248 277 -1330 309 -244 275 -1328 309 -244 273 -1324 309 -244 275 -1324 309 -246 273 -1324 307 -246 275 -1328 309 -244 273 -234 261 -1378 277 -248 275 -1328 309 -244 273 -1356 277 -248 275 -1326 309 -1344 277 -248 275 -1326 309 -246 273 -234 259 -1380 277 -1348 281 -248 279 -1328 307 -246 273 -234 259 -1382 277 -246 275 -1360 275 -248 275 -1324 309 -1340 279 -248 277 -238 261 -1382 277 -1344 277 -248 279 -1330 311 -244 273 -234 259 -1378 277 -248 275 -1326 309 -1340 279 -248 279 -1336 307 -246 271 -1324 309 -244 275 -1324 307 -246 273 -1326 309 -174 269 -10296 257 -2648 299 -234 297 -1352 277 -248 273 -1326 309 -1342 277 -248 277 -1328 309 -246 275 -1328 309 -244 273 -1326 309 -244 273 -1322 309 -244 273 -1328 307 -244 275 -1328 309 -246 273 -234 261 -1382 277 -246 275 -1326 309 -244 273 -1352 277 -248 275 -1330 309 -1340 277 -248 277 -1328 309 -244 275 -232 261 -1384 277 -1342 279 -250 279 -1328 309 -244 273 -234 263 -1380 277 -246 273 -1360 277 -246 275 -1326 309 -1340 277 -250 277 -236 263 -1382 277 -1342 277 -248 279 -1362 277 -246 273 -234 263 -1382 277 -244 275 -1356 277 -1340 279 -248 279 -1362 275 -246 275 -1328 307 -246 273 -1356 275 -246 273 -1356 275 -174 269 -10292 287 -2650 269 -236 301 -1354 275 -248 273 -1358 275 -1340 279 -248 277 -1332 307 -246 275 -1328
RAW_Data: 309 -244 273 -1324 309 -244 273 -1356 275 -246 273 -1358 275 -244 277 -1330 309 -244 273 -234 261 -1382 277 -244 275 -1358 275 -246 273 -1356 277 -248 275 -1360 275 -1340 277 -248 277 -1360 275 -246 273 -236 261 -1382 279 -1344 279 -248 279 -1360 277 -244 273 -234 261 -1380 277 -246 275 -1360 277 -246 273 -1360 275 -1342 279 -248 275 -236 263 -1382 275 -1344 279 -248 279 -1362 277 -246 273 -234 263 -1380 277 -246 275 -1356 275 -1342 277 -248 281 -1336 307 -246 271 -1354 277 -246 275 -1328 307 -244 273 -1352 277 -176 269 -10300 257 -2650 299 -232 297 -1354 277 -246 275 -1356 277 -1342 277 -248 279 -1328 309 -244 275 -1360 275 -246 273 -1328 307 -246 273 -1356 277 -246 277 -1326 309 -244 277 -1360 277 -246 273 -234 263 -1384 277 -246 275 -1324 309 -246 275 -1358 277 -246 277 -1360 277 -1344 277 -248 277 -1326 309 -246 273 -236 261 -1382 277 -1348 279 -250 281 -1330 307 -246 273 -234 263 -1386 277 -244 275 -1356 277 -248 277 -1362 277 -1342 277 -250 277 -238 263 -1384 277 -1342 277 -250 281 -1332 309 -246 273 -234 263 -1380 277 -246 275 -1360 277 -1342 279 -248 281 -1334 307 -246 273 -1356 275 -248 275 -1328 309 -244 275 -1324 309 -176 269 -115034 163 -362 67 -894 529 -166 14663 -98 4135 -66 3681 -100 299 -68 9829 -66 3517 -64 21569 -66 3251 -66 2209 -64 23701 -66 3359 -68 1057 -66 723 -66 299 -134 765 -66 589 -98 1687 -134 2153 -66 3081 -68 10447 -66 11643 -66 2451 -66 2277 -66 2897 -66 755 -100 5539 -64 5117 -132 4867 -134 3931 -64 625 -66 1317 -98 11597 -66 2255 -66 1165 -66 1123 -66 6371 -100 699 -68 1811 -66 621 -68 2191 -64 1291 -134 3003 -66 2423 -64 1463 -66 663 -100 1127 -100 6169 -100 489 -100 6087 -100 2027 -66 1195 -66 13195 -66 557 -66 40423 -98 1919 -100 1061 -132 201 -66 2553 -132 12549 -66 1789 -100 921 -134 1067 -66 729 -66 10029 -66 3909 -100 265 -100 16017 -134 21177 -68 2461 -66 2215 -68 1197 -66 5911 -66 2645 -66 3419 -132 16275 -64 5091 -68 2123 -66 2677 -64 10305 -66 12381 -100 427 -166 25331 -66 2457 -66 11859 -248 279 -1368 275 -246 275 -1360 275 -1340 277 -246 279 -1364 239 -278 275 -1358 275 -244 275 -1362 239 -278 273 -1358 239 -280 271 -1360 241 -278 273 -1360 275 -244 275 -234 261 -1384 239 -280 273 -1356 275 -244 273 -1360 275 -244 275 -1358 275 -1344 277 -248 275 -1358 275 -244 273 -236 261 -1384 275 -1342 279 -246 279 -1360 275 -244 275 -234 263 -1384 239 -278 273 -1358 275 -244 275 -1362 275 -1342 275 -248 275 -238 263 -1382 275 -1344 275 -248
RAW_Data: 277 -1364 275 -244 273 -234 263 -1380 275 -246 273 -1358 275 -1342 277 -246 279 -1366 275 -244 273 -1362 239 -278 239 -1386 275 -246 273 -1360 241 -208 269 -10290 257 -2686 265 -232 265 -1384 275 -246 275 -1358 275 -1344 277 -248 275 -1358 275 -246 275 -1360 277 -244 273 -1326 309 -244 271 -1354 275 -244 275 -1358 275 -246 273 -1358 275 -246 273 -234 263 -1378 275 -246 275 -1360 275 -244 273 -1356 275 -246 275 -1360 275 -1342 277 -246 277 -1360 275 -246 273 -232 261 -1382 277 -1342 279 -248 279 -1360 275 -244 275 -232 261 -1380 277 -244 275 -1356 277 -246 277 -1360 275 -1342 277 -246 275 -236 263 -1384 275 -1342 277 -248 277 -1362 275 -246 273 -234 261 -1378 277 -246 275 -1328 307 -1340 277 -246 279 -1366 275 -244 273 -1326 307 -244 273 -1324 309 -244 273 -1356 275 -174 267 -10304 255 -2648 297 -230 263 -1382 277 -244 275 -1330 307 -1338 277 -248 277 -1330 309 -244 273 -1356 275 -246 273 -1362 275 -244 273 -1356 275 -244 273 -1326 307 -244 273 -1360 273 -246 273 -236 261 -1380 275 -244 275 -1328 307 -244 273 -1358 275 -244 275 -1360 275 -1342 277 -246 277 -1364 275 -244 271 -232 261 -1384 277 -1340 279 -248 279 -1360 275 -246 273 -234 261 -1380 275 -244 275 -1360 277 -244 275 -1356 275 -1342 279 -246 277 -236 263 -1382 275 -1340 277 -248 279 -1366 275 -246 271 -234 261 -1382 277 -244 275 -1354 275 -1342 277 -248 277 -1364 273 -246 273 -1362 275 -244 271 -1360 275 -244 273 -1358 275 -174 267 -10272 289 -2646 265 -262 261 -1382 277 -244 275 -1356 275 -1342 277 -248 277 -1364 275 -244 275 -1360 275 -244 273 -1358 275 -244 273 -1358 275 -244 273 -1326 307 -244 275 -1358 275 -246 273 -234 261 -1382 275 -246 273 -1358 275 -244 273 -1358 275 -246 275 -1360 275 -1338 277 -248 277 -1362 277 -244 271 -234 261 -1380 277 -1344 279 -248 277 -1332 273 -278 271 -234 261 -1382 275 -244 275 -1356 277 -246 275 -1360 277 -1340 277 -246 277 -234 263 -1384 275 -1342 277 -248 277 -1366 275 -244 273 -234 261 -1380 275 -246 273 -1360 275 -1340 277 -246 279 -1334 307 -244 273 -1356 275 -246 273 -1360 275 -244 271 -1354 277 -174 269 -10300 257 -2648 297 -230 263 -1384 277 -244 273 -1356 277 -1342 277 -248 277 -1362 275 -244 275 -1330 307 -244 273 -1324 309 -244 273 -1324 307 -246 273 -1326 307 -244 273 -1358 275 -246 273 -234 261 -1380 277 -246 273 -1358 275 -244 275 -1354 277 -248 275 -1360 275 -1338 279 -246 277 -1360 275 -244 273 -234 261 -1378 279 -1344 279 -248 279 -1330 309 -244 271 -232 261 -1380 277 -246 273 -1360
RAW_Data: 277 -244 275 -1360 275 -1340 277 -246 277 -236 261 -1380 275 -1346 277 -248 277 -1362 275 -246 273 -234 263 -1380 275 -244 275 -1358 275 -1340 277 -248 279 -1334 309 -244 273 -1324 307 -246 273 -1356 275 -244 273 -1356 275 -174 269 -10302 257 -2644 297 -232 263 -1384 277 -246 275 -1354 275 -1344 277 -248 275 -1360 275 -246 275 -1358 275 -246 273 -1326 307 -246 273 -1324 307 -244 273 -1328 307 -244 273 -1358 275 -244 273 -236 261 -1380 275 -246 273 -1358 275 -244 273 -1358 275 -246 273 -1360 275 -1344 275 -248 275 -1360 275 -244 273 -234 261 -1378 277 -1344 279 -248 277 -1362 275 -246 273 -234 261 -1378 275 -244 275 -1360 275 -246 275 -1358 275 -1344 277 -246 277 -234 263 -1380 275 -1338 279 -246 281 -1368 275 -244 271 -234 261 -1386 275 -244 271 -1358 275 -1342 277 -246 279 -1362 275 -244 275 -1326 273 -278 273 -1358 239 -278 273 -1358 275 -174 267 -127478 195 -964 2317 -66 763 -98 1455 -100 16109 -66 5683 -98 11469 -66 34413 -66 5443 -66 11613 -66 2737 -66 12191 -66 2951 -68 1851 -68 1895 -68 2643
RAW_Data: 29262 361 -68 2635 -66 24113 -66 1131 -100 4157 -66 26253 -130 621 -18438 99 -298 231 -66 197 -496 753 -230 7503 -16526 65 -396 65 -296 99 -196 293 -64 429 -132 397 -66 329 -66 37701 -66 13475 -100 54967 -64 18209 -18340 97 -462 197 -98 587 -232 97 -100 259 -98 197 -262 297 -64 557 -100 599 -100 333 -234 42493 -13212 6449 -206 173 -214 217 -176 195 -218 181 -218 181 -182 217 -182 217 -176 187 -214 215 -180 217 -182 217 -182 217 -178 185 -424 1177 -388 387 -240 381 -214 181 -398 211 -380 419 -176 217 -394 203 -394 205 -380 189 -402 421 -168 219 -398 393 -190 191 -398 205 -406 185 -402 381 -212 215 -362 241 -378 421 -176 377 -218 197 -378 427 -210 393 -172 429 -172 397 -212 217 -362 389 -228 197 -372 417 -204 395 -210 181 -398 391 -192 201 -216888 761 -200 299 -166 695 -132 15435 -66 5611 -66 21049 -66 4947 -66 2355 -66 1921 -100 2223 -100 2107 -100 397 -98 3643 -66 5301 -98 14205 -66 37371 -246 175 -216 179 -216 177 -224 149 -246 159 -228 181 -212 201 -204 159 -244 151 -254 169 -214 181 -210 197 -182 181 -454 1141 -444 357 -228 361 -246 177 -396 209 -412 367 -188 187 -434 201 -394 185 -406 193 -402 377 -238 181 -386 381 -234 153 -424 205 -412 157 -412 383 -240 181 -398 203 -392 385 -236 371 -212 179 -400 383 -240 359 -210 375 -220 381 -246 175 -394 383 -240 181 -398 363 -222 379 -246 175 -394 383 -204 217 -182856 99 -66 99 -300 133 -402 65 -198 99 -328 65 -100 491 -164 593 -100 3547 -64 361 -66 789 -68 2521 -66 22883 -66 2659 -98 3309 -130 3789 -100 9689 -17178 99 -1388 65 -266 197 -100 131 -134 99 -232 627 -130 233 -66 1949 -100 14567 -198 165 -256 181 -208 159 -214 183 -220 163 -244 149 -246 159 -236 181 -254 141 -226 151 -246 157 -228 181 -212 201 -400 1163 -428 379 -230 355 -244 177 -396 207 -412 367 -222 157 -418 189 -410 207 -412 171 -430 357 -226 165 -404 413 -204 181 -428 173 -428 169 -426 353 -236 173 -414 173 -408 381 -244 337 -222 201 -408 397 -208 393 -204 395 -208 359 -246 177 -394 387 -200 205 -380 415 -202 395 -208 181 -432 357 -226 169 -195084 65 -300 763 -66 297 -364 593 -68 2883 -66 1357 -68 363 -98 3841 -66 3119 -66 5153 -66 4023 -268 143 -246 133 -290 141 -250 139 -254 141 -226 181 -248 137 -254 143 -252 139 -252 143 -230 181 -250 139 -254 145 -436 1135 -448 349 -240 347 -254 157 -434 167 -426 377 -226 157 -434 167 -426 155 -440 163 -434 375 -206 215 -380 381 -234 153
RAW_Data: -424 205 -412 159 -412 381 -240 181 -398 203 -392 387 -236 369 -212 179 -400 383 -240 359 -244 339 -222 381 -246 175 -394 383 -240 181 -398 363 -222 381 -244 175 -392 383 -240 181 -184002 99 -360 63 -330 65 -132 129 -232 97 -198 295 -328 6031 -66 831 -132 3417 -66 2187 -64 2183 -100 6535 -66 1127 -66 2569 -66 2031 -66 2271 -66 2183 -66 3815 -66 3803 -66 493 -66 1909 -66 1627 -98 4805 -17512 67 -2164 131 -498 265 -430 163 -98 97 -64 99 -230 99 -100 229 -230 165 -196 63 -132 99 -66 927 -66 14955 -66 19621 -68 2627 -66 14305 -68 23247 -66 2891 -66 3941 -66 3021 -212 173 -242 181 -218 181 -214 181 -208 157 -250 141 -248 181 -218 179 -214 179 -210 159 -250 179 -214 181 -218 181 -404 1153 -404 389 -244 375 -192 181 -436 161 -414 383 -240 181 -398 205 -392 201 -394 205 -394 365 -246 177 -396 383 -204 217 -398 171 -426 167 -428 353 -242 173 -420 173 -408 373 -220 403 -208 175 -422 381 -194 399 -228 357 -246 355 -210 215 -400 387 -208 181 -398 391 -226 353 -246 177 -398 383 -204 217 -185098 163 -166 525 -98 293 -100 63 -66 229 -66 1183 -66 1507 -66 3089 -98 30187 -66 2847 -19112 133 -364 131 -394 97 -166 295 -66 229 -164 227 -66 263 -130 623 -98 2071 -66 493 -66 787 -98 691 -64 10249 -132 3879 -66 1949 -66 3453 -198 23157 -66 2845 -100 1193 -66 1587 -100 3797 -98 3187 -100 3319 -66 22119 -98 5513 -226 155 -244 153 -256 131 -248 151 -246 159 -262 121 -274 133 -272 127 -244 153 -254 167 -248 145 -244 133 -252 177 -398 1169 -418 381 -238 359 -242 141 -430 169 -426 357 -274 139 -422 171 -442 173 -428 167 -426 353 -236 171 -416 379 -226 149 -436 161 -438 173 -406 381 -234 153 -424 205 -380 389 -244 359 -206 215 -384 381 -246 335 -224 383 -246 355 -244 179 -404 385 -206 181 -432 359 -226 355 -246 175 -398 383 -240 181 -179760 97 -168 727 -66 97 -332 1389 -66 2793 -66 4955 -100 12453 -100 2425 -66 21965 -66 3809 -68 1683 -66 3095 -66 2153 -64 999 -208 173 -220 181 -214 191 -196 181 -212 183 -220 191 -212 181 -214 191 -198 181 -212 181 -222 191 -212 181 -214 191 -416 1167 -424 369 -220 373 -210 209 -390 207 -376 403 -190 187 -418 189 -408 209 -412 173 -428 357 -226 169 -404 399 -208 179 -412 209 -396 169 -428 355 -230 201 -378 205 -406 381 -244 339 -222 193 -400 413 -204 393 -208 347 -220 401 -210 175 -422 383 -202 217 -398 365 -222 377 -246 175 -390 385 -204 217 -179890 165 -1552 131 -164 65
RAW_Data: -1448 361 -17056 131 -134 233 -1462 131 -166 953 -100 261 -164 5077 -272 137 -268 143 -252 141 -248 143 -246 159 -252 141 -244 143 -290 107 -276 145 -244 131 -250 179 -248 143 -252 141 -414 1165 -424 373 -236 359 -242 145 -434 169 -428 355 -230 169 -442 173 -434 157 -406 193 -402 379 -238 181 -422 335 -252 157 -434 167 -428 185 -406 381 -208 211 -390 207 -410 381 -200 373 -236 171 -414 383 -202 393 -210 379 -220 373 -208 211 -390 383 -204 217 -398 365 -220 379 -244 175 -394 381 -240 181 -161030 97 -166 167 -930 593 -2670 1091 -132 229 -98 461 -164 1649 -66 6311 -100 44723 -16832 67 -2656 131 -132 99 -132 263 -100 399 -68 893 -18950 99 -164 165 -198 525 -998 335 -66 565 -66 1057 -17880 97 -360 195 -262 131 -332 625 -98 197 -230 455 -98 9343 -16498 67 -368 131 -598 65 -1066 333 -300 789 -130 757 -66 87207 -16554 97 -3520 97 -786 591 -64 461 -98 21495 -66 24811 -18448 131 -296 491 -134 163 -760 1091 -230 893 -66 927 -68 4581 -68 32965 -64 45217 -17292 131 -1684 231 -132 327 -64 163 -330 263 -230 25751

View file

@ -244,6 +244,8 @@ if should_gen_cdb_and_link_dir(fwenv, BUILD_TARGETS):
# without filtering, both updater & firmware commands would be generated
fwenv.Replace(COMPILATIONDB_PATH_FILTER=fwenv.subst("*${FW_FLAVOR}*"))
AlwaysBuild(fwcdb)
Precious(fwcdb)
NoClean(fwcdb)
Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_cdb", fwcdb)
fw_artifacts.append(fwcdb)

View file

@ -3,6 +3,11 @@ Import("env")
env.Append(LINT_SOURCES=["firmware"])
libenv = env.Clone(FW_LIB_NAME="flipper${TARGET_HW}")
libenv.Append(
CPPPATH=[
"#/lib/STM32CubeWB/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl",
]
)
libenv.ApplyLibFlags()

View file

@ -16,36 +16,6 @@
/* bit value */
#define _BV(bit) (0x01 << (bit))
#if defined(STM32F0)
#include "STM32F0xx/Include/stm32f0xx.h"
#elif defined(STM32F1)
#include "STM32F1xx/Include/stm32f1xx.h"
#elif defined(STM32F2)
#include "STM32F2xx/Include/stm32f2xx.h"
#elif defined(STM32F3)
#include "STM32F3xx/Include/stm32f3xx.h"
#elif defined(STM32F4)
#include "STM32F4xx/Include/stm32f4xx.h"
#elif defined(STM32F7)
#include "STM32F7xx/Include/stm32f7xx.h"
#elif defined(STM32H7)
#include "STM32H7xx/Include/stm32h7xx.h"
#elif defined(STM32L0)
#include "STM32L0xx/Include/stm32l0xx.h"
#elif defined(STM32L1)
#include "STM32L1xx/Include/stm32l1xx.h"
#elif defined(STM32L4)
#include "STM32L4xx/Include/stm32l4xx.h"
#elif defined(STM32L5)
#include "STM32L5xx/Include/stm32l5xx.h"
#elif defined(STM32G0)
#include "STM32G0xx/Include/stm32g0xx.h"
#elif defined(STM32G4)
#include "STM32G4xx/Include/stm32g4xx.h"
#elif defined(STM32WB)
#include "STM32WBxx/Include/stm32wbxx.h"
#else
#error "STM32 family not defined"
#endif
#include "stm32wbxx.h"
#endif // _STM32_H_

View file

@ -1,9 +1,10 @@
#pragma once
#include "hw.h"
#include "hw_conf.h"
#include "hw_if.h"
#include "ble_bufsize.h"
#include <interface/patterns/ble_thread/hw.h>
#include <ble/core/ble_bufsize.h>
#define CFG_TX_POWER (0x19) /* +0dBm */

View file

@ -1,10 +1,11 @@
#include "utilities_common.h"
#include "app_common.h"
#include "app_debug.h"
#include "shci.h"
#include "tl.h"
#include "dbg_trace.h"
#include <interface/patterns/ble_thread/tl/tl.h>
#include <interface/patterns/ble_thread/tl/mbox_def.h>
#include <interface/patterns/ble_thread/shci/shci.h>
#include <utilities/dbg_trace.h>
#include <utilities/utilities_common.h>
#include <furi_hal.h>
typedef PACKED_STRUCT {

View file

@ -1,6 +1,6 @@
#include "battery_service.h"
#include "app_common.h"
#include "ble.h"
#include <ble/ble.h>
#include <furi.h>
#include <furi_hal_power.h>

View file

@ -1,8 +1,8 @@
#include "ble_app.h"
#include "hci_tl.h"
#include "ble.h"
#include "shci.h"
#include <ble/ble.h>
#include <interface/patterns/ble_thread/tl/hci_tl.h>
#include <interface/patterns/ble_thread/shci/shci.h>
#include "gap.h"
#include <furi_hal.h>

View file

@ -0,0 +1,115 @@
/*****************************************************************************
* @file ble_const.h
* @author MDG
* @brief This file contains the definitions which are compiler dependent.
*****************************************************************************
* @attention
*
* Copyright (c) 2018-2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
*****************************************************************************
*/
#ifndef BLE_CONST_H__
#define BLE_CONST_H__
#include <stdint.h>
#include <string.h>
#include <ble/core/ble_std.h>
#include <ble/core/ble_defs.h>
#include "osal.h"
/* Default BLE variant */
#ifndef BASIC_FEATURES
#define BASIC_FEATURES 0
#endif
#ifndef SLAVE_ONLY
#define SLAVE_ONLY 0
#endif
#ifndef LL_ONLY
#define LL_ONLY 0
#endif
#ifndef BEACON_ONLY
#define BEACON_ONLY 0
#endif
/* Size of command/events buffers:
*
* To change the size of commands and events parameters used in the
* auto-generated files, you need to update 2 defines:
*
* - BLE_CMD_MAX_PARAM_LEN
* - BLE_EVT_MAX_PARAM_LEN
*
* These 2 defines are set below with default values and can be changed.
*
* To compute the value to support a characteristic of 512 bytes for a specific
* command or an event, you need to look in "ble_types.h".
*
* Here are 2 examples, one with a command and one with an event:
*
* - aci_gatt_update_char_value_ext_cp0
* ----------------------------------
*
* we have in the structure:
*
* uint8_t Value[(BLE_CMD_MAX_PARAM_LEN- 12)/sizeof(uint8_t)];
*
* so to support a 512 byte value, we need to have
*
* BLE_CMD_MAX_PARAM_LEN at least equal to: 512 + 12 = 524
*
* - aci_gatt_read_handle_value_rp0
* ------------------------------
*
* we have in the structure:
*
* uint8_t Value[((BLE_EVT_MAX_PARAM_LEN - 3) - 5)/sizeof(uint8_t)];
*
* so to support a 512 byte value, we need to have
*
* BLE_EVT_MAX_PARAM_LEN at least equal to: 512 + 3 + 5 = 520
*
* If you need several events or commands with 512-size values, you need to
* take the maximum values for BLE_EVT_MAX_PARAM_LEN and BLE_CMD_MAX_PARAM_LEN.
*
*/
/* Maximum parameter size of BLE commands.
* Change this value if needed. */
#define BLE_CMD_MAX_PARAM_LEN HCI_COMMAND_MAX_PARAM_LEN
/* Maximum parameter size of BLE responses/events.
* Change this value if needed. */
#define BLE_EVT_MAX_PARAM_LEN HCI_EVENT_MAX_PARAM_LEN
/* Callback function to send command and receive response */
struct hci_request {
uint16_t ogf;
uint16_t ocf;
int event;
void* cparam;
int clen;
void* rparam;
int rlen;
};
extern int hci_send_req(struct hci_request* req, uint8_t async);
#ifndef FALSE
#define FALSE 0
#endif
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
#endif /* BLE_CONST_H__ */

View file

@ -1,14 +1,14 @@
#include "ble_glue.h"
#include "app_common.h"
#include "ble_app.h"
#include "ble.h"
#include "tl.h"
#include "shci.h"
#include "shci_tl.h"
#include <ble/ble.h>
#include <interface/patterns/ble_thread/tl/tl.h>
#include <interface/patterns/ble_thread/shci/shci.h>
#include <interface/patterns/ble_thread/tl/shci_tl.h>
#include "app_debug.h"
#include <furi_hal.h>
#include <shci/shci.h>
#define TAG "Core2"

View file

@ -0,0 +1,150 @@
/*****************************************************************************
* @file compiler.h
* @author MDG
* @brief This file contains the definitions which are compiler dependent.
*****************************************************************************
* @attention
*
* Copyright (c) 2018-2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
*****************************************************************************
*/
#ifndef COMPILER_H__
#define COMPILER_H__
/**
* @brief This is the section dedicated to IAR toolchain
*/
#if defined(__ICCARM__) || defined(__IAR_SYSTEMS_ASM__)
#ifndef __WEAK
#define __WEAK __weak
#endif
#define QUOTE_(a) #a
/**
* @brief PACKED
* Use the PACKED macro for variables that needs to be packed.
* Usage: PACKED(struct) myStruct_s
* PACKED(union) myStruct_s
*/
#define PACKED(decl) __packed decl
/**
* @brief SECTION
* Use the SECTION macro to assign data or code in a specific section.
* Usage: SECTION(".my_section")
*/
#define SECTION(name) _Pragma(QUOTE_(location = name))
/**
* @brief ALIGN_DEF
* Use the ALIGN_DEF macro to specify the alignment of a variable.
* Usage: ALIGN_DEF(4)
*/
#define ALIGN_DEF(v) _Pragma(QUOTE_(data_alignment = v))
/**
* @brief NO_INIT
* Use the NO_INIT macro to declare a not initialized variable.
* Usage: NO_INIT(int my_no_init_var)
* Usage: NO_INIT(uint16_t my_no_init_array[10])
*/
#define NO_INIT(var) __no_init var
/**
* @brief This is the section dedicated to GNU toolchain
*/
#else
#ifdef __GNUC__
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif
/**
* @brief PACKED
* Use the PACKED macro for variables that needs to be packed.
* Usage: PACKED(struct) myStruct_s
* PACKED(union) myStruct_s
*/
#define PACKED(decl) decl __attribute__((packed))
/**
* @brief SECTION
* Use the SECTION macro to assign data or code in a specific section.
* Usage: SECTION(".my_section")
*/
#define SECTION(name) __attribute__((section(name)))
/**
* @brief ALIGN_DEF
* Use the ALIGN_DEF macro to specify the alignment of a variable.
* Usage: ALIGN_DEF(4)
*/
#define ALIGN_DEF(N) __attribute__((aligned(N)))
/**
* @brief NO_INIT
* Use the NO_INIT macro to declare a not initialized variable.
* Usage: NO_INIT(int my_no_init_var)
* Usage: NO_INIT(uint16_t my_no_init_array[10])
*/
#define NO_INIT(var) var __attribute__((section(".noinit")))
/**
* @brief This is the section dedicated to Keil toolchain
*/
#else
#ifdef __CC_ARM
#ifndef __WEAK
#define __WEAK __weak
#endif
/**
* @brief PACKED
* Use the PACKED macro for variables that needs to be packed.
* Usage: PACKED(struct) myStruct_s
* PACKED(union) myStruct_s
*/
#define PACKED(decl) decl __attribute__((packed))
/**
* @brief SECTION
* Use the SECTION macro to assign data or code in a specific section.
* Usage: SECTION(".my_section")
*/
#define SECTION(name) __attribute__((section(name)))
/**
* @brief ALIGN_DEF
* Use the ALIGN_DEF macro to specify the alignment of a variable.
* Usage: ALIGN_DEF(4)
*/
#define ALIGN_DEF(N) __attribute__((aligned(N)))
/**
* @brief NO_INIT
* Use the NO_INIT macro to declare a not initialized variable.
* Usage: NO_INIT(int my_no_init_var)
* Usage: NO_INIT(uint16_t my_no_init_array[10])
*/
#define NO_INIT(var) var __attribute__((section("NoInit")))
#else
#error Neither ICCARM, CC ARM nor GNUC C detected. Define your macros.
#endif
#endif
#endif
#endif /* COMPILER_H__ */

View file

@ -1,6 +1,6 @@
#include "dev_info_service.h"
#include "app_common.h"
#include "ble.h"
#include <ble/ble.h>
#include <furi.h>
#include <m-string.h>

View file

@ -1,6 +1,6 @@
#include "gap.h"
#include "ble.h"
#include <ble/ble.h>
#include <furi_hal.h>
#include <furi.h>

View file

@ -1,6 +1,6 @@
#include "hid_service.h"
#include "app_common.h"
#include "ble.h"
#include <ble/ble.h>
#include <furi.h>

View file

@ -19,7 +19,7 @@
/* Includes ------------------------------------------------------------------*/
#include "app_common.h"
#include "mbox_def.h"
#include <interface/patterns/ble_thread/tl/mbox_def.h>
/* Global variables ---------------------------------------------------------*/
/* Private defines -----------------------------------------------------------*/

View file

@ -0,0 +1,63 @@
/*****************************************************************************
* @file osal.h
* @author MDG
* @brief This header file defines the OS abstraction layer used by
* the BLE stack. OSAL defines the set of functions which needs to be
* ported to target operating system and target platform.
* Actually, only memset, memcpy and memcmp wrappers are defined.
*****************************************************************************
* @attention
*
* Copyright (c) 2018-2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
*****************************************************************************
*/
#ifndef OSAL_H__
#define OSAL_H__
/**
* This function copies size number of bytes from a
* memory location pointed by src to a destination
* memory location pointed by dest
*
* @param[in] dest Destination address
* @param[in] src Source address
* @param[in] size size in the bytes
*
* @return Address of the destination
*/
extern void* Osal_MemCpy(void* dest, const void* src, unsigned int size);
/**
* This function sets first number of bytes, specified
* by size, to the destination memory pointed by ptr
* to the specified value
*
* @param[in] ptr Destination address
* @param[in] value Value to be set
* @param[in] size Size in the bytes
*
* @return Address of the destination
*/
extern void* Osal_MemSet(void* ptr, int value, unsigned int size);
/**
* This function compares n bytes of two regions of memory
*
* @param[in] s1 First buffer to compare.
* @param[in] s2 Second buffer to compare.
* @param[in] size Number of bytes to compare.
*
* @return 0 if the two buffers are equal, 1 otherwise
*/
extern int Osal_MemCmp(const void* s1, const void* s2, unsigned int size);
#endif /* OSAL_H__ */

View file

@ -1,6 +1,6 @@
#include "serial_service.h"
#include "app_common.h"
#include "ble.h"
#include <ble/ble.h>
#include <furi.h>

View file

@ -1,7 +1,8 @@
#include <furi_hal_bt.h>
#include <ble.h>
#include <ble/ble.h>
#include <interface/patterns/ble_thread/shci/shci.h>
#include <stm32wbxx.h>
#include <shci.h>
#include <furi_hal_version.h>
#include <furi_hal_bt_hid.h>

View file

@ -4,7 +4,7 @@
#include <stm32wbxx_ll_cortex.h>
#include <stm32wbxx_ll_bus.h>
#include <furi.h>
#include <shci.h>
#include <interface/patterns/ble_thread/shci/shci.h>
#define TAG "FuriHalCrypto"

View file

@ -1,8 +1,8 @@
#include <furi_hal_flash.h>
#include <furi_hal_bt.h>
#include <furi.h>
#include <ble.h>
#include <shci.h>
#include <ble/ble.h>
#include <interface/patterns/ble_thread/shci/shci.h>
#include <stm32wbxx.h>

View file

@ -4,7 +4,7 @@
#include <furi_hal_bt.h>
#include <furi_hal_crypto.h>
#include <shci.h>
#include <interface/patterns/ble_thread/shci/shci.h>
#include <m-string.h>
#include <protobuf_version.h>

View file

@ -6,7 +6,7 @@
#include <stm32wbxx_ll_rtc.h>
#include <stdio.h>
#include "ble.h"
#include <ble/ble.h>
#define TAG "FuriHalVersion"

View file

@ -1,5 +1,6 @@
#pragma once
#include "core_defines.h"
#include <stdbool.h>
#include <FreeRTOS.h>
#include <task.h>
@ -10,92 +11,6 @@ extern "C" {
#include <cmsis_compiler.h>
#ifndef MAX
#define MAX(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a > _b ? _a : _b; \
})
#endif
#ifndef MIN
#define MIN(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a < _b ? _a : _b; \
})
#endif
#ifndef ROUND_UP_TO
#define ROUND_UP_TO(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a / _b + !!(_a % _b); \
})
#endif
#ifndef CLAMP
#define CLAMP(x, upper, lower) (MIN(upper, MAX(x, lower)))
#endif
#ifndef COUNT_OF
#define COUNT_OF(x) (sizeof(x) / sizeof(x[0]))
#endif
#ifndef FURI_SWAP
#define FURI_SWAP(x, y) \
do { \
typeof(x) SWAP = x; \
x = y; \
y = SWAP; \
} while(0)
#endif
#ifndef PLACE_IN_SECTION
#define PLACE_IN_SECTION(x) __attribute__((section(x)))
#endif
#ifndef ALIGN
#define ALIGN(n) __attribute__((aligned(n)))
#endif
#ifndef __weak
#define __weak __attribute__((weak))
#endif
#ifndef UNUSED
#define UNUSED(X) (void)(X)
#endif
#ifndef STRINGIFY
#define STRINGIFY(x) #x
#endif
#ifndef TOSTRING
#define TOSTRING(x) STRINGIFY(x)
#endif
#ifndef REVERSE_BYTES_U32
#define REVERSE_BYTES_U32(x) \
((((x)&0x000000FF) << 24) | (((x)&0x0000FF00) << 8) | (((x)&0x00FF0000) >> 8) | \
(((x)&0xFF000000) >> 24))
#endif
#ifndef FURI_BIT
#define FURI_BIT(x, n) (((x) >> (n)) & 1)
#endif
#ifndef FURI_BIT_SET
#define FURI_BIT_SET(x, n) ((x) |= (1 << (n)))
#endif
#ifndef FURI_BIT_CLEAR
#define FURI_BIT_CLEAR(x, n) ((x) &= ~(1 << (n)))
#endif
#ifndef FURI_IS_IRQ_MASKED
#define FURI_IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
#endif

97
furi/core/core_defines.h Normal file
View file

@ -0,0 +1,97 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#define FURI_RETURNS_NONNULL __attribute__((returns_nonnull))
#ifndef MAX
#define MAX(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a > _b ? _a : _b; \
})
#endif
#ifndef MIN
#define MIN(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a < _b ? _a : _b; \
})
#endif
#ifndef ROUND_UP_TO
#define ROUND_UP_TO(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a / _b + !!(_a % _b); \
})
#endif
#ifndef CLAMP
#define CLAMP(x, upper, lower) (MIN(upper, MAX(x, lower)))
#endif
#ifndef COUNT_OF
#define COUNT_OF(x) (sizeof(x) / sizeof(x[0]))
#endif
#ifndef FURI_SWAP
#define FURI_SWAP(x, y) \
do { \
typeof(x) SWAP = x; \
x = y; \
y = SWAP; \
} while(0)
#endif
#ifndef PLACE_IN_SECTION
#define PLACE_IN_SECTION(x) __attribute__((section(x)))
#endif
#ifndef ALIGN
#define ALIGN(n) __attribute__((aligned(n)))
#endif
#ifndef __weak
#define __weak __attribute__((weak))
#endif
#ifndef UNUSED
#define UNUSED(X) (void)(X)
#endif
#ifndef STRINGIFY
#define STRINGIFY(x) #x
#endif
#ifndef TOSTRING
#define TOSTRING(x) STRINGIFY(x)
#endif
#ifndef REVERSE_BYTES_U32
#define REVERSE_BYTES_U32(x) \
((((x)&0x000000FF) << 24) | (((x)&0x0000FF00) << 8) | (((x)&0x00FF0000) >> 8) | \
(((x)&0xFF000000) >> 24))
#endif
#ifndef FURI_BIT
#define FURI_BIT(x, n) (((x) >> (n)) & 1)
#endif
#ifndef FURI_BIT_SET
#define FURI_BIT_SET(x, n) ((x) |= (1 << (n)))
#endif
#ifndef FURI_BIT_CLEAR
#define FURI_BIT_CLEAR(x, n) ((x) &= ~(1 << (n)))
#endif
#ifdef __cplusplus
}
#endif

View file

@ -6,6 +6,7 @@
#pragma once
#include <stdbool.h>
#include "core_defines.h"
#ifdef __cplusplus
extern "C" {
@ -51,7 +52,7 @@ bool furi_record_destroy(const char* name);
* @note Thread safe. Open and close must be executed from the same
* thread. Suspends caller thread till record is available
*/
void* furi_record_open(const char* name);
FURI_RETURNS_NONNULL void* furi_record_open(const char* name);
/** Close record
*

View file

@ -2,19 +2,10 @@ Import("env")
env.Append(
CPPPATH=[
"#/lib/STM32CubeWB/Drivers/CMSIS/Device/ST",
"#/lib/STM32CubeWB/Drivers/CMSIS/Device/ST/STM32WBxx/Include",
"#/lib/STM32CubeWB/Drivers/CMSIS/Include",
"#/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Inc",
"#/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Inc/Legacy",
"#/lib/STM32CubeWB/Middlewares/ST/STM32_WPAN",
"#/lib/STM32CubeWB/Middlewares/ST/STM32_WPAN/ble",
"#/lib/STM32CubeWB/Middlewares/ST/STM32_WPAN/ble/core",
"#/lib/STM32CubeWB/Middlewares/ST/STM32_WPAN/ble/core/template",
"#/lib/STM32CubeWB/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread",
"#/lib/STM32CubeWB/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/shci",
"#/lib/STM32CubeWB/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl",
"#/lib/STM32CubeWB/Middlewares/ST/STM32_WPAN/utilities",
],
CPPDEFINES=[
"STM32WB",
@ -33,6 +24,16 @@ if env["RAM_EXEC"]:
libenv = env.Clone(FW_LIB_NAME="stm32cubewb")
libenv.Append(
CPPPATH=[
"#/lib/STM32CubeWB/Middlewares/ST/STM32_WPAN/ble",
"#/lib/STM32CubeWB/Middlewares/ST/STM32_WPAN/ble/core",
"#/lib/STM32CubeWB/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread",
"#/lib/STM32CubeWB/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/shci",
"#/lib/STM32CubeWB/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl",
"#/lib/STM32CubeWB/Middlewares/ST/STM32_WPAN/utilities",
]
)
libenv.ApplyLibFlags()
sources = libenv.GlobRecursive(

View file

@ -545,6 +545,16 @@ void nfc_worker_mf_ultralight_read_auth(NfcWorker* nfc_worker) {
}
data->auth_success = mf_ultralight_authenticate(&tx_rx, key, &pack);
if(!data->auth_success) {
// Reset card
furi_hal_nfc_sleep();
if(!furi_hal_nfc_activate_nfca(300, NULL)) {
nfc_worker->callback(NfcWorkerEventFail, nfc_worker->context);
break;
}
}
mf_ul_read_card(&tx_rx, &reader, data);
if(data->auth_success) {
MfUltralightConfigPages* config_pages = mf_ultralight_get_config_pages(data);

View file

@ -0,0 +1,444 @@
#include "magellen.h"
#include "../blocks/const.h"
#include "../blocks/decoder.h"
#include "../blocks/encoder.h"
#include "../blocks/generic.h"
#include "../blocks/math.h"
#define TAG "SubGhzProtocolMagellen"
static const SubGhzBlockConst subghz_protocol_magellen_const = {
.te_short = 200,
.te_long = 400,
.te_delta = 100,
.min_count_bit_for_found = 32,
};
struct SubGhzProtocolDecoderMagellen {
SubGhzProtocolDecoderBase base;
SubGhzBlockDecoder decoder;
SubGhzBlockGeneric generic;
uint16_t header_count;
};
struct SubGhzProtocolEncoderMagellen {
SubGhzProtocolEncoderBase base;
SubGhzProtocolBlockEncoder encoder;
SubGhzBlockGeneric generic;
};
typedef enum {
MagellenDecoderStepReset = 0,
MagellenDecoderStepCheckPreambula,
MagellenDecoderStepFoundPreambula,
MagellenDecoderStepSaveDuration,
MagellenDecoderStepCheckDuration,
} MagellenDecoderStep;
const SubGhzProtocolDecoder subghz_protocol_magellen_decoder = {
.alloc = subghz_protocol_decoder_magellen_alloc,
.free = subghz_protocol_decoder_magellen_free,
.feed = subghz_protocol_decoder_magellen_feed,
.reset = subghz_protocol_decoder_magellen_reset,
.get_hash_data = subghz_protocol_decoder_magellen_get_hash_data,
.serialize = subghz_protocol_decoder_magellen_serialize,
.deserialize = subghz_protocol_decoder_magellen_deserialize,
.get_string = subghz_protocol_decoder_magellen_get_string,
};
const SubGhzProtocolEncoder subghz_protocol_magellen_encoder = {
.alloc = subghz_protocol_encoder_magellen_alloc,
.free = subghz_protocol_encoder_magellen_free,
.deserialize = subghz_protocol_encoder_magellen_deserialize,
.stop = subghz_protocol_encoder_magellen_stop,
.yield = subghz_protocol_encoder_magellen_yield,
};
const SubGhzProtocol subghz_protocol_magellen = {
.name = SUBGHZ_PROTOCOL_MAGELLEN_NAME,
.type = SubGhzProtocolTypeStatic,
.flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable |
SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send,
.decoder = &subghz_protocol_magellen_decoder,
.encoder = &subghz_protocol_magellen_encoder,
};
void* subghz_protocol_encoder_magellen_alloc(SubGhzEnvironment* environment) {
UNUSED(environment);
SubGhzProtocolEncoderMagellen* instance = malloc(sizeof(SubGhzProtocolEncoderMagellen));
instance->base.protocol = &subghz_protocol_magellen;
instance->generic.protocol_name = instance->base.protocol->name;
instance->encoder.repeat = 10;
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
return instance;
}
void subghz_protocol_encoder_magellen_free(void* context) {
furi_assert(context);
SubGhzProtocolEncoderMagellen* instance = context;
free(instance->encoder.upload);
free(instance);
}
/**
* Generating an upload from data.
* @param instance Pointer to a SubGhzProtocolEncoderMagellen instance
* @return true On success
*/
static bool subghz_protocol_encoder_magellen_get_upload(SubGhzProtocolEncoderMagellen* instance) {
furi_assert(instance);
size_t index = 0;
//Send header
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_magellen_const.te_short * 4);
instance->encoder.upload[index++] =
level_duration_make(false, (uint32_t)subghz_protocol_magellen_const.te_short);
for(uint8_t i = 0; i < 12; i++) {
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_magellen_const.te_short);
instance->encoder.upload[index++] =
level_duration_make(false, (uint32_t)subghz_protocol_magellen_const.te_short);
}
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_magellen_const.te_short);
instance->encoder.upload[index++] =
level_duration_make(false, (uint32_t)subghz_protocol_magellen_const.te_long);
//Send start bit
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_magellen_const.te_long * 3);
instance->encoder.upload[index++] =
level_duration_make(false, (uint32_t)subghz_protocol_magellen_const.te_long);
//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_magellen_const.te_short);
instance->encoder.upload[index++] =
level_duration_make(false, (uint32_t)subghz_protocol_magellen_const.te_long);
} else {
//send bit 0
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_magellen_const.te_long);
instance->encoder.upload[index++] =
level_duration_make(false, (uint32_t)subghz_protocol_magellen_const.te_short);
}
}
//Send stop bit
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_magellen_const.te_short);
instance->encoder.upload[index++] =
level_duration_make(false, (uint32_t)subghz_protocol_magellen_const.te_long * 100);
instance->encoder.size_upload = index;
return true;
}
bool subghz_protocol_encoder_magellen_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolEncoderMagellen* 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_magellen_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_magellen_get_upload(instance);
instance->encoder.is_running = true;
res = true;
} while(false);
return res;
}
void subghz_protocol_encoder_magellen_stop(void* context) {
SubGhzProtocolEncoderMagellen* instance = context;
instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_magellen_yield(void* context) {
SubGhzProtocolEncoderMagellen* 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_magellen_alloc(SubGhzEnvironment* environment) {
UNUSED(environment);
SubGhzProtocolDecoderMagellen* instance = malloc(sizeof(SubGhzProtocolDecoderMagellen));
instance->base.protocol = &subghz_protocol_magellen;
instance->generic.protocol_name = instance->base.protocol->name;
return instance;
}
void subghz_protocol_decoder_magellen_free(void* context) {
furi_assert(context);
SubGhzProtocolDecoderMagellen* instance = context;
free(instance);
}
void subghz_protocol_decoder_magellen_reset(void* context) {
furi_assert(context);
SubGhzProtocolDecoderMagellen* instance = context;
instance->decoder.parser_step = MagellenDecoderStepReset;
}
uint8_t subghz_protocol_magellen_crc8(uint8_t* data, size_t len) {
uint8_t crc = 0x00;
size_t i, j;
for(i = 0; i < len; i++) {
crc ^= data[i];
for(j = 0; j < 8; j++) {
if((crc & 0x80) != 0)
crc = (uint8_t)((crc << 1) ^ 0x31);
else
crc <<= 1;
}
}
return crc;
}
static bool subghz_protocol_magellen_check_crc(SubGhzProtocolDecoderMagellen* instance) {
uint8_t data[3] = {
instance->decoder.decode_data >> 24,
instance->decoder.decode_data >> 16,
instance->decoder.decode_data >> 8};
return (instance->decoder.decode_data & 0xFF) ==
subghz_protocol_magellen_crc8(data, sizeof(data));
}
void subghz_protocol_decoder_magellen_feed(void* context, bool level, uint32_t duration) {
furi_assert(context);
SubGhzProtocolDecoderMagellen* instance = context;
switch(instance->decoder.parser_step) {
case MagellenDecoderStepReset:
if((level) && (DURATION_DIFF(duration, subghz_protocol_magellen_const.te_short) <
subghz_protocol_magellen_const.te_delta)) {
instance->decoder.parser_step = MagellenDecoderStepCheckPreambula;
instance->decoder.te_last = duration;
instance->header_count = 0;
}
break;
case MagellenDecoderStepCheckPreambula:
if(level) {
instance->decoder.te_last = duration;
} else {
if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_magellen_const.te_short) <
subghz_protocol_magellen_const.te_delta) &&
(DURATION_DIFF(duration, subghz_protocol_magellen_const.te_short) <
subghz_protocol_magellen_const.te_delta)) {
// Found header
instance->header_count++;
} else if(
(DURATION_DIFF(instance->decoder.te_last, subghz_protocol_magellen_const.te_short) <
subghz_protocol_magellen_const.te_delta) &&
(DURATION_DIFF(duration, subghz_protocol_magellen_const.te_long) <
subghz_protocol_magellen_const.te_delta * 2) &&
(instance->header_count > 10)) {
instance->decoder.parser_step = MagellenDecoderStepFoundPreambula;
} else {
instance->decoder.parser_step = MagellenDecoderStepReset;
}
}
break;
case MagellenDecoderStepFoundPreambula:
if(level) {
instance->decoder.te_last = duration;
} else {
if((DURATION_DIFF(
instance->decoder.te_last, subghz_protocol_magellen_const.te_short * 6) <
subghz_protocol_magellen_const.te_delta * 3) &&
(DURATION_DIFF(duration, subghz_protocol_magellen_const.te_long) <
subghz_protocol_magellen_const.te_delta * 2)) {
instance->decoder.parser_step = MagellenDecoderStepSaveDuration;
instance->decoder.decode_data = 0;
instance->decoder.decode_count_bit = 0;
} else {
instance->decoder.parser_step = MagellenDecoderStepReset;
}
}
break;
case MagellenDecoderStepSaveDuration:
if(level) {
instance->decoder.te_last = duration;
instance->decoder.parser_step = MagellenDecoderStepCheckDuration;
} else {
instance->decoder.parser_step = MagellenDecoderStepReset;
}
break;
case MagellenDecoderStepCheckDuration:
if(!level) {
if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_magellen_const.te_short) <
subghz_protocol_magellen_const.te_delta) &&
(DURATION_DIFF(duration, subghz_protocol_magellen_const.te_long) <
subghz_protocol_magellen_const.te_delta)) {
subghz_protocol_blocks_add_bit(&instance->decoder, 1);
instance->decoder.parser_step = MagellenDecoderStepSaveDuration;
} else if(
(DURATION_DIFF(instance->decoder.te_last, subghz_protocol_magellen_const.te_long) <
subghz_protocol_magellen_const.te_delta) &&
(DURATION_DIFF(duration, subghz_protocol_magellen_const.te_short) <
subghz_protocol_magellen_const.te_delta)) {
subghz_protocol_blocks_add_bit(&instance->decoder, 0);
instance->decoder.parser_step = MagellenDecoderStepSaveDuration;
} else if(duration >= (subghz_protocol_magellen_const.te_long * 3)) {
//Found stop bit
if((instance->decoder.decode_count_bit ==
subghz_protocol_magellen_const.min_count_bit_for_found) &&
subghz_protocol_magellen_check_crc(instance)) {
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.decode_data = 0;
instance->decoder.decode_count_bit = 0;
instance->decoder.parser_step = MagellenDecoderStepReset;
} else {
instance->decoder.parser_step = MagellenDecoderStepReset;
}
} else {
instance->decoder.parser_step = MagellenDecoderStepReset;
}
break;
}
}
/**
* Analysis of received data
* @param instance Pointer to a SubGhzBlockGeneric* instance
*/
static void subghz_protocol_magellen_check_remote_controller(SubGhzBlockGeneric* instance) {
/*
* package 32b data 24b CRC8
* 0x037AE4828 => 001101111010111001001000 00101000
*
* 0x037AE48 (flipped in reverse bit sequence) => 0x1275EC
*
* 0x1275EC => 0x12-event codes, 0x75EC-serial (dec 117236)
*
* event codes
* bit_0: 1-alarm, 0-close
* bit_1: 1-Tamper On (alarm), 0-Tamper Off (ok)
* bit_2: ?
* bit_3: 1-power on
* bit_4: model type - door alarm
* bit_5: model type - motion sensor
* bit_6: ?
* bit_7: ?
*
*/
uint64_t data_rev = subghz_protocol_blocks_reverse_key(instance->data >> 8, 24);
instance->serial = data_rev & 0xFFFF;
instance->btn = (data_rev >> 16) & 0xFF;
}
static void subghz_protocol_magellen_get_event_serialize(uint8_t event, string_t output) {
string_cat_printf(
output,
"%s%s%s%s%s%s%s%s",
(event & 0x1 ? " Alarm" : "Ok"),
((event >> 1) & 0x1 ? ", Tamper On (Alarm)" : ""),
((event >> 2) & 0x1 ? ", ?" : ""),
((event >> 3) & 0x1 ? ", Power On" : ""),
((event >> 4) & 0x1 ? ", MT:Door_Alarm" : ""),
((event >> 5) & 0x1 ? ", MT:Motion_Sensor" : ""),
((event >> 6) & 0x1 ? ", ?" : ""),
((event >> 7) & 0x1 ? ", ?" : ""));
}
uint8_t subghz_protocol_decoder_magellen_get_hash_data(void* context) {
furi_assert(context);
SubGhzProtocolDecoderMagellen* instance = context;
return subghz_protocol_blocks_get_hash_data(
&instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
}
bool subghz_protocol_decoder_magellen_serialize(
void* context,
FlipperFormat* flipper_format,
SubGhzPresetDefinition* preset) {
furi_assert(context);
SubGhzProtocolDecoderMagellen* instance = context;
return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
}
bool subghz_protocol_decoder_magellen_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolDecoderMagellen* instance = context;
bool ret = false;
do {
if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
break;
}
if(instance->generic.data_count_bit !=
subghz_protocol_magellen_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_magellen_get_string(void* context, string_t output) {
furi_assert(context);
SubGhzProtocolDecoderMagellen* instance = context;
subghz_protocol_magellen_check_remote_controller(&instance->generic);
string_cat_printf(
output,
"%s %dbit\r\n"
"Key:0x%08lX\r\n"
"Sn:%03d%03d, Event:0x%02X\r\n"
"Stat:",
instance->generic.protocol_name,
instance->generic.data_count_bit,
(uint32_t)(instance->generic.data & 0xFFFFFFFF),
(instance->generic.serial >> 8) & 0xFF,
instance->generic.serial & 0xFF,
instance->generic.btn);
subghz_protocol_magellen_get_event_serialize(instance->generic.btn, output);
}

View file

@ -0,0 +1,107 @@
#pragma once
#include "base.h"
#define SUBGHZ_PROTOCOL_MAGELLEN_NAME "Magellen"
typedef struct SubGhzProtocolDecoderMagellen SubGhzProtocolDecoderMagellen;
typedef struct SubGhzProtocolEncoderMagellen SubGhzProtocolEncoderMagellen;
extern const SubGhzProtocolDecoder subghz_protocol_magellen_decoder;
extern const SubGhzProtocolEncoder subghz_protocol_magellen_encoder;
extern const SubGhzProtocol subghz_protocol_magellen;
/**
* Allocate SubGhzProtocolEncoderMagellen.
* @param environment Pointer to a SubGhzEnvironment instance
* @return SubGhzProtocolEncoderMagellen* pointer to a SubGhzProtocolEncoderMagellen instance
*/
void* subghz_protocol_encoder_magellen_alloc(SubGhzEnvironment* environment);
/**
* Free SubGhzProtocolEncoderMagellen.
* @param context Pointer to a SubGhzProtocolEncoderMagellen instance
*/
void subghz_protocol_encoder_magellen_free(void* context);
/**
* Deserialize and generating an upload to send.
* @param context Pointer to a SubGhzProtocolEncoderMagellen instance
* @param flipper_format Pointer to a FlipperFormat instance
* @return true On success
*/
bool subghz_protocol_encoder_magellen_deserialize(void* context, FlipperFormat* flipper_format);
/**
* Forced transmission stop.
* @param context Pointer to a SubGhzProtocolEncoderMagellen instance
*/
void subghz_protocol_encoder_magellen_stop(void* context);
/**
* Getting the level and duration of the upload to be loaded into DMA.
* @param context Pointer to a SubGhzProtocolEncoderMagellen instance
* @return LevelDuration
*/
LevelDuration subghz_protocol_encoder_magellen_yield(void* context);
/**
* Allocate SubGhzProtocolDecoderMagellen.
* @param environment Pointer to a SubGhzEnvironment instance
* @return SubGhzProtocolDecoderMagellen* pointer to a SubGhzProtocolDecoderMagellen instance
*/
void* subghz_protocol_decoder_magellen_alloc(SubGhzEnvironment* environment);
/**
* Free SubGhzProtocolDecoderMagellen.
* @param context Pointer to a SubGhzProtocolDecoderMagellen instance
*/
void subghz_protocol_decoder_magellen_free(void* context);
/**
* Reset decoder SubGhzProtocolDecoderMagellen.
* @param context Pointer to a SubGhzProtocolDecoderMagellen instance
*/
void subghz_protocol_decoder_magellen_reset(void* context);
/**
* Parse a raw sequence of levels and durations received from the air.
* @param context Pointer to a SubGhzProtocolDecoderMagellen instance
* @param level Signal level true-high false-low
* @param duration Duration of this level in, us
*/
void subghz_protocol_decoder_magellen_feed(void* context, bool level, uint32_t duration);
/**
* Getting the hash sum of the last randomly received parcel.
* @param context Pointer to a SubGhzProtocolDecoderMagellen instance
* @return hash Hash sum
*/
uint8_t subghz_protocol_decoder_magellen_get_hash_data(void* context);
/**
* Serialize data SubGhzProtocolDecoderMagellen.
* @param context Pointer to a SubGhzProtocolDecoderMagellen 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_magellen_serialize(
void* context,
FlipperFormat* flipper_format,
SubGhzPresetDefinition* preset);
/**
* Deserialize data SubGhzProtocolDecoderMagellen.
* @param context Pointer to a SubGhzProtocolDecoderMagellen instance
* @param flipper_format Pointer to a FlipperFormat instance
* @return true On success
*/
bool subghz_protocol_decoder_magellen_deserialize(void* context, FlipperFormat* flipper_format);
/**
* Getting a textual representation of the received data.
* @param context Pointer to a SubGhzProtocolDecoderMagellen instance
* @param output Resulting text
*/
void subghz_protocol_decoder_magellen_get_string(void* context, string_t output);

View file

@ -11,7 +11,7 @@ const SubGhzProtocol* subghz_protocol_registry[] = {
&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,
&subghz_protocol_honeywell_wdb, &subghz_protocol_magellen,
};

View file

@ -33,6 +33,7 @@
#include "doitrand.h"
#include "phoenix_v2.h"
#include "honeywell_wdb.h"
#include "magellen.h"
/**
* Registration by name SubGhzProtocol.

View file

@ -29,6 +29,7 @@ build_version = libenv.VersionBuilder(
fw_version_json = libenv.InstallAs(
"${BUILD_DIR}/${FIRMWARE_BUILD_CFG}.json", "version.json"
)
Alias("version_json", fw_version_json)
env.Append(FW_VERSION_JSON=fw_version_json)
# Default(fw_version_json)
@ -40,7 +41,7 @@ if not version_depends:
sources = libenv.GlobRecursive("*.c")
libenv.Append(CPPPATH=["."])
libenv.Append(CPPPATH=[libenv.Dir(".")])
lib = libenv.StaticLibrary("${FW_LIB_NAME}", sources)
libenv.Install("${LIB_DIST_DIR}", lib)

View file

@ -36,7 +36,7 @@ class Main(App):
file_idx += 1
except Exception as e:
self.logger.error(e)
break
return 3
widths = set(img.width for img in images)
heights = set(img.height for img in images)