diff --git a/.drone.yml b/.drone.yml
index 7499ccbee..15c5dfce1 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -44,6 +44,7 @@ steps:
- cp assets/resources/nfc/assets/mf_classic_dict.nfc sd-card/nfc/assets/mf_classic_dict.nfc
- cp assets/resources/infrared/assets/tv.ir sd-card/infrared/assets/tv.ir
- cp assets/resources/infrared/assets/ac.ir sd-card/infrared/assets/ac.ir
+ - cp assets/resources/infrared/assets/projectors.ir sd-card/infrared/assets/projectors.ir
- cp assets/resources/infrared/assets/audio.ir sd-card/infrared/assets/audio.ir
- cp assets/resources/unirf/unirf_map_example.txt sd-card/unirf/unirf_map_example.txt
- cp assets/resources/Manifest sd-card/Manifest
diff --git a/.gitignore b/.gitignore
index a2e0be12d..8f4ab0e1f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,3 +51,7 @@ build/
# openocd output file
openocd.log
+
+# PVS Studio temporary files
+.PVS-Studio/
+PVS-Studio.log
diff --git a/.pvsconfig b/.pvsconfig
new file mode 100644
index 000000000..d17eaa5a0
--- /dev/null
+++ b/.pvsconfig
@@ -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
diff --git a/.pvsoptions b/.pvsoptions
new file mode 100644
index 000000000..4c80ab667
--- /dev/null
+++ b/.pvsoptions
@@ -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 */arm-none-eabi/*
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 88ad7cdba..64ed851a2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,13 +1,23 @@
### New changes
-* Wifi Marauder app update (by @0xchocolate)
-* Updated Universal remote assets (by @Amec0e)
-* Fixed music player
-* Fixed typos in subghz encoders
-* OFW: New NFC info screens
-* OFW: U2F fixes
+* New universal remote for projectors
+* OFW: New LF-RFID subsystem (New protocols, Animal tags support)
+* Updated universal remote assets (by @Amec0e)
+* Renamed UniRF Remix -> Sub-GHz Remote
+* Replaced Hex/Dec converter with Multi Converter plugin [(by theisolinearchip)](https://github.com/theisolinearchip/flipperzero_stuff)
+* New update screen, readme pictures (by @Svaarich)
+* Fixed crash if Center button is pressed on the "update success" screen via screensharing
+* Temporary disabled one log call in picopass plugin to fix crash/freeze on Read screen
+* OFW: Picopass load/info/delete
+* OFW: SubGhz: add protocol Magellen
+* OFW: Fix mifare ultralight/ntag unlock
+* OFW: Dolphin level thresholds update
+* OFW: Add MFC 1/4K 4/7bUID to "Add Manually"
+* OFW: Other fixes and changes
**Note: Prefer installing using web updater or by self update package, all needed assets will be installed**
+**Build naming has been changed - all same as before but `cg - codegrabber` changed to `un - unleashed`**
+
Self-update package (update from microSD) - `flipper-z-f7-update-(version).zip`
DFU for update using qFlipper - `flipper-z-f7-full-(version).dfu`
diff --git a/ReadMe.md b/ReadMe.md
index 927369e07..b9cc9e257 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -1,6 +1,8 @@
-# Flipper Zero Unleashed Firmware
-
-
+
Welcome to Flipper Zero's Custom Firmware repo!
Our goal is to make any features possible in this device without any limitations!
@@ -30,6 +32,9 @@ Our Discord Community:
* Picopass/iClass plugin included in releases
* Recompiled IR TV Universal Remote for ALL buttons
* Universal A/C and Audio(soundbars, etc.) remote
+* Universal remote for Projectors
+* BadUSB keyboard layouts
+* Customizable Flipper name
* Other small fixes and changes throughout
See changelog in releases for latest updates!
@@ -57,13 +62,12 @@ See changelog in releases for latest updates!
- ESP8266 Deauther plugin [(by SequoiaSan)](https://github.com/SequoiaSan/FlipperZero-Wifi-ESP8266-Deauther-Module)
- WiFi Scanner plugin [(by SequoiaSan)](https://github.com/SequoiaSan/FlipperZero-WiFi-Scanner_Module)
-- Dec/Hex Converter plugin [(by theisolinearchip)](https://github.com/theisolinearchip/flipperzero_stuff/tree/main/applications/dec_hex_converter)
+- MultiConverter plugin [(by theisolinearchip)](https://github.com/theisolinearchip/flipperzero_stuff)
- WAV player plugin (fixed) [(OFW: DrZlo13)](https://github.com/flipperdevices/flipperzero-firmware/tree/zlo/wav-player)
- UPC-A Barcode generator plugin [(by McAzzaMan)](https://github.com/McAzzaMan/flipperzero-firmware/tree/UPC-A_Barcode_Generator/applications/barcode_generator)
- GPIO: Sentry Safe plugin [(by H4ckd4ddy)](https://github.com/H4ckd4ddy/flipperzero-sentry-safe-plugin)
- ESP32: WiFi Marauder companion plugin [(by 0xchocolate)](https://github.com/0xchocolate/flipperzero-firmware-with-wifi-marauder-companion)
- NRF24: Sniffer & MouseJacker (with changes) [(by mothball187)](https://github.com/mothball187/flipperzero-nrf24/tree/main/mousejacker)
-- HID Analyzer [(by Ownasaurus)](https://github.com/Ownasaurus/flipperzero-firmware/tree/hid-analyzer/applications/hid_analyzer)
- Simple Clock (fixed) !! New version WIP, wait for updates !! [(Original by CompaqDisc)](https://gist.github.com/CompaqDisc/4e329c501bd03c1e801849b81f48ea61)
- UniversalRF Remix (with changes)(only RAW subghz files) [(by ESurge)(Original UniversalRF by jimilinuxguy)](https://github.com/ESurge/flipperzero-firmware-unirfremix)
- Tetris (with fixes) [(by jeffplang)](https://github.com/jeffplang/flipperzero-firmware/tree/tetris_game/applications/tetris_game)
@@ -87,10 +91,12 @@ See changelog in releases for latest updates!
### **Plugins**
-## [- Configure UniversalRF Remix App](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/UniRFRemix.md)
+## [- Configure Sub-GHz Remote App](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/SubGHzRemotePlugin.md)
## [- Barcode Generator](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/BarcodeGenerator.md)
+## [- Multi Converter](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/MultiConverter.md)
+
## [- WAV Player sample files & how to convert](https://github.com/UberGuidoZ/Flipper/tree/main/Wav_Player#readme)
### **Plugins that works with external hardware**
@@ -142,7 +148,6 @@ See changelog in releases for latest updates!
- `assets` - Assets used by applications and services
- `furi` - Furi Core: os level primitives and helpers
- `debug` - Debug tool: GDB-plugins, SVD-file and etc
-- `docker` - Docker image sources (used for firmware build automation)
- `documentation` - Documentation generation system configs and input files
- `firmware` - Firmware source code
- `lib` - Our and 3rd party libraries, drivers and etc...
diff --git a/applications/archive/helpers/archive_apps.c b/applications/archive/helpers/archive_apps.c
index 9a3f825f1..72084f113 100644
--- a/applications/archive/helpers/archive_apps.c
+++ b/applications/archive/helpers/archive_apps.c
@@ -29,23 +29,13 @@ bool archive_app_is_available(void* context, const char* path) {
if(app == ArchiveAppTypeU2f) {
bool file_exists = false;
- Storage* fs_api = furi_record_open(RECORD_STORAGE);
- File* file = storage_file_alloc(fs_api);
+ Storage* storage = furi_record_open(RECORD_STORAGE);
- file_exists =
- storage_file_open(file, ANY_PATH("u2f/key.u2f"), FSAM_READ, FSOM_OPEN_EXISTING);
- if(file_exists) {
- storage_file_close(file);
- file_exists =
- storage_file_open(file, ANY_PATH("u2f/cnt.u2f"), FSAM_READ, FSOM_OPEN_EXISTING);
- if(file_exists) {
- storage_file_close(file);
- }
+ if(storage_file_exists(storage, ANY_PATH("u2f/key.u2f"))) {
+ file_exists = storage_file_exists(storage, ANY_PATH("u2f/cnt.u2f"));
}
- storage_file_free(file);
furi_record_close(RECORD_STORAGE);
-
return file_exists;
} else {
return false;
diff --git a/applications/archive/helpers/archive_browser.c b/applications/archive/helpers/archive_browser.c
index 54759dadc..2dfb9484b 100644
--- a/applications/archive/helpers/archive_browser.c
+++ b/applications/archive/helpers/archive_browser.c
@@ -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;
diff --git a/applications/archive/helpers/archive_browser.h b/applications/archive/helpers/archive_browser.h
index d6c79817a..ad64a9845 100644
--- a/applications/archive/helpers/archive_browser.h
+++ b/applications/archive/helpers/archive_browser.h
@@ -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);
diff --git a/applications/archive/helpers/archive_favorites.c b/applications/archive/helpers/archive_favorites.c
index 35199242e..4d5b555f5 100644
--- a/applications/archive/helpers/archive_favorites.c
+++ b/applications/archive/helpers/archive_favorites.c
@@ -82,9 +82,8 @@ uint16_t archive_favorites_count(void* context) {
static bool archive_favourites_rescan() {
string_t buffer;
string_init(buffer);
- Storage* fs_api = furi_record_open(RECORD_STORAGE);
- File* file = storage_file_alloc(fs_api);
- File* fav_item_file = storage_file_alloc(fs_api);
+ Storage* storage = furi_record_open(RECORD_STORAGE);
+ File* file = storage_file_alloc(storage);
bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING);
if(result) {
@@ -101,13 +100,8 @@ static bool archive_favourites_rescan() {
archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(buffer));
}
} else {
- bool file_exists = storage_file_open(
- fav_item_file, string_get_cstr(buffer), FSAM_READ, FSOM_OPEN_EXISTING);
- if(file_exists) {
- storage_file_close(fav_item_file);
+ if(storage_file_exists(storage, string_get_cstr(buffer))) {
archive_file_append(ARCHIVE_FAV_TEMP_PATH, "%s\n", string_get_cstr(buffer));
- } else {
- storage_file_close(fav_item_file);
}
}
}
@@ -116,12 +110,11 @@ static bool archive_favourites_rescan() {
string_clear(buffer);
storage_file_close(file);
- storage_common_remove(fs_api, ARCHIVE_FAV_PATH);
- storage_common_rename(fs_api, ARCHIVE_FAV_TEMP_PATH, ARCHIVE_FAV_PATH);
- storage_common_remove(fs_api, ARCHIVE_FAV_TEMP_PATH);
+ storage_common_remove(storage, ARCHIVE_FAV_PATH);
+ storage_common_rename(storage, ARCHIVE_FAV_TEMP_PATH, ARCHIVE_FAV_PATH);
+ storage_common_remove(storage, ARCHIVE_FAV_TEMP_PATH);
storage_file_free(file);
- storage_file_free(fav_item_file);
furi_record_close(RECORD_STORAGE);
return result;
@@ -131,9 +124,8 @@ bool archive_favorites_read(void* context) {
furi_assert(context);
ArchiveBrowserView* browser = context;
- Storage* fs_api = furi_record_open(RECORD_STORAGE);
- File* file = storage_file_alloc(fs_api);
- File* fav_item_file = storage_file_alloc(fs_api);
+ Storage* storage = furi_record_open(RECORD_STORAGE);
+ File* file = storage_file_alloc(storage);
string_t buffer;
FileInfo file_info;
@@ -163,16 +155,12 @@ bool archive_favorites_read(void* context) {
need_refresh = true;
}
} else {
- bool file_exists = storage_file_open(
- fav_item_file, string_get_cstr(buffer), FSAM_READ, FSOM_OPEN_EXISTING);
- if(file_exists) {
- storage_common_stat(fs_api, string_get_cstr(buffer), &file_info);
- storage_file_close(fav_item_file);
+ if(storage_file_exists(storage, string_get_cstr(buffer))) {
+ storage_common_stat(storage, string_get_cstr(buffer), &file_info);
archive_add_file_item(
browser, (file_info.flags & FSF_DIRECTORY), string_get_cstr(buffer));
file_count++;
} else {
- storage_file_close(fav_item_file);
need_refresh = true;
}
}
@@ -183,7 +171,6 @@ bool archive_favorites_read(void* context) {
storage_file_close(file);
string_clear(buffer);
storage_file_free(file);
- storage_file_free(fav_item_file);
furi_record_close(RECORD_STORAGE);
archive_set_item_count(browser, file_count);
diff --git a/applications/archive/views/archive_browser_view.c b/applications/archive/views/archive_browser_view.c
index 810d5c8f7..174071ad4 100644
--- a/applications/archive/views/archive_browser_view.c
+++ b/applications/archive/views/archive_browser_view.c
@@ -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) {
diff --git a/applications/archive/views/archive_browser_view.h b/applications/archive/views/archive_browser_view.h
index 2de04a166..5c649c389 100644
--- a/applications/archive/views/archive_browser_view.h
+++ b/applications/archive/views/archive_browser_view.h
@@ -74,6 +74,7 @@ typedef enum {
struct ArchiveBrowserView {
View* view;
BrowserWorker* worker;
+ bool worker_running;
ArchiveBrowserViewCallback callback;
void* context;
string_t path;
diff --git a/applications/bt/bt_cli.c b/applications/bt/bt_cli.c
index 3aa1bc752..79500fac4 100644
--- a/applications/bt/bt_cli.c
+++ b/applications/bt/bt_cli.c
@@ -3,7 +3,7 @@
#include
#include
-#include "ble.h"
+#include
#include "bt_settings.h"
#include "bt_service/bt.h"
diff --git a/applications/bt/bt_hid_app/bt_hid.c b/applications/bt/bt_hid_app/bt_hid.c
old mode 100755
new mode 100644
index b6f00e939..0827bd0ad
--- a/applications/bt/bt_hid_app/bt_hid.c
+++ b/applications/bt/bt_hid_app/bt_hid.c
@@ -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;
}
diff --git a/applications/bt/bt_hid_app/views/bt_hid_keynote.c b/applications/bt/bt_hid_app/views/bt_hid_keynote.c
index 60a1ebc08..ea4ee16fa 100755
--- a/applications/bt/bt_hid_app/views/bt_hid_keynote.c
+++ b/applications/bt/bt_hid_app/views/bt_hid_keynote.c
@@ -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) {
diff --git a/applications/bt/bt_hid_app/views/bt_hid_media.c b/applications/bt/bt_hid_app/views/bt_hid_media.c
index b384f47cf..258ea0a40 100755
--- a/applications/bt/bt_hid_app/views/bt_hid_media.c
+++ b/applications/bt/bt_hid_app/views/bt_hid_media.c
@@ -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) {
diff --git a/applications/bt/bt_hid_app/views/bt_hid_mouse.c b/applications/bt/bt_hid_app/views/bt_hid_mouse.c
index fb1537a2c..f9d84f9fb 100644
--- a/applications/bt/bt_hid_app/views/bt_hid_mouse.c
+++ b/applications/bt/bt_hid_app/views/bt_hid_mouse.c
@@ -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) {
diff --git a/applications/dec_hex_converter/dec_hex_converter.c b/applications/dec_hex_converter/dec_hex_converter.c
deleted file mode 100644
index 98a090a82..000000000
--- a/applications/dec_hex_converter/dec_hex_converter.c
+++ /dev/null
@@ -1,404 +0,0 @@
-#include
-#include
-#include
-#include
-
-#define DEC_HEX_CONVERTER_NUMBER_DIGITS 9
-#define DEC_HEX_CONVERTER_KEYS 18
-#define DEC_HEX_CONVERTER_KEY_DEL 16
-// #define DEC_HEX_CONVERTER_KEY_SWAP 17 // actually not used...
-
-#define DEC_HEX_CONVERTER_CHAR_DEL '<'
-#define DEC_HEX_CONVERTER_CHAR_SWAP 's'
-#define DEC_HEX_CONVERTER_CHAR_MODE '#'
-#define DEC_HEX_CONVERTER_CHAR_OVERFLOW '#'
-
-#define DEC_HEX_CONVERTER_KEY_FRAME_MARGIN 3
-#define DEC_HEX_CONVERTER_KEY_CHAR_HEIGHT 8
-
-#define DEC_HEX_MAX_SUPORTED_DEC_INT 999999999
-
-typedef enum {
- EventTypeKey,
-} EventType;
-
-typedef struct {
- InputEvent input;
- EventType type;
-} DecHexConverterEvent;
-
-typedef enum {
- ModeDec,
- ModeHex,
-} Mode;
-
-// setting up one char array next to the other one causes the canvas_draw_str to display both of them
-// when addressing the first one if there's no string terminator or similar indicator. Adding a \0 seems
-// to work fine to prevent that, so add a final last char outside the size constants (added on init
-// and NEVER changed nor referenced again)
-//
-// (as a reference, canvas_draw_str ends up calling u8g2_DrawStr from u8g2_font.c,
-// that finally ends up calling u8g2_draw_string)
-typedef struct {
- char dec_number[DEC_HEX_CONVERTER_NUMBER_DIGITS + 1];
- char hex_number[DEC_HEX_CONVERTER_NUMBER_DIGITS + 1];
- Mode mode; // dec / hex
- int8_t cursor; // position on keyboard (includes digit letters and other options)
- int8_t digit_pos; // current digit on selected mode
-} DecHexConverterState;
-
-// move cursor left / right (TODO: implement menu nav in a more "standard" and reusable way?)
-void dec_hex_converter_logic_move_cursor_lr(
- DecHexConverterState* const dec_hex_converter_state,
- int8_t d) {
- dec_hex_converter_state->cursor += d;
-
- if(dec_hex_converter_state->cursor > DEC_HEX_CONVERTER_KEYS - 1)
- dec_hex_converter_state->cursor = 0;
- else if(dec_hex_converter_state->cursor < 0)
- dec_hex_converter_state->cursor = DEC_HEX_CONVERTER_KEYS - 1;
-
- // if we're moving left / right to the letters keys on ModeDec just go to the closest available key
- if(dec_hex_converter_state->mode == ModeDec) {
- if(dec_hex_converter_state->cursor == 10)
- dec_hex_converter_state->cursor = 16;
- else if(dec_hex_converter_state->cursor == 15)
- dec_hex_converter_state->cursor = 9;
- }
-}
-
-// move cursor up / down; there're two lines, so we basically toggle
-void dec_hex_converter_logic_move_cursor_ud(DecHexConverterState* const dec_hex_converter_state) {
- if(dec_hex_converter_state->cursor < 9) {
- // move to second line ("down")
- dec_hex_converter_state->cursor += 9;
-
- // if we're reaching the letter keys while ModeDec, just move left / right for the first available key
- if(dec_hex_converter_state->mode == ModeDec &&
- (dec_hex_converter_state->cursor >= 10 && dec_hex_converter_state->cursor <= 15)) {
- if(dec_hex_converter_state->cursor <= 12)
- dec_hex_converter_state->cursor = 9;
- else
- dec_hex_converter_state->cursor = 16;
- }
- } else {
- // move to first line ("up")
- dec_hex_converter_state->cursor -= 9;
- }
-}
-
-// fetch number from current mode and modifies the destination one, RM dnt stel pls
-// (if destination is shorter than the output value, overried with "-" chars or something similar)
-void dec_hex_converter_logic_convert_number(DecHexConverterState* const dec_hex_converter_state) {
- char* s_ptr;
- char* d_ptr;
-
- char dest[DEC_HEX_CONVERTER_NUMBER_DIGITS];
- int i = 0; // current index on destination array
-
- if(dec_hex_converter_state->mode == ModeDec) {
- // DEC to HEX cannot overflow if they're, at least, the same size
-
- s_ptr = dec_hex_converter_state->dec_number;
- d_ptr = dec_hex_converter_state->hex_number;
-
- int a = atoi(s_ptr);
- int r;
- while(a != 0) {
- r = a % 16;
- dest[i] = r + (r < 10 ? '0' : ('A' - 10));
- a /= 16;
- i++;
- }
-
- } else {
- s_ptr = dec_hex_converter_state->hex_number;
- d_ptr = dec_hex_converter_state->dec_number;
-
- int a = strtol(s_ptr, NULL, 16);
- if(a > DEC_HEX_MAX_SUPORTED_DEC_INT) {
- // draw all "###" if there's an overflow
- for(int j = 0; j < DEC_HEX_CONVERTER_NUMBER_DIGITS; j++) {
- d_ptr[j] = DEC_HEX_CONVERTER_CHAR_OVERFLOW;
- }
- return;
- } else {
- while(a > 0) {
- dest[i++] = (a % 10) + '0';
- a /= 10;
- }
- }
- }
-
- // dest is reversed, copy to destination pointer and append empty chars at the end
- for(int j = 0; j < DEC_HEX_CONVERTER_NUMBER_DIGITS; j++) {
- if(i >= 1)
- d_ptr[j] = dest[--i];
- else
- d_ptr[j] = ' ';
- }
-}
-
-// change from DEC to HEX or HEX to DEC, set the digit_pos to the last position not empty on the destination mode
-void dec_hex_converter_logic_swap_mode(DecHexConverterState* const dec_hex_converter_state) {
- char* n_ptr;
- if(dec_hex_converter_state->mode == ModeDec) {
- dec_hex_converter_state->mode = ModeHex;
- n_ptr = dec_hex_converter_state->hex_number;
- } else {
- dec_hex_converter_state->mode = ModeDec;
- n_ptr = dec_hex_converter_state->dec_number;
- }
-
- dec_hex_converter_state->digit_pos = DEC_HEX_CONVERTER_NUMBER_DIGITS;
- for(int i = 0; i < DEC_HEX_CONVERTER_NUMBER_DIGITS; i++) {
- if(n_ptr[i] == ' ') {
- dec_hex_converter_state->digit_pos = i;
- break;
- }
- }
-}
-
-// removes the number on current digit on current mode
-static void
- dec_hex_converter_logic_del_number(DecHexConverterState* const dec_hex_converter_state) {
- if(dec_hex_converter_state->digit_pos > 0) dec_hex_converter_state->digit_pos--;
-
- if(dec_hex_converter_state->mode == ModeDec) {
- dec_hex_converter_state->dec_number[dec_hex_converter_state->digit_pos] = ' ';
- } else {
- dec_hex_converter_state->hex_number[dec_hex_converter_state->digit_pos] = ' ';
- }
-}
-
-// append a number to the digit on the current mode
-static void dec_hex_converter_logic_add_number(
- DecHexConverterState* const dec_hex_converter_state,
- int8_t number) {
- // ignore HEX values on DEC mode (probably button nav will be disabled too, so cannot reach);
- // also do not add anything if we're out of bound
- if((number > 9 && dec_hex_converter_state->mode == ModeDec) ||
- dec_hex_converter_state->digit_pos >= DEC_HEX_CONVERTER_NUMBER_DIGITS)
- return;
-
- char* s_ptr;
-
- if(dec_hex_converter_state->mode == ModeDec) {
- s_ptr = dec_hex_converter_state->dec_number;
- } else {
- s_ptr = dec_hex_converter_state->hex_number;
- }
-
- if(number < 10) {
- s_ptr[dec_hex_converter_state->digit_pos] = number + '0';
- } else {
- s_ptr[dec_hex_converter_state->digit_pos] = (number - 10) + 'A'; // A-F (HEX only)
- }
-
- dec_hex_converter_state->digit_pos++;
-}
-
-// ---------------
-
-static void dec_hex_converter_render_callback(Canvas* const canvas, void* ctx) {
- const DecHexConverterState* dec_hex_converter_state = acquire_mutex((ValueMutex*)ctx, 25);
- if(dec_hex_converter_state == NULL) {
- return;
- }
-
- canvas_set_color(canvas, ColorBlack);
-
- // DEC
- canvas_set_font(canvas, FontPrimary);
- canvas_draw_str(canvas, 2, 10, "DEC: ");
-
- canvas_set_font(canvas, FontPrimary);
- canvas_draw_str(canvas, 2 + 30, 10, dec_hex_converter_state->dec_number);
-
- // HEX
- canvas_set_font(canvas, FontPrimary);
- canvas_draw_str(canvas, 2, 10 + 12, "HEX: ");
-
- canvas_set_font(canvas, FontPrimary);
- canvas_draw_str(canvas, 2 + 30, 10 + 12, dec_hex_converter_state->hex_number);
-
- // current mode indicator
- // char buffer[4];
- // snprintf(buffer, sizeof(buffer), "%u", dec_hex_converter_state->digit_pos); // debug: show digit position instead of selected mode
- if(dec_hex_converter_state->mode == ModeDec) {
- canvas_draw_glyph(canvas, 128 - 10, 10, DEC_HEX_CONVERTER_CHAR_MODE);
- } else {
- canvas_draw_glyph(canvas, 128 - 10, 10 + 12, DEC_HEX_CONVERTER_CHAR_MODE);
- }
-
- // draw the line
- canvas_draw_line(canvas, 2, 25, 128 - 3, 25);
-
- // draw the keyboard
- uint8_t _x = 5;
- uint8_t _y = 25 + 15; // line + 10
-
- for(int i = 0; i < DEC_HEX_CONVERTER_KEYS; i++) {
- char g;
- if(i < 10)
- g = (i + '0');
- else if(i < 16)
- g = ((i - 10) + 'A');
- else if(i == 16)
- g = DEC_HEX_CONVERTER_CHAR_DEL; // '<'
- else
- g = DEC_HEX_CONVERTER_CHAR_SWAP; // 's'
-
- uint8_t g_w = canvas_glyph_width(canvas, g);
-
- // disable letters on DEC mode (but keep the previous width for visual purposes - show "blank keys")
- if(dec_hex_converter_state->mode == ModeDec && i > 9 && i < 16) g = ' ';
-
- if(dec_hex_converter_state->cursor == i) {
- canvas_draw_box(
- canvas,
- _x - DEC_HEX_CONVERTER_KEY_FRAME_MARGIN,
- _y - (DEC_HEX_CONVERTER_KEY_CHAR_HEIGHT + DEC_HEX_CONVERTER_KEY_FRAME_MARGIN),
- DEC_HEX_CONVERTER_KEY_FRAME_MARGIN + g_w + DEC_HEX_CONVERTER_KEY_FRAME_MARGIN,
- DEC_HEX_CONVERTER_KEY_CHAR_HEIGHT + DEC_HEX_CONVERTER_KEY_FRAME_MARGIN * 2);
- canvas_set_color(canvas, ColorWhite);
- canvas_draw_glyph(canvas, _x, _y, g);
- canvas_set_color(canvas, ColorBlack);
- } else {
- canvas_draw_frame(
- canvas,
- _x - DEC_HEX_CONVERTER_KEY_FRAME_MARGIN,
- _y - (DEC_HEX_CONVERTER_KEY_CHAR_HEIGHT + DEC_HEX_CONVERTER_KEY_FRAME_MARGIN),
- DEC_HEX_CONVERTER_KEY_FRAME_MARGIN + g_w + DEC_HEX_CONVERTER_KEY_FRAME_MARGIN,
- DEC_HEX_CONVERTER_KEY_CHAR_HEIGHT + DEC_HEX_CONVERTER_KEY_FRAME_MARGIN * 2);
- canvas_draw_glyph(canvas, _x, _y, g);
- }
-
- if(i < 8) {
- _x += g_w + DEC_HEX_CONVERTER_KEY_FRAME_MARGIN * 2 + 2;
- } else if(i == 8) {
- _y += (DEC_HEX_CONVERTER_KEY_CHAR_HEIGHT + DEC_HEX_CONVERTER_KEY_FRAME_MARGIN * 2) + 3;
- _x = 7; // some padding at the beginning on second line
- } else {
- _x += g_w + DEC_HEX_CONVERTER_KEY_FRAME_MARGIN * 2 + 1;
- }
- }
-
- release_mutex((ValueMutex*)ctx, dec_hex_converter_state);
-}
-
-static void
- dec_hex_converter_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
- furi_assert(event_queue);
-
- DecHexConverterEvent event = {.type = EventTypeKey, .input = *input_event};
- furi_message_queue_put(event_queue, &event, FuriWaitForever);
-}
-
-static void dec_hex_converter_init(DecHexConverterState* const dec_hex_converter_state) {
- dec_hex_converter_state->mode = ModeDec;
- dec_hex_converter_state->digit_pos = 0;
-
- dec_hex_converter_state->dec_number[DEC_HEX_CONVERTER_NUMBER_DIGITS] = '\0'; // null terminator
- dec_hex_converter_state->hex_number[DEC_HEX_CONVERTER_NUMBER_DIGITS] = '\0'; // null terminator
-
- for(int i = 0; i < DEC_HEX_CONVERTER_NUMBER_DIGITS; i++) {
- dec_hex_converter_state->dec_number[i] = ' ';
- dec_hex_converter_state->hex_number[i] = ' ';
- }
-}
-
-// main entry point
-int32_t dec_hex_converter_app(void* p) {
- UNUSED(p);
-
- // get event queue
- FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(DecHexConverterEvent));
-
- // allocate state
- DecHexConverterState* dec_hex_converter_state = malloc(sizeof(DecHexConverterState));
-
- // set mutex for plugin state (different threads can access it)
- ValueMutex state_mutex;
- if(!init_mutex(&state_mutex, dec_hex_converter_state, sizeof(dec_hex_converter_state))) {
- FURI_LOG_E("DecHexConverter", "cannot create mutex\r\n");
- furi_message_queue_free(event_queue);
- free(dec_hex_converter_state);
- return 255;
- }
-
- // register callbacks for drawing and input processing
- ViewPort* view_port = view_port_alloc();
- view_port_draw_callback_set(view_port, dec_hex_converter_render_callback, &state_mutex);
- view_port_input_callback_set(view_port, dec_hex_converter_input_callback, event_queue);
-
- // open GUI and register view_port
- Gui* gui = furi_record_open(RECORD_GUI);
- gui_add_view_port(gui, view_port, GuiLayerFullscreen);
-
- dec_hex_converter_init(dec_hex_converter_state);
-
- // main loop
- DecHexConverterEvent event;
- for(bool processing = true; processing;) {
- FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
- DecHexConverterState* dec_hex_converter_state =
- (DecHexConverterState*)acquire_mutex_block(&state_mutex);
-
- if(event_status == FuriStatusOk) {
- // press events
- if(event.type == EventTypeKey) {
- if(event.input.type == InputTypePress) {
- switch(event.input.key) {
- default:
- break;
- case InputKeyUp:
- case InputKeyDown:
- dec_hex_converter_logic_move_cursor_ud(dec_hex_converter_state);
- break;
- case InputKeyRight:
- dec_hex_converter_logic_move_cursor_lr(dec_hex_converter_state, 1);
- break;
- case InputKeyLeft:
- dec_hex_converter_logic_move_cursor_lr(dec_hex_converter_state, -1);
- break;
- case InputKeyOk:
- if(dec_hex_converter_state->cursor < DEC_HEX_CONVERTER_KEY_DEL) {
- // positions from 0 to 15 works as regular numbers (DEC / HEX where applicable)
- // (logic won't allow add numbers > 9 on ModeDec)
- dec_hex_converter_logic_add_number(
- dec_hex_converter_state, dec_hex_converter_state->cursor);
- } else if(dec_hex_converter_state->cursor == DEC_HEX_CONVERTER_KEY_DEL) {
- // del
- dec_hex_converter_logic_del_number(dec_hex_converter_state);
- } else {
- // swap
- dec_hex_converter_logic_swap_mode(dec_hex_converter_state);
- }
-
- dec_hex_converter_logic_convert_number(dec_hex_converter_state);
- break;
- case InputKeyBack:
- processing = false;
- break;
- }
- }
- }
- } else {
- // event timeout
- }
-
- view_port_update(view_port);
- release_mutex(&state_mutex, dec_hex_converter_state);
- }
-
- view_port_enabled_set(view_port, false);
- gui_remove_view_port(gui, view_port);
- furi_record_close(RECORD_GUI);
- view_port_free(view_port);
- furi_message_queue_free(event_queue);
- delete_mutex(&state_mutex);
- free(dec_hex_converter_state);
-
- return 0;
-}
\ No newline at end of file
diff --git a/applications/desktop/animations/animation_manager.c b/applications/desktop/animations/animation_manager.c
index d755be9c0..1e2a521e1 100644
--- a/applications/desktop/animations/animation_manager.c
+++ b/applications/desktop/animations/animation_manager.c
@@ -220,8 +220,7 @@ static bool animation_manager_check_blocking(AnimationManager* animation_manager
furi_assert(blocking_animation);
animation_manager->sd_shown_sd_ok = true;
} else if(!animation_manager->sd_shown_no_db) {
- bool db_exists = storage_common_stat(storage, EXT_PATH("Manifest"), NULL) == FSE_OK;
- if(!db_exists) {
+ if(!storage_file_exists(storage, EXT_PATH("Manifest"))) {
blocking_animation = animation_storage_find_animation(NO_DB_ANIMATION_NAME);
furi_assert(blocking_animation);
animation_manager->sd_shown_no_db = true;
diff --git a/applications/desktop/helpers/slideshow.c b/applications/desktop/helpers/slideshow.c
index 63bd42b55..b4d85cb90 100644
--- a/applications/desktop/helpers/slideshow.c
+++ b/applications/desktop/helpers/slideshow.c
@@ -94,6 +94,10 @@ bool slideshow_is_loaded(Slideshow* slideshow) {
return slideshow->loaded;
}
+bool slideshow_is_one_page(Slideshow* slideshow) {
+ return slideshow->loaded && (slideshow->icon.frame_count == 1);
+}
+
bool slideshow_advance(Slideshow* slideshow) {
uint8_t next_frame = slideshow->current_frame + 1;
if(next_frame < slideshow->icon.frame_count) {
diff --git a/applications/desktop/helpers/slideshow.h b/applications/desktop/helpers/slideshow.h
index eeaac0e8b..9083e0dcf 100644
--- a/applications/desktop/helpers/slideshow.h
+++ b/applications/desktop/helpers/slideshow.h
@@ -9,6 +9,7 @@ Slideshow* slideshow_alloc();
void slideshow_free(Slideshow* slideshow);
bool slideshow_load(Slideshow* slideshow, const char* fspath);
bool slideshow_is_loaded(Slideshow* slideshow);
+bool slideshow_is_one_page(Slideshow* slideshow);
void slideshow_goback(Slideshow* slideshow);
bool slideshow_advance(Slideshow* slideshow);
void slideshow_draw(Slideshow* slideshow, Canvas* canvas, uint8_t x, uint8_t y);
diff --git a/applications/desktop/views/desktop_view_debug.c b/applications/desktop/views/desktop_view_debug.c
index 69c82bdbe..c965432f1 100644
--- a/applications/desktop/views/desktop_view_debug.c
+++ b/applications/desktop/views/desktop_view_debug.c
@@ -23,11 +23,12 @@ void desktop_debug_render(Canvas* canvas, void* model) {
const Version* ver;
char buffer[64];
- static const char* headers[] = {"FW Version Info:", "Dolphin Info:"};
+ static const char* headers[] = {"Device Info:", "Dolphin Info:"};
canvas_set_color(canvas, ColorBlack);
canvas_set_font(canvas, FontPrimary);
- canvas_draw_str(canvas, 2, 9 + STATUS_BAR_Y_SHIFT, headers[m->screen]);
+ canvas_draw_str_aligned(
+ canvas, 64, 1 + STATUS_BAR_Y_SHIFT, AlignCenter, AlignTop, headers[m->screen]);
canvas_set_font(canvas, FontSecondary);
if(m->screen != DesktopViewStatsMeta) {
@@ -44,7 +45,7 @@ void desktop_debug_render(Canvas* canvas, void* model) {
furi_hal_version_get_hw_region_name(),
furi_hal_region_get_name(),
my_name ? my_name : "Unknown");
- canvas_draw_str(canvas, 5, 19 + STATUS_BAR_Y_SHIFT, buffer);
+ canvas_draw_str(canvas, 0, 19 + STATUS_BAR_Y_SHIFT, buffer);
ver = furi_hal_version_get_firmware_version();
const BleGlueC2Info* c2_ver = NULL;
@@ -52,7 +53,7 @@ void desktop_debug_render(Canvas* canvas, void* model) {
c2_ver = ble_glue_get_c2_info();
#endif
if(!ver) {
- canvas_draw_str(canvas, 5, 29 + STATUS_BAR_Y_SHIFT, "No info");
+ canvas_draw_str(canvas, 0, 30 + STATUS_BAR_Y_SHIFT, "No info");
return;
}
@@ -62,7 +63,7 @@ void desktop_debug_render(Canvas* canvas, void* model) {
"%s [%s]",
version_get_version(ver),
version_get_builddate(ver));
- canvas_draw_str(canvas, 5, 28 + STATUS_BAR_Y_SHIFT, buffer);
+ canvas_draw_str(canvas, 0, 30 + STATUS_BAR_Y_SHIFT, buffer);
snprintf(
buffer,
@@ -72,11 +73,11 @@ void desktop_debug_render(Canvas* canvas, void* model) {
version_get_githash(ver),
version_get_gitbranchnum(ver),
c2_ver ? c2_ver->StackTypeString : "");
- canvas_draw_str(canvas, 5, 39 + STATUS_BAR_Y_SHIFT, buffer);
+ canvas_draw_str(canvas, 0, 40 + STATUS_BAR_Y_SHIFT, buffer);
snprintf(
buffer, sizeof(buffer), "[%d] %s", version_get_target(ver), version_get_gitbranch(ver));
- canvas_draw_str(canvas, 5, 50 + STATUS_BAR_Y_SHIFT, buffer);
+ canvas_draw_str(canvas, 0, 50 + STATUS_BAR_Y_SHIFT, buffer);
} else {
Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN);
diff --git a/applications/desktop/views/desktop_view_slideshow.c b/applications/desktop/views/desktop_view_slideshow.c
index 26ae95eae..3462d2f08 100644
--- a/applications/desktop/views/desktop_view_slideshow.c
+++ b/applications/desktop/views/desktop_view_slideshow.c
@@ -35,8 +35,9 @@ static bool desktop_view_slideshow_input(InputEvent* event, void* context) {
furi_assert(event);
DesktopSlideshowView* instance = context;
+ DesktopSlideshowViewModel* model = view_get_model(instance->view);
+ bool update_view = false;
if(event->type == InputTypeShort) {
- DesktopSlideshowViewModel* model = view_get_model(instance->view);
bool end_slideshow = false;
switch(event->key) {
case InputKeyLeft:
@@ -54,15 +55,18 @@ static bool desktop_view_slideshow_input(InputEvent* event, void* context) {
if(end_slideshow) {
instance->callback(DesktopSlideshowCompleted, instance->context);
}
- view_commit_model(instance->view, true);
+ update_view = true;
} else if(event->key == InputKeyOk) {
if(event->type == InputTypePress) {
furi_timer_start(instance->timer, DESKTOP_SLIDESHOW_POWEROFF_SHORT);
} else if(event->type == InputTypeRelease) {
furi_timer_stop(instance->timer);
- furi_timer_start(instance->timer, DESKTOP_SLIDESHOW_POWEROFF_LONG);
+ /*if(!slideshow_is_one_page(model->slideshow)) {
+ furi_timer_start(instance->timer, DESKTOP_SLIDESHOW_POWEROFF_LONG);
+ }*/
}
}
+ view_commit_model(instance->view, update_view);
return true;
}
@@ -79,12 +83,12 @@ static void desktop_view_slideshow_enter(void* context) {
instance->timer =
furi_timer_alloc(desktop_first_start_timer_callback, FuriTimerTypeOnce, instance);
- furi_timer_start(instance->timer, DESKTOP_SLIDESHOW_POWEROFF_LONG);
-
DesktopSlideshowViewModel* model = view_get_model(instance->view);
model->slideshow = slideshow_alloc();
if(!slideshow_load(model->slideshow, SLIDESHOW_FS_PATH)) {
instance->callback(DesktopSlideshowCompleted, instance->context);
+ } else if(!slideshow_is_one_page(model->slideshow)) {
+ furi_timer_start(instance->timer, DESKTOP_SLIDESHOW_POWEROFF_LONG);
}
view_commit_model(instance->view, false);
}
diff --git a/applications/dolphin/helpers/dolphin_state.c b/applications/dolphin/helpers/dolphin_state.c
index 76f38a5fd..95e2f42f4 100644
--- a/applications/dolphin/helpers/dolphin_state.c
+++ b/applications/dolphin/helpers/dolphin_state.c
@@ -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
diff --git a/applications/gui/modules/file_browser_worker.c b/applications/gui/modules/file_browser_worker.c
index d705e5c3a..36df6cc83 100644
--- a/applications/gui/modules/file_browser_worker.c
+++ b/applications/gui/modules/file_browser_worker.c
@@ -99,6 +99,11 @@ static bool browser_folder_check_and_switch(string_t path) {
FileInfo file_info;
Storage* storage = furi_record_open(RECORD_STORAGE);
bool is_root = false;
+
+ if(string_search_rchar(path, '/') == 0) {
+ is_root = true;
+ }
+
while(1) {
// Check if folder is existing and navigate back if not
if(storage_common_stat(storage, string_get_cstr(path), &file_info) == FSE_OK) {
diff --git a/applications/gui/modules/widget.h b/applications/gui/modules/widget.h
index 587fa3c65..03586165c 100755
--- a/applications/gui/modules/widget.h
+++ b/applications/gui/modules/widget.h
@@ -115,8 +115,8 @@ void widget_add_text_box_element(
* @param[in] text Formatted text. Default format: align left, Secondary font.
* The following formats are available:
* "\e#Bold text" - sets bold font before until next '\n' symbol
- * "\ecBold text" - sets center horizontal align before until next '\n' symbol
- * "\erBold text" - sets right horizontal align before until next '\n' symbol
+ * "\ecCenter-aligned text" - sets center horizontal align until the next '\n' symbol
+ * "\erRight-aligned text" - sets right horizontal align until the next '\n' symbol
*/
void widget_add_text_scroll_element(
Widget* widget,
diff --git a/applications/hid_analyzer/application.fam b/applications/hid_analyzer/application.fam
deleted file mode 100644
index 5005190cc..000000000
--- a/applications/hid_analyzer/application.fam
+++ /dev/null
@@ -1,9 +0,0 @@
-App(
- appid="hid_analyzer",
- name="HID Analyzer",
- apptype=FlipperAppType.PLUGIN,
- entry_point="hid_analyzer_app",
- cdefines=["APP_HID_ANALYZER"],
- stack_size=2 * 1024,
- order=40,
-)
diff --git a/applications/hid_analyzer/helpers/decoder_hid.cpp b/applications/hid_analyzer/helpers/decoder_hid.cpp
deleted file mode 100644
index 176bfe0b9..000000000
--- a/applications/hid_analyzer/helpers/decoder_hid.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-#include "decoder_hid.h"
-#include
-
-constexpr uint32_t clocks_in_us = 64;
-
-constexpr uint32_t jitter_time_us = 20;
-constexpr uint32_t min_time_us = 64;
-constexpr uint32_t max_time_us = 80;
-
-constexpr uint32_t min_time = (min_time_us - jitter_time_us) * clocks_in_us;
-constexpr uint32_t mid_time = ((max_time_us - min_time_us) / 2 + min_time_us) * clocks_in_us;
-constexpr uint32_t max_time = (max_time_us + jitter_time_us) * clocks_in_us;
-
-bool DecoderHID::read(uint8_t* data, uint8_t data_size) {
- bool result = false;
- furi_assert(data_size >= 3);
-
- if(ready) {
- result = true;
- hid.decode(
- reinterpret_cast(&stored_data), sizeof(uint32_t) * 3, data, data_size);
- ready = false;
- }
-
- return result;
-}
-
-void DecoderHID::process_front(bool polarity, uint32_t time) {
- if(ready) return;
-
- if(polarity == true) {
- last_pulse_time = time;
- } else {
- last_pulse_time += time;
-
- if(last_pulse_time > min_time && last_pulse_time < max_time) {
- bool pulse;
-
- if(last_pulse_time < mid_time) {
- // 6 pulses
- pulse = false;
- } else {
- // 5 pulses
- pulse = true;
- }
-
- if(last_pulse == pulse) {
- pulse_count++;
-
- if(pulse) {
- if(pulse_count > 4) {
- pulse_count = 0;
- store_data(1);
- }
- } else {
- if(pulse_count > 5) {
- pulse_count = 0;
- store_data(0);
- }
- }
- } else {
- if(last_pulse) {
- if(pulse_count > 2) {
- store_data(1);
- }
- } else {
- if(pulse_count > 3) {
- store_data(0);
- }
- }
-
- pulse_count = 0;
- last_pulse = pulse;
- }
- }
- }
-}
-
-DecoderHID::DecoderHID() {
- reset_state();
-}
-
-void DecoderHID::store_data(bool data) {
- stored_data[0] = (stored_data[0] << 1) | ((stored_data[1] >> 31) & 1);
- stored_data[1] = (stored_data[1] << 1) | ((stored_data[2] >> 31) & 1);
- stored_data[2] = (stored_data[2] << 1) | data;
-
- if(hid.can_be_decoded(reinterpret_cast(&stored_data), sizeof(uint32_t) * 3)) {
- ready = true;
- }
-}
-
-void DecoderHID::reset_state() {
- last_pulse = false;
- pulse_count = 0;
- ready = false;
- last_pulse_time = 0;
-}
diff --git a/applications/hid_analyzer/helpers/decoder_hid.h b/applications/hid_analyzer/helpers/decoder_hid.h
deleted file mode 100644
index 5dcb6c265..000000000
--- a/applications/hid_analyzer/helpers/decoder_hid.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-#include
-#include
-#include "protocols/protocol_hid.h"
-
-class DecoderHID {
-public:
- bool read(uint8_t* data, uint8_t data_size);
- void process_front(bool polarity, uint32_t time);
- DecoderHID();
-
-private:
- uint32_t last_pulse_time = 0;
- bool last_pulse;
- uint8_t pulse_count;
-
- uint32_t stored_data[3] = {0, 0, 0};
- void store_data(bool data);
-
- std::atomic ready;
-
- void reset_state();
- ProtocolHID hid;
-};
diff --git a/applications/hid_analyzer/helpers/hid_reader.cpp b/applications/hid_analyzer/helpers/hid_reader.cpp
deleted file mode 100644
index 890d7c651..000000000
--- a/applications/hid_analyzer/helpers/hid_reader.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-#include "hid_reader.h"
-#include
-#include
-#include
-
-/**
- * @brief private violation assistant for HIDReader
- */
-struct HIDReaderAccessor {
- static void decode(HIDReader& hid_reader, bool polarity) {
- hid_reader.decode(polarity);
- }
-};
-
-void HIDReader::decode(bool polarity) {
- uint32_t current_dwt_value = DWT->CYCCNT;
- uint32_t period = current_dwt_value - last_dwt_value;
- last_dwt_value = current_dwt_value;
-
- decoder_hid.process_front(polarity, period);
-
- detect_ticks++;
-}
-
-bool HIDReader::switch_timer_elapsed() {
- const uint32_t seconds_to_switch = furi_kernel_get_tick_frequency() * 2.0f;
- return (furi_get_tick() - switch_os_tick_last) > seconds_to_switch;
-}
-
-void HIDReader::switch_timer_reset() {
- switch_os_tick_last = furi_get_tick();
-}
-
-void HIDReader::switch_mode() {
- switch(type) {
- case Type::Normal:
- type = Type::Indala;
- furi_hal_rfid_change_read_config(62500.0f, 0.25f);
- break;
- case Type::Indala:
- type = Type::Normal;
- furi_hal_rfid_change_read_config(125000.0f, 0.5f);
- break;
- }
-
- switch_timer_reset();
-}
-
-static void comparator_trigger_callback(bool level, void* comp_ctx) {
- HIDReader* _this = static_cast(comp_ctx);
-
- HIDReaderAccessor::decode(*_this, !level);
-}
-
-HIDReader::HIDReader() {
-}
-
-void HIDReader::start() {
- type = Type::Normal;
-
- furi_hal_rfid_pins_read();
- furi_hal_rfid_tim_read(125000, 0.5);
- furi_hal_rfid_tim_read_start();
- start_comparator();
-
- switch_timer_reset();
- last_read_count = 0;
-}
-
-void HIDReader::start_forced(HIDReader::Type _type) {
- start();
- if(_type == Type::Indala) {
- switch_mode();
- }
-}
-
-void HIDReader::stop() {
- furi_hal_rfid_pins_reset();
- furi_hal_rfid_tim_read_stop();
- furi_hal_rfid_tim_reset();
- stop_comparator();
-}
-
-bool HIDReader::read(LfrfidKeyType* _type, uint8_t* data, uint8_t data_size, bool switch_enable) {
- bool result = false;
- bool something_read = false;
-
- if(decoder_hid.read(data, data_size)) {
- *_type = LfrfidKeyType::KeyH10301; // should be an OK temp
- something_read = true;
- }
-
- // validation
- if(something_read) {
- switch_timer_reset();
-
- if(last_read_type == *_type && memcmp(last_read_data, data, data_size) == 0) {
- last_read_count = last_read_count + 1;
-
- if(last_read_count > 2) {
- result = true;
- }
- } else {
- last_read_type = *_type;
- memcpy(last_read_data, data, data_size);
- last_read_count = 0;
- }
- }
-
- // mode switching
- if(switch_enable && switch_timer_elapsed()) {
- switch_mode();
- last_read_count = 0;
- }
-
- return result;
-}
-
-bool HIDReader::detect() {
- bool detected = false;
- if(detect_ticks > 10) {
- detected = true;
- }
- detect_ticks = 0;
-
- return detected;
-}
-
-bool HIDReader::any_read() {
- return last_read_count > 0;
-}
-
-void HIDReader::start_comparator(void) {
- furi_hal_rfid_comp_set_callback(comparator_trigger_callback, this);
- last_dwt_value = DWT->CYCCNT;
-
- furi_hal_rfid_comp_start();
-}
-
-void HIDReader::stop_comparator(void) {
- furi_hal_rfid_comp_stop();
- furi_hal_rfid_comp_set_callback(NULL, NULL);
-}
diff --git a/applications/hid_analyzer/helpers/hid_reader.h b/applications/hid_analyzer/helpers/hid_reader.h
deleted file mode 100644
index 99dbeb08d..000000000
--- a/applications/hid_analyzer/helpers/hid_reader.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#pragma once
-#include "decoder_hid.h"
-#include "key_info.h"
-
-//#define RFID_GPIO_DEBUG 1
-
-class HIDReader {
-public:
- enum class Type : uint8_t {
- Normal,
- Indala,
- };
-
- HIDReader();
- void start();
- void start_forced(HIDReader::Type type);
- void stop();
- bool read(LfrfidKeyType* _type, uint8_t* data, uint8_t data_size, bool switch_enable = true);
-
- bool detect();
- bool any_read();
-
-private:
- friend struct HIDReaderAccessor;
-
- DecoderHID decoder_hid;
-
- uint32_t last_dwt_value;
-
- void start_comparator(void);
- void stop_comparator(void);
-
- void decode(bool polarity);
-
- uint32_t detect_ticks;
-
- uint32_t switch_os_tick_last;
- bool switch_timer_elapsed();
- void switch_timer_reset();
- void switch_mode();
-
- LfrfidKeyType last_read_type;
- uint8_t last_read_data[LFRFID_KEY_SIZE];
- uint8_t last_read_count;
-
- Type type = Type::Normal;
-};
diff --git a/applications/hid_analyzer/helpers/hid_worker.cpp b/applications/hid_analyzer/helpers/hid_worker.cpp
deleted file mode 100644
index 42230858c..000000000
--- a/applications/hid_analyzer/helpers/hid_worker.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-#include "hid_worker.h"
-
-HIDWorker::HIDWorker() {
-}
-
-HIDWorker::~HIDWorker() {
-}
-
-void HIDWorker::start_read() {
- reader.start();
-}
-
-bool HIDWorker::read() {
- static const uint8_t data_size = LFRFID_KEY_SIZE;
- uint8_t data[data_size] = {0};
- LfrfidKeyType type;
-
- bool result = reader.read(&type, data, data_size);
-
- if(result) {
- key.set_type(type);
- key.set_data(data, data_size);
- };
-
- return result;
-}
-
-bool HIDWorker::detect() {
- return reader.detect();
-}
-
-bool HIDWorker::any_read() {
- return reader.any_read();
-}
-
-void HIDWorker::stop_read() {
- reader.stop();
-}
diff --git a/applications/hid_analyzer/helpers/hid_worker.h b/applications/hid_analyzer/helpers/hid_worker.h
deleted file mode 100644
index e6674bd1b..000000000
--- a/applications/hid_analyzer/helpers/hid_worker.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-#include "key_info.h"
-#include "rfid_key.h"
-#include "hid_reader.h"
-
-class HIDWorker {
-public:
- HIDWorker();
- ~HIDWorker();
-
- void start_read();
- bool read();
- bool detect();
- bool any_read();
- void stop_read();
-
- RfidKey key;
-
-private:
- HIDReader reader;
-};
diff --git a/applications/hid_analyzer/helpers/key_info.h b/applications/hid_analyzer/helpers/key_info.h
deleted file mode 100644
index e465011d0..000000000
--- a/applications/hid_analyzer/helpers/key_info.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-#include
-
-static const uint8_t LFRFID_KEY_SIZE = 8;
-static const uint8_t LFRFID_KEY_NAME_SIZE = 22;
-
-enum class LfrfidKeyType : uint8_t {
- KeyEM4100,
- KeyH10301,
- KeyI40134,
-};
-
-const char* lfrfid_key_get_type_string(LfrfidKeyType type);
-const char* lfrfid_key_get_manufacturer_string(LfrfidKeyType type);
-bool lfrfid_key_get_string_type(const char* string, LfrfidKeyType* type);
-uint8_t lfrfid_key_get_type_data_count(LfrfidKeyType type);
diff --git a/applications/hid_analyzer/helpers/osc_fsk.h b/applications/hid_analyzer/helpers/osc_fsk.h
deleted file mode 100644
index eaaaa10ad..000000000
--- a/applications/hid_analyzer/helpers/osc_fsk.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-#include
-
-/**
- * This code tries to fit the periods into a given number of cycles (phases) by taking cycles from the next cycle of periods.
- */
-class OscFSK {
-public:
- /**
- * Get next period
- * @param bit bit value
- * @param period return period
- * @return bool whether to advance to the next bit
- */
- bool next(bool bit, uint16_t* period);
-
- /**
- * FSK ocillator constructor
- *
- * @param freq_low bit 0 freq
- * @param freq_hi bit 1 freq
- * @param osc_phase_max max oscillator phase
- */
- OscFSK(uint16_t freq_low, uint16_t freq_hi, uint16_t osc_phase_max);
-
-private:
- const uint16_t freq[2];
- const uint16_t osc_phase_max;
- int32_t osc_phase_current;
-};
diff --git a/applications/hid_analyzer/helpers/protocols/protocol_generic.h b/applications/hid_analyzer/helpers/protocols/protocol_generic.h
deleted file mode 100644
index d593f7089..000000000
--- a/applications/hid_analyzer/helpers/protocols/protocol_generic.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#pragma once
-#include "stdint.h"
-#include "stdbool.h"
-
-class ProtocolGeneric {
-public:
- /**
- * @brief Get the encoded data size
- *
- * @return uint8_t size of encoded data in bytes
- */
- virtual uint8_t get_encoded_data_size() = 0;
-
- /**
- * @brief Get the decoded data size
- *
- * @return uint8_t size of decoded data in bytes
- */
- virtual uint8_t get_decoded_data_size() = 0;
-
- /**
- * @brief encode decoded data
- *
- * @param decoded_data
- * @param decoded_data_size
- * @param encoded_data
- * @param encoded_data_size
- */
- virtual void encode(
- const uint8_t* decoded_data,
- const uint8_t decoded_data_size,
- uint8_t* encoded_data,
- const uint8_t encoded_data_size) = 0;
-
- /**
- * @brief decode encoded data
- *
- * @param encoded_data
- * @param encoded_data_size
- * @param decoded_data
- * @param decoded_data_size
- */
- virtual void decode(
- const uint8_t* encoded_data,
- const uint8_t encoded_data_size,
- uint8_t* decoded_data,
- const uint8_t decoded_data_size) = 0;
-
- /**
- * @brief fast check that data can be correctly decoded
- *
- * @param encoded_data
- * @param encoded_data_size
- * @return true - can be correctly decoded
- * @return false - cannot be correctly decoded
- */
- virtual bool can_be_decoded(const uint8_t* encoded_data, const uint8_t encoded_data_size) = 0;
-
- virtual ~ProtocolGeneric(){};
-};
diff --git a/applications/hid_analyzer/helpers/protocols/protocol_hid.cpp b/applications/hid_analyzer/helpers/protocols/protocol_hid.cpp
deleted file mode 100644
index e60eafa29..000000000
--- a/applications/hid_analyzer/helpers/protocols/protocol_hid.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-#include "protocol_hid.h"
-#include
-
-typedef uint32_t HIDCardData;
-constexpr uint8_t HIDCount = 3;
-constexpr uint8_t HIDBitSize = sizeof(HIDCardData) * 8;
-
-uint8_t ProtocolHID::get_encoded_data_size() {
- return sizeof(HIDCardData) * HIDCount;
-}
-
-uint8_t ProtocolHID::get_decoded_data_size() {
- return 3;
-}
-
-void ProtocolHID::encode(
- const uint8_t* decoded_data,
- const uint8_t decoded_data_size,
- uint8_t* encoded_data,
- const uint8_t encoded_data_size) {
- UNUSED(decoded_data);
- UNUSED(decoded_data_size);
- UNUSED(encoded_data);
- UNUSED(encoded_data_size);
- // bob!
-}
-
-void ProtocolHID::decode(
- const uint8_t* encoded_data,
- const uint8_t encoded_data_size,
- uint8_t* decoded_data,
- const uint8_t decoded_data_size) {
- furi_check(decoded_data_size >= get_decoded_data_size());
- furi_check(encoded_data_size >= get_encoded_data_size());
-
- // header check
- int16_t second1pos = find_second_1(encoded_data);
-
- if((*(encoded_data + 1) & 0b1100) != 0x08) {
- *decoded_data = 37;
- } else {
- *decoded_data = (36 - (second1pos - 8));
- }
-}
-
-int16_t ProtocolHID::find_second_1(const uint8_t* encoded_data) {
- if((*(encoded_data + 1) & 0b11) == 0b10) {
- return 8;
- } else {
- for(int8_t i = 3; i >= 0; i--) {
- if(((*(encoded_data + 0) >> (2 * i)) & 0b11) == 0b10) {
- return (12 - i);
- }
- }
- for(int8_t i = 3; i >= 0; i--) {
- if(((*(encoded_data + 7) >> (2 * i)) & 0b11) == 0b10) {
- return (16 - i);
- }
- }
- for(int8_t i = 3; i >= 2; i--) {
- if(((*(encoded_data + 6) >> (2 * i)) & 0b11) == 0b10) {
- return (20 - i);
- }
- }
- }
-
- return -1;
-}
-
-bool ProtocolHID::can_be_decoded(const uint8_t* encoded_data, const uint8_t encoded_data_size) {
- furi_check(encoded_data_size >= get_encoded_data_size());
-
- const HIDCardData* card_data = reinterpret_cast(encoded_data);
-
- // header check
- int16_t second1pos = -1;
- // packet pre-preamble
- if(*(encoded_data + 3) != 0x1D) {
- return false;
- }
-
- // packet preamble
- if(*(encoded_data + 2) != 0x55) { // first four 0s mandatory in preamble
- return false;
- }
-
- if((*(encoded_data + 1) & 0xF0) != 0x50) { // next two 0s mandatory in preamble
- return false;
- }
-
- if((*(encoded_data + 1) & 0b1100) != 0x08) { // if it's not a 1...
- // either it's a 37-bit or invalid
- // so just continue with the manchester encoding checks
- } else { // it is a 1. so it could be anywhere between 26 and 36 bit encoding. or invalid.
- // we need to find the location of the second 1
- second1pos = find_second_1(encoded_data);
- }
-
- if(second1pos == -1) {
- // we're 37 bit or invalid
- }
-
- // data decoding. ensure all is properly manchester encoded
- uint32_t result = 0;
-
- // decode from word 0
- // coded with 01 = 0, 10 = 1 transitions
- for(int8_t i = 11; i >= 0; i--) {
- switch((*(card_data + 0) >> (2 * i)) & 0b11) {
- case 0b01:
- result = (result << 1) | 0;
- break;
- case 0b10:
- result = (result << 1) | 1;
- break;
- default:
- return false;
- break;
- }
- }
-
- // decode from word 1
- // coded with 01 = 0, 10 = 1 transitions
- for(int8_t i = 15; i >= 0; i--) {
- switch((*(card_data + 1) >> (2 * i)) & 0b11) {
- case 0b01:
- result = (result << 1) | 0;
- break;
- case 0b10:
- result = (result << 1) | 1;
- break;
- default:
- return false;
- break;
- }
- }
-
- // decode from word 2
- // coded with 01 = 0, 10 = 1 transitions
- for(int8_t i = 15; i >= 0; i--) {
- switch((*(card_data + 2) >> (2 * i)) & 0b11) {
- case 0b01:
- result = (result << 1) | 0;
- break;
- case 0b10:
- result = (result << 1) | 1;
- break;
- default:
- return false;
- break;
- }
- }
-
- return true;
-}
diff --git a/applications/hid_analyzer/helpers/protocols/protocol_hid.h b/applications/hid_analyzer/helpers/protocols/protocol_hid.h
deleted file mode 100644
index 0e2636d5b..000000000
--- a/applications/hid_analyzer/helpers/protocols/protocol_hid.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-#include "protocol_generic.h"
-
-class ProtocolHID : public ProtocolGeneric {
-public:
- uint8_t get_encoded_data_size() final;
- uint8_t get_decoded_data_size() final;
-
- void encode(
- const uint8_t* decoded_data,
- const uint8_t decoded_data_size,
- uint8_t* encoded_data,
- const uint8_t encoded_data_size) final;
-
- void decode(
- const uint8_t* encoded_data,
- const uint8_t encoded_data_size,
- uint8_t* decoded_data,
- const uint8_t decoded_data_size) final;
-
- bool can_be_decoded(const uint8_t* encoded_data, const uint8_t encoded_data_size) final;
-
-private:
- int16_t find_second_1(const uint8_t* encoded_data);
-};
diff --git a/applications/hid_analyzer/helpers/pulse_joiner.h b/applications/hid_analyzer/helpers/pulse_joiner.h
deleted file mode 100644
index 1639d8371..000000000
--- a/applications/hid_analyzer/helpers/pulse_joiner.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#pragma once
-#include "stdint.h"
-
-class PulseJoiner {
-public:
- /**
- * @brief Push timer pulse. First negative pulse is ommited.
- *
- * @param polarity pulse polarity: true = high2low, false = low2high
- * @param period overall period time in timer clicks
- * @param pulse pulse time in timer clicks
- *
- * @return true - next pulse can and must be popped immediatly
- */
- bool push_pulse(bool polarity, uint16_t period, uint16_t pulse);
-
- /**
- * @brief Get the next timer pulse. Call only if push_pulse returns true.
- *
- * @param period overall period time in timer clicks
- * @param pulse pulse time in timer clicks
- */
- void pop_pulse(uint16_t* period, uint16_t* pulse);
-
- PulseJoiner();
-
-private:
- struct Pulse {
- bool polarity;
- uint16_t time;
- };
-
- uint8_t pulse_index = 0;
- static const uint8_t pulse_max = 6;
- Pulse pulses[pulse_max];
-};
diff --git a/applications/hid_analyzer/helpers/rfid_key.h b/applications/hid_analyzer/helpers/rfid_key.h
deleted file mode 100644
index 29b87cf9c..000000000
--- a/applications/hid_analyzer/helpers/rfid_key.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#pragma once
-#include "key_info.h"
-#include
-
-class RfidKey {
-public:
- RfidKey();
- ~RfidKey();
-
- void set_type(LfrfidKeyType type);
- void set_data(const uint8_t* data, const uint8_t data_size);
- void set_name(const char* name);
-
- LfrfidKeyType get_type();
- const uint8_t* get_data();
- const char* get_type_text();
- uint8_t get_type_data_count() const;
- char* get_name();
- uint8_t get_name_length();
- void clear();
- RfidKey& operator=(const RfidKey& rhs);
-
-private:
- std::array data;
- LfrfidKeyType type;
- char name[LFRFID_KEY_NAME_SIZE + 1];
-};
diff --git a/applications/hid_analyzer/helpers/rfid_timer_emulator.h b/applications/hid_analyzer/helpers/rfid_timer_emulator.h
deleted file mode 100644
index 874a4c3dd..000000000
--- a/applications/hid_analyzer/helpers/rfid_timer_emulator.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-#include
-#include "key_info.h"
-#include "encoder_generic.h"
-#include "encoder_emmarin.h"
-#include "encoder_hid_h10301.h"
-#include "encoder_indala_40134.h"
-#include "pulse_joiner.h"
-#include