diff --git a/lib/subghz/blocks/custom_btn_i.h b/lib/subghz/blocks/custom_btn_i.h index f75ba4068..2aadba6f4 100644 --- a/lib/subghz/blocks/custom_btn_i.h +++ b/lib/subghz/blocks/custom_btn_i.h @@ -5,6 +5,7 @@ #define PROG_MODE_OFF (0U) #define PROG_MODE_KEELOQ_BFT (1U) #define PROG_MODE_KEELOQ_APRIMATIC (2U) +#define PROG_MODE_FAAC_SLH (3U) typedef uint8_t ProgMode; diff --git a/lib/subghz/blocks/generic.h b/lib/subghz/blocks/generic.h index 6f3395620..19c5f3fbe 100644 --- a/lib/subghz/blocks/generic.h +++ b/lib/subghz/blocks/generic.h @@ -25,8 +25,8 @@ struct SubGhzBlockGeneric { uint32_t cnt; uint8_t cnt_2; uint32_t seed; - bool prg_mode; - bool allow_zero_seed; + bool prg_mode : 1; + bool allow_zero_seed : 1; }; /** diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index 2d3510002..1cddcec85 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -8,6 +8,8 @@ #include "../blocks/generic.h" #include "../blocks/math.h" +#include "../blocks/custom_btn_i.h" + #define TAG "SubGhzProtocolFaacSLH" static const SubGhzBlockConst subghz_protocol_faac_slh_const = { @@ -110,17 +112,42 @@ void subghz_protocol_encoder_faac_slh_free(void* context) { } static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* instance) { - if(instance->generic.allow_zero_seed || (instance->generic.seed != 0x0)) { - instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); - } else if(instance->generic.prg_mode == true) { + // Stupid bypass for custom button, remake later + if(subghz_custom_btn_get_original() == 0) { + subghz_custom_btn_set_original(0xF); + } + + uint8_t custom_btn_id = subghz_custom_btn_get(); + ProgMode prog_mode_btn_status = subghz_custom_btn_get_prog_mode(); + bool button_for_programming = false; + + FURI_LOG_I("GENDATA", "CUSTOMBTN: %d\r", subghz_custom_btn_get()); + + // If custom button left is pressed, enable programming mode and disable it on Ok button + if((custom_btn_id == SUBGHZ_CUSTOM_BTN_OK)) { + if(prog_mode_btn_status == PROG_MODE_FAAC_SLH) { + button_for_programming = false; + prog_mode_btn_status = PROG_MODE_OFF; + } + } else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_UP) { + button_for_programming = true; + prog_mode_btn_status = PROG_MODE_FAAC_SLH; + } + subghz_custom_btn_set_prog_mode(prog_mode_btn_status); + FURI_LOG_I("FAAC", "Button for programming: %d\r", button_for_programming); + FURI_LOG_I("FAAC", "Programming mode: %d\r", instance->generic.prg_mode); + + if(button_for_programming) { uint8_t data_tmp = 0; uint8_t data_prg[8]; - instance->generic.cnt_2++; - data_prg[0] = 0x00; - data_prg[1] = instance->generic.cnt_2; + if(instance->generic.allow_zero_seed || (instance->generic.seed != 0x0)) { + instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); + } + + data_prg[1] = instance->generic.cnt & 0xFF; data_prg[2] = (uint8_t)(instance->generic.seed & 0xFF); data_prg[3] = (uint8_t)(instance->generic.seed >> 8 & 0xFF); @@ -132,26 +159,30 @@ static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* inst data_prg[4] ^= data_prg[1]; data_prg[5] ^= data_prg[1]; - for(uint8_t i=data_prg[1] & 0x0F ; i!=0; i--) { - data_tmp = data_prg[5]; + for(uint8_t i = data_prg[1] & 0x0F; i != 0; i--) { + data_tmp = data_prg[5]; - data_prg[5] = ((data_prg[5] << 1) & 0xFF) | (data_prg[4] & 0x80) >> 7; - data_prg[4] = ((data_prg[4] << 1) & 0xFF) | (data_prg[3] & 0x80) >> 7; - data_prg[3] = ((data_prg[3] << 1) & 0xFF) | (data_prg[2] & 0x80) >> 7; - data_prg[2] = ((data_prg[2] << 1) & 0xFF) | (data_tmp & 0x80) >> 7; - } + data_prg[5] = ((data_prg[5] << 1) & 0xFF) | (data_prg[4] & 0x80) >> 7; + data_prg[4] = ((data_prg[4] << 1) & 0xFF) | (data_prg[3] & 0x80) >> 7; + data_prg[3] = ((data_prg[3] << 1) & 0xFF) | (data_prg[2] & 0x80) >> 7; + data_prg[2] = ((data_prg[2] << 1) & 0xFF) | (data_tmp & 0x80) >> 7; + } data_prg[6] = 0x0F; data_prg[7] = 0x52; - uint32_t enc_prg_1 = data_prg[7] << 24 | data_prg[6] << 16 | data_prg[5] << 8 | data_prg[4]; - uint32_t enc_prg_2 = data_prg[3] << 24 | data_prg[2] << 16 | data_prg[1] << 8 | data_prg[0]; + uint32_t enc_prg_1 = data_prg[7] << 24 | data_prg[6] << 16 | data_prg[5] << 8 | + data_prg[4]; + uint32_t enc_prg_2 = data_prg[3] << 24 | data_prg[2] << 16 | data_prg[1] << 8 | + data_prg[0]; instance->generic.data = (uint64_t)enc_prg_1 << 32 | enc_prg_2; FURI_LOG_I(TAG, "New MasterKey encrypted : %016llX\r", instance->generic.data); return true; } else { - // Do not generate new data, send data from buffer - return true; + if(!instance->generic.allow_zero_seed && (instance->generic.seed == 0x0)) { + // Do not generate new data, send data from buffer + return true; + } } uint32_t fix = instance->generic.serial << 4 | instance->generic.btn; uint32_t hop = 0; @@ -163,6 +194,11 @@ static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* inst for(int i = 0; i < 8; i++) { fixx[i] = (fix >> (shiftby -= 4)) & 0xF; } + + if(instance->generic.allow_zero_seed || (instance->generic.seed != 0x0)) { + instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); + } + if((instance->generic.cnt % 2) == 0) { decrypt = fixx[6] << 28 | fixx[7] << 24 | fixx[5] << 20 | (instance->generic.cnt & 0xFFFFF); @@ -209,6 +245,7 @@ bool subghz_protocol_faac_slh_create_data( instance->generic.seed = seed; instance->manufacture_name = manufacture_name; instance->generic.data_count_bit = 64; + instance->generic.allow_zero_seed = true; bool res = subghz_protocol_faac_slh_gen_data(instance); if(res) { return SubGhzProtocolStatusOk == @@ -447,11 +484,16 @@ static void subghz_protocol_faac_slh_check_remote_controller( const char** manufacture_name) { 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; + // Stupid bypass for custom button, remake later + if(subghz_custom_btn_get_original() == 0) { + subghz_custom_btn_set_original(0xF); + } + + subghz_custom_btn_set_max(1); + FURI_LOG_I("RMC", "CUSTOMBTN: %d\r", subghz_custom_btn_get()); uint8_t data_tmp = 0; uint8_t data_prg[8]; data_prg[0] = (code_hop & 0xFF); @@ -463,36 +505,37 @@ static void subghz_protocol_faac_slh_check_remote_controller( data_prg[6] = ((code_fix >> 16) & 0xFF); data_prg[7] = (code_fix >> 24); - if( (data_prg[7] == 0x52) && (data_prg[6] == 0x0F) && (data_prg[0] == 0x00) ) { + if(((data_prg[7] == 0x52) && (data_prg[6] == 0x0F) && (data_prg[0] == 0x00))) { instance->prg_mode = true; // ProgMode ON - FURI_LOG_I(TAG, "Master Key detected!"); - for(uint8_t i = data_prg[1] & 0xF; i != 0; i--) { + data_tmp = data_prg[2]; - data_tmp = data_prg[2]; - - data_prg[2] = data_prg[2] >> 1 | (data_prg[3] & 1) << 7; - data_prg[3] = data_prg[3] >> 1 | (data_prg[4] & 1) << 7; - data_prg[4] = data_prg[4] >> 1 | (data_prg[5] & 1) << 7; - data_prg[5] = data_prg[5] >> 1 | (data_tmp & 1) << 7; - - } - data_prg[2] ^= data_prg[1]; - data_prg[3] ^= data_prg[1]; - data_prg[4] ^= data_prg[1]; - data_prg[5] ^= data_prg[1]; - FURI_LOG_I(TAG, "Got SEED value!"); - instance->seed = data_prg[5] << 24 | data_prg[4] << 16 | data_prg[3] << 8 | data_prg[2]; - FURI_LOG_I(TAG, "SEED = %08lX", instance->seed); - uint32_t dec_prg_1 = data_prg[7] << 24 | data_prg[6] << 16 | data_prg[5] << 8 | data_prg[4]; - uint32_t dec_prg_2 = data_prg[3] << 24 | data_prg[2] << 16 | data_prg[1] << 8 | data_prg[0]; - instance->data_2 = (uint64_t)dec_prg_1 << 32 | dec_prg_2; - FURI_LOG_I(TAG, "MasterKey decrypted : %016llX\r", instance->data_2); - instance->cnt_2 = data_prg[1]; - } else { - instance->prg_mode = false; + data_prg[2] = data_prg[2] >> 1 | (data_prg[3] & 1) << 7; + data_prg[3] = data_prg[3] >> 1 | (data_prg[4] & 1) << 7; + data_prg[4] = data_prg[4] >> 1 | (data_prg[5] & 1) << 7; + data_prg[5] = data_prg[5] >> 1 | (data_tmp & 1) << 7; } + data_prg[2] ^= data_prg[1]; + data_prg[3] ^= data_prg[1]; + data_prg[4] ^= data_prg[1]; + data_prg[5] ^= data_prg[1]; + instance->seed = data_prg[5] << 24 | data_prg[4] << 16 | data_prg[3] << 8 | data_prg[2]; + uint32_t dec_prg_1 = data_prg[7] << 24 | data_prg[6] << 16 | data_prg[5] << 8 | + data_prg[4]; + uint32_t dec_prg_2 = data_prg[3] << 24 | data_prg[2] << 16 | data_prg[1] << 8 | + data_prg[0]; + instance->data_2 = (uint64_t)dec_prg_1 << 32 | dec_prg_2; + instance->cnt = data_prg[1]; + + *manufacture_name = "FAAC_SLH"; + return; + } else { + instance->serial = code_fix >> 4; + instance->btn = code_fix & 0xF; + + instance->prg_mode = false; + } for M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) { @@ -603,6 +646,7 @@ void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* outp furi_string_cat_printf( output, "%s %dbit\r\n" + "Master Remote Prog Mode\r\n" "Ke:%lX%08lX\r\n" "Kd:%lX%08lX\r\n" "Seed:%08lX mCnt:%02X", @@ -613,7 +657,7 @@ void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* outp (uint32_t)(instance->generic.data_2 >> 32), (uint32_t)instance->generic.data_2, instance->generic.seed, - instance->generic.cnt_2); + (uint8_t)(instance->generic.cnt & 0xFF)); } else if(instance->generic.allow_zero_seed == false) { furi_string_cat_printf( output,