This commit is contained in:
Willy-JL
2023-02-28 21:01:06 +00:00
parent fa8ed7f6e4
commit 2d9c6d5bb9
26 changed files with 479 additions and 140 deletions
+10
View File
@@ -78,6 +78,16 @@ bool subghz_block_generic_serialize(
FURI_LOG_E(TAG, "Unable to add Key");
break;
}
// Nice One - Manual adding support
if(instance->data_count_bit == 72 &&
(strcmp(instance->protocol_name, "Nice FloR-S") == 0)) {
uint32_t temp = (instance->data_2 >> 4) & 0xFFFFF;
if(!flipper_format_write_uint32(flipper_format, "Data", &temp, 1)) {
FURI_LOG_E(TAG, "Unable to add Data");
break;
}
}
res = true;
} while(false);
furi_string_free(temp_str);
+1 -5
View File
@@ -110,11 +110,7 @@ void subghz_protocol_encoder_faac_slh_free(void* context) {
}
static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* instance) {
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();
}
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
uint32_t fix = instance->generic.serial << 4 | instance->generic.btn;
uint32_t hop = 0;
uint32_t decrypt = 0;
+113 -60
View File
@@ -88,6 +88,8 @@ static const char* mfname;
static uint8_t kl_type;
static uint8_t btn_temp_id;
static uint8_t btn_temp_id_original;
static bool bft_prog_mode;
static uint16_t temp_counter;
void keeloq_set_btn(uint8_t b) {
btn_temp_id = b;
@@ -103,6 +105,8 @@ uint8_t keeloq_get_custom_btn() {
void keeloq_reset_original_btn() {
btn_temp_id_original = 0;
temp_counter = 0;
bft_prog_mode = false;
}
void keeloq_reset_mfname() {
@@ -158,7 +162,27 @@ static bool subghz_protocol_keeloq_gen_data(
SubGhzProtocolEncoderKeeloq* instance,
uint8_t btn,
bool counter_up) {
if(counter_up) {
uint32_t fix = (uint32_t)btn << 28 | instance->generic.serial;
uint32_t hop = 0;
uint64_t man = 0;
uint64_t code_found_reverse;
int res = 0;
if(instance->manufacture_name == 0x0) {
instance->manufacture_name = "";
}
// BFT programming mode on / off conditions
if((strcmp(instance->manufacture_name, "BFT") == 0) && (btn == 0xF)) {
bft_prog_mode = true;
}
if((strcmp(instance->manufacture_name, "BFT") == 0) && (btn != 0xF) && bft_prog_mode) {
bft_prog_mode = false;
}
// If we using BFT programming mode we will trasmit its seed in hop part like original remote
if(bft_prog_mode) {
hop = instance->generic.seed;
}
if(counter_up && !bft_prog_mode) {
if(instance->generic.cnt < 0xFFFF) {
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) {
instance->generic.cnt = 0;
@@ -169,49 +193,41 @@ static bool subghz_protocol_keeloq_gen_data(
instance->generic.cnt = 0;
}
}
uint32_t fix = (uint32_t)btn << 28 | instance->generic.serial;
uint32_t decrypt = (uint32_t)btn << 28 |
(instance->generic.serial & 0x3FF)
<< 16 | //ToDo in some protocols the discriminator is 0
instance->generic.cnt;
uint32_t hop = 0;
uint64_t man = 0;
uint64_t code_found_reverse;
int res = 0;
if(instance->manufacture_name == 0x0) {
instance->manufacture_name = "";
}
if(!bft_prog_mode) {
uint32_t decrypt = (uint32_t)btn << 28 |
(instance->generic.serial & 0x3FF)
<< 16 | //ToDo in some protocols the discriminator is 0
instance->generic.cnt;
// DTM Neo uses 12bit -> simple learning -- FAAC_RC,XT , Mutanco_Mutancode -> 12bit normal learning
if((strcmp(instance->manufacture_name, "DTM_Neo") == 0) ||
(strcmp(instance->manufacture_name, "FAAC_RC,XT") == 0) ||
(strcmp(instance->manufacture_name, "Mutanco_Mutancode") == 0)) {
decrypt = btn << 28 | (instance->generic.serial & 0xFFF) << 16 | instance->generic.cnt;
}
// DTM Neo uses 12bit -> simple learning -- FAAC_RC,XT , Mutanco_Mutancode -> 12bit normal learning
if((strcmp(instance->manufacture_name, "DTM_Neo") == 0) ||
(strcmp(instance->manufacture_name, "FAAC_RC,XT") == 0) ||
(strcmp(instance->manufacture_name, "Mutanco_Mutancode") == 0)) {
decrypt = btn << 28 | (instance->generic.serial & 0xFFF) << 16 | instance->generic.cnt;
}
// Nice Smilo, MHouse, JCM, Normstahl -> 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) ||
(strcmp(instance->manufacture_name, "Normstahl") == 0)) {
decrypt = btn << 28 | (instance->generic.serial & 0xFF) << 16 | instance->generic.cnt;
}
// Nice Smilo, MHouse, JCM, Normstahl -> 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) ||
(strcmp(instance->manufacture_name, "Normstahl") == 0)) {
decrypt = btn << 28 | (instance->generic.serial & 0xFF) << 16 | instance->generic.cnt;
}
// Beninca -> 4bit serial - simple XOR
if(strcmp(instance->manufacture_name, "Beninca") == 0) {
decrypt = btn << 28 | (instance->generic.serial & 0xF) << 16 | instance->generic.cnt;
}
// Beninca -> 4bit serial - simple XOR
if(strcmp(instance->manufacture_name, "Beninca") == 0) {
decrypt = btn << 28 | (instance->generic.serial & 0xF) << 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);
hop = code_found_reverse & 0x00000000ffffffff;
} else if(strcmp(instance->manufacture_name, "AN-Motors") == 0) {
hop = (instance->generic.cnt & 0xFF) << 24 | (instance->generic.cnt & 0xFF) << 16 |
(btn & 0xF) << 12 | 0x404;
} else if(strcmp(instance->manufacture_name, "HCS101") == 0) {
hop = instance->generic.cnt << 16 | (btn & 0xF) << 12 | 0x000;
} else {
if(strcmp(instance->manufacture_name, "Unknown") == 0) {
code_found_reverse = subghz_protocol_blocks_reverse_key(
instance->generic.data, instance->generic.data_count_bit);
hop = code_found_reverse & 0x00000000ffffffff;
} else if(strcmp(instance->manufacture_name, "AN-Motors") == 0) {
hop = (instance->generic.cnt & 0xFF) << 24 | (instance->generic.cnt & 0xFF) << 16 |
(btn & 0xF) << 12 | 0x404;
} else if(strcmp(instance->manufacture_name, "HCS101") == 0) {
hop = instance->generic.cnt << 16 | (btn & 0xF) << 12 | 0x000;
} else {
for
M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) {
res = strcmp(furi_string_get_cstr(manufacture_code->name), instance->manufacture_name);
@@ -270,6 +286,7 @@ static bool subghz_protocol_keeloq_gen_data(
break;
}
}
}
}
if(hop) {
uint64_t yek = (uint64_t)fix << 32 | hop;
@@ -339,6 +356,17 @@ static bool
btn_temp_id_original = btn;
}
if(instance->manufacture_name == 0x0) {
instance->manufacture_name = "";
}
if(bft_prog_mode) {
instance->manufacture_name = "BFT";
}
uint8_t klq_last_custom_btn = 0xA;
if(strcmp(instance->manufacture_name, "BFT") == 0) {
klq_last_custom_btn = 0xF;
}
// Set custom button
if(btn_temp_id == 1) {
switch(btn_temp_id_original) {
@@ -357,6 +385,9 @@ static bool
case 0x8:
btn = 0x1;
break;
case 0xF:
btn = 0x1;
break;
default:
break;
@@ -374,11 +405,14 @@ static bool
btn = 0x4;
break;
case 0x4:
btn = 0xA;
btn = klq_last_custom_btn;
break;
case 0x8:
btn = 0x4;
break;
case 0xF:
btn = 0x4;
break;
default:
break;
@@ -401,6 +435,9 @@ static bool
case 0x8:
btn = 0x2;
break;
case 0xF:
btn = 0x8;
break;
default:
break;
@@ -409,10 +446,10 @@ static bool
if(btn_temp_id == 4) {
switch(btn_temp_id_original) {
case 0x1:
btn = 0xA;
btn = klq_last_custom_btn;
break;
case 0x2:
btn = 0xA;
btn = klq_last_custom_btn;
break;
case 0xA:
btn = 0x2;
@@ -421,7 +458,10 @@ static bool
btn = 0x2;
break;
case 0x8:
btn = 0xA;
btn = klq_last_custom_btn;
break;
case 0xF:
btn = 0x2;
break;
default:
@@ -433,9 +473,10 @@ static bool
btn = btn_temp_id_original;
}
//gen new key
// Generate new key
if(subghz_protocol_keeloq_gen_data(instance, btn, true)) {
//ToDo if you need to add a callback to automatically update the data on the display
// OK
} else {
return false;
}
@@ -590,6 +631,8 @@ void* subghz_protocol_decoder_keeloq_alloc(SubGhzEnvironment* environment) {
instance->keystore = subghz_environment_get_keystore(environment);
instance->manufacture_from_file = furi_string_alloc();
bft_prog_mode = false;
return instance;
}
@@ -706,7 +749,7 @@ void subghz_protocol_decoder_keeloq_feed(void* context, bool level, uint32_t dur
/**
* Validation of decrypt data.
* @param instance Pointer to a SubGhzBlockGeneric instance
* @param decrypt Decrypd data
* @param decrypt Decrypted data
* @param btn Button number, 4 bit
* @param end_serial decrement the last 10 bits of the serial number
* @return true On success
@@ -1088,19 +1131,29 @@ static void subghz_protocol_keeloq_check_remote_controller(
uint64_t key = subghz_protocol_blocks_reverse_key(instance->data, instance->data_count_bit);
uint32_t key_fix = key >> 32;
uint32_t key_hop = key & 0x00000000ffffffff;
// Check key AN-Motors
if((key_hop >> 24) == ((key_hop >> 16) & 0x00ff) &&
(key_fix >> 28) == ((key_hop >> 12) & 0x0f) && (key_hop & 0xFFF) == 0x404) {
*manufacture_name = "AN-Motors";
mfname = *manufacture_name;
instance->cnt = key_hop >> 16;
} else if((key_hop & 0xFFF) == (0x000) && (key_fix >> 28) == ((key_hop >> 12) & 0x0f)) {
*manufacture_name = "HCS101";
mfname = *manufacture_name;
instance->cnt = key_hop >> 16;
// If we are in BFT programming mode we will set previous remembered counter and skip mf keys check
if(!bft_prog_mode) {
// Check key AN-Motors
if((key_hop >> 24) == ((key_hop >> 16) & 0x00ff) &&
(key_fix >> 28) == ((key_hop >> 12) & 0x0f) && (key_hop & 0xFFF) == 0x404) {
*manufacture_name = "AN-Motors";
mfname = *manufacture_name;
instance->cnt = key_hop >> 16;
} else if((key_hop & 0xFFF) == (0x000) && (key_fix >> 28) == ((key_hop >> 12) & 0x0f)) {
*manufacture_name = "HCS101";
mfname = *manufacture_name;
instance->cnt = key_hop >> 16;
} else {
subghz_protocol_keeloq_check_remote_controller_selector(
instance, key_fix, key_hop, keystore, manufacture_name);
}
temp_counter = instance->cnt;
} else {
subghz_protocol_keeloq_check_remote_controller_selector(
instance, key_fix, key_hop, keystore, manufacture_name);
*manufacture_name = "BFT";
mfname = *manufacture_name;
instance->cnt = temp_counter;
}
instance->serial = key_fix & 0x0FFFFFFF;
+20 -2
View File
@@ -543,18 +543,36 @@ bool subghz_protocol_nice_flor_s_create_data(
uint32_t serial,
uint8_t btn,
uint16_t cnt,
SubGhzRadioPreset* preset) {
SubGhzRadioPreset* preset,
bool nice_one) {
furi_assert(context);
SubGhzProtocolEncoderNiceFlorS* instance = context;
instance->generic.serial = serial;
instance->generic.cnt = cnt;
instance->generic.data_count_bit = 52;
if(nice_one) {
instance->generic.data_count_bit = NICE_ONE_COUNT_BIT;
} else {
instance->generic.data_count_bit = 52;
}
uint64_t decrypt = ((uint64_t)instance->generic.serial << 16) | instance->generic.cnt;
uint64_t enc_part = subghz_protocol_nice_flor_s_encrypt(
decrypt, instance->nice_flor_s_rainbow_table_file_name);
uint8_t byte = btn << 4 | (0xF ^ btn ^ 0x3);
instance->generic.data = (uint64_t)byte << 44 | enc_part;
if(instance->generic.data_count_bit == NICE_ONE_COUNT_BIT) {
uint8_t add_data[10] = {0};
for(size_t i = 0; i < 7; i++) {
add_data[i] = (instance->generic.data >> (48 - i * 8)) & 0xFF;
}
subghz_protocol_nice_one_get_data(add_data, 0, 0);
instance->generic.data_2 = 0;
for(size_t j = 7; j < 10; j++) {
instance->generic.data_2 <<= 8;
instance->generic.data_2 += add_data[j];
}
}
bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
return res;
+3 -1
View File
@@ -63,6 +63,7 @@ uint64_t subghz_protocol_nice_flor_s_encrypt(uint64_t data, const char* file_nam
* @param btn Button number, 4 bit
* @param cnt Counter value, 16 bit
* @param preset Modulation, SubGhzRadioPreset
* @param nice_one Nice One if true, Nice Flor S if false
* @return true On success
*/
bool subghz_protocol_nice_flor_s_create_data(
@@ -71,7 +72,8 @@ bool subghz_protocol_nice_flor_s_create_data(
uint32_t serial,
uint8_t btn,
uint16_t cnt,
SubGhzRadioPreset* preset);
SubGhzRadioPreset* preset,
bool nice_one);
/**
* Allocate SubGhzProtocolDecoderNiceFlorS.
+2 -5
View File
@@ -379,11 +379,8 @@ static void subghz_protocol_secplus_v2_encode(SubGhzProtocolEncoderSecPlus_v2* i
uint8_t roll_1[9] = {0};
uint8_t roll_2[9] = {0};
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();
}
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
//ToDo it is not known what value the counter starts
if(instance->generic.cnt > 0xFFFFFFF) instance->generic.cnt = 0xE500000;
uint32_t rolling = subghz_protocol_blocks_reverse_key(instance->generic.cnt, 28);
+111 -10
View File
@@ -73,6 +73,25 @@ const SubGhzProtocol subghz_protocol_somfy_telis = {
.encoder = &subghz_protocol_somfy_telis_encoder,
};
static uint8_t st_btn_temp_id;
static uint8_t st_btn_temp_id_original;
void somfy_telis_set_btn(uint8_t b) {
st_btn_temp_id = b;
}
uint8_t somfy_telis_get_original_btn() {
return st_btn_temp_id_original;
}
uint8_t somfy_telis_get_custom_btn() {
return st_btn_temp_id;
}
void somfy_telis_reset_original_btn() {
st_btn_temp_id_original = 0;
}
void* subghz_protocol_encoder_somfy_telis_alloc(SubGhzEnvironment* environment) {
UNUSED(environment);
SubGhzProtocolEncoderSomfyTelis* instance = malloc(sizeof(SubGhzProtocolEncoderSomfyTelis));
@@ -95,13 +114,86 @@ void subghz_protocol_encoder_somfy_telis_free(void* context) {
free(instance);
}
static bool
subghz_protocol_somfy_telis_gen_data(SubGhzProtocolEncoderSomfyTelis* instance, uint8_t btn) {
UNUSED(btn);
static bool subghz_protocol_somfy_telis_gen_data(
SubGhzProtocolEncoderSomfyTelis* instance,
uint8_t btn,
bool new_remote) {
// If we doing a clone we will use its data
uint64_t data = instance->generic.data ^ (instance->generic.data >> 8);
instance->generic.btn = (data >> 44) & 0xF; // ctrl
instance->generic.cnt = (data >> 24) & 0xFFFF; // rolling code
instance->generic.serial = data & 0xFFFFFF; // address
if(!new_remote) {
instance->generic.btn = (data >> 44) & 0xF; // ctrl
btn = instance->generic.btn;
instance->generic.cnt = (data >> 24) & 0xFFFF; // rolling code
instance->generic.serial = data & 0xFFFFFF; // address
}
// Save original button for later use
if(st_btn_temp_id_original == 0) {
st_btn_temp_id_original = btn;
}
// Set custom button
if(st_btn_temp_id == 1) {
switch(st_btn_temp_id_original) {
case 0x1:
btn = 0x2;
break;
case 0x2:
btn = 0x1;
break;
case 0x4:
btn = 0x1;
break;
case 0x8:
btn = 0x1;
break;
default:
break;
}
}
if(st_btn_temp_id == 2) {
switch(st_btn_temp_id_original) {
case 0x1:
btn = 0x4;
break;
case 0x2:
btn = 0x4;
break;
case 0x4:
btn = 0x2;
break;
case 0x8:
btn = 0x4;
break;
default:
break;
}
}
if(st_btn_temp_id == 3) {
switch(st_btn_temp_id_original) {
case 0x1:
btn = 0x8;
break;
case 0x2:
btn = 0x8;
break;
case 0x4:
btn = 0x8;
break;
case 0x8:
btn = 0x2;
break;
default:
break;
}
}
if((st_btn_temp_id == 0) && (st_btn_temp_id_original != 0)) {
btn = st_btn_temp_id_original;
}
if(instance->generic.cnt < 0xFFFF) {
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) {
@@ -114,8 +206,12 @@ static bool
}
uint8_t frame[7];
frame[0] = data >> 48;
frame[1] = instance->generic.btn << 4;
if(!new_remote) {
frame[0] = data >> 48;
} else {
frame[0] = 0xA7;
}
frame[1] = btn << 4;
frame[2] = instance->generic.cnt >> 8;
frame[3] = instance->generic.cnt;
frame[4] = instance->generic.serial >> 16;
@@ -154,7 +250,7 @@ bool subghz_protocol_somfy_telis_create_data(
instance->generic.serial = serial;
instance->generic.cnt = cnt;
instance->generic.data_count_bit = 56;
bool res = subghz_protocol_somfy_telis_gen_data(instance, btn);
bool res = subghz_protocol_somfy_telis_gen_data(instance, btn, true);
if(res) {
res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
}
@@ -172,7 +268,7 @@ static bool subghz_protocol_encoder_somfy_telis_get_upload(
furi_assert(instance);
//gen new key
if(subghz_protocol_somfy_telis_gen_data(instance, btn)) {
if(subghz_protocol_somfy_telis_gen_data(instance, btn, false)) {
//ToDo if you need to add a callback to automatically update the data on the display
} else {
return false;
@@ -583,6 +679,11 @@ static void subghz_protocol_somfy_telis_check_remote_controller(SubGhzBlockGener
instance->btn = (data >> 44) & 0xF; // ctrl
instance->cnt = (data >> 24) & 0xFFFF; // rolling code
instance->serial = data & 0xFFFFFF; // address
// Save original button for later use
if(st_btn_temp_id_original == 0) {
st_btn_temp_id_original = instance->btn;
}
}
/**
+8
View File
@@ -11,6 +11,14 @@ extern const SubGhzProtocolDecoder subghz_protocol_somfy_telis_decoder;
extern const SubGhzProtocolEncoder subghz_protocol_somfy_telis_encoder;
extern const SubGhzProtocol subghz_protocol_somfy_telis;
// Custom buttons
void somfy_telis_set_btn(uint8_t b);
uint8_t somfy_telis_get_original_btn();
uint8_t somfy_telis_get_custom_btn();
void somfy_telis_reset_original_btn();
/**
* Allocate SubGhzProtocolEncoderSomfyTelis.
* @param environment Pointer to a SubGhzEnvironment instance