From 1ab7b893ee7d951c2748de1c946e726905d7eebc Mon Sep 17 00:00:00 2001 From: VerstreuteSeele Date: Fri, 10 Feb 2023 22:53:37 +0100 Subject: [PATCH] subghz != subghz | same name, entirely different place = no good --- applications/main/subghz/SConscript | 32 - applications/main/subghz/blocks/const.c | 1 - applications/main/subghz/blocks/const.h | 20 - applications/main/subghz/blocks/decoder.c | 27 - applications/main/subghz/blocks/decoder.h | 47 - applications/main/subghz/blocks/encoder.c | 58 - applications/main/subghz/blocks/encoder.h | 67 - applications/main/subghz/blocks/generic.c | 120 -- applications/main/subghz/blocks/generic.h | 59 - applications/main/subghz/blocks/math.c | 244 ---- applications/main/subghz/blocks/math.h | 222 ---- applications/main/subghz/environment.c | 116 -- applications/main/subghz/environment.h | 115 -- .../main/subghz/protocols/alutech_at_4n.c | 455 ------- .../main/subghz/protocols/alutech_at_4n.h | 74 -- applications/main/subghz/protocols/ansonic.c | 346 ----- applications/main/subghz/protocols/ansonic.h | 107 -- applications/main/subghz/protocols/base.c | 62 - applications/main/subghz/protocols/base.h | 88 -- applications/main/subghz/protocols/bett.c | 342 ----- applications/main/subghz/protocols/bett.h | 107 -- applications/main/subghz/protocols/bin_raw.c | 1120 ----------------- applications/main/subghz/protocols/bin_raw.h | 111 -- applications/main/subghz/protocols/came.c | 347 ----- applications/main/subghz/protocols/came.h | 107 -- .../main/subghz/protocols/came_atomo.c | 598 --------- .../main/subghz/protocols/came_atomo.h | 110 -- .../main/subghz/protocols/came_twee.c | 468 ------- .../main/subghz/protocols/came_twee.h | 107 -- .../main/subghz/protocols/chamberlain_code.c | 499 -------- .../main/subghz/protocols/chamberlain_code.h | 107 -- applications/main/subghz/protocols/clemsa.c | 365 ------ applications/main/subghz/protocols/clemsa.h | 107 -- applications/main/subghz/protocols/doitrand.c | 356 ------ applications/main/subghz/protocols/doitrand.h | 107 -- applications/main/subghz/protocols/dooya.c | 447 ------- applications/main/subghz/protocols/dooya.h | 107 -- applications/main/subghz/protocols/faac_slh.c | 512 -------- applications/main/subghz/protocols/faac_slh.h | 129 -- applications/main/subghz/protocols/gate_tx.c | 334 ----- applications/main/subghz/protocols/gate_tx.h | 107 -- applications/main/subghz/protocols/holtek.c | 374 ------ applications/main/subghz/protocols/holtek.h | 107 -- .../main/subghz/protocols/holtek_ht12x.c | 400 ------ .../main/subghz/protocols/holtek_ht12x.h | 107 -- .../main/subghz/protocols/honeywell_wdb.c | 399 ------ .../main/subghz/protocols/honeywell_wdb.h | 111 -- applications/main/subghz/protocols/hormann.c | 341 ----- applications/main/subghz/protocols/hormann.h | 107 -- applications/main/subghz/protocols/ido.c | 234 ---- applications/main/subghz/protocols/ido.h | 73 -- .../main/subghz/protocols/intertechno_v3.c | 472 ------- .../main/subghz/protocols/intertechno_v3.h | 111 -- applications/main/subghz/protocols/keeloq.c | 1115 ---------------- applications/main/subghz/protocols/keeloq.h | 153 --- .../main/subghz/protocols/keeloq_common.c | 142 --- .../main/subghz/protocols/keeloq_common.h | 100 -- applications/main/subghz/protocols/kia.c | 279 ---- applications/main/subghz/protocols/kia.h | 73 -- .../subghz/protocols/kinggates_stylo_4k.c | 581 --------- .../subghz/protocols/kinggates_stylo_4k.h | 110 -- applications/main/subghz/protocols/linear.c | 352 ------ applications/main/subghz/protocols/linear.h | 107 -- .../main/subghz/protocols/linear_delta3.c | 359 ------ .../main/subghz/protocols/linear_delta3.h | 111 -- applications/main/subghz/protocols/magellan.c | 445 ------- applications/main/subghz/protocols/magellan.h | 107 -- applications/main/subghz/protocols/marantec.c | 393 ------ applications/main/subghz/protocols/marantec.h | 107 -- applications/main/subghz/protocols/megacode.c | 429 ------- applications/main/subghz/protocols/megacode.h | 107 -- .../main/subghz/protocols/nero_radio.c | 397 ------ .../main/subghz/protocols/nero_radio.h | 107 -- .../main/subghz/protocols/nero_sketch.c | 382 ------ .../main/subghz/protocols/nero_sketch.h | 107 -- applications/main/subghz/protocols/nice_flo.c | 330 ----- applications/main/subghz/protocols/nice_flo.h | 107 -- .../main/subghz/protocols/nice_flor_s.c | 694 ---------- .../main/subghz/protocols/nice_flor_s.h | 127 -- .../main/subghz/protocols/phoenix_v2.c | 339 ----- .../main/subghz/protocols/phoenix_v2.h | 107 -- .../main/subghz/protocols/power_smart.c | 394 ------ .../main/subghz/protocols/power_smart.h | 107 -- .../main/subghz/protocols/princeton.c | 374 ------ .../main/subghz/protocols/princeton.h | 115 -- .../subghz/protocols/princeton_for_testing.c | 288 ----- .../subghz/protocols/princeton_for_testing.h | 97 -- .../main/subghz/protocols/protocol_items.c | 50 - .../main/subghz/protocols/protocol_items.h | 55 - applications/main/subghz/protocols/raw.c | 374 ------ applications/main/subghz/protocols/raw.h | 148 --- .../main/subghz/protocols/scher_khan.c | 288 ----- .../main/subghz/protocols/scher_khan.h | 73 -- .../main/subghz/protocols/secplus_v1.c | 634 ---------- .../main/subghz/protocols/secplus_v1.h | 113 -- .../main/subghz/protocols/secplus_v2.c | 833 ------------ .../main/subghz/protocols/secplus_v2.h | 125 -- applications/main/subghz/protocols/smc5326.c | 387 ------ applications/main/subghz/protocols/smc5326.h | 107 -- .../main/subghz/protocols/somfy_keytis.c | 797 ------------ .../main/subghz/protocols/somfy_keytis.h | 125 -- .../main/subghz/protocols/somfy_telis.c | 663 ---------- .../main/subghz/protocols/somfy_telis.h | 125 -- .../main/subghz/protocols/star_line.c | 780 ------------ .../main/subghz/protocols/star_line.h | 131 -- applications/main/subghz/receiver.c | 124 -- applications/main/subghz/receiver.h | 73 -- applications/main/subghz/registry.c | 30 - applications/main/subghz/registry.h | 47 - .../main/subghz/subghz_file_encoder_worker.c | 244 ---- .../main/subghz/subghz_file_encoder_worker.h | 65 - applications/main/subghz/subghz_keystore.c | 613 --------- applications/main/subghz/subghz_keystore.h | 80 -- applications/main/subghz/subghz_setting.c | 480 ------- applications/main/subghz/subghz_setting.h | 58 - .../main/subghz/subghz_tx_rx_worker.c | 260 ---- .../main/subghz/subghz_tx_rx_worker.h | 89 -- applications/main/subghz/subghz_worker.c | 149 --- applications/main/subghz/subghz_worker.h | 80 -- applications/main/subghz/transmitter.c | 64 - applications/main/subghz/transmitter.h | 55 - applications/main/subghz/types.h | 104 -- lib/subghz/subghz_keystore.h | 2 +- 123 files changed, 1 insertion(+), 29256 deletions(-) delete mode 100644 applications/main/subghz/SConscript delete mode 100644 applications/main/subghz/blocks/const.c delete mode 100644 applications/main/subghz/blocks/const.h delete mode 100644 applications/main/subghz/blocks/decoder.c delete mode 100644 applications/main/subghz/blocks/decoder.h delete mode 100644 applications/main/subghz/blocks/encoder.c delete mode 100644 applications/main/subghz/blocks/encoder.h delete mode 100644 applications/main/subghz/blocks/generic.c delete mode 100644 applications/main/subghz/blocks/generic.h delete mode 100644 applications/main/subghz/blocks/math.c delete mode 100644 applications/main/subghz/blocks/math.h delete mode 100644 applications/main/subghz/environment.c delete mode 100644 applications/main/subghz/environment.h delete mode 100644 applications/main/subghz/protocols/alutech_at_4n.c delete mode 100644 applications/main/subghz/protocols/alutech_at_4n.h delete mode 100644 applications/main/subghz/protocols/ansonic.c delete mode 100644 applications/main/subghz/protocols/ansonic.h delete mode 100644 applications/main/subghz/protocols/base.c delete mode 100644 applications/main/subghz/protocols/base.h delete mode 100644 applications/main/subghz/protocols/bett.c delete mode 100644 applications/main/subghz/protocols/bett.h delete mode 100644 applications/main/subghz/protocols/bin_raw.c delete mode 100644 applications/main/subghz/protocols/bin_raw.h delete mode 100644 applications/main/subghz/protocols/came.c delete mode 100644 applications/main/subghz/protocols/came.h delete mode 100644 applications/main/subghz/protocols/came_atomo.c delete mode 100644 applications/main/subghz/protocols/came_atomo.h delete mode 100644 applications/main/subghz/protocols/came_twee.c delete mode 100644 applications/main/subghz/protocols/came_twee.h delete mode 100644 applications/main/subghz/protocols/chamberlain_code.c delete mode 100644 applications/main/subghz/protocols/chamberlain_code.h delete mode 100644 applications/main/subghz/protocols/clemsa.c delete mode 100644 applications/main/subghz/protocols/clemsa.h delete mode 100644 applications/main/subghz/protocols/doitrand.c delete mode 100644 applications/main/subghz/protocols/doitrand.h delete mode 100644 applications/main/subghz/protocols/dooya.c delete mode 100644 applications/main/subghz/protocols/dooya.h delete mode 100644 applications/main/subghz/protocols/faac_slh.c delete mode 100644 applications/main/subghz/protocols/faac_slh.h delete mode 100644 applications/main/subghz/protocols/gate_tx.c delete mode 100644 applications/main/subghz/protocols/gate_tx.h delete mode 100644 applications/main/subghz/protocols/holtek.c delete mode 100644 applications/main/subghz/protocols/holtek.h delete mode 100644 applications/main/subghz/protocols/holtek_ht12x.c delete mode 100644 applications/main/subghz/protocols/holtek_ht12x.h delete mode 100644 applications/main/subghz/protocols/honeywell_wdb.c delete mode 100644 applications/main/subghz/protocols/honeywell_wdb.h delete mode 100644 applications/main/subghz/protocols/hormann.c delete mode 100644 applications/main/subghz/protocols/hormann.h delete mode 100644 applications/main/subghz/protocols/ido.c delete mode 100644 applications/main/subghz/protocols/ido.h delete mode 100644 applications/main/subghz/protocols/intertechno_v3.c delete mode 100644 applications/main/subghz/protocols/intertechno_v3.h delete mode 100644 applications/main/subghz/protocols/keeloq.c delete mode 100644 applications/main/subghz/protocols/keeloq.h delete mode 100644 applications/main/subghz/protocols/keeloq_common.c delete mode 100644 applications/main/subghz/protocols/keeloq_common.h delete mode 100644 applications/main/subghz/protocols/kia.c delete mode 100644 applications/main/subghz/protocols/kia.h delete mode 100644 applications/main/subghz/protocols/kinggates_stylo_4k.c delete mode 100644 applications/main/subghz/protocols/kinggates_stylo_4k.h delete mode 100644 applications/main/subghz/protocols/linear.c delete mode 100644 applications/main/subghz/protocols/linear.h delete mode 100644 applications/main/subghz/protocols/linear_delta3.c delete mode 100644 applications/main/subghz/protocols/linear_delta3.h delete mode 100644 applications/main/subghz/protocols/magellan.c delete mode 100644 applications/main/subghz/protocols/magellan.h delete mode 100644 applications/main/subghz/protocols/marantec.c delete mode 100644 applications/main/subghz/protocols/marantec.h delete mode 100644 applications/main/subghz/protocols/megacode.c delete mode 100644 applications/main/subghz/protocols/megacode.h delete mode 100644 applications/main/subghz/protocols/nero_radio.c delete mode 100644 applications/main/subghz/protocols/nero_radio.h delete mode 100644 applications/main/subghz/protocols/nero_sketch.c delete mode 100644 applications/main/subghz/protocols/nero_sketch.h delete mode 100644 applications/main/subghz/protocols/nice_flo.c delete mode 100644 applications/main/subghz/protocols/nice_flo.h delete mode 100644 applications/main/subghz/protocols/nice_flor_s.c delete mode 100644 applications/main/subghz/protocols/nice_flor_s.h delete mode 100644 applications/main/subghz/protocols/phoenix_v2.c delete mode 100644 applications/main/subghz/protocols/phoenix_v2.h delete mode 100644 applications/main/subghz/protocols/power_smart.c delete mode 100644 applications/main/subghz/protocols/power_smart.h delete mode 100644 applications/main/subghz/protocols/princeton.c delete mode 100644 applications/main/subghz/protocols/princeton.h delete mode 100644 applications/main/subghz/protocols/princeton_for_testing.c delete mode 100644 applications/main/subghz/protocols/princeton_for_testing.h delete mode 100644 applications/main/subghz/protocols/protocol_items.c delete mode 100644 applications/main/subghz/protocols/protocol_items.h delete mode 100644 applications/main/subghz/protocols/raw.c delete mode 100644 applications/main/subghz/protocols/raw.h delete mode 100644 applications/main/subghz/protocols/scher_khan.c delete mode 100644 applications/main/subghz/protocols/scher_khan.h delete mode 100644 applications/main/subghz/protocols/secplus_v1.c delete mode 100644 applications/main/subghz/protocols/secplus_v1.h delete mode 100644 applications/main/subghz/protocols/secplus_v2.c delete mode 100644 applications/main/subghz/protocols/secplus_v2.h delete mode 100644 applications/main/subghz/protocols/smc5326.c delete mode 100644 applications/main/subghz/protocols/smc5326.h delete mode 100644 applications/main/subghz/protocols/somfy_keytis.c delete mode 100644 applications/main/subghz/protocols/somfy_keytis.h delete mode 100644 applications/main/subghz/protocols/somfy_telis.c delete mode 100644 applications/main/subghz/protocols/somfy_telis.h delete mode 100644 applications/main/subghz/protocols/star_line.c delete mode 100644 applications/main/subghz/protocols/star_line.h delete mode 100644 applications/main/subghz/receiver.c delete mode 100644 applications/main/subghz/receiver.h delete mode 100644 applications/main/subghz/registry.c delete mode 100644 applications/main/subghz/registry.h delete mode 100644 applications/main/subghz/subghz_file_encoder_worker.c delete mode 100644 applications/main/subghz/subghz_file_encoder_worker.h delete mode 100644 applications/main/subghz/subghz_keystore.c delete mode 100644 applications/main/subghz/subghz_keystore.h delete mode 100644 applications/main/subghz/subghz_setting.c delete mode 100644 applications/main/subghz/subghz_setting.h delete mode 100644 applications/main/subghz/subghz_tx_rx_worker.c delete mode 100644 applications/main/subghz/subghz_tx_rx_worker.h delete mode 100644 applications/main/subghz/subghz_worker.c delete mode 100644 applications/main/subghz/subghz_worker.h delete mode 100644 applications/main/subghz/transmitter.c delete mode 100644 applications/main/subghz/transmitter.h delete mode 100644 applications/main/subghz/types.h diff --git a/applications/main/subghz/SConscript b/applications/main/subghz/SConscript deleted file mode 100644 index 8fbec94ad..000000000 --- a/applications/main/subghz/SConscript +++ /dev/null @@ -1,32 +0,0 @@ -Import("env") - -env.Append( - CPPPATH=[ - "#/lib/subghz", - ], - SDK_HEADERS=[ - File("environment.h"), - File("receiver.h"), - File("subghz_worker.h"), - File("subghz_tx_rx_worker.h"), - File("transmitter.h"), - File("registry.h"), - File("protocols/protocol_items.h"), - File("protocols/raw.h"), - File("blocks/const.h"), - File("blocks/decoder.h"), - File("blocks/encoder.h"), - File("blocks/generic.h"), - File("blocks/math.h"), - File("subghz_setting.h"), - ], -) - -libenv = env.Clone(FW_LIB_NAME="subghz") -libenv.ApplyLibFlags() - -sources = libenv.GlobRecursive("*.c*") - -lib = libenv.StaticLibrary("${FW_LIB_NAME}", sources) -libenv.Install("${LIB_DIST_DIR}", lib) -Return("lib") diff --git a/applications/main/subghz/blocks/const.c b/applications/main/subghz/blocks/const.c deleted file mode 100644 index 15719b2ac..000000000 --- a/applications/main/subghz/blocks/const.c +++ /dev/null @@ -1 +0,0 @@ -#include "const.h" diff --git a/applications/main/subghz/blocks/const.h b/applications/main/subghz/blocks/const.h deleted file mode 100644 index f32334e2f..000000000 --- a/applications/main/subghz/blocks/const.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - const uint16_t te_long; - const uint16_t te_short; - const uint16_t te_delta; - const uint8_t min_count_bit_for_found; -} SubGhzBlockConst; - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/applications/main/subghz/blocks/decoder.c b/applications/main/subghz/blocks/decoder.c deleted file mode 100644 index f491c87bf..000000000 --- a/applications/main/subghz/blocks/decoder.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "decoder.h" - -#define TAG "SubGhzBlockDecoder" - -void subghz_protocol_blocks_add_bit(SubGhzBlockDecoder* decoder, uint8_t bit) { - decoder->decode_data = decoder->decode_data << 1 | bit; - decoder->decode_count_bit++; -} - -void subghz_protocol_blocks_add_to_128_bit( - SubGhzBlockDecoder* decoder, - uint8_t bit, - uint64_t* head_64_bit) { - if(++decoder->decode_count_bit > 64) { - (*head_64_bit) = ((*head_64_bit) << 1) | (decoder->decode_data >> 63); - } - decoder->decode_data = decoder->decode_data << 1 | bit; -} - -uint8_t subghz_protocol_blocks_get_hash_data(SubGhzBlockDecoder* decoder, size_t len) { - uint8_t hash = 0; - uint8_t* p = (uint8_t*)&decoder->decode_data; - for(size_t i = 0; i < len; i++) { - hash ^= p[i]; - } - return hash; -} diff --git a/applications/main/subghz/blocks/decoder.h b/applications/main/subghz/blocks/decoder.h deleted file mode 100644 index a5e561e35..000000000 --- a/applications/main/subghz/blocks/decoder.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct SubGhzBlockDecoder SubGhzBlockDecoder; - -struct SubGhzBlockDecoder { - uint32_t parser_step; - uint32_t te_last; - uint64_t decode_data; - uint8_t decode_count_bit; -}; - -/** - * Add data bit when decoding. - * @param decoder Pointer to a SubGhzBlockDecoder instance - * @param bit data, 1bit - */ -void subghz_protocol_blocks_add_bit(SubGhzBlockDecoder* decoder, uint8_t bit); - -/** - * Add data to_128 bit when decoding. - * @param decoder Pointer to a SubGhzBlockDecoder instance - * @param head_64_bit Pointer to a head_64_bit - * @param bit data, 1bit - */ -void subghz_protocol_blocks_add_to_128_bit( - SubGhzBlockDecoder* decoder, - uint8_t bit, - uint64_t* head_64_bit); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param decoder Pointer to a SubGhzBlockDecoder instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_blocks_get_hash_data(SubGhzBlockDecoder* decoder, size_t len); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/applications/main/subghz/blocks/encoder.c b/applications/main/subghz/blocks/encoder.c deleted file mode 100644 index 49ec4f177..000000000 --- a/applications/main/subghz/blocks/encoder.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "encoder.h" -#include "math.h" -#include - -#include "furi.h" - -#define TAG "SubGhzBlockEncoder" - -void subghz_protocol_blocks_set_bit_array( - bool bit_value, - uint8_t data_array[], - size_t set_index_bit, - size_t max_size_array) { - furi_assert(set_index_bit < max_size_array * 8); - bit_write(data_array[set_index_bit >> 3], 7 - (set_index_bit & 0x7), bit_value); -} - -bool subghz_protocol_blocks_get_bit_array(uint8_t data_array[], size_t read_index_bit) { - return bit_read(data_array[read_index_bit >> 3], 7 - (read_index_bit & 0x7)); -} - -size_t subghz_protocol_blocks_get_upload_from_bit_array( - uint8_t data_array[], - size_t count_bit_data_array, - LevelDuration* upload, - size_t max_size_upload, - uint32_t duration_bit, - SubGhzProtocolBlockAlignBit align_bit) { - size_t bias_bit = 0; - size_t size_upload = 0; - uint32_t duration = duration_bit; - - if(align_bit == SubGhzProtocolBlockAlignBitRight) { - if(count_bit_data_array & 0x7) { - bias_bit = 8 - (count_bit_data_array & 0x7); - } - } - size_t index_bit = bias_bit; - - bool last_bit = subghz_protocol_blocks_get_bit_array(data_array, index_bit++); - for(size_t i = 1 + bias_bit; i < count_bit_data_array + bias_bit; i++) { - if(last_bit == subghz_protocol_blocks_get_bit_array(data_array, index_bit)) { - duration += duration_bit; - } else { - if(size_upload > max_size_upload) { - furi_crash("SubGhz: Encoder buffer overflow"); - } - upload[size_upload++] = level_duration_make( - subghz_protocol_blocks_get_bit_array(data_array, index_bit - 1), duration); - last_bit = !last_bit; - duration = duration_bit; - } - index_bit++; - } - upload[size_upload++] = level_duration_make( - subghz_protocol_blocks_get_bit_array(data_array, index_bit - 1), duration); - return size_upload; -} diff --git a/applications/main/subghz/blocks/encoder.h b/applications/main/subghz/blocks/encoder.h deleted file mode 100644 index aeaa2add0..000000000 --- a/applications/main/subghz/blocks/encoder.h +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - bool is_running; - size_t repeat; - size_t front; - size_t size_upload; - LevelDuration* upload; - -} SubGhzProtocolBlockEncoder; - -typedef enum { - SubGhzProtocolBlockAlignBitLeft, - SubGhzProtocolBlockAlignBitRight, -} SubGhzProtocolBlockAlignBit; - -/** - * Set data bit when encoding HEX array. - * @param bit_value The value of the bit to be set - * @param data_array Pointer to a HEX array - * @param set_index_bit Number set a bit in the array starting from the left - * @param max_size_array array size, check not to overflow - */ -void subghz_protocol_blocks_set_bit_array( - bool bit_value, - uint8_t data_array[], - size_t set_index_bit, - size_t max_size_array); - -/** - * Get data bit when encoding HEX array. - * @param data_array Pointer to a HEX array - * @param read_index_bit Number get a bit in the array starting from the left - * @return bool value bit - */ -bool subghz_protocol_blocks_get_bit_array(uint8_t data_array[], size_t read_index_bit); - -/** - * Generating an upload from data. - * @param data_array Pointer to a HEX array - * @param count_bit_data_array How many bits in the array are processed - * @param upload Pointer to a LevelDuration - * @param max_size_upload upload size, check not to overflow - * @param duration_bit duration 1 bit - * @param align_bit alignment of useful bits in an array - */ -size_t subghz_protocol_blocks_get_upload_from_bit_array( - uint8_t data_array[], - size_t count_bit_data_array, - LevelDuration* upload, - size_t max_size_upload, - uint32_t duration_bit, - SubGhzProtocolBlockAlignBit align_bit); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/applications/main/subghz/blocks/generic.c b/applications/main/subghz/blocks/generic.c deleted file mode 100644 index 3d59adc82..000000000 --- a/applications/main/subghz/blocks/generic.c +++ /dev/null @@ -1,120 +0,0 @@ -#include "generic.h" -#include -#include - -#define TAG "SubGhzBlockGeneric" - -void subghz_block_generic_get_preset_name(const char* preset_name, FuriString* preset_str) { - const char* preset_name_temp; - if(!strcmp(preset_name, "AM270")) { - preset_name_temp = "FuriHalSubGhzPresetOok270Async"; - } else if(!strcmp(preset_name, "AM650")) { - preset_name_temp = "FuriHalSubGhzPresetOok650Async"; - } else if(!strcmp(preset_name, "FM238")) { - preset_name_temp = "FuriHalSubGhzPreset2FSKDev238Async"; - } else if(!strcmp(preset_name, "FM476")) { - preset_name_temp = "FuriHalSubGhzPreset2FSKDev476Async"; - } else { - preset_name_temp = "FuriHalSubGhzPresetCustom"; - } - furi_string_set(preset_str, preset_name_temp); -} - -bool subghz_block_generic_serialize( - SubGhzBlockGeneric* instance, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(instance); - bool res = false; - FuriString* temp_str; - temp_str = furi_string_alloc(); - do { - stream_clean(flipper_format_get_raw_stream(flipper_format)); - if(!flipper_format_write_header_cstr( - flipper_format, SUBGHZ_KEY_FILE_TYPE, SUBGHZ_KEY_FILE_VERSION)) { - FURI_LOG_E(TAG, "Unable to add header"); - break; - } - - if(!flipper_format_write_uint32(flipper_format, "Frequency", &preset->frequency, 1)) { - FURI_LOG_E(TAG, "Unable to add Frequency"); - break; - } - - subghz_block_generic_get_preset_name(furi_string_get_cstr(preset->name), temp_str); - if(!flipper_format_write_string_cstr( - flipper_format, "Preset", furi_string_get_cstr(temp_str))) { - FURI_LOG_E(TAG, "Unable to add Preset"); - break; - } - if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { - if(!flipper_format_write_string_cstr( - flipper_format, "Custom_preset_module", "CC1101")) { - FURI_LOG_E(TAG, "Unable to add Custom_preset_module"); - break; - } - if(!flipper_format_write_hex( - flipper_format, "Custom_preset_data", preset->data, preset->data_size)) { - FURI_LOG_E(TAG, "Unable to add Custom_preset_data"); - break; - } - } - if(!flipper_format_write_string_cstr(flipper_format, "Protocol", instance->protocol_name)) { - FURI_LOG_E(TAG, "Unable to add Protocol"); - break; - } - uint32_t temp = instance->data_count_bit; - if(!flipper_format_write_uint32(flipper_format, "Bit", &temp, 1)) { - FURI_LOG_E(TAG, "Unable to add Bit"); - break; - } - - uint8_t key_data[sizeof(uint64_t)] = {0}; - for(size_t i = 0; i < sizeof(uint64_t); i++) { - key_data[sizeof(uint64_t) - i - 1] = (instance->data >> (i * 8)) & 0xFF; - } - - if(!flipper_format_write_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Unable to add Key"); - break; - } - res = true; - } while(false); - furi_string_free(temp_str); - return res; -} - -bool subghz_block_generic_deserialize(SubGhzBlockGeneric* instance, FlipperFormat* flipper_format) { - furi_assert(instance); - bool res = false; - FuriString* temp_str; - temp_str = furi_string_alloc(); - uint32_t temp_data = 0; - - do { - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - if(!flipper_format_read_uint32(flipper_format, "Bit", (uint32_t*)&temp_data, 1)) { - FURI_LOG_E(TAG, "Missing Bit"); - break; - } - instance->data_count_bit = (uint16_t)temp_data; - - uint8_t key_data[sizeof(uint64_t)] = {0}; - if(!flipper_format_read_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Missing Key"); - break; - } - for(uint8_t i = 0; i < sizeof(uint64_t); i++) { - instance->data = instance->data << 8 | key_data[i]; - } - - res = true; - } while(0); - - furi_string_free(temp_str); - - return res; -} diff --git a/applications/main/subghz/blocks/generic.h b/applications/main/subghz/blocks/generic.h deleted file mode 100644 index e69de8b4f..000000000 --- a/applications/main/subghz/blocks/generic.h +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include -#include -#include "../types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct SubGhzBlockGeneric SubGhzBlockGeneric; - -struct SubGhzBlockGeneric { - const char* protocol_name; - uint64_t data; - uint64_t data_2; - uint32_t serial; - uint16_t data_count_bit; - uint8_t btn; - uint32_t cnt; - uint8_t cnt_2; - uint32_t seed; -}; - -/** - * Get name preset. - * @param preset_name name preset - * @param preset_str Output name preset - */ -void subghz_block_generic_get_preset_name(const char* preset_name, FuriString* preset_str); - -/** - * Serialize data SubGhzBlockGeneric. - * @param instance Pointer to a SubGhzBlockGeneric instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_block_generic_serialize( - SubGhzBlockGeneric* instance, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzBlockGeneric. - * @param instance Pointer to a SubGhzBlockGeneric instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_block_generic_deserialize(SubGhzBlockGeneric* instance, FlipperFormat* flipper_format); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/applications/main/subghz/blocks/math.c b/applications/main/subghz/blocks/math.c deleted file mode 100644 index 24202ad1c..000000000 --- a/applications/main/subghz/blocks/math.c +++ /dev/null @@ -1,244 +0,0 @@ -#include "math.h" - -uint64_t subghz_protocol_blocks_reverse_key(uint64_t key, uint8_t bit_count) { - uint64_t reverse_key = 0; - for(uint8_t i = 0; i < bit_count; i++) { - reverse_key = reverse_key << 1 | bit_read(key, i); - } - return reverse_key; -} - -uint8_t subghz_protocol_blocks_get_parity(uint64_t key, uint8_t bit_count) { - uint8_t parity = 0; - for(uint8_t i = 0; i < bit_count; i++) { - parity += bit_read(key, i); - } - return parity & 0x01; -} - -uint8_t subghz_protocol_blocks_crc4( - uint8_t const message[], - size_t size, - uint8_t polynomial, - uint8_t init) { - uint8_t remainder = init << 4; // LSBs are unused - uint8_t poly = polynomial << 4; - uint8_t bit; - - while(size--) { - remainder ^= *message++; - for(bit = 0; bit < 8; bit++) { - if(remainder & 0x80) { - remainder = (remainder << 1) ^ poly; - } else { - remainder = (remainder << 1); - } - } - } - return remainder >> 4 & 0x0f; // discard the LSBs -} - -uint8_t subghz_protocol_blocks_crc7( - uint8_t const message[], - size_t size, - uint8_t polynomial, - uint8_t init) { - uint8_t remainder = init << 1; // LSB is unused - uint8_t poly = polynomial << 1; - - for(size_t byte = 0; byte < size; ++byte) { - remainder ^= message[byte]; - for(uint8_t bit = 0; bit < 8; ++bit) { - if(remainder & 0x80) { - remainder = (remainder << 1) ^ poly; - } else { - remainder = (remainder << 1); - } - } - } - return remainder >> 1 & 0x7f; // discard the LSB -} - -uint8_t subghz_protocol_blocks_crc8( - uint8_t const message[], - size_t size, - uint8_t polynomial, - uint8_t init) { - uint8_t remainder = init; - - for(size_t byte = 0; byte < size; ++byte) { - remainder ^= message[byte]; - for(uint8_t bit = 0; bit < 8; ++bit) { - if(remainder & 0x80) { - remainder = (remainder << 1) ^ polynomial; - } else { - remainder = (remainder << 1); - } - } - } - return remainder; -} - -uint8_t subghz_protocol_blocks_crc8le( - uint8_t const message[], - size_t size, - uint8_t polynomial, - uint8_t init) { - uint8_t remainder = subghz_protocol_blocks_reverse_key(init, 8); - polynomial = subghz_protocol_blocks_reverse_key(polynomial, 8); - - for(size_t byte = 0; byte < size; ++byte) { - remainder ^= message[byte]; - for(uint8_t bit = 0; bit < 8; ++bit) { - if(remainder & 1) { - remainder = (remainder >> 1) ^ polynomial; - } else { - remainder = (remainder >> 1); - } - } - } - return remainder; -} - -uint16_t subghz_protocol_blocks_crc16lsb( - uint8_t const message[], - size_t size, - uint16_t polynomial, - uint16_t init) { - uint16_t remainder = init; - - for(size_t byte = 0; byte < size; ++byte) { - remainder ^= message[byte]; - for(uint8_t bit = 0; bit < 8; ++bit) { - if(remainder & 1) { - remainder = (remainder >> 1) ^ polynomial; - } else { - remainder = (remainder >> 1); - } - } - } - return remainder; -} - -uint16_t subghz_protocol_blocks_crc16( - uint8_t const message[], - size_t size, - uint16_t polynomial, - uint16_t init) { - uint16_t remainder = init; - - for(size_t byte = 0; byte < size; ++byte) { - remainder ^= message[byte] << 8; - for(uint8_t bit = 0; bit < 8; ++bit) { - if(remainder & 0x8000) { - remainder = (remainder << 1) ^ polynomial; - } else { - remainder = (remainder << 1); - } - } - } - return remainder; -} - -uint8_t subghz_protocol_blocks_lfsr_digest8( - uint8_t const message[], - size_t size, - uint8_t gen, - uint8_t key) { - uint8_t sum = 0; - for(size_t byte = 0; byte < size; ++byte) { - uint8_t data = message[byte]; - for(int i = 7; i >= 0; --i) { - // XOR key into sum if data bit is set - if((data >> i) & 1) sum ^= key; - - // roll the key right (actually the LSB is dropped here) - // and apply the gen (needs to include the dropped LSB as MSB) - if(key & 1) - key = (key >> 1) ^ gen; - else - key = (key >> 1); - } - } - return sum; -} - -uint8_t subghz_protocol_blocks_lfsr_digest8_reflect( - uint8_t const message[], - size_t size, - uint8_t gen, - uint8_t key) { - uint8_t sum = 0; - // Process message from last byte to first byte (reflected) - for(int byte = size - 1; byte >= 0; --byte) { - uint8_t data = message[byte]; - // Process individual bits of each byte (reflected) - for(uint8_t i = 0; i < 8; ++i) { - // XOR key into sum if data bit is set - if((data >> i) & 1) { - sum ^= key; - } - - // roll the key left (actually the LSB is dropped here) - // and apply the gen (needs to include the dropped lsb as MSB) - if(key & 0x80) - key = (key << 1) ^ gen; - else - key = (key << 1); - } - } - return sum; -} - -uint16_t subghz_protocol_blocks_lfsr_digest16( - uint8_t const message[], - size_t size, - uint16_t gen, - uint16_t key) { - uint16_t sum = 0; - for(size_t byte = 0; byte < size; ++byte) { - uint8_t data = message[byte]; - for(int8_t i = 7; i >= 0; --i) { - // if data bit is set then xor with key - if((data >> i) & 1) sum ^= key; - - // roll the key right (actually the LSB is dropped here) - // and apply the gen (needs to include the dropped LSB as MSB) - if(key & 1) - key = (key >> 1) ^ gen; - else - key = (key >> 1); - } - } - return sum; -} - -uint8_t subghz_protocol_blocks_add_bytes(uint8_t const message[], size_t size) { - uint32_t result = 0; - for(size_t i = 0; i < size; ++i) { - result += message[i]; - } - return (uint8_t)result; -} - -uint8_t subghz_protocol_blocks_parity8(uint8_t byte) { - byte ^= byte >> 4; - byte &= 0xf; - return (0x6996 >> byte) & 1; -} - -uint8_t subghz_protocol_blocks_parity_bytes(uint8_t const message[], size_t size) { - uint8_t result = 0; - for(size_t i = 0; i < size; ++i) { - result ^= subghz_protocol_blocks_parity8(message[i]); - } - return result; -} - -uint8_t subghz_protocol_blocks_xor_bytes(uint8_t const message[], size_t size) { - uint8_t result = 0; - for(size_t i = 0; i < size; ++i) { - result ^= message[i]; - } - return result; -} \ No newline at end of file diff --git a/applications/main/subghz/blocks/math.h b/applications/main/subghz/blocks/math.h deleted file mode 100644 index dcea3da5f..000000000 --- a/applications/main/subghz/blocks/math.h +++ /dev/null @@ -1,222 +0,0 @@ -#pragma once - -#include -#include -#include - -#define bit_read(value, bit) (((value) >> (bit)) & 0x01) -#define bit_set(value, bit) \ - ({ \ - __typeof__(value) _one = (1); \ - (value) |= (_one << (bit)); \ - }) -#define bit_clear(value, bit) \ - ({ \ - __typeof__(value) _one = (1); \ - (value) &= ~(_one << (bit)); \ - }) -#define bit_write(value, bit, bitvalue) (bitvalue ? bit_set(value, bit) : bit_clear(value, bit)) -#define DURATION_DIFF(x, y) (((x) < (y)) ? ((y) - (x)) : ((x) - (y))) - -#ifdef __cplusplus -extern "C" { -#endif - -/** Flip the data bitwise - * - * @param key In data - * @param bit_count number of data bits - * - * @return Reverse data - */ -uint64_t subghz_protocol_blocks_reverse_key(uint64_t key, uint8_t bit_count); - -/** Get parity the data bitwise - * - * @param key In data - * @param bit_count number of data bits - * - * @return parity - */ -uint8_t subghz_protocol_blocks_get_parity(uint64_t key, uint8_t bit_count); - -/** CRC-4 - * - * @param message array of bytes to check - * @param size number of bytes in message - * @param polynomial CRC polynomial - * @param init starting crc value - * - * @return CRC value - */ -uint8_t subghz_protocol_blocks_crc4( - uint8_t const message[], - size_t size, - uint8_t polynomial, - uint8_t init); - -/** CRC-7 - * - * @param message array of bytes to check - * @param size number of bytes in message - * @param polynomial CRC polynomial - * @param init starting crc value - * - * @return CRC value - */ -uint8_t subghz_protocol_blocks_crc7( - uint8_t const message[], - size_t size, - uint8_t polynomial, - uint8_t init); - -/** Generic Cyclic Redundancy Check CRC-8. Example polynomial: 0x31 = x8 + x5 + - * x4 + 1 (x8 is implicit) Example polynomial: 0x80 = x8 + x7 (a normal - * bit-by-bit parity XOR) - * - * @param message array of bytes to check - * @param size number of bytes in message - * @param polynomial byte is from x^7 to x^0 (x^8 is implicitly one) - * @param init starting crc value - * - * @return CRC value - */ -uint8_t subghz_protocol_blocks_crc8( - uint8_t const message[], - size_t size, - uint8_t polynomial, - uint8_t init); - -/** "Little-endian" Cyclic Redundancy Check CRC-8 LE Input and output are - * reflected, i.e. least significant bit is shifted in first - * - * @param message array of bytes to check - * @param size number of bytes in message - * @param polynomial CRC polynomial - * @param init starting crc value - * - * @return CRC value - */ -uint8_t subghz_protocol_blocks_crc8le( - uint8_t const message[], - size_t size, - uint8_t polynomial, - uint8_t init); - -/** CRC-16 LSB. Input and output are reflected, i.e. least significant bit is - * shifted in first. Note that poly and init already need to be reflected - * - * @param message array of bytes to check - * @param size number of bytes in message - * @param polynomial CRC polynomial - * @param init starting crc value - * - * @return CRC value - */ -uint16_t subghz_protocol_blocks_crc16lsb( - uint8_t const message[], - size_t size, - uint16_t polynomial, - uint16_t init); - -/** CRC-16 - * - * @param message array of bytes to check - * @param size number of bytes in message - * @param polynomial CRC polynomial - * @param init starting crc value - * - * @return CRC value - */ -uint16_t subghz_protocol_blocks_crc16( - uint8_t const message[], - size_t size, - uint16_t polynomial, - uint16_t init); - -/** Digest-8 by "LFSR-based Toeplitz hash" - * - * @param message bytes of message data - * @param size number of bytes to digest - * @param gen key stream generator, needs to includes the MSB if the - * LFSR is rolling - * @param key initial key - * - * @return digest value - */ -uint8_t subghz_protocol_blocks_lfsr_digest8( - uint8_t const message[], - size_t size, - uint8_t gen, - uint8_t key); - -/** Digest-8 by "LFSR-based Toeplitz hash", byte reflect, bit reflect - * - * @param message bytes of message data - * @param size number of bytes to digest - * @param gen key stream generator, needs to includes the MSB if the - * LFSR is rolling - * @param key initial key - * - * @return digest value - */ -uint8_t subghz_protocol_blocks_lfsr_digest8_reflect( - uint8_t const message[], - size_t size, - uint8_t gen, - uint8_t key); - -/** Digest-16 by "LFSR-based Toeplitz hash" - * - * @param message bytes of message data - * @param size number of bytes to digest - * @param gen key stream generator, needs to includes the MSB if the - * LFSR is rolling - * @param key initial key - * - * @return digest value - */ -uint16_t subghz_protocol_blocks_lfsr_digest16( - uint8_t const message[], - size_t size, - uint16_t gen, - uint16_t key); - -/** Compute Addition of a number of bytes - * - * @param message bytes of message data - * @param size number of bytes to sum - * - * @return summation value - */ -uint8_t subghz_protocol_blocks_add_bytes(uint8_t const message[], size_t size); - -/** Compute bit parity of a single byte (8 bits) - * - * @param byte single byte to check - * - * @return 1 odd parity, 0 even parity - */ -uint8_t subghz_protocol_blocks_parity8(uint8_t byte); - -/** Compute bit parity of a number of bytes - * - * @param message bytes of message data - * @param size number of bytes to sum - * - * @return 1 odd parity, 0 even parity - */ -uint8_t subghz_protocol_blocks_parity_bytes(uint8_t const message[], size_t size); - -/** Compute XOR (byte-wide parity) of a number of bytes - * - * @param message bytes of message data - * @param size number of bytes to sum - * - * @return summation value, per bit-position 1 odd parity, 0 even parity - */ -uint8_t subghz_protocol_blocks_xor_bytes(uint8_t const message[], size_t size); - -#ifdef __cplusplus -} -#endif diff --git a/applications/main/subghz/environment.c b/applications/main/subghz/environment.c deleted file mode 100644 index b39b259d4..000000000 --- a/applications/main/subghz/environment.c +++ /dev/null @@ -1,116 +0,0 @@ -#include "environment.h" -#include "registry.h" - -struct SubGhzEnvironment { - SubGhzKeystore* keystore; - const SubGhzProtocolRegistry* protocol_registry; - const char* came_atomo_rainbow_table_file_name; - const char* nice_flor_s_rainbow_table_file_name; - const char* alutech_at_4n_rainbow_table_file_name; -}; - -SubGhzEnvironment* subghz_environment_alloc() { - SubGhzEnvironment* instance = malloc(sizeof(SubGhzEnvironment)); - - instance->keystore = subghz_keystore_alloc(); - instance->protocol_registry = NULL; - instance->came_atomo_rainbow_table_file_name = NULL; - instance->nice_flor_s_rainbow_table_file_name = NULL; - - return instance; -} - -void subghz_environment_free(SubGhzEnvironment* instance) { - furi_assert(instance); - - instance->protocol_registry = NULL; - instance->came_atomo_rainbow_table_file_name = NULL; - instance->nice_flor_s_rainbow_table_file_name = NULL; - subghz_keystore_free(instance->keystore); - - free(instance); -} - -bool subghz_environment_load_keystore(SubGhzEnvironment* instance, const char* filename) { - furi_assert(instance); - - return subghz_keystore_load(instance->keystore, filename); -} - -SubGhzKeystore* subghz_environment_get_keystore(SubGhzEnvironment* instance) { - furi_assert(instance); - - return instance->keystore; -} - -void subghz_environment_set_came_atomo_rainbow_table_file_name( - SubGhzEnvironment* instance, - const char* filename) { - furi_assert(instance); - - instance->came_atomo_rainbow_table_file_name = filename; -} - -const char* - subghz_environment_get_came_atomo_rainbow_table_file_name(SubGhzEnvironment* instance) { - furi_assert(instance); - - return instance->came_atomo_rainbow_table_file_name; -} - -void subghz_environment_set_alutech_at_4n_rainbow_table_file_name( - SubGhzEnvironment* instance, - const char* filename) { - furi_assert(instance); - - instance->alutech_at_4n_rainbow_table_file_name = filename; -} - -const char* - subghz_environment_get_alutech_at_4n_rainbow_table_file_name(SubGhzEnvironment* instance) { - furi_assert(instance); - - return instance->alutech_at_4n_rainbow_table_file_name; -} - -void subghz_environment_set_nice_flor_s_rainbow_table_file_name( - SubGhzEnvironment* instance, - const char* filename) { - furi_assert(instance); - - instance->nice_flor_s_rainbow_table_file_name = filename; -} - -const char* - subghz_environment_get_nice_flor_s_rainbow_table_file_name(SubGhzEnvironment* instance) { - furi_assert(instance); - - return instance->nice_flor_s_rainbow_table_file_name; -} - -void subghz_environment_set_protocol_registry( - SubGhzEnvironment* instance, - void* protocol_registry_items) { - furi_assert(instance); - const SubGhzProtocolRegistry* protocol_registry = protocol_registry_items; - instance->protocol_registry = protocol_registry; -} - -void* subghz_environment_get_protocol_registry(SubGhzEnvironment* instance) { - furi_assert(instance); - furi_assert(instance->protocol_registry); - return (void*)instance->protocol_registry; -} - -const char* - subghz_environment_get_protocol_name_registry(SubGhzEnvironment* instance, size_t idx) { - furi_assert(instance); - furi_assert(instance->protocol_registry); - const SubGhzProtocol* protocol = - subghz_protocol_registry_get_by_index(instance->protocol_registry, idx); - if(protocol != NULL) { - return protocol->name; - } else { - return NULL; - } -} \ No newline at end of file diff --git a/applications/main/subghz/environment.h b/applications/main/subghz/environment.h deleted file mode 100644 index 7bd38ba2f..000000000 --- a/applications/main/subghz/environment.h +++ /dev/null @@ -1,115 +0,0 @@ -#pragma once - -#include - -#include "subghz_keystore.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct SubGhzEnvironment SubGhzEnvironment; - -/** - * Allocate SubGhzEnvironment. - * @return SubGhzEnvironment* pointer to a SubGhzEnvironment instance - */ -SubGhzEnvironment* subghz_environment_alloc(); - -/** - * Free SubGhzEnvironment. - * @param instance Pointer to a SubGhzEnvironment instance - */ -void subghz_environment_free(SubGhzEnvironment* instance); - -/** - * Downloading the manufacture key file. - * @param instance Pointer to a SubGhzEnvironment instance - * @param filename Full path to the file - * @return true On success - */ -bool subghz_environment_load_keystore(SubGhzEnvironment* instance, const char* filename); - -/** - * Get pointer to a SubGhzKeystore* instance. - * @return SubGhzEnvironment* pointer to a SubGhzEnvironment instance - */ -SubGhzKeystore* subghz_environment_get_keystore(SubGhzEnvironment* instance); - -/** - * Set filename to work with Came Atomo. - * @param instance Pointer to a SubGhzEnvironment instance - * @param filename Full path to the file - */ -void subghz_environment_set_came_atomo_rainbow_table_file_name( - SubGhzEnvironment* instance, - const char* filename); - -/** - * Get filename to work with Came Atomo. - * @param instance Pointer to a SubGhzEnvironment instance - * @return Full path to the file - */ -const char* subghz_environment_get_came_atomo_rainbow_table_file_name(SubGhzEnvironment* instance); - -/** - * Set filename to work with Alutech at-4n. - * @param instance Pointer to a SubGhzEnvironment instance - * @param filename Full path to the file - */ -void subghz_environment_set_alutech_at_4n_rainbow_table_file_name( - SubGhzEnvironment* instance, - const char* filename); - -/** - * Get filename to work with Alutech at-4n. - * @param instance Pointer to a SubGhzEnvironment instance - * @return Full path to the file - */ -const char* - subghz_environment_get_alutech_at_4n_rainbow_table_file_name(SubGhzEnvironment* instance); - -/** - * Set filename to work with Nice Flor-S. - * @param instance Pointer to a SubGhzEnvironment instance - * @param filename Full path to the file - */ -void subghz_environment_set_nice_flor_s_rainbow_table_file_name( - SubGhzEnvironment* instance, - const char* filename); - -/** - * Get filename to work with Nice Flor-S. - * @param instance Pointer to a SubGhzEnvironment instance - * @return Full path to the file - */ -const char* - subghz_environment_get_nice_flor_s_rainbow_table_file_name(SubGhzEnvironment* instance); - -/** - * Set list of protocols to work. - * @param instance Pointer to a SubGhzEnvironment instance - * @param protocol_registry_items Pointer to a SubGhzProtocolRegistry - */ -void subghz_environment_set_protocol_registry( - SubGhzEnvironment* instance, - void* protocol_registry_items); - -/** - * Get list of protocols to work. - * @param instance Pointer to a SubGhzEnvironment instance - * @return Pointer to a SubGhzProtocolRegistry - */ -void* subghz_environment_get_protocol_registry(SubGhzEnvironment* instance); - -/** - * Get list of protocols names. - * @param instance Pointer to a SubGhzEnvironment instance - * @param idx index protocols - * @return Pointer to a SubGhzProtocolRegistry - */ -const char* subghz_environment_get_protocol_name_registry(SubGhzEnvironment* instance, size_t idx); - -#ifdef __cplusplus -} -#endif diff --git a/applications/main/subghz/protocols/alutech_at_4n.c b/applications/main/subghz/protocols/alutech_at_4n.c deleted file mode 100644 index 6bcf9f25d..000000000 --- a/applications/main/subghz/protocols/alutech_at_4n.c +++ /dev/null @@ -1,455 +0,0 @@ -#include "alutech_at_4n.h" -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocoAlutech_at_4n" - -#define SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE 0xFFFFFFFF - -static const SubGhzBlockConst subghz_protocol_alutech_at_4n_const = { - .te_short = 400, - .te_long = 800, - .te_delta = 140, - .min_count_bit_for_found = 72, -}; - -struct SubGhzProtocolDecoderAlutech_at_4n { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - - uint64_t data; - uint32_t crc; - uint16_t header_count; - - const char* alutech_at_4n_rainbow_table_file_name; -}; - -struct SubGhzProtocolEncoderAlutech_at_4n { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - Alutech_at_4nDecoderStepReset = 0, - Alutech_at_4nDecoderStepCheckPreambula, - Alutech_at_4nDecoderStepSaveDuration, - Alutech_at_4nDecoderStepCheckDuration, -} Alutech_at_4nDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_alutech_at_4n_decoder = { - .alloc = subghz_protocol_decoder_alutech_at_4n_alloc, - .free = subghz_protocol_decoder_alutech_at_4n_free, - - .feed = subghz_protocol_decoder_alutech_at_4n_feed, - .reset = subghz_protocol_decoder_alutech_at_4n_reset, - - .get_hash_data = subghz_protocol_decoder_alutech_at_4n_get_hash_data, - .serialize = subghz_protocol_decoder_alutech_at_4n_serialize, - .deserialize = subghz_protocol_decoder_alutech_at_4n_deserialize, - .get_string = subghz_protocol_decoder_alutech_at_4n_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_alutech_at_4n_encoder = { - .alloc = NULL, - .free = NULL, - - .deserialize = NULL, - .stop = NULL, - .yield = NULL, -}; - -const SubGhzProtocol subghz_protocol_alutech_at_4n = { - .name = SUBGHZ_PROTOCOL_ALUTECH_AT_4N_NAME, - .type = SubGhzProtocolTypeDynamic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, - - .decoder = &subghz_protocol_alutech_at_4n_decoder, - .encoder = &subghz_protocol_alutech_at_4n_encoder, -}; - -/** - * Read bytes from rainbow table - * @param file_name Full path to rainbow table the file - * @param number_alutech_at_4n_magic_data number in the array - * @return alutech_at_4n_magic_data - */ -static uint32_t subghz_protocol_alutech_at_4n_get_magic_data_in_file( - const char* file_name, - uint8_t number_alutech_at_4n_magic_data) { - if(!strcmp(file_name, "")) return SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE; - - uint8_t buffer[sizeof(uint32_t)] = {0}; - uint32_t address = number_alutech_at_4n_magic_data * sizeof(uint32_t); - uint32_t alutech_at_4n_magic_data = 0; - - if(subghz_keystore_raw_get_data(file_name, address, buffer, sizeof(uint32_t))) { - for(size_t i = 0; i < sizeof(uint32_t); i++) { - alutech_at_4n_magic_data = (alutech_at_4n_magic_data << 8) | buffer[i]; - } - } else { - alutech_at_4n_magic_data = SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE; - } - return alutech_at_4n_magic_data; -} - -static uint8_t subghz_protocol_alutech_at_4n_crc(uint64_t data) { - uint8_t* p = (uint8_t*)&data; - uint8_t crc = 0xff; - for(uint8_t y = 0; y < 8; y++) { - crc = crc ^ p[y]; - for(uint8_t i = 0; i < 8; i++) { - if((crc & 0x80) != 0) { - crc <<= 1; - crc ^= 0x31; - } else { - crc <<= 1; - } - } - } - return crc; -} - -static uint8_t subghz_protocol_alutech_at_4n_decrypt_data_crc(uint8_t data) { - uint8_t crc = data; - for(uint8_t i = 0; i < 8; i++) { - if((crc & 0x80) != 0) { - crc <<= 1; - crc ^= 0x31; - } else { - crc <<= 1; - } - } - return ~crc; -} - -static uint64_t subghz_protocol_alutech_at_4n_decrypt(uint64_t data, const char* file_name) { - uint8_t* p = (uint8_t*)&data; - uint32_t data1 = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; - uint32_t data2 = p[4] << 24 | p[5] << 16 | p[6] << 8 | p[7]; - uint32_t data3 = 0; - uint32_t magic_data[] = { - subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 0), - subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 1), - subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 2), - subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 3), - subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 4), - subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 5)}; - - uint32_t i = magic_data[0]; - do { - data2 = data2 - - ((magic_data[1] + (data1 << 4)) ^ ((magic_data[2] + (data1 >> 5)) ^ (data1 + i))); - data3 = data2 + i; - i += magic_data[3]; - data1 = - data1 - ((magic_data[4] + (data2 << 4)) ^ ((magic_data[5] + (data2 >> 5)) ^ data3)); - } while(i != 0); - - p[0] = (uint8_t)(data1 >> 24); - p[1] = (uint8_t)(data1 >> 16); - p[3] = (uint8_t)data1; - p[4] = (uint8_t)(data2 >> 24); - p[5] = (uint8_t)(data2 >> 16); - p[2] = (uint8_t)(data1 >> 8); - p[6] = (uint8_t)(data2 >> 8); - p[7] = (uint8_t)data2; - - return data; -} - -// static uint64_t subghz_protocol_alutech_at_4n_encrypt(uint64_t data, const char* file_name) { -// uint8_t* p = (uint8_t*)&data; -// uint32_t data1 = 0; -// uint32_t data2 = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; -// uint32_t data3 = p[4] << 24 | p[5] << 16 | p[6] << 8 | p[7]; -// uint32_t magic_data[] = { -// subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 6), -// subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 4), -// subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 5), -// subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 1), -// subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 2), -// subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 0)}; - -// do { -// data1 = data1 + magic_data[0]; -// data2 = data2 + ((magic_data[1] + (data3 << 4)) ^ -// ((magic_data[2] + (data3 >> 5)) ^ (data1 + data3))); -// data3 = data3 + ((magic_data[3] + (data2 << 4)) ^ -// ((magic_data[4] + (data2 >> 5)) ^ (data1 + data2))); -// } while(data1 != magic_data[5]); -// p[0] = (uint8_t)(data2 >> 24); -// p[1] = (uint8_t)(data2 >> 16); -// p[3] = (uint8_t)data2; -// p[4] = (uint8_t)(data3 >> 24); -// p[5] = (uint8_t)(data3 >> 16); -// p[2] = (uint8_t)(data2 >> 8); -// p[6] = (uint8_t)(data3 >> 8); -// p[7] = (uint8_t)data3; - -// return data; -// } - -void* subghz_protocol_decoder_alutech_at_4n_alloc(SubGhzEnvironment* environment) { - SubGhzProtocolDecoderAlutech_at_4n* instance = - malloc(sizeof(SubGhzProtocolDecoderAlutech_at_4n)); - instance->base.protocol = &subghz_protocol_alutech_at_4n; - instance->generic.protocol_name = instance->base.protocol->name; - instance->alutech_at_4n_rainbow_table_file_name = - subghz_environment_get_alutech_at_4n_rainbow_table_file_name(environment); - if(instance->alutech_at_4n_rainbow_table_file_name) { - FURI_LOG_I( - TAG, "Loading rainbow table from %s", instance->alutech_at_4n_rainbow_table_file_name); - } - return instance; -} - -void subghz_protocol_decoder_alutech_at_4n_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderAlutech_at_4n* instance = context; - instance->alutech_at_4n_rainbow_table_file_name = NULL; - free(instance); -} - -void subghz_protocol_decoder_alutech_at_4n_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderAlutech_at_4n* instance = context; - instance->decoder.parser_step = Alutech_at_4nDecoderStepReset; -} - -void subghz_protocol_decoder_alutech_at_4n_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderAlutech_at_4n* instance = context; - - switch(instance->decoder.parser_step) { - case Alutech_at_4nDecoderStepReset: - if((level) && DURATION_DIFF(duration, subghz_protocol_alutech_at_4n_const.te_short) < - subghz_protocol_alutech_at_4n_const.te_delta) { - instance->decoder.parser_step = Alutech_at_4nDecoderStepCheckPreambula; - instance->header_count++; - } - break; - case Alutech_at_4nDecoderStepCheckPreambula: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_alutech_at_4n_const.te_short) < - subghz_protocol_alutech_at_4n_const.te_delta)) { - instance->decoder.parser_step = Alutech_at_4nDecoderStepReset; - break; - } - if((instance->header_count > 2) && - (DURATION_DIFF(duration, subghz_protocol_alutech_at_4n_const.te_short * 10) < - subghz_protocol_alutech_at_4n_const.te_delta * 10)) { - // Found header - instance->decoder.parser_step = Alutech_at_4nDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->data = 0; - instance->decoder.decode_count_bit = 0; - } else { - instance->decoder.parser_step = Alutech_at_4nDecoderStepReset; - instance->header_count = 0; - } - break; - case Alutech_at_4nDecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = Alutech_at_4nDecoderStepCheckDuration; - } - break; - case Alutech_at_4nDecoderStepCheckDuration: - if(!level) { - if(duration >= ((uint32_t)subghz_protocol_alutech_at_4n_const.te_short * 2 + - subghz_protocol_alutech_at_4n_const.te_delta)) { - //add last bit - if(DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_alutech_at_4n_const.te_short) < - subghz_protocol_alutech_at_4n_const.te_delta) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - } else if( - DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_alutech_at_4n_const.te_long) < - subghz_protocol_alutech_at_4n_const.te_delta * 2) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - } - - // Found end TX - instance->decoder.parser_step = Alutech_at_4nDecoderStepReset; - if(instance->decoder.decode_count_bit == - subghz_protocol_alutech_at_4n_const.min_count_bit_for_found) { - if(instance->generic.data != instance->data) { - instance->generic.data = instance->data; - - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - instance->crc = instance->decoder.decode_data; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->data = 0; - instance->decoder.decode_count_bit = 0; - instance->header_count = 0; - } - break; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_alutech_at_4n_const.te_short) < - subghz_protocol_alutech_at_4n_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_alutech_at_4n_const.te_long) < - subghz_protocol_alutech_at_4n_const.te_delta * 2)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - if(instance->decoder.decode_count_bit == 64) { - instance->data = instance->decoder.decode_data; - instance->decoder.decode_data = 0; - } - instance->decoder.parser_step = Alutech_at_4nDecoderStepSaveDuration; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_alutech_at_4n_const.te_long) < - subghz_protocol_alutech_at_4n_const.te_delta * 2) && - (DURATION_DIFF(duration, subghz_protocol_alutech_at_4n_const.te_short) < - subghz_protocol_alutech_at_4n_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - if(instance->decoder.decode_count_bit == 64) { - instance->data = instance->decoder.decode_data; - instance->decoder.decode_data = 0; - } - instance->decoder.parser_step = Alutech_at_4nDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = Alutech_at_4nDecoderStepReset; - instance->header_count = 0; - } - } else { - instance->decoder.parser_step = Alutech_at_4nDecoderStepReset; - instance->header_count = 0; - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - * @param file_name Full path to rainbow table the file - */ -static void subghz_protocol_alutech_at_4n_remote_controller( - SubGhzBlockGeneric* instance, - uint8_t crc, - const char* file_name) { - /** - * Message format 72bit LSB first - * data crc - * XXXXXXXXXXXXXXXX CC - * - * For analysis, you need to turn the package MSB - * in decoded messages format - * - * crc1 serial cnt key - * cc SSSSSSSS XXxx BB - * - * crc1 is calculated from the lower part of cnt - * key 1=0xff, 2=0x11, 3=0x22, 4=0x33, 5=0x44 - * - */ - - bool status = false; - uint64_t data = subghz_protocol_blocks_reverse_key(instance->data, 64); - crc = subghz_protocol_blocks_reverse_key(crc, 8); - - if(crc == subghz_protocol_alutech_at_4n_crc(data)) { - data = subghz_protocol_alutech_at_4n_decrypt(data, file_name); - status = true; - } - - if(status && ((uint8_t)(data >> 56) == - subghz_protocol_alutech_at_4n_decrypt_data_crc((uint8_t)((data >> 8) & 0xFF)))) { - instance->btn = (uint8_t)data & 0xFF; - instance->cnt = (uint16_t)(data >> 8) & 0xFFFF; - instance->serial = (uint32_t)(data >> 24) & 0xFFFFFFFF; - } - - if(!status) { - instance->btn = 0; - instance->cnt = 0; - instance->serial = 0; - } -} - -uint8_t subghz_protocol_decoder_alutech_at_4n_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderAlutech_at_4n* instance = context; - return (uint8_t)instance->crc; -} - -bool subghz_protocol_decoder_alutech_at_4n_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderAlutech_at_4n* instance = context; - bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); - if(res && !flipper_format_write_uint32(flipper_format, "CRC", &instance->crc, 1)) { - FURI_LOG_E(TAG, "Unable to add CRC"); - res = false; - } - return res; - - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_alutech_at_4n_deserialize( - void* context, - FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderAlutech_at_4n* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_alutech_at_4n_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - if(!flipper_format_read_uint32(flipper_format, "CRC", (uint32_t*)&instance->crc, 1)) { - FURI_LOG_E(TAG, "Missing CRC"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_alutech_at_4n_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderAlutech_at_4n* instance = context; - subghz_protocol_alutech_at_4n_remote_controller( - &instance->generic, instance->crc, instance->alutech_at_4n_rainbow_table_file_name); - uint32_t code_found_hi = instance->generic.data >> 32; - uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; - - furi_string_cat_printf( - output, - "%s %d\r\n" - "Key:0x%08lX%08lX%02X\r\n" - "Sn:0x%08lX Btn:0x%01X\r\n" - "Cnt:0x%03lX\r\n", - - instance->generic.protocol_name, - instance->generic.data_count_bit, - code_found_hi, - code_found_lo, - (uint8_t)instance->crc, - instance->generic.serial, - instance->generic.btn, - instance->generic.cnt); -} diff --git a/applications/main/subghz/protocols/alutech_at_4n.h b/applications/main/subghz/protocols/alutech_at_4n.h deleted file mode 100644 index 38bac3ea6..000000000 --- a/applications/main/subghz/protocols/alutech_at_4n.h +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once -#include "base.h" - -#define SUBGHZ_PROTOCOL_ALUTECH_AT_4N_NAME "Alutech at-4n" - -typedef struct SubGhzProtocolDecoderAlutech_at_4n SubGhzProtocolDecoderAlutech_at_4n; -typedef struct SubGhzProtocolEncoderAlutech_at_4n SubGhzProtocolEncoderAlutech_at_4n; - -extern const SubGhzProtocolDecoder subghz_protocol_alutech_at_4n_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_alutech_at_4n_encoder; -extern const SubGhzProtocol subghz_protocol_alutech_at_4n; - -/** - * Allocate SubGhzProtocolDecoderAlutech_at_4n. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderAlutech_at_4n* pointer to a SubGhzProtocolDecoderAlutech_at_4n instance - */ -void* subghz_protocol_decoder_alutech_at_4n_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderAlutech_at_4n. - * @param context Pointer to a SubGhzProtocolDecoderAlutech_at_4n instance - */ -void subghz_protocol_decoder_alutech_at_4n_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderAlutech_at_4n. - * @param context Pointer to a SubGhzProtocolDecoderAlutech_at_4n instance - */ -void subghz_protocol_decoder_alutech_at_4n_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderAlutech_at_4n instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_alutech_at_4n_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderAlutech_at_4n instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_alutech_at_4n_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderAlutech_at_4n. - * @param context Pointer to a SubGhzProtocolDecoderAlutech_at_4n instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_alutech_at_4n_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderAlutech_at_4n. - * @param context Pointer to a SubGhzProtocolDecoderAlutech_at_4n instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_alutech_at_4n_deserialize( - void* context, - FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderAlutech_at_4n instance - * @param output Resulting text - */ -void subghz_protocol_decoder_alutech_at_4n_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/ansonic.c b/applications/main/subghz/protocols/ansonic.c deleted file mode 100644 index 81b196e36..000000000 --- a/applications/main/subghz/protocols/ansonic.c +++ /dev/null @@ -1,346 +0,0 @@ -#include "ansonic.h" -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolAnsonic" - -#define DIP_PATTERN "%c%c%c%c%c%c%c%c%c%c" -#define CNT_TO_DIP(dip) \ - (dip & 0x0800 ? '1' : '0'), (dip & 0x0400 ? '1' : '0'), (dip & 0x0200 ? '1' : '0'), \ - (dip & 0x0100 ? '1' : '0'), (dip & 0x0080 ? '1' : '0'), (dip & 0x0040 ? '1' : '0'), \ - (dip & 0x0020 ? '1' : '0'), (dip & 0x0010 ? '1' : '0'), (dip & 0x0001 ? '1' : '0'), \ - (dip & 0x0008 ? '1' : '0') - -static const SubGhzBlockConst subghz_protocol_ansonic_const = { - .te_short = 555, - .te_long = 1111, - .te_delta = 120, - .min_count_bit_for_found = 12, -}; - -struct SubGhzProtocolDecoderAnsonic { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; -}; - -struct SubGhzProtocolEncoderAnsonic { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - AnsonicDecoderStepReset = 0, - AnsonicDecoderStepFoundStartBit, - AnsonicDecoderStepSaveDuration, - AnsonicDecoderStepCheckDuration, -} AnsonicDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_ansonic_decoder = { - .alloc = subghz_protocol_decoder_ansonic_alloc, - .free = subghz_protocol_decoder_ansonic_free, - - .feed = subghz_protocol_decoder_ansonic_feed, - .reset = subghz_protocol_decoder_ansonic_reset, - - .get_hash_data = subghz_protocol_decoder_ansonic_get_hash_data, - .serialize = subghz_protocol_decoder_ansonic_serialize, - .deserialize = subghz_protocol_decoder_ansonic_deserialize, - .get_string = subghz_protocol_decoder_ansonic_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_ansonic_encoder = { - .alloc = subghz_protocol_encoder_ansonic_alloc, - .free = subghz_protocol_encoder_ansonic_free, - - .deserialize = subghz_protocol_encoder_ansonic_deserialize, - .stop = subghz_protocol_encoder_ansonic_stop, - .yield = subghz_protocol_encoder_ansonic_yield, -}; - -const SubGhzProtocol subghz_protocol_ansonic = { - .name = SUBGHZ_PROTOCOL_ANSONIC_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_FM | - SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | - SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_ansonic_decoder, - .encoder = &subghz_protocol_ansonic_encoder, -}; - -void* subghz_protocol_encoder_ansonic_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderAnsonic* instance = malloc(sizeof(SubGhzProtocolEncoderAnsonic)); - - instance->base.protocol = &subghz_protocol_ansonic; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 52; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_ansonic_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderAnsonic* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderAnsonic instance - * @return true On success - */ -static bool subghz_protocol_encoder_ansonic_get_upload(SubGhzProtocolEncoderAnsonic* instance) { - furi_assert(instance); - size_t index = 0; - size_t size_upload = (instance->generic.data_count_bit * 2) + 2; - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - //Send header - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_ansonic_const.te_short * 35); - //Send start bit - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_ansonic_const.te_short); - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_ansonic_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_ansonic_const.te_long); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_ansonic_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_ansonic_const.te_short); - } - } - return true; -} - -bool subghz_protocol_encoder_ansonic_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderAnsonic* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_ansonic_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_ansonic_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_ansonic_stop(void* context) { - SubGhzProtocolEncoderAnsonic* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_ansonic_yield(void* context) { - SubGhzProtocolEncoderAnsonic* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_ansonic_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderAnsonic* instance = malloc(sizeof(SubGhzProtocolDecoderAnsonic)); - instance->base.protocol = &subghz_protocol_ansonic; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_ansonic_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderAnsonic* instance = context; - free(instance); -} - -void subghz_protocol_decoder_ansonic_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderAnsonic* instance = context; - instance->decoder.parser_step = AnsonicDecoderStepReset; -} - -void subghz_protocol_decoder_ansonic_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderAnsonic* instance = context; - - switch(instance->decoder.parser_step) { - case AnsonicDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_ansonic_const.te_short * 35) < - subghz_protocol_ansonic_const.te_delta * 35)) { - //Found header Ansonic - instance->decoder.parser_step = AnsonicDecoderStepFoundStartBit; - } - break; - case AnsonicDecoderStepFoundStartBit: - if(!level) { - break; - } else if( - DURATION_DIFF(duration, subghz_protocol_ansonic_const.te_short) < - subghz_protocol_ansonic_const.te_delta) { - //Found start bit Ansonic - instance->decoder.parser_step = AnsonicDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else { - instance->decoder.parser_step = AnsonicDecoderStepReset; - } - break; - case AnsonicDecoderStepSaveDuration: - if(!level) { //save interval - if(duration >= (subghz_protocol_ansonic_const.te_short * 4)) { - instance->decoder.parser_step = AnsonicDecoderStepFoundStartBit; - if(instance->decoder.decode_count_bit >= - subghz_protocol_ansonic_const.min_count_bit_for_found) { - instance->generic.serial = 0x0; - instance->generic.btn = 0x0; - - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - break; - } - instance->decoder.te_last = duration; - instance->decoder.parser_step = AnsonicDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = AnsonicDecoderStepReset; - } - break; - case AnsonicDecoderStepCheckDuration: - if(level) { - if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_ansonic_const.te_short) < - subghz_protocol_ansonic_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_ansonic_const.te_long) < - subghz_protocol_ansonic_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = AnsonicDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_ansonic_const.te_long) < - subghz_protocol_ansonic_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_ansonic_const.te_short) < - subghz_protocol_ansonic_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = AnsonicDecoderStepSaveDuration; - } else - instance->decoder.parser_step = AnsonicDecoderStepReset; - } else { - instance->decoder.parser_step = AnsonicDecoderStepReset; - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - */ -static void subghz_protocol_ansonic_check_remote_controller(SubGhzBlockGeneric* instance) { - /* - * 12345678(10) k 9 - * AAA => 10101010 1 01 0 - * - * 1...10 - DIP - * k- KEY - */ - instance->cnt = instance->data & 0xFFF; - instance->btn = ((instance->data >> 1) & 0x3); -} - -uint8_t subghz_protocol_decoder_ansonic_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderAnsonic* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_ansonic_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderAnsonic* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_ansonic_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderAnsonic* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_ansonic_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_ansonic_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderAnsonic* instance = context; - subghz_protocol_ansonic_check_remote_controller(&instance->generic); - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:%03lX\r\n" - "Btn:%X\r\n" - "DIP:" DIP_PATTERN "\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data & 0xFFFFFFFF), - instance->generic.btn, - CNT_TO_DIP(instance->generic.cnt)); -} diff --git a/applications/main/subghz/protocols/ansonic.h b/applications/main/subghz/protocols/ansonic.h deleted file mode 100644 index 0170a6048..000000000 --- a/applications/main/subghz/protocols/ansonic.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_ANSONIC_NAME "Ansonic" - -typedef struct SubGhzProtocolDecoderAnsonic SubGhzProtocolDecoderAnsonic; -typedef struct SubGhzProtocolEncoderAnsonic SubGhzProtocolEncoderAnsonic; - -extern const SubGhzProtocolDecoder subghz_protocol_ansonic_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_ansonic_encoder; -extern const SubGhzProtocol subghz_protocol_ansonic; - -/** - * Allocate SubGhzProtocolEncoderAnsonic. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderAnsonic* pointer to a SubGhzProtocolEncoderAnsonic instance - */ -void* subghz_protocol_encoder_ansonic_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderAnsonic. - * @param context Pointer to a SubGhzProtocolEncoderAnsonic instance - */ -void subghz_protocol_encoder_ansonic_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderAnsonic instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_ansonic_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderAnsonic instance - */ -void subghz_protocol_encoder_ansonic_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderAnsonic instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_ansonic_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderAnsonic. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderAnsonic* pointer to a SubGhzProtocolDecoderAnsonic instance - */ -void* subghz_protocol_decoder_ansonic_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderAnsonic. - * @param context Pointer to a SubGhzProtocolDecoderAnsonic instance - */ -void subghz_protocol_decoder_ansonic_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderAnsonic. - * @param context Pointer to a SubGhzProtocolDecoderAnsonic instance - */ -void subghz_protocol_decoder_ansonic_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderAnsonic instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_ansonic_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderAnsonic instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_ansonic_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderAnsonic. - * @param context Pointer to a SubGhzProtocolDecoderAnsonic instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_ansonic_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderAnsonic. - * @param context Pointer to a SubGhzProtocolDecoderAnsonic instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_ansonic_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderAnsonic instance - * @param output Resulting text - */ -void subghz_protocol_decoder_ansonic_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/base.c b/applications/main/subghz/protocols/base.c deleted file mode 100644 index 36f33b9a5..000000000 --- a/applications/main/subghz/protocols/base.c +++ /dev/null @@ -1,62 +0,0 @@ -#include "base.h" -#include "registry.h" - -void subghz_protocol_decoder_base_set_decoder_callback( - SubGhzProtocolDecoderBase* decoder_base, - SubGhzProtocolDecoderBaseRxCallback callback, - void* context) { - decoder_base->callback = callback; - decoder_base->context = context; -} - -bool subghz_protocol_decoder_base_get_string( - SubGhzProtocolDecoderBase* decoder_base, - FuriString* output) { - bool status = false; - - if(decoder_base->protocol && decoder_base->protocol->decoder && - decoder_base->protocol->decoder->get_string) { - decoder_base->protocol->decoder->get_string(decoder_base, output); - status = true; - } - - return status; -} - -bool subghz_protocol_decoder_base_serialize( - SubGhzProtocolDecoderBase* decoder_base, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - bool status = false; - - if(decoder_base->protocol && decoder_base->protocol->decoder && - decoder_base->protocol->decoder->serialize) { - status = decoder_base->protocol->decoder->serialize(decoder_base, flipper_format, preset); - } - - return status; -} - -bool subghz_protocol_decoder_base_deserialize( - SubGhzProtocolDecoderBase* decoder_base, - FlipperFormat* flipper_format) { - bool status = false; - - if(decoder_base->protocol && decoder_base->protocol->decoder && - decoder_base->protocol->decoder->deserialize) { - status = decoder_base->protocol->decoder->deserialize(decoder_base, flipper_format); - } - - return status; -} - -uint8_t subghz_protocol_decoder_base_get_hash_data(SubGhzProtocolDecoderBase* decoder_base) { - uint8_t hash = 0; - - if(decoder_base->protocol && decoder_base->protocol->decoder && - decoder_base->protocol->decoder->get_hash_data) { - hash = decoder_base->protocol->decoder->get_hash_data(decoder_base); - } - - return hash; -} diff --git a/applications/main/subghz/protocols/base.h b/applications/main/subghz/protocols/base.h deleted file mode 100644 index 1f3d3e1be..000000000 --- a/applications/main/subghz/protocols/base.h +++ /dev/null @@ -1,88 +0,0 @@ -#pragma once - -#include "../types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct SubGhzProtocolDecoderBase SubGhzProtocolDecoderBase; - -typedef void ( - *SubGhzProtocolDecoderBaseRxCallback)(SubGhzProtocolDecoderBase* instance, void* context); - -typedef void (*SubGhzProtocolDecoderBaseSerialize)( - SubGhzProtocolDecoderBase* decoder_base, - FuriString* output); - -struct SubGhzProtocolDecoderBase { - // Decoder general section - const SubGhzProtocol* protocol; - - // Callback section - SubGhzProtocolDecoderBaseRxCallback callback; - void* context; -}; - -/** - * Set a callback upon completion of successful decoding of one of the protocols. - * @param decoder_base Pointer to a SubGhzProtocolDecoderBase instance - * @param callback Callback, SubGhzProtocolDecoderBaseRxCallback - * @param context Context - */ -void subghz_protocol_decoder_base_set_decoder_callback( - SubGhzProtocolDecoderBase* decoder_base, - SubGhzProtocolDecoderBaseRxCallback callback, - void* context); - -/** - * Getting a textual representation of the received data. - * @param decoder_base Pointer to a SubGhzProtocolDecoderBase instance - * @param output Resulting text - */ -bool subghz_protocol_decoder_base_get_string( - SubGhzProtocolDecoderBase* decoder_base, - FuriString* output); - -/** - * Serialize data SubGhzProtocolDecoderBase. - * @param decoder_base Pointer to a SubGhzProtocolDecoderBase instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_base_serialize( - SubGhzProtocolDecoderBase* decoder_base, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderBase. - * @param decoder_base Pointer to a SubGhzProtocolDecoderBase instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_base_deserialize( - SubGhzProtocolDecoderBase* decoder_base, - FlipperFormat* flipper_format); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param decoder_base Pointer to a SubGhzProtocolDecoderBase instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_base_get_hash_data(SubGhzProtocolDecoderBase* decoder_base); - -// Encoder Base -typedef struct SubGhzProtocolEncoderBase SubGhzProtocolEncoderBase; - -struct SubGhzProtocolEncoderBase { - // Decoder general section - const SubGhzProtocol* protocol; - - // Callback section -}; - -#ifdef __cplusplus -} -#endif diff --git a/applications/main/subghz/protocols/bett.c b/applications/main/subghz/protocols/bett.c deleted file mode 100644 index 644d80fd8..000000000 --- a/applications/main/subghz/protocols/bett.c +++ /dev/null @@ -1,342 +0,0 @@ -#include "bett.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -// protocol BERNER / ELKA / TEDSEN / TELETASTER -#define TAG "SubGhzProtocolBETT" - -#define DIP_P 0b11 //(+) -#define DIP_O 0b10 //(0) -#define DIP_N 0b00 //(-) - -#define DIP_PATTERN "%c%c%c%c%c%c%c%c%c" -#define SHOW_DIP_P(dip, check_dip) \ - ((((dip >> 0x8) >> 0x8) == check_dip) ? '*' : '_'), \ - ((((dip >> 0xE) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0xC) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0xA) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0x8) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0x6) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0x4) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0x2) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0x0) & 0x3) == check_dip) ? '*' : '_') - -static const SubGhzBlockConst subghz_protocol_bett_const = { - .te_short = 340, - .te_long = 2000, - .te_delta = 150, - .min_count_bit_for_found = 18, -}; - -struct SubGhzProtocolDecoderBETT { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; -}; - -struct SubGhzProtocolEncoderBETT { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - BETTDecoderStepReset = 0, - BETTDecoderStepSaveDuration, - BETTDecoderStepCheckDuration, -} BETTDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_bett_decoder = { - .alloc = subghz_protocol_decoder_bett_alloc, - .free = subghz_protocol_decoder_bett_free, - - .feed = subghz_protocol_decoder_bett_feed, - .reset = subghz_protocol_decoder_bett_reset, - - .get_hash_data = subghz_protocol_decoder_bett_get_hash_data, - .serialize = subghz_protocol_decoder_bett_serialize, - .deserialize = subghz_protocol_decoder_bett_deserialize, - .get_string = subghz_protocol_decoder_bett_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_bett_encoder = { - .alloc = subghz_protocol_encoder_bett_alloc, - .free = subghz_protocol_encoder_bett_free, - - .deserialize = subghz_protocol_encoder_bett_deserialize, - .stop = subghz_protocol_encoder_bett_stop, - .yield = subghz_protocol_encoder_bett_yield, -}; - -const SubGhzProtocol subghz_protocol_bett = { - .name = SUBGHZ_PROTOCOL_BETT_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_bett_decoder, - .encoder = &subghz_protocol_bett_encoder, -}; - -void* subghz_protocol_encoder_bett_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderBETT* instance = malloc(sizeof(SubGhzProtocolEncoderBETT)); - - instance->base.protocol = &subghz_protocol_bett; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 52; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_bett_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderBETT* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderBETT instance - * @return true On success - */ -static bool subghz_protocol_encoder_bett_get_upload(SubGhzProtocolEncoderBETT* instance) { - furi_assert(instance); - size_t index = 0; - size_t size_upload = (instance->generic.data_count_bit * 2); - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - - for(uint8_t i = instance->generic.data_count_bit; i > 1; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_bett_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_bett_const.te_short); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_bett_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_bett_const.te_long); - } - } - if(bit_read(instance->generic.data, 0)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_bett_const.te_long); - instance->encoder.upload[index++] = level_duration_make( - false, - (uint32_t)subghz_protocol_bett_const.te_short + - subghz_protocol_bett_const.te_long * 7); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_bett_const.te_short); - instance->encoder.upload[index++] = level_duration_make( - false, - (uint32_t)subghz_protocol_bett_const.te_long + subghz_protocol_bett_const.te_long * 7); - } - return true; -} - -bool subghz_protocol_encoder_bett_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderBETT* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_bett_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_bett_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_bett_stop(void* context) { - SubGhzProtocolEncoderBETT* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_bett_yield(void* context) { - SubGhzProtocolEncoderBETT* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_bett_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderBETT* instance = malloc(sizeof(SubGhzProtocolDecoderBETT)); - instance->base.protocol = &subghz_protocol_bett; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_bett_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderBETT* instance = context; - free(instance); -} - -void subghz_protocol_decoder_bett_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderBETT* instance = context; - instance->decoder.parser_step = BETTDecoderStepReset; -} - -void subghz_protocol_decoder_bett_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderBETT* instance = context; - - switch(instance->decoder.parser_step) { - case BETTDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_bett_const.te_short * 44) < - (subghz_protocol_bett_const.te_delta * 15))) { - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->decoder.parser_step = BETTDecoderStepCheckDuration; - } - break; - case BETTDecoderStepSaveDuration: - if(!level) { - if(DURATION_DIFF(duration, subghz_protocol_bett_const.te_short * 44) < - (subghz_protocol_bett_const.te_delta * 15)) { - if(instance->decoder.decode_count_bit == - subghz_protocol_bett_const.min_count_bit_for_found) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } else { - instance->decoder.parser_step = BETTDecoderStepReset; - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - break; - } else { - if((DURATION_DIFF(duration, subghz_protocol_bett_const.te_short) < - subghz_protocol_bett_const.te_delta) || - (DURATION_DIFF(duration, subghz_protocol_bett_const.te_long) < - subghz_protocol_bett_const.te_delta * 3)) { - instance->decoder.parser_step = BETTDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = BETTDecoderStepReset; - } - } - } - break; - case BETTDecoderStepCheckDuration: - if(level) { - if(DURATION_DIFF(duration, subghz_protocol_bett_const.te_long) < - subghz_protocol_bett_const.te_delta * 3) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = BETTDecoderStepSaveDuration; - } else if( - DURATION_DIFF(duration, subghz_protocol_bett_const.te_short) < - subghz_protocol_bett_const.te_delta) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = BETTDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = BETTDecoderStepReset; - } - } else { - instance->decoder.parser_step = BETTDecoderStepReset; - } - break; - } -} - -uint8_t subghz_protocol_decoder_bett_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderBETT* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_bett_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderBETT* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_bett_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderBETT* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_bett_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_bett_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderBETT* instance = context; - uint32_t data = (uint32_t)(instance->generic.data & 0x3FFFF); - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:%05lX\r\n" - " +: " DIP_PATTERN "\r\n" - " o: " DIP_PATTERN "\r\n" - " -: " DIP_PATTERN "\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - data, - SHOW_DIP_P(data, DIP_P), - SHOW_DIP_P(data, DIP_O), - SHOW_DIP_P(data, DIP_N)); -} diff --git a/applications/main/subghz/protocols/bett.h b/applications/main/subghz/protocols/bett.h deleted file mode 100644 index c0ce0b7f4..000000000 --- a/applications/main/subghz/protocols/bett.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_BETT_NAME "BETT" - -typedef struct SubGhzProtocolDecoderBETT SubGhzProtocolDecoderBETT; -typedef struct SubGhzProtocolEncoderBETT SubGhzProtocolEncoderBETT; - -extern const SubGhzProtocolDecoder subghz_protocol_bett_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_bett_encoder; -extern const SubGhzProtocol subghz_protocol_bett; - -/** - * Allocate SubGhzProtocolEncoderBETT. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderBETT* pointer to a SubGhzProtocolEncoderBETT instance - */ -void* subghz_protocol_encoder_bett_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderBETT. - * @param context Pointer to a SubGhzProtocolEncoderBETT instance - */ -void subghz_protocol_encoder_bett_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderBETT instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_bett_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderBETT instance - */ -void subghz_protocol_encoder_bett_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderBETT instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_bett_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderBETT. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderBETT* pointer to a SubGhzProtocolDecoderBETT instance - */ -void* subghz_protocol_decoder_bett_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderBETT. - * @param context Pointer to a SubGhzProtocolDecoderBETT instance - */ -void subghz_protocol_decoder_bett_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderBETT. - * @param context Pointer to a SubGhzProtocolDecoderBETT instance - */ -void subghz_protocol_decoder_bett_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderBETT instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_bett_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderBETT instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_bett_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderBETT. - * @param context Pointer to a SubGhzProtocolDecoderBETT instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_bett_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderBETT. - * @param context Pointer to a SubGhzProtocolDecoderBETT instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_bett_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderBETT instance - * @param output Resulting text - */ -void subghz_protocol_decoder_bett_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/bin_raw.c b/applications/main/subghz/protocols/bin_raw.c deleted file mode 100644 index 67e0467ee..000000000 --- a/applications/main/subghz/protocols/bin_raw.c +++ /dev/null @@ -1,1120 +0,0 @@ -#include "bin_raw.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" -#include -#include -#include - -#define TAG "SubGhzProtocolBinRAW" - -//change very carefully, RAM ends at the most inopportune moment -#define BIN_RAW_BUF_RAW_SIZE 2048 -#define BIN_RAW_BUF_DATA_SIZE 512 - -#define BIN_RAW_THRESHOLD_RSSI -85.0f -#define BIN_RAW_DELTA_RSSI 7.0f -#define BIN_RAW_SEARCH_CLASSES 20 -#define BIN_RAW_TE_MIN_COUNT 40 -#define BIN_RAW_BUF_MIN_DATA_COUNT 128 -#define BIN_RAW_MAX_MARKUP_COUNT 20 - -//#define BIN_RAW_DEBUG - -#ifdef BIN_RAW_DEBUG -#define bin_raw_debug(...) FURI_LOG_RAW_D(__VA_ARGS__) -#define bin_raw_debug_tag(tag, ...) \ - FURI_LOG_RAW_D("\033[0;32m[" tag "]\033[0m "); \ - FURI_LOG_RAW_D(__VA_ARGS__) -#else -#define bin_raw_debug(...) -#define bin_raw_debug_tag(...) -#endif - -static const SubGhzBlockConst subghz_protocol_bin_raw_const = { - .te_short = 30, - .te_long = 65000, - .te_delta = 0, - .min_count_bit_for_found = 0, -}; - -typedef enum { - BinRAWDecoderStepReset = 0, - BinRAWDecoderStepWrite, - BinRAWDecoderStepBufFull, - BinRAWDecoderStepNoParse, -} BinRAWDecoderStep; - -typedef enum { - BinRAWTypeUnknown = 0, - BinRAWTypeNoGap, - BinRAWTypeGap, - BinRAWTypeGapRecurring, - BinRAWTypeGapRolling, - BinRAWTypeGapUnknown, -} BinRAWType; - -struct BinRAW_Markup { - uint16_t byte_bias; - uint16_t bit_count; -}; -typedef struct BinRAW_Markup BinRAW_Markup; - -struct SubGhzProtocolDecoderBinRAW { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - int32_t* data_raw; - uint8_t* data; - BinRAW_Markup data_markup[BIN_RAW_MAX_MARKUP_COUNT]; - size_t data_raw_ind; - uint32_t te; - float adaptive_threshold_rssi; -}; - -struct SubGhzProtocolEncoderBinRAW { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; - - uint8_t* data; - BinRAW_Markup data_markup[BIN_RAW_MAX_MARKUP_COUNT]; - uint32_t te; -}; - -const SubGhzProtocolDecoder subghz_protocol_bin_raw_decoder = { - .alloc = subghz_protocol_decoder_bin_raw_alloc, - .free = subghz_protocol_decoder_bin_raw_free, - - .feed = subghz_protocol_decoder_bin_raw_feed, - .reset = subghz_protocol_decoder_bin_raw_reset, - - .get_hash_data = subghz_protocol_decoder_bin_raw_get_hash_data, - .serialize = subghz_protocol_decoder_bin_raw_serialize, - .deserialize = subghz_protocol_decoder_bin_raw_deserialize, - .get_string = subghz_protocol_decoder_bin_raw_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_bin_raw_encoder = { - .alloc = subghz_protocol_encoder_bin_raw_alloc, - .free = subghz_protocol_encoder_bin_raw_free, - - .deserialize = subghz_protocol_encoder_bin_raw_deserialize, - .stop = subghz_protocol_encoder_bin_raw_stop, - .yield = subghz_protocol_encoder_bin_raw_yield, -}; - -const SubGhzProtocol subghz_protocol_bin_raw = { - .name = SUBGHZ_PROTOCOL_BIN_RAW_NAME, - .type = SubGhzProtocolTypeBinRAW, -#ifdef BIN_RAW_DEBUG - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_FM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, -#else - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_FM | SubGhzProtocolFlag_BinRAW | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, -#endif - .decoder = &subghz_protocol_bin_raw_decoder, - .encoder = &subghz_protocol_bin_raw_encoder, -}; - -static uint16_t subghz_protocol_bin_raw_get_full_byte(uint16_t bit_count) { - if(bit_count & 0x7) { - return (bit_count >> 3) + 1; - } else { - return (bit_count >> 3); - } -} - -void* subghz_protocol_encoder_bin_raw_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderBinRAW* instance = malloc(sizeof(SubGhzProtocolEncoderBinRAW)); - - instance->base.protocol = &subghz_protocol_bin_raw; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = BIN_RAW_BUF_DATA_SIZE * 5; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->data = malloc(instance->encoder.size_upload * sizeof(uint8_t)); - memset(instance->data_markup, 0x00, BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_bin_raw_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderBinRAW* instance = context; - free(instance->encoder.upload); - free(instance->data); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderBinRAW instance - * @return true On success - */ -static bool subghz_protocol_encoder_bin_raw_get_upload(SubGhzProtocolEncoderBinRAW* instance) { - furi_assert(instance); - - //we glue all the pieces of the package into 1 long sequence with left alignment, - //in the uploaded data we have right alignment. - - bin_raw_debug_tag(TAG, "Recovery of offset bits in sequences\r\n"); - uint16_t i = 0; - uint16_t ind = 0; - bin_raw_debug("\tind byte_bias\tbit_count\tbit_bias\r\n"); - while((i < BIN_RAW_MAX_MARKUP_COUNT) && (instance->data_markup[i].bit_count != 0)) { - uint8_t bit_bias = - subghz_protocol_bin_raw_get_full_byte(instance->data_markup[i].bit_count) * 8 - - instance->data_markup[i].bit_count; - bin_raw_debug( - "\t%d\t%d\t%d :\t\t%d\r\n", - i, - instance->data_markup[i].byte_bias, - instance->data_markup[i].bit_count, - bit_bias); - for(uint16_t y = instance->data_markup[i].byte_bias * 8; - y < instance->data_markup[i].byte_bias * 8 + - subghz_protocol_bin_raw_get_full_byte(instance->data_markup[i].bit_count) * 8 - - bit_bias; - y++) { - subghz_protocol_blocks_set_bit_array( - subghz_protocol_blocks_get_bit_array(instance->data, y + bit_bias), - instance->data, - ind++, - BIN_RAW_BUF_DATA_SIZE); - } - i++; - } - bin_raw_debug("\r\n"); -#ifdef BIN_RAW_DEBUG - bin_raw_debug_tag(TAG, "Restored Sequence left aligned\r\n"); - for(uint16_t y = 0; y < subghz_protocol_bin_raw_get_full_byte(ind); y++) { - bin_raw_debug("%02X ", instance->data[y]); - } - bin_raw_debug("\r\n\tbin_count_result= %d\r\n\r\n", ind); - - bin_raw_debug_tag( - TAG, "Maximum levels encoded in upload %zu\r\n", instance->encoder.size_upload); -#endif - instance->encoder.size_upload = subghz_protocol_blocks_get_upload_from_bit_array( - instance->data, - ind, - instance->encoder.upload, - instance->encoder.size_upload, - instance->te, - SubGhzProtocolBlockAlignBitLeft); - - bin_raw_debug_tag(TAG, "The result %zu is levels\r\n", instance->encoder.size_upload); - bin_raw_debug_tag(TAG, "Remaining free memory %zu\r\n", memmgr_get_free_heap()); - return true; -} - -bool subghz_protocol_encoder_bin_raw_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderBinRAW* instance = context; - - bool res = false; - uint32_t temp_data = 0; - - do { - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - if(!flipper_format_read_uint32(flipper_format, "Bit", (uint32_t*)&temp_data, 1)) { - FURI_LOG_E(TAG, "Missing Bit"); - break; - } - - instance->generic.data_count_bit = (uint16_t)temp_data; - - if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) { - FURI_LOG_E(TAG, "Missing TE"); - break; - } - - temp_data = 0; - uint16_t ind = 0; - uint16_t byte_bias = 0; - uint16_t byte_count = 0; - memset(instance->data_markup, 0x00, BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup)); - while(flipper_format_read_uint32(flipper_format, "Bit_RAW", (uint32_t*)&temp_data, 1)) { - if(ind >= BIN_RAW_MAX_MARKUP_COUNT) { - FURI_LOG_E(TAG, "Markup overflow"); - break; - } - byte_count += subghz_protocol_bin_raw_get_full_byte(temp_data); - if(byte_count > BIN_RAW_BUF_DATA_SIZE) { - FURI_LOG_E(TAG, "Receive buffer overflow"); - break; - } - - instance->data_markup[ind].bit_count = temp_data; - instance->data_markup[ind].byte_bias = byte_bias; - byte_bias += subghz_protocol_bin_raw_get_full_byte(temp_data); - - if(!flipper_format_read_hex( - flipper_format, - "Data_RAW", - instance->data + instance->data_markup[ind].byte_bias, - subghz_protocol_bin_raw_get_full_byte(temp_data))) { - instance->data_markup[ind].bit_count = 0; - FURI_LOG_E(TAG, "Missing Data_RAW"); - break; - } - ind++; - } - -#ifdef BIN_RAW_DEBUG - uint16_t i = 0; - bin_raw_debug_tag(TAG, "Download data to encoder\r\n"); - bin_raw_debug("\tind byte_bias\tbit_count\t\tbin_data"); - while((i < BIN_RAW_MAX_MARKUP_COUNT) && (instance->data_markup[i].bit_count != 0)) { - bin_raw_debug( - "\r\n\t%d\t%d\t%d :\t", - i, - instance->data_markup[i].byte_bias, - instance->data_markup[i].bit_count); - for(uint16_t y = instance->data_markup[i].byte_bias; - y < instance->data_markup[i].byte_bias + - subghz_protocol_bin_raw_get_full_byte(instance->data_markup[i].bit_count); - y++) { - bin_raw_debug("%02X ", instance->data[y]); - } - i++; - } - bin_raw_debug("\r\n\r\n"); -#endif - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_bin_raw_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(0); - - return res; -} - -void subghz_protocol_encoder_bin_raw_stop(void* context) { - SubGhzProtocolEncoderBinRAW* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_bin_raw_yield(void* context) { - SubGhzProtocolEncoderBinRAW* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_bin_raw_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderBinRAW* instance = malloc(sizeof(SubGhzProtocolDecoderBinRAW)); - instance->base.protocol = &subghz_protocol_bin_raw; - instance->generic.protocol_name = instance->base.protocol->name; - instance->data_raw_ind = 0; - instance->data_raw = malloc(BIN_RAW_BUF_RAW_SIZE * sizeof(int32_t)); - instance->data = malloc(BIN_RAW_BUF_RAW_SIZE * sizeof(uint8_t)); - memset(instance->data_markup, 0x00, BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup)); - instance->adaptive_threshold_rssi = BIN_RAW_THRESHOLD_RSSI; - return instance; -} - -void subghz_protocol_decoder_bin_raw_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderBinRAW* instance = context; - free(instance->data_raw); - free(instance->data); - free(instance); -} - -void subghz_protocol_decoder_bin_raw_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderBinRAW* instance = context; -#ifdef BIN_RAW_DEBUG - UNUSED(instance); -#else - instance->decoder.parser_step = BinRAWDecoderStepNoParse; - instance->data_raw_ind = 0; -#endif -} - -void subghz_protocol_decoder_bin_raw_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderBinRAW* instance = context; - - if(instance->decoder.parser_step == BinRAWDecoderStepWrite) { - if(instance->data_raw_ind == BIN_RAW_BUF_RAW_SIZE) { - instance->decoder.parser_step = BinRAWDecoderStepBufFull; - } else { - instance->data_raw[instance->data_raw_ind++] = (level ? duration : -duration); - } - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzProtocolDecoderBinRAW* instance - */ -static bool - subghz_protocol_bin_raw_check_remote_controller(SubGhzProtocolDecoderBinRAW* instance) { - struct { - float data; - uint16_t count; - } classes[BIN_RAW_SEARCH_CLASSES]; - - size_t ind = 0; - - memset(classes, 0x00, sizeof(classes)); - - uint16_t data_markup_ind = 0; - memset(instance->data_markup, 0x00, BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup)); - - if(instance->data_raw_ind < 512) { - ind = - instance->data_raw_ind - - 100; //there is usually garbage at the end of the record, we exclude it from the classification - } else { - ind = 512; - } - - //sort the durations to find the shortest correlated interval - for(size_t i = 0; i < ind; i++) { - for(size_t k = 0; k < BIN_RAW_SEARCH_CLASSES; k++) { - if(classes[k].count == 0) { - classes[k].data = (float)(abs(instance->data_raw[i])); - classes[k].count++; - break; - } else if( - DURATION_DIFF((float)(abs(instance->data_raw[i])), (classes[k].data)) < - (classes[k].data / 4)) { //if the test value does not differ by more than 25% - classes[k].data += ((float)(abs(instance->data_raw[i])) - classes[k].data) * - 0.05f; //running average k=0.05 - classes[k].count++; - break; - } - } - } - - // if(classes[BIN_RAW_SEARCH_CLASSES - 1].count != 0) { - // //filling the classifier, it means that they received an unclean signal - // return false; - // } - - //looking for the minimum te with an occurrence greater than BIN_RAW_TE_MIN_COUNT - instance->te = subghz_protocol_bin_raw_const.te_long * 2; - - bool te_ok = false; - uint16_t gap_ind = 0; - uint16_t gap_delta = 0; - uint32_t gap = 0; - int data_temp = 0; - BinRAWType bin_raw_type = BinRAWTypeUnknown; - - //sort by number of occurrences - bool swap = true; - while(swap) { - swap = false; - for(size_t i = 1; i < BIN_RAW_SEARCH_CLASSES; i++) { - if(classes[i].count > classes[i - 1].count) { - uint32_t data = classes[i - 1].data; - uint32_t count = classes[i - 1].count; - classes[i - 1].data = classes[i].data; - classes[i - 1].count = classes[i].count; - classes[i].data = data; - classes[i].count = count; - swap = true; - } - } - } -#ifdef BIN_RAW_DEBUG - bin_raw_debug_tag(TAG, "Sorted durations\r\n"); - bin_raw_debug("\t\tind\tcount\tus\r\n"); - for(size_t k = 0; k < BIN_RAW_SEARCH_CLASSES; k++) { - bin_raw_debug("\t\t%zu\t%u\t%lu\r\n", k, classes[k].count, (uint32_t)classes[k].data); - } - bin_raw_debug("\r\n"); -#endif - if((classes[0].count > BIN_RAW_TE_MIN_COUNT) && (classes[1].count == 0)) { - //adopted only the preamble - instance->te = (uint32_t)classes[0].data; - te_ok = true; - gap = 0; //gap no - } else { - //take the 2 most common durations - //check that there are enough - if((classes[0].count < BIN_RAW_TE_MIN_COUNT) || - (classes[1].count < (BIN_RAW_TE_MIN_COUNT >> 1))) - return false; - //arrange the first 2 date values in ascending order - if(classes[0].data > classes[1].data) { - uint32_t data = classes[1].data; - classes[0].data = classes[1].data; - classes[1].data = data; - } - - //determine the value to be corrected - for(uint8_t k = 1; k < 5; k++) { - float delta = (classes[1].data / (classes[0].data / k)); - bin_raw_debug_tag(TAG, "K_div= %f\r\n", (double)(delta)); - delta -= (uint32_t)delta; - - if((delta < 0.20f) || (delta > 0.80f)) { - instance->te = (uint32_t)classes[0].data / k; - bin_raw_debug_tag(TAG, "K= %d\r\n", k); - te_ok = true; //found a correlated duration - break; - } - } - if(!te_ok) { - //did not find the minimum TE satisfying the condition - return false; - } - bin_raw_debug_tag(TAG, "TE= %lu\r\n\r\n", instance->te); - - //looking for a gap - for(size_t k = 2; k < BIN_RAW_SEARCH_CLASSES; k++) { - if((classes[k].count > 2) && (classes[k].data > gap)) { - gap = (uint32_t)classes[k].data; - gap_delta = gap / 5; //calculate 20% deviation from ideal value - } - } - - if((gap / instance->te) < - 10) { //make an assumption, the longest gap should be more than 10 TE - gap = 0; //check that our signal has a gap greater than 10*TE - bin_raw_type = BinRAWTypeNoGap; - } else { - bin_raw_type = BinRAWTypeGap; - //looking for the last occurrence of gap - ind = instance->data_raw_ind - 1; - while((ind > 0) && (DURATION_DIFF(abs(instance->data_raw[ind]), gap) > gap_delta)) { - ind--; - } - gap_ind = ind; - } - } - - //if we consider that there is a gap, then we divide the signal with respect to this gap - //processing input data from the end - if(bin_raw_type == BinRAWTypeGap) { - bin_raw_debug_tag(TAG, "Tinted sequence\r\n"); - ind = (BIN_RAW_BUF_DATA_SIZE * 8); - uint16_t bit_count = 0; - do { - gap_ind--; - data_temp = (int)(round((float)(instance->data_raw[gap_ind]) / instance->te)); - bin_raw_debug("%d ", data_temp); - if(data_temp == 0) bit_count++; //there is noise in the package - for(size_t i = 0; i < abs(data_temp); i++) { - bit_count++; - if(ind) { - ind--; - } else { - break; - } - if(data_temp > 0) { - subghz_protocol_blocks_set_bit_array( - true, instance->data, ind, BIN_RAW_BUF_DATA_SIZE); - } else { - subghz_protocol_blocks_set_bit_array( - false, instance->data, ind, BIN_RAW_BUF_DATA_SIZE); - } - } - //split into full bytes if gap is caught - if(DURATION_DIFF(abs(instance->data_raw[gap_ind]), gap) < gap_delta) { - instance->data_markup[data_markup_ind].byte_bias = ind >> 3; - instance->data_markup[data_markup_ind++].bit_count = bit_count; - bit_count = 0; - - if(data_markup_ind == BIN_RAW_MAX_MARKUP_COUNT) break; - ind &= 0xFFFFFFF8; //jump to the pre whole byte - } - } while(gap_ind != 0); - if((data_markup_ind != BIN_RAW_MAX_MARKUP_COUNT) && (ind != 0)) { - instance->data_markup[data_markup_ind].byte_bias = ind >> 3; - instance->data_markup[data_markup_ind++].bit_count = bit_count; - } - - bin_raw_debug("\r\n\t count bit= %zu\r\n\r\n", (BIN_RAW_BUF_DATA_SIZE * 8) - ind); - - //reset the classifier and classify the received data - memset(classes, 0x00, sizeof(classes)); - - bin_raw_debug_tag(TAG, "Sort the found pieces by the number of bits in them\r\n"); - for(size_t i = 0; i < data_markup_ind; i++) { - for(size_t k = 0; k < BIN_RAW_SEARCH_CLASSES; k++) { - if(classes[k].count == 0) { - classes[k].data = instance->data_markup[i].bit_count; - classes[k].count++; - break; - } else if(instance->data_markup[i].bit_count == (uint16_t)classes[k].data) { - classes[k].count++; - break; - } - } - } - -#ifdef BIN_RAW_DEBUG - bin_raw_debug("\t\tind\tcount\tus\r\n"); - for(size_t k = 0; k < BIN_RAW_SEARCH_CLASSES; k++) { - bin_raw_debug("\t\t%zu\t%u\t%lu\r\n", k, classes[k].count, (uint32_t)classes[k].data); - } - bin_raw_debug("\r\n"); -#endif - - //choose the value with the maximum repetition - data_temp = 0; - for(size_t i = 0; i < BIN_RAW_SEARCH_CLASSES; i++) { - if((classes[i].count > 1) && (data_temp < classes[i].count)) - data_temp = (int)classes[i].data; - } - - //if(data_markup_ind == 0) return false; - -#ifdef BIN_RAW_DEBUG - //output in reverse order - bin_raw_debug_tag(TAG, "Found sequences\r\n"); - bin_raw_debug("\tind byte_bias\tbit_count\t\tbin_data\r\n"); - uint16_t data_markup_ind_temp = data_markup_ind; - if(data_markup_ind) { - data_markup_ind_temp--; - for(size_t i = (ind / 8); i < BIN_RAW_BUF_DATA_SIZE; i++) { - if(instance->data_markup[data_markup_ind_temp].byte_bias == i) { - bin_raw_debug( - "\r\n\t%d\t%d\t%d :\t", - data_markup_ind_temp, - instance->data_markup[data_markup_ind_temp].byte_bias, - instance->data_markup[data_markup_ind_temp].bit_count); - if(data_markup_ind_temp != 0) data_markup_ind_temp--; - } - bin_raw_debug("%02X ", instance->data[i]); - } - bin_raw_debug("\r\n\r\n"); - } - //compare data in chunks with the same number of bits - bin_raw_debug_tag(TAG, "Analyze sequences of long %d bit\r\n\r\n", data_temp); -#endif - - //if(data_temp == 0) data_temp = (int)classes[0].data; - - if(data_temp != 0) { - //check that data in transmission is repeated every packet - for(uint16_t i = 0; i < data_markup_ind - 1; i++) { - if((instance->data_markup[i].bit_count == data_temp) && - (instance->data_markup[i + 1].bit_count == data_temp)) { - //if the number of bits in adjacent parcels is the same, compare the data - bin_raw_debug_tag( - TAG, - "Comparison of neighboring sequences ind_1=%d ind_2=%d %02X=%02X .... %02X=%02X\r\n", - i, - i + 1, - instance->data[instance->data_markup[i].byte_bias], - instance->data[instance->data_markup[i + 1].byte_bias], - instance->data - [instance->data_markup[i].byte_bias + - subghz_protocol_bin_raw_get_full_byte( - instance->data_markup[i].bit_count) - - 1], - instance->data - [instance->data_markup[i + 1].byte_bias + - subghz_protocol_bin_raw_get_full_byte( - instance->data_markup[i + 1].bit_count) - - 1]); - - uint16_t byte_count = - subghz_protocol_bin_raw_get_full_byte(instance->data_markup[i].bit_count); - if(memcmp( - instance->data + instance->data_markup[i].byte_bias, - instance->data + instance->data_markup[i + 1].byte_bias, - byte_count - 1) == 0) { - bin_raw_debug_tag( - TAG, "Match found bin_raw_type=BinRAWTypeGapRecurring\r\n\r\n"); - - //place in 1 element the offset to valid data - instance->data_markup[0].bit_count = instance->data_markup[i].bit_count; - instance->data_markup[0].byte_bias = instance->data_markup[i].byte_bias; - //markup end sign - instance->data_markup[1].bit_count = 0; - instance->data_markup[1].byte_bias = 0; - - bin_raw_type = BinRAWTypeGapRecurring; - i = data_markup_ind; - break; - } - } - } - } - - if(bin_raw_type == BinRAWTypeGap) { - // check that retry occurs every n packets - for(uint16_t i = 0; i < data_markup_ind - 2; i++) { - uint16_t byte_count = - subghz_protocol_bin_raw_get_full_byte(instance->data_markup[i].bit_count); - for(uint16_t y = i + 1; y < data_markup_ind - 1; y++) { - bin_raw_debug_tag( - TAG, - "Comparison every N sequences ind_1=%d ind_2=%d %02X=%02X .... %02X=%02X\r\n", - i, - y, - instance->data[instance->data_markup[i].byte_bias], - instance->data[instance->data_markup[y].byte_bias], - instance->data - [instance->data_markup[i].byte_bias + - subghz_protocol_bin_raw_get_full_byte( - instance->data_markup[i].bit_count) - - 1], - instance->data - [instance->data_markup[y].byte_bias + - subghz_protocol_bin_raw_get_full_byte( - instance->data_markup[y].bit_count) - - 1]); - - if(byte_count == - subghz_protocol_bin_raw_get_full_byte( - instance->data_markup[y].bit_count)) { //if the length in bytes matches - - if((memcmp( - instance->data + instance->data_markup[i].byte_bias, - instance->data + instance->data_markup[y].byte_bias, - byte_count - 1) == 0) && - (memcmp( - instance->data + instance->data_markup[i + 1].byte_bias, - instance->data + instance->data_markup[y + 1].byte_bias, - byte_count - 1) == 0)) { - uint8_t index = 0; -#ifdef BIN_RAW_DEBUG - bin_raw_debug_tag( - TAG, "Match found bin_raw_type=BinRAWTypeGapRolling\r\n\r\n"); - //output in reverse order - bin_raw_debug("\tind byte_bias\tbit_count\t\tbin_data\r\n"); - index = y - 1; - for(size_t z = instance->data_markup[y].byte_bias + byte_count; - z < instance->data_markup[i].byte_bias + byte_count; - z++) { - if(instance->data_markup[index].byte_bias == z) { - bin_raw_debug( - "\r\n\t%d\t%d\t%d :\t", - index, - instance->data_markup[index].byte_bias, - instance->data_markup[index].bit_count); - if(index != 0) index--; - } - bin_raw_debug("%02X ", instance->data[z]); - } - - bin_raw_debug("\r\n\r\n"); -#endif - //todo can be optimized - BinRAW_Markup markup_temp[BIN_RAW_MAX_MARKUP_COUNT]; - memcpy( - markup_temp, - instance->data_markup, - BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup)); - memset( - instance->data_markup, - 0x00, - BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup)); - - for(index = i; index < y; index++) { - instance->data_markup[index - i].bit_count = - markup_temp[y - index - 1].bit_count; - instance->data_markup[index - i].byte_bias = - markup_temp[y - index - 1].byte_bias; - } - - bin_raw_type = BinRAWTypeGapRolling; - i = data_markup_ind; - break; - } - } - } - } - } - //todo can be optimized - if(bin_raw_type == BinRAWTypeGap) { - if(data_temp != 0) { //there are sequences with the same number of bits - - BinRAW_Markup markup_temp[BIN_RAW_MAX_MARKUP_COUNT]; - memcpy( - markup_temp, - instance->data_markup, - BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup)); - memset( - instance->data_markup, 0x00, BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup)); - uint16_t byte_count = subghz_protocol_bin_raw_get_full_byte(data_temp); - uint16_t index = 0; - uint16_t it = BIN_RAW_MAX_MARKUP_COUNT; - do { - it--; - if(subghz_protocol_bin_raw_get_full_byte(markup_temp[it].bit_count) == - byte_count) { - instance->data_markup[index].bit_count = markup_temp[it].bit_count; - instance->data_markup[index].byte_bias = markup_temp[it].byte_bias; - index++; - bin_raw_type = BinRAWTypeGapUnknown; - } - } while(it != 0); - } - } - - if(bin_raw_type != BinRAWTypeGap) - return true; - else - return false; - - } else { - // if bin_raw_type == BinRAWTypeGap - bin_raw_debug_tag(TAG, "Sequence analysis without gap\r\n"); - ind = 0; - for(size_t i = 0; i < instance->data_raw_ind; i++) { - int data_temp = (int)(round((float)(instance->data_raw[i]) / instance->te)); - if(data_temp == 0) break; //found an interval 2 times shorter than TE, this is noise - bin_raw_debug("%d ", data_temp); - - for(size_t k = 0; k < abs(data_temp); k++) { - if(data_temp > 0) { - subghz_protocol_blocks_set_bit_array( - true, instance->data, ind++, BIN_RAW_BUF_DATA_SIZE); - } else { - subghz_protocol_blocks_set_bit_array( - false, instance->data, ind++, BIN_RAW_BUF_DATA_SIZE); - } - if(ind == BIN_RAW_BUF_DATA_SIZE * 8) { - i = instance->data_raw_ind; - break; - } - } - } - - if(ind != 0) { - bin_raw_type = BinRAWTypeNoGap; - //right alignment - uint8_t bit_bias = (subghz_protocol_bin_raw_get_full_byte(ind) << 3) - ind; -#ifdef BIN_RAW_DEBUG - bin_raw_debug( - "\r\n\t count bit= %zu\tcount full byte= %d\tbias bit= %d\r\n\r\n", - ind, - subghz_protocol_bin_raw_get_full_byte(ind), - bit_bias); - - for(size_t i = 0; i < subghz_protocol_bin_raw_get_full_byte(ind); i++) { - bin_raw_debug("%02X ", instance->data[i]); - } - bin_raw_debug("\r\n\r\n"); -#endif - //checking that the received sequence contains useful data - bool data_check = false; - for(size_t i = 0; i < subghz_protocol_bin_raw_get_full_byte(ind); i++) { - if(instance->data[i] != 0) { - data_check = true; - break; - } - } - - if(data_check) { - for(size_t i = subghz_protocol_bin_raw_get_full_byte(ind) - 1; i > 0; i--) { - instance->data[i] = (instance->data[i - 1] << (8 - bit_bias)) | - (instance->data[i] >> bit_bias); - } - instance->data[0] = (instance->data[0] >> bit_bias); - -#ifdef BIN_RAW_DEBUG - bin_raw_debug_tag(TAG, "Data right alignment\r\n"); - for(size_t i = 0; i < subghz_protocol_bin_raw_get_full_byte(ind); i++) { - bin_raw_debug("%02X ", instance->data[i]); - } - bin_raw_debug("\r\n\r\n"); -#endif - instance->data_markup[0].bit_count = ind; - instance->data_markup[0].byte_bias = 0; - - return true; - } else { - return false; - } - } else { - return false; - } - } - return false; -} - -void subghz_protocol_decoder_bin_raw_data_input_rssi( - SubGhzProtocolDecoderBinRAW* instance, - float rssi) { - furi_assert(instance); - switch(instance->decoder.parser_step) { - case BinRAWDecoderStepReset: - - bin_raw_debug("%ld %ld :", (int32_t)rssi, (int32_t)instance->adaptive_threshold_rssi); - if(rssi > (instance->adaptive_threshold_rssi + BIN_RAW_DELTA_RSSI)) { - instance->data_raw_ind = 0; - memset(instance->data_raw, 0x00, BIN_RAW_BUF_RAW_SIZE * sizeof(int32_t)); - memset(instance->data, 0x00, BIN_RAW_BUF_RAW_SIZE * sizeof(uint8_t)); - instance->decoder.parser_step = BinRAWDecoderStepWrite; - bin_raw_debug_tag(TAG, "RSSI\r\n"); - } else { - //adaptive noise level adjustment - instance->adaptive_threshold_rssi += (rssi - instance->adaptive_threshold_rssi) * 0.2f; - } - break; - - case BinRAWDecoderStepBufFull: - case BinRAWDecoderStepWrite: -#ifdef BIN_RAW_DEBUG - if(rssi > (instance->adaptive_threshold_rssi + BIN_RAW_DELTA_RSSI)) { - bin_raw_debug("\033[0;32m%ld \033[0m ", (int32_t)rssi); - } else { - bin_raw_debug("%ld ", (int32_t)rssi); - } -#endif - if(rssi < instance->adaptive_threshold_rssi + BIN_RAW_DELTA_RSSI) { -#ifdef BIN_RAW_DEBUG - bin_raw_debug("\r\n\r\n"); - bin_raw_debug_tag(TAG, "Data for analysis, positive high, negative low, us\r\n"); - for(size_t i = 0; i < instance->data_raw_ind; i++) { - bin_raw_debug("%ld ", instance->data_raw[i]); - } - bin_raw_debug("\r\n\t count data= %zu\r\n\r\n", instance->data_raw_ind); -#endif - instance->decoder.parser_step = BinRAWDecoderStepReset; - instance->generic.data_count_bit = 0; - if(instance->data_raw_ind >= BIN_RAW_BUF_MIN_DATA_COUNT) { - if(subghz_protocol_bin_raw_check_remote_controller(instance)) { - bin_raw_debug_tag(TAG, "Sequence found\r\n"); - bin_raw_debug("\tind byte_bias\tbit_count\t\tbin_data"); - uint16_t i = 0; - while((i < BIN_RAW_MAX_MARKUP_COUNT) && - (instance->data_markup[i].bit_count != 0)) { - instance->generic.data_count_bit += instance->data_markup[i].bit_count; -#ifdef BIN_RAW_DEBUG - bin_raw_debug( - "\r\n\t%d\t%d\t%d :\t", - i, - instance->data_markup[i].byte_bias, - instance->data_markup[i].bit_count); - for(uint16_t y = instance->data_markup[i].byte_bias; - y < instance->data_markup[i].byte_bias + - subghz_protocol_bin_raw_get_full_byte( - instance->data_markup[i].bit_count); - y++) { - bin_raw_debug("%02X ", instance->data[y]); - } -#endif - i++; - } - bin_raw_debug("\r\n"); - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - } - } - break; - - default: - //if instance->decoder.parser_step == BinRAWDecoderStepNoParse or others, restore the initial state - if(rssi < instance->adaptive_threshold_rssi + BIN_RAW_DELTA_RSSI) { - instance->decoder.parser_step = BinRAWDecoderStepReset; - } - break; - } -} - -uint8_t subghz_protocol_decoder_bin_raw_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderBinRAW* instance = context; - return subghz_protocol_blocks_add_bytes( - instance->data + instance->data_markup[0].byte_bias, - subghz_protocol_bin_raw_get_full_byte(instance->data_markup[0].bit_count)); -} - -bool subghz_protocol_decoder_bin_raw_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderBinRAW* instance = context; - - bool res = false; - FuriString* temp_str; - temp_str = furi_string_alloc(); - do { - stream_clean(flipper_format_get_raw_stream(flipper_format)); - if(!flipper_format_write_header_cstr( - flipper_format, SUBGHZ_KEY_FILE_TYPE, SUBGHZ_KEY_FILE_VERSION)) { - FURI_LOG_E(TAG, "Unable to add header"); - break; - } - - if(!flipper_format_write_uint32(flipper_format, "Frequency", &preset->frequency, 1)) { - FURI_LOG_E(TAG, "Unable to add Frequency"); - break; - } - - subghz_block_generic_get_preset_name(furi_string_get_cstr(preset->name), temp_str); - if(!flipper_format_write_string_cstr( - flipper_format, "Preset", furi_string_get_cstr(temp_str))) { - FURI_LOG_E(TAG, "Unable to add Preset"); - break; - } - if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { - if(!flipper_format_write_string_cstr( - flipper_format, "Custom_preset_module", "CC1101")) { - FURI_LOG_E(TAG, "Unable to add Custom_preset_module"); - break; - } - if(!flipper_format_write_hex( - flipper_format, "Custom_preset_data", preset->data, preset->data_size)) { - FURI_LOG_E(TAG, "Unable to add Custom_preset_data"); - break; - } - } - if(!flipper_format_write_string_cstr( - flipper_format, "Protocol", instance->generic.protocol_name)) { - FURI_LOG_E(TAG, "Unable to add Protocol"); - break; - } - - uint32_t temp = instance->generic.data_count_bit; - if(!flipper_format_write_uint32(flipper_format, "Bit", &temp, 1)) { - FURI_LOG_E(TAG, "Unable to add Bit"); - break; - } - - if(!flipper_format_write_uint32(flipper_format, "TE", &instance->te, 1)) { - FURI_LOG_E(TAG, "Unable to add TE"); - break; - } - - uint16_t i = 0; - while((i < BIN_RAW_MAX_MARKUP_COUNT) && (instance->data_markup[i].bit_count != 0)) { - temp = instance->data_markup[i].bit_count; - if(!flipper_format_write_uint32(flipper_format, "Bit_RAW", &temp, 1)) { - FURI_LOG_E(TAG, "Bit_RAW"); - break; - } - if(!flipper_format_write_hex( - flipper_format, - "Data_RAW", - instance->data + instance->data_markup[i].byte_bias, - subghz_protocol_bin_raw_get_full_byte(instance->data_markup[i].bit_count))) { - FURI_LOG_E(TAG, "Unable to add Data_RAW"); - break; - } - i++; - } - - res = true; - } while(false); - furi_string_free(temp_str); - return res; -} - -bool subghz_protocol_decoder_bin_raw_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderBinRAW* instance = context; - - bool res = false; - uint32_t temp_data = 0; - - do { - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - if(!flipper_format_read_uint32(flipper_format, "Bit", (uint32_t*)&temp_data, 1)) { - FURI_LOG_E(TAG, "Missing Bit"); - break; - } - - instance->generic.data_count_bit = (uint16_t)temp_data; - - if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) { - FURI_LOG_E(TAG, "Missing TE"); - break; - } - - temp_data = 0; - uint16_t ind = 0; - uint16_t byte_bias = 0; - uint16_t byte_count = 0; - memset(instance->data_markup, 0x00, BIN_RAW_MAX_MARKUP_COUNT * sizeof(BinRAW_Markup)); - while(flipper_format_read_uint32(flipper_format, "Bit_RAW", (uint32_t*)&temp_data, 1)) { - if(ind >= BIN_RAW_MAX_MARKUP_COUNT) { - FURI_LOG_E(TAG, "Markup overflow"); - break; - } - byte_count += subghz_protocol_bin_raw_get_full_byte(temp_data); - if(byte_count > BIN_RAW_BUF_DATA_SIZE) { - FURI_LOG_E(TAG, "Receive buffer overflow"); - break; - } - - instance->data_markup[ind].bit_count = temp_data; - instance->data_markup[ind].byte_bias = byte_bias; - byte_bias += subghz_protocol_bin_raw_get_full_byte(temp_data); - - if(!flipper_format_read_hex( - flipper_format, - "Data_RAW", - instance->data + instance->data_markup[ind].byte_bias, - subghz_protocol_bin_raw_get_full_byte(temp_data))) { - instance->data_markup[ind].bit_count = 0; - FURI_LOG_E(TAG, "Missing Data_RAW"); - break; - } - ind++; - } - - res = true; - } while(0); - - return res; -} - -void subghz_protocol_decoder_bin_raw_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderBinRAW* instance = context; - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:", - instance->generic.protocol_name, - instance->generic.data_count_bit); - - uint16_t byte_count = subghz_protocol_bin_raw_get_full_byte(instance->generic.data_count_bit); - for(size_t i = 0; (byte_count < 36 ? i < byte_count : i < 36); i++) { - furi_string_cat_printf(output, "%02X", instance->data[i]); - } - - furi_string_cat_printf(output, "\r\nTe:%luus\r\n", instance->te); -} diff --git a/applications/main/subghz/protocols/bin_raw.h b/applications/main/subghz/protocols/bin_raw.h deleted file mode 100644 index c63f86ce6..000000000 --- a/applications/main/subghz/protocols/bin_raw.h +++ /dev/null @@ -1,111 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_BIN_RAW_NAME "BinRAW" - -typedef struct SubGhzProtocolDecoderBinRAW SubGhzProtocolDecoderBinRAW; -typedef struct SubGhzProtocolEncoderBinRAW SubGhzProtocolEncoderBinRAW; - -extern const SubGhzProtocolDecoder subghz_protocol_bin_raw_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_bin_raw_encoder; -extern const SubGhzProtocol subghz_protocol_bin_raw; - -/** - * Allocate SubGhzProtocolEncoderBinRAW. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderBinRAW* pointer to a SubGhzProtocolEncoderBinRAW instance - */ -void* subghz_protocol_encoder_bin_raw_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderBinRAW. - * @param context Pointer to a SubGhzProtocolEncoderBinRAW instance - */ -void subghz_protocol_encoder_bin_raw_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderBinRAW instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_bin_raw_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderBinRAW instance - */ -void subghz_protocol_encoder_bin_raw_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderBinRAW instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_bin_raw_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderBinRAW. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderBinRAW* pointer to a SubGhzProtocolDecoderBinRAW instance - */ -void* subghz_protocol_decoder_bin_raw_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderBinRAW. - * @param context Pointer to a SubGhzProtocolDecoderBinRAW instance - */ -void subghz_protocol_decoder_bin_raw_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderBinRAW. - * @param context Pointer to a SubGhzProtocolDecoderBinRAW instance - */ -void subghz_protocol_decoder_bin_raw_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderBinRAW instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_bin_raw_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderBinRAW instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_bin_raw_get_hash_data(void* context); - -void subghz_protocol_decoder_bin_raw_data_input_rssi( - SubGhzProtocolDecoderBinRAW* instance, - float rssi); - -/** - * Serialize data SubGhzProtocolDecoderBinRAW. - * @param context Pointer to a SubGhzProtocolDecoderBinRAW instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_bin_raw_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderBinRAW. - * @param context Pointer to a SubGhzProtocolDecoderBinRAW instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_bin_raw_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderBinRAW instance - * @param output Resulting text - */ -void subghz_protocol_decoder_bin_raw_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/came.c b/applications/main/subghz/protocols/came.c deleted file mode 100644 index bed26d7d2..000000000 --- a/applications/main/subghz/protocols/came.c +++ /dev/null @@ -1,347 +0,0 @@ -#include "came.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -/* - * Help - * https://phreakerclub.com/447 - * - */ - -#define TAG "SubGhzProtocolCAME" -#define CAME_24_COUNT_BIT 24 -#define PRASTEL_COUNT_BIT 25 -#define PRASTEL_NAME "Prastel" -#define AIRFORCE_COUNT_BIT 18 -#define AIRFORCE_NAME "Airforce" - -static const SubGhzBlockConst subghz_protocol_came_const = { - .te_short = 320, - .te_long = 640, - .te_delta = 150, - .min_count_bit_for_found = 12, -}; - -struct SubGhzProtocolDecoderCame { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; -}; - -struct SubGhzProtocolEncoderCame { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - CameDecoderStepReset = 0, - CameDecoderStepFoundStartBit, - CameDecoderStepSaveDuration, - CameDecoderStepCheckDuration, -} CameDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_came_decoder = { - .alloc = subghz_protocol_decoder_came_alloc, - .free = subghz_protocol_decoder_came_free, - - .feed = subghz_protocol_decoder_came_feed, - .reset = subghz_protocol_decoder_came_reset, - - .get_hash_data = subghz_protocol_decoder_came_get_hash_data, - .serialize = subghz_protocol_decoder_came_serialize, - .deserialize = subghz_protocol_decoder_came_deserialize, - .get_string = subghz_protocol_decoder_came_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_came_encoder = { - .alloc = subghz_protocol_encoder_came_alloc, - .free = subghz_protocol_encoder_came_free, - - .deserialize = subghz_protocol_encoder_came_deserialize, - .stop = subghz_protocol_encoder_came_stop, - .yield = subghz_protocol_encoder_came_yield, -}; - -const SubGhzProtocol subghz_protocol_came = { - .name = SUBGHZ_PROTOCOL_CAME_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_AM | - SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | - SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_came_decoder, - .encoder = &subghz_protocol_came_encoder, -}; - -void* subghz_protocol_encoder_came_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderCame* instance = malloc(sizeof(SubGhzProtocolEncoderCame)); - - instance->base.protocol = &subghz_protocol_came; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 128; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_came_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderCame* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderCame instance - * @return true On success - */ -static bool subghz_protocol_encoder_came_get_upload(SubGhzProtocolEncoderCame* instance) { - furi_assert(instance); - size_t index = 0; - size_t size_upload = (instance->generic.data_count_bit * 2) + 2; - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - //Send header - instance->encoder.upload[index++] = level_duration_make( - false, - (((instance->generic.data_count_bit == CAME_24_COUNT_BIT) || - (instance->generic.data_count_bit == - subghz_protocol_came_const.min_count_bit_for_found)) ? - (uint32_t)subghz_protocol_came_const.te_short * 76 : - (uint32_t)subghz_protocol_came_const.te_short * 39)); - //Send start bit - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_came_const.te_short); - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_came_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_came_const.te_short); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_came_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_came_const.te_long); - } - } - return true; -} - -bool subghz_protocol_encoder_came_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderCame* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if((instance->generic.data_count_bit > PRASTEL_COUNT_BIT)) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_came_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_came_stop(void* context) { - SubGhzProtocolEncoderCame* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_came_yield(void* context) { - SubGhzProtocolEncoderCame* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_came_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderCame* instance = malloc(sizeof(SubGhzProtocolDecoderCame)); - instance->base.protocol = &subghz_protocol_came; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_came_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderCame* instance = context; - free(instance); -} - -void subghz_protocol_decoder_came_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderCame* instance = context; - instance->decoder.parser_step = CameDecoderStepReset; -} - -void subghz_protocol_decoder_came_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderCame* instance = context; - switch(instance->decoder.parser_step) { - case CameDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_came_const.te_short * 56) < - subghz_protocol_came_const.te_delta * 47)) { - //Found header CAME - instance->decoder.parser_step = CameDecoderStepFoundStartBit; - } - break; - case CameDecoderStepFoundStartBit: - if(!level) { - break; - } else if( - DURATION_DIFF(duration, subghz_protocol_came_const.te_short) < - subghz_protocol_came_const.te_delta) { - //Found start bit CAME - instance->decoder.parser_step = CameDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else { - instance->decoder.parser_step = CameDecoderStepReset; - } - break; - case CameDecoderStepSaveDuration: - if(!level) { //save interval - if(duration >= (subghz_protocol_came_const.te_short * 4)) { - instance->decoder.parser_step = CameDecoderStepFoundStartBit; - if(instance->decoder.decode_count_bit >= - subghz_protocol_came_const.min_count_bit_for_found) { - instance->generic.serial = 0x0; - instance->generic.btn = 0x0; - - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - break; - } - instance->decoder.te_last = duration; - instance->decoder.parser_step = CameDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = CameDecoderStepReset; - } - break; - case CameDecoderStepCheckDuration: - if(level) { - if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_came_const.te_short) < - subghz_protocol_came_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_came_const.te_long) < - subghz_protocol_came_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = CameDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_came_const.te_long) < - subghz_protocol_came_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_came_const.te_short) < - subghz_protocol_came_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = CameDecoderStepSaveDuration; - } else - instance->decoder.parser_step = CameDecoderStepReset; - } else { - instance->decoder.parser_step = CameDecoderStepReset; - } - break; - } -} - -uint8_t subghz_protocol_decoder_came_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderCame* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_came_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderCame* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_came_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderCame* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if((instance->generic.data_count_bit > PRASTEL_COUNT_BIT)) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_came_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderCame* instance = context; - - uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; - - uint64_t code_found_reverse = subghz_protocol_blocks_reverse_key( - instance->generic.data, instance->generic.data_count_bit); - - uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:0x%08lX\r\n" - "Yek:0x%08lX\r\n", - (instance->generic.data_count_bit == PRASTEL_COUNT_BIT ? - PRASTEL_NAME : - (instance->generic.data_count_bit == AIRFORCE_COUNT_BIT ? - AIRFORCE_NAME : - instance->generic.protocol_name)), - instance->generic.data_count_bit, - code_found_lo, - code_found_reverse_lo); -} diff --git a/applications/main/subghz/protocols/came.h b/applications/main/subghz/protocols/came.h deleted file mode 100644 index 253c93aae..000000000 --- a/applications/main/subghz/protocols/came.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_CAME_NAME "CAME" - -typedef struct SubGhzProtocolDecoderCame SubGhzProtocolDecoderCame; -typedef struct SubGhzProtocolEncoderCame SubGhzProtocolEncoderCame; - -extern const SubGhzProtocolDecoder subghz_protocol_came_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_came_encoder; -extern const SubGhzProtocol subghz_protocol_came; - -/** - * Allocate SubGhzProtocolEncoderCame. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderCame* pointer to a SubGhzProtocolEncoderCame instance - */ -void* subghz_protocol_encoder_came_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderCame. - * @param context Pointer to a SubGhzProtocolEncoderCame instance - */ -void subghz_protocol_encoder_came_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderCame instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_came_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderCame instance - */ -void subghz_protocol_encoder_came_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderCame instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_came_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderCame. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderCame* pointer to a SubGhzProtocolDecoderCame instance - */ -void* subghz_protocol_decoder_came_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderCame. - * @param context Pointer to a SubGhzProtocolDecoderCame instance - */ -void subghz_protocol_decoder_came_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderCame. - * @param context Pointer to a SubGhzProtocolDecoderCame instance - */ -void subghz_protocol_decoder_came_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderCame instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_came_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderCame instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_came_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderCame. - * @param context Pointer to a SubGhzProtocolDecoderCame instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_came_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderCame. - * @param context Pointer to a SubGhzProtocolDecoderCame instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_came_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderCame instance - * @param output Resulting text - */ -void subghz_protocol_decoder_came_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/came_atomo.c b/applications/main/subghz/protocols/came_atomo.c deleted file mode 100644 index d12e5976c..000000000 --- a/applications/main/subghz/protocols/came_atomo.c +++ /dev/null @@ -1,598 +0,0 @@ -#include "came_atomo.h" -#include -#include -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocoCameAtomo" - -static const SubGhzBlockConst subghz_protocol_came_atomo_const = { - .te_short = 600, - .te_long = 1200, - .te_delta = 250, - .min_count_bit_for_found = 62, -}; - -struct SubGhzProtocolDecoderCameAtomo { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - - ManchesterState manchester_saved_state; -}; - -struct SubGhzProtocolEncoderCameAtomo { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - CameAtomoDecoderStepReset = 0, - CameAtomoDecoderStepDecoderData, -} CameAtomoDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_came_atomo_decoder = { - .alloc = subghz_protocol_decoder_came_atomo_alloc, - .free = subghz_protocol_decoder_came_atomo_free, - - .feed = subghz_protocol_decoder_came_atomo_feed, - .reset = subghz_protocol_decoder_came_atomo_reset, - - .get_hash_data = subghz_protocol_decoder_came_atomo_get_hash_data, - .serialize = subghz_protocol_decoder_came_atomo_serialize, - .deserialize = subghz_protocol_decoder_came_atomo_deserialize, - .get_string = subghz_protocol_decoder_came_atomo_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_came_atomo_encoder = { - .alloc = subghz_protocol_encoder_came_atomo_alloc, - .free = subghz_protocol_encoder_came_atomo_free, - - .deserialize = subghz_protocol_encoder_came_atomo_deserialize, - .stop = subghz_protocol_encoder_came_atomo_stop, - .yield = subghz_protocol_encoder_came_atomo_yield, -}; - -const SubGhzProtocol subghz_protocol_came_atomo = { - .name = SUBGHZ_PROTOCOL_CAME_ATOMO_NAME, - .type = SubGhzProtocolTypeDynamic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_came_atomo_decoder, - .encoder = &subghz_protocol_came_atomo_encoder, -}; - -static void subghz_protocol_came_atomo_remote_controller(SubGhzBlockGeneric* instance); - -void* subghz_protocol_encoder_came_atomo_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderCameAtomo* instance = malloc(sizeof(SubGhzProtocolEncoderCameAtomo)); - - instance->base.protocol = &subghz_protocol_came_atomo; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 900; //actual size 766+ - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_came_atomo_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderCameAtomo* instance = context; - free(instance->encoder.upload); - free(instance); -} - -static LevelDuration - subghz_protocol_encoder_came_atomo_add_duration_to_upload(ManchesterEncoderResult result) { - LevelDuration data = {.duration = 0, .level = 0}; - switch(result) { - case ManchesterEncoderResultShortLow: - data.duration = subghz_protocol_came_atomo_const.te_short; - data.level = false; - break; - case ManchesterEncoderResultLongLow: - data.duration = subghz_protocol_came_atomo_const.te_long; - data.level = false; - break; - case ManchesterEncoderResultLongHigh: - data.duration = subghz_protocol_came_atomo_const.te_long; - data.level = true; - break; - case ManchesterEncoderResultShortHigh: - data.duration = subghz_protocol_came_atomo_const.te_short; - data.level = true; - break; - - default: - FURI_LOG_E(TAG, "SubGhz: ManchesterEncoderResult is incorrect."); - break; - } - return level_duration_make(data.level, data.duration); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderCameAtomo instance - */ -static void - subghz_protocol_encoder_came_atomo_get_upload(SubGhzProtocolEncoderCameAtomo* instance) { - furi_assert(instance); - size_t index = 0; - - ManchesterEncoderState enc_state; - manchester_encoder_reset(&enc_state); - ManchesterEncoderResult result; - - uint8_t pack[8] = {}; - - if(instance->generic.cnt < 0xFFFF) { - instance->generic.cnt++; - } else if(instance->generic.cnt >= 0xFFFF) { - instance->generic.cnt = 0; - } - - //Send header - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_came_atomo_const.te_long * 15); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_came_atomo_const.te_long * 60); - - for(uint8_t i = 0; i < 8; i++) { - pack[0] = (instance->generic.data_2 >> 56); - pack[1] = (instance->generic.cnt >> 8); - pack[2] = (instance->generic.cnt & 0xFF); - pack[3] = ((instance->generic.data_2 >> 32) & 0xFF); - pack[4] = ((instance->generic.data_2 >> 24) & 0xFF); - pack[5] = ((instance->generic.data_2 >> 16) & 0xFF); - pack[6] = ((instance->generic.data_2 >> 8) & 0xFF); - pack[7] = (instance->generic.data_2 & 0xFF); - - if(pack[0] == 0x7F) { - pack[0] = 0; - } else { - pack[0] += (i + 1); - } - - atomo_encrypt(pack); - uint32_t hi = pack[0] << 24 | pack[1] << 16 | pack[2] << 8 | pack[3]; - uint32_t lo = pack[4] << 24 | pack[5] << 16 | pack[6] << 8 | pack[7]; - instance->generic.data = (uint64_t)hi << 32 | lo; - - instance->generic.data ^= 0xFFFFFFFFFFFFFFFF; - instance->generic.data >>= 4; - instance->generic.data &= 0xFFFFFFFFFFFFFFF; - - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_came_atomo_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_came_atomo_const.te_short); - - for(uint8_t i = (instance->generic.data_count_bit - 2); i > 0; i--) { - if(!manchester_encoder_advance( - &enc_state, !bit_read(instance->generic.data, i - 1), &result)) { - instance->encoder.upload[index++] = - subghz_protocol_encoder_came_atomo_add_duration_to_upload(result); - manchester_encoder_advance( - &enc_state, !bit_read(instance->generic.data, i - 1), &result); - } - instance->encoder.upload[index++] = - subghz_protocol_encoder_came_atomo_add_duration_to_upload(result); - } - instance->encoder.upload[index] = - subghz_protocol_encoder_came_atomo_add_duration_to_upload( - manchester_encoder_finish(&enc_state)); - if(level_duration_get_level(instance->encoder.upload[index])) { - index++; - } - //Send pause - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_came_atomo_const.te_delta * 272); - } - instance->encoder.size_upload = index; - instance->generic.cnt_2++; - pack[0] = (instance->generic.cnt_2); - pack[1] = (instance->generic.cnt >> 8); - pack[2] = (instance->generic.cnt & 0xFF); - pack[3] = ((instance->generic.data_2 >> 32) & 0xFF); - pack[4] = ((instance->generic.data_2 >> 24) & 0xFF); - pack[5] = ((instance->generic.data_2 >> 16) & 0xFF); - pack[6] = ((instance->generic.data_2 >> 8) & 0xFF); - pack[7] = (instance->generic.data_2 & 0xFF); - - atomo_encrypt(pack); - uint32_t hi = pack[0] << 24 | pack[1] << 16 | pack[2] << 8 | pack[3]; - uint32_t lo = pack[4] << 24 | pack[5] << 16 | pack[6] << 8 | pack[7]; - instance->generic.data = (uint64_t)hi << 32 | lo; - - instance->generic.data ^= 0xFFFFFFFFFFFFFFFF; - instance->generic.data >>= 4; - instance->generic.data &= 0xFFFFFFFFFFFFFFF; -} - -bool subghz_protocol_encoder_came_atomo_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderCameAtomo* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - subghz_protocol_came_atomo_remote_controller(&instance->generic); - subghz_protocol_encoder_came_atomo_get_upload(instance); - - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - uint8_t key_data[sizeof(uint64_t)] = {0}; - for(size_t i = 0; i < sizeof(uint64_t); i++) { - key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data >> i * 8) & 0xFF; - } - if(!flipper_format_update_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Unable to add Key"); - break; - } - - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_came_atomo_stop(void* context) { - SubGhzProtocolEncoderCameAtomo* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_came_atomo_yield(void* context) { - SubGhzProtocolEncoderCameAtomo* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_came_atomo_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderCameAtomo* instance = malloc(sizeof(SubGhzProtocolDecoderCameAtomo)); - instance->base.protocol = &subghz_protocol_came_atomo; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_came_atomo_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderCameAtomo* instance = context; - free(instance); -} - -void subghz_protocol_decoder_came_atomo_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderCameAtomo* instance = context; - instance->decoder.parser_step = CameAtomoDecoderStepReset; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventReset, - &instance->manchester_saved_state, - NULL); -} - -void subghz_protocol_decoder_came_atomo_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderCameAtomo* instance = context; - - ManchesterEvent event = ManchesterEventReset; - switch(instance->decoder.parser_step) { - case CameAtomoDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_came_atomo_const.te_long * 60) < - subghz_protocol_came_atomo_const.te_delta * 40)) { - //Found header CAME - instance->decoder.parser_step = CameAtomoDecoderStepDecoderData; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 1; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventReset, - &instance->manchester_saved_state, - NULL); - manchester_advance( - instance->manchester_saved_state, - ManchesterEventShortLow, - &instance->manchester_saved_state, - NULL); - } - break; - case CameAtomoDecoderStepDecoderData: - if(!level) { - if(DURATION_DIFF(duration, subghz_protocol_came_atomo_const.te_short) < - subghz_protocol_came_atomo_const.te_delta) { - event = ManchesterEventShortLow; - } else if( - DURATION_DIFF(duration, subghz_protocol_came_atomo_const.te_long) < - subghz_protocol_came_atomo_const.te_delta) { - event = ManchesterEventLongLow; - } else if( - duration >= ((uint32_t)subghz_protocol_came_atomo_const.te_long * 2 + - subghz_protocol_came_atomo_const.te_delta)) { - if(instance->decoder.decode_count_bit == - subghz_protocol_came_atomo_const.min_count_bit_for_found) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 1; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventReset, - &instance->manchester_saved_state, - NULL); - manchester_advance( - instance->manchester_saved_state, - ManchesterEventShortLow, - &instance->manchester_saved_state, - NULL); - } else { - instance->decoder.parser_step = CameAtomoDecoderStepReset; - } - } else { - if(DURATION_DIFF(duration, subghz_protocol_came_atomo_const.te_short) < - subghz_protocol_came_atomo_const.te_delta) { - event = ManchesterEventShortHigh; - } else if( - DURATION_DIFF(duration, subghz_protocol_came_atomo_const.te_long) < - subghz_protocol_came_atomo_const.te_delta) { - event = ManchesterEventLongHigh; - } else { - instance->decoder.parser_step = CameAtomoDecoderStepReset; - } - } - if(event != ManchesterEventReset) { - bool data; - bool data_ok = manchester_advance( - instance->manchester_saved_state, event, &instance->manchester_saved_state, &data); - - if(data_ok) { - instance->decoder.decode_data = (instance->decoder.decode_data << 1) | !data; - instance->decoder.decode_count_bit++; - } - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - * @param file_name Full path to rainbow table the file - */ -static void subghz_protocol_came_atomo_remote_controller(SubGhzBlockGeneric* instance) { - /* - * ***SkorP ver.*** - * 0x1fafef3ed0f7d9ef - * 0x185fcc1531ee86e7 - * 0x184fa96912c567ff - * 0x187f8a42f3dc38f7 - * 0x186f63915492a5cd - * 0x181f40bab58bfac5 - * 0x180f25c696a01bdd - * 0x183f06ed77b944d5 - * 0x182ef661d83d21a9 - * 0x18ded54a39247ea1 - * 0x18ceb0361a0f9fb9 - * 0x18fe931dfb16c0b1 - * 0x18ee7ace5c585d8b - * ........ - * transmission consists of 99 parcels with increasing counter while holding down the button - * with each new press, the counter in the encrypted part increases - * - * 0x1FAFF13ED0F7D9EF - * 0x1FAFF11ED0F7D9EF - * 0x1FAFF10ED0F7D9EF - * 0x1FAFF0FED0F7D9EF - * 0x1FAFF0EED0F7D9EF - * 0x1FAFF0DED0F7D9EF - * 0x1FAFF0CED0F7D9EF - * 0x1FAFF0BED0F7D9EF - * 0x1FAFF0AED0F7D9EF - * - * where 0x1FAF - parcel counter, 0хF0A - button press counter, - * 0xED0F7D9E - serial number, 0хF - key - * 0x1FAF parcel counter - 1 in the parcel queue ^ 0x185F = 0x07F0 - * 0x185f ^ 0x185F = 0x0000 - * 0x184f ^ 0x185F = 0x0010 - * 0x187f ^ 0x185F = 0x0020 - * ..... - * 0x182e ^ 0x185F = 0x0071 - * 0x18de ^ 0x185F = 0x0081 - * ..... - * 0x1e43 ^ 0x185F = 0x061C - * where the last nibble is incremented every 8 samples - * - * Decode - * - * 0x1cf6931dfb16c0b1 => 0x1cf6 - * 0x1cf6 ^ 0x185F = 0x04A9 - * 0x04A9 => 0x04A = 74 (dec) - * 74+1 % 32(atomo_magic_xor) = 11 - * GET atomo_magic_xor[11] = 0xXXXXXXXXXXXXXXXX - * 0x931dfb16c0b1 ^ 0xXXXXXXXXXXXXXXXX = 0xEF3ED0F7D9EF - * 0xEF3 ED0F7D9E F => 0xEF3 - CNT, 0xED0F7D9E - SN, 0xF - key - * - * ***Eng1n33r ver. (actual)*** - * 0x1FF08D9924984115 - received data - * 0x00F7266DB67BEEA0 - inverted data - * 0x0501FD0000A08300 - decrypted data, - * where: 0x05 - Button hold-cycle counter (8-bit, from 0 to 0x7F) - * 0x01FD - Parcel counter (normal 16-bit counter) - * 0x0000A083 - Serial number (32-bit) - * 0x0 - Button code (4-bit, 0x0 - #1 left-up; 0x2 - #2 right-up; 0x4 - #3 left-down; 0x6 - #4 right-down) - * 0x0 - Last zero nibble - * */ - - instance->data ^= 0xFFFFFFFFFFFFFFFF; - instance->data <<= 4; - - uint8_t pack[8] = {}; - pack[0] = (instance->data >> 56); - pack[1] = ((instance->data >> 48) & 0xFF); - pack[2] = ((instance->data >> 40) & 0xFF); - pack[3] = ((instance->data >> 32) & 0xFF); - pack[4] = ((instance->data >> 24) & 0xFF); - pack[5] = ((instance->data >> 16) & 0xFF); - pack[6] = ((instance->data >> 8) & 0xFF); - pack[7] = (instance->data & 0xFF); - - atomo_decrypt(pack); - - instance->cnt_2 = pack[0]; - instance->cnt = (uint16_t)pack[1] << 8 | pack[2]; - instance->serial = (uint32_t)(pack[3]) << 24 | pack[4] << 16 | pack[5] << 8 | pack[6]; - - uint8_t btn_decode = (pack[7] >> 4); - if(btn_decode == 0x0) { - instance->btn = 0x1; - } - if(btn_decode == 0x2) { - instance->btn = 0x2; - } - if(btn_decode == 0x4) { - instance->btn = 0x3; - } - if(btn_decode == 0x6) { - instance->btn = 0x4; - } - - uint32_t hi = pack[0] << 24 | pack[1] << 16 | pack[2] << 8 | pack[3]; - uint32_t lo = pack[4] << 24 | pack[5] << 16 | pack[6] << 8 | pack[7]; - instance->data_2 = (uint64_t)hi << 32 | lo; -} - -void atomo_encrypt(uint8_t* buff) { - uint8_t tmpB = (~buff[0] + 1) & 0x7F; - - uint8_t bitCnt = 8; - while(bitCnt < 59) { - if((tmpB & 0x18) && (((tmpB / 8) & 3) != 3)) { - tmpB = ((tmpB << 1) & 0xFF) | 1; - } else { - tmpB = (tmpB << 1) & 0xFF; - } - - if(tmpB & 0x80) { - buff[bitCnt / 8] ^= (0x80 >> (bitCnt & 7)); - } - - bitCnt++; - } - - buff[0] = (buff[0] ^ 5) & 0x7F; -} - -void atomo_decrypt(uint8_t* buff) { - buff[0] = (buff[0] ^ 5) & 0x7F; - uint8_t tmpB = (-buff[0]) & 0x7F; - - uint8_t bitCnt = 8; - while(bitCnt < 59) { - if((tmpB & 0x18) && (((tmpB / 8) & 3) != 3)) { - tmpB = ((tmpB << 1) & 0xFF) | 1; - } else { - tmpB = (tmpB << 1) & 0xFF; - } - - if(tmpB & 0x80) { - buff[bitCnt / 8] ^= (0x80 >> (bitCnt & 7)); - } - - bitCnt++; - } -} - -uint8_t subghz_protocol_decoder_came_atomo_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderCameAtomo* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_came_atomo_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderCameAtomo* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_came_atomo_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderCameAtomo* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_came_atomo_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_came_atomo_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderCameAtomo* instance = context; - subghz_protocol_came_atomo_remote_controller(&instance->generic); - uint32_t code_found_hi = instance->generic.data >> 32; - uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; - - furi_string_cat_printf( - output, - "%s %db\r\n" - "Key:0x%08lX%08lX\r\n" - "Sn:0x%08lX Btn:0x%01X\r\n" - "Pcl_Cnt:0x%04lX\r\n" - "Btn_Cnt:0x%02X", - - instance->generic.protocol_name, - instance->generic.data_count_bit, - code_found_hi, - code_found_lo, - instance->generic.serial, - instance->generic.btn, - instance->generic.cnt, - instance->generic.cnt_2); -} diff --git a/applications/main/subghz/protocols/came_atomo.h b/applications/main/subghz/protocols/came_atomo.h deleted file mode 100644 index 736aee850..000000000 --- a/applications/main/subghz/protocols/came_atomo.h +++ /dev/null @@ -1,110 +0,0 @@ -#pragma once -#include "base.h" - -#define SUBGHZ_PROTOCOL_CAME_ATOMO_NAME "CAME Atomo" - -typedef struct SubGhzProtocolDecoderCameAtomo SubGhzProtocolDecoderCameAtomo; -typedef struct SubGhzProtocolEncoderCameAtomo SubGhzProtocolEncoderCameAtomo; - -extern const SubGhzProtocolDecoder subghz_protocol_came_atomo_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_came_atomo_encoder; -extern const SubGhzProtocol subghz_protocol_came_atomo; - -void atomo_decrypt(uint8_t* buff); - -void atomo_encrypt(uint8_t* buff); - -/** - * Allocate SubGhzProtocolEncoderCameAtomo. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderCameAtomo* pointer to a SubGhzProtocolEncoderCameAtomo instance - */ -void* subghz_protocol_encoder_came_atomo_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderCameAtomo. - * @param context Pointer to a SubGhzProtocolEncoderCameAtomo instance - */ -void subghz_protocol_encoder_came_atomo_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderCameAtomo instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_came_atomo_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderCameAtomo instance - */ -void subghz_protocol_encoder_came_atomo_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderCameAtomo instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_came_atomo_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderCameAtomo. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderCameAtomo* pointer to a SubGhzProtocolDecoderCameAtomo instance - */ -void* subghz_protocol_decoder_came_atomo_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderCameAtomo. - * @param context Pointer to a SubGhzProtocolDecoderCameAtomo instance - */ -void subghz_protocol_decoder_came_atomo_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderCameAtomo. - * @param context Pointer to a SubGhzProtocolDecoderCameAtomo instance - */ -void subghz_protocol_decoder_came_atomo_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderCameAtomo instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_came_atomo_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderCameAtomo instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_came_atomo_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderCameAtomo. - * @param context Pointer to a SubGhzProtocolDecoderCameAtomo instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_came_atomo_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderCameAtomo. - * @param context Pointer to a SubGhzProtocolDecoderCameAtomo instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_came_atomo_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderCameAtomo instance - * @param output Resulting text - */ -void subghz_protocol_decoder_came_atomo_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/came_twee.c b/applications/main/subghz/protocols/came_twee.c deleted file mode 100644 index e7eb33c42..000000000 --- a/applications/main/subghz/protocols/came_twee.c +++ /dev/null @@ -1,468 +0,0 @@ -#include "came_twee.h" -#include -#include -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -/* - * Help - * https://phreakerclub.com/forum/showthread.php?t=635&highlight=came+twin - * - */ - -#define TAG "SubGhzProtocolCAME_Twee" - -#define DIP_PATTERN "%c%c%c%c%c%c%c%c%c%c" -#define CNT_TO_DIP(dip) \ - (dip & 0x0200 ? '1' : '0'), (dip & 0x0100 ? '1' : '0'), (dip & 0x0080 ? '1' : '0'), \ - (dip & 0x0040 ? '1' : '0'), (dip & 0x0020 ? '1' : '0'), (dip & 0x0010 ? '1' : '0'), \ - (dip & 0x0008 ? '1' : '0'), (dip & 0x0004 ? '1' : '0'), (dip & 0x0002 ? '1' : '0'), \ - (dip & 0x0001 ? '1' : '0') - -/** - * Rainbow table Came Twee. - */ -static const uint32_t came_twee_magic_numbers_xor[15] = { - 0x0E0E0E00, - 0x1D1D1D11, - 0x2C2C2C22, - 0x3B3B3B33, - 0x4A4A4A44, - 0x59595955, - 0x68686866, - 0x77777777, - 0x86868688, - 0x95959599, - 0xA4A4A4AA, - 0xB3B3B3BB, - 0xC2C2C2CC, - 0xD1D1D1DD, - 0xE0E0E0EE, -}; - -static const SubGhzBlockConst subghz_protocol_came_twee_const = { - .te_short = 500, - .te_long = 1000, - .te_delta = 250, - .min_count_bit_for_found = 54, -}; - -struct SubGhzProtocolDecoderCameTwee { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - ManchesterState manchester_saved_state; -}; - -struct SubGhzProtocolEncoderCameTwee { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - CameTweeDecoderStepReset = 0, - CameTweeDecoderStepDecoderData, -} CameTweeDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_came_twee_decoder = { - .alloc = subghz_protocol_decoder_came_twee_alloc, - .free = subghz_protocol_decoder_came_twee_free, - - .feed = subghz_protocol_decoder_came_twee_feed, - .reset = subghz_protocol_decoder_came_twee_reset, - - .get_hash_data = subghz_protocol_decoder_came_twee_get_hash_data, - .serialize = subghz_protocol_decoder_came_twee_serialize, - .deserialize = subghz_protocol_decoder_came_twee_deserialize, - .get_string = subghz_protocol_decoder_came_twee_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_came_twee_encoder = { - .alloc = subghz_protocol_encoder_came_twee_alloc, - .free = subghz_protocol_encoder_came_twee_free, - - .deserialize = subghz_protocol_encoder_came_twee_deserialize, - .stop = subghz_protocol_encoder_came_twee_stop, - .yield = subghz_protocol_encoder_came_twee_yield, -}; - -const SubGhzProtocol subghz_protocol_came_twee = { - .name = SUBGHZ_PROTOCOL_CAME_TWEE_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_came_twee_decoder, - .encoder = &subghz_protocol_came_twee_encoder, -}; - -void* subghz_protocol_encoder_came_twee_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderCameTwee* instance = malloc(sizeof(SubGhzProtocolEncoderCameTwee)); - - instance->base.protocol = &subghz_protocol_came_twee; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 1536; //max upload 92*14 = 1288 !!!! - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_came_twee_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderCameTwee* instance = context; - free(instance->encoder.upload); - free(instance); -} - -static LevelDuration - subghz_protocol_encoder_came_twee_add_duration_to_upload(ManchesterEncoderResult result) { - LevelDuration data = {.duration = 0, .level = 0}; - switch(result) { - case ManchesterEncoderResultShortLow: - data.duration = subghz_protocol_came_twee_const.te_short; - data.level = false; - break; - case ManchesterEncoderResultLongLow: - data.duration = subghz_protocol_came_twee_const.te_long; - data.level = false; - break; - case ManchesterEncoderResultLongHigh: - data.duration = subghz_protocol_came_twee_const.te_long; - data.level = true; - break; - case ManchesterEncoderResultShortHigh: - data.duration = subghz_protocol_came_twee_const.te_short; - data.level = true; - break; - - default: - furi_crash("SubGhz: ManchesterEncoderResult is incorrect."); - break; - } - return level_duration_make(data.level, data.duration); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderCameTwee instance - */ -static void subghz_protocol_encoder_came_twee_get_upload(SubGhzProtocolEncoderCameTwee* instance) { - furi_assert(instance); - size_t index = 0; - - ManchesterEncoderState enc_state; - manchester_encoder_reset(&enc_state); - ManchesterEncoderResult result; - - uint64_t temp_parcel = 0x003FFF7200000000; //parcel mask - - for(int i = 14; i >= 0; i--) { - temp_parcel = (temp_parcel & 0xFFFFFFFF00000000) | - (instance->generic.serial ^ came_twee_magic_numbers_xor[i]); - - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(!manchester_encoder_advance(&enc_state, !bit_read(temp_parcel, i - 1), &result)) { - instance->encoder.upload[index++] = - subghz_protocol_encoder_came_twee_add_duration_to_upload(result); - manchester_encoder_advance(&enc_state, !bit_read(temp_parcel, i - 1), &result); - } - instance->encoder.upload[index++] = - subghz_protocol_encoder_came_twee_add_duration_to_upload(result); - } - instance->encoder.upload[index] = subghz_protocol_encoder_came_twee_add_duration_to_upload( - manchester_encoder_finish(&enc_state)); - if(level_duration_get_level(instance->encoder.upload[index])) { - index++; - } - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_came_twee_const.te_long * 51); - } - instance->encoder.size_upload = index; -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - */ -static void subghz_protocol_came_twee_remote_controller(SubGhzBlockGeneric* instance) { - /* Came Twee 54 bit, rolling code 15 parcels with - * a decreasing counter from 0xE to 0x0 - * with originally coded dip switches on the console 10 bit code - * - * 0x003FFF72E04A6FEE - * 0x003FFF72D17B5EDD - * 0x003FFF72C2684DCC - * 0x003FFF72B3193CBB - * 0x003FFF72A40E2BAA - * 0x003FFF72953F1A99 - * 0x003FFF72862C0988 - * 0x003FFF7277DDF877 - * 0x003FFF7268C2E766 - * 0x003FFF7259F3D655 - * 0x003FFF724AE0C544 - * 0x003FFF723B91B433 - * 0x003FFF722C86A322 - * 0x003FFF721DB79211 - * 0x003FFF720EA48100 - * - * decryption - * the last 32 bits, do XOR by the desired number, divide the result by 4, - * convert the first 16 bits of the resulting 32-bit number to bin and do - * bit-by-bit mirroring, adding up to 10 bits - * - * Example - * Step 1. 0x003FFF721DB79211 => 0x1DB79211 - * Step 4. 0x1DB79211 xor 0x1D1D1D11 => 0x00AA8F00 - * Step 4. 0x00AA8F00 / 4 => 0x002AA3C0 - * Step 5. 0x002AA3C0 => 0x002A - * Step 6. 0x002A bin => b101010 - * Step 7. b101010 => b0101010000 - * Step 8. b0101010000 => (Dip) Off ON Off ON Off ON Off Off Off Off - */ - - uint8_t cnt_parcel = (uint8_t)(instance->data & 0xF); - uint32_t data = (uint32_t)(instance->data & 0x0FFFFFFFF); - - data = (data ^ came_twee_magic_numbers_xor[cnt_parcel]); - instance->serial = data; - data /= 4; - instance->btn = (data >> 4) & 0x0F; - data >>= 16; - data = (uint16_t)subghz_protocol_blocks_reverse_key(data, 16); - instance->cnt = data >> 6; -} - -bool subghz_protocol_encoder_came_twee_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderCameTwee* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_came_twee_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - subghz_protocol_came_twee_remote_controller(&instance->generic); - subghz_protocol_encoder_came_twee_get_upload(instance); - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_came_twee_stop(void* context) { - SubGhzProtocolEncoderCameTwee* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_came_twee_yield(void* context) { - SubGhzProtocolEncoderCameTwee* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_came_twee_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderCameTwee* instance = malloc(sizeof(SubGhzProtocolDecoderCameTwee)); - instance->base.protocol = &subghz_protocol_came_twee; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_came_twee_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderCameTwee* instance = context; - free(instance); -} - -void subghz_protocol_decoder_came_twee_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderCameTwee* instance = context; - instance->decoder.parser_step = CameTweeDecoderStepReset; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventReset, - &instance->manchester_saved_state, - NULL); -} - -void subghz_protocol_decoder_came_twee_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderCameTwee* instance = context; - ManchesterEvent event = ManchesterEventReset; - switch(instance->decoder.parser_step) { - case CameTweeDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_came_twee_const.te_long * 51) < - subghz_protocol_came_twee_const.te_delta * 20)) { - //Found header CAME - instance->decoder.parser_step = CameTweeDecoderStepDecoderData; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventLongLow, - &instance->manchester_saved_state, - NULL); - manchester_advance( - instance->manchester_saved_state, - ManchesterEventLongHigh, - &instance->manchester_saved_state, - NULL); - manchester_advance( - instance->manchester_saved_state, - ManchesterEventShortLow, - &instance->manchester_saved_state, - NULL); - } - break; - case CameTweeDecoderStepDecoderData: - if(!level) { - if(DURATION_DIFF(duration, subghz_protocol_came_twee_const.te_short) < - subghz_protocol_came_twee_const.te_delta) { - event = ManchesterEventShortLow; - } else if( - DURATION_DIFF(duration, subghz_protocol_came_twee_const.te_long) < - subghz_protocol_came_twee_const.te_delta) { - event = ManchesterEventLongLow; - } else if( - duration >= ((uint32_t)subghz_protocol_came_twee_const.te_long * 2 + - subghz_protocol_came_twee_const.te_delta)) { - if(instance->decoder.decode_count_bit == - subghz_protocol_came_twee_const.min_count_bit_for_found) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventLongLow, - &instance->manchester_saved_state, - NULL); - manchester_advance( - instance->manchester_saved_state, - ManchesterEventLongHigh, - &instance->manchester_saved_state, - NULL); - manchester_advance( - instance->manchester_saved_state, - ManchesterEventShortLow, - &instance->manchester_saved_state, - NULL); - } else { - instance->decoder.parser_step = CameTweeDecoderStepReset; - } - } else { - if(DURATION_DIFF(duration, subghz_protocol_came_twee_const.te_short) < - subghz_protocol_came_twee_const.te_delta) { - event = ManchesterEventShortHigh; - } else if( - DURATION_DIFF(duration, subghz_protocol_came_twee_const.te_long) < - subghz_protocol_came_twee_const.te_delta) { - event = ManchesterEventLongHigh; - } else { - instance->decoder.parser_step = CameTweeDecoderStepReset; - } - } - if(event != ManchesterEventReset) { - bool data; - bool data_ok = manchester_advance( - instance->manchester_saved_state, event, &instance->manchester_saved_state, &data); - - if(data_ok) { - instance->decoder.decode_data = (instance->decoder.decode_data << 1) | !data; - instance->decoder.decode_count_bit++; - } - } - break; - } -} - -uint8_t subghz_protocol_decoder_came_twee_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderCameTwee* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_came_twee_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderCameTwee* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_came_twee_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderCameTwee* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_came_twee_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_came_twee_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderCameTwee* instance = context; - subghz_protocol_came_twee_remote_controller(&instance->generic); - uint32_t code_found_hi = instance->generic.data >> 32; - uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; - - furi_string_cat_printf( - output, - "%s %db\r\n" - "Key:0x%lX%08lX\r\n" - "Btn:%X\r\n" - "DIP:" DIP_PATTERN "\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - code_found_hi, - code_found_lo, - instance->generic.btn, - CNT_TO_DIP(instance->generic.cnt)); -} diff --git a/applications/main/subghz/protocols/came_twee.h b/applications/main/subghz/protocols/came_twee.h deleted file mode 100644 index 359b964da..000000000 --- a/applications/main/subghz/protocols/came_twee.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_CAME_TWEE_NAME "CAME TWEE" - -typedef struct SubGhzProtocolDecoderCameTwee SubGhzProtocolDecoderCameTwee; -typedef struct SubGhzProtocolEncoderCameTwee SubGhzProtocolEncoderCameTwee; - -extern const SubGhzProtocolDecoder subghz_protocol_came_twee_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_came_twee_encoder; -extern const SubGhzProtocol subghz_protocol_came_twee; - -/** - * Allocate SubGhzProtocolEncoderCameTwee. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderCameTwee* pointer to a SubGhzProtocolEncoderCameTwee instance - */ -void* subghz_protocol_encoder_came_twee_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderCameTwee. - * @param context Pointer to a SubGhzProtocolEncoderCameTwee instance - */ -void subghz_protocol_encoder_came_twee_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderCameTwee instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_came_twee_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderCameTwee instance - */ -void subghz_protocol_encoder_came_twee_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderCameTwee instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_came_twee_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderCameTwee. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderCameTwee* pointer to a SubGhzProtocolDecoderCameTwee instance - */ -void* subghz_protocol_decoder_came_twee_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderCameTwee. - * @param context Pointer to a SubGhzProtocolDecoderCameTwee instance - */ -void subghz_protocol_decoder_came_twee_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderCameTwee. - * @param context Pointer to a SubGhzProtocolDecoderCameTwee instance - */ -void subghz_protocol_decoder_came_twee_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderCameTwee instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_came_twee_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderCameTwee instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_came_twee_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderCameTwee. - * @param context Pointer to a SubGhzProtocolDecoderCameTwee instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_came_twee_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderCameTwee. - * @param context Pointer to a SubGhzProtocolDecoderCameTwee instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_came_twee_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderCameTwee instance - * @param output Resulting text - */ -void subghz_protocol_decoder_came_twee_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/chamberlain_code.c b/applications/main/subghz/protocols/chamberlain_code.c deleted file mode 100644 index 9c8e5ee4a..000000000 --- a/applications/main/subghz/protocols/chamberlain_code.c +++ /dev/null @@ -1,499 +0,0 @@ -#include "chamberlain_code.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolChamb_Code" - -#define CHAMBERLAIN_CODE_BIT_STOP 0b0001 -#define CHAMBERLAIN_CODE_BIT_1 0b0011 -#define CHAMBERLAIN_CODE_BIT_0 0b0111 - -#define CHAMBERLAIN_7_CODE_MASK 0xF000000FF0F -#define CHAMBERLAIN_8_CODE_MASK 0xF00000F00F -#define CHAMBERLAIN_9_CODE_MASK 0xF000000000F - -#define CHAMBERLAIN_7_CODE_MASK_CHECK 0x10000001101 -#define CHAMBERLAIN_8_CODE_MASK_CHECK 0x1000001001 -#define CHAMBERLAIN_9_CODE_MASK_CHECK 0x10000000001 - -#define CHAMBERLAIN_7_CODE_DIP_PATTERN "%c%c%c%c%c%c%c" -#define CHAMBERLAIN_7_CODE_DATA_TO_DIP(dip) \ - (dip & 0x0040 ? '1' : '0'), (dip & 0x0020 ? '1' : '0'), (dip & 0x0010 ? '1' : '0'), \ - (dip & 0x0008 ? '1' : '0'), (dip & 0x0004 ? '1' : '0'), (dip & 0x0002 ? '1' : '0'), \ - (dip & 0x0001 ? '1' : '0') - -#define CHAMBERLAIN_8_CODE_DIP_PATTERN "%c%c%c%c%cx%c%c" -#define CHAMBERLAIN_8_CODE_DATA_TO_DIP(dip) \ - (dip & 0x0080 ? '1' : '0'), (dip & 0x0040 ? '1' : '0'), (dip & 0x0020 ? '1' : '0'), \ - (dip & 0x0010 ? '1' : '0'), (dip & 0x0008 ? '1' : '0'), (dip & 0x0001 ? '1' : '0'), \ - (dip & 0x0002 ? '1' : '0') - -#define CHAMBERLAIN_9_CODE_DIP_PATTERN "%c%c%c%c%c%c%c%c%c" -#define CHAMBERLAIN_9_CODE_DATA_TO_DIP(dip) \ - (dip & 0x0100 ? '1' : '0'), (dip & 0x0080 ? '1' : '0'), (dip & 0x0040 ? '1' : '0'), \ - (dip & 0x0020 ? '1' : '0'), (dip & 0x0010 ? '1' : '0'), (dip & 0x0008 ? '1' : '0'), \ - (dip & 0x0001 ? '1' : '0'), (dip & 0x0002 ? '1' : '0'), (dip & 0x0004 ? '1' : '0') - -static const SubGhzBlockConst subghz_protocol_chamb_code_const = { - .te_short = 1000, - .te_long = 3000, - .te_delta = 200, - .min_count_bit_for_found = 10, -}; - -struct SubGhzProtocolDecoderChamb_Code { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; -}; - -struct SubGhzProtocolEncoderChamb_Code { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - Chamb_CodeDecoderStepReset = 0, - Chamb_CodeDecoderStepFoundStartBit, - Chamb_CodeDecoderStepSaveDuration, - Chamb_CodeDecoderStepCheckDuration, -} Chamb_CodeDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_chamb_code_decoder = { - .alloc = subghz_protocol_decoder_chamb_code_alloc, - .free = subghz_protocol_decoder_chamb_code_free, - - .feed = subghz_protocol_decoder_chamb_code_feed, - .reset = subghz_protocol_decoder_chamb_code_reset, - - .get_hash_data = subghz_protocol_decoder_chamb_code_get_hash_data, - .serialize = subghz_protocol_decoder_chamb_code_serialize, - .deserialize = subghz_protocol_decoder_chamb_code_deserialize, - .get_string = subghz_protocol_decoder_chamb_code_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_chamb_code_encoder = { - .alloc = subghz_protocol_encoder_chamb_code_alloc, - .free = subghz_protocol_encoder_chamb_code_free, - - .deserialize = subghz_protocol_encoder_chamb_code_deserialize, - .stop = subghz_protocol_encoder_chamb_code_stop, - .yield = subghz_protocol_encoder_chamb_code_yield, -}; - -const SubGhzProtocol subghz_protocol_chamb_code = { - .name = SUBGHZ_PROTOCOL_CHAMB_CODE_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_315 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_chamb_code_decoder, - .encoder = &subghz_protocol_chamb_code_encoder, -}; - -void* subghz_protocol_encoder_chamb_code_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderChamb_Code* instance = malloc(sizeof(SubGhzProtocolEncoderChamb_Code)); - - instance->base.protocol = &subghz_protocol_chamb_code; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 24; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_chamb_code_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderChamb_Code* instance = context; - free(instance->encoder.upload); - free(instance); -} - -static uint64_t subghz_protocol_chamb_bit_to_code(uint64_t data, uint8_t size) { - uint64_t data_res = 0; - for(uint8_t i = 0; i < size; i++) { - if(!(bit_read(data, size - i - 1))) { - data_res = data_res << 4 | CHAMBERLAIN_CODE_BIT_0; - } else { - data_res = data_res << 4 | CHAMBERLAIN_CODE_BIT_1; - } - } - return data_res; -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderChamb_Code instance - * @return true On success - */ -static bool - subghz_protocol_encoder_chamb_code_get_upload(SubGhzProtocolEncoderChamb_Code* instance) { - furi_assert(instance); - - uint64_t data = subghz_protocol_chamb_bit_to_code( - instance->generic.data, instance->generic.data_count_bit); - - switch(instance->generic.data_count_bit) { - case 7: - data = ((data >> 4) << 16) | (data & 0xF) << 4 | CHAMBERLAIN_7_CODE_MASK_CHECK; - break; - case 8: - data = ((data >> 12) << 16) | (data & 0xFF) << 4 | CHAMBERLAIN_8_CODE_MASK_CHECK; - break; - case 9: - data = (data << 4) | CHAMBERLAIN_9_CODE_MASK_CHECK; - break; - - default: - FURI_LOG_E(TAG, "Invalid bits count"); - return false; - break; - } -#define UPLOAD_HEX_DATA_SIZE 10 - uint8_t upload_hex_data[UPLOAD_HEX_DATA_SIZE] = {0}; - size_t upload_hex_count_bit = 0; - - //insert guard time - for(uint8_t i = 0; i < 36; i++) { - subghz_protocol_blocks_set_bit_array( - 0, upload_hex_data, upload_hex_count_bit++, UPLOAD_HEX_DATA_SIZE); - } - - //insert data - switch(instance->generic.data_count_bit) { - case 7: - case 9: - for(uint8_t i = 44; i > 0; i--) { - if(!bit_read(data, i - 1)) { - subghz_protocol_blocks_set_bit_array( - 0, upload_hex_data, upload_hex_count_bit++, UPLOAD_HEX_DATA_SIZE); - } else { - subghz_protocol_blocks_set_bit_array( - 1, upload_hex_data, upload_hex_count_bit++, UPLOAD_HEX_DATA_SIZE); - } - } - break; - case 8: - for(uint8_t i = 40; i > 0; i--) { - if(!bit_read(data, i - 1)) { - subghz_protocol_blocks_set_bit_array( - 0, upload_hex_data, upload_hex_count_bit++, UPLOAD_HEX_DATA_SIZE); - } else { - subghz_protocol_blocks_set_bit_array( - 1, upload_hex_data, upload_hex_count_bit++, UPLOAD_HEX_DATA_SIZE); - } - } - break; - } - - instance->encoder.size_upload = subghz_protocol_blocks_get_upload_from_bit_array( - upload_hex_data, - upload_hex_count_bit, - instance->encoder.upload, - instance->encoder.size_upload, - subghz_protocol_chamb_code_const.te_short, - SubGhzProtocolBlockAlignBitLeft); - - return true; -} - -bool subghz_protocol_encoder_chamb_code_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderChamb_Code* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit > - subghz_protocol_chamb_code_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_chamb_code_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_chamb_code_stop(void* context) { - SubGhzProtocolEncoderChamb_Code* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_chamb_code_yield(void* context) { - SubGhzProtocolEncoderChamb_Code* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_chamb_code_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderChamb_Code* instance = malloc(sizeof(SubGhzProtocolDecoderChamb_Code)); - instance->base.protocol = &subghz_protocol_chamb_code; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_chamb_code_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderChamb_Code* instance = context; - free(instance); -} - -void subghz_protocol_decoder_chamb_code_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderChamb_Code* instance = context; - instance->decoder.parser_step = Chamb_CodeDecoderStepReset; -} - -static bool subghz_protocol_chamb_code_to_bit(uint64_t* data, uint8_t size) { - uint64_t data_tmp = data[0]; - uint64_t data_res = 0; - for(uint8_t i = 0; i < size; i++) { - if((data_tmp & 0xFll) == CHAMBERLAIN_CODE_BIT_0) { - bit_write(data_res, i, 0); - } else if((data_tmp & 0xFll) == CHAMBERLAIN_CODE_BIT_1) { - bit_write(data_res, i, 1); - } else { - return false; - } - data_tmp >>= 4; - } - data[0] = data_res; - return true; -} - -static bool subghz_protocol_decoder_chamb_code_check_mask_and_parse( - SubGhzProtocolDecoderChamb_Code* instance) { - furi_assert(instance); - if(instance->decoder.decode_count_bit > - subghz_protocol_chamb_code_const.min_count_bit_for_found + 1) - return false; - - if((instance->decoder.decode_data & CHAMBERLAIN_7_CODE_MASK) == - CHAMBERLAIN_7_CODE_MASK_CHECK) { - instance->decoder.decode_count_bit = 7; - instance->decoder.decode_data &= ~CHAMBERLAIN_7_CODE_MASK; - instance->decoder.decode_data = (instance->decoder.decode_data >> 12) | - ((instance->decoder.decode_data >> 4) & 0xF); - } else if( - (instance->decoder.decode_data & CHAMBERLAIN_8_CODE_MASK) == - CHAMBERLAIN_8_CODE_MASK_CHECK) { - instance->decoder.decode_count_bit = 8; - instance->decoder.decode_data &= ~CHAMBERLAIN_8_CODE_MASK; - instance->decoder.decode_data = instance->decoder.decode_data >> 4 | - CHAMBERLAIN_CODE_BIT_0 << 8; //DIP 6 no use - } else if( - (instance->decoder.decode_data & CHAMBERLAIN_9_CODE_MASK) == - CHAMBERLAIN_9_CODE_MASK_CHECK) { - instance->decoder.decode_count_bit = 9; - instance->decoder.decode_data &= ~CHAMBERLAIN_9_CODE_MASK; - instance->decoder.decode_data >>= 4; - } else { - return false; - } - return subghz_protocol_chamb_code_to_bit( - &instance->decoder.decode_data, instance->decoder.decode_count_bit); -} - -void subghz_protocol_decoder_chamb_code_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderChamb_Code* instance = context; - switch(instance->decoder.parser_step) { - case Chamb_CodeDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_chamb_code_const.te_short * 39) < - subghz_protocol_chamb_code_const.te_delta * 20)) { - //Found header Chamb_Code - instance->decoder.parser_step = Chamb_CodeDecoderStepFoundStartBit; - } - break; - case Chamb_CodeDecoderStepFoundStartBit: - if((level) && (DURATION_DIFF(duration, subghz_protocol_chamb_code_const.te_short) < - subghz_protocol_chamb_code_const.te_delta)) { - //Found start bit Chamb_Code - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->decoder.decode_data = instance->decoder.decode_data << 4 | - CHAMBERLAIN_CODE_BIT_STOP; - instance->decoder.decode_count_bit++; - instance->decoder.parser_step = Chamb_CodeDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = Chamb_CodeDecoderStepReset; - } - break; - case Chamb_CodeDecoderStepSaveDuration: - if(!level) { //save interval - if(duration > subghz_protocol_chamb_code_const.te_short * 5) { - if(instance->decoder.decode_count_bit >= - subghz_protocol_chamb_code_const.min_count_bit_for_found) { - instance->generic.serial = 0x0; - instance->generic.btn = 0x0; - if(subghz_protocol_decoder_chamb_code_check_mask_and_parse(instance)) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - } - instance->decoder.parser_step = Chamb_CodeDecoderStepReset; - } else { - instance->decoder.te_last = duration; - instance->decoder.parser_step = Chamb_CodeDecoderStepCheckDuration; - } - } else { - instance->decoder.parser_step = Chamb_CodeDecoderStepReset; - } - break; - case Chamb_CodeDecoderStepCheckDuration: - if(level) { - if((DURATION_DIFF( //Found stop bit Chamb_Code - instance->decoder.te_last, - subghz_protocol_chamb_code_const.te_short * 3) < - subghz_protocol_chamb_code_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_chamb_code_const.te_short) < - subghz_protocol_chamb_code_const.te_delta)) { - instance->decoder.decode_data = instance->decoder.decode_data << 4 | - CHAMBERLAIN_CODE_BIT_STOP; - instance->decoder.decode_count_bit++; - instance->decoder.parser_step = Chamb_CodeDecoderStepSaveDuration; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_chamb_code_const.te_short * 2) < - subghz_protocol_chamb_code_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_chamb_code_const.te_short * 2) < - subghz_protocol_chamb_code_const.te_delta)) { - instance->decoder.decode_data = instance->decoder.decode_data << 4 | - CHAMBERLAIN_CODE_BIT_1; - instance->decoder.decode_count_bit++; - instance->decoder.parser_step = Chamb_CodeDecoderStepSaveDuration; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_chamb_code_const.te_short) < - subghz_protocol_chamb_code_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_chamb_code_const.te_short * 3) < - subghz_protocol_chamb_code_const.te_delta)) { - instance->decoder.decode_data = instance->decoder.decode_data << 4 | - CHAMBERLAIN_CODE_BIT_0; - instance->decoder.decode_count_bit++; - instance->decoder.parser_step = Chamb_CodeDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = Chamb_CodeDecoderStepReset; - } - - } else { - instance->decoder.parser_step = Chamb_CodeDecoderStepReset; - } - break; - } -} - -uint8_t subghz_protocol_decoder_chamb_code_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderChamb_Code* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_chamb_code_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderChamb_Code* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_chamb_code_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderChamb_Code* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit > - subghz_protocol_chamb_code_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_chamb_code_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderChamb_Code* instance = context; - - uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; - - uint64_t code_found_reverse = subghz_protocol_blocks_reverse_key( - instance->generic.data, instance->generic.data_count_bit); - - uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - - furi_string_cat_printf( - output, - "%s %db\r\n" - "Key:0x%03lX\r\n" - "Yek:0x%03lX\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - code_found_lo, - code_found_reverse_lo); - - switch(instance->generic.data_count_bit) { - case 7: - furi_string_cat_printf( - output, - "DIP:" CHAMBERLAIN_7_CODE_DIP_PATTERN "\r\n", - CHAMBERLAIN_7_CODE_DATA_TO_DIP(code_found_lo)); - break; - case 8: - furi_string_cat_printf( - output, - "DIP:" CHAMBERLAIN_8_CODE_DIP_PATTERN "\r\n", - CHAMBERLAIN_8_CODE_DATA_TO_DIP(code_found_lo)); - break; - case 9: - furi_string_cat_printf( - output, - "DIP:" CHAMBERLAIN_9_CODE_DIP_PATTERN "\r\n", - CHAMBERLAIN_9_CODE_DATA_TO_DIP(code_found_lo)); - break; - - default: - break; - } -} diff --git a/applications/main/subghz/protocols/chamberlain_code.h b/applications/main/subghz/protocols/chamberlain_code.h deleted file mode 100644 index f87b64d90..000000000 --- a/applications/main/subghz/protocols/chamberlain_code.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_CHAMB_CODE_NAME "Cham_Code" - -typedef struct SubGhzProtocolDecoderChamb_Code SubGhzProtocolDecoderChamb_Code; -typedef struct SubGhzProtocolEncoderChamb_Code SubGhzProtocolEncoderChamb_Code; - -extern const SubGhzProtocolDecoder subghz_protocol_chamb_code_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_chamb_code_encoder; -extern const SubGhzProtocol subghz_protocol_chamb_code; - -/** - * Allocate SubGhzProtocolEncoderChamb_Code. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderChamb_Code* pointer to a SubGhzProtocolEncoderChamb_Code instance - */ -void* subghz_protocol_encoder_chamb_code_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderChamb_Code. - * @param context Pointer to a SubGhzProtocolEncoderChamb_Code instance - */ -void subghz_protocol_encoder_chamb_code_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderChamb_Code instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_chamb_code_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderChamb_Code instance - */ -void subghz_protocol_encoder_chamb_code_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderChamb_Code instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_chamb_code_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderChamb_Code. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderChamb_Code* pointer to a SubGhzProtocolDecoderChamb_Code instance - */ -void* subghz_protocol_decoder_chamb_code_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderChamb_Code. - * @param context Pointer to a SubGhzProtocolDecoderChamb_Code instance - */ -void subghz_protocol_decoder_chamb_code_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderChamb_Code. - * @param context Pointer to a SubGhzProtocolDecoderChamb_Code instance - */ -void subghz_protocol_decoder_chamb_code_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderChamb_Code instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_chamb_code_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderChamb_Code instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_chamb_code_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderChamb_Code. - * @param context Pointer to a SubGhzProtocolDecoderChamb_Code instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_chamb_code_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderChamb_Code. - * @param context Pointer to a SubGhzProtocolDecoderChamb_Code instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_chamb_code_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderChamb_Code instance - * @param output Resulting text - */ -void subghz_protocol_decoder_chamb_code_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/clemsa.c b/applications/main/subghz/protocols/clemsa.c deleted file mode 100644 index a2cb7a18b..000000000 --- a/applications/main/subghz/protocols/clemsa.c +++ /dev/null @@ -1,365 +0,0 @@ -#include "clemsa.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -// protocol BERNER / ELKA / TEDSEN / TELETASTER -#define TAG "SubGhzProtocolClemsa" - -#define DIP_P 0b11 //(+) -#define DIP_O 0b10 //(0) -#define DIP_N 0b00 //(-) - -#define DIP_PATTERN "%c%c%c%c%c%c%c%c" -#define SHOW_DIP_P(dip, check_dip) \ - ((((dip >> 0xE) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0xC) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0xA) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0x8) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0x6) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0x4) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0x2) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0x0) & 0x3) == check_dip) ? '*' : '_') - -static const SubGhzBlockConst subghz_protocol_clemsa_const = { - .te_short = 385, - .te_long = 2695, - .te_delta = 150, - .min_count_bit_for_found = 18, -}; - -struct SubGhzProtocolDecoderClemsa { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; -}; - -struct SubGhzProtocolEncoderClemsa { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - ClemsaDecoderStepReset = 0, - ClemsaDecoderStepSaveDuration, - ClemsaDecoderStepCheckDuration, -} ClemsaDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_clemsa_decoder = { - .alloc = subghz_protocol_decoder_clemsa_alloc, - .free = subghz_protocol_decoder_clemsa_free, - - .feed = subghz_protocol_decoder_clemsa_feed, - .reset = subghz_protocol_decoder_clemsa_reset, - - .get_hash_data = subghz_protocol_decoder_clemsa_get_hash_data, - .serialize = subghz_protocol_decoder_clemsa_serialize, - .deserialize = subghz_protocol_decoder_clemsa_deserialize, - .get_string = subghz_protocol_decoder_clemsa_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_clemsa_encoder = { - .alloc = subghz_protocol_encoder_clemsa_alloc, - .free = subghz_protocol_encoder_clemsa_free, - - .deserialize = subghz_protocol_encoder_clemsa_deserialize, - .stop = subghz_protocol_encoder_clemsa_stop, - .yield = subghz_protocol_encoder_clemsa_yield, -}; - -const SubGhzProtocol subghz_protocol_clemsa = { - .name = SUBGHZ_PROTOCOL_CLEMSA_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_clemsa_decoder, - .encoder = &subghz_protocol_clemsa_encoder, -}; - -void* subghz_protocol_encoder_clemsa_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderClemsa* instance = malloc(sizeof(SubGhzProtocolEncoderClemsa)); - - instance->base.protocol = &subghz_protocol_clemsa; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 52; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_clemsa_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderClemsa* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderClemsa instance - * @return true On success - */ -static bool subghz_protocol_encoder_clemsa_get_upload(SubGhzProtocolEncoderClemsa* instance) { - furi_assert(instance); - size_t index = 0; - size_t size_upload = (instance->generic.data_count_bit * 2); - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - - for(uint8_t i = instance->generic.data_count_bit; i > 1; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_clemsa_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_clemsa_const.te_short); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_clemsa_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_clemsa_const.te_long); - } - } - if(bit_read(instance->generic.data, 0)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_clemsa_const.te_long); - instance->encoder.upload[index++] = level_duration_make( - false, - (uint32_t)subghz_protocol_clemsa_const.te_short + - subghz_protocol_clemsa_const.te_long * 7); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_clemsa_const.te_short); - instance->encoder.upload[index++] = level_duration_make( - false, - (uint32_t)subghz_protocol_clemsa_const.te_long + - subghz_protocol_clemsa_const.te_long * 7); - } - return true; -} - -bool subghz_protocol_encoder_clemsa_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderClemsa* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_clemsa_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_clemsa_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_clemsa_stop(void* context) { - SubGhzProtocolEncoderClemsa* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_clemsa_yield(void* context) { - SubGhzProtocolEncoderClemsa* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_clemsa_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderClemsa* instance = malloc(sizeof(SubGhzProtocolDecoderClemsa)); - instance->base.protocol = &subghz_protocol_clemsa; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_clemsa_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderClemsa* instance = context; - free(instance); -} - -void subghz_protocol_decoder_clemsa_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderClemsa* instance = context; - instance->decoder.parser_step = ClemsaDecoderStepReset; -} - -void subghz_protocol_decoder_clemsa_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderClemsa* instance = context; - - switch(instance->decoder.parser_step) { - case ClemsaDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_clemsa_const.te_short * 51) < - subghz_protocol_clemsa_const.te_delta * 25)) { - instance->decoder.parser_step = ClemsaDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } - break; - - case ClemsaDecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = ClemsaDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = ClemsaDecoderStepReset; - } - break; - - case ClemsaDecoderStepCheckDuration: - if(!level) { - if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_clemsa_const.te_short) < - subghz_protocol_clemsa_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_clemsa_const.te_long) < - subghz_protocol_clemsa_const.te_delta * 3)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = ClemsaDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_clemsa_const.te_long) < - subghz_protocol_clemsa_const.te_delta * 3) && - (DURATION_DIFF(duration, subghz_protocol_clemsa_const.te_short) < - subghz_protocol_clemsa_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = ClemsaDecoderStepSaveDuration; - } else if( - DURATION_DIFF(duration, subghz_protocol_clemsa_const.te_short * 51) < - subghz_protocol_clemsa_const.te_delta * 25) { - if((DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_clemsa_const.te_short) < - subghz_protocol_clemsa_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - } else if((DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_clemsa_const.te_long) < - subghz_protocol_clemsa_const.te_delta * 3)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - } else { - instance->decoder.parser_step = ClemsaDecoderStepReset; - } - - if(instance->decoder.decode_count_bit == - subghz_protocol_clemsa_const.min_count_bit_for_found) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.parser_step = ClemsaDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - - } else { - instance->decoder.parser_step = ClemsaDecoderStepReset; - } - } else { - instance->decoder.parser_step = ClemsaDecoderStepReset; - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - */ -static void subghz_protocol_clemsa_check_remote_controller(SubGhzBlockGeneric* instance) { - instance->serial = (instance->data >> 2) & 0xFFFF; - instance->btn = (instance->data & 0x03); -} - -uint8_t subghz_protocol_decoder_clemsa_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderClemsa* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_clemsa_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderClemsa* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_clemsa_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderClemsa* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_clemsa_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_clemsa_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderClemsa* instance = context; - subghz_protocol_clemsa_check_remote_controller(&instance->generic); - //uint32_t data = (uint32_t)(instance->generic.data & 0xFFFFFF); - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:%05lX Btn %X\r\n" - " +: " DIP_PATTERN "\r\n" - " o: " DIP_PATTERN "\r\n" - " -: " DIP_PATTERN "\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data & 0x3FFFF), - instance->generic.btn, - SHOW_DIP_P(instance->generic.serial, DIP_P), - SHOW_DIP_P(instance->generic.serial, DIP_O), - SHOW_DIP_P(instance->generic.serial, DIP_N)); -} diff --git a/applications/main/subghz/protocols/clemsa.h b/applications/main/subghz/protocols/clemsa.h deleted file mode 100644 index 8858c1a3b..000000000 --- a/applications/main/subghz/protocols/clemsa.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_CLEMSA_NAME "Clemsa" - -typedef struct SubGhzProtocolDecoderClemsa SubGhzProtocolDecoderClemsa; -typedef struct SubGhzProtocolEncoderClemsa SubGhzProtocolEncoderClemsa; - -extern const SubGhzProtocolDecoder subghz_protocol_clemsa_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_clemsa_encoder; -extern const SubGhzProtocol subghz_protocol_clemsa; - -/** - * Allocate SubGhzProtocolEncoderClemsa. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderClemsa* pointer to a SubGhzProtocolEncoderClemsa instance - */ -void* subghz_protocol_encoder_clemsa_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderClemsa. - * @param context Pointer to a SubGhzProtocolEncoderClemsa instance - */ -void subghz_protocol_encoder_clemsa_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderClemsa instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_clemsa_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderClemsa instance - */ -void subghz_protocol_encoder_clemsa_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderClemsa instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_clemsa_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderClemsa. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderClemsa* pointer to a SubGhzProtocolDecoderClemsa instance - */ -void* subghz_protocol_decoder_clemsa_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderClemsa. - * @param context Pointer to a SubGhzProtocolDecoderClemsa instance - */ -void subghz_protocol_decoder_clemsa_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderClemsa. - * @param context Pointer to a SubGhzProtocolDecoderClemsa instance - */ -void subghz_protocol_decoder_clemsa_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderClemsa instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_clemsa_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderClemsa instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_clemsa_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderClemsa. - * @param context Pointer to a SubGhzProtocolDecoderClemsa instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_clemsa_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderClemsa. - * @param context Pointer to a SubGhzProtocolDecoderClemsa instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_clemsa_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderClemsa instance - * @param output Resulting text - */ -void subghz_protocol_decoder_clemsa_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/doitrand.c b/applications/main/subghz/protocols/doitrand.c deleted file mode 100644 index 6b31d4f27..000000000 --- a/applications/main/subghz/protocols/doitrand.c +++ /dev/null @@ -1,356 +0,0 @@ -#include "doitrand.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolDoitrand" - -#define DIP_PATTERN "%c%c%c%c%c%c%c%c%c%c" -#define CNT_TO_DIP(dip) \ - (dip & 0x0001 ? '1' : '0'), (dip & 0x0100 ? '1' : '0'), (dip & 0x0080 ? '1' : '0'), \ - (dip & 0x0040 ? '1' : '0'), (dip & 0x0020 ? '1' : '0'), (dip & 0x1000 ? '1' : '0'), \ - (dip & 0x0800 ? '1' : '0'), (dip & 0x0400 ? '1' : '0'), (dip & 0x0200 ? '1' : '0'), \ - (dip & 0x0002 ? '1' : '0') - -static const SubGhzBlockConst subghz_protocol_doitrand_const = { - .te_short = 400, - .te_long = 1100, - .te_delta = 150, - .min_count_bit_for_found = 37, -}; - -struct SubGhzProtocolDecoderDoitrand { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; -}; - -struct SubGhzProtocolEncoderDoitrand { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - DoitrandDecoderStepReset = 0, - DoitrandDecoderStepFoundStartBit, - DoitrandDecoderStepSaveDuration, - DoitrandDecoderStepCheckDuration, -} DoitrandDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_doitrand_decoder = { - .alloc = subghz_protocol_decoder_doitrand_alloc, - .free = subghz_protocol_decoder_doitrand_free, - - .feed = subghz_protocol_decoder_doitrand_feed, - .reset = subghz_protocol_decoder_doitrand_reset, - - .get_hash_data = subghz_protocol_decoder_doitrand_get_hash_data, - .serialize = subghz_protocol_decoder_doitrand_serialize, - .deserialize = subghz_protocol_decoder_doitrand_deserialize, - .get_string = subghz_protocol_decoder_doitrand_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_doitrand_encoder = { - .alloc = subghz_protocol_encoder_doitrand_alloc, - .free = subghz_protocol_encoder_doitrand_free, - - .deserialize = subghz_protocol_encoder_doitrand_deserialize, - .stop = subghz_protocol_encoder_doitrand_stop, - .yield = subghz_protocol_encoder_doitrand_yield, -}; - -const SubGhzProtocol subghz_protocol_doitrand = { - .name = SUBGHZ_PROTOCOL_DOITRAND_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_doitrand_decoder, - .encoder = &subghz_protocol_doitrand_encoder, -}; - -void* subghz_protocol_encoder_doitrand_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderDoitrand* instance = malloc(sizeof(SubGhzProtocolEncoderDoitrand)); - - instance->base.protocol = &subghz_protocol_doitrand; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 128; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_doitrand_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderDoitrand* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderDoitrand instance - * @return true On success - */ -static bool subghz_protocol_encoder_doitrand_get_upload(SubGhzProtocolEncoderDoitrand* instance) { - furi_assert(instance); - size_t index = 0; - size_t size_upload = (instance->generic.data_count_bit * 2) + 2; - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - //Send header - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_doitrand_const.te_short * 62); - //Send start bit - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_doitrand_const.te_short * 2 - 100); - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_doitrand_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_doitrand_const.te_short); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_doitrand_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_doitrand_const.te_long); - } - } - return true; -} - -bool subghz_protocol_encoder_doitrand_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderDoitrand* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_doitrand_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_doitrand_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_doitrand_stop(void* context) { - SubGhzProtocolEncoderDoitrand* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_doitrand_yield(void* context) { - SubGhzProtocolEncoderDoitrand* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_doitrand_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderDoitrand* instance = malloc(sizeof(SubGhzProtocolDecoderDoitrand)); - instance->base.protocol = &subghz_protocol_doitrand; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_doitrand_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderDoitrand* instance = context; - free(instance); -} - -void subghz_protocol_decoder_doitrand_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderDoitrand* instance = context; - instance->decoder.parser_step = DoitrandDecoderStepReset; -} - -void subghz_protocol_decoder_doitrand_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderDoitrand* instance = context; - - switch(instance->decoder.parser_step) { - case DoitrandDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_doitrand_const.te_short * 62) < - subghz_protocol_doitrand_const.te_delta * 30)) { - //Found Preambula - instance->decoder.parser_step = DoitrandDecoderStepFoundStartBit; - } - break; - case DoitrandDecoderStepFoundStartBit: - if(level && ((DURATION_DIFF(duration, (subghz_protocol_doitrand_const.te_short * 2)) < - subghz_protocol_doitrand_const.te_delta * 3))) { - //Found start bit - instance->decoder.parser_step = DoitrandDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else { - instance->decoder.parser_step = DoitrandDecoderStepReset; - } - break; - case DoitrandDecoderStepSaveDuration: - if(!level) { - if(duration >= ((uint32_t)subghz_protocol_doitrand_const.te_short * 10 + - subghz_protocol_doitrand_const.te_delta)) { - instance->decoder.parser_step = DoitrandDecoderStepFoundStartBit; - if(instance->decoder.decode_count_bit == - subghz_protocol_doitrand_const.min_count_bit_for_found) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - break; - } else { - instance->decoder.te_last = duration; - instance->decoder.parser_step = DoitrandDecoderStepCheckDuration; - } - } - break; - case DoitrandDecoderStepCheckDuration: - if(level) { - if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_doitrand_const.te_short) < - subghz_protocol_doitrand_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_doitrand_const.te_long) < - subghz_protocol_doitrand_const.te_delta * 3)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = DoitrandDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_doitrand_const.te_long) < - subghz_protocol_doitrand_const.te_delta * 3) && - (DURATION_DIFF(duration, subghz_protocol_doitrand_const.te_short) < - subghz_protocol_doitrand_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = DoitrandDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = DoitrandDecoderStepReset; - } - } else { - instance->decoder.parser_step = DoitrandDecoderStepReset; - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - */ -static void subghz_protocol_doitrand_check_remote_controller(SubGhzBlockGeneric* instance) { - /* -* 67892345 0 k 1 -* 0000082F5F => 00000000000000000 10 000010111101011111 -* 0002082F5F => 00000000000100000 10 000010111101011111 -* 0200082F5F => 00010000000000000 10 000010111101011111 -* 0400082F5F => 00100000000000000 10 000010111101011111 -* 0800082F5F => 01000000000000000 10 000010111101011111 -* 1000082F5F => 10000000000000000 10 000010111101011111 -* 0020082F5F => 00000001000000000 10 000010111101011111 -* 0040082F5F => 00000010000000000 10 000010111101011111 -* 0080082F5F => 00000100000000000 10 000010111101011111 -* 0100082F5F => 00001000000000000 10 000010111101011111 -* 000008AF5F => 00000000000000000 10 001010111101011111 -* 1FE208AF5F => 11111111000100000 10 001010111101011111 -* -* 0...9 - DIP -* k- KEY -*/ - instance->cnt = (instance->data >> 24) | ((instance->data >> 15) & 0x1); - instance->btn = ((instance->data >> 18) & 0x3); -} - -uint8_t subghz_protocol_decoder_doitrand_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderDoitrand* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_doitrand_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderDoitrand* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_doitrand_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderDoitrand* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_doitrand_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_doitrand_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderDoitrand* instance = context; - subghz_protocol_doitrand_check_remote_controller(&instance->generic); - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:%02lX%08lX\r\n" - "Btn:%X\r\n" - "DIP:" DIP_PATTERN "\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32) & 0xFFFFFFFF, - (uint32_t)(instance->generic.data & 0xFFFFFFFF), - instance->generic.btn, - CNT_TO_DIP(instance->generic.cnt)); -} diff --git a/applications/main/subghz/protocols/doitrand.h b/applications/main/subghz/protocols/doitrand.h deleted file mode 100644 index 30f1fffd0..000000000 --- a/applications/main/subghz/protocols/doitrand.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_DOITRAND_NAME "Doitrand" - -typedef struct SubGhzProtocolDecoderDoitrand SubGhzProtocolDecoderDoitrand; -typedef struct SubGhzProtocolEncoderDoitrand SubGhzProtocolEncoderDoitrand; - -extern const SubGhzProtocolDecoder subghz_protocol_doitrand_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_doitrand_encoder; -extern const SubGhzProtocol subghz_protocol_doitrand; - -/** - * Allocate SubGhzProtocolEncoderDoitrand. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderDoitrand* pointer to a SubGhzProtocolEncoderDoitrand instance - */ -void* subghz_protocol_encoder_doitrand_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderDoitrand. - * @param context Pointer to a SubGhzProtocolEncoderDoitrand instance - */ -void subghz_protocol_encoder_doitrand_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderDoitrand instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_doitrand_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderDoitrand instance - */ -void subghz_protocol_encoder_doitrand_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderDoitrand instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_doitrand_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderDoitrand. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderDoitrand* pointer to a SubGhzProtocolDecoderDoitrand instance - */ -void* subghz_protocol_decoder_doitrand_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderDoitrand. - * @param context Pointer to a SubGhzProtocolDecoderDoitrand instance - */ -void subghz_protocol_decoder_doitrand_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderDoitrand. - * @param context Pointer to a SubGhzProtocolDecoderDoitrand instance - */ -void subghz_protocol_decoder_doitrand_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderDoitrand instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_doitrand_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderDoitrand instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_doitrand_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderDoitrand. - * @param context Pointer to a SubGhzProtocolDecoderDoitrand instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_doitrand_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderDoitrand. - * @param context Pointer to a SubGhzProtocolDecoderDoitrand instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_doitrand_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderDoitrand instance - * @param output Resulting text - */ -void subghz_protocol_decoder_doitrand_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/dooya.c b/applications/main/subghz/protocols/dooya.c deleted file mode 100644 index c70b6d54e..000000000 --- a/applications/main/subghz/protocols/dooya.c +++ /dev/null @@ -1,447 +0,0 @@ -#include "dooya.h" -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolDooya" - -#define DOYA_SINGLE_CHANNEL 0xFF - -static const SubGhzBlockConst subghz_protocol_dooya_const = { - .te_short = 366, - .te_long = 733, - .te_delta = 120, - .min_count_bit_for_found = 40, -}; - -struct SubGhzProtocolDecoderDooya { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; -}; - -struct SubGhzProtocolEncoderDooya { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - DooyaDecoderStepReset = 0, - DooyaDecoderStepFoundStartBit, - DooyaDecoderStepSaveDuration, - DooyaDecoderStepCheckDuration, -} DooyaDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_dooya_decoder = { - .alloc = subghz_protocol_decoder_dooya_alloc, - .free = subghz_protocol_decoder_dooya_free, - - .feed = subghz_protocol_decoder_dooya_feed, - .reset = subghz_protocol_decoder_dooya_reset, - - .get_hash_data = subghz_protocol_decoder_dooya_get_hash_data, - .serialize = subghz_protocol_decoder_dooya_serialize, - .deserialize = subghz_protocol_decoder_dooya_deserialize, - .get_string = subghz_protocol_decoder_dooya_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_dooya_encoder = { - .alloc = subghz_protocol_encoder_dooya_alloc, - .free = subghz_protocol_encoder_dooya_free, - - .deserialize = subghz_protocol_encoder_dooya_deserialize, - .stop = subghz_protocol_encoder_dooya_stop, - .yield = subghz_protocol_encoder_dooya_yield, -}; - -const SubGhzProtocol subghz_protocol_dooya = { - .name = SUBGHZ_PROTOCOL_DOOYA_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_AM | - SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | - SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_dooya_decoder, - .encoder = &subghz_protocol_dooya_encoder, -}; - -void* subghz_protocol_encoder_dooya_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderDooya* instance = malloc(sizeof(SubGhzProtocolEncoderDooya)); - - instance->base.protocol = &subghz_protocol_dooya; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 128; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_dooya_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderDooya* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderDooya instance - * @return true On success - */ -static bool subghz_protocol_encoder_dooya_get_upload(SubGhzProtocolEncoderDooya* instance) { - furi_assert(instance); - - size_t index = 0; - size_t size_upload = (instance->generic.data_count_bit * 2) + 2; - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - - //Send header - if(bit_read(instance->generic.data, 0)) { - instance->encoder.upload[index++] = level_duration_make( - false, - (uint32_t)subghz_protocol_dooya_const.te_long * 12 + - subghz_protocol_dooya_const.te_long); - } else { - instance->encoder.upload[index++] = level_duration_make( - false, - (uint32_t)subghz_protocol_dooya_const.te_long * 12 + - subghz_protocol_dooya_const.te_short); - } - - //Send start bit - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_dooya_const.te_short * 13); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_dooya_const.te_long * 2); - - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_dooya_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_dooya_const.te_short); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_dooya_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_dooya_const.te_long); - } - } - return true; -} - -bool subghz_protocol_encoder_dooya_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderDooya* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_dooya_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_dooya_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_dooya_stop(void* context) { - SubGhzProtocolEncoderDooya* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_dooya_yield(void* context) { - SubGhzProtocolEncoderDooya* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_dooya_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderDooya* instance = malloc(sizeof(SubGhzProtocolDecoderDooya)); - instance->base.protocol = &subghz_protocol_dooya; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_dooya_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderDooya* instance = context; - free(instance); -} - -void subghz_protocol_decoder_dooya_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderDooya* instance = context; - instance->decoder.parser_step = DooyaDecoderStepReset; -} - -void subghz_protocol_decoder_dooya_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderDooya* instance = context; - - switch(instance->decoder.parser_step) { - case DooyaDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_dooya_const.te_long * 12) < - subghz_protocol_dooya_const.te_delta * 20)) { - instance->decoder.parser_step = DooyaDecoderStepFoundStartBit; - } - break; - - case DooyaDecoderStepFoundStartBit: - if(!level) { - if(DURATION_DIFF(duration, subghz_protocol_dooya_const.te_long * 2) < - subghz_protocol_dooya_const.te_delta * 3) { - instance->decoder.parser_step = DooyaDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else { - instance->decoder.parser_step = DooyaDecoderStepReset; - } - } else if( - DURATION_DIFF(duration, subghz_protocol_dooya_const.te_short * 13) < - subghz_protocol_dooya_const.te_delta * 5) { - break; - } else { - instance->decoder.parser_step = DooyaDecoderStepReset; - } - break; - - case DooyaDecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = DooyaDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = DooyaDecoderStepReset; - } - break; - - case DooyaDecoderStepCheckDuration: - if(!level) { - if(duration >= (subghz_protocol_dooya_const.te_long * 4)) { - //add last bit - if(DURATION_DIFF(instance->decoder.te_last, subghz_protocol_dooya_const.te_short) < - subghz_protocol_dooya_const.te_delta) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - } else if( - DURATION_DIFF(instance->decoder.te_last, subghz_protocol_dooya_const.te_long) < - subghz_protocol_dooya_const.te_delta * 2) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - } else { - instance->decoder.parser_step = DooyaDecoderStepReset; - break; - } - instance->decoder.parser_step = DooyaDecoderStepFoundStartBit; - if(instance->decoder.decode_count_bit == - subghz_protocol_dooya_const.min_count_bit_for_found) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - break; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_dooya_const.te_short) < - subghz_protocol_dooya_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_dooya_const.te_long) < - subghz_protocol_dooya_const.te_delta * 2)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = DooyaDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_dooya_const.te_long) < - subghz_protocol_dooya_const.te_delta * 2) && - (DURATION_DIFF(duration, subghz_protocol_dooya_const.te_short) < - subghz_protocol_dooya_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = DooyaDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = DooyaDecoderStepReset; - } - } else { - instance->decoder.parser_step = DooyaDecoderStepReset; - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - */ -static void subghz_protocol_somfy_telis_check_remote_controller(SubGhzBlockGeneric* instance) { - /* - * serial s/m ch key - * long press down X * E1DC030533, 40b 111000011101110000000011 0000 0101 0011 0011 - * - * short press down 3 * E1DC030533, 40b 111000011101110000000011 0000 0101 0011 0011 - * 3 * E1DC03053C, 40b 111000011101110000000011 0000 0101 0011 1100 - * - * press stop X * E1DC030555, 40b 111000011101110000000011 0000 0101 0101 0101 - * - * long press up X * E1DC030511, 40b 111000011101110000000011 0000 0101 0001 0001 - * - * short press up 3 * E1DC030511, 40b 111000011101110000000011 0000 0101 0001 0001 - * 3 * E1DC03051E, 40b 111000011101110000000011 0000 0101 0001 1110 - * - * serial: 3 byte serial number - * s/m: single (b0000) / multi (b0001) channel console - * ch: channel if single (always b0101) or multi - * key: 0b00010001 - long press up - * 0b00011110 - short press up - * 0b00110011 - long press down - * 0b00111100 - short press down - * 0b01010101 - press stop - * 0b01111001 - press up + down - * 0b10000000 - press up + stop - * 0b10000001 - press down + stop - * 0b11001100 - press P2 - * -*/ - - instance->serial = (instance->data >> 16); - if((instance->data >> 12) & 0x0F) { - instance->cnt = (instance->data >> 8) & 0x0F; - } else { - instance->cnt = DOYA_SINGLE_CHANNEL; - } - instance->btn = instance->data & 0xFF; -} - -uint8_t subghz_protocol_decoder_dooya_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderDooya* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_dooya_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderDooya* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_dooya_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderDooya* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_dooya_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -/** - * Get button name. - * @param btn Button number, 8 bit - */ -static const char* subghz_protocol_dooya_get_name_button(uint8_t btn) { - const char* btn_name; - switch(btn) { - case 0b00010001: - btn_name = "Up_Long"; - break; - case 0b00011110: - btn_name = "Up_Short"; - break; - case 0b00110011: - btn_name = "Down_Long"; - break; - case 0b00111100: - btn_name = "Down_Short"; - break; - case 0b01010101: - btn_name = "Stop"; - break; - case 0b01111001: - btn_name = "Up+Down"; - break; - case 0b10000000: - btn_name = "Up+Stop"; - break; - case 0b10000001: - btn_name = "Down+Stop"; - break; - case 0b11001100: - btn_name = "P2"; - break; - default: - btn_name = "Unknown"; - break; - } - return btn_name; -} - -void subghz_protocol_decoder_dooya_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderDooya* instance = context; - - subghz_protocol_somfy_telis_check_remote_controller(&instance->generic); - - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:0x%010llX\r\n" - "Sn:0x%08lX\r\n" - "Btn:%s\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - instance->generic.data, - instance->generic.serial, - subghz_protocol_dooya_get_name_button(instance->generic.btn)); - if(instance->generic.cnt == DOYA_SINGLE_CHANNEL) { - furi_string_cat_printf(output, "Ch:Single\r\n"); - } else { - furi_string_cat_printf(output, "Ch:%lu\r\n", instance->generic.cnt); - } -} diff --git a/applications/main/subghz/protocols/dooya.h b/applications/main/subghz/protocols/dooya.h deleted file mode 100644 index f0cf843c0..000000000 --- a/applications/main/subghz/protocols/dooya.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_DOOYA_NAME "Dooya" - -typedef struct SubGhzProtocolDecoderDooya SubGhzProtocolDecoderDooya; -typedef struct SubGhzProtocolEncoderDooya SubGhzProtocolEncoderDooya; - -extern const SubGhzProtocolDecoder subghz_protocol_dooya_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_dooya_encoder; -extern const SubGhzProtocol subghz_protocol_dooya; - -/** - * Allocate SubGhzProtocolEncoderDooya. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderDooya* pointer to a SubGhzProtocolEncoderDooya instance - */ -void* subghz_protocol_encoder_dooya_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderDooya. - * @param context Pointer to a SubGhzProtocolEncoderDooya instance - */ -void subghz_protocol_encoder_dooya_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderDooya instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_dooya_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderDooya instance - */ -void subghz_protocol_encoder_dooya_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderDooya instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_dooya_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderDooya. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderDooya* pointer to a SubGhzProtocolDecoderDooya instance - */ -void* subghz_protocol_decoder_dooya_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderDooya. - * @param context Pointer to a SubGhzProtocolDecoderDooya instance - */ -void subghz_protocol_decoder_dooya_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderDooya. - * @param context Pointer to a SubGhzProtocolDecoderDooya instance - */ -void subghz_protocol_decoder_dooya_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderDooya instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_dooya_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderDooya instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_dooya_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderDooya. - * @param context Pointer to a SubGhzProtocolDecoderDooya instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_dooya_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderDooya. - * @param context Pointer to a SubGhzProtocolDecoderDooya instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_dooya_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderDooya instance - * @param output Resulting text - */ -void subghz_protocol_decoder_dooya_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/faac_slh.c b/applications/main/subghz/protocols/faac_slh.c deleted file mode 100644 index 7572bd8ab..000000000 --- a/applications/main/subghz/protocols/faac_slh.c +++ /dev/null @@ -1,512 +0,0 @@ -#include "faac_slh.h" -#include "../subghz_keystore.h" -#include -#include "keeloq_common.h" -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolFaacSLH" - -static const SubGhzBlockConst subghz_protocol_faac_slh_const = { - .te_short = 255, - .te_long = 595, - .te_delta = 100, - .min_count_bit_for_found = 64, -}; - -struct SubGhzProtocolDecoderFaacSLH { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - - SubGhzKeystore* keystore; - const char* manufacture_name; -}; - -struct SubGhzProtocolEncoderFaacSLH { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; - - SubGhzKeystore* keystore; - const char* manufacture_name; -}; - -typedef enum { - FaacSLHDecoderStepReset = 0, - FaacSLHDecoderStepFoundPreambula, - FaacSLHDecoderStepSaveDuration, - FaacSLHDecoderStepCheckDuration, -} FaacSLHDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_faac_slh_decoder = { - .alloc = subghz_protocol_decoder_faac_slh_alloc, - .free = subghz_protocol_decoder_faac_slh_free, - - .feed = subghz_protocol_decoder_faac_slh_feed, - .reset = subghz_protocol_decoder_faac_slh_reset, - - .get_hash_data = subghz_protocol_decoder_faac_slh_get_hash_data, - .serialize = subghz_protocol_decoder_faac_slh_serialize, - .deserialize = subghz_protocol_decoder_faac_slh_deserialize, - .get_string = subghz_protocol_decoder_faac_slh_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_faac_slh_encoder = { - .alloc = subghz_protocol_encoder_faac_slh_alloc, - .free = subghz_protocol_encoder_faac_slh_free, - - .deserialize = subghz_protocol_encoder_faac_slh_deserialize, - .stop = subghz_protocol_encoder_faac_slh_stop, - .yield = subghz_protocol_encoder_faac_slh_yield, -}; - -const SubGhzProtocol subghz_protocol_faac_slh = { - .name = SUBGHZ_PROTOCOL_FAAC_SLH_NAME, - .type = SubGhzProtocolTypeDynamic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_868 | SubGhzProtocolFlag_AM | - SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | - SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_faac_slh_decoder, - .encoder = &subghz_protocol_faac_slh_encoder, -}; - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - * @param keystore Pointer to a SubGhzKeystore* instance - * @param manufacture_name - */ -static void subghz_protocol_faac_slh_check_remote_controller( - SubGhzBlockGeneric* instance, - SubGhzKeystore* keystore, - const char** manufacture_name); - -void* subghz_protocol_encoder_faac_slh_alloc(SubGhzEnvironment* environment) { - SubGhzProtocolEncoderFaacSLH* instance = malloc(sizeof(SubGhzProtocolEncoderFaacSLH)); - - instance->base.protocol = &subghz_protocol_faac_slh; - instance->generic.protocol_name = instance->base.protocol->name; - instance->keystore = subghz_environment_get_keystore(environment); - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 256; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_faac_slh_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderFaacSLH* instance = context; - free(instance->encoder.upload); - free(instance); -} - -static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* instance) { - instance->generic.cnt++; - uint32_t fix = instance->generic.serial << 4 | instance->generic.btn; - uint32_t hop = 0; - uint32_t decrypt = 0; - uint64_t man = 0; - int res = 0; - char fixx[8] = {}; - int shiftby = 32; - for(int i = 0; i < 8; i++) { - fixx[i] = (fix >> (shiftby -= 4)) & 0xF; - } - if((instance->generic.cnt % 2) == 0) { - decrypt = fixx[6] << 28 | fixx[7] << 24 | fixx[5] << 20 | - (instance->generic.cnt & 0xFFFFF); - } else { - decrypt = fixx[2] << 28 | fixx[3] << 24 | fixx[4] << 20 | - (instance->generic.cnt & 0xFFFFF); - } - for - M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) { - res = strcmp(furi_string_get_cstr(manufacture_code->name), instance->manufacture_name); - if(res == 0) { - switch(manufacture_code->type) { - case KEELOQ_LEARNING_FAAC: - //FAAC Learning - man = subghz_protocol_keeloq_common_faac_learning( - instance->generic.seed, manufacture_code->key); - hop = subghz_protocol_keeloq_common_encrypt(decrypt, man); - break; - } - break; - } - } - if(hop) { - instance->generic.data = (uint64_t)fix << 32 | hop; - } - return true; -} - -bool subghz_protocol_faac_slh_create_data( - void* context, - FlipperFormat* flipper_format, - uint32_t serial, - uint8_t btn, - uint32_t cnt, - uint32_t seed, - const char* manufacture_name, - SubGhzRadioPreset* preset) { - furi_assert(context); - // roguemaster don't steal!!! - SubGhzProtocolEncoderFaacSLH* instance = context; - instance->generic.serial = serial; - instance->generic.btn = btn; - instance->generic.cnt = (cnt & 0xFFFFF); - instance->generic.seed = seed; - instance->manufacture_name = manufacture_name; - instance->generic.data_count_bit = 64; - bool res = subghz_protocol_faac_slh_gen_data(instance); - if(res) { - res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); - } - return res; -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderFaacSLH instance - * @return true On success - */ -static bool subghz_protocol_encoder_faac_slh_get_upload(SubGhzProtocolEncoderFaacSLH* instance) { - furi_assert(instance); - - subghz_protocol_faac_slh_gen_data(instance); - size_t index = 0; - size_t size_upload = 2 + (instance->generic.data_count_bit * 2); - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - - //Send header - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_faac_slh_const.te_long * 2); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_faac_slh_const.te_long * 2); - - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_faac_slh_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_faac_slh_const.te_short); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_faac_slh_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_faac_slh_const.te_long); - } - } - return true; -} - -bool subghz_protocol_encoder_faac_slh_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderFaacSLH* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - uint8_t seed_data[sizeof(uint32_t)] = {0}; - for(size_t i = 0; i < sizeof(uint32_t); i++) { - seed_data[sizeof(uint32_t) - i - 1] = (instance->generic.seed >> i * 8) & 0xFF; - } - if(!flipper_format_read_hex(flipper_format, "Seed", seed_data, sizeof(uint32_t))) { - FURI_LOG_E(TAG, "Missing Seed"); - break; - } - instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 | - seed_data[3]; - - subghz_protocol_faac_slh_check_remote_controller( - &instance->generic, instance->keystore, &instance->manufacture_name); - - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - subghz_protocol_encoder_faac_slh_get_upload(instance); - - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - uint8_t key_data[sizeof(uint64_t)] = {0}; - for(size_t i = 0; i < sizeof(uint64_t); i++) { - key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data >> i * 8) & 0xFF; - } - if(!flipper_format_update_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Unable to add Key"); - break; - } - - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_faac_slh_stop(void* context) { - SubGhzProtocolEncoderFaacSLH* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_faac_slh_yield(void* context) { - SubGhzProtocolEncoderFaacSLH* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_faac_slh_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderFaacSLH* instance = malloc(sizeof(SubGhzProtocolDecoderFaacSLH)); - instance->base.protocol = &subghz_protocol_faac_slh; - instance->generic.protocol_name = instance->base.protocol->name; - instance->keystore = subghz_environment_get_keystore(environment); - return instance; -} - -void subghz_protocol_decoder_faac_slh_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderFaacSLH* instance = context; - free(instance); -} - -void subghz_protocol_decoder_faac_slh_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderFaacSLH* instance = context; - instance->decoder.parser_step = FaacSLHDecoderStepReset; -} - -void subghz_protocol_decoder_faac_slh_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderFaacSLH* instance = context; - - switch(instance->decoder.parser_step) { - case FaacSLHDecoderStepReset: - if((level) && (DURATION_DIFF(duration, subghz_protocol_faac_slh_const.te_long * 2) < - subghz_protocol_faac_slh_const.te_delta * 3)) { - instance->decoder.parser_step = FaacSLHDecoderStepFoundPreambula; - } - break; - case FaacSLHDecoderStepFoundPreambula: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_faac_slh_const.te_long * 2) < - subghz_protocol_faac_slh_const.te_delta * 3)) { - //Found Preambula - instance->decoder.parser_step = FaacSLHDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else { - instance->decoder.parser_step = FaacSLHDecoderStepReset; - } - break; - case FaacSLHDecoderStepSaveDuration: - if(level) { - if(duration >= ((uint32_t)subghz_protocol_faac_slh_const.te_short * 3 + - subghz_protocol_faac_slh_const.te_delta)) { - instance->decoder.parser_step = FaacSLHDecoderStepFoundPreambula; - if(instance->decoder.decode_count_bit == - subghz_protocol_faac_slh_const.min_count_bit_for_found) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - break; - } else { - instance->decoder.te_last = duration; - instance->decoder.parser_step = FaacSLHDecoderStepCheckDuration; - } - - } else { - instance->decoder.parser_step = FaacSLHDecoderStepReset; - } - break; - case FaacSLHDecoderStepCheckDuration: - if(!level) { - if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_faac_slh_const.te_short) < - subghz_protocol_faac_slh_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_faac_slh_const.te_long) < - subghz_protocol_faac_slh_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = FaacSLHDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_faac_slh_const.te_long) < - subghz_protocol_faac_slh_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_faac_slh_const.te_short) < - subghz_protocol_faac_slh_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = FaacSLHDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = FaacSLHDecoderStepReset; - } - } else { - instance->decoder.parser_step = FaacSLHDecoderStepReset; - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - * @param keystore Pointer to a SubGhzKeystore* instance - * @param manifacture_name Manufacturer name - */ -static void subghz_protocol_faac_slh_check_remote_controller( - SubGhzBlockGeneric* instance, - SubGhzKeystore* keystore, - const char** manufacture_name) { - uint32_t code_fix = instance->data >> 32; - uint32_t code_hop = instance->data & 0xFFFFFFFF; - instance->serial = code_fix >> 4; - instance->btn = code_fix & 0xF; - uint32_t decrypt = 0; - uint64_t man; - - for - M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) { - switch(manufacture_code->type) { - case KEELOQ_LEARNING_FAAC: - // FAAC Learning - man = subghz_protocol_keeloq_common_faac_learning( - instance->seed, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(code_hop, man); - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - break; - } - } - instance->cnt = decrypt & 0xFFFFF; -} - -uint8_t subghz_protocol_decoder_faac_slh_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderFaacSLH* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_faac_slh_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderFaacSLH* instance = context; - - bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); - - uint8_t seed_data[sizeof(uint32_t)] = {0}; - for(size_t i = 0; i < sizeof(uint32_t); i++) { - seed_data[sizeof(uint32_t) - i - 1] = (instance->generic.seed >> i * 8) & 0xFF; - } - if(res && !flipper_format_write_hex(flipper_format, "Seed", seed_data, sizeof(uint32_t))) { - FURI_LOG_E(TAG, "Unable to add Seed"); - res = false; - } - instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 | - seed_data[3]; - - subghz_protocol_faac_slh_check_remote_controller( - &instance->generic, instance->keystore, &instance->manufacture_name); - - return res; -} - -bool subghz_protocol_decoder_faac_slh_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderFaacSLH* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_faac_slh_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - - uint8_t seed_data[sizeof(uint32_t)] = {0}; - for(size_t i = 0; i < sizeof(uint32_t); i++) { - seed_data[sizeof(uint32_t) - i - 1] = (instance->generic.seed >> i * 8) & 0xFF; - } - if(!flipper_format_read_hex(flipper_format, "Seed", seed_data, sizeof(uint32_t))) { - FURI_LOG_E(TAG, "Missing Seed"); - break; - } - instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 | - seed_data[3]; - - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - res = true; - } while(false); - - return res; -} - -void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderFaacSLH* instance = context; - subghz_protocol_faac_slh_check_remote_controller( - &instance->generic, instance->keystore, &instance->manufacture_name); - uint32_t code_fix = instance->generic.data >> 32; - uint32_t code_hop = instance->generic.data & 0xFFFFFFFF; - - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:%lX%08lX\r\n" - "Fix:%08lX Cnt:%05lX\r\n" - "Hop:%08lX Btn:%X\r\n" - "Sn:%07lX Sd:%08lX", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)instance->generic.data, - code_fix, - instance->generic.cnt, - code_hop, - instance->generic.btn, - instance->generic.serial, - instance->generic.seed); -} diff --git a/applications/main/subghz/protocols/faac_slh.h b/applications/main/subghz/protocols/faac_slh.h deleted file mode 100644 index 9390da43a..000000000 --- a/applications/main/subghz/protocols/faac_slh.h +++ /dev/null @@ -1,129 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_FAAC_SLH_NAME "Faac SLH" - -typedef struct SubGhzProtocolDecoderFaacSLH SubGhzProtocolDecoderFaacSLH; -typedef struct SubGhzProtocolEncoderFaacSLH SubGhzProtocolEncoderFaacSLH; - -extern const SubGhzProtocolDecoder subghz_protocol_faac_slh_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_faac_slh_encoder; -extern const SubGhzProtocol subghz_protocol_faac_slh; - -/** - * Allocate SubGhzProtocolEncoderFaacSLH. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderFaacSLH* pointer to a SubGhzProtocolEncoderFaacSLH instance - */ -void* subghz_protocol_encoder_faac_slh_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderFaacSLH. - * @param context Pointer to a SubGhzProtocolEncoderFaacSLH instance - */ -void subghz_protocol_encoder_faac_slh_free(void* context); - -/** - * Key generation from simple data. - * @param context Pointer to a SubGhzProtocolEncoderFaacSLH instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param serial Serial number, 28 bit - * @param btn Button number, 4 bit - * @param cnt Counter value, 16 bit - * @param seed Seed value, 32 bit - * @param manufacture_name Name of manufacturer's key - * @param preset Modulation, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_faac_slh_create_data( - void* context, - FlipperFormat* flipper_format, - uint32_t serial, - uint8_t btn, - uint32_t cnt, - uint32_t seed, - const char* manufacture_name, - SubGhzRadioPreset* preset); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderFaacSLH instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_faac_slh_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderFaacSLH instance - */ -void subghz_protocol_encoder_faac_slh_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderFaacSLH instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_faac_slh_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderFaacSLH. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderFaacSLH* pointer to a SubGhzProtocolDecoderFaacSLH instance - */ -void* subghz_protocol_decoder_faac_slh_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderFaacSLH. - * @param context Pointer to a SubGhzProtocolDecoderFaacSLH instance - */ -void subghz_protocol_decoder_faac_slh_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderFaacSLH. - * @param context Pointer to a SubGhzProtocolDecoderFaacSLH instance - */ -void subghz_protocol_decoder_faac_slh_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderFaacSLH instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_faac_slh_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderFaacSLH instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_faac_slh_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderFaacSLH. - * @param context Pointer to a SubGhzProtocolDecoderFaacSLH instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_faac_slh_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderFaacSLH. - * @param context Pointer to a SubGhzProtocolDecoderFaacSLH instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_faac_slh_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderFaacSLH instance - * @param output Resulting text - */ -void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/gate_tx.c b/applications/main/subghz/protocols/gate_tx.c deleted file mode 100644 index 4c7c2d484..000000000 --- a/applications/main/subghz/protocols/gate_tx.c +++ /dev/null @@ -1,334 +0,0 @@ -#include "gate_tx.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolGateTx" - -static const SubGhzBlockConst subghz_protocol_gate_tx_const = { - .te_short = 350, - .te_long = 700, - .te_delta = 100, - .min_count_bit_for_found = 24, -}; - -struct SubGhzProtocolDecoderGateTx { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; -}; - -struct SubGhzProtocolEncoderGateTx { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - GateTXDecoderStepReset = 0, - GateTXDecoderStepFoundStartBit, - GateTXDecoderStepSaveDuration, - GateTXDecoderStepCheckDuration, -} GateTXDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_gate_tx_decoder = { - .alloc = subghz_protocol_decoder_gate_tx_alloc, - .free = subghz_protocol_decoder_gate_tx_free, - - .feed = subghz_protocol_decoder_gate_tx_feed, - .reset = subghz_protocol_decoder_gate_tx_reset, - - .get_hash_data = subghz_protocol_decoder_gate_tx_get_hash_data, - .serialize = subghz_protocol_decoder_gate_tx_serialize, - .deserialize = subghz_protocol_decoder_gate_tx_deserialize, - .get_string = subghz_protocol_decoder_gate_tx_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_gate_tx_encoder = { - .alloc = subghz_protocol_encoder_gate_tx_alloc, - .free = subghz_protocol_encoder_gate_tx_free, - - .deserialize = subghz_protocol_encoder_gate_tx_deserialize, - .stop = subghz_protocol_encoder_gate_tx_stop, - .yield = subghz_protocol_encoder_gate_tx_yield, -}; - -const SubGhzProtocol subghz_protocol_gate_tx = { - .name = SUBGHZ_PROTOCOL_GATE_TX_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_gate_tx_decoder, - .encoder = &subghz_protocol_gate_tx_encoder, -}; - -void* subghz_protocol_encoder_gate_tx_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderGateTx* instance = malloc(sizeof(SubGhzProtocolEncoderGateTx)); - - instance->base.protocol = &subghz_protocol_gate_tx; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 52; //max 24bit*2 + 2 (start, stop) - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_gate_tx_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderGateTx* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderGateTx instance - * @return true On success - */ -static bool subghz_protocol_encoder_gate_tx_get_upload(SubGhzProtocolEncoderGateTx* instance) { - furi_assert(instance); - size_t index = 0; - size_t size_upload = (instance->generic.data_count_bit * 2) + 2; - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - //Send header - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_gate_tx_const.te_short * 49); - //Send start bit - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_gate_tx_const.te_long); - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_gate_tx_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_gate_tx_const.te_short); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_gate_tx_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_gate_tx_const.te_long); - } - } - return true; -} - -bool subghz_protocol_encoder_gate_tx_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderGateTx* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_gate_tx_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_gate_tx_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_gate_tx_stop(void* context) { - SubGhzProtocolEncoderGateTx* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_gate_tx_yield(void* context) { - SubGhzProtocolEncoderGateTx* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_gate_tx_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderGateTx* instance = malloc(sizeof(SubGhzProtocolDecoderGateTx)); - instance->base.protocol = &subghz_protocol_gate_tx; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_gate_tx_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderGateTx* instance = context; - free(instance); -} - -void subghz_protocol_decoder_gate_tx_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderGateTx* instance = context; - instance->decoder.parser_step = GateTXDecoderStepReset; -} - -void subghz_protocol_decoder_gate_tx_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderGateTx* instance = context; - - switch(instance->decoder.parser_step) { - case GateTXDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_gate_tx_const.te_short * 47) < - subghz_protocol_gate_tx_const.te_delta * 47)) { - //Found Preambula - instance->decoder.parser_step = GateTXDecoderStepFoundStartBit; - } - break; - case GateTXDecoderStepFoundStartBit: - if(level && ((DURATION_DIFF(duration, subghz_protocol_gate_tx_const.te_long) < - subghz_protocol_gate_tx_const.te_delta * 3))) { - //Found start bit - instance->decoder.parser_step = GateTXDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else { - instance->decoder.parser_step = GateTXDecoderStepReset; - } - break; - case GateTXDecoderStepSaveDuration: - if(!level) { - if(duration >= ((uint32_t)subghz_protocol_gate_tx_const.te_short * 10 + - subghz_protocol_gate_tx_const.te_delta)) { - instance->decoder.parser_step = GateTXDecoderStepFoundStartBit; - if(instance->decoder.decode_count_bit >= - subghz_protocol_gate_tx_const.min_count_bit_for_found) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - break; - } else { - instance->decoder.te_last = duration; - instance->decoder.parser_step = GateTXDecoderStepCheckDuration; - } - } - break; - case GateTXDecoderStepCheckDuration: - if(level) { - if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_gate_tx_const.te_short) < - subghz_protocol_gate_tx_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_gate_tx_const.te_long) < - subghz_protocol_gate_tx_const.te_delta * 3)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = GateTXDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_gate_tx_const.te_long) < - subghz_protocol_gate_tx_const.te_delta * 3) && - (DURATION_DIFF(duration, subghz_protocol_gate_tx_const.te_short) < - subghz_protocol_gate_tx_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = GateTXDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = GateTXDecoderStepReset; - } - } else { - instance->decoder.parser_step = GateTXDecoderStepReset; - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - */ -static void subghz_protocol_gate_tx_check_remote_controller(SubGhzBlockGeneric* instance) { - uint32_t code_found_reverse = - subghz_protocol_blocks_reverse_key(instance->data, instance->data_count_bit); - - instance->serial = (code_found_reverse & 0xFF) << 12 | - ((code_found_reverse >> 8) & 0xFF) << 4 | - ((code_found_reverse >> 20) & 0x0F); - instance->btn = ((code_found_reverse >> 16) & 0x0F); -} - -uint8_t subghz_protocol_decoder_gate_tx_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderGateTx* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_gate_tx_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderGateTx* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_gate_tx_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderGateTx* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_gate_tx_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_gate_tx_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderGateTx* instance = context; - subghz_protocol_gate_tx_check_remote_controller(&instance->generic); - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:%06lX\r\n" - "Sn:%05lX Btn:%X\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data & 0xFFFFFF), - instance->generic.serial, - instance->generic.btn); -} diff --git a/applications/main/subghz/protocols/gate_tx.h b/applications/main/subghz/protocols/gate_tx.h deleted file mode 100644 index 4bfba3597..000000000 --- a/applications/main/subghz/protocols/gate_tx.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_GATE_TX_NAME "GateTX" - -typedef struct SubGhzProtocolDecoderGateTx SubGhzProtocolDecoderGateTx; -typedef struct SubGhzProtocolEncoderGateTx SubGhzProtocolEncoderGateTx; - -extern const SubGhzProtocolDecoder subghz_protocol_gate_tx_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_gate_tx_encoder; -extern const SubGhzProtocol subghz_protocol_gate_tx; - -/** - * Allocate SubGhzProtocolEncoderGateTx. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderGateTx* pointer to a SubGhzProtocolEncoderGateTx instance - */ -void* subghz_protocol_encoder_gate_tx_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderGateTx. - * @param context Pointer to a SubGhzProtocolEncoderGateTx instance - */ -void subghz_protocol_encoder_gate_tx_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderGateTx instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_gate_tx_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderGateTx instance - */ -void subghz_protocol_encoder_gate_tx_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderGateTx instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_gate_tx_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderGateTx. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderGateTx* pointer to a SubGhzProtocolDecoderGateTx instance - */ -void* subghz_protocol_decoder_gate_tx_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderGateTx. - * @param context Pointer to a SubGhzProtocolDecoderGateTx instance - */ -void subghz_protocol_decoder_gate_tx_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderGateTx. - * @param context Pointer to a SubGhzProtocolDecoderGateTx instance - */ -void subghz_protocol_decoder_gate_tx_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderGateTx instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_gate_tx_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderGateTx instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_gate_tx_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderGateTx. - * @param context Pointer to a SubGhzProtocolDecoderGateTx instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_gate_tx_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderGateTx. - * @param context Pointer to a SubGhzProtocolDecoderGateTx instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_gate_tx_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderGateTx instance - * @param output Resulting text - */ -void subghz_protocol_decoder_gate_tx_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/holtek.c b/applications/main/subghz/protocols/holtek.c deleted file mode 100644 index 8aaad3b71..000000000 --- a/applications/main/subghz/protocols/holtek.c +++ /dev/null @@ -1,374 +0,0 @@ -#include "holtek.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -/* - * Help - * https://pdf1.alldatasheet.com/datasheet-pdf/view/82103/HOLTEK/HT640.html - * https://fccid.io/OJM-CMD-HHLR-XXXA - * - */ - -#define TAG "SubGhzProtocolHoltek" - -#define HOLTEK_HEADER_MASK 0xF000000000 -#define HOLTEK_HEADER 0x5000000000 - -static const SubGhzBlockConst subghz_protocol_holtek_const = { - .te_short = 430, - .te_long = 870, - .te_delta = 100, - .min_count_bit_for_found = 40, -}; - -struct SubGhzProtocolDecoderHoltek { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; -}; - -struct SubGhzProtocolEncoderHoltek { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - HoltekDecoderStepReset = 0, - HoltekDecoderStepFoundStartBit, - HoltekDecoderStepSaveDuration, - HoltekDecoderStepCheckDuration, -} HoltekDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_holtek_decoder = { - .alloc = subghz_protocol_decoder_holtek_alloc, - .free = subghz_protocol_decoder_holtek_free, - - .feed = subghz_protocol_decoder_holtek_feed, - .reset = subghz_protocol_decoder_holtek_reset, - - .get_hash_data = subghz_protocol_decoder_holtek_get_hash_data, - .serialize = subghz_protocol_decoder_holtek_serialize, - .deserialize = subghz_protocol_decoder_holtek_deserialize, - .get_string = subghz_protocol_decoder_holtek_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_holtek_encoder = { - .alloc = subghz_protocol_encoder_holtek_alloc, - .free = subghz_protocol_encoder_holtek_free, - - .deserialize = subghz_protocol_encoder_holtek_deserialize, - .stop = subghz_protocol_encoder_holtek_stop, - .yield = subghz_protocol_encoder_holtek_yield, -}; - -const SubGhzProtocol subghz_protocol_holtek = { - .name = SUBGHZ_PROTOCOL_HOLTEK_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_868 | SubGhzProtocolFlag_315 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | - SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_holtek_decoder, - .encoder = &subghz_protocol_holtek_encoder, -}; - -void* subghz_protocol_encoder_holtek_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderHoltek* instance = malloc(sizeof(SubGhzProtocolEncoderHoltek)); - - instance->base.protocol = &subghz_protocol_holtek; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 128; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_holtek_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderHoltek* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderHoltek instance - * @return true On success - */ -static bool subghz_protocol_encoder_holtek_get_upload(SubGhzProtocolEncoderHoltek* instance) { - furi_assert(instance); - - size_t index = 0; - size_t size_upload = (instance->generic.data_count_bit * 2) + 2; - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - - //Send header - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_holtek_const.te_short * 36); - //Send start bit - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_holtek_const.te_short); - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_holtek_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_holtek_const.te_short); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_holtek_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_holtek_const.te_long); - } - } - return true; -} - -bool subghz_protocol_encoder_holtek_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderHoltek* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_holtek_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_holtek_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_holtek_stop(void* context) { - SubGhzProtocolEncoderHoltek* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_holtek_yield(void* context) { - SubGhzProtocolEncoderHoltek* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_holtek_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderHoltek* instance = malloc(sizeof(SubGhzProtocolDecoderHoltek)); - instance->base.protocol = &subghz_protocol_holtek; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_holtek_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderHoltek* instance = context; - free(instance); -} - -void subghz_protocol_decoder_holtek_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderHoltek* instance = context; - instance->decoder.parser_step = HoltekDecoderStepReset; -} - -void subghz_protocol_decoder_holtek_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderHoltek* instance = context; - - switch(instance->decoder.parser_step) { - case HoltekDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_holtek_const.te_short * 36) < - subghz_protocol_holtek_const.te_delta * 36)) { - //Found Preambula - instance->decoder.parser_step = HoltekDecoderStepFoundStartBit; - } - break; - case HoltekDecoderStepFoundStartBit: - if((level) && (DURATION_DIFF(duration, subghz_protocol_holtek_const.te_short) < - subghz_protocol_holtek_const.te_delta)) { - //Found StartBit - instance->decoder.parser_step = HoltekDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else { - instance->decoder.parser_step = HoltekDecoderStepReset; - } - break; - case HoltekDecoderStepSaveDuration: - //save duration - if(!level) { - if(duration >= ((uint32_t)subghz_protocol_holtek_const.te_short * 10 + - subghz_protocol_holtek_const.te_delta)) { - if(instance->decoder.decode_count_bit == - subghz_protocol_holtek_const.min_count_bit_for_found) { - if((instance->decoder.decode_data & HOLTEK_HEADER_MASK) == HOLTEK_HEADER) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->decoder.parser_step = HoltekDecoderStepFoundStartBit; - break; - } else { - instance->decoder.te_last = duration; - - instance->decoder.parser_step = HoltekDecoderStepCheckDuration; - } - } else { - instance->decoder.parser_step = HoltekDecoderStepReset; - } - break; - case HoltekDecoderStepCheckDuration: - if(level) { - if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_holtek_const.te_short) < - subghz_protocol_holtek_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_holtek_const.te_long) < - subghz_protocol_holtek_const.te_delta * 2)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = HoltekDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_holtek_const.te_long) < - subghz_protocol_holtek_const.te_delta * 2) && - (DURATION_DIFF(duration, subghz_protocol_holtek_const.te_short) < - subghz_protocol_holtek_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = HoltekDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = HoltekDecoderStepReset; - } - } else { - instance->decoder.parser_step = HoltekDecoderStepReset; - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - */ -static void subghz_protocol_holtek_check_remote_controller(SubGhzBlockGeneric* instance) { - if((instance->data & HOLTEK_HEADER_MASK) == HOLTEK_HEADER) { - instance->serial = - subghz_protocol_blocks_reverse_key((instance->data >> 16) & 0xFFFFF, 20); - uint16_t btn = instance->data & 0xFFFF; - if((btn & 0xf) != 0xA) { - instance->btn = 0x1 << 4 | (btn & 0xF); - } else if(((btn >> 4) & 0xF) != 0xA) { - instance->btn = 0x2 << 4 | ((btn >> 4) & 0xF); - } else if(((btn >> 8) & 0xF) != 0xA) { - instance->btn = 0x3 << 4 | ((btn >> 8) & 0xF); - } else if(((btn >> 12) & 0xF) != 0xA) { - instance->btn = 0x4 << 4 | ((btn >> 12) & 0xF); - } else { - instance->btn = 0; - } - } else { - instance->serial = 0; - instance->btn = 0; - instance->cnt = 0; - } -} - -uint8_t subghz_protocol_decoder_holtek_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderHoltek* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_holtek_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderHoltek* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_holtek_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderHoltek* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_holtek_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_holtek_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderHoltek* instance = context; - subghz_protocol_holtek_check_remote_controller(&instance->generic); - - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%05lX Btn:%X ", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)((instance->generic.data >> 32) & 0xFFFFFFFF), - (uint32_t)(instance->generic.data & 0xFFFFFFFF), - instance->generic.serial, - instance->generic.btn >> 4); - - if((instance->generic.btn & 0xF) == 0xE) { - furi_string_cat_printf(output, "ON\r\n"); - } else if(((instance->generic.btn & 0xF) == 0xB)) { - furi_string_cat_printf(output, "OFF\r\n"); - } -} diff --git a/applications/main/subghz/protocols/holtek.h b/applications/main/subghz/protocols/holtek.h deleted file mode 100644 index 252a26dc7..000000000 --- a/applications/main/subghz/protocols/holtek.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_HOLTEK_NAME "Holtek" - -typedef struct SubGhzProtocolDecoderHoltek SubGhzProtocolDecoderHoltek; -typedef struct SubGhzProtocolEncoderHoltek SubGhzProtocolEncoderHoltek; - -extern const SubGhzProtocolDecoder subghz_protocol_holtek_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_holtek_encoder; -extern const SubGhzProtocol subghz_protocol_holtek; - -/** - * Allocate SubGhzProtocolEncoderHoltek. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderHoltek* pointer to a SubGhzProtocolEncoderHoltek instance - */ -void* subghz_protocol_encoder_holtek_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderHoltek. - * @param context Pointer to a SubGhzProtocolEncoderHoltek instance - */ -void subghz_protocol_encoder_holtek_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderHoltek instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_holtek_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderHoltek instance - */ -void subghz_protocol_encoder_holtek_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderHoltek instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_holtek_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderHoltek. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderHoltek* pointer to a SubGhzProtocolDecoderHoltek instance - */ -void* subghz_protocol_decoder_holtek_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderHoltek. - * @param context Pointer to a SubGhzProtocolDecoderHoltek instance - */ -void subghz_protocol_decoder_holtek_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderHoltek. - * @param context Pointer to a SubGhzProtocolDecoderHoltek instance - */ -void subghz_protocol_decoder_holtek_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderHoltek instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_holtek_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderHoltek instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_holtek_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderHoltek. - * @param context Pointer to a SubGhzProtocolDecoderHoltek instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_holtek_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderHoltek. - * @param context Pointer to a SubGhzProtocolDecoderHoltek instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_holtek_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderHoltek instance - * @param output Resulting text - */ -void subghz_protocol_decoder_holtek_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/holtek_ht12x.c b/applications/main/subghz/protocols/holtek_ht12x.c deleted file mode 100644 index 169387ded..000000000 --- a/applications/main/subghz/protocols/holtek_ht12x.c +++ /dev/null @@ -1,400 +0,0 @@ -#include "holtek_ht12x.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -/* - * Help - * https://www.holtek.com/documents/10179/116711/HT12A_Ev130.pdf - * - */ - -#define TAG "SubGhzProtocolHoltek_HT12X" - -#define DIP_PATTERN "%c%c%c%c%c%c%c%c" -#define CNT_TO_DIP(dip) \ - (dip & 0x0080 ? '0' : '1'), (dip & 0x0040 ? '0' : '1'), (dip & 0x0020 ? '0' : '1'), \ - (dip & 0x0010 ? '0' : '1'), (dip & 0x0008 ? '0' : '1'), (dip & 0x0004 ? '0' : '1'), \ - (dip & 0x0002 ? '0' : '1'), (dip & 0x0001 ? '0' : '1') - -static const SubGhzBlockConst subghz_protocol_holtek_th12x_const = { - .te_short = 320, - .te_long = 640, - .te_delta = 200, - .min_count_bit_for_found = 12, -}; - -struct SubGhzProtocolDecoderHoltek_HT12X { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - - uint32_t te; - uint32_t last_data; -}; - -struct SubGhzProtocolEncoderHoltek_HT12X { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; - - uint32_t te; -}; - -typedef enum { - Holtek_HT12XDecoderStepReset = 0, - Holtek_HT12XDecoderStepFoundStartBit, - Holtek_HT12XDecoderStepSaveDuration, - Holtek_HT12XDecoderStepCheckDuration, -} Holtek_HT12XDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_holtek_th12x_decoder = { - .alloc = subghz_protocol_decoder_holtek_th12x_alloc, - .free = subghz_protocol_decoder_holtek_th12x_free, - - .feed = subghz_protocol_decoder_holtek_th12x_feed, - .reset = subghz_protocol_decoder_holtek_th12x_reset, - - .get_hash_data = subghz_protocol_decoder_holtek_th12x_get_hash_data, - .serialize = subghz_protocol_decoder_holtek_th12x_serialize, - .deserialize = subghz_protocol_decoder_holtek_th12x_deserialize, - .get_string = subghz_protocol_decoder_holtek_th12x_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_holtek_th12x_encoder = { - .alloc = subghz_protocol_encoder_holtek_th12x_alloc, - .free = subghz_protocol_encoder_holtek_th12x_free, - - .deserialize = subghz_protocol_encoder_holtek_th12x_deserialize, - .stop = subghz_protocol_encoder_holtek_th12x_stop, - .yield = subghz_protocol_encoder_holtek_th12x_yield, -}; - -const SubGhzProtocol subghz_protocol_holtek_th12x = { - .name = SUBGHZ_PROTOCOL_HOLTEK_HT12X_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_868 | SubGhzProtocolFlag_315 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_FM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_holtek_th12x_decoder, - .encoder = &subghz_protocol_holtek_th12x_encoder, -}; - -void* subghz_protocol_encoder_holtek_th12x_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderHoltek_HT12X* instance = - malloc(sizeof(SubGhzProtocolEncoderHoltek_HT12X)); - - instance->base.protocol = &subghz_protocol_holtek_th12x; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 128; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_holtek_th12x_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderHoltek_HT12X* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderHoltek_HT12X instance - * @return true On success - */ -static bool - subghz_protocol_encoder_holtek_th12x_get_upload(SubGhzProtocolEncoderHoltek_HT12X* instance) { - furi_assert(instance); - - size_t index = 0; - size_t size_upload = (instance->generic.data_count_bit * 2) + 2; - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - - //Send header - instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)instance->te * 36); - //Send start bit - instance->encoder.upload[index++] = level_duration_make(true, (uint32_t)instance->te); - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)instance->te * 2); - instance->encoder.upload[index++] = level_duration_make(true, (uint32_t)instance->te); - } else { - //send bit 0 - instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)instance->te); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)instance->te * 2); - } - } - return true; -} - -bool subghz_protocol_encoder_holtek_th12x_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderHoltek_HT12X* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) { - FURI_LOG_E(TAG, "Missing TE"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_holtek_th12x_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_holtek_th12x_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_holtek_th12x_stop(void* context) { - SubGhzProtocolEncoderHoltek_HT12X* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_holtek_th12x_yield(void* context) { - SubGhzProtocolEncoderHoltek_HT12X* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_holtek_th12x_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderHoltek_HT12X* instance = - malloc(sizeof(SubGhzProtocolDecoderHoltek_HT12X)); - instance->base.protocol = &subghz_protocol_holtek_th12x; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_holtek_th12x_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderHoltek_HT12X* instance = context; - free(instance); -} - -void subghz_protocol_decoder_holtek_th12x_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderHoltek_HT12X* instance = context; - instance->decoder.parser_step = Holtek_HT12XDecoderStepReset; -} - -void subghz_protocol_decoder_holtek_th12x_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderHoltek_HT12X* instance = context; - - switch(instance->decoder.parser_step) { - case Holtek_HT12XDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_holtek_th12x_const.te_short * 36) < - subghz_protocol_holtek_th12x_const.te_delta * 36)) { - //Found Preambula - instance->decoder.parser_step = Holtek_HT12XDecoderStepFoundStartBit; - } - break; - case Holtek_HT12XDecoderStepFoundStartBit: - if((level) && (DURATION_DIFF(duration, subghz_protocol_holtek_th12x_const.te_short) < - subghz_protocol_holtek_th12x_const.te_delta)) { - //Found StartBit - instance->decoder.parser_step = Holtek_HT12XDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->te = duration; - } else { - instance->decoder.parser_step = Holtek_HT12XDecoderStepReset; - } - break; - case Holtek_HT12XDecoderStepSaveDuration: - //save duration - if(!level) { - if(duration >= ((uint32_t)subghz_protocol_holtek_th12x_const.te_short * 10 + - subghz_protocol_holtek_th12x_const.te_delta)) { - if(instance->decoder.decode_count_bit == - subghz_protocol_holtek_th12x_const.min_count_bit_for_found) { - if((instance->last_data == instance->decoder.decode_data) && - instance->last_data) { - instance->te /= (instance->decoder.decode_count_bit * 3 + 1); - - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->last_data = instance->decoder.decode_data; - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->te = 0; - instance->decoder.parser_step = Holtek_HT12XDecoderStepFoundStartBit; - break; - } else { - instance->decoder.te_last = duration; - instance->te += duration; - instance->decoder.parser_step = Holtek_HT12XDecoderStepCheckDuration; - } - } else { - instance->decoder.parser_step = Holtek_HT12XDecoderStepReset; - } - break; - case Holtek_HT12XDecoderStepCheckDuration: - if(level) { - instance->te += duration; - if((DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_holtek_th12x_const.te_long) < - subghz_protocol_holtek_th12x_const.te_delta * 2) && - (DURATION_DIFF(duration, subghz_protocol_holtek_th12x_const.te_short) < - subghz_protocol_holtek_th12x_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = Holtek_HT12XDecoderStepSaveDuration; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_holtek_th12x_const.te_short) < - subghz_protocol_holtek_th12x_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_holtek_th12x_const.te_long) < - subghz_protocol_holtek_th12x_const.te_delta * 2)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = Holtek_HT12XDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = Holtek_HT12XDecoderStepReset; - } - } else { - instance->decoder.parser_step = Holtek_HT12XDecoderStepReset; - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - */ -static void subghz_protocol_holtek_th12x_check_remote_controller(SubGhzBlockGeneric* instance) { - instance->btn = instance->data & 0x0F; - instance->cnt = (instance->data >> 4) & 0xFF; -} - -uint8_t subghz_protocol_decoder_holtek_th12x_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderHoltek_HT12X* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_holtek_th12x_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderHoltek_HT12X* instance = context; - bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); - if(res && !flipper_format_write_uint32(flipper_format, "TE", &instance->te, 1)) { - FURI_LOG_E(TAG, "Unable to add TE"); - res = false; - } - return res; -} - -bool subghz_protocol_decoder_holtek_th12x_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderHoltek_HT12X* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_holtek_th12x_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) { - FURI_LOG_E(TAG, "Missing TE"); - break; - } - ret = true; - } while(false); - return ret; -} - -static void subghz_protocol_holtek_th12x_event_serialize(uint8_t event, FuriString* output) { - furi_string_cat_printf( - output, - "%s%s%s%s\r\n", - (((event >> 3) & 0x1) == 0x0 ? "B1 " : ""), - (((event >> 2) & 0x1) == 0x0 ? "B2 " : ""), - (((event >> 1) & 0x1) == 0x0 ? "B3 " : ""), - (((event >> 0) & 0x1) == 0x0 ? "B4 " : "")); -} - -void subghz_protocol_decoder_holtek_th12x_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderHoltek_HT12X* instance = context; - subghz_protocol_holtek_th12x_check_remote_controller(&instance->generic); - - furi_string_cat_printf( - output, - "%s %db\r\n" - "Key:0x%03lX\r\n" - "Btn: ", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data & 0xFFF)); - subghz_protocol_holtek_th12x_event_serialize(instance->generic.btn, output); - furi_string_cat_printf( - output, - "DIP:" DIP_PATTERN "\r\n" - "Te:%luus\r\n", - CNT_TO_DIP(instance->generic.cnt), - instance->te); -} diff --git a/applications/main/subghz/protocols/holtek_ht12x.h b/applications/main/subghz/protocols/holtek_ht12x.h deleted file mode 100644 index 7b5c31dd7..000000000 --- a/applications/main/subghz/protocols/holtek_ht12x.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_HOLTEK_HT12X_NAME "Holtek_HT12X" - -typedef struct SubGhzProtocolDecoderHoltek_HT12X SubGhzProtocolDecoderHoltek_HT12X; -typedef struct SubGhzProtocolEncoderHoltek_HT12X SubGhzProtocolEncoderHoltek_HT12X; - -extern const SubGhzProtocolDecoder subghz_protocol_holtek_th12x_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_holtek_th12x_encoder; -extern const SubGhzProtocol subghz_protocol_holtek_th12x; - -/** - * Allocate SubGhzProtocolEncoderHoltek_HT12X. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderHoltek_HT12X* pointer to a SubGhzProtocolEncoderHoltek_HT12X instance - */ -void* subghz_protocol_encoder_holtek_th12x_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderHoltek_HT12X. - * @param context Pointer to a SubGhzProtocolEncoderHoltek_HT12X instance - */ -void subghz_protocol_encoder_holtek_th12x_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderHoltek_HT12X instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_holtek_th12x_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderHoltek_HT12X instance - */ -void subghz_protocol_encoder_holtek_th12x_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderHoltek_HT12X instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_holtek_th12x_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderHoltek_HT12X. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderHoltek_HT12X* pointer to a SubGhzProtocolDecoderHoltek_HT12X instance - */ -void* subghz_protocol_decoder_holtek_th12x_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderHoltek_HT12X. - * @param context Pointer to a SubGhzProtocolDecoderHoltek_HT12X instance - */ -void subghz_protocol_decoder_holtek_th12x_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderHoltek_HT12X. - * @param context Pointer to a SubGhzProtocolDecoderHoltek_HT12X instance - */ -void subghz_protocol_decoder_holtek_th12x_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderHoltek_HT12X instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_holtek_th12x_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderHoltek_HT12X instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_holtek_th12x_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderHoltek_HT12X. - * @param context Pointer to a SubGhzProtocolDecoderHoltek_HT12X instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_holtek_th12x_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderHoltek_HT12X. - * @param context Pointer to a SubGhzProtocolDecoderHoltek_HT12X instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_holtek_th12x_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderHoltek_HT12X instance - * @param output Resulting text - */ -void subghz_protocol_decoder_holtek_th12x_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/honeywell_wdb.c b/applications/main/subghz/protocols/honeywell_wdb.c deleted file mode 100644 index 3b940fc67..000000000 --- a/applications/main/subghz/protocols/honeywell_wdb.c +++ /dev/null @@ -1,399 +0,0 @@ -#include "honeywell_wdb.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolHoneywellWDB" - -/* - * - * https://github.com/klohner/honeywell-wireless-doorbell - * - */ - -static const SubGhzBlockConst subghz_protocol_honeywell_wdb_const = { - .te_short = 160, - .te_long = 320, - .te_delta = 60, - .min_count_bit_for_found = 48, -}; - -struct SubGhzProtocolDecoderHoneywell_WDB { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - const char* device_type; - const char* alert; - uint8_t secret_knock; - uint8_t relay; - uint8_t lowbat; -}; - -struct SubGhzProtocolEncoderHoneywell_WDB { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - Honeywell_WDBDecoderStepReset = 0, - Honeywell_WDBDecoderStepFoundStartBit, - Honeywell_WDBDecoderStepSaveDuration, - Honeywell_WDBDecoderStepCheckDuration, -} Honeywell_WDBDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_honeywell_wdb_decoder = { - .alloc = subghz_protocol_decoder_honeywell_wdb_alloc, - .free = subghz_protocol_decoder_honeywell_wdb_free, - - .feed = subghz_protocol_decoder_honeywell_wdb_feed, - .reset = subghz_protocol_decoder_honeywell_wdb_reset, - - .get_hash_data = subghz_protocol_decoder_honeywell_wdb_get_hash_data, - .serialize = subghz_protocol_decoder_honeywell_wdb_serialize, - .deserialize = subghz_protocol_decoder_honeywell_wdb_deserialize, - .get_string = subghz_protocol_decoder_honeywell_wdb_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_honeywell_wdb_encoder = { - .alloc = subghz_protocol_encoder_honeywell_wdb_alloc, - .free = subghz_protocol_encoder_honeywell_wdb_free, - - .deserialize = subghz_protocol_encoder_honeywell_wdb_deserialize, - .stop = subghz_protocol_encoder_honeywell_wdb_stop, - .yield = subghz_protocol_encoder_honeywell_wdb_yield, -}; - -const SubGhzProtocol subghz_protocol_honeywell_wdb = { - .name = SUBGHZ_PROTOCOL_HONEYWELL_WDB_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_AM | - SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | - SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_honeywell_wdb_decoder, - .encoder = &subghz_protocol_honeywell_wdb_encoder, -}; - -void* subghz_protocol_encoder_honeywell_wdb_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderHoneywell_WDB* instance = - malloc(sizeof(SubGhzProtocolEncoderHoneywell_WDB)); - - instance->base.protocol = &subghz_protocol_honeywell_wdb; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 128; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_honeywell_wdb_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderHoneywell_WDB* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderHoneywell_WDB instance - * @return true On success - */ -static bool subghz_protocol_encoder_honeywell_wdb_get_upload( - SubGhzProtocolEncoderHoneywell_WDB* instance) { - furi_assert(instance); - size_t index = 0; - size_t size_upload = (instance->generic.data_count_bit * 2) + 2; - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - //Send header - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_honeywell_wdb_const.te_short * 3); - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_honeywell_wdb_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_honeywell_wdb_const.te_short); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_honeywell_wdb_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_honeywell_wdb_const.te_long); - } - } - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_honeywell_wdb_const.te_short * 3); - return true; -} - -bool subghz_protocol_encoder_honeywell_wdb_deserialize( - void* context, - FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderHoneywell_WDB* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_honeywell_wdb_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_honeywell_wdb_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_honeywell_wdb_stop(void* context) { - SubGhzProtocolEncoderHoneywell_WDB* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_honeywell_wdb_yield(void* context) { - SubGhzProtocolEncoderHoneywell_WDB* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_honeywell_wdb_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderHoneywell_WDB* instance = - malloc(sizeof(SubGhzProtocolDecoderHoneywell_WDB)); - instance->base.protocol = &subghz_protocol_honeywell_wdb; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_honeywell_wdb_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderHoneywell_WDB* instance = context; - free(instance); -} - -void subghz_protocol_decoder_honeywell_wdb_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderHoneywell_WDB* instance = context; - instance->decoder.parser_step = Honeywell_WDBDecoderStepReset; -} - -void subghz_protocol_decoder_honeywell_wdb_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderHoneywell_WDB* instance = context; - switch(instance->decoder.parser_step) { - case Honeywell_WDBDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_honeywell_wdb_const.te_short * 3) < - subghz_protocol_honeywell_wdb_const.te_delta)) { - //Found header Honeywell_WDB - instance->decoder.decode_count_bit = 0; - instance->decoder.decode_data = 0; - instance->decoder.parser_step = Honeywell_WDBDecoderStepSaveDuration; - } - break; - case Honeywell_WDBDecoderStepSaveDuration: - if(level) { //save interval - if(DURATION_DIFF(duration, subghz_protocol_honeywell_wdb_const.te_short * 3) < - subghz_protocol_honeywell_wdb_const.te_delta) { - if((instance->decoder.decode_count_bit == - subghz_protocol_honeywell_wdb_const.min_count_bit_for_found) && - ((instance->decoder.decode_data & 0x01) == - subghz_protocol_blocks_get_parity( - instance->decoder.decode_data >> 1, - subghz_protocol_honeywell_wdb_const.min_count_bit_for_found - 1))) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.parser_step = Honeywell_WDBDecoderStepReset; - break; - } - instance->decoder.te_last = duration; - instance->decoder.parser_step = Honeywell_WDBDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = Honeywell_WDBDecoderStepReset; - } - break; - case Honeywell_WDBDecoderStepCheckDuration: - if(!level) { - if((DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_honeywell_wdb_const.te_short) < - subghz_protocol_honeywell_wdb_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_honeywell_wdb_const.te_long) < - subghz_protocol_honeywell_wdb_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = Honeywell_WDBDecoderStepSaveDuration; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_honeywell_wdb_const.te_long) < - subghz_protocol_honeywell_wdb_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_honeywell_wdb_const.te_short) < - subghz_protocol_honeywell_wdb_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = Honeywell_WDBDecoderStepSaveDuration; - } else - instance->decoder.parser_step = Honeywell_WDBDecoderStepReset; - } else { - instance->decoder.parser_step = Honeywell_WDBDecoderStepReset; - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzProtocolDecoderHoneywell_WDB* instance - */ -static void subghz_protocol_honeywell_wdb_check_remote_controller( - SubGhzProtocolDecoderHoneywell_WDB* instance) { - /* - * - * Frame bits used in Honeywell RCWL300A, RCWL330A, Series 3, 5, 9 and all Decor Series Wireless Chimes - * 0000 0000 1111 1111 2222 2222 3333 3333 4444 4444 5555 5555 - * 7654 3210 7654 3210 7654 3210 7654 3210 7654 3210 7654 3210 - * XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XX.. XXX. .... KEY DATA (any change and receiver doesn't seem to recognize signal) - * XXXX XXXX XXXX XXXX XXXX .... .... .... .... .... .... .... KEY ID (different for each transmitter) - * .... .... .... .... .... 0000 00.. 0000 0000 00.. 000. .... KEY UNKNOWN 0 (always 0 in devices I've tested) - * .... .... .... .... .... .... ..XX .... .... .... .... .... DEVICE TYPE (10 = doorbell, 01 = PIR Motion sensor) - * .... .... .... .... .... .... .... .... .... ..XX ...X XXX. FLAG DATA (may be modified for possible effects on receiver) - * .... .... .... .... .... .... .... .... .... ..XX .... .... ALERT (00 = normal, 01 or 10 = right-left halo light pattern, 11 = full volume alarm) - * .... .... .... .... .... .... .... .... .... .... ...X .... SECRET KNOCK (0 = default, 1 if doorbell is pressed 3x rapidly) - * .... .... .... .... .... .... .... .... .... .... .... X... RELAY (1 if signal is a retransmission of a received transmission, only some models) - * .... .... .... .... .... .... .... .... .... .... .... .X.. FLAG UNKNOWN (0 = default, but 1 is accepted and I don't observe any effects) - * .... .... .... .... .... .... .... .... .... .... .... ..X. LOWBAT (1 if battery is low, receiver gives low battery alert) - * .... .... .... .... .... .... .... .... .... .... .... ...X PARITY (LSB of count of set bits in previous 47 bits) - * - */ - - instance->generic.serial = (instance->generic.data >> 28) & 0xFFFFF; - switch((instance->generic.data >> 20) & 0x3) { - case 0x02: - instance->device_type = "Doorbell"; - break; - case 0x01: - instance->device_type = "PIR-Motion"; - break; - default: - instance->device_type = "Unknown"; - break; - } - - switch((instance->generic.data >> 16) & 0x3) { - case 0x00: - instance->alert = "Normal"; - break; - case 0x01: - case 0x02: - instance->alert = "High"; - break; - case 0x03: - instance->alert = "Full"; - break; - default: - instance->alert = "Unknown"; - break; - } - - instance->secret_knock = (uint8_t)((instance->generic.data >> 4) & 0x1); - instance->relay = (uint8_t)((instance->generic.data >> 3) & 0x1); - instance->lowbat = (uint8_t)((instance->generic.data >> 1) & 0x1); -} - -uint8_t subghz_protocol_decoder_honeywell_wdb_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderHoneywell_WDB* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_honeywell_wdb_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderHoneywell_WDB* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_honeywell_wdb_deserialize( - void* context, - FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderHoneywell_WDB* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_honeywell_wdb_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_honeywell_wdb_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderHoneywell_WDB* instance = context; - subghz_protocol_honeywell_wdb_check_remote_controller(instance); - - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%05lX\r\n" - "DT:%s Al:%s\r\n" - "SK:%01X R:%01X LBat:%01X\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)((instance->generic.data >> 32) & 0xFFFFFFFF), - (uint32_t)(instance->generic.data & 0xFFFFFFFF), - instance->generic.serial, - instance->device_type, - instance->alert, - instance->secret_knock, - instance->relay, - instance->lowbat); -} diff --git a/applications/main/subghz/protocols/honeywell_wdb.h b/applications/main/subghz/protocols/honeywell_wdb.h deleted file mode 100644 index 828631837..000000000 --- a/applications/main/subghz/protocols/honeywell_wdb.h +++ /dev/null @@ -1,111 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_HONEYWELL_WDB_NAME "Honeywell" - -typedef struct SubGhzProtocolDecoderHoneywell_WDB SubGhzProtocolDecoderHoneywell_WDB; -typedef struct SubGhzProtocolEncoderHoneywell_WDB SubGhzProtocolEncoderHoneywell_WDB; - -extern const SubGhzProtocolDecoder subghz_protocol_honeywell_wdb_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_honeywell_wdb_encoder; -extern const SubGhzProtocol subghz_protocol_honeywell_wdb; - -/** - * Allocate SubGhzProtocolEncoderHoneywell_WDB. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderHoneywell_WDB* pointer to a SubGhzProtocolEncoderHoneywell_WDB instance - */ -void* subghz_protocol_encoder_honeywell_wdb_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderHoneywell_WDB. - * @param context Pointer to a SubGhzProtocolEncoderHoneywell_WDB instance - */ -void subghz_protocol_encoder_honeywell_wdb_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderHoneywell_WDB instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_honeywell_wdb_deserialize( - void* context, - FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderHoneywell_WDB instance - */ -void subghz_protocol_encoder_honeywell_wdb_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderHoneywell_WDB instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_honeywell_wdb_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderHoneywell_WDB. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderHoneywell_WDB* pointer to a SubGhzProtocolDecoderHoneywell_WDB instance - */ -void* subghz_protocol_decoder_honeywell_wdb_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderHoneywell_WDB. - * @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance - */ -void subghz_protocol_decoder_honeywell_wdb_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderHoneywell_WDB. - * @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance - */ -void subghz_protocol_decoder_honeywell_wdb_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_honeywell_wdb_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_honeywell_wdb_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderHoneywell_WDB. - * @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_honeywell_wdb_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderHoneywell_WDB. - * @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_honeywell_wdb_deserialize( - void* context, - FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderHoneywell_WDB instance - * @param output Resulting text - */ -void subghz_protocol_decoder_honeywell_wdb_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/hormann.c b/applications/main/subghz/protocols/hormann.c deleted file mode 100644 index 67b8cdfca..000000000 --- a/applications/main/subghz/protocols/hormann.c +++ /dev/null @@ -1,341 +0,0 @@ -#include "hormann.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolHormannHSM" - -#define HORMANN_HSM_PATTERN 0xFF000000003 - -static const SubGhzBlockConst subghz_protocol_hormann_const = { - .te_short = 500, - .te_long = 1000, - .te_delta = 200, - .min_count_bit_for_found = 44, -}; - -struct SubGhzProtocolDecoderHormann { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; -}; - -struct SubGhzProtocolEncoderHormann { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - HormannDecoderStepReset = 0, - HormannDecoderStepFoundStartHeader, - HormannDecoderStepFoundHeader, - HormannDecoderStepFoundStartBit, - HormannDecoderStepSaveDuration, - HormannDecoderStepCheckDuration, -} HormannDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_hormann_decoder = { - .alloc = subghz_protocol_decoder_hormann_alloc, - .free = subghz_protocol_decoder_hormann_free, - - .feed = subghz_protocol_decoder_hormann_feed, - .reset = subghz_protocol_decoder_hormann_reset, - - .get_hash_data = subghz_protocol_decoder_hormann_get_hash_data, - .serialize = subghz_protocol_decoder_hormann_serialize, - .deserialize = subghz_protocol_decoder_hormann_deserialize, - .get_string = subghz_protocol_decoder_hormann_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_hormann_encoder = { - .alloc = subghz_protocol_encoder_hormann_alloc, - .free = subghz_protocol_encoder_hormann_free, - - .deserialize = subghz_protocol_encoder_hormann_deserialize, - .stop = subghz_protocol_encoder_hormann_stop, - .yield = subghz_protocol_encoder_hormann_yield, -}; - -const SubGhzProtocol subghz_protocol_hormann = { - .name = SUBGHZ_PROTOCOL_HORMANN_HSM_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_868 | SubGhzProtocolFlag_AM | - SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | - SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_hormann_decoder, - .encoder = &subghz_protocol_hormann_encoder, -}; - -void* subghz_protocol_encoder_hormann_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderHormann* instance = malloc(sizeof(SubGhzProtocolEncoderHormann)); - - instance->base.protocol = &subghz_protocol_hormann; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 2048; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_hormann_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderHormann* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderHormann instance - * @return true On success - */ -static bool subghz_protocol_encoder_hormann_get_upload(SubGhzProtocolEncoderHormann* instance) { - furi_assert(instance); - - size_t index = 0; - size_t size_upload = (instance->generic.data_count_bit * 2 + 2) * 20 + 1; - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - instance->encoder.repeat = 10; //original remote does 10 repeats - - for(size_t repeat = 0; repeat < 20; repeat++) { - //Send start bit - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_hormann_const.te_short * 24); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_hormann_const.te_short); - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_hormann_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_hormann_const.te_short); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_hormann_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_hormann_const.te_long); - } - } - } - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_hormann_const.te_short * 24); - return true; -} - -bool subghz_protocol_encoder_hormann_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderHormann* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_hormann_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_hormann_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_hormann_stop(void* context) { - SubGhzProtocolEncoderHormann* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_hormann_yield(void* context) { - SubGhzProtocolEncoderHormann* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_hormann_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderHormann* instance = malloc(sizeof(SubGhzProtocolDecoderHormann)); - instance->base.protocol = &subghz_protocol_hormann; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_hormann_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderHormann* instance = context; - free(instance); -} - -static bool subghz_protocol_decoder_hormann_check_pattern(SubGhzProtocolDecoderHormann* instance) { - return (instance->decoder.decode_data & HORMANN_HSM_PATTERN) == HORMANN_HSM_PATTERN; -} - -void subghz_protocol_decoder_hormann_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderHormann* instance = context; - instance->decoder.parser_step = HormannDecoderStepReset; -} - -void subghz_protocol_decoder_hormann_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderHormann* instance = context; - - switch(instance->decoder.parser_step) { - case HormannDecoderStepReset: - if((level) && (DURATION_DIFF(duration, subghz_protocol_hormann_const.te_short * 24) < - subghz_protocol_hormann_const.te_delta * 24)) { - instance->decoder.parser_step = HormannDecoderStepFoundStartBit; - } - break; - case HormannDecoderStepFoundStartBit: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_hormann_const.te_short) < - subghz_protocol_hormann_const.te_delta)) { - instance->decoder.parser_step = HormannDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else { - instance->decoder.parser_step = HormannDecoderStepReset; - } - break; - case HormannDecoderStepSaveDuration: - if(level) { //save interval - if(duration >= (subghz_protocol_hormann_const.te_short * 5) && - subghz_protocol_decoder_hormann_check_pattern(instance)) { - instance->decoder.parser_step = HormannDecoderStepFoundStartBit; - if(instance->decoder.decode_count_bit >= - subghz_protocol_hormann_const.min_count_bit_for_found) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - break; - } - instance->decoder.te_last = duration; - instance->decoder.parser_step = HormannDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = HormannDecoderStepReset; - } - break; - case HormannDecoderStepCheckDuration: - if(!level) { - if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_hormann_const.te_short) < - subghz_protocol_hormann_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_hormann_const.te_long) < - subghz_protocol_hormann_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = HormannDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_hormann_const.te_long) < - subghz_protocol_hormann_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_hormann_const.te_short) < - subghz_protocol_hormann_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = HormannDecoderStepSaveDuration; - } else - instance->decoder.parser_step = HormannDecoderStepReset; - } else { - instance->decoder.parser_step = HormannDecoderStepReset; - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - */ -static void subghz_protocol_hormann_check_remote_controller(SubGhzBlockGeneric* instance) { - instance->btn = (instance->data >> 4) & 0xF; -} - -uint8_t subghz_protocol_decoder_hormann_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderHormann* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_hormann_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderHormann* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_hormann_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderHormann* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_hormann_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_hormann_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderHormann* instance = context; - subghz_protocol_hormann_check_remote_controller(&instance->generic); - - furi_string_cat_printf( - output, - "%s\r\n" - "%dbit\r\n" - "Key:0x%03lX%08lX\r\n" - "Btn:0x%01X\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)instance->generic.data, - instance->generic.btn); -} diff --git a/applications/main/subghz/protocols/hormann.h b/applications/main/subghz/protocols/hormann.h deleted file mode 100644 index 857a50041..000000000 --- a/applications/main/subghz/protocols/hormann.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_HORMANN_HSM_NAME "Hormann HSM" - -typedef struct SubGhzProtocolDecoderHormann SubGhzProtocolDecoderHormann; -typedef struct SubGhzProtocolEncoderHormann SubGhzProtocolEncoderHormann; - -extern const SubGhzProtocolDecoder subghz_protocol_hormann_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_hormann_encoder; -extern const SubGhzProtocol subghz_protocol_hormann; - -/** - * Allocate SubGhzProtocolEncoderHormann. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderHormann* pointer to a SubGhzProtocolEncoderHormann instance - */ -void* subghz_protocol_encoder_hormann_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderHormann. - * @param context Pointer to a SubGhzProtocolEncoderHormann instance - */ -void subghz_protocol_encoder_hormann_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderHormann instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_hormann_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderHormann instance - */ -void subghz_protocol_encoder_hormann_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderHormann instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_hormann_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderHormann. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderHormann* pointer to a SubGhzProtocolDecoderHormann instance - */ -void* subghz_protocol_decoder_hormann_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderHormann. - * @param context Pointer to a SubGhzProtocolDecoderHormann instance - */ -void subghz_protocol_decoder_hormann_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderHormann. - * @param context Pointer to a SubGhzProtocolDecoderHormann instance - */ -void subghz_protocol_decoder_hormann_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderHormann instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_hormann_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderHormann instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_hormann_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderHormann. - * @param context Pointer to a SubGhzProtocolDecoderHormann instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_hormann_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderHormann. - * @param context Pointer to a SubGhzProtocolDecoderHormann instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_hormann_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderHormann instance - * @param output Resulting text - */ -void subghz_protocol_decoder_hormann_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/ido.c b/applications/main/subghz/protocols/ido.c deleted file mode 100644 index dff9defc0..000000000 --- a/applications/main/subghz/protocols/ido.c +++ /dev/null @@ -1,234 +0,0 @@ -#include "ido.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocol_iDo_117/111" - -static const SubGhzBlockConst subghz_protocol_ido_const = { - .te_short = 450, - .te_long = 1450, - .te_delta = 150, - .min_count_bit_for_found = 48, -}; - -struct SubGhzProtocolDecoderIDo { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; -}; - -struct SubGhzProtocolEncoderIDo { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - IDoDecoderStepReset = 0, - IDoDecoderStepFoundPreambula, - IDoDecoderStepSaveDuration, - IDoDecoderStepCheckDuration, -} IDoDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_ido_decoder = { - .alloc = subghz_protocol_decoder_ido_alloc, - .free = subghz_protocol_decoder_ido_free, - - .feed = subghz_protocol_decoder_ido_feed, - .reset = subghz_protocol_decoder_ido_reset, - - .get_hash_data = subghz_protocol_decoder_ido_get_hash_data, - .deserialize = subghz_protocol_decoder_ido_deserialize, - .serialize = subghz_protocol_decoder_ido_serialize, - .get_string = subghz_protocol_decoder_ido_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_ido_encoder = { - .alloc = NULL, - .free = NULL, - - .deserialize = NULL, - .stop = NULL, - .yield = NULL, -}; - -const SubGhzProtocol subghz_protocol_ido = { - .name = SUBGHZ_PROTOCOL_IDO_NAME, - .type = SubGhzProtocolTypeDynamic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Save, - - .decoder = &subghz_protocol_ido_decoder, - .encoder = &subghz_protocol_ido_encoder, -}; - -void* subghz_protocol_decoder_ido_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderIDo* instance = malloc(sizeof(SubGhzProtocolDecoderIDo)); - instance->base.protocol = &subghz_protocol_ido; - instance->generic.protocol_name = instance->base.protocol->name; - - return instance; -} - -void subghz_protocol_decoder_ido_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderIDo* instance = context; - free(instance); -} - -void subghz_protocol_decoder_ido_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderIDo* instance = context; - instance->decoder.parser_step = IDoDecoderStepReset; -} - -void subghz_protocol_decoder_ido_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderIDo* instance = context; - - switch(instance->decoder.parser_step) { - case IDoDecoderStepReset: - if((level) && (DURATION_DIFF(duration, subghz_protocol_ido_const.te_short * 10) < - subghz_protocol_ido_const.te_delta * 5)) { - instance->decoder.parser_step = IDoDecoderStepFoundPreambula; - } - break; - case IDoDecoderStepFoundPreambula: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_ido_const.te_short * 10) < - subghz_protocol_ido_const.te_delta * 5)) { - //Found Preambula - instance->decoder.parser_step = IDoDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else { - instance->decoder.parser_step = IDoDecoderStepReset; - } - break; - case IDoDecoderStepSaveDuration: - if(level) { - if(duration >= ((uint32_t)subghz_protocol_ido_const.te_short * 5 + - subghz_protocol_ido_const.te_delta)) { - instance->decoder.parser_step = IDoDecoderStepFoundPreambula; - if(instance->decoder.decode_count_bit >= - subghz_protocol_ido_const.min_count_bit_for_found) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - break; - } else { - instance->decoder.te_last = duration; - instance->decoder.parser_step = IDoDecoderStepCheckDuration; - } - - } else { - instance->decoder.parser_step = IDoDecoderStepReset; - } - break; - case IDoDecoderStepCheckDuration: - if(!level) { - if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_ido_const.te_short) < - subghz_protocol_ido_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_ido_const.te_long) < - subghz_protocol_ido_const.te_delta * 3)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = IDoDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_ido_const.te_short) < - subghz_protocol_ido_const.te_delta * 3) && - (DURATION_DIFF(duration, subghz_protocol_ido_const.te_short) < - subghz_protocol_ido_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = IDoDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = IDoDecoderStepReset; - } - } else { - instance->decoder.parser_step = IDoDecoderStepReset; - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - */ -static void subghz_protocol_ido_check_remote_controller(SubGhzBlockGeneric* instance) { - uint64_t code_found_reverse = - subghz_protocol_blocks_reverse_key(instance->data, instance->data_count_bit); - uint32_t code_fix = code_found_reverse & 0xFFFFFF; - - instance->serial = code_fix & 0xFFFFF; - instance->btn = (code_fix >> 20) & 0x0F; -} - -uint8_t subghz_protocol_decoder_ido_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderIDo* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_ido_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderIDo* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_ido_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderIDo* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != subghz_protocol_ido_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_ido_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderIDo* instance = context; - - subghz_protocol_ido_check_remote_controller(&instance->generic); - uint64_t code_found_reverse = subghz_protocol_blocks_reverse_key( - instance->generic.data, instance->generic.data_count_bit); - uint32_t code_fix = code_found_reverse & 0xFFFFFF; - uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFFF; - - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Fix:%06lX \r\n" - "Hop:%06lX \r\n" - "Sn:%05lX Btn:%X\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)instance->generic.data, - code_fix, - code_hop, - instance->generic.serial, - instance->generic.btn); -} diff --git a/applications/main/subghz/protocols/ido.h b/applications/main/subghz/protocols/ido.h deleted file mode 100644 index 634f6ff89..000000000 --- a/applications/main/subghz/protocols/ido.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_IDO_NAME "iDo 117/111" - -typedef struct SubGhzProtocolDecoderIDo SubGhzProtocolDecoderIDo; -typedef struct SubGhzProtocolEncoderIDo SubGhzProtocolEncoderIDo; - -extern const SubGhzProtocolDecoder subghz_protocol_ido_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_ido_encoder; -extern const SubGhzProtocol subghz_protocol_ido; - -/** - * Allocate SubGhzProtocolDecoderIDo. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderIDo* pointer to a SubGhzProtocolDecoderIDo instance - */ -void* subghz_protocol_decoder_ido_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderIDo. - * @param context Pointer to a SubGhzProtocolDecoderIDo instance - */ -void subghz_protocol_decoder_ido_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderIDo. - * @param context Pointer to a SubGhzProtocolDecoderIDo instance - */ -void subghz_protocol_decoder_ido_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderIDo instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_ido_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderIDo instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_ido_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderIDo. - * @param context Pointer to a SubGhzProtocolDecoderIDo instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_ido_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderIDo. - * @param context Pointer to a SubGhzProtocolDecoderIDo instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_ido_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderIDo instance - * @param output Resulting text - */ -void subghz_protocol_decoder_ido_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/intertechno_v3.c b/applications/main/subghz/protocols/intertechno_v3.c deleted file mode 100644 index 2c4e514cc..000000000 --- a/applications/main/subghz/protocols/intertechno_v3.c +++ /dev/null @@ -1,472 +0,0 @@ -#include "intertechno_v3.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolIntertechnoV3" - -#define CH_PATTERN "%c%c%c%c" -#define CNT_TO_CH(ch) \ - (ch & 0x8 ? '1' : '0'), (ch & 0x4 ? '1' : '0'), (ch & 0x2 ? '1' : '0'), (ch & 0x1 ? '1' : '0') - -#define INTERTECHNO_V3_DIMMING_COUNT_BIT 36 - -static const SubGhzBlockConst subghz_protocol_intertechno_v3_const = { - .te_short = 275, - .te_long = 1375, - .te_delta = 150, - .min_count_bit_for_found = 32, -}; - -struct SubGhzProtocolDecoderIntertechno_V3 { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; -}; - -struct SubGhzProtocolEncoderIntertechno_V3 { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - IntertechnoV3DecoderStepReset = 0, - IntertechnoV3DecoderStepStartSync, - IntertechnoV3DecoderStepFoundSync, - IntertechnoV3DecoderStepStartDuration, - IntertechnoV3DecoderStepSaveDuration, - IntertechnoV3DecoderStepCheckDuration, - IntertechnoV3DecoderStepEndDuration, -} IntertechnoV3DecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_intertechno_v3_decoder = { - .alloc = subghz_protocol_decoder_intertechno_v3_alloc, - .free = subghz_protocol_decoder_intertechno_v3_free, - - .feed = subghz_protocol_decoder_intertechno_v3_feed, - .reset = subghz_protocol_decoder_intertechno_v3_reset, - - .get_hash_data = subghz_protocol_decoder_intertechno_v3_get_hash_data, - .serialize = subghz_protocol_decoder_intertechno_v3_serialize, - .deserialize = subghz_protocol_decoder_intertechno_v3_deserialize, - .get_string = subghz_protocol_decoder_intertechno_v3_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_intertechno_v3_encoder = { - .alloc = subghz_protocol_encoder_intertechno_v3_alloc, - .free = subghz_protocol_encoder_intertechno_v3_free, - - .deserialize = subghz_protocol_encoder_intertechno_v3_deserialize, - .stop = subghz_protocol_encoder_intertechno_v3_stop, - .yield = subghz_protocol_encoder_intertechno_v3_yield, -}; - -const SubGhzProtocol subghz_protocol_intertechno_v3 = { - .name = SUBGHZ_PROTOCOL_INTERTECHNO_V3_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | - SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_intertechno_v3_decoder, - .encoder = &subghz_protocol_intertechno_v3_encoder, -}; - -void* subghz_protocol_encoder_intertechno_v3_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderIntertechno_V3* instance = - malloc(sizeof(SubGhzProtocolEncoderIntertechno_V3)); - - instance->base.protocol = &subghz_protocol_intertechno_v3; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 256; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_intertechno_v3_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderIntertechno_V3* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderIntertechno_V3 instance - * @return true On success - */ -static bool subghz_protocol_encoder_intertechno_v3_get_upload( - SubGhzProtocolEncoderIntertechno_V3* instance) { - furi_assert(instance); - size_t index = 0; - - //Send header - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_intertechno_v3_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_intertechno_v3_const.te_short * 38); - //Send sync - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_intertechno_v3_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_intertechno_v3_const.te_short * 10); - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if((instance->generic.data_count_bit == INTERTECHNO_V3_DIMMING_COUNT_BIT) && (i == 9)) { - //send bit dimm - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_intertechno_v3_const.te_short); - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_intertechno_v3_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_intertechno_v3_const.te_short); - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_intertechno_v3_const.te_short); - } else if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_intertechno_v3_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_intertechno_v3_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_intertechno_v3_const.te_short); - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_intertechno_v3_const.te_short); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_intertechno_v3_const.te_short); - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_intertechno_v3_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_intertechno_v3_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_intertechno_v3_const.te_long); - } - } - instance->encoder.size_upload = index; - return true; -} - -bool subghz_protocol_encoder_intertechno_v3_deserialize( - void* context, - FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderIntertechno_V3* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if((instance->generic.data_count_bit != - subghz_protocol_intertechno_v3_const.min_count_bit_for_found) && - (instance->generic.data_count_bit != INTERTECHNO_V3_DIMMING_COUNT_BIT)) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_intertechno_v3_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_intertechno_v3_stop(void* context) { - SubGhzProtocolEncoderIntertechno_V3* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_intertechno_v3_yield(void* context) { - SubGhzProtocolEncoderIntertechno_V3* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_intertechno_v3_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderIntertechno_V3* instance = - malloc(sizeof(SubGhzProtocolDecoderIntertechno_V3)); - instance->base.protocol = &subghz_protocol_intertechno_v3; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_intertechno_v3_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderIntertechno_V3* instance = context; - free(instance); -} - -void subghz_protocol_decoder_intertechno_v3_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderIntertechno_V3* instance = context; - instance->decoder.parser_step = IntertechnoV3DecoderStepReset; -} - -void subghz_protocol_decoder_intertechno_v3_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderIntertechno_V3* instance = context; - switch(instance->decoder.parser_step) { - case IntertechnoV3DecoderStepReset: - if((!level) && - (DURATION_DIFF(duration, subghz_protocol_intertechno_v3_const.te_short * 37) < - subghz_protocol_intertechno_v3_const.te_delta * 15)) { - instance->decoder.parser_step = IntertechnoV3DecoderStepStartSync; - } - break; - case IntertechnoV3DecoderStepStartSync: - if(level && (DURATION_DIFF(duration, subghz_protocol_intertechno_v3_const.te_short) < - subghz_protocol_intertechno_v3_const.te_delta)) { - instance->decoder.parser_step = IntertechnoV3DecoderStepFoundSync; - } else { - instance->decoder.parser_step = IntertechnoV3DecoderStepReset; - } - break; - - case IntertechnoV3DecoderStepFoundSync: - if(!level && (DURATION_DIFF(duration, subghz_protocol_intertechno_v3_const.te_short * 10) < - subghz_protocol_intertechno_v3_const.te_delta * 3)) { - instance->decoder.parser_step = IntertechnoV3DecoderStepStartDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else { - instance->decoder.parser_step = IntertechnoV3DecoderStepReset; - } - break; - - case IntertechnoV3DecoderStepStartDuration: - if(level && (DURATION_DIFF(duration, subghz_protocol_intertechno_v3_const.te_short) < - subghz_protocol_intertechno_v3_const.te_delta)) { - instance->decoder.parser_step = IntertechnoV3DecoderStepSaveDuration; - } else { - instance->decoder.parser_step = IntertechnoV3DecoderStepReset; - } - break; - - case IntertechnoV3DecoderStepSaveDuration: - if(!level) { //save interval - if(duration >= (subghz_protocol_intertechno_v3_const.te_short * 11)) { - instance->decoder.parser_step = IntertechnoV3DecoderStepStartSync; - if((instance->decoder.decode_count_bit == - subghz_protocol_intertechno_v3_const.min_count_bit_for_found) || - (instance->decoder.decode_count_bit == INTERTECHNO_V3_DIMMING_COUNT_BIT)) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - break; - } - instance->decoder.te_last = duration; - instance->decoder.parser_step = IntertechnoV3DecoderStepCheckDuration; - } else { - instance->decoder.parser_step = IntertechnoV3DecoderStepReset; - } - break; - case IntertechnoV3DecoderStepCheckDuration: - if(level) { - //Add 0 bit - if((DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_intertechno_v3_const.te_short) < - subghz_protocol_intertechno_v3_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_intertechno_v3_const.te_short) < - subghz_protocol_intertechno_v3_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = IntertechnoV3DecoderStepEndDuration; - } else if( - //Add 1 bit - (DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_intertechno_v3_const.te_long) < - subghz_protocol_intertechno_v3_const.te_delta * 2) && - (DURATION_DIFF(duration, subghz_protocol_intertechno_v3_const.te_short) < - subghz_protocol_intertechno_v3_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = IntertechnoV3DecoderStepEndDuration; - - } else if( - //Add dimm_state - (DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_intertechno_v3_const.te_short) < - subghz_protocol_intertechno_v3_const.te_delta * 2) && - (DURATION_DIFF(duration, subghz_protocol_intertechno_v3_const.te_short) < - subghz_protocol_intertechno_v3_const.te_delta) && - (instance->decoder.decode_count_bit == 27)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = IntertechnoV3DecoderStepEndDuration; - - } else - instance->decoder.parser_step = IntertechnoV3DecoderStepReset; - } else { - instance->decoder.parser_step = IntertechnoV3DecoderStepReset; - } - break; - - case IntertechnoV3DecoderStepEndDuration: - if(!level && ((DURATION_DIFF(duration, subghz_protocol_intertechno_v3_const.te_short) < - subghz_protocol_intertechno_v3_const.te_delta) || - (DURATION_DIFF(duration, subghz_protocol_intertechno_v3_const.te_long) < - subghz_protocol_intertechno_v3_const.te_delta * 2))) { - instance->decoder.parser_step = IntertechnoV3DecoderStepStartDuration; - } else { - instance->decoder.parser_step = IntertechnoV3DecoderStepReset; - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - */ -static void subghz_protocol_intertechno_v3_check_remote_controller(SubGhzBlockGeneric* instance) { - /* - * A frame is either 32 or 36 bits: - * - * _ - * start bit: | |__________ (T,10T) - * _ _ - * '0': | |_| |_____ (T,T,T,5T) - * _ _ - * '1': | |_____| |_ (T,5T,T,T) - * _ _ - * dimm: | |_| |_ (T,T,T,T) - * - * _ - * stop bit: | |____...____ (T,38T) - * - * if frame 32 bits - * SSSSSSSSSSSSSSSSSSSSSSSSSS all_ch on/off ~ch - * Key:0x3F86C59F => 00111111100001101100010110 0 1 1111 - * - * if frame 36 bits - * SSSSSSSSSSSSSSSSSSSSSSSSSS all_ch dimm ~ch dimm_level - * Key:0x42D2E8856 => 01000010110100101110100010 0 X 0101 0110 - * - */ - - if(instance->data_count_bit == subghz_protocol_intertechno_v3_const.min_count_bit_for_found) { - instance->serial = (instance->data >> 6) & 0x3FFFFFF; - if((instance->data >> 5) & 0x1) { - instance->cnt = 1 << 5; - } else { - instance->cnt = (~instance->data & 0xF); - } - instance->btn = (instance->data >> 4) & 0x1; - } else if(instance->data_count_bit == INTERTECHNO_V3_DIMMING_COUNT_BIT) { - instance->serial = (instance->data >> 10) & 0x3FFFFFF; - if((instance->data >> 9) & 0x1) { - instance->cnt = 1 << 5; - } else { - instance->cnt = (~(instance->data >> 4) & 0xF); - } - instance->btn = (instance->data) & 0xF; - } else { - instance->serial = 0; - instance->cnt = 0; - instance->btn = 0; - } -} - -uint8_t subghz_protocol_decoder_intertechno_v3_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderIntertechno_V3* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_intertechno_v3_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderIntertechno_V3* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_intertechno_v3_deserialize( - void* context, - FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderIntertechno_V3* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if((instance->generic.data_count_bit != - subghz_protocol_intertechno_v3_const.min_count_bit_for_found) && - (instance->generic.data_count_bit != INTERTECHNO_V3_DIMMING_COUNT_BIT)) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_intertechno_v3_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderIntertechno_V3* instance = context; - - subghz_protocol_intertechno_v3_check_remote_controller(&instance->generic); - - furi_string_cat_printf( - output, - "%.11s %db\r\n" - "Key:0x%08llX\r\n" - "Sn:%07lX\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - instance->generic.data, - instance->generic.serial); - - if(instance->generic.data_count_bit == - subghz_protocol_intertechno_v3_const.min_count_bit_for_found) { - if(instance->generic.cnt >> 5) { - furi_string_cat_printf( - output, "Ch: All Btn:%s\r\n", (instance->generic.btn ? "On" : "Off")); - } else { - furi_string_cat_printf( - output, - "Ch:" CH_PATTERN " Btn:%s\r\n", - CNT_TO_CH(instance->generic.cnt), - (instance->generic.btn ? "On" : "Off")); - } - } else if(instance->generic.data_count_bit == INTERTECHNO_V3_DIMMING_COUNT_BIT) { - furi_string_cat_printf( - output, - "Ch:" CH_PATTERN " Dimm:%d%%\r\n", - CNT_TO_CH(instance->generic.cnt), - (int)(6.67 * (float)instance->generic.btn)); - } -} diff --git a/applications/main/subghz/protocols/intertechno_v3.h b/applications/main/subghz/protocols/intertechno_v3.h deleted file mode 100644 index ffee14b04..000000000 --- a/applications/main/subghz/protocols/intertechno_v3.h +++ /dev/null @@ -1,111 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_INTERTECHNO_V3_NAME "Intertechno_V3" - -typedef struct SubGhzProtocolDecoderIntertechno_V3 SubGhzProtocolDecoderIntertechno_V3; -typedef struct SubGhzProtocolEncoderIntertechno_V3 SubGhzProtocolEncoderIntertechno_V3; - -extern const SubGhzProtocolDecoder subghz_protocol_intertechno_v3_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_intertechno_v3_encoder; -extern const SubGhzProtocol subghz_protocol_intertechno_v3; - -/** - * Allocate SubGhzProtocolEncoderIntertechno_V3. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderIntertechno_V3* pointer to a SubGhzProtocolEncoderIntertechno_V3 instance - */ -void* subghz_protocol_encoder_intertechno_v3_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderIntertechno_V3. - * @param context Pointer to a SubGhzProtocolEncoderIntertechno_V3 instance - */ -void subghz_protocol_encoder_intertechno_v3_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderIntertechno_V3 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_intertechno_v3_deserialize( - void* context, - FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderIntertechno_V3 instance - */ -void subghz_protocol_encoder_intertechno_v3_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderIntertechno_V3 instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_intertechno_v3_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderIntertechno_V3. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderIntertechno_V3* pointer to a SubGhzProtocolDecoderIntertechno_V3 instance - */ -void* subghz_protocol_decoder_intertechno_v3_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderIntertechno_V3. - * @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance - */ -void subghz_protocol_decoder_intertechno_v3_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderIntertechno_V3. - * @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance - */ -void subghz_protocol_decoder_intertechno_v3_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_intertechno_v3_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_intertechno_v3_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderIntertechno_V3. - * @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_intertechno_v3_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderIntertechno_V3. - * @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_intertechno_v3_deserialize( - void* context, - FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderIntertechno_V3 instance - * @param output Resulting text - */ -void subghz_protocol_decoder_intertechno_v3_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/keeloq.c b/applications/main/subghz/protocols/keeloq.c deleted file mode 100644 index a0970de4d..000000000 --- a/applications/main/subghz/protocols/keeloq.c +++ /dev/null @@ -1,1115 +0,0 @@ -#include "keeloq.h" -#include "keeloq_common.h" - -#include "../subghz_keystore.h" -#include - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolKeeloq" - -static const SubGhzBlockConst subghz_protocol_keeloq_const = { - .te_short = 400, - .te_long = 800, - .te_delta = 140, - .min_count_bit_for_found = 64, -}; - -struct SubGhzProtocolDecoderKeeloq { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - - uint16_t header_count; - SubGhzKeystore* keystore; - const char* manufacture_name; - - FuriString* manufacture_from_file; -}; - -struct SubGhzProtocolEncoderKeeloq { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; - - SubGhzKeystore* keystore; - const char* manufacture_name; - - FuriString* manufacture_from_file; -}; - -typedef enum { - KeeloqDecoderStepReset = 0, - KeeloqDecoderStepCheckPreambula, - KeeloqDecoderStepSaveDuration, - KeeloqDecoderStepCheckDuration, -} KeeloqDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_keeloq_decoder = { - .alloc = subghz_protocol_decoder_keeloq_alloc, - .free = subghz_protocol_decoder_keeloq_free, - - .feed = subghz_protocol_decoder_keeloq_feed, - .reset = subghz_protocol_decoder_keeloq_reset, - - .get_hash_data = subghz_protocol_decoder_keeloq_get_hash_data, - .serialize = subghz_protocol_decoder_keeloq_serialize, - .deserialize = subghz_protocol_decoder_keeloq_deserialize, - .get_string = subghz_protocol_decoder_keeloq_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_keeloq_encoder = { - .alloc = subghz_protocol_encoder_keeloq_alloc, - .free = subghz_protocol_encoder_keeloq_free, - - .deserialize = subghz_protocol_encoder_keeloq_deserialize, - .stop = subghz_protocol_encoder_keeloq_stop, - .yield = subghz_protocol_encoder_keeloq_yield, -}; - -const SubGhzProtocol subghz_protocol_keeloq = { - .name = SUBGHZ_PROTOCOL_KEELOQ_NAME, - .type = SubGhzProtocolTypeDynamic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_868 | SubGhzProtocolFlag_315 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | - SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_keeloq_decoder, - .encoder = &subghz_protocol_keeloq_encoder, -}; - -static const char* mfname; -static int kl_type; - -void keeloq_reset_mfname() { - mfname = ""; -} - -void keeloq_reset_kl_type() { - kl_type = 0; -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - * @param keystore Pointer to a SubGhzKeystore* instance - * @param manufacture_name - */ -static void subghz_protocol_keeloq_check_remote_controller( - SubGhzBlockGeneric* instance, - SubGhzKeystore* keystore, - const char** manufacture_name); - -void* subghz_protocol_encoder_keeloq_alloc(SubGhzEnvironment* environment) { - SubGhzProtocolEncoderKeeloq* instance = malloc(sizeof(SubGhzProtocolEncoderKeeloq)); - - instance->base.protocol = &subghz_protocol_keeloq; - instance->generic.protocol_name = instance->base.protocol->name; - instance->keystore = subghz_environment_get_keystore(environment); - - instance->encoder.repeat = 100; - instance->encoder.size_upload = 256; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - - instance->manufacture_from_file = furi_string_alloc(); - - return instance; -} - -void subghz_protocol_encoder_keeloq_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderKeeloq* instance = context; - furi_string_free(instance->manufacture_from_file); - free(instance->encoder.upload); - free(instance); -} - -/** - * Key generation from simple data - * @param instance Pointer to a SubGhzProtocolEncoderKeeloq* instance - * @param btn Button number, 4 bit - */ -static bool subghz_protocol_keeloq_gen_data(SubGhzProtocolEncoderKeeloq* instance, uint8_t btn) { - if(instance->generic.cnt < 0xFFFF) { - instance->generic.cnt++; - } else if(instance->generic.cnt >= 0xFFFF) { - instance->generic.cnt = 0; - } - uint32_t fix = (uint32_t)btn << 28 | instance->generic.serial; - uint32_t decrypt = (uint32_t)btn << 28 | - (instance->generic.serial & 0x3FF) - << 16 | //ToDo in some protocols the discriminator is 0 - instance->generic.cnt; - uint32_t hop = 0; - uint64_t man = 0; - uint64_t code_found_reverse; - int res = 0; - if(instance->manufacture_name == 0x0) { - instance->manufacture_name = ""; - } - - // DTM Neo uses 12bit -> simple learning -- FAAC_RC,XT , Mutanco_Mutancode -> 12bit normal learning - if((strcmp(instance->manufacture_name, "DTM_Neo") == 0) || - (strcmp(instance->manufacture_name, "FAAC_RC,XT") == 0) || - (strcmp(instance->manufacture_name, "Mutanco_Mutancode") == 0)) { - decrypt = btn << 28 | (instance->generic.serial & 0xFFF) << 16 | instance->generic.cnt; - } - - // Nice Smilo, MHouse, JCM, Normstahl -> 8bit serial - simple learning - if((strcmp(instance->manufacture_name, "NICE_Smilo") == 0) || - (strcmp(instance->manufacture_name, "NICE_MHOUSE") == 0) || - (strcmp(instance->manufacture_name, "JCM_Tech") == 0) || - (strcmp(instance->manufacture_name, "Normstahl") == 0)) { - decrypt = btn << 28 | (instance->generic.serial & 0xFF) << 16 | instance->generic.cnt; - } - - if(strcmp(instance->manufacture_name, "Unknown") == 0) { - code_found_reverse = subghz_protocol_blocks_reverse_key( - instance->generic.data, instance->generic.data_count_bit); - hop = code_found_reverse & 0x00000000ffffffff; - } else if(strcmp(instance->manufacture_name, "AN-Motors") == 0) { - hop = (instance->generic.cnt & 0xFF) << 24 | (instance->generic.cnt & 0xFF) << 16 | - (instance->generic.btn & 0xF) << 12 | 0x404; - } else if(strcmp(instance->manufacture_name, "HCS101") == 0) { - hop = instance->generic.cnt << 16 | (instance->generic.btn & 0xF) << 12 | 0x000; - } else { - for - M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) { - res = strcmp(furi_string_get_cstr(manufacture_code->name), instance->manufacture_name); - if(res == 0) { - switch(manufacture_code->type) { - case KEELOQ_LEARNING_SIMPLE: - //Simple Learning - hop = subghz_protocol_keeloq_common_encrypt(decrypt, manufacture_code->key); - break; - case KEELOQ_LEARNING_NORMAL: - //Simple Learning - man = - subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); - hop = subghz_protocol_keeloq_common_encrypt(decrypt, man); - break; - case KEELOQ_LEARNING_SECURE: - //Secure Learning - man = subghz_protocol_keeloq_common_secure_learning( - fix, instance->generic.seed, manufacture_code->key); - hop = subghz_protocol_keeloq_common_encrypt(decrypt, man); - break; - case KEELOQ_LEARNING_MAGIC_XOR_TYPE_1: - //Magic XOR type-1 Learning - man = subghz_protocol_keeloq_common_magic_xor_type1_learning( - instance->generic.serial, manufacture_code->key); - hop = subghz_protocol_keeloq_common_encrypt(decrypt, man); - break; - case KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_1: - //Magic Serial Type 1 learning - man = subghz_protocol_keeloq_common_magic_serial_type1_learning( - fix, manufacture_code->key); - hop = subghz_protocol_keeloq_common_encrypt(decrypt, man); - break; - case KEELOQ_LEARNING_UNKNOWN: - if(kl_type == 1) { - hop = - subghz_protocol_keeloq_common_encrypt(decrypt, manufacture_code->key); - } - if(kl_type == 2) { - man = subghz_protocol_keeloq_common_normal_learning( - fix, manufacture_code->key); - hop = subghz_protocol_keeloq_common_encrypt(decrypt, man); - } - if(kl_type == 3) { - man = subghz_protocol_keeloq_common_secure_learning( - fix, instance->generic.seed, manufacture_code->key); - hop = subghz_protocol_keeloq_common_encrypt(decrypt, man); - } - if(kl_type == 4) { - man = subghz_protocol_keeloq_common_magic_xor_type1_learning( - instance->generic.serial, manufacture_code->key); - hop = subghz_protocol_keeloq_common_encrypt(decrypt, man); - } - break; - } - break; - } - } - } - if(hop) { - uint64_t yek = (uint64_t)fix << 32 | hop; - instance->generic.data = - subghz_protocol_blocks_reverse_key(yek, instance->generic.data_count_bit); - } - return true; -} - -bool subghz_protocol_keeloq_create_data( - void* context, - FlipperFormat* flipper_format, - uint32_t serial, - uint8_t btn, - uint16_t cnt, - const char* manufacture_name, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolEncoderKeeloq* instance = context; - instance->generic.serial = serial; - instance->generic.cnt = cnt; - instance->manufacture_name = manufacture_name; - instance->generic.data_count_bit = 64; - bool res = subghz_protocol_keeloq_gen_data(instance, btn); - if(res) { - res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); - } - return res; -} - -bool subghz_protocol_keeloq_bft_create_data( - void* context, - FlipperFormat* flipper_format, - uint32_t serial, - uint8_t btn, - uint16_t cnt, - uint32_t seed, - const char* manufacture_name, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolEncoderKeeloq* instance = context; - instance->generic.serial = serial; - instance->generic.btn = btn; - instance->generic.cnt = cnt; - instance->generic.seed = seed; - instance->manufacture_name = manufacture_name; - instance->generic.data_count_bit = 64; - // roguuemaster don't steal.!!!! - bool res = subghz_protocol_keeloq_gen_data(instance, btn); - if(res) { - res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); - } - return res; -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderKeeloq instance - * @return true On success - */ -static bool - subghz_protocol_encoder_keeloq_get_upload(SubGhzProtocolEncoderKeeloq* instance, uint8_t btn) { - furi_assert(instance); - - //gen new key - if(subghz_protocol_keeloq_gen_data(instance, btn)) { - //ToDo if you need to add a callback to automatically update the data on the display - } else { - return false; - } - - size_t index = 0; - size_t size_upload = 11 * 2 + 2 + (instance->generic.data_count_bit * 2) + 4; - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - - //Send header - for(uint8_t i = 11; i > 0; i--) { - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_keeloq_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_keeloq_const.te_short); - } - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_keeloq_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_keeloq_const.te_short * 10); - - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_keeloq_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_keeloq_const.te_long); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_keeloq_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_keeloq_const.te_short); - } - } - // +send 2 status bit - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_keeloq_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_keeloq_const.te_long); - // send end - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_keeloq_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_keeloq_const.te_short * 40); - - return true; -} - -bool subghz_protocol_encoder_keeloq_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderKeeloq* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_keeloq_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - - uint8_t seed_data[sizeof(uint32_t)] = {0}; - for(size_t i = 0; i < sizeof(uint32_t); i++) { - seed_data[sizeof(uint32_t) - i - 1] = (instance->generic.seed >> i * 8) & 0xFF; - } - if(!flipper_format_read_hex(flipper_format, "Seed", seed_data, sizeof(uint32_t))) { - FURI_LOG_D(TAG, "ENCODER: Missing Seed"); - } - instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 | - seed_data[3]; - - // Read manufacturer from file - if(flipper_format_read_string( - flipper_format, "Manufacture", instance->manufacture_from_file)) { - instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); - mfname = furi_string_get_cstr(instance->manufacture_from_file); - } else { - FURI_LOG_D(TAG, "ENCODER: Missing Manufacture"); - } - - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - - subghz_protocol_keeloq_check_remote_controller( - &instance->generic, instance->keystore, &instance->manufacture_name); - - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_keeloq_get_upload(instance, instance->generic.btn)) break; - - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - uint8_t key_data[sizeof(uint64_t)] = {0}; - for(size_t i = 0; i < sizeof(uint64_t); i++) { - key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data >> (i * 8)) & 0xFF; - } - if(!flipper_format_update_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Unable to add Key"); - break; - } - - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_keeloq_stop(void* context) { - SubGhzProtocolEncoderKeeloq* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_keeloq_yield(void* context) { - SubGhzProtocolEncoderKeeloq* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_keeloq_alloc(SubGhzEnvironment* environment) { - SubGhzProtocolDecoderKeeloq* instance = malloc(sizeof(SubGhzProtocolDecoderKeeloq)); - instance->base.protocol = &subghz_protocol_keeloq; - instance->generic.protocol_name = instance->base.protocol->name; - instance->keystore = subghz_environment_get_keystore(environment); - instance->manufacture_from_file = furi_string_alloc(); - - return instance; -} - -void subghz_protocol_decoder_keeloq_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderKeeloq* instance = context; - furi_string_free(instance->manufacture_from_file); - - free(instance); -} - -void subghz_protocol_decoder_keeloq_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderKeeloq* instance = context; - instance->decoder.parser_step = KeeloqDecoderStepReset; - mfname = ""; - kl_type = 0; -} - -void subghz_protocol_decoder_keeloq_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderKeeloq* instance = context; - - switch(instance->decoder.parser_step) { - case KeeloqDecoderStepReset: - if((level) && DURATION_DIFF(duration, subghz_protocol_keeloq_const.te_short) < - subghz_protocol_keeloq_const.te_delta) { - instance->decoder.parser_step = KeeloqDecoderStepCheckPreambula; - instance->header_count++; - } - break; - case KeeloqDecoderStepCheckPreambula: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_keeloq_const.te_short) < - subghz_protocol_keeloq_const.te_delta)) { - instance->decoder.parser_step = KeeloqDecoderStepReset; - break; - } - if((instance->header_count > 2) && - (DURATION_DIFF(duration, subghz_protocol_keeloq_const.te_short * 10) < - subghz_protocol_keeloq_const.te_delta * 10)) { - // Found header - instance->decoder.parser_step = KeeloqDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else { - instance->decoder.parser_step = KeeloqDecoderStepReset; - instance->header_count = 0; - } - break; - case KeeloqDecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = KeeloqDecoderStepCheckDuration; - } - break; - case KeeloqDecoderStepCheckDuration: - if(!level) { - if(duration >= ((uint32_t)subghz_protocol_keeloq_const.te_short * 2 + - subghz_protocol_keeloq_const.te_delta)) { - // Found end TX - instance->decoder.parser_step = KeeloqDecoderStepReset; - if((instance->decoder.decode_count_bit >= - subghz_protocol_keeloq_const.min_count_bit_for_found) && - (instance->decoder.decode_count_bit <= - subghz_protocol_keeloq_const.min_count_bit_for_found + 2)) { - if(instance->generic.data != instance->decoder.decode_data) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = - subghz_protocol_keeloq_const.min_count_bit_for_found; - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->header_count = 0; - } - break; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_keeloq_const.te_short) < - subghz_protocol_keeloq_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_keeloq_const.te_long) < - subghz_protocol_keeloq_const.te_delta * 2)) { - if(instance->decoder.decode_count_bit < - subghz_protocol_keeloq_const.min_count_bit_for_found) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - } else { - instance->decoder.decode_count_bit++; - } - instance->decoder.parser_step = KeeloqDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_keeloq_const.te_long) < - subghz_protocol_keeloq_const.te_delta * 2) && - (DURATION_DIFF(duration, subghz_protocol_keeloq_const.te_short) < - subghz_protocol_keeloq_const.te_delta)) { - if(instance->decoder.decode_count_bit < - subghz_protocol_keeloq_const.min_count_bit_for_found) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - } else { - instance->decoder.decode_count_bit++; - } - instance->decoder.parser_step = KeeloqDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = KeeloqDecoderStepReset; - instance->header_count = 0; - } - } else { - instance->decoder.parser_step = KeeloqDecoderStepReset; - instance->header_count = 0; - } - break; - } -} - -/** - * Validation of decrypt data. - * @param instance Pointer to a SubGhzBlockGeneric instance - * @param decrypt Decrypd data - * @param btn Button number, 4 bit - * @param end_serial decrement the last 10 bits of the serial number - * @return true On success - */ -static inline bool subghz_protocol_keeloq_check_decrypt( - SubGhzBlockGeneric* instance, - uint32_t decrypt, - uint8_t btn, - uint32_t end_serial) { - furi_assert(instance); - if((decrypt >> 28 == btn) && (((((uint16_t)(decrypt >> 16)) & 0xFF) == end_serial) || - ((((uint16_t)(decrypt >> 16)) & 0xFF) == 0))) { - instance->cnt = decrypt & 0x0000FFFF; - return true; - } - return false; -} - -/** - * Checking the accepted code against the database manafacture key - * @param instance Pointer to a SubGhzBlockGeneric* instance - * @param fix Fix part of the parcel - * @param hop Hop encrypted part of the parcel - * @param keystore Pointer to a SubGhzKeystore* instance - * @param manufacture_name - * @return true on successful search - */ -static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( - SubGhzBlockGeneric* instance, - uint32_t fix, - uint32_t hop, - SubGhzKeystore* keystore, - const char** manufacture_name) { - // protocol HCS300 uses 10 bits in discriminator, HCS200 uses 8 bits, for backward compatibility, we are looking for the 8-bit pattern - // HCS300 -> uint16_t end_serial = (uint16_t)(fix & 0x3FF); - // HCS200 -> uint16_t end_serial = (uint16_t)(fix & 0xFF); - - uint16_t end_serial = (uint16_t)(fix & 0xFF); - uint8_t btn = (uint8_t)(fix >> 28); - uint32_t decrypt = 0; - uint64_t man; - int res = 0; - if(mfname == 0x0) { - mfname = ""; - } - - if(strcmp(mfname, "") == 0) { - for - M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) { - switch(manufacture_code->type) { - case KEELOQ_LEARNING_SIMPLE: - // Simple Learning - decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - return 1; - } - break; - case KEELOQ_LEARNING_NORMAL: - // Normal Learning - // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 - man = subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - return 1; - } - break; - case KEELOQ_LEARNING_SECURE: - man = subghz_protocol_keeloq_common_secure_learning( - fix, instance->seed, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - return 1; - } - break; - case KEELOQ_LEARNING_MAGIC_XOR_TYPE_1: - man = subghz_protocol_keeloq_common_magic_xor_type1_learning( - fix, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - return 1; - } - break; - case KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_1: - man = subghz_protocol_keeloq_common_magic_serial_type1_learning( - fix, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - return 1; - } - break; - case KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_2: - man = subghz_protocol_keeloq_common_magic_serial_type2_learning( - fix, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - return 1; - } - break; - case KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_3: - man = subghz_protocol_keeloq_common_magic_serial_type3_learning( - fix, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - return 1; - } - break; - case KEELOQ_LEARNING_UNKNOWN: - // Simple Learning - decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 1; - return 1; - } - - // Check for mirrored man - uint64_t man_rev = 0; - uint64_t man_rev_byte = 0; - for(uint8_t i = 0; i < 64; i += 8) { - man_rev_byte = (uint8_t)(manufacture_code->key >> i); - man_rev = man_rev | man_rev_byte << (56 - i); - } - - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 1; - return 1; - } - - //########################### - // Normal Learning - // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 - man = subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 2; - return 1; - } - - // Check for mirrored man - man = subghz_protocol_keeloq_common_normal_learning(fix, man_rev); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 2; - return 1; - } - - // Secure Learning - man = subghz_protocol_keeloq_common_secure_learning( - fix, instance->seed, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 3; - return 1; - } - - // Check for mirrored man - man = subghz_protocol_keeloq_common_secure_learning(fix, instance->seed, man_rev); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 3; - return 1; - } - - // Magic xor type1 learning - man = subghz_protocol_keeloq_common_magic_xor_type1_learning( - fix, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 4; - return 1; - } - - // Check for mirrored man - man = subghz_protocol_keeloq_common_magic_xor_type1_learning(fix, man_rev); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 4; - return 1; - } - - break; - } - } - } else if(strcmp(mfname, "Unknown") == 0) { - return 1; - } else { - for - M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) { - res = strcmp(furi_string_get_cstr(manufacture_code->name), mfname); - if(res == 0) { - switch(manufacture_code->type) { - case KEELOQ_LEARNING_SIMPLE: - // Simple Learning - decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - return 1; - } - break; - case KEELOQ_LEARNING_NORMAL: - // Normal Learning - // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 - man = - subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - return 1; - } - break; - case KEELOQ_LEARNING_SECURE: - man = subghz_protocol_keeloq_common_secure_learning( - fix, instance->seed, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - return 1; - } - break; - case KEELOQ_LEARNING_MAGIC_XOR_TYPE_1: - man = subghz_protocol_keeloq_common_magic_xor_type1_learning( - fix, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - return 1; - } - break; - case KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_1: - man = subghz_protocol_keeloq_common_magic_serial_type1_learning( - fix, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - return 1; - } - break; - case KEELOQ_LEARNING_UNKNOWN: - // Simple Learning - decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 1; - return 1; - } - // Check for mirrored man - uint64_t man_rev = 0; - uint64_t man_rev_byte = 0; - for(uint8_t i = 0; i < 64; i += 8) { - man_rev_byte = (uint8_t)(manufacture_code->key >> i); - man_rev = man_rev | man_rev_byte << (56 - i); - } - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 1; - return 1; - } - //########################### - // Normal Learning - // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 - man = - subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 2; - return 1; - } - - // Check for mirrored man - man = subghz_protocol_keeloq_common_normal_learning(fix, man_rev); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 2; - return 1; - } - - // Secure Learning - man = subghz_protocol_keeloq_common_secure_learning( - fix, instance->seed, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 3; - return 1; - } - - // Check for mirrored man - man = subghz_protocol_keeloq_common_secure_learning( - fix, instance->seed, man_rev); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 3; - return 1; - } - - // Magic xor type1 learning - man = subghz_protocol_keeloq_common_magic_xor_type1_learning( - fix, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 4; - return 1; - } - - // Check for mirrored man - man = subghz_protocol_keeloq_common_magic_xor_type1_learning(fix, man_rev); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 4; - return 1; - } - - break; - } - } - } - } - - *manufacture_name = "Unknown"; - mfname = "Unknown"; - instance->cnt = 0; - - return 0; -} - -static void subghz_protocol_keeloq_check_remote_controller( - SubGhzBlockGeneric* instance, - SubGhzKeystore* keystore, - const char** manufacture_name) { - uint64_t key = subghz_protocol_blocks_reverse_key(instance->data, instance->data_count_bit); - 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) && (key_hop & 0xFFF) == 0x404) { - *manufacture_name = "AN-Motors"; - mfname = *manufacture_name; - instance->cnt = key_hop >> 16; - } else if((key_hop & 0xFFF) == (0x000) && (key_fix >> 28) == ((key_hop >> 12) & 0x0f)) { - *manufacture_name = "HCS101"; - mfname = *manufacture_name; - instance->cnt = key_hop >> 16; - } else { - subghz_protocol_keeloq_check_remote_controller_selector( - instance, key_fix, key_hop, keystore, manufacture_name); - } - - instance->serial = key_fix & 0x0FFFFFFF; - instance->btn = key_fix >> 28; -} - -uint8_t subghz_protocol_decoder_keeloq_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderKeeloq* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_keeloq_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderKeeloq* instance = context; - - bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); - - subghz_protocol_keeloq_check_remote_controller( - &instance->generic, instance->keystore, &instance->manufacture_name); - - if(strcmp(instance->manufacture_name, "BFT") == 0) { - uint8_t seed_data[sizeof(uint32_t)] = {0}; - for(size_t i = 0; i < sizeof(uint32_t); i++) { - seed_data[sizeof(uint32_t) - i - 1] = (instance->generic.seed >> i * 8) & 0xFF; - } - if(res && !flipper_format_write_hex(flipper_format, "Seed", seed_data, sizeof(uint32_t))) { - FURI_LOG_E(TAG, "DECODER Serialize: Unable to add Seed"); - res = false; - } - instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 | - seed_data[3]; - } - - if(res && !flipper_format_write_string_cstr( - flipper_format, "Manufacture", instance->manufacture_name)) { - FURI_LOG_E(TAG, "DECODER Serialize: Unable to add manufacture name"); - res = false; - } - return res; -} - -bool subghz_protocol_decoder_keeloq_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderKeeloq* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_keeloq_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - - uint8_t seed_data[sizeof(uint32_t)] = {0}; - for(size_t i = 0; i < sizeof(uint32_t); i++) { - seed_data[sizeof(uint32_t) - i - 1] = (instance->generic.seed >> i * 8) & 0xFF; - } - if(!flipper_format_read_hex(flipper_format, "Seed", seed_data, sizeof(uint32_t))) { - FURI_LOG_D(TAG, "DECODER: Missing Seed"); - } - instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 | - seed_data[3]; - - // Read manufacturer from file - if(flipper_format_read_string( - flipper_format, "Manufacture", instance->manufacture_from_file)) { - instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); - mfname = furi_string_get_cstr(instance->manufacture_from_file); - } else { - FURI_LOG_D(TAG, "DECODER: Missing Manufacture"); - } - - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderKeeloq* instance = context; - - subghz_protocol_keeloq_check_remote_controller( - &instance->generic, instance->keystore, &instance->manufacture_name); - - uint32_t code_found_hi = instance->generic.data >> 32; - uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; - - uint64_t code_found_reverse = subghz_protocol_blocks_reverse_key( - instance->generic.data, instance->generic.data_count_bit); - uint32_t code_found_reverse_hi = code_found_reverse >> 32; - uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - - if(strcmp(instance->manufacture_name, "BFT") == 0) { - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:%08lX%08lX\r\n" - "Fix:0x%08lX Cnt:%04lX\r\n" - "Hop:0x%08lX Btn:%01X\r\n" - "MF:%s Sd:%08lX", - instance->generic.protocol_name, - instance->generic.data_count_bit, - code_found_hi, - code_found_lo, - code_found_reverse_hi, - instance->generic.cnt, - code_found_reverse_lo, - instance->generic.btn, - instance->manufacture_name, - instance->generic.seed); - } else { - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:%08lX%08lX\r\n" - "Fix:0x%08lX Cnt:%04lX\r\n" - "Hop:0x%08lX Btn:%01X\r\n" - "MF:%s", - instance->generic.protocol_name, - instance->generic.data_count_bit, - code_found_hi, - code_found_lo, - code_found_reverse_hi, - instance->generic.cnt, - code_found_reverse_lo, - instance->generic.btn, - instance->manufacture_name); - } -} diff --git a/applications/main/subghz/protocols/keeloq.h b/applications/main/subghz/protocols/keeloq.h deleted file mode 100644 index 7b0cfc3bd..000000000 --- a/applications/main/subghz/protocols/keeloq.h +++ /dev/null @@ -1,153 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_KEELOQ_NAME "KeeLoq" - -typedef struct SubGhzProtocolDecoderKeeloq SubGhzProtocolDecoderKeeloq; -typedef struct SubGhzProtocolEncoderKeeloq SubGhzProtocolEncoderKeeloq; - -extern const SubGhzProtocolDecoder subghz_protocol_keeloq_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_keeloq_encoder; -extern const SubGhzProtocol subghz_protocol_keeloq; - -void keeloq_reset_mfname(); - -void keeloq_reset_kl_type(); - -/** - * Allocate SubGhzProtocolEncoderKeeloq. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderKeeloq* pointer to a SubGhzProtocolEncoderKeeloq instance - */ -void* subghz_protocol_encoder_keeloq_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderKeeloq. - * @param context Pointer to a SubGhzProtocolEncoderKeeloq instance - */ -void subghz_protocol_encoder_keeloq_free(void* context); - -/** - * Key generation from simple data. - * @param context Pointer to a SubGhzProtocolEncoderKeeloq instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param serial Serial number, 28 bit - * @param btn Button number, 4 bit - * @param cnt Counter value, 16 bit - * @param manufacture_name Name of manufacturer's key - * @param preset Modulation, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_keeloq_create_data( - void* context, - FlipperFormat* flipper_format, - uint32_t serial, - uint8_t btn, - uint16_t cnt, - const char* manufacture_name, - SubGhzRadioPreset* preset); - -/** - * Key generation for BFT. - * @param context Pointer to a SubGhzProtocolEncoderKeeloq instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param serial Serial number, 28 bit - * @param btn Button number, 4 bit - * @param cnt Counter value, 16 bit - * @param seed Seed value, 32 bit - * @param manufacture_name Name of manufacturer's key - * @param preset Modulation, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_keeloq_bft_create_data( - void* context, - FlipperFormat* flipper_format, - uint32_t serial, - uint8_t btn, - uint16_t cnt, - uint32_t seed, - const char* manufacture_name, - SubGhzRadioPreset* preset); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderKeeloq instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_keeloq_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderKeeloq instance - */ -void subghz_protocol_encoder_keeloq_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderKeeloq instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_keeloq_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderKeeloq. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderKeeloq* pointer to a SubGhzProtocolDecoderKeeloq instance - */ -void* subghz_protocol_decoder_keeloq_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderKeeloq. - * @param context Pointer to a SubGhzProtocolDecoderKeeloq instance - */ -void subghz_protocol_decoder_keeloq_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderKeeloq. - * @param context Pointer to a SubGhzProtocolDecoderKeeloq instance - */ -void subghz_protocol_decoder_keeloq_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderKeeloq instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_keeloq_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderKeeloq instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_keeloq_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderKeeloq. - * @param context Pointer to a SubGhzProtocolDecoderKeeloq instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_keeloq_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderKeeloq. - * @param context Pointer to a SubGhzProtocolDecoderKeeloq instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_keeloq_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderKeeloq instance - * @param output Resulting text - */ -void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/keeloq_common.c b/applications/main/subghz/protocols/keeloq_common.c deleted file mode 100644 index 1d2d04457..000000000 --- a/applications/main/subghz/protocols/keeloq_common.c +++ /dev/null @@ -1,142 +0,0 @@ -#include "keeloq_common.h" - -#include - -#include - -#define bit(x, n) (((x) >> (n)) & 1) -#define g5(x, a, b, c, d, e) \ - (bit(x, a) + bit(x, b) * 2 + bit(x, c) * 4 + bit(x, d) * 8 + bit(x, e) * 16) - -/** Simple Learning Encrypt - * @param data - 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter - * @param key - manufacture (64bit) - * @return keeloq encrypt data - */ -inline uint32_t subghz_protocol_keeloq_common_encrypt(const uint32_t data, const uint64_t key) { - uint32_t x = data, r; - for(r = 0; r < 528; r++) - x = (x >> 1) ^ ((bit(x, 0) ^ bit(x, 16) ^ (uint32_t)bit(key, r & 63) ^ - bit(KEELOQ_NLF, g5(x, 1, 9, 20, 26, 31))) - << 31); - return x; -} - -/** Simple Learning Decrypt - * @param data - keelog encrypt data - * @param key - manufacture (64bit) - * @return 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter - */ -inline uint32_t subghz_protocol_keeloq_common_decrypt(const uint32_t data, const uint64_t key) { - uint32_t x = data, r; - for(r = 0; r < 528; r++) - x = (x << 1) ^ bit(x, 31) ^ bit(x, 15) ^ (uint32_t)bit(key, (15 - r) & 63) ^ - bit(KEELOQ_NLF, g5(x, 0, 8, 19, 25, 30)); - return x; -} - -/** Normal Learning - * @param data - serial number (28bit) - * @param key - manufacture (64bit) - * @return manufacture for this serial number (64bit) - */ -inline uint64_t subghz_protocol_keeloq_common_normal_learning(uint32_t data, const uint64_t key) { - uint32_t k1, k2; - - data &= 0x0FFFFFFF; - data |= 0x20000000; - k1 = subghz_protocol_keeloq_common_decrypt(data, key); - - data &= 0x0FFFFFFF; - data |= 0x60000000; - k2 = subghz_protocol_keeloq_common_decrypt(data, key); - - return ((uint64_t)k2 << 32) | k1; // key - shifrovanoya -} - -/** Secure Learning - * @param data - serial number (28bit) - * @param seed - seed number (32bit) - * @param key - manufacture (64bit) - * @return manufacture for this serial number (64bit) - */ - -inline uint64_t subghz_protocol_keeloq_common_secure_learning( - uint32_t data, - uint32_t seed, - const uint64_t key) { - uint32_t k1, k2; - - data &= 0x0FFFFFFF; - k1 = subghz_protocol_keeloq_common_decrypt(data, key); - k2 = subghz_protocol_keeloq_common_decrypt(seed, key); - - return ((uint64_t)k1 << 32) | k2; -} - -/** Magic_xor_type1 Learning - * @param data - serial number (28bit) - * @param xor - magic xor (64bit) - * @return manufacture for this serial number (64bit) - */ - -inline uint64_t - subghz_protocol_keeloq_common_magic_xor_type1_learning(uint32_t data, uint64_t xor) { - data &= 0x0FFFFFFF; - return (((uint64_t)data << 32) | data) ^ xor; -} - -/** Faac SLH (Spa) Learning - * @param seed - seed number (32bit) - * @param key - mfkey (64bit) - * @return man_learning for this seed number (64bit) - */ - -inline uint64_t - subghz_protocol_keeloq_common_faac_learning(const uint32_t seed, const uint64_t key) { - uint16_t hs = seed >> 16; - const uint16_t ending = 0x544D; - uint32_t lsb = (uint32_t)hs << 16 | ending; - uint64_t man = (uint64_t)subghz_protocol_keeloq_common_encrypt(seed, key) << 32 | - subghz_protocol_keeloq_common_encrypt(lsb, key); - return man; -} -/** Magic_serial_type1 Learning - * @param data - serial number (28bit) - * @param man - magic man (64bit) - * @return manufacture for this serial number (64bit) - */ - -inline uint64_t - subghz_protocol_keeloq_common_magic_serial_type1_learning(uint32_t data, uint64_t man) { - return (man & 0xFFFFFFFF) | ((uint64_t)data << 40) | - ((uint64_t)(((data & 0xff) + ((data >> 8) & 0xFF)) & 0xFF) << 32); -} - -/** Magic_serial_type2 Learning - * @param data - btn+serial number (32bit) - * @param man - magic man (64bit) - * @return manufacture for this serial number (64bit) - */ - -inline uint64_t - subghz_protocol_keeloq_common_magic_serial_type2_learning(uint32_t data, uint64_t man) { - uint8_t* p = (uint8_t*)&data; - uint8_t* m = (uint8_t*)&man; - m[7] = p[0]; - m[6] = p[1]; - m[5] = p[2]; - m[4] = p[3]; - return man; -} - -/** Magic_serial_type3 Learning - * @param data - serial number (24bit) - * @param man - magic man (64bit) - * @return manufacture for this serial number (64bit) - */ - -inline uint64_t - subghz_protocol_keeloq_common_magic_serial_type3_learning(uint32_t data, uint64_t man) { - return (man & 0xFFFFFFFFFF000000) | (data & 0xFFFFFF); -} diff --git a/applications/main/subghz/protocols/keeloq_common.h b/applications/main/subghz/protocols/keeloq_common.h deleted file mode 100644 index a6c0d346e..000000000 --- a/applications/main/subghz/protocols/keeloq_common.h +++ /dev/null @@ -1,100 +0,0 @@ -#pragma once - -#include "base.h" - -#include - -/* - * Keeloq - * https://ru.wikipedia.org/wiki/KeeLoq - * https://phreakerclub.com/forum/showthread.php?t=1094 - * - */ -#define KEELOQ_NLF 0x3A5C742E - -/* - * KeeLoq learning types - * https://phreakerclub.com/forum/showthread.php?t=67 - */ -#define KEELOQ_LEARNING_UNKNOWN 0u -#define KEELOQ_LEARNING_SIMPLE 1u -#define KEELOQ_LEARNING_NORMAL 2u -#define KEELOQ_LEARNING_SECURE 3u -#define KEELOQ_LEARNING_MAGIC_XOR_TYPE_1 4u -#define KEELOQ_LEARNING_FAAC 5u -#define KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_1 6u -#define KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_2 7u -#define KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_3 8u - -/** - * Simple Learning Encrypt - * @param data - 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter - * @param key - manufacture (64bit) - * @return keeloq encrypt data - */ -uint32_t subghz_protocol_keeloq_common_encrypt(const uint32_t data, const uint64_t key); - -/** - * Simple Learning Decrypt - * @param data - keeloq encrypt data - * @param key - manufacture (64bit) - * @return 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter - */ -uint32_t subghz_protocol_keeloq_common_decrypt(const uint32_t data, const uint64_t key); - -/** - * Normal Learning - * @param data - serial number (28bit) - * @param key - manufacture (64bit) - * @return manufacture for this serial number (64bit) - */ -uint64_t subghz_protocol_keeloq_common_normal_learning(uint32_t data, const uint64_t key); - -/** - * Secure Learning - * @param data - serial number (28bit) - * @param seed - seed number (32bit) - * @param key - manufacture (64bit) - * @return manufacture for this serial number (64bit) - */ -uint64_t - subghz_protocol_keeloq_common_secure_learning(uint32_t data, uint32_t seed, const uint64_t key); - -/** - * Magic_xor_type1 Learning - * @param data - serial number (28bit) - * @param xor - magic xor (64bit) - * @return manufacture for this serial number (64bit) - */ -uint64_t subghz_protocol_keeloq_common_magic_xor_type1_learning(uint32_t data, uint64_t xor); - -/** Faac SLH (Spa) Learning - * @param seed - seed number (32bit) - * @param key - mfkey (64bit) - * @return man_learning for this fix number (64bit) - */ -uint64_t subghz_protocol_keeloq_common_faac_learning(const uint32_t seed, const uint64_t key); - -/** Magic_serial_type1 Learning - * @param data - serial number (28bit) - * @param man - magic man (64bit) - * @return manufacture for this serial number (64bit) - */ - -uint64_t subghz_protocol_keeloq_common_magic_serial_type1_learning(uint32_t data, uint64_t man); - -/** Magic_serial_type2 Learning - * @param data - btn+serial number (32bit) - * @param man - magic man (64bit) - * @return manufacture for this serial number (64bit) - */ - -uint64_t subghz_protocol_keeloq_common_magic_serial_type2_learning(uint32_t data, uint64_t man); - -/** Magic_serial_type3 Learning - * @param data - btn+serial number (32bit) - * @param man - magic man (64bit) - * @return manufacture for this serial number (64bit) - */ - -uint64_t subghz_protocol_keeloq_common_magic_serial_type3_learning(uint32_t data, uint64_t man); diff --git a/applications/main/subghz/protocols/kia.c b/applications/main/subghz/protocols/kia.c deleted file mode 100644 index a5d9e37ef..000000000 --- a/applications/main/subghz/protocols/kia.c +++ /dev/null @@ -1,279 +0,0 @@ -#include "kia.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocoKIA" - -static const SubGhzBlockConst subghz_protocol_kia_const = { - .te_short = 250, - .te_long = 500, - .te_delta = 100, - .min_count_bit_for_found = 61, -}; - -struct SubGhzProtocolDecoderKIA { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - - uint16_t header_count; -}; - -struct SubGhzProtocolEncoderKIA { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - KIADecoderStepReset = 0, - KIADecoderStepCheckPreambula, - KIADecoderStepSaveDuration, - KIADecoderStepCheckDuration, -} KIADecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_kia_decoder = { - .alloc = subghz_protocol_decoder_kia_alloc, - .free = subghz_protocol_decoder_kia_free, - - .feed = subghz_protocol_decoder_kia_feed, - .reset = subghz_protocol_decoder_kia_reset, - - .get_hash_data = subghz_protocol_decoder_kia_get_hash_data, - .serialize = subghz_protocol_decoder_kia_serialize, - .deserialize = subghz_protocol_decoder_kia_deserialize, - .get_string = subghz_protocol_decoder_kia_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_kia_encoder = { - .alloc = NULL, - .free = NULL, - - .deserialize = NULL, - .stop = NULL, - .yield = NULL, -}; - -const SubGhzProtocol subghz_protocol_kia = { - .name = SUBGHZ_PROTOCOL_KIA_NAME, - .type = SubGhzProtocolTypeDynamic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_FM | SubGhzProtocolFlag_Decodable, - - .decoder = &subghz_protocol_kia_decoder, - .encoder = &subghz_protocol_kia_encoder, -}; - -void* subghz_protocol_decoder_kia_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderKIA* instance = malloc(sizeof(SubGhzProtocolDecoderKIA)); - instance->base.protocol = &subghz_protocol_kia; - instance->generic.protocol_name = instance->base.protocol->name; - - return instance; -} - -void subghz_protocol_decoder_kia_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderKIA* instance = context; - free(instance); -} - -void subghz_protocol_decoder_kia_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderKIA* instance = context; - instance->decoder.parser_step = KIADecoderStepReset; -} - -void subghz_protocol_decoder_kia_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderKIA* instance = context; - - switch(instance->decoder.parser_step) { - case KIADecoderStepReset: - if((level) && (DURATION_DIFF(duration, subghz_protocol_kia_const.te_short) < - subghz_protocol_kia_const.te_delta)) { - instance->decoder.parser_step = KIADecoderStepCheckPreambula; - instance->decoder.te_last = duration; - instance->header_count = 0; - } - break; - case KIADecoderStepCheckPreambula: - if(level) { - if((DURATION_DIFF(duration, subghz_protocol_kia_const.te_short) < - subghz_protocol_kia_const.te_delta) || - (DURATION_DIFF(duration, subghz_protocol_kia_const.te_long) < - subghz_protocol_kia_const.te_delta)) { - instance->decoder.te_last = duration; - } else { - instance->decoder.parser_step = KIADecoderStepReset; - } - } else if( - (DURATION_DIFF(duration, subghz_protocol_kia_const.te_short) < - subghz_protocol_kia_const.te_delta) && - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_kia_const.te_short) < - subghz_protocol_kia_const.te_delta)) { - // Found header - instance->header_count++; - break; - } else if( - (DURATION_DIFF(duration, subghz_protocol_kia_const.te_long) < - subghz_protocol_kia_const.te_delta) && - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_kia_const.te_long) < - subghz_protocol_kia_const.te_delta)) { - // Found start bit - if(instance->header_count > 15) { - instance->decoder.parser_step = KIADecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 1; - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - } else { - instance->decoder.parser_step = KIADecoderStepReset; - } - } else { - instance->decoder.parser_step = KIADecoderStepReset; - } - break; - case KIADecoderStepSaveDuration: - if(level) { - if(duration >= - (subghz_protocol_kia_const.te_long + subghz_protocol_kia_const.te_delta * 2UL)) { - //Found stop bit - instance->decoder.parser_step = KIADecoderStepReset; - if(instance->decoder.decode_count_bit == - subghz_protocol_kia_const.min_count_bit_for_found) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - break; - } else { - instance->decoder.te_last = duration; - instance->decoder.parser_step = KIADecoderStepCheckDuration; - } - - } else { - instance->decoder.parser_step = KIADecoderStepReset; - } - break; - case KIADecoderStepCheckDuration: - if(!level) { - if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_kia_const.te_short) < - subghz_protocol_kia_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_kia_const.te_short) < - subghz_protocol_kia_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = KIADecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_kia_const.te_long) < - subghz_protocol_kia_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_kia_const.te_long) < - subghz_protocol_kia_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = KIADecoderStepSaveDuration; - } else { - instance->decoder.parser_step = KIADecoderStepReset; - } - } else { - instance->decoder.parser_step = KIADecoderStepReset; - } - break; - } -} - -uint8_t subghz_protocol_kia_crc8(uint8_t* data, size_t len) { - uint8_t crc = 0x08; - size_t i, j; - for(i = 0; i < len; i++) { - crc ^= data[i]; - for(j = 0; j < 8; j++) { - if((crc & 0x80) != 0) - crc = (uint8_t)((crc << 1) ^ 0x7F); - else - crc <<= 1; - } - } - return crc; -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - */ -static void subghz_protocol_kia_check_remote_controller(SubGhzBlockGeneric* instance) { - /* - * 0x0F 0112 43B04EC 1 7D - * 0x0F 0113 43B04EC 1 DF - * 0x0F 0114 43B04EC 1 30 - * 0x0F 0115 43B04EC 2 13 - * 0x0F 0116 43B04EC 3 F5 - * CNT Serial K CRC8 Kia (CRC8, poly 0x7f, start_crc 0x08) - */ - - instance->serial = (uint32_t)((instance->data >> 12) & 0x0FFFFFFF); - instance->btn = (instance->data >> 8) & 0x0F; - instance->cnt = (instance->data >> 40) & 0xFFFF; -} - -uint8_t subghz_protocol_decoder_kia_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderKIA* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_kia_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderKIA* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_kia_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderKIA* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != subghz_protocol_kia_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_kia_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderKIA* instance = context; - - subghz_protocol_kia_check_remote_controller(&instance->generic); - uint32_t code_found_hi = instance->generic.data >> 32; - uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; - - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:%08lX%08lX\r\n" - "Sn:%07lX Btn:%X Cnt:%04lX\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - code_found_hi, - code_found_lo, - instance->generic.serial, - instance->generic.btn, - instance->generic.cnt); -} diff --git a/applications/main/subghz/protocols/kia.h b/applications/main/subghz/protocols/kia.h deleted file mode 100644 index a9afcf149..000000000 --- a/applications/main/subghz/protocols/kia.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_KIA_NAME "KIA Seed" - -typedef struct SubGhzProtocolDecoderKIA SubGhzProtocolDecoderKIA; -typedef struct SubGhzProtocolEncoderKIA SubGhzProtocolEncoderKIA; - -extern const SubGhzProtocolDecoder subghz_protocol_kia_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_kia_encoder; -extern const SubGhzProtocol subghz_protocol_kia; - -/** - * Allocate SubGhzProtocolDecoderKIA. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderKIA* pointer to a SubGhzProtocolDecoderKIA instance - */ -void* subghz_protocol_decoder_kia_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderKIA. - * @param context Pointer to a SubGhzProtocolDecoderKIA instance - */ -void subghz_protocol_decoder_kia_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderKIA. - * @param context Pointer to a SubGhzProtocolDecoderKIA instance - */ -void subghz_protocol_decoder_kia_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderKIA instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_kia_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderKIA instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_kia_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderKIA. - * @param context Pointer to a SubGhzProtocolDecoderKIA instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_kia_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderKIA. - * @param context Pointer to a SubGhzProtocolDecoderKIA instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_kia_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderKIA instance - * @param output Resulting text - */ -void subghz_protocol_decoder_kia_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/kinggates_stylo_4k.c b/applications/main/subghz/protocols/kinggates_stylo_4k.c deleted file mode 100644 index 5f2a83d77..000000000 --- a/applications/main/subghz/protocols/kinggates_stylo_4k.c +++ /dev/null @@ -1,581 +0,0 @@ -#include "kinggates_stylo_4k.h" -#include "keeloq_common.h" - -#include "../subghz_keystore.h" -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocoKingGates_stylo_4k" - -static const SubGhzBlockConst subghz_protocol_kinggates_stylo_4k_const = { - .te_short = 400, - .te_long = 1100, - .te_delta = 140, - .min_count_bit_for_found = 89, -}; - -struct SubGhzProtocolDecoderKingGates_stylo_4k { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - - uint16_t header_count; - SubGhzKeystore* keystore; -}; - -struct SubGhzProtocolEncoderKingGates_stylo_4k { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; - SubGhzKeystore* keystore; -}; - -typedef enum { - KingGates_stylo_4kDecoderStepReset = 0, - KingGates_stylo_4kDecoderStepCheckPreambula, - KingGates_stylo_4kDecoderStepCheckStartBit, - KingGates_stylo_4kDecoderStepSaveDuration, - KingGates_stylo_4kDecoderStepCheckDuration, -} KingGates_stylo_4kDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_kinggates_stylo_4k_decoder = { - .alloc = subghz_protocol_decoder_kinggates_stylo_4k_alloc, - .free = subghz_protocol_decoder_kinggates_stylo_4k_free, - - .feed = subghz_protocol_decoder_kinggates_stylo_4k_feed, - .reset = subghz_protocol_decoder_kinggates_stylo_4k_reset, - - .get_hash_data = subghz_protocol_decoder_kinggates_stylo_4k_get_hash_data, - .serialize = subghz_protocol_decoder_kinggates_stylo_4k_serialize, - .deserialize = subghz_protocol_decoder_kinggates_stylo_4k_deserialize, - .get_string = subghz_protocol_decoder_kinggates_stylo_4k_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_kinggates_stylo_4k_encoder = { - .alloc = subghz_protocol_encoder_kinggates_stylo_4k_alloc, - .free = subghz_protocol_encoder_kinggates_stylo_4k_free, - - .deserialize = subghz_protocol_encoder_kinggates_stylo_4k_deserialize, - .stop = subghz_protocol_encoder_kinggates_stylo_4k_stop, - .yield = subghz_protocol_encoder_kinggates_stylo_4k_yield, -}; - -const SubGhzProtocol subghz_protocol_kinggates_stylo_4k = { - .name = SUBGHZ_PROTOCOL_KINGGATES_STYLO_4K_NAME, - .type = SubGhzProtocolTypeDynamic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_kinggates_stylo_4k_decoder, - .encoder = &subghz_protocol_kinggates_stylo_4k_encoder, -}; - -// -// Encoder -// - -// Pre define function -static void subghz_protocol_kinggates_stylo_4k_remote_controller( - SubGhzBlockGeneric* instance, - SubGhzKeystore* keystore); - -void* subghz_protocol_encoder_kinggates_stylo_4k_alloc(SubGhzEnvironment* environment) { - SubGhzProtocolEncoderKingGates_stylo_4k* instance = - malloc(sizeof(SubGhzProtocolEncoderKingGates_stylo_4k)); - - instance->base.protocol = &subghz_protocol_kinggates_stylo_4k; - instance->generic.protocol_name = instance->base.protocol->name; - instance->keystore = subghz_environment_get_keystore(environment); - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 512; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - - return instance; -} - -void subghz_protocol_encoder_kinggates_stylo_4k_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderKingGates_stylo_4k* instance = context; - free(instance->encoder.upload); - free(instance); -} - -void subghz_protocol_encoder_kinggates_stylo_4k_stop(void* context) { - SubGhzProtocolEncoderKingGates_stylo_4k* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_kinggates_stylo_4k_yield(void* context) { - SubGhzProtocolEncoderKingGates_stylo_4k* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -/** - * Key generation from simple data - * @param instance Pointer to a SubGhzProtocolEncoderKingGates_stylo_4k* instance - * @param btn Button number, 4 bit - */ -static bool subghz_protocol_kinggates_stylo_4k_gen_data( - SubGhzProtocolEncoderKingGates_stylo_4k* instance, - uint8_t btn) { - UNUSED(btn); - uint32_t hop = subghz_protocol_blocks_reverse_key(instance->generic.data_2 >> 4, 32); - uint64_t fix = subghz_protocol_blocks_reverse_key(instance->generic.data, 53); - int res = 0; - uint32_t decrypt = 0; - - for - M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) { - res = strcmp(furi_string_get_cstr(manufacture_code->name), "Kingates_Stylo4k"); - if(res == 0) { - //Simple Learning - decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); - break; - } - } - instance->generic.cnt = decrypt & 0xFFFF; - - if(instance->generic.cnt < 0xFFFF) { - instance->generic.cnt++; - } else if(instance->generic.cnt >= 0xFFFF) { - instance->generic.cnt = 0; - } - - instance->generic.btn = (fix >> 17) & 0x0F; - instance->generic.serial = ((fix >> 5) & 0xFFFF0000) | (fix & 0xFFFF); - - uint32_t data = (decrypt & 0xFFFF0000) | instance->generic.cnt; - - uint64_t encrypt = 0; - for - M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) { - res = strcmp(furi_string_get_cstr(manufacture_code->name), "Kingates_Stylo4k"); - if(res == 0) { - //Simple Learning - encrypt = subghz_protocol_keeloq_common_encrypt(data, manufacture_code->key); - encrypt = subghz_protocol_blocks_reverse_key(encrypt, 32); - instance->generic.data_2 = encrypt << 4; - return true; - } - } - - return false; -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderKingGates_stylo_4k instance - * @return true On success - */ -static bool subghz_protocol_encoder_kinggates_stylo_4k_get_upload( - SubGhzProtocolEncoderKingGates_stylo_4k* instance, - uint8_t btn) { - furi_assert(instance); - - // Gen new key - if(subghz_protocol_kinggates_stylo_4k_gen_data(instance, btn)) { - //ToDo if you need to add a callback to automatically update the data on the display - } else { - return false; - } - - size_t index = 0; - - // Start - instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)9500); - - // Send header - for(uint8_t i = 12; i > 0; i--) { - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_kinggates_stylo_4k_const.te_short); - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_kinggates_stylo_4k_const.te_short); - } - - // After header - instance->encoder.upload[index - 1].duration = - (uint32_t)subghz_protocol_kinggates_stylo_4k_const.te_long * 2; - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_kinggates_stylo_4k_const.te_short * 2); - - // Send key fix - for(uint8_t i = 53; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_kinggates_stylo_4k_const.te_short); - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_kinggates_stylo_4k_const.te_long); - } else { - //send bit 0 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_kinggates_stylo_4k_const.te_long); - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_kinggates_stylo_4k_const.te_short); - } - } - - // Send key hop - for(uint8_t i = 36; i > 0; i--) { - if(bit_read(instance->generic.data_2, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_kinggates_stylo_4k_const.te_short); - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_kinggates_stylo_4k_const.te_long); - } else { - //send bit 0 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_kinggates_stylo_4k_const.te_long); - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_kinggates_stylo_4k_const.te_short); - } - } - - // Set upload size after generating upload, fix it later - - instance->encoder.size_upload = index; - - return true; -} - -bool subghz_protocol_encoder_kinggates_stylo_4k_deserialize( - void* context, - FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderKingGates_stylo_4k* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - - subghz_protocol_kinggates_stylo_4k_remote_controller( - &instance->generic, instance->keystore); - - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - - uint8_t key_data[sizeof(uint64_t)] = {0}; - if(!flipper_format_read_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Missing Data"); - break; - } - - for(uint8_t i = 0; i < sizeof(uint64_t); i++) { - instance->generic.data_2 = instance->generic.data_2 << 8 | key_data[i]; - } - - subghz_protocol_encoder_kinggates_stylo_4k_get_upload(instance, instance->generic.btn); - - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - - for(size_t i = 0; i < sizeof(uint64_t); i++) { - key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data_2 >> i * 8) & 0xFF; - } - if(!flipper_format_update_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Unable to add Key"); - break; - } - - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -// -// Decoder -// -void* subghz_protocol_decoder_kinggates_stylo_4k_alloc(SubGhzEnvironment* environment) { - SubGhzProtocolDecoderKingGates_stylo_4k* instance = - malloc(sizeof(SubGhzProtocolDecoderKingGates_stylo_4k)); - instance->base.protocol = &subghz_protocol_kinggates_stylo_4k; - instance->generic.protocol_name = instance->base.protocol->name; - instance->keystore = subghz_environment_get_keystore(environment); - return instance; -} - -void subghz_protocol_decoder_kinggates_stylo_4k_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderKingGates_stylo_4k* instance = context; - free(instance); -} - -void subghz_protocol_decoder_kinggates_stylo_4k_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderKingGates_stylo_4k* instance = context; - instance->decoder.parser_step = KingGates_stylo_4kDecoderStepReset; -} - -void subghz_protocol_decoder_kinggates_stylo_4k_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderKingGates_stylo_4k* instance = context; - - switch(instance->decoder.parser_step) { - case KingGates_stylo_4kDecoderStepReset: - if((level) && DURATION_DIFF(duration, subghz_protocol_kinggates_stylo_4k_const.te_short) < - subghz_protocol_kinggates_stylo_4k_const.te_delta) { - instance->decoder.parser_step = KingGates_stylo_4kDecoderStepCheckPreambula; - instance->header_count++; - } - break; - case KingGates_stylo_4kDecoderStepCheckPreambula: - if((!level) && - (DURATION_DIFF(duration, subghz_protocol_kinggates_stylo_4k_const.te_short) < - subghz_protocol_kinggates_stylo_4k_const.te_delta)) { - instance->decoder.parser_step = KingGates_stylo_4kDecoderStepReset; - break; - } - if((instance->header_count > 2) && - (DURATION_DIFF(duration, subghz_protocol_kinggates_stylo_4k_const.te_long * 2) < - subghz_protocol_kinggates_stylo_4k_const.te_delta * 2)) { - // Found header - instance->decoder.parser_step = KingGates_stylo_4kDecoderStepCheckStartBit; - } else { - instance->decoder.parser_step = KingGates_stylo_4kDecoderStepReset; - instance->header_count = 0; - } - break; - case KingGates_stylo_4kDecoderStepCheckStartBit: - if((level) && - DURATION_DIFF(duration, subghz_protocol_kinggates_stylo_4k_const.te_short * 2) < - subghz_protocol_kinggates_stylo_4k_const.te_delta * 2) { - instance->decoder.parser_step = KingGates_stylo_4kDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->generic.data_2 = 0; - instance->decoder.decode_count_bit = 0; - instance->header_count = 0; - } - break; - case KingGates_stylo_4kDecoderStepSaveDuration: - if(!level) { - if(duration >= ((uint32_t)subghz_protocol_kinggates_stylo_4k_const.te_long * 3)) { - if(instance->decoder.decode_count_bit == - subghz_protocol_kinggates_stylo_4k_const.min_count_bit_for_found) { - instance->generic.data = instance->generic.data_2; - instance->generic.data_2 = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - - instance->decoder.parser_step = KingGates_stylo_4kDecoderStepReset; - instance->decoder.decode_data = 0; - instance->generic.data_2 = 0; - instance->decoder.decode_count_bit = 0; - instance->header_count = 0; - break; - } else { - instance->decoder.te_last = duration; - instance->decoder.parser_step = KingGates_stylo_4kDecoderStepCheckDuration; - } - } else { - instance->decoder.parser_step = KingGates_stylo_4kDecoderStepReset; - instance->header_count = 0; - } - break; - case KingGates_stylo_4kDecoderStepCheckDuration: - if(level) { - if((DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_kinggates_stylo_4k_const.te_short) < - subghz_protocol_kinggates_stylo_4k_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_kinggates_stylo_4k_const.te_long) < - subghz_protocol_kinggates_stylo_4k_const.te_delta * 2)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = KingGates_stylo_4kDecoderStepSaveDuration; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_kinggates_stylo_4k_const.te_long) < - subghz_protocol_kinggates_stylo_4k_const.te_delta * 2) && - (DURATION_DIFF(duration, subghz_protocol_kinggates_stylo_4k_const.te_short) < - subghz_protocol_kinggates_stylo_4k_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = KingGates_stylo_4kDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = KingGates_stylo_4kDecoderStepReset; - instance->header_count = 0; - } - if(instance->decoder.decode_count_bit == 53) { - instance->generic.data_2 = instance->decoder.decode_data; - instance->decoder.decode_data = 0; - } - } else { - instance->decoder.parser_step = KingGates_stylo_4kDecoderStepReset; - instance->header_count = 0; - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - * @param data Input encrypted data - * @param keystore Pointer to a SubGhzKeystore* instance - */ -static void subghz_protocol_kinggates_stylo_4k_remote_controller( - SubGhzBlockGeneric* instance, - SubGhzKeystore* keystore) { - /** - * 9500us 12*(400/400) 2200/800|1-bit|0-bit| - * _ _ _ __ ___ _ - * ________| |_| |_..._| |_____| |_| |___| |..... - * - * 1-bit 400/1100 us - * 0-bit 1100/400 us - * - * The package consists of 89 bits of data, LSB first - * Data - 1C9037F0C80000 CE280BA00 - * S[3] S[2] 1 key S[1] S[0] 2 byte always 0 Hop[3] Hop[2] Hop[1] Hop[0] 0 - * 11100100 10000001 1 0111 11110000 11001000 00000000 00000000 11001110 00101000 00001011 10100000 0000 - * - * Encryption - keeloq Simple Learning - * key C S[3] CNT - * Decrypt - 0xEC270B9C => 0x E C 27 0B9C - * - * - * -*/ - - uint32_t hop = subghz_protocol_blocks_reverse_key(instance->data_2 >> 4, 32); - uint64_t fix = subghz_protocol_blocks_reverse_key(instance->data, 53); - bool ret = false; - uint32_t decrypt = 0; - instance->btn = (fix >> 17) & 0x0F; - instance->serial = ((fix >> 5) & 0xFFFF0000) | (fix & 0xFFFF); - - for - M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) { - if(manufacture_code->type == KEELOQ_LEARNING_SIMPLE) { - decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); - if(((decrypt >> 28) == instance->btn) && (((decrypt >> 24) & 0x0F) == 0x0C) && - (((decrypt >> 16) & 0xFF) == (instance->serial & 0xFF))) { - ret = true; - break; - } - } - } - if(ret) { - instance->cnt = decrypt & 0xFFFF; - } else { - instance->btn = 0; - instance->serial = 0; - instance->cnt = 0; - } -} - -uint8_t subghz_protocol_decoder_kinggates_stylo_4k_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderKingGates_stylo_4k* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_kinggates_stylo_4k_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderKingGates_stylo_4k* instance = context; - bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); - - uint8_t key_data[sizeof(uint64_t)] = {0}; - for(size_t i = 0; i < sizeof(uint64_t); i++) { - key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data_2 >> (i * 8)) & 0xFF; - } - - if(res && !flipper_format_write_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Unable to add Data"); - res = false; - } - return res; - - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_kinggates_stylo_4k_deserialize( - void* context, - FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderKingGates_stylo_4k* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_kinggates_stylo_4k_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - uint8_t key_data[sizeof(uint64_t)] = {0}; - if(!flipper_format_read_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Missing Data"); - break; - } - - for(uint8_t i = 0; i < sizeof(uint64_t); i++) { - instance->generic.data_2 = instance->generic.data_2 << 8 | key_data[i]; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_kinggates_stylo_4k_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderKingGates_stylo_4k* instance = context; - subghz_protocol_kinggates_stylo_4k_remote_controller(&instance->generic, instance->keystore); - - furi_string_cat_printf( - output, - "%s\r\n" - "Key:0x%llX%07llX %dbit\r\n" - "Sn:0x%08lX Btn:0x%01X\r\n" - "Cnt:0x%04lX\r\n", - instance->generic.protocol_name, - instance->generic.data, - instance->generic.data_2, - instance->generic.data_count_bit, - instance->generic.serial, - instance->generic.btn, - instance->generic.cnt); -} \ No newline at end of file diff --git a/applications/main/subghz/protocols/kinggates_stylo_4k.h b/applications/main/subghz/protocols/kinggates_stylo_4k.h deleted file mode 100644 index 9717f6715..000000000 --- a/applications/main/subghz/protocols/kinggates_stylo_4k.h +++ /dev/null @@ -1,110 +0,0 @@ -#pragma once -#include "base.h" - -#define SUBGHZ_PROTOCOL_KINGGATES_STYLO_4K_NAME "KingGates Stylo4k" - -typedef struct SubGhzProtocolDecoderKingGates_stylo_4k SubGhzProtocolDecoderKingGates_stylo_4k; -typedef struct SubGhzProtocolEncoderKingGates_stylo_4k SubGhzProtocolEncoderKingGates_stylo_4k; - -extern const SubGhzProtocolDecoder subghz_protocol_kinggates_stylo_4k_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_kinggates_stylo_4k_encoder; -extern const SubGhzProtocol subghz_protocol_kinggates_stylo_4k; - -/** - * Allocate SubGhzProtocolEncoderKingGates_stylo_4k. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderKingGates_stylo_4k* pointer to a SubGhzProtocolEncoderKingGates_stylo_4k instance - */ -void* subghz_protocol_encoder_kinggates_stylo_4k_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderKingGates_stylo_4k. - * @param context Pointer to a SubGhzProtocolEncoderKingGates_stylo_4k instance - */ -void subghz_protocol_encoder_kinggates_stylo_4k_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderKingGates_stylo_4k instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_kinggates_stylo_4k_deserialize( - void* context, - FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderKingGates_stylo_4k instance - */ -void subghz_protocol_encoder_kinggates_stylo_4k_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderKingGates_stylo_4k instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_kinggates_stylo_4k_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderKingGates_stylo_4k. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderKingGates_stylo_4k* pointer to a SubGhzProtocolDecoderKingGates_stylo_4k instance - */ -void* subghz_protocol_decoder_kinggates_stylo_4k_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderKingGates_stylo_4k. - * @param context Pointer to a SubGhzProtocolDecoderKingGates_stylo_4k instance - */ -void subghz_protocol_decoder_kinggates_stylo_4k_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderKingGates_stylo_4k. - * @param context Pointer to a SubGhzProtocolDecoderKingGates_stylo_4k instance - */ -void subghz_protocol_decoder_kinggates_stylo_4k_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderKingGates_stylo_4k instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_kinggates_stylo_4k_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderKingGates_stylo_4k instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_kinggates_stylo_4k_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderKingGates_stylo_4k. - * @param context Pointer to a SubGhzProtocolDecoderKingGates_stylo_4k instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_kinggates_stylo_4k_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderKingGates_stylo_4k. - * @param context Pointer to a SubGhzProtocolDecoderKingGates_stylo_4k instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_kinggates_stylo_4k_deserialize( - void* context, - FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderKingGates_stylo_4k instance - * @param output Resulting text - */ -void subghz_protocol_decoder_kinggates_stylo_4k_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/linear.c b/applications/main/subghz/protocols/linear.c deleted file mode 100644 index 2fc8b20c8..000000000 --- a/applications/main/subghz/protocols/linear.c +++ /dev/null @@ -1,352 +0,0 @@ -#include "linear.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolLinear" - -#define DIP_PATTERN "%c%c%c%c%c%c%c%c%c%c" -#define DATA_TO_DIP(dip) \ - (dip & 0x0200 ? '1' : '0'), (dip & 0x0100 ? '1' : '0'), (dip & 0x0080 ? '1' : '0'), \ - (dip & 0x0040 ? '1' : '0'), (dip & 0x0020 ? '1' : '0'), (dip & 0x0010 ? '1' : '0'), \ - (dip & 0x0008 ? '1' : '0'), (dip & 0x0004 ? '1' : '0'), (dip & 0x0002 ? '1' : '0'), \ - (dip & 0x0001 ? '1' : '0') - -static const SubGhzBlockConst subghz_protocol_linear_const = { - .te_short = 500, - .te_long = 1500, - .te_delta = 150, - .min_count_bit_for_found = 10, -}; - -struct SubGhzProtocolDecoderLinear { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; -}; - -struct SubGhzProtocolEncoderLinear { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - LinearDecoderStepReset = 0, - LinearDecoderStepSaveDuration, - LinearDecoderStepCheckDuration, -} LinearDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_linear_decoder = { - .alloc = subghz_protocol_decoder_linear_alloc, - .free = subghz_protocol_decoder_linear_free, - - .feed = subghz_protocol_decoder_linear_feed, - .reset = subghz_protocol_decoder_linear_reset, - - .get_hash_data = subghz_protocol_decoder_linear_get_hash_data, - .serialize = subghz_protocol_decoder_linear_serialize, - .deserialize = subghz_protocol_decoder_linear_deserialize, - .get_string = subghz_protocol_decoder_linear_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_linear_encoder = { - .alloc = subghz_protocol_encoder_linear_alloc, - .free = subghz_protocol_encoder_linear_free, - - .deserialize = subghz_protocol_encoder_linear_deserialize, - .stop = subghz_protocol_encoder_linear_stop, - .yield = subghz_protocol_encoder_linear_yield, -}; - -const SubGhzProtocol subghz_protocol_linear = { - .name = SUBGHZ_PROTOCOL_LINEAR_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_315 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_linear_decoder, - .encoder = &subghz_protocol_linear_encoder, -}; - -void* subghz_protocol_encoder_linear_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderLinear* instance = malloc(sizeof(SubGhzProtocolEncoderLinear)); - - instance->base.protocol = &subghz_protocol_linear; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 28; //max 10bit*2 + 2 (start, stop) - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_linear_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderLinear* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderLinear instance - * @return true On success - */ -static bool subghz_protocol_encoder_linear_get_upload(SubGhzProtocolEncoderLinear* instance) { - furi_assert(instance); - size_t index = 0; - size_t size_upload = (instance->generic.data_count_bit * 2); - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 1; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_linear_const.te_short * 3); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_linear_const.te_short); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_linear_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_linear_const.te_short * 3); - } - } - //Send end bit - if(bit_read(instance->generic.data, 0)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_linear_const.te_short * 3); - //Send PT_GUARD - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_linear_const.te_short * 42); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_linear_const.te_short); - //Send PT_GUARD - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_linear_const.te_short * 44); - } - - return true; -} - -bool subghz_protocol_encoder_linear_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderLinear* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_linear_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_linear_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_linear_stop(void* context) { - SubGhzProtocolEncoderLinear* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_linear_yield(void* context) { - SubGhzProtocolEncoderLinear* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_linear_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderLinear* instance = malloc(sizeof(SubGhzProtocolDecoderLinear)); - instance->base.protocol = &subghz_protocol_linear; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_linear_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderLinear* instance = context; - free(instance); -} - -void subghz_protocol_decoder_linear_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderLinear* instance = context; - instance->decoder.parser_step = LinearDecoderStepReset; -} - -void subghz_protocol_decoder_linear_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderLinear* instance = context; - switch(instance->decoder.parser_step) { - case LinearDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_linear_const.te_short * 42) < - subghz_protocol_linear_const.te_delta * 20)) { - //Found header Linear - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->decoder.parser_step = LinearDecoderStepSaveDuration; - } - break; - case LinearDecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = LinearDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = LinearDecoderStepReset; - } - break; - case LinearDecoderStepCheckDuration: - if(!level) { //save interval - if(duration >= (subghz_protocol_linear_const.te_short * 5)) { - instance->decoder.parser_step = LinearDecoderStepReset; - //checking that the duration matches the guardtime - if((DURATION_DIFF(duration, subghz_protocol_linear_const.te_short * 42) > - subghz_protocol_linear_const.te_delta * 20)) { - break; - } - if(DURATION_DIFF(instance->decoder.te_last, subghz_protocol_linear_const.te_short) < - subghz_protocol_linear_const.te_delta) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - } else if( - DURATION_DIFF(instance->decoder.te_last, subghz_protocol_linear_const.te_long) < - subghz_protocol_linear_const.te_delta) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - } - if(instance->decoder.decode_count_bit == - subghz_protocol_linear_const.min_count_bit_for_found) { - instance->generic.serial = 0x0; - instance->generic.btn = 0x0; - - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - break; - } - - if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_linear_const.te_short) < - subghz_protocol_linear_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_linear_const.te_long) < - subghz_protocol_linear_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = LinearDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_linear_const.te_long) < - subghz_protocol_linear_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_linear_const.te_short) < - subghz_protocol_linear_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = LinearDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = LinearDecoderStepReset; - } - - } else { - instance->decoder.parser_step = LinearDecoderStepReset; - } - break; - } -} - -uint8_t subghz_protocol_decoder_linear_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderLinear* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_linear_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderLinear* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_linear_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderLinear* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_linear_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_linear_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderLinear* instance = context; - - uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; - - uint64_t code_found_reverse = subghz_protocol_blocks_reverse_key( - instance->generic.data, instance->generic.data_count_bit); - - uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:0x%08lX\r\n" - "Yek:0x%08lX\r\n" - "DIP:" DIP_PATTERN "\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - code_found_lo, - code_found_reverse_lo, - DATA_TO_DIP(code_found_lo)); -} diff --git a/applications/main/subghz/protocols/linear.h b/applications/main/subghz/protocols/linear.h deleted file mode 100644 index 923337ac2..000000000 --- a/applications/main/subghz/protocols/linear.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_LINEAR_NAME "Linear" - -typedef struct SubGhzProtocolDecoderLinear SubGhzProtocolDecoderLinear; -typedef struct SubGhzProtocolEncoderLinear SubGhzProtocolEncoderLinear; - -extern const SubGhzProtocolDecoder subghz_protocol_linear_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_linear_encoder; -extern const SubGhzProtocol subghz_protocol_linear; - -/** - * Allocate SubGhzProtocolEncoderLinear. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderLinear* pointer to a SubGhzProtocolEncoderLinear instance - */ -void* subghz_protocol_encoder_linear_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderLinear. - * @param context Pointer to a SubGhzProtocolEncoderLinear instance - */ -void subghz_protocol_encoder_linear_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderLinear instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_linear_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderLinear instance - */ -void subghz_protocol_encoder_linear_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderLinear instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_linear_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderLinear. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderLinear* pointer to a SubGhzProtocolDecoderLinear instance - */ -void* subghz_protocol_decoder_linear_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderLinear. - * @param context Pointer to a SubGhzProtocolDecoderLinear instance - */ -void subghz_protocol_decoder_linear_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderLinear. - * @param context Pointer to a SubGhzProtocolDecoderLinear instance - */ -void subghz_protocol_decoder_linear_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderLinear instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_linear_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderLinear instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_linear_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderLinear. - * @param context Pointer to a SubGhzProtocolDecoderLinear instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_linear_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderLinear. - * @param context Pointer to a SubGhzProtocolDecoderLinear instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_linear_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderLinear instance - * @param output Resulting text - */ -void subghz_protocol_decoder_linear_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/linear_delta3.c b/applications/main/subghz/protocols/linear_delta3.c deleted file mode 100644 index 869edac84..000000000 --- a/applications/main/subghz/protocols/linear_delta3.c +++ /dev/null @@ -1,359 +0,0 @@ -#include "linear_delta3.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolLinearDelta3" - -#define DIP_PATTERN "%c%c%c%c%c%c%c%c" -#define DATA_TO_DIP(dip) \ - (dip & 0x0080 ? '1' : '0'), (dip & 0x0040 ? '1' : '0'), (dip & 0x0020 ? '1' : '0'), \ - (dip & 0x0010 ? '1' : '0'), (dip & 0x0008 ? '1' : '0'), (dip & 0x0004 ? '1' : '0'), \ - (dip & 0x0002 ? '1' : '0'), (dip & 0x0001 ? '1' : '0') - -static const SubGhzBlockConst subghz_protocol_linear_delta3_const = { - .te_short = 500, - .te_long = 2000, - .te_delta = 150, - .min_count_bit_for_found = 8, -}; - -struct SubGhzProtocolDecoderLinearDelta3 { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - - uint32_t last_data; -}; - -struct SubGhzProtocolEncoderLinearDelta3 { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - LinearDecoderStepReset = 0, - LinearDecoderStepSaveDuration, - LinearDecoderStepCheckDuration, -} LinearDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_linear_delta3_decoder = { - .alloc = subghz_protocol_decoder_linear_delta3_alloc, - .free = subghz_protocol_decoder_linear_delta3_free, - - .feed = subghz_protocol_decoder_linear_delta3_feed, - .reset = subghz_protocol_decoder_linear_delta3_reset, - - .get_hash_data = subghz_protocol_decoder_linear_delta3_get_hash_data, - .serialize = subghz_protocol_decoder_linear_delta3_serialize, - .deserialize = subghz_protocol_decoder_linear_delta3_deserialize, - .get_string = subghz_protocol_decoder_linear_delta3_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_linear_delta3_encoder = { - .alloc = subghz_protocol_encoder_linear_delta3_alloc, - .free = subghz_protocol_encoder_linear_delta3_free, - - .deserialize = subghz_protocol_encoder_linear_delta3_deserialize, - .stop = subghz_protocol_encoder_linear_delta3_stop, - .yield = subghz_protocol_encoder_linear_delta3_yield, -}; - -const SubGhzProtocol subghz_protocol_linear_delta3 = { - .name = SUBGHZ_PROTOCOL_LINEAR_DELTA3_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_315 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_linear_delta3_decoder, - .encoder = &subghz_protocol_linear_delta3_encoder, -}; - -void* subghz_protocol_encoder_linear_delta3_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderLinearDelta3* instance = - malloc(sizeof(SubGhzProtocolEncoderLinearDelta3)); - - instance->base.protocol = &subghz_protocol_linear_delta3; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 16; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_linear_delta3_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderLinearDelta3* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderLinearDelta3 instance - * @return true On success - */ -static bool - subghz_protocol_encoder_linear_delta3_get_upload(SubGhzProtocolEncoderLinearDelta3* instance) { - furi_assert(instance); - size_t index = 0; - size_t size_upload = (instance->generic.data_count_bit * 2); - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 1; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_linear_delta3_const.te_short); - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_linear_delta3_const.te_short * 7); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_linear_delta3_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_linear_delta3_const.te_long); - } - } - //Send end bit - if(bit_read(instance->generic.data, 0)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_linear_delta3_const.te_short); - //Send PT_GUARD - instance->encoder.upload[index] = level_duration_make( - false, (uint32_t)subghz_protocol_linear_delta3_const.te_short * 73); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_linear_delta3_const.te_long); - //Send PT_GUARD - instance->encoder.upload[index] = level_duration_make( - false, (uint32_t)subghz_protocol_linear_delta3_const.te_short * 70); - } - - return true; -} - -bool subghz_protocol_encoder_linear_delta3_deserialize( - void* context, - FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderLinearDelta3* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_linear_delta3_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_linear_delta3_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_linear_delta3_stop(void* context) { - SubGhzProtocolEncoderLinearDelta3* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_linear_delta3_yield(void* context) { - SubGhzProtocolEncoderLinearDelta3* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_linear_delta3_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderLinearDelta3* instance = - malloc(sizeof(SubGhzProtocolDecoderLinearDelta3)); - instance->base.protocol = &subghz_protocol_linear_delta3; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_linear_delta3_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderLinearDelta3* instance = context; - free(instance); -} - -void subghz_protocol_decoder_linear_delta3_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderLinearDelta3* instance = context; - instance->decoder.parser_step = LinearDecoderStepReset; - instance->last_data = 0; -} - -void subghz_protocol_decoder_linear_delta3_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderLinearDelta3* instance = context; - switch(instance->decoder.parser_step) { - case LinearDecoderStepReset: - if((!level) && - (DURATION_DIFF(duration, subghz_protocol_linear_delta3_const.te_short * 70) < - subghz_protocol_linear_delta3_const.te_delta * 24)) { - //Found header Linear - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->decoder.parser_step = LinearDecoderStepSaveDuration; - } - break; - case LinearDecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = LinearDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = LinearDecoderStepReset; - } - break; - case LinearDecoderStepCheckDuration: - if(!level) { - if(duration >= (subghz_protocol_linear_delta3_const.te_short * 10)) { - instance->decoder.parser_step = LinearDecoderStepReset; - if(DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_linear_delta3_const.te_short) < - subghz_protocol_linear_delta3_const.te_delta) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - } else if( - DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_linear_delta3_const.te_long) < - subghz_protocol_linear_delta3_const.te_delta) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - } - if(instance->decoder.decode_count_bit == - subghz_protocol_linear_delta3_const.min_count_bit_for_found) { - if((instance->last_data == instance->decoder.decode_data) && - instance->last_data) { - instance->generic.serial = 0x0; - instance->generic.btn = 0x0; - - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.parser_step = LinearDecoderStepSaveDuration; - instance->last_data = instance->decoder.decode_data; - } - break; - } - - if((DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_linear_delta3_const.te_short) < - subghz_protocol_linear_delta3_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_linear_delta3_const.te_short * 7) < - subghz_protocol_linear_delta3_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = LinearDecoderStepSaveDuration; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_linear_delta3_const.te_long) < - subghz_protocol_linear_delta3_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_linear_delta3_const.te_long) < - subghz_protocol_linear_delta3_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = LinearDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = LinearDecoderStepReset; - } - - } else { - instance->decoder.parser_step = LinearDecoderStepReset; - } - break; - } -} - -uint8_t subghz_protocol_decoder_linear_delta3_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderLinearDelta3* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8)); -} - -bool subghz_protocol_decoder_linear_delta3_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderLinearDelta3* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_linear_delta3_deserialize( - void* context, - FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderLinearDelta3* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_linear_delta3_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_linear_delta3_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderLinearDelta3* instance = context; - - uint32_t data = instance->generic.data & 0xFF; - - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX\r\n" - "DIP:" DIP_PATTERN "\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - data, - DATA_TO_DIP(data)); -} diff --git a/applications/main/subghz/protocols/linear_delta3.h b/applications/main/subghz/protocols/linear_delta3.h deleted file mode 100644 index 2f0a32e68..000000000 --- a/applications/main/subghz/protocols/linear_delta3.h +++ /dev/null @@ -1,111 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_LINEAR_DELTA3_NAME "LinearDelta3" - -typedef struct SubGhzProtocolDecoderLinearDelta3 SubGhzProtocolDecoderLinearDelta3; -typedef struct SubGhzProtocolEncoderLinearDelta3 SubGhzProtocolEncoderLinearDelta3; - -extern const SubGhzProtocolDecoder subghz_protocol_linear_delta3_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_linear_delta3_encoder; -extern const SubGhzProtocol subghz_protocol_linear_delta3; - -/** - * Allocate SubGhzProtocolEncoderLinearDelta3. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderLinearDelta3* pointer to a SubGhzProtocolEncoderLinearDelta3 instance - */ -void* subghz_protocol_encoder_linear_delta3_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderLinearDelta3. - * @param context Pointer to a SubGhzProtocolEncoderLinearDelta3 instance - */ -void subghz_protocol_encoder_linear_delta3_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderLinearDelta3 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_linear_delta3_deserialize( - void* context, - FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderLinearDelta3 instance - */ -void subghz_protocol_encoder_linear_delta3_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderLinearDelta3 instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_linear_delta3_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderLinearDelta3. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderLinearDelta3* pointer to a SubGhzProtocolDecoderLinearDelta3 instance - */ -void* subghz_protocol_decoder_linear_delta3_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderLinearDelta3. - * @param context Pointer to a SubGhzProtocolDecoderLinearDelta3 instance - */ -void subghz_protocol_decoder_linear_delta3_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderLinearDelta3. - * @param context Pointer to a SubGhzProtocolDecoderLinearDelta3 instance - */ -void subghz_protocol_decoder_linear_delta3_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderLinearDelta3 instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_linear_delta3_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderLinearDelta3 instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_linear_delta3_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderLinearDelta3. - * @param context Pointer to a SubGhzProtocolDecoderLinearDelta3 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_linear_delta3_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderLinearDelta3. - * @param context Pointer to a SubGhzProtocolDecoderLinearDelta3 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_linear_delta3_deserialize( - void* context, - FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderLinearDelta3 instance - * @param output Resulting text - */ -void subghz_protocol_decoder_linear_delta3_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/magellan.c b/applications/main/subghz/protocols/magellan.c deleted file mode 100644 index 67d3fe3d3..000000000 --- a/applications/main/subghz/protocols/magellan.c +++ /dev/null @@ -1,445 +0,0 @@ -#include "magellan.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolMagellan" - -static const SubGhzBlockConst subghz_protocol_magellan_const = { - .te_short = 200, - .te_long = 400, - .te_delta = 100, - .min_count_bit_for_found = 32, -}; - -struct SubGhzProtocolDecoderMagellan { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - uint16_t header_count; -}; - -struct SubGhzProtocolEncoderMagellan { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - MagellanDecoderStepReset = 0, - MagellanDecoderStepCheckPreambula, - MagellanDecoderStepFoundPreambula, - MagellanDecoderStepSaveDuration, - MagellanDecoderStepCheckDuration, -} MagellanDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_magellan_decoder = { - .alloc = subghz_protocol_decoder_magellan_alloc, - .free = subghz_protocol_decoder_magellan_free, - - .feed = subghz_protocol_decoder_magellan_feed, - .reset = subghz_protocol_decoder_magellan_reset, - - .get_hash_data = subghz_protocol_decoder_magellan_get_hash_data, - .serialize = subghz_protocol_decoder_magellan_serialize, - .deserialize = subghz_protocol_decoder_magellan_deserialize, - .get_string = subghz_protocol_decoder_magellan_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_magellan_encoder = { - .alloc = subghz_protocol_encoder_magellan_alloc, - .free = subghz_protocol_encoder_magellan_free, - - .deserialize = subghz_protocol_encoder_magellan_deserialize, - .stop = subghz_protocol_encoder_magellan_stop, - .yield = subghz_protocol_encoder_magellan_yield, -}; - -const SubGhzProtocol subghz_protocol_magellan = { - .name = SUBGHZ_PROTOCOL_MAGELLAN_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_magellan_decoder, - .encoder = &subghz_protocol_magellan_encoder, -}; - -void* subghz_protocol_encoder_magellan_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderMagellan* instance = malloc(sizeof(SubGhzProtocolEncoderMagellan)); - - instance->base.protocol = &subghz_protocol_magellan; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 256; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_magellan_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderMagellan* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderMagellan instance - * @return true On success - */ -static bool subghz_protocol_encoder_magellan_get_upload(SubGhzProtocolEncoderMagellan* instance) { - furi_assert(instance); - - size_t index = 0; - - //Send header - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_magellan_const.te_short * 4); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_magellan_const.te_short); - for(uint8_t i = 0; i < 12; i++) { - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_magellan_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_magellan_const.te_short); - } - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_magellan_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_magellan_const.te_long); - - //Send start bit - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_magellan_const.te_long * 3); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_magellan_const.te_long); - - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_magellan_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_magellan_const.te_long); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_magellan_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_magellan_const.te_short); - } - } - - //Send stop bit - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_magellan_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_magellan_const.te_long * 100); - - instance->encoder.size_upload = index; - return true; -} - -bool subghz_protocol_encoder_magellan_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderMagellan* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_magellan_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_magellan_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_magellan_stop(void* context) { - SubGhzProtocolEncoderMagellan* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_magellan_yield(void* context) { - SubGhzProtocolEncoderMagellan* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_magellan_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderMagellan* instance = malloc(sizeof(SubGhzProtocolDecoderMagellan)); - instance->base.protocol = &subghz_protocol_magellan; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_magellan_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderMagellan* instance = context; - free(instance); -} - -void subghz_protocol_decoder_magellan_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderMagellan* instance = context; - instance->decoder.parser_step = MagellanDecoderStepReset; -} - -uint8_t subghz_protocol_magellan_crc8(uint8_t* data, size_t len) { - uint8_t crc = 0x00; - size_t i, j; - for(i = 0; i < len; i++) { - crc ^= data[i]; - for(j = 0; j < 8; j++) { - if((crc & 0x80) != 0) - crc = (uint8_t)((crc << 1) ^ 0x31); - else - crc <<= 1; - } - } - return crc; -} - -static bool subghz_protocol_magellan_check_crc(SubGhzProtocolDecoderMagellan* instance) { - uint8_t data[3] = { - instance->decoder.decode_data >> 24, - instance->decoder.decode_data >> 16, - instance->decoder.decode_data >> 8}; - return (instance->decoder.decode_data & 0xFF) == - subghz_protocol_magellan_crc8(data, sizeof(data)); -} - -void subghz_protocol_decoder_magellan_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderMagellan* instance = context; - - switch(instance->decoder.parser_step) { - case MagellanDecoderStepReset: - if((level) && (DURATION_DIFF(duration, subghz_protocol_magellan_const.te_short) < - subghz_protocol_magellan_const.te_delta)) { - instance->decoder.parser_step = MagellanDecoderStepCheckPreambula; - instance->decoder.te_last = duration; - instance->header_count = 0; - } - break; - - case MagellanDecoderStepCheckPreambula: - if(level) { - instance->decoder.te_last = duration; - } else { - if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_magellan_const.te_short) < - subghz_protocol_magellan_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_magellan_const.te_short) < - subghz_protocol_magellan_const.te_delta)) { - // Found header - instance->header_count++; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_magellan_const.te_short) < - subghz_protocol_magellan_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_magellan_const.te_long) < - subghz_protocol_magellan_const.te_delta * 2) && - (instance->header_count > 10)) { - instance->decoder.parser_step = MagellanDecoderStepFoundPreambula; - } else { - instance->decoder.parser_step = MagellanDecoderStepReset; - } - } - break; - - case MagellanDecoderStepFoundPreambula: - if(level) { - instance->decoder.te_last = duration; - } else { - if((DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_magellan_const.te_short * 6) < - subghz_protocol_magellan_const.te_delta * 3) && - (DURATION_DIFF(duration, subghz_protocol_magellan_const.te_long) < - subghz_protocol_magellan_const.te_delta * 2)) { - instance->decoder.parser_step = MagellanDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else { - instance->decoder.parser_step = MagellanDecoderStepReset; - } - } - break; - - case MagellanDecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = MagellanDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = MagellanDecoderStepReset; - } - break; - - case MagellanDecoderStepCheckDuration: - if(!level) { - if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_magellan_const.te_short) < - subghz_protocol_magellan_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_magellan_const.te_long) < - subghz_protocol_magellan_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = MagellanDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_magellan_const.te_long) < - subghz_protocol_magellan_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_magellan_const.te_short) < - subghz_protocol_magellan_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = MagellanDecoderStepSaveDuration; - } else if(duration >= (subghz_protocol_magellan_const.te_long * 3)) { - //Found stop bit - if((instance->decoder.decode_count_bit == - subghz_protocol_magellan_const.min_count_bit_for_found) && - subghz_protocol_magellan_check_crc(instance)) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->decoder.parser_step = MagellanDecoderStepReset; - } else { - instance->decoder.parser_step = MagellanDecoderStepReset; - } - } else { - instance->decoder.parser_step = MagellanDecoderStepReset; - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - */ -static void subghz_protocol_magellan_check_remote_controller(SubGhzBlockGeneric* instance) { - /* -* package 32b data 24b CRC8 -* 0x037AE4828 => 001101111010111001001000 00101000 -* -* 0x037AE48 (flipped in reverse bit sequence) => 0x1275EC -* -* 0x1275EC => 0x12-event codes, 0x75EC-serial (dec 117236) -* -* event codes -* bit_0: 1-Open/Motion, 0-close/ok -* bit_1: 1-Tamper On (alarm), 0-Tamper Off (ok) -* bit_2: ? -* bit_3: 1-power on -* bit_4: model type - wireless reed -* bit_5: model type - motion sensor -* bit_6: ? -* bit_7: ? -* -*/ - uint64_t data_rev = subghz_protocol_blocks_reverse_key(instance->data >> 8, 24); - instance->serial = data_rev & 0xFFFF; - instance->btn = (data_rev >> 16) & 0xFF; -} - -static void subghz_protocol_magellan_get_event_serialize(uint8_t event, FuriString* output) { - furi_string_cat_printf( - output, - "%s%s%s%s%s%s%s%s", - ((event >> 4) & 0x1 ? (event & 0x1 ? " Open" : " Close") : - (event & 0x1 ? " Motion" : " Ok")), - ((event >> 1) & 0x1 ? ", Tamper On\n(Alarm)" : ""), - ((event >> 2) & 0x1 ? ", ?" : ""), - ((event >> 3) & 0x1 ? ", Power On" : ""), - ((event >> 4) & 0x1 ? ", MT:Wireless_Reed" : ""), - ((event >> 5) & 0x1 ? ", MT:Motion_\nSensor" : ""), - ((event >> 6) & 0x1 ? ", ?" : ""), - ((event >> 7) & 0x1 ? ", ?" : "")); -} - -uint8_t subghz_protocol_decoder_magellan_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderMagellan* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_magellan_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderMagellan* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_magellan_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderMagellan* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_magellan_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_magellan_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderMagellan* instance = context; - subghz_protocol_magellan_check_remote_controller(&instance->generic); - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:0x%08lX\r\n" - "Sn:%03ld%03ld, Event:0x%02X\r\n" - "Stat:", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data & 0xFFFFFFFF), - (instance->generic.serial >> 8) & 0xFF, - instance->generic.serial & 0xFF, - instance->generic.btn); - - subghz_protocol_magellan_get_event_serialize(instance->generic.btn, output); -} diff --git a/applications/main/subghz/protocols/magellan.h b/applications/main/subghz/protocols/magellan.h deleted file mode 100644 index a179c9cb4..000000000 --- a/applications/main/subghz/protocols/magellan.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_MAGELLAN_NAME "Magellan" - -typedef struct SubGhzProtocolDecoderMagellan SubGhzProtocolDecoderMagellan; -typedef struct SubGhzProtocolEncoderMagellan SubGhzProtocolEncoderMagellan; - -extern const SubGhzProtocolDecoder subghz_protocol_magellan_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_magellan_encoder; -extern const SubGhzProtocol subghz_protocol_magellan; - -/** - * Allocate SubGhzProtocolEncoderMagellan. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderMagellan* pointer to a SubGhzProtocolEncoderMagellan instance - */ -void* subghz_protocol_encoder_magellan_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderMagellan. - * @param context Pointer to a SubGhzProtocolEncoderMagellan instance - */ -void subghz_protocol_encoder_magellan_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderMagellan instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_magellan_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderMagellan instance - */ -void subghz_protocol_encoder_magellan_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderMagellan instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_magellan_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderMagellan. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderMagellan* pointer to a SubGhzProtocolDecoderMagellan instance - */ -void* subghz_protocol_decoder_magellan_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderMagellan. - * @param context Pointer to a SubGhzProtocolDecoderMagellan instance - */ -void subghz_protocol_decoder_magellan_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderMagellan. - * @param context Pointer to a SubGhzProtocolDecoderMagellan instance - */ -void subghz_protocol_decoder_magellan_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderMagellan instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_magellan_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderMagellan instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_magellan_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderMagellan. - * @param context Pointer to a SubGhzProtocolDecoderMagellan instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_magellan_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderMagellan. - * @param context Pointer to a SubGhzProtocolDecoderMagellan instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_magellan_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderMagellan instance - * @param output Resulting text - */ -void subghz_protocol_decoder_magellan_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/marantec.c b/applications/main/subghz/protocols/marantec.c deleted file mode 100644 index d557c29b0..000000000 --- a/applications/main/subghz/protocols/marantec.c +++ /dev/null @@ -1,393 +0,0 @@ -#include "marantec.h" -#include -#include -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolMarantec" - -static const SubGhzBlockConst subghz_protocol_marantec_const = { - .te_short = 1000, - .te_long = 2000, - .te_delta = 200, - .min_count_bit_for_found = 49, -}; - -struct SubGhzProtocolDecoderMarantec { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - ManchesterState manchester_saved_state; - uint16_t header_count; -}; - -struct SubGhzProtocolEncoderMarantec { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - MarantecDecoderStepReset = 0, - MarantecDecoderFoundHeader, - MarantecDecoderStepDecoderData, -} MarantecDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_marantec_decoder = { - .alloc = subghz_protocol_decoder_marantec_alloc, - .free = subghz_protocol_decoder_marantec_free, - - .feed = subghz_protocol_decoder_marantec_feed, - .reset = subghz_protocol_decoder_marantec_reset, - - .get_hash_data = subghz_protocol_decoder_marantec_get_hash_data, - .serialize = subghz_protocol_decoder_marantec_serialize, - .deserialize = subghz_protocol_decoder_marantec_deserialize, - .get_string = subghz_protocol_decoder_marantec_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_marantec_encoder = { - .alloc = subghz_protocol_encoder_marantec_alloc, - .free = subghz_protocol_encoder_marantec_free, - - .deserialize = subghz_protocol_encoder_marantec_deserialize, - .stop = subghz_protocol_encoder_marantec_stop, - .yield = subghz_protocol_encoder_marantec_yield, -}; - -const SubGhzProtocol subghz_protocol_marantec = { - .name = SUBGHZ_PROTOCOL_MARANTEC_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_marantec_decoder, - .encoder = &subghz_protocol_marantec_encoder, -}; - -void* subghz_protocol_encoder_marantec_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderMarantec* instance = malloc(sizeof(SubGhzProtocolEncoderMarantec)); - - instance->base.protocol = &subghz_protocol_marantec; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 256; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_marantec_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderMarantec* instance = context; - free(instance->encoder.upload); - free(instance); -} - -static LevelDuration - subghz_protocol_encoder_marantec_add_duration_to_upload(ManchesterEncoderResult result) { - LevelDuration data = {.duration = 0, .level = 0}; - switch(result) { - case ManchesterEncoderResultShortLow: - data.duration = subghz_protocol_marantec_const.te_short; - data.level = false; - break; - case ManchesterEncoderResultLongLow: - data.duration = subghz_protocol_marantec_const.te_long; - data.level = false; - break; - case ManchesterEncoderResultLongHigh: - data.duration = subghz_protocol_marantec_const.te_long; - data.level = true; - break; - case ManchesterEncoderResultShortHigh: - data.duration = subghz_protocol_marantec_const.te_short; - data.level = true; - break; - - default: - furi_crash("SubGhz: ManchesterEncoderResult is incorrect."); - break; - } - return level_duration_make(data.level, data.duration); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderMarantec instance - */ -static void subghz_protocol_encoder_marantec_get_upload(SubGhzProtocolEncoderMarantec* instance) { - furi_assert(instance); - size_t index = 0; - - ManchesterEncoderState enc_state; - manchester_encoder_reset(&enc_state); - ManchesterEncoderResult result; - - if(!manchester_encoder_advance( - &enc_state, - bit_read(instance->generic.data, instance->generic.data_count_bit - 1), - &result)) { - instance->encoder.upload[index++] = - subghz_protocol_encoder_marantec_add_duration_to_upload(result); - manchester_encoder_advance( - &enc_state, - bit_read(instance->generic.data, instance->generic.data_count_bit - 1), - &result); - } - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_marantec_const.te_long * 5); - - for(uint8_t i = instance->generic.data_count_bit - 1; i > 0; i--) { - if(!manchester_encoder_advance( - &enc_state, bit_read(instance->generic.data, i - 1), &result)) { - instance->encoder.upload[index++] = - subghz_protocol_encoder_marantec_add_duration_to_upload(result); - manchester_encoder_advance( - &enc_state, bit_read(instance->generic.data, i - 1), &result); - } - instance->encoder.upload[index++] = - subghz_protocol_encoder_marantec_add_duration_to_upload(result); - } - instance->encoder.upload[index] = subghz_protocol_encoder_marantec_add_duration_to_upload( - manchester_encoder_finish(&enc_state)); - if(level_duration_get_level(instance->encoder.upload[index])) { - index++; - } - instance->encoder.size_upload = index; -} - -uint8_t subghz_protocol_marantec_crc8(uint8_t* data, size_t len) { - uint8_t crc = 0x08; - size_t i, j; - for(i = 0; i < len; i++) { - crc ^= data[i]; - for(j = 0; j < 8; j++) { - if((crc & 0x80) != 0) - crc = (uint8_t)((crc << 1) ^ 0x1D); - else - crc <<= 1; - } - } - return crc; -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - */ -static void subghz_protocol_marantec_remote_controller(SubGhzBlockGeneric* instance) { - instance->btn = (instance->data >> 16) & 0xF; - instance->serial = ((instance->data >> 12) & 0xFFFFFF00) | ((instance->data >> 8) & 0xFF); -} - -bool subghz_protocol_encoder_marantec_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderMarantec* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_marantec_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - subghz_protocol_marantec_remote_controller(&instance->generic); - subghz_protocol_encoder_marantec_get_upload(instance); - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_marantec_stop(void* context) { - SubGhzProtocolEncoderMarantec* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_marantec_yield(void* context) { - SubGhzProtocolEncoderMarantec* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_marantec_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderMarantec* instance = malloc(sizeof(SubGhzProtocolDecoderMarantec)); - instance->base.protocol = &subghz_protocol_marantec; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_marantec_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderMarantec* instance = context; - free(instance); -} - -void subghz_protocol_decoder_marantec_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderMarantec* instance = context; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventReset, - &instance->manchester_saved_state, - NULL); -} - -void subghz_protocol_decoder_marantec_feed(void* context, bool level, volatile uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderMarantec* instance = context; - ManchesterEvent event = ManchesterEventReset; - - switch(instance->decoder.parser_step) { - case MarantecDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_marantec_const.te_long * 5) < - subghz_protocol_marantec_const.te_delta * 8)) { - //Found header marantec - instance->decoder.parser_step = MarantecDecoderStepDecoderData; - instance->decoder.decode_data = 1; - instance->decoder.decode_count_bit = 1; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventReset, - &instance->manchester_saved_state, - NULL); - } - break; - case MarantecDecoderStepDecoderData: - if(!level) { - if(DURATION_DIFF(duration, subghz_protocol_marantec_const.te_short) < - subghz_protocol_marantec_const.te_delta) { - event = ManchesterEventShortLow; - } else if( - DURATION_DIFF(duration, subghz_protocol_marantec_const.te_long) < - subghz_protocol_marantec_const.te_delta) { - event = ManchesterEventLongLow; - } else if( - duration >= ((uint32_t)subghz_protocol_marantec_const.te_long * 2 + - subghz_protocol_marantec_const.te_delta)) { - if(instance->decoder.decode_count_bit == - subghz_protocol_marantec_const.min_count_bit_for_found) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 1; - instance->decoder.decode_count_bit = 1; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventReset, - &instance->manchester_saved_state, - NULL); - } else { - instance->decoder.parser_step = MarantecDecoderStepReset; - } - } else { - if(DURATION_DIFF(duration, subghz_protocol_marantec_const.te_short) < - subghz_protocol_marantec_const.te_delta) { - event = ManchesterEventShortHigh; - } else if( - DURATION_DIFF(duration, subghz_protocol_marantec_const.te_long) < - subghz_protocol_marantec_const.te_delta) { - event = ManchesterEventLongHigh; - } else { - instance->decoder.parser_step = MarantecDecoderStepReset; - } - } - if(event != ManchesterEventReset) { - bool data; - bool data_ok = manchester_advance( - instance->manchester_saved_state, event, &instance->manchester_saved_state, &data); - - if(data_ok) { - instance->decoder.decode_data = (instance->decoder.decode_data << 1) | data; - instance->decoder.decode_count_bit++; - } - } - break; - } -} - -uint8_t subghz_protocol_decoder_marantec_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderMarantec* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_marantec_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderMarantec* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_marantec_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderMarantec* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_marantec_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_marantec_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderMarantec* instance = context; - subghz_protocol_marantec_remote_controller(&instance->generic); - - furi_string_cat_printf( - output, - "%s %db\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%07lX \r\n" - "Btn:%X\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)(instance->generic.data & 0xFFFFFFFF), - instance->generic.serial, - instance->generic.btn); -} diff --git a/applications/main/subghz/protocols/marantec.h b/applications/main/subghz/protocols/marantec.h deleted file mode 100644 index e330ccf16..000000000 --- a/applications/main/subghz/protocols/marantec.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_MARANTEC_NAME "Marantec" - -typedef struct SubGhzProtocolDecoderMarantec SubGhzProtocolDecoderMarantec; -typedef struct SubGhzProtocolEncoderMarantec SubGhzProtocolEncoderMarantec; - -extern const SubGhzProtocolDecoder subghz_protocol_marantec_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_marantec_encoder; -extern const SubGhzProtocol subghz_protocol_marantec; - -/** - * Allocate SubGhzProtocolEncoderMarantec. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderMarantec* pointer to a SubGhzProtocolEncoderMarantec instance - */ -void* subghz_protocol_encoder_marantec_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderMarantec. - * @param context Pointer to a SubGhzProtocolEncoderMarantec instance - */ -void subghz_protocol_encoder_marantec_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderMarantec instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_marantec_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderMarantec instance - */ -void subghz_protocol_encoder_marantec_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderMarantec instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_marantec_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderMarantec. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderMarantec* pointer to a SubGhzProtocolDecoderMarantec instance - */ -void* subghz_protocol_decoder_marantec_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderMarantec. - * @param context Pointer to a SubGhzProtocolDecoderMarantec instance - */ -void subghz_protocol_decoder_marantec_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderMarantec. - * @param context Pointer to a SubGhzProtocolDecoderMarantec instance - */ -void subghz_protocol_decoder_marantec_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderMarantec instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_marantec_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderMarantec instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_marantec_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderMarantec. - * @param context Pointer to a SubGhzProtocolDecoderMarantec instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_marantec_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderMarantec. - * @param context Pointer to a SubGhzProtocolDecoderMarantec instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_marantec_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderMarantec instance - * @param output Resulting text - */ -void subghz_protocol_decoder_marantec_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/megacode.c b/applications/main/subghz/protocols/megacode.c deleted file mode 100644 index 05b5b6894..000000000 --- a/applications/main/subghz/protocols/megacode.c +++ /dev/null @@ -1,429 +0,0 @@ -#include "megacode.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -/* - * Help - * https://wiki.cuvoodoo.info/doku.php?id=megacode - * https://wiki.cuvoodoo.info/lib/exe/fetch.php?media=megacode:megacode_1.pdf - * https://fccid.io/EF4ACP00872/Test-Report/Megacode-2-112615.pdf - * https://github.com/aaronsp777/megadecoder - * https://github.com/rjmendez/Linear_keyfob - * https://github.com/j07rdi/Linear_MegaCode_Garage_Remote - * - */ - -#define TAG "SubGhzProtocolMegaCode" - -static const SubGhzBlockConst subghz_protocol_megacode_const = { - .te_short = 1000, - .te_long = 1000, - .te_delta = 200, - .min_count_bit_for_found = 24, -}; - -struct SubGhzProtocolDecoderMegaCode { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - uint8_t last_bit; -}; - -struct SubGhzProtocolEncoderMegaCode { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - MegaCodeDecoderStepReset = 0, - MegaCodeDecoderStepFoundStartBit, - MegaCodeDecoderStepSaveDuration, - MegaCodeDecoderStepCheckDuration, -} MegaCodeDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_megacode_decoder = { - .alloc = subghz_protocol_decoder_megacode_alloc, - .free = subghz_protocol_decoder_megacode_free, - - .feed = subghz_protocol_decoder_megacode_feed, - .reset = subghz_protocol_decoder_megacode_reset, - - .get_hash_data = subghz_protocol_decoder_megacode_get_hash_data, - .serialize = subghz_protocol_decoder_megacode_serialize, - .deserialize = subghz_protocol_decoder_megacode_deserialize, - .get_string = subghz_protocol_decoder_megacode_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_megacode_encoder = { - .alloc = subghz_protocol_encoder_megacode_alloc, - .free = subghz_protocol_encoder_megacode_free, - - .deserialize = subghz_protocol_encoder_megacode_deserialize, - .stop = subghz_protocol_encoder_megacode_stop, - .yield = subghz_protocol_encoder_megacode_yield, -}; - -const SubGhzProtocol subghz_protocol_megacode = { - .name = SUBGHZ_PROTOCOL_MEGACODE_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_315 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_megacode_decoder, - .encoder = &subghz_protocol_megacode_encoder, -}; - -void* subghz_protocol_encoder_megacode_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderMegaCode* instance = malloc(sizeof(SubGhzProtocolEncoderMegaCode)); - - instance->base.protocol = &subghz_protocol_megacode; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 52; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_megacode_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderMegaCode* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderMegaCode instance - * @return true On success - */ -static bool subghz_protocol_encoder_megacode_get_upload(SubGhzProtocolEncoderMegaCode* instance) { - furi_assert(instance); - uint8_t last_bit = 0; - size_t size_upload = (instance->generic.data_count_bit * 2); - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - - /* - * Due to the nature of the protocol - * - * 00000 1 - * _____|-| = 1 becomes - * - * 00 1 000 - * __|-|___ = 0 becomes - * - * it's easier for us to generate an upload backwards - */ - - size_t index = size_upload - 1; - - // Send end level - instance->encoder.upload[index--] = - level_duration_make(true, (uint32_t)subghz_protocol_megacode_const.te_short); - if(bit_read(instance->generic.data, 0)) { - last_bit = 1; - } else { - last_bit = 0; - } - - //Send key data - for(uint8_t i = 1; i < instance->generic.data_count_bit; i++) { - if(bit_read(instance->generic.data, i)) { - //if bit 1 - instance->encoder.upload[index--] = level_duration_make( - false, - last_bit ? (uint32_t)subghz_protocol_megacode_const.te_short * 5 : - (uint32_t)subghz_protocol_megacode_const.te_short * 2); - last_bit = 1; - } else { - //if bit 0 - instance->encoder.upload[index--] = level_duration_make( - false, - last_bit ? (uint32_t)subghz_protocol_megacode_const.te_short * 8 : - (uint32_t)subghz_protocol_megacode_const.te_short * 5); - last_bit = 0; - } - instance->encoder.upload[index--] = - level_duration_make(true, (uint32_t)subghz_protocol_megacode_const.te_short); - } - - //Send PT_GUARD - if(bit_read(instance->generic.data, 0)) { - //if end bit 1 - instance->encoder.upload[index] = - level_duration_make(false, (uint32_t)subghz_protocol_megacode_const.te_short * 11); - } else { - //if end bit 1 - instance->encoder.upload[index] = - level_duration_make(false, (uint32_t)subghz_protocol_megacode_const.te_short * 14); - } - - return true; -} - -bool subghz_protocol_encoder_megacode_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderMegaCode* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_megacode_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_megacode_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_megacode_stop(void* context) { - SubGhzProtocolEncoderMegaCode* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_megacode_yield(void* context) { - SubGhzProtocolEncoderMegaCode* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_megacode_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderMegaCode* instance = malloc(sizeof(SubGhzProtocolDecoderMegaCode)); - instance->base.protocol = &subghz_protocol_megacode; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_megacode_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderMegaCode* instance = context; - free(instance); -} - -void subghz_protocol_decoder_megacode_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderMegaCode* instance = context; - instance->decoder.parser_step = MegaCodeDecoderStepReset; -} - -void subghz_protocol_decoder_megacode_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderMegaCode* instance = context; - switch(instance->decoder.parser_step) { - case MegaCodeDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_megacode_const.te_short * 13) < - subghz_protocol_megacode_const.te_delta * 17)) { //10..16ms - //Found header MegaCode - instance->decoder.parser_step = MegaCodeDecoderStepFoundStartBit; - } - break; - case MegaCodeDecoderStepFoundStartBit: - if(level && (DURATION_DIFF(duration, subghz_protocol_megacode_const.te_short) < - subghz_protocol_megacode_const.te_delta)) { - //Found start bit MegaCode - instance->decoder.parser_step = MegaCodeDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->last_bit = 1; - - } else { - instance->decoder.parser_step = MegaCodeDecoderStepReset; - } - break; - case MegaCodeDecoderStepSaveDuration: - if(!level) { //save interval - if(duration >= (subghz_protocol_megacode_const.te_short * 10)) { - instance->decoder.parser_step = MegaCodeDecoderStepReset; - if(instance->decoder.decode_count_bit == - subghz_protocol_megacode_const.min_count_bit_for_found) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - break; - } - - if(!instance->last_bit) { - instance->decoder.te_last = duration - subghz_protocol_megacode_const.te_short * 3; - } else { - instance->decoder.te_last = duration; - } - instance->decoder.parser_step = MegaCodeDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = MegaCodeDecoderStepReset; - } - break; - case MegaCodeDecoderStepCheckDuration: - if(level) { - if((DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_megacode_const.te_short * 5) < - subghz_protocol_megacode_const.te_delta * 5) && - (DURATION_DIFF(duration, subghz_protocol_megacode_const.te_short) < - subghz_protocol_megacode_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->last_bit = 1; - instance->decoder.parser_step = MegaCodeDecoderStepSaveDuration; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_megacode_const.te_short * 2) < - subghz_protocol_megacode_const.te_delta * 2) && - (DURATION_DIFF(duration, subghz_protocol_megacode_const.te_short) < - subghz_protocol_megacode_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->last_bit = 0; - instance->decoder.parser_step = MegaCodeDecoderStepSaveDuration; - } else - instance->decoder.parser_step = MegaCodeDecoderStepReset; - } else { - instance->decoder.parser_step = MegaCodeDecoderStepReset; - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - */ -static void subghz_protocol_megacode_check_remote_controller(SubGhzBlockGeneric* instance) { - /* - * Short: 1000 µs - * Long: 1000 µs - * Gap: 11000 .. 14000 µs - * A Linear Megacode transmission consists of 24 bit frames starting with - * the most significant bit and ending with the least. Each of the 24 bit - * frames is 6 milliseconds wide and always contains a single 1 millisecond - * pulse. A frame with more than 1 pulse or a frame with no pulse is invalid - * and a receiver should reset and begin watching for another start bit. - * Start bit is always 1. - * - * - * Example (I created with my own remote): - * Remote “A” has the code “17316”, a Facility Code of “3”, and a single button. - * Start bit (S) = 1 - * Facility Code 3 (F) = 0011 - * Remote Code (Key) 17316 = 43A4 = 0100001110100100 - * Button (Btn) 1 = 001 - * S F Key Btn - * Result = 1|0011|0100001110100100|001 - * - * 00000 1 - * _____|-| = 1 becomes - * - * 00 1 000 - * __|-|___ = 0 becomes - * - * The device needs to transmit with a 9000 µs gap between retransmissions: - * 000001 001000 001000 000001 000001 001000 000001 001000 001000 001000 001000 000001 - * 000001 000001 001000 000001 001000 001000 000001 001000 001000 001000 001000 000001 - * wait 9000 µs - * 000001 001000 001000 000001 000001 001000 000001 001000 001000 001000 001000 000001 - * 000001 000001 001000 000001 001000 001000 000001 001000 001000 001000 001000 000001 - * - */ - if((instance->data >> 23) == 1) { - instance->serial = (instance->data >> 3) & 0xFFFF; - instance->btn = instance->data & 0b111; - instance->cnt = (instance->data >> 19) & 0b1111; - } else { - instance->serial = 0; - instance->btn = 0; - instance->cnt = 0; - } -} - -uint8_t subghz_protocol_decoder_megacode_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderMegaCode* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_megacode_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderMegaCode* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_megacode_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderMegaCode* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_megacode_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_megacode_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderMegaCode* instance = context; - subghz_protocol_megacode_check_remote_controller(&instance->generic); - - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:0x%06lX\r\n" - "Sn:0x%04lX - %lu\r\n" - "Facility:%lX Btn:%X\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)instance->generic.data, - instance->generic.serial, - instance->generic.serial, - instance->generic.cnt, - instance->generic.btn); -} diff --git a/applications/main/subghz/protocols/megacode.h b/applications/main/subghz/protocols/megacode.h deleted file mode 100644 index e31434fa3..000000000 --- a/applications/main/subghz/protocols/megacode.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_MEGACODE_NAME "MegaCode" - -typedef struct SubGhzProtocolDecoderMegaCode SubGhzProtocolDecoderMegaCode; -typedef struct SubGhzProtocolEncoderMegaCode SubGhzProtocolEncoderMegaCode; - -extern const SubGhzProtocolDecoder subghz_protocol_megacode_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_megacode_encoder; -extern const SubGhzProtocol subghz_protocol_megacode; - -/** - * Allocate SubGhzProtocolEncoderMegaCode. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderMegaCode* pointer to a SubGhzProtocolEncoderMegaCode instance - */ -void* subghz_protocol_encoder_megacode_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderMegaCode. - * @param context Pointer to a SubGhzProtocolEncoderMegaCode instance - */ -void subghz_protocol_encoder_megacode_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderMegaCode instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_megacode_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderMegaCode instance - */ -void subghz_protocol_encoder_megacode_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderMegaCode instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_megacode_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderMegaCode. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderMegaCode* pointer to a SubGhzProtocolDecoderMegaCode instance - */ -void* subghz_protocol_decoder_megacode_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderMegaCode. - * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance - */ -void subghz_protocol_decoder_megacode_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderMegaCode. - * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance - */ -void subghz_protocol_decoder_megacode_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_megacode_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_megacode_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderMegaCode. - * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_megacode_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderMegaCode. - * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_megacode_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderMegaCode instance - * @param output Resulting text - */ -void subghz_protocol_decoder_megacode_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/nero_radio.c b/applications/main/subghz/protocols/nero_radio.c deleted file mode 100644 index c8126b1e1..000000000 --- a/applications/main/subghz/protocols/nero_radio.c +++ /dev/null @@ -1,397 +0,0 @@ -#include "nero_radio.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolNeroRadio" - -static const SubGhzBlockConst subghz_protocol_nero_radio_const = { - .te_short = 200, - .te_long = 400, - .te_delta = 80, - .min_count_bit_for_found = 56, -}; - -struct SubGhzProtocolDecoderNeroRadio { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - - uint16_t header_count; -}; - -struct SubGhzProtocolEncoderNeroRadio { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - NeroRadioDecoderStepReset = 0, - NeroRadioDecoderStepCheckPreambula, - NeroRadioDecoderStepSaveDuration, - NeroRadioDecoderStepCheckDuration, -} NeroRadioDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_nero_radio_decoder = { - .alloc = subghz_protocol_decoder_nero_radio_alloc, - .free = subghz_protocol_decoder_nero_radio_free, - - .feed = subghz_protocol_decoder_nero_radio_feed, - .reset = subghz_protocol_decoder_nero_radio_reset, - - .get_hash_data = subghz_protocol_decoder_nero_radio_get_hash_data, - .serialize = subghz_protocol_decoder_nero_radio_serialize, - .deserialize = subghz_protocol_decoder_nero_radio_deserialize, - .get_string = subghz_protocol_decoder_nero_radio_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_nero_radio_encoder = { - .alloc = subghz_protocol_encoder_nero_radio_alloc, - .free = subghz_protocol_encoder_nero_radio_free, - - .deserialize = subghz_protocol_encoder_nero_radio_deserialize, - .stop = subghz_protocol_encoder_nero_radio_stop, - .yield = subghz_protocol_encoder_nero_radio_yield, -}; - -const SubGhzProtocol subghz_protocol_nero_radio = { - .name = SUBGHZ_PROTOCOL_NERO_RADIO_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_nero_radio_decoder, - .encoder = &subghz_protocol_nero_radio_encoder, -}; - -void* subghz_protocol_encoder_nero_radio_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderNeroRadio* instance = malloc(sizeof(SubGhzProtocolEncoderNeroRadio)); - - instance->base.protocol = &subghz_protocol_nero_radio; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 256; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_nero_radio_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderNeroRadio* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderNeroRadio instance - * @return true On success - */ -static bool - subghz_protocol_encoder_nero_radio_get_upload(SubGhzProtocolEncoderNeroRadio* instance) { - furi_assert(instance); - size_t index = 0; - size_t size_upload = 49 * 2 + 2 + (instance->generic.data_count_bit * 2); - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - - //Send header - for(uint8_t i = 0; i < 49; i++) { - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_nero_radio_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_nero_radio_const.te_short); - } - - //Send start bit - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_nero_radio_const.te_short * 4); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_nero_radio_const.te_short); - - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 1; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_nero_radio_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_nero_radio_const.te_short); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_nero_radio_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_nero_radio_const.te_long); - } - } - if(bit_read(instance->generic.data, 0)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_nero_radio_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_nero_radio_const.te_short * 37); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_nero_radio_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_nero_radio_const.te_short * 37); - } - return true; -} - -bool subghz_protocol_encoder_nero_radio_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderNeroRadio* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_nero_radio_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_nero_radio_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_nero_radio_stop(void* context) { - SubGhzProtocolEncoderNeroRadio* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_nero_radio_yield(void* context) { - SubGhzProtocolEncoderNeroRadio* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_nero_radio_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderNeroRadio* instance = malloc(sizeof(SubGhzProtocolDecoderNeroRadio)); - instance->base.protocol = &subghz_protocol_nero_radio; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_nero_radio_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderNeroRadio* instance = context; - free(instance); -} - -void subghz_protocol_decoder_nero_radio_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderNeroRadio* instance = context; - instance->decoder.parser_step = NeroRadioDecoderStepReset; -} - -void subghz_protocol_decoder_nero_radio_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderNeroRadio* instance = context; - - switch(instance->decoder.parser_step) { - case NeroRadioDecoderStepReset: - if((level) && (DURATION_DIFF(duration, subghz_protocol_nero_radio_const.te_short) < - subghz_protocol_nero_radio_const.te_delta)) { - instance->decoder.parser_step = NeroRadioDecoderStepCheckPreambula; - instance->decoder.te_last = duration; - instance->header_count = 0; - } - break; - case NeroRadioDecoderStepCheckPreambula: - if(level) { - if((DURATION_DIFF(duration, subghz_protocol_nero_radio_const.te_short) < - subghz_protocol_nero_radio_const.te_delta) || - (DURATION_DIFF(duration, subghz_protocol_nero_radio_const.te_short * 4) < - subghz_protocol_nero_radio_const.te_delta)) { - instance->decoder.te_last = duration; - } else { - instance->decoder.parser_step = NeroRadioDecoderStepReset; - } - } else if( - DURATION_DIFF(duration, subghz_protocol_nero_radio_const.te_short) < - subghz_protocol_nero_radio_const.te_delta) { - if(DURATION_DIFF(instance->decoder.te_last, subghz_protocol_nero_radio_const.te_short) < - subghz_protocol_nero_radio_const.te_delta) { - // Found header - instance->header_count++; - break; - } else if( - DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_nero_radio_const.te_short * 4) < - subghz_protocol_nero_radio_const.te_delta) { - // Found start bit - if(instance->header_count > 40) { - instance->decoder.parser_step = NeroRadioDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else { - instance->decoder.parser_step = NeroRadioDecoderStepReset; - } - } else { - instance->decoder.parser_step = NeroRadioDecoderStepReset; - } - } else { - instance->decoder.parser_step = NeroRadioDecoderStepReset; - } - break; - case NeroRadioDecoderStepSaveDuration: - if(level) { - instance->decoder.te_last = duration; - instance->decoder.parser_step = NeroRadioDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = NeroRadioDecoderStepReset; - } - break; - case NeroRadioDecoderStepCheckDuration: - if(!level) { - if(duration >= ((uint32_t)subghz_protocol_nero_radio_const.te_short * 10 + - subghz_protocol_nero_radio_const.te_delta * 2)) { - //Found stop bit - if(DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_nero_radio_const.te_short) < - subghz_protocol_nero_radio_const.te_delta) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - } else if( - DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_nero_radio_const.te_long) < - subghz_protocol_nero_radio_const.te_delta) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - } - instance->decoder.parser_step = NeroRadioDecoderStepReset; - if(instance->decoder.decode_count_bit == - subghz_protocol_nero_radio_const.min_count_bit_for_found) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->decoder.parser_step = NeroRadioDecoderStepReset; //-V1048 - break; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_nero_radio_const.te_short) < - subghz_protocol_nero_radio_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_nero_radio_const.te_long) < - subghz_protocol_nero_radio_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = NeroRadioDecoderStepSaveDuration; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_nero_radio_const.te_long) < - subghz_protocol_nero_radio_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_nero_radio_const.te_short) < - subghz_protocol_nero_radio_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = NeroRadioDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = NeroRadioDecoderStepReset; - } - } else { - instance->decoder.parser_step = NeroRadioDecoderStepReset; - } - break; - } -} - -uint8_t subghz_protocol_decoder_nero_radio_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderNeroRadio* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_nero_radio_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderNeroRadio* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_nero_radio_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderNeroRadio* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_nero_radio_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_nero_radio_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderNeroRadio* instance = context; - - uint32_t code_found_hi = instance->generic.data >> 32; - uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; - - uint64_t code_found_reverse = subghz_protocol_blocks_reverse_key( - instance->generic.data, instance->generic.data_count_bit); - - uint32_t code_found_reverse_hi = code_found_reverse >> 32; - uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Yek:0x%lX%08lX\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - code_found_hi, - code_found_lo, - code_found_reverse_hi, - code_found_reverse_lo); -} diff --git a/applications/main/subghz/protocols/nero_radio.h b/applications/main/subghz/protocols/nero_radio.h deleted file mode 100644 index 361da6173..000000000 --- a/applications/main/subghz/protocols/nero_radio.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_NERO_RADIO_NAME "Nero Radio" - -typedef struct SubGhzProtocolDecoderNeroRadio SubGhzProtocolDecoderNeroRadio; -typedef struct SubGhzProtocolEncoderNeroRadio SubGhzProtocolEncoderNeroRadio; - -extern const SubGhzProtocolDecoder subghz_protocol_nero_radio_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_nero_radio_encoder; -extern const SubGhzProtocol subghz_protocol_nero_radio; - -/** - * Allocate SubGhzProtocolEncoderNeroRadio. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderNeroRadio* pointer to a SubGhzProtocolEncoderNeroRadio instance - */ -void* subghz_protocol_encoder_nero_radio_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderNeroRadio. - * @param context Pointer to a SubGhzProtocolEncoderNeroRadio instance - */ -void subghz_protocol_encoder_nero_radio_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderNeroRadio instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_nero_radio_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderNeroRadio instance - */ -void subghz_protocol_encoder_nero_radio_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderNeroRadio instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_nero_radio_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderNeroRadio. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderNeroRadio* pointer to a SubGhzProtocolDecoderNeroRadio instance - */ -void* subghz_protocol_decoder_nero_radio_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderNeroRadio. - * @param context Pointer to a SubGhzProtocolDecoderNeroRadio instance - */ -void subghz_protocol_decoder_nero_radio_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderNeroRadio. - * @param context Pointer to a SubGhzProtocolDecoderNeroRadio instance - */ -void subghz_protocol_decoder_nero_radio_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderNeroRadio instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_nero_radio_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderNeroRadio instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_nero_radio_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderNeroRadio. - * @param context Pointer to a SubGhzProtocolDecoderNeroRadio instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_nero_radio_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderNeroRadio. - * @param context Pointer to a SubGhzProtocolDecoderNeroRadio instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_nero_radio_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderNeroRadio instance - * @param output Resulting text - */ -void subghz_protocol_decoder_nero_radio_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/nero_sketch.c b/applications/main/subghz/protocols/nero_sketch.c deleted file mode 100644 index b124b717b..000000000 --- a/applications/main/subghz/protocols/nero_sketch.c +++ /dev/null @@ -1,382 +0,0 @@ -#include "nero_sketch.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolNeroSketch" - -static const SubGhzBlockConst subghz_protocol_nero_sketch_const = { - .te_short = 330, - .te_long = 660, - .te_delta = 150, - .min_count_bit_for_found = 40, -}; - -struct SubGhzProtocolDecoderNeroSketch { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - uint16_t header_count; -}; - -struct SubGhzProtocolEncoderNeroSketch { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - NeroSketchDecoderStepReset = 0, - NeroSketchDecoderStepCheckPreambula, - NeroSketchDecoderStepSaveDuration, - NeroSketchDecoderStepCheckDuration, -} NeroSketchDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_nero_sketch_decoder = { - .alloc = subghz_protocol_decoder_nero_sketch_alloc, - .free = subghz_protocol_decoder_nero_sketch_free, - - .feed = subghz_protocol_decoder_nero_sketch_feed, - .reset = subghz_protocol_decoder_nero_sketch_reset, - - .get_hash_data = subghz_protocol_decoder_nero_sketch_get_hash_data, - .serialize = subghz_protocol_decoder_nero_sketch_serialize, - .deserialize = subghz_protocol_decoder_nero_sketch_deserialize, - .get_string = subghz_protocol_decoder_nero_sketch_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_nero_sketch_encoder = { - .alloc = subghz_protocol_encoder_nero_sketch_alloc, - .free = subghz_protocol_encoder_nero_sketch_free, - - .deserialize = subghz_protocol_encoder_nero_sketch_deserialize, - .stop = subghz_protocol_encoder_nero_sketch_stop, - .yield = subghz_protocol_encoder_nero_sketch_yield, -}; - -const SubGhzProtocol subghz_protocol_nero_sketch = { - .name = SUBGHZ_PROTOCOL_NERO_SKETCH_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_nero_sketch_decoder, - .encoder = &subghz_protocol_nero_sketch_encoder, -}; - -void* subghz_protocol_encoder_nero_sketch_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderNeroSketch* instance = malloc(sizeof(SubGhzProtocolEncoderNeroSketch)); - - instance->base.protocol = &subghz_protocol_nero_sketch; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 256; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_nero_sketch_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderNeroSketch* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderNeroSketch instance - * @return true On success - */ -static bool - subghz_protocol_encoder_nero_sketch_get_upload(SubGhzProtocolEncoderNeroSketch* instance) { - furi_assert(instance); - - size_t index = 0; - size_t size_upload = 47 * 2 + 2 + (instance->generic.data_count_bit * 2) + 2; - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - - //Send header - for(uint8_t i = 0; i < 47; i++) { - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_nero_sketch_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_nero_sketch_const.te_short); - } - - //Send start bit - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_nero_sketch_const.te_short * 4); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_nero_sketch_const.te_short); - - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_nero_sketch_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_nero_sketch_const.te_short); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_nero_sketch_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_nero_sketch_const.te_long); - } - } - - //Send stop bit - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_nero_sketch_const.te_short * 3); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_nero_sketch_const.te_short); - - return true; -} - -bool subghz_protocol_encoder_nero_sketch_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderNeroSketch* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_nero_sketch_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_nero_sketch_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_nero_sketch_stop(void* context) { - SubGhzProtocolEncoderNeroSketch* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_nero_sketch_yield(void* context) { - SubGhzProtocolEncoderNeroSketch* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_nero_sketch_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderNeroSketch* instance = malloc(sizeof(SubGhzProtocolDecoderNeroSketch)); - instance->base.protocol = &subghz_protocol_nero_sketch; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_nero_sketch_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderNeroSketch* instance = context; - free(instance); -} - -void subghz_protocol_decoder_nero_sketch_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderNeroSketch* instance = context; - instance->decoder.parser_step = NeroSketchDecoderStepReset; -} - -void subghz_protocol_decoder_nero_sketch_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderNeroSketch* instance = context; - - switch(instance->decoder.parser_step) { - case NeroSketchDecoderStepReset: - if((level) && (DURATION_DIFF(duration, subghz_protocol_nero_sketch_const.te_short) < - subghz_protocol_nero_sketch_const.te_delta)) { - instance->decoder.parser_step = NeroSketchDecoderStepCheckPreambula; - instance->decoder.te_last = duration; - instance->header_count = 0; - } - break; - case NeroSketchDecoderStepCheckPreambula: - if(level) { - if((DURATION_DIFF(duration, subghz_protocol_nero_sketch_const.te_short) < - subghz_protocol_nero_sketch_const.te_delta) || - (DURATION_DIFF(duration, subghz_protocol_nero_sketch_const.te_short * 4) < - subghz_protocol_nero_sketch_const.te_delta)) { - instance->decoder.te_last = duration; - } else { - instance->decoder.parser_step = NeroSketchDecoderStepReset; - } - } else if( - DURATION_DIFF(duration, subghz_protocol_nero_sketch_const.te_short) < - subghz_protocol_nero_sketch_const.te_delta) { - if(DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_nero_sketch_const.te_short) < - subghz_protocol_nero_sketch_const.te_delta) { - // Found header - instance->header_count++; - break; - } else if( - DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_nero_sketch_const.te_short * 4) < - subghz_protocol_nero_sketch_const.te_delta) { - // Found start bit - if(instance->header_count > 40) { - instance->decoder.parser_step = NeroSketchDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else { - instance->decoder.parser_step = NeroSketchDecoderStepReset; - } - } else { - instance->decoder.parser_step = NeroSketchDecoderStepReset; - } - } else { - instance->decoder.parser_step = NeroSketchDecoderStepReset; - } - break; - case NeroSketchDecoderStepSaveDuration: - if(level) { - if(duration >= (subghz_protocol_nero_sketch_const.te_short * 2 + - subghz_protocol_nero_sketch_const.te_delta * 2)) { - //Found stop bit - instance->decoder.parser_step = NeroSketchDecoderStepReset; - if(instance->decoder.decode_count_bit == - subghz_protocol_nero_sketch_const.min_count_bit_for_found) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - break; - } else { - instance->decoder.te_last = duration; - instance->decoder.parser_step = NeroSketchDecoderStepCheckDuration; - } - - } else { - instance->decoder.parser_step = NeroSketchDecoderStepReset; - } - break; - case NeroSketchDecoderStepCheckDuration: - if(!level) { - if((DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_nero_sketch_const.te_short) < - subghz_protocol_nero_sketch_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_nero_sketch_const.te_long) < - subghz_protocol_nero_sketch_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = NeroSketchDecoderStepSaveDuration; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_nero_sketch_const.te_long) < - subghz_protocol_nero_sketch_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_nero_sketch_const.te_short) < - subghz_protocol_nero_sketch_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = NeroSketchDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = NeroSketchDecoderStepReset; - } - } else { - instance->decoder.parser_step = NeroSketchDecoderStepReset; - } - break; - } -} - -uint8_t subghz_protocol_decoder_nero_sketch_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderNeroSketch* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_nero_sketch_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderNeroSketch* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_nero_sketch_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderNeroSketch* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_nero_sketch_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_nero_sketch_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderNeroSketch* instance = context; - - uint32_t code_found_hi = instance->generic.data >> 32; - uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; - - uint64_t code_found_reverse = subghz_protocol_blocks_reverse_key( - instance->generic.data, instance->generic.data_count_bit); - - uint32_t code_found_reverse_hi = code_found_reverse >> 32; - uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Yek:0x%lX%08lX\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - code_found_hi, - code_found_lo, - code_found_reverse_hi, - code_found_reverse_lo); -} diff --git a/applications/main/subghz/protocols/nero_sketch.h b/applications/main/subghz/protocols/nero_sketch.h deleted file mode 100644 index ac87fb00a..000000000 --- a/applications/main/subghz/protocols/nero_sketch.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_NERO_SKETCH_NAME "Nero Sketch" - -typedef struct SubGhzProtocolDecoderNeroSketch SubGhzProtocolDecoderNeroSketch; -typedef struct SubGhzProtocolEncoderNeroSketch SubGhzProtocolEncoderNeroSketch; - -extern const SubGhzProtocolDecoder subghz_protocol_nero_sketch_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_nero_sketch_encoder; -extern const SubGhzProtocol subghz_protocol_nero_sketch; - -/** - * Allocate SubGhzProtocolEncoderNeroSketch. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderNeroSketch* pointer to a SubGhzProtocolEncoderNeroSketch instance - */ -void* subghz_protocol_encoder_nero_sketch_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderNeroSketch. - * @param context Pointer to a SubGhzProtocolEncoderNeroSketch instance - */ -void subghz_protocol_encoder_nero_sketch_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderNeroSketch instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_nero_sketch_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderNeroSketch instance - */ -void subghz_protocol_encoder_nero_sketch_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderNeroSketch instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_nero_sketch_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderNeroSketch. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderNeroSketch* pointer to a SubGhzProtocolDecoderNeroSketch instance - */ -void* subghz_protocol_decoder_nero_sketch_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderNeroSketch. - * @param context Pointer to a SubGhzProtocolDecoderNeroSketch instance - */ -void subghz_protocol_decoder_nero_sketch_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderNeroSketch. - * @param context Pointer to a SubGhzProtocolDecoderNeroSketch instance - */ -void subghz_protocol_decoder_nero_sketch_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderNeroSketch instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_nero_sketch_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderNeroSketch instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_nero_sketch_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderNeroSketch. - * @param context Pointer to a SubGhzProtocolDecoderNeroSketch instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_nero_sketch_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderNeroSketch. - * @param context Pointer to a SubGhzProtocolDecoderNeroSketch instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_nero_sketch_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderNeroSketch instance - * @param output Resulting text - */ -void subghz_protocol_decoder_nero_sketch_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/nice_flo.c b/applications/main/subghz/protocols/nice_flo.c deleted file mode 100644 index a57d5f4da..000000000 --- a/applications/main/subghz/protocols/nice_flo.c +++ /dev/null @@ -1,330 +0,0 @@ -#include "nice_flo.h" -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolNiceFLO" - -static const SubGhzBlockConst subghz_protocol_nice_flo_const = { - .te_short = 700, - .te_long = 1400, - .te_delta = 200, - .min_count_bit_for_found = 12, -}; - -struct SubGhzProtocolDecoderNiceFlo { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; -}; - -struct SubGhzProtocolEncoderNiceFlo { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - NiceFloDecoderStepReset = 0, - NiceFloDecoderStepFoundStartBit, - NiceFloDecoderStepSaveDuration, - NiceFloDecoderStepCheckDuration, -} NiceFloDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_nice_flo_decoder = { - .alloc = subghz_protocol_decoder_nice_flo_alloc, - .free = subghz_protocol_decoder_nice_flo_free, - - .feed = subghz_protocol_decoder_nice_flo_feed, - .reset = subghz_protocol_decoder_nice_flo_reset, - - .get_hash_data = subghz_protocol_decoder_nice_flo_get_hash_data, - .serialize = subghz_protocol_decoder_nice_flo_serialize, - .deserialize = subghz_protocol_decoder_nice_flo_deserialize, - .get_string = subghz_protocol_decoder_nice_flo_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_nice_flo_encoder = { - .alloc = subghz_protocol_encoder_nice_flo_alloc, - .free = subghz_protocol_encoder_nice_flo_free, - - .deserialize = subghz_protocol_encoder_nice_flo_deserialize, - .stop = subghz_protocol_encoder_nice_flo_stop, - .yield = subghz_protocol_encoder_nice_flo_yield, -}; - -const SubGhzProtocol subghz_protocol_nice_flo = { - .name = SUBGHZ_PROTOCOL_NICE_FLO_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_AM | - SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | - SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_nice_flo_decoder, - .encoder = &subghz_protocol_nice_flo_encoder, -}; - -void* subghz_protocol_encoder_nice_flo_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderNiceFlo* instance = malloc(sizeof(SubGhzProtocolEncoderNiceFlo)); - - instance->base.protocol = &subghz_protocol_nice_flo; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 52; //max 24bit*2 + 2 (start, stop) - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_nice_flo_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderNiceFlo* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderNiceFlo instance - * @return true On success - */ -static bool subghz_protocol_encoder_nice_flo_get_upload(SubGhzProtocolEncoderNiceFlo* instance) { - furi_assert(instance); - size_t index = 0; - size_t size_upload = (instance->generic.data_count_bit * 2) + 2; - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - //Send header - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_nice_flo_const.te_short * 36); - //Send start bit - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_nice_flo_const.te_short); - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_nice_flo_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_nice_flo_const.te_short); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_nice_flo_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_nice_flo_const.te_long); - } - } - return true; -} - -bool subghz_protocol_encoder_nice_flo_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderNiceFlo* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if((instance->generic.data_count_bit < - subghz_protocol_nice_flo_const.min_count_bit_for_found) || - (instance->generic.data_count_bit > - 2 * subghz_protocol_nice_flo_const.min_count_bit_for_found)) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_nice_flo_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_nice_flo_stop(void* context) { - SubGhzProtocolEncoderNiceFlo* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_nice_flo_yield(void* context) { - SubGhzProtocolEncoderNiceFlo* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_nice_flo_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderNiceFlo* instance = malloc(sizeof(SubGhzProtocolDecoderNiceFlo)); - instance->base.protocol = &subghz_protocol_nice_flo; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_nice_flo_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderNiceFlo* instance = context; - free(instance); -} - -void subghz_protocol_decoder_nice_flo_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderNiceFlo* instance = context; - instance->decoder.parser_step = NiceFloDecoderStepReset; -} - -void subghz_protocol_decoder_nice_flo_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderNiceFlo* instance = context; - - switch(instance->decoder.parser_step) { - case NiceFloDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_nice_flo_const.te_short * 36) < - subghz_protocol_nice_flo_const.te_delta * 36)) { - //Found header Nice Flo - instance->decoder.parser_step = NiceFloDecoderStepFoundStartBit; - } - break; - case NiceFloDecoderStepFoundStartBit: - if(!level) { - break; - } else if( - DURATION_DIFF(duration, subghz_protocol_nice_flo_const.te_short) < - subghz_protocol_nice_flo_const.te_delta) { - //Found start bit Nice Flo - instance->decoder.parser_step = NiceFloDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else { - instance->decoder.parser_step = NiceFloDecoderStepReset; - } - break; - case NiceFloDecoderStepSaveDuration: - if(!level) { //save interval - if(duration >= (subghz_protocol_nice_flo_const.te_short * 4)) { - instance->decoder.parser_step = NiceFloDecoderStepFoundStartBit; - if(instance->decoder.decode_count_bit >= - subghz_protocol_nice_flo_const.min_count_bit_for_found) { - instance->generic.serial = 0x0; - instance->generic.btn = 0x0; - - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - break; - } - instance->decoder.te_last = duration; - instance->decoder.parser_step = NiceFloDecoderStepCheckDuration; - } else { - instance->decoder.parser_step = NiceFloDecoderStepReset; - } - break; - case NiceFloDecoderStepCheckDuration: - if(level) { - if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_nice_flo_const.te_short) < - subghz_protocol_nice_flo_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_nice_flo_const.te_long) < - subghz_protocol_nice_flo_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = NiceFloDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_nice_flo_const.te_long) < - subghz_protocol_nice_flo_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_nice_flo_const.te_short) < - subghz_protocol_nice_flo_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = NiceFloDecoderStepSaveDuration; - } else - instance->decoder.parser_step = NiceFloDecoderStepReset; - } else { - instance->decoder.parser_step = NiceFloDecoderStepReset; - } - break; - } -} - -uint8_t subghz_protocol_decoder_nice_flo_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderNiceFlo* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_nice_flo_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderNiceFlo* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_nice_flo_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderNiceFlo* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if((instance->generic.data_count_bit < - subghz_protocol_nice_flo_const.min_count_bit_for_found) || - (instance->generic.data_count_bit > - 2 * subghz_protocol_nice_flo_const.min_count_bit_for_found)) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_nice_flo_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderNiceFlo* instance = context; - - uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; - uint64_t code_found_reverse = subghz_protocol_blocks_reverse_key( - instance->generic.data, instance->generic.data_count_bit); - uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:0x%08lX\r\n" - "Yek:0x%08lX\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - code_found_lo, - code_found_reverse_lo); -} diff --git a/applications/main/subghz/protocols/nice_flo.h b/applications/main/subghz/protocols/nice_flo.h deleted file mode 100644 index e382e6146..000000000 --- a/applications/main/subghz/protocols/nice_flo.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_NICE_FLO_NAME "Nice FLO" - -typedef struct SubGhzProtocolDecoderNiceFlo SubGhzProtocolDecoderNiceFlo; -typedef struct SubGhzProtocolEncoderNiceFlo SubGhzProtocolEncoderNiceFlo; - -extern const SubGhzProtocolDecoder subghz_protocol_nice_flo_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_nice_flo_encoder; -extern const SubGhzProtocol subghz_protocol_nice_flo; - -/** - * Allocate SubGhzProtocolEncoderNiceFlo. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderNiceFlo* pointer to a SubGhzProtocolEncoderNiceFlo instance - */ -void* subghz_protocol_encoder_nice_flo_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderNiceFlo. - * @param context Pointer to a SubGhzProtocolEncoderNiceFlo instance - */ -void subghz_protocol_encoder_nice_flo_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderNiceFlo instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_nice_flo_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderNiceFlo instance - */ -void subghz_protocol_encoder_nice_flo_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderNiceFlo instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_nice_flo_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderNiceFlo. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderNiceFlo* pointer to a SubGhzProtocolDecoderNiceFlo instance - */ -void* subghz_protocol_decoder_nice_flo_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderNiceFlo. - * @param context Pointer to a SubGhzProtocolDecoderNiceFlo instance - */ -void subghz_protocol_decoder_nice_flo_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderNiceFlo. - * @param context Pointer to a SubGhzProtocolDecoderNiceFlo instance - */ -void subghz_protocol_decoder_nice_flo_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderNiceFlo instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_nice_flo_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderNiceFlo instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_nice_flo_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderNiceFlo. - * @param context Pointer to a SubGhzProtocolDecoderNiceFlo instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_nice_flo_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderNiceFlo. - * @param context Pointer to a SubGhzProtocolDecoderNiceFlo instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_nice_flo_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderNiceFlo instance - * @param output Resulting text - */ -void subghz_protocol_decoder_nice_flo_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/nice_flor_s.c b/applications/main/subghz/protocols/nice_flor_s.c deleted file mode 100644 index 6447676cc..000000000 --- a/applications/main/subghz/protocols/nice_flor_s.c +++ /dev/null @@ -1,694 +0,0 @@ -#include "nice_flor_s.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -/* - * https://phreakerclub.com/1615 - * https://phreakerclub.com/forum/showthread.php?t=2360 - * https://vrtp.ru/index.php?showtopic=27867 - */ - -#define TAG "SubGhzProtocolNiceFlorS" - -#define NICE_ONE_COUNT_BIT 72 -#define NICE_ONE_NAME "Nice One" - -static const SubGhzBlockConst subghz_protocol_nice_flor_s_const = { - .te_short = 500, - .te_long = 1000, - .te_delta = 300, - .min_count_bit_for_found = 52, -}; - -struct SubGhzProtocolDecoderNiceFlorS { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - - const char* nice_flor_s_rainbow_table_file_name; - uint64_t data; -}; - -struct SubGhzProtocolEncoderNiceFlorS { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; - - const char* nice_flor_s_rainbow_table_file_name; -}; - -typedef enum { - NiceFlorSDecoderStepReset = 0, - NiceFlorSDecoderStepCheckHeader, - NiceFlorSDecoderStepFoundHeader, - NiceFlorSDecoderStepSaveDuration, - NiceFlorSDecoderStepCheckDuration, -} NiceFlorSDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_nice_flor_s_decoder = { - .alloc = subghz_protocol_decoder_nice_flor_s_alloc, - .free = subghz_protocol_decoder_nice_flor_s_free, - - .feed = subghz_protocol_decoder_nice_flor_s_feed, - .reset = subghz_protocol_decoder_nice_flor_s_reset, - - .get_hash_data = subghz_protocol_decoder_nice_flor_s_get_hash_data, - .serialize = subghz_protocol_decoder_nice_flor_s_serialize, - .deserialize = subghz_protocol_decoder_nice_flor_s_deserialize, - .get_string = subghz_protocol_decoder_nice_flor_s_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_nice_flor_s_encoder = { - .alloc = subghz_protocol_encoder_nice_flor_s_alloc, - .free = subghz_protocol_encoder_nice_flor_s_free, - - .deserialize = subghz_protocol_encoder_nice_flor_s_deserialize, - .stop = subghz_protocol_encoder_nice_flor_s_stop, - .yield = subghz_protocol_encoder_nice_flor_s_yield, -}; - -const SubGhzProtocol subghz_protocol_nice_flor_s = { - .name = SUBGHZ_PROTOCOL_NICE_FLOR_S_NAME, - .type = SubGhzProtocolTypeDynamic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_868 | SubGhzProtocolFlag_AM | - SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | - SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_nice_flor_s_decoder, - .encoder = &subghz_protocol_nice_flor_s_encoder, -}; - -static void subghz_protocol_nice_flor_s_remote_controller( - SubGhzBlockGeneric* instance, - const char* file_name); - -void* subghz_protocol_encoder_nice_flor_s_alloc(SubGhzEnvironment* environment) { - SubGhzProtocolEncoderNiceFlorS* instance = malloc(sizeof(SubGhzProtocolEncoderNiceFlorS)); - - instance->base.protocol = &subghz_protocol_nice_flor_s; - instance->generic.protocol_name = instance->base.protocol->name; - instance->nice_flor_s_rainbow_table_file_name = - subghz_environment_get_nice_flor_s_rainbow_table_file_name(environment); - if(instance->nice_flor_s_rainbow_table_file_name) { - FURI_LOG_D( - TAG, "Loading rainbow table from %s", instance->nice_flor_s_rainbow_table_file_name); - } - instance->encoder.repeat = 10; - instance->encoder.size_upload = 1728; //wrong!! upload 186*16 = 2976 - actual size about 1728 - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_nice_flor_s_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderNiceFlorS* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderNiceFlorS instance - * @return true On success - */ -static void subghz_protocol_encoder_nice_flor_s_get_upload( - SubGhzProtocolEncoderNiceFlorS* instance, - uint8_t btn, - const char* file_name) { - furi_assert(instance); - size_t index = 0; - btn = instance->generic.btn; - - size_t size_upload = ((instance->generic.data_count_bit * 2) + ((37 + 2 + 2) * 2) * 16); - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - } else { - instance->encoder.size_upload = size_upload; - } - - if(instance->generic.cnt < 0xFFFF) { - instance->generic.cnt++; - } else if(instance->generic.cnt >= 0xFFFF) { - instance->generic.cnt = 0; - } - uint64_t decrypt = ((uint64_t)instance->generic.serial << 16) | instance->generic.cnt; - uint64_t enc_part = subghz_protocol_nice_flor_s_encrypt(decrypt, file_name); - - for(int i = 0; i < 16; i++) { - static const uint64_t loops[16] = { - 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF}; - - uint8_t byte; - - byte = btn << 4 | (0xF ^ btn ^ loops[i]); - instance->generic.data = (uint64_t)byte << 44 | enc_part; - - //Send header - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_nice_flor_s_const.te_short * 37); - //Send start bit - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_nice_flor_s_const.te_short * 3); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_nice_flor_s_const.te_short * 3); - - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_nice_flor_s_const.te_long); - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_nice_flor_s_const.te_short); - } else { - //send bit 0 - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_nice_flor_s_const.te_short); - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_nice_flor_s_const.te_long); - } - } - //Send stop bit - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_nice_flor_s_const.te_short * 3); - //instance->encoder.upload[index++] = - //level_duration_make(false, (uint32_t)subghz_protocol_nice_flor_s_const.te_short * 3); - } - instance->encoder.size_upload = index; -} - -bool subghz_protocol_encoder_nice_flor_s_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderNiceFlorS* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - subghz_protocol_nice_flor_s_remote_controller( - &instance->generic, instance->nice_flor_s_rainbow_table_file_name); - subghz_protocol_encoder_nice_flor_s_get_upload( - instance, instance->generic.btn, instance->nice_flor_s_rainbow_table_file_name); - - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - uint8_t key_data[sizeof(uint64_t)] = {0}; - for(size_t i = 0; i < sizeof(uint64_t); i++) { - key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data >> i * 8) & 0xFF; - } - if(!flipper_format_update_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Unable to add Key"); - break; - } - - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_nice_flor_s_stop(void* context) { - SubGhzProtocolEncoderNiceFlorS* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_nice_flor_s_yield(void* context) { - SubGhzProtocolEncoderNiceFlorS* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -// /** -// * Read bytes from rainbow table -// * @param p array[10] P0-P1|P2-P3-P4-P5-P6-P7-P8-P9-P10 -// * @return crc -// */ -// static uint32_t subghz_protocol_nice_one_crc(uint8_t* p) { -// uint8_t crc = 0; -// uint8_t crc_data = 0xff; -// for(uint8_t i = 4; i < 68; i++) { -// if(subghz_protocol_blocks_get_bit_array(p, i)) { -// crc = crc_data ^ 1; -// } else { -// crc = crc_data; -// } -// crc_data >>= 1; -// if((crc & 0x01)) { -// crc_data ^= 0x97; -// } -// } -// crc = 0; -// for(uint8_t i = 0; i < 8; i++) { -// crc <<= 1; -// if((crc_data >> i) & 0x01) crc = crc | 1; -// } -// return crc; -// } - -// /** -// * Read bytes from rainbow table -// * @param p array[10] P0-P1|P2-P3-P4-P5-P6-P7-XX-XX-XX -// * @param num_parcel parcel number 0..15 -// * @param hold_bit 0 - the button was only pressed, 1 - the button was held down -// */ -// static void subghz_protocol_nice_one_get_data(uint8_t* p, uint8_t num_parcel, uint8_t hold_bit) { -// uint8_t k = 0; -// uint8_t crc = 0; -// p[1] = (p[1] & 0x0f) | ((0x0f ^ (p[0] & 0x0F) ^ num_parcel) << 4); -// if(num_parcel < 4) { -// k = 0x8f; -// } else { -// k = 0x80; -// } - -// if(!hold_bit) { -// hold_bit = 0; -// } else { -// hold_bit = 0x10; -// } -// k = num_parcel ^ k; -// p[7] = k; -// p[8] = hold_bit ^ (k << 4); - -// crc = subghz_protocol_nice_one_crc(p); - -// p[8] |= crc >> 4; -// p[9] = crc << 4; -// } - -/** - * Read bytes from rainbow table - * @param file_name Full path to rainbow table the file - * @param address Byte address in file - * @return data - */ -static uint8_t - subghz_protocol_nice_flor_s_get_byte_in_file(const char* file_name, uint32_t address) { - if(!file_name) return 0; - - uint8_t buffer[1] = {0}; - if(subghz_keystore_raw_get_data(file_name, address, buffer, sizeof(uint8_t))) { - return buffer[0]; - } else { - return 0; - } -} - -static inline void subghz_protocol_decoder_nice_flor_s_magic_xor(uint8_t* p, uint8_t k) { - for(uint8_t i = 1; i < 6; i++) { - p[i] ^= k; - } -} - -uint64_t subghz_protocol_nice_flor_s_encrypt(uint64_t data, const char* file_name) { - uint8_t* p = (uint8_t*)&data; - - uint8_t k = 0; - for(uint8_t y = 0; y < 2; y++) { - k = subghz_protocol_nice_flor_s_get_byte_in_file(file_name, p[0] & 0x1f); - subghz_protocol_decoder_nice_flor_s_magic_xor(p, k); - - p[5] &= 0x0f; - p[0] ^= k & 0xe0; - k = subghz_protocol_nice_flor_s_get_byte_in_file(file_name, p[0] >> 3) + 0x25; - subghz_protocol_decoder_nice_flor_s_magic_xor(p, k); - - p[5] &= 0x0f; - p[0] ^= k & 0x7; - if(y == 0) { - k = p[0]; - p[0] = p[1]; - p[1] = k; - } - } - - p[5] = ~p[5] & 0x0f; - k = ~p[4]; - p[4] = ~p[0]; - p[0] = ~p[2]; - p[2] = k; - k = ~p[3]; - p[3] = ~p[1]; - p[1] = k; - - return data; -} - -static uint64_t - subghz_protocol_nice_flor_s_decrypt(SubGhzBlockGeneric* instance, const char* file_name) { - furi_assert(instance); - uint64_t data = instance->data; - uint8_t* p = (uint8_t*)&data; - - uint8_t k = 0; - - k = ~p[4]; - p[5] = ~p[5]; - p[4] = ~p[2]; - p[2] = ~p[0]; - p[0] = k; - k = ~p[3]; - p[3] = ~p[1]; - p[1] = k; - - for(uint8_t y = 0; y < 2; y++) { - k = subghz_protocol_nice_flor_s_get_byte_in_file(file_name, p[0] >> 3) + 0x25; - subghz_protocol_decoder_nice_flor_s_magic_xor(p, k); - - p[5] &= 0x0f; - p[0] ^= k & 0x7; - k = subghz_protocol_nice_flor_s_get_byte_in_file(file_name, p[0] & 0x1f); - subghz_protocol_decoder_nice_flor_s_magic_xor(p, k); - - p[5] &= 0x0f; - p[0] ^= k & 0xe0; - - if(y == 0) { - k = p[0]; - p[0] = p[1]; - p[1] = k; - } - } - - return data; -} - -bool subghz_protocol_nice_flor_s_create_data( - void* context, - FlipperFormat* flipper_format, - uint32_t serial, - uint8_t btn, - uint16_t cnt, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolEncoderNiceFlorS* instance = context; - instance->generic.serial = serial; - instance->generic.cnt = cnt; - instance->generic.data_count_bit = 52; - uint64_t decrypt = ((uint64_t)instance->generic.serial << 16) | instance->generic.cnt; - uint64_t enc_part = subghz_protocol_nice_flor_s_encrypt( - decrypt, instance->nice_flor_s_rainbow_table_file_name); - uint8_t byte = btn << 4 | (0xF ^ btn ^ 0x3); - instance->generic.data = (uint64_t)byte << 44 | enc_part; - - bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); - - return res; -} - -void* subghz_protocol_decoder_nice_flor_s_alloc(SubGhzEnvironment* environment) { - SubGhzProtocolDecoderNiceFlorS* instance = malloc(sizeof(SubGhzProtocolDecoderNiceFlorS)); - instance->base.protocol = &subghz_protocol_nice_flor_s; - instance->generic.protocol_name = instance->base.protocol->name; - instance->nice_flor_s_rainbow_table_file_name = - subghz_environment_get_nice_flor_s_rainbow_table_file_name(environment); - if(instance->nice_flor_s_rainbow_table_file_name) { - FURI_LOG_D( - TAG, "Loading rainbow table from %s", instance->nice_flor_s_rainbow_table_file_name); - } - return instance; -} - -void subghz_protocol_decoder_nice_flor_s_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderNiceFlorS* instance = context; - instance->nice_flor_s_rainbow_table_file_name = NULL; - free(instance); -} - -void subghz_protocol_decoder_nice_flor_s_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderNiceFlorS* instance = context; - instance->decoder.parser_step = NiceFlorSDecoderStepReset; -} - -void subghz_protocol_decoder_nice_flor_s_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderNiceFlorS* instance = context; - - switch(instance->decoder.parser_step) { - case NiceFlorSDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_nice_flor_s_const.te_short * 38) < - subghz_protocol_nice_flor_s_const.te_delta * 38)) { - //Found start header Nice Flor-S - instance->decoder.parser_step = NiceFlorSDecoderStepCheckHeader; - } - break; - case NiceFlorSDecoderStepCheckHeader: - if((level) && (DURATION_DIFF(duration, subghz_protocol_nice_flor_s_const.te_short * 3) < - subghz_protocol_nice_flor_s_const.te_delta * 3)) { - //Found next header Nice Flor-S - instance->decoder.parser_step = NiceFlorSDecoderStepFoundHeader; - } else { - instance->decoder.parser_step = NiceFlorSDecoderStepReset; - } - break; - case NiceFlorSDecoderStepFoundHeader: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_nice_flor_s_const.te_short * 3) < - subghz_protocol_nice_flor_s_const.te_delta * 3)) { - //Found header Nice Flor-S - instance->decoder.parser_step = NiceFlorSDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else { - instance->decoder.parser_step = NiceFlorSDecoderStepReset; - } - break; - case NiceFlorSDecoderStepSaveDuration: - if(level) { - if(DURATION_DIFF(duration, subghz_protocol_nice_flor_s_const.te_short * 3) < - subghz_protocol_nice_flor_s_const.te_delta) { - //Found STOP bit - instance->decoder.parser_step = NiceFlorSDecoderStepReset; - if((instance->decoder.decode_count_bit == - subghz_protocol_nice_flor_s_const.min_count_bit_for_found) || - (instance->decoder.decode_count_bit == NICE_ONE_COUNT_BIT)) { - instance->generic.data = instance->data; - instance->data = instance->decoder.decode_data; - instance->decoder.decode_data = instance->generic.data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - break; - } else { - //save interval - instance->decoder.te_last = duration; - instance->decoder.parser_step = NiceFlorSDecoderStepCheckDuration; - } - } - break; - case NiceFlorSDecoderStepCheckDuration: - if(!level) { - if((DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_nice_flor_s_const.te_short) < - subghz_protocol_nice_flor_s_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_nice_flor_s_const.te_long) < - subghz_protocol_nice_flor_s_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = NiceFlorSDecoderStepSaveDuration; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_nice_flor_s_const.te_long) < - subghz_protocol_nice_flor_s_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_nice_flor_s_const.te_short) < - subghz_protocol_nice_flor_s_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = NiceFlorSDecoderStepSaveDuration; - } else - instance->decoder.parser_step = NiceFlorSDecoderStepReset; - } else { - instance->decoder.parser_step = NiceFlorSDecoderStepReset; - } - if(instance->decoder.decode_count_bit == - subghz_protocol_nice_flor_s_const.min_count_bit_for_found) { - instance->data = instance->decoder.decode_data; - instance->decoder.decode_data = 0; - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - * @param file_name Full path to rainbow table the file - */ -static void subghz_protocol_nice_flor_s_remote_controller( - SubGhzBlockGeneric* instance, - const char* file_name) { - /* - * Protocol Nice Flor-S - * Packet format Nice Flor-s: START-P0-P1-P2-P3-P4-P5-P6-P7-STOP - * P0 (4-bit) - button positional code - 1:0x1, 2:0x2, 3:0x4, 4:0x8; - * P1 (4-bit) - batch repetition number, calculated by the formula: - * P1 = 0xF ^ P0 ^ n; where n changes from 1 to 15, then 0, and then in a circle - * key 1: {0xE,0xF,0xC,0xD,0xA,0xB,0x8,0x9,0x6,0x7,0x4,0x5,0x2,0x3,0x0,0x1}; - * key 2: {0xD,0xC,0xF,0xE,0x9,0x8,0xB,0xA,0x5,0x4,0x7,0x6,0x1,0x0,0x3,0x2}; - * key 3: {0xB,0xA,0x9,0x8,0xF,0xE,0xD,0xC,0x3,0x2,0x1,0x0,0x7,0x6,0x5,0x4}; - * key 4: {0x7,0x6,0x5,0x4,0x3,0x2,0x1,0x0,0xF,0xE,0xD,0xC,0xB,0xA,0x9,0x8}; - * P2 (4-bit) - part of the serial number, P2 = (K ^ S3) & 0xF; - * P3 (byte) - the major part of the encrypted index - * P4 (byte) - the low-order part of the encrypted index - * P5 (byte) - part of the serial number, P5 = K ^ S2; - * P6 (byte) - part of the serial number, P6 = K ^ S1; - * P7 (byte) - part of the serial number, P7 = K ^ S0; - * K (byte) - depends on P3 and P4, K = Fk(P3, P4); - * S3,S2,S1,S0 - serial number of the console 28 bit. - * - * data => 0x1c5783607f7b3 key serial cnt - * decrypt => 0x10436c6820444 => 0x1 0436c682 0444 - * - * Protocol Nice One - * Generally repeats the Nice Flor-S protocol, but there are a few changes - * Packet format first 52 bytes repeat Nice Flor-S protocol - * The additional 20 bytes contain the code of the pressed button, - * the button hold bit and the CRC of the entire message. - * START-P0-P1-P2-P3-P4-P5-P6-P7-P8-P9-P10-STOP - * P7 (byte) - if (n<4) k=0x8f : k=0x80; P7= k^n; - * P8 (byte) - if (hold bit) b=0x00 : b=0x10; P8= b^(k<<4) | 4 hi bit crc - * P10 (4-bit) - 4 lo bit crc - * key+b crc - * data => 0x1724A7D9A522F 899 D6 hold bit = 0 - just pressed the button - * data => 0x1424A7D9A522F 8AB 03 hold bit = 1 - button hold - * - * A small button hold counter (0..15) is stored between each press, - * i.e. if 1 press of the button stops counter 6, then the next press - * of the button will start from the value 7 (hold bit = 0), 8 (hold bit = 1)... - * further up to 15 with overflow - * - */ - if(!file_name) { - instance->cnt = 0; - instance->serial = 0; - instance->btn = 0; - } else { - uint64_t decrypt = subghz_protocol_nice_flor_s_decrypt(instance, file_name); - instance->cnt = decrypt & 0xFFFF; - instance->serial = (decrypt >> 16) & 0xFFFFFFF; - instance->btn = (decrypt >> 48) & 0xF; - } -} - -uint8_t subghz_protocol_decoder_nice_flor_s_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderNiceFlorS* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_nice_flor_s_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderNiceFlorS* instance = context; - bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); - if(instance->generic.data_count_bit == NICE_ONE_COUNT_BIT) { - if(res && - !flipper_format_write_uint32(flipper_format, "Data", (uint32_t*)&instance->data, 1)) { - FURI_LOG_E(TAG, "Unable to add Data"); - res = false; - } - } - return res; -} - -bool subghz_protocol_decoder_nice_flor_s_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderNiceFlorS* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if((instance->generic.data_count_bit != - subghz_protocol_nice_flor_s_const.min_count_bit_for_found) && - (instance->generic.data_count_bit != NICE_ONE_COUNT_BIT)) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - if(instance->generic.data_count_bit == NICE_ONE_COUNT_BIT) { - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - uint32_t temp = 0; - if(!flipper_format_read_uint32(flipper_format, "Data", (uint32_t*)&temp, 1)) { - FURI_LOG_E(TAG, "Missing Data"); - break; - } - instance->data = (uint64_t)temp; - } - - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_nice_flor_s_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderNiceFlorS* instance = context; - - subghz_protocol_nice_flor_s_remote_controller( - &instance->generic, instance->nice_flor_s_rainbow_table_file_name); - - if(instance->generic.data_count_bit == NICE_ONE_COUNT_BIT) { - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:0x%013llX%llX\r\n" - "Sn:%05lX\r\n" - "Cnt:%04lX Btn:%02X\r\n", - NICE_ONE_NAME, - instance->generic.data_count_bit, - instance->generic.data, - instance->data, - instance->generic.serial, - instance->generic.cnt, - instance->generic.btn); - } else { - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:0x%013llX\r\n" - "Sn:%05lX\r\n" - "Cnt:%04lX Btn:%02X\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - instance->generic.data, - instance->generic.serial, - instance->generic.cnt, - instance->generic.btn); - } -} diff --git a/applications/main/subghz/protocols/nice_flor_s.h b/applications/main/subghz/protocols/nice_flor_s.h deleted file mode 100644 index e333fc979..000000000 --- a/applications/main/subghz/protocols/nice_flor_s.h +++ /dev/null @@ -1,127 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_NICE_FLOR_S_NAME "Nice FloR-S" - -typedef struct SubGhzProtocolDecoderNiceFlorS SubGhzProtocolDecoderNiceFlorS; -typedef struct SubGhzProtocolEncoderNiceFlorS SubGhzProtocolEncoderNiceFlorS; - -extern const SubGhzProtocolDecoder subghz_protocol_nice_flor_s_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_nice_flor_s_encoder; -extern const SubGhzProtocol subghz_protocol_nice_flor_s; - -/** - * Allocate SubGhzProtocolEncoderNiceFlorS. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderNiceFlorS* pointer to a SubGhzProtocolEncoderNiceFlorS instance - */ -void* subghz_protocol_encoder_nice_flor_s_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderNiceFlorS. - * @param context Pointer to a SubGhzProtocolEncoderNiceFlorS instance - */ -void subghz_protocol_encoder_nice_flor_s_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderNiceFlorS instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_nice_flor_s_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderNiceFlorS instance - */ -void subghz_protocol_encoder_nice_flor_s_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderNiceFlorS instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_nice_flor_s_yield(void* context); - -uint64_t subghz_protocol_nice_flor_s_encrypt(uint64_t data, const char* file_name); - -/** - * New remote generation. - * @param context Pointer to a SubGhzProtocolEncoderNiceFlorS instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param serial Serial number - * @param btn Button number, 4 bit - * @param cnt Counter value, 16 bit - * @param preset Modulation, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_nice_flor_s_create_data( - void* context, - FlipperFormat* flipper_format, - uint32_t serial, - uint8_t btn, - uint16_t cnt, - SubGhzRadioPreset* preset); - -/** - * Allocate SubGhzProtocolDecoderNiceFlorS. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderNiceFlorS* pointer to a SubGhzProtocolDecoderNiceFlorS instance - */ -void* subghz_protocol_decoder_nice_flor_s_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderNiceFlorS. - * @param context Pointer to a SubGhzProtocolDecoderNiceFlorS instance - */ -void subghz_protocol_decoder_nice_flor_s_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderNiceFlorS. - * @param context Pointer to a SubGhzProtocolDecoderNiceFlorS instance - */ -void subghz_protocol_decoder_nice_flor_s_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderNiceFlorS instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_nice_flor_s_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderNiceFlorS instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_nice_flor_s_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderNiceFlorS. - * @param context Pointer to a SubGhzProtocolDecoderNiceFlorS instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_nice_flor_s_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderNiceFlorS. - * @param context Pointer to a SubGhzProtocolDecoderNiceFlorS instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_nice_flor_s_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderNiceFlorS instance - * @param output Resulting text - */ -void subghz_protocol_decoder_nice_flor_s_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/phoenix_v2.c b/applications/main/subghz/protocols/phoenix_v2.c deleted file mode 100644 index b3d6f1e98..000000000 --- a/applications/main/subghz/protocols/phoenix_v2.c +++ /dev/null @@ -1,339 +0,0 @@ -#include "phoenix_v2.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolPhoenix_V2" - -//transmission only static mode - -static const SubGhzBlockConst subghz_protocol_phoenix_v2_const = { - .te_short = 427, - .te_long = 853, - .te_delta = 100, - .min_count_bit_for_found = 52, -}; - -struct SubGhzProtocolDecoderPhoenix_V2 { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; -}; - -struct SubGhzProtocolEncoderPhoenix_V2 { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - Phoenix_V2DecoderStepReset = 0, - Phoenix_V2DecoderStepFoundStartBit, - Phoenix_V2DecoderStepSaveDuration, - Phoenix_V2DecoderStepCheckDuration, -} Phoenix_V2DecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_phoenix_v2_decoder = { - .alloc = subghz_protocol_decoder_phoenix_v2_alloc, - .free = subghz_protocol_decoder_phoenix_v2_free, - - .feed = subghz_protocol_decoder_phoenix_v2_feed, - .reset = subghz_protocol_decoder_phoenix_v2_reset, - - .get_hash_data = subghz_protocol_decoder_phoenix_v2_get_hash_data, - .serialize = subghz_protocol_decoder_phoenix_v2_serialize, - .deserialize = subghz_protocol_decoder_phoenix_v2_deserialize, - .get_string = subghz_protocol_decoder_phoenix_v2_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_phoenix_v2_encoder = { - .alloc = subghz_protocol_encoder_phoenix_v2_alloc, - .free = subghz_protocol_encoder_phoenix_v2_free, - - .deserialize = subghz_protocol_encoder_phoenix_v2_deserialize, - .stop = subghz_protocol_encoder_phoenix_v2_stop, - .yield = subghz_protocol_encoder_phoenix_v2_yield, -}; - -const SubGhzProtocol subghz_protocol_phoenix_v2 = { - .name = SUBGHZ_PROTOCOL_PHOENIX_V2_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_phoenix_v2_decoder, - .encoder = &subghz_protocol_phoenix_v2_encoder, -}; - -void* subghz_protocol_encoder_phoenix_v2_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderPhoenix_V2* instance = malloc(sizeof(SubGhzProtocolEncoderPhoenix_V2)); - - instance->base.protocol = &subghz_protocol_phoenix_v2; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 128; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_phoenix_v2_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderPhoenix_V2* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderPhoenix_V2 instance - * @return true On success - */ -static bool - subghz_protocol_encoder_phoenix_v2_get_upload(SubGhzProtocolEncoderPhoenix_V2* instance) { - furi_assert(instance); - size_t index = 0; - size_t size_upload = (instance->generic.data_count_bit * 2) + 2; - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - //Send header - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_phoenix_v2_const.te_short * 60); - //Send start bit - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_phoenix_v2_const.te_short * 6); - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(!bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_phoenix_v2_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_phoenix_v2_const.te_short); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_phoenix_v2_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_phoenix_v2_const.te_long); - } - } - return true; -} - -bool subghz_protocol_encoder_phoenix_v2_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderPhoenix_V2* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_phoenix_v2_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_phoenix_v2_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_phoenix_v2_stop(void* context) { - SubGhzProtocolEncoderPhoenix_V2* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_phoenix_v2_yield(void* context) { - SubGhzProtocolEncoderPhoenix_V2* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_phoenix_v2_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderPhoenix_V2* instance = malloc(sizeof(SubGhzProtocolDecoderPhoenix_V2)); - instance->base.protocol = &subghz_protocol_phoenix_v2; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_phoenix_v2_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderPhoenix_V2* instance = context; - free(instance); -} - -void subghz_protocol_decoder_phoenix_v2_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderPhoenix_V2* instance = context; - instance->decoder.parser_step = Phoenix_V2DecoderStepReset; -} - -void subghz_protocol_decoder_phoenix_v2_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderPhoenix_V2* instance = context; - - switch(instance->decoder.parser_step) { - case Phoenix_V2DecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_phoenix_v2_const.te_short * 60) < - subghz_protocol_phoenix_v2_const.te_delta * 30)) { - //Found Preambula - instance->decoder.parser_step = Phoenix_V2DecoderStepFoundStartBit; - } - break; - case Phoenix_V2DecoderStepFoundStartBit: - if(level && ((DURATION_DIFF(duration, (subghz_protocol_phoenix_v2_const.te_short * 6)) < - subghz_protocol_phoenix_v2_const.te_delta * 4))) { - //Found start bit - instance->decoder.parser_step = Phoenix_V2DecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else { - instance->decoder.parser_step = Phoenix_V2DecoderStepReset; - } - break; - case Phoenix_V2DecoderStepSaveDuration: - if(!level) { - if(duration >= ((uint32_t)subghz_protocol_phoenix_v2_const.te_short * 10 + - subghz_protocol_phoenix_v2_const.te_delta)) { - instance->decoder.parser_step = Phoenix_V2DecoderStepFoundStartBit; - if(instance->decoder.decode_count_bit == - subghz_protocol_phoenix_v2_const.min_count_bit_for_found) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - break; - } else { - instance->decoder.te_last = duration; - instance->decoder.parser_step = Phoenix_V2DecoderStepCheckDuration; - } - } - break; - case Phoenix_V2DecoderStepCheckDuration: - if(level) { - if((DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_phoenix_v2_const.te_short) < - subghz_protocol_phoenix_v2_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_phoenix_v2_const.te_long) < - subghz_protocol_phoenix_v2_const.te_delta * 3)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = Phoenix_V2DecoderStepSaveDuration; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_phoenix_v2_const.te_long) < - subghz_protocol_phoenix_v2_const.te_delta * 3) && - (DURATION_DIFF(duration, subghz_protocol_phoenix_v2_const.te_short) < - subghz_protocol_phoenix_v2_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = Phoenix_V2DecoderStepSaveDuration; - } else { - instance->decoder.parser_step = Phoenix_V2DecoderStepReset; - } - } else { - instance->decoder.parser_step = Phoenix_V2DecoderStepReset; - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - */ -static void subghz_protocol_phoenix_v2_check_remote_controller(SubGhzBlockGeneric* instance) { - uint64_t data_rev = - subghz_protocol_blocks_reverse_key(instance->data, instance->data_count_bit + 4); - instance->serial = data_rev & 0xFFFFFFFF; - instance->cnt = (data_rev >> 40) & 0xFFFF; - instance->btn = (data_rev >> 32) & 0xF; -} - -uint8_t subghz_protocol_decoder_phoenix_v2_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderPhoenix_V2* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_phoenix_v2_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderPhoenix_V2* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_phoenix_v2_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderPhoenix_V2* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_phoenix_v2_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_phoenix_v2_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderPhoenix_V2* instance = context; - subghz_protocol_phoenix_v2_check_remote_controller(&instance->generic); - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:%02lX%08lX\r\n" - "Sn:0x%07lX \r\n" - "Btn:%X\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32) & 0xFFFFFFFF, - (uint32_t)(instance->generic.data & 0xFFFFFFFF), - instance->generic.serial, - instance->generic.btn); -} diff --git a/applications/main/subghz/protocols/phoenix_v2.h b/applications/main/subghz/protocols/phoenix_v2.h deleted file mode 100644 index 48487535e..000000000 --- a/applications/main/subghz/protocols/phoenix_v2.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_PHOENIX_V2_NAME "Phoenix_V2" - -typedef struct SubGhzProtocolDecoderPhoenix_V2 SubGhzProtocolDecoderPhoenix_V2; -typedef struct SubGhzProtocolEncoderPhoenix_V2 SubGhzProtocolEncoderPhoenix_V2; - -extern const SubGhzProtocolDecoder subghz_protocol_phoenix_v2_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_phoenix_v2_encoder; -extern const SubGhzProtocol subghz_protocol_phoenix_v2; - -/** - * Allocate SubGhzProtocolEncoderPhoenix_V2. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderPhoenix_V2* pointer to a SubGhzProtocolEncoderPhoenix_V2 instance - */ -void* subghz_protocol_encoder_phoenix_v2_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderPhoenix_V2. - * @param context Pointer to a SubGhzProtocolEncoderPhoenix_V2 instance - */ -void subghz_protocol_encoder_phoenix_v2_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderPhoenix_V2 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_phoenix_v2_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderPhoenix_V2 instance - */ -void subghz_protocol_encoder_phoenix_v2_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderPhoenix_V2 instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_phoenix_v2_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderPhoenix_V2. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderPhoenix_V2* pointer to a SubGhzProtocolDecoderPhoenix_V2 instance - */ -void* subghz_protocol_decoder_phoenix_v2_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderPhoenix_V2. - * @param context Pointer to a SubGhzProtocolDecoderPhoenix_V2 instance - */ -void subghz_protocol_decoder_phoenix_v2_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderPhoenix_V2. - * @param context Pointer to a SubGhzProtocolDecoderPhoenix_V2 instance - */ -void subghz_protocol_decoder_phoenix_v2_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderPhoenix_V2 instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_phoenix_v2_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderPhoenix_V2 instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_phoenix_v2_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderPhoenix_V2. - * @param context Pointer to a SubGhzProtocolDecoderPhoenix_V2 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_phoenix_v2_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderPhoenix_V2. - * @param context Pointer to a SubGhzProtocolDecoderPhoenix_V2 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_phoenix_v2_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderPhoenix_V2 instance - * @param output Resulting text - */ -void subghz_protocol_decoder_phoenix_v2_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/power_smart.c b/applications/main/subghz/protocols/power_smart.c deleted file mode 100644 index 1e8d10e95..000000000 --- a/applications/main/subghz/protocols/power_smart.c +++ /dev/null @@ -1,394 +0,0 @@ -#include "power_smart.h" -#include -#include -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolPowerSmart" -#define POWER_SMART_PACKET_HEADER 0xFD000000AA000000 -#define POWER_SMART_PACKET_HEADER_MASK 0xFF000000FF000000 - -#define CHANNEL_PATTERN "%c%c%c%c%c%c" -#define CNT_TO_CHANNEL(dip) \ - (dip & 0x0001 ? '*' : '-'), (dip & 0x0002 ? '*' : '-'), (dip & 0x0004 ? '*' : '-'), \ - (dip & 0x0008 ? '*' : '-'), (dip & 0x0010 ? '*' : '-'), (dip & 0x0020 ? '*' : '-') - -static const SubGhzBlockConst subghz_protocol_power_smart_const = { - .te_short = 225, - .te_long = 450, - .te_delta = 100, - .min_count_bit_for_found = 64, -}; - -struct SubGhzProtocolDecoderPowerSmart { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - ManchesterState manchester_saved_state; - uint16_t header_count; -}; - -struct SubGhzProtocolEncoderPowerSmart { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - PowerSmartDecoderStepReset = 0, - PowerSmartDecoderFoundHeader, - PowerSmartDecoderStepDecoderData, -} PowerSmartDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_power_smart_decoder = { - .alloc = subghz_protocol_decoder_power_smart_alloc, - .free = subghz_protocol_decoder_power_smart_free, - - .feed = subghz_protocol_decoder_power_smart_feed, - .reset = subghz_protocol_decoder_power_smart_reset, - - .get_hash_data = subghz_protocol_decoder_power_smart_get_hash_data, - .serialize = subghz_protocol_decoder_power_smart_serialize, - .deserialize = subghz_protocol_decoder_power_smart_deserialize, - .get_string = subghz_protocol_decoder_power_smart_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_power_smart_encoder = { - .alloc = subghz_protocol_encoder_power_smart_alloc, - .free = subghz_protocol_encoder_power_smart_free, - - .deserialize = subghz_protocol_encoder_power_smart_deserialize, - .stop = subghz_protocol_encoder_power_smart_stop, - .yield = subghz_protocol_encoder_power_smart_yield, -}; - -const SubGhzProtocol subghz_protocol_power_smart = { - .name = SUBGHZ_PROTOCOL_POWER_SMART_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_power_smart_decoder, - .encoder = &subghz_protocol_power_smart_encoder, -}; - -void* subghz_protocol_encoder_power_smart_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderPowerSmart* instance = malloc(sizeof(SubGhzProtocolEncoderPowerSmart)); - - instance->base.protocol = &subghz_protocol_power_smart; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 1024; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_power_smart_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderPowerSmart* instance = context; - free(instance->encoder.upload); - free(instance); -} - -static LevelDuration - subghz_protocol_encoder_power_smart_add_duration_to_upload(ManchesterEncoderResult result) { - LevelDuration data = {.duration = 0, .level = 0}; - switch(result) { - case ManchesterEncoderResultShortLow: - data.duration = subghz_protocol_power_smart_const.te_short; - data.level = false; - break; - case ManchesterEncoderResultLongLow: - data.duration = subghz_protocol_power_smart_const.te_long; - data.level = false; - break; - case ManchesterEncoderResultLongHigh: - data.duration = subghz_protocol_power_smart_const.te_long; - data.level = true; - break; - case ManchesterEncoderResultShortHigh: - data.duration = subghz_protocol_power_smart_const.te_short; - data.level = true; - break; - - default: - furi_crash("SubGhz: ManchesterEncoderResult is incorrect."); - break; - } - return level_duration_make(data.level, data.duration); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderPowerSmart instance - */ -static void - subghz_protocol_encoder_power_smart_get_upload(SubGhzProtocolEncoderPowerSmart* instance) { - furi_assert(instance); - size_t index = 0; - - ManchesterEncoderState enc_state; - manchester_encoder_reset(&enc_state); - ManchesterEncoderResult result; - - for(int i = 8; i > 0; i--) { - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(!manchester_encoder_advance( - &enc_state, !bit_read(instance->generic.data, i - 1), &result)) { - instance->encoder.upload[index++] = - subghz_protocol_encoder_power_smart_add_duration_to_upload(result); - manchester_encoder_advance( - &enc_state, !bit_read(instance->generic.data, i - 1), &result); - } - instance->encoder.upload[index++] = - subghz_protocol_encoder_power_smart_add_duration_to_upload(result); - } - } - instance->encoder.upload[index] = subghz_protocol_encoder_power_smart_add_duration_to_upload( - manchester_encoder_finish(&enc_state)); - if(level_duration_get_level(instance->encoder.upload[index])) { - index++; - } - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_power_smart_const.te_long * 1111); - instance->encoder.size_upload = index; -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - */ -static void subghz_protocol_power_smart_remote_controller(SubGhzBlockGeneric* instance) { - /* - * Protocol: Manchester encoding, symbol rate ~2222. - * Packet Format: - * 0xFDXXXXYYAAZZZZWW where 0xFD and 0xAA sync word - * XXXX = ~ZZZZ, YY=(~WW)-1 - * Example: - * SYNC1 K1 CHANNEL DATA1 K2 DATA2 SYNC2 ~K1 ~CHANNEL ~DATA2 ~K2 (~DATA2)-1 - * 0xFD2137ACAADEC852 => 11111101 0 010000 10011011 1 10101100 10101010 1 1011110 1100100 0 01010010 - * 0xFDA137ACAA5EC852 => 11111101 1 010000 10011011 1 10101100 10101010 0 1011110 1100100 0 01010010 - * 0xFDA136ACAA5EC952 => 11111101 1 010000 10011011 0 10101100 10101010 0 1011110 1100100 1 01010010 - * - * Key: - * K1K2 - * 0 0 - key_unknown - * 0 1 - key_down - * 1 0 - key_up - * 1 1 - key_stop - * - */ - - instance->btn = ((instance->data >> 54) & 0x02) | ((instance->data >> 40) & 0x1); - instance->serial = ((instance->data >> 33) & 0x3FFF00) | ((instance->data >> 32) & 0xFF); - instance->cnt = ((instance->data >> 49) & 0x3F); -} - -bool subghz_protocol_encoder_power_smart_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderPowerSmart* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_power_smart_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - subghz_protocol_power_smart_remote_controller(&instance->generic); - subghz_protocol_encoder_power_smart_get_upload(instance); - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_power_smart_stop(void* context) { - SubGhzProtocolEncoderPowerSmart* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_power_smart_yield(void* context) { - SubGhzProtocolEncoderPowerSmart* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_power_smart_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderPowerSmart* instance = malloc(sizeof(SubGhzProtocolDecoderPowerSmart)); - instance->base.protocol = &subghz_protocol_power_smart; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_power_smart_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderPowerSmart* instance = context; - free(instance); -} - -void subghz_protocol_decoder_power_smart_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderPowerSmart* instance = context; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventReset, - &instance->manchester_saved_state, - NULL); -} - -bool subghz_protocol_power_smart_chek_valid(uint64_t packet) { - uint32_t data_1 = (uint32_t)((packet >> 40) & 0xFFFF); - uint32_t data_2 = (uint32_t)((~packet >> 8) & 0xFFFF); - uint8_t data_3 = (uint8_t)(packet >> 32) & 0xFF; - uint8_t data_4 = (uint8_t)(((~packet) & 0xFF) - 1); - return (data_1 == data_2) && (data_3 == data_4); -} - -void subghz_protocol_decoder_power_smart_feed( - void* context, - bool level, - volatile uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderPowerSmart* instance = context; - ManchesterEvent event = ManchesterEventReset; - if(!level) { - if(DURATION_DIFF(duration, subghz_protocol_power_smart_const.te_short) < - subghz_protocol_power_smart_const.te_delta) { - event = ManchesterEventShortLow; - } else if( - DURATION_DIFF(duration, subghz_protocol_power_smart_const.te_long) < - subghz_protocol_power_smart_const.te_delta * 2) { - event = ManchesterEventLongLow; - } - } else { - if(DURATION_DIFF(duration, subghz_protocol_power_smart_const.te_short) < - subghz_protocol_power_smart_const.te_delta) { - event = ManchesterEventShortHigh; - } else if( - DURATION_DIFF(duration, subghz_protocol_power_smart_const.te_long) < - subghz_protocol_power_smart_const.te_delta * 2) { - event = ManchesterEventLongHigh; - } - } - if(event != ManchesterEventReset) { - bool data; - bool data_ok = manchester_advance( - instance->manchester_saved_state, event, &instance->manchester_saved_state, &data); - - if(data_ok) { - instance->decoder.decode_data = (instance->decoder.decode_data << 1) | !data; - } - if((instance->decoder.decode_data & POWER_SMART_PACKET_HEADER_MASK) == - POWER_SMART_PACKET_HEADER) { - if(subghz_protocol_power_smart_chek_valid(instance->decoder.decode_data)) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = - subghz_protocol_power_smart_const.min_count_bit_for_found; - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } - } - } else { - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventReset, - &instance->manchester_saved_state, - NULL); - } -} - -static const char* subghz_protocol_power_smart_get_name_button(uint8_t btn) { - btn &= 0x3; - const char* name_btn[0x4] = {"Unknown", "Down", "Up", "Stop"}; - return name_btn[btn]; -} - -uint8_t subghz_protocol_decoder_power_smart_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderPowerSmart* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_power_smart_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderPowerSmart* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_power_smart_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderPowerSmart* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_power_smart_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_power_smart_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderPowerSmart* instance = context; - subghz_protocol_power_smart_remote_controller(&instance->generic); - - furi_string_cat_printf( - output, - "%s %db\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%07lX \r\n" - "Btn:%s\r\n" - "Channel:" CHANNEL_PATTERN "\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)(instance->generic.data & 0xFFFFFFFF), - instance->generic.serial, - subghz_protocol_power_smart_get_name_button(instance->generic.btn), - CNT_TO_CHANNEL(instance->generic.cnt)); -} diff --git a/applications/main/subghz/protocols/power_smart.h b/applications/main/subghz/protocols/power_smart.h deleted file mode 100644 index 806729f8e..000000000 --- a/applications/main/subghz/protocols/power_smart.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_POWER_SMART_NAME "Power Smart" - -typedef struct SubGhzProtocolDecoderPowerSmart SubGhzProtocolDecoderPowerSmart; -typedef struct SubGhzProtocolEncoderPowerSmart SubGhzProtocolEncoderPowerSmart; - -extern const SubGhzProtocolDecoder subghz_protocol_power_smart_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_power_smart_encoder; -extern const SubGhzProtocol subghz_protocol_power_smart; - -/** - * Allocate SubGhzProtocolEncoderPowerSmart. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderPowerSmart* pointer to a SubGhzProtocolEncoderPowerSmart instance - */ -void* subghz_protocol_encoder_power_smart_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderPowerSmart. - * @param context Pointer to a SubGhzProtocolEncoderPowerSmart instance - */ -void subghz_protocol_encoder_power_smart_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderPowerSmart instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_power_smart_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderPowerSmart instance - */ -void subghz_protocol_encoder_power_smart_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderPowerSmart instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_power_smart_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderPowerSmart. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderPowerSmart* pointer to a SubGhzProtocolDecoderPowerSmart instance - */ -void* subghz_protocol_decoder_power_smart_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderPowerSmart. - * @param context Pointer to a SubGhzProtocolDecoderPowerSmart instance - */ -void subghz_protocol_decoder_power_smart_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderPowerSmart. - * @param context Pointer to a SubGhzProtocolDecoderPowerSmart instance - */ -void subghz_protocol_decoder_power_smart_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderPowerSmart instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_power_smart_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderPowerSmart instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_power_smart_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderPowerSmart. - * @param context Pointer to a SubGhzProtocolDecoderPowerSmart instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_power_smart_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderPowerSmart. - * @param context Pointer to a SubGhzProtocolDecoderPowerSmart instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_power_smart_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderPowerSmart instance - * @param output Resulting text - */ -void subghz_protocol_decoder_power_smart_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/princeton.c b/applications/main/subghz/protocols/princeton.c deleted file mode 100644 index 7fc8f6524..000000000 --- a/applications/main/subghz/protocols/princeton.c +++ /dev/null @@ -1,374 +0,0 @@ -#include "princeton.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -/* - * Help - * https://phreakerclub.com/447 - * - */ - -#define TAG "SubGhzProtocolPrinceton" - -static const SubGhzBlockConst subghz_protocol_princeton_const = { - .te_short = 390, - .te_long = 1170, - .te_delta = 300, - .min_count_bit_for_found = 24, -}; - -struct SubGhzProtocolDecoderPrinceton { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - - uint32_t te; - uint32_t last_data; -}; - -struct SubGhzProtocolEncoderPrinceton { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; - - uint32_t te; -}; - -typedef enum { - PrincetonDecoderStepReset = 0, - PrincetonDecoderStepSaveDuration, - PrincetonDecoderStepCheckDuration, -} PrincetonDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_princeton_decoder = { - .alloc = subghz_protocol_decoder_princeton_alloc, - .free = subghz_protocol_decoder_princeton_free, - - .feed = subghz_protocol_decoder_princeton_feed, - .reset = subghz_protocol_decoder_princeton_reset, - - .get_hash_data = subghz_protocol_decoder_princeton_get_hash_data, - .serialize = subghz_protocol_decoder_princeton_serialize, - .deserialize = subghz_protocol_decoder_princeton_deserialize, - .get_string = subghz_protocol_decoder_princeton_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_princeton_encoder = { - .alloc = subghz_protocol_encoder_princeton_alloc, - .free = subghz_protocol_encoder_princeton_free, - - .deserialize = subghz_protocol_encoder_princeton_deserialize, - .stop = subghz_protocol_encoder_princeton_stop, - .yield = subghz_protocol_encoder_princeton_yield, -}; - -const SubGhzProtocol subghz_protocol_princeton = { - .name = SUBGHZ_PROTOCOL_PRINCETON_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_868 | SubGhzProtocolFlag_315 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | - SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_princeton_decoder, - .encoder = &subghz_protocol_princeton_encoder, -}; - -void* subghz_protocol_encoder_princeton_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderPrinceton* instance = malloc(sizeof(SubGhzProtocolEncoderPrinceton)); - - instance->base.protocol = &subghz_protocol_princeton; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 52; //max 24bit*2 + 2 (start, stop) - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_princeton_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderPrinceton* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderPrinceton instance - * @return true On success - */ -static bool - subghz_protocol_encoder_princeton_get_upload(SubGhzProtocolEncoderPrinceton* instance) { - furi_assert(instance); - - size_t index = 0; - size_t size_upload = (instance->generic.data_count_bit * 2) + 2; - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)instance->te * 3); - instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)instance->te); - } else { - //send bit 0 - instance->encoder.upload[index++] = level_duration_make(true, (uint32_t)instance->te); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)instance->te * 3); - } - } - - //Send Stop bit - instance->encoder.upload[index++] = level_duration_make(true, (uint32_t)instance->te); - //Send PT_GUARD - instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)instance->te * 30); - - return true; -} - -bool subghz_protocol_encoder_princeton_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderPrinceton* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) { - FURI_LOG_E(TAG, "Missing TE"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_princeton_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_princeton_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_princeton_stop(void* context) { - SubGhzProtocolEncoderPrinceton* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_princeton_yield(void* context) { - SubGhzProtocolEncoderPrinceton* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_princeton_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderPrinceton* instance = malloc(sizeof(SubGhzProtocolDecoderPrinceton)); - instance->base.protocol = &subghz_protocol_princeton; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_princeton_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderPrinceton* instance = context; - free(instance); -} - -void subghz_protocol_decoder_princeton_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderPrinceton* instance = context; - instance->decoder.parser_step = PrincetonDecoderStepReset; - instance->last_data = 0; -} - -void subghz_protocol_decoder_princeton_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderPrinceton* instance = context; - - switch(instance->decoder.parser_step) { - case PrincetonDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_princeton_const.te_short * 36) < - subghz_protocol_princeton_const.te_delta * 36)) { - //Found Preambula - instance->decoder.parser_step = PrincetonDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->te = 0; - } - break; - case PrincetonDecoderStepSaveDuration: - //save duration - if(level) { - instance->decoder.te_last = duration; - instance->te += duration; - instance->decoder.parser_step = PrincetonDecoderStepCheckDuration; - } - break; - case PrincetonDecoderStepCheckDuration: - if(!level) { - if(duration >= ((uint32_t)subghz_protocol_princeton_const.te_long * 2)) { - instance->decoder.parser_step = PrincetonDecoderStepSaveDuration; - if(instance->decoder.decode_count_bit == - subghz_protocol_princeton_const.min_count_bit_for_found) { - if((instance->last_data == instance->decoder.decode_data) && - instance->last_data) { - instance->te /= (instance->decoder.decode_count_bit * 4 + 1); - - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->last_data = instance->decoder.decode_data; - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->te = 0; - break; - } - - instance->te += duration; - - if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_princeton_const.te_short) < - subghz_protocol_princeton_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_princeton_const.te_long) < - subghz_protocol_princeton_const.te_delta * 3)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = PrincetonDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_princeton_const.te_long) < - subghz_protocol_princeton_const.te_delta * 3) && - (DURATION_DIFF(duration, subghz_protocol_princeton_const.te_short) < - subghz_protocol_princeton_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = PrincetonDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = PrincetonDecoderStepReset; - } - } else { - instance->decoder.parser_step = PrincetonDecoderStepReset; - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - */ -static void subghz_protocol_princeton_check_remote_controller(SubGhzBlockGeneric* instance) { - instance->serial = instance->data >> 4; - instance->btn = instance->data & 0xF; -} - -uint8_t subghz_protocol_decoder_princeton_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderPrinceton* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_princeton_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderPrinceton* instance = context; - bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); - if(res && !flipper_format_write_uint32(flipper_format, "TE", &instance->te, 1)) { - FURI_LOG_E(TAG, "Unable to add TE"); - res = false; - } - return res; -} - -bool subghz_protocol_decoder_princeton_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderPrinceton* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_princeton_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) { - FURI_LOG_E(TAG, "Missing TE"); - break; - } - res = true; - } while(false); - - return res; -} - -void subghz_protocol_decoder_princeton_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderPrinceton* instance = context; - subghz_protocol_princeton_check_remote_controller(&instance->generic); - uint32_t data_rev = subghz_protocol_blocks_reverse_key( - instance->generic.data, instance->generic.data_count_bit); - - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:0x%08lX\r\n" - "Yek:0x%08lX\r\n" - "Sn:0x%05lX Btn:%01X\r\n" - "Te:%luus\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data & 0xFFFFFF), - data_rev, - instance->generic.serial, - instance->generic.btn, - instance->te); -} diff --git a/applications/main/subghz/protocols/princeton.h b/applications/main/subghz/protocols/princeton.h deleted file mode 100644 index a2a11292e..000000000 --- a/applications/main/subghz/protocols/princeton.h +++ /dev/null @@ -1,115 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_PRINCETON_NAME "Princeton" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct SubGhzProtocolDecoderPrinceton SubGhzProtocolDecoderPrinceton; -typedef struct SubGhzProtocolEncoderPrinceton SubGhzProtocolEncoderPrinceton; - -extern const SubGhzProtocolDecoder subghz_protocol_princeton_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_princeton_encoder; -extern const SubGhzProtocol subghz_protocol_princeton; - -/** - * Allocate SubGhzProtocolEncoderPrinceton. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderPrinceton* pointer to a SubGhzProtocolEncoderPrinceton instance - */ -void* subghz_protocol_encoder_princeton_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderPrinceton. - * @param context Pointer to a SubGhzProtocolEncoderPrinceton instance - */ -void subghz_protocol_encoder_princeton_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderPrinceton instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_princeton_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderPrinceton instance - */ -void subghz_protocol_encoder_princeton_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderPrinceton instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_princeton_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderPrinceton. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderPrinceton* pointer to a SubGhzProtocolDecoderPrinceton instance - */ -void* subghz_protocol_decoder_princeton_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderPrinceton. - * @param context Pointer to a SubGhzProtocolDecoderPrinceton instance - */ -void subghz_protocol_decoder_princeton_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderPrinceton. - * @param context Pointer to a SubGhzProtocolDecoderPrinceton instance - */ -void subghz_protocol_decoder_princeton_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderPrinceton instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_princeton_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderPrinceton instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_princeton_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderPrinceton. - * @param context Pointer to a SubGhzProtocolDecoderPrinceton instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_princeton_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderPrinceton. - * @param context Pointer to a SubGhzProtocolDecoderPrinceton instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_princeton_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderPrinceton instance - * @param output Resulting text - */ -void subghz_protocol_decoder_princeton_get_string(void* context, FuriString* output); - -#ifdef __cplusplus -} -#endif diff --git a/applications/main/subghz/protocols/princeton_for_testing.c b/applications/main/subghz/protocols/princeton_for_testing.c deleted file mode 100644 index 478d14cdf..000000000 --- a/applications/main/subghz/protocols/princeton_for_testing.c +++ /dev/null @@ -1,288 +0,0 @@ -#include "princeton_for_testing.h" - -#include -#include "../blocks/math.h" - -/* - * Help - * https://phreakerclub.com/447 - * - */ - -#define SUBGHZ_PT_SHORT 300 -#define SUBGHZ_PT_LONG (SUBGHZ_PT_SHORT * 3) -#define SUBGHZ_PT_GUARD (SUBGHZ_PT_SHORT * 30) -#define SUBGHZ_PT_COUNT_KEY_433 9 -#define SUBGHZ_PT_TIMEOUT_433 900 -#define SUBGHZ_PT_COUNT_KEY_868 9 -#define SUBGHZ_PT_TIMEOUT_868 14000 - -#define TAG "SubGhzProtocolPrinceton" - -struct SubGhzEncoderPrinceton { - uint32_t key; - uint16_t te; - size_t repeat; - size_t front; - size_t count_key; - size_t count_key_package; - uint32_t time_high; - uint32_t time_low; - uint32_t timeout; - uint32_t time_stop; -}; - -typedef enum { - PrincetonDecoderStepReset = 0, - PrincetonDecoderStepSaveDuration, - PrincetonDecoderStepCheckDuration, -} PrincetonDecoderStep; - -SubGhzEncoderPrinceton* subghz_encoder_princeton_for_testing_alloc() { - SubGhzEncoderPrinceton* instance = malloc(sizeof(SubGhzEncoderPrinceton)); - return instance; -} - -void subghz_encoder_princeton_for_testing_free(SubGhzEncoderPrinceton* instance) { - furi_assert(instance); - free(instance); -} - -void subghz_encoder_princeton_for_testing_stop( - SubGhzEncoderPrinceton* instance, - uint32_t time_stop) { - instance->time_stop = time_stop; -} - -void subghz_encoder_princeton_for_testing_set( - SubGhzEncoderPrinceton* instance, - uint32_t key, - size_t repeat, - uint32_t frequency) { - furi_assert(instance); - instance->te = SUBGHZ_PT_SHORT; - instance->key = key; - instance->repeat = repeat + 1; - instance->front = 48; - instance->time_high = 0; - instance->time_low = 0; - if(frequency < 700000000) { - instance->count_key_package = SUBGHZ_PT_COUNT_KEY_433; - instance->timeout = SUBGHZ_PT_TIMEOUT_433; - } else { - instance->count_key_package = SUBGHZ_PT_COUNT_KEY_868; - instance->timeout = SUBGHZ_PT_TIMEOUT_868; - } - - instance->count_key = instance->count_key_package + 3; - - if((furi_get_tick() - instance->time_stop) < instance->timeout) { - instance->time_stop = (instance->timeout - (furi_get_tick() - instance->time_stop)) * 1000; - } else { - instance->time_stop = 0; - } -} - -size_t subghz_encoder_princeton_for_testing_get_repeat_left(SubGhzEncoderPrinceton* instance) { - furi_assert(instance); - return instance->repeat; -} - -void subghz_encoder_princeton_for_testing_print_log(void* context) { - SubGhzEncoderPrinceton* instance = context; - float duty_cycle = - ((float)instance->time_high / (instance->time_high + instance->time_low)) * 100; - FURI_LOG_I( - TAG "Encoder", - "Radio tx_time=%luus ON=%luus, OFF=%luus, DutyCycle=%lu,%lu%%", - instance->time_high + instance->time_low, - instance->time_high, - instance->time_low, - (uint32_t)duty_cycle, - (uint32_t)((duty_cycle - (uint32_t)duty_cycle) * 100UL)); -} - -LevelDuration subghz_encoder_princeton_for_testing_yield(void* context) { - SubGhzEncoderPrinceton* instance = context; - if(instance->repeat == 0) { - subghz_encoder_princeton_for_testing_print_log(instance); - return level_duration_reset(); - } - - size_t bit = instance->front / 2; - bool level = !(instance->front % 2); - - LevelDuration ret; - if(bit < 24) { - uint8_t byte = bit / 8; - uint8_t bit_in_byte = bit % 8; - bool value = (((uint8_t*)&instance->key)[2 - byte] >> (7 - bit_in_byte)) & 1; - if(value) { - ret = level_duration_make(level, level ? instance->te * 3 : instance->te); - if(level) - instance->time_high += instance->te * 3; - else - instance->time_low += instance->te; - } else { - ret = level_duration_make(level, level ? instance->te : instance->te * 3); - if(level) - instance->time_high += instance->te; - else - instance->time_low += instance->te * 3; - } - } else { - if(instance->time_stop) { - ret = level_duration_make(level, level ? instance->te : instance->time_stop); - if(level) - instance->time_high += instance->te; - else { - instance->time_low += instance->time_stop; - instance->time_stop = 0; - instance->front = 47; - } - } else { - if(--instance->count_key != 0) { - ret = level_duration_make(level, level ? instance->te : instance->te * 30); - if(level) - instance->time_high += instance->te; - else - instance->time_low += instance->te * 30; - } else { - instance->count_key = instance->count_key_package + 2; - instance->front = 48; - ret = level_duration_make(level, level ? instance->te : instance->timeout * 1000); - if(level) - instance->time_high += instance->te; - else - instance->time_low += instance->timeout * 1000; - } - } - } - - instance->front++; - if(instance->front == 50) { - instance->repeat--; - instance->front = 0; - } - return ret; -} - -struct SubGhzDecoderPrinceton { - const char* name; - uint16_t te_long; - uint16_t te_short; - uint16_t te_delta; - uint8_t code_count_bit; - uint8_t code_last_count_bit; - uint64_t code_found; - uint64_t code_last_found; - uint8_t code_min_count_bit_for_found; - uint8_t btn; - uint32_t te_last; - uint32_t serial; - uint32_t parser_step; - uint16_t cnt; - uint32_t te; - - SubGhzDecoderPrincetonCallback callback; - void* context; -}; - -SubGhzDecoderPrinceton* subghz_decoder_princeton_for_testing_alloc(void) { - SubGhzDecoderPrinceton* instance = malloc(sizeof(SubGhzDecoderPrinceton)); - - instance->te = SUBGHZ_PT_SHORT; - instance->name = "Princeton"; - instance->code_min_count_bit_for_found = 24; - instance->te_short = 400; - instance->te_long = 1200; - instance->te_delta = 250; - return instance; -} - -void subghz_decoder_princeton_for_testing_free(SubGhzDecoderPrinceton* instance) { - furi_assert(instance); - free(instance); -} - -void subghz_decoder_princeton_for_testing_set_callback( - SubGhzDecoderPrinceton* instance, - SubGhzDecoderPrincetonCallback callback, - void* context) { - instance->callback = callback; - instance->context = context; -} - -void subghz_decoder_princeton_for_testing_reset(SubGhzDecoderPrinceton* instance) { - instance->parser_step = PrincetonDecoderStepReset; -} - -static void - subghz_decoder_princeton_for_testing_add_bit(SubGhzDecoderPrinceton* instance, uint8_t bit) { - instance->code_found = instance->code_found << 1 | bit; - instance->code_count_bit++; -} - -void subghz_decoder_princeton_for_testing_parse( - SubGhzDecoderPrinceton* instance, - bool level, - uint32_t duration) { - switch(instance->parser_step) { - case PrincetonDecoderStepReset: - if((!level) && - (DURATION_DIFF(duration, instance->te_short * 36) < instance->te_delta * 36)) { - //Found Preambula - instance->parser_step = PrincetonDecoderStepSaveDuration; - instance->code_found = 0; - instance->code_count_bit = 0; - instance->te = 0; - } - break; - case PrincetonDecoderStepSaveDuration: - //save duration - if(level) { - instance->te_last = duration; - instance->te += duration; - instance->parser_step = PrincetonDecoderStepCheckDuration; - } - break; - case PrincetonDecoderStepCheckDuration: - if(!level) { - if(duration >= ((uint32_t)instance->te_short * 10 + instance->te_delta)) { - instance->parser_step = PrincetonDecoderStepSaveDuration; - if(instance->code_count_bit == instance->code_min_count_bit_for_found) { - instance->te /= (instance->code_count_bit * 4 + 1); - - instance->code_last_found = instance->code_found; - instance->code_last_count_bit = instance->code_count_bit; - instance->serial = instance->code_found >> 4; - instance->btn = (uint8_t)instance->code_found & 0x00000F; - - if(instance->callback) instance->callback(instance, instance->context); - } - instance->code_found = 0; - instance->code_count_bit = 0; - instance->te = 0; - break; - } - - instance->te += duration; - - if((DURATION_DIFF(instance->te_last, instance->te_short) < instance->te_delta) && - (DURATION_DIFF(duration, instance->te_long) < instance->te_delta * 3)) { - subghz_decoder_princeton_for_testing_add_bit(instance, 0); - instance->parser_step = PrincetonDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->te_last, instance->te_long) < instance->te_delta * 3) && - (DURATION_DIFF(duration, instance->te_short) < instance->te_delta)) { - subghz_decoder_princeton_for_testing_add_bit(instance, 1); - instance->parser_step = PrincetonDecoderStepSaveDuration; - } else { - instance->parser_step = PrincetonDecoderStepReset; - } - } else { - instance->parser_step = PrincetonDecoderStepReset; - } - break; - } -} diff --git a/applications/main/subghz/protocols/princeton_for_testing.h b/applications/main/subghz/protocols/princeton_for_testing.h deleted file mode 100644 index 07a37ec5f..000000000 --- a/applications/main/subghz/protocols/princeton_for_testing.h +++ /dev/null @@ -1,97 +0,0 @@ -#pragma once - -#include "base.h" - -/** SubGhzDecoderPrinceton anonymous type */ -typedef struct SubGhzDecoderPrinceton SubGhzDecoderPrinceton; -/** SubGhzEncoderPrinceton anonymous type */ -typedef struct SubGhzEncoderPrinceton SubGhzEncoderPrinceton; - -typedef void (*SubGhzDecoderPrincetonCallback)(SubGhzDecoderPrinceton* parser, void* context); - -/** - * Allocate SubGhzEncoderPrinceton - * @return pointer to SubGhzEncoderPrinceton instance - */ -SubGhzEncoderPrinceton* subghz_encoder_princeton_for_testing_alloc(); - -/** - * Free SubGhzEncoderPrinceton instance - * @param instance - SubGhzEncoderPrinceton instance - */ -void subghz_encoder_princeton_for_testing_free(SubGhzEncoderPrinceton* instance); - -/** - * Forced transmission stop. - * @param instance Pointer to a SubGhzEncoderPrinceton instance - * @param time_stop Transmission stop time, ms - */ -void subghz_encoder_princeton_for_testing_stop( - SubGhzEncoderPrinceton* instance, - uint32_t time_stop); - -/** - * Set new encoder params - * @param instance - SubGhzEncoderPrinceton instance - * @param key - 24bit key - * @param repeat - how many times to repeat - * @param frequency - frequency - */ -void subghz_encoder_princeton_for_testing_set( - SubGhzEncoderPrinceton* instance, - uint32_t key, - size_t repeat, - uint32_t frequency); - -/** - * Get repeat count left - * @param instance - SubGhzEncoderPrinceton instance - * @return repeat count left - */ -size_t subghz_encoder_princeton_for_testing_get_repeat_left(SubGhzEncoderPrinceton* instance); - -/** - * Print encoder log - * @param instance - SubGhzEncoderPrinceton instance - */ -void subghz_encoder_princeton_for_testing_print_log(void* context); - -/** - * Get level duration - * @param instance - SubGhzEncoderPrinceton instance - * @return level duration - */ -LevelDuration subghz_encoder_princeton_for_testing_yield(void* context); - -/** - * Allocate SubGhzDecoderPrinceton - * @return SubGhzDecoderPrinceton* - */ -SubGhzDecoderPrinceton* subghz_decoder_princeton_for_testing_alloc(); - -/** - * Free SubGhzDecoderPrinceton - * @param instance - */ -void subghz_decoder_princeton_for_testing_free(SubGhzDecoderPrinceton* instance); - -void subghz_decoder_princeton_for_testing_set_callback( - SubGhzDecoderPrinceton* instance, - SubGhzDecoderPrincetonCallback callback, - void* context); - -/** - * Reset internal state - * @param instance - SubGhzDecoderPrinceton instance - */ -void subghz_decoder_princeton_for_testing_reset(SubGhzDecoderPrinceton* instance); - -/** - * Parse accepted duration - * @param instance - SubGhzDecoderPrinceton instance - * @param data - LevelDuration level_duration - */ -void subghz_decoder_princeton_for_testing_parse( - SubGhzDecoderPrinceton* instance, - bool level, - uint32_t duration); diff --git a/applications/main/subghz/protocols/protocol_items.c b/applications/main/subghz/protocols/protocol_items.c deleted file mode 100644 index 74244c5ff..000000000 --- a/applications/main/subghz/protocols/protocol_items.c +++ /dev/null @@ -1,50 +0,0 @@ -#include "protocol_items.h" - -const SubGhzProtocol* subghz_protocol_registry_items[] = { - &subghz_protocol_gate_tx, - &subghz_protocol_keeloq, - &subghz_protocol_star_line, - &subghz_protocol_nice_flo, - &subghz_protocol_came, - &subghz_protocol_faac_slh, - &subghz_protocol_nice_flor_s, - &subghz_protocol_came_twee, - &subghz_protocol_came_atomo, - &subghz_protocol_nero_sketch, - &subghz_protocol_ido, - &subghz_protocol_kia, - &subghz_protocol_hormann, - &subghz_protocol_nero_radio, - &subghz_protocol_somfy_telis, - &subghz_protocol_somfy_keytis, - &subghz_protocol_scher_khan, - &subghz_protocol_princeton, - &subghz_protocol_raw, - &subghz_protocol_linear, - &subghz_protocol_secplus_v2, - &subghz_protocol_secplus_v1, - &subghz_protocol_megacode, - &subghz_protocol_holtek, - &subghz_protocol_chamb_code, - &subghz_protocol_power_smart, - &subghz_protocol_marantec, - &subghz_protocol_bett, - &subghz_protocol_doitrand, - &subghz_protocol_phoenix_v2, - &subghz_protocol_honeywell_wdb, - &subghz_protocol_magellan, - &subghz_protocol_intertechno_v3, - &subghz_protocol_clemsa, - &subghz_protocol_ansonic, - &subghz_protocol_smc5326, - &subghz_protocol_holtek_th12x, - &subghz_protocol_linear_delta3, - &subghz_protocol_dooya, - &subghz_protocol_alutech_at_4n, - &subghz_protocol_kinggates_stylo_4k, - &subghz_protocol_bin_raw, -}; - -const SubGhzProtocolRegistry subghz_protocol_registry = { - .items = subghz_protocol_registry_items, - .size = COUNT_OF(subghz_protocol_registry_items)}; diff --git a/applications/main/subghz/protocols/protocol_items.h b/applications/main/subghz/protocols/protocol_items.h deleted file mode 100644 index b7e082bf5..000000000 --- a/applications/main/subghz/protocols/protocol_items.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once -#include "../registry.h" - -#include "princeton.h" -#include "keeloq.h" -#include "star_line.h" -#include "nice_flo.h" -#include "came.h" -#include "faac_slh.h" -#include "nice_flor_s.h" -#include "came_twee.h" -#include "came_atomo.h" -#include "nero_sketch.h" -#include "ido.h" -#include "kia.h" -#include "hormann.h" -#include "nero_radio.h" -#include "somfy_telis.h" -#include "somfy_keytis.h" -#include "scher_khan.h" -#include "gate_tx.h" -#include "raw.h" -#include "linear.h" -#include "linear_delta3.h" -#include "secplus_v2.h" -#include "secplus_v1.h" -#include "megacode.h" -#include "holtek.h" -#include "chamberlain_code.h" -#include "power_smart.h" -#include "marantec.h" -#include "bett.h" -#include "doitrand.h" -#include "phoenix_v2.h" -#include "honeywell_wdb.h" -#include "magellan.h" -#include "intertechno_v3.h" -#include "clemsa.h" -#include "ansonic.h" -#include "smc5326.h" -#include "holtek_ht12x.h" -#include "dooya.h" -#include "alutech_at_4n.h" -#include "kinggates_stylo_4k.h" -#include "bin_raw.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const SubGhzProtocolRegistry subghz_protocol_registry; - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/applications/main/subghz/protocols/raw.c b/applications/main/subghz/protocols/raw.c deleted file mode 100644 index 01a229047..000000000 --- a/applications/main/subghz/protocols/raw.c +++ /dev/null @@ -1,374 +0,0 @@ -#include "raw.h" -#include -#include "../subghz_file_encoder_worker.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#include -#include - -#define TAG "SubGhzProtocolRAW" -#define SUBGHZ_DOWNLOAD_MAX_SIZE 512 - -static const SubGhzBlockConst subghz_protocol_raw_const = { - .te_short = 50, - .te_long = 32700, - .te_delta = 0, - .min_count_bit_for_found = 0, -}; - -struct SubGhzProtocolDecoderRAW { - SubGhzProtocolDecoderBase base; - - int32_t* upload_raw; - uint16_t ind_write; - Storage* storage; - FlipperFormat* flipper_file; - uint32_t file_is_open; - FuriString* file_name; - size_t sample_write; - bool last_level; - bool pause; -}; - -struct SubGhzProtocolEncoderRAW { - SubGhzProtocolEncoderBase base; - - bool is_running; - FuriString* file_name; - SubGhzFileEncoderWorker* file_worker_encoder; -}; - -typedef enum { - RAWFileIsOpenClose = 0, - RAWFileIsOpenWrite, - RAWFileIsOpenRead, -} RAWFilIsOpen; - -const SubGhzProtocolDecoder subghz_protocol_raw_decoder = { - .alloc = subghz_protocol_decoder_raw_alloc, - .free = subghz_protocol_decoder_raw_free, - - .feed = subghz_protocol_decoder_raw_feed, - .reset = subghz_protocol_decoder_raw_reset, - - .get_hash_data = NULL, - .serialize = NULL, - .deserialize = subghz_protocol_decoder_raw_deserialize, - .get_string = subghz_protocol_decoder_raw_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_raw_encoder = { - .alloc = subghz_protocol_encoder_raw_alloc, - .free = subghz_protocol_encoder_raw_free, - - .deserialize = subghz_protocol_encoder_raw_deserialize, - .stop = subghz_protocol_encoder_raw_stop, - .yield = subghz_protocol_encoder_raw_yield, -}; - -const SubGhzProtocol subghz_protocol_raw = { - .name = SUBGHZ_PROTOCOL_RAW_NAME, - .type = SubGhzProtocolTypeRAW, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_868 | SubGhzProtocolFlag_315 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_FM | SubGhzProtocolFlag_RAW | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_raw_decoder, - .encoder = &subghz_protocol_raw_encoder, -}; - -bool subghz_protocol_raw_save_to_file_init( - SubGhzProtocolDecoderRAW* instance, - const char* dev_name, - SubGhzRadioPreset* preset) { - furi_assert(instance); - - instance->storage = furi_record_open(RECORD_STORAGE); - instance->flipper_file = flipper_format_file_alloc(instance->storage); - - FuriString* temp_str; - temp_str = furi_string_alloc(); - bool init = false; - - do { - // Create subghz folder directory if necessary - if(!storage_simply_mkdir(instance->storage, SUBGHZ_RAW_FOLDER)) { - break; - } - // Create saved directory if necessary - if(!storage_simply_mkdir(instance->storage, SUBGHZ_RAW_FOLDER)) { - break; - } - - furi_string_set(instance->file_name, dev_name); - // First remove subghz device file if it was saved - furi_string_printf(temp_str, "%s/%s%s", SUBGHZ_RAW_FOLDER, dev_name, SUBGHZ_APP_EXTENSION); - - if(!storage_simply_remove(instance->storage, furi_string_get_cstr(temp_str))) { - break; - } - - // Open file - if(!flipper_format_file_open_always( - instance->flipper_file, furi_string_get_cstr(temp_str))) { - FURI_LOG_E(TAG, "Unable to open file for write: %s", furi_string_get_cstr(temp_str)); - break; - } - - if(!flipper_format_write_header_cstr( - instance->flipper_file, SUBGHZ_RAW_FILE_TYPE, SUBGHZ_RAW_FILE_VERSION)) { - FURI_LOG_E(TAG, "Unable to add header"); - break; - } - - if(!flipper_format_write_uint32( - instance->flipper_file, "Frequency", &preset->frequency, 1)) { - FURI_LOG_E(TAG, "Unable to add Frequency"); - break; - } - - subghz_block_generic_get_preset_name(furi_string_get_cstr(preset->name), temp_str); - if(!flipper_format_write_string_cstr( - instance->flipper_file, "Preset", furi_string_get_cstr(temp_str))) { - FURI_LOG_E(TAG, "Unable to add Preset"); - break; - } - if(!strcmp(furi_string_get_cstr(temp_str), "FuriHalSubGhzPresetCustom")) { - if(!flipper_format_write_string_cstr( - instance->flipper_file, "Custom_preset_module", "CC1101")) { - FURI_LOG_E(TAG, "Unable to add Custom_preset_module"); - break; - } - if(!flipper_format_write_hex( - instance->flipper_file, "Custom_preset_data", preset->data, preset->data_size)) { - FURI_LOG_E(TAG, "Unable to add Custom_preset_data"); - break; - } - } - if(!flipper_format_write_string_cstr( - instance->flipper_file, "Protocol", instance->base.protocol->name)) { - FURI_LOG_E(TAG, "Unable to add Protocol"); - break; - } - - instance->upload_raw = malloc(SUBGHZ_DOWNLOAD_MAX_SIZE * sizeof(int32_t)); - instance->file_is_open = RAWFileIsOpenWrite; - instance->sample_write = 0; - instance->last_level = false; - instance->pause = false; - init = true; - } while(0); - - furi_string_free(temp_str); - - return init; -} - -static bool subghz_protocol_raw_save_to_file_write(SubGhzProtocolDecoderRAW* instance) { - furi_assert(instance); - - bool is_write = false; - if(instance->file_is_open == RAWFileIsOpenWrite) { - if(!flipper_format_write_int32( - instance->flipper_file, "RAW_Data", instance->upload_raw, instance->ind_write)) { - FURI_LOG_E(TAG, "Unable to add RAW_Data"); - } else { - instance->sample_write += instance->ind_write; - instance->ind_write = 0; - is_write = true; - } - } - return is_write; -} - -void subghz_protocol_raw_save_to_file_stop(SubGhzProtocolDecoderRAW* instance) { - furi_assert(instance); - - if(instance->file_is_open == RAWFileIsOpenWrite && instance->ind_write) - subghz_protocol_raw_save_to_file_write(instance); - if(instance->file_is_open != RAWFileIsOpenClose) { - free(instance->upload_raw); - instance->upload_raw = NULL; - flipper_format_file_close(instance->flipper_file); - flipper_format_free(instance->flipper_file); - furi_record_close(RECORD_STORAGE); - } - - instance->file_is_open = RAWFileIsOpenClose; -} - -void subghz_protocol_raw_save_to_file_pause(SubGhzProtocolDecoderRAW* instance, bool pause) { - furi_assert(instance); - - if(instance->pause != pause) { - instance->pause = pause; - } -} - -size_t subghz_protocol_raw_get_sample_write(SubGhzProtocolDecoderRAW* instance) { - return instance->sample_write + instance->ind_write; -} - -void* subghz_protocol_decoder_raw_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderRAW* instance = malloc(sizeof(SubGhzProtocolDecoderRAW)); - instance->base.protocol = &subghz_protocol_raw; - instance->upload_raw = NULL; - instance->ind_write = 0; - instance->last_level = false; - instance->file_is_open = RAWFileIsOpenClose; - instance->file_name = furi_string_alloc(); - - return instance; -} - -void subghz_protocol_decoder_raw_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderRAW* instance = context; - furi_string_free(instance->file_name); - free(instance); -} - -void subghz_protocol_decoder_raw_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderRAW* instance = context; - instance->ind_write = 0; - instance->last_level = false; -} - -void subghz_protocol_decoder_raw_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderRAW* instance = context; - - if(!instance->pause && (instance->upload_raw != NULL)) { - if(duration > subghz_protocol_raw_const.te_short) { - if(instance->last_level != level) { - instance->last_level = (level ? true : false); - instance->upload_raw[instance->ind_write++] = (level ? duration : -duration); - } - } - - if(instance->ind_write == SUBGHZ_DOWNLOAD_MAX_SIZE) { - subghz_protocol_raw_save_to_file_write(instance); - } - } -} - -bool subghz_protocol_decoder_raw_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - UNUSED(context); - UNUSED(flipper_format); - //ToDo stub, for backwards compatibility - return true; -} - -void subghz_protocol_decoder_raw_get_string(void* context, FuriString* output) { - furi_assert(context); - //SubGhzProtocolDecoderRAW* instance = context; - UNUSED(context); - //ToDo no use - furi_string_cat_printf(output, "RAW Data"); -} - -void* subghz_protocol_encoder_raw_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderRAW* instance = malloc(sizeof(SubGhzProtocolEncoderRAW)); - - instance->base.protocol = &subghz_protocol_raw; - instance->file_name = furi_string_alloc(); - instance->is_running = false; - return instance; -} - -void subghz_protocol_encoder_raw_stop(void* context) { - SubGhzProtocolEncoderRAW* instance = context; - instance->is_running = false; - if(subghz_file_encoder_worker_is_running(instance->file_worker_encoder)) { - subghz_file_encoder_worker_stop(instance->file_worker_encoder); - subghz_file_encoder_worker_free(instance->file_worker_encoder); - } -} - -void subghz_protocol_encoder_raw_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderRAW* instance = context; - subghz_protocol_encoder_raw_stop(instance); - furi_string_free(instance->file_name); - free(instance); -} - -void subghz_protocol_raw_file_encoder_worker_set_callback_end( - SubGhzProtocolEncoderRAW* instance, - SubGhzProtocolEncoderRAWCallbackEnd callback_end, - void* context_end) { - furi_assert(instance); - furi_assert(callback_end); - subghz_file_encoder_worker_callback_end( - instance->file_worker_encoder, callback_end, context_end); -} - -static bool subghz_protocol_encoder_raw_worker_init(SubGhzProtocolEncoderRAW* instance) { - furi_assert(instance); - - instance->file_worker_encoder = subghz_file_encoder_worker_alloc(); - if(subghz_file_encoder_worker_start( - instance->file_worker_encoder, furi_string_get_cstr(instance->file_name))) { - //the worker needs a file in order to open and read part of the file - furi_delay_ms(100); - instance->is_running = true; - } else { - subghz_protocol_encoder_raw_stop(instance); - } - return instance->is_running; -} - -void subghz_protocol_raw_gen_fff_data(FlipperFormat* flipper_format, const char* file_path) { - do { - stream_clean(flipper_format_get_raw_stream(flipper_format)); - if(!flipper_format_write_string_cstr(flipper_format, "Protocol", "RAW")) { - FURI_LOG_E(TAG, "Unable to add Protocol"); - break; - } - - if(!flipper_format_write_string_cstr(flipper_format, "File_name", file_path)) { - FURI_LOG_E(TAG, "Unable to add File_name"); - break; - } - } while(false); -} - -bool subghz_protocol_encoder_raw_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderRAW* instance = context; - bool res = false; - FuriString* temp_str; - temp_str = furi_string_alloc(); - do { - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - - if(!flipper_format_read_string(flipper_format, "File_name", temp_str)) { - FURI_LOG_E(TAG, "Missing File_name"); - break; - } - furi_string_set(instance->file_name, temp_str); - - res = subghz_protocol_encoder_raw_worker_init(instance); - } while(false); - furi_string_free(temp_str); - return res; -} - -LevelDuration subghz_protocol_encoder_raw_yield(void* context) { - SubGhzProtocolEncoderRAW* instance = context; - - if(!instance->is_running) return level_duration_reset(); - return subghz_file_encoder_worker_get_level_duration(instance->file_worker_encoder); -} diff --git a/applications/main/subghz/protocols/raw.h b/applications/main/subghz/protocols/raw.h deleted file mode 100644 index 44c7faec5..000000000 --- a/applications/main/subghz/protocols/raw.h +++ /dev/null @@ -1,148 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_RAW_NAME "RAW" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*SubGhzProtocolEncoderRAWCallbackEnd)(void* context); - -typedef struct SubGhzProtocolDecoderRAW SubGhzProtocolDecoderRAW; -typedef struct SubGhzProtocolEncoderRAW SubGhzProtocolEncoderRAW; - -extern const SubGhzProtocolDecoder subghz_protocol_raw_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_raw_encoder; -extern const SubGhzProtocol subghz_protocol_raw; - -/** - * Open file for writing - * @param instance Pointer to a SubGhzProtocolDecoderRAW instance - * @param dev_name File name - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_raw_save_to_file_init( - SubGhzProtocolDecoderRAW* instance, - const char* dev_name, - SubGhzRadioPreset* preset); - -/** - * Stop writing file to flash - * @param instance Pointer to a SubGhzProtocolDecoderRAW instance - */ -void subghz_protocol_raw_save_to_file_stop(SubGhzProtocolDecoderRAW* instance); - -/** - * Get the number of samples received SubGhzProtocolDecoderRAW. - * @param instance Pointer to a SubGhzProtocolDecoderRAW instance - * @return count of samples - */ -size_t subghz_protocol_raw_get_sample_write(SubGhzProtocolDecoderRAW* instance); - -/** - * Allocate SubGhzProtocolDecoderRAW. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderRAW* pointer to a SubGhzProtocolDecoderRAW instance - */ -void* subghz_protocol_decoder_raw_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderRAW. - * @param context Pointer to a SubGhzProtocolDecoderRAW instance - */ -void subghz_protocol_decoder_raw_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderRAW. - * @param context Pointer to a SubGhzProtocolDecoderRAW instance - */ -void subghz_protocol_decoder_raw_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderRAW instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_raw_feed(void* context, bool level, uint32_t duration); - -/** - * Deserialize data SubGhzProtocolDecoderRAW. - * @param context Pointer to a SubGhzProtocolDecoderRAW instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_raw_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderRAW instance - * @param output Resulting text - */ -void subghz_protocol_decoder_raw_get_string(void* context, FuriString* output); - -/** - * Allocate SubGhzProtocolEncoderRAW. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderRAW* pointer to a SubGhzProtocolEncoderRAW instance - */ -void* subghz_protocol_encoder_raw_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderRAW. - * @param context Pointer to a SubGhzProtocolEncoderRAW instance - */ -void subghz_protocol_encoder_raw_free(void* context); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderRAW instance - */ -void subghz_protocol_encoder_raw_stop(void* context); - -/** - * pause writing to flash. - * @param context Pointer to a SubGhzProtocolEncoderRAW instance - * @param pause pause writing - */ -void subghz_protocol_raw_save_to_file_pause(SubGhzProtocolDecoderRAW* instance, bool pause); - -/** - * Set callback on completion of file transfer. - * @param instance Pointer to a SubGhzProtocolEncoderRAW instance - * @param callback_end Callback, SubGhzProtocolEncoderRAWCallbackEnd - * @param context_end Context - */ -void subghz_protocol_raw_file_encoder_worker_set_callback_end( - SubGhzProtocolEncoderRAW* instance, - SubGhzProtocolEncoderRAWCallbackEnd callback_end, - void* context_end); - -/** - * File generation for RAW work. - * @param flipper_format Pointer to a FlipperFormat instance - * @param file_path File path - */ -void subghz_protocol_raw_gen_fff_data(FlipperFormat* flipper_format, const char* file_path); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderRAW instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_raw_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderRAW instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_raw_yield(void* context); - -#ifdef __cplusplus -} -#endif diff --git a/applications/main/subghz/protocols/scher_khan.c b/applications/main/subghz/protocols/scher_khan.c deleted file mode 100644 index a5de7d04b..000000000 --- a/applications/main/subghz/protocols/scher_khan.c +++ /dev/null @@ -1,288 +0,0 @@ -#include "scher_khan.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -//https://phreakerclub.com/72 -//https://phreakerclub.com/forum/showthread.php?t=7&page=2 -//https://phreakerclub.com/forum/showthread.php?t=274&highlight=magicar -//!!! https://phreakerclub.com/forum/showthread.php?t=489&highlight=magicar&page=5 - -#define TAG "SubGhzProtocolScherKhan" - -static const SubGhzBlockConst subghz_protocol_scher_khan_const = { - .te_short = 750, - .te_long = 1100, - .te_delta = 150, - .min_count_bit_for_found = 35, -}; - -struct SubGhzProtocolDecoderScherKhan { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - - uint16_t header_count; - const char* protocol_name; -}; - -struct SubGhzProtocolEncoderScherKhan { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - ScherKhanDecoderStepReset = 0, - ScherKhanDecoderStepCheckPreambula, - ScherKhanDecoderStepSaveDuration, - ScherKhanDecoderStepCheckDuration, -} ScherKhanDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_scher_khan_decoder = { - .alloc = subghz_protocol_decoder_scher_khan_alloc, - .free = subghz_protocol_decoder_scher_khan_free, - - .feed = subghz_protocol_decoder_scher_khan_feed, - .reset = subghz_protocol_decoder_scher_khan_reset, - - .get_hash_data = subghz_protocol_decoder_scher_khan_get_hash_data, - .serialize = subghz_protocol_decoder_scher_khan_serialize, - .deserialize = subghz_protocol_decoder_scher_khan_deserialize, - .get_string = subghz_protocol_decoder_scher_khan_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_scher_khan_encoder = { - .alloc = NULL, - .free = NULL, - - .deserialize = NULL, - .stop = NULL, - .yield = NULL, -}; - -const SubGhzProtocol subghz_protocol_scher_khan = { - .name = SUBGHZ_PROTOCOL_SCHER_KHAN_NAME, - .type = SubGhzProtocolTypeDynamic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_FM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Save, - - .decoder = &subghz_protocol_scher_khan_decoder, - .encoder = &subghz_protocol_scher_khan_encoder, -}; - -void* subghz_protocol_decoder_scher_khan_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderScherKhan* instance = malloc(sizeof(SubGhzProtocolDecoderScherKhan)); - instance->base.protocol = &subghz_protocol_scher_khan; - instance->generic.protocol_name = instance->base.protocol->name; - - return instance; -} - -void subghz_protocol_decoder_scher_khan_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderScherKhan* instance = context; - free(instance); -} - -void subghz_protocol_decoder_scher_khan_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderScherKhan* instance = context; - instance->decoder.parser_step = ScherKhanDecoderStepReset; -} - -void subghz_protocol_decoder_scher_khan_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderScherKhan* instance = context; - - switch(instance->decoder.parser_step) { - case ScherKhanDecoderStepReset: - if((level) && (DURATION_DIFF(duration, subghz_protocol_scher_khan_const.te_short * 2) < - subghz_protocol_scher_khan_const.te_delta)) { - instance->decoder.parser_step = ScherKhanDecoderStepCheckPreambula; - instance->decoder.te_last = duration; - instance->header_count = 0; - } - break; - case ScherKhanDecoderStepCheckPreambula: - if(level) { - if((DURATION_DIFF(duration, subghz_protocol_scher_khan_const.te_short * 2) < - subghz_protocol_scher_khan_const.te_delta) || - (DURATION_DIFF(duration, subghz_protocol_scher_khan_const.te_short) < - subghz_protocol_scher_khan_const.te_delta)) { - instance->decoder.te_last = duration; - } else { - instance->decoder.parser_step = ScherKhanDecoderStepReset; - } - } else if( - (DURATION_DIFF(duration, subghz_protocol_scher_khan_const.te_short * 2) < - subghz_protocol_scher_khan_const.te_delta) || - (DURATION_DIFF(duration, subghz_protocol_scher_khan_const.te_short) < - subghz_protocol_scher_khan_const.te_delta)) { - if(DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_scher_khan_const.te_short * 2) < - subghz_protocol_scher_khan_const.te_delta) { - // Found header - instance->header_count++; - break; - } else if( - DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_scher_khan_const.te_short) < - subghz_protocol_scher_khan_const.te_delta) { - // Found start bit - if(instance->header_count >= 2) { - instance->decoder.parser_step = ScherKhanDecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 1; - } else { - instance->decoder.parser_step = ScherKhanDecoderStepReset; - } - } else { - instance->decoder.parser_step = ScherKhanDecoderStepReset; - } - } else { - instance->decoder.parser_step = ScherKhanDecoderStepReset; - } - break; - case ScherKhanDecoderStepSaveDuration: - if(level) { - if(duration >= (subghz_protocol_scher_khan_const.te_delta * 2UL + - subghz_protocol_scher_khan_const.te_long)) { - //Found stop bit - instance->decoder.parser_step = ScherKhanDecoderStepReset; - if(instance->decoder.decode_count_bit >= - subghz_protocol_scher_khan_const.min_count_bit_for_found) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - break; - } else { - instance->decoder.te_last = duration; - instance->decoder.parser_step = ScherKhanDecoderStepCheckDuration; - } - - } else { - instance->decoder.parser_step = ScherKhanDecoderStepReset; - } - break; - case ScherKhanDecoderStepCheckDuration: - if(!level) { - if((DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_scher_khan_const.te_short) < - subghz_protocol_scher_khan_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_scher_khan_const.te_short) < - subghz_protocol_scher_khan_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = ScherKhanDecoderStepSaveDuration; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_scher_khan_const.te_long) < - subghz_protocol_scher_khan_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_scher_khan_const.te_long) < - subghz_protocol_scher_khan_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = ScherKhanDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = ScherKhanDecoderStepReset; - } - } else { - instance->decoder.parser_step = ScherKhanDecoderStepReset; - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - * @param protocol_name - */ -static void subghz_protocol_scher_khan_check_remote_controller( - SubGhzBlockGeneric* instance, - const char** protocol_name) { - /* - * MAGICAR 51 bit 00000001A99121DE83C3 MAGIC CODE, Dynamic - * 0E8C1619E830C -> 000011101000110000010110 0001 1001 1110 1000001100001100 - * 0E8C1629D830D -> 000011101000110000010110 0010 1001 1101 1000001100001101 - * 0E8C1649B830E -> 000011101000110000010110 0100 1001 1011 1000001100001110 - * 0E8C16897830F -> 000011101000110000010110 1000 1001 0111 1000001100001111 - * Serial Key Ser ~Key CNT - */ - - switch(instance->data_count_bit) { - // case 35: //MAGIC CODE, Static - // instance->protocol_name = "MAGIC CODE, Static"; - // break; - case 51: //MAGIC CODE, Dynamic - *protocol_name = "MAGIC CODE, Dynamic"; - instance->serial = ((instance->data >> 24) & 0xFFFFFF0) | ((instance->data >> 20) & 0x0F); - instance->btn = (instance->data >> 24) & 0x0F; - instance->cnt = instance->data & 0xFFFF; - break; - // case 57: //MAGIC CODE PRO / PRO2 - // instance->protocol_name = "MAGIC CODE PRO / PRO2"; - // break; - - default: - *protocol_name = "Unknown"; - instance->serial = 0; - instance->btn = 0; - instance->cnt = 0; - break; - } -} - -uint8_t subghz_protocol_decoder_scher_khan_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderScherKhan* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_scher_khan_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderScherKhan* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_scher_khan_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderScherKhan* instance = context; - return subghz_block_generic_deserialize(&instance->generic, flipper_format); -} - -void subghz_protocol_decoder_scher_khan_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderScherKhan* instance = context; - - subghz_protocol_scher_khan_check_remote_controller( - &instance->generic, &instance->protocol_name); - - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:%07lX Btn:%X Cnt:%04lX\r\n" - "Pt: %s\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)instance->generic.data, - instance->generic.serial, - instance->generic.btn, - instance->generic.cnt, - instance->protocol_name); -} diff --git a/applications/main/subghz/protocols/scher_khan.h b/applications/main/subghz/protocols/scher_khan.h deleted file mode 100644 index b7e84ea1f..000000000 --- a/applications/main/subghz/protocols/scher_khan.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_SCHER_KHAN_NAME "Scher-Khan" - -typedef struct SubGhzProtocolDecoderScherKhan SubGhzProtocolDecoderScherKhan; -typedef struct SubGhzProtocolEncoderScherKhan SubGhzProtocolEncoderScherKhan; - -extern const SubGhzProtocolDecoder subghz_protocol_scher_khan_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_scher_khan_encoder; -extern const SubGhzProtocol subghz_protocol_scher_khan; - -/** - * Allocate SubGhzProtocolDecoderScherKhan. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderScherKhan* pointer to a SubGhzProtocolDecoderScherKhan instance - */ -void* subghz_protocol_decoder_scher_khan_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderScherKhan. - * @param context Pointer to a SubGhzProtocolDecoderScherKhan instance - */ -void subghz_protocol_decoder_scher_khan_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderScherKhan. - * @param context Pointer to a SubGhzProtocolDecoderScherKhan instance - */ -void subghz_protocol_decoder_scher_khan_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderScherKhan instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_scher_khan_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderScherKhan instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_scher_khan_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderScherKhan. - * @param context Pointer to a SubGhzProtocolDecoderScherKhan instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_scher_khan_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderScherKhan. - * @param context Pointer to a SubGhzProtocolDecoderScherKhan instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_scher_khan_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderScherKhan instance - * @param output Resulting text - */ -void subghz_protocol_decoder_scher_khan_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/secplus_v1.c b/applications/main/subghz/protocols/secplus_v1.c deleted file mode 100644 index 3ef95db36..000000000 --- a/applications/main/subghz/protocols/secplus_v1.c +++ /dev/null @@ -1,634 +0,0 @@ -#include "secplus_v1.h" -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -/* -* Help -* https://github.com/argilo/secplus -* https://github.com/merbanan/rtl_433/blob/master/src/devices/secplus_v1.c -*/ - -#define TAG "SubGhzProtocoSecPlus_v1" - -#define SECPLUS_V1_BIT_ERR -1 //0b0000 -#define SECPLUS_V1_BIT_0 0 //0b0001 -#define SECPLUS_V1_BIT_1 1 //0b0011 -#define SECPLUS_V1_BIT_2 2 //0b0111 - -#define SECPLUS_V1_PACKET_1_HEADER 0x00 -#define SECPLUS_V1_PACKET_2_HEADER 0x02 -#define SECPLUS_V1_PACKET_1_INDEX_BASE 0 -#define SECPLUS_V1_PACKET_2_INDEX_BASE 21 -#define SECPLUS_V1_PACKET_1_ACCEPTED (1 << 0) -#define SECPLUS_V1_PACKET_2_ACCEPTED (1 << 1) - -static const SubGhzBlockConst subghz_protocol_secplus_v1_const = { - .te_short = 500, - .te_long = 1500, - .te_delta = 100, - .min_count_bit_for_found = 21, -}; - -struct SubGhzProtocolDecoderSecPlus_v1 { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - - uint8_t packet_accepted; - uint8_t base_packet_index; - uint8_t data_array[44]; -}; - -struct SubGhzProtocolEncoderSecPlus_v1 { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; - - uint8_t data_array[44]; -}; - -typedef enum { - SecPlus_v1DecoderStepReset = 0, - SecPlus_v1DecoderStepSearchStartBit, - SecPlus_v1DecoderStepSaveDuration, - SecPlus_v1DecoderStepDecoderData, -} SecPlus_v1DecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_secplus_v1_decoder = { - .alloc = subghz_protocol_decoder_secplus_v1_alloc, - .free = subghz_protocol_decoder_secplus_v1_free, - - .feed = subghz_protocol_decoder_secplus_v1_feed, - .reset = subghz_protocol_decoder_secplus_v1_reset, - - .get_hash_data = subghz_protocol_decoder_secplus_v1_get_hash_data, - .serialize = subghz_protocol_decoder_secplus_v1_serialize, - .deserialize = subghz_protocol_decoder_secplus_v1_deserialize, - .get_string = subghz_protocol_decoder_secplus_v1_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_secplus_v1_encoder = { - .alloc = subghz_protocol_encoder_secplus_v1_alloc, - .free = subghz_protocol_encoder_secplus_v1_free, - - .deserialize = subghz_protocol_encoder_secplus_v1_deserialize, - .stop = subghz_protocol_encoder_secplus_v1_stop, - .yield = subghz_protocol_encoder_secplus_v1_yield, -}; - -const SubGhzProtocol subghz_protocol_secplus_v1 = { - .name = SUBGHZ_PROTOCOL_SECPLUS_V1_NAME, - .type = SubGhzProtocolTypeDynamic, - .flag = SubGhzProtocolFlag_315 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Send | SubGhzProtocolFlag_Save, - - .decoder = &subghz_protocol_secplus_v1_decoder, - .encoder = &subghz_protocol_secplus_v1_encoder, -}; - -void* subghz_protocol_encoder_secplus_v1_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderSecPlus_v1* instance = malloc(sizeof(SubGhzProtocolEncoderSecPlus_v1)); - - instance->base.protocol = &subghz_protocol_secplus_v1; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 128; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_secplus_v1_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderSecPlus_v1* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderSecPlus_v1 instance - * @return true On success - */ -static bool - subghz_protocol_encoder_secplus_v1_get_upload(SubGhzProtocolEncoderSecPlus_v1* instance) { - furi_assert(instance); - size_t index = 0; - size_t size_upload = (instance->generic.data_count_bit * 2); - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Encoder size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - - //Send header packet 1 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_secplus_v1_const.te_short * (116 + 3)); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_secplus_v1_const.te_short); - - //Send data packet 1 - for(uint8_t i = SECPLUS_V1_PACKET_1_INDEX_BASE + 1; i < SECPLUS_V1_PACKET_1_INDEX_BASE + 21; - i++) { - switch(instance->data_array[i]) { - case SECPLUS_V1_BIT_0: - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_secplus_v1_const.te_short * 3); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_secplus_v1_const.te_short); - break; - case SECPLUS_V1_BIT_1: - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_secplus_v1_const.te_short * 2); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_secplus_v1_const.te_short * 2); - break; - case SECPLUS_V1_BIT_2: - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_secplus_v1_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_secplus_v1_const.te_short * 3); - break; - - default: - FURI_LOG_E(TAG, "Encoder error, wrong bit type"); - return false; - break; - } - } - - //Send header packet 2 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_secplus_v1_const.te_short * (116)); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_secplus_v1_const.te_short * 3); - - //Send data packet 2 - for(uint8_t i = SECPLUS_V1_PACKET_2_INDEX_BASE + 1; i < SECPLUS_V1_PACKET_2_INDEX_BASE + 21; - i++) { - switch(instance->data_array[i]) { - case SECPLUS_V1_BIT_0: - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_secplus_v1_const.te_short * 3); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_secplus_v1_const.te_short); - break; - case SECPLUS_V1_BIT_1: - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_secplus_v1_const.te_short * 2); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_secplus_v1_const.te_short * 2); - break; - case SECPLUS_V1_BIT_2: - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_secplus_v1_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_secplus_v1_const.te_short * 3); - break; - - default: - FURI_LOG_E(TAG, "Encoder error, wrong bit type."); - return false; - break; - } - } - - return true; -} - -/** - * Security+ 1.0 message encoding - * @param instance SubGhzProtocolEncoderSecPlus_v1* - */ - -static bool subghz_protocol_secplus_v1_encode(SubGhzProtocolEncoderSecPlus_v1* instance) { - uint32_t fixed = (instance->generic.data >> 32) & 0xFFFFFFFF; - uint32_t rolling = instance->generic.data & 0xFFFFFFFF; - - uint8_t rolling_array[20] = {0}; - uint8_t fixed_array[20] = {0}; - uint32_t acc = 0; - - //increment the counter - rolling += 2; - - //update data - instance->generic.data &= 0xFFFFFFFF00000000; - instance->generic.data |= rolling; - - if(rolling == 0xFFFFFFFF) { - rolling = 0xE6000000; - } - if(fixed > 0xCFD41B90) { - FURI_LOG_E("TAG", "Encode wrong fixed data"); - return false; - } - - rolling = subghz_protocol_blocks_reverse_key(rolling, 32); - - for(int i = 19; i > -1; i--) { - rolling_array[i] = rolling % 3; - rolling /= 3; - fixed_array[i] = fixed % 3; - fixed /= 3; - } - - instance->data_array[SECPLUS_V1_PACKET_1_INDEX_BASE] = SECPLUS_V1_PACKET_1_HEADER; - instance->data_array[SECPLUS_V1_PACKET_2_INDEX_BASE] = SECPLUS_V1_PACKET_2_HEADER; - - //encode packet 1 - for(uint8_t i = 1; i < 11; i++) { - acc += rolling_array[i - 1]; - instance->data_array[i * 2 - 1] = rolling_array[i - 1]; - acc += fixed_array[i - 1]; - instance->data_array[i * 2] = acc % 3; - } - - acc = 0; - //encode packet 2 - for(uint8_t i = 11; i < 21; i++) { - acc += rolling_array[i - 1]; - instance->data_array[i * 2] = rolling_array[i - 1]; - acc += fixed_array[i - 1]; - instance->data_array[i * 2 + 1] = acc % 3; - } - - return true; -} - -bool subghz_protocol_encoder_secplus_v1_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderSecPlus_v1* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - 2 * subghz_protocol_secplus_v1_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_secplus_v1_encode(instance)) { - break; - } - if(!subghz_protocol_encoder_secplus_v1_get_upload(instance)) { - break; - } - - uint8_t key_data[sizeof(uint64_t)] = {0}; - for(size_t i = 0; i < sizeof(uint64_t); i++) { - key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data >> (i * 8)) & 0xFF; - } - if(!flipper_format_update_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Unable to add Key"); - break; - } - - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_secplus_v1_stop(void* context) { - SubGhzProtocolEncoderSecPlus_v1* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_secplus_v1_yield(void* context) { - SubGhzProtocolEncoderSecPlus_v1* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_secplus_v1_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderSecPlus_v1* instance = malloc(sizeof(SubGhzProtocolDecoderSecPlus_v1)); - instance->base.protocol = &subghz_protocol_secplus_v1; - instance->generic.protocol_name = instance->base.protocol->name; - - return instance; -} - -void subghz_protocol_decoder_secplus_v1_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderSecPlus_v1* instance = context; - free(instance); -} - -void subghz_protocol_decoder_secplus_v1_reset(void* context) { - furi_assert(context); - // SubGhzProtocolDecoderSecPlus_v1* instance = context; - // does not reset the decoder because you need to get 2 parts of the package -} - -/** - * Security+ 1.0 message decoding - * @param instance SubGhzProtocolDecoderSecPlus_v1* - */ - -static void subghz_protocol_secplus_v1_decode(SubGhzProtocolDecoderSecPlus_v1* instance) { - uint32_t rolling = 0; - uint32_t fixed = 0; - uint32_t acc = 0; - uint8_t digit = 0; - - //decode packet 1 - for(uint8_t i = 1; i < 21; i += 2) { - digit = instance->data_array[i]; - rolling = (rolling * 3) + digit; - acc += digit; - - digit = (60 + instance->data_array[i + 1] - acc) % 3; - fixed = (fixed * 3) + digit; - acc += digit; - } - - acc = 0; - //decode packet 2 - for(uint8_t i = 22; i < 42; i += 2) { - digit = instance->data_array[i]; - rolling = (rolling * 3) + digit; - acc += digit; - - digit = (60 + instance->data_array[i + 1] - acc) % 3; - fixed = (fixed * 3) + digit; - acc += digit; - } - - rolling = subghz_protocol_blocks_reverse_key(rolling, 32); - instance->generic.data = (uint64_t)fixed << 32 | rolling; - - instance->generic.data_count_bit = - subghz_protocol_secplus_v1_const.min_count_bit_for_found * 2; -} - -void subghz_protocol_decoder_secplus_v1_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderSecPlus_v1* instance = context; - - switch(instance->decoder.parser_step) { - case SecPlus_v1DecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_secplus_v1_const.te_short * 120) < - subghz_protocol_secplus_v1_const.te_delta * 120)) { - //Found header Security+ 1.0 - instance->decoder.parser_step = SecPlus_v1DecoderStepSearchStartBit; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->packet_accepted = 0; - memset(instance->data_array, 0, sizeof(instance->data_array)); - } - break; - case SecPlus_v1DecoderStepSearchStartBit: - if(level) { - if(DURATION_DIFF(duration, subghz_protocol_secplus_v1_const.te_short) < - subghz_protocol_secplus_v1_const.te_delta) { - instance->base_packet_index = SECPLUS_V1_PACKET_1_INDEX_BASE; - instance - ->data_array[instance->decoder.decode_count_bit + instance->base_packet_index] = - SECPLUS_V1_BIT_0; - instance->decoder.decode_count_bit++; - instance->decoder.parser_step = SecPlus_v1DecoderStepSaveDuration; - } else if( - DURATION_DIFF(duration, subghz_protocol_secplus_v1_const.te_long) < - subghz_protocol_secplus_v1_const.te_delta) { - instance->base_packet_index = SECPLUS_V1_PACKET_2_INDEX_BASE; - instance - ->data_array[instance->decoder.decode_count_bit + instance->base_packet_index] = - SECPLUS_V1_BIT_2; - instance->decoder.decode_count_bit++; - instance->decoder.parser_step = SecPlus_v1DecoderStepSaveDuration; - } else { - instance->decoder.parser_step = SecPlus_v1DecoderStepReset; - } - } else { - instance->decoder.parser_step = SecPlus_v1DecoderStepReset; - } - break; - case SecPlus_v1DecoderStepSaveDuration: - if(!level) { //save interval - if(DURATION_DIFF(duration, subghz_protocol_secplus_v1_const.te_short * 120) < - subghz_protocol_secplus_v1_const.te_delta * 120) { - if(instance->decoder.decode_count_bit == - subghz_protocol_secplus_v1_const.min_count_bit_for_found) { - if(instance->base_packet_index == SECPLUS_V1_PACKET_1_INDEX_BASE) - instance->packet_accepted |= SECPLUS_V1_PACKET_1_ACCEPTED; - if(instance->base_packet_index == SECPLUS_V1_PACKET_2_INDEX_BASE) - instance->packet_accepted |= SECPLUS_V1_PACKET_2_ACCEPTED; - - if(instance->packet_accepted == - (SECPLUS_V1_PACKET_1_ACCEPTED | SECPLUS_V1_PACKET_2_ACCEPTED)) { - subghz_protocol_secplus_v1_decode(instance); - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - instance->decoder.parser_step = SecPlus_v1DecoderStepReset; - } - } - instance->decoder.parser_step = SecPlus_v1DecoderStepSearchStartBit; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - } else { - instance->decoder.te_last = duration; - instance->decoder.parser_step = SecPlus_v1DecoderStepDecoderData; - } - } else { - instance->decoder.parser_step = SecPlus_v1DecoderStepReset; - } - break; - case SecPlus_v1DecoderStepDecoderData: - if(level && (instance->decoder.decode_count_bit <= - subghz_protocol_secplus_v1_const.min_count_bit_for_found)) { - if((DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_secplus_v1_const.te_short * 3) < - subghz_protocol_secplus_v1_const.te_delta * 3) && - (DURATION_DIFF(duration, subghz_protocol_secplus_v1_const.te_short) < - subghz_protocol_secplus_v1_const.te_delta)) { - instance - ->data_array[instance->decoder.decode_count_bit + instance->base_packet_index] = - SECPLUS_V1_BIT_0; - instance->decoder.decode_count_bit++; - instance->decoder.parser_step = SecPlus_v1DecoderStepSaveDuration; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_secplus_v1_const.te_short * 2) < - subghz_protocol_secplus_v1_const.te_delta * 2) && - (DURATION_DIFF(duration, subghz_protocol_secplus_v1_const.te_short * 2) < - subghz_protocol_secplus_v1_const.te_delta * 2)) { - instance - ->data_array[instance->decoder.decode_count_bit + instance->base_packet_index] = - SECPLUS_V1_BIT_1; - instance->decoder.decode_count_bit++; - instance->decoder.parser_step = SecPlus_v1DecoderStepSaveDuration; - } else if( - (DURATION_DIFF( - instance->decoder.te_last, subghz_protocol_secplus_v1_const.te_short) < - subghz_protocol_secplus_v1_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_secplus_v1_const.te_short * 3) < - subghz_protocol_secplus_v1_const.te_delta * 3)) { - instance - ->data_array[instance->decoder.decode_count_bit + instance->base_packet_index] = - SECPLUS_V1_BIT_2; - instance->decoder.decode_count_bit++; - instance->decoder.parser_step = SecPlus_v1DecoderStepSaveDuration; - } else { - instance->decoder.parser_step = SecPlus_v1DecoderStepReset; - } - } else { - instance->decoder.parser_step = SecPlus_v1DecoderStepReset; - } - break; - } -} - -uint8_t subghz_protocol_decoder_secplus_v1_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderSecPlus_v1* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_secplus_v1_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderSecPlus_v1* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_secplus_v1_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderSecPlus_v1* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - 2 * subghz_protocol_secplus_v1_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -bool subghz_protocol_secplus_v1_check_fixed(uint32_t fixed) { - //uint8_t id0 = (fixed / 3) % 3; - uint8_t id1 = (fixed / 9) % 3; - uint8_t btn = fixed % 3; - - do { - if(id1 == 0) return false; - if(!(btn == 0 || btn == 1 || btn == 2)) return false; //-V560 - } while(false); - return true; -} - -void subghz_protocol_decoder_secplus_v1_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderSecPlus_v1* instance = context; - - uint32_t fixed = (instance->generic.data >> 32) & 0xFFFFFFFF; - instance->generic.cnt = instance->generic.data & 0xFFFFFFFF; - - instance->generic.btn = fixed % 3; - uint8_t id0 = (fixed / 3) % 3; - uint8_t id1 = (fixed / 9) % 3; - uint16_t pin = 0; - - furi_string_cat_printf( - output, - "%s %db\r\n" - "Key:0x%lX%08lX\r\n" - "id1:%d id0:%d", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)instance->generic.data, - id1, - id0); - - if(id1 == 0) { - // (fixed // 3**3) % (3**7) 3^3=27 3^73=72187 - - instance->generic.serial = (fixed / 27) % 2187; - // pin = (fixed // 3**10) % (3**9) 3^10=59049 3^9=19683 - pin = (fixed / 59049) % 19683; - - if(pin <= 9999) { - furi_string_cat_printf(output, " pin:%d", pin); - } else if(pin <= 11029) { - furi_string_cat_printf(output, " pin:enter"); - } - - int pin_suffix = 0; - // pin_suffix = (fixed // 3**19) % 3 3^19=1162261467 - pin_suffix = (fixed / 1162261467) % 3; - - if(pin_suffix == 1) { - furi_string_cat_printf(output, " #\r\n"); - } else if(pin_suffix == 2) { - furi_string_cat_printf(output, " *\r\n"); - } else { - furi_string_cat_printf(output, "\r\n"); - } - furi_string_cat_printf( - output, - "Sn:0x%08lX\r\n" - "Cnt:0x%03lX " - "Sw_id:0x%X\r\n", - instance->generic.serial, - instance->generic.cnt, - instance->generic.btn); - } else { - //id = fixed / 27; - instance->generic.serial = fixed / 27; - if(instance->generic.btn == 1) { - furi_string_cat_printf(output, " Btn:left\r\n"); - } else if(instance->generic.btn == 0) { - furi_string_cat_printf(output, " Btn:middle\r\n"); - } else if(instance->generic.btn == 2) { //-V547 - furi_string_cat_printf(output, " Btn:right\r\n"); - } - - furi_string_cat_printf( - output, - "Sn:0x%08lX\r\n" - "Cnt:0x%03lX " - "Sw_id:0x%X\r\n", - instance->generic.serial, - instance->generic.cnt, - instance->generic.btn); - } -} diff --git a/applications/main/subghz/protocols/secplus_v1.h b/applications/main/subghz/protocols/secplus_v1.h deleted file mode 100644 index 99480b62b..000000000 --- a/applications/main/subghz/protocols/secplus_v1.h +++ /dev/null @@ -1,113 +0,0 @@ -#pragma once -#include "base.h" - -#define SUBGHZ_PROTOCOL_SECPLUS_V1_NAME "Security+ 1.0" - -typedef struct SubGhzProtocolDecoderSecPlus_v1 SubGhzProtocolDecoderSecPlus_v1; -typedef struct SubGhzProtocolEncoderSecPlus_v1 SubGhzProtocolEncoderSecPlus_v1; - -extern const SubGhzProtocolDecoder subghz_protocol_secplus_v1_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_secplus_v1_encoder; -extern const SubGhzProtocol subghz_protocol_secplus_v1; - -/** - * Allocate SubGhzProtocolEncoderSecPlus_v1. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderSecPlus_v1* pointer to a SubGhzProtocolEncoderSecPlus_v1 instance - */ -void* subghz_protocol_encoder_secplus_v1_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderSecPlus_v1. - * @param context Pointer to a SubGhzProtocolEncoderSecPlus_v1 instance - */ -void subghz_protocol_encoder_secplus_v1_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderSecPlus_v1 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_secplus_v1_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderSecPlus_v1 instance - */ -void subghz_protocol_encoder_secplus_v1_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderSecPlus_v1 instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_secplus_v1_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderSecPlus_v1. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderSecPlus_v1* pointer to a SubGhzProtocolDecoderSecPlus_v1 instance - */ -void* subghz_protocol_decoder_secplus_v1_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderSecPlus_v1. - * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v1 instance - */ -void subghz_protocol_decoder_secplus_v1_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderSecPlus_v1. - * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v1 instance - */ -void subghz_protocol_decoder_secplus_v1_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v1 instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_secplus_v1_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v1 instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_secplus_v1_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderSecPlus_v1. - * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v1 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_secplus_v1_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderSecPlus_v1. - * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v1 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_secplus_v1_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Validation of fixed parts SubGhzProtocolDecoderSecPlus_v1. - * @param fixed fixed parts - * @return true On success - */ -bool subghz_protocol_secplus_v1_check_fixed(uint32_t fixed); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v1 instance - * @param output Resulting text - */ -void subghz_protocol_decoder_secplus_v1_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/secplus_v2.c b/applications/main/subghz/protocols/secplus_v2.c deleted file mode 100644 index bcef90dad..000000000 --- a/applications/main/subghz/protocols/secplus_v2.c +++ /dev/null @@ -1,833 +0,0 @@ -#include "secplus_v2.h" -#include -#include -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -/* -* Help -* https://github.com/argilo/secplus -* https://github.com/merbanan/rtl_433/blob/master/src/devices/secplus_v2.c -*/ - -#define TAG "SubGhzProtocoSecPlus_v2" - -#define SECPLUS_V2_HEADER 0x3C0000000000 -#define SECPLUS_V2_HEADER_MASK 0xFFFF3C0000000000 -#define SECPLUS_V2_PACKET_1 0x000000000000 -#define SECPLUS_V2_PACKET_2 0x010000000000 -#define SECPLUS_V2_PACKET_MASK 0x30000000000 - -static const SubGhzBlockConst subghz_protocol_secplus_v2_const = { - .te_short = 250, - .te_long = 500, - .te_delta = 110, - .min_count_bit_for_found = 62, -}; - -struct SubGhzProtocolDecoderSecPlus_v2 { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - - ManchesterState manchester_saved_state; - uint64_t secplus_packet_1; -}; - -struct SubGhzProtocolEncoderSecPlus_v2 { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; - uint64_t secplus_packet_1; -}; - -typedef enum { - SecPlus_v2DecoderStepReset = 0, - SecPlus_v2DecoderStepDecoderData, -} SecPlus_v2DecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_secplus_v2_decoder = { - .alloc = subghz_protocol_decoder_secplus_v2_alloc, - .free = subghz_protocol_decoder_secplus_v2_free, - - .feed = subghz_protocol_decoder_secplus_v2_feed, - .reset = subghz_protocol_decoder_secplus_v2_reset, - - .get_hash_data = subghz_protocol_decoder_secplus_v2_get_hash_data, - .serialize = subghz_protocol_decoder_secplus_v2_serialize, - .deserialize = subghz_protocol_decoder_secplus_v2_deserialize, - .get_string = subghz_protocol_decoder_secplus_v2_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_secplus_v2_encoder = { - .alloc = subghz_protocol_encoder_secplus_v2_alloc, - .free = subghz_protocol_encoder_secplus_v2_free, - - .deserialize = subghz_protocol_encoder_secplus_v2_deserialize, - .stop = subghz_protocol_encoder_secplus_v2_stop, - .yield = subghz_protocol_encoder_secplus_v2_yield, -}; - -const SubGhzProtocol subghz_protocol_secplus_v2 = { - .name = SUBGHZ_PROTOCOL_SECPLUS_V2_NAME, - .type = SubGhzProtocolTypeDynamic, - .flag = SubGhzProtocolFlag_315 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_secplus_v2_decoder, - .encoder = &subghz_protocol_secplus_v2_encoder, -}; - -void* subghz_protocol_encoder_secplus_v2_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderSecPlus_v2* instance = malloc(sizeof(SubGhzProtocolEncoderSecPlus_v2)); - - instance->base.protocol = &subghz_protocol_secplus_v2; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 256; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_secplus_v2_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderSecPlus_v2* instance = context; - free(instance->encoder.upload); - free(instance); -} - -static bool subghz_protocol_secplus_v2_mix_invet(uint8_t invert, uint16_t p[]) { - // selectively invert buffers - switch(invert) { - case 0x00: // 0b0000 (True, True, False), - p[0] = ~p[0] & 0x03FF; - p[1] = ~p[1] & 0x03FF; - break; - case 0x01: // 0b0001 (False, True, False), - p[1] = ~p[1] & 0x03FF; - break; - case 0x02: // 0b0010 (False, False, True), - p[2] = ~p[2] & 0x03FF; - break; - case 0x04: // 0b0100 (True, True, True), - p[0] = ~p[0] & 0x03FF; - p[1] = ~p[1] & 0x03FF; - p[2] = ~p[2] & 0x03FF; - break; - case 0x05: // 0b0101 (True, False, True), - case 0x0a: // 0b1010 (True, False, True), - p[0] = ~p[0] & 0x03FF; - p[2] = ~p[2] & 0x03FF; - break; - case 0x06: // 0b0110 (False, True, True), - p[1] = ~p[1] & 0x03FF; - p[2] = ~p[2] & 0x03FF; - break; - case 0x08: // 0b1000 (True, False, False), - p[0] = ~p[0] & 0x03FF; - break; - case 0x09: // 0b1001 (False, False, False), - break; - default: - FURI_LOG_E(TAG, "Invert FAIL"); - return false; - } - return true; -} - -static bool subghz_protocol_secplus_v2_mix_order_decode(uint8_t order, uint16_t p[]) { - uint16_t a = p[0], b = p[1], c = p[2]; - - // selectively reorder buffers - switch(order) { - case 0x06: // 0b0110 2, 1, 0], - case 0x09: // 0b1001 2, 1, 0], - p[2] = a; - // p[1]: no change - p[0] = c; - break; - case 0x08: // 0b1000 1, 2, 0], - case 0x04: // 0b0100 1, 2, 0], - p[1] = a; - p[2] = b; - p[0] = c; - break; - case 0x01: // 0b0001 2, 0, 1], - p[2] = a; - p[0] = b; - p[1] = c; - break; - case 0x00: // 0b0000 0, 2, 1], - // p[0]: no change - p[2] = b; - p[1] = c; - break; - case 0x05: // 0b0101 1, 0, 2], - p[1] = a; - p[0] = b; - // p[2]: no change - break; - case 0x02: // 0b0010 0, 1, 2], - case 0x0A: // 0b1010 0, 1, 2], - // no reordering - break; - default: - FURI_LOG_E(TAG, "Order FAIL"); - return false; - } - return true; -} - -static bool subghz_protocol_secplus_v2_mix_order_encode(uint8_t order, uint16_t p[]) { - uint16_t a, b, c; - - // selectively reorder buffers - switch(order) { - case 0x06: // 0b0110 2, 1, 0], - case 0x09: // 0b1001 2, 1, 0], - a = p[2]; - b = p[1]; - c = p[0]; - break; - case 0x08: // 0b1000 1, 2, 0], - case 0x04: // 0b0100 1, 2, 0], - a = p[1]; - b = p[2]; - c = p[0]; - break; - case 0x01: // 0b0001 2, 0, 1], - a = p[2]; - b = p[0]; - c = p[1]; - break; - case 0x00: // 0b0000 0, 2, 1], - a = p[0]; - b = p[2]; - c = p[1]; - break; - case 0x05: // 0b0101 1, 0, 2], - a = p[1]; - b = p[0]; - c = p[2]; - break; - case 0x02: // 0b0010 0, 1, 2], - case 0x0A: // 0b1010 0, 1, 2], - a = p[0]; - b = p[1]; - c = p[2]; - break; - default: - FURI_LOG_E(TAG, "Order FAIL"); - return false; - } - - p[0] = a; - p[1] = b; - p[2] = c; - return true; -} - -/** - * Security+ 2.0 half-message decoding - * @param data data - * @param roll_array[] return roll_array part - * @param fixed[] return fixed part - * @return true On success - */ - -static bool - subghz_protocol_secplus_v2_decode_half(uint64_t data, uint8_t roll_array[], uint32_t* fixed) { - uint8_t order = (data >> 34) & 0x0f; - uint8_t invert = (data >> 30) & 0x0f; - uint16_t p[3] = {0}; - - for(int i = 29; i >= 0; i -= 3) { - p[0] = p[0] << 1 | bit_read(data, i); - p[1] = p[1] << 1 | bit_read(data, i - 1); - p[2] = p[2] << 1 | bit_read(data, i - 2); - } - - if(!subghz_protocol_secplus_v2_mix_invet(invert, p)) return false; - if(!subghz_protocol_secplus_v2_mix_order_decode(order, p)) return false; - - data = order << 4 | invert; - int k = 0; - for(int i = 6; i >= 0; i -= 2) { - roll_array[k] = (data >> i) & 0x03; - if(roll_array[k++] == 3) { - FURI_LOG_E(TAG, "Roll_Array FAIL"); - return false; - } - } - - for(int i = 8; i >= 0; i -= 2) { - roll_array[k] = (p[2] >> i) & 0x03; - if(roll_array[k++] == 3) { - FURI_LOG_E(TAG, "Roll_Array FAIL"); - return false; - } - } - - fixed[0] = p[0] << 10 | p[1]; - return true; -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - * @param packet_1 first part of the message - */ -static void - subghz_protocol_secplus_v2_remote_controller(SubGhzBlockGeneric* instance, uint64_t packet_1) { - uint32_t fixed_1[1]; - uint8_t roll_1[9] = {0}; - uint32_t fixed_2[1]; - uint8_t roll_2[9] = {0}; - uint8_t rolling_digits[18] = {0}; - - if(subghz_protocol_secplus_v2_decode_half(packet_1, roll_1, fixed_1) && - subghz_protocol_secplus_v2_decode_half(instance->data, roll_2, fixed_2)) { - rolling_digits[0] = roll_2[8]; - rolling_digits[1] = roll_1[8]; - - rolling_digits[2] = roll_2[4]; - rolling_digits[3] = roll_2[5]; - rolling_digits[4] = roll_2[6]; - rolling_digits[5] = roll_2[7]; - - rolling_digits[6] = roll_1[4]; - rolling_digits[7] = roll_1[5]; - rolling_digits[8] = roll_1[6]; - rolling_digits[9] = roll_1[7]; - - rolling_digits[10] = roll_2[0]; - rolling_digits[11] = roll_2[1]; - rolling_digits[12] = roll_2[2]; - rolling_digits[13] = roll_2[3]; - - rolling_digits[14] = roll_1[0]; - rolling_digits[15] = roll_1[1]; - rolling_digits[16] = roll_1[2]; - rolling_digits[17] = roll_1[3]; - - uint32_t rolling = 0; - for(int i = 0; i < 18; i++) { - rolling = (rolling * 3) + rolling_digits[i]; - } - // Max value = 2^28 (268435456) - if(rolling >= 0x10000000) { - FURI_LOG_E(TAG, "Rolling FAIL"); - instance->cnt = 0; - instance->btn = 0; - instance->serial = 0; - } else { - instance->cnt = subghz_protocol_blocks_reverse_key(rolling, 28); - instance->btn = fixed_1[0] >> 12; - instance->serial = fixed_1[0] << 20 | fixed_2[0]; - } - } else { - instance->cnt = 0; - instance->btn = 0; - instance->serial = 0; - } -} - -/** - * Security+ 2.0 half-message encoding - * @param roll_array[] roll_array part - * @param fixed[] fixed part - * @return return data - */ - -static uint64_t subghz_protocol_secplus_v2_encode_half(uint8_t roll_array[], uint32_t fixed) { - uint64_t data = 0; - uint16_t p[3] = {(fixed >> 10) & 0x3FF, fixed & 0x3FF, 0}; - uint8_t order = roll_array[0] << 2 | roll_array[1]; - uint8_t invert = roll_array[2] << 2 | roll_array[3]; - p[2] = (uint16_t)roll_array[4] << 8 | roll_array[5] << 6 | roll_array[6] << 4 | - roll_array[7] << 2 | roll_array[8]; - - if(!subghz_protocol_secplus_v2_mix_order_encode(order, p)) return 0; - if(!subghz_protocol_secplus_v2_mix_invet(invert, p)) return 0; - - for(int i = 0; i < 10; i++) { - data <<= 3; - data |= bit_read(p[0], 9 - i) << 2 | bit_read(p[1], 9 - i) << 1 | bit_read(p[2], 9 - i); - } - data |= ((uint64_t)order) << 34 | ((uint64_t)invert) << 30; - - return data; -} - -/** - * Security+ 2.0 message encoding - * @param instance SubGhzProtocolEncoderSecPlus_v2* - */ - -static void subghz_protocol_secplus_v2_encode(SubGhzProtocolEncoderSecPlus_v2* instance) { - uint32_t fixed_1[1] = {instance->generic.btn << 12 | instance->generic.serial >> 20}; - uint32_t fixed_2[1] = {instance->generic.serial & 0xFFFFF}; - uint8_t rolling_digits[18] = {0}; - uint8_t roll_1[9] = {0}; - uint8_t roll_2[9] = {0}; - - instance->generic.cnt++; - //ToDo it is not known what value the counter starts - if(instance->generic.cnt > 0xFFFFFFF) instance->generic.cnt = 0xE500000; - uint32_t rolling = subghz_protocol_blocks_reverse_key(instance->generic.cnt, 28); - - for(int8_t i = 17; i > -1; i--) { - rolling_digits[i] = rolling % 3; - rolling /= 3; - } - - roll_2[8] = rolling_digits[0]; - roll_1[8] = rolling_digits[1]; - - roll_2[4] = rolling_digits[2]; - roll_2[5] = rolling_digits[3]; - roll_2[6] = rolling_digits[4]; - roll_2[7] = rolling_digits[5]; - - roll_1[4] = rolling_digits[6]; - roll_1[5] = rolling_digits[7]; - roll_1[6] = rolling_digits[8]; - roll_1[7] = rolling_digits[9]; - - roll_2[0] = rolling_digits[10]; - roll_2[1] = rolling_digits[11]; - roll_2[2] = rolling_digits[12]; - roll_2[3] = rolling_digits[13]; - - roll_1[0] = rolling_digits[14]; - roll_1[1] = rolling_digits[15]; - roll_1[2] = rolling_digits[16]; - roll_1[3] = rolling_digits[17]; - - instance->secplus_packet_1 = SECPLUS_V2_HEADER | SECPLUS_V2_PACKET_1 | - subghz_protocol_secplus_v2_encode_half(roll_1, fixed_1[0]); - instance->generic.data = SECPLUS_V2_HEADER | SECPLUS_V2_PACKET_2 | - subghz_protocol_secplus_v2_encode_half(roll_2, fixed_2[0]); -} - -static LevelDuration - subghz_protocol_encoder_secplus_v2_add_duration_to_upload(ManchesterEncoderResult result) { - LevelDuration data = {.duration = 0, .level = 0}; - switch(result) { - case ManchesterEncoderResultShortLow: - data.duration = subghz_protocol_secplus_v2_const.te_short; - data.level = false; - break; - case ManchesterEncoderResultLongLow: - data.duration = subghz_protocol_secplus_v2_const.te_long; - data.level = false; - break; - case ManchesterEncoderResultLongHigh: - data.duration = subghz_protocol_secplus_v2_const.te_long; - data.level = true; - break; - case ManchesterEncoderResultShortHigh: - data.duration = subghz_protocol_secplus_v2_const.te_short; - data.level = true; - break; - - default: - furi_crash("SubGhz: ManchesterEncoderResult is incorrect."); - break; - } - return level_duration_make(data.level, data.duration); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderSecPlus_v2 instance - */ -static void - subghz_protocol_encoder_secplus_v2_get_upload(SubGhzProtocolEncoderSecPlus_v2* instance) { - furi_assert(instance); - size_t index = 0; - - ManchesterEncoderState enc_state; - manchester_encoder_reset(&enc_state); - ManchesterEncoderResult result; - - //Send data packet 1 - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(!manchester_encoder_advance( - &enc_state, bit_read(instance->secplus_packet_1, i - 1), &result)) { - instance->encoder.upload[index++] = - subghz_protocol_encoder_secplus_v2_add_duration_to_upload(result); - manchester_encoder_advance( - &enc_state, bit_read(instance->secplus_packet_1, i - 1), &result); - } - instance->encoder.upload[index++] = - subghz_protocol_encoder_secplus_v2_add_duration_to_upload(result); - } - instance->encoder.upload[index] = subghz_protocol_encoder_secplus_v2_add_duration_to_upload( - manchester_encoder_finish(&enc_state)); - if(level_duration_get_level(instance->encoder.upload[index])) { - index++; - } - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_secplus_v2_const.te_long * 136); - - //Send data packet 2 - manchester_encoder_reset(&enc_state); - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(!manchester_encoder_advance( - &enc_state, bit_read(instance->generic.data, i - 1), &result)) { - instance->encoder.upload[index++] = - subghz_protocol_encoder_secplus_v2_add_duration_to_upload(result); - manchester_encoder_advance( - &enc_state, bit_read(instance->generic.data, i - 1), &result); - } - instance->encoder.upload[index++] = - subghz_protocol_encoder_secplus_v2_add_duration_to_upload(result); - } - instance->encoder.upload[index] = subghz_protocol_encoder_secplus_v2_add_duration_to_upload( - manchester_encoder_finish(&enc_state)); - if(level_duration_get_level(instance->encoder.upload[index])) { - index++; - } - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_secplus_v2_const.te_long * 136); - - instance->encoder.size_upload = index; -} - -bool subghz_protocol_encoder_secplus_v2_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderSecPlus_v2* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_secplus_v2_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - uint8_t key_data[sizeof(uint64_t)] = {0}; - if(!flipper_format_read_hex( - flipper_format, "Secplus_packet_1", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Secplus_packet_1"); - break; - } - for(uint8_t i = 0; i < sizeof(uint64_t); i++) { - instance->secplus_packet_1 = instance->secplus_packet_1 << 8 | key_data[i]; - } - - subghz_protocol_secplus_v2_remote_controller( - &instance->generic, instance->secplus_packet_1); - subghz_protocol_secplus_v2_encode(instance); - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - subghz_protocol_encoder_secplus_v2_get_upload(instance); - - //update data - for(size_t i = 0; i < sizeof(uint64_t); i++) { - key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data >> (i * 8)) & 0xFF; - } - if(!flipper_format_update_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Unable to add Key"); - break; - } - - for(size_t i = 0; i < sizeof(uint64_t); i++) { - key_data[sizeof(uint64_t) - i - 1] = (instance->secplus_packet_1 >> (i * 8)) & 0xFF; - } - if(!flipper_format_update_hex( - flipper_format, "Secplus_packet_1", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Unable to add Secplus_packet_1"); - break; - } - - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_secplus_v2_stop(void* context) { - SubGhzProtocolEncoderSecPlus_v2* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_secplus_v2_yield(void* context) { - SubGhzProtocolEncoderSecPlus_v2* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -bool subghz_protocol_secplus_v2_create_data( - void* context, - FlipperFormat* flipper_format, - uint32_t serial, - uint8_t btn, - uint32_t cnt, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolEncoderSecPlus_v2* instance = context; - instance->generic.serial = serial; - instance->generic.cnt = cnt; - instance->generic.btn = btn; - instance->generic.data_count_bit = - (uint8_t)subghz_protocol_secplus_v2_const.min_count_bit_for_found; - subghz_protocol_secplus_v2_encode(instance); - bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); - - uint8_t key_data[sizeof(uint64_t)] = {0}; - for(size_t i = 0; i < sizeof(uint64_t); i++) { - key_data[sizeof(uint64_t) - i - 1] = (instance->secplus_packet_1 >> (i * 8)) & 0xFF; - } - - if(res && - !flipper_format_write_hex(flipper_format, "Secplus_packet_1", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Unable to add Secplus_packet_1"); - res = false; - } - return res; -} - -void* subghz_protocol_decoder_secplus_v2_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderSecPlus_v2* instance = malloc(sizeof(SubGhzProtocolDecoderSecPlus_v2)); - instance->base.protocol = &subghz_protocol_secplus_v2; - instance->generic.protocol_name = instance->base.protocol->name; - - return instance; -} - -void subghz_protocol_decoder_secplus_v2_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderSecPlus_v2* instance = context; - free(instance); -} - -void subghz_protocol_decoder_secplus_v2_reset(void* context) { - furi_assert(context); - // SubGhzProtocolDecoderSecPlus_v2* instance = context; - // does not reset the decoder because you need to get 2 parts of the package -} - -static bool subghz_protocol_secplus_v2_check_packet(SubGhzProtocolDecoderSecPlus_v2* instance) { - if((instance->decoder.decode_data & SECPLUS_V2_HEADER_MASK) == SECPLUS_V2_HEADER) { - if((instance->decoder.decode_data & SECPLUS_V2_PACKET_MASK) == SECPLUS_V2_PACKET_1) { - instance->secplus_packet_1 = instance->decoder.decode_data; - } else if( - ((instance->decoder.decode_data & SECPLUS_V2_PACKET_MASK) == SECPLUS_V2_PACKET_2) && - (instance->secplus_packet_1)) { - return true; - } - } - return false; -} - -void subghz_protocol_decoder_secplus_v2_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderSecPlus_v2* instance = context; - - ManchesterEvent event = ManchesterEventReset; - switch(instance->decoder.parser_step) { - case SecPlus_v2DecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_secplus_v2_const.te_long * 130) < - subghz_protocol_secplus_v2_const.te_delta * 100)) { - //Found header Security+ 2.0 - instance->decoder.parser_step = SecPlus_v2DecoderStepDecoderData; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->secplus_packet_1 = 0; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventReset, - &instance->manchester_saved_state, - NULL); - manchester_advance( - instance->manchester_saved_state, - ManchesterEventLongHigh, - &instance->manchester_saved_state, - NULL); - manchester_advance( - instance->manchester_saved_state, - ManchesterEventShortLow, - &instance->manchester_saved_state, - NULL); - } - break; - case SecPlus_v2DecoderStepDecoderData: - if(!level) { - if(DURATION_DIFF(duration, subghz_protocol_secplus_v2_const.te_short) < - subghz_protocol_secplus_v2_const.te_delta) { - event = ManchesterEventShortLow; - } else if( - DURATION_DIFF(duration, subghz_protocol_secplus_v2_const.te_long) < - subghz_protocol_secplus_v2_const.te_delta) { - event = ManchesterEventLongLow; - } else if( - duration >= (subghz_protocol_secplus_v2_const.te_long * 2UL + - subghz_protocol_secplus_v2_const.te_delta)) { - if(instance->decoder.decode_count_bit == - subghz_protocol_secplus_v2_const.min_count_bit_for_found) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - if(subghz_protocol_secplus_v2_check_packet(instance)) { - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - instance->decoder.parser_step = SecPlus_v2DecoderStepReset; - } - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventReset, - &instance->manchester_saved_state, - NULL); - manchester_advance( - instance->manchester_saved_state, - ManchesterEventLongHigh, - &instance->manchester_saved_state, - NULL); - manchester_advance( - instance->manchester_saved_state, - ManchesterEventShortLow, - &instance->manchester_saved_state, - NULL); - } else { - instance->decoder.parser_step = SecPlus_v2DecoderStepReset; - } - } else { - if(DURATION_DIFF(duration, subghz_protocol_secplus_v2_const.te_short) < - subghz_protocol_secplus_v2_const.te_delta) { - event = ManchesterEventShortHigh; - } else if( - DURATION_DIFF(duration, subghz_protocol_secplus_v2_const.te_long) < - subghz_protocol_secplus_v2_const.te_delta) { - event = ManchesterEventLongHigh; - } else { - instance->decoder.parser_step = SecPlus_v2DecoderStepReset; - } - } - if(event != ManchesterEventReset) { - bool data; - bool data_ok = manchester_advance( - instance->manchester_saved_state, event, &instance->manchester_saved_state, &data); - - if(data_ok) { - instance->decoder.decode_data = (instance->decoder.decode_data << 1) | data; - instance->decoder.decode_count_bit++; - } - } - break; - } -} - -uint8_t subghz_protocol_decoder_secplus_v2_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderSecPlus_v2* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_secplus_v2_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderSecPlus_v2* instance = context; - bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); - - uint8_t key_data[sizeof(uint64_t)] = {0}; - for(size_t i = 0; i < sizeof(uint64_t); i++) { - key_data[sizeof(uint64_t) - i - 1] = (instance->secplus_packet_1 >> (i * 8)) & 0xFF; - } - - if(res && - !flipper_format_write_hex(flipper_format, "Secplus_packet_1", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Unable to add Secplus_packet_1"); - res = false; - } - return res; -} - -bool subghz_protocol_decoder_secplus_v2_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderSecPlus_v2* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_secplus_v2_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - uint8_t key_data[sizeof(uint64_t)] = {0}; - if(!flipper_format_read_hex( - flipper_format, "Secplus_packet_1", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Missing Secplus_packet_1"); - break; - } - for(uint8_t i = 0; i < sizeof(uint64_t); i++) { - instance->secplus_packet_1 = instance->secplus_packet_1 << 8 | key_data[i]; - } - res = true; - } while(false); - - return res; -} - -void subghz_protocol_decoder_secplus_v2_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderSecPlus_v2* instance = context; - subghz_protocol_secplus_v2_remote_controller(&instance->generic, instance->secplus_packet_1); - - furi_string_cat_printf( - output, - "%s %db\r\n" - "Pk1:0x%lX%08lX\r\n" - "Pk2:0x%lX%08lX\r\n" - "Sn:0x%08lX Btn:0x%01X\r\n" - "Cnt:0x%03lX\r\n", - - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->secplus_packet_1 >> 32), - (uint32_t)instance->secplus_packet_1, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)instance->generic.data, - instance->generic.serial, - instance->generic.btn, - instance->generic.cnt); -} diff --git a/applications/main/subghz/protocols/secplus_v2.h b/applications/main/subghz/protocols/secplus_v2.h deleted file mode 100644 index bea8cdb5d..000000000 --- a/applications/main/subghz/protocols/secplus_v2.h +++ /dev/null @@ -1,125 +0,0 @@ -#pragma once -#include "base.h" - -#define SUBGHZ_PROTOCOL_SECPLUS_V2_NAME "Security+ 2.0" - -typedef struct SubGhzProtocolDecoderSecPlus_v2 SubGhzProtocolDecoderSecPlus_v2; -typedef struct SubGhzProtocolEncoderSecPlus_v2 SubGhzProtocolEncoderSecPlus_v2; - -extern const SubGhzProtocolDecoder subghz_protocol_secplus_v2_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_secplus_v2_encoder; -extern const SubGhzProtocol subghz_protocol_secplus_v2; - -/** - * Allocate SubGhzProtocolEncoderSecPlus_v2. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderSecPlus_v2* pointer to a SubGhzProtocolEncoderSecPlus_v2 instance - */ -void* subghz_protocol_encoder_secplus_v2_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderSecPlus_v2. - * @param context Pointer to a SubGhzProtocolEncoderSecPlus_v2 instance - */ -void subghz_protocol_encoder_secplus_v2_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderSecPlus_v2 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_secplus_v2_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderSecPlus_v2 instance - */ -void subghz_protocol_encoder_secplus_v2_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderSecPlus_v2 instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_secplus_v2_yield(void* context); - -/** - * Key generation from simple data. - * @param context Pointer to a SubGhzProtocolEncoderSecPlus_v2 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param serial Serial number, 32 bit - * @param btn Button number, 8 bit - * @param cnt Container value, 28 bit - * @param manufacture_name Name of manufacturer's key - * @param preset Modulation, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_secplus_v2_create_data( - void* context, - FlipperFormat* flipper_format, - uint32_t serial, - uint8_t btn, - uint32_t cnt, - SubGhzRadioPreset* preset); - -/** - * Allocate SubGhzProtocolDecoderSecPlus_v2. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderSecPlus_v2* pointer to a SubGhzProtocolDecoderSecPlus_v2 instance - */ -void* subghz_protocol_decoder_secplus_v2_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderSecPlus_v2. - * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v2 instance - */ -void subghz_protocol_decoder_secplus_v2_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderSecPlus_v2. - * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v2 instance - */ -void subghz_protocol_decoder_secplus_v2_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v2 instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_secplus_v2_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v2 instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_secplus_v2_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderSecPlus_v2. - * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v2 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_secplus_v2_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderSecPlus_v2. - * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v2 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_secplus_v2_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderSecPlus_v2 instance - * @param output Resulting text - */ -void subghz_protocol_decoder_secplus_v2_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/smc5326.c b/applications/main/subghz/protocols/smc5326.c deleted file mode 100644 index 9c9b5d4fd..000000000 --- a/applications/main/subghz/protocols/smc5326.c +++ /dev/null @@ -1,387 +0,0 @@ -#include "smc5326.h" - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -/* - * Help - * https://datasheetspdf.com/pdf-file/532079/Aslic/AX5326-4/1 - * - */ - -#define TAG "SubGhzProtocolSMC5326" - -#define DIP_P 0b11 //(+) -#define DIP_O 0b10 //(0) -#define DIP_N 0b00 //(-) - -#define DIP_PATTERN "%c%c%c%c%c%c%c%c" -#define SHOW_DIP_P(dip, check_dip) \ - ((((dip >> 0xE) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0xC) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0xA) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0x8) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0x6) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0x4) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0x2) & 0x3) == check_dip) ? '*' : '_'), \ - ((((dip >> 0x0) & 0x3) == check_dip) ? '*' : '_') - -static const SubGhzBlockConst subghz_protocol_smc5326_const = { - .te_short = 300, - .te_long = 900, - .te_delta = 200, - .min_count_bit_for_found = 25, -}; - -struct SubGhzProtocolDecoderSMC5326 { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - - uint32_t te; - uint32_t last_data; -}; - -struct SubGhzProtocolEncoderSMC5326 { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; - - uint32_t te; -}; - -typedef enum { - SMC5326DecoderStepReset = 0, - SMC5326DecoderStepSaveDuration, - SMC5326DecoderStepCheckDuration, -} SMC5326DecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_smc5326_decoder = { - .alloc = subghz_protocol_decoder_smc5326_alloc, - .free = subghz_protocol_decoder_smc5326_free, - - .feed = subghz_protocol_decoder_smc5326_feed, - .reset = subghz_protocol_decoder_smc5326_reset, - - .get_hash_data = subghz_protocol_decoder_smc5326_get_hash_data, - .serialize = subghz_protocol_decoder_smc5326_serialize, - .deserialize = subghz_protocol_decoder_smc5326_deserialize, - .get_string = subghz_protocol_decoder_smc5326_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_smc5326_encoder = { - .alloc = subghz_protocol_encoder_smc5326_alloc, - .free = subghz_protocol_encoder_smc5326_free, - - .deserialize = subghz_protocol_encoder_smc5326_deserialize, - .stop = subghz_protocol_encoder_smc5326_stop, - .yield = subghz_protocol_encoder_smc5326_yield, -}; - -const SubGhzProtocol subghz_protocol_smc5326 = { - .name = SUBGHZ_PROTOCOL_SMC5326_NAME, - .type = SubGhzProtocolTypeStatic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_868 | SubGhzProtocolFlag_315 | - SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | - SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_smc5326_decoder, - .encoder = &subghz_protocol_smc5326_encoder, -}; - -void* subghz_protocol_encoder_smc5326_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderSMC5326* instance = malloc(sizeof(SubGhzProtocolEncoderSMC5326)); - - instance->base.protocol = &subghz_protocol_smc5326; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 128; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - return instance; -} - -void subghz_protocol_encoder_smc5326_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderSMC5326* instance = context; - free(instance->encoder.upload); - free(instance); -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderSMC5326 instance - * @return true On success - */ -static bool subghz_protocol_encoder_smc5326_get_upload(SubGhzProtocolEncoderSMC5326* instance) { - furi_assert(instance); - - size_t index = 0; - size_t size_upload = (instance->generic.data_count_bit * 2) + 2; - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)instance->te * 3); - instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)instance->te); - } else { - //send bit 0 - instance->encoder.upload[index++] = level_duration_make(true, (uint32_t)instance->te); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)instance->te * 3); - } - } - - //Send Stop bit - instance->encoder.upload[index++] = level_duration_make(true, (uint32_t)instance->te); - //Send PT_GUARD - instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)instance->te * 25); - - return true; -} - -bool subghz_protocol_encoder_smc5326_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderSMC5326* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) { - FURI_LOG_E(TAG, "Missing TE"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_smc5326_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - if(!subghz_protocol_encoder_smc5326_get_upload(instance)) break; - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_smc5326_stop(void* context) { - SubGhzProtocolEncoderSMC5326* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_smc5326_yield(void* context) { - SubGhzProtocolEncoderSMC5326* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_smc5326_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderSMC5326* instance = malloc(sizeof(SubGhzProtocolDecoderSMC5326)); - instance->base.protocol = &subghz_protocol_smc5326; - instance->generic.protocol_name = instance->base.protocol->name; - return instance; -} - -void subghz_protocol_decoder_smc5326_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderSMC5326* instance = context; - free(instance); -} - -void subghz_protocol_decoder_smc5326_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderSMC5326* instance = context; - instance->decoder.parser_step = SMC5326DecoderStepReset; - instance->last_data = 0; -} - -void subghz_protocol_decoder_smc5326_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderSMC5326* instance = context; - - switch(instance->decoder.parser_step) { - case SMC5326DecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_smc5326_const.te_short * 24) < - subghz_protocol_smc5326_const.te_delta * 12)) { - //Found Preambula - instance->decoder.parser_step = SMC5326DecoderStepSaveDuration; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->te = 0; - } - break; - case SMC5326DecoderStepSaveDuration: - //save duration - if(level) { - instance->decoder.te_last = duration; - instance->te += duration; - instance->decoder.parser_step = SMC5326DecoderStepCheckDuration; - } - break; - case SMC5326DecoderStepCheckDuration: - if(!level) { - if(duration >= ((uint32_t)subghz_protocol_smc5326_const.te_long * 2)) { - instance->decoder.parser_step = SMC5326DecoderStepSaveDuration; - if(instance->decoder.decode_count_bit == - subghz_protocol_smc5326_const.min_count_bit_for_found) { - if((instance->last_data == instance->decoder.decode_data) && - instance->last_data) { - instance->te /= (instance->decoder.decode_count_bit * 4 + 1); - - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - instance->last_data = instance->decoder.decode_data; - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->te = 0; - break; - } - - instance->te += duration; - - if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_smc5326_const.te_short) < - subghz_protocol_smc5326_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_smc5326_const.te_long) < - subghz_protocol_smc5326_const.te_delta * 3)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = SMC5326DecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_smc5326_const.te_long) < - subghz_protocol_smc5326_const.te_delta * 3) && - (DURATION_DIFF(duration, subghz_protocol_smc5326_const.te_short) < - subghz_protocol_smc5326_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = SMC5326DecoderStepSaveDuration; - } else { - instance->decoder.parser_step = SMC5326DecoderStepReset; - } - } else { - instance->decoder.parser_step = SMC5326DecoderStepReset; - } - break; - } -} - -uint8_t subghz_protocol_decoder_smc5326_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderSMC5326* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_smc5326_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderSMC5326* instance = context; - bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); - if(res && !flipper_format_write_uint32(flipper_format, "TE", &instance->te, 1)) { - FURI_LOG_E(TAG, "Unable to add TE"); - res = false; - } - return res; -} - -bool subghz_protocol_decoder_smc5326_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderSMC5326* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_smc5326_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) { - FURI_LOG_E(TAG, "Missing TE"); - break; - } - res = true; - } while(false); - - return res; -} - -static void subghz_protocol_smc5326_get_event_serialize(uint8_t event, FuriString* output) { - furi_string_cat_printf( - output, - "%s%s%s%s\r\n", - (((event >> 6) & 0x3) == 0x3 ? "B1 " : ""), - (((event >> 4) & 0x3) == 0x3 ? "B2 " : ""), - (((event >> 2) & 0x3) == 0x3 ? "B3 " : ""), - (((event >> 0) & 0x3) == 0x3 ? "B4 " : "")); -} - -void subghz_protocol_decoder_smc5326_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderSMC5326* instance = context; - uint32_t data = (uint32_t)((instance->generic.data >> 9) & 0xFFFF); - - furi_string_cat_printf( - output, - "%s %ubit\r\n" - "Key:%07lX Te:%luus\r\n" - " +: " DIP_PATTERN "\r\n" - " o: " DIP_PATTERN " ", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data & 0x1FFFFFF), - instance->te, - SHOW_DIP_P(data, DIP_P), - SHOW_DIP_P(data, DIP_O)); - subghz_protocol_smc5326_get_event_serialize(instance->generic.data >> 1, output); - furi_string_cat_printf(output, " -: " DIP_PATTERN "\r\n", SHOW_DIP_P(data, DIP_N)); -} diff --git a/applications/main/subghz/protocols/smc5326.h b/applications/main/subghz/protocols/smc5326.h deleted file mode 100644 index ddc954bd5..000000000 --- a/applications/main/subghz/protocols/smc5326.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_SMC5326_NAME "SMC5326" - -typedef struct SubGhzProtocolDecoderSMC5326 SubGhzProtocolDecoderSMC5326; -typedef struct SubGhzProtocolEncoderSMC5326 SubGhzProtocolEncoderSMC5326; - -extern const SubGhzProtocolDecoder subghz_protocol_smc5326_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_smc5326_encoder; -extern const SubGhzProtocol subghz_protocol_smc5326; - -/** - * Allocate SubGhzProtocolEncoderSMC5326. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderSMC5326* pointer to a SubGhzProtocolEncoderSMC5326 instance - */ -void* subghz_protocol_encoder_smc5326_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderSMC5326. - * @param context Pointer to a SubGhzProtocolEncoderSMC5326 instance - */ -void subghz_protocol_encoder_smc5326_free(void* context); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderSMC5326 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_smc5326_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderSMC5326 instance - */ -void subghz_protocol_encoder_smc5326_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderSMC5326 instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_smc5326_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderSMC5326. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderSMC5326* pointer to a SubGhzProtocolDecoderSMC5326 instance - */ -void* subghz_protocol_decoder_smc5326_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderSMC5326. - * @param context Pointer to a SubGhzProtocolDecoderSMC5326 instance - */ -void subghz_protocol_decoder_smc5326_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderSMC5326. - * @param context Pointer to a SubGhzProtocolDecoderSMC5326 instance - */ -void subghz_protocol_decoder_smc5326_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderSMC5326 instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_smc5326_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderSMC5326 instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_smc5326_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderSMC5326. - * @param context Pointer to a SubGhzProtocolDecoderSMC5326 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_smc5326_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderSMC5326. - * @param context Pointer to a SubGhzProtocolDecoderSMC5326 instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_smc5326_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderSMC5326 instance - * @param output Resulting text - */ -void subghz_protocol_decoder_smc5326_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/somfy_keytis.c b/applications/main/subghz/protocols/somfy_keytis.c deleted file mode 100644 index ab9202cc3..000000000 --- a/applications/main/subghz/protocols/somfy_keytis.c +++ /dev/null @@ -1,797 +0,0 @@ -#include "somfy_keytis.h" -#include - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolSomfyKeytis" - -static const SubGhzBlockConst subghz_protocol_somfy_keytis_const = { - .te_short = 640, - .te_long = 1280, - .te_delta = 250, - .min_count_bit_for_found = 80, -}; - -struct SubGhzProtocolDecoderSomfyKeytis { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - - uint16_t header_count; - ManchesterState manchester_saved_state; - uint32_t press_duration_counter; -}; - -struct SubGhzProtocolEncoderSomfyKeytis { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - SomfyKeytisDecoderStepReset = 0, - SomfyKeytisDecoderStepCheckPreambula, - SomfyKeytisDecoderStepFoundPreambula, - SomfyKeytisDecoderStepStartDecode, - SomfyKeytisDecoderStepDecoderData, -} SomfyKeytisDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_somfy_keytis_decoder = { - .alloc = subghz_protocol_decoder_somfy_keytis_alloc, - .free = subghz_protocol_decoder_somfy_keytis_free, - - .feed = subghz_protocol_decoder_somfy_keytis_feed, - .reset = subghz_protocol_decoder_somfy_keytis_reset, - - .get_hash_data = subghz_protocol_decoder_somfy_keytis_get_hash_data, - .serialize = subghz_protocol_decoder_somfy_keytis_serialize, - .deserialize = subghz_protocol_decoder_somfy_keytis_deserialize, - .get_string = subghz_protocol_decoder_somfy_keytis_get_string, -}; - -const SubGhzProtocol subghz_protocol_somfy_keytis = { - .name = SUBGHZ_PROTOCOL_SOMFY_KEYTIS_NAME, - .type = SubGhzProtocolTypeDynamic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_868 | SubGhzProtocolFlag_AM | - SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_somfy_keytis_decoder, - .encoder = &subghz_protocol_somfy_keytis_encoder, -}; - -const SubGhzProtocolEncoder subghz_protocol_somfy_keytis_encoder = { - .alloc = subghz_protocol_encoder_somfy_keytis_alloc, - .free = subghz_protocol_encoder_somfy_keytis_free, - - .deserialize = subghz_protocol_encoder_somfy_keytis_deserialize, - .stop = subghz_protocol_encoder_somfy_keytis_stop, - .yield = subghz_protocol_encoder_somfy_keytis_yield, -}; - -void* subghz_protocol_encoder_somfy_keytis_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderSomfyKeytis* instance = malloc(sizeof(SubGhzProtocolEncoderSomfyKeytis)); - - instance->base.protocol = &subghz_protocol_somfy_keytis; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 512; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - - return instance; -} - -void* subghz_protocol_decoder_somfy_keytis_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderSomfyKeytis* instance = malloc(sizeof(SubGhzProtocolDecoderSomfyKeytis)); - instance->base.protocol = &subghz_protocol_somfy_keytis; - instance->generic.protocol_name = instance->base.protocol->name; - - return instance; -} - -void subghz_protocol_encoder_somfy_keytis_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderSomfyKeytis* instance = context; - free(instance->encoder.upload); - free(instance); -} - -void subghz_protocol_decoder_somfy_keytis_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderSomfyKeytis* instance = context; - free(instance); -} - -void subghz_protocol_decoder_somfy_keytis_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderSomfyKeytis* instance = context; - instance->decoder.parser_step = SomfyKeytisDecoderStepReset; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventReset, - &instance->manchester_saved_state, - NULL); -} - -static bool - subghz_protocol_somfy_keytis_gen_data(SubGhzProtocolEncoderSomfyKeytis* instance, uint8_t btn) { - UNUSED(btn); - uint64_t data = instance->generic.data ^ (instance->generic.data >> 8); - instance->generic.btn = (data >> 48) & 0xF; - instance->generic.cnt = (data >> 24) & 0xFFFF; - instance->generic.serial = data & 0xFFFFFF; - - if(instance->generic.cnt < 0xFFFF) { - instance->generic.cnt++; - } else if(instance->generic.cnt >= 0xFFFF) { - instance->generic.cnt = 0; - } - - uint8_t frame[10]; - frame[0] = (0xA << 4) | instance->generic.btn; - frame[1] = 0xF << 4; - frame[2] = instance->generic.cnt >> 8; - frame[3] = instance->generic.cnt; - frame[4] = instance->generic.serial >> 16; - frame[5] = instance->generic.serial >> 8; - frame[6] = instance->generic.serial; - frame[7] = 0xC4; - frame[8] = 0x00; - frame[9] = 0x19; - - uint8_t checksum = 0; - for(uint8_t i = 0; i < 7; i++) { - checksum = checksum ^ frame[i] ^ (frame[i] >> 4); - } - checksum &= 0xF; - - frame[1] |= checksum; - - for(uint8_t i = 1; i < 7; i++) { - frame[i] ^= frame[i - 1]; - } - data = 0; - for(uint8_t i = 0; i < 7; ++i) { - data <<= 8; - data |= frame[i]; - } - instance->generic.data = data; - data = 0; - for(uint8_t i = 7; i < 10; ++i) { - data <<= 8; - data |= frame[i]; - } - instance->generic.data_2 = data; - return true; -} - -bool subghz_protocol_somfy_keytis_create_data( - void* context, - FlipperFormat* flipper_format, - uint32_t serial, - uint8_t btn, - uint16_t cnt, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolEncoderSomfyKeytis* instance = context; - instance->generic.serial = serial; - instance->generic.cnt = cnt; - instance->generic.data_count_bit = 80; - bool res = subghz_protocol_somfy_keytis_gen_data(instance, btn); - if(res) { - res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); - } - return res; -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderKeeloq instance - * @return true On success - */ -static bool subghz_protocol_encoder_somfy_keytis_get_upload( - SubGhzProtocolEncoderSomfyKeytis* instance, - uint8_t btn) { - furi_assert(instance); - - //gen new key - if(subghz_protocol_somfy_keytis_gen_data(instance, btn)) { - //ToDo if you need to add a callback to automatically update the data on the display - } else { - return false; - } - - size_t index = 0; - - //Send header - //Wake up - instance->encoder.upload[index++] = level_duration_make(true, (uint32_t)9415); // 1 - instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)89565); // 0 - //Hardware sync - for(uint8_t i = 0; i < 12; ++i) { - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_keytis_const.te_short * 4); // 1 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_keytis_const.te_short * 4); // 0 - } - //Software sync - instance->encoder.upload[index++] = level_duration_make(true, (uint32_t)4550); // 1 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 0 - - //Send key data MSB manchester - - for(uint8_t i = instance->generic.data_count_bit - 24; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - if(instance->encoder.upload[index - 1].level == LEVEL_DURATION_LEVEL_LOW) { - instance->encoder.upload[index - 1].duration *= 2; // 00 - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 1 - } else { - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 0 - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 1 - } - - } else { - if(instance->encoder.upload[index - 1].level == LEVEL_DURATION_LEVEL_HIGH) { - instance->encoder.upload[index - 1].duration *= 2; // 11 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 0 - } else { - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 1 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 0 - } - } - } - - for(uint8_t i = 24; i > 0; i--) { - if(bit_read(instance->generic.data_2, i - 1)) { - if(instance->encoder.upload[index - 1].level == LEVEL_DURATION_LEVEL_LOW) { - instance->encoder.upload[index - 1].duration *= 2; // 00 - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 1 - } else { - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 0 - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 1 - } - - } else { - if(instance->encoder.upload[index - 1].level == LEVEL_DURATION_LEVEL_HIGH) { - instance->encoder.upload[index - 1].duration *= 2; // 11 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 0 - } else { - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 1 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 0 - } - } - } - - //Inter-frame silence - if(instance->encoder.upload[index - 1].level == LEVEL_DURATION_LEVEL_LOW) { - instance->encoder.upload[index - 1].duration += - (uint32_t)subghz_protocol_somfy_keytis_const.te_short * 3; - } else { - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_somfy_keytis_const.te_short * 3); - } - - for(uint8_t i = 0; i < 2; ++i) { - //Hardware sync - for(uint8_t i = 0; i < 6; ++i) { - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_keytis_const.te_short * 4); // 1 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_keytis_const.te_short * 4); // 0 - } - //Software sync - instance->encoder.upload[index++] = level_duration_make(true, (uint32_t)4550); // 1 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 0 - - //Send key data MSB manchester - - for(uint8_t i = instance->generic.data_count_bit - 24; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - if(instance->encoder.upload[index - 1].level == LEVEL_DURATION_LEVEL_LOW) { - instance->encoder.upload[index - 1].duration *= 2; // 00 - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 1 - } else { - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 0 - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 1 - } - - } else { - if(instance->encoder.upload[index - 1].level == LEVEL_DURATION_LEVEL_HIGH) { - instance->encoder.upload[index - 1].duration *= 2; // 11 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 0 - } else { - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 1 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 0 - } - } - } - - for(uint8_t i = 24; i > 0; i--) { - if(bit_read(instance->generic.data_2, i - 1)) { - if(instance->encoder.upload[index - 1].level == LEVEL_DURATION_LEVEL_LOW) { - instance->encoder.upload[index - 1].duration *= 2; // 00 - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 1 - } else { - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 0 - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 1 - } - - } else { - if(instance->encoder.upload[index - 1].level == LEVEL_DURATION_LEVEL_HIGH) { - instance->encoder.upload[index - 1].duration *= 2; // 11 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 0 - } else { - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 1 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_keytis_const.te_short); // 0 - } - } - } - //Inter-frame silence - if(instance->encoder.upload[index - 1].level == LEVEL_DURATION_LEVEL_LOW) { - instance->encoder.upload[index - 1].duration += - (uint32_t)subghz_protocol_somfy_keytis_const.te_short * 3; - } else { - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_keytis_const.te_short * 3); - } - } - - //Inter-frame silence - instance->encoder.upload[index - 1].duration += - (uint32_t)30415 - (uint32_t)subghz_protocol_somfy_keytis_const.te_short * 3; - - size_t size_upload = index; - - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - return true; -} - -bool subghz_protocol_encoder_somfy_keytis_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderSomfyKeytis* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - subghz_protocol_encoder_somfy_keytis_get_upload(instance, instance->generic.btn); - - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - uint8_t key_data[sizeof(uint64_t)] = {0}; - for(size_t i = 0; i < sizeof(uint64_t); i++) { - key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data >> i * 8) & 0xFF; - } - if(!flipper_format_update_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Unable to add Key"); - break; - } - - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_somfy_keytis_stop(void* context) { - SubGhzProtocolEncoderSomfyKeytis* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_somfy_keytis_yield(void* context) { - SubGhzProtocolEncoderSomfyKeytis* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -/** - * Сhecksum calculation. - * @param data Вata for checksum calculation - * @return CRC - */ -static uint8_t subghz_protocol_somfy_keytis_crc(uint64_t data) { - uint8_t crc = 0; - data &= 0xFFF0FFFFFFFFFF; - for(uint8_t i = 0; i < 56; i += 8) { - crc = crc ^ data >> i ^ (data >> (i + 4)); - } - return crc & 0xf; -} - -void subghz_protocol_decoder_somfy_keytis_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderSomfyKeytis* instance = context; - - ManchesterEvent event = ManchesterEventReset; - switch(instance->decoder.parser_step) { - case SomfyKeytisDecoderStepReset: - if((level) && DURATION_DIFF(duration, subghz_protocol_somfy_keytis_const.te_short * 4) < - subghz_protocol_somfy_keytis_const.te_delta * 4) { - instance->decoder.parser_step = SomfyKeytisDecoderStepFoundPreambula; - instance->header_count++; - } - break; - case SomfyKeytisDecoderStepFoundPreambula: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_somfy_keytis_const.te_short * 4) < - subghz_protocol_somfy_keytis_const.te_delta * 4)) { - instance->decoder.parser_step = SomfyKeytisDecoderStepCheckPreambula; - } else { - instance->header_count = 0; - instance->decoder.parser_step = SomfyKeytisDecoderStepReset; - } - break; - case SomfyKeytisDecoderStepCheckPreambula: - if(level) { - if(DURATION_DIFF(duration, subghz_protocol_somfy_keytis_const.te_short * 4) < - subghz_protocol_somfy_keytis_const.te_delta * 4) { - instance->decoder.parser_step = SomfyKeytisDecoderStepFoundPreambula; - instance->header_count++; - } else if( - (instance->header_count > 1) && - (DURATION_DIFF(duration, subghz_protocol_somfy_keytis_const.te_short * 7) < - subghz_protocol_somfy_keytis_const.te_delta * 4)) { - instance->decoder.parser_step = SomfyKeytisDecoderStepDecoderData; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->press_duration_counter = 0; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventReset, - &instance->manchester_saved_state, - NULL); - manchester_advance( - instance->manchester_saved_state, - ManchesterEventLongHigh, - &instance->manchester_saved_state, - NULL); - } - } - - break; - - case SomfyKeytisDecoderStepDecoderData: - if(!level) { - if(DURATION_DIFF(duration, subghz_protocol_somfy_keytis_const.te_short) < - subghz_protocol_somfy_keytis_const.te_delta) { - event = ManchesterEventShortLow; - } else if( - DURATION_DIFF(duration, subghz_protocol_somfy_keytis_const.te_long) < - subghz_protocol_somfy_keytis_const.te_delta) { - event = ManchesterEventLongLow; - } else if( - duration >= (subghz_protocol_somfy_keytis_const.te_long + - subghz_protocol_somfy_keytis_const.te_delta)) { - if(instance->decoder.decode_count_bit == - subghz_protocol_somfy_keytis_const.min_count_bit_for_found) { - //check crc - uint64_t data_tmp = instance->generic.data ^ (instance->generic.data >> 8); - if(((data_tmp >> 40) & 0xF) == subghz_protocol_somfy_keytis_crc(data_tmp)) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventReset, - &instance->manchester_saved_state, - NULL); - manchester_advance( - instance->manchester_saved_state, - ManchesterEventLongHigh, - &instance->manchester_saved_state, - NULL); - instance->decoder.parser_step = SomfyKeytisDecoderStepReset; - } else { - instance->decoder.parser_step = SomfyKeytisDecoderStepReset; - } - } else { - if(DURATION_DIFF(duration, subghz_protocol_somfy_keytis_const.te_short) < - subghz_protocol_somfy_keytis_const.te_delta) { - event = ManchesterEventShortHigh; - } else if( - DURATION_DIFF(duration, subghz_protocol_somfy_keytis_const.te_long) < - subghz_protocol_somfy_keytis_const.te_delta) { - event = ManchesterEventLongHigh; - } else { - instance->decoder.parser_step = SomfyKeytisDecoderStepReset; - } - } - if(event != ManchesterEventReset) { - bool data; - bool data_ok = manchester_advance( - instance->manchester_saved_state, event, &instance->manchester_saved_state, &data); - - if(data_ok) { - if(instance->decoder.decode_count_bit < 56) { - instance->decoder.decode_data = (instance->decoder.decode_data << 1) | data; - } else { - instance->press_duration_counter = (instance->press_duration_counter << 1) | - data; - } - - instance->decoder.decode_count_bit++; - } - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - */ -static void subghz_protocol_somfy_keytis_check_remote_controller(SubGhzBlockGeneric* instance) { - //https://pushstack.wordpress.com/somfy-rts-protocol/ - /* - * 604 us - * / - * | 2416us | 2416us | 2416us | 2416us | 4550 us | | - * - * +--------+ +--------+ +---...---+ - * + +--------+ +--------+ +--+XXXX...XXX+ - * - * | hw. sync. | soft. | | - * | | sync. | data | - * - * - * encrypt | decrypt - * - * package 80 bit pdc key btn crc cnt serial - * - * 0xA453537C4B9855 C40019 => 0xA 4 F 7 002F 37D3CD - * 0xA453537C4B9855 C80026 => 0xA 4 F 7 002F 37D3CD - * 0xA453537C4B9855 CC0033 => 0xA 4 F 7 002F 37D3CD - * 0xA453537C4B9855 D00049 => 0xA 4 F 7 002F 37D3CD - * 0xA453537C4B9855 D4005C => 0xA 4 F 7 002F 37D3CD - * 0xA453537C4B9855 D80063 => 0xA 4 F 7 002F 37D3CD - * 0xA453537C4B9855 DC0076 => 0xA 4 F 7 002F 37D3CD - * 0xA453537C4B9855 E00086 => 0xA 4 F 7 002F 37D3CD - * 0xA453537C4B9855 E40093 => 0xA 4 F 7 002F 37D3CD - * 0xA453537C4B9855 E800AC => 0xA 4 F 7 002F 37D3CD - * 0xA453537C4B9855 EC00B9 => 0xA 4 F 7 002F 37D3CD - * 0xA453537C4B9855 F000C3 => 0xA 4 F 7 002F 37D3CD - * 0xA453537C4B9855 F400D6 => 0xA 4 F 7 002F 37D3CD - * 0xA453537C4B9855 F800E9 => 0xA 4 F 7 002F 37D3CD - * 0xA453537C4B9855 FC00FC => 0xA 4 F 7 002F 37D3CD - * 0xA453537C4B9855 FC0102 => 0xA 4 F 7 002F 37D3CD - * 0xA453537C4B9855 FC0113 => 0xA 4 F 7 002F 37D3CD - * 0xA453537C4B9855 FC0120 => 0xA 4 F 7 002F 37D3CD - * .......... - * 0xA453537C4B9855 FC048F => 0xA 4 F 7 002F 37D3CD - * - * Pdc: "Press Duration Counter" the total delay of the button is sent 72 parcels, - * pdc cnt4b cnt8b pdc_crc - * C40019 => 11 0001 00 0000 00000001 1001 - * C80026 => 11 0010 00 0000 00000010 0110 - * CC0033 => 11 0011 00 0000 00000011 0011 - * D00049 => 11 0100 00 0000 00000100 1001 - * D4005C => 11 0101 00 0000 00000101 1100 - * D80063 => 11 0110 00 0000 00000110 0011 - * DC0076 => 11 0111 00 0000 00000111 0110 - * E00086 => 11 1000 00 0000 00001000 0110 - * E40093 => 11 1001 00 0000 00001001 0011 - * E800AC => 11 1010 00 0000 00001010 1100 - * EC00B9 => 11 1011 00 0000 00001011 1001 - * F000C3 => 11 1100 00 0000 00001100 0011 - * F400D6 => 11 1101 00 0000 00001101 0110 - * F800E9 => 11 1110 00 0000 00001110 1001 - * FC00FC => 11 1111 00 0000 00001111 1100 - * FC0102 => 11 1111 00 0000 00010000 0010 - * FC0113 => 11 1111 00 0000 00010001 0011 - * FC0120 => 11 1111 00 0000 00010010 0000 - * - * Cnt4b: 4-bit counter changes from 1 to 15 then always equals 15 - * Cnt8b: 8-bit counter changes from 1 to 72 (0x48) - * Ppdc_crc: - * uint8_t crc=0; - * for(i=4; i<24; i+=4){ - * crc ^=(pdc>>i); - * } - * return crc; - * example: crc = 1^0^0^4^C = 9 - * 11, 00, 0000: const - * - * Key: “Encryption Key”, Most significant 4-bit are always 0xA, Least Significant bits is - * a linear counter. In the Smoove Origin this counter is increased together with the - * rolling code. But leaving this on a constant value also works. Gerardwr notes that - * for some other types of remotes the MSB is not constant. - * Btn: 4-bit Control codes, this indicates the button that is pressed - * CRC: 4-bit Checksum. - * Ctn: 16-bit rolling code (big-endian) increased with every button press. - * Serial: 24-bit identifier of sending device (little-endian) - * - * - * Decrypt - * - * uint8_t frame[7]; - * for (i=1; i < 7; i++) { - * frame[i] = frame[i] ^ frame[i-1]; - * } - * or - * uint64 Decrypt = frame ^ (frame>>8); - * - * CRC - * - * uint8_t frame[7]; - * for (i=0; i < 7; i++) { - * crc = crc ^ frame[i] ^ (frame[i] >> 4); - * } - * crc = crc & 0xf; - * - */ - - uint64_t data = instance->data ^ (instance->data >> 8); - instance->btn = (data >> 48) & 0xF; - instance->cnt = (data >> 24) & 0xFFFF; - instance->serial = data & 0xFFFFFF; -} - -/** - * Get button name. - * @param btn Button number, 4 bit - */ -static const char* subghz_protocol_somfy_keytis_get_name_button(uint8_t btn) { - const char* name_btn[0x10] = { - "Unknown", - "0x01", - "0x02", - "Prog", - "Key_1", - "0x05", - "0x06", - "0x07", - "0x08", - "0x09", - "0x0A", - "0x0B", - "0x0C", - "0x0D", - "0x0E", - "0x0F"}; - return btn <= 0xf ? name_btn[btn] : name_btn[0]; -} - -uint8_t subghz_protocol_decoder_somfy_keytis_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderSomfyKeytis* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_somfy_keytis_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderSomfyKeytis* instance = context; - bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); - if(res && !flipper_format_write_uint32( - flipper_format, "Duration_Counter", &instance->press_duration_counter, 1)) { - FURI_LOG_E(TAG, "Unable to add Duration_Counter"); - res = false; - } - return res; -} - -bool subghz_protocol_decoder_somfy_keytis_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderSomfyKeytis* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_somfy_keytis_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - if(!flipper_format_read_uint32( - flipper_format, - "Duration_Counter", - (uint32_t*)&instance->press_duration_counter, - 1)) { - FURI_LOG_E(TAG, "Missing Duration_Counter"); - break; - } - res = true; - } while(false); - - return res; -} - -void subghz_protocol_decoder_somfy_keytis_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderSomfyKeytis* instance = context; - - subghz_protocol_somfy_keytis_check_remote_controller(&instance->generic); - - furi_string_cat_printf( - output, - "%s %db\r\n" - "%lX%08lX%06lX\r\n" - "Sn:0x%06lX \r\n" - "Cnt:0x%04lX\r\n" - "Btn:%s\r\n", - - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)instance->generic.data, - instance->press_duration_counter, - instance->generic.serial, - instance->generic.cnt, - subghz_protocol_somfy_keytis_get_name_button(instance->generic.btn)); -} diff --git a/applications/main/subghz/protocols/somfy_keytis.h b/applications/main/subghz/protocols/somfy_keytis.h deleted file mode 100644 index b08da3641..000000000 --- a/applications/main/subghz/protocols/somfy_keytis.h +++ /dev/null @@ -1,125 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_SOMFY_KEYTIS_NAME "Somfy Keytis" - -typedef struct SubGhzProtocolDecoderSomfyKeytis SubGhzProtocolDecoderSomfyKeytis; -typedef struct SubGhzProtocolEncoderSomfyKeytis SubGhzProtocolEncoderSomfyKeytis; - -extern const SubGhzProtocolDecoder subghz_protocol_somfy_keytis_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_somfy_keytis_encoder; -extern const SubGhzProtocol subghz_protocol_somfy_keytis; - -/** - * Allocate SubGhzProtocolEncoderSomfyKeytis. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderSomfyKeytis* pointer to a SubGhzProtocolEncoderSomfyKeytis instance - */ -void* subghz_protocol_encoder_somfy_keytis_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderSomfyKeytis. - * @param context Pointer to a SubGhzProtocolEncoderSomfyKeytis instance - */ -void subghz_protocol_encoder_somfy_keytis_free(void* context); - -/** - * Key generation from simple data. - * @param context Pointer to a SubGhzProtocolEncoderSomfyKeytis instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param serial Serial number, 24 bit - * @param btn Button number, 8 bit - * @param cnt Counter value, 16 bit - * @param preset Modulation, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_somfy_keytis_create_data( - void* context, - FlipperFormat* flipper_format, - uint32_t serial, - uint8_t btn, - uint16_t cnt, - SubGhzRadioPreset* preset); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderSomfyKeytis instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_somfy_keytis_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderSomfyKeytis instance - */ -void subghz_protocol_encoder_somfy_keytis_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderSomfyKeytis instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_somfy_keytis_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderSomfyKeytis. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderSomfyKeytis* pointer to a SubGhzProtocolDecoderSomfyKeytis instance - */ -void* subghz_protocol_decoder_somfy_keytis_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderSomfyKeytis. - * @param context Pointer to a SubGhzProtocolDecoderSomfyKeytis instance - */ -void subghz_protocol_decoder_somfy_keytis_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderSomfyKeytis. - * @param context Pointer to a SubGhzProtocolDecoderSomfyKeytis instance - */ -void subghz_protocol_decoder_somfy_keytis_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderSomfyKeytis instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_somfy_keytis_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderSomfyKeytis instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_somfy_keytis_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderSomfyKeytis. - * @param context Pointer to a SubGhzProtocolDecoderSomfyKeytis instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_somfy_keytis_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderSomfyKeytis. - * @param context Pointer to a SubGhzProtocolDecoderSomfyKeytis instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_somfy_keytis_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderSomfyKeytis instance - * @param output Resulting text - */ -void subghz_protocol_decoder_somfy_keytis_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/somfy_telis.c b/applications/main/subghz/protocols/somfy_telis.c deleted file mode 100644 index 96997c581..000000000 --- a/applications/main/subghz/protocols/somfy_telis.c +++ /dev/null @@ -1,663 +0,0 @@ -#include "somfy_telis.h" -#include - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolSomfyTelis" - -static const SubGhzBlockConst subghz_protocol_somfy_telis_const = { - .te_short = 640, - .te_long = 1280, - .te_delta = 250, - .min_count_bit_for_found = 56, -}; - -struct SubGhzProtocolDecoderSomfyTelis { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - - uint16_t header_count; - ManchesterState manchester_saved_state; -}; - -struct SubGhzProtocolEncoderSomfyTelis { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; -}; - -typedef enum { - SomfyTelisDecoderStepReset = 0, - SomfyTelisDecoderStepCheckPreambula, - SomfyTelisDecoderStepFoundPreambula, - SomfyTelisDecoderStepStartDecode, - SomfyTelisDecoderStepDecoderData, -} SomfyTelisDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_somfy_telis_decoder = { - .alloc = subghz_protocol_decoder_somfy_telis_alloc, - .free = subghz_protocol_decoder_somfy_telis_free, - - .feed = subghz_protocol_decoder_somfy_telis_feed, - .reset = subghz_protocol_decoder_somfy_telis_reset, - - .get_hash_data = subghz_protocol_decoder_somfy_telis_get_hash_data, - .serialize = subghz_protocol_decoder_somfy_telis_serialize, - .deserialize = subghz_protocol_decoder_somfy_telis_deserialize, - .get_string = subghz_protocol_decoder_somfy_telis_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_somfy_telis_encoder = { - .alloc = subghz_protocol_encoder_somfy_telis_alloc, - .free = subghz_protocol_encoder_somfy_telis_free, - - .deserialize = subghz_protocol_encoder_somfy_telis_deserialize, - .stop = subghz_protocol_encoder_somfy_telis_stop, - .yield = subghz_protocol_encoder_somfy_telis_yield, -}; - -const SubGhzProtocol subghz_protocol_somfy_telis = { - .name = SUBGHZ_PROTOCOL_SOMFY_TELIS_NAME, - .type = SubGhzProtocolTypeDynamic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_868 | SubGhzProtocolFlag_AM | - SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_somfy_telis_decoder, - .encoder = &subghz_protocol_somfy_telis_encoder, -}; - -void* subghz_protocol_encoder_somfy_telis_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolEncoderSomfyTelis* instance = malloc(sizeof(SubGhzProtocolEncoderSomfyTelis)); - - instance->base.protocol = &subghz_protocol_somfy_telis; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 512; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - - return instance; -} - -void subghz_protocol_encoder_somfy_telis_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderSomfyTelis* instance = context; - free(instance->encoder.upload); - free(instance); -} - -static bool - subghz_protocol_somfy_telis_gen_data(SubGhzProtocolEncoderSomfyTelis* instance, uint8_t btn) { - UNUSED(btn); - uint64_t data = instance->generic.data ^ (instance->generic.data >> 8); - instance->generic.btn = (data >> 44) & 0xF; // ctrl - instance->generic.cnt = (data >> 24) & 0xFFFF; // rolling code - instance->generic.serial = data & 0xFFFFFF; // address - - if(instance->generic.cnt < 0xFFFF) { - instance->generic.cnt++; - } else if(instance->generic.cnt >= 0xFFFF) { - instance->generic.cnt = 0; - } - - uint8_t frame[7]; - frame[0] = data >> 48; - frame[1] = instance->generic.btn << 4; - frame[2] = instance->generic.cnt >> 8; - frame[3] = instance->generic.cnt; - frame[4] = instance->generic.serial >> 16; - frame[5] = instance->generic.serial >> 8; - frame[6] = instance->generic.serial; - - uint8_t checksum = 0; - for(uint8_t i = 0; i < 7; i++) { - checksum = checksum ^ frame[i] ^ (frame[i] >> 4); - } - checksum &= 0xF; - - frame[1] |= checksum; - - for(uint8_t i = 1; i < 7; i++) { - frame[i] ^= frame[i - 1]; - } - data = 0; - for(uint8_t i = 0; i < 7; ++i) { - data <<= 8; - data |= frame[i]; - } - instance->generic.data = data; - return true; -} - -bool subghz_protocol_somfy_telis_create_data( - void* context, - FlipperFormat* flipper_format, - uint32_t serial, - uint8_t btn, - uint16_t cnt, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolEncoderSomfyTelis* instance = context; - instance->generic.serial = serial; - instance->generic.cnt = cnt; - instance->generic.data_count_bit = 56; - bool res = subghz_protocol_somfy_telis_gen_data(instance, btn); - if(res) { - res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); - } - return res; -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderKeeloq instance - * @return true On success - */ -static bool subghz_protocol_encoder_somfy_telis_get_upload( - SubGhzProtocolEncoderSomfyTelis* instance, - uint8_t btn) { - furi_assert(instance); - - //gen new key - if(subghz_protocol_somfy_telis_gen_data(instance, btn)) { - //ToDo if you need to add a callback to automatically update the data on the display - } else { - return false; - } - - size_t index = 0; - - //Send header - //Wake up - instance->encoder.upload[index++] = level_duration_make(true, (uint32_t)9415); // 1 - instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)89565); // 0 - //Hardware sync - for(uint8_t i = 0; i < 2; ++i) { - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_telis_const.te_short * 4); // 1 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_telis_const.te_short * 4); // 0 - } - //Software sync - instance->encoder.upload[index++] = level_duration_make(true, (uint32_t)4550); // 1 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_somfy_telis_const.te_short); // 0 - - //Send key data MSB manchester - - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - if(instance->encoder.upload[index - 1].level == LEVEL_DURATION_LEVEL_LOW) { - instance->encoder.upload[index - 1].duration *= 2; // 00 - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_telis_const.te_short); // 1 - } else { - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_telis_const.te_short); // 0 - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_telis_const.te_short); // 1 - } - - } else { - if(instance->encoder.upload[index - 1].level == LEVEL_DURATION_LEVEL_HIGH) { - instance->encoder.upload[index - 1].duration *= 2; // 11 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_telis_const.te_short); // 0 - } else { - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_telis_const.te_short); // 1 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_telis_const.te_short); // 0 - } - } - } - - //Inter-frame silence - if(instance->encoder.upload[index - 1].level == LEVEL_DURATION_LEVEL_LOW) { - instance->encoder.upload[index - 1].duration += (uint32_t)30415; - } else { - instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)30415); - } - - //Retransmission - for(uint8_t i = 0; i < 2; i++) { - //Hardware sync - for(uint8_t i = 0; i < 7; ++i) { - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_telis_const.te_short * 4); // 1 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_telis_const.te_short * 4); // 0 - } - //Software sync - instance->encoder.upload[index++] = level_duration_make(true, (uint32_t)4550); // 1 - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_somfy_telis_const.te_short); // 0 - - //Send key data MSB manchester - - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - if(instance->encoder.upload[index - 1].level == LEVEL_DURATION_LEVEL_LOW) { - instance->encoder.upload[index - 1].duration *= 2; // 00 - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_telis_const.te_short); // 1 - } else { - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_telis_const.te_short); // 0 - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_telis_const.te_short); // 1 - } - - } else { - if(instance->encoder.upload[index - 1].level == LEVEL_DURATION_LEVEL_HIGH) { - instance->encoder.upload[index - 1].duration *= 2; // 11 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_telis_const.te_short); // 0 - } else { - instance->encoder.upload[index++] = level_duration_make( - true, (uint32_t)subghz_protocol_somfy_telis_const.te_short); // 1 - instance->encoder.upload[index++] = level_duration_make( - false, (uint32_t)subghz_protocol_somfy_telis_const.te_short); // 0 - } - } - } - - //Inter-frame silence - if(instance->encoder.upload[index - 1].level == LEVEL_DURATION_LEVEL_LOW) { - instance->encoder.upload[index - 1].duration += (uint32_t)30415; - } else { - instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)30415); - } - } - - size_t size_upload = index; - - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - return true; -} - -bool subghz_protocol_encoder_somfy_telis_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderSomfyTelis* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - subghz_protocol_encoder_somfy_telis_get_upload(instance, instance->generic.btn); - - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - uint8_t key_data[sizeof(uint64_t)] = {0}; - for(size_t i = 0; i < sizeof(uint64_t); i++) { - key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data >> i * 8) & 0xFF; - } - if(!flipper_format_update_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Unable to add Key"); - break; - } - - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_somfy_telis_stop(void* context) { - SubGhzProtocolEncoderSomfyTelis* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_somfy_telis_yield(void* context) { - SubGhzProtocolEncoderSomfyTelis* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_somfy_telis_alloc(SubGhzEnvironment* environment) { - UNUSED(environment); - SubGhzProtocolDecoderSomfyTelis* instance = malloc(sizeof(SubGhzProtocolDecoderSomfyTelis)); - instance->base.protocol = &subghz_protocol_somfy_telis; - instance->generic.protocol_name = instance->base.protocol->name; - - return instance; -} - -void subghz_protocol_decoder_somfy_telis_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderSomfyTelis* instance = context; - free(instance); -} - -void subghz_protocol_decoder_somfy_telis_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderSomfyTelis* instance = context; - instance->decoder.parser_step = SomfyTelisDecoderStepReset; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventReset, - &instance->manchester_saved_state, - NULL); -} - -/** - * Сhecksum calculation. - * @param data Вata for checksum calculation - * @return CRC - */ -static uint8_t subghz_protocol_somfy_telis_crc(uint64_t data) { - uint8_t crc = 0; - data &= 0xFFF0FFFFFFFFFF; - for(uint8_t i = 0; i < 56; i += 8) { - crc = crc ^ data >> i ^ (data >> (i + 4)); - } - return crc & 0xf; -} - -void subghz_protocol_decoder_somfy_telis_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderSomfyTelis* instance = context; - - ManchesterEvent event = ManchesterEventReset; - switch(instance->decoder.parser_step) { - case SomfyTelisDecoderStepReset: - if((level) && DURATION_DIFF(duration, subghz_protocol_somfy_telis_const.te_short * 4) < - subghz_protocol_somfy_telis_const.te_delta * 4) { - instance->decoder.parser_step = SomfyTelisDecoderStepFoundPreambula; - instance->header_count++; - } - break; - case SomfyTelisDecoderStepFoundPreambula: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_somfy_telis_const.te_short * 4) < - subghz_protocol_somfy_telis_const.te_delta * 4)) { - instance->decoder.parser_step = SomfyTelisDecoderStepCheckPreambula; - } else { - instance->header_count = 0; - instance->decoder.parser_step = SomfyTelisDecoderStepReset; - } - break; - case SomfyTelisDecoderStepCheckPreambula: - if(level) { - if(DURATION_DIFF(duration, subghz_protocol_somfy_telis_const.te_short * 4) < - subghz_protocol_somfy_telis_const.te_delta * 4) { - instance->decoder.parser_step = SomfyTelisDecoderStepFoundPreambula; - instance->header_count++; - } else if( - (instance->header_count > 1) && - (DURATION_DIFF(duration, subghz_protocol_somfy_telis_const.te_short * 7) < - subghz_protocol_somfy_telis_const.te_delta * 4)) { - instance->decoder.parser_step = SomfyTelisDecoderStepDecoderData; - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->header_count = 0; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventReset, - &instance->manchester_saved_state, - NULL); - manchester_advance( - instance->manchester_saved_state, - ManchesterEventLongHigh, - &instance->manchester_saved_state, - NULL); - } - } - - break; - - case SomfyTelisDecoderStepDecoderData: - if(!level) { - if(DURATION_DIFF(duration, subghz_protocol_somfy_telis_const.te_short) < - subghz_protocol_somfy_telis_const.te_delta) { - event = ManchesterEventShortLow; - } else if( - DURATION_DIFF(duration, subghz_protocol_somfy_telis_const.te_long) < - subghz_protocol_somfy_telis_const.te_delta) { - event = ManchesterEventLongLow; - } else if( - duration >= (subghz_protocol_somfy_telis_const.te_long + - subghz_protocol_somfy_telis_const.te_delta)) { - if(instance->decoder.decode_count_bit == - subghz_protocol_somfy_telis_const.min_count_bit_for_found) { - //check crc - uint64_t data_tmp = instance->decoder.decode_data ^ - (instance->decoder.decode_data >> 8); - if(((data_tmp >> 40) & 0xF) == subghz_protocol_somfy_telis_crc(data_tmp)) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - manchester_advance( - instance->manchester_saved_state, - ManchesterEventReset, - &instance->manchester_saved_state, - NULL); - manchester_advance( - instance->manchester_saved_state, - ManchesterEventLongHigh, - &instance->manchester_saved_state, - NULL); - instance->decoder.parser_step = SomfyTelisDecoderStepReset; - } else { - instance->decoder.parser_step = SomfyTelisDecoderStepReset; - } - } else { - if(DURATION_DIFF(duration, subghz_protocol_somfy_telis_const.te_short) < - subghz_protocol_somfy_telis_const.te_delta) { - event = ManchesterEventShortHigh; - } else if( - DURATION_DIFF(duration, subghz_protocol_somfy_telis_const.te_long) < - subghz_protocol_somfy_telis_const.te_delta) { - event = ManchesterEventLongHigh; - } else { - instance->decoder.parser_step = SomfyTelisDecoderStepReset; - } - } - if(event != ManchesterEventReset) { - bool data; - bool data_ok = manchester_advance( - instance->manchester_saved_state, event, &instance->manchester_saved_state, &data); - - if(data_ok) { - instance->decoder.decode_data = (instance->decoder.decode_data << 1) | data; - instance->decoder.decode_count_bit++; - } - } - break; - } -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - */ -static void subghz_protocol_somfy_telis_check_remote_controller(SubGhzBlockGeneric* instance) { - //https://pushstack.wordpress.com/somfy-rts-protocol/ - /* - * 604 us - * / - * | 2416us | 2416us | 2416us | 2416us | 4550 us | | 67648 us | 30415 us | - * - * +--------+ +--------+ +---...---+ - * + +--------+ +--------+ +--+XXXX...XXX+-----...----- - * - * | hw. sync. | soft. | | Inter-frame - * | | sync. | data | gap - * - * - * encrypt | decrypt - * - * package 56 bit cnt key btn|crc cnt serial - * 0xA7232323312222 - 0 => A7 8 0 | 00 00 | 12 13 00 - * 0xA7222223312222 - 1 => A7 8 5 | 00 01 | 12 13 00 - * 0xA7212123312222 - 2 => A7 8 6 | 00 02 | 12 13 00 - * - * Key: “Encryption Key”, Most significant 4-bit are always 0xA, Least Significant bits is - * a linear counter. In the Smoove Origin this counter is increased together with the - * rolling code. But leaving this on a constant value also works. Gerardwr notes that - * for some other types of remotes the MSB is not constant. - * Btn: 4-bit Control codes, this indicates the button that is pressed - * CRC: 4-bit Checksum. - * Ctn: 16-bit rolling code (big-endian) increased with every button press. - * Serial: 24-bit identifier of sending device (little-endian) - * - * - * Decrypt - * - * uint8_t frame[7]; - * for (i=1; i < 7; i++) { - * frame[i] = frame[i] ^ frame[i-1]; - * } - * or - * uint64 Decrypt = frame ^ (frame>>8); - * - * Btn - * - * Value Button(s) Description - * 0x1 My Stop or move to favourite position - * 0x2 Up Move up - * 0x3 My + Up Set upper motor limit in initial programming mode - * 0x4 Down Move down - * 0x5 My + Down Set lower motor limit in initial programming mode - * 0x6 Up + Down Change motor limit and initial programming mode - * 0x8 Prog Used for (de-)registering remotes, see below - * 0x9 Sun + Flag Enable sun and wind detector (SUN and FLAG symbol on the Telis Soliris RC) - * 0xA Flag Disable sun detector (FLAG symbol on the Telis Soliris RC) - * - * CRC - * - * uint8_t frame[7]; - * for (i=0; i < 7; i++) { - * cksum = cksum ^ frame[i] ^ (frame[i] >> 4); - * } - * cksum = cksum & 0xf; - * - */ - - uint64_t data = instance->data ^ (instance->data >> 8); - instance->btn = (data >> 44) & 0xF; // ctrl - instance->cnt = (data >> 24) & 0xFFFF; // rolling code - instance->serial = data & 0xFFFFFF; // address -} - -/** - * Get button name. - * @param btn Button number, 4 bit - */ -static const char* subghz_protocol_somfy_telis_get_name_button(uint8_t btn) { - const char* name_btn[16] = { - "Unknown", - "My", - "Up", - "My+Up", - "Down", - "My+Down", - "Up+Down", - "0x07", - "Prog", - "Sun+Flag", - "Flag", - "0x0B", - "0x0C", - "0x0D", - "0x0E", - "0x0F"}; - return btn <= 0xf ? name_btn[btn] : name_btn[0]; -} - -uint8_t subghz_protocol_decoder_somfy_telis_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderSomfyTelis* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_somfy_telis_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderSomfyTelis* instance = context; - return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); -} - -bool subghz_protocol_decoder_somfy_telis_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderSomfyTelis* instance = context; - bool ret = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - break; - } - if(instance->generic.data_count_bit != - subghz_protocol_somfy_telis_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - break; - } - ret = true; - } while(false); - return ret; -} - -void subghz_protocol_decoder_somfy_telis_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderSomfyTelis* instance = context; - - subghz_protocol_somfy_telis_check_remote_controller(&instance->generic); - furi_string_cat_printf( - output, - "%s %db\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%06lX \r\n" - "Cnt:0x%04lX\r\n" - "Btn:%s\r\n", - - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)instance->generic.data, - instance->generic.serial, - instance->generic.cnt, - subghz_protocol_somfy_telis_get_name_button(instance->generic.btn)); -} diff --git a/applications/main/subghz/protocols/somfy_telis.h b/applications/main/subghz/protocols/somfy_telis.h deleted file mode 100644 index b5e989866..000000000 --- a/applications/main/subghz/protocols/somfy_telis.h +++ /dev/null @@ -1,125 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_SOMFY_TELIS_NAME "Somfy Telis" - -typedef struct SubGhzProtocolDecoderSomfyTelis SubGhzProtocolDecoderSomfyTelis; -typedef struct SubGhzProtocolEncoderSomfyTelis SubGhzProtocolEncoderSomfyTelis; - -extern const SubGhzProtocolDecoder subghz_protocol_somfy_telis_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_somfy_telis_encoder; -extern const SubGhzProtocol subghz_protocol_somfy_telis; - -/** - * Allocate SubGhzProtocolEncoderSomfyTelis. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderSomfyTelis* pointer to a SubGhzProtocolEncoderSomfyTelis instance - */ -void* subghz_protocol_encoder_somfy_telis_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderSomfyTelis. - * @param context Pointer to a SubGhzProtocolEncoderSomfyTelis instance - */ -void subghz_protocol_encoder_somfy_telis_free(void* context); - -/** - * Key generation from simple data. - * @param context Pointer to a SubGhzProtocolEncoderSomfyTelis instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param serial Serial number, 24 bit - * @param btn Button number, 8 bit - * @param cnt Counter value, 16 bit - * @param preset Modulation, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_somfy_telis_create_data( - void* context, - FlipperFormat* flipper_format, - uint32_t serial, - uint8_t btn, - uint16_t cnt, - SubGhzRadioPreset* preset); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderSomfyTelis instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_somfy_telis_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderSomfyTelis instance - */ -void subghz_protocol_encoder_somfy_telis_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderSomfyTelis instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_somfy_telis_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderSomfyTelis. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderSomfyTelis* pointer to a SubGhzProtocolDecoderSomfyTelis instance - */ -void* subghz_protocol_decoder_somfy_telis_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderSomfyTelis. - * @param context Pointer to a SubGhzProtocolDecoderSomfyTelis instance - */ -void subghz_protocol_decoder_somfy_telis_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderSomfyTelis. - * @param context Pointer to a SubGhzProtocolDecoderSomfyTelis instance - */ -void subghz_protocol_decoder_somfy_telis_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderSomfyTelis instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_somfy_telis_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderSomfyTelis instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_somfy_telis_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderSomfyTelis. - * @param context Pointer to a SubGhzProtocolDecoderSomfyTelis instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_somfy_telis_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderSomfyTelis. - * @param context Pointer to a SubGhzProtocolDecoderSomfyTelis instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_somfy_telis_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderSomfyTelis instance - * @param output Resulting text - */ -void subghz_protocol_decoder_somfy_telis_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/protocols/star_line.c b/applications/main/subghz/protocols/star_line.c deleted file mode 100644 index 3066c6e2b..000000000 --- a/applications/main/subghz/protocols/star_line.c +++ /dev/null @@ -1,780 +0,0 @@ -#include "star_line.h" -#include "keeloq_common.h" - -#include "../subghz_keystore.h" -#include - -#include "../blocks/const.h" -#include "../blocks/decoder.h" -#include "../blocks/encoder.h" -#include "../blocks/generic.h" -#include "../blocks/math.h" - -#define TAG "SubGhzProtocolStarLine" - -static const SubGhzBlockConst subghz_protocol_star_line_const = { - .te_short = 250, - .te_long = 500, - .te_delta = 120, - .min_count_bit_for_found = 64, -}; - -struct SubGhzProtocolDecoderStarLine { - SubGhzProtocolDecoderBase base; - - SubGhzBlockDecoder decoder; - SubGhzBlockGeneric generic; - - uint16_t header_count; - SubGhzKeystore* keystore; - const char* manufacture_name; - - FuriString* manufacture_from_file; -}; - -struct SubGhzProtocolEncoderStarLine { - SubGhzProtocolEncoderBase base; - - SubGhzProtocolBlockEncoder encoder; - SubGhzBlockGeneric generic; - - SubGhzKeystore* keystore; - const char* manufacture_name; - - FuriString* manufacture_from_file; -}; - -typedef enum { - StarLineDecoderStepReset = 0, - StarLineDecoderStepCheckPreambula, - StarLineDecoderStepSaveDuration, - StarLineDecoderStepCheckDuration, -} StarLineDecoderStep; - -const SubGhzProtocolDecoder subghz_protocol_star_line_decoder = { - .alloc = subghz_protocol_decoder_star_line_alloc, - .free = subghz_protocol_decoder_star_line_free, - - .feed = subghz_protocol_decoder_star_line_feed, - .reset = subghz_protocol_decoder_star_line_reset, - - .get_hash_data = subghz_protocol_decoder_star_line_get_hash_data, - .serialize = subghz_protocol_decoder_star_line_serialize, - .deserialize = subghz_protocol_decoder_star_line_deserialize, - .get_string = subghz_protocol_decoder_star_line_get_string, -}; - -const SubGhzProtocolEncoder subghz_protocol_star_line_encoder = { - .alloc = subghz_protocol_encoder_star_line_alloc, - .free = subghz_protocol_encoder_star_line_free, - - .deserialize = subghz_protocol_encoder_star_line_deserialize, - .stop = subghz_protocol_encoder_star_line_stop, - .yield = subghz_protocol_encoder_star_line_yield, -}; - -const SubGhzProtocol subghz_protocol_star_line = { - .name = SUBGHZ_PROTOCOL_STAR_LINE_NAME, - .type = SubGhzProtocolTypeDynamic, - .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | - SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, - - .decoder = &subghz_protocol_star_line_decoder, - .encoder = &subghz_protocol_star_line_encoder, -}; - -static const char* mfname; - -static int kl_type; - -void star_line_reset_mfname() { - mfname = ""; -} - -void star_line_reset_kl_type() { - kl_type = 0; -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - * @param keystore Pointer to a SubGhzKeystore* instance - * @param manufacture_name - */ -static void subghz_protocol_star_line_check_remote_controller( - SubGhzBlockGeneric* instance, - SubGhzKeystore* keystore, - const char** manufacture_name); - -void* subghz_protocol_encoder_star_line_alloc(SubGhzEnvironment* environment) { - SubGhzProtocolEncoderStarLine* instance = malloc(sizeof(SubGhzProtocolEncoderStarLine)); - - instance->base.protocol = &subghz_protocol_star_line; - instance->generic.protocol_name = instance->base.protocol->name; - instance->keystore = subghz_environment_get_keystore(environment); - - instance->manufacture_from_file = furi_string_alloc(); - - instance->encoder.repeat = 10; - instance->encoder.size_upload = 256; - instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); - instance->encoder.is_running = false; - - return instance; -} - -void subghz_protocol_encoder_star_line_free(void* context) { - furi_assert(context); - SubGhzProtocolEncoderStarLine* instance = context; - furi_string_free(instance->manufacture_from_file); - free(instance->encoder.upload); - free(instance); -} - -/** - * Key generation from simple data - * @param instance Pointer to a SubGhzProtocolEncoderKeeloq* instance - * @param btn Button number, 4 bit - */ -static bool - subghz_protocol_star_line_gen_data(SubGhzProtocolEncoderStarLine* instance, uint8_t btn) { - if(instance->generic.cnt < 0xFFFF) { - instance->generic.cnt++; - } else if(instance->generic.cnt >= 0xFFFF) { - instance->generic.cnt = 0; - } - uint32_t fix = btn << 24 | instance->generic.serial; - uint32_t decrypt = btn << 24 | (instance->generic.serial & 0xFF) << 16 | instance->generic.cnt; - uint32_t hop = 0; - uint64_t man = 0; - uint64_t code_found_reverse; - int res = 0; - - if(instance->manufacture_name == 0x0) { - instance->manufacture_name = ""; - } - - if(strcmp(instance->manufacture_name, "Unknown") == 0) { - code_found_reverse = subghz_protocol_blocks_reverse_key( - instance->generic.data, instance->generic.data_count_bit); - hop = code_found_reverse & 0x00000000ffffffff; - } else { - for - M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) { - res = strcmp(furi_string_get_cstr(manufacture_code->name), instance->manufacture_name); - if(res == 0) { - switch(manufacture_code->type) { - case KEELOQ_LEARNING_SIMPLE: - //Simple Learning - hop = subghz_protocol_keeloq_common_encrypt(decrypt, manufacture_code->key); - break; - case KEELOQ_LEARNING_NORMAL: - //Normal Learning - man = - subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); - hop = subghz_protocol_keeloq_common_encrypt(decrypt, man); - break; - case KEELOQ_LEARNING_UNKNOWN: - if(kl_type == 1) { - hop = - subghz_protocol_keeloq_common_encrypt(decrypt, manufacture_code->key); - } - if(kl_type == 2) { - man = subghz_protocol_keeloq_common_normal_learning( - fix, manufacture_code->key); - hop = subghz_protocol_keeloq_common_encrypt(decrypt, man); - } - break; - } - break; - } - } - } - if(hop) { - uint64_t yek = (uint64_t)fix << 32 | hop; - instance->generic.data = - subghz_protocol_blocks_reverse_key(yek, instance->generic.data_count_bit); - return true; - } else { - instance->manufacture_name = "Unknown"; - return false; - } -} - -bool subghz_protocol_star_line_create_data( - void* context, - FlipperFormat* flipper_format, - uint32_t serial, - uint8_t btn, - uint16_t cnt, - const char* manufacture_name, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolEncoderStarLine* instance = context; - instance->generic.serial = serial; - instance->generic.cnt = cnt; - instance->manufacture_name = manufacture_name; - instance->generic.data_count_bit = 64; - bool res = subghz_protocol_star_line_gen_data(instance, btn); - if(res) { - res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); - } - return res; -} - -/** - * Generating an upload from data. - * @param instance Pointer to a SubGhzProtocolEncoderKeeloq instance - * @return true On success - */ -static bool subghz_protocol_encoder_star_line_get_upload( - SubGhzProtocolEncoderStarLine* instance, - uint8_t btn) { - furi_assert(instance); - - //gen new key - if(subghz_protocol_star_line_gen_data(instance, btn)) { - //ToDo if you need to add a callback to automatically update the data on the display - } else { - return false; - } - - size_t index = 0; - size_t size_upload = 6 * 2 + (instance->generic.data_count_bit * 2); - if(size_upload > instance->encoder.size_upload) { - FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer."); - return false; - } else { - instance->encoder.size_upload = size_upload; - } - - //Send header - for(uint8_t i = 6; i > 0; i--) { - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_star_line_const.te_long * 2); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_star_line_const.te_long * 2); - } - - //Send key data - for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { - if(bit_read(instance->generic.data, i - 1)) { - //send bit 1 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_star_line_const.te_long); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_star_line_const.te_long); - } else { - //send bit 0 - instance->encoder.upload[index++] = - level_duration_make(true, (uint32_t)subghz_protocol_star_line_const.te_short); - instance->encoder.upload[index++] = - level_duration_make(false, (uint32_t)subghz_protocol_star_line_const.te_short); - } - } - - return true; -} - -bool subghz_protocol_encoder_star_line_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolEncoderStarLine* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - - // Read manufacturer from file - if(flipper_format_read_string( - flipper_format, "Manufacture", instance->manufacture_from_file)) { - instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); - mfname = furi_string_get_cstr(instance->manufacture_from_file); - } else { - FURI_LOG_D(TAG, "ENCODER: Missing Manufacture"); - } - - subghz_protocol_star_line_check_remote_controller( - &instance->generic, instance->keystore, &instance->manufacture_name); - - //optional parameter parameter - flipper_format_read_uint32( - flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - - subghz_protocol_encoder_star_line_get_upload(instance, instance->generic.btn); - - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - uint8_t key_data[sizeof(uint64_t)] = {0}; - for(size_t i = 0; i < sizeof(uint64_t); i++) { - key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data >> i * 8) & 0xFF; - } - if(!flipper_format_update_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) { - FURI_LOG_E(TAG, "Unable to add Key"); - break; - } - - instance->encoder.is_running = true; - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_encoder_star_line_stop(void* context) { - SubGhzProtocolEncoderStarLine* instance = context; - instance->encoder.is_running = false; -} - -LevelDuration subghz_protocol_encoder_star_line_yield(void* context) { - SubGhzProtocolEncoderStarLine* instance = context; - - if(instance->encoder.repeat == 0 || !instance->encoder.is_running) { - instance->encoder.is_running = false; - return level_duration_reset(); - } - - LevelDuration ret = instance->encoder.upload[instance->encoder.front]; - - if(++instance->encoder.front == instance->encoder.size_upload) { - instance->encoder.repeat--; - instance->encoder.front = 0; - } - - return ret; -} - -void* subghz_protocol_decoder_star_line_alloc(SubGhzEnvironment* environment) { - SubGhzProtocolDecoderStarLine* instance = malloc(sizeof(SubGhzProtocolDecoderStarLine)); - instance->base.protocol = &subghz_protocol_star_line; - instance->generic.protocol_name = instance->base.protocol->name; - - instance->manufacture_from_file = furi_string_alloc(); - - instance->keystore = subghz_environment_get_keystore(environment); - - return instance; -} - -void subghz_protocol_decoder_star_line_free(void* context) { - furi_assert(context); - SubGhzProtocolDecoderStarLine* instance = context; - furi_string_free(instance->manufacture_from_file); - - free(instance); -} - -void subghz_protocol_decoder_star_line_reset(void* context) { - furi_assert(context); - SubGhzProtocolDecoderStarLine* instance = context; - instance->decoder.parser_step = StarLineDecoderStepReset; - mfname = ""; - kl_type = 0; -} - -void subghz_protocol_decoder_star_line_feed(void* context, bool level, uint32_t duration) { - furi_assert(context); - SubGhzProtocolDecoderStarLine* instance = context; - - switch(instance->decoder.parser_step) { - case StarLineDecoderStepReset: - if(level) { - if(DURATION_DIFF(duration, subghz_protocol_star_line_const.te_long * 2) < - subghz_protocol_star_line_const.te_delta * 2) { - instance->decoder.parser_step = StarLineDecoderStepCheckPreambula; - instance->header_count++; - } else if(instance->header_count > 4) { - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->decoder.te_last = duration; - instance->decoder.parser_step = StarLineDecoderStepCheckDuration; - } - } else { - instance->header_count = 0; - } - break; - case StarLineDecoderStepCheckPreambula: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_star_line_const.te_long * 2) < - subghz_protocol_star_line_const.te_delta * 2)) { - //Found Preambula - instance->decoder.parser_step = StarLineDecoderStepReset; - } else { - instance->header_count = 0; - instance->decoder.parser_step = StarLineDecoderStepReset; - } - break; - case StarLineDecoderStepSaveDuration: - if(level) { - if(duration >= (subghz_protocol_star_line_const.te_long + - subghz_protocol_star_line_const.te_delta)) { - instance->decoder.parser_step = StarLineDecoderStepReset; - if(instance->decoder.decode_count_bit >= - subghz_protocol_star_line_const.min_count_bit_for_found) { - if(instance->generic.data != instance->decoder.decode_data) { - instance->generic.data = instance->decoder.decode_data; - instance->generic.data_count_bit = instance->decoder.decode_count_bit; - if(instance->base.callback) - instance->base.callback(&instance->base, instance->base.context); - } - } - instance->decoder.decode_data = 0; - instance->decoder.decode_count_bit = 0; - instance->header_count = 0; - break; - } else { - instance->decoder.te_last = duration; - instance->decoder.parser_step = StarLineDecoderStepCheckDuration; - } - - } else { - instance->decoder.parser_step = StarLineDecoderStepReset; - } - break; - case StarLineDecoderStepCheckDuration: - if(!level) { - if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_star_line_const.te_short) < - subghz_protocol_star_line_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_star_line_const.te_short) < - subghz_protocol_star_line_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 0); - instance->decoder.parser_step = StarLineDecoderStepSaveDuration; - } else if( - (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_star_line_const.te_long) < - subghz_protocol_star_line_const.te_delta) && - (DURATION_DIFF(duration, subghz_protocol_star_line_const.te_long) < - subghz_protocol_star_line_const.te_delta)) { - subghz_protocol_blocks_add_bit(&instance->decoder, 1); - instance->decoder.parser_step = StarLineDecoderStepSaveDuration; - } else { - instance->decoder.parser_step = StarLineDecoderStepReset; - } - } else { - instance->decoder.parser_step = StarLineDecoderStepReset; - } - break; - } -} - -/** - * Validation of decrypt data. - * @param instance Pointer to a SubGhzBlockGeneric instance - * @param decrypt Decrypd data - * @param btn Button number, 4 bit - * @param end_serial decrement the last 10 bits of the serial number - * @return true On success - */ -static inline bool subghz_protocol_star_line_check_decrypt( - SubGhzBlockGeneric* instance, - uint32_t decrypt, - uint8_t btn, - uint32_t end_serial) { - furi_assert(instance); - if((decrypt >> 24 == btn) && ((((uint16_t)(decrypt >> 16)) & 0x00FF) == end_serial)) { - instance->cnt = decrypt & 0x0000FFFF; - return true; - } - return false; -} - -/** - * Checking the accepted code against the database manafacture key - * @param instance Pointer to a SubGhzBlockGeneric* instance - * @param fix Fix part of the parcel - * @param hop Hop encrypted part of the parcel - * @param keystore Pointer to a SubGhzKeystore* instance - * @param manufacture_name - * @return true on successful search - */ -static uint8_t subghz_protocol_star_line_check_remote_controller_selector( - SubGhzBlockGeneric* instance, - uint32_t fix, - uint32_t hop, - SubGhzKeystore* keystore, - const char** manufacture_name) { - uint16_t end_serial = (uint16_t)(fix & 0xFF); - uint8_t btn = (uint8_t)(fix >> 24); - uint32_t decrypt = 0; - uint64_t man_normal_learning; - int res = 0; - if(mfname == 0x0) { - mfname = ""; - } - - if(strcmp(mfname, "") == 0) { - for - M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) { - switch(manufacture_code->type) { - case KEELOQ_LEARNING_SIMPLE: - // Simple Learning - decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); - if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - return 1; - } - break; - case KEELOQ_LEARNING_NORMAL: - // Normal Learning - // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 - man_normal_learning = - subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); - if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - return 1; - } - break; - case KEELOQ_LEARNING_UNKNOWN: - // Simple Learning - decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); - if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 1; - return 1; - } - // Check for mirrored man - uint64_t man_rev = 0; - uint64_t man_rev_byte = 0; - for(uint8_t i = 0; i < 64; i += 8) { - man_rev_byte = (uint8_t)(manufacture_code->key >> i); - man_rev = man_rev | man_rev_byte << (56 - i); - } - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev); - if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 1; - return 1; - } - //########################### - // Normal Learning - // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 - man_normal_learning = - subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); - if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 2; - return 1; - } - // Check for mirrored man - man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, man_rev); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); - if(subghz_protocol_star_line_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 2; - return 1; - } - break; - } - } - } else if(strcmp(mfname, "Unknown") == 0) { - return 1; - } else { - for - M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) { - res = strcmp(furi_string_get_cstr(manufacture_code->name), mfname); - if(res == 0) { - switch(manufacture_code->type) { - case KEELOQ_LEARNING_SIMPLE: - // Simple Learning - decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); - if(subghz_protocol_star_line_check_decrypt( - instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - return 1; - } - break; - case KEELOQ_LEARNING_NORMAL: - // Normal Learning - // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 - man_normal_learning = - subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); - if(subghz_protocol_star_line_check_decrypt( - instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - return 1; - } - break; - case KEELOQ_LEARNING_UNKNOWN: - // Simple Learning - decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); - if(subghz_protocol_star_line_check_decrypt( - instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 1; - return 1; - } - // Check for mirrored man - uint64_t man_rev = 0; - uint64_t man_rev_byte = 0; - for(uint8_t i = 0; i < 64; i += 8) { - man_rev_byte = (uint8_t)(manufacture_code->key >> i); - man_rev = man_rev | man_rev_byte << (56 - i); - } - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev); - if(subghz_protocol_star_line_check_decrypt( - instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 1; - return 1; - } - //########################### - // Normal Learning - // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 - man_normal_learning = - subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); - if(subghz_protocol_star_line_check_decrypt( - instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 2; - return 1; - } - - // Check for mirrored man - man_normal_learning = - subghz_protocol_keeloq_common_normal_learning(fix, man_rev); - decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning); - if(subghz_protocol_star_line_check_decrypt( - instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - mfname = *manufacture_name; - kl_type = 2; - return 1; - } - break; - } - } - } - } - - *manufacture_name = "Unknown"; - mfname = "Unknown"; - instance->cnt = 0; - - return 0; -} - -/** - * Analysis of received data - * @param instance Pointer to a SubGhzBlockGeneric* instance - * @param keystore Pointer to a SubGhzKeystore* instance - * @param manufacture_name - */ -static void subghz_protocol_star_line_check_remote_controller( - SubGhzBlockGeneric* instance, - SubGhzKeystore* keystore, - const char** manufacture_name) { - uint64_t key = subghz_protocol_blocks_reverse_key(instance->data, instance->data_count_bit); - uint32_t key_fix = key >> 32; - uint32_t key_hop = key & 0x00000000ffffffff; - - subghz_protocol_star_line_check_remote_controller_selector( - instance, key_fix, key_hop, keystore, manufacture_name); - - instance->serial = key_fix & 0x00FFFFFF; - instance->btn = key_fix >> 24; -} - -uint8_t subghz_protocol_decoder_star_line_get_hash_data(void* context) { - furi_assert(context); - SubGhzProtocolDecoderStarLine* instance = context; - return subghz_protocol_blocks_get_hash_data( - &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); -} - -bool subghz_protocol_decoder_star_line_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset) { - furi_assert(context); - SubGhzProtocolDecoderStarLine* instance = context; - subghz_protocol_star_line_check_remote_controller( - &instance->generic, instance->keystore, &instance->manufacture_name); - bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); - - if(res && !flipper_format_write_string_cstr( - flipper_format, "Manufacture", instance->manufacture_name)) { - FURI_LOG_E(TAG, "Unable to add manufacture name"); - res = false; - } - if(res && instance->generic.data_count_bit != - subghz_protocol_star_line_const.min_count_bit_for_found) { - FURI_LOG_E(TAG, "Wrong number of bits in key"); - res = false; - } - return res; -} - -bool subghz_protocol_decoder_star_line_deserialize(void* context, FlipperFormat* flipper_format) { - furi_assert(context); - SubGhzProtocolDecoderStarLine* instance = context; - bool res = false; - do { - if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { - FURI_LOG_E(TAG, "Deserialize error"); - break; - } - - // Read manufacturer from file - if(flipper_format_read_string( - flipper_format, "Manufacture", instance->manufacture_from_file)) { - instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); - mfname = furi_string_get_cstr(instance->manufacture_from_file); - } else { - FURI_LOG_D(TAG, "DECODER: Missing Manufacture"); - } - - res = true; - } while(false); - - return res; -} - -void subghz_protocol_decoder_star_line_get_string(void* context, FuriString* output) { - furi_assert(context); - SubGhzProtocolDecoderStarLine* instance = context; - - subghz_protocol_star_line_check_remote_controller( - &instance->generic, instance->keystore, &instance->manufacture_name); - - uint32_t code_found_hi = instance->generic.data >> 32; - uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; - - uint64_t code_found_reverse = subghz_protocol_blocks_reverse_key( - instance->generic.data, instance->generic.data_count_bit); - uint32_t code_found_reverse_hi = code_found_reverse >> 32; - uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; - - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:%08lX%08lX\r\n" - "Fix:0x%08lX Cnt:%04lX\r\n" - "Hop:0x%08lX Btn:%02X\r\n" - "MF:%s\r\n", - instance->generic.protocol_name, - instance->generic.data_count_bit, - code_found_hi, - code_found_lo, - code_found_reverse_hi, - instance->generic.cnt, - code_found_reverse_lo, - instance->generic.btn, - instance->manufacture_name); -} diff --git a/applications/main/subghz/protocols/star_line.h b/applications/main/subghz/protocols/star_line.h deleted file mode 100644 index e8873d41a..000000000 --- a/applications/main/subghz/protocols/star_line.h +++ /dev/null @@ -1,131 +0,0 @@ -#pragma once - -#include "base.h" - -#define SUBGHZ_PROTOCOL_STAR_LINE_NAME "Star Line" - -typedef struct SubGhzProtocolDecoderStarLine SubGhzProtocolDecoderStarLine; -typedef struct SubGhzProtocolEncoderStarLine SubGhzProtocolEncoderStarLine; - -extern const SubGhzProtocolDecoder subghz_protocol_star_line_decoder; -extern const SubGhzProtocolEncoder subghz_protocol_star_line_encoder; -extern const SubGhzProtocol subghz_protocol_star_line; - -void star_line_reset_mfname(); - -void star_line_reset_kl_type(); - -/** - * Allocate SubGhzProtocolEncoderStarLine. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolEncoderStarLine* pointer to a SubGhzProtocolEncoderStarLine instance - */ -void* subghz_protocol_encoder_star_line_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolEncoderStarLine. - * @param context Pointer to a SubGhzProtocolEncoderStarLine instance - */ -void subghz_protocol_encoder_star_line_free(void* context); - -/** - * Key generation from simple data. - * @param context Pointer to a SubGhzProtocolEncoderStarLine instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param serial Serial number, 24 bit - * @param btn Button number, 8 bit - * @param cnt Counter value, 16 bit - * @param manufacture_name Name of manufacturer's key - * @param preset Modulation, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_star_line_create_data( - void* context, - FlipperFormat* flipper_format, - uint32_t serial, - uint8_t btn, - uint16_t cnt, - const char* manufacture_name, - SubGhzRadioPreset* preset); - -/** - * Deserialize and generating an upload to send. - * @param context Pointer to a SubGhzProtocolEncoderStarLine instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_encoder_star_line_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Forced transmission stop. - * @param context Pointer to a SubGhzProtocolEncoderStarLine instance - */ -void subghz_protocol_encoder_star_line_stop(void* context); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzProtocolEncoderStarLine instance - * @return LevelDuration - */ -LevelDuration subghz_protocol_encoder_star_line_yield(void* context); - -/** - * Allocate SubGhzProtocolDecoderStarLine. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzProtocolDecoderStarLine* pointer to a SubGhzProtocolDecoderStarLine instance - */ -void* subghz_protocol_decoder_star_line_alloc(SubGhzEnvironment* environment); - -/** - * Free SubGhzProtocolDecoderStarLine. - * @param context Pointer to a SubGhzProtocolDecoderStarLine instance - */ -void subghz_protocol_decoder_star_line_free(void* context); - -/** - * Reset decoder SubGhzProtocolDecoderStarLine. - * @param context Pointer to a SubGhzProtocolDecoderStarLine instance - */ -void subghz_protocol_decoder_star_line_reset(void* context); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param context Pointer to a SubGhzProtocolDecoderStarLine instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_protocol_decoder_star_line_feed(void* context, bool level, uint32_t duration); - -/** - * Getting the hash sum of the last randomly received parcel. - * @param context Pointer to a SubGhzProtocolDecoderStarLine instance - * @return hash Hash sum - */ -uint8_t subghz_protocol_decoder_star_line_get_hash_data(void* context); - -/** - * Serialize data SubGhzProtocolDecoderStarLine. - * @param context Pointer to a SubGhzProtocolDecoderStarLine instance - * @param flipper_format Pointer to a FlipperFormat instance - * @param preset The modulation on which the signal was received, SubGhzRadioPreset - * @return true On success - */ -bool subghz_protocol_decoder_star_line_serialize( - void* context, - FlipperFormat* flipper_format, - SubGhzRadioPreset* preset); - -/** - * Deserialize data SubGhzProtocolDecoderStarLine. - * @param context Pointer to a SubGhzProtocolDecoderStarLine instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_protocol_decoder_star_line_deserialize(void* context, FlipperFormat* flipper_format); - -/** - * Getting a textual representation of the received data. - * @param context Pointer to a SubGhzProtocolDecoderStarLine instance - * @param output Resulting text - */ -void subghz_protocol_decoder_star_line_get_string(void* context, FuriString* output); diff --git a/applications/main/subghz/receiver.c b/applications/main/subghz/receiver.c deleted file mode 100644 index 698fe098e..000000000 --- a/applications/main/subghz/receiver.c +++ /dev/null @@ -1,124 +0,0 @@ -#include "receiver.h" - -#include "registry.h" -#include "protocols/protocol_items.h" - -#include - -typedef struct { - SubGhzProtocolEncoderBase* base; -} SubGhzReceiverSlot; - -ARRAY_DEF(SubGhzReceiverSlotArray, SubGhzReceiverSlot, M_POD_OPLIST); -#define M_OPL_SubGhzReceiverSlotArray_t() ARRAY_OPLIST(SubGhzReceiverSlotArray, M_POD_OPLIST) - -struct SubGhzReceiver { - SubGhzReceiverSlotArray_t slots; - SubGhzProtocolFlag filter; - - SubGhzReceiverCallback callback; - void* context; -}; - -SubGhzReceiver* subghz_receiver_alloc_init(SubGhzEnvironment* environment) { - SubGhzReceiver* instance = malloc(sizeof(SubGhzReceiver)); - SubGhzReceiverSlotArray_init(instance->slots); - const SubGhzProtocolRegistry* protocol_registry_items = - subghz_environment_get_protocol_registry(environment); - - for(size_t i = 0; i < subghz_protocol_registry_count(protocol_registry_items); ++i) { - const SubGhzProtocol* protocol = - subghz_protocol_registry_get_by_index(protocol_registry_items, i); - - if(protocol->decoder && protocol->decoder->alloc) { - SubGhzReceiverSlot* slot = SubGhzReceiverSlotArray_push_new(instance->slots); - slot->base = protocol->decoder->alloc(environment); - } - } - - instance->callback = NULL; - instance->context = NULL; - return instance; -} - -void subghz_receiver_free(SubGhzReceiver* instance) { - furi_assert(instance); - - instance->callback = NULL; - instance->context = NULL; - - // Release allocated slots - for - M_EACH(slot, instance->slots, SubGhzReceiverSlotArray_t) { - slot->base->protocol->decoder->free(slot->base); - slot->base = NULL; - } - SubGhzReceiverSlotArray_clear(instance->slots); - - free(instance); -} - -void subghz_receiver_decode(SubGhzReceiver* instance, bool level, uint32_t duration) { - furi_assert(instance); - furi_assert(instance->slots); - - for - M_EACH(slot, instance->slots, SubGhzReceiverSlotArray_t) { - if((slot->base->protocol->flag & instance->filter) != 0) { - slot->base->protocol->decoder->feed(slot->base, level, duration); - } - } -} - -void subghz_receiver_reset(SubGhzReceiver* instance) { - furi_assert(instance); - furi_assert(instance->slots); - - for - M_EACH(slot, instance->slots, SubGhzReceiverSlotArray_t) { - slot->base->protocol->decoder->reset(slot->base); - } -} - -static void subghz_receiver_rx_callback(SubGhzProtocolDecoderBase* decoder_base, void* context) { - SubGhzReceiver* instance = context; - if(instance->callback) { - instance->callback(instance, decoder_base, instance->context); - } -} - -void subghz_receiver_set_rx_callback( - SubGhzReceiver* instance, - SubGhzReceiverCallback callback, - void* context) { - furi_assert(instance); - - for - M_EACH(slot, instance->slots, SubGhzReceiverSlotArray_t) { - subghz_protocol_decoder_base_set_decoder_callback( - (SubGhzProtocolDecoderBase*)slot->base, subghz_receiver_rx_callback, instance); - } - - instance->callback = callback; - instance->context = context; -} - -void subghz_receiver_set_filter(SubGhzReceiver* instance, SubGhzProtocolFlag filter) { - furi_assert(instance); - instance->filter = filter; -} - -SubGhzProtocolDecoderBase* subghz_receiver_search_decoder_base_by_name( - SubGhzReceiver* instance, - const char* decoder_name) { - SubGhzProtocolDecoderBase* result = NULL; - - for - M_EACH(slot, instance->slots, SubGhzReceiverSlotArray_t) { - if(strcmp(slot->base->protocol->name, decoder_name) == 0) { - result = (SubGhzProtocolDecoderBase*)slot->base; - break; - } - } - return result; -} diff --git a/applications/main/subghz/receiver.h b/applications/main/subghz/receiver.h deleted file mode 100644 index 2ef722d1f..000000000 --- a/applications/main/subghz/receiver.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include "types.h" -#include "protocols/base.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct SubGhzReceiver SubGhzReceiver; - -typedef void (*SubGhzReceiverCallback)( - SubGhzReceiver* decoder, - SubGhzProtocolDecoderBase* decoder_base, - void* context); - -/** - * Allocate and init SubGhzReceiver. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzReceiver* pointer to a SubGhzReceiver instance - */ -SubGhzReceiver* subghz_receiver_alloc_init(SubGhzEnvironment* environment); - -/** - * Free SubGhzReceiver. - * @param instance Pointer to a SubGhzReceiver instance - */ -void subghz_receiver_free(SubGhzReceiver* instance); - -/** - * Parse a raw sequence of levels and durations received from the air. - * @param instance Pointer to a SubGhzReceiver instance - * @param level Signal level true-high false-low - * @param duration Duration of this level in, us - */ -void subghz_receiver_decode(SubGhzReceiver* instance, bool level, uint32_t duration); - -/** - * Reset decoder SubGhzReceiver. - * @param instance Pointer to a SubGhzReceiver instance - */ -void subghz_receiver_reset(SubGhzReceiver* instance); - -/** - * Set a callback upon completion of successful decoding of one of the protocols. - * @param instance Pointer to a SubGhzReceiver instance - * @param callback Callback, SubGhzReceiverCallback - * @param context Context - */ -void subghz_receiver_set_rx_callback( - SubGhzReceiver* instance, - SubGhzReceiverCallback callback, - void* context); - -/** - * Set the filter of receivers that will work at the moment. - * @param instance Pointer to a SubGhzReceiver instance - * @param filter Filter, SubGhzProtocolFlag - */ -void subghz_receiver_set_filter(SubGhzReceiver* instance, SubGhzProtocolFlag filter); - -/** - * Search for a cattery by his name. - * @param instance Pointer to a SubGhzReceiver instance - * @param decoder_name Receiver name - * @return SubGhzProtocolDecoderBase* pointer to a SubGhzProtocolDecoderBase instance - */ -SubGhzProtocolDecoderBase* - subghz_receiver_search_decoder_base_by_name(SubGhzReceiver* instance, const char* decoder_name); - -#ifdef __cplusplus -} -#endif diff --git a/applications/main/subghz/registry.c b/applications/main/subghz/registry.c deleted file mode 100644 index d0c22ea8c..000000000 --- a/applications/main/subghz/registry.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "registry.h" - -const SubGhzProtocol* subghz_protocol_registry_get_by_name( - const SubGhzProtocolRegistry* protocol_registry, - const char* name) { - furi_assert(protocol_registry); - - for(size_t i = 0; i < subghz_protocol_registry_count(protocol_registry); i++) { - if(strcmp(name, protocol_registry->items[i]->name) == 0) { - return protocol_registry->items[i]; - } - } - return NULL; -} - -const SubGhzProtocol* subghz_protocol_registry_get_by_index( - const SubGhzProtocolRegistry* protocol_registry, - size_t index) { - furi_assert(protocol_registry); - if(index < subghz_protocol_registry_count(protocol_registry)) { - return protocol_registry->items[index]; - } else { - return NULL; - } -} - -size_t subghz_protocol_registry_count(const SubGhzProtocolRegistry* protocol_registry) { - furi_assert(protocol_registry); - return protocol_registry->size; -} diff --git a/applications/main/subghz/registry.h b/applications/main/subghz/registry.h deleted file mode 100644 index 91027807e..000000000 --- a/applications/main/subghz/registry.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include "types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct SubGhzEnvironment SubGhzEnvironment; - -typedef struct SubGhzProtocolRegistry SubGhzProtocolRegistry; - -struct SubGhzProtocolRegistry { - const SubGhzProtocol** items; - const size_t size; -}; - -/** - * Registration by name SubGhzProtocol. - * @param protocol_registry SubGhzProtocolRegistry - * @param name Protocol name - * @return SubGhzProtocol* pointer to a SubGhzProtocol instance - */ -const SubGhzProtocol* subghz_protocol_registry_get_by_name( - const SubGhzProtocolRegistry* protocol_registry, - const char* name); - -/** - * Registration protocol by index in array SubGhzProtocol. - * @param protocol_registry SubGhzProtocolRegistry - * @param index Protocol by index in array - * @return SubGhzProtocol* pointer to a SubGhzProtocol instance - */ -const SubGhzProtocol* subghz_protocol_registry_get_by_index( - const SubGhzProtocolRegistry* protocol_registry, - size_t index); - -/** - * Getting the number of registered protocols. - * @param protocol_registry SubGhzProtocolRegistry - * @return Number of protocols - */ -size_t subghz_protocol_registry_count(const SubGhzProtocolRegistry* protocol_registry); - -#ifdef __cplusplus -} -#endif diff --git a/applications/main/subghz/subghz_file_encoder_worker.c b/applications/main/subghz/subghz_file_encoder_worker.c deleted file mode 100644 index a8c6519ef..000000000 --- a/applications/main/subghz/subghz_file_encoder_worker.c +++ /dev/null @@ -1,244 +0,0 @@ -#include "subghz_file_encoder_worker.h" - -#include -#include -#include - -#define TAG "SubGhzFileEncoderWorker" - -#define SUBGHZ_FILE_ENCODER_LOAD 512 - -struct SubGhzFileEncoderWorker { - FuriThread* thread; - FuriStreamBuffer* stream; - - Storage* storage; - FlipperFormat* flipper_format; - - volatile bool worker_running; - volatile bool worker_stoping; - bool level; - bool is_storage_slow; - FuriString* str_data; - FuriString* file_path; - - SubGhzFileEncoderWorkerCallbackEnd callback_end; - void* context_end; -}; - -void subghz_file_encoder_worker_callback_end( - SubGhzFileEncoderWorker* instance, - SubGhzFileEncoderWorkerCallbackEnd callback_end, - void* context_end) { - furi_assert(instance); - furi_assert(callback_end); - instance->callback_end = callback_end; - instance->context_end = context_end; -} - -void subghz_file_encoder_worker_add_level_duration( - SubGhzFileEncoderWorker* instance, - int32_t duration) { - bool res = true; - if(duration < 0 && !instance->level) { - res = false; - } else if(duration > 0 && instance->level) { - res = false; - } - - if(res) { - instance->level = !instance->level; - furi_stream_buffer_send(instance->stream, &duration, sizeof(int32_t), 100); - } else { - FURI_LOG_E(TAG, "Invalid level in the stream"); - } -} - -bool subghz_file_encoder_worker_data_parse(SubGhzFileEncoderWorker* instance, const char* strStart) { - char* str1; - bool res = false; - // Line sample: "RAW_Data: -1, 2, -2..." - - // Look for a key in the line - str1 = strstr(strStart, "RAW_Data: "); - - if(str1 != NULL) { - // Skip key - str1 = strchr(str1, ' '); - - // Check that there is still an element in the line - while(strchr(str1, ' ') != NULL) { - str1 = strchr(str1, ' '); - - // Skip space - str1 += 1; - subghz_file_encoder_worker_add_level_duration(instance, atoi(str1)); - } - res = true; - } - return res; -} - -void subghz_file_encoder_worker_get_text_progress( - SubGhzFileEncoderWorker* instance, - FuriString* output) { - UNUSED(output); - Stream* stream = flipper_format_get_raw_stream(instance->flipper_format); - size_t total_size = stream_size(stream); - size_t current_offset = stream_tell(stream); - size_t buffer_avail = furi_stream_buffer_bytes_available(instance->stream); - - furi_string_printf(output, "%03u%%", 100 * (current_offset - buffer_avail) / total_size); -} - -LevelDuration subghz_file_encoder_worker_get_level_duration(void* context) { - furi_assert(context); - SubGhzFileEncoderWorker* instance = context; - int32_t duration; - int ret = furi_stream_buffer_receive(instance->stream, &duration, sizeof(int32_t), 0); - if(ret == sizeof(int32_t)) { - LevelDuration level_duration = {.level = LEVEL_DURATION_RESET}; - if(duration < 0) { - level_duration = level_duration_make(false, -duration); - } else if(duration > 0) { - level_duration = level_duration_make(true, duration); - } else if(duration == 0) { //-V547 - level_duration = level_duration_reset(); - FURI_LOG_I(TAG, "Stop transmission"); - instance->worker_stoping = true; - } - return level_duration; - } else { - instance->is_storage_slow = true; - return level_duration_wait(); - } -} - -/** Worker thread - * - * @param context - * @return exit code - */ -static int32_t subghz_file_encoder_worker_thread(void* context) { - SubGhzFileEncoderWorker* instance = context; - FURI_LOG_I(TAG, "Worker start"); - bool res = false; - instance->is_storage_slow = false; - Stream* stream = flipper_format_get_raw_stream(instance->flipper_format); - do { - if(!flipper_format_file_open_existing( - instance->flipper_format, furi_string_get_cstr(instance->file_path))) { - FURI_LOG_E( - TAG, - "Unable to open file for read: %s", - furi_string_get_cstr(instance->file_path)); - break; - } - if(!flipper_format_read_string(instance->flipper_format, "Protocol", instance->str_data)) { - FURI_LOG_E(TAG, "Missing Protocol"); - break; - } - - //skip the end of the previous line "\n" - stream_seek(stream, 1, StreamOffsetFromCurrent); - res = true; - instance->worker_stoping = false; - FURI_LOG_I(TAG, "Start transmission"); - } while(0); - - while(res && instance->worker_running) { - size_t stream_free_byte = furi_stream_buffer_spaces_available(instance->stream); - if((stream_free_byte / sizeof(int32_t)) >= SUBGHZ_FILE_ENCODER_LOAD) { - if(stream_read_line(stream, instance->str_data)) { - furi_string_trim(instance->str_data); - if(!subghz_file_encoder_worker_data_parse( - instance, furi_string_get_cstr(instance->str_data))) { - subghz_file_encoder_worker_add_level_duration(instance, LEVEL_DURATION_RESET); - break; - } - } else { - subghz_file_encoder_worker_add_level_duration(instance, LEVEL_DURATION_RESET); - break; - } - } else { - furi_delay_ms(1); - } - } - //waiting for the end of the transfer - if(instance->is_storage_slow) { - FURI_LOG_E(TAG, "Storage is slow"); - } - FURI_LOG_I(TAG, "End read file"); - while(!furi_hal_subghz_is_async_tx_complete() && instance->worker_running) { - furi_delay_ms(5); - } - FURI_LOG_I(TAG, "End transmission"); - while(instance->worker_running) { - if(instance->worker_stoping) { - if(instance->callback_end) instance->callback_end(instance->context_end); - } - furi_delay_ms(50); - } - flipper_format_file_close(instance->flipper_format); - - FURI_LOG_I(TAG, "Worker stop"); - return 0; -} - -SubGhzFileEncoderWorker* subghz_file_encoder_worker_alloc() { - SubGhzFileEncoderWorker* instance = malloc(sizeof(SubGhzFileEncoderWorker)); - - instance->thread = - furi_thread_alloc_ex("SubGhzFEWorker", 2048, subghz_file_encoder_worker_thread, instance); - instance->stream = furi_stream_buffer_alloc(sizeof(int32_t) * 2048, sizeof(int32_t)); - - instance->storage = furi_record_open(RECORD_STORAGE); - instance->flipper_format = flipper_format_file_alloc(instance->storage); - - instance->str_data = furi_string_alloc(); - instance->file_path = furi_string_alloc(); - instance->level = false; - instance->worker_stoping = true; - - return instance; -} - -void subghz_file_encoder_worker_free(SubGhzFileEncoderWorker* instance) { - furi_assert(instance); - - furi_stream_buffer_free(instance->stream); - furi_thread_free(instance->thread); - - furi_string_free(instance->str_data); - furi_string_free(instance->file_path); - - flipper_format_free(instance->flipper_format); - furi_record_close(RECORD_STORAGE); - - free(instance); -} - -bool subghz_file_encoder_worker_start(SubGhzFileEncoderWorker* instance, const char* file_path) { - furi_assert(instance); - furi_assert(!instance->worker_running); - - furi_stream_buffer_reset(instance->stream); - furi_string_set(instance->file_path, file_path); - instance->worker_running = true; - furi_thread_start(instance->thread); - - return true; -} - -void subghz_file_encoder_worker_stop(SubGhzFileEncoderWorker* instance) { - furi_assert(instance); - furi_assert(instance->worker_running); - - instance->worker_running = false; - furi_thread_join(instance->thread); -} - -bool subghz_file_encoder_worker_is_running(SubGhzFileEncoderWorker* instance) { - furi_assert(instance); - return instance->worker_running; -} diff --git a/applications/main/subghz/subghz_file_encoder_worker.h b/applications/main/subghz/subghz_file_encoder_worker.h deleted file mode 100644 index 19a46f1e6..000000000 --- a/applications/main/subghz/subghz_file_encoder_worker.h +++ /dev/null @@ -1,65 +0,0 @@ -#pragma once - -#include - -typedef void (*SubGhzFileEncoderWorkerCallbackEnd)(void* context); - -typedef struct SubGhzFileEncoderWorker SubGhzFileEncoderWorker; - -/** - * End callback SubGhzWorker. - * @param instance SubGhzFileEncoderWorker instance - * @param callback SubGhzFileEncoderWorkerCallbackEnd callback - */ -void subghz_file_encoder_worker_callback_end( - SubGhzFileEncoderWorker* instance, - SubGhzFileEncoderWorkerCallbackEnd callback_end, - void* context_end); - -/** - * Allocate SubGhzFileEncoderWorker. - * @return SubGhzFileEncoderWorker* pointer to a SubGhzFileEncoderWorker instance - */ -SubGhzFileEncoderWorker* subghz_file_encoder_worker_alloc(); - -/** - * Free SubGhzFileEncoderWorker. - * @param instance Pointer to a SubGhzFileEncoderWorker instance - */ -void subghz_file_encoder_worker_free(SubGhzFileEncoderWorker* instance); - -/** - * Get a description of the progress. - * @param instance Pointer to a SubGhzFileEncoderWorker instance - * @param output - */ -void subghz_file_encoder_worker_get_text_progress( - SubGhzFileEncoderWorker* instance, - FuriString* output); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzFileEncoderWorker instance - * @return LevelDuration - */ -LevelDuration subghz_file_encoder_worker_get_level_duration(void* context); - -/** - * Start SubGhzFileEncoderWorker. - * @param instance Pointer to a SubGhzFileEncoderWorker instance - * @return bool - true if ok - */ -bool subghz_file_encoder_worker_start(SubGhzFileEncoderWorker* instance, const char* file_path); - -/** - * Stop SubGhzFileEncoderWorker - * @param instance Pointer to a SubGhzFileEncoderWorker instance - */ -void subghz_file_encoder_worker_stop(SubGhzFileEncoderWorker* instance); - -/** - * Check if worker is running - * @param instance Pointer to a SubGhzFileEncoderWorker instance - * @return bool - true if running - */ -bool subghz_file_encoder_worker_is_running(SubGhzFileEncoderWorker* instance); diff --git a/applications/main/subghz/subghz_keystore.c b/applications/main/subghz/subghz_keystore.c deleted file mode 100644 index e0b1cf6ca..000000000 --- a/applications/main/subghz/subghz_keystore.c +++ /dev/null @@ -1,613 +0,0 @@ -#include "subghz_keystore.h" - -#include -#include - -#include -#include -#include -#include -#include - -#define TAG "SubGhzKeystore" - -#define FILE_BUFFER_SIZE 64 - -#define SUBGHZ_KEYSTORE_FILE_TYPE "Flipper SubGhz Keystore File" -#define SUBGHZ_KEYSTORE_FILE_RAW_TYPE "Flipper SubGhz Keystore RAW File" -#define SUBGHZ_KEYSTORE_FILE_VERSION 0 - -#define SUBGHZ_KEYSTORE_FILE_ENCRYPTION_KEY_SLOT 1 -#define SUBGHZ_KEYSTORE_FILE_DECRYPTED_LINE_SIZE 512 -#define SUBGHZ_KEYSTORE_FILE_ENCRYPTED_LINE_SIZE (SUBGHZ_KEYSTORE_FILE_DECRYPTED_LINE_SIZE * 2) - -typedef enum { - SubGhzKeystoreEncryptionNone, - SubGhzKeystoreEncryptionAES256, -} SubGhzKeystoreEncryption; - -struct SubGhzKeystore { - SubGhzKeyArray_t data; -}; - -SubGhzKeystore* subghz_keystore_alloc() { - SubGhzKeystore* instance = malloc(sizeof(SubGhzKeystore)); - - SubGhzKeyArray_init(instance->data); - - return instance; -} - -void subghz_keystore_free(SubGhzKeystore* instance) { - furi_assert(instance); - - for - M_EACH(manufacture_code, instance->data, SubGhzKeyArray_t) { - furi_string_free(manufacture_code->name); - manufacture_code->key = 0; - } - SubGhzKeyArray_clear(instance->data); - - free(instance); -} - -static void subghz_keystore_add_key( - SubGhzKeystore* instance, - const char* name, - uint64_t key, - uint16_t type) { - SubGhzKey* manufacture_code = SubGhzKeyArray_push_raw(instance->data); - manufacture_code->name = furi_string_alloc_set(name); - manufacture_code->key = key; - manufacture_code->type = type; -} - -static bool subghz_keystore_process_line(SubGhzKeystore* instance, char* line) { - uint64_t key = 0; - uint16_t type = 0; - char skey[17] = {0}; - char name[65] = {0}; - int ret = sscanf(line, "%16s:%hu:%64s", skey, &type, name); - key = strtoull(skey, NULL, 16); - if(ret == 3) { - subghz_keystore_add_key(instance, name, key, type); - return true; - } else { - FURI_LOG_E(TAG, "Failed to load line: %s\r\n", line); - return false; - } -} - -static void subghz_keystore_mess_with_iv(uint8_t* iv) { - // Alignment check for `ldrd` instruction - furi_assert(((uint32_t)iv) % 4 == 0); - // Please do not share decrypted manufacture keys - // Sharing them will bring some discomfort to legal owners - // And potential legal action against you - // While you reading this code think about your own personal responsibility - asm volatile("nani%=: \n" - "ldrd r0, r2, [%0, #0x0] \n" - "lsl r1, r0, #8 \n" - "lsl r3, r2, #8 \n" - "orr r3, r3, r0, lsr #24\n" - "uadd8 r1, r1, r0 \n" - "uadd8 r3, r3, r2 \n" - "strd r1, r3, [%0, #0x0] \n" - "ldrd r1, r3, [%0, #0x8] \n" - "lsl r0, r1, #8 \n" - "orr r0, r0, r2, lsr #24\n" - "lsl r2, r3, #8 \n" - "orr r2, r2, r1, lsr #24\n" - "uadd8 r1, r1, r0 \n" - "uadd8 r3, r3, r2 \n" - "strd r1, r3, [%0, #0x8] \n" - : - : "r"(iv) - : "r0", "r1", "r2", "r3", "memory"); -} - -static bool subghz_keystore_read_file(SubGhzKeystore* instance, Stream* stream, uint8_t* iv) { - bool result = true; - uint8_t buffer[FILE_BUFFER_SIZE]; - - char* decrypted_line = malloc(SUBGHZ_KEYSTORE_FILE_DECRYPTED_LINE_SIZE); - char* encrypted_line = malloc(SUBGHZ_KEYSTORE_FILE_ENCRYPTED_LINE_SIZE); - size_t encrypted_line_cursor = 0; - - do { - if(iv) { - if(!furi_hal_crypto_store_load_key(SUBGHZ_KEYSTORE_FILE_ENCRYPTION_KEY_SLOT, iv)) { - FURI_LOG_E(TAG, "Unable to load decryption key"); - break; - } - } - - size_t ret = 0; - do { - ret = stream_read(stream, buffer, FILE_BUFFER_SIZE); - for(uint16_t i = 0; i < ret; i++) { - if(buffer[i] == '\n' && encrypted_line_cursor > 0) { - // Process line - if(iv) { - // Data alignment check, 32 instead of 16 because of hex encoding - size_t len = strlen(encrypted_line); - if(len % 32 == 0) { - // Inplace hex to bin conversion - for(size_t i = 0; i < len; i += 2) { - uint8_t hi_nibble = 0; - uint8_t lo_nibble = 0; - hex_char_to_hex_nibble(encrypted_line[i], &hi_nibble); - hex_char_to_hex_nibble(encrypted_line[i + 1], &lo_nibble); - encrypted_line[i / 2] = (hi_nibble << 4) | lo_nibble; - } - len /= 2; - - if(furi_hal_crypto_decrypt( - (uint8_t*)encrypted_line, (uint8_t*)decrypted_line, len)) { - subghz_keystore_process_line(instance, decrypted_line); - } else { - FURI_LOG_E(TAG, "Decryption failed"); - result = false; - break; - } - } else { - FURI_LOG_E(TAG, "Invalid encrypted data: %s", encrypted_line); - } - } else { - subghz_keystore_process_line(instance, encrypted_line); - } - // reset line buffer - memset(decrypted_line, 0, SUBGHZ_KEYSTORE_FILE_DECRYPTED_LINE_SIZE); - memset(encrypted_line, 0, SUBGHZ_KEYSTORE_FILE_ENCRYPTED_LINE_SIZE); - encrypted_line_cursor = 0; - } else if(buffer[i] == '\r' || buffer[i] == '\n') { - // do not add line endings to the buffer - } else { - if(encrypted_line_cursor < SUBGHZ_KEYSTORE_FILE_ENCRYPTED_LINE_SIZE) { - encrypted_line[encrypted_line_cursor] = buffer[i]; - encrypted_line_cursor++; - } else { - FURI_LOG_E(TAG, "Malformed file"); - result = false; - break; - } - } - } - } while(ret > 0 && result); - - if(iv) furi_hal_crypto_store_unload_key(SUBGHZ_KEYSTORE_FILE_ENCRYPTION_KEY_SLOT); - } while(false); - - free(encrypted_line); - free(decrypted_line); - - return result; -} - -bool subghz_keystore_load(SubGhzKeystore* instance, const char* file_name) { - furi_assert(instance); - bool result = false; - uint8_t iv[16]; - uint32_t version; - uint32_t encryption; - - FuriString* filetype; - filetype = furi_string_alloc(); - - FURI_LOG_I(TAG, "Loading keystore %s", file_name); - - Storage* storage = furi_record_open(RECORD_STORAGE); - - FlipperFormat* flipper_format = flipper_format_file_alloc(storage); - do { - if(!flipper_format_file_open_existing(flipper_format, file_name)) { - FURI_LOG_E(TAG, "Unable to open file for read: %s", file_name); - break; - } - if(!flipper_format_read_header(flipper_format, filetype, &version)) { - FURI_LOG_E(TAG, "Missing or incorrect header"); - break; - } - if(!flipper_format_read_uint32(flipper_format, "Encryption", (uint32_t*)&encryption, 1)) { - FURI_LOG_E(TAG, "Missing encryption type"); - break; - } - - if(strcmp(furi_string_get_cstr(filetype), SUBGHZ_KEYSTORE_FILE_TYPE) != 0 || - version != SUBGHZ_KEYSTORE_FILE_VERSION) { - FURI_LOG_E(TAG, "Type or version mismatch"); - break; - } - - Stream* stream = flipper_format_get_raw_stream(flipper_format); - if(encryption == SubGhzKeystoreEncryptionNone) { - result = subghz_keystore_read_file(instance, stream, NULL); - } else if(encryption == SubGhzKeystoreEncryptionAES256) { - if(!flipper_format_read_hex(flipper_format, "IV", iv, 16)) { - FURI_LOG_E(TAG, "Missing IV"); - break; - } - subghz_keystore_mess_with_iv(iv); - result = subghz_keystore_read_file(instance, stream, iv); - } else { - FURI_LOG_E(TAG, "Unknown encryption"); - break; - } - } while(0); - flipper_format_free(flipper_format); - - furi_record_close(RECORD_STORAGE); - - furi_string_free(filetype); - - return result; -} - -bool subghz_keystore_save(SubGhzKeystore* instance, const char* file_name, uint8_t* iv) { - furi_assert(instance); - bool result = false; - - Storage* storage = furi_record_open(RECORD_STORAGE); - char* decrypted_line = malloc(SUBGHZ_KEYSTORE_FILE_DECRYPTED_LINE_SIZE); - char* encrypted_line = malloc(SUBGHZ_KEYSTORE_FILE_ENCRYPTED_LINE_SIZE); - - FlipperFormat* flipper_format = flipper_format_file_alloc(storage); - do { - if(!flipper_format_file_open_always(flipper_format, file_name)) { - FURI_LOG_E(TAG, "Unable to open file for write: %s", file_name); - break; - } - if(!flipper_format_write_header_cstr( - flipper_format, SUBGHZ_KEYSTORE_FILE_TYPE, SUBGHZ_KEYSTORE_FILE_VERSION)) { - FURI_LOG_E(TAG, "Unable to add header"); - break; - } - uint32_t encryption = SubGhzKeystoreEncryptionAES256; - if(!flipper_format_write_uint32(flipper_format, "Encryption", &encryption, 1)) { - FURI_LOG_E(TAG, "Unable to add Encryption"); - break; - } - if(!flipper_format_write_hex(flipper_format, "IV", iv, 16)) { - FURI_LOG_E(TAG, "Unable to add IV"); - break; - } - - subghz_keystore_mess_with_iv(iv); - - if(!furi_hal_crypto_store_load_key(SUBGHZ_KEYSTORE_FILE_ENCRYPTION_KEY_SLOT, iv)) { - FURI_LOG_E(TAG, "Unable to load encryption key"); - break; - } - - Stream* stream = flipper_format_get_raw_stream(flipper_format); - size_t encrypted_line_count = 0; - for - M_EACH(key, instance->data, SubGhzKeyArray_t) { - // Wipe buffer before packing - memset(decrypted_line, 0, SUBGHZ_KEYSTORE_FILE_DECRYPTED_LINE_SIZE); - memset(encrypted_line, 0, SUBGHZ_KEYSTORE_FILE_ENCRYPTED_LINE_SIZE); - // Form unecreypted line - int len = snprintf( - decrypted_line, - SUBGHZ_KEYSTORE_FILE_DECRYPTED_LINE_SIZE, - "%08lX%08lX:%hu:%s", - (uint32_t)(key->key >> 32), - (uint32_t)key->key, - key->type, - furi_string_get_cstr(key->name)); - // Verify length and align - furi_assert(len > 0); - if(len % 16 != 0) { - len += (16 - len % 16); - } - furi_assert(len % 16 == 0); - furi_assert(len <= SUBGHZ_KEYSTORE_FILE_DECRYPTED_LINE_SIZE); - // Form encrypted line - if(!furi_hal_crypto_encrypt( - (uint8_t*)decrypted_line, (uint8_t*)encrypted_line, len)) { - FURI_LOG_E(TAG, "Encryption failed"); - break; - } - // HEX Encode encrypted line - const char xx[] = "0123456789ABCDEF"; - for(int i = 0; i < len; i++) { - size_t cursor = len - i - 1; - size_t hex_cursor = len * 2 - i * 2 - 1; - encrypted_line[hex_cursor] = xx[encrypted_line[cursor] & 0xF]; - encrypted_line[hex_cursor - 1] = xx[(encrypted_line[cursor] >> 4) & 0xF]; - } - stream_write_cstring(stream, encrypted_line); - stream_write_char(stream, '\n'); - encrypted_line_count++; - } - furi_hal_crypto_store_unload_key(SUBGHZ_KEYSTORE_FILE_ENCRYPTION_KEY_SLOT); - size_t total_keys = SubGhzKeyArray_size(instance->data); - result = encrypted_line_count == total_keys; - if(result) { - FURI_LOG_I(TAG, "Success. Encrypted: %zu of %zu", encrypted_line_count, total_keys); - } else { - FURI_LOG_E(TAG, "Failure. Encrypted: %zu of %zu", encrypted_line_count, total_keys); - } - } while(0); - flipper_format_free(flipper_format); - - free(encrypted_line); - free(decrypted_line); - furi_record_close(RECORD_STORAGE); - - return result; -} - -SubGhzKeyArray_t* subghz_keystore_get_data(SubGhzKeystore* instance) { - furi_assert(instance); - return &instance->data; -} - -bool subghz_keystore_raw_encrypted_save( - const char* input_file_name, - const char* output_file_name, - uint8_t* iv) { - bool encrypted = false; - uint32_t version; - uint32_t encryption; - FuriString* filetype; - filetype = furi_string_alloc(); - - Storage* storage = furi_record_open(RECORD_STORAGE); - - char* encrypted_line = malloc(SUBGHZ_KEYSTORE_FILE_ENCRYPTED_LINE_SIZE); - - FlipperFormat* input_flipper_format = flipper_format_file_alloc(storage); - do { - if(!flipper_format_file_open_existing(input_flipper_format, input_file_name)) { - FURI_LOG_E(TAG, "Unable to open file for read: %s", input_file_name); - break; - } - if(!flipper_format_read_header(input_flipper_format, filetype, &version)) { - FURI_LOG_E(TAG, "Missing or incorrect header"); - break; - } - if(!flipper_format_read_uint32( - input_flipper_format, "Encryption", (uint32_t*)&encryption, 1)) { - FURI_LOG_E(TAG, "Missing encryption type"); - break; - } - - if(strcmp(furi_string_get_cstr(filetype), SUBGHZ_KEYSTORE_FILE_RAW_TYPE) != 0 || - version != SUBGHZ_KEYSTORE_FILE_VERSION) { - FURI_LOG_E(TAG, "Type or version mismatch"); - break; - } - - if(encryption != SubGhzKeystoreEncryptionNone) { - FURI_LOG_E(TAG, "Already encryption"); - break; - } - Stream* input_stream = flipper_format_get_raw_stream(input_flipper_format); - - FlipperFormat* output_flipper_format = flipper_format_file_alloc(storage); - - if(!flipper_format_file_open_always(output_flipper_format, output_file_name)) { - FURI_LOG_E(TAG, "Unable to open file for write: %s", output_file_name); - break; - } - if(!flipper_format_write_header_cstr( - output_flipper_format, - furi_string_get_cstr(filetype), - SUBGHZ_KEYSTORE_FILE_VERSION)) { - FURI_LOG_E(TAG, "Unable to add header"); - break; - } - uint32_t encryption = SubGhzKeystoreEncryptionAES256; - if(!flipper_format_write_uint32(output_flipper_format, "Encryption", &encryption, 1)) { - FURI_LOG_E(TAG, "Unable to add Encryption"); - break; - } - if(!flipper_format_write_hex(output_flipper_format, "IV", iv, 16)) { - FURI_LOG_E(TAG, "Unable to add IV"); - break; - } - - if(!flipper_format_write_string_cstr(output_flipper_format, "Encrypt_data", "RAW")) { - FURI_LOG_E(TAG, "Unable to add Encrypt_data"); - break; - } - - subghz_keystore_mess_with_iv(iv); - - if(!furi_hal_crypto_store_load_key(SUBGHZ_KEYSTORE_FILE_ENCRYPTION_KEY_SLOT, iv)) { - FURI_LOG_E(TAG, "Unable to load encryption key"); - break; - } - - Stream* output_stream = flipper_format_get_raw_stream(output_flipper_format); - uint8_t buffer[FILE_BUFFER_SIZE]; - bool result = true; - - size_t ret = 0; - furi_assert(FILE_BUFFER_SIZE % 16 == 0); - - //skip the end of the previous line "\n" - stream_read(input_stream, buffer, 1); - - do { - memset(buffer, 0, FILE_BUFFER_SIZE); - ret = stream_read(input_stream, buffer, FILE_BUFFER_SIZE); - if(ret == 0) { - break; - } - - for(uint16_t i = 0; i < FILE_BUFFER_SIZE - 1; i += 2) { - uint8_t hi_nibble = 0; - uint8_t lo_nibble = 0; - hex_char_to_hex_nibble(buffer[i], &hi_nibble); - hex_char_to_hex_nibble(buffer[i + 1], &lo_nibble); - buffer[i / 2] = (hi_nibble << 4) | lo_nibble; - } - - memset(encrypted_line, 0, SUBGHZ_KEYSTORE_FILE_ENCRYPTED_LINE_SIZE); - // Form encrypted line - if(!furi_hal_crypto_encrypt( - (uint8_t*)buffer, (uint8_t*)encrypted_line, FILE_BUFFER_SIZE / 2)) { - FURI_LOG_E(TAG, "Encryption failed"); - result = false; - break; - } - - // HEX Encode encrypted line - const char xx[] = "0123456789ABCDEF"; - for(size_t i = 0; i < FILE_BUFFER_SIZE / 2; i++) { - size_t cursor = FILE_BUFFER_SIZE / 2 - i - 1; - size_t hex_cursor = FILE_BUFFER_SIZE - i * 2 - 1; - encrypted_line[hex_cursor] = xx[encrypted_line[cursor] & 0xF]; - encrypted_line[hex_cursor - 1] = xx[(encrypted_line[cursor] >> 4) & 0xF]; - } - stream_write_cstring(output_stream, encrypted_line); - - } while(true); - - flipper_format_free(output_flipper_format); - - furi_hal_crypto_store_unload_key(SUBGHZ_KEYSTORE_FILE_ENCRYPTION_KEY_SLOT); - - if(!result) break; - - encrypted = true; - } while(0); - - flipper_format_free(input_flipper_format); - - free(encrypted_line); - - furi_record_close(RECORD_STORAGE); - - return encrypted; -} - -bool subghz_keystore_raw_get_data(const char* file_name, size_t offset, uint8_t* data, size_t len) { - bool result = false; - uint8_t iv[16]; - uint32_t version; - uint32_t encryption; - - FuriString* str_temp; - str_temp = furi_string_alloc(); - - Storage* storage = furi_record_open(RECORD_STORAGE); - char* decrypted_line = malloc(SUBGHZ_KEYSTORE_FILE_DECRYPTED_LINE_SIZE); - - FlipperFormat* flipper_format = flipper_format_file_alloc(storage); - do { - if(!flipper_format_file_open_existing(flipper_format, file_name)) { - FURI_LOG_E(TAG, "Unable to open file for read: %s", file_name); - break; - } - if(!flipper_format_read_header(flipper_format, str_temp, &version)) { - FURI_LOG_E(TAG, "Missing or incorrect header"); - break; - } - if(!flipper_format_read_uint32(flipper_format, "Encryption", (uint32_t*)&encryption, 1)) { - FURI_LOG_E(TAG, "Missing encryption type"); - break; - } - - if(strcmp(furi_string_get_cstr(str_temp), SUBGHZ_KEYSTORE_FILE_RAW_TYPE) != 0 || - version != SUBGHZ_KEYSTORE_FILE_VERSION) { - FURI_LOG_E(TAG, "Type or version mismatch"); - break; - } - - Stream* stream = flipper_format_get_raw_stream(flipper_format); - if(encryption != SubGhzKeystoreEncryptionAES256) { - FURI_LOG_E(TAG, "Unknown encryption"); - break; - } - - if(offset < 16) { - if(!flipper_format_read_hex(flipper_format, "IV", iv, 16)) { - FURI_LOG_E(TAG, "Missing IV"); - break; - } - subghz_keystore_mess_with_iv(iv); - } - - if(!flipper_format_read_string(flipper_format, "Encrypt_data", str_temp)) { - FURI_LOG_E(TAG, "Missing Encrypt_data"); - break; - } - - size_t bufer_size; - if(len <= (16 - offset % 16)) { - bufer_size = 32; - } else { - bufer_size = (((len) / 16) + 2) * 32; - } - furi_assert(SUBGHZ_KEYSTORE_FILE_DECRYPTED_LINE_SIZE >= bufer_size / 2); - - uint8_t buffer[bufer_size]; - size_t ret = 0; - bool decrypted = true; - //skip the end of the previous line "\n" - stream_read(stream, buffer, 1); - - size_t size = stream_size(stream); - size -= stream_tell(stream); - if(size < (offset * 2 + len * 2)) { - FURI_LOG_E(TAG, "Seek position exceeds file size"); - break; - } - - if(offset >= 16) { - stream_seek(stream, ((offset / 16) - 1) * 32, StreamOffsetFromCurrent); - ret = stream_read(stream, buffer, 32); - furi_assert(ret == 32); - for(uint16_t i = 0; i < ret - 1; i += 2) { - uint8_t hi_nibble = 0; - uint8_t lo_nibble = 0; - hex_char_to_hex_nibble(buffer[i], &hi_nibble); - hex_char_to_hex_nibble(buffer[i + 1], &lo_nibble); - iv[i / 2] = (hi_nibble << 4) | lo_nibble; - } - } - - if(!furi_hal_crypto_store_load_key(SUBGHZ_KEYSTORE_FILE_ENCRYPTION_KEY_SLOT, iv)) { - FURI_LOG_E(TAG, "Unable to load encryption key"); - break; - } - - do { - memset(buffer, 0, bufer_size); - ret = stream_read(stream, buffer, bufer_size); - furi_assert(ret == bufer_size); - for(uint16_t i = 0; i < ret - 1; i += 2) { - uint8_t hi_nibble = 0; - uint8_t lo_nibble = 0; - hex_char_to_hex_nibble(buffer[i], &hi_nibble); - hex_char_to_hex_nibble(buffer[i + 1], &lo_nibble); - buffer[i / 2] = (hi_nibble << 4) | lo_nibble; - } - - memset(decrypted_line, 0, SUBGHZ_KEYSTORE_FILE_DECRYPTED_LINE_SIZE); - - if(!furi_hal_crypto_decrypt( - (uint8_t*)buffer, (uint8_t*)decrypted_line, bufer_size / 2)) { - decrypted = false; - FURI_LOG_E(TAG, "Decryption failed"); - break; - } - memcpy(data, (uint8_t*)decrypted_line + (offset - (offset / 16) * 16), len); - - } while(0); - furi_hal_crypto_store_unload_key(SUBGHZ_KEYSTORE_FILE_ENCRYPTION_KEY_SLOT); - if(decrypted) result = true; - } while(0); - flipper_format_free(flipper_format); - - furi_record_close(RECORD_STORAGE); - - free(decrypted_line); - - furi_string_free(str_temp); - - return result; -} diff --git a/applications/main/subghz/subghz_keystore.h b/applications/main/subghz/subghz_keystore.h deleted file mode 100644 index 06ae8adae..000000000 --- a/applications/main/subghz/subghz_keystore.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - FuriString* name; - uint64_t key; - uint16_t type; -} SubGhzKey; - -ARRAY_DEF(SubGhzKeyArray, SubGhzKey, M_POD_OPLIST) - -#define M_OPL_SubGhzKeyArray_t() ARRAY_OPLIST(SubGhzKeyArray, M_POD_OPLIST) - -typedef struct SubGhzKeystore SubGhzKeystore; - -/** - * Allocate SubGhzKeystore. - * @return SubGhzKeystore* pointer to a SubGhzKeystore instance - */ -SubGhzKeystore* subghz_keystore_alloc(); - -/** - * Free SubGhzKeystore. - * @param instance Pointer to a SubGhzKeystore instance - */ -void subghz_keystore_free(SubGhzKeystore* instance); - -/** - * Loading manufacture key from file - * @param instance Pointer to a SubGhzKeystore instance - * @param filename Full path to the file - */ -bool subghz_keystore_load(SubGhzKeystore* instance, const char* filename); - -/** - * Save manufacture key to file - * @param instance Pointer to a SubGhzKeystore instance - * @param filename Full path to the file - * @return true On success - */ -bool subghz_keystore_save(SubGhzKeystore* instance, const char* filename, uint8_t* iv); - -/** - * Get array of keys and names manufacture - * @param instance Pointer to a SubGhzKeystore instance - * @return SubGhzKeyArray_t* - */ -SubGhzKeyArray_t* subghz_keystore_get_data(SubGhzKeystore* instance); - -/** - * Save RAW encrypted to file - * @param input_file_name Full path to the input file - * @param output_file_name Full path to the output file - * @param iv IV, 16 bytes in hex - */ -bool subghz_keystore_raw_encrypted_save( - const char* input_file_name, - const char* output_file_name, - uint8_t* iv); - -/** - * Get decrypt RAW data to file - * @param file_name Full path to the input file - * @param offset Offset from the start of the RAW data - * @param data Returned array - * @param len Required data length - * @return true On success - */ -bool subghz_keystore_raw_get_data(const char* file_name, size_t offset, uint8_t* data, size_t len); - -#ifdef __cplusplus -} -#endif diff --git a/applications/main/subghz/subghz_setting.c b/applications/main/subghz/subghz_setting.c deleted file mode 100644 index 35ba54a8a..000000000 --- a/applications/main/subghz/subghz_setting.c +++ /dev/null @@ -1,480 +0,0 @@ -#include "subghz_setting.h" -#include "types.h" -//#include "subghz_i.h" - -#include -#include -#include - -#define TAG "SubGhzSetting" - -#define SUBGHZ_SETTING_FILE_TYPE "Flipper SubGhz Setting File" -#define SUBGHZ_SETTING_FILE_VERSION 1 - -#define FREQUENCY_FLAG_DEFAULT (1 << 31) -#define FREQUENCY_MASK (0xFFFFFFFF ^ FREQUENCY_FLAG_DEFAULT) - -/* Default */ -static const uint32_t subghz_frequency_list[] = { - /* 300 - 348 */ - 300000000, - 302757000, - 303875000, - 304250000, - 307000000, - 307500000, - 307800000, - 309000000, - 310000000, - 312000000, - 312100000, - 312200000, - 313000000, - 313850000, - 314000000, - 314350000, - 314980000, - 315000000, - 318000000, - 330000000, - 345000000, - 348000000, - 350000000, - - /* 387 - 464 */ - 387000000, - 390000000, - 418000000, - 433075000, /* LPD433 first */ - 433220000, - 433420000, - 433657070, - 433889000, - 433920000 | FREQUENCY_FLAG_DEFAULT, /* LPD433 mid */ - 434075000, - 434176948, - 434190000, - 434390000, - 434420000, - 434620000, - 434775000, /* LPD433 last channels */ - 438900000, - 440175000, - 464000000, - - /* 779 - 928 */ - 779000000, - 868350000, - 868400000, - 868800000, - 868950000, - 906400000, - 915000000, - 925000000, - 928000000, - 0, -}; - -static const uint32_t subghz_hopper_frequency_list[] = { - 315000000, - 330000000, - 390000000, - 433420000, - 433920000, - 868350000, - 0, -}; - -typedef struct { - FuriString* custom_preset_name; - uint8_t* custom_preset_data; - size_t custom_preset_data_size; -} SubGhzSettingCustomPresetItem; - -ARRAY_DEF(SubGhzSettingCustomPresetItemArray, SubGhzSettingCustomPresetItem, M_POD_OPLIST) - -#define M_OPL_SubGhzSettingCustomPresetItemArray_t() \ - ARRAY_OPLIST(SubGhzSettingCustomPresetItemArray, M_POD_OPLIST) - -LIST_DEF(FrequencyList, uint32_t) - -#define M_OPL_FrequencyList_t() LIST_OPLIST(FrequencyList) - -typedef struct { - SubGhzSettingCustomPresetItemArray_t data; -} SubGhzSettingCustomPresetStruct; - -struct SubGhzSetting { - FrequencyList_t frequencies; - FrequencyList_t hopper_frequencies; - SubGhzSettingCustomPresetStruct* preset; -}; - -SubGhzSetting* subghz_setting_alloc(void) { - SubGhzSetting* instance = malloc(sizeof(SubGhzSetting)); - FrequencyList_init(instance->frequencies); - FrequencyList_init(instance->hopper_frequencies); - instance->preset = malloc(sizeof(SubGhzSettingCustomPresetStruct)); - SubGhzSettingCustomPresetItemArray_init(instance->preset->data); - return instance; -} - -static void subghz_setting_preset_reset(SubGhzSetting* instance) { - for - M_EACH(item, instance->preset->data, SubGhzSettingCustomPresetItemArray_t) { - furi_string_free(item->custom_preset_name); - free(item->custom_preset_data); - } - SubGhzSettingCustomPresetItemArray_reset(instance->preset->data); -} - -void subghz_setting_free(SubGhzSetting* instance) { - furi_assert(instance); - FrequencyList_clear(instance->frequencies); - FrequencyList_clear(instance->hopper_frequencies); - for - M_EACH(item, instance->preset->data, SubGhzSettingCustomPresetItemArray_t) { - furi_string_free(item->custom_preset_name); - free(item->custom_preset_data); - } - SubGhzSettingCustomPresetItemArray_clear(instance->preset->data); - free(instance->preset); - free(instance); -} - -static void subghz_setting_load_default_preset( - SubGhzSetting* instance, - const char* preset_name, - const uint8_t* preset_data, - const uint8_t preset_pa_table[8]) { - furi_assert(instance); - furi_assert(preset_data); - uint32_t preset_data_count = 0; - SubGhzSettingCustomPresetItem* item = - SubGhzSettingCustomPresetItemArray_push_raw(instance->preset->data); - - item->custom_preset_name = furi_string_alloc(); - furi_string_set(item->custom_preset_name, preset_name); - - while(preset_data[preset_data_count]) { - preset_data_count += 2; - } - preset_data_count += 2; - item->custom_preset_data_size = sizeof(uint8_t) * preset_data_count + sizeof(uint8_t) * 8; - item->custom_preset_data = malloc(item->custom_preset_data_size); - //load preset register - memcpy(&item->custom_preset_data[0], &preset_data[0], preset_data_count); - //load pa table - memcpy(&item->custom_preset_data[preset_data_count], &preset_pa_table[0], 8); -} - -static void subghz_setting_load_default_region( - SubGhzSetting* instance, - const uint32_t frequencies[], - const uint32_t hopper_frequencies[]) { - furi_assert(instance); - - FrequencyList_reset(instance->frequencies); - FrequencyList_reset(instance->hopper_frequencies); - subghz_setting_preset_reset(instance); - - while(*frequencies) { - FrequencyList_push_back(instance->frequencies, *frequencies); - frequencies++; - } - - while(*hopper_frequencies) { - FrequencyList_push_back(instance->hopper_frequencies, *hopper_frequencies); - hopper_frequencies++; - } - - subghz_setting_load_default_preset( - instance, - "AM270", - (uint8_t*)furi_hal_subghz_preset_ook_270khz_async_regs, - furi_hal_subghz_preset_ook_async_patable); - subghz_setting_load_default_preset( - instance, - "AM650", - (uint8_t*)furi_hal_subghz_preset_ook_650khz_async_regs, - furi_hal_subghz_preset_ook_async_patable); - subghz_setting_load_default_preset( - instance, - "FM238", - (uint8_t*)furi_hal_subghz_preset_2fsk_dev2_38khz_async_regs, - furi_hal_subghz_preset_2fsk_async_patable); - subghz_setting_load_default_preset( - instance, - "FM476", - (uint8_t*)furi_hal_subghz_preset_2fsk_dev47_6khz_async_regs, - furi_hal_subghz_preset_2fsk_async_patable); -} - -// Region check removed -void subghz_setting_load_default(SubGhzSetting* instance) { - subghz_setting_load_default_region( - instance, subghz_frequency_list, subghz_hopper_frequency_list); -} - -void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { - furi_assert(instance); - - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); - - FuriString* temp_str; - temp_str = furi_string_alloc(); - uint32_t temp_data32; - bool temp_bool; - - subghz_setting_load_default(instance); - - if(file_path) { - do { - if(!flipper_format_file_open_existing(fff_data_file, file_path)) { - FURI_LOG_I(TAG, "File is not used %s", file_path); - break; - } - - if(!flipper_format_read_header(fff_data_file, temp_str, &temp_data32)) { - FURI_LOG_E(TAG, "Missing or incorrect header"); - break; - } - - if((!strcmp(furi_string_get_cstr(temp_str), SUBGHZ_SETTING_FILE_TYPE)) && - temp_data32 == SUBGHZ_SETTING_FILE_VERSION) { - } else { - FURI_LOG_E(TAG, "Type or version mismatch"); - break; - } - - // Standard frequencies (optional) - temp_bool = true; - flipper_format_read_bool(fff_data_file, "Add_standard_frequencies", &temp_bool, 1); - if(!temp_bool) { - FURI_LOG_I(TAG, "Removing standard frequencies"); - FrequencyList_reset(instance->frequencies); - FrequencyList_reset(instance->hopper_frequencies); - } else { - FURI_LOG_I(TAG, "Keeping standard frequencies"); - } - - // Load frequencies - if(!flipper_format_rewind(fff_data_file)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - while(flipper_format_read_uint32( - fff_data_file, "Frequency", (uint32_t*)&temp_data32, 1)) { - if(furi_hal_subghz_is_frequency_valid(temp_data32)) { - FURI_LOG_I(TAG, "Frequency loaded %lu", temp_data32); - FrequencyList_push_back(instance->frequencies, temp_data32); - } else { - FURI_LOG_E(TAG, "Frequency not supported %lu", temp_data32); - } - } - - // Load hopper frequencies - if(!flipper_format_rewind(fff_data_file)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - while(flipper_format_read_uint32( - fff_data_file, "Hopper_frequency", (uint32_t*)&temp_data32, 1)) { - if(furi_hal_subghz_is_frequency_valid(temp_data32)) { - FURI_LOG_I(TAG, "Hopper frequency loaded %lu", temp_data32); - FrequencyList_push_back(instance->hopper_frequencies, temp_data32); - } else { - FURI_LOG_E(TAG, "Hopper frequency not supported %lu", temp_data32); - } - } - - // Default frequency (optional) - if(!flipper_format_rewind(fff_data_file)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - if(flipper_format_read_uint32(fff_data_file, "Default_frequency", &temp_data32, 1)) { - subghz_setting_set_default_frequency(instance, temp_data32); - } - - // custom preset (optional) - if(!flipper_format_rewind(fff_data_file)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - while(flipper_format_read_string(fff_data_file, "Custom_preset_name", temp_str)) { - FURI_LOG_I(TAG, "Custom preset loaded %s", furi_string_get_cstr(temp_str)); - subghz_setting_load_custom_preset( - instance, furi_string_get_cstr(temp_str), fff_data_file); - } - - } while(false); - } - - furi_string_free(temp_str); - flipper_format_free(fff_data_file); - furi_record_close(RECORD_STORAGE); - - if(!FrequencyList_size(instance->frequencies) || - !FrequencyList_size(instance->hopper_frequencies)) { - FURI_LOG_E(TAG, "Error loading user settings, loading default settings"); - subghz_setting_load_default(instance); - } -} - -void subghz_setting_set_default_frequency(SubGhzSetting* instance, uint32_t frequency_to_setup) { - for - M_EACH(frequency, instance->frequencies, FrequencyList_t) { - *frequency &= FREQUENCY_MASK; - if(*frequency == frequency_to_setup) { - *frequency |= FREQUENCY_FLAG_DEFAULT; - } - } -} - -size_t subghz_setting_get_frequency_count(SubGhzSetting* instance) { - furi_assert(instance); - return FrequencyList_size(instance->frequencies); -} - -size_t subghz_setting_get_hopper_frequency_count(SubGhzSetting* instance) { - furi_assert(instance); - return FrequencyList_size(instance->hopper_frequencies); -} - -size_t subghz_setting_get_preset_count(SubGhzSetting* instance) { - furi_assert(instance); - return SubGhzSettingCustomPresetItemArray_size(instance->preset->data); -} - -const char* subghz_setting_get_preset_name(SubGhzSetting* instance, size_t idx) { - furi_assert(instance); - if(idx >= SubGhzSettingCustomPresetItemArray_size(instance->preset->data)) { - idx = 0; - } - SubGhzSettingCustomPresetItem* item = - SubGhzSettingCustomPresetItemArray_get(instance->preset->data, idx); - return furi_string_get_cstr(item->custom_preset_name); -} - -int subghz_setting_get_inx_preset_by_name(SubGhzSetting* instance, const char* preset_name) { - furi_assert(instance); - size_t idx = 0; - for - M_EACH(item, instance->preset->data, SubGhzSettingCustomPresetItemArray_t) { - if(strcmp(furi_string_get_cstr(item->custom_preset_name), preset_name) == 0) { - return idx; - } - idx++; - } - furi_crash("SubGhz: No name preset."); - return -1; -} - -bool subghz_setting_load_custom_preset( - SubGhzSetting* instance, - const char* preset_name, - FlipperFormat* fff_data_file) { - furi_assert(instance); - furi_assert(preset_name); - uint32_t temp_data32; - SubGhzSettingCustomPresetItem* item = - SubGhzSettingCustomPresetItemArray_push_raw(instance->preset->data); - item->custom_preset_name = furi_string_alloc(); - furi_string_set(item->custom_preset_name, preset_name); - do { - if(!flipper_format_get_value_count(fff_data_file, "Custom_preset_data", &temp_data32)) - break; - if(!temp_data32 || (temp_data32 % 2)) { - FURI_LOG_E(TAG, "Integrity error Custom_preset_data"); - break; - } - item->custom_preset_data_size = sizeof(uint8_t) * temp_data32; - item->custom_preset_data = malloc(item->custom_preset_data_size); - if(!flipper_format_read_hex( - fff_data_file, - "Custom_preset_data", - item->custom_preset_data, - item->custom_preset_data_size)) { - FURI_LOG_E(TAG, "Missing Custom_preset_data"); - break; - } - return true; - } while(true); - return false; -} - -bool subghz_setting_delete_custom_preset(SubGhzSetting* instance, const char* preset_name) { - furi_assert(instance); - furi_assert(preset_name); - SubGhzSettingCustomPresetItemArray_it_t it; - SubGhzSettingCustomPresetItemArray_it_last(it, instance->preset->data); - while(!SubGhzSettingCustomPresetItemArray_end_p(it)) { - SubGhzSettingCustomPresetItem* item = SubGhzSettingCustomPresetItemArray_ref(it); - if(strcmp(furi_string_get_cstr(item->custom_preset_name), preset_name) == 0) { - furi_string_free(item->custom_preset_name); - free(item->custom_preset_data); - SubGhzSettingCustomPresetItemArray_remove(instance->preset->data, it); - return true; - } - SubGhzSettingCustomPresetItemArray_previous(it); - } - return false; -} - -uint8_t* subghz_setting_get_preset_data(SubGhzSetting* instance, size_t idx) { - furi_assert(instance); - SubGhzSettingCustomPresetItem* item = - SubGhzSettingCustomPresetItemArray_get(instance->preset->data, idx); - return item->custom_preset_data; -} - -size_t subghz_setting_get_preset_data_size(SubGhzSetting* instance, size_t idx) { - furi_assert(instance); - SubGhzSettingCustomPresetItem* item = - SubGhzSettingCustomPresetItemArray_get(instance->preset->data, idx); - return item->custom_preset_data_size; -} - -uint8_t* subghz_setting_get_preset_data_by_name(SubGhzSetting* instance, const char* preset_name) { - furi_assert(instance); - SubGhzSettingCustomPresetItem* item = SubGhzSettingCustomPresetItemArray_get( - instance->preset->data, subghz_setting_get_inx_preset_by_name(instance, preset_name)); - return item->custom_preset_data; -} - -uint32_t subghz_setting_get_frequency(SubGhzSetting* instance, size_t idx) { - furi_assert(instance); - if(idx < FrequencyList_size(instance->frequencies)) { - return (*FrequencyList_get(instance->frequencies, idx)) & FREQUENCY_MASK; - } else { - return 0; - } -} - -uint32_t subghz_setting_get_hopper_frequency(SubGhzSetting* instance, size_t idx) { - furi_assert(instance); - if(idx < FrequencyList_size(instance->frequencies)) { - return *FrequencyList_get(instance->hopper_frequencies, idx); - } else { - return 0; - } -} - -uint32_t subghz_setting_get_frequency_default_index(SubGhzSetting* instance) { - furi_assert(instance); - for(size_t i = 0; i < FrequencyList_size(instance->frequencies); i++) { - uint32_t frequency = *FrequencyList_get(instance->frequencies, i); - if(frequency & FREQUENCY_FLAG_DEFAULT) { - return i; - } - } - return 0; -} - -uint32_t subghz_setting_get_default_frequency(SubGhzSetting* instance) { - furi_assert(instance); - return subghz_setting_get_frequency( - instance, subghz_setting_get_frequency_default_index(instance)); -} diff --git a/applications/main/subghz/subghz_setting.h b/applications/main/subghz/subghz_setting.h deleted file mode 100644 index 3cb07ff6d..000000000 --- a/applications/main/subghz/subghz_setting.h +++ /dev/null @@ -1,58 +0,0 @@ - -#pragma once - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define SUBGHZ_SETTING_DEFAULT_PRESET_COUNT 4 - -typedef struct SubGhzSetting SubGhzSetting; - -SubGhzSetting* subghz_setting_alloc(void); - -void subghz_setting_free(SubGhzSetting* instance); - -void subghz_setting_load(SubGhzSetting* instance, const char* file_path); - -size_t subghz_setting_get_frequency_count(SubGhzSetting* instance); - -size_t subghz_setting_get_hopper_frequency_count(SubGhzSetting* instance); - -size_t subghz_setting_get_preset_count(SubGhzSetting* instance); - -const char* subghz_setting_get_preset_name(SubGhzSetting* instance, size_t idx); - -int subghz_setting_get_inx_preset_by_name(SubGhzSetting* instance, const char* preset_name); - -uint8_t* subghz_setting_get_preset_data(SubGhzSetting* instance, size_t idx); - -size_t subghz_setting_get_preset_data_size(SubGhzSetting* instance, size_t idx); - -uint8_t* subghz_setting_get_preset_data_by_name(SubGhzSetting* instance, const char* preset_name); - -bool subghz_setting_load_custom_preset( - SubGhzSetting* instance, - const char* preset_name, - FlipperFormat* fff_data_file); - -bool subghz_setting_delete_custom_preset(SubGhzSetting* instance, const char* preset_name); - -uint32_t subghz_setting_get_frequency(SubGhzSetting* instance, size_t idx); - -uint32_t subghz_setting_get_hopper_frequency(SubGhzSetting* instance, size_t idx); - -uint32_t subghz_setting_get_frequency_default_index(SubGhzSetting* instance); - -uint32_t subghz_setting_get_default_frequency(SubGhzSetting* instance); - -void subghz_setting_set_default_frequency(SubGhzSetting* instance, uint32_t frequency_to_setup); - -#ifdef __cplusplus -} -#endif diff --git a/applications/main/subghz/subghz_tx_rx_worker.c b/applications/main/subghz/subghz_tx_rx_worker.c deleted file mode 100644 index e380fc967..000000000 --- a/applications/main/subghz/subghz_tx_rx_worker.c +++ /dev/null @@ -1,260 +0,0 @@ -#include "subghz_tx_rx_worker.h" - -#include - -#define TAG "SubGhzTxRxWorker" - -#define SUBGHZ_TXRX_WORKER_BUF_SIZE 2048 -//you can not set more than 62 because it will not fit into the FIFO CC1101 -#define SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE 60 - -#define SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF 40 - -struct SubGhzTxRxWorker { - FuriThread* thread; - FuriStreamBuffer* stream_tx; - FuriStreamBuffer* stream_rx; - - volatile bool worker_running; - volatile bool worker_stoping; - - SubGhzTxRxWorkerStatus status; - - uint32_t frequency; - - SubGhzTxRxWorkerCallbackHaveRead callback_have_read; - void* context_have_read; -}; - -bool subghz_tx_rx_worker_write(SubGhzTxRxWorker* instance, uint8_t* data, size_t size) { - furi_assert(instance); - bool ret = false; - size_t stream_tx_free_byte = furi_stream_buffer_spaces_available(instance->stream_tx); - if(size && (stream_tx_free_byte >= size)) { - if(furi_stream_buffer_send( - instance->stream_tx, data, size, SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF) == - size) { - ret = true; - } - } - return ret; -} - -size_t subghz_tx_rx_worker_available(SubGhzTxRxWorker* instance) { - furi_assert(instance); - return furi_stream_buffer_bytes_available(instance->stream_rx); -} - -size_t subghz_tx_rx_worker_read(SubGhzTxRxWorker* instance, uint8_t* data, size_t size) { - furi_assert(instance); - return furi_stream_buffer_receive(instance->stream_rx, data, size, 0); -} - -void subghz_tx_rx_worker_set_callback_have_read( - SubGhzTxRxWorker* instance, - SubGhzTxRxWorkerCallbackHaveRead callback, - void* context) { - furi_assert(instance); - furi_assert(callback); - furi_assert(context); - instance->callback_have_read = callback; - instance->context_have_read = context; -} - -bool subghz_tx_rx_worker_rx(SubGhzTxRxWorker* instance, uint8_t* data, uint8_t* size) { - uint8_t timeout = 100; - bool ret = false; - if(instance->status != SubGhzTxRxWorkerStatusRx) { - furi_hal_subghz_rx(); - instance->status = SubGhzTxRxWorkerStatusRx; - furi_delay_tick(1); - } - //waiting for reception to complete - while(furi_hal_gpio_read(furi_hal_subghz.cc1101_g0_pin)) { - furi_delay_tick(1); - if(!--timeout) { - FURI_LOG_W(TAG, "RX cc1101_g0 timeout"); - furi_hal_subghz_flush_rx(); - furi_hal_subghz_rx(); - break; - } - } - - if(furi_hal_subghz_rx_pipe_not_empty()) { - FURI_LOG_I( - TAG, - "RSSI: %03.1fdbm LQI: %d", - (double)furi_hal_subghz_get_rssi(), - furi_hal_subghz_get_lqi()); - if(furi_hal_subghz_is_rx_data_crc_valid()) { - furi_hal_subghz_read_packet(data, size); - ret = true; - } - furi_hal_subghz_flush_rx(); - furi_hal_subghz_rx(); - } - return ret; -} - -void subghz_tx_rx_worker_tx(SubGhzTxRxWorker* instance, uint8_t* data, size_t size) { - uint8_t timeout = 200; - if(instance->status != SubGhzTxRxWorkerStatusIDLE) { - furi_hal_subghz_idle(); - } - furi_hal_subghz_write_packet(data, size); - furi_hal_subghz_tx(); //start send - instance->status = SubGhzTxRxWorkerStatusTx; - while(!furi_hal_gpio_read( - furi_hal_subghz.cc1101_g0_pin)) { // Wait for GDO0 to be set -> sync transmitted - furi_delay_tick(1); - if(!--timeout) { - FURI_LOG_W(TAG, "TX !cc1101_g0 timeout"); - break; - } - } - while(furi_hal_gpio_read( - furi_hal_subghz.cc1101_g0_pin)) { // Wait for GDO0 to be cleared -> end of packet - furi_delay_tick(1); - if(!--timeout) { - FURI_LOG_W(TAG, "TX cc1101_g0 timeout"); - break; - } - } - furi_hal_subghz_idle(); - instance->status = SubGhzTxRxWorkerStatusIDLE; -} -/** Worker thread - * - * @param context - * @return exit code - */ -static int32_t subghz_tx_rx_worker_thread(void* context) { - SubGhzTxRxWorker* instance = context; - FURI_LOG_I(TAG, "Worker start"); - - furi_hal_subghz_reset(); - furi_hal_subghz_idle(); - furi_hal_subghz_load_preset(FuriHalSubGhzPresetGFSK9_99KbAsync); - //furi_hal_subghz_load_preset(FuriHalSubGhzPresetMSK99_97KbAsync); - furi_hal_gpio_init(furi_hal_subghz.cc1101_g0_pin, GpioModeInput, GpioPullNo, GpioSpeedLow); - - furi_hal_subghz_set_frequency_and_path(instance->frequency); - furi_hal_subghz_flush_rx(); - - uint8_t data[SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE + 1] = {0}; - size_t size_tx = 0; - uint8_t size_rx[1] = {0}; - uint8_t timeout_tx = 0; - bool callback_rx = false; - - while(instance->worker_running) { - //transmit - size_tx = furi_stream_buffer_bytes_available(instance->stream_tx); - if(size_tx > 0 && !timeout_tx) { - timeout_tx = 10; //20ms - if(size_tx > SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE) { - furi_stream_buffer_receive( - instance->stream_tx, - &data, - SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE, - SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); - subghz_tx_rx_worker_tx(instance, data, SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE); - } else { - //todo checking that he managed to write all the data to the TX buffer - furi_stream_buffer_receive( - instance->stream_tx, &data, size_tx, SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); - subghz_tx_rx_worker_tx(instance, data, size_tx); - } - } else { - //recive - if(subghz_tx_rx_worker_rx(instance, data, size_rx)) { - if(furi_stream_buffer_spaces_available(instance->stream_rx) >= size_rx[0]) { - if(instance->callback_have_read && - furi_stream_buffer_bytes_available(instance->stream_rx) == 0) { - callback_rx = true; - } - //todo checking that he managed to write all the data to the RX buffer - furi_stream_buffer_send( - instance->stream_rx, - &data, - size_rx[0], - SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); - if(callback_rx) { - instance->callback_have_read(instance->context_have_read); - callback_rx = false; - } - } else { - //todo RX buffer overflow - } - } - } - - if(timeout_tx) timeout_tx--; - furi_delay_tick(1); - } - - furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); - furi_hal_subghz_sleep(); - - FURI_LOG_I(TAG, "Worker stop"); - return 0; -} - -SubGhzTxRxWorker* subghz_tx_rx_worker_alloc() { - SubGhzTxRxWorker* instance = malloc(sizeof(SubGhzTxRxWorker)); - - instance->thread = - furi_thread_alloc_ex("SubGhzTxRxWorker", 2048, subghz_tx_rx_worker_thread, instance); - instance->stream_tx = - furi_stream_buffer_alloc(sizeof(uint8_t) * SUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t)); - instance->stream_rx = - furi_stream_buffer_alloc(sizeof(uint8_t) * SUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t)); - - instance->status = SubGhzTxRxWorkerStatusIDLE; - instance->worker_stoping = true; - - return instance; -} - -void subghz_tx_rx_worker_free(SubGhzTxRxWorker* instance) { - furi_assert(instance); - furi_assert(!instance->worker_running); - furi_stream_buffer_free(instance->stream_tx); - furi_stream_buffer_free(instance->stream_rx); - furi_thread_free(instance->thread); - - free(instance); -} - -bool subghz_tx_rx_worker_start(SubGhzTxRxWorker* instance, uint32_t frequency) { - furi_assert(instance); - furi_assert(!instance->worker_running); - bool res = false; - furi_stream_buffer_reset(instance->stream_tx); - furi_stream_buffer_reset(instance->stream_rx); - - instance->worker_running = true; - - if(furi_hal_subghz_is_tx_allowed(frequency)) { - instance->frequency = frequency; - res = true; - } - - furi_thread_start(instance->thread); - - return res; -} - -void subghz_tx_rx_worker_stop(SubGhzTxRxWorker* instance) { - furi_assert(instance); - furi_assert(instance->worker_running); - - instance->worker_running = false; - - furi_thread_join(instance->thread); -} - -bool subghz_tx_rx_worker_is_running(SubGhzTxRxWorker* instance) { - furi_assert(instance); - return instance->worker_running; -} diff --git a/applications/main/subghz/subghz_tx_rx_worker.h b/applications/main/subghz/subghz_tx_rx_worker.h deleted file mode 100644 index ddc02e749..000000000 --- a/applications/main/subghz/subghz_tx_rx_worker.h +++ /dev/null @@ -1,89 +0,0 @@ -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*SubGhzTxRxWorkerCallbackHaveRead)(void* context); - -typedef struct SubGhzTxRxWorker SubGhzTxRxWorker; - -typedef enum { - SubGhzTxRxWorkerStatusIDLE, - SubGhzTxRxWorkerStatusTx, - SubGhzTxRxWorkerStatusRx, -} SubGhzTxRxWorkerStatus; - -/** - * SubGhzTxRxWorker, add data to transfer - * @param instance Pointer to a SubGhzTxRxWorker instance - * @param data *data - * @param size data size - * @return bool true if ok - */ -bool subghz_tx_rx_worker_write(SubGhzTxRxWorker* instance, uint8_t* data, size_t size); - -/** - * SubGhzTxRxWorker, get available data - * @param instance Pointer to a SubGhzTxRxWorker instance - * @return size_t data size - */ -size_t subghz_tx_rx_worker_available(SubGhzTxRxWorker* instance); - -/** - * SubGhzTxRxWorker, read data - * @param instance Pointer to a SubGhzTxRxWorker instance - * @param data *data - * @param size max data size, which can be read - * @return size_t data size, how much is actually read - */ -size_t subghz_tx_rx_worker_read(SubGhzTxRxWorker* instance, uint8_t* data, size_t size); - -/** - * Сallback SubGhzTxRxWorker when there is data to read in an empty buffer - * @param instance Pointer to a SubGhzTxRxWorker instance - * @param callback SubGhzTxRxWorkerCallbackHaveRead callback - * @param context - */ -void subghz_tx_rx_worker_set_callback_have_read( - SubGhzTxRxWorker* instance, - SubGhzTxRxWorkerCallbackHaveRead callback, - void* context); - -/** - * Allocate SubGhzTxRxWorker - * @return SubGhzTxRxWorker* Pointer to a SubGhzTxRxWorker instance - */ -SubGhzTxRxWorker* subghz_tx_rx_worker_alloc(); - -/** - * Free SubGhzTxRxWorker - * @param instance Pointer to a SubGhzTxRxWorker instance - */ -void subghz_tx_rx_worker_free(SubGhzTxRxWorker* instance); - -/** - * Start SubGhzTxRxWorker - * @param instance Pointer to a SubGhzTxRxWorker instance - * @return bool - true if ok - */ -bool subghz_tx_rx_worker_start(SubGhzTxRxWorker* instance, uint32_t frequency); - -/** - * Stop SubGhzTxRxWorker - * @param instance Pointer to a SubGhzTxRxWorker instance - */ -void subghz_tx_rx_worker_stop(SubGhzTxRxWorker* instance); - -/** - * Check if worker is running - * @param instance Pointer to a SubGhzTxRxWorker instance - * @return bool - true if running - */ -bool subghz_tx_rx_worker_is_running(SubGhzTxRxWorker* instance); - -#ifdef __cplusplus -} -#endif diff --git a/applications/main/subghz/subghz_worker.c b/applications/main/subghz/subghz_worker.c deleted file mode 100644 index 50b5aba51..000000000 --- a/applications/main/subghz/subghz_worker.c +++ /dev/null @@ -1,149 +0,0 @@ -#include "subghz_worker.h" - -#include - -#define TAG "SubGhzWorker" - -struct SubGhzWorker { - FuriThread* thread; - FuriStreamBuffer* stream; - - volatile bool running; - volatile bool overrun; - - LevelDuration filter_level_duration; - uint16_t filter_duration; - - SubGhzWorkerOverrunCallback overrun_callback; - SubGhzWorkerPairCallback pair_callback; - void* context; -}; - -/** Rx callback timer - * - * @param level received signal level - * @param duration received signal duration - * @param context - */ -void subghz_worker_rx_callback(bool level, uint32_t duration, void* context) { - SubGhzWorker* instance = context; - - LevelDuration level_duration = level_duration_make(level, duration); - if(instance->overrun) { - instance->overrun = false; - level_duration = level_duration_reset(); - } - size_t ret = - furi_stream_buffer_send(instance->stream, &level_duration, sizeof(LevelDuration), 0); - if(sizeof(LevelDuration) != ret) instance->overrun = true; -} - -/** Worker callback thread - * - * @param context - * @return exit code - */ -static int32_t subghz_worker_thread_callback(void* context) { - SubGhzWorker* instance = context; - - LevelDuration level_duration; - while(instance->running) { - int ret = furi_stream_buffer_receive( - instance->stream, &level_duration, sizeof(LevelDuration), 10); - if(ret == sizeof(LevelDuration)) { - if(level_duration_is_reset(level_duration)) { - FURI_LOG_E(TAG, "Overrun buffer"); - if(instance->overrun_callback) instance->overrun_callback(instance->context); - } else { - bool level = level_duration_get_level(level_duration); - uint32_t duration = level_duration_get_duration(level_duration); - - if((duration < instance->filter_duration) || - (instance->filter_level_duration.level == level)) { - instance->filter_level_duration.duration += duration; - - } else if(instance->filter_level_duration.level != level) { - if(instance->pair_callback) - instance->pair_callback( - instance->context, - instance->filter_level_duration.level, - instance->filter_level_duration.duration); - - instance->filter_level_duration.duration = duration; - instance->filter_level_duration.level = level; - } - } - } - } - - return 0; -} - -SubGhzWorker* subghz_worker_alloc() { - SubGhzWorker* instance = malloc(sizeof(SubGhzWorker)); - - instance->thread = - furi_thread_alloc_ex("SubGhzWorker", 2048, subghz_worker_thread_callback, instance); - - instance->stream = - furi_stream_buffer_alloc(sizeof(LevelDuration) * 4096, sizeof(LevelDuration)); - - //setting default filter in us - instance->filter_duration = 30; - - return instance; -} - -void subghz_worker_free(SubGhzWorker* instance) { - furi_assert(instance); - - furi_stream_buffer_free(instance->stream); - furi_thread_free(instance->thread); - - free(instance); -} - -void subghz_worker_set_overrun_callback( - SubGhzWorker* instance, - SubGhzWorkerOverrunCallback callback) { - furi_assert(instance); - instance->overrun_callback = callback; -} - -void subghz_worker_set_pair_callback(SubGhzWorker* instance, SubGhzWorkerPairCallback callback) { - furi_assert(instance); - instance->pair_callback = callback; -} - -void subghz_worker_set_context(SubGhzWorker* instance, void* context) { - furi_assert(instance); - instance->context = context; -} - -void subghz_worker_start(SubGhzWorker* instance) { - furi_assert(instance); - furi_assert(!instance->running); - - instance->running = true; - - furi_thread_start(instance->thread); -} - -void subghz_worker_stop(SubGhzWorker* instance) { - furi_assert(instance); - furi_assert(instance->running); - - instance->running = false; - - furi_thread_join(instance->thread); -} - -bool subghz_worker_is_running(SubGhzWorker* instance) { - furi_assert(instance); - return instance->running; -} - -void subghz_worker_set_filter(SubGhzWorker* instance, uint16_t timeout) { - furi_assert(instance); - instance->filter_duration = timeout; -} \ No newline at end of file diff --git a/applications/main/subghz/subghz_worker.h b/applications/main/subghz/subghz_worker.h deleted file mode 100644 index 657278f50..000000000 --- a/applications/main/subghz/subghz_worker.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct SubGhzWorker SubGhzWorker; - -typedef void (*SubGhzWorkerOverrunCallback)(void* context); - -typedef void (*SubGhzWorkerPairCallback)(void* context, bool level, uint32_t duration); - -void subghz_worker_rx_callback(bool level, uint32_t duration, void* context); - -/** - * Allocate SubGhzWorker. - * @return SubGhzWorker* Pointer to a SubGhzWorker instance - */ -SubGhzWorker* subghz_worker_alloc(); - -/** - * Free SubGhzWorker. - * @param instance Pointer to a SubGhzWorker instance - */ -void subghz_worker_free(SubGhzWorker* instance); - -/** - * Overrun callback SubGhzWorker. - * @param instance Pointer to a SubGhzWorker instance - * @param callback SubGhzWorkerOverrunCallback callback - */ -void subghz_worker_set_overrun_callback( - SubGhzWorker* instance, - SubGhzWorkerOverrunCallback callback); - -/** - * Pair callback SubGhzWorker. - * @param instance Pointer to a SubGhzWorker instance - * @param callback SubGhzWorkerOverrunCallback callback - */ -void subghz_worker_set_pair_callback(SubGhzWorker* instance, SubGhzWorkerPairCallback callback); - -/** - * Context callback SubGhzWorker. - * @param instance Pointer to a SubGhzWorker instance - * @param context - */ -void subghz_worker_set_context(SubGhzWorker* instance, void* context); - -/** - * Start SubGhzWorker. - * @param instance Pointer to a SubGhzWorker instance - */ -void subghz_worker_start(SubGhzWorker* instance); - -/** Stop SubGhzWorker - * @param instance Pointer to a SubGhzWorker instance - */ -void subghz_worker_stop(SubGhzWorker* instance); - -/** - * Check if worker is running. - * @param instance Pointer to a SubGhzWorker instance - * @return bool - true if running - */ -bool subghz_worker_is_running(SubGhzWorker* instance); - -/** - * Short duration filter setting. - * glues short durations into 1. The default setting is 30 us, if set to 0 the filter will be disabled - * @param instance Pointer to a SubGhzWorker instance - * @param timeout time in us - */ -void subghz_worker_set_filter(SubGhzWorker* instance, uint16_t timeout); - -#ifdef __cplusplus -} -#endif diff --git a/applications/main/subghz/transmitter.c b/applications/main/subghz/transmitter.c deleted file mode 100644 index 8507ee054..000000000 --- a/applications/main/subghz/transmitter.c +++ /dev/null @@ -1,64 +0,0 @@ -#include "transmitter.h" - -#include "protocols/base.h" -#include "registry.h" -#include "protocols/protocol_items.h" - -struct SubGhzTransmitter { - const SubGhzProtocol* protocol; - SubGhzProtocolEncoderBase* protocol_instance; -}; - -SubGhzTransmitter* - subghz_transmitter_alloc_init(SubGhzEnvironment* environment, const char* protocol_name) { - SubGhzTransmitter* instance = NULL; - const SubGhzProtocolRegistry* protocol_registry_items = - subghz_environment_get_protocol_registry(environment); - - const SubGhzProtocol* protocol = - subghz_protocol_registry_get_by_name(protocol_registry_items, protocol_name); - - if(protocol && protocol->encoder && protocol->encoder->alloc) { - instance = malloc(sizeof(SubGhzTransmitter)); - instance->protocol = protocol; - instance->protocol_instance = instance->protocol->encoder->alloc(environment); - } - return instance; -} - -void subghz_transmitter_free(SubGhzTransmitter* instance) { - furi_assert(instance); - instance->protocol->encoder->free(instance->protocol_instance); - free(instance); -} - -SubGhzProtocolEncoderBase* subghz_transmitter_get_protocol_instance(SubGhzTransmitter* instance) { - furi_assert(instance); - return instance->protocol_instance; -} - -bool subghz_transmitter_stop(SubGhzTransmitter* instance) { - furi_assert(instance); - bool ret = false; - if(instance->protocol && instance->protocol->encoder && instance->protocol->encoder->stop) { - instance->protocol->encoder->stop(instance->protocol_instance); - ret = true; - } - return ret; -} - -bool subghz_transmitter_deserialize(SubGhzTransmitter* instance, FlipperFormat* flipper_format) { - furi_assert(instance); - bool ret = false; - if(instance->protocol && instance->protocol->encoder && - instance->protocol->encoder->deserialize) { - ret = - instance->protocol->encoder->deserialize(instance->protocol_instance, flipper_format); - } - return ret; -} - -LevelDuration subghz_transmitter_yield(void* context) { - SubGhzTransmitter* instance = context; - return instance->protocol->encoder->yield(instance->protocol_instance); -} diff --git a/applications/main/subghz/transmitter.h b/applications/main/subghz/transmitter.h deleted file mode 100644 index cce98a463..000000000 --- a/applications/main/subghz/transmitter.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -#include "types.h" -#include "environment.h" -#include "protocols/base.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct SubGhzTransmitter SubGhzTransmitter; - -/** - * Allocate and init SubGhzTransmitter. - * @param environment Pointer to a SubGhzEnvironment instance - * @return SubGhzTransmitter* pointer to a SubGhzTransmitter instance - */ -SubGhzTransmitter* - subghz_transmitter_alloc_init(SubGhzEnvironment* environment, const char* protocol_name); - -/** - * Free SubGhzTransmitter. - * @param instance Pointer to a SubGhzTransmitter instance - */ -void subghz_transmitter_free(SubGhzTransmitter* instance); - -/** Get protocol instance. - * @param instance Pointer to a SubGhzTransmitter instance - */ -SubGhzProtocolEncoderBase* subghz_transmitter_get_protocol_instance(SubGhzTransmitter* instance); - -/** - * Forced transmission stop. - * @param instance Pointer to a SubGhzTransmitter instance - */ -bool subghz_transmitter_stop(SubGhzTransmitter* instance); - -/** - * Deserialize and generating an upload to send. - * @param instance Pointer to a SubGhzTransmitter instance - * @param flipper_format Pointer to a FlipperFormat instance - * @return true On success - */ -bool subghz_transmitter_deserialize(SubGhzTransmitter* instance, FlipperFormat* flipper_format); - -/** - * Getting the level and duration of the upload to be loaded into DMA. - * @param context Pointer to a SubGhzTransmitter instance - * @return LevelDuration - */ -LevelDuration subghz_transmitter_yield(void* context); - -#ifdef __cplusplus -} -#endif diff --git a/applications/main/subghz/types.h b/applications/main/subghz/types.h deleted file mode 100644 index 9d121dc3c..000000000 --- a/applications/main/subghz/types.h +++ /dev/null @@ -1,104 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include - -#include "environment.h" -#include -#include - -#define SUBGHZ_APP_FOLDER ANY_PATH("subghz") -#define SUBGHZ_RAW_FOLDER EXT_PATH("subghz") -#define SUBGHZ_APP_EXTENSION ".sub" - -#define SUBGHZ_KEY_FILE_VERSION 1 -#define SUBGHZ_KEY_FILE_TYPE "Flipper SubGhz Key File" - -#define SUBGHZ_RAW_FILE_VERSION 1 -#define SUBGHZ_RAW_FILE_TYPE "Flipper SubGhz RAW File" - -// Radio Preset -typedef struct { - FuriString* name; - uint32_t frequency; - uint8_t* data; - size_t data_size; -} SubGhzRadioPreset; - -// Allocator and Deallocator -typedef void* (*SubGhzAlloc)(SubGhzEnvironment* environment); -typedef void (*SubGhzFree)(void* context); - -// Serialize and Deserialize -typedef bool ( - *SubGhzSerialize)(void* context, FlipperFormat* flipper_format, SubGhzRadioPreset* preset); -typedef bool (*SubGhzDeserialize)(void* context, FlipperFormat* flipper_format); - -// Decoder specific -typedef void (*SubGhzDecoderFeed)(void* decoder, bool level, uint32_t duration); -typedef void (*SubGhzDecoderReset)(void* decoder); -typedef uint8_t (*SubGhzGetHashData)(void* decoder); -typedef void (*SubGhzGetString)(void* decoder, FuriString* output); - -// Encoder specific -typedef void (*SubGhzEncoderStop)(void* encoder); -typedef LevelDuration (*SubGhzEncoderYield)(void* context); - -typedef struct { - SubGhzAlloc alloc; - SubGhzFree free; - - SubGhzDecoderFeed feed; - SubGhzDecoderReset reset; - - SubGhzGetHashData get_hash_data; - SubGhzGetString get_string; - SubGhzSerialize serialize; - SubGhzDeserialize deserialize; -} SubGhzProtocolDecoder; - -typedef struct { - SubGhzAlloc alloc; - SubGhzFree free; - - SubGhzDeserialize deserialize; - SubGhzEncoderStop stop; - SubGhzEncoderYield yield; -} SubGhzProtocolEncoder; - -typedef enum { - SubGhzProtocolTypeUnknown = 0, - SubGhzProtocolTypeStatic, - SubGhzProtocolTypeDynamic, - SubGhzProtocolTypeRAW, - SubGhzProtocolWeatherStation, - SubGhzProtocolCustom, - SubGhzProtocolTypeBinRAW, -} SubGhzProtocolType; - -typedef enum { - SubGhzProtocolFlag_RAW = (1 << 0), - SubGhzProtocolFlag_Decodable = (1 << 1), - SubGhzProtocolFlag_315 = (1 << 2), - SubGhzProtocolFlag_433 = (1 << 3), - SubGhzProtocolFlag_868 = (1 << 4), - SubGhzProtocolFlag_AM = (1 << 5), - SubGhzProtocolFlag_FM = (1 << 6), - SubGhzProtocolFlag_Save = (1 << 7), - SubGhzProtocolFlag_Load = (1 << 8), - SubGhzProtocolFlag_Send = (1 << 9), - SubGhzProtocolFlag_BinRAW = (1 << 10), -} SubGhzProtocolFlag; - -typedef struct { - const char* name; - SubGhzProtocolType type; - SubGhzProtocolFlag flag; - - const SubGhzProtocolEncoder* encoder; - const SubGhzProtocolDecoder* decoder; -} SubGhzProtocol; diff --git a/lib/subghz/subghz_keystore.h b/lib/subghz/subghz_keystore.h index 06ae8adae..43f8356d0 100644 --- a/lib/subghz/subghz_keystore.h +++ b/lib/subghz/subghz_keystore.h @@ -77,4 +77,4 @@ bool subghz_keystore_raw_get_data(const char* file_name, size_t offset, uint8_t* #ifdef __cplusplus } -#endif +#endif \ No newline at end of file