Detect RAW feature

by perspecdev
This commit is contained in:
MX 2022-09-14 16:01:30 +03:00
parent ee6b59ab9d
commit b00117e02c
No known key found for this signature in database
GPG key ID: 6C4C311DFD4B4AB5
10 changed files with 388 additions and 14 deletions

View file

@ -99,6 +99,9 @@ void subghz_scene_read_raw_on_enter(void* context) {
subghz->txrx->receiver, SUBGHZ_PROTOCOL_RAW_NAME);
furi_assert(subghz->txrx->decoder_result);
// make sure we're not in auto-detect mode, which is only meant for the Read app
subghz_protocol_decoder_raw_set_auto_mode(subghz->txrx->decoder_result, false);
//set filter RAW feed
subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_RAW);
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdReadRAW);

View file

@ -1,9 +1,13 @@
#include "../subghz_i.h"
#include <lib/subghz/protocols/raw.h>
enum SubGhzSettingIndex {
SubGhzSettingIndexFrequency,
SubGhzSettingIndexHopping,
SubGhzSettingIndexModulation,
SubGhzSettingIndexDetectRaw,
SubGhzSettingIndexRSSIThreshold,
SubGhzSettingIndexLock,
};
@ -17,6 +21,38 @@ const uint32_t hopping_value[HOPPING_COUNT] = {
SubGhzHopperStateRunnig,
};
#define DETECT_RAW_COUNT 2
const char* const detect_raw_text[DETECT_RAW_COUNT] = {
"OFF",
"ON",
};
const SubGhzProtocolFlag detect_raw_value[DETECT_RAW_COUNT] = {
SubGhzProtocolFlag_Decodable,
SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_RAW,
};
#define RSSI_THRESHOLD_COUNT 7
const char* const rssi_threshold_text[RSSI_THRESHOLD_COUNT] = {
"-72db",
"-67db",
"-62db",
"-57db",
"-52db",
"-47db",
"-42db",
};
const int rssi_threshold_value[RSSI_THRESHOLD_COUNT] = {
-72,
-67,
-62,
-57,
-52,
-47,
-42,
};
uint8_t subghz_scene_receiver_config_next_frequency(const uint32_t value, void* context) {
furi_assert(context);
SubGhz* subghz = context;
@ -67,6 +103,34 @@ uint8_t subghz_scene_receiver_config_hopper_value_index(
}
}
uint8_t subghz_scene_receiver_config_detect_raw_value_index(
const SubGhzProtocolFlag value,
const SubGhzProtocolFlag values[],
uint8_t values_count) {
uint8_t index = 0;
for(uint8_t i = 0; i < values_count; i++) {
if(value == values[i]) {
index = i;
break;
}
}
return index;
}
uint8_t subghz_scene_receiver_config_rssi_threshold_value_index(
const int value,
const int values[],
uint8_t values_count) {
uint8_t index = 0;
for(uint8_t i = 0; i < values_count; i++) {
if(value == values[i]) {
index = i;
break;
}
}
return index;
}
static void subghz_scene_receiver_config_set_frequency(VariableItem* item) {
SubGhz* subghz = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item);
@ -100,6 +164,30 @@ static void subghz_scene_receiver_config_set_preset(VariableItem* item) {
subghz_setting_get_preset_data_size(subghz->setting, index));
}
static void subghz_scene_receiver_config_set_rssi_threshold(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, rssi_threshold_text[index]);
subghz_protocol_decoder_raw_set_rssi_threshold(
subghz_receiver_search_decoder_base_by_name(
subghz->txrx->receiver, SUBGHZ_PROTOCOL_RAW_NAME),
rssi_threshold_value[index]);
}
static void subghz_scene_receiver_config_set_detect_raw(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, detect_raw_text[index]);
subghz_receiver_set_filter(subghz->txrx->receiver, detect_raw_value[index]);
subghz_protocol_decoder_raw_set_auto_mode(
subghz_receiver_search_decoder_base_by_name(
subghz->txrx->receiver, SUBGHZ_PROTOCOL_RAW_NAME),
(index == 1));
}
static void subghz_scene_receiver_config_set_hopping_running(VariableItem* item) {
SubGhz* subghz = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item);
@ -196,6 +284,39 @@ void subghz_scene_receiver_config_on_enter(void* context) {
variable_item_set_current_value_text(
item, subghz_setting_get_preset_name(subghz->setting, value_index));
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) !=
SubGhzCustomEventManagerSet) {
item = variable_item_list_add(
subghz->variable_item_list,
"Detect Raw:",
DETECT_RAW_COUNT,
subghz_scene_receiver_config_set_detect_raw,
subghz);
value_index = subghz_scene_receiver_config_detect_raw_value_index(
subghz_receiver_get_filter(subghz->txrx->receiver),
detect_raw_value,
DETECT_RAW_COUNT);
variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, detect_raw_text[value_index]);
}
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) !=
SubGhzCustomEventManagerSet) {
item = variable_item_list_add(
subghz->variable_item_list,
"RSSI for Raw:",
RSSI_THRESHOLD_COUNT,
subghz_scene_receiver_config_set_rssi_threshold,
subghz);
value_index = subghz_scene_receiver_config_rssi_threshold_value_index(
subghz_protocol_encoder_get_rssi_threshold(subghz_receiver_search_decoder_base_by_name(
subghz->txrx->receiver, SUBGHZ_PROTOCOL_RAW_NAME)),
rssi_threshold_value,
RSSI_THRESHOLD_COUNT);
variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, rssi_threshold_text[value_index]);
}
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) !=
SubGhzCustomEventManagerSet) {
variable_item_list_add(subghz->variable_item_list, "Lock Keyboard", 1, NULL, NULL);
@ -204,6 +325,7 @@ void subghz_scene_receiver_config_on_enter(void* context) {
subghz_scene_receiver_config_var_list_enter_callback,
subghz);
}
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdVariableItemList);
}

