mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2025-10-04 11:07:02 +02:00
SubGhz: Ignore filters at driver level, better efficiency
This commit is contained in:
@@ -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,
|
||||||
|
@@ -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
|
||||||
*
|
*
|
||||||
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
|
@@ -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) {
|
||||||
|
@@ -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) {
|
||||||
|
@@ -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
|
||||||
|
@@ -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*
|
||||||
|
|
Reference in New Issue
Block a user