Git: set git attributes to automatically manage line endings. (#771)

* Git: set git attributes to automatically manage line endings.

* Git: cleanup gitignore file
This commit is contained in:
あく
2021-10-18 01:54:19 +03:00
committed by GitHub
parent f390060922
commit bde3a47078
179 changed files with 42218 additions and 42254 deletions

View File

@@ -1,228 +1,228 @@
#include "subghz_protocol_came.h"
#include "subghz_protocol_common.h"
/*
* Help
* https://phreakerclub.com/447
*
*/
struct SubGhzProtocolCame {
SubGhzProtocolCommon common;
};
typedef enum {
CameDecoderStepReset = 0,
CameDecoderStepFoundStartBit,
CameDecoderStepSaveDuration,
CameDecoderStepCheckDuration,
} CameDecoderStep;
SubGhzProtocolCame* subghz_protocol_came_alloc() {
SubGhzProtocolCame* instance = furi_alloc(sizeof(SubGhzProtocolCame));
instance->common.name = "CAME";
instance->common.code_min_count_bit_for_found = 12;
instance->common.te_short = 320;
instance->common.te_long = 640;
instance->common.te_delta = 150;
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 =
(SubGhzProtocolCommonLoadFromFile)subghz_protocol_came_to_load_protocol_from_file;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoadFromRAW)subghz_decoder_came_to_load_protocol;
instance->common.get_upload_protocol =
(SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_came_send_key;
return instance;
}
void subghz_protocol_came_free(SubGhzProtocolCame* instance) {
furi_assert(instance);
free(instance);
}
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;
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);
//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)) {
//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 {
//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);
}
}
return true;
}
void subghz_protocol_came_reset(SubGhzProtocolCame* instance) {
instance->common.parser_step = CameDecoderStepReset;
}
void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32_t duration) {
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 = CameDecoderStepFoundStartBit;
} else {
instance->common.parser_step = CameDecoderStepReset;
}
break;
case CameDecoderStepFoundStartBit:
if(!level) {
break;
} else if(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) {
//Found start bit CAME
instance->common.parser_step = CameDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = CameDecoderStepReset;
}
break;
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);
}
break;
}
instance->common.te_last = duration;
instance->common.parser_step = CameDecoderStepCheckDuration;
} else {
instance->common.parser_step = CameDecoderStepReset;
}
break;
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 = 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 = CameDecoderStepSaveDuration;
} else
instance->common.parser_step = CameDecoderStepReset;
} else {
instance->common.parser_step = CameDecoderStepReset;
}
break;
}
}
void subghz_protocol_came_to_str(SubGhzProtocolCame* instance, string_t output) {
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(
instance->common.code_last_found, instance->common.code_last_count_bit);
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
string_cat_printf(
output,
"%s %dbit\r\n"
"Key:0x%08lX\r\n"
"Yek:0x%08lX\r\n",
instance->common.name,
instance->common.code_last_count_bit,
code_found_lo,
code_found_reverse_lo);
}
void subghz_protocol_came_to_save_str(SubGhzProtocolCame* instance, string_t output) {
string_printf(
output,
"Protocol: %s\n"
"Bit: %d\n"
"Key: %08lX\n",
instance->common.name,
instance->common.code_last_count_bit,
(uint32_t)(instance->common.code_last_found & 0x00000000ffffffff));
}
bool subghz_protocol_came_to_load_protocol_from_file(
FileWorker* file_worker,
SubGhzProtocolCame* instance) {
bool loaded = false;
string_t temp_str;
string_init(temp_str);
int res = 0;
int data = 0;
do {
// Read and parse bit data from 2nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
if(res != 1) {
break;
}
instance->common.code_last_count_bit = (uint8_t)data;
// Read and parse key data from 3nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
uint32_t temp_key = 0;
res = sscanf(string_get_cstr(temp_str), "Key: %08lX\n", &temp_key);
if(res != 1) {
break;
}
instance->common.code_last_found = (uint64_t)temp_key;
loaded = true;
} while(0);
string_clear(temp_str);
return loaded;
}
void subghz_decoder_came_to_load_protocol(SubGhzProtocolCame* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;
instance->common.code_last_found = data->code_found;
instance->common.code_last_count_bit = data->code_count_bit;
}
#include "subghz_protocol_came.h"
#include "subghz_protocol_common.h"
/*
* Help
* https://phreakerclub.com/447
*
*/
struct SubGhzProtocolCame {
SubGhzProtocolCommon common;
};
typedef enum {
CameDecoderStepReset = 0,
CameDecoderStepFoundStartBit,
CameDecoderStepSaveDuration,
CameDecoderStepCheckDuration,
} CameDecoderStep;
SubGhzProtocolCame* subghz_protocol_came_alloc() {
SubGhzProtocolCame* instance = furi_alloc(sizeof(SubGhzProtocolCame));
instance->common.name = "CAME";
instance->common.code_min_count_bit_for_found = 12;
instance->common.te_short = 320;
instance->common.te_long = 640;
instance->common.te_delta = 150;
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 =
(SubGhzProtocolCommonLoadFromFile)subghz_protocol_came_to_load_protocol_from_file;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoadFromRAW)subghz_decoder_came_to_load_protocol;
instance->common.get_upload_protocol =
(SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_came_send_key;
return instance;
}
void subghz_protocol_came_free(SubGhzProtocolCame* instance) {
furi_assert(instance);
free(instance);
}
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;
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);
//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)) {
//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 {
//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);
}
}
return true;
}
void subghz_protocol_came_reset(SubGhzProtocolCame* instance) {
instance->common.parser_step = CameDecoderStepReset;
}
void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32_t duration) {
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 = CameDecoderStepFoundStartBit;
} else {
instance->common.parser_step = CameDecoderStepReset;
}
break;
case CameDecoderStepFoundStartBit:
if(!level) {
break;
} else if(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) {
//Found start bit CAME
instance->common.parser_step = CameDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = CameDecoderStepReset;
}
break;
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);
}
break;
}
instance->common.te_last = duration;
instance->common.parser_step = CameDecoderStepCheckDuration;
} else {
instance->common.parser_step = CameDecoderStepReset;
}
break;
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 = 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 = CameDecoderStepSaveDuration;
} else
instance->common.parser_step = CameDecoderStepReset;
} else {
instance->common.parser_step = CameDecoderStepReset;
}
break;
}
}
void subghz_protocol_came_to_str(SubGhzProtocolCame* instance, string_t output) {
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(
instance->common.code_last_found, instance->common.code_last_count_bit);
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
string_cat_printf(
output,
"%s %dbit\r\n"
"Key:0x%08lX\r\n"
"Yek:0x%08lX\r\n",
instance->common.name,
instance->common.code_last_count_bit,
code_found_lo,
code_found_reverse_lo);
}
void subghz_protocol_came_to_save_str(SubGhzProtocolCame* instance, string_t output) {
string_printf(
output,
"Protocol: %s\n"
"Bit: %d\n"
"Key: %08lX\n",
instance->common.name,
instance->common.code_last_count_bit,
(uint32_t)(instance->common.code_last_found & 0x00000000ffffffff));
}
bool subghz_protocol_came_to_load_protocol_from_file(
FileWorker* file_worker,
SubGhzProtocolCame* instance) {
bool loaded = false;
string_t temp_str;
string_init(temp_str);
int res = 0;
int data = 0;
do {
// Read and parse bit data from 2nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
if(res != 1) {
break;
}
instance->common.code_last_count_bit = (uint8_t)data;
// Read and parse key data from 3nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
uint32_t temp_key = 0;
res = sscanf(string_get_cstr(temp_str), "Key: %08lX\n", &temp_key);
if(res != 1) {
break;
}
instance->common.code_last_found = (uint64_t)temp_key;
loaded = true;
} while(0);
string_clear(temp_str);
return loaded;
}
void subghz_decoder_came_to_load_protocol(SubGhzProtocolCame* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;
instance->common.code_last_found = data->code_found;
instance->common.code_last_count_bit = data->code_count_bit;
}

View File

@@ -1,70 +1,70 @@
#pragma once
#include "subghz_protocol_common.h"
typedef struct SubGhzProtocolCame SubGhzProtocolCame;
/** Allocate SubGhzProtocolCame
*
* @return SubGhzProtocolCame*
*/
SubGhzProtocolCame* subghz_protocol_came_alloc();
/** Free SubGhzProtocolCame
*
* @param instance
*/
void subghz_protocol_came_free(SubGhzProtocolCame* instance);
/** Get upload protocol
*
* @param instance - SubGhzProtocolCame instance
* @param encoder - SubGhzProtocolCommonEncoder encoder
* @return bool
*/
bool subghz_protocol_came_send_key(
SubGhzProtocolCame* instance,
SubGhzProtocolCommonEncoder* encoder);
/** Reset internal state
* @param instance - SubGhzProtocolCame instance
*/
void subghz_protocol_came_reset(SubGhzProtocolCame* instance);
/** Parse accepted duration
*
* @param instance - SubGhzProtocolCame instance
* @param data - LevelDuration level_duration
*/
void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzProtocolCame* instance
* @param output - output string
*/
void subghz_protocol_came_to_str(SubGhzProtocolCame* instance, string_t output);
/** Get a string to save the protocol
*
* @param instance - SubGhzProtocolCame instance
* @param output - the resulting string
*/
void subghz_protocol_came_to_save_str(SubGhzProtocolCame* instance, string_t output);
/** Loading protocol from file
*
* @param file_worker - FileWorker file_worker
* @param instance - SubGhzProtocolCame instance
* @return bool
*/
bool subghz_protocol_came_to_load_protocol_from_file(
FileWorker* file_worker,
SubGhzProtocolCame* instance);
/** Loading protocol from bin data
*
* @param instance - SubGhzProtocolCame instance
* @param context - SubGhzProtocolCommonLoad context
*/
#pragma once
#include "subghz_protocol_common.h"
typedef struct SubGhzProtocolCame SubGhzProtocolCame;
/** Allocate SubGhzProtocolCame
*
* @return SubGhzProtocolCame*
*/
SubGhzProtocolCame* subghz_protocol_came_alloc();
/** Free SubGhzProtocolCame
*
* @param instance
*/
void subghz_protocol_came_free(SubGhzProtocolCame* instance);
/** Get upload protocol
*
* @param instance - SubGhzProtocolCame instance
* @param encoder - SubGhzProtocolCommonEncoder encoder
* @return bool
*/
bool subghz_protocol_came_send_key(
SubGhzProtocolCame* instance,
SubGhzProtocolCommonEncoder* encoder);
/** Reset internal state
* @param instance - SubGhzProtocolCame instance
*/
void subghz_protocol_came_reset(SubGhzProtocolCame* instance);
/** Parse accepted duration
*
* @param instance - SubGhzProtocolCame instance
* @param data - LevelDuration level_duration
*/
void subghz_protocol_came_parse(SubGhzProtocolCame* instance, bool level, uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzProtocolCame* instance
* @param output - output string
*/
void subghz_protocol_came_to_str(SubGhzProtocolCame* instance, string_t output);
/** Get a string to save the protocol
*
* @param instance - SubGhzProtocolCame instance
* @param output - the resulting string
*/
void subghz_protocol_came_to_save_str(SubGhzProtocolCame* instance, string_t output);
/** Loading protocol from file
*
* @param file_worker - FileWorker file_worker
* @param instance - SubGhzProtocolCame instance
* @return bool
*/
bool subghz_protocol_came_to_load_protocol_from_file(
FileWorker* file_worker,
SubGhzProtocolCame* instance);
/** Loading protocol from bin data
*
* @param instance - SubGhzProtocolCame instance
* @param context - SubGhzProtocolCommonLoad context
*/
void subghz_decoder_came_to_load_protocol(SubGhzProtocolCame* instance, void* context);

View File

@@ -1,4 +1,4 @@
/*
* https://phreakerclub.com/616
*/
/*
* https://phreakerclub.com/616
*/

View File

@@ -1,139 +1,139 @@
#include "subghz_protocol_common.h"
#include <stdio.h>
#include <lib/toolbox/hex.h>
SubGhzProtocolCommonEncoder* subghz_protocol_encoder_common_alloc() {
SubGhzProtocolCommonEncoder* instance = furi_alloc(sizeof(SubGhzProtocolCommonEncoder));
instance->upload = furi_alloc(SUBGHZ_ENCODER_UPLOAD_MAX_SIZE * sizeof(LevelDuration));
instance->start = true;
instance->repeat = 10; //default number of repeat
return instance;
}
void subghz_protocol_encoder_common_free(SubGhzProtocolCommonEncoder* instance) {
furi_assert(instance);
free(instance->upload);
free(instance);
}
size_t subghz_encoder_common_get_repeat_left(SubGhzProtocolCommonEncoder* instance) {
furi_assert(instance);
return instance->repeat;
}
LevelDuration subghz_protocol_encoder_common_yield(void* context) {
SubGhzProtocolCommonEncoder* instance = context;
if(instance->repeat == 0){
return level_duration_reset();
}
LevelDuration ret = instance->upload[instance->front];
if(++instance->front == instance->size_upload) {
instance->repeat--;
instance->front = 0;
}
return ret;
}
void subghz_protocol_common_add_bit(SubGhzProtocolCommon *common, uint8_t bit){
common->code_found = common->code_found << 1 | bit;
common->code_count_bit++;
}
bool subghz_protocol_common_check_interval(SubGhzProtocolCommon *common, uint32_t duration, uint16_t duration_check) {
if ((duration_check >= (duration - common->te_delta))&&(duration_check <= (duration + common->te_delta))){
return true;
} else {
return false;
}
}
uint64_t subghz_protocol_common_reverse_key(uint64_t key, uint8_t count_bit){
uint64_t key_reverse=0;
for(uint8_t i=0; i<count_bit; i++) {
key_reverse=key_reverse<<1|bit_read(key,i);
}
return key_reverse;
}
void subghz_protocol_common_set_callback(SubGhzProtocolCommon* common, SubGhzProtocolCommonCallback callback, void* context) {
common->callback = callback;
common->context = context;
}
void subghz_protocol_common_to_str(SubGhzProtocolCommon* instance, string_t output) {
if (instance->to_string) {
instance->to_string(instance, output);
} else {
uint32_t code_found_hi = instance->code_found >> 32;
uint32_t code_found_lo = instance->code_found & 0x00000000ffffffff;
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->code_found, instance->code_count_bit);
uint32_t code_found_reverse_hi = code_found_reverse>>32;
uint32_t code_found_reverse_lo = code_found_reverse&0x00000000ffffffff;
if (code_found_hi>0) {
string_cat_printf(
output,
"Protocol %s, %d Bit\r\n"
" KEY:0x%lX%08lX\r\n"
" YEK:0x%lX%08lX\r\n"
" SN:0x%05lX BTN:%02X\r\n",
instance->name,
instance->code_count_bit,
code_found_hi,
code_found_lo,
code_found_reverse_hi,
code_found_reverse_lo,
instance->serial,
instance->btn
);
} else {
string_cat_printf(
output,
"Protocol %s, %d Bit\r\n"
" KEY:0x%lX%lX\r\n"
" YEK:0x%lX%lX\r\n"
" SN:0x%05lX BTN:%02X\r\n",
instance->name,
instance->code_count_bit,
code_found_hi,
code_found_lo,
code_found_reverse_hi,
code_found_reverse_lo,
instance->serial,
instance->btn
);
}
}
}
bool subghz_protocol_common_read_hex(string_t str, uint8_t* buff, uint16_t len) {
string_strim(str);
uint8_t nibble_high = 0;
uint8_t nibble_low = 0;
bool parsed = true;
for(uint16_t i = 0; i < len; i++) {
if(hex_char_to_hex_nibble(string_get_char(str, 0), &nibble_high) &&
hex_char_to_hex_nibble(string_get_char(str, 1), &nibble_low)) {
buff[i] = (nibble_high << 4) | nibble_low;
if(string_size(str)>2){
string_right(str, 2);
}else if(i<len-1){
parsed = false;
break;
};
} else {
parsed = false;
break;
}
}
return parsed;
}
#include "subghz_protocol_common.h"
#include <stdio.h>
#include <lib/toolbox/hex.h>
SubGhzProtocolCommonEncoder* subghz_protocol_encoder_common_alloc() {
SubGhzProtocolCommonEncoder* instance = furi_alloc(sizeof(SubGhzProtocolCommonEncoder));
instance->upload = furi_alloc(SUBGHZ_ENCODER_UPLOAD_MAX_SIZE * sizeof(LevelDuration));
instance->start = true;
instance->repeat = 10; //default number of repeat
return instance;
}
void subghz_protocol_encoder_common_free(SubGhzProtocolCommonEncoder* instance) {
furi_assert(instance);
free(instance->upload);
free(instance);
}
size_t subghz_encoder_common_get_repeat_left(SubGhzProtocolCommonEncoder* instance) {
furi_assert(instance);
return instance->repeat;
}
LevelDuration subghz_protocol_encoder_common_yield(void* context) {
SubGhzProtocolCommonEncoder* instance = context;
if(instance->repeat == 0){
return level_duration_reset();
}
LevelDuration ret = instance->upload[instance->front];
if(++instance->front == instance->size_upload) {
instance->repeat--;
instance->front = 0;
}
return ret;
}
void subghz_protocol_common_add_bit(SubGhzProtocolCommon *common, uint8_t bit){
common->code_found = common->code_found << 1 | bit;
common->code_count_bit++;
}
bool subghz_protocol_common_check_interval(SubGhzProtocolCommon *common, uint32_t duration, uint16_t duration_check) {
if ((duration_check >= (duration - common->te_delta))&&(duration_check <= (duration + common->te_delta))){
return true;
} else {
return false;
}
}
uint64_t subghz_protocol_common_reverse_key(uint64_t key, uint8_t count_bit){
uint64_t key_reverse=0;
for(uint8_t i=0; i<count_bit; i++) {
key_reverse=key_reverse<<1|bit_read(key,i);
}
return key_reverse;
}
void subghz_protocol_common_set_callback(SubGhzProtocolCommon* common, SubGhzProtocolCommonCallback callback, void* context) {
common->callback = callback;
common->context = context;
}
void subghz_protocol_common_to_str(SubGhzProtocolCommon* instance, string_t output) {
if (instance->to_string) {
instance->to_string(instance, output);
} else {
uint32_t code_found_hi = instance->code_found >> 32;
uint32_t code_found_lo = instance->code_found & 0x00000000ffffffff;
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->code_found, instance->code_count_bit);
uint32_t code_found_reverse_hi = code_found_reverse>>32;
uint32_t code_found_reverse_lo = code_found_reverse&0x00000000ffffffff;
if (code_found_hi>0) {
string_cat_printf(
output,
"Protocol %s, %d Bit\r\n"
" KEY:0x%lX%08lX\r\n"
" YEK:0x%lX%08lX\r\n"
" SN:0x%05lX BTN:%02X\r\n",
instance->name,
instance->code_count_bit,
code_found_hi,
code_found_lo,
code_found_reverse_hi,
code_found_reverse_lo,
instance->serial,
instance->btn
);
} else {
string_cat_printf(
output,
"Protocol %s, %d Bit\r\n"
" KEY:0x%lX%lX\r\n"
" YEK:0x%lX%lX\r\n"
" SN:0x%05lX BTN:%02X\r\n",
instance->name,
instance->code_count_bit,
code_found_hi,
code_found_lo,
code_found_reverse_hi,
code_found_reverse_lo,
instance->serial,
instance->btn
);
}
}
}
bool subghz_protocol_common_read_hex(string_t str, uint8_t* buff, uint16_t len) {
string_strim(str);
uint8_t nibble_high = 0;
uint8_t nibble_low = 0;
bool parsed = true;
for(uint16_t i = 0; i < len; i++) {
if(hex_char_to_hex_nibble(string_get_char(str, 0), &nibble_high) &&
hex_char_to_hex_nibble(string_get_char(str, 1), &nibble_low)) {
buff[i] = (nibble_high << 4) | nibble_low;
if(string_size(str)>2){
string_right(str, 2);
}else if(i<len-1){
parsed = false;
break;
};
} else {
parsed = false;
break;
}
}
return parsed;
}

View File

