1
mirror of https://github.com/DarkFlippers/unleashed-firmware.git synced 2025-12-12 04:34:43 +04:00

subghz marantec protocol implement crc verification and add manually

fix crc function, add valid/invalid display (does not affect TX) and use new crc sum in add manually menu
This commit is contained in:
MX
2025-07-06 18:42:16 +03:00
parent 6ae1ce6861
commit 43b35019ed
6 changed files with 99 additions and 4 deletions

View File

@@ -126,6 +126,8 @@ typedef enum {
SetTypeHollarm_433, SetTypeHollarm_433,
SetTypeReversRB2_433, SetTypeReversRB2_433,
SetTypeMarantec24_868, SetTypeMarantec24_868,
SetTypeMarantec_433,
SetTypeMarantec_868,
SetTypeLinear_300_00, SetTypeLinear_300_00,
// SetTypeNeroSketch, //Deleted in OFW // SetTypeNeroSketch, //Deleted in OFW
// SetTypeNeroRadio, //Deleted in OFW // SetTypeNeroRadio, //Deleted in OFW

View File

@@ -6,6 +6,7 @@
#include <lib/subghz/protocols/secplus_v1.h> #include <lib/subghz/protocols/secplus_v1.h>
#include <lib/subghz/protocols/secplus_v2.h> #include <lib/subghz/protocols/secplus_v2.h>
#include <lib/subghz/protocols/nice_flor_s.h> #include <lib/subghz/protocols/nice_flor_s.h>
#include <lib/subghz/protocols/marantec.h>
#include <flipper_format/flipper_format_i.h> #include <flipper_format/flipper_format_i.h>
#include <lib/toolbox/stream/stream.h> #include <lib/toolbox/stream/stream.h>
@@ -395,3 +396,27 @@ void subghz_txrx_gen_serial_gangqi(uint64_t* result_key) {
// serial | const_and_button // serial | const_and_button
*result_key = (serial << 18) | (const_and_button << 10) | (bytesum << 2); *result_key = (serial << 18) | (const_and_button << 10) | (bytesum << 2);
} }
void subghz_txrx_gen_key_marantec(uint64_t* result_key) {
uint64_t randkey = (uint64_t)rand();
uint32_t serial = (uint32_t)((randkey) & 0xFFFFF);
// 0x130 is the constant
// 0x4 is the button code
// 0x86 is the serial constant
// serial is random value that we pre generate above
// At the end we will put the crc sum
uint64_t full_key_no_crc = (uint64_t)((uint64_t)0x130 << 40 | (uint64_t)serial << 20 |
(uint64_t)0x4 << 16 | (uint64_t)0x86 << 8);
uint8_t tdata[6] = {
full_key_no_crc >> 48,
full_key_no_crc >> 40,
full_key_no_crc >> 32,
full_key_no_crc >> 24,
full_key_no_crc >> 16,
full_key_no_crc >> 8};
uint8_t crc = subghz_protocol_marantec_crc8(tdata, sizeof(tdata));
*result_key = ((full_key_no_crc >> 8) << 8) | crc;
}

View File

