From 015ee6e7e48118b74b78c32c769b78350f20edb0 Mon Sep 17 00:00:00 2001 From: Dmitry422 Date: Fri, 9 Jan 2026 00:39:44 +0700 Subject: [PATCH 1/3] 1. Add debug status to Desktop clock like "D hh:mm" 2. Alutech_at_4n protocol acceleration --- applications/services/desktop/desktop.c | 16 +++--- lib/subghz/protocols/alutech_at_4n.c | 67 ++++++++++++++++--------- 2 files changed, 52 insertions(+), 31 deletions(-) diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index eed5537c6..41cf3f7d8 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -105,14 +105,18 @@ static void desktop_clock_draw_callback(Canvas* canvas, void* context) { } char buffer[20]; - snprintf(buffer, sizeof(buffer), "%02u:%02u", hour, desktop->clock.minute); + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { + snprintf(buffer, sizeof(buffer), "D %02u:%02u", hour, desktop->clock.minute); + } else { + snprintf(buffer, sizeof(buffer), "%02u:%02u", hour, desktop->clock.minute); + } - view_port_set_width( - desktop->clock_viewport, - canvas_string_width(canvas, buffer) - 1 + (desktop->clock.minute % 10 == 1)); + view_port_set_width( + desktop->clock_viewport, + canvas_string_width(canvas, buffer) - 1 + (desktop->clock.minute % 10 == 1)); - canvas_draw_str_aligned(canvas, 0, 8, AlignLeft, AlignBottom, buffer); -} + canvas_draw_str_aligned(canvas, 0, 8, AlignLeft, AlignBottom, buffer); + } static void desktop_stealth_mode_icon_draw_callback(Canvas* canvas, void* context) { UNUSED(context); diff --git a/lib/subghz/protocols/alutech_at_4n.c b/lib/subghz/protocols/alutech_at_4n.c index ccbe2ccf9..6175cc47b 100644 --- a/lib/subghz/protocols/alutech_at_4n.c +++ b/lib/subghz/protocols/alutech_at_4n.c @@ -9,7 +9,8 @@ #define TAG "SubGhzProtocoAlutech_at_4n" -#define SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE 0xFFFFFFFF +#define SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE 0xFFFFFFFFFFFFFFFF +#define SUBGHZ_ALUTECH_AT_4N_RAINBOW_TABLE_SIZE_BYTES 32 static const SubGhzBlockConst subghz_protocol_alutech_at_4n_const = { .te_short = 400, @@ -141,26 +142,20 @@ LevelDuration subghz_protocol_encoder_alutech_at_4n_yield(void* context) { /** * Read bytes from rainbow table - * @param file_name Full path to rainbow table the file + * @param buffer Pointer to decrypted magic data buffer * @param number_alutech_at_4n_magic_data number in the array * @return alutech_at_4n_magic_data */ -static uint32_t subghz_protocol_alutech_at_4n_get_magic_data_in_file( - const char* file_name, +static uint32_t subghz_protocol_alutech_at_4n_get_magic_data_from_buffer( + uint8_t* buffer, uint8_t number_alutech_at_4n_magic_data) { - if(!strcmp(file_name, "")) return SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE; - - uint8_t buffer[sizeof(uint32_t)] = {0}; uint32_t address = number_alutech_at_4n_magic_data * sizeof(uint32_t); uint32_t alutech_at_4n_magic_data = 0; - if(subghz_keystore_raw_get_data(file_name, address, buffer, sizeof(uint32_t))) { - for(size_t i = 0; i < sizeof(uint32_t); i++) { - alutech_at_4n_magic_data = (alutech_at_4n_magic_data << 8) | buffer[i]; - } - } else { - alutech_at_4n_magic_data = SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE; + for(size_t i = address; i < (address + sizeof(uint32_t)); i++) { + alutech_at_4n_magic_data = (alutech_at_4n_magic_data << 8) | buffer[i]; } + return alutech_at_4n_magic_data; } @@ -195,17 +190,28 @@ static uint8_t subghz_protocol_alutech_at_4n_decrypt_data_crc(uint8_t data) { } static uint64_t subghz_protocol_alutech_at_4n_decrypt(uint64_t data, const char* file_name) { + if(!strcmp(file_name, "")) return SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE; + + uint8_t buffer[SUBGHZ_ALUTECH_AT_4N_RAINBOW_TABLE_SIZE_BYTES] = {0}; + uint8_t* buffer_ptr = (uint8_t*)&buffer; + + if(subghz_keystore_raw_get_data( + file_name, 0, buffer, SUBGHZ_ALUTECH_AT_4N_RAINBOW_TABLE_SIZE_BYTES)) { + } else { + return SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE; + } + uint8_t* p = (uint8_t*)&data; uint32_t data1 = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; uint32_t data2 = p[4] << 24 | p[5] << 16 | p[6] << 8 | p[7]; uint32_t data3 = 0; uint32_t magic_data[] = { - subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 0), - subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 1), - subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 2), - subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 3), - subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 4), - subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 5)}; + subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 0), + subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 1), + subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 2), + subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 3), + subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 4), + subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 5)}; uint32_t i = magic_data[0]; do { @@ -230,17 +236,28 @@ static uint64_t subghz_protocol_alutech_at_4n_decrypt(uint64_t data, const char* } static uint64_t subghz_protocol_alutech_at_4n_encrypt(uint64_t data, const char* file_name) { + if(!strcmp(file_name, "")) return SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE; + + uint8_t buffer[SUBGHZ_ALUTECH_AT_4N_RAINBOW_TABLE_SIZE_BYTES] = {0}; + uint8_t* buffer_ptr = (uint8_t*)&buffer; + + if(subghz_keystore_raw_get_data( + file_name, 0, buffer, SUBGHZ_ALUTECH_AT_4N_RAINBOW_TABLE_SIZE_BYTES)) { + } else { + return SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE; + } + uint8_t* p = (uint8_t*)&data; uint32_t data1 = 0; uint32_t data2 = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; uint32_t data3 = p[4] << 24 | p[5] << 16 | p[6] << 8 | p[7]; uint32_t magic_data[] = { - subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 6), - subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 4), - subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 5), - subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 1), - subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 2), - subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 0)}; + subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 6), + subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 4), + subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 5), + subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 1), + subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 2), + subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 0)}; do { data1 = data1 + magic_data[0]; From ed7c4fd8af36ba41a403f12b76effa50ec480670 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Fri, 9 Jan 2026 01:06:34 +0300 Subject: [PATCH 2/3] fmt --- applications/services/desktop/desktop.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index 41cf3f7d8..3a96bf30a 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -111,12 +111,12 @@ static void desktop_clock_draw_callback(Canvas* canvas, void* context) { snprintf(buffer, sizeof(buffer), "%02u:%02u", hour, desktop->clock.minute); } - view_port_set_width( - desktop->clock_viewport, - canvas_string_width(canvas, buffer) - 1 + (desktop->clock.minute % 10 == 1)); + view_port_set_width( + desktop->clock_viewport, + canvas_string_width(canvas, buffer) - 1 + (desktop->clock.minute % 10 == 1)); - canvas_draw_str_aligned(canvas, 0, 8, AlignLeft, AlignBottom, buffer); - } + canvas_draw_str_aligned(canvas, 0, 8, AlignLeft, AlignBottom, buffer); +} static void desktop_stealth_mode_icon_draw_callback(Canvas* canvas, void* context) { UNUSED(context); From ea3b2375306e5ac7b4c147bc8d404f416ae715ad Mon Sep 17 00:00:00 2001 From: Dmitry422 Date: Fri, 9 Jan 2026 10:36:32 +0700 Subject: [PATCH 3/3] Nice Flor S protocol acceleration --- lib/subghz/protocols/alutech_at_4n.c | 8 ++-- lib/subghz/protocols/nice_flor_s.c | 55 +++++++++++++++++++--------- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/lib/subghz/protocols/alutech_at_4n.c b/lib/subghz/protocols/alutech_at_4n.c index 6175cc47b..9959e7cd2 100644 --- a/lib/subghz/protocols/alutech_at_4n.c +++ b/lib/subghz/protocols/alutech_at_4n.c @@ -141,7 +141,7 @@ LevelDuration subghz_protocol_encoder_alutech_at_4n_yield(void* context) { } /** - * Read bytes from rainbow table + * Read bytes from buffer array with rainbow table * @param buffer Pointer to decrypted magic data buffer * @param number_alutech_at_4n_magic_data number in the array * @return alutech_at_4n_magic_data @@ -190,7 +190,8 @@ static uint8_t subghz_protocol_alutech_at_4n_decrypt_data_crc(uint8_t data) { } static uint64_t subghz_protocol_alutech_at_4n_decrypt(uint64_t data, const char* file_name) { - if(!strcmp(file_name, "")) return SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE; + // load and decrypt rainbow table from file to buffer array in RAM + if(!file_name) return SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE; uint8_t buffer[SUBGHZ_ALUTECH_AT_4N_RAINBOW_TABLE_SIZE_BYTES] = {0}; uint8_t* buffer_ptr = (uint8_t*)&buffer; @@ -236,7 +237,8 @@ static uint64_t subghz_protocol_alutech_at_4n_decrypt(uint64_t data, const char* } static uint64_t subghz_protocol_alutech_at_4n_encrypt(uint64_t data, const char* file_name) { - if(!strcmp(file_name, "")) return SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE; + // load and decrypt rainbow table from file to buffer array in RAM + if(!file_name) return SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE; uint8_t buffer[SUBGHZ_ALUTECH_AT_4N_RAINBOW_TABLE_SIZE_BYTES] = {0}; uint8_t* buffer_ptr = (uint8_t*)&buffer; diff --git a/lib/subghz/protocols/nice_flor_s.c b/lib/subghz/protocols/nice_flor_s.c index b46f5e747..0b5c39311 100644 --- a/lib/subghz/protocols/nice_flor_s.c +++ b/lib/subghz/protocols/nice_flor_s.c @@ -16,8 +16,10 @@ #define TAG "SubGhzProtocolNiceFlorS" -#define NICE_ONE_COUNT_BIT 72 -#define NICE_ONE_NAME "Nice One" +#define NICE_ONE_COUNT_BIT 72 +#define NICE_ONE_NAME "Nice One" +#define SUBGHZ_NICE_FLOR_S_RAINBOW_TABLE_SIZE_BYTES 32 +#define SUBGHZ_NO_NICE_FLOR_S_RAINBOW_TABLE 0 static const SubGhzBlockConst subghz_protocol_nice_flor_s_const = { .te_short = 500, @@ -414,21 +416,13 @@ static void subghz_protocol_nice_one_get_data(uint8_t* p, uint8_t num_parcel, ui } /** - * Read bytes from rainbow table - * @param file_name Full path to rainbow table the file + * Read bytes from buffer array with rainbow table + * @param buffer pointer to decrypted rainbow table * @param address Byte address in file * @return data */ -static uint8_t - subghz_protocol_nice_flor_s_get_byte_in_file(const char* file_name, uint32_t address) { - if(!file_name) return 0; - - uint8_t buffer[1] = {0}; - if(subghz_keystore_raw_get_data(file_name, address, buffer, sizeof(uint8_t))) { - return buffer[0]; - } else { - return 0; - } +static uint8_t subghz_protocol_nice_flor_s_get_byte_from_buffer(uint8_t* buffer, uint8_t address) { + return buffer[address]; } static inline void subghz_protocol_decoder_nice_flor_s_magic_xor(uint8_t* p, uint8_t k) { @@ -438,16 +432,28 @@ static inline void subghz_protocol_decoder_nice_flor_s_magic_xor(uint8_t* p, uin } uint64_t subghz_protocol_nice_flor_s_encrypt(uint64_t data, const char* file_name) { + // load and decrypt rainbow table from file to buffer array in RAM + if(!file_name) return SUBGHZ_NO_NICE_FLOR_S_RAINBOW_TABLE; + + uint8_t buffer[SUBGHZ_NICE_FLOR_S_RAINBOW_TABLE_SIZE_BYTES] = {0}; + uint8_t* buffer_ptr = (uint8_t*)&buffer; + + if(subghz_keystore_raw_get_data( + file_name, 0, buffer, SUBGHZ_NICE_FLOR_S_RAINBOW_TABLE_SIZE_BYTES)) { + } else { + return SUBGHZ_NO_NICE_FLOR_S_RAINBOW_TABLE; + } + uint8_t* p = (uint8_t*)&data; uint8_t k = 0; for(uint8_t y = 0; y < 2; y++) { - k = subghz_protocol_nice_flor_s_get_byte_in_file(file_name, p[0] & 0x1f); + k = subghz_protocol_nice_flor_s_get_byte_from_buffer(buffer_ptr, p[0] & 0x1f); subghz_protocol_decoder_nice_flor_s_magic_xor(p, k); p[5] &= 0x0f; p[0] ^= k & 0xe0; - k = subghz_protocol_nice_flor_s_get_byte_in_file(file_name, p[0] >> 3) + 0x25; + k = subghz_protocol_nice_flor_s_get_byte_from_buffer(buffer_ptr, p[0] >> 3) + 0x25; subghz_protocol_decoder_nice_flor_s_magic_xor(p, k); p[5] &= 0x0f; @@ -475,6 +481,19 @@ static uint64_t subghz_protocol_nice_flor_s_decrypt(SubGhzBlockGeneric* instance, const char* file_name) { furi_assert(instance); uint64_t data = instance->data; + + // load and decrypt rainbow table from file to buffer array in RAM + if(!file_name) return SUBGHZ_NO_NICE_FLOR_S_RAINBOW_TABLE; + + uint8_t buffer[SUBGHZ_NICE_FLOR_S_RAINBOW_TABLE_SIZE_BYTES] = {0}; + uint8_t* buffer_ptr = (uint8_t*)&buffer; + + if(subghz_keystore_raw_get_data( + file_name, 0, buffer, SUBGHZ_NICE_FLOR_S_RAINBOW_TABLE_SIZE_BYTES)) { + } else { + return SUBGHZ_NO_NICE_FLOR_S_RAINBOW_TABLE; + } + uint8_t* p = (uint8_t*)&data; uint8_t k = 0; @@ -489,12 +508,12 @@ static uint64_t p[1] = k; for(uint8_t y = 0; y < 2; y++) { - k = subghz_protocol_nice_flor_s_get_byte_in_file(file_name, p[0] >> 3) + 0x25; + k = subghz_protocol_nice_flor_s_get_byte_from_buffer(buffer_ptr, p[0] >> 3) + 0x25; subghz_protocol_decoder_nice_flor_s_magic_xor(p, k); p[5] &= 0x0f; p[0] ^= k & 0x7; - k = subghz_protocol_nice_flor_s_get_byte_in_file(file_name, p[0] & 0x1f); + k = subghz_protocol_nice_flor_s_get_byte_from_buffer(buffer_ptr, p[0] & 0x1f); subghz_protocol_decoder_nice_flor_s_magic_xor(p, k); p[5] &= 0x0f;