@@ -1,177 +1,177 @@
#pragma once
#include <m-string.h>
#include <furi-hal.h>
#include <stdint.h>
#include "file-worker.h"
#define bit_read(value, bit) (((value) >> (bit)) & 0x01)
#define bit_set(value, bit) ((value) |= (1UL << (bit)))
#define bit_clear(value, bit) ((value) &= ~(1UL << (bit)))
#define bit_write(value, bit, bitvalue) (bitvalue ? bit_set(value, bit) : bit_clear(value, bit))
#define SUBGHZ_TX_PIN_HIGH()
#define SUBGHZ_TX_PIN_LOW()
#define DURATION_DIFF(x, y) ((x < y) ? (y - x) : (x - y))
#define SUBGHZ_APP_FOLDER "/any/subghz"
#define SUBGHZ_APP_PATH_FOLDER "/any/subghz/saved"
#define SUBGHZ_APP_EXTENSION ".sub"
#define SUBGHZ_ENCODER_UPLOAD_MAX_SIZE 2048
typedef enum {
SubGhzProtocolCommonTypeUnknown,
SubGhzProtocolCommonTypeStatic,
SubGhzProtocolCommonTypeDynamic,
} SubGhzProtocolCommonType;
typedef struct SubGhzProtocolCommon SubGhzProtocolCommon;
typedef struct SubGhzProtocolCommonEncoder SubGhzProtocolCommonEncoder;
typedef struct SubGhzProtocolCommonLoad SubGhzProtocolCommonLoad;
typedef void (*SubGhzProtocolCommonCallback)(SubGhzProtocolCommon* parser, void* context);
typedef void (*SubGhzProtocolCommonToStr)(SubGhzProtocolCommon* instance, string_t output);
//Get string to save
typedef void (*SubGhzProtocolCommonGetStrSave)(SubGhzProtocolCommon* instance, string_t output);
//Load protocol from file
typedef bool (
*SubGhzProtocolCommonLoadFromFile)(FileWorker* file_worker, SubGhzProtocolCommon* instance);
//Load protocol
typedef void (*SubGhzProtocolCommonLoadFromRAW)(SubGhzProtocolCommon* instance, void* context);
//Get upload encoder protocol
typedef bool (*SubGhzProtocolCommonEncoderGetUpLoad)(
SubGhzProtocolCommon* instance,
SubGhzProtocolCommonEncoder* encoder);
struct SubGhzProtocolCommon {
const char* name;
uint16_t te_long;
uint16_t te_short;
uint16_t te_delta;
uint8_t code_count_bit;
uint8_t code_last_count_bit;
uint64_t code_found;
uint64_t code_last_found;
uint8_t code_min_count_bit_for_found;
uint8_t btn;
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;
void* context;
/* Dump To String */
SubGhzProtocolCommonToStr to_string;
/* Get string to save */
SubGhzProtocolCommonGetStrSave to_save_string;
/* Load protocol from file */
SubGhzProtocolCommonLoadFromFile to_load_protocol_from_file;
/* Load protocol from RAW data */
SubGhzProtocolCommonLoadFromRAW to_load_protocol;
/* Get upload encoder protocol */
SubGhzProtocolCommonEncoderGetUpLoad get_upload_protocol;
};
struct SubGhzProtocolCommonEncoder {
bool start;
size_t repeat;
size_t front;
size_t size_upload;
LevelDuration* upload;
};
struct SubGhzProtocolCommonLoad {
uint64_t code_found;
uint8_t code_count_bit;
uint32_t param1;
uint32_t param2;
uint32_t param3;
};
/** Allocate SubGhzProtocolCommonEncoder
*
* @return SubGhzProtocolCommonEncoder*
*/
SubGhzProtocolCommonEncoder* subghz_protocol_encoder_common_alloc();
/** Free SubGhzProtocolCommonEncoder
*
* @param instance
*/
void subghz_protocol_encoder_common_free(SubGhzProtocolCommonEncoder* instance);
/** Get count repeat left
*
* @param instance - SubGhzProtocolCommonEncoder instance
* @return count repeat left
*/
size_t subghz_encoder_common_get_repeat_left(SubGhzProtocolCommonEncoder* instance);
/** Get LevelDuration this encoder step
*
* @param context - SubGhzProtocolCommonEncoder context
* @return LevelDuration this step
*/
LevelDuration subghz_protocol_encoder_common_yield(void* context);
/** Add data bit to code_found
*
* @param common - SubGhzProtocolCommon common
* @param bit - add bit
*/
void subghz_protocol_common_add_bit(SubGhzProtocolCommon* common, uint8_t bit);
/** Checking that the duration is included in the interval
*
* @param common - SubGhzProtocolCommon common
* @param duration duration reference
* @param duration_check duration checked
* @return true on success
*/
bool subghz_protocol_common_check_interval(
SubGhzProtocolCommon* common,
uint32_t duration,
uint16_t duration_check);
/** Bit-by-bit data mirroring
*
* @param key - data to mirror
* @param count_bit number of data bits
* @return mirrored data
*/
uint64_t subghz_protocol_common_reverse_key(uint64_t key, uint8_t count_bit);
/** Callback protocol
*
* @param instance - SubGhzProtocolCommon* instance
* @param callback
* @param context
*/
void subghz_protocol_common_set_callback(
SubGhzProtocolCommon* instance,
SubGhzProtocolCommonCallback callback,
void* context);
/** outputting information from the parser
*
* @param instance - SubGhzProtocolCommon* instance
* @param output - output string
*/
void subghz_protocol_common_to_str(SubGhzProtocolCommon* instance, string_t output);
/** Converting a string to a HEX array
*
* @param str - string data
* @param buff - uint8_t* buff
* @param len - size buff
* @return bool
*/
bool subghz_protocol_common_read_hex(string_t str, uint8_t* buff, uint16_t len);
#pragma once
#include <m-string.h>
#include <furi-hal.h>
#include <stdint.h>
#include "file-worker.h"
#define bit_read(value, bit) (((value) >> (bit)) & 0x01)
#define bit_set(value, bit) ((value) |= (1UL << (bit)))
#define bit_clear(value, bit) ((value) &= ~(1UL << (bit)))
#define bit_write(value, bit, bitvalue) (bitvalue ? bit_set(value, bit) : bit_clear(value, bit))
#define SUBGHZ_TX_PIN_HIGH()
#define SUBGHZ_TX_PIN_LOW()
#define DURATION_DIFF(x, y) ((x < y) ? (y - x) : (x - y))
#define SUBGHZ_APP_FOLDER "/any/subghz"
#define SUBGHZ_APP_PATH_FOLDER "/any/subghz/saved"
#define SUBGHZ_APP_EXTENSION ".sub"
#define SUBGHZ_ENCODER_UPLOAD_MAX_SIZE 2048
typedef enum {
SubGhzProtocolCommonTypeUnknown,
SubGhzProtocolCommonTypeStatic,
SubGhzProtocolCommonTypeDynamic,
} SubGhzProtocolCommonType;
typedef struct SubGhzProtocolCommon SubGhzProtocolCommon;
typedef struct SubGhzProtocolCommonEncoder SubGhzProtocolCommonEncoder;
typedef struct SubGhzProtocolCommonLoad SubGhzProtocolCommonLoad;
typedef void (*SubGhzProtocolCommonCallback)(SubGhzProtocolCommon* parser, void* context);
typedef void (*SubGhzProtocolCommonToStr)(SubGhzProtocolCommon* instance, string_t output);
//Get string to save
typedef void (*SubGhzProtocolCommonGetStrSave)(SubGhzProtocolCommon* instance, string_t output);
//Load protocol from file
typedef bool (
*SubGhzProtocolCommonLoadFromFile)(FileWorker* file_worker, SubGhzProtocolCommon* instance);
//Load protocol
typedef void (*SubGhzProtocolCommonLoadFromRAW)(SubGhzProtocolCommon* instance, void* context);
//Get upload encoder protocol
typedef bool (*SubGhzProtocolCommonEncoderGetUpLoad)(
SubGhzProtocolCommon* instance,
SubGhzProtocolCommonEncoder* encoder);
struct SubGhzProtocolCommon {
const char* name;
uint16_t te_long;
uint16_t te_short;
uint16_t te_delta;
uint8_t code_count_bit;
uint8_t code_last_count_bit;
uint64_t code_found;
uint64_t code_last_found;
uint8_t code_min_count_bit_for_found;
uint8_t btn;
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;
void* context;
/* Dump To String */
SubGhzProtocolCommonToStr to_string;
/* Get string to save */
SubGhzProtocolCommonGetStrSave to_save_string;
/* Load protocol from file */
SubGhzProtocolCommonLoadFromFile to_load_protocol_from_file;
/* Load protocol from RAW data */
SubGhzProtocolCommonLoadFromRAW to_load_protocol;
/* Get upload encoder protocol */
SubGhzProtocolCommonEncoderGetUpLoad get_upload_protocol;
};
struct SubGhzProtocolCommonEncoder {
bool start;
size_t repeat;
size_t front;
size_t size_upload;
LevelDuration* upload;
};
struct SubGhzProtocolCommonLoad {
uint64_t code_found;
uint8_t code_count_bit;
uint32_t param1;
uint32_t param2;
uint32_t param3;
};
/** Allocate SubGhzProtocolCommonEncoder
*
* @return SubGhzProtocolCommonEncoder*
*/
SubGhzProtocolCommonEncoder* subghz_protocol_encoder_common_alloc();
/** Free SubGhzProtocolCommonEncoder
*
* @param instance
*/
void subghz_protocol_encoder_common_free(SubGhzProtocolCommonEncoder* instance);
/** Get count repeat left
*
* @param instance - SubGhzProtocolCommonEncoder instance
* @return count repeat left
*/
size_t subghz_encoder_common_get_repeat_left(SubGhzProtocolCommonEncoder* instance);
/** Get LevelDuration this encoder step
*
* @param context - SubGhzProtocolCommonEncoder context
* @return LevelDuration this step
*/
LevelDuration subghz_protocol_encoder_common_yield(void* context);
/** Add data bit to code_found
*
* @param common - SubGhzProtocolCommon common
* @param bit - add bit
*/
void subghz_protocol_common_add_bit(SubGhzProtocolCommon* common, uint8_t bit);
/** Checking that the duration is included in the interval
*
* @param common - SubGhzProtocolCommon common
* @param duration duration reference
* @param duration_check duration checked
* @return true on success
*/
bool subghz_protocol_common_check_interval(
SubGhzProtocolCommon* common,
uint32_t duration,
uint16_t duration_check);
/** Bit-by-bit data mirroring
*
* @param key - data to mirror
* @param count_bit number of data bits
* @return mirrored data
*/
uint64_t subghz_protocol_common_reverse_key(uint64_t key, uint8_t count_bit);
/** Callback protocol
*
* @param instance - SubGhzProtocolCommon* instance
* @param callback
* @param context
*/
void subghz_protocol_common_set_callback(
SubGhzProtocolCommon* instance,
SubGhzProtocolCommonCallback callback,
void* context);
/** outputting information from the parser
*
* @param instance - SubGhzProtocolCommon* instance
* @param output - output string
*/
void subghz_protocol_common_to_str(SubGhzProtocolCommon* instance, string_t output);
/** Converting a string to a HEX array
*
* @param str - string data
* @param buff - uint8_t* buff
* @param len - size buff
* @return bool
*/
bool subghz_protocol_common_read_hex(string_t str, uint8_t* buff, uint16_t len);

View File

@@ -1,191 +1,191 @@
#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.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 = 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;
return instance;
}
void subghz_protocol_faac_slh_free(SubGhzProtocolFaacSLH* instance) {
furi_assert(instance);
free(instance);
}
/** Send bit
*
* @param instance - SubGhzProtocolFaacSLH instance
* @param bit - bit
*/
void subghz_protocol_faac_slh_send_bit(SubGhzProtocolFaacSLH* instance, uint8_t bit) {
if(bit) {
//send bit 1
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_long);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_short);
} else {
//send bit 0
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_short);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_long);
}
}
void subghz_protocol_faac_slh_send_key(
SubGhzProtocolFaacSLH* instance,
uint64_t key,
uint8_t bit,
uint8_t repeat) {
while(repeat--) {
SUBGHZ_TX_PIN_HIGH();
//Send header
delay_us(instance->common.te_long * 2);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_long * 2);
//Send key data
for(uint8_t i = bit; i > 0; i--) {
subghz_protocol_faac_slh_send_bit(instance, bit_read(key, i - 1));
}
}
}
void subghz_protocol_faac_slh_reset(SubGhzProtocolFaacSLH* instance) {
instance->common.parser_step = FaacSLHDecoderStepReset;
}
/** Analysis of received data
*
* @param instance SubGhzProtocolFaacSLH instance
*/
void subghz_protocol_faac_slh_check_remote_controller(SubGhzProtocolFaacSLH* instance) {
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(
instance->common.code_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;
instance->common.serial = code_fix & 0xFFFFFFF;
instance->common.btn = (code_fix >> 28) & 0x0F;
}
void subghz_protocol_faac_slh_parse(SubGhzProtocolFaacSLH* instance, bool level, uint32_t duration) {
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 = FaacSLHDecoderStepReset;
}
break;
case FaacSLHDecoderStepFoundPreambula:
if((!level) && (DURATION_DIFF(duration, instance->common.te_long * 2) <
instance->common.te_delta * 3)) {
//Found Preambula
instance->common.parser_step = FaacSLHDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = FaacSLHDecoderStepReset;
}
break;
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);
}
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
break;
} else {
instance->common.te_last = duration;
instance->common.parser_step = FaacSLHDecoderStepCheckDuration;
}
} else {
instance->common.parser_step = FaacSLHDecoderStepReset;
}
break;
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 = 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 = FaacSLHDecoderStepSaveDuration;
} else {
instance->common.parser_step = FaacSLHDecoderStepReset;
}
} else {
instance->common.parser_step = FaacSLHDecoderStepReset;
}
break;
}
}
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);
uint32_t code_fix = code_found_reverse & 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);
}
void subghz_decoder_faac_slh_to_load_protocol(SubGhzProtocolFaacSLH* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;
instance->common.code_last_found = data->code_found;
instance->common.code_last_count_bit = data->code_count_bit;
subghz_protocol_faac_slh_check_remote_controller(instance);
#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.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 = 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;
return instance;
}
void subghz_protocol_faac_slh_free(SubGhzProtocolFaacSLH* instance) {
furi_assert(instance);
free(instance);
}
/** Send bit
*
* @param instance - SubGhzProtocolFaacSLH instance
* @param bit - bit
*/
void subghz_protocol_faac_slh_send_bit(SubGhzProtocolFaacSLH* instance, uint8_t bit) {
if(bit) {
//send bit 1
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_long);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_short);
} else {
//send bit 0
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_short);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_long);
}
}
void subghz_protocol_faac_slh_send_key(
SubGhzProtocolFaacSLH* instance,
uint64_t key,
uint8_t bit,
uint8_t repeat) {
while(repeat--) {
SUBGHZ_TX_PIN_HIGH();
//Send header
delay_us(instance->common.te_long * 2);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_long * 2);
//Send key data
for(uint8_t i = bit; i > 0; i--) {
subghz_protocol_faac_slh_send_bit(instance, bit_read(key, i - 1));
}
}
}
void subghz_protocol_faac_slh_reset(SubGhzProtocolFaacSLH* instance) {
instance->common.parser_step = FaacSLHDecoderStepReset;
}
/** Analysis of received data
*
* @param instance SubGhzProtocolFaacSLH instance
*/
void subghz_protocol_faac_slh_check_remote_controller(SubGhzProtocolFaacSLH* instance) {
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(
instance->common.code_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;
instance->common.serial = code_fix & 0xFFFFFFF;
instance->common.btn = (code_fix >> 28) & 0x0F;
}
void subghz_protocol_faac_slh_parse(SubGhzProtocolFaacSLH* instance, bool level, uint32_t duration) {
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 = FaacSLHDecoderStepReset;
}
break;
case FaacSLHDecoderStepFoundPreambula:
if((!level) && (DURATION_DIFF(duration, instance->common.te_long * 2) <
instance->common.te_delta * 3)) {
//Found Preambula
instance->common.parser_step = FaacSLHDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = FaacSLHDecoderStepReset;
}
break;
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);
}
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
break;
} else {
instance->common.te_last = duration;
instance->common.parser_step = FaacSLHDecoderStepCheckDuration;
}
} else {
instance->common.parser_step = FaacSLHDecoderStepReset;
}
break;
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 = 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 = FaacSLHDecoderStepSaveDuration;
} else {
instance->common.parser_step = FaacSLHDecoderStepReset;
}
} else {
instance->common.parser_step = FaacSLHDecoderStepReset;
}
break;
}
}
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);
uint32_t code_fix = code_found_reverse & 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);
}
void subghz_decoder_faac_slh_to_load_protocol(SubGhzProtocolFaacSLH* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;
instance->common.code_last_found = data->code_found;
instance->common.code_last_count_bit = data->code_count_bit;
subghz_protocol_faac_slh_check_remote_controller(instance);
}

View File

@@ -1,58 +1,58 @@
#pragma once
#include "subghz_protocol_common.h"
typedef struct SubGhzProtocolFaacSLH SubGhzProtocolFaacSLH;
/** Allocate SubGhzProtocolFaacSLH
*
* @return SubGhzProtocolFaacSLH*
*/
SubGhzProtocolFaacSLH* subghz_protocol_faac_slh_alloc();
/** Free SubGhzProtocolFaacSLH
*
* @param instance
*/
void subghz_protocol_faac_slh_free(SubGhzProtocolFaacSLH* instance);
/** Sends the key on the air
*
* @param instance - SubGhzProtocolFaacSLH instance
* @param key - key send
* @param bit - count bit key
* @param repeat - repeat send key
*/
void subghz_protocol_faac_slh_send_key(SubGhzProtocolFaacSLH* instance, uint64_t key, uint8_t bit, uint8_t repeat);
/** Reset internal state
* @param instance - SubGhzProtocolFaacSLH instance
*/
void subghz_protocol_faac_slh_reset(SubGhzProtocolFaacSLH* instance);
/** Analysis of received data
*
* @param instance SubGhzProtocolFaacSLH instance
*/
void subghz_protocol_faac_slh_check_remote_controller(SubGhzProtocolFaacSLH* instance);
/** Parse accepted duration
*
* @param instance - SubGhzProtocolFaacSLH instance
* @param data - LevelDuration level_duration
*/
void subghz_protocol_faac_slh_parse(SubGhzProtocolFaacSLH* instance, bool level, uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzProtocolFaacSLH* instance
* @param output - output string
*/
void subghz_protocol_faac_slh_to_str(SubGhzProtocolFaacSLH* instance, string_t output);
/** Loading protocol from bin data
*
* @param instance - SubGhzProtocolFaacSLH instance
* @param context - SubGhzProtocolCommonLoad context
*/
void subghz_decoder_faac_slh_to_load_protocol(SubGhzProtocolFaacSLH* instance, void* context);
#pragma once
#include "subghz_protocol_common.h"
typedef struct SubGhzProtocolFaacSLH SubGhzProtocolFaacSLH;
/** Allocate SubGhzProtocolFaacSLH
*
* @return SubGhzProtocolFaacSLH*
*/
SubGhzProtocolFaacSLH* subghz_protocol_faac_slh_alloc();
/** Free SubGhzProtocolFaacSLH
*
* @param instance
*/
void subghz_protocol_faac_slh_free(SubGhzProtocolFaacSLH* instance);
/** Sends the key on the air
*
* @param instance - SubGhzProtocolFaacSLH instance
* @param key - key send
* @param bit - count bit key
* @param repeat - repeat send key
*/
void subghz_protocol_faac_slh_send_key(SubGhzProtocolFaacSLH* instance, uint64_t key, uint8_t bit, uint8_t repeat);
/** Reset internal state
* @param instance - SubGhzProtocolFaacSLH instance
*/
void subghz_protocol_faac_slh_reset(SubGhzProtocolFaacSLH* instance);
/** Analysis of received data
*
* @param instance SubGhzProtocolFaacSLH instance
*/
void subghz_protocol_faac_slh_check_remote_controller(SubGhzProtocolFaacSLH* instance);
/** Parse accepted duration
*
* @param instance - SubGhzProtocolFaacSLH instance
* @param data - LevelDuration level_duration
*/
void subghz_protocol_faac_slh_parse(SubGhzProtocolFaacSLH* instance, bool level, uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzProtocolFaacSLH* instance
* @param output - output string
*/
void subghz_protocol_faac_slh_to_str(SubGhzProtocolFaacSLH* instance, string_t output);
/** Loading protocol from bin data
*
* @param instance - SubGhzProtocolFaacSLH instance
* @param context - SubGhzProtocolCommonLoad context
*/
void subghz_decoder_faac_slh_to_load_protocol(SubGhzProtocolFaacSLH* instance, void* context);

View File

@@ -1,230 +1,230 @@
#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));
instance->common.name = "GateTX";
instance->common.code_min_count_bit_for_found = 24;
instance->common.te_short = 350;
instance->common.te_long = 700;
instance->common.te_delta = 100;
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 =
(SubGhzProtocolCommonLoadFromFile)subghz_protocol_gate_tx_to_load_protocol_from_file;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoadFromRAW)subghz_decoder_gate_tx_to_load_protocol;
instance->common.get_upload_protocol =
(SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_gate_tx_send_key;
return instance;
}
void subghz_protocol_gate_tx_free(SubGhzProtocolGateTX* instance) {
furi_assert(instance);
free(instance);
}
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;
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);
//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)) {
//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 {
//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);
}
}
return true;
}
void subghz_protocol_gate_tx_reset(SubGhzProtocolGateTX* instance) {
instance->common.parser_step = GateTXDecoderStepReset;
}
/** Analysis of received data
*
* @param instance SubGhzProtocolFaacSLH instance
*/
void subghz_protocol_gate_tx_check_remote_controller(SubGhzProtocolGateTX* instance) {
uint32_t code_found_reverse = subghz_protocol_common_reverse_key(
instance->common.code_last_found, instance->common.code_last_count_bit);
instance->common.serial = (code_found_reverse & 0xFF) << 12 |
((code_found_reverse >> 8) & 0xFF) << 4 |
((code_found_reverse >> 20) & 0x0F);
instance->common.btn = ((code_found_reverse >> 16) & 0x0F);
}
void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, uint32_t duration) {
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 = GateTXDecoderStepFoundStartBit;
} else {
instance->common.parser_step = GateTXDecoderStepReset;
}
break;
case GateTXDecoderStepFoundStartBit:
if(level &&
((DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta * 3))) {
//Found start bit
instance->common.parser_step = GateTXDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = GateTXDecoderStepReset;
}
break;
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);
}
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
break;
} else {
instance->common.te_last = duration;
instance->common.parser_step = GateTXDecoderStepCheckDuration;
}
}
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 = 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 = GateTXDecoderStepSaveDuration;
} else {
instance->common.parser_step = GateTXDecoderStepReset;
}
} else {
instance->common.parser_step = GateTXDecoderStepReset;
}
break;
}
}
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);
}
void subghz_protocol_gate_tx_to_save_str(SubGhzProtocolGateTX* instance, string_t output) {
string_printf(
output,
"Protocol: %s\n"
"Bit: %d\n"
"Key: %08lX\n",
instance->common.name,
instance->common.code_last_count_bit,
(uint32_t)(instance->common.code_last_found & 0x00000000ffffffff));
}
bool subghz_protocol_gate_tx_to_load_protocol_from_file(
FileWorker* file_worker,
SubGhzProtocolGateTX* instance) {
bool loaded = false;
string_t temp_str;
string_init(temp_str);
int res = 0;
int data = 0;
do {
// Read and parse bit data from 2nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
if(res != 1) {
break;
}
instance->common.code_last_count_bit = (uint8_t)data;
// Read and parse key data from 3nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
uint32_t temp_key = 0;
res = sscanf(string_get_cstr(temp_str), "Key: %08lX\n", &temp_key);
if(res != 1) {
break;
}
instance->common.code_last_found = (uint64_t)temp_key;
subghz_protocol_gate_tx_check_remote_controller(instance);
loaded = true;
} while(0);
string_clear(temp_str);
return loaded;
}
void subghz_decoder_gate_tx_to_load_protocol(SubGhzProtocolGateTX* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;
instance->common.code_last_found = data->code_found;
instance->common.code_last_count_bit = data->code_count_bit;
subghz_protocol_gate_tx_check_remote_controller(instance);
#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));
instance->common.name = "GateTX";
instance->common.code_min_count_bit_for_found = 24;
instance->common.te_short = 350;
instance->common.te_long = 700;
instance->common.te_delta = 100;
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 =
(SubGhzProtocolCommonLoadFromFile)subghz_protocol_gate_tx_to_load_protocol_from_file;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoadFromRAW)subghz_decoder_gate_tx_to_load_protocol;
instance->common.get_upload_protocol =
(SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_gate_tx_send_key;
return instance;
}
void subghz_protocol_gate_tx_free(SubGhzProtocolGateTX* instance) {
furi_assert(instance);
free(instance);
}
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;
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);
//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)) {
//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 {
//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);
}
}
return true;
}
void subghz_protocol_gate_tx_reset(SubGhzProtocolGateTX* instance) {
instance->common.parser_step = GateTXDecoderStepReset;
}
/** Analysis of received data
*
* @param instance SubGhzProtocolFaacSLH instance
*/
void subghz_protocol_gate_tx_check_remote_controller(SubGhzProtocolGateTX* instance) {
uint32_t code_found_reverse = subghz_protocol_common_reverse_key(
instance->common.code_last_found, instance->common.code_last_count_bit);
instance->common.serial = (code_found_reverse & 0xFF) << 12 |
((code_found_reverse >> 8) & 0xFF) << 4 |
((code_found_reverse >> 20) & 0x0F);
instance->common.btn = ((code_found_reverse >> 16) & 0x0F);
}
void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, uint32_t duration) {
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 = GateTXDecoderStepFoundStartBit;
} else {
instance->common.parser_step = GateTXDecoderStepReset;
}
break;
case GateTXDecoderStepFoundStartBit:
if(level &&
((DURATION_DIFF(duration, instance->common.te_long) < instance->common.te_delta * 3))) {
//Found start bit
instance->common.parser_step = GateTXDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = GateTXDecoderStepReset;
}
break;
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);
}
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
break;
} else {
instance->common.te_last = duration;
instance->common.parser_step = GateTXDecoderStepCheckDuration;
}
}
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 = 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 = GateTXDecoderStepSaveDuration;
} else {
instance->common.parser_step = GateTXDecoderStepReset;
}
} else {
instance->common.parser_step = GateTXDecoderStepReset;
}
break;
}
}
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);
}
void subghz_protocol_gate_tx_to_save_str(SubGhzProtocolGateTX* instance, string_t output) {
string_printf(
output,
"Protocol: %s\n"
"Bit: %d\n"
"Key: %08lX\n",
instance->common.name,
instance->common.code_last_count_bit,
(uint32_t)(instance->common.code_last_found & 0x00000000ffffffff));
}
bool subghz_protocol_gate_tx_to_load_protocol_from_file(
FileWorker* file_worker,
SubGhzProtocolGateTX* instance) {
bool loaded = false;
string_t temp_str;
string_init(temp_str);
int res = 0;
int data = 0;
do {
// Read and parse bit data from 2nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
if(res != 1) {
break;
}
instance->common.code_last_count_bit = (uint8_t)data;
// Read and parse key data from 3nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
uint32_t temp_key = 0;
res = sscanf(string_get_cstr(temp_str), "Key: %08lX\n", &temp_key);
if(res != 1) {
break;
}
instance->common.code_last_found = (uint64_t)temp_key;
subghz_protocol_gate_tx_check_remote_controller(instance);
loaded = true;
} while(0);
string_clear(temp_str);
return loaded;
}
void subghz_decoder_gate_tx_to_load_protocol(SubGhzProtocolGateTX* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;
instance->common.code_last_found = data->code_found;
instance->common.code_last_count_bit = data->code_count_bit;
subghz_protocol_gate_tx_check_remote_controller(instance);
}

