[FL-1610] SubGhz: scene based application, PT save and replay (#630)

* SubGhz: scene based application
* SubGhz: encoder/decoder separation, DMA streaming, update app and cli.
* SubGhz: 2 stage async tx complete, minor cleanup
* SubGhz: 2 stage async tx complete, FIX state pin end transmit
* SubGhz: Pricenton, receive TE signal
* SubGhz: Pricenton, add save data, add load data
* SubGhz: Add Read scene, Fix pricenton save, load funtion
* SubGhz: Add Read, Receiver, SaveName scene
* SubGhz: Read and Save (pricenton)
* SubGhz: add Load scence
* SubGhz: Fix select file scene, add load scene, add transmitter view, add send tx pricenton
* SubGhz: Fix pricenton encoder, fix transmitter send
* SubGhz: modified Pricenton Encoder (added guard time at the beginning), modified CC1101 config, code refactoring
* SubGhz: Fix pricenton encoder defalut TE
* Archive: Fix path and name SubGhz
* Archive: Fix name app SubGhz
* GubGhz: Came: add Save, Load key
* GubGhz: GateTX: add Save, Load key
* GubGhz: NeroSketch: add Save, Load key
* Github: better linters triggers
* SubGhz: adding fast loading keys Archive -> Run in app
* GubGhz: KeeLog: add Save, Load key, key generation from the serial number of the meter and the button
* SubGhz: format sources and fix compilation
* FuriHal: add subghz configuration description for AGC section
* SubGhz: save only protocols that can be saved. Cleanup.
* Github: lint on pull requests

Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
Skorpionm
2021-08-12 18:42:56 +04:00
committed by GitHub
parent 37d7870e52
commit 1cfa857f98
51 changed files with 2466 additions and 671 deletions

View File

@@ -16,19 +16,26 @@
#include <furi.h>
#include <m-string.h>
typedef enum {
SubGhzProtocolTypeCame,
SubGhzProtocolTypeKeeloq,
SubGhzProtocolTypeNiceFlo,
SubGhzProtocolTypeNiceFlorS,
SubGhzProtocolTypePrinceton,
SubGhzProtocolTypeGateTX,
SubGhzProtocolTypeIDo,
SubGhzProtocolTypeFaacSLH,
SubGhzProtocolTypeNeroSketch,
SubGhzProtocolTypeStarLine,
SubGhzProtocolTypeMax,
} SubGhzProtocolType;
struct SubGhzProtocol {
SubGhzKeystore* keystore;
SubGhzProtocolCame* came;
SubGhzProtocolKeeloq* keeloq;
SubGhzProtocolNiceFlo* nice_flo;
SubGhzProtocolNiceFlorS* nice_flor_s;
SubGhzProtocolPrinceton* princeton;
SubGhzProtocolGateTX* gate_tx;
SubGhzProtocolIDo* ido;
SubGhzProtocolFaacSLH* faac_slh;
SubGhzProtocolNeroSketch* nero_sketch;
SubGhzProtocolStarLine* star_line;
SubGhzProtocolCommon* protocols[SubGhzProtocolTypeMax];
SubGhzProtocolTextCallback text_callback;
void* text_callback_context;
@@ -62,16 +69,16 @@ SubGhzProtocol* subghz_protocol_alloc() {
instance->keystore = subghz_keystore_alloc();
instance->came = subghz_protocol_came_alloc();
instance->keeloq = subghz_protocol_keeloq_alloc(instance->keystore);
instance->princeton = subghz_protocol_princeton_alloc();
instance->nice_flo = subghz_protocol_nice_flo_alloc();
instance->nice_flor_s = subghz_protocol_nice_flor_s_alloc();
instance->gate_tx = subghz_protocol_gate_tx_alloc();
instance->ido = subghz_protocol_ido_alloc();
instance->faac_slh = subghz_protocol_faac_slh_alloc();
instance->nero_sketch = subghz_protocol_nero_sketch_alloc();
instance->star_line = subghz_protocol_star_line_alloc(instance->keystore);
instance->protocols[SubGhzProtocolTypeCame] =(SubGhzProtocolCommon*)subghz_protocol_came_alloc();
instance->protocols[SubGhzProtocolTypeKeeloq] = (SubGhzProtocolCommon*)subghz_protocol_keeloq_alloc(instance->keystore);
instance->protocols[SubGhzProtocolTypePrinceton] = (SubGhzProtocolCommon*)subghz_decoder_princeton_alloc();
instance->protocols[SubGhzProtocolTypeNiceFlo] = (SubGhzProtocolCommon*)subghz_protocol_nice_flo_alloc();
instance->protocols[SubGhzProtocolTypeNiceFlorS] = (SubGhzProtocolCommon*)subghz_protocol_nice_flor_s_alloc();
instance->protocols[SubGhzProtocolTypeGateTX] = (SubGhzProtocolCommon*)subghz_protocol_gate_tx_alloc();
instance->protocols[SubGhzProtocolTypeIDo] = (SubGhzProtocolCommon*)subghz_protocol_ido_alloc();
instance->protocols[SubGhzProtocolTypeFaacSLH] = (SubGhzProtocolCommon*)subghz_protocol_faac_slh_alloc();
instance->protocols[SubGhzProtocolTypeNeroSketch] = (SubGhzProtocolCommon*)subghz_protocol_nero_sketch_alloc();
instance->protocols[SubGhzProtocolTypeStarLine] = (SubGhzProtocolCommon*)subghz_protocol_star_line_alloc(instance->keystore);
return instance;
}
@@ -79,35 +86,41 @@ SubGhzProtocol* subghz_protocol_alloc() {
void subghz_protocol_free(SubGhzProtocol* instance) {
furi_assert(instance);
subghz_protocol_came_free(instance->came);
subghz_protocol_keeloq_free(instance->keeloq);
subghz_protocol_princeton_free(instance->princeton);
subghz_protocol_nice_flo_free(instance->nice_flo);
subghz_protocol_nice_flor_s_free(instance->nice_flor_s);
subghz_protocol_gate_tx_free(instance->gate_tx);
subghz_protocol_ido_free(instance->ido);
subghz_protocol_faac_slh_free(instance->faac_slh);
subghz_protocol_nero_sketch_free(instance->nero_sketch);
subghz_protocol_star_line_free(instance->star_line);
subghz_protocol_came_free((SubGhzProtocolCame*)instance->protocols[SubGhzProtocolTypeCame]);
subghz_protocol_keeloq_free((SubGhzProtocolKeeloq*)instance->protocols[SubGhzProtocolTypeKeeloq]);
subghz_decoder_princeton_free((SubGhzDecoderPrinceton*)instance->protocols[SubGhzProtocolTypePrinceton]);
subghz_protocol_nice_flo_free((SubGhzProtocolNiceFlo*)instance->protocols[SubGhzProtocolTypeNiceFlo]);
subghz_protocol_nice_flor_s_free((SubGhzProtocolNiceFlorS*)instance->protocols[SubGhzProtocolTypeNiceFlorS]);
subghz_protocol_gate_tx_free((SubGhzProtocolGateTX*)instance->protocols[SubGhzProtocolTypeGateTX]);
subghz_protocol_ido_free((SubGhzProtocolIDo*)instance->protocols[SubGhzProtocolTypeIDo]);
subghz_protocol_faac_slh_free((SubGhzProtocolFaacSLH*)instance->protocols[SubGhzProtocolTypeFaacSLH]);
subghz_protocol_nero_sketch_free((SubGhzProtocolNeroSketch*)instance->protocols[SubGhzProtocolTypeNeroSketch]);
subghz_protocol_star_line_free((SubGhzProtocolStarLine*)instance->protocols[SubGhzProtocolTypeStarLine]);
subghz_keystore_free(instance->keystore);
free(instance);
}
SubGhzProtocolCommon* subghz_protocol_get_by_name(SubGhzProtocol* instance, const char* name) {
SubGhzProtocolCommon* result = NULL;
for(size_t i = 0; i < SubGhzProtocolTypeMax; i++) {
if(strcmp(instance->protocols[i]->name, name) == 0) {
result = instance->protocols[i];
break;
}
}
return result;
}
void subghz_protocol_enable_dump_text(SubGhzProtocol* instance, SubGhzProtocolTextCallback callback, void* context) {
furi_assert(instance);
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->came, subghz_protocol_text_rx_callback, instance);
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->keeloq, subghz_protocol_text_rx_callback, instance);
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->princeton, subghz_protocol_text_rx_callback, instance);
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->nice_flo, subghz_protocol_text_rx_callback, instance);
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->nice_flor_s, subghz_protocol_text_rx_callback, instance);
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->gate_tx, subghz_protocol_text_rx_callback, instance);
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->ido, subghz_protocol_text_rx_callback, instance);
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->faac_slh, subghz_protocol_text_rx_callback, instance);
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->nero_sketch, subghz_protocol_text_rx_callback, instance);
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->star_line, subghz_protocol_text_rx_callback, instance);
for(size_t i = 0; i < SubGhzProtocolTypeMax; i++) {
subghz_protocol_common_set_callback(instance->protocols[i], subghz_protocol_text_rx_callback, instance);
}
instance->text_callback = callback;
instance->text_callback_context = context;
@@ -116,24 +129,18 @@ void subghz_protocol_enable_dump_text(SubGhzProtocol* instance, SubGhzProtocolTe
void subghz_protocol_enable_dump(SubGhzProtocol* instance, SubGhzProtocolCommonCallbackDump callback, void* context) {
furi_assert(instance);
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->came, subghz_protocol_parser_rx_callback, instance);
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->keeloq, subghz_protocol_parser_rx_callback, instance);
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->princeton, subghz_protocol_parser_rx_callback, instance);
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->nice_flo, subghz_protocol_parser_rx_callback, instance);
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->nice_flor_s, subghz_protocol_parser_rx_callback, instance);
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->gate_tx, subghz_protocol_parser_rx_callback, instance);
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->ido, subghz_protocol_parser_rx_callback, instance);
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->faac_slh, subghz_protocol_parser_rx_callback, instance);
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->nero_sketch, subghz_protocol_parser_rx_callback, instance);
subghz_protocol_common_set_callback((SubGhzProtocolCommon*)instance->star_line, subghz_protocol_parser_rx_callback, instance);
for(size_t i = 0; i < SubGhzProtocolTypeMax; i++) {
subghz_protocol_common_set_callback(instance->protocols[i], subghz_protocol_parser_rx_callback, instance);
}
instance->parser_callback = callback;
instance->parser_callback_context = context;
}
void subghz_protocol_load_nice_flor_s_file(SubGhzProtocol* instance, const char* file_name) {
subghz_protocol_nice_flor_s_name_file(instance->nice_flor_s, file_name);
// subghz_protocol_nice_flor_s_name_file(instance->nice_flor_s, file_name);
subghz_protocol_nice_flor_s_name_file((SubGhzProtocolNiceFlorS*) instance->protocols[SubGhzProtocolTypeNiceFlorS], file_name);
}
void subghz_protocol_load_keeloq_file(SubGhzProtocol* instance, const char* file_name) {
@@ -141,27 +148,29 @@ void subghz_protocol_load_keeloq_file(SubGhzProtocol* instance, const char* file
}
void subghz_protocol_reset(SubGhzProtocol* instance) {
subghz_protocol_came_reset(instance->came);
subghz_protocol_keeloq_reset(instance->keeloq);
subghz_protocol_princeton_reset(instance->princeton);
subghz_protocol_nice_flo_reset(instance->nice_flo);
subghz_protocol_nice_flor_s_reset(instance->nice_flor_s);
subghz_protocol_gate_tx_reset(instance->gate_tx);
subghz_protocol_ido_reset(instance->ido);
subghz_protocol_faac_slh_reset(instance->faac_slh);
subghz_protocol_nero_sketch_reset(instance->nero_sketch);
subghz_protocol_star_line_reset(instance->star_line);
subghz_protocol_came_reset((SubGhzProtocolCame*)instance->protocols[SubGhzProtocolTypeCame]);
subghz_protocol_keeloq_reset((SubGhzProtocolKeeloq*)instance->protocols[SubGhzProtocolTypeKeeloq]);
subghz_decoder_princeton_reset((SubGhzDecoderPrinceton*)instance->protocols[SubGhzProtocolTypePrinceton]);
subghz_protocol_nice_flo_reset((SubGhzProtocolNiceFlo*)instance->protocols[SubGhzProtocolTypeNiceFlo]);
subghz_protocol_nice_flor_s_reset((SubGhzProtocolNiceFlorS*)instance->protocols[SubGhzProtocolTypeNiceFlorS]);
subghz_protocol_gate_tx_reset((SubGhzProtocolGateTX*)instance->protocols[SubGhzProtocolTypeGateTX]);
subghz_protocol_ido_reset((SubGhzProtocolIDo*)instance->protocols[SubGhzProtocolTypeIDo]);
subghz_protocol_faac_slh_reset((SubGhzProtocolFaacSLH*)instance->protocols[SubGhzProtocolTypeFaacSLH]);
subghz_protocol_nero_sketch_reset((SubGhzProtocolNeroSketch*)instance->protocols[SubGhzProtocolTypeNeroSketch]);
subghz_protocol_star_line_reset((SubGhzProtocolStarLine*)instance->protocols[SubGhzProtocolTypeStarLine]);
}
void subghz_protocol_parse(SubGhzProtocol* instance, bool level, uint32_t duration) {
subghz_protocol_came_parse(instance->came, level, duration);
subghz_protocol_keeloq_parse(instance->keeloq, level, duration);
subghz_protocol_princeton_parse(instance->princeton, level, duration);
subghz_protocol_nice_flo_parse(instance->nice_flo, level, duration);
subghz_protocol_nice_flor_s_parse(instance->nice_flor_s, level, duration);
subghz_protocol_gate_tx_parse(instance->gate_tx, level, duration);
subghz_protocol_ido_parse(instance->ido, level, duration);
subghz_protocol_faac_slh_parse(instance->faac_slh, level, duration);
subghz_protocol_nero_sketch_parse(instance->nero_sketch, level, duration);
subghz_protocol_star_line_parse(instance->star_line, level, duration);
subghz_protocol_came_parse((SubGhzProtocolCame*)instance->protocols[SubGhzProtocolTypeCame], level, duration);
subghz_protocol_keeloq_parse((SubGhzProtocolKeeloq*)instance->protocols[SubGhzProtocolTypeKeeloq], level, duration);
subghz_decoder_princeton_parse((SubGhzDecoderPrinceton*)instance->protocols[SubGhzProtocolTypePrinceton], level, duration);
subghz_protocol_nice_flo_parse((SubGhzProtocolNiceFlo*)instance->protocols[SubGhzProtocolTypeNiceFlo], level, duration);
subghz_protocol_nice_flor_s_parse((SubGhzProtocolNiceFlorS*)instance->protocols[SubGhzProtocolTypeNiceFlorS], level, duration);
subghz_protocol_gate_tx_parse((SubGhzProtocolGateTX*)instance->protocols[SubGhzProtocolTypeGateTX], level, duration);
subghz_protocol_ido_parse((SubGhzProtocolIDo*)instance->protocols[SubGhzProtocolTypeIDo], level, duration);
subghz_protocol_faac_slh_parse((SubGhzProtocolFaacSLH*)instance->protocols[SubGhzProtocolTypeFaacSLH], level, duration);
subghz_protocol_nero_sketch_parse((SubGhzProtocolNeroSketch*)instance->protocols[SubGhzProtocolTypeNeroSketch], level, duration);
subghz_protocol_star_line_parse((SubGhzProtocolStarLine*)instance->protocols[SubGhzProtocolTypeStarLine], level, duration);
}

View File

@@ -19,6 +19,14 @@ SubGhzProtocol* subghz_protocol_alloc();
*/
void subghz_protocol_free(SubGhzProtocol* instance);
/** Get protocol by name
*
* @param instance - SubGhzProtocol instance
* @param name - name protocol
* @param SubGhzProtocolCommon
*/
SubGhzProtocolCommon* subghz_protocol_get_by_name(SubGhzProtocol* instance, const char* name);
/** Outputting data text from all parsers
*
* @param instance - SubGhzProtocol instance

View File

@@ -19,6 +19,11 @@ SubGhzProtocolCame* subghz_protocol_came_alloc() {
instance->common.te_shot = 320;
instance->common.te_long = 640;
instance->common.te_delta = 150;
instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_came_to_str;
instance->common.to_save_string =
(SubGhzProtocolCommonGetStrSave)subghz_protocol_came_to_save_str;
instance->common.to_load_protocol=
(SubGhzProtocolCommonLoad)subghz_protocol_came_to_load_protocol;
return instance;
}
@@ -99,6 +104,10 @@ void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32
instance->common.serial = 0x0;
instance->common.btn = 0x0;
instance->common.code_last_found = instance->common.code_found;
instance->common.code_last_count_bit = instance->common.code_count_bit;
if (instance->common.callback)
instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
@@ -129,3 +138,75 @@ void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32
break;
}
}
void subghz_protocol_came_to_str(SubGhzProtocolCame* instance, string_t output) {
uint32_t code_found_hi = instance->common.code_last_found >> 32;
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(
instance->common.code_last_found, instance->common.code_last_count_bit);
uint32_t code_found_reverse_hi = code_found_reverse >> 32;
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
string_cat_printf(
output,
"%s %d Bit\r\n"
" KEY:0x%lX%08lX\r\n"
" YEK:0x%lX%08lX\r\n",
instance->common.name,
instance->common.code_last_count_bit,
code_found_hi,
code_found_lo,
code_found_reverse_hi,
code_found_reverse_lo
);
}
void subghz_protocol_came_to_save_str(SubGhzProtocolCame* instance, string_t output) {
string_printf(
output,
"Protocol: %s\n"
"Bit: %d\n"
"Key: %08lX\n",
instance->common.name,
instance->common.code_last_count_bit,
(uint32_t)(instance->common.code_last_found & 0x00000000ffffffff));
}
bool subghz_protocol_came_to_load_protocol(FileWorker* file_worker, SubGhzProtocolCame* instance){
bool loaded = false;
string_t temp_str;
string_init(temp_str);
int res = 0;
int data = 0;
do {
// Read and parse bit data from 2nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
if(res != 1) {
break;
}
instance->common.code_last_count_bit = (uint8_t)data;
// Read and parse key data from 3nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
uint32_t temp_key = 0;
res = sscanf(string_get_cstr(temp_str), "Key: %08lX\n", &temp_key);
if(res != 1) {
break;
}
instance->common.code_last_found = (uint64_t)temp_key;
loaded = true;
} while(0);
string_clear(temp_str);
return loaded;
}

View File

@@ -36,3 +36,13 @@ void subghz_protocol_came_reset(SubGhzProtocolCame* instance);
* @param data - LevelDuration level_duration
*/
void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzProtocolCame* instance
* @param output - output string
*/
void subghz_protocol_came_to_str(SubGhzProtocolCame* instance, string_t output);
void subghz_protocol_came_to_save_str(SubGhzProtocolCame* instance, string_t output);
bool subghz_protocol_came_to_load_protocol(FileWorker* file_worker, SubGhzProtocolCame* instance);

View File

@@ -3,37 +3,50 @@
#include <m-string.h>
#include <furi-hal.h>
#include <stdint.h>
#include "file-worker.h"
#define bit_read(value, bit) (((value) >> (bit)) & 0x01)
#define bit_set(value, bit) ((value) |= (1UL << (bit)))
#define bit_clear(value, bit) ((value) &= ~(1UL << (bit)))
#define bit_write(value, bit, bitvalue) (bitvalue ? bit_set(value, bit) : bit_clear(value, bit))
#define SUBGHZ_TX_PIN_HIGTH()
#define SUBGHZ_TX_PIN_LOW()
#define SUBGHZ_TX_PIN_HIGTH()
#define SUBGHZ_TX_PIN_LOW()
#define DURATION_DIFF(x, y) ((x < y) ? (y - x) : (x - y))
//#define SUBGHZ_APP_PATH_FOLDER "/ext/subghz/saved"
#define SUBGHZ_APP_FOLDER "/any/subghz"
#define SUBGHZ_APP_PATH_FOLDER "/any/subghz/saved"
#define SUBGHZ_APP_EXTENSION ".sub"
typedef struct SubGhzProtocolCommon SubGhzProtocolCommon;
typedef void (*SubGhzProtocolCommonCallback)(SubGhzProtocolCommon* parser, void* context);
typedef void (*SubGhzProtocolCommonToStr)(SubGhzProtocolCommon* instance, string_t output);
//Save
typedef void (*SubGhzProtocolCommonGetStrSave)(SubGhzProtocolCommon* instance, string_t output);
//Load
typedef bool (*SubGhzProtocolCommonLoad)(FileWorker* file_worker, SubGhzProtocolCommon* instance);
struct SubGhzProtocolCommon {
const char* name;
uint16_t te_long;
uint16_t te_shot;
uint16_t te_delta;
uint64_t code_found;
uint64_t code_last_found;
uint8_t code_count_bit;
uint8_t code_min_count_bit_for_found;
uint8_t parser_step;
uint32_t te_last;
uint8_t header_count;
uint16_t cnt;
uint32_t serial;
uint8_t btn;
uint16_t te_long;
uint16_t te_shot;
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 parser_step;
uint32_t te_last;
uint8_t header_count;
uint16_t cnt;
uint32_t serial;
uint8_t btn;
/* Standard Callback for on rx complete event */
SubGhzProtocolCommonCallback callback;
@@ -41,15 +54,18 @@ struct SubGhzProtocolCommon {
/* Dump To String */
SubGhzProtocolCommonToStr to_string;
/* Get string to save */
SubGhzProtocolCommonGetStrSave to_save_string;
/*Load protocol by file*/
SubGhzProtocolCommonLoad to_load_protocol;
};
/** Add data bit to code_found
*
* @param common - SubGhzProtocolCommon common
* @param bit - add bit
*/
void subghz_protocol_common_add_bit(SubGhzProtocolCommon *common, uint8_t bit);
void subghz_protocol_common_add_bit(SubGhzProtocolCommon* common, uint8_t bit);
/** Checking that the duration is included in the interval
*
@@ -58,7 +74,10 @@ void subghz_protocol_common_add_bit(SubGhzProtocolCommon *common, uint8_t bit);
* @param duration_check duration checked
* @return true on success
*/
bool subghz_protocol_common_check_interval(SubGhzProtocolCommon *common, uint32_t duration, uint16_t duration_check);
bool subghz_protocol_common_check_interval(
SubGhzProtocolCommon* common,
uint32_t duration,
uint16_t duration_check);
/** Bit-by-bit data mirroring
*
@@ -68,14 +87,16 @@ bool subghz_protocol_common_check_interval(SubGhzProtocolCommon *common, uint32_
*/
uint64_t subghz_protocol_common_reverse_key(uint64_t key, uint8_t count_bit);
/** Callback protocol
*
* @param instance - SubGhzProtocolCommon* instance
* @param callback
* @param context
*/
void subghz_protocol_common_set_callback(SubGhzProtocolCommon* instance, SubGhzProtocolCommonCallback callback, void* context);
void subghz_protocol_common_set_callback(
SubGhzProtocolCommon* instance,
SubGhzProtocolCommonCallback callback,
void* context);
/** outputting information from the parser
*
@@ -83,4 +104,3 @@ void subghz_protocol_common_set_callback(SubGhzProtocolCommon* instance, SubGhzP
* @param output - output string
*/
void subghz_protocol_common_to_str(SubGhzProtocolCommon* instance, string_t output);

View File

@@ -14,6 +14,10 @@ SubGhzProtocolGateTX* subghz_protocol_gate_tx_alloc(void) {
instance->common.te_long = 700;
instance->common.te_delta = 100;
instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_gate_tx_to_str;
instance->common.to_save_string =
(SubGhzProtocolCommonGetStrSave)subghz_protocol_gate_tx_to_save_str;
instance->common.to_load_protocol=
(SubGhzProtocolCommonLoad)subghz_protocol_gate_tx_to_load_protocol;
return instance;
}
@@ -68,13 +72,10 @@ void subghz_protocol_gate_tx_reset(SubGhzProtocolGateTX* instance) {
* @param instance SubGhzProtocolFaacSLH instance
*/
void subghz_protocol_gate_tx_check_remote_controller(SubGhzProtocolGateTX* instance) {
uint32_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit);
uint32_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_count_bit);
instance->common.serial = (code_found_reverse & 0xFF) << 12 | ((code_found_reverse >>8) & 0xFF) << 4 | ((code_found_reverse >>20) & 0x0F) ;
instance->common.btn = ((code_found_reverse >> 16) & 0x0F);
if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
}
void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, uint32_t duration) {
@@ -103,7 +104,11 @@ void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, u
if (duration >= (instance->common.te_shot * 10 + instance->common.te_delta)) {
instance->common.parser_step = 1;
if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) {
subghz_protocol_gate_tx_check_remote_controller(instance);
instance->common.code_last_found = instance->common.code_found;
instance->common.code_last_count_bit = instance->common.code_count_bit;
if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
}
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
@@ -135,20 +140,64 @@ void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, u
}
void subghz_protocol_gate_tx_to_str(SubGhzProtocolGateTX* instance, string_t output) {
// uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit);
// uint32_t code_fix = code_found_reverse & 0xFFFFFFFF;
// uint32_t code_hop = (code_found_reverse >>32) & 0xFFFFFFFF;
//uint32_t rev_hi =
subghz_protocol_gate_tx_check_remote_controller(instance);
string_cat_printf(output,
"Protocol %s, %d Bit\r\n"
"%s, %d Bit\r\n"
" KEY:%06lX\r\n"
" SN:%05lX BTN:%lX\r\n",
instance->common.name,
instance->common.code_count_bit,
(uint32_t)(instance->common.code_found & 0xFFFFFF),
instance->common.code_last_count_bit,
(uint32_t)(instance->common.code_last_found & 0xFFFFFF),
instance->common.serial,
instance->common.btn);
}
instance->common.btn
);
}
void subghz_protocol_gate_tx_to_save_str(SubGhzProtocolGateTX* instance, string_t output) {
string_printf(
output,
"Protocol: %s\n"
"Bit: %d\n"
"Key: %08lX\n",
instance->common.name,
instance->common.code_last_count_bit,
(uint32_t)(instance->common.code_last_found & 0x00000000ffffffff));
}
bool subghz_protocol_gate_tx_to_load_protocol(FileWorker* file_worker, SubGhzProtocolGateTX* instance){
bool loaded = false;
string_t temp_str;
string_init(temp_str);
int res = 0;
int data = 0;
do {
// Read and parse bit data from 2nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
if(res != 1) {
break;
}
instance->common.code_last_count_bit = (uint8_t)data;
// Read and parse key data from 3nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
uint32_t temp_key = 0;
res = sscanf(string_get_cstr(temp_str), "Key: %08lX\n", &temp_key);
if(res != 1) {
break;
}
instance->common.code_last_found = (uint64_t)temp_key;
subghz_protocol_gate_tx_check_remote_controller(instance);
loaded = true;
} while(0);
string_clear(temp_str);
return loaded;
}

