Skorp subghz capture refactoring (#569)
* SubGhz: changing the operation of the capture timer, and the logic of the work of parsers * Add toolbox lib. Move levels to toolbox. Subghz switch to levels. * Subghz: update worker signatures * SubGhz: pluggable level duration implementations. * SubGhz : test drawing pictures in Gui * SubGhz: Added a callback with the parser structure as argument * SubGhz: copy protocol data to model * SubGhz: refactoing code * SubGhz: cleanup and format sources * SubGhz: remove comments Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com> Co-authored-by: DrZlo13 <who.just.the.doctor@gmail.com>
This commit is contained in:
@@ -22,9 +22,11 @@ struct SubGhzProtocol {
|
||||
|
||||
SubGhzProtocolTextCallback text_callback;
|
||||
void* text_callback_context;
|
||||
SubGhzProtocolCommonCallbackDump parser_callback;
|
||||
void* parser_callback_context;
|
||||
};
|
||||
|
||||
static void subghz_protocol_came_rx_callback(SubGhzProtocolCommon* parser, void* context) {
|
||||
static void subghz_protocol_text_rx_callback(SubGhzProtocolCommon* parser, void* context) {
|
||||
SubGhzProtocol* instance = context;
|
||||
|
||||
string_t output;
|
||||
@@ -38,6 +40,13 @@ static void subghz_protocol_came_rx_callback(SubGhzProtocolCommon* parser, void*
|
||||
string_clear(output);
|
||||
}
|
||||
|
||||
static void subghz_protocol_parser_rx_callback(SubGhzProtocolCommon* parser, void* context) {
|
||||
SubGhzProtocol* instance = context;
|
||||
if (instance->parser_callback) {
|
||||
instance->parser_callback(parser, instance->parser_callback_context);
|
||||
}
|
||||
}
|
||||
|
||||
SubGhzProtocol* subghz_protocol_alloc() {
|
||||
SubGhzProtocol* instance = furi_alloc(sizeof(SubGhzProtocol));
|
||||
|
||||
@@ -62,19 +71,31 @@ void subghz_protocol_free(SubGhzProtocol* instance) {
|
||||
free(instance);
|
||||
}
|
||||
|
||||
void subghz_protocol_enable_dump(SubGhzProtocol* instance, SubGhzProtocolTextCallback callback, void* context) {
|
||||
void subghz_protocol_enable_dump_text(SubGhzProtocol* instance, SubGhzProtocolTextCallback callback, void* context) {
|
||||
furi_assert(instance);
|
||||
|
||||
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->came, subghz_protocol_came_rx_callback, instance);
|
||||
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->keeloq, subghz_protocol_came_rx_callback, instance);
|
||||
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->princeton, subghz_protocol_came_rx_callback, instance);
|
||||
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->nice_flo, subghz_protocol_came_rx_callback, instance);
|
||||
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->nice_flor_s, subghz_protocol_came_rx_callback, instance);
|
||||
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->came, subghz_protocol_text_rx_callback, instance);
|
||||
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->keeloq, subghz_protocol_text_rx_callback, instance);
|
||||
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->princeton, subghz_protocol_text_rx_callback, instance);
|
||||
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->nice_flo, subghz_protocol_text_rx_callback, instance);
|
||||
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->nice_flor_s, subghz_protocol_text_rx_callback, instance);
|
||||
|
||||
instance->text_callback = callback;
|
||||
instance->text_callback_context = context;
|
||||
}
|
||||
|
||||
void subghz_protocol_enable_dump(SubGhzProtocol* instance, SubGhzProtocolCommonCallbackDump callback, void* context) {
|
||||
furi_assert(instance);
|
||||
|
||||
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->came, subghz_protocol_parser_rx_callback, instance);
|
||||
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->keeloq, subghz_protocol_parser_rx_callback, instance);
|
||||
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->princeton, subghz_protocol_parser_rx_callback, instance);
|
||||
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->nice_flo, subghz_protocol_parser_rx_callback, instance);
|
||||
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->nice_flor_s, subghz_protocol_parser_rx_callback, instance);
|
||||
instance->parser_callback = callback;
|
||||
instance->parser_callback_context = context;
|
||||
}
|
||||
|
||||
static void subghz_protocol_load_keeloq_file_process_line(SubGhzProtocol* instance, string_t line) {
|
||||
uint64_t key = 0;
|
||||
uint16_t type = 0;
|
||||
@@ -123,12 +144,17 @@ void subghz_protocol_load_keeloq_file(SubGhzProtocol* instance, const char* file
|
||||
}
|
||||
|
||||
void subghz_protocol_reset(SubGhzProtocol* instance) {
|
||||
subghz_protocol_came_reset(instance->came);
|
||||
subghz_protocol_keeloq_reset(instance->keeloq);
|
||||
subghz_protocol_princeton_reset(instance->princeton);
|
||||
subghz_protocol_nice_flo_reset(instance->nice_flo);
|
||||
subghz_protocol_nice_flor_s_reset(instance->nice_flor_s);
|
||||
}
|
||||
|
||||
void subghz_protocol_parse(SubGhzProtocol* instance, LevelPair data) {
|
||||
subghz_protocol_came_parse(instance->came, data);
|
||||
subghz_protocol_keeloq_parse(instance->keeloq, data);
|
||||
subghz_protocol_princeton_parse(instance->princeton, data);
|
||||
subghz_protocol_nice_flo_parse(instance->nice_flo, data);
|
||||
subghz_protocol_nice_flor_s_parse(instance->nice_flor_s, data);
|
||||
void subghz_protocol_parse(SubGhzProtocol* instance, bool level, uint32_t duration) {
|
||||
subghz_protocol_came_parse(instance->came, level, duration);
|
||||
subghz_protocol_keeloq_parse(instance->keeloq, level, duration);
|
||||
subghz_protocol_princeton_parse(instance->princeton, level, duration);
|
||||
subghz_protocol_nice_flo_parse(instance->nice_flo, level, duration);
|
||||
subghz_protocol_nice_flor_s_parse(instance->nice_flor_s, level, duration);
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@
|
||||
#include "subghz_protocol_common.h"
|
||||
|
||||
typedef void (*SubGhzProtocolTextCallback)(string_t text, void* context);
|
||||
typedef void (*SubGhzProtocolCommonCallbackDump)(SubGhzProtocolCommon *parser, void* context);
|
||||
|
||||
typedef struct SubGhzProtocol SubGhzProtocol;
|
||||
|
||||
@@ -18,16 +19,21 @@ SubGhzProtocol* subghz_protocol_alloc();
|
||||
*/
|
||||
void subghz_protocol_free(SubGhzProtocol* instance);
|
||||
|
||||
/** Outputting data from all parsers
|
||||
/** Outputting data text from all parsers
|
||||
*
|
||||
* @param instance - SubGhzProtocol instance
|
||||
* @param callback - SubGhzProtocolTextCallback callback
|
||||
* @param context
|
||||
*/
|
||||
void subghz_protocol_enable_dump(
|
||||
SubGhzProtocol* instance,
|
||||
SubGhzProtocolTextCallback callback,
|
||||
void* context);
|
||||
void subghz_protocol_enable_dump_text(SubGhzProtocol* instance,SubGhzProtocolTextCallback callback,void* context);
|
||||
|
||||
/** Outputting data SubGhzProtocol from all parsers
|
||||
*
|
||||
* @param instance - SubGhzProtocol instance
|
||||
* @param callback - SubGhzProtocolTextCallback callback
|
||||
* @param context
|
||||
*/
|
||||
void subghz_protocol_enable_dump( SubGhzProtocol* instance, SubGhzProtocolCommonCallbackDump callback, void* context);
|
||||
|
||||
/** File name rainbow table Nice Flor-S
|
||||
*
|
||||
@@ -52,6 +58,7 @@ void subghz_protocol_reset(SubGhzProtocol* instance);
|
||||
/** Loading data into all parsers
|
||||
*
|
||||
* @param instance - SubGhzProtocol instance
|
||||
* @param data - LevelPair data
|
||||
* @param level - true is high, false if low
|
||||
* @param duration - level duration in microseconds
|
||||
*/
|
||||
void subghz_protocol_parse(SubGhzProtocol* instance, LevelPair data);
|
||||
void subghz_protocol_parse(SubGhzProtocol* instance, bool level, uint32_t duration);
|
||||
|
@@ -63,11 +63,15 @@ void subghz_protocol_came_send_key(SubGhzProtocolCame* instance, uint64_t key, u
|
||||
}
|
||||
}
|
||||
|
||||
void subghz_protocol_came_parse(SubGhzProtocolCame* instance, LevelPair data) {
|
||||
void subghz_protocol_came_reset(SubGhzProtocolCame* instance) {
|
||||
instance->common.parser_step = 0;
|
||||
}
|
||||
|
||||
void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32_t duration) {
|
||||
switch (instance->common.parser_step) {
|
||||
case 0:
|
||||
if ((data.level == ApiHalSubGhzCaptureLevelLow)
|
||||
&& (DURATION_DIFF(data.duration,instance->common.te_shot * 51)< instance->common.te_delta * 51)) { //Need protocol 36 te_shot
|
||||
if ((!level)
|
||||
&& (DURATION_DIFF(duration, instance->common.te_shot * 51)< instance->common.te_delta * 51)) { //Need protocol 36 te_shot
|
||||
//Found header CAME
|
||||
instance->common.parser_step = 1;
|
||||
} else {
|
||||
@@ -75,9 +79,9 @@ void subghz_protocol_came_parse(SubGhzProtocolCame* instance, LevelPair data) {
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (data.level == ApiHalSubGhzCaptureLevelLow) {
|
||||
if (!level) {
|
||||
break;
|
||||
} else if (DURATION_DIFF(data.duration,instance->common.te_shot)< instance->common.te_delta) {
|
||||
} else if (DURATION_DIFF(duration, instance->common.te_shot)< instance->common.te_delta) {
|
||||
//Found start bit CAME
|
||||
instance->common.parser_step = 2;
|
||||
instance->common.code_found = 0;
|
||||
@@ -87,33 +91,34 @@ void subghz_protocol_came_parse(SubGhzProtocolCame* instance, LevelPair data) {
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (data.level == ApiHalSubGhzCaptureLevelLow) { //save interval
|
||||
if (data.duration >= (instance->common.te_shot * 4)) {
|
||||
if (!level) { //save interval
|
||||
if (duration >= (instance->common.te_shot * 4)) {
|
||||
instance->common.parser_step = 1;
|
||||
if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) {
|
||||
|
||||
//ToDo out data display
|
||||
|
||||
instance->common.serial = 0x0;
|
||||
instance->common.btn = 0x0;
|
||||
if (instance->common.callback)
|
||||
instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
instance->common.te_last = data.duration;
|
||||
instance->common.te_last = duration;
|
||||
instance->common.parser_step = 3;
|
||||
} else {
|
||||
instance->common.parser_step = 0;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (data.level == ApiHalSubGhzCaptureLevelHigh) {
|
||||
if (level) {
|
||||
if ((DURATION_DIFF(instance->common.te_last,instance->common.te_shot) < instance->common.te_delta)
|
||||
&& (DURATION_DIFF(data.duration,instance->common.te_long)< instance->common.te_delta)) {
|
||||
&& (DURATION_DIFF(duration, instance->common.te_long)< instance->common.te_delta)) {
|
||||
subghz_protocol_common_add_bit(&instance->common, 0);
|
||||
instance->common.parser_step = 2;
|
||||
} else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long)< instance->common.te_delta)
|
||||
&& (DURATION_DIFF(data.duration,instance->common.te_shot)< instance->common.te_delta)) {
|
||||
&& (DURATION_DIFF(duration, instance->common.te_shot)< instance->common.te_delta)) {
|
||||
subghz_protocol_common_add_bit(&instance->common, 1);
|
||||
instance->common.parser_step = 2;
|
||||
} else
|
||||
|
@@ -25,9 +25,14 @@ void subghz_protocol_came_free(SubGhzProtocolCame* instance);
|
||||
*/
|
||||
void subghz_protocol_came_send_key(SubGhzProtocolCame* instance, uint64_t key, uint8_t bit, uint8_t repeat);
|
||||
|
||||
/** Reset internal state
|
||||
* @param instance - SubGhzProtocolCame instance
|
||||
*/
|
||||
void subghz_protocol_came_reset(SubGhzProtocolCame* instance);
|
||||
|
||||
/** Parse accepted duration
|
||||
*
|
||||
* @param instance - SubGhzProtocolCame instance
|
||||
* @param data - LevelPair data
|
||||
* @param data - LevelDuration level_duration
|
||||
*/
|
||||
void subghz_protocol_came_parse(SubGhzProtocolCame* instance, LevelPair data);
|
||||
void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32_t duration);;
|
||||
|
@@ -27,6 +27,7 @@ void subghz_protocol_common_set_callback(SubGhzProtocolCommon* common, SubGhzPro
|
||||
common->context = context;
|
||||
}
|
||||
|
||||
|
||||
void subghz_protocol_common_to_str(SubGhzProtocolCommon* instance, string_t output) {
|
||||
if (instance->to_string) {
|
||||
instance->to_string(instance, output);
|
||||
|
@@ -11,7 +11,7 @@
|
||||
|
||||
#define SUBGHZ_TX_PIN_HIGTH()
|
||||
#define SUBGHZ_TX_PIN_LOW()
|
||||
#define DURATION_DIFF(x,y) ((x < y) ? (y - x) : (x - y))
|
||||
#define DURATION_DIFF(x, y) ((x < y) ? (y - x) : (x - y))
|
||||
|
||||
typedef struct SubGhzProtocolCommon SubGhzProtocolCommon;
|
||||
|
||||
@@ -29,7 +29,7 @@ struct SubGhzProtocolCommon {
|
||||
uint8_t code_count_bit;
|
||||
uint8_t code_min_count_bit_for_found;
|
||||
uint8_t parser_step;
|
||||
uint16_t te_last;
|
||||
uint32_t te_last;
|
||||
uint8_t header_count;
|
||||
uint16_t cnt;
|
||||
uint32_t serial;
|
||||
|
@@ -271,10 +271,14 @@ void subghz_protocol_keeloq_send_key(SubGhzProtocolKeeloq* instance, uint64_t ke
|
||||
}
|
||||
}
|
||||
|
||||
void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, LevelPair data) {
|
||||
void subghz_protocol_keeloq_reset(SubGhzProtocolKeeloq* instance) {
|
||||
instance->common.parser_step = 0;
|
||||
}
|
||||
|
||||
void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, uint32_t duration) {
|
||||
switch (instance->common.parser_step) {
|
||||
case 0:
|
||||
if ((data.level == ApiHalSubGhzCaptureLevelHigh) && DURATION_DIFF(data.duration, instance->common.te_shot)< instance->common.te_delta) {
|
||||
if ((level) && DURATION_DIFF(duration, instance->common.te_shot)< instance->common.te_delta) {
|
||||
instance->common.parser_step = 1;
|
||||
instance->common.header_count++;
|
||||
} else {
|
||||
@@ -283,11 +287,11 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, LevelPair data
|
||||
|
||||
break;
|
||||
case 1:
|
||||
if ((data.level == ApiHalSubGhzCaptureLevelLow) && (DURATION_DIFF(data.duration, instance->common.te_shot ) < instance->common.te_delta)) {
|
||||
if ((!level) && (DURATION_DIFF(duration, instance->common.te_shot ) < instance->common.te_delta)) {
|
||||
instance->common.parser_step = 0;
|
||||
break;
|
||||
}
|
||||
if ((instance->common.header_count > 2) && ( DURATION_DIFF(data.duration, instance->common.te_shot * 10)< instance->common.te_delta * 10)) {
|
||||
if ((instance->common.header_count > 2) && ( DURATION_DIFF(duration, instance->common.te_shot * 10)< instance->common.te_delta * 10)) {
|
||||
// Found header
|
||||
instance->common.parser_step = 2;
|
||||
instance->common.code_found = 0;
|
||||
@@ -298,21 +302,19 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, LevelPair data
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (data.level == ApiHalSubGhzCaptureLevelHigh) {
|
||||
instance->common.te_last = data.duration;
|
||||
if (level) {
|
||||
instance->common.te_last = duration;
|
||||
instance->common.parser_step = 3;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (data.level == ApiHalSubGhzCaptureLevelLow) {
|
||||
if (data.duration >= (instance->common.te_shot * 2 + instance->common.te_delta)) {
|
||||
if (!level) {
|
||||
if (duration >= (instance->common.te_shot * 2 + instance->common.te_delta)) {
|
||||
// Found end TX
|
||||
instance->common.parser_step = 0;
|
||||
if (instance->common.code_count_bit >= instance->common.code_min_count_bit_for_found) {
|
||||
//&& (instance->common.code_last_found != instance->common.code_found )) {
|
||||
instance->common.code_last_found = instance->common.code_found;
|
||||
|
||||
//ToDo out data display
|
||||
subghz_protocol_keeloq_check_remote_controller(instance);
|
||||
|
||||
instance->common.code_found = 0;
|
||||
@@ -321,13 +323,13 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, LevelPair data
|
||||
}
|
||||
break;
|
||||
} else if ((DURATION_DIFF(instance->common.te_last, instance->common.te_shot) < instance->common.te_delta)
|
||||
&& (DURATION_DIFF(data.duration, instance->common.te_long) < instance->common.te_delta)) {
|
||||
&& (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) {
|
||||
if (instance->common.code_count_bit < instance->common.code_min_count_bit_for_found) {
|
||||
subghz_protocol_common_add_bit(&instance->common, 1);
|
||||
}
|
||||
instance->common.parser_step = 2;
|
||||
} else if ((DURATION_DIFF(instance->common.te_last, instance->common.te_long) < instance->common.te_delta)
|
||||
&& (DURATION_DIFF(data.duration, instance->common.te_shot) < instance->common.te_delta)) {
|
||||
&& (DURATION_DIFF(duration, instance->common.te_shot) < instance->common.te_delta)) {
|
||||
if (instance->common.code_count_bit < instance->common.code_min_count_bit_for_found) {
|
||||
subghz_protocol_common_add_bit(&instance->common, 0);
|
||||
}
|
||||
|
@@ -34,12 +34,17 @@ void subghz_protocol_keeloq_add_manafacture_key(SubGhzProtocolKeeloq* instance,
|
||||
*/
|
||||
void subghz_protocol_keeloq_send_key(SubGhzProtocolKeeloq* instance, uint64_t key, uint8_t bit, uint8_t repeat);
|
||||
|
||||
/** Reset internal state
|
||||
* @param instance - SubGhzProtocolKeeloq instance
|
||||
*/
|
||||
void subghz_protocol_keeloq_reset(SubGhzProtocolKeeloq* instance);
|
||||
|
||||
/** Parse accepted duration
|
||||
*
|
||||
* @param instance - SubGhzProtocolKeeloq instance
|
||||
* @param data - LevelPair data
|
||||
* @param data - LevelDuration level_duration
|
||||
*/
|
||||
void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, LevelPair data);
|
||||
void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, uint32_t duration);;
|
||||
|
||||
/** Outputting information from the parser
|
||||
*
|
||||
|
@@ -62,11 +62,15 @@ void subghz_protocol_nice_flo_send_key(SubGhzProtocolNiceFlo* instance, uint64_t
|
||||
}
|
||||
}
|
||||
|
||||
void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, LevelPair data) {
|
||||
void subghz_protocol_nice_flo_reset(SubGhzProtocolNiceFlo* instance) {
|
||||
instance->common.parser_step = 0;
|
||||
}
|
||||
|
||||
void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, bool level, uint32_t duration) {
|
||||
switch (instance->common.parser_step) {
|
||||
case 0:
|
||||
if ((data.level == ApiHalSubGhzCaptureLevelLow)
|
||||
&& (DURATION_DIFF(data.duration,instance->common.te_shot * 36)< instance->common.te_delta * 36)) {
|
||||
if ((!level)
|
||||
&& (DURATION_DIFF(duration, instance->common.te_shot * 36)< instance->common.te_delta * 36)) {
|
||||
//Found header Nice Flo
|
||||
instance->common.parser_step = 1;
|
||||
} else {
|
||||
@@ -74,9 +78,9 @@ void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, LevelPair d
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (data.level == ApiHalSubGhzCaptureLevelLow) {
|
||||
if (!level) {
|
||||
break;
|
||||
} else if (DURATION_DIFF(data.duration,instance->common.te_shot)< instance->common.te_delta) {
|
||||
} else if (DURATION_DIFF(duration, instance->common.te_shot)< instance->common.te_delta) {
|
||||
//Found start bit Nice Flo
|
||||
instance->common.parser_step = 2;
|
||||
instance->common.code_found = 0;
|
||||
@@ -86,31 +90,30 @@ void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, LevelPair d
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (data.level == ApiHalSubGhzCaptureLevelLow) { //save interval
|
||||
if (data.duration >= (instance->common.te_shot * 4)) {
|
||||
if (!level) { //save interval
|
||||
if (duration >= (instance->common.te_shot * 4)) {
|
||||
instance->common.parser_step = 1;
|
||||
if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) {
|
||||
|
||||
//ToDo out data display
|
||||
//instance->common.serial = 0x12345;
|
||||
if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
instance->common.te_last = data.duration;
|
||||
instance->common.te_last = duration;
|
||||
instance->common.parser_step = 3;
|
||||
} else {
|
||||
instance->common.parser_step = 0;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (data.level == ApiHalSubGhzCaptureLevelHigh) {
|
||||
if (level) {
|
||||
if ((DURATION_DIFF(instance->common.te_last,instance->common.te_shot) < instance->common.te_delta)
|
||||
&& (DURATION_DIFF(data.duration,instance->common.te_long)< instance->common.te_delta)) {
|
||||
&& (DURATION_DIFF(duration, instance->common.te_long)< instance->common.te_delta)) {
|
||||
subghz_protocol_common_add_bit(&instance->common, 0);
|
||||
instance->common.parser_step = 2;
|
||||
} else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long)< instance->common.te_delta)
|
||||
&& (DURATION_DIFF(data.duration,instance->common.te_shot)< instance->common.te_delta)) {
|
||||
&& (DURATION_DIFF(duration, instance->common.te_shot)< instance->common.te_delta)) {
|
||||
subghz_protocol_common_add_bit(&instance->common, 1);
|
||||
instance->common.parser_step = 2;
|
||||
} else
|
||||
|
@@ -25,9 +25,14 @@ void subghz_protocol_nice_flo_free(SubGhzProtocolNiceFlo* instance);
|
||||
*/
|
||||
void subghz_protocol_nice_flo_send_key(SubGhzProtocolNiceFlo* instance, uint64_t key, uint8_t bit, uint8_t repeat);
|
||||
|
||||
/** Reset internal state
|
||||
* @param instance - SubGhzProtocolNiceFlo instance
|
||||
*/
|
||||
void subghz_protocol_nice_flo_reset(SubGhzProtocolNiceFlo* instance);
|
||||
|
||||
/** Parse accepted duration
|
||||
*
|
||||
* @param instance - SubGhzProtocolNiceFlo instance
|
||||
* @param data - LevelPair data
|
||||
* @param data - LevelDuration level_duration
|
||||
*/
|
||||
void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, LevelPair data);
|
||||
void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, bool level, uint32_t duration);;
|
||||
|
@@ -144,11 +144,15 @@ void subghz_nice_flor_s_decoder_decrypt(SubGhzProtocolNiceFlorS* instance) {
|
||||
if(instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
|
||||
}
|
||||
|
||||
void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, LevelPair data) {
|
||||
void subghz_protocol_nice_flor_s_reset(SubGhzProtocolNiceFlorS* instance) {
|
||||
instance->common.parser_step = 0;
|
||||
}
|
||||
|
||||
void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, bool level, uint32_t duration) {
|
||||
switch(instance->common.parser_step) {
|
||||
case 0:
|
||||
if((data.level == ApiHalSubGhzCaptureLevelLow)
|
||||
&& (DURATION_DIFF(data.duration, instance->common.te_shot * 38) < instance->common.te_delta * 38)) {
|
||||
if((!level)
|
||||
&& (DURATION_DIFF(duration, instance->common.te_shot * 38) < instance->common.te_delta * 38)) {
|
||||
//Found start header Nice Flor-S
|
||||
instance->common.parser_step = 1;
|
||||
} else {
|
||||
@@ -156,8 +160,8 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, LevelP
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if((data.level == ApiHalSubGhzCaptureLevelHigh)
|
||||
&& (DURATION_DIFF(data.duration, instance->common.te_shot * 3) < instance->common.te_delta * 3)) {
|
||||
if((level)
|
||||
&& (DURATION_DIFF(duration, instance->common.te_shot * 3) < instance->common.te_delta * 3)) {
|
||||
//Found next header Nice Flor-S
|
||||
instance->common.parser_step = 2;
|
||||
} else {
|
||||
@@ -165,8 +169,8 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, LevelP
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if((data.level == ApiHalSubGhzCaptureLevelLow)
|
||||
&& (DURATION_DIFF(data.duration, instance->common.te_shot * 3) < instance->common.te_delta * 3)) {
|
||||
if((!level)
|
||||
&& (DURATION_DIFF(duration, instance->common.te_shot * 3) < instance->common.te_delta * 3)) {
|
||||
//Found header Nice Flor-S
|
||||
instance->common.parser_step = 3;
|
||||
instance->common.code_found = 0;
|
||||
@@ -176,31 +180,32 @@ void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, LevelP
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if(data.level == ApiHalSubGhzCaptureLevelHigh) {
|
||||
if(DURATION_DIFF(data.duration, instance->common.te_shot * 3) < instance->common.te_delta) {
|
||||
if(level) {
|
||||
if(DURATION_DIFF(duration, instance->common.te_shot * 3) < instance->common.te_delta) {
|
||||
//Found STOP bit
|
||||
instance->common.parser_step = 0;
|
||||
if(instance->common.code_count_bit >=instance->common.code_min_count_bit_for_found) {
|
||||
//ToDo out data display
|
||||
|
||||
subghz_nice_flor_s_decoder_decrypt(instance);
|
||||
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
//save interval
|
||||
instance->common.te_last = data.duration;
|
||||
instance->common.te_last = duration;
|
||||
instance->common.parser_step = 4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if(data.level == ApiHalSubGhzCaptureLevelLow) {
|
||||
if(!level) {
|
||||
if((DURATION_DIFF(instance->common.te_last, instance->common.te_shot) < instance->common.te_delta)
|
||||
&&(DURATION_DIFF(data.duration, instance->common.te_long) < instance->common.te_delta)) {
|
||||
&&(DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) {
|
||||
subghz_protocol_common_add_bit(&instance->common, 0);
|
||||
instance->common.parser_step = 3;
|
||||
} else if(
|
||||
(DURATION_DIFF(instance->common.te_last, instance->common.te_long) < instance->common.te_delta)
|
||||
&&(DURATION_DIFF(data.duration, instance->common.te_shot) < instance->common.te_delta)) {
|
||||
&&(DURATION_DIFF(duration, instance->common.te_shot) < instance->common.te_delta)) {
|
||||
subghz_protocol_common_add_bit(&instance->common, 1);
|
||||
instance->common.parser_step = 3;
|
||||
} else
|
||||
|
@@ -32,12 +32,17 @@ void subghz_protocol_nice_flor_s_name_file(SubGhzProtocolNiceFlorS* instance, co
|
||||
*/
|
||||
void subghz_protocol_nice_flor_s_send_key(SubGhzProtocolNiceFlorS* instance, uint64_t key, uint8_t bit, uint8_t repeat);
|
||||
|
||||
/** Reset internal state
|
||||
* @param instance - SubGhzProtocolNiceFlorS instance
|
||||
*/
|
||||
void subghz_protocol_nice_flor_s_reset(SubGhzProtocolNiceFlorS* instance);
|
||||
|
||||
/** Parse accepted duration
|
||||
*
|
||||
* @param instance - SubGhzProtocolNiceFlorS instance
|
||||
* @param data - LevelPair data
|
||||
* @param data - LevelDuration level_duration
|
||||
*/
|
||||
void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, LevelPair data);
|
||||
void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, bool level, uint32_t duration);;
|
||||
|
||||
/** Outputting information from the parser
|
||||
*
|
||||
|
@@ -62,11 +62,15 @@ void subghz_protocol_princeton_send_key(SubGhzProtocolPrinceton* instance, uint6
|
||||
}
|
||||
}
|
||||
|
||||
void subghz_protocol_princeton_parse(SubGhzProtocolPrinceton* instance, LevelPair data) {
|
||||
void subghz_protocol_princeton_reset(SubGhzProtocolPrinceton* instance) {
|
||||
instance->common.parser_step = 0;
|
||||
}
|
||||
|
||||
void subghz_protocol_princeton_parse(SubGhzProtocolPrinceton* instance, bool level, uint32_t duration) {
|
||||
switch (instance->common.parser_step) {
|
||||
case 0:
|
||||
if ((data.level == ApiHalSubGhzCaptureLevelLow)
|
||||
&& (DURATION_DIFF(data.duration,instance->common.te_shot * 36)< instance->common.te_delta * 36)) {
|
||||
if ((!level)
|
||||
&& (DURATION_DIFF(duration,instance->common.te_shot * 36)< instance->common.te_delta * 36)) {
|
||||
//Found Preambula
|
||||
instance->common.parser_step = 1;
|
||||
instance->common.code_found = 0;
|
||||
@@ -77,20 +81,21 @@ void subghz_protocol_princeton_parse(SubGhzProtocolPrinceton* instance, LevelPai
|
||||
break;
|
||||
case 1:
|
||||
//save duration
|
||||
if (data.level == ApiHalSubGhzCaptureLevelHigh) {
|
||||
instance->common.te_last = data.duration;
|
||||
if (level) {
|
||||
instance->common.te_last = duration;
|
||||
instance->common.parser_step = 2;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (data.level == ApiHalSubGhzCaptureLevelLow) {
|
||||
if (data.duration>= (instance->common.te_shot * 10+ instance->common.te_delta)) {
|
||||
if (!level) {
|
||||
if (duration >= (instance->common.te_shot * 10 + instance->common.te_delta)) {
|
||||
instance->common.parser_step = 1;
|
||||
if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) {
|
||||
//ToDo out data display
|
||||
|
||||
instance->common.serial = instance->common.code_found >> 4;
|
||||
instance->common.btn = (uint8_t)instance->common.code_found & 0x00000F;
|
||||
if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
|
||||
|
||||
}
|
||||
instance->common.code_found = 0;
|
||||
instance->common.code_count_bit = 0;
|
||||
@@ -98,11 +103,11 @@ void subghz_protocol_princeton_parse(SubGhzProtocolPrinceton* instance, LevelPai
|
||||
}
|
||||
|
||||
if ((DURATION_DIFF(instance->common.te_last,instance->common.te_shot)< instance->common.te_delta)
|
||||
&& (DURATION_DIFF(data.duration,instance->common.te_long)< instance->common.te_delta*3)) {
|
||||
&& (DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta*3)) {
|
||||
subghz_protocol_common_add_bit(&instance->common, 0);
|
||||
instance->common.parser_step = 1;
|
||||
} else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long)< instance->common.te_delta*3)
|
||||
&& (DURATION_DIFF(data.duration,instance->common.te_shot)< instance->common.te_delta)) {
|
||||
&& (DURATION_DIFF(duration,instance->common.te_shot)< instance->common.te_delta)) {
|
||||
subghz_protocol_common_add_bit(&instance->common, 1);
|
||||
instance->common.parser_step = 1;
|
||||
} else {
|
||||
|
@@ -25,12 +25,17 @@ void subghz_protocol_princeton_free(SubGhzProtocolPrinceton* instance);
|
||||
*/
|
||||
void subghz_protocol_princeton_send_key(SubGhzProtocolPrinceton* instance, uint64_t key, uint8_t bit, uint8_t repeat);
|
||||
|
||||
/** Reset internal state
|
||||
* @param instance - SubGhzProtocolPrinceton instance
|
||||
*/
|
||||
void subghz_protocol_princeton_reset(SubGhzProtocolPrinceton* instance);
|
||||
|
||||
/** Parse accepted duration
|
||||
*
|
||||
* @param instance - SubGhzProtocolPrinceton instance
|
||||
* @param data - LevelPair data
|
||||
* @param data - LevelDuration level_duration
|
||||
*/
|
||||
void subghz_protocol_princeton_parse(SubGhzProtocolPrinceton* instance, LevelPair data);
|
||||
void subghz_protocol_princeton_parse(SubGhzProtocolPrinceton* instance, bool level, uint32_t duration);;
|
||||
|
||||
/** Outputting information from the parser
|
||||
*
|
||||
|
@@ -21,22 +21,18 @@ struct SubGhzWorker {
|
||||
* @param duration received signal duration
|
||||
* @param context
|
||||
*/
|
||||
void subghz_worker_rx_callback(
|
||||
ApiHalSubGhzCaptureLevel level,
|
||||
uint32_t duration,
|
||||
void* context) {
|
||||
|
||||
void subghz_worker_rx_callback(bool level, uint32_t duration, void* context) {
|
||||
SubGhzWorker* instance = context;
|
||||
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
LevelPair pair = {.level = level, .duration = duration};
|
||||
LevelDuration level_duration = level_duration_make(level, duration);
|
||||
if(instance->overrun) {
|
||||
instance->overrun = false;
|
||||
pair.level = ApiHalSubGhzCaptureLevelOverrun;
|
||||
level_duration = level_duration_reset();
|
||||
}
|
||||
size_t ret =
|
||||
xStreamBufferSendFromISR(instance->stream, &pair, sizeof(LevelPair), &xHigherPriorityTaskWoken);
|
||||
if(sizeof(LevelPair) != ret) instance->overrun = true;
|
||||
xStreamBufferSendFromISR(instance->stream, &level_duration, sizeof(LevelDuration), &xHigherPriorityTaskWoken);
|
||||
if(sizeof(LevelDuration) != ret) instance->overrun = true;
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
@@ -48,15 +44,17 @@ void subghz_worker_rx_callback(
|
||||
static int32_t subghz_worker_thread_callback(void* context) {
|
||||
SubGhzWorker* instance = context;
|
||||
|
||||
LevelPair pair;
|
||||
LevelDuration level_duration;
|
||||
while(instance->running) {
|
||||
int ret = xStreamBufferReceive(instance->stream, &pair, sizeof(LevelPair), 10);
|
||||
if(ret == sizeof(LevelPair)) {
|
||||
if(pair.level == ApiHalSubGhzCaptureLevelOverrun) {
|
||||
int ret = xStreamBufferReceive(instance->stream, &level_duration, sizeof(LevelDuration), 10);
|
||||
if(ret == sizeof(LevelDuration)) {
|
||||
if(level_duration_is_reset(level_duration)) {
|
||||
printf(".");
|
||||
if (instance->overrun_callback) instance->overrun_callback(instance->context);
|
||||
} else {
|
||||
if (instance->pair_callback) instance->pair_callback(instance->context, pair);
|
||||
bool level = level_duration_get_level(level_duration);
|
||||
uint32_t duration = level_duration_get_duration(level_duration);
|
||||
if (instance->pair_callback) instance->pair_callback(instance->context, level, duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,7 +71,7 @@ SubGhzWorker* subghz_worker_alloc() {
|
||||
furi_thread_set_context(instance->thread, instance);
|
||||
furi_thread_set_callback(instance->thread, subghz_worker_thread_callback);
|
||||
|
||||
instance->stream = xStreamBufferCreate(sizeof(LevelPair) * 1024, sizeof(LevelPair));
|
||||
instance->stream = xStreamBufferCreate(sizeof(LevelDuration) * 1024, sizeof(LevelDuration));
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
@@ -6,9 +6,9 @@ typedef struct SubGhzWorker SubGhzWorker;
|
||||
|
||||
typedef void (*SubGhzWorkerOverrunCallback)(void* context);
|
||||
|
||||
typedef void (*SubGhzWorkerPairCallback)(void* context, LevelPair pair);
|
||||
typedef void (*SubGhzWorkerPairCallback)(void* context, bool level, uint32_t duration);
|
||||
|
||||
void subghz_worker_rx_callback(ApiHalSubGhzCaptureLevel level, uint32_t duration, void* context);
|
||||
void subghz_worker_rx_callback(bool level, uint32_t duration, void* context);
|
||||
|
||||
/** Allocate SubGhzWorker
|
||||
*
|
||||
|
71
lib/toolbox/level_duration.h
Normal file
71
lib/toolbox/level_duration.h
Normal file
@@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define LEVEL_DURATION_BIG
|
||||
|
||||
#ifdef LEVEL_DURATION_BIG
|
||||
|
||||
#define LEVEL_DURATION_RESET 0U
|
||||
#define LEVEL_DURATION_LEVEL_LOW 1U
|
||||
#define LEVEL_DURATION_LEVEL_HIGH 2U
|
||||
#define LEVEL_DURATION_RESERVED 0x800000U
|
||||
|
||||
typedef struct {
|
||||
uint32_t level;
|
||||
uint32_t duration;
|
||||
} LevelDuration;
|
||||
|
||||
static inline LevelDuration level_duration_make(bool level, uint32_t duration) {
|
||||
LevelDuration level_duration;
|
||||
level_duration.level = level ? LEVEL_DURATION_LEVEL_HIGH : LEVEL_DURATION_LEVEL_LOW;
|
||||
level_duration.duration = duration;
|
||||
return level_duration;
|
||||
}
|
||||
|
||||
static inline LevelDuration level_duration_reset() {
|
||||
LevelDuration level_duration;
|
||||
level_duration.level = LEVEL_DURATION_RESET;
|
||||
return level_duration;
|
||||
}
|
||||
|
||||
static inline bool level_duration_is_reset(LevelDuration level_duration) {
|
||||
return level_duration.level == LEVEL_DURATION_RESET;
|
||||
}
|
||||
|
||||
static inline bool level_duration_get_level(LevelDuration level_duration) {
|
||||
return level_duration.level == LEVEL_DURATION_LEVEL_HIGH;
|
||||
}
|
||||
|
||||
static inline uint32_t level_duration_get_duration(LevelDuration level_duration) {
|
||||
return level_duration.duration;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define LEVEL_DURATION_RESET 0U
|
||||
#define LEVEL_DURATION_RESERVED 0x800000U
|
||||
|
||||
typedef int32_t LevelDuration;
|
||||
|
||||
static inline LevelDuration level_duration(bool level, uint32_t duration) {
|
||||
return level ? duration : -(int32_t)duration;
|
||||
}
|
||||
|
||||
static inline LevelDuration level_duration_reset() {
|
||||
return LEVEL_DURATION_RESET;
|
||||
}
|
||||
|
||||
static inline bool level_duration_is_reset(LevelDuration level_duration) {
|
||||
return (level_duration == LEVEL_DURATION_RESET);
|
||||
}
|
||||
|
||||
static inline bool level_duration_get_level(LevelDuration level_duration) {
|
||||
return (level_duration > 0);
|
||||
}
|
||||
|
||||
static inline uint32_t level_duration_get_duration(LevelDuration level_duration) {
|
||||
return (level_duration >= 0) ? level_duration : -level_duration;
|
||||
}
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user