View File

@@ -1,66 +1,66 @@
#pragma once
#include "subghz_protocol_common.h"
typedef struct SubGhzProtocolGateTX SubGhzProtocolGateTX;
/** Allocate SubGhzProtocolGateTX
*
* @return SubGhzProtocolGateTX*
*/
SubGhzProtocolGateTX* subghz_protocol_gate_tx_alloc();
/** Free SubGhzProtocolGateTX
*
* @param instance
*/
void subghz_protocol_gate_tx_free(SubGhzProtocolGateTX* instance);
/** Get upload protocol
*
* @param instance - SubGhzProtocolGateTX instance
* @param encoder - SubGhzProtocolCommonEncoder encoder
* @return bool
*/
bool subghz_protocol_gate_tx_send_key(SubGhzProtocolGateTX* instance, SubGhzProtocolCommonEncoder* encoder);
/** Reset internal state
* @param instance - SubGhzProtocolGateTX instance
*/
void subghz_protocol_gate_tx_reset(SubGhzProtocolGateTX* instance);
/** Parse accepted duration
*
* @param instance - SubGhzProtocolGateTX instance
* @param data - LevelDuration level_duration
*/
void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzProtocolFaacSLH* instance
* @param output - output string
*/
void subghz_protocol_gate_tx_to_str(SubGhzProtocolGateTX* instance, string_t output);
/** Get a string to save the protocol
*
* @param instance - SubGhzProtocolGateTX instance
* @param output - the resulting string
*/
void subghz_protocol_gate_tx_to_save_str(SubGhzProtocolGateTX* instance, string_t output);
/** Loading protocol from file
*
* @param file_worker - FileWorker file_worker
* @param instance - SubGhzProtocolGateTX instance
* @return bool
*/
bool subghz_protocol_gate_tx_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolGateTX* instance);
/** Loading protocol from bin data
*
* @param instance - SubGhzProtocolGateTX instance
* @param context - SubGhzProtocolCommonLoad context
*/
void subghz_decoder_gate_tx_to_load_protocol(SubGhzProtocolGateTX* instance, void* context);
#pragma once
#include "subghz_protocol_common.h"
typedef struct SubGhzProtocolGateTX SubGhzProtocolGateTX;
/** Allocate SubGhzProtocolGateTX
*
* @return SubGhzProtocolGateTX*
*/
SubGhzProtocolGateTX* subghz_protocol_gate_tx_alloc();
/** Free SubGhzProtocolGateTX
*
* @param instance
*/
void subghz_protocol_gate_tx_free(SubGhzProtocolGateTX* instance);
/** Get upload protocol
*
* @param instance - SubGhzProtocolGateTX instance
* @param encoder - SubGhzProtocolCommonEncoder encoder
* @return bool
*/
bool subghz_protocol_gate_tx_send_key(SubGhzProtocolGateTX* instance, SubGhzProtocolCommonEncoder* encoder);
/** Reset internal state
* @param instance - SubGhzProtocolGateTX instance
*/
void subghz_protocol_gate_tx_reset(SubGhzProtocolGateTX* instance);
/** Parse accepted duration
*
* @param instance - SubGhzProtocolGateTX instance
* @param data - LevelDuration level_duration
*/
void subghz_protocol_gate_tx_parse(SubGhzProtocolGateTX* instance, bool level, uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzProtocolFaacSLH* instance
* @param output - output string
*/
void subghz_protocol_gate_tx_to_str(SubGhzProtocolGateTX* instance, string_t output);
/** Get a string to save the protocol
*
* @param instance - SubGhzProtocolGateTX instance
* @param output - the resulting string
*/
void subghz_protocol_gate_tx_to_save_str(SubGhzProtocolGateTX* instance, string_t output);
/** Loading protocol from file
*
* @param file_worker - FileWorker file_worker
* @param instance - SubGhzProtocolGateTX instance
* @return bool
*/
bool subghz_protocol_gate_tx_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolGateTX* instance);
/** Loading protocol from bin data
*
* @param instance - SubGhzProtocolGateTX instance
* @param context - SubGhzProtocolCommonLoad context
*/
void subghz_decoder_gate_tx_to_load_protocol(SubGhzProtocolGateTX* instance, void* context);

View File

@@ -1,191 +1,191 @@
#include "subghz_protocol_ido.h"
struct SubGhzProtocolIDo {
SubGhzProtocolCommon common;
};
typedef enum {
IDoDecoderStepReset = 0,
IDoDecoderStepFoundPreambula,
IDoDecoderStepSaveDuration,
IDoDecoderStepCheckDuration,
} IDoDecoderStep;
SubGhzProtocolIDo* subghz_protocol_ido_alloc(void) {
SubGhzProtocolIDo* instance = furi_alloc(sizeof(SubGhzProtocolIDo));
instance->common.name = "iDo 117/111"; // PT4301-X";
instance->common.code_min_count_bit_for_found = 48;
instance->common.te_short = 450;
instance->common.te_long = 1450;
instance->common.te_delta = 150;
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;
return instance;
}
void subghz_protocol_ido_free(SubGhzProtocolIDo* instance) {
furi_assert(instance);
free(instance);
}
/** Send bit
*
* @param instance - SubGhzProtocolIDo instance
* @param bit - bit
*/
void subghz_protocol_ido_send_bit(SubGhzProtocolIDo* instance, uint8_t bit) {
if(bit) {
//send bit 1
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_short);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_short);
} else {
//send bit 0
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_short);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_long);
}
}
void subghz_protocol_ido_send_key(
SubGhzProtocolIDo* instance,
uint64_t key,
uint8_t bit,
uint8_t repeat) {
while(repeat--) {
SUBGHZ_TX_PIN_HIGH();
//Send header
delay_us(instance->common.te_short * 10);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_short * 10);
//Send key data
for(uint8_t i = bit; i > 0; i--) {
subghz_protocol_ido_send_bit(instance, bit_read(key, i - 1));
}
}
}
void subghz_protocol_ido_reset(SubGhzProtocolIDo* instance) {
instance->common.parser_step = IDoDecoderStepReset;
}
/** Analysis of received data
*
* @param instance SubGhzProtocolIDo instance
*/
void subghz_protocol_ido_check_remote_controller(SubGhzProtocolIDo* instance) {
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(
instance->common.code_last_found, instance->common.code_last_count_bit);
uint32_t code_fix = code_found_reverse & 0xFFFFFF;
instance->common.serial = code_fix & 0xFFFFF;
instance->common.btn = (code_fix >> 20) & 0x0F;
}
void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t duration) {
switch(instance->common.parser_step) {
case IDoDecoderStepReset:
if((level) && (DURATION_DIFF(duration, instance->common.te_short * 10) <
instance->common.te_delta * 5)) {
instance->common.parser_step = IDoDecoderStepFoundPreambula;
} else {
instance->common.parser_step = IDoDecoderStepReset;
}
break;
case IDoDecoderStepFoundPreambula:
if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 10) <
instance->common.te_delta * 5)) {
//Found Preambula
instance->common.parser_step = IDoDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = IDoDecoderStepReset;
}
break;
case IDoDecoderStepSaveDuration:
if(level) {
if(duration >= (instance->common.te_short * 5 + instance->common.te_delta)) {
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;
instance->common.code_last_count_bit = instance->common.code_count_bit;
if(instance->common.callback)
instance->common.callback(
(SubGhzProtocolCommon*)instance, instance->common.context);
}
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
break;
} else {
instance->common.te_last = duration;
instance->common.parser_step = IDoDecoderStepCheckDuration;
}
} else {
instance->common.parser_step = IDoDecoderStepReset;
}
break;
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 = 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 = IDoDecoderStepSaveDuration;
} else {
instance->common.parser_step = IDoDecoderStepReset;
}
} else {
instance->common.parser_step = IDoDecoderStepReset;
}
break;
}
}
void subghz_protocol_ido_to_str(SubGhzProtocolIDo* instance, string_t output) {
subghz_protocol_ido_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);
uint32_t code_fix = code_found_reverse & 0xFFFFFF;
uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFFF;
string_cat_printf(
output,
"%s %dbit\r\n"
"Key:0x%lX%08lX\r\n"
"Fix:%06lX \r\n"
"Hop:%06lX \r\n"
"Sn:%05lX Btn:%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_ido_to_load_protocol(SubGhzProtocolIDo* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;
instance->common.code_last_found = data->code_found;
instance->common.code_last_count_bit = data->code_count_bit;
subghz_protocol_ido_check_remote_controller(instance);
#include "subghz_protocol_ido.h"
struct SubGhzProtocolIDo {
SubGhzProtocolCommon common;
};
typedef enum {
IDoDecoderStepReset = 0,
IDoDecoderStepFoundPreambula,
IDoDecoderStepSaveDuration,
IDoDecoderStepCheckDuration,
} IDoDecoderStep;
SubGhzProtocolIDo* subghz_protocol_ido_alloc(void) {
SubGhzProtocolIDo* instance = furi_alloc(sizeof(SubGhzProtocolIDo));
instance->common.name = "iDo 117/111"; // PT4301-X";
instance->common.code_min_count_bit_for_found = 48;
instance->common.te_short = 450;
instance->common.te_long = 1450;
instance->common.te_delta = 150;
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;
return instance;
}
void subghz_protocol_ido_free(SubGhzProtocolIDo* instance) {
furi_assert(instance);
free(instance);
}
/** Send bit
*
* @param instance - SubGhzProtocolIDo instance
* @param bit - bit
*/
void subghz_protocol_ido_send_bit(SubGhzProtocolIDo* instance, uint8_t bit) {
if(bit) {
//send bit 1
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_short);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_short);
} else {
//send bit 0
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_short);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_long);
}
}
void subghz_protocol_ido_send_key(
SubGhzProtocolIDo* instance,
uint64_t key,
uint8_t bit,
uint8_t repeat) {
while(repeat--) {
SUBGHZ_TX_PIN_HIGH();
//Send header
delay_us(instance->common.te_short * 10);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_short * 10);
//Send key data
for(uint8_t i = bit; i > 0; i--) {
subghz_protocol_ido_send_bit(instance, bit_read(key, i - 1));
}
}
}
void subghz_protocol_ido_reset(SubGhzProtocolIDo* instance) {
instance->common.parser_step = IDoDecoderStepReset;
}
/** Analysis of received data
*
* @param instance SubGhzProtocolIDo instance
*/
void subghz_protocol_ido_check_remote_controller(SubGhzProtocolIDo* instance) {
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(
instance->common.code_last_found, instance->common.code_last_count_bit);
uint32_t code_fix = code_found_reverse & 0xFFFFFF;
instance->common.serial = code_fix & 0xFFFFF;
instance->common.btn = (code_fix >> 20) & 0x0F;
}
void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t duration) {
switch(instance->common.parser_step) {
case IDoDecoderStepReset:
if((level) && (DURATION_DIFF(duration, instance->common.te_short * 10) <
instance->common.te_delta * 5)) {
instance->common.parser_step = IDoDecoderStepFoundPreambula;
} else {
instance->common.parser_step = IDoDecoderStepReset;
}
break;
case IDoDecoderStepFoundPreambula:
if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 10) <
instance->common.te_delta * 5)) {
//Found Preambula
instance->common.parser_step = IDoDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = IDoDecoderStepReset;
}
break;
case IDoDecoderStepSaveDuration:
if(level) {
if(duration >= (instance->common.te_short * 5 + instance->common.te_delta)) {
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;
instance->common.code_last_count_bit = instance->common.code_count_bit;
if(instance->common.callback)
instance->common.callback(
(SubGhzProtocolCommon*)instance, instance->common.context);
}
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
break;
} else {
instance->common.te_last = duration;
instance->common.parser_step = IDoDecoderStepCheckDuration;
}
} else {
instance->common.parser_step = IDoDecoderStepReset;
}
break;
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 = 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 = IDoDecoderStepSaveDuration;
} else {
instance->common.parser_step = IDoDecoderStepReset;
}
} else {
instance->common.parser_step = IDoDecoderStepReset;
}
break;
}
}
void subghz_protocol_ido_to_str(SubGhzProtocolIDo* instance, string_t output) {
subghz_protocol_ido_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);
uint32_t code_fix = code_found_reverse & 0xFFFFFF;
uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFFF;
string_cat_printf(
output,
"%s %dbit\r\n"
"Key:0x%lX%08lX\r\n"
"Fix:%06lX \r\n"
"Hop:%06lX \r\n"
"Sn:%05lX Btn:%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_ido_to_load_protocol(SubGhzProtocolIDo* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;
instance->common.code_last_found = data->code_found;
instance->common.code_last_count_bit = data->code_count_bit;
subghz_protocol_ido_check_remote_controller(instance);
}

View File

