diff --git a/applications/external/passgen/icons/Pin_back_arrow_10x8.png b/applications/external/passgen/icons/Pin_back_arrow_10x8.png deleted file mode 100644 index 3bafabd14..000000000 Binary files a/applications/external/passgen/icons/Pin_back_arrow_10x8.png and /dev/null differ diff --git a/applications/main/nfc/scenes/nfc_scene_restore_original_confirm.c b/applications/main/nfc/scenes/nfc_scene_restore_original_confirm.c index 730dd41e8..16b0953f8 100644 --- a/applications/main/nfc/scenes/nfc_scene_restore_original_confirm.c +++ b/applications/main/nfc/scenes/nfc_scene_restore_original_confirm.c @@ -11,7 +11,7 @@ void nfc_scene_restore_original_confirm_on_enter(void* context) { DialogEx* dialog_ex = nfc->dialog_ex; dialog_ex_set_header(dialog_ex, "Restore Card Data?", 64, 0, AlignCenter, AlignTop); - dialog_ex_set_icon(dialog_ex, 5, 15, &I_Restoring_38x32); + dialog_ex_set_icon(dialog_ex, 5, 11, &I_ArrowC_1_36x36); dialog_ex_set_text( dialog_ex, "It will be returned\nto its original state.", 47, 21, AlignLeft, AlignTop); dialog_ex_set_left_button_text(dialog_ex, "Cancel"); diff --git a/applications/services/notification/notification.h b/applications/services/notification/notification.h index b38620f0f..0e1c07e5d 100644 --- a/applications/services/notification/notification.h +++ b/applications/services/notification/notification.h @@ -75,6 +75,8 @@ typedef enum { NotificationMessageTypeForceDisplayBrightnessSetting, NotificationMessageTypeLedBrightnessSettingApply, + + NotificationMessageTypeLcdContrastUpdate, } NotificationMessageType; typedef struct { diff --git a/applications/services/notification/notification_app.c b/applications/services/notification/notification_app.c index 409c51957..b7b789104 100644 --- a/applications/services/notification/notification_app.c +++ b/applications/services/notification/notification_app.c @@ -4,6 +4,9 @@ #include #include #include +#include +#include + #include "notification.h" #include "notification_messages.h" #include "notification_app.h" @@ -21,14 +24,14 @@ static const uint8_t reset_sound_mask = 1 << 4; static const uint8_t reset_display_mask = 1 << 5; static const uint8_t reset_blink_mask = 1 << 6; -void notification_vibro_on(bool force); -void notification_vibro_off(); -void notification_sound_on(float freq, float volume, bool force); -void notification_sound_off(); +static void notification_vibro_on(bool force); +static void notification_vibro_off(); +static void notification_sound_on(float freq, float volume, bool force); +static void notification_sound_off(); -uint8_t notification_settings_get_display_brightness(NotificationApp* app, uint8_t value); -uint8_t notification_settings_get_rgb_led_brightness(NotificationApp* app, uint8_t value); -uint32_t notification_settings_display_off_delay_ticks(NotificationApp* app); +static uint8_t notification_settings_get_display_brightness(NotificationApp* app, uint8_t value); +static uint8_t notification_settings_get_rgb_led_brightness(NotificationApp* app, uint8_t value); +static uint32_t notification_settings_display_off_delay_ticks(NotificationApp* app); void notification_message_save_settings(NotificationApp* app) { NotificationAppMessage m = { @@ -40,7 +43,8 @@ void notification_message_save_settings(NotificationApp* app) { } // internal layer -void notification_apply_internal_led_layer(NotificationLedLayer* layer, uint8_t layer_value) { +static void + notification_apply_internal_led_layer(NotificationLedLayer* layer, uint8_t layer_value) { furi_assert(layer); furi_assert(layer->index < LayerMAX); @@ -53,7 +57,13 @@ void notification_apply_internal_led_layer(NotificationLedLayer* layer, uint8_t } } -bool notification_is_any_led_layer_internal_and_not_empty(NotificationApp* app) { +static void notification_apply_lcd_contrast(NotificationApp* app) { + Gui* gui = furi_record_open(RECORD_GUI); + u8x8_d_st756x_set_contrast(&gui->canvas->fb.u8x8, app->settings.contrast); + furi_record_close(RECORD_GUI); +} + +static bool notification_is_any_led_layer_internal_and_not_empty(NotificationApp* app) { bool result = false; if((app->led[0].index == LayerInternal) || (app->led[1].index == LayerInternal) || (app->led[2].index == LayerInternal)) { @@ -68,7 +78,7 @@ bool notification_is_any_led_layer_internal_and_not_empty(NotificationApp* app) } // notification layer -void notification_apply_notification_led_layer( +static void notification_apply_notification_led_layer( NotificationLedLayer* layer, const uint8_t layer_value) { furi_assert(layer); @@ -82,7 +92,7 @@ void notification_apply_notification_led_layer( furi_hal_light_set(layer->light, layer->value[LayerNotification]); } -void notification_reset_notification_led_layer(NotificationLedLayer* layer) { +static void notification_reset_notification_led_layer(NotificationLedLayer* layer) { furi_assert(layer); furi_assert(layer->index < LayerMAX); @@ -95,7 +105,7 @@ void notification_reset_notification_led_layer(NotificationLedLayer* layer) { furi_hal_light_set(layer->light, layer->value[LayerInternal]); } -void notification_reset_notification_layer(NotificationApp* app, uint8_t reset_mask) { +static void notification_reset_notification_layer(NotificationApp* app, uint8_t reset_mask) { if(reset_mask & reset_blink_mask) { furi_hal_light_blink_stop(); } @@ -131,28 +141,28 @@ uint8_t notification_settings_get_display_brightness(NotificationApp* app, uint8 return (value * app->settings.display_brightness); } -uint8_t notification_settings_get_rgb_led_brightness(NotificationApp* app, uint8_t value) { +static uint8_t notification_settings_get_rgb_led_brightness(NotificationApp* app, uint8_t value) { return (value * app->settings.led_brightness); } -uint32_t notification_settings_display_off_delay_ticks(NotificationApp* app) { +static uint32_t notification_settings_display_off_delay_ticks(NotificationApp* app) { return ( (float)(app->settings.display_off_delay_ms) / (1000.0f / furi_kernel_get_tick_frequency())); } // generics -void notification_vibro_on(bool force) { +static void notification_vibro_on(bool force) { if(!furi_hal_rtc_is_flag_set(FuriHalRtcFlagStealthMode) || force) { furi_hal_vibro_on(true); } } -void notification_vibro_off() { +static void notification_vibro_off() { furi_hal_vibro_on(false); } -void notification_sound_on(float freq, float volume, bool force) { +static void notification_sound_on(float freq, float volume, bool force) { if(!furi_hal_rtc_is_flag_set(FuriHalRtcFlagStealthMode) || force) { if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) { furi_hal_speaker_start(freq, volume); @@ -160,7 +170,7 @@ void notification_sound_on(float freq, float volume, bool force) { } } -void notification_sound_off() { +static void notification_sound_off() { if(furi_hal_speaker_is_mine()) { furi_hal_speaker_stop(); furi_hal_speaker_release(); @@ -175,7 +185,7 @@ static void notification_display_timer(void* ctx) { } // message processing -void notification_process_notification_message( +static void notification_process_notification_message( NotificationApp* app, NotificationAppMessage* message) { uint32_t notification_message_index = 0; @@ -334,6 +344,9 @@ void notification_process_notification_message( reset_mask |= reset_green_mask; reset_mask |= reset_blue_mask; break; + case NotificationMessageTypeLcdContrastUpdate: + notification_apply_lcd_contrast(app); + break; } notification_message_index++; notification_message = (*message->sequence)[notification_message_index]; @@ -362,7 +375,8 @@ void notification_process_notification_message( } } -void notification_process_internal_message(NotificationApp* app, NotificationAppMessage* message) { +static void + notification_process_internal_message(NotificationApp* app, NotificationAppMessage* message) { uint32_t notification_message_index = 0; const NotificationMessage* notification_message; notification_message = (*message->sequence)[notification_message_index]; @@ -495,6 +509,7 @@ int32_t notification_srv(void* p) { notification_apply_internal_led_layer(&app->led[0], 0x00); notification_apply_internal_led_layer(&app->led[1], 0x00); notification_apply_internal_led_layer(&app->led[2], 0x00); + notification_apply_lcd_contrast(app); furi_record_create(RECORD_NOTIFICATION, app); diff --git a/applications/services/notification/notification_app.h b/applications/services/notification/notification_app.h index 92a668ee9..fe315ef88 100644 --- a/applications/services/notification/notification_app.h +++ b/applications/services/notification/notification_app.h @@ -31,7 +31,7 @@ typedef struct { Light light; } NotificationLedLayer; -#define NOTIFICATION_SETTINGS_VERSION 0x01 +#define NOTIFICATION_SETTINGS_VERSION 0x02 #define NOTIFICATION_SETTINGS_MAGIC 0x16 #define NOTIFICATION_SETTINGS_OLD_PATH INT_PATH(".notification.settings") #define NOTIFICATION_SETTINGS_PATH CFG_PATH("notification.settings") @@ -42,6 +42,7 @@ typedef struct { float led_brightness; float speaker_volume; uint32_t display_off_delay_ms; + int8_t contrast; bool vibro_on; } NotificationSettings; diff --git a/applications/services/notification/notification_messages.c b/applications/services/notification/notification_messages.c index 51f3533c3..28ec327c6 100644 --- a/applications/services/notification/notification_messages.c +++ b/applications/services/notification/notification_messages.c @@ -197,6 +197,10 @@ const NotificationMessage message_force_display_brightness_setting_1f = { .data.forced_settings.display_brightness = 1.0f, }; +const NotificationMessage message_lcd_contrast_update = { + .type = NotificationMessageTypeLcdContrastUpdate, +}; + /****************************** Message sequences ******************************/ // Reset @@ -566,3 +570,8 @@ const NotificationSequence sequence_audiovisual_alert = { &message_vibro_off, NULL, }; + +const NotificationSequence sequence_lcd_contrast_update = { + &message_lcd_contrast_update, + NULL, +}; diff --git a/applications/services/notification/notification_messages.h b/applications/services/notification/notification_messages.h index 100796917..d87cf74f4 100644 --- a/applications/services/notification/notification_messages.h +++ b/applications/services/notification/notification_messages.h @@ -63,6 +63,9 @@ extern const NotificationMessage message_force_vibro_setting_on; extern const NotificationMessage message_force_vibro_setting_off; extern const NotificationMessage message_force_display_brightness_setting_1f; +// LCD Messages +extern const NotificationMessage message_lcd_contrast_update; + /****************************** Message sequences ******************************/ // Reset @@ -138,6 +141,9 @@ extern const NotificationSequence sequence_success; extern const NotificationSequence sequence_error; extern const NotificationSequence sequence_audiovisual_alert; +// LCD +extern const NotificationSequence sequence_lcd_contrast_update; + #ifdef __cplusplus } #endif diff --git a/applications/settings/notification_settings/notification_settings_app.c b/applications/settings/notification_settings/notification_settings_app.c index 364734a62..04c021913 100644 --- a/applications/settings/notification_settings/notification_settings_app.c +++ b/applications/settings/notification_settings/notification_settings_app.c @@ -20,6 +20,34 @@ static const NotificationSequence sequence_note_c = { NULL, }; +#define CONTRAST_COUNT 11 +const char* const contrast_text[CONTRAST_COUNT] = { + "-5", + "-4", + "-3", + "-2", + "-1", + "0", + "+1", + "+2", + "+3", + "+4", + "+5", +}; +const int32_t contrast_value[CONTRAST_COUNT] = { + -5, + -4, + -3, + -2, + -1, + 0, + 1, + 2, + 3, + 4, + 5, +}; + #define BACKLIGHT_COUNT 21 const char* const backlight_text[BACKLIGHT_COUNT] = { "0%", "5%", "10%", "15%", "20%", "25%", "30%", "35%", "40%", "45%", "50%", @@ -64,6 +92,15 @@ const char* const vibro_text[VIBRO_COUNT] = { }; const bool vibro_value[VIBRO_COUNT] = {false, true}; +static void contrast_changed(VariableItem* item) { + NotificationAppSettings* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + + variable_item_set_current_value_text(item, contrast_text[index]); + app->notification->settings.contrast = contrast_value[index]; + notification_message(app->notification, &sequence_lcd_contrast_update); +} + static void backlight_changed(VariableItem* item) { NotificationAppSettings* app = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); @@ -136,6 +173,13 @@ static NotificationAppSettings* alloc_settings() { VariableItem* item; uint8_t value_index; + item = variable_item_list_add( + app->variable_item_list, "LCD Contrast", CONTRAST_COUNT, contrast_changed, app); + value_index = + value_index_int32(app->notification->settings.contrast, contrast_value, CONTRAST_COUNT); + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, contrast_text[value_index]); + item = variable_item_list_add( app->variable_item_list, "LCD Brightness", BACKLIGHT_COUNT, backlight_changed, app); value_index = value_index_float( diff --git a/assets/icons/NFC/Restoring_38x32.png b/assets/icons/NFC/Restoring_38x32.png deleted file mode 100644 index 9e058869f..000000000 Binary files a/assets/icons/NFC/Restoring_38x32.png and /dev/null differ diff --git a/firmware/targets/f18/api_symbols.csv b/firmware/targets/f18/api_symbols.csv index 3c075e0d1..f551a09c1 100644 --- a/firmware/targets/f18/api_symbols.csv +++ b/firmware/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,28.2,, +Version,+,29.0,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -288,6 +288,8 @@ Function,+,__clear_cache,void,"void*, void*" Function,-,__eprintf,void,"const char*, const char*, unsigned int, const char*" Function,+,__errno,int*, Function,+,__furi_crash,void, +Function,+,__furi_critical_enter,__FuriCriticalInfo, +Function,+,__furi_critical_exit,void,__FuriCriticalInfo Function,+,__furi_halt,void, Function,-,__getdelim,ssize_t,"char**, size_t*, int, FILE*" Function,-,__getline,ssize_t,"char**, size_t*, FILE*" @@ -1999,6 +2001,7 @@ Function,+,validator_is_file_callback,_Bool,"const char*, FuriString*, void*" Function,+,validator_is_file_free,void,ValidatorIsFile* Function,+,value_index_bool,uint8_t,"const _Bool, const _Bool[], uint8_t" Function,+,value_index_float,uint8_t,"const float, const float[], uint8_t" +Function,+,value_index_int32,uint8_t,"const int32_t, const int32_t[], uint8_t" Function,+,value_index_uint32,uint8_t,"const uint32_t, const uint32_t[], uint8_t" Function,+,variable_item_get_context,void*,VariableItem* Function,+,variable_item_get_current_value_index,uint8_t,VariableItem* @@ -2259,6 +2262,7 @@ Variable,+,message_force_vibro_setting_off,const NotificationMessage, Variable,+,message_force_vibro_setting_on,const NotificationMessage, Variable,+,message_green_0,const NotificationMessage, Variable,+,message_green_255,const NotificationMessage, +Variable,+,message_lcd_contrast_update,const NotificationMessage, Variable,+,message_note_a0,const NotificationMessage, Variable,+,message_note_a1,const NotificationMessage, Variable,+,message_note_a2,const NotificationMessage, @@ -2402,6 +2406,7 @@ Variable,+,sequence_display_backlight_off_delay_1000,const NotificationSequence, Variable,+,sequence_display_backlight_on,const NotificationSequence, Variable,+,sequence_double_vibro,const NotificationSequence, Variable,+,sequence_error,const NotificationSequence, +Variable,+,sequence_lcd_contrast_update,const NotificationSequence, Variable,+,sequence_not_charging,const NotificationSequence, Variable,+,sequence_reset_blue,const NotificationSequence, Variable,+,sequence_reset_display,const NotificationSequence, diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 5a8de3d23..61b430e99 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,28.2,, +Version,+,29.0,, Header,+,applications/main/archive/helpers/favorite_timeout.h,, Header,+,applications/main/fap_loader/fap_loader_app.h,, Header,+,applications/main/subghz/helpers/subghz_txrx.h,, @@ -192,10 +192,10 @@ Header,+,lib/subghz/blocks/encoder.h,, Header,+,lib/subghz/blocks/generic.h,, Header,+,lib/subghz/blocks/math.h,, Header,+,lib/subghz/environment.h,, -Header,+,lib/subghz/protocols/protocol_items.h,, Header,+,lib/subghz/protocols/raw.h,, Header,+,lib/subghz/receiver.h,, Header,+,lib/subghz/registry.h,, +Header,+,lib/subghz/subghz_protocol_registry.h,, Header,+,lib/subghz/subghz_setting.h,, Header,+,lib/subghz/subghz_tx_rx_worker.h,, Header,+,lib/subghz/subghz_worker.h,, @@ -337,6 +337,8 @@ Function,+,__errno,int*, Function,-,__fpclassifyd,int,double Function,-,__fpclassifyf,int,float Function,+,__furi_crash,void, +Function,+,__furi_critical_enter,__FuriCriticalInfo, +Function,+,__furi_critical_exit,void,__FuriCriticalInfo Function,+,__furi_halt,void, Function,-,__getdelim,ssize_t,"char**, size_t*, int, FILE*" Function,-,__getline,ssize_t,"char**, size_t*, FILE*" @@ -558,8 +560,6 @@ Function,-,atoff,float,const char* Function,+,atoi,int,const char* Function,-,atol,long,const char* Function,-,atoll,long long,const char* -Function,-,atomo_decrypt,void,uint8_t* -Function,-,atomo_encrypt,void,uint8_t* Function,-,basename,char*,const char* Function,-,bcmp,int,"const void*, const void*, size_t" Function,-,bcopy,void,"const void*, void*, size_t" @@ -2782,13 +2782,13 @@ Function,+,subghz_environment_get_came_atomo_rainbow_table_file_name,const char* Function,+,subghz_environment_get_keystore,SubGhzKeystore*,SubGhzEnvironment* Function,+,subghz_environment_get_nice_flor_s_rainbow_table_file_name,const char*,SubGhzEnvironment* Function,+,subghz_environment_get_protocol_name_registry,const char*,"SubGhzEnvironment*, size_t" -Function,+,subghz_environment_get_protocol_registry,void*,SubGhzEnvironment* +Function,+,subghz_environment_get_protocol_registry,const SubGhzProtocolRegistry*,SubGhzEnvironment* Function,+,subghz_environment_load_keystore,_Bool,"SubGhzEnvironment*, const char*" Function,+,subghz_environment_reset_keeloq,void,SubGhzEnvironment* Function,+,subghz_environment_set_alutech_at_4n_rainbow_table_file_name,void,"SubGhzEnvironment*, const char*" Function,+,subghz_environment_set_came_atomo_rainbow_table_file_name,void,"SubGhzEnvironment*, const char*" Function,+,subghz_environment_set_nice_flor_s_rainbow_table_file_name,void,"SubGhzEnvironment*, const char*" -Function,+,subghz_environment_set_protocol_registry,void,"SubGhzEnvironment*, void*" +Function,+,subghz_environment_set_protocol_registry,void,"SubGhzEnvironment*, const SubGhzProtocolRegistry*" Function,-,subghz_keystore_alloc,SubGhzKeystore*, Function,-,subghz_keystore_free,void,SubGhzKeystore* Function,-,subghz_keystore_get_data,SubGhzKeyArray_t*,SubGhzKeystore* @@ -2797,7 +2797,6 @@ Function,-,subghz_keystore_raw_encrypted_save,_Bool,"const char*, const char*, u Function,-,subghz_keystore_raw_get_data,_Bool,"const char*, size_t, uint8_t*, size_t" Function,-,subghz_keystore_reset_kl,void,SubGhzKeystore* Function,-,subghz_keystore_save,_Bool,"SubGhzKeystore*, const char*, uint8_t*" -Function,-,subghz_protocol_alutech_at_4n_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, SubGhzRadioPreset*" Function,+,subghz_protocol_blocks_add_bit,void,"SubGhzBlockDecoder*, uint8_t" Function,+,subghz_protocol_blocks_add_bytes,uint8_t,"const uint8_t[], size_t" Function,+,subghz_protocol_blocks_add_to_128_bit,void,"SubGhzBlockDecoder*, uint8_t, uint64_t*" @@ -2819,547 +2818,22 @@ Function,+,subghz_protocol_blocks_parity_bytes,uint8_t,"const uint8_t[], size_t" Function,+,subghz_protocol_blocks_reverse_key,uint64_t,"uint64_t, uint8_t" Function,+,subghz_protocol_blocks_set_bit_array,void,"_Bool, uint8_t[], size_t, size_t" Function,+,subghz_protocol_blocks_xor_bytes,uint8_t,"const uint8_t[], size_t" -Function,-,subghz_protocol_came_atomo_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint16_t, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_alutech_at_4n_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_alutech_at_4n_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_alutech_at_4n_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_alutech_at_4n_free,void,void* -Function,-,subghz_protocol_decoder_alutech_at_4n_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_alutech_at_4n_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_alutech_at_4n_reset,void,void* -Function,-,subghz_protocol_decoder_alutech_at_4n_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_ansonic_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_ansonic_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_ansonic_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_ansonic_free,void,void* -Function,-,subghz_protocol_decoder_ansonic_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_ansonic_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_ansonic_reset,void,void* -Function,-,subghz_protocol_decoder_ansonic_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" Function,+,subghz_protocol_decoder_base_deserialize,SubGhzProtocolStatus,"SubGhzProtocolDecoderBase*, FlipperFormat*" Function,+,subghz_protocol_decoder_base_get_hash_data,uint8_t,SubGhzProtocolDecoderBase* Function,+,subghz_protocol_decoder_base_get_string,_Bool,"SubGhzProtocolDecoderBase*, FuriString*" Function,+,subghz_protocol_decoder_base_serialize,SubGhzProtocolStatus,"SubGhzProtocolDecoderBase*, FlipperFormat*, SubGhzRadioPreset*" Function,-,subghz_protocol_decoder_base_set_decoder_callback,void,"SubGhzProtocolDecoderBase*, SubGhzProtocolDecoderBaseRxCallback, void*" -Function,-,subghz_protocol_decoder_bett_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_bett_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_bett_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_bett_free,void,void* -Function,-,subghz_protocol_decoder_bett_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_bett_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_bett_reset,void,void* -Function,-,subghz_protocol_decoder_bett_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_bin_raw_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_bin_raw_data_input_rssi,void,"SubGhzProtocolDecoderBinRAW*, float" -Function,-,subghz_protocol_decoder_bin_raw_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_bin_raw_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_bin_raw_free,void,void* -Function,-,subghz_protocol_decoder_bin_raw_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_bin_raw_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_bin_raw_reset,void,void* -Function,-,subghz_protocol_decoder_bin_raw_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_came_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_came_atomo_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_came_atomo_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_came_atomo_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_came_atomo_free,void,void* -Function,-,subghz_protocol_decoder_came_atomo_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_came_atomo_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_came_atomo_reset,void,void* -Function,-,subghz_protocol_decoder_came_atomo_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_came_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_came_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_came_free,void,void* -Function,-,subghz_protocol_decoder_came_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_came_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_came_reset,void,void* -Function,-,subghz_protocol_decoder_came_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_came_twee_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_came_twee_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_came_twee_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_came_twee_free,void,void* -Function,-,subghz_protocol_decoder_came_twee_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_came_twee_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_came_twee_reset,void,void* -Function,-,subghz_protocol_decoder_came_twee_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_chamb_code_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_chamb_code_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_chamb_code_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_chamb_code_free,void,void* -Function,-,subghz_protocol_decoder_chamb_code_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_chamb_code_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_chamb_code_reset,void,void* -Function,-,subghz_protocol_decoder_chamb_code_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_clemsa_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_clemsa_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_clemsa_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_clemsa_free,void,void* -Function,-,subghz_protocol_decoder_clemsa_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_clemsa_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_clemsa_reset,void,void* -Function,-,subghz_protocol_decoder_clemsa_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_doitrand_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_doitrand_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_doitrand_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_doitrand_free,void,void* -Function,-,subghz_protocol_decoder_doitrand_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_doitrand_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_doitrand_reset,void,void* -Function,-,subghz_protocol_decoder_doitrand_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_dooya_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_dooya_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_dooya_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_dooya_free,void,void* -Function,-,subghz_protocol_decoder_dooya_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_dooya_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_dooya_reset,void,void* -Function,-,subghz_protocol_decoder_dooya_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_faac_slh_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_faac_slh_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_faac_slh_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_faac_slh_free,void,void* -Function,-,subghz_protocol_decoder_faac_slh_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_faac_slh_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_faac_slh_reset,void,void* -Function,-,subghz_protocol_decoder_faac_slh_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_gate_tx_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_gate_tx_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_gate_tx_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_gate_tx_free,void,void* -Function,-,subghz_protocol_decoder_gate_tx_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_gate_tx_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_gate_tx_reset,void,void* -Function,-,subghz_protocol_decoder_gate_tx_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_holtek_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_holtek_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_holtek_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_holtek_free,void,void* -Function,-,subghz_protocol_decoder_holtek_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_holtek_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_holtek_reset,void,void* -Function,-,subghz_protocol_decoder_holtek_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_holtek_th12x_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_holtek_th12x_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_holtek_th12x_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_holtek_th12x_free,void,void* -Function,-,subghz_protocol_decoder_holtek_th12x_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_holtek_th12x_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_holtek_th12x_reset,void,void* -Function,-,subghz_protocol_decoder_holtek_th12x_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_honeywell_wdb_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_honeywell_wdb_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_honeywell_wdb_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_honeywell_wdb_free,void,void* -Function,-,subghz_protocol_decoder_honeywell_wdb_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_honeywell_wdb_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_honeywell_wdb_reset,void,void* -Function,-,subghz_protocol_decoder_honeywell_wdb_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_hormann_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_hormann_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_hormann_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_hormann_free,void,void* -Function,-,subghz_protocol_decoder_hormann_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_hormann_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_hormann_reset,void,void* -Function,-,subghz_protocol_decoder_hormann_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_ido_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_ido_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_ido_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_ido_free,void,void* -Function,-,subghz_protocol_decoder_ido_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_ido_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_ido_reset,void,void* -Function,-,subghz_protocol_decoder_ido_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_intertechno_v3_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_intertechno_v3_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_intertechno_v3_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_intertechno_v3_free,void,void* -Function,-,subghz_protocol_decoder_intertechno_v3_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_intertechno_v3_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_intertechno_v3_reset,void,void* -Function,-,subghz_protocol_decoder_intertechno_v3_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_keeloq_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_keeloq_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_keeloq_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_keeloq_free,void,void* -Function,-,subghz_protocol_decoder_keeloq_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_keeloq_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_keeloq_reset,void,void* -Function,-,subghz_protocol_decoder_keeloq_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_kia_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_kia_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_kia_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_kia_free,void,void* -Function,-,subghz_protocol_decoder_kia_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_kia_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_kia_reset,void,void* -Function,-,subghz_protocol_decoder_kia_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_kinggates_stylo_4k_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_kinggates_stylo_4k_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_kinggates_stylo_4k_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_kinggates_stylo_4k_free,void,void* -Function,-,subghz_protocol_decoder_kinggates_stylo_4k_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_kinggates_stylo_4k_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_kinggates_stylo_4k_reset,void,void* -Function,-,subghz_protocol_decoder_kinggates_stylo_4k_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_linear_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_linear_delta3_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_linear_delta3_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_linear_delta3_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_linear_delta3_free,void,void* -Function,-,subghz_protocol_decoder_linear_delta3_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_linear_delta3_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_linear_delta3_reset,void,void* -Function,-,subghz_protocol_decoder_linear_delta3_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_linear_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_linear_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_linear_free,void,void* -Function,-,subghz_protocol_decoder_linear_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_linear_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_linear_reset,void,void* -Function,-,subghz_protocol_decoder_linear_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_magellan_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_magellan_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_magellan_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_magellan_free,void,void* -Function,-,subghz_protocol_decoder_magellan_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_magellan_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_magellan_reset,void,void* -Function,-,subghz_protocol_decoder_magellan_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_marantec_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_marantec_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_marantec_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_marantec_free,void,void* -Function,-,subghz_protocol_decoder_marantec_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_marantec_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_marantec_reset,void,void* -Function,-,subghz_protocol_decoder_marantec_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_megacode_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_megacode_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_megacode_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_megacode_free,void,void* -Function,-,subghz_protocol_decoder_megacode_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_megacode_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_megacode_reset,void,void* -Function,-,subghz_protocol_decoder_megacode_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_nero_radio_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_nero_radio_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_nero_radio_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_nero_radio_free,void,void* -Function,-,subghz_protocol_decoder_nero_radio_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_nero_radio_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_nero_radio_reset,void,void* -Function,-,subghz_protocol_decoder_nero_radio_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_nero_sketch_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_nero_sketch_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_nero_sketch_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_nero_sketch_free,void,void* -Function,-,subghz_protocol_decoder_nero_sketch_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_nero_sketch_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_nero_sketch_reset,void,void* -Function,-,subghz_protocol_decoder_nero_sketch_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_nice_flo_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_nice_flo_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_nice_flo_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_nice_flo_free,void,void* -Function,-,subghz_protocol_decoder_nice_flo_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_nice_flo_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_nice_flo_reset,void,void* -Function,-,subghz_protocol_decoder_nice_flo_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_nice_flor_s_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_nice_flor_s_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_nice_flor_s_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_nice_flor_s_free,void,void* -Function,-,subghz_protocol_decoder_nice_flor_s_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_nice_flor_s_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_nice_flor_s_reset,void,void* -Function,-,subghz_protocol_decoder_nice_flor_s_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_phoenix_v2_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_phoenix_v2_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_phoenix_v2_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_phoenix_v2_free,void,void* -Function,-,subghz_protocol_decoder_phoenix_v2_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_phoenix_v2_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_phoenix_v2_reset,void,void* -Function,-,subghz_protocol_decoder_phoenix_v2_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_power_smart_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_power_smart_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_power_smart_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_power_smart_free,void,void* -Function,-,subghz_protocol_decoder_power_smart_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_power_smart_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_power_smart_reset,void,void* -Function,-,subghz_protocol_decoder_power_smart_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_princeton_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_princeton_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_princeton_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_princeton_free,void,void* -Function,-,subghz_protocol_decoder_princeton_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_princeton_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_princeton_reset,void,void* -Function,-,subghz_protocol_decoder_princeton_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" Function,+,subghz_protocol_decoder_raw_alloc,void*,SubGhzEnvironment* Function,+,subghz_protocol_decoder_raw_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" Function,+,subghz_protocol_decoder_raw_feed,void,"void*, _Bool, uint32_t" Function,+,subghz_protocol_decoder_raw_free,void,void* Function,+,subghz_protocol_decoder_raw_get_string,void,"void*, FuriString*" Function,+,subghz_protocol_decoder_raw_reset,void,void* -Function,-,subghz_protocol_decoder_scher_khan_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_scher_khan_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_scher_khan_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_scher_khan_free,void,void* -Function,-,subghz_protocol_decoder_scher_khan_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_scher_khan_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_scher_khan_reset,void,void* -Function,-,subghz_protocol_decoder_scher_khan_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_secplus_v1_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_secplus_v1_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_secplus_v1_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_secplus_v1_free,void,void* -Function,-,subghz_protocol_decoder_secplus_v1_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_secplus_v1_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_secplus_v1_reset,void,void* -Function,-,subghz_protocol_decoder_secplus_v1_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_secplus_v2_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_secplus_v2_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_secplus_v2_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_secplus_v2_free,void,void* -Function,-,subghz_protocol_decoder_secplus_v2_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_secplus_v2_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_secplus_v2_reset,void,void* -Function,-,subghz_protocol_decoder_secplus_v2_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_smc5326_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_smc5326_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_smc5326_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_smc5326_free,void,void* -Function,-,subghz_protocol_decoder_smc5326_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_smc5326_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_smc5326_reset,void,void* -Function,-,subghz_protocol_decoder_smc5326_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_somfy_keytis_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_somfy_keytis_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_somfy_keytis_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_somfy_keytis_free,void,void* -Function,-,subghz_protocol_decoder_somfy_keytis_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_somfy_keytis_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_somfy_keytis_reset,void,void* -Function,-,subghz_protocol_decoder_somfy_keytis_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_somfy_telis_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_somfy_telis_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_somfy_telis_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_somfy_telis_free,void,void* -Function,-,subghz_protocol_decoder_somfy_telis_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_somfy_telis_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_somfy_telis_reset,void,void* -Function,-,subghz_protocol_decoder_somfy_telis_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_decoder_star_line_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_decoder_star_line_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_decoder_star_line_feed,void,"void*, _Bool, uint32_t" -Function,-,subghz_protocol_decoder_star_line_free,void,void* -Function,-,subghz_protocol_decoder_star_line_get_hash_data,uint8_t,void* -Function,-,subghz_protocol_decoder_star_line_get_string,void,"void*, FuriString*" -Function,-,subghz_protocol_decoder_star_line_reset,void,void* -Function,-,subghz_protocol_decoder_star_line_serialize,SubGhzProtocolStatus,"void*, FlipperFormat*, SubGhzRadioPreset*" -Function,-,subghz_protocol_encoder_alutech_at_4n_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_alutech_at_4n_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_alutech_at_4n_free,void,void* -Function,-,subghz_protocol_encoder_alutech_at_4n_stop,void,void* -Function,-,subghz_protocol_encoder_alutech_at_4n_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_ansonic_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_ansonic_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_ansonic_free,void,void* -Function,-,subghz_protocol_encoder_ansonic_stop,void,void* -Function,-,subghz_protocol_encoder_ansonic_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_bett_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_bett_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_bett_free,void,void* -Function,-,subghz_protocol_encoder_bett_stop,void,void* -Function,-,subghz_protocol_encoder_bett_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_bin_raw_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_bin_raw_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_bin_raw_free,void,void* -Function,-,subghz_protocol_encoder_bin_raw_stop,void,void* -Function,-,subghz_protocol_encoder_bin_raw_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_came_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_came_atomo_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_came_atomo_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_came_atomo_free,void,void* -Function,-,subghz_protocol_encoder_came_atomo_stop,void,void* -Function,-,subghz_protocol_encoder_came_atomo_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_came_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_came_free,void,void* -Function,-,subghz_protocol_encoder_came_stop,void,void* -Function,-,subghz_protocol_encoder_came_twee_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_came_twee_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_came_twee_free,void,void* -Function,-,subghz_protocol_encoder_came_twee_stop,void,void* -Function,-,subghz_protocol_encoder_came_twee_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_came_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_chamb_code_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_chamb_code_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_chamb_code_free,void,void* -Function,-,subghz_protocol_encoder_chamb_code_stop,void,void* -Function,-,subghz_protocol_encoder_chamb_code_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_clemsa_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_clemsa_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_clemsa_free,void,void* -Function,-,subghz_protocol_encoder_clemsa_stop,void,void* -Function,-,subghz_protocol_encoder_clemsa_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_doitrand_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_doitrand_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_doitrand_free,void,void* -Function,-,subghz_protocol_encoder_doitrand_stop,void,void* -Function,-,subghz_protocol_encoder_doitrand_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_dooya_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_dooya_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_dooya_free,void,void* -Function,-,subghz_protocol_encoder_dooya_stop,void,void* -Function,-,subghz_protocol_encoder_dooya_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_faac_slh_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_faac_slh_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_faac_slh_free,void,void* -Function,-,subghz_protocol_encoder_faac_slh_stop,void,void* -Function,-,subghz_protocol_encoder_faac_slh_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_gate_tx_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_gate_tx_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_gate_tx_free,void,void* -Function,-,subghz_protocol_encoder_gate_tx_stop,void,void* -Function,-,subghz_protocol_encoder_gate_tx_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_holtek_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_holtek_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_holtek_free,void,void* -Function,-,subghz_protocol_encoder_holtek_stop,void,void* -Function,-,subghz_protocol_encoder_holtek_th12x_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_holtek_th12x_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_holtek_th12x_free,void,void* -Function,-,subghz_protocol_encoder_holtek_th12x_stop,void,void* -Function,-,subghz_protocol_encoder_holtek_th12x_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_holtek_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_honeywell_wdb_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_honeywell_wdb_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_honeywell_wdb_free,void,void* -Function,-,subghz_protocol_encoder_honeywell_wdb_stop,void,void* -Function,-,subghz_protocol_encoder_honeywell_wdb_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_hormann_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_hormann_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_hormann_free,void,void* -Function,-,subghz_protocol_encoder_hormann_stop,void,void* -Function,-,subghz_protocol_encoder_hormann_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_intertechno_v3_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_intertechno_v3_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_intertechno_v3_free,void,void* -Function,-,subghz_protocol_encoder_intertechno_v3_stop,void,void* -Function,-,subghz_protocol_encoder_intertechno_v3_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_keeloq_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_keeloq_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_keeloq_free,void,void* -Function,-,subghz_protocol_encoder_keeloq_stop,void,void* -Function,-,subghz_protocol_encoder_keeloq_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_kinggates_stylo_4k_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_kinggates_stylo_4k_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_kinggates_stylo_4k_free,void,void* -Function,-,subghz_protocol_encoder_kinggates_stylo_4k_stop,void,void* -Function,-,subghz_protocol_encoder_kinggates_stylo_4k_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_linear_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_linear_delta3_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_linear_delta3_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_linear_delta3_free,void,void* -Function,-,subghz_protocol_encoder_linear_delta3_stop,void,void* -Function,-,subghz_protocol_encoder_linear_delta3_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_linear_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_linear_free,void,void* -Function,-,subghz_protocol_encoder_linear_stop,void,void* -Function,-,subghz_protocol_encoder_linear_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_magellan_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_magellan_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_magellan_free,void,void* -Function,-,subghz_protocol_encoder_magellan_stop,void,void* -Function,-,subghz_protocol_encoder_magellan_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_marantec_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_marantec_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_marantec_free,void,void* -Function,-,subghz_protocol_encoder_marantec_stop,void,void* -Function,-,subghz_protocol_encoder_marantec_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_megacode_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_megacode_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_megacode_free,void,void* -Function,-,subghz_protocol_encoder_megacode_stop,void,void* -Function,-,subghz_protocol_encoder_megacode_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_nero_radio_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_nero_radio_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_nero_radio_free,void,void* -Function,-,subghz_protocol_encoder_nero_radio_stop,void,void* -Function,-,subghz_protocol_encoder_nero_radio_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_nero_sketch_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_nero_sketch_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_nero_sketch_free,void,void* -Function,-,subghz_protocol_encoder_nero_sketch_stop,void,void* -Function,-,subghz_protocol_encoder_nero_sketch_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_nice_flo_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_nice_flo_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_nice_flo_free,void,void* -Function,-,subghz_protocol_encoder_nice_flo_stop,void,void* -Function,-,subghz_protocol_encoder_nice_flo_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_nice_flor_s_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_nice_flor_s_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_nice_flor_s_free,void,void* -Function,-,subghz_protocol_encoder_nice_flor_s_stop,void,void* -Function,-,subghz_protocol_encoder_nice_flor_s_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_phoenix_v2_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_phoenix_v2_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_phoenix_v2_free,void,void* -Function,-,subghz_protocol_encoder_phoenix_v2_stop,void,void* -Function,-,subghz_protocol_encoder_phoenix_v2_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_power_smart_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_power_smart_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_power_smart_free,void,void* -Function,-,subghz_protocol_encoder_power_smart_stop,void,void* -Function,-,subghz_protocol_encoder_power_smart_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_princeton_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_princeton_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_princeton_free,void,void* -Function,-,subghz_protocol_encoder_princeton_stop,void,void* -Function,-,subghz_protocol_encoder_princeton_yield,LevelDuration,void* Function,+,subghz_protocol_encoder_raw_alloc,void*,SubGhzEnvironment* Function,+,subghz_protocol_encoder_raw_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" Function,+,subghz_protocol_encoder_raw_free,void,void* Function,+,subghz_protocol_encoder_raw_stop,void,void* Function,+,subghz_protocol_encoder_raw_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_secplus_v1_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_secplus_v1_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_secplus_v1_free,void,void* -Function,-,subghz_protocol_encoder_secplus_v1_stop,void,void* -Function,-,subghz_protocol_encoder_secplus_v1_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_secplus_v2_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_secplus_v2_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_secplus_v2_free,void,void* -Function,-,subghz_protocol_encoder_secplus_v2_stop,void,void* -Function,-,subghz_protocol_encoder_secplus_v2_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_smc5326_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_smc5326_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_smc5326_free,void,void* -Function,-,subghz_protocol_encoder_smc5326_stop,void,void* -Function,-,subghz_protocol_encoder_smc5326_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_somfy_keytis_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_somfy_keytis_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_somfy_keytis_free,void,void* -Function,-,subghz_protocol_encoder_somfy_keytis_stop,void,void* -Function,-,subghz_protocol_encoder_somfy_keytis_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_somfy_telis_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_somfy_telis_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_somfy_telis_free,void,void* -Function,-,subghz_protocol_encoder_somfy_telis_stop,void,void* -Function,-,subghz_protocol_encoder_somfy_telis_yield,LevelDuration,void* -Function,-,subghz_protocol_encoder_star_line_alloc,void*,SubGhzEnvironment* -Function,-,subghz_protocol_encoder_star_line_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*" -Function,-,subghz_protocol_encoder_star_line_free,void,void* -Function,-,subghz_protocol_encoder_star_line_stop,void,void* -Function,-,subghz_protocol_encoder_star_line_yield,LevelDuration,void* -Function,-,subghz_protocol_faac_slh_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint32_t, uint32_t, const char*, SubGhzRadioPreset*" -Function,-,subghz_protocol_keeloq_bft_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, uint32_t, const char*, SubGhzRadioPreset*" -Function,-,subghz_protocol_keeloq_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, const char*, SubGhzRadioPreset*" -Function,-,subghz_protocol_nice_flor_s_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, SubGhzRadioPreset*, _Bool" -Function,-,subghz_protocol_nice_flor_s_encrypt,uint64_t,"uint64_t, const char*" Function,+,subghz_protocol_raw_file_encoder_worker_set_callback_end,void,"SubGhzProtocolEncoderRAW*, SubGhzProtocolEncoderRAWCallbackEnd, void*" Function,+,subghz_protocol_raw_gen_fff_data,void,"FlipperFormat*, const char*" Function,+,subghz_protocol_raw_get_sample_write,size_t,SubGhzProtocolDecoderRAW* @@ -3369,11 +2843,6 @@ Function,+,subghz_protocol_raw_save_to_file_stop,void,SubGhzProtocolDecoderRAW* Function,+,subghz_protocol_registry_count,size_t,const SubGhzProtocolRegistry* Function,+,subghz_protocol_registry_get_by_index,const SubGhzProtocol*,"const SubGhzProtocolRegistry*, size_t" Function,+,subghz_protocol_registry_get_by_name,const SubGhzProtocol*,"const SubGhzProtocolRegistry*, const char*" -Function,-,subghz_protocol_secplus_v1_check_fixed,_Bool,uint32_t -Function,-,subghz_protocol_secplus_v2_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint32_t, SubGhzRadioPreset*" -Function,-,subghz_protocol_somfy_keytis_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, SubGhzRadioPreset*" -Function,-,subghz_protocol_somfy_telis_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, SubGhzRadioPreset*" -Function,-,subghz_protocol_star_line_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, const char*, SubGhzRadioPreset*" Function,+,subghz_receiver_alloc_init,SubGhzReceiver*,SubGhzEnvironment* Function,+,subghz_receiver_decode,void,"SubGhzReceiver*, _Bool, uint32_t" Function,+,subghz_receiver_free,void,SubGhzReceiver* @@ -3898,6 +3367,7 @@ Variable,+,message_force_vibro_setting_off,const NotificationMessage, Variable,+,message_force_vibro_setting_on,const NotificationMessage, Variable,+,message_green_0,const NotificationMessage, Variable,+,message_green_255,const NotificationMessage, +Variable,+,message_lcd_contrast_update,const NotificationMessage, Variable,+,message_note_a0,const NotificationMessage, Variable,+,message_note_a1,const NotificationMessage, Variable,+,message_note_a2,const NotificationMessage, @@ -4041,6 +3511,7 @@ Variable,+,sequence_display_backlight_off_delay_1000,const NotificationSequence, Variable,+,sequence_display_backlight_on,const NotificationSequence, Variable,+,sequence_double_vibro,const NotificationSequence, Variable,+,sequence_error,const NotificationSequence, +Variable,+,sequence_lcd_contrast_update,const NotificationSequence, Variable,+,sequence_not_charging,const NotificationSequence, Variable,+,sequence_reset_blue,const NotificationSequence, Variable,+,sequence_reset_display,const NotificationSequence, @@ -4059,133 +3530,10 @@ Variable,+,sequence_set_vibro_on,const NotificationSequence, Variable,+,sequence_single_vibro,const NotificationSequence, Variable,+,sequence_solid_yellow,const NotificationSequence, Variable,+,sequence_success,const NotificationSequence, -Variable,-,subghz_protocol_alutech_at_4n,const SubGhzProtocol, -Variable,-,subghz_protocol_alutech_at_4n_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_alutech_at_4n_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_ansonic,const SubGhzProtocol, -Variable,-,subghz_protocol_ansonic_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_ansonic_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_bett,const SubGhzProtocol, -Variable,-,subghz_protocol_bett_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_bett_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_bin_raw,const SubGhzProtocol, -Variable,-,subghz_protocol_bin_raw_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_bin_raw_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_came,const SubGhzProtocol, -Variable,-,subghz_protocol_came_atomo,const SubGhzProtocol, -Variable,-,subghz_protocol_came_atomo_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_came_atomo_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_came_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_came_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_came_twee,const SubGhzProtocol, -Variable,-,subghz_protocol_came_twee_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_came_twee_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_chamb_code,const SubGhzProtocol, -Variable,-,subghz_protocol_chamb_code_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_chamb_code_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_clemsa,const SubGhzProtocol, -Variable,-,subghz_protocol_clemsa_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_clemsa_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_doitrand,const SubGhzProtocol, -Variable,-,subghz_protocol_doitrand_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_doitrand_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_dooya,const SubGhzProtocol, -Variable,-,subghz_protocol_dooya_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_dooya_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_faac_slh,const SubGhzProtocol, -Variable,-,subghz_protocol_faac_slh_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_faac_slh_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_gate_tx,const SubGhzProtocol, -Variable,-,subghz_protocol_gate_tx_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_gate_tx_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_holtek,const SubGhzProtocol, -Variable,-,subghz_protocol_holtek_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_holtek_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_holtek_th12x,const SubGhzProtocol, -Variable,-,subghz_protocol_holtek_th12x_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_holtek_th12x_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_honeywell_wdb,const SubGhzProtocol, -Variable,-,subghz_protocol_honeywell_wdb_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_honeywell_wdb_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_hormann,const SubGhzProtocol, -Variable,-,subghz_protocol_hormann_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_hormann_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_ido,const SubGhzProtocol, -Variable,-,subghz_protocol_ido_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_ido_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_intertechno_v3,const SubGhzProtocol, -Variable,-,subghz_protocol_intertechno_v3_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_intertechno_v3_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_keeloq,const SubGhzProtocol, -Variable,-,subghz_protocol_keeloq_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_keeloq_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_kia,const SubGhzProtocol, -Variable,-,subghz_protocol_kia_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_kia_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_kinggates_stylo_4k,const SubGhzProtocol, -Variable,-,subghz_protocol_kinggates_stylo_4k_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_kinggates_stylo_4k_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_linear,const SubGhzProtocol, -Variable,-,subghz_protocol_linear_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_linear_delta3,const SubGhzProtocol, -Variable,-,subghz_protocol_linear_delta3_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_linear_delta3_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_linear_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_magellan,const SubGhzProtocol, -Variable,-,subghz_protocol_magellan_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_magellan_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_marantec,const SubGhzProtocol, -Variable,-,subghz_protocol_marantec_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_marantec_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_megacode,const SubGhzProtocol, -Variable,-,subghz_protocol_megacode_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_megacode_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_nero_radio,const SubGhzProtocol, -Variable,-,subghz_protocol_nero_radio_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_nero_radio_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_nero_sketch,const SubGhzProtocol, -Variable,-,subghz_protocol_nero_sketch_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_nero_sketch_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_nice_flo,const SubGhzProtocol, -Variable,-,subghz_protocol_nice_flo_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_nice_flo_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_nice_flor_s,const SubGhzProtocol, -Variable,-,subghz_protocol_nice_flor_s_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_nice_flor_s_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_phoenix_v2,const SubGhzProtocol, -Variable,-,subghz_protocol_phoenix_v2_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_phoenix_v2_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_power_smart,const SubGhzProtocol, -Variable,-,subghz_protocol_power_smart_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_power_smart_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_princeton,const SubGhzProtocol, -Variable,-,subghz_protocol_princeton_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_princeton_encoder,const SubGhzProtocolEncoder, Variable,+,subghz_protocol_raw,const SubGhzProtocol, Variable,+,subghz_protocol_raw_decoder,const SubGhzProtocolDecoder, Variable,+,subghz_protocol_raw_encoder,const SubGhzProtocolEncoder, Variable,+,subghz_protocol_registry,const SubGhzProtocolRegistry, -Variable,-,subghz_protocol_scher_khan,const SubGhzProtocol, -Variable,-,subghz_protocol_scher_khan_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_scher_khan_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_secplus_v1,const SubGhzProtocol, -Variable,-,subghz_protocol_secplus_v1_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_secplus_v1_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_secplus_v2,const SubGhzProtocol, -Variable,-,subghz_protocol_secplus_v2_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_secplus_v2_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_smc5326,const SubGhzProtocol, -Variable,-,subghz_protocol_smc5326_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_smc5326_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_somfy_keytis,const SubGhzProtocol, -Variable,-,subghz_protocol_somfy_keytis_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_somfy_keytis_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_somfy_telis,const SubGhzProtocol, -Variable,-,subghz_protocol_somfy_telis_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_somfy_telis_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_star_line,const SubGhzProtocol, -Variable,-,subghz_protocol_star_line_decoder,const SubGhzProtocolDecoder, -Variable,-,subghz_protocol_star_line_encoder,const SubGhzProtocolEncoder, Variable,-,suboptarg,char*, Variable,+,usb_cdc_dual,FuriHalUsbInterface, Variable,+,usb_cdc_single,FuriHalUsbInterface, diff --git a/firmware/targets/f7/furi_hal/furi_hal_info.c b/firmware/targets/f7/furi_hal/furi_hal_info.c index 47672c97a..a2c9232c0 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_info.c +++ b/firmware/targets/f7/furi_hal/furi_hal_info.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -23,10 +24,10 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) { // Device Info version if(sep == '.') { property_value_out(&property_context, NULL, 2, "format", "major", "3"); - property_value_out(&property_context, NULL, 2, "format", "minor", "1"); + property_value_out(&property_context, NULL, 2, "format", "minor", "2"); } else { property_value_out(&property_context, NULL, 3, "device", "info", "major", "2"); - property_value_out(&property_context, NULL, 3, "device", "info", "minor", "2"); + property_value_out(&property_context, NULL, 3, "device", "info", "minor", "3"); } // Model name @@ -297,6 +298,18 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) { property_value_out(&property_context, NULL, 2, "radio", "alive", "false"); } + property_value_out( + &property_context, + "%u", + 2, + "system", + "debug", + furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)); + property_value_out( + &property_context, "%u", 3, "system", "heap", "track", furi_hal_rtc_get_heap_track_mode()); + property_value_out( + &property_context, "%u", 3, "system", "log", "level", furi_hal_rtc_get_log_level()); + property_value_out( &property_context, "%u", 3, "protobuf", "version", "major", PROTOBUF_MAJOR_VERSION); property_context.last = true; diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.c b/firmware/targets/f7/furi_hal/furi_hal_resources.c index 9d6cd7caf..63507bd7b 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.c @@ -86,6 +86,7 @@ const GpioPinRecord gpio_pins[] = { /* Dangerous pins, may damage hardware */ {.pin = &gpio_usart_rx, .name = "PB7", .debug = true}, {.pin = &gpio_speaker, .name = "PB8", .debug = true}, + {.pin = &gpio_infrared_tx, .name = "PB9", .debug = true}, }; const size_t gpio_pins_count = sizeof(gpio_pins) / sizeof(GpioPinRecord); diff --git a/furi/core/common_defines.h b/furi/core/common_defines.h index d7bfaf207..5bd218d35 100644 --- a/furi/core/common_defines.h +++ b/furi/core/common_defines.h @@ -31,29 +31,22 @@ extern "C" { #define FURI_IS_ISR() (FURI_IS_IRQ_MODE() || FURI_IS_IRQ_MASKED()) #endif +typedef struct { + uint32_t isrm; + bool from_isr; + bool kernel_running; +} __FuriCriticalInfo; + +__FuriCriticalInfo __furi_critical_enter(void); + +void __furi_critical_exit(__FuriCriticalInfo info); + #ifndef FURI_CRITICAL_ENTER -#define FURI_CRITICAL_ENTER() \ - uint32_t __isrm = 0; \ - bool __from_isr = FURI_IS_ISR(); \ - bool __kernel_running = (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING); \ - if(__from_isr) { \ - __isrm = taskENTER_CRITICAL_FROM_ISR(); \ - } else if(__kernel_running) { \ - taskENTER_CRITICAL(); \ - } else { \ - __disable_irq(); \ - } +#define FURI_CRITICAL_ENTER() __FuriCriticalInfo __furi_critical_info = __furi_critical_enter(); #endif #ifndef FURI_CRITICAL_EXIT -#define FURI_CRITICAL_EXIT() \ - if(__from_isr) { \ - taskEXIT_CRITICAL_FROM_ISR(__isrm); \ - } else if(__kernel_running) { \ - taskEXIT_CRITICAL(); \ - } else { \ - __enable_irq(); \ - } +#define FURI_CRITICAL_EXIT() __furi_critical_exit(__furi_critical_info); #endif #ifdef __cplusplus diff --git a/furi/core/critical.c b/furi/core/critical.c new file mode 100644 index 000000000..57fe2403b --- /dev/null +++ b/furi/core/critical.c @@ -0,0 +1,29 @@ +#include "common_defines.h" + +__FuriCriticalInfo __furi_critical_enter(void) { + __FuriCriticalInfo info; + + info.isrm = 0; + info.from_isr = FURI_IS_ISR(); + info.kernel_running = (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING); + + if(info.from_isr) { + info.isrm = taskENTER_CRITICAL_FROM_ISR(); + } else if(info.kernel_running) { + taskENTER_CRITICAL(); + } else { + __disable_irq(); + } + + return info; +} + +void __furi_critical_exit(__FuriCriticalInfo info) { + if(info.from_isr) { + taskEXIT_CRITICAL_FROM_ISR(info.isrm); + } else if(info.kernel_running) { + taskEXIT_CRITICAL(); + } else { + __enable_irq(); + } +} \ No newline at end of file diff --git a/lib/subghz/SConscript b/lib/subghz/SConscript index 9b96c7306..40e5a9b63 100644 --- a/lib/subghz/SConscript +++ b/lib/subghz/SConscript @@ -7,11 +7,10 @@ env.Append( SDK_HEADERS=[ File("environment.h"), File("receiver.h"), + File("registry.h"), File("subghz_worker.h"), File("subghz_tx_rx_worker.h"), File("transmitter.h"), - File("registry.h"), - File("protocols/protocol_items.h"), File("protocols/raw.h"), File("blocks/const.h"), File("blocks/custom_btn.h"), @@ -20,6 +19,7 @@ env.Append( File("blocks/generic.h"), File("blocks/math.h"), File("subghz_setting.h"), + File("subghz_protocol_registry.h"), ], ) diff --git a/lib/subghz/environment.c b/lib/subghz/environment.c index bcada8752..b69494e66 100644 --- a/lib/subghz/environment.c +++ b/lib/subghz/environment.c @@ -96,16 +96,17 @@ const char* void subghz_environment_set_protocol_registry( SubGhzEnvironment* instance, - void* protocol_registry_items) { + const SubGhzProtocolRegistry* protocol_registry_items) { furi_assert(instance); const SubGhzProtocolRegistry* protocol_registry = protocol_registry_items; instance->protocol_registry = protocol_registry; } -void* subghz_environment_get_protocol_registry(SubGhzEnvironment* instance) { +const SubGhzProtocolRegistry* + subghz_environment_get_protocol_registry(SubGhzEnvironment* instance) { furi_assert(instance); furi_assert(instance->protocol_registry); - return (void*)instance->protocol_registry; + return instance->protocol_registry; } const char* diff --git a/lib/subghz/environment.h b/lib/subghz/environment.h index 67de48df9..ff694acb8 100644 --- a/lib/subghz/environment.h +++ b/lib/subghz/environment.h @@ -1,6 +1,7 @@ #pragma once #include +#include "registry.h" #include "subghz_keystore.h" @@ -9,6 +10,7 @@ extern "C" { #endif typedef struct SubGhzEnvironment SubGhzEnvironment; +typedef struct SubGhzProtocolRegistry SubGhzProtocolRegistry; /** * Allocate SubGhzEnvironment. @@ -93,14 +95,15 @@ const char* */ void subghz_environment_set_protocol_registry( SubGhzEnvironment* instance, - void* protocol_registry_items); + const SubGhzProtocolRegistry* protocol_registry_items); /** * Get list of protocols to work. * @param instance Pointer to a SubGhzEnvironment instance * @return Pointer to a SubGhzProtocolRegistry */ -void* subghz_environment_get_protocol_registry(SubGhzEnvironment* instance); +const SubGhzProtocolRegistry* + subghz_environment_get_protocol_registry(SubGhzEnvironment* instance); /** * Get list of protocols names. diff --git a/lib/subghz/protocols/protocol_items.h b/lib/subghz/protocols/protocol_items.h index b7e082bf5..f1a28ac9b 100644 --- a/lib/subghz/protocols/protocol_items.h +++ b/lib/subghz/protocols/protocol_items.h @@ -1,5 +1,6 @@ #pragma once #include "../registry.h" +#include "../subghz_protocol_registry.h" #include "princeton.h" #include "keeloq.h" @@ -43,13 +44,3 @@ #include "alutech_at_4n.h" #include "kinggates_stylo_4k.h" #include "bin_raw.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const SubGhzProtocolRegistry subghz_protocol_registry; - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/lib/subghz/registry.h b/lib/subghz/registry.h index 91027807e..8529c1097 100644 --- a/lib/subghz/registry.h +++ b/lib/subghz/registry.h @@ -9,6 +9,7 @@ extern "C" { typedef struct SubGhzEnvironment SubGhzEnvironment; typedef struct SubGhzProtocolRegistry SubGhzProtocolRegistry; +typedef struct SubGhzProtocol SubGhzProtocol; struct SubGhzProtocolRegistry { const SubGhzProtocol** items; diff --git a/lib/subghz/subghz_protocol_registry.h b/lib/subghz/subghz_protocol_registry.h new file mode 100644 index 000000000..6a27da992 --- /dev/null +++ b/lib/subghz/subghz_protocol_registry.h @@ -0,0 +1,13 @@ +#pragma once + +#include "registry.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const SubGhzProtocolRegistry subghz_protocol_registry; + +#ifdef __cplusplus +} +#endif diff --git a/lib/subghz/types.h b/lib/subghz/types.h index e0ed95654..ce65789a9 100644 --- a/lib/subghz/types.h +++ b/lib/subghz/types.h @@ -21,6 +21,9 @@ #define SUBGHZ_RAW_FILE_VERSION 1 #define SUBGHZ_RAW_FILE_TYPE "Flipper SubGhz RAW File" +typedef struct SubGhzProtocolRegistry SubGhzProtocolRegistry; +typedef struct SubGhzEnvironment SubGhzEnvironment; + // Radio Preset typedef struct { FuriString* name; @@ -116,11 +119,11 @@ typedef enum { SubGhzProtocolFlag_BinRAW = (1 << 10), } SubGhzProtocolFlag; -typedef struct { +struct SubGhzProtocol { const char* name; SubGhzProtocolType type; SubGhzProtocolFlag flag; const SubGhzProtocolEncoder* encoder; const SubGhzProtocolDecoder* decoder; -} SubGhzProtocol; +}; diff --git a/lib/toolbox/value_index.c b/lib/toolbox/value_index.c index 87bf990f3..5ec0fb962 100644 --- a/lib/toolbox/value_index.c +++ b/lib/toolbox/value_index.c @@ -1,12 +1,14 @@ #include "value_index.h" uint8_t value_index_int32(const int32_t value, const int32_t values[], uint8_t values_count) { + int64_t last_value = INT64_MIN; uint8_t index = 0; for(uint8_t i = 0; i < values_count; i++) { - if(value == values[i]) { + if((value >= last_value) && (value <= values[i])) { index = i; break; } + last_value = values[i]; } return index; } diff --git a/lib/toolbox/value_index.h b/lib/toolbox/value_index.h index 23d53ca21..5aa768e3d 100644 --- a/lib/toolbox/value_index.h +++ b/lib/toolbox/value_index.h @@ -7,7 +7,7 @@ extern "C" { #endif -/** Get the index of a int32_t array element which is equal to the given value. +/** Get the index of a int32_t array element which is closest to the given value. * * Returned index corresponds to the first element found. * If no suitable elements were found, the function returns 0. diff --git a/lib/u8g2/u8g2_glue.c b/lib/u8g2/u8g2_glue.c index 17a702b50..0d4879bce 100644 --- a/lib/u8g2/u8g2_glue.c +++ b/lib/u8g2/u8g2_glue.c @@ -2,6 +2,9 @@ #include +#define CONTRAST_ERC 32 +#define CONTRAST_MGG 31 + uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr) { UNUSED(u8x8); UNUSED(arg_ptr); @@ -207,6 +210,19 @@ void u8x8_d_st756x_init(u8x8_t* u8x8, uint8_t contrast, uint8_t regulation_ratio u8x8_cad_EndTransfer(u8x8); } +void u8x8_d_st756x_set_contrast(u8x8_t* u8x8, int8_t contrast_offset) { + uint8_t contrast = (furi_hal_version_get_hw_display() == FuriHalVersionDisplayMgg) ? + CONTRAST_MGG : + CONTRAST_ERC; + contrast += contrast_offset; + contrast = contrast & 0b00111111; + + u8x8_cad_StartTransfer(u8x8); + u8x8_cad_SendCmd(u8x8, ST756X_CMD_SET_EV); + u8x8_cad_SendArg(u8x8, contrast); + u8x8_cad_EndTransfer(u8x8); +} + uint8_t u8x8_d_st756x_flipper(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr) { /* call common procedure first and handle messages there */ if(u8x8_d_st756x_common(u8x8, msg, arg_int, arg_ptr) == 0) { @@ -225,7 +241,7 @@ uint8_t u8x8_d_st756x_flipper(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* * RR = 10 / ((1 - (63 - 32) / 162) * 2.1) ~= 5.88 is 6 (0b110) * Bias = 1/9 (false) */ - u8x8_d_st756x_init(u8x8, 31, 0b110, false); + u8x8_d_st756x_init(u8x8, CONTRAST_MGG, 0b110, false); } else { /* ERC v1(ST7565) and v2(ST7567) * EV = 33 @@ -233,7 +249,7 @@ uint8_t u8x8_d_st756x_flipper(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* * RR = 9.3 / ((1 - (63 - 32) / 162) * 2.1) ~= 5.47 is 5.5 (0b101) * Bias = 1/9 (false) */ - u8x8_d_st756x_init(u8x8, 32, 0b101, false); + u8x8_d_st756x_init(u8x8, CONTRAST_ERC, 0b101, false); } break; case U8X8_MSG_DISPLAY_SET_FLIP_MODE: diff --git a/lib/u8g2/u8g2_glue.h b/lib/u8g2/u8g2_glue.h index 91ba2980a..af236279e 100644 --- a/lib/u8g2/u8g2_glue.h +++ b/lib/u8g2/u8g2_glue.h @@ -14,3 +14,5 @@ void u8g2_Setup_st756x_flipper( u8x8_msg_cb gpio_and_delay_cb); void u8x8_d_st756x_init(u8x8_t* u8x8, uint8_t contrast, uint8_t regulation_ratio, bool bias); + +void u8x8_d_st756x_set_contrast(u8x8_t* u8x8, int8_t contrast_offset); diff --git a/scripts/fbt/appmanifest.py b/scripts/fbt/appmanifest.py index 32070b55a..bba748bfa 100644 --- a/scripts/fbt/appmanifest.py +++ b/scripts/fbt/appmanifest.py @@ -1,7 +1,8 @@ import os +import re from dataclasses import dataclass, field from enum import Enum -from typing import Callable, List, Optional, Tuple, Union +from typing import Callable, ClassVar, List, Optional, Tuple, Union class FlipperManifestException(Exception): @@ -24,6 +25,8 @@ class FlipperAppType(Enum): @dataclass class FlipperApplication: + APP_ID_REGEX: ClassVar[re.Pattern] = re.compile(r"^[a-z0-9_]+$") + @dataclass class ExternallyBuiltFile: path: str @@ -86,6 +89,10 @@ class FlipperApplication: def __post_init__(self): if self.apptype == FlipperAppType.PLUGIN: self.stack_size = 0 + if not self.APP_ID_REGEX.match(self.appid): + raise FlipperManifestException( + f"Invalid appid '{self.appid}'. Must match regex '{self.APP_ID_REGEX}'" + ) if isinstance(self.fap_version, str): try: self.fap_version = tuple(int(v) for v in self.fap_version.split(".")) diff --git a/scripts/flipper/assets/copro.py b/scripts/flipper/assets/copro.py index f176e3b2e..25c072899 100644 --- a/scripts/flipper/assets/copro.py +++ b/scripts/flipper/assets/copro.py @@ -58,14 +58,23 @@ class Copro: def _getFileName(self, name): return posixpath.join(self.COPRO_TAR_DIR, name) + def _addFileReadPermission(self, tarinfo): + tarinfo.mode = 0o644 + return tarinfo + def addFile(self, array, filename, **kwargs): source_file = os.path.join(self.mcu_copro, filename) - self.output_tar.add(source_file, arcname=self._getFileName(filename)) + self.output_tar.add( + source_file, + arcname=self._getFileName(filename), + filter=self._addFileReadPermission, + ) array.append({"name": filename, "sha256": file_sha256(source_file), **kwargs}) def bundle(self, output_file, stack_file_name, stack_type, stack_addr=None): self.output_tar = tarfile.open(output_file, "w:gz", format=tarfile.USTAR_FORMAT) fw_directory = tarfile.TarInfo(self.COPRO_TAR_DIR) + fw_directory.mode = 0o755 fw_directory.type = tarfile.DIRTYPE self.output_tar.addfile(fw_directory) diff --git a/scripts/flipper/assets/coprobin.py b/scripts/flipper/assets/coprobin.py index 75bf76d76..84f52fbb3 100644 --- a/scripts/flipper/assets/coprobin.py +++ b/scripts/flipper/assets/coprobin.py @@ -46,7 +46,10 @@ class CoproFooterBase: _SIG_BIN_COMMON_SIZE = 2 * 4 def get_version(self): - return f"Version {self.version_major}.{self.version_minor}.{self.version_sub}, branch {self.version_branch}, build {self.version_build} (magic {self.magic:X})" + return ( + f"Version {self.version_major}.{self.version_minor}.{self.version_sub}, " + f"branch {self.version_branch}, build {self.version_build} (magic {self.magic:X})" + ) def get_details(self): raise CoproException("Not implemented") diff --git a/scripts/map_mariadb_insert.py b/scripts/map_mariadb_insert.py new file mode 100755 index 000000000..a4c9ed5c7 --- /dev/null +++ b/scripts/map_mariadb_insert.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python3 + +# Requiremets: +# mariadb==1.1.6 + +from datetime import datetime +import argparse +import mariadb +import sys +import os + + +def parseArgs(): + parser = argparse.ArgumentParser() + parser.add_argument("db_user", help="MariaDB user") + parser.add_argument("db_pass", help="MariaDB password") + parser.add_argument("db_host", help="MariaDB hostname") + parser.add_argument("db_port", type=int, help="MariaDB port") + parser.add_argument("db_name", help="MariaDB database") + parser.add_argument("report_file", help="Report file(.map.all)") + args = parser.parse_args() + return args + + +def mariadbConnect(args): + try: + conn = mariadb.connect( + user=args.db_user, + password=args.db_pass, + host=args.db_host, + port=args.db_port, + database=args.db_name, + ) + except mariadb.Error as e: + print(f"Error connecting to MariaDB: {e}") + sys.exit(1) + return conn + + +def parseEnv(): + outArr = [] + outArr.append(datetime.now().strftime("%Y-%m-%d %H:%M:%S")) + outArr.append(os.getenv("COMMIT_HASH", default=None)) + outArr.append(os.getenv("COMMIT_MSG", default=None)) + outArr.append(os.getenv("BRANCH_NAME", default=None)) + outArr.append(os.getenv("BSS_SIZE", default=None)) + outArr.append(os.getenv("TEXT_SIZE", default=None)) + outArr.append(os.getenv("RODATA_SIZE", default=None)) + outArr.append(os.getenv("DATA_SIZE", default=None)) + outArr.append(os.getenv("FREE_FLASH_SIZE", default=None)) + outArr.append(os.getenv("PULL_ID", default=None)) + outArr.append(os.getenv("PULL_NAME", default=None)) + return outArr + + +def createTables(cur, conn): + headerTable = "CREATE TABLE IF NOT EXISTS `header` ( \ + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, \ + `datetime` datetime NOT NULL, \ + `commit` varchar(40) NOT NULL, \ + `commit_msg` text NOT NULL, \ + `branch_name` text NOT NULL, \ + `bss_size` int(10) unsigned NOT NULL, \ + `text_size` int(10) unsigned NOT NULL, \ + `rodata_size` int(10) unsigned NOT NULL, \ + `data_size` int(10) unsigned NOT NULL, \ + `free_flash_size` int(10) unsigned NOT NULL, \ + `pullrequest_id` int(10) unsigned DEFAULT NULL, \ + `pullrequest_name` text DEFAULT NULL, \ + PRIMARY KEY (`id`), \ + KEY `header_id_index` (`id`) )" + dataTable = "CREATE TABLE IF NOT EXISTS `data` ( \ + `header_id` int(10) unsigned NOT NULL, \ + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, \ + `section` text NOT NULL, \ + `address` text NOT NULL, \ + `size` int(10) unsigned NOT NULL, \ + `name` text NOT NULL, \ + `lib` text NOT NULL, \ + `obj_name` text NOT NULL, \ + PRIMARY KEY (`id`), \ + KEY `data_id_index` (`id`), \ + KEY `data_header_id_index` (`header_id`), \ + CONSTRAINT `data_header_id_foreign` FOREIGN KEY (`header_id`) REFERENCES `header` (`id`) )" + cur.execute(headerTable) + cur.execute(dataTable) + conn.commit() + + +def insertHeader(data, cur, conn): + query = "INSERT INTO `header` ( \ + datetime, commit, commit_msg, branch_name, bss_size, text_size, \ + rodata_size, data_size, free_flash_size, pullrequest_id, pullrequest_name) \ + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" + cur.execute(query, data) + conn.commit() + return cur.lastrowid + + +def parseFile(fileObj, headerID): + arr = [] + fileLines = fileObj.readlines() + for line in fileLines: + lineArr = [] + tempLineArr = line.split("\t") + lineArr.append(headerID) + lineArr.append(tempLineArr[0]) # section + lineArr.append(int(tempLineArr[2], 16)) # address hex + lineArr.append(int(tempLineArr[3])) # size + lineArr.append(tempLineArr[4]) # name + lineArr.append(tempLineArr[5]) # lib + lineArr.append(tempLineArr[6]) # obj_name + arr.append(tuple(lineArr)) + return arr + + +def insertData(data, cur, conn): + query = "INSERT INTO `data` ( \ + header_id, section, address, size, \ + name, lib, obj_name) \ + VALUES (?, ?, ?, ?, ? ,?, ?)" + cur.executemany(query, data) + conn.commit() + + +def main(): + args = parseArgs() + dbConn = mariadbConnect(args) + reportFile = open(args.report_file) + dbCurs = dbConn.cursor() + createTables(dbCurs, dbConn) + headerID = insertHeader(parseEnv(), dbCurs, dbConn) + insertData(parseFile(reportFile, headerID), dbCurs, dbConn) + reportFile.close() + dbCurs.close() + + +if __name__ == "__main__": + main() diff --git a/scripts/map_parser.py b/scripts/map_parser.py new file mode 100755 index 000000000..1efc4fe82 --- /dev/null +++ b/scripts/map_parser.py @@ -0,0 +1,274 @@ +#!/usr/bin/env python3 + +# Requiremets: +# cxxfilt==0.3.0 + +# Most part of this code written by Lars-Dominik Braun https://github.com/PromyLOPh/linkermapviz +# and distributes under MIT licence + +# Copyright (c) 2017 Lars-Dominik Braun +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import sys +import re +import os +from typing import TextIO +from cxxfilt import demangle + + +class Objectfile: + def __init__(self, section: str, offset: int, size: int, comment: str): + self.section = section.strip() + self.offset = offset + self.size = size + self.path = (None, None) + self.basepath = None + + if comment: + self.path = re.match(r"^(.+?)(?:\(([^\)]+)\))?$", comment).groups() + self.basepath = os.path.basename(self.path[0]) + + self.children = [] + + def __repr__(self) -> str: + return f"" + + +def update_children_size(children: list[list], subsection_size: int) -> list: + # set subsection size to an only child + if len(children) == 1: + children[0][1] = subsection_size + return children + + rest_size = subsection_size + + for index in range(1, len(children)): + if rest_size > 0: + # current size = current address - previous child address + child_size = children[index][0] - children[index - 1][0] + rest_size -= child_size + children[index - 1][1] = child_size + + # if there is rest size, set it to the last child element + if rest_size > 0: + children[-1][1] = rest_size + + return children + + +def parse_sections(file_name: str) -> list: + """ + Quick&Dirty parsing for GNU ld’s linker map output, needs LANG=C, because + some messages are localized. + """ + + sections = [] + with open(file_name, "r") as file: + # skip until memory map is found + found = False + + while True: + line = file.readline() + if not line: + break + if line.strip() == "Memory Configuration": + found = True + break + + if not found: + raise Exception(f"Memory configuration is not found in the{input_file}") + + # long section names result in a linebreak afterwards + sectionre = re.compile( + "(?P
.+?|.{14,}\n)[ ]+0x(?P[0-9a-f]+)[ ]+0x(?P[0-9a-f]+)(?:[ ]+(?P.+))?\n+", + re.I, + ) + subsectionre = re.compile( + "[ ]{16}0x(?P[0-9a-f]+)[ ]+(?P.+)\n+", re.I + ) + s = file.read() + pos = 0 + + while True: + m = sectionre.match(s, pos) + if not m: + # skip that line + try: + nextpos = s.index("\n", pos) + 1 + pos = nextpos + continue + except ValueError: + break + + pos = m.end() + section = m.group("section") + v = m.group("offset") + offset = int(v, 16) if v is not None else None + v = m.group("size") + size = int(v, 16) if v is not None else None + comment = m.group("comment") + + if section != "*default*" and size > 0: + of = Objectfile(section, offset, size, comment) + + if section.startswith(" "): + children = [] + sections[-1].children.append(of) + + while True: + m = subsectionre.match(s, pos) + if not m: + break + pos = m.end() + offset, function = m.groups() + offset = int(offset, 16) + if sections and sections[-1].children: + children.append([offset, 0, function]) + + if children: + children = update_children_size( + children=children, subsection_size=of.size + ) + + sections[-1].children[-1].children.extend(children) + + else: + sections.append(of) + + return sections + + +def get_subsection_name(section_name: str, subsection: Objectfile) -> str: + subsection_split_names = subsection.section.split(".") + if subsection.section.startswith("."): + subsection_split_names = subsection_split_names[1:] + + return ( + f".{subsection_split_names[1]}" + if len(subsection_split_names) > 2 + else section_name + ) + + +def write_subsection( + section_name: str, + subsection_name: str, + address: str, + size: int, + demangled_name: str, + module_name: str, + file_name: str, + mangled_name: str, + write_file_object: TextIO, +) -> None: + write_file_object.write( + f"{section_name}\t" + f"{subsection_name}\t" + f"{address}\t" + f"{size}\t" + f"{demangled_name}\t" + f"{module_name}\t" + f"{file_name}\t" + f"{mangled_name}\n" + ) + + +def save_subsection( + section_name: str, subsection: Objectfile, write_file_object: TextIO +) -> None: + subsection_name = get_subsection_name(section_name, subsection) + module_name = subsection.path[0] + file_name = subsection.path[1] + + if not file_name: + file_name, module_name = module_name, "" + + if not subsection.children: + address = f"{subsection.offset:x}" + size = subsection.size + mangled_name = ( + "" + if subsection.section == section_name + else subsection.section.split(".")[-1] + ) + demangled_name = demangle(mangled_name) if mangled_name else mangled_name + + write_subsection( + section_name=section_name, + subsection_name=subsection_name, + address=address, + size=size, + demangled_name=demangled_name, + module_name=module_name, + file_name=file_name, + mangled_name=mangled_name, + write_file_object=write_file_object, + ) + return + + for subsection_child in subsection.children: + address = f"{subsection_child[0]:x}" + size = subsection_child[1] + mangled_name = subsection_child[2] + demangled_name = demangle(mangled_name) + + write_subsection( + section_name=section_name, + subsection_name=subsection_name, + address=address, + size=size, + demangled_name=demangled_name, + module_name=module_name, + file_name=file_name, + mangled_name=mangled_name, + write_file_object=write_file_object, + ) + + +def save_section(section: Objectfile, write_file_object: TextIO) -> None: + section_name = section.section + for subsection in section.children: + save_subsection( + section_name=section_name, + subsection=subsection, + write_file_object=write_file_object, + ) + + +def save_parsed_data(parsed_data: list[Objectfile], output_file_name: str) -> None: + with open(output_file_name, "w") as write_file_object: + for section in parsed_data: + if section.children: + save_section(section=section, write_file_object=write_file_object) + + +if __name__ == "__main__": + if len(sys.argv) < 3: + raise Exception(f"Usage: {sys.argv[0]} ") + + input_file = sys.argv[1] + output_file = sys.argv[2] + + parsed_sections = parse_sections(input_file) + + if parsed_sections is None: + raise Exception(f"Memory configuration is not {input_file}") + + save_parsed_data(parsed_sections, output_file) diff --git a/scripts/serial_cli.py b/scripts/serial_cli.py index 2fa37d751..6dae68be6 100644 --- a/scripts/serial_cli.py +++ b/scripts/serial_cli.py @@ -9,7 +9,7 @@ from flipper.utils.cdc import resolve_port def main(): logger = logging.getLogger() if not (port := resolve_port(logger, "auto")): - logger.error("Is Flipper connected over USB and is it not in DFU mode?") + logger.error("Is Flipper connected via USB and not in DFU mode?") return 1 subprocess.call( [ diff --git a/scripts/ufbt/SConstruct b/scripts/ufbt/SConstruct index d72de380c..a1acd270a 100644 --- a/scripts/ufbt/SConstruct +++ b/scripts/ufbt/SConstruct @@ -75,7 +75,7 @@ from fbt.util import ( wrap_tempfile, path_as_posix, ) -from fbt.appmanifest import FlipperAppType +from fbt.appmanifest import FlipperAppType, FlipperApplication from fbt.sdk.cache import SdkCache # Base environment with all tools loaded from SDK @@ -410,6 +410,12 @@ dist_env.Alias("vscode_dist", vscode_dist) # Creating app from base template dist_env.SetDefault(FBT_APPID=appenv.subst("$APPID") or "template") +if fbt_appid := dist_env.subst("$FBT_APPID"): + if not FlipperApplication.APP_ID_REGEX.match(fbt_appid): + raise UserError( + f"Invalid app id '{fbt_appid}'. App id must match {FlipperApplication.APP_ID_REGEX.pattern}" + ) + app_template_dir = project_template_dir.Dir("app_template") app_template_dist = [] for template_file in app_template_dir.glob("*"):