From aaa444f3f04c73ecf8730cd69f3171db398bfae6 Mon Sep 17 00:00:00 2001 From: HaxSam Date: Thu, 7 Mar 2024 02:31:34 +0100 Subject: [PATCH 01/16] added new rgb property --- .../scenes/momentum_app_scene_misc_screen.c | 5 +++++ targets/f7/furi_hal/furi_hal_info.c | 22 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/applications/main/momentum_app/scenes/momentum_app_scene_misc_screen.c b/applications/main/momentum_app/scenes/momentum_app_scene_misc_screen.c index ef0d04468a..4f39c38c07 100644 --- a/applications/main/momentum_app/scenes/momentum_app_scene_misc_screen.c +++ b/applications/main/momentum_app/scenes/momentum_app_scene_misc_screen.c @@ -1,3 +1,4 @@ +#include #include "../momentum_app.h" enum VarItemListIndex { @@ -55,6 +56,10 @@ static void momentum_app_scene_misc_screen_lcd_color_changed(VariableItem* item, variable_item_set_current_value_text(item, lcd_colors[index].name); rgb_backlight_set_color(led, &lcd_colors[index].color); app->save_backlight = true; + + Expansion* expansion = furi_record_open(RECORD_EXPANSION); + expansion_disable(expansion); + expansion_enable(expansion); } static void momentum_app_scene_misc_screen_lcd_color_0_changed(VariableItem* item) { momentum_app_scene_misc_screen_lcd_color_changed(item, 0); diff --git a/targets/f7/furi_hal/furi_hal_info.c b/targets/f7/furi_hal/furi_hal_info.c index 4908cca69d..385c19eae3 100644 --- a/targets/f7/furi_hal/furi_hal_info.c +++ b/targets/f7/furi_hal/furi_hal_info.c @@ -1,3 +1,6 @@ +#include "SK6805.h" +#include "colors.h" +#include "property.h" #include #include #include @@ -9,6 +12,10 @@ #include #include +#include "momentum/momentum.h" +#include "rgb_backlight.h" +#include + FURI_WEAK void furi_hal_info_get_api_version(uint16_t* major, uint16_t* minor) { *major = 0; *minor = 0; @@ -64,6 +71,21 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) { property_value_out( &property_context, "%d", 2, "hardware", "color", furi_hal_version_get_hw_color()); + // RGB Settings + property_value_out(&property_context, "%d", 3, "hardware", "rgb", "enabled", momentum_settings.rgb_backlight); + + for(int i = 0; i < SK6805_get_led_count(); i++){ + RgbColor rgb; + rgb_backlight_get_color(i, &rgb); + + uint32_t led_value = 0; + memcpy(((void *)&led_value) + 1, &rgb, sizeof(RgbColor)); + + char id_string[2] = {'0'+i, '\0'}; + + property_value_out(&property_context, "%06X", 4, "hardware", "rgb", "led", id_string, __REV(led_value)); + } + if(sep == '.') { property_value_out( &property_context, From 4f7eb770711f0f6d07c66a1018618918a604806f Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Thu, 7 Mar 2024 08:57:32 +0200 Subject: [PATCH 02/16] Fix troika 4K keys (#3499) --- .../main/nfc/plugins/supported_cards/troika.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/applications/main/nfc/plugins/supported_cards/troika.c b/applications/main/nfc/plugins/supported_cards/troika.c index 50806e137d..758f824b70 100644 --- a/applications/main/nfc/plugins/supported_cards/troika.c +++ b/applications/main/nfc/plugins/supported_cards/troika.c @@ -73,14 +73,14 @@ static const MfClassicKeyPair troika_4k_keys[] = { {.a = 0x7A38E3511A38, .b = 0xAB16584C972A}, //30 {.a = 0x7545DF809202, .b = 0xECF751084A80}, //31 {.a = 0x5125974CD391, .b = 0xD3EAFB5DF46D}, //32 - {.a = 0xFFFFFFFFFFFF, .b = 0xFFFFFFFFFFFF}, //33 - {.a = 0xFFFFFFFFFFFF, .b = 0xFFFFFFFFFFFF}, //34 - {.a = 0xFFFFFFFFFFFF, .b = 0xFFFFFFFFFFFF}, //35 - {.a = 0xFFFFFFFFFFFF, .b = 0xFFFFFFFFFFFF}, //36 - {.a = 0xFFFFFFFFFFFF, .b = 0xFFFFFFFFFFFF}, //37 - {.a = 0xFFFFFFFFFFFF, .b = 0xFFFFFFFFFFFF}, //38 - {.a = 0xFFFFFFFFFFFF, .b = 0xFFFFFFFFFFFF}, //39 - {.a = 0xFFFFFFFFFFFF, .b = 0xFFFFFFFFFFFF}, //40 + {.a = 0x7A86AA203788, .b = 0xE41242278CA2}, //33 + {.a = 0xAFCEF64C9913, .b = 0x9DB96DCA4324}, //34 + {.a = 0x04EAA462F70B, .b = 0xAC17B93E2FAE}, //35 + {.a = 0xE734C210F27E, .b = 0x29BA8C3E9FDA}, //36 + {.a = 0xD5524F591EED, .b = 0x5DAF42861B4D}, //37 + {.a = 0xE4821A377B75, .b = 0xE8709E486465}, //38 + {.a = 0x518DC6EEA089, .b = 0x97C64AC98CA4}, //39 + {.a = 0xBB52F8CCE07F, .b = 0x6B6119752C70}, //40 }; static bool troika_get_card_config(TroikaCardConfig* config, MfClassicType type) { From 99ce5a30ce474081bfa3a87aa7226bc32eef445c Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Thu, 7 Mar 2024 21:15:12 +0000 Subject: [PATCH 03/16] Momentum Settings: Variable int/enum size --- lib/momentum/momentum.h | 5 ----- lib/momentum/settings.c | 37 ++++++++++++++++++------------------- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/lib/momentum/momentum.h b/lib/momentum/momentum.h index 1bbbde2d40..bc9dea329f 100644 --- a/lib/momentum/momentum.h +++ b/lib/momentum/momentum.h @@ -43,11 +43,6 @@ typedef enum { SpiCount, } SpiHandle; -_Static_assert(sizeof(MenuStyle) == sizeof(uint8_t), "enum too big, fix load/save"); -_Static_assert(sizeof(BatteryIcon) == sizeof(uint8_t), "enum too big, fix load/save"); -_Static_assert(sizeof(SpiHandle) == sizeof(uint8_t), "enum too big, fix load/save"); -_Static_assert(sizeof(FuriHalSerialId) == sizeof(uint8_t), "enum too big, fix load/save"); - typedef struct { char asset_pack[ASSET_PACKS_NAME_LEN]; uint32_t anim_speed; diff --git a/lib/momentum/settings.c b/lib/momentum/settings.c index f5b1d3de63..898b98c819 100644 --- a/lib/momentum/settings.c +++ b/lib/momentum/settings.c @@ -47,7 +47,6 @@ typedef enum { momentum_settings_type_str, momentum_settings_type_int, momentum_settings_type_uint, - momentum_settings_type_enum, momentum_settings_type_bool, } momentum_settings_type; @@ -60,19 +59,20 @@ static const struct { struct { int32_t i_min; int32_t i_max; + uint8_t i_sz; }; struct { uint32_t u_min; uint32_t u_max; + uint8_t u_sz; }; - uint8_t e_cnt; }; -#define clamp(t, min, max) .t##_min = min, .t##_max = max #define setting(t, n) .type = momentum_settings_type##t, .key = #n, .val = &momentum_settings.n #define setting_str(n) setting(_str, n), .str_len = sizeof(momentum_settings.n) -#define setting_int(n, min, max) setting(_int, n), clamp(i, min, max) -#define setting_uint(n, min, max) setting(_uint, n), clamp(u, min, max) -#define setting_enum(n, cnt) setting(_enum, n), .e_cnt = cnt +#define num(t, n, min, max) .t##_min = min, .t##_max = max, .t##_sz = sizeof(momentum_settings.n) +#define setting_int(n, min, max) setting(_int, n), num(i, n, min, max) +#define setting_uint(n, min, max) setting(_uint, n), num(u, n, min, max) +#define setting_enum(n, cnt) setting_uint(n, 0, cnt - 1) #define setting_bool(n) setting(_bool, n) } momentum_settings_entries[] = { {setting_str(asset_pack)}, @@ -131,15 +131,13 @@ void momentum_settings_load() { break; case momentum_settings_type_int: ok = flipper_format_read_int32(file, entry.key, &val_int, 1); - if(ok) *(int32_t*)entry.val = CLAMP(val_int, entry.i_max, entry.i_min); + val_int = CLAMP(val_int, entry.i_max, entry.i_min); + if(ok) memcpy(entry.val, &val_int, entry.i_sz); break; case momentum_settings_type_uint: ok = flipper_format_read_uint32(file, entry.key, &val_uint, 1); - if(ok) *(uint32_t*)entry.val = CLAMP(val_uint, entry.u_max, entry.u_min); - break; - case momentum_settings_type_enum: - ok = flipper_format_read_uint32(file, entry.key, &val_uint, 1); - if(ok) *(uint8_t*)entry.val = CLAMP(val_uint, entry.e_cnt - 1U, 0U); + val_uint = CLAMP(val_uint, entry.u_max, entry.u_min); + if(ok) memcpy(entry.val, &val_uint, entry.u_sz); break; case momentum_settings_type_bool: ok = flipper_format_read_bool(file, entry.key, &val_bool, 1); @@ -164,7 +162,8 @@ void momentum_settings_save() { FlipperFormat* file = flipper_format_file_alloc(storage); if(flipper_format_file_open_always(file, MOMENTUM_SETTINGS_PATH)) { - uint32_t tmp_enum; + int32_t tmp_int; + uint32_t tmp_uint; for(size_t entry_i = 0; entry_i < COUNT_OF(momentum_settings_entries); entry_i++) { #define entry momentum_settings_entries[entry_i] switch(entry.type) { @@ -172,14 +171,14 @@ void momentum_settings_save() { flipper_format_write_string_cstr(file, entry.key, (char*)entry.val); break; case momentum_settings_type_int: - flipper_format_write_int32(file, entry.key, (int32_t*)entry.val, 1); + tmp_int = 0; + memcpy(&tmp_int, entry.val, entry.i_sz); + flipper_format_write_int32(file, entry.key, &tmp_int, 1); break; case momentum_settings_type_uint: - flipper_format_write_uint32(file, entry.key, (uint32_t*)entry.val, 1); - break; - case momentum_settings_type_enum: - tmp_enum = *(uint8_t*)entry.val; - flipper_format_write_uint32(file, entry.key, &tmp_enum, 1); + tmp_uint = 0; + memcpy(&tmp_uint, entry.val, entry.u_sz); + flipper_format_write_uint32(file, entry.key, &tmp_uint, 1); break; case momentum_settings_type_bool: flipper_format_write_bool(file, entry.key, (bool*)entry.val, 1); From bf045ccf51a17f993106afc6d26a69adb36271da Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Thu, 7 Mar 2024 21:34:22 +0000 Subject: [PATCH 04/16] Add VGM color settings backend --- lib/momentum/momentum.h | 11 +++++++++++ lib/momentum/settings.c | 6 ++++++ lib/toolbox/colors.h | 9 +++++++++ targets/f7/furi_hal/furi_hal_info.c | 29 +++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+) diff --git a/lib/momentum/momentum.h b/lib/momentum/momentum.h index bc9dea329f..c5dc325262 100644 --- a/lib/momentum/momentum.h +++ b/lib/momentum/momentum.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #ifdef __cplusplus @@ -43,6 +44,13 @@ typedef enum { SpiCount, } SpiHandle; +typedef enum { + VgmColorModeDefault, + VgmColorModeRgbBacklight, + VgmColorModeCustom, + VgmColorModeCount, +} VgmColorMode; + typedef struct { char asset_pack[ASSET_PACKS_NAME_LEN]; uint32_t anim_speed; @@ -79,6 +87,9 @@ typedef struct { FuriHalSerialId uart_esp_channel; FuriHalSerialId uart_nmea_channel; bool file_naming_prefix_after; + VgmColorMode vgm_color_mode; + Rgb565Color vgm_color_fg; + Rgb565Color vgm_color_bg; } MomentumSettings; typedef struct { diff --git a/lib/momentum/settings.c b/lib/momentum/settings.c index 898b98c819..3caaf1d345 100644 --- a/lib/momentum/settings.c +++ b/lib/momentum/settings.c @@ -41,6 +41,9 @@ MomentumSettings momentum_settings = { .uart_esp_channel = FuriHalSerialIdUsart, // pin 13,14 .uart_nmea_channel = FuriHalSerialIdUsart, // pin 13,14 .file_naming_prefix_after = false, // Before + .vgm_color_mode = VgmColorModeDefault, // Default + .vgm_color_fg.value = 0xFC00, // Default Orange + .vgm_color_bg.value = 0x0000, // Default Black }; typedef enum { @@ -110,6 +113,9 @@ static const struct { {setting_enum(uart_esp_channel, FuriHalSerialIdMax)}, {setting_enum(uart_nmea_channel, FuriHalSerialIdMax)}, {setting_bool(file_naming_prefix_after)}, + {setting_enum(vgm_color_mode, VgmColorModeCount)}, + {setting_uint(vgm_color_fg, 0x0000, 0xFFFF)}, + {setting_uint(vgm_color_bg, 0x0000, 0xFFFF)}, }; void momentum_settings_load() { diff --git a/lib/toolbox/colors.h b/lib/toolbox/colors.h index f53f44873c..c2acec0bb4 100644 --- a/lib/toolbox/colors.h +++ b/lib/toolbox/colors.h @@ -25,6 +25,15 @@ int hsvcmp(const HsvColor* a, const HsvColor* b); void hsv2rgb(const HsvColor* hsv, RgbColor* rgb); void rgb2hsv(const RgbColor* rgb, HsvColor* hsv); +typedef union { + uint16_t value; + struct { + uint8_t r : 5; + uint8_t g : 6; + uint8_t b : 5; + }; +} Rgb565Color; + #ifdef __cplusplus } #endif diff --git a/targets/f7/furi_hal/furi_hal_info.c b/targets/f7/furi_hal/furi_hal_info.c index 385c19eae3..7c33c5840a 100644 --- a/targets/f7/furi_hal/furi_hal_info.c +++ b/targets/f7/furi_hal/furi_hal_info.c @@ -86,6 +86,35 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) { property_value_out(&property_context, "%06X", 4, "hardware", "rgb", "led", id_string, __REV(led_value)); } + // VGM Settings + property_value_out( + &property_context, + "%d", + 4, + "hardware", + "vgm", + "color", + "mode", + momentum_settings.vgm_color_mode); + property_value_out( + &property_context, + "%04X", + 4, + "hardware", + "vgm", + "color", + "fg", + momentum_settings.vgm_color_fg.value); + property_value_out( + &property_context, + "%04X", + 4, + "hardware", + "vgm", + "color", + "bg", + momentum_settings.vgm_color_bg.value); + if(sep == '.') { property_value_out( &property_context, From 47bd1696ba58b91cc0cf0766ace8759ec764593b Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Thu, 7 Mar 2024 21:34:52 +0000 Subject: [PATCH 05/16] Tidy up RGB screen property info --- targets/f7/furi_hal/furi_hal_info.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/targets/f7/furi_hal/furi_hal_info.c b/targets/f7/furi_hal/furi_hal_info.c index 7c33c5840a..3780c96e12 100644 --- a/targets/f7/furi_hal/furi_hal_info.c +++ b/targets/f7/furi_hal/furi_hal_info.c @@ -72,18 +72,25 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) { &property_context, "%d", 2, "hardware", "color", furi_hal_version_get_hw_color()); // RGB Settings - property_value_out(&property_context, "%d", 3, "hardware", "rgb", "enabled", momentum_settings.rgb_backlight); - - for(int i = 0; i < SK6805_get_led_count(); i++){ + property_value_out( + &property_context, + "%d", + 4, + "hardware", + "screen", + "rgb", + "enabled", + momentum_settings.rgb_backlight); + for(int i = 0; i < SK6805_get_led_count(); i++) { RgbColor rgb; rgb_backlight_get_color(i, &rgb); uint32_t led_value = 0; - memcpy(((void *)&led_value) + 1, &rgb, sizeof(RgbColor)); + memcpy(((void*)&led_value) + 1, &rgb, sizeof(RgbColor)); - char id_string[2] = {'0'+i, '\0'}; - - property_value_out(&property_context, "%06X", 4, "hardware", "rgb", "led", id_string, __REV(led_value)); + char led_string[5] = {'l', 'e', 'd', '0' + i, '\0'}; + property_value_out( + &property_context, "%06X", 4, "hardware", "screen", "rgb", led_string, __REV(led_value)); } // VGM Settings From d09a8f25172326234ea76c8f0f7212c1db94eb4e Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Thu, 7 Mar 2024 23:27:55 +0000 Subject: [PATCH 06/16] Fix some imports --- applications/main/momentum_app/momentum_app.c | 2 ++ applications/main/momentum_app/momentum_app.h | 2 ++ .../momentum_app/scenes/momentum_app_scene_misc_screen.c | 9 ++++----- .../scenes/momentum_app_scene_misc_screen_color.c | 4 ++++ targets/f7/furi_hal/furi_hal_info.c | 9 ++++----- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/applications/main/momentum_app/momentum_app.c b/applications/main/momentum_app/momentum_app.c index 3692b08aec..5502364457 100644 --- a/applications/main/momentum_app/momentum_app.c +++ b/applications/main/momentum_app/momentum_app.c @@ -163,6 +163,7 @@ MomentumApp* momentum_app_alloc() { MomentumApp* app = malloc(sizeof(MomentumApp)); app->gui = furi_record_open(RECORD_GUI); app->dialogs = furi_record_open(RECORD_DIALOGS); + app->expansion = furi_record_open(RECORD_EXPANSION); app->notification = furi_record_open(RECORD_NOTIFICATION); // View Dispatcher and Scene Manager @@ -361,6 +362,7 @@ void momentum_app_free(MomentumApp* app) { // Records furi_record_close(RECORD_NOTIFICATION); + furi_record_close(RECORD_EXPANSION); furi_record_close(RECORD_DIALOGS); furi_record_close(RECORD_GUI); free(app); diff --git a/applications/main/momentum_app/momentum_app.h b/applications/main/momentum_app/momentum_app.h index 67981177a8..3493647868 100644 --- a/applications/main/momentum_app/momentum_app.h +++ b/applications/main/momentum_app/momentum_app.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +36,7 @@ ARRAY_DEF(CharList, char*) typedef struct { Gui* gui; DialogsApp* dialogs; + Expansion* expansion; NotificationApp* notification; SceneManager* scene_manager; ViewDispatcher* view_dispatcher; diff --git a/applications/main/momentum_app/scenes/momentum_app_scene_misc_screen.c b/applications/main/momentum_app/scenes/momentum_app_scene_misc_screen.c index 4f39c38c07..945a3c724f 100644 --- a/applications/main/momentum_app/scenes/momentum_app_scene_misc_screen.c +++ b/applications/main/momentum_app/scenes/momentum_app_scene_misc_screen.c @@ -1,4 +1,3 @@ -#include #include "../momentum_app.h" enum VarItemListIndex { @@ -56,10 +55,10 @@ static void momentum_app_scene_misc_screen_lcd_color_changed(VariableItem* item, variable_item_set_current_value_text(item, lcd_colors[index].name); rgb_backlight_set_color(led, &lcd_colors[index].color); app->save_backlight = true; - - Expansion* expansion = furi_record_open(RECORD_EXPANSION); - expansion_disable(expansion); - expansion_enable(expansion); + if(momentum_settings.vgm_color_mode == VgmColorModeRgbBacklight) { + expansion_disable(app->expansion); + expansion_enable(app->expansion); + } } static void momentum_app_scene_misc_screen_lcd_color_0_changed(VariableItem* item) { momentum_app_scene_misc_screen_lcd_color_changed(item, 0); diff --git a/applications/main/momentum_app/scenes/momentum_app_scene_misc_screen_color.c b/applications/main/momentum_app/scenes/momentum_app_scene_misc_screen_color.c index a62dfa8884..bf78402756 100644 --- a/applications/main/momentum_app/scenes/momentum_app_scene_misc_screen_color.c +++ b/applications/main/momentum_app/scenes/momentum_app_scene_misc_screen_color.c @@ -43,6 +43,10 @@ bool momentum_app_scene_misc_screen_color_on_event(void* context, SceneManagerEv scene_manager_get_scene_state(app->scene_manager, MomentumAppSceneMiscScreenColor), &app->lcd_color); app->save_backlight = true; + if(momentum_settings.vgm_color_mode == VgmColorModeRgbBacklight) { + expansion_disable(app->expansion); + expansion_enable(app->expansion); + } scene_manager_previous_scene(app->scene_manager); break; default: diff --git a/targets/f7/furi_hal/furi_hal_info.c b/targets/f7/furi_hal/furi_hal_info.c index 3780c96e12..9b9298b78e 100644 --- a/targets/f7/furi_hal/furi_hal_info.c +++ b/targets/f7/furi_hal/furi_hal_info.c @@ -1,6 +1,3 @@ -#include "SK6805.h" -#include "colors.h" -#include "property.h" #include #include #include @@ -12,8 +9,10 @@ #include #include -#include "momentum/momentum.h" -#include "rgb_backlight.h" +#include +#include +#include +#include #include FURI_WEAK void furi_hal_info_get_api_version(uint16_t* major, uint16_t* minor) { From 5a61ee494426faa2194bf629361816dc181c3c70 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 8 Mar 2024 00:28:34 +0000 Subject: [PATCH 07/16] Add rgb565cmp() color helper --- lib/toolbox/colors.c | 4 ++++ lib/toolbox/colors.h | 2 ++ targets/f7/api_symbols.csv | 1 + 3 files changed, 7 insertions(+) diff --git a/lib/toolbox/colors.c b/lib/toolbox/colors.c index 22f06ac681..d40cf89897 100644 --- a/lib/toolbox/colors.c +++ b/lib/toolbox/colors.c @@ -86,3 +86,7 @@ void rgb2hsv(const RgbColor* rgb, HsvColor* hsv) { hsv->h = 171 + 43 * (rgb->r - rgb->g) / (rgbMax - rgbMin); } } + +inline int rgb565cmp(const Rgb565Color* a, const Rgb565Color* b) { + return memcmp(a, b, sizeof(Rgb565Color)); +} diff --git a/lib/toolbox/colors.h b/lib/toolbox/colors.h index c2acec0bb4..5bfa64539c 100644 --- a/lib/toolbox/colors.h +++ b/lib/toolbox/colors.h @@ -34,6 +34,8 @@ typedef union { }; } Rgb565Color; +int rgb565cmp(const Rgb565Color* a, const Rgb565Color* b); + #ifdef __cplusplus } #endif diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index d8f7a99e14..6a738babe2 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -2958,6 +2958,7 @@ Function,-,rename,int,"const char*, const char*" Function,-,renameat,int,"int, const char*, int, const char*" Function,-,rewind,void,FILE* Function,+,rgb2hsv,void,"const RgbColor*, HsvColor*" +Function,+,rgb565cmp,int,"const Rgb565Color*, const Rgb565Color*" Function,+,rgb_backlight_get_color,void,"uint8_t, RgbColor*" Function,+,rgb_backlight_get_rainbow_interval,uint32_t, Function,+,rgb_backlight_get_rainbow_mode,RGBBacklightRainbowMode, From 537fd8daccdcde35a1248a318a400e38ca170d61 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 8 Mar 2024 00:28:48 +0000 Subject: [PATCH 08/16] Swap color modes in enum --- lib/momentum/momentum.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/momentum/momentum.h b/lib/momentum/momentum.h index c5dc325262..6a8c82b5be 100644 --- a/lib/momentum/momentum.h +++ b/lib/momentum/momentum.h @@ -46,8 +46,8 @@ typedef enum { typedef enum { VgmColorModeDefault, - VgmColorModeRgbBacklight, VgmColorModeCustom, + VgmColorModeRgbBacklight, VgmColorModeCount, } VgmColorMode; From 3ba5198bb662caa64df65db73646739c30dfcc4b Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 8 Mar 2024 00:48:38 +0000 Subject: [PATCH 09/16] Fix Rgb565Color memory packing --- lib/toolbox/colors.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/toolbox/colors.h b/lib/toolbox/colors.h index 5bfa64539c..c76af31baa 100644 --- a/lib/toolbox/colors.h +++ b/lib/toolbox/colors.h @@ -28,10 +28,10 @@ void rgb2hsv(const RgbColor* rgb, HsvColor* hsv); typedef union { uint16_t value; struct { - uint8_t r : 5; - uint8_t g : 6; - uint8_t b : 5; - }; + uint16_t r : 5; + uint16_t g : 6; + uint16_t b : 5; + } FURI_PACKED; } Rgb565Color; int rgb565cmp(const Rgb565Color* a, const Rgb565Color* b); From 4c347fce53cf7e8ecbe1837418cea9c639f90f4b Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 8 Mar 2024 00:57:44 +0000 Subject: [PATCH 10/16] Add VGM color settings section --- applications/main/momentum_app/momentum_app.h | 1 + .../scenes/momentum_app_scene_config.h | 2 + .../scenes/momentum_app_scene_misc.c | 8 + .../scenes/momentum_app_scene_misc_vgm.c | 170 ++++++++++++++++++ .../momentum_app_scene_misc_vgm_color.c | 70 ++++++++ 5 files changed, 251 insertions(+) create mode 100644 applications/main/momentum_app/scenes/momentum_app_scene_misc_vgm.c create mode 100644 applications/main/momentum_app/scenes/momentum_app_scene_misc_vgm_color.c diff --git a/applications/main/momentum_app/momentum_app.h b/applications/main/momentum_app/momentum_app.h index 3493647868..9511185d36 100644 --- a/applications/main/momentum_app/momentum_app.h +++ b/applications/main/momentum_app/momentum_app.h @@ -60,6 +60,7 @@ typedef struct { char subghz_freq_buffer[7]; bool subghz_extend; RgbColor lcd_color; + Rgb565Color vgm_color; char device_name[FURI_HAL_VERSION_ARRAY_NAME_LENGTH]; int32_t dolphin_level; int32_t dolphin_angry; diff --git a/applications/main/momentum_app/scenes/momentum_app_scene_config.h b/applications/main/momentum_app/scenes/momentum_app_scene_config.h index edf216614b..77eb464325 100644 --- a/applications/main/momentum_app/scenes/momentum_app_scene_config.h +++ b/applications/main/momentum_app/scenes/momentum_app_scene_config.h @@ -18,4 +18,6 @@ ADD_SCENE(momentum_app, misc, Misc) ADD_SCENE(momentum_app, misc_screen, MiscScreen) ADD_SCENE(momentum_app, misc_screen_color, MiscScreenColor) ADD_SCENE(momentum_app, misc_dolphin, MiscDolphin) +ADD_SCENE(momentum_app, misc_vgm, MiscVgm) +ADD_SCENE(momentum_app, misc_vgm_color, MiscVgmColor) ADD_SCENE(momentum_app, misc_rename, MiscRename) diff --git a/applications/main/momentum_app/scenes/momentum_app_scene_misc.c b/applications/main/momentum_app/scenes/momentum_app_scene_misc.c index 1cff3957fc..ba9c1077e2 100644 --- a/applications/main/momentum_app/scenes/momentum_app_scene_misc.c +++ b/applications/main/momentum_app/scenes/momentum_app_scene_misc.c @@ -3,6 +3,7 @@ enum VarItemListIndex { VarItemListIndexScreen, VarItemListIndexDolphin, + VarItemListIndexVgm, VarItemListIndexChangeDeviceName, VarItemListIndexChargeCap, VarItemListIndexShowMomentumIntro, @@ -36,6 +37,9 @@ void momentum_app_scene_misc_on_enter(void* context) { item = variable_item_list_add(var_item_list, "Dolphin", 0, NULL, app); variable_item_set_current_value_text(item, ">"); + item = variable_item_list_add(var_item_list, "VGM Options", 0, NULL, app); + variable_item_set_current_value_text(item, ">"); + variable_item_list_add(var_item_list, "Change Device Name", 0, NULL, app); char cap_str[6]; @@ -77,6 +81,10 @@ bool momentum_app_scene_misc_on_event(void* context, SceneManagerEvent event) { scene_manager_set_scene_state(app->scene_manager, MomentumAppSceneMiscDolphin, 0); scene_manager_next_scene(app->scene_manager, MomentumAppSceneMiscDolphin); break; + case VarItemListIndexVgm: + scene_manager_set_scene_state(app->scene_manager, MomentumAppSceneMiscVgm, 0); + scene_manager_next_scene(app->scene_manager, MomentumAppSceneMiscVgm); + break; case VarItemListIndexChangeDeviceName: scene_manager_set_scene_state(app->scene_manager, MomentumAppSceneMiscRename, 0); scene_manager_next_scene(app->scene_manager, MomentumAppSceneMiscRename); diff --git a/applications/main/momentum_app/scenes/momentum_app_scene_misc_vgm.c b/applications/main/momentum_app/scenes/momentum_app_scene_misc_vgm.c new file mode 100644 index 0000000000..788067b5b1 --- /dev/null +++ b/applications/main/momentum_app/scenes/momentum_app_scene_misc_vgm.c @@ -0,0 +1,170 @@ +#include "../momentum_app.h" + +enum VarItemListIndex { + VarItemListIndexColors, + VarItemListIndexForeground, + VarItemListIndexBackground, +}; + +void momentum_app_scene_misc_vgm_var_item_list_callback(void* context, uint32_t index) { + MomentumApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +const char* const colors_names[VgmColorModeCount] = { + "Default", + "Custom", + "RGB Backlight", +}; +static void momentum_app_scene_misc_vgm_colors_changed(VariableItem* item) { + MomentumApp* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, colors_names[index]); + momentum_settings.vgm_color_mode = index; + app->save_settings = true; + variable_item_set_locked( + variable_item_list_get(app->var_item_list, VarItemListIndexForeground), + index != VgmColorModeCustom, + NULL); + variable_item_set_locked( + variable_item_list_get(app->var_item_list, VarItemListIndexBackground), + index != VgmColorModeCustom, + NULL); + expansion_disable(app->expansion); + expansion_enable(app->expansion); +} + +static const struct { + char* name; + Rgb565Color color; +} vgm_colors[] = { + {"Orange", {0xFC00}}, + {"Black", {0x0000}}, +}; +static const size_t vgm_colors_count = COUNT_OF(vgm_colors); +static void momentum_app_scene_misc_vgm_foreground_changed(VariableItem* item) { + MomentumApp* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, vgm_colors[index].name); + momentum_settings.vgm_color_fg = vgm_colors[index].color; + app->save_settings = true; + if(momentum_settings.vgm_color_mode == VgmColorModeCustom) { + expansion_disable(app->expansion); + expansion_enable(app->expansion); + } +} +static void momentum_app_scene_misc_vgm_background_changed(VariableItem* item) { + MomentumApp* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, vgm_colors[index].name); + momentum_settings.vgm_color_bg = vgm_colors[index].color; + app->save_settings = true; + if(momentum_settings.vgm_color_mode == VgmColorModeCustom) { + expansion_disable(app->expansion); + expansion_enable(app->expansion); + } +} + +void momentum_app_scene_misc_vgm_on_enter(void* context) { + MomentumApp* app = context; + VariableItemList* var_item_list = app->var_item_list; + VariableItem* item; + uint8_t value_index; + + item = variable_item_list_add( + var_item_list, + "VGM Colors", + VgmColorModeCount, + momentum_app_scene_misc_vgm_colors_changed, + app); + value_index = momentum_settings.vgm_color_mode; + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, colors_names[value_index]); + + item = variable_item_list_add( + var_item_list, + "Foreground", + vgm_colors_count, + momentum_app_scene_misc_vgm_foreground_changed, + app); + Rgb565Color color = momentum_settings.vgm_color_fg; + bool found = false; + for(size_t i = 0; i < vgm_colors_count; i++) { + if(rgb565cmp(&color, &vgm_colors[i].color) != 0) continue; + value_index = i; + found = true; + break; + } + variable_item_set_current_value_index(item, found ? value_index : vgm_colors_count); + if(found) { + variable_item_set_current_value_text(item, vgm_colors[value_index].name); + } else { + char str[5]; + snprintf(str, sizeof(str), "%04X", color.value); + variable_item_set_current_value_text(item, str); + } + variable_item_set_locked( + item, momentum_settings.vgm_color_mode != VgmColorModeCustom, "Need Custom\nColors!"); + + item = variable_item_list_add( + var_item_list, + "Background", + vgm_colors_count, + momentum_app_scene_misc_vgm_background_changed, + app); + color = momentum_settings.vgm_color_bg; + found = false; + for(size_t i = 0; i < vgm_colors_count; i++) { + if(rgb565cmp(&color, &vgm_colors[i].color) != 0) continue; + value_index = i; + found = true; + break; + } + variable_item_set_current_value_index(item, found ? value_index : vgm_colors_count); + if(found) { + variable_item_set_current_value_text(item, vgm_colors[value_index].name); + } else { + char str[5]; + snprintf(str, sizeof(str), "%04X", color.value); + variable_item_set_current_value_text(item, str); + } + variable_item_set_locked( + item, momentum_settings.vgm_color_mode != VgmColorModeCustom, "Need Custom\nColors!"); + + variable_item_list_set_enter_callback( + var_item_list, momentum_app_scene_misc_vgm_var_item_list_callback, app); + + variable_item_list_set_selected_item( + var_item_list, scene_manager_get_scene_state(app->scene_manager, MomentumAppSceneMiscVgm)); + + view_dispatcher_switch_to_view(app->view_dispatcher, MomentumAppViewVarItemList); +} + +bool momentum_app_scene_misc_vgm_on_event(void* context, SceneManagerEvent event) { + MomentumApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state(app->scene_manager, MomentumAppSceneMiscVgm, event.event); + consumed = true; + switch(event.event) { + case VarItemListIndexForeground: + case VarItemListIndexBackground: + scene_manager_set_scene_state( + app->scene_manager, + MomentumAppSceneMiscVgmColor, + event.event - VarItemListIndexForeground); + scene_manager_next_scene(app->scene_manager, MomentumAppSceneMiscVgmColor); + break; + default: + break; + } + } + + return consumed; +} + +void momentum_app_scene_misc_vgm_on_exit(void* context) { + MomentumApp* app = context; + variable_item_list_reset(app->var_item_list); +} diff --git a/applications/main/momentum_app/scenes/momentum_app_scene_misc_vgm_color.c b/applications/main/momentum_app/scenes/momentum_app_scene_misc_vgm_color.c new file mode 100644 index 0000000000..98ef4cf3ed --- /dev/null +++ b/applications/main/momentum_app/scenes/momentum_app_scene_misc_vgm_color.c @@ -0,0 +1,70 @@ +#include "../momentum_app.h" + +enum ByteInputResult { + ByteInputResultOk, +}; + +void momentum_app_scene_misc_vgm_color_byte_input_callback(void* context) { + MomentumApp* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, ByteInputResultOk); +} + +void momentum_app_scene_misc_vgm_color_on_enter(void* context) { + MomentumApp* app = context; + ByteInput* byte_input = app->byte_input; + + byte_input_set_header_text(byte_input, "Set VGM Color (RGB565)"); + + if(scene_manager_get_scene_state(app->scene_manager, MomentumAppSceneMiscVgmColor)) { + app->vgm_color = momentum_settings.vgm_color_bg; + } else { + app->vgm_color = momentum_settings.vgm_color_fg; + } + app->vgm_color.value = __REVSH(app->vgm_color.value); + + byte_input_set_result_callback( + byte_input, + momentum_app_scene_misc_vgm_color_byte_input_callback, + NULL, + app, + (void*)&app->vgm_color, + sizeof(app->vgm_color)); + + view_dispatcher_switch_to_view(app->view_dispatcher, MomentumAppViewByteInput); +} + +bool momentum_app_scene_misc_vgm_color_on_event(void* context, SceneManagerEvent event) { + MomentumApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + switch(event.event) { + case ByteInputResultOk: + app->vgm_color.value = __REVSH(app->vgm_color.value); + if(scene_manager_get_scene_state(app->scene_manager, MomentumAppSceneMiscVgmColor)) { + momentum_settings.vgm_color_bg = app->vgm_color; + } else { + momentum_settings.vgm_color_fg = app->vgm_color; + } + app->save_settings = true; + if(momentum_settings.vgm_color_mode == VgmColorModeCustom) { + expansion_disable(app->expansion); + expansion_enable(app->expansion); + } + scene_manager_previous_scene(app->scene_manager); + break; + default: + break; + } + } + + return consumed; +} + +void momentum_app_scene_misc_vgm_color_on_exit(void* context) { + MomentumApp* app = context; + byte_input_set_result_callback(app->byte_input, NULL, NULL, NULL, NULL, 0); + byte_input_set_header_text(app->byte_input, ""); +} From db979f4f4d0ca402d49241e90e6f15fa6375416d Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 8 Mar 2024 02:19:58 +0000 Subject: [PATCH 11/16] Add default VGM colors --- .../main/momentum_app/scenes/momentum_app_scene_misc_vgm.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/applications/main/momentum_app/scenes/momentum_app_scene_misc_vgm.c b/applications/main/momentum_app/scenes/momentum_app_scene_misc_vgm.c index 788067b5b1..3091da0198 100644 --- a/applications/main/momentum_app/scenes/momentum_app_scene_misc_vgm.c +++ b/applications/main/momentum_app/scenes/momentum_app_scene_misc_vgm.c @@ -38,8 +38,11 @@ static const struct { char* name; Rgb565Color color; } vgm_colors[] = { - {"Orange", {0xFC00}}, - {"Black", {0x0000}}, + {"Orange", {0xFC00}}, {"Black", {0x0000}}, {"Red", {0xF800}}, {"Maroon", {0x8000}}, + {"Yellow", {0xFFE0}}, {"Olive", {0x8400}}, {"Lime", {0x07E0}}, {"Green", {0x0400}}, + {"Aqua", {0x07EF}}, {"Cyan", {0x069A}}, {"Azure", {0x03FF}}, {"Teal", {0x0410}}, + {"Blue", {0x001F}}, {"Navy", {0x0010}}, {"Purple", {0x8010}}, {"Fuchsia", {0xF81F}}, + {"Pink", {0xA8F5}}, {"Brown", {0xA145}}, {"White", {0xFFFF}}, }; static const size_t vgm_colors_count = COUNT_OF(vgm_colors); static void momentum_app_scene_misc_vgm_foreground_changed(VariableItem* item) { From c977bef15e3bf147a7820edf3d1c6999ab0b0aa8 Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 8 Mar 2024 02:21:45 +0000 Subject: [PATCH 12/16] Fix VGM color assignment --- lib/momentum/settings.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/momentum/settings.c b/lib/momentum/settings.c index 3caaf1d345..a4086ebbb4 100644 --- a/lib/momentum/settings.c +++ b/lib/momentum/settings.c @@ -42,8 +42,8 @@ MomentumSettings momentum_settings = { .uart_nmea_channel = FuriHalSerialIdUsart, // pin 13,14 .file_naming_prefix_after = false, // Before .vgm_color_mode = VgmColorModeDefault, // Default - .vgm_color_fg.value = 0xFC00, // Default Orange - .vgm_color_bg.value = 0x0000, // Default Black + .vgm_color_fg.value = 0x0000, // Default Black + .vgm_color_bg.value = 0xFC00, // Default Orange }; typedef enum { From b112711f655ff9061b34c304b20e2b44771fdcbe Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 8 Mar 2024 02:34:12 +0000 Subject: [PATCH 13/16] VgmTool: Add RGB fw for MNTM VGM options --- applications/external | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/external b/applications/external index 3da3a125fe..746531bdf1 160000 --- a/applications/external +++ b/applications/external @@ -1 +1 @@ -Subproject commit 3da3a125fe9d9a286d265d0209a403dd728fb2b1 +Subproject commit 746531bdf1646328448533f1d3c9612ec6c061a1 From eff2fda6444e5790caa92dacb9e35eac5861eb0b Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 8 Mar 2024 06:10:48 +0000 Subject: [PATCH 14/16] Logo splash on boot --- furi/flipper.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/furi/flipper.c b/furi/flipper.c index 8b1c65d5d0..50c6659e01 100644 --- a/furi/flipper.c +++ b/furi/flipper.c @@ -44,6 +44,7 @@ static void flipper_print_version(const char* target, const Version* version) { #include #include #include +#include void flipper_migrate_files() { Storage* storage = furi_record_open(RECORD_STORAGE); @@ -101,9 +102,8 @@ void flipper_migrate_files() { static void flipper_boot_status(Canvas* canvas, const char* text) { FURI_LOG_I(TAG, text); canvas_reset(canvas); - canvas_draw_str_aligned(canvas, 64, 40, AlignCenter, AlignCenter, text); - canvas_set_font(canvas, FontPrimary); - canvas_draw_str_aligned(canvas, 64, 24, AlignCenter, AlignCenter, "Momentum is Booting"); + canvas_draw_icon(canvas, 33, 16, &I_Updating_Logo_62x15); + canvas_draw_str_aligned(canvas, 64, 44, AlignCenter, AlignCenter, text); canvas_commit(canvas); } #endif @@ -143,7 +143,7 @@ void flipper_init() { flipper_boot_status(canvas, "Starting Namespoof"); namespoof_init(); - flipper_boot_status(canvas, "Loading Momentum Settings"); + flipper_boot_status(canvas, "Loading Settings"); momentum_settings_load(); furi_hal_light_sequence("rgb RB"); From 13fe7b3bfcf2bde14471d76e395334ec95336ae5 Mon Sep 17 00:00:00 2001 From: MatthewKuKanich Date: Fri, 8 Mar 2024 13:10:14 -0500 Subject: [PATCH 15/16] Add FindMy Flipper to system apps --- applications/system/findmy/application.fam | 14 ++ applications/system/findmy/findmy.c | 164 ++++++++++++++++++ applications/system/findmy/findmy.h | 3 + applications/system/findmy/findmy_i.h | 42 +++++ applications/system/findmy/location_icon.png | Bin 0 -> 6750 bytes .../system/findmy/scenes/findmy_scene.c | 31 ++++ .../system/findmy/scenes/findmy_scene.h | 30 ++++ .../findmy/scenes/findmy_scene_config.c | 98 +++++++++++ .../findmy/scenes/findmy_scene_config_mac.c | 60 +++++++ .../scenes/findmy_scene_config_packet.c | 64 +++++++ .../system/findmy/scenes/findmy_scene_main.c | 54 ++++++ .../system/findmy/scenes/findmy_scenes.h | 4 + .../system/findmy/views/findmy_main.c | 143 +++++++++++++++ .../system/findmy/views/findmy_main.h | 29 ++++ 14 files changed, 736 insertions(+) create mode 100644 applications/system/findmy/application.fam create mode 100644 applications/system/findmy/findmy.c create mode 100644 applications/system/findmy/findmy.h create mode 100644 applications/system/findmy/findmy_i.h create mode 100644 applications/system/findmy/location_icon.png create mode 100644 applications/system/findmy/scenes/findmy_scene.c create mode 100644 applications/system/findmy/scenes/findmy_scene.h create mode 100644 applications/system/findmy/scenes/findmy_scene_config.c create mode 100644 applications/system/findmy/scenes/findmy_scene_config_mac.c create mode 100644 applications/system/findmy/scenes/findmy_scene_config_packet.c create mode 100644 applications/system/findmy/scenes/findmy_scene_main.c create mode 100644 applications/system/findmy/scenes/findmy_scenes.h create mode 100644 applications/system/findmy/views/findmy_main.c create mode 100644 applications/system/findmy/views/findmy_main.h diff --git a/applications/system/findmy/application.fam b/applications/system/findmy/application.fam new file mode 100644 index 0000000000..0b6006923c --- /dev/null +++ b/applications/system/findmy/application.fam @@ -0,0 +1,14 @@ +App( + appid="findmy", + name="FindMy Flipper", + apptype=FlipperAppType.EXTERNAL, + entry_point="findmy_main", + requires=["gui"], + stack_size=1 * 1024, + order=35, + fap_icon="location_icon.png", + fap_category="Bluetooth", + fap_author="@MatthewKuKanich", + fap_version="1.0", + fap_description="BLE FindMy Location Beacon", +) diff --git a/applications/system/findmy/findmy.c b/applications/system/findmy/findmy.c new file mode 100644 index 0000000000..2722f32ab7 --- /dev/null +++ b/applications/system/findmy/findmy.c @@ -0,0 +1,164 @@ +#include "findmy_i.h" + +static bool findmy_custom_event_callback(void* context, uint32_t event) { + furi_assert(context); + FindMy* app = context; + return scene_manager_handle_custom_event(app->scene_manager, event); +} + +static bool findmy_back_event_callback(void* context) { + furi_assert(context); + FindMy* app = context; + return scene_manager_handle_back_event(app->scene_manager); +} + +static FindMy* findmy_app_alloc() { + FindMy* app = malloc(sizeof(FindMy)); + + app->gui = furi_record_open(RECORD_GUI); + + app->view_dispatcher = view_dispatcher_alloc(); + view_dispatcher_enable_queue(app->view_dispatcher); + + app->scene_manager = scene_manager_alloc(&findmy_scene_handlers, app); + + view_dispatcher_set_event_callback_context(app->view_dispatcher, app); + view_dispatcher_set_custom_event_callback(app->view_dispatcher, findmy_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + app->view_dispatcher, findmy_back_event_callback); + + app->findmy_main = findmy_main_alloc(app); + view_dispatcher_add_view( + app->view_dispatcher, FindMyViewMain, findmy_main_get_view(app->findmy_main)); + + app->byte_input = byte_input_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, FindMyViewByteInput, byte_input_get_view(app->byte_input)); + + app->var_item_list = variable_item_list_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, + FindMyViewVarItemList, + variable_item_list_get_view(app->var_item_list)); + + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + + app->beacon_active = false; + findmy_main_update_active(app->findmy_main, app->beacon_active); + app->broadcast_interval = 5; + findmy_main_update_interval(app->findmy_main, app->broadcast_interval); + app->transmit_power = 6; + app->apple = true; + findmy_main_update_apple(app->findmy_main, app->apple); + + return app; +} + +static void findmy_app_free(FindMy* app) { + furi_assert(app); + + view_dispatcher_remove_view(app->view_dispatcher, FindMyViewVarItemList); + variable_item_list_free(app->var_item_list); + + view_dispatcher_remove_view(app->view_dispatcher, FindMyViewByteInput); + byte_input_free(app->byte_input); + + view_dispatcher_remove_view(app->view_dispatcher, FindMyViewMain); + findmy_main_free(app->findmy_main); + + view_dispatcher_free(app->view_dispatcher); + scene_manager_free(app->scene_manager); + + furi_record_close(RECORD_GUI); + + free(app); +} + +static void findmy_start(FindMy* app) { + furi_hal_bt_extra_beacon_stop(); // Stop any running beacon + + app->config.min_adv_interval_ms = app->broadcast_interval * 1000; // Converting s to ms + app->config.max_adv_interval_ms = (app->broadcast_interval * 1000) + 150; + app->config.adv_channel_map = GapAdvChannelMapAll; + app->config.adv_power_level = GapAdvPowerLevel_0dBm + app->transmit_power; + app->config.address_type = GapAddressTypePublic; + + uint8_t mac[EXTRA_BEACON_MAC_ADDR_SIZE] = {0x4D, 0x61, 0x74, 0x4B, 0x75, 0x4B}; + furi_hal_bt_reverse_mac_addr(mac); + memcpy(&app->config.address, mac, sizeof(app->config.address)); + furi_check(furi_hal_bt_extra_beacon_set_config(&app->config)); + + uint8_t data[EXTRA_BEACON_MAX_DATA_SIZE]; + uint8_t* it = data; + + // For Apple AirTags + *it++ = 0x1E; // Length + *it++ = 0xFF; // Manufacturer Specific Data + *it++ = 0x4C; // Company ID (Apple, Inc.) + *it++ = 0x00; // State + *it++ = 0x12; // Data - Public Key without the MAC address + *it++ = 0x81; // ... + *it++ = 0xB9; // ... + *it++ = 0x02; // First 2 bits are the version, the rest is the battery level + *it++ = 0x7E; // Hint (0x00) + + furi_check(furi_hal_bt_extra_beacon_set_data(data, it - data)); +} + +int32_t findmy_main(void* p) { + UNUSED(p); + FindMy* app = findmy_app_alloc(); + + findmy_start(app); + + scene_manager_next_scene(app->scene_manager, FindMySceneMain); + + view_dispatcher_run(app->view_dispatcher); + + findmy_app_free(app); + return 0; +} + +void findmy_change_broadcast_interval(FindMy* app, uint8_t value) { + if(value > 10 || value < 1) { + return; + } + app->broadcast_interval = value; + findmy_main_update_interval(app->findmy_main, app->broadcast_interval); + if(app->beacon_active) { + // Always check if beacon is active before changing config + furi_check(furi_hal_bt_extra_beacon_stop()); + } + app->config.min_adv_interval_ms = app->broadcast_interval * 1000; + app->config.max_adv_interval_ms = app->config.min_adv_interval_ms + 150; + furi_check(furi_hal_bt_extra_beacon_set_config(&app->config)); + if(app->beacon_active) { + furi_check(furi_hal_bt_extra_beacon_start()); + } +} + +void findmy_change_transmit_power(FindMy* app, uint8_t value) { + if(value > 6) { + return; + } + app->transmit_power = value; + if(app->beacon_active) { + furi_check(furi_hal_bt_extra_beacon_stop()); + } + app->config.adv_power_level = GapAdvPowerLevel_0dBm + app->transmit_power; + furi_check(furi_hal_bt_extra_beacon_set_config(&app->config)); + if(app->beacon_active) { + furi_check(furi_hal_bt_extra_beacon_start()); + } +} + +void findmy_toggle_beacon(FindMy* app) { + app->beacon_active = !app->beacon_active; + findmy_main_update_active(app->findmy_main, app->beacon_active); + findmy_main_update_apple(app->findmy_main, app->apple); + if(app->beacon_active) { + furi_hal_bt_extra_beacon_start(); + } else { + furi_hal_bt_extra_beacon_stop(); + } +} \ No newline at end of file diff --git a/applications/system/findmy/findmy.h b/applications/system/findmy/findmy.h new file mode 100644 index 0000000000..344882ef10 --- /dev/null +++ b/applications/system/findmy/findmy.h @@ -0,0 +1,3 @@ +#pragma once + +typedef struct FindMy FindMy; diff --git a/applications/system/findmy/findmy_i.h b/applications/system/findmy/findmy_i.h new file mode 100644 index 0000000000..fd09e5324a --- /dev/null +++ b/applications/system/findmy/findmy_i.h @@ -0,0 +1,42 @@ +#pragma once + +#include "findmy.h" +#include +#include +#include +#include +#include +#include +#include "views/findmy_main.h" +#include +#include +#include "scenes/findmy_scene.h" + +struct FindMy { + Gui* gui; + SceneManager* scene_manager; + ViewDispatcher* view_dispatcher; + + FindMyMain* findmy_main; + ByteInput* byte_input; + VariableItemList* var_item_list; + + uint8_t mac_buf[EXTRA_BEACON_MAC_ADDR_SIZE]; + uint8_t packet_buf[EXTRA_BEACON_MAX_DATA_SIZE]; + + GapExtraBeaconConfig config; + bool apple; + bool beacon_active; + uint8_t broadcast_interval; + uint8_t transmit_power; +}; + +typedef enum { + FindMyViewMain, + FindMyViewByteInput, + FindMyViewVarItemList, +} FindMyView; + +void findmy_change_broadcast_interval(FindMy* app, uint8_t value); +void findmy_change_transmit_power(FindMy* app, uint8_t value); +void findmy_toggle_beacon(FindMy* app); diff --git a/applications/system/findmy/location_icon.png b/applications/system/findmy/location_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..841787a2a6131015634e906ff1cd4f189e0855aa GIT binary patch literal 6750 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 literal 0 HcmV?d00001 diff --git a/applications/system/findmy/scenes/findmy_scene.c b/applications/system/findmy/scenes/findmy_scene.c new file mode 100644 index 0000000000..dca1adbb4f --- /dev/null +++ b/applications/system/findmy/scenes/findmy_scene.c @@ -0,0 +1,31 @@ +#include "findmy_scene.h" +#include "findmy.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const findmy_on_enter_handlers[])(void*) = { +#include "findmy_scenes.h" +}; +#undef ADD_SCENE + +// Generate scene on_event handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, +bool (*const findmy_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "findmy_scenes.h" +}; +#undef ADD_SCENE + +// Generate scene on_exit handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, +void (*const findmy_on_exit_handlers[])(void* context) = { +#include "findmy_scenes.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers findmy_scene_handlers = { + .on_enter_handlers = findmy_on_enter_handlers, + .on_event_handlers = findmy_on_event_handlers, + .on_exit_handlers = findmy_on_exit_handlers, + .scene_num = FindMySceneNum, +}; \ No newline at end of file diff --git a/applications/system/findmy/scenes/findmy_scene.h b/applications/system/findmy/scenes/findmy_scene.h new file mode 100644 index 0000000000..993b9d0542 --- /dev/null +++ b/applications/system/findmy/scenes/findmy_scene.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include "findmy.h" + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) FindMyScene##id, +typedef enum { +#include "findmy_scenes.h" + FindMySceneNum, +} FindMyScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers findmy_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "findmy_scenes.h" +#undef ADD_SCENE + +// Generate scene on_event handlers declaration +#define ADD_SCENE(prefix, name, id) \ + bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); +#include "findmy_scenes.h" +#undef ADD_SCENE + +// Generate scene on_exit handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); +#include "findmy_scenes.h" +#undef ADD_SCENE \ No newline at end of file diff --git a/applications/system/findmy/scenes/findmy_scene_config.c b/applications/system/findmy/scenes/findmy_scene_config.c new file mode 100644 index 0000000000..8f16d7b190 --- /dev/null +++ b/applications/system/findmy/scenes/findmy_scene_config.c @@ -0,0 +1,98 @@ +#include "../findmy_i.h" + +enum VarItemListIndex { + VarItemListIndexBroadcastInterval, + VarItemListIndexTransmitPower, + VarItemListIndexRegisterTag, + VarItemListIndexAbout, +}; + +void findmy_scene_config_broadcast_interval_changed(VariableItem* item) { + FindMy* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + findmy_change_broadcast_interval(app, index + 1); + char str[5]; + snprintf(str, sizeof(str), "%ds", app->broadcast_interval); + variable_item_set_current_value_text(item, str); + variable_item_set_current_value_index(item, app->broadcast_interval - 1); +} + +void findmy_scene_config_transmit_power_changed(VariableItem* item) { + FindMy* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + findmy_change_transmit_power(app, index); + char str[7]; + snprintf(str, sizeof(str), "%ddBm", app->transmit_power); + variable_item_set_current_value_text(item, str); + variable_item_set_current_value_index(item, app->transmit_power); +} + +void findmy_scene_config_callback(void* context, uint32_t index) { + furi_assert(context); + FindMy* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +void findmy_scene_config_on_enter(void* context) { + FindMy* app = context; + VariableItemList* var_item_list = app->var_item_list; + VariableItem* item; + + item = variable_item_list_add( + var_item_list, + "Broadcast Interval", + 10, + findmy_scene_config_broadcast_interval_changed, + app); + // Broadcast Interval is 1-10, so use 0-9 and offset indexes by 1 + variable_item_set_current_value_index(item, app->broadcast_interval - 1); + char broadcast_interval_s[5]; + snprintf(broadcast_interval_s, sizeof(broadcast_interval_s), "%ds", app->broadcast_interval); + variable_item_set_current_value_text(item, broadcast_interval_s); + + item = variable_item_list_add( + var_item_list, "Transmit Power", 7, findmy_scene_config_transmit_power_changed, app); + variable_item_set_current_value_index(item, app->transmit_power); + char transmit_power_s[7]; + snprintf(transmit_power_s, sizeof(transmit_power_s), "%ddBm", app->transmit_power); + variable_item_set_current_value_text(item, transmit_power_s); + + item = variable_item_list_add(var_item_list, "Register Tag", 0, NULL, NULL); + item = variable_item_list_add(var_item_list, "Matthew KuKanich, Thanks to Chapoly1305, WillyJL, OpenHaystack, Testers", 1, NULL, NULL); + variable_item_set_current_value_text(item, "Credits"); + + variable_item_list_set_enter_callback(var_item_list, findmy_scene_config_callback, app); + + variable_item_list_set_selected_item( + var_item_list, scene_manager_get_scene_state(app->scene_manager, FindMySceneConfig)); + + view_dispatcher_switch_to_view(app->view_dispatcher, FindMyViewVarItemList); +} + +bool findmy_scene_config_on_event(void* context, SceneManagerEvent event) { + FindMy* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + scene_manager_set_scene_state(app->scene_manager, FindMySceneConfig, event.event); + consumed = true; + switch(event.event) { + case VarItemListIndexRegisterTag: + scene_manager_next_scene(app->scene_manager, FindMySceneConfigMac); + break; + case VarItemListIndexAbout: + break; + default: + break; + } + } + + return consumed; +} + +void findmy_scene_config_on_exit(void* context) { + FindMy* app = context; + VariableItemList* var_item_list = app->var_item_list; + + variable_item_list_reset(var_item_list); +} \ No newline at end of file diff --git a/applications/system/findmy/scenes/findmy_scene_config_mac.c b/applications/system/findmy/scenes/findmy_scene_config_mac.c new file mode 100644 index 0000000000..c86e3dc1e7 --- /dev/null +++ b/applications/system/findmy/scenes/findmy_scene_config_mac.c @@ -0,0 +1,60 @@ +#include "../findmy_i.h" + +enum ByteInputResult { + ByteInputResultOk, +}; + +static void findmy_scene_config_mac_callback(void* context) { + FindMy* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, ByteInputResultOk); +} + +void findmy_scene_config_mac_on_enter(void* context) { + FindMy* app = context; + ByteInput* byte_input = app->byte_input; + + byte_input_set_header_text(byte_input, "Enter Bluetooth MAC:"); + + memcpy(app->mac_buf, &app->config.address, sizeof(app->mac_buf)); + furi_hal_bt_reverse_mac_addr(app->mac_buf); + + byte_input_set_result_callback( + byte_input, + findmy_scene_config_mac_callback, + NULL, + app, + app->mac_buf, + sizeof(app->mac_buf)); + + view_dispatcher_switch_to_view(app->view_dispatcher, FindMyViewByteInput); +} + +bool findmy_scene_config_mac_on_event(void* context, SceneManagerEvent event) { + FindMy* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + switch(event.event) { + case ByteInputResultOk: + furi_hal_bt_reverse_mac_addr(app->mac_buf); + memcpy(&app->config.address, app->mac_buf, sizeof(app->config.address)); + furi_hal_bt_extra_beacon_set_config(&app->config); + scene_manager_next_scene(app->scene_manager, FindMySceneConfigPacket); + break; + default: + break; + } + } + + return consumed; +} + +void findmy_scene_config_mac_on_exit(void* context) { + FindMy* app = context; + + byte_input_set_result_callback(app->byte_input, NULL, NULL, NULL, NULL, 0); + byte_input_set_header_text(app->byte_input, ""); + +} \ No newline at end of file diff --git a/applications/system/findmy/scenes/findmy_scene_config_packet.c b/applications/system/findmy/scenes/findmy_scene_config_packet.c new file mode 100644 index 0000000000..4dddf6c02b --- /dev/null +++ b/applications/system/findmy/scenes/findmy_scene_config_packet.c @@ -0,0 +1,64 @@ +#include "../findmy_i.h" + +enum ByteInputResult { + ByteInputResultOk, +}; + +static void findmy_scene_config_packet_callback(void* context) { + FindMy* app = context; + + view_dispatcher_send_custom_event(app->view_dispatcher, ByteInputResultOk); +} + +void findmy_scene_config_packet_on_enter(void* context) { + FindMy* app = context; + ByteInput* byte_input = app->byte_input; + + byte_input_set_header_text(byte_input, "Enter Bluetooth Payload:"); + + memset(app->packet_buf, 0, sizeof(app->packet_buf)); + furi_hal_bt_extra_beacon_get_data(app->packet_buf); + + byte_input_set_result_callback( + byte_input, + findmy_scene_config_packet_callback, + NULL, + app, + app->packet_buf, + sizeof(app->packet_buf)); + + view_dispatcher_switch_to_view(app->view_dispatcher, FindMyViewByteInput); +} + +bool findmy_scene_config_packet_on_event(void* context, SceneManagerEvent event) { + FindMy* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + switch(event.event) { + case ByteInputResultOk: + scene_manager_search_and_switch_to_previous_scene( + app->scene_manager, FindMySceneConfig); + furi_check(furi_hal_bt_extra_beacon_set_data(app->packet_buf, sizeof(app->packet_buf))); + if (app->packet_buf[0] == 0x1E && app->packet_buf[3] == 0x00) { + app->apple = true; // Checks payload data for Apple identifier + } else { + app->apple = false; + } + findmy_main_update_apple(app->findmy_main, app->apple); + break; + default: + break; + } + } + + return consumed; +} + +void findmy_scene_config_packet_on_exit(void* context) { + FindMy* app = context; + + byte_input_set_result_callback(app->byte_input, NULL, NULL, NULL, NULL, 0); + byte_input_set_header_text(app->byte_input, ""); +} \ No newline at end of file diff --git a/applications/system/findmy/scenes/findmy_scene_main.c b/applications/system/findmy/scenes/findmy_scene_main.c new file mode 100644 index 0000000000..5738370cf8 --- /dev/null +++ b/applications/system/findmy/scenes/findmy_scene_main.c @@ -0,0 +1,54 @@ +#include "../findmy_i.h" + +void findmy_scene_main_callback(FindMyMainEvent event, void* context) { + furi_assert(context); + FindMy* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, event); +} + +void findmy_scene_main_on_enter(void* context) { + FindMy* app = context; + + findmy_main_set_callback(app->findmy_main, findmy_scene_main_callback, app); + + view_dispatcher_switch_to_view(app->view_dispatcher, FindMyViewMain); +} + +bool findmy_scene_main_on_event(void* context, SceneManagerEvent event) { + FindMy* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + consumed = true; + switch(event.event) { + case FindMyMainEventToggle: + findmy_toggle_beacon(app); + break; + case FindMyMainEventBackground: + furi_hal_bt_extra_beacon_start(); + view_dispatcher_stop(app->view_dispatcher); + break; + case FindMyMainEventConfig: + scene_manager_next_scene(app->scene_manager, FindMySceneConfig); + break; + case FindMyMainEventIntervalUp: + findmy_change_broadcast_interval(app, app->broadcast_interval + 1); + break; + case FindMyMainEventIntervalDown: + findmy_change_broadcast_interval(app, app->broadcast_interval - 1); + break; + case FindMyMainEventQuit: + break; + default: + consumed = false; + break; + } + } + + return consumed; +} + +void findmy_scene_main_on_exit(void* context) { + FindMy* app = context; + UNUSED(app); +} \ No newline at end of file diff --git a/applications/system/findmy/scenes/findmy_scenes.h b/applications/system/findmy/scenes/findmy_scenes.h new file mode 100644 index 0000000000..683c52c5b7 --- /dev/null +++ b/applications/system/findmy/scenes/findmy_scenes.h @@ -0,0 +1,4 @@ +ADD_SCENE(findmy, main, Main) +ADD_SCENE(findmy, config, Config) +ADD_SCENE(findmy, config_mac, ConfigMac) +ADD_SCENE(findmy, config_packet, ConfigPacket) diff --git a/applications/system/findmy/views/findmy_main.c b/applications/system/findmy/views/findmy_main.c new file mode 100644 index 0000000000..f7b2485462 --- /dev/null +++ b/applications/system/findmy/views/findmy_main.c @@ -0,0 +1,143 @@ +#include "findmy_main.h" +#include "../findmy_i.h" + +struct FindMyMain { + View* view; + FindMyMainCallback callback; + void* context; +}; + +typedef struct { + bool active; + bool apple; + uint8_t interval; +} FindMyMainModel; + +static void findmy_main_draw_callback(Canvas* canvas, void* _model) { + FindMyMainModel* model = _model; + canvas_clear(canvas); + canvas_set_bitmap_mode(canvas, true); + canvas_set_font(canvas, FontPrimary); + + canvas_draw_str(canvas, 4, 11, "FindMy Flipper"); + canvas_set_font(canvas, FontSecondary); + if(model->active) { + canvas_draw_str(canvas, 4, 49, "Broadcast Active"); + canvas_draw_icon(canvas, 78, 42, &I_Ok_btn_9x9); + } else { + canvas_draw_str(canvas, 4, 49, "Broadcast Inactive"); + } + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 4, 21, "Press <- to run in background"); + canvas_set_font(canvas, FontSecondary); + char interval_str[20]; + snprintf(interval_str, sizeof(interval_str), "Ping Interval: %ds", model->interval); + canvas_draw_str(canvas, 4, 62, interval_str); + canvas_set_font(canvas, FontPrimary); + if(model->apple){ + canvas_draw_str(canvas, 4, 32, "Apple Network"); + canvas_draw_icon(canvas, 80, 24, &I_Lock_7x8); + } else { + canvas_draw_str(canvas, 4, 32, "Samsung Network"); + canvas_draw_icon(canvas, 97, 24, &I_Lock_7x8); + } + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 100, 61, "Config"); + canvas_draw_line(canvas, 100, 51, 127, 51); + canvas_draw_line(canvas, 97, 53, 97, 63); + canvas_draw_line(canvas, 97, 53, 99, 51); + canvas_draw_line(canvas, 3, 52, 87, 52); +} + +static bool findmy_main_input_callback(InputEvent* event, void* context) { + furi_assert(context); + FindMyMain* findmy_main = context; + bool consumed = false; + + if(event->type == InputTypePress) { + consumed = true; + // FIXME: finish implementing handlers in scene side + switch(event->key) { + case InputKeyBack: + findmy_main->callback(FindMyMainEventQuit, findmy_main->context); + // furi_hal_bt_extra_beacon_stop(); + break; + case InputKeyOk: + findmy_main->callback(FindMyMainEventToggle, findmy_main->context); + break; + case InputKeyLeft: + findmy_main->callback(FindMyMainEventBackground, findmy_main->context); + break; + case InputKeyRight: + findmy_main->callback(FindMyMainEventConfig, findmy_main->context); + break; + case InputKeyUp: + findmy_main->callback(FindMyMainEventIntervalUp, findmy_main->context); + break; + case InputKeyDown: + findmy_main->callback(FindMyMainEventIntervalDown, findmy_main->context); + break; + default: + break; + } + } + + return consumed; +} + +FindMyMain* findmy_main_alloc(FindMy* app) { + FindMyMain* findmy_main = malloc(sizeof(FindMyMain)); + + findmy_main->view = view_alloc(); + view_allocate_model(findmy_main->view, ViewModelTypeLocking, sizeof(FindMyMainModel)); + with_view_model( + findmy_main->view, + FindMyMainModel * model, + { + model->active = app->beacon_active; + model->apple = app->apple; + model->interval = app->broadcast_interval; + }, + false); + view_set_context(findmy_main->view, findmy_main); + view_set_draw_callback(findmy_main->view, findmy_main_draw_callback); + view_set_input_callback(findmy_main->view, findmy_main_input_callback); + + return findmy_main; +} + +void findmy_main_free(FindMyMain* findmy_main) { + furi_assert(findmy_main); + view_free(findmy_main->view); + free(findmy_main); +} + +View* findmy_main_get_view(FindMyMain* findmy_main) { + furi_assert(findmy_main); + return findmy_main->view; +} + +void findmy_main_set_callback(FindMyMain* findmy_main, FindMyMainCallback callback, void* context) { + furi_assert(findmy_main); + furi_assert(callback); + findmy_main->callback = callback; + findmy_main->context = context; +} + +void findmy_main_update_active(FindMyMain* findmy_main, bool active) { + furi_assert(findmy_main); + with_view_model( + findmy_main->view, FindMyMainModel * model, { model->active = active; }, true); +} + +void findmy_main_update_interval(FindMyMain* findmy_main, uint8_t interval) { + furi_assert(findmy_main); + with_view_model( + findmy_main->view, FindMyMainModel * model, { model->interval = interval; }, true); +} + +void findmy_main_update_apple(FindMyMain* findmy_main, bool apple) { + furi_assert(findmy_main); + with_view_model( + findmy_main->view, FindMyMainModel * model, { model->apple = apple; }, true); +} \ No newline at end of file diff --git a/applications/system/findmy/views/findmy_main.h b/applications/system/findmy/views/findmy_main.h new file mode 100644 index 0000000000..977f574d71 --- /dev/null +++ b/applications/system/findmy/views/findmy_main.h @@ -0,0 +1,29 @@ +#pragma once + +#include "../findmy.h" +#include + +typedef enum { + FindMyMainEventToggle, + FindMyMainEventBackground, + FindMyMainEventConfig, + FindMyMainEventIntervalUp, + FindMyMainEventIntervalDown, + FindMyMainEventQuit, +} FindMyMainEvent; + +typedef struct FindMyMain FindMyMain; +typedef void (*FindMyMainCallback)(FindMyMainEvent event, void* context); + +// Main functionality +FindMyMain* findmy_main_alloc(FindMy* app); +void findmy_main_free(FindMyMain* findmy_main); +View* findmy_main_get_view(FindMyMain* findmy_main); + +// To communicate with scene +void findmy_main_set_callback(FindMyMain* findmy_main, FindMyMainCallback callback, void* context); + +// To redraw when info changes +void findmy_main_update_active(FindMyMain* findmy_main, bool active); +void findmy_main_update_interval(FindMyMain* findmy_main, uint8_t interval); +void findmy_main_update_apple(FindMyMain* findmy_main, bool apple); \ No newline at end of file From 435c35cee93e5332ebc91f1ffb8243394bbe9fbf Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Fri, 8 Mar 2024 20:56:39 +0000 Subject: [PATCH 16/16] Improve beacon state handling --- applications/external | 2 +- applications/system/js_app/modules/js_blebeacon.c | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/applications/external b/applications/external index 746531bdf1..3dbd298b07 160000 --- a/applications/external +++ b/applications/external @@ -1 +1 @@ -Subproject commit 746531bdf1646328448533f1d3c9612ec6c061a1 +Subproject commit 3dbd298b0714312cc6af4d74c52cd802e718d343 diff --git a/applications/system/js_app/modules/js_blebeacon.c b/applications/system/js_app/modules/js_blebeacon.c index a87f4d2291..4d19accb1c 100644 --- a/applications/system/js_app/modules/js_blebeacon.c +++ b/applications/system/js_app/modules/js_blebeacon.c @@ -176,7 +176,10 @@ static void js_blebeacon_stop(struct mjs* mjs) { blebeacon->saved_prev_active = true; blebeacon->prev_active = furi_hal_bt_extra_beacon_is_active(); } - furi_hal_bt_extra_beacon_stop(); + if(!furi_hal_bt_extra_beacon_stop()) { + ret_int_err(mjs, "Failed stopping beacon"); + return; + } mjs_return(mjs, MJS_UNDEFINED); } @@ -209,7 +212,7 @@ static void js_blebeacon_destroy(void* inst) { JsBlebeaconInst* blebeacon = inst; if(!blebeacon->keep_alive) { if(furi_hal_bt_extra_beacon_is_active()) { - furi_hal_bt_extra_beacon_stop(); + furi_check(furi_hal_bt_extra_beacon_stop()); } if(blebeacon->saved_prev_cfg && blebeacon->prev_cfg_set) { furi_check(furi_hal_bt_extra_beacon_set_config(&blebeacon->prev_cfg));