@@ -1,58 +1,58 @@
#pragma once
#include "subghz_protocol_common.h"
typedef struct SubGhzProtocolIDo SubGhzProtocolIDo;
/** Allocate SubGhzProtocolIDo
*
* @return SubGhzProtocolIDo*
*/
SubGhzProtocolIDo* subghz_protocol_ido_alloc();
/** Free SubGhzProtocolIDo
*
* @param instance
*/
void subghz_protocol_ido_free(SubGhzProtocolIDo* instance);
/** Sends the key on the air
*
* @param instance - SubGhzProtocolIDo instance
* @param key - key send
* @param bit - count bit key
* @param repeat - repeat send key
*/
void subghz_protocol_ido_send_key(SubGhzProtocolIDo* instance, uint64_t key, uint8_t bit, uint8_t repeat);
/** Reset internal state
* @param instance - SubGhzProtocolIDo instance
*/
void subghz_protocol_ido_reset(SubGhzProtocolIDo* instance);
/** Analysis of received data
*
* @param instance SubGhzProtocolIDo instance
*/
void subghz_protocol_ido_check_remote_controller(SubGhzProtocolIDo* instance);
/** Parse accepted duration
*
* @param instance - SubGhzProtocolIDo instance
* @param data - LevelDuration level_duration
*/
void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzProtocolIDo* instance
* @param output - output string
*/
void subghz_protocol_ido_to_str(SubGhzProtocolIDo* instance, string_t output);
/** Loading protocol from bin data
*
* @param instance - SubGhzProtocolIDo instance
* @param context - SubGhzProtocolCommonLoad context
*/
void subghz_decoder_ido_to_load_protocol(SubGhzProtocolIDo* instance, void* context);
#pragma once
#include "subghz_protocol_common.h"
typedef struct SubGhzProtocolIDo SubGhzProtocolIDo;
/** Allocate SubGhzProtocolIDo
*
* @return SubGhzProtocolIDo*
*/
SubGhzProtocolIDo* subghz_protocol_ido_alloc();
/** Free SubGhzProtocolIDo
*
* @param instance
*/
void subghz_protocol_ido_free(SubGhzProtocolIDo* instance);
/** Sends the key on the air
*
* @param instance - SubGhzProtocolIDo instance
* @param key - key send
* @param bit - count bit key
* @param repeat - repeat send key
*/
void subghz_protocol_ido_send_key(SubGhzProtocolIDo* instance, uint64_t key, uint8_t bit, uint8_t repeat);
/** Reset internal state
* @param instance - SubGhzProtocolIDo instance
*/
void subghz_protocol_ido_reset(SubGhzProtocolIDo* instance);
/** Analysis of received data
*
* @param instance SubGhzProtocolIDo instance
*/
void subghz_protocol_ido_check_remote_controller(SubGhzProtocolIDo* instance);
/** Parse accepted duration
*
* @param instance - SubGhzProtocolIDo instance
* @param data - LevelDuration level_duration
*/
void subghz_protocol_ido_parse(SubGhzProtocolIDo* instance, bool level, uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzProtocolIDo* instance
* @param output - output string
*/
void subghz_protocol_ido_to_str(SubGhzProtocolIDo* instance, string_t output);
/** Loading protocol from bin data
*
* @param instance - SubGhzProtocolIDo instance
* @param context - SubGhzProtocolCommonLoad context
*/
void subghz_decoder_ido_to_load_protocol(SubGhzProtocolIDo* instance, void* context);

View File

@@ -1,486 +1,486 @@
#include "subghz_protocol_keeloq.h"
#include "subghz_protocol_keeloq_common.h"
#include "../subghz_keystore.h"
#include <furi.h>
#include <m-string.h>
struct SubGhzProtocolKeeloq {
SubGhzProtocolCommon common;
SubGhzKeystore* keystore;
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));
instance->keystore = keystore;
instance->common.name = "KeeLoq";
instance->common.code_min_count_bit_for_found = 64;
instance->common.te_short = 400;
instance->common.te_long = 800;
instance->common.te_delta = 140;
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;
instance->common.to_load_protocol_from_file =
(SubGhzProtocolCommonLoadFromFile)subghz_protocol_keeloq_to_load_protocol_from_file;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoadFromRAW)subghz_decoder_keeloq_to_load_protocol;
instance->common.get_upload_protocol =
(SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_keeloq_send_key;
return instance;
}
void subghz_protocol_keeloq_free(SubGhzProtocolKeeloq* instance) {
furi_assert(instance);
free(instance);
}
/** Checking the accepted code against the database manafacture key
*
* @param instance SubGhzProtocolKeeloq instance
* @param fix fix part of the parcel
* @param hop hop encrypted part of the parcel
* @return true on successful search
*/
uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
SubGhzProtocolKeeloq* instance,
uint32_t fix,
uint32_t hop) {
uint16_t end_serial = (uint16_t)(fix & 0x3FF);
uint8_t btn = (uint8_t)(fix >> 28);
uint32_t decrypt = 0;
uint64_t man_normal_learning;
for
M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) {
switch(manufacture_code->type) {
case KEELOQ_LEARNING_SIMPLE:
//Simple Learning
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
if((decrypt >> 28 == btn) &&
(((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial) ||
((((uint16_t)(decrypt >> 16)) & 0x3FF) == 0))) {
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt = decrypt & 0x0000FFFF;
return 1;
}
break;
case KEELOQ_LEARNING_NORMAL:
// Normal_Learning
// https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37
man_normal_learning =
subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning);
if((decrypt >> 28 == btn) &&
(((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial) ||
((((uint16_t)(decrypt >> 16)) & 0x3FF) == 0))) {
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt = decrypt & 0x0000FFFF;
return 1;
}
break;
case KEELOQ_LEARNING_UNKNOWN:
// Simple Learning
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
if((decrypt >> 28 == btn) &&
(((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial) ||
((((uint16_t)(decrypt >> 16)) & 0x3FF) == 0))) {
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt = decrypt & 0x0000FFFF;
return 1;
}
// Check for mirrored man
uint64_t man_rev = 0;
uint64_t man_rev_byte = 0;
for(uint8_t i = 0; i < 64; i += 8) {
man_rev_byte = (uint8_t)(manufacture_code->key >> i);
man_rev = man_rev | man_rev_byte << (56 - i);
}
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev);
if((decrypt >> 28 == btn) &&
(((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial) ||
((((uint16_t)(decrypt >> 16)) & 0x3FF) == 0))) {
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt = decrypt & 0x0000FFFF;
return 1;
}
//###########################
// Normal_Learning
// https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37
man_normal_learning =
subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning);
if((decrypt >> 28 == btn) &&
(((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial) ||
((((uint16_t)(decrypt >> 16)) & 0x3FF) == 0))) {
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt = decrypt & 0x0000FFFF;
return 1;
}
// Check for mirrored man
man_rev = 0;
man_rev_byte = 0;
for(uint8_t i = 0; i < 64; i += 8) {
man_rev_byte = (uint8_t)(manufacture_code->key >> i);
man_rev = man_rev | man_rev_byte << (56 - i);
}
man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, man_rev);
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning);
if((decrypt >> 28 == btn) &&
(((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial) ||
((((uint16_t)(decrypt >> 16)) & 0x3FF) == 0))) {
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;
return 0;
}
/** Analysis of received data
*
* @param instance SubGhzProtocolKeeloq instance
*/
void subghz_protocol_keeloq_check_remote_controller(SubGhzProtocolKeeloq* instance) {
uint64_t key = subghz_protocol_common_reverse_key(
instance->common.code_last_found, instance->common.code_last_count_bit);
uint32_t key_fix = key >> 32;
uint32_t key_hop = key & 0x00000000ffffffff;
// Check key AN-Motors
if((key_hop >> 24) == ((key_hop >> 16) & 0x00ff) &&
(key_fix >> 28) == ((key_hop >> 12) & 0x0f) && (key_hop & 0xFFF) == 0x404) {
instance->manufacture_name = "AN-Motors";
instance->common.cnt = key_hop >> 16;
} else if((key_hop & 0xFFF) == (0x000) && (key_fix >> 28) == ((key_hop >> 12) & 0x0f)) {
instance->manufacture_name = "HCS101";
instance->common.cnt = key_hop >> 16;
} else {
subghz_protocol_keeloq_check_remote_controller_selector(instance, key_fix, key_hop);
}
instance->common.serial = key_fix & 0x0FFFFFFF;
instance->common.btn = key_fix >> 28;
}
const char* subghz_protocol_keeloq_find_and_get_manufacture_name(void* context) {
SubGhzProtocolKeeloq* instance = context;
subghz_protocol_keeloq_check_remote_controller(instance);
return instance->manufacture_name;
}
const char* subghz_protocol_keeloq_get_manufacture_name(void* context) {
SubGhzProtocolKeeloq* instance = context;
return instance->manufacture_name;
}
bool subghz_protocol_keeloq_set_manufacture_name(void* context, const char* manufacture_name) {
SubGhzProtocolKeeloq* instance = context;
instance->manufacture_name = manufacture_name;
int res = 0;
for
M_EACH(
manufacture_code,
*subghz_keystore_get_data(instance->keystore),
SubGhzKeyArray_t) {
res = strcmp(string_get_cstr(manufacture_code->name), instance->manufacture_name);
if(res == 0) return true;
}
instance->manufacture_name = "Unknown";
return false;
}
uint64_t subghz_protocol_keeloq_gen_key(void* context) {
SubGhzProtocolKeeloq* instance = context;
uint32_t fix = instance->common.btn << 28 | instance->common.serial;
uint32_t decrypt = instance->common.btn << 28 | (instance->common.serial & 0x3FF) << 16 |
instance->common.cnt;
uint32_t hop = 0;
uint64_t man_normal_learning = 0;
int res = 0;
for
M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) {
res = strcmp(string_get_cstr(manufacture_code->name), instance->manufacture_name);
if(res == 0) {
switch(manufacture_code->type) {
case KEELOQ_LEARNING_SIMPLE:
//Simple Learning
hop = subghz_protocol_keeloq_common_encrypt(decrypt, manufacture_code->key);
break;
case KEELOQ_LEARNING_NORMAL:
//Simple Learning
man_normal_learning =
subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man_normal_learning);
break;
case KEELOQ_LEARNING_UNKNOWN:
hop = 0; //todo
break;
}
break;
}
}
uint64_t yek = (uint64_t)fix << 32 | hop;
return subghz_protocol_common_reverse_key(yek, instance->common.code_last_count_bit);
}
bool subghz_protocol_keeloq_send_key(
SubGhzProtocolKeeloq* instance,
SubGhzProtocolCommonEncoder* encoder) {
furi_assert(instance);
furi_assert(encoder);
//gen new key
instance->common.cnt++;
instance->common.code_last_found = subghz_protocol_keeloq_gen_key(instance);
if(instance->common.callback)
instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
if(!strcmp(instance->manufacture_name, "Unknown")) {
return false;
}
size_t index = 0;
encoder->size_upload = 11 * 2 + 2 + (instance->common.code_last_count_bit * 2) + 4;
if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false;
//Send header
for(uint8_t i = 11; i > 0; 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);
}
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 * 10);
//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)) {
//send bit 1
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);
} else {
//send bit 0
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);
}
}
// +send 2 status bit
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_long);
//encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short);
// send end
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 * 40);
return true;
}
void subghz_protocol_keeloq_reset(SubGhzProtocolKeeloq* instance) {
instance->common.parser_step = KeeloqDecoderStepReset;
}
void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, uint32_t duration) {
switch(instance->common.parser_step) {
case KeeloqDecoderStepReset:
if((level) &&
DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) {
instance->common.parser_step = KeeloqDecoderStepCheckPreambula;
instance->common.header_count++;
} else {
instance->common.parser_step = KeeloqDecoderStepReset;
}
break;
case KeeloqDecoderStepCheckPreambula:
if((!level) &&
(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
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 = KeeloqDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = KeeloqDecoderStepReset;
instance->common.header_count = 0;
}
break;
case KeeloqDecoderStepSaveDuration:
if(level) {
instance->common.te_last = duration;
instance->common.parser_step = KeeloqDecoderStepCheckDuration;
}
break;
case KeeloqDecoderStepCheckDuration:
if(!level) {
if(duration >= (instance->common.te_short * 2 + instance->common.te_delta)) {
// Found end TX
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) {
instance->common.code_last_found = instance->common.code_found;
instance->common.code_last_count_bit = instance->common.code_count_bit;
if(instance->common.callback)
instance->common.callback(
(SubGhzProtocolCommon*)instance, instance->common.context);
}
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
instance->common.header_count = 0;
}
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)) {
if(instance->common.code_count_bit <
instance->common.code_min_count_bit_for_found) {
subghz_protocol_common_add_bit(&instance->common, 1);
}
instance->common.parser_step = KeeloqDecoderStepSaveDuration;
} 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)) {
if(instance->common.code_count_bit <
instance->common.code_min_count_bit_for_found) {
subghz_protocol_common_add_bit(&instance->common, 0);
}
instance->common.parser_step = KeeloqDecoderStepSaveDuration;
} else {
instance->common.parser_step = KeeloqDecoderStepReset;
instance->common.header_count = 0;
}
} else {
instance->common.parser_step = KeeloqDecoderStepReset;
instance->common.header_count = 0;
}
break;
}
}
void subghz_protocol_keeloq_to_str(SubGhzProtocolKeeloq* instance, string_t output) {
subghz_protocol_keeloq_check_remote_controller(instance);
uint32_t code_found_hi = instance->common.code_last_found >> 32;
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(
instance->common.code_last_found, instance->common.code_last_count_bit);
uint32_t code_found_reverse_hi = code_found_reverse >> 32;
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
string_cat_printf(
output,
"%s %dbit\r\n"
"Key:%08lX%08lX\r\n"
"Fix:0x%08lX Cnt:%04X\r\n"
"Hop:0x%08lX Btn:%02lX\r\n"
"MF:%s\r\n"
"Sn:0x%07lX \r\n",
instance->common.name,
instance->common.code_last_count_bit,
code_found_hi,
code_found_lo,
code_found_reverse_hi,
instance->common.cnt,
code_found_reverse_lo,
instance->common.btn,
instance->manufacture_name,
instance->common.serial);
}
void subghz_protocol_keeloq_to_save_str(SubGhzProtocolKeeloq* instance, string_t output) {
string_printf(
output,
"Protocol: %s\n"
"Bit: %d\n"
"Key: %08lX%08lX\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 & 0xFFFFFFFF));
}
bool subghz_protocol_keeloq_to_load_protocol_from_file(
FileWorker* file_worker,
SubGhzProtocolKeeloq* instance) {
bool loaded = false;
string_t temp_str;
string_init(temp_str);
int res = 0;
int data = 0;
do {
// Read and parse bit data from 2nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
if(res != 1) {
break;
}
instance->common.code_last_count_bit = (uint8_t)data;
// Read and parse key data from 3nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
// strlen("Key: ") = 5
string_right(temp_str, 5);
uint8_t buf_key[8] = {0};
if(!subghz_protocol_common_read_hex(temp_str, buf_key, 8)) {
break;
}
for(uint8_t i = 0; i < 8; i++) {
instance->common.code_last_found = instance->common.code_last_found << 8 | buf_key[i];
}
loaded = true;
} while(0);
string_clear(temp_str);
return loaded;
}
void subghz_decoder_keeloq_to_load_protocol(SubGhzProtocolKeeloq* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;
instance->common.code_last_found = data->code_found;
instance->common.code_last_count_bit = data->code_count_bit;
subghz_protocol_keeloq_check_remote_controller(instance);
}
#include "subghz_protocol_keeloq.h"
#include "subghz_protocol_keeloq_common.h"
#include "../subghz_keystore.h"
#include <furi.h>
#include <m-string.h>
struct SubGhzProtocolKeeloq {
SubGhzProtocolCommon common;
SubGhzKeystore* keystore;
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));
instance->keystore = keystore;
instance->common.name = "KeeLoq";
instance->common.code_min_count_bit_for_found = 64;
instance->common.te_short = 400;
instance->common.te_long = 800;
instance->common.te_delta = 140;
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;
instance->common.to_load_protocol_from_file =
(SubGhzProtocolCommonLoadFromFile)subghz_protocol_keeloq_to_load_protocol_from_file;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoadFromRAW)subghz_decoder_keeloq_to_load_protocol;
instance->common.get_upload_protocol =
(SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_keeloq_send_key;
return instance;
}
void subghz_protocol_keeloq_free(SubGhzProtocolKeeloq* instance) {
furi_assert(instance);
free(instance);
}
/** Checking the accepted code against the database manafacture key
*
* @param instance SubGhzProtocolKeeloq instance
* @param fix fix part of the parcel
* @param hop hop encrypted part of the parcel
* @return true on successful search
*/
uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
SubGhzProtocolKeeloq* instance,
uint32_t fix,
uint32_t hop) {
uint16_t end_serial = (uint16_t)(fix & 0x3FF);
uint8_t btn = (uint8_t)(fix >> 28);
uint32_t decrypt = 0;
uint64_t man_normal_learning;
for
M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) {
switch(manufacture_code->type) {
case KEELOQ_LEARNING_SIMPLE:
//Simple Learning
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
if((decrypt >> 28 == btn) &&
(((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial) ||
((((uint16_t)(decrypt >> 16)) & 0x3FF) == 0))) {
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt = decrypt & 0x0000FFFF;
return 1;
}
break;
case KEELOQ_LEARNING_NORMAL:
// Normal_Learning
// https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37
man_normal_learning =
subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning);
if((decrypt >> 28 == btn) &&
(((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial) ||
((((uint16_t)(decrypt >> 16)) & 0x3FF) == 0))) {
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt = decrypt & 0x0000FFFF;
return 1;
}
break;
case KEELOQ_LEARNING_UNKNOWN:
// Simple Learning
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
if((decrypt >> 28 == btn) &&
(((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial) ||
((((uint16_t)(decrypt >> 16)) & 0x3FF) == 0))) {
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt = decrypt & 0x0000FFFF;
return 1;
}
// Check for mirrored man
uint64_t man_rev = 0;
uint64_t man_rev_byte = 0;
for(uint8_t i = 0; i < 64; i += 8) {
man_rev_byte = (uint8_t)(manufacture_code->key >> i);
man_rev = man_rev | man_rev_byte << (56 - i);
}
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev);
if((decrypt >> 28 == btn) &&
(((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial) ||
((((uint16_t)(decrypt >> 16)) & 0x3FF) == 0))) {
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt = decrypt & 0x0000FFFF;
return 1;
}
//###########################
// Normal_Learning
// https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37
man_normal_learning =
subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning);
if((decrypt >> 28 == btn) &&
(((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial) ||
((((uint16_t)(decrypt >> 16)) & 0x3FF) == 0))) {
instance->manufacture_name = string_get_cstr(manufacture_code->name);
instance->common.cnt = decrypt & 0x0000FFFF;
return 1;
}
// Check for mirrored man
man_rev = 0;
man_rev_byte = 0;
for(uint8_t i = 0; i < 64; i += 8) {
man_rev_byte = (uint8_t)(manufacture_code->key >> i);
man_rev = man_rev | man_rev_byte << (56 - i);
}
man_normal_learning = subghz_protocol_keeloq_common_normal_learning(fix, man_rev);
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning);
if((decrypt >> 28 == btn) &&
(((((uint16_t)(decrypt >> 16)) & 0x3FF) == end_serial) ||
((((uint16_t)(decrypt >> 16)) & 0x3FF) == 0))) {
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;
return 0;
}
/** Analysis of received data
*
* @param instance SubGhzProtocolKeeloq instance
*/
void subghz_protocol_keeloq_check_remote_controller(SubGhzProtocolKeeloq* instance) {
uint64_t key = subghz_protocol_common_reverse_key(
instance->common.code_last_found, instance->common.code_last_count_bit);
uint32_t key_fix = key >> 32;
uint32_t key_hop = key & 0x00000000ffffffff;
// Check key AN-Motors
if((key_hop >> 24) == ((key_hop >> 16) & 0x00ff) &&
(key_fix >> 28) == ((key_hop >> 12) & 0x0f) && (key_hop & 0xFFF) == 0x404) {
instance->manufacture_name = "AN-Motors";
instance->common.cnt = key_hop >> 16;
} else if((key_hop & 0xFFF) == (0x000) && (key_fix >> 28) == ((key_hop >> 12) & 0x0f)) {
instance->manufacture_name = "HCS101";
instance->common.cnt = key_hop >> 16;
} else {
subghz_protocol_keeloq_check_remote_controller_selector(instance, key_fix, key_hop);
}
instance->common.serial = key_fix & 0x0FFFFFFF;
instance->common.btn = key_fix >> 28;
}
const char* subghz_protocol_keeloq_find_and_get_manufacture_name(void* context) {
SubGhzProtocolKeeloq* instance = context;
subghz_protocol_keeloq_check_remote_controller(instance);
return instance->manufacture_name;
}
const char* subghz_protocol_keeloq_get_manufacture_name(void* context) {
SubGhzProtocolKeeloq* instance = context;
return instance->manufacture_name;
}
bool subghz_protocol_keeloq_set_manufacture_name(void* context, const char* manufacture_name) {
SubGhzProtocolKeeloq* instance = context;
instance->manufacture_name = manufacture_name;
int res = 0;
for
M_EACH(
manufacture_code,
*subghz_keystore_get_data(instance->keystore),
SubGhzKeyArray_t) {
res = strcmp(string_get_cstr(manufacture_code->name), instance->manufacture_name);
if(res == 0) return true;
}
instance->manufacture_name = "Unknown";
return false;
}
uint64_t subghz_protocol_keeloq_gen_key(void* context) {
SubGhzProtocolKeeloq* instance = context;
uint32_t fix = instance->common.btn << 28 | instance->common.serial;
uint32_t decrypt = instance->common.btn << 28 | (instance->common.serial & 0x3FF) << 16 |
instance->common.cnt;
uint32_t hop = 0;
uint64_t man_normal_learning = 0;
int res = 0;
for
M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) {
res = strcmp(string_get_cstr(manufacture_code->name), instance->manufacture_name);
if(res == 0) {
switch(manufacture_code->type) {
case KEELOQ_LEARNING_SIMPLE:
//Simple Learning
hop = subghz_protocol_keeloq_common_encrypt(decrypt, manufacture_code->key);
break;
case KEELOQ_LEARNING_NORMAL:
//Simple Learning
man_normal_learning =
subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man_normal_learning);
break;
case KEELOQ_LEARNING_UNKNOWN:
hop = 0; //todo
break;
}
break;
}
}
uint64_t yek = (uint64_t)fix << 32 | hop;
return subghz_protocol_common_reverse_key(yek, instance->common.code_last_count_bit);
}
bool subghz_protocol_keeloq_send_key(
SubGhzProtocolKeeloq* instance,
SubGhzProtocolCommonEncoder* encoder) {
furi_assert(instance);
furi_assert(encoder);
//gen new key
instance->common.cnt++;
instance->common.code_last_found = subghz_protocol_keeloq_gen_key(instance);
if(instance->common.callback)
instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
if(!strcmp(instance->manufacture_name, "Unknown")) {
return false;
}
size_t index = 0;
encoder->size_upload = 11 * 2 + 2 + (instance->common.code_last_count_bit * 2) + 4;
if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false;
//Send header
for(uint8_t i = 11; i > 0; 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);
}
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 * 10);
//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)) {
//send bit 1
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);
} else {
//send bit 0
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);
}
}
// +send 2 status bit
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_long);
//encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->common.te_short);
// send end
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 * 40);
return true;
}
void subghz_protocol_keeloq_reset(SubGhzProtocolKeeloq* instance) {
instance->common.parser_step = KeeloqDecoderStepReset;
}
void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, uint32_t duration) {
switch(instance->common.parser_step) {
case KeeloqDecoderStepReset:
if((level) &&
DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) {
instance->common.parser_step = KeeloqDecoderStepCheckPreambula;
instance->common.header_count++;
} else {
instance->common.parser_step = KeeloqDecoderStepReset;
}
break;
case KeeloqDecoderStepCheckPreambula:
if((!level) &&
(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta)) {
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 = KeeloqDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = KeeloqDecoderStepReset;
instance->common.header_count = 0;
}
break;
case KeeloqDecoderStepSaveDuration:
if(level) {
instance->common.te_last = duration;
instance->common.parser_step = KeeloqDecoderStepCheckDuration;
}
break;
case KeeloqDecoderStepCheckDuration:
if(!level) {
if(duration >= (instance->common.te_short * 2 + instance->common.te_delta)) {
// Found end TX
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) {
instance->common.code_last_found = instance->common.code_found;
instance->common.code_last_count_bit = instance->common.code_count_bit;
if(instance->common.callback)
instance->common.callback(
(SubGhzProtocolCommon*)instance, instance->common.context);
}
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
instance->common.header_count = 0;
}
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)) {
if(instance->common.code_count_bit <
instance->common.code_min_count_bit_for_found) {
subghz_protocol_common_add_bit(&instance->common, 1);
}
instance->common.parser_step = KeeloqDecoderStepSaveDuration;
} 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)) {
if(instance->common.code_count_bit <
instance->common.code_min_count_bit_for_found) {
subghz_protocol_common_add_bit(&instance->common, 0);
}
instance->common.parser_step = KeeloqDecoderStepSaveDuration;
} else {
instance->common.parser_step = KeeloqDecoderStepReset;
instance->common.header_count = 0;
}
} else {
instance->common.parser_step = KeeloqDecoderStepReset;
instance->common.header_count = 0;
}
break;
}
}
void subghz_protocol_keeloq_to_str(SubGhzProtocolKeeloq* instance, string_t output) {
subghz_protocol_keeloq_check_remote_controller(instance);
uint32_t code_found_hi = instance->common.code_last_found >> 32;
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(
instance->common.code_last_found, instance->common.code_last_count_bit);
uint32_t code_found_reverse_hi = code_found_reverse >> 32;
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
string_cat_printf(
output,
"%s %dbit\r\n"
"Key:%08lX%08lX\r\n"
"Fix:0x%08lX Cnt:%04X\r\n"
"Hop:0x%08lX Btn:%02lX\r\n"
"MF:%s\r\n"
"Sn:0x%07lX \r\n",
instance->common.name,
instance->common.code_last_count_bit,
code_found_hi,
code_found_lo,
code_found_reverse_hi,
instance->common.cnt,
code_found_reverse_lo,
instance->common.btn,
instance->manufacture_name,
instance->common.serial);
}
void subghz_protocol_keeloq_to_save_str(SubGhzProtocolKeeloq* instance, string_t output) {
string_printf(
output,
"Protocol: %s\n"
"Bit: %d\n"
"Key: %08lX%08lX\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 & 0xFFFFFFFF));
}
bool subghz_protocol_keeloq_to_load_protocol_from_file(
FileWorker* file_worker,
SubGhzProtocolKeeloq* instance) {
bool loaded = false;
string_t temp_str;
string_init(temp_str);
int res = 0;
int data = 0;
do {
// Read and parse bit data from 2nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
if(res != 1) {
break;
}
instance->common.code_last_count_bit = (uint8_t)data;
// Read and parse key data from 3nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
// strlen("Key: ") = 5
string_right(temp_str, 5);
uint8_t buf_key[8] = {0};
if(!subghz_protocol_common_read_hex(temp_str, buf_key, 8)) {
break;
}
for(uint8_t i = 0; i < 8; i++) {
instance->common.code_last_found = instance->common.code_last_found << 8 | buf_key[i];
}
loaded = true;
} while(0);
string_clear(temp_str);
return loaded;
}
void subghz_decoder_keeloq_to_load_protocol(SubGhzProtocolKeeloq* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;
instance->common.code_last_found = data->code_found;
instance->common.code_last_count_bit = data->code_count_bit;
subghz_protocol_keeloq_check_remote_controller(instance);
}

View File

@@ -1,97 +1,97 @@
#pragma once
#include "subghz_protocol_common.h"
typedef struct SubGhzKeystore SubGhzKeystore;
typedef struct SubGhzProtocolKeeloq SubGhzProtocolKeeloq;
/** Allocate SubGhzProtocolKeeloq
*
* @return SubGhzProtocolKeeloq*
*/
SubGhzProtocolKeeloq* subghz_protocol_keeloq_alloc(SubGhzKeystore* keystore);
/** Free SubGhzProtocolKeeloq
*
* @param instance
*/
void subghz_protocol_keeloq_free(SubGhzProtocolKeeloq* instance);
/** Find and get manufacture name
*
* @param context - SubGhzProtocolKeeloq context
* @return name - char* manufacture name
*/
const char* subghz_protocol_keeloq_find_and_get_manufacture_name(void* context);
/** Get manufacture name
*
* @param context - SubGhzProtocolKeeloq context
* @return name - char* manufacture name
*/
const char* subghz_protocol_keeloq_get_manufacture_name(void* context);
/** Set manufacture name
*
* @param manufacture_name - manufacture name
* @param context - SubGhzProtocolKeeloq context
* @return bool
*/
bool subghz_protocol_keeloq_set_manufacture_name(void* context, const char* manufacture_name);
/** Get key keeloq
*
* @param context - SubGhzProtocolKeeloq context
* @return key
*/
uint64_t subghz_protocol_keeloq_gen_key(void* context);
/** Get upload protocol
*
* @param instance - SubGhzProtocolKeeloq instance
* @param encoder - SubGhzProtocolCommonEncoder encoder
* @return bool
*/
bool subghz_protocol_keeloq_send_key(SubGhzProtocolKeeloq* instance, SubGhzProtocolCommonEncoder* encoder);
/** Reset internal state
* @param instance - SubGhzProtocolKeeloq instance
*/
void subghz_protocol_keeloq_reset(SubGhzProtocolKeeloq* instance);
/** Parse accepted duration
*
* @param instance - SubGhzProtocolKeeloq instance
* @param data - LevelDuration level_duration
*/
void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzProtocolKeeloq* instance
* @param output - output string
*/
void subghz_protocol_keeloq_to_str(SubGhzProtocolKeeloq* instance, string_t output);
/** Get a string to save the protocol
*
* @param instance - SubGhzProtocolKeeloq instance
* @param output - the resulting string
*/
void subghz_protocol_keeloq_to_save_str(SubGhzProtocolKeeloq* instance, string_t output);
/** Loading protocol from file
*
* @param file_worker - FileWorker file_worker
* @param instance - SubGhzProtocolKeeloq instance
* @return bool
*/
bool subghz_protocol_keeloq_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolKeeloq* instance);
/** Loading protocol from bin data
*
* @param instance - SubGhzProtocolKeeloq instance
* @param context - SubGhzProtocolCommonLoad context
*/
void subghz_decoder_keeloq_to_load_protocol(SubGhzProtocolKeeloq* instance, void* context);
#pragma once
#include "subghz_protocol_common.h"
typedef struct SubGhzKeystore SubGhzKeystore;
typedef struct SubGhzProtocolKeeloq SubGhzProtocolKeeloq;
/** Allocate SubGhzProtocolKeeloq
*
* @return SubGhzProtocolKeeloq*
*/
SubGhzProtocolKeeloq* subghz_protocol_keeloq_alloc(SubGhzKeystore* keystore);
/** Free SubGhzProtocolKeeloq
*
* @param instance
*/
void subghz_protocol_keeloq_free(SubGhzProtocolKeeloq* instance);
/** Find and get manufacture name
*
* @param context - SubGhzProtocolKeeloq context
* @return name - char* manufacture name
*/
const char* subghz_protocol_keeloq_find_and_get_manufacture_name(void* context);
/** Get manufacture name
*
* @param context - SubGhzProtocolKeeloq context
* @return name - char* manufacture name
*/
const char* subghz_protocol_keeloq_get_manufacture_name(void* context);
/** Set manufacture name
*
* @param manufacture_name - manufacture name
* @param context - SubGhzProtocolKeeloq context
* @return bool
*/
bool subghz_protocol_keeloq_set_manufacture_name(void* context, const char* manufacture_name);
/** Get key keeloq
*
* @param context - SubGhzProtocolKeeloq context
* @return key
*/
uint64_t subghz_protocol_keeloq_gen_key(void* context);
/** Get upload protocol
*
* @param instance - SubGhzProtocolKeeloq instance
* @param encoder - SubGhzProtocolCommonEncoder encoder
* @return bool
*/
bool subghz_protocol_keeloq_send_key(SubGhzProtocolKeeloq* instance, SubGhzProtocolCommonEncoder* encoder);
/** Reset internal state
* @param instance - SubGhzProtocolKeeloq instance
*/
void subghz_protocol_keeloq_reset(SubGhzProtocolKeeloq* instance);
/** Parse accepted duration
*
* @param instance - SubGhzProtocolKeeloq instance
* @param data - LevelDuration level_duration
*/
void subghz_protocol_keeloq_parse(SubGhzProtocolKeeloq* instance, bool level, uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzProtocolKeeloq* instance
* @param output - output string
*/
void subghz_protocol_keeloq_to_str(SubGhzProtocolKeeloq* instance, string_t output);
/** Get a string to save the protocol
*
* @param instance - SubGhzProtocolKeeloq instance
* @param output - the resulting string
*/
void subghz_protocol_keeloq_to_save_str(SubGhzProtocolKeeloq* instance, string_t output);
/** Loading protocol from file
*
* @param file_worker - FileWorker file_worker
* @param instance - SubGhzProtocolKeeloq instance
* @return bool
*/
bool subghz_protocol_keeloq_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolKeeloq* instance);
/** Loading protocol from bin data
*
* @param instance - SubGhzProtocolKeeloq instance
* @param context - SubGhzProtocolCommonLoad context
*/
void subghz_decoder_keeloq_to_load_protocol(SubGhzProtocolKeeloq* instance, void* context);

