From 830dbc7a715cc0858af80c1708d6bcbde83b4f8c Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Sun, 28 Jan 2024 22:47:47 +0300 Subject: [PATCH] subghz dea_mio fixes and programming mode support --- .../subghz/scenes/subghz_scene_set_type.c | 8 ++++- lib/subghz/blocks/custom_btn_i.h | 1 + lib/subghz/protocols/keeloq.c | 34 +++++++++++++++---- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/applications/main/subghz/scenes/subghz_scene_set_type.c b/applications/main/subghz/scenes/subghz_scene_set_type.c index cd07b30bb2..17f358fa6e 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_type.c +++ b/applications/main/subghz/scenes/subghz_scene_set_type.c @@ -761,7 +761,13 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { break; case SubmenuIndexDeaMio433: generated_protocol = subghz_txrx_gen_keeloq_protocol( - subghz->txrx, "AM650", 433920000, key & 0x00FFFFFF, 0x2, 0x0003, "Dea_Mio"); + subghz->txrx, + "AM650", + 433920000, + (key & 0x0FFFF000) | 0x00000869, + 0x2, + 0x0003, + "Dea_Mio"); if(!generated_protocol) { furi_string_set( subghz->error_str, "Function requires\nan SD card with\nfresh databases."); diff --git a/lib/subghz/blocks/custom_btn_i.h b/lib/subghz/blocks/custom_btn_i.h index 33ea6be9f1..aafcc82da8 100644 --- a/lib/subghz/blocks/custom_btn_i.h +++ b/lib/subghz/blocks/custom_btn_i.h @@ -5,6 +5,7 @@ #define PROG_MODE_OFF (0U) #define PROG_MODE_KEELOQ_BFT (1U) #define PROG_MODE_KEELOQ_APRIMATIC (2U) +#define PROG_MODE_KEELOQ_DEA_MIO (3U) typedef uint8_t ProgMode; diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index 3a6ee57969..14341a4086 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -159,6 +159,13 @@ static bool subghz_protocol_keeloq_gen_data( } else if(prog_mode == PROG_MODE_KEELOQ_APRIMATIC) { prog_mode = PROG_MODE_OFF; } + } else if(strcmp(instance->manufacture_name, "Dea_Mio") == 0) { + // Dea_Mio programming mode on / off conditions + if(btn == 0xF) { + prog_mode = PROG_MODE_KEELOQ_DEA_MIO; + } else if(prog_mode == PROG_MODE_KEELOQ_DEA_MIO) { + prog_mode = PROG_MODE_OFF; + } } subghz_custom_btn_set_prog_mode(prog_mode); @@ -168,6 +175,9 @@ static bool subghz_protocol_keeloq_gen_data( } else if(prog_mode == PROG_MODE_KEELOQ_APRIMATIC) { // If we using Aprimatic programming mode we will trasmit some strange looking hop value, why? cuz manufacturer did it this way :) hop = 0x1A2B3C4D; + } else if(prog_mode == PROG_MODE_KEELOQ_DEA_MIO) { + // If we using DEA Mio programming mode we will trasmit only FIX value with button code 0xF, hop is zero + hop = 0x00000000; } if(counter_up && prog_mode == PROG_MODE_OFF) { // Counter increment conditions @@ -244,9 +254,13 @@ static bool subghz_protocol_keeloq_gen_data( decrypt = btn << 28 | (0x1CE) << 16 | instance->generic.cnt; // Centurion -> no serial in hop, uses fixed value 0x1CE - normal learning } else if(strcmp(instance->manufacture_name, "Dea_Mio") == 0) { - uint32_t dea_serial = (instance->generic.serial & 0xFFF) + 0x800; + uint8_t first_disc_num = (instance->generic.serial >> 8) & 0xF; + uint8_t result_disc = (0xC + ((first_disc_num % 4) ? 2 : 0)); + uint32_t dea_serial = (instance->generic.serial & 0xFF) | + (((uint32_t)result_disc) << 8); decrypt = btn << 28 | (dea_serial & 0xFFF) << 16 | instance->generic.cnt; - // Dea_Mio -> modified serial in hop, uses last 3 digits adding +8 to first one (example - 419 -> C19) - simple learning + // Dea_Mio -> modified serial in hop, uses last 3 digits modifying first one (example - 419 -> C19) + // (see formula in result_disc var) - simple learning } // Old type selector fixage for compatibilitiy with old signal files uint8_t kl_type_en = instance->keystore->kl_type; @@ -315,7 +329,7 @@ static bool subghz_protocol_keeloq_gen_data( } } } - if(hop) { + if(hop || (prog_mode == PROG_MODE_KEELOQ_DEA_MIO) || (prog_mode == PROG_MODE_KEELOQ_BFT)) { // If we have hop - we will save it to generic data var that will be used later in transmission uint64_t yek = (uint64_t)fix << 32 | hop; instance->generic.data = @@ -404,11 +418,14 @@ static bool instance->manufacture_name = "BFT"; } else if(prog_mode == PROG_MODE_KEELOQ_APRIMATIC) { instance->manufacture_name = "Aprimatic"; + } else if(prog_mode == PROG_MODE_KEELOQ_DEA_MIO) { + instance->manufacture_name = "Dea_Mio"; } - // Custom button (programming mode button) for BFT and Aprimatic + // Custom button (programming mode button) for BFT, Aprimatic, Dea_Mio uint8_t klq_last_custom_btn = 0xA; if((strcmp(instance->manufacture_name, "BFT") == 0) || - (strcmp(instance->manufacture_name, "Aprimatic") == 0)) { + (strcmp(instance->manufacture_name, "Aprimatic") == 0) || + (strcmp(instance->manufacture_name, "Dea_Mio") == 0)) { klq_last_custom_btn = 0xF; } @@ -981,7 +998,7 @@ static void subghz_protocol_keeloq_check_remote_controller( uint32_t key_hop = key & 0x00000000ffffffff; static uint16_t temp_counter = 0; // Be careful with prog_mode - // If we are in BFT / Aprimatic programming mode we will set previous remembered counter and skip mf keys check + // If we are in BFT / Aprimatic / Dea_Mio programming mode we will set previous remembered counter and skip mf keys check ProgMode prog_mode = subghz_custom_btn_get_prog_mode(); if(prog_mode == PROG_MODE_OFF) { if(keystore->mfname == 0x0) { @@ -1038,6 +1055,11 @@ static void subghz_protocol_keeloq_check_remote_controller( *manufacture_name = "Aprimatic"; keystore->mfname = *manufacture_name; instance->cnt = temp_counter; + } else if(prog_mode == PROG_MODE_KEELOQ_DEA_MIO) { + // When we are in prog mode we should fix mfname and apply temp counter + *manufacture_name = "Dea_Mio"; + keystore->mfname = *manufacture_name; + instance->cnt = temp_counter; } else { // Counter protection furi_crash("Unsupported Prog Mode");