View File

@@ -42,4 +42,7 @@ void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, u
* @param instance - SubGhzProtocolFaacSLH* instance
* @param output - output string
*/
void subghz_protocol_gate_tx_to_str(SubGhzProtocolGateTX* instance, string_t output);
void subghz_protocol_gate_tx_to_str(SubGhzProtocolGateTX* instance, string_t output);
void subghz_protocol_gate_tx_to_save_str(SubGhzProtocolGateTX* instance, string_t output);
bool subghz_protocol_gate_tx_to_load_protocol(FileWorker* file_worker, SubGhzProtocolGateTX* instance);

View File

@@ -24,6 +24,10 @@ SubGhzProtocolKeeloq* subghz_protocol_keeloq_alloc(SubGhzKeystore* keystore) {
instance->common.te_long = 800;
instance->common.te_delta = 140;
instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_keeloq_to_str;
instance->common.to_save_string =
(SubGhzProtocolCommonGetStrSave)subghz_protocol_keeloq_to_save_str;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoad)subghz_protocol_keeloq_to_load_protocol;
return instance;
}
@@ -40,86 +44,97 @@ void subghz_protocol_keeloq_free(SubGhzProtocolKeeloq* instance) {
* @param hop hop encrypted part of the parcel
* @return true on successful search
*/
uint8_t subghz_protocol_keeloq_check_remote_controller_selector(SubGhzProtocolKeeloq* instance, uint32_t fix , uint32_t hop) {
uint16_t end_serial = (uint16_t)(fix&0x3FF);
uint8_t btn = (uint8_t)(fix>>28);
uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
SubGhzProtocolKeeloq* instance,
uint32_t fix,
uint32_t hop) {
uint16_t end_serial = (uint16_t)(fix & 0x3FF);
uint8_t btn = (uint8_t)(fix >> 28);
uint32_t decrypt = 0;
uint64_t man_normal_learning;
for
M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) {
switch (manufacture_code->type){
case KEELOQ_LEARNING_SIMPLE:
//Simple Learning
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
if((decrypt>>28 == btn) && ((((uint16_t)(decrypt>>16)) & 0x3FF) == end_serial)){
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt = decrypt & 0x0000FFFF;
return 1;
}
switch(manufacture_code->type) {
case KEELOQ_LEARNING_SIMPLE:
//Simple Learning
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
if((decrypt >> 28 == btn) &&
((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial)) {
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt = decrypt & 0x0000FFFF;
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( (decrypt>>28 ==btn)&& ((((uint16_t)(decrypt>>16))&0x3FF)==end_serial)){
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt = decrypt & 0x0000FFFF;
return 1;
}
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((decrypt >> 28 == btn) &&
((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial)) {
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt = decrypt & 0x0000FFFF;
return 1;
}
break;
case KEELOQ_LEARNING_UNKNOWN:
// Simple Learning
decrypt=subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
if( (decrypt>>28 ==btn) && ((((uint16_t)(decrypt>>16))&0x3FF)==end_serial)){
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt = decrypt & 0x0000FFFF;
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( (decrypt>>28 ==btn) && ((((uint16_t)(decrypt>>16))&0x3FF)==end_serial)){
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt= decrypt&0x0000FFFF;
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( (decrypt>>28 ==btn)&& ((((uint16_t)(decrypt>>16))&0x3FF)==end_serial)){
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt= decrypt&0x0000FFFF;
return 1;
}
// Check for mirrored man
man_rev=0;
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);
}
man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, man_rev);
decrypt=subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning);
if( (decrypt>>28 ==btn) && ((((uint16_t)(decrypt>>16))&0x3FF)==end_serial)){
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt= decrypt&0x0000FFFF;
return 1;
}
case KEELOQ_LEARNING_UNKNOWN:
// Simple Learning
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
if((decrypt >> 28 == btn) &&
((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial)) {
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt = decrypt & 0x0000FFFF;
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((decrypt >> 28 == btn) &&
((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial)) {
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt = decrypt & 0x0000FFFF;
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((decrypt >> 28 == btn) &&
((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial)) {
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt = decrypt & 0x0000FFFF;
return 1;
}
// Check for mirrored man
man_rev = 0;
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);
}
man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, man_rev);
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning);
if((decrypt >> 28 == btn) &&
((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial)) {
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt = decrypt & 0x0000FFFF;
return 1;
}
break;
}
}
instance->manufacture_name = "Unknown";
instance->common.cnt=0;
instance->common.cnt = 0;
return 0;
}
@@ -129,22 +144,23 @@ uint8_t subghz_protocol_keeloq_check_remote_controller_selector(SubGhzProtocolKe
* @param instance SubGhzProtocolKeeloq instance
*/
void subghz_protocol_keeloq_check_remote_controller(SubGhzProtocolKeeloq* instance) {
uint64_t key = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit);
uint64_t key = subghz_protocol_common_reverse_key(
instance->common.code_last_found, instance->common.code_last_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){
if((key_hop >> 24) == ((key_hop >> 16) & 0x00ff) &&
(key_fix >> 28) == ((key_hop >> 12) & 0x0f) && (key_hop & 0xFFF) == 0x404) {
instance->manufacture_name = "AN-Motors";
instance->common.cnt = key_hop>>16;
} else if((key_hop & 0xFFF) == (0x000) && (key_fix>>28) ==((key_hop>>12)&0x0f) ){
instance->common.cnt = key_hop >> 16;
} else if((key_hop & 0xFFF) == (0x000) && (key_fix >> 28) == ((key_hop >> 12) & 0x0f)) {
instance->manufacture_name = "HCS101";
instance->common.cnt = key_hop>>16;
instance->common.cnt = key_hop >> 16;
} else {
subghz_protocol_keeloq_check_remote_controller_selector(instance, key_fix, key_hop);
}
instance ->common.serial= key_fix&0x0FFFFFFF;
instance->common.serial = key_fix & 0x0FFFFFFF;
instance->common.btn = key_fix >> 28;
if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
}
/** Send bit
@@ -153,7 +169,7 @@ void subghz_protocol_keeloq_check_remote_controller(SubGhzProtocolKeeloq* instan
* @param bit - bit
*/
void subghz_protocol_keeloq_send_bit(SubGhzProtocolKeeloq* instance, uint8_t bit) {
if (bit) {
if(bit) {
// send bit 1
SUBGHZ_TX_PIN_HIGTH();
delay_us(instance->common.te_shot);
@@ -168,10 +184,14 @@ void subghz_protocol_keeloq_send_bit(SubGhzProtocolKeeloq* instance, uint8_t bit
}
}
void subghz_protocol_keeloq_send_key(SubGhzProtocolKeeloq* instance, uint64_t key, uint8_t bit, uint8_t repeat) {
while (repeat--) {
void subghz_protocol_keeloq_send_key(
SubGhzProtocolKeeloq* instance,
uint64_t key,
uint8_t bit,
uint8_t repeat) {
while(repeat--) {
// Send header
for (uint8_t i = 11; i > 0; i--) {
for(uint8_t i = 11; i > 0; i--) {
SUBGHZ_TX_PIN_HIGTH();
delay_us(instance->common.te_shot);
SUBGHZ_TX_PIN_LOW();
@@ -179,7 +199,7 @@ void subghz_protocol_keeloq_send_key(SubGhzProtocolKeeloq* instance, uint64_t ke
}
delay_us(instance->common.te_shot * 9); //+1 up Send header
for (uint8_t i = bit; i > 0; i--) {
for(uint8_t i = bit; i > 0; i--) {
subghz_protocol_keeloq_send_bit(instance, bit_read(key, i - 1));
}
// +send 2 status bit
@@ -187,7 +207,7 @@ void subghz_protocol_keeloq_send_key(SubGhzProtocolKeeloq* instance, uint64_t ke
subghz_protocol_keeloq_send_bit(instance, 0);
// send end
subghz_protocol_keeloq_send_bit(instance, 0);
delay_us(instance->common.te_shot * 2); //+2 interval END SEND
delay_us(instance->common.te_shot * 2); //+2 interval END SEND
}
}
@@ -196,9 +216,10 @@ void subghz_protocol_keeloq_reset(SubGhzProtocolKeeloq* instance) {
}
void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, uint32_t duration) {
switch (instance->common.parser_step) {
switch(instance->common.parser_step) {
case 0:
if ((level) && DURATION_DIFF(duration, instance->common.te_shot)< instance->common.te_delta) {
if((level) &&
DURATION_DIFF(duration, instance->common.te_shot) < instance->common.te_delta) {
instance->common.parser_step = 1;
instance->common.header_count++;
} else {
@@ -207,11 +228,14 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui
break;
case 1:
if ((!level) && (DURATION_DIFF(duration, instance->common.te_shot ) < instance->common.te_delta)) {
if((!level) &&
(DURATION_DIFF(duration, instance->common.te_shot) < instance->common.te_delta)) {
instance->common.parser_step = 0;
break;
}
if ((instance->common.header_count > 2) && ( DURATION_DIFF(duration, instance->common.te_shot * 10)< instance->common.te_delta * 10)) {
if((instance->common.header_count > 2) &&
(DURATION_DIFF(duration, instance->common.te_shot * 10) <
instance->common.te_delta * 10)) {
// Found header
instance->common.parser_step = 2;
instance->common.code_found = 0;
@@ -222,35 +246,45 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui
}
break;
case 2:
if (level) {
if(level) {
instance->common.te_last = duration;
instance->common.parser_step = 3;
}
break;
case 3:
if (!level) {
if (duration >= (instance->common.te_shot * 2 + instance->common.te_delta)) {
if(!level) {
if(duration >= (instance->common.te_shot * 2 + instance->common.te_delta)) {
// Found end TX
instance->common.parser_step = 0;
if (instance->common.code_count_bit >= instance->common.code_min_count_bit_for_found) {
if(instance->common.code_last_found != instance->common.code_found ){
subghz_protocol_keeloq_check_remote_controller(instance);
if(instance->common.code_count_bit >=
instance->common.code_min_count_bit_for_found) {
if(instance->common.code_last_found != instance->common.code_found) {
instance->common.code_last_found = instance->common.code_found;
instance->common.code_last_count_bit = instance->common.code_count_bit;
if(instance->common.callback)
instance->common.callback(
(SubGhzProtocolCommon*)instance, instance->common.context);
}
instance->common.code_last_found = instance->common.code_found;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
instance->common.header_count = 0;
}
break;
} else if ((DURATION_DIFF(instance->common.te_last, instance->common.te_shot) < instance->common.te_delta)
&& (DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) {
if (instance->common.code_count_bit < instance->common.code_min_count_bit_for_found) {
} else if(
(DURATION_DIFF(instance->common.te_last, instance->common.te_shot) <
instance->common.te_delta) &&
(DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) {
if(instance->common.code_count_bit <
instance->common.code_min_count_bit_for_found) {
subghz_protocol_common_add_bit(&instance->common, 1);
}
instance->common.parser_step = 2;
} else if ((DURATION_DIFF(instance->common.te_last, instance->common.te_long) < instance->common.te_delta)
&& (DURATION_DIFF(duration, instance->common.te_shot) < instance->common.te_delta)) {
if (instance->common.code_count_bit < instance->common.code_min_count_bit_for_found) {
} else if(
(DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
instance->common.te_delta) &&
(DURATION_DIFF(duration, instance->common.te_shot) < instance->common.te_delta)) {
if(instance->common.code_count_bit <
instance->common.code_min_count_bit_for_found) {
subghz_protocol_common_add_bit(&instance->common, 0);
}
instance->common.parser_step = 2;
@@ -267,29 +301,152 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui
}
void subghz_protocol_keeloq_to_str(SubGhzProtocolKeeloq* instance, string_t output) {
uint32_t code_found_hi = instance->common.code_found >> 32;
uint32_t code_found_lo = instance->common.code_found & 0x00000000ffffffff;
subghz_protocol_keeloq_check_remote_controller(instance);
uint32_t code_found_hi = instance->common.code_last_found >> 32;
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit);
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(
instance->common.code_last_found, instance->common.code_last_count_bit);
uint32_t code_found_reverse_hi = code_found_reverse>>32;
uint32_t code_found_reverse_lo = code_found_reverse&0x00000000ffffffff;
uint32_t code_found_reverse_hi = code_found_reverse >> 32;
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
string_cat_printf(
output,
"Protocol %s, %d Bit\r\n"
"%s, %d Bit\r\n"
"KEY:0x%lX%lX\r\n"
"FIX:%08lX MF:%s \r\n"
"HOP:%08lX \r\n"
"SN:%07lX CNT:%04X B:%02lX\r\n",
instance->common.name,
instance->common.code_count_bit,
instance->common.code_last_count_bit,
code_found_hi,
code_found_lo,
code_found_reverse_hi,
instance->manufacture_name,
code_found_reverse_lo,
instance->common.serial,
instance->common.cnt,
instance->common.btn
);
instance->common.cnt,
instance->common.btn);
}
uint64_t subghz_protocol_keeloq_gen_key(SubGhzProtocolKeeloq* instance) {
uint32_t fix = instance->common.btn << 28 | instance->common.serial;
uint32_t decrypt = instance->common.btn << 28 | (instance->common.serial & 0x3FF) << 16 |
instance->common.cnt;
uint32_t hop = 0;
uint64_t man_normal_learning = 0;
int res = 0;
for
M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) {
res = strcmp(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_normal_learning =
subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man_normal_learning);
break;
case KEELOQ_LEARNING_UNKNOWN:
hop = 0; //todo
break;
}
break;
}
}
uint64_t yek = (uint64_t)fix << 32 | hop;
return subghz_protocol_common_reverse_key(yek, instance->common.code_last_count_bit);
}
void subghz_protocol_keeloq_to_save_str(SubGhzProtocolKeeloq* instance, string_t output) {
string_printf(
output,
"Protocol: %s\n"
"Bit: %d\n"
"Manufacture_name: %s\n"
"Serial: %08lX\n"
"Cnt: %04lX\n"
"Btn: %01lX\n",
instance->common.name,
instance->common.code_last_count_bit,
instance->manufacture_name,
instance->common.serial,
instance->common.cnt,
instance->common.btn);
}
bool subghz_protocol_keeloq_to_load_protocol(
FileWorker* file_worker,
SubGhzProtocolKeeloq* instance) {
bool loaded = false;
string_t temp_str;
string_init(temp_str);
string_t temp_name_man;
string_init(temp_name_man);
int res = 0;
int data = 0;
do {
// Read and parse bit data from 2nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
if(res != 1) {
break;
}
instance->common.code_last_count_bit = (uint8_t)data;
// Read and parse name protocol from 3st line
if(!file_worker_read_until(file_worker, temp_name_man, '\n')) {
break;
}
// strlen("Manufacture_name: ") = 18
string_right(temp_name_man, 18);
instance->manufacture_name = string_get_cstr(temp_name_man);
// Read and parse key data from 4nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
uint32_t temp_param = 0;
res = sscanf(string_get_cstr(temp_str), "Serial: %08lX\n", &temp_param);
if(res != 1) {
break;
}
instance->common.serial = temp_param;
// Read and parse key data from 5nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Cnt: %04lX\n", &temp_param);
if(res != 1) {
break;
}
instance->common.cnt = (uint16_t)temp_param;
// Read and parse key data from 5nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Btn: %01lX\n", &temp_param);
if(res != 1) {
break;
}
instance->common.btn = (uint8_t)temp_param;
instance->common.code_last_found = subghz_protocol_keeloq_gen_key(instance);
loaded = true;
} while(0);
string_clear(temp_name_man);
string_clear(temp_str);
return loaded;
}

View File

@@ -45,3 +45,6 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui
* @param output - output string
*/
void subghz_protocol_keeloq_to_str(SubGhzProtocolKeeloq* instance, string_t output);
void subghz_protocol_keeloq_to_save_str(SubGhzProtocolKeeloq* instance, string_t output);
bool subghz_protocol_keeloq_to_load_protocol(FileWorker* file_worker, SubGhzProtocolKeeloq* instance);

View File

@@ -1,5 +1,7 @@
#pragma once
#include "subghz_protocol_common.h"
#include "file-worker.h"
#include <furi.h>

View File

@@ -14,6 +14,10 @@ SubGhzProtocolNeroSketch* subghz_protocol_nero_sketch_alloc(void) {
instance->common.te_long = 660;
instance->common.te_delta = 150;
instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nero_sketch_to_str;
instance->common.to_save_string =
(SubGhzProtocolCommonGetStrSave)subghz_protocol_nero_sketch_to_save_str;
instance->common.to_load_protocol=
(SubGhzProtocolCommonLoad)subghz_protocol_nero_sketch_to_load_protocol;
return instance;
}
@@ -80,18 +84,18 @@ void subghz_protocol_nero_sketch_reset(SubGhzProtocolNeroSketch* instance) {
*
* @param instance SubGhzProtocolNeroSketch instance
*/
void subghz_protocol_nero_sketch_check_remote_controller(SubGhzProtocolNeroSketch* instance) {
//пока не понятно с серийником, но код статический
// uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit);
// uint32_t code_fix = code_found_reverse & 0xFFFFFFFF;
// //uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFF;
// void subghz_protocol_nero_sketch_check_remote_controller(SubGhzProtocolNeroSketch* instance) {
// //пока не понятно с серийником, но код статический
// // uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit);
// // uint32_t code_fix = code_found_reverse & 0xFFFFFFFF;
// // //uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFF;
// instance->common.serial = code_fix & 0xFFFFFFF;
// instance->common.btn = (code_fix >> 28) & 0x0F;
// // instance->common.serial = code_fix & 0xFFFFFFF;
// // instance->common.btn = (code_fix >> 28) & 0x0F;
if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
// //if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
}
// }
void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool level, uint32_t duration) {
switch (instance->common.parser_step) {
@@ -140,7 +144,11 @@ void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool
//Found stop bit
instance->common.parser_step = 0;
if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) {
subghz_protocol_nero_sketch_check_remote_controller(instance);
instance->common.code_last_found = instance->common.code_found;
instance->common.code_last_count_bit = instance->common.code_count_bit;
if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
}
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
@@ -176,25 +184,77 @@ void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool
void subghz_protocol_nero_sketch_to_str(SubGhzProtocolNeroSketch* instance, string_t output) {
uint32_t code_found_hi = instance->common.code_found >> 32;
uint32_t code_found_lo = instance->common.code_found & 0x00000000ffffffff;
uint32_t code_found_hi = instance->common.code_last_found >> 32;
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit);
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_count_bit);
uint32_t code_found_reverse_hi = code_found_reverse>>32;
uint32_t code_found_reverse_lo = code_found_reverse&0x00000000ffffffff;
//uint32_t rev_hi =
string_cat_printf(output,
"Protocol %s, %d Bit\r\n"
"%s, %d Bit\r\n"
" KEY:0x%lX%08lX\r\n"
" YEK:0x%lX%08lX\r\n",
instance->common.name,
instance->common.code_count_bit,
instance->common.code_last_count_bit,
code_found_hi,
code_found_lo,
code_found_reverse_hi,
code_found_reverse_lo
);
}
void subghz_protocol_nero_sketch_to_save_str(SubGhzProtocolNeroSketch* instance, string_t output) {
uint32_t code_found_hi = instance->common.code_last_found >> 32;
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
string_printf(
output,
"Protocol: %s\n"
"Bit: %d\n"
"Key: %08lX%08lX\n",
instance->common.name,
instance->common.code_last_count_bit,
code_found_hi,
code_found_lo
);
}
bool subghz_protocol_nero_sketch_to_load_protocol(FileWorker* file_worker, SubGhzProtocolNeroSketch* instance){
bool loaded = false;
string_t temp_str;
string_init(temp_str);
int res = 0;
int data = 0;
do {
// Read and parse bit data from 2nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
if(res != 1) {
break;
}
instance->common.code_last_count_bit = (uint8_t)data;
// Read and parse key data from 3nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
uint32_t temp_key_hi = 0;
uint32_t temp_key_lo = 0;
res = sscanf(string_get_cstr(temp_str), "Key: %08lX%08lX\n", &temp_key_hi, &temp_key_lo);
if(res != 2) {
break;
}
instance->common.code_last_found = (uint64_t)temp_key_hi<<32 | temp_key_lo;
loaded = true;
} while(0);
string_clear(temp_str);
return loaded;
}

View File

@@ -49,3 +49,6 @@ void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool
* @param output - output string
*/
void subghz_protocol_nero_sketch_to_str(SubGhzProtocolNeroSketch* instance, string_t output);
void subghz_protocol_nero_sketch_to_save_str(SubGhzProtocolNeroSketch* instance, string_t output);
bool subghz_protocol_nero_sketch_to_load_protocol(FileWorker* file_worker, SubGhzProtocolNeroSketch* instance);

View File

@@ -1,39 +1,120 @@
#include "subghz_protocol_princeton.h"
/*
* Help
* https://phreakerclub.com/447
*
*/
struct SubGhzProtocolPrinceton {
SubGhzProtocolCommon common;
#define SUBGHZ_PT_SHORT 450
#define SUBGHZ_PT_LONG (SUBGHZ_PT_SHORT * 3)
#define SUBGHZ_PT_GUARD (SUBGHZ_PT_SHORT * 30)
struct SubGhzEncoderPrinceton {
uint32_t key;
uint16_t te;
size_t repeat;
size_t front;
};
SubGhzProtocolPrinceton* subghz_protocol_princeton_alloc(void) {
SubGhzProtocolPrinceton* instance = furi_alloc(sizeof(SubGhzProtocolPrinceton));
struct SubGhzDecoderPrinceton {
SubGhzProtocolCommon common;
uint16_t te;
};
instance->common.name = "Princeton";
instance->common.code_min_count_bit_for_found = 24;
instance->common.te_shot = 450;//150;
instance->common.te_long = 1350;//450;
instance->common.te_delta = 200;//50;
SubGhzEncoderPrinceton* subghz_encoder_princeton_alloc() {
SubGhzEncoderPrinceton* instance = furi_alloc(sizeof(SubGhzEncoderPrinceton));
return instance;
}
void subghz_protocol_princeton_free(SubGhzProtocolPrinceton* instance) {
void subghz_encoder_princeton_free(SubGhzEncoderPrinceton* instance) {
furi_assert(instance);
free(instance);
}
void subghz_encoder_princeton_set_te(SubGhzEncoderPrinceton* instance, void* decoder){
SubGhzDecoderPrinceton* pricenton = decoder;
if((pricenton->te) !=0){
instance->te = pricenton->te;
}else{
instance->te = SUBGHZ_PT_SHORT;
}
}
void subghz_encoder_princeton_reset(SubGhzEncoderPrinceton* instance, uint32_t key, size_t repeat) {
furi_assert(instance);
instance->te = SUBGHZ_PT_SHORT;
instance->key = key;
instance->repeat = repeat;
instance->front = 48;
}
size_t subghz_encoder_princeton_get_repeat_left(SubGhzEncoderPrinceton* instance) {
furi_assert(instance);
return instance->repeat;
}
LevelDuration subghz_encoder_princeton_yield(void* context) {
SubGhzEncoderPrinceton* instance = context;
if(instance->repeat == 0) 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);
} else {
ret = level_duration_make(level, level ? instance->te : instance->te * 3);
}
} else {
ret = level_duration_make(level, level ? instance->te : instance->te * 30);
}
instance->front++;
if(instance->front == 50) {
instance->repeat--;
instance->front = 0;
}
return ret;
}
SubGhzDecoderPrinceton* subghz_decoder_princeton_alloc(void) {
SubGhzDecoderPrinceton* instance = furi_alloc(sizeof(SubGhzDecoderPrinceton));
instance->common.name = "Princeton";
instance->common.code_min_count_bit_for_found = 24;
instance->common.te_shot = 450; //150;
instance->common.te_long = 1350; //450;
instance->common.te_delta = 200; //50;
instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_decoder_princeton_to_str;
instance->common.to_save_string =
(SubGhzProtocolCommonGetStrSave)subghz_decoder_princeton_to_save_str;
instance->common.to_load_protocol=
(SubGhzProtocolCommonLoad)subghz_decoder_princeton_to_load_protocol;
return instance;
}
void subghz_decoder_princeton_free(SubGhzDecoderPrinceton* instance) {
furi_assert(instance);
free(instance);
}
/** Send bit
*
* @param instance - SubGhzProtocolPrinceton instance
* @param instance - SubGhzDecoderPrinceton instance
* @param bit - bit
*/
void subghz_protocol_princeton_send_bit(SubGhzProtocolPrinceton* instance, uint8_t bit) {
if (bit) {
void subghz_decoder_princeton_send_bit(SubGhzDecoderPrinceton* instance, uint8_t bit) {
if(bit) {
//send bit 1
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_long);
@@ -48,29 +129,36 @@ void subghz_protocol_princeton_send_bit(SubGhzProtocolPrinceton* instance, uint8
}
}
void subghz_protocol_princeton_send_key(SubGhzProtocolPrinceton* instance, uint64_t key, uint8_t bit,uint8_t repeat) {
while (repeat--) {
void subghz_decoder_princeton_send_key(
SubGhzDecoderPrinceton* instance,
uint64_t key,
uint8_t bit,
uint8_t repeat) {
while(repeat--) {
SUBGHZ_TX_PIN_LOW();
//Send start bit
subghz_protocol_princeton_send_bit(instance, 1);
subghz_decoder_princeton_send_bit(instance, 1);
//Send header
delay_us(instance->common.te_shot * 33); //+2 interval v bit 1
//Send key data
for (uint8_t i = bit; i > 0; i--) {
subghz_protocol_princeton_send_bit(instance, bit_read(key, i - 1));
for(uint8_t i = bit; i > 0; i--) {
subghz_decoder_princeton_send_bit(instance, bit_read(key, i - 1));
}
}
}
void subghz_protocol_princeton_reset(SubGhzProtocolPrinceton* instance) {
void subghz_decoder_princeton_reset(SubGhzDecoderPrinceton* instance) {
instance->common.parser_step = 0;
}
void subghz_protocol_princeton_parse(SubGhzProtocolPrinceton* instance, bool level, uint32_t duration) {
switch (instance->common.parser_step) {
void subghz_decoder_princeton_parse(
SubGhzDecoderPrinceton* instance,
bool level,
uint32_t duration) {
switch(instance->common.parser_step) {
case 0:
if ((!level)
&& (DURATION_DIFF(duration,instance->common.te_shot * 36) < instance->common.te_delta * 36)) {
if((!level) && (DURATION_DIFF(duration, instance->common.te_shot * 36) <
instance->common.te_delta * 36)) {
//Found Preambula
instance->common.parser_step = 1;
instance->common.code_found = 0;
@@ -81,33 +169,49 @@ void subghz_protocol_princeton_parse(SubGhzProtocolPrinceton* instance, bool lev
break;
case 1:
//save duration
if (level) {
if(level) {
instance->common.te_last = duration;
instance->common.parser_step = 2;
}
break;
case 2:
if (!level) {
if (duration >= (instance->common.te_shot * 10 + instance->common.te_delta)) {
if(!level) {
if(duration >= (instance->common.te_shot * 10 + instance->common.te_delta)) {
instance->common.parser_step = 1;
if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) {
if(instance->common.code_count_bit >=
instance->common.code_min_count_bit_for_found) {
if(instance->common.code_last_found == instance->common.code_found) {
//instance->te = (instance->te+instance->common.te_last)/2; //Option 1 TE averaging
if(instance->te > instance->common.te_last)
instance->te = instance->common.te_last; //Option 2 TE averaging
} else {
instance->te = instance->common.te_last;
}
instance->common.code_last_found = instance->common.code_found;
instance->common.code_last_count_bit = instance->common.code_count_bit;
instance->common.serial = instance->common.code_found >> 4;
instance->common.btn = (uint8_t)instance->common.code_found & 0x00000F;
if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
if(instance->common.callback)
instance->common.callback(
(SubGhzProtocolCommon*)instance, instance->common.context);
}
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
break;
}
if ((DURATION_DIFF(instance->common.te_last,instance->common.te_shot)< instance->common.te_delta)
&& (DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta*3)) {
if((DURATION_DIFF(instance->common.te_last, instance->common.te_shot) <
instance->common.te_delta) &&
(DURATION_DIFF(duration, instance->common.te_long) <
instance->common.te_delta * 3)) {
subghz_protocol_common_add_bit(&instance->common, 0);
instance->common.parser_step = 1;
} else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long)< instance->common.te_delta*3)
&& (DURATION_DIFF(duration,instance->common.te_shot)< instance->common.te_delta)) {
} else if(
(DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
instance->common.te_delta * 3) &&
(DURATION_DIFF(duration, instance->common.te_shot) < instance->common.te_delta)) {
subghz_protocol_common_add_bit(&instance->common, 1);
instance->common.parser_step = 1;
} else {
@@ -119,3 +223,92 @@ void subghz_protocol_princeton_parse(SubGhzProtocolPrinceton* instance, bool lev
break;
}
}
void subghz_decoder_princeton_to_str(SubGhzDecoderPrinceton* instance, string_t output) {
uint32_t code_found_hi = instance->common.code_last_found >> 32;
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(
instance->common.code_last_found, instance->common.code_last_count_bit);
uint32_t code_found_reverse_hi = code_found_reverse >> 32;
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
string_cat_printf(
output,
"%s %d Bit te %dus\r\n"
" KEY:0x%lX%08lX\r\n"
" YEK:0x%lX%08lX\r\n"
" SN:0x%05lX BTN:%02X\r\n",
instance->common.name,
instance->common.code_last_count_bit,
instance->te,
code_found_hi,
code_found_lo,
code_found_reverse_hi,
code_found_reverse_lo,
instance->common.serial,
instance->common.btn);
}
void subghz_decoder_princeton_to_save_str(SubGhzDecoderPrinceton* instance, string_t output) {
string_printf(
output,
"Protocol: %s\n"
"Bit: %d\n"
"Te: %d\n"
"Key: %08lX\n",
instance->common.name,
instance->common.code_last_count_bit,
instance->te,
(uint32_t)(instance->common.code_last_found & 0x00000000ffffffff));
}
bool subghz_decoder_princeton_to_load_protocol(FileWorker* file_worker, SubGhzDecoderPrinceton* instance){
bool loaded = false;
string_t temp_str;
string_init(temp_str);
int res = 0;
int data = 0;
do {
// Read and parse bit data from 2nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
if(res != 1) {
break;
}
instance->common.code_last_count_bit = (uint8_t)data;
// Read and parse te data from 3nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Te: %d\n", &data);
if(res != 1) {
break;
}
instance->te = (uint16_t)data;
// Read and parse key data from 4nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
uint32_t temp_key = 0;
res = sscanf(string_get_cstr(temp_str), "Key: %08lX\n", &temp_key);
if(res != 1) {
break;
}
instance->common.code_last_found = (uint64_t)temp_key;
instance->common.serial = instance->common.code_last_found >> 4;
instance->common.btn = (uint8_t)instance->common.code_last_found & 0x00000F;
loaded = true;
} while(0);
string_clear(temp_str);
return loaded;
}

View File

@@ -2,38 +2,90 @@
#include "subghz_protocol_common.h"
typedef struct SubGhzProtocolPrinceton SubGhzProtocolPrinceton;
/** Allocate SubGhzProtocolPrinceton
*
* @return SubGhzProtocolPrinceton*
/** SubGhzEncoderPrinceton anonymous type */
typedef struct SubGhzEncoderPrinceton SubGhzEncoderPrinceton;
/** Allocate SubGhzEncoderPrinceton
* @return pointer to SubGhzEncoderPrinceton instance
*/
SubGhzProtocolPrinceton* subghz_protocol_princeton_alloc();
SubGhzEncoderPrinceton* subghz_encoder_princeton_alloc();
/** Free SubGhzProtocolPrinceton
/** Free SubGhzEncoderPrinceton instance
* @param instance - SubGhzEncoderPrinceton instance
*/
void subghz_encoder_princeton_free(SubGhzEncoderPrinceton* instance);
/** Reset encoder with new params
* @param instance - SubGhzEncoderPrinceton instance
* @param key - 24bit key
* @param repeat - how many times to repeat
*/
void subghz_encoder_princeton_reset(SubGhzEncoderPrinceton* instance, uint32_t key, size_t repeat);
/** Get repeat count left
* @param instance - SubGhzEncoderPrinceton instance
* @return repeat count left
*/
size_t subghz_encoder_princeton_get_repeat_left(SubGhzEncoderPrinceton* instance);
/** Get level duration
* @param instance - SubGhzEncoderPrinceton instance
* @return level duration
*/
LevelDuration subghz_encoder_princeton_yield(void* context);
/** SubGhzDecoderPrinceton anonymous type */
typedef struct SubGhzDecoderPrinceton SubGhzDecoderPrinceton;
void subghz_encoder_princeton_set_te(
SubGhzEncoderPrinceton* instance,
void* decoder);
/** Allocate SubGhzDecoderPrinceton
*
* @return SubGhzDecoderPrinceton*
*/
SubGhzDecoderPrinceton* subghz_decoder_princeton_alloc();
/** Free SubGhzDecoderPrinceton
*
* @param instance
*/
void subghz_protocol_princeton_free(SubGhzProtocolPrinceton* instance);
void subghz_decoder_princeton_free(SubGhzDecoderPrinceton* instance);
/** Sends the key on the air
*
* @param instance - SubGhzProtocolPrinceton instance
* @param instance - SubGhzDecoderPrinceton instance
* @param key - key send
* @param bit - count bit key
* @param repeat - repeat send key
*/
void subghz_protocol_princeton_send_key(SubGhzProtocolPrinceton* instance, uint64_t key, uint8_t bit, uint8_t repeat);
void subghz_decoder_princeton_send_key(SubGhzDecoderPrinceton* instance, uint64_t key, uint8_t bit, uint8_t repeat);
/** Reset internal state
* @param instance - SubGhzProtocolPrinceton instance
* @param instance - SubGhzDecoderPrinceton instance
*/
void subghz_protocol_princeton_reset(SubGhzProtocolPrinceton* instance);
void subghz_decoder_princeton_reset(SubGhzDecoderPrinceton* instance);
/** Parse accepted duration
*
* @param instance - SubGhzProtocolPrinceton instance
* @param instance - SubGhzDecoderPrinceton instance
* @param data - LevelDuration level_duration
*/
void subghz_protocol_princeton_parse(SubGhzProtocolPrinceton* instance, bool level, uint32_t duration);
void subghz_decoder_princeton_parse(SubGhzDecoderPrinceton* instance, bool level, uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzDecoderPrinceton* instance
* @param output - output string
*/
void subghz_decoder_princeton_to_str(SubGhzDecoderPrinceton* instance, string_t output);
void subghz_decoder_princeton_to_save_str(SubGhzDecoderPrinceton* instance, string_t output);
bool subghz_decoder_princeton_to_load_protocol(FileWorker* file_worker, SubGhzDecoderPrinceton* instance);