mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-24 03:29:57 -07:00
Merge branch 'dev' of https://github.com/DarkFlippers/unleashed-firmware into xfw-dev
This commit is contained in:
@@ -42,8 +42,6 @@ static void subghz_test_rx_callback(
|
||||
|
||||
static void subghz_test_init(void) {
|
||||
environment_handler = subghz_environment_alloc();
|
||||
subghz_environment_set_came_atomo_rainbow_table_file_name(
|
||||
environment_handler, CAME_ATOMO_DIR_NAME);
|
||||
subghz_environment_set_nice_flor_s_rainbow_table_file_name(
|
||||
environment_handler, NICE_FLOR_S_DIR_NAME);
|
||||
subghz_environment_set_alutech_at_4n_rainbow_table_file_name(
|
||||
|
||||
@@ -196,6 +196,7 @@ bool ibutton_load_key(iButton* ibutton) {
|
||||
|
||||
bool ibutton_select_and_load_key(iButton* ibutton) {
|
||||
DialogsFileBrowserOptions browser_options;
|
||||
bool success = false;
|
||||
dialog_file_browser_set_basic_options(
|
||||
&browser_options, IBUTTON_APP_FILENAME_EXTENSION, &I_ibutt_10px);
|
||||
browser_options.base_path = IBUTTON_APP_FOLDER;
|
||||
@@ -204,9 +205,14 @@ bool ibutton_select_and_load_key(iButton* ibutton) {
|
||||
furi_string_set(ibutton->file_path, browser_options.base_path);
|
||||
}
|
||||
|
||||
return dialog_file_browser_show(
|
||||
ibutton->dialogs, ibutton->file_path, ibutton->file_path, &browser_options) &&
|
||||
ibutton_load_key(ibutton);
|
||||
do {
|
||||
if(!dialog_file_browser_show(
|
||||
ibutton->dialogs, ibutton->file_path, ibutton->file_path, &browser_options))
|
||||
break;
|
||||
success = ibutton_load_key(ibutton);
|
||||
} while(!success);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool ibutton_save_key(iButton* ibutton) {
|
||||
|
||||
@@ -6,6 +6,8 @@ typedef enum {
|
||||
SubGhzCustomEventManagerSetRAW,
|
||||
|
||||
//SubmenuIndex
|
||||
SubmenuIndexFaacSLH_Manual_433,
|
||||
SubmenuIndexFaacSLH_Manual_868,
|
||||
SubmenuIndexFaacSLH_433,
|
||||
SubmenuIndexFaacSLH_868,
|
||||
SubmenuIndexBFTClone,
|
||||
|
||||
@@ -46,8 +46,6 @@ SubGhzTxRx* subghz_txrx_alloc() {
|
||||
instance->is_database_loaded =
|
||||
subghz_environment_load_keystore(instance->environment, SUBGHZ_KEYSTORE_DIR_NAME);
|
||||
subghz_environment_load_keystore(instance->environment, SUBGHZ_KEYSTORE_DIR_USER_NAME);
|
||||
subghz_environment_set_came_atomo_rainbow_table_file_name(
|
||||
instance->environment, SUBGHZ_CAME_ATOMO_DIR_NAME);
|
||||
subghz_environment_set_alutech_at_4n_rainbow_table_file_name(
|
||||
instance->environment, SUBGHZ_ALUTECH_AT_4N_DIR_NAME);
|
||||
subghz_environment_set_nice_flor_s_rainbow_table_file_name(
|
||||
@@ -665,6 +663,8 @@ void subghz_txrx_reset_dynamic_and_custom_btns(SubGhzTxRx* instance) {
|
||||
furi_assert(instance);
|
||||
subghz_environment_reset_keeloq(instance->environment);
|
||||
|
||||
faac_slh_reset_prog_mode();
|
||||
|
||||
subghz_custom_btns_reset();
|
||||
}
|
||||
|
||||
|
||||
@@ -228,7 +228,9 @@ bool subghz_txrx_gen_faac_slh_protocol(
|
||||
seed_data[sizeof(uint32_t) - i - 1] = (seed >> i * 8) & 0xFF;
|
||||
}
|
||||
|
||||
bool tmp_allow_zero_seed = true;
|
||||
flipper_format_write_hex(txrx->fff_data, "Seed", seed_data, sizeof(uint32_t));
|
||||
flipper_format_write_bool(txrx->fff_data, "AllowZeroSeed", &tmp_allow_zero_seed, 1);
|
||||
}
|
||||
|
||||
subghz_transmitter_free(txrx->transmitter);
|
||||
|
||||
@@ -23,4 +23,4 @@ ADD_SCENE(subghz, more_raw, MoreRAW)
|
||||
ADD_SCENE(subghz, decode_raw, DecodeRAW)
|
||||
ADD_SCENE(subghz, delete_raw, DeleteRAW)
|
||||
ADD_SCENE(subghz, need_saving, NeedSaving)
|
||||
ADD_SCENE(subghz, rpc, Rpc)
|
||||
ADD_SCENE(subghz, rpc, Rpc)
|
||||
@@ -32,7 +32,7 @@ const char* const debug_pin_text[DEBUG_P_COUNT] = {
|
||||
"17(1W)",
|
||||
};
|
||||
|
||||
#define DEBUG_COUNTER_COUNT 6
|
||||
#define DEBUG_COUNTER_COUNT 13
|
||||
const char* const debug_counter_text[DEBUG_COUNTER_COUNT] = {
|
||||
"+1",
|
||||
"+2",
|
||||
@@ -40,6 +40,13 @@ const char* const debug_counter_text[DEBUG_COUNTER_COUNT] = {
|
||||
"+4",
|
||||
"+5",
|
||||
"+10",
|
||||
"0",
|
||||
"-1",
|
||||
"-2",
|
||||
"-3",
|
||||
"-4",
|
||||
"-5",
|
||||
"-10",
|
||||
};
|
||||
const uint32_t debug_counter_val[DEBUG_COUNTER_COUNT] = {
|
||||
1,
|
||||
@@ -48,6 +55,13 @@ const uint32_t debug_counter_val[DEBUG_COUNTER_COUNT] = {
|
||||
4,
|
||||
5,
|
||||
10,
|
||||
0,
|
||||
-1,
|
||||
-2,
|
||||
-3,
|
||||
-4,
|
||||
-5,
|
||||
-10,
|
||||
};
|
||||
|
||||
static void subghz_scene_radio_settings_set_device(VariableItem* item) {
|
||||
|
||||
@@ -130,7 +130,15 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) {
|
||||
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);
|
||||
}
|
||||
// Set file path to default
|
||||
furi_string_set(subghz->file_path, SUBGHZ_APP_FOLDER);
|
||||
|
||||
return true;
|
||||
} else if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == SubGhzCustomEventSceneSaveName) {
|
||||
|
||||
@@ -19,7 +19,7 @@ void subghz_scene_saved_menu_on_enter(void* context) {
|
||||
SubmenuIndexEmulate,
|
||||
subghz_scene_saved_menu_submenu_callback,
|
||||
subghz);
|
||||
|
||||
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"Rename",
|
||||
|
||||
@@ -18,7 +18,7 @@ void subghz_scene_set_cnt_on_enter(void* context) {
|
||||
|
||||
switch(state) {
|
||||
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,
|
||||
subghz_scene_set_cnt_byte_input_callback,
|
||||
@@ -27,9 +27,9 @@ void subghz_scene_set_cnt_on_enter(void* context) {
|
||||
subghz->secure_data->cnt,
|
||||
2);
|
||||
break;
|
||||
case SubmenuIndexFaacSLH_433:
|
||||
case SubmenuIndexFaacSLH_868:
|
||||
byte_input_set_header_text(byte_input, "Enter COUNTER in hex, 20bits");
|
||||
case SubmenuIndexFaacSLH_Manual_433:
|
||||
case SubmenuIndexFaacSLH_Manual_868:
|
||||
byte_input_set_header_text(byte_input, "Enter COUNTER in Hex 20 bits");
|
||||
byte_input_set_result_callback(
|
||||
byte_input,
|
||||
subghz_scene_set_cnt_byte_input_callback,
|
||||
|
||||
@@ -13,7 +13,7 @@ void subghz_scene_set_fix_on_enter(void* context) {
|
||||
|
||||
// Setup view
|
||||
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,
|
||||
subghz_scene_set_fix_byte_input_callback,
|
||||
|
||||
@@ -14,7 +14,7 @@ void subghz_scene_set_seed_on_enter(void* context) {
|
||||
|
||||
// Setup view
|
||||
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,
|
||||
subghz_scene_set_seed_byte_input_callback,
|
||||
@@ -45,13 +45,6 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) {
|
||||
seed = subghz->secure_data->seed[0] << 24 | subghz->secure_data->seed[1] << 16 |
|
||||
subghz->secure_data->seed[2] << 8 | subghz->secure_data->seed[3];
|
||||
|
||||
if(seed == 0) {
|
||||
furi_string_set(subghz->error_str, "Seed value\ncan not be 0.");
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
|
||||
consumed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
generated_protocol = subghz_txrx_gen_keeloq_bft_protocol(
|
||||
subghz->txrx,
|
||||
"AM650",
|
||||
@@ -69,8 +62,8 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) {
|
||||
}
|
||||
consumed = true;
|
||||
break;
|
||||
case SubmenuIndexFaacSLH_433:
|
||||
case SubmenuIndexFaacSLH_868:
|
||||
case SubmenuIndexFaacSLH_Manual_433:
|
||||
case SubmenuIndexFaacSLH_Manual_868:
|
||||
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];
|
||||
|
||||
@@ -80,13 +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 |
|
||||
subghz->secure_data->seed[2] << 8 | subghz->secure_data->seed[3];
|
||||
|
||||
if(seed == 0) {
|
||||
furi_string_set(subghz->error_str, "Seed value\ncan not be 0.");
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneShowError);
|
||||
consumed = true;
|
||||
break;
|
||||
}
|
||||
if(state == SubmenuIndexFaacSLH_433) {
|
||||
if(state == SubmenuIndexFaacSLH_Manual_433) {
|
||||
generated_protocol = subghz_txrx_gen_faac_slh_protocol(
|
||||
subghz->txrx,
|
||||
"AM650",
|
||||
@@ -96,7 +83,7 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) {
|
||||
(cnt & 0xFFFFF),
|
||||
seed,
|
||||
"FAAC_SLH");
|
||||
} else if(state == SubmenuIndexFaacSLH_868) {
|
||||
} else if(state == SubmenuIndexFaacSLH_Manual_868) {
|
||||
generated_protocol = subghz_txrx_gen_faac_slh_protocol(
|
||||
subghz->txrx,
|
||||
"AM650",
|
||||
|
||||
@@ -15,14 +15,14 @@ void subghz_scene_set_type_on_enter(void* context) {
|
||||
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"Faac SLH 868MHz",
|
||||
SubmenuIndexFaacSLH_868,
|
||||
"FAAC SLH [Man.] 868MHz",
|
||||
SubmenuIndexFaacSLH_Manual_868,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"Faac SLH 433MHz",
|
||||
SubmenuIndexFaacSLH_433,
|
||||
"FAAC SLH [Man.] 433MHz",
|
||||
SubmenuIndexFaacSLH_Manual_433,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
@@ -31,6 +31,18 @@ void subghz_scene_set_type_on_enter(void* context) {
|
||||
SubmenuIndexBFTClone,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"FAAC SLH 868MHz",
|
||||
SubmenuIndexFaacSLH_868,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"FAAC SLH 433MHz",
|
||||
SubmenuIndexFaacSLH_433,
|
||||
subghz_scene_set_type_submenu_callback,
|
||||
subghz);
|
||||
submenu_add_item(
|
||||
subghz->submenu,
|
||||
"BFT Mitto 433MHz",
|
||||
@@ -319,10 +331,10 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
uint32_t key = (uint32_t)rand();
|
||||
switch(event.event) {
|
||||
case SubmenuIndexFaacSLH_868:
|
||||
case SubmenuIndexFaacSLH_Manual_868:
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFix);
|
||||
break;
|
||||
case SubmenuIndexFaacSLH_433:
|
||||
case SubmenuIndexFaacSLH_Manual_433:
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetFix);
|
||||
break;
|
||||
case SubmenuIndexBFTClone:
|
||||
@@ -390,6 +402,38 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
|
||||
generated_protocol = subghz_txrx_gen_data_protocol(
|
||||
subghz->txrx, "AM650", 433920000, SUBGHZ_PROTOCOL_GATE_TX_NAME, rev_key, 24);
|
||||
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:
|
||||
generated_protocol = subghz_txrx_gen_keeloq_protocol(
|
||||
subghz->txrx,
|
||||
|
||||
@@ -101,11 +101,15 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) {
|
||||
subghz_txrx_stop(subghz->txrx);
|
||||
if(subghz_custom_btn_get() != SUBGHZ_CUSTOM_BTN_OK) {
|
||||
subghz_custom_btn_set(SUBGHZ_CUSTOM_BTN_OK);
|
||||
uint8_t tmp_counter = furi_hal_subghz_get_rolling_counter_mult();
|
||||
int8_t tmp_counter = furi_hal_subghz_get_rolling_counter_mult();
|
||||
furi_hal_subghz_set_rolling_counter_mult(0);
|
||||
// Calling restore!
|
||||
subghz_tx_start(subghz, subghz_txrx_get_fff_data(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);
|
||||
}
|
||||
if(subghz->fav_timeout) {
|
||||
|
||||
@@ -326,8 +326,6 @@ void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) {
|
||||
SubGhzEnvironment* environment = subghz_environment_alloc();
|
||||
subghz_environment_load_keystore(environment, SUBGHZ_KEYSTORE_DIR_NAME);
|
||||
subghz_environment_load_keystore(environment, SUBGHZ_KEYSTORE_DIR_USER_NAME);
|
||||
subghz_environment_set_came_atomo_rainbow_table_file_name(
|
||||
environment, SUBGHZ_CAME_ATOMO_DIR_NAME);
|
||||
subghz_environment_set_alutech_at_4n_rainbow_table_file_name(
|
||||
environment, SUBGHZ_ALUTECH_AT_4N_DIR_NAME);
|
||||
subghz_environment_set_nice_flor_s_rainbow_table_file_name(
|
||||
@@ -526,8 +524,6 @@ void subghz_cli_command_decode_raw(Cli* cli, FuriString* args, void* context) {
|
||||
printf(
|
||||
"SubGhz decode_raw: Load_keystore keeloq_mfcodes_user \033[0;31mERROR\033[0m\r\n");
|
||||
}
|
||||
subghz_environment_set_came_atomo_rainbow_table_file_name(
|
||||
environment, SUBGHZ_CAME_ATOMO_DIR_NAME);
|
||||
subghz_environment_set_alutech_at_4n_rainbow_table_file_name(
|
||||
environment, SUBGHZ_ALUTECH_AT_4N_DIR_NAME);
|
||||
subghz_environment_set_nice_flor_s_rainbow_table_file_name(
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
typedef struct {
|
||||
uint8_t fix[4];
|
||||
uint8_t cnt[3];
|
||||
uint8_t cnt[4];
|
||||
uint8_t seed[4];
|
||||
} SecureData;
|
||||
|
||||
|
||||
@@ -313,7 +313,8 @@ void elements_multiline_text_aligned(
|
||||
} else if((y + font_height) > canvas_height(canvas)) {
|
||||
line = furi_string_alloc_printf("%.*s...\n", chars_fit, start);
|
||||
} else {
|
||||
line = furi_string_alloc_printf("%.*s-\n", chars_fit, start);
|
||||
// Account for the added "-" in length
|
||||
line = furi_string_alloc_printf("%.*s-\n", chars_fit - 1, start);
|
||||
}
|
||||
canvas_draw_str_aligned(canvas, x, y, horizontal, vertical, furi_string_get_cstr(line));
|
||||
furi_string_free(line);
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
Filetype: Flipper SubGhz Keystore RAW File
|
||||
Version: 0
|
||||
Encryption: 1
|
||||
IV: 47 69 6D 6D 65 20 74 68 65 63 6F 6F 6B 69 65 73
|
||||
Encrypt_data: RAW
|
||||
E0BDF15D68F29AE787E7FCEE6C3611C90A92305D677B8FFFBE225196F5DC04CAEAE1102B4AB830E76C9C14DBA7FA5BD1F30864ABAF51387222FDCC0BA87E4FF709812D5C59DD953859AFD698A0EA2ECEFA0DC49652861EF4CF1864843F135DB8680E0C5C9EEC3BC548E2EB696DC8CA1B0F627347D2C476B410CF03A0F4D1EFB36DFB0574FE8F48FB61910CA539EC04583CA170A51822225A1D3E86C07219FE92E5DE9F557A45E611D74028BAF56E7F2C53DBA8DC53DA89B642FAC0A9A0BAC1756BDA0833ACB09F56E0FA3080CBE9E6A04B235F3AC82BB955FBFD779C59725E6D1875E04E0E84ABD0C3C1C8FAB247EC2755ACEC9961244E0D79AE710E4C7D33E9
|
||||
@@ -8,6 +8,9 @@ from fbt_extra.util import (
|
||||
link_elf_dir_as_latest,
|
||||
)
|
||||
|
||||
from fbt.sdk.cache import LazySdkVersionLoader
|
||||
|
||||
|
||||
Import("ENV", "fw_build_meta")
|
||||
|
||||
# Building initial C environment for libs
|
||||
@@ -71,6 +74,8 @@ env = ENV.Clone(
|
||||
},
|
||||
FW_API_TABLE=None,
|
||||
_APP_ICONS=None,
|
||||
APPS=_.split(",") if (_ := GetOption("extra_int_apps")) else [],
|
||||
EXTRA_EXT_APPS=_.split(",") if (_ := GetOption("extra_ext_apps")) else [],
|
||||
)
|
||||
|
||||
env.PreConfigureFwEnvionment()
|
||||
@@ -125,9 +130,6 @@ if env["IS_BASE_FIRMWARE"]:
|
||||
else:
|
||||
fwenv.Append(APPS=["updater"])
|
||||
|
||||
if extra_int_apps := GetOption("extra_int_apps"):
|
||||
fwenv.Append(APPS=extra_int_apps.split(","))
|
||||
|
||||
|
||||
for app_dir, _ in fwenv["APPDIRS"]:
|
||||
app_dir_node = env.Dir("#").Dir(app_dir)
|
||||
@@ -136,7 +138,6 @@ for app_dir, _ in fwenv["APPDIRS"]:
|
||||
if isinstance(entry, FS.Dir) and not str(entry).startswith("."):
|
||||
fwenv.LoadAppManifest(entry)
|
||||
|
||||
|
||||
fwenv.PrepareApplicationsBuild()
|
||||
|
||||
# Build external apps + configure SDK
|
||||
@@ -148,6 +149,11 @@ if env["IS_BASE_FIRMWARE"]:
|
||||
)
|
||||
fw_artifacts.append(fwenv["FW_EXTAPPS"].sdk_tree)
|
||||
|
||||
fwenv.Append(FBT_API_VERSION=LazySdkVersionLoader(fwenv.subst("$SDK_DEFINITION")))
|
||||
fwenv.PhonyTarget(
|
||||
"get_apiversion",
|
||||
"@echo $( ${FBT_API_VERSION} $)",
|
||||
)
|
||||
|
||||
# Add preprocessor definitions for current set of apps
|
||||
fwenv.Append(
|
||||
|
||||
@@ -1461,7 +1461,7 @@ Function,+,furi_hal_subghz_flush_tx,void,
|
||||
Function,+,furi_hal_subghz_get_data_gpio,const GpioPin*,
|
||||
Function,+,furi_hal_subghz_get_ext_power_amp,_Bool,
|
||||
Function,+,furi_hal_subghz_get_lqi,uint8_t,
|
||||
Function,+,furi_hal_subghz_get_rolling_counter_mult,uint8_t,
|
||||
Function,+,furi_hal_subghz_get_rolling_counter_mult,int8_t,
|
||||
Function,+,furi_hal_subghz_get_rssi,float,
|
||||
Function,+,furi_hal_subghz_idle,void,
|
||||
Function,-,furi_hal_subghz_init,void,
|
||||
@@ -1481,7 +1481,7 @@ Function,+,furi_hal_subghz_set_ext_power_amp,void,_Bool
|
||||
Function,+,furi_hal_subghz_set_frequency,uint32_t,uint32_t
|
||||
Function,+,furi_hal_subghz_set_frequency_and_path,uint32_t,uint32_t
|
||||
Function,+,furi_hal_subghz_set_path,void,FuriHalSubGhzPath
|
||||
Function,+,furi_hal_subghz_set_rolling_counter_mult,void,uint8_t
|
||||
Function,+,furi_hal_subghz_set_rolling_counter_mult,void,int8_t
|
||||
Function,+,furi_hal_subghz_shutdown,void,
|
||||
Function,+,furi_hal_subghz_sleep,void,
|
||||
Function,+,furi_hal_subghz_start_async_rx,void,"FuriHalSubGhzCaptureCallback, void*"
|
||||
|
||||
|
@@ -489,7 +489,7 @@ bool furi_hal_bt_custom_adv_set(const uint8_t* adv_data, size_t adv_len) {
|
||||
FURI_LOG_E(TAG, "custom_adv_set failed %d", status);
|
||||
return false;
|
||||
} else {
|
||||
FURI_LOG_I(TAG, "custom_adv_set success");
|
||||
FURI_LOG_D(TAG, "custom_adv_set success");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -511,7 +511,7 @@ bool furi_hal_bt_custom_adv_start(
|
||||
FURI_LOG_E(TAG, "custom_adv_start failed %d", status);
|
||||
return false;
|
||||
} else {
|
||||
FURI_LOG_I(TAG, "custom_adv_start success");
|
||||
FURI_LOG_D(TAG, "custom_adv_start success");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -522,7 +522,7 @@ bool furi_hal_bt_custom_adv_stop() {
|
||||
FURI_LOG_E(TAG, "custom_adv_stop failed %d", status);
|
||||
return false;
|
||||
} else {
|
||||
FURI_LOG_I(TAG, "custom_adv_stop success");
|
||||
FURI_LOG_D(TAG, "custom_adv_stop success");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ typedef struct {
|
||||
volatile SubGhzRegulation regulation;
|
||||
const GpioPin* async_mirror_pin;
|
||||
|
||||
uint8_t rolling_counter_mult;
|
||||
int8_t rolling_counter_mult;
|
||||
bool ext_power_amp : 1;
|
||||
bool extended_frequency_i : 1;
|
||||
} FuriHalSubGhz;
|
||||
@@ -66,11 +66,11 @@ volatile FuriHalSubGhz furi_hal_subghz = {
|
||||
.extended_frequency_i = false,
|
||||
};
|
||||
|
||||
uint8_t furi_hal_subghz_get_rolling_counter_mult(void) {
|
||||
int8_t furi_hal_subghz_get_rolling_counter_mult(void) {
|
||||
return furi_hal_subghz.rolling_counter_mult;
|
||||
}
|
||||
|
||||
void furi_hal_subghz_set_rolling_counter_mult(uint8_t mult) {
|
||||
void furi_hal_subghz_set_rolling_counter_mult(int8_t mult) {
|
||||
furi_hal_subghz.rolling_counter_mult = mult;
|
||||
}
|
||||
|
||||
|
||||
@@ -173,15 +173,15 @@ uint32_t furi_hal_subghz_set_frequency_and_path(uint32_t value);
|
||||
*/
|
||||
bool furi_hal_subghz_is_tx_allowed(uint32_t value);
|
||||
|
||||
/** Get the current rolling protocols counter ++ value
|
||||
* @return uint8_t current value
|
||||
/** Get the current rolling protocols counter ++/-- value
|
||||
* @return int8_t current value
|
||||
*/
|
||||
uint8_t furi_hal_subghz_get_rolling_counter_mult(void);
|
||||
int8_t furi_hal_subghz_get_rolling_counter_mult(void);
|
||||
|
||||
/** Set the current rolling protocols counter ++ value
|
||||
* @param mult uint8_t = 1, 2, 4, 8
|
||||
/** Set the current rolling protocols counter ++/-- value
|
||||
* @param mult int8_t = -1, -10, -100, 0, 1, 10, 100
|
||||
*/
|
||||
void furi_hal_subghz_set_rolling_counter_mult(uint8_t mult);
|
||||
void furi_hal_subghz_set_rolling_counter_mult(int8_t mult);
|
||||
|
||||
/** Set frequency
|
||||
*
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -188,8 +188,19 @@ class AppManager:
|
||||
raise FlipperManifestException(f"Duplicate app declaration: {app.appid}")
|
||||
self.known_apps[app.appid] = app
|
||||
|
||||
def filter_apps(self, applist: List[str], hw_target: str):
|
||||
return AppBuildset(self, applist, hw_target)
|
||||
def filter_apps(
|
||||
self,
|
||||
*,
|
||||
applist: List[str],
|
||||
ext_applist: List[str],
|
||||
hw_target: str,
|
||||
):
|
||||
return AppBuildset(
|
||||
self,
|
||||
hw_target=hw_target,
|
||||
appnames=applist,
|
||||
extra_ext_appnames=ext_applist,
|
||||
)
|
||||
|
||||
|
||||
class AppBuilderException(Exception):
|
||||
@@ -206,6 +217,12 @@ class AppBuildset:
|
||||
FlipperAppType.SETTINGS,
|
||||
FlipperAppType.STARTUP,
|
||||
)
|
||||
EXTERNAL_APP_TYPES = (
|
||||
FlipperAppType.EXTERNAL,
|
||||
FlipperAppType.MENUEXTERNAL,
|
||||
FlipperAppType.PLUGIN,
|
||||
FlipperAppType.DEBUG,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def print_writer(message):
|
||||
@@ -214,16 +231,21 @@ class AppBuildset:
|
||||
def __init__(
|
||||
self,
|
||||
appmgr: AppManager,
|
||||
appnames: List[str],
|
||||
hw_target: str,
|
||||
appnames: List[str],
|
||||
*,
|
||||
extra_ext_appnames: List[str],
|
||||
message_writer: Callable | None = None,
|
||||
):
|
||||
self.appmgr = appmgr
|
||||
self.appnames = set(appnames)
|
||||
self.incompatible_extapps, self.extapps = [], []
|
||||
self._extra_ext_appnames = extra_ext_appnames
|
||||
self._orig_appnames = appnames
|
||||
self.hw_target = hw_target
|
||||
self._writer = message_writer if message_writer else self.print_writer
|
||||
self._process_deps()
|
||||
self._process_ext_apps()
|
||||
self._check_conflicts()
|
||||
self._check_unsatisfied() # unneeded?
|
||||
self._check_target_match()
|
||||
@@ -267,6 +289,27 @@ class AppBuildset:
|
||||
break
|
||||
self.appnames.update(provided)
|
||||
|
||||
def _process_ext_apps(self):
|
||||
extapps = [
|
||||
app
|
||||
for apptype in self.EXTERNAL_APP_TYPES
|
||||
for app in self.get_apps_of_type(apptype, True)
|
||||
]
|
||||
extapps.extend(map(self.appmgr.get, self._extra_ext_appnames))
|
||||
|
||||
for app in extapps:
|
||||
(
|
||||
self.extapps
|
||||
if app.supports_hardware_target(self.hw_target)
|
||||
else self.incompatible_extapps
|
||||
).append(app)
|
||||
|
||||
def get_ext_apps(self):
|
||||
return self.extapps
|
||||
|
||||
def get_incompatible_ext_apps(self):
|
||||
return self.incompatible_extapps
|
||||
|
||||
def _check_conflicts(self):
|
||||
conflicts = []
|
||||
for app in self.appnames:
|
||||
|
||||
@@ -255,3 +255,18 @@ class SdkCache:
|
||||
self.sync_sets(self.sdk.headers, api.headers, False)
|
||||
self.sync_sets(self.sdk.functions, api.functions)
|
||||
self.sync_sets(self.sdk.variables, api.variables)
|
||||
|
||||
|
||||
class LazySdkVersionLoader:
|
||||
def __init__(self, sdk_path: str):
|
||||
self.sdk_path = sdk_path
|
||||
self._version = None
|
||||
|
||||
@property
|
||||
def version(self) -> SdkVersion:
|
||||
if self._version is None:
|
||||
self._version = SdkCache(self.sdk_path, load_version_only=True).version
|
||||
return self._version
|
||||
|
||||
def __str__(self) -> str:
|
||||
return str(self.version)
|
||||
|
||||
@@ -36,7 +36,9 @@ def LoadAppManifest(env, entry):
|
||||
def PrepareApplicationsBuild(env):
|
||||
try:
|
||||
appbuild = env["APPBUILD"] = env["APPMGR"].filter_apps(
|
||||
env["APPS"], env.subst("f${TARGET_HW}")
|
||||
applist=env["APPS"],
|
||||
ext_applist=env["EXTRA_EXT_APPS"],
|
||||
hw_target=env.subst("f${TARGET_HW}"),
|
||||
)
|
||||
except Exception as e:
|
||||
raise StopError(e)
|
||||
@@ -56,6 +58,11 @@ def DumpApplicationConfig(target, source, env):
|
||||
fg.green(f"{apptype.value}:\n\t"),
|
||||
", ".join(app.appid for app in app_sublist),
|
||||
)
|
||||
if incompatible_ext_apps := env["APPBUILD"].get_incompatible_ext_apps():
|
||||
print(
|
||||
fg.blue("Incompatible apps (skipped):\n\t"),
|
||||
", ".join(app.appid for app in incompatible_ext_apps),
|
||||
)
|
||||
|
||||
|
||||
def build_apps_c(target, source, env):
|
||||
|
||||
@@ -107,6 +107,7 @@ env = core_env.Clone(
|
||||
SINGLEQUOTEFUNC=single_quote,
|
||||
ABSPATHGETTERFUNC=resolve_real_dir_node,
|
||||
APPS=[],
|
||||
EXTRA_EXT_APPS=[],
|
||||
UFBT_API_VERSION=SdkCache(
|
||||
core_env.subst("$SDK_DEFINITION"), load_version_only=True
|
||||
).version,
|
||||
|
||||
@@ -60,40 +60,12 @@ class FlipperExtAppBuildArtifacts:
|
||||
sdk_tree: NodeList = field(default_factory=NodeList)
|
||||
|
||||
|
||||
apps_to_build_as_faps = [
|
||||
FlipperAppType.PLUGIN,
|
||||
FlipperAppType.EXTERNAL,
|
||||
FlipperAppType.MENUEXTERNAL,
|
||||
FlipperAppType.DEBUG,
|
||||
]
|
||||
|
||||
known_extapps = [
|
||||
app
|
||||
for apptype in apps_to_build_as_faps
|
||||
for app in appenv["APPBUILD"].get_apps_of_type(apptype, True)
|
||||
]
|
||||
|
||||
# Ugly access to global option
|
||||
if extra_app_list := GetOption("extra_ext_apps"):
|
||||
known_extapps.extend(map(appenv["APPMGR"].get, extra_app_list.split(",")))
|
||||
|
||||
incompatible_apps = []
|
||||
for app in known_extapps:
|
||||
if not app.supports_hardware_target(appenv.subst("f${TARGET_HW}")):
|
||||
incompatible_apps.append(app)
|
||||
continue
|
||||
|
||||
for app in appenv["APPBUILD"].get_ext_apps():
|
||||
appenv.BuildAppElf(app)
|
||||
|
||||
extapps = FlipperExtAppBuildArtifacts()
|
||||
extapps.application_map = appenv["EXT_APPS"]
|
||||
|
||||
if incompatible_apps:
|
||||
warn(
|
||||
WarningOnByDefault,
|
||||
f"Skipping build of {len(incompatible_apps)} incompatible app(s): "
|
||||
+ ", ".join(f"'{app.name}' (id '{app.appid}')" for app in incompatible_apps),
|
||||
)
|
||||
|
||||
if appenv["FORCE"]:
|
||||
appenv.AlwaysBuild(
|
||||
|
||||
Reference in New Issue
Block a user