mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-12-19 19:31:50 +03:00
Actually working progmode, new add manually options + bonus fixes
This commit is contained in:
parent
2a789ae1c1
commit
0eb06ba2b7
@ -6,6 +6,8 @@ typedef enum {
|
|||||||
SubGhzCustomEventManagerSetRAW,
|
SubGhzCustomEventManagerSetRAW,
|
||||||
|
|
||||||
//SubmenuIndex
|
//SubmenuIndex
|
||||||
|
SubmenuIndexFaacSLH_Manual_433,
|
||||||
|
SubmenuIndexFaacSLH_Manual_868,
|
||||||
SubmenuIndexFaacSLH_433,
|
SubmenuIndexFaacSLH_433,
|
||||||
SubmenuIndexFaacSLH_868,
|
SubmenuIndexFaacSLH_868,
|
||||||
SubmenuIndexBFTClone,
|
SubmenuIndexBFTClone,
|
||||||
|
@ -665,6 +665,8 @@ void subghz_txrx_reset_dynamic_and_custom_btns(SubGhzTxRx* instance) {
|
|||||||
furi_assert(instance);
|
furi_assert(instance);
|
||||||
subghz_environment_reset_keeloq(instance->environment);
|
subghz_environment_reset_keeloq(instance->environment);
|
||||||
|
|
||||||
|
faac_slh_reset_prog_mode();
|
||||||
|
|
||||||
subghz_custom_btns_reset();
|
subghz_custom_btns_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,12 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) {
|
|||||||
furi_string_set(subghz->file_path, subghz->file_path_tmp);
|
furi_string_set(subghz->file_path, subghz->file_path_tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scene_manager_previous_scene(subghz->scene_manager);
|
if(scene_manager_has_previous_scene(subghz->scene_manager, SubGhzSceneSetSeed)) {
|
||||||
|
scene_manager_search_and_switch_to_previous_scene(
|
||||||
|
subghz->scene_manager, SubGhzSceneSetType);
|
||||||
|
} else {
|
||||||
|
scene_manager_previous_scene(subghz->scene_manager);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||||
if(event.event == SubGhzCustomEventSceneSaveName) {
|
if(event.event == SubGhzCustomEventSceneSaveName) {
|
||||||
|
@ -18,7 +18,7 @@ void subghz_scene_set_cnt_on_enter(void* context) {
|
|||||||
|
|
||||||
switch(state) {
|
switch(state) {
|
||||||
case SubmenuIndexBFTClone:
|
case SubmenuIndexBFTClone:
|
||||||
byte_input_set_header_text(byte_input, "Enter COUNTER in hex");
|
byte_input_set_header_text(byte_input, "Enter COUNTER in Hex");
|
||||||
byte_input_set_result_callback(
|
byte_input_set_result_callback(
|
||||||
byte_input,
|
byte_input,
|
||||||
subghz_scene_set_cnt_byte_input_callback,
|
subghz_scene_set_cnt_byte_input_callback,
|
||||||
@ -27,9 +27,9 @@ void subghz_scene_set_cnt_on_enter(void* context) {
|
|||||||
subghz->secure_data->cnt,
|
subghz->secure_data->cnt,
|
||||||
2);
|
2);
|
||||||
break;
|
break;
|
||||||
case SubmenuIndexFaacSLH_433:
|
case SubmenuIndexFaacSLH_Manual_433:
|
||||||
case SubmenuIndexFaacSLH_868:
|
case SubmenuIndexFaacSLH_Manual_868:
|
||||||
byte_input_set_header_text(byte_input, "Enter COUNTER in hex [20 bits]");
|
byte_input_set_header_text(byte_input, "Enter COUNTER in Hex 20 bits");
|
||||||
byte_input_set_result_callback(
|
byte_input_set_result_callback(
|
||||||
byte_input,
|
byte_input,
|
||||||
subghz_scene_set_cnt_byte_input_callback,
|
subghz_scene_set_cnt_byte_input_callback,
|
||||||
|
@ -13,7 +13,7 @@ void subghz_scene_set_fix_on_enter(void* context) {
|
|||||||
|
|
||||||
// Setup view
|
// Setup view
|
||||||
ByteInput* byte_input = subghz->byte_input;
|
ByteInput* byte_input = subghz->byte_input;
|
||||||
byte_input_set_header_text(byte_input, "Enter FIX in hex");
|
byte_input_set_header_text(byte_input, "Enter FIX in Hex");
|
||||||
byte_input_set_result_callback(
|
byte_input_set_result_callback(
|
||||||
byte_input,
|
byte_input,
|
||||||
subghz_scene_set_fix_byte_input_callback,
|
subghz_scene_set_fix_byte_input_callback,
|
||||||
|
@ -14,7 +14,7 @@ void subghz_scene_set_seed_on_enter(void* context) {
|
|||||||
|
|
||||||
// Setup view
|
// Setup view
|
||||||
ByteInput* byte_input = subghz->byte_input;
|
ByteInput* byte_input = subghz->byte_input;
|
||||||
byte_input_set_header_text(byte_input, "Enter SEED in hex");
|
byte_input_set_header_text(byte_input, "Enter SEED in Hex");
|
||||||
byte_input_set_result_callback(
|
byte_input_set_result_callback(
|
||||||
byte_input,
|
byte_input,
|
||||||
subghz_scene_set_seed_byte_input_callback,
|
subghz_scene_set_seed_byte_input_callback,
|
||||||
@ -62,8 +62,8 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) {
|
|||||||
}
|
}
|
||||||
consumed = true;
|
consumed = true;
|
||||||
break;
|
break;
|
||||||
case SubmenuIndexFaacSLH_433:
|
case SubmenuIndexFaacSLH_Manual_433:
|
||||||
case SubmenuIndexFaacSLH_868:
|
case SubmenuIndexFaacSLH_Manual_868:
|
||||||
fix_part = subghz->secure_data->fix[0] << 24 | subghz->secure_data->fix[1] << 16 |
|
fix_part = subghz->secure_data->fix[0] << 24 | subghz->secure_data->fix[1] << 16 |
|
||||||
subghz->secure_data->fix[2] << 8 | subghz->secure_data->fix[3];
|
subghz->secure_data->fix[2] << 8 | subghz->secure_data->fix[3];
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) {
|
|||||||
seed = subghz->secure_data->seed[0] << 24 | subghz->secure_data->seed[1] << 16 |
|
seed = subghz->secure_data->seed[0] << 24 | subghz->secure_data->seed[1] << 16 |
|
||||||
subghz->secure_data->seed[2] << 8 | subghz->secure_data->seed[3];
|
subghz->secure_data->seed[2] << 8 | subghz->secure_data->seed[3];
|
||||||
|
|
||||||
if(state == SubmenuIndexFaacSLH_433) {
|
if(state == SubmenuIndexFaacSLH_Manual_433) {
|
||||||
generated_protocol = subghz_txrx_gen_faac_slh_protocol(
|
generated_protocol = subghz_txrx_gen_faac_slh_protocol(
|
||||||
subghz->txrx,
|
subghz->txrx,
|
||||||
"AM650",
|
"AM650",
|
||||||
@ -83,7 +83,7 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) {
|
|||||||
(cnt & 0xFFFFF),
|
(cnt & 0xFFFFF),
|
||||||
seed,
|
seed,
|
||||||
"FAAC_SLH");
|
"FAAC_SLH");
|
||||||
} else if(state == SubmenuIndexFaacSLH_868) {
|
} else if(state == SubmenuIndexFaacSLH_Manual_868) {
|
||||||
generated_protocol = subghz_txrx_gen_faac_slh_protocol(
|
generated_protocol = subghz_txrx_gen_faac_slh_protocol(
|
||||||
subghz->txrx,
|
subghz->txrx,
|
||||||
"AM650",
|
"AM650",
|
||||||
|
@ -13,6 +13,24 @@ void subghz_scene_set_type_submenu_callback(void* context, uint32_t index) {
|
|||||||
void subghz_scene_set_type_on_enter(void* context) {
|
void subghz_scene_set_type_on_enter(void* context) {
|
||||||
SubGhz* subghz = context;
|
SubGhz* subghz = context;
|
||||||
|
|
||||||
|
submenu_add_item(
|
||||||
|
subghz->submenu,
|
||||||
|
"Faac SLH [Man.] 868MHz",
|
||||||
|
SubmenuIndexFaacSLH_Manual_868,
|
||||||
|
subghz_scene_set_type_submenu_callback,
|
||||||
|
subghz);
|
||||||
|
submenu_add_item(
|
||||||
|
subghz->submenu,
|
||||||
|
"Faac SLH [Man.] 433MHz",
|
||||||
|
SubmenuIndexFaacSLH_Manual_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(
|
submenu_add_item(
|
||||||
subghz->submenu,
|
subghz->submenu,
|
||||||
"Faac SLH 868MHz",
|
"Faac SLH 868MHz",
|
||||||
@ -25,12 +43,6 @@ void subghz_scene_set_type_on_enter(void* context) {
|
|||||||
SubmenuIndexFaacSLH_433,
|
SubmenuIndexFaacSLH_433,
|
||||||
subghz_scene_set_type_submenu_callback,
|
subghz_scene_set_type_submenu_callback,
|
||||||
subghz);
|
subghz);
|
||||||
submenu_add_item(
|
|
||||||
subghz->submenu,
|
|
||||||
"BFT [Manual] 433MHz",
|
|
||||||
SubmenuIndexBFTClone,
|
|
||||||
subghz_scene_set_type_submenu_callback,
|
|
||||||
subghz);
|
|
||||||
submenu_add_item(
|
submenu_add_item(
|
||||||
subghz->submenu,
|
subghz->submenu,
|
||||||
"BFT Mitto 433MHz",
|
"BFT Mitto 433MHz",
|
||||||
@ -319,10 +331,10 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
|
|||||||
if(event.type == SceneManagerEventTypeCustom) {
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
uint32_t key = (uint32_t)rand();
|
uint32_t key = (uint32_t)rand();
|
||||||
switch(event.event) {
|
switch(event.event) {
|
||||||
case SubmenuIndexFaacSLH_868:
|
case SubmenuIndexFaacSLH_Manual_868:
|
||||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFix);
|
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFix);
|
||||||
break;
|
break;
|
||||||
case SubmenuIndexFaacSLH_433:
|
case SubmenuIndexFaacSLH_Manual_433:
|
||||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFix);
|
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFix);
|
||||||
break;
|
break;
|
||||||
case SubmenuIndexBFTClone:
|
case SubmenuIndexBFTClone:
|
||||||
@ -390,6 +402,38 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
|
|||||||
generated_protocol = subghz_txrx_gen_data_protocol(
|
generated_protocol = subghz_txrx_gen_data_protocol(
|
||||||
subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_GATE_TX_NAME, rev_key, 24);
|
subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_GATE_TX_NAME, rev_key, 24);
|
||||||
break;
|
break;
|
||||||
|
case SubmenuIndexFaacSLH_433:
|
||||||
|
generated_protocol = subghz_txrx_gen_faac_slh_protocol(
|
||||||
|
subghz->txrx,
|
||||||
|
"AM650",
|
||||||
|
433920000,
|
||||||
|
((key & 0x00FFFFF0) | 0xA0000006) >> 4,
|
||||||
|
0x6,
|
||||||
|
0x00002,
|
||||||
|
key,
|
||||||
|
"FAAC_SLH");
|
||||||
|
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 SubmenuIndexFaacSLH_868:
|
||||||
|
generated_protocol = subghz_txrx_gen_faac_slh_protocol(
|
||||||
|
subghz->txrx,
|
||||||
|
"AM650",
|
||||||
|
868350000,
|
||||||
|
((key & 0x00FFFFF0) | 0xA0000006) >> 4,
|
||||||
|
0x6,
|
||||||
|
0x00002,
|
||||||
|
key,
|
||||||
|
"FAAC_SLH");
|
||||||
|
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 SubmenuIndexBeninca433:
|
case SubmenuIndexBeninca433:
|
||||||
generated_protocol = subghz_txrx_gen_keeloq_protocol(
|
generated_protocol = subghz_txrx_gen_keeloq_protocol(
|
||||||
subghz->txrx,
|
subghz->txrx,
|
||||||
|
@ -20,7 +20,6 @@ bool subghz_scene_transmitter_update_data_show(void* context) {
|
|||||||
FuriString* frequency_str = furi_string_alloc();
|
FuriString* frequency_str = furi_string_alloc();
|
||||||
FuriString* modulation_str = furi_string_alloc();
|
FuriString* modulation_str = furi_string_alloc();
|
||||||
|
|
||||||
|
|
||||||
if(subghz_protocol_decoder_base_deserialize(
|
if(subghz_protocol_decoder_base_deserialize(
|
||||||
decoder, subghz_txrx_get_fff_data(subghz->txrx)) == SubGhzProtocolStatusOk) {
|
decoder, subghz_txrx_get_fff_data(subghz->txrx)) == SubGhzProtocolStatusOk) {
|
||||||
subghz_protocol_decoder_base_get_string(decoder, key_str);
|
subghz_protocol_decoder_base_get_string(decoder, key_str);
|
||||||
@ -83,6 +82,10 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) {
|
|||||||
// Calling restore!
|
// Calling restore!
|
||||||
subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx));
|
subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx));
|
||||||
subghz_txrx_stop(subghz->txrx);
|
subghz_txrx_stop(subghz->txrx);
|
||||||
|
// Calling restore 2nd time special for FAAC SLH!
|
||||||
|
// TODO: Find better way to restore after custom button is used!!!
|
||||||
|
subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx));
|
||||||
|
subghz_txrx_stop(subghz->txrx);
|
||||||
furi_hal_subghz_set_rolling_counter_mult(tmp_counter);
|
furi_hal_subghz_set_rolling_counter_mult(tmp_counter);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -48,4 +48,4 @@ void subghz_custom_btn_set_prog_mode(ProgMode prog_mode) {
|
|||||||
|
|
||||||
ProgMode subghz_custom_btn_get_prog_mode() {
|
ProgMode subghz_custom_btn_get_prog_mode() {
|
||||||
return controller_programming_mode;
|
return controller_programming_mode;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#define PROG_MODE_OFF (0U)
|
#define PROG_MODE_OFF (0U)
|
||||||
#define PROG_MODE_KEELOQ_BFT (1U)
|
#define PROG_MODE_KEELOQ_BFT (1U)
|
||||||
#define PROG_MODE_KEELOQ_APRIMATIC (2U)
|
#define PROG_MODE_KEELOQ_APRIMATIC (2U)
|
||||||
#define PROG_MODE_FAAC_SLH (3U)
|
|
||||||
|
|
||||||
typedef uint8_t ProgMode;
|
typedef uint8_t ProgMode;
|
||||||
|
|
||||||
@ -15,4 +14,4 @@ void subghz_custom_btn_set_max(uint8_t b);
|
|||||||
|
|
||||||
void subghz_custom_btn_set_prog_mode(ProgMode prog_mode);
|
void subghz_custom_btn_set_prog_mode(ProgMode prog_mode);
|
||||||
|
|
||||||
ProgMode subghz_custom_btn_get_prog_mode();
|
ProgMode subghz_custom_btn_get_prog_mode();
|
||||||
|
@ -25,8 +25,6 @@ struct SubGhzBlockGeneric {
|
|||||||
uint32_t cnt;
|
uint32_t cnt;
|
||||||
uint8_t cnt_2;
|
uint8_t cnt_2;
|
||||||
uint32_t seed;
|
uint32_t seed;
|
||||||
bool prg_mode : 1;
|
|
||||||
bool allow_zero_seed : 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include "../blocks/generic.h"
|
#include "../blocks/generic.h"
|
||||||
#include "../blocks/math.h"
|
#include "../blocks/math.h"
|
||||||
|
|
||||||
|
#include "../blocks/custom_btn_i.h"
|
||||||
|
|
||||||
#define TAG "SubGhzProtocolFaacSLH"
|
#define TAG "SubGhzProtocolFaacSLH"
|
||||||
|
|
||||||
static const SubGhzBlockConst subghz_protocol_faac_slh_const = {
|
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,
|
.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 {
|
struct SubGhzProtocolDecoderFaacSLH {
|
||||||
SubGhzProtocolDecoderBase base;
|
SubGhzProtocolDecoderBase base;
|
||||||
|
|
||||||
@ -110,18 +124,35 @@ void subghz_protocol_encoder_faac_slh_free(void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* instance) {
|
static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* instance) {
|
||||||
if(instance->generic.allow_zero_seed || (instance->generic.seed != 0x0)) {
|
// TODO: Stupid bypass for custom button, remake later
|
||||||
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
|
if(subghz_custom_btn_get_original() == 0) {
|
||||||
FURI_LOG_I(TAG, "Counter ++");
|
subghz_custom_btn_set_original(0xF);
|
||||||
} else if(instance->generic.prg_mode == true) {
|
}
|
||||||
|
|
||||||
|
uint8_t custom_btn_id = subghz_custom_btn_get();
|
||||||
|
bool button_for_programming = false;
|
||||||
|
|
||||||
|
// If custom button left is pressed, enable programming mode and disable it on Ok button
|
||||||
|
if((custom_btn_id == SUBGHZ_CUSTOM_BTN_OK)) {
|
||||||
|
button_for_programming = false;
|
||||||
|
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_UP) {
|
||||||
|
button_for_programming = true;
|
||||||
|
}
|
||||||
|
// If we are using UP button - generate programming mode key and send it, otherwise - send regular key if possible
|
||||||
|
if(button_for_programming) {
|
||||||
uint8_t data_tmp = 0;
|
uint8_t data_tmp = 0;
|
||||||
uint8_t data_prg[8];
|
uint8_t data_prg[8];
|
||||||
|
|
||||||
instance->generic.cnt_2++;
|
|
||||||
|
|
||||||
data_prg[0] = 0x00;
|
data_prg[0] = 0x00;
|
||||||
|
|
||||||
data_prg[1] = instance->generic.cnt_2;
|
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[2] = (uint8_t)(instance->generic.seed & 0xFF);
|
||||||
data_prg[3] = (uint8_t)(instance->generic.seed >> 8 & 0xFF);
|
data_prg[3] = (uint8_t)(instance->generic.seed >> 8 & 0xFF);
|
||||||
@ -133,27 +164,42 @@ static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* inst
|
|||||||
data_prg[4] ^= data_prg[1];
|
data_prg[4] ^= data_prg[1];
|
||||||
data_prg[5] ^= data_prg[1];
|
data_prg[5] ^= data_prg[1];
|
||||||
|
|
||||||
for(uint8_t i=data_prg[1] & 0x0F ; i!=0; i--) {
|
for(uint8_t i = data_prg[1] & 0x0F; i != 0; i--) {
|
||||||
data_tmp = data_prg[5];
|
data_tmp = data_prg[5];
|
||||||
|
|
||||||
data_prg[5] = ((data_prg[5] << 1) & 0xFF) | (data_prg[4] & 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[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[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[2] = ((data_prg[2] << 1) & 0xFF) | (data_tmp & 0x80) >> 7;
|
||||||
}
|
}
|
||||||
data_prg[6] = 0x0F;
|
data_prg[6] = 0x0F;
|
||||||
data_prg[7] = 0x52;
|
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_1 = data_prg[7] << 24 | data_prg[6] << 16 | data_prg[5] << 8 |
|
||||||
uint32_t enc_prg_2 = data_prg[3] << 24 | data_prg[2] << 16 | data_prg[1] << 8 | data_prg[0];
|
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;
|
instance->generic.data = (uint64_t)enc_prg_1 << 32 | enc_prg_2;
|
||||||
FURI_LOG_I(TAG, "New MasterKey encrypted : %016llX", instance->generic.data);
|
//FURI_LOG_D(TAG, "New Prog Mode Key Generated: %016llX\r", instance->generic.data);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// Do not generate new data, send data from buffer
|
if(!allow_zero_seed && (instance->generic.seed == 0x0)) {
|
||||||
FURI_LOG_I(TAG, "Unknown / Static mode");
|
// Do not generate new data, send data from buffer
|
||||||
return true;
|
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 fix = instance->generic.serial << 4 | instance->generic.btn;
|
||||||
uint32_t hop = 0;
|
uint32_t hop = 0;
|
||||||
@ -165,6 +211,11 @@ static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* inst
|
|||||||
for(int i = 0; i < 8; i++) {
|
for(int i = 0; i < 8; i++) {
|
||||||
fixx[i] = (fix >> (shiftby -= 4)) & 0xF;
|
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) {
|
if((instance->generic.cnt % 2) == 0) {
|
||||||
decrypt = fixx[6] << 28 | fixx[7] << 24 | fixx[5] << 20 |
|
decrypt = fixx[6] << 28 | fixx[7] << 24 | fixx[5] << 20 |
|
||||||
(instance->generic.cnt & 0xFFFFF);
|
(instance->generic.cnt & 0xFFFFF);
|
||||||
@ -211,7 +262,7 @@ bool subghz_protocol_faac_slh_create_data(
|
|||||||
instance->generic.seed = seed;
|
instance->generic.seed = seed;
|
||||||
instance->manufacture_name = manufacture_name;
|
instance->manufacture_name = manufacture_name;
|
||||||
instance->generic.data_count_bit = 64;
|
instance->generic.data_count_bit = 64;
|
||||||
instance->generic.allow_zero_seed = true;
|
allow_zero_seed = true;
|
||||||
bool res = subghz_protocol_faac_slh_gen_data(instance);
|
bool res = subghz_protocol_faac_slh_gen_data(instance);
|
||||||
if(res) {
|
if(res) {
|
||||||
return SubGhzProtocolStatusOk ==
|
return SubGhzProtocolStatusOk ==
|
||||||
@ -282,13 +333,11 @@ SubGhzProtocolStatus
|
|||||||
FURI_LOG_E(TAG, "Missing Seed");
|
FURI_LOG_E(TAG, "Missing Seed");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bool allow_zero_seed;
|
bool tmp_allow_zero_seed;
|
||||||
if(flipper_format_read_bool(flipper_format, "AllowZeroSeed", &allow_zero_seed, 1)) {
|
if(flipper_format_read_bool(flipper_format, "AllowZeroSeed", &tmp_allow_zero_seed, 1)) {
|
||||||
instance->generic.allow_zero_seed = true;
|
allow_zero_seed = true;
|
||||||
FURI_LOG_I(TAG, "Enc. des. TRUE");
|
|
||||||
} else {
|
} else {
|
||||||
instance->generic.allow_zero_seed = false;
|
allow_zero_seed = false;
|
||||||
FURI_LOG_I(TAG, "Enc. des. FALSE");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 |
|
instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 |
|
||||||
@ -452,11 +501,16 @@ static void subghz_protocol_faac_slh_check_remote_controller(
|
|||||||
const char** manufacture_name) {
|
const char** manufacture_name) {
|
||||||
uint32_t code_fix = instance->data >> 32;
|
uint32_t code_fix = instance->data >> 32;
|
||||||
uint32_t code_hop = instance->data & 0xFFFFFFFF;
|
uint32_t code_hop = instance->data & 0xFFFFFFFF;
|
||||||
instance->serial = code_fix >> 4;
|
|
||||||
instance->btn = code_fix & 0xF;
|
|
||||||
uint32_t decrypt = 0;
|
uint32_t decrypt = 0;
|
||||||
uint64_t man;
|
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_tmp = 0;
|
||||||
uint8_t data_prg[8];
|
uint8_t data_prg[8];
|
||||||
data_prg[0] = (code_hop & 0xFF);
|
data_prg[0] = (code_hop & 0xFF);
|
||||||
@ -468,36 +522,40 @@ static void subghz_protocol_faac_slh_check_remote_controller(
|
|||||||
data_prg[6] = ((code_fix >> 16) & 0xFF);
|
data_prg[6] = ((code_fix >> 16) & 0xFF);
|
||||||
data_prg[7] = (code_fix >> 24);
|
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;
|
faac_prog_mode = true;
|
||||||
// ProgMode ON
|
// ProgMode ON
|
||||||
FURI_LOG_I(TAG, "Master Key detected!");
|
|
||||||
|
|
||||||
for(uint8_t i = data_prg[1] & 0xF; i != 0; i--) {
|
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[2] = data_prg[2] >> 1 | (data_prg[3] & 1) << 7;
|
data_prg[4] = data_prg[4] >> 1 | (data_prg[5] & 1) << 7;
|
||||||
data_prg[3] = data_prg[3] >> 1 | (data_prg[4] & 1) << 7;
|
data_prg[5] = data_prg[5] >> 1 | (data_tmp & 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", instance->data_2);
|
|
||||||
instance->cnt_2 = data_prg[1];
|
|
||||||
} else {
|
|
||||||
instance->prg_mode = false;
|
|
||||||
}
|
}
|
||||||
|
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
|
for
|
||||||
M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) {
|
M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) {
|
||||||
@ -512,6 +570,10 @@ static void subghz_protocol_faac_slh_check_remote_controller(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
instance->cnt = decrypt & 0xFFFFF;
|
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) {
|
uint8_t subghz_protocol_decoder_faac_slh_get_hash_data(void* context) {
|
||||||
@ -530,6 +592,7 @@ SubGhzProtocolStatus subghz_protocol_decoder_faac_slh_serialize(
|
|||||||
|
|
||||||
// Reset seed leftover from previous decoded signal
|
// Reset seed leftover from previous decoded signal
|
||||||
instance->generic.seed = 0x0;
|
instance->generic.seed = 0x0;
|
||||||
|
temp_fix_backup = 0x0;
|
||||||
|
|
||||||
SubGhzProtocolStatus res =
|
SubGhzProtocolStatus res =
|
||||||
subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
|
subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
|
||||||
@ -577,13 +640,11 @@ SubGhzProtocolStatus
|
|||||||
FURI_LOG_E(TAG, "Missing Seed");
|
FURI_LOG_E(TAG, "Missing Seed");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bool allow_zero_seed;
|
bool tmp_allow_zero_seed;
|
||||||
if(flipper_format_read_bool(flipper_format, "AllowZeroSeed", &allow_zero_seed, 1)) {
|
if(flipper_format_read_bool(flipper_format, "AllowZeroSeed", &tmp_allow_zero_seed, 1)) {
|
||||||
instance->generic.allow_zero_seed = true;
|
allow_zero_seed = true;
|
||||||
FURI_LOG_I(TAG, "Dec. des. TRUE");
|
|
||||||
} else {
|
} else {
|
||||||
instance->generic.allow_zero_seed = false;
|
allow_zero_seed = false;
|
||||||
FURI_LOG_I(TAG, "Dec. des. FALSE");
|
|
||||||
}
|
}
|
||||||
instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 |
|
instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 |
|
||||||
seed_data[3];
|
seed_data[3];
|
||||||
@ -606,10 +667,11 @@ void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* outp
|
|||||||
uint32_t code_fix = instance->generic.data >> 32;
|
uint32_t code_fix = instance->generic.data >> 32;
|
||||||
uint32_t code_hop = instance->generic.data & 0xFFFFFFFF;
|
uint32_t code_hop = instance->generic.data & 0xFFFFFFFF;
|
||||||
|
|
||||||
if(instance->generic.prg_mode == true) {
|
if(faac_prog_mode == true) {
|
||||||
furi_string_cat_printf(
|
furi_string_cat_printf(
|
||||||
output,
|
output,
|
||||||
"%s %dbit\r\n"
|
"%s %dbit\r\n"
|
||||||
|
"Master Remote Prog Mode\r\n"
|
||||||
"Ke:%lX%08lX\r\n"
|
"Ke:%lX%08lX\r\n"
|
||||||
"Kd:%lX%08lX\r\n"
|
"Kd:%lX%08lX\r\n"
|
||||||
"Seed:%08lX mCnt:%02X",
|
"Seed:%08lX mCnt:%02X",
|
||||||
@ -620,8 +682,8 @@ 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 >> 32),
|
||||||
(uint32_t)instance->generic.data_2,
|
(uint32_t)instance->generic.data_2,
|
||||||
instance->generic.seed,
|
instance->generic.seed,
|
||||||
instance->generic.cnt_2);
|
(uint8_t)(instance->generic.cnt & 0xFF));
|
||||||
} else if(instance->generic.allow_zero_seed == false) {
|
} else if(allow_zero_seed == false) {
|
||||||
furi_string_cat_printf(
|
furi_string_cat_printf(
|
||||||
output,
|
output,
|
||||||
"%s %dbit\r\n"
|
"%s %dbit\r\n"
|
||||||
|
@ -129,3 +129,7 @@ SubGhzProtocolStatus
|
|||||||
* @param output Resulting text
|
* @param output Resulting text
|
||||||
*/
|
*/
|
||||||
void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* output);
|
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();
|
Loading…
Reference in New Issue
Block a user