mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-07-16 00:18:11 -07:00
Merge commit '95dd537bf81ee445b1fb71aa60431cb62080333d' into mntm-dev
This commit is contained in:
+5
-1
@@ -9,8 +9,9 @@
|
||||
- UL: Treadmill37 protocol support (37bit static) (by @xMasterX)
|
||||
- UL: New modulation FSK with 12KHz deviation (by @xMasterX)
|
||||
- UL: KingGates Stylo 4k Add manually and button switch support and refactoring of encoder (by @xMasterX)
|
||||
- UL: Stilmatic button 9 support (two buttons hold simulation) (mapped on arrow keys) (by @xMasterX)
|
||||
- UL: Stilmatic (R-Tech) 12bit discr. fix & button 9 support (two buttons hold simulation) (mapped on arrow keys) (by @xMasterX)
|
||||
- UL: Sommer last button code 0x6 support (mapped on arrow keys) (by @xMasterX)
|
||||
- UL: V2 Phoenix (Phox) added 2 counter modes support (docs updated) (by @xMasterX)
|
||||
- UL: Add 390MHz and 430.5MHz to default hopper list (6 elements like in OFW) (works well with Hopper RSSI level set for your enviroment) (by @xMasterX)
|
||||
- UL: Docs: Add [full list of supported SubGHz protocols](https://github.com/Next-Flip/Momentum-Firmware/blob/dev/documentation/SubGHzSupportedSystems.md) and their frequencies/modulations that can be used for reading remotes (by @xMasterX)
|
||||
|
||||
@@ -34,6 +35,9 @@
|
||||
- UL: Sommer fm2 in Add manually now uses FM12K modulation (Sommer without fm2 tag uses FM476) (try this if regular option doesn't work for you) (by @xMasterX)
|
||||
- UL: Replaced Cars ignore option with Revers RB2 protocol ignore option (by @xMasterX)
|
||||
- UL: Improve docs on low level code (by @Dmitry422)
|
||||
- UL: KeeLoq display decrypted `Hop` instead of showing encrypted as is (encrypted non byte reversed hop is still displayed in `Key` field) (by @xMasterX)
|
||||
- UL: BFT KeeLoq try decoding with zero seed too (by @xMasterX)
|
||||
- UL: KeeLoq display BFT programming mode TX (when arrow button is held) (by @xMasterX)
|
||||
- Archive: Support opening and pinning ProtoPirate files from Archive (#510 by @LeeroysHub)
|
||||
|
||||
### Fixed:
|
||||
|
||||
@@ -47,6 +47,7 @@ static Protocols protocols[] = {
|
||||
{"CAME Atomo", 4},
|
||||
{"Alutech AT-4N", 3},
|
||||
{"KeeLoq", 7},
|
||||
{"Phoenix_V2", 3},
|
||||
};
|
||||
|
||||
#define PROTOCOLS_COUNT (sizeof(protocols) / sizeof(Protocols));
|
||||
|
||||
@@ -131,6 +131,24 @@ CounterMode: 1
|
||||
|
||||
---
|
||||
|
||||
### 5. V2 Phoenix (Phox)
|
||||
|
||||
**Mode 0 (Default):**
|
||||
- Standard - acts like regular remote
|
||||
- Uses rolling counter multiplier from global settings (default +1)
|
||||
- Counter increments based on the multiplier value (default +1)
|
||||
- Resets to 0 when overflow occurs (> 0xFFFF)
|
||||
|
||||
**Mode 1 (ofex like):**
|
||||
- Counter sequence: `0x0000 / 0x0001 / 0xFFFE / 0xFFFF`
|
||||
- Verified as working
|
||||
|
||||
**Mode 2 (0 - 4):**
|
||||
- Counter sequence: `0x0000 / 0x0001 / 0x0002 / 0x0003 / 0x0004`
|
||||
- Might work (let us know!)
|
||||
|
||||
---
|
||||
|
||||
## Notes and Warnings
|
||||
|
||||
### Important Considerations:
|
||||
|
||||
@@ -24,7 +24,7 @@ That list is only for default SubGHz app, apps like *Weather Station* have their
|
||||
- AN-Motors (Alutech) AT4 `433.92MHz` `AM650` (64 bits, Pseudo-Dynamic, KeeLoq based)
|
||||
- Ansonic `433MHz` `FM` (12 bits, Static)
|
||||
- BETT `433.92MHz` `AM650` (18 bits, Static)
|
||||
- Beninca ARC (TOGO2VA) `433.92MHz` `AM650` (128 bits, Dynamic AES)
|
||||
- Beninca ARC (TOGO2VA) `433.92MHz` `AM650` (128 bits, Dynamic AES) (button code `0` emulates `hidden button` option on the remote)
|
||||
- BFT Mitto `433.92MHz` `AM650` (64 bits, Dynamic, KeeLoq based with Seed)
|
||||
- CAME Atomo `433.92MHz, 868MHz` `AM650` (62 bits, Dynamic)
|
||||
- CAME TWEE `433.92MHz` `AM650` (54 bits, Static)
|
||||
@@ -50,7 +50,7 @@ That list is only for default SubGHz app, apps like *Weather Station* have their
|
||||
- Nice One `433.92MHz` `AM650` (72 bits, Dynamic)
|
||||
- Revers RB2 (Реверс РБ-2 (М)) `433.92MHz` `AM650` (64 bits, Static)
|
||||
- Roger `433.92MHz` `AM650` (28 bits, Static)
|
||||
- V2 Phoenix (Phox) `433.92MHz` `AM650` (52 bits, Dynamic)
|
||||
- V2 Phoenix (Phox) `433.92MHz` `AM650` (52 bits, Dynamic) (receivers have option to enable Static mode, making them ignore rolling part of the key)
|
||||
- Marantec `433.92MHz, 868MHz` `AM650` (49 bits, Static)
|
||||
- Marantec24 `868MHz` `AM650` (24 bits, Static)
|
||||
- Somfy Keytis `433.92MHz, 868MHz` `AM650` (80 bits, Dynamic)
|
||||
@@ -102,7 +102,7 @@ The following manufacturers have KeeLoq support in Unleashed firmware:
|
||||
- Aprimatic - `433.92MHz` `AM650` (KeeLoq, 64 bits) (12bit serial number art in Hop + 2bit "parity" in front of it replacing first 2 bits of serial)
|
||||
- Beninca - `433.92MHz, 868MHz` `AM650` (KeeLoq, 64 bits) (no serial part in Hop - magic XOR)
|
||||
- CAME Space - `433.92MHz` `AM650` (KeeLoq, 64 bits) (12bit serial part in Hop - simple learning)
|
||||
- Cardin S449 - `433.92MHz` `FSK12K` (KeeLoq, 64 bits) (12bit (original remotes) or 10bit (chinese remotes) serial part in Hop - normal learning)
|
||||
- Cardin S449 - `433.92MHz` `FSK12K` (KeeLoq, 64 bits) (12bit (original remotes) or 10bit (chinese remotes) serial part in Hop - normal learning) (receiver checks for 10bit only (unverified))
|
||||
- Centurion - `433.92MHz` `AM650` (KeeLoq, 64 bits) (no serial in Hop, uses fixed value 0x1CE - normal learning)
|
||||
- Comunello - `433.92MHz, 868MHz` `AM650` (KeeLoq, 64 bits) (normal learning)
|
||||
- DEA Mio - `433.92MHz` `AM650` (KeeLoq, 64 bits) (modified serial in Hop, uses last 3 digits modifying first one (example - 419 -> C19) - simple learning)
|
||||
@@ -128,7 +128,7 @@ The following manufacturers have KeeLoq support in Unleashed firmware:
|
||||
- Novoferm - `433.92MHz` `AM650` (KeeLoq, 64 bits)
|
||||
- Sommer `434.42MHz, 868.80MHz` `FSK12K (or FSK476)` (KeeLoq, 64 bits) (normal learning) (TX03-868-4, Pearl, and maybe other models are supported (SOMloq))
|
||||
- Steelmate - `433.92MHz` `AM650` (KeeLoq, 64 bits) (12bit serial part in Hop - normal learning)
|
||||
- Stilmatic - `433.92MHz` `AM650` (KeeLoq, 64 bits) (normal learning)
|
||||
- Stilmatic (R-Tech) - `433.92MHz` `AM650` (KeeLoq, 64 bits) (12bit serial part in Hop - normal learning) (receiver checks for 10bit only (unverified))
|
||||
|
||||
### Alarms, unknown origin, etc.
|
||||
- APS-1100/APS-2550 (KeeLoq, 64 bits)
|
||||
|
||||
@@ -97,7 +97,7 @@ const SubGhzProtocol subghz_protocol_keeloq = {
|
||||
* @param keystore Pointer to a SubGhzKeystore* instance
|
||||
* @param manufacture_name
|
||||
*/
|
||||
static void subghz_protocol_keeloq_check_remote_controller(
|
||||
static uint32_t subghz_protocol_keeloq_check_remote_controller(
|
||||
SubGhzBlockGeneric* instance,
|
||||
SubGhzKeystore* keystore,
|
||||
const char** manufacture_name);
|
||||
@@ -307,12 +307,14 @@ static bool subghz_protocol_keeloq_gen_data(
|
||||
(strcmp(instance->manufacture_name, "Rossi") == 0) ||
|
||||
(strcmp(instance->manufacture_name, "Pecinin") == 0) ||
|
||||
(strcmp(instance->manufacture_name, "Steelmate") == 0) ||
|
||||
(strcmp(instance->manufacture_name, "Cardin_S449") == 0)) {
|
||||
(strcmp(instance->manufacture_name, "Cardin_S449") == 0) ||
|
||||
(strcmp(instance->manufacture_name, "Stilmatic") == 0)) {
|
||||
// DTM Neo, Came_Space uses 12bit serial -> simple learning
|
||||
// FAAC_RC,XT , Mutanco_Mutancode, Genius_Bravo, GSN 12bit serial -> normal learning
|
||||
// Rosh, Rossi, Pecinin -> 12bit serial - simple learning
|
||||
// Steelmate -> 12bit serial - normal learning
|
||||
// Cardin_S449 -> 12bit serial - normal learning
|
||||
// Stilmatic (r-tech) -> 12bit serial - normal learning
|
||||
decrypt = btn << 28 | (instance->generic.serial & 0xFFF) << 16 |
|
||||
instance->generic.cnt;
|
||||
} else if(
|
||||
@@ -901,9 +903,9 @@ static inline bool subghz_protocol_keeloq_check_decrypt_centurion(
|
||||
* @param hop Hop encrypted part of the parcel
|
||||
* @param keystore Pointer to a SubGhzKeystore* instance
|
||||
* @param manufacture_name
|
||||
* @return true on successful search
|
||||
*/
|
||||
static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
* @return uint32_t decrypt data */
|
||||
|
||||
static uint32_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
SubGhzBlockGeneric* instance,
|
||||
uint32_t fix,
|
||||
uint32_t hop,
|
||||
@@ -926,7 +928,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
const char* mfname = keystore->mfname;
|
||||
|
||||
if(strcmp(mfname, "Unknown") == 0) {
|
||||
return 1;
|
||||
return 0;
|
||||
} else if(strcmp(mfname, "") == 0) {
|
||||
mf_not_set = true;
|
||||
}
|
||||
@@ -940,7 +942,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
keystore->mfname = *manufacture_name;
|
||||
return 1;
|
||||
return decrypt;
|
||||
}
|
||||
break;
|
||||
case KEELOQ_LEARNING_NORMAL:
|
||||
@@ -953,14 +955,14 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
if(subghz_protocol_keeloq_check_decrypt_centurion(instance, decrypt, btn)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
keystore->mfname = *manufacture_name;
|
||||
return 1;
|
||||
return decrypt;
|
||||
}
|
||||
} else {
|
||||
if(subghz_protocol_keeloq_check_decrypt(
|
||||
instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
keystore->mfname = *manufacture_name;
|
||||
return 1;
|
||||
return decrypt;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -978,9 +980,19 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
keystore->mfname = *manufacture_name;
|
||||
return 1;
|
||||
return decrypt;
|
||||
} else {
|
||||
if(reset_seed_back) instance->seed = 0;
|
||||
// Try with zero seed (some strange remotes have been reported to use 0 seed)
|
||||
man = subghz_protocol_keeloq_common_secure_learning(
|
||||
fix, instance->seed, manufacture_code->key);
|
||||
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man);
|
||||
if(subghz_protocol_keeloq_check_decrypt(
|
||||
instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
keystore->mfname = *manufacture_name;
|
||||
return decrypt;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case KEELOQ_LEARNING_MAGIC_XOR_TYPE_1:
|
||||
@@ -990,7 +1002,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
keystore->mfname = *manufacture_name;
|
||||
return 1;
|
||||
return decrypt;
|
||||
}
|
||||
break;
|
||||
case KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_1:
|
||||
@@ -1000,7 +1012,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
keystore->mfname = *manufacture_name;
|
||||
return 1;
|
||||
return decrypt;
|
||||
}
|
||||
break;
|
||||
case KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_2:
|
||||
@@ -1010,7 +1022,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
keystore->mfname = *manufacture_name;
|
||||
return 1;
|
||||
return decrypt;
|
||||
}
|
||||
break;
|
||||
case KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_3:
|
||||
@@ -1020,7 +1032,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) {
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
keystore->mfname = *manufacture_name;
|
||||
return 1;
|
||||
return decrypt;
|
||||
}
|
||||
break;
|
||||
case KEELOQ_LEARNING_UNKNOWN:
|
||||
@@ -1030,7 +1042,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
keystore->mfname = *manufacture_name;
|
||||
keystore->kl_type = 1;
|
||||
return 1;
|
||||
return decrypt;
|
||||
}
|
||||
|
||||
// Check for mirrored man
|
||||
@@ -1046,7 +1058,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
keystore->mfname = *manufacture_name;
|
||||
keystore->kl_type = 1;
|
||||
return 1;
|
||||
return decrypt;
|
||||
}
|
||||
|
||||
//###########################
|
||||
@@ -1059,7 +1071,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
keystore->mfname = *manufacture_name;
|
||||
keystore->kl_type = 2;
|
||||
return 1;
|
||||
return decrypt;
|
||||
}
|
||||
|
||||
// Check for mirrored man
|
||||
@@ -1069,7 +1081,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
keystore->mfname = *manufacture_name;
|
||||
keystore->kl_type = 2;
|
||||
return 1;
|
||||
return decrypt;
|
||||
}
|
||||
|
||||
// Secure Learning
|
||||
@@ -1080,7 +1092,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
keystore->mfname = *manufacture_name;
|
||||
keystore->kl_type = 3;
|
||||
return 1;
|
||||
return decrypt;
|
||||
}
|
||||
|
||||
// Check for mirrored man
|
||||
@@ -1091,7 +1103,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
keystore->mfname = *manufacture_name;
|
||||
keystore->kl_type = 3;
|
||||
return 1;
|
||||
return decrypt;
|
||||
}
|
||||
|
||||
// Magic xor type1 learning
|
||||
@@ -1102,7 +1114,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
keystore->mfname = *manufacture_name;
|
||||
keystore->kl_type = 4;
|
||||
return 1;
|
||||
return decrypt;
|
||||
}
|
||||
|
||||
// Check for mirrored man
|
||||
@@ -1112,7 +1124,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
|
||||
keystore->mfname = *manufacture_name;
|
||||
keystore->kl_type = 4;
|
||||
return 1;
|
||||
return decrypt;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -1128,7 +1140,7 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void subghz_protocol_keeloq_check_remote_controller(
|
||||
static uint32_t subghz_protocol_keeloq_check_remote_controller(
|
||||
SubGhzBlockGeneric* instance,
|
||||
SubGhzKeystore* keystore,
|
||||
const char** manufacture_name) {
|
||||
@@ -1137,6 +1149,7 @@ static void subghz_protocol_keeloq_check_remote_controller(
|
||||
uint32_t key_fix = key >> 32;
|
||||
uint32_t key_hop = key & 0x00000000ffffffff;
|
||||
static uint16_t temp_counter = 0; // Be careful with prog_mode
|
||||
uint32_t resdecrypt = 0;
|
||||
|
||||
// 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();
|
||||
@@ -1161,7 +1174,7 @@ static void subghz_protocol_keeloq_check_remote_controller(
|
||||
keystore->mfname = *manufacture_name;
|
||||
instance->cnt = key_hop >> 16;
|
||||
} else {
|
||||
subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
resdecrypt = subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
instance, key_fix, key_hop, keystore, manufacture_name);
|
||||
}
|
||||
} else {
|
||||
@@ -1178,7 +1191,7 @@ static void subghz_protocol_keeloq_check_remote_controller(
|
||||
instance->cnt = key_hop >> 16;
|
||||
} else {
|
||||
// Else we have mfname that is not AN-Motors or HCS101 we should check it via default selector
|
||||
subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
resdecrypt = subghz_protocol_keeloq_check_remote_controller_selector(
|
||||
instance, key_fix, key_hop, keystore, manufacture_name);
|
||||
}
|
||||
}
|
||||
@@ -1215,6 +1228,8 @@ static void subghz_protocol_keeloq_check_remote_controller(
|
||||
}
|
||||
// Set max custom buttons
|
||||
subghz_custom_btn_set_max(4);
|
||||
|
||||
return resdecrypt;
|
||||
}
|
||||
|
||||
uint32_t subghz_protocol_decoder_keeloq_get_hash_data(void* context) {
|
||||
@@ -1485,7 +1500,9 @@ void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderKeeloq* instance = context;
|
||||
|
||||
subghz_protocol_keeloq_check_remote_controller(
|
||||
uint32_t hopdecrypt = 0;
|
||||
|
||||
hopdecrypt = subghz_protocol_keeloq_check_remote_controller(
|
||||
&instance->generic, instance->keystore, &instance->manufacture_name);
|
||||
|
||||
uint32_t code_found_hi = instance->generic.data >> 32;
|
||||
@@ -1500,23 +1517,44 @@ void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output
|
||||
subghz_block_generic_global.cnt_is_available = true;
|
||||
subghz_block_generic_global.cnt_length_bit = 16;
|
||||
subghz_block_generic_global.current_cnt = instance->generic.cnt;
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:%08lX%08lX\r\n"
|
||||
"Fix:0x%08lX Cnt:%04lX\r\n"
|
||||
"Hop:0x%08lX Btn:%01X\r\n"
|
||||
"MF:%s Sd:%08lX",
|
||||
instance->generic.protocol_name,
|
||||
instance->generic.data_count_bit,
|
||||
code_found_hi,
|
||||
code_found_lo,
|
||||
code_found_reverse_hi,
|
||||
instance->generic.cnt,
|
||||
code_found_reverse_lo,
|
||||
instance->generic.btn,
|
||||
instance->manufacture_name,
|
||||
instance->generic.seed);
|
||||
ProgMode prog_mode = subghz_custom_btn_get_prog_mode();
|
||||
if(prog_mode == PROG_MODE_KEELOQ_BFT) {
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:%08lX%08lX\r\n"
|
||||
"Fix:0x%08lX Cnt:%04lX\r\n"
|
||||
"Hop:0x%08lX Btn:%01X\r\n"
|
||||
"MF:%s PRG Sd:%08lX",
|
||||
instance->generic.protocol_name,
|
||||
instance->generic.data_count_bit,
|
||||
code_found_hi,
|
||||
code_found_lo,
|
||||
code_found_reverse_hi,
|
||||
instance->generic.cnt,
|
||||
code_found_reverse_lo,
|
||||
instance->generic.btn,
|
||||
instance->manufacture_name,
|
||||
instance->generic.seed);
|
||||
} else {
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:%08lX%08lX\r\n"
|
||||
"Fix:0x%08lX Cnt:%04lX\r\n"
|
||||
"Hop:0x%08lX Btn:%01X\r\n"
|
||||
"MF:%s Sd:%08lX",
|
||||
instance->generic.protocol_name,
|
||||
instance->generic.data_count_bit,
|
||||
code_found_hi,
|
||||
code_found_lo,
|
||||
code_found_reverse_hi,
|
||||
instance->generic.cnt,
|
||||
hopdecrypt,
|
||||
instance->generic.btn,
|
||||
instance->manufacture_name,
|
||||
instance->generic.seed);
|
||||
}
|
||||
} else if(strcmp(instance->manufacture_name, "Unknown") == 0) {
|
||||
instance->generic.cnt = 0x0;
|
||||
furi_string_cat_printf(
|
||||
@@ -1551,7 +1589,7 @@ void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output
|
||||
code_found_lo,
|
||||
code_found_reverse_hi,
|
||||
instance->generic.cnt,
|
||||
code_found_reverse_lo,
|
||||
hopdecrypt,
|
||||
instance->generic.btn,
|
||||
instance->manufacture_name);
|
||||
}
|
||||
|
||||
@@ -93,6 +93,8 @@ void subghz_protocol_encoder_phoenix_v2_free(void* context) {
|
||||
free(instance);
|
||||
}
|
||||
|
||||
static uint8_t v2_phoenix_counter_mode = 0;
|
||||
|
||||
// Pre define functions
|
||||
static uint16_t subghz_protocol_phoenix_v2_encrypt_counter(uint64_t full_key, uint16_t counter);
|
||||
static void subghz_protocol_phoenix_v2_check_remote_controller(SubGhzBlockGeneric* instance);
|
||||
@@ -254,18 +256,30 @@ static bool
|
||||
btn = subghz_protocol_phoenix_v2_get_btn_code();
|
||||
|
||||
// Reconstruction of the data
|
||||
// Check for OFEX (overflow experimental) mode
|
||||
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
|
||||
// standart counter mode. PULL data from subghz_block_generic_global variables
|
||||
if(!subghz_block_generic_global_counter_override_get(&instance->generic.cnt)) {
|
||||
// if counter_override_get return FALSE then counter was not changed and we increase counter by standart mult value
|
||||
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) {
|
||||
if(v2_phoenix_counter_mode == 0) {
|
||||
// Check for OFEX (overflow experimental) mode
|
||||
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
|
||||
// standart counter mode. PULL data from subghz_block_generic_global variables
|
||||
if(!subghz_block_generic_global_counter_override_get(&instance->generic.cnt)) {
|
||||
// if counter_override_get return FALSE then counter was not changed and we increase counter by standart mult value
|
||||
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) {
|
||||
instance->generic.cnt = 0;
|
||||
} else {
|
||||
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if((instance->generic.cnt + 0x1) > 0xFFFF) {
|
||||
instance->generic.cnt = 0;
|
||||
} else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) {
|
||||
instance->generic.cnt = 0xFFFE;
|
||||
} else {
|
||||
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
|
||||
instance->generic.cnt++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if(v2_phoenix_counter_mode == 1) {
|
||||
// Mode 1 (ofex like)
|
||||
// 0000 / 0001 / FFFE / FFFF
|
||||
if((instance->generic.cnt + 0x1) > 0xFFFF) {
|
||||
instance->generic.cnt = 0;
|
||||
} else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) {
|
||||
@@ -273,6 +287,14 @@ static bool
|
||||
} else {
|
||||
instance->generic.cnt++;
|
||||
}
|
||||
} else {
|
||||
// Mode 2 (0 to 4)
|
||||
// 0x0000 / 0x0001 / 0x0002 / 0x0003 / 0x0004
|
||||
if(instance->generic.cnt >= 0x0004) {
|
||||
instance->generic.cnt = 0;
|
||||
} else {
|
||||
instance->generic.cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t local_data_rev = subghz_protocol_blocks_reverse_key(
|
||||
@@ -328,6 +350,18 @@ SubGhzProtocolStatus
|
||||
flipper_format_read_uint32(
|
||||
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
|
||||
|
||||
if(!flipper_format_rewind(flipper_format)) {
|
||||
FURI_LOG_E(TAG, "Rewind error");
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t tmp_counter_mode;
|
||||
if(flipper_format_read_uint32(flipper_format, "CounterMode", &tmp_counter_mode, 1)) {
|
||||
v2_phoenix_counter_mode = (uint8_t)tmp_counter_mode;
|
||||
} else {
|
||||
v2_phoenix_counter_mode = 0;
|
||||
}
|
||||
|
||||
subghz_protocol_phoenix_v2_check_remote_controller(&instance->generic);
|
||||
|
||||
if(!subghz_protocol_encoder_phoenix_v2_get_upload(instance)) {
|
||||
@@ -335,6 +369,11 @@ SubGhzProtocolStatus
|
||||
break;
|
||||
}
|
||||
|
||||
if(!flipper_format_rewind(flipper_format)) {
|
||||
FURI_LOG_E(TAG, "Rewind error");
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t key_data[sizeof(uint64_t)] = {0};
|
||||
for(size_t i = 0; i < sizeof(uint64_t); i++) {
|
||||
key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data >> i * 8) & 0xFF;
|
||||
@@ -584,10 +623,25 @@ SubGhzProtocolStatus
|
||||
subghz_protocol_decoder_phoenix_v2_deserialize(void* context, FlipperFormat* flipper_format) {
|
||||
furi_assert(context);
|
||||
SubGhzProtocolDecoderPhoenix_V2* instance = context;
|
||||
return subghz_block_generic_deserialize_check_count_bit(
|
||||
SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
|
||||
|
||||
ret = subghz_block_generic_deserialize_check_count_bit(
|
||||
&instance->generic,
|
||||
flipper_format,
|
||||
subghz_protocol_phoenix_v2_const.min_count_bit_for_found);
|
||||
|
||||
if(!flipper_format_rewind(flipper_format)) {
|
||||
FURI_LOG_E(TAG, "Rewind error");
|
||||
return SubGhzProtocolStatusError;
|
||||
}
|
||||
|
||||
uint32_t tmp_counter_mode;
|
||||
if(flipper_format_read_uint32(flipper_format, "CounterMode", &tmp_counter_mode, 1)) {
|
||||
v2_phoenix_counter_mode = (uint8_t)tmp_counter_mode;
|
||||
} else {
|
||||
v2_phoenix_counter_mode = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void subghz_protocol_decoder_phoenix_v2_get_string(void* context, FuriString* output) {
|
||||
|
||||
Reference in New Issue
Block a user