From 63d49b6e48533c8a182f3d0af97c59e629f07706 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 21 Apr 2026 03:31:11 +0300 Subject: [PATCH] subghz upgrades [ci skip] docs update pr template update changelog update --- .github/pull_request_template.md | 20 +- CHANGELOG.md | 7 +- .../main/subghz/helpers/subghz_custom_event.h | 14 ++ .../main/subghz/helpers/subghz_gen_info.c | 153 +++++++++++++- .../main/subghz/helpers/subghz_gen_info.h | 4 +- .../helpers/subghz_txrx_create_protocol_key.c | 6 +- .../helpers/subghz_txrx_create_protocol_key.h | 2 +- .../resources/subghz/assets/keeloq_mfcodes | 190 +++++++++++------- .../subghz/scenes/subghz_scene_set_button.c | 8 +- .../subghz/scenes/subghz_scene_set_counter.c | 12 +- .../subghz/scenes/subghz_scene_set_seed.c | 22 +- .../subghz/scenes/subghz_scene_set_serial.c | 14 +- .../subghz/scenes/subghz_scene_set_type.c | 30 ++- documentation/SubGHzSupportedSystems.md | 56 +++++- lib/nfc/protocols/mf_desfire/mf_desfire_i.c | 4 +- .../mf_ultralight/mf_ultralight_listener.c | 4 + lib/subghz/protocols/came_atomo.c | 56 +++++- lib/subghz/protocols/keeloq.c | 100 ++++++++- lib/subghz/protocols/keeloq_common.c | 94 +++++++++ lib/subghz/protocols/keeloq_common.h | 20 ++ lib/subghz/protocols/public_api.h | 2 +- targets/f7/api_symbols.csv | 2 +- 22 files changed, 673 insertions(+), 147 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 4bc69d8e6..234fbe7c5 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -6,8 +6,22 @@ - [ Describe how to verify changes ] -# Checklist (For Reviewer) +# Author Checklist (Fill this out): -- [ ] PR has description of feature/bug -- [ ] Description contains actions to verify feature/bugfix +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation (if it exists) + +# AI usage disclosure (Fill this out): + +- [ ] Partially AI assisted (clarify below which code was AI assisted and briefly explain what it does). +- [ ] Fully AI generated (explain what all the generated code does in moderate detail). + +- [ Describe how AI was used in this PR if it was used ] + +# Checklist (For Reviewer) (Don't fill this out!): + +- [ ] PR has proper description of new feature/bugfix +- [ ] Description contains actions to verify feature/bugfix on the hardware +- [ ] No obvious issues with the code was found - [ ] I've built this code, uploaded it to the device and verified feature/bugfix diff --git a/CHANGELOG.md b/CHANGELOG.md index d432473eb..428c8e8f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ ## Main changes -- Current API: 87.6 +- Current API: 87.7 +* SubGHz: Add support for **42+ Keeloq based systems** (with partial Add Manually support) (see [Full list](/documentation/SubGHzSupportedSystems.md)) (by @zero-mega, @xMasterX, ARF Team) * SubGHz: Add **Nord ICE** protocol (33 bits, Static) +* SubGHz: **Better support for CAME Atomo** type remotes (TOPD4REN) (decode + button codes) (thx to Roman for raw recordings) * SubGHz: Add **CAME TOP44FGN** support in CAME TWEE protocol * SubGHz: Add all 0x0s and all 0xFs KeeLoq MF codes for normal and simple learning * SubGHz: **Fix CAME TWEE repeats count for button click** @@ -9,7 +11,8 @@ * NFC: Add **Mifare Ultralight C Write Support** (by @haw8411) * NFC: Add **new parsers SZPPK, SKPPK and SevPPK**, upgrade Plantain parser, fix TwoCities parser (PR #981 | by @mxcdoam) * OFW PR 4362: NFC: **Fix BusFault** in Write to Initial Card (by @akrylysov) -* Apps: Build tag (**1apr2026**) - **Check out more Apps updates and fixes by following** [this link](https://github.com/xMasterX/all-the-plugins/commits/dev) +* OFW PR 4369: NFC: Fix stack buffer overflows in MFUL FAST_READ and DESFire file settings parsers (by @qp-x-qp) +* Apps: Build tag (**21apr2026**) - **Check out more Apps updates and fixes by following** [this link](https://github.com/xMasterX/all-the-plugins/commits/dev) ## Other changes * OFW PR 4364: JS: Address utf8 support when uploading JavaScript application (by @bekindpleaserewind) * Display: Extend lcd contrast range to full ST756x 6-bit range (by @ShaTie) (reduced to -10 to +18 to avoid fully unreadable state) diff --git a/applications/main/subghz/helpers/subghz_custom_event.h b/applications/main/subghz/helpers/subghz_custom_event.h index ebb120929..63b590bfc 100644 --- a/applications/main/subghz/helpers/subghz_custom_event.h +++ b/applications/main/subghz/helpers/subghz_custom_event.h @@ -69,6 +69,7 @@ typedef enum { SetTypeFaacSLH_868, SetTypeFaacSLH_433, SetTypeBFTMitto, + SetTypeErreka433, SetTypeSomfyTelis, SetTypeSomfyKeytis, SetTypeKingGatesStylo4k, @@ -109,6 +110,19 @@ typedef enum { SetTypeNovoferm_433_92, SetTypeHormannEcoStar_433_92, SetTypeCardinS449_433FM, + SetTypePujol433, + SetTypePujol_Vario433, + SetTypeET_Blue433, + SetTypeET_Blue_Mix433, + SetTypeATA_PTX4_433, + SetTypeSeav433, + SetTypeWisniowski433, + SetTypeFadini433, + SetTypeMc_Garcia433, + SetTypeClemsa_Mutancode433, + SetTypeDoormatic433, + SetTypeElvox433, + SetTypeVerex433, SetTypeFAACRCXT_433_92, SetTypeFAACRCXT_868, SetTypeGeniusBravo433, diff --git a/applications/main/subghz/helpers/subghz_gen_info.c b/applications/main/subghz/helpers/subghz_gen_info.c index db3f2926a..7feaea887 100644 --- a/applications/main/subghz/helpers/subghz_gen_info.c +++ b/applications/main/subghz/helpers/subghz_gen_info.c @@ -496,14 +496,25 @@ void subghz_scene_set_type_fill_generation_infos(GenInfo* infos_dest, SetType ty break; case SetTypeBFTMitto: gen_info = (GenInfo){ - .type = GenKeeloqBFT, + .type = GenKeeloqSeed, .mod = "AM650", .freq = 433920000, - .keeloq_bft.serial = key & 0x000FFFFF, - .keeloq_bft.btn = 0x02, - .keeloq_bft.cnt = 0x02, - .keeloq_bft.seed = key & 0x000FFFFF, - .keeloq_bft.manuf = "BFT"}; + .keeloq_seed.serial = key & 0x000FFFFF, + .keeloq_seed.btn = 0x02, + .keeloq_seed.cnt = 0x02, + .keeloq_seed.seed = key & 0x000FFFFF, + .keeloq_seed.manuf = "BFT"}; + break; + case SetTypeErreka433: + gen_info = (GenInfo){ + .type = GenKeeloqSeed, + .mod = "AM650", + .freq = 433920000, + .keeloq_seed.serial = key & 0x000FFFFF, + .keeloq_seed.btn = 0x02, + .keeloq_seed.cnt = 0x02, + .keeloq_seed.seed = key & 0x000FFFFF, + .keeloq_seed.manuf = "Erreka"}; break; case SetTypeAlutechAT4N: gen_info = (GenInfo){ @@ -698,6 +709,136 @@ void subghz_scene_set_type_fill_generation_infos(GenInfo* infos_dest, SetType ty .keeloq.cnt = 0x03, .keeloq.manuf = "Cardin_S449"}; break; + case SetTypePujol433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Pujol"}; + break; + case SetTypeET_Blue433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x04, + .keeloq.cnt = 0x03, + .keeloq.manuf = "ET_Blue"}; + break; + case SetTypeET_Blue_Mix433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x04, + .keeloq.cnt = 0x03, + .keeloq.manuf = "ET_Blue_Mix"}; + break; + case SetTypeATA_PTX4_433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "ATA_PTX4"}; + break; + case SetTypePujol_Vario433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Pujol_Vario"}; + break; + case SetTypeSeav433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Seav"}; + break; + case SetTypeWisniowski433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Wisniowski"}; + break; + case SetTypeFadini433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Fadini"}; + break; + case SetTypeMc_Garcia433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Mc_Garcia"}; + break; + case SetTypeClemsa_Mutancode433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Clemsa_Mutancode"}; + break; + case SetTypeDoormatic433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Doormatic"}; + break; + case SetTypeElvox433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Elvox"}; + break; + case SetTypeVerex433: + gen_info = (GenInfo){ + .type = GenKeeloq, + .mod = "AM650", + .freq = 433920000, + .keeloq.serial = key & 0x00FFFFFF, + .keeloq.btn = 0x02, + .keeloq.cnt = 0x03, + .keeloq.manuf = "Verex"}; + break; case SetTypeFAACRCXT_433_92: gen_info = (GenInfo){ .type = GenKeeloq, diff --git a/applications/main/subghz/helpers/subghz_gen_info.h b/applications/main/subghz/helpers/subghz_gen_info.h index 60212801c..8fcfb92fc 100644 --- a/applications/main/subghz/helpers/subghz_gen_info.h +++ b/applications/main/subghz/helpers/subghz_gen_info.h @@ -7,7 +7,7 @@ typedef enum { GenFaacSLH, GenKeeloq, GenCameAtomo, - GenKeeloqBFT, + GenKeeloqSeed, GenAlutechAt4n, GenSomfyTelis, GenSomfyKeytis, @@ -55,7 +55,7 @@ typedef struct { uint16_t cnt; uint32_t seed; const char* manuf; - } keeloq_bft; + } keeloq_seed; struct { uint32_t serial; uint8_t btn; 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 11bb70ed9..4601cbc28 100644 --- a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c +++ b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c @@ -125,7 +125,7 @@ bool subghz_txrx_gen_keeloq_protocol( //TODO lead to a general appearance return res; } -bool subghz_txrx_gen_keeloq_bft_protocol( +bool subghz_txrx_gen_keeloq_seed_protocol( void* context, const char* preset_name, uint32_t frequency, @@ -142,7 +142,7 @@ bool subghz_txrx_gen_keeloq_bft_protocol( subghz_transmitter_alloc_init(txrx->environment, SUBGHZ_PROTOCOL_KEELOQ_NAME); subghz_txrx_set_preset(txrx, preset_name, frequency, NULL, 0); - if(txrx->transmitter && subghz_protocol_keeloq_bft_create_data( + if(txrx->transmitter && subghz_protocol_keeloq_seed_create_data( subghz_transmitter_get_protocol_instance(txrx->transmitter), txrx->fff_data, serial, @@ -162,7 +162,7 @@ bool subghz_txrx_gen_keeloq_bft_protocol( flipper_format_write_hex(txrx->fff_data, "Seed", seed_data, sizeof(uint32_t)); - flipper_format_write_string_cstr(txrx->fff_data, "Manufacture", "BFT"); + flipper_format_write_string_cstr(txrx->fff_data, "Manufacture", manufacture_name); } subghz_transmitter_free(txrx->transmitter); 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 811724584..d9d8bbb0a 100644 --- a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.h +++ b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.h @@ -63,7 +63,7 @@ bool subghz_txrx_gen_keeloq_protocol( uint16_t cnt, const char* manufacture_name); -bool subghz_txrx_gen_keeloq_bft_protocol( +bool subghz_txrx_gen_keeloq_seed_protocol( void* context, const char* preset_name, uint32_t frequency, diff --git a/applications/main/subghz/resources/subghz/assets/keeloq_mfcodes b/applications/main/subghz/resources/subghz/assets/keeloq_mfcodes index 572bda5cc..2772b0e39 100644 --- a/applications/main/subghz/resources/subghz/assets/keeloq_mfcodes +++ b/applications/main/subghz/resources/subghz/assets/keeloq_mfcodes @@ -1,76 +1,120 @@ Filetype: Flipper SubGhz Keystore File Version: 0 Encryption: 1 -IV: 4E 6F 74 69 63 65 73 20 62 75 6C 67 65 55 77 55 -DD5D658073C2C257430FD30815480D300A4FAA72750B741431D90E7B74C6F94B -D30DBA9B63C4A5A47E6F1462819706F347B4524FB0342729B454791ECB491338 -4BF3E836BECF53BF8ECADC9E35EB94A6F2A424C4918226B7B2F3B0102BB28AFB61610BF188269855559DDEF49413635B -96BD4E3E3D02094DFE3C4E5CCBC8ED7BE679ACE3C83ADF1433BA4E08576E610D -99B4D5475099E999558BBBCFC5083B08BB99FF7F9E8EFEB222388750CBA464CD -DA94EF9FED763E6625C2FA839C8A288986664EFD12575D21575B6C77345EC6A2 -FD0A76366C8F84C2BF080A40EB6573CF41AFA51138320C187BDDB1E40CEA35E8 -5C375767AB4BE93E3A10875B4B006D4264FD9FB606381A8878AF4EC960EFC849 -01297BF2D4372C5FC376E79835D8D5A382F76E3D9367E2FA81F54C10BDB2FDA8 -415FE673D1CDAE0E7141EA78326573987E51353C91992E334FCD030E3172B8C6 -C6EA321FA06DBD86D328B5CBBCFE94628DA3D415463835229F1224EAB5F8B181 -6468B83FB26298BD496299D64DAE0F2D12B081CDE9B83AA5B19500162D7DA6E8 -2569E458EFFE0725581F7490CBF416B3E8E64C1D0F2C13DEA5BE926475F631DC -857A04B029277DA403276CADE88EAD4956A959AB9C652614F435DCE1B3B92215 -A08B60A323178B3A8644D0018C705E5E13F5F34DB41132348CEDBBCB6C75164F -A171F6CEEB240D1117DF8A5396B4E468EB03D8AA315321FA19F01E67145A861E -4255FAC9CD843A206D89D6D5204409193E594AE73D5E490F84F39DC76A0C6C23 -589E6270609485D8FEA3029A23C3084F48FB5384939ACF447CA289C4282F38BA -D1B349CF3C402BCF7F87FEF5A19E8C2748D52715092EC5668C3C61A15958F7F2 -34191142584299F22C0A007EC8E333646E57C6B406C103795ED4A2731CAF55A5 -158809D80C052D780C8AA05F88AF67FF4CF93234A7F7A78B5AA11F067623AD2D -81C22401A96674BB64D3512AEEB5F8A060537AFE1D4F2BB31ADB237E1BC61FC0 -C732F26FEC449F545CD379BF9AD2AC2769EDA98C0D7163A69E37EE17853E98AF -59375DCD3703B87223DE49174274CD28FF95BA077357A10304FC3B44E679CA91 -E9E9E87E1098CCB6C3799EB31D91E9C77EF243164FE98DAA688B22CD8ED7D944 -AC0319E2F9D0520357E61B88B17D293AE32B68661484890AEBCBADA0E7C47C40 -865F354CA28D9AABFFB3ABBD15CB22ECBDC937D292AA2D72B9D7457E870E9117 -7D2D90D3D583F77F60C8782E61011D52A452FC33F8B5E6A8AD6A2378F2819D3B -FC3C20DA524C0E1D43881F15605E18B58D9E804D15F01AB3DC9850D472C4C3A1 -25C03EAA292F03155ACD4C599030C159C2F085970B2BD905A6CF42E69D5E7BF4 -F84099879C1BD93BD77489CBEE9DB22F7F4688480A5DB9F1CF8359ADAA456B10 -21A4BE7E01B1848FB26E7CFEAD9FA841F4B80C4C2C84D07F6737F61E1FB4F4F3 -8094BD23328B5854C11FE696D21F1F58C280DC6D31F7F6B56F99E04D83949EFD -B87664A507982A6103904E81BF7D6AE1222E038D405EE84F3B5E84F4E3D6BFC7 -F102B622433FCBA3910DA43309D67FC46BE7A472BAAF8CDDEFFCD796D23DB122 -D3A015CE7E7D9CD23CED808CC72CBB42A09C5D718B58C04E1E25B3D7F46BCBB3 -02E1C8124D6B955689193369C87BDFCC66C0750E65EED7D7592E6EECA83BF1CA -4A37AC36B48DF89D664CC0390F2B1AAF553EBC2C661D14E5DDA2016C66946FF6 -3087AB22BF5A72376A888C26846B15DF842E70F8AE113E64BC855B2BA4801831 -562ED92C172D0B20799D0FDC565AED5B2A771249ACBA7D8F33176B99B3C4CD88 -448D6DEAC1C01D1B96EBB480D22A5AD011DC36655D8318BACCEE630F9BA5CC20 -2F9C204D0A2E7A5686F7684E438DC3DCEE400AE23306D6B604A5905DB33DBF0F -50A7E7773F4BCA75247E2E9ACF9025F5DF0370A2C20E2ECE8EDC00F25761D158 -2F2B0A5F9A71FD2B1E2AA55B3C6EA75789FC5A20CE3E8790E0260E59D10E7D96 -EBBD9E861DCC0A85A2828026C98D69F882F05CE2DE0CD58AB06FE2E778CBEABC40E591AE59EEA3A4012F9266E61D4971 -8716AE40A23BB9D23DC9EE0917D7E2D50891A4D8495F08174953A883B4EA61DA -F2B9B78FA7239BB61E4FB5DDA4286C5FA2CFF34A4456781C55AC4E23644E2A46 -D570A2BD25921E6E3409E0017BC9547F1BFF0992EDC35F0BC0C526B03738D8F0 -BDA88E42BAA3025E730AF8244F2F0DC5E8F9B531882A5E1EF48BF6F0B86DB186 -03E2FFCDF9243D7DB19DAEAF2563D2CF604D82E73E501071523EA1DD3E3A1313 -702A8F9F8F5D670D999D2D4F6388F22846B23FFC4EB53A71DAC92BED76A7D1111C0536FA5293B148B501E8BE70F84C3F -A605F5B456CD733EAD4E12432617936494C1ACA42B2CEE639151AD8846D02EFBF17575565A458B7E8D6E2929BEE70ADB -F5628A7A8602546DD4BAB166DF796B7011A3F66F896599FFC7467045B1B3EB4F -BE6B94C4A7C701FBF7D189FA3C371DC7D208CF84E1EEC00A4C2F4DC14BF8CC17 -AFF0D5E080A7DAD2AFE0C498D3DFD58EAA0AE4F4F96883B46C36537B66D344C2 -E0435324027761281E17E62CCDB964E7B87EA673205DC76109570DEEA25E9C86 -84EB0F58B6F3ED2B6D62BA21D0EBCA0A1C7E17C792EBB47A2EA596AB6E4E98A78908E5E31CCE35CD8091F8D39DA52EF5 -C4027456DE3BF67B080AC563B2F38318B04DB5ED968D33D7493F0FC5CC51B165 -7C59386D2F5AE8F14AA3C1FBD953F5B7B153A3B94B20BA51C18B18BF2F0DB037 -A8E7A91824FA42085CEEE47A80A9269779AE69AFADFA210E8A4C48585F827FCB99509686D7C62215E556DBE73BB476B5 -514F6030D39CC0DE60B0280EC55F32CE93CA5D9446E7DDF03949AAB7C1276CA036A65A5B58C0904158117768D0AA22A6 -F75FC0AA714F37B75E2FDAFB837B671CD7A349A8D77565C6C0F2943A4B0B88A8 -E8C43768DA5C853253C9FD9D2112A66C509DAA37601CBD83DBFA59329E015D40 -2006DA52D75063F76A99A726E0E7B21A737A7D759C470867FF7EECC61B6A5637 -5B474E6EC7E10EB5415B5593E2C03ED5C079B2CFE2B7BCBC8B3D758727043CD4 -1F3328F14AE9C0867143929D0020AF17F58D09C1B47DBD92FFEAFD2260779DFD -CB194E675F700497AA04686CB17CF77F4295D095A0500D41FD0DC2C4FD8BE294 -328E577B4A997108194BEE91E68190663C4AA3E142B8BEF2A99B70CB4D11897DAA990D5F1FC3D33098982D73F63A26DA -4D5DC5AEF974F0E15A0B06726AC0D2589B1C931B848BFD15BFFE01B8F3BF8E50 -A9B1734BCB160609DF5B02E3C9E459D2DE3297920CBAA7677692C27886527D82 -A161A69B3BE5975F8742AE5461A4983201D7B6B91978D87C0E0D71BF74F5A6D7 -FE3F0F9875D8D2C6E51923E610A812E6BAC4E65FCD4026AA965600A4235AF3EE03D27B793C4E629948BADA5C44EE8915 +IV: 2E 2E 2E 4D 65 6F 77 20 4D 65 6F 77 20 4F 77 4F +411F604B4F4487BEFB5285C7023822BE66D08DD0AAB0B659D58A35E68850BD85 +12BB80D35A9750D218BDE6D4BE4E5FD3B5CE20EDA464E1FA80A000D49FF567B4 +81B613E6CFD99287BCBF0957733704E61B4FFE9CBEED2DC721FBABFEB1A249CE91EEEAE285FC10E0A83A6E1BBEA7EB56 +421C18DF4D8280560EFADDBF0BB02F90942CC5B5B2986327D96F5446CC531BD0 +8BB08D9758943404ACE935B58640E78478C91140E5871D7D070B104DE470C3F2 +1E45CCF03C56DDA4403214A430330647D58D443F665794F5F04D9701C6F32AA2 +4429DDE801D7EB69ADD042A70F83AD6160E8504D6C28A9A4A3D7531140549343 +64BC31C7E98E5223E7D74B844CF4BA26594119D3E468188123D6056C52AF11E7 +F7133D37B1A05BCFB3267D7659B85598E3B2B23502C090C042F0AAEB84E4326D +97FA5E05D70495342BACADA35918C339518DC3EC4AC94F94BC73A08BC539A80F +45F22E4ED7559C875725F2DFCF2DFC0631DF1565A12F455F13C4A101A54E607B +95C78F6417110955813DA8E4AFDCF118A1E19006B4D627FCD1B1688F16CE1933 +7B19D2DA8DEA82083E9F52CED668A0CD6B997AED26F40F6BED30EE7D0E3BD117 +A9B4AECEB0C40BFE38F06302769702C89CF530C16308D0DB7A74AF9B70D3034B +D97B2D17062FD5264C88A2369ACA8BBA064B9B99D064C8831B12B1A23E51BEC1 +A26401DADE20E5D99F53703D17B6E247D169FE0073512A23F6EDB8B3FD9AA73E +FFA8F754EC999FA789C333D7C2EEE62CE7ABEFEF9EDA191DDF9C0BEE59E30927 +82FB6C3FB0AD818834B4335855599741728466E3418EBB0C03382C01F2CFE517 +2D284BC94C8C3EAE99FB8060524540C1FA07866A648CD49B82B874DF2073691E +5EFE887394C60DADCDBE4E25E323CAFDC8E0E5A435FE4941CE29274A319E2F4B +8B3CD3C3310933B59C328892998E434CF34F5230B219B9F00EE888154F71D234 +FF176D5DD6D6C296498E40E30FFF2F8498760ED5609B2E3080661A29B1F3C7E7 +CFFD9A9B1210EE4B49849E00B8513400B5399BEDCC98D8C1CEFB5F062BA0F2D7 +99DACFB462669C3F2C87C09F2B3FB0AC8F9F26DEDF6D04CF0C306F7F91615FCF +47A99EB39C8655BD8CB93D349478514E0ECA46C6463011B6B1F0A9B807DEF300 +CC2EDDB4A96311B0A3D4A55F485292CF7585E1CAE9D3D46ADBD40A3391396DFF +82DE652C1008367C54C8C431DADC5026CCF1B300BB112D2F4B3366B319F61284 +71BBA17FDC6261801D17434538524D3B6EE42355B8ABF99C07DBD69F3C1031CE +974DC30EDA9E1CA01C0532E82593D7D84E7FE282659EDAA8FC3474DA422D57B2 +6975A600597A196A21D8432881D95D977C168027D9FFAB273DE00A5AEE3BC5E1 +0B7EC247D17B8C80E151E9DD60B94D2D6CD4E7A03E6404FA044D6BC2A15CF214 +73D12A173C2B97A77231901E94B1C81EA1AF79BD1EA01F8F8E2A3B38177A84EC +9D309CE4B225FC251019B1354E8AEB47EE1D6FA792FF0E14FAFB0C0944D79350 +816B8EB8CB5ADEAC80C9359F9BF538A6641A20AB8BE422AD65E50802DFF38CED +1F41BBFFA9338DB4143D4D3CBA84637FB397EEA36D5D89D4A5D08B3FB8181540 +295359A1E73F5F94186DBFC13175A6DA08771483043408C145B0FB4A10716C86 +990E0B2ABE53757378385879D4D5BBCEF45A69F659963DB6813931973B69ABD6 +6509E69551E5D3E38349DC16CBABBD059DB80852ECA56F7902DEE11F280B14B6 +C8D22F8E7592087432BC4FF32D1810697406948F2C69C54BC5CA8F59BE65278F +E53840FE4593AB7708C14E3E1A33D689160C018CF2CEC3A6FB309929BDA2A66F +3CE77B617C5E133046704DAE55B5328C861CE02F223CE75E6CDFF296927D0012 +0CD25E6B29860621BED286C97675EC6515D9A93B7BCC5E8571460DF90A73F748 +C387DAC55E4B8F15BCB228CF58F857419C91BAF619D38D2700E7149BE56C9D37 +E1AEB1E36C5C0D30B858101BE459E29CE2A49470022495A8D4869D44826F7928 +173D2BB833DCB4291D25E43C9E85AA7900198BF92D6E97EE861BBF6CBE1D2147ADABA5DAEA976F6D2A2716B7E3E75DEC +A388246FAB037912C9B1D2D25C144795B16E917BD2653693346E1A076718FC03 +4EA223311825F64F88AB509D69B708A2143A76A180ED1AB46C8F1AA1C4A9E5AF +0CBBC26D7C458E415DCEECC9F73008B556BED1B77A3AA6BE8C557B46058180D9 +9DE0FFD924900E5B3FD4CCE2B69D7B20FF52EE1E747FFACC6A631056D7D2B4CE +2C05D81B20DA46ED217BE759EFD95919D434FAC98B08405FB9604B61982E4141 +4EEBB881DBE7A97C9C043221B2038F8B919C144D33ACDCE0F9AB5A2D63363E07 +F19CDBD22DCC70D2A11AD7D6210FEA7601BA2093F1E9766C4F8452F1AD14046B +AA165E848FB25FAF3AC74D1AD809BA2A45FE2E79090256BF9E77BDDCD7A4A4E2 +C63B40C559AE339DB491E1E5B39C0EB321EC3A3BD2441763A5B2DF7C2DF534F4 +DA1CEA4B84C64D744AC3BE1D29B1E752CCFB3CFAA56AEB85C1BED37293BEAF93 +C67E0C619482F59D63C6B097347A4C777EBC60D800DD586C10A0BCEC67628618 +0EDE32F4FB6ED09526381B638A7CA5869C7B20FE6E003311065398E3ED3E3474 +43714DC1C28BC0FD3DDD348E93169523D6BC4C8AC1F62545C44D405ED1CA4927 +B49A42DCCC1A76C1643AD96CAE981BE430BEC9CA372A115C02E87BECE4FFFAA6 +E66E1F05704B9BE33AC1A52D33B3CE1D373106B61C10252E56618F64FB2E665B +A78DD00AF303F280CACF7DC5C91778096D77989AAE29EDDC3D772EA32A6A5CB1038196BB1C2394C3E09A706EB421447F +7EC357770322CFB212E77C7A1557C46AF1048A87CB14AE0339FF18E031927DD9 +698F99BEC7BBDA2F06BA8F393235783C05F1E324CB89A2F9239A93C63A96D657 +5955B7E969ECD7E5DDAB6AC8C103CD1C03504A8DA71346452302887FD72ED9D4 +A6856ADA5AD21EAC6255C1A3166CBAFC8763DD6BB4F2AB42BCCB1B71D02B722C +DB86290A20BD5A1CAFED7D06511096B32BAA7CAEDC49A53488542F3944B72531 +83B8E69B9A50EB7D3F51D4221C4002110AB129A5E32A5CF07763BF5A198EBC68978CCF097D4396AFD920DD5A23C4DE14 +95C4CA690A9214E66520F67150A42E5ADE143E9C8D0C5B9CFABDFC93D193FC3D +A3B3E5E7B57F758FDB2062613DC7CF3990DAEF6F2F1EABCD169EFA85C1237F8D +2FD52B5A55EA063680E6CD164F6CD50148E6CBF0DAD1250494CF0E536D39687D46876E1E2C0A9902F785C60273BB5026 +38F372E8F07F16FB50942FFAC6FC4D49601CF09A65C714AC0998EB1FE0DD8F5A +94B863DA82DD1BD27D083690AB4B59D9B6236FCB1172B9480F2E11BC420FC46C3D554B78B2476C964379E028DC89BA29 +4D52AAF64319E435FDD046276964E7A819A3CCF9EEC576A0993FE6F8E29095BB +F44CE71DE07CFAD16BEE0041832A532EA266557C640B4FAE6245252B47C6B8C05AFD9C6F305596ECF68BFE8829B9032D +8520769CE953F5F02C132DE95141E8F78FF2C846B9F672970771BBFCB51386BF +FAA8C71F036FD5A1BDCFCEC05E890BCCA8EB92E7AABF4C7D64D1EA3D25730DD0 +CDB89D5B8B73DB2013EDBB34D8444B37EBAA308345A9626E153FF0A9574FC4D6A2B9588BC20EC0D9B1498228F116D3F6 +13351D444888E92AD03EFFE3466EFD5719DA41FB5BA0805C09CF3E79B188223B +B36B0913A714AB0DD7C0005426127B3A2C02DD3112E745064D7A5899DE26A128 +C3AB7BBA577D74FD581FDA6BA17C1D2E1EBD4A4AA5CB42852E59CEE91D81B3E263549755171B22A5FBF4A1156C8C0A7B +18F579227253BAB1E3CA2E71331C6090286480D19BB1FEF242793D27BCA157D3 +BF613CE44B9BDA278D884D2F756FBE164A9736D28A52B0101611D61B643EB978 +9DE9087BD023D6F6ABDF4A345E85A1110D6B205CCC31DC7372126CCC5EC618EF +764602226E608E5371E693185D57B7C4D6FE2CBDA379D986A251CC7286B283FEE35E07E5B32B93649D52D9CE4FFC90A7 +3AA3162A345891481F09C9231238AD644B6804643C5EED165B3B3F078E0FC216435AE2385B3AF4EB44C029D9A60FC5D9 +867DD29F637DDFBE24CA6AFDA94366D865D701CBCAA9E7074B6FB29592AE31933F230C6471C5A513D19560F5E0820BCB +EDB4BC2F025C11311527B227E42726C3BB4A6CFF49898E2FFEB2097F0924E8EE +D54BFE2E7C21D84AD967433C7329BBBD257A026BFC7866071C80396B45E764D6 +ED13A30EC29B22AB34D5EFE27C74C112ACD42CFFFD0695CE743FE2D0ECCCB35EF58222519E54289E7AD0624A11698986 +84AF1F78D666058274DE1896D706E6196B55B782C395216915C1023E1E44F4A2 +648F762C38B32B930029E5730609A46CF0BCB4117BEF41D36ED47BE8EB8DB2AC +745FAFAFC79AD2DFBE3B03387EE5C3FC05EBF1A61A371E439B7FA977A1ACA3B0 +8C4FE20E0F71A9822FD32A866571D9ED6F8A1F393430AF5DB5FDBF4F7030165A +CC54F712C0C63A6B207C9ACAD7943BDCCC0F8126449E82CA5681F88A0491625B +9F1654268308E44DD6A9128AB1BF9B01D521D5BA9A98E5A77D35564C3678D9EAF2C8A2EC09FC3E5CD1A831FDB95486D0 +58E094157F881A156E0D4EBB79ABFED8D855A9BE1589471A8BDA6AA9F9C58F4B8BF6B326653B6CE28C45DDC3DE4CC4BE +B3BE094F6E487FD211792E424BB5EB95FC11AC78832FE9EAFDB076867A9B4AA2 +9FC6BE151041C150003E5BA940ADABDD02A080A9F4EE61215A6162BB1C13B7D9 +7CFE8E8FE7E2218425F581F70AC6E043E9253774A80450113C836EBAF4EAF4A0 +8610A9694E586306A4078E5DD3C757870C21130D6F67593994568FA1E7B7F4CA +774DDBA8E8AA78BFF82B1E9C8CC58873C73AD0B977ED4EDD465513F9D238AA7DB2BE64536F4950BDAA00F971551F0922 +DB103B1AB06E9115193F5DC6F0C2D806AE9518C91D7D72945B27BE86B2D16351 +86C4A3F2ACBFA942CF4FF3DC062A4786D9D005C05671E232D93DEBCF5C1D7B96 +909EB49451C1D7A1B6E01FFC55EED8DA3C5DB4AFEA5C347DD4E79642746C963E64113CEDECF951947C095B12390BA10F +AD7CFDF6D5C93806F8E5321EC2B4E2C6C7B750874E046154EC76EC2678B6F0C938D2D99A6646663ABC730190C7108C1F +F3DC34F33197A7D2DCBA4D25ACC6EAA0612723C92BFF226E7B3A73BD07B2EBEA +B7074A0B79FE44FA94C3EC55C2C694ADD593C021DED43085CB5D69DBA7F6F6F1 +9C7B26FC47E16E41E8F1F560EBEE3B580E5F44C1A2DA0BA415C279530416F231 +EBED9733677546781E77DC9E6668AE3CA6D1B6C0E1446EE10EBEC8F8ABF5228C +D21EB73FE8C693DD4C580A51DB46D5DF26D798A8A67095FF087B8F14907993C2 +CB9D919298CB3EF9458A962BDD79736F6FC00E209B389C0543D06687AB16ADE0 +EED58F3D2003F1F288718544B95F8F7728AB6D0A7D10E3BEFED3C7F4A55A6B7CCBF8EACE17F0FADCDA6B19DBA74A2324 +D4E83675B9B5BB81D1E5C17CB88225C514C6DD2852D22A8C4681F0683248B21E +0949495177B2C21F42679921EA4C83CD7A9700FB34B13DDF3E61CE26162DE0AF +2C38210508654DE730157BA138118793DDA2BCD7958EDD21B02796B689D0990C +47C78252386879DB6F9F3516FBCA29BAD3EB5F837B881422D7D421A41CCB851EFEA209D371E6E81EF957441D31D71842 diff --git a/applications/main/subghz/scenes/subghz_scene_set_button.c b/applications/main/subghz/scenes/subghz_scene_set_button.c index 2006fdfa6..efec4e4a3 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_button.c +++ b/applications/main/subghz/scenes/subghz_scene_set_button.c @@ -24,9 +24,9 @@ void subghz_scene_set_button_on_enter(void* context) { byte_ptr = &subghz->gen_info->keeloq.btn; byte_count = sizeof(subghz->gen_info->keeloq.btn); break; - case GenKeeloqBFT: - byte_ptr = &subghz->gen_info->keeloq_bft.btn; - byte_count = sizeof(subghz->gen_info->keeloq_bft.btn); + case GenKeeloqSeed: + byte_ptr = &subghz->gen_info->keeloq_seed.btn; + byte_count = sizeof(subghz->gen_info->keeloq_seed.btn); break; case GenAlutechAt4n: byte_ptr = &subghz->gen_info->alutech_at_4n.btn; @@ -99,7 +99,7 @@ bool subghz_scene_set_button_on_event(void* context, SceneManagerEvent event) { switch(subghz->gen_info->type) { case GenFaacSLH: case GenKeeloq: - case GenKeeloqBFT: + case GenKeeloqSeed: case GenAlutechAt4n: case GenSomfyTelis: case GenKingGatesStylo4k: diff --git a/applications/main/subghz/scenes/subghz_scene_set_counter.c b/applications/main/subghz/scenes/subghz_scene_set_counter.c index be13499b8..7a5da91c3 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_counter.c +++ b/applications/main/subghz/scenes/subghz_scene_set_counter.c @@ -30,9 +30,9 @@ void subghz_scene_set_counter_on_enter(void* context) { byte_ptr = (uint8_t*)&subghz->gen_info->came_atomo.cnt; byte_count = sizeof(subghz->gen_info->came_atomo.cnt); break; - case GenKeeloqBFT: - byte_ptr = (uint8_t*)&subghz->gen_info->keeloq_bft.cnt; - byte_count = sizeof(subghz->gen_info->keeloq_bft.cnt); + case GenKeeloqSeed: + byte_ptr = (uint8_t*)&subghz->gen_info->keeloq_seed.cnt; + byte_count = sizeof(subghz->gen_info->keeloq_seed.cnt); break; case GenAlutechAt4n: byte_ptr = (uint8_t*)&subghz->gen_info->alutech_at_4n.cnt; @@ -123,8 +123,8 @@ bool subghz_scene_set_counter_on_event(void* context, SceneManagerEvent event) { case GenCameAtomo: subghz->gen_info->came_atomo.cnt = __bswap16(subghz->gen_info->came_atomo.cnt); break; - case GenKeeloqBFT: - subghz->gen_info->keeloq_bft.cnt = __bswap16(subghz->gen_info->keeloq_bft.cnt); + case GenKeeloqSeed: + subghz->gen_info->keeloq_seed.cnt = __bswap16(subghz->gen_info->keeloq_seed.cnt); break; case GenAlutechAt4n: subghz->gen_info->alutech_at_4n.cnt = @@ -168,7 +168,7 @@ bool subghz_scene_set_counter_on_event(void* context, SceneManagerEvent event) { switch(subghz->gen_info->type) { case GenFaacSLH: - case GenKeeloqBFT: + case GenKeeloqSeed: scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetSeed); return true; case GenKeeloq: diff --git a/applications/main/subghz/scenes/subghz_scene_set_seed.c b/applications/main/subghz/scenes/subghz_scene_set_seed.c index b3bd447e6..482ad07e4 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_seed.c +++ b/applications/main/subghz/scenes/subghz_scene_set_seed.c @@ -22,9 +22,9 @@ void subghz_scene_set_seed_on_enter(void* context) { byte_ptr = (uint8_t*)&subghz->gen_info->faac_slh.seed; byte_count = sizeof(subghz->gen_info->faac_slh.seed); break; - case GenKeeloqBFT: - byte_ptr = (uint8_t*)&subghz->gen_info->keeloq_bft.seed; - byte_count = sizeof(subghz->gen_info->keeloq_bft.seed); + case GenKeeloqSeed: + byte_ptr = (uint8_t*)&subghz->gen_info->keeloq_seed.seed; + byte_count = sizeof(subghz->gen_info->keeloq_seed.seed); break; // Not needed for these types case GenKeeloq: @@ -78,17 +78,17 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) { subghz->gen_info->faac_slh.seed, subghz->gen_info->faac_slh.manuf); break; - case GenKeeloqBFT: - subghz->gen_info->keeloq_bft.seed = __bswap32(subghz->gen_info->keeloq_bft.seed); - generated_protocol = subghz_txrx_gen_keeloq_bft_protocol( + case GenKeeloqSeed: + subghz->gen_info->keeloq_seed.seed = __bswap32(subghz->gen_info->keeloq_seed.seed); + generated_protocol = subghz_txrx_gen_keeloq_seed_protocol( subghz->txrx, subghz->gen_info->mod, subghz->gen_info->freq, - subghz->gen_info->keeloq_bft.serial, - subghz->gen_info->keeloq_bft.btn, - subghz->gen_info->keeloq_bft.cnt, - subghz->gen_info->keeloq_bft.seed, - subghz->gen_info->keeloq_bft.manuf); + subghz->gen_info->keeloq_seed.serial, + subghz->gen_info->keeloq_seed.btn, + subghz->gen_info->keeloq_seed.cnt, + subghz->gen_info->keeloq_seed.seed, + subghz->gen_info->keeloq_seed.manuf); break; // Not needed for these types case GenKeeloq: diff --git a/applications/main/subghz/scenes/subghz_scene_set_serial.c b/applications/main/subghz/scenes/subghz_scene_set_serial.c index ba105a804..9d4640d00 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_serial.c +++ b/applications/main/subghz/scenes/subghz_scene_set_serial.c @@ -30,9 +30,9 @@ void subghz_scene_set_serial_on_enter(void* context) { byte_ptr = (uint8_t*)&subghz->gen_info->came_atomo.serial; byte_count = sizeof(subghz->gen_info->came_atomo.serial); break; - case GenKeeloqBFT: - byte_ptr = (uint8_t*)&subghz->gen_info->keeloq_bft.serial; - byte_count = sizeof(subghz->gen_info->keeloq_bft.serial); + case GenKeeloqSeed: + byte_ptr = (uint8_t*)&subghz->gen_info->keeloq_seed.serial; + byte_count = sizeof(subghz->gen_info->keeloq_seed.serial); break; case GenAlutechAt4n: byte_ptr = (uint8_t*)&subghz->gen_info->alutech_at_4n.serial; @@ -118,9 +118,9 @@ bool subghz_scene_set_serial_on_event(void* context, SceneManagerEvent event) { subghz->gen_info->came_atomo.serial = __bswap32(subghz->gen_info->came_atomo.serial); break; - case GenKeeloqBFT: - subghz->gen_info->keeloq_bft.serial = - __bswap32(subghz->gen_info->keeloq_bft.serial); + case GenKeeloqSeed: + subghz->gen_info->keeloq_seed.serial = + __bswap32(subghz->gen_info->keeloq_seed.serial); break; case GenAlutechAt4n: subghz->gen_info->alutech_at_4n.serial = @@ -172,7 +172,7 @@ bool subghz_scene_set_serial_on_event(void* context, SceneManagerEvent event) { switch(subghz->gen_info->type) { case GenFaacSLH: case GenKeeloq: - case GenKeeloqBFT: + case GenKeeloqSeed: case GenAlutechAt4n: case GenSomfyTelis: case GenSomfyKeytis: diff --git a/applications/main/subghz/scenes/subghz_scene_set_type.c b/applications/main/subghz/scenes/subghz_scene_set_type.c index 7ee72ea21..f144947d7 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_type.c +++ b/applications/main/subghz/scenes/subghz_scene_set_type.c @@ -15,6 +15,7 @@ static const char* submenu_names[SetTypeMAX] = { [SetTypeFaacSLH_868] = "FAAC SLH 868MHz", [SetTypeFaacSLH_433] = "FAAC SLH 433MHz", [SetTypeBFTMitto] = "BFT Mitto 433MHz", + [SetTypeErreka433] = "Erreka 433MHz", [SetTypeSomfyTelis] = "Somfy Telis 433MHz", [SetTypeSomfyKeytis] = "Somfy Keytis 433MHz", [SetTypeANMotorsAT4] = "AN-Motors AT4 433MHz", @@ -56,6 +57,19 @@ static const char* submenu_names[SetTypeMAX] = { [SetTypeNovoferm_433_92] = "KL: Novoferm 433MHz", [SetTypeHormannEcoStar_433_92] = "KL: Hor. EcoStar 433MHz", [SetTypeCardinS449_433FM] = "KL: Cardin S449 433MHz", + [SetTypePujol433] = "KL: Pujol 433MHz", + [SetTypePujol_Vario433] = "KL: Pujol Vario 433MHz", + [SetTypeET_Blue433] = "KL: ET Blue 433MHz", + [SetTypeET_Blue_Mix433] = "KL: ET Blue Mix 433MHz", + [SetTypeATA_PTX4_433] = "KL: ATA PTX4 433MHz", + [SetTypeSeav433] = "KL: Seav 433MHz", + [SetTypeWisniowski433] = "KL: Wisniowski 433MHz", + [SetTypeFadini433] = "KL: Fadini 433MHz", + [SetTypeMc_Garcia433] = "KL: Mc Garcia 433MHz", + [SetTypeClemsa_Mutancode433] = "KL: Clemsa Mutancode 433MHz", + [SetTypeDoormatic433] = "KL: Doormatic 433MHz", + [SetTypeElvox433] = "KL: Elvox 433MHz", + [SetTypeVerex433] = "KL: Verex 433MHz", [SetTypeFAACRCXT_433_92] = "KL: FAAC RC,XT 433MHz", [SetTypeFAACRCXT_868] = "KL: FAAC RC,XT 868MHz", [SetTypeGeniusBravo433] = "KL: Genius TX4RC 433MHz", @@ -163,16 +177,16 @@ bool subghz_scene_set_type_generate_protocol_from_infos(SubGhz* subghz) { gen_info.came_atomo.serial, gen_info.came_atomo.cnt); break; - case GenKeeloqBFT: - generated_protocol = subghz_txrx_gen_keeloq_bft_protocol( + case GenKeeloqSeed: + generated_protocol = subghz_txrx_gen_keeloq_seed_protocol( subghz->txrx, gen_info.mod, gen_info.freq, - gen_info.keeloq_bft.serial, - gen_info.keeloq_bft.btn, - gen_info.keeloq_bft.cnt, - gen_info.keeloq_bft.seed, - gen_info.keeloq_bft.manuf); + gen_info.keeloq_seed.serial, + gen_info.keeloq_seed.btn, + gen_info.keeloq_seed.cnt, + gen_info.keeloq_seed.seed, + gen_info.keeloq_seed.manuf); break; case GenAlutechAt4n: generated_protocol = subghz_txrx_gen_alutech_at_4n_protocol( @@ -313,7 +327,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { case GenFaacSLH: // Serial (u32), Button (u8), Counter (u32), Seed (u32) case GenKeeloq: // Serial (u32), Button (u8), Counter (u16) case GenCameAtomo: // Serial (u32), Counter (u16) - case GenKeeloqBFT: // Serial (u32), Button (u8), Counter (u16), Seed (u32) + case GenKeeloqSeed: // Serial (u32), Button (u8), Counter (u16), Seed (u32) case GenAlutechAt4n: // Serial (u32), Button (u8), Counter (u16) case GenSomfyTelis: // Serial (u32), Button (u8), Counter (u16) case GenSomfyKeytis: // Serial (u32), Button (u8), Counter (u16) diff --git a/documentation/SubGHzSupportedSystems.md b/documentation/SubGHzSupportedSystems.md index 87615f2b0..b6f1b34f0 100644 --- a/documentation/SubGHzSupportedSystems.md +++ b/documentation/SubGHzSupportedSystems.md @@ -22,7 +22,7 @@ That list is only for default SubGHz app, apps like *Weather Station* have their - BETT `433.92MHz` `AM650` (18 bits, Static) - Beninca ARC (TOGO2VA) `433.92MHz` `AM650` (128 bits, Dynamic AES128) (button code `0` emulates `hidden button` option on the remote) - BFT Mitto `433.92MHz` `AM650` (64 bits, Dynamic, KeeLoq based with Seed taken from serial) -- CAME Atomo `433.92MHz, 868MHz` `AM650` (62 bits, Dynamic) +- CAME Atomo `433.92MHz, 868MHz` `AM650` (62 bits, Dynamic) (TOPD4REN, TOP44RBN, TOP42R, TOP44R) - CAME TWEE `433.92MHz` `AM650` (54 bits, Pseudo-Dynamic) (+ TOP44FGN) (aka New Fixed Code) - CAME `433.92MHz, 868MHz` `AM650` (12, 24 bits, Static) - Ditec GOL4 `433.92MHz` `AM650` (54 bits, Dynamic) (should be compatible with BIXLG4, BIXLS2, BIXLP2) - (right arrow emulates button `0` (hidden button)) @@ -33,7 +33,7 @@ That list is only for default SubGHz app, apps like *Weather Station* have their - Dickert MAHS `AM650` (36 bits, Static) - Doitrand `AM650` (37 bits, Dynamic) - Elplast/P-11B/3BK/E.C.A `433MHz` `AM650` (18 bits, Static) -- FAAC SLH `433.92MHz, 868.35MHz` `AM650` (64 bits, Dynamic) (+ Genius KILO TX2/4 JLC) +- FAAC SLH `433.92MHz, 868.35MHz` `AM650` (64 bits, Dynamic) (+ Genius KILO TX2/4 JLC, other Genius models) - Gate TX `433.92MHz` `AM650` (64 bits, Static) - Hormann `868MHz` `AM650` (44 bits, Static) - HCS101 `AM650` (64 bits, Simple Dynamic, KeeLoq-like) @@ -120,7 +120,7 @@ The following manufacturers have KeeLoq support in Unleashed firmware: - KEY (KeeLoq, 64 bits) - Monarch - `433.92MHz` `AM650` (KeeLoq, 64 bits) (no serial in Hop, uses fixed value 0x100 - normal learning) - Motorline - `433.92MHz` `AM650` (KeeLoq, 64 bits) (normal learning) -- Mutanco/Mutancode (KeeLoq, 64 bits) (12bit serial part in Hop - normal learning) +- Clemsa Mutancode (KeeLoq, 64 bits) (12bit serial part in Hop - normal learning) - Mhouse - `433.92MHz` `AM650` (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) - Nice Smilo - `433.92MHz` `AM650` (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) - Normstahl - `433.92MHz` `AM650` (KeeLoq, 64 bits) @@ -128,6 +128,47 @@ The following manufacturers have KeeLoq support in Unleashed firmware: - 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 (R-Tech) - `433.92MHz` `AM650` (KeeLoq, 64 bits) (12bit serial part in Hop - normal learning) (receiver checks for 10bit only (unverified)) +- Erreka - `433.92MHz` `AM650` (KeeLoq, 64 bits) (8bit serial part in Hop - secure learning with Seed) +- Pujol - `433.92MHz` `AM650` (KeeLoq, 64 bits) (8bit serial part in Hop - special learning) (Pujol Vario 4, other models) +- Pujol Vario - `433.92MHz` `AM650` (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) (older models) +- Wisniowski (KeeLoq, 64 bits) (12bit serial part in Hop - normal learning) +- Doormatic (KeeLoq, 64 bits) (normal learning) +- Elvox (KeeLoq, 64 bits) (normal learning) +- ET Blue (KeeLoq, 64 bits) (10bit serial part in Hop - normal learning) +- ET Blue Mix (KeeLoq, 64 bits) (10bit serial part in Hop - normal learning) +- ATA PTX4 (KeeLoq, 64 bits) (12bit serial part in Hop - normal learning) +- Verex (KeeLoq, 64 bits) (normal learning) +- Mc Garcia (KeeLoq, 64 bits) (10bit serial part in Hop - simple learning) +- Fadini (KeeLoq, 64 bits) (12bit serial part in Hop - simple learning) +- Seav (KeeLoq, 64 bits) (12bit serial part in Hop - normal learning) +- AERF Otros (KeeLoq, 64 bits) (10bit serial part in Hop - special learning) +- AERF Collbaix (KeeLoq, 64 bits) (10bit serial part in Hop - special learning) +- AERF Hy dom (KeeLoq, 64 bits) (10bit serial part in Hop - special learning) +- AERF Medva (KeeLoq, 64 bits) (10bit serial part in Hop - special learning) +- AERF VDS (KeeLoq, 64 bits) (10bit serial part in Hop - special learning) +- AERF Temp (KeeLoq, 64 bits) (10bit serial part in Hop - special learning) +- AERF Sabutom (KeeLoq, 64 bits) (10bit serial part in Hop - special learning) +- AERF Motorgate (KeeLoq, 64 bits) (10bit serial part in Hop - special learning) +- JCM1G EMFA (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) +- JCM1G DMIL (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) +- JCM1G Antonio Meca (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) +- JCM1G Hy dom (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) +- JCM1G Baleato (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) +- JCM1G Cas (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) +- JCM1G Cubells (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) +- JCM1G Cyacsa (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) +- JCM1G Forsa (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) +- JCM1G Gandara (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) +- JCM1G Pujol (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) +- JCM1G Gibidi (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) +- JCM1G Gibidi2 (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) +- JCM1G Hybrid (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) +- JCM1G Tech (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) +- JCM1G Norton (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) +- JCM1G Nueva Castilla (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) +- JCM1G Puertas Lorenzo (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) +- JCM1G Serviparking (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) +- JCM1G Zibor (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning) ### Alarms, unknown origin, etc. - APS-1100/APS-2550 (KeeLoq, 64 bits) @@ -163,10 +204,11 @@ The following manufacturers have KeeLoq support in Unleashed firmware: - Tomahawk TZ-9030 (KeeLoq, 64 bits) - Tomahawk Z,X 3-5 (KeeLoq, 64 bits) - ZX-730-750-1055 (KeeLoq, 64 bits) -- Zero_Simple (KeeLoq, 64 bits) -- Zero_Normal (KeeLoq, 64 bits) -- FFFF_Simple (KeeLoq, 64 bits) -- FFFF_Normal (KeeLoq, 64 bits) +- Zero Simple (KeeLoq, 64 bits) +- Zero Normal (KeeLoq, 64 bits) +- FFFF Simple (KeeLoq, 64 bits) +- FFFF Normal (KeeLoq, 64 bits) +- Miserere (KeeLoq, 64 bits) (normal learning) *Note: Most KeeLoq manufacturers operate in the 433 MHz and 868 MHz frequency bands with AM650 modulation. Some operate at other frequencies or modulations. Not all KeeLoq systems are supported for full decoding or emulation.* diff --git a/lib/nfc/protocols/mf_desfire/mf_desfire_i.c b/lib/nfc/protocols/mf_desfire/mf_desfire_i.c index b90ef8ccf..886049685 100644 --- a/lib/nfc/protocols/mf_desfire/mf_desfire_i.c +++ b/lib/nfc/protocols/mf_desfire/mf_desfire_i.c @@ -290,9 +290,7 @@ bool mf_desfire_file_settings_parse(MfDesfireFileSettings* data, const BitBuffer printf("\r\n"); break; } - if(additional_access_rights_len > - MF_DESFIRE_MAX_KEYS * sizeof(MfDesfireFileAccessRights)) - break; + if(additional_access_rights_len > MF_DESFIRE_MAX_KEYS - 1) break; memcpy( &file_settings_temp.access_rights[1], diff --git a/lib/nfc/protocols/mf_ultralight/mf_ultralight_listener.c b/lib/nfc/protocols/mf_ultralight/mf_ultralight_listener.c index d8c5fb1e6..9a25d81b6 100644 --- a/lib/nfc/protocols/mf_ultralight/mf_ultralight_listener.c +++ b/lib/nfc/protocols/mf_ultralight/mf_ultralight_listener.c @@ -169,6 +169,10 @@ static MfUltralightCommand MfUltralightPage pages[64] = {}; uint8_t page_cnt = (end_page - start_page) + 1; + if(page_cnt > COUNT_OF(pages)) { + command = MfUltralightCommandNotProcessedNAK; + break; + } mf_ultralight_listener_perform_read(pages, instance, start_page, page_cnt, do_i2c_check); bit_buffer_copy_bytes(instance->tx_buffer, (uint8_t*)pages, page_cnt * 4); diff --git a/lib/subghz/protocols/came_atomo.c b/lib/subghz/protocols/came_atomo.c index bd21dafd1..ddab59ff3 100644 --- a/lib/subghz/protocols/came_atomo.c +++ b/lib/subghz/protocols/came_atomo.c @@ -258,6 +258,10 @@ static void subghz_protocol_encoder_came_atomo_get_upload( btn = 0x4; } else if(btn == 0x4) { btn = 0x6; + } else if(btn == 0x5) { + btn = 0x0C; + } else if(btn == 0x6) { + btn = 0x0E; } // override button if we change it with signal settings button editor @@ -482,9 +486,11 @@ void subghz_protocol_decoder_came_atomo_feed(void* context, bool level, uint32_t ManchesterEvent event = ManchesterEventReset; switch(instance->decoder.parser_step) { case CameAtomoDecoderStepReset: - // There are two known options for the header: 72K us (TOP42R, TOP44R) or 12k us (found on TOP44RBN) + // There are two known options for the header: 72K us (TOP42R, TOP44R) or 12k us (found on TOP44RBN) / 19k us (TOPD4REN) if((!level) && ((DURATION_DIFF(duration, subghz_protocol_came_atomo_const.te_long * 10) < subghz_protocol_came_atomo_const.te_delta * 20) || + (DURATION_DIFF(duration, subghz_protocol_came_atomo_const.te_long * 16) < + subghz_protocol_came_atomo_const.te_delta * 10) || (DURATION_DIFF(duration, subghz_protocol_came_atomo_const.te_long * 60) < subghz_protocol_came_atomo_const.te_delta * 40))) { //Found header CAME @@ -661,6 +667,10 @@ static void subghz_protocol_came_atomo_remote_controller(SubGhzBlockGeneric* ins instance->btn = 0x3; } else if(btn_decode == 0x6) { instance->btn = 0x4; + } else if(btn_decode == 0x0C) { + instance->btn = 0x5; + } else if(btn_decode == 0x0E) { + instance->btn = 0x6; } uint32_t hi = pack[0] << 24 | pack[1] << 16 | pack[2] << 8 | pack[3]; @@ -671,7 +681,7 @@ static void subghz_protocol_came_atomo_remote_controller(SubGhzBlockGeneric* ins if(subghz_custom_btn_get_original() == 0) { subghz_custom_btn_set_original(instance->btn); } - subghz_custom_btn_set_max(3); + subghz_custom_btn_set_max(4); } void atomo_encrypt(uint8_t* buff) { @@ -738,6 +748,12 @@ static uint8_t subghz_protocol_came_atomo_get_btn_code(void) { case 0x4: btn = 0x1; break; + case 0x5: + btn = 0x1; + break; + case 0x6: + btn = 0x1; + break; default: break; @@ -756,6 +772,12 @@ static uint8_t subghz_protocol_came_atomo_get_btn_code(void) { case 0x4: btn = 0x2; break; + case 0x5: + btn = 0x2; + break; + case 0x6: + btn = 0x2; + break; default: break; @@ -774,6 +796,36 @@ static uint8_t subghz_protocol_came_atomo_get_btn_code(void) { case 0x4: btn = 0x3; break; + case 0x5: + btn = 0x4; + break; + case 0x6: + btn = 0x4; + break; + + default: + break; + } + } else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_RIGHT) { + switch(original_btn_code) { + case 0x1: + btn = 0x5; + break; + case 0x2: + btn = 0x5; + break; + case 0x3: + btn = 0x5; + break; + case 0x4: + btn = 0x5; + break; + case 0x5: + btn = 0x6; + break; + case 0x6: + btn = 0x5; + break; default: break; diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index 2bf173994..ac04610f9 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -367,7 +367,7 @@ static bool subghz_protocol_keeloq_gen_data( } else if( (strcmp(instance->manufacture_name, "DTM_Neo") == 0) || (strcmp(instance->manufacture_name, "FAAC_RC,XT") == 0) || - (strcmp(instance->manufacture_name, "Mutanco_Mutancode") == 0) || + (strcmp(instance->manufacture_name, "Clemsa_Mutancode") == 0) || (strcmp(instance->manufacture_name, "Came_Space") == 0) || (strcmp(instance->manufacture_name, "Genius_Bravo") == 0) || (strcmp(instance->manufacture_name, "GSN") == 0) || @@ -376,20 +376,33 @@ static bool subghz_protocol_keeloq_gen_data( (strcmp(instance->manufacture_name, "Pecinin") == 0) || (strcmp(instance->manufacture_name, "Steelmate") == 0) || (strcmp(instance->manufacture_name, "Cardin_S449") == 0) || - (strcmp(instance->manufacture_name, "Stilmatic") == 0)) { + (strcmp(instance->manufacture_name, "Stilmatic") == 0) || + (strcmp(instance->manufacture_name, "Wisniowski") == 0) || + (strcmp(instance->manufacture_name, "ATA_PTX4") == 0) || + (strcmp(instance->manufacture_name, "Fadini") == 0) || + (strcmp(instance->manufacture_name, "Seav") == 0)) { // DTM Neo, Came_Space uses 12bit serial -> simple learning - // FAAC_RC,XT , Mutanco_Mutancode, Genius_Bravo, GSN 12bit serial -> normal learning + // FAAC_RC,XT , Clemsa_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 + // Wisniowski -> 12bit serial - normal learning + // ATA_PTX4 -> 12bit serial - normal learning + // Fadini -> 12bit serial - simple learning + // Seav -> 12bit serial - normal learning decrypt = btn << 28 | (instance->generic.serial & 0xFFF) << 16 | instance->generic.cnt; } else if( (strcmp(instance->manufacture_name, "NICE_Smilo") == 0) || (strcmp(instance->manufacture_name, "NICE_MHOUSE") == 0) || - (strcmp(instance->manufacture_name, "JCM_Tech") == 0)) { - // Nice Smilo, MHouse, JCM -> 8bit serial - simple learning + (strcmp(instance->manufacture_name, "JCM_Tech") == 0) || + (strcmp(instance->manufacture_name, "Pujol_Vario") == 0) || + (strcmp(instance->manufacture_name, "Pujol") == 0) || + (strcmp(instance->manufacture_name, "Erreka") == 0)) { + // Nice Smilo, MHouse, JCM, Pujol_Vario -> 8bit serial - simple learning + // Pujol -> 8bit serial - special learning + // Erreka -> 8bit serial - secure learning with seed decrypt = btn << 28 | (instance->generic.serial & 0xFF) << 16 | instance->generic.cnt; } else if( @@ -453,6 +466,28 @@ static bool subghz_protocol_keeloq_gen_data( fix, manufacture_code->key); hop = subghz_protocol_keeloq_common_encrypt(decrypt, man); break; + case KEELOQ_LEARNING_AERF: + man = subghz_protocol_keeloq_common_learning_aerf( + fix, manufacture_code->key); + hop = subghz_protocol_keeloq_common_encrypt(decrypt, man); + break; + case KEELOQ_LEARNING_ERREKA: + man = subghz_protocol_keeloq_common_learning_erreka( + fix, instance->generic.seed, manufacture_code->key); + hop = subghz_protocol_keeloq_common_encrypt(decrypt, man); + break; + case KEELOQ_LEARNING_PUJOL: + man = subghz_protocol_keeloq_common_learning_pujol( + fix, manufacture_code->key); + hop = subghz_protocol_keeloq_common_encrypt(decrypt, man); + break; + case KEELOQ_LEARNING_SIMPLE_JCM: + //Simple Learning 8 bit serial + decrypt = btn << 28 | (instance->generic.serial & 0xFF) << 16 | + instance->generic.cnt; + hop = subghz_protocol_keeloq_common_encrypt( + decrypt, manufacture_code->key); + break; case KEELOQ_LEARNING_UNKNOWN: if(kl_type_en == 1) { hop = subghz_protocol_keeloq_common_encrypt( @@ -511,7 +546,7 @@ bool subghz_protocol_keeloq_create_data( return false; } -bool subghz_protocol_keeloq_bft_create_data( +bool subghz_protocol_keeloq_seed_create_data( void* context, FlipperFormat* flipper_format, uint32_t serial, @@ -1101,6 +1136,55 @@ static uint32_t subghz_protocol_keeloq_check_remote_controller_selector( return decrypt; } break; + case KEELOQ_LEARNING_AERF: + man = subghz_protocol_keeloq_common_learning_aerf(fix, manufacture_code->key); + decrypt = subghz_protocol_keeloq_common_decrypt_derived(hop, man, 0x240u); + 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; + } + decrypt = subghz_protocol_keeloq_common_decrypt_derived(hop, man, 0x210u); + 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; + } + 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_ERREKA: + man = subghz_protocol_keeloq_common_learning_erreka( + 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_PUJOL: + man = subghz_protocol_keeloq_common_learning_pujol(fix, 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_SIMPLE_JCM: + // Simple Learning 8 bit serial + decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); + 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_UNKNOWN: // Simple Learning decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key); @@ -1625,7 +1709,9 @@ void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output code_found_reverse_lo, instance->generic.btn, instance->manufacture_name); - } else if(strcmp(instance->manufacture_name, "BFT") == 0) { + } else if( + (strcmp(instance->manufacture_name, "BFT") == 0) || + (strcmp(instance->manufacture_name, "Erreka") == 0)) { // Allow counter edit subghz_block_generic_global.cnt_is_available = true; subghz_block_generic_global.cnt_length_bit = 16; diff --git a/lib/subghz/protocols/keeloq_common.c b/lib/subghz/protocols/keeloq_common.c index a9a2238dd..2486ec45f 100644 --- a/lib/subghz/protocols/keeloq_common.c +++ b/lib/subghz/protocols/keeloq_common.c @@ -140,3 +140,97 @@ inline uint64_t subghz_protocol_keeloq_common_magic_serial_type3_learning(uint32_t data, uint64_t man) { return (man & 0xFFFFFFFFFF000000) | (data & 0xFFFFFF); } + +// Key utils + +static inline uint32_t subghz_protocol_keeloq_common_manufacturer_nl_extend( + uint32_t x, + uint32_t k_lo, + uint32_t k_hi, + uint32_t outer_limit) { + uint32_t r4 = outer_limit; + uint32_t r5 = 0u; + const uint32_t r6 = KEELOQ_NLF; + + while(r5 != r4) { + if(r5 < 0x210u) { + uint32_t r1 = (x >> 15) & 1u; + uint32_t r7 = r1 ^ ((x >> 1) | (x << 31)); + r1 = (15u - r5) & 0x3Fu; + uint32_t lr = 32u - r1; + uint32_t ip = r1 - 32u; + lr = k_hi << lr; + r1 = k_lo >> r1; + ip = (r1 < 32u) ? (k_hi >> ip) : 0u; + r1 = (r1 | lr | ip) & 1u; + ip = (x >> 30) & 1u; + r1 ^= r7; + r7 = (x >> 25) & 1u; + r7 += ip << 1; + ip = (x >> 19) & 1u; + ip += r7 << 1; + r7 = (x >> 8) & 1u; + r7 += ip << 1; + x &= 1u; + x += r7 << 1; + x = (int32_t)r6 >> (x & 31u); + x &= 1u; + x ^= r1; + } + r5 += 1u; + } + return x; +} + +static inline uint32_t subghz_protocol_keeloq_common_word_rotate16(uint32_t v) { + return (v >> 16) | (v << 16); +} + +inline uint32_t subghz_protocol_keeloq_common_decrypt_derived( + uint32_t hop_encrypted, + uint64_t derived_manufacturing_key, + uint32_t outer_limit) { + return subghz_protocol_keeloq_common_manufacturer_nl_extend( + hop_encrypted, + (uint32_t)derived_manufacturing_key, + (uint32_t)(derived_manufacturing_key >> 32u), + outer_limit); +} + +// Protocol (Manufacturer) specific learning +// TODO: Better documentation for these functions + +inline uint64_t subghz_protocol_keeloq_common_learning_aerf(uint32_t data, const uint64_t key) { + uint32_t k_lo = (uint32_t)key; + uint32_t k_hi = (uint32_t)(key >> 32); + uint32_t d = data & 0x0FFFFFFFu; + uint32_t x = d | 0x20000000u; + x = subghz_protocol_keeloq_common_manufacturer_nl_extend(x, k_lo, k_hi, 0x40u); + uint32_t k1 = x; + x = d | 0x60000000u; + x = subghz_protocol_keeloq_common_manufacturer_nl_extend(x, k_lo, k_hi, 0x40u); + return ((uint64_t)x << 32) | k1; +} + +inline uint64_t + subghz_protocol_keeloq_common_learning_erreka(uint32_t data, uint32_t mix, const uint64_t key) { + uint32_t d = data & 0x0FFFFFFFu; + uint32_t k1 = subghz_protocol_keeloq_common_decrypt(d | 0x20000000u, key); + uint32_t r4 = mix >> 4; + uint32_t r1 = (mix << 4) & 0xF000F000u; + r4 = (r4 & 0x0F000F00u) | r1; + uint32_t r5 = mix & 0x00FF00FFu; + uint32_t x = r4 | r5; + x |= 0x60000000u; + uint32_t k2 = subghz_protocol_keeloq_common_decrypt(x, key); + return ((uint64_t)k2 << 32) | k1; +} + +inline uint64_t subghz_protocol_keeloq_common_learning_pujol(uint32_t data, const uint64_t key) { + uint32_t d = data & 0x0FFFFFFFu; + uint32_t w1 = subghz_protocol_keeloq_common_decrypt(d | 0x20000000u, key); + uint32_t w2 = subghz_protocol_keeloq_common_decrypt(d | 0x60000000u, key); + uint32_t k1 = subghz_protocol_keeloq_common_word_rotate16(w1); + uint32_t k2 = subghz_protocol_keeloq_common_word_rotate16(w2); + return ((uint64_t)k2 << 32) | k1; +} diff --git a/lib/subghz/protocols/keeloq_common.h b/lib/subghz/protocols/keeloq_common.h index 1250cd2fc..93904f194 100644 --- a/lib/subghz/protocols/keeloq_common.h +++ b/lib/subghz/protocols/keeloq_common.h @@ -28,6 +28,10 @@ // #define BENINCA_ARC_KEY_TYPE 9u -- RESERVED #define KEELOQ_LEARNING_SIMPLE_KINGGATES 10u #define KEELOQ_LEARNING_NORMAL_JAROLIFT 11u +#define KEELOQ_LEARNING_ERREKA 12u +#define KEELOQ_LEARNING_PUJOL 13u +#define KEELOQ_LEARNING_AERF 14u +#define KEELOQ_LEARNING_SIMPLE_JCM 15u /** * Simple Learning Encrypt @@ -101,3 +105,19 @@ uint64_t subghz_protocol_keeloq_common_magic_serial_type2_learning(uint32_t data */ uint64_t subghz_protocol_keeloq_common_magic_serial_type3_learning(uint32_t data, uint64_t man); + +// Protocol (Manufacturer) specific learning +// TODO: Better documentation for these functions + +uint64_t subghz_protocol_keeloq_common_learning_aerf(uint32_t data, const uint64_t key); + +uint64_t + subghz_protocol_keeloq_common_learning_erreka(uint32_t data, uint32_t mix, const uint64_t key); + +uint64_t subghz_protocol_keeloq_common_learning_pujol(uint32_t data, const uint64_t key); + +// Utils +uint32_t subghz_protocol_keeloq_common_decrypt_derived( + uint32_t hop_encrypted, + uint64_t derived_manufacturing_key, + uint32_t outer_limit); diff --git a/lib/subghz/protocols/public_api.h b/lib/subghz/protocols/public_api.h index 43bef118b..aa5e1965a 100644 --- a/lib/subghz/protocols/public_api.h +++ b/lib/subghz/protocols/public_api.h @@ -57,7 +57,7 @@ bool subghz_protocol_keeloq_create_data( * @param preset Modulation, SubGhzRadioPreset * @return true On success */ -bool subghz_protocol_keeloq_bft_create_data( +bool subghz_protocol_keeloq_seed_create_data( void* context, FlipperFormat* flipper_format, uint32_t serial, diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index bccd2c381..c1c6cbcef 100755 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -3734,7 +3734,7 @@ Function,+,subghz_protocol_encoder_raw_stop,void,void* Function,+,subghz_protocol_encoder_raw_yield,LevelDuration,void* Function,+,subghz_protocol_faac_slh_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint32_t, uint32_t, const char*, SubGhzRadioPreset*" Function,+,subghz_protocol_jarolift_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, SubGhzRadioPreset*" -Function,+,subghz_protocol_keeloq_bft_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, uint32_t, const char*, SubGhzRadioPreset*" +Function,+,subghz_protocol_keeloq_seed_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, uint32_t, const char*, SubGhzRadioPreset*" Function,+,subghz_protocol_keeloq_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, const char*, SubGhzRadioPreset*" Function,+,subghz_protocol_kinggates_stylo_4k_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, SubGhzRadioPreset*" Function,+,subghz_protocol_nice_flor_s_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, SubGhzRadioPreset*, _Bool"