diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index d5006ae66..1a41904bb 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -1,5 +1,8 @@ #include "faac_slh.h" - +#include "../subghz_keystore.h" +#include +#include +#include "keeloq_common.h" #include "../blocks/const.h" #include "../blocks/decoder.h" #include "../blocks/encoder.h" @@ -20,6 +23,9 @@ struct SubGhzProtocolDecoderFaacSLH { SubGhzBlockDecoder decoder; SubGhzBlockGeneric generic; + + SubGhzKeystore* keystore; + const char* manufacture_name; }; struct SubGhzProtocolEncoderFaacSLH { @@ -27,6 +33,9 @@ struct SubGhzProtocolEncoderFaacSLH { SubGhzProtocolBlockEncoder encoder; SubGhzBlockGeneric generic; + + SubGhzKeystore* keystore; + const char* manufacture_name; }; typedef enum { @@ -72,6 +81,7 @@ void* subghz_protocol_decoder_faac_slh_alloc(SubGhzEnvironment* environment) { SubGhzProtocolDecoderFaacSLH* instance = malloc(sizeof(SubGhzProtocolDecoderFaacSLH)); instance->base.protocol = &subghz_protocol_faac_slh; instance->generic.protocol_name = instance->base.protocol->name; + instance->keystore = subghz_environment_get_keystore(environment); return instance; } @@ -163,13 +173,34 @@ void subghz_protocol_decoder_faac_slh_feed(void* context, bool level, uint32_t d * Analysis of received data * @param instance Pointer to a SubGhzBlockGeneric* instance */ -static void subghz_protocol_faac_slh_check_remote_controller(SubGhzBlockGeneric* instance) { - uint64_t code_found_reverse = - subghz_protocol_blocks_reverse_key(instance->data, instance->data_count_bit); - uint32_t code_fix = code_found_reverse & 0xFFFFFFFF; +static void subghz_protocol_faac_slh_check_remote_controller + (SubGhzBlockGeneric* instance, + SubGhzKeystore* keystore, + const char** manufacture_name) { + //uint64_t code_found_reverse = + //subghz_protocol_blocks_reverse_key(instance->data, instance->data_count_bit); + uint32_t code_fix = instance->data >> 32; + uint32_t code_hop = instance->data & 0xFFFFFFFF; + instance->serial = code_fix >> 4; + instance->btn = code_fix & 0xF; + uint32_t decrypt = 0; + uint64_t man; + uint32_t seed = 0; - instance->serial = code_fix & 0xFFFFFFF; - instance->btn = (code_fix >> 28) & 0x0F; + for + M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) { + uint32_t hi = manufacture_code->key >> 32; + uint32_t lo = manufacture_code->key & 0xFFFFFFFF; + switch(manufacture_code->type) { + case KEELOQ_LEARNING_FAAC: + // FAAC Learning + man = subghz_protocol_keeloq_common_faac_learning(code_fix, seed, manufacture_code->key); + FURI_LOG_I(TAG, "mfkey: %08lX%08lX mf: %s", hi, lo, manufacture_code->name); + decrypt = subghz_protocol_keeloq_common_decrypt(code_hop, man); + *manufacture_name = string_get_cstr(manufacture_code->name); + break; + } + } instance->cnt = decrypt & 0xFFFF; } uint8_t subghz_protocol_decoder_faac_slh_get_hash_data(void* context) { @@ -198,25 +229,26 @@ bool subghz_protocol_decoder_faac_slh_deserialize(void* context, FlipperFormat* void subghz_protocol_decoder_faac_slh_get_string(void* context, string_t output) { furi_assert(context); SubGhzProtocolDecoderFaacSLH* instance = context; - subghz_protocol_faac_slh_check_remote_controller(&instance->generic); - uint64_t code_found_reverse = subghz_protocol_blocks_reverse_key( - instance->generic.data, instance->generic.data_count_bit); - uint32_t code_fix = code_found_reverse & 0xFFFFFFFF; - uint32_t code_hop = (code_found_reverse >> 32) & 0xFFFFFFFF; + subghz_protocol_faac_slh_check_remote_controller(&instance->generic, instance->keystore, &instance->manufacture_name); + //uint64_t code_found_reverse = subghz_protocol_blocks_reverse_key( + //instance->generic.data, instance->generic.data_count_bit); + uint32_t code_fix = instance->generic.data >> 32; + uint32_t code_hop = instance->generic.data & 0xFFFFFFFF; string_cat_printf( output, "%s %dbit\r\n" "Key:%lX%08lX\r\n" - "Fix:%08lX \r\n" - "Hop:%08lX \r\n" - "Sn:%07lX Btn:%lX\r\n", + "Fix:%08lX Cnt:%04X\r\n" + "Hop:%08lX Btn:%lX\r\n" + "Sn:%07lX \r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data >> 32), (uint32_t)instance->generic.data, code_fix, + instance->generic.cnt, code_hop, - instance->generic.serial, - instance->generic.btn); + instance->generic.btn, + instance->generic.serial); } diff --git a/lib/subghz/protocols/keeloq_common.c b/lib/subghz/protocols/keeloq_common.c index 9dfc09348..ca2752a46 100644 --- a/lib/subghz/protocols/keeloq_common.c +++ b/lib/subghz/protocols/keeloq_common.c @@ -81,4 +81,21 @@ inline uint64_t subghz_protocol_keeloq_common_magic_xor_type1_learning(uint32_t data, uint64_t xor) { data &= 0x0FFFFFFF; return (((uint64_t)data << 32) | data) ^ xor; +} + +/** Faac SLH (Spa) Learning + * @param data - fix number (32bit) + * @param seed - seed number (32bit) + * @param key - mfkey (64bit) + * @return man_learning for this fix number (64bit) + */ + +inline uint64_t + subghz_protocol_keeloq_common_faac_learning(uint32_t data, uint32_t seed, const uint32_t key) { + uint32_t k1, k2; + uint16_t hs = seed >> 16; + uint32_t lsb = (uint32_t)hs << 16 | 0x544D; + k1 = subghz_protocol_keeloq_common_encrypt(seed, key); + k2 = subghz_protocol_keeloq_common_encrypt(lsb, key); + return ((uint64_t)k1 << 32) | k2; } \ No newline at end of file diff --git a/lib/subghz/protocols/keeloq_common.h b/lib/subghz/protocols/keeloq_common.h index 50d447ed7..d48f95a60 100644 --- a/lib/subghz/protocols/keeloq_common.h +++ b/lib/subghz/protocols/keeloq_common.h @@ -24,6 +24,7 @@ #define KEELOQ_LEARNING_NORMAL 2u #define KEELOQ_LEARNING_SECURE 3u #define KEELOQ_LEARNING_MAGIC_XOR_TYPE_1 4u +#define KEELOQ_LEARNING_FAAC 5u /** * Simple Learning Encrypt @@ -66,3 +67,11 @@ uint64_t * @return manufacture for this serial number (64bit) */ uint64_t subghz_protocol_keeloq_common_magic_xor_type1_learning(uint32_t data, uint64_t xor); + +/** Faac SLH (Spa) Learning + * @param data - fix number (32bit) + * @param seed - seed number (32bit) + * @param key - mfkey (64bit) + * @return man_learning for this fix number (64bit) + */ +uint64_t subghz_protocol_keeloq_common_faac_learning(uint32_t data, uint32_t seed, const uint32_t key);