[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:
@@ -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);
|
||||
}
|
@@ -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);
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user