View File

@@ -1,49 +1,49 @@
#include "subghz_protocol_keeloq_common.h"
#include <furi.h>
#include <m-string.h>
#include <m-array.h>
/** Simple Learning Encrypt
* @param data - 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter
* @param key - manufacture (64bit)
* @return keelog encrypt data
*/
inline uint32_t subghz_protocol_keeloq_common_encrypt(const uint32_t data, const uint64_t key) {
uint32_t x = data, r;
for (r = 0; r < 528; r++)
x = (x>>1)^((bit(x,0)^bit(x,16)^(uint32_t)bit(key,r&63)^bit(KEELOQ_NLF,g5(x,1,9,20,26,31)))<<31);
return x;
}
/** Simple Learning Decrypt
* @param data - keelog encrypt data
* @param key - manufacture (64bit)
* @return 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter
*/
inline uint32_t subghz_protocol_keeloq_common_decrypt(const uint32_t data, const uint64_t key) {
uint32_t x = data, r;
for (r = 0; r < 528; r++)
x = (x<<1)^bit(x,31)^bit(x,15)^(uint32_t)bit(key,(15-r)&63)^bit(KEELOQ_NLF,g5(x,0,8,19,25,30));
return x;
}
/** Normal Learning
* @param data - serial number (28bit)
* @param key - manufacture (64bit)
* @return manufacture for this serial number (64bit)
*/
inline uint64_t subghz_protocol_keeloq_common_normal_learning(uint32_t data, const uint64_t key){
uint32_t k1,k2;
data&=0x0FFFFFFF;
data|=0x20000000;
k1=subghz_protocol_keeloq_common_decrypt(data, key);
data&=0x0FFFFFFF;
data|=0x60000000;
k2=subghz_protocol_keeloq_common_decrypt(data, key);
return ((uint64_t)k2<<32)| k1; // key - shifrovanoya
}
#include "subghz_protocol_keeloq_common.h"
#include <furi.h>
#include <m-string.h>
#include <m-array.h>
/** Simple Learning Encrypt
* @param data - 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter
* @param key - manufacture (64bit)
* @return keelog encrypt data
*/
inline uint32_t subghz_protocol_keeloq_common_encrypt(const uint32_t data, const uint64_t key) {
uint32_t x = data, r;
for (r = 0; r < 528; r++)
x = (x>>1)^((bit(x,0)^bit(x,16)^(uint32_t)bit(key,r&63)^bit(KEELOQ_NLF,g5(x,1,9,20,26,31)))<<31);
return x;
}
/** Simple Learning Decrypt
* @param data - keelog encrypt data
* @param key - manufacture (64bit)
* @return 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter
*/
inline uint32_t subghz_protocol_keeloq_common_decrypt(const uint32_t data, const uint64_t key) {
uint32_t x = data, r;
for (r = 0; r < 528; r++)
x = (x<<1)^bit(x,31)^bit(x,15)^(uint32_t)bit(key,(15-r)&63)^bit(KEELOQ_NLF,g5(x,0,8,19,25,30));
return x;
}
/** Normal Learning
* @param data - serial number (28bit)
* @param key - manufacture (64bit)
* @return manufacture for this serial number (64bit)
*/
inline uint64_t subghz_protocol_keeloq_common_normal_learning(uint32_t data, const uint64_t key){
uint32_t k1,k2;
data&=0x0FFFFFFF;
data|=0x20000000;
k1=subghz_protocol_keeloq_common_decrypt(data, key);
data&=0x0FFFFFFF;
data|=0x60000000;
k2=subghz_protocol_keeloq_common_decrypt(data, key);
return ((uint64_t)k2<<32)| k1; // key - shifrovanoya
}

View File

@@ -1,48 +1,48 @@
#pragma once
#include "subghz_protocol_common.h"
#include "file-worker.h"
#include <furi.h>
/*
* Keeloq
* https://ru.wikipedia.org/wiki/KeeLoq
* https://phreakerclub.com/forum/showthread.php?t=1094
*
*/
#define KEELOQ_NLF 0x3A5C742E
#define bit(x,n) (((x)>>(n))&1)
#define g5(x,a,b,c,d,e) (bit(x,a)+bit(x,b)*2+bit(x,c)*4+bit(x,d)*8+bit(x,e)*16)
/*
* KeeLoq learning types
* https://phreakerclub.com/forum/showthread.php?t=67
*/
#define KEELOQ_LEARNING_UNKNOWN 0u
#define KEELOQ_LEARNING_SIMPLE 1u
#define KEELOQ_LEARNING_NORMAL 2u
#define KEELOQ_LEARNING_SECURE 3u
/** Simple Learning Encrypt
* @param data - 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter
* @param key - manufacture (64bit)
* @return keelog encrypt data
*/
uint32_t subghz_protocol_keeloq_common_encrypt(const uint32_t data, const uint64_t key);
/** Simple Learning Decrypt
* @param data - keelog encrypt data
* @param key - manufacture (64bit)
* @return 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter
*/
uint32_t subghz_protocol_keeloq_common_decrypt(const uint32_t data, const uint64_t key);
/** Normal Learning
* @param data - serial number (28bit)
* @param key - manufacture (64bit)
* @return manufacture for this serial number (64bit)
*/
uint64_t subghz_protocol_keeloq_common_normal_learning(uint32_t data, const uint64_t key);
#pragma once
#include "subghz_protocol_common.h"
#include "file-worker.h"
#include <furi.h>
/*
* Keeloq
* https://ru.wikipedia.org/wiki/KeeLoq
* https://phreakerclub.com/forum/showthread.php?t=1094
*
*/
#define KEELOQ_NLF 0x3A5C742E
#define bit(x,n) (((x)>>(n))&1)
#define g5(x,a,b,c,d,e) (bit(x,a)+bit(x,b)*2+bit(x,c)*4+bit(x,d)*8+bit(x,e)*16)
/*
* KeeLoq learning types
* https://phreakerclub.com/forum/showthread.php?t=67
*/
#define KEELOQ_LEARNING_UNKNOWN 0u
#define KEELOQ_LEARNING_SIMPLE 1u
#define KEELOQ_LEARNING_NORMAL 2u
#define KEELOQ_LEARNING_SECURE 3u
/** Simple Learning Encrypt
* @param data - 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter
* @param key - manufacture (64bit)
* @return keelog encrypt data
*/
uint32_t subghz_protocol_keeloq_common_encrypt(const uint32_t data, const uint64_t key);
/** Simple Learning Decrypt
* @param data - keelog encrypt data
* @param key - manufacture (64bit)
* @return 0xBSSSCCCC, B(4bit) key, S(10bit) serial&0x3FF, C(16bit) counter
*/
uint32_t subghz_protocol_keeloq_common_decrypt(const uint32_t data, const uint64_t key);
/** Normal Learning
* @param data - serial number (28bit)
* @param key - manufacture (64bit)
* @return manufacture for this serial number (64bit)
*/
uint64_t subghz_protocol_keeloq_common_normal_learning(uint32_t data, const uint64_t key);

View File

@@ -1,285 +1,285 @@
#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.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 = 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 =
(SubGhzProtocolCommonLoadFromFile)subghz_protocol_nero_sketch_to_load_protocol_from_file;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoadFromRAW)subghz_decoder_nero_sketch_to_load_protocol;
instance->common.get_upload_protocol =
(SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_nero_sketch_send_key;
return instance;
}
void subghz_protocol_nero_sketch_free(SubGhzProtocolNeroSketch* instance) {
furi_assert(instance);
free(instance);
}
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;
if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false;
//Send header
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(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)) {
//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 {
//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);
}
}
//Send stop bit
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 = NeroSketchDecoderStepReset;
}
/** Analysis of received data
*
* @param instance SubGhzProtocolNeroSketch instance
*/
// void subghz_protocol_nero_sketch_check_remote_controller(SubGhzProtocolNeroSketch* instance) {
// //пока не понятно с серийником, но код статический
// // uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit);
// // uint32_t code_fix = code_found_reverse & 0xFFFFFFFF;
// // //uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFF;
// // instance->common.serial = code_fix & 0xFFFFFFF;
// // instance->common.btn = (code_fix >> 28) & 0x0F;
// //if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
// }
void subghz_protocol_nero_sketch_parse(
SubGhzProtocolNeroSketch* instance,
bool level,
uint32_t duration) {
switch(instance->common.parser_step) {
case 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 = NeroSketchDecoderStepReset;
}
break;
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 = 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) {
// 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 = NeroSketchDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = NeroSketchDecoderStepReset;
}
} else {
instance->common.parser_step = NeroSketchDecoderStepReset;
}
} else {
instance->common.parser_step = NeroSketchDecoderStepReset;
}
break;
case NeroSketchDecoderStepSaveDuration:
if(level) {
if(duration >= (instance->common.te_short * 2 + instance->common.te_delta * 2)) {
//Found stop bit
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);
}
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
break;
} else {
instance->common.te_last = duration;
instance->common.parser_step = NeroSketchDecoderStepCheckDuration;
}
} else {
instance->common.parser_step = NeroSketchDecoderStepReset;
}
break;
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 = 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 = NeroSketchDecoderStepSaveDuration;
} else {
instance->common.parser_step = NeroSketchDecoderStepReset;
}
} else {
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);
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);
}
void subghz_protocol_nero_sketch_to_save_str(SubGhzProtocolNeroSketch* instance, string_t output) {
uint32_t code_found_hi = instance->common.code_last_found >> 32;
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
string_printf(
output,
"Protocol: %s\n"
"Bit: %d\n"
"Key: %08lX%08lX\n",
instance->common.name,
instance->common.code_last_count_bit,
code_found_hi,
code_found_lo);
}
bool subghz_protocol_nero_sketch_to_load_protocol_from_file(
FileWorker* file_worker,
SubGhzProtocolNeroSketch* instance) {
bool loaded = false;
string_t temp_str;
string_init(temp_str);
int res = 0;
int data = 0;
do {
// Read and parse bit data from 2nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
if(res != 1) {
break;
}
instance->common.code_last_count_bit = (uint8_t)data;
// Read and parse key data from 3nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
uint32_t temp_key_hi = 0;
uint32_t temp_key_lo = 0;
res = sscanf(string_get_cstr(temp_str), "Key: %08lX%08lX\n", &temp_key_hi, &temp_key_lo);
if(res != 2) {
break;
}
instance->common.code_last_found = (uint64_t)temp_key_hi << 32 | temp_key_lo;
loaded = true;
} while(0);
string_clear(temp_str);
return loaded;
}
void subghz_decoder_nero_sketch_to_load_protocol(SubGhzProtocolNeroSketch* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;
instance->common.code_last_found = data->code_found;
instance->common.code_last_count_bit = data->code_count_bit;
#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.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 = 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 =
(SubGhzProtocolCommonLoadFromFile)subghz_protocol_nero_sketch_to_load_protocol_from_file;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoadFromRAW)subghz_decoder_nero_sketch_to_load_protocol;
instance->common.get_upload_protocol =
(SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_nero_sketch_send_key;
return instance;
}
void subghz_protocol_nero_sketch_free(SubGhzProtocolNeroSketch* instance) {
furi_assert(instance);
free(instance);
}
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;
if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false;
//Send header
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(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)) {
//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 {
//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);
}
}
//Send stop bit
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 = NeroSketchDecoderStepReset;
}
/** Analysis of received data
*
* @param instance SubGhzProtocolNeroSketch instance
*/
// void subghz_protocol_nero_sketch_check_remote_controller(SubGhzProtocolNeroSketch* instance) {
// //пока не понятно с серийником, но код статический
// // uint64_t code_found_reverse = subghz_protocol_common_reverse_key(instance->common.code_found, instance->common.code_count_bit);
// // uint32_t code_fix = code_found_reverse & 0xFFFFFFFF;
// // //uint32_t code_hop = (code_found_reverse >> 24) & 0xFFFFF;
// // instance->common.serial = code_fix & 0xFFFFFFF;
// // instance->common.btn = (code_fix >> 28) & 0x0F;
// //if (instance->common.callback) instance->common.callback((SubGhzProtocolCommon*)instance, instance->common.context);
// }
void subghz_protocol_nero_sketch_parse(
SubGhzProtocolNeroSketch* instance,
bool level,
uint32_t duration) {
switch(instance->common.parser_step) {
case 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 = NeroSketchDecoderStepReset;
}
break;
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 = 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) {
// 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 = NeroSketchDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = NeroSketchDecoderStepReset;
}
} else {
instance->common.parser_step = NeroSketchDecoderStepReset;
}
} else {
instance->common.parser_step = NeroSketchDecoderStepReset;
}
break;
case NeroSketchDecoderStepSaveDuration:
if(level) {
if(duration >= (instance->common.te_short * 2 + instance->common.te_delta * 2)) {
//Found stop bit
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);
}
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
break;
} else {
instance->common.te_last = duration;
instance->common.parser_step = NeroSketchDecoderStepCheckDuration;
}
} else {
instance->common.parser_step = NeroSketchDecoderStepReset;
}
break;
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 = 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 = NeroSketchDecoderStepSaveDuration;
} else {
instance->common.parser_step = NeroSketchDecoderStepReset;
}
} else {
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);
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);
}
void subghz_protocol_nero_sketch_to_save_str(SubGhzProtocolNeroSketch* instance, string_t output) {
uint32_t code_found_hi = instance->common.code_last_found >> 32;
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
string_printf(
output,
"Protocol: %s\n"
"Bit: %d\n"
"Key: %08lX%08lX\n",
instance->common.name,
instance->common.code_last_count_bit,
code_found_hi,
code_found_lo);
}
bool subghz_protocol_nero_sketch_to_load_protocol_from_file(
FileWorker* file_worker,
SubGhzProtocolNeroSketch* instance) {
bool loaded = false;
string_t temp_str;
string_init(temp_str);
int res = 0;
int data = 0;
do {
// Read and parse bit data from 2nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
if(res != 1) {
break;
}
instance->common.code_last_count_bit = (uint8_t)data;
// Read and parse key data from 3nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
uint32_t temp_key_hi = 0;
uint32_t temp_key_lo = 0;
res = sscanf(string_get_cstr(temp_str), "Key: %08lX%08lX\n", &temp_key_hi, &temp_key_lo);
if(res != 2) {
break;
}
instance->common.code_last_found = (uint64_t)temp_key_hi << 32 | temp_key_lo;
loaded = true;
} while(0);
string_clear(temp_str);
return loaded;
}
void subghz_decoder_nero_sketch_to_load_protocol(SubGhzProtocolNeroSketch* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;
instance->common.code_last_found = data->code_found;
instance->common.code_last_count_bit = data->code_count_bit;
}

View File

@@ -1,72 +1,72 @@
#pragma once
#include "subghz_protocol_common.h"
typedef struct SubGhzProtocolNeroSketch SubGhzProtocolNeroSketch;
/** Allocate SubGhzProtocolNeroSketch
*
* @return SubGhzProtocolNeroSketch*
*/
SubGhzProtocolNeroSketch* subghz_protocol_nero_sketch_alloc();
/** Free SubGhzProtocolNeroSketch
*
* @param instance
*/
void subghz_protocol_nero_sketch_free(SubGhzProtocolNeroSketch* instance);
/** Get upload protocol
*
* @param instance - SubGhzProtocolNeroSketch instance
* @param encoder - SubGhzProtocolCommonEncoder encoder
* @return bool
*/
bool subghz_protocol_nero_sketch_send_key(SubGhzProtocolNeroSketch* instance, SubGhzProtocolCommonEncoder* encoder);
/** Reset internal state
* @param instance - SubGhzProtocolNeroSketch instance
*/
void subghz_protocol_nero_sketch_reset(SubGhzProtocolNeroSketch* instance);
/** Analysis of received data
*
* @param instance SubGhzProtocolNeroSketch instance
*/
void subghz_protocol_nero_sketch_check_remote_controller(SubGhzProtocolNeroSketch* instance);
/** Parse accepted duration
*
* @param instance - SubGhzProtocolNeroSketch instance
* @param data - LevelDuration level_duration
*/
void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool level, uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzProtocolNeroSketch* instance
* @param output - output string
*/
void subghz_protocol_nero_sketch_to_str(SubGhzProtocolNeroSketch* instance, string_t output);
/** Get a string to save the protocol
*
* @param instance - SubGhzProtocolNeroSketch instance
* @param output - the resulting string
*/
void subghz_protocol_nero_sketch_to_save_str(SubGhzProtocolNeroSketch* instance, string_t output);
/** Loading protocol from file
*
* @param file_worker - FileWorker file_worker
* @param instance - SubGhzProtocolNeroSketch instance
* @return bool
*/
bool subghz_protocol_nero_sketch_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolNeroSketch* instance);
/** Loading protocol from bin data
*
* @param instance - SubGhzProtocolNeroSketch instance
* @param context - SubGhzProtocolCommonLoad context
*/
#pragma once
#include "subghz_protocol_common.h"
typedef struct SubGhzProtocolNeroSketch SubGhzProtocolNeroSketch;
/** Allocate SubGhzProtocolNeroSketch
*
* @return SubGhzProtocolNeroSketch*
*/
SubGhzProtocolNeroSketch* subghz_protocol_nero_sketch_alloc();
/** Free SubGhzProtocolNeroSketch
*
* @param instance
*/
void subghz_protocol_nero_sketch_free(SubGhzProtocolNeroSketch* instance);
/** Get upload protocol
*
* @param instance - SubGhzProtocolNeroSketch instance
* @param encoder - SubGhzProtocolCommonEncoder encoder
* @return bool
*/
bool subghz_protocol_nero_sketch_send_key(SubGhzProtocolNeroSketch* instance, SubGhzProtocolCommonEncoder* encoder);
/** Reset internal state
* @param instance - SubGhzProtocolNeroSketch instance
*/
void subghz_protocol_nero_sketch_reset(SubGhzProtocolNeroSketch* instance);
/** Analysis of received data
*
* @param instance SubGhzProtocolNeroSketch instance
*/
void subghz_protocol_nero_sketch_check_remote_controller(SubGhzProtocolNeroSketch* instance);
/** Parse accepted duration
*
* @param instance - SubGhzProtocolNeroSketch instance
* @param data - LevelDuration level_duration
*/
void subghz_protocol_nero_sketch_parse(SubGhzProtocolNeroSketch* instance, bool level, uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzProtocolNeroSketch* instance
* @param output - output string
*/
void subghz_protocol_nero_sketch_to_str(SubGhzProtocolNeroSketch* instance, string_t output);
/** Get a string to save the protocol
*
* @param instance - SubGhzProtocolNeroSketch instance
* @param output - the resulting string
*/
void subghz_protocol_nero_sketch_to_save_str(SubGhzProtocolNeroSketch* instance, string_t output);
/** Loading protocol from file
*
* @param file_worker - FileWorker file_worker
* @param instance - SubGhzProtocolNeroSketch instance
* @return bool
*/
bool subghz_protocol_nero_sketch_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolNeroSketch* instance);
/** Loading protocol from bin data
*
* @param instance - SubGhzProtocolNeroSketch instance
* @param context - SubGhzProtocolCommonLoad context
*/
void subghz_decoder_nero_sketch_to_load_protocol(SubGhzProtocolNeroSketch* instance, void* context);

View File

