[FL-1758, FL-1790] SubGhz refactoring part 2, fix generation of a new GateTX serial (#696)

* WidGet: fix name  Multiline String Element
* SubGhz: rename  SubGhzProtocol to SubGhzParser and bring it up
* SubGhz: a new way to navigate in receiver views
* SubGhz: fix syntax
* WedGet: add forwarding input type to wedget button callback, fix using a callback in an application
* SubGhz: add assertions and status checks
* SubGhz: fix syntax
* [FL-1790] SubGhz: fix GateTX
* SubGhz:  add 434.42 MHz frequency support
* SubGhz: rename type protocol, add decoder stage names
* SubGhz: fix navigation through received signals when changing scenes
* SubGhz: fix 2-fsk config

Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
Skorpionm
2021-09-15 19:24:19 +04:00
committed by GitHub
parent 72ca76097a
commit 8fd411097e
35 changed files with 1326 additions and 1113 deletions

View File

@@ -1,234 +0,0 @@
#include "subghz_protocol.h"
#include "subghz_protocol_came.h"
#include "subghz_protocol_cfm.h"
#include "subghz_protocol_keeloq.h"
#include "subghz_protocol_nice_flo.h"
#include "subghz_protocol_nice_flor_s.h"
#include "subghz_protocol_princeton.h"
#include "subghz_protocol_gate_tx.h"
#include "subghz_protocol_ido.h"
#include "subghz_protocol_faac_slh.h"
#include "subghz_protocol_nero_sketch.h"
#include "subghz_protocol_star_line.h"
#include "subghz_protocol_nero_radio.h"
#include "../subghz_keystore.h"
#include <furi.h>
#include <m-string.h>
typedef enum {
SubGhzProtocolTypeCame,
SubGhzProtocolTypeKeeloq,
SubGhzProtocolTypeNiceFlo,
SubGhzProtocolTypeNiceFlorS,
SubGhzProtocolTypePrinceton,
SubGhzProtocolTypeGateTX,
SubGhzProtocolTypeIDo,
SubGhzProtocolTypeFaacSLH,
SubGhzProtocolTypeNeroSketch,
SubGhzProtocolTypeStarLine,
SubGhzProtocolTypeNeroRadio,
SubGhzProtocolTypeMax,
} SubGhzProtocolType;
struct SubGhzProtocol {
SubGhzKeystore* keystore;
SubGhzProtocolCommon* protocols[SubGhzProtocolTypeMax];
SubGhzProtocolTextCallback text_callback;
void* text_callback_context;
SubGhzProtocolCommonCallbackDump parser_callback;
void* parser_callback_context;
};
static void subghz_protocol_text_rx_callback(SubGhzProtocolCommon* parser, void* context) {
SubGhzProtocol* instance = context;
string_t output;
string_init(output);
subghz_protocol_common_to_str((SubGhzProtocolCommon*)parser, output);
if(instance->text_callback) {
instance->text_callback(output, instance->text_callback_context);
} else {
printf(string_get_cstr(output));
}
string_clear(output);
}
static void subghz_protocol_parser_rx_callback(SubGhzProtocolCommon* parser, void* context) {
SubGhzProtocol* instance = context;
if(instance->parser_callback) {
instance->parser_callback(parser, instance->parser_callback_context);
}
}
SubGhzProtocol* subghz_protocol_alloc() {
SubGhzProtocol* instance = furi_alloc(sizeof(SubGhzProtocol));
instance->keystore = subghz_keystore_alloc();
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);
instance->protocols[SubGhzProtocolTypeNeroRadio] =
(SubGhzProtocolCommon*)subghz_protocol_nero_radio_alloc();
return instance;
}
void subghz_protocol_free(SubGhzProtocol* instance) {
furi_assert(instance);
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_protocol_nero_radio_free(
(SubGhzProtocolNeroRadio*)instance->protocols[SubGhzProtocolTypeNeroRadio]);
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);
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;
}
void subghz_protocol_enable_dump(
SubGhzProtocol* instance,
SubGhzProtocolCommonCallbackDump callback,
void* context) {
furi_assert(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(
(SubGhzProtocolNiceFlorS*)instance->protocols[SubGhzProtocolTypeNiceFlorS], file_name);
}
void subghz_protocol_load_keeloq_file(SubGhzProtocol* instance, const char* file_name) {
subghz_keystore_load(instance->keystore, file_name);
}
void subghz_protocol_reset(SubGhzProtocol* instance) {
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]);
subghz_protocol_nero_radio_reset(
(SubGhzProtocolNeroRadio*)instance->protocols[SubGhzProtocolTypeNeroRadio]);
}
void subghz_protocol_parse(SubGhzProtocol* instance, bool level, uint32_t 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);
subghz_protocol_nero_radio_parse(
(SubGhzProtocolNeroRadio*)instance->protocols[SubGhzProtocolTypeNeroRadio],
level,
duration);
}

View File

@@ -1,72 +0,0 @@
#pragma once
#include "subghz_protocol_common.h"
typedef void (*SubGhzProtocolTextCallback)(string_t text, void* context);
typedef void (*SubGhzProtocolCommonCallbackDump)(SubGhzProtocolCommon *parser, void* context);
typedef struct SubGhzProtocol SubGhzProtocol;
/** Allocate SubGhzProtocol
*
* @return SubGhzProtocol*
*/
SubGhzProtocol* subghz_protocol_alloc();
/** Free SubGhzProtocol
*
* @param instance
*/
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
* @param callback - SubGhzProtocolTextCallback callback
* @param context
*/
void subghz_protocol_enable_dump_text(SubGhzProtocol* instance, SubGhzProtocolTextCallback callback, void* context);
/** Outputting data SubGhzProtocol from all parsers
*
* @param instance - SubGhzProtocol instance
* @param callback - SubGhzProtocolTextCallback callback
* @param context
*/
void subghz_protocol_enable_dump(SubGhzProtocol* instance, SubGhzProtocolCommonCallbackDump callback, void* context);
/** File name rainbow table Nice Flor-S
*
* @param instance - SubGhzProtocol instance
* @param file_name - "path/file_name"
*/
void subghz_protocol_load_nice_flor_s_file(SubGhzProtocol* instance, const char* file_name);
/** File upload manufacture keys
*
* @param instance - SubGhzProtocol instance
* @param file_name - "path/file_name"
*/
void subghz_protocol_load_keeloq_file(SubGhzProtocol* instance, const char* file_name);
/** Restarting all parsers
*
* @param instance - SubGhzProtocol instance
*/
void subghz_protocol_reset(SubGhzProtocol* instance);
/** Loading data into all parsers
*
* @param instance - SubGhzProtocol instance
* @param level - true is high, false if low
* @param duration - level duration in microseconds
*/
void subghz_protocol_parse(SubGhzProtocol* instance, bool level, uint32_t duration);

View File

