Throw away Kostily & Velosipedy

Ne bag a ficha, bolshe ne nuzhna
This commit is contained in:
MX 2023-02-09 17:21:40 +03:00
parent a7a4f9b885
commit ba36f4672c
No known key found for this signature in database
GPG Key ID: 7CCC66B7DBDD1C83
14 changed files with 74 additions and 1200 deletions

View File

@ -170,11 +170,6 @@ void subghz_scene_decode_raw_on_enter(void* context) {
subghz_receiver_set_rx_callback(
subghz->txrx->receiver, subghz_scene_add_to_history_callback, subghz);
// 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_receiver_search_decoder_base_by_name(
subghz->txrx->receiver, SUBGHZ_PROTOCOL_RAW_NAME),
false);
subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_Decodable);
if(subghz->decode_raw_state == SubGhzDecodeRawStateStart) {

View File

@ -119,9 +119,6 @@ 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);
@ -422,10 +419,6 @@ void subghz_scene_read_raw_on_exit(void* context) {
subghz->state_notifications = SubGhzNotificationStateIDLE;
notification_message(subghz->notifications, &sequence_reset_rgb);
//filter restoration
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
subghz_last_settings_set_detect_raw_values(subghz);
#else
// filter restoration
subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_Decodable);
#endif
}

View File

@ -1,16 +1,10 @@
#include "../subghz_i.h"
#include <lib/toolbox/value_index.h>
#include <lib/subghz/protocols/raw.h>
#define TAG "SubGhzSceneReceiverConfig"
enum SubGhzSettingIndex {
SubGhzSettingIndexFrequency,
SubGhzSettingIndexHopping,
SubGhzSettingIndexModulation,
SubGhzSettingIndexDetectRaw,
SubGhzSettingIndexRSSIThreshold,
SubGhzSettingIndexSound,
SubGhzSettingIndexLock,
SubGhzSettingIndexRAWThesholdRSSI,
@ -55,40 +49,6 @@ const uint32_t hopping_value[HOPPING_COUNT] = {
SubGhzHopperStateRunnig,
};
#define DETECT_RAW_COUNT 2
const char* const detect_raw_text[DETECT_RAW_COUNT] = {
"OFF",
"ON",
};
#ifndef SUBGHZ_SAVE_DETECT_RAW_SETTING
const SubGhzProtocolFlag detect_raw_value[DETECT_RAW_COUNT] = {
SubGhzProtocolFlag_Decodable,
SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_RAW,
};
#endif
#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,
};
#define SPEAKER_COUNT 2
const char* const speaker_text[SPEAKER_COUNT] = {
"OFF",
@ -149,36 +109,6 @@ uint8_t subghz_scene_receiver_config_hopper_value_index(
}
}
#ifndef SUBGHZ_SAVE_DETECT_RAW_SETTING
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;
}
#endif
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);
@ -216,79 +146,40 @@ 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);
if(subghz->txrx->hopper_state == 0) {
variable_item_set_current_value_text(item, detect_raw_text[index]);
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
subghz->last_settings->detect_raw = index;
subghz_last_settings_set_detect_raw_values(subghz);
#else
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));
#endif
} else {
variable_item_set_current_value_index(item, 0);
}
}
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);
if(subghz_receiver_get_filter(subghz->txrx->receiver) == SubGhzProtocolFlag_Decodable) {
variable_item_set_current_value_text(item, hopping_text[index]);
if(hopping_value[index] == SubGhzHopperStateOFF) {
char text_buf[10] = {0};
snprintf(
text_buf,
sizeof(text_buf),
"%lu.%02lu",
subghz_setting_get_default_frequency(subghz->setting) / 1000000,
(subghz_setting_get_default_frequency(subghz->setting) % 1000000) / 10000);
variable_item_set_current_value_text(
(VariableItem*)scene_manager_get_scene_state(
subghz->scene_manager, SubGhzSceneReceiverConfig),
text_buf);
subghz->txrx->preset->frequency =
subghz_setting_get_default_frequency(subghz->setting);
variable_item_set_current_value_index(
(VariableItem*)scene_manager_get_scene_state(
subghz->scene_manager, SubGhzSceneReceiverConfig),
subghz_setting_get_frequency_default_index(subghz->setting));
} else {
variable_item_set_current_value_text(
(VariableItem*)scene_manager_get_scene_state(
subghz->scene_manager, SubGhzSceneReceiverConfig),
" -----");
variable_item_set_current_value_index(
(VariableItem*)scene_manager_get_scene_state(
subghz->scene_manager, SubGhzSceneReceiverConfig),
subghz_setting_get_frequency_default_index(subghz->setting));
}
subghz->txrx->hopper_state = hopping_value[index];
variable_item_set_current_value_text(item, hopping_text[index]);
if(hopping_value[index] == SubGhzHopperStateOFF) {
char text_buf[10] = {0};
snprintf(
text_buf,
sizeof(text_buf),
"%lu.%02lu",
subghz_setting_get_default_frequency(subghz->setting) / 1000000,
(subghz_setting_get_default_frequency(subghz->setting) % 1000000) / 10000);
variable_item_set_current_value_text(
(VariableItem*)scene_manager_get_scene_state(
subghz->scene_manager, SubGhzSceneReceiverConfig),
text_buf);
subghz->txrx->preset->frequency = subghz_setting_get_default_frequency(subghz->setting);
variable_item_set_current_value_index(
(VariableItem*)scene_manager_get_scene_state(
subghz->scene_manager, SubGhzSceneReceiverConfig),
subghz_setting_get_frequency_default_index(subghz->setting));
} else {
variable_item_set_current_value_index(item, 0);
variable_item_set_current_value_text(
(VariableItem*)scene_manager_get_scene_state(
subghz->scene_manager, SubGhzSceneReceiverConfig),
" -----");
variable_item_set_current_value_index(
(VariableItem*)scene_manager_get_scene_state(
subghz->scene_manager, SubGhzSceneReceiverConfig),
subghz_setting_get_frequency_default_index(subghz->setting));
}
subghz->txrx->hopper_state = hopping_value[index];
}
static void subghz_scene_receiver_config_set_speaker(VariableItem* item) {
@ -321,13 +212,6 @@ void subghz_scene_receiver_config_on_enter(void* context) {
VariableItem* item;
uint8_t value_index;
#ifdef FURI_DEBUG
FURI_LOG_D(
TAG,
"Last frequency: %ld, Preset: %ld",
subghz->last_settings->frequency,
subghz->last_settings->preset);
#endif
item = variable_item_list_add(
subghz->variable_item_list,
"Frequency:",
@ -373,40 +257,8 @@ void subghz_scene_receiver_config_on_enter(void* context) {
subghz->txrx->hopper_state, hopping_value, HOPPING_COUNT, subghz);
variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, hopping_text[value_index]);
// Detect Raw
item = variable_item_list_add(
subghz->variable_item_list,
"Detect Raw:",
DETECT_RAW_COUNT,
subghz_scene_receiver_config_set_detect_raw,
subghz);
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
value_index = subghz->last_settings->detect_raw;
#else
value_index = subghz_scene_receiver_config_detect_raw_value_index(
subghz_receiver_get_filter(subghz->txrx->receiver),
detect_raw_value,
DETECT_RAW_COUNT);
#endif
variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, detect_raw_text[value_index]);
// RSSI
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]);
}
// Enable speaker, will send all incoming noises and signals to speaker so you can listen how your remote sounds like :)
item = variable_item_list_add(
subghz->variable_item_list,

View File

@ -23,15 +23,6 @@ void subghz_scene_start_on_enter(void* context) {
if(subghz->state_notifications == SubGhzNotificationStateStarting) {
subghz->state_notifications = SubGhzNotificationStateIDLE;
}
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
subghz_last_settings_set_detect_raw_values(subghz);
#else
subghz_protocol_decoder_raw_set_auto_mode(
subghz_receiver_search_decoder_base_by_name(
subghz->txrx->receiver, SUBGHZ_PROTOCOL_RAW_NAME),
false);
subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_Decodable);
#endif
submenu_add_item(
subghz->submenu, "Read", SubmenuIndexRead, subghz_scene_start_submenu_callback, subghz);

View File

@ -236,20 +236,11 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) {
subghz->last_settings = subghz_last_settings_alloc();
subghz_last_settings_load(subghz->last_settings, 0);
#if FURI_DEBUG
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
FURI_LOG_D(
TAG,
"last frequency: %ld, preset: %ld, detect_raw: %d",
subghz->last_settings->frequency,
subghz->last_settings->preset,
subghz->last_settings->detect_raw);
#else
FURI_LOG_D(
TAG,
"last frequency: %ld, preset: %ld",
subghz->last_settings->frequency,
subghz->last_settings->preset);
#endif
#endif
subghz_setting_set_default_frequency(subghz->setting, subghz->last_settings->frequency);
}
@ -288,11 +279,8 @@ SubGhz* subghz_alloc(bool alloc_for_tx_only) {
subghz_environment_set_protocol_registry(
subghz->txrx->environment, (void*)&subghz_protocol_registry);
subghz->txrx->receiver = subghz_receiver_alloc_init(subghz->txrx->environment);
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
subghz_last_settings_set_detect_raw_values(subghz);
#else
subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_Decodable);
#endif
subghz_worker_set_overrun_callback(
subghz->txrx->worker, (SubGhzWorkerOverrunCallback)subghz_receiver_reset);

