From 0af8bd1e8bdd24727b35d6cc9db6400445f7e2f7 Mon Sep 17 00:00:00 2001 From: Eng1n33r <101719414+Eng1n33r@users.noreply.github.com> Date: Fri, 18 Aug 2023 16:41:35 +0300 Subject: [PATCH 01/59] Test FAAC 0x0 seed --- lib/subghz/protocols/faac_slh.c | 59 ++++++++++----------------------- 1 file changed, 18 insertions(+), 41 deletions(-) diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index 3ae6c8e23..ecc1266ee 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -110,12 +110,7 @@ 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 - return true; - } + instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); uint32_t fix = instance->generic.serial << 4 | instance->generic.btn; uint32_t hop = 0; uint32_t decrypt = 0; @@ -507,39 +502,21 @@ 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) { - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:%lX%08lX\r\n" - "Fix:%08lX\r\n" - "Hop:%08lX Btn:%X\r\n" - "Sn:%07lX Sd:Unknown", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)instance->generic.data, - code_fix, - code_hop, - instance->generic.btn, - instance->generic.serial); - } else { - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:%lX%08lX\r\n" - "Fix:%08lX Cnt:%05lX\r\n" - "Hop:%08lX Btn:%X\r\n" - "Sn:%07lX Sd:%08lX", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)instance->generic.data, - code_fix, - instance->generic.cnt, - code_hop, - instance->generic.btn, - instance->generic.serial, - instance->generic.seed); - } + furi_string_cat_printf( + output, + "%s %dbit\r\n" + "Key:%lX%08lX\r\n" + "Fix:%08lX Cnt:%05lX\r\n" + "Hop:%08lX Btn:%X\r\n" + "Sn:%07lX Sd:%08lX", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->generic.data >> 32), + (uint32_t)instance->generic.data, + code_fix, + instance->generic.cnt, + code_hop, + instance->generic.btn, + instance->generic.serial, + instance->generic.seed); } From 2458cb2b96244e274a9e69171243a1b00d381731 Mon Sep 17 00:00:00 2001 From: Eng1n33r <101719414+Eng1n33r@users.noreply.github.com> Date: Fri, 18 Aug 2023 22:35:13 +0300 Subject: [PATCH 02/59] Allow 0x0 seed for testing --- .../main/subghz/scenes/subghz_scene_set_seed.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/applications/main/subghz/scenes/subghz_scene_set_seed.c b/applications/main/subghz/scenes/subghz_scene_set_seed.c index e5778b84f..f7727f0d6 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_seed.c +++ b/applications/main/subghz/scenes/subghz_scene_set_seed.c @@ -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", @@ -80,12 +73,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; - } if(state == SubmenuIndexFaacSLH_433) { generated_protocol = subghz_txrx_gen_faac_slh_protocol( subghz->txrx, From 69debc36a0e155d2c1aca68bd04b23fce8436ff2 Mon Sep 17 00:00:00 2001 From: Eng1n33r <101719414+Eng1n33r@users.noreply.github.com> Date: Mon, 21 Aug 2023 04:18:47 +0300 Subject: [PATCH 03/59] FAAC SLH 0x0 seed new "smart logic" Comeback --- .../helpers/subghz_txrx_create_protocol_key.c | 2 + lib/subghz/protocols/faac_slh.c | 79 ++++++++++++++----- 2 files changed, 63 insertions(+), 18 deletions(-) diff --git a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c index 0a9d12909..614f3fcf3 100644 --- a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c +++ b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c @@ -229,6 +229,8 @@ bool subghz_txrx_gen_faac_slh_protocol( } flipper_format_write_hex(txrx->fff_data, "Seed", seed_data, sizeof(uint32_t)); + flipper_format_write_string_cstr(txrx->fff_data, "Valid", "1\n"); + FURI_LOG_I(TAG, "Flag write to SD is OK"); } subghz_transmitter_free(txrx->transmitter); diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index ecc1266ee..848a61d9a 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -10,6 +10,8 @@ #define TAG "SubGhzProtocolFaacSLH" +bool bvalid; + static const SubGhzBlockConst subghz_protocol_faac_slh_const = { .te_short = 255, .te_long = 595, @@ -110,7 +112,14 @@ void subghz_protocol_encoder_faac_slh_free(void* context) { } static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* instance) { - instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); + if(bvalid) { + instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); + FURI_LOG_I(TAG, "[gen_data] TRUE : %i", bvalid); + } else { + // Do not generate new data, send data from buffer + FURI_LOG_I(TAG, "[gen_data] FALSE : %i", bvalid); + //return true; + } uint32_t fix = instance->generic.serial << 4 | instance->generic.btn; uint32_t hop = 0; uint32_t decrypt = 0; @@ -237,6 +246,14 @@ SubGhzProtocolStatus FURI_LOG_E(TAG, "Missing Seed"); break; } + FuriString* valid = furi_string_alloc(); + if(flipper_format_read_string(flipper_format, "Valid", valid)) { + bvalid = true; + FURI_LOG_I(TAG, "[encoder_des] Valid : %i", bvalid); + } else { + bvalid = false; + } + furi_string_free(valid); instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 | seed_data[3]; @@ -481,6 +498,14 @@ SubGhzProtocolStatus FURI_LOG_E(TAG, "Missing Seed"); break; } + FuriString* valid = furi_string_alloc(); + if(flipper_format_read_string(flipper_format, "Valid", valid)) { + bvalid = true; + FURI_LOG_I(TAG, "[decoder_des] Valid : %i", bvalid); + } else { + bvalid = false; + } + furi_string_free(valid); instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 | seed_data[3]; @@ -502,21 +527,39 @@ 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; - furi_string_cat_printf( - output, - "%s %dbit\r\n" - "Key:%lX%08lX\r\n" - "Fix:%08lX Cnt:%05lX\r\n" - "Hop:%08lX Btn:%X\r\n" - "Sn:%07lX Sd:%08lX", - instance->generic.protocol_name, - instance->generic.data_count_bit, - (uint32_t)(instance->generic.data >> 32), - (uint32_t)instance->generic.data, - code_fix, - instance->generic.cnt, - code_hop, - instance->generic.btn, - instance->generic.serial, - instance->generic.seed); + if(bvalid == false) { + furi_string_cat_printf( + output, + "%s %dbit\r\n" + "Key:%lX%08lX\r\n" + "Fix:%08lX\r\n" + "Hop:%08lX Btn:%X\r\n" + "Sn:%07lX Sd:Unknown", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->generic.data >> 32), + (uint32_t)instance->generic.data, + code_fix, + code_hop, + instance->generic.btn, + instance->generic.serial); + } else { + furi_string_cat_printf( + output, + "%s %dbit\r\n" + "Key:%lX%08lX\r\n" + "Fix:%08lX Cnt:%05lX\r\n" + "Hop:%08lX Btn:%X\r\n" + "Sn:%07lX Sd:%08lX", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->generic.data >> 32), + (uint32_t)instance->generic.data, + code_fix, + instance->generic.cnt, + code_hop, + instance->generic.btn, + instance->generic.serial, + instance->generic.seed); + } } From 2b5ad4f5afee0a8f56286432f437a042ed4bb970 Mon Sep 17 00:00:00 2001 From: Eng1n33r <101719414+Eng1n33r@users.noreply.github.com> Date: Tue, 22 Aug 2023 20:22:49 +0300 Subject: [PATCH 04/59] Correct counter work. FAAC SLH bugfix. --- .../main/subghz/scenes/subghz_scene_config.h | 1 + .../subghz/scenes/subghz_scene_edit_cnt.c | 57 +++++++++++++++++++ .../subghz/scenes/subghz_scene_saved_menu.c | 13 +++++ .../main/subghz/scenes/subghz_scene_set_cnt.c | 2 +- applications/main/subghz/subghz_i.h | 2 +- lib/subghz/protocols/alutech_at_4n.c | 2 +- lib/subghz/protocols/came_atomo.c | 2 +- lib/subghz/protocols/faac_slh.c | 27 ++++++--- lib/subghz/protocols/keeloq.c | 10 +++- lib/subghz/protocols/keeloq.h | 7 +++ lib/subghz/protocols/kinggates_stylo_4k.c | 2 +- lib/subghz/protocols/nice_flor_s.c | 2 +- lib/subghz/protocols/somfy_keytis.c | 2 +- lib/subghz/protocols/somfy_telis.c | 2 +- lib/subghz/protocols/star_line.c | 2 +- 15 files changed, 115 insertions(+), 18 deletions(-) create mode 100644 applications/main/subghz/scenes/subghz_scene_edit_cnt.c diff --git a/applications/main/subghz/scenes/subghz_scene_config.h b/applications/main/subghz/scenes/subghz_scene_config.h index ddff47208..311f954c5 100644 --- a/applications/main/subghz/scenes/subghz_scene_config.h +++ b/applications/main/subghz/scenes/subghz_scene_config.h @@ -24,3 +24,4 @@ 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, edit_cnt, EditCnt) \ No newline at end of file diff --git a/applications/main/subghz/scenes/subghz_scene_edit_cnt.c b/applications/main/subghz/scenes/subghz_scene_edit_cnt.c new file mode 100644 index 000000000..f5d0d483b --- /dev/null +++ b/applications/main/subghz/scenes/subghz_scene_edit_cnt.c @@ -0,0 +1,57 @@ +#include "../subghz_i.h" +#include + +#define TAG "SubGhzEditCnt" + +void subghz_scene_edit_cnt_byte_input_callback(void* context) { + SubGhz* subghz = context; + + view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventByteInputDone); +} + +void subghz_scene_edit_cnt_on_enter(void* context) { + SubGhz* subghz = context; + + // Setup view + ByteInput* byte_input = subghz->byte_input; + + byte_input_set_header_text(byte_input, "Enter COUNTER in hex"); + byte_input_set_result_callback( + byte_input, + subghz_scene_edit_cnt_byte_input_callback, + NULL, + subghz, + subghz->secure_data->cnt, + 4); + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdByteInput); +} + +bool subghz_scene_edit_cnt_on_event(void* context, SceneManagerEvent event) { + SubGhz* subghz = context; + bool consumed = false; + uint32_t cnt; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubGhzCustomEventByteInputDone) { + cnt = subghz->secure_data->cnt[0] << 24 | subghz->secure_data->cnt[1] << 16 | + subghz->secure_data->cnt[2] << 8 | subghz->secure_data->cnt[3]; + FURI_LOG_I(TAG, "cnt = %08lX", cnt); + if(subghz_protocol_keeloq_edit_cnt(subghz->txrx, cnt)) { + FURI_LOG_I(TAG, "Hook func from scene to protocol OK"); + }; + + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTransmitter); + consumed = true; + } + memset(subghz->secure_data->cnt, 0, sizeof(subghz->secure_data->cnt)); + } + return consumed; +} + +void subghz_scene_edit_cnt_on_exit(void* context) { + SubGhz* subghz = context; + + // Clear view + byte_input_set_result_callback(subghz->byte_input, NULL, NULL, NULL, NULL, 0); + byte_input_set_header_text(subghz->byte_input, ""); +} \ No newline at end of file diff --git a/applications/main/subghz/scenes/subghz_scene_saved_menu.c b/applications/main/subghz/scenes/subghz_scene_saved_menu.c index a65830f4b..3672be9e4 100644 --- a/applications/main/subghz/scenes/subghz_scene_saved_menu.c +++ b/applications/main/subghz/scenes/subghz_scene_saved_menu.c @@ -4,6 +4,7 @@ enum SubmenuIndex { SubmenuIndexEmulate, SubmenuIndexEdit, SubmenuIndexDelete, + SubmenuIndesEditCnt, }; void subghz_scene_saved_menu_submenu_callback(void* context, uint32_t index) { @@ -19,6 +20,13 @@ void subghz_scene_saved_menu_on_enter(void* context) { SubmenuIndexEmulate, subghz_scene_saved_menu_submenu_callback, subghz); + + submenu_add_item( + subghz->submenu, + "Edit counter", + SubmenuIndexEditCnt, + subghz_scene_saved_menu_submenu_callback, + subghz); submenu_add_item( subghz->submenu, @@ -60,6 +68,11 @@ bool subghz_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { subghz->scene_manager, SubGhzSceneSavedMenu, SubmenuIndexEdit); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); return true; + } else if(event.event == SubmenuIndexEditCnt) { + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneSavedMenu, SubmenuIndexEditCnt); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneEditCnt); + return true; } } return false; diff --git a/applications/main/subghz/scenes/subghz_scene_set_cnt.c b/applications/main/subghz/scenes/subghz_scene_set_cnt.c index 4faff7bbb..35c6c1c92 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_cnt.c +++ b/applications/main/subghz/scenes/subghz_scene_set_cnt.c @@ -29,7 +29,7 @@ void subghz_scene_set_cnt_on_enter(void* context) { break; case SubmenuIndexFaacSLH_433: case SubmenuIndexFaacSLH_868: - byte_input_set_header_text(byte_input, "Enter COUNTER in hex, 20bits"); + 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, diff --git a/applications/main/subghz/subghz_i.h b/applications/main/subghz/subghz_i.h index 8d01c845d..6a266bf51 100644 --- a/applications/main/subghz/subghz_i.h +++ b/applications/main/subghz/subghz_i.h @@ -45,7 +45,7 @@ typedef struct { uint8_t fix[4]; - uint8_t cnt[3]; + uint8_t cnt[4]; uint8_t seed[4]; } SecureData; diff --git a/lib/subghz/protocols/alutech_at_4n.c b/lib/subghz/protocols/alutech_at_4n.c index 1a35550c6..2a16cae85 100644 --- a/lib/subghz/protocols/alutech_at_4n.c +++ b/lib/subghz/protocols/alutech_at_4n.c @@ -274,7 +274,7 @@ static bool subghz_protocol_alutech_at_4n_gen_data( } if(instance->generic.cnt < 0xFFFF) { - if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) { + if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { instance->generic.cnt = 0; } else { instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); diff --git a/lib/subghz/protocols/came_atomo.c b/lib/subghz/protocols/came_atomo.c index cea7ebf6f..0d9545020 100644 --- a/lib/subghz/protocols/came_atomo.c +++ b/lib/subghz/protocols/came_atomo.c @@ -186,7 +186,7 @@ static void subghz_protocol_encoder_came_atomo_get_upload( uint8_t pack[8] = {}; if(instance->generic.cnt < 0xFFFF) { - if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) { + if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { instance->generic.cnt = 0; } else { instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index 848a61d9a..a69be67be 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -111,14 +111,23 @@ void subghz_protocol_encoder_faac_slh_free(void* context) { free(instance); } -static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* instance) { +static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* instance, FlipperFormat* flipper_format) { + FuriString* valid = furi_string_alloc(); + if(flipper_format_read_string(flipper_format, "Valid", valid)) { + bvalid = true; + FURI_LOG_I(TAG, "[gen_data] is valid ? : %i", bvalid); + } else { + bvalid = false; + FURI_LOG_I(TAG, "[gen_data] is valid ? : %i", bvalid); + } + furi_string_free(valid); if(bvalid) { instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); FURI_LOG_I(TAG, "[gen_data] TRUE : %i", bvalid); } else { // Do not generate new data, send data from buffer FURI_LOG_I(TAG, "[gen_data] FALSE : %i", bvalid); - //return true; + return true; } uint32_t fix = instance->generic.serial << 4 | instance->generic.btn; uint32_t hop = 0; @@ -176,7 +185,7 @@ bool subghz_protocol_faac_slh_create_data( instance->generic.seed = seed; instance->manufacture_name = manufacture_name; instance->generic.data_count_bit = 64; - bool res = subghz_protocol_faac_slh_gen_data(instance); + bool res = subghz_protocol_faac_slh_gen_data(instance, flipper_format); if(res) { return SubGhzProtocolStatusOk == subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -189,10 +198,10 @@ bool subghz_protocol_faac_slh_create_data( * @param instance Pointer to a SubGhzProtocolEncoderFaacSLH instance * @return true On success */ -static bool subghz_protocol_encoder_faac_slh_get_upload(SubGhzProtocolEncoderFaacSLH* instance) { +static bool subghz_protocol_encoder_faac_slh_get_upload(SubGhzProtocolEncoderFaacSLH* instance, FlipperFormat* flipper_format) { furi_assert(instance); - subghz_protocol_faac_slh_gen_data(instance); + subghz_protocol_faac_slh_gen_data(instance, flipper_format); size_t index = 0; size_t size_upload = 2 + (instance->generic.data_count_bit * 2); if(size_upload > instance->encoder.size_upload) { @@ -249,9 +258,10 @@ SubGhzProtocolStatus FuriString* valid = furi_string_alloc(); if(flipper_format_read_string(flipper_format, "Valid", valid)) { bvalid = true; - FURI_LOG_I(TAG, "[encoder_des] Valid : %i", bvalid); + FURI_LOG_I(TAG, "[encoder_des] True : %i", bvalid); } else { bvalid = false; + FURI_LOG_I(TAG, "[encoder_des] False : %i", bvalid); } furi_string_free(valid); instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 | @@ -264,7 +274,7 @@ SubGhzProtocolStatus flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - subghz_protocol_encoder_faac_slh_get_upload(instance); + subghz_protocol_encoder_faac_slh_get_upload(instance, flipper_format); if(!flipper_format_rewind(flipper_format)) { FURI_LOG_E(TAG, "Rewind error"); @@ -501,9 +511,10 @@ SubGhzProtocolStatus FuriString* valid = furi_string_alloc(); if(flipper_format_read_string(flipper_format, "Valid", valid)) { bvalid = true; - FURI_LOG_I(TAG, "[decoder_des] Valid : %i", bvalid); + FURI_LOG_I(TAG, "[decoder_des] TRUE : %i", bvalid); } else { bvalid = false; + FURI_LOG_I(TAG, "[decoder_des] FALSE : %i", bvalid); } furi_string_free(valid); instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 | diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index db46936c2..1e12146bc 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -170,7 +170,7 @@ static bool subghz_protocol_keeloq_gen_data( } if(counter_up && prog_mode == PROG_MODE_OFF) { if(instance->generic.cnt < 0xFFFF) { - if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) { + if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { instance->generic.cnt = 0; } else { instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); @@ -454,6 +454,14 @@ static bool return true; } +bool subghz_protocol_keeloq_edit_cnt(void* context, uint32_t cnt) { + furi_assert(context); + SubGhzProtocolEncoderKeeloq* instance = context; + instance->generic.cnt = cnt; + FURI_LOG_I(TAG, "edit_cnt value : %08lX", cnt); + return true; +} + SubGhzProtocolStatus subghz_protocol_encoder_keeloq_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); diff --git a/lib/subghz/protocols/keeloq.h b/lib/subghz/protocols/keeloq.h index a757e82d5..d90d3e2d3 100644 --- a/lib/subghz/protocols/keeloq.h +++ b/lib/subghz/protocols/keeloq.h @@ -11,6 +11,13 @@ extern const SubGhzProtocolDecoder subghz_protocol_keeloq_decoder; extern const SubGhzProtocolEncoder subghz_protocol_keeloq_encoder; extern const SubGhzProtocol subghz_protocol_keeloq; +/** + * Edit counter function + * @param context Pointer to a SubGhzProtocolEncoderKeeloq instance + * @param cnt Counter + */ +bool subghz_protocol_keeloq_edit_cnt(void* context, uint32_t cnt); + /** * Allocate SubGhzProtocolEncoderKeeloq. * @param environment Pointer to a SubGhzEnvironment instance diff --git a/lib/subghz/protocols/kinggates_stylo_4k.c b/lib/subghz/protocols/kinggates_stylo_4k.c index c5d21bcb0..998f17458 100644 --- a/lib/subghz/protocols/kinggates_stylo_4k.c +++ b/lib/subghz/protocols/kinggates_stylo_4k.c @@ -156,7 +156,7 @@ static bool subghz_protocol_kinggates_stylo_4k_gen_data( instance->generic.cnt = decrypt & 0xFFFF; if(instance->generic.cnt < 0xFFFF) { - if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) { + if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { instance->generic.cnt = 0; } else { instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); diff --git a/lib/subghz/protocols/nice_flor_s.c b/lib/subghz/protocols/nice_flor_s.c index eca9c4e95..6448378f6 100644 --- a/lib/subghz/protocols/nice_flor_s.c +++ b/lib/subghz/protocols/nice_flor_s.c @@ -152,7 +152,7 @@ static void subghz_protocol_encoder_nice_flor_s_get_upload( } if(instance->generic.cnt < 0xFFFF) { - if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) { + if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { instance->generic.cnt = 0; } else { instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); diff --git a/lib/subghz/protocols/somfy_keytis.c b/lib/subghz/protocols/somfy_keytis.c index 4074d757b..be8ebacf5 100644 --- a/lib/subghz/protocols/somfy_keytis.c +++ b/lib/subghz/protocols/somfy_keytis.c @@ -131,7 +131,7 @@ static bool instance->generic.serial = data & 0xFFFFFF; if(instance->generic.cnt < 0xFFFF) { - if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) { + if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { instance->generic.cnt = 0; } else { instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); diff --git a/lib/subghz/protocols/somfy_telis.c b/lib/subghz/protocols/somfy_telis.c index 5fbd90275..9a3882d87 100644 --- a/lib/subghz/protocols/somfy_telis.c +++ b/lib/subghz/protocols/somfy_telis.c @@ -125,7 +125,7 @@ static bool subghz_protocol_somfy_telis_gen_data( btn = subghz_protocol_somfy_telis_get_btn_code(); if(instance->generic.cnt < 0xFFFF) { - if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) { + if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { instance->generic.cnt = 0; } else { instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); diff --git a/lib/subghz/protocols/star_line.c b/lib/subghz/protocols/star_line.c index bf338b35d..75a7fd471 100644 --- a/lib/subghz/protocols/star_line.c +++ b/lib/subghz/protocols/star_line.c @@ -130,7 +130,7 @@ void subghz_protocol_encoder_star_line_free(void* context) { static bool subghz_protocol_star_line_gen_data(SubGhzProtocolEncoderStarLine* instance, uint8_t btn) { if(instance->generic.cnt < 0xFFFF) { - if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >= 0xFFFF) { + if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { instance->generic.cnt = 0; } else { instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); From 67a0136e811a5d3cb09dc0b616fd67787490231c Mon Sep 17 00:00:00 2001 From: Eng1n33r <101719414+Eng1n33r@users.noreply.github.com> Date: Tue, 22 Aug 2023 20:33:36 +0300 Subject: [PATCH 05/59] microfix --- applications/main/subghz/scenes/subghz_scene_saved_menu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/applications/main/subghz/scenes/subghz_scene_saved_menu.c b/applications/main/subghz/scenes/subghz_scene_saved_menu.c index 3672be9e4..6ced59de2 100644 --- a/applications/main/subghz/scenes/subghz_scene_saved_menu.c +++ b/applications/main/subghz/scenes/subghz_scene_saved_menu.c @@ -4,7 +4,7 @@ enum SubmenuIndex { SubmenuIndexEmulate, SubmenuIndexEdit, SubmenuIndexDelete, - SubmenuIndesEditCnt, + SubmenuIndexEditCnt, }; void subghz_scene_saved_menu_submenu_callback(void* context, uint32_t index) { @@ -20,7 +20,7 @@ void subghz_scene_saved_menu_on_enter(void* context) { SubmenuIndexEmulate, subghz_scene_saved_menu_submenu_callback, subghz); - + submenu_add_item( subghz->submenu, "Edit counter", From df5b2cbddd98511beb5b4ae92155047f2c641551 Mon Sep 17 00:00:00 2001 From: Eng1n33r <101719414+Eng1n33r@users.noreply.github.com> Date: Tue, 22 Aug 2023 23:58:49 +0300 Subject: [PATCH 06/59] fix misspelling --- lib/subghz/protocols/somfy_keytis.c | 2 +- lib/subghz/protocols/somfy_telis.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/subghz/protocols/somfy_keytis.c b/lib/subghz/protocols/somfy_keytis.c index be8ebacf5..22d2b5e9f 100644 --- a/lib/subghz/protocols/somfy_keytis.c +++ b/lib/subghz/protocols/somfy_keytis.c @@ -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( diff --git a/lib/subghz/protocols/somfy_telis.c b/lib/subghz/protocols/somfy_telis.c index 9a3882d87..b198ce491 100644 --- a/lib/subghz/protocols/somfy_telis.c +++ b/lib/subghz/protocols/somfy_telis.c @@ -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( From 09aabff55bbb9a1785efa6b7596bd8925680f51b Mon Sep 17 00:00:00 2001 From: Eng1n33r <101719414+Eng1n33r@users.noreply.github.com> Date: Thu, 24 Aug 2023 00:00:28 +0300 Subject: [PATCH 07/59] EditCnt rework [in progress] --- .../main/subghz/helpers/subghz_custom_event.h | 1 + .../main/subghz/scenes/subghz_scene_edit_cnt.c | 5 +---- .../main/subghz/scenes/subghz_scene_saved_menu.c | 13 ------------- .../main/subghz/scenes/subghz_scene_transmitter.c | 4 ++++ lib/subghz/protocols/keeloq.c | 8 -------- lib/subghz/protocols/keeloq.h | 7 ------- 6 files changed, 6 insertions(+), 32 deletions(-) diff --git a/applications/main/subghz/helpers/subghz_custom_event.h b/applications/main/subghz/helpers/subghz_custom_event.h index e5321264e..ea6f0a911 100644 --- a/applications/main/subghz/helpers/subghz_custom_event.h +++ b/applications/main/subghz/helpers/subghz_custom_event.h @@ -105,6 +105,7 @@ typedef enum { SubGhzCustomEventViewTransmitterBack, SubGhzCustomEventViewTransmitterSendStart, SubGhzCustomEventViewTransmitterSendStop, + SubGhzCustomEventViewTransmitterEditCnt, SubGhzCustomEventViewTransmitterError, SubGhzCustomEventViewFreqAnalOkShort, diff --git a/applications/main/subghz/scenes/subghz_scene_edit_cnt.c b/applications/main/subghz/scenes/subghz_scene_edit_cnt.c index f5d0d483b..4a25256f3 100644 --- a/applications/main/subghz/scenes/subghz_scene_edit_cnt.c +++ b/applications/main/subghz/scenes/subghz_scene_edit_cnt.c @@ -36,10 +36,7 @@ bool subghz_scene_edit_cnt_on_event(void* context, SceneManagerEvent event) { cnt = subghz->secure_data->cnt[0] << 24 | subghz->secure_data->cnt[1] << 16 | subghz->secure_data->cnt[2] << 8 | subghz->secure_data->cnt[3]; FURI_LOG_I(TAG, "cnt = %08lX", cnt); - if(subghz_protocol_keeloq_edit_cnt(subghz->txrx, cnt)) { - FURI_LOG_I(TAG, "Hook func from scene to protocol OK"); - }; - + // TO DO scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTransmitter); consumed = true; } diff --git a/applications/main/subghz/scenes/subghz_scene_saved_menu.c b/applications/main/subghz/scenes/subghz_scene_saved_menu.c index 6ced59de2..a65830f4b 100644 --- a/applications/main/subghz/scenes/subghz_scene_saved_menu.c +++ b/applications/main/subghz/scenes/subghz_scene_saved_menu.c @@ -4,7 +4,6 @@ enum SubmenuIndex { SubmenuIndexEmulate, SubmenuIndexEdit, SubmenuIndexDelete, - SubmenuIndexEditCnt, }; void subghz_scene_saved_menu_submenu_callback(void* context, uint32_t index) { @@ -21,13 +20,6 @@ void subghz_scene_saved_menu_on_enter(void* context) { subghz_scene_saved_menu_submenu_callback, subghz); - submenu_add_item( - subghz->submenu, - "Edit counter", - SubmenuIndexEditCnt, - subghz_scene_saved_menu_submenu_callback, - subghz); - submenu_add_item( subghz->submenu, "Rename", @@ -68,11 +60,6 @@ bool subghz_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { subghz->scene_manager, SubGhzSceneSavedMenu, SubmenuIndexEdit); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); return true; - } else if(event.event == SubmenuIndexEditCnt) { - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneSavedMenu, SubmenuIndexEditCnt); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneEditCnt); - return true; } } return false; diff --git a/applications/main/subghz/scenes/subghz_scene_transmitter.c b/applications/main/subghz/scenes/subghz_scene_transmitter.c index 9a38cecd7..512bf26c3 100644 --- a/applications/main/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/main/subghz/scenes/subghz_scene_transmitter.c @@ -85,6 +85,10 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) { furi_hal_subghz_set_rolling_counter_mult(tmp_counter); } return true; + } else if(event.event == SubGhzCustomEventViewTransmitterEditCnt) { + subghz->state_notifications = SubGhzNotificationStateIDLE; + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneEditCnt); + return true; } else if(event.event == SubGhzCustomEventViewTransmitterBack) { subghz->state_notifications = SubGhzNotificationStateIDLE; scene_manager_search_and_switch_to_previous_scene( diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index 1e12146bc..a274602f3 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -454,14 +454,6 @@ static bool return true; } -bool subghz_protocol_keeloq_edit_cnt(void* context, uint32_t cnt) { - furi_assert(context); - SubGhzProtocolEncoderKeeloq* instance = context; - instance->generic.cnt = cnt; - FURI_LOG_I(TAG, "edit_cnt value : %08lX", cnt); - return true; -} - SubGhzProtocolStatus subghz_protocol_encoder_keeloq_deserialize(void* context, FlipperFormat* flipper_format) { furi_assert(context); diff --git a/lib/subghz/protocols/keeloq.h b/lib/subghz/protocols/keeloq.h index d90d3e2d3..a757e82d5 100644 --- a/lib/subghz/protocols/keeloq.h +++ b/lib/subghz/protocols/keeloq.h @@ -11,13 +11,6 @@ extern const SubGhzProtocolDecoder subghz_protocol_keeloq_decoder; extern const SubGhzProtocolEncoder subghz_protocol_keeloq_encoder; extern const SubGhzProtocol subghz_protocol_keeloq; -/** - * Edit counter function - * @param context Pointer to a SubGhzProtocolEncoderKeeloq instance - * @param cnt Counter - */ -bool subghz_protocol_keeloq_edit_cnt(void* context, uint32_t cnt); - /** * Allocate SubGhzProtocolEncoderKeeloq. * @param environment Pointer to a SubGhzEnvironment instance From 32fb94f5db4fbc7702b18353b9e3d04f12720d0a Mon Sep 17 00:00:00 2001 From: Eng1n33r <101719414+Eng1n33r@users.noreply.github.com> Date: Thu, 24 Aug 2023 19:23:05 +0300 Subject: [PATCH 08/59] Cnt value edit [in progress] --- .../main/subghz/helpers/subghz_custom_event.h | 1 - .../helpers/subghz_txrx_create_protocol_key.c | 2 +- .../main/subghz/scenes/subghz_scene_edit_cnt.c | 8 +------- .../main/subghz/scenes/subghz_scene_saved_menu.c | 13 +++++++++++++ .../subghz/scenes/subghz_scene_transmitter.c | 16 ++++++++++++---- firmware/targets/f7/api_symbols.csv | 4 +++- firmware/targets/f7/furi_hal/furi_hal_subghz.c | 10 ++++++++++ firmware/targets/f7/furi_hal/furi_hal_subghz.h | 10 ++++++++++ 8 files changed, 50 insertions(+), 14 deletions(-) diff --git a/applications/main/subghz/helpers/subghz_custom_event.h b/applications/main/subghz/helpers/subghz_custom_event.h index ea6f0a911..e5321264e 100644 --- a/applications/main/subghz/helpers/subghz_custom_event.h +++ b/applications/main/subghz/helpers/subghz_custom_event.h @@ -105,7 +105,6 @@ typedef enum { SubGhzCustomEventViewTransmitterBack, SubGhzCustomEventViewTransmitterSendStart, SubGhzCustomEventViewTransmitterSendStop, - SubGhzCustomEventViewTransmitterEditCnt, SubGhzCustomEventViewTransmitterError, SubGhzCustomEventViewFreqAnalOkShort, diff --git a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c index cf4c07673..ba72652f2 100644 --- a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c +++ b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c @@ -229,7 +229,7 @@ bool subghz_txrx_gen_faac_slh_protocol( } flipper_format_write_hex(txrx->fff_data, "Seed", seed_data, sizeof(uint32_t)); - flipper_format_write_string_cstr(txrx->fff_data, "Valid", "1\n"); + flipper_format_write_string_cstr(txrx->fff_data, "Valid", "1\r\n"); FURI_LOG_I(TAG, "Flag write to SD is OK"); } diff --git a/applications/main/subghz/scenes/subghz_scene_edit_cnt.c b/applications/main/subghz/scenes/subghz_scene_edit_cnt.c index 4a25256f3..0373779f6 100644 --- a/applications/main/subghz/scenes/subghz_scene_edit_cnt.c +++ b/applications/main/subghz/scenes/subghz_scene_edit_cnt.c @@ -1,7 +1,6 @@ #include "../subghz_i.h" -#include -#define TAG "SubGhzEditCnt" +#define TAG "subghz_scene_edit_cnt" void subghz_scene_edit_cnt_byte_input_callback(void* context) { SubGhz* subghz = context; @@ -29,14 +28,9 @@ void subghz_scene_edit_cnt_on_enter(void* context) { bool subghz_scene_edit_cnt_on_event(void* context, SceneManagerEvent event) { SubGhz* subghz = context; bool consumed = false; - uint32_t cnt; if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventByteInputDone) { - cnt = subghz->secure_data->cnt[0] << 24 | subghz->secure_data->cnt[1] << 16 | - subghz->secure_data->cnt[2] << 8 | subghz->secure_data->cnt[3]; - FURI_LOG_I(TAG, "cnt = %08lX", cnt); - // TO DO scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTransmitter); consumed = true; } diff --git a/applications/main/subghz/scenes/subghz_scene_saved_menu.c b/applications/main/subghz/scenes/subghz_scene_saved_menu.c index a65830f4b..d02e7930f 100644 --- a/applications/main/subghz/scenes/subghz_scene_saved_menu.c +++ b/applications/main/subghz/scenes/subghz_scene_saved_menu.c @@ -4,6 +4,7 @@ enum SubmenuIndex { SubmenuIndexEmulate, SubmenuIndexEdit, SubmenuIndexDelete, + SubmenuIndexEditCnt, }; void subghz_scene_saved_menu_submenu_callback(void* context, uint32_t index) { @@ -19,6 +20,13 @@ void subghz_scene_saved_menu_on_enter(void* context) { SubmenuIndexEmulate, subghz_scene_saved_menu_submenu_callback, subghz); + + submenu_add_item( + subghz->submenu, + "Edit counter", + SubmenuIndexEditCnt, + subghz_scene_saved_menu_submenu_callback, + subghz); submenu_add_item( subghz->submenu, @@ -60,6 +68,11 @@ bool subghz_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { subghz->scene_manager, SubGhzSceneSavedMenu, SubmenuIndexEdit); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); return true; + } else if(event.event == SubmenuIndexEditCnt) { + scene_manager_set_scene_state( + subghz->scene_manager, SubGhzSceneSavedMenu, SubmenuIndexEditCnt); + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneEditCnt); + return true; } } return false; diff --git a/applications/main/subghz/scenes/subghz_scene_transmitter.c b/applications/main/subghz/scenes/subghz_scene_transmitter.c index 512bf26c3..45efdce18 100644 --- a/applications/main/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/main/subghz/scenes/subghz_scene_transmitter.c @@ -4,6 +4,8 @@ #include +#define TAG "subghz_scene_transmitter" + void subghz_scene_transmitter_callback(SubGhzCustomEvent event, void* context) { furi_assert(context); SubGhz* subghz = context; @@ -20,6 +22,16 @@ bool subghz_scene_transmitter_update_data_show(void* context) { FuriString* frequency_str = furi_string_alloc(); FuriString* modulation_str = furi_string_alloc(); + if(scene_manager_has_previous_scene(subghz->scene_manager, SubGhzSceneEditCnt)) { + FURI_LOG_I(TAG, " has previous scene "); + uint32_t cnt_temp; + cnt_temp = subghz->secure_data->cnt[0] << 24 | subghz->secure_data->cnt[1] << 16 | + subghz->secure_data->cnt[2] << 8 | subghz->secure_data->cnt[3]; + FURI_LOG_I(TAG, "cnt = %08lX", cnt_temp); + furi_hal_subghz_set_rolling_counter_value(cnt_temp); + FURI_LOG_I(TAG, "furi_hal_subghz.rolling_counter_value == %08lX", cnt_temp); + } + if(subghz_protocol_decoder_base_deserialize( decoder, subghz_txrx_get_fff_data(subghz->txrx)) == SubGhzProtocolStatusOk) { subghz_protocol_decoder_base_get_string(decoder, key_str); @@ -85,10 +97,6 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) { furi_hal_subghz_set_rolling_counter_mult(tmp_counter); } return true; - } else if(event.event == SubGhzCustomEventViewTransmitterEditCnt) { - subghz->state_notifications = SubGhzNotificationStateIDLE; - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneEditCnt); - return true; } else if(event.event == SubGhzCustomEventViewTransmitterBack) { subghz->state_notifications = SubGhzNotificationStateIDLE; scene_manager_search_and_switch_to_previous_scene( diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 847c76643..870642478 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,35.1,, +Version,+,35.2,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, @@ -1419,6 +1419,7 @@ 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_value,uint32_t, Function,+,furi_hal_subghz_get_rssi,float, Function,+,furi_hal_subghz_idle,void, Function,-,furi_hal_subghz_init,void, @@ -1439,6 +1440,7 @@ 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_value,void,uint32_t Function,+,furi_hal_subghz_shutdown,void, Function,+,furi_hal_subghz_sleep,void, Function,+,furi_hal_subghz_start_async_rx,void,"FuriHalSubGhzCaptureCallback, void*" diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.c b/firmware/targets/f7/furi_hal/furi_hal_subghz.c index 1ea5334ee..fe583784e 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.c +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.c @@ -53,6 +53,7 @@ typedef struct { const GpioPin* async_mirror_pin; uint8_t rolling_counter_mult; + uint32_t rolling_counter_value; bool ext_power_amp : 1; bool dangerous_frequency_i : 1; } FuriHalSubGhz; @@ -62,6 +63,7 @@ volatile FuriHalSubGhz furi_hal_subghz = { .regulation = SubGhzRegulationTxRx, .async_mirror_pin = NULL, .rolling_counter_mult = 1, + .rolling_counter_value = 0x0, .ext_power_amp = false, .dangerous_frequency_i = false, }; @@ -74,6 +76,14 @@ void furi_hal_subghz_set_rolling_counter_mult(uint8_t mult) { furi_hal_subghz.rolling_counter_mult = mult; } +uint32_t furi_hal_subghz_get_rolling_counter_value(void) { + return furi_hal_subghz.rolling_counter_value; +} + +void furi_hal_subghz_set_rolling_counter_value(uint32_t value) { + furi_hal_subghz.rolling_counter_value = value; +} + void furi_hal_subghz_set_dangerous_frequency(bool state_i) { furi_hal_subghz.dangerous_frequency_i = state_i; } diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.h b/firmware/targets/f7/furi_hal/furi_hal_subghz.h index b390ac6cc..e9a3e7a03 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.h +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.h @@ -183,6 +183,16 @@ uint8_t furi_hal_subghz_get_rolling_counter_mult(void); */ void furi_hal_subghz_set_rolling_counter_mult(uint8_t mult); +/** Get the current rolling protocols counter value + * @return uint32_t current value + */ +uint32_t furi_hal_subghz_get_rolling_counter_value(void); + +/** Set the current rolling protocols counter value + * @param value uint32_t = 0xFFFF / 0xFFFFF / 0xFFFFFFFF + */ +void furi_hal_subghz_set_rolling_counter_value(uint32_t value); + /** Set frequency * * @param value frequency in Hz From ce1336c0ed1aa42e7e0b24157dc80876aad8b3c9 Mon Sep 17 00:00:00 2001 From: Eng1n33r <101719414+Eng1n33r@users.noreply.github.com> Date: Thu, 24 Aug 2023 22:14:00 +0300 Subject: [PATCH 09/59] fix anomaly --- lib/subghz/protocols/faac_slh.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index a69be67be..b01e3a02e 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -111,16 +111,16 @@ void subghz_protocol_encoder_faac_slh_free(void* context) { free(instance); } -static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* instance, FlipperFormat* flipper_format) { - FuriString* valid = furi_string_alloc(); - if(flipper_format_read_string(flipper_format, "Valid", valid)) { - bvalid = true; - FURI_LOG_I(TAG, "[gen_data] is valid ? : %i", bvalid); - } else { - bvalid = false; - FURI_LOG_I(TAG, "[gen_data] is valid ? : %i", bvalid); - } - furi_string_free(valid); +static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* instance) { + //FuriString* valid = furi_string_alloc(); + //if(flipper_format_read_string(flipper_format, "Valid", valid)) { + //bvalid = true; + //FURI_LOG_I(TAG, "[gen_data] is valid ? : %i", bvalid); + //} else { + //bvalid = false; + //FURI_LOG_I(TAG, "[gen_data] is valid ? : %i", bvalid); + //} + //furi_string_free(valid); if(bvalid) { instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); FURI_LOG_I(TAG, "[gen_data] TRUE : %i", bvalid); @@ -185,7 +185,7 @@ bool subghz_protocol_faac_slh_create_data( instance->generic.seed = seed; instance->manufacture_name = manufacture_name; instance->generic.data_count_bit = 64; - bool res = subghz_protocol_faac_slh_gen_data(instance, flipper_format); + bool res = subghz_protocol_faac_slh_gen_data(instance); if(res) { return SubGhzProtocolStatusOk == subghz_block_generic_serialize(&instance->generic, flipper_format, preset); @@ -198,10 +198,10 @@ bool subghz_protocol_faac_slh_create_data( * @param instance Pointer to a SubGhzProtocolEncoderFaacSLH instance * @return true On success */ -static bool subghz_protocol_encoder_faac_slh_get_upload(SubGhzProtocolEncoderFaacSLH* instance, FlipperFormat* flipper_format) { +static bool subghz_protocol_encoder_faac_slh_get_upload(SubGhzProtocolEncoderFaacSLH* instance) { furi_assert(instance); - subghz_protocol_faac_slh_gen_data(instance, flipper_format); + subghz_protocol_faac_slh_gen_data(instance); size_t index = 0; size_t size_upload = 2 + (instance->generic.data_count_bit * 2); if(size_upload > instance->encoder.size_upload) { @@ -274,7 +274,7 @@ SubGhzProtocolStatus flipper_format_read_uint32( flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); - subghz_protocol_encoder_faac_slh_get_upload(instance, flipper_format); + subghz_protocol_encoder_faac_slh_get_upload(instance); if(!flipper_format_rewind(flipper_format)) { FURI_LOG_E(TAG, "Rewind error"); From c3aa15171244856327558b48085d538f2f315189 Mon Sep 17 00:00:00 2001 From: hedger Date: Fri, 25 Aug 2023 17:38:41 +0300 Subject: [PATCH 10/59] github: Check for todos (#3011) --- .../workflows/lint_and_submodule_check.yml | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/.github/workflows/lint_and_submodule_check.yml b/.github/workflows/lint_and_submodule_check.yml index 22ca7d893..b85409ecd 100644 --- a/.github/workflows/lint_and_submodule_check.yml +++ b/.github/workflows/lint_and_submodule_check.yml @@ -23,9 +23,8 @@ jobs: - name: 'Checkout code' uses: actions/checkout@v3 with: - fetch-depth: 1 - ref: ${{ github.event.pull_request.head.sha }} - + fetch-depth: 2 + ref: ${{ github.sha }} - name: 'Check protobuf branch' run: | @@ -48,8 +47,26 @@ jobs: exit 1; fi + - name: 'Check for new TODOs' + id: check_todos + if: github.event_name == 'pull_request' + run: | + set +e; + git diff --unified=0 --no-color ${{ github.event.pull_request.base.sha }} ${{ github.sha }} | grep -E '^\+' | grep -i -E '(TODO|HACK|FIXME|XXX)[ :]' | grep -v -- '-nofl' > lines.log; + MISSING_TICKETS=$( grep -v -E '\[FL-[0-9]+\]' lines.log ); + if [ -n "$MISSING_TICKETS" ]; then + echo "Error: Missing ticket number in \`TODO\` comment(s)" >> $GITHUB_STEP_SUMMARY; + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY; + echo "$MISSING_TICKETS" >> $GITHUB_STEP_SUMMARY; + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY; + exit 1; + else + echo "No new TODOs without tickets found" >> $GITHUB_STEP_SUMMARY; + fi + - name: 'Check Python code formatting' id: syntax_check_py + if: always() run: | set +e; ./fbt -s lint_py 2>&1 | tee lint-py.log; From 66d26c16cd012dc83e699d3903e3aea3843dc972 Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Sat, 26 Aug 2023 01:09:40 +0900 Subject: [PATCH 11/59] [FL-3580] AC OFF button (#3010) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- .../infrared/scenes/infrared_scene_universal_ac.c | 6 +++--- assets/icons/Infrared/off_19x20.png | Bin 0 -> 193 bytes assets/icons/Infrared/off_hover_19x20.png | Bin 0 -> 160 bytes assets/icons/Infrared/off_text_12x5.png | Bin 0 -> 130 bytes 4 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 assets/icons/Infrared/off_19x20.png create mode 100644 assets/icons/Infrared/off_hover_19x20.png create mode 100644 assets/icons/Infrared/off_text_12x5.png diff --git a/applications/main/infrared/scenes/infrared_scene_universal_ac.c b/applications/main/infrared/scenes/infrared_scene_universal_ac.c index 8914e5ad0..cbb09a525 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_ac.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_ac.c @@ -21,11 +21,11 @@ void infrared_scene_universal_ac_on_enter(void* context) { 0, 6, 15, - &I_power_19x20, - &I_power_hover_19x20, + &I_off_19x20, + &I_off_hover_19x20, infrared_scene_universal_common_item_callback, context); - button_panel_add_icon(button_panel, 4, 37, &I_power_text_24x5); + button_panel_add_icon(button_panel, 10, 37, &I_off_text_12x5); infrared_brute_force_add_record(brute_force, i++, "Off"); button_panel_add_item( button_panel, diff --git a/assets/icons/Infrared/off_19x20.png b/assets/icons/Infrared/off_19x20.png new file mode 100644 index 0000000000000000000000000000000000000000..6d68d7e6e1527c309de8e19e764dbcb4e68a5584 GIT binary patch literal 193 zcmeAS@N?(olHy`uVBq!ia0vp^!ayv-!2~29m`_v&Qk(@Ik;M!Q+&~F#VMc~ob0mO* z#hxyXAr`$?Cm-ZGV8G$*`||()P1Y>Cd@m>N)iqc2&)!f_Zp@sJDme2DF1jQH+wBmKZB>MpUXO@geCx>bSJI= literal 0 HcmV?d00001 From cf74dd259966df4b1772d7f398bb80c2fda991ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Sat, 26 Aug 2023 02:00:00 +0900 Subject: [PATCH 12/59] Rfid: fix crash on broken key launch from archive (#3012) --- applications/main/lfrfid/lfrfid.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/applications/main/lfrfid/lfrfid.c b/applications/main/lfrfid/lfrfid.c index edde23804..aa7510a90 100644 --- a/applications/main/lfrfid/lfrfid.c +++ b/applications/main/lfrfid/lfrfid.c @@ -186,13 +186,15 @@ int32_t lfrfid_app(void* p) { dolphin_deed(DolphinDeedRfidEmulate); } else { furi_string_set(app->file_path, args); - lfrfid_load_key_data(app, app->file_path, true); - view_dispatcher_attach_to_gui( - app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - scene_manager_next_scene(app->scene_manager, LfRfidSceneEmulate); - dolphin_deed(DolphinDeedRfidEmulate); + if(lfrfid_load_key_data(app, app->file_path, true)) { + view_dispatcher_attach_to_gui( + app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + scene_manager_next_scene(app->scene_manager, LfRfidSceneEmulate); + dolphin_deed(DolphinDeedRfidEmulate); + } else { + view_dispatcher_stop(app->view_dispatcher); + } } - } else { view_dispatcher_attach_to_gui( app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); From a772408ee6def5fc464e23f110499246b7bb9bc1 Mon Sep 17 00:00:00 2001 From: Eng1n33r <101719414+Eng1n33r@users.noreply.github.com> Date: Mon, 28 Aug 2023 00:02:48 +0300 Subject: [PATCH 13/59] Good Monday [SubGhz / RadioSettings] More flexible rolling counter rate; Remove unused stuff & small UI revisal --- .../main/subghz/scenes/subghz_scene_config.h | 3 +- .../subghz/scenes/subghz_scene_edit_cnt.c | 48 ------------------- .../scenes/subghz_scene_radio_settings.c | 20 +++++++- .../subghz/scenes/subghz_scene_saved_menu.c | 13 ----- .../main/subghz/scenes/subghz_scene_set_cnt.c | 2 +- .../subghz/scenes/subghz_scene_transmitter.c | 13 +---- firmware/targets/f7/api_symbols.csv | 6 +-- .../targets/f7/furi_hal/furi_hal_subghz.c | 16 ++----- .../targets/f7/furi_hal/furi_hal_subghz.h | 22 +++------ 9 files changed, 33 insertions(+), 110 deletions(-) delete mode 100644 applications/main/subghz/scenes/subghz_scene_edit_cnt.c diff --git a/applications/main/subghz/scenes/subghz_scene_config.h b/applications/main/subghz/scenes/subghz_scene_config.h index 311f954c5..b12a66f98 100644 --- a/applications/main/subghz/scenes/subghz_scene_config.h +++ b/applications/main/subghz/scenes/subghz_scene_config.h @@ -23,5 +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, edit_cnt, EditCnt) \ No newline at end of file +ADD_SCENE(subghz, rpc, Rpc) \ No newline at end of file diff --git a/applications/main/subghz/scenes/subghz_scene_edit_cnt.c b/applications/main/subghz/scenes/subghz_scene_edit_cnt.c deleted file mode 100644 index 0373779f6..000000000 --- a/applications/main/subghz/scenes/subghz_scene_edit_cnt.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "../subghz_i.h" - -#define TAG "subghz_scene_edit_cnt" - -void subghz_scene_edit_cnt_byte_input_callback(void* context) { - SubGhz* subghz = context; - - view_dispatcher_send_custom_event(subghz->view_dispatcher, SubGhzCustomEventByteInputDone); -} - -void subghz_scene_edit_cnt_on_enter(void* context) { - SubGhz* subghz = context; - - // Setup view - ByteInput* byte_input = subghz->byte_input; - - byte_input_set_header_text(byte_input, "Enter COUNTER in hex"); - byte_input_set_result_callback( - byte_input, - subghz_scene_edit_cnt_byte_input_callback, - NULL, - subghz, - subghz->secure_data->cnt, - 4); - view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdByteInput); -} - -bool subghz_scene_edit_cnt_on_event(void* context, SceneManagerEvent event) { - SubGhz* subghz = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubGhzCustomEventByteInputDone) { - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTransmitter); - consumed = true; - } - memset(subghz->secure_data->cnt, 0, sizeof(subghz->secure_data->cnt)); - } - return consumed; -} - -void subghz_scene_edit_cnt_on_exit(void* context) { - SubGhz* subghz = context; - - // Clear view - byte_input_set_result_callback(subghz->byte_input, NULL, NULL, NULL, NULL, 0); - byte_input_set_header_text(subghz->byte_input, ""); -} \ No newline at end of file diff --git a/applications/main/subghz/scenes/subghz_scene_radio_settings.c b/applications/main/subghz/scenes/subghz_scene_radio_settings.c index 0bd2b1f3e..864df6326 100644 --- a/applications/main/subghz/scenes/subghz_scene_radio_settings.c +++ b/applications/main/subghz/scenes/subghz_scene_radio_settings.c @@ -32,7 +32,7 @@ const char* const debug_pin_text[DEBUG_P_COUNT] = { "17(1W)", }; -#define DEBUG_COUNTER_COUNT 6 +#define DEBUG_COUNTER_COUNT 15 const char* const debug_counter_text[DEBUG_COUNTER_COUNT] = { "+1", "+2", @@ -40,6 +40,15 @@ const char* const debug_counter_text[DEBUG_COUNTER_COUNT] = { "+4", "+5", "+10", + "+100", + "0", + "-1", + "-2", + "-3", + "-4", + "-5", + "-10", + "-100", }; const uint32_t debug_counter_val[DEBUG_COUNTER_COUNT] = { 1, @@ -48,6 +57,15 @@ const uint32_t debug_counter_val[DEBUG_COUNTER_COUNT] = { 4, 5, 10, + 100, + 0, + -1, + -2, + -3, + -4, + -5, + -10, + -100, }; static void subghz_scene_radio_settings_set_device(VariableItem* item) { diff --git a/applications/main/subghz/scenes/subghz_scene_saved_menu.c b/applications/main/subghz/scenes/subghz_scene_saved_menu.c index d02e7930f..6897a2d8a 100644 --- a/applications/main/subghz/scenes/subghz_scene_saved_menu.c +++ b/applications/main/subghz/scenes/subghz_scene_saved_menu.c @@ -4,7 +4,6 @@ enum SubmenuIndex { SubmenuIndexEmulate, SubmenuIndexEdit, SubmenuIndexDelete, - SubmenuIndexEditCnt, }; void subghz_scene_saved_menu_submenu_callback(void* context, uint32_t index) { @@ -21,13 +20,6 @@ void subghz_scene_saved_menu_on_enter(void* context) { subghz_scene_saved_menu_submenu_callback, subghz); - submenu_add_item( - subghz->submenu, - "Edit counter", - SubmenuIndexEditCnt, - subghz_scene_saved_menu_submenu_callback, - subghz); - submenu_add_item( subghz->submenu, "Rename", @@ -68,11 +60,6 @@ bool subghz_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { subghz->scene_manager, SubGhzSceneSavedMenu, SubmenuIndexEdit); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSaveName); return true; - } else if(event.event == SubmenuIndexEditCnt) { - scene_manager_set_scene_state( - subghz->scene_manager, SubGhzSceneSavedMenu, SubmenuIndexEditCnt); - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneEditCnt); - return true; } } return false; diff --git a/applications/main/subghz/scenes/subghz_scene_set_cnt.c b/applications/main/subghz/scenes/subghz_scene_set_cnt.c index 35c6c1c92..008ffa1ad 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_cnt.c +++ b/applications/main/subghz/scenes/subghz_scene_set_cnt.c @@ -29,7 +29,7 @@ void subghz_scene_set_cnt_on_enter(void* context) { break; case SubmenuIndexFaacSLH_433: case SubmenuIndexFaacSLH_868: - byte_input_set_header_text(byte_input, "Enter COUNTER in hex"); + 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, diff --git a/applications/main/subghz/scenes/subghz_scene_transmitter.c b/applications/main/subghz/scenes/subghz_scene_transmitter.c index 45efdce18..5f1be6c21 100644 --- a/applications/main/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/main/subghz/scenes/subghz_scene_transmitter.c @@ -4,8 +4,6 @@ #include -#define TAG "subghz_scene_transmitter" - void subghz_scene_transmitter_callback(SubGhzCustomEvent event, void* context) { furi_assert(context); SubGhz* subghz = context; @@ -22,15 +20,6 @@ bool subghz_scene_transmitter_update_data_show(void* context) { FuriString* frequency_str = furi_string_alloc(); FuriString* modulation_str = furi_string_alloc(); - if(scene_manager_has_previous_scene(subghz->scene_manager, SubGhzSceneEditCnt)) { - FURI_LOG_I(TAG, " has previous scene "); - uint32_t cnt_temp; - cnt_temp = subghz->secure_data->cnt[0] << 24 | subghz->secure_data->cnt[1] << 16 | - subghz->secure_data->cnt[2] << 8 | subghz->secure_data->cnt[3]; - FURI_LOG_I(TAG, "cnt = %08lX", cnt_temp); - furi_hal_subghz_set_rolling_counter_value(cnt_temp); - FURI_LOG_I(TAG, "furi_hal_subghz.rolling_counter_value == %08lX", cnt_temp); - } if(subghz_protocol_decoder_base_deserialize( decoder, subghz_txrx_get_fff_data(subghz->txrx)) == SubGhzProtocolStatusOk) { @@ -89,7 +78,7 @@ 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)); diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 870642478..95b05fdaf 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1418,8 +1418,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_value,uint32_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, @@ -1439,8 +1438,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_value,void,uint32_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*" diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.c b/firmware/targets/f7/furi_hal/furi_hal_subghz.c index fe583784e..323f737f4 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.c +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.c @@ -52,8 +52,7 @@ typedef struct { volatile SubGhzRegulation regulation; const GpioPin* async_mirror_pin; - uint8_t rolling_counter_mult; - uint32_t rolling_counter_value; + int8_t rolling_counter_mult; bool ext_power_amp : 1; bool dangerous_frequency_i : 1; } FuriHalSubGhz; @@ -63,27 +62,18 @@ volatile FuriHalSubGhz furi_hal_subghz = { .regulation = SubGhzRegulationTxRx, .async_mirror_pin = NULL, .rolling_counter_mult = 1, - .rolling_counter_value = 0x0, .ext_power_amp = false, .dangerous_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; } -uint32_t furi_hal_subghz_get_rolling_counter_value(void) { - return furi_hal_subghz.rolling_counter_value; -} - -void furi_hal_subghz_set_rolling_counter_value(uint32_t value) { - furi_hal_subghz.rolling_counter_value = value; -} - void furi_hal_subghz_set_dangerous_frequency(bool state_i) { furi_hal_subghz.dangerous_frequency_i = state_i; } diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.h b/firmware/targets/f7/furi_hal/furi_hal_subghz.h index e9a3e7a03..136a2af41 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.h +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.h @@ -173,25 +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); - -/** Get the current rolling protocols counter value - * @return uint32_t current value - */ -uint32_t furi_hal_subghz_get_rolling_counter_value(void); - -/** Set the current rolling protocols counter value - * @param value uint32_t = 0xFFFF / 0xFFFFF / 0xFFFFFFFF - */ -void furi_hal_subghz_set_rolling_counter_value(uint32_t value); +void furi_hal_subghz_set_rolling_counter_mult(int8_t mult); /** Set frequency * From 46e74b3823a72e146e3fb492c684bd38da33d110 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 28 Aug 2023 05:48:40 +0300 Subject: [PATCH 14/59] remake fix in ofw way view_dispatcher will skip on _run and free will be called, then app will exit same as normal --- applications/main/lfrfid/lfrfid.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/applications/main/lfrfid/lfrfid.c b/applications/main/lfrfid/lfrfid.c index a57637a4b..040043b12 100644 --- a/applications/main/lfrfid/lfrfid.c +++ b/applications/main/lfrfid/lfrfid.c @@ -192,10 +192,7 @@ int32_t lfrfid_app(void* p) { scene_manager_next_scene(app->scene_manager, LfRfidSceneEmulate); dolphin_deed(DolphinDeedRfidEmulate); } else { - // TODO: exit properly view_dispatcher_stop(app->view_dispatcher); - lfrfid_free(app); - return 0; } } } else { From 5bd868665e1c04e46867dadf9389097f2249b09f Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 28 Aug 2023 05:50:32 +0300 Subject: [PATCH 15/59] fix timer icons in ir remote icons by @Svaarich --- assets/icons/Infrared/timer_19x20.png | Bin 215 -> 225 bytes assets/icons/Infrared/timer_hover_19x20.png | Bin 208 -> 212 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/assets/icons/Infrared/timer_19x20.png b/assets/icons/Infrared/timer_19x20.png index 3938d4bf1c64aef7fb54b3d1826dfda8b2eee822..6c2bdf6bbdcc08317f2d47c21f0ccc78cfca3178 100644 GIT binary patch delta 184 zcmV;p07w7V0pS6VF@Kv$L_t(IjkT0f4!|G?LtEqhugpF+7UBR=vwoRHo`pIoA_4#; zv8xAxt|0xeBdzBRjzQM3?(+^Oi8eb`iz?1j7|GX}U5}1cJp*}eviZ8s#)5HfQSu*H zCD{l#4PZrO*cgDPFaWFSh5o<{907*qoM6N<$f~pQmhyVZp diff --git a/assets/icons/Infrared/timer_hover_19x20.png b/assets/icons/Infrared/timer_hover_19x20.png index 930a53ae4ac5103a3e816fd74077a1ec6241310d..560ef895d9f147491ff623d511d74acb939da178 100644 GIT binary patch delta 171 zcmV;c0960b0n`DIF@KIpL_t(IjkQ!;4!|G`0<-&HnSE@U#@NT^M&eH+2)0T|0sxYD zi(3M1SIF`SKwC-%E!!YzEL(deHX;?$N(F?R(! Z{{+@ZQw~YC`aS>v002ovPDHLkV1mRbNlE|! delta 167 zcmV;Y09gOj0nh=EF@K6lL_t(IjlGoH3cw%?LsQxR|8n-QDMfly*#dhh>oGN|kR$+z z2zK=%&`v?RUjXokq|~w>NRCg}wqRp~!d8T1S`I{H)aM1R2xPhO>VPxm+@Kw5XDKXN zIRmBvtf&l|kB22U0Ili``F6}Gtu8Ml(^&+J(%!lOp8kC`mLOo+W>-b>adryq{Wlyx VQw}NB%4`4t002ovPDHLkV1nWBNwxq0 From 5eb045e25fbc0385f2a0296458e6b698ea06002f Mon Sep 17 00:00:00 2001 From: gornekich Date: Tue, 29 Aug 2023 08:31:40 +0400 Subject: [PATCH 16/59] nfc: add rfal wrong state error handling (#3017) --- firmware/targets/f7/furi_hal/furi_hal_nfc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_nfc.c b/firmware/targets/f7/furi_hal/furi_hal_nfc.c index b249c8658..baffde1eb 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_nfc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_nfc.c @@ -701,7 +701,9 @@ bool furi_hal_nfc_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_t timeout_ms) { rfalNfcWorker(); state = rfalNfcGetState(); ret = rfalNfcDataExchangeGetStatus(); - if(ret == ERR_BUSY) { + if(ret == ERR_WRONG_STATE) { + return false; + } else if(ret == ERR_BUSY) { if(DWT->CYCCNT - start > timeout_ms * clocks_in_ms) { FURI_LOG_D(TAG, "Timeout during data exchange"); return false; From c6be6f487a1ec0d8e8b7f4af7016665d8dde0440 Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Tue, 29 Aug 2023 13:39:34 +0900 Subject: [PATCH 17/59] [FL-3495] Remove the TODO for GPIO settings save/load (#3015) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- applications/main/gpio/scenes/gpio_scene_usb_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/main/gpio/scenes/gpio_scene_usb_uart.c b/applications/main/gpio/scenes/gpio_scene_usb_uart.c index 52b2142dc..c5e085192 100644 --- a/applications/main/gpio/scenes/gpio_scene_usb_uart.c +++ b/applications/main/gpio/scenes/gpio_scene_usb_uart.c @@ -19,7 +19,7 @@ void gpio_scene_usb_uart_on_enter(void* context) { uint32_t prev_state = scene_manager_get_scene_state(app->scene_manager, GpioAppViewUsbUart); if(prev_state == 0) { scene_usb_uart = malloc(sizeof(SceneUsbUartBridge)); - scene_usb_uart->cfg.vcp_ch = 0; // TODO FL-3495: settings load + scene_usb_uart->cfg.vcp_ch = 0; scene_usb_uart->cfg.uart_ch = 0; scene_usb_uart->cfg.flow_pins = 0; scene_usb_uart->cfg.baudrate_mode = 0; From cb5c5c08f6d23111471f97ae448f2c764b7c5b6b Mon Sep 17 00:00:00 2001 From: gid9798 <30450294+gid9798@users.noreply.github.com> Date: Tue, 29 Aug 2023 13:37:15 +0300 Subject: [PATCH 18/59] SubGHz Remote: submodule --- .gitmodules | 4 + applications/main/subghz_remote/.gitignore | 4 + applications/main/subghz_remote/LICENSE | 21 +++ .../main/subghz_remote/application.fam | 32 ++++- .../subghz_remote/catalog/docs/Changelog.md | 25 ++++ .../main/subghz_remote/catalog/docs/Readme.md | 24 ++++ .../catalog/screenshots/Editor_main.png | Bin 0 -> 2361 bytes .../catalog/screenshots/Editor_submenu.png | Bin 0 -> 1381 bytes .../catalog/screenshots/Remote_idle.png | Bin 0 -> 2026 bytes .../catalog/screenshots/Remote_send.png | Bin 0 -> 1730 bytes .../helpers/subrem_custom_event.h | 7 + .../subghz_remote/helpers/subrem_presets.c | 2 + .../subghz_remote/helpers/txrx/subghz_txrx.c | 6 +- .../subghz_remote/helpers/txrx/subghz_txrx.h | 4 +- .../subghz_remote/icons/DolphinNice_96x59.png | Bin 0 -> 2459 bytes .../icons/remote_scene/ButtonDown_7x4.png | Bin 0 -> 102 bytes .../icons/remote_scene/ButtonLeft_4x7.png | Bin 0 -> 1415 bytes .../icons/remote_scene/ButtonRight_4x7.png | Bin 0 -> 1839 bytes .../icons/remote_scene/ButtonUp_7x4.png | Bin 0 -> 102 bytes .../icons/remote_scene/Ok_btn_9x9.png | Bin 0 -> 3605 bytes .../icons/remote_scene/Pin_arrow_up_7x9.png | Bin 0 -> 3603 bytes .../icons/remote_scene/Pin_cell_13x13.png | Bin 0 -> 3593 bytes .../icons/remote_scene/Pin_star_7x7.png | Bin 0 -> 3600 bytes .../icons/remote_scene/back_10px.png | Bin 0 -> 154 bytes .../main/subghz_remote/icons/sub1_10px.png | Bin 0 -> 299 bytes .../main/subghz_remote/icons/subrem_10px.png | Bin 0 -> 5000 bytes .../scenes/subrem_scene_config.h | 5 +- .../scenes/subrem_scene_edit_label.c | 4 +- .../scenes/subrem_scene_fw_warning.c | 129 ++++++++++++++++++ .../main/subghz_remote/subghz_remote_app.c | 16 ++- .../main/subghz_remote/subghz_remote_app_i.c | 15 +- .../main/subghz_remote/subghz_remote_app_i.h | 2 +- 32 files changed, 280 insertions(+), 20 deletions(-) create mode 100644 applications/main/subghz_remote/.gitignore create mode 100644 applications/main/subghz_remote/LICENSE create mode 100644 applications/main/subghz_remote/catalog/docs/Changelog.md create mode 100644 applications/main/subghz_remote/catalog/docs/Readme.md create mode 100644 applications/main/subghz_remote/catalog/screenshots/Editor_main.png create mode 100644 applications/main/subghz_remote/catalog/screenshots/Editor_submenu.png create mode 100644 applications/main/subghz_remote/catalog/screenshots/Remote_idle.png create mode 100644 applications/main/subghz_remote/catalog/screenshots/Remote_send.png create mode 100644 applications/main/subghz_remote/icons/DolphinNice_96x59.png create mode 100644 applications/main/subghz_remote/icons/remote_scene/ButtonDown_7x4.png create mode 100644 applications/main/subghz_remote/icons/remote_scene/ButtonLeft_4x7.png create mode 100644 applications/main/subghz_remote/icons/remote_scene/ButtonRight_4x7.png create mode 100644 applications/main/subghz_remote/icons/remote_scene/ButtonUp_7x4.png create mode 100644 applications/main/subghz_remote/icons/remote_scene/Ok_btn_9x9.png create mode 100644 applications/main/subghz_remote/icons/remote_scene/Pin_arrow_up_7x9.png create mode 100644 applications/main/subghz_remote/icons/remote_scene/Pin_cell_13x13.png create mode 100644 applications/main/subghz_remote/icons/remote_scene/Pin_star_7x7.png create mode 100644 applications/main/subghz_remote/icons/remote_scene/back_10px.png create mode 100644 applications/main/subghz_remote/icons/sub1_10px.png create mode 100644 applications/main/subghz_remote/icons/subrem_10px.png create mode 100644 applications/main/subghz_remote/scenes/subrem_scene_fw_warning.c diff --git a/.gitmodules b/.gitmodules index 52cf4a207..e68c05465 100644 --- a/.gitmodules +++ b/.gitmodules @@ -38,3 +38,7 @@ [submodule "lib/stm32wb_copro"] path = lib/stm32wb_copro url = https://github.com/flipperdevices/stm32wb_copro.git +[submodule "subghz_remote"] + path = applications/main/subghz_remote + url = https://github.com/DarkFlippers/SubGHz_Remote + branch = ufw_main_app diff --git a/applications/main/subghz_remote/.gitignore b/applications/main/subghz_remote/.gitignore new file mode 100644 index 000000000..e2a15a10a --- /dev/null +++ b/applications/main/subghz_remote/.gitignore @@ -0,0 +1,4 @@ +dist/* +.vscode +.clang-format +.editorconfig \ No newline at end of file diff --git a/applications/main/subghz_remote/LICENSE b/applications/main/subghz_remote/LICENSE new file mode 100644 index 000000000..6f55e3b0d --- /dev/null +++ b/applications/main/subghz_remote/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 DarkFlippers @gid9798 @xMasterX + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/applications/main/subghz_remote/application.fam b/applications/main/subghz_remote/application.fam index 7d11e153e..34fb390ab 100644 --- a/applications/main/subghz_remote/application.fam +++ b/applications/main/subghz_remote/application.fam @@ -1,17 +1,43 @@ +# App( +# appid="subghz_remote_ofw", +# name="Sub-GHz Remote", +# apptype=FlipperAppType.EXTERNAL, +# entry_point="subghz_remote_app", +# requires=[ +# "gui", +# "dialogs", +# ], +# stack_size=2 * 1024, +# targets=["f7"], +# fap_icon="icon.png", +# fap_author="gid9798 xMasterX", +# fap_description="SubGhz Remote, uses up to 5 .sub files", +# fap_category="Sub-GHz", +# fap_icon_assets="icons", +# fap_icon_assets_symbol="subghz_remote", +# fap_version="1.2", +# fap_weburl="https://github.com/DarkFlippers/SubGHz_Remote", +# ) + App( appid="subghz_remote", name="Sub-GHz Remote", apptype=FlipperAppType.MENUEXTERNAL, entry_point="subghz_remote_app", icon="A_SubGHzRemote_14", + order=11, requires=[ "gui", "dialogs", ], stack_size=2 * 1024, - order=11, - fap_libs=["assets",], + targets=["f7"], fap_icon="icon.png", + fap_author="gid9798 xMasterX", fap_description="SubGhz Remote, uses up to 5 .sub files", fap_category="Sub-GHz", -) \ No newline at end of file + fap_icon_assets="icons", + fap_icon_assets_symbol="subghz_remote", + fap_version="1.2", + fap_weburl="https://github.com/DarkFlippers/SubGHz_Remote", +) diff --git a/applications/main/subghz_remote/catalog/docs/Changelog.md b/applications/main/subghz_remote/catalog/docs/Changelog.md new file mode 100644 index 000000000..31ed245e8 --- /dev/null +++ b/applications/main/subghz_remote/catalog/docs/Changelog.md @@ -0,0 +1,25 @@ +## v1.2 +- **Official FirmWare Support** +- Add warning screen on CustomFW + - The .sub file format may differ from the official one and may be broken + +## v1.1 +- **Was combined with a configuration plugin** + - Editing/Creating map file +- Support for starting arguments + +## v1.0 + +**Initial implementation:** +- Transmission +- GUI +- All .sub files for which transfer is available are supported +- Signal types: + - Static + - Dynamic + - RAW + - BinRAW + +*Custom modulations are not supported yet* + +**Map File Format** - FlipperFormat .txt file \ No newline at end of file diff --git a/applications/main/subghz_remote/catalog/docs/Readme.md b/applications/main/subghz_remote/catalog/docs/Readme.md new file mode 100644 index 000000000..1da170e19 --- /dev/null +++ b/applications/main/subghz_remote/catalog/docs/Readme.md @@ -0,0 +1,24 @@ +With this application, you can combine up to 5 .sub files into one remote, and use flipper as a remote with multiple buttons. +## What is "Map" Files? +"Map" is short for mapping +A Map Files is a .txt files that the application uses to store information about remotes +# How to use +## First screen +After launching the application, you will see the MAP file selection screen (file browser). +- Select map file or press "back" to go Main menu +## Main menu +- Open map file - switching to remote + - Select map file + - On remote screen, use the navigation buttons(D-pad) to send a signal +- Edit Map File - map file editor + - Select map file + - Up/Down - slot nafigation + - Ok - edit menu + - Left - preview/save +- New Map File - Creating a new map file + - Enter a name + - The rest is similar to map file editor +# About map file +Map file - FlipperFormat .txt file. + +Stores custom names, and paths to used .sub files. \ No newline at end of file diff --git a/applications/main/subghz_remote/catalog/screenshots/Editor_main.png b/applications/main/subghz_remote/catalog/screenshots/Editor_main.png new file mode 100644 index 0000000000000000000000000000000000000000..9498c94514411bd81fd4f7c474bb3286b0ec6c8f GIT binary patch literal 2361 zcma)8YgAL&6+Rf>3iPFph~TuNj8GOz1PEg$Z$g@kajmOse)Pv(=bn4d-uv78 zeBVCjk4Xu!o?Csk0suVYPR4u+z&huv2iWWyPQA)J4 z*2cyBCZ(uxNpYs;8_`cU^e*-J4XE|+mtt50D~v1o)lvHx@dqcA8y4G`YG|cvT`vX+Dw5WLeSdLUh6y&V+^H|zVB0mHfeX618_POENH9nP zEaPO{*V|vOad{VHAu6ud7caBd8j`jtzx5BT_W)Oa2Egt0;G+-8Am%+;H*vW+o6pzz zwtSIXQa)VT@gi~viFl1|i!f6q#hS&?RemwUR!T0$=mokeV1Lg zG9Q%QueUE-(DWjC?OJKuUeI;YS(_hzj!)#M>P#c$f%FXGq|jT4s5szC$r(t)d+2un z9F@YV@QK7bCsjy)f?602C=lF!NL7t>+L_ZG`0piYtS#m{7)}l>a1Gz1loWia64S{b zo4RC}Z2G4AT5}Mr`U1hme6nxL4kz1EG?prXUeaR2kjWbzYP>cKn0wxRH zl!#Nww4v6;|8U3>$||Wvp7X%IlOGD(o@6o*j<+{m<|aa#&hrTh3T{k_k_OF`g;=)Z z#Q`wTVP_FZ?Y7iHR))7ZwGw@kF!O5r*LC>?^WSsZTRK)}WuaSXcP^ zYTDb=j!;%*#-op6jId`Q*dhj`_ET0p z$mr|jl4&hd9mT8DDti{4PpqM7bVQ7ps~0h&MuO*7#7v@BAPhZwmI8PNfvlu5Xc^_l zVHZN8O6oac2xCM=mSstE8-1n~MwE};!L--{3bWJ=7SGZ@!DK;d+m%!pyf}_RU^p1e z6N`OoL8l}!aB7BjufaCW8P%HNVI%NCyh4P&`O%vKg}GINLr zqTwnWkb^Xn>c+F5H~$@qqO1m(;_gi*=Mj6ZSJ}0(CvItx&^T#ETBi$Y`N+wG!4g9 zeJ5_FOy3~Fcyr2$SNjFZFh5<3yq}zi{l{@8wIv^8H8IIlF1lsS4}w?Xl^PHlxgoVR z$@Ep`+-05xV%yS1^WsLIJ_3N9B%8X@d2F0A<9JWou!>147tYOG zQhG`6u9)8O3>k48hzrs1e0_g-y7^AoPqW$ms7ci6|t7+{z!Qr>Pb-hk2S~`)Y3ZrWreeorPk<RK$`+_f81*v|;P)gVI_ITO@%C3y?@)2C zM%M`=>iv!2vwEG@1JyGNL;7DIXQzdsG#DU+*^z&?fm6gd*b^Ea+4q)X(MRf=_okM` z)t+x{CY}sbx&t$#>MJZtaXp{5UVbSOOz8W9K*tuJV?bGd}ZMxWEHBjMdVzW^cI zJPhwFB(7Ul>CxdW280R^-zFoJnIW@dsegeV~!F%-$9`0y0`B&p#X@ zGITtF-%3`Cu_#l341Xe*L`Q}tD6Mq1`9hT8ng2l4rC)&7U%A_2c0oi%*k01899bM1 no&i5z-OgQ?jUSQo+BW2_eUVyER*ds51mZqUh-p2R^ZEY(w3puR literal 0 HcmV?d00001 diff --git a/applications/main/subghz_remote/catalog/screenshots/Editor_submenu.png b/applications/main/subghz_remote/catalog/screenshots/Editor_submenu.png new file mode 100644 index 0000000000000000000000000000000000000000..f5f7cd8495aef5c0e33c4594679670b40eff387e GIT binary patch literal 1381 zcmeAS@N?(olHy`uVBq!ia0y~yU;;8388|?c*QZDWAjMhW5n0T@z;^_M8K-LVNi#68 zihH^^hE&XXd)F~?>BV~whRn*stgQ)Obi0}sIR}idq0z@wEKGRz2XhI?BDm!*V%o(r+mD2`R;QM zIp@n-Oy^`!@M2(C#KNHPYD+akba||DS*}#VJS5>s)ePx3cSjp+mN)qPt9;ha9%E}> zQ?E0<@ts0-+y?OuFCjdAIS$x=dm8yqkR89 z!7*JXFkPiF#$4>XvNsH)umZC8pD80NiS^L)unh(AHzZF|pL@#*t-Mr8j(gMmWo zRq3_*FMprE*WdsB{CfF#yKCR}&i`BUY;Se{?(1hN zNyNJM%>D@opX_=fcOdfHzq^0W+`oQ)&%dnjH%dF!GrUPfRdHtPZ{_o^ZdT_%=z9KE z=4X$4U+Gcfz6LdWH9KOgrq?x+5j8;0&I*ZD3nlndASeaTab44i_ek}WvJ~WOZA1ZpN$h9|dfo&E8id+&SS`};l5^ZPyb{Utak zV1e}))&PJ7+XDS|17KmEBEY=aVf!f2%{*Ae1`??N*gl?p5Lqs^O94P}w)t%$Byxtj zHeKjgZ*SRD*Vp@oh4pK^ti4$}>|gMC%>cqTZCo=ncwyy2k82SbD^lf>6w?F>(33lp zEI{WL08TFi;KnDwcO?SYZ~y;ga<}dwe#Urv%qY9IRa1*SO3owpQZMXDk#VBl7zDcR zR*7~sU zOWeb2NX<3&{)Al366_&4jjI0(4BN~_Yi&gyX>cEs*&WH}EpMTcaR+t_ql+?M3-5(f z`_R?f_OTWpO5*Q@GPEH>-7#6t6YZ(0jIm}Yw=xgqrV<~U25d_DRK{M!f86h6I#rRi zx{9L35nUmX!t*0<%P%cDP{FXdTibH>wX2JGzCbL880yw}8FAcr^kJJ<;n3?=Attue zMU#WiazBmB2Vk?+oG1$O99p*=mm=y((&-jmbRo?o?9!iOV|GJm*2*lD?G>f&@?1Bm z_qvUk{O|+SSE}YMdS4{t0D_>wX-XJsp{LYawQ=O4+KbP7W*T#6J(d3CQ8+${-J$hP z9-)I`tGT+)9#J%fC1f*;W_2_rQdkK~%areA{IhUiq{`ZRO08oBK!O#NJDi)4Y20n) z#SZrAdmxCsX;5IGJ+e+VM7lz_R%@&(8KP@0_%ekcA+(nn&0_El>PS<9nkK<2x69V= z8suxU9HRP*$(hXN+9g|pN;@=EId@q|jtyXb`mT<5MycQ^uaY)HsIk}Iv;gyFkIbsc z0Fo#!gY%)jEx~q?(L-m?d%iy0unHeHWXmSPBs!6yB@&8iy#FCW_5;kpsj84}YTZ}p z9f3O}4b^d^bwZyJPO1tj6+wU+eoQwJr4IEQ`m;156(=MeAG-je9HR#$ZKZcu9Cuf_ z-VyCG-nXj9653ai<`1lzW-l^asW>UhE%~bLvlJ8Dt(BPJ6Vq(2HovidNKy3E`i&~}U(Rm|9#tqiyD9$W2S^X8^!TF?WBz(1g< zWTpk5t1VLVCm+)l7_LX`dg#1TiKy(LyNVTUX$C4!EN0jiNl9_Gcloypblnv^%W*vP z@oEF;Zcw7q>nHS_M@noTu{T&$LzH)GiMZNAF-<1~5peU|FbmHt$-VE;bV7j)z6C+* zb7D`ZBMJ<~$U%S0_xI5Q2Dqyb2FR58ydp_8*{r5~$GU$S*k zKpX&p3D=m=^cB}P1mK%7_bGPa?2Aw)0u|3zl6<|TPePbznkcy}4%rB69yVy@Q)=*) zx`+7m1SciwSYt?bE0j6rtXUfz5)8oQZ*Z!rBYA7@sXLgJo(m4a- zB=VO%Jvs6{_<&MD8xp)c25I%Lqvo#JkCr-t@n=W z%NHlYqIcj>Za+RrQsZhXck7lVWY@|Mu#=!lw>V6n;ygRRZlcWdyd>`D40dLD8lLDlK9vh%Q2fmG1#zw5H(1bYP*M!_91F zS^rG18|`(HI1r&QEfg5t%~--B9~Jp1U!@QtlwosarPLNKtT@KKH7?nYoAk>(CcQa z0(FxC%gUAkAiV~_S8o8o^#kvo0f4g`DBmZ5*WLr*wm&%W-S$Uotn=!x=yNv$AqLu@ zMYZpFq2!QiYWZ!bJ-!}0>KO|HGbucQI7#EinKQM7?Do)O9nckhPg{q*kF8tn^qbdQ z4vzlQeN~MHwW0P1f`PFe_6{G^(uP7Rrc#!2g4p*3ldK-1bkxR-bhsO9oAwKGJL6Na ze1ip`!Bxf9yBZOyscbmfxFBCo;u3ZWaTbzFQmIRctmP4j7+SH+)(=D_A!1_#F6*O2 z!*3OAdTUSg{X0EEM9!a77tpE7BBn6n7QJadou^W80(LMNK6@$rRwB0l7o%4KIPBWo z{3DuYei&PD5$)8O6|Oll`|N)@%gQNvl3X`;z!)o=ziBO3t=q&rs5ISD#)q^aN=MCQ zH0GggD$S?9X8RudqCj@n9P?D9nIc2un>M3RP;yBW%F>!Jq{&}U2meAQdQAlIOtRWXx)&BwICC%JzbXYVy$&Nvrknzlf@CcAODe&V-;xkRx(_aE zR4fG$VpP5$|3C)5rZBjw{H0J@La~|*rmAtCIdmXXDA&$o@%1q;YA4~+PI+-?0k43^ zR`La$(@RNr>y<{YvL}x_iwUq3r&`ZZ;@B$cT3J?2P=U{d6B~uYI;i|W9zV+gluI~3 zO2;x!RG`3h+wXr26)#*u!<&!FSP%;#f|>7ejqZx?+F-F{2niV2xZ-qNmE5U;vpgHX z{1X;J80B>z$GN|Hh;6q=mTQ668$Q^@n_Q-LXth!d4 z7B%O{f;tk!D{8eO7tMeVOSJk45#=t%Eic;X_9Okpox&vR`ZrD?&(-d%Fa3OaTm-52 z00&Q(BN>RpLE)t*dy!?JYc0o>k~*-q-kPu*W^h;mTxPYEQRI>%``nOFHY D{V;BS literal 0 HcmV?d00001 diff --git a/applications/main/subghz_remote/helpers/subrem_custom_event.h b/applications/main/subghz_remote/helpers/subrem_custom_event.h index e6b9e8ac6..810df6a89 100644 --- a/applications/main/subghz_remote/helpers/subrem_custom_event.h +++ b/applications/main/subghz_remote/helpers/subrem_custom_event.h @@ -48,4 +48,11 @@ typedef enum { SubRemCustomEventSceneEditPreviewSaved, SubRemCustomEventSceneNewName, + +#ifdef FW_ORIGIN_Official + SubRemCustomEventSceneFwWarningExit, + SubRemCustomEventSceneFwWarningNext, + SubRemCustomEventSceneFwWarningContinue, +#endif + } SubRemCustomEvent; \ No newline at end of file diff --git a/applications/main/subghz_remote/helpers/subrem_presets.c b/applications/main/subghz_remote/helpers/subrem_presets.c index ca91ccbaf..bca888b96 100644 --- a/applications/main/subghz_remote/helpers/subrem_presets.c +++ b/applications/main/subghz_remote/helpers/subrem_presets.c @@ -149,7 +149,9 @@ SubRemLoadSubState subrem_sub_preset_load( if(protocol->flag & SubGhzProtocolFlag_Send) { if((protocol->type == SubGhzProtocolTypeStatic) || (protocol->type == SubGhzProtocolTypeDynamic) || +#ifndef FW_ORIGIN_Official (protocol->type == SubGhzProtocolTypeBinRAW) || +#endif (protocol->type == SubGhzProtocolTypeRAW)) { sub_preset->type = protocol->type; } else { diff --git a/applications/main/subghz_remote/helpers/txrx/subghz_txrx.c b/applications/main/subghz_remote/helpers/txrx/subghz_txrx.c index aa713c7a8..8c8c3b56d 100644 --- a/applications/main/subghz_remote/helpers/txrx/subghz_txrx.c +++ b/applications/main/subghz_remote/helpers/txrx/subghz_txrx.c @@ -1,10 +1,12 @@ #include "subghz_txrx_i.h" -#include +#include #include #include +#ifndef FW_ORIGIN_Official #include +#endif #define TAG "SubGhz" @@ -657,12 +659,14 @@ bool subghz_txrx_get_debug_pin_state(SubGhzTxRx* instance) { return instance->debug_pin_state; } +#ifndef FW_ORIGIN_Official void subghz_txrx_reset_dynamic_and_custom_btns(SubGhzTxRx* instance) { furi_assert(instance); subghz_environment_reset_keeloq(instance->environment); subghz_custom_btns_reset(); } +#endif SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance) { furi_assert(instance); diff --git a/applications/main/subghz_remote/helpers/txrx/subghz_txrx.h b/applications/main/subghz_remote/helpers/txrx/subghz_txrx.h index 4593ea20c..93c4a2276 100644 --- a/applications/main/subghz_remote/helpers/txrx/subghz_txrx.h +++ b/applications/main/subghz_remote/helpers/txrx/subghz_txrx.h @@ -369,7 +369,7 @@ bool subghz_txrx_radio_device_is_tx_allowed(SubGhzTxRx* instance, uint32_t frequ void subghz_txrx_set_debug_pin_state(SubGhzTxRx* instance, bool state); bool subghz_txrx_get_debug_pin_state(SubGhzTxRx* instance); - +#ifndef FW_ORIGIN_Official void subghz_txrx_reset_dynamic_and_custom_btns(SubGhzTxRx* instance); - +#endif SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance); // TODO use only in DecodeRaw diff --git a/applications/main/subghz_remote/icons/DolphinNice_96x59.png b/applications/main/subghz_remote/icons/DolphinNice_96x59.png new file mode 100644 index 0000000000000000000000000000000000000000..a299d3630239b4486e249cc501872bed5996df3b GIT binary patch literal 2459 zcmbVO3s4i+8V(M(gEFORwSrA`4O0uPn|M|5y* zB*aMDxC&7(gP9JN;POOi-9khrC>Z9YJs2U!LnVcQEEC0fDtKo&ILlzb30%M}3J^;~ zv7RzcsilOs4Mq@tD*&R;!LMSk2A~{(`HK9|hQBqEX)3sQr9Je6SZU*F-^fD-p+~Hs; zHLkO%v?>ZoxEv+F#whudr%615FkA0DYR0tMEo}3OOY#xecLWe>xV?u5KtSmC^ z7)Fmj6gjfKstiEV-*Cxbbb+&rRWuI_rBJ)ybs_f1Rn&f2>q3pYwI^|J(hdn{j{0EZIm_F zpIyIWLsRUgOItR-dUbVd|6Zo=_BU_Tj4|{{jxO#=JH4o8er(5{!nZD_j4}MH&zh~9 zVLC~y(0-D6GO0ghZD8BYzP?o{>22~lT6^d@X{SwQ8vrNY-PPIMajIwC)`s14Ep72@ zeq7YOzM`?U{+W)ocXBr`eSOcpk?Rxc=ou5&)fWW|pD};-Z0mvk9}=&`Rb&y<77W~a z(>6YM;6Y5aIU~JKZ}mQZynKHiSTQ#Bczn@&jTiN^?vPJ(jhm7cXLx0oum5P$`TceG zU+wR;OO^)8CVlnM)5p$CO&e94KJt>HccCaHGusmW_b`T6m| z-R6V6Db1pErTot?^d22ojm+2>_)FbD`_+WbDGMx9f@hO27maS2`csiV(D&Fs`PS2& zvrq18du_&zXID(!KIxsU$)iuTYuZ?zmYiP&n&i@Be{IdbS-jA2c0QAlu5NXQv_0K< z3Hvs4eeu6B7yD&CNT~gIkMV&UkRU=V!iQ(+_(O&u^ah$+s{_yn(yBYeD40HeU{xGsIT6W Zfq!wOp!Q_E)I!3HFqj;YoHDIHH2#}J9|(o>FH3<^BV2haYO z-y5_sM4;GPjq%Ck6>60csmUj6EiNa>ORduPH4*)h!w|e3sE@(Z)z4*}Q$iC10Gods AV*mgE literal 0 HcmV?d00001 diff --git a/applications/main/subghz_remote/icons/remote_scene/ButtonLeft_4x7.png b/applications/main/subghz_remote/icons/remote_scene/ButtonLeft_4x7.png new file mode 100644 index 0000000000000000000000000000000000000000..0b4655d43247083aa705620e9836ac415b42ca46 GIT binary patch literal 1415 zcmbVM+iKK67*5rq)>aU2M7$VM1Vxif;vTv~W2u`S7ED{V3s&&L*<`XiG|9wd+THd> z5CnY!sdyuJtrvQyAo>KpiLcV|{Tkc)riAbluXfwSZCApL`ztB&p zx6LGKvks4K_4~)qD&oGa-YdJlW)hAKMNJd7<=t?6c^RI1>c$ifyjaM>^|&8!ey zB4!nh9u>5uen6Ve@<H5rru6h<2Ef#GQdQ*CmZOlQi~N!?9H`Rp;C% zU}CB21#?;r`&0|6C0}b-=jODa5|nEJ#ntxQ&{~jpgtwDta4hftr~G=#p@V36e4Zjh zq%J~{y26Jjn=1Nw-l*3%QW5YFE*v4z3gt0$&(*xf2en34c?JpH8+FYldo+Alvg8af-pG4(=!fyUi-Wsg z`g#n9VUcf(DFr{poMSNzw-lz>w+HV+n1ELr&SLA#LHUb0p(xWQ(1*vJ-i+1!`swxZ Z!O7;c$;lT_->m1Ovaz)0yuI`A$q$F8u*d)a literal 0 HcmV?d00001 diff --git a/applications/main/subghz_remote/icons/remote_scene/ButtonRight_4x7.png b/applications/main/subghz_remote/icons/remote_scene/ButtonRight_4x7.png new file mode 100644 index 0000000000000000000000000000000000000000..8e1c74c1c0038ea55172f19ac875003fc80c2d06 GIT binary patch literal 1839 zcmcIlO>f*p7#Yw)M6zw!O+@VZ{?d|D~WYi~8rHRY?X-&T}Yen`g$^+EJ;z+|RV zE@PoDvZ9%#+_}3bC_5Cj8jDGq541mi{7F+&KF}W65sr$Xn5H|YrMQ2(J7%Yc%;(zO z57ax000=TsQ+1Ke@+w#iw3au3cGGQWY740k2ijH>P(6tD)S)be>gX6Tj7`<`b>di- zgWp$8Y+?i31~CzF0&E4uRlA=C(Mp~K`{74jEchB|)4DDK!ZVhSwdFyw0YIZ1cDh0S{OvfO-U_~ zvmRF*m9sWDXNH)GOyqS1Skhxbr6}s*7t&@~kFM(NW5}qh?Lu@lJ}HE;FDiLdGO>LO z5pS*%E2grR)l^;|?O5b_?u0me&c1U}%jrk8*%=Wk%i)8yp2P|kuxmKg<=(u_`oQRI_0 zS`-DNysBx=#3&qSkgA@hJP>~D+ZM(s5jI6Owp`?yE=3e`YGUqkVOp#Cp=3wR3O4hX zX6BLsN3UBzV(vI5;|SZHgOb=HD0VFjpTyfFW}GnQuh>2*Q`k>*cAmA#iUT7EXSpo# zkPm5~#I-o^cpgfe#P$=4-Pi*SpT!-@nJgp8L347xe>5EKl`=_ZFc8XGy+_j=_R_7! z@vZZMowS1GJ?Zw)eetks%~G{BTR>T}9|jt0j3Btyb*C3-`C?fwY3EY`q*oYZ39DpM z&uJ;PCZPLs4QO1Jd_|A1PF)azZJ)RZ`^-VMWr6e#XUOA%3eLG_Ch@BDOHzMk*MF0G zCo7xMd?Mg*HMIXw%nNz?%60fZiZPlqb?GqUpXO`F&Yi!okZl(n>P@r1P2i)yk3DgRwbHeNn6e|;J^SK4TM LH~i+q&mR8;k>NTA literal 0 HcmV?d00001 diff --git a/applications/main/subghz_remote/icons/remote_scene/ButtonUp_7x4.png b/applications/main/subghz_remote/icons/remote_scene/ButtonUp_7x4.png new file mode 100644 index 0000000000000000000000000000000000000000..1be79328b40a93297a5609756328406565c437c0 GIT binary patch literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)I!3HFqj;YoHDIHH2#}J8d-yTOk1_O>mFaFD) zeWb+ZHz{mGZZ1QpXe09^4tcYT#4oe=UbmGC^A-KE*|F&zP#=S*tDnm{r-UX30HgpM AM*si- literal 0 HcmV?d00001 diff --git a/applications/main/subghz_remote/icons/remote_scene/Ok_btn_9x9.png b/applications/main/subghz_remote/icons/remote_scene/Ok_btn_9x9.png new file mode 100644 index 0000000000000000000000000000000000000000..9a1539da2049f12f7b25f96b11a9c40cd8227302 GIT binary patch literal 3605 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 LwKgd=cDwXHDN#*w literal 0 HcmV?d00001 diff --git a/applications/main/subghz_remote/icons/remote_scene/back_10px.png b/applications/main/subghz_remote/icons/remote_scene/back_10px.png new file mode 100644 index 0000000000000000000000000000000000000000..f9c615a99e69c0100b03a9ae7b2df903da4ecd66 GIT binary patch literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xGmzZ=C-xtZVk{1FcVbv~PUa<$!;&U>c zv7h@-A}f&37T^=&`v3obAT#vPO>_%)r1c48n{Iv*t(u1!X;5977~7Co?ed rv9U?Av01aVRT(gMJdt+jXk=uN>R^g!*w%ImsF1<>&pI=m5)cB{fFDGZlI8yr;B3<$MxhJ?+;A4eL&#) z0Ra}bue?07WhLz78x$BO|L3mq-MMxdP^D^#YeY#(Vo9o1a#1RfVlXl=GSoFN)ipE; zF*LF=Hn1|b&^9ozGB8+QQTzo(LvDUbW?CgwgE3G~h=HkCbE6;07#-3sX@sAxkg$U?hnu$6%_P+PX_Jv(ud zLf1xG|CwUz?7R1Up5OC4zxVgNce*W&4YheW_vK(1mglK+H=%$1JZE+m`hA@F<1zI2 zyA8fptqH{ONK}=TAjGw<2*hDRkufZBKGgVD-U({Lf_l{mhyV1gGrhn5dOvmG&rb;X|2#O* z`;Gdu`y8=lFC6>o;MdlzEhu;(gUPC_z|AEGi;B+`t?Ze5z3-kKC+@xe!rsi0?9s|K zy?-daKNrL9+N8K#jUJb4ydqS`GmmU@)cv;7aPpz%>TUZsFY*}}-;x*iZ59ty6_jpT zvujoMQ}z8jJ+AG;!%Gj}Yq-_gD;(ypTplW&z40q}pQ&N1scCq0d(~q_cR%sbwf8Sv zdVdlA`l;oI1plLZ-jYiT3faL`zr6A#=Lo=7=AJsu{N?^-b1q)%coKW)>T~u}qi^rn z-7>H`clPEJwEVR7TGqAGdqR;5OY#pr*E?^={1s1Y&f(g=vM=|qHywW9AEyugs9|9K z_qUv^T38l3y>(BG-D_BB`RVoV^}JI09`V|mBd`AW<~wBWyCXky1n0|1Nlg+*V)QGN;EdcVFdq|MubW(V_Tn9{lz<&(!Cf?0&8A zl@E$Ck9Ky~46J|Y$whnDXUy8sU3Tos>?t>Un9|+}sNpj`p?cz$4F;W6I^yu1td=)j zwphHBH{ybAO5KJiY~Ik|6F0PrHpy5~o?}l42p|MCfG0x1a7;)zj7eMpo$JG-5l@?` zHXBJXB*PHMf{1m6HIN{}u@W63h2e%VF{(r~MGfORCh)5rn!{*B^Z0mvp@`R;h7ZTa zSU`M`2@oM^6GetXP{HeN+v@{V%k5_5e+8G zkwg*(VF;PVP*i$K$XbuLG3}vK5Kuyqq!%K4ie;ot)zny<8cCZ^NiaQ~ENpU0nj%lI zJjF+!xy>BKy>oC09YBCl_0@MKq5HSOc8#H zHxrPt@G@uPXxUw}=@F^kKtO1=<+RE`fZLx72 zM^h}%PZ&K2qcJ389h0U^tT{O|!J$hHs!^{hL5Gn|PU-6=pgIxrK<@yAog7DH3a%&w z8g!!r!BMD#C>udrd^9VVErOXZqga7TC7!lcqdrv)I*fX4xSm29%!}Gu0vbreA!k;g z%|4nF%vOQs$|!0w97;_$K_%JJIG$`y z0f?!B#blXMGE;<>npEzfp3l7GX_S~MYjF^T&H&=qVRY(yC*C;TeK^CKEcntEB`m4& z*s`e!#M_|0il0b3`57vUflm0by2LgR4nVX&k8KG5wO*Mw+x#3L%ravoDAo)K9*8VK z`z@R#$`oXol=A*h>SY-g(0){rAj zX|i`eX-Qc`CULv;$ClJi>UW`W?b^xP)oq_>=<%(|iFP_&{;^5&uL6OoA}L2u$;}G@ zRN$B(Zj5Yq}83M;=f=r9w8MiVD2l{4`U z0fy0oX&k*FI5pSMi{36|`Ri-l*r@*9d2H`fXk<>LZgmX9OeOkpSK|4KPBfUUdA!xx z?`7r}mffile_name_tmp, 25, false); - +#ifndef FW_ORIGIN_Official text_input_set_minimum_length(app->text_input, 0); - +#endif widget_add_string_element( app->widget, 63, 12, AlignCenter, AlignCenter, FontPrimary, "Empty Label Name"); widget_add_string_element( diff --git a/applications/main/subghz_remote/scenes/subrem_scene_fw_warning.c b/applications/main/subghz_remote/scenes/subrem_scene_fw_warning.c new file mode 100644 index 000000000..de473b72c --- /dev/null +++ b/applications/main/subghz_remote/scenes/subrem_scene_fw_warning.c @@ -0,0 +1,129 @@ +#include "../subghz_remote_app_i.h" +#include "../helpers/subrem_custom_event.h" +#ifdef FW_ORIGIN_Official +typedef enum { + SceneFwWarningStateAttention, + SceneFwWarningStateAccept, +} SceneFwWarningState; + +static void subrem_scene_fw_warning_widget_render(SubGhzRemoteApp* app, SceneFwWarningState state); + +static void + subrem_scene_fw_warning_widget_callback(GuiButtonType result, InputType type, void* context) { + furi_assert(context); + SubGhzRemoteApp* app = context; + + if(type == InputTypeShort) { + SubRemCustomEvent event = SubRemCustomEventSceneFwWarningExit; + + switch(scene_manager_get_scene_state(app->scene_manager, SubRemSceneFwWarning)) { + case SceneFwWarningStateAttention: + if(result == GuiButtonTypeRight) { + event = SubRemCustomEventSceneFwWarningNext; + } + break; + + case SceneFwWarningStateAccept: + if(result == GuiButtonTypeRight) { + event = SubRemCustomEventSceneFwWarningContinue; + } + + break; + } + + view_dispatcher_send_custom_event(app->view_dispatcher, event); + } +} + +static void + subrem_scene_fw_warning_widget_render(SubGhzRemoteApp* app, SceneFwWarningState state) { + furi_assert(app); + Widget* widget = app->widget; + + widget_reset(widget); + + switch(state) { + case SceneFwWarningStateAttention: + widget_add_button_element( + widget, GuiButtonTypeLeft, "Exit", subrem_scene_fw_warning_widget_callback, app); + widget_add_button_element( + widget, GuiButtonTypeRight, "Continue", subrem_scene_fw_warning_widget_callback, app); + widget_add_string_element( + widget, 64, 12, AlignCenter, AlignBottom, FontPrimary, "Not official FW"); + widget_add_string_multiline_element( + widget, + 64, + 32, + AlignCenter, + AlignCenter, + FontSecondary, + "You are using custom firmware\nPlease download a compatible\nversion of the application"); + break; + + case SceneFwWarningStateAccept: + widget_add_button_element( + widget, GuiButtonTypeLeft, "Exit", subrem_scene_fw_warning_widget_callback, app); + widget_add_button_element( + widget, GuiButtonTypeRight, "Accept", subrem_scene_fw_warning_widget_callback, app); + widget_add_string_element( + widget, 64, 12, AlignCenter, AlignBottom, FontPrimary, "Not official FW"); + widget_add_string_multiline_element( + widget, + 64, + 32, + AlignCenter, + AlignCenter, + FontSecondary, + "Yes, I understand that\nthe application can\nbreak my subghz key file"); + break; + } +} + +void subrem_scene_fw_warning_on_enter(void* context) { + furi_assert(context); + + SubGhzRemoteApp* app = context; + + scene_manager_set_scene_state( + app->scene_manager, SubRemSceneFwWarning, SceneFwWarningStateAttention); + + subrem_scene_fw_warning_widget_render(app, SceneFwWarningStateAttention); + + view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDWidget); +} + +bool subrem_scene_fw_warning_on_event(void* context, SceneManagerEvent event) { + furi_assert(context); + + SubGhzRemoteApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeBack) { + consumed = true; + } else if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubRemCustomEventSceneFwWarningExit) { + scene_manager_stop(app->scene_manager); + view_dispatcher_stop(app->view_dispatcher); + consumed = true; + } else if(event.event == SubRemCustomEventSceneFwWarningNext) { + scene_manager_set_scene_state( + app->scene_manager, SubRemSceneFwWarning, SceneFwWarningStateAccept); + subrem_scene_fw_warning_widget_render(app, SceneFwWarningStateAccept); + view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDWidget); + consumed = true; + } else if(event.event == SubRemCustomEventSceneFwWarningContinue) { + scene_manager_previous_scene(app->scene_manager); + consumed = true; + } + } + + return consumed; +} + +void subrem_scene_fw_warning_on_exit(void* context) { + furi_assert(context); + + SubGhzRemoteApp* app = context; + widget_reset(app->widget); +} +#endif \ No newline at end of file diff --git a/applications/main/subghz_remote/subghz_remote_app.c b/applications/main/subghz_remote/subghz_remote_app.c index 1af39f57d..473e3c012 100644 --- a/applications/main/subghz_remote/subghz_remote_app.c +++ b/applications/main/subghz_remote/subghz_remote_app.c @@ -1,4 +1,5 @@ #include "subghz_remote_app_i.h" +#include static bool subghz_remote_app_custom_event_callback(void* context, uint32_t event) { furi_assert(context); @@ -174,7 +175,9 @@ int32_t subghz_remote_app(void* arg) { subghz_remote_make_app_folder(subghz_remote_app); bool map_loaded = false; - +#ifdef FW_ORIGIN_Official + const bool fw_ofw = strcmp(version_get_firmware_origin(version_get()), "Official") == 0; +#endif if((arg != NULL) && (strlen(arg) != 0)) { furi_string_set(subghz_remote_app->file_path, (const char*)arg); SubRemLoadMapState load_state = subrem_map_file_load( @@ -193,8 +196,19 @@ int32_t subghz_remote_app(void* arg) { } else { furi_string_set(subghz_remote_app->file_path, SUBREM_APP_FOLDER); scene_manager_next_scene(subghz_remote_app->scene_manager, SubRemSceneStart); +#ifdef FW_ORIGIN_Official + if(fw_ofw) { + scene_manager_next_scene(subghz_remote_app->scene_manager, SubRemSceneOpenMapFile); + } + } + + if(!fw_ofw) { + scene_manager_next_scene(subghz_remote_app->scene_manager, SubRemSceneFwWarning); + } +#else scene_manager_next_scene(subghz_remote_app->scene_manager, SubRemSceneOpenMapFile); } +#endif view_dispatcher_run(subghz_remote_app->view_dispatcher); diff --git a/applications/main/subghz_remote/subghz_remote_app_i.c b/applications/main/subghz_remote/subghz_remote_app_i.c index 82e762c2a..ca54a997b 100644 --- a/applications/main/subghz_remote/subghz_remote_app_i.c +++ b/applications/main/subghz_remote/subghz_remote_app_i.c @@ -3,12 +3,9 @@ #include #include "helpers/txrx/subghz_txrx.h" - -// #include -// #include - -#include +#ifndef FW_ORIGIN_Official #include +#endif #define TAG "SubGhzRemote" @@ -225,9 +222,9 @@ bool subrem_tx_start_sub(SubGhzRemoteApp* app, SubRemSubFilePreset* sub_preset) sub_preset->freq_preset.frequency, NULL, 0); - +#ifndef FW_ORIGIN_Official subghz_custom_btns_reset(); - +#endif if(subghz_txrx_tx_start(app->txrx, sub_preset->fff_data) == SubGhzTxRxStartTxStateOk) { ret = true; } @@ -242,12 +239,12 @@ bool subrem_tx_stop_sub(SubGhzRemoteApp* app, bool forced) { if(forced || (sub_preset->type != SubGhzProtocolTypeRAW)) { subghz_txrx_stop(app->txrx); - +#ifndef FW_ORIGIN_Official if(sub_preset->type == SubGhzProtocolTypeDynamic) { subghz_txrx_reset_dynamic_and_custom_btns(app->txrx); } subghz_custom_btns_reset(); - +#endif return true; } diff --git a/applications/main/subghz_remote/subghz_remote_app_i.h b/applications/main/subghz_remote/subghz_remote_app_i.h index d200bdf96..2300b3e52 100644 --- a/applications/main/subghz_remote/subghz_remote_app_i.h +++ b/applications/main/subghz_remote/subghz_remote_app_i.h @@ -6,7 +6,7 @@ #include "helpers/txrx/subghz_txrx.h" -#include +#include "subghz_remote_icons.h" #include "views/remote.h" #include "views/edit_menu.h" From aa1c1fd905225b02b218eb5b93aa91d6b9e9ac3e Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Tue, 29 Aug 2023 15:55:36 +0400 Subject: [PATCH 19/59] [FL-3582] SubGhz: heap overflow text error (#3021) --- applications/main/subghz/scenes/subghz_scene_receiver.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/applications/main/subghz/scenes/subghz_scene_receiver.c b/applications/main/subghz/scenes/subghz_scene_receiver.c index 6ab443579..497938fee 100644 --- a/applications/main/subghz/scenes/subghz_scene_receiver.c +++ b/applications/main/subghz/scenes/subghz_scene_receiver.c @@ -123,7 +123,7 @@ void subghz_scene_receiver_on_enter(void* context) { subghz_rx_key_state_set(subghz, SubGhzRxKeyStateAddKey); } furi_string_free(str_buff); - subghz_scene_receiver_update_statusbar(subghz); + subghz_view_receiver_set_callback( subghz->subghz_receiver, subghz_scene_receiver_callback, subghz); subghz_txrx_set_rx_calback(subghz->txrx, subghz_scene_add_to_history_callback, subghz); @@ -136,6 +136,8 @@ void subghz_scene_receiver_on_enter(void* context) { furi_check( subghz_txrx_load_decoder_by_name_protocol(subghz->txrx, SUBGHZ_PROTOCOL_BIN_RAW_NAME)); + subghz_scene_receiver_update_statusbar(subghz); + view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdReceiver); } From b91f8d009e13735b2f0b6317cd0dd9554851dbac Mon Sep 17 00:00:00 2001 From: Eng1n33r <101719414+Eng1n33r@users.noreply.github.com> Date: Thu, 31 Aug 2023 22:39:22 +0300 Subject: [PATCH 20/59] Fix KL unknown mf cnt bug --- lib/subghz/protocols/keeloq.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index a274602f3..0bda954ba 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -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, From 809418b9dabef8914f4f56badd12ae7a0d34f19c Mon Sep 17 00:00:00 2001 From: Sergey Gavrilov Date: Fri, 1 Sep 2023 04:23:37 +0300 Subject: [PATCH 21/59] [FL-3563] StorageListRequest: size filter (#3018) * Protobuf: size filter * Update protobuf * Scripts: types for fwflash.py * RPC: handle fliter for StorageListRequest * RPC: StorageListRequest tests for filtering * Fix unit tests configuration * Assets: sync protobuf with upstream Co-authored-by: Aleksandr Kutuzov --- applications/debug/unit_tests/rpc/rpc_test.c | 208 +++++++++++-------- applications/services/rpc/rpc_storage.c | 33 ++- assets/protobuf | 2 +- fbt_options.py | 1 + scripts/fwflash.py | 15 +- 5 files changed, 154 insertions(+), 105 deletions(-) diff --git a/applications/debug/unit_tests/rpc/rpc_test.c b/applications/debug/unit_tests/rpc/rpc_test.c index 533a8a9ca..645e75e84 100644 --- a/applications/debug/unit_tests/rpc/rpc_test.c +++ b/applications/debug/unit_tests/rpc/rpc_test.c @@ -67,7 +67,6 @@ static RpcSessionContext rpc_session[TEST_RPC_SESSIONS]; } while(0) static void output_bytes_callback(void* ctx, uint8_t* got_bytes, size_t got_size); -static void clean_directory(Storage* fs_api, const char* clean_dir); static void test_rpc_add_empty_to_list(MsgList_t msg_list, PB_CommandStatus status, uint32_t command_id); static void test_rpc_encode_and_feed(MsgList_t msg_list, uint8_t session); @@ -149,11 +148,41 @@ static void test_rpc_teardown_second_session(void) { rpc_session[1].session = NULL; } +static void test_rpc_storage_clean_directory(Storage* fs_api, const char* clean_dir) { + furi_check(fs_api); + furi_check(clean_dir); + storage_simply_remove_recursive(fs_api, clean_dir); + FS_Error error = storage_common_mkdir(fs_api, clean_dir); + furi_check(error == FSE_OK); +} + +static void test_rpc_storage_create_file(Storage* fs_api, const char* path, size_t size) { + File* file = storage_file_alloc(fs_api); + + bool success = false; + do { + if(!storage_file_open(file, path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) break; + if(!storage_file_seek(file, size, true)) break; + success = true; + } while(false); + + storage_file_close(file); + storage_file_free(file); + + furi_check(success); +} + static void test_rpc_storage_setup(void) { test_rpc_setup(); Storage* fs_api = furi_record_open(RECORD_STORAGE); - clean_directory(fs_api, TEST_DIR_NAME); + test_rpc_storage_clean_directory(fs_api, TEST_DIR_NAME); + test_rpc_storage_create_file(fs_api, TEST_DIR_NAME "/file100", 100); + test_rpc_storage_create_file(fs_api, TEST_DIR_NAME "/file250", 250); + test_rpc_storage_create_file(fs_api, TEST_DIR_NAME "/file500", 200); + test_rpc_storage_create_file(fs_api, TEST_DIR_NAME "/file1000", 1000); + test_rpc_storage_create_file(fs_api, TEST_DIR_NAME "/file2500", 2500); + test_rpc_storage_create_file(fs_api, TEST_DIR_NAME "/file5000", 5000); furi_record_close(RECORD_STORAGE); } @@ -161,7 +190,7 @@ static void test_rpc_storage_teardown(void) { test_rpc_teardown(); Storage* fs_api = furi_record_open(RECORD_STORAGE); - clean_directory(fs_api, TEST_DIR_NAME); + test_rpc_storage_clean_directory(fs_api, TEST_DIR_NAME); furi_record_close(RECORD_STORAGE); } @@ -179,36 +208,6 @@ static void test_rpc_session_terminated_callback(void* context) { xSemaphoreGive(callbacks_context->terminate_semaphore); } -static void clean_directory(Storage* fs_api, const char* clean_dir) { - furi_check(fs_api); - furi_check(clean_dir); - - File* dir = storage_file_alloc(fs_api); - if(storage_dir_open(dir, clean_dir)) { - FileInfo fileinfo; - char* name = malloc(MAX_NAME_LENGTH + 1); - while(storage_dir_read(dir, &fileinfo, name, MAX_NAME_LENGTH)) { - size_t size = strlen(clean_dir) + strlen(name) + 1 + 1; - char* fullname = malloc(size); - snprintf(fullname, size, "%s/%s", clean_dir, name); - if(file_info_is_dir(&fileinfo)) { - clean_directory(fs_api, fullname); - } - FS_Error error = storage_common_remove(fs_api, fullname); - furi_check(error == FSE_OK); - free(fullname); - } - free(name); - } else { - FS_Error error = storage_common_mkdir(fs_api, clean_dir); - (void)error; - furi_check(error == FSE_OK); - } - - storage_dir_close(dir); - storage_file_free(dir); -} - static void test_rpc_print_message_list(MsgList_t msg_list) { #if DEBUG_PRINT MsgList_reverse(msg_list); @@ -282,24 +281,40 @@ static void test_rpc_add_ping_to_list(MsgList_t msg_list, bool request, uint32_t response->which_content = (request == PING_REQUEST) ? PB_Main_system_ping_request_tag : PB_Main_system_ping_response_tag; } +static void test_rpc_fill_basic_message(PB_Main* message, uint16_t tag, uint32_t command_id) { + message->command_id = command_id; + message->command_status = PB_CommandStatus_OK; + message->cb_content.funcs.encode = NULL; + message->which_content = tag; + message->has_next = false; +} + +static void test_rpc_create_storage_list_request( + PB_Main* message, + const char* path, + bool include_md5, + uint32_t command_id, + uint32_t filter_max_size) { + furi_check(message); + furi_check(path); + test_rpc_fill_basic_message(message, PB_Main_storage_list_request_tag, command_id); + message->content.storage_list_request.path = strdup(path); + message->content.storage_list_request.include_md5 = include_md5; + message->content.storage_list_request.filter_max_size = filter_max_size; +} static void test_rpc_create_simple_message( PB_Main* message, uint16_t tag, const char* str, - uint32_t command_id, - bool flag) { + uint32_t command_id) { furi_check(message); char* str_copy = NULL; if(str) { str_copy = strdup(str); } - message->command_id = command_id; - message->command_status = PB_CommandStatus_OK; - message->cb_content.funcs.encode = NULL; - message->which_content = tag; - message->has_next = false; + test_rpc_fill_basic_message(message, tag, command_id); switch(tag) { case PB_Main_storage_info_request_tag: message->content.storage_info_request.path = str_copy; @@ -307,10 +322,6 @@ static void test_rpc_create_simple_message( case PB_Main_storage_stat_request_tag: message->content.storage_stat_request.path = str_copy; break; - case PB_Main_storage_list_request_tag: - message->content.storage_list_request.path = str_copy; - message->content.storage_list_request.include_md5 = flag; - break; case PB_Main_storage_mkdir_request_tag: message->content.storage_mkdir_request.path = str_copy; break; @@ -573,11 +584,29 @@ static void message->content.storage_list_response.file[2].name = str; } +static bool test_rpc_system_storage_list_filter( + const FileInfo* fileinfo, + const char* name, + size_t filter_max_size) { + bool result = false; + + do { + if(!path_contains_only_ascii(name)) break; + if(filter_max_size) { + if(fileinfo->size > filter_max_size) break; + } + result = true; + } while(false); + + return result; +} + static void test_rpc_storage_list_create_expected_list( MsgList_t msg_list, const char* path, uint32_t command_id, - bool append_md5) { + bool append_md5, + size_t filter_max_size) { Storage* fs_api = furi_record_open(RECORD_STORAGE); File* dir = storage_file_alloc(fs_api); @@ -615,7 +644,7 @@ static void test_rpc_storage_list_create_expected_list( i = 0; } - if(path_contains_only_ascii(name)) { + if(test_rpc_system_storage_list_filter(&fileinfo, name, filter_max_size)) { list->file[i].type = file_info_is_dir(&fileinfo) ? PB_Storage_File_FileType_DIR : PB_Storage_File_FileType_FILE; list->file[i].size = fileinfo.size; @@ -698,17 +727,21 @@ static void test_rpc_free_msg_list(MsgList_t msg_list) { MsgList_clear(msg_list); } -static void test_rpc_storage_list_run(const char* path, uint32_t command_id, bool md5) { +static void test_rpc_storage_list_run( + const char* path, + uint32_t command_id, + bool md5, + size_t filter_max_size) { PB_Main request; MsgList_t expected_msg_list; MsgList_init(expected_msg_list); - test_rpc_create_simple_message( - &request, PB_Main_storage_list_request_tag, path, command_id, md5); + test_rpc_create_storage_list_request(&request, path, md5, command_id, filter_max_size); if(!strcmp(path, "/")) { test_rpc_storage_list_create_expected_list_root(expected_msg_list, command_id); } else { - test_rpc_storage_list_create_expected_list(expected_msg_list, path, command_id, md5); + test_rpc_storage_list_create_expected_list( + expected_msg_list, path, command_id, md5, filter_max_size); } test_rpc_encode_and_feed_one(&request, 0); test_rpc_decode_and_compare(expected_msg_list, 0); @@ -718,25 +751,32 @@ static void test_rpc_storage_list_run(const char* path, uint32_t command_id, boo } MU_TEST(test_storage_list) { - test_rpc_storage_list_run("/", ++command_id, false); - test_rpc_storage_list_run(EXT_PATH("nfc"), ++command_id, false); - test_rpc_storage_list_run(STORAGE_INT_PATH_PREFIX, ++command_id, false); - test_rpc_storage_list_run(STORAGE_EXT_PATH_PREFIX, ++command_id, false); - test_rpc_storage_list_run(EXT_PATH("infrared"), ++command_id, false); - test_rpc_storage_list_run(EXT_PATH("ibutton"), ++command_id, false); - test_rpc_storage_list_run(EXT_PATH("lfrfid"), ++command_id, false); - test_rpc_storage_list_run("error_path", ++command_id, false); + test_rpc_storage_list_run("/", ++command_id, false, 0); + test_rpc_storage_list_run(EXT_PATH("nfc"), ++command_id, false, 0); + test_rpc_storage_list_run(STORAGE_INT_PATH_PREFIX, ++command_id, false, 0); + test_rpc_storage_list_run(STORAGE_EXT_PATH_PREFIX, ++command_id, false, 0); + test_rpc_storage_list_run(EXT_PATH("infrared"), ++command_id, false, 0); + test_rpc_storage_list_run(EXT_PATH("ibutton"), ++command_id, false, 0); + test_rpc_storage_list_run(EXT_PATH("lfrfid"), ++command_id, false, 0); + test_rpc_storage_list_run("error_path", ++command_id, false, 0); } MU_TEST(test_storage_list_md5) { - test_rpc_storage_list_run("/", ++command_id, true); - test_rpc_storage_list_run(EXT_PATH("nfc"), ++command_id, true); - test_rpc_storage_list_run(STORAGE_INT_PATH_PREFIX, ++command_id, true); - test_rpc_storage_list_run(STORAGE_EXT_PATH_PREFIX, ++command_id, true); - test_rpc_storage_list_run(EXT_PATH("infrared"), ++command_id, true); - test_rpc_storage_list_run(EXT_PATH("ibutton"), ++command_id, true); - test_rpc_storage_list_run(EXT_PATH("lfrfid"), ++command_id, true); - test_rpc_storage_list_run("error_path", ++command_id, true); + test_rpc_storage_list_run("/", ++command_id, true, 0); + test_rpc_storage_list_run(EXT_PATH("nfc"), ++command_id, true, 0); + test_rpc_storage_list_run(STORAGE_INT_PATH_PREFIX, ++command_id, true, 0); + test_rpc_storage_list_run(STORAGE_EXT_PATH_PREFIX, ++command_id, true, 0); + test_rpc_storage_list_run(EXT_PATH("infrared"), ++command_id, true, 0); + test_rpc_storage_list_run(EXT_PATH("ibutton"), ++command_id, true, 0); + test_rpc_storage_list_run(EXT_PATH("lfrfid"), ++command_id, true, 0); + test_rpc_storage_list_run("error_path", ++command_id, true, 0); +} + +MU_TEST(test_storage_list_size) { + test_rpc_storage_list_run(TEST_DIR_NAME, ++command_id, false, 0); + test_rpc_storage_list_run(TEST_DIR_NAME, ++command_id, false, 1); + test_rpc_storage_list_run(TEST_DIR_NAME, ++command_id, false, 1000); + test_rpc_storage_list_run(TEST_DIR_NAME, ++command_id, false, 2500); } static void @@ -804,8 +844,7 @@ static void test_storage_read_run(const char* path, uint32_t command_id) { MsgList_init(expected_msg_list); test_rpc_add_read_to_list_by_reading_real_file(expected_msg_list, path, command_id); - test_rpc_create_simple_message( - &request, PB_Main_storage_read_request_tag, path, command_id, false); + test_rpc_create_simple_message(&request, PB_Main_storage_read_request_tag, path, command_id); test_rpc_encode_and_feed_one(&request, 0); test_rpc_decode_and_compare(expected_msg_list, 0); @@ -859,8 +898,7 @@ static void test_rpc_storage_info_run(const char* path, uint32_t command_id) { MsgList_t expected_msg_list; MsgList_init(expected_msg_list); - test_rpc_create_simple_message( - &request, PB_Main_storage_info_request_tag, path, command_id, false); + test_rpc_create_simple_message(&request, PB_Main_storage_info_request_tag, path, command_id); PB_Main* response = MsgList_push_new(expected_msg_list); response->command_id = command_id; @@ -892,8 +930,7 @@ static void test_rpc_storage_stat_run(const char* path, uint32_t command_id) { MsgList_t expected_msg_list; MsgList_init(expected_msg_list); - test_rpc_create_simple_message( - &request, PB_Main_storage_stat_request_tag, path, command_id, false); + test_rpc_create_simple_message(&request, PB_Main_storage_stat_request_tag, path, command_id); Storage* fs_api = furi_record_open(RECORD_STORAGE); FileInfo fileinfo; @@ -1005,11 +1042,7 @@ static void test_storage_write_read_run( test_rpc_add_empty_to_list(expected_msg_list, PB_CommandStatus_OK, *command_id); test_rpc_create_simple_message( - MsgList_push_raw(input_msg_list), - PB_Main_storage_read_request_tag, - path, - ++*command_id, - false); + MsgList_push_raw(input_msg_list), PB_Main_storage_read_request_tag, path, ++*command_id); test_rpc_add_read_or_write_to_list( expected_msg_list, READ_RESPONSE, @@ -1082,8 +1115,7 @@ MU_TEST(test_storage_interrupt_continuous_same_system) { MsgList_push_new(input_msg_list), PB_Main_storage_mkdir_request_tag, TEST_DIR "dir1", - command_id + 1, - false); + command_id + 1); test_rpc_add_read_or_write_to_list( input_msg_list, WRITE_REQUEST, @@ -1163,8 +1195,7 @@ static void test_storage_delete_run( MsgList_t expected_msg_list; MsgList_init(expected_msg_list); - test_rpc_create_simple_message( - &request, PB_Main_storage_delete_request_tag, path, command_id, false); + test_rpc_create_simple_message(&request, PB_Main_storage_delete_request_tag, path, command_id); request.content.storage_delete_request.recursive = recursive; test_rpc_add_empty_to_list(expected_msg_list, status, command_id); @@ -1245,8 +1276,7 @@ static void test_storage_mkdir_run(const char* path, size_t command_id, PB_Comma MsgList_t expected_msg_list; MsgList_init(expected_msg_list); - test_rpc_create_simple_message( - &request, PB_Main_storage_mkdir_request_tag, path, command_id, false); + test_rpc_create_simple_message(&request, PB_Main_storage_mkdir_request_tag, path, command_id); test_rpc_add_empty_to_list(expected_msg_list, status, command_id); test_rpc_encode_and_feed_one(&request, 0); @@ -1297,12 +1327,11 @@ static void test_storage_md5sum_run( MsgList_t expected_msg_list; MsgList_init(expected_msg_list); - test_rpc_create_simple_message( - &request, PB_Main_storage_md5sum_request_tag, path, command_id, false); + test_rpc_create_simple_message(&request, PB_Main_storage_md5sum_request_tag, path, command_id); if(status == PB_CommandStatus_OK) { PB_Main* response = MsgList_push_new(expected_msg_list); test_rpc_create_simple_message( - response, PB_Main_storage_md5sum_response_tag, md5sum, command_id, false); + response, PB_Main_storage_md5sum_response_tag, md5sum, command_id); response->command_status = status; } else { test_rpc_add_empty_to_list(expected_msg_list, status, command_id); @@ -1461,6 +1490,7 @@ MU_TEST_SUITE(test_rpc_storage) { MU_RUN_TEST(test_storage_stat); MU_RUN_TEST(test_storage_list); MU_RUN_TEST(test_storage_list_md5); + MU_RUN_TEST(test_storage_list_size); MU_RUN_TEST(test_storage_read); MU_RUN_TEST(test_storage_write_read); MU_RUN_TEST(test_storage_write); @@ -1759,8 +1789,7 @@ MU_TEST(test_rpc_multisession_storage) { MsgList_push_raw(input_0), PB_Main_storage_read_request_tag, TEST_DIR "file0.txt", - ++command_id, - false); + ++command_id); test_rpc_add_read_or_write_to_list( expected_0, READ_RESPONSE, TEST_DIR "file0.txt", pattern, sizeof(pattern), 1, command_id); @@ -1768,8 +1797,7 @@ MU_TEST(test_rpc_multisession_storage) { MsgList_push_raw(input_1), PB_Main_storage_read_request_tag, TEST_DIR "file1.txt", - ++command_id, - false); + ++command_id); test_rpc_add_read_or_write_to_list( expected_1, READ_RESPONSE, TEST_DIR "file1.txt", pattern, sizeof(pattern), 1, command_id); diff --git a/applications/services/rpc/rpc_storage.c b/applications/services/rpc/rpc_storage.c index 93c7043e8..ee024b823 100644 --- a/applications/services/rpc/rpc_storage.c +++ b/applications/services/rpc/rpc_storage.c @@ -242,6 +242,23 @@ static void rpc_system_storage_list_root(const PB_Main* request, void* context) rpc_send_and_release(session, &response); } +static bool rpc_system_storage_list_filter( + const PB_Storage_ListRequest* request, + const FileInfo* fileinfo, + const char* name) { + bool result = false; + + do { + if(!path_contains_only_ascii(name)) break; + if(request->filter_max_size) { + if(fileinfo->size > request->filter_max_size) break; + } + result = true; + } while(false); + + return result; +} + static void rpc_system_storage_list_process(const PB_Main* request, void* context) { furi_assert(request); furi_assert(context); @@ -253,9 +270,11 @@ static void rpc_system_storage_list_process(const PB_Main* request, void* contex RpcSession* session = rpc_storage->session; furi_assert(session); + const PB_Storage_ListRequest* list_request = &request->content.storage_list_request; + rpc_system_storage_reset_state(rpc_storage, session, true); - if(!strcmp(request->content.storage_list_request.path, "/")) { + if(!strcmp(list_request->path, "/")) { rpc_system_storage_list_root(request, context); return; } @@ -271,7 +290,7 @@ static void rpc_system_storage_list_process(const PB_Main* request, void* contex }; PB_Storage_ListResponse* list = &response.content.storage_list_response; - bool include_md5 = request->content.storage_list_request.include_md5; + bool include_md5 = list_request->include_md5; FuriString* md5 = furi_string_alloc(); FuriString* md5_path = furi_string_alloc(); File* file = storage_file_alloc(fs_api); @@ -279,7 +298,7 @@ static void rpc_system_storage_list_process(const PB_Main* request, void* contex bool finish = false; int i = 0; - if(!storage_dir_open(dir, request->content.storage_list_request.path)) { + if(!storage_dir_open(dir, list_request->path)) { response.command_status = rpc_system_storage_get_file_error(dir); response.which_content = PB_Main_empty_tag; finish = true; @@ -289,7 +308,7 @@ static void rpc_system_storage_list_process(const PB_Main* request, void* contex FileInfo fileinfo; char* name = malloc(MAX_NAME_LENGTH + 1); if(storage_dir_read(dir, &fileinfo, name, MAX_NAME_LENGTH)) { - if(path_contains_only_ascii(name)) { + if(rpc_system_storage_list_filter(list_request, &fileinfo, name)) { if(i == COUNT_OF(list->file)) { list->file_count = i; response.has_next = true; @@ -303,11 +322,7 @@ static void rpc_system_storage_list_process(const PB_Main* request, void* contex list->file[i].name = name; if(include_md5 && !file_info_is_dir(&fileinfo)) { - furi_string_printf( //-V576 - md5_path, - "%s/%s", - request->content.storage_list_request.path, - name); + furi_string_printf(md5_path, "%s/%s", list_request->path, name); //-V576 if(md5_string_calc_file(file, furi_string_get_cstr(md5_path), md5, NULL)) { char* md5sum = list->file[i].md5sum; diff --git a/assets/protobuf b/assets/protobuf index 7e011a958..327163d58 160000 --- a/assets/protobuf +++ b/assets/protobuf @@ -1 +1 @@ -Subproject commit 7e011a95863716e72e7c6b5d552bca241d688304 +Subproject commit 327163d5867c7aa3051334c93ced718d15bfe4da diff --git a/fbt_options.py b/fbt_options.py index b6fcc70f2..bd804fc8b 100644 --- a/fbt_options.py +++ b/fbt_options.py @@ -72,6 +72,7 @@ FIRMWARE_APPS = { "unit_tests": [ "basic_services", "updater_app", + "radio_device_cc1101_ext", "unit_tests", ], } diff --git a/scripts/fwflash.py b/scripts/fwflash.py index c119aaf80..6948bd7f5 100755 --- a/scripts/fwflash.py +++ b/scripts/fwflash.py @@ -10,6 +10,7 @@ from abc import ABC, abstractmethod from dataclasses import dataclass, field from flipper.app import App +from serial.tools.list_ports_common import ListPortInfo # When adding an interface, also add it to SWD_TRANSPORT in fbt/ufbt options @@ -88,8 +89,9 @@ class OpenOCDProgrammer(Programmer): self._add_file(openocd_launch_params, self.interface.config_file) if self.serial: self._add_serial(openocd_launch_params, self.serial) - for additional_arg in self.interface.additional_args: - self._add_command(openocd_launch_params, additional_arg) + if self.interface.additional_args: + for additional_arg in self.interface.additional_args: + self._add_command(openocd_launch_params, additional_arg) self._add_file(openocd_launch_params, "target/stm32wbx.cfg") self._add_command(openocd_launch_params, "init") program_params = [ @@ -124,8 +126,9 @@ class OpenOCDProgrammer(Programmer): self._add_file(openocd_launch_params, self.interface.config_file) if self.serial: self._add_serial(openocd_launch_params, self.serial) - for additional_arg in self.interface.additional_args: - self._add_command(openocd_launch_params, additional_arg) + if self.interface.additional_args: + for additional_arg in self.interface.additional_args: + self._add_command(openocd_launch_params, additional_arg) self._add_file(openocd_launch_params, "target/stm32wbx.cfg") self._add_command(openocd_launch_params, "init") self._add_command(openocd_launch_params, "exit") @@ -167,7 +170,9 @@ def blackmagic_find_serial(serial: str): if not serial.startswith("\\\\.\\"): serial = f"\\\\.\\{serial}" - ports = list(list_ports.grep("blackmagic")) + # idk why, but python thinks that list_ports.grep returns tuple[str, str, str] + ports: list[ListPortInfo] = list(list_ports.grep("blackmagic")) # type: ignore + if len(ports) == 0: return None elif len(ports) > 2: From 7aa55ebc6c2a68afcba1392baae416d13837bab0 Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Fri, 1 Sep 2023 10:47:02 +0900 Subject: [PATCH 22/59] [FL-3543] Check the filetype of the update manifest (#3025) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- lib/update_util/update_manifest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/update_util/update_manifest.c b/lib/update_util/update_manifest.c index 47b2cc0b9..42ab073b0 100644 --- a/lib/update_util/update_manifest.c +++ b/lib/update_util/update_manifest.c @@ -54,10 +54,10 @@ static bool FuriString* filetype; - // TODO FL-3543: compare filetype? filetype = furi_string_alloc(); update_manifest->valid = flipper_format_read_header(flipper_file, filetype, &update_manifest->manifest_version) && + furi_string_cmp_str(filetype, "Flipper firmware upgrade configuration") == 0 && flipper_format_read_string(flipper_file, MANIFEST_KEY_INFO, update_manifest->version) && flipper_format_read_uint32( flipper_file, MANIFEST_KEY_TARGET, &update_manifest->target, 1) && From f218c41d835354e382806ed6c44f1582a322279f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Fri, 1 Sep 2023 10:54:52 +0900 Subject: [PATCH 23/59] Undo some TODO (#3024) * TODO FL-3497: impossible to fix with current memory allocator * TODO FL-3497: removed, requires radically different settings approach * TODO FL-3514: removed, yes we should * TODO FL-3498: implemented, guarding view port access with mutex. * TODO FL-3515: removed, questionable but ok * TODO FL-3510: removed, comment added * TODO FL-3500: refactored, store pin numbers in GpioPinRecord, fix gpio app crash caused by incorrect gpio_pins traversal. * Format Sources * TODO FL-3505: removed, mutex alone is not going to fix issue with WPAN architecture * TODO FL-3506: removed, change ownership by copy is good * TODO FL-3519: documentation and link to source added * Lib: remove unneded total sum from comment in bq27220 --------- Co-authored-by: hedger --- .../debug/unit_tests/furi/furi_memmgr_test.c | 1 - applications/main/gpio/gpio_items.c | 8 +- applications/services/desktop/desktop.c | 3 - applications/services/gui/gui.c | 7 +- applications/services/gui/view_dispatcher.c | 1 - applications/services/gui/view_port.c | 46 +++++++-- applications/services/gui/view_port_i.h | 1 + .../services/power/power_service/power.c | 2 +- .../targets/f18/furi_hal/furi_hal_resources.c | 95 ++++++++++--------- .../targets/f18/furi_hal/furi_hal_resources.h | 1 + firmware/targets/f7/ble_glue/ble_glue.c | 1 - .../targets/f7/ble_glue/services/gatt_char.c | 1 - .../targets/f7/furi_hal/furi_hal_resources.c | 58 ++++++----- .../targets/f7/furi_hal/furi_hal_resources.h | 1 + lib/drivers/bq27220.c | 9 +- 15 files changed, 137 insertions(+), 98 deletions(-) diff --git a/applications/debug/unit_tests/furi/furi_memmgr_test.c b/applications/debug/unit_tests/furi/furi_memmgr_test.c index 05d967a99..a28632cf4 100644 --- a/applications/debug/unit_tests/furi/furi_memmgr_test.c +++ b/applications/debug/unit_tests/furi/furi_memmgr_test.c @@ -26,7 +26,6 @@ void test_furi_memmgr() { mu_assert_int_eq(66, ((uint8_t*)ptr)[i]); } - // TODO FL-3492: fix realloc to copy only old size, and write testcase that leftover of reallocated memory is zero-initialized free(ptr); // allocate and zero-initialize array (calloc) diff --git a/applications/main/gpio/gpio_items.c b/applications/main/gpio/gpio_items.c index 02f7d95b0..746abe032 100644 --- a/applications/main/gpio/gpio_items.c +++ b/applications/main/gpio/gpio_items.c @@ -18,10 +18,12 @@ GPIOItems* gpio_items_alloc() { } items->pins = malloc(sizeof(GpioPinRecord) * items->count); - for(size_t i = 0; i < items->count; i++) { + size_t index = 0; + for(size_t i = 0; i < gpio_pins_count; i++) { if(!gpio_pins[i].debug) { - items->pins[i].pin = gpio_pins[i].pin; - items->pins[i].name = gpio_pins[i].name; + items->pins[index].pin = gpio_pins[i].pin; + items->pins[index].name = gpio_pins[i].name; + index++; } } return items; diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index 0627652ab..547883e9a 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -101,7 +101,6 @@ static void desktop_clock_draw_callback(Canvas* canvas, void* context) { char buffer[20]; snprintf(buffer, sizeof(buffer), "%02u:%02u", hour, desktop->time_minute); - // TODO FL-3515: never do that, may cause visual glitches view_port_set_width( desktop->clock_viewport, canvas_string_width(canvas, buffer) - 1 + (desktop->time_minute % 10 == 1)); @@ -126,8 +125,6 @@ static bool desktop_custom_event_callback(void* context, uint32_t event) { return true; case DesktopGlobalAfterAppFinished: animation_manager_load_and_continue_animation(desktop->animation_manager); - // TODO FL-3497: Implement a message mechanism for loading settings and (optionally) - // locking and unlocking DESKTOP_SETTINGS_LOAD(&desktop->settings); desktop_clock_reconfigure(desktop); diff --git a/applications/services/gui/gui.c b/applications/services/gui/gui.c index b96f89db9..0bdc999b7 100644 --- a/applications/services/gui/gui.c +++ b/applications/services/gui/gui.c @@ -361,10 +361,11 @@ void gui_add_view_port(Gui* gui, ViewPort* view_port, GuiLayer layer) { furi_assert(view_port); furi_check(layer < GuiLayerMAX); // Only fullscreen supports Vertical orientation for now - furi_assert( + ViewPortOrientation view_port_orientation = view_port_get_orientation(view_port); + furi_check( (layer == GuiLayerFullscreen) || - ((view_port->orientation != ViewPortOrientationVertical) && - (view_port->orientation != ViewPortOrientationVerticalFlip))); + ((view_port_orientation != ViewPortOrientationVertical) && + (view_port_orientation != ViewPortOrientationVerticalFlip))); gui_lock(gui); // Verify that view port is not yet added diff --git a/applications/services/gui/view_dispatcher.c b/applications/services/gui/view_dispatcher.c index 83f0edbea..0119abc20 100644 --- a/applications/services/gui/view_dispatcher.c +++ b/applications/services/gui/view_dispatcher.c @@ -272,7 +272,6 @@ void view_dispatcher_handle_input(ViewDispatcher* view_dispatcher, InputEvent* e } else if(view_dispatcher->navigation_event_callback) { // Dispatch navigation event if(!view_dispatcher->navigation_event_callback(view_dispatcher->event_context)) { - // TODO FL-3514: should we allow view_dispatcher to stop without navigation_event_callback? view_dispatcher_stop(view_dispatcher); return; } diff --git a/applications/services/gui/view_port.c b/applications/services/gui/view_port.c index 57c0fddb4..0f300c168 100644 --- a/applications/services/gui/view_port.c +++ b/applications/services/gui/view_port.c @@ -7,8 +7,6 @@ #include "gui.h" #include "gui_i.h" -// TODO FL-3498: add mutex to view_port ops - _Static_assert(ViewPortOrientationMAX == 4, "Incorrect ViewPortOrientation count"); _Static_assert( (ViewPortOrientationHorizontal == 0 && ViewPortOrientationHorizontalFlip == 1 && @@ -95,52 +93,73 @@ ViewPort* view_port_alloc() { ViewPort* view_port = malloc(sizeof(ViewPort)); view_port->orientation = ViewPortOrientationHorizontal; view_port->is_enabled = true; + view_port->mutex = furi_mutex_alloc(FuriMutexTypeRecursive); return view_port; } void view_port_free(ViewPort* view_port) { furi_assert(view_port); + furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk); furi_check(view_port->gui == NULL); + furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk); + furi_mutex_free(view_port->mutex); free(view_port); } void view_port_set_width(ViewPort* view_port, uint8_t width) { furi_assert(view_port); + furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk); view_port->width = width; + furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk); } uint8_t view_port_get_width(const ViewPort* view_port) { furi_assert(view_port); - return view_port->width; + furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk); + uint8_t width = view_port->width; + furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk); + return width; } void view_port_set_height(ViewPort* view_port, uint8_t height) { furi_assert(view_port); + furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk); view_port->height = height; + furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk); } uint8_t view_port_get_height(const ViewPort* view_port) { furi_assert(view_port); - return view_port->height; + furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk); + uint8_t height = view_port->height; + furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk); + return height; } void view_port_enabled_set(ViewPort* view_port, bool enabled) { furi_assert(view_port); + furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk); if(view_port->is_enabled != enabled) { view_port->is_enabled = enabled; if(view_port->gui) gui_update(view_port->gui); } + furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk); } bool view_port_is_enabled(const ViewPort* view_port) { furi_assert(view_port); - return view_port->is_enabled; + furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk); + bool is_enabled = view_port->is_enabled; + furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk); + return is_enabled; } void view_port_draw_callback_set(ViewPort* view_port, ViewPortDrawCallback callback, void* context) { furi_assert(view_port); + furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk); view_port->draw_callback = callback; view_port->draw_callback_context = context; + furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk); } void view_port_input_callback_set( @@ -148,34 +167,43 @@ void view_port_input_callback_set( ViewPortInputCallback callback, void* context) { furi_assert(view_port); + furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk); view_port->input_callback = callback; view_port->input_callback_context = context; + furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk); } void view_port_update(ViewPort* view_port) { furi_assert(view_port); + furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk); if(view_port->gui && view_port->is_enabled) gui_update(view_port->gui); + furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk); } void view_port_gui_set(ViewPort* view_port, Gui* gui) { furi_assert(view_port); + furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk); view_port->gui = gui; + furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk); } void view_port_draw(ViewPort* view_port, Canvas* canvas) { furi_assert(view_port); furi_assert(canvas); + furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk); furi_check(view_port->gui); if(view_port->draw_callback) { view_port_setup_canvas_orientation(view_port, canvas); view_port->draw_callback(canvas, view_port->draw_callback_context); } + furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk); } void view_port_input(ViewPort* view_port, InputEvent* event) { furi_assert(view_port); furi_assert(event); + furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk); furi_check(view_port->gui); if(view_port->input_callback) { @@ -183,13 +211,19 @@ void view_port_input(ViewPort* view_port, InputEvent* event) { view_port_map_input(event, orientation); view_port->input_callback(event, view_port->input_callback_context); } + furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk); } void view_port_set_orientation(ViewPort* view_port, ViewPortOrientation orientation) { furi_assert(view_port); + furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk); view_port->orientation = orientation; + furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk); } ViewPortOrientation view_port_get_orientation(const ViewPort* view_port) { - return view_port->orientation; + furi_check(furi_mutex_acquire(view_port->mutex, FuriWaitForever) == FuriStatusOk); + ViewPortOrientation orientation = view_port->orientation; + furi_check(furi_mutex_release(view_port->mutex) == FuriStatusOk); + return orientation; } diff --git a/applications/services/gui/view_port_i.h b/applications/services/gui/view_port_i.h index 90f48ac93..444e1a27c 100644 --- a/applications/services/gui/view_port_i.h +++ b/applications/services/gui/view_port_i.h @@ -10,6 +10,7 @@ struct ViewPort { Gui* gui; + FuriMutex* mutex; bool is_enabled; ViewPortOrientation orientation; diff --git a/applications/services/power/power_service/power.c b/applications/services/power/power_service/power.c index e39a84eaf..ad3a5114d 100644 --- a/applications/services/power/power_service/power.c +++ b/applications/services/power/power_service/power.c @@ -30,7 +30,7 @@ void power_draw_battery_callback(Canvas* canvas, void* context) { if(power->state == PowerStateCharging) { canvas_set_bitmap_mode(canvas, 1); canvas_set_color(canvas, ColorWhite); - // TODO FL-3510: replace -1 magic for uint8_t with re-framing + // -1 used here to overflow u8 number and render is outside of the area canvas_draw_icon(canvas, 8, -1, &I_Charging_lightning_mask_9x10); canvas_set_color(canvas, ColorBlack); canvas_draw_icon(canvas, 8, -1, &I_Charging_lightning_9x10); diff --git a/firmware/targets/f18/furi_hal/furi_hal_resources.c b/firmware/targets/f18/furi_hal/furi_hal_resources.c index 63da03e04..efd39977b 100644 --- a/firmware/targets/f18/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f18/furi_hal/furi_hal_resources.c @@ -67,35 +67,53 @@ const GpioPin gpio_usb_dm = {.port = GPIOA, .pin = LL_GPIO_PIN_11}; const GpioPin gpio_usb_dp = {.port = GPIOA, .pin = LL_GPIO_PIN_12}; const GpioPinRecord gpio_pins[] = { - {.pin = &gpio_ext_pa7, .name = "PA7", .debug = false}, - {.pin = &gpio_ext_pa6, .name = "PA6", .debug = false}, - {.pin = &gpio_ext_pa4, .name = "PA4", .debug = false}, - {.pin = &gpio_ext_pb3, .name = "PB3", .debug = false}, - {.pin = &gpio_ext_pb2, .name = "PB2", .debug = false}, - {.pin = &gpio_ext_pc3, .name = "PC3", .debug = false}, - {.pin = &gpio_ext_pc1, .name = "PC1", .debug = false}, - {.pin = &gpio_ext_pc0, .name = "PC0", .debug = false}, + // 5V: 1 + {.pin = &gpio_ext_pa7, .name = "PA7", .number = 2, .debug = false}, + {.pin = &gpio_ext_pa6, .name = "PA6", .number = 3, .debug = false}, + {.pin = &gpio_ext_pa4, .name = "PA4", .number = 4, .debug = false}, + {.pin = &gpio_ext_pb3, .name = "PB3", .number = 5, .debug = false}, + {.pin = &gpio_ext_pb2, .name = "PB2", .number = 6, .debug = false}, + {.pin = &gpio_ext_pc3, .name = "PC3", .number = 7, .debug = false}, + // GND: 8 + // Space + // 3v3: 9 + {.pin = &gpio_swclk, .name = "PA14", .number = 10, .debug = true}, + // GND: 11 + {.pin = &gpio_swdio, .name = "PA13", .number = 12, .debug = true}, + {.pin = &gpio_usart_tx, .name = "PB6", .number = 13, .debug = true}, + {.pin = &gpio_usart_rx, .name = "PB7", .number = 14, .debug = true}, + {.pin = &gpio_ext_pc1, .name = "PC1", .number = 15, .debug = false}, + {.pin = &gpio_ext_pc0, .name = "PC0", .number = 16, .debug = false}, + {.pin = &gpio_ibutton, .name = "PB14", .number = 17, .debug = true}, + // GND: 18 - {.pin = &gpio_ext_pc5, .name = "PC5", .debug = false}, - {.pin = &gpio_ext_pc4, .name = "PC4", .debug = false}, - {.pin = &gpio_ext_pa5, .name = "PA5", .debug = false}, - {.pin = &gpio_ext_pb9, .name = "PB9", .debug = false}, - {.pin = &gpio_ext_pa0, .name = "PA0", .debug = false}, - {.pin = &gpio_ext_pa1, .name = "PA1", .debug = false}, - {.pin = &gpio_ext_pa15, .name = "PA15", .debug = false}, - {.pin = &gpio_ext_pe4, .name = "PE4", .debug = false}, - {.pin = &gpio_ext_pa2, .name = "PA2", .debug = false}, - {.pin = &gpio_ext_pb4, .name = "PB4", .debug = false}, - {.pin = &gpio_ext_pb5, .name = "PB5", .debug = false}, - {.pin = &gpio_ext_pd0, .name = "PD0", .debug = false}, - {.pin = &gpio_ext_pb13, .name = "PB13", .debug = false}, + // 2nd column + // 5V: 19 + {.pin = &gpio_ext_pc5, .name = "PC5", .number = 20, .debug = false}, + {.pin = &gpio_ext_pc4, .name = "PC4", .number = 21, .debug = false}, + {.pin = &gpio_ext_pa5, .name = "PA5", .number = 22, .debug = false}, + {.pin = &gpio_ext_pb9, .name = "PB9", .number = 23, .debug = false}, + {.pin = &gpio_ext_pa0, .name = "PA0", .number = 24, .debug = false}, + {.pin = &gpio_ext_pa1, .name = "PA1", .number = 25, .debug = false}, + // KEY: 26 + // Space + // 3v3: 27 + {.pin = &gpio_ext_pa15, .name = "PA15", .number = 28, .debug = false}, + // GND: 29 + {.pin = &gpio_ext_pe4, .name = "PE4", .number = 30, .debug = false}, + {.pin = &gpio_ext_pa2, .name = "PA2", .number = 31, .debug = false}, + {.pin = &gpio_ext_pb4, .name = "PB4", .number = 32, .debug = false}, + {.pin = &gpio_ext_pb5, .name = "PB5", .number = 33, .debug = false}, + {.pin = &gpio_ext_pd0, .name = "PD0", .number = 34, .debug = false}, + {.pin = &gpio_ext_pb13, .name = "PB13", .number = 35, .debug = false}, + // GND: 36 /* Dangerous pins, may damage hardware */ - {.pin = &gpio_usart_rx, .name = "PB7", .debug = true}, - {.pin = &gpio_speaker, .name = "PB8", .debug = true}, + {.pin = &gpio_usart_rx, .name = "PB7", .number = 0, .debug = true}, + {.pin = &gpio_speaker, .name = "PB8", .number = 0, .debug = true}, }; -const size_t gpio_pins_count = sizeof(gpio_pins) / sizeof(GpioPinRecord); +const size_t gpio_pins_count = COUNT_OF(gpio_pins); const InputPin input_pins[] = { {.gpio = &gpio_button_up, .key = InputKeyUp, .inverted = true, .name = "Up"}, @@ -106,7 +124,7 @@ const InputPin input_pins[] = { {.gpio = &gpio_button_back, .key = InputKeyBack, .inverted = true, .name = "Back"}, }; -const size_t input_pins_count = sizeof(input_pins) / sizeof(InputPin); +const size_t input_pins_count = COUNT_OF(input_pins); static void furi_hal_resources_init_input_pins(GpioMode mode) { for(size_t i = 0; i < input_pins_count; i++) { @@ -216,25 +234,10 @@ void furi_hal_resources_init() { } int32_t furi_hal_resources_get_ext_pin_number(const GpioPin* gpio) { - // TODO FL-3500: describe second ROW - if(gpio == &gpio_ext_pa7) - return 2; - else if(gpio == &gpio_ext_pa6) - return 3; - else if(gpio == &gpio_ext_pa4) - return 4; - else if(gpio == &gpio_ext_pb3) - return 5; - else if(gpio == &gpio_ext_pb2) - return 6; - else if(gpio == &gpio_ext_pc3) - return 7; - else if(gpio == &gpio_ext_pc1) - return 15; - else if(gpio == &gpio_ext_pc0) - return 16; - else if(gpio == &gpio_ibutton) - return 17; - else - return -1; + for(size_t i = 0; i < gpio_pins_count; i++) { + if(gpio_pins[i].pin == gpio) { + return gpio_pins[i].number; + } + } + return -1; } diff --git a/firmware/targets/f18/furi_hal/furi_hal_resources.h b/firmware/targets/f18/furi_hal/furi_hal_resources.h index 7d2caab36..fed7802a5 100644 --- a/firmware/targets/f18/furi_hal/furi_hal_resources.h +++ b/firmware/targets/f18/furi_hal/furi_hal_resources.h @@ -41,6 +41,7 @@ typedef struct { typedef struct { const GpioPin* pin; const char* name; + const uint8_t number; const bool debug; } GpioPinRecord; diff --git a/firmware/targets/f7/ble_glue/ble_glue.c b/firmware/targets/f7/ble_glue/ble_glue.c index 746df71c7..2c30612b5 100644 --- a/firmware/targets/f7/ble_glue/ble_glue.c +++ b/firmware/targets/f7/ble_glue/ble_glue.c @@ -222,7 +222,6 @@ bool ble_glue_wait_for_c2_start(int32_t timeout) { bool started = false; do { - // TODO FL-3505: use mutex? started = ble_glue->status == BleGlueStatusC2Started; if(!started) { timeout--; diff --git a/firmware/targets/f7/ble_glue/services/gatt_char.c b/firmware/targets/f7/ble_glue/services/gatt_char.c index e0539c34f..f6e27f53e 100644 --- a/firmware/targets/f7/ble_glue/services/gatt_char.c +++ b/firmware/targets/f7/ble_glue/services/gatt_char.c @@ -14,7 +14,6 @@ void flipper_gatt_characteristic_init( furi_assert(char_instance); // Copy the descriptor to the instance, since it may point to stack memory - // TODO FL-3506: only copy if really comes from stack char_instance->characteristic = malloc(sizeof(FlipperGattCharacteristicParams)); memcpy( (void*)char_instance->characteristic, diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.c b/firmware/targets/f7/furi_hal/furi_hal_resources.c index 4d52960d8..d519484d1 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.c @@ -69,22 +69,32 @@ const GpioPin gpio_usb_dm = {.port = GPIOA, .pin = LL_GPIO_PIN_11}; const GpioPin gpio_usb_dp = {.port = GPIOA, .pin = LL_GPIO_PIN_12}; const GpioPinRecord gpio_pins[] = { - {.pin = &gpio_ext_pa7, .name = "PA7", .debug = false}, - {.pin = &gpio_ext_pa6, .name = "PA6", .debug = false}, - {.pin = &gpio_ext_pa4, .name = "PA4", .debug = false}, - {.pin = &gpio_ext_pb3, .name = "PB3", .debug = false}, - {.pin = &gpio_ext_pb2, .name = "PB2", .debug = false}, - {.pin = &gpio_ext_pc3, .name = "PC3", .debug = false}, - {.pin = &gpio_ext_pc1, .name = "PC1", .debug = false}, - {.pin = &gpio_ext_pc0, .name = "PC0", .debug = false}, + // 5V: 1 + {.pin = &gpio_ext_pa7, .name = "PA7", .number = 2, .debug = false}, + {.pin = &gpio_ext_pa6, .name = "PA6", .number = 3, .debug = false}, + {.pin = &gpio_ext_pa4, .name = "PA4", .number = 4, .debug = false}, + {.pin = &gpio_ext_pb3, .name = "PB3", .number = 5, .debug = false}, + {.pin = &gpio_ext_pb2, .name = "PB2", .number = 6, .debug = false}, + {.pin = &gpio_ext_pc3, .name = "PC3", .number = 7, .debug = false}, + // GND: 8 + // Space + // 3v3: 9 + {.pin = &gpio_swclk, .name = "PA14", .number = 10, .debug = true}, + // GND: 11 + {.pin = &gpio_swdio, .name = "PA13", .number = 12, .debug = true}, + {.pin = &gpio_usart_tx, .name = "PB6", .number = 13, .debug = true}, + {.pin = &gpio_usart_rx, .name = "PB7", .number = 14, .debug = true}, + {.pin = &gpio_ext_pc1, .name = "PC1", .number = 15, .debug = false}, + {.pin = &gpio_ext_pc0, .name = "PC0", .number = 16, .debug = false}, + {.pin = &gpio_ibutton, .name = "PB14", .number = 17, .debug = true}, + // GND: 18 /* Dangerous pins, may damage hardware */ - {.pin = &gpio_usart_rx, .name = "PB7", .debug = true}, {.pin = &gpio_speaker, .name = "PB8", .debug = true}, {.pin = &gpio_infrared_tx, .name = "PB9", .debug = true}, }; -const size_t gpio_pins_count = sizeof(gpio_pins) / sizeof(GpioPinRecord); +const size_t gpio_pins_count = COUNT_OF(gpio_pins); const InputPin input_pins[] = { {.gpio = &gpio_button_up, .key = InputKeyUp, .inverted = true, .name = "Up"}, @@ -95,7 +105,7 @@ const InputPin input_pins[] = { {.gpio = &gpio_button_back, .key = InputKeyBack, .inverted = true, .name = "Back"}, }; -const size_t input_pins_count = sizeof(input_pins) / sizeof(InputPin); +const size_t input_pins_count = COUNT_OF(input_pins); static void furi_hal_resources_init_input_pins(GpioMode mode) { for(size_t i = 0; i < input_pins_count; i++) { @@ -210,24 +220,10 @@ void furi_hal_resources_init() { } int32_t furi_hal_resources_get_ext_pin_number(const GpioPin* gpio) { - if(gpio == &gpio_ext_pa7) - return 2; - else if(gpio == &gpio_ext_pa6) - return 3; - else if(gpio == &gpio_ext_pa4) - return 4; - else if(gpio == &gpio_ext_pb3) - return 5; - else if(gpio == &gpio_ext_pb2) - return 6; - else if(gpio == &gpio_ext_pc3) - return 7; - else if(gpio == &gpio_ext_pc1) - return 15; - else if(gpio == &gpio_ext_pc0) - return 16; - else if(gpio == &gpio_ibutton) - return 17; - else - return -1; + for(size_t i = 0; i < gpio_pins_count; i++) { + if(gpio_pins[i].pin == gpio) { + return gpio_pins[i].number; + } + } + return -1; } diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.h b/firmware/targets/f7/furi_hal/furi_hal_resources.h index 6e585c518..6ca6f9df0 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.h +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.h @@ -41,6 +41,7 @@ typedef struct { typedef struct { const GpioPin* pin; const char* name; + const uint8_t number; const bool debug; } GpioPinRecord; diff --git a/lib/drivers/bq27220.c b/lib/drivers/bq27220.c index 4a9feed9b..a3a88603d 100644 --- a/lib/drivers/bq27220.c +++ b/lib/drivers/bq27220.c @@ -54,6 +54,10 @@ static bool bq27220_parameter_check( } if(update) { + // Datasheet contains incorrect procedure for memory update, more info: + // https://e2e.ti.com/support/power-management-group/power-management/f/power-management-forum/719878/bq27220-technical-reference-manual-sluubd4-is-missing-extended-data-commands-chapter + + // 2. Write the address AND the parameter data to 0x3E+ (auto increment) if(!furi_hal_i2c_write_mem( handle, BQ27220_ADDRESS, @@ -67,9 +71,12 @@ static bool bq27220_parameter_check( furi_delay_us(10000); + // 3. Calculate the check sum: 0xFF - (sum of address and data) OR 0xFF uint8_t checksum = bq27220_get_checksum(buffer, size + 2); + // 4. Write the check sum to 0x60 and the total length of (address + parameter data + check sum + length) to 0x61 buffer[0] = checksum; - buffer[1] = 4 + size; // TODO FL-3519: why 4? + // 2 bytes address, `size` bytes data, 1 byte check sum, 1 byte length + buffer[1] = 2 + size + 1 + 1; if(!furi_hal_i2c_write_mem( handle, BQ27220_ADDRESS, CommandMACDataSum, buffer, 2, BQ27220_I2C_TIMEOUT)) { FURI_LOG_I(TAG, "CRC write failed"); From 7531e18020b4f2b67b60950c841dc8e282d97d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Fri, 1 Sep 2023 11:00:40 +0900 Subject: [PATCH 24/59] Move roadmap link to readme (#3014) Co-authored-by: hedger --- ReadMe.md | 4 ++++ documentation/RoadMap.md | 46 ---------------------------------------- 2 files changed, 4 insertions(+), 46 deletions(-) delete mode 100644 documentation/RoadMap.md diff --git a/ReadMe.md b/ReadMe.md index bbaf9603e..dcf39c3ae 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -36,6 +36,10 @@ Finally, open a [Pull Request](https://github.com/flipperdevices/flipperzero-fir Flipper Zero Firmware is written in C, with some bits and pieces written in C++ and armv7m assembly languages. An intermediate level of C knowledge is recommended for comfortable programming. C, C++, and armv7m assembly languages are supported for Flipper applications. +# Firmware RoadMap + +[Firmware RoadMap Miro Board](https://miro.com/app/board/uXjVO_3D6xU=/) + ## Requirements Supported development platforms: diff --git a/documentation/RoadMap.md b/documentation/RoadMap.md deleted file mode 100644 index 658bb2086..000000000 --- a/documentation/RoadMap.md +++ /dev/null @@ -1,46 +0,0 @@ -# RoadMap - -# Where we are now (0.x.x branch) - -Our goal for the 0.x.x branch is to build an API and apps that are stable and usable. The first public release in this branch is 0.43.1. - -## What's already implemented - -**System and HAL** - -- Furi Core -- Furi HAL -- Loading applications from SD - -**Applications** - -- SubGhz: all most common protocols, reading RAW for everything else -- 125kHz RFID: all most common protocols -- NFC: reading/emulating MIFARE Ultralight, reading MIFARE Classic and DESFire, basic EMV, and basic NFC-B/F/V -- Infrared: all most common RC protocols, RAW format for everything else -- GPIO: UART bridge, basic GPIO controls -- iButton: DS1990, Cyfral, Metakom -- Bad USB: full USB Rubber Ducky support, some extras for Windows Alt codes -- U2F: full U2F specification support - -**External applications** - -- Bluetooth -- Snake game - -# Where we're going (Version 1) - -The main goal for 1.0.0 is to provide the first stable version for both Users and Developers. - -## What we're planning to implement in 1.0.0 - -- More protocols (gathering feedback) -- User documentation (work in progress) -- FuriHal: deep sleep mode, stable API, examples, documentation (work in progress) -- Application improvements (a ton of things that we want to add and improve that are too numerous to list here) - -## When will it happen, and where can I see the progress? - -Release 1.0.0 will likely happen around the end of 2023Q1. - -You can track the development progress in our public Miro board: https://miro.com/app/board/uXjVO_3D6xU=/?moveToWidget=3458764522498020058&cot=14 From d8d2b360cb819fedef198427b9d22adab5e0da8d Mon Sep 17 00:00:00 2001 From: suaveolent <2163625+suaveolent@users.noreply.github.com> Date: Fri, 1 Sep 2023 04:22:29 +0200 Subject: [PATCH 25/59] Add support for Mifare Classic 4k SAK 0x38 ATQA 0x02, 0x04, 0x08 (#3009) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: suaveolent Co-authored-by: あく --- lib/nfc/protocols/mifare_classic.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/nfc/protocols/mifare_classic.c b/lib/nfc/protocols/mifare_classic.c index 011747d59..a72d4aac0 100644 --- a/lib/nfc/protocols/mifare_classic.c +++ b/lib/nfc/protocols/mifare_classic.c @@ -381,7 +381,9 @@ bool mf_classic_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) { } else if((ATQA0 == 0x01) && (ATQA1 == 0x0F) && (SAK == 0x01)) { //skylanders support return true; - } else if((ATQA0 == 0x42 || ATQA0 == 0x02) && (SAK == 0x18)) { + } else if( + ((ATQA0 == 0x42 || ATQA0 == 0x02) && (SAK == 0x18)) || + ((ATQA0 == 0x02 || ATQA0 == 0x04 || ATQA0 == 0x08) && (SAK == 0x38))) { return true; } else { return false; @@ -393,13 +395,17 @@ MfClassicType mf_classic_get_classic_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t if((ATQA0 == 0x44 || ATQA0 == 0x04)) { if((SAK == 0x08 || SAK == 0x88)) { return MfClassicType1k; + } else if((SAK == 0x38)) { + return MfClassicType4k; } else if(SAK == 0x09) { return MfClassicTypeMini; } } else if((ATQA0 == 0x01) && (ATQA1 == 0x0F) && (SAK == 0x01)) { //skylanders support return MfClassicType1k; - } else if((ATQA0 == 0x42 || ATQA0 == 0x02) && (SAK == 0x18)) { + } else if( + ((ATQA0 == 0x42 || ATQA0 == 0x02) && (SAK == 0x18)) || + ((ATQA0 == 0x02 || ATQA0 == 0x08) && (SAK == 0x38))) { return MfClassicType4k; } return MfClassicType1k; From 5eeb672dd454659ea2f1d218e136ebb9f321cebf Mon Sep 17 00:00:00 2001 From: hedger Date: Fri, 1 Sep 2023 06:09:48 +0300 Subject: [PATCH 26/59] github: workflow trigger optimizations (#3030) --- .github/workflows/build.yml | 72 +----------------- .github/workflows/build_compact.yml | 75 +++++++++++++++++++ .../workflows/lint_and_submodule_check.yml | 7 +- .github/workflows/merge_report.yml | 2 +- .github/workflows/pvs_studio.yml | 2 - .github/workflows/reindex.yml | 2 +- 6 files changed, 79 insertions(+), 81 deletions(-) create mode 100644 .github/workflows/build_compact.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bd85858a3..07b219712 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,7 @@ env: jobs: main: - runs-on: [self-hosted,FlipperZeroShell] + runs-on: [self-hosted, FlipperZeroShell] steps: - name: 'Wipe workspace' run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; @@ -37,7 +37,6 @@ jobs: TYPE="other" fi python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE" || cat "${{ github.event_path }}" - echo random_hash=$(openssl rand -base64 40 | shasum -a 256 | awk '{print $1}') >> $GITHUB_OUTPUT echo "event_type=$TYPE" >> $GITHUB_OUTPUT - name: 'Check API versions' @@ -149,72 +148,3 @@ jobs: - [📥 DFU file](https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-full-${{steps.names.outputs.suffix}}.dfu) - [☁️ Web/App updater](https://lab.flipper.net/?url=https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-update-${{steps.names.outputs.suffix}}.tgz&channel=${{steps.names.outputs.branch_name}}&version=${{steps.names.outputs.commit_sha}}) edit-mode: replace - - compact: - if: ${{ !startsWith(github.ref, 'refs/tags') }} - runs-on: [self-hosted,FlipperZeroShell] - strategy: - matrix: - target: [f7, f18] - steps: - - name: 'Wipe workspace' - run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; - - - name: 'Checkout code' - uses: actions/checkout@v3 - with: - fetch-depth: 1 - submodules: false - ref: ${{ github.event.pull_request.head.sha }} - - - name: 'Get commit details' - run: | - if [[ ${{ github.event_name }} == 'pull_request' ]]; then - TYPE="pull" - elif [[ "${{ github.ref }}" == "refs/tags/"* ]]; then - TYPE="tag" - else - TYPE="other" - fi - python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE" || cat "${{ github.event_path }}" - - - name: 'Build the firmware' - id: build-fw - run: | - set -e - TARGET="$(echo '${{ matrix.target }}' | sed 's/f//')"; \ - ./fbt TARGET_HW=$TARGET DEBUG=0 COMPACT=1 fap_dist updater_package - echo "sdk-file=$(ls dist/${{ matrix.target }}-*/flipper-z-${{ matrix.target }}-sdk-*.zip)" >> $GITHUB_OUTPUT - echo "hw-target-code=$TARGET" >> $GITHUB_OUTPUT - - - name: Deploy uFBT with SDK - uses: flipperdevices/flipperzero-ufbt-action@v0.1.0 - with: - task: setup - sdk-file: ${{ steps.build-fw.outputs.sdk-file }} - sdk-hw-target: ${{ steps.build-fw.outputs.hw-target-code }} - - - name: Build test app with SDK - run: | - mkdir testapp - cd testapp - ufbt create APPID=testapp - ufbt - - - name: Build example & external apps with uFBT - run: | - for appdir in 'applications/examples'; do - for app in $(find "$appdir" -maxdepth 1 -mindepth 1 -type d); do - pushd $app - TARGETS_FAM=$(grep "targets" application.fam || echo "${{ matrix.target }}") - if ! grep -q "${{ matrix.target }}" <<< $TARGETS_FAM ; then - echo Skipping unsupported app: $app - popd - continue - fi - echo Building $app - ufbt - popd - done - done - diff --git a/.github/workflows/build_compact.yml b/.github/workflows/build_compact.yml new file mode 100644 index 000000000..705888a41 --- /dev/null +++ b/.github/workflows/build_compact.yml @@ -0,0 +1,75 @@ +name: 'Compact build' + +on: + pull_request: + +env: + FBT_TOOLCHAIN_PATH: /runner/_work + +jobs: + compact: + runs-on: [self-hosted, FlipperZeroShell] + strategy: + matrix: + target: [f7, f18] + steps: + - name: 'Wipe workspace' + run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; + + - name: 'Checkout code' + uses: actions/checkout@v3 + with: + fetch-depth: 1 + submodules: false + ref: ${{ github.event.pull_request.head.sha }} + + - name: 'Get commit details' + run: | + if [[ ${{ github.event_name }} == 'pull_request' ]]; then + TYPE="pull" + elif [[ "${{ github.ref }}" == "refs/tags/"* ]]; then + TYPE="tag" + else + TYPE="other" + fi + python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE" || cat "${{ github.event_path }}" + + - name: 'Build the firmware' + id: build-fw + run: | + set -e + TARGET="$(echo '${{ matrix.target }}' | sed 's/f//')"; \ + ./fbt TARGET_HW=$TARGET DEBUG=0 COMPACT=1 fap_dist updater_package + echo "sdk-file=$(ls dist/${{ matrix.target }}-*/flipper-z-${{ matrix.target }}-sdk-*.zip)" >> $GITHUB_OUTPUT + echo "hw-target-code=$TARGET" >> $GITHUB_OUTPUT + + - name: Deploy uFBT with SDK + uses: flipperdevices/flipperzero-ufbt-action@v0.1.0 + with: + task: setup + sdk-file: ${{ steps.build-fw.outputs.sdk-file }} + sdk-hw-target: ${{ steps.build-fw.outputs.hw-target-code }} + + - name: Build test app with SDK + run: | + mkdir testapp + cd testapp + ufbt create APPID=testapp + ufbt + + - name: Build example & external apps with uFBT + run: | + for appdir in 'applications/examples'; do + for app in $(find "$appdir" -maxdepth 1 -mindepth 1 -type d); do + pushd $app + TARGETS_FAM=$(grep "targets" application.fam || echo "${{ matrix.target }}") + if ! grep -q "${{ matrix.target }}" <<< $TARGETS_FAM ; then + echo Skipping unsupported app: $app + popd + continue + fi + echo Building $app + ufbt + popd + done + done diff --git a/.github/workflows/lint_and_submodule_check.yml b/.github/workflows/lint_and_submodule_check.yml index b85409ecd..62e02b8a4 100644 --- a/.github/workflows/lint_and_submodule_check.yml +++ b/.github/workflows/lint_and_submodule_check.yml @@ -1,11 +1,6 @@ name: 'Lint sources & check submodule integrity' on: - push: - branches: - - dev - tags: - - '*' pull_request: env: @@ -15,7 +10,7 @@ env: jobs: lint_sources_check_submodules: - runs-on: [self-hosted,FlipperZeroShell] + runs-on: [self-hosted, FlipperZeroShell] steps: - name: 'Wipe workspace' run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; diff --git a/.github/workflows/merge_report.yml b/.github/workflows/merge_report.yml index 020166666..fedc4b87f 100644 --- a/.github/workflows/merge_report.yml +++ b/.github/workflows/merge_report.yml @@ -10,7 +10,7 @@ env: jobs: merge_report: - runs-on: [self-hosted,FlipperZeroShell] + runs-on: [self-hosted, FlipperZeroShell] steps: - name: 'Wipe workspace' run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; diff --git a/.github/workflows/pvs_studio.yml b/.github/workflows/pvs_studio.yml index cb5b50278..24964a309 100644 --- a/.github/workflows/pvs_studio.yml +++ b/.github/workflows/pvs_studio.yml @@ -4,8 +4,6 @@ on: push: branches: - dev - tags: - - '*' pull_request: env: diff --git a/.github/workflows/reindex.yml b/.github/workflows/reindex.yml index 5645f609b..82cb04680 100644 --- a/.github/workflows/reindex.yml +++ b/.github/workflows/reindex.yml @@ -7,7 +7,7 @@ on: jobs: reindex: name: 'Reindex updates' - runs-on: [self-hosted,FlipperZeroShell] + runs-on: [self-hosted, FlipperZeroShell] steps: - name: Trigger reindex run: | From e5fdb2e069698c441af69e03d876034f9c05c559 Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Fri, 1 Sep 2023 13:54:12 +0900 Subject: [PATCH 27/59] [FL-3314] Disconnect from BLE on protobuf error (#2955) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Disconnect from BLE on protobuf error * Set profile instead of disconnecting and add logging Co-authored-by: あく --- applications/services/rpc/rpc.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/applications/services/rpc/rpc.c b/applications/services/rpc/rpc.c index b3ed4417c..3e9665ad8 100644 --- a/applications/services/rpc/rpc.c +++ b/applications/services/rpc/rpc.c @@ -15,6 +15,8 @@ #include #include +#include + #define TAG "RpcSrv" typedef enum { @@ -316,6 +318,15 @@ static int32_t rpc_session_worker(void* context) { session->closed_callback(session->context); } furi_mutex_release(session->callbacks_mutex); + + if(session->owner == RpcOwnerBle) { + // Disconnect BLE session + FURI_LOG_E("RPC", "BLE session closed due to a decode error"); + Bt* bt = furi_record_open(RECORD_BT); + bt_set_profile(bt, BtProfileSerial); + furi_record_close(RECORD_BT); + FURI_LOG_E("RPC", "Finished disconnecting the BLE session"); + } } } From 52b59662627254ae5ccde6201b5c4921573fc769 Mon Sep 17 00:00:00 2001 From: Max <66625166+m1-ins@users.noreply.github.com> Date: Fri, 1 Sep 2023 06:57:49 +0100 Subject: [PATCH 28/59] Add File Naming setting for more detailed naming (#3002) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * added filename mode setting * added furi_flag checks for when filename_mode is set * changed naming for ibutton, lfrfid and subghz * requested changes from PR * Lib: gather all naming bits and pieces under name generator module. Properly bump api version. FuriHal: fix RTC flag enum. * PR requested changes * bug fix for arg type * added functionality for other application scenes * Lib: cleanup name generator API, simplify usage. Sync API symbols. * Lib: proper size type in name_generator. Cleanup. * FuriHal: cleanup rtc api usage across firmware Co-authored-by: あく --- applications/main/ibutton/ibutton.c | 3 +- applications/main/ibutton/ibutton_i.h | 3 +- .../ibutton/scenes/ibutton_scene_save_name.c | 11 +-- .../scenes/infrared_scene_universal_ac.c | 1 - applications/main/lfrfid/lfrfid.c | 10 ++- applications/main/lfrfid/lfrfid_i.h | 5 +- .../lfrfid/scenes/lfrfid_scene_save_name.c | 9 ++- applications/main/nfc/nfc.c | 6 +- .../main/nfc/scenes/nfc_scene_save_name.c | 8 +- .../subghz/scenes/subghz_scene_read_raw.c | 6 +- .../subghz/scenes/subghz_scene_save_name.c | 13 +++- applications/main/subghz/subghz_i.c | 9 ++- applications/services/gui/canvas.c | 1 - applications/services/gui/view_port.c | 1 - .../settings/system/system_settings.c | 21 ++++++ firmware/targets/f18/api_symbols.csv | 8 +- firmware/targets/f7/api_symbols.csv | 8 +- .../targets/furi_hal_include/furi_hal_rtc.h | 1 + lib/nfc/nfc_device.c | 8 +- lib/nfc/nfc_device.h | 3 +- lib/subghz/protocols/raw.c | 3 +- lib/subghz/types.h | 3 +- lib/toolbox/SConscript | 2 +- lib/toolbox/name_generator.c | 75 +++++++++++++++++++ lib/toolbox/name_generator.h | 35 +++++++++ lib/toolbox/random_name.c | 35 --------- lib/toolbox/random_name.h | 17 ----- 27 files changed, 207 insertions(+), 98 deletions(-) create mode 100644 lib/toolbox/name_generator.c create mode 100644 lib/toolbox/name_generator.h delete mode 100644 lib/toolbox/random_name.c delete mode 100644 lib/toolbox/random_name.h diff --git a/applications/main/ibutton/ibutton.c b/applications/main/ibutton/ibutton.c index ad5b233b5..67873690c 100644 --- a/applications/main/ibutton/ibutton.c +++ b/applications/main/ibutton/ibutton.c @@ -195,7 +195,8 @@ bool ibutton_load_key(iButton* ibutton) { bool ibutton_select_and_load_key(iButton* ibutton) { DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options(&browser_options, IBUTTON_APP_EXTENSION, &I_ibutt_10px); + dialog_file_browser_set_basic_options( + &browser_options, IBUTTON_APP_FILENAME_EXTENSION, &I_ibutt_10px); browser_options.base_path = IBUTTON_APP_FOLDER; if(furi_string_empty(ibutton->file_path)) { diff --git a/applications/main/ibutton/ibutton_i.h b/applications/main/ibutton/ibutton_i.h index 509279210..077b14807 100644 --- a/applications/main/ibutton/ibutton_i.h +++ b/applications/main/ibutton/ibutton_i.h @@ -29,7 +29,8 @@ #include "scenes/ibutton_scene.h" #define IBUTTON_APP_FOLDER ANY_PATH("ibutton") -#define IBUTTON_APP_EXTENSION ".ibtn" +#define IBUTTON_APP_FILENAME_PREFIX "iBtn" +#define IBUTTON_APP_FILENAME_EXTENSION ".ibtn" #define IBUTTON_KEY_NAME_SIZE 22 diff --git a/applications/main/ibutton/scenes/ibutton_scene_save_name.c b/applications/main/ibutton/scenes/ibutton_scene_save_name.c index 7bd49df83..e6236dc35 100644 --- a/applications/main/ibutton/scenes/ibutton_scene_save_name.c +++ b/applications/main/ibutton/scenes/ibutton_scene_save_name.c @@ -1,6 +1,6 @@ #include "../ibutton_i.h" -#include +#include #include #include @@ -17,7 +17,8 @@ void ibutton_scene_save_name_on_enter(void* context) { const bool is_new_file = furi_string_empty(ibutton->file_path); if(is_new_file) { - set_random_name(ibutton->key_name, IBUTTON_KEY_NAME_SIZE); + name_generator_make_auto( + ibutton->key_name, IBUTTON_KEY_NAME_SIZE, IBUTTON_APP_FILENAME_PREFIX); } text_input_set_header_text(text_input, "Name the key"); @@ -29,8 +30,8 @@ void ibutton_scene_save_name_on_enter(void* context) { IBUTTON_KEY_NAME_SIZE, is_new_file); - ValidatorIsFile* validator_is_file = - validator_is_file_alloc_init(IBUTTON_APP_FOLDER, IBUTTON_APP_EXTENSION, ibutton->key_name); + ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( + IBUTTON_APP_FOLDER, IBUTTON_APP_FILENAME_EXTENSION, ibutton->key_name); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewTextInput); @@ -48,7 +49,7 @@ bool ibutton_scene_save_name_on_event(void* context, SceneManagerEvent event) { "%s/%s%s", IBUTTON_APP_FOLDER, ibutton->key_name, - IBUTTON_APP_EXTENSION); + IBUTTON_APP_FILENAME_EXTENSION); if(ibutton_save_key(ibutton)) { scene_manager_next_scene(ibutton->scene_manager, iButtonSceneSaveSuccess); diff --git a/applications/main/infrared/scenes/infrared_scene_universal_ac.c b/applications/main/infrared/scenes/infrared_scene_universal_ac.c index cbb09a525..5f762d122 100644 --- a/applications/main/infrared/scenes/infrared_scene_universal_ac.c +++ b/applications/main/infrared/scenes/infrared_scene_universal_ac.c @@ -1,7 +1,6 @@ #include "../infrared_i.h" #include "common/infrared_scene_universal_common.h" -#include void infrared_scene_universal_ac_on_enter(void* context) { infrared_scene_universal_common_on_enter(context); diff --git a/applications/main/lfrfid/lfrfid.c b/applications/main/lfrfid/lfrfid.c index aa7510a90..2bef08df2 100644 --- a/applications/main/lfrfid/lfrfid.c +++ b/applications/main/lfrfid/lfrfid.c @@ -215,13 +215,16 @@ bool lfrfid_save_key(LfRfid* app) { lfrfid_make_app_folder(app); - if(furi_string_end_with(app->file_path, LFRFID_APP_EXTENSION)) { + if(furi_string_end_with(app->file_path, LFRFID_APP_FILENAME_EXTENSION)) { size_t filename_start = furi_string_search_rchar(app->file_path, '/'); furi_string_left(app->file_path, filename_start); } furi_string_cat_printf( - app->file_path, "/%s%s", furi_string_get_cstr(app->file_name), LFRFID_APP_EXTENSION); + app->file_path, + "/%s%s", + furi_string_get_cstr(app->file_name), + LFRFID_APP_FILENAME_EXTENSION); result = lfrfid_save_key_data(app, app->file_path); return result; @@ -231,7 +234,8 @@ bool lfrfid_load_key_from_file_select(LfRfid* app) { furi_assert(app); DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options(&browser_options, LFRFID_APP_EXTENSION, &I_125_10px); + dialog_file_browser_set_basic_options( + &browser_options, LFRFID_APP_FILENAME_EXTENSION, &I_125_10px); browser_options.base_path = LFRFID_APP_FOLDER; // Input events and views are managed by file_browser diff --git a/applications/main/lfrfid/lfrfid_i.h b/applications/main/lfrfid/lfrfid_i.h index 72b061930..d94a5f865 100644 --- a/applications/main/lfrfid/lfrfid_i.h +++ b/applications/main/lfrfid/lfrfid_i.h @@ -40,8 +40,9 @@ #define LFRFID_APP_FOLDER ANY_PATH("lfrfid") #define LFRFID_SD_FOLDER EXT_PATH("lfrfid") -#define LFRFID_APP_EXTENSION ".rfid" -#define LFRFID_APP_SHADOW_EXTENSION ".shd" +#define LFRFID_APP_FILENAME_PREFIX "RFID" +#define LFRFID_APP_FILENAME_EXTENSION ".rfid" +#define LFRFID_APP_SHADOW_FILENAME_EXTENSION ".shd" #define LFRFID_APP_RAW_ASK_EXTENSION ".ask.raw" #define LFRFID_APP_RAW_PSK_EXTENSION ".psk.raw" diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_save_name.c b/applications/main/lfrfid/scenes/lfrfid_scene_save_name.c index 771f2f603..3a38e213d 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_save_name.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_save_name.c @@ -1,6 +1,6 @@ -#include #include "../lfrfid_i.h" #include +#include void lfrfid_scene_save_name_on_enter(void* context) { LfRfid* app = context; @@ -11,7 +11,10 @@ void lfrfid_scene_save_name_on_enter(void* context) { bool key_name_is_empty = furi_string_empty(app->file_name); if(key_name_is_empty) { furi_string_set(app->file_path, LFRFID_APP_FOLDER); - set_random_name(app->text_store, LFRFID_TEXT_STORE_SIZE); + + name_generator_make_auto( + app->text_store, LFRFID_TEXT_STORE_SIZE, LFRFID_APP_FILENAME_PREFIX); + furi_string_set(folder_path, LFRFID_APP_FOLDER); } else { lfrfid_text_store_set(app, "%s", furi_string_get_cstr(app->file_name)); @@ -31,7 +34,7 @@ void lfrfid_scene_save_name_on_enter(void* context) { ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( furi_string_get_cstr(folder_path), - LFRFID_APP_EXTENSION, + LFRFID_APP_FILENAME_EXTENSION, furi_string_get_cstr(app->file_name)); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); diff --git a/applications/main/nfc/nfc.c b/applications/main/nfc/nfc.c index 56d98a8c6..4ac793b5b 100644 --- a/applications/main/nfc/nfc.c +++ b/applications/main/nfc/nfc.c @@ -223,7 +223,11 @@ void nfc_blink_stop(Nfc* nfc) { bool nfc_save_file(Nfc* nfc) { furi_string_printf( - nfc->dev->load_path, "%s/%s%s", NFC_APP_FOLDER, nfc->dev->dev_name, NFC_APP_EXTENSION); + nfc->dev->load_path, + "%s/%s%s", + NFC_APP_FOLDER, + nfc->dev->dev_name, + NFC_APP_FILENAME_EXTENSION); bool file_saved = nfc_device_save(nfc->dev, furi_string_get_cstr(nfc->dev->load_path)); return file_saved; } diff --git a/applications/main/nfc/scenes/nfc_scene_save_name.c b/applications/main/nfc/scenes/nfc_scene_save_name.c index a7b97aac0..b18e17633 100644 --- a/applications/main/nfc/scenes/nfc_scene_save_name.c +++ b/applications/main/nfc/scenes/nfc_scene_save_name.c @@ -1,5 +1,5 @@ #include "../nfc_i.h" -#include +#include #include #include #include @@ -17,7 +17,7 @@ void nfc_scene_save_name_on_enter(void* context) { TextInput* text_input = nfc->text_input; bool dev_name_empty = false; if(!strcmp(nfc->dev->dev_name, "")) { - set_random_name(nfc->text_store, sizeof(nfc->text_store)); + name_generator_make_auto(nfc->text_store, NFC_DEV_NAME_MAX_LEN, NFC_APP_FILENAME_PREFIX); dev_name_empty = true; } else { nfc_text_store_set(nfc, nfc->dev->dev_name); @@ -34,14 +34,14 @@ void nfc_scene_save_name_on_enter(void* context) { FuriString* folder_path; folder_path = furi_string_alloc(); - if(furi_string_end_with(nfc->dev->load_path, NFC_APP_EXTENSION)) { + if(furi_string_end_with(nfc->dev->load_path, NFC_APP_FILENAME_EXTENSION)) { path_extract_dirname(furi_string_get_cstr(nfc->dev->load_path), folder_path); } else { furi_string_set(folder_path, NFC_APP_FOLDER); } ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - furi_string_get_cstr(folder_path), NFC_APP_EXTENSION, nfc->dev->dev_name); + furi_string_get_cstr(folder_path), NFC_APP_FILENAME_EXTENSION, nfc->dev->dev_name); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewTextInput); diff --git a/applications/main/subghz/scenes/subghz_scene_read_raw.c b/applications/main/subghz/scenes/subghz_scene_read_raw.c index 58e4b0429..bbcc43256 100644 --- a/applications/main/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_read_raw.c @@ -239,7 +239,11 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { FuriString* temp_str = furi_string_alloc(); furi_string_printf( - temp_str, "%s/%s%s", SUBGHZ_RAW_FOLDER, RAW_FILE_NAME, SUBGHZ_APP_EXTENSION); + temp_str, + "%s/%s%s", + SUBGHZ_RAW_FOLDER, + RAW_FILE_NAME, + SUBGHZ_APP_FILENAME_EXTENSION); subghz_protocol_raw_gen_fff_data( subghz_txrx_get_fff_data(subghz->txrx), furi_string_get_cstr(temp_str), diff --git a/applications/main/subghz/scenes/subghz_scene_save_name.c b/applications/main/subghz/scenes/subghz_scene_save_name.c index 86eddfe8e..394dda89e 100644 --- a/applications/main/subghz/scenes/subghz_scene_save_name.c +++ b/applications/main/subghz/scenes/subghz_scene_save_name.c @@ -1,10 +1,10 @@ #include "../subghz_i.h" #include "subghz/types.h" -#include #include "../helpers/subghz_custom_event.h" #include #include #include +#include #define MAX_TEXT_INPUT_LEN 22 @@ -40,7 +40,9 @@ void subghz_scene_save_name_on_enter(void* context) { if(!subghz_path_is_file(subghz->file_path)) { char file_name_buf[SUBGHZ_MAX_LEN_NAME] = {0}; - set_random_name(file_name_buf, SUBGHZ_MAX_LEN_NAME); + + name_generator_make_auto(file_name_buf, SUBGHZ_MAX_LEN_NAME, SUBGHZ_APP_FILENAME_PREFIX); + furi_string_set(file_name, file_name_buf); furi_string_set(subghz->file_path, SUBGHZ_APP_FOLDER); //highlighting the entire filename by default @@ -71,7 +73,7 @@ void subghz_scene_save_name_on_enter(void* context) { dev_name_empty); ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - furi_string_get_cstr(subghz->file_path), SUBGHZ_APP_EXTENSION, ""); + furi_string_get_cstr(subghz->file_path), SUBGHZ_APP_FILENAME_EXTENSION, ""); text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); furi_string_free(file_name); @@ -94,7 +96,10 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { if(event.event == SubGhzCustomEventSceneSaveName) { if(strcmp(subghz->file_name_tmp, "") != 0) { furi_string_cat_printf( - subghz->file_path, "/%s%s", subghz->file_name_tmp, SUBGHZ_APP_EXTENSION); + subghz->file_path, + "/%s%s", + subghz->file_name_tmp, + SUBGHZ_APP_FILENAME_EXTENSION); if(subghz_path_is_file(subghz->file_path_tmp)) { if(!subghz_rename_file(subghz)) { return false; diff --git a/applications/main/subghz/subghz_i.c b/applications/main/subghz/subghz_i.c index 9ff618371..c03efe5e5 100644 --- a/applications/main/subghz/subghz_i.c +++ b/applications/main/subghz/subghz_i.c @@ -238,7 +238,7 @@ bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len) { storage, furi_string_get_cstr(file_path), furi_string_get_cstr(file_name), - SUBGHZ_APP_EXTENSION, + SUBGHZ_APP_FILENAME_EXTENSION, file_name, max_len); @@ -247,7 +247,7 @@ bool subghz_get_next_name_file(SubGhz* subghz, uint8_t max_len) { "%s/%s%s", furi_string_get_cstr(file_path), furi_string_get_cstr(file_name), - SUBGHZ_APP_EXTENSION); + SUBGHZ_APP_FILENAME_EXTENSION); furi_string_set(subghz->file_path, temp_str); res = true; } @@ -320,7 +320,8 @@ bool subghz_load_protocol_from_file(SubGhz* subghz) { FuriString* file_path = furi_string_alloc(); DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options(&browser_options, SUBGHZ_APP_EXTENSION, &I_sub1_10px); + dialog_file_browser_set_basic_options( + &browser_options, SUBGHZ_APP_FILENAME_EXTENSION, &I_sub1_10px); browser_options.base_path = SUBGHZ_APP_FOLDER; // Input events and views are managed by file_select @@ -394,7 +395,7 @@ void subghz_file_name_clear(SubGhz* subghz) { } bool subghz_path_is_file(FuriString* path) { - return furi_string_end_with(path, SUBGHZ_APP_EXTENSION); + return furi_string_end_with(path, SUBGHZ_APP_FILENAME_EXTENSION); } void subghz_lock(SubGhz* subghz) { diff --git a/applications/services/gui/canvas.c b/applications/services/gui/canvas.c index 6e35dcffb..37edc5d33 100644 --- a/applications/services/gui/canvas.c +++ b/applications/services/gui/canvas.c @@ -4,7 +4,6 @@ #include #include -#include #include #include diff --git a/applications/services/gui/view_port.c b/applications/services/gui/view_port.c index 0f300c168..6723a777b 100644 --- a/applications/services/gui/view_port.c +++ b/applications/services/gui/view_port.c @@ -2,7 +2,6 @@ #include #include -#include #include "gui.h" #include "gui_i.h" diff --git a/applications/settings/system/system_settings.c b/applications/settings/system/system_settings.c index dd3c0dc6b..d19b4747b 100644 --- a/applications/settings/system/system_settings.c +++ b/applications/settings/system/system_settings.c @@ -153,6 +153,21 @@ static void sleep_method_changed(VariableItem* item) { } } +const char* const filename_scheme[] = { + "Default", + "Detailed", +}; + +static void filename_scheme_changed(VariableItem* item) { + uint8_t index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, filename_scheme[index]); + if(index) { + furi_hal_rtc_set_flag(FuriHalRtcFlagDetailedFilename); + } else { + furi_hal_rtc_reset_flag(FuriHalRtcFlagDetailedFilename); + } +} + static uint32_t system_settings_exit(void* context) { UNUSED(context); return VIEW_NONE; @@ -236,6 +251,12 @@ SystemSettings* system_settings_alloc() { variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, sleep_method[value_index]); + item = variable_item_list_add( + app->var_item_list, "File Naming", COUNT_OF(filename_scheme), filename_scheme_changed, app); + value_index = furi_hal_rtc_is_flag_set(FuriHalRtcFlagDetailedFilename) ? 1 : 0; + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, filename_scheme[value_index]); + view_set_previous_callback( variable_item_list_get_view(app->var_item_list), system_settings_exit); view_dispatcher_add_view( diff --git a/firmware/targets/f18/api_symbols.csv b/firmware/targets/f18/api_symbols.csv index a61679bca..a26db8823 100644 --- a/firmware/targets/f18/api_symbols.csv +++ b/firmware/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,35.1,, +Version,+,36.0,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -172,10 +172,10 @@ Header,+,lib/toolbox/hex.h,, Header,+,lib/toolbox/manchester_decoder.h,, Header,+,lib/toolbox/manchester_encoder.h,, Header,+,lib/toolbox/md5.h,, +Header,+,lib/toolbox/name_generator.h,, Header,+,lib/toolbox/path.h,, Header,+,lib/toolbox/pretty_format.h,, Header,+,lib/toolbox/protocols/protocol_dict.h,, -Header,+,lib/toolbox/random_name.h,, Header,+,lib/toolbox/saved_struct.h,, Header,+,lib/toolbox/sha256.h,, Header,+,lib/toolbox/stream/buffered_file_stream.h,, @@ -1705,6 +1705,9 @@ Function,-,music_worker_set_callback,void,"MusicWorker*, MusicWorkerCallback, vo Function,-,music_worker_set_volume,void,"MusicWorker*, float" Function,-,music_worker_start,void,MusicWorker* Function,-,music_worker_stop,void,MusicWorker* +Function,+,name_generator_make_auto,void,"char*, size_t, const char*" +Function,+,name_generator_make_detailed,void,"char*, size_t, const char*" +Function,+,name_generator_make_random,void,"char*, size_t" Function,-,nan,double,const char* Function,-,nanf,float,const char* Function,-,nanl,long double,const char* @@ -1925,7 +1928,6 @@ Function,-,serial_svc_set_rpc_status,void,SerialServiceRpcStatus Function,-,serial_svc_start,void, Function,-,serial_svc_stop,void, Function,-,serial_svc_update_tx,_Bool,"uint8_t*, uint16_t" -Function,+,set_random_name,void,"char*, uint8_t" Function,-,setbuf,void,"FILE*, char*" Function,-,setbuffer,void,"FILE*, char*, int" Function,-,setenv,int,"const char*, const char*, int" diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 8baec5a8d..6ad88d9b8 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,35.1,, +Version,+,36.0,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, @@ -213,10 +213,10 @@ Header,+,lib/toolbox/hex.h,, Header,+,lib/toolbox/manchester_decoder.h,, Header,+,lib/toolbox/manchester_encoder.h,, Header,+,lib/toolbox/md5.h,, +Header,+,lib/toolbox/name_generator.h,, Header,+,lib/toolbox/path.h,, Header,+,lib/toolbox/pretty_format.h,, Header,+,lib/toolbox/protocols/protocol_dict.h,, -Header,+,lib/toolbox/random_name.h,, Header,+,lib/toolbox/saved_struct.h,, Header,+,lib/toolbox/sha256.h,, Header,+,lib/toolbox/stream/buffered_file_stream.h,, @@ -2090,6 +2090,9 @@ Function,-,music_worker_set_callback,void,"MusicWorker*, MusicWorkerCallback, vo Function,-,music_worker_set_volume,void,"MusicWorker*, float" Function,-,music_worker_start,void,MusicWorker* Function,-,music_worker_stop,void,MusicWorker* +Function,+,name_generator_make_auto,void,"char*, size_t, const char*" +Function,+,name_generator_make_detailed,void,"char*, size_t, const char*" +Function,+,name_generator_make_random,void,"char*, size_t" Function,-,nan,double,const char* Function,-,nanf,float,const char* Function,-,nanl,long double,const char* @@ -2535,7 +2538,6 @@ Function,-,serial_svc_set_rpc_status,void,SerialServiceRpcStatus Function,-,serial_svc_start,void, Function,-,serial_svc_stop,void, Function,-,serial_svc_update_tx,_Bool,"uint8_t*, uint16_t" -Function,+,set_random_name,void,"char*, uint8_t" Function,-,setbuf,void,"FILE*, char*" Function,-,setbuffer,void,"FILE*, char*, int" Function,-,setenv,int,"const char*, const char*, int" diff --git a/firmware/targets/furi_hal_include/furi_hal_rtc.h b/firmware/targets/furi_hal_include/furi_hal_rtc.h index 186d22f07..c457b6903 100644 --- a/firmware/targets/furi_hal_include/furi_hal_rtc.h +++ b/firmware/targets/furi_hal_include/furi_hal_rtc.h @@ -32,6 +32,7 @@ typedef enum { FuriHalRtcFlagHandOrient = (1 << 4), FuriHalRtcFlagLegacySleep = (1 << 5), FuriHalRtcFlagStealthMode = (1 << 6), + FuriHalRtcFlagDetailedFilename = (1 << 7), } FuriHalRtcFlag; typedef enum { diff --git a/lib/nfc/nfc_device.c b/lib/nfc/nfc_device.c index 2c92b5bf3..c5c8b4338 100644 --- a/lib/nfc/nfc_device.c +++ b/lib/nfc/nfc_device.c @@ -1360,7 +1360,7 @@ void nfc_device_set_name(NfcDevice* dev, const char* name) { static void nfc_device_get_path_without_ext(FuriString* orig_path, FuriString* shadow_path) { // TODO: this won't work if there is ".nfc" anywhere in the path other than // at the end - size_t ext_start = furi_string_search(orig_path, NFC_APP_EXTENSION); + size_t ext_start = furi_string_search(orig_path, NFC_APP_FILENAME_EXTENSION); furi_string_set_n(shadow_path, orig_path, 0, ext_start); } @@ -1587,7 +1587,7 @@ bool nfc_file_select(NfcDevice* dev) { // Input events and views are managed by file_browser const DialogsFileBrowserOptions browser_options = { - .extension = NFC_APP_EXTENSION, + .extension = NFC_APP_FILENAME_EXTENSION, .skip_assets = true, .hide_dot_files = true, .icon = &I_Nfc_10px, @@ -1659,7 +1659,7 @@ bool nfc_device_delete(NfcDevice* dev, bool use_load_path) { "%s/%s%s", furi_string_get_cstr(dev->folder), dev->dev_name, - NFC_APP_EXTENSION); + NFC_APP_FILENAME_EXTENSION); } if(!storage_simply_remove(dev->storage, furi_string_get_cstr(file_path))) break; // Delete shadow file if it exists @@ -1717,7 +1717,7 @@ bool nfc_device_restore(NfcDevice* dev, bool use_load_path) { "%s/%s%s", furi_string_get_cstr(dev->folder), dev->dev_name, - NFC_APP_EXTENSION); + NFC_APP_FILENAME_EXTENSION); } if(!nfc_device_load_data(dev, path, true)) break; restored = true; diff --git a/lib/nfc/nfc_device.h b/lib/nfc/nfc_device.h index 20df4f891..76de0b61c 100644 --- a/lib/nfc/nfc_device.h +++ b/lib/nfc/nfc_device.h @@ -21,7 +21,8 @@ extern "C" { #define NFC_READER_DATA_MAX_SIZE 64 #define NFC_DICT_KEY_BATCH_SIZE 10 -#define NFC_APP_EXTENSION ".nfc" +#define NFC_APP_FILENAME_PREFIX "NFC" +#define NFC_APP_FILENAME_EXTENSION ".nfc" #define NFC_APP_SHADOW_EXTENSION ".shd" typedef void (*NfcLoadingCallback)(void* context, bool state); diff --git a/lib/subghz/protocols/raw.c b/lib/subghz/protocols/raw.c index c9d2b3017..4a8ae1d5e 100644 --- a/lib/subghz/protocols/raw.c +++ b/lib/subghz/protocols/raw.c @@ -108,7 +108,8 @@ bool subghz_protocol_raw_save_to_file_init( furi_string_set(instance->file_name, dev_name); // First remove subghz device file if it was saved - furi_string_printf(temp_str, "%s/%s%s", SUBGHZ_RAW_FOLDER, dev_name, SUBGHZ_APP_EXTENSION); + furi_string_printf( + temp_str, "%s/%s%s", SUBGHZ_RAW_FOLDER, dev_name, SUBGHZ_APP_FILENAME_EXTENSION); if(!storage_simply_remove(instance->storage, furi_string_get_cstr(temp_str))) { break; diff --git a/lib/subghz/types.h b/lib/subghz/types.h index cccf70bad..93f94cc74 100644 --- a/lib/subghz/types.h +++ b/lib/subghz/types.h @@ -13,7 +13,8 @@ #define SUBGHZ_APP_FOLDER ANY_PATH("subghz") #define SUBGHZ_RAW_FOLDER EXT_PATH("subghz") -#define SUBGHZ_APP_EXTENSION ".sub" +#define SUBGHZ_APP_FILENAME_PREFIX "SubGHz" +#define SUBGHZ_APP_FILENAME_EXTENSION ".sub" #define SUBGHZ_KEY_FILE_VERSION 1 #define SUBGHZ_KEY_FILE_TYPE "Flipper SubGhz Key File" diff --git a/lib/toolbox/SConscript b/lib/toolbox/SConscript index 761755d2d..04fd8567f 100644 --- a/lib/toolbox/SConscript +++ b/lib/toolbox/SConscript @@ -13,7 +13,7 @@ env.Append( File("manchester_decoder.h"), File("manchester_encoder.h"), File("path.h"), - File("random_name.h"), + File("name_generator.h"), File("sha256.h"), File("crc32_calc.h"), File("dir_walk.h"), diff --git a/lib/toolbox/name_generator.c b/lib/toolbox/name_generator.c new file mode 100644 index 000000000..36366485a --- /dev/null +++ b/lib/toolbox/name_generator.c @@ -0,0 +1,75 @@ +#include "name_generator.h" + +#include +#include +#include +#include +#include +#include + +const char* const name_generator_left[] = { + "ancient", "hollow", "strange", "disappeared", "unknown", "unthinkable", "unnameable", + "nameless", "my", "concealed", "forgotten", "hidden", "mysterious", "obscure", + "random", "remote", "uncharted", "undefined", "untraveled", "untold", +}; + +const char* const name_generator_right[] = { + "door", + "entrance", + "doorway", + "entry", + "portal", + "entree", + "opening", + "crack", + "access", + "corridor", + "passage", + "port", +}; + +void name_generator_make_auto(char* name, size_t max_name_size, const char* prefix) { + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDetailedFilename)) { + name_generator_make_detailed(name, max_name_size, prefix); + } else { + name_generator_make_random(name, max_name_size); + } +} + +void name_generator_make_random(char* name, size_t max_name_size) { + furi_assert(name); + furi_assert(max_name_size); + + uint8_t name_generator_left_i = rand() % COUNT_OF(name_generator_left); + uint8_t name_generator_right_i = rand() % COUNT_OF(name_generator_right); + + snprintf( + name, + max_name_size, + "%s_%s", + name_generator_left[name_generator_left_i], + name_generator_right[name_generator_right_i]); + + // Set first symbol to upper case + name[0] = name[0] - 0x20; +} + +void name_generator_make_detailed(char* name, size_t max_name_size, const char* prefix) { + furi_assert(name); + furi_assert(max_name_size); + furi_assert(prefix); + + FuriHalRtcDateTime dateTime; + furi_hal_rtc_get_datetime(&dateTime); + + snprintf( + name, + max_name_size, + "%s-%.4d_%.2d_%.2d-%.2d_%.2d", + prefix, + dateTime.year, + dateTime.month, + dateTime.day, + dateTime.hour, + dateTime.minute); +} diff --git a/lib/toolbox/name_generator.h b/lib/toolbox/name_generator.h new file mode 100644 index 000000000..bc17d54cd --- /dev/null +++ b/lib/toolbox/name_generator.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Generates detailed/random name based on furi_hal flags + * + * @param name buffer to write random name + * @param max_name_size length of given buffer + * @param[in] prefix The prefix of the name + */ +void name_generator_make_auto(char* name, size_t max_name_size, const char* prefix); + +/** Generates random name + * + * @param name buffer to write random name + * @param max_name_size length of given buffer + */ +void name_generator_make_random(char* name, size_t max_name_size); + +/** Generates detailed name + * + * @param name buffer to write random name + * @param max_name_size length of given buffer + * @param[in] prefix The prefix of the name + */ +void name_generator_make_detailed(char* name, size_t max_name_size, const char* prefix); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/lib/toolbox/random_name.c b/lib/toolbox/random_name.c deleted file mode 100644 index 64e712c7c..000000000 --- a/lib/toolbox/random_name.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "random_name.h" -#include -#include -#include -#include - -void set_random_name(char* name, uint8_t max_name_size) { - const char* prefix[] = { - "ancient", "hollow", "strange", "disappeared", "unknown", - "unthinkable", "unnamable", "nameless", "my", "concealed", - "forgotten", "hidden", "mysterious", "obscure", "random", - "remote", "uncharted", "undefined", "untravelled", "untold", - }; - - const char* suffix[] = { - "door", - "entrance", - "doorway", - "entry", - "portal", - "entree", - "opening", - "crack", - "access", - "corridor", - "passage", - "port", - }; - uint8_t prefix_i = rand() % COUNT_OF(prefix); - uint8_t suffix_i = rand() % COUNT_OF(suffix); - - snprintf(name, max_name_size, "%s_%s", prefix[prefix_i], suffix[suffix_i]); - // Set first symbol to upper case - name[0] = name[0] - 0x20; -} diff --git a/lib/toolbox/random_name.h b/lib/toolbox/random_name.h deleted file mode 100644 index 358ea685d..000000000 --- a/lib/toolbox/random_name.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Generates random name - * @param name buffer to write random name - * @param max_name_size length of given buffer - */ -void set_random_name(char* name, uint8_t max_name_size); - -#ifdef __cplusplus -} -#endif From 7a0c896626ddb68c10ea3dca0fd91b14df1c655e Mon Sep 17 00:00:00 2001 From: amec0e <88857687+amec0e@users.noreply.github.com> Date: Fri, 1 Sep 2023 22:35:31 +0100 Subject: [PATCH 29/59] Update audio.ir New additions --- assets/resources/infrared/assets/audio.ir | 148 +++++++++++++++++++++- 1 file changed, 146 insertions(+), 2 deletions(-) diff --git a/assets/resources/infrared/assets/audio.ir b/assets/resources/infrared/assets/audio.ir index 51ccb6569..2f44cf926 100644 --- a/assets/resources/infrared/assets/audio.ir +++ b/assets/resources/infrared/assets/audio.ir @@ -1,7 +1,7 @@ Filetype: IR library file Version: 1 -# Last Updated 24th Jul, 2023 -# Last Checked 19th Aug, 2023 +# Last Updated 1st Sept, 2023 +# Last Checked 1st Sept, 2023 # name: Power type: parsed @@ -3752,3 +3752,147 @@ type: parsed protocol: NEC address: A0 00 00 00 command: 0A 00 00 00 +# +name: Power +type: parsed +protocol: NECext +address: D9 14 00 00 +command: 6D 92 00 00 +# +name: Mute +type: parsed +protocol: NECext +address: D9 14 00 00 +command: 6E 91 00 00 +# +name: Vol_up +type: parsed +protocol: NECext +address: D9 14 00 00 +command: 4F B0 00 00 +# +name: Vol_down +type: parsed +protocol: NECext +address: D9 14 00 00 +command: 50 AF 00 00 +# +name: Prev +type: parsed +protocol: SIRC20 +address: 3A 07 00 00 +command: 30 00 00 00 +# +name: Next +type: parsed +protocol: SIRC20 +address: 3A 07 00 00 +command: 31 00 00 00 +# +name: Next +type: parsed +protocol: SIRC20 +address: 3A 07 00 00 +command: 34 00 00 00 +# +name: Power +type: parsed +protocol: RC5 +address: 1A 00 00 00 +command: 0C 00 00 00 +# +name: Prev +type: parsed +protocol: RC5 +address: 1A 00 00 00 +command: 21 00 00 00 +# +name: Next +type: parsed +protocol: RC5 +address: 1A 00 00 00 +command: 20 00 00 00 +# +name: Pause +type: parsed +protocol: RC5 +address: 1A 00 00 00 +command: 30 00 00 00 +# +name: Play +type: parsed +protocol: RC5 +address: 1A 00 00 00 +command: 35 00 00 00 +# +name: Play +type: parsed +protocol: SIRC +address: 11 00 00 00 +command: 32 00 00 00 +# +name: Pause +type: parsed +protocol: SIRC +address: 11 00 00 00 +command: 39 00 00 00 +# +name: Prev +type: parsed +protocol: SIRC +address: 11 00 00 00 +command: 30 00 00 00 +# +name: Next +type: parsed +protocol: SIRC +address: 11 00 00 00 +command: 31 00 00 00 +# +name: Play +type: parsed +protocol: SIRC20 +address: 5A 19 00 00 +command: 2A 00 00 00 +# +name: Pause +type: parsed +protocol: SIRC20 +address: 5A 19 00 00 +command: 29 00 00 00 +# +name: Prev +type: parsed +protocol: SIRC20 +address: 5A 19 00 00 +command: 20 00 00 00 +# +name: Next +type: parsed +protocol: SIRC20 +address: 5A 19 00 00 +command: 21 00 00 00 +# +name: Power +type: parsed +protocol: NECext +address: 84 74 00 00 +command: FF 00 00 00 +# +name: Vol_up +type: parsed +protocol: NECext +address: 80 70 00 00 +command: C7 38 00 00 +# +name: Vol_dn +type: parsed +protocol: NECext +address: 80 70 00 00 +command: C8 37 00 00 +# +name: Mute +type: parsed +protocol: NECext +address: 80 70 00 00 +command: C1 3E 00 00 From 832d861b9d7dba767547016d4c57b43e41a510b9 Mon Sep 17 00:00:00 2001 From: amec0e <88857687+amec0e@users.noreply.github.com> Date: Fri, 1 Sep 2023 22:35:58 +0100 Subject: [PATCH 30/59] Update fans.ir New additions --- assets/resources/infrared/assets/fans.ir | 28 ++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/assets/resources/infrared/assets/fans.ir b/assets/resources/infrared/assets/fans.ir index 2c84eb829..6b728f708 100644 --- a/assets/resources/infrared/assets/fans.ir +++ b/assets/resources/infrared/assets/fans.ir @@ -1,7 +1,7 @@ Filetype: IR library file Version: 1 -#Last Updated 19th Aug, 2023 -#Last Checked 19th Aug, 2023 +#Last Updated 1st Sept, 2023 +#Last Checked 1st Sept, 2023 # name: Power type: raw @@ -1965,3 +1965,27 @@ type: parsed protocol: NEC address: 03 00 00 00 command: 9B 00 00 00 +# +name: Power +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 9018 4461 617 1623 617 502 618 502 617 502 617 503 616 501 619 503 616 501 618 502 617 1622 617 1623 617 1621 618 1621 618 1622 617 1623 617 1622 618 1623 617 1623 617 501 619 503 617 531 588 502 618 502 617 502 617 503 617 501 618 1623 617 1623 617 1622 618 1623 617 1622 618 1623 617 1623 617 1621 619 503 617 503 617 501 619 503 616 501 618 503 617 503 616 504 616 1621 619 1623 617 1623 617 1624 615 1623 617 1623 616 +# +name: Speed_up +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 9021 4460 676 1564 676 445 675 444 676 445 675 445 675 445 674 445 675 446 674 445 675 1566 674 1565 674 1565 674 1566 673 1565 674 1565 674 1565 674 1566 674 1565 674 1565 674 445 674 446 674 445 674 446 673 445 674 446 674 446 673 446 674 1566 673 1565 674 1567 672 1568 672 1567 672 1566 674 1567 673 1567 673 447 673 447 673 448 672 446 621 499 621 499 621 500 672 449 618 1619 620 1621 619 1619 621 1620 620 1620 620 +# +name: Rotate +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 8995 4486 588 1653 587 532 588 530 590 531 589 534 585 532 587 531 589 532 587 532 588 1652 587 1652 588 1652 588 1652 588 1653 587 1652 588 1652 588 1652 588 1651 589 531 589 532 588 1652 588 532 588 531 589 531 589 531 588 531 589 1652 588 1651 589 532 588 1651 589 1651 589 1652 588 1651 589 1652 587 533 586 531 588 1653 587 531 588 531 589 532 588 531 589 532 587 1651 588 1653 586 530 589 1651 588 1651 588 1652 587 +# +name: Mode +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 8993 4485 589 1651 589 529 590 529 591 530 590 530 589 530 590 531 589 530 589 531 589 1649 590 1650 589 1649 590 1650 589 1651 588 1649 590 1650 589 1654 585 1650 589 1651 588 1650 590 533 586 531 588 532 588 530 590 530 590 532 587 531 588 530 589 1650 589 1650 589 1652 587 1651 588 1651 588 1650 589 1650 589 1652 587 530 590 530 589 530 589 531 588 531 588 531 588 530 589 531 588 1651 588 1650 590 1651 589 1651 589 From 7ecd5684cb84323635df8ec3a717396f9dfd1f2b Mon Sep 17 00:00:00 2001 From: amec0e <88857687+amec0e@users.noreply.github.com> Date: Fri, 1 Sep 2023 22:36:21 +0100 Subject: [PATCH 31/59] Update projectors.ir New additions --- .../resources/infrared/assets/projectors.ir | 52 ++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/assets/resources/infrared/assets/projectors.ir b/assets/resources/infrared/assets/projectors.ir index c06a17cb3..b33be0681 100644 --- a/assets/resources/infrared/assets/projectors.ir +++ b/assets/resources/infrared/assets/projectors.ir @@ -1,7 +1,7 @@ Filetype: IR library file Version: 1 -# Last Updated 19th Aug, 2023 -# Last Checked 19th Aug, 2023 +# Last Updated 1st Sept, 2023 +# Last Checked 1st Sept, 2023 # # ON name: Power @@ -1078,9 +1078,57 @@ type: parsed protocol: NEC address: 01 00 00 00 command: 03 00 00 00 +# +name: Pause +type: parsed +protocol: NEC +address: 01 00 00 00 +command: 03 00 00 00 # name: Mute type: parsed protocol: NEC address: 03 00 00 00 command: 02 00 00 00 +# +name: Power +type: parsed +protocol: NECext +address: 87 4E 00 00 +command: 17 E8 00 00 +# +name: Vol_up +type: parsed +protocol: NECext +address: 4F 50 00 00 +command: 07 F8 00 00 +# +name: Vol_dn +type: parsed +protocol: NECext +address: 4F 50 00 00 +command: 0A F5 00 00 +# +name: Power +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 293 1801 296 753 295 1801 296 1801 296 752 296 754 294 1801 296 1800 297 752 296 1802 295 752 296 1801 296 753 295 1800 297 752 296 42709 296 1800 297 753 295 1800 297 1800 297 753 295 1802 295 753 295 753 295 1801 296 753 295 1801 296 754 294 1802 295 753 295 1801 296 42694 295 1800 297 752 296 1803 294 1803 294 753 295 753 295 1801 296 1802 295 752 296 1802 295 752 296 1801 296 753 295 1802 295 753 295 42709 295 1802 295 753 295 1803 294 1801 296 753 295 1802 295 752 296 752 296 1801 296 752 296 1803 294 754 294 1803 294 754 294 1804 293 42694 294 1802 294 755 293 1803 294 1804 268 779 269 779 269 1828 269 1828 269 780 268 1829 268 778 270 1829 323 725 268 1829 268 781 324 +# +name: Mute +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 363 1732 365 685 363 1734 363 1735 362 686 362 1735 362 687 361 685 362 1735 363 686 267 1830 362 1734 363 686 268 1830 361 687 267 42739 267 1829 268 780 268 1830 267 1829 268 781 267 781 267 1832 265 1830 267 780 268 1830 267 781 267 780 268 1830 267 781 267 1830 267 42723 267 1830 267 781 362 1735 267 1829 268 781 267 1830 267 782 266 780 268 1830 267 781 267 1831 266 1830 267 781 267 1829 268 782 266 +# +name: Vol_up +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 270 1825 272 780 268 1827 349 1747 350 699 349 698 351 698 350 1748 350 698 350 1748 349 699 349 697 351 699 349 1746 351 698 350 44740 349 1745 352 698 350 1747 350 1747 350 698 350 1747 355 1742 355 692 356 1742 355 694 355 1743 354 1742 355 1742 355 694 354 1742 355 40555 355 1742 355 693 355 1742 355 1743 354 693 355 694 354 693 355 1743 354 693 355 1742 355 693 355 692 357 693 355 1741 356 694 354 +# +name: Vol_dn +type: raw +frequency: 38000 +duty_cycle: 0.33 +data: 353 1742 355 693 355 1742 355 1742 355 693 355 1744 353 694 354 1743 354 693 355 1743 354 694 354 693 355 694 354 1742 355 695 353 43687 354 1743 354 696 352 1744 353 1744 353 694 354 695 353 1742 355 694 354 1743 354 694 354 1743 354 1742 355 1742 355 694 354 1744 353 41606 351 1745 352 696 352 1746 351 1746 351 697 351 1747 350 696 352 1745 352 698 350 1746 351 698 350 696 352 698 350 1746 351 699 349 From a8456208da8fc8d4be86546ca2566647d5a79f79 Mon Sep 17 00:00:00 2001 From: amec0e <88857687+amec0e@users.noreply.github.com> Date: Fri, 1 Sep 2023 22:36:42 +0100 Subject: [PATCH 32/59] Update tv.ir New additions --- assets/resources/infrared/assets/tv.ir | 28 ++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/assets/resources/infrared/assets/tv.ir b/assets/resources/infrared/assets/tv.ir index a6b5650ac..1b4eab6e8 100755 --- a/assets/resources/infrared/assets/tv.ir +++ b/assets/resources/infrared/assets/tv.ir @@ -1,7 +1,7 @@ Filetype: IR library file Version: 1 -# Last Updated 24th Jul, 2023 -# Last Checked 19th Aug, 2023 +# Last Updated 1st Sept, 2023 +# Last Checked 1st Sept, 2023 # name: Power type: parsed @@ -2345,3 +2345,27 @@ type: parsed protocol: NEC address: 80 00 00 00 command: D0 00 00 00 +# +name: Ch_next +type: parsed +protocol: NECext +address: 00 7F 00 00 +command: 48 B7 00 00 +# +name: Ch_prev +type: parsed +protocol: NECext +address: 00 7F 00 00 +command: 44 BB 00 00 +# +name: Vol_up +type: parsed +protocol: NECext +address: 00 7F 00 00 +command: 0A F5 00 00 +# +name: Vol_dn +type: parsed +protocol: NECext +address: 00 7F 00 00 +command: 06 F9 00 00 From ec9df8711a5640a4cfbcf2a7e2c827dd927bb476 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Sat, 2 Sep 2023 14:26:32 +0300 Subject: [PATCH 33/59] fmt + fix subrem --- applications/main/subghz/scenes/subghz_scene_save_name.c | 5 +++-- .../main/subghz_remote/scenes/subrem_scene_open_sub_file.c | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/applications/main/subghz/scenes/subghz_scene_save_name.c b/applications/main/subghz/scenes/subghz_scene_save_name.c index 2dd22e5a8..f523aaddf 100644 --- a/applications/main/subghz/scenes/subghz_scene_save_name.c +++ b/applications/main/subghz/scenes/subghz_scene_save_name.c @@ -79,8 +79,9 @@ void subghz_scene_save_name_on_enter(void* context) { subghz_scene_save_name_get_timefilename(file_name, "S", true); } } else { - name_generator_make_auto(file_name_buf, SUBGHZ_MAX_LEN_NAME, SUBGHZ_APP_FILENAME_PREFIX); - furi_string_set(file_name, file_name_buf); + name_generator_make_auto( + file_name_buf, SUBGHZ_MAX_LEN_NAME, SUBGHZ_APP_FILENAME_PREFIX); + furi_string_set(file_name, file_name_buf); } furi_string_set(subghz->file_path, SUBGHZ_APP_FOLDER); //highlighting the entire filename by default diff --git a/applications/main/subghz_remote/scenes/subrem_scene_open_sub_file.c b/applications/main/subghz_remote/scenes/subrem_scene_open_sub_file.c index eb438cb92..663e80ba7 100644 --- a/applications/main/subghz_remote/scenes/subrem_scene_open_sub_file.c +++ b/applications/main/subghz_remote/scenes/subrem_scene_open_sub_file.c @@ -23,7 +23,8 @@ SubRemLoadSubState subrem_scene_open_sub_file_dialog(SubGhzRemoteApp* app) { DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options(&browser_options, SUBGHZ_APP_EXTENSION, &I_sub1_10px); + dialog_file_browser_set_basic_options( + &browser_options, SUBGHZ_APP_FILENAME_EXTENSION, &I_sub1_10px); browser_options.base_path = SUBGHZ_RAW_FOLDER; // Input events and views are managed by file_select From 3898e6e71d7134becb07bff72ccf3ec7e640eeba Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Sat, 2 Sep 2023 16:00:24 +0300 Subject: [PATCH 34/59] Fixes and de-kostilying --- .../helpers/subghz_txrx_create_protocol_key.c | 4 +- .../scenes/subghz_scene_radio_settings.c | 6 +-- lib/subghz/blocks/generic.h | 1 + lib/subghz/protocols/faac_slh.c | 40 +++++-------------- 4 files changed, 15 insertions(+), 36 deletions(-) diff --git a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c index ba72652f2..149d1d711 100644 --- a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c +++ b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c @@ -228,9 +228,9 @@ bool subghz_txrx_gen_faac_slh_protocol( seed_data[sizeof(uint32_t) - i - 1] = (seed >> i * 8) & 0xFF; } + bool allow_zero_seed = true; flipper_format_write_hex(txrx->fff_data, "Seed", seed_data, sizeof(uint32_t)); - flipper_format_write_string_cstr(txrx->fff_data, "Valid", "1\r\n"); - FURI_LOG_I(TAG, "Flag write to SD is OK"); + flipper_format_write_bool(txrx->fff_data, "AllowZeroSeed", &allow_zero_seed, 1); } subghz_transmitter_free(txrx->transmitter); diff --git a/applications/main/subghz/scenes/subghz_scene_radio_settings.c b/applications/main/subghz/scenes/subghz_scene_radio_settings.c index 864df6326..1b83510a9 100644 --- a/applications/main/subghz/scenes/subghz_scene_radio_settings.c +++ b/applications/main/subghz/scenes/subghz_scene_radio_settings.c @@ -32,7 +32,7 @@ const char* const debug_pin_text[DEBUG_P_COUNT] = { "17(1W)", }; -#define DEBUG_COUNTER_COUNT 15 +#define DEBUG_COUNTER_COUNT 13 const char* const debug_counter_text[DEBUG_COUNTER_COUNT] = { "+1", "+2", @@ -40,7 +40,6 @@ const char* const debug_counter_text[DEBUG_COUNTER_COUNT] = { "+4", "+5", "+10", - "+100", "0", "-1", "-2", @@ -48,7 +47,6 @@ const char* const debug_counter_text[DEBUG_COUNTER_COUNT] = { "-4", "-5", "-10", - "-100", }; const uint32_t debug_counter_val[DEBUG_COUNTER_COUNT] = { 1, @@ -57,7 +55,6 @@ const uint32_t debug_counter_val[DEBUG_COUNTER_COUNT] = { 4, 5, 10, - 100, 0, -1, -2, @@ -65,7 +62,6 @@ const uint32_t debug_counter_val[DEBUG_COUNTER_COUNT] = { -4, -5, -10, - -100, }; static void subghz_scene_radio_settings_set_device(VariableItem* item) { diff --git a/lib/subghz/blocks/generic.h b/lib/subghz/blocks/generic.h index 10e7b63fa..be61f533e 100644 --- a/lib/subghz/blocks/generic.h +++ b/lib/subghz/blocks/generic.h @@ -25,6 +25,7 @@ struct SubGhzBlockGeneric { uint32_t cnt; uint8_t cnt_2; uint32_t seed; + bool allow_zero_seed; }; /** diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index b01e3a02e..319c6288f 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -10,8 +10,6 @@ #define TAG "SubGhzProtocolFaacSLH" -bool bvalid; - static const SubGhzBlockConst subghz_protocol_faac_slh_const = { .te_short = 255, .te_long = 595, @@ -112,21 +110,10 @@ void subghz_protocol_encoder_faac_slh_free(void* context) { } static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* instance) { - //FuriString* valid = furi_string_alloc(); - //if(flipper_format_read_string(flipper_format, "Valid", valid)) { - //bvalid = true; - //FURI_LOG_I(TAG, "[gen_data] is valid ? : %i", bvalid); - //} else { - //bvalid = false; - //FURI_LOG_I(TAG, "[gen_data] is valid ? : %i", bvalid); - //} - //furi_string_free(valid); - if(bvalid) { + if(instance->generic.allow_zero_seed) { instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); - FURI_LOG_I(TAG, "[gen_data] TRUE : %i", bvalid); } else { // Do not generate new data, send data from buffer - FURI_LOG_I(TAG, "[gen_data] FALSE : %i", bvalid); return true; } uint32_t fix = instance->generic.serial << 4 | instance->generic.btn; @@ -255,15 +242,13 @@ SubGhzProtocolStatus FURI_LOG_E(TAG, "Missing Seed"); break; } - FuriString* valid = furi_string_alloc(); - if(flipper_format_read_string(flipper_format, "Valid", valid)) { - bvalid = true; - FURI_LOG_I(TAG, "[encoder_des] True : %i", bvalid); + bool allow_zero_seed; + if(flipper_format_read_bool(flipper_format, "AllowZeroSeed", &allow_zero_seed, 1)) { + instance->generic.allow_zero_seed = true; } else { - bvalid = false; - FURI_LOG_I(TAG, "[encoder_des] False : %i", bvalid); + instance->generic.allow_zero_seed = false; } - furi_string_free(valid); + instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 | seed_data[3]; @@ -508,15 +493,12 @@ SubGhzProtocolStatus FURI_LOG_E(TAG, "Missing Seed"); break; } - FuriString* valid = furi_string_alloc(); - if(flipper_format_read_string(flipper_format, "Valid", valid)) { - bvalid = true; - FURI_LOG_I(TAG, "[decoder_des] TRUE : %i", bvalid); + bool allow_zero_seed; + if(flipper_format_read_bool(flipper_format, "AllowZeroSeed", &allow_zero_seed, 1)) { + instance->generic.allow_zero_seed = true; } else { - bvalid = false; - FURI_LOG_I(TAG, "[decoder_des] FALSE : %i", bvalid); + instance->generic.allow_zero_seed = false; } - furi_string_free(valid); instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 | seed_data[3]; @@ -538,7 +520,7 @@ 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(bvalid == false) { + if(instance->generic.allow_zero_seed == false) { furi_string_cat_printf( output, "%s %dbit\r\n" From 72e6f5f59e009233924529b556570a31b15b34ce Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Sat, 2 Sep 2023 16:02:32 +0300 Subject: [PATCH 35/59] fix --- assets/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/protobuf b/assets/protobuf index 7e011a958..327163d58 160000 --- a/assets/protobuf +++ b/assets/protobuf @@ -1 +1 @@ -Subproject commit 7e011a95863716e72e7c6b5d552bca241d688304 +Subproject commit 327163d5867c7aa3051334c93ced718d15bfe4da From 265d2592e7bf60b4ff2f1ed5e293abf6b093059f Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Sat, 2 Sep 2023 16:26:19 +0300 Subject: [PATCH 36/59] proper check --- lib/subghz/protocols/faac_slh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index 319c6288f..1d9b66d29 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -110,7 +110,7 @@ void subghz_protocol_encoder_faac_slh_free(void* context) { } static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* instance) { - if(instance->generic.allow_zero_seed) { + if(instance->generic.allow_zero_seed || (instance->generic.seed != 0x0)) { instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); } else { // Do not generate new data, send data from buffer From 06a528f497b08e6517802431d8892dd7386dce0d Mon Sep 17 00:00:00 2001 From: Eng1n33r <101719414+Eng1n33r@users.noreply.github.com> Date: Sat, 2 Sep 2023 19:00:45 +0300 Subject: [PATCH 37/59] FAAC SLH prog mode [beta] --- lib/subghz/blocks/generic.h | 1 + lib/subghz/protocols/faac_slh.c | 96 ++++++++++++++++++++++++++++++++- 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/lib/subghz/blocks/generic.h b/lib/subghz/blocks/generic.h index be61f533e..6f3395620 100644 --- a/lib/subghz/blocks/generic.h +++ b/lib/subghz/blocks/generic.h @@ -25,6 +25,7 @@ struct SubGhzBlockGeneric { uint32_t cnt; uint8_t cnt_2; uint32_t seed; + bool prg_mode; bool allow_zero_seed; }; diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index 1d9b66d29..2d3510002 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -112,6 +112,43 @@ void subghz_protocol_encoder_faac_slh_free(void* context) { static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* instance) { if(instance->generic.allow_zero_seed || (instance->generic.seed != 0x0)) { instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); + } else if(instance->generic.prg_mode == true) { + uint8_t data_tmp = 0; + uint8_t data_prg[8]; + + instance->generic.cnt_2++; + + data_prg[0] = 0x00; + + data_prg[1] = instance->generic.cnt_2; + + 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_I(TAG, "New MasterKey encrypted : %016llX\r", instance->generic.data); + + return true; } else { // Do not generate new data, send data from buffer return true; @@ -415,6 +452,48 @@ static void subghz_protocol_faac_slh_check_remote_controller( uint32_t decrypt = 0; uint64_t man; + 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) ) { + instance->prg_mode = true; + // ProgMode ON + FURI_LOG_I(TAG, "Master Key detected!"); + + 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]; + 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\r", instance->data_2); + instance->cnt_2 = data_prg[1]; + } else { + instance->prg_mode = false; + } + for M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) { switch(manufacture_code->type) { @@ -520,7 +599,22 @@ 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.allow_zero_seed == false) { + if(instance->generic.prg_mode == true) { + furi_string_cat_printf( + output, + "%s %dbit\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, + instance->generic.cnt_2); + } else if(instance->generic.allow_zero_seed == false) { furi_string_cat_printf( output, "%s %dbit\r\n" From 7d2deb5939a42285f934193ad04c2e3483240145 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Sat, 2 Sep 2023 21:45:51 +0300 Subject: [PATCH 38/59] add some non working code --- lib/subghz/blocks/custom_btn_i.h | 1 + lib/subghz/blocks/generic.h | 3 +- lib/subghz/protocols/faac_slh.c | 152 +++++++++++++++++++++++++++++-- 3 files changed, 148 insertions(+), 8 deletions(-) diff --git a/lib/subghz/blocks/custom_btn_i.h b/lib/subghz/blocks/custom_btn_i.h index f75ba4068..2aadba6f4 100644 --- a/lib/subghz/blocks/custom_btn_i.h +++ b/lib/subghz/blocks/custom_btn_i.h @@ -5,6 +5,7 @@ #define PROG_MODE_OFF (0U) #define PROG_MODE_KEELOQ_BFT (1U) #define PROG_MODE_KEELOQ_APRIMATIC (2U) +#define PROG_MODE_FAAC_SLH (3U) typedef uint8_t ProgMode; diff --git a/lib/subghz/blocks/generic.h b/lib/subghz/blocks/generic.h index be61f533e..4b2b6a017 100644 --- a/lib/subghz/blocks/generic.h +++ b/lib/subghz/blocks/generic.h @@ -25,7 +25,8 @@ struct SubGhzBlockGeneric { uint32_t cnt; uint8_t cnt_2; uint32_t seed; - bool allow_zero_seed; + bool allow_zero_seed : 1; + bool prg_mode : 1; }; /** diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index 1d9b66d29..1cddcec85 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -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 = { @@ -110,11 +112,77 @@ void subghz_protocol_encoder_faac_slh_free(void* context) { } static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* instance) { - if(instance->generic.allow_zero_seed || (instance->generic.seed != 0x0)) { - instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); - } else { - // Do not generate new data, send data from buffer + // 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(); + ProgMode prog_mode_btn_status = subghz_custom_btn_get_prog_mode(); + bool button_for_programming = false; + + FURI_LOG_I("GENDATA", "CUSTOMBTN: %d\r", subghz_custom_btn_get()); + + // If custom button left is pressed, enable programming mode and disable it on Ok button + if((custom_btn_id == SUBGHZ_CUSTOM_BTN_OK)) { + if(prog_mode_btn_status == PROG_MODE_FAAC_SLH) { + button_for_programming = false; + prog_mode_btn_status = PROG_MODE_OFF; + } + } else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_UP) { + button_for_programming = true; + prog_mode_btn_status = PROG_MODE_FAAC_SLH; + } + subghz_custom_btn_set_prog_mode(prog_mode_btn_status); + FURI_LOG_I("FAAC", "Button for programming: %d\r", button_for_programming); + FURI_LOG_I("FAAC", "Programming mode: %d\r", instance->generic.prg_mode); + + if(button_for_programming) { + uint8_t data_tmp = 0; + uint8_t data_prg[8]; + + data_prg[0] = 0x00; + + if(instance->generic.allow_zero_seed || (instance->generic.seed != 0x0)) { + instance->generic.cnt += 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_I(TAG, "New MasterKey encrypted : %016llX\r", instance->generic.data); + return true; + } else { + if(!instance->generic.allow_zero_seed && (instance->generic.seed == 0x0)) { + // Do not generate new data, send data from buffer + return true; + } } uint32_t fix = instance->generic.serial << 4 | instance->generic.btn; uint32_t hop = 0; @@ -126,6 +194,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(instance->generic.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 +245,7 @@ bool subghz_protocol_faac_slh_create_data( instance->generic.seed = seed; instance->manufacture_name = manufacture_name; instance->generic.data_count_bit = 64; + instance->generic.allow_zero_seed = true; bool res = subghz_protocol_faac_slh_gen_data(instance); if(res) { return SubGhzProtocolStatusOk == @@ -410,11 +484,59 @@ 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; + // 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); + FURI_LOG_I("RMC", "CUSTOMBTN: %d\r", subghz_custom_btn_get()); + 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))) { + instance->prg_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 { + instance->serial = code_fix >> 4; + instance->btn = code_fix & 0xF; + + instance->prg_mode = false; + } + for M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) { switch(manufacture_code->type) { @@ -520,7 +642,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.allow_zero_seed == false) { + if(instance->generic.prg_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(instance->generic.allow_zero_seed == false) { furi_string_cat_printf( output, "%s %dbit\r\n" From ce89240f6f41ce725421794ad71b99471be0a4d1 Mon Sep 17 00:00:00 2001 From: Linn Dahlgren Date: Mon, 4 Sep 2023 05:37:12 +0200 Subject: [PATCH 39/59] [DOC] Remove defunct link in ReadMe.md (#3036) --- ReadMe.md | 1 - 1 file changed, 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index dcf39c3ae..387ac2de7 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -95,7 +95,6 @@ Make sure your Flipper is on, and your firmware is functioning. Connect your Fli - [Hardware combos and Un-bricking](/documentation/KeyCombo.md) - recovering your Flipper from the most nasty situations - [Flipper File Formats](/documentation/file_formats) - everything about how Flipper stores your data and how you can work with it - [Universal Remotes](/documentation/UniversalRemotes.md) - contributing your infrared remote to the universal remote database -- [Firmware Roadmap](/documentation/RoadMap.md) - And much more in the [documentation](/documentation) folder # Project structure From 0b806c23600ebe3c179f92e0883448e4e46950bd Mon Sep 17 00:00:00 2001 From: Sergey Gavrilov Date: Mon, 4 Sep 2023 08:10:07 +0300 Subject: [PATCH 40/59] Storage: force mount (#3033) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Storage: count opened files * Storage: sd mount * Storage: prompt to mount SD card if not mounted * F18: update API * F18: update API version * Fix logger naming scheme * Storage: storage_files_count -> storage_open_files_count Co-authored-by: あく --- .../debug/unit_tests/subghz/subghz_test.c | 2 +- .../drivers/subghz/cc1101_ext/cc1101_ext.c | 2 +- .../cc1101_ext/cc1101_ext_interconnect.c | 2 +- .../example_apps_assets/example_apps_assets.c | 2 +- .../example_apps_data/example_apps_data.c | 2 +- .../example_plugins/example_plugins.c | 2 +- .../example_plugins/example_plugins_multi.c | 2 +- .../example_advanced_plugins.c | 2 +- .../main/bad_usb/helpers/ducky_script.c | 2 +- .../bad_usb/helpers/ducky_script_commands.c | 2 +- applications/main/ibutton/ibutton.c | 2 +- .../subghz/scenes/subghz_scene_read_raw.c | 2 +- applications/main/subghz/subghz_cli.c | 2 +- .../main/subghz/views/subghz_read_raw.c | 2 +- applications/main/u2f/u2f.c | 2 +- applications/main/u2f/u2f_data.c | 2 +- applications/main/u2f/u2f_hid.c | 2 +- applications/services/storage/storage.c | 2 +- applications/services/storage/storage.h | 10 +++- .../services/storage/storage_external_api.c | 10 +++- applications/services/storage/storage_glue.c | 7 +++ applications/services/storage/storage_glue.h | 2 + .../services/storage/storage_message.h | 1 + .../services/storage/storage_processing.c | 41 +++++++++++++--- .../services/storage/storages/storage_ext.c | 47 +++++++++++-------- .../services/storage/storages/storage_ext.h | 1 + .../scenes/storage_settings_scene_start.c | 24 +++++++--- .../storage_settings_scene_unmount_confirm.c | 14 ++++-- .../scenes/storage_settings_scene_unmounted.c | 41 +++++++++++----- .../updater/util/update_task_worker_flasher.c | 2 +- firmware/targets/f18/api_symbols.csv | 3 +- firmware/targets/f7/api_symbols.csv | 3 +- firmware/targets/f7/furi_hal/furi_hal_i2c.c | 2 +- .../api_hashtable/api_hashtable.cpp | 2 +- lib/flipper_application/application_assets.c | 2 +- lib/flipper_application/elf/elf_file.c | 2 +- .../plugins/plugin_manager.c | 2 +- lib/lfrfid/lfrfid_raw_file.c | 2 +- lib/lfrfid/lfrfid_raw_worker.c | 2 +- lib/lfrfid/lfrfid_worker_modes.c | 2 +- lib/nfc/protocols/slix.c | 2 +- .../cc1101_int/cc1101_int_interconnect.c | 2 +- lib/subghz/protocols/alutech_at_4n.c | 2 +- lib/subghz/protocols/bett.c | 2 +- lib/subghz/protocols/bin_raw.c | 2 +- lib/subghz/protocols/came.c | 2 +- lib/subghz/protocols/came_twee.c | 2 +- lib/subghz/protocols/chamberlain_code.c | 2 +- lib/subghz/protocols/faac_slh.c | 2 +- lib/subghz/protocols/holtek_ht12x.c | 2 +- lib/subghz/protocols/honeywell_wdb.c | 2 +- lib/subghz/protocols/hormann.c | 2 +- lib/subghz/protocols/ido.c | 2 +- lib/subghz/protocols/kia.c | 2 +- lib/subghz/protocols/kinggates_stylo_4k.c | 2 +- lib/subghz/protocols/nice_flo.c | 2 +- lib/subghz/protocols/phoenix_v2.c | 2 +- lib/subghz/protocols/raw.c | 2 +- lib/subghz/protocols/secplus_v1.c | 2 +- lib/subghz/protocols/secplus_v2.c | 2 +- lib/subghz/protocols/smc5326.c | 2 +- 61 files changed, 201 insertions(+), 99 deletions(-) diff --git a/applications/debug/unit_tests/subghz/subghz_test.c b/applications/debug/unit_tests/subghz/subghz_test.c index e32a57482..1900f2045 100644 --- a/applications/debug/unit_tests/subghz/subghz_test.c +++ b/applications/debug/unit_tests/subghz/subghz_test.c @@ -10,7 +10,7 @@ #include #include -#define TAG "SubGhz TEST" +#define TAG "SubGhzTest" #define KEYSTORE_DIR_NAME EXT_PATH("subghz/assets/keeloq_mfcodes") #define CAME_ATOMO_DIR_NAME EXT_PATH("subghz/assets/came_atomo") #define NICE_FLOR_S_DIR_NAME EXT_PATH("subghz/assets/nice_flor_s") diff --git a/applications/drivers/subghz/cc1101_ext/cc1101_ext.c b/applications/drivers/subghz/cc1101_ext/cc1101_ext.c index 0a9599d03..4fb249c6d 100644 --- a/applications/drivers/subghz/cc1101_ext/cc1101_ext.c +++ b/applications/drivers/subghz/cc1101_ext/cc1101_ext.c @@ -16,7 +16,7 @@ #include #include -#define TAG "SubGhz_Device_CC1101_Ext" +#define TAG "SubGhzDeviceCc1101Ext" #define SUBGHZ_DEVICE_CC1101_EXT_TX_GPIO &gpio_ext_pb2 diff --git a/applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.c b/applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.c index 51f5a0d1d..1f1193154 100644 --- a/applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.c +++ b/applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.c @@ -2,7 +2,7 @@ #include "cc1101_ext.h" #include -#define TAG "SubGhzDeviceCC1101Ext" +#define TAG "SubGhzDeviceCc1101Ext" static bool subghz_device_cc1101_ext_interconnect_is_frequency_valid(uint32_t frequency) { bool ret = subghz_device_cc1101_ext_is_frequency_valid(frequency); diff --git a/applications/examples/example_apps_assets/example_apps_assets.c b/applications/examples/example_apps_assets/example_apps_assets.c index f2d0272f0..2c2cc8a87 100644 --- a/applications/examples/example_apps_assets/example_apps_assets.c +++ b/applications/examples/example_apps_assets/example_apps_assets.c @@ -4,7 +4,7 @@ #include // Define log tag -#define TAG "example_apps_assets" +#define TAG "ExampleAppsAssets" static void example_apps_data_print_file_content(Storage* storage, const char* path) { Stream* stream = file_stream_alloc(storage); diff --git a/applications/examples/example_apps_data/example_apps_data.c b/applications/examples/example_apps_data/example_apps_data.c index d6104c137..7a297b01c 100644 --- a/applications/examples/example_apps_data/example_apps_data.c +++ b/applications/examples/example_apps_data/example_apps_data.c @@ -2,7 +2,7 @@ #include // Define log tag -#define TAG "example_apps_data" +#define TAG "ExampleAppsData" // Application entry point int32_t example_apps_data_main(void* p) { diff --git a/applications/examples/example_plugins/example_plugins.c b/applications/examples/example_plugins/example_plugins.c index acc5903ad..7e71e0d2e 100644 --- a/applications/examples/example_plugins/example_plugins.c +++ b/applications/examples/example_plugins/example_plugins.c @@ -11,7 +11,7 @@ #include #include -#define TAG "example_plugins" +#define TAG "ExamplePlugins" int32_t example_plugins_app(void* p) { UNUSED(p); diff --git a/applications/examples/example_plugins/example_plugins_multi.c b/applications/examples/example_plugins/example_plugins_multi.c index 12eba01c1..3525b39ea 100644 --- a/applications/examples/example_plugins/example_plugins_multi.c +++ b/applications/examples/example_plugins/example_plugins_multi.c @@ -11,7 +11,7 @@ #include -#define TAG "example_plugins" +#define TAG "ExamplePlugins" int32_t example_plugins_multi_app(void* p) { UNUSED(p); diff --git a/applications/examples/example_plugins_advanced/example_advanced_plugins.c b/applications/examples/example_plugins_advanced/example_advanced_plugins.c index f27b0a084..2b137e1d4 100644 --- a/applications/examples/example_plugins_advanced/example_advanced_plugins.c +++ b/applications/examples/example_plugins_advanced/example_advanced_plugins.c @@ -8,7 +8,7 @@ #include -#define TAG "example_advanced_plugins" +#define TAG "ExampleAdvancedPlugins" int32_t example_advanced_plugins_app(void* p) { UNUSED(p); diff --git a/applications/main/bad_usb/helpers/ducky_script.c b/applications/main/bad_usb/helpers/ducky_script.c index f194178a0..11c74c010 100644 --- a/applications/main/bad_usb/helpers/ducky_script.c +++ b/applications/main/bad_usb/helpers/ducky_script.c @@ -9,7 +9,7 @@ #include "ducky_script_i.h" #include -#define TAG "BadUSB" +#define TAG "BadUsb" #define WORKER_TAG TAG "Worker" #define BADUSB_ASCII_TO_KEY(script, x) \ diff --git a/applications/main/bad_usb/helpers/ducky_script_commands.c b/applications/main/bad_usb/helpers/ducky_script_commands.c index d073b4c8d..cc713135e 100644 --- a/applications/main/bad_usb/helpers/ducky_script_commands.c +++ b/applications/main/bad_usb/helpers/ducky_script_commands.c @@ -171,7 +171,7 @@ static const DuckyCmd ducky_commands[] = { {"WAIT_FOR_BUTTON_PRESS", ducky_fnc_waitforbutton, -1}, }; -#define TAG "BadUSB" +#define TAG "BadUsb" #define WORKER_TAG TAG "Worker" int32_t ducky_execute_cmd(BadUsbScript* bad_usb, const char* line) { diff --git a/applications/main/ibutton/ibutton.c b/applications/main/ibutton/ibutton.c index 67873690c..0e4c621b2 100644 --- a/applications/main/ibutton/ibutton.c +++ b/applications/main/ibutton/ibutton.c @@ -3,7 +3,7 @@ #include #include -#define TAG "iButtonApp" +#define TAG "IButtonApp" static const NotificationSequence sequence_blink_set_yellow = { &message_blink_set_color_yellow, diff --git a/applications/main/subghz/scenes/subghz_scene_read_raw.c b/applications/main/subghz/scenes/subghz_scene_read_raw.c index bbcc43256..f2ab65770 100644 --- a/applications/main/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/main/subghz/scenes/subghz_scene_read_raw.c @@ -5,7 +5,7 @@ #include #define RAW_FILE_NAME "Raw_signal_" -#define TAG "SubGhzSceneReadRAW" +#define TAG "SubGhzSceneReadRaw" bool subghz_scene_read_raw_update_filename(SubGhz* subghz) { bool ret = false; diff --git a/applications/main/subghz/subghz_cli.c b/applications/main/subghz/subghz_cli.c index fe97c8a06..f7d6b3a1c 100644 --- a/applications/main/subghz/subghz_cli.c +++ b/applications/main/subghz/subghz_cli.c @@ -28,7 +28,7 @@ #define SUBGHZ_REGION_FILENAME "/int/.region_data" -#define TAG "SubGhz CLI" +#define TAG "SubGhzCli" static void subghz_cli_radio_device_power_on() { uint8_t attempts = 5; diff --git a/applications/main/subghz/views/subghz_read_raw.c b/applications/main/subghz/views/subghz_read_raw.c index 88ac129ca..b074cdc9f 100644 --- a/applications/main/subghz/views/subghz_read_raw.c +++ b/applications/main/subghz/views/subghz_read_raw.c @@ -9,7 +9,7 @@ #include #define SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE 100 -#define TAG "SubGhzReadRAW" +#define TAG "SubGhzReadRaw" struct SubGhzReadRAW { View* view; diff --git a/applications/main/u2f/u2f.c b/applications/main/u2f/u2f.c index 0ed5ebb29..ce70212a9 100644 --- a/applications/main/u2f/u2f.c +++ b/applications/main/u2f/u2f.c @@ -10,7 +10,7 @@ #include "hmac_sha256.h" #include "micro-ecc/uECC.h" -#define TAG "U2F" +#define TAG "U2f" #define WORKER_TAG TAG "Worker" #define U2F_CMD_REGISTER 0x01 diff --git a/applications/main/u2f/u2f_data.c b/applications/main/u2f/u2f_data.c index 8489ed91e..34360f3d6 100644 --- a/applications/main/u2f/u2f_data.c +++ b/applications/main/u2f/u2f_data.c @@ -5,7 +5,7 @@ #include #include -#define TAG "U2F" +#define TAG "U2f" #define U2F_DATA_FOLDER EXT_PATH("u2f/") #define U2F_CERT_FILE U2F_DATA_FOLDER "assets/cert.der" diff --git a/applications/main/u2f/u2f_hid.c b/applications/main/u2f/u2f_hid.c index 9b625c1f3..d7d7e6cf4 100644 --- a/applications/main/u2f/u2f_hid.c +++ b/applications/main/u2f/u2f_hid.c @@ -10,7 +10,7 @@ #include -#define TAG "U2FHID" +#define TAG "U2fHid" #define WORKER_TAG TAG "Worker" #define U2F_HID_MAX_PAYLOAD_LEN ((HID_U2F_PACKET_LEN - 7) + 128 * (HID_U2F_PACKET_LEN - 5)) diff --git a/applications/services/storage/storage.c b/applications/services/storage/storage.c index 1816bf921..a6229af81 100644 --- a/applications/services/storage/storage.c +++ b/applications/services/storage/storage.c @@ -12,7 +12,7 @@ #define ICON_SD_MOUNTED &I_SDcardMounted_11x8 #define ICON_SD_ERROR &I_SDcardFail_11x8 -#define TAG RECORD_STORAGE +#define TAG "Storage" static void storage_app_sd_icon_draw_callback(Canvas* canvas, void* context) { furi_assert(canvas); diff --git a/applications/services/storage/storage.h b/applications/services/storage/storage.h index dccf29592..1abc8ed0e 100644 --- a/applications/services/storage/storage.h +++ b/applications/services/storage/storage.h @@ -334,12 +334,20 @@ const char* storage_file_get_error_desc(File* file); */ FS_Error storage_sd_format(Storage* api); -/** Will unmount the SD card +/** Will unmount the SD card. + * Will return FSE_NOT_READY if the SD card is not mounted. + * Will return FSE_DENIED if there are open files on the SD card. * @param api pointer to the api * @return FS_Error operation result */ FS_Error storage_sd_unmount(Storage* api); +/** Will mount the SD card + * @param api pointer to the api + * @return FS_Error operation result + */ +FS_Error storage_sd_mount(Storage* api); + /** Retrieves SD card information * @param api pointer to the api * @param info pointer to the info diff --git a/applications/services/storage/storage_external_api.c b/applications/services/storage/storage_external_api.c index 585ded414..2ba58f9c6 100644 --- a/applications/services/storage/storage_external_api.c +++ b/applications/services/storage/storage_external_api.c @@ -11,7 +11,7 @@ #define MAX_EXT_LEN 16 #define FILE_BUFFER_SIZE 512 -#define TAG "StorageAPI" +#define TAG "StorageApi" #define S_API_PROLOGUE FuriApiLock lock = api_lock_alloc_locked(); @@ -781,6 +781,14 @@ FS_Error storage_sd_unmount(Storage* storage) { return S_RETURN_ERROR; } +FS_Error storage_sd_mount(Storage* storage) { + S_API_PROLOGUE; + SAData data = {}; + S_API_MESSAGE(StorageCommandSDMount); + S_API_EPILOGUE; + return S_RETURN_ERROR; +} + FS_Error storage_sd_info(Storage* storage, SDInfo* info) { S_API_PROLOGUE; SAData data = { diff --git a/applications/services/storage/storage_glue.c b/applications/services/storage/storage_glue.c index 63e44c9d7..41da6c3f4 100644 --- a/applications/services/storage/storage_glue.c +++ b/applications/services/storage/storage_glue.c @@ -1,6 +1,8 @@ #include "storage_glue.h" #include +#define TAG "StorageGlue" + /****************** storage file ******************/ void storage_file_init(StorageFile* obj) { @@ -149,3 +151,8 @@ bool storage_pop_storage_file(File* file, StorageData* storage) { return result; } + +size_t storage_open_files_count(StorageData* storage) { + size_t count = StorageFileList_size(storage->files); + return count; +} diff --git a/applications/services/storage/storage_glue.h b/applications/services/storage/storage_glue.h index f10640345..4323296cf 100644 --- a/applications/services/storage/storage_glue.h +++ b/applications/services/storage/storage_glue.h @@ -68,6 +68,8 @@ void* storage_get_storage_file_data(const File* file, StorageData* storage); void storage_push_storage_file(File* file, FuriString* path, StorageData* storage); bool storage_pop_storage_file(File* file, StorageData* storage); +size_t storage_open_files_count(StorageData* storage); + #ifdef __cplusplus } #endif diff --git a/applications/services/storage/storage_message.h b/applications/services/storage/storage_message.h index 9e13bf83d..01bc20380 100644 --- a/applications/services/storage/storage_message.h +++ b/applications/services/storage/storage_message.h @@ -141,6 +141,7 @@ typedef enum { StorageCommandSDInfo, StorageCommandSDStatus, StorageCommandCommonResolvePath, + StorageCommandSDMount, } StorageCommand; typedef struct { diff --git a/applications/services/storage/storage_processing.c b/applications/services/storage/storage_processing.c index 70cb7b92f..00126af6f 100644 --- a/applications/services/storage/storage_processing.c +++ b/applications/services/storage/storage_processing.c @@ -418,12 +418,38 @@ static FS_Error storage_process_sd_format(Storage* app) { static FS_Error storage_process_sd_unmount(Storage* app) { FS_Error ret = FSE_OK; - if(storage_data_status(&app->storage[ST_EXT]) == StorageStatusNotReady) { - ret = FSE_NOT_READY; - } else { - sd_unmount_card(&app->storage[ST_EXT]); - storage_data_timestamp(&app->storage[ST_EXT]); - } + do { + StorageData* storage = &app->storage[ST_EXT]; + if(storage_data_status(storage) == StorageStatusNotReady) { + ret = FSE_NOT_READY; + break; + } + + if(storage_open_files_count(storage)) { + ret = FSE_DENIED; + break; + } + + sd_unmount_card(storage); + storage_data_timestamp(storage); + } while(false); + + return ret; +} + +static FS_Error storage_process_sd_mount(Storage* app) { + FS_Error ret = FSE_OK; + + do { + StorageData* storage = &app->storage[ST_EXT]; + if(storage_data_status(storage) != StorageStatusNotReady) { + ret = FSE_NOT_READY; + break; + } + + ret = sd_mount_card(storage, true); + storage_data_timestamp(storage); + } while(false); return ret; } @@ -630,6 +656,9 @@ void storage_process_message_internal(Storage* app, StorageMessage* message) { case StorageCommandSDUnmount: message->return_data->error_value = storage_process_sd_unmount(app); break; + case StorageCommandSDMount: + message->return_data->error_value = storage_process_sd_mount(app); + break; case StorageCommandSDInfo: message->return_data->error_value = storage_process_sd_info(app, message->data->sdinfo.info); diff --git a/applications/services/storage/storages/storage_ext.c b/applications/services/storage/storages/storage_ext.c index 35b3ee253..080ac4faf 100644 --- a/applications/services/storage/storages/storage_ext.c +++ b/applications/services/storage/storages/storage_ext.c @@ -24,7 +24,7 @@ static FS_Error storage_ext_parse_error(SDError error); /******************* Core Functions *******************/ -static bool sd_mount_card(StorageData* storage, bool notify) { +static bool sd_mount_card_internal(StorageData* storage, bool notify) { bool result = false; uint8_t counter = sd_max_mount_retry_count(); uint8_t bsp_result; @@ -106,6 +106,32 @@ FS_Error sd_unmount_card(StorageData* storage) { return storage_ext_parse_error(error); } +FS_Error sd_mount_card(StorageData* storage, bool notify) { + sd_mount_card_internal(storage, notify); + FS_Error error; + + if(storage->status != StorageStatusOK) { + FURI_LOG_E(TAG, "sd init error: %s", storage_data_status_text(storage)); + if(notify) { + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); + sd_notify_error(notification); + furi_record_close(RECORD_NOTIFICATION); + } + error = FSE_INTERNAL; + } else { + FURI_LOG_I(TAG, "card mounted"); + if(notify) { + NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); + sd_notify_success(notification); + furi_record_close(RECORD_NOTIFICATION); + } + + error = FSE_OK; + } + + return error; +} + FS_Error sd_format_card(StorageData* storage) { #ifdef FURI_RAM_EXEC UNUSED(storage); @@ -222,25 +248,8 @@ static void storage_ext_tick_internal(StorageData* storage, bool notify) { if(sd_data->sd_was_present) { if(hal_sd_detect()) { FURI_LOG_I(TAG, "card detected"); - sd_mount_card(storage, notify); - - if(storage->status != StorageStatusOK) { - FURI_LOG_E(TAG, "sd init error: %s", storage_data_status_text(storage)); - if(notify) { - NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); - sd_notify_error(notification); - furi_record_close(RECORD_NOTIFICATION); - } - } else { - FURI_LOG_I(TAG, "card mounted"); - if(notify) { - NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); - sd_notify_success(notification); - furi_record_close(RECORD_NOTIFICATION); - } - } - sd_data->sd_was_present = false; + sd_mount_card(storage, notify); if(!hal_sd_detect()) { FURI_LOG_I(TAG, "card removed while mounting"); diff --git a/applications/services/storage/storages/storage_ext.h b/applications/services/storage/storages/storage_ext.h index 07ddbcf2f..18d1f7143 100644 --- a/applications/services/storage/storages/storage_ext.h +++ b/applications/services/storage/storages/storage_ext.h @@ -8,6 +8,7 @@ extern "C" { #endif void storage_ext_init(StorageData* storage); +FS_Error sd_mount_card(StorageData* storage, bool notify); FS_Error sd_unmount_card(StorageData* storage); FS_Error sd_format_card(StorageData* storage); FS_Error sd_card_info(StorageData* storage, SDInfo* sd_info); diff --git a/applications/settings/storage_settings/scenes/storage_settings_scene_start.c b/applications/settings/storage_settings/scenes/storage_settings_scene_start.c index 9f41061b8..0e667024f 100644 --- a/applications/settings/storage_settings/scenes/storage_settings_scene_start.c +++ b/applications/settings/storage_settings/scenes/storage_settings_scene_start.c @@ -31,12 +31,24 @@ void storage_settings_scene_start_on_enter(void* context) { StorageSettingsStartSubmenuIndexSDInfo, storage_settings_scene_start_submenu_callback, app); - submenu_add_item( - submenu, - "Unmount SD Card", - StorageSettingsStartSubmenuIndexUnmount, - storage_settings_scene_start_submenu_callback, - app); + + FS_Error sd_status = storage_sd_status(app->fs_api); + if(sd_status != FSE_OK) { + submenu_add_item( + submenu, + "Mount SD Card", + StorageSettingsStartSubmenuIndexUnmount, + storage_settings_scene_start_submenu_callback, + app); + } else { + submenu_add_item( + submenu, + "Unmount SD Card", + StorageSettingsStartSubmenuIndexUnmount, + storage_settings_scene_start_submenu_callback, + app); + } + submenu_add_item( submenu, "Format SD Card", diff --git a/applications/settings/storage_settings/scenes/storage_settings_scene_unmount_confirm.c b/applications/settings/storage_settings/scenes/storage_settings_scene_unmount_confirm.c index 0c15116be..1b9970f9f 100644 --- a/applications/settings/storage_settings/scenes/storage_settings_scene_unmount_confirm.c +++ b/applications/settings/storage_settings/scenes/storage_settings_scene_unmount_confirm.c @@ -12,13 +12,17 @@ void storage_settings_scene_unmount_confirm_on_enter(void* context) { DialogEx* dialog_ex = app->dialog_ex; FS_Error sd_status = storage_sd_status(app->fs_api); - if(sd_status == FSE_NOT_READY) { - dialog_ex_set_icon(dialog_ex, 72, 17, &I_DolphinCommon_56x48); - dialog_ex_set_header(dialog_ex, "SD Card Not Mounted", 64, 3, AlignCenter, AlignTop); + dialog_ex_set_header(dialog_ex, "Mount SD Card?", 64, 10, AlignCenter, AlignCenter); dialog_ex_set_text( - dialog_ex, "Try to reinsert\nor format SD\ncard.", 3, 19, AlignLeft, AlignTop); - dialog_ex_set_center_button_text(dialog_ex, "Ok"); + dialog_ex, + "This may turn off power\nfor external modules", + 64, + 32, + AlignCenter, + AlignCenter); + dialog_ex_set_left_button_text(dialog_ex, "Cancel"); + dialog_ex_set_right_button_text(dialog_ex, "Mount"); } else { dialog_ex_set_header(dialog_ex, "Unmount SD Card?", 64, 10, AlignCenter, AlignCenter); dialog_ex_set_text( diff --git a/applications/settings/storage_settings/scenes/storage_settings_scene_unmounted.c b/applications/settings/storage_settings/scenes/storage_settings_scene_unmounted.c index 486f07603..33bb95522 100644 --- a/applications/settings/storage_settings/scenes/storage_settings_scene_unmounted.c +++ b/applications/settings/storage_settings/scenes/storage_settings_scene_unmounted.c @@ -9,22 +9,41 @@ static void void storage_settings_scene_unmounted_on_enter(void* context) { StorageSettings* app = context; - FS_Error error = storage_sd_unmount(app->fs_api); DialogEx* dialog_ex = app->dialog_ex; + FS_Error sd_status = storage_sd_status(app->fs_api); + if(sd_status == FSE_NOT_READY) { + FS_Error error = storage_sd_mount(app->fs_api); + if(error == FSE_OK) { + dialog_ex_set_header(dialog_ex, "SD Card Mounted", 64, 3, AlignCenter, AlignTop); + dialog_ex_set_text( + dialog_ex, "Flipper can use\nSD card now.", 3, 22, AlignLeft, AlignTop); + notification_message(app->notification, &sequence_blink_green_100); + } else { + dialog_ex_set_header(dialog_ex, "Cannot Mount SD Card", 64, 3, AlignCenter, AlignTop); + dialog_ex_set_text( + dialog_ex, storage_error_get_desc(error), 3, 22, AlignLeft, AlignTop); + notification_message(app->notification, &sequence_blink_red_100); + } + } else { + FS_Error error = storage_sd_unmount(app->fs_api); + if(error == FSE_OK) { + dialog_ex_set_header(dialog_ex, "SD Card Unmounted", 64, 3, AlignCenter, AlignTop); + dialog_ex_set_text( + dialog_ex, "You can remove\nSD card now.", 3, 22, AlignLeft, AlignTop); + notification_message(app->notification, &sequence_blink_green_100); + } else { + dialog_ex_set_header( + dialog_ex, "Cannot Unmount SD Card", 64, 3, AlignCenter, AlignTop); + dialog_ex_set_text( + dialog_ex, storage_error_get_desc(error), 3, 22, AlignLeft, AlignTop); + notification_message(app->notification, &sequence_blink_red_100); + } + } + dialog_ex_set_center_button_text(dialog_ex, "OK"); dialog_ex_set_icon(dialog_ex, 72, 17, &I_DolphinCommon_56x48); - if(error == FSE_OK) { - dialog_ex_set_header(dialog_ex, "SD Card Unmounted", 64, 3, AlignCenter, AlignTop); - dialog_ex_set_text(dialog_ex, "You can remove\nSD card now.", 3, 22, AlignLeft, AlignTop); - notification_message(app->notification, &sequence_blink_green_100); - } else { - dialog_ex_set_header(dialog_ex, "Cannot Unmount SD Card", 64, 3, AlignCenter, AlignTop); - dialog_ex_set_text(dialog_ex, storage_error_get_desc(error), 3, 22, AlignLeft, AlignTop); - notification_message(app->notification, &sequence_blink_red_100); - } - dialog_ex_set_context(dialog_ex, app); dialog_ex_set_result_callback(dialog_ex, storage_settings_scene_unmounted_dialog_callback); diff --git a/applications/system/updater/util/update_task_worker_flasher.c b/applications/system/updater/util/update_task_worker_flasher.c index d6dc13e37..c56031992 100644 --- a/applications/system/updater/util/update_task_worker_flasher.c +++ b/applications/system/updater/util/update_task_worker_flasher.c @@ -11,7 +11,7 @@ #include #include -#define TAG "UpdWorkerRAM" +#define TAG "UpdWorkerRam" #define STM_DFU_VENDOR_ID 0x0483 #define STM_DFU_PRODUCT_ID 0xDF11 diff --git a/firmware/targets/f18/api_symbols.csv b/firmware/targets/f18/api_symbols.csv index a26db8823..52f9a4d90 100644 --- a/firmware/targets/f18/api_symbols.csv +++ b/firmware/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,36.0,, +Version,+,36.1,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -2002,6 +2002,7 @@ Function,+,storage_int_backup,FS_Error,"Storage*, const char*" Function,+,storage_int_restore,FS_Error,"Storage*, const char*, Storage_name_converter" Function,+,storage_sd_format,FS_Error,Storage* Function,+,storage_sd_info,FS_Error,"Storage*, SDInfo*" +Function,+,storage_sd_mount,FS_Error,Storage* Function,+,storage_sd_status,FS_Error,Storage* Function,+,storage_sd_unmount,FS_Error,Storage* Function,+,storage_simply_mkdir,_Bool,"Storage*, const char*" diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 6ad88d9b8..2222d1702 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,36.0,, +Version,+,36.1,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, @@ -2612,6 +2612,7 @@ Function,+,storage_int_backup,FS_Error,"Storage*, const char*" Function,+,storage_int_restore,FS_Error,"Storage*, const char*, Storage_name_converter" Function,+,storage_sd_format,FS_Error,Storage* Function,+,storage_sd_info,FS_Error,"Storage*, SDInfo*" +Function,+,storage_sd_mount,FS_Error,Storage* Function,+,storage_sd_status,FS_Error,Storage* Function,+,storage_sd_unmount,FS_Error,Storage* Function,+,storage_simply_mkdir,_Bool,"Storage*, const char*" diff --git a/firmware/targets/f7/furi_hal/furi_hal_i2c.c b/firmware/targets/f7/furi_hal/furi_hal_i2c.c index 6c17d6ade..bdfe0b0a3 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_i2c.c +++ b/firmware/targets/f7/furi_hal/furi_hal_i2c.c @@ -8,7 +8,7 @@ #include #include -#define TAG "FuriHalI2C" +#define TAG "FuriHalI2c" void furi_hal_i2c_init_early() { furi_hal_i2c_bus_power.callback(&furi_hal_i2c_bus_power, FuriHalI2cBusEventInit); diff --git a/lib/flipper_application/api_hashtable/api_hashtable.cpp b/lib/flipper_application/api_hashtable/api_hashtable.cpp index 6db5fb5fd..ef22ee9ad 100644 --- a/lib/flipper_application/api_hashtable/api_hashtable.cpp +++ b/lib/flipper_application/api_hashtable/api_hashtable.cpp @@ -3,7 +3,7 @@ #include #include -#define TAG "hashtable_api" +#define TAG "ApiHashtable" bool elf_resolve_from_hashtable( const ElfApiInterface* interface, diff --git a/lib/flipper_application/application_assets.c b/lib/flipper_application/application_assets.c index 083c3ca19..ec3fc22ee 100644 --- a/lib/flipper_application/application_assets.c +++ b/lib/flipper_application/application_assets.c @@ -17,7 +17,7 @@ #define BUFFER_SIZE 512 -#define TAG "fap_assets" +#define TAG "FapAssets" #pragma pack(push, 1) diff --git a/lib/flipper_application/elf/elf_file.c b/lib/flipper_application/elf/elf_file.c index bea7c1231..7ac4c655d 100644 --- a/lib/flipper_application/elf/elf_file.c +++ b/lib/flipper_application/elf/elf_file.c @@ -5,7 +5,7 @@ #include "elf_api_interface.h" #include "../api_hashtable/api_hashtable.h" -#define TAG "elf" +#define TAG "Elf" #define ELF_NAME_BUFFER_LEN 32 #define SECTION_OFFSET(e, n) ((e)->section_table + (n) * sizeof(Elf32_Shdr)) diff --git a/lib/flipper_application/plugins/plugin_manager.c b/lib/flipper_application/plugins/plugin_manager.c index 101471dc5..e2a7b83f4 100644 --- a/lib/flipper_application/plugins/plugin_manager.c +++ b/lib/flipper_application/plugins/plugin_manager.c @@ -9,7 +9,7 @@ #include -#define TAG "libmgr" +#define TAG "PluginManager" ARRAY_DEF(FlipperApplicationList, FlipperApplication*, M_PTR_OPLIST) #define M_OPL_FlipperApplicationList_t() ARRAY_OPLIST(FlipperApplicationList, M_PTR_OPLIST) diff --git a/lib/lfrfid/lfrfid_raw_file.c b/lib/lfrfid/lfrfid_raw_file.c index 27c6f2475..ca29770f1 100644 --- a/lib/lfrfid/lfrfid_raw_file.c +++ b/lib/lfrfid/lfrfid_raw_file.c @@ -6,7 +6,7 @@ #define LFRFID_RAW_FILE_MAGIC 0x4C464952 #define LFRFID_RAW_FILE_VERSION 1 -#define TAG "RFID RAW File" +#define TAG "LfRfidRawFile" typedef struct { uint32_t magic; diff --git a/lib/lfrfid/lfrfid_raw_worker.c b/lib/lfrfid/lfrfid_raw_worker.c index aa962a47d..344c2afa2 100644 --- a/lib/lfrfid/lfrfid_raw_worker.c +++ b/lib/lfrfid/lfrfid_raw_worker.c @@ -10,7 +10,7 @@ #define RFID_DATA_BUFFER_SIZE 2048 #define READ_DATA_BUFFER_COUNT 4 -#define TAG_EMULATE "RAW EMULATE" +#define TAG_EMULATE "RawEmulate" // emulate mode typedef struct { diff --git a/lib/lfrfid/lfrfid_worker_modes.c b/lib/lfrfid/lfrfid_worker_modes.c index 8a2667774..32e253259 100644 --- a/lib/lfrfid/lfrfid_worker_modes.c +++ b/lib/lfrfid/lfrfid_worker_modes.c @@ -7,7 +7,7 @@ #include "tools/varint_pair.h" #include "tools/bit_lib.h" -#define TAG "LFRFIDWorker" +#define TAG "LfRfidWorker" /** * if READ_DEBUG_GPIO is defined: diff --git a/lib/nfc/protocols/slix.c b/lib/nfc/protocols/slix.c index 68937d161..dbff2f218 100644 --- a/lib/nfc/protocols/slix.c +++ b/lib/nfc/protocols/slix.c @@ -7,7 +7,7 @@ #include "furi_hal_nfc.h" #include -#define TAG "SLIX" +#define TAG "Slix" ReturnCode slix2_read_nxp_sysinfo(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) { furi_assert(nfc_data); diff --git a/lib/subghz/devices/cc1101_int/cc1101_int_interconnect.c b/lib/subghz/devices/cc1101_int/cc1101_int_interconnect.c index 41a0609df..284c717fd 100644 --- a/lib/subghz/devices/cc1101_int/cc1101_int_interconnect.c +++ b/lib/subghz/devices/cc1101_int/cc1101_int_interconnect.c @@ -2,7 +2,7 @@ #include #include "../cc1101_configs.h" -#define TAG "SubGhzDeviceCC1101Int" +#define TAG "SubGhzDeviceCc1101Int" static bool subghz_device_cc1101_int_interconnect_is_frequency_valid(uint32_t frequency) { bool ret = furi_hal_subghz_is_frequency_valid(frequency); diff --git a/lib/subghz/protocols/alutech_at_4n.c b/lib/subghz/protocols/alutech_at_4n.c index e8bb87055..16c715f80 100644 --- a/lib/subghz/protocols/alutech_at_4n.c +++ b/lib/subghz/protocols/alutech_at_4n.c @@ -5,7 +5,7 @@ #include "../blocks/generic.h" #include "../blocks/math.h" -#define TAG "SubGhzProtocoAlutech_at_4n" +#define TAG "SubGhzProtocoAlutechAt4n" #define SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE 0xFFFFFFFF diff --git a/lib/subghz/protocols/bett.c b/lib/subghz/protocols/bett.c index de13472ac..7fce94448 100644 --- a/lib/subghz/protocols/bett.c +++ b/lib/subghz/protocols/bett.c @@ -7,7 +7,7 @@ #include "../blocks/math.h" // protocol BERNER / ELKA / TEDSEN / TELETASTER -#define TAG "SubGhzProtocolBETT" +#define TAG "SubGhzProtocolBett" #define DIP_P 0b11 //(+) #define DIP_O 0b10 //(0) diff --git a/lib/subghz/protocols/bin_raw.c b/lib/subghz/protocols/bin_raw.c index 9509280c2..03f4c5bd4 100644 --- a/lib/subghz/protocols/bin_raw.c +++ b/lib/subghz/protocols/bin_raw.c @@ -9,7 +9,7 @@ #include #include -#define TAG "SubGhzProtocolBinRAW" +#define TAG "SubGhzProtocolBinRaw" //change very carefully, RAM ends at the most inopportune moment #define BIN_RAW_BUF_RAW_SIZE 2048 diff --git a/lib/subghz/protocols/came.c b/lib/subghz/protocols/came.c index 14b2e0101..40ae05bad 100644 --- a/lib/subghz/protocols/came.c +++ b/lib/subghz/protocols/came.c @@ -12,7 +12,7 @@ * */ -#define TAG "SubGhzProtocolCAME" +#define TAG "SubGhzProtocolCame" #define CAME_12_COUNT_BIT 12 #define CAME_24_COUNT_BIT 24 #define PRASTEL_COUNT_BIT 25 diff --git a/lib/subghz/protocols/came_twee.c b/lib/subghz/protocols/came_twee.c index 6fe615813..1d79d2201 100644 --- a/lib/subghz/protocols/came_twee.c +++ b/lib/subghz/protocols/came_twee.c @@ -13,7 +13,7 @@ * */ -#define TAG "SubGhzProtocolCAME_Twee" +#define TAG "SubGhzProtocolCameTwee" #define DIP_PATTERN "%c%c%c%c%c%c%c%c%c%c" #define CNT_TO_DIP(dip) \ diff --git a/lib/subghz/protocols/chamberlain_code.c b/lib/subghz/protocols/chamberlain_code.c index be0877fb5..0dd0d2b0b 100644 --- a/lib/subghz/protocols/chamberlain_code.c +++ b/lib/subghz/protocols/chamberlain_code.c @@ -6,7 +6,7 @@ #include "../blocks/generic.h" #include "../blocks/math.h" -#define TAG "SubGhzProtocolChamb_Code" +#define TAG "SubGhzProtocolChambCode" #define CHAMBERLAIN_CODE_BIT_STOP 0b0001 #define CHAMBERLAIN_CODE_BIT_1 0b0011 diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index d9dd68408..cdee7cd9f 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -6,7 +6,7 @@ #include "../blocks/generic.h" #include "../blocks/math.h" -#define TAG "SubGhzProtocolFaacSHL" +#define TAG "SubGhzProtocolFaacShl" static const SubGhzBlockConst subghz_protocol_faac_slh_const = { .te_short = 255, diff --git a/lib/subghz/protocols/holtek_ht12x.c b/lib/subghz/protocols/holtek_ht12x.c index 831f824dd..302b78598 100644 --- a/lib/subghz/protocols/holtek_ht12x.c +++ b/lib/subghz/protocols/holtek_ht12x.c @@ -12,7 +12,7 @@ * */ -#define TAG "SubGhzProtocolHoltek_HT12X" +#define TAG "SubGhzProtocolHoltekHt12x" #define DIP_PATTERN "%c%c%c%c%c%c%c%c" #define CNT_TO_DIP(dip) \ diff --git a/lib/subghz/protocols/honeywell_wdb.c b/lib/subghz/protocols/honeywell_wdb.c index 7fd8d66d6..fcf282201 100644 --- a/lib/subghz/protocols/honeywell_wdb.c +++ b/lib/subghz/protocols/honeywell_wdb.c @@ -6,7 +6,7 @@ #include "../blocks/generic.h" #include "../blocks/math.h" -#define TAG "SubGhzProtocolHoneywellWDB" +#define TAG "SubGhzProtocolHoneywellWdb" /* * diff --git a/lib/subghz/protocols/hormann.c b/lib/subghz/protocols/hormann.c index 4c5c68cc4..fc490e9d1 100644 --- a/lib/subghz/protocols/hormann.c +++ b/lib/subghz/protocols/hormann.c @@ -6,7 +6,7 @@ #include "../blocks/generic.h" #include "../blocks/math.h" -#define TAG "SubGhzProtocolHormannHSM" +#define TAG "SubGhzProtocolHormannHsm" #define HORMANN_HSM_PATTERN 0xFF000000003 diff --git a/lib/subghz/protocols/ido.c b/lib/subghz/protocols/ido.c index 90c0fb0e3..e96e6566b 100644 --- a/lib/subghz/protocols/ido.c +++ b/lib/subghz/protocols/ido.c @@ -6,7 +6,7 @@ #include "../blocks/generic.h" #include "../blocks/math.h" -#define TAG "SubGhzProtocol_iDo_117/111" +#define TAG "SubGhzProtocolIdo117/111" static const SubGhzBlockConst subghz_protocol_ido_const = { .te_short = 450, diff --git a/lib/subghz/protocols/kia.c b/lib/subghz/protocols/kia.c index 1d134f7ba..9b63271b4 100644 --- a/lib/subghz/protocols/kia.c +++ b/lib/subghz/protocols/kia.c @@ -6,7 +6,7 @@ #include "../blocks/generic.h" #include "../blocks/math.h" -#define TAG "SubGhzProtocoKIA" +#define TAG "SubGhzProtocoKia" static const SubGhzBlockConst subghz_protocol_kia_const = { .te_short = 250, diff --git a/lib/subghz/protocols/kinggates_stylo_4k.c b/lib/subghz/protocols/kinggates_stylo_4k.c index cd027b99c..0b2a102c4 100644 --- a/lib/subghz/protocols/kinggates_stylo_4k.c +++ b/lib/subghz/protocols/kinggates_stylo_4k.c @@ -8,7 +8,7 @@ #include "../blocks/generic.h" #include "../blocks/math.h" -#define TAG "SubGhzProtocoKingGates_stylo_4k" +#define TAG "SubGhzProtocoKingGatesStylo4k" static const SubGhzBlockConst subghz_protocol_kinggates_stylo_4k_const = { .te_short = 400, diff --git a/lib/subghz/protocols/nice_flo.c b/lib/subghz/protocols/nice_flo.c index af81d9f90..f60e07fb8 100644 --- a/lib/subghz/protocols/nice_flo.c +++ b/lib/subghz/protocols/nice_flo.c @@ -5,7 +5,7 @@ #include "../blocks/generic.h" #include "../blocks/math.h" -#define TAG "SubGhzProtocolNiceFLO" +#define TAG "SubGhzProtocolNiceFlo" static const SubGhzBlockConst subghz_protocol_nice_flo_const = { .te_short = 700, diff --git a/lib/subghz/protocols/phoenix_v2.c b/lib/subghz/protocols/phoenix_v2.c index 4ed9766ef..2416a9d01 100644 --- a/lib/subghz/protocols/phoenix_v2.c +++ b/lib/subghz/protocols/phoenix_v2.c @@ -6,7 +6,7 @@ #include "../blocks/generic.h" #include "../blocks/math.h" -#define TAG "SubGhzProtocolPhoenix_V2" +#define TAG "SubGhzProtocolPhoenixV2" //transmission only static mode diff --git a/lib/subghz/protocols/raw.c b/lib/subghz/protocols/raw.c index 4a8ae1d5e..95dff3093 100644 --- a/lib/subghz/protocols/raw.c +++ b/lib/subghz/protocols/raw.c @@ -11,7 +11,7 @@ #include #include -#define TAG "SubGhzProtocolRAW" +#define TAG "SubGhzProtocolRaw" #define SUBGHZ_DOWNLOAD_MAX_SIZE 512 static const SubGhzBlockConst subghz_protocol_raw_const = { diff --git a/lib/subghz/protocols/secplus_v1.c b/lib/subghz/protocols/secplus_v1.c index 783351c6b..644b2fba9 100644 --- a/lib/subghz/protocols/secplus_v1.c +++ b/lib/subghz/protocols/secplus_v1.c @@ -11,7 +11,7 @@ * https://github.com/merbanan/rtl_433/blob/master/src/devices/secplus_v1.c */ -#define TAG "SubGhzProtocoSecPlus_v1" +#define TAG "SubGhzProtocoSecPlusV1" #define SECPLUS_V1_BIT_ERR -1 //0b0000 #define SECPLUS_V1_BIT_0 0 //0b0001 diff --git a/lib/subghz/protocols/secplus_v2.c b/lib/subghz/protocols/secplus_v2.c index 12d2fac74..374c407b0 100644 --- a/lib/subghz/protocols/secplus_v2.c +++ b/lib/subghz/protocols/secplus_v2.c @@ -13,7 +13,7 @@ * https://github.com/merbanan/rtl_433/blob/master/src/devices/secplus_v2.c */ -#define TAG "SubGhzProtocoSecPlus_v2" +#define TAG "SubGhzProtocoSecPlusV2" #define SECPLUS_V2_HEADER 0x3C0000000000 #define SECPLUS_V2_HEADER_MASK 0xFFFF3C0000000000 diff --git a/lib/subghz/protocols/smc5326.c b/lib/subghz/protocols/smc5326.c index bfb36b76a..0b9755b8c 100644 --- a/lib/subghz/protocols/smc5326.c +++ b/lib/subghz/protocols/smc5326.c @@ -12,7 +12,7 @@ * */ -#define TAG "SubGhzProtocolSMC5326" +#define TAG "SubGhzProtocolSmc5326" #define DIP_P 0b11 //(+) #define DIP_O 0b10 //(0) From 2b383ebcee19199988b2c26fed10906d3f3bdd47 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 4 Sep 2023 21:19:35 +0300 Subject: [PATCH 41/59] Keyboard ok to toggle select all in cursor mode by Willy-JL --- applications/services/gui/modules/text_input.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/applications/services/gui/modules/text_input.c b/applications/services/gui/modules/text_input.c index 446730e95..ab5bc5b41 100644 --- a/applications/services/gui/modules/text_input.c +++ b/applications/services/gui/modules/text_input.c @@ -325,6 +325,7 @@ static void text_input_handle_down(TextInput* text_input, TextInputModel* model) static void text_input_handle_left(TextInput* text_input, TextInputModel* model) { UNUSED(text_input); if(model->cursor_select) { + model->clear_default_text = false; if(model->cursor_pos > 0) { model->cursor_pos = CLAMP(model->cursor_pos - 1, strlen(model->text_buffer), 0u); } @@ -338,6 +339,7 @@ static void text_input_handle_left(TextInput* text_input, TextInputModel* model) static void text_input_handle_right(TextInput* text_input, TextInputModel* model) { UNUSED(text_input); if(model->cursor_select) { + model->clear_default_text = false; model->cursor_pos = CLAMP(model->cursor_pos + 1, strlen(model->text_buffer), 0u); } else if(model->selected_column < get_row_size(model->selected_row) - 1) { model->selected_column++; @@ -347,7 +349,10 @@ static void text_input_handle_right(TextInput* text_input, TextInputModel* model } static void text_input_handle_ok(TextInput* text_input, TextInputModel* model, InputType type) { - if(model->cursor_select) return; + if(model->cursor_select) { + model->clear_default_text = !model->clear_default_text; + return; + } bool shift = type == InputTypeLong; bool repeat = type == InputTypeRepeat; char selected = get_selected_char(model); From 99eb10d6e70100d9a2939ec653cbb708df31578b Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 4 Sep 2023 23:11:40 +0300 Subject: [PATCH 42/59] fix module p1 --- applications/main/subghz_remote/.gitignore | 4 - applications/main/subghz_remote/LICENSE | 21 - .../main/subghz_remote/application.fam | 43 -- .../subghz_remote/catalog/docs/Changelog.md | 25 - .../main/subghz_remote/catalog/docs/Readme.md | 24 - .../catalog/screenshots/Editor_main.png | Bin 2361 -> 0 bytes .../catalog/screenshots/Editor_submenu.png | Bin 1381 -> 0 bytes .../catalog/screenshots/Remote_idle.png | Bin 2026 -> 0 bytes .../catalog/screenshots/Remote_send.png | Bin 1730 -> 0 bytes .../helpers/subrem_custom_event.h | 58 -- .../subghz_remote/helpers/subrem_presets.c | 183 ----- .../subghz_remote/helpers/subrem_presets.h | 39 - .../main/subghz_remote/helpers/subrem_types.h | 48 -- .../main/subghz_remote/helpers/txrx/Readme.md | 4 - .../subghz_remote/helpers/txrx/subghz_txrx.c | 674 ------------------ .../subghz_remote/helpers/txrx/subghz_txrx.h | 375 ---------- .../helpers/txrx/subghz_txrx_i.h | 31 - applications/main/subghz_remote/icon.png | Bin 5000 -> 0 bytes .../subghz_remote/icons/DolphinNice_96x59.png | Bin 2459 -> 0 bytes .../icons/remote_scene/ButtonDown_7x4.png | Bin 102 -> 0 bytes .../icons/remote_scene/ButtonLeft_4x7.png | Bin 1415 -> 0 bytes .../icons/remote_scene/ButtonRight_4x7.png | Bin 1839 -> 0 bytes .../icons/remote_scene/ButtonUp_7x4.png | Bin 102 -> 0 bytes .../icons/remote_scene/Ok_btn_9x9.png | Bin 3605 -> 0 bytes .../icons/remote_scene/Pin_arrow_up_7x9.png | Bin 3603 -> 0 bytes .../icons/remote_scene/Pin_cell_13x13.png | Bin 3593 -> 0 bytes .../icons/remote_scene/Pin_star_7x7.png | Bin 3600 -> 0 bytes .../icons/remote_scene/back_10px.png | Bin 154 -> 0 bytes .../main/subghz_remote/icons/sub1_10px.png | Bin 299 -> 0 bytes .../main/subghz_remote/icons/subrem_10px.png | Bin 5000 -> 0 bytes .../main/subghz_remote/scenes/subrem_scene.c | 30 - .../main/subghz_remote/scenes/subrem_scene.h | 29 - .../scenes/subrem_scene_config.h | 12 - .../scenes/subrem_scene_edit_label.c | 133 ---- .../scenes/subrem_scene_edit_menu.c | 123 ---- .../scenes/subrem_scene_edit_preview.c | 74 -- .../scenes/subrem_scene_edit_submenu.c | 54 -- .../scenes/subrem_scene_enter_new_name.c | 70 -- .../scenes/subrem_scene_fw_warning.c | 129 ---- .../scenes/subrem_scene_open_map_file.c | 29 - .../scenes/subrem_scene_open_sub_file.c | 119 ---- .../scenes/subrem_scene_remote.c | 118 --- .../subghz_remote/scenes/subrem_scene_start.c | 100 --- .../main/subghz_remote/subghz_remote_app.c | 218 ------ .../main/subghz_remote/subghz_remote_app_i.c | 317 -------- .../main/subghz_remote/subghz_remote_app_i.h | 68 -- .../main/subghz_remote/views/edit_menu.c | 290 -------- .../main/subghz_remote/views/edit_menu.h | 29 - .../main/subghz_remote/views/remote.c | 307 -------- .../main/subghz_remote/views/remote.h | 38 - 50 files changed, 3816 deletions(-) delete mode 100644 applications/main/subghz_remote/.gitignore delete mode 100644 applications/main/subghz_remote/LICENSE delete mode 100644 applications/main/subghz_remote/application.fam delete mode 100644 applications/main/subghz_remote/catalog/docs/Changelog.md delete mode 100644 applications/main/subghz_remote/catalog/docs/Readme.md delete mode 100644 applications/main/subghz_remote/catalog/screenshots/Editor_main.png delete mode 100644 applications/main/subghz_remote/catalog/screenshots/Editor_submenu.png delete mode 100644 applications/main/subghz_remote/catalog/screenshots/Remote_idle.png delete mode 100644 applications/main/subghz_remote/catalog/screenshots/Remote_send.png delete mode 100644 applications/main/subghz_remote/helpers/subrem_custom_event.h delete mode 100644 applications/main/subghz_remote/helpers/subrem_presets.c delete mode 100644 applications/main/subghz_remote/helpers/subrem_presets.h delete mode 100644 applications/main/subghz_remote/helpers/subrem_types.h delete mode 100644 applications/main/subghz_remote/helpers/txrx/Readme.md delete mode 100644 applications/main/subghz_remote/helpers/txrx/subghz_txrx.c delete mode 100644 applications/main/subghz_remote/helpers/txrx/subghz_txrx.h delete mode 100644 applications/main/subghz_remote/helpers/txrx/subghz_txrx_i.h delete mode 100644 applications/main/subghz_remote/icon.png delete mode 100644 applications/main/subghz_remote/icons/DolphinNice_96x59.png delete mode 100644 applications/main/subghz_remote/icons/remote_scene/ButtonDown_7x4.png delete mode 100644 applications/main/subghz_remote/icons/remote_scene/ButtonLeft_4x7.png delete mode 100644 applications/main/subghz_remote/icons/remote_scene/ButtonRight_4x7.png delete mode 100644 applications/main/subghz_remote/icons/remote_scene/ButtonUp_7x4.png delete mode 100644 applications/main/subghz_remote/icons/remote_scene/Ok_btn_9x9.png delete mode 100644 applications/main/subghz_remote/icons/remote_scene/Pin_arrow_up_7x9.png delete mode 100644 applications/main/subghz_remote/icons/remote_scene/Pin_cell_13x13.png delete mode 100644 applications/main/subghz_remote/icons/remote_scene/Pin_star_7x7.png delete mode 100644 applications/main/subghz_remote/icons/remote_scene/back_10px.png delete mode 100644 applications/main/subghz_remote/icons/sub1_10px.png delete mode 100644 applications/main/subghz_remote/icons/subrem_10px.png delete mode 100644 applications/main/subghz_remote/scenes/subrem_scene.c delete mode 100644 applications/main/subghz_remote/scenes/subrem_scene.h delete mode 100644 applications/main/subghz_remote/scenes/subrem_scene_config.h delete mode 100644 applications/main/subghz_remote/scenes/subrem_scene_edit_label.c delete mode 100644 applications/main/subghz_remote/scenes/subrem_scene_edit_menu.c delete mode 100644 applications/main/subghz_remote/scenes/subrem_scene_edit_preview.c delete mode 100644 applications/main/subghz_remote/scenes/subrem_scene_edit_submenu.c delete mode 100644 applications/main/subghz_remote/scenes/subrem_scene_enter_new_name.c delete mode 100644 applications/main/subghz_remote/scenes/subrem_scene_fw_warning.c delete mode 100644 applications/main/subghz_remote/scenes/subrem_scene_open_map_file.c delete mode 100644 applications/main/subghz_remote/scenes/subrem_scene_open_sub_file.c delete mode 100644 applications/main/subghz_remote/scenes/subrem_scene_remote.c delete mode 100644 applications/main/subghz_remote/scenes/subrem_scene_start.c delete mode 100644 applications/main/subghz_remote/subghz_remote_app.c delete mode 100644 applications/main/subghz_remote/subghz_remote_app_i.c delete mode 100644 applications/main/subghz_remote/subghz_remote_app_i.h delete mode 100644 applications/main/subghz_remote/views/edit_menu.c delete mode 100644 applications/main/subghz_remote/views/edit_menu.h delete mode 100644 applications/main/subghz_remote/views/remote.c delete mode 100644 applications/main/subghz_remote/views/remote.h diff --git a/applications/main/subghz_remote/.gitignore b/applications/main/subghz_remote/.gitignore deleted file mode 100644 index e2a15a10a..000000000 --- a/applications/main/subghz_remote/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -dist/* -.vscode -.clang-format -.editorconfig \ No newline at end of file diff --git a/applications/main/subghz_remote/LICENSE b/applications/main/subghz_remote/LICENSE deleted file mode 100644 index 6f55e3b0d..000000000 --- a/applications/main/subghz_remote/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 DarkFlippers @gid9798 @xMasterX - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/applications/main/subghz_remote/application.fam b/applications/main/subghz_remote/application.fam deleted file mode 100644 index 34fb390ab..000000000 --- a/applications/main/subghz_remote/application.fam +++ /dev/null @@ -1,43 +0,0 @@ -# App( -# appid="subghz_remote_ofw", -# name="Sub-GHz Remote", -# apptype=FlipperAppType.EXTERNAL, -# entry_point="subghz_remote_app", -# requires=[ -# "gui", -# "dialogs", -# ], -# stack_size=2 * 1024, -# targets=["f7"], -# fap_icon="icon.png", -# fap_author="gid9798 xMasterX", -# fap_description="SubGhz Remote, uses up to 5 .sub files", -# fap_category="Sub-GHz", -# fap_icon_assets="icons", -# fap_icon_assets_symbol="subghz_remote", -# fap_version="1.2", -# fap_weburl="https://github.com/DarkFlippers/SubGHz_Remote", -# ) - -App( - appid="subghz_remote", - name="Sub-GHz Remote", - apptype=FlipperAppType.MENUEXTERNAL, - entry_point="subghz_remote_app", - icon="A_SubGHzRemote_14", - order=11, - requires=[ - "gui", - "dialogs", - ], - stack_size=2 * 1024, - targets=["f7"], - fap_icon="icon.png", - fap_author="gid9798 xMasterX", - fap_description="SubGhz Remote, uses up to 5 .sub files", - fap_category="Sub-GHz", - fap_icon_assets="icons", - fap_icon_assets_symbol="subghz_remote", - fap_version="1.2", - fap_weburl="https://github.com/DarkFlippers/SubGHz_Remote", -) diff --git a/applications/main/subghz_remote/catalog/docs/Changelog.md b/applications/main/subghz_remote/catalog/docs/Changelog.md deleted file mode 100644 index 31ed245e8..000000000 --- a/applications/main/subghz_remote/catalog/docs/Changelog.md +++ /dev/null @@ -1,25 +0,0 @@ -## v1.2 -- **Official FirmWare Support** -- Add warning screen on CustomFW - - The .sub file format may differ from the official one and may be broken - -## v1.1 -- **Was combined with a configuration plugin** - - Editing/Creating map file -- Support for starting arguments - -## v1.0 - -**Initial implementation:** -- Transmission -- GUI -- All .sub files for which transfer is available are supported -- Signal types: - - Static - - Dynamic - - RAW - - BinRAW - -*Custom modulations are not supported yet* - -**Map File Format** - FlipperFormat .txt file \ No newline at end of file diff --git a/applications/main/subghz_remote/catalog/docs/Readme.md b/applications/main/subghz_remote/catalog/docs/Readme.md deleted file mode 100644 index 1da170e19..000000000 --- a/applications/main/subghz_remote/catalog/docs/Readme.md +++ /dev/null @@ -1,24 +0,0 @@ -With this application, you can combine up to 5 .sub files into one remote, and use flipper as a remote with multiple buttons. -## What is "Map" Files? -"Map" is short for mapping -A Map Files is a .txt files that the application uses to store information about remotes -# How to use -## First screen -After launching the application, you will see the MAP file selection screen (file browser). -- Select map file or press "back" to go Main menu -## Main menu -- Open map file - switching to remote - - Select map file - - On remote screen, use the navigation buttons(D-pad) to send a signal -- Edit Map File - map file editor - - Select map file - - Up/Down - slot nafigation - - Ok - edit menu - - Left - preview/save -- New Map File - Creating a new map file - - Enter a name - - The rest is similar to map file editor -# About map file -Map file - FlipperFormat .txt file. - -Stores custom names, and paths to used .sub files. \ No newline at end of file diff --git a/applications/main/subghz_remote/catalog/screenshots/Editor_main.png b/applications/main/subghz_remote/catalog/screenshots/Editor_main.png deleted file mode 100644 index 9498c94514411bd81fd4f7c474bb3286b0ec6c8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2361 zcma)8YgAL&6+Rf>3iPFph~TuNj8GOz1PEg$Z$g@kajmOse)Pv(=bn4d-uv78 zeBVCjk4Xu!o?Csk0suVYPR4u+z&huv2iWWyPQA)J4 z*2cyBCZ(uxNpYs;8_`cU^e*-J4XE|+mtt50D~v1o)lvHx@dqcA8y4G`YG|cvT`vX+Dw5WLeSdLUh6y&V+^H|zVB0mHfeX618_POENH9nP zEaPO{*V|vOad{VHAu6ud7caBd8j`jtzx5BT_W)Oa2Egt0;G+-8Am%+;H*vW+o6pzz zwtSIXQa)VT@gi~viFl1|i!f6q#hS&?RemwUR!T0$=mokeV1Lg zG9Q%QueUE-(DWjC?OJKuUeI;YS(_hzj!)#M>P#c$f%FXGq|jT4s5szC$r(t)d+2un z9F@YV@QK7bCsjy)f?602C=lF!NL7t>+L_ZG`0piYtS#m{7)}l>a1Gz1loWia64S{b zo4RC}Z2G4AT5}Mr`U1hme6nxL4kz1EG?prXUeaR2kjWbzYP>cKn0wxRH zl!#Nww4v6;|8U3>$||Wvp7X%IlOGD(o@6o*j<+{m<|aa#&hrTh3T{k_k_OF`g;=)Z z#Q`wTVP_FZ?Y7iHR))7ZwGw@kF!O5r*LC>?^WSsZTRK)}WuaSXcP^ zYTDb=j!;%*#-op6jId`Q*dhj`_ET0p z$mr|jl4&hd9mT8DDti{4PpqM7bVQ7ps~0h&MuO*7#7v@BAPhZwmI8PNfvlu5Xc^_l zVHZN8O6oac2xCM=mSstE8-1n~MwE};!L--{3bWJ=7SGZ@!DK;d+m%!pyf}_RU^p1e z6N`OoL8l}!aB7BjufaCW8P%HNVI%NCyh4P&`O%vKg}GINLr zqTwnWkb^Xn>c+F5H~$@qqO1m(;_gi*=Mj6ZSJ}0(CvItx&^T#ETBi$Y`N+wG!4g9 zeJ5_FOy3~Fcyr2$SNjFZFh5<3yq}zi{l{@8wIv^8H8IIlF1lsS4}w?Xl^PHlxgoVR z$@Ep`+-05xV%yS1^WsLIJ_3N9B%8X@d2F0A<9JWou!>147tYOG zQhG`6u9)8O3>k48hzrs1e0_g-y7^AoPqW$ms7ci6|t7+{z!Qr>Pb-hk2S~`)Y3ZrWreeorPk<RK$`+_f81*v|;P)gVI_ITO@%C3y?@)2C zM%M`=>iv!2vwEG@1JyGNL;7DIXQzdsG#DU+*^z&?fm6gd*b^Ea+4q)X(MRf=_okM` z)t+x{CY}sbx&t$#>MJZtaXp{5UVbSOOz8W9K*tuJV?bGd}ZMxWEHBjMdVzW^cI zJPhwFB(7Ul>CxdW280R^-zFoJnIW@dsegeV~!F%-$9`0y0`B&p#X@ zGITtF-%3`Cu_#l341Xe*L`Q}tD6Mq1`9hT8ng2l4rC)&7U%A_2c0oi%*k01899bM1 no&i5z-OgQ?jUSQo+BW2_eUVyER*ds51mZqUh-p2R^ZEY(w3puR diff --git a/applications/main/subghz_remote/catalog/screenshots/Editor_submenu.png b/applications/main/subghz_remote/catalog/screenshots/Editor_submenu.png deleted file mode 100644 index f5f7cd8495aef5c0e33c4594679670b40eff387e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1381 zcmeAS@N?(olHy`uVBq!ia0y~yU;;8388|?c*QZDWAjMhW5n0T@z;^_M8K-LVNi#68 zihH^^hE&XXd)F~?>BV~whRn*stgQ)Obi0}sIR}idq0z@wEKGRz2XhI?BDm!*V%o(r+mD2`R;QM zIp@n-Oy^`!@M2(C#KNHPYD+akba||DS*}#VJS5>s)ePx3cSjp+mN)qPt9;ha9%E}> zQ?E0<@ts0-+y?OuFCjdAIS$x=dm8yqkR89 z!7*JXFkPiF#$4>XvNsH)umZC8pD80NiS^L)unh(AHzZF|pL@#*t-Mr8j(gMmWo zRq3_*FMprE*WdsB{CfF#yKCR}&i`BUY;Se{?(1hN zNyNJM%>D@opX_=fcOdfHzq^0W+`oQ)&%dnjH%dF!GrUPfRdHtPZ{_o^ZdT_%=z9KE z=4X$4U+Gcfz6LdWH9KOgrq?x+5j8;0&I*ZD3nlndASeaTab44i_ek}WvJ~WOZA1ZpN$h9|dfo&E8id+&SS`};l5^ZPyb{Utak zV1e}))&PJ7+XDS|17KmEBEY=aVf!f2%{*Ae1`??N*gl?p5Lqs^O94P}w)t%$Byxtj zHeKjgZ*SRD*Vp@oh4pK^ti4$}>|gMC%>cqTZCo=ncwyy2k82SbD^lf>6w?F>(33lp zEI{WL08TFi;KnDwcO?SYZ~y;ga<}dwe#Urv%qY9IRa1*SO3owpQZMXDk#VBl7zDcR zR*7~sU zOWeb2NX<3&{)Al366_&4jjI0(4BN~_Yi&gyX>cEs*&WH}EpMTcaR+t_ql+?M3-5(f z`_R?f_OTWpO5*Q@GPEH>-7#6t6YZ(0jIm}Yw=xgqrV<~U25d_DRK{M!f86h6I#rRi zx{9L35nUmX!t*0<%P%cDP{FXdTibH>wX2JGzCbL880yw}8FAcr^kJJ<;n3?=Attue zMU#WiazBmB2Vk?+oG1$O99p*=mm=y((&-jmbRo?o?9!iOV|GJm*2*lD?G>f&@?1Bm z_qvUk{O|+SSE}YMdS4{t0D_>wX-XJsp{LYawQ=O4+KbP7W*T#6J(d3CQ8+${-J$hP z9-)I`tGT+)9#J%fC1f*;W_2_rQdkK~%areA{IhUiq{`ZRO08oBK!O#NJDi)4Y20n) z#SZrAdmxCsX;5IGJ+e+VM7lz_R%@&(8KP@0_%ekcA+(nn&0_El>PS<9nkK<2x69V= z8suxU9HRP*$(hXN+9g|pN;@=EId@q|jtyXb`mT<5MycQ^uaY)HsIk}Iv;gyFkIbsc z0Fo#!gY%)jEx~q?(L-m?d%iy0unHeHWXmSPBs!6yB@&8iy#FCW_5;kpsj84}YTZ}p z9f3O}4b^d^bwZyJPO1tj6+wU+eoQwJr4IEQ`m;156(=MeAG-je9HR#$ZKZcu9Cuf_ z-VyCG-nXj9653ai<`1lzW-l^asW>UhE%~bLvlJ8Dt(BPJ6Vq(2HovidNKy3E`i&~}U(Rm|9#tqiyD9$W2S^X8^!TF?WBz(1g< zWTpk5t1VLVCm+)l7_LX`dg#1TiKy(LyNVTUX$C4!EN0jiNl9_Gcloypblnv^%W*vP z@oEF;Zcw7q>nHS_M@noTu{T&$LzH)GiMZNAF-<1~5peU|FbmHt$-VE;bV7j)z6C+* zb7D`ZBMJ<~$U%S0_xI5Q2Dqyb2FR58ydp_8*{r5~$GU$S*k zKpX&p3D=m=^cB}P1mK%7_bGPa?2Aw)0u|3zl6<|TPePbznkcy}4%rB69yVy@Q)=*) zx`+7m1SciwSYt?bE0j6rtXUfz5)8oQZ*Z!rBYA7@sXLgJo(m4a- zB=VO%Jvs6{_<&MD8xp)c25I%Lqvo#JkCr-t@n=W z%NHlYqIcj>Za+RrQsZhXck7lVWY@|Mu#=!lw>V6n;ygRRZlcWdyd>`D40dLD8lLDlK9vh%Q2fmG1#zw5H(1bYP*M!_91F zS^rG18|`(HI1r&QEfg5t%~--B9~Jp1U!@QtlwosarPLNKtT@KKH7?nYoAk>(CcQa z0(FxC%gUAkAiV~_S8o8o^#kvo0f4g`DBmZ5*WLr*wm&%W-S$Uotn=!x=yNv$AqLu@ zMYZpFq2!QiYWZ!bJ-!}0>KO|HGbucQI7#EinKQM7?Do)O9nckhPg{q*kF8tn^qbdQ z4vzlQeN~MHwW0P1f`PFe_6{G^(uP7Rrc#!2g4p*3ldK-1bkxR-bhsO9oAwKGJL6Na ze1ip`!Bxf9yBZOyscbmfxFBCo;u3ZWaTbzFQmIRctmP4j7+SH+)(=D_A!1_#F6*O2 z!*3OAdTUSg{X0EEM9!a77tpE7BBn6n7QJadou^W80(LMNK6@$rRwB0l7o%4KIPBWo z{3DuYei&PD5$)8O6|Oll`|N)@%gQNvl3X`;z!)o=ziBO3t=q&rs5ISD#)q^aN=MCQ zH0GggD$S?9X8RudqCj@n9P?D9nIc2un>M3RP;yBW%F>!Jq{&}U2meAQdQAlIOtRWXx)&BwICC%JzbXYVy$&Nvrknzlf@CcAODe&V-;xkRx(_aE zR4fG$VpP5$|3C)5rZBjw{H0J@La~|*rmAtCIdmXXDA&$o@%1q;YA4~+PI+-?0k43^ zR`La$(@RNr>y<{YvL}x_iwUq3r&`ZZ;@B$cT3J?2P=U{d6B~uYI;i|W9zV+gluI~3 zO2;x!RG`3h+wXr26)#*u!<&!FSP%;#f|>7ejqZx?+F-F{2niV2xZ-qNmE5U;vpgHX z{1X;J80B>z$GN|Hh;6q=mTQ668$Q^@n_Q-LXth!d4 z7B%O{f;tk!D{8eO7tMeVOSJk45#=t%Eic;X_9Okpox&vR`ZrD?&(-d%Fa3OaTm-52 z00&Q(BN>RpLE)t*dy!?JYc0o>k~*-q-kPu*W^h;mTxPYEQRI>%``nOFHY D{V;BS diff --git a/applications/main/subghz_remote/helpers/subrem_custom_event.h b/applications/main/subghz_remote/helpers/subrem_custom_event.h deleted file mode 100644 index 810df6a89..000000000 --- a/applications/main/subghz_remote/helpers/subrem_custom_event.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -typedef enum { - SubRemEditMenuStateUP = 0, - SubRemEditMenuStateDOWN, - SubRemEditMenuStateLEFT, - SubRemEditMenuStateRIGHT, - SubRemEditMenuStateOK, -} SubRemEditMenuState; - -typedef enum { - // StartSubmenuIndex - SubmenuIndexSubRemOpenMapFile = 0, - SubmenuIndexSubRemEditMapFile, - SubmenuIndexSubRemNewMapFile, -#if FURI_DEBUG - SubmenuIndexSubRemRemoteView, -#endif - // SubmenuIndexSubRemAbout, - - // EditSubmenuIndex - EditSubmenuIndexEditLabel, - EditSubmenuIndexEditFile, - - // SubRemCustomEvent - SubRemCustomEventViewRemoteStartUP = 100, - SubRemCustomEventViewRemoteStartDOWN, - SubRemCustomEventViewRemoteStartLEFT, - SubRemCustomEventViewRemoteStartRIGHT, - SubRemCustomEventViewRemoteStartOK, - SubRemCustomEventViewRemoteBack, - SubRemCustomEventViewRemoteStop, - SubRemCustomEventViewRemoteForcedStop, - - SubRemCustomEventViewEditMenuBack, - SubRemCustomEventViewEditMenuUP, - SubRemCustomEventViewEditMenuDOWN, - SubRemCustomEventViewEditMenuEdit, - SubRemCustomEventViewEditMenuSave, - - SubRemCustomEventSceneEditsubmenu, - SubRemCustomEventSceneEditLabelInputDone, - SubRemCustomEventSceneEditLabelWidgetAcces, - SubRemCustomEventSceneEditLabelWidgetBack, - - SubRemCustomEventSceneEditOpenSubErrorPopup, - - SubRemCustomEventSceneEditPreviewSaved, - - SubRemCustomEventSceneNewName, - -#ifdef FW_ORIGIN_Official - SubRemCustomEventSceneFwWarningExit, - SubRemCustomEventSceneFwWarningNext, - SubRemCustomEventSceneFwWarningContinue, -#endif - -} SubRemCustomEvent; \ No newline at end of file diff --git a/applications/main/subghz_remote/helpers/subrem_presets.c b/applications/main/subghz_remote/helpers/subrem_presets.c deleted file mode 100644 index bca888b96..000000000 --- a/applications/main/subghz_remote/helpers/subrem_presets.c +++ /dev/null @@ -1,183 +0,0 @@ -#include "subrem_presets.h" - -#define TAG "SubRemPresets" - -SubRemSubFilePreset* subrem_sub_file_preset_alloc() { - SubRemSubFilePreset* sub_preset = malloc(sizeof(SubRemSubFilePreset)); - - sub_preset->fff_data = flipper_format_string_alloc(); - sub_preset->file_path = furi_string_alloc(); - sub_preset->protocaol_name = furi_string_alloc(); - sub_preset->label = furi_string_alloc(); - - sub_preset->freq_preset.name = furi_string_alloc(); - - sub_preset->type = SubGhzProtocolTypeUnknown; - sub_preset->load_state = SubRemLoadSubStateNotSet; - - return sub_preset; -} - -void subrem_sub_file_preset_free(SubRemSubFilePreset* sub_preset) { - furi_assert(sub_preset); - - furi_string_free(sub_preset->label); - furi_string_free(sub_preset->protocaol_name); - furi_string_free(sub_preset->file_path); - flipper_format_free(sub_preset->fff_data); - - furi_string_free(sub_preset->freq_preset.name); - - free(sub_preset); -} - -void subrem_sub_file_preset_reset(SubRemSubFilePreset* sub_preset) { - furi_assert(sub_preset); - - furi_string_set_str(sub_preset->label, ""); - furi_string_reset(sub_preset->protocaol_name); - furi_string_reset(sub_preset->file_path); - - Stream* fff_data_stream = flipper_format_get_raw_stream(sub_preset->fff_data); - stream_clean(fff_data_stream); - - sub_preset->type = SubGhzProtocolTypeUnknown; - sub_preset->load_state = SubRemLoadSubStateNotSet; -} - -SubRemLoadSubState subrem_sub_preset_load( - SubRemSubFilePreset* sub_preset, - SubGhzTxRx* txrx, - FlipperFormat* fff_data_file) { - furi_assert(sub_preset); - furi_assert(txrx); - furi_assert(fff_data_file); - - Stream* fff_data_stream = flipper_format_get_raw_stream(sub_preset->fff_data); - - SubRemLoadSubState ret; - FuriString* temp_str = furi_string_alloc(); - uint32_t temp_data32; - uint32_t repeat = 200; - - ret = SubRemLoadSubStateError; - - do { - stream_clean(fff_data_stream); - if(!flipper_format_read_header(fff_data_file, temp_str, &temp_data32)) { - FURI_LOG_E(TAG, "Missing or incorrect header"); - break; - } - - if(((!strcmp(furi_string_get_cstr(temp_str), SUBGHZ_KEY_FILE_TYPE)) || - (!strcmp(furi_string_get_cstr(temp_str), SUBGHZ_RAW_FILE_TYPE))) && - temp_data32 == SUBGHZ_KEY_FILE_VERSION) { - } else { - FURI_LOG_E(TAG, "Type or version mismatch"); - break; - } - - SubGhzSetting* setting = subghz_txrx_get_setting(txrx); - - //Load frequency or using default from settings - ret = SubRemLoadSubStateErrorFreq; - if(!flipper_format_read_uint32(fff_data_file, "Frequency", &temp_data32, 1)) { - FURI_LOG_W(TAG, "Cannot read frequency. Set default frequency"); - sub_preset->freq_preset.frequency = subghz_setting_get_default_frequency(setting); - } else if(!subghz_txrx_radio_device_is_frequency_valid(txrx, temp_data32)) { - FURI_LOG_E(TAG, "Frequency not supported on chosen radio module"); - break; - } - sub_preset->freq_preset.frequency = temp_data32; - - //Load preset - ret = SubRemLoadSubStateErrorMod; - if(!flipper_format_read_string(fff_data_file, "Preset", temp_str)) { - FURI_LOG_E(TAG, "Missing Preset"); - break; - } - - furi_string_set_str( - temp_str, subghz_txrx_get_preset_name(txrx, furi_string_get_cstr(temp_str))); - if(!strcmp(furi_string_get_cstr(temp_str), "")) { - break; - } - - if(!strcmp(furi_string_get_cstr(temp_str), "CUSTOM")) { - FURI_LOG_E(TAG, "CUSTOM preset is not supported"); - break; - // TODO Custom preset loading logic if need - // sub_preset->freq_preset.preset_index = - // subghz_setting_get_inx_preset_by_name(setting, furi_string_get_cstr(temp_str)); - } - - furi_string_set(sub_preset->freq_preset.name, temp_str); - - // Load protocol - ret = SubRemLoadSubStateErrorProtocol; - if(!flipper_format_read_string(fff_data_file, "Protocol", temp_str)) { - FURI_LOG_E(TAG, "Missing Protocol"); - break; - } - - FlipperFormat* fff_data = sub_preset->fff_data; - if(!strcmp(furi_string_get_cstr(temp_str), "RAW")) { - //if RAW - subghz_protocol_raw_gen_fff_data( - fff_data, - furi_string_get_cstr(sub_preset->file_path), - subghz_txrx_radio_device_get_name(txrx)); - } else { - stream_copy_full( - flipper_format_get_raw_stream(fff_data_file), - flipper_format_get_raw_stream(fff_data)); - } - - if(subghz_txrx_load_decoder_by_name_protocol(txrx, furi_string_get_cstr(temp_str))) { - SubGhzProtocolStatus status = - subghz_protocol_decoder_base_deserialize(subghz_txrx_get_decoder(txrx), fff_data); - if(status != SubGhzProtocolStatusOk) { - break; - } - } else { - FURI_LOG_E(TAG, "Protocol not found"); - break; - } - - const SubGhzProtocol* protocol = subghz_txrx_get_decoder(txrx)->protocol; - - if(protocol->flag & SubGhzProtocolFlag_Send) { - if((protocol->type == SubGhzProtocolTypeStatic) || - (protocol->type == SubGhzProtocolTypeDynamic) || -#ifndef FW_ORIGIN_Official - (protocol->type == SubGhzProtocolTypeBinRAW) || -#endif - (protocol->type == SubGhzProtocolTypeRAW)) { - sub_preset->type = protocol->type; - } else { - FURI_LOG_E(TAG, "Unsuported Protocol"); - break; - } - - furi_string_set(sub_preset->protocaol_name, temp_str); - } else { - FURI_LOG_E(TAG, "Protocol does not support transmission"); - break; - } - - if(!flipper_format_insert_or_update_uint32(fff_data, "Repeat", &repeat, 1)) { - FURI_LOG_E(TAG, "Unable Repeat"); - break; - } - - ret = SubRemLoadSubStateOK; - -#if FURI_DEBUG - FURI_LOG_I(TAG, "%-16s - protocol Loaded", furi_string_get_cstr(sub_preset->label)); -#endif - } while(false); - - furi_string_free(temp_str); - sub_preset->load_state = ret; - return ret; -} diff --git a/applications/main/subghz_remote/helpers/subrem_presets.h b/applications/main/subghz_remote/helpers/subrem_presets.h deleted file mode 100644 index d66181b90..000000000 --- a/applications/main/subghz_remote/helpers/subrem_presets.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include "subrem_types.h" -#include "txrx/subghz_txrx.h" - -#include -#include - -typedef struct { - FuriString* name; - uint32_t frequency; - // size_t preset_index; // Need for custom preset -} FreqPreset; - -// Sub File preset -typedef struct { - FlipperFormat* fff_data; - FreqPreset freq_preset; - FuriString* file_path; - FuriString* protocaol_name; - FuriString* label; - SubGhzProtocolType type; - SubRemLoadSubState load_state; -} SubRemSubFilePreset; - -typedef struct { - SubRemSubFilePreset* subs_preset[SubRemSubKeyNameMaxCount]; -} SubRemMapPreset; - -SubRemSubFilePreset* subrem_sub_file_preset_alloc(); - -void subrem_sub_file_preset_free(SubRemSubFilePreset* sub_preset); - -void subrem_sub_file_preset_reset(SubRemSubFilePreset* sub_preset); - -SubRemLoadSubState subrem_sub_preset_load( - SubRemSubFilePreset* sub_preset, - SubGhzTxRx* txrx, - FlipperFormat* fff_data_file); diff --git a/applications/main/subghz_remote/helpers/subrem_types.h b/applications/main/subghz_remote/helpers/subrem_types.h deleted file mode 100644 index b43f8499d..000000000 --- a/applications/main/subghz_remote/helpers/subrem_types.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include -#include - -#define SUBREM_APP_APP_FILE_VERSION 1 -#define SUBREM_APP_APP_FILE_TYPE "Flipper SubRem Map file" -#define SUBREM_APP_EXTENSION ".txt" - -typedef enum { - SubRemSubKeyNameUp = (0U), - SubRemSubKeyNameDown, - SubRemSubKeyNameLeft, - SubRemSubKeyNameRight, - SubRemSubKeyNameOk, - SubRemSubKeyNameMaxCount, -} SubRemSubKeyName; - -typedef enum { - SubRemViewIDSubmenu, - SubRemViewIDWidget, - SubRemViewIDPopup, - SubRemViewIDTextInput, - SubRemViewIDRemote, - SubRemViewIDEditMenu, -} SubRemViewID; - -typedef enum { - SubRemLoadSubStateNotSet = 0, - SubRemLoadSubStatePreloaded, - SubRemLoadSubStateError, - SubRemLoadSubStateErrorIncorectPath, - SubRemLoadSubStateErrorNoFile, - SubRemLoadSubStateErrorFreq, - SubRemLoadSubStateErrorMod, - SubRemLoadSubStateErrorProtocol, - SubRemLoadSubStateOK, -} SubRemLoadSubState; - -typedef enum { - SubRemLoadMapStateBack = 0, - SubRemLoadMapStateError, - SubRemLoadMapStateErrorOpenError, - SubRemLoadMapStateErrorStorage, - SubRemLoadMapStateErrorBrokenFile, - SubRemLoadMapStateNotAllOK, - SubRemLoadMapStateOK, -} SubRemLoadMapState; \ No newline at end of file diff --git a/applications/main/subghz_remote/helpers/txrx/Readme.md b/applications/main/subghz_remote/helpers/txrx/Readme.md deleted file mode 100644 index 918160198..000000000 --- a/applications/main/subghz_remote/helpers/txrx/Readme.md +++ /dev/null @@ -1,4 +0,0 @@ -This is part of the official `SubGhz` app from [flipperzero-firmware](https://github.com/flipperdevices/flipperzero-firmware/tree/3217f286f03da119398586daf94c0723d28b872a/applications/main/subghz) - -With changes from [unleashed-firmware -](https://github.com/DarkFlippers/unleashed-firmware/tree/3eac6ccd48a3851cf5d63bf7899b387a293e5319/applications/main/subghz) \ No newline at end of file diff --git a/applications/main/subghz_remote/helpers/txrx/subghz_txrx.c b/applications/main/subghz_remote/helpers/txrx/subghz_txrx.c deleted file mode 100644 index 8c8c3b56d..000000000 --- a/applications/main/subghz_remote/helpers/txrx/subghz_txrx.c +++ /dev/null @@ -1,674 +0,0 @@ -#include "subghz_txrx_i.h" - -#include -#include -#include - -#ifndef FW_ORIGIN_Official -#include -#endif - -#define TAG "SubGhz" - -static void subghz_txrx_radio_device_power_on(SubGhzTxRx* instance) { - UNUSED(instance); - uint8_t attempts = 0; - while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { - furi_hal_power_enable_otg(); - //CC1101 power-up time - furi_delay_ms(10); - } -} - -static void subghz_txrx_radio_device_power_off(SubGhzTxRx* instance) { - UNUSED(instance); - if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg(); -} - -SubGhzTxRx* subghz_txrx_alloc() { - SubGhzTxRx* instance = malloc(sizeof(SubGhzTxRx)); - instance->setting = subghz_setting_alloc(); - subghz_setting_load(instance->setting, EXT_PATH("subghz/assets/setting_user")); - - instance->preset = malloc(sizeof(SubGhzRadioPreset)); - instance->preset->name = furi_string_alloc(); - subghz_txrx_set_preset( - instance, "AM650", subghz_setting_get_default_frequency(instance->setting), NULL, 0); - - instance->txrx_state = SubGhzTxRxStateSleep; - - subghz_txrx_hopper_set_state(instance, SubGhzHopperStateOFF); - subghz_txrx_speaker_set_state(instance, SubGhzSpeakerStateDisable); - subghz_txrx_set_debug_pin_state(instance, false); - - instance->worker = subghz_worker_alloc(); - instance->fff_data = flipper_format_string_alloc(); - - instance->environment = subghz_environment_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( - instance->environment, SUBGHZ_NICE_FLOR_S_DIR_NAME); - subghz_environment_set_protocol_registry( - instance->environment, (void*)&subghz_protocol_registry); - instance->receiver = subghz_receiver_alloc_init(instance->environment); - - subghz_worker_set_overrun_callback( - instance->worker, (SubGhzWorkerOverrunCallback)subghz_receiver_reset); - subghz_worker_set_pair_callback( - instance->worker, (SubGhzWorkerPairCallback)subghz_receiver_decode); - subghz_worker_set_context(instance->worker, instance->receiver); - - //set default device Internal - subghz_devices_init(); - instance->radio_device_type = SubGhzRadioDeviceTypeInternal; - instance->radio_device_type = - subghz_txrx_radio_device_set(instance, SubGhzRadioDeviceTypeExternalCC1101); - - return instance; -} - -void subghz_txrx_free(SubGhzTxRx* instance) { - furi_assert(instance); - - if(instance->radio_device_type != SubGhzRadioDeviceTypeInternal) { - subghz_txrx_radio_device_power_off(instance); - subghz_devices_end(instance->radio_device); - } - - subghz_devices_deinit(); - - subghz_worker_free(instance->worker); - subghz_receiver_free(instance->receiver); - subghz_environment_free(instance->environment); - flipper_format_free(instance->fff_data); - furi_string_free(instance->preset->name); - subghz_setting_free(instance->setting); - - free(instance->preset); - free(instance); -} - -bool subghz_txrx_is_database_loaded(SubGhzTxRx* instance) { - furi_assert(instance); - return instance->is_database_loaded; -} - -void subghz_txrx_set_preset( - SubGhzTxRx* instance, - const char* preset_name, - uint32_t frequency, - uint8_t* preset_data, - size_t preset_data_size) { - furi_assert(instance); - furi_string_set(instance->preset->name, preset_name); - SubGhzRadioPreset* preset = instance->preset; - preset->frequency = frequency; - preset->data = preset_data; - preset->data_size = preset_data_size; -} - -const char* subghz_txrx_get_preset_name(SubGhzTxRx* instance, const char* preset) { - UNUSED(instance); - const char* preset_name = ""; - if(!strcmp(preset, "FuriHalSubGhzPresetOok270Async")) { - preset_name = "AM270"; - } else if(!strcmp(preset, "FuriHalSubGhzPresetOok650Async")) { - preset_name = "AM650"; - } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev238Async")) { - preset_name = "FM238"; - } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev476Async")) { - preset_name = "FM476"; - } else if(!strcmp(preset, "FuriHalSubGhzPresetCustom")) { - preset_name = "CUSTOM"; - } else { - FURI_LOG_E(TAG, "Unknown preset"); - } - return preset_name; -} - -SubGhzRadioPreset subghz_txrx_get_preset(SubGhzTxRx* instance) { - furi_assert(instance); - return *instance->preset; -} - -void subghz_txrx_get_frequency_and_modulation( - SubGhzTxRx* instance, - FuriString* frequency, - FuriString* modulation, - bool long_name) { - furi_assert(instance); - SubGhzRadioPreset* preset = instance->preset; - if(frequency != NULL) { - furi_string_printf( - frequency, - "%03ld.%02ld", - preset->frequency / 1000000 % 1000, - preset->frequency / 10000 % 100); - } - if(modulation != NULL) { - if(long_name) { - furi_string_printf(modulation, "%s", furi_string_get_cstr(preset->name)); - } else { - furi_string_printf(modulation, "%.2s", furi_string_get_cstr(preset->name)); - } - } -} - -static void subghz_txrx_begin(SubGhzTxRx* instance, uint8_t* preset_data) { - furi_assert(instance); - subghz_devices_reset(instance->radio_device); - subghz_devices_idle(instance->radio_device); - subghz_devices_load_preset(instance->radio_device, FuriHalSubGhzPresetCustom, preset_data); - instance->txrx_state = SubGhzTxRxStateIDLE; -} - -static uint32_t subghz_txrx_rx(SubGhzTxRx* instance, uint32_t frequency) { - furi_assert(instance); - furi_assert( - instance->txrx_state != SubGhzTxRxStateRx && instance->txrx_state != SubGhzTxRxStateSleep); - - subghz_devices_idle(instance->radio_device); - - uint32_t value = subghz_devices_set_frequency(instance->radio_device, frequency); - subghz_devices_flush_rx(instance->radio_device); - subghz_txrx_speaker_on(instance); - - subghz_devices_start_async_rx( - instance->radio_device, subghz_worker_rx_callback, instance->worker); - subghz_worker_start(instance->worker); - instance->txrx_state = SubGhzTxRxStateRx; - return value; -} - -static void subghz_txrx_idle(SubGhzTxRx* instance) { - furi_assert(instance); - furi_assert(instance->txrx_state != SubGhzTxRxStateSleep); - subghz_devices_idle(instance->radio_device); - subghz_txrx_speaker_off(instance); - instance->txrx_state = SubGhzTxRxStateIDLE; -} - -static void subghz_txrx_rx_end(SubGhzTxRx* instance) { - furi_assert(instance); - furi_assert(instance->txrx_state == SubGhzTxRxStateRx); - - if(subghz_worker_is_running(instance->worker)) { - subghz_worker_stop(instance->worker); - subghz_devices_stop_async_rx(instance->radio_device); - } - subghz_devices_idle(instance->radio_device); - subghz_txrx_speaker_off(instance); - instance->txrx_state = SubGhzTxRxStateIDLE; -} - -void subghz_txrx_sleep(SubGhzTxRx* instance) { - furi_assert(instance); - subghz_devices_sleep(instance->radio_device); - instance->txrx_state = SubGhzTxRxStateSleep; -} - -static bool subghz_txrx_tx(SubGhzTxRx* instance, uint32_t frequency) { - furi_assert(instance); - furi_assert(instance->txrx_state != SubGhzTxRxStateSleep); - - subghz_devices_idle(instance->radio_device); - subghz_devices_set_frequency(instance->radio_device, frequency); - - bool ret = subghz_devices_set_tx(instance->radio_device); - if(ret) { - subghz_txrx_speaker_on(instance); - instance->txrx_state = SubGhzTxRxStateTx; - } - - return ret; -} - -SubGhzTxRxStartTxState subghz_txrx_tx_start(SubGhzTxRx* instance, FlipperFormat* flipper_format) { - furi_assert(instance); - furi_assert(flipper_format); - - subghz_txrx_stop(instance); - - SubGhzTxRxStartTxState ret = SubGhzTxRxStartTxStateErrorParserOthers; - FuriString* temp_str = furi_string_alloc(); - uint32_t repeat = 200; - do { - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - if(!flipper_format_read_string(flipper_format, "Protocol", temp_str)) { - FURI_LOG_E(TAG, "Missing Protocol"); - break; - } - if(!flipper_format_insert_or_update_uint32(flipper_format, "Repeat", &repeat, 1)) { - FURI_LOG_E(TAG, "Unable Repeat"); - break; - } - ret = SubGhzTxRxStartTxStateOk; - - SubGhzRadioPreset* preset = instance->preset; - instance->transmitter = - subghz_transmitter_alloc_init(instance->environment, furi_string_get_cstr(temp_str)); - - if(instance->transmitter) { - if(subghz_transmitter_deserialize(instance->transmitter, flipper_format) == - SubGhzProtocolStatusOk) { - if(strcmp(furi_string_get_cstr(preset->name), "") != 0) { - subghz_txrx_begin( - instance, - subghz_setting_get_preset_data_by_name( - instance->setting, furi_string_get_cstr(preset->name))); - if(preset->frequency) { - if(!subghz_txrx_tx(instance, preset->frequency)) { - FURI_LOG_E(TAG, "Only Rx"); - ret = SubGhzTxRxStartTxStateErrorOnlyRx; - } - } else { - ret = SubGhzTxRxStartTxStateErrorParserOthers; - } - - } else { - FURI_LOG_E( - TAG, "Unknown name preset \" %s \"", furi_string_get_cstr(preset->name)); - ret = SubGhzTxRxStartTxStateErrorParserOthers; - } - - if(ret == SubGhzTxRxStartTxStateOk) { - //Start TX - subghz_devices_start_async_tx( - instance->radio_device, subghz_transmitter_yield, instance->transmitter); - } - } else { - ret = SubGhzTxRxStartTxStateErrorParserOthers; - } - } else { - ret = SubGhzTxRxStartTxStateErrorParserOthers; - } - if(ret != SubGhzTxRxStartTxStateOk) { - subghz_transmitter_free(instance->transmitter); - if(instance->txrx_state != SubGhzTxRxStateIDLE) { - subghz_txrx_idle(instance); - } - } - - } while(false); - furi_string_free(temp_str); - return ret; -} - -void subghz_txrx_rx_start(SubGhzTxRx* instance) { - furi_assert(instance); - subghz_txrx_stop(instance); - subghz_txrx_begin( - instance, - subghz_setting_get_preset_data_by_name( - subghz_txrx_get_setting(instance), furi_string_get_cstr(instance->preset->name))); - subghz_txrx_rx(instance, instance->preset->frequency); -} - -void subghz_txrx_set_need_save_callback( - SubGhzTxRx* instance, - SubGhzTxRxNeedSaveCallback callback, - void* context) { - furi_assert(instance); - instance->need_save_callback = callback; - instance->need_save_context = context; -} - -static void subghz_txrx_tx_stop(SubGhzTxRx* instance) { - furi_assert(instance); - furi_assert(instance->txrx_state == SubGhzTxRxStateTx); - //Stop TX - subghz_devices_stop_async_tx(instance->radio_device); - subghz_transmitter_stop(instance->transmitter); - subghz_transmitter_free(instance->transmitter); - - //if protocol dynamic then we save the last upload - if(instance->decoder_result->protocol->type == SubGhzProtocolTypeDynamic) { - if(instance->need_save_callback) { - instance->need_save_callback(instance->need_save_context); - } - } - subghz_txrx_idle(instance); - subghz_txrx_speaker_off(instance); - //Todo: Show message -} - -FlipperFormat* subghz_txrx_get_fff_data(SubGhzTxRx* instance) { - furi_assert(instance); - return instance->fff_data; -} - -SubGhzSetting* subghz_txrx_get_setting(SubGhzTxRx* instance) { - furi_assert(instance); - return instance->setting; -} - -void subghz_txrx_stop(SubGhzTxRx* instance) { - furi_assert(instance); - - switch(instance->txrx_state) { - case SubGhzTxRxStateTx: - subghz_txrx_tx_stop(instance); - subghz_txrx_speaker_unmute(instance); - break; - case SubGhzTxRxStateRx: - subghz_txrx_rx_end(instance); - subghz_txrx_speaker_mute(instance); - break; - - default: - break; - } -} - -void subghz_txrx_hopper_update(SubGhzTxRx* instance) { - furi_assert(instance); - - switch(instance->hopper_state) { - case SubGhzHopperStateOFF: - case SubGhzHopperStatePause: - return; - case SubGhzHopperStateRSSITimeOut: - if(instance->hopper_timeout != 0) { - instance->hopper_timeout--; - return; - } - break; - default: - break; - } - float rssi = -127.0f; - if(instance->hopper_state != SubGhzHopperStateRSSITimeOut) { - // See RSSI Calculation timings in CC1101 17.3 RSSI - rssi = subghz_devices_get_rssi(instance->radio_device); - - // Stay if RSSI is high enough - if(rssi > -90.0f) { - instance->hopper_timeout = 10; - instance->hopper_state = SubGhzHopperStateRSSITimeOut; - return; - } - } else { - instance->hopper_state = SubGhzHopperStateRunning; - } - // Select next frequency - if(instance->hopper_idx_frequency < - subghz_setting_get_hopper_frequency_count(instance->setting) - 1) { - instance->hopper_idx_frequency++; - } else { - instance->hopper_idx_frequency = 0; - } - - if(instance->txrx_state == SubGhzTxRxStateRx) { - subghz_txrx_rx_end(instance); - }; - if(instance->txrx_state == SubGhzTxRxStateIDLE) { - subghz_receiver_reset(instance->receiver); - instance->preset->frequency = - subghz_setting_get_hopper_frequency(instance->setting, instance->hopper_idx_frequency); - subghz_txrx_rx(instance, instance->preset->frequency); - } -} - -SubGhzHopperState subghz_txrx_hopper_get_state(SubGhzTxRx* instance) { - furi_assert(instance); - return instance->hopper_state; -} - -void subghz_txrx_hopper_set_state(SubGhzTxRx* instance, SubGhzHopperState state) { - furi_assert(instance); - instance->hopper_state = state; -} - -void subghz_txrx_hopper_unpause(SubGhzTxRx* instance) { - furi_assert(instance); - if(instance->hopper_state == SubGhzHopperStatePause) { - instance->hopper_state = SubGhzHopperStateRunning; - } -} - -void subghz_txrx_hopper_pause(SubGhzTxRx* instance) { - furi_assert(instance); - if(instance->hopper_state == SubGhzHopperStateRunning) { - instance->hopper_state = SubGhzHopperStatePause; - } -} - -void subghz_txrx_speaker_on(SubGhzTxRx* instance) { - furi_assert(instance); - if(instance->debug_pin_state) { - subghz_devices_set_async_mirror_pin(instance->radio_device, &gpio_ibutton); - } - - if(instance->speaker_state == SubGhzSpeakerStateEnable) { - if(furi_hal_speaker_acquire(30)) { - if(!instance->debug_pin_state) { - subghz_devices_set_async_mirror_pin(instance->radio_device, &gpio_speaker); - } - } else { - instance->speaker_state = SubGhzSpeakerStateDisable; - } - } -} - -void subghz_txrx_speaker_off(SubGhzTxRx* instance) { - furi_assert(instance); - if(instance->debug_pin_state) { - subghz_devices_set_async_mirror_pin(instance->radio_device, NULL); - } - if(instance->speaker_state != SubGhzSpeakerStateDisable) { - if(furi_hal_speaker_is_mine()) { - if(!instance->debug_pin_state) { - subghz_devices_set_async_mirror_pin(instance->radio_device, NULL); - } - furi_hal_speaker_release(); - if(instance->speaker_state == SubGhzSpeakerStateShutdown) - instance->speaker_state = SubGhzSpeakerStateDisable; - } - } -} - -void subghz_txrx_speaker_mute(SubGhzTxRx* instance) { - furi_assert(instance); - if(instance->debug_pin_state) { - subghz_devices_set_async_mirror_pin(instance->radio_device, NULL); - } - if(instance->speaker_state == SubGhzSpeakerStateEnable) { - if(furi_hal_speaker_is_mine()) { - if(!instance->debug_pin_state) { - subghz_devices_set_async_mirror_pin(instance->radio_device, NULL); - } - } - } -} - -void subghz_txrx_speaker_unmute(SubGhzTxRx* instance) { - furi_assert(instance); - if(instance->debug_pin_state) { - subghz_devices_set_async_mirror_pin(instance->radio_device, &gpio_ibutton); - } - if(instance->speaker_state == SubGhzSpeakerStateEnable) { - if(furi_hal_speaker_is_mine()) { - if(!instance->debug_pin_state) { - subghz_devices_set_async_mirror_pin(instance->radio_device, &gpio_speaker); - } - } - } -} - -void subghz_txrx_speaker_set_state(SubGhzTxRx* instance, SubGhzSpeakerState state) { - furi_assert(instance); - instance->speaker_state = state; -} - -SubGhzSpeakerState subghz_txrx_speaker_get_state(SubGhzTxRx* instance) { - furi_assert(instance); - return instance->speaker_state; -} - -bool subghz_txrx_load_decoder_by_name_protocol(SubGhzTxRx* instance, const char* name_protocol) { - furi_assert(instance); - furi_assert(name_protocol); - bool res = false; - instance->decoder_result = - subghz_receiver_search_decoder_base_by_name(instance->receiver, name_protocol); - if(instance->decoder_result) { - res = true; - } - return res; -} - -SubGhzProtocolDecoderBase* subghz_txrx_get_decoder(SubGhzTxRx* instance) { - furi_assert(instance); - return instance->decoder_result; -} - -bool subghz_txrx_protocol_is_serializable(SubGhzTxRx* instance) { - furi_assert(instance); - return ( - (instance->decoder_result->protocol->flag & SubGhzProtocolFlag_Save) == - SubGhzProtocolFlag_Save); -} - -bool subghz_txrx_protocol_is_transmittable(SubGhzTxRx* instance, bool check_type) { - furi_assert(instance); - const SubGhzProtocol* protocol = instance->decoder_result->protocol; - if(check_type) { - return ( - ((protocol->flag & SubGhzProtocolFlag_Send) == SubGhzProtocolFlag_Send) && - protocol->encoder->deserialize && protocol->type == SubGhzProtocolTypeStatic); - } - return ( - ((protocol->flag & SubGhzProtocolFlag_Send) == SubGhzProtocolFlag_Send) && - protocol->encoder->deserialize); -} - -void subghz_txrx_receiver_set_filter(SubGhzTxRx* instance, SubGhzProtocolFlag filter) { - furi_assert(instance); - subghz_receiver_set_filter(instance->receiver, filter); -} - -void subghz_txrx_set_rx_calback( - SubGhzTxRx* instance, - SubGhzReceiverCallback callback, - void* context) { - subghz_receiver_set_rx_callback(instance->receiver, callback, context); -} - -void subghz_txrx_set_raw_file_encoder_worker_callback_end( - SubGhzTxRx* instance, - SubGhzProtocolEncoderRAWCallbackEnd callback, - void* context) { - subghz_protocol_raw_file_encoder_worker_set_callback_end( - (SubGhzProtocolEncoderRAW*)subghz_transmitter_get_protocol_instance(instance->transmitter), - callback, - context); -} - -bool subghz_txrx_radio_device_is_external_connected(SubGhzTxRx* instance, const char* name) { - furi_assert(instance); - - bool is_connect = false; - bool is_otg_enabled = furi_hal_power_is_otg_enabled(); - - if(!is_otg_enabled) { - subghz_txrx_radio_device_power_on(instance); - } - - const SubGhzDevice* device = subghz_devices_get_by_name(name); - if(device) { - is_connect = subghz_devices_is_connect(device); - } - - if(!is_otg_enabled) { - subghz_txrx_radio_device_power_off(instance); - } - return is_connect; -} - -SubGhzRadioDeviceType - subghz_txrx_radio_device_set(SubGhzTxRx* instance, SubGhzRadioDeviceType radio_device_type) { - furi_assert(instance); - - if(radio_device_type == SubGhzRadioDeviceTypeExternalCC1101 && - subghz_txrx_radio_device_is_external_connected(instance, SUBGHZ_DEVICE_CC1101_EXT_NAME)) { - subghz_txrx_radio_device_power_on(instance); - instance->radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_EXT_NAME); - subghz_devices_begin(instance->radio_device); - instance->radio_device_type = SubGhzRadioDeviceTypeExternalCC1101; - } else { - subghz_txrx_radio_device_power_off(instance); - if(instance->radio_device_type != SubGhzRadioDeviceTypeInternal) { - subghz_devices_end(instance->radio_device); - } - instance->radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME); - instance->radio_device_type = SubGhzRadioDeviceTypeInternal; - } - - return instance->radio_device_type; -} - -SubGhzRadioDeviceType subghz_txrx_radio_device_get(SubGhzTxRx* instance) { - furi_assert(instance); - return instance->radio_device_type; -} - -float subghz_txrx_radio_device_get_rssi(SubGhzTxRx* instance) { - furi_assert(instance); - return subghz_devices_get_rssi(instance->radio_device); -} - -const char* subghz_txrx_radio_device_get_name(SubGhzTxRx* instance) { - furi_assert(instance); - return subghz_devices_get_name(instance->radio_device); -} - -bool subghz_txrx_radio_device_is_frequency_valid(SubGhzTxRx* instance, uint32_t frequency) { - furi_assert(instance); - return subghz_devices_is_frequency_valid(instance->radio_device, frequency); -} - -bool subghz_txrx_radio_device_is_tx_allowed(SubGhzTxRx* instance, uint32_t frequency) { - furi_assert(instance); - furi_assert(instance->txrx_state != SubGhzTxRxStateSleep); - - subghz_devices_idle(instance->radio_device); - subghz_devices_set_frequency(instance->radio_device, frequency); - - bool ret = subghz_devices_set_tx(instance->radio_device); - subghz_devices_idle(instance->radio_device); - - return ret; -} - -void subghz_txrx_set_debug_pin_state(SubGhzTxRx* instance, bool state) { - furi_assert(instance); - instance->debug_pin_state = state; -} - -bool subghz_txrx_get_debug_pin_state(SubGhzTxRx* instance) { - furi_assert(instance); - return instance->debug_pin_state; -} - -#ifndef FW_ORIGIN_Official -void subghz_txrx_reset_dynamic_and_custom_btns(SubGhzTxRx* instance) { - furi_assert(instance); - subghz_environment_reset_keeloq(instance->environment); - - subghz_custom_btns_reset(); -} -#endif - -SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance) { - furi_assert(instance); - return instance->receiver; -} \ No newline at end of file diff --git a/applications/main/subghz_remote/helpers/txrx/subghz_txrx.h b/applications/main/subghz_remote/helpers/txrx/subghz_txrx.h deleted file mode 100644 index 93c4a2276..000000000 --- a/applications/main/subghz_remote/helpers/txrx/subghz_txrx.h +++ /dev/null @@ -1,375 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -typedef struct SubGhzTxRx SubGhzTxRx; - -typedef void (*SubGhzTxRxNeedSaveCallback)(void* context); - -typedef enum { - SubGhzTxRxStartTxStateOk, - SubGhzTxRxStartTxStateErrorOnlyRx, - SubGhzTxRxStartTxStateErrorParserOthers, -} SubGhzTxRxStartTxState; - -// Type from subghz_types.h need for txrx working -/** SubGhzTxRx state */ -typedef enum { - SubGhzTxRxStateIDLE, - SubGhzTxRxStateRx, - SubGhzTxRxStateTx, - SubGhzTxRxStateSleep, -} SubGhzTxRxState; - -/** SubGhzHopperState state */ -typedef enum { - SubGhzHopperStateOFF, - SubGhzHopperStateRunning, - SubGhzHopperStatePause, - SubGhzHopperStateRSSITimeOut, -} SubGhzHopperState; - -/** SubGhzSpeakerState state */ -typedef enum { - SubGhzSpeakerStateDisable, - SubGhzSpeakerStateShutdown, - SubGhzSpeakerStateEnable, -} SubGhzSpeakerState; - -/** SubGhzRadioDeviceType */ -typedef enum { - SubGhzRadioDeviceTypeAuto, - SubGhzRadioDeviceTypeInternal, - SubGhzRadioDeviceTypeExternalCC1101, -} SubGhzRadioDeviceType; - -/** - * Allocate SubGhzTxRx - * - * @return SubGhzTxRx* pointer to SubGhzTxRx - */ -SubGhzTxRx* subghz_txrx_alloc(); - -/** - * Free SubGhzTxRx - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_free(SubGhzTxRx* instance); - -/** - * Check if the database is loaded - * - * @param instance Pointer to a SubGhzTxRx - * @return bool True if the database is loaded - */ -bool subghz_txrx_is_database_loaded(SubGhzTxRx* instance); - -/** - * Set preset - * - * @param instance Pointer to a SubGhzTxRx - * @param preset_name Name of preset - * @param frequency Frequency in Hz - * @param preset_data Data of preset - * @param preset_data_size Size of preset data - */ -void subghz_txrx_set_preset( - SubGhzTxRx* instance, - const char* preset_name, - uint32_t frequency, - uint8_t* preset_data, - size_t preset_data_size); - -/** - * Get name of preset - * - * @param instance Pointer to a SubGhzTxRx - * @param preset String of preset - * @return const char* Name of preset - */ -const char* subghz_txrx_get_preset_name(SubGhzTxRx* instance, const char* preset); - -/** - * Get of preset - * - * @param instance Pointer to a SubGhzTxRx - * @return SubGhzRadioPreset Preset - */ -SubGhzRadioPreset subghz_txrx_get_preset(SubGhzTxRx* instance); - -/** - * Get string frequency and modulation - * - * @param instance Pointer to a SubGhzTxRx - * @param frequency Pointer to a string frequency - * @param modulation Pointer to a string modulation - */ -void subghz_txrx_get_frequency_and_modulation( - SubGhzTxRx* instance, - FuriString* frequency, - FuriString* modulation, - bool long_name); - -/** - * Start TX CC1101 - * - * @param instance Pointer to a SubGhzTxRx - * @param flipper_format Pointer to a FlipperFormat - * @return SubGhzTxRxStartTxState - */ -SubGhzTxRxStartTxState subghz_txrx_tx_start(SubGhzTxRx* instance, FlipperFormat* flipper_format); - -/** - * Start RX CC1101 - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_rx_start(SubGhzTxRx* instance); - -/** - * Stop TX/RX CC1101 - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_stop(SubGhzTxRx* instance); - -/** - * Set sleep mode CC1101 - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_sleep(SubGhzTxRx* instance); - -/** - * Update frequency CC1101 in automatic mode (hopper) - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_hopper_update(SubGhzTxRx* instance); - -/** - * Get state hopper - * - * @param instance Pointer to a SubGhzTxRx - * @return SubGhzHopperState - */ -SubGhzHopperState subghz_txrx_hopper_get_state(SubGhzTxRx* instance); - -/** - * Set state hopper - * - * @param instance Pointer to a SubGhzTxRx - * @param state State hopper - */ -void subghz_txrx_hopper_set_state(SubGhzTxRx* instance, SubGhzHopperState state); - -/** - * Unpause hopper - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_hopper_unpause(SubGhzTxRx* instance); - -/** - * Set pause hopper - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_hopper_pause(SubGhzTxRx* instance); - -/** - * Speaker on - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_speaker_on(SubGhzTxRx* instance); - -/** - * Speaker off - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_speaker_off(SubGhzTxRx* instance); - -/** - * Speaker mute - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_speaker_mute(SubGhzTxRx* instance); - -/** - * Speaker unmute - * - * @param instance Pointer to a SubGhzTxRx - */ -void subghz_txrx_speaker_unmute(SubGhzTxRx* instance); - -/** - * Set state speaker - * - * @param instance Pointer to a SubGhzTxRx - * @param state State speaker - */ -void subghz_txrx_speaker_set_state(SubGhzTxRx* instance, SubGhzSpeakerState state); - -/** - * Get state speaker - * - * @param instance Pointer to a SubGhzTxRx - * @return SubGhzSpeakerState - */ -SubGhzSpeakerState subghz_txrx_speaker_get_state(SubGhzTxRx* instance); - -/** - * load decoder by name protocol - * - * @param instance Pointer to a SubGhzTxRx - * @param name_protocol Name protocol - * @return bool True if the decoder is loaded - */ -bool subghz_txrx_load_decoder_by_name_protocol(SubGhzTxRx* instance, const char* name_protocol); - -/** - * Get decoder - * - * @param instance Pointer to a SubGhzTxRx - * @return SubGhzProtocolDecoderBase* Pointer to a SubGhzProtocolDecoderBase - */ -SubGhzProtocolDecoderBase* subghz_txrx_get_decoder(SubGhzTxRx* instance); - -/** - * Set callback for save data - * - * @param instance Pointer to a SubGhzTxRx - * @param callback Callback for save data - * @param context Context for callback - */ -void subghz_txrx_set_need_save_callback( - SubGhzTxRx* instance, - SubGhzTxRxNeedSaveCallback callback, - void* context); - -/** - * Get pointer to a load data key - * - * @param instance Pointer to a SubGhzTxRx - * @return FlipperFormat* - */ -FlipperFormat* subghz_txrx_get_fff_data(SubGhzTxRx* instance); - -/** - * Get pointer to a SugGhzSetting - * - * @param instance Pointer to a SubGhzTxRx - * @return SubGhzSetting* - */ -SubGhzSetting* subghz_txrx_get_setting(SubGhzTxRx* instance); - -/** - * Is it possible to save this protocol - * - * @param instance Pointer to a SubGhzTxRx - * @return bool True if it is possible to save this protocol - */ -bool subghz_txrx_protocol_is_serializable(SubGhzTxRx* instance); - -/** - * Is it possible to send this protocol - * - * @param instance Pointer to a SubGhzTxRx - * @return bool True if it is possible to send this protocol - */ -bool subghz_txrx_protocol_is_transmittable(SubGhzTxRx* instance, bool check_type); - -/** - * Set filter, what types of decoder to use - * - * @param instance Pointer to a SubGhzTxRx - * @param filter Filter - */ -void subghz_txrx_receiver_set_filter(SubGhzTxRx* instance, SubGhzProtocolFlag filter); - -/** - * Set callback for receive data - * - * @param instance Pointer to a SubGhzTxRx - * @param callback Callback for receive data - * @param context Context for callback - */ -void subghz_txrx_set_rx_calback( - SubGhzTxRx* instance, - SubGhzReceiverCallback callback, - void* context); - -/** - * Set callback for Raw decoder, end of data transfer - * - * @param instance Pointer to a SubGhzTxRx - * @param callback Callback for Raw decoder, end of data transfer - * @param context Context for callback - */ -void subghz_txrx_set_raw_file_encoder_worker_callback_end( - SubGhzTxRx* instance, - SubGhzProtocolEncoderRAWCallbackEnd callback, - void* context); - -/* Checking if an external radio device is connected -* -* @param instance Pointer to a SubGhzTxRx -* @param name Name of external radio device -* @return bool True if is connected to the external radio device -*/ -bool subghz_txrx_radio_device_is_external_connected(SubGhzTxRx* instance, const char* name); - -/* Set the selected radio device to use -* -* @param instance Pointer to a SubGhzTxRx -* @param radio_device_type Radio device type -* @return SubGhzRadioDeviceType Type of installed radio device -*/ -SubGhzRadioDeviceType - subghz_txrx_radio_device_set(SubGhzTxRx* instance, SubGhzRadioDeviceType radio_device_type); - -/* Get the selected radio device to use -* -* @param instance Pointer to a SubGhzTxRx -* @return SubGhzRadioDeviceType Type of installed radio device -*/ -SubGhzRadioDeviceType subghz_txrx_radio_device_get(SubGhzTxRx* instance); - -/* Get RSSI the selected radio device to use -* -* @param instance Pointer to a SubGhzTxRx -* @return float RSSI -*/ -float subghz_txrx_radio_device_get_rssi(SubGhzTxRx* instance); - -/* Get name the selected radio device to use -* -* @param instance Pointer to a SubGhzTxRx -* @return const char* Name of installed radio device -*/ -const char* subghz_txrx_radio_device_get_name(SubGhzTxRx* instance); - -/* Get get intelligence whether frequency the selected radio device to use -* -* @param instance Pointer to a SubGhzTxRx -* @return bool True if the frequency is valid -*/ -bool subghz_txrx_radio_device_is_frequency_valid(SubGhzTxRx* instance, uint32_t frequency); - -bool subghz_txrx_radio_device_is_tx_allowed(SubGhzTxRx* instance, uint32_t frequency); - -void subghz_txrx_set_debug_pin_state(SubGhzTxRx* instance, bool state); -bool subghz_txrx_get_debug_pin_state(SubGhzTxRx* instance); -#ifndef FW_ORIGIN_Official -void subghz_txrx_reset_dynamic_and_custom_btns(SubGhzTxRx* instance); -#endif -SubGhzReceiver* subghz_txrx_get_receiver(SubGhzTxRx* instance); // TODO use only in DecodeRaw diff --git a/applications/main/subghz_remote/helpers/txrx/subghz_txrx_i.h b/applications/main/subghz_remote/helpers/txrx/subghz_txrx_i.h deleted file mode 100644 index f058c2282..000000000 --- a/applications/main/subghz_remote/helpers/txrx/subghz_txrx_i.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include "subghz_txrx.h" - -struct SubGhzTxRx { - SubGhzWorker* worker; - - SubGhzEnvironment* environment; - SubGhzReceiver* receiver; - SubGhzTransmitter* transmitter; - SubGhzProtocolDecoderBase* decoder_result; - FlipperFormat* fff_data; - - SubGhzRadioPreset* preset; - SubGhzSetting* setting; - - uint8_t hopper_timeout; - uint8_t hopper_idx_frequency; - bool is_database_loaded; - SubGhzHopperState hopper_state; - - SubGhzTxRxState txrx_state; - SubGhzSpeakerState speaker_state; - const SubGhzDevice* radio_device; - SubGhzRadioDeviceType radio_device_type; - - SubGhzTxRxNeedSaveCallback need_save_callback; - void* need_save_context; - - bool debug_pin_state; -}; diff --git a/applications/main/subghz_remote/icon.png b/applications/main/subghz_remote/icon.png deleted file mode 100644 index c6b410f4c598d6b241b851826875a568c74f4d20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5000 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 AV*mgE diff --git a/applications/main/subghz_remote/icons/remote_scene/ButtonLeft_4x7.png b/applications/main/subghz_remote/icons/remote_scene/ButtonLeft_4x7.png deleted file mode 100644 index 0b4655d43247083aa705620e9836ac415b42ca46..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1415 zcmbVM+iKK67*5rq)>aU2M7$VM1Vxif;vTv~W2u`S7ED{V3s&&L*<`XiG|9wd+THd> z5CnY!sdyuJtrvQyAo>KpiLcV|{Tkc)riAbluXfwSZCApL`ztB&p zx6LGKvks4K_4~)qD&oGa-YdJlW)hAKMNJd7<=t?6c^RI1>c$ifyjaM>^|&8!ey zB4!nh9u>5uen6Ve@<H5rru6h<2Ef#GQdQ*CmZOlQi~N!?9H`Rp;C% zU}CB21#?;r`&0|6C0}b-=jODa5|nEJ#ntxQ&{~jpgtwDta4hftr~G=#p@V36e4Zjh zq%J~{y26Jjn=1Nw-l*3%QW5YFE*v4z3gt0$&(*xf2en34c?JpH8+FYldo+Alvg8af-pG4(=!fyUi-Wsg z`g#n9VUcf(DFr{poMSNzw-lz>w+HV+n1ELr&SLA#LHUb0p(xWQ(1*vJ-i+1!`swxZ Z!O7;c$;lT_->m1Ovaz)0yuI`A$q$F8u*d)a diff --git a/applications/main/subghz_remote/icons/remote_scene/ButtonRight_4x7.png b/applications/main/subghz_remote/icons/remote_scene/ButtonRight_4x7.png deleted file mode 100644 index 8e1c74c1c0038ea55172f19ac875003fc80c2d06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1839 zcmcIlO>f*p7#Yw)M6zw!O+@VZ{?d|D~WYi~8rHRY?X-&T}Yen`g$^+EJ;z+|RV zE@PoDvZ9%#+_}3bC_5Cj8jDGq541mi{7F+&KF}W65sr$Xn5H|YrMQ2(J7%Yc%;(zO z57ax000=TsQ+1Ke@+w#iw3au3cGGQWY740k2ijH>P(6tD)S)be>gX6Tj7`<`b>di- zgWp$8Y+?i31~CzF0&E4uRlA=C(Mp~K`{74jEchB|)4DDK!ZVhSwdFyw0YIZ1cDh0S{OvfO-U_~ zvmRF*m9sWDXNH)GOyqS1Skhxbr6}s*7t&@~kFM(NW5}qh?Lu@lJ}HE;FDiLdGO>LO z5pS*%E2grR)l^;|?O5b_?u0me&c1U}%jrk8*%=Wk%i)8yp2P|kuxmKg<=(u_`oQRI_0 zS`-DNysBx=#3&qSkgA@hJP>~D+ZM(s5jI6Owp`?yE=3e`YGUqkVOp#Cp=3wR3O4hX zX6BLsN3UBzV(vI5;|SZHgOb=HD0VFjpTyfFW}GnQuh>2*Q`k>*cAmA#iUT7EXSpo# zkPm5~#I-o^cpgfe#P$=4-Pi*SpT!-@nJgp8L347xe>5EKl`=_ZFc8XGy+_j=_R_7! z@vZZMowS1GJ?Zw)eetks%~G{BTR>T}9|jt0j3Btyb*C3-`C?fwY3EY`q*oYZ39DpM z&uJ;PCZPLs4QO1Jd_|A1PF)azZJ)RZ`^-VMWr6e#XUOA%3eLG_Ch@BDOHzMk*MF0G zCo7xMd?Mg*HMIXw%nNz?%60fZiZPlqb?GqUpXO`F&Yi!okZl(n>P@r1P2i)yk3DgRwbHeNn6e|;J^SK4TM LH~i+q&mR8;k>NTA diff --git a/applications/main/subghz_remote/icons/remote_scene/ButtonUp_7x4.png b/applications/main/subghz_remote/icons/remote_scene/ButtonUp_7x4.png deleted file mode 100644 index 1be79328b40a93297a5609756328406565c437c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 102 zcmeAS@N?(olHy`uVBq!ia0vp^>_E)I!3HFqj;YoHDIHH2#}J8d-yTOk1_O>mFaFD) zeWb+ZHz{mGZZ1QpXe09^4tcYT#4oe=UbmGC^A-KE*|F&zP#=S*tDnm{r-UX30HgpM AM*si- diff --git a/applications/main/subghz_remote/icons/remote_scene/Ok_btn_9x9.png b/applications/main/subghz_remote/icons/remote_scene/Ok_btn_9x9.png deleted file mode 100644 index 9a1539da2049f12f7b25f96b11a9c40cd8227302..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3605 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 LwKgd=cDwXHDN#*w diff --git a/applications/main/subghz_remote/icons/remote_scene/back_10px.png b/applications/main/subghz_remote/icons/remote_scene/back_10px.png deleted file mode 100644 index f9c615a99e69c0100b03a9ae7b2df903da4ecd66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2xGmzZ=C-xtZVk{1FcVbv~PUa<$!;&U>c zv7h@-A}f&37T^=&`v3obAT#vPO>_%)r1c48n{Iv*t(u1!X;5977~7Co?ed rv9U?Av01aVRT(gMJdt+jXk=uN>R^g!*w%ImsF1<>&pI=m5)cB{fFDGZlI8yr;B3<$MxhJ?+;A4eL&#) z0Ra}bue?07WhLz78x$BO|L3mq-MMxdP^D^#YeY#(Vo9o1a#1RfVlXl=GSoFN)ipE; zF*LF=Hn1|b&^9ozGB8+QQTzo(LvDUbW?CgwgE3G~h=HkCbE6;07#-3sX@sAxkg$U?hnu$6%_P+PX_Jv(ud zLf1xG|CwUz?7R1Up5OC4zxVgNce*W&4YheW_vK(1mglK+H=%$1JZE+m`hA@F<1zI2 zyA8fptqH{ONK}=TAjGw<2*hDRkufZBKGgVD-U({Lf_l{mhyV1gGrhn5dOvmG&rb;X|2#O* z`;Gdu`y8=lFC6>o;MdlzEhu;(gUPC_z|AEGi;B+`t?Ze5z3-kKC+@xe!rsi0?9s|K zy?-daKNrL9+N8K#jUJb4ydqS`GmmU@)cv;7aPpz%>TUZsFY*}}-;x*iZ59ty6_jpT zvujoMQ}z8jJ+AG;!%Gj}Yq-_gD;(ypTplW&z40q}pQ&N1scCq0d(~q_cR%sbwf8Sv zdVdlA`l;oI1plLZ-jYiT3faL`zr6A#=Lo=7=AJsu{N?^-b1q)%coKW)>T~u}qi^rn z-7>H`clPEJwEVR7TGqAGdqR;5OY#pr*E?^={1s1Y&f(g=vM=|qHywW9AEyugs9|9K z_qUv^T38l3y>(BG-D_BB`RVoV^}JI09`V|mBd`AW<~wBWyCXky1n0|1Nlg+*V)QGN;EdcVFdq|MubW(V_Tn9{lz<&(!Cf?0&8A zl@E$Ck9Ky~46J|Y$whnDXUy8sU3Tos>?t>Un9|+}sNpj`p?cz$4F;W6I^yu1td=)j zwphHBH{ybAO5KJiY~Ik|6F0PrHpy5~o?}l42p|MCfG0x1a7;)zj7eMpo$JG-5l@?` zHXBJXB*PHMf{1m6HIN{}u@W63h2e%VF{(r~MGfORCh)5rn!{*B^Z0mvp@`R;h7ZTa zSU`M`2@oM^6GetXP{HeN+v@{V%k5_5e+8G zkwg*(VF;PVP*i$K$XbuLG3}vK5Kuyqq!%K4ie;ot)zny<8cCZ^NiaQ~ENpU0nj%lI zJjF+!xy>BKy>oC09YBCl_0@MKq5HSOc8#H zHxrPt@G@uPXxUw}=@F^kKtO1=<+RE`fZLx72 zM^h}%PZ&K2qcJ389h0U^tT{O|!J$hHs!^{hL5Gn|PU-6=pgIxrK<@yAog7DH3a%&w z8g!!r!BMD#C>udrd^9VVErOXZqga7TC7!lcqdrv)I*fX4xSm29%!}Gu0vbreA!k;g z%|4nF%vOQs$|!0w97;_$K_%JJIG$`y z0f?!B#blXMGE;<>npEzfp3l7GX_S~MYjF^T&H&=qVRY(yC*C;TeK^CKEcntEB`m4& z*s`e!#M_|0il0b3`57vUflm0by2LgR4nVX&k8KG5wO*Mw+x#3L%ravoDAo)K9*8VK z`z@R#$`oXol=A*h>SY-g(0){rAj zX|i`eX-Qc`CULv;$ClJi>UW`W?b^xP)oq_>=<%(|iFP_&{;^5&uL6OoA}L2u$;}G@ zRN$B(Zj5Yq}83M;=f=r9w8MiVD2l{4`U z0fy0oX&k*FI5pSMi{36|`Ri-l*r@*9d2H`fXk<>LZgmX9OeOkpSK|4KPBfUUdA!xx z?`7r}mf - -// Generate scene id and total number -#define ADD_SCENE(prefix, name, id) SubRemScene##id, -typedef enum { -#include "subrem_scene_config.h" - SubRemSceneNum, -} SubRemScene; -#undef ADD_SCENE - -extern const SceneManagerHandlers subrem_scene_handlers; - -// Generate scene on_enter handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); -#include "subrem_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_event handlers declaration -#define ADD_SCENE(prefix, name, id) \ - bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); -#include "subrem_scene_config.h" -#undef ADD_SCENE - -// Generate scene on_exit handlers declaration -#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); -#include "subrem_scene_config.h" -#undef ADD_SCENE diff --git a/applications/main/subghz_remote/scenes/subrem_scene_config.h b/applications/main/subghz_remote/scenes/subrem_scene_config.h deleted file mode 100644 index 56fe641a6..000000000 --- a/applications/main/subghz_remote/scenes/subrem_scene_config.h +++ /dev/null @@ -1,12 +0,0 @@ -ADD_SCENE(subrem, start, Start) -ADD_SCENE(subrem, open_map_file, OpenMapFile) -ADD_SCENE(subrem, remote, Remote) -ADD_SCENE(subrem, edit_menu, EditMenu) -ADD_SCENE(subrem, edit_submenu, EditSubMenu) -ADD_SCENE(subrem, edit_label, EditLabel) -ADD_SCENE(subrem, open_sub_file, OpenSubFile) -ADD_SCENE(subrem, edit_preview, EditPreview) -ADD_SCENE(subrem, enter_new_name, EnterNewName) -#ifdef FW_ORIGIN_Official -ADD_SCENE(subrem, fw_warning, FwWarning) -#endif \ No newline at end of file diff --git a/applications/main/subghz_remote/scenes/subrem_scene_edit_label.c b/applications/main/subghz_remote/scenes/subrem_scene_edit_label.c deleted file mode 100644 index af4a33c1a..000000000 --- a/applications/main/subghz_remote/scenes/subrem_scene_edit_label.c +++ /dev/null @@ -1,133 +0,0 @@ -#include "../subghz_remote_app_i.h" - -#include - -typedef enum { - SubRemSceneEditLabelStateTextInput, - SubRemSceneEditLabelStateWidget, -} SubRemSceneEditLabelState; - -void subrem_scene_edit_label_text_input_callback(void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - view_dispatcher_send_custom_event( - app->view_dispatcher, SubRemCustomEventSceneEditLabelInputDone); -} - -void subrem_scene_edit_label_widget_callback(GuiButtonType result, InputType type, void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - if((result == GuiButtonTypeCenter) && (type == InputTypeShort)) { - view_dispatcher_send_custom_event( - app->view_dispatcher, SubRemCustomEventSceneEditLabelWidgetAcces); - } else if((result == GuiButtonTypeLeft) && (type == InputTypeShort)) { - view_dispatcher_send_custom_event( - app->view_dispatcher, SubRemCustomEventSceneEditLabelWidgetBack); - } -} - -void subrem_scene_edit_label_on_enter(void* context) { - SubGhzRemoteApp* app = context; - - SubRemSubFilePreset* sub_preset = app->map_preset->subs_preset[app->chusen_sub]; - - FuriString* temp_str = furi_string_alloc(); - - if(furi_string_empty(sub_preset->label)) { - if(furi_string_empty(sub_preset->file_path)) { - path_extract_filename(sub_preset->file_path, temp_str, true); - strcpy(app->file_name_tmp, furi_string_get_cstr(temp_str)); - } else { - strcpy(app->file_name_tmp, ""); - } - } else { - strcpy(app->file_name_tmp, furi_string_get_cstr(sub_preset->label)); - } - - TextInput* text_input = app->text_input; - text_input_set_header_text(text_input, "Label name"); - text_input_set_result_callback( - text_input, - subrem_scene_edit_label_text_input_callback, - app, - app->file_name_tmp, - 25, - false); -#ifndef FW_ORIGIN_Official - text_input_set_minimum_length(app->text_input, 0); -#endif - widget_add_string_element( - app->widget, 63, 12, AlignCenter, AlignCenter, FontPrimary, "Empty Label Name"); - widget_add_string_element( - app->widget, 63, 32, AlignCenter, AlignCenter, FontSecondary, "Continue?"); - - widget_add_button_element( - app->widget, GuiButtonTypeCenter, "Ok", subrem_scene_edit_label_widget_callback, app); - widget_add_button_element( - app->widget, GuiButtonTypeLeft, "Back", subrem_scene_edit_label_widget_callback, app); - - scene_manager_set_scene_state( - app->scene_manager, SubRemSceneEditLabel, SubRemSceneEditLabelStateTextInput); - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDTextInput); - - furi_string_free(temp_str); -} - -bool subrem_scene_edit_label_on_event(void* context, SceneManagerEvent event) { - SubGhzRemoteApp* app = context; - - FuriString* label = app->map_preset->subs_preset[app->chusen_sub]->label; - - if(event.type == SceneManagerEventTypeBack) { - if(scene_manager_get_scene_state(app->scene_manager, SubRemSceneEditLabel) == - SubRemSceneEditLabelStateWidget) { - scene_manager_set_scene_state( - app->scene_manager, SubRemSceneEditLabel, SubRemSceneEditLabelStateTextInput); - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDTextInput); - return true; - } else if( - scene_manager_get_scene_state(app->scene_manager, SubRemSceneEditLabel) == - SubRemSceneEditLabelStateTextInput) { - scene_manager_previous_scene(app->scene_manager); - return true; - } - - scene_manager_previous_scene(app->scene_manager); - return true; - } else if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubRemCustomEventSceneEditLabelInputDone) { - if(strcmp(app->file_name_tmp, "") == 0) { - scene_manager_set_scene_state( - app->scene_manager, SubRemSceneEditLabel, SubRemSceneEditLabelStateWidget); - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDWidget); - - } else { - furi_string_set(label, app->file_name_tmp); - app->map_not_saved = true; - scene_manager_previous_scene(app->scene_manager); - } - return true; - } else if(event.event == SubRemCustomEventSceneEditLabelWidgetAcces) { - furi_string_set(label, app->file_name_tmp); - app->map_not_saved = true; - scene_manager_previous_scene(app->scene_manager); - - return true; - } else if(event.event == SubRemCustomEventSceneEditLabelWidgetBack) { - scene_manager_set_scene_state( - app->scene_manager, SubRemSceneEditLabel, SubRemSceneEditLabelStateTextInput); - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDTextInput); - - return true; - } - } - return false; -} - -void subrem_scene_edit_label_on_exit(void* context) { - SubGhzRemoteApp* app = context; - - // Clear view - text_input_reset(app->text_input); - widget_reset(app->widget); -} diff --git a/applications/main/subghz_remote/scenes/subrem_scene_edit_menu.c b/applications/main/subghz_remote/scenes/subrem_scene_edit_menu.c deleted file mode 100644 index a8882009a..000000000 --- a/applications/main/subghz_remote/scenes/subrem_scene_edit_menu.c +++ /dev/null @@ -1,123 +0,0 @@ -#include "../subghz_remote_app_i.h" - -void subrem_scene_edit_menu_callback(SubRemCustomEvent event, void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -void subrem_scene_edit_menu_widget_callback(GuiButtonType result, InputType type, void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - if((result == GuiButtonTypeRight) && (type == InputTypeShort)) { - app->map_not_saved = false; - view_dispatcher_send_custom_event(app->view_dispatcher, SubRemCustomEventViewEditMenuBack); - } else if((result == GuiButtonTypeLeft) && (type == InputTypeShort)) { - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDEditMenu); - } -} - -static uint8_t subrem_scene_edit_menu_state_to_index(SubRemEditMenuState event_id) { - uint8_t ret = 0; - - if(event_id == SubRemEditMenuStateUP) { - ret = SubRemSubKeyNameUp; - } else if(event_id == SubRemEditMenuStateDOWN) { - ret = SubRemSubKeyNameDown; - } else if(event_id == SubRemEditMenuStateLEFT) { - ret = SubRemSubKeyNameLeft; - } else if(event_id == SubRemEditMenuStateRIGHT) { - ret = SubRemSubKeyNameRight; - } else if(event_id == SubRemEditMenuStateOK) { - ret = SubRemSubKeyNameOk; - } - - return ret; -} - -static void subrem_scene_edit_menu_update_data(SubGhzRemoteApp* app) { - furi_assert(app); - uint8_t index = subrem_scene_edit_menu_state_to_index( - scene_manager_get_scene_state(app->scene_manager, SubRemSceneEditMenu)); - - subrem_view_edit_menu_add_data_to_show( - app->subrem_edit_menu, - index, - app->map_preset->subs_preset[index]->label, - app->map_preset->subs_preset[index]->file_path, - app->map_preset->subs_preset[index]->load_state); -} - -void subrem_scene_edit_menu_on_enter(void* context) { - SubGhzRemoteApp* app = context; - - subrem_view_edit_menu_set_callback( - app->subrem_edit_menu, subrem_scene_edit_menu_callback, app); - - subrem_scene_edit_menu_update_data(app); - - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDEditMenu); - - Widget* widget = app->widget; - - widget_add_string_element( - widget, 63, 12, AlignCenter, AlignBottom, FontPrimary, "Changes are not saved"); - widget_add_string_element( - widget, 63, 32, AlignCenter, AlignBottom, FontPrimary, "do you want to exit?"); - - widget_add_button_element( - widget, GuiButtonTypeRight, "Yes", subrem_scene_edit_menu_widget_callback, app); - widget_add_button_element( - widget, GuiButtonTypeLeft, "No", subrem_scene_edit_menu_widget_callback, app); -} - -bool subrem_scene_edit_menu_on_event(void* context, SceneManagerEvent event) { - SubGhzRemoteApp* app = context; - - if(event.type == SceneManagerEventTypeBack) { - // Catch widget backEvent - return true; - } - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubRemCustomEventViewEditMenuBack) { - if(app->map_not_saved) { - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDWidget); - } else if(!scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, SubRemSceneStart)) { - scene_manager_stop(app->scene_manager); - view_dispatcher_stop(app->view_dispatcher); - } - - return true; - } else if( - event.event == SubRemCustomEventViewEditMenuUP || - event.event == SubRemCustomEventViewEditMenuDOWN) { - scene_manager_set_scene_state( - app->scene_manager, - SubRemSceneEditMenu, - subrem_view_edit_menu_get_index(app->subrem_edit_menu)); - subrem_scene_edit_menu_update_data(app); - - return true; - } else if(event.event == SubRemCustomEventViewEditMenuEdit) { - app->chusen_sub = subrem_view_edit_menu_get_index(app->subrem_edit_menu); - scene_manager_set_scene_state( - app->scene_manager, SubRemSceneEditSubMenu, EditSubmenuIndexEditLabel); - scene_manager_next_scene(app->scene_manager, SubRemSceneEditSubMenu); - - return true; - } else if(event.event == SubRemCustomEventViewEditMenuSave) { - scene_manager_next_scene(app->scene_manager, SubRemSceneEditPreview); - - return true; - } - } - - return false; -} - -void subrem_scene_edit_menu_on_exit(void* context) { - SubGhzRemoteApp* app = context; - widget_reset(app->widget); -} diff --git a/applications/main/subghz_remote/scenes/subrem_scene_edit_preview.c b/applications/main/subghz_remote/scenes/subrem_scene_edit_preview.c deleted file mode 100644 index 98a423202..000000000 --- a/applications/main/subghz_remote/scenes/subrem_scene_edit_preview.c +++ /dev/null @@ -1,74 +0,0 @@ -#include "../subghz_remote_app_i.h" -#include "../views/remote.h" - -#define TAG "SubRemScenRemote" - -void subghz_scene_edit_preview_save_popup_callback(void* context) { - SubGhzRemoteApp* app = context; - view_dispatcher_send_custom_event( - app->view_dispatcher, SubRemCustomEventSceneEditPreviewSaved); -} - -void subrem_scene_edit_preview_callback(SubRemCustomEvent event, void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -void subrem_scene_edit_preview_on_enter(void* context) { - SubGhzRemoteApp* app = context; - - // Setup view - Popup* popup = app->popup; - popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); - popup_set_header(popup, "Saved!", 13, 22, AlignLeft, AlignBottom); - popup_set_timeout(popup, 1500); - popup_set_context(popup, app); - popup_set_callback(popup, subghz_scene_edit_preview_save_popup_callback); - popup_enable_timeout(popup); - - subrem_view_remote_update_data_labels(app->subrem_remote_view, app->map_preset->subs_preset); - subrem_view_remote_set_state(app->subrem_remote_view, SubRemViewRemoteStateOFF, 0); - - subrem_view_remote_set_callback( - app->subrem_remote_view, subrem_scene_edit_preview_callback, app); - - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDRemote); -} - -bool subrem_scene_edit_preview_on_event(void* context, SceneManagerEvent event) { - SubGhzRemoteApp* app = context; - - if(event.type == SceneManagerEventTypeBack || - (event.type == SceneManagerEventTypeCustom && - (event.event == SubRemCustomEventViewRemoteStartLEFT || - event.event == SubRemCustomEventViewRemoteForcedStop))) { - scene_manager_previous_scene(app->scene_manager); - return true; - } else if( - event.type == SceneManagerEventTypeCustom && - (event.event == SubRemCustomEventViewRemoteStartRIGHT || - event.event == SubRemCustomEventViewRemoteStartOK)) { - if(subrem_save_map_to_file(app)) { - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDPopup); - app->map_not_saved = false; - return true; - } - // TODO error screen - return true; - } else if( - event.type == SceneManagerEventTypeCustom && - event.event == SubRemCustomEventSceneEditPreviewSaved) { - scene_manager_search_and_switch_to_previous_scene(app->scene_manager, SubRemSceneEditMenu); - } - // } else if(event.type == SceneManagerEventTypeTick) { - // } - return false; -} - -void subrem_scene_edit_preview_on_exit(void* context) { - SubGhzRemoteApp* app = context; - - subrem_view_remote_set_state(app->subrem_remote_view, SubRemViewRemoteStateIdle, 0); - popup_reset(app->popup); -} diff --git a/applications/main/subghz_remote/scenes/subrem_scene_edit_submenu.c b/applications/main/subghz_remote/scenes/subrem_scene_edit_submenu.c deleted file mode 100644 index 447beb96d..000000000 --- a/applications/main/subghz_remote/scenes/subrem_scene_edit_submenu.c +++ /dev/null @@ -1,54 +0,0 @@ -#include "../subghz_remote_app_i.h" -#include "../helpers/subrem_custom_event.h" - -void subrem_scene_edit_submenu_text_input_callback(void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, SubRemCustomEventSceneEditsubmenu); -} - -void subrem_scene_edit_submenu_callback(void* context, uint32_t index) { - furi_assert(context); - SubGhzRemoteApp* app = context; - - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -void subrem_scene_edit_submenu_on_enter(void* context) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - Submenu* submenu = app->submenu; - submenu_add_item( - submenu, "Edit Label", EditSubmenuIndexEditLabel, subrem_scene_edit_submenu_callback, app); - submenu_add_item( - submenu, "Edit File", EditSubmenuIndexEditFile, subrem_scene_edit_submenu_callback, app); - - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDSubmenu); -} - -bool subrem_scene_edit_submenu_on_event(void* context, SceneManagerEvent event) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == EditSubmenuIndexEditLabel) { - scene_manager_next_scene(app->scene_manager, SubRemSceneEditLabel); - consumed = true; - } else if(event.event == EditSubmenuIndexEditFile) { - scene_manager_next_scene(app->scene_manager, SubRemSceneOpenSubFile); - consumed = true; - } - } - - return consumed; -} - -void subrem_scene_edit_submenu_on_exit(void* context) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - submenu_reset(app->submenu); -} diff --git a/applications/main/subghz_remote/scenes/subrem_scene_enter_new_name.c b/applications/main/subghz_remote/scenes/subrem_scene_enter_new_name.c deleted file mode 100644 index b829723a3..000000000 --- a/applications/main/subghz_remote/scenes/subrem_scene_enter_new_name.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "../subghz_remote_app_i.h" -#include "../helpers/subrem_custom_event.h" - -#include - -void subrem_scene_enter_new_name_text_input_callback(void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, SubRemCustomEventSceneNewName); -} - -void subrem_scene_enter_new_name_on_enter(void* context) { - SubGhzRemoteApp* app = context; - - // Setup view - TextInput* text_input = app->text_input; - - //strncpy(app->file_name_tmp, "subrem_", SUBREM_MAX_LEN_NAME); - text_input_set_header_text(text_input, "Map file Name"); - text_input_set_result_callback( - text_input, - subrem_scene_enter_new_name_text_input_callback, - app, - app->file_name_tmp, - 25, - false); - - ValidatorIsFile* validator_is_file = validator_is_file_alloc_init( - furi_string_get_cstr(app->file_path), SUBREM_APP_EXTENSION, ""); - text_input_set_validator(text_input, validator_is_file_callback, validator_is_file); - - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDTextInput); -} - -bool subrem_scene_enter_new_name_on_event(void* context, SceneManagerEvent event) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubRemCustomEventSceneNewName) { - if(strcmp(app->file_name_tmp, "") != 0) { - furi_string_set(app->file_path, SUBREM_APP_FOLDER); - furi_string_cat_printf( - app->file_path, "/%s%s", app->file_name_tmp, SUBREM_APP_EXTENSION); - - subrem_map_preset_reset(app->map_preset); - scene_manager_next_scene(app->scene_manager, SubRemSceneEditMenu); - } else { //error - } - consumed = true; - } - } - - return consumed; -} - -void subrem_scene_enter_new_name_on_exit(void* context) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - submenu_reset(app->submenu); - - // Clear validator & view - void* validator_context = text_input_get_validator_callback_context(app->text_input); - text_input_set_validator(app->text_input, NULL, NULL); - validator_is_file_free(validator_context); - text_input_reset(app->text_input); -} diff --git a/applications/main/subghz_remote/scenes/subrem_scene_fw_warning.c b/applications/main/subghz_remote/scenes/subrem_scene_fw_warning.c deleted file mode 100644 index de473b72c..000000000 --- a/applications/main/subghz_remote/scenes/subrem_scene_fw_warning.c +++ /dev/null @@ -1,129 +0,0 @@ -#include "../subghz_remote_app_i.h" -#include "../helpers/subrem_custom_event.h" -#ifdef FW_ORIGIN_Official -typedef enum { - SceneFwWarningStateAttention, - SceneFwWarningStateAccept, -} SceneFwWarningState; - -static void subrem_scene_fw_warning_widget_render(SubGhzRemoteApp* app, SceneFwWarningState state); - -static void - subrem_scene_fw_warning_widget_callback(GuiButtonType result, InputType type, void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - - if(type == InputTypeShort) { - SubRemCustomEvent event = SubRemCustomEventSceneFwWarningExit; - - switch(scene_manager_get_scene_state(app->scene_manager, SubRemSceneFwWarning)) { - case SceneFwWarningStateAttention: - if(result == GuiButtonTypeRight) { - event = SubRemCustomEventSceneFwWarningNext; - } - break; - - case SceneFwWarningStateAccept: - if(result == GuiButtonTypeRight) { - event = SubRemCustomEventSceneFwWarningContinue; - } - - break; - } - - view_dispatcher_send_custom_event(app->view_dispatcher, event); - } -} - -static void - subrem_scene_fw_warning_widget_render(SubGhzRemoteApp* app, SceneFwWarningState state) { - furi_assert(app); - Widget* widget = app->widget; - - widget_reset(widget); - - switch(state) { - case SceneFwWarningStateAttention: - widget_add_button_element( - widget, GuiButtonTypeLeft, "Exit", subrem_scene_fw_warning_widget_callback, app); - widget_add_button_element( - widget, GuiButtonTypeRight, "Continue", subrem_scene_fw_warning_widget_callback, app); - widget_add_string_element( - widget, 64, 12, AlignCenter, AlignBottom, FontPrimary, "Not official FW"); - widget_add_string_multiline_element( - widget, - 64, - 32, - AlignCenter, - AlignCenter, - FontSecondary, - "You are using custom firmware\nPlease download a compatible\nversion of the application"); - break; - - case SceneFwWarningStateAccept: - widget_add_button_element( - widget, GuiButtonTypeLeft, "Exit", subrem_scene_fw_warning_widget_callback, app); - widget_add_button_element( - widget, GuiButtonTypeRight, "Accept", subrem_scene_fw_warning_widget_callback, app); - widget_add_string_element( - widget, 64, 12, AlignCenter, AlignBottom, FontPrimary, "Not official FW"); - widget_add_string_multiline_element( - widget, - 64, - 32, - AlignCenter, - AlignCenter, - FontSecondary, - "Yes, I understand that\nthe application can\nbreak my subghz key file"); - break; - } -} - -void subrem_scene_fw_warning_on_enter(void* context) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - - scene_manager_set_scene_state( - app->scene_manager, SubRemSceneFwWarning, SceneFwWarningStateAttention); - - subrem_scene_fw_warning_widget_render(app, SceneFwWarningStateAttention); - - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDWidget); -} - -bool subrem_scene_fw_warning_on_event(void* context, SceneManagerEvent event) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeBack) { - consumed = true; - } else if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubRemCustomEventSceneFwWarningExit) { - scene_manager_stop(app->scene_manager); - view_dispatcher_stop(app->view_dispatcher); - consumed = true; - } else if(event.event == SubRemCustomEventSceneFwWarningNext) { - scene_manager_set_scene_state( - app->scene_manager, SubRemSceneFwWarning, SceneFwWarningStateAccept); - subrem_scene_fw_warning_widget_render(app, SceneFwWarningStateAccept); - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDWidget); - consumed = true; - } else if(event.event == SubRemCustomEventSceneFwWarningContinue) { - scene_manager_previous_scene(app->scene_manager); - consumed = true; - } - } - - return consumed; -} - -void subrem_scene_fw_warning_on_exit(void* context) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - widget_reset(app->widget); -} -#endif \ No newline at end of file diff --git a/applications/main/subghz_remote/scenes/subrem_scene_open_map_file.c b/applications/main/subghz_remote/scenes/subrem_scene_open_map_file.c deleted file mode 100644 index b91a35129..000000000 --- a/applications/main/subghz_remote/scenes/subrem_scene_open_map_file.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "../subghz_remote_app_i.h" - -void subrem_scene_open_map_file_on_enter(void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - - SubRemLoadMapState load_state = subrem_load_from_file(app); - uint32_t start_scene_state = - scene_manager_get_scene_state(app->scene_manager, SubRemSceneStart); - - if(load_state == SubRemLoadMapStateBack) { - scene_manager_previous_scene(app->scene_manager); - } else if(start_scene_state == SubmenuIndexSubRemEditMapFile) { - scene_manager_set_scene_state(app->scene_manager, SubRemSceneEditMenu, SubRemSubKeyNameUp); - scene_manager_next_scene(app->scene_manager, SubRemSceneEditMenu); - } else if(start_scene_state == SubmenuIndexSubRemOpenMapFile) { - scene_manager_next_scene(app->scene_manager, SubRemSceneRemote); - } -} - -bool subrem_scene_open_map_file_on_event(void* context, SceneManagerEvent event) { - UNUSED(context); - UNUSED(event); - return false; -} - -void subrem_scene_open_map_file_on_exit(void* context) { - UNUSED(context); -} diff --git a/applications/main/subghz_remote/scenes/subrem_scene_open_sub_file.c b/applications/main/subghz_remote/scenes/subrem_scene_open_sub_file.c deleted file mode 100644 index 663e80ba7..000000000 --- a/applications/main/subghz_remote/scenes/subrem_scene_open_sub_file.c +++ /dev/null @@ -1,119 +0,0 @@ -#include "../subghz_remote_app_i.h" - -void subrem_scene_open_sub_file_error_popup_callback(void* context) { - SubGhzRemoteApp* app = context; - view_dispatcher_send_custom_event( - app->view_dispatcher, SubRemCustomEventSceneEditOpenSubErrorPopup); -} - -SubRemLoadSubState subrem_scene_open_sub_file_dialog(SubGhzRemoteApp* app) { - furi_assert(app); - - SubRemSubFilePreset* sub = app->map_preset->subs_preset[app->chusen_sub]; - - FuriString* temp_file_path = furi_string_alloc(); - - if(furi_string_empty(sub->file_path)) { - furi_string_set(temp_file_path, SUBGHZ_RAW_FOLDER); - } else { - furi_string_set(temp_file_path, sub->file_path); - } - - SubRemLoadSubState ret = SubRemLoadSubStateNotSet; - - DialogsFileBrowserOptions browser_options; - - dialog_file_browser_set_basic_options( - &browser_options, SUBGHZ_APP_FILENAME_EXTENSION, &I_sub1_10px); - browser_options.base_path = SUBGHZ_RAW_FOLDER; - - // Input events and views are managed by file_select - if(!dialog_file_browser_show(app->dialogs, temp_file_path, temp_file_path, &browser_options)) { - } else { - // Check sub file - SubRemSubFilePreset* sub_candidate = subrem_sub_file_preset_alloc(); - furi_string_set(sub_candidate->label, sub->label); - furi_string_set(sub_candidate->file_path, temp_file_path); - - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* fff_file = flipper_format_file_alloc(storage); - - if(flipper_format_file_open_existing( - fff_file, furi_string_get_cstr(sub_candidate->file_path))) { - ret = subrem_sub_preset_load(sub_candidate, app->txrx, fff_file); - } - - flipper_format_file_close(fff_file); - flipper_format_free(fff_file); - furi_record_close(RECORD_STORAGE); - - if(ret == SubRemLoadSubStateOK) { - subrem_sub_file_preset_free(app->map_preset->subs_preset[app->chusen_sub]); - app->map_preset->subs_preset[app->chusen_sub] = sub_candidate; - app->map_not_saved = true; - } else { - subrem_sub_file_preset_free(sub_candidate); - } - } - - furi_string_free(temp_file_path); - - return ret; -} - -void subrem_scene_open_sub_file_on_enter(void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - - SubRemLoadSubState load_state = subrem_scene_open_sub_file_dialog(app); - - Popup* popup = app->popup; - // popup_set_icon(); - popup_set_header(popup, "ERROR", 63, 16, AlignCenter, AlignBottom); - popup_set_timeout(popup, 1500); - popup_set_context(popup, app); - popup_set_callback(popup, subrem_scene_open_sub_file_error_popup_callback); - popup_enable_timeout(popup); - - if(load_state == SubRemLoadSubStateOK) { - scene_manager_previous_scene(app->scene_manager); - } else if(load_state == SubRemLoadSubStateNotSet) { - scene_manager_previous_scene(app->scene_manager); - } else { - switch(load_state) { - case SubRemLoadSubStateErrorFreq: - - popup_set_text(popup, "Bad frequency", 63, 30, AlignCenter, AlignBottom); - break; - case SubRemLoadSubStateErrorMod: - - popup_set_text(popup, "Bad modulation", 63, 30, AlignCenter, AlignBottom); - break; - case SubRemLoadSubStateErrorProtocol: - - popup_set_text(popup, "Unsupported protocol", 63, 30, AlignCenter, AlignBottom); - break; - - default: - break; - } - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDPopup); - } -} - -bool subrem_scene_open_sub_file_on_event(void* context, SceneManagerEvent event) { - SubGhzRemoteApp* app = context; - - if(event.type == SceneManagerEventTypeCustom && - event.event == SubRemCustomEventSceneEditOpenSubErrorPopup) { - scene_manager_previous_scene(app->scene_manager); - return true; - } - return false; -} - -void subrem_scene_open_sub_file_on_exit(void* context) { - SubGhzRemoteApp* app = context; - - popup_reset(app->popup); -} diff --git a/applications/main/subghz_remote/scenes/subrem_scene_remote.c b/applications/main/subghz_remote/scenes/subrem_scene_remote.c deleted file mode 100644 index e8d57dae7..000000000 --- a/applications/main/subghz_remote/scenes/subrem_scene_remote.c +++ /dev/null @@ -1,118 +0,0 @@ -#include "../subghz_remote_app_i.h" -#include "../views/remote.h" - -#include - -#define TAG "SubRemScenRemote" - -void subrem_scene_remote_callback(SubRemCustomEvent event, void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, event); -} - -void subrem_scene_remote_raw_callback_end_tx(void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - view_dispatcher_send_custom_event(app->view_dispatcher, SubRemCustomEventViewRemoteForcedStop); -} - -static uint8_t subrem_scene_remote_event_to_index(SubRemCustomEvent event_id) { - uint8_t ret = 0; - - if(event_id == SubRemCustomEventViewRemoteStartUP) { - ret = SubRemSubKeyNameUp; - } else if(event_id == SubRemCustomEventViewRemoteStartDOWN) { - ret = SubRemSubKeyNameDown; - } else if(event_id == SubRemCustomEventViewRemoteStartLEFT) { - ret = SubRemSubKeyNameLeft; - } else if(event_id == SubRemCustomEventViewRemoteStartRIGHT) { - ret = SubRemSubKeyNameRight; - } else if(event_id == SubRemCustomEventViewRemoteStartOK) { - ret = SubRemSubKeyNameOk; - } - - return ret; -} - -void subrem_scene_remote_on_enter(void* context) { - SubGhzRemoteApp* app = context; - - subrem_view_remote_update_data_labels(app->subrem_remote_view, app->map_preset->subs_preset); - subrem_view_remote_set_radio( - app->subrem_remote_view, - subghz_txrx_radio_device_get(app->txrx) != SubGhzRadioDeviceTypeInternal); - - subrem_view_remote_set_callback(app->subrem_remote_view, subrem_scene_remote_callback, app); - - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDRemote); -} - -bool subrem_scene_remote_on_event(void* context, SceneManagerEvent event) { - SubGhzRemoteApp* app = context; - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubRemCustomEventViewRemoteBack) { - if(!scene_manager_previous_scene(app->scene_manager)) { - scene_manager_stop(app->scene_manager); - view_dispatcher_stop(app->view_dispatcher); - } - return true; - } else if( - event.event == SubRemCustomEventViewRemoteStartUP || - event.event == SubRemCustomEventViewRemoteStartDOWN || - event.event == SubRemCustomEventViewRemoteStartLEFT || - event.event == SubRemCustomEventViewRemoteStartRIGHT || - event.event == SubRemCustomEventViewRemoteStartOK) { - // Start sending sub - subrem_tx_stop_sub(app, true); - - uint8_t chusen_sub = subrem_scene_remote_event_to_index(event.event); - app->chusen_sub = chusen_sub; - - subrem_view_remote_set_state( - app->subrem_remote_view, SubRemViewRemoteStateLoading, chusen_sub); - - if(subrem_tx_start_sub(app, app->map_preset->subs_preset[chusen_sub])) { - if(app->map_preset->subs_preset[chusen_sub]->type == SubGhzProtocolTypeRAW) { - subghz_txrx_set_raw_file_encoder_worker_callback_end( - app->txrx, subrem_scene_remote_raw_callback_end_tx, app); - } - subrem_view_remote_set_state( - app->subrem_remote_view, SubRemViewRemoteStateSending, chusen_sub); - notification_message(app->notifications, &sequence_blink_start_magenta); - } else { - subrem_view_remote_set_state( - app->subrem_remote_view, SubRemViewRemoteStateIdle, 0); - notification_message(app->notifications, &sequence_blink_red_100); - } - return true; - } else if(event.event == SubRemCustomEventViewRemoteForcedStop) { - subrem_tx_stop_sub(app, true); - subrem_view_remote_set_state(app->subrem_remote_view, SubRemViewRemoteStateIdle, 0); - - notification_message(app->notifications, &sequence_blink_stop); - return true; - } else if(event.event == SubRemCustomEventViewRemoteStop) { - if(subrem_tx_stop_sub(app, false)) { - subrem_view_remote_set_state( - app->subrem_remote_view, SubRemViewRemoteStateIdle, 0); - - notification_message(app->notifications, &sequence_blink_stop); - } - return true; - } - } - // } else if(event.type == SceneManagerEventTypeTick) { - // } - return false; -} - -void subrem_scene_remote_on_exit(void* context) { - SubGhzRemoteApp* app = context; - - subrem_tx_stop_sub(app, true); - - subrem_view_remote_set_state(app->subrem_remote_view, SubRemViewRemoteStateIdle, 0); - - notification_message(app->notifications, &sequence_blink_stop); -} diff --git a/applications/main/subghz_remote/scenes/subrem_scene_start.c b/applications/main/subghz_remote/scenes/subrem_scene_start.c deleted file mode 100644 index 0f3399b7c..000000000 --- a/applications/main/subghz_remote/scenes/subrem_scene_start.c +++ /dev/null @@ -1,100 +0,0 @@ -#include "../subghz_remote_app_i.h" -#include "../helpers/subrem_custom_event.h" - -void subrem_scene_start_submenu_callback(void* context, uint32_t index) { - furi_assert(context); - SubGhzRemoteApp* app = context; - - view_dispatcher_send_custom_event(app->view_dispatcher, index); -} - -void subrem_scene_start_on_enter(void* context) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - Submenu* submenu = app->submenu; - submenu_add_item( - submenu, - "Open Map File", - SubmenuIndexSubRemOpenMapFile, - subrem_scene_start_submenu_callback, - app); -#if FURI_DEBUG - submenu_add_item( - submenu, - "Remote_Debug", - SubmenuIndexSubRemRemoteView, - subrem_scene_start_submenu_callback, - app); -#endif - submenu_add_item( - submenu, - "Edit Map File", - SubmenuIndexSubRemEditMapFile, - subrem_scene_start_submenu_callback, - app); - submenu_add_item( - submenu, - "New Map File", - SubmenuIndexSubRemNewMapFile, - subrem_scene_start_submenu_callback, - app); - // submenu_add_item( - // submenu, - // "About", - // SubmenuIndexSubGhzRemoteAbout, - // subrem_scene_start_submenu_callback, - // app); - - submenu_set_selected_item( - submenu, scene_manager_get_scene_state(app->scene_manager, SubRemSceneStart)); - - view_dispatcher_switch_to_view(app->view_dispatcher, SubRemViewIDSubmenu); -} - -bool subrem_scene_start_on_event(void* context, SceneManagerEvent event) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - bool consumed = false; - - if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexSubRemOpenMapFile) { - scene_manager_set_scene_state( - app->scene_manager, SubRemSceneStart, SubmenuIndexSubRemOpenMapFile); - - scene_manager_next_scene(app->scene_manager, SubRemSceneOpenMapFile); - consumed = true; - } -#if FURI_DEBUG - else if(event.event == SubmenuIndexSubRemRemoteView) { - scene_manager_next_scene(app->scene_manager, SubRemSceneRemote); - consumed = true; - } -#endif - else if(event.event == SubmenuIndexSubRemEditMapFile) { - scene_manager_set_scene_state( - app->scene_manager, SubRemSceneStart, SubmenuIndexSubRemEditMapFile); - scene_manager_next_scene(app->scene_manager, SubRemSceneOpenMapFile); - consumed = true; - } else if(event.event == SubmenuIndexSubRemNewMapFile) { - scene_manager_set_scene_state( - app->scene_manager, SubRemSceneStart, SubmenuIndexSubRemNewMapFile); - scene_manager_next_scene(app->scene_manager, SubRemSceneEnterNewName); - consumed = true; - } - // } else if(event.event == SubmenuIndexSubRemAbout) { - // scene_manager_next_scene(app->scene_manager, SubRemSceneAbout); - // consumed = true; - // } - } - - return consumed; -} - -void subrem_scene_start_on_exit(void* context) { - furi_assert(context); - - SubGhzRemoteApp* app = context; - submenu_reset(app->submenu); -} diff --git a/applications/main/subghz_remote/subghz_remote_app.c b/applications/main/subghz_remote/subghz_remote_app.c deleted file mode 100644 index 473e3c012..000000000 --- a/applications/main/subghz_remote/subghz_remote_app.c +++ /dev/null @@ -1,218 +0,0 @@ -#include "subghz_remote_app_i.h" -#include - -static bool subghz_remote_app_custom_event_callback(void* context, uint32_t event) { - furi_assert(context); - SubGhzRemoteApp* app = context; - return scene_manager_handle_custom_event(app->scene_manager, event); -} - -static bool subghz_remote_app_back_event_callback(void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - return scene_manager_handle_back_event(app->scene_manager); -} - -static void subghz_remote_app_tick_event_callback(void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - scene_manager_handle_tick_event(app->scene_manager); -} - -static void subghz_remote_make_app_folder(SubGhzRemoteApp* app) { - furi_assert(app); - - Storage* storage = furi_record_open(RECORD_STORAGE); - - // Migrate old users data - storage_common_migrate(storage, EXT_PATH("unirf"), SUBREM_APP_FOLDER); - - if(!storage_simply_mkdir(storage, SUBREM_APP_FOLDER)) { - // FURI_LOG_E(TAG, "Could not create folder %s", SUBREM_APP_FOLDER); - dialog_message_show_storage_error(app->dialogs, "Cannot create\napp folder"); - } - furi_record_close(RECORD_STORAGE); -} - -SubGhzRemoteApp* subghz_remote_app_alloc() { - SubGhzRemoteApp* app = malloc(sizeof(SubGhzRemoteApp)); - - furi_hal_power_suppress_charge_enter(); - - app->file_path = furi_string_alloc(); - furi_string_set(app->file_path, SUBREM_APP_FOLDER); - - // GUI - app->gui = furi_record_open(RECORD_GUI); - - // View Dispatcher - app->view_dispatcher = view_dispatcher_alloc(); - - app->scene_manager = scene_manager_alloc(&subrem_scene_handlers, app); - view_dispatcher_enable_queue(app->view_dispatcher); - - view_dispatcher_set_event_callback_context(app->view_dispatcher, app); - view_dispatcher_set_custom_event_callback( - app->view_dispatcher, subghz_remote_app_custom_event_callback); - view_dispatcher_set_navigation_event_callback( - app->view_dispatcher, subghz_remote_app_back_event_callback); - view_dispatcher_set_tick_event_callback( - app->view_dispatcher, subghz_remote_app_tick_event_callback, 100); - - view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); - - // Open Notification record - app->notifications = furi_record_open(RECORD_NOTIFICATION); - - // SubMenu - app->submenu = submenu_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, SubRemViewIDSubmenu, submenu_get_view(app->submenu)); - - // Dialog - app->dialogs = furi_record_open(RECORD_DIALOGS); - - // TextInput - app->text_input = text_input_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, SubRemViewIDTextInput, text_input_get_view(app->text_input)); - - // Widget - app->widget = widget_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, SubRemViewIDWidget, widget_get_view(app->widget)); - - // Popup - app->popup = popup_alloc(); - view_dispatcher_add_view(app->view_dispatcher, SubRemViewIDPopup, popup_get_view(app->popup)); - - // Remote view - app->subrem_remote_view = subrem_view_remote_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - SubRemViewIDRemote, - subrem_view_remote_get_view(app->subrem_remote_view)); - - // Edit Menu view - app->subrem_edit_menu = subrem_view_edit_menu_alloc(); - view_dispatcher_add_view( - app->view_dispatcher, - SubRemViewIDEditMenu, - subrem_view_edit_menu_get_view(app->subrem_edit_menu)); - - app->map_preset = malloc(sizeof(SubRemMapPreset)); - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - app->map_preset->subs_preset[i] = subrem_sub_file_preset_alloc(); - } - - app->txrx = subghz_txrx_alloc(); - - subghz_txrx_set_need_save_callback(app->txrx, subrem_save_active_sub, app); - - app->map_not_saved = false; - - return app; -} - -void subghz_remote_app_free(SubGhzRemoteApp* app) { - furi_assert(app); - - furi_hal_power_suppress_charge_exit(); - - // Submenu - view_dispatcher_remove_view(app->view_dispatcher, SubRemViewIDSubmenu); - submenu_free(app->submenu); - - // Dialog - furi_record_close(RECORD_DIALOGS); - - // TextInput - view_dispatcher_remove_view(app->view_dispatcher, SubRemViewIDTextInput); - text_input_free(app->text_input); - - // Widget - view_dispatcher_remove_view(app->view_dispatcher, SubRemViewIDWidget); - widget_free(app->widget); - - // Popup - view_dispatcher_remove_view(app->view_dispatcher, SubRemViewIDPopup); - popup_free(app->popup); - - // Remote view - view_dispatcher_remove_view(app->view_dispatcher, SubRemViewIDRemote); - subrem_view_remote_free(app->subrem_remote_view); - - // Edit view - view_dispatcher_remove_view(app->view_dispatcher, SubRemViewIDEditMenu); - subrem_view_edit_menu_free(app->subrem_edit_menu); - - scene_manager_free(app->scene_manager); - view_dispatcher_free(app->view_dispatcher); - - subghz_txrx_free(app->txrx); - - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - subrem_sub_file_preset_free(app->map_preset->subs_preset[i]); - } - free(app->map_preset); - - // Notifications - furi_record_close(RECORD_NOTIFICATION); - app->notifications = NULL; - - // Close records - furi_record_close(RECORD_GUI); - - // Path strings - furi_string_free(app->file_path); - - free(app); -} - -int32_t subghz_remote_app(void* arg) { - SubGhzRemoteApp* subghz_remote_app = subghz_remote_app_alloc(); - - subghz_remote_make_app_folder(subghz_remote_app); - - bool map_loaded = false; -#ifdef FW_ORIGIN_Official - const bool fw_ofw = strcmp(version_get_firmware_origin(version_get()), "Official") == 0; -#endif - if((arg != NULL) && (strlen(arg) != 0)) { - furi_string_set(subghz_remote_app->file_path, (const char*)arg); - SubRemLoadMapState load_state = subrem_map_file_load( - subghz_remote_app, furi_string_get_cstr(subghz_remote_app->file_path)); - - if(load_state == SubRemLoadMapStateOK || load_state == SubRemLoadMapStateNotAllOK) { - map_loaded = true; - } else { - // TODO Replace - dialog_message_show_storage_error(subghz_remote_app->dialogs, "Cannot load\nmap file"); - } - } - - if(map_loaded) { - scene_manager_next_scene(subghz_remote_app->scene_manager, SubRemSceneRemote); - } else { - furi_string_set(subghz_remote_app->file_path, SUBREM_APP_FOLDER); - scene_manager_next_scene(subghz_remote_app->scene_manager, SubRemSceneStart); -#ifdef FW_ORIGIN_Official - if(fw_ofw) { - scene_manager_next_scene(subghz_remote_app->scene_manager, SubRemSceneOpenMapFile); - } - } - - if(!fw_ofw) { - scene_manager_next_scene(subghz_remote_app->scene_manager, SubRemSceneFwWarning); - } -#else - scene_manager_next_scene(subghz_remote_app->scene_manager, SubRemSceneOpenMapFile); - } -#endif - - view_dispatcher_run(subghz_remote_app->view_dispatcher); - - subghz_remote_app_free(subghz_remote_app); - - return 0; -} diff --git a/applications/main/subghz_remote/subghz_remote_app_i.c b/applications/main/subghz_remote/subghz_remote_app_i.c deleted file mode 100644 index ca54a997b..000000000 --- a/applications/main/subghz_remote/subghz_remote_app_i.c +++ /dev/null @@ -1,317 +0,0 @@ -#include "subghz_remote_app_i.h" -#include -#include - -#include "helpers/txrx/subghz_txrx.h" -#ifndef FW_ORIGIN_Official -#include -#endif - -#define TAG "SubGhzRemote" - -static const char* map_file_labels[SubRemSubKeyNameMaxCount][2] = { - [SubRemSubKeyNameUp] = {"UP", "ULABEL"}, - [SubRemSubKeyNameDown] = {"DOWN", "DLABEL"}, - [SubRemSubKeyNameLeft] = {"LEFT", "LLABEL"}, - [SubRemSubKeyNameRight] = {"RIGHT", "RLABEL"}, - [SubRemSubKeyNameOk] = {"OK", "OKLABEL"}, -}; - -void subrem_map_preset_reset(SubRemMapPreset* map_preset) { - furi_assert(map_preset); - - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - subrem_sub_file_preset_reset(map_preset->subs_preset[i]); - } -} - -static SubRemLoadMapState subrem_map_preset_check( - SubRemMapPreset* map_preset, - SubGhzTxRx* txrx, - FlipperFormat* fff_data_file) { - furi_assert(map_preset); - furi_assert(txrx); - - bool all_loaded = true; - SubRemLoadMapState ret = SubRemLoadMapStateErrorBrokenFile; - - SubRemLoadSubState sub_loadig_state; - SubRemSubFilePreset* sub_preset; - - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - sub_preset = map_preset->subs_preset[i]; - - sub_loadig_state = SubRemLoadSubStateErrorNoFile; - - if(furi_string_empty(sub_preset->file_path)) { - // FURI_LOG_I(TAG, "Empty file path"); - } else if(!flipper_format_file_open_existing( - fff_data_file, furi_string_get_cstr(sub_preset->file_path))) { - sub_preset->load_state = SubRemLoadSubStateErrorNoFile; - FURI_LOG_W(TAG, "Error open file %s", furi_string_get_cstr(sub_preset->file_path)); - } else { - sub_loadig_state = subrem_sub_preset_load(sub_preset, txrx, fff_data_file); - } - - if(sub_loadig_state != SubRemLoadSubStateOK) { - all_loaded = false; - } else { - ret = SubRemLoadMapStateNotAllOK; - } - - if(ret != SubRemLoadMapStateErrorBrokenFile && all_loaded) { - ret = SubRemLoadMapStateOK; - } - - flipper_format_file_close(fff_data_file); - } - - return ret; -} - -static bool subrem_map_preset_load(SubRemMapPreset* map_preset, FlipperFormat* fff_data_file) { - furi_assert(map_preset); - bool ret = false; - SubRemSubFilePreset* sub_preset; - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - sub_preset = map_preset->subs_preset[i]; - if(!flipper_format_read_string( - fff_data_file, map_file_labels[i][0], sub_preset->file_path)) { -#if FURI_DEBUG - FURI_LOG_W(TAG, "No file patch for %s", map_file_labels[i][0]); -#endif - sub_preset->type = SubGhzProtocolTypeUnknown; - } else if(!path_contains_only_ascii(furi_string_get_cstr(sub_preset->file_path))) { - FURI_LOG_E(TAG, "Incorrect characters in [%s] file path", map_file_labels[i][0]); - sub_preset->type = SubGhzProtocolTypeUnknown; - } else if(!flipper_format_rewind(fff_data_file)) { - // Rewind error - } else if(!flipper_format_read_string( - fff_data_file, map_file_labels[i][1], sub_preset->label)) { -#if FURI_DEBUG - FURI_LOG_W(TAG, "No Label for %s", map_file_labels[i][0]); -#endif - ret = true; - } else { - ret = true; - } - if(ret) { - // Preload seccesful - FURI_LOG_I( - TAG, - "%-5s: %s %s", - map_file_labels[i][0], - furi_string_get_cstr(sub_preset->label), - furi_string_get_cstr(sub_preset->file_path)); - sub_preset->load_state = SubRemLoadSubStatePreloaded; - } - - flipper_format_rewind(fff_data_file); - } - return ret; -} - -SubRemLoadMapState subrem_map_file_load(SubGhzRemoteApp* app, const char* file_path) { - furi_assert(app); - furi_assert(file_path); -#if FURI_DEBUG - FURI_LOG_I(TAG, "Load Map File Start"); -#endif - Storage* storage = furi_record_open(RECORD_STORAGE); - FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); - SubRemLoadMapState ret = SubRemLoadMapStateErrorOpenError; -#if FURI_DEBUG - FURI_LOG_I(TAG, "Open Map File.."); -#endif - subrem_map_preset_reset(app->map_preset); - - if(!flipper_format_file_open_existing(fff_data_file, file_path)) { - FURI_LOG_E(TAG, "Could not open MAP file %s", file_path); - ret = SubRemLoadMapStateErrorOpenError; - } else { - if(!subrem_map_preset_load(app->map_preset, fff_data_file)) { - FURI_LOG_E(TAG, "Could no Sub file path in MAP file"); - // ret = // error for popup - } else if(!flipper_format_file_close(fff_data_file)) { - ret = SubRemLoadMapStateErrorOpenError; - } else { - ret = subrem_map_preset_check(app->map_preset, app->txrx, fff_data_file); - } - } - - if(ret == SubRemLoadMapStateOK) { - FURI_LOG_I(TAG, "Load Map File Seccesful"); - } else if(ret == SubRemLoadMapStateNotAllOK) { - FURI_LOG_I(TAG, "Load Map File Seccesful [Not all files]"); - } else { - FURI_LOG_E(TAG, "Broken Map File"); - } - - flipper_format_file_close(fff_data_file); - flipper_format_free(fff_data_file); - - furi_record_close(RECORD_STORAGE); - return ret; -} - -bool subrem_save_protocol_to_file(FlipperFormat* flipper_format, const char* sub_file_name) { - furi_assert(flipper_format); - furi_assert(sub_file_name); - - Storage* storage = furi_record_open(RECORD_STORAGE); - Stream* flipper_format_stream = flipper_format_get_raw_stream(flipper_format); - - bool saved = false; - uint32_t repeat = 200; - FuriString* file_dir = furi_string_alloc(); - - path_extract_dirname(sub_file_name, file_dir); - do { - // removing additional fields - flipper_format_delete_key(flipper_format, "Repeat"); - // flipper_format_delete_key(flipper_format, "Manufacture"); - - if(!storage_simply_remove(storage, sub_file_name)) { - break; - } - - //ToDo check Write - stream_seek(flipper_format_stream, 0, StreamOffsetFromStart); - stream_save_to_file(flipper_format_stream, storage, sub_file_name, FSOM_CREATE_ALWAYS); - - if(!flipper_format_insert_or_update_uint32(flipper_format, "Repeat", &repeat, 1)) { - FURI_LOG_E(TAG, "Unable Repeat"); - break; - } - - saved = true; - } while(0); - - furi_string_free(file_dir); - furi_record_close(RECORD_STORAGE); - return saved; -} - -void subrem_save_active_sub(void* context) { - furi_assert(context); - SubGhzRemoteApp* app = context; - - SubRemSubFilePreset* sub_preset = app->map_preset->subs_preset[app->chusen_sub]; - subrem_save_protocol_to_file( - sub_preset->fff_data, furi_string_get_cstr(sub_preset->file_path)); -} - -bool subrem_tx_start_sub(SubGhzRemoteApp* app, SubRemSubFilePreset* sub_preset) { - furi_assert(app); - furi_assert(sub_preset); - bool ret = false; - - subrem_tx_stop_sub(app, true); - - if(sub_preset->type == SubGhzProtocolTypeUnknown) { - ret = false; - } else { - FURI_LOG_I(TAG, "Send %s", furi_string_get_cstr(sub_preset->label)); - - subghz_txrx_load_decoder_by_name_protocol( - app->txrx, furi_string_get_cstr(sub_preset->protocaol_name)); - - subghz_txrx_set_preset( - app->txrx, - furi_string_get_cstr(sub_preset->freq_preset.name), - sub_preset->freq_preset.frequency, - NULL, - 0); -#ifndef FW_ORIGIN_Official - subghz_custom_btns_reset(); -#endif - if(subghz_txrx_tx_start(app->txrx, sub_preset->fff_data) == SubGhzTxRxStartTxStateOk) { - ret = true; - } - } - - return ret; -} - -bool subrem_tx_stop_sub(SubGhzRemoteApp* app, bool forced) { - furi_assert(app); - SubRemSubFilePreset* sub_preset = app->map_preset->subs_preset[app->chusen_sub]; - - if(forced || (sub_preset->type != SubGhzProtocolTypeRAW)) { - subghz_txrx_stop(app->txrx); -#ifndef FW_ORIGIN_Official - if(sub_preset->type == SubGhzProtocolTypeDynamic) { - subghz_txrx_reset_dynamic_and_custom_btns(app->txrx); - } - subghz_custom_btns_reset(); -#endif - return true; - } - - return false; -} - -SubRemLoadMapState subrem_load_from_file(SubGhzRemoteApp* app) { - furi_assert(app); - - FuriString* file_path = furi_string_alloc(); - SubRemLoadMapState ret = SubRemLoadMapStateBack; - - DialogsFileBrowserOptions browser_options; - dialog_file_browser_set_basic_options(&browser_options, SUBREM_APP_EXTENSION, &I_subrem_10px); - browser_options.base_path = SUBREM_APP_FOLDER; - - // Input events and views are managed by file_select - if(!dialog_file_browser_show(app->dialogs, app->file_path, app->file_path, &browser_options)) { - } else { - ret = subrem_map_file_load(app, furi_string_get_cstr(app->file_path)); - } - - furi_string_free(file_path); - - return ret; -} - -bool subrem_save_map_to_file(SubGhzRemoteApp* app) { - furi_assert(app); - - const char* file_name = furi_string_get_cstr(app->file_path); - bool saved = false; - FlipperFormat* fff_data = flipper_format_string_alloc(); - - SubRemSubFilePreset* sub_preset; - - flipper_format_write_header_cstr( - fff_data, SUBREM_APP_APP_FILE_TYPE, SUBREM_APP_APP_FILE_VERSION); - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - sub_preset = app->map_preset->subs_preset[i]; - if(!furi_string_empty(sub_preset->file_path)) { - flipper_format_write_string(fff_data, map_file_labels[i][0], sub_preset->file_path); - } - } - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - sub_preset = app->map_preset->subs_preset[i]; - if(!furi_string_empty(sub_preset->file_path)) { - flipper_format_write_string(fff_data, map_file_labels[i][1], sub_preset->label); - } - } - - Storage* storage = furi_record_open(RECORD_STORAGE); - Stream* flipper_format_stream = flipper_format_get_raw_stream(fff_data); - - do { - if(!storage_simply_remove(storage, file_name)) { - break; - } - //ToDo check Write - stream_seek(flipper_format_stream, 0, StreamOffsetFromStart); - stream_save_to_file(flipper_format_stream, storage, file_name, FSOM_CREATE_ALWAYS); - - saved = true; - } while(0); - - furi_record_close(RECORD_STORAGE); - flipper_format_free(fff_data); - - return saved; -} \ No newline at end of file diff --git a/applications/main/subghz_remote/subghz_remote_app_i.h b/applications/main/subghz_remote/subghz_remote_app_i.h deleted file mode 100644 index 2300b3e52..000000000 --- a/applications/main/subghz_remote/subghz_remote_app_i.h +++ /dev/null @@ -1,68 +0,0 @@ -#pragma once - -#include "helpers/subrem_types.h" -#include "helpers/subrem_presets.h" -#include "scenes/subrem_scene.h" - -#include "helpers/txrx/subghz_txrx.h" - -#include "subghz_remote_icons.h" - -#include "views/remote.h" -#include "views/edit_menu.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define SUBREM_APP_FOLDER EXT_PATH("subghz_remote") -#define SUBREM_MAX_LEN_NAME 64 - -typedef struct { - Gui* gui; - ViewDispatcher* view_dispatcher; - SceneManager* scene_manager; - NotificationApp* notifications; - DialogsApp* dialogs; - Widget* widget; - Popup* popup; - TextInput* text_input; - Submenu* submenu; - - FuriString* file_path; - char file_name_tmp[SUBREM_MAX_LEN_NAME]; - - SubRemViewRemote* subrem_remote_view; - SubRemViewEditMenu* subrem_edit_menu; - - SubRemMapPreset* map_preset; - - SubGhzTxRx* txrx; - - bool map_not_saved; - - uint8_t chusen_sub; -} SubGhzRemoteApp; - -SubRemLoadMapState subrem_load_from_file(SubGhzRemoteApp* app); - -bool subrem_tx_start_sub(SubGhzRemoteApp* app, SubRemSubFilePreset* sub_preset); - -bool subrem_tx_stop_sub(SubGhzRemoteApp* app, bool forced); - -SubRemLoadMapState subrem_map_file_load(SubGhzRemoteApp* app, const char* file_path); - -void subrem_map_preset_reset(SubRemMapPreset* map_preset); - -bool subrem_save_map_to_file(SubGhzRemoteApp* app); - -void subrem_save_active_sub(void* context); \ No newline at end of file diff --git a/applications/main/subghz_remote/views/edit_menu.c b/applications/main/subghz_remote/views/edit_menu.c deleted file mode 100644 index 9b88182b5..000000000 --- a/applications/main/subghz_remote/views/edit_menu.c +++ /dev/null @@ -1,290 +0,0 @@ -#include "edit_menu.h" -#include "../subghz_remote_app_i.h" - -#include -#include - -#define subrem_view_edit_menu_MAX_LABEL_LENGTH 12 - -#define FRAME_HEIGHT 12 - -struct SubRemViewEditMenu { - View* view; - SubRemViewEditMenuCallback callback; - void* context; -}; - -typedef struct { - FuriString* label; - FuriString* file_path; - SubRemLoadSubState sub_state; - - uint8_t chusen; -} SubRemViewEditMenuModel; - -void subrem_view_edit_menu_set_callback( - SubRemViewEditMenu* subrem_view_edit_menu, - SubRemViewEditMenuCallback callback, - void* context) { - furi_assert(subrem_view_edit_menu); - - subrem_view_edit_menu->callback = callback; - subrem_view_edit_menu->context = context; -} - -void subrem_view_edit_menu_add_data_to_show( - SubRemViewEditMenu* subrem_view_edit_remote, - uint8_t index, - FuriString* label, - FuriString* path, - SubRemLoadSubState state) { - furi_assert(subrem_view_edit_remote); - - with_view_model( - subrem_view_edit_remote->view, - SubRemViewEditMenuModel * model, - { - model->chusen = index; - if(!furi_string_empty(label)) { - furi_string_set(model->label, label); - } else { - furi_string_set(model->label, "Empty label"); - } - furi_string_set(model->file_path, path); - model->sub_state = state; - }, - true); -} - -uint8_t subrem_view_edit_menu_get_index(SubRemViewEditMenu* subrem_view_edit_remote) { - furi_assert(subrem_view_edit_remote); - uint8_t index; - - with_view_model( - subrem_view_edit_remote->view, - SubRemViewEditMenuModel * model, - { index = model->chusen; }, - true); - return index; -} - -void subrem_view_edit_menu_draw(Canvas* canvas, SubRemViewEditMenuModel* model) { - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - - canvas_clear(canvas); - - // Draw bottom btn - canvas_set_font(canvas, FontSecondary); - elements_button_left(canvas, "Back"); - elements_button_center(canvas, "Edit"); - elements_button_right(canvas, "Save"); - - // Draw top frame - canvas_draw_line(canvas, 1, 0, 125, 0); - canvas_draw_box(canvas, 0, 1, 127, FRAME_HEIGHT - 2); - canvas_draw_line(canvas, 1, FRAME_HEIGHT - 1, 125, FRAME_HEIGHT - 1); - - canvas_set_color(canvas, ColorWhite); - - // Draw btn name - canvas_set_font(canvas, FontPrimary); - switch(model->chusen) { - case SubRemSubKeyNameUp: - canvas_draw_str(canvas, 3, FRAME_HEIGHT - 2, "UP"); - break; - - case SubRemSubKeyNameDown: - canvas_draw_str(canvas, 3, FRAME_HEIGHT - 2, "DOWN"); - break; - - case SubRemSubKeyNameLeft: - canvas_draw_str(canvas, 3, FRAME_HEIGHT - 2, "LEFT"); - break; - - case SubRemSubKeyNameRight: - canvas_draw_str(canvas, 3, FRAME_HEIGHT - 2, "RIGHT"); - break; - - case SubRemSubKeyNameOk: - canvas_draw_str(canvas, 3, FRAME_HEIGHT - 2, "OK"); - break; - - default: - break; - } - - // Draw Label - canvas_set_font(canvas, FontSecondary); - elements_text_box( - canvas, - 38, - 2, - 127 - 38, - FRAME_HEIGHT, - AlignCenter, - AlignBottom, - furi_string_empty(model->label) ? "Empty label" : furi_string_get_cstr(model->label), - true); - - // Draw arrow - canvas_set_color(canvas, ColorBlack); - if(model->chusen != 0) { - canvas_draw_icon(canvas, 119, 13, &I_Pin_arrow_up_7x9); - } - if(model->chusen != 4) { - canvas_draw_icon_ex(canvas, 119, 42, &I_Pin_arrow_up_7x9, IconRotation180); - } - - // Draw file_path - if(model->sub_state == SubRemLoadSubStateOK) { - canvas_set_font(canvas, FontSecondary); - elements_text_box( - canvas, - 1, - FRAME_HEIGHT + 1, - 118, - (63 - FRAME_HEIGHT * 2), - AlignLeft, - AlignTop, - furi_string_get_cstr(model->file_path), - false); - } else if(furi_string_empty(model->file_path)) { - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 1, FRAME_HEIGHT * 2 - 2, "Button not set"); - } else { - canvas_set_font(canvas, FontPrimary); - canvas_draw_str(canvas, 1, FRAME_HEIGHT * 2 - 2, "ERR:"); - canvas_set_font(canvas, FontSecondary); - switch(model->sub_state) { - case SubRemLoadSubStateErrorNoFile: - canvas_draw_str(canvas, 26, FRAME_HEIGHT * 2 - 2, "File not found"); - break; - case SubRemLoadSubStateErrorFreq: - canvas_draw_str(canvas, 26, FRAME_HEIGHT * 2 - 2, "Bad frequency"); - break; - case SubRemLoadSubStateErrorMod: - canvas_draw_str(canvas, 26, FRAME_HEIGHT * 2 - 2, "Bad modulation"); - break; - case SubRemLoadSubStateErrorProtocol: - canvas_draw_str(canvas, 26, FRAME_HEIGHT * 2 - 2, "Unsupported protocol"); - break; - - default: - break; - } - elements_text_box( - canvas, - 1, - FRAME_HEIGHT * 2, - 118, - 30, - AlignLeft, - AlignTop, - furi_string_get_cstr(model->file_path), - false); - } -} - -bool subrem_view_edit_menu_input(InputEvent* event, void* context) { - furi_assert(context); - SubRemViewEditMenu* subrem_view_edit_menu = context; - - if((event->key == InputKeyBack || event->key == InputKeyLeft) && - event->type == InputTypeShort) { - subrem_view_edit_menu->callback( - SubRemCustomEventViewEditMenuBack, subrem_view_edit_menu->context); - return true; - } else if(event->key == InputKeyUp && event->type == InputTypeShort) { - with_view_model( - subrem_view_edit_menu->view, - SubRemViewEditMenuModel * model, - { - if(model->chusen > 0) { - model->chusen -= 1; - }; - }, - true); - subrem_view_edit_menu->callback( - SubRemCustomEventViewEditMenuUP, subrem_view_edit_menu->context); - return true; - } else if(event->key == InputKeyDown && event->type == InputTypeShort) { - with_view_model( - subrem_view_edit_menu->view, - SubRemViewEditMenuModel * model, - { - if(model->chusen < 4) { - model->chusen += 1; - }; - }, - true); - subrem_view_edit_menu->callback( - SubRemCustomEventViewEditMenuDOWN, subrem_view_edit_menu->context); - return true; - } else if(event->key == InputKeyOk && event->type == InputTypeShort) { - subrem_view_edit_menu->callback( - SubRemCustomEventViewEditMenuEdit, subrem_view_edit_menu->context); - return true; - } else if(event->key == InputKeyRight && event->type == InputTypeShort) { - subrem_view_edit_menu->callback( - SubRemCustomEventViewEditMenuSave, subrem_view_edit_menu->context); - return true; - } - - return true; -} - -void subrem_view_edit_menu_enter(void* context) { - furi_assert(context); -} - -void subrem_view_edit_menu_exit(void* context) { - furi_assert(context); -} - -SubRemViewEditMenu* subrem_view_edit_menu_alloc() { - SubRemViewEditMenu* subrem_view_edit_menu = malloc(sizeof(SubRemViewEditMenu)); - - // View allocation and configuration - subrem_view_edit_menu->view = view_alloc(); - view_allocate_model( - subrem_view_edit_menu->view, ViewModelTypeLocking, sizeof(SubRemViewEditMenuModel)); - view_set_context(subrem_view_edit_menu->view, subrem_view_edit_menu); - view_set_draw_callback( - subrem_view_edit_menu->view, (ViewDrawCallback)subrem_view_edit_menu_draw); - view_set_input_callback(subrem_view_edit_menu->view, subrem_view_edit_menu_input); - view_set_enter_callback(subrem_view_edit_menu->view, subrem_view_edit_menu_enter); - view_set_exit_callback(subrem_view_edit_menu->view, subrem_view_edit_menu_exit); - - with_view_model( - subrem_view_edit_menu->view, - SubRemViewEditMenuModel * model, - { - model->label = furi_string_alloc(); // furi_string_alloc_set_str("LABEL"); - model->file_path = furi_string_alloc(); // furi_string_alloc_set_str("FILE_PATH"); - - model->chusen = 0; - }, - true); - return subrem_view_edit_menu; -} - -void subrem_view_edit_menu_free(SubRemViewEditMenu* subghz_edit_menu) { - furi_assert(subghz_edit_menu); - - with_view_model( - subghz_edit_menu->view, - SubRemViewEditMenuModel * model, - { - furi_string_free(model->label); - furi_string_free(model->file_path); - }, - true); - view_free(subghz_edit_menu->view); - free(subghz_edit_menu); -} - -View* subrem_view_edit_menu_get_view(SubRemViewEditMenu* subrem_view_edit_menu) { - furi_assert(subrem_view_edit_menu); - return subrem_view_edit_menu->view; -} \ No newline at end of file diff --git a/applications/main/subghz_remote/views/edit_menu.h b/applications/main/subghz_remote/views/edit_menu.h deleted file mode 100644 index 7ceb7fac0..000000000 --- a/applications/main/subghz_remote/views/edit_menu.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include -#include "../helpers/subrem_custom_event.h" -#include "../helpers/subrem_presets.h" - -typedef struct SubRemViewEditMenu SubRemViewEditMenu; - -typedef void (*SubRemViewEditMenuCallback)(SubRemCustomEvent event, void* context); - -void subrem_view_edit_menu_set_callback( - SubRemViewEditMenu* subrem_view_edit_menu, - SubRemViewEditMenuCallback callback, - void* context); - -SubRemViewEditMenu* subrem_view_edit_menu_alloc(); - -void subrem_view_edit_menu_free(SubRemViewEditMenu* subrem_view_edit_menu); - -View* subrem_view_edit_menu_get_view(SubRemViewEditMenu* subrem_view_edit_menu); - -void subrem_view_edit_menu_add_data_to_show( - SubRemViewEditMenu* subrem_view_edit_remote, - uint8_t index, - FuriString* label, - FuriString* path, - SubRemLoadSubState state); - -uint8_t subrem_view_edit_menu_get_index(SubRemViewEditMenu* subrem_view_edit_remote); \ No newline at end of file diff --git a/applications/main/subghz_remote/views/remote.c b/applications/main/subghz_remote/views/remote.c deleted file mode 100644 index fc7608624..000000000 --- a/applications/main/subghz_remote/views/remote.c +++ /dev/null @@ -1,307 +0,0 @@ -#include "remote.h" -#include "../subghz_remote_app_i.h" - -#include -#include - -#include - -#define SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH 30 -#define SUBREM_VIEW_REMOTE_LEFT_OFFSET 10 -#define SUBREM_VIEW_REMOTE_RIGHT_OFFSET 22 - -struct SubRemViewRemote { - View* view; - SubRemViewRemoteCallback callback; - void* context; -}; - -typedef struct { - char* labels[SubRemSubKeyNameMaxCount]; - - SubRemViewRemoteState state; - - uint8_t pressed_btn; - bool is_external; -} SubRemViewRemoteModel; - -void subrem_view_remote_set_callback( - SubRemViewRemote* subrem_view_remote, - SubRemViewRemoteCallback callback, - void* context) { - furi_assert(subrem_view_remote); - - subrem_view_remote->callback = callback; - subrem_view_remote->context = context; -} - -void subrem_view_remote_update_data_labels( - SubRemViewRemote* subrem_view_remote, - SubRemSubFilePreset** subs_presets) { - furi_assert(subrem_view_remote); - furi_assert(subs_presets); - - FuriString* labels[SubRemSubKeyNameMaxCount]; - SubRemSubFilePreset* sub_preset; - - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - sub_preset = subs_presets[i]; - switch(sub_preset->load_state) { - case SubRemLoadSubStateOK: - if(!furi_string_empty(sub_preset->label)) { - labels[i] = furi_string_alloc_set(sub_preset->label); - } else if(!furi_string_empty(sub_preset->file_path)) { - labels[i] = furi_string_alloc(); - path_extract_filename(sub_preset->file_path, labels[i], true); - } else { - labels[i] = furi_string_alloc_set("Empty Label"); - } - break; - - case SubRemLoadSubStateErrorNoFile: - labels[i] = furi_string_alloc_set("[X] Can't open file"); - break; - - case SubRemLoadSubStateErrorFreq: - case SubRemLoadSubStateErrorMod: - case SubRemLoadSubStateErrorProtocol: - labels[i] = furi_string_alloc_set("[X] Error in .sub file"); - break; - - default: - labels[i] = furi_string_alloc_set(""); - break; - } - } - - with_view_model( - subrem_view_remote->view, - SubRemViewRemoteModel * model, - { - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - strncpy( - model->labels[i], - furi_string_get_cstr(labels[i]), - SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH); - } - }, - true); - - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - furi_string_free(labels[i]); - } -} - -void subrem_view_remote_set_state( - SubRemViewRemote* subrem_view_remote, - SubRemViewRemoteState state, - uint8_t presed_btn) { - furi_assert(subrem_view_remote); - with_view_model( - subrem_view_remote->view, - SubRemViewRemoteModel * model, - { - model->state = state; - model->pressed_btn = presed_btn; - }, - true); -} - -void subrem_view_remote_set_radio(SubRemViewRemote* subrem_view_remote, bool external) { - furi_assert(subrem_view_remote); - with_view_model( - subrem_view_remote->view, - SubRemViewRemoteModel * model, - { model->is_external = external; }, - true); -} - -void subrem_view_remote_draw(Canvas* canvas, SubRemViewRemoteModel* model) { - canvas_clear(canvas); - canvas_set_color(canvas, ColorBlack); - - canvas_clear(canvas); - - //Icons for Labels - //canvas_draw_icon(canvas, 0, 0, &I_SubGHzRemote_LeftAlignedButtons_9x64); - canvas_draw_icon(canvas, 1, 5, &I_ButtonUp_7x4); - canvas_draw_icon(canvas, 1, 15, &I_ButtonDown_7x4); - canvas_draw_icon(canvas, 2, 23, &I_ButtonLeft_4x7); - canvas_draw_icon(canvas, 2, 33, &I_ButtonRight_4x7); - canvas_draw_icon(canvas, 0, 42, &I_Ok_btn_9x9); - canvas_draw_icon(canvas, 0, 53, &I_back_10px); - - //Labels - canvas_set_font(canvas, FontSecondary); - uint8_t y = 0; - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - elements_text_box( - canvas, - SUBREM_VIEW_REMOTE_LEFT_OFFSET, - y + 2, - 126 - SUBREM_VIEW_REMOTE_LEFT_OFFSET - SUBREM_VIEW_REMOTE_RIGHT_OFFSET, - 12, - AlignLeft, - AlignBottom, - model->labels[i], - false); - y += 10; - } - - if(model->state == SubRemViewRemoteStateOFF) { - elements_button_left(canvas, "Back"); - elements_button_right(canvas, "Save"); - } else { - canvas_draw_str_aligned(canvas, 11, 62, AlignLeft, AlignBottom, "Hold=Exit."); - canvas_draw_str_aligned( - canvas, 126, 62, AlignRight, AlignBottom, ((model->is_external) ? "Ext" : "Int")); - } - - //Status text and indicator - canvas_draw_icon(canvas, 113, 15, &I_Pin_cell_13x13); - - if(model->state == SubRemViewRemoteStateIdle || model->state == SubRemViewRemoteStateOFF) { - canvas_draw_str_aligned(canvas, 126, 10, AlignRight, AlignBottom, "Idle"); - } else { - switch(model->state) { - case SubRemViewRemoteStateSending: - canvas_draw_str_aligned(canvas, 126, 10, AlignRight, AlignBottom, "Send"); - break; - case SubRemViewRemoteStateLoading: - canvas_draw_str_aligned(canvas, 126, 10, AlignRight, AlignBottom, "Load"); - break; - default: -#if FURI_DEBUG - canvas_draw_str_aligned(canvas, 126, 10, AlignRight, AlignBottom, "Wrong_state"); -#endif - break; - } - - switch(model->pressed_btn) { - case SubRemSubKeyNameUp: - canvas_draw_icon(canvas, 116, 17, &I_Pin_arrow_up_7x9); - break; - case SubRemSubKeyNameDown: - canvas_draw_icon_ex(canvas, 116, 17, &I_Pin_arrow_up_7x9, IconRotation180); - break; - case SubRemSubKeyNameLeft: - canvas_draw_icon_ex(canvas, 115, 18, &I_Pin_arrow_up_7x9, IconRotation270); - break; - case SubRemSubKeyNameRight: - canvas_draw_icon_ex(canvas, 115, 18, &I_Pin_arrow_up_7x9, IconRotation90); - break; - case SubRemSubKeyNameOk: - canvas_draw_icon(canvas, 116, 18, &I_Pin_star_7x7); - break; - } - } -} - -bool subrem_view_remote_input(InputEvent* event, void* context) { - furi_assert(context); - SubRemViewRemote* subrem_view_remote = context; - - if(event->key == InputKeyBack && event->type == InputTypeLong) { - subrem_view_remote->callback(SubRemCustomEventViewRemoteBack, subrem_view_remote->context); - return true; - } else if(event->key == InputKeyBack && event->type == InputTypeShort) { - with_view_model( - subrem_view_remote->view, - SubRemViewRemoteModel * model, - { model->pressed_btn = 0; }, - true); - subrem_view_remote->callback( - SubRemCustomEventViewRemoteForcedStop, subrem_view_remote->context); - return true; - } else if(event->key == InputKeyBack) { - return true; - } - // BACK button processing end - - if(event->key == InputKeyUp && event->type == InputTypePress) { - subrem_view_remote->callback( - SubRemCustomEventViewRemoteStartUP, subrem_view_remote->context); - return true; - } else if(event->key == InputKeyDown && event->type == InputTypePress) { - subrem_view_remote->callback( - SubRemCustomEventViewRemoteStartDOWN, subrem_view_remote->context); - return true; - } else if(event->key == InputKeyLeft && event->type == InputTypePress) { - subrem_view_remote->callback( - SubRemCustomEventViewRemoteStartLEFT, subrem_view_remote->context); - return true; - } else if(event->key == InputKeyRight && event->type == InputTypePress) { - subrem_view_remote->callback( - SubRemCustomEventViewRemoteStartRIGHT, subrem_view_remote->context); - return true; - } else if(event->key == InputKeyOk && event->type == InputTypePress) { - subrem_view_remote->callback( - SubRemCustomEventViewRemoteStartOK, subrem_view_remote->context); - return true; - } else if(event->type == InputTypeRelease) { - subrem_view_remote->callback(SubRemCustomEventViewRemoteStop, subrem_view_remote->context); - return true; - } - - return true; -} - -void subrem_view_remote_enter(void* context) { - furi_assert(context); -} - -void subrem_view_remote_exit(void* context) { - furi_assert(context); -} - -SubRemViewRemote* subrem_view_remote_alloc() { - SubRemViewRemote* subrem_view_remote = malloc(sizeof(SubRemViewRemote)); - - // View allocation and configuration - subrem_view_remote->view = view_alloc(); - view_allocate_model( - subrem_view_remote->view, ViewModelTypeLocking, sizeof(SubRemViewRemoteModel)); - view_set_context(subrem_view_remote->view, subrem_view_remote); - view_set_draw_callback(subrem_view_remote->view, (ViewDrawCallback)subrem_view_remote_draw); - view_set_input_callback(subrem_view_remote->view, subrem_view_remote_input); - view_set_enter_callback(subrem_view_remote->view, subrem_view_remote_enter); - view_set_exit_callback(subrem_view_remote->view, subrem_view_remote_exit); - - with_view_model( - subrem_view_remote->view, - SubRemViewRemoteModel * model, - { - model->state = SubRemViewRemoteStateIdle; - - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - model->labels[i] = malloc(sizeof(char) * SUBREM_VIEW_REMOTE_MAX_LABEL_LENGTH + 1); - strcpy(model->labels[i], ""); - } - - model->pressed_btn = 0; - model->is_external = false; - }, - true); - return subrem_view_remote; -} - -void subrem_view_remote_free(SubRemViewRemote* subghz_remote) { - furi_assert(subghz_remote); - - with_view_model( - subghz_remote->view, - SubRemViewRemoteModel * model, - { - for(uint8_t i = 0; i < SubRemSubKeyNameMaxCount; i++) { - free(model->labels[i]); - } - }, - true); - view_free(subghz_remote->view); - free(subghz_remote); -} - -View* subrem_view_remote_get_view(SubRemViewRemote* subrem_view_remote) { - furi_assert(subrem_view_remote); - return subrem_view_remote->view; -} \ No newline at end of file diff --git a/applications/main/subghz_remote/views/remote.h b/applications/main/subghz_remote/views/remote.h deleted file mode 100644 index 39f9a007d..000000000 --- a/applications/main/subghz_remote/views/remote.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include -#include "../helpers/subrem_custom_event.h" -#include "../helpers/subrem_presets.h" - -typedef enum { - SubRemViewRemoteStateIdle, - SubRemViewRemoteStateLoading, - SubRemViewRemoteStateSending, - SubRemViewRemoteStateOFF, -} SubRemViewRemoteState; - -typedef struct SubRemViewRemote SubRemViewRemote; - -typedef void (*SubRemViewRemoteCallback)(SubRemCustomEvent event, void* context); - -void subrem_view_remote_set_callback( - SubRemViewRemote* subrem_view_remote, - SubRemViewRemoteCallback callback, - void* context); - -SubRemViewRemote* subrem_view_remote_alloc(); - -void subrem_view_remote_free(SubRemViewRemote* subrem_view_remote); - -View* subrem_view_remote_get_view(SubRemViewRemote* subrem_view_remote); - -void subrem_view_remote_update_data_labels( - SubRemViewRemote* subrem_view_remote, - SubRemSubFilePreset** subs_presets); - -void subrem_view_remote_set_state( - SubRemViewRemote* subrem_view_remote, - SubRemViewRemoteState state, - uint8_t presed_btn); - -void subrem_view_remote_set_radio(SubRemViewRemote* subrem_view_remote, bool external); \ No newline at end of file From 654b3245c27537ff3ad105ed0dcd7605f0be24ee Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 4 Sep 2023 23:14:07 +0300 Subject: [PATCH 43/59] fix module p2 --- .gitmodules | 2 +- applications/main/subghz_remote | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 160000 applications/main/subghz_remote diff --git a/.gitmodules b/.gitmodules index e68c05465..6f73e125a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -40,5 +40,5 @@ url = https://github.com/flipperdevices/stm32wb_copro.git [submodule "subghz_remote"] path = applications/main/subghz_remote - url = https://github.com/DarkFlippers/SubGHz_Remote + url = https://github.com/DarkFlippers/SubGHz_Remote.git branch = ufw_main_app diff --git a/applications/main/subghz_remote b/applications/main/subghz_remote new file mode 160000 index 000000000..64a21d952 --- /dev/null +++ b/applications/main/subghz_remote @@ -0,0 +1 @@ +Subproject commit 64a21d9521161268407f44395302d15d5c37b89e From 1cafa9a46bad33ba323314bb2fabd36ddf29d7a9 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 4 Sep 2023 23:15:23 +0300 Subject: [PATCH 44/59] Fix naming var --- applications/main/subghz_remote | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/main/subghz_remote b/applications/main/subghz_remote index 64a21d952..208134409 160000 --- a/applications/main/subghz_remote +++ b/applications/main/subghz_remote @@ -1 +1 @@ -Subproject commit 64a21d9521161268407f44395302d15d5c37b89e +Subproject commit 2081344093ee4d1f72d2de6335884cc5e2d5952a From 2a789ae1c1996e40a9e3d6e69b93c2dd00f8a250 Mon Sep 17 00:00:00 2001 From: Eng1n33r <101719414+Eng1n33r@users.noreply.github.com> Date: Mon, 4 Sep 2023 23:55:08 +0300 Subject: [PATCH 45/59] faac beta-3 --- lib/subghz/protocols/faac_slh.c | 137 ++++++++++++-------------------- 1 file changed, 50 insertions(+), 87 deletions(-) diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index 1cddcec85..14e3b1789 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -8,8 +8,6 @@ #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 = { @@ -112,42 +110,18 @@ void subghz_protocol_encoder_faac_slh_free(void* context) { } static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* instance) { - // 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(); - ProgMode prog_mode_btn_status = subghz_custom_btn_get_prog_mode(); - bool button_for_programming = false; - - FURI_LOG_I("GENDATA", "CUSTOMBTN: %d\r", subghz_custom_btn_get()); - - // If custom button left is pressed, enable programming mode and disable it on Ok button - if((custom_btn_id == SUBGHZ_CUSTOM_BTN_OK)) { - if(prog_mode_btn_status == PROG_MODE_FAAC_SLH) { - button_for_programming = false; - prog_mode_btn_status = PROG_MODE_OFF; - } - } else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_UP) { - button_for_programming = true; - prog_mode_btn_status = PROG_MODE_FAAC_SLH; - } - subghz_custom_btn_set_prog_mode(prog_mode_btn_status); - FURI_LOG_I("FAAC", "Button for programming: %d\r", button_for_programming); - FURI_LOG_I("FAAC", "Programming mode: %d\r", instance->generic.prg_mode); - - if(button_for_programming) { + if(instance->generic.allow_zero_seed || (instance->generic.seed != 0x0)) { + instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); + FURI_LOG_I(TAG, "Counter ++"); + } else if(instance->generic.prg_mode == true) { uint8_t data_tmp = 0; uint8_t data_prg[8]; + instance->generic.cnt_2++; + data_prg[0] = 0x00; - if(instance->generic.allow_zero_seed || (instance->generic.seed != 0x0)) { - instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); - } - - data_prg[1] = instance->generic.cnt & 0xFF; + data_prg[1] = instance->generic.cnt_2; data_prg[2] = (uint8_t)(instance->generic.seed & 0xFF); data_prg[3] = (uint8_t)(instance->generic.seed >> 8 & 0xFF); @@ -159,30 +133,27 @@ static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* inst 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]; + 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[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]; + 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_I(TAG, "New MasterKey encrypted : %016llX\r", instance->generic.data); + FURI_LOG_I(TAG, "New MasterKey encrypted : %016llX", instance->generic.data); return true; } else { - if(!instance->generic.allow_zero_seed && (instance->generic.seed == 0x0)) { - // Do not generate new data, send data from buffer - return true; - } + // Do not generate new data, send data from buffer + FURI_LOG_I(TAG, "Unknown / Static mode"); + return true; } uint32_t fix = instance->generic.serial << 4 | instance->generic.btn; uint32_t hop = 0; @@ -194,11 +165,6 @@ static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* inst for(int i = 0; i < 8; i++) { fixx[i] = (fix >> (shiftby -= 4)) & 0xF; } - - if(instance->generic.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); @@ -319,8 +285,10 @@ SubGhzProtocolStatus bool allow_zero_seed; if(flipper_format_read_bool(flipper_format, "AllowZeroSeed", &allow_zero_seed, 1)) { instance->generic.allow_zero_seed = true; + FURI_LOG_I(TAG, "Enc. des. TRUE"); } else { instance->generic.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 | @@ -484,16 +452,11 @@ 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; - // 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); - FURI_LOG_I("RMC", "CUSTOMBTN: %d\r", subghz_custom_btn_get()); uint8_t data_tmp = 0; uint8_t data_prg[8]; data_prg[0] = (code_hop & 0xFF); @@ -505,37 +468,36 @@ static void subghz_protocol_faac_slh_check_remote_controller( 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))) { + if( (data_prg[7] == 0x52) && (data_prg[6] == 0x0F) && (data_prg[0] == 0x00) ) { instance->prg_mode = true; // ProgMode ON + FURI_LOG_I(TAG, "Master Key detected!"); + 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]; + data_tmp = data_prg[2]; - *manufacture_name = "FAAC_SLH"; - return; + 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]; + 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->serial = code_fix >> 4; - instance->btn = code_fix & 0xF; - instance->prg_mode = false; - } + } for M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) { @@ -618,8 +580,10 @@ SubGhzProtocolStatus bool allow_zero_seed; if(flipper_format_read_bool(flipper_format, "AllowZeroSeed", &allow_zero_seed, 1)) { instance->generic.allow_zero_seed = true; + FURI_LOG_I(TAG, "Dec. des. TRUE"); } else { instance->generic.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 | seed_data[3]; @@ -646,7 +610,6 @@ void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* outp 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", @@ -657,7 +620,7 @@ 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, instance->generic.seed, - (uint8_t)(instance->generic.cnt & 0xFF)); + instance->generic.cnt_2); } else if(instance->generic.allow_zero_seed == false) { furi_string_cat_printf( output, From 0eb06ba2b7c696751a42a54c41a38b10f939d10f Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 5 Sep 2023 05:31:03 +0300 Subject: [PATCH 46/59] Actually working progmode, new add manually options + bonus fixes --- .../main/subghz/helpers/subghz_custom_event.h | 2 + .../main/subghz/helpers/subghz_txrx.c | 2 + .../subghz/scenes/subghz_scene_save_name.c | 7 +- .../main/subghz/scenes/subghz_scene_set_cnt.c | 8 +- .../main/subghz/scenes/subghz_scene_set_fix.c | 2 +- .../subghz/scenes/subghz_scene_set_seed.c | 10 +- .../subghz/scenes/subghz_scene_set_type.c | 60 +++++- .../subghz/scenes/subghz_scene_transmitter.c | 5 +- lib/subghz/blocks/custom_btn.c | 2 +- lib/subghz/blocks/custom_btn_i.h | 3 +- lib/subghz/blocks/generic.h | 2 - lib/subghz/protocols/faac_slh.c | 190 ++++++++++++------ lib/subghz/protocols/faac_slh.h | 4 + 13 files changed, 208 insertions(+), 89 deletions(-) diff --git a/applications/main/subghz/helpers/subghz_custom_event.h b/applications/main/subghz/helpers/subghz_custom_event.h index e5321264e..d59d0ea3c 100644 --- a/applications/main/subghz/helpers/subghz_custom_event.h +++ b/applications/main/subghz/helpers/subghz_custom_event.h @@ -6,6 +6,8 @@ typedef enum { SubGhzCustomEventManagerSetRAW, //SubmenuIndex + SubmenuIndexFaacSLH_Manual_433, + SubmenuIndexFaacSLH_Manual_868, SubmenuIndexFaacSLH_433, SubmenuIndexFaacSLH_868, SubmenuIndexBFTClone, diff --git a/applications/main/subghz/helpers/subghz_txrx.c b/applications/main/subghz/helpers/subghz_txrx.c index 5c36a781a..0f8a8da32 100644 --- a/applications/main/subghz/helpers/subghz_txrx.c +++ b/applications/main/subghz/helpers/subghz_txrx.c @@ -665,6 +665,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(); } diff --git a/applications/main/subghz/scenes/subghz_scene_save_name.c b/applications/main/subghz/scenes/subghz_scene_save_name.c index f523aaddf..6320c12f2 100644 --- a/applications/main/subghz/scenes/subghz_scene_save_name.c +++ b/applications/main/subghz/scenes/subghz_scene_save_name.c @@ -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); } } - 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; } else if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubGhzCustomEventSceneSaveName) { diff --git a/applications/main/subghz/scenes/subghz_scene_set_cnt.c b/applications/main/subghz/scenes/subghz_scene_set_cnt.c index 008ffa1ad..0a07557fb 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_cnt.c +++ b/applications/main/subghz/scenes/subghz_scene_set_cnt.c @@ -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 [20 bits]"); + 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, diff --git a/applications/main/subghz/scenes/subghz_scene_set_fix.c b/applications/main/subghz/scenes/subghz_scene_set_fix.c index 7564fb24d..b58f39ddd 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_fix.c +++ b/applications/main/subghz/scenes/subghz_scene_set_fix.c @@ -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, diff --git a/applications/main/subghz/scenes/subghz_scene_set_seed.c b/applications/main/subghz/scenes/subghz_scene_set_seed.c index f7727f0d6..c1f3662cb 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_seed.c +++ b/applications/main/subghz/scenes/subghz_scene_set_seed.c @@ -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, @@ -62,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]; @@ -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 | 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( subghz->txrx, "AM650", @@ -83,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", diff --git a/applications/main/subghz/scenes/subghz_scene_set_type.c b/applications/main/subghz/scenes/subghz_scene_set_type.c index e5a92608e..9f5b61499 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_type.c +++ b/applications/main/subghz/scenes/subghz_scene_set_type.c @@ -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) { 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( subghz->submenu, "Faac SLH 868MHz", @@ -25,12 +43,6 @@ 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", @@ -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, diff --git a/applications/main/subghz/scenes/subghz_scene_transmitter.c b/applications/main/subghz/scenes/subghz_scene_transmitter.c index 5f1be6c21..bb51c073d 100644 --- a/applications/main/subghz/scenes/subghz_scene_transmitter.c +++ b/applications/main/subghz/scenes/subghz_scene_transmitter.c @@ -20,7 +20,6 @@ bool subghz_scene_transmitter_update_data_show(void* context) { FuriString* frequency_str = furi_string_alloc(); FuriString* modulation_str = furi_string_alloc(); - if(subghz_protocol_decoder_base_deserialize( decoder, subghz_txrx_get_fff_data(subghz->txrx)) == SubGhzProtocolStatusOk) { 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! 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); } return true; diff --git a/lib/subghz/blocks/custom_btn.c b/lib/subghz/blocks/custom_btn.c index 1919fc5e4..e33f79887 100644 --- a/lib/subghz/blocks/custom_btn.c +++ b/lib/subghz/blocks/custom_btn.c @@ -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; -} \ No newline at end of file +} diff --git a/lib/subghz/blocks/custom_btn_i.h b/lib/subghz/blocks/custom_btn_i.h index 2aadba6f4..33ea6be9f 100644 --- a/lib/subghz/blocks/custom_btn_i.h +++ b/lib/subghz/blocks/custom_btn_i.h @@ -5,7 +5,6 @@ #define PROG_MODE_OFF (0U) #define PROG_MODE_KEELOQ_BFT (1U) #define PROG_MODE_KEELOQ_APRIMATIC (2U) -#define PROG_MODE_FAAC_SLH (3U) 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); -ProgMode subghz_custom_btn_get_prog_mode(); \ No newline at end of file +ProgMode subghz_custom_btn_get_prog_mode(); diff --git a/lib/subghz/blocks/generic.h b/lib/subghz/blocks/generic.h index 19c5f3fbe..10e7b63fa 100644 --- a/lib/subghz/blocks/generic.h +++ b/lib/subghz/blocks/generic.h @@ -25,8 +25,6 @@ struct SubGhzBlockGeneric { uint32_t cnt; uint8_t cnt_2; uint32_t seed; - bool prg_mode : 1; - bool allow_zero_seed : 1; }; /** diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index 14e3b1789..702dcb537 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -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,18 +124,35 @@ void subghz_protocol_encoder_faac_slh_free(void* context) { } static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* instance) { - if(instance->generic.allow_zero_seed || (instance->generic.seed != 0x0)) { - instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); - FURI_LOG_I(TAG, "Counter ++"); - } else if(instance->generic.prg_mode == true) { + // 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(); + 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_prg[8]; - instance->generic.cnt_2++; - 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[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[5] ^= data_prg[1]; - for(uint8_t i=data_prg[1] & 0x0F ; i!=0; i--) { - data_tmp = data_prg[5]; + 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[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]; + 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_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; } else { - // Do not generate new data, send data from buffer - FURI_LOG_I(TAG, "Unknown / Static mode"); - return true; + 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; @@ -165,6 +211,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); @@ -211,7 +262,7 @@ bool subghz_protocol_faac_slh_create_data( instance->generic.seed = seed; instance->manufacture_name = manufacture_name; 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); if(res) { return SubGhzProtocolStatusOk == @@ -282,13 +333,11 @@ SubGhzProtocolStatus FURI_LOG_E(TAG, "Missing Seed"); break; } - bool allow_zero_seed; - if(flipper_format_read_bool(flipper_format, "AllowZeroSeed", &allow_zero_seed, 1)) { - instance->generic.allow_zero_seed = true; - FURI_LOG_I(TAG, "Enc. des. TRUE"); + bool tmp_allow_zero_seed; + if(flipper_format_read_bool(flipper_format, "AllowZeroSeed", &tmp_allow_zero_seed, 1)) { + allow_zero_seed = true; } else { - instance->generic.allow_zero_seed = false; - FURI_LOG_I(TAG, "Enc. des. FALSE"); + allow_zero_seed = false; } 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) { 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); @@ -468,36 +522,40 @@ static void subghz_protocol_faac_slh_check_remote_controller( 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) ) { - instance->prg_mode = true; + if(((data_prg[7] == 0x52) && (data_prg[6] == 0x0F) && (data_prg[0] == 0x00))) { + faac_prog_mode = true; // ProgMode ON - FURI_LOG_I(TAG, "Master Key detected!"); - 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[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[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) { @@ -512,6 +570,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) { @@ -530,6 +592,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); @@ -577,13 +640,11 @@ SubGhzProtocolStatus FURI_LOG_E(TAG, "Missing Seed"); break; } - bool allow_zero_seed; - if(flipper_format_read_bool(flipper_format, "AllowZeroSeed", &allow_zero_seed, 1)) { - instance->generic.allow_zero_seed = true; - FURI_LOG_I(TAG, "Dec. des. TRUE"); + bool tmp_allow_zero_seed; + if(flipper_format_read_bool(flipper_format, "AllowZeroSeed", &tmp_allow_zero_seed, 1)) { + allow_zero_seed = true; } else { - instance->generic.allow_zero_seed = false; - FURI_LOG_I(TAG, "Dec. des. FALSE"); + allow_zero_seed = false; } instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 | 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_hop = instance->generic.data & 0xFFFFFFFF; - if(instance->generic.prg_mode == true) { + 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", @@ -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, instance->generic.seed, - instance->generic.cnt_2); - } else if(instance->generic.allow_zero_seed == false) { + (uint8_t)(instance->generic.cnt & 0xFF)); + } else if(allow_zero_seed == false) { furi_string_cat_printf( output, "%s %dbit\r\n" diff --git a/lib/subghz/protocols/faac_slh.h b/lib/subghz/protocols/faac_slh.h index bab042ca6..8d03d7907 100644 --- a/lib/subghz/protocols/faac_slh.h +++ b/lib/subghz/protocols/faac_slh.h @@ -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(); \ No newline at end of file From ffc6f726f00992397dc2417952f44c5ef417a2e6 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 5 Sep 2023 05:43:06 +0300 Subject: [PATCH 47/59] fix small bug --- lib/subghz/protocols/faac_slh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index 702dcb537..be52983c4 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -139,7 +139,7 @@ static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* inst 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) { + if(button_for_programming && !(!allow_zero_seed && (instance->generic.seed == 0x0))) { uint8_t data_tmp = 0; uint8_t data_prg[8]; From b24fba6ad702214ef98907486127e59ab60c28ca Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 5 Sep 2023 05:44:09 +0300 Subject: [PATCH 48/59] just in case --- .../main/subghz/helpers/subghz_txrx_create_protocol_key.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c index 149d1d711..040aff46c 100644 --- a/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c +++ b/applications/main/subghz/helpers/subghz_txrx_create_protocol_key.c @@ -228,9 +228,9 @@ bool subghz_txrx_gen_faac_slh_protocol( seed_data[sizeof(uint32_t) - i - 1] = (seed >> i * 8) & 0xFF; } - bool allow_zero_seed = true; + 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", &allow_zero_seed, 1); + flipper_format_write_bool(txrx->fff_data, "AllowZeroSeed", &tmp_allow_zero_seed, 1); } subghz_transmitter_free(txrx->transmitter); From 1653abe0ef6eea03da1b4c8e73707fbf69f7de62 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 5 Sep 2023 05:51:21 +0300 Subject: [PATCH 49/59] Remove unused table --- applications/debug/unit_tests/subghz/subghz_test.c | 2 -- applications/main/subghz/helpers/subghz_txrx.c | 2 -- applications/main/subghz/subghz_cli.c | 4 ---- applications/main/subghz_remote | 2 +- assets/resources/subghz/assets/came_atomo | 6 ------ lib/subghz/environment.c | 11 ++++------- 6 files changed, 5 insertions(+), 22 deletions(-) delete mode 100644 assets/resources/subghz/assets/came_atomo diff --git a/applications/debug/unit_tests/subghz/subghz_test.c b/applications/debug/unit_tests/subghz/subghz_test.c index 1900f2045..80a1c1040 100644 --- a/applications/debug/unit_tests/subghz/subghz_test.c +++ b/applications/debug/unit_tests/subghz/subghz_test.c @@ -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( diff --git a/applications/main/subghz/helpers/subghz_txrx.c b/applications/main/subghz/helpers/subghz_txrx.c index 0f8a8da32..c3f8ad445 100644 --- a/applications/main/subghz/helpers/subghz_txrx.c +++ b/applications/main/subghz/helpers/subghz_txrx.c @@ -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( diff --git a/applications/main/subghz/subghz_cli.c b/applications/main/subghz/subghz_cli.c index b11359413..177dad1ac 100644 --- a/applications/main/subghz/subghz_cli.c +++ b/applications/main/subghz/subghz_cli.c @@ -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( diff --git a/applications/main/subghz_remote b/applications/main/subghz_remote index 208134409..a905d701e 160000 --- a/applications/main/subghz_remote +++ b/applications/main/subghz_remote @@ -1 +1 @@ -Subproject commit 2081344093ee4d1f72d2de6335884cc5e2d5952a +Subproject commit a905d701ee357f9d019ea496222626f102604be3 diff --git a/assets/resources/subghz/assets/came_atomo b/assets/resources/subghz/assets/came_atomo deleted file mode 100644 index 0952f3f20..000000000 --- a/assets/resources/subghz/assets/came_atomo +++ /dev/null @@ -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 \ No newline at end of file diff --git a/lib/subghz/environment.c b/lib/subghz/environment.c index b69494e66..33a78cfdd 100644 --- a/lib/subghz/environment.c +++ b/lib/subghz/environment.c @@ -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); @@ -53,15 +50,15 @@ 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; + // 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; + // No table, sorry + return ""; } void subghz_environment_set_alutech_at_4n_rainbow_table_file_name( From 1859b06b6afe5078b419493366fccac3d48805b4 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 5 Sep 2023 05:59:21 +0300 Subject: [PATCH 50/59] oops --- lib/subghz/environment.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/subghz/environment.c b/lib/subghz/environment.c index 33a78cfdd..7b1e87b41 100644 --- a/lib/subghz/environment.c +++ b/lib/subghz/environment.c @@ -49,14 +49,15 @@ 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); + UNUSED(instance); + UNUSED(filename); // Do nothing :) return; } const char* subghz_environment_get_came_atomo_rainbow_table_file_name(SubGhzEnvironment* instance) { - furi_assert(instance); + UNUSED(instance); // No table, sorry return ""; } From b3cce2351a704fa70b6f348e92612b5d05462d32 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 5 Sep 2023 14:40:49 +0300 Subject: [PATCH 51/59] Some faac fixes --- lib/subghz/protocols/faac_slh.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index be52983c4..2044d9d20 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -130,16 +130,10 @@ static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* inst } 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 && !(!allow_zero_seed && (instance->generic.seed == 0x0))) { + 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]; @@ -683,7 +677,7 @@ void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* outp (uint32_t)instance->generic.data_2, instance->generic.seed, (uint8_t)(instance->generic.cnt & 0xFF)); - } else if(allow_zero_seed == false) { + } else if((allow_zero_seed == false) && (instance->generic.seed == 0x0)) { furi_string_cat_printf( output, "%s %dbit\r\n" From 452e27b05ed26fb76f0d3f3ff14d4dcb2e46aa7e Mon Sep 17 00:00:00 2001 From: hedger Date: Tue, 5 Sep 2023 14:49:39 +0300 Subject: [PATCH 52/59] github: workflow improvements (#3032) * github: compact build: status reporting step * github: build: matrix strategy * debugging * github: added version_token to /uploadfiles request * github: reworked main build flow * github: suppressed non-zero cp status * github: build: fixed comment lookup; experimental changes to apps build order * github: removed summary step for compact builds; united map analyzer steps * fbt: added get_apiversion target; moved ext apps processing logic to AppBuildset * ufbt: added missing global * fbt: Moved incompatible app list to firmware config output * fbt: cleaner extapps processing * github: build: added automation for SDK publishing --- .github/workflows/build.yml | 128 +++++++++++++++++----------- .github/workflows/build_compact.yml | 9 ++ firmware.scons | 14 ++- scripts/fbt/appmanifest.py | 49 ++++++++++- scripts/fbt/sdk/cache.py | 15 ++++ scripts/fbt_tools/fbt_apps.py | 9 +- scripts/ufbt/SConstruct | 1 + site_scons/extapps.scons | 30 +------ 8 files changed, 167 insertions(+), 88 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 07b219712..510542c3a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,13 +9,15 @@ on: pull_request: env: - TARGETS: f7 f18 DEFAULT_TARGET: f7 FBT_TOOLCHAIN_PATH: /runner/_work jobs: main: runs-on: [self-hosted, FlipperZeroShell] + strategy: + matrix: + target: [f7, f18] steps: - name: 'Wipe workspace' run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; @@ -33,68 +35,69 @@ jobs: TYPE="pull" elif [[ "${{ github.ref }}" == "refs/tags/"* ]]; then TYPE="tag" + echo 'FBT_BUILD_TYPE="DEBUG=0 COMPACT=1"' >> $GITHUB_ENV else TYPE="other" fi python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE" || cat "${{ github.event_path }}" echo "event_type=$TYPE" >> $GITHUB_OUTPUT + echo "TARGET=${{ matrix.target }}" >> $GITHUB_ENV + echo "TARGET_HW=$(echo "${{ matrix.target }}" | sed 's/f//')" >> $GITHUB_ENV - - name: 'Check API versions' + - name: 'Check API versions for consistency between targets' run: | set -e N_API_HEADER_SIGNATURES=`ls -1 firmware/targets/f*/api_symbols.csv | xargs -I {} sh -c "head -n2 {} | md5sum" | sort -u | wc -l` if [ $N_API_HEADER_SIGNATURES != 1 ] ; then echo API versions aren\'t matching for available targets. Please update! + echo API versions are: head -n2 firmware/targets/f*/api_symbols.csv exit 1 fi - - name: 'Make artifacts directory' + - name: 'Build the firmware and apps' run: | - rm -rf artifacts map_analyser_files - mkdir artifacts map_analyser_files + ./fbt TARGET_HW=$TARGET_HW $FBT_BUILD_TYPE copro_dist updater_package fap_dist - - name: 'Bundle scripts' - if: ${{ !github.event.pull_request.head.repo.fork }} - run: | - tar czpf "artifacts/flipper-z-any-scripts-${SUFFIX}.tgz" scripts - - - name: 'Build the firmware' - run: | - set -e - for TARGET in ${TARGETS}; do - TARGET_HW="$(echo "${TARGET}" | sed 's/f//')"; \ - ./fbt TARGET_HW=$TARGET_HW copro_dist updater_package \ - ${{ startsWith(github.ref, 'refs/tags') && 'DEBUG=0 COMPACT=1' || '' }} - mv dist/${TARGET}-*/* artifacts/ - tar czpf "artifacts/flipper-z-${TARGET}-resources-${SUFFIX}.tgz" \ - -C assets resources - ./fbt TARGET_HW=$TARGET_HW fap_dist - tar czpf "artifacts/flipper-z-${TARGET}-debugapps-${SUFFIX}.tgz" \ - -C dist/${TARGET}-*/apps/Debug . - tar czpf "artifacts/flipper-z-${TARGET}-appsymbols-${SUFFIX}.tgz" \ - -C dist/${TARGET}-*/debug_elf . - done - - - name: "Check for uncommitted changes" + - name: 'Check for uncommitted changes' run: | git diff --exit-code - - name: 'Bundle core2 firmware' - if: ${{ !github.event.pull_request.head.repo.fork }} + - name: 'Copy build output' run: | + set -e + rm -rf artifacts map_analyser_files || true + mkdir artifacts map_analyser_files + cp dist/${TARGET}-*/* artifacts/ || true + tar czpf "artifacts/flipper-z-${TARGET}-resources-${SUFFIX}.tgz" \ + -C assets resources + tar czpf "artifacts/flipper-z-${TARGET}-debugapps-${SUFFIX}.tgz" \ + -C dist/${TARGET}-*/apps/Debug . + tar czpf "artifacts/flipper-z-${TARGET}-appsymbols-${SUFFIX}.tgz" \ + -C dist/${TARGET}-*/debug_elf . + + - name: 'Copy universal artifacts' + if: ${{ !github.event.pull_request.head.repo.fork && matrix.target == env.DEFAULT_TARGET }} + run: | + tar czpf "artifacts/flipper-z-any-scripts-${SUFFIX}.tgz" scripts cp build/core2_firmware.tgz "artifacts/flipper-z-any-core2_firmware-${SUFFIX}.tgz" - - name: 'Copy map analyser files' + - name: 'Upload artifacts to update server' if: ${{ !github.event.pull_request.head.repo.fork }} + run: | + FILES=$(for ARTIFACT in $(find artifacts -maxdepth 1 -not -type d); do echo "-F files=@${ARTIFACT}"; done) + curl --fail -L -H "Token: ${{ secrets.INDEXER_TOKEN }}" \ + -F "branch=${BRANCH_NAME}" \ + -F "version_token=${COMMIT_SHA}" \ + ${FILES[@]} \ + "${{ secrets.INDEXER_URL }}"/firmware/uploadfiles + + - name: 'Copy & analyse map analyser files' + if: ${{ !github.event.pull_request.head.repo.fork && matrix.target == env.DEFAULT_TARGET }} run: | cp build/${DEFAULT_TARGET}-firmware-*/firmware.elf.map map_analyser_files/firmware.elf.map cp build/${DEFAULT_TARGET}-firmware-*/firmware.elf map_analyser_files/firmware.elf cp ${{ github.event_path }} map_analyser_files/event.json - - - name: 'Analyse map file' - if: ${{ !github.event.pull_request.head.repo.fork }} - run: | source scripts/toolchain/fbtenv.sh get_size() { @@ -118,33 +121,56 @@ jobs: ${{ secrets.AMAP_MARIADB_DATABASE }} \ map_analyser_files/firmware.elf.map.all - - name: 'Upload artifacts to update server' - if: ${{ !github.event.pull_request.head.repo.fork }} - run: | - FILES=$(for CUR in $(ls artifacts/); do echo "-F files=@artifacts/$CUR"; done) - curl --fail -L -H "Token: ${{ secrets.INDEXER_TOKEN }}" \ - -F "branch=${BRANCH_NAME}" \ - ${FILES[@]} \ - "${{ secrets.INDEXER_URL }}"/firmware/uploadfiles - - - name: 'Find Previous Comment' - if: ${{ !github.event.pull_request.head.repo.fork && github.event.pull_request }} + - name: 'Find previous comment' + if: ${{ !github.event.pull_request.head.repo.fork && matrix.target == env.DEFAULT_TARGET && github.event.pull_request }} uses: peter-evans/find-comment@v2 - id: fc + id: find-comment with: issue-number: ${{ github.event.pull_request.number }} comment-author: 'github-actions[bot]' - body-includes: 'Compiled firmware for commit' + body-includes: 'Compiled ${{ matrix.target }} firmware for commit' - name: 'Create or update comment' - if: ${{ !github.event.pull_request.head.repo.fork && github.event.pull_request}} + if: ${{ !github.event.pull_request.head.repo.fork && matrix.target == env.DEFAULT_TARGET && github.event.pull_request }} uses: peter-evans/create-or-update-comment@v3 with: - comment-id: ${{ steps.fc.outputs.comment-id }} + comment-id: ${{ steps.find-comment.outputs.comment-id }} issue-number: ${{ github.event.pull_request.number }} body: | - **Compiled firmware for commit `${{steps.names.outputs.commit_sha}}`:** + **Compiled ${{ matrix.target }} firmware for commit `${{steps.names.outputs.commit_sha}}`:** - [📦 Update package](https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-update-${{steps.names.outputs.suffix}}.tgz) - [📥 DFU file](https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-full-${{steps.names.outputs.suffix}}.dfu) - [☁️ Web/App updater](https://lab.flipper.net/?url=https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-update-${{steps.names.outputs.suffix}}.tgz&channel=${{steps.names.outputs.branch_name}}&version=${{steps.names.outputs.commit_sha}}) edit-mode: replace + + - name: 'Check if API version exists' + if: ${{ steps.names.outputs.event_type == 'tag' && matrix.target == env.DEFAULT_TARGET }} + run: | + FIRMWARE_API=$(./fbt TARGET_HW=$TARGET_HW get_apiversion) + curl -sX 'GET' \ + '${{ secrets.CATALOG_URL }}/api/v0/0/sdk?length=200' \ + -H 'Accept: application/json' > sdk_versions.json + if jq -r -e ".[] | select((.api == \"${FIRMWARE_API}\") and .target == \"f${TARGET_HW}\")" sdk_versions.json > found_sdk.json ; then + echo "API version $FIRMWARE_API already exists in catalog" + if [ $(jq -r -e ".released_at" found_sdk.json) != "null" ] ; then + echo "API version is already released" + exit 0 + fi + if ! echo "$SUFFIX" | grep -q "-rc" ; then + SDK_ID=$(jq -r ._id found_sdk.json) + echo "Marking SDK $SDK_ID as released" + curl -X 'POST' \ + "${{ secrets.CATALOG_URL }}/api/v0/0/sdk/${SDK_ID}/release" \ + -H 'Accept: application/json' \ + -H 'Authorization: Bearer ${{ secrets.CATALOG_API_TOKEN }}' \ + -d '' + fi + else + echo "API version $FIRMWARE_API doesn't exist in catalog, adding" + curl -X 'POST' \ + '${{ secrets.CATALOG_URL }}/api/v0/0/sdk' \ + -H 'Accept: application/json' \ + -H 'Authorization: Bearer ${{ secrets.CATALOG_API_TOKEN }}' \ + -H 'Content-Type: application/json' \ + -d "{\"name\": \"${SUFFIX}\", \"target\": \"f${TARGET_HW}\", \"api\": \"${FIRMWARE_API}\"}\" + fi diff --git a/.github/workflows/build_compact.yml b/.github/workflows/build_compact.yml index 705888a41..37ebc0ca1 100644 --- a/.github/workflows/build_compact.yml +++ b/.github/workflows/build_compact.yml @@ -73,3 +73,12 @@ jobs: popd done done + +## Uncomment this for a single job that will run only if all targets are built successfully +# report-status: +# name: Report status +# needs: [compact] +# if: always() && !contains(needs.*.result, 'failure') +# runs-on: [self-hosted, FlipperZeroShell] +# steps: +# - run: echo "All good ✨" ; diff --git a/firmware.scons b/firmware.scons index a91b7cdfc..2a82db371 100644 --- a/firmware.scons +++ b/firmware.scons @@ -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( diff --git a/scripts/fbt/appmanifest.py b/scripts/fbt/appmanifest.py index b8b8a8d68..7bb8e40b2 100644 --- a/scripts/fbt/appmanifest.py +++ b/scripts/fbt/appmanifest.py @@ -193,8 +193,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): @@ -211,6 +222,12 @@ class AppBuildset: FlipperAppType.SETTINGS, FlipperAppType.STARTUP, ) + EXTERNAL_APP_TYPES = ( + FlipperAppType.EXTERNAL, + FlipperAppType.MENUEXTERNAL, + FlipperAppType.PLUGIN, + FlipperAppType.DEBUG, + ) @staticmethod def print_writer(message): @@ -219,16 +236,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() @@ -271,6 +293,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: diff --git a/scripts/fbt/sdk/cache.py b/scripts/fbt/sdk/cache.py index 074cac6b9..e3d93a319 100644 --- a/scripts/fbt/sdk/cache.py +++ b/scripts/fbt/sdk/cache.py @@ -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) diff --git a/scripts/fbt_tools/fbt_apps.py b/scripts/fbt_tools/fbt_apps.py index cbb3bf726..9a0718055 100644 --- a/scripts/fbt_tools/fbt_apps.py +++ b/scripts/fbt_tools/fbt_apps.py @@ -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): diff --git a/scripts/ufbt/SConstruct b/scripts/ufbt/SConstruct index 1630135c2..98e6b638f 100644 --- a/scripts/ufbt/SConstruct +++ b/scripts/ufbt/SConstruct @@ -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, diff --git a/site_scons/extapps.scons b/site_scons/extapps.scons index 97b7ac095..f9227ed37 100644 --- a/site_scons/extapps.scons +++ b/site_scons/extapps.scons @@ -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( From 8cbb757533a093fcb61109fb92f145808a43ac5f Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Tue, 5 Sep 2023 22:13:50 +0900 Subject: [PATCH 53/59] [FL-3583]Account for the "-" in line carry-over (#3038) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- applications/services/gui/elements.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/applications/services/gui/elements.c b/applications/services/gui/elements.c index 37ecfde4c..891435c96 100644 --- a/applications/services/gui/elements.c +++ b/applications/services/gui/elements.c @@ -290,7 +290,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); From d40f66434289ce27129e17d5f6c091f9997ba920 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 5 Sep 2023 16:22:14 +0300 Subject: [PATCH 54/59] API for BLE Beacon app thanks to Willy-JL --- firmware/targets/f7/api_symbols.csv | 2 + firmware/targets/f7/ble_glue/gap.c | 52 ++++++++++++++----- firmware/targets/f7/ble_glue/gap.h | 2 + firmware/targets/f7/furi_hal/furi_hal_bt.c | 7 +++ .../targets/furi_hal_include/furi_hal_bt.h | 3 ++ 5 files changed, 54 insertions(+), 12 deletions(-) diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 108605593..de973a440 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1079,6 +1079,7 @@ Function,+,furi_hal_bt_serial_set_rpc_status,void,FuriHalBtSerialRpcStatus Function,+,furi_hal_bt_serial_start,void, Function,+,furi_hal_bt_serial_stop,void, Function,+,furi_hal_bt_serial_tx,_Bool,"uint8_t*, uint16_t" +Function,+,furi_hal_bt_set_custom_adv_data,void,"const uint8_t*, size_t" Function,+,furi_hal_bt_set_key_storage_change_callback,void,"BleGlueKeyStorageChangedCallback, void*" Function,+,furi_hal_bt_set_profile_adv_name,void,"FuriHalBtProfile, const char[( ( 1 + 8 + ( 8 + 1 ) ) + 1 )]" Function,+,furi_hal_bt_set_profile_mac_addr,void,"FuriHalBtProfile, const uint8_t[( 6 )]" @@ -1662,6 +1663,7 @@ Function,-,gammaf_r,float,"float, int*" Function,-,gap_get_remote_conn_rssi,uint32_t,int8_t* Function,-,gap_get_state,GapState, Function,-,gap_init,_Bool,"GapConfig*, GapEventCallback, void*" +Function,-,gap_set_custom_adv_data,void,"size_t, const uint8_t*" Function,-,gap_start_advertising,void, Function,-,gap_stop_advertising,void, Function,-,gap_thread_stop,void, diff --git a/firmware/targets/f7/ble_glue/gap.c b/firmware/targets/f7/ble_glue/gap.c index ab7b9d16c..6fedb54cf 100644 --- a/firmware/targets/f7/ble_glue/gap.c +++ b/firmware/targets/f7/ble_glue/gap.c @@ -37,6 +37,9 @@ typedef struct { FuriThread* thread; FuriMessageQueue* command_queue; bool enable_adv; + // API for BLE beacon plugin + size_t custom_adv_len; + const uint8_t* custom_adv_data; } Gap; typedef enum { @@ -430,18 +433,36 @@ static void gap_advertise_start(GapState new_state) { } } // Configure advertising - status = aci_gap_set_discoverable( - ADV_IND, - min_interval, - max_interval, - CFG_IDENTITY_ADDRESS, - 0, - strlen(gap->service.adv_name), - (uint8_t*)gap->service.adv_name, - gap->service.adv_svc_uuid_len, - gap->service.adv_svc_uuid, - 0, - 0); + // API For BLE beacon plugin + if(gap->custom_adv_data) { + // Custom adv logic from https://techryptic.github.io/2023/09/01/Annoying-Apple-Fans/ + static const uint16_t gap_appearance = 0x0000; //GAP_APPEARANCE_UNKNOWN + status = aci_gatt_update_char_value( + gap->service.gap_svc_handle, + gap->service.gap_svc_handle, + 0, + sizeof(gap_appearance), + (uint8_t*)&gap_appearance); + status = aci_gap_set_discoverable( + ADV_IND, min_interval, max_interval, CFG_IDENTITY_ADDRESS, 0, 0, NULL, 0, NULL, 0, 0); + status = aci_gap_delete_ad_type(AD_TYPE_FLAGS); + status = aci_gap_delete_ad_type(AD_TYPE_TX_POWER_LEVEL); + status = aci_gap_update_adv_data(gap->custom_adv_len, gap->custom_adv_data); + } else { + // Default adv logic + status = aci_gap_set_discoverable( + ADV_IND, + min_interval, + max_interval, + CFG_IDENTITY_ADDRESS, + 0, + strlen(gap->service.adv_name), + (uint8_t*)gap->service.adv_name, + gap->service.adv_svc_uuid_len, + gap->service.adv_svc_uuid, + 0, + 0); + } if(status) { FURI_LOG_E(TAG, "set_discoverable failed %d", status); } @@ -559,6 +580,13 @@ uint32_t gap_get_remote_conn_rssi(int8_t* rssi) { return 0; } +// API For BLE beacon plugin + +void gap_set_custom_adv_data(size_t adv_len, const uint8_t* adv_data) { + gap->custom_adv_len = adv_len; + gap->custom_adv_data = adv_data; +} + GapState gap_get_state() { GapState state; if(gap) { diff --git a/firmware/targets/f7/ble_glue/gap.h b/firmware/targets/f7/ble_glue/gap.h index 396d64e67..27bbc1cf0 100644 --- a/firmware/targets/f7/ble_glue/gap.h +++ b/firmware/targets/f7/ble_glue/gap.h @@ -83,6 +83,8 @@ void gap_thread_stop(); uint32_t gap_get_remote_conn_rssi(int8_t* rssi); +void gap_set_custom_adv_data(size_t adv_len, const uint8_t* adv_data); + #ifdef __cplusplus } #endif diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt.c b/firmware/targets/f7/furi_hal/furi_hal_bt.c index 5a150d388..9fab0164a 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_bt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_bt.c @@ -483,6 +483,13 @@ uint32_t furi_hal_bt_get_conn_rssi(uint8_t* rssi) { return since; } +// API for BLE beacon plugin +void furi_hal_bt_set_custom_adv_data(const uint8_t* adv_data, size_t adv_len) { + gap_set_custom_adv_data(adv_len, adv_data); + furi_hal_bt_stop_advertising(); + furi_hal_bt_start_advertising(); +} + void furi_hal_bt_reverse_mac_addr(uint8_t mac_addr[GAP_MAC_ADDR_SIZE]) { uint8_t tmp; for(size_t i = 0; i < GAP_MAC_ADDR_SIZE / 2; i++) { diff --git a/firmware/targets/furi_hal_include/furi_hal_bt.h b/firmware/targets/furi_hal_include/furi_hal_bt.h index 7354d8770..9ef2c7646 100644 --- a/firmware/targets/furi_hal_include/furi_hal_bt.h +++ b/firmware/targets/furi_hal_include/furi_hal_bt.h @@ -252,6 +252,9 @@ const uint8_t* furi_hal_bt_get_profile_mac_addr(FuriHalBtProfile profile); uint32_t furi_hal_bt_get_conn_rssi(uint8_t* rssi); +// API for BLE Beacon plugin +void furi_hal_bt_set_custom_adv_data(const uint8_t* adv_data, size_t adv_len); + void furi_hal_bt_set_profile_pairing_method(FuriHalBtProfile profile, GapPairing pairing_method); GapPairing furi_hal_bt_get_profile_pairing_method(FuriHalBtProfile profile); From 600b2ce627a2b01bd3581e996763d8777d066cd2 Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Tue, 5 Sep 2023 22:24:50 +0900 Subject: [PATCH 55/59] [FL-3566] iButton: Return to the file selection if file is corrupted (#3040) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- applications/main/ibutton/ibutton.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/applications/main/ibutton/ibutton.c b/applications/main/ibutton/ibutton.c index 0e4c621b2..760918097 100644 --- a/applications/main/ibutton/ibutton.c +++ b/applications/main/ibutton/ibutton.c @@ -195,6 +195,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; @@ -203,9 +204,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) { From 45fd5ef9d88efe36d9b0445b460c17492a870281 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 5 Sep 2023 19:28:47 +0300 Subject: [PATCH 56/59] Subghz fix path reset on save name exit --- applications/main/subghz/scenes/subghz_scene_save_name.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/applications/main/subghz/scenes/subghz_scene_save_name.c b/applications/main/subghz/scenes/subghz_scene_save_name.c index 6320c12f2..e1bb6c33b 100644 --- a/applications/main/subghz/scenes/subghz_scene_save_name.c +++ b/applications/main/subghz/scenes/subghz_scene_save_name.c @@ -138,6 +138,9 @@ bool subghz_scene_save_name_on_event(void* context, SceneManagerEvent event) { } 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) { From 1df2fc035fd496705239bbd115672c64b9900615 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 7 Sep 2023 13:45:37 +0300 Subject: [PATCH 57/59] New bt beacon api by Willy-JL --- firmware/targets/f7/api_symbols.csv | 5 +- firmware/targets/f7/ble_glue/gap.c | 52 +++++-------------- firmware/targets/f7/ble_glue/gap.h | 2 - firmware/targets/f7/furi_hal/furi_hal_bt.c | 46 ++++++++++++++-- .../targets/furi_hal_include/furi_hal_bt.h | 30 ++++++++++- 5 files changed, 86 insertions(+), 49 deletions(-) diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index de973a440..e89e29513 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1037,6 +1037,9 @@ Function,+,furi_event_flag_wait,uint32_t,"FuriEventFlag*, uint32_t, uint32_t, ui Function,+,furi_get_tick,uint32_t, Function,+,furi_hal_bt_change_app,_Bool,"FuriHalBtProfile, GapEventCallback, void*" Function,+,furi_hal_bt_clear_white_list,_Bool, +Function,+,furi_hal_bt_custom_adv_set,_Bool,"const uint8_t*, size_t" +Function,+,furi_hal_bt_custom_adv_start,_Bool,"uint16_t, uint16_t, uint8_t, const uint8_t[( 6 )], uint8_t" +Function,+,furi_hal_bt_custom_adv_stop,_Bool, Function,+,furi_hal_bt_dump_state,void,FuriString* Function,+,furi_hal_bt_ensure_c2_mode,_Bool,BleGlueC2Mode Function,-,furi_hal_bt_get_conn_rssi,uint32_t,uint8_t* @@ -1079,7 +1082,6 @@ Function,+,furi_hal_bt_serial_set_rpc_status,void,FuriHalBtSerialRpcStatus Function,+,furi_hal_bt_serial_start,void, Function,+,furi_hal_bt_serial_stop,void, Function,+,furi_hal_bt_serial_tx,_Bool,"uint8_t*, uint16_t" -Function,+,furi_hal_bt_set_custom_adv_data,void,"const uint8_t*, size_t" Function,+,furi_hal_bt_set_key_storage_change_callback,void,"BleGlueKeyStorageChangedCallback, void*" Function,+,furi_hal_bt_set_profile_adv_name,void,"FuriHalBtProfile, const char[( ( 1 + 8 + ( 8 + 1 ) ) + 1 )]" Function,+,furi_hal_bt_set_profile_mac_addr,void,"FuriHalBtProfile, const uint8_t[( 6 )]" @@ -1663,7 +1665,6 @@ Function,-,gammaf_r,float,"float, int*" Function,-,gap_get_remote_conn_rssi,uint32_t,int8_t* Function,-,gap_get_state,GapState, Function,-,gap_init,_Bool,"GapConfig*, GapEventCallback, void*" -Function,-,gap_set_custom_adv_data,void,"size_t, const uint8_t*" Function,-,gap_start_advertising,void, Function,-,gap_stop_advertising,void, Function,-,gap_thread_stop,void, diff --git a/firmware/targets/f7/ble_glue/gap.c b/firmware/targets/f7/ble_glue/gap.c index 6fedb54cf..ab7b9d16c 100644 --- a/firmware/targets/f7/ble_glue/gap.c +++ b/firmware/targets/f7/ble_glue/gap.c @@ -37,9 +37,6 @@ typedef struct { FuriThread* thread; FuriMessageQueue* command_queue; bool enable_adv; - // API for BLE beacon plugin - size_t custom_adv_len; - const uint8_t* custom_adv_data; } Gap; typedef enum { @@ -433,36 +430,18 @@ static void gap_advertise_start(GapState new_state) { } } // Configure advertising - // API For BLE beacon plugin - if(gap->custom_adv_data) { - // Custom adv logic from https://techryptic.github.io/2023/09/01/Annoying-Apple-Fans/ - static const uint16_t gap_appearance = 0x0000; //GAP_APPEARANCE_UNKNOWN - status = aci_gatt_update_char_value( - gap->service.gap_svc_handle, - gap->service.gap_svc_handle, - 0, - sizeof(gap_appearance), - (uint8_t*)&gap_appearance); - status = aci_gap_set_discoverable( - ADV_IND, min_interval, max_interval, CFG_IDENTITY_ADDRESS, 0, 0, NULL, 0, NULL, 0, 0); - status = aci_gap_delete_ad_type(AD_TYPE_FLAGS); - status = aci_gap_delete_ad_type(AD_TYPE_TX_POWER_LEVEL); - status = aci_gap_update_adv_data(gap->custom_adv_len, gap->custom_adv_data); - } else { - // Default adv logic - status = aci_gap_set_discoverable( - ADV_IND, - min_interval, - max_interval, - CFG_IDENTITY_ADDRESS, - 0, - strlen(gap->service.adv_name), - (uint8_t*)gap->service.adv_name, - gap->service.adv_svc_uuid_len, - gap->service.adv_svc_uuid, - 0, - 0); - } + status = aci_gap_set_discoverable( + ADV_IND, + min_interval, + max_interval, + CFG_IDENTITY_ADDRESS, + 0, + strlen(gap->service.adv_name), + (uint8_t*)gap->service.adv_name, + gap->service.adv_svc_uuid_len, + gap->service.adv_svc_uuid, + 0, + 0); if(status) { FURI_LOG_E(TAG, "set_discoverable failed %d", status); } @@ -580,13 +559,6 @@ uint32_t gap_get_remote_conn_rssi(int8_t* rssi) { return 0; } -// API For BLE beacon plugin - -void gap_set_custom_adv_data(size_t adv_len, const uint8_t* adv_data) { - gap->custom_adv_len = adv_len; - gap->custom_adv_data = adv_data; -} - GapState gap_get_state() { GapState state; if(gap) { diff --git a/firmware/targets/f7/ble_glue/gap.h b/firmware/targets/f7/ble_glue/gap.h index 27bbc1cf0..396d64e67 100644 --- a/firmware/targets/f7/ble_glue/gap.h +++ b/firmware/targets/f7/ble_glue/gap.h @@ -83,8 +83,6 @@ void gap_thread_stop(); uint32_t gap_get_remote_conn_rssi(int8_t* rssi); -void gap_set_custom_adv_data(size_t adv_len, const uint8_t* adv_data); - #ifdef __cplusplus } #endif diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt.c b/firmware/targets/f7/furi_hal/furi_hal_bt.c index 9fab0164a..5b62052ea 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_bt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_bt.c @@ -484,10 +484,48 @@ uint32_t furi_hal_bt_get_conn_rssi(uint8_t* rssi) { } // API for BLE beacon plugin -void furi_hal_bt_set_custom_adv_data(const uint8_t* adv_data, size_t adv_len) { - gap_set_custom_adv_data(adv_len, adv_data); - furi_hal_bt_stop_advertising(); - furi_hal_bt_start_advertising(); +bool furi_hal_bt_custom_adv_set(const uint8_t* adv_data, size_t adv_len) { + tBleStatus status = aci_gap_additional_beacon_set_data(adv_len, adv_data); + if(status) { + FURI_LOG_E(TAG, "custom_adv_set failed %d", status); + return false; + } else { + FURI_LOG_D(TAG, "custom_adv_set success"); + return true; + } +} + +bool furi_hal_bt_custom_adv_start( + uint16_t min_interval, + uint16_t max_interval, + uint8_t mac_type, + const uint8_t mac_addr[GAP_MAC_ADDR_SIZE], + uint8_t power_amp_level) { + tBleStatus status = aci_gap_additional_beacon_start( + min_interval / 0.625, // Millis to gap time + max_interval / 0.625, // Millis to gap time + 0b00000111, // All 3 channels + mac_type, + mac_addr, + power_amp_level); + if(status) { + FURI_LOG_E(TAG, "custom_adv_start failed %d", status); + return false; + } else { + FURI_LOG_D(TAG, "custom_adv_start success"); + return true; + } +} + +bool furi_hal_bt_custom_adv_stop() { + tBleStatus status = aci_gap_additional_beacon_stop(); + if(status) { + FURI_LOG_E(TAG, "custom_adv_stop failed %d", status); + return false; + } else { + FURI_LOG_D(TAG, "custom_adv_stop success"); + return true; + } } void furi_hal_bt_reverse_mac_addr(uint8_t mac_addr[GAP_MAC_ADDR_SIZE]) { diff --git a/firmware/targets/furi_hal_include/furi_hal_bt.h b/firmware/targets/furi_hal_include/furi_hal_bt.h index 9ef2c7646..2969cfbb8 100644 --- a/firmware/targets/furi_hal_include/furi_hal_bt.h +++ b/firmware/targets/furi_hal_include/furi_hal_bt.h @@ -253,7 +253,35 @@ const uint8_t* furi_hal_bt_get_profile_mac_addr(FuriHalBtProfile profile); uint32_t furi_hal_bt_get_conn_rssi(uint8_t* rssi); // API for BLE Beacon plugin -void furi_hal_bt_set_custom_adv_data(const uint8_t* adv_data, size_t adv_len); +/** Set custom advertisement packet data + * @param[in] adv_data pointer to advertisement data + * @param[in] adv_len length of advertisement data + * + * @return true on success +*/ +bool furi_hal_bt_custom_adv_set(const uint8_t* adv_data, size_t adv_len); + +/** Start custom advertisement beacon + * @param[in] min_interval minimum advertisement interval (20 - 10240 ms) + * @param[in] max_interval maximum advertisement interval (20 - 10240 ms) + * @param[in] mac_type type of mac address (0x00 public, 0x01 static random) + * @param[in] mac_addr pointer to mac address + * @param[in] power_amp_level amplifier level (output dBm) (0x00 - 0x1F) + * + * @return true on success +*/ +bool furi_hal_bt_custom_adv_start( + uint16_t min_interval, + uint16_t max_interval, + uint8_t mac_type, + const uint8_t mac_addr[GAP_MAC_ADDR_SIZE], + uint8_t power_amp_level); + +/** Stop custom advertisement beacon + * + * @return true on success +*/ +bool furi_hal_bt_custom_adv_stop(); void furi_hal_bt_set_profile_pairing_method(FuriHalBtProfile profile, GapPairing pairing_method); From b1b35e87f9ee407ce3a07fae654b5c4385187df2 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 7 Sep 2023 14:46:06 +0300 Subject: [PATCH 58/59] update readme, docs, fix build versions --- .drone.yml | 2 ++ ReadMe.md | 8 +++--- .../subghz/scenes/subghz_scene_set_type.c | 8 +++--- documentation/SubGHzRemoteProg.md | 27 +++++++++++++++++++ 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/.drone.yml b/.drone.yml index 35d2ce2ec..13fc878ed 100644 --- a/.drone.yml +++ b/.drone.yml @@ -47,6 +47,7 @@ steps: - cp -R base_pack_build/artifacts-base/* assets/resources/apps/ - rm -rf base_pack_build - rm -rf all-the-apps-base.tgz + - rm -f build/f7-firmware-C/toolbox/version.* - ./fbt COMPACT=1 DEBUG=0 updater_package - mkdir artifacts-default - mv dist/f7-C/* artifacts-default/ @@ -414,6 +415,7 @@ steps: - cp -R base_pack_build/artifacts-base/* assets/resources/apps/ - rm -rf base_pack_build - rm -rf all-the-apps-base.tgz + - rm -f build/f7-firmware-C/toolbox/version.* - ./fbt COMPACT=1 DEBUG=0 updater_package - mkdir artifacts-default - mv dist/f7-C/* artifacts-default/ diff --git a/ReadMe.md b/ReadMe.md index 4e21dc3f9..a9f41d4ed 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -53,12 +53,12 @@ - Press OK in frequency analyzer to use detected frequency in Read modes [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/77) - Long press OK button in Sub-GHz Frequency analyzer to switch to Read menu [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/79) - New option to use timestamps + protocol name when you saving file, instead of random name - Enable in `Radio Settings -> Time in names = ON` - - Read mode UI improvements (scrolling text, + shows time when signal was received) (by @wosk) + - Read mode UI improvements (shows time when signal was received) (by @wosk) - External CC1101 module support (Hardware SPI used) - **Hold right in received signal list to delete selected signal** - **Custom buttons for Keeloq / Alutech AT4N / Nice Flor S / Somfy Telis / Security+ 2.0 / CAME Atomo** - now you can use arrow buttons to send signal with different button code - `Add manually` menu extended with new protocols - - BFT Mitto / Somfy Telis / Nice Flor S / CAME Atomo, etc.. manual creation with programming new remote into receiver (use button 0xF for BFT Mitto, 0x8 (Prog) on Somfy Telis) + - FAAC SLH, BFT Mitto / Somfy Telis / Nice Flor S / CAME Atomo, etc.. manual creation with programming new remote into receiver (use button 0xF for BFT Mitto, 0x8 (Prog) on Somfy Telis) - Debug mode counter increase settings (+1 -> +5, +10, default: +1) - Debug PIN output settings for protocol development @@ -120,8 +120,8 @@ Encoders or sending made by @xMasterX: Encoders or sending made by @Eng1n33r(first implementation in Q2 2022) & @xMasterX (current version): - CAME Atomo -> Update! check out new [instructions](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md) - Nice Flor S -> How to create new remote - [instructions](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md) -- FAAC SLH (Spa) [External seed calculation required (For info contact me in Discord: @mmx7)] -- Keeloq: BFT Mitto -> Update! check out new [instructions](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md) +- FAAC SLH (Spa) -> Update!!! Check out new [instructions](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md) +- Keeloq: BFT Mitto -> Update! Check out new [instructions](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md) - Star Line - Security+ v1 & v2 (encoders was made in OFW) diff --git a/applications/main/subghz/scenes/subghz_scene_set_type.c b/applications/main/subghz/scenes/subghz_scene_set_type.c index 9f5b61499..062bc813a 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_type.c +++ b/applications/main/subghz/scenes/subghz_scene_set_type.c @@ -15,13 +15,13 @@ void subghz_scene_set_type_on_enter(void* context) { submenu_add_item( subghz->submenu, - "Faac SLH [Man.] 868MHz", + "FAAC SLH [Man.] 868MHz", SubmenuIndexFaacSLH_Manual_868, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "Faac SLH [Man.] 433MHz", + "FAAC SLH [Man.] 433MHz", SubmenuIndexFaacSLH_Manual_433, subghz_scene_set_type_submenu_callback, subghz); @@ -33,13 +33,13 @@ void subghz_scene_set_type_on_enter(void* context) { subghz); submenu_add_item( subghz->submenu, - "Faac SLH 868MHz", + "FAAC SLH 868MHz", SubmenuIndexFaacSLH_868, subghz_scene_set_type_submenu_callback, subghz); submenu_add_item( subghz->submenu, - "Faac SLH 433MHz", + "FAAC SLH 433MHz", SubmenuIndexFaacSLH_433, subghz_scene_set_type_submenu_callback, subghz); diff --git a/documentation/SubGHzRemoteProg.md b/documentation/SubGHzRemoteProg.md index e53319b2f..0a799fc58 100644 --- a/documentation/SubGHzRemoteProg.md +++ b/documentation/SubGHzRemoteProg.md @@ -3,6 +3,32 @@ ### If your system is not added here that doesn't mean flipper don't support it! Look into add manually menu, and search for your manufacturers inscturctions! ### Also many supported systems can be used only from `Read` mode, `Add Manually` is used only to make new remotes that can be binded with receiver +## FAAC SLH (NEW!) +1. Create new remote with randomly generated serial: Go to SubGHz -> Add Manually -> FAAC SLH (select your frequency) +2. Open your new remote file +3. Open your receiver box, find programming button on the receiver board. +4. Hold Up arrow button on the flipper to send programming signal - at same time press and hold programming button on the receiver board. +5. Led on the receiver board will light on, then off, then on, then off again then on again +6. Release all buttons +7. Press send button on the flipper couple times holding it for 1-3 seconds +8. Done! +Watch this video to learn more : https://www.youtube.com/watch?v=NfZmMy37XUs + +... +How to get Seed value from your original remote or bind new remote using existing (master) remote? +1. Go to SubGHz -> Read - Select frequency 868.35 or 433.92 and modulation AM650 +2. Hold two buttons on the original master remote until led turns on +3. Click one button that you want to get seed from (Seed is unique for each button on original remote!) +4. You will get signal in the read screen on flipper, open that and see your original remote seed for button you used +5. You can create new remote using that seed and bind that to receiver without opening the box! Faac has procedure that allows to bind new remotes using master remote, you can use flipper for that +6. Go to SubGHz -> Add Manually -> FAAC SLH Man. (your Freq) +7. Enter those values -> REPLACE `R` with any random digits like 1,2,3.. +FIX -> A0 RR RR R6 +COUNTER -> 00 00 02 +SEED -> Your seed from the remote button you got earlier +8. Flipper will act as new remote, press Send button couple times near the receiver to register new remote +9. Done! + ## AN-Motors AT4 **This instruction for older boards, if your has no** `Learn` **button but has buttons** `F`, `CL`, `+`, `-` **read instruction from Alutech AT4N** @@ -137,6 +163,7 @@ garage/gate. #### Follow links below to find more detailed instructions!!! #### Materials used: +- [FAAC SLH](https://www.youtube.com/watch?v=NfZmMy37XUs) - [Somfy Telis](https://pushstack.wordpress.com/somfy-rts-protocol/) - [BFT Mitto](https://www.retroremotes.com.au/wp-content/uploads/2017/03/BFT-MITTO-2-4-19-6-17.pdf) - [NICE FLOX2R Receiver Programming](https://apollogateopeners.com/store/pdf/apollo-flor-s-receiver-programming-guide.pdf) From a90ebd7b53dfc3bc17e5b7a8f7cdbe5b4b41ab01 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 8 Sep 2023 15:53:15 +0300 Subject: [PATCH 59/59] Update changelog --- CHANGELOG.md | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14c20e5d9..37f086227 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,41 @@ ## New changes -* !!! **Warning! After installing, Desktop settings (Favoutite apps, PIN Code, AutoLock time..) will be resetted to default due to settings changes, Please set your PIN code, Favourite apps again in Settings->Desktop** !!! -* Desktop: **New way to set favourite apps and fully configurable dummy mode** (now you can set up to 4 favourite apps!) (port of OFW PR 2972 by nminaylov) (by @gid9798 | PR #578) -* Desktop: Fix lock timer after rebooting (by @gid9798 | PR #578) -* Infrared: Updated universal assets (by @amec0e | PR #581) -* Core: Added proper error message on out of memory crash (by @Willy-JL) -* SubGHz: Fix FAAC SLH add manually issues and fix sending signals with unknown seed -* SubGHz: Temporarily reverted changes from OFW PR 2984: SubGhz: fix todo (by Skorpionm) - Fixes Enhanced Sub-GHz Chat app and various issues related to receiving signals that was found in 061 release +* **Apple BLE Spam app** (by @Willy-JL | Plus research from ECTO-1A, xMasterX and techryptic) -> (app can be found in builds ` `, `e`, `n`, `r`) +* SubGHz: **FAAC SLH - Programming mode** (by @xMasterX & @Eng1n33r (full research and PoC by @Skorpionm)| PR #585) -> [How to use](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzRemoteProg.md) +* SubGHz: FAAC SLH -> Add manually new options +* SubGHz: Fix 0xFFFF counter value being skipped +* SubGHz: Fix path reset on save name scene exit +* SubGHz: Various fixes +* SubGHz Remote: Fix Sub-GHz Remote folder name (by @OperKH | PR #583) +* SubGHz Remote: submodule (by @gid9798 | PR #592) +* Infrared: Updated universal assets (by @amec0e | PR #594) +* Infrared: Remake custom universal remotes to use new design (New icons by @Svaarich) +* UI: Keyboard ok to toggle select all in cursor mode (by @Willy-JL) +* CI/CD: Fixed regular builds having `c` in version name in the device info while not being actual `c` build +* Docs: New FAAC SLH instructions +* Docs: Readme & Changelog fixes (by @gid9798 | PR #586) +* OFW: iButton: Return to the file selection if file is corrupted +* OFW: Account for the "-" in line carry-over +* OFW: github: workflow improvements +* OFW: Storage: force mount +* OFW: Add File Naming setting for more detailed naming -> **Breaking API change, API 35.x -> API 36.x** - **Update your apps!** +* OFW: Disconnect from BLE on protobuf error +* OFW: Add support for Mifare Classic 4k SAK 0x38 ATQA 0x02, 0x04, 0x08 +* OFW: Undo some TODO +* OFW: Check the filetype of the update manifest +* OFW: StorageListRequest: size filter +* OFW: SubGhz: heap overflow text error +* OFW: nfc: add rfal wrong state error handling +* OFW: Rfid: fix crash on broken key launch from archive (fix was already done in UL in similar way) +* OFW: AC OFF button +* OFW: New IR universal remote graphics +* OFW: Intelligent probing with warnings for fwflash.py +* OFW: FuriHal: explicitly pull display pins at early init stage, move PUPD config to early stage +* OFW: Fix display last symbol in multiline text +* OFW: Properly reset the NFC device data +* OFW: fbt: various improvements and bug fixes +* OFW: Littlefs updated to v2.7.0 +* OFW: loader: restored support for debug apps +* OFW: Removed explicit dependency on scons for external scripting ----