SubGhz: Ignore filters at driver level, better efficiency

This commit is contained in:
Willy-JL
2024-02-27 14:22:51 +00:00
parent a99959a9f9
commit fed49ad256
8 changed files with 140 additions and 109 deletions

View File

@@ -569,6 +569,13 @@ void subghz_txrx_receiver_set_filter(SubGhzTxRx* instance, SubGhzProtocolFlag fi
subghz_receiver_set_filter(instance->receiver, filter); 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( void subghz_txrx_set_rx_callback(
SubGhzTxRx* instance, SubGhzTxRx* instance,
SubGhzReceiverCallback callback, SubGhzReceiverCallback callback,

View File

@@ -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); 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 * Set callback for receive data
* *

View File

@@ -125,125 +125,116 @@ static void subghz_scene_add_to_history_callback(
furi_assert(context); furi_assert(context);
SubGhz* subghz = context; SubGhz* subghz = context;
// The check can be moved to /lib/subghz/receiver.c, but may result in false positives SubGhzHistory* history = subghz->history;
if((decoder_base->protocol->filter & subghz->ignore_filter) == 0) { FuriString* item_name = furi_string_alloc();
SubGhzHistory* history = subghz->history; FuriString* item_time = furi_string_alloc();
FuriString* item_name = furi_string_alloc(); uint16_t idx = subghz_history_get_item(history);
FuriString* item_time = furi_string_alloc();
uint16_t idx = subghz_history_get_item(history);
SubGhzRadioPreset preset = subghz_txrx_get_preset(subghz->txrx); SubGhzRadioPreset preset = subghz_txrx_get_preset(subghz->txrx);
preset.latitude = subghz->gps->latitude; preset.latitude = subghz->gps->latitude;
preset.longitude = subghz->gps->longitude; preset.longitude = subghz->gps->longitude;
if(subghz->last_settings->delete_old_signals && subghz_history_full(subghz->history)) { if(subghz->last_settings->delete_old_signals && subghz_history_full(subghz->history)) {
subghz_view_receiver_disable_draw_callback(subghz->subghz_receiver); subghz_view_receiver_disable_draw_callback(subghz->subghz_receiver);
while(idx > 0 && subghz_history_full(subghz->history)) { while(idx > 0 && subghz_history_full(subghz->history)) {
subghz_history_delete_item(subghz->history, 0); subghz_history_delete_item(subghz->history, 0);
subghz_view_receiver_delete_item(subghz->subghz_receiver, 0); subghz_view_receiver_delete_item(subghz->subghz_receiver, 0);
idx--; 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);
} }
if(subghz_history_add_to_history(history, decoder_base, &preset)) { subghz_view_receiver_enable_draw_callback(subghz->subghz_receiver);
furi_string_reset(item_name); if(idx == 0) {
furi_string_reset(item_time); 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_history_add_to_history(history, decoder_base, &preset)) {
if(subghz->repeater != SubGhzRepeaterStateOff) { furi_string_reset(item_name);
view_dispatcher_send_custom_event( furi_string_reset(item_time);
subghz->view_dispatcher, SubGhzCustomEventViewRepeaterStart);
//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 { } else {
subghz->state_notifications = SubGhzNotificationStateRxDone; 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) { 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->filter = subghz->last_settings->filter;
subghz_txrx_receiver_set_filter(subghz->txrx, subghz->filter); subghz_txrx_receiver_set_filter(subghz->txrx, subghz->filter);
subghz->ignore_filter = subghz->last_settings->ignore_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_history_reset(history);
subghz_rx_key_state_set(subghz, SubGhzRxKeyStateStart); subghz_rx_key_state_set(subghz, SubGhzRxKeyStateStart);

View File

@@ -106,6 +106,7 @@ static void subghz_scene_receiver_config_set_ignore_filter(
} }
subghz->last_settings->ignore_filter = subghz->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) { 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->ignore_filter = 0x00;
subghz->remove_duplicates = false; subghz->remove_duplicates = false;
subghz_txrx_receiver_set_filter(subghz->txrx, subghz->filter); 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->remove_duplicates = subghz->remove_duplicates;
subghz->last_settings->ignore_filter = subghz->ignore_filter; subghz->last_settings->ignore_filter = subghz->ignore_filter;
subghz->last_settings->filter = subghz->filter; subghz->last_settings->filter = subghz->filter;

View File

@@ -234,6 +234,7 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) {
subghz->remove_duplicates = false; subghz->remove_duplicates = false;
} }
subghz_txrx_receiver_set_filter(subghz->txrx, subghz->filter); 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); subghz_txrx_set_need_save_callback(subghz->txrx, subghz_save_to_file, subghz);
if(!alloc_for_tx_only) { if(!alloc_for_tx_only) {

View File

@@ -15,6 +15,7 @@ ARRAY_DEF(SubGhzReceiverSlotArray, SubGhzReceiverSlot, M_POD_OPLIST);
struct SubGhzReceiver { struct SubGhzReceiver {
SubGhzReceiverSlotArray_t slots; SubGhzReceiverSlotArray_t slots;
SubGhzProtocolFlag filter; SubGhzProtocolFlag filter;
SubGhzProtocolFilter ignore_filter;
SubGhzReceiverCallback callback; SubGhzReceiverCallback callback;
void* context; void* context;
@@ -64,7 +65,8 @@ void subghz_receiver_decode(SubGhzReceiver* instance, bool level, uint32_t durat
for for
M_EACH(slot, instance->slots, SubGhzReceiverSlotArray_t) { 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); 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; 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( SubGhzProtocolDecoderBase* subghz_receiver_search_decoder_base_by_name(
SubGhzReceiver* instance, SubGhzReceiver* instance,
const char* decoder_name) { const char* decoder_name) {

View File

@@ -59,6 +59,15 @@ void subghz_receiver_set_rx_callback(
*/ */
void subghz_receiver_set_filter(SubGhzReceiver* instance, SubGhzProtocolFlag filter); 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. * Search for a cattery by his name.
* @param instance Pointer to a SubGhzReceiver instance * @param instance Pointer to a SubGhzReceiver instance

View File

@@ -3421,6 +3421,7 @@ Function,+,subghz_receiver_free,void,SubGhzReceiver*
Function,+,subghz_receiver_reset,void,SubGhzReceiver* Function,+,subghz_receiver_reset,void,SubGhzReceiver*
Function,+,subghz_receiver_search_decoder_base_by_name,SubGhzProtocolDecoderBase*,"SubGhzReceiver*, const char*" Function,+,subghz_receiver_search_decoder_base_by_name,SubGhzProtocolDecoderBase*,"SubGhzReceiver*, const char*"
Function,+,subghz_receiver_set_filter,void,"SubGhzReceiver*, SubGhzProtocolFlag" 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_receiver_set_rx_callback,void,"SubGhzReceiver*, SubGhzReceiverCallback, void*"
Function,+,subghz_setting_alloc,SubGhzSetting*, Function,+,subghz_setting_alloc,SubGhzSetting*,
Function,+,subghz_setting_customs_presets_to_log,uint8_t,SubGhzSetting* Function,+,subghz_setting_customs_presets_to_log,uint8_t,SubGhzSetting*
1 entry status name type params
3421 Function + subghz_receiver_reset void SubGhzReceiver*
3422 Function + subghz_receiver_search_decoder_base_by_name SubGhzProtocolDecoderBase* SubGhzReceiver*, const char*
3423 Function + subghz_receiver_set_filter void SubGhzReceiver*, SubGhzProtocolFlag
3424 Function + subghz_receiver_set_ignore_filter void SubGhzReceiver*, SubGhzProtocolFilter
3425 Function + subghz_receiver_set_rx_callback void SubGhzReceiver*, SubGhzReceiverCallback, void*
3426 Function + subghz_setting_alloc SubGhzSetting*
3427 Function + subghz_setting_customs_presets_to_log uint8_t SubGhzSetting*