SubGhz: add protocol BinRAW (binarization of data quantized by the minimum correlated duration) (#2322)
* SubGhz: add protocol DataRAW (binarization of data quantized by the minimum correlated duration) * SubGhz: fix name history * SubGhz: add encoder Data_RAW protocol * SubGhz: decreasing the size of the LevelDuration structure * SubGhz: history, added check that there is free RAM * SubGhz: checking for free memory, support to pass without gap * SubGhz: add running average to average the result, auto cut noise at the end of a burst * SubGhz: support for repeating sequences * SubGhz: fix secplus_v2 decoder * SubGhz: bin_RAW fix add history * SubGhz: add debug * SubGhz: debug refactoring * FURI_LOG: add FURI_LOG_RAW_x formatted string output like printf * SubGhz: fix new FURI_LOG metod * FURI_LOG: fix unit test * SubGhz: add enable/disable BinRAW protocol decoding * SubGhz: fix PVS * SubGhz: forcibly turn off the speaker when exiting SubGhz * SubGhz: adaptive adjustment to the noise level Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
parent
71871949ec
commit
163be139eb
@ -70,7 +70,7 @@ void minunit_print_progress() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void minunit_print_fail(const char* str) {
|
void minunit_print_fail(const char* str) {
|
||||||
printf(FURI_LOG_CLR_E "%s\r\n" FURI_LOG_CLR_RESET, str);
|
printf(_FURI_LOG_CLR_E "%s\r\n" _FURI_LOG_CLR_RESET, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unit_tests_cli(Cli* cli, FuriString* args, void* context) {
|
void unit_tests_cli(Cli* cli, FuriString* args, void* context) {
|
||||||
|
@ -12,7 +12,7 @@ App(
|
|||||||
],
|
],
|
||||||
provides=["subghz_start"],
|
provides=["subghz_start"],
|
||||||
icon="A_Sub1ghz_14",
|
icon="A_Sub1ghz_14",
|
||||||
stack_size=2 * 1024,
|
stack_size=3 * 1024,
|
||||||
order=10,
|
order=10,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -411,5 +411,5 @@ void subghz_scene_read_raw_on_exit(void* context) {
|
|||||||
notification_message(subghz->notifications, &sequence_reset_rgb);
|
notification_message(subghz->notifications, &sequence_reset_rgb);
|
||||||
|
|
||||||
//filter restoration
|
//filter restoration
|
||||||
subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_Decodable);
|
subghz_receiver_set_filter(subghz->txrx->receiver, subghz->txrx->filter);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "../subghz_i.h"
|
#include "../subghz_i.h"
|
||||||
#include "../views/receiver.h"
|
#include "../views/receiver.h"
|
||||||
#include <dolphin/dolphin.h>
|
#include <dolphin/dolphin.h>
|
||||||
|
#include <lib/subghz/protocols/bin_raw.h>
|
||||||
|
|
||||||
static const NotificationSequence subghs_sequence_rx = {
|
static const NotificationSequence subghs_sequence_rx = {
|
||||||
&message_green_255,
|
&message_green_255,
|
||||||
@ -143,6 +144,11 @@ void subghz_scene_receiver_on_enter(void* context) {
|
|||||||
}
|
}
|
||||||
subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, subghz->txrx->idx_menu_chosen);
|
subghz_view_receiver_set_idx_menu(subghz->subghz_receiver, subghz->txrx->idx_menu_chosen);
|
||||||
|
|
||||||
|
//to use a universal decoder, we are looking for a link to it
|
||||||
|
subghz->txrx->decoder_result = subghz_receiver_search_decoder_base_by_name(
|
||||||
|
subghz->txrx->receiver, SUBGHZ_PROTOCOL_BIN_RAW_NAME);
|
||||||
|
furi_assert(subghz->txrx->decoder_result);
|
||||||
|
|
||||||
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdReceiver);
|
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdReceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,6 +214,13 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) {
|
|||||||
subghz_hopper_update(subghz);
|
subghz_hopper_update(subghz);
|
||||||
subghz_scene_receiver_update_statusbar(subghz);
|
subghz_scene_receiver_update_statusbar(subghz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//get RSSI
|
||||||
|
float rssi = furi_hal_subghz_get_rssi();
|
||||||
|
subghz_receiver_rssi(subghz->subghz_receiver, rssi);
|
||||||
|
subghz_protocol_decoder_bin_raw_data_input_rssi(
|
||||||
|
(SubGhzProtocolDecoderBinRAW*)subghz->txrx->decoder_result, rssi);
|
||||||
|
|
||||||
switch(subghz->state_notifications) {
|
switch(subghz->state_notifications) {
|
||||||
case SubGhzNotificationStateRx:
|
case SubGhzNotificationStateRx:
|
||||||
notification_message(subghz->notifications, &sequence_blink_cyan_10);
|
notification_message(subghz->notifications, &sequence_blink_cyan_10);
|
||||||
|
@ -5,6 +5,7 @@ enum SubGhzSettingIndex {
|
|||||||
SubGhzSettingIndexFrequency,
|
SubGhzSettingIndexFrequency,
|
||||||
SubGhzSettingIndexHopping,
|
SubGhzSettingIndexHopping,
|
||||||
SubGhzSettingIndexModulation,
|
SubGhzSettingIndexModulation,
|
||||||
|
SubGhzSettingIndexBinRAW,
|
||||||
SubGhzSettingIndexSound,
|
SubGhzSettingIndexSound,
|
||||||
SubGhzSettingIndexLock,
|
SubGhzSettingIndexLock,
|
||||||
SubGhzSettingIndexRAWThesholdRSSI,
|
SubGhzSettingIndexRAWThesholdRSSI,
|
||||||
@ -58,6 +59,15 @@ const uint32_t speaker_value[SPEAKER_COUNT] = {
|
|||||||
SubGhzSpeakerStateShutdown,
|
SubGhzSpeakerStateShutdown,
|
||||||
SubGhzSpeakerStateEnable,
|
SubGhzSpeakerStateEnable,
|
||||||
};
|
};
|
||||||
|
#define BIN_RAW_COUNT 2
|
||||||
|
const char* const bin_raw_text[BIN_RAW_COUNT] = {
|
||||||
|
"OFF",
|
||||||
|
"ON",
|
||||||
|
};
|
||||||
|
const uint32_t bin_raw_value[BIN_RAW_COUNT] = {
|
||||||
|
SubGhzProtocolFlag_Decodable,
|
||||||
|
SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_BinRAW,
|
||||||
|
};
|
||||||
|
|
||||||
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);
|
||||||
@ -186,6 +196,15 @@ static void subghz_scene_receiver_config_set_speaker(VariableItem* item) {
|
|||||||
subghz->txrx->speaker_state = speaker_value[index];
|
subghz->txrx->speaker_state = speaker_value[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void subghz_scene_receiver_config_set_bin_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, bin_raw_text[index]);
|
||||||
|
subghz->txrx->filter = bin_raw_value[index];
|
||||||
|
subghz_receiver_set_filter(subghz->txrx->receiver, subghz->txrx->filter);
|
||||||
|
}
|
||||||
|
|
||||||
static void subghz_scene_receiver_config_set_raw_threshold_rssi(VariableItem* item) {
|
static void subghz_scene_receiver_config_set_raw_threshold_rssi(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);
|
||||||
@ -254,6 +273,19 @@ 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,
|
||||||
|
"Bin_RAW:",
|
||||||
|
BIN_RAW_COUNT,
|
||||||
|
subghz_scene_receiver_config_set_bin_raw,
|
||||||
|
subghz);
|
||||||
|
value_index = value_index_uint32(subghz->txrx->filter, bin_raw_value, BIN_RAW_COUNT);
|
||||||
|
variable_item_set_current_value_index(item, value_index);
|
||||||
|
variable_item_set_current_value_text(item, bin_raw_text[value_index]);
|
||||||
|
}
|
||||||
|
|
||||||
item = variable_item_list_add(
|
item = variable_item_list_add(
|
||||||
subghz->variable_item_list,
|
subghz->variable_item_list,
|
||||||
"Sound:",
|
"Sound:",
|
||||||
|
@ -194,7 +194,8 @@ SubGhz* subghz_alloc() {
|
|||||||
subghz_environment_set_protocol_registry(
|
subghz_environment_set_protocol_registry(
|
||||||
subghz->txrx->environment, (void*)&subghz_protocol_registry);
|
subghz->txrx->environment, (void*)&subghz_protocol_registry);
|
||||||
subghz->txrx->receiver = subghz_receiver_alloc_init(subghz->txrx->environment);
|
subghz->txrx->receiver = subghz_receiver_alloc_init(subghz->txrx->environment);
|
||||||
subghz_receiver_set_filter(subghz->txrx->receiver, SubGhzProtocolFlag_Decodable);
|
subghz->txrx->filter = SubGhzProtocolFlag_Decodable;
|
||||||
|
subghz_receiver_set_filter(subghz->txrx->receiver, subghz->txrx->filter);
|
||||||
|
|
||||||
subghz_worker_set_overrun_callback(
|
subghz_worker_set_overrun_callback(
|
||||||
subghz->txrx->worker, (SubGhzWorkerOverrunCallback)subghz_receiver_reset);
|
subghz->txrx->worker, (SubGhzWorkerOverrunCallback)subghz_receiver_reset);
|
||||||
@ -218,6 +219,8 @@ void subghz_free(SubGhz* subghz) {
|
|||||||
subghz->rpc_ctx = NULL;
|
subghz->rpc_ctx = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
subghz_speaker_off(subghz);
|
||||||
|
|
||||||
// Packet Test
|
// Packet Test
|
||||||
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdTestPacket);
|
view_dispatcher_remove_view(subghz->view_dispatcher, SubGhzViewIdTestPacket);
|
||||||
subghz_test_packet_free(subghz->subghz_test_packet);
|
subghz_test_packet_free(subghz->subghz_test_packet);
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
|
||||||
#define SUBGHZ_HISTORY_MAX 50
|
#define SUBGHZ_HISTORY_MAX 50
|
||||||
|
#define SUBGHZ_HISTORY_FREE_HEAP 20480
|
||||||
#define TAG "SubGhzHistory"
|
#define TAG "SubGhzHistory"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -121,8 +122,12 @@ FlipperFormat* subghz_history_get_raw_data(SubGhzHistory* instance, uint16_t idx
|
|||||||
}
|
}
|
||||||
bool subghz_history_get_text_space_left(SubGhzHistory* instance, FuriString* output) {
|
bool subghz_history_get_text_space_left(SubGhzHistory* instance, FuriString* output) {
|
||||||
furi_assert(instance);
|
furi_assert(instance);
|
||||||
|
if(memmgr_get_free_heap() < SUBGHZ_HISTORY_FREE_HEAP) {
|
||||||
|
if(output != NULL) furi_string_printf(output, " Free heap LOW");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if(instance->last_index_write == SUBGHZ_HISTORY_MAX) {
|
if(instance->last_index_write == SUBGHZ_HISTORY_MAX) {
|
||||||
if(output != NULL) furi_string_printf(output, "Memory is FULL");
|
if(output != NULL) furi_string_printf(output, " Memory is FULL");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if(output != NULL)
|
if(output != NULL)
|
||||||
@ -142,6 +147,7 @@ bool subghz_history_add_to_history(
|
|||||||
furi_assert(instance);
|
furi_assert(instance);
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
|
|
||||||
|
if(memmgr_get_free_heap() < SUBGHZ_HISTORY_FREE_HEAP) return false;
|
||||||
if(instance->last_index_write >= SUBGHZ_HISTORY_MAX) return false;
|
if(instance->last_index_write >= SUBGHZ_HISTORY_MAX) return false;
|
||||||
|
|
||||||
SubGhzProtocolDecoderBase* decoder_base = context;
|
SubGhzProtocolDecoderBase* decoder_base = context;
|
||||||
@ -200,13 +206,13 @@ bool subghz_history_add_to_history(
|
|||||||
}
|
}
|
||||||
uint8_t key_data[sizeof(uint64_t)] = {0};
|
uint8_t key_data[sizeof(uint64_t)] = {0};
|
||||||
if(!flipper_format_read_hex(item->flipper_string, "Key", key_data, sizeof(uint64_t))) {
|
if(!flipper_format_read_hex(item->flipper_string, "Key", key_data, sizeof(uint64_t))) {
|
||||||
FURI_LOG_E(TAG, "Missing Key");
|
FURI_LOG_D(TAG, "No Key");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
uint64_t data = 0;
|
uint64_t data = 0;
|
||||||
for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
|
for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
|
||||||
data = (data << 8) | key_data[i];
|
data = (data << 8) | key_data[i];
|
||||||
}
|
}
|
||||||
|
if(data != 0) {
|
||||||
if(!(uint32_t)(data >> 32)) {
|
if(!(uint32_t)(data >> 32)) {
|
||||||
furi_string_printf(
|
furi_string_printf(
|
||||||
item->item_str,
|
item->item_str,
|
||||||
@ -221,6 +227,10 @@ bool subghz_history_add_to_history(
|
|||||||
(uint32_t)(data >> 32),
|
(uint32_t)(data >> 32),
|
||||||
(uint32_t)(data & 0xFFFFFFFF));
|
(uint32_t)(data & 0xFFFFFFFF));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
furi_string_printf(item->item_str, "%s", furi_string_get_cstr(instance->tmp_string));
|
||||||
|
}
|
||||||
|
|
||||||
} while(false);
|
} while(false);
|
||||||
|
|
||||||
furi_string_free(text);
|
furi_string_free(text);
|
||||||
|
@ -45,6 +45,7 @@ struct SubGhzTxRx {
|
|||||||
SubGhzEnvironment* environment;
|
SubGhzEnvironment* environment;
|
||||||
SubGhzReceiver* receiver;
|
SubGhzReceiver* receiver;
|
||||||
SubGhzTransmitter* transmitter;
|
SubGhzTransmitter* transmitter;
|
||||||
|
SubGhzProtocolFlag filter;
|
||||||
SubGhzProtocolDecoderBase* decoder_result;
|
SubGhzProtocolDecoderBase* decoder_result;
|
||||||
FlipperFormat* fff_data;
|
FlipperFormat* fff_data;
|
||||||
|
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
#define MENU_ITEMS 4u
|
#define MENU_ITEMS 4u
|
||||||
#define UNLOCK_CNT 3
|
#define UNLOCK_CNT 3
|
||||||
|
|
||||||
|
#define SUBGHZ_RAW_TRESHOLD_MIN -90.0f
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
FuriString* item_str;
|
FuriString* item_str;
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
@ -59,8 +61,24 @@ typedef struct {
|
|||||||
uint16_t list_offset;
|
uint16_t list_offset;
|
||||||
uint16_t history_item;
|
uint16_t history_item;
|
||||||
SubGhzViewReceiverBarShow bar_show;
|
SubGhzViewReceiverBarShow bar_show;
|
||||||
|
uint8_t u_rssi;
|
||||||
} SubGhzViewReceiverModel;
|
} SubGhzViewReceiverModel;
|
||||||
|
|
||||||
|
void subghz_receiver_rssi(SubGhzViewReceiver* instance, float rssi) {
|
||||||
|
furi_assert(instance);
|
||||||
|
with_view_model(
|
||||||
|
instance->view,
|
||||||
|
SubGhzViewReceiverModel * model,
|
||||||
|
{
|
||||||
|
if(rssi < SUBGHZ_RAW_TRESHOLD_MIN) {
|
||||||
|
model->u_rssi = 0;
|
||||||
|
} else {
|
||||||
|
model->u_rssi = (uint8_t)(rssi - SUBGHZ_RAW_TRESHOLD_MIN);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
void subghz_view_receiver_set_lock(SubGhzViewReceiver* subghz_receiver, SubGhzLock lock) {
|
void subghz_view_receiver_set_lock(SubGhzViewReceiver* subghz_receiver, SubGhzLock lock) {
|
||||||
furi_assert(subghz_receiver);
|
furi_assert(subghz_receiver);
|
||||||
subghz_receiver->lock_count = 0;
|
subghz_receiver->lock_count = 0;
|
||||||
@ -168,13 +186,22 @@ static void subghz_view_receiver_draw_frame(Canvas* canvas, uint16_t idx, bool s
|
|||||||
canvas_draw_dot(canvas, scrollbar ? 121 : 126, (0 + idx * FRAME_HEIGHT) + 11);
|
canvas_draw_dot(canvas, scrollbar ? 121 : 126, (0 + idx * FRAME_HEIGHT) + 11);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void subghz_view_rssi_draw(Canvas* canvas, SubGhzViewReceiverModel* model) {
|
||||||
|
for(uint8_t i = 1; i < model->u_rssi; i++) {
|
||||||
|
if(i % 5) {
|
||||||
|
canvas_draw_dot(canvas, 46 + i, 50);
|
||||||
|
canvas_draw_dot(canvas, 47 + i, 51);
|
||||||
|
canvas_draw_dot(canvas, 46 + i, 52);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) {
|
void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) {
|
||||||
canvas_clear(canvas);
|
canvas_clear(canvas);
|
||||||
canvas_set_color(canvas, ColorBlack);
|
canvas_set_color(canvas, ColorBlack);
|
||||||
canvas_set_font(canvas, FontSecondary);
|
canvas_set_font(canvas, FontSecondary);
|
||||||
|
|
||||||
elements_button_left(canvas, "Config");
|
elements_button_left(canvas, "Config");
|
||||||
canvas_draw_line(canvas, 46, 51, 125, 51);
|
|
||||||
|
|
||||||
bool scrollbar = model->history_item > 4;
|
bool scrollbar = model->history_item > 4;
|
||||||
FuriString* str_buff;
|
FuriString* str_buff;
|
||||||
@ -206,11 +233,11 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) {
|
|||||||
if(model->history_item == 0) {
|
if(model->history_item == 0) {
|
||||||
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, "Scanning...");
|
canvas_draw_str(canvas, 63, 44, "Scanning...");
|
||||||
canvas_draw_line(canvas, 46, 51, 125, 51);
|
|
||||||
canvas_set_font(canvas, FontSecondary);
|
canvas_set_font(canvas, FontSecondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
subghz_view_rssi_draw(canvas, model);
|
||||||
switch(model->bar_show) {
|
switch(model->bar_show) {
|
||||||
case SubGhzViewReceiverBarShowLock:
|
case SubGhzViewReceiverBarShowLock:
|
||||||
canvas_draw_icon(canvas, 64, 55, &I_Lock_7x8);
|
canvas_draw_icon(canvas, 64, 55, &I_Lock_7x8);
|
||||||
|
@ -8,6 +8,8 @@ typedef struct SubGhzViewReceiver SubGhzViewReceiver;
|
|||||||
|
|
||||||
typedef void (*SubGhzViewReceiverCallback)(SubGhzCustomEvent event, void* context);
|
typedef void (*SubGhzViewReceiverCallback)(SubGhzCustomEvent event, void* context);
|
||||||
|
|
||||||
|
void subghz_receiver_rssi(SubGhzViewReceiver* instance, float rssi);
|
||||||
|
|
||||||
void subghz_view_receiver_set_lock(SubGhzViewReceiver* subghz_receiver, SubGhzLock keyboard);
|
void subghz_view_receiver_set_lock(SubGhzViewReceiver* subghz_receiver, SubGhzLock keyboard);
|
||||||
|
|
||||||
void subghz_view_receiver_set_callback(
|
void subghz_view_receiver_set_callback(
|
||||||
|
@ -79,7 +79,6 @@ void subghz_frequency_analyzer_draw_rssi(Canvas* canvas, uint8_t rssi, uint8_t x
|
|||||||
void subghz_frequency_analyzer_draw_log_rssi(Canvas* canvas, uint8_t rssi, uint8_t x, uint8_t y) {
|
void subghz_frequency_analyzer_draw_log_rssi(Canvas* canvas, uint8_t rssi, uint8_t x, uint8_t y) {
|
||||||
uint8_t column_height = 6;
|
uint8_t column_height = 6;
|
||||||
if(rssi) {
|
if(rssi) {
|
||||||
//rssi = rssi
|
|
||||||
if(rssi > 54) rssi = 54;
|
if(rssi > 54) rssi = 54;
|
||||||
for(uint8_t i = 1; i < rssi; i++) {
|
for(uint8_t i = 1; i < rssi; i++) {
|
||||||
if(i % 5) {
|
if(i % 5) {
|
||||||
|
@ -84,9 +84,10 @@ void subghz_view_transmitter_draw(Canvas* canvas, SubGhzViewTransmitterModel* mo
|
|||||||
canvas_clear(canvas);
|
canvas_clear(canvas);
|
||||||
canvas_set_color(canvas, ColorBlack);
|
canvas_set_color(canvas, ColorBlack);
|
||||||
canvas_set_font(canvas, FontSecondary);
|
canvas_set_font(canvas, FontSecondary);
|
||||||
elements_multiline_text(canvas, 0, 8, furi_string_get_cstr(model->key_str));
|
elements_multiline_text_aligned(
|
||||||
canvas_draw_str(canvas, 78, 8, furi_string_get_cstr(model->frequency_str));
|
canvas, 0, 0, AlignLeft, AlignTop, furi_string_get_cstr(model->key_str));
|
||||||
canvas_draw_str(canvas, 113, 8, furi_string_get_cstr(model->preset_str));
|
canvas_draw_str(canvas, 78, 7, furi_string_get_cstr(model->frequency_str));
|
||||||
|
canvas_draw_str(canvas, 113, 7, furi_string_get_cstr(model->preset_str));
|
||||||
if(model->show_button) subghz_view_transmitter_button_right(canvas, "Send");
|
if(model->show_button) subghz_view_transmitter_button_right(canvas, "Send");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1409,6 +1409,7 @@ Function,+,furi_kernel_unlock,int32_t,
|
|||||||
Function,+,furi_log_get_level,FuriLogLevel,
|
Function,+,furi_log_get_level,FuriLogLevel,
|
||||||
Function,-,furi_log_init,void,
|
Function,-,furi_log_init,void,
|
||||||
Function,+,furi_log_print_format,void,"FuriLogLevel, const char*, const char*, ..."
|
Function,+,furi_log_print_format,void,"FuriLogLevel, const char*, const char*, ..."
|
||||||
|
Function,+,furi_log_print_raw_format,void,"FuriLogLevel, const char*, ..."
|
||||||
Function,+,furi_log_set_level,void,FuriLogLevel
|
Function,+,furi_log_set_level,void,FuriLogLevel
|
||||||
Function,-,furi_log_set_puts,void,FuriLogPuts
|
Function,-,furi_log_set_puts,void,FuriLogPuts
|
||||||
Function,-,furi_log_set_timestamp,void,FuriLogTimestamp
|
Function,-,furi_log_set_timestamp,void,FuriLogTimestamp
|
||||||
@ -2599,7 +2600,7 @@ Function,+,subghz_protocol_blocks_crc8le,uint8_t,"const uint8_t[], size_t, uint8
|
|||||||
Function,+,subghz_protocol_blocks_get_bit_array,_Bool,"uint8_t[], size_t"
|
Function,+,subghz_protocol_blocks_get_bit_array,_Bool,"uint8_t[], size_t"
|
||||||
Function,+,subghz_protocol_blocks_get_hash_data,uint8_t,"SubGhzBlockDecoder*, size_t"
|
Function,+,subghz_protocol_blocks_get_hash_data,uint8_t,"SubGhzBlockDecoder*, size_t"
|
||||||
Function,+,subghz_protocol_blocks_get_parity,uint8_t,"uint64_t, uint8_t"
|
Function,+,subghz_protocol_blocks_get_parity,uint8_t,"uint64_t, uint8_t"
|
||||||
Function,+,subghz_protocol_blocks_get_upload,size_t,"uint8_t[], size_t, LevelDuration*, size_t, uint32_t"
|
Function,+,subghz_protocol_blocks_get_upload_from_bit_array,size_t,"uint8_t[], size_t, LevelDuration*, size_t, uint32_t, SubGhzProtocolBlockAlignBit"
|
||||||
Function,+,subghz_protocol_blocks_lfsr_digest16,uint16_t,"const uint8_t[], size_t, uint16_t, uint16_t"
|
Function,+,subghz_protocol_blocks_lfsr_digest16,uint16_t,"const uint8_t[], size_t, uint16_t, uint16_t"
|
||||||
Function,+,subghz_protocol_blocks_lfsr_digest8,uint8_t,"const uint8_t[], size_t, uint8_t, uint8_t"
|
Function,+,subghz_protocol_blocks_lfsr_digest8,uint8_t,"const uint8_t[], size_t, uint8_t, uint8_t"
|
||||||
Function,+,subghz_protocol_blocks_lfsr_digest8_reflect,uint8_t,"const uint8_t[], size_t, uint8_t, uint8_t"
|
Function,+,subghz_protocol_blocks_lfsr_digest8_reflect,uint8_t,"const uint8_t[], size_t, uint8_t, uint8_t"
|
||||||
|
|
@ -28,27 +28,27 @@ void furi_log_print_format(FuriLogLevel level, const char* tag, const char* form
|
|||||||
FuriString* string;
|
FuriString* string;
|
||||||
string = furi_string_alloc();
|
string = furi_string_alloc();
|
||||||
|
|
||||||
const char* color = FURI_LOG_CLR_RESET;
|
const char* color = _FURI_LOG_CLR_RESET;
|
||||||
const char* log_letter = " ";
|
const char* log_letter = " ";
|
||||||
switch(level) {
|
switch(level) {
|
||||||
case FuriLogLevelError:
|
case FuriLogLevelError:
|
||||||
color = FURI_LOG_CLR_E;
|
color = _FURI_LOG_CLR_E;
|
||||||
log_letter = "E";
|
log_letter = "E";
|
||||||
break;
|
break;
|
||||||
case FuriLogLevelWarn:
|
case FuriLogLevelWarn:
|
||||||
color = FURI_LOG_CLR_W;
|
color = _FURI_LOG_CLR_W;
|
||||||
log_letter = "W";
|
log_letter = "W";
|
||||||
break;
|
break;
|
||||||
case FuriLogLevelInfo:
|
case FuriLogLevelInfo:
|
||||||
color = FURI_LOG_CLR_I;
|
color = _FURI_LOG_CLR_I;
|
||||||
log_letter = "I";
|
log_letter = "I";
|
||||||
break;
|
break;
|
||||||
case FuriLogLevelDebug:
|
case FuriLogLevelDebug:
|
||||||
color = FURI_LOG_CLR_D;
|
color = _FURI_LOG_CLR_D;
|
||||||
log_letter = "D";
|
log_letter = "D";
|
||||||
break;
|
break;
|
||||||
case FuriLogLevelTrace:
|
case FuriLogLevelTrace:
|
||||||
color = FURI_LOG_CLR_T;
|
color = _FURI_LOG_CLR_T;
|
||||||
log_letter = "T";
|
log_letter = "T";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -58,7 +58,7 @@ void furi_log_print_format(FuriLogLevel level, const char* tag, const char* form
|
|||||||
// Timestamp
|
// Timestamp
|
||||||
furi_string_printf(
|
furi_string_printf(
|
||||||
string,
|
string,
|
||||||
"%lu %s[%s][%s] " FURI_LOG_CLR_RESET,
|
"%lu %s[%s][%s] " _FURI_LOG_CLR_RESET,
|
||||||
furi_log.timestamp(),
|
furi_log.timestamp(),
|
||||||
color,
|
color,
|
||||||
log_letter,
|
log_letter,
|
||||||
@ -80,6 +80,23 @@ void furi_log_print_format(FuriLogLevel level, const char* tag, const char* form
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void furi_log_print_raw_format(FuriLogLevel level, const char* format, ...) {
|
||||||
|
if(level <= furi_log.log_level &&
|
||||||
|
furi_mutex_acquire(furi_log.mutex, FuriWaitForever) == FuriStatusOk) {
|
||||||
|
FuriString* string;
|
||||||
|
string = furi_string_alloc();
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
furi_string_vprintf(string, format, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
furi_log.puts(furi_string_get_cstr(string));
|
||||||
|
furi_string_free(string);
|
||||||
|
|
||||||
|
furi_mutex_release(furi_log.mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void furi_log_set_level(FuriLogLevel level) {
|
void furi_log_set_level(FuriLogLevel level) {
|
||||||
if(level == FuriLogLevelDefault) {
|
if(level == FuriLogLevelDefault) {
|
||||||
level = FURI_LOG_LEVEL_DEFAULT;
|
level = FURI_LOG_LEVEL_DEFAULT;
|
||||||
|
@ -22,21 +22,21 @@ typedef enum {
|
|||||||
FuriLogLevelTrace = 6,
|
FuriLogLevelTrace = 6,
|
||||||
} FuriLogLevel;
|
} FuriLogLevel;
|
||||||
|
|
||||||
#define FURI_LOG_CLR(clr) "\033[0;" clr "m"
|
#define _FURI_LOG_CLR(clr) "\033[0;" clr "m"
|
||||||
#define FURI_LOG_CLR_RESET "\033[0m"
|
#define _FURI_LOG_CLR_RESET "\033[0m"
|
||||||
|
|
||||||
#define FURI_LOG_CLR_BLACK "30"
|
#define _FURI_LOG_CLR_BLACK "30"
|
||||||
#define FURI_LOG_CLR_RED "31"
|
#define _FURI_LOG_CLR_RED "31"
|
||||||
#define FURI_LOG_CLR_GREEN "32"
|
#define _FURI_LOG_CLR_GREEN "32"
|
||||||
#define FURI_LOG_CLR_BROWN "33"
|
#define _FURI_LOG_CLR_BROWN "33"
|
||||||
#define FURI_LOG_CLR_BLUE "34"
|
#define _FURI_LOG_CLR_BLUE "34"
|
||||||
#define FURI_LOG_CLR_PURPLE "35"
|
#define _FURI_LOG_CLR_PURPLE "35"
|
||||||
|
|
||||||
#define FURI_LOG_CLR_E FURI_LOG_CLR(FURI_LOG_CLR_RED)
|
#define _FURI_LOG_CLR_E _FURI_LOG_CLR(_FURI_LOG_CLR_RED)
|
||||||
#define FURI_LOG_CLR_W FURI_LOG_CLR(FURI_LOG_CLR_BROWN)
|
#define _FURI_LOG_CLR_W _FURI_LOG_CLR(_FURI_LOG_CLR_BROWN)
|
||||||
#define FURI_LOG_CLR_I FURI_LOG_CLR(FURI_LOG_CLR_GREEN)
|
#define _FURI_LOG_CLR_I _FURI_LOG_CLR(_FURI_LOG_CLR_GREEN)
|
||||||
#define FURI_LOG_CLR_D FURI_LOG_CLR(FURI_LOG_CLR_BLUE)
|
#define _FURI_LOG_CLR_D _FURI_LOG_CLR(_FURI_LOG_CLR_BLUE)
|
||||||
#define FURI_LOG_CLR_T FURI_LOG_CLR(FURI_LOG_CLR_PURPLE)
|
#define _FURI_LOG_CLR_T _FURI_LOG_CLR(_FURI_LOG_CLR_PURPLE)
|
||||||
|
|
||||||
typedef void (*FuriLogPuts)(const char* data);
|
typedef void (*FuriLogPuts)(const char* data);
|
||||||
typedef uint32_t (*FuriLogTimestamp)(void);
|
typedef uint32_t (*FuriLogTimestamp)(void);
|
||||||
@ -54,6 +54,15 @@ void furi_log_init();
|
|||||||
void furi_log_print_format(FuriLogLevel level, const char* tag, const char* format, ...)
|
void furi_log_print_format(FuriLogLevel level, const char* tag, const char* format, ...)
|
||||||
_ATTRIBUTE((__format__(__printf__, 3, 4)));
|
_ATTRIBUTE((__format__(__printf__, 3, 4)));
|
||||||
|
|
||||||
|
/** Print log record
|
||||||
|
*
|
||||||
|
* @param level
|
||||||
|
* @param format
|
||||||
|
* @param ...
|
||||||
|
*/
|
||||||
|
void furi_log_print_raw_format(FuriLogLevel level, const char* format, ...)
|
||||||
|
_ATTRIBUTE((__format__(__printf__, 2, 3)));
|
||||||
|
|
||||||
/** Set log level
|
/** Set log level
|
||||||
*
|
*
|
||||||
* @param[in] level The level
|
* @param[in] level The level
|
||||||
@ -95,6 +104,22 @@ void furi_log_set_timestamp(FuriLogTimestamp timestamp);
|
|||||||
#define FURI_LOG_T(tag, format, ...) \
|
#define FURI_LOG_T(tag, format, ...) \
|
||||||
furi_log_print_format(FuriLogLevelTrace, tag, format, ##__VA_ARGS__)
|
furi_log_print_format(FuriLogLevelTrace, tag, format, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
/** Log methods
|
||||||
|
*
|
||||||
|
* @param format The raw format
|
||||||
|
* @param ... VA Args
|
||||||
|
*/
|
||||||
|
#define FURI_LOG_RAW_E(format, ...) \
|
||||||
|
furi_log_print_raw_format(FuriLogLevelError, format, ##__VA_ARGS__)
|
||||||
|
#define FURI_LOG_RAW_W(format, ...) \
|
||||||
|
furi_log_print_raw_format(FuriLogLevelWarn, format, ##__VA_ARGS__)
|
||||||
|
#define FURI_LOG_RAW_I(format, ...) \
|
||||||
|
furi_log_print_raw_format(FuriLogLevelInfo, format, ##__VA_ARGS__)
|
||||||
|
#define FURI_LOG_RAW_D(format, ...) \
|
||||||
|
furi_log_print_raw_format(FuriLogLevelDebug, format, ##__VA_ARGS__)
|
||||||
|
#define FURI_LOG_RAW_T(format, ...) \
|
||||||
|
furi_log_print_raw_format(FuriLogLevelTrace, format, ##__VA_ARGS__)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
#include "math.h"
|
#include "math.h"
|
||||||
#include <core/check.h>
|
#include <core/check.h>
|
||||||
|
|
||||||
|
#include "furi.h"
|
||||||
|
|
||||||
#define TAG "SubGhzBlockEncoder"
|
#define TAG "SubGhzBlockEncoder"
|
||||||
|
|
||||||
void subghz_protocol_blocks_set_bit_array(
|
void subghz_protocol_blocks_set_bit_array(
|
||||||
@ -17,21 +19,32 @@ bool subghz_protocol_blocks_get_bit_array(uint8_t data_array[], size_t read_inde
|
|||||||
return bit_read(data_array[read_index_bit >> 3], 7 - (read_index_bit & 0x7));
|
return bit_read(data_array[read_index_bit >> 3], 7 - (read_index_bit & 0x7));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t subghz_protocol_blocks_get_upload(
|
size_t subghz_protocol_blocks_get_upload_from_bit_array(
|
||||||
uint8_t data_array[],
|
uint8_t data_array[],
|
||||||
size_t count_bit_data_array,
|
size_t count_bit_data_array,
|
||||||
LevelDuration* upload,
|
LevelDuration* upload,
|
||||||
size_t max_size_upload,
|
size_t max_size_upload,
|
||||||
uint32_t duration_bit) {
|
uint32_t duration_bit,
|
||||||
size_t index_bit = 0;
|
SubGhzProtocolBlockAlignBit align_bit) {
|
||||||
|
size_t bias_bit = 0;
|
||||||
size_t size_upload = 0;
|
size_t size_upload = 0;
|
||||||
uint32_t duration = duration_bit;
|
uint32_t duration = duration_bit;
|
||||||
|
|
||||||
|
if(align_bit == SubGhzProtocolBlockAlignBitRight) {
|
||||||
|
if(count_bit_data_array & 0x7) {
|
||||||
|
bias_bit = 8 - (count_bit_data_array & 0x7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t index_bit = bias_bit;
|
||||||
|
|
||||||
bool last_bit = subghz_protocol_blocks_get_bit_array(data_array, index_bit++);
|
bool last_bit = subghz_protocol_blocks_get_bit_array(data_array, index_bit++);
|
||||||
for(size_t i = 1; i < count_bit_data_array; i++) {
|
for(size_t i = 1 + bias_bit; i < count_bit_data_array + bias_bit; i++) {
|
||||||
if(last_bit == subghz_protocol_blocks_get_bit_array(data_array, index_bit)) {
|
if(last_bit == subghz_protocol_blocks_get_bit_array(data_array, index_bit)) {
|
||||||
duration += duration_bit;
|
duration += duration_bit;
|
||||||
} else {
|
} else {
|
||||||
furi_assert(max_size_upload > size_upload);
|
if(size_upload > max_size_upload) {
|
||||||
|
furi_crash("SubGhz: Encoder buffer overflow");
|
||||||
|
}
|
||||||
upload[size_upload++] = level_duration_make(
|
upload[size_upload++] = level_duration_make(
|
||||||
subghz_protocol_blocks_get_bit_array(data_array, index_bit - 1), duration);
|
subghz_protocol_blocks_get_bit_array(data_array, index_bit - 1), duration);
|
||||||
last_bit = !last_bit;
|
last_bit = !last_bit;
|
||||||
|
@ -19,6 +19,11 @@ typedef struct {
|
|||||||
|
|
||||||
} SubGhzProtocolBlockEncoder;
|
} SubGhzProtocolBlockEncoder;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SubGhzProtocolBlockAlignBitLeft,
|
||||||
|
SubGhzProtocolBlockAlignBitRight,
|
||||||
|
} SubGhzProtocolBlockAlignBit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set data bit when encoding HEX array.
|
* Set data bit when encoding HEX array.
|
||||||
* @param bit_value The value of the bit to be set
|
* @param bit_value The value of the bit to be set
|
||||||
@ -47,13 +52,15 @@ bool subghz_protocol_blocks_get_bit_array(uint8_t data_array[], size_t read_inde
|
|||||||
* @param upload Pointer to a LevelDuration
|
* @param upload Pointer to a LevelDuration
|
||||||
* @param max_size_upload upload size, check not to overflow
|
* @param max_size_upload upload size, check not to overflow
|
||||||
* @param duration_bit duration 1 bit
|
* @param duration_bit duration 1 bit
|
||||||
|
* @param align_bit alignment of useful bits in an array
|
||||||
*/
|
*/
|
||||||
size_t subghz_protocol_blocks_get_upload(
|
size_t subghz_protocol_blocks_get_upload_from_bit_array(
|
||||||
uint8_t data_array[],
|
uint8_t data_array[],
|
||||||
size_t count_bit_data_array,
|
size_t count_bit_data_array,
|
||||||
LevelDuration* upload,
|
LevelDuration* upload,
|
||||||
size_t max_size_upload,
|
size_t max_size_upload,
|
||||||
uint32_t duration_bit);
|
uint32_t duration_bit,
|
||||||
|
SubGhzProtocolBlockAlignBit align_bit);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ bool subghz_block_generic_deserialize(SubGhzBlockGeneric* instance, FlipperForma
|
|||||||
FURI_LOG_E(TAG, "Missing Bit");
|
FURI_LOG_E(TAG, "Missing Bit");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
instance->data_count_bit = (uint8_t)temp_data;
|
instance->data_count_bit = (uint16_t)temp_data;
|
||||||
|
|
||||||
uint8_t key_data[sizeof(uint64_t)] = {0};
|
uint8_t key_data[sizeof(uint64_t)] = {0};
|
||||||
if(!flipper_format_read_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) {
|
if(!flipper_format_read_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) {
|
||||||
|
@ -19,7 +19,7 @@ struct SubGhzBlockGeneric {
|
|||||||
const char* protocol_name;
|
const char* protocol_name;
|
||||||
uint64_t data;
|
uint64_t data;
|
||||||
uint32_t serial;
|
uint32_t serial;
|
||||||
uint8_t data_count_bit;
|
uint16_t data_count_bit;
|
||||||
uint8_t btn;
|
uint8_t btn;
|
||||||
uint32_t cnt;
|
uint32_t cnt;
|
||||||
};
|
};
|
||||||
|
1120
lib/subghz/protocols/bin_raw.c
Normal file
1120
lib/subghz/protocols/bin_raw.c
Normal file
File diff suppressed because it is too large
Load Diff
111
lib/subghz/protocols/bin_raw.h
Normal file
111
lib/subghz/protocols/bin_raw.h
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "base.h"
|
||||||
|
|
||||||
|
#define SUBGHZ_PROTOCOL_BIN_RAW_NAME "BinRAW"
|
||||||
|
|
||||||
|
typedef struct SubGhzProtocolDecoderBinRAW SubGhzProtocolDecoderBinRAW;
|
||||||
|
typedef struct SubGhzProtocolEncoderBinRAW SubGhzProtocolEncoderBinRAW;
|
||||||
|
|
||||||
|
extern const SubGhzProtocolDecoder subghz_protocol_bin_raw_decoder;
|
||||||
|
extern const SubGhzProtocolEncoder subghz_protocol_bin_raw_encoder;
|
||||||
|
extern const SubGhzProtocol subghz_protocol_bin_raw;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate SubGhzProtocolEncoderBinRAW.
|
||||||
|
* @param environment Pointer to a SubGhzEnvironment instance
|
||||||
|
* @return SubGhzProtocolEncoderBinRAW* pointer to a SubGhzProtocolEncoderBinRAW instance
|
||||||
|
*/
|
||||||
|
void* subghz_protocol_encoder_bin_raw_alloc(SubGhzEnvironment* environment);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free SubGhzProtocolEncoderBinRAW.
|
||||||
|
* @param context Pointer to a SubGhzProtocolEncoderBinRAW instance
|
||||||
|
*/
|
||||||
|
void subghz_protocol_encoder_bin_raw_free(void* context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize and generating an upload to send.
|
||||||
|
* @param context Pointer to a SubGhzProtocolEncoderBinRAW instance
|
||||||
|
* @param flipper_format Pointer to a FlipperFormat instance
|
||||||
|
* @return true On success
|
||||||
|
*/
|
||||||
|
bool subghz_protocol_encoder_bin_raw_deserialize(void* context, FlipperFormat* flipper_format);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forced transmission stop.
|
||||||
|
* @param context Pointer to a SubGhzProtocolEncoderBinRAW instance
|
||||||
|
*/
|
||||||
|
void subghz_protocol_encoder_bin_raw_stop(void* context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getting the level and duration of the upload to be loaded into DMA.
|
||||||
|
* @param context Pointer to a SubGhzProtocolEncoderBinRAW instance
|
||||||
|
* @return LevelDuration
|
||||||
|
*/
|
||||||
|
LevelDuration subghz_protocol_encoder_bin_raw_yield(void* context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate SubGhzProtocolDecoderBinRAW.
|
||||||
|
* @param environment Pointer to a SubGhzEnvironment instance
|
||||||
|
* @return SubGhzProtocolDecoderBinRAW* pointer to a SubGhzProtocolDecoderBinRAW instance
|
||||||
|
*/
|
||||||
|
void* subghz_protocol_decoder_bin_raw_alloc(SubGhzEnvironment* environment);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free SubGhzProtocolDecoderBinRAW.
|
||||||
|
* @param context Pointer to a SubGhzProtocolDecoderBinRAW instance
|
||||||
|
*/
|
||||||
|
void subghz_protocol_decoder_bin_raw_free(void* context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset decoder SubGhzProtocolDecoderBinRAW.
|
||||||
|
* @param context Pointer to a SubGhzProtocolDecoderBinRAW instance
|
||||||
|
*/
|
||||||
|
void subghz_protocol_decoder_bin_raw_reset(void* context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a raw sequence of levels and durations received from the air.
|
||||||
|
* @param context Pointer to a SubGhzProtocolDecoderBinRAW instance
|
||||||
|
* @param level Signal level true-high false-low
|
||||||
|
* @param duration Duration of this level in, us
|
||||||
|
*/
|
||||||
|
void subghz_protocol_decoder_bin_raw_feed(void* context, bool level, uint32_t duration);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getting the hash sum of the last randomly received parcel.
|
||||||
|
* @param context Pointer to a SubGhzProtocolDecoderBinRAW instance
|
||||||
|
* @return hash Hash sum
|
||||||
|
*/
|
||||||
|
uint8_t subghz_protocol_decoder_bin_raw_get_hash_data(void* context);
|
||||||
|
|
||||||
|
void subghz_protocol_decoder_bin_raw_data_input_rssi(
|
||||||
|
SubGhzProtocolDecoderBinRAW* instance,
|
||||||
|
float rssi);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize data SubGhzProtocolDecoderBinRAW.
|
||||||
|
* @param context Pointer to a SubGhzProtocolDecoderBinRAW instance
|
||||||
|
* @param flipper_format Pointer to a FlipperFormat instance
|
||||||
|
* @param preset The modulation on which the signal was received, SubGhzRadioPreset
|
||||||
|
* @return true On success
|
||||||
|
*/
|
||||||
|
bool subghz_protocol_decoder_bin_raw_serialize(
|
||||||
|
void* context,
|
||||||
|
FlipperFormat* flipper_format,
|
||||||
|
SubGhzRadioPreset* preset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize data SubGhzProtocolDecoderBinRAW.
|
||||||
|
* @param context Pointer to a SubGhzProtocolDecoderBinRAW instance
|
||||||
|
* @param flipper_format Pointer to a FlipperFormat instance
|
||||||
|
* @return true On success
|
||||||
|
*/
|
||||||
|
bool subghz_protocol_decoder_bin_raw_deserialize(void* context, FlipperFormat* flipper_format);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getting a textual representation of the received data.
|
||||||
|
* @param context Pointer to a SubGhzProtocolDecoderBinRAW instance
|
||||||
|
* @param output Resulting text
|
||||||
|
*/
|
||||||
|
void subghz_protocol_decoder_bin_raw_get_string(void* context, FuriString* output);
|
@ -196,12 +196,13 @@ static bool
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
instance->encoder.size_upload = subghz_protocol_blocks_get_upload(
|
instance->encoder.size_upload = subghz_protocol_blocks_get_upload_from_bit_array(
|
||||||
upload_hex_data,
|
upload_hex_data,
|
||||||
upload_hex_count_bit,
|
upload_hex_count_bit,
|
||||||
instance->encoder.upload,
|
instance->encoder.upload,
|
||||||
instance->encoder.size_upload,
|
instance->encoder.size_upload,
|
||||||
subghz_protocol_chamb_code_const.te_short);
|
subghz_protocol_chamb_code_const.te_short,
|
||||||
|
SubGhzProtocolBlockAlignBitLeft);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@ const SubGhzProtocol* subghz_protocol_registry_items[] = {
|
|||||||
&subghz_protocol_dooya,
|
&subghz_protocol_dooya,
|
||||||
&subghz_protocol_alutech_at_4n,
|
&subghz_protocol_alutech_at_4n,
|
||||||
&subghz_protocol_kinggates_stylo_4k,
|
&subghz_protocol_kinggates_stylo_4k,
|
||||||
|
&subghz_protocol_bin_raw,
|
||||||
};
|
};
|
||||||
|
|
||||||
const SubGhzProtocolRegistry subghz_protocol_registry = {
|
const SubGhzProtocolRegistry subghz_protocol_registry = {
|
||||||
|
@ -42,5 +42,6 @@
|
|||||||
#include "dooya.h"
|
#include "dooya.h"
|
||||||
#include "alutech_at_4n.h"
|
#include "alutech_at_4n.h"
|
||||||
#include "kinggates_stylo_4k.h"
|
#include "kinggates_stylo_4k.h"
|
||||||
|
#include "bin_raw.h"
|
||||||
|
|
||||||
extern const SubGhzProtocolRegistry subghz_protocol_registry;
|
extern const SubGhzProtocolRegistry subghz_protocol_registry;
|
||||||
|
@ -261,16 +261,16 @@ static bool
|
|||||||
data = order << 4 | invert;
|
data = order << 4 | invert;
|
||||||
int k = 0;
|
int k = 0;
|
||||||
for(int i = 6; i >= 0; i -= 2) {
|
for(int i = 6; i >= 0; i -= 2) {
|
||||||
roll_array[k++] = (data >> i) & 0x03;
|
roll_array[k] = (data >> i) & 0x03;
|
||||||
if(roll_array[k] == 3) {
|
if(roll_array[k++] == 3) {
|
||||||
FURI_LOG_E(TAG, "Roll_Array FAIL");
|
FURI_LOG_E(TAG, "Roll_Array FAIL");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 8; i >= 0; i -= 2) {
|
for(int i = 8; i >= 0; i -= 2) {
|
||||||
roll_array[k++] = (p[2] >> i) & 0x03;
|
roll_array[k] = (p[2] >> i) & 0x03;
|
||||||
if(roll_array[k] == 3) {
|
if(roll_array[k++] == 3) {
|
||||||
FURI_LOG_E(TAG, "Roll_Array FAIL");
|
FURI_LOG_E(TAG, "Roll_Array FAIL");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,7 @@ typedef enum {
|
|||||||
SubGhzProtocolFlag_Save = (1 << 7),
|
SubGhzProtocolFlag_Save = (1 << 7),
|
||||||
SubGhzProtocolFlag_Load = (1 << 8),
|
SubGhzProtocolFlag_Load = (1 << 8),
|
||||||
SubGhzProtocolFlag_Send = (1 << 9),
|
SubGhzProtocolFlag_Send = (1 << 9),
|
||||||
|
SubGhzProtocolFlag_BinRAW = (1 << 10),
|
||||||
} SubGhzProtocolFlag;
|
} SubGhzProtocolFlag;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
#define LEVEL_DURATION_RESERVED 0x800000U
|
#define LEVEL_DURATION_RESERVED 0x800000U
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t level;
|
uint32_t duration : 30;
|
||||||
uint32_t duration;
|
uint8_t level : 2;
|
||||||
} LevelDuration;
|
} LevelDuration;
|
||||||
|
|
||||||
static inline LevelDuration level_duration_make(bool level, uint32_t duration) {
|
static inline LevelDuration level_duration_make(bool level, uint32_t duration) {
|
||||||
|
Loading…
Reference in New Issue
Block a user