Improve keeloq, add JCM support, fix Nice Smilo, MHouse, and more

now manufacturer name is saved into file, and will not change randomly, 
added support for JCM
fixed Nice Smilo, MHouse
This commit is contained in:
MX 2022-10-12 04:18:29 +03:00
parent be293757c0
commit 022315e93d
No known key found for this signature in database
GPG key ID: 6C4C311DFD4B4AB5
6 changed files with 126 additions and 55 deletions

View file

@ -44,13 +44,16 @@ Our Discord Community:
Also check changelog in releases for latest updates!
### Current modified and new SubGHz protocols list:
- HCS101
- An-Motors
- Keeloq [Not ALL systems supported for decode or emulation yet!] - [Supported manufacturers list](https://0bin.net/paste/VwR2lNJY#WH9vnPgvcp7w6zVKucFCuNREKAcOij8KsJ6vqLfMn3b)
- Keeloq: HCS101
- Keeloq: An-Motors
- Keeloq: JCM Tech
- Keeloq: MHouse
- Keeloq: Nice Smilo
- CAME Atomo
- FAAC SLH (Spa) [External seed calculation required]
- BFT Mitto [External seed calculation required]
- Keeloq [Not ALL systems supported yet!]
- Nice Flor S
- FAAC SLH (Spa) [External seed calculation required (For info conatct me in Discord: Nano#8998)]
- BFT Mitto [External seed calculation required (For info conatct me in Discord: Nano#8998)]
- Security+ v1 & v2
- Star Line (saving only)

View file

@ -431,7 +431,7 @@ bool subghz_save_protocol_to_file(
do {
//removing additional fields
flipper_format_delete_key(flipper_format, "Repeat");
flipper_format_delete_key(flipper_format, "Manufacture");
//flipper_format_delete_key(flipper_format, "Manufacture");
// Create subghz folder directory if necessary
if(!storage_simply_mkdir(storage, furi_string_get_cstr(file_dir))) {

View file

@ -562,7 +562,7 @@ bool unirfremix_save_protocol_to_file(FlipperFormat* fff_file, const char* dev_f
path_extract_dirname(dev_file_name, file_dir);
do {
flipper_format_delete_key(fff_file, "Repeat");
flipper_format_delete_key(fff_file, "Manufacture");
//flipper_format_delete_key(fff_file, "Manufacture");
if(!storage_simply_mkdir(storage, furi_string_get_cstr(file_dir))) {
FURI_LOG_E(TAG, "(save) Cannot mkdir");

View file

@ -1,51 +1,51 @@
Filetype: Flipper SubGhz Keystore File
Version: 0
Encryption: 1
IV: 2A 34 F1 5A AF 6F F5 1A 83 A6 1E DA DE B7 3D F1
06B63DF24AE073A2F2B19C55CA9E8364FBECD26E49C551990153F6513BDE5267
6139C78C74C341EB7474085CF1D047BD6FB005F80A72AF3EF3F89D58EF5DF500
D85F11689020ECA47FBE9C2B67EE41A81E1F06DE2A35AF958965E3ECE29EA701
1AE9073A42FE0E439544FE6945F6B33CF15A7A4A279020B5E0B3BE33FD189A7E
E161F007854BB33E0056FA09A2E2DEE66789B5C87C8D6D3DE2C8C1BD2B48983EB9D1C5697CA6E95996918F7C47B761B0
59AE4644DCB3D720C38B5115F230DA58E7BE0A697907F6174BB05AB7886ACDB1
634DF0BCC185C4C1F7E1B1594B4438D051ABAE092433078963063B51D961D08C
1EBEBCB49E498B9BE977D53EC21B9A546155B627737BD0AA832D496035729346
4DFA93E639197772D57E8ACE04512CEFC045B8CC965C175A25ED525B630CBB63
C2D5235D1014A319B249EAE8A5EE350F18D5AB8A498EF222704BD4EB1435F388
F66D1937160E1392197F463A52E87FCE938A92070892113443C348D7553327A5715CF615CE2F2C96284F47759E043419
841D29E7CBE040188E2283BFBA9F26EF2F65CCB085B56C3515E8C46C3F20BD75BAA963550869435FDAF509CEEE66A2C4
7D87E24487D307635E7A17B989B8547EE11F3BF3468D055F0B44633B631BA42C
B4916043973501B95A82B329196D6EBA69FBBC3AF8FD914583104E0E18CE82F6
E4649F9C2A5465D2EA6F3E9724DD06CD6962FE2BAEB14F1453C14D1559232AE1
96E15D890DF7FD348441F5E429A875754C6BF0520A787F8E9D8C5415674783CC
CB52005EDED47B57F795BC92FB0522EAB18D23EE028B8D10ED57828C250EB285BFEC6E4A4BE8DABCE0D57ECAA20D90C3
8E5A50C7D5C374445E88752301D20F0B3D6E4988B61D90FD63779B0EDEF9C60D
49D6CB276A0E5FF134A38062503F01351F44CD6455708B50B5F07D03FC477C33
CB45B56613DF208E79E4E10A6510F07DC1AA49210C7B94E8BBAECD2C35EC6ABC99FB10FD7C96DD6BB6A6685E9FAD93FB
0743F3CC51200F763C242F1956B4D775C092ADF1A5C19ACAE96EB60C2990CF214F8FEA8FC6749286F6BDAB67657C479A
E5608B28A058787D64A145F0362DEFD98CAE0B5A0F22C6DA7C6D278C7B5F95E3
D4C113D43E7FB6D2EFA9E87471AA76A61B26872607B4AF5B87F9D72113835CE6
2DC502800BFD21B76126390CA64A08C5432A2254E822F214CDE1EA11430084C5
CA22C73010B0F1CB8009601BE2AF0B3674D83D5880E4A26C2A3FF0EA0A098CEA
E53B2B102FDB000E9BB747F957156976E5A0C0E3898AA844C13AE8A9CEE7013B
EFB27324B5661419265804ABD130C13DC9DF9CD4D2AC2011CB4FD43D56304AD1
491D75A82ACE8CE216FBE4F0D2D0133BAC7EA8F4A5304337D5E8611AD9C72523
BBFA2B00827E0BCC8AC5CE12C972BB58DFA2EA59DFEFF5A538398FCF970F58A7
6BAF9C855926B683BEDC11883543B2C0E0866FF6B06C46CC09B3C4E1200E7716
B35A4D25FF4D5CFF93B9C4C07B78FCF7E2646138DAB7C090A938C8055CCCE3D8
71CC3C0180771E6B304CE984F5A9962EB35D1965CB78EBAE6F4DDFA44E5E02A2
3DCF52C549FEFCCE2831DB74579AA2C157A4BEE70C43905664C9A6491A171F5D
F7E45AF200F7663DCCE54C14118D2CDFD1228ED0BFF7F70CFBCE15B6F9DF3D40
C44E048AD5C003E68DCF0111317D109CF2B7DD79299692CDA7DA2A12EC9A295A
2B3E6778A97B251A5FEB190991B8AE8EC48F5FC6E94C2ECB8DFADFDD9D8E21FEE5DCCEDD9A1EB8C5212DEAE36FBBDF92
1DD4756E681528CBBDBA6C7BF8833DF556D41E5EA4E4DE52CAD3544C946CD8CA
F903D388CF2016B40B492494F7475E71C50E9FDD63304558212DAF6FBC4E1BA4
9E9F24951DB27917668CD6366795052306022F6F8BA11B08A970691C6857E6C5
C88461104FA0EAA68001B0C2D0483D1A53D6AE04F4CB291C76CEF3A1A5C5DC10
8345B2B9F08B018FEAC2F74D76747FF30DBF426C9B390ACD42AD48104C12042E
087269DC66C76E1D6449831A2C3B6F0006C0F8B1861062B95708C6B222C58A9C
4D31DE05DB12E552D43B1017C68AF3F52B6FE8063E4AD82CB568CDAF22950BCC26FF21EE968FB57650111B617A84DEF7
769BAA780F84797431B6E9DD5180AF3848E03C942C67040B39CC6384E2A8F4C6
1844AAAAD6A6AFB2623DF1452DF940715E6EB92F54C49F408872EC4B2156DDB2
23EB39CD7F3921081199BA8B63D4C19F74365F8D8E71D486576DC900E5EFEEA3
45958B93A16A73CA2578ADCFB1EADAA983BB7015321B0592B67CDF573B084194
IV: 3B 23 A4 2B B1 5D D3 2C 45 B7 3D AF AE B1 D8 53
FA10AAD920563C9F593B7CDDBB544A0F3F2D372854A3A9AB69D10199E7CCFA54
92423F7ED2493A8015BE619D2983056022FC634B68F17EB1260670497FDFB189
6AB9C91E650D048078F87D7DACB278F52EC84CA7F2AECC4338D6A6B456BDE934
84EF6BCCB35F1FCCE0EAC6344D4E4E37A263F04B1FDE79A1D0884BE1FCB8A664
BEC8FBBE9CB4C8C894DD8F2D63A49E76F0363203154710FE8762592858CAD6AF47B9E4BC7ADA14D77F8A82BF9BACE6C6
FB558B51A1DCAB34D119C9D3AC0B0F681E152ED3F9D00E3D40C4B868EEEF8F73
A6E060649AB62907D3B584F1AAC27C2BA1D4BC964BE527A5B901A46C5CADD9BB
7E2E6B38427BFCDB5CD9ED52CF342181446EA6B61192DF28928B64440364F77D
0E3F30701EA2071F9291FA3783149181B27E7B83FF8E259AB458ED3997EE649B
A8ABE616CFF13397BA3D21992C14E43B42FE496C84B97CB7FF0FD4611DAEC8A3
EBBB491879A73FD43718C6851855F621B0AE986C728A8F8D99359F882406132BFB2CF9811BA464D878F36E5712759869
ED4EEF947C6E3475F5FF9905352C7D78F153C65A9AB418892069202C6677002EA2AFC55462797DEE0B69375283D84A26
A27B11AD0DDB5E96B68EB1A016598152FE27C966CF675F7BF17990DEAFF58B62
0BF77CB175A18ADCBDAEA31EAF80ABD886D6BF5034088A25722BC8BB6F7E65FD
66B3C2C98F8154F0B54887B251F8C583199D06ADE895DCEE324213EF3701A44D
A00342176255312C795DD2048087E5B93C28A11BE39E44E2F60B27A1D1B0532F
E6C8A79585A0E091C17E3633ED3074FFA3A5093142B5FB0921873B006257C5F7258B7094F38ACC0D77EA01F31967D2CB
0A2D80FFD35E8D0FD9D728594E91FC8930C7F28EDF59DA2EC896F76A7D71AAF3
0520C7F9BB04EADAF8A74CF89E8EF7AF2B445EB30E5044448B6B8E58CB2467CB
1B7A5310AA25A22042320874ABDF28A7C49432B8364CBF8AB4F04B954D7198C4274F684E4265F82317AB46ACAEA4E849
F0B462179B43E94C50CA2AC75D8C37C0FB606FB0A5380E2BE9F7C5BF24EF3CEFE12E36B41961626F83F9458735AE0A28
9D3A735349C6D83E22C84088DE19EDAD877CBF8E485ED20D25019580354B51B5
4285797E07FF121D73926DFB11B4CE0E7914FD7AECD62381F45A26091ED1EB3D
63787A106DB07DBECB108A45959E15F7DEB04858989DE536483DA06D3F0D1509
A64DF8135E264E799DFB8C8063F665890BDE3CE671FC9878E96516386B1421DB
CCF9B4EF4D817F0A38D023937AD4CE201B0A84AF480CB9FC797AFE8AE9D7C50A
D8DDE6F46CDC89283BAB72171A0F0E470A434F3973CC5FD5617E3F9E0B469048
F08C5ECAC04171983A3923CFFC22BA5CC0C9EECA20D7D5EB2D9495FB9F3B7E80
5AEB9E25A24FA3BF5715D264610E0A6D68197B376555470DA19743569B2CA52C
95E621103E87C52397A53053045FE7B916E43B153F9140144DEEB840F2C43D02
12DFA9AFC04287DE60E540EA46472BE1283012646F3614A501CEA416B591BB89
9375214B3188DE8E4FBA9BB746323B10862B906B8250B6F49E6A3E6400AC5DA6
047BA7E96986B6054F44F2A20AA338C145FE53099BE77481A635D6E73CEC97FB
42115D1C01E03A411D4940644472FC6F6BC85D90305995D00B1839D5FA6B18CC
A962C5FA4F0D5443C8E7555C1F9563588D206B0EA60886B0C44E6EB1EC733971
62E66CDD2FE2ABCA8997D8D8DE24F81C8051C9371F2DB7C8BB6E8DC54A342F9FB09E896133D7F50B8DC058812C90A122
B6E6DEEA620F723D2F7E0325F558F4590DB33553E7680447FA17EEDC1B7C37DF
15621585B61B3EF2858777E0649801F9AE45FEEBC350786E015E8B669E40453F
60D5FEABB8D4C371BF8F700A2C06B15E26CA940FF7990892DDED3D1898787D03
AB0B79C7F5B7BA414E5091CEE9E7F186185A04A9C2E89B4F7C0FA1EB2212EA8C
96065C37BD3B8FBCAA987E8242DB2BDEDE97B3A0F9D7B4C5E753B77989FDE01F
9B9F6302870EF6724F9F7501BC69D4A994485639FB5C437A1461A79D5700D6EF
2D0042C0215561D6E991EDC884477ABA85800D60714CC05FB964A756F2EB05E8
61B88BBB34E93B215CC17C39F2B848AA3CC37EF946FBC467C53873E79985276DB86FF1508972758FE7FC9047B87A7C91
02401832ACADB1DC195902ABD1219965DBA9D38FF651553D18F158A54D98562F
BB5E86C8CB07ACA72B27DCBE578C71080AA1D4071E088E0A6E5CD3DBB0BBB95E
0E86D4024CDBF883C701CBCEA75501158FCB442E0EC30FB592D2F8BBCBF24F4F

View file

@ -28,6 +28,8 @@ struct SubGhzProtocolDecoderKeeloq {
uint16_t header_count;
SubGhzKeystore* keystore;
const char* manufacture_name;
FuriString* manufacture_from_file;
};
struct SubGhzProtocolEncoderKeeloq {
@ -38,6 +40,8 @@ struct SubGhzProtocolEncoderKeeloq {
SubGhzKeystore* keystore;
const char* manufacture_name;
FuriString* manufacture_from_file;
};
typedef enum {
@ -113,12 +117,16 @@ void* subghz_protocol_encoder_keeloq_alloc(SubGhzEnvironment* environment) {
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
instance->manufacture_from_file = furi_string_alloc();
return instance;
}
void subghz_protocol_encoder_keeloq_free(void* context) {
furi_assert(context);
SubGhzProtocolEncoderKeeloq* instance = context;
furi_string_free(instance->manufacture_from_file);
free(instance->encoder.upload);
free(instance);
}
@ -143,6 +151,13 @@ static bool subghz_protocol_keeloq_gen_data(SubGhzProtocolEncoderKeeloq* instanc
instance->manufacture_name = "";
}
// Nice Smilo, MHouse, JCM has 8bit serial - simple learning
if((strcmp(instance->manufacture_name, "NICE_Smilo") == 0) ||
(strcmp(instance->manufacture_name, "NICE_MHOUSE") == 0) ||
(strcmp(instance->manufacture_name, "JCM_Tech") == 0)) {
decrypt = btn << 28 | (instance->generic.serial & 0xFF) << 16 | instance->generic.cnt;
}
if(strcmp(instance->manufacture_name, "Unknown") == 0) {
code_found_reverse = subghz_protocol_blocks_reverse_key(
instance->generic.data, instance->generic.data_count_bit);
@ -347,6 +362,16 @@ bool subghz_protocol_encoder_keeloq_deserialize(void* context, FlipperFormat* fl
FURI_LOG_E(TAG, "Wrong number of bits in key");
break;
}
// Read manufacturer from file
if(flipper_format_read_string(
flipper_format, "Manufacture", instance->manufacture_from_file)) {
instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file);
mfname = furi_string_get_cstr(instance->manufacture_from_file);
} else {
FURI_LOG_D(TAG, "ENCODER: Missing Manufacture");
}
uint8_t seed_data[sizeof(uint32_t)] = {0};
for(size_t i = 0; i < sizeof(uint32_t); i++) {
seed_data[sizeof(uint32_t) - i - 1] = (instance->generic.seed >> i * 8) & 0xFF;
@ -415,6 +440,7 @@ void* subghz_protocol_decoder_keeloq_alloc(SubGhzEnvironment* environment) {
instance->base.protocol = &subghz_protocol_keeloq;
instance->generic.protocol_name = instance->base.protocol->name;
instance->keystore = subghz_environment_get_keystore(environment);
instance->manufacture_from_file = furi_string_alloc();
return instance;
}
@ -422,6 +448,7 @@ void* subghz_protocol_decoder_keeloq_alloc(SubGhzEnvironment* environment) {
void subghz_protocol_decoder_keeloq_free(void* context) {
furi_assert(context);
SubGhzProtocolDecoderKeeloq* instance = context;
furi_string_free(instance->manufacture_from_file);
free(instance);
}
@ -950,6 +977,16 @@ bool subghz_protocol_decoder_keeloq_deserialize(void* context, FlipperFormat* fl
FURI_LOG_E(TAG, "Rewind error");
break;
}
// Read manufacturer from file
if(flipper_format_read_string(
flipper_format, "Manufacture", instance->manufacture_from_file)) {
instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file);
mfname = furi_string_get_cstr(instance->manufacture_from_file);
} else {
FURI_LOG_D(TAG, "DECODER: Missing Manufacture");
}
uint8_t seed_data[sizeof(uint32_t)] = {0};
for(size_t i = 0; i < sizeof(uint32_t); i++) {
seed_data[sizeof(uint32_t) - i - 1] = (instance->generic.seed >> i * 8) & 0xFF;

View file

@ -28,6 +28,8 @@ struct SubGhzProtocolDecoderStarLine {
uint16_t header_count;
SubGhzKeystore* keystore;
const char* manufacture_name;
FuriString* manufacture_from_file;
};
struct SubGhzProtocolEncoderStarLine {
@ -38,6 +40,8 @@ struct SubGhzProtocolEncoderStarLine {
SubGhzKeystore* keystore;
const char* manufacture_name;
FuriString* manufacture_from_file;
};
typedef enum {
@ -109,16 +113,20 @@ void* subghz_protocol_encoder_star_line_alloc(SubGhzEnvironment* environment) {
instance->generic.protocol_name = instance->base.protocol->name;
instance->keystore = subghz_environment_get_keystore(environment);
instance->manufacture_from_file = furi_string_alloc();
instance->encoder.repeat = 10;
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
return instance;
}
void subghz_protocol_encoder_star_line_free(void* context) {
furi_assert(context);
SubGhzProtocolEncoderStarLine* instance = context;
furi_string_free(instance->manufacture_from_file);
free(instance->encoder.upload);
free(instance);
}
@ -274,6 +282,15 @@ bool subghz_protocol_encoder_star_line_deserialize(void* context, FlipperFormat*
break;
}
// Read manufacturer from file
if(flipper_format_read_string(
flipper_format, "Manufacture", instance->manufacture_from_file)) {
instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file);
mfname = furi_string_get_cstr(instance->manufacture_from_file);
} else {
FURI_LOG_D(TAG, "ENCODER: Missing Manufacture");
}
subghz_protocol_star_line_check_remote_controller(
&instance->generic, instance->keystore, &instance->manufacture_name);
@ -331,6 +348,9 @@ void* subghz_protocol_decoder_star_line_alloc(SubGhzEnvironment* environment) {
SubGhzProtocolDecoderStarLine* instance = malloc(sizeof(SubGhzProtocolDecoderStarLine));
instance->base.protocol = &subghz_protocol_star_line;
instance->generic.protocol_name = instance->base.protocol->name;
instance->manufacture_from_file = furi_string_alloc();
instance->keystore = subghz_environment_get_keystore(environment);
return instance;
@ -339,6 +359,7 @@ void* subghz_protocol_decoder_star_line_alloc(SubGhzEnvironment* environment) {
void subghz_protocol_decoder_star_line_free(void* context) {
furi_assert(context);
SubGhzProtocolDecoderStarLine* instance = context;
furi_string_free(instance->manufacture_from_file);
free(instance);
}
@ -705,6 +726,16 @@ bool subghz_protocol_decoder_star_line_deserialize(void* context, FlipperFormat*
FURI_LOG_E(TAG, "Deserialize error");
break;
}
// Read manufacturer from file
if(flipper_format_read_string(
flipper_format, "Manufacture", instance->manufacture_from_file)) {
instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file);
mfname = furi_string_get_cstr(instance->manufacture_from_file);
} else {
FURI_LOG_D(TAG, "DECODER: Missing Manufacture");
}
res = true;
} while(false);