mirror of
https://github.com/DarkFlippers/unleashed-firmware
synced 2024-11-26 22:40:25 +00:00
better subghz settings and more anim unload fixes
by Willy-JL
This commit is contained in:
parent
a830d6b511
commit
ef29ed149d
15 changed files with 167 additions and 241 deletions
|
@ -60,9 +60,6 @@ bool subghz_scene_frequency_analyzer_on_event(void* context, SceneManagerEvent e
|
||||||
subghz_frequency_analyzer_get_frequency_to_save(subghz->subghz_frequency_analyzer);
|
subghz_frequency_analyzer_get_frequency_to_save(subghz->subghz_frequency_analyzer);
|
||||||
if(frequency > 0) {
|
if(frequency > 0) {
|
||||||
subghz->last_settings->frequency = frequency;
|
subghz->last_settings->frequency = frequency;
|
||||||
#ifdef FURI_DEBUG
|
|
||||||
subghz_last_settings_log(subghz->last_settings);
|
|
||||||
#endif
|
|
||||||
// Disable Hopping before opening the receiver scene!
|
// Disable Hopping before opening the receiver scene!
|
||||||
if(subghz->last_settings->enable_hopping) {
|
if(subghz->last_settings->enable_hopping) {
|
||||||
subghz->last_settings->enable_hopping = false;
|
subghz->last_settings->enable_hopping = false;
|
||||||
|
@ -73,9 +70,6 @@ bool subghz_scene_frequency_analyzer_on_event(void* context, SceneManagerEvent e
|
||||||
return true;
|
return true;
|
||||||
} else if(event.event == SubGhzCustomEventViewFreqAnalOkLong) {
|
} else if(event.event == SubGhzCustomEventViewFreqAnalOkLong) {
|
||||||
// Don't need to save, we already saved on short event
|
// Don't need to save, we already saved on short event
|
||||||
#ifdef FURI_DEBUG
|
|
||||||
FURI_LOG_W(TAG, "Goto next scene!");
|
|
||||||
#endif
|
|
||||||
//scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneStart, 10);
|
//scene_manager_set_scene_state(subghz->scene_manager, SubGhzSceneStart, 10);
|
||||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiver);
|
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReceiver);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -94,7 +94,7 @@ static void subghz_scene_receiver_config_set_timestamp_file_names(VariableItem*
|
||||||
|
|
||||||
variable_item_set_current_value_text(item, timestamp_names_text[index]);
|
variable_item_set_current_value_text(item, timestamp_names_text[index]);
|
||||||
|
|
||||||
subghz->last_settings->timestamp_file_names = (index == 1);
|
subghz->last_settings->protocol_file_names = (index == 1);
|
||||||
subghz_last_settings_save(subghz->last_settings);
|
subghz_last_settings_save(subghz->last_settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ void subghz_scene_radio_settings_on_enter(void* context) {
|
||||||
TIMESTAMP_NAMES_COUNT,
|
TIMESTAMP_NAMES_COUNT,
|
||||||
subghz_scene_receiver_config_set_timestamp_file_names,
|
subghz_scene_receiver_config_set_timestamp_file_names,
|
||||||
subghz);
|
subghz);
|
||||||
value_index = subghz->last_settings->timestamp_file_names;
|
value_index = subghz->last_settings->protocol_file_names;
|
||||||
variable_item_set_current_value_index(item, value_index);
|
variable_item_set_current_value_index(item, value_index);
|
||||||
variable_item_set_current_value_text(item, timestamp_names_text[value_index]);
|
variable_item_set_current_value_text(item, timestamp_names_text[value_index]);
|
||||||
|
|
||||||
|
|
|
@ -104,14 +104,13 @@ void subghz_scene_read_raw_on_enter(void* context) {
|
||||||
|
|
||||||
if(subghz_rx_key_state_get(subghz) != SubGhzRxKeyStateBack) {
|
if(subghz_rx_key_state_get(subghz) != SubGhzRxKeyStateBack) {
|
||||||
subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE);
|
subghz_rx_key_state_set(subghz, SubGhzRxKeyStateIDLE);
|
||||||
#if SUBGHZ_LAST_SETTING_SAVE_PRESET
|
|
||||||
if(furi_string_empty(file_name)) {
|
if(furi_string_empty(file_name)) {
|
||||||
subghz_txrx_set_preset_internal(
|
subghz_txrx_set_preset_internal(
|
||||||
subghz->txrx,
|
subghz->txrx,
|
||||||
subghz->last_settings->frequency,
|
subghz->last_settings->frequency,
|
||||||
subghz->last_settings->preset_index);
|
subghz->last_settings->preset_index);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
subghz_scene_read_raw_update_statusbar(subghz);
|
subghz_scene_read_raw_update_statusbar(subghz);
|
||||||
|
|
||||||
|
|
|
@ -164,12 +164,8 @@ void subghz_scene_receiver_on_enter(void* context) {
|
||||||
FuriString* item_time = furi_string_alloc();
|
FuriString* item_time = furi_string_alloc();
|
||||||
|
|
||||||
if(subghz_rx_key_state_get(subghz) == SubGhzRxKeyStateIDLE) {
|
if(subghz_rx_key_state_get(subghz) == SubGhzRxKeyStateIDLE) {
|
||||||
#if SUBGHZ_LAST_SETTING_SAVE_PRESET
|
|
||||||
subghz_txrx_set_preset_internal(
|
subghz_txrx_set_preset_internal(
|
||||||
subghz->txrx, subghz->last_settings->frequency, subghz->last_settings->preset_index);
|
subghz->txrx, subghz->last_settings->frequency, subghz->last_settings->preset_index);
|
||||||
#else
|
|
||||||
subghz_txrx_set_default_preset(subghz->txrx, subghz->last_settings->frequency);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
subghz->filter = subghz->last_settings->filter;
|
subghz->filter = subghz->last_settings->filter;
|
||||||
subghz_txrx_receiver_set_filter(subghz->txrx, subghz->filter);
|
subghz_txrx_receiver_set_filter(subghz->txrx, subghz->filter);
|
||||||
|
|
|
@ -301,14 +301,11 @@ static void subghz_scene_receiver_config_var_list_enter_callback(void* context,
|
||||||
subghz->view_dispatcher, SubGhzCustomEventSceneSettingLock);
|
subghz->view_dispatcher, SubGhzCustomEventSceneSettingLock);
|
||||||
} else if(index == SubGhzSettingIndexResetToDefault) {
|
} else if(index == SubGhzSettingIndexResetToDefault) {
|
||||||
// Reset all values to default state!
|
// Reset all values to default state!
|
||||||
#if SUBGHZ_LAST_SETTING_SAVE_PRESET
|
|
||||||
subghz_txrx_set_preset_internal(
|
subghz_txrx_set_preset_internal(
|
||||||
subghz->txrx,
|
subghz->txrx,
|
||||||
SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY,
|
SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY,
|
||||||
SUBGHZ_LAST_SETTING_DEFAULT_PRESET);
|
SUBGHZ_LAST_SETTING_DEFAULT_PRESET);
|
||||||
#else
|
|
||||||
subghz_txrx_set_default_preset(subghz->txrx, SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY);
|
|
||||||
#endif
|
|
||||||
SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx);
|
SubGhzSetting* setting = subghz_txrx_get_setting(subghz->txrx);
|
||||||
SubGhzRadioPreset preset = subghz_txrx_get_preset(subghz->txrx);
|
SubGhzRadioPreset preset = subghz_txrx_get_preset(subghz->txrx);
|
||||||
const char* preset_name = furi_string_get_cstr(preset.name);
|
const char* preset_name = furi_string_get_cstr(preset.name);
|
||||||
|
@ -333,9 +330,7 @@ static void subghz_scene_receiver_config_var_list_enter_callback(void* context,
|
||||||
|
|
||||||
variable_item_list_set_selected_item(subghz->variable_item_list, default_index);
|
variable_item_list_set_selected_item(subghz->variable_item_list, default_index);
|
||||||
variable_item_list_reset(subghz->variable_item_list);
|
variable_item_list_reset(subghz->variable_item_list);
|
||||||
#ifdef FURI_DEBUG
|
|
||||||
subghz_last_settings_log(subghz->last_settings);
|
|
||||||
#endif
|
|
||||||
subghz_last_settings_save(subghz->last_settings);
|
subghz_last_settings_save(subghz->last_settings);
|
||||||
|
|
||||||
view_dispatcher_send_custom_event(
|
view_dispatcher_send_custom_event(
|
||||||
|
@ -556,9 +551,7 @@ void subghz_scene_receiver_config_on_exit(void* context) {
|
||||||
SubGhz* subghz = context;
|
SubGhz* subghz = context;
|
||||||
variable_item_list_set_selected_item(subghz->variable_item_list, 0);
|
variable_item_list_set_selected_item(subghz->variable_item_list, 0);
|
||||||
variable_item_list_reset(subghz->variable_item_list);
|
variable_item_list_reset(subghz->variable_item_list);
|
||||||
#ifdef FURI_DEBUG
|
|
||||||
subghz_last_settings_log(subghz->last_settings);
|
|
||||||
#endif
|
|
||||||
subghz_last_settings_save(subghz->last_settings);
|
subghz_last_settings_save(subghz->last_settings);
|
||||||
scene_manager_set_scene_state(
|
scene_manager_set_scene_state(
|
||||||
subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerNoSet);
|
subghz->scene_manager, SubGhzSceneReadRAW, SubGhzCustomEventManagerNoSet);
|
||||||
|
|
|
@ -32,7 +32,7 @@ void subghz_scene_save_name_on_enter(void* context) {
|
||||||
if(decoder_result != 0x0) {
|
if(decoder_result != 0x0) {
|
||||||
if(decoder_result != NULL) {
|
if(decoder_result != NULL) {
|
||||||
if(strlen(decoder_result->protocol->name) != 0 &&
|
if(strlen(decoder_result->protocol->name) != 0 &&
|
||||||
subghz->last_settings->timestamp_file_names) {
|
subghz->last_settings->protocol_file_names) {
|
||||||
if(!scene_manager_has_previous_scene(
|
if(!scene_manager_has_previous_scene(
|
||||||
subghz->scene_manager, SubGhzSceneSetType)) {
|
subghz->scene_manager, SubGhzSceneSetType)) {
|
||||||
name_generator_make_auto_datetime(
|
name_generator_make_auto_datetime(
|
||||||
|
|
|
@ -202,16 +202,9 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) {
|
||||||
subghz->last_settings = subghz_last_settings_alloc();
|
subghz->last_settings = subghz_last_settings_alloc();
|
||||||
size_t preset_count = subghz_setting_get_preset_count(setting);
|
size_t preset_count = subghz_setting_get_preset_count(setting);
|
||||||
subghz_last_settings_load(subghz->last_settings, preset_count);
|
subghz_last_settings_load(subghz->last_settings, preset_count);
|
||||||
#ifdef FURI_DEBUG
|
|
||||||
subghz_last_settings_log(subghz->last_settings);
|
|
||||||
#endif
|
|
||||||
if(!alloc_for_tx_only) {
|
if(!alloc_for_tx_only) {
|
||||||
#if SUBGHZ_LAST_SETTING_SAVE_PRESET
|
|
||||||
subghz_txrx_set_preset_internal(
|
subghz_txrx_set_preset_internal(
|
||||||
subghz->txrx, subghz->last_settings->frequency, subghz->last_settings->preset_index);
|
subghz->txrx, subghz->last_settings->frequency, subghz->last_settings->preset_index);
|
||||||
#else
|
|
||||||
subghz_txrx_set_default_preset(subghz->txrx, subghz->last_settings->frequency);
|
|
||||||
#endif
|
|
||||||
subghz->history = subghz_history_alloc();
|
subghz->history = subghz_history_alloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
#define TAG "SubGhzLastSettings"
|
#define TAG "SubGhzLastSettings"
|
||||||
|
|
||||||
#define SUBGHZ_LAST_SETTING_FILE_TYPE "Flipper SubGhz Last Setting File"
|
#define SUBGHZ_LAST_SETTING_FILE_TYPE "Flipper SubGhz Last Setting File"
|
||||||
#define SUBGHZ_LAST_SETTING_FILE_VERSION 2
|
#define SUBGHZ_LAST_SETTING_FILE_VERSION 3
|
||||||
#define SUBGHZ_LAST_SETTINGS_PATH EXT_PATH("subghz/assets/last_subghz.settings")
|
#define SUBGHZ_LAST_SETTINGS_PATH EXT_PATH("subghz/assets/last_subghz.settings")
|
||||||
|
|
||||||
#define SUBGHZ_LAST_SETTING_FIELD_FREQUENCY "Frequency"
|
#define SUBGHZ_LAST_SETTING_FIELD_FREQUENCY "Frequency"
|
||||||
#define SUBGHZ_LAST_SETTING_FIELD_PRESET "Preset" // AKA Modulation
|
#define SUBGHZ_LAST_SETTING_FIELD_PRESET "Preset" // AKA Modulation
|
||||||
#define SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_FEEDBACK_LEVEL "FeedbackLevel"
|
#define SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_FEEDBACK_LEVEL "FeedbackLevel"
|
||||||
#define SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_TRIGGER "FATrigger"
|
#define SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_TRIGGER "FATrigger"
|
||||||
#define SUBGHZ_LAST_SETTING_FIELD_TIMESTAMP_FILE_NAMES "TimestampNames"
|
#define SUBGHZ_LAST_SETTING_FIELD_PROTOCOL_FILE_NAMES "ProtocolNames"
|
||||||
#define SUBGHZ_LAST_SETTING_FIELD_HOPPING_ENABLE "Hopping"
|
#define SUBGHZ_LAST_SETTING_FIELD_HOPPING_ENABLE "Hopping"
|
||||||
#define SUBGHZ_LAST_SETTING_FIELD_IGNORE_FILTER "IgnoreFilter"
|
#define SUBGHZ_LAST_SETTING_FIELD_IGNORE_FILTER "IgnoreFilter"
|
||||||
#define SUBGHZ_LAST_SETTING_FIELD_FILTER "Filter"
|
#define SUBGHZ_LAST_SETTING_FIELD_FILTER "Filter"
|
||||||
|
@ -31,31 +31,23 @@ void subghz_last_settings_free(SubGhzLastSettings* instance) {
|
||||||
void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count) {
|
void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count) {
|
||||||
furi_assert(instance);
|
furi_assert(instance);
|
||||||
|
|
||||||
|
// Default values (all others set to 0, if read from file fails these are used)
|
||||||
|
instance->frequency = SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY;
|
||||||
|
instance->preset_index = SUBGHZ_LAST_SETTING_DEFAULT_PRESET;
|
||||||
|
instance->frequency_analyzer_feedback_level =
|
||||||
|
SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_FEEDBACK_LEVEL;
|
||||||
|
instance->frequency_analyzer_trigger = SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER;
|
||||||
|
// See bin_raw_value in scenes/subghz_scene_receiver_config.c
|
||||||
|
instance->filter = SubGhzProtocolFlag_Decodable;
|
||||||
|
instance->rssi = SUBGHZ_RAW_THRESHOLD_MIN;
|
||||||
|
|
||||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||||
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
|
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
|
||||||
|
|
||||||
uint32_t temp_frequency = 0;
|
|
||||||
uint32_t temp_frequency_analyzer_feedback_level = 0;
|
|
||||||
float temp_frequency_analyzer_trigger = 0;
|
|
||||||
bool temp_timestamp_file_names = false;
|
|
||||||
bool temp_enable_hopping = false;
|
|
||||||
bool temp_delete_old_sig = false;
|
|
||||||
uint32_t temp_ignore_filter = 0;
|
|
||||||
uint32_t temp_filter = 0;
|
|
||||||
float temp_rssi = 0;
|
|
||||||
uint32_t temp_preset = 0;
|
|
||||||
|
|
||||||
bool preset_was_read = false;
|
|
||||||
bool rssi_was_read = false;
|
|
||||||
bool filter_was_read = false;
|
|
||||||
bool ignore_filter_was_read = false;
|
|
||||||
bool frequency_analyzer_feedback_level_was_read = false;
|
|
||||||
bool frequency_analyzer_trigger_was_read = false;
|
|
||||||
|
|
||||||
FuriString* temp_str = furi_string_alloc();
|
FuriString* temp_str = furi_string_alloc();
|
||||||
uint32_t config_version = 0;
|
uint32_t config_version = 0;
|
||||||
|
|
||||||
if(FSE_OK == storage_sd_status(storage) && SUBGHZ_LAST_SETTINGS_PATH &&
|
if(FSE_OK == storage_sd_status(storage) &&
|
||||||
flipper_format_file_open_existing(fff_data_file, SUBGHZ_LAST_SETTINGS_PATH)) {
|
flipper_format_file_open_existing(fff_data_file, SUBGHZ_LAST_SETTINGS_PATH)) {
|
||||||
do {
|
do {
|
||||||
if(!flipper_format_read_header(fff_data_file, temp_str, &config_version)) break;
|
if(!flipper_format_read_header(fff_data_file, temp_str, &config_version)) break;
|
||||||
|
@ -64,44 +56,65 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
preset_was_read = flipper_format_read_uint32(
|
if(!flipper_format_read_uint32(
|
||||||
fff_data_file, SUBGHZ_LAST_SETTING_FIELD_PRESET, (uint32_t*)&temp_preset, 1);
|
fff_data_file, SUBGHZ_LAST_SETTING_FIELD_FREQUENCY, &instance->frequency, 1)) {
|
||||||
flipper_format_read_uint32(
|
flipper_format_rewind(fff_data_file);
|
||||||
fff_data_file, SUBGHZ_LAST_SETTING_FIELD_FREQUENCY, (uint32_t*)&temp_frequency, 1);
|
}
|
||||||
frequency_analyzer_feedback_level_was_read = flipper_format_read_uint32(
|
if(!flipper_format_read_uint32(
|
||||||
fff_data_file,
|
fff_data_file, SUBGHZ_LAST_SETTING_FIELD_PRESET, &instance->preset_index, 1)) {
|
||||||
SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_FEEDBACK_LEVEL,
|
flipper_format_rewind(fff_data_file);
|
||||||
(uint32_t*)&temp_frequency_analyzer_feedback_level,
|
}
|
||||||
1);
|
if(!flipper_format_read_uint32(
|
||||||
frequency_analyzer_trigger_was_read = flipper_format_read_float(
|
fff_data_file,
|
||||||
fff_data_file,
|
SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_FEEDBACK_LEVEL,
|
||||||
SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_TRIGGER,
|
&instance->frequency_analyzer_feedback_level,
|
||||||
(float*)&temp_frequency_analyzer_trigger,
|
1)) {
|
||||||
1);
|
flipper_format_rewind(fff_data_file);
|
||||||
flipper_format_read_bool(
|
}
|
||||||
fff_data_file,
|
if(!flipper_format_read_float(
|
||||||
SUBGHZ_LAST_SETTING_FIELD_TIMESTAMP_FILE_NAMES,
|
fff_data_file,
|
||||||
(bool*)&temp_timestamp_file_names,
|
SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_TRIGGER,
|
||||||
1);
|
&instance->frequency_analyzer_trigger,
|
||||||
flipper_format_read_bool(
|
1)) {
|
||||||
fff_data_file,
|
flipper_format_rewind(fff_data_file);
|
||||||
SUBGHZ_LAST_SETTING_FIELD_HOPPING_ENABLE,
|
}
|
||||||
(bool*)&temp_enable_hopping,
|
if(!flipper_format_read_bool(
|
||||||
1);
|
fff_data_file,
|
||||||
rssi_was_read = flipper_format_read_float(
|
SUBGHZ_LAST_SETTING_FIELD_PROTOCOL_FILE_NAMES,
|
||||||
fff_data_file, SUBGHZ_LAST_SETTING_FIELD_RSSI_THRESHOLD, (float*)&temp_rssi, 1);
|
&instance->protocol_file_names,
|
||||||
ignore_filter_was_read = flipper_format_read_uint32(
|
1)) {
|
||||||
fff_data_file,
|
flipper_format_rewind(fff_data_file);
|
||||||
SUBGHZ_LAST_SETTING_FIELD_IGNORE_FILTER,
|
}
|
||||||
(uint32_t*)&temp_ignore_filter,
|
if(!flipper_format_read_bool(
|
||||||
1);
|
fff_data_file,
|
||||||
filter_was_read = flipper_format_read_uint32(
|
SUBGHZ_LAST_SETTING_FIELD_HOPPING_ENABLE,
|
||||||
fff_data_file, SUBGHZ_LAST_SETTING_FIELD_FILTER, (uint32_t*)&temp_filter, 1);
|
&instance->enable_hopping,
|
||||||
flipper_format_read_bool(
|
1)) {
|
||||||
fff_data_file,
|
flipper_format_rewind(fff_data_file);
|
||||||
SUBGHZ_LAST_SETTING_FIELD_DELETE_OLD,
|
}
|
||||||
(bool*)&temp_delete_old_sig,
|
if(!flipper_format_read_uint32(
|
||||||
1);
|
fff_data_file,
|
||||||
|
SUBGHZ_LAST_SETTING_FIELD_IGNORE_FILTER,
|
||||||
|
&instance->ignore_filter,
|
||||||
|
1)) {
|
||||||
|
flipper_format_rewind(fff_data_file);
|
||||||
|
}
|
||||||
|
if(!flipper_format_read_uint32(
|
||||||
|
fff_data_file, SUBGHZ_LAST_SETTING_FIELD_FILTER, &instance->filter, 1)) {
|
||||||
|
flipper_format_rewind(fff_data_file);
|
||||||
|
}
|
||||||
|
if(!flipper_format_read_float(
|
||||||
|
fff_data_file, SUBGHZ_LAST_SETTING_FIELD_RSSI_THRESHOLD, &instance->rssi, 1)) {
|
||||||
|
flipper_format_rewind(fff_data_file);
|
||||||
|
}
|
||||||
|
if(!flipper_format_read_bool(
|
||||||
|
fff_data_file,
|
||||||
|
SUBGHZ_LAST_SETTING_FIELD_DELETE_OLD,
|
||||||
|
&instance->delete_old_signals,
|
||||||
|
1)) {
|
||||||
|
flipper_format_rewind(fff_data_file);
|
||||||
|
}
|
||||||
|
|
||||||
} while(0);
|
} while(0);
|
||||||
} else {
|
} else {
|
||||||
FURI_LOG_E(TAG, "Error open file %s", SUBGHZ_LAST_SETTINGS_PATH);
|
FURI_LOG_E(TAG, "Error open file %s", SUBGHZ_LAST_SETTINGS_PATH);
|
||||||
|
@ -109,76 +122,22 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count
|
||||||
|
|
||||||
furi_string_free(temp_str);
|
furi_string_free(temp_str);
|
||||||
|
|
||||||
if(temp_frequency == 0 || !furi_hal_subghz_is_tx_allowed(temp_frequency)) {
|
|
||||||
FURI_LOG_W(TAG, "Last used frequency not found or can't be used!");
|
|
||||||
|
|
||||||
instance->frequency = SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY;
|
|
||||||
instance->preset_index = SUBGHZ_LAST_SETTING_DEFAULT_PRESET;
|
|
||||||
instance->frequency_analyzer_feedback_level =
|
|
||||||
SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_FEEDBACK_LEVEL;
|
|
||||||
instance->frequency_analyzer_trigger = SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER;
|
|
||||||
instance->timestamp_file_names = false;
|
|
||||||
instance->enable_hopping = false;
|
|
||||||
instance->delete_old_signals = false;
|
|
||||||
instance->ignore_filter = 0x00;
|
|
||||||
// See bin_raw_value in applications/main/subghz/scenes/subghz_scene_receiver_config.c
|
|
||||||
instance->filter = SubGhzProtocolFlag_Decodable;
|
|
||||||
instance->rssi = SUBGHZ_RAW_THRESHOLD_MIN;
|
|
||||||
} else {
|
|
||||||
instance->frequency = temp_frequency;
|
|
||||||
instance->frequency_analyzer_feedback_level =
|
|
||||||
frequency_analyzer_feedback_level_was_read ?
|
|
||||||
temp_frequency_analyzer_feedback_level :
|
|
||||||
SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_FEEDBACK_LEVEL;
|
|
||||||
|
|
||||||
instance->frequency_analyzer_trigger = frequency_analyzer_trigger_was_read ?
|
|
||||||
temp_frequency_analyzer_trigger :
|
|
||||||
SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER;
|
|
||||||
|
|
||||||
if(!preset_was_read) {
|
|
||||||
FURI_LOG_W(TAG, "Preset was not read. Set default");
|
|
||||||
instance->preset_index = SUBGHZ_LAST_SETTING_DEFAULT_PRESET;
|
|
||||||
} else if(temp_preset > (uint32_t)preset_count - 1) {
|
|
||||||
FURI_LOG_W(
|
|
||||||
TAG,
|
|
||||||
"Last used preset out of range. Preset to set: %ld, Max index: %ld. Set default",
|
|
||||||
temp_preset,
|
|
||||||
(uint32_t)preset_count - 1);
|
|
||||||
instance->preset_index = SUBGHZ_LAST_SETTING_DEFAULT_PRESET;
|
|
||||||
} else {
|
|
||||||
instance->preset_index = temp_preset;
|
|
||||||
}
|
|
||||||
instance->timestamp_file_names = temp_timestamp_file_names;
|
|
||||||
|
|
||||||
instance->delete_old_signals = temp_delete_old_sig;
|
|
||||||
|
|
||||||
instance->rssi = rssi_was_read ? temp_rssi : SUBGHZ_RAW_THRESHOLD_MIN;
|
|
||||||
instance->enable_hopping = temp_enable_hopping;
|
|
||||||
instance->ignore_filter = ignore_filter_was_read ? temp_ignore_filter : 0x00;
|
|
||||||
#if SUBGHZ_LAST_SETTING_SAVE_BIN_RAW
|
|
||||||
instance->filter = filter_was_read ? temp_filter : SubGhzProtocolFlag_Decodable;
|
|
||||||
#else
|
|
||||||
if(filter_was_read) {
|
|
||||||
instance->filter = temp_filter != SubGhzProtocolFlag_Decodable ?
|
|
||||||
SubGhzProtocolFlag_Decodable :
|
|
||||||
temp_filter;
|
|
||||||
} else {
|
|
||||||
instance->filter = SubGhzProtocolFlag_Decodable;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
flipper_format_file_close(fff_data_file);
|
flipper_format_file_close(fff_data_file);
|
||||||
flipper_format_free(fff_data_file);
|
flipper_format_free(fff_data_file);
|
||||||
furi_record_close(RECORD_STORAGE);
|
furi_record_close(RECORD_STORAGE);
|
||||||
|
|
||||||
|
if(instance->frequency == 0 || !furi_hal_subghz_is_tx_allowed(instance->frequency)) {
|
||||||
|
instance->frequency = SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(instance->preset_index > (uint32_t)preset_count - 1) {
|
||||||
|
instance->preset_index = SUBGHZ_LAST_SETTING_DEFAULT_PRESET;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool subghz_last_settings_save(SubGhzLastSettings* instance) {
|
bool subghz_last_settings_save(SubGhzLastSettings* instance) {
|
||||||
furi_assert(instance);
|
furi_assert(instance);
|
||||||
|
|
||||||
#if SUBGHZ_LAST_SETTING_SAVE_BIN_RAW != true
|
|
||||||
instance->filter = SubGhzProtocolFlag_Decodable;
|
|
||||||
#endif
|
|
||||||
bool saved = false;
|
bool saved = false;
|
||||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||||
FlipperFormat* file = flipper_format_file_alloc(storage);
|
FlipperFormat* file = flipper_format_file_alloc(storage);
|
||||||
|
@ -195,55 +154,56 @@ bool subghz_last_settings_save(SubGhzLastSettings* instance) {
|
||||||
if(!flipper_format_write_header_cstr(
|
if(!flipper_format_write_header_cstr(
|
||||||
file, SUBGHZ_LAST_SETTING_FILE_TYPE, SUBGHZ_LAST_SETTING_FILE_VERSION))
|
file, SUBGHZ_LAST_SETTING_FILE_TYPE, SUBGHZ_LAST_SETTING_FILE_VERSION))
|
||||||
break;
|
break;
|
||||||
if(!flipper_format_insert_or_update_uint32(
|
if(!flipper_format_write_uint32(
|
||||||
file, SUBGHZ_LAST_SETTING_FIELD_PRESET, &instance->preset_index, 1)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(!flipper_format_insert_or_update_uint32(
|
|
||||||
file, SUBGHZ_LAST_SETTING_FIELD_FREQUENCY, &instance->frequency, 1)) {
|
file, SUBGHZ_LAST_SETTING_FIELD_FREQUENCY, &instance->frequency, 1)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!flipper_format_insert_or_update_uint32(
|
if(!flipper_format_write_uint32(
|
||||||
|
file, SUBGHZ_LAST_SETTING_FIELD_PRESET, &instance->preset_index, 1)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(!flipper_format_write_uint32(
|
||||||
file,
|
file,
|
||||||
SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_FEEDBACK_LEVEL,
|
SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_FEEDBACK_LEVEL,
|
||||||
&instance->frequency_analyzer_feedback_level,
|
&instance->frequency_analyzer_feedback_level,
|
||||||
1)) {
|
1)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!flipper_format_insert_or_update_float(
|
if(!flipper_format_write_float(
|
||||||
file,
|
file,
|
||||||
SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_TRIGGER,
|
SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_TRIGGER,
|
||||||
&instance->frequency_analyzer_trigger,
|
&instance->frequency_analyzer_trigger,
|
||||||
1)) {
|
1)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!flipper_format_insert_or_update_bool(
|
if(!flipper_format_write_bool(
|
||||||
file,
|
file,
|
||||||
SUBGHZ_LAST_SETTING_FIELD_TIMESTAMP_FILE_NAMES,
|
SUBGHZ_LAST_SETTING_FIELD_PROTOCOL_FILE_NAMES,
|
||||||
&instance->timestamp_file_names,
|
&instance->protocol_file_names,
|
||||||
1)) {
|
1)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!flipper_format_insert_or_update_bool(
|
if(!flipper_format_write_bool(
|
||||||
file, SUBGHZ_LAST_SETTING_FIELD_HOPPING_ENABLE, &instance->enable_hopping, 1)) {
|
file, SUBGHZ_LAST_SETTING_FIELD_HOPPING_ENABLE, &instance->enable_hopping, 1)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!flipper_format_insert_or_update_float(
|
if(!flipper_format_write_uint32(
|
||||||
file, SUBGHZ_LAST_SETTING_FIELD_RSSI_THRESHOLD, &instance->rssi, 1)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(!flipper_format_insert_or_update_uint32(
|
|
||||||
file, SUBGHZ_LAST_SETTING_FIELD_IGNORE_FILTER, &instance->ignore_filter, 1)) {
|
file, SUBGHZ_LAST_SETTING_FIELD_IGNORE_FILTER, &instance->ignore_filter, 1)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!flipper_format_insert_or_update_uint32(
|
if(!flipper_format_write_uint32(
|
||||||
file, SUBGHZ_LAST_SETTING_FIELD_FILTER, &instance->filter, 1)) {
|
file, SUBGHZ_LAST_SETTING_FIELD_FILTER, &instance->filter, 1)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!flipper_format_insert_or_update_bool(
|
if(!flipper_format_write_float(
|
||||||
|
file, SUBGHZ_LAST_SETTING_FIELD_RSSI_THRESHOLD, &instance->rssi, 1)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(!flipper_format_write_bool(
|
||||||
file, SUBGHZ_LAST_SETTING_FIELD_DELETE_OLD, &instance->delete_old_signals, 1)) {
|
file, SUBGHZ_LAST_SETTING_FIELD_DELETE_OLD, &instance->delete_old_signals, 1)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
saved = true;
|
saved = true;
|
||||||
} while(0);
|
} while(0);
|
||||||
|
|
||||||
|
@ -257,42 +217,3 @@ bool subghz_last_settings_save(SubGhzLastSettings* instance) {
|
||||||
|
|
||||||
return saved;
|
return saved;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* LOG_ON = "ON";
|
|
||||||
const char* LOG_OFF = "OFF";
|
|
||||||
|
|
||||||
static inline const char*
|
|
||||||
subghz_last_settings_log_filter_get_index(uint32_t filter, uint32_t flag) {
|
|
||||||
return READ_BIT(filter, flag) > 0 ? LOG_ON : LOG_OFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const char* bool_to_char(bool value) {
|
|
||||||
return value ? LOG_ON : LOG_OFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
void subghz_last_settings_log(SubGhzLastSettings* instance) {
|
|
||||||
furi_assert(instance);
|
|
||||||
|
|
||||||
FURI_LOG_I(
|
|
||||||
TAG,
|
|
||||||
"Frequency: %03ld.%02ld, FeedbackLevel: %ld, FATrigger: %.2f, TimestampNames: %s,\n"
|
|
||||||
"Hopping: %s,\nPreset: %ld, RSSI: %.2f, "
|
|
||||||
"Starline: %s, Cars: %s, Magellan: %s, NiceFloR-S: %s, BinRAW: %s",
|
|
||||||
instance->frequency / 1000000 % 1000,
|
|
||||||
instance->frequency / 10000 % 100,
|
|
||||||
instance->frequency_analyzer_feedback_level,
|
|
||||||
(double)instance->frequency_analyzer_trigger,
|
|
||||||
bool_to_char(instance->timestamp_file_names),
|
|
||||||
bool_to_char(instance->enable_hopping),
|
|
||||||
instance->preset_index,
|
|
||||||
(double)instance->rssi,
|
|
||||||
subghz_last_settings_log_filter_get_index(
|
|
||||||
instance->ignore_filter, SubGhzProtocolFlag_StarLine),
|
|
||||||
subghz_last_settings_log_filter_get_index(
|
|
||||||
instance->ignore_filter, SubGhzProtocolFlag_AutoAlarms),
|
|
||||||
subghz_last_settings_log_filter_get_index(
|
|
||||||
instance->ignore_filter, SubGhzProtocolFlag_Magellan),
|
|
||||||
subghz_last_settings_log_filter_get_index(
|
|
||||||
instance->ignore_filter, SubGhzProtocolFlag_NiceFlorS),
|
|
||||||
subghz_last_settings_log_filter_get_index(instance->filter, SubGhzProtocolFlag_BinRAW));
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
#include <lib/subghz/types.h>
|
#include <lib/subghz/types.h>
|
||||||
|
|
||||||
#define SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER (-93.0f)
|
#define SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER (-93.0f)
|
||||||
#define SUBGHZ_LAST_SETTING_SAVE_BIN_RAW true
|
|
||||||
#define SUBGHZ_LAST_SETTING_SAVE_PRESET true
|
|
||||||
// 1 = "AM650"
|
// 1 = "AM650"
|
||||||
// "AM270", "AM650", "FM238", "FM476",
|
// "AM270", "AM650", "FM238", "FM476",
|
||||||
#define SUBGHZ_LAST_SETTING_DEFAULT_PRESET 1
|
#define SUBGHZ_LAST_SETTING_DEFAULT_PRESET 1
|
||||||
|
@ -20,7 +18,7 @@ typedef struct {
|
||||||
uint32_t preset_index; // AKA Modulation
|
uint32_t preset_index; // AKA Modulation
|
||||||
uint32_t frequency_analyzer_feedback_level;
|
uint32_t frequency_analyzer_feedback_level;
|
||||||
float frequency_analyzer_trigger;
|
float frequency_analyzer_trigger;
|
||||||
bool timestamp_file_names;
|
bool protocol_file_names;
|
||||||
bool enable_hopping;
|
bool enable_hopping;
|
||||||
uint32_t ignore_filter;
|
uint32_t ignore_filter;
|
||||||
uint32_t filter;
|
uint32_t filter;
|
||||||
|
@ -35,5 +33,3 @@ void subghz_last_settings_free(SubGhzLastSettings* instance);
|
||||||
void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count);
|
void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count);
|
||||||
|
|
||||||
bool subghz_last_settings_save(SubGhzLastSettings* instance);
|
bool subghz_last_settings_save(SubGhzLastSettings* instance);
|
||||||
|
|
||||||
void subghz_last_settings_log(SubGhzLastSettings* instance);
|
|
||||||
|
|
|
@ -32,12 +32,14 @@ static void desktop_loader_callback(const void* message, void* context) {
|
||||||
Desktop* desktop = context;
|
Desktop* desktop = context;
|
||||||
const LoaderEvent* event = message;
|
const LoaderEvent* event = message;
|
||||||
|
|
||||||
if(event->type == LoaderEventTypeApplicationStarted) {
|
if(event->type == LoaderEventTypeApplicationBeforeLoad) {
|
||||||
desktop->animation_lock = api_lock_alloc_locked();
|
desktop->animation_lock = api_lock_alloc_locked();
|
||||||
view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopGlobalBeforeAppStarted);
|
view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopGlobalBeforeAppStarted);
|
||||||
api_lock_wait_unlock_and_free(desktop->animation_lock);
|
api_lock_wait_unlock_and_free(desktop->animation_lock);
|
||||||
desktop->animation_lock = NULL;
|
desktop->animation_lock = NULL;
|
||||||
} else if(event->type == LoaderEventTypeApplicationStopped) {
|
} else if(
|
||||||
|
event->type == LoaderEventTypeApplicationLoadFailed ||
|
||||||
|
event->type == LoaderEventTypeApplicationStopped) {
|
||||||
view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopGlobalAfterAppFinished);
|
view_dispatcher_send_custom_event(desktop->view_dispatcher, DesktopGlobalAfterAppFinished);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,7 +152,7 @@ bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DesktopMainEventOpenPowerOff: {
|
case DesktopMainEventOpenPowerOff: {
|
||||||
loader_start(desktop->loader, "Power", "off", NULL);
|
loader_start_detached_with_gui_error(desktop->loader, "Power", "off");
|
||||||
consumed = true;
|
consumed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,34 +47,16 @@ LoaderStatus
|
||||||
return result.value;
|
return result.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
LoaderStatus loader_start_with_gui_error(Loader* loader, const char* name, const char* args) {
|
static void loader_show_gui_error(LoaderStatus status, FuriString* error_message) {
|
||||||
furi_check(loader);
|
// TODO FL-3522: we have many places where we can emit a double start, ex: desktop, menu
|
||||||
furi_check(name);
|
// so i prefer to not show LoaderStatusErrorAppStarted error message for now
|
||||||
|
if(status == LoaderStatusErrorUnknownApp || status == LoaderStatusErrorInternal) {
|
||||||
FuriString* error_message = furi_string_alloc();
|
|
||||||
LoaderStatus status = loader_start(loader, name, args, error_message);
|
|
||||||
|
|
||||||
if(status == LoaderStatusErrorUnknownApp &&
|
|
||||||
loader_find_external_application_by_name(name) != NULL) {
|
|
||||||
// Special case for external apps
|
|
||||||
DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
|
|
||||||
DialogMessage* message = dialog_message_alloc();
|
|
||||||
dialog_message_set_header(message, "Update needed", 64, 3, AlignCenter, AlignTop);
|
|
||||||
dialog_message_set_buttons(message, NULL, NULL, NULL);
|
|
||||||
dialog_message_set_icon(message, &I_WarningDolphinFlip_45x42, 83, 22);
|
|
||||||
dialog_message_set_text(
|
|
||||||
message, "Update firmware\nto run this app", 3, 26, AlignLeft, AlignTop);
|
|
||||||
dialog_message_show(dialogs, message);
|
|
||||||
dialog_message_free(message);
|
|
||||||
furi_record_close(RECORD_DIALOGS);
|
|
||||||
} else if(status == LoaderStatusErrorUnknownApp || status == LoaderStatusErrorInternal) {
|
|
||||||
// TODO FL-3522: we have many places where we can emit a double start, ex: desktop, menu
|
|
||||||
// so i prefer to not show LoaderStatusErrorAppStarted error message for now
|
|
||||||
DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
|
DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS);
|
||||||
DialogMessage* message = dialog_message_alloc();
|
DialogMessage* message = dialog_message_alloc();
|
||||||
dialog_message_set_header(message, "Error", 64, 0, AlignCenter, AlignTop);
|
dialog_message_set_header(message, "Error", 64, 0, AlignCenter, AlignTop);
|
||||||
dialog_message_set_buttons(message, NULL, NULL, NULL);
|
dialog_message_set_buttons(message, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
furi_string_replace(error_message, ":", "\n");
|
||||||
furi_string_replace(error_message, "/ext/apps/", "");
|
furi_string_replace(error_message, "/ext/apps/", "");
|
||||||
furi_string_replace(error_message, ", ", "\n");
|
furi_string_replace(error_message, ", ", "\n");
|
||||||
furi_string_replace(error_message, ": ", "\n");
|
furi_string_replace(error_message, ": ", "\n");
|
||||||
|
@ -86,11 +68,31 @@ LoaderStatus loader_start_with_gui_error(Loader* loader, const char* name, const
|
||||||
dialog_message_free(message);
|
dialog_message_free(message);
|
||||||
furi_record_close(RECORD_DIALOGS);
|
furi_record_close(RECORD_DIALOGS);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LoaderStatus loader_start_with_gui_error(Loader* loader, const char* name, const char* args) {
|
||||||
|
furi_check(loader);
|
||||||
|
furi_check(name);
|
||||||
|
|
||||||
|
FuriString* error_message = furi_string_alloc();
|
||||||
|
LoaderStatus status = loader_start(loader, name, args, error_message);
|
||||||
|
loader_show_gui_error(status, error_message);
|
||||||
furi_string_free(error_message);
|
furi_string_free(error_message);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void loader_start_detached_with_gui_error(Loader* loader, const char* name, const char* args) {
|
||||||
|
furi_check(loader);
|
||||||
|
furi_check(name);
|
||||||
|
|
||||||
|
LoaderMessage message;
|
||||||
|
|
||||||
|
message.type = LoaderMessageTypeStartByNameDetachedWithGuiError;
|
||||||
|
message.start.name = name ? strdup(name) : NULL;
|
||||||
|
message.start.args = args ? strdup(args) : NULL;
|
||||||
|
furi_message_queue_put(loader->queue, &message, FuriWaitForever);
|
||||||
|
}
|
||||||
|
|
||||||
bool loader_lock(Loader* loader) {
|
bool loader_lock(Loader* loader) {
|
||||||
furi_check(loader);
|
furi_check(loader);
|
||||||
|
|
||||||
|
@ -256,6 +258,9 @@ static void loader_start_internal_app(
|
||||||
const FlipperInternalApplication* app,
|
const FlipperInternalApplication* app,
|
||||||
const char* args) {
|
const char* args) {
|
||||||
FURI_LOG_I(TAG, "Starting %s", app->name);
|
FURI_LOG_I(TAG, "Starting %s", app->name);
|
||||||
|
LoaderEvent event;
|
||||||
|
event.type = LoaderEventTypeApplicationBeforeLoad;
|
||||||
|
furi_pubsub_publish(loader->pubsub, &event);
|
||||||
|
|
||||||
// store args
|
// store args
|
||||||
furi_assert(loader->app.args == NULL);
|
furi_assert(loader->app.args == NULL);
|
||||||
|
@ -311,6 +316,9 @@ static LoaderStatus loader_start_external_app(
|
||||||
FuriString* error_message,
|
FuriString* error_message,
|
||||||
bool ignore_mismatch) {
|
bool ignore_mismatch) {
|
||||||
LoaderStatus status = loader_make_success_status(error_message);
|
LoaderStatus status = loader_make_success_status(error_message);
|
||||||
|
LoaderEvent event;
|
||||||
|
event.type = LoaderEventTypeApplicationBeforeLoad;
|
||||||
|
furi_pubsub_publish(loader->pubsub, &event);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
loader->app.fap = flipper_application_alloc(storage, firmware_api_interface);
|
loader->app.fap = flipper_application_alloc(storage, firmware_api_interface);
|
||||||
|
@ -390,6 +398,8 @@ static LoaderStatus loader_start_external_app(
|
||||||
if(status != LoaderStatusOk) {
|
if(status != LoaderStatusOk) {
|
||||||
flipper_application_free(loader->app.fap);
|
flipper_application_free(loader->app.fap);
|
||||||
loader->app.fap = NULL;
|
loader->app.fap = NULL;
|
||||||
|
event.type = LoaderEventTypeApplicationLoadFailed;
|
||||||
|
furi_pubsub_publish(loader->pubsub, &event);
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
@ -567,6 +577,16 @@ int32_t loader_srv(void* p) {
|
||||||
loader, message.start.name, message.start.args, message.start.error_message);
|
loader, message.start.name, message.start.args, message.start.error_message);
|
||||||
api_lock_unlock(message.api_lock);
|
api_lock_unlock(message.api_lock);
|
||||||
break;
|
break;
|
||||||
|
case LoaderMessageTypeStartByNameDetachedWithGuiError: {
|
||||||
|
FuriString* error_message = furi_string_alloc();
|
||||||
|
LoaderStatus status = loader_do_start_by_name(
|
||||||
|
loader, message.start.name, message.start.args, error_message);
|
||||||
|
loader_show_gui_error(status, error_message);
|
||||||
|
if(message.start.name) free((void*)message.start.name);
|
||||||
|
if(message.start.args) free((void*)message.start.args);
|
||||||
|
furi_string_free(error_message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case LoaderMessageTypeShowMenu:
|
case LoaderMessageTypeShowMenu:
|
||||||
loader_do_menu_show(loader);
|
loader_do_menu_show(loader);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -20,6 +20,8 @@ typedef enum {
|
||||||
} LoaderStatus;
|
} LoaderStatus;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
LoaderEventTypeApplicationBeforeLoad,
|
||||||
|
LoaderEventTypeApplicationLoadFailed,
|
||||||
LoaderEventTypeApplicationStarted,
|
LoaderEventTypeApplicationStarted,
|
||||||
LoaderEventTypeApplicationStopped
|
LoaderEventTypeApplicationStopped
|
||||||
} LoaderEventType;
|
} LoaderEventType;
|
||||||
|
@ -48,6 +50,14 @@ LoaderStatus
|
||||||
*/
|
*/
|
||||||
LoaderStatus loader_start_with_gui_error(Loader* loader, const char* name, const char* args);
|
LoaderStatus loader_start_with_gui_error(Loader* loader, const char* name, const char* args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Start application detached with GUI error message
|
||||||
|
* @param[in] instance loader instance
|
||||||
|
* @param[in] name application name
|
||||||
|
* @param[in] args application arguments
|
||||||
|
*/
|
||||||
|
void loader_start_detached_with_gui_error(Loader* loader, const char* name, const char* args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Lock application start
|
* @brief Lock application start
|
||||||
* @param[in] instance loader instance
|
* @param[in] instance loader instance
|
||||||
|
|
|
@ -30,6 +30,7 @@ typedef enum {
|
||||||
LoaderMessageTypeLock,
|
LoaderMessageTypeLock,
|
||||||
LoaderMessageTypeUnlock,
|
LoaderMessageTypeUnlock,
|
||||||
LoaderMessageTypeIsLocked,
|
LoaderMessageTypeIsLocked,
|
||||||
|
LoaderMessageTypeStartByNameDetachedWithGuiError,
|
||||||
} LoaderMessageType;
|
} LoaderMessageType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -2172,6 +2172,7 @@ Function,+,loader_is_locked,_Bool,Loader*
|
||||||
Function,+,loader_lock,_Bool,Loader*
|
Function,+,loader_lock,_Bool,Loader*
|
||||||
Function,+,loader_show_menu,void,Loader*
|
Function,+,loader_show_menu,void,Loader*
|
||||||
Function,+,loader_start,LoaderStatus,"Loader*, const char*, const char*, FuriString*"
|
Function,+,loader_start,LoaderStatus,"Loader*, const char*, const char*, FuriString*"
|
||||||
|
Function,+,loader_start_detached_with_gui_error,void,"Loader*, const char*, const char*"
|
||||||
Function,+,loader_start_with_gui_error,LoaderStatus,"Loader*, const char*, const char*"
|
Function,+,loader_start_with_gui_error,LoaderStatus,"Loader*, const char*, const char*"
|
||||||
Function,+,loader_unlock,void,Loader*
|
Function,+,loader_unlock,void,Loader*
|
||||||
Function,+,loading_alloc,Loading*,
|
Function,+,loading_alloc,Loading*,
|
||||||
|
|
|
Loading…
Reference in a new issue