diff --git a/applications/main/subghz/scenes/subghz_scene_decode_raw.c b/applications/main/subghz/scenes/subghz_scene_decode_raw.c index 5746efbed..5ac4fcccd 100644 --- a/applications/main/subghz/scenes/subghz_scene_decode_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_decode_raw.c @@ -62,26 +62,31 @@ static void subghz_scene_add_to_history_callback( void* context) { furi_assert(context); SubGhz* subghz = context; - FuriString* str_buff; - str_buff = furi_string_alloc(); + FuriString* item_name; + FuriString* item_time; + uint16_t idx = subghz_history_get_item(subghz->txrx->history); + item_name = furi_string_alloc(); + item_time = furi_string_alloc(); if(subghz_history_add_to_history(subghz->txrx->history, decoder_base, subghz->txrx->preset)) { - furi_string_reset(str_buff); + furi_string_reset(item_name); + furi_string_reset(item_time); subghz->state_notifications = SubGhzNotificationStateRxDone; - subghz_history_get_text_item_menu( - subghz->txrx->history, str_buff, subghz_history_get_item(subghz->txrx->history) - 1); + subghz_history_get_text_item_menu(subghz->txrx->history, item_name, idx); + subghz_history_get_time_item_menu(subghz->txrx->history, item_time, idx); subghz_view_receiver_add_item_to_menu( subghz->subghz_receiver, - furi_string_get_cstr(str_buff), - subghz_history_get_type_protocol( - subghz->txrx->history, subghz_history_get_item(subghz->txrx->history) - 1)); + furi_string_get_cstr(item_name), + furi_string_get_cstr(item_time), + subghz_history_get_type_protocol(subghz->txrx->history, idx)); subghz_scene_receiver_update_statusbar(subghz); } subghz_receiver_reset(receiver); - furi_string_free(str_buff); + furi_string_free(item_name); + furi_string_free(item_time); } bool subghz_scene_decode_raw_start(SubGhz* subghz) { @@ -159,8 +164,10 @@ bool subghz_scene_decode_raw_next(SubGhz* subghz) { void subghz_scene_decode_raw_on_enter(void* context) { SubGhz* subghz = context; - FuriString* str_buff; - str_buff = furi_string_alloc(); + FuriString* item_name; + FuriString* item_time; + item_name = furi_string_alloc(); + item_time = furi_string_alloc(); subghz_view_receiver_set_lock(subghz->subghz_receiver, subghz->lock); subghz_view_receiver_set_mode(subghz->subghz_receiver, SubGhzViewReceiverModeFile); @@ -183,14 +190,18 @@ void subghz_scene_decode_raw_on_enter(void* context) { //Load history to receiver subghz_view_receiver_exit(subghz->subghz_receiver); for(uint8_t i = 0; i < subghz_history_get_item(subghz->txrx->history); i++) { - furi_string_reset(str_buff); - subghz_history_get_text_item_menu(subghz->txrx->history, str_buff, i); + furi_string_reset(item_name); + furi_string_reset(item_time); + subghz_history_get_text_item_menu(subghz->txrx->history, item_name, i); + subghz_history_get_time_item_menu(subghz->txrx->history, item_time, i); subghz_view_receiver_add_item_to_menu( subghz->subghz_receiver, - furi_string_get_cstr(str_buff), + furi_string_get_cstr(item_name), + furi_string_get_cstr(item_time), subghz_history_get_type_protocol(subghz->txrx->history, i)); } - furi_string_free(str_buff); + furi_string_free(item_name); + furi_string_free(item_time); subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, subghz->txrx->idx_menu_chosen); } diff --git a/applications/main/subghz/scenes/subghz_scene_ext_module_settings.c b/applications/main/subghz/scenes/subghz_scene_ext_module_settings.c index a96208074..75a2215fc 100644 --- a/applications/main/subghz/scenes/subghz_scene_ext_module_settings.c +++ b/applications/main/subghz/scenes/subghz_scene_ext_module_settings.c @@ -1,10 +1,11 @@ #include "../subghz_i.h" #include "../helpers/subghz_custom_event.h" -uint8_t value_index_exm; -uint8_t value_index_dpin; -uint8_t value_index_cnt; -uint8_t value_index_pwr; +static uint8_t value_index_exm; +static uint8_t value_index_dpin; +static uint8_t value_index_cnt; +static uint8_t value_index_pwr; +static uint8_t value_index_time; #define EXT_MODULES_COUNT (sizeof(radio_modules_variables_text) / sizeof(char* const)) const char* const radio_modules_variables_text[] = { @@ -18,6 +19,12 @@ const char* const ext_mod_power_text[EXT_MOD_POWER_COUNT] = { "OFF", }; +#define TIMESTAMP_NAMES_COUNT 2 +const char* const timestamp_names_text[TIMESTAMP_NAMES_COUNT] = { + "OFF", + "ON", +}; + #define DEBUG_P_COUNT 2 const char* const debug_pin_text[DEBUG_P_COUNT] = { "OFF", @@ -104,6 +111,17 @@ static void subghz_scene_receiver_config_set_ext_mod_power(VariableItem* item) { subghz_last_settings_save(subghz->last_settings); } +static void subghz_scene_receiver_config_set_timestamp_file_names(VariableItem* item) { + SubGhz* subghz = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + + variable_item_set_current_value_text(item, timestamp_names_text[index]); + + furi_hal_subghz_set_timestamp_file_names((index == 1)); + subghz->last_settings->timestamp_file_names = (index == 1); + subghz_last_settings_save(subghz->last_settings); +} + void subghz_scene_ext_module_settings_on_enter(void* context) { SubGhz* subghz = context; @@ -129,6 +147,16 @@ void subghz_scene_ext_module_settings_on_enter(void* context) { variable_item_set_current_value_index(item, value_index_pwr); variable_item_set_current_value_text(item, ext_mod_power_text[value_index_pwr]); + item = variable_item_list_add( + subghz->variable_item_list, + "Time in names", + TIMESTAMP_NAMES_COUNT, + subghz_scene_receiver_config_set_timestamp_file_names, + subghz); + value_index_time = furi_hal_subghz_get_timestamp_file_names(); + variable_item_set_current_value_index(item, value_index_time); + variable_item_set_current_value_text(item, timestamp_names_text[value_index_time]); + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { item = variable_item_list_add( subghz->variable_item_list, diff --git a/applications/main/subghz/scenes/subghz_scene_receiver.c b/applications/main/subghz/scenes/subghz_scene_receiver.c index 5276bc4a8..b17a0700b 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver.c @@ -91,34 +91,41 @@ static void subghz_scene_add_to_history_callback( void* context) { furi_assert(context); SubGhz* subghz = context; - FuriString* str_buff; - str_buff = furi_string_alloc(); + FuriString* item_name; + FuriString* item_time; + uint16_t idx = subghz_history_get_item(subghz->txrx->history); + item_name = furi_string_alloc(); + item_time = furi_string_alloc(); if(subghz_history_add_to_history(subghz->txrx->history, decoder_base, subghz->txrx->preset)) { - furi_string_reset(str_buff); + furi_string_reset(item_name); + furi_string_reset(item_time); subghz->state_notifications = SubGhzNotificationStateRxDone; - subghz_history_get_text_item_menu( - subghz->txrx->history, str_buff, subghz_history_get_item(subghz->txrx->history) - 1); + subghz_history_get_text_item_menu(subghz->txrx->history, item_name, idx); + subghz_history_get_time_item_menu(subghz->txrx->history, item_time, idx); subghz_view_receiver_add_item_to_menu( subghz->subghz_receiver, - furi_string_get_cstr(str_buff), - subghz_history_get_type_protocol( - subghz->txrx->history, subghz_history_get_item(subghz->txrx->history) - 1)); + furi_string_get_cstr(item_name), + furi_string_get_cstr(item_time), + subghz_history_get_type_protocol(subghz->txrx->history, idx)); subghz_scene_receiver_update_statusbar(subghz); } subghz_receiver_reset(receiver); - furi_string_free(str_buff); + furi_string_free(item_name); + furi_string_free(item_time); subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; } void subghz_scene_receiver_on_enter(void* context) { SubGhz* subghz = context; - FuriString* str_buff; - str_buff = furi_string_alloc(); + FuriString* item_name; + FuriString* item_time; + item_name = furi_string_alloc(); + item_time = furi_string_alloc(); if(subghz->txrx->rx_key_state == SubGhzRxKeyStateIDLE) { subghz_preset_init(subghz, "AM650", subghz->last_settings->frequency, NULL, 0); @@ -132,15 +139,19 @@ void subghz_scene_receiver_on_enter(void* context) { //Load history to receiver subghz_view_receiver_exit(subghz->subghz_receiver); for(uint8_t i = 0; i < subghz_history_get_item(subghz->txrx->history); i++) { - furi_string_reset(str_buff); - subghz_history_get_text_item_menu(subghz->txrx->history, str_buff, i); + furi_string_reset(item_name); + furi_string_reset(item_time); + subghz_history_get_text_item_menu(subghz->txrx->history, item_name, i); + subghz_history_get_time_item_menu(subghz->txrx->history, item_time, i); subghz_view_receiver_add_item_to_menu( subghz->subghz_receiver, - furi_string_get_cstr(str_buff), + furi_string_get_cstr(item_name), + furi_string_get_cstr(item_time), subghz_history_get_type_protocol(subghz->txrx->history, i)); subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; } - furi_string_free(str_buff); + furi_string_free(item_name); + furi_string_free(item_time); subghz_scene_receiver_update_statusbar(subghz); subghz_view_receiver_set_callback( subghz->subghz_receiver, subghz_scene_receiver_callback, subghz); diff --git a/applications/main/subghz/scenes/subghz_scene_save_name.c b/applications/main/subghz/scenes/subghz_scene_save_name.c index 4f37ebc0b..282e22201 100644 --- a/applications/main/subghz/scenes/subghz_scene_save_name.c +++ b/applications/main/subghz/scenes/subghz_scene_save_name.c @@ -14,18 +14,34 @@ void subghz_scene_save_name_text_input_callback(void* context) { view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventSceneSaveName); } -void subghz_scene_save_name_get_timefilename(FuriString* name) { +void subghz_scene_save_name_get_timefilename( + FuriString* name, + const char* proto_name, + bool fulldate) { FuriHalRtcDateTime datetime = {0}; furi_hal_rtc_get_datetime(&datetime); - furi_string_printf( - name, - "RAW_%.4d%.2d%.2d-%.2d%.2d%.2d", - datetime.year, - datetime.month, - datetime.day, - datetime.hour, - datetime.minute, - datetime.second); + if(fulldate) { + furi_string_printf( + name, + "%s_%.4d%.2d%.2d-%.2d%.2d%.2d", + proto_name, + datetime.year, + datetime.month, + datetime.day, + datetime.hour, + datetime.minute, + datetime.second); + } else { + furi_string_printf( + name, + "%s_%.2d%.2d-%.2d%.2d%.2d", + proto_name, + datetime.month, + datetime.day, + datetime.hour, + datetime.minute, + datetime.second); + } } void subghz_scene_save_name_on_enter(void* context) { @@ -42,8 +58,25 @@ void subghz_scene_save_name_on_enter(void* context) { if(!subghz_path_is_file(subghz->file_path)) { char file_name_buf[SUBGHZ_MAX_LEN_NAME] = {0}; - set_random_name(file_name_buf, SUBGHZ_MAX_LEN_NAME); - furi_string_set(file_name, file_name_buf); + if(furi_hal_subghz_get_timestamp_file_names()) { + if(subghz->txrx->decoder_result->protocol->name != 0x0) { + if(subghz->txrx->decoder_result->protocol->name != NULL) { + if(strlen(subghz->txrx->decoder_result->protocol->name) != 0) { + subghz_scene_save_name_get_timefilename( + file_name, subghz->txrx->decoder_result->protocol->name, false); + } else { + subghz_scene_save_name_get_timefilename(file_name, "S", true); + } + } else { + subghz_scene_save_name_get_timefilename(file_name, "S", true); + } + } else { + subghz_scene_save_name_get_timefilename(file_name, "S", true); + } + } else { + set_random_name(file_name_buf, SUBGHZ_MAX_LEN_NAME); + furi_string_set(file_name, file_name_buf); + } furi_string_set(subghz->file_path, SUBGHZ_APP_FOLDER); //highlighting the entire filename by default dev_name_empty = true; @@ -57,7 +90,7 @@ void subghz_scene_save_name_on_enter(void* context) { if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) == SubGhzCustomEventManagerSetRAW) { dev_name_empty = true; - subghz_scene_save_name_get_timefilename(file_name); + subghz_scene_save_name_get_timefilename(file_name, "RAW", true); } } furi_string_set(subghz->file_path, dir_name); diff --git a/applications/main/subghz/subghz_history.c b/applications/main/subghz/subghz_history.c index f6530238e..51d5ada7d 100644 --- a/applications/main/subghz/subghz_history.c +++ b/applications/main/subghz/subghz_history.c @@ -12,6 +12,7 @@ typedef struct { FlipperFormat* flipper_string; uint8_t type; SubGhzRadioPreset* preset; + FuriHalRtcDateTime datetime; } SubGhzHistoryItem; ARRAY_DEF(SubGhzHistoryItemArray, SubGhzHistoryItem, M_POD_OPLIST) @@ -164,6 +165,12 @@ void subghz_history_get_text_item_menu(SubGhzHistory* instance, FuriString* outp furi_string_set(output, item->item_str); } +void subghz_history_get_time_item_menu(SubGhzHistory* instance, FuriString* output, uint16_t idx) { + SubGhzHistoryItem* item = SubGhzHistoryItemArray_get(instance->history->data, idx); + FuriHalRtcDateTime* t = &item->datetime; + furi_string_printf(output, "%.2d:%.2d:%.2d ", t->hour, t->minute, t->second); +} + bool subghz_history_add_to_history( SubGhzHistory* instance, void* context, @@ -195,6 +202,7 @@ bool subghz_history_add_to_history( furi_string_set(item->preset->name, preset->name); item->preset->data = preset->data; item->preset->data_size = preset->data_size; + furi_hal_rtc_get_datetime(&item->datetime); item->item_str = furi_string_alloc(); item->flipper_string = flipper_format_string_alloc(); diff --git a/applications/main/subghz/subghz_history.h b/applications/main/subghz/subghz_history.h index 1f2f8d246..1b27d52ad 100644 --- a/applications/main/subghz/subghz_history.h +++ b/applications/main/subghz/subghz_history.h @@ -78,6 +78,14 @@ const char* subghz_history_get_protocol_name(SubGhzHistory* instance, uint16_t i */ void subghz_history_get_text_item_menu(SubGhzHistory* instance, FuriString* output, uint16_t idx); +/** Get time item menu to history[idx] + * + * @param instance - SubGhzHistory instance + * @param output - FuriString* output + * @param idx - record index + */ +void subghz_history_get_time_item_menu(SubGhzHistory* instance, FuriString* output, uint16_t idx); + /** Get string the remaining number of records to history * * @param instance - SubGhzHistory instance diff --git a/applications/main/subghz/subghz_last_settings.c b/applications/main/subghz/subghz_last_settings.c index 6fc51554d..2f4445a42 100644 --- a/applications/main/subghz/subghz_last_settings.c +++ b/applications/main/subghz/subghz_last_settings.c @@ -19,6 +19,7 @@ #define SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_TRIGGER "FATrigger" #define SUBGHZ_LAST_SETTING_FIELD_EXTERNAL_MODULE_ENABLED "External" #define SUBGHZ_LAST_SETTING_FIELD_EXTERNAL_MODULE_POWER "ExtPower" +#define SUBGHZ_LAST_SETTING_FIELD_TIMESTAMP_FILE_NAMES "TimestampNames" SubGhzLastSettings* subghz_last_settings_alloc(void) { SubGhzLastSettings* instance = malloc(sizeof(SubGhzLastSettings)); @@ -45,6 +46,7 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count float temp_frequency_analyzer_trigger = 0; bool temp_external_module_enabled = false; bool temp_external_module_power_5v_disable = false; + bool temp_timestamp_file_names = false; //int32_t temp_preset = 0; bool frequency_analyzer_feedback_level_was_read = false; bool frequency_analyzer_trigger_was_read = false; @@ -76,6 +78,11 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count SUBGHZ_LAST_SETTING_FIELD_EXTERNAL_MODULE_POWER, (bool*)&temp_external_module_power_5v_disable, 1); + flipper_format_read_bool( + fff_data_file, + SUBGHZ_LAST_SETTING_FIELD_TIMESTAMP_FILE_NAMES, + (bool*)&temp_timestamp_file_names, + 1); } else { FURI_LOG_E(TAG, "Error open file %s", SUBGHZ_LAST_SETTINGS_PATH); @@ -89,6 +96,7 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_FEEDBACK_LEVEL; instance->frequency_analyzer_trigger = SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER; instance->external_module_enabled = false; + instance->timestamp_file_names = false; } else { instance->frequency = temp_frequency; @@ -109,6 +117,11 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count instance->external_module_power_5v_disable = temp_external_module_power_5v_disable; + instance->timestamp_file_names = temp_timestamp_file_names; + + // Set globally + furi_hal_subghz_set_timestamp_file_names(instance->timestamp_file_names); + if(instance->external_module_power_5v_disable) { furi_hal_subghz_set_external_power_disable(true); furi_hal_subghz_disable_ext_power(); @@ -189,6 +202,13 @@ bool subghz_last_settings_save(SubGhzLastSettings* instance) { 1)) { break; } + if(!flipper_format_insert_or_update_bool( + file, + SUBGHZ_LAST_SETTING_FIELD_TIMESTAMP_FILE_NAMES, + &instance->timestamp_file_names, + 1)) { + break; + } saved = true; } while(0); diff --git a/applications/main/subghz/subghz_last_settings.h b/applications/main/subghz/subghz_last_settings.h index 5e3630468..260c879f4 100644 --- a/applications/main/subghz/subghz_last_settings.h +++ b/applications/main/subghz/subghz_last_settings.h @@ -12,6 +12,7 @@ typedef struct { float frequency_analyzer_trigger; bool external_module_enabled; bool external_module_power_5v_disable; + bool timestamp_file_names; } SubGhzLastSettings; SubGhzLastSettings* subghz_last_settings_alloc(void); diff --git a/applications/main/subghz/views/receiver.c b/applications/main/subghz/views/receiver.c index 8dbb22b86..33a3c79d1 100644 --- a/applications/main/subghz/views/receiver.c +++ b/applications/main/subghz/views/receiver.c @@ -14,8 +14,12 @@ #define SUBGHZ_RAW_THRESHOLD_MIN -90.0f +#define SCROLL_INTERVAL (333) +#define SCROLL_DELAY (2) + typedef struct { FuriString* item_str; + FuriString* time; uint8_t type; } SubGhzReceiverMenuItem; @@ -51,6 +55,7 @@ struct SubGhzViewReceiver { View* view; SubGhzViewReceiverCallback callback; void* context; + FuriTimer* scroll_timer; }; typedef struct { @@ -65,6 +70,7 @@ typedef struct { SubGhzViewReceiverBarShow bar_show; SubGhzViewReceiverMode mode; uint8_t u_rssi; + size_t scroll_counter; } SubGhzViewReceiverModel; void subghz_view_receiver_set_mode( @@ -144,6 +150,7 @@ static void subghz_view_receiver_update_offset(SubGhzViewReceiver* subghz_receiv void subghz_view_receiver_add_item_to_menu( SubGhzViewReceiver* subghz_receiver, const char* name, + const char* time, uint8_t type) { furi_assert(subghz_receiver); with_view_model( @@ -152,6 +159,7 @@ void subghz_view_receiver_add_item_to_menu( { SubGhzReceiverMenuItem* item_menu = SubGhzReceiverMenuItemArray_push_raw(model->history->data); + item_menu->time = furi_string_alloc_set(time); item_menu->item_str = furi_string_alloc_set(name); item_menu->type = type; if((model->idx == model->history_item - 1)) { @@ -240,14 +248,29 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { size_t idx = CLAMP((uint16_t)(i + model->list_offset), model->history_item, 0); item_menu = SubGhzReceiverMenuItemArray_get(model->history->data, idx); furi_string_set(str_buff, item_menu->item_str); - elements_string_fit_width(canvas, str_buff, scrollbar ? MAX_LEN_PX - 7 : MAX_LEN_PX); + size_t scroll_counter = model->scroll_counter; if(model->idx == idx) { subghz_view_receiver_draw_frame(canvas, i, scrollbar); + if(scroll_counter < SCROLL_DELAY) { + // Show time of signal one moment + furi_string_set(str_buff, item_menu->time); + scroll_counter = 0; + } else { + scroll_counter -= SCROLL_DELAY; + } } else { canvas_set_color(canvas, ColorBlack); + scroll_counter = 0; } canvas_draw_icon(canvas, 4, 2 + i * FRAME_HEIGHT, ReceiverItemIcons[item_menu->type]); - canvas_draw_str(canvas, 15, 9 + i * FRAME_HEIGHT, furi_string_get_cstr(str_buff)); + elements_scrollable_text_line( + canvas, + 15, + 9 + i * FRAME_HEIGHT, + (scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX), + str_buff, + scroll_counter, + (model->idx != idx)); furi_string_reset(str_buff); } if(scrollbar) { @@ -353,6 +376,13 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) { } } +static void subghz_view_receiver_scroll_timer_callback(void* context) { + furi_assert(context); + SubGhzViewReceiver* subghz_receiver = context; + with_view_model( + subghz_receiver->view, SubGhzViewReceiverModel * model, { model->scroll_counter++; }, true); +} + static void subghz_view_receiver_timer_callback(void* context) { furi_assert(context); SubGhzViewReceiver* subghz_receiver = context; @@ -412,6 +442,7 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) { SubGhzViewReceiverModel * model, { if(model->idx != 0) model->idx--; + model->scroll_counter = 0; }, true); } else if( @@ -423,6 +454,7 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) { { if((model->history_item != 0) && (model->idx != model->history_item - 1)) model->idx++; + model->scroll_counter = 0; }, true); } else if(event->key == InputKeyLeft && event->type == InputTypeShort) { @@ -442,6 +474,7 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) { if(it->index == (size_t)(model->idx)) { furi_string_free(item->item_str); + furi_string_free(item->time); item->type = 0; SubGhzReceiverMenuItemArray_remove(model->history->data, it); } @@ -475,6 +508,13 @@ bool subghz_view_receiver_input(InputEvent* event, void* context) { void subghz_view_receiver_enter(void* context) { furi_assert(context); + SubGhzViewReceiver* subghz_receiver = context; + with_view_model( + subghz_receiver->view, + SubGhzViewReceiverModel * model, + { model->scroll_counter = 0; }, + true); + furi_timer_start(subghz_receiver->scroll_timer, SCROLL_INTERVAL); } void subghz_view_receiver_exit(void* context) { @@ -491,6 +531,7 @@ void subghz_view_receiver_exit(void* context) { for M_EACH(item_menu, model->history->data, SubGhzReceiverMenuItemArray_t) { furi_string_free(item_menu->item_str); + furi_string_free(item_menu->time); item_menu->type = 0; } SubGhzReceiverMenuItemArray_reset(model->history->data); @@ -500,6 +541,7 @@ void subghz_view_receiver_exit(void* context) { }, false); furi_timer_stop(subghz_receiver->timer); + furi_timer_stop(subghz_receiver->scroll_timer); } SubGhzViewReceiver* subghz_view_receiver_alloc() { @@ -518,6 +560,9 @@ SubGhzViewReceiver* subghz_view_receiver_alloc() { view_set_enter_callback(subghz_receiver->view, subghz_view_receiver_enter); view_set_exit_callback(subghz_receiver->view, subghz_view_receiver_exit); + subghz_receiver->scroll_timer = furi_timer_alloc( + subghz_view_receiver_scroll_timer_callback, FuriTimerTypePeriodic, subghz_receiver); + with_view_model( subghz_receiver->view, SubGhzViewReceiverModel * model, @@ -539,6 +584,8 @@ SubGhzViewReceiver* subghz_view_receiver_alloc() { void subghz_view_receiver_free(SubGhzViewReceiver* subghz_receiver) { furi_assert(subghz_receiver); + furi_timer_free(subghz_receiver->scroll_timer); + with_view_model( subghz_receiver->view, SubGhzViewReceiverModel * model, @@ -550,6 +597,7 @@ void subghz_view_receiver_free(SubGhzViewReceiver* subghz_receiver) { for M_EACH(item_menu, model->history->data, SubGhzReceiverMenuItemArray_t) { furi_string_free(item_menu->item_str); + furi_string_free(item_menu->time); item_menu->type = 0; } SubGhzReceiverMenuItemArray_clear(model->history->data); diff --git a/applications/main/subghz/views/receiver.h b/applications/main/subghz/views/receiver.h index ad8c31eda..f5ec86b4b 100644 --- a/applications/main/subghz/views/receiver.h +++ b/applications/main/subghz/views/receiver.h @@ -40,6 +40,7 @@ void subghz_view_receiver_add_data_progress( void subghz_view_receiver_add_item_to_menu( SubGhzViewReceiver* subghz_receiver, const char* name, + const char* time, uint8_t type); uint16_t subghz_view_receiver_get_idx_menu(SubGhzViewReceiver* subghz_receiver); diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index f19310349..6bbb94a6a 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1373,6 +1373,7 @@ Function,+,furi_hal_subghz_get_lqi,uint8_t, Function,+,furi_hal_subghz_get_radio_type,SubGhzRadioType, Function,+,furi_hal_subghz_get_rolling_counter_mult,uint8_t, Function,+,furi_hal_subghz_get_rssi,float, +Function,+,furi_hal_subghz_get_timestamp_file_names,_Bool, Function,+,furi_hal_subghz_idle,void, Function,-,furi_hal_subghz_init,void, Function,+,furi_hal_subghz_init_check,_Bool, @@ -1395,6 +1396,7 @@ Function,+,furi_hal_subghz_set_frequency_and_path,uint32_t,uint32_t Function,+,furi_hal_subghz_set_path,void,FuriHalSubGhzPath Function,+,furi_hal_subghz_set_radio_type,_Bool,SubGhzRadioType Function,+,furi_hal_subghz_set_rolling_counter_mult,void,uint8_t +Function,+,furi_hal_subghz_set_timestamp_file_names,void,_Bool Function,-,furi_hal_subghz_shutdown,void, Function,+,furi_hal_subghz_sleep,void, Function,+,furi_hal_subghz_start_async_rx,void,"FuriHalSubGhzCaptureCallback, void*" diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.c b/firmware/targets/f7/furi_hal/furi_hal_subghz.c index ed9864ae9..1a4e39965 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.c +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.c @@ -40,6 +40,7 @@ volatile FuriHalSubGhz furi_hal_subghz = { .cc1101_g0_pin = &gpio_cc1101_g0, .rolling_counter_mult = 1, .ext_module_power_disabled = false, + .timestamp_file_names = false, }; bool furi_hal_subghz_set_radio_type(SubGhzRadioType state) { @@ -79,6 +80,14 @@ bool furi_hal_subghz_get_external_power_disable(void) { return furi_hal_subghz.ext_module_power_disabled; } +void furi_hal_subghz_set_timestamp_file_names(bool state) { + furi_hal_subghz.timestamp_file_names = state; +} + +bool furi_hal_subghz_get_timestamp_file_names(void) { + return furi_hal_subghz.timestamp_file_names; +} + void furi_hal_subghz_set_async_mirror_pin(const GpioPin* pin) { furi_hal_subghz.async_mirror_pin = pin; } diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.h b/firmware/targets/f7/furi_hal/furi_hal_subghz.h index ec886f693..b366e8578 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.h +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.h @@ -79,6 +79,7 @@ typedef struct { const GpioPin* cc1101_g0_pin; uint8_t rolling_counter_mult; bool ext_module_power_disabled; + bool timestamp_file_names; } FuriHalSubGhz; extern volatile FuriHalSubGhz furi_hal_subghz; @@ -330,6 +331,14 @@ void furi_hal_subghz_set_external_power_disable(bool state); */ bool furi_hal_subghz_get_external_power_disable(void); +/** If true - disable generation of random name and add timestamp to filenames instead + */ +void furi_hal_subghz_set_timestamp_file_names(bool state); + +/** Get the current state of the timestamp instead of random name flag + */ +bool furi_hal_subghz_get_timestamp_file_names(void); + #ifdef __cplusplus } #endif