@@ -1,227 +1,227 @@
#include "subghz_protocol_nice_flo.h"
/*
* Help
* https://phreakerclub.com/447
*
*/
struct SubGhzProtocolNiceFlo {
SubGhzProtocolCommon common;
};
typedef enum {
NiceFloDecoderStepReset = 0,
NiceFloDecoderStepFoundStartBit,
NiceFloDecoderStepSaveDuration,
NiceFloDecoderStepCheckDuration,
} NiceFloDecoderStep;
SubGhzProtocolNiceFlo* subghz_protocol_nice_flo_alloc() {
SubGhzProtocolNiceFlo* instance = furi_alloc(sizeof(SubGhzProtocolNiceFlo));
instance->common.name = "Nice FLO";
instance->common.code_min_count_bit_for_found = 12;
instance->common.te_short = 700;
instance->common.te_long = 1400;
instance->common.te_delta = 200;
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 =
(SubGhzProtocolCommonLoadFromFile)subghz_protocol_nice_flo_to_load_protocol_from_file;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoadFromRAW)subghz_decoder_nice_flo_to_load_protocol;
instance->common.get_upload_protocol =
(SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_nice_flo_send_key;
return instance;
}
void subghz_protocol_nice_flo_free(SubGhzProtocolNiceFlo* instance) {
furi_assert(instance);
free(instance);
}
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;
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);
//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)) {
//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 {
//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);
}
}
return true;
}
void subghz_protocol_nice_flo_reset(SubGhzProtocolNiceFlo* instance) {
instance->common.parser_step = NiceFloDecoderStepReset;
}
void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, bool level, uint32_t duration) {
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 = NiceFloDecoderStepFoundStartBit;
} else {
instance->common.parser_step = NiceFloDecoderStepReset;
}
break;
case NiceFloDecoderStepFoundStartBit:
if(!level) {
break;
} else if(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) {
//Found start bit Nice Flo
instance->common.parser_step = NiceFloDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = NiceFloDecoderStepReset;
}
break;
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);
}
break;
}
instance->common.te_last = duration;
instance->common.parser_step = NiceFloDecoderStepCheckDuration;
} else {
instance->common.parser_step = NiceFloDecoderStepReset;
}
break;
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 = 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 = NiceFloDecoderStepSaveDuration;
} else
instance->common.parser_step = NiceFloDecoderStepReset;
} else {
instance->common.parser_step = NiceFloDecoderStepReset;
}
break;
}
}
void subghz_protocol_nice_flo_to_str(SubGhzProtocolNiceFlo* instance, string_t output) {
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(
instance->common.code_last_found, instance->common.code_last_count_bit);
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
string_cat_printf(
output,
"%s %dbit\r\n"
"Key:0x%08lX\r\n"
"Yek:0x%08lX\r\n",
instance->common.name,
instance->common.code_last_count_bit,
code_found_lo,
code_found_reverse_lo);
}
void subghz_protocol_nice_flo_to_save_str(SubGhzProtocolNiceFlo* instance, string_t output) {
string_printf(
output,
"Protocol: %s\n"
"Bit: %d\n"
"Key: %08lX\n",
instance->common.name,
instance->common.code_last_count_bit,
(uint32_t)(instance->common.code_last_found & 0x00000000ffffffff));
}
bool subghz_protocol_nice_flo_to_load_protocol_from_file(
FileWorker* file_worker,
SubGhzProtocolNiceFlo* instance) {
bool loaded = false;
string_t temp_str;
string_init(temp_str);
int res = 0;
int data = 0;
do {
// Read and parse bit data from 2nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
if(res != 1) {
break;
}
instance->common.code_last_count_bit = (uint8_t)data;
// Read and parse key data from 3nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
uint32_t temp_key = 0;
res = sscanf(string_get_cstr(temp_str), "Key: %08lX\n", &temp_key);
if(res != 1) {
break;
}
instance->common.code_last_found = (uint64_t)temp_key;
loaded = true;
} while(0);
string_clear(temp_str);
return loaded;
}
void subghz_decoder_nice_flo_to_load_protocol(SubGhzProtocolNiceFlo* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;
instance->common.code_last_found = data->code_found;
instance->common.code_last_count_bit = data->code_count_bit;
instance->common.serial = 0x0;
instance->common.btn = 0x0;
#include "subghz_protocol_nice_flo.h"
/*
* Help
* https://phreakerclub.com/447
*
*/
struct SubGhzProtocolNiceFlo {
SubGhzProtocolCommon common;
};
typedef enum {
NiceFloDecoderStepReset = 0,
NiceFloDecoderStepFoundStartBit,
NiceFloDecoderStepSaveDuration,
NiceFloDecoderStepCheckDuration,
} NiceFloDecoderStep;
SubGhzProtocolNiceFlo* subghz_protocol_nice_flo_alloc() {
SubGhzProtocolNiceFlo* instance = furi_alloc(sizeof(SubGhzProtocolNiceFlo));
instance->common.name = "Nice FLO";
instance->common.code_min_count_bit_for_found = 12;
instance->common.te_short = 700;
instance->common.te_long = 1400;
instance->common.te_delta = 200;
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 =
(SubGhzProtocolCommonLoadFromFile)subghz_protocol_nice_flo_to_load_protocol_from_file;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoadFromRAW)subghz_decoder_nice_flo_to_load_protocol;
instance->common.get_upload_protocol =
(SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_nice_flo_send_key;
return instance;
}
void subghz_protocol_nice_flo_free(SubGhzProtocolNiceFlo* instance) {
furi_assert(instance);
free(instance);
}
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;
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);
//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)) {
//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 {
//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);
}
}
return true;
}
void subghz_protocol_nice_flo_reset(SubGhzProtocolNiceFlo* instance) {
instance->common.parser_step = NiceFloDecoderStepReset;
}
void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, bool level, uint32_t duration) {
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 = NiceFloDecoderStepFoundStartBit;
} else {
instance->common.parser_step = NiceFloDecoderStepReset;
}
break;
case NiceFloDecoderStepFoundStartBit:
if(!level) {
break;
} else if(DURATION_DIFF(duration, instance->common.te_short) < instance->common.te_delta) {
//Found start bit Nice Flo
instance->common.parser_step = NiceFloDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = NiceFloDecoderStepReset;
}
break;
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);
}
break;
}
instance->common.te_last = duration;
instance->common.parser_step = NiceFloDecoderStepCheckDuration;
} else {
instance->common.parser_step = NiceFloDecoderStepReset;
}
break;
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 = 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 = NiceFloDecoderStepSaveDuration;
} else
instance->common.parser_step = NiceFloDecoderStepReset;
} else {
instance->common.parser_step = NiceFloDecoderStepReset;
}
break;
}
}
void subghz_protocol_nice_flo_to_str(SubGhzProtocolNiceFlo* instance, string_t output) {
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(
instance->common.code_last_found, instance->common.code_last_count_bit);
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
string_cat_printf(
output,
"%s %dbit\r\n"
"Key:0x%08lX\r\n"
"Yek:0x%08lX\r\n",
instance->common.name,
instance->common.code_last_count_bit,
code_found_lo,
code_found_reverse_lo);
}
void subghz_protocol_nice_flo_to_save_str(SubGhzProtocolNiceFlo* instance, string_t output) {
string_printf(
output,
"Protocol: %s\n"
"Bit: %d\n"
"Key: %08lX\n",
instance->common.name,
instance->common.code_last_count_bit,
(uint32_t)(instance->common.code_last_found & 0x00000000ffffffff));
}
bool subghz_protocol_nice_flo_to_load_protocol_from_file(
FileWorker* file_worker,
SubGhzProtocolNiceFlo* instance) {
bool loaded = false;
string_t temp_str;
string_init(temp_str);
int res = 0;
int data = 0;
do {
// Read and parse bit data from 2nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
if(res != 1) {
break;
}
instance->common.code_last_count_bit = (uint8_t)data;
// Read and parse key data from 3nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
uint32_t temp_key = 0;
res = sscanf(string_get_cstr(temp_str), "Key: %08lX\n", &temp_key);
if(res != 1) {
break;
}
instance->common.code_last_found = (uint64_t)temp_key;
loaded = true;
} while(0);
string_clear(temp_str);
return loaded;
}
void subghz_decoder_nice_flo_to_load_protocol(SubGhzProtocolNiceFlo* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;
instance->common.code_last_found = data->code_found;
instance->common.code_last_count_bit = data->code_count_bit;
instance->common.serial = 0x0;
instance->common.btn = 0x0;
}

View File

@@ -1,66 +1,66 @@
#pragma once
#include "subghz_protocol_common.h"
typedef struct SubGhzProtocolNiceFlo SubGhzProtocolNiceFlo;
/** Allocate SubGhzProtocolNiceFlo
*
* @return SubGhzProtocolNiceFlo*
*/
SubGhzProtocolNiceFlo* subghz_protocol_nice_flo_alloc();
/** Free SubGhzProtocolNiceFlo
*
* @param instance
*/
void subghz_protocol_nice_flo_free(SubGhzProtocolNiceFlo* instance);
/** Get upload protocol
*
* @param instance - SubGhzProtocolNiceFlo instance
* @param encoder - SubGhzProtocolCommonEncoder encoder
* @return bool
*/
bool subghz_protocol_nice_flo_send_key(SubGhzProtocolNiceFlo* instance, SubGhzProtocolCommonEncoder* encoder);
/** Reset internal state
* @param instance - SubGhzProtocolNiceFlo instance
*/
void subghz_protocol_nice_flo_reset(SubGhzProtocolNiceFlo* instance);
/** Parse accepted duration
*
* @param instance - SubGhzProtocolNiceFlo instance
* @param data - LevelDuration level_duration
*/
void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, bool level, uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzProtocolNiceFlo* instance
* @param output - output string
*/
void subghz_protocol_nice_flo_to_str(SubGhzProtocolNiceFlo* instance, string_t output);
/** Get a string to save the protocol
*
* @param instance - SubGhzProtocolNiceFlo instance
* @param output - the resulting string
*/
void subghz_protocol_nice_flo_to_save_str(SubGhzProtocolNiceFlo* instance, string_t output);
/** Loading protocol from file
*
* @param file_worker - FileWorker file_worker
* @param instance - SubGhzProtocolNiceFlo instance
* @return bool
*/
bool subghz_protocol_nice_flo_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolNiceFlo* instance);
/** Loading protocol from bin data
*
* @param instance - SubGhzProtocolNiceFlo instance
* @param context - SubGhzProtocolCommonLoad context
*/
void subghz_decoder_nice_flo_to_load_protocol(SubGhzProtocolNiceFlo* instance, void* context);
#pragma once
#include "subghz_protocol_common.h"
typedef struct SubGhzProtocolNiceFlo SubGhzProtocolNiceFlo;
/** Allocate SubGhzProtocolNiceFlo
*
* @return SubGhzProtocolNiceFlo*
*/
SubGhzProtocolNiceFlo* subghz_protocol_nice_flo_alloc();
/** Free SubGhzProtocolNiceFlo
*
* @param instance
*/
void subghz_protocol_nice_flo_free(SubGhzProtocolNiceFlo* instance);
/** Get upload protocol
*
* @param instance - SubGhzProtocolNiceFlo instance
* @param encoder - SubGhzProtocolCommonEncoder encoder
* @return bool
*/
bool subghz_protocol_nice_flo_send_key(SubGhzProtocolNiceFlo* instance, SubGhzProtocolCommonEncoder* encoder);
/** Reset internal state
* @param instance - SubGhzProtocolNiceFlo instance
*/
void subghz_protocol_nice_flo_reset(SubGhzProtocolNiceFlo* instance);
/** Parse accepted duration
*
* @param instance - SubGhzProtocolNiceFlo instance
* @param data - LevelDuration level_duration
*/
void subghz_protocol_nice_flo_parse(SubGhzProtocolNiceFlo* instance, bool level, uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzProtocolNiceFlo* instance
* @param output - output string
*/
void subghz_protocol_nice_flo_to_str(SubGhzProtocolNiceFlo* instance, string_t output);
/** Get a string to save the protocol
*
* @param instance - SubGhzProtocolNiceFlo instance
* @param output - the resulting string
*/
void subghz_protocol_nice_flo_to_save_str(SubGhzProtocolNiceFlo* instance, string_t output);
/** Loading protocol from file
*
* @param file_worker - FileWorker file_worker
* @param instance - SubGhzProtocolNiceFlo instance
* @return bool
*/
bool subghz_protocol_nice_flo_to_load_protocol_from_file(FileWorker* file_worker, SubGhzProtocolNiceFlo* instance);
/** Loading protocol from bin data
*
* @param instance - SubGhzProtocolNiceFlo instance
* @param context - SubGhzProtocolCommonLoad context
*/
void subghz_decoder_nice_flo_to_load_protocol(SubGhzProtocolNiceFlo* instance, void* context);

View File

@@ -1,267 +1,267 @@
#include "subghz_protocol_nice_flor_s.h"
#include <furi.h>
#include "file-worker.h"
/*
* https://phreakerclub.com/1615
* https://phreakerclub.com/forum/showthread.php?t=2360
* https://vrtp.ru/index.php?showtopic=27867
*/
struct SubGhzProtocolNiceFlorS {
SubGhzProtocolCommon common;
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));
instance->common.name = "Nice FloR-S";
instance->common.code_min_count_bit_for_found = 52;
instance->common.te_short = 500;
instance->common.te_long = 1000;
instance->common.te_delta = 300;
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;
return instance;
}
void subghz_protocol_nice_flor_s_free(SubGhzProtocolNiceFlorS* instance) {
furi_assert(instance);
free(instance);
}
void subghz_protocol_nice_flor_s_name_file(SubGhzProtocolNiceFlorS* instance, const char* name) {
instance->rainbow_table_file_name = name;
printf("Loading Nice FloR S rainbow table %s\r\n", name);
}
/** Send bit
*
* @param instance - SubGhzProtocolNiceFlorS instance
* @param bit - bit
*/
void subghz_protocol_nice_flor_s_send_bit(SubGhzProtocolNiceFlorS* instance, uint8_t bit) {
if(bit) {
//send bit 1
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_long);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_short);
} else {
//send bit 0
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_short);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_long);
}
}
void subghz_protocol_nice_flor_s_send_key(
SubGhzProtocolNiceFlorS* instance,
uint64_t key,
uint8_t bit,
uint8_t repeat) {
while(repeat--) {
//Send header
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_short * 34);
//Send Start Bit
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_short * 3);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_short * 3);
//Send key data
for(uint8_t i = bit; i > 0; i--) {
subghz_protocol_nice_flor_s_send_bit(instance, bit_read(key, i - 1));
}
//Send Stop Bit
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_short * 3);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_short * 3);
}
}
/** Read bytes from rainbow table
*
* @param instance - SubGhzProtocolNiceFlorS* instance
* @param address - address byte
* @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;
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)) {
file_worker_seek(file_worker, address, true);
file_worker_read(file_worker, &buffer, 1);
}
file_worker_close(file_worker);
file_worker_free(file_worker);
return buffer;
}
/** Decrypt protocol Nice Flor S
*
* @param instance - SubGhzProtocolNiceFlorS* instance
*/
void subghz_nice_flor_s_decoder_decrypt(SubGhzProtocolNiceFlorS* instance) {
/*
* Packet format Nice Flor-s: START-P0-P1-P2-P3-P4-P5-P6-P7-STOP
* P0 (4-bit) - button positional code - 1:0x1, 2:0x2, 3:0x4, 4:0x8;
* P1 (4-bit) - batch repetition number, calculated by the formula:
* P1 = 0xF ^ P0 ^ n; where n changes from 1 to 15, then 0, and then in a circle
* key 1: {0xF,0xC,0xD,0xA,0xB,0x8,0x9,0x6,0x7,0x4,0x5,0x2,0x3,0x0,0x1,0xE};
* key 2: {0xC,0xF,0xE,0x9,0x8,0xB,0xA,0x5,0x4,0x7,0x6,0x1,0x0,0x3,0x2,0xD};
* key 3: {0xA,0x9,0x8,0xF,0xE,0xD,0xC,0x3,0x2,0x1,0x0,0x7,0x6,0x5,0x4,0xB};
* P2 (4-bit) - part of the serial number, P2 = (K ^ S3) & 0xF;
* P3 (byte) - the major part of the encrypted index
* P4 (byte) - the low-order part of the encrypted index
* P5 (byte) - part of the serial number, P5 = K ^ S2;
* P6 (byte) - part of the serial number, P6 = K ^ S1;
* P7 (byte) - part of the serial number, P7 = K ^ S0;
* K (byte) - depends on P3 and P4, K = Fk(P3, P4);
* S3,S2,S1,S0 - serial number of the console 28 bit.
*/
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)));
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);
uint8_t s1 = ((uint8_t)(instance->common.code_last_found >> 8) ^ k);
uint8_t s0 = ((uint8_t)(instance->common.code_last_found) ^ k);
instance->common.serial = s3 << 24 | s2 << 16 | s1 << 8 | s0;
instance->common.btn = (instance->common.code_last_found >> 48) & 0x0f;
}
void subghz_protocol_nice_flor_s_reset(SubGhzProtocolNiceFlorS* instance) {
instance->common.parser_step = NiceFlorSDecoderStepReset;
}
void subghz_protocol_nice_flor_s_parse(
SubGhzProtocolNiceFlorS* instance,
bool level,
uint32_t duration) {
switch(instance->common.parser_step) {
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 = NiceFlorSDecoderStepCheckHeader;
} else {
instance->common.parser_step = NiceFlorSDecoderStepReset;
}
break;
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 = NiceFlorSDecoderStepFoundHeader;
} else {
instance->common.parser_step = NiceFlorSDecoderStepReset;
}
break;
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 = NiceFlorSDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = NiceFlorSDecoderStepReset;
}
break;
case NiceFlorSDecoderStepSaveDuration:
if(level) {
if(DURATION_DIFF(duration, instance->common.te_short * 3) <
instance->common.te_delta) {
//Found STOP bit
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);
}
break;
} else {
//save interval
instance->common.te_last = duration;
instance->common.parser_step = NiceFlorSDecoderStepCheckDuration;
}
}
break;
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)) {
subghz_protocol_common_add_bit(&instance->common, 0);
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)) {
subghz_protocol_common_add_bit(&instance->common, 1);
instance->common.parser_step = NiceFlorSDecoderStepSaveDuration;
} else
instance->common.parser_step = NiceFlorSDecoderStepReset;
} else {
instance->common.parser_step = NiceFlorSDecoderStepReset;
}
break;
}
}
void subghz_protocol_nice_flor_s_to_str(SubGhzProtocolNiceFlorS* instance, string_t output) {
subghz_nice_flor_s_decoder_decrypt(instance);
uint32_t code_found_hi = instance->common.code_last_found >> 32;
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
string_cat_printf(
output,
"%s %dbit\r\n"
"Key:0x%lX%08lX\r\n"
"Sn:%05lX\r\n"
"Cnt:%04X Btn:%02lX\r\n",
instance->common.name,
instance->common.code_last_count_bit,
code_found_hi,
code_found_lo,
instance->common.serial,
instance->common.cnt,
instance->common.btn);
}
void subghz_decoder_nice_flor_s_to_load_protocol(SubGhzProtocolNiceFlorS* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;
instance->common.code_last_found = data->code_found;
instance->common.code_last_count_bit = data->code_count_bit;
subghz_nice_flor_s_decoder_decrypt(instance);
#include "subghz_protocol_nice_flor_s.h"
#include <furi.h>
#include "file-worker.h"
/*
* https://phreakerclub.com/1615
* https://phreakerclub.com/forum/showthread.php?t=2360
* https://vrtp.ru/index.php?showtopic=27867
*/
struct SubGhzProtocolNiceFlorS {
SubGhzProtocolCommon common;
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));
instance->common.name = "Nice FloR-S";
instance->common.code_min_count_bit_for_found = 52;
instance->common.te_short = 500;
instance->common.te_long = 1000;
instance->common.te_delta = 300;
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;
return instance;
}
void subghz_protocol_nice_flor_s_free(SubGhzProtocolNiceFlorS* instance) {
furi_assert(instance);
free(instance);
}
void subghz_protocol_nice_flor_s_name_file(SubGhzProtocolNiceFlorS* instance, const char* name) {
instance->rainbow_table_file_name = name;
printf("Loading Nice FloR S rainbow table %s\r\n", name);
}
/** Send bit
*
* @param instance - SubGhzProtocolNiceFlorS instance
* @param bit - bit
*/
void subghz_protocol_nice_flor_s_send_bit(SubGhzProtocolNiceFlorS* instance, uint8_t bit) {
if(bit) {
//send bit 1
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_long);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_short);
} else {
//send bit 0
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_short);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_long);
}
}
void subghz_protocol_nice_flor_s_send_key(
SubGhzProtocolNiceFlorS* instance,
uint64_t key,
uint8_t bit,
uint8_t repeat) {
while(repeat--) {
//Send header
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_short * 34);
//Send Start Bit
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_short * 3);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_short * 3);
//Send key data
for(uint8_t i = bit; i > 0; i--) {
subghz_protocol_nice_flor_s_send_bit(instance, bit_read(key, i - 1));
}
//Send Stop Bit
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_short * 3);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_short * 3);
}
}
/** Read bytes from rainbow table
*
* @param instance - SubGhzProtocolNiceFlorS* instance
* @param address - address byte
* @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;
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)) {
file_worker_seek(file_worker, address, true);
file_worker_read(file_worker, &buffer, 1);
}
file_worker_close(file_worker);
file_worker_free(file_worker);
return buffer;
}
/** Decrypt protocol Nice Flor S
*
* @param instance - SubGhzProtocolNiceFlorS* instance
*/
void subghz_nice_flor_s_decoder_decrypt(SubGhzProtocolNiceFlorS* instance) {
/*
* Packet format Nice Flor-s: START-P0-P1-P2-P3-P4-P5-P6-P7-STOP
* P0 (4-bit) - button positional code - 1:0x1, 2:0x2, 3:0x4, 4:0x8;
* P1 (4-bit) - batch repetition number, calculated by the formula:
* P1 = 0xF ^ P0 ^ n; where n changes from 1 to 15, then 0, and then in a circle
* key 1: {0xF,0xC,0xD,0xA,0xB,0x8,0x9,0x6,0x7,0x4,0x5,0x2,0x3,0x0,0x1,0xE};
* key 2: {0xC,0xF,0xE,0x9,0x8,0xB,0xA,0x5,0x4,0x7,0x6,0x1,0x0,0x3,0x2,0xD};
* key 3: {0xA,0x9,0x8,0xF,0xE,0xD,0xC,0x3,0x2,0x1,0x0,0x7,0x6,0x5,0x4,0xB};
* P2 (4-bit) - part of the serial number, P2 = (K ^ S3) & 0xF;
* P3 (byte) - the major part of the encrypted index
* P4 (byte) - the low-order part of the encrypted index
* P5 (byte) - part of the serial number, P5 = K ^ S2;
* P6 (byte) - part of the serial number, P6 = K ^ S1;
* P7 (byte) - part of the serial number, P7 = K ^ S0;
* K (byte) - depends on P3 and P4, K = Fk(P3, P4);
* S3,S2,S1,S0 - serial number of the console 28 bit.
*/
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)));
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);
uint8_t s1 = ((uint8_t)(instance->common.code_last_found >> 8) ^ k);
uint8_t s0 = ((uint8_t)(instance->common.code_last_found) ^ k);
instance->common.serial = s3 << 24 | s2 << 16 | s1 << 8 | s0;
instance->common.btn = (instance->common.code_last_found >> 48) & 0x0f;
}
void subghz_protocol_nice_flor_s_reset(SubGhzProtocolNiceFlorS* instance) {
instance->common.parser_step = NiceFlorSDecoderStepReset;
}
void subghz_protocol_nice_flor_s_parse(
SubGhzProtocolNiceFlorS* instance,
bool level,
uint32_t duration) {
switch(instance->common.parser_step) {
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 = NiceFlorSDecoderStepCheckHeader;
} else {
instance->common.parser_step = NiceFlorSDecoderStepReset;
}
break;
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 = NiceFlorSDecoderStepFoundHeader;
} else {
instance->common.parser_step = NiceFlorSDecoderStepReset;
}
break;
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 = NiceFlorSDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
} else {
instance->common.parser_step = NiceFlorSDecoderStepReset;
}
break;
case NiceFlorSDecoderStepSaveDuration:
if(level) {
if(DURATION_DIFF(duration, instance->common.te_short * 3) <
instance->common.te_delta) {
//Found STOP bit
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);
}
break;
} else {
//save interval
instance->common.te_last = duration;
instance->common.parser_step = NiceFlorSDecoderStepCheckDuration;
}
}
break;
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)) {
subghz_protocol_common_add_bit(&instance->common, 0);
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)) {
subghz_protocol_common_add_bit(&instance->common, 1);
instance->common.parser_step = NiceFlorSDecoderStepSaveDuration;
} else
instance->common.parser_step = NiceFlorSDecoderStepReset;
} else {
instance->common.parser_step = NiceFlorSDecoderStepReset;
}
break;
}
}
void subghz_protocol_nice_flor_s_to_str(SubGhzProtocolNiceFlorS* instance, string_t output) {
subghz_nice_flor_s_decoder_decrypt(instance);
uint32_t code_found_hi = instance->common.code_last_found >> 32;
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
string_cat_printf(
output,
"%s %dbit\r\n"
"Key:0x%lX%08lX\r\n"
"Sn:%05lX\r\n"
"Cnt:%04X Btn:%02lX\r\n",
instance->common.name,
instance->common.code_last_count_bit,
code_found_hi,
code_found_lo,
instance->common.serial,
instance->common.cnt,
instance->common.btn);
}
void subghz_decoder_nice_flor_s_to_load_protocol(SubGhzProtocolNiceFlorS* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;
instance->common.code_last_found = data->code_found;
instance->common.code_last_count_bit = data->code_count_bit;
subghz_nice_flor_s_decoder_decrypt(instance);
}