@@ -11,6 +11,13 @@ struct SubGhzProtocolCame {
SubGhzProtocolCommon common;
};
typedef enum {
CameDecoderStepReset = 0,
CameDecoderStepFoundStartBit,
CameDecoderStepSaveDuration,
CameDecoderStepCheckDuration,
} CameDecoderStep;
SubGhzProtocolCame* subghz_protocol_came_alloc() {
SubGhzProtocolCame* instance = furi_alloc(sizeof(SubGhzProtocolCame));
@@ -19,11 +26,11 @@ SubGhzProtocolCame* subghz_protocol_came_alloc() {
instance->common.te_short = 320;
instance->common.te_long = 640;
instance->common.te_delta = 150;
instance->common.type_protocol = TYPE_PROTOCOL_STATIC;
instance->common.type_protocol = SubGhzProtocolCommonTypeStatic;
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_from_file=
instance->common.to_load_protocol_from_file =
(SubGhzProtocolCommonLoadFromFile)subghz_protocol_came_to_load_protocol_from_file;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoadFromRAW)subghz_decoder_came_to_load_protocol;
@@ -38,97 +45,106 @@ void subghz_protocol_came_free(SubGhzProtocolCame* instance) {
free(instance);
}
bool subghz_protocol_came_send_key(SubGhzProtocolCame* instance, SubGhzProtocolCommonEncoder* encoder){
bool subghz_protocol_came_send_key(
SubGhzProtocolCame* instance,
SubGhzProtocolCommonEncoder* encoder) {
furi_assert(instance);
furi_assert(encoder);
size_t index = 0;
encoder->size_upload =(instance->common.code_last_count_bit * 2) + 2;
encoder->size_upload = (instance->common.code_last_count_bit * 2) + 2;
if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false;
//Send header
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short * 36);
encoder->upload[index++] =
level_duration_make(false, (uint32_t)instance->common.te_short * 36);
//Send start bit
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short);
//Send key data
for (uint8_t i = instance->common.code_last_count_bit; i > 0; i--) {
if(bit_read(instance->common.code_last_found, i - 1)){
for(uint8_t i = instance->common.code_last_count_bit; i > 0; i--) {
if(bit_read(instance->common.code_last_found, i - 1)) {
//send bit 1
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_long);
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short);
}else{
encoder->upload[index++] =
level_duration_make(false, (uint32_t)instance->common.te_long);
encoder->upload[index++] =
level_duration_make(true, (uint32_t)instance->common.te_short);
} else {
//send bit 0
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short);
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_long);
encoder->upload[index++] =
level_duration_make(false, (uint32_t)instance->common.te_short);
encoder->upload[index++] =
level_duration_make(true, (uint32_t)instance->common.te_long);
}
}
return true;
}
void subghz_protocol_came_reset(SubGhzProtocolCame* instance) {
instance->common.parser_step = 0;
instance->common.parser_step = CameDecoderStepReset;
}
void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32_t duration) {
switch (instance->common.parser_step) {
case 0:
if ((!level)
&& (DURATION_DIFF(duration, instance->common.te_short * 51)< instance->common.te_delta * 51)) { //Need protocol 36 te_short
switch(instance->common.parser_step) {
case CameDecoderStepReset:
if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 51) <
instance->common.te_delta * 51)) { //Need protocol 36 te_short
//Found header CAME
instance->common.parser_step = 1;
instance->common.parser_step = CameDecoderStepFoundStartBit;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = CameDecoderStepReset;
}
break;
case 1:
if (!level) {
case CameDecoderStepFoundStartBit:
if(!level) {
break;
} else if (DURATION_DIFF(duration, instance->common.te_short)< instance->common.te_delta) {
} else if(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) {
//Found start bit CAME
instance->common.parser_step = 2;
instance->common.parser_step = CameDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = CameDecoderStepReset;
}
break;
case 2:
if (!level) { //save interval
if (duration >= (instance->common.te_short * 4)) {
instance->common.parser_step = 1;
if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) {
case CameDecoderStepSaveDuration:
if(!level) { //save interval
if(duration >= (instance->common.te_short * 4)) {
instance->common.parser_step = CameDecoderStepFoundStartBit;
if(instance->common.code_count_bit >=
instance->common.code_min_count_bit_for_found) {
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);
if(instance->common.callback)
instance->common.callback(
(SubGhzProtocolCommon*)instance, instance->common.context);
}
break;
}
instance->common.te_last = duration;
instance->common.parser_step = 3;
instance->common.parser_step = CameDecoderStepCheckDuration;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = CameDecoderStepReset;
}
break;
case 3:
if (level) {
if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short) < instance->common.te_delta)
&& (DURATION_DIFF(duration, instance->common.te_long)< instance->common.te_delta)) {
case CameDecoderStepCheckDuration:
if(level) {
if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
instance->common.te_delta) &&
(DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) {
subghz_protocol_common_add_bit(&instance->common, 0);
instance->common.parser_step = 2;
} else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long)< instance->common.te_delta)
&& (DURATION_DIFF(duration, instance->common.te_short)< instance->common.te_delta)) {
instance->common.parser_step = CameDecoderStepSaveDuration;
} else if(
(DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
instance->common.te_delta) &&
(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
subghz_protocol_common_add_bit(&instance->common, 1);
instance->common.parser_step = 2;
instance->common.parser_step = CameDecoderStepSaveDuration;
} else
instance->common.parser_step = 0;
instance->common.parser_step = CameDecoderStepReset;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = CameDecoderStepReset;
}
break;
}
@@ -150,8 +166,7 @@ void subghz_protocol_came_to_str(SubGhzProtocolCame* instance, string_t output)
instance->common.name,
instance->common.code_last_count_bit,
code_found_lo,
code_found_reverse_lo
);
code_found_reverse_lo);
}
void subghz_protocol_came_to_save_str(SubGhzProtocolCame* instance, string_t output) {
@@ -165,7 +180,9 @@ void subghz_protocol_came_to_save_str(SubGhzProtocolCame* instance, string_t out
(uint32_t)(instance->common.code_last_found & 0x00000000ffffffff));
}
bool subghz_protocol_came_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolCame* instance){
bool subghz_protocol_came_to_load_protocol_from_file(
FileWorker* file_worker,
SubGhzProtocolCame* instance) {
bool loaded = false;
string_t temp_str;
string_init(temp_str);
@@ -202,9 +219,7 @@ bool subghz_protocol_came_to_load_protocol_from_file(FileWorker* file_worker, Su
return loaded;
}
void subghz_decoder_came_to_load_protocol(
SubGhzProtocolCame* instance,
void* context) {
void subghz_decoder_came_to_load_protocol(SubGhzProtocolCame* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;

View File

@@ -19,12 +19,11 @@
#define SUBGHZ_APP_EXTENSION ".sub"
#define SUBGHZ_ENCODER_UPLOAD_MAX_SIZE 512
enum {
TYPE_PROTOCOL_UNKNOWN,
TYPE_PROTOCOL_STATIC,
TYPE_PROTOCOL_DYNAMIC,
};
typedef enum {
SubGhzProtocolCommonTypeUnknown,
SubGhzProtocolCommonTypeStatic,
SubGhzProtocolCommonTypeDynamic,
}SubGhzProtocolCommonType;
typedef struct SubGhzProtocolCommon SubGhzProtocolCommon;
typedef struct SubGhzProtocolCommonEncoder SubGhzProtocolCommonEncoder;
@@ -38,7 +37,8 @@ typedef void (*SubGhzProtocolCommonToStr)(SubGhzProtocolCommon* instance, string
typedef void (*SubGhzProtocolCommonGetStrSave)(SubGhzProtocolCommon* instance, string_t output);
//Load protocol from file
typedef bool (*SubGhzProtocolCommonLoadFromFile)(FileWorker* file_worker, SubGhzProtocolCommon* instance);
typedef bool (
*SubGhzProtocolCommonLoadFromFile)(FileWorker* file_worker, SubGhzProtocolCommon* instance);
//Load protocol
typedef void (*SubGhzProtocolCommonLoadFromRAW)(SubGhzProtocolCommon* instance, void* context);
//Get upload encoder protocol
@@ -56,13 +56,13 @@ struct SubGhzProtocolCommon {
uint64_t code_found;
uint64_t code_last_found;
uint8_t code_min_count_bit_for_found;
uint8_t parser_step;
uint8_t type_protocol;
uint32_t te_last;
uint8_t header_count;
uint16_t cnt;
uint32_t serial;
uint8_t btn;
uint8_t header_count;
SubGhzProtocolCommonType type_protocol;
uint32_t te_last;
uint32_t serial;
uint32_t parser_step;
uint16_t cnt;
/* Standard Callback for on rx complete event */
SubGhzProtocolCommonCallback callback;
@@ -88,7 +88,7 @@ struct SubGhzProtocolCommonEncoder {
LevelDuration* upload;
};
struct SubGhzProtocolCommonLoad{
struct SubGhzProtocolCommonLoad {
uint64_t code_found;
uint8_t code_count_bit;
uint32_t param1;

View File

@@ -1,19 +1,25 @@
#include "subghz_protocol_faac_slh.h"
struct SubGhzProtocolFaacSLH {
SubGhzProtocolCommon common;
};
typedef enum {
FaacSLHDecoderStepReset = 0,
FaacSLHDecoderStepFoundPreambula,
FaacSLHDecoderStepSaveDuration,
FaacSLHDecoderStepCheckDuration,
} FaacSLHDecoderStep;
SubGhzProtocolFaacSLH* subghz_protocol_faac_slh_alloc(void) {
SubGhzProtocolFaacSLH* instance = furi_alloc(sizeof(SubGhzProtocolFaacSLH));
instance->common.name = "Faac SLH";
instance->common.name = "Faac SLH";
instance->common.code_min_count_bit_for_found = 64;
instance->common.te_short = 255;
instance->common.te_long = 595;
instance->common.te_delta = 100;
instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC;
instance->common.type_protocol = SubGhzProtocolCommonTypeDynamic;
instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_faac_slh_to_str;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoadFromRAW)subghz_decoder_faac_slh_to_load_protocol;
@@ -32,7 +38,7 @@ void subghz_protocol_faac_slh_free(SubGhzProtocolFaacSLH* instance) {
* @param bit - bit
*/
void subghz_protocol_faac_slh_send_bit(SubGhzProtocolFaacSLH* instance, uint8_t bit) {
if (bit) {
if(bit) {
//send bit 1
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_long);
@@ -47,22 +53,26 @@ void subghz_protocol_faac_slh_send_bit(SubGhzProtocolFaacSLH* instance, uint8_t
}
}
void subghz_protocol_faac_slh_send_key(SubGhzProtocolFaacSLH* instance, uint64_t key, uint8_t bit,uint8_t repeat) {
while (repeat--) {
void subghz_protocol_faac_slh_send_key(
SubGhzProtocolFaacSLH* instance,
uint64_t key,
uint8_t bit,
uint8_t repeat) {
while(repeat--) {
SUBGHZ_TX_PIN_HIGH();
//Send header
delay_us(instance->common.te_long * 2);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_long * 2);
delay_us(instance->common.te_long * 2);
//Send key data
for (uint8_t i = bit; i > 0; i--) {
for(uint8_t i = bit; i > 0; i--) {
subghz_protocol_faac_slh_send_bit(instance, bit_read(key, i - 1));
}
}
}
void subghz_protocol_faac_slh_reset(SubGhzProtocolFaacSLH* instance) {
instance->common.parser_step = 0;
instance->common.parser_step = FaacSLHDecoderStepReset;
}
/** Analysis of received data
@@ -70,7 +80,8 @@ void subghz_protocol_faac_slh_reset(SubGhzProtocolFaacSLH* instance) {
* @param instance SubGhzProtocolFaacSLH instance
*/
void subghz_protocol_faac_slh_check_remote_controller(SubGhzProtocolFaacSLH* instance) {
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_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_fix = code_found_reverse & 0xFFFFFFFF;
//uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFF;
@@ -79,62 +90,68 @@ void subghz_protocol_faac_slh_check_remote_controller(SubGhzProtocolFaacSLH* ins
}
void subghz_protocol_faac_slh_parse(SubGhzProtocolFaacSLH* instance, bool level, uint32_t duration) {
switch (instance->common.parser_step) {
case 0:
if ((level)
&& (DURATION_DIFF(duration,instance->common.te_long * 2)< instance->common.te_delta * 3)) {
instance->common.parser_step = 1;
switch(instance->common.parser_step) {
case FaacSLHDecoderStepReset:
if((level) && (DURATION_DIFF(duration, instance->common.te_long * 2) <
instance->common.te_delta * 3)) {
instance->common.parser_step = FaacSLHDecoderStepFoundPreambula;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = FaacSLHDecoderStepReset;
}
break;
case 1:
if ((!level)
&& (DURATION_DIFF(duration,instance->common.te_long * 2)< instance->common.te_delta * 3)) {
case FaacSLHDecoderStepFoundPreambula:
if((!level) && (DURATION_DIFF(duration, instance->common.te_long * 2) <
instance->common.te_delta * 3)) {
//Found Preambula
instance->common.parser_step = 2;
instance->common.parser_step = FaacSLHDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = FaacSLHDecoderStepReset;
}
break;
case 2:
if (level) {
if (duration >= (instance->common.te_short * 3 + instance->common.te_delta)) {
instance->common.parser_step = 1;
if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) {
case FaacSLHDecoderStepSaveDuration:
if(level) {
if(duration >= (instance->common.te_short * 3 + instance->common.te_delta)) {
instance->common.parser_step = FaacSLHDecoderStepFoundPreambula;
if(instance->common.code_count_bit >=
instance->common.code_min_count_bit_for_found) {
instance->common.code_last_found = instance->common.code_found;
instance->common.code_last_count_bit = instance->common.code_count_bit;
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;
} else {
instance->common.te_last = duration;
instance->common.parser_step = 3;
instance->common.parser_step = FaacSLHDecoderStepCheckDuration;
}
}else{
instance->common.parser_step = 0;
} else {
instance->common.parser_step = FaacSLHDecoderStepReset;
}
break;
case 3:
if(!level){
if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short)< instance->common.te_delta)
&& (DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta)) {
case FaacSLHDecoderStepCheckDuration:
if(!level) {
if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
instance->common.te_delta) &&
(DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) {
subghz_protocol_common_add_bit(&instance->common, 0);
instance->common.parser_step = 2;
} else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long )< instance->common.te_delta)
&& (DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta)) {
instance->common.parser_step = FaacSLHDecoderStepSaveDuration;
} else if(
(DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
instance->common.te_delta) &&
(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
subghz_protocol_common_add_bit(&instance->common, 1);
instance->common.parser_step = 2;
instance->common.parser_step = FaacSLHDecoderStepSaveDuration;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = FaacSLHDecoderStepReset;
}
} else {
instance->common.parser_step = 0;
instance->common.parser_step = FaacSLHDecoderStepReset;
}
break;
}
@@ -142,28 +159,29 @@ void subghz_protocol_faac_slh_parse(SubGhzProtocolFaacSLH* instance, bool level,
void subghz_protocol_faac_slh_to_str(SubGhzProtocolFaacSLH* instance, string_t output) {
subghz_protocol_faac_slh_check_remote_controller(instance);
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_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_fix = code_found_reverse & 0xFFFFFFFF;
uint32_t code_hop = (code_found_reverse >>32) & 0xFFFFFFFF;
uint32_t code_hop = (code_found_reverse >> 32) & 0xFFFFFFFF;
string_cat_printf(output,
"%s %dbit\r\n"
"Key:0x%lX%08lX\r\n"
"Fix:%08lX \r\n"
"Hop:%08lX \r\n"
"Sn:%07lX Btn:%lX\r\n",
instance->common.name,
instance->common.code_last_count_bit,
(uint32_t)(instance->common.code_last_found >> 32),
(uint32_t)instance->common.code_last_found,
code_fix, code_hop,
instance->common.serial,
instance->common.btn);
string_cat_printf(
output,
"%s %dbit\r\n"
"Key:0x%lX%08lX\r\n"
"Fix:%08lX \r\n"
"Hop:%08lX \r\n"
"Sn:%07lX Btn:%lX\r\n",
instance->common.name,
instance->common.code_last_count_bit,
(uint32_t)(instance->common.code_last_found >> 32),
(uint32_t)instance->common.code_last_found,
code_fix,
code_hop,
instance->common.serial,
instance->common.btn);
}
void subghz_decoder_faac_slh_to_load_protocol(
SubGhzProtocolFaacSLH* instance,
void* context) {
void subghz_decoder_faac_slh_to_load_protocol(SubGhzProtocolFaacSLH* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;

View File

@@ -1,10 +1,16 @@
#include "subghz_protocol_gate_tx.h"
struct SubGhzProtocolGateTX {
SubGhzProtocolCommon common;
};
typedef enum {
GateTXDecoderStepReset = 0,
GateTXDecoderStepFoundStartBit,
GateTXDecoderStepSaveDuration,
GateTXDecoderStepCheckDuration,
} GateTXDecoderStep;
SubGhzProtocolGateTX* subghz_protocol_gate_tx_alloc(void) {
SubGhzProtocolGateTX* instance = furi_alloc(sizeof(SubGhzProtocolGateTX));
@@ -13,11 +19,11 @@ SubGhzProtocolGateTX* subghz_protocol_gate_tx_alloc(void) {
instance->common.te_short = 350;
instance->common.te_long = 700;
instance->common.te_delta = 100;
instance->common.type_protocol = TYPE_PROTOCOL_STATIC;
instance->common.type_protocol = SubGhzProtocolCommonTypeStatic;
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_from_file=
instance->common.to_load_protocol_from_file =
(SubGhzProtocolCommonLoadFromFile)subghz_protocol_gate_tx_to_load_protocol_from_file;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoadFromRAW)subghz_decoder_gate_tx_to_load_protocol;
@@ -31,33 +37,40 @@ void subghz_protocol_gate_tx_free(SubGhzProtocolGateTX* instance) {
free(instance);
}
bool subghz_protocol_gate_tx_send_key(SubGhzProtocolGateTX* instance, SubGhzProtocolCommonEncoder* encoder){
bool subghz_protocol_gate_tx_send_key(
SubGhzProtocolGateTX* instance,
SubGhzProtocolCommonEncoder* encoder) {
furi_assert(instance);
furi_assert(encoder);
size_t index = 0;
encoder->size_upload =(instance->common.code_last_count_bit * 2) + 2;
encoder->size_upload = (instance->common.code_last_count_bit * 2) + 2;
if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false;
//Send header
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short * 49);
encoder->upload[index++] =
level_duration_make(false, (uint32_t)instance->common.te_short * 49);
//Send start bit
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_long);
//Send key data
for (uint8_t i = instance->common.code_last_count_bit; i > 0; i--) {
if(bit_read(instance->common.code_last_found, i - 1)){
for(uint8_t i = instance->common.code_last_count_bit; i > 0; i--) {
if(bit_read(instance->common.code_last_found, i - 1)) {
//send bit 1
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_long);
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short);
}else{
encoder->upload[index++] =
level_duration_make(false, (uint32_t)instance->common.te_long);
encoder->upload[index++] =
level_duration_make(true, (uint32_t)instance->common.te_short);
} else {
//send bit 0
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short);
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_long);
encoder->upload[index++] =
level_duration_make(false, (uint32_t)instance->common.te_short);
encoder->upload[index++] =
level_duration_make(true, (uint32_t)instance->common.te_long);
}
}
return true;
}
void subghz_protocol_gate_tx_reset(SubGhzProtocolGateTX* instance) {
instance->common.parser_step = 0;
instance->common.parser_step = GateTXDecoderStepReset;
}
/** Analysis of received data
@@ -65,68 +78,78 @@ 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_last_found, instance->common.code_last_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.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);
}
void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, uint32_t duration) {
switch (instance->common.parser_step) {
case 0:
if ((!level)
&& (DURATION_DIFF(duration,instance->common.te_short * 47)< instance->common.te_delta * 47)) {
switch(instance->common.parser_step) {
case GateTXDecoderStepReset:
if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 47) <
instance->common.te_delta * 47)) {
//Found Preambula
instance->common.parser_step = 1;
instance->common.parser_step = GateTXDecoderStepFoundStartBit;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = GateTXDecoderStepReset;
}
break;
case 1:
if (level && ((DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta*3))){
case GateTXDecoderStepFoundStartBit:
if(level &&
((DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta * 3))) {
//Found start bit
instance->common.parser_step = 2;
instance->common.parser_step = GateTXDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = GateTXDecoderStepReset;
}
break;
case 2:
if (!level) {
if (duration >= (instance->common.te_short * 10 + instance->common.te_delta)) {
instance->common.parser_step = 1;
if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) {
case GateTXDecoderStepSaveDuration:
if(!level) {
if(duration >= (instance->common.te_short * 10 + instance->common.te_delta)) {
instance->common.parser_step = GateTXDecoderStepFoundStartBit;
if(instance->common.code_count_bit >=
instance->common.code_min_count_bit_for_found) {
instance->common.code_last_found = instance->common.code_found;
instance->common.code_last_count_bit = instance->common.code_count_bit;
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;
} else {
instance->common.te_last = duration;
instance->common.parser_step = 3;
instance->common.parser_step = GateTXDecoderStepCheckDuration;
}
}
break;
case 3:
if(level){
if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short)< instance->common.te_delta)
&& (DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta*3)) {
break;
case GateTXDecoderStepCheckDuration:
if(level) {
if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
instance->common.te_delta) &&
(DURATION_DIFF(duration, instance->common.te_long) <
instance->common.te_delta * 3)) {
subghz_protocol_common_add_bit(&instance->common, 0);
instance->common.parser_step = 2;
} else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long)< instance->common.te_delta*3)
&& (DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta)) {
instance->common.parser_step = GateTXDecoderStepSaveDuration;
} else if(
(DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
instance->common.te_delta * 3) &&
(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
subghz_protocol_common_add_bit(&instance->common, 1);
instance->common.parser_step = 2;
instance->common.parser_step = GateTXDecoderStepSaveDuration;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = GateTXDecoderStepReset;
}
}else{
instance->common.parser_step = 0;
} else {
instance->common.parser_step = GateTXDecoderStepReset;
}
break;
}
@@ -134,16 +157,16 @@ void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, u
void subghz_protocol_gate_tx_to_str(SubGhzProtocolGateTX* instance, string_t output) {
subghz_protocol_gate_tx_check_remote_controller(instance);
string_cat_printf(output,
"%s %dbit\r\n"
"Key:%06lX\r\n"
"Sn:%05lX Btn:%lX\r\n",
instance->common.name,
instance->common.code_last_count_bit,
(uint32_t)(instance->common.code_last_found & 0xFFFFFF),
instance->common.serial,
instance->common.btn
);
string_cat_printf(
output,
"%s %dbit\r\n"
"Key:%06lX\r\n"
"Sn:%05lX Btn:%lX\r\n",
instance->common.name,
instance->common.code_last_count_bit,
(uint32_t)(instance->common.code_last_found & 0xFFFFFF),
instance->common.serial,
instance->common.btn);
}
void subghz_protocol_gate_tx_to_save_str(SubGhzProtocolGateTX* instance, string_t output) {
@@ -157,7 +180,9 @@ void subghz_protocol_gate_tx_to_save_str(SubGhzProtocolGateTX* instance, string_
(uint32_t)(instance->common.code_last_found & 0x00000000ffffffff));
}
bool subghz_protocol_gate_tx_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolGateTX* instance){
bool subghz_protocol_gate_tx_to_load_protocol_from_file(
FileWorker* file_worker,
SubGhzProtocolGateTX* instance) {
bool loaded = false;
string_t temp_str;
string_init(temp_str);
@@ -195,9 +220,7 @@ bool subghz_protocol_gate_tx_to_load_protocol_from_file(FileWorker* file_worker,
return loaded;
}
void subghz_decoder_gate_tx_to_load_protocol(
SubGhzProtocolGateTX* instance,
void* context) {
void subghz_decoder_gate_tx_to_load_protocol(SubGhzProtocolGateTX* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;

View File

@@ -4,6 +4,13 @@ struct SubGhzProtocolIDo {
SubGhzProtocolCommon common;
};
typedef enum {
IDoDecoderStepReset = 0,
IDoDecoderStepFoundPreambula,
IDoDecoderStepSaveDuration,
IDoDecoderStepCheckDuration,
} IDoDecoderStep;
SubGhzProtocolIDo* subghz_protocol_ido_alloc(void) {
SubGhzProtocolIDo* instance = furi_alloc(sizeof(SubGhzProtocolIDo));
@@ -12,7 +19,7 @@ SubGhzProtocolIDo* subghz_protocol_ido_alloc(void) {
instance->common.te_short = 450;
instance->common.te_long = 1450;
instance->common.te_delta = 150;
instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC;
instance->common.type_protocol = SubGhzProtocolCommonTypeDynamic;
instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_ido_to_str;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoadFromRAW)subghz_decoder_ido_to_load_protocol;
@@ -65,7 +72,7 @@ void subghz_protocol_ido_send_key(
}
void subghz_protocol_ido_reset(SubGhzProtocolIDo* instance) {
instance->common.parser_step = 0;
instance->common.parser_step = IDoDecoderStepReset;
}
/** Analysis of received data
@@ -83,29 +90,29 @@ void subghz_protocol_ido_check_remote_controller(SubGhzProtocolIDo* instance) {
void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t duration) {
switch(instance->common.parser_step) {
case 0:
case IDoDecoderStepReset:
if((level) && (DURATION_DIFF(duration, instance->common.te_short * 10) <
instance->common.te_delta * 5)) {
instance->common.parser_step = 1;
instance->common.parser_step = IDoDecoderStepFoundPreambula;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = IDoDecoderStepReset;
}
break;
case 1:
case IDoDecoderStepFoundPreambula:
if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 10) <
instance->common.te_delta * 5)) {
//Found Preambula
instance->common.parser_step = 2;
instance->common.parser_step = IDoDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = IDoDecoderStepReset;
}
break;
case 2:
case IDoDecoderStepSaveDuration:
if(level) {
if(duration >= (instance->common.te_short * 5 + instance->common.te_delta)) {
instance->common.parser_step = 1;
instance->common.parser_step = IDoDecoderStepFoundPreambula;
if(instance->common.code_count_bit >=
instance->common.code_min_count_bit_for_found) {
instance->common.code_last_found = instance->common.code_found;
@@ -119,32 +126,32 @@ void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t
break;
} else {
instance->common.te_last = duration;
instance->common.parser_step = 3;
instance->common.parser_step = IDoDecoderStepCheckDuration;
}
} else {
instance->common.parser_step = 0;
instance->common.parser_step = IDoDecoderStepReset;
}
break;
case 3:
case IDoDecoderStepCheckDuration:
if(!level) {
if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
instance->common.te_delta) &&
(DURATION_DIFF(duration, instance->common.te_long) <
instance->common.te_delta * 3)) {
subghz_protocol_common_add_bit(&instance->common, 0);
instance->common.parser_step = 2;
instance->common.parser_step = IDoDecoderStepSaveDuration;
} else if(
(DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
instance->common.te_delta * 3) &&
(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
subghz_protocol_common_add_bit(&instance->common, 1);
instance->common.parser_step = 2;
instance->common.parser_step = IDoDecoderStepSaveDuration;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = IDoDecoderStepReset;
}
} else {
instance->common.parser_step = 0;
instance->common.parser_step = IDoDecoderStepReset;
}
break;
}
@@ -174,9 +181,7 @@ void subghz_protocol_ido_to_str(SubGhzProtocolIDo* instance, string_t output) {
instance->common.btn);
}
void subghz_decoder_ido_to_load_protocol(
SubGhzProtocolIDo* instance,
void* context) {
void subghz_decoder_ido_to_load_protocol(SubGhzProtocolIDo* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;

View File

@@ -13,6 +13,13 @@ struct SubGhzProtocolKeeloq {
const char* manufacture_name;
};
typedef enum {
KeeloqDecoderStepReset = 0,
KeeloqDecoderStepCheckPreambula,
KeeloqDecoderStepSaveDuration,
KeeloqDecoderStepCheckDuration,
} KeeloqDecoderStep;
SubGhzProtocolKeeloq* subghz_protocol_keeloq_alloc(SubGhzKeystore* keystore) {
SubGhzProtocolKeeloq* instance = furi_alloc(sizeof(SubGhzProtocolKeeloq));
@@ -23,7 +30,7 @@ SubGhzProtocolKeeloq* subghz_protocol_keeloq_alloc(SubGhzKeystore* keystore) {
instance->common.te_short = 400;
instance->common.te_long = 800;
instance->common.te_delta = 140;
instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC;
instance->common.type_protocol = SubGhzProtocolCommonTypeDynamic;
instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_keeloq_to_str;
instance->common.to_save_string =
(SubGhzProtocolCommonGetStrSave)subghz_protocol_keeloq_to_save_str;
@@ -297,50 +304,50 @@ bool subghz_protocol_keeloq_send_key(
}
void subghz_protocol_keeloq_reset(SubGhzProtocolKeeloq* instance) {
instance->common.parser_step = 0;
instance->common.parser_step = KeeloqDecoderStepReset;
}
void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, uint32_t duration) {
switch(instance->common.parser_step) {
case 0:
case KeeloqDecoderStepReset:
if((level) &&
DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) {
instance->common.parser_step = 1;
instance->common.parser_step = KeeloqDecoderStepCheckPreambula;
instance->common.header_count++;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = KeeloqDecoderStepReset;
}
break;
case 1:
case KeeloqDecoderStepCheckPreambula:
if((!level) &&
(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
instance->common.parser_step = 0;
instance->common.parser_step = KeeloqDecoderStepReset;
break;
}
if((instance->common.header_count > 2) &&
(DURATION_DIFF(duration, instance->common.te_short * 10) <
instance->common.te_delta * 10)) {
// Found header
instance->common.parser_step = 2;
instance->common.parser_step = KeeloqDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = KeeloqDecoderStepReset;
instance->common.header_count = 0;
}
break;
case 2:
case KeeloqDecoderStepSaveDuration:
if(level) {
instance->common.te_last = duration;
instance->common.parser_step = 3;
instance->common.parser_step = KeeloqDecoderStepCheckDuration;
}
break;
case 3:
case KeeloqDecoderStepCheckDuration:
if(!level) {
if(duration >= (instance->common.te_short * 2 + instance->common.te_delta)) {
// Found end TX
instance->common.parser_step = 0;
instance->common.parser_step = KeeloqDecoderStepReset;
if(instance->common.code_count_bit >=
instance->common.code_min_count_bit_for_found) {
if(instance->common.code_last_found != instance->common.code_found) {
@@ -363,7 +370,7 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui
instance->common.code_min_count_bit_for_found) {
subghz_protocol_common_add_bit(&instance->common, 1);
}
instance->common.parser_step = 2;
instance->common.parser_step = KeeloqDecoderStepSaveDuration;
} else if(
(DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
instance->common.te_delta) &&
@@ -372,13 +379,13 @@ void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, ui
instance->common.code_min_count_bit_for_found) {
subghz_protocol_common_add_bit(&instance->common, 0);
}
instance->common.parser_step = 2;
instance->common.parser_step = KeeloqDecoderStepSaveDuration;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = KeeloqDecoderStepReset;
instance->common.header_count = 0;
}
} else {
instance->common.parser_step = 0;
instance->common.parser_step = KeeloqDecoderStepReset;
instance->common.header_count = 0;
}
break;

View File

@@ -4,6 +4,13 @@ struct SubGhzProtocolNeroRadio {
SubGhzProtocolCommon common;
};
typedef enum {
NeroRadioDecoderStepReset = 0,
NeroRadioDecoderStepCheckPreambula,
NeroRadioDecoderStepSaveDuration,
NeroRadioDecoderStepCheckDuration,
} NeroRadioDecoderStep;
SubGhzProtocolNeroRadio* subghz_protocol_nero_radio_alloc(void) {
SubGhzProtocolNeroRadio* instance = furi_alloc(sizeof(SubGhzProtocolNeroRadio));
@@ -12,7 +19,7 @@ SubGhzProtocolNeroRadio* subghz_protocol_nero_radio_alloc(void) {
instance->common.te_short = 200;
instance->common.te_long = 400;
instance->common.te_delta = 80;
instance->common.type_protocol = TYPE_PROTOCOL_STATIC;
instance->common.type_protocol = SubGhzProtocolCommonTypeStatic;
instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nero_radio_to_str;
instance->common.to_save_string =
(SubGhzProtocolCommonGetStrSave)subghz_protocol_nero_radio_to_save_str;
@@ -74,7 +81,7 @@ bool subghz_protocol_nero_radio_send_key(
}
void subghz_protocol_nero_radio_reset(SubGhzProtocolNeroRadio* instance) {
instance->common.parser_step = 0;
instance->common.parser_step = NeroRadioDecoderStepReset;
}
/** Analysis of received data
@@ -99,24 +106,24 @@ void subghz_protocol_nero_radio_parse(
bool level,
uint32_t duration) {
switch(instance->common.parser_step) {
case 0:
case NeroRadioDecoderStepReset:
if((level) &&
(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
instance->common.parser_step = 1;
instance->common.parser_step = NeroRadioDecoderStepCheckPreambula;
instance->common.te_last = duration;
instance->common.header_count = 0;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NeroRadioDecoderStepReset;
}
break;
case 1:
case NeroRadioDecoderStepCheckPreambula:
if(level) {
if((DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) ||
(DURATION_DIFF(duration, instance->common.te_short * 4) <
instance->common.te_delta)) {
instance->common.te_last = duration;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NeroRadioDecoderStepReset;
}
} else if(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) {
if(DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
@@ -129,32 +136,32 @@ void subghz_protocol_nero_radio_parse(
instance->common.te_delta) {
// Found start bit
if(instance->common.header_count > 40) {
instance->common.parser_step = 2;
instance->common.parser_step = NeroRadioDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NeroRadioDecoderStepReset;
}
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NeroRadioDecoderStepReset;
}
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NeroRadioDecoderStepReset;
}
break;
case 2:
case NeroRadioDecoderStepSaveDuration:
if(level) {
instance->common.te_last = duration;
instance->common.parser_step = 3;
instance->common.parser_step = NeroRadioDecoderStepCheckDuration;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NeroRadioDecoderStepReset;
}
break;
case 3:
case NeroRadioDecoderStepCheckDuration:
if(!level) {
if(duration >= (instance->common.te_short * 10 + instance->common.te_delta * 2)) {
//Found stop bit
instance->common.parser_step = 0;
instance->common.parser_step = NeroRadioDecoderStepReset;
if(instance->common.code_count_bit >=
instance->common.code_min_count_bit_for_found) {
instance->common.code_last_found = instance->common.code_found;
@@ -165,25 +172,25 @@ void subghz_protocol_nero_radio_parse(
}
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
instance->common.parser_step = 0;
instance->common.parser_step = NeroRadioDecoderStepReset;
break;
} else if(
(DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
instance->common.te_delta) &&
(DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) {
subghz_protocol_common_add_bit(&instance->common, 0);
instance->common.parser_step = 2;
instance->common.parser_step = NeroRadioDecoderStepSaveDuration;
} else if(
(DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
instance->common.te_delta) &&
(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
subghz_protocol_common_add_bit(&instance->common, 1);
instance->common.parser_step = 2;
instance->common.parser_step = NeroRadioDecoderStepSaveDuration;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NeroRadioDecoderStepReset;
}
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NeroRadioDecoderStepReset;
}
break;
}

View File

@@ -1,23 +1,29 @@
#include "subghz_protocol_nero_sketch.h"
struct SubGhzProtocolNeroSketch {
SubGhzProtocolCommon common;
};
typedef enum {
NeroSketchDecoderStepReset = 0,
NeroSketchDecoderStepCheckPreambula,
NeroSketchDecoderStepSaveDuration,
NeroSketchDecoderStepCheckDuration,
} NeroSketchDecoderStep;
SubGhzProtocolNeroSketch* subghz_protocol_nero_sketch_alloc(void) {
SubGhzProtocolNeroSketch* instance = furi_alloc(sizeof(SubGhzProtocolNeroSketch));
instance->common.name = "Nero Sketch";
instance->common.name = "Nero Sketch";
instance->common.code_min_count_bit_for_found = 40;
instance->common.te_short = 330;
instance->common.te_long = 660;
instance->common.te_delta = 150;
instance->common.type_protocol = TYPE_PROTOCOL_STATIC;
instance->common.type_protocol = SubGhzProtocolCommonTypeStatic;
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_from_file=
instance->common.to_load_protocol_from_file =
(SubGhzProtocolCommonLoadFromFile)subghz_protocol_nero_sketch_to_load_protocol_from_file;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoadFromRAW)subghz_decoder_nero_sketch_to_load_protocol;
@@ -32,45 +38,51 @@ void subghz_protocol_nero_sketch_free(SubGhzProtocolNeroSketch* instance) {
free(instance);
}
bool subghz_protocol_nero_sketch_send_key(SubGhzProtocolNeroSketch* instance, SubGhzProtocolCommonEncoder* encoder){
bool subghz_protocol_nero_sketch_send_key(
SubGhzProtocolNeroSketch* instance,
SubGhzProtocolCommonEncoder* encoder) {
furi_assert(instance);
furi_assert(encoder);
size_t index = 0;
encoder->size_upload = 47*2+2+(instance->common.code_last_count_bit * 2) + 2;
encoder->size_upload = 47 * 2 + 2 + (instance->common.code_last_count_bit * 2) + 2;
if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false;
//Send header
for(uint8_t i = 0; i < 47; i++){
for(uint8_t i = 0; i < 47; i++) {
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short);
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short);
}
//Send start bit
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short*4);
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short * 4);
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short);
//Send key data
for (uint8_t i = instance->common.code_last_count_bit; i > 0; i--) {
if(bit_read(instance->common.code_last_found, i - 1)){
for(uint8_t i = instance->common.code_last_count_bit; i > 0; i--) {
if(bit_read(instance->common.code_last_found, i - 1)) {
//send bit 1
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_long);
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short);
}else{
encoder->upload[index++] =
level_duration_make(true, (uint32_t)instance->common.te_long);
encoder->upload[index++] =
level_duration_make(false, (uint32_t)instance->common.te_short);
} else {
//send bit 0
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short);
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_long);
encoder->upload[index++] =
level_duration_make(true, (uint32_t)instance->common.te_short);
encoder->upload[index++] =
level_duration_make(false, (uint32_t)instance->common.te_long);
}
}
//Send stop bit
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short*3);
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short * 3);
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short);
return true;
}
void subghz_protocol_nero_sketch_reset(SubGhzProtocolNeroSketch* instance) {
instance->common.parser_step = 0;
instance->common.parser_step = NeroSketchDecoderStepReset;
}
/** Analysis of received data
@@ -90,112 +102,123 @@ void subghz_protocol_nero_sketch_reset(SubGhzProtocolNeroSketch* instance) {
// }
void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool level, uint32_t duration) {
switch (instance->common.parser_step) {
case 0:
if ((level)
&& (DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta)) {
instance->common.parser_step = 1;
void subghz_protocol_nero_sketch_parse(
SubGhzProtocolNeroSketch* instance,
bool level,
uint32_t duration) {
switch(instance->common.parser_step) {
case NeroSketchDecoderStepReset:
if((level) &&
(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
instance->common.parser_step = NeroSketchDecoderStepCheckPreambula;
instance->common.te_last = duration;
instance->common.header_count = 0;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NeroSketchDecoderStepReset;
}
break;
case 1:
if (level){
if((DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta )
|| (DURATION_DIFF(duration,instance->common.te_short*4)< instance->common.te_delta)) {
case NeroSketchDecoderStepCheckPreambula:
if(level) {
if((DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) ||
(DURATION_DIFF(duration, instance->common.te_short * 4) <
instance->common.te_delta)) {
instance->common.te_last = duration;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NeroSketchDecoderStepReset;
}
} else if(DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta){
if(DURATION_DIFF(instance->common.te_last,instance->common.te_short)< instance->common.te_delta){
} else if(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) {
if(DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
instance->common.te_delta) {
// Found header
instance->common.header_count++;
break;
}else if(DURATION_DIFF(instance->common.te_last,instance->common.te_short*4)< instance->common.te_delta){
// Found start bit
if(instance->common.header_count>40) {
instance->common.parser_step = 2;
} else if(
DURATION_DIFF(instance->common.te_last, instance->common.te_short * 4) <
instance->common.te_delta) {
// Found start bit
if(instance->common.header_count > 40) {
instance->common.parser_step = NeroSketchDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
}else {
instance->common.parser_step = 0;
}
} else {
instance->common.parser_step = NeroSketchDecoderStepReset;
}
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NeroSketchDecoderStepReset;
}
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NeroSketchDecoderStepReset;
}
break;
case 2:
if (level) {
if (duration >= (instance->common.te_short * 2 + instance->common.te_delta*2)) {
case NeroSketchDecoderStepSaveDuration:
if(level) {
if(duration >= (instance->common.te_short * 2 + instance->common.te_delta * 2)) {
//Found stop bit
instance->common.parser_step = 0;
if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) {
instance->common.parser_step = NeroSketchDecoderStepReset;
if(instance->common.code_count_bit >=
instance->common.code_min_count_bit_for_found) {
instance->common.code_last_found = instance->common.code_found;
instance->common.code_last_count_bit = instance->common.code_count_bit;
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;
} else {
instance->common.te_last = duration;
instance->common.parser_step = 3;
instance->common.parser_step = NeroSketchDecoderStepCheckDuration;
}
}else{
instance->common.parser_step = 0;
} else {
instance->common.parser_step = NeroSketchDecoderStepReset;
}
break;
case 3:
if(!level){
if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short)< instance->common.te_delta)
&& (DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta)) {
case NeroSketchDecoderStepCheckDuration:
if(!level) {
if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
instance->common.te_delta) &&
(DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) {
subghz_protocol_common_add_bit(&instance->common, 0);
instance->common.parser_step = 2;
} else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long )< instance->common.te_delta)
&& (DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta)) {
instance->common.parser_step = NeroSketchDecoderStepSaveDuration;
} else if(
(DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
instance->common.te_delta) &&
(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
subghz_protocol_common_add_bit(&instance->common, 1);
instance->common.parser_step = 2;
instance->common.parser_step = NeroSketchDecoderStepSaveDuration;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NeroSketchDecoderStepReset;
}
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NeroSketchDecoderStepReset;
}
break;
}
}
void subghz_protocol_nero_sketch_to_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;
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_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,
"%s %dbit\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
);
string_cat_printf(
output,
"%s %dbit\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_nero_sketch_to_save_str(SubGhzProtocolNeroSketch* instance, string_t output) {
@@ -210,11 +233,12 @@ void subghz_protocol_nero_sketch_to_save_str(SubGhzProtocolNeroSketch* instance,
instance->common.name,
instance->common.code_last_count_bit,
code_found_hi,
code_found_lo
);
code_found_lo);
}
bool subghz_protocol_nero_sketch_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolNeroSketch* instance){
bool subghz_protocol_nero_sketch_to_load_protocol_from_file(
FileWorker* file_worker,
SubGhzProtocolNeroSketch* instance) {
bool loaded = false;
string_t temp_str;
string_init(temp_str);
@@ -242,7 +266,7 @@ bool subghz_protocol_nero_sketch_to_load_protocol_from_file(FileWorker* file_wor
if(res != 2) {
break;
}
instance->common.code_last_found = (uint64_t)temp_key_hi<<32 | temp_key_lo;
instance->common.code_last_found = (uint64_t)temp_key_hi << 32 | temp_key_lo;
loaded = true;
} while(0);
@@ -252,9 +276,7 @@ bool subghz_protocol_nero_sketch_to_load_protocol_from_file(FileWorker* file_wor
return loaded;
}
void subghz_decoder_nero_sketch_to_load_protocol(
SubGhzProtocolNeroSketch* instance,
void* context) {
void subghz_decoder_nero_sketch_to_load_protocol(SubGhzProtocolNeroSketch* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;

View File

@@ -10,6 +10,13 @@ struct SubGhzProtocolNiceFlo {
SubGhzProtocolCommon common;
};
typedef enum {
NiceFloDecoderStepReset = 0,
NiceFloDecoderStepFoundStartBit,
NiceFloDecoderStepSaveDuration,
NiceFloDecoderStepCheckDuration,
} NiceFloDecoderStep;
SubGhzProtocolNiceFlo* subghz_protocol_nice_flo_alloc() {
SubGhzProtocolNiceFlo* instance = furi_alloc(sizeof(SubGhzProtocolNiceFlo));
@@ -18,11 +25,11 @@ SubGhzProtocolNiceFlo* subghz_protocol_nice_flo_alloc() {
instance->common.te_short = 700;
instance->common.te_long = 1400;
instance->common.te_delta = 200;
instance->common.type_protocol = TYPE_PROTOCOL_STATIC;
instance->common.type_protocol = SubGhzProtocolCommonTypeStatic;
instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nice_flo_to_str;
instance->common.to_save_string =
(SubGhzProtocolCommonGetStrSave)subghz_protocol_nice_flo_to_save_str;
instance->common.to_load_protocol_from_file=
instance->common.to_load_protocol_from_file =
(SubGhzProtocolCommonLoadFromFile)subghz_protocol_nice_flo_to_load_protocol_from_file;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoadFromRAW)subghz_decoder_nice_flo_to_load_protocol;
@@ -36,94 +43,105 @@ void subghz_protocol_nice_flo_free(SubGhzProtocolNiceFlo* instance) {
free(instance);
}
bool subghz_protocol_nice_flo_send_key(SubGhzProtocolNiceFlo* instance, SubGhzProtocolCommonEncoder* encoder){
bool subghz_protocol_nice_flo_send_key(
SubGhzProtocolNiceFlo* instance,
SubGhzProtocolCommonEncoder* encoder) {
furi_assert(instance);
furi_assert(encoder);
size_t index = 0;
encoder->size_upload =(instance->common.code_last_count_bit * 2) + 2;
encoder->size_upload = (instance->common.code_last_count_bit * 2) + 2;
if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false;
//Send header
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short * 36);
encoder->upload[index++] =
level_duration_make(false, (uint32_t)instance->common.te_short * 36);
//Send start bit
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short);
//Send key data
for (uint8_t i = instance->common.code_last_count_bit; i > 0; i--) {
if(bit_read(instance->common.code_last_found, i - 1)){
for(uint8_t i = instance->common.code_last_count_bit; i > 0; i--) {
if(bit_read(instance->common.code_last_found, i - 1)) {
//send bit 1
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_long);
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_short);
}else{
encoder->upload[index++] =
level_duration_make(false, (uint32_t)instance->common.te_long);
encoder->upload[index++] =
level_duration_make(true, (uint32_t)instance->common.te_short);
} else {
//send bit 0
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short);
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->common.te_long);
encoder->upload[index++] =
level_duration_make(false, (uint32_t)instance->common.te_short);
encoder->upload[index++] =
level_duration_make(true, (uint32_t)instance->common.te_long);
}
}
return true;
}
void subghz_protocol_nice_flo_reset(SubGhzProtocolNiceFlo* instance) {
instance->common.parser_step = 0;
instance->common.parser_step = NiceFloDecoderStepReset;
}
void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, bool level, uint32_t duration) {
switch (instance->common.parser_step) {
case 0:
if ((!level)
&& (DURATION_DIFF(duration, instance->common.te_short * 36)< instance->common.te_delta * 36)) {
switch(instance->common.parser_step) {
case NiceFloDecoderStepReset:
if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 36) <
instance->common.te_delta * 36)) {
//Found header Nice Flo
instance->common.parser_step = 1;
instance->common.parser_step = NiceFloDecoderStepFoundStartBit;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NiceFloDecoderStepReset;
}
break;
case 1:
if (!level) {
case NiceFloDecoderStepFoundStartBit:
if(!level) {
break;
} else if (DURATION_DIFF(duration, instance->common.te_short)< instance->common.te_delta) {
} else if(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) {
//Found start bit Nice Flo
instance->common.parser_step = 2;
instance->common.parser_step = NiceFloDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NiceFloDecoderStepReset;
}
break;
case 2:
if (!level) { //save interval
if (duration >= (instance->common.te_short * 4)) {
instance->common.parser_step = 1;
if (instance->common.code_count_bit>= instance->common.code_min_count_bit_for_found) {
case NiceFloDecoderStepSaveDuration:
if(!level) { //save interval
if(duration >= (instance->common.te_short * 4)) {
instance->common.parser_step = NiceFloDecoderStepFoundStartBit;
if(instance->common.code_count_bit >=
instance->common.code_min_count_bit_for_found) {
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);
if(instance->common.callback)
instance->common.callback(
(SubGhzProtocolCommon*)instance, instance->common.context);
}
break;
}
instance->common.te_last = duration;
instance->common.parser_step = 3;
instance->common.parser_step = NiceFloDecoderStepCheckDuration;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NiceFloDecoderStepReset;
}
break;
case 3:
if (level) {
if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short) < instance->common.te_delta)
&& (DURATION_DIFF(duration, instance->common.te_long)< instance->common.te_delta)) {
case NiceFloDecoderStepCheckDuration:
if(level) {
if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
instance->common.te_delta) &&
(DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) {
subghz_protocol_common_add_bit(&instance->common, 0);
instance->common.parser_step = 2;
} else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long)< instance->common.te_delta)
&& (DURATION_DIFF(duration, instance->common.te_short)< instance->common.te_delta)) {
instance->common.parser_step = NiceFloDecoderStepSaveDuration;
} else if(
(DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
instance->common.te_delta) &&
(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
subghz_protocol_common_add_bit(&instance->common, 1);
instance->common.parser_step = 2;
instance->common.parser_step = NiceFloDecoderStepSaveDuration;
} else
instance->common.parser_step = 0;
instance->common.parser_step = NiceFloDecoderStepReset;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NiceFloDecoderStepReset;
}
break;
}
@@ -145,11 +163,9 @@ void subghz_protocol_nice_flo_to_str(SubGhzProtocolNiceFlo* instance, string_t o
instance->common.name,
instance->common.code_last_count_bit,
code_found_lo,
code_found_reverse_lo
);
code_found_reverse_lo);
}
void subghz_protocol_nice_flo_to_save_str(SubGhzProtocolNiceFlo* instance, string_t output) {
string_printf(
output,
@@ -161,7 +177,9 @@ void subghz_protocol_nice_flo_to_save_str(SubGhzProtocolNiceFlo* instance, strin
(uint32_t)(instance->common.code_last_found & 0x00000000ffffffff));
}
bool subghz_protocol_nice_flo_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolNiceFlo* instance){
bool subghz_protocol_nice_flo_to_load_protocol_from_file(
FileWorker* file_worker,
SubGhzProtocolNiceFlo* instance) {
bool loaded = false;
string_t temp_str;
string_init(temp_str);
@@ -198,9 +216,7 @@ bool subghz_protocol_nice_flo_to_load_protocol_from_file(FileWorker* file_worker
return loaded;
}
void subghz_decoder_nice_flo_to_load_protocol(
SubGhzProtocolNiceFlo* instance,
void* context) {
void subghz_decoder_nice_flo_to_load_protocol(SubGhzProtocolNiceFlo* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;

View File

@@ -13,6 +13,14 @@ struct SubGhzProtocolNiceFlorS {
const char* rainbow_table_file_name;
};
typedef enum {
NiceFlorSDecoderStepReset = 0,
NiceFlorSDecoderStepCheckHeader,
NiceFlorSDecoderStepFoundHeader,
NiceFlorSDecoderStepSaveDuration,
NiceFlorSDecoderStepCheckDuration,
} NiceFlorSDecoderStep;
SubGhzProtocolNiceFlorS* subghz_protocol_nice_flor_s_alloc() {
SubGhzProtocolNiceFlorS* instance = furi_alloc(sizeof(SubGhzProtocolNiceFlorS));
@@ -21,7 +29,7 @@ SubGhzProtocolNiceFlorS* subghz_protocol_nice_flor_s_alloc() {
instance->common.te_short = 500;
instance->common.te_long = 1000;
instance->common.te_delta = 300;
instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC;
instance->common.type_protocol = SubGhzProtocolCommonTypeDynamic;
instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_nice_flor_s_to_str;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoadFromRAW)subghz_decoder_nice_flor_s_to_load_protocol;
@@ -93,16 +101,14 @@ void subghz_protocol_nice_flor_s_send_key(
* @return byte data
*/
uint8_t subghz_nice_flor_s_get_byte_in_file(SubGhzProtocolNiceFlorS* instance, uint32_t address) {
if(!instance->rainbow_table_file_name)
return 0;
if(!instance->rainbow_table_file_name) return 0;
uint8_t buffer = 0;
FileWorker* file_worker = file_worker_alloc(true);
if(file_worker_open(file_worker, instance->rainbow_table_file_name, FSAM_READ, FSOM_OPEN_EXISTING)) {
if(file_worker_open(
file_worker, instance->rainbow_table_file_name, FSAM_READ, FSOM_OPEN_EXISTING)) {
file_worker_seek(file_worker, address, true);
file_worker_read(file_worker, &buffer, 1);
// bool res = file_worker_read(file_worker, &buffer, 1);
// furi_assert(res== true);
}
file_worker_close(file_worker);
file_worker_free(file_worker);
@@ -134,8 +140,11 @@ void subghz_nice_flor_s_decoder_decrypt(SubGhzProtocolNiceFlorS* instance) {
*/
uint16_t p3p4 = (uint16_t)(instance->common.code_last_found >> 24);
instance->common.cnt = subghz_nice_flor_s_get_byte_in_file(instance,p3p4*2) << 8 | subghz_nice_flor_s_get_byte_in_file(instance,p3p4*2+1);
uint8_t k =(uint8_t)(p3p4 & 0x00FF) ^subghz_nice_flor_s_get_byte_in_file(instance,(0x20000 |(instance->common.cnt &0x00ff)));
instance->common.cnt = subghz_nice_flor_s_get_byte_in_file(instance, p3p4 * 2) << 8 |
subghz_nice_flor_s_get_byte_in_file(instance, p3p4 * 2 + 1);
uint8_t k =
(uint8_t)(p3p4 & 0x00FF) ^
subghz_nice_flor_s_get_byte_in_file(instance, (0x20000 | (instance->common.cnt & 0x00ff)));
uint8_t s3 = ((uint8_t)(instance->common.code_last_found >> 40) ^ k) & 0x0f;
uint8_t s2 = ((uint8_t)(instance->common.code_last_found >> 16) ^ k);
@@ -147,73 +156,82 @@ void subghz_nice_flor_s_decoder_decrypt(SubGhzProtocolNiceFlorS* instance) {
}
void subghz_protocol_nice_flor_s_reset(SubGhzProtocolNiceFlorS* instance) {
instance->common.parser_step = 0;
instance->common.parser_step = NiceFlorSDecoderStepReset;
}
void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, bool level, uint32_t duration) {
void subghz_protocol_nice_flor_s_parse(
SubGhzProtocolNiceFlorS* instance,
bool level,
uint32_t duration) {
switch(instance->common.parser_step) {
case 0:
if((!level)
&& (DURATION_DIFF(duration, instance->common.te_short * 38) < instance->common.te_delta * 38)) {
case NiceFlorSDecoderStepReset:
if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 38) <
instance->common.te_delta * 38)) {
//Found start header Nice Flor-S
instance->common.parser_step = 1;
instance->common.parser_step = NiceFlorSDecoderStepCheckHeader;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NiceFlorSDecoderStepReset;
}
break;
case 1:
if((level)
&& (DURATION_DIFF(duration, instance->common.te_short * 3) < instance->common.te_delta * 3)) {
case NiceFlorSDecoderStepCheckHeader:
if((level) && (DURATION_DIFF(duration, instance->common.te_short * 3) <
instance->common.te_delta * 3)) {
//Found next header Nice Flor-S
instance->common.parser_step = 2;
instance->common.parser_step = NiceFlorSDecoderStepFoundHeader;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NiceFlorSDecoderStepReset;
}
break;
case 2:
if((!level)
&& (DURATION_DIFF(duration, instance->common.te_short * 3) < instance->common.te_delta * 3)) {
case NiceFlorSDecoderStepFoundHeader:
if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 3) <
instance->common.te_delta * 3)) {
//Found header Nice Flor-S
instance->common.parser_step = 3;
instance->common.parser_step = NiceFlorSDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NiceFlorSDecoderStepReset;
}
break;
case 3:
case NiceFlorSDecoderStepSaveDuration:
if(level) {
if(DURATION_DIFF(duration, instance->common.te_short * 3) < instance->common.te_delta) {
if(DURATION_DIFF(duration, instance->common.te_short * 3) <
instance->common.te_delta) {
//Found STOP bit
instance->common.parser_step = 0;
if(instance->common.code_count_bit >=instance->common.code_min_count_bit_for_found) {
instance->common.parser_step = NiceFlorSDecoderStepReset;
if(instance->common.code_count_bit >=
instance->common.code_min_count_bit_for_found) {
instance->common.code_last_found = instance->common.code_found;
instance->common.code_last_count_bit = instance->common.code_count_bit;
if(instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
if(instance->common.callback)
instance->common.callback(
(SubGhzProtocolCommon*)instance, instance->common.context);
}
break;
} else {
//save interval
instance->common.te_last = duration;
instance->common.parser_step = 4;
instance->common.parser_step = NiceFlorSDecoderStepCheckDuration;
}
}
break;
case 4:
case NiceFlorSDecoderStepCheckDuration:
if(!level) {
if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) < instance->common.te_delta)
&&(DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) {
if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
instance->common.te_delta) &&
(DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) {
subghz_protocol_common_add_bit(&instance->common, 0);
instance->common.parser_step = 3;
instance->common.parser_step = NiceFlorSDecoderStepSaveDuration;
} else if(
(DURATION_DIFF(instance->common.te_last, instance->common.te_long) < instance->common.te_delta)
&&(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
(DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
instance->common.te_delta) &&
(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
subghz_protocol_common_add_bit(&instance->common, 1);
instance->common.parser_step = 3;
instance->common.parser_step = NiceFlorSDecoderStepSaveDuration;
} else
instance->common.parser_step = 0;
instance->common.parser_step = NiceFlorSDecoderStepReset;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = NiceFlorSDecoderStepReset;
}
break;
}
@@ -236,13 +254,10 @@ void subghz_protocol_nice_flor_s_to_str(SubGhzProtocolNiceFlorS* instance, strin
code_found_lo,
instance->common.serial,
instance->common.cnt,
instance->common.btn
);
instance->common.btn);
}
void subghz_decoder_nice_flor_s_to_load_protocol(
SubGhzProtocolNiceFlorS* instance,
void* context) {
void subghz_decoder_nice_flor_s_to_load_protocol(SubGhzProtocolNiceFlorS* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;

View File

@@ -16,6 +16,12 @@ struct SubGhzEncoderPrinceton {
size_t front;
};
typedef enum {
PrincetonDecoderStepReset = 0,
PrincetonDecoderStepSaveDuration,
PrincetonDecoderStepCheckDuration,
} PrincetonDecoderStep;
SubGhzEncoderPrinceton* subghz_encoder_princeton_alloc() {
SubGhzEncoderPrinceton* instance = furi_alloc(sizeof(SubGhzEncoderPrinceton));
return instance;
@@ -87,7 +93,7 @@ SubGhzDecoderPrinceton* subghz_decoder_princeton_alloc(void) {
instance->common.te_short = SUBGHZ_PT_SHORT; //150;
instance->common.te_long = SUBGHZ_PT_LONG; //450;
instance->common.te_delta = 250; //50;
instance->common.type_protocol = TYPE_PROTOCOL_STATIC;
instance->common.type_protocol = SubGhzProtocolCommonTypeStatic;
instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_decoder_princeton_to_str;
instance->common.to_save_string =
(SubGhzProtocolCommonGetStrSave)subghz_decoder_princeton_to_save_str;
@@ -142,7 +148,7 @@ bool subghz_protocol_princeton_send_key(
}
void subghz_decoder_princeton_reset(SubGhzDecoderPrinceton* instance) {
instance->common.parser_step = 0;
instance->common.parser_step = PrincetonDecoderStepReset;
}
void subghz_decoder_princeton_parse(
@@ -150,28 +156,28 @@ void subghz_decoder_princeton_parse(
bool level,
uint32_t duration) {
switch(instance->common.parser_step) {
case 0:
case PrincetonDecoderStepReset:
if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 36) <
instance->common.te_delta * 36)) {
//Found Preambula
instance->common.parser_step = 1;
instance->common.parser_step = PrincetonDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = PrincetonDecoderStepReset;
}
break;
case 1:
case PrincetonDecoderStepSaveDuration:
//save duration
if(level) {
instance->common.te_last = duration;
instance->common.parser_step = 2;
instance->common.parser_step = PrincetonDecoderStepCheckDuration;
}
break;
case 2:
case PrincetonDecoderStepCheckDuration:
if(!level) {
if(duration >= (instance->common.te_short * 10 + instance->common.te_delta)) {
instance->common.parser_step = 1;
instance->common.parser_step = PrincetonDecoderStepSaveDuration;
if(instance->common.code_count_bit ==
instance->common.code_min_count_bit_for_found) {
if(instance->common.code_last_found == instance->common.code_found) {
@@ -201,18 +207,18 @@ void subghz_decoder_princeton_parse(
(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;
instance->common.parser_step = PrincetonDecoderStepSaveDuration;
} else if(
(DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
instance->common.te_delta * 3) &&
(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
subghz_protocol_common_add_bit(&instance->common, 1);
instance->common.parser_step = 1;
instance->common.parser_step = PrincetonDecoderStepSaveDuration;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = PrincetonDecoderStepReset;
}
} else {
instance->common.parser_step = 0;
instance->common.parser_step = PrincetonDecoderStepReset;
}
break;
}
@@ -306,9 +312,7 @@ bool subghz_decoder_princeton_to_load_protocol_from_file(
return loaded;
}
void subghz_decoder_princeton_to_load_protocol(
SubGhzDecoderPrinceton* instance,
void* context) {
void subghz_decoder_princeton_to_load_protocol(SubGhzDecoderPrinceton* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;

View File

@@ -8,24 +8,30 @@
#include <m-string.h>
#include <m-array.h>
struct SubGhzProtocolStarLine {
SubGhzProtocolCommon common;
SubGhzKeystore* keystore;
const char* manufacture_name;
};
typedef enum {
StarLineDecoderStepReset = 0,
StarLineDecoderStepCheckPreambula,
StarLineDecoderStepSaveDuration,
StarLineDecoderStepCheckDuration,
} StarLineDecoderStep;
SubGhzProtocolStarLine* subghz_protocol_star_line_alloc(SubGhzKeystore* keystore) {
SubGhzProtocolStarLine* instance = furi_alloc(sizeof(SubGhzProtocolStarLine));
instance->keystore = keystore;
instance->common.name = "Star Line";
instance->common.name = "Star Line";
instance->common.code_min_count_bit_for_found = 64;
instance->common.te_short = 250;
instance->common.te_long = 500;
instance->common.te_delta = 120;
instance->common.type_protocol = TYPE_PROTOCOL_DYNAMIC;
instance->common.type_protocol = SubGhzProtocolCommonTypeDynamic;
instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_star_line_to_str;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoadFromRAW)subghz_decoder_star_line_to_load_protocol;
@@ -38,13 +44,13 @@ void subghz_protocol_star_line_free(SubGhzProtocolStarLine* instance) {
free(instance);
}
const char* subghz_protocol_star_line_find_and_get_manufacture_name (void* context){
const char* subghz_protocol_star_line_find_and_get_manufacture_name(void* context) {
SubGhzProtocolStarLine* instance = context;
subghz_protocol_star_line_check_remote_controller(instance);
return instance->manufacture_name;
}
const char* subghz_protocol_star_line_get_manufacture_name (void* context){
const char* subghz_protocol_star_line_get_manufacture_name(void* context) {
SubGhzProtocolStarLine* instance = context;
return instance->manufacture_name;
}
@@ -55,7 +61,7 @@ const char* subghz_protocol_star_line_get_manufacture_name (void* context){
* @param bit - bit
*/
void subghz_protocol_star_line_send_bit(SubGhzProtocolStarLine* instance, uint8_t bit) {
if (bit) {
if(bit) {
//send bit 1
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_long);
@@ -70,18 +76,22 @@ void subghz_protocol_star_line_send_bit(SubGhzProtocolStarLine* instance, uint8_
}
}
void subghz_protocol_star_line_send_key(SubGhzProtocolStarLine* instance, uint64_t key, uint8_t bit,uint8_t repeat) {
while (repeat--) {
void subghz_protocol_star_line_send_key(
SubGhzProtocolStarLine* instance,
uint64_t key,
uint8_t bit,
uint8_t repeat) {
while(repeat--) {
//Send header
for(uint8_t i = 0; i < 6; i++){
for(uint8_t i = 0; i < 6; i++) {
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_long * 2);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_long * 2);
}
delay_us(instance->common.te_long * 2);
}
//Send Start bit ??????????
//Send key data
for (uint8_t i = bit; i > 0; i--) {
for(uint8_t i = bit; i > 0; i--) {
subghz_protocol_star_line_send_bit(instance, bit_read(key, i - 1));
}
//Send Stop bit ??????????
@@ -89,7 +99,7 @@ void subghz_protocol_star_line_send_key(SubGhzProtocolStarLine* instance, uint64
}
void subghz_protocol_star_line_reset(SubGhzProtocolStarLine* instance) {
instance->common.parser_step = 0;
instance->common.parser_step = StarLineDecoderStepReset;
}
/** Checking the accepted code against the database manafacture key
@@ -99,86 +109,97 @@ void subghz_protocol_star_line_reset(SubGhzProtocolStarLine* instance) {
* @param hop hop encrypted part of the parcel
* @return true on successful search
*/
uint8_t subghz_protocol_star_line_check_remote_controller_selector(SubGhzProtocolStarLine* instance, uint32_t fix , uint32_t hop) {
uint16_t end_serial = (uint16_t)(fix&0xFF);
uint8_t btn = (uint8_t)(fix>>24);
uint8_t subghz_protocol_star_line_check_remote_controller_selector(
SubGhzProtocolStarLine* instance,
uint32_t fix,
uint32_t hop) {
uint16_t end_serial = (uint16_t)(fix & 0xFF);
uint8_t btn = (uint8_t)(fix >> 24);
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>>24 == btn) && ((((uint16_t)(decrypt>>16)) & 0x00FF) == 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 >> 24 == btn) &&
((((uint16_t)(decrypt >> 16)) & 0x00FF) == 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>>24 ==btn)&& ((((uint16_t)(decrypt>>16))&0x00FF)==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 >> 24 == btn) &&
((((uint16_t)(decrypt >> 16)) & 0x00FF) == 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>>24 ==btn) && ((((uint16_t)(decrypt>>16))&0x00FF)==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>>24 ==btn) && ((((uint16_t)(decrypt>>16))&0x00FF)==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>>24 ==btn)&& ((((uint16_t)(decrypt>>16))&0x00FF)==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>>24 ==btn) && ((((uint16_t)(decrypt>>16))&0x00FF)==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 >> 24 == btn) &&
((((uint16_t)(decrypt >> 16)) & 0x00FF) == 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 >> 24 == btn) &&
((((uint16_t)(decrypt >> 16)) & 0x00FF) == 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 >> 24 == btn) &&
((((uint16_t)(decrypt >> 16)) & 0x00FF) == 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 >> 24 == btn) &&
((((uint16_t)(decrypt >> 16)) & 0x00FF) == 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;
}
@@ -188,53 +209,61 @@ uint8_t subghz_protocol_star_line_check_remote_controller_selector(SubGhzProtoco
* @param instance SubGhzProtocolStarLine instance
*/
void subghz_protocol_star_line_check_remote_controller(SubGhzProtocolStarLine* instance) {
uint64_t key = subghz_protocol_common_reverse_key(instance->common.code_last_found, instance->common.code_last_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;
subghz_protocol_star_line_check_remote_controller_selector(instance, key_fix, key_hop);
instance ->common.serial= key_fix&0x00FFFFFF;
instance->common.serial = key_fix & 0x00FFFFFF;
instance->common.btn = key_fix >> 24;
}
void subghz_protocol_star_line_parse(SubGhzProtocolStarLine* instance, bool level, uint32_t duration) {
switch (instance->common.parser_step) {
case 0:
if (level){
if(DURATION_DIFF(duration,instance->common.te_long * 2)< instance->common.te_delta * 2) {
instance->common.parser_step = 1;
void subghz_protocol_star_line_parse(
SubGhzProtocolStarLine* instance,
bool level,
uint32_t duration) {
switch(instance->common.parser_step) {
case StarLineDecoderStepReset:
if(level) {
if(DURATION_DIFF(duration, instance->common.te_long * 2) <
instance->common.te_delta * 2) {
instance->common.parser_step = StarLineDecoderStepCheckPreambula;
instance->common.header_count++;
} else if(instance->common.header_count>4){
} else if(instance->common.header_count > 4) {
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
instance->common.te_last = duration;
instance->common.parser_step = 3;
instance->common.parser_step = StarLineDecoderStepCheckDuration;
}
}else{
instance->common.parser_step = 0;
} else {
instance->common.parser_step = StarLineDecoderStepReset;
instance->common.header_count = 0;
}
break;
case 1:
if ((!level)
&& (DURATION_DIFF(duration,instance->common.te_long * 2)< instance->common.te_delta * 2)) {
case StarLineDecoderStepCheckPreambula:
if((!level) && (DURATION_DIFF(duration, instance->common.te_long * 2) <
instance->common.te_delta * 2)) {
//Found Preambula
instance->common.parser_step = 0;
instance->common.parser_step = StarLineDecoderStepReset;
} else {
instance->common.header_count = 0;
instance->common.parser_step = 0;
instance->common.parser_step = StarLineDecoderStepReset;
}
break;
case 2:
if (level) {
if (duration >= (instance->common.te_long + instance->common.te_delta)) {
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){
case StarLineDecoderStepSaveDuration:
if(level) {
if(duration >= (instance->common.te_long + instance->common.te_delta)) {
instance->common.parser_step = StarLineDecoderStepReset;
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);
if(instance->common.callback)
instance->common.callback(
(SubGhzProtocolCommon*)instance, instance->common.context);
}
}
instance->common.code_found = 0;
@@ -243,28 +272,31 @@ void subghz_protocol_star_line_parse(SubGhzProtocolStarLine* instance, bool leve
break;
} else {
instance->common.te_last = duration;
instance->common.parser_step = 3;
instance->common.parser_step = StarLineDecoderStepCheckDuration;
}
}else{
instance->common.parser_step = 0;
} else {
instance->common.parser_step = StarLineDecoderStepReset;
}
break;
case 3:
if(!level){
if ((DURATION_DIFF(instance->common.te_last,instance->common.te_short)< instance->common.te_delta)
&& (DURATION_DIFF(duration,instance->common.te_short)< instance->common.te_delta)) {
case StarLineDecoderStepCheckDuration:
if(!level) {
if((DURATION_DIFF(instance->common.te_last, instance->common.te_short) <
instance->common.te_delta) &&
(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
subghz_protocol_common_add_bit(&instance->common, 0);
instance->common.parser_step = 2;
} else if ((DURATION_DIFF(instance->common.te_last,instance->common.te_long )< instance->common.te_delta)
&& (DURATION_DIFF(duration,instance->common.te_long)< instance->common.te_delta)) {
instance->common.parser_step = StarLineDecoderStepSaveDuration;
} else if(
(DURATION_DIFF(instance->common.te_last, instance->common.te_long) <
instance->common.te_delta) &&
(DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta)) {
subghz_protocol_common_add_bit(&instance->common, 1);
instance->common.parser_step = 2;
instance->common.parser_step = StarLineDecoderStepSaveDuration;
} else {
instance->common.parser_step = 0;
instance->common.parser_step = StarLineDecoderStepReset;
}
} else {
instance->common.parser_step = 0;
instance->common.parser_step = StarLineDecoderStepReset;
}
break;
}
@@ -275,10 +307,11 @@ void subghz_protocol_star_line_to_str(SubGhzProtocolStarLine* instance, string_t
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);
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,
"%s %dbit\r\n"
@@ -296,13 +329,10 @@ void subghz_protocol_star_line_to_str(SubGhzProtocolStarLine* instance, string_t
code_found_reverse_lo,
instance->common.btn,
instance->manufacture_name,
instance->common.serial
);
instance->common.serial);
}
void subghz_decoder_star_line_to_load_protocol(
SubGhzProtocolStarLine* instance,
void* context) {
void subghz_decoder_star_line_to_load_protocol(SubGhzProtocolStarLine* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;