mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-07-21 00:58:10 -07:00
Merge branch 'dev' of https://github.com/DarkFlippers/unleashed-firmware into xfw-dev
This commit is contained in:
@@ -48,4 +48,4 @@ void subghz_custom_btn_set_prog_mode(ProgMode prog_mode) {
|
||||
|
||||
ProgMode subghz_custom_btn_get_prog_mode() {
|
||||
return controller_programming_mode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,4 +14,4 @@ void subghz_custom_btn_set_max(uint8_t b);
|
||||
|
||||
void subghz_custom_btn_set_prog_mode(ProgMode prog_mode);
|
||||
|
||||
ProgMode subghz_custom_btn_get_prog_mode();
|
||||
ProgMode subghz_custom_btn_get_prog_mode();
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
struct SubGhzEnvironment {
|
||||
SubGhzKeystore* keystore;
|
||||
const SubGhzProtocolRegistry* protocol_registry;
|
||||
const char* came_atomo_rainbow_table_file_name;
|
||||
const char* nice_flor_s_rainbow_table_file_name;
|
||||
const char* alutech_at_4n_rainbow_table_file_name;
|
||||
const char* mfname;
|
||||
@@ -16,7 +15,6 @@ SubGhzEnvironment* subghz_environment_alloc() {
|
||||
|
||||
instance->keystore = subghz_keystore_alloc();
|
||||
instance->protocol_registry = NULL;
|
||||
instance->came_atomo_rainbow_table_file_name = NULL;
|
||||
instance->nice_flor_s_rainbow_table_file_name = NULL;
|
||||
instance->alutech_at_4n_rainbow_table_file_name = NULL;
|
||||
instance->mfname = "";
|
||||
@@ -29,7 +27,6 @@ void subghz_environment_free(SubGhzEnvironment* instance) {
|
||||
furi_assert(instance);
|
||||
|
||||
instance->protocol_registry = NULL;
|
||||
instance->came_atomo_rainbow_table_file_name = NULL;
|
||||
instance->nice_flor_s_rainbow_table_file_name = NULL;
|
||||
instance->alutech_at_4n_rainbow_table_file_name = NULL;
|
||||
subghz_keystore_free(instance->keystore);
|
||||
@@ -52,16 +49,17 @@ SubGhzKeystore* subghz_environment_get_keystore(SubGhzEnvironment* instance) {
|
||||
void subghz_environment_set_came_atomo_rainbow_table_file_name(
|
||||
SubGhzEnvironment* instance,
|
||||
const char* filename) {
|
||||
furi_assert(instance);
|
||||
|
||||
instance->came_atomo_rainbow_table_file_name = filename;
|
||||
UNUSED(instance);
|
||||
UNUSED(filename);
|
||||
// Do nothing :)
|
||||
return;
|
||||
}
|
||||
|
||||
const char*
|
||||
subghz_environment_get_came_atomo_rainbow_table_file_name(SubGhzEnvironment* instance) {
|
||||
furi_assert(instance);
|
||||
|
||||
return instance->came_atomo_rainbow_table_file_name;
|
||||
UNUSED(instance);
|
||||
// No table, sorry
|
||||
return "";
|
||||
}
|
||||
|
||||
void subghz_environment_set_alutech_at_4n_rainbow_table_file_name(
|
||||
|
||||
@@ -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 = {
|
||||
@@ -17,6 +19,18 @@ static const SubGhzBlockConst subghz_protocol_faac_slh_const = {
|
||||
.min_count_bit_for_found = 64,
|
||||
};
|
||||
|
||||
static uint32_t temp_fix_backup = 0;
|
||||
static uint32_t temp_counter_backup = 0;
|
||||
static bool faac_prog_mode = false;
|
||||
static bool allow_zero_seed = false;
|
||||
|
||||
void faac_slh_reset_prog_mode() {
|
||||
temp_fix_backup = 0;
|
||||
temp_counter_backup = 0;
|
||||
faac_prog_mode = false;
|
||||
allow_zero_seed = false;
|
||||
}
|
||||
|
||||
struct SubGhzProtocolDecoderFaacSLH {
|
||||
SubGhzProtocolDecoderBase base;
|
||||
|
||||
@@ -110,11 +124,76 @@ void subghz_protocol_encoder_faac_slh_free(void* context) {
|
||||
}
|
||||
|
||||
static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* instance) {
|
||||
if(instance->generic.seed != 0x0) {
|
||||
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
|
||||
} else {
|
||||
// Do not generate new data, send data from buffer
|
||||
// TODO: 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();
|
||||
|
||||
// If we are using UP button - generate programming mode key and send it, otherwise - send regular key if possible
|
||||
if((custom_btn_id == SUBGHZ_CUSTOM_BTN_UP) &&
|
||||
!(!allow_zero_seed && (instance->generic.seed == 0x0))) {
|
||||
uint8_t data_tmp = 0;
|
||||
uint8_t data_prg[8];
|
||||
|
||||
data_prg[0] = 0x00;
|
||||
|
||||
if(allow_zero_seed || (instance->generic.seed != 0x0)) {
|
||||
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
|
||||
if(temp_counter_backup != 0x0) {
|
||||
temp_counter_backup += 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);
|
||||
data_prg[4] = (uint8_t)(instance->generic.seed >> 16 & 0xFF);
|
||||
data_prg[5] = (uint8_t)(instance->generic.seed >> 24);
|
||||
|
||||
data_prg[2] ^= data_prg[1];
|
||||
data_prg[3] ^= data_prg[1];
|
||||
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];
|
||||
|
||||
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];
|
||||
instance->generic.data = (uint64_t)enc_prg_1 << 32 | enc_prg_2;
|
||||
//FURI_LOG_D(TAG, "New Prog Mode Key Generated: %016llX\r", instance->generic.data);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
if(!allow_zero_seed && (instance->generic.seed == 0x0)) {
|
||||
// Do not generate new data, send data from buffer
|
||||
return true;
|
||||
}
|
||||
// If we are in prog mode and regular Send button is used - Do not generate new data, send data from buffer
|
||||
if((faac_prog_mode == true) && (instance->generic.serial == 0x0) &&
|
||||
(instance->generic.btn == 0x0) && (temp_fix_backup == 0x0)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Restore main remote data when we exit programming mode
|
||||
if((instance->generic.serial == 0x0) && (instance->generic.btn == 0x0) &&
|
||||
(temp_fix_backup != 0x0) && !faac_prog_mode) {
|
||||
instance->generic.serial = temp_fix_backup >> 4;
|
||||
instance->generic.btn = temp_fix_backup & 0xF;
|
||||
instance->generic.cnt = temp_counter_backup;
|
||||
}
|
||||
uint32_t fix = instance->generic.serial << 4 | instance->generic.btn;
|
||||
uint32_t hop = 0;
|
||||
@@ -126,6 +205,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(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);
|
||||
@@ -172,6 +256,7 @@ bool subghz_protocol_faac_slh_create_data(
|
||||
instance->generic.seed = seed;
|
||||
instance->manufacture_name = manufacture_name;
|
||||
instance->generic.data_count_bit = 64;
|
||||
allow_zero_seed = true;
|
||||
bool res = subghz_protocol_faac_slh_gen_data(instance);
|
||||
if(res) {
|
||||
return SubGhzProtocolStatusOk ==
|
||||
@@ -242,6 +327,13 @@ SubGhzProtocolStatus
|
||||
FURI_LOG_E(TAG, "Missing Seed");
|
||||
break;
|
||||
}
|
||||
bool tmp_allow_zero_seed;
|
||||
if(flipper_format_read_bool(flipper_format, "AllowZeroSeed", &tmp_allow_zero_seed, 1)) {
|
||||
allow_zero_seed = true;
|
||||
} else {
|
||||
allow_zero_seed = false;
|
||||
}
|
||||
|
||||
instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 |
|
||||
seed_data[3];
|
||||
|
||||
@@ -403,11 +495,62 @@ 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;
|
||||
|
||||
// TODO: 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);
|
||||
|
||||
uint8_t data_tmp = 0;
|
||||
uint8_t data_prg[8];
|
||||
data_prg[0] = (code_hop & 0xFF);
|
||||
data_prg[1] = ((code_hop >> 8) & 0xFF);
|
||||
data_prg[2] = ((code_hop >> 16) & 0xFF);
|
||||
data_prg[3] = (code_hop >> 24);
|
||||
data_prg[4] = (code_fix & 0xFF);
|
||||
data_prg[5] = ((code_fix >> 8) & 0xFF);
|
||||
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))) {
|
||||
faac_prog_mode = true;
|
||||
// ProgMode ON
|
||||
for(uint8_t i = data_prg[1] & 0xF; i != 0; i--) {
|
||||
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];
|
||||
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 {
|
||||
if(code_fix != 0x0) {
|
||||
temp_fix_backup = code_fix;
|
||||
instance->serial = code_fix >> 4;
|
||||
instance->btn = code_fix & 0xF;
|
||||
}
|
||||
|
||||
faac_prog_mode = false;
|
||||
}
|
||||
|
||||
for
|
||||
M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) {
|
||||
switch(manufacture_code->type) {
|
||||
@@ -421,6 +564,10 @@ static void subghz_protocol_faac_slh_check_remote_controller(
|
||||
}
|
||||
}
|
||||
instance->cnt = decrypt & 0xFFFFF;
|
||||
// Backup counter in case when we need to use programming mode
|
||||
if(code_fix != 0x0) {
|
||||
temp_counter_backup = instance->cnt;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t subghz_protocol_decoder_faac_slh_get_hash_data(void* context) {
|
||||
@@ -439,6 +586,7 @@ SubGhzProtocolStatus subghz_protocol_decoder_faac_slh_serialize(
|
||||
|
||||
// Reset seed leftover from previous decoded signal
|
||||
instance->generic.seed = 0x0;
|
||||
temp_fix_backup = 0x0;
|
||||
|
||||
SubGhzProtocolStatus res =
|
||||
subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
|
||||
@@ -486,6 +634,12 @@ SubGhzProtocolStatus
|
||||
FURI_LOG_E(TAG, "Missing Seed");
|
||||
break;
|
||||
}
|
||||
bool tmp_allow_zero_seed;
|
||||
if(flipper_format_read_bool(flipper_format, "AllowZeroSeed", &tmp_allow_zero_seed, 1)) {
|
||||
allow_zero_seed = true;
|
||||
} else {
|
||||
allow_zero_seed = false;
|
||||
}
|
||||
instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 |
|
||||
seed_data[3];
|
||||
|
||||
@@ -507,7 +661,23 @@ void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* outp
|
||||
uint32_t code_fix = instance->generic.data >> 32;
|
||||
uint32_t code_hop = instance->generic.data & 0xFFFFFFFF;
|
||||
|
||||
if(instance->generic.seed == 0x0) {
|
||||
if(faac_prog_mode == true) {
|
||||
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",
|
||||
instance->generic.protocol_name,
|
||||
instance->generic.data_count_bit,
|
||||
(uint32_t)(instance->generic.data >> 32),
|
||||
(uint32_t)instance->generic.data,
|
||||
(uint32_t)(instance->generic.data_2 >> 32),
|
||||
(uint32_t)instance->generic.data_2,
|
||||
instance->generic.seed,
|
||||
(uint8_t)(instance->generic.cnt & 0xFF));
|
||||
} else if((allow_zero_seed == false) && (instance->generic.seed == 0x0)) {
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
|
||||
@@ -129,3 +129,7 @@ SubGhzProtocolStatus
|
||||
* @param output Resulting text
|
||||
*/
|
||||
void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* output);
|
||||
|
||||
// Reset prog mode vars
|
||||
// TODO: Remake in proper way
|
||||
void faac_slh_reset_prog_mode();
|
||||
@@ -990,7 +990,7 @@ static void subghz_protocol_keeloq_check_remote_controller(
|
||||
instance->cnt = temp_counter;
|
||||
} else {
|
||||
// Counter protection
|
||||
furi_crash("Unsuported Prog Mode");
|
||||
furi_crash("Unsupported Prog Mode");
|
||||
}
|
||||
|
||||
instance->serial = key_fix & 0x0FFFFFFF;
|
||||
@@ -1249,6 +1249,23 @@ void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output
|
||||
instance->generic.btn,
|
||||
instance->manufacture_name,
|
||||
instance->generic.seed);
|
||||
} else if(strcmp(instance->manufacture_name, "Unknown") == 0) {
|
||||
instance->generic.cnt = 0x0;
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
"%s %dbit\r\n"
|
||||
"Key:%08lX%08lX\r\n"
|
||||
"Fix:0x%08lX Cnt:????\r\n"
|
||||
"Hop:0x%08lX Btn:%01X\r\n"
|
||||
"MF:%s",
|
||||
instance->generic.protocol_name,
|
||||
instance->generic.data_count_bit,
|
||||
code_found_hi,
|
||||
code_found_lo,
|
||||
code_found_reverse_hi,
|
||||
code_found_reverse_lo,
|
||||
instance->generic.btn,
|
||||
instance->manufacture_name);
|
||||
} else {
|
||||
furi_string_cat_printf(
|
||||
output,
|
||||
|
||||
@@ -200,7 +200,7 @@ bool subghz_protocol_somfy_keytis_create_data(
|
||||
|
||||
/**
|
||||
* Generating an upload from data.
|
||||
* @param instance Pointer to a SubGhzProtocolEncoderKeeloq instance
|
||||
* @param instance Pointer to a SubGhzProtocolEncoderSomfyKeytis instance
|
||||
* @return true On success
|
||||
*/
|
||||
static bool subghz_protocol_encoder_somfy_keytis_get_upload(
|
||||
|
||||
@@ -189,7 +189,7 @@ bool subghz_protocol_somfy_telis_create_data(
|
||||
|
||||
/**
|
||||
* Generating an upload from data.
|
||||
* @param instance Pointer to a SubGhzProtocolEncoderKeeloq instance
|
||||
* @param instance Pointer to a SubGhzProtocolEncoderSomfyTelis instance
|
||||
* @return true On success
|
||||
*/
|
||||
static bool subghz_protocol_encoder_somfy_telis_get_upload(
|
||||
|
||||
Reference in New Issue
Block a user