View File

@@ -1,59 +1,59 @@
#pragma once
#include "subghz_protocol_common.h"
typedef struct SubGhzProtocolNiceFlorS SubGhzProtocolNiceFlorS;
/** Allocate SubGhzProtocolNiceFlorS
*
* @return SubGhzProtocolNiceFlorS*
*/
SubGhzProtocolNiceFlorS* subghz_protocol_nice_flor_s_alloc();
/** Free SubGhzProtocolNiceFlorS
*
* @param instance
*/
void subghz_protocol_nice_flor_s_free(SubGhzProtocolNiceFlorS* instance);
/** File name rainbow table Nice Flor-S
*
* @param instance - SubGhzProtocolNiceFlorS instance
* @param file_name - "path/file_name"
*/
void subghz_protocol_nice_flor_s_name_file(SubGhzProtocolNiceFlorS* instance, const char* name);
/** Sends the key on the air
*
* @param instance - SubGhzProtocolNiceFlorS instance
* @param key - key send
* @param bit - count bit key
* @param repeat - repeat send key
*/
void subghz_protocol_nice_flor_s_send_key(SubGhzProtocolNiceFlorS* instance, uint64_t key, uint8_t bit, uint8_t repeat);
/** Reset internal state
* @param instance - SubGhzProtocolNiceFlorS instance
*/
void subghz_protocol_nice_flor_s_reset(SubGhzProtocolNiceFlorS* instance);
/** Parse accepted duration
*
* @param instance - SubGhzProtocolNiceFlorS instance
* @param data - LevelDuration level_duration
*/
void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, bool level, uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzProtocolNiceFlorS* instance
* @param output - output string
*/
void subghz_protocol_nice_flor_s_to_str(SubGhzProtocolNiceFlorS* instance, string_t output);
/** Loading protocol from bin data
*
* @param instance - SubGhzProtocolNiceFlorS instance
* @param context - SubGhzProtocolCommonLoad context
*/
#pragma once
#include "subghz_protocol_common.h"
typedef struct SubGhzProtocolNiceFlorS SubGhzProtocolNiceFlorS;
/** Allocate SubGhzProtocolNiceFlorS
*
* @return SubGhzProtocolNiceFlorS*
*/
SubGhzProtocolNiceFlorS* subghz_protocol_nice_flor_s_alloc();
/** Free SubGhzProtocolNiceFlorS
*
* @param instance
*/
void subghz_protocol_nice_flor_s_free(SubGhzProtocolNiceFlorS* instance);
/** File name rainbow table Nice Flor-S
*
* @param instance - SubGhzProtocolNiceFlorS instance
* @param file_name - "path/file_name"
*/
void subghz_protocol_nice_flor_s_name_file(SubGhzProtocolNiceFlorS* instance, const char* name);
/** Sends the key on the air
*
* @param instance - SubGhzProtocolNiceFlorS instance
* @param key - key send
* @param bit - count bit key
* @param repeat - repeat send key
*/
void subghz_protocol_nice_flor_s_send_key(SubGhzProtocolNiceFlorS* instance, uint64_t key, uint8_t bit, uint8_t repeat);
/** Reset internal state
* @param instance - SubGhzProtocolNiceFlorS instance
*/
void subghz_protocol_nice_flor_s_reset(SubGhzProtocolNiceFlorS* instance);
/** Parse accepted duration
*
* @param instance - SubGhzProtocolNiceFlorS instance
* @param data - LevelDuration level_duration
*/
void subghz_protocol_nice_flor_s_parse(SubGhzProtocolNiceFlorS* instance, bool level, uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzProtocolNiceFlorS* instance
* @param output - output string
*/
void subghz_protocol_nice_flor_s_to_str(SubGhzProtocolNiceFlorS* instance, string_t output);
/** Loading protocol from bin data
*
* @param instance - SubGhzProtocolNiceFlorS instance
* @param context - SubGhzProtocolCommonLoad context
*/
void subghz_decoder_nice_flor_s_to_load_protocol(SubGhzProtocolNiceFlorS* instance, void* context);

View File

@@ -1,369 +1,369 @@
#include "subghz_protocol_princeton.h"
/*
* Help
* https://phreakerclub.com/447
*
*/
#define SUBGHZ_PT_SHORT 400
#define SUBGHZ_PT_LONG (SUBGHZ_PT_SHORT * 3)
#define SUBGHZ_PT_GUARD (SUBGHZ_PT_SHORT * 30)
#define SUBGHZ_PT_COUNT_KEY 5
#define SUBGHZ_PT_TIMEOUT 320
struct SubGhzEncoderPrinceton {
uint32_t key;
uint16_t te;
size_t repeat;
size_t front;
size_t count_key;
uint32_t time_high;
uint32_t time_low;
};
typedef enum {
PrincetonDecoderStepReset = 0,
PrincetonDecoderStepSaveDuration,
PrincetonDecoderStepCheckDuration,
} PrincetonDecoderStep;
SubGhzEncoderPrinceton* subghz_encoder_princeton_alloc() {
SubGhzEncoderPrinceton* instance = furi_alloc(sizeof(SubGhzEncoderPrinceton));
return instance;
}
void subghz_encoder_princeton_free(SubGhzEncoderPrinceton* instance) {
furi_assert(instance);
free(instance);
}
void subghz_encoder_princeton_set_te(SubGhzEncoderPrinceton* instance, void* decoder) {
SubGhzDecoderPrinceton* pricenton = decoder;
if((pricenton->te) != 0) {
instance->te = pricenton->te;
} else {
instance->te = SUBGHZ_PT_SHORT;
}
}
void subghz_encoder_princeton_set(SubGhzEncoderPrinceton* instance, uint32_t key, size_t repeat) {
furi_assert(instance);
instance->te = SUBGHZ_PT_SHORT;
instance->key = key;
instance->repeat = repeat + 1;
instance->front = 48;
instance->count_key = SUBGHZ_PT_COUNT_KEY + 7;
instance->time_high = 0;
instance->time_low = 0;
}
size_t subghz_encoder_princeton_get_repeat_left(SubGhzEncoderPrinceton* instance) {
furi_assert(instance);
return instance->repeat;
}
void subghz_encoder_princeton_print_log(void* context) {
SubGhzEncoderPrinceton* instance = context;
float duty_cycle =
((float)instance->time_high / (instance->time_high + instance->time_low)) * 100;
FURI_LOG_I(
"EncoderPrinceton",
"Radio ON=%dus, OFF=%dus, DutyCycle=%d,%d%%",
instance->time_high,
instance->time_low,
(uint32_t)duty_cycle,
(uint32_t)((duty_cycle - (uint32_t)duty_cycle) * 100));
}
LevelDuration subghz_encoder_princeton_yield(void* context) {
SubGhzEncoderPrinceton* instance = context;
if(instance->repeat == 0) {
subghz_encoder_princeton_print_log(instance);
return level_duration_reset();
}
size_t bit = instance->front / 2;
bool level = !(instance->front % 2);
LevelDuration ret;
if(bit < 24) {
uint8_t byte = bit / 8;
uint8_t bit_in_byte = bit % 8;
bool value = (((uint8_t*)&instance->key)[2 - byte] >> (7 - bit_in_byte)) & 1;
if(value) {
ret = level_duration_make(level, level ? instance->te * 3 : instance->te);
if(level)
instance->time_high += instance->te * 3;
else
instance->time_low += instance->te;
} else {
ret = level_duration_make(level, level ? instance->te : instance->te * 3);
if(level)
instance->time_high += instance->te;
else
instance->time_low += instance->te * 3;
}
} else {
if(--instance->count_key != 0) {
ret = level_duration_make(level, level ? instance->te : instance->te * 30);
if(level)
instance->time_high += instance->te;
else
instance->time_low += instance->te * 30;
} else {
instance->count_key = SUBGHZ_PT_COUNT_KEY + 6;
instance->front = 48;
ret = level_duration_make(level, level ? instance->te : SUBGHZ_PT_TIMEOUT * 1000);
if(level)
instance->time_high += instance->te;
else
instance->time_low += SUBGHZ_PT_TIMEOUT * 1000;
}
}
instance->front++;
if(instance->front == 50) {
instance->repeat--;
instance->front = 0;
}
return ret;
}
SubGhzDecoderPrinceton* subghz_decoder_princeton_alloc(void) {
SubGhzDecoderPrinceton* instance = furi_alloc(sizeof(SubGhzDecoderPrinceton));
instance->te = SUBGHZ_PT_SHORT;
instance->common.name = "Princeton";
instance->common.code_min_count_bit_for_found = 24;
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 = SubGhzProtocolCommonTypeStatic;
instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_decoder_princeton_to_str;
instance->common.to_save_string =
(SubGhzProtocolCommonGetStrSave)subghz_decoder_princeton_to_save_str;
instance->common.to_load_protocol_from_file =
(SubGhzProtocolCommonLoadFromFile)subghz_decoder_princeton_to_load_protocol_from_file;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoadFromRAW)subghz_decoder_princeton_to_load_protocol;
instance->common.get_upload_protocol =
(SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_princeton_send_key;
return instance;
}
void subghz_decoder_princeton_free(SubGhzDecoderPrinceton* instance) {
furi_assert(instance);
free(instance);
}
uint16_t subghz_protocol_princeton_get_te(void* context) {
SubGhzDecoderPrinceton* instance = context;
return instance->te;
}
bool subghz_protocol_princeton_send_key(
SubGhzDecoderPrinceton* instance,
SubGhzProtocolCommonEncoder* encoder) {
furi_assert(instance);
furi_assert(encoder);
size_t index = 0;
encoder->size_upload = (instance->common.code_last_count_bit * 2) + 2;
if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false;
//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)) {
//send bit 1
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->te * 3);
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->te);
} else {
//send bit 0
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->te);
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->te * 3);
}
}
//Send Stop bit
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->te);
//Send PT_GUARD
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->te * 30);
return true;
}
void subghz_decoder_princeton_reset(SubGhzDecoderPrinceton* instance) {
instance->common.parser_step = PrincetonDecoderStepReset;
}
void subghz_decoder_princeton_parse(
SubGhzDecoderPrinceton* instance,
bool level,
uint32_t duration) {
switch(instance->common.parser_step) {
case PrincetonDecoderStepReset:
if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 36) <
instance->common.te_delta * 36)) {
//Found Preambula
instance->common.parser_step = PrincetonDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
instance->te = 0;
} else {
instance->common.parser_step = PrincetonDecoderStepReset;
}
break;
case PrincetonDecoderStepSaveDuration:
//save duration
if(level) {
instance->common.te_last = duration;
instance->te += duration;
instance->common.parser_step = PrincetonDecoderStepCheckDuration;
}
break;
case PrincetonDecoderStepCheckDuration:
if(!level) {
if(duration >= (instance->common.te_short * 10 + instance->common.te_delta)) {
instance->common.parser_step = PrincetonDecoderStepSaveDuration;
if(instance->common.code_count_bit ==
instance->common.code_min_count_bit_for_found) {
instance->te /= (instance->common.code_count_bit * 4 + 1);
instance->common.code_last_found = instance->common.code_found;
instance->common.code_last_count_bit = instance->common.code_count_bit;
instance->common.serial = instance->common.code_found >> 4;
instance->common.btn = (uint8_t)instance->common.code_found & 0x00000F;
if(instance->common.callback)
instance->common.callback(
(SubGhzProtocolCommon*)instance, instance->common.context);
}
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
instance->te = 0;
break;
}
instance->te += duration;
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 = 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 = PrincetonDecoderStepSaveDuration;
} else {
instance->common.parser_step = PrincetonDecoderStepReset;
}
} else {
instance->common.parser_step = PrincetonDecoderStepReset;
}
break;
}
}
void subghz_decoder_princeton_to_str(SubGhzDecoderPrinceton* instance, string_t output) {
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(
instance->common.code_last_found, instance->common.code_last_count_bit);
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
string_cat_printf(
output,
"%s %dbit\r\n"
"Key:0x%08lX\r\n"
"Yek:0x%08lX\r\n"
"Sn:0x%05lX BTN:%02X\r\n"
"Te:%dus\r\n",
instance->common.name,
instance->common.code_last_count_bit,
code_found_lo,
code_found_reverse_lo,
instance->common.serial,
instance->common.btn,
instance->te);
}
void subghz_decoder_princeton_to_save_str(SubGhzDecoderPrinceton* instance, string_t output) {
string_printf(
output,
"Protocol: %s\n"
"Bit: %d\n"
"Te: %d\n"
"Key: %08lX\n",
instance->common.name,
instance->common.code_last_count_bit,
instance->te,
(uint32_t)(instance->common.code_last_found & 0x00000000ffffffff));
}
bool subghz_decoder_princeton_to_load_protocol_from_file(
FileWorker* file_worker,
SubGhzDecoderPrinceton* instance) {
bool loaded = false;
string_t temp_str;
string_init(temp_str);
int res = 0;
int data = 0;
do {
// Read and parse bit data from 2nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
if(res != 1) {
break;
}
instance->common.code_last_count_bit = (uint8_t)data;
// Read and parse te data from 3nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Te: %d\n", &data);
if(res != 1) {
break;
}
instance->te = (uint16_t)data;
// Read and parse key data from 4nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
uint32_t temp_key = 0;
res = sscanf(string_get_cstr(temp_str), "Key: %08lX\n", &temp_key);
if(res != 1) {
break;
}
instance->common.code_last_found = (uint64_t)temp_key;
instance->common.serial = instance->common.code_last_found >> 4;
instance->common.btn = (uint8_t)instance->common.code_last_found & 0x00000F;
loaded = true;
} while(0);
string_clear(temp_str);
return loaded;
}
void subghz_decoder_princeton_to_load_protocol(SubGhzDecoderPrinceton* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;
instance->common.code_last_found = data->code_found;
instance->common.code_last_count_bit = data->code_count_bit;
instance->te = data->param1;
instance->common.serial = instance->common.code_last_found >> 4;
instance->common.btn = (uint8_t)instance->common.code_last_found & 0x00000F;
}
#include "subghz_protocol_princeton.h"
/*
* Help
* https://phreakerclub.com/447
*
*/
#define SUBGHZ_PT_SHORT 400
#define SUBGHZ_PT_LONG (SUBGHZ_PT_SHORT * 3)
#define SUBGHZ_PT_GUARD (SUBGHZ_PT_SHORT * 30)
#define SUBGHZ_PT_COUNT_KEY 5
#define SUBGHZ_PT_TIMEOUT 320
struct SubGhzEncoderPrinceton {
uint32_t key;
uint16_t te;
size_t repeat;
size_t front;
size_t count_key;
uint32_t time_high;
uint32_t time_low;
};
typedef enum {
PrincetonDecoderStepReset = 0,
PrincetonDecoderStepSaveDuration,
PrincetonDecoderStepCheckDuration,
} PrincetonDecoderStep;
SubGhzEncoderPrinceton* subghz_encoder_princeton_alloc() {
SubGhzEncoderPrinceton* instance = furi_alloc(sizeof(SubGhzEncoderPrinceton));
return instance;
}
void subghz_encoder_princeton_free(SubGhzEncoderPrinceton* instance) {
furi_assert(instance);
free(instance);
}
void subghz_encoder_princeton_set_te(SubGhzEncoderPrinceton* instance, void* decoder) {
SubGhzDecoderPrinceton* pricenton = decoder;
if((pricenton->te) != 0) {
instance->te = pricenton->te;
} else {
instance->te = SUBGHZ_PT_SHORT;
}
}
void subghz_encoder_princeton_set(SubGhzEncoderPrinceton* instance, uint32_t key, size_t repeat) {
furi_assert(instance);
instance->te = SUBGHZ_PT_SHORT;
instance->key = key;
instance->repeat = repeat + 1;
instance->front = 48;
instance->count_key = SUBGHZ_PT_COUNT_KEY + 7;
instance->time_high = 0;
instance->time_low = 0;
}
size_t subghz_encoder_princeton_get_repeat_left(SubGhzEncoderPrinceton* instance) {
furi_assert(instance);
return instance->repeat;
}
void subghz_encoder_princeton_print_log(void* context) {
SubGhzEncoderPrinceton* instance = context;
float duty_cycle =
((float)instance->time_high / (instance->time_high + instance->time_low)) * 100;
FURI_LOG_I(
"EncoderPrinceton",
"Radio ON=%dus, OFF=%dus, DutyCycle=%d,%d%%",
instance->time_high,
instance->time_low,
(uint32_t)duty_cycle,
(uint32_t)((duty_cycle - (uint32_t)duty_cycle) * 100));
}
LevelDuration subghz_encoder_princeton_yield(void* context) {
SubGhzEncoderPrinceton* instance = context;
if(instance->repeat == 0) {
subghz_encoder_princeton_print_log(instance);
return level_duration_reset();
}
size_t bit = instance->front / 2;
bool level = !(instance->front % 2);
LevelDuration ret;
if(bit < 24) {
uint8_t byte = bit / 8;
uint8_t bit_in_byte = bit % 8;
bool value = (((uint8_t*)&instance->key)[2 - byte] >> (7 - bit_in_byte)) & 1;
if(value) {
ret = level_duration_make(level, level ? instance->te * 3 : instance->te);
if(level)
instance->time_high += instance->te * 3;
else
instance->time_low += instance->te;
} else {
ret = level_duration_make(level, level ? instance->te : instance->te * 3);
if(level)
instance->time_high += instance->te;
else
instance->time_low += instance->te * 3;
}
} else {
if(--instance->count_key != 0) {
ret = level_duration_make(level, level ? instance->te : instance->te * 30);
if(level)
instance->time_high += instance->te;
else
instance->time_low += instance->te * 30;
} else {
instance->count_key = SUBGHZ_PT_COUNT_KEY + 6;
instance->front = 48;
ret = level_duration_make(level, level ? instance->te : SUBGHZ_PT_TIMEOUT * 1000);
if(level)
instance->time_high += instance->te;
else
instance->time_low += SUBGHZ_PT_TIMEOUT * 1000;
}
}
instance->front++;
if(instance->front == 50) {
instance->repeat--;
instance->front = 0;
}
return ret;
}
SubGhzDecoderPrinceton* subghz_decoder_princeton_alloc(void) {
SubGhzDecoderPrinceton* instance = furi_alloc(sizeof(SubGhzDecoderPrinceton));
instance->te = SUBGHZ_PT_SHORT;
instance->common.name = "Princeton";
instance->common.code_min_count_bit_for_found = 24;
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 = SubGhzProtocolCommonTypeStatic;
instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_decoder_princeton_to_str;
instance->common.to_save_string =
(SubGhzProtocolCommonGetStrSave)subghz_decoder_princeton_to_save_str;
instance->common.to_load_protocol_from_file =
(SubGhzProtocolCommonLoadFromFile)subghz_decoder_princeton_to_load_protocol_from_file;
instance->common.to_load_protocol =
(SubGhzProtocolCommonLoadFromRAW)subghz_decoder_princeton_to_load_protocol;
instance->common.get_upload_protocol =
(SubGhzProtocolCommonEncoderGetUpLoad)subghz_protocol_princeton_send_key;
return instance;
}
void subghz_decoder_princeton_free(SubGhzDecoderPrinceton* instance) {
furi_assert(instance);
free(instance);
}
uint16_t subghz_protocol_princeton_get_te(void* context) {
SubGhzDecoderPrinceton* instance = context;
return instance->te;
}
bool subghz_protocol_princeton_send_key(
SubGhzDecoderPrinceton* instance,
SubGhzProtocolCommonEncoder* encoder) {
furi_assert(instance);
furi_assert(encoder);
size_t index = 0;
encoder->size_upload = (instance->common.code_last_count_bit * 2) + 2;
if(encoder->size_upload > SUBGHZ_ENCODER_UPLOAD_MAX_SIZE) return false;
//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)) {
//send bit 1
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->te * 3);
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->te);
} else {
//send bit 0
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->te);
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->te * 3);
}
}
//Send Stop bit
encoder->upload[index++] = level_duration_make(true, (uint32_t)instance->te);
//Send PT_GUARD
encoder->upload[index++] = level_duration_make(false, (uint32_t)instance->te * 30);
return true;
}
void subghz_decoder_princeton_reset(SubGhzDecoderPrinceton* instance) {
instance->common.parser_step = PrincetonDecoderStepReset;
}
void subghz_decoder_princeton_parse(
SubGhzDecoderPrinceton* instance,
bool level,
uint32_t duration) {
switch(instance->common.parser_step) {
case PrincetonDecoderStepReset:
if((!level) && (DURATION_DIFF(duration, instance->common.te_short * 36) <
instance->common.te_delta * 36)) {
//Found Preambula
instance->common.parser_step = PrincetonDecoderStepSaveDuration;
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
instance->te = 0;
} else {
instance->common.parser_step = PrincetonDecoderStepReset;
}
break;
case PrincetonDecoderStepSaveDuration:
//save duration
if(level) {
instance->common.te_last = duration;
instance->te += duration;
instance->common.parser_step = PrincetonDecoderStepCheckDuration;
}
break;
case PrincetonDecoderStepCheckDuration:
if(!level) {
if(duration >= (instance->common.te_short * 10 + instance->common.te_delta)) {
instance->common.parser_step = PrincetonDecoderStepSaveDuration;
if(instance->common.code_count_bit ==
instance->common.code_min_count_bit_for_found) {
instance->te /= (instance->common.code_count_bit * 4 + 1);
instance->common.code_last_found = instance->common.code_found;
instance->common.code_last_count_bit = instance->common.code_count_bit;
instance->common.serial = instance->common.code_found >> 4;
instance->common.btn = (uint8_t)instance->common.code_found & 0x00000F;
if(instance->common.callback)
instance->common.callback(
(SubGhzProtocolCommon*)instance, instance->common.context);
}
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
instance->te = 0;
break;
}
instance->te += duration;
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 = 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 = PrincetonDecoderStepSaveDuration;
} else {
instance->common.parser_step = PrincetonDecoderStepReset;
}
} else {
instance->common.parser_step = PrincetonDecoderStepReset;
}
break;
}
}
void subghz_decoder_princeton_to_str(SubGhzDecoderPrinceton* instance, string_t output) {
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(
instance->common.code_last_found, instance->common.code_last_count_bit);
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
string_cat_printf(
output,
"%s %dbit\r\n"
"Key:0x%08lX\r\n"
"Yek:0x%08lX\r\n"
"Sn:0x%05lX BTN:%02X\r\n"
"Te:%dus\r\n",
instance->common.name,
instance->common.code_last_count_bit,
code_found_lo,
code_found_reverse_lo,
instance->common.serial,
instance->common.btn,
instance->te);
}
void subghz_decoder_princeton_to_save_str(SubGhzDecoderPrinceton* instance, string_t output) {
string_printf(
output,
"Protocol: %s\n"
"Bit: %d\n"
"Te: %d\n"
"Key: %08lX\n",
instance->common.name,
instance->common.code_last_count_bit,
instance->te,
(uint32_t)(instance->common.code_last_found & 0x00000000ffffffff));
}
bool subghz_decoder_princeton_to_load_protocol_from_file(
FileWorker* file_worker,
SubGhzDecoderPrinceton* instance) {
bool loaded = false;
string_t temp_str;
string_init(temp_str);
int res = 0;
int data = 0;
do {
// Read and parse bit data from 2nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Bit: %d\n", &data);
if(res != 1) {
break;
}
instance->common.code_last_count_bit = (uint8_t)data;
// Read and parse te data from 3nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
res = sscanf(string_get_cstr(temp_str), "Te: %d\n", &data);
if(res != 1) {
break;
}
instance->te = (uint16_t)data;
// Read and parse key data from 4nd line
if(!file_worker_read_until(file_worker, temp_str, '\n')) {
break;
}
uint32_t temp_key = 0;
res = sscanf(string_get_cstr(temp_str), "Key: %08lX\n", &temp_key);
if(res != 1) {
break;
}
instance->common.code_last_found = (uint64_t)temp_key;
instance->common.serial = instance->common.code_last_found >> 4;
instance->common.btn = (uint8_t)instance->common.code_last_found & 0x00000F;
loaded = true;
} while(0);
string_clear(temp_str);
return loaded;
}
void subghz_decoder_princeton_to_load_protocol(SubGhzDecoderPrinceton* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;
instance->common.code_last_found = data->code_found;
instance->common.code_last_count_bit = data->code_count_bit;
instance->te = data->param1;
instance->common.serial = instance->common.code_last_found >> 4;
instance->common.btn = (uint8_t)instance->common.code_last_found & 0x00000F;
}