View File

@ -1,33 +1,14 @@
#include "subghz_history.h"
#include "subghz_history_private.h"
#include <lib/subghz/receiver.h>
#include <toolbox/path.h>
#include <flipper_format/flipper_format_i.h>
#include "flipper_format_stream_i.h"
#include <inttypes.h>
#define SUBGHZ_HISTORY_MAX 60
/**
* @brief Settings for temporary files
*
*/
#define SUBGHZ_HISTORY_TMP_DIR EXT_PATH("subghz/tmp_history")
#define SUBGHZ_HISTORY_TMP_EXTENSION ".tmp"
#define SUBGHZ_HISTORY_TMP_SIGNAL_MAX 700
#define SUBGHZ_HISTORY_TMP_SIGNAL_MIN 100
#define SUBGHZ_HISTORY_TMP_REMOVE_FILES true
#define SUBGHZ_HISTORY_TMP_RAW_KEY "RAW_Data"
#define MAX_LINE 500
const size_t buffer_size = 32;
#include <furi.h>
#define SUBGHZ_HISTORY_MAX 50
#define TAG "SubGhzHistory"
typedef struct {
FuriString* item_str;
FlipperFormat* flipper_string;
FuriString* protocol_name;
bool is_file;
uint8_t type;
SubGhzRadioPreset* preset;
} SubGhzHistoryItem;
@ -45,143 +26,30 @@ struct SubGhzHistory {
uint16_t last_index_write;
uint8_t code_last_hash_data;
FuriString* tmp_string;
bool write_tmp_files;
Storage* storage;
SubGhzHistoryStruct* history;
};
#ifdef FURI_DEBUG
#define LOG_DELAY 0
#endif
FuriString* subghz_history_generate_temp_filename(uint32_t index) {
FuriHalRtcDateTime datetime = {0};
furi_hal_rtc_get_datetime(&datetime);
return furi_string_alloc_printf("%03ld%s", index, SUBGHZ_HISTORY_TMP_EXTENSION);
}
bool subghz_history_is_tmp_dir_exists(SubGhzHistory* instance) {
FileInfo file_info;
FS_Error error = storage_common_stat(instance->storage, SUBGHZ_HISTORY_TMP_DIR, &file_info);
if(error == FSE_OK) {
if(file_info.flags & FSF_DIRECTORY) {
return true;
}
}
return false;
}
bool subghz_history_check_sdcard(SubGhzHistory* instance) {
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "check_sdcard");
uint32_t start_time = furi_get_tick();
#endif
bool result = false;
// Stage 0 - check SD Card
FS_Error status = storage_sd_status(instance->storage);
if(status == FSE_OK) {
result = subghz_history_is_tmp_dir_exists(instance);
if(!subghz_history_is_tmp_dir_exists(instance)) {
result = storage_simply_mkdir(instance->storage, SUBGHZ_HISTORY_TMP_DIR);
}
} else {
FURI_LOG_W(TAG, "SD storage not installed! Status: %d", status);
}
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "Running time (check_sdcard): %ld ms", furi_get_tick() - start_time);
#endif
return result;
}
void subghz_history_clear_tmp_dir(SubGhzHistory* instance) {
furi_assert(instance);
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "clear_tmp_dir");
#endif
if(!instance->write_tmp_files) {
// Nothing to do here!
return;
}
//uint32_t start_time = furi_get_tick();
#ifdef SUBGHZ_HISTORY_TMP_REMOVE_FILES
// Stage 0 - Dir exists?
bool res = subghz_history_is_tmp_dir_exists(instance);
if(res) {
// Stage 1 - delete all content if exists
FileInfo fileinfo;
storage_common_stat(instance->storage, SUBGHZ_HISTORY_TMP_DIR, &fileinfo);
res = fileinfo.flags & FSF_DIRECTORY ?
storage_simply_remove_recursive(instance->storage, SUBGHZ_HISTORY_TMP_DIR) :
(storage_common_remove(instance->storage, SUBGHZ_HISTORY_TMP_DIR) == FSE_OK);
}
// Stage 2 - create dir if necessary
res = storage_simply_mkdir(instance->storage, SUBGHZ_HISTORY_TMP_DIR);
if(!res) {
FURI_LOG_E(TAG, "Cannot process temp dir!");
}
#endif
/* uint32_t stop_time = furi_get_tick() - start_time;
FURI_LOG_I(TAG, "Running time (clear_tmp_dir): %d ms", stop_time);*/
}
SubGhzHistory* subghz_history_alloc(void) {
SubGhzHistory* instance = malloc(sizeof(SubGhzHistory));
instance->tmp_string = furi_string_alloc();
instance->history = malloc(sizeof(SubGhzHistoryStruct));
SubGhzHistoryItemArray_init(instance->history->data);
instance->storage = furi_record_open(RECORD_STORAGE);
instance->write_tmp_files = subghz_history_check_sdcard(instance);
if(!instance->write_tmp_files) {
FURI_LOG_E(TAG, "Unstable work! Cannot use SD Card!");
}
return instance;
}
void subghz_history_item_free(void* current_item) {
furi_assert(current_item);
SubGhzHistoryItem* item = (SubGhzHistoryItem*)current_item;
furi_string_free(item->item_str);
furi_string_free(item->preset->name);
furi_string_free(item->protocol_name);
free(item->preset);
item->type = 0;
item->is_file = false;
if(item->flipper_string != NULL) {
flipper_format_free(item->flipper_string);
}
}
void subghz_history_clean_item_array(SubGhzHistory* instance) {
for
M_EACH(item, instance->history->data, SubGhzHistoryItemArray_t) {
subghz_history_item_free(item);
}
}
void subghz_history_free(SubGhzHistory* instance) {
furi_assert(instance);
furi_string_free(instance->tmp_string);
subghz_history_clean_item_array(instance);
for
M_EACH(item, instance->history->data, SubGhzHistoryItemArray_t) {
furi_string_free(item->item_str);
furi_string_free(item->preset->name);
free(item->preset);
flipper_format_free(item->flipper_string);
item->type = 0;
}
SubGhzHistoryItemArray_clear(instance->history->data);
free(instance->history);
// Delete all temporary file, on exit it's ok
subghz_history_clear_tmp_dir(instance);
furi_record_close(RECORD_STORAGE);
free(instance);
}
@ -206,9 +74,14 @@ const char* subghz_history_get_preset(SubGhzHistory* instance, uint16_t idx) {
void subghz_history_reset(SubGhzHistory* instance) {
furi_assert(instance);
furi_string_reset(instance->tmp_string);
subghz_history_clean_item_array(instance);
for
M_EACH(item, instance->history->data, SubGhzHistoryItemArray_t) {
furi_string_free(item->item_str);
furi_string_free(item->preset->name);
free(item->preset);
flipper_format_free(item->flipper_string);
item->type = 0;
}
SubGhzHistoryItemArray_reset(instance->history->data);
instance->last_index_write = 0;
instance->code_last_hash_data = 0;
@ -228,8 +101,12 @@ uint8_t subghz_history_get_type_protocol(SubGhzHistory* instance, uint16_t idx)
const char* subghz_history_get_protocol_name(SubGhzHistory* instance, uint16_t idx) {
furi_assert(instance);
SubGhzHistoryItem* item = SubGhzHistoryItemArray_get(instance->history->data, idx);
return furi_string_get_cstr(item->protocol_name);
flipper_format_rewind(item->flipper_string);
if(!flipper_format_read_string(item->flipper_string, "Protocol", instance->tmp_string)) {
FURI_LOG_E(TAG, "Missing Protocol");
furi_string_reset(instance->tmp_string);
}
return furi_string_get_cstr(instance->tmp_string);
}
FlipperFormat* subghz_history_get_raw_data(SubGhzHistory* instance, uint16_t idx) {
@ -238,72 +115,23 @@ FlipperFormat* subghz_history_get_raw_data(SubGhzHistory* instance, uint16_t idx
if(item->flipper_string) {
return item->flipper_string;
} else {
bool result_ok = false;
if(instance->write_tmp_files && item->is_file) {
// We have files!
FuriString* filename = subghz_history_generate_temp_filename(idx);
FuriString* dir_path;
dir_path = furi_string_alloc_printf(
"%s/%s", SUBGHZ_HISTORY_TMP_DIR, furi_string_get_cstr(filename));
if(storage_file_exists(instance->storage, furi_string_get_cstr(dir_path))) {
#ifdef FURI_DEBUG
FURI_LOG_D(TAG, "Exist: %s", furi_string_get_cstr(dir_path));
furi_delay_ms(LOG_DELAY);
#endif
// Set to current anyway it has NULL value
item->flipper_string = flipper_format_string_alloc();
Stream* dst_stream = flipper_format_get_raw_stream(item->flipper_string);
stream_clean(dst_stream);
size_t size = stream_load_from_file(
dst_stream, instance->storage, furi_string_get_cstr(dir_path));
if(size > 0) {
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "Save ok!");
furi_delay_ms(LOG_DELAY);
#endif
// We changed contents of file, so we no needed to load
// content from disk for the next time
item->is_file = false;
result_ok = true;
} else {
FURI_LOG_E(TAG, "Stream copy failed!");
flipper_format_free(item->flipper_string);
}
} else {
FURI_LOG_E(TAG, "Can't convert filename to file");
}
furi_string_free(filename);
furi_string_free(dir_path);
} else {
#ifdef FURI_DEBUG
FURI_LOG_W(TAG, "Write TMP files failed!");
furi_delay_ms(LOG_DELAY);
#endif
}
return result_ok ? item->flipper_string : NULL;
return NULL;
}
}
bool subghz_history_get_text_space_left(SubGhzHistory* instance, FuriString* output) {
furi_assert(instance);
if(instance->last_index_write == SUBGHZ_HISTORY_MAX) {
if(output != NULL) furi_string_printf(output, "Memory is FULL");
return true;
}
if(output != NULL) {
if(output != NULL)
furi_string_printf(output, "%02u/%02u", instance->last_index_write, SUBGHZ_HISTORY_MAX);
}
return false;
}
uint16_t subghz_history_get_last_index(SubGhzHistory* instance) {
return instance->last_index_write;
}
void subghz_history_get_text_item_menu(SubGhzHistory* instance, FuriString* output, uint16_t idx) {
SubGhzHistoryItem* item = SubGhzHistoryItemArray_get(instance->history->data, idx);
furi_string_set(output, item->item_str);
@ -316,9 +144,7 @@ bool subghz_history_add_to_history(
furi_assert(instance);
furi_assert(context);
if(instance->last_index_write >= SUBGHZ_HISTORY_MAX) {
return false;
}
if(instance->last_index_write >= SUBGHZ_HISTORY_MAX) return false;
SubGhzProtocolDecoderBase* decoder_base = context;
if((instance->code_last_hash_data ==
@ -330,6 +156,7 @@ bool subghz_history_add_to_history(
instance->code_last_hash_data = subghz_protocol_decoder_base_get_hash_data(decoder_base);
instance->last_update_timestamp = furi_get_tick();
FuriString* text;
text = furi_string_alloc();
SubGhzHistoryItem* item = SubGhzHistoryItemArray_push_raw(instance->history->data);
@ -342,11 +169,6 @@ bool subghz_history_add_to_history(
item->preset->data_size = preset->data_size;
item->item_str = furi_string_alloc();
item->protocol_name = furi_string_alloc();
bool tmp_file_for_raw = false;
// At this point file mapped to memory otherwise file cannot decode
item->flipper_string = flipper_format_string_alloc();
subghz_protocol_decoder_base_serialize(decoder_base, item->flipper_string, preset);
@ -358,26 +180,8 @@ bool subghz_history_add_to_history(
if(!flipper_format_read_string(item->flipper_string, "Protocol", instance->tmp_string)) {
FURI_LOG_E(TAG, "Missing Protocol");
break;
} else {
furi_string_printf(
item->protocol_name, "%s", furi_string_get_cstr(instance->tmp_string));
}
if(!strcmp(furi_string_get_cstr(instance->tmp_string), "RAW")) {
// Enable writing temp files to micro sd
tmp_file_for_raw = true;
// Write display name
furi_string_printf(
item->item_str,
"RAW %03ld.%02ld",
preset->frequency / 1000000 % 1000,
preset->frequency / 10000 % 100);
// Rewind
if(!flipper_format_rewind(item->flipper_string)) {
FURI_LOG_E(TAG, "Rewind error");
}
break;
} else if(!strcmp(furi_string_get_cstr(instance->tmp_string), "KeeLoq")) {
if(!strcmp(furi_string_get_cstr(instance->tmp_string), "KeeLoq")) {
furi_string_set(instance->tmp_string, "KL ");
if(!flipper_format_read_string(item->flipper_string, "Manufacture", text)) {
FURI_LOG_E(TAG, "Missing Protocol");
@ -405,7 +209,6 @@ bool subghz_history_add_to_history(
for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
data = (data << 8) | key_data[i];
}
if(!(uint32_t)(data >> 32)) {
furi_string_printf(
item->item_str,
@ -422,461 +225,7 @@ bool subghz_history_add_to_history(
}
} while(false);
// If we can write to files
if(instance->write_tmp_files && tmp_file_for_raw) {
FuriString* filename = subghz_history_generate_temp_filename(instance->last_index_write);
FuriString* dir_path;
dir_path = furi_string_alloc();
furi_string_cat_printf(
dir_path, "%s/%s", SUBGHZ_HISTORY_TMP_DIR, furi_string_get_cstr(filename));
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "Save temp file: %s", furi_string_get_cstr(dir_path));
#endif
if(!subghz_history_tmp_write_file_split(instance, item, furi_string_get_cstr(dir_path))) {
// Plan B!
subghz_history_tmp_write_file_full(instance, item, dir_path);
}
if(item->is_file) {
flipper_format_free(item->flipper_string);
item->flipper_string = NULL;
}
furi_string_free(filename);
furi_string_free(dir_path);
} else {
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "Old fashion way");
#endif
}
furi_string_free(text);
instance->last_index_write++;
return true;
}
static inline bool is_space_playground(char c) {
return c == ' ' || c == '\t' || c == flipper_format_eolr;
}
bool subghz_history_stream_read_valid_key(Stream* stream, FuriString* key) {
furi_string_reset(key);
uint8_t buffer[buffer_size];
bool found = false;
bool error = false;
bool accumulate = true;
bool new_line = true;
while(true) {
size_t was_read = stream_read(stream, buffer, buffer_size);
if(was_read == 0) break;
for(size_t i = 0; i < was_read; i++) {
uint8_t data = buffer[i];
if(data == flipper_format_eoln) {
// EOL found, clean data, start accumulating data and set the new_line flag
furi_string_reset(key);
accumulate = true;
new_line = true;
} else if(data == flipper_format_eolr) {
// ignore
} else if(data == flipper_format_comment && new_line) {
// if there is a comment character and we are at the beginning of a new line
// do not accumulate comment data and reset the new_line flag
accumulate = false;
new_line = false;
} else if(data == flipper_format_delimiter) {
if(new_line) {
// we are on a "new line" and found the delimiter
// this can only be if we have previously found some kind of key, so
// clear the data, set the flag that we no longer want to accumulate data
// and reset the new_line flag
furi_string_reset(key);
accumulate = false;
new_line = false;
} else {
// parse the delimiter only if we are accumulating data
if(accumulate) {
// we found the delimiter, move the rw pointer to the delimiter location
// and signal that we have found something
if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) {
error = true;
break;
}
found = true;
break;
}
}
} else {
// just new symbol, reset the new_line flag
new_line = false;
if(accumulate) {
// and accumulate data if we want
furi_string_push_back(key, data);
}
}
}
if(found || error) break;
}
return found;
}
bool subghz_history_stream_seek_to_key(Stream* stream, const char* key, bool strict_mode) {
bool found = false;
FuriString* read_key;
read_key = furi_string_alloc();
while(!stream_eof(stream)) {
if(subghz_history_stream_read_valid_key(stream, read_key)) {
if(furi_string_cmp_str(read_key, key) == 0) {
if(!stream_seek(stream, 2, StreamOffsetFromCurrent)) {
break;
}
found = true;
break;
} else if(strict_mode) {
found = false;
break;
}
}
}
furi_string_free(read_key);
return found;
}
bool subghz_history_stream_read_value(Stream* stream, FuriString* value, bool* last) {
enum { LeadingSpace, ReadValue, TrailingSpace } state = LeadingSpace;
const size_t buffer_size = 32;
uint8_t buffer[buffer_size];
bool result = false;
bool error = false;
furi_string_reset(value);
while(true) {
size_t was_read = stream_read(stream, buffer, buffer_size);
if(was_read == 0) {
if(state != LeadingSpace && stream_eof(stream)) {
result = true;
*last = true;
} else {
error = true;
}
}
for(uint16_t i = 0; i < was_read; i++) {
const uint8_t data = buffer[i];
if(state == LeadingSpace) {
if(is_space_playground(data)) {
continue;
} else if(data == flipper_format_eoln) {
stream_seek(stream, i - was_read, StreamOffsetFromCurrent);
error = true;
break;
} else {
state = ReadValue;
furi_string_push_back(value, data);
}
} else if(state == ReadValue) {
if(is_space_playground(data)) {
state = TrailingSpace;
} else if(data == flipper_format_eoln) {
if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) {
error = true;
} else {
result = true;
*last = true;
}
break;
} else {
furi_string_push_back(value, data);
}
} else if(state == TrailingSpace) {
if(is_space_playground(data)) {
continue;
} else if(!stream_seek(stream, i - was_read, StreamOffsetFromCurrent)) {
error = true;
} else {
*last = (data == flipper_format_eoln);
result = true;
}
break;
}
}
if(error || result) break;
}
return result;
}
bool subghz_history_read_int32(Stream* stream, int32_t* _data, const uint16_t data_size) {
bool result = false;
result = true;
FuriString* value;
value = furi_string_alloc();
for(size_t i = 0; i < data_size; i++) {
bool last = false;
result = subghz_history_stream_read_value(stream, value, &last);
if(result) {
int scan_values = 0;
int32_t* data = _data;
scan_values = sscanf(furi_string_get_cstr(value), "%" PRIi32, &data[i]);
if(scan_values != 1) {
result = false;
break;
}
} else {
break;
}
if(last && ((i + 1) != data_size)) {
result = false;
break;
}
}
furi_string_free(value);
return result;
}
uint32_t subghz_history_rand_range(uint32_t min, uint32_t max) {
// size of range, inclusive
const uint32_t length_of_range = max - min + 1;
// add n so that we don't return a number below our range
return (uint32_t)(rand() % length_of_range + min);
}
bool subghz_history_write_file_noise(
Stream* file,
bool is_negative_start,
size_t current_position,
bool empty_line) {
size_t was_write = 0;
if(empty_line) {
was_write = stream_write_format(file, "%s: ", SUBGHZ_HISTORY_TMP_RAW_KEY);
if(was_write <= 0) {
FURI_LOG_E(TAG, "Can't write key!");
return false;
}
}
int8_t first;
int8_t second;
if(is_negative_start) {
first = -1;
second = 1;
} else {
first = 1;
second = -1;
}
while(current_position < MAX_LINE) {
was_write = stream_write_format(
file,
"%ld %ld ",
subghz_history_rand_range(
SUBGHZ_HISTORY_TMP_SIGNAL_MIN, SUBGHZ_HISTORY_TMP_SIGNAL_MAX) *
first,
subghz_history_rand_range(
SUBGHZ_HISTORY_TMP_SIGNAL_MIN, SUBGHZ_HISTORY_TMP_SIGNAL_MAX) *
second);
if(was_write <= 0) {
FURI_LOG_E(TAG, "Can't write random values!");
return false;
}
current_position += was_write;
}
// Step back to write \n instead of space
size_t offset = stream_tell(file);
if(stream_seek(file, offset - 1, StreamOffsetFromCurrent)) {
FURI_LOG_E(TAG, "Step back failed!");
return false;
}
return stream_write_char(file, flipper_format_eoln) > 0;
}
bool subghz_history_write_file_data(
Stream* src,
Stream* file,
bool* is_negative_start,
size_t* current_position) {
size_t offset_file = 0;
bool result = false;
int32_t value = 0;
do {
if(!subghz_history_read_int32(src, &value, 1)) {
result = true;
break;
}
offset_file = stream_tell(file);
stream_write_format(file, "%ld ", value);
*current_position += stream_tell(file) - offset_file;
if(*current_position > MAX_LINE) {
if((is_negative_start && value > 0) || (!is_negative_start && value < 0)) {
// Align values
continue;
}
if(stream_write_format(file, "\n%s: ", SUBGHZ_HISTORY_TMP_RAW_KEY) == 0) {
FURI_LOG_E(TAG, "Can't write new line!");
result = false;
break;
}
*current_position = 0;
}
} while(true);
*is_negative_start = value < 0;
return result;
}
bool subghz_history_tmp_write_file_split(
SubGhzHistory* instance,
void* current_item,
const char* dir_path) {
furi_assert(instance);
furi_assert(current_item);
furi_assert(dir_path);
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "Save temp file splitted: %s", dir_path);
#endif
SubGhzHistoryItem* item = (SubGhzHistoryItem*)current_item;
uint8_t buffer[buffer_size];
Stream* src = flipper_format_get_raw_stream(item->flipper_string);
stream_rewind(src);
FlipperFormat* flipper_format_file = flipper_format_file_alloc(instance->storage);
bool result = false;
FuriString* temp_str = furi_string_alloc();
do {
if(storage_file_exists(instance->storage, dir_path) &&
storage_common_remove(instance->storage, dir_path) != FSE_OK) {
FURI_LOG_E(TAG, "Can't delete old file!");
break;
}
path_extract_dirname(dir_path, temp_str);
FS_Error fs_result =
storage_common_mkdir(instance->storage, furi_string_get_cstr(temp_str));
if(fs_result != FSE_OK && fs_result != FSE_EXIST) {
FURI_LOG_E(TAG, "Can't create dir!");
break;
}
result = flipper_format_file_open_always(flipper_format_file, dir_path);
if(!result) {
FURI_LOG_E(TAG, "Can't open file for write!");
break;
}
Stream* file = flipper_format_get_raw_stream(flipper_format_file);
if(!subghz_history_stream_seek_to_key(src, SUBGHZ_HISTORY_TMP_RAW_KEY, false)) {
FURI_LOG_E(TAG, "Can't find key!");
break;
}
bool is_negative_start = false;
bool found = false;
size_t offset_start;
offset_start = stream_tell(src);
// Check for negative value at the start and end to align file by correct values
size_t was_read = stream_read(src, buffer, 1);
if(was_read <= 0) {
FURI_LOG_E(TAG, "Can't obtain first mark!");
break;
}
is_negative_start = buffer[0] == '-';
// Ready to write stream to file
size_t current_position;
stream_rewind(src);
current_position = stream_copy(src, file, offset_start);
if(current_position != offset_start) {
FURI_LOG_E(TAG, "Invalid copy header data from one stream to another!");
break;
}
found = true;
current_position = 0;
if(!subghz_history_write_file_noise(file, is_negative_start, current_position, false)) {
FURI_LOG_E(TAG, "Add start noise failed!");
break;
}
if(stream_write_format(file, "%s: ", SUBGHZ_HISTORY_TMP_RAW_KEY) == 0) {
FURI_LOG_E(TAG, "Can't write new line!");
result = false;
break;
}
if(!subghz_history_write_file_data(src, file, &is_negative_start, &current_position)) {
FURI_LOG_E(TAG, "Split by lines failed!");
break;
}
if(!subghz_history_write_file_noise(file, is_negative_start, current_position, false)) {
FURI_LOG_E(TAG, "Add end noise failed!");
break;
}
if(!subghz_history_write_file_noise(file, is_negative_start, 0, true)) {
FURI_LOG_E(TAG, "Add end noise failed!");
break;
}
result = found;
} while(false);
flipper_format_file_close(flipper_format_file);
flipper_format_free(flipper_format_file);
furi_string_free(temp_str);
item->is_file = result;
return result;
}
void subghz_history_tmp_write_file_full(
SubGhzHistory* instance,
void* current_item,
FuriString* dir_path) {
SubGhzHistoryItem* item = (SubGhzHistoryItem*)current_item;
#ifdef FURI_DEBUG
FURI_LOG_W(TAG, "Save temp file full: %s", furi_string_get_cstr(dir_path));
#endif
Stream* dst = flipper_format_get_raw_stream(item->flipper_string);
stream_rewind(dst);
if(stream_save_to_file(
dst, instance->storage, furi_string_get_cstr(dir_path), FSOM_CREATE_ALWAYS) > 0) {
#ifdef FURI_DEBUG
FURI_LOG_I(TAG, "Save done!");
#endif
// This item contains fake data to load from SD
item->is_file = true;
} else {
FURI_LOG_E(TAG, "Stream copy failed!");
}
}

View File

@ -1,8 +1,5 @@
#include "subghz_last_settings.h"
#include "subghz_i.h"
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
#include <lib/subghz/protocols/raw.h>
#endif
#define TAG "SubGhzLastSettings"
@ -16,11 +13,6 @@
#define SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_FEEDBACK_LEVEL 2
#define SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER -93.0f
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
#define SUBGHZ_LAST_SETTING_DEFAULT_READ_RAW 0
#define SUBGHZ_LAST_SETTING_FIELD_DETECT_RAW "DetectRaw"
#endif
#define SUBGHZ_LAST_SETTING_FIELD_FREQUENCY "Frequency"
//#define SUBGHZ_LAST_SETTING_FIELD_PRESET "Preset"
#define SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_FEEDBACK_LEVEL "FeedbackLevel"
@ -52,9 +44,6 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count
//int32_t temp_preset = 0;
bool frequency_analyzer_feedback_level_was_read = false;
bool frequency_analyzer_trigger_was_read = false;
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
uint32_t temp_read_raw = 0;
#endif
if(FSE_OK == storage_sd_status(storage) && SUBGHZ_LAST_SETTINGS_PATH &&
flipper_format_file_open_existing(fff_data_file, SUBGHZ_LAST_SETTINGS_PATH)) {
@ -73,10 +62,7 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count
SUBGHZ_LAST_SETTING_FIELD_FREQUENCY_ANALYZER_TRIGGER,
(float*)&temp_frequency_analyzer_trigger,
1);
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
flipper_format_read_uint32(
fff_data_file, SUBGHZ_LAST_SETTING_FIELD_DETECT_RAW, (uint32_t*)&temp_read_raw, 1);
#endif
} else {
FURI_LOG_E(TAG, "Error open file %s", SUBGHZ_LAST_SETTINGS_PATH);
}
@ -88,9 +74,7 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count
instance->frequency_analyzer_feedback_level =
SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_FEEDBACK_LEVEL;
instance->frequency_analyzer_trigger = SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER;
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
instance->detect_raw = SUBGHZ_LAST_SETTING_DEFAULT_READ_RAW;
#endif
} else {
instance->frequency = temp_frequency;
instance->frequency_analyzer_feedback_level =
@ -101,9 +85,6 @@ void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count
instance->frequency_analyzer_trigger = frequency_analyzer_trigger_was_read ?
temp_frequency_analyzer_trigger :
SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER;
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
instance->detect_raw = temp_read_raw;
#endif
/*if(temp_preset > (int32_t)preset_count - 1 || temp_preset < 0) {
FURI_LOG_W(TAG, "Last used preset no found");*/
@ -164,12 +145,6 @@ bool subghz_last_settings_save(SubGhzLastSettings* instance) {
1)) {
break;
}
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
if(!flipper_format_insert_or_update_uint32(
file, SUBGHZ_LAST_SETTING_FIELD_DETECT_RAW, &instance->detect_raw, 1)) {
break;
}
#endif
saved = true;
} while(0);
@ -183,17 +158,3 @@ bool subghz_last_settings_save(SubGhzLastSettings* instance) {
return saved;
}
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
void subghz_last_settings_set_detect_raw_values(void* context) {
furi_assert(context);
SubGhz* instance = (SubGhz*)context;
bool is_detect_raw = instance->last_settings->detect_raw > 0;
subghz_receiver_set_filter(
instance->txrx->receiver, is_detect_raw ? DETECT_RAW_TRUE : DETECT_RAW_FALSE);
subghz_protocol_decoder_raw_set_auto_mode(
subghz_receiver_search_decoder_base_by_name(
instance->txrx->receiver, SUBGHZ_PROTOCOL_RAW_NAME),
is_detect_raw);
}
#endif

View File

@ -1,23 +1,12 @@
#pragma once
// Enable saving detect raw setting state
// #define SUBGHZ_SAVE_DETECT_RAW_SETTING 1
#include <furi_hal.h>
#include <stdint.h>
#include <stdbool.h>
#include <storage/storage.h>
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
#include <lib/subghz/protocols/base.h>
#define DETECT_RAW_FALSE SubGhzProtocolFlag_Decodable
#define DETECT_RAW_TRUE SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_RAW
#endif
typedef struct {
uint32_t frequency;
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
uint32_t detect_raw;
#endif
int32_t preset;
uint32_t frequency_analyzer_feedback_level;
float frequency_analyzer_trigger;
@ -30,6 +19,3 @@ void subghz_last_settings_free(SubGhzLastSettings* instance);
void subghz_last_settings_load(SubGhzLastSettings* instance, size_t preset_count);
bool subghz_last_settings_save(SubGhzLastSettings* instance);
#ifdef SUBGHZ_SAVE_DETECT_RAW_SETTING
void subghz_last_settings_set_detect_raw_values(void* context);
#endif

View File

@ -15,7 +15,6 @@
#define TAG "BrowserWorker"
#define ASSETS_DIR "assets"
#define SUBGHZ_TEMP_DIR "tmp_history"
#define BROWSER_ROOT STORAGE_ANY_PATH_PREFIX
#define FILE_NAME_LEN_MAX 256
#define LONG_LOAD_THRESHOLD 100
@ -91,8 +90,7 @@ static bool browser_filter_by_name(BrowserWorker* browser, FuriString* name, boo
if(is_folder) {
// Skip assets folders (if enabled)
if(browser->skip_assets) {
return ((furi_string_cmp_str(name, ASSETS_DIR) == 0) ? (false) : (true)) &&
((furi_string_cmp_str(name, SUBGHZ_TEMP_DIR) == 0) ? (false) : (true));
return ((furi_string_cmp_str(name, ASSETS_DIR) == 0) ? (false) : (true));
} else {
return true;
}

View File

@ -2909,13 +2909,8 @@ Function,+,subghz_protocol_decoder_raw_alloc,void*,SubGhzEnvironment*
Function,+,subghz_protocol_decoder_raw_deserialize,_Bool,"void*, FlipperFormat*"
Function,+,subghz_protocol_decoder_raw_feed,void,"void*, _Bool, uint32_t"
Function,+,subghz_protocol_decoder_raw_free,void,void*
Function,+,subghz_protocol_decoder_raw_get_hash_data,uint8_t,void*
Function,+,subghz_protocol_decoder_raw_get_string,void,"void*, FuriString*"
Function,+,subghz_protocol_decoder_raw_reset,void,void*
Function,+,subghz_protocol_decoder_raw_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
Function,+,subghz_protocol_decoder_raw_set_auto_mode,void,"void*, _Bool"
Function,+,subghz_protocol_decoder_raw_set_rssi_threshold,void,"void*, int"
Function,+,subghz_protocol_decoder_raw_write_data,_Bool,"void*, _Bool, uint32_t"
Function,-,subghz_protocol_decoder_scher_khan_alloc,void*,SubGhzEnvironment*
Function,-,subghz_protocol_decoder_scher_khan_deserialize,_Bool,"void*, FlipperFormat*"
Function,-,subghz_protocol_decoder_scher_khan_feed,void,"void*, _Bool, uint32_t"
@ -3027,7 +3022,6 @@ Function,-,subghz_protocol_encoder_gate_tx_deserialize,_Bool,"void*, FlipperForm
Function,-,subghz_protocol_encoder_gate_tx_free,void,void*
Function,-,subghz_protocol_encoder_gate_tx_stop,void,void*
Function,-,subghz_protocol_encoder_gate_tx_yield,LevelDuration,void*
Function,-,subghz_protocol_encoder_get_rssi_threshold,int,void*
Function,-,subghz_protocol_encoder_holtek_alloc,void*,SubGhzEnvironment*
Function,-,subghz_protocol_encoder_holtek_deserialize,_Bool,"void*, FlipperFormat*"
Function,-,subghz_protocol_encoder_holtek_free,void,void*
@ -3175,7 +3169,6 @@ Function,-,subghz_protocol_star_line_create_data,_Bool,"void*, FlipperFormat*, u
Function,+,subghz_receiver_alloc_init,SubGhzReceiver*,SubGhzEnvironment*
Function,+,subghz_receiver_decode,void,"SubGhzReceiver*, _Bool, uint32_t"
Function,+,subghz_receiver_free,void,SubGhzReceiver*
Function,+,subghz_receiver_get_filter,SubGhzProtocolFlag,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"

1 entry status name type params
2909 Function + subghz_protocol_decoder_raw_deserialize _Bool void*, FlipperFormat*
2910 Function + subghz_protocol_decoder_raw_feed void void*, _Bool, uint32_t
2911 Function + subghz_protocol_decoder_raw_free void void*
Function + subghz_protocol_decoder_raw_get_hash_data uint8_t void*
2912 Function + subghz_protocol_decoder_raw_get_string void void*, FuriString*
2913 Function + subghz_protocol_decoder_raw_reset void void*
Function + subghz_protocol_decoder_raw_serialize _Bool void*, FlipperFormat*, SubGhzRadioPreset*
Function + subghz_protocol_decoder_raw_set_auto_mode void void*, _Bool
Function + subghz_protocol_decoder_raw_set_rssi_threshold void void*, int
Function + subghz_protocol_decoder_raw_write_data _Bool void*, _Bool, uint32_t
2914 Function - subghz_protocol_decoder_scher_khan_alloc void* SubGhzEnvironment*
2915 Function - subghz_protocol_decoder_scher_khan_deserialize _Bool void*, FlipperFormat*
2916 Function - subghz_protocol_decoder_scher_khan_feed void void*, _Bool, uint32_t
3022 Function - subghz_protocol_encoder_gate_tx_free void void*
3023 Function - subghz_protocol_encoder_gate_tx_stop void void*
3024 Function - subghz_protocol_encoder_gate_tx_yield LevelDuration void*
Function - subghz_protocol_encoder_get_rssi_threshold int void*
3025 Function - subghz_protocol_encoder_holtek_alloc void* SubGhzEnvironment*
3026 Function - subghz_protocol_encoder_holtek_deserialize _Bool void*, FlipperFormat*
3027 Function - subghz_protocol_encoder_holtek_free void void*
3169 Function + subghz_receiver_alloc_init SubGhzReceiver* SubGhzEnvironment*
3170 Function + subghz_receiver_decode void SubGhzReceiver*, _Bool, uint32_t
3171 Function + subghz_receiver_free void SubGhzReceiver*
Function + subghz_receiver_get_filter SubGhzProtocolFlag SubGhzReceiver*
3172 Function + subghz_receiver_reset void SubGhzReceiver*
3173 Function + subghz_receiver_search_decoder_base_by_name SubGhzProtocolDecoderBase* SubGhzReceiver*, const char*
3174 Function + subghz_receiver_set_filter void SubGhzReceiver*, SubGhzProtocolFlag

View File

@ -8,16 +8,11 @@
#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 40
static const SubGhzBlockConst subghz_protocol_raw_const = {
.te_short = 50,
@ -29,8 +24,6 @@ static const SubGhzBlockConst subghz_protocol_raw_const = {
struct SubGhzProtocolDecoderRAW {
SubGhzProtocolDecoderBase base;
SubGhzBlockDecoder decoder;
int32_t* upload_raw;
uint16_t ind_write;
Storage* storage;
@ -39,10 +32,6 @@ struct SubGhzProtocolDecoderRAW {
FuriString* file_name;
size_t sample_write;
bool last_level;
bool auto_mode;
bool has_rssi_above_threshold;
int rssi_threshold;
uint8_t postroll_frames;
bool pause;
};
@ -67,8 +56,8 @@ const SubGhzProtocolDecoder subghz_protocol_raw_decoder = {
.feed = subghz_protocol_decoder_raw_feed,
.reset = subghz_protocol_decoder_raw_reset,
.get_hash_data = subghz_protocol_decoder_raw_get_hash_data,
.serialize = subghz_protocol_decoder_raw_serialize,
.get_hash_data = NULL,
.serialize = NULL,
.deserialize = subghz_protocol_decoder_raw_deserialize,
.get_string = subghz_protocol_decoder_raw_get_string,
};
@ -213,36 +202,6 @@ 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);
}
void subghz_protocol_raw_save_to_file_pause(SubGhzProtocolDecoderRAW* instance, bool pause) {
furi_assert(instance);
@ -263,8 +222,6 @@ 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;
instance->file_name = furi_string_alloc();
return instance;
@ -274,10 +231,6 @@ void subghz_protocol_decoder_raw_free(void* context) {
furi_assert(context);
SubGhzProtocolDecoderRAW* instance = context;
furi_string_free(instance->file_name);
if(instance->upload_raw != NULL) {
free(instance->upload_raw);
instance->upload_raw = NULL;
}
free(instance);
}
@ -285,66 +238,23 @@ 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 && !instance->pause &&
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->pause && (instance->upload_raw != NULL)) {
if(duration > subghz_protocol_raw_const.te_short) {
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);
}
}
}
@ -357,13 +267,6 @@ 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, FuriString* output) {
furi_assert(context);
//SubGhzProtocolDecoderRAW* instance = context;
@ -382,13 +285,6 @@ 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;
@ -446,70 +342,6 @@ 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,
SubGhzRadioPreset* preset) {
furi_assert(context);
SubGhzProtocolDecoderRAW* instance = context;
if(instance->auto_mode) {
furi_assert(instance);
bool res = false;
FuriString* temp_str;
temp_str = furi_string_alloc();
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(furi_string_get_cstr(preset->name), temp_str);
if(!flipper_format_write_string_cstr(
flipper_format, "Preset", furi_string_get_cstr(temp_str))) {
FURI_LOG_E(TAG, "Unable to add Preset");
break;
}
if(!strcmp(furi_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);
furi_string_free(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,8 +2,6 @@
#include "base.h"
#include <furi_hal.h>
#define SUBGHZ_PROTOCOL_RAW_NAME "RAW"
#ifdef __cplusplus
@ -31,27 +29,6 @@ bool subghz_protocol_raw_save_to_file_init(
const char* dev_name,
SubGhzRadioPreset* 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
@ -84,15 +61,6 @@ 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
@ -103,19 +71,12 @@ 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
@ -167,19 +128,6 @@ 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,
SubGhzRadioPreset* preset);
/**
* Deserialize and generating an upload to send.
* @param context Pointer to a SubGhzProtocolEncoderRAW instance
@ -191,7 +139,7 @@ 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

@ -64,7 +64,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) != 0) {
if((slot->base->protocol->flag & instance->filter) == instance->filter) {
slot->base->protocol->decoder->feed(slot->base, level, duration);
}
}
@ -108,11 +108,6 @@ 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

@ -59,13 +59,6 @@ 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