From fed49ad256e2409a74356491a3ccd22f3228813e Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Tue, 27 Feb 2024 14:22:51 +0000 Subject: [PATCH] SubGhz: Ignore filters at driver level, better efficiency --- .../main/subghz/helpers/subghz_txrx.c | 7 + .../main/subghz/helpers/subghz_txrx.h | 10 + .../subghz/scenes/subghz_scene_receiver.c | 208 +++++++++--------- .../scenes/subghz_scene_receiver_config.c | 2 + applications/main/subghz/subghz.c | 1 + lib/subghz/receiver.c | 11 +- lib/subghz/receiver.h | 9 + targets/f7/api_symbols.csv | 1 + 8 files changed, 140 insertions(+), 109 deletions(-) diff --git a/applications/main/subghz/helpers/subghz_txrx.c b/applications/main/subghz/helpers/subghz_txrx.c index 99791d0eb..1eb98b0ef 100644 --- a/applications/main/subghz/helpers/subghz_txrx.c +++ b/applications/main/subghz/helpers/subghz_txrx.c @@ -569,6 +569,13 @@ void subghz_txrx_receiver_set_filter(SubGhzTxRx* instance, SubGhzProtocolFlag fi subghz_receiver_set_filter(instance->receiver, filter); } +void subghz_txrx_receiver_set_ignore_filter( + SubGhzTxRx* instance, + SubGhzProtocolFilter ignore_filter) { + furi_assert(instance); + subghz_receiver_set_ignore_filter(instance->receiver, ignore_filter); +} + void subghz_txrx_set_rx_callback( SubGhzTxRx* instance, SubGhzReceiverCallback callback, diff --git a/applications/main/subghz/helpers/subghz_txrx.h b/applications/main/subghz/helpers/subghz_txrx.h index fda684378..8c9ac00ac 100644 --- a/applications/main/subghz/helpers/subghz_txrx.h +++ b/applications/main/subghz/helpers/subghz_txrx.h @@ -283,6 +283,16 @@ bool subghz_txrx_protocol_is_transmittable(SubGhzTxRx* instance, bool check_type */ void subghz_txrx_receiver_set_filter(SubGhzTxRx* instance, SubGhzProtocolFlag filter); +/** + * Set ignore filter, what types of decoder to skip + * + * @param instance Pointer to a SubGhzTxRx + * @param ignore_filter Ignore filter + */ +void subghz_txrx_receiver_set_ignore_filter( + SubGhzTxRx* instance, + SubGhzProtocolFilter ignore_filter); + /** * Set callback for receive data * diff --git a/applications/main/subghz/scenes/subghz_scene_receiver.c b/applications/main/subghz/scenes/subghz_scene_receiver.c index 5fad0405b..83406594b 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver.c @@ -125,125 +125,116 @@ static void subghz_scene_add_to_history_callback( furi_assert(context); SubGhz* subghz = context; - // The check can be moved to /lib/subghz/receiver.c, but may result in false positives - if((decoder_base->protocol->filter & subghz->ignore_filter) == 0) { - SubGhzHistory* history = subghz->history; - FuriString* item_name = furi_string_alloc(); - FuriString* item_time = furi_string_alloc(); - uint16_t idx = subghz_history_get_item(history); + SubGhzHistory* history = subghz->history; + FuriString* item_name = furi_string_alloc(); + FuriString* item_time = furi_string_alloc(); + uint16_t idx = subghz_history_get_item(history); - SubGhzRadioPreset preset = subghz_txrx_get_preset(subghz->txrx); - preset.latitude = subghz->gps->latitude; - preset.longitude = subghz->gps->longitude; + SubGhzRadioPreset preset = subghz_txrx_get_preset(subghz->txrx); + preset.latitude = subghz->gps->latitude; + preset.longitude = subghz->gps->longitude; - if(subghz->last_settings->delete_old_signals && subghz_history_full(subghz->history)) { - subghz_view_receiver_disable_draw_callback(subghz->subghz_receiver); + if(subghz->last_settings->delete_old_signals && subghz_history_full(subghz->history)) { + subghz_view_receiver_disable_draw_callback(subghz->subghz_receiver); - while(idx > 0 && subghz_history_full(subghz->history)) { - subghz_history_delete_item(subghz->history, 0); - subghz_view_receiver_delete_item(subghz->subghz_receiver, 0); - idx--; - } - - subghz_view_receiver_enable_draw_callback(subghz->subghz_receiver); - if(idx == 0) { - subghz_rx_key_state_set(subghz, SubGhzRxKeyStateStart); - } - subghz_scene_receiver_update_statusbar(subghz); - subghz->idx_menu_chosen = subghz_view_receiver_get_idx_menu(subghz->subghz_receiver); + while(idx > 0 && subghz_history_full(subghz->history)) { + subghz_history_delete_item(subghz->history, 0); + subghz_view_receiver_delete_item(subghz->subghz_receiver, 0); + idx--; } - if(subghz_history_add_to_history(history, decoder_base, &preset)) { - furi_string_reset(item_name); - furi_string_reset(item_time); + subghz_view_receiver_enable_draw_callback(subghz->subghz_receiver); + if(idx == 0) { + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateStart); + } + subghz_scene_receiver_update_statusbar(subghz); + subghz->idx_menu_chosen = subghz_view_receiver_get_idx_menu(subghz->subghz_receiver); + } - //If the repeater is on, dont add to the menu, just TX the signal. - if(subghz->repeater != SubGhzRepeaterStateOff) { - view_dispatcher_send_custom_event( - subghz->view_dispatcher, SubGhzCustomEventViewRepeaterStart); + if(subghz_history_add_to_history(history, decoder_base, &preset)) { + furi_string_reset(item_name); + furi_string_reset(item_time); + + //If the repeater is on, dont add to the menu, just TX the signal. + if(subghz->repeater != SubGhzRepeaterStateOff) { + view_dispatcher_send_custom_event( + subghz->view_dispatcher, SubGhzCustomEventViewRepeaterStart); + } else { + subghz->state_notifications = SubGhzNotificationStateRxDone; + + if(subghz->remove_duplicates) { + // Look in history for signal hash + uint32_t hash_data = subghz_protocol_decoder_base_get_hash_data_long(decoder_base); + subghz_view_receiver_disable_draw_callback(subghz->subghz_receiver); + for(uint16_t i = idx; i > 0; i--) { + i--; // Iterating in reverse with off by one + if(subghz_history_get_hash_data(subghz->history, i) == hash_data && + subghz_history_get_protocol(subghz->history, i) == decoder_base->protocol) { + // Remove previous instance and update menu index + subghz_history_delete_item(subghz->history, i); + subghz_view_receiver_delete_item(subghz->subghz_receiver, i); + idx--; + } + i++; + } + // Restore ui state + subghz->idx_menu_chosen = + subghz_view_receiver_get_idx_menu(subghz->subghz_receiver); + subghz_view_receiver_enable_draw_callback(subghz->subghz_receiver); + if(idx == 0) { + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateStart); + } + } + + subghz_history_get_text_item_menu(history, item_name, idx); + subghz_history_get_time_item_menu(history, item_time, idx); + subghz_view_receiver_add_item_to_menu( + subghz->subghz_receiver, + furi_string_get_cstr(item_name), + furi_string_get_cstr(item_time), + subghz_history_get_type_protocol(history, idx), + subghz_history_get_repeats(history, idx)); + + if(decoder_base->protocol->flag & SubGhzProtocolFlag_Save && + subghz->last_settings->autosave) { + // File name + char file[SUBGHZ_MAX_LEN_NAME] = {0}; + const char* suf = subghz->last_settings->protocol_file_names ? + decoder_base->protocol->name : + SUBGHZ_APP_FILENAME_PREFIX; + DateTime time = subghz_history_get_datetime(history, idx); + name_generator_make_detailed_datetime(file, sizeof(file), suf, &time, true); + // Dir name + FuriString* path = furi_string_alloc_set(SUBGHZ_APP_FOLDER "/Autosave"); + char* dir = strdup(furi_string_get_cstr(path)); + // Find non-existent path + const char* ext = SUBGHZ_APP_FILENAME_EXTENSION; + Storage* storage = furi_record_open(RECORD_STORAGE); + storage_get_next_filename(storage, dir, file, ext, path, sizeof(file)); + strlcpy(file, furi_string_get_cstr(path), sizeof(file)); + furi_string_printf(path, "%s/%s%s", dir, file, ext); + furi_record_close(RECORD_STORAGE); + free(dir); + // Save + subghz_save_protocol_to_file( + subghz, subghz_history_get_raw_data(history, idx), furi_string_get_cstr(path)); + furi_string_free(path); + } + + subghz_scene_receiver_update_statusbar(subghz); + if(!subghz->last_settings->delete_old_signals && + subghz_history_full(subghz->history)) { + subghz->state_notifications = SubGhzNotificationStateIDLE; + notification_message(subghz->notifications, &sequence_error); } else { subghz->state_notifications = SubGhzNotificationStateRxDone; - - if(subghz->remove_duplicates) { - // Look in history for signal hash - uint32_t hash_data = - subghz_protocol_decoder_base_get_hash_data_long(decoder_base); - subghz_view_receiver_disable_draw_callback(subghz->subghz_receiver); - for(uint16_t i = idx; i > 0; i--) { - i--; // Iterating in reverse with off by one - if(subghz_history_get_hash_data(subghz->history, i) == hash_data && - subghz_history_get_protocol(subghz->history, i) == - decoder_base->protocol) { - // Remove previous instance and update menu index - subghz_history_delete_item(subghz->history, i); - subghz_view_receiver_delete_item(subghz->subghz_receiver, i); - idx--; - } - i++; - } - // Restore ui state - subghz->idx_menu_chosen = - subghz_view_receiver_get_idx_menu(subghz->subghz_receiver); - subghz_view_receiver_enable_draw_callback(subghz->subghz_receiver); - if(idx == 0) { - subghz_rx_key_state_set(subghz, SubGhzRxKeyStateStart); - } - } - - subghz_history_get_text_item_menu(history, item_name, idx); - subghz_history_get_time_item_menu(history, item_time, idx); - subghz_view_receiver_add_item_to_menu( - subghz->subghz_receiver, - furi_string_get_cstr(item_name), - furi_string_get_cstr(item_time), - subghz_history_get_type_protocol(history, idx), - subghz_history_get_repeats(history, idx)); - - if(decoder_base->protocol->flag & SubGhzProtocolFlag_Save && - subghz->last_settings->autosave) { - // File name - char file[SUBGHZ_MAX_LEN_NAME] = {0}; - const char* suf = subghz->last_settings->protocol_file_names ? - decoder_base->protocol->name : - SUBGHZ_APP_FILENAME_PREFIX; - DateTime time = subghz_history_get_datetime(history, idx); - name_generator_make_detailed_datetime(file, sizeof(file), suf, &time, true); - // Dir name - FuriString* path = furi_string_alloc_set(SUBGHZ_APP_FOLDER "/Autosave"); - char* dir = strdup(furi_string_get_cstr(path)); - // Find non-existent path - const char* ext = SUBGHZ_APP_FILENAME_EXTENSION; - Storage* storage = furi_record_open(RECORD_STORAGE); - storage_get_next_filename(storage, dir, file, ext, path, sizeof(file)); - strlcpy(file, furi_string_get_cstr(path), sizeof(file)); - furi_string_printf(path, "%s/%s%s", dir, file, ext); - furi_record_close(RECORD_STORAGE); - free(dir); - // Save - subghz_save_protocol_to_file( - subghz, - subghz_history_get_raw_data(history, idx), - furi_string_get_cstr(path)); - furi_string_free(path); - } - - subghz_scene_receiver_update_statusbar(subghz); - if(!subghz->last_settings->delete_old_signals && - subghz_history_full(subghz->history)) { - subghz->state_notifications = SubGhzNotificationStateIDLE; - notification_message(subghz->notifications, &sequence_error); - } else { - subghz->state_notifications = SubGhzNotificationStateRxDone; - } } } - subghz_receiver_reset(receiver); - furi_string_free(item_name); - furi_string_free(item_time); - subghz_rx_key_state_set(subghz, SubGhzRxKeyStateAddKey); - } else { - FURI_LOG_D(TAG, "%s protocol ignored", decoder_base->protocol->name); } + subghz_receiver_reset(receiver); + furi_string_free(item_name); + furi_string_free(item_time); + subghz_rx_key_state_set(subghz, SubGhzRxKeyStateAddKey); } void subghz_scene_receiver_on_enter(void* context) { @@ -264,6 +255,7 @@ void subghz_scene_receiver_on_enter(void* context) { subghz->filter = subghz->last_settings->filter; subghz_txrx_receiver_set_filter(subghz->txrx, subghz->filter); subghz->ignore_filter = subghz->last_settings->ignore_filter; + subghz_txrx_receiver_set_ignore_filter(subghz->txrx, subghz->ignore_filter); subghz_history_reset(history); subghz_rx_key_state_set(subghz, SubGhzRxKeyStateStart); diff --git a/applications/main/subghz/scenes/subghz_scene_receiver_config.c b/applications/main/subghz/scenes/subghz_scene_receiver_config.c index ae3741e53..5d02cb387 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver_config.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver_config.c @@ -106,6 +106,7 @@ static void subghz_scene_receiver_config_set_ignore_filter( } subghz->last_settings->ignore_filter = subghz->ignore_filter; + subghz_txrx_receiver_set_ignore_filter(subghz->txrx, subghz->ignore_filter); } uint8_t subghz_scene_receiver_config_next_frequency(const uint32_t value, void* context) { @@ -431,6 +432,7 @@ static void subghz_scene_receiver_config_var_list_enter_callback(void* context, subghz->ignore_filter = 0x00; subghz->remove_duplicates = false; subghz_txrx_receiver_set_filter(subghz->txrx, subghz->filter); + subghz_txrx_receiver_set_ignore_filter(subghz->txrx, subghz->ignore_filter); subghz->last_settings->remove_duplicates = subghz->remove_duplicates; subghz->last_settings->ignore_filter = subghz->ignore_filter; subghz->last_settings->filter = subghz->filter; diff --git a/applications/main/subghz/subghz.c b/applications/main/subghz/subghz.c index 8998b5645..c743f90d6 100644 --- a/applications/main/subghz/subghz.c +++ b/applications/main/subghz/subghz.c @@ -234,6 +234,7 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) { subghz->remove_duplicates = false; } subghz_txrx_receiver_set_filter(subghz->txrx, subghz->filter); + subghz_txrx_receiver_set_ignore_filter(subghz->txrx, subghz->ignore_filter); subghz_txrx_set_need_save_callback(subghz->txrx, subghz_save_to_file, subghz); if(!alloc_for_tx_only) { diff --git a/lib/subghz/receiver.c b/lib/subghz/receiver.c index 698fe098e..bc89a3812 100644 --- a/lib/subghz/receiver.c +++ b/lib/subghz/receiver.c @@ -15,6 +15,7 @@ ARRAY_DEF(SubGhzReceiverSlotArray, SubGhzReceiverSlot, M_POD_OPLIST); struct SubGhzReceiver { SubGhzReceiverSlotArray_t slots; SubGhzProtocolFlag filter; + SubGhzProtocolFilter ignore_filter; SubGhzReceiverCallback callback; void* context; @@ -64,7 +65,8 @@ void subghz_receiver_decode(SubGhzReceiver* instance, bool level, uint32_t durat for M_EACH(slot, instance->slots, SubGhzReceiverSlotArray_t) { - if((slot->base->protocol->flag & instance->filter) != 0) { + if((slot->base->protocol->flag & instance->filter) != 0 && + (slot->base->protocol->filter & instance->ignore_filter) == 0) { slot->base->protocol->decoder->feed(slot->base, level, duration); } } @@ -108,6 +110,13 @@ void subghz_receiver_set_filter(SubGhzReceiver* instance, SubGhzProtocolFlag fil instance->filter = filter; } +void subghz_receiver_set_ignore_filter( + SubGhzReceiver* instance, + SubGhzProtocolFilter ignore_filter) { + furi_assert(instance); + instance->ignore_filter = ignore_filter; +} + SubGhzProtocolDecoderBase* subghz_receiver_search_decoder_base_by_name( SubGhzReceiver* instance, const char* decoder_name) { diff --git a/lib/subghz/receiver.h b/lib/subghz/receiver.h index 2ef722d1f..9f84fa761 100644 --- a/lib/subghz/receiver.h +++ b/lib/subghz/receiver.h @@ -59,6 +59,15 @@ void subghz_receiver_set_rx_callback( */ void subghz_receiver_set_filter(SubGhzReceiver* instance, SubGhzProtocolFlag filter); +/** + * Set the filter of receivers that will be ignored at the moment. + * @param instance Pointer to a SubGhzReceiver instance + * @param ignore_filter Ignore filter, SubGhzProtocolFilter + */ +void subghz_receiver_set_ignore_filter( + SubGhzReceiver* instance, + SubGhzProtocolFilter ignore_filter); + /** * Search for a cattery by his name. * @param instance Pointer to a SubGhzReceiver instance diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index 21acb0fdc..f51e6fd22 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -3421,6 +3421,7 @@ Function,+,subghz_receiver_free,void,SubGhzReceiver* Function,+,subghz_receiver_reset,void,SubGhzReceiver* Function,+,subghz_receiver_search_decoder_base_by_name,SubGhzProtocolDecoderBase*,"SubGhzReceiver*, const char*" Function,+,subghz_receiver_set_filter,void,"SubGhzReceiver*, SubGhzProtocolFlag" +Function,+,subghz_receiver_set_ignore_filter,void,"SubGhzReceiver*, SubGhzProtocolFilter" Function,+,subghz_receiver_set_rx_callback,void,"SubGhzReceiver*, SubGhzReceiverCallback, void*" Function,+,subghz_setting_alloc,SubGhzSetting*, Function,+,subghz_setting_customs_presets_to_log,uint8_t,SubGhzSetting*