View File

@@ -1,125 +1,125 @@
#pragma once
#include "subghz_protocol_common.h"
struct SubGhzDecoderPrinceton {
SubGhzProtocolCommon common;
uint32_t te;
};
/** SubGhzEncoderPrinceton anonymous type */
typedef struct SubGhzEncoderPrinceton SubGhzEncoderPrinceton;
/** Allocate SubGhzEncoderPrinceton
* @return pointer to SubGhzEncoderPrinceton instance
*/
SubGhzEncoderPrinceton* subghz_encoder_princeton_alloc();
/** Free SubGhzEncoderPrinceton instance
* @param instance - SubGhzEncoderPrinceton instance
*/
void subghz_encoder_princeton_free(SubGhzEncoderPrinceton* instance);
/** Set new encoder params
* @param instance - SubGhzEncoderPrinceton instance
* @param key - 24bit key
* @param repeat - how many times to repeat
*/
void subghz_encoder_princeton_set(SubGhzEncoderPrinceton* instance, uint32_t key, size_t repeat);
/** Get repeat count left
* @param instance - SubGhzEncoderPrinceton instance
* @return repeat count left
*/
size_t subghz_encoder_princeton_get_repeat_left(SubGhzEncoderPrinceton* instance);
/** Print encoder log
* @param instance - SubGhzEncoderPrinceton instance
*/
void subghz_encoder_princeton_print_log(void* context);
/** Get level duration
* @param instance - SubGhzEncoderPrinceton instance
* @return level duration
*/
LevelDuration subghz_encoder_princeton_yield(void* context);
/** SubGhzDecoderPrinceton anonymous type */
typedef struct SubGhzDecoderPrinceton SubGhzDecoderPrinceton;
void subghz_encoder_princeton_set_te(SubGhzEncoderPrinceton* instance, void* decoder);
/** Allocate SubGhzDecoderPrinceton
*
* @return SubGhzDecoderPrinceton*
*/
SubGhzDecoderPrinceton* subghz_decoder_princeton_alloc();
/** Free SubGhzDecoderPrinceton
*
* @param instance
*/
void subghz_decoder_princeton_free(SubGhzDecoderPrinceton* instance);
/** Get Te interval protocol
*
* @param context - SubGhzDecoderPrinceton context
* @return Te interval (us)
*/
uint16_t subghz_protocol_princeton_get_te(void* context);
/** Get upload protocol
*
* @param instance - SubGhzDecoderPrinceton instance
* @param encoder - SubGhzProtocolCommonEncoder encoder
* @return bool
*/
bool subghz_protocol_princeton_send_key(
SubGhzDecoderPrinceton* instance,
SubGhzProtocolCommonEncoder* encoder);
/** Reset internal state
* @param instance - SubGhzDecoderPrinceton instance
*/
void subghz_decoder_princeton_reset(SubGhzDecoderPrinceton* instance);
/** Parse accepted duration
*
* @param instance - SubGhzDecoderPrinceton instance
* @param data - LevelDuration level_duration
*/
void subghz_decoder_princeton_parse(
SubGhzDecoderPrinceton* instance,
bool level,
uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzDecoderPrinceton* instance
* @param output - output string
*/
void subghz_decoder_princeton_to_str(SubGhzDecoderPrinceton* instance, string_t output);
/** Get a string to save the protocol
*
* @param instance - SubGhzDecoderPrinceton instance
* @param output - the resulting string
*/
void subghz_decoder_princeton_to_save_str(SubGhzDecoderPrinceton* instance, string_t output);
/** Loading protocol from file
*
* @param file_worker - FileWorker file_worker
* @param instance - SubGhzDecoderPrinceton instance
* @return bool
*/
bool subghz_decoder_princeton_to_load_protocol_from_file(FileWorker* file_worker, SubGhzDecoderPrinceton* instance);
/** Loading protocol from bin data
*
* @param instance - SubGhzDecoderPrinceton instance
* @param context - SubGhzProtocolCommonLoad context
*/
void subghz_decoder_princeton_to_load_protocol(
SubGhzDecoderPrinceton* instance,
void* context) ;
#pragma once
#include "subghz_protocol_common.h"
struct SubGhzDecoderPrinceton {
SubGhzProtocolCommon common;
uint32_t te;
};
/** SubGhzEncoderPrinceton anonymous type */
typedef struct SubGhzEncoderPrinceton SubGhzEncoderPrinceton;
/** Allocate SubGhzEncoderPrinceton
* @return pointer to SubGhzEncoderPrinceton instance
*/
SubGhzEncoderPrinceton* subghz_encoder_princeton_alloc();
/** Free SubGhzEncoderPrinceton instance
* @param instance - SubGhzEncoderPrinceton instance
*/
void subghz_encoder_princeton_free(SubGhzEncoderPrinceton* instance);
/** Set new encoder params
* @param instance - SubGhzEncoderPrinceton instance
* @param key - 24bit key
* @param repeat - how many times to repeat
*/
void subghz_encoder_princeton_set(SubGhzEncoderPrinceton* instance, uint32_t key, size_t repeat);
/** Get repeat count left
* @param instance - SubGhzEncoderPrinceton instance
* @return repeat count left
*/
size_t subghz_encoder_princeton_get_repeat_left(SubGhzEncoderPrinceton* instance);
/** Print encoder log
* @param instance - SubGhzEncoderPrinceton instance
*/
void subghz_encoder_princeton_print_log(void* context);
/** Get level duration
* @param instance - SubGhzEncoderPrinceton instance
* @return level duration
*/
LevelDuration subghz_encoder_princeton_yield(void* context);
/** SubGhzDecoderPrinceton anonymous type */
typedef struct SubGhzDecoderPrinceton SubGhzDecoderPrinceton;
void subghz_encoder_princeton_set_te(SubGhzEncoderPrinceton* instance, void* decoder);
/** Allocate SubGhzDecoderPrinceton
*
* @return SubGhzDecoderPrinceton*
*/
SubGhzDecoderPrinceton* subghz_decoder_princeton_alloc();
/** Free SubGhzDecoderPrinceton
*
* @param instance
*/
void subghz_decoder_princeton_free(SubGhzDecoderPrinceton* instance);
/** Get Te interval protocol
*
* @param context - SubGhzDecoderPrinceton context
* @return Te interval (us)
*/
uint16_t subghz_protocol_princeton_get_te(void* context);
/** Get upload protocol
*
* @param instance - SubGhzDecoderPrinceton instance
* @param encoder - SubGhzProtocolCommonEncoder encoder
* @return bool
*/
bool subghz_protocol_princeton_send_key(
SubGhzDecoderPrinceton* instance,
SubGhzProtocolCommonEncoder* encoder);
/** Reset internal state
* @param instance - SubGhzDecoderPrinceton instance
*/
void subghz_decoder_princeton_reset(SubGhzDecoderPrinceton* instance);
/** Parse accepted duration
*
* @param instance - SubGhzDecoderPrinceton instance
* @param data - LevelDuration level_duration
*/
void subghz_decoder_princeton_parse(
SubGhzDecoderPrinceton* instance,
bool level,
uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzDecoderPrinceton* instance
* @param output - output string
*/
void subghz_decoder_princeton_to_str(SubGhzDecoderPrinceton* instance, string_t output);
/** Get a string to save the protocol
*
* @param instance - SubGhzDecoderPrinceton instance
* @param output - the resulting string
*/
void subghz_decoder_princeton_to_save_str(SubGhzDecoderPrinceton* instance, string_t output);
/** Loading protocol from file
*
* @param file_worker - FileWorker file_worker
* @param instance - SubGhzDecoderPrinceton instance
* @return bool
*/
bool subghz_decoder_princeton_to_load_protocol_from_file(FileWorker* file_worker, SubGhzDecoderPrinceton* instance);
/** Loading protocol from bin data
*
* @param instance - SubGhzDecoderPrinceton instance
* @param context - SubGhzProtocolCommonLoad context
*/
void subghz_decoder_princeton_to_load_protocol(
SubGhzDecoderPrinceton* instance,
void* context) ;

View File

@@ -1,342 +1,342 @@
#include "subghz_protocol_star_line.h"
#include "subghz_protocol_keeloq_common.h"
#include "../subghz_keystore.h"
#include <furi.h>
#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.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 = 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;
return instance;
}
void subghz_protocol_star_line_free(SubGhzProtocolStarLine* instance) {
furi_assert(instance);
free(instance);
}
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) {
SubGhzProtocolStarLine* instance = context;
return instance->manufacture_name;
}
/** Send bit
*
* @param instance - SubGhzProtocolStarLine instance
* @param bit - bit
*/
void subghz_protocol_star_line_send_bit(SubGhzProtocolStarLine* instance, uint8_t bit) {
if(bit) {
//send bit 1
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_long);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_long);
} else {
//send bit 0
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_short);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_short);
}
}
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++) {
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_long * 2);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_long * 2);
}
//Send Start bit ??????????
//Send key data
for(uint8_t i = bit; i > 0; i--) {
subghz_protocol_star_line_send_bit(instance, bit_read(key, i - 1));
}
//Send Stop bit ??????????
}
}
void subghz_protocol_star_line_reset(SubGhzProtocolStarLine* instance) {
instance->common.parser_step = StarLineDecoderStepReset;
}
/** Checking the accepted code against the database manafacture key
*
* @param instance SubGhzProtocolStarLine instance
* @param fix fix part of the parcel
* @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);
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;
}
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;
}
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;
}
break;
}
}
instance->manufacture_name = "Unknown";
instance->common.cnt = 0;
return 0;
}
/** Analysis of received data
*
* @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);
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.btn = key_fix >> 24;
}
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) {
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
instance->common.te_last = duration;
instance->common.parser_step = StarLineDecoderStepCheckDuration;
}
} else {
instance->common.parser_step = StarLineDecoderStepReset;
instance->common.header_count = 0;
}
break;
case StarLineDecoderStepCheckPreambula:
if((!level) && (DURATION_DIFF(duration, instance->common.te_long * 2) <
instance->common.te_delta * 2)) {
//Found Preambula
instance->common.parser_step = StarLineDecoderStepReset;
} else {
instance->common.header_count = 0;
instance->common.parser_step = StarLineDecoderStepReset;
}
break;
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);
}
}
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
instance->common.header_count = 0;
break;
} else {
instance->common.te_last = duration;
instance->common.parser_step = StarLineDecoderStepCheckDuration;
}
} else {
instance->common.parser_step = StarLineDecoderStepReset;
}
break;
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 = 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 = StarLineDecoderStepSaveDuration;
} else {
instance->common.parser_step = StarLineDecoderStepReset;
}
} else {
instance->common.parser_step = StarLineDecoderStepReset;
}
break;
}
}
void subghz_protocol_star_line_to_str(SubGhzProtocolStarLine* instance, string_t output) {
subghz_protocol_star_line_check_remote_controller(instance);
uint32_t code_found_hi = instance->common.code_last_found >> 32;
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(
instance->common.code_last_found, instance->common.code_last_count_bit);
uint32_t code_found_reverse_hi = code_found_reverse >> 32;
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
string_cat_printf(
output,
"%s %dbit\r\n"
"Key:%08lX%08lX\r\n"
"Fix:0x%08lX Cnt:%04X\r\n"
"Hop:0x%08lX Btn:%02lX\r\n"
"MF:%s\r\n"
"Sn:0x%07lX \r\n",
instance->common.name,
instance->common.code_last_count_bit,
code_found_hi,
code_found_lo,
code_found_reverse_hi,
instance->common.cnt,
code_found_reverse_lo,
instance->common.btn,
instance->manufacture_name,
instance->common.serial);
}
void subghz_decoder_star_line_to_load_protocol(SubGhzProtocolStarLine* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;
instance->common.code_last_found = data->code_found;
instance->common.code_last_count_bit = data->code_count_bit;
subghz_protocol_star_line_check_remote_controller(instance);
#include "subghz_protocol_star_line.h"
#include "subghz_protocol_keeloq_common.h"
#include "../subghz_keystore.h"
#include <furi.h>
#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.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 = 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;
return instance;
}
void subghz_protocol_star_line_free(SubGhzProtocolStarLine* instance) {
furi_assert(instance);
free(instance);
}
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) {
SubGhzProtocolStarLine* instance = context;
return instance->manufacture_name;
}
/** Send bit
*
* @param instance - SubGhzProtocolStarLine instance
* @param bit - bit
*/
void subghz_protocol_star_line_send_bit(SubGhzProtocolStarLine* instance, uint8_t bit) {
if(bit) {
//send bit 1
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_long);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_long);
} else {
//send bit 0
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_short);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_short);
}
}
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++) {
SUBGHZ_TX_PIN_HIGH();
delay_us(instance->common.te_long * 2);
SUBGHZ_TX_PIN_LOW();
delay_us(instance->common.te_long * 2);
}
//Send Start bit ??????????
//Send key data
for(uint8_t i = bit; i > 0; i--) {
subghz_protocol_star_line_send_bit(instance, bit_read(key, i - 1));
}
//Send Stop bit ??????????
}
}
void subghz_protocol_star_line_reset(SubGhzProtocolStarLine* instance) {
instance->common.parser_step = StarLineDecoderStepReset;
}
/** Checking the accepted code against the database manafacture key
*
* @param instance SubGhzProtocolStarLine instance
* @param fix fix part of the parcel
* @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);
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;
}
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;
}
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;
}
break;
}
}
instance->manufacture_name = "Unknown";
instance->common.cnt = 0;
return 0;
}
/** Analysis of received data
*
* @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);
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.btn = key_fix >> 24;
}
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) {
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
instance->common.te_last = duration;
instance->common.parser_step = StarLineDecoderStepCheckDuration;
}
} else {
instance->common.parser_step = StarLineDecoderStepReset;
instance->common.header_count = 0;
}
break;
case StarLineDecoderStepCheckPreambula:
if((!level) && (DURATION_DIFF(duration, instance->common.te_long * 2) <
instance->common.te_delta * 2)) {
//Found Preambula
instance->common.parser_step = StarLineDecoderStepReset;
} else {
instance->common.header_count = 0;
instance->common.parser_step = StarLineDecoderStepReset;
}
break;
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);
}
}
instance->common.code_found = 0;
instance->common.code_count_bit = 0;
instance->common.header_count = 0;
break;
} else {
instance->common.te_last = duration;
instance->common.parser_step = StarLineDecoderStepCheckDuration;
}
} else {
instance->common.parser_step = StarLineDecoderStepReset;
}
break;
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 = 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 = StarLineDecoderStepSaveDuration;
} else {
instance->common.parser_step = StarLineDecoderStepReset;
}
} else {
instance->common.parser_step = StarLineDecoderStepReset;
}
break;
}
}
void subghz_protocol_star_line_to_str(SubGhzProtocolStarLine* instance, string_t output) {
subghz_protocol_star_line_check_remote_controller(instance);
uint32_t code_found_hi = instance->common.code_last_found >> 32;
uint32_t code_found_lo = instance->common.code_last_found & 0x00000000ffffffff;
uint64_t code_found_reverse = subghz_protocol_common_reverse_key(
instance->common.code_last_found, instance->common.code_last_count_bit);
uint32_t code_found_reverse_hi = code_found_reverse >> 32;
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
string_cat_printf(
output,
"%s %dbit\r\n"
"Key:%08lX%08lX\r\n"
"Fix:0x%08lX Cnt:%04X\r\n"
"Hop:0x%08lX Btn:%02lX\r\n"
"MF:%s\r\n"
"Sn:0x%07lX \r\n",
instance->common.name,
instance->common.code_last_count_bit,
code_found_hi,
code_found_lo,
code_found_reverse_hi,
instance->common.cnt,
code_found_reverse_lo,
instance->common.btn,
instance->manufacture_name,
instance->common.serial);
}
void subghz_decoder_star_line_to_load_protocol(SubGhzProtocolStarLine* instance, void* context) {
furi_assert(context);
furi_assert(instance);
SubGhzProtocolCommonLoad* data = context;
instance->common.code_last_found = data->code_found;
instance->common.code_last_count_bit = data->code_count_bit;
subghz_protocol_star_line_check_remote_controller(instance);
}

View File

@@ -1,74 +1,74 @@
#pragma once
#include "subghz_protocol_common.h"
typedef struct SubGhzKeystore SubGhzKeystore;
typedef struct SubGhzProtocolStarLine SubGhzProtocolStarLine;
/** Allocate SubGhzProtocolStarLine
*
* @return SubGhzProtocolStarLine*
*/
SubGhzProtocolStarLine* subghz_protocol_star_line_alloc(SubGhzKeystore* keystore);
/** Free SubGhzProtocolStarLine
*
* @param instance
*/
void subghz_protocol_star_line_free(SubGhzProtocolStarLine* instance);
/** Find and get manufacture name
*
* @param context - SubGhzProtocolStarLine context
* @return name - char* manufacture name
*/
const char* subghz_protocol_star_line_find_and_get_manufacture_name(void* context);
/** Get manufacture name
*
* @param context - SubGhzProtocolStarLine context
* @return name - char* manufacture name
*/
const char* subghz_protocol_star_line_get_manufacture_name(void* context);
/** Sends the key on the air
*
* @param instance - SubGhzProtocolStarLine instance
* @param key - key send
* @param bit - count bit key
* @param repeat - repeat send key
*/
void subghz_protocol_star_line_send_key(SubGhzProtocolStarLine* instance, uint64_t key, uint8_t bit, uint8_t repeat);
/** Reset internal state
* @param instance - SubGhzProtocolStarLine instance
*/
void subghz_protocol_star_line_reset(SubGhzProtocolStarLine* instance);
/** Analysis of received data
*
* @param instance SubGhzProtocolStarLine instance
*/
void subghz_protocol_star_line_check_remote_controller(SubGhzProtocolStarLine* instance);
/** Parse accepted duration
*
* @param instance - SubGhzProtocolStarLine instance
* @param data - LevelDuration level_duration
*/
void subghz_protocol_star_line_parse(SubGhzProtocolStarLine* instance, bool level, uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzProtocolStarLine* instance
* @param output - output string
*/
void subghz_protocol_star_line_to_str(SubGhzProtocolStarLine* instance, string_t output);
/** Loading protocol from bin data
*
* @param instance - SubGhzDecoderPrinceton instance
* @param context - SubGhzProtocolCommonLoad context
*/
void subghz_decoder_star_line_to_load_protocol(SubGhzProtocolStarLine* instance, void* context);
#pragma once
#include "subghz_protocol_common.h"
typedef struct SubGhzKeystore SubGhzKeystore;
typedef struct SubGhzProtocolStarLine SubGhzProtocolStarLine;
/** Allocate SubGhzProtocolStarLine
*
* @return SubGhzProtocolStarLine*
*/
SubGhzProtocolStarLine* subghz_protocol_star_line_alloc(SubGhzKeystore* keystore);
/** Free SubGhzProtocolStarLine
*
* @param instance
*/
void subghz_protocol_star_line_free(SubGhzProtocolStarLine* instance);
/** Find and get manufacture name
*
* @param context - SubGhzProtocolStarLine context
* @return name - char* manufacture name
*/
const char* subghz_protocol_star_line_find_and_get_manufacture_name(void* context);
/** Get manufacture name
*
* @param context - SubGhzProtocolStarLine context
* @return name - char* manufacture name
*/
const char* subghz_protocol_star_line_get_manufacture_name(void* context);
/** Sends the key on the air
*
* @param instance - SubGhzProtocolStarLine instance
* @param key - key send
* @param bit - count bit key
* @param repeat - repeat send key
*/
void subghz_protocol_star_line_send_key(SubGhzProtocolStarLine* instance, uint64_t key, uint8_t bit, uint8_t repeat);
/** Reset internal state
* @param instance - SubGhzProtocolStarLine instance
*/
void subghz_protocol_star_line_reset(SubGhzProtocolStarLine* instance);
/** Analysis of received data
*
* @param instance SubGhzProtocolStarLine instance
*/
void subghz_protocol_star_line_check_remote_controller(SubGhzProtocolStarLine* instance);
/** Parse accepted duration
*
* @param instance - SubGhzProtocolStarLine instance
* @param data - LevelDuration level_duration
*/
void subghz_protocol_star_line_parse(SubGhzProtocolStarLine* instance, bool level, uint32_t duration);
/** Outputting information from the parser
*
* @param instance - SubGhzProtocolStarLine* instance
* @param output - output string
*/
void subghz_protocol_star_line_to_str(SubGhzProtocolStarLine* instance, string_t output);
/** Loading protocol from bin data
*
* @param instance - SubGhzDecoderPrinceton instance
* @param context - SubGhzProtocolCommonLoad context
*/
void subghz_decoder_star_line_to_load_protocol(SubGhzProtocolStarLine* instance, void* context);