View file

@ -92,6 +92,8 @@ void subghz_scene_receiver_info_draw_widget(SubGhz* subghz) {
// Removed static check
if(((subghz->txrx->decoder_result->protocol->flag & SubGhzProtocolFlag_Send) ==
SubGhzProtocolFlag_Send) &&
// disable "Send" for auto-captured RAW signals for now. They can still be saved and sent by loading them.
subghz->txrx->decoder_result->protocol->type != SubGhzProtocolTypeRAW &&
subghz->txrx->decoder_result->protocol->encoder->deserialize) {
widget_add_button_element(
subghz->widget,

View file

@ -180,7 +180,19 @@ bool subghz_history_add_to_history(
FURI_LOG_E(TAG, "Missing Protocol");
break;
}
if(!strcmp(string_get_cstr(instance->tmp_string), "KeeLoq")) {
if(!strcmp(string_get_cstr(instance->tmp_string), "RAW")) {
string_printf(
item->item_str,
"RAW %03ld.%02ld",
preset->frequency / 1000000 % 1000,
preset->frequency / 10000 % 100);
if(!flipper_format_rewind(item->flipper_string)) {
FURI_LOG_E(TAG, "Rewind error");
}
break;
} else if(!strcmp(string_get_cstr(instance->tmp_string), "KeeLoq")) {
string_set_str(instance->tmp_string, "KL ");
if(!flipper_format_read_string(item->flipper_string, "Manufacture", text)) {
FURI_LOG_E(TAG, "Missing Protocol");

View file

@ -33,6 +33,7 @@ static const Icon* ReceiverItemIcons[] = {
[SubGhzProtocolTypeUnknown] = &I_Quest_7x8,
[SubGhzProtocolTypeStatic] = &I_Unlock_7x8,
[SubGhzProtocolTypeDynamic] = &I_Lock_7x8,
[SubGhzProtocolTypeRAW] = &I_Unlock_7x8,
};
typedef enum {
@ -234,7 +235,6 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) {
canvas_draw_line(canvas, 46, 51, 125, 51);
canvas_set_font(canvas, FontSecondary);
} else {
//canvas_draw_icon(canvas, 0, 0, &I_Decoding_123x52);
canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52);
canvas_set_font(canvas, FontPrimary);
canvas_draw_str(canvas, 63, 46, "Decoding...");

View file

@ -8,11 +8,16 @@
#include "../blocks/generic.h"
#include "../blocks/math.h"
#include <furi.h>
#include <flipper_format/flipper_format_i.h>
#include <lib/toolbox/stream/stream.h>
#include <stm32wbxx_ll_rtc.h>
#define TAG "SubGhzProtocolRAW"
#define SUBGHZ_DOWNLOAD_MAX_SIZE 512
#define SUBGHZ_AUTO_DETECT_DOWNLOAD_MAX_SIZE 2048
#define SUBGHZ_AUTO_DETECT_RAW_THRESHOLD -72.0f
#define SUBGHZ_AUTO_DETECT_RAW_POSTROLL_FRAMES 30
static const SubGhzBlockConst subghz_protocol_raw_const = {
.te_short = 50,
@ -24,6 +29,8 @@ static const SubGhzBlockConst subghz_protocol_raw_const = {
struct SubGhzProtocolDecoderRAW {
SubGhzProtocolDecoderBase base;
SubGhzBlockDecoder decoder;
int32_t* upload_raw;
uint16_t ind_write;
Storage* storage;
@ -32,6 +39,10 @@ struct SubGhzProtocolDecoderRAW {
string_t file_name;
size_t sample_write;
bool last_level;
bool auto_mode;
bool has_rssi_above_threshold;
int rssi_threshold;
uint8_t postroll_frames;
};
struct SubGhzProtocolEncoderRAW {
@ -55,8 +66,8 @@ const SubGhzProtocolDecoder subghz_protocol_raw_decoder = {
.feed = subghz_protocol_decoder_raw_feed,
.reset = subghz_protocol_decoder_raw_reset,
.get_hash_data = NULL,
.serialize = NULL,
.get_hash_data = subghz_protocol_decoder_raw_get_hash_data,
.serialize = subghz_protocol_decoder_raw_serialize,
.deserialize = subghz_protocol_decoder_raw_deserialize,
.get_string = subghz_protocol_decoder_raw_get_string,
};
@ -198,6 +209,36 @@ void subghz_protocol_raw_save_to_file_stop(SubGhzProtocolDecoderRAW* instance) {
instance->file_is_open = RAWFileIsOpenClose;
}
void subghz_protocol_decoder_raw_set_rssi_threshold(void* context, int rssi_threshold) {
furi_assert(context);
SubGhzProtocolDecoderRAW* instance = context;
FURI_LOG_D(TAG, "RSSI set: (%d)", rssi_threshold);
instance->rssi_threshold = rssi_threshold;
subghz_protocol_decoder_raw_reset(context);
}
void subghz_protocol_decoder_raw_set_auto_mode(void* context, bool auto_mode) {
furi_assert(context);
SubGhzProtocolDecoderRAW* instance = context;
instance->auto_mode = auto_mode;
if(auto_mode) {
if(instance->upload_raw == NULL) {
instance->upload_raw = malloc(SUBGHZ_AUTO_DETECT_DOWNLOAD_MAX_SIZE * sizeof(int32_t));
}
} else {
if(instance->upload_raw != NULL) {
free(instance->upload_raw);
instance->upload_raw = NULL;
}
}
subghz_protocol_decoder_raw_reset(context);
}
size_t subghz_protocol_raw_get_sample_write(SubGhzProtocolDecoderRAW* instance) {
return instance->sample_write + instance->ind_write;
}
@ -210,6 +251,8 @@ void* subghz_protocol_decoder_raw_alloc(SubGhzEnvironment* environment) {
instance->ind_write = 0;
instance->last_level = false;
instance->file_is_open = RAWFileIsOpenClose;
instance->postroll_frames = 0;
instance->rssi_threshold = SUBGHZ_AUTO_DETECT_RAW_THRESHOLD;
string_init(instance->file_name);
return instance;
@ -219,6 +262,10 @@ void subghz_protocol_decoder_raw_free(void* context) {
furi_assert(context);
SubGhzProtocolDecoderRAW* instance = context;
string_clear(instance->file_name);
if(instance->upload_raw != NULL) {
free(instance->upload_raw);
instance->upload_raw = NULL;
}
free(instance);
}
@ -226,23 +273,65 @@ void subghz_protocol_decoder_raw_reset(void* context) {
furi_assert(context);
SubGhzProtocolDecoderRAW* instance = context;
instance->ind_write = 0;
instance->has_rssi_above_threshold = false;
instance->last_level = false;
instance->postroll_frames = 0;
}
bool subghz_protocol_decoder_raw_write_data(void* context, bool level, uint32_t duration) {
furi_assert(context);
SubGhzProtocolDecoderRAW* instance = context;
bool wrote_data = false;
if(instance->last_level != level) {
instance->last_level = (level ? true : false);
instance->upload_raw[instance->ind_write++] = (level ? duration : -duration);
subghz_protocol_blocks_add_bit(&instance->decoder, (level) ? 1 : 0);
wrote_data = true;
}
if(instance->ind_write == SUBGHZ_AUTO_DETECT_DOWNLOAD_MAX_SIZE) {
if(instance->base.callback)
instance->base.callback(&instance->base, instance->base.context);
return false;
}
return wrote_data;
}
void subghz_protocol_decoder_raw_feed(void* context, bool level, uint32_t duration) {
furi_assert(context);
SubGhzProtocolDecoderRAW* instance = context;
if(instance->upload_raw != NULL) {
if(duration > subghz_protocol_raw_const.te_short) {
if(instance->upload_raw != NULL && duration > subghz_protocol_raw_const.te_short) {
if(instance->auto_mode) {
float rssi = furi_hal_subghz_get_rssi();
if(rssi >= instance->rssi_threshold) {
subghz_protocol_decoder_raw_write_data(context, level, duration);
instance->has_rssi_above_threshold = true;
instance->postroll_frames = 0;
} else if(instance->has_rssi_above_threshold) {
subghz_protocol_decoder_raw_write_data(instance, level, duration);
instance->postroll_frames++;
if(instance->postroll_frames >= SUBGHZ_AUTO_DETECT_RAW_POSTROLL_FRAMES) {
if(instance->base.callback)
instance->base.callback(&instance->base, instance->base.context);
}
}
} else {
if(instance->last_level != level) {
instance->last_level = (level ? true : false);
instance->upload_raw[instance->ind_write++] = (level ? duration : -duration);
subghz_protocol_blocks_add_bit(&instance->decoder, (level) ? 1 : 0);
}
}
if(instance->ind_write == SUBGHZ_DOWNLOAD_MAX_SIZE) {
subghz_protocol_raw_save_to_file_write(instance);
if(instance->ind_write == SUBGHZ_DOWNLOAD_MAX_SIZE) {
subghz_protocol_raw_save_to_file_write(instance);
}
}
}
}
@ -255,12 +344,19 @@ bool subghz_protocol_decoder_raw_deserialize(void* context, FlipperFormat* flipp
return true;
}
uint8_t subghz_protocol_decoder_raw_get_hash_data(void* context) {
furi_assert(context);
SubGhzProtocolDecoderRAW* instance = context;
return subghz_protocol_blocks_get_hash_data(
&instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
}
void subghz_protocol_decoder_raw_get_string(void* context, string_t output) {
furi_assert(context);
//SubGhzProtocolDecoderRAW* instance = context;
UNUSED(context);
//ToDo no use
string_cat_printf(output, "RAW Date");
string_cat_printf(output, "RAW Data");
}
void* subghz_protocol_encoder_raw_alloc(SubGhzEnvironment* environment) {
@ -273,6 +369,13 @@ void* subghz_protocol_encoder_raw_alloc(SubGhzEnvironment* environment) {
return instance;
}
int subghz_protocol_encoder_get_rssi_threshold(void* context) {
furi_assert(context);
SubGhzProtocolDecoderRAW* instance = context;
return instance->rssi_threshold;
}
void subghz_protocol_encoder_raw_stop(void* context) {
SubGhzProtocolEncoderRAW* instance = context;
instance->is_running = false;
@ -330,6 +433,70 @@ void subghz_protocol_raw_gen_fff_data(FlipperFormat* flipper_format, const char*
} while(false);
}
bool subghz_protocol_decoder_raw_serialize(
void* context,
FlipperFormat* flipper_format,
SubGhzPresetDefinition* preset) {
furi_assert(context);
SubGhzProtocolDecoderRAW* instance = context;
if(instance->auto_mode) {
furi_assert(instance);
bool res = false;
string_t temp_str;
string_init(temp_str);
do {
stream_clean(flipper_format_get_raw_stream(flipper_format));
if(!flipper_format_write_header_cstr(
flipper_format, SUBGHZ_RAW_FILE_TYPE, SUBGHZ_RAW_FILE_VERSION)) {
FURI_LOG_E(TAG, "Unable to add header");
break;
}
if(!flipper_format_write_uint32(flipper_format, "Frequency", &preset->frequency, 1)) {
FURI_LOG_E(TAG, "Unable to add Frequency");
break;
}
subghz_block_generic_get_preset_name(string_get_cstr(preset->name), temp_str);
if(!flipper_format_write_string_cstr(
flipper_format, "Preset", string_get_cstr(temp_str))) {
FURI_LOG_E(TAG, "Unable to add Preset");
break;
}
if(!strcmp(string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) {
if(!flipper_format_write_string_cstr(
flipper_format, "Custom_preset_module", "CC1101")) {
FURI_LOG_E(TAG, "Unable to add Custom_preset_module");
break;
}
if(!flipper_format_write_hex(
flipper_format, "Custom_preset_data", preset->data, preset->data_size)) {
FURI_LOG_E(TAG, "Unable to add Custom_preset_data");
break;
}
}
if(!flipper_format_write_string_cstr(
flipper_format, "Protocol", instance->base.protocol->name)) {
FURI_LOG_E(TAG, "Unable to add Protocol");
break;
}
if(!flipper_format_write_int32(
flipper_format, "RAW_Data", instance->upload_raw, instance->ind_write)) {
FURI_LOG_E(TAG, "Unable to add Raw Data");
break;
} else {
instance->ind_write = 0;
}
res = true;
} while(false);
string_clear(temp_str);
return res;
} else {
return false;
}
}
bool subghz_protocol_encoder_raw_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolEncoderRAW* instance = context;

View file

@ -2,6 +2,8 @@
#include "base.h"
#include <furi_hal.h>
#define SUBGHZ_PROTOCOL_RAW_NAME "RAW"
typedef void (*SubGhzProtocolEncoderRAWCallbackEnd)(void* context);
@ -25,6 +27,27 @@ bool subghz_protocol_raw_save_to_file_init(
const char* dev_name,
SubGhzPresetDefinition* preset);
/**
* Set SubGhzProtocolDecoderRAW to auto mode, which allows subghz_scene_receiver to capture RAW.
* @param context Pointer to a SubGhzProtocolDecoderRAW instance
* @param auto_mode Whether or not to enable auto mode
*/
void subghz_protocol_decoder_raw_set_auto_mode(void* context, bool auto_mode);
/**
* Set RSSI threshold ("sensitivity" level).
* @param context Pointer to a SubGhzProtocolDecoderRAW instance
* @param rssi_threshold The desired RSSI threshold
*/
void subghz_protocol_decoder_raw_set_rssi_threshold(void* context, int rssi_threshold);
/**
* Get RSSI threshold ("sensitivity" level).
* @param context Pointer to a SubGhzProtocolDecoderRAW instance
* @return rssi threshold in db
*/
int subghz_protocol_encoder_get_rssi_threshold(void* context);
/**
* Stop writing file to flash
* @param instance Pointer to a SubGhzProtocolDecoderRAW instance
@ -57,6 +80,15 @@ void subghz_protocol_decoder_raw_free(void* context);
*/
void subghz_protocol_decoder_raw_reset(void* context);
/**
* Write raw data to the instance's internal buffer.
* @param context Pointer to a SubGhzProtocolDecoderRAW instance
* @param level Signal level true-high false-low
* @param duration Duration of this level in, us
* @return whether or not data was written
*/
bool subghz_protocol_decoder_raw_write_data(void* context, bool level, uint32_t duration);
/**
* Parse a raw sequence of levels and durations received from the air.
* @param context Pointer to a SubGhzProtocolDecoderRAW instance
@ -67,12 +99,19 @@ void subghz_protocol_decoder_raw_feed(void* context, bool level, uint32_t durati
/**
* Deserialize data SubGhzProtocolDecoderRAW.
* @param context Pointer to a SubGhzProtocolDecoderRAW instance
* @param flipper_format Pointer to a FlipperFormat instance
* @param context Pointer to a SubGhzProtocolDecoderRAW instance
* @param flipper_format Pointer to a FlipperFormat instance
* @return true On success
*/
bool subghz_protocol_decoder_raw_deserialize(void* context, FlipperFormat* flipper_format);
/**
* Getting the hash sum of the last randomly received parcel.
* @param context Pointer to a SubGhzProtocolDecoderRAW instance
* @return hash Hash sum
*/
uint8_t subghz_protocol_decoder_raw_get_hash_data(void* context);
/**
* Getting a textual representation of the received data.
* @param context Pointer to a SubGhzProtocolDecoderRAW instance
@ -123,6 +162,19 @@ void subghz_protocol_raw_file_encoder_worker_set_callback_end(
*/
void subghz_protocol_raw_gen_fff_data(FlipperFormat* flipper_format, const char* file_path);
/**
* Serialize data SubGhzProtocolDecoderRAW.
* @param context Pointer to a SubGhzProtocolDecoderRAW instance
* @param flipper_format Pointer to a FlipperFormat instance
* @param frequency The frequency at which the signal was received, Hz
* @param preset The modulation on which the signal was received, FuriHalSubGhzPreset
* @return true On success
*/
bool subghz_protocol_decoder_raw_serialize(
void* context,
FlipperFormat* flipper_format,
SubGhzPresetDefinition* preset);
/**
* Deserialize and generating an upload to send.
* @param context Pointer to a SubGhzProtocolEncoderRAW instance
@ -134,6 +186,6 @@ bool subghz_protocol_encoder_raw_deserialize(void* context, FlipperFormat* flipp
/**
* Getting the level and duration of the upload to be loaded into DMA.
* @param context Pointer to a SubGhzProtocolEncoderRAW instance
* @return LevelDuration
* @return LevelDuration
*/
LevelDuration subghz_protocol_encoder_raw_yield(void* context);

View file

@ -139,6 +139,10 @@ static bool
uint64_t code_found_reverse;
int res = 0;
if(instance->manufacture_name == 0x0) {
instance->manufacture_name = "";
}
if(strcmp(instance->manufacture_name, "Unknown") == 0) {
code_found_reverse = subghz_protocol_blocks_reverse_key(
instance->generic.data, instance->generic.data_count_bit);

View file

@ -61,7 +61,7 @@ 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) == instance->filter) {
if((slot->base->protocol->flag & instance->filter) != 0) {
slot->base->protocol->decoder->feed(slot->base, level, duration);
}
}
@ -105,6 +105,11 @@ void subghz_receiver_set_filter(SubGhzReceiver* instance, SubGhzProtocolFlag fil
instance->filter = filter;
}
SubGhzProtocolFlag subghz_receiver_get_filter(SubGhzReceiver* instance) {
furi_assert(instance);
return instance->filter;
}
SubGhzProtocolDecoderBase* subghz_receiver_search_decoder_base_by_name(
SubGhzReceiver* instance,
const char* decoder_name) {

View file

@ -55,6 +55,13 @@ void subghz_receiver_set_rx_callback(
*/
void subghz_receiver_set_filter(SubGhzReceiver* instance, SubGhzProtocolFlag filter);
/**
* Get the filter of receivers that will work at the moment.
* @param instance Pointer to a SubGhzReceiver instance
* @return filter Filter, SubGhzProtocolFlag
*/
SubGhzProtocolFlag subghz_receiver_get_filter(SubGhzReceiver* instance);
/**
* Search for a cattery by his name.
* @param instance Pointer to a SubGhzReceiver instance