mirror of
https://github.com/DarkFlippers/unleashed-firmware
synced 2024-12-03 17:59:16 +00:00
BFT Programming mode and Add manually
This commit is contained in:
parent
9c9688dd5b
commit
cbb09b6812
3 changed files with 136 additions and 59 deletions
|
@ -8,7 +8,8 @@ typedef enum {
|
|||
//SubmenuIndex
|
||||
SubmenuIndexFaacSLH_433,
|
||||
SubmenuIndexFaacSLH_868,
|
||||
SubmenuIndexBFT,
|
||||
SubmenuIndexBFTClone,
|
||||
SubmenuIndexBFTMitto,
|
||||
SubmenuIndexPricenton,
|
||||
SubmenuIndexNiceFlo12bit,
|
||||
SubmenuIndexNiceFlo24bit,
|
||||
|
|
|
@ -79,10 +79,16 @@ void subghz_scene_set_type_on_enter(void* context) {
|
|||
SubmenuIndexFaacSLH_433,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"BFT [Manual] 433MHz",
|
||||
SubmenuIndexBFTClone,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"BFT Mitto 433MHz",
|
||||
SubmenuIndexBFT,
|
||||
SubmenuIndexBFTMitto,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
|
@ -236,7 +242,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
|
|||
case SubmenuIndexFaacSLH_433:
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFixFaac);
|
||||
break;
|
||||
case SubmenuIndexBFT:
|
||||
case SubmenuIndexBFTClone:
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFixBft);
|
||||
break;
|
||||
case SubmenuIndexPricenton:
|
||||
|
@ -312,6 +318,42 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
|
|||
generated_protocol = true;
|
||||
}
|
||||
break;
|
||||
case SubmenuIndexBFTMitto:
|
||||
subghz->txrx->transmitter = subghz_transmitter_alloc_init(
|
||||
subghz->txrx->environment, SUBGHZ_PROTOCOL_KEELOQ_NAME);
|
||||
subghz_preset_init(subghz, "AM650", 433920000, NULL, 0);
|
||||
if(subghz->txrx->transmitter) {
|
||||
subghz_protocol_keeloq_bft_create_data(
|
||||
subghz_transmitter_get_protocol_instance(subghz->txrx->transmitter),
|
||||
subghz->txrx->fff_data,
|
||||
key & 0x000FFFFF,
|
||||
0x2,
|
||||
0x0002,
|
||||
key & 0x000FFFFF,
|
||||
"BFT",
|
||||
subghz->txrx->preset);
|
||||
|
||||
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] = ((key & 0x000FFFFF) >> i * 8) & 0xFF;
|
||||
}
|
||||
|
||||
flipper_format_write_hex(
|
||||
subghz->txrx->fff_data, "Seed", seed_data, sizeof(uint32_t));
|
||||
|
||||
flipper_format_write_string_cstr(subghz->txrx->fff_data, "Manufacture", "BFT");
|
||||
|
||||
generated_protocol = true;
|
||||
} else {
|
||||
generated_protocol = false;
|
||||
}
|
||||
subghz_transmitter_free(subghz->txrx->transmitter);
|
||||
if(!generated_protocol) {
|
||||
furi_string_set(
|
||||
subghz->error_str, "Function requires\nan SD card with\nfresh databases.");
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
|
||||
}
|
||||
break;
|
||||
case SubmenuIndexDoorHan_433_92:
|
||||
subghz->txrx->transmitter = subghz_transmitter_alloc_init(
|
||||
subghz->txrx->environment, SUBGHZ_PROTOCOL_KEELOQ_NAME);
|
||||
|
|
|
@ -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;
|
||||
|
@ -158,7 +160,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 +191,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 +284,7 @@ static bool subghz_protocol_keeloq_gen_data(
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(hop) {
|
||||
uint64_t yek = (uint64_t)fix << 32 | hop;
|
||||
|
@ -339,6 +354,12 @@ 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;
|
||||
|
@ -450,9 +471,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;
|
||||
}
|
||||
|
@ -607,6 +629,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;
|
||||
}
|
||||
|
||||
|
@ -723,7 +747,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
|
||||
|
@ -1105,19 +1129,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;
|
||||
|
|
Loading…
Reference in a new issue