diff --git a/applications/main/subghz/helpers/subghz_custom_event.h b/applications/main/subghz/helpers/subghz_custom_event.h index bdd5f849d..a3dae60b8 100644 --- a/applications/main/subghz/helpers/subghz_custom_event.h +++ b/applications/main/subghz/helpers/subghz_custom_event.h @@ -126,6 +126,8 @@ typedef enum { SetTypeHollarm_433, SetTypeReversRB2_433, SetTypeMarantec24_868, + SetTypeMarantec_433, + SetTypeMarantec_868, SetTypeLinear_300_00, // SetTypeNeroSketch, //Deleted in OFW // SetTypeNeroRadio, //Deleted in OFW diff --git a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c index 63b892401..813b706b6 100644 --- a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c +++ b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -395,3 +396,27 @@ void subghz_txrx_gen_serial_gangqi(uint64_t* result_key) { // serial | const_and_button *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; +} diff --git a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.h b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.h index 55932bd39..fba7acb6f 100644 --- a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.h +++ b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.h @@ -153,3 +153,10 @@ bool subghz_txrx_gen_secplus_v1_protocol( * @return uint64_t if success */ 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); diff --git a/applications/main/subghz/scenes/subghz_scene_set_type.c b/applications/main/subghz/scenes/subghz_scene_set_type.c index f70aec803..134d2e1d1 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_type.c +++ b/applications/main/subghz/scenes/subghz_scene_set_type.c @@ -71,6 +71,8 @@ static const char* submenu_names[SetTypeMAX] = { [SetTypeHollarm_433] = "Hollarm 433MHz", [SetTypeReversRB2_433] = "Revers RB2 433MHz", [SetTypeMarantec24_868] = "Marantec24 868MHz", + [SetTypeMarantec_433] = "Marantec 433MHz", + [SetTypeMarantec_868] = "Marantec 868MHz", [SetTypeBETT_433] = "BETT 433MHz", [SetTypeLinear_300_00] = "Linear 300MHz", // [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; subghz_txrx_gen_serial_gangqi(&gangqi_key); + uint64_t marantec_key; + subghz_txrx_gen_key_marantec(&marantec_key); + GenInfo gen_info = {0}; switch(event.event) { case SetTypePricenton433: @@ -360,6 +365,28 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { .data.bits = 24, .data.te = 0}; 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: gen_info = (GenInfo){ .type = GenFaacSLH, diff --git a/lib/subghz/protocols/marantec.c b/lib/subghz/protocols/marantec.c index fc4aa0dca..edb176635 100644 --- a/lib/subghz/protocols/marantec.c +++ b/lib/subghz/protocols/marantec.c @@ -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 crc = 0x08; + uint8_t crc = 0x01; size_t i, j; for(i = 0; i < len; 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 */ 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->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; 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( output, "%s %db\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%07lX \r\n" - "Btn:%X\r\n", + "Key: 0x%lX%08lX\r\n" + "Sn: 0x%07lX \r\n" + "CRC: 0x%02X - %s\r\n" + "Btn: %X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data >> 32), (uint32_t)(instance->generic.data & 0xFFFFFFFF), instance->generic.serial, + crc, + crc_ok ? "Valid" : "Invalid", instance->generic.btn); } diff --git a/lib/subghz/protocols/marantec.h b/lib/subghz/protocols/marantec.h index 485c563b2..9a7b55b7e 100644 --- a/lib/subghz/protocols/marantec.h +++ b/lib/subghz/protocols/marantec.h @@ -107,3 +107,11 @@ SubGhzProtocolStatus * @param output Resulting text */ 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);