mirror of
https://github.com/DarkFlippers/unleashed-firmware
synced 2024-11-23 21:13:16 +00:00
Detect RAW feature
by perspecdev
This commit is contained in:
parent
ee6b59ab9d
commit
b00117e02c
10 changed files with 388 additions and 14 deletions
|
@ -99,6 +99,9 @@ void subghz_scene_read_raw_on_enter(void* context) {
|
||||||
subghz->txrx->receiver, SUBGHZ_PROTOCOL_RAW_NAME);
|
subghz->txrx->receiver, SUBGHZ_PROTOCOL_RAW_NAME);
|
||||||
furi_assert(subghz->txrx->decoder_result);
|
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
|
//set filter RAW feed
|
||||||
subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_RAW);
|
subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_RAW);
|
||||||
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdReadRAW);
|
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdReadRAW);
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
#include "../subghz_i.h"
|
#include "../subghz_i.h"
|
||||||
|
|
||||||
|
#include <lib/subghz/protocols/raw.h>
|
||||||
|
|
||||||
enum SubGhzSettingIndex {
|
enum SubGhzSettingIndex {
|
||||||
SubGhzSettingIndexFrequency,
|
SubGhzSettingIndexFrequency,
|
||||||
SubGhzSettingIndexHopping,
|
SubGhzSettingIndexHopping,
|
||||||
SubGhzSettingIndexModulation,
|
SubGhzSettingIndexModulation,
|
||||||
|
SubGhzSettingIndexDetectRaw,
|
||||||
|
SubGhzSettingIndexRSSIThreshold,
|
||||||
SubGhzSettingIndexLock,
|
SubGhzSettingIndexLock,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,6 +21,38 @@ const uint32_t hopping_value[HOPPING_COUNT] = {
|
||||||
SubGhzHopperStateRunnig,
|
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) {
|
uint8_t subghz_scene_receiver_config_next_frequency(const uint32_t value, void* context) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
SubGhz* subghz = 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) {
|
static void subghz_scene_receiver_config_set_frequency(VariableItem* item) {
|
||||||
SubGhz* subghz = variable_item_get_context(item);
|
SubGhz* subghz = variable_item_get_context(item);
|
||||||
uint8_t index = variable_item_get_current_value_index(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));
|
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) {
|
static void subghz_scene_receiver_config_set_hopping_running(VariableItem* item) {
|
||||||
SubGhz* subghz = variable_item_get_context(item);
|
SubGhz* subghz = variable_item_get_context(item);
|
||||||
uint8_t index = variable_item_get_current_value_index(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(
|
variable_item_set_current_value_text(
|
||||||
item, subghz_setting_get_preset_name(subghz->setting, value_index));
|
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) !=
|
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW) !=
|
||||||
SubGhzCustomEventManagerSet) {
|
SubGhzCustomEventManagerSet) {
|
||||||
variable_item_list_add(subghz->variable_item_list, "Lock Keyboard", 1, NULL, NULL);
|
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_scene_receiver_config_var_list_enter_callback,
|
||||||
subghz);
|
subghz);
|
||||||
}
|
}
|
||||||
|
|
||||||
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdVariableItemList);
|
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdVariableItemList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,8 @@ void subghz_scene_receiver_info_draw_widget(SubGhz* subghz) {
|
||||||
// Removed static check
|
// Removed static check
|
||||||
if(((subghz->txrx->decoder_result->protocol->flag & SubGhzProtocolFlag_Send) ==
|
if(((subghz->txrx->decoder_result->protocol->flag & SubGhzProtocolFlag_Send) ==
|
||||||
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) {
|
subghz->txrx->decoder_result->protocol->encoder->deserialize) {
|
||||||
widget_add_button_element(
|
widget_add_button_element(
|
||||||
subghz->widget,
|
subghz->widget,
|
||||||
|
|
|
@ -180,7 +180,19 @@ bool subghz_history_add_to_history(
|
||||||
FURI_LOG_E(TAG, "Missing Protocol");
|
FURI_LOG_E(TAG, "Missing Protocol");
|
||||||
break;
|
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 ");
|
string_set_str(instance->tmp_string, "KL ");
|
||||||
if(!flipper_format_read_string(item->flipper_string, "Manufacture", text)) {
|
if(!flipper_format_read_string(item->flipper_string, "Manufacture", text)) {
|
||||||
FURI_LOG_E(TAG, "Missing Protocol");
|
FURI_LOG_E(TAG, "Missing Protocol");
|
||||||
|
|
|
@ -33,6 +33,7 @@ static const Icon* ReceiverItemIcons[] = {
|
||||||
[SubGhzProtocolTypeUnknown] = &I_Quest_7x8,
|
[SubGhzProtocolTypeUnknown] = &I_Quest_7x8,
|
||||||
[SubGhzProtocolTypeStatic] = &I_Unlock_7x8,
|
[SubGhzProtocolTypeStatic] = &I_Unlock_7x8,
|
||||||
[SubGhzProtocolTypeDynamic] = &I_Lock_7x8,
|
[SubGhzProtocolTypeDynamic] = &I_Lock_7x8,
|
||||||
|
[SubGhzProtocolTypeRAW] = &I_Unlock_7x8,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -234,7 +235,6 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) {
|
||||||
canvas_draw_line(canvas, 46, 51, 125, 51);
|
canvas_draw_line(canvas, 46, 51, 125, 51);
|
||||||
canvas_set_font(canvas, FontSecondary);
|
canvas_set_font(canvas, FontSecondary);
|
||||||
} else {
|
} else {
|
||||||
//canvas_draw_icon(canvas, 0, 0, &I_Decoding_123x52);
|
|
||||||
canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52);
|
canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52);
|
||||||
canvas_set_font(canvas, FontPrimary);
|
canvas_set_font(canvas, FontPrimary);
|
||||||
canvas_draw_str(canvas, 63, 46, "Decoding...");
|
canvas_draw_str(canvas, 63, 46, "Decoding...");
|
||||||
|
|
|
@ -8,11 +8,16 @@
|
||||||
#include "../blocks/generic.h"
|
#include "../blocks/generic.h"
|
||||||
#include "../blocks/math.h"
|
#include "../blocks/math.h"
|
||||||
|
|
||||||
|
#include <furi.h>
|
||||||
#include <flipper_format/flipper_format_i.h>
|
#include <flipper_format/flipper_format_i.h>
|
||||||
#include <lib/toolbox/stream/stream.h>
|
#include <lib/toolbox/stream/stream.h>
|
||||||
|
#include <stm32wbxx_ll_rtc.h>
|
||||||
|
|
||||||
#define TAG "SubGhzProtocolRAW"
|
#define TAG "SubGhzProtocolRAW"
|
||||||
#define SUBGHZ_DOWNLOAD_MAX_SIZE 512
|
#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 = {
|
static const SubGhzBlockConst subghz_protocol_raw_const = {
|
||||||
.te_short = 50,
|
.te_short = 50,
|
||||||
|
@ -24,6 +29,8 @@ static const SubGhzBlockConst subghz_protocol_raw_const = {
|
||||||
struct SubGhzProtocolDecoderRAW {
|
struct SubGhzProtocolDecoderRAW {
|
||||||
SubGhzProtocolDecoderBase base;
|
SubGhzProtocolDecoderBase base;
|
||||||
|
|
||||||
|
SubGhzBlockDecoder decoder;
|
||||||
|
|
||||||
int32_t* upload_raw;
|
int32_t* upload_raw;
|
||||||
uint16_t ind_write;
|
uint16_t ind_write;
|
||||||
Storage* storage;
|
Storage* storage;
|
||||||
|
@ -32,6 +39,10 @@ struct SubGhzProtocolDecoderRAW {
|
||||||
string_t file_name;
|
string_t file_name;
|
||||||
size_t sample_write;
|
size_t sample_write;
|
||||||
bool last_level;
|
bool last_level;
|
||||||
|
bool auto_mode;
|
||||||
|
bool has_rssi_above_threshold;
|
||||||
|
int rssi_threshold;
|
||||||
|
uint8_t postroll_frames;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SubGhzProtocolEncoderRAW {
|
struct SubGhzProtocolEncoderRAW {
|
||||||
|
@ -55,8 +66,8 @@ const SubGhzProtocolDecoder subghz_protocol_raw_decoder = {
|
||||||
.feed = subghz_protocol_decoder_raw_feed,
|
.feed = subghz_protocol_decoder_raw_feed,
|
||||||
.reset = subghz_protocol_decoder_raw_reset,
|
.reset = subghz_protocol_decoder_raw_reset,
|
||||||
|
|
||||||
.get_hash_data = NULL,
|
.get_hash_data = subghz_protocol_decoder_raw_get_hash_data,
|
||||||
.serialize = NULL,
|
.serialize = subghz_protocol_decoder_raw_serialize,
|
||||||
.deserialize = subghz_protocol_decoder_raw_deserialize,
|
.deserialize = subghz_protocol_decoder_raw_deserialize,
|
||||||
.get_string = subghz_protocol_decoder_raw_get_string,
|
.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;
|
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) {
|
size_t subghz_protocol_raw_get_sample_write(SubGhzProtocolDecoderRAW* instance) {
|
||||||
return instance->sample_write + instance->ind_write;
|
return instance->sample_write + instance->ind_write;
|
||||||
}
|
}
|
||||||
|
@ -210,6 +251,8 @@ void* subghz_protocol_decoder_raw_alloc(SubGhzEnvironment* environment) {
|
||||||
instance->ind_write = 0;
|
instance->ind_write = 0;
|
||||||
instance->last_level = false;
|
instance->last_level = false;
|
||||||
instance->file_is_open = RAWFileIsOpenClose;
|
instance->file_is_open = RAWFileIsOpenClose;
|
||||||
|
instance->postroll_frames = 0;
|
||||||
|
instance->rssi_threshold = SUBGHZ_AUTO_DETECT_RAW_THRESHOLD;
|
||||||
string_init(instance->file_name);
|
string_init(instance->file_name);
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
|
@ -219,6 +262,10 @@ void subghz_protocol_decoder_raw_free(void* context) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
SubGhzProtocolDecoderRAW* instance = context;
|
SubGhzProtocolDecoderRAW* instance = context;
|
||||||
string_clear(instance->file_name);
|
string_clear(instance->file_name);
|
||||||
|
if(instance->upload_raw != NULL) {
|
||||||
|
free(instance->upload_raw);
|
||||||
|
instance->upload_raw = NULL;
|
||||||
|
}
|
||||||
free(instance);
|
free(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,23 +273,65 @@ void subghz_protocol_decoder_raw_reset(void* context) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
SubGhzProtocolDecoderRAW* instance = context;
|
SubGhzProtocolDecoderRAW* instance = context;
|
||||||
instance->ind_write = 0;
|
instance->ind_write = 0;
|
||||||
|
instance->has_rssi_above_threshold = false;
|
||||||
instance->last_level = 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) {
|
void subghz_protocol_decoder_raw_feed(void* context, bool level, uint32_t duration) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
SubGhzProtocolDecoderRAW* instance = context;
|
SubGhzProtocolDecoderRAW* instance = context;
|
||||||
|
|
||||||
if(instance->upload_raw != NULL) {
|
if(instance->upload_raw != NULL && duration > subghz_protocol_raw_const.te_short) {
|
||||||
if(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) {
|
if(instance->last_level != level) {
|
||||||
instance->last_level = (level ? true : false);
|
instance->last_level = (level ? true : false);
|
||||||
instance->upload_raw[instance->ind_write++] = (level ? duration : -duration);
|
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) {
|
if(instance->ind_write == SUBGHZ_DOWNLOAD_MAX_SIZE) {
|
||||||
subghz_protocol_raw_save_to_file_write(instance);
|
subghz_protocol_raw_save_to_file_write(instance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,12 +344,19 @@ bool subghz_protocol_decoder_raw_deserialize(void* context, FlipperFormat* flipp
|
||||||
return true;
|
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) {
|
void subghz_protocol_decoder_raw_get_string(void* context, string_t output) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
//SubGhzProtocolDecoderRAW* instance = context;
|
//SubGhzProtocolDecoderRAW* instance = context;
|
||||||
UNUSED(context);
|
UNUSED(context);
|
||||||
//ToDo no use
|
//ToDo no use
|
||||||
string_cat_printf(output, "RAW Date");
|
string_cat_printf(output, "RAW Data");
|
||||||
}
|
}
|
||||||
|
|
||||||
void* subghz_protocol_encoder_raw_alloc(SubGhzEnvironment* environment) {
|
void* subghz_protocol_encoder_raw_alloc(SubGhzEnvironment* environment) {
|
||||||
|
@ -273,6 +369,13 @@ void* subghz_protocol_encoder_raw_alloc(SubGhzEnvironment* environment) {
|
||||||
return instance;
|
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) {
|
void subghz_protocol_encoder_raw_stop(void* context) {
|
||||||
SubGhzProtocolEncoderRAW* instance = context;
|
SubGhzProtocolEncoderRAW* instance = context;
|
||||||
instance->is_running = false;
|
instance->is_running = false;
|
||||||
|
@ -330,6 +433,70 @@ void subghz_protocol_raw_gen_fff_data(FlipperFormat* flipper_format, const char*
|
||||||
} while(false);
|
} 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) {
|
bool subghz_protocol_encoder_raw_deserialize(void* context, FlipperFormat* flipper_format) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
SubGhzProtocolEncoderRAW* instance = context;
|
SubGhzProtocolEncoderRAW* instance = context;
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include "base.h"
|
#include "base.h"
|
||||||
|
|
||||||
|
#include <furi_hal.h>
|
||||||
|
|
||||||
#define SUBGHZ_PROTOCOL_RAW_NAME "RAW"
|
#define SUBGHZ_PROTOCOL_RAW_NAME "RAW"
|
||||||
|
|
||||||
typedef void (*SubGhzProtocolEncoderRAWCallbackEnd)(void* context);
|
typedef void (*SubGhzProtocolEncoderRAWCallbackEnd)(void* context);
|
||||||
|
@ -25,6 +27,27 @@ bool subghz_protocol_raw_save_to_file_init(
|
||||||
const char* dev_name,
|
const char* dev_name,
|
||||||
SubGhzPresetDefinition* preset);
|
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
|
* Stop writing file to flash
|
||||||
* @param instance Pointer to a SubGhzProtocolDecoderRAW instance
|
* @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);
|
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.
|
* Parse a raw sequence of levels and durations received from the air.
|
||||||
* @param context Pointer to a SubGhzProtocolDecoderRAW instance
|
* @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.
|
* Deserialize data SubGhzProtocolDecoderRAW.
|
||||||
* @param context Pointer to a SubGhzProtocolDecoderRAW instance
|
* @param context Pointer to a SubGhzProtocolDecoderRAW instance
|
||||||
* @param flipper_format Pointer to a FlipperFormat instance
|
* @param flipper_format Pointer to a FlipperFormat instance
|
||||||
* @return true On success
|
* @return true On success
|
||||||
*/
|
*/
|
||||||
bool subghz_protocol_decoder_raw_deserialize(void* context, FlipperFormat* flipper_format);
|
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.
|
* Getting a textual representation of the received data.
|
||||||
* @param context Pointer to a SubGhzProtocolDecoderRAW instance
|
* @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);
|
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.
|
* Deserialize and generating an upload to send.
|
||||||
* @param context Pointer to a SubGhzProtocolEncoderRAW instance
|
* @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.
|
* Getting the level and duration of the upload to be loaded into DMA.
|
||||||
* @param context Pointer to a SubGhzProtocolEncoderRAW instance
|
* @param context Pointer to a SubGhzProtocolEncoderRAW instance
|
||||||
* @return LevelDuration
|
* @return LevelDuration
|
||||||
*/
|
*/
|
||||||
LevelDuration subghz_protocol_encoder_raw_yield(void* context);
|
LevelDuration subghz_protocol_encoder_raw_yield(void* context);
|
||||||
|
|
|
@ -139,6 +139,10 @@ static bool
|
||||||
uint64_t code_found_reverse;
|
uint64_t code_found_reverse;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
|
if(instance->manufacture_name == 0x0) {
|
||||||
|
instance->manufacture_name = "";
|
||||||
|
}
|
||||||
|
|
||||||
if(strcmp(instance->manufacture_name, "Unknown") == 0) {
|
if(strcmp(instance->manufacture_name, "Unknown") == 0) {
|
||||||
code_found_reverse = subghz_protocol_blocks_reverse_key(
|
code_found_reverse = subghz_protocol_blocks_reverse_key(
|
||||||
instance->generic.data, instance->generic.data_count_bit);
|
instance->generic.data, instance->generic.data_count_bit);
|
||||||
|
|
|
@ -61,7 +61,7 @@ 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) == instance->filter) {
|
if((slot->base->protocol->flag & instance->filter) != 0) {
|
||||||
slot->base->protocol->decoder->feed(slot->base, level, duration);
|
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;
|
instance->filter = filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SubGhzProtocolFlag subghz_receiver_get_filter(SubGhzReceiver* instance) {
|
||||||
|
furi_assert(instance);
|
||||||
|
return instance->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) {
|
||||||
|
|
|
@ -55,6 +55,13 @@ void subghz_receiver_set_rx_callback(
|
||||||
*/
|
*/
|
||||||
void subghz_receiver_set_filter(SubGhzReceiver* instance, SubGhzProtocolFlag filter);
|
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.
|
* Search for a cattery by his name.
|
||||||
* @param instance Pointer to a SubGhzReceiver instance
|
* @param instance Pointer to a SubGhzReceiver instance
|
||||||
|
|
Loading…
Reference in a new issue