@@ -153,3 +153,10 @@ bool subghz_txrx_gen_secplus_v1_protocol(
* @return uint64_t if success * @return uint64_t if success
*/ */
void subghz_txrx_gen_serial_gangqi(uint64_t* result_key); void subghz_txrx_gen_serial_gangqi(uint64_t* result_key);
/**
* Generate key for Marantec protocol
*
* @param result_key Pointer to a uint64_t where the key will be stored
*/
void subghz_txrx_gen_key_marantec(uint64_t* result_key);

View File

@@ -71,6 +71,8 @@ static const char* submenu_names[SetTypeMAX] = {
[SetTypeHollarm_433] = "Hollarm 433MHz", [SetTypeHollarm_433] = "Hollarm 433MHz",
[SetTypeReversRB2_433] = "Revers RB2 433MHz", [SetTypeReversRB2_433] = "Revers RB2 433MHz",
[SetTypeMarantec24_868] = "Marantec24 868MHz", [SetTypeMarantec24_868] = "Marantec24 868MHz",
[SetTypeMarantec_433] = "Marantec 433MHz",
[SetTypeMarantec_868] = "Marantec 868MHz",
[SetTypeBETT_433] = "BETT 433MHz", [SetTypeBETT_433] = "BETT 433MHz",
[SetTypeLinear_300_00] = "Linear 300MHz", [SetTypeLinear_300_00] = "Linear 300MHz",
// [SetTypeNeroSketch] = "Nero Sketch", // Deleted in OFW // [SetTypeNeroSketch] = "Nero Sketch", // Deleted in OFW
@@ -192,6 +194,9 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
uint64_t gangqi_key; uint64_t gangqi_key;
subghz_txrx_gen_serial_gangqi(&gangqi_key); subghz_txrx_gen_serial_gangqi(&gangqi_key);
uint64_t marantec_key;
subghz_txrx_gen_key_marantec(&marantec_key);
GenInfo gen_info = {0}; GenInfo gen_info = {0};
switch(event.event) { switch(event.event) {
case SetTypePricenton433: case SetTypePricenton433:
@@ -360,6 +365,28 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
.data.bits = 24, .data.bits = 24,
.data.te = 0}; .data.te = 0};
break; break;
case SetTypeMarantec_433:
gen_info = (GenInfo){
.type = GenData,
.mod = "AM650",
.freq = 433920000,
.data.name =
SUBGHZ_PROTOCOL_MARANTEC_NAME, // Button code is 0x4 and crc sum to the end
.data.key = marantec_key,
.data.bits = 49,
.data.te = 0};
break;
case SetTypeMarantec_868:
gen_info = (GenInfo){
.type = GenData,
.mod = "AM650",
.freq = 868350000,
.data.name =
SUBGHZ_PROTOCOL_MARANTEC_NAME, // Button code is 0x4 and crc sum to the end
.data.key = marantec_key,
.data.bits = 49,
.data.te = 0};
break;
case SetTypeFaacSLH_433: case SetTypeFaacSLH_433:
gen_info = (GenInfo){ gen_info = (GenInfo){
.type = GenFaacSLH, .type = GenFaacSLH,

View File

@@ -165,7 +165,7 @@ static void subghz_protocol_encoder_marantec_get_upload(SubGhzProtocolEncoderMar
} }
uint8_t subghz_protocol_marantec_crc8(uint8_t* data, size_t len) { uint8_t subghz_protocol_marantec_crc8(uint8_t* data, size_t len) {
uint8_t crc = 0x08; uint8_t crc = 0x01;
size_t i, j; size_t i, j;
for(i = 0; i < len; i++) { for(i = 0; i < len; i++) {
crc ^= data[i]; crc ^= data[i];
@@ -184,6 +184,18 @@ uint8_t subghz_protocol_marantec_crc8(uint8_t* data, size_t len) {
* @param instance Pointer to a SubGhzBlockGeneric* instance * @param instance Pointer to a SubGhzBlockGeneric* instance
*/ */
static void subghz_protocol_marantec_remote_controller(SubGhzBlockGeneric* instance) { static void subghz_protocol_marantec_remote_controller(SubGhzBlockGeneric* instance) {
// Key samples
// 1307EDF6486C5 = 000 100110000 01111110110111110110 0100 10000110 11000101
// 1303EFAFD8683 = 000 100110000 00111110111110101111 1101 10000110 10000011
// From unittests
// 1300710DF869F
// const serial button serial crc
// 130 7EDF6 4 86 C5
// 130 3EFAF D 86 83
// 130 0710D F 86 9F
instance->btn = (instance->data >> 16) & 0xF; instance->btn = (instance->data >> 16) & 0xF;
instance->serial = ((instance->data >> 12) & 0xFFFFFF00) | ((instance->data >> 8) & 0xFF); instance->serial = ((instance->data >> 12) & 0xFFFFFF00) | ((instance->data >> 8) & 0xFF);
} }
@@ -367,16 +379,30 @@ void subghz_protocol_decoder_marantec_get_string(void* context, FuriString* outp
SubGhzProtocolDecoderMarantec* instance = context; SubGhzProtocolDecoderMarantec* instance = context;
subghz_protocol_marantec_remote_controller(&instance->generic); subghz_protocol_marantec_remote_controller(&instance->generic);
uint8_t tdata[6] = {
instance->generic.data >> 48,
instance->generic.data >> 40,
instance->generic.data >> 32,
instance->generic.data >> 24,
instance->generic.data >> 16,
instance->generic.data >> 8};
uint8_t crc = subghz_protocol_marantec_crc8(tdata, sizeof(tdata));
bool crc_ok = (crc == (instance->generic.data & 0xFF));
furi_string_cat_printf( furi_string_cat_printf(
output, output,
"%s %db\r\n" "%s %db\r\n"
"Key:0x%lX%08lX\r\n" "Key: 0x%lX%08lX\r\n"
"Sn:0x%07lX \r\n" "Sn: 0x%07lX \r\n"
"Btn:%X\r\n", "CRC: 0x%02X - %s\r\n"
"Btn: %X\r\n",
instance->generic.protocol_name, instance->generic.protocol_name,
instance->generic.data_count_bit, instance->generic.data_count_bit,
(uint32_t)(instance->generic.data >> 32), (uint32_t)(instance->generic.data >> 32),
(uint32_t)(instance->generic.data & 0xFFFFFFFF), (uint32_t)(instance->generic.data & 0xFFFFFFFF),
instance->generic.serial, instance->generic.serial,
crc,
crc_ok ? "Valid" : "Invalid",
instance->generic.btn); instance->generic.btn);
} }

View File

@@ -107,3 +107,11 @@ SubGhzProtocolStatus
* @param output Resulting text * @param output Resulting text
*/ */
void subghz_protocol_decoder_marantec_get_string(void* context, FuriString* output); void subghz_protocol_decoder_marantec_get_string(void* context, FuriString* output);
/**
* Calculate CRC8 for Marantec protocol.
* @param data Pointer to the data buffer
* @param len Length of the data buffer
* @return CRC8 value
*/
uint8_t subghz_protocol_marantec_crc8(uint8_t* data, size_t len);