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:
Skorpionm
2021-07-07 23:49:45 +04:00
committed by GitHub
parent a7283280ef
commit 4ce41a3e6f
21 changed files with 328 additions and 150 deletions

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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);;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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
*

View File

@@ -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

View File

@@ -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);;

View File

@@ -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

View File

@@ -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
*

View File

@@ -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 {

View File

@@ -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
*

View File

@@ -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;
}

View File

@@ -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
*

View 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