From 5df346aebe031f3d20ba4240ee507cf664b5ea2c Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Tue, 13 Jul 2021 15:47:27 +0400 Subject: [PATCH] Skorp sub ghz add protocol (#578) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SubGhz: add HCS101 protocol * SubGhz: add GateTx protocol * GubGHz: keeLog, key re-acceptance check, do not decrypt repeated messages * SubGhz: add iDo 117/111 protocol * SubGhz: add Faac SLH protocol * SubGhz: fix KeeLog, serial number on display * SubGhz: fix Faac SLH, serial number on display. Refactoring code parser * SubGhz: add Nero Sketch protocol * SubGhz: fix showing serial key, Gate Tx protocol Co-authored-by: あく --- lib/fl_subghz/protocols/subghz_protocol.c | 33 +++ .../protocols/subghz_protocol_came.h | 2 +- .../protocols/subghz_protocol_faac_slh.c | 162 ++++++++++++++ .../protocols/subghz_protocol_faac_slh.h | 51 +++++ .../protocols/subghz_protocol_gate_tx.c | 154 ++++++++++++++ .../protocols/subghz_protocol_gate_tx.h | 45 ++++ lib/fl_subghz/protocols/subghz_protocol_ido.c | 160 ++++++++++++++ lib/fl_subghz/protocols/subghz_protocol_ido.h | 51 +++++ .../protocols/subghz_protocol_keeloq.c | 23 +- .../protocols/subghz_protocol_keeloq.h | 2 +- .../protocols/subghz_protocol_nero_sketch.c | 200 ++++++++++++++++++ .../protocols/subghz_protocol_nero_sketch.h | 51 +++++ .../protocols/subghz_protocol_nice_flo.h | 2 +- .../protocols/subghz_protocol_nice_flor_s.h | 2 +- .../protocols/subghz_protocol_princeton.h | 8 +- 15 files changed, 923 insertions(+), 23 deletions(-) create mode 100644 lib/fl_subghz/protocols/subghz_protocol_faac_slh.c create mode 100644 lib/fl_subghz/protocols/subghz_protocol_faac_slh.h create mode 100644 lib/fl_subghz/protocols/subghz_protocol_gate_tx.c create mode 100644 lib/fl_subghz/protocols/subghz_protocol_gate_tx.h create mode 100644 lib/fl_subghz/protocols/subghz_protocol_ido.c create mode 100644 lib/fl_subghz/protocols/subghz_protocol_ido.h create mode 100644 lib/fl_subghz/protocols/subghz_protocol_nero_sketch.c create mode 100644 lib/fl_subghz/protocols/subghz_protocol_nero_sketch.h diff --git a/lib/fl_subghz/protocols/subghz_protocol.c b/lib/fl_subghz/protocols/subghz_protocol.c index 684e0629..e85c4268 100644 --- a/lib/fl_subghz/protocols/subghz_protocol.c +++ b/lib/fl_subghz/protocols/subghz_protocol.c @@ -6,6 +6,10 @@ #include "subghz_protocol_nice_flo.h" #include "subghz_protocol_nice_flor_s.h" #include "subghz_protocol_princeton.h" +#include "subghz_protocol_gate_tx.h" +#include "subghz_protocol_ido.h" +#include "subghz_protocol_faac_slh.h" +#include "subghz_protocol_nero_sketch.h" #include #include @@ -19,6 +23,10 @@ struct SubGhzProtocol { SubGhzProtocolNiceFlo* nice_flo; SubGhzProtocolNiceFlorS* nice_flor_s; SubGhzProtocolPrinceton* princeton; + SubGhzProtocolGateTX* gate_tx; + SubGhzProtocolIDo* ido; + SubGhzProtocolFaacSLH* faac_slh; + SubGhzProtocolNeroSketch* nero_sketch; SubGhzProtocolTextCallback text_callback; void* text_callback_context; @@ -55,6 +63,10 @@ SubGhzProtocol* subghz_protocol_alloc() { instance->princeton = subghz_protocol_princeton_alloc(); instance->nice_flo = subghz_protocol_nice_flo_alloc(); instance->nice_flor_s = subghz_protocol_nice_flor_s_alloc(); + instance->gate_tx = subghz_protocol_gate_tx_alloc(); + instance->ido = subghz_protocol_ido_alloc(); + instance->faac_slh = subghz_protocol_faac_slh_alloc(); + instance->nero_sketch = subghz_protocol_nero_sketch_alloc(); return instance; } @@ -67,6 +79,10 @@ void subghz_protocol_free(SubGhzProtocol* instance) { subghz_protocol_princeton_free(instance->princeton); subghz_protocol_nice_flo_free(instance->nice_flo); subghz_protocol_nice_flor_s_free(instance->nice_flor_s); + subghz_protocol_gate_tx_free(instance->gate_tx); + subghz_protocol_ido_free(instance->ido); + subghz_protocol_faac_slh_free(instance->faac_slh); + subghz_protocol_nero_sketch_free(instance->nero_sketch); free(instance); } @@ -79,6 +95,10 @@ void subghz_protocol_enable_dump_text(SubGhzProtocol* instance, SubGhzProtocolTe 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); + subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->gate_tx, subghz_protocol_text_rx_callback, instance); + subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->ido, subghz_protocol_text_rx_callback, instance); + subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->faac_slh, subghz_protocol_text_rx_callback, instance); + subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->nero_sketch, subghz_protocol_text_rx_callback, instance); instance->text_callback = callback; instance->text_callback_context = context; @@ -92,6 +112,11 @@ void subghz_protocol_enable_dump(SubGhzProtocol* instance, SubGhzProtocolCommonC 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); + subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->gate_tx, subghz_protocol_parser_rx_callback, instance); + subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->ido, subghz_protocol_parser_rx_callback, instance); + subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->faac_slh, subghz_protocol_parser_rx_callback, instance); + subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->nero_sketch, subghz_protocol_parser_rx_callback, instance); + instance->parser_callback = callback; instance->parser_callback_context = context; } @@ -149,6 +174,10 @@ void subghz_protocol_reset(SubGhzProtocol* instance) { subghz_protocol_princeton_reset(instance->princeton); subghz_protocol_nice_flo_reset(instance->nice_flo); subghz_protocol_nice_flor_s_reset(instance->nice_flor_s); + subghz_protocol_gate_tx_reset(instance->gate_tx); + subghz_protocol_ido_reset(instance->ido); + subghz_protocol_faac_slh_reset(instance->faac_slh); + subghz_protocol_nero_sketch_reset(instance->nero_sketch); } void subghz_protocol_parse(SubGhzProtocol* instance, bool level, uint32_t duration) { @@ -157,4 +186,8 @@ void subghz_protocol_parse(SubGhzProtocol* instance, bool level, uint32_t durati 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); + subghz_protocol_gate_tx_parse(instance->gate_tx, level, duration); + subghz_protocol_ido_parse(instance->ido, level, duration); + subghz_protocol_faac_slh_parse(instance->faac_slh, level, duration); + subghz_protocol_nero_sketch_parse(instance->nero_sketch, level, duration); } diff --git a/lib/fl_subghz/protocols/subghz_protocol_came.h b/lib/fl_subghz/protocols/subghz_protocol_came.h index 3babbff1..7ce1aa09 100644 --- a/lib/fl_subghz/protocols/subghz_protocol_came.h +++ b/lib/fl_subghz/protocols/subghz_protocol_came.h @@ -35,4 +35,4 @@ void subghz_protocol_came_reset(SubGhzProtocolCame* instance); * @param instance - SubGhzProtocolCame instance * @param data - LevelDuration level_duration */ -void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32_t duration);; +void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32_t duration); diff --git a/lib/fl_subghz/protocols/subghz_protocol_faac_slh.c b/lib/fl_subghz/protocols/subghz_protocol_faac_slh.c new file mode 100644 index 00000000..cc436dfe --- /dev/null +++ b/lib/fl_subghz/protocols/subghz_protocol_faac_slh.c @@ -0,0 +1,162 @@ +#include "subghz_protocol_faac_slh.h" + + +struct SubGhzProtocolFaacSLH { + SubGhzProtocolCommon common; +}; + +SubGhzProtocolFaacSLH* subghz_protocol_faac_slh_alloc(void) { + SubGhzProtocolFaacSLH* instance = furi_alloc(sizeof(SubGhzProtocolFaacSLH)); + + instance->common.name = "Faac SLH"; + instance->common.code_min_count_bit_for_found = 64; + instance->common.te_shot = 255; + instance->common.te_long = 595; + instance->common.te_delta = 100; + instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_faac_slh_to_str; + + return instance; +} + +void subghz_protocol_faac_slh_free(SubGhzProtocolFaacSLH* instance) { + furi_assert(instance); + free(instance); +} + +/** Send bit + * + * @param instance - SubGhzProtocolFaacSLH instance + * @param bit - bit + */ +void subghz_protocol_faac_slh_send_bit(SubGhzProtocolFaacSLH* instance, uint8_t bit) { + if (bit) { + //send bit 1 + SUBGHZ_TX_PIN_HIGTH(); + delay_us(instance->common.te_long); + SUBGHZ_TX_PIN_LOW(); + delay_us(instance->common.te_shot); + } else { + //send bit 0 + SUBGHZ_TX_PIN_HIGTH(); + delay_us(instance->common.te_shot); + SUBGHZ_TX_PIN_LOW(); + delay_us(instance->common.te_long); + } +} + +void subghz_protocol_faac_slh_send_key(SubGhzProtocolFaacSLH* instance, uint64_t key, uint8_t bit,uint8_t repeat) { + while (repeat--) { + SUBGHZ_TX_PIN_HIGTH(); + //Send header + delay_us(instance->common.te_long * 2); + SUBGHZ_TX_PIN_LOW(); + delay_us(instance->common.te_long * 2); + //Send key data + for (uint8_t i = bit; i > 0; i--) { + subghz_protocol_faac_slh_send_bit(instance, bit_read(key, i - 1)); + } + } +} + +void subghz_protocol_faac_slh_reset(SubGhzProtocolFaacSLH* instance) { + instance->common.parser_step = 0; +} + +/** Analysis of received data + * + * @param instance SubGhzProtocolFaacSLH instance + */ +void subghz_protocol_faac_slh_check_remote_controller(SubGhzProtocolFaacSLH* instance) { + uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit); + uint32_t code_fix = code_found_reverse & 0xFFFFFFFF; + //uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFF; + + instance->common.serial = code_fix & 0xFFFFFFF; + instance->common.btn = (code_fix >> 28) & 0x0F; + + if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); + +} + +void subghz_protocol_faac_slh_parse(SubGhzProtocolFaacSLH* instance, bool level, uint32_t duration) { + switch (instance->common.parser_step) { + case 0: + if ((level) + && (DURATION_DIFF(duration,instance->common.te_long * 2)< instance->common.te_delta * 3)) { + instance->common.parser_step = 1; + } else { + instance->common.parser_step = 0; + } + break; + case 1: + if ((!level) + && (DURATION_DIFF(duration,instance->common.te_long * 2)< instance->common.te_delta * 3)) { + //Found Preambula + instance->common.parser_step = 2; + instance->common.code_found = 0; + instance->common.code_count_bit = 0; + } else { + instance->common.parser_step = 0; + } + break; + case 2: + if (level) { + if (duration >= (instance->common.te_shot * 3 + instance->common.te_delta)) { + instance->common.parser_step = 1; + if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { + subghz_protocol_faac_slh_check_remote_controller(instance); + } + instance->common.code_found = 0; + instance->common.code_count_bit = 0; + break; + } else { + instance->common.te_last = duration; + instance->common.parser_step = 3; + } + + }else{ + instance->common.parser_step = 0; + } + break; + case 3: + if(!level){ + if ((DURATION_DIFF(instance->common.te_last,instance->common.te_shot)< 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(duration,instance->common.te_shot)< instance->common.te_delta)) { + subghz_protocol_common_add_bit(&instance->common, 1); + instance->common.parser_step = 2; + } else { + instance->common.parser_step = 0; + } + } else { + instance->common.parser_step = 0; + } + break; + } +} + +void subghz_protocol_faac_slh_to_str(SubGhzProtocolFaacSLH* instance, string_t output) { + + uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit); + uint32_t code_fix = code_found_reverse & 0xFFFFFFFF; + uint32_t code_hop = (code_found_reverse >>32) & 0xFFFFFFFF; + + //uint32_t rev_hi = + + string_cat_printf(output, + "Protocol %s, %d Bit\r\n" + " KEY:0x%lX%08lX\r\n" + " FIX:%08lX \r\n" + " HOP:%08lX \r\n" + " SN:%07lX BTN:%lX\r\n", + instance->common.name, + instance->common.code_count_bit, + (uint32_t)(instance->common.code_found >> 32), + (uint32_t)instance->common.code_found, + code_fix, code_hop, + instance->common.serial, + instance->common.btn); +} \ No newline at end of file diff --git a/lib/fl_subghz/protocols/subghz_protocol_faac_slh.h b/lib/fl_subghz/protocols/subghz_protocol_faac_slh.h new file mode 100644 index 00000000..26b4ac08 --- /dev/null +++ b/lib/fl_subghz/protocols/subghz_protocol_faac_slh.h @@ -0,0 +1,51 @@ +#pragma once + +#include "subghz_protocol_common.h" + +typedef struct SubGhzProtocolFaacSLH SubGhzProtocolFaacSLH; + +/** Allocate SubGhzProtocolFaacSLH + * + * @return SubGhzProtocolFaacSLH* + */ +SubGhzProtocolFaacSLH* subghz_protocol_faac_slh_alloc(); + +/** Free SubGhzProtocolFaacSLH + * + * @param instance + */ +void subghz_protocol_faac_slh_free(SubGhzProtocolFaacSLH* instance); + +/** Sends the key on the air + * + * @param instance - SubGhzProtocolFaacSLH instance + * @param key - key send + * @param bit - count bit key + * @param repeat - repeat send key + */ +void subghz_protocol_faac_slh_send_key(SubGhzProtocolFaacSLH* instance, uint64_t key, uint8_t bit, uint8_t repeat); + +/** Reset internal state + * @param instance - SubGhzProtocolFaacSLH instance + */ +void subghz_protocol_faac_slh_reset(SubGhzProtocolFaacSLH* instance); + +/** Analysis of received data + * + * @param instance SubGhzProtocolFaacSLH instance + */ +void subghz_protocol_faac_slh_check_remote_controller(SubGhzProtocolFaacSLH* instance); + +/** Parse accepted duration + * + * @param instance - SubGhzProtocolFaacSLH instance + * @param data - LevelDuration level_duration + */ +void subghz_protocol_faac_slh_parse(SubGhzProtocolFaacSLH* instance, bool level, uint32_t duration); + +/** Outputting information from the parser + * + * @param instance - SubGhzProtocolFaacSLH* instance + * @param output - output string + */ +void subghz_protocol_faac_slh_to_str(SubGhzProtocolFaacSLH* instance, string_t output); diff --git a/lib/fl_subghz/protocols/subghz_protocol_gate_tx.c b/lib/fl_subghz/protocols/subghz_protocol_gate_tx.c new file mode 100644 index 00000000..90fa0521 --- /dev/null +++ b/lib/fl_subghz/protocols/subghz_protocol_gate_tx.c @@ -0,0 +1,154 @@ +#include "subghz_protocol_gate_tx.h" + + +struct SubGhzProtocolGateTX { + SubGhzProtocolCommon common; +}; + +SubGhzProtocolGateTX* subghz_protocol_gate_tx_alloc(void) { + SubGhzProtocolGateTX* instance = furi_alloc(sizeof(SubGhzProtocolGateTX)); + + instance->common.name = "GateTX"; + instance->common.code_min_count_bit_for_found = 24; + instance->common.te_shot = 350; + instance->common.te_long = 700; + instance->common.te_delta = 100; + instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_gate_tx_to_str; + + return instance; +} + +void subghz_protocol_gate_tx_free(SubGhzProtocolGateTX* instance) { + furi_assert(instance); + free(instance); +} + +/** Send bit + * + * @param instance - SubGhzProtocolGateTX instance + * @param bit - bit + */ +void subghz_protocol_gate_tx_send_bit(SubGhzProtocolGateTX* instance, uint8_t bit) { + if (bit) { + //send bit 1 + SUBGHZ_TX_PIN_LOW(); + delay_us(instance->common.te_long); + SUBGHZ_TX_PIN_HIGTH(); + delay_us(instance->common.te_shot); + } else { + //send bit 0 + SUBGHZ_TX_PIN_LOW(); + delay_us(instance->common.te_shot); + SUBGHZ_TX_PIN_HIGTH(); + delay_us(instance->common.te_long); + } +} + +void subghz_protocol_gate_tx_send_key(SubGhzProtocolGateTX* instance, uint64_t key, uint8_t bit,uint8_t repeat) { + while (repeat--) { + //Send header + SUBGHZ_TX_PIN_LOW(); + delay_us(instance->common.te_shot * 47); //+2 interval v bit 1 + //Send start bit + SUBGHZ_TX_PIN_HIGTH(); + delay_us(instance->common.te_long); + //Send key data + for (uint8_t i = bit; i > 0; i--) { + subghz_protocol_gate_tx_send_bit(instance, bit_read(key, i - 1)); + } + } +} + +void subghz_protocol_gate_tx_reset(SubGhzProtocolGateTX* instance) { + instance->common.parser_step = 0; +} + +/** Analysis of received data + * + * @param instance SubGhzProtocolFaacSLH instance + */ +void subghz_protocol_gate_tx_check_remote_controller(SubGhzProtocolGateTX* instance) { + uint32_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit); + + instance->common.serial = (code_found_reverse & 0xFF) << 12 | ((code_found_reverse >>8) & 0xFF) << 4 | ((code_found_reverse >>20) & 0x0F) ; + instance->common.btn = ((code_found_reverse >> 16) & 0x0F); + + if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); + +} + +void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, uint32_t duration) { + switch (instance->common.parser_step) { + case 0: + if ((!level) + && (DURATION_DIFF(duration,instance->common.te_shot * 47)< instance->common.te_delta * 47)) { + //Found Preambula + instance->common.parser_step = 1; + } else { + instance->common.parser_step = 0; + } + break; + case 1: + if (level && ((DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta*3))){ + //Found start bit + instance->common.parser_step = 2; + instance->common.code_found = 0; + instance->common.code_count_bit = 0; + } else { + instance->common.parser_step = 0; + } + break; + case 2: + 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) { + subghz_protocol_gate_tx_check_remote_controller(instance); + } + instance->common.code_found = 0; + instance->common.code_count_bit = 0; + break; + } else { + instance->common.te_last = duration; + instance->common.parser_step = 3; + } + } + break; + case 3: + if(level){ + if ((DURATION_DIFF(instance->common.te_last,instance->common.te_shot)< instance->common.te_delta) + && (DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta*3)) { + 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*3) + && (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 { + instance->common.parser_step = 0; + } + }else{ + instance->common.parser_step = 0; + } + break; + } +} + +void subghz_protocol_gate_tx_to_str(SubGhzProtocolGateTX* instance, string_t output) { + + // uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit); + // uint32_t code_fix = code_found_reverse & 0xFFFFFFFF; + // uint32_t code_hop = (code_found_reverse >>32) & 0xFFFFFFFF; + + //uint32_t rev_hi = + + string_cat_printf(output, + "Protocol %s, %d Bit\r\n" + " KEY:%06lX\r\n" + " SN:%05lX BTN:%lX\r\n", + instance->common.name, + instance->common.code_count_bit, + (uint32_t)(instance->common.code_found & 0xFFFFFF), + instance->common.serial, + instance->common.btn); +} \ No newline at end of file diff --git a/lib/fl_subghz/protocols/subghz_protocol_gate_tx.h b/lib/fl_subghz/protocols/subghz_protocol_gate_tx.h new file mode 100644 index 00000000..3e73da92 --- /dev/null +++ b/lib/fl_subghz/protocols/subghz_protocol_gate_tx.h @@ -0,0 +1,45 @@ +#pragma once + +#include "subghz_protocol_common.h" + +typedef struct SubGhzProtocolGateTX SubGhzProtocolGateTX; + +/** Allocate SubGhzProtocolGateTX + * + * @return SubGhzProtocolGateTX* + */ +SubGhzProtocolGateTX* subghz_protocol_gate_tx_alloc(); + +/** Free SubGhzProtocolGateTX + * + * @param instance + */ +void subghz_protocol_gate_tx_free(SubGhzProtocolGateTX* instance); + +/** Sends the key on the air + * + * @param instance - SubGhzProtocolGateTX instance + * @param key - key send + * @param bit - count bit key + * @param repeat - repeat send key + */ +void subghz_protocol_gate_tx_send_key(SubGhzProtocolGateTX* instance, uint64_t key, uint8_t bit, uint8_t repeat); + +/** Reset internal state + * @param instance - SubGhzProtocolGateTX instance + */ +void subghz_protocol_gate_tx_reset(SubGhzProtocolGateTX* instance); + +/** Parse accepted duration + * + * @param instance - SubGhzProtocolGateTX instance + * @param data - LevelDuration level_duration + */ +void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, uint32_t duration); + +/** Outputting information from the parser + * + * @param instance - SubGhzProtocolFaacSLH* instance + * @param output - output string + */ +void subghz_protocol_gate_tx_to_str(SubGhzProtocolGateTX* instance, string_t output); \ No newline at end of file diff --git a/lib/fl_subghz/protocols/subghz_protocol_ido.c b/lib/fl_subghz/protocols/subghz_protocol_ido.c new file mode 100644 index 00000000..7b95061a --- /dev/null +++ b/lib/fl_subghz/protocols/subghz_protocol_ido.c @@ -0,0 +1,160 @@ +#include "subghz_protocol_ido.h" + + +struct SubGhzProtocolIDo { + SubGhzProtocolCommon common; +}; + +SubGhzProtocolIDo* subghz_protocol_ido_alloc(void) { + SubGhzProtocolIDo* instance = furi_alloc(sizeof(SubGhzProtocolIDo)); + + instance->common.name = "iDo 117/111"; // PT4301-X"; + instance->common.code_min_count_bit_for_found = 48; + instance->common.te_shot = 450; + instance->common.te_long = 1450; + instance->common.te_delta = 150; + instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_ido_to_str; + + return instance; +} + +void subghz_protocol_ido_free(SubGhzProtocolIDo* instance) { + furi_assert(instance); + free(instance); +} + +/** Send bit + * + * @param instance - SubGhzProtocolIDo instance + * @param bit - bit + */ +void subghz_protocol_ido_send_bit(SubGhzProtocolIDo* instance, uint8_t bit) { + if (bit) { + //send bit 1 + SUBGHZ_TX_PIN_HIGTH(); + delay_us(instance->common.te_shot); + SUBGHZ_TX_PIN_LOW(); + delay_us(instance->common.te_shot); + } else { + //send bit 0 + SUBGHZ_TX_PIN_HIGTH(); + delay_us(instance->common.te_shot); + SUBGHZ_TX_PIN_LOW(); + delay_us(instance->common.te_long); + } +} + +void subghz_protocol_ido_send_key(SubGhzProtocolIDo* instance, uint64_t key, uint8_t bit,uint8_t repeat) { + while (repeat--) { + SUBGHZ_TX_PIN_HIGTH(); + //Send header + delay_us(instance->common.te_shot * 10); + SUBGHZ_TX_PIN_LOW(); + delay_us(instance->common.te_shot * 10); + //Send key data + for (uint8_t i = bit; i > 0; i--) { + subghz_protocol_ido_send_bit(instance, bit_read(key, i - 1)); + } + } +} + +void subghz_protocol_ido_reset(SubGhzProtocolIDo* instance) { + instance->common.parser_step = 0; +} + +/** Analysis of received data + * + * @param instance SubGhzProtocolIDo instance + */ +void subghz_protocol_ido_check_remote_controller(SubGhzProtocolIDo* instance) { + uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit); + uint32_t code_fix = code_found_reverse & 0xFFFFFF; + //uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFF; + + instance->common.serial = code_fix & 0xFFFFF; + instance->common.btn = (code_fix >> 20) & 0x0F; + + if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); + +} + +void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t duration) { + switch (instance->common.parser_step) { + case 0: + if ((level) + && (DURATION_DIFF(duration,instance->common.te_shot * 10)< instance->common.te_delta * 5)) { + instance->common.parser_step = 1; + } else { + instance->common.parser_step = 0; + } + break; + case 1: + if ((!level) + && (DURATION_DIFF(duration,instance->common.te_shot * 10)< instance->common.te_delta * 5)) { + //Found Preambula + instance->common.parser_step = 2; + instance->common.code_found = 0; + instance->common.code_count_bit = 0; + } else { + instance->common.parser_step = 0; + } + break; + case 2: + if (level) { + if (duration >= (instance->common.te_shot * 5 + instance->common.te_delta)) { + instance->common.parser_step = 1; + if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { + subghz_protocol_ido_check_remote_controller(instance); + } + instance->common.code_found = 0; + instance->common.code_count_bit = 0; + break; + } else { + instance->common.te_last = duration; + instance->common.parser_step = 3; + } + + }else{ + instance->common.parser_step = 0; + } + break; + case 3: + if(!level){ + if ((DURATION_DIFF(instance->common.te_last,instance->common.te_shot)< instance->common.te_delta) + && (DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta*3)) { + subghz_protocol_common_add_bit(&instance->common, 0); + instance->common.parser_step = 2; + } else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_shot )< instance->common.te_delta*3) + && (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 { + instance->common.parser_step = 0; + } + } else { + instance->common.parser_step = 0; + } + break; + } +} + +void subghz_protocol_ido_to_str(SubGhzProtocolIDo* instance, string_t output) { + + uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit); + uint32_t code_fix = code_found_reverse & 0xFFFFFF; + uint32_t code_hop = (code_found_reverse >>24) & 0xFFFFFF; + + string_cat_printf(output, + "Protocol %s, %d Bit\r\n" + " KEY:0x%lX%08lX\r\n" + " FIX:%06lX \r\n" + " HOP:%06lX \r\n" + " SN:%05lX BTN:%lX\r\n", + instance->common.name, + instance->common.code_count_bit, + (uint32_t)(instance->common.code_found >> 32), + (uint32_t)instance->common.code_found, + code_fix, code_hop, + instance->common.serial, + instance->common.btn); +} \ No newline at end of file diff --git a/lib/fl_subghz/protocols/subghz_protocol_ido.h b/lib/fl_subghz/protocols/subghz_protocol_ido.h new file mode 100644 index 00000000..35d26967 --- /dev/null +++ b/lib/fl_subghz/protocols/subghz_protocol_ido.h @@ -0,0 +1,51 @@ +#pragma once + +#include "subghz_protocol_common.h" + +typedef struct SubGhzProtocolIDo SubGhzProtocolIDo; + +/** Allocate SubGhzProtocolIDo + * + * @return SubGhzProtocolIDo* + */ +SubGhzProtocolIDo* subghz_protocol_ido_alloc(); + +/** Free SubGhzProtocolIDo + * + * @param instance + */ +void subghz_protocol_ido_free(SubGhzProtocolIDo* instance); + +/** Sends the key on the air + * + * @param instance - SubGhzProtocolIDo instance + * @param key - key send + * @param bit - count bit key + * @param repeat - repeat send key + */ +void subghz_protocol_ido_send_key(SubGhzProtocolIDo* instance, uint64_t key, uint8_t bit, uint8_t repeat); + +/** Reset internal state + * @param instance - SubGhzProtocolIDo instance + */ +void subghz_protocol_ido_reset(SubGhzProtocolIDo* instance); + +/** Analysis of received data + * + * @param instance SubGhzProtocolIDo instance + */ +void subghz_protocol_ido_check_remote_controller(SubGhzProtocolIDo* instance); + +/** Parse accepted duration + * + * @param instance - SubGhzProtocolIDo instance + * @param data - LevelDuration level_duration + */ +void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t duration); + +/** Outputting information from the parser + * + * @param instance - SubGhzProtocolIDo* instance + * @param output - output string + */ +void subghz_protocol_ido_to_str(SubGhzProtocolIDo* instance, string_t output); diff --git a/lib/fl_subghz/protocols/subghz_protocol_keeloq.c b/lib/fl_subghz/protocols/subghz_protocol_keeloq.c index 974dcec9..02bc23d5 100644 --- a/lib/fl_subghz/protocols/subghz_protocol_keeloq.c +++ b/lib/fl_subghz/protocols/subghz_protocol_keeloq.c @@ -216,13 +216,16 @@ void subghz_protocol_keeloq_check_remote_controller(SubGhzProtocolKeeloq* instan uint32_t key_fix = key >> 32; uint32_t key_hop = key & 0x00000000ffffffff; // Check key AN-Motors - if((key_hop >> 24) == ((key_hop>>16)&0x00ff) && (key_fix>>28) ==((key_hop>>12)&0x0f) ){ + if((key_hop >> 24) == ((key_hop>>16)&0x00ff) && (key_fix>>28) ==((key_hop>>12)&0x0f) && (key_hop & 0xFFF ) == 0x404){ instance->manufacture_name = "AN-Motors"; instance->common.cnt = key_hop>>16; + } else if((key_hop & 0xFFF) == (0x000) && (key_fix>>28) ==((key_hop>>12)&0x0f) ){ + instance->manufacture_name = "HCS101"; + instance->common.cnt = key_hop>>16; } else { subghz_protocol_keeloq_check_remote_controller_selector(instance, key_fix, key_hop); } - instance ->common.serial= key_fix&0x0FFFFF; + instance ->common.serial= key_fix&0x0FFFFFFF; instance->common.btn = key_fix >> 28; if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); } @@ -313,10 +316,10 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui // Found end TX instance->common.parser_step = 0; if (instance->common.code_count_bit >= instance->common.code_min_count_bit_for_found) { + if(instance->common.code_last_found != instance->common.code_found ){ + subghz_protocol_keeloq_check_remote_controller(instance); + } instance->common.code_last_found = instance->common.code_found; - - subghz_protocol_keeloq_check_remote_controller(instance); - instance->common.code_found = 0; instance->common.code_count_bit = 0; instance->common.header_count = 0; @@ -358,17 +361,13 @@ void subghz_protocol_keeloq_to_str(SubGhzProtocolKeeloq* instance, string_t outp output, "Protocol %s, %d Bit\r\n" "KEY:0x%lX%lX\r\n" - "FIX:%lX MF:%s \r\n" - "HOP:%lX \r\n" - //"CNT:%04X BTN:%02lX\r\n", - "SN:%05lX CNT:%04X BTN:%02lX\r\n", - //"YEK:0x%lX%lX\r\n", + "FIX:%08lX MF:%s \r\n" + "HOP:%08lX \r\n" + "SN:%07lX CNT:%04X B:%02lX\r\n", instance->common.name, instance->common.code_count_bit, code_found_hi, code_found_lo, - //code_found_reverse_hi, - //code_found_reverse_lo code_found_reverse_hi, instance->manufacture_name, code_found_reverse_lo, diff --git a/lib/fl_subghz/protocols/subghz_protocol_keeloq.h b/lib/fl_subghz/protocols/subghz_protocol_keeloq.h index a4bf61bd..5d9185f0 100644 --- a/lib/fl_subghz/protocols/subghz_protocol_keeloq.h +++ b/lib/fl_subghz/protocols/subghz_protocol_keeloq.h @@ -44,7 +44,7 @@ void subghz_protocol_keeloq_reset(SubGhzProtocolKeeloq* instance); * @param instance - SubGhzProtocolKeeloq instance * @param data - LevelDuration level_duration */ -void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, uint32_t duration);; +void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, uint32_t duration); /** Outputting information from the parser * diff --git a/lib/fl_subghz/protocols/subghz_protocol_nero_sketch.c b/lib/fl_subghz/protocols/subghz_protocol_nero_sketch.c new file mode 100644 index 00000000..5f9f6a51 --- /dev/null +++ b/lib/fl_subghz/protocols/subghz_protocol_nero_sketch.c @@ -0,0 +1,200 @@ +#include "subghz_protocol_nero_sketch.h" + + +struct SubGhzProtocolNeroSketch { + SubGhzProtocolCommon common; +}; + +SubGhzProtocolNeroSketch* subghz_protocol_nero_sketch_alloc(void) { + SubGhzProtocolNeroSketch* instance = furi_alloc(sizeof(SubGhzProtocolNeroSketch)); + + instance->common.name = "Nero Sketch"; + instance->common.code_min_count_bit_for_found = 40; + instance->common.te_shot = 330; + instance->common.te_long = 660; + instance->common.te_delta = 150; + instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nero_sketch_to_str; + + return instance; +} + +void subghz_protocol_nero_sketch_free(SubGhzProtocolNeroSketch* instance) { + furi_assert(instance); + free(instance); +} + +/** Send bit + * + * @param instance - SubGhzProtocolNeroSketch instance + * @param bit - bit + */ +void subghz_protocol_nero_sketch_send_bit(SubGhzProtocolNeroSketch* instance, uint8_t bit) { + if (bit) { + //send bit 1 + SUBGHZ_TX_PIN_HIGTH(); + delay_us(instance->common.te_long); + SUBGHZ_TX_PIN_LOW(); + delay_us(instance->common.te_shot); + } else { + //send bit 0 + SUBGHZ_TX_PIN_HIGTH(); + delay_us(instance->common.te_shot); + SUBGHZ_TX_PIN_LOW(); + delay_us(instance->common.te_long); + } +} + +void subghz_protocol_nero_sketch_send_key(SubGhzProtocolNeroSketch* instance, uint64_t key, uint8_t bit,uint8_t repeat) { + while (repeat--) { + //Send header + for(uint8_t i = 0; i < 47; i++){ + SUBGHZ_TX_PIN_HIGTH(); + delay_us(instance->common.te_shot); + SUBGHZ_TX_PIN_LOW(); + delay_us(instance->common.te_shot); + } + + //Send start bit + SUBGHZ_TX_PIN_HIGTH(); + delay_us(instance->common.te_shot*4); + SUBGHZ_TX_PIN_LOW(); + delay_us(instance->common.te_shot); + + //Send key data + for (uint8_t i = bit; i > 0; i--) { + subghz_protocol_nero_sketch_send_bit(instance, bit_read(key, i - 1)); + } + //Send stop bit + SUBGHZ_TX_PIN_HIGTH(); + delay_us(instance->common.te_shot*3); + SUBGHZ_TX_PIN_LOW(); + delay_us(instance->common.te_shot); + } +} + +void subghz_protocol_nero_sketch_reset(SubGhzProtocolNeroSketch* instance) { + instance->common.parser_step = 0; +} + +/** Analysis of received data + * + * @param instance SubGhzProtocolNeroSketch instance + */ +void subghz_protocol_nero_sketch_check_remote_controller(SubGhzProtocolNeroSketch* instance) { + //пока не понятно с серийником, но код статический + // uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit); + // uint32_t code_fix = code_found_reverse & 0xFFFFFFFF; + // //uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFF; + + // instance->common.serial = code_fix & 0xFFFFFFF; + // instance->common.btn = (code_fix >> 28) & 0x0F; + + if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context); + +} + +void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool level, uint32_t duration) { + switch (instance->common.parser_step) { + case 0: + if ((level) + && (DURATION_DIFF(duration,instance->common.te_shot)< instance->common.te_delta)) { + instance->common.parser_step = 1; + instance->common.te_last = duration; + instance->common.header_count = 0; + } else { + instance->common.parser_step = 0; + } + break; + case 1: + if (level){ + if((DURATION_DIFF(duration,instance->common.te_shot)< instance->common.te_delta ) + || (DURATION_DIFF(duration,instance->common.te_shot*4)< instance->common.te_delta)) { + instance->common.te_last = duration; + } else { + instance->common.parser_step = 0; + } + } else if(DURATION_DIFF(duration,instance->common.te_shot)< instance->common.te_delta){ + if(DURATION_DIFF(instance->common.te_last,instance->common.te_shot)< instance->common.te_delta){ + // Found header + instance->common.header_count++; + break; + }else if(DURATION_DIFF(instance->common.te_last,instance->common.te_shot*4)< instance->common.te_delta){ + // Found start bit + if(instance->common.header_count>40) { + instance->common.parser_step = 2; + instance->common.code_found = 0; + instance->common.code_count_bit = 0; + }else { + instance->common.parser_step = 0; + } + } else { + instance->common.parser_step = 0; + } + } else { + instance->common.parser_step = 0; + } + break; + case 2: + if (level) { + if (duration >= (instance->common.te_shot * 2 + instance->common.te_delta*2)) { + //Found stop bit + instance->common.parser_step = 0; + if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) { + subghz_protocol_nero_sketch_check_remote_controller(instance); + } + instance->common.code_found = 0; + instance->common.code_count_bit = 0; + break; + } else { + instance->common.te_last = duration; + instance->common.parser_step = 3; + } + + }else{ + instance->common.parser_step = 0; + } + break; + case 3: + if(!level){ + if ((DURATION_DIFF(instance->common.te_last,instance->common.te_shot)< 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(duration,instance->common.te_shot)< instance->common.te_delta)) { + subghz_protocol_common_add_bit(&instance->common, 1); + instance->common.parser_step = 2; + } else { + instance->common.parser_step = 0; + } + } else { + instance->common.parser_step = 0; + } + break; + } +} + +void subghz_protocol_nero_sketch_to_str(SubGhzProtocolNeroSketch* instance, string_t output) { + + uint32_t code_found_hi = instance->common.code_found >> 32; + uint32_t code_found_lo = instance->common.code_found & 0x00000000ffffffff; + + uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit); + + uint32_t code_found_reverse_hi = code_found_reverse>>32; + uint32_t code_found_reverse_lo = code_found_reverse&0x00000000ffffffff; + + //uint32_t rev_hi = + + string_cat_printf(output, + "Protocol %s, %d Bit\r\n" + " KEY:0x%lX%08lX\r\n" + " YEK:0x%lX%08lX\r\n", + instance->common.name, + instance->common.code_count_bit, + code_found_hi, + code_found_lo, + code_found_reverse_hi, + code_found_reverse_lo + ); +} diff --git a/lib/fl_subghz/protocols/subghz_protocol_nero_sketch.h b/lib/fl_subghz/protocols/subghz_protocol_nero_sketch.h new file mode 100644 index 00000000..99d5dbca --- /dev/null +++ b/lib/fl_subghz/protocols/subghz_protocol_nero_sketch.h @@ -0,0 +1,51 @@ +#pragma once + +#include "subghz_protocol_common.h" + +typedef struct SubGhzProtocolNeroSketch SubGhzProtocolNeroSketch; + +/** Allocate SubGhzProtocolNeroSketch + * + * @return SubGhzProtocolNeroSketch* + */ +SubGhzProtocolNeroSketch* subghz_protocol_nero_sketch_alloc(); + +/** Free SubGhzProtocolNeroSketch + * + * @param instance + */ +void subghz_protocol_nero_sketch_free(SubGhzProtocolNeroSketch* instance); + +/** Sends the key on the air + * + * @param instance - SubGhzProtocolNeroSketch instance + * @param key - key send + * @param bit - count bit key + * @param repeat - repeat send key + */ +void subghz_protocol_faac_nero_sketch_key(SubGhzProtocolNeroSketch* instance, uint64_t key, uint8_t bit, uint8_t repeat); + +/** Reset internal state + * @param instance - SubGhzProtocolNeroSketch instance + */ +void subghz_protocol_nero_sketch_reset(SubGhzProtocolNeroSketch* instance); + +/** Analysis of received data + * + * @param instance SubGhzProtocolNeroSketch instance + */ +void subghz_protocol_nero_sketch_check_remote_controller(SubGhzProtocolNeroSketch* instance); + +/** Parse accepted duration + * + * @param instance - SubGhzProtocolNeroSketch instance + * @param data - LevelDuration level_duration + */ +void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool level, uint32_t duration); + +/** Outputting information from the parser + * + * @param instance - SubGhzProtocolNeroSketch* instance + * @param output - output string + */ +void subghz_protocol_nero_sketch_to_str(SubGhzProtocolNeroSketch* instance, string_t output); diff --git a/lib/fl_subghz/protocols/subghz_protocol_nice_flo.h b/lib/fl_subghz/protocols/subghz_protocol_nice_flo.h index 6e2c0df3..80075bb2 100644 --- a/lib/fl_subghz/protocols/subghz_protocol_nice_flo.h +++ b/lib/fl_subghz/protocols/subghz_protocol_nice_flo.h @@ -35,4 +35,4 @@ void subghz_protocol_nice_flo_reset(SubGhzProtocolNiceFlo* instance); * @param instance - SubGhzProtocolNiceFlo instance * @param data - LevelDuration level_duration */ -void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, bool level, uint32_t duration);; +void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, bool level, uint32_t duration); diff --git a/lib/fl_subghz/protocols/subghz_protocol_nice_flor_s.h b/lib/fl_subghz/protocols/subghz_protocol_nice_flor_s.h index 2ece1927..32ae54fa 100644 --- a/lib/fl_subghz/protocols/subghz_protocol_nice_flor_s.h +++ b/lib/fl_subghz/protocols/subghz_protocol_nice_flor_s.h @@ -42,7 +42,7 @@ void subghz_protocol_nice_flor_s_reset(SubGhzProtocolNiceFlorS* instance); * @param instance - SubGhzProtocolNiceFlorS instance * @param data - LevelDuration level_duration */ -void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, bool level, uint32_t duration);; +void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, bool level, uint32_t duration); /** Outputting information from the parser * diff --git a/lib/fl_subghz/protocols/subghz_protocol_princeton.h b/lib/fl_subghz/protocols/subghz_protocol_princeton.h index 02c5c717..8d260462 100644 --- a/lib/fl_subghz/protocols/subghz_protocol_princeton.h +++ b/lib/fl_subghz/protocols/subghz_protocol_princeton.h @@ -35,11 +35,5 @@ void subghz_protocol_princeton_reset(SubGhzProtocolPrinceton* instance); * @param instance - SubGhzProtocolPrinceton instance * @param data - LevelDuration level_duration */ -void subghz_protocol_princeton_parse(SubGhzProtocolPrinceton* instance, bool level, uint32_t duration);; +void subghz_protocol_princeton_parse(SubGhzProtocolPrinceton* instance, bool level, uint32_t duration); -/** Outputting information from the parser - * - * @param instance - SubGhzProtocolPrinceton* instance - * @param output - output string - */ -//void subghz_protocol_princeton_to_str(SubGhzProtocolPrinceton* instance, string_t output);