From ff2e1acfdb480712b06f6c913424294d9a38e70d Mon Sep 17 00:00:00 2001 From: Max Andreev Date: Fri, 28 Jul 2023 22:45:27 +0300 Subject: [PATCH 01/19] Fix fbtenv restore (#2924) --- scripts/toolchain/fbtenv.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/scripts/toolchain/fbtenv.sh b/scripts/toolchain/fbtenv.sh index 85d13904..a86b0ece 100755 --- a/scripts/toolchain/fbtenv.sh +++ b/scripts/toolchain/fbtenv.sh @@ -38,11 +38,11 @@ fbtenv_wget() fbtenv_restore_env() { TOOLCHAIN_ARCH_DIR_SED="$(echo "$TOOLCHAIN_ARCH_DIR" | sed 's/\//\\\//g')" - PATH="$(echo "$PATH" | /usr/bin/sed "s/$TOOLCHAIN_ARCH_DIR_SED\/python\/bin://g")"; - PATH="$(echo "$PATH" | /usr/bin/sed "s/$TOOLCHAIN_ARCH_DIR_SED\/bin://g")"; - PATH="$(echo "$PATH" | /usr/bin/sed "s/$TOOLCHAIN_ARCH_DIR_SED\/protobuf\/bin://g")"; - PATH="$(echo "$PATH" | /usr/bin/sed "s/$TOOLCHAIN_ARCH_DIR_SED\/openocd\/bin://g")"; - PATH="$(echo "$PATH" | /usr/bin/sed "s/$TOOLCHAIN_ARCH_DIR_SED\/openssl\/bin://g")"; + PATH="$(echo "$PATH" | sed "s/$TOOLCHAIN_ARCH_DIR_SED\/python\/bin://g")"; + PATH="$(echo "$PATH" | sed "s/$TOOLCHAIN_ARCH_DIR_SED\/bin://g")"; + PATH="$(echo "$PATH" | sed "s/$TOOLCHAIN_ARCH_DIR_SED\/protobuf\/bin://g")"; + PATH="$(echo "$PATH" | sed "s/$TOOLCHAIN_ARCH_DIR_SED\/openocd\/bin://g")"; + PATH="$(echo "$PATH" | sed "s/$TOOLCHAIN_ARCH_DIR_SED\/openssl\/bin://g")"; if [ -n "${PS1:-""}" ]; then PS1="$(echo "$PS1" | sed 's/\[fbt\]//g')"; elif [ -n "${PROMPT:-""}" ]; then @@ -104,8 +104,6 @@ fbtenv_check_if_sourced_multiple_times() return 0; fi fi - echo "Warning! FBT environment script was sourced more than once!"; - echo "You might be doing things wrong, please open a new shell!"; return 1; } @@ -160,7 +158,7 @@ fbtenv_get_kernel_type() fbtenv_check_rosetta() { if [ "$ARCH_TYPE" = "arm64" ]; then - if ! /usr/bin/pgrep -q oahd; then + if ! pgrep -q oahd; then echo "Flipper Zero Toolchain needs Rosetta2 to run under Apple Silicon"; echo "Please instal it by typing 'softwareupdate --install-rosetta --agree-to-license'"; return 1; @@ -312,7 +310,9 @@ fbtenv_main() fbtenv_restore_env; return 0; fi - fbtenv_check_if_sourced_multiple_times; + if ! fbtenv_check_if_sourced_multiple_times; then + return 0; + fi; fbtenv_check_env_vars || return 1; fbtenv_check_download_toolchain || return 1; fbtenv_set_shell_prompt; From a2a4fa8cdac2a3c7753100ccaa2f7c9f8c28b9c8 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Tue, 1 Aug 2023 10:56:11 +0300 Subject: [PATCH 02/19] [FL-3408, FL-3429, FL-3430] Backlight notification fix (#2878) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Notifications: display brightness override fix * FuriHalVersionColor update * float comparison fix Co-authored-by: あく --- .../services/notification/notification_app.c | 15 +++++++++++---- .../targets/furi_hal_include/furi_hal_version.h | 1 + scripts/otp.py | 1 + 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/applications/services/notification/notification_app.c b/applications/services/notification/notification_app.c index 2f947fe8..6fa48e7f 100644 --- a/applications/services/notification/notification_app.c +++ b/applications/services/notification/notification_app.c @@ -5,7 +5,7 @@ #include #include #include - +#include #include "notification.h" #include "notification_messages.h" #include "notification_app.h" @@ -104,7 +104,10 @@ static void notification_reset_notification_led_layer(NotificationLedLayer* laye furi_hal_light_set(layer->light, layer->value[LayerInternal]); } -static void notification_reset_notification_layer(NotificationApp* app, uint8_t reset_mask) { +static void notification_reset_notification_layer( + NotificationApp* app, + uint8_t reset_mask, + float display_brightness_set) { if(reset_mask & reset_blink_mask) { furi_hal_light_blink_stop(); } @@ -124,6 +127,9 @@ static void notification_reset_notification_layer(NotificationApp* app, uint8_t notification_sound_off(); } if(reset_mask & reset_display_mask) { + if(!float_is_equal(display_brightness_set, app->settings.display_brightness)) { + furi_hal_light_set(LightBacklight, app->settings.display_brightness * 0xFF); + } furi_timer_start(app->display_timer, notification_settings_display_off_delay_ticks(app)); } } @@ -212,13 +218,14 @@ static void notification_process_notification_message( notification_apply_notification_led_layer( &app->display, notification_message->data.led.value * display_brightness_setting); + reset_mask |= reset_display_mask; } else { + reset_mask &= ~reset_display_mask; notification_reset_notification_led_layer(&app->display); if(furi_timer_is_running(app->display_timer)) { furi_timer_stop(app->display_timer); } } - reset_mask |= reset_display_mask; break; case NotificationMessageTypeLedDisplayBacklightEnforceOn: furi_assert(app->display_led_lock < UINT8_MAX); @@ -370,7 +377,7 @@ static void notification_process_notification_message( } if(reset_notifications) { - notification_reset_notification_layer(app, reset_mask); + notification_reset_notification_layer(app, reset_mask, display_brightness_setting); } } diff --git a/firmware/targets/furi_hal_include/furi_hal_version.h b/firmware/targets/furi_hal_include/furi_hal_version.h index a9339a6c..98d011cb 100644 --- a/firmware/targets/furi_hal_include/furi_hal_version.h +++ b/firmware/targets/furi_hal_include/furi_hal_version.h @@ -33,6 +33,7 @@ typedef enum { FuriHalVersionColorUnknown = 0x00, FuriHalVersionColorBlack = 0x01, FuriHalVersionColorWhite = 0x02, + FuriHalVersionColorTransparent = 0x03, } FuriHalVersionColor; /** Device Regions */ diff --git a/scripts/otp.py b/scripts/otp.py index 19b8c4df..e3f07099 100755 --- a/scripts/otp.py +++ b/scripts/otp.py @@ -17,6 +17,7 @@ OTP_COLORS = { "unknown": 0x00, "black": 0x01, "white": 0x02, + "transparent": 0x03, } OTP_REGIONS = { From 68eb1ecebb463b148b21358dd2ba89b1bfc29e41 Mon Sep 17 00:00:00 2001 From: Dzhos Oleksii <35292229+Programistich@users.noreply.github.com> Date: Tue, 1 Aug 2023 11:20:30 +0300 Subject: [PATCH 03/19] [FL-3385] New RTC flags in device info (#2884) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add new rtc flags to device info * FuriHal: bump info version * Fix local * Rework device info by hierarchy filtering Co-authored-by: あく --- firmware/targets/f7/furi_hal/furi_hal_info.c | 49 +++++++++++++++++++- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_info.c b/firmware/targets/f7/furi_hal/furi_hal_info.c index a2c9232c..cefb6a11 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_info.c +++ b/firmware/targets/f7/furi_hal/furi_hal_info.c @@ -24,10 +24,10 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) { // Device Info version if(sep == '.') { property_value_out(&property_context, NULL, 2, "format", "major", "3"); - property_value_out(&property_context, NULL, 2, "format", "minor", "2"); + property_value_out(&property_context, NULL, 2, "format", "minor", "3"); } else { property_value_out(&property_context, NULL, 3, "device", "info", "major", "2"); - property_value_out(&property_context, NULL, 3, "device", "info", "minor", "3"); + property_value_out(&property_context, NULL, 3, "device", "info", "minor", "4"); } // Model name @@ -298,6 +298,7 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) { property_value_out(&property_context, NULL, 2, "radio", "alive", "false"); } + // RTC flags property_value_out( &property_context, "%u", @@ -305,8 +306,52 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) { "system", "debug", furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)); + property_value_out( + &property_context, "%u", 2, "system", "lock", furi_hal_rtc_is_flag_set(FuriHalRtcFlagLock)); + property_value_out( + &property_context, + "%u", + 2, + "system", + "orient", + furi_hal_rtc_is_flag_set(FuriHalRtcFlagHandOrient)); + property_value_out( + &property_context, + "%u", + 3, + "system", + "sleep", + "legacy", + furi_hal_rtc_is_flag_set(FuriHalRtcFlagLegacySleep)); + property_value_out( + &property_context, + "%u", + 2, + "system", + "stealth", + furi_hal_rtc_is_flag_set(FuriHalRtcFlagStealthMode)); + property_value_out( &property_context, "%u", 3, "system", "heap", "track", furi_hal_rtc_get_heap_track_mode()); + property_value_out(&property_context, "%u", 2, "system", "boot", furi_hal_rtc_get_boot_mode()); + property_value_out( + &property_context, + "%u", + 3, + "system", + "locale", + "time", + furi_hal_rtc_get_locale_timeformat()); + property_value_out( + &property_context, + "%u", + 3, + "system", + "locale", + "date", + furi_hal_rtc_get_locale_dateformat()); + property_value_out( + &property_context, "%u", 3, "system", "locale", "unit", furi_hal_rtc_get_locale_units()); property_value_out( &property_context, "%u", 3, "system", "log", "level", furi_hal_rtc_get_log_level()); From aadb72af53b2b9d95c6b52ce200df1c7112d0d94 Mon Sep 17 00:00:00 2001 From: MMX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 1 Aug 2023 12:09:30 +0300 Subject: [PATCH 04/19] UI: New way to input bytes in byte_input (#2890) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * New byte input UI option * Gui: reformat and cleanup byte_input docs, make PVS happy Co-authored-by: hedger Co-authored-by: あく --- .../services/gui/modules/byte_input.c | 444 ++++++++++-------- 1 file changed, 252 insertions(+), 192 deletions(-) diff --git a/applications/services/gui/modules/byte_input.c b/applications/services/gui/modules/byte_input.c index b2d21f7a..3bca8fc7 100644 --- a/applications/services/gui/modules/byte_input.c +++ b/applications/services/gui/modules/byte_input.c @@ -4,6 +4,7 @@ #include #include +/** ByteInput type */ struct ByteInput { View* view; }; @@ -25,7 +26,7 @@ typedef struct { bool selected_high_nibble; uint8_t selected_byte; - int8_t selected_row; // row -1 - input, row 0 & 1 - keyboard + int8_t selected_row; // row -2 - mini_editor, -1 - input, row 0 & 1 - keyboard uint8_t selected_column; uint8_t first_visible_byte; } ByteInputModel; @@ -61,11 +62,11 @@ static const ByteInputKey keyboard_keys_row_2[] = { {enter_symbol, 95, 17}, }; -/** - * @brief Get row size - * - * @param row_index Index of row - * @return uint8_t Row size +/** Get row size + * + * @param row_index Index of row + * + * @return uint8_t Row size */ static uint8_t byte_input_get_row_size(uint8_t row_index) { uint8_t row_size = 0; @@ -84,11 +85,11 @@ static uint8_t byte_input_get_row_size(uint8_t row_index) { return row_size; } -/** - * @brief Get row pointer - * - * @param row_index Index of row - * @return const ByteInputKey* Row pointer +/** Get row pointer + * + * @param row_index Index of row + * + * @return const ByteInputKey* Row pointer */ static const ByteInputKey* byte_input_get_row(uint8_t row_index) { const ByteInputKey* row = NULL; @@ -107,12 +108,12 @@ static const ByteInputKey* byte_input_get_row(uint8_t row_index) { return row; } -/** - * @brief Get text from nibble - * - * @param byte byte value - * @param high_nibble Get from high nibble, otherwise low nibble - * @return char nibble text +/** Get text from nibble + * + * @param byte byte value + * @param high_nibble Get from high nibble, otherwise low nibble + * + * @return char nibble text */ static char byte_input_get_nibble_text(uint8_t byte, bool high_nibble) { if(high_nibble) { @@ -149,15 +150,20 @@ static char byte_input_get_nibble_text(uint8_t byte, bool high_nibble) { return byte; } -/** - * @brief Draw input box (common view) - * - * @param canvas - * @param model +const char num_to_char[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; + +/** Draw input box (common view) + * + * @param canvas The canvas + * @param model The model */ static void byte_input_draw_input(Canvas* canvas, ByteInputModel* model) { const uint8_t text_x = 8; const uint8_t text_y = 25; + const uint8_t text_y2 = 40; + const bool draw_index_line = + (model->selected_row == -2) && + (model->first_visible_byte + MIN(model->bytes_count, max_drawable_bytes + 1) <= 100); elements_slightly_rounded_frame(canvas, 6, 14, 116, 15); @@ -225,6 +231,27 @@ static void byte_input_draw_input(Canvas* canvas, ByteInputModel* model) { text_y, byte_input_get_nibble_text(model->bytes[i], false)); } + + if(draw_index_line) { + canvas_draw_glyph( + canvas, text_x + 2 + byte_position * 14, text_y2, num_to_char[(i + 1) / 10]); + + canvas_draw_glyph( + canvas, text_x + 8 + byte_position * 14, text_y2, num_to_char[(i + 1) % 10]); + } + } + + if((model->selected_row == -2) && + (model->first_visible_byte + MIN(model->bytes_count, max_drawable_bytes + 1) > 100)) { + char str[20]; + + canvas_set_font(canvas, FontSecondary); + snprintf(str, 20, "Selected index"); + canvas_draw_str(canvas, text_x, text_y2, str); + + canvas_set_font(canvas, FontPrimary); + snprintf(str, 20, "%u", (model->selected_byte + 1)); + canvas_draw_str(canvas, text_x + 75, text_y2, str); } if(model->bytes_count - model->first_visible_byte > max_drawable_bytes) { @@ -236,11 +263,10 @@ static void byte_input_draw_input(Canvas* canvas, ByteInputModel* model) { } } -/** - * @brief Draw input box (selected view) - * - * @param canvas - * @param model +/** Draw input box (selected view) + * + * @param canvas The canvas + * @param model The model */ static void byte_input_draw_input_selected(Canvas* canvas, ByteInputModel* model) { const uint8_t text_x = 7; @@ -297,13 +323,12 @@ static void byte_input_draw_input_selected(Canvas* canvas, ByteInputModel* model canvas_invert_color(canvas); } -/** - * @brief Set nibble at position - * - * @param data where to set nibble - * @param position byte position - * @param value char value - * @param high_nibble set high nibble +/** Set nibble at position + * + * @param data where to set nibble + * @param position byte position + * @param value char value + * @param high_nibble set high nibble */ static void byte_input_set_nibble(uint8_t* data, uint8_t position, char value, bool high_nibble) { switch(value) { @@ -341,29 +366,28 @@ static void byte_input_set_nibble(uint8_t* data, uint8_t position, char value, b } } -/** - * @brief What currently selected - * - * @return true - keyboard selected, false - input selected +/** What currently selected + * + * @param model The model + * + * @return true - keyboard selected, false - input selected */ static bool byte_input_keyboard_selected(ByteInputModel* model) { return model->selected_row >= 0; } -/** - * @brief Do transition from keyboard - * - * @param model +/** Do transition from keyboard + * + * @param model The model */ static void byte_input_transition_from_keyboard(ByteInputModel* model) { model->selected_row += 1; model->selected_high_nibble = true; } -/** - * @brief Increase selected byte position - * - * @param model +/** Increase selected byte position + * + * @param model The model */ static void byte_input_inc_selected_byte(ByteInputModel* model) { if(model->selected_byte < model->bytes_count - 1) { @@ -379,10 +403,20 @@ static void byte_input_inc_selected_byte(ByteInputModel* model) { } } -/** - * @brief Decrease selected byte position - * - * @param model +static void byte_input_inc_selected_byte_mini(ByteInputModel* model) { + if((model->selected_byte < model->bytes_count - 1) || model->selected_high_nibble) { + if(!model->selected_high_nibble) { + model->selected_high_nibble = !model->selected_high_nibble; //-V547 + byte_input_inc_selected_byte(model); + } else { + model->selected_high_nibble = !model->selected_high_nibble; //-V547 + } + } +} + +/** Decrease selected byte position + * + * @param model The model */ static void byte_input_dec_selected_byte(ByteInputModel* model) { if(model->selected_byte > 0) { @@ -397,10 +431,20 @@ static void byte_input_dec_selected_byte(ByteInputModel* model) { } } -/** - * @brief Call input callback - * - * @param model +static void byte_input_dec_selected_byte_mini(ByteInputModel* model) { + if(model->selected_byte > 0 || !model->selected_high_nibble) { + if(model->selected_high_nibble) { + model->selected_high_nibble = !model->selected_high_nibble; //-V547 + byte_input_dec_selected_byte(model); + } else { + model->selected_high_nibble = !model->selected_high_nibble; //-V547 + } + } +} + +/** Call input callback + * + * @param model The model */ static void byte_input_call_input_callback(ByteInputModel* model) { if(model->input_callback != NULL) { @@ -408,10 +452,9 @@ static void byte_input_call_input_callback(ByteInputModel* model) { } } -/** - * @brief Call changed callback - * - * @param model +/** Call changed callback + * + * @param model The model */ static void byte_input_call_changed_callback(ByteInputModel* model) { if(model->changed_callback != NULL) { @@ -419,8 +462,9 @@ static void byte_input_call_changed_callback(ByteInputModel* model) { } } -/** - * @brief Clear selected byte +/** Clear selected byte + * + * @param model The model */ static void byte_input_clear_selected_byte(ByteInputModel* model) { @@ -430,36 +474,55 @@ static void byte_input_clear_selected_byte(ByteInputModel* model) { byte_input_call_changed_callback(model); } -/** - * @brief Handle up button - * - * @param model +/** Handle up button + * + * @param model The model */ static void byte_input_handle_up(ByteInputModel* model) { - if(model->selected_row > -1) { + if(model->selected_row > -2) { model->selected_row -= 1; + } else if(model->selected_row == -2) { + if(!model->selected_high_nibble) { + model->bytes[model->selected_byte] = (model->bytes[model->selected_byte] & 0xF0) | + ((model->bytes[model->selected_byte] + 1) & 0x0F); + } else { + model->bytes[model->selected_byte] = + ((model->bytes[model->selected_byte] + 0x10) & 0xF0) | + (model->bytes[model->selected_byte] & 0x0F); + } + byte_input_call_changed_callback(model); } } -/** - * @brief Handle down button - * - * @param model +/** Handle down button + * + * @param model The model */ static void byte_input_handle_down(ByteInputModel* model) { - if(byte_input_keyboard_selected(model)) { - if(model->selected_row < keyboard_row_count - 1) { - model->selected_row += 1; + if(model->selected_row != -2) { + if(byte_input_keyboard_selected(model)) { + if(model->selected_row < keyboard_row_count - 1) { + model->selected_row += 1; + } + } else { + byte_input_transition_from_keyboard(model); } } else { - byte_input_transition_from_keyboard(model); + if(!model->selected_high_nibble) { + model->bytes[model->selected_byte] = (model->bytes[model->selected_byte] & 0xF0) | + ((model->bytes[model->selected_byte] - 1) & 0x0F); + } else { + model->bytes[model->selected_byte] = + ((model->bytes[model->selected_byte] - 0x10) & 0xF0) | + (model->bytes[model->selected_byte] & 0x0F); + } + byte_input_call_changed_callback(model); } } -/** - * @brief Handle left button - * - * @param model +/** Handle left button + * + * @param model The model */ static void byte_input_handle_left(ByteInputModel* model) { if(byte_input_keyboard_selected(model)) { @@ -469,14 +532,17 @@ static void byte_input_handle_left(ByteInputModel* model) { model->selected_column = byte_input_get_row_size(model->selected_row) - 1; } } else { - byte_input_dec_selected_byte(model); + if(model->selected_row != -2) { + byte_input_dec_selected_byte(model); + } else { + byte_input_dec_selected_byte_mini(model); + } } } -/** - * @brief Handle right button - * - * @param model +/** Handle right button + * + * @param model The model */ static void byte_input_handle_right(ByteInputModel* model) { if(byte_input_keyboard_selected(model)) { @@ -486,14 +552,17 @@ static void byte_input_handle_right(ByteInputModel* model) { model->selected_column = 0; } } else { - byte_input_inc_selected_byte(model); + if(model->selected_row != -2) { + byte_input_inc_selected_byte(model); + } else { + byte_input_inc_selected_byte_mini(model); + } } } -/** - * @brief Handle OK button - * - * @param model +/** Handle OK button + * + * @param model The model */ static void byte_input_handle_ok(ByteInputModel* model) { if(byte_input_keyboard_selected(model)) { @@ -514,16 +583,17 @@ static void byte_input_handle_ok(ByteInputModel* model) { } byte_input_call_changed_callback(model); } + } else if(model->selected_row == -2) { + byte_input_call_input_callback(model); } else { byte_input_transition_from_keyboard(model); } } -/** - * @brief Draw callback - * - * @param canvas - * @param _model +/** Draw callback + * + * @param canvas The canvas + * @param _model The model */ static void byte_input_view_draw_callback(Canvas* canvas, void* _model) { ByteInputModel* model = _model; @@ -541,80 +611,89 @@ static void byte_input_view_draw_callback(Canvas* canvas, void* _model) { byte_input_draw_input(canvas, model); } - for(uint8_t row = 0; row < keyboard_row_count; row++) { - const uint8_t column_count = byte_input_get_row_size(row); - const ByteInputKey* keys = byte_input_get_row(row); + if(model->selected_row == -2) { + canvas_set_font(canvas, FontSecondary); + canvas_draw_icon(canvas, 3, 52, &I_Pin_back_arrow_10x8); + canvas_draw_str_aligned(canvas, 16, 60, AlignLeft, AlignBottom, "back to keyboard"); + } else { + // Draw keyboard + for(uint8_t row = 0; row < keyboard_row_count; row++) { + const uint8_t column_count = byte_input_get_row_size(row); + const ByteInputKey* keys = byte_input_get_row(row); - for(size_t column = 0; column < column_count; column++) { - if(keys[column].value == enter_symbol) { - canvas_set_color(canvas, ColorBlack); - if(model->selected_row == row && model->selected_column == column) { - canvas_draw_icon( - canvas, - keyboard_origin_x + keys[column].x, - keyboard_origin_y + keys[column].y, - &I_KeySaveSelected_24x11); - } else { - canvas_draw_icon( - canvas, - keyboard_origin_x + keys[column].x, - keyboard_origin_y + keys[column].y, - &I_KeySave_24x11); - } - } else if(keys[column].value == backspace_symbol) { - canvas_set_color(canvas, ColorBlack); - if(model->selected_row == row && model->selected_column == column) { - canvas_draw_icon( - canvas, - keyboard_origin_x + keys[column].x, - keyboard_origin_y + keys[column].y, - &I_KeyBackspaceSelected_16x9); - } else { - canvas_draw_icon( - canvas, - keyboard_origin_x + keys[column].x, - keyboard_origin_y + keys[column].y, - &I_KeyBackspace_16x9); - } - } else { - if(model->selected_row == row && model->selected_column == column) { + for(size_t column = 0; column < column_count; column++) { + if(keys[column].value == enter_symbol) { canvas_set_color(canvas, ColorBlack); - canvas_draw_box( - canvas, - keyboard_origin_x + keys[column].x - 3, - keyboard_origin_y + keys[column].y - 10, - 11, - 13); - canvas_set_color(canvas, ColorWhite); - } else if(model->selected_row == -1 && row == 0 && model->selected_column == column) { + if(model->selected_row == row && model->selected_column == column) { + canvas_draw_icon( + canvas, + keyboard_origin_x + keys[column].x, + keyboard_origin_y + keys[column].y, + &I_KeySaveSelected_24x11); + } else { + canvas_draw_icon( + canvas, + keyboard_origin_x + keys[column].x, + keyboard_origin_y + keys[column].y, + &I_KeySave_24x11); + } + } else if(keys[column].value == backspace_symbol) { canvas_set_color(canvas, ColorBlack); - canvas_draw_frame( - canvas, - keyboard_origin_x + keys[column].x - 3, - keyboard_origin_y + keys[column].y - 10, - 11, - 13); + if(model->selected_row == row && model->selected_column == column) { + canvas_draw_icon( + canvas, + keyboard_origin_x + keys[column].x, + keyboard_origin_y + keys[column].y, + &I_KeyBackspaceSelected_16x9); + } else { + canvas_draw_icon( + canvas, + keyboard_origin_x + keys[column].x, + keyboard_origin_y + keys[column].y, + &I_KeyBackspace_16x9); + } } else { - canvas_set_color(canvas, ColorBlack); - } + if(model->selected_row == row && model->selected_column == column) { + canvas_set_color(canvas, ColorBlack); + canvas_draw_box( + canvas, + keyboard_origin_x + keys[column].x - 3, + keyboard_origin_y + keys[column].y - 10, + 11, + 13); + canvas_set_color(canvas, ColorWhite); + } else if( + model->selected_row == -1 && row == 0 && + model->selected_column == column) { + canvas_set_color(canvas, ColorBlack); + canvas_draw_frame( + canvas, + keyboard_origin_x + keys[column].x - 3, + keyboard_origin_y + keys[column].y - 10, + 11, + 13); + } else { + canvas_set_color(canvas, ColorBlack); + } - canvas_draw_glyph( - canvas, - keyboard_origin_x + keys[column].x, - keyboard_origin_y + keys[column].y, - keys[column].value); + canvas_draw_glyph( + canvas, + keyboard_origin_x + keys[column].x, + keyboard_origin_y + keys[column].y, + keys[column].value); + } } } } } -/** - * @brief Input callback - * - * @param event - * @param context - * @return true - * @return false +/** Input callback + * + * @param event The event + * @param context The context + * + * @return true + * @return false */ static bool byte_input_view_input_callback(InputEvent* event, void* context) { ByteInput* byte_input = context; @@ -656,6 +735,20 @@ static bool byte_input_view_input_callback(InputEvent* event, void* context) { } } + if(event->type == InputTypeShort && event->key == InputKeyBack) { + // Back to keyboard + with_view_model( + byte_input->view, + ByteInputModel * model, + { + if(model->selected_row == -2) { + model->selected_row += 1; + consumed = true; + }; + }, + true); + } + if((event->type == InputTypeLong || event->type == InputTypeRepeat) && event->key == InputKeyBack) { with_view_model( @@ -669,10 +762,9 @@ static bool byte_input_view_input_callback(InputEvent* event, void* context) { return consumed; } -/** - * @brief Reset all input-related data in model - * - * @param model ByteInputModel +/** Reset all input-related data in model + * + * @param model The model */ static void byte_input_reset_model_input_data(ByteInputModel* model) { model->bytes = NULL; @@ -684,11 +776,6 @@ static void byte_input_reset_model_input_data(ByteInputModel* model) { model->first_visible_byte = 0; } -/** - * @brief Allocate and initialize byte input. This byte input is used to enter bytes. - * - * @return ByteInput instance pointer - */ ByteInput* byte_input_alloc() { ByteInput* byte_input = malloc(sizeof(ByteInput)); byte_input->view = view_alloc(); @@ -712,38 +799,17 @@ ByteInput* byte_input_alloc() { return byte_input; } -/** - * @brief Deinitialize and free byte input - * - * @param byte_input Byte input instance - */ void byte_input_free(ByteInput* byte_input) { furi_assert(byte_input); view_free(byte_input->view); free(byte_input); } -/** - * @brief Get byte input view - * - * @param byte_input byte input instance - * @return View instance that can be used for embedding - */ View* byte_input_get_view(ByteInput* byte_input) { furi_assert(byte_input); return byte_input->view; } -/** - * @brief Deinitialize and free byte input - * - * @param byte_input byte input instance - * @param input_callback input callback fn - * @param changed_callback changed callback fn - * @param callback_context callback context - * @param bytes buffer to use - * @param bytes_count buffer length - */ void byte_input_set_result_callback( ByteInput* byte_input, ByteInputCallback input_callback, @@ -765,12 +831,6 @@ void byte_input_set_result_callback( true); } -/** - * @brief Set byte input header text - * - * @param byte_input byte input instance - * @param text text to be shown - */ void byte_input_set_header_text(ByteInput* byte_input, const char* text) { with_view_model( byte_input->view, ByteInputModel * model, { model->header = text; }, true); From fe7a1c2fccc96a1dc0589d5f01db8e22ffd9c122 Mon Sep 17 00:00:00 2001 From: MMX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 1 Aug 2023 12:32:24 +0300 Subject: [PATCH 05/19] SubGHz - Keeloq: Read Centurion Nova remotes (#2892) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: hedger Co-authored-by: あく --- assets/resources/subghz/assets/keeloq_mfcodes | 107 +++++++++--------- lib/subghz/protocols/keeloq.c | 26 ++++- 2 files changed, 77 insertions(+), 56 deletions(-) diff --git a/assets/resources/subghz/assets/keeloq_mfcodes b/assets/resources/subghz/assets/keeloq_mfcodes index 3eedc564..f2e45b49 100644 --- a/assets/resources/subghz/assets/keeloq_mfcodes +++ b/assets/resources/subghz/assets/keeloq_mfcodes @@ -1,56 +1,57 @@ Filetype: Flipper SubGhz Keystore File Version: 0 Encryption: 1 -IV: 41 84 34 43 84 1D 43 04 45 44 34 38 41 24 3E 74 -8C5AEF725F0620DB3952B40BB8E76A815BCEE1D1B92F7E8E8E63D1894F1C7FD0 -1DFF1D6A322D6B3D8AD7C594A02462AADE723D417B9233585526982F08187DAA -0A9184F15D4A5589DDDA6422063BACD58580661CFE60EE600D87F73F0CB5013E -6E56802DAA049C3DFDEDC90432A0E694A172C369EBECD136F4C911B979AA098D -A659716B51053604059F7FC3651D6A153F5EAB1852F95B20C44C41A7889A0DE91A078B63E3C311280C4315F0A3C8BA1F -A315170EDC51627157725D9A96490DB75EBF8232957FBA313C03B2BA2884EA85 -DEAB3C2C2E2DC76FE45AEBAC7EBFB478CECCD970A63B8DE2024FBFDCCBD1B26E -7BBFC36CBA77468B4624C6B685610877D53985C985DAD8EFE47527EB7C7260CD -879EE18B314ED4F3F548B41176099176FB97F4F1A062481C935B2DDFBCE2FE4D -493372D7D47A96A66305DFDC8A915EB651620881AE1D603B7E9605E004C04CA9 -F80AAA4C447F8E8C0B039DDAECF9126119C32FF164118780BE268E326A8CBF8010DE2EBF94033CEAC39815D6A8958CF4 -41C1393A039E665F6A53A5E5D1C105008BD14D9755751545A667860C39B2E39AA47306E76E2BA7DDDAA2A286FDB58D23 -34853A4CDE42CB80045E641AB4800C86C1CF6907EAAFA399156CCC727A008584 -D0783A34BD6A36D31BFF5F70FA1116CAE48EF02716D80481AE406DABB3C3400E -0BB3582605434CF2A5D74A27773B88DA331B6033C444837E9F7A155897258B03 -E4E71F3EB290B9436FFF0FDADA468BE37D964E89BE8D9971A14776F821822769 -744AA59D129C892120B5DAB81C8A3D573B0AD80EF0708C1B9ECF13DA60CECA07DC0591A08611DB4D3A8B7C70994D5DEF -716F9F8D5D2C697BC4183EFCC97E52D08ECA07B613A0F389C801F65803DFF4A4 -560262DA8489D2C18C8D97E314DC663403AFE4DE9DCB6D453087D2BFBD36532D -9E31F7152C50B6940EE3E3894C98F75702C7897F702B48E5C9B54B6E25083641AD2E521267505066C7E5BAB7F6CF1433 -6630EDA18A6E58BD395792CCC656DD10CD9C5DD2B1949FE677122FA39A53C724E79C0D0752A3A39A03407BBA2282185E -00D15A06F5DD82A4B926B78809CC4D129AAFA9A92B0A81568F255D15697FE0FD -29FF9A4F5346ABEE8FEDE034988F87FCD29EA747735898F1E7207EF74FAB71A8 -C0E8EB6AE6F77EE38DF2AB1B7742E34ED5236F3D8E964845E66762A4675AA21F -00FC4C459DC4CE92B62D0AC2546F9FBBE0893F84D2AF0A20ED462A5EAE63DE3B -E92EF482A40CEEFC8339BBB713BBC452A266A09B2645EDEB12716544B2DB9B09 -D7D9C5C757831BCE2FF1DB25A080D77769FB36A1F3F48F4361418A0A45609280 -C19246F52AE1EE5CE968CED52F642D9CD78B020029632FE83C49C657D23ED075 -FEE3C05432FB3860D5D28562323F5D1B053B8F3ADCD416BD0C4645F6F4D43DCF -D780A4AADD0205E0BACDCC9AF46ED259E0946C5DA888C341BFE96E09A87CCCFA -CE3C13CFA08E532B637FDB707E29548D57EE92EAEF6516C3D67E9D36FCD59CF9 -5E88CE71258CB0D91631FEB41C9A2F47AE0FF4810A9A1EDF3F308BBDE6944D5E -1531F4107FC64810BA5DB5E46C7B9AD61531AF5430E137B7688109FBC06B6221 -68050A39C0B302E0B713FAAC5F829C79AB30E18B1D982A94005DBAC7CCFB95379A619C0B9F7409C44D19FF2C5E8E4546 -3F73E8BA22C602280496EF8E88E2CAA9EC442E3B3083B684942DBF9CB5121241 -FA1FCD7C9182FAE8FFF4E88433AE68F66076B3BDFF8AD0BF5CEA43870082E9BE -DFF7DD2678C03401656B093BF7AC7E033F15FD0F30188E48A62045740B423699 -371BCFF653E7811D99C048A1A39921AAA563E06AC86CB3D2F392C2C955A1ABD0 -F4F1766DEAEDE934478208B9EB3050326D9FFCC001C73EEE93407D8B12CD49E4 -A241C9FC62DDF67D645936245FAFFE2A42C86151F484B7BCE5410E8F36FC87901D3AC4E40334E08FFFC2AD676E490D94 -3566A94A9C0479E0C4387D9137375ADF2C921504364F3903F198D6757CDFD21B -7274E1B5A6445FDC29C355D550E981C17F349BC4A14251B3B51BC96FC334FBCA -04EEA5EDD9B3BC3E0638E53A5561DC8BF761D615A64D435BD31A94AF2650159E -B84818CC1695FE8B731CD653D0679D1AAA0578C0B06AD1E3510785B2DE20841C -4121343D6B79E38C06DD038D770D76D10336AFF47ED0D0DCDDD6B0FEA4DAE67C -75E49C839CCD7019D9CE90AC364F488468B2AB01E387A8BEF8815915925166A6 -CFAA9F4717568C1EC7B96E0D71D260B828A70484E1D9CA7C99A50D10704F8BBBAE62EE98C9FBDFF06F357F1C1E2F2677 -41E4D250B92BC57442B91DE2015C41226531CF9A8D77B83AFC8E4F3183DB11DE -45EA8BD854D7F044FB249C16F08A0C24FF117D54BC20A4CC667B3DAD09EAC4F9 -F455CA0BB8B496C301406DE4FB52C9B0F64645776803BC2935A2F38675318BE2 -22FF72A5D2E1A2EBFB6C55FFD0A3CEA0474CCBD13462D63229C9708276E87D3F -8470F9A300170F226C0216C07AA829591CBD4CE34AA918EAE49363BDE86CC77EEEBEEA84A097488D35B92F773F5DBB4C +IV: 23 17 32 54 92 3A 28 13 12 DE 8B A7 24 71 25 74 +B8ACA082EA4B34E8B217A6FE63F3545D160AB7F4833C87E8743BAA7002ACC123 +E779135FE66629CAC4661B1C3D5C9857C9417CAF216241933FF6CE60A74D53C0 +15340C049A444C79ED489619A31E2AFDCFF6E4864CC4D9B1DA8E98D7EAB9C8D5 +8E696E85837B3BA8D6D380E1F36E445D630CF0B7B18A45930A08F832EE634A02 +C85341BE669E509E902FEFCA7D025A20DC80D4F14FE1C3542B1DC3A5C7393A36F901A63C3BC074B058897B12F0F5F0D6 +2834E5D7726670A03ED6C8B27B5863EEE2FD3668795251AB65B9E4FF76ADEC3E +8E71AF7660BCFC545E92674D74F98A35FCF1B54AB5BACCEE182B7F8EDB3FA356 +C20442D506332D1A410AF3187C29BE01729C282A69B85CF8D92D70FAE3407BA8 +00BC449D006566A6549A86F52B98410871B0C14D60C181BFC017446B192C934A +8A6A28DAF1F61867B1209AB9105986A7383ECE72A40F8D93F1D0066251800A3A +4A6AFDFA6130A50180358B111145D7914C720E04D69EE5459C049FCD64249153315F86A5A9F75AEE5CB726847BA64F2A +91F838BC515C8CDD32C5803679B81A24FD5CF0C3A4AEA2C07342ACA1020E05F3B393A410B33847A8C48141D923202CF3 +7C4DEBC03295291EC5B2EBB002670D14E7C972F32DB2B3CD4E61B2BE846345D9 +8FFEB948DA3D1A7FCF620F043B1D35354F83861F22B6D693F2A7119A2E287D01 +309C66AF38E6447CB33FB0967C9365CA36314DBF74695F63CF9E558A4FF5193B +411D32EC6ADED3360DE9E9A0962F97DF2B80A09F2A2AC8D4DB6DB09FAD6EA217 +A5E5550BD59425003F9166237CD4BB6A323885D7916F71F3B2795B8A4C7125ACC1237BBF0840F0E999BD2EC14327654F +4370A828AFED684B96E8EDAB670C46D2D525FCB7E469B63CD1228C902C3ACF4E +88E3853F58129C4D834B18E4D01785591094301148D802A3A21B63521DDDA325 +D5365BF55DFE7107909684F4ECCE052E617F91FAF08CE5254721A30BEF87F368F329C46439BD1EA2819DC416B2CEF247 +BDAB9FFD3A82ECE05E8CA00F11954CDB1C124B558A5D369DFE16D32C3AEF08B2013945CC69212F170F17F62A55D35928 +8E448AA1D39C894F306FE65B0D0DD733717EF81758FFA908AF7583BFD00108E5 +019A1B0AA3492427DF3DB817B438D0302B0B8C77807D19EE45EAC7F697B2EB85 +C678A3F9DA726FE1688F86BB063EA017EDB5389E0F185484D9F5DFD4EBEE0579 +760F77AB9BD99593AC855E4AE00FBAFBB34FA2BFF504BD5CC9557658E850C6D0 +4F3E77342E9A655D4EC167E2B0428833FEE31CF603FA1CE3D1BCD619D5C9D511 +2233EFBEDD4A3A95BA8160EFCED533D9F25B65AAB10F627681D2753871814366 +A1261BE878933B4905956BE7708F7C40E999714503B52B8021D44E131D87FF6C +8F31E76314A46EA9B0CCD3EDA4B2DF603829D8E3AF8CE41AEA6BFFBA2E2990AC +850C08E45CDA4E42BD4F09B956299C0ED58615BE3664791C88D1E2608D46D205 +6283656518C6ADFC3B7D309D2763BD91111720CD51029FAA691211DEFF84CB47 +9FCAF9F77C9D1B9B6934E53DB10DFF88D392D8E7BB4DC28D65F65DC396E2E00A +41D2406BE1887FCC094861E4DF0683B1BE534C5CBF059259E946F9D04222C2AB +1D6F37E645591F0C491312C1E0CB54F1A6B70F94B54D63100C4584AA016DB589338A704B6D8B6B89C2381F660D987A2F +DCEA08D6E5C0D6229EBDE07DBB6CBC0EA8D6E24A3B631CC3775CE23A496CF178 +907051215A741BE55603F27C3FD86561CC6231CEED83AA76665D6A0B6B3FEC88 +36CD5B5BCC63D45B89592B2938D6542B9D82AB47BEB73C0D30D2EC19BD8B35C2 +1FD9651ABAD773D6D22DE677CF7B19615D5B805594DCA117F04AC3255AE8184A +4900723A8F7736C9BEAE938EE021F3E44AD806244010F825D04C59E6C67B5EA2 +0D56A8CE77106DA2CB44F65B8CF5F4A024B9CC774D1C4CB8E862C95BD30B42E7B2E946CAC361F2830361C010DC938833 +11543FD104EA7D68B6B9C3BFE3F25A84F651FCB7FB5423AADDC472A48E12AFB2 +98CD236E8B92D706DA0F92F43AC1D2CAF1CFBCDC7B330A7C9D65CDC4F2E2A677 +753557A9A5075C033206111E3C832044227A32EBF3AB2B08F6FBFCC2109B2F2A +4AA124232EF6C25CB7321F5E5F7BE11114C763F8DDAFB6B05E8412ADF37B5C7B +01514EA408E26BAFD30290429DE1A0211F4FBDB09DE2E66CE92A6F09B998EF29 +4715716D5AFF99A2D8205A46AEEF0BC20D72F3F54991F7DF4142FF187485C178 +281A32B90F8B85F31F54BF0D83B6D03E4E65A72ADB3D5A297C91881E36B45E8F +9C05D3CB9F473D5693697A8567DBA7CF650C0A0D6C1BBE3ACE78ACDE0BD027B6C836B6CB6365D5B5D00F101FA83876B9 +DC88B0237634CB007244A4169A5D9F5F65FC782E3C4388358A7E2019F7B4CC05 +BC7ACAA91D23616A0070DCA328901DDDE3BB5B59260FB45083916B6ED0E6450C +A280434D059D652D77ACB9F44409CDC7393A876239BA894DD4BE843FAB0AC561 +334F1316A35EB8A838F6B209FA4F8148062972E27A296379731B1F728A0BB32E +DDC9883E90EBE73915CFDF8EA7193F2449B66010D45F5EC6F20949D5C49719A9298B95269531A3440577B00EADE1B379 diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index 7748da1e..80fecbbf 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -467,6 +467,19 @@ static inline bool subghz_protocol_keeloq_check_decrypt( } return false; } +// Centurion specific check +static inline bool subghz_protocol_keeloq_check_decrypt_centurion( + SubGhzBlockGeneric* instance, + uint32_t decrypt, + uint8_t btn) { + furi_assert(instance); + + if((decrypt >> 28 == btn) && (((((uint16_t)(decrypt >> 16)) & 0x3FF) == 0x1CE))) { + instance->cnt = decrypt & 0x0000FFFF; + return true; + } + return false; +} /** * Checking the accepted code against the database manafacture key @@ -509,9 +522,16 @@ static uint8_t subghz_protocol_keeloq_check_remote_controller_selector( // https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37 man = subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key); decrypt = subghz_protocol_keeloq_common_decrypt(hop, man); - if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { - *manufacture_name = furi_string_get_cstr(manufacture_code->name); - return 1; + if((strcmp(furi_string_get_cstr(manufacture_code->name), "Centurion") == 0)) { + if(subghz_protocol_keeloq_check_decrypt_centurion(instance, decrypt, btn)) { + *manufacture_name = furi_string_get_cstr(manufacture_code->name); + return 1; + } + } else { + if(subghz_protocol_keeloq_check_decrypt(instance, decrypt, btn, end_serial)) { + *manufacture_name = furi_string_get_cstr(manufacture_code->name); + return 1; + } } break; case KEELOQ_LEARNING_SECURE: From 67ca96ea96cdcdf0942b7186128db9a8db3e88a6 Mon Sep 17 00:00:00 2001 From: Francis Date: Tue, 1 Aug 2023 11:45:39 +0200 Subject: [PATCH 06/19] Added French Canadian layout (#2896) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit French Canadian layout for Windows Co-authored-by: あく --- assets/resources/badusb/assets/layouts/fr-CA.kl | Bin 0 -> 256 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 assets/resources/badusb/assets/layouts/fr-CA.kl diff --git a/assets/resources/badusb/assets/layouts/fr-CA.kl b/assets/resources/badusb/assets/layouts/fr-CA.kl new file mode 100644 index 0000000000000000000000000000000000000000..9de8a4732d3184c4de543bec65d445bcc6e82200 GIT binary patch literal 256 zcmaKnHx9x;0KhDZ-g|F>6hxO$lJ)-oDp*d}Zgp{{$itwNeC-+vYTC;A$rY+lc?Ao*Mz@a0@PMkV(?!u)j*KXXJ vhTJSXx%&(is??~{ph=519lG@BGhoPwF%zcDn6qHXiZvUy#32t!czw@4f$0q} literal 0 HcmV?d00001 From 1536f7a643ce9636745f5270bbd79f53249bfc2a Mon Sep 17 00:00:00 2001 From: Astro <130178009+astro-cyberpaws@users.noreply.github.com> Date: Tue, 1 Aug 2023 06:33:17 -0700 Subject: [PATCH 07/19] Update audio.ir (#2897) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update audio.ir: added Panasonic SA-PM193 codes to universal remote * Update audio.ir: added play/pause code as Pause button Co-authored-by: あく --- assets/resources/infrared/assets/audio.ir | 49 +++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/assets/resources/infrared/assets/audio.ir b/assets/resources/infrared/assets/audio.ir index 825d1bc3..3b9e626b 100644 --- a/assets/resources/infrared/assets/audio.ir +++ b/assets/resources/infrared/assets/audio.ir @@ -328,3 +328,52 @@ type: parsed protocol: NECext address: 30 FC 00 00 command: 0C F3 00 00 +# +# Model: Panasonic SA-PM193 +name: Power +type: parsed +protocol: Kaseikyo +address: AC 02 20 00 +command: D1 03 00 00 +# CD play/pause, tape play also exists but probably less commonly used +name: Play +type: parsed +protocol: Kaseikyo +address: AA 02 20 00 +command: A0 00 00 00 +# same as above +name: Pause +type: parsed +protocol: Kaseikyo +address: AA 02 20 00 +command: A0 00 00 00 +# +name: Vol_up +type: parsed +protocol: Kaseikyo +address: A0 02 20 00 +command: 00 02 00 00 +# +name: Vol_dn +type: parsed +protocol: Kaseikyo +address: A0 02 20 00 +command: 10 02 00 00 +# +name: Next +type: parsed +protocol: Kaseikyo +address: AC 02 20 01 +command: A1 00 00 00 +# +name: Prev +type: parsed +protocol: Kaseikyo +address: AC 02 20 01 +command: 91 00 00 00 +# +name: Mute +type: parsed +protocol: Kaseikyo +address: A0 02 20 00 +command: 20 03 00 00 From 17bcfee2242f5fe00923fdc61cec5a4f3c856719 Mon Sep 17 00:00:00 2001 From: hedger Date: Tue, 1 Aug 2023 18:43:14 +0300 Subject: [PATCH 08/19] [FL-3441] faploader: always create app dir, even if it doesn't have subdirs (#2901) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- lib/flipper_application/application_assets.c | 25 ++++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/lib/flipper_application/application_assets.c b/lib/flipper_application/application_assets.c index 1262870d..083c3ca1 100644 --- a/lib/flipper_application/application_assets.c +++ b/lib/flipper_application/application_assets.c @@ -157,14 +157,6 @@ static bool flipper_application_assets_process_dirs( FuriString* full_path = flipper_application_assets_alloc_app_full_path(app_name); do { - if(!storage_simply_mkdir(storage, APPS_ASSETS_PATH)) { - break; - } - - if(!storage_simply_mkdir(storage, furi_string_get_cstr(full_path))) { - break; - } - FuriString* dir_path = furi_string_alloc(); char* path = NULL; @@ -279,6 +271,8 @@ bool flipper_application_assets_load(File* file, const char* elf_path, size_t of FURI_LOG_D(TAG, "Loading assets for %s", furi_string_get_cstr(app_name)); + FuriString* full_path = flipper_application_assets_alloc_app_full_path(app_name); + do { if(!storage_file_seek(file, offset, true)) { break; @@ -319,13 +313,23 @@ bool flipper_application_assets_load(File* file, const char* elf_path, size_t of FURI_LOG_D(TAG, "Assets removed"); } + if(!storage_simply_mkdir(storage, APPS_ASSETS_PATH)) { + break; + } + + if(!storage_simply_mkdir(storage, furi_string_get_cstr(full_path))) { + break; + } + // process directories - if(!flipper_application_assets_process_dirs(storage, file, app_name, header.dirs_count)) { + if(header.dirs_count && + !flipper_application_assets_process_dirs(storage, file, app_name, header.dirs_count)) { break; } // process files - if(!flipper_application_assets_process_files(storage, file, app_name, header.files_count)) { + if(header.files_count && !flipper_application_assets_process_files( + storage, file, app_name, header.files_count)) { break; } @@ -353,6 +357,7 @@ bool flipper_application_assets_load(File* file, const char* elf_path, size_t of } furi_record_close(RECORD_STORAGE); + furi_string_free(full_path); furi_string_free(app_name); FURI_LOG_D(TAG, "Assets loading %s", result ? "success" : "failed"); From a677b2bcc23a6f44f584b4bfdd4bbdfb8443b815 Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Wed, 2 Aug 2023 00:50:17 +0900 Subject: [PATCH 09/19] [FL-3469] Move U2F path to ext (#2935) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- applications/main/u2f/u2f_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/main/u2f/u2f_data.c b/applications/main/u2f/u2f_data.c index 66604d16..e5433544 100644 --- a/applications/main/u2f/u2f_data.c +++ b/applications/main/u2f/u2f_data.c @@ -7,7 +7,7 @@ #define TAG "U2F" -#define U2F_DATA_FOLDER ANY_PATH("u2f/") +#define U2F_DATA_FOLDER EXT_PATH("u2f/") #define U2F_CERT_FILE U2F_DATA_FOLDER "assets/cert.der" #define U2F_CERT_KEY_FILE U2F_DATA_FOLDER "assets/cert_key.u2f" #define U2F_KEY_FILE U2F_DATA_FOLDER "key.u2f" From be86b0f38ad7245749ac8bcafa12bf55f142f76b Mon Sep 17 00:00:00 2001 From: plgcoder <112718803+plgcoder@users.noreply.github.com> Date: Wed, 2 Aug 2023 05:43:36 +0200 Subject: [PATCH 10/19] Overly missed feature: Infrared: move button (change button order in a remote) (#2894) * Feature: Infrared: move button (change button order in a remote) * little fix in furi_assert (case Move button to the end) --- applications/main/infrared/infrared_i.h | 3 + applications/main/infrared/infrared_remote.c | 15 +++ applications/main/infrared/infrared_remote.h | 1 + .../infrared/scenes/infrared_scene_config.h | 2 + .../infrared/scenes/infrared_scene_edit.c | 12 ++ .../infrared_scene_edit_button_select.c | 35 +++++- .../scenes/infrared_scene_edit_move.c | 103 ++++++++++++++++++ .../scenes/infrared_scene_edit_move_done.c | 48 ++++++++ 8 files changed, 215 insertions(+), 4 deletions(-) create mode 100644 applications/main/infrared/scenes/infrared_scene_edit_move.c create mode 100644 applications/main/infrared/scenes/infrared_scene_edit_move_done.c diff --git a/applications/main/infrared/infrared_i.h b/applications/main/infrared/infrared_i.h index 9e65c2b1..96932d9b 100644 --- a/applications/main/infrared/infrared_i.h +++ b/applications/main/infrared/infrared_i.h @@ -60,6 +60,8 @@ typedef enum { InfraredEditModeNone, InfraredEditModeRename, InfraredEditModeDelete, + InfraredEditModeMove, + InfraredEditModeMoveSelectDest } InfraredEditMode; typedef struct { @@ -69,6 +71,7 @@ typedef struct { InfraredEditTarget edit_target : 8; InfraredEditMode edit_mode : 8; int32_t current_button_index; + int32_t current_button_index_move_orig; uint32_t last_transmit_time; } InfraredAppState; diff --git a/applications/main/infrared/infrared_remote.c b/applications/main/infrared/infrared_remote.c index d3dfc2cc..a04a338b 100644 --- a/applications/main/infrared/infrared_remote.c +++ b/applications/main/infrared/infrared_remote.c @@ -108,6 +108,21 @@ bool infrared_remote_delete_button(InfraredRemote* remote, size_t index) { return infrared_remote_store(remote); } +bool infrared_remote_move_button(InfraredRemote* remote, size_t index_orig, size_t index_dest) { + furi_assert(index_orig < InfraredButtonArray_size(remote->buttons)); + furi_assert(index_dest <= InfraredButtonArray_size(remote->buttons)); + if(index_orig == index_dest) { + return true; + } + InfraredRemoteButton* button; + InfraredButtonArray_pop_at(&button, remote->buttons, index_orig); + if(index_orig > index_dest) + InfraredButtonArray_push_at(remote->buttons, index_dest, button); + else + InfraredButtonArray_push_at(remote->buttons, index_dest - 1, button); + return infrared_remote_store(remote); +} + bool infrared_remote_store(InfraredRemote* remote) { Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* ff = flipper_format_file_alloc(storage); diff --git a/applications/main/infrared/infrared_remote.h b/applications/main/infrared/infrared_remote.h index 6eac193d..2640149a 100644 --- a/applications/main/infrared/infrared_remote.h +++ b/applications/main/infrared/infrared_remote.h @@ -23,6 +23,7 @@ bool infrared_remote_find_button_by_name(InfraredRemote* remote, const char* nam bool infrared_remote_add_button(InfraredRemote* remote, const char* name, InfraredSignal* signal); bool infrared_remote_rename_button(InfraredRemote* remote, const char* new_name, size_t index); bool infrared_remote_delete_button(InfraredRemote* remote, size_t index); +bool infrared_remote_move_button(InfraredRemote* remote, size_t index_orig, size_t index_dest); bool infrared_remote_store(InfraredRemote* remote); bool infrared_remote_load(InfraredRemote* remote, FuriString* path); diff --git a/applications/main/infrared/scenes/infrared_scene_config.h b/applications/main/infrared/scenes/infrared_scene_config.h index 27eabe22..36e6ae25 100644 --- a/applications/main/infrared/scenes/infrared_scene_config.h +++ b/applications/main/infrared/scenes/infrared_scene_config.h @@ -7,6 +7,8 @@ ADD_SCENE(infrared, edit_delete_done, EditDeleteDone) ADD_SCENE(infrared, edit_button_select, EditButtonSelect) ADD_SCENE(infrared, edit_rename, EditRename) ADD_SCENE(infrared, edit_rename_done, EditRenameDone) +ADD_SCENE(infrared, edit_move, EditMove) +ADD_SCENE(infrared, edit_move_done, EditMoveDone) ADD_SCENE(infrared, learn, Learn) ADD_SCENE(infrared, learn_done, LearnDone) ADD_SCENE(infrared, learn_enter_name, LearnEnterName) diff --git a/applications/main/infrared/scenes/infrared_scene_edit.c b/applications/main/infrared/scenes/infrared_scene_edit.c index 360ed49b..79de04bd 100644 --- a/applications/main/infrared/scenes/infrared_scene_edit.c +++ b/applications/main/infrared/scenes/infrared_scene_edit.c @@ -3,6 +3,7 @@ typedef enum { SubmenuIndexAddButton, SubmenuIndexRenameButton, + SubmenuIndexMoveButton, SubmenuIndexDeleteButton, SubmenuIndexRenameRemote, SubmenuIndexDeleteRemote, @@ -30,6 +31,12 @@ void infrared_scene_edit_on_enter(void* context) { SubmenuIndexRenameButton, infrared_scene_edit_submenu_callback, context); + submenu_add_item( + submenu, + "Move Button", + SubmenuIndexMoveButton, + infrared_scene_edit_submenu_callback, + context); submenu_add_item( submenu, "Delete Button", @@ -74,6 +81,11 @@ bool infrared_scene_edit_on_event(void* context, SceneManagerEvent event) { infrared->app_state.edit_mode = InfraredEditModeRename; scene_manager_next_scene(scene_manager, InfraredSceneEditButtonSelect); consumed = true; + } else if(submenu_index == SubmenuIndexMoveButton) { + infrared->app_state.edit_target = InfraredEditTargetButton; + infrared->app_state.edit_mode = InfraredEditModeMove; + scene_manager_next_scene(scene_manager, InfraredSceneEditButtonSelect); + consumed = true; } else if(submenu_index == SubmenuIndexDeleteButton) { infrared->app_state.edit_target = InfraredEditTargetButton; infrared->app_state.edit_mode = InfraredEditModeDelete; diff --git a/applications/main/infrared/scenes/infrared_scene_edit_button_select.c b/applications/main/infrared/scenes/infrared_scene_edit_button_select.c index a7f8a2bf..7056a205 100644 --- a/applications/main/infrared/scenes/infrared_scene_edit_button_select.c +++ b/applications/main/infrared/scenes/infrared_scene_edit_button_select.c @@ -11,9 +11,23 @@ void infrared_scene_edit_button_select_on_enter(void* context) { InfraredRemote* remote = infrared->remote; InfraredAppState* app_state = &infrared->app_state; - const char* header = infrared->app_state.edit_mode == InfraredEditModeRename ? - "Rename Button:" : - "Delete Button:"; + const char* header = NULL; + switch(infrared->app_state.edit_mode) { + case InfraredEditModeRename: + header = "Rename Button:"; + break; + case InfraredEditModeDelete: + header = "Delete Button:"; + break; + case InfraredEditModeMove: + header = "Select Button to Move:"; + break; + case InfraredEditModeMoveSelectDest: + case InfraredEditModeNone: + default: + header = "Move Button Before:"; + break; + } submenu_set_header(submenu, header); const size_t button_count = infrared_remote_get_button_count(remote); @@ -26,7 +40,14 @@ void infrared_scene_edit_button_select_on_enter(void* context) { infrared_scene_edit_button_select_submenu_callback, context); } - + if(infrared->app_state.edit_mode == InfraredEditModeMoveSelectDest) { + submenu_add_item( + submenu, + "-- Move to the end --", + button_count, + infrared_scene_edit_button_select_submenu_callback, + context); + } if(button_count && app_state->current_button_index != InfraredButtonIndexNone) { submenu_set_selected_item(submenu, app_state->current_button_index); app_state->current_button_index = InfraredButtonIndexNone; @@ -48,6 +69,12 @@ bool infrared_scene_edit_button_select_on_event(void* context, SceneManagerEvent scene_manager_next_scene(scene_manager, InfraredSceneEditRename); } else if(edit_mode == InfraredEditModeDelete) { scene_manager_next_scene(scene_manager, InfraredSceneEditDelete); + } else if(edit_mode == InfraredEditModeMove) { + app_state->current_button_index_move_orig = event.event; + app_state->edit_mode = InfraredEditModeMoveSelectDest; + scene_manager_next_scene(scene_manager, InfraredSceneEditButtonSelect); + } else if(edit_mode == InfraredEditModeMoveSelectDest) { + scene_manager_next_scene(scene_manager, InfraredSceneEditMove); } else { furi_assert(0); } diff --git a/applications/main/infrared/scenes/infrared_scene_edit_move.c b/applications/main/infrared/scenes/infrared_scene_edit_move.c new file mode 100644 index 00000000..69c7ec41 --- /dev/null +++ b/applications/main/infrared/scenes/infrared_scene_edit_move.c @@ -0,0 +1,103 @@ +#include "../infrared_i.h" + +static void infrared_scene_edit_move_dialog_result_callback(DialogExResult result, void* context) { + Infrared* infrared = context; + view_dispatcher_send_custom_event(infrared->view_dispatcher, result); +} + +void infrared_scene_edit_move_on_enter(void* context) { + Infrared* infrared = context; + DialogEx* dialog_ex = infrared->dialog_ex; + InfraredRemote* remote = infrared->remote; + + const InfraredEditTarget edit_target = infrared->app_state.edit_target; + if(edit_target == InfraredEditTargetButton) { + int32_t current_button_index = infrared->app_state.current_button_index_move_orig; + furi_assert(current_button_index != InfraredButtonIndexNone); + + dialog_ex_set_header(dialog_ex, "Move Button?", 64, 0, AlignCenter, AlignTop); + InfraredRemoteButton* current_button = + infrared_remote_get_button(remote, current_button_index); + InfraredSignal* signal = infrared_remote_button_get_signal(current_button); + + if(infrared_signal_is_raw(signal)) { + const InfraredRawSignal* raw = infrared_signal_get_raw_signal(signal); + infrared_text_store_set( + infrared, + 0, + "%s\nRAW\n%ld samples", + infrared_remote_button_get_name(current_button), + raw->timings_size); + + } else { + const InfraredMessage* message = infrared_signal_get_message(signal); + infrared_text_store_set( + infrared, + 0, + "%s\n%s\nA=0x%0*lX C=0x%0*lX", + infrared_remote_button_get_name(current_button), + infrared_get_protocol_name(message->protocol), + ROUND_UP_TO(infrared_get_protocol_address_length(message->protocol), 4), + message->address, + ROUND_UP_TO(infrared_get_protocol_command_length(message->protocol), 4), + message->command); + } + } else { + furi_assert(0); + } + + dialog_ex_set_text(dialog_ex, infrared->text_store[0], 64, 31, AlignCenter, AlignCenter); + dialog_ex_set_icon(dialog_ex, 0, 0, NULL); + dialog_ex_set_left_button_text(dialog_ex, "Cancel"); + dialog_ex_set_right_button_text(dialog_ex, "Move"); + dialog_ex_set_result_callback(dialog_ex, infrared_scene_edit_move_dialog_result_callback); + dialog_ex_set_context(dialog_ex, context); + + view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewDialogEx); +} + +bool infrared_scene_edit_move_on_event(void* context, SceneManagerEvent event) { + Infrared* infrared = context; + SceneManager* scene_manager = infrared->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == DialogExResultLeft) { + scene_manager_previous_scene(scene_manager); + consumed = true; + } else if(event.event == DialogExResultRight) { + bool success = false; + InfraredRemote* remote = infrared->remote; + InfraredAppState* app_state = &infrared->app_state; + const InfraredEditTarget edit_target = app_state->edit_target; + + if(edit_target == InfraredEditTargetButton) { + furi_assert(app_state->current_button_index != InfraredButtonIndexNone); + success = infrared_remote_move_button( + remote, + app_state->current_button_index_move_orig, + app_state->current_button_index); + app_state->current_button_index_move_orig = InfraredButtonIndexNone; + app_state->current_button_index = InfraredButtonIndexNone; + } else { + furi_assert(0); + } + + if(success) { + scene_manager_next_scene(scene_manager, InfraredSceneEditMoveDone); + } else { + const uint32_t possible_scenes[] = {InfraredSceneRemoteList, InfraredSceneStart}; + scene_manager_search_and_switch_to_previous_scene_one_of( + scene_manager, possible_scenes, COUNT_OF(possible_scenes)); + } + consumed = true; + } + } + + return consumed; +} + +void infrared_scene_edit_move_on_exit(void* context) { + Infrared* infrared = context; + UNUSED(infrared); +} diff --git a/applications/main/infrared/scenes/infrared_scene_edit_move_done.c b/applications/main/infrared/scenes/infrared_scene_edit_move_done.c new file mode 100644 index 00000000..9f9b4b80 --- /dev/null +++ b/applications/main/infrared/scenes/infrared_scene_edit_move_done.c @@ -0,0 +1,48 @@ +#include "../infrared_i.h" + +void infrared_scene_edit_move_done_on_enter(void* context) { + Infrared* infrared = context; + Popup* popup = infrared->popup; + + popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62); + popup_set_header(popup, "Moved", 83, 19, AlignLeft, AlignBottom); + + popup_set_callback(popup, infrared_popup_closed_callback); + popup_set_context(popup, context); + popup_set_timeout(popup, 1500); + popup_enable_timeout(popup); + + view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewPopup); +} + +bool infrared_scene_edit_move_done_on_event(void* context, SceneManagerEvent event) { + Infrared* infrared = context; + SceneManager* scene_manager = infrared->scene_manager; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == InfraredCustomEventTypePopupClosed) { + const InfraredEditTarget edit_target = infrared->app_state.edit_target; + if(edit_target == InfraredEditTargetButton) { + scene_manager_search_and_switch_to_previous_scene( + scene_manager, InfraredSceneRemote); + } else if(edit_target == InfraredEditTargetRemote) { + const uint32_t possible_scenes[] = {InfraredSceneStart, InfraredSceneRemoteList}; + if(!scene_manager_search_and_switch_to_previous_scene_one_of( + scene_manager, possible_scenes, COUNT_OF(possible_scenes))) { + view_dispatcher_stop(infrared->view_dispatcher); + } + } else { + furi_assert(0); + } + consumed = true; + } + } + + return consumed; +} + +void infrared_scene_edit_move_done_on_exit(void* context) { + Infrared* infrared = context; + UNUSED(infrared); +} From 035e447009b6e075ef2f94fd5e761ffb2ed87f99 Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Wed, 2 Aug 2023 12:58:39 +0900 Subject: [PATCH 11/19] [FL-3462] External apps icounter (#2928) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- applications/external/hid_app/hid.c | 5 ----- applications/services/dolphin/helpers/dolphin_deed.c | 2 +- applications/services/loader/loader_applications.c | 3 +++ 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/applications/external/hid_app/hid.c b/applications/external/hid_app/hid.c index a969a933..2be9afd9 100644 --- a/applications/external/hid_app/hid.c +++ b/applications/external/hid_app/hid.c @@ -1,7 +1,6 @@ #include "hid.h" #include "views.h" #include -#include #define TAG "HidApp" @@ -389,8 +388,6 @@ int32_t hid_usb_app(void* p) { bt_hid_connection_status_changed_callback(BtStatusConnected, app); - dolphin_deed(DolphinDeedPluginStart); - view_dispatcher_run(app->view_dispatcher); furi_hal_usb_set_config(usb_mode_prev, NULL); @@ -429,8 +426,6 @@ int32_t hid_ble_app(void* p) { furi_hal_bt_start_advertising(); bt_set_status_changed_callback(app->bt, bt_hid_connection_status_changed_callback, app); - dolphin_deed(DolphinDeedPluginStart); - view_dispatcher_run(app->view_dispatcher); bt_set_status_changed_callback(app->bt, NULL, NULL); diff --git a/applications/services/dolphin/helpers/dolphin_deed.c b/applications/services/dolphin/helpers/dolphin_deed.c index 51db56fd..f1f42b77 100644 --- a/applications/services/dolphin/helpers/dolphin_deed.c +++ b/applications/services/dolphin/helpers/dolphin_deed.c @@ -39,7 +39,7 @@ static const DolphinDeedWeight dolphin_deed_weights[] = { {1, DolphinAppPlugin}, // DolphinDeedGpioUartBridge - {1, DolphinAppPlugin}, // DolphinDeedPluginStart + {2, DolphinAppPlugin}, // DolphinDeedPluginStart {1, DolphinAppPlugin}, // DolphinDeedPluginGameStart {10, DolphinAppPlugin}, // DolphinDeedPluginGameWin }; diff --git a/applications/services/loader/loader_applications.c b/applications/services/loader/loader_applications.c index 8ae91d76..2e1de613 100644 --- a/applications/services/loader/loader_applications.c +++ b/applications/services/loader/loader_applications.c @@ -6,6 +6,7 @@ #include #include #include +#include #define TAG "LoaderApplications" @@ -119,6 +120,8 @@ static void loader_pubsub_callback(const void* message, void* context) { static void loader_applications_start_app(LoaderApplicationsApp* app) { const char* name = furi_string_get_cstr(app->fap_path); + dolphin_deed(DolphinDeedPluginStart); + // load app FuriThreadId thread_id = furi_thread_get_current_id(); FuriPubSubSubscription* subscription = From c72531edc636ddbacda75d86f9bb74e0f1bb92fb Mon Sep 17 00:00:00 2001 From: Leopold Date: Wed, 2 Aug 2023 12:23:04 +0800 Subject: [PATCH 12/19] change FuriThreadPriorityIsr to 31 (configMAX_PRIORITIES-1) (#2920) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * change FuriThreadPriorityIsr to 31 (configMAX_PRIORITIES-1) * Furi: less hardcoded max priority, fix spelling * Format sources Co-authored-by: hedger Co-authored-by: あく --- furi/core/thread.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/furi/core/thread.h b/furi/core/thread.h index 022894ee..692f2a10 100644 --- a/furi/core/thread.h +++ b/furi/core/thread.h @@ -28,7 +28,7 @@ typedef enum { FuriThreadPriorityNormal = 16, /**< Normal */ FuriThreadPriorityHigh = 17, /**< High */ FuriThreadPriorityHighest = 18, /**< Highest */ - FuriThreadPriorityIsr = 32, /**< Deffered Isr (highest possible) */ + FuriThreadPriorityIsr = (configMAX_PRIORITIES - 1), /**< Deferred ISR (highest possible) */ } FuriThreadPriority; /** FuriThread anonymous structure */ From 313e9c3d890f874ef62821b0108540071fe59e61 Mon Sep 17 00:00:00 2001 From: minchogaydarov <134236905+minchogaydarov@users.noreply.github.com> Date: Wed, 2 Aug 2023 07:32:12 +0300 Subject: [PATCH 13/19] Add Daikin FTXC35DV1B ac remote (#2913) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: hedger Co-authored-by: あく --- assets/resources/infrared/assets/ac.ir | 37 ++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/assets/resources/infrared/assets/ac.ir b/assets/resources/infrared/assets/ac.ir index 6ec6fc82..ac7628e1 100644 --- a/assets/resources/infrared/assets/ac.ir +++ b/assets/resources/infrared/assets/ac.ir @@ -581,3 +581,40 @@ type: raw frequency: 38000 duty_cycle: 0.330000 data: 3204 9889 537 1587 491 529 512 544 489 545 489 1573 510 530 511 543 491 552 490 538 511 543 491 543 491 532 509 543 491 1587 489 537 512 543 491 1577 490 543 491 543 491 544 489 543 491 1586 489 544 490 1587 489 539 510 543 491 543 491 1586 490 +# +# Model: Daikin FTXC35DV1B +name: Off +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 530 315 532 314 532 314 532 314 532 314 506 340 561 24780 3568 1647 507 1213 535 313 534 340 506 340 506 1212 507 339 507 339 506 339 506 339 506 1214 505 341 504 1215 505 1216 504 343 503 1217 503 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 1219 501 345 501 344 502 345 501 1219 501 1219 501 345 501 344 502 344 502 345 501 344 502 345 501 344 502 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 1219 501 1219 501 345 501 1219 501 345 501 1219 501 1219 501 34807 3563 1652 502 1218 502 344 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1219 501 344 502 1218 502 1219 501 344 502 1219 501 1218 502 1219 501 1219 501 1219 501 345 501 344 502 1219 501 345 501 344 502 345 501 344 502 344 502 345 501 345 501 345 501 344 502 345 501 345 501 1219 501 345 501 345 501 345 501 345 501 1219 501 345 501 345 501 1219 501 345 501 345 501 1219 501 1219 501 345 501 1219 501 1219 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 345 501 345 501 1220 500 346 500 345 501 346 500 346 500 34806 3564 1652 502 1218 502 344 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 1218 502 344 502 1218 502 1218 502 1218 502 1219 501 1218 502 344 502 345 501 1219 501 345 501 344 502 345 501 344 502 344 502 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 345 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 1219 501 345 501 345 501 345 501 346 500 345 501 345 501 345 501 345 501 346 500 346 500 346 500 346 500 346 500 1220 499 346 500 1220 499 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 347 499 346 500 1221 499 1221 499 1221 499 347 499 347 499 347 499 347 499 347 499 347 499 347 499 347 499 347 499 1245 475 1222 498 1245 475 371 475 348 498 348 498 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 372 474 372 474 372 474 371 475 371 475 1246 474 371 475 1246 474 372 474 372 474 372 474 1246 474 1246 474 372 474 371 475 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 1246 474 372 474 1246 474 1246 473 372 474 372 474 1246 474 372 474 +# +name: Dh +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 536 339 507 311 535 312 534 312 534 312 534 339 507 24807 3710 1507 594 1156 563 305 543 304 542 304 570 1126 592 304 515 304 542 304 542 304 542 1155 564 304 541 1158 505 1215 505 342 504 1217 503 1217 503 1218 502 1218 502 1218 502 344 502 343 503 1218 502 343 503 343 503 344 502 344 502 344 502 344 502 344 502 343 503 343 503 344 502 1218 502 344 502 1218 502 344 502 344 502 344 502 1218 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 1218 502 1218 501 344 502 1218 502 344 502 1218 502 1218 502 34800 3564 1651 503 1217 503 343 503 344 502 343 503 1217 503 343 503 343 503 344 502 344 502 1218 502 344 502 1217 503 1218 502 344 502 1218 502 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 1218 502 344 502 344 502 1218 502 1218 502 344 502 1218 502 1219 501 1219 501 345 501 344 502 344 502 344 502 344 502 345 501 345 501 1219 501 345 501 1219 501 345 501 345 501 345 501 345 501 34805 3565 1650 503 1216 503 343 503 343 503 344 502 1217 503 343 503 344 502 343 503 343 503 1217 503 344 502 1218 502 1218 502 344 502 1218 502 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 344 502 1218 502 344 502 1218 501 344 502 344 502 344 502 345 501 344 502 345 501 344 502 345 501 1219 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 345 501 1219 501 345 501 345 501 345 501 345 501 346 500 345 501 345 501 346 500 370 476 346 500 346 500 346 500 370 476 346 500 346 500 346 500 346 500 1221 499 1244 476 1244 476 370 476 346 500 370 476 370 476 370 476 370 476 370 476 370 476 370 476 1244 476 1244 476 1244 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 1244 476 370 476 1245 475 370 476 371 475 370 476 1245 475 1245 475 371 475 371 475 370 476 370 476 370 476 370 476 370 476 371 475 370 476 371 475 371 475 371 475 371 475 370 476 371 475 371 475 371 475 1245 475 1245 475 1245 475 371 475 371 475 1245 475 371 475 +# +name: Cool_hi +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 507 340 559 306 487 341 530 315 531 313 561 305 541 24776 3569 1646 508 1212 537 340 506 340 506 340 506 1213 507 339 507 339 506 339 506 340 505 1214 505 341 504 1215 504 1216 503 343 503 1217 502 1218 502 1218 502 1218 502 1218 501 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 344 502 344 502 344 502 1219 501 1218 502 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 1219 501 1219 501 345 501 1219 501 345 501 1219 501 1219 501 34800 3563 1652 502 1217 502 344 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 1218 501 344 502 1218 502 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 502 345 501 345 501 344 502 345 501 344 502 345 501 345 501 345 501 344 502 345 501 345 501 1219 501 345 501 345 501 345 501 345 501 1219 501 345 501 1219 501 1219 501 345 501 345 501 1219 501 1219 501 345 501 1219 500 1219 500 1219 500 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 345 501 1220 500 346 500 346 500 346 500 346 500 34808 3564 1652 503 1218 502 344 502 344 502 344 502 1218 502 344 502 344 502 345 501 344 502 1218 502 345 501 1218 502 1219 501 344 502 1219 501 1219 501 1219 501 1219 501 1219 501 345 501 345 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 500 345 501 345 501 1219 500 1219 501 1219 501 345 501 345 501 345 501 345 501 1219 501 345 501 345 501 1219 501 346 500 346 500 345 501 345 501 346 500 346 500 346 500 345 501 346 500 346 500 346 500 346 500 346 500 346 500 346 500 1220 500 346 500 1220 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 347 499 347 499 346 500 1221 499 1245 475 1221 499 347 499 347 499 347 499 348 498 347 499 348 498 348 498 371 475 348 498 1222 498 1245 475 1245 475 348 498 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 372 474 372 474 372 474 371 475 1245 474 372 474 1246 474 372 474 372 474 372 474 1246 474 1246 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 1246 474 372 474 372 474 372 474 372 474 1247 473 1247 473 +# +name: Cool_lo +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 533 311 535 312 534 312 534 313 533 310 536 312 534 24804 3705 1509 593 1129 590 305 542 305 542 305 569 1127 590 304 514 305 541 304 542 305 541 1155 564 305 540 1157 561 1159 504 341 504 1217 503 1217 503 1217 503 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 344 502 344 502 344 502 1218 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 345 501 1218 502 1218 502 1218 502 344 502 1219 501 345 501 1219 501 1219 501 34806 3565 1650 503 1217 502 343 503 343 503 343 503 1217 503 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 1218 502 344 502 1218 502 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1218 502 344 502 1219 501 344 502 1218 502 344 502 1219 501 1218 501 345 501 1218 501 1219 501 1218 502 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 1219 501 345 501 345 501 345 501 345 501 34805 3565 1651 503 1217 502 343 503 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 1218 502 344 502 1218 502 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 344 502 1218 502 1219 501 1218 502 345 501 344 502 345 501 1219 501 1219 501 1219 501 345 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 345 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 346 500 346 500 345 501 345 501 346 500 346 500 346 500 346 500 346 500 346 500 1220 500 1221 499 1221 498 346 500 346 500 370 476 346 500 347 499 347 499 370 476 370 476 370 476 1244 476 1244 476 1244 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 371 475 370 476 370 476 370 476 371 475 370 476 370 476 370 476 370 476 1244 476 371 475 1245 475 370 476 371 475 371 475 1245 475 1245 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 476 371 475 1245 475 1245 475 371 475 371 475 1246 474 1245 475 +# +name: Heat_lo +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 535 313 533 311 535 311 535 312 534 312 534 313 533 24805 3711 1506 592 1129 592 305 543 305 540 305 569 1126 592 304 514 304 542 304 541 304 485 1213 507 340 506 1214 506 1215 505 342 504 1217 503 1218 502 1218 502 1218 502 1218 502 344 502 344 502 1218 503 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 1218 502 344 502 344 502 344 502 1218 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 503 344 502 1219 501 1219 501 1219 501 345 501 1219 501 345 501 1219 502 1219 502 34818 3566 1651 503 1217 503 343 503 344 502 344 502 1218 502 344 502 344 502 344 502 344 503 1218 502 344 502 1218 503 1218 502 344 502 1218 502 1218 503 1218 503 1218 502 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 1218 502 344 502 345 501 344 502 344 502 1219 501 345 501 345 502 1219 501 345 501 1219 502 1219 502 1219 502 344 502 1219 501 1219 502 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 1219 501 345 501 345 501 345 501 1219 501 345 501 345 501 345 501 34812 3566 1651 503 1217 503 344 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 1218 503 344 502 1218 502 1218 502 344 502 1218 502 1218 502 1218 502 1219 501 1218 502 344 502 344 502 1218 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 344 502 345 501 344 502 345 501 345 501 1219 502 345 501 345 501 1219 502 345 501 345 501 1219 501 345 501 345 501 1219 501 1219 501 1219 501 345 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 502 345 501 345 501 345 501 346 500 345 501 345 501 345 501 345 501 345 501 1220 500 346 500 1220 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 347 499 346 500 347 499 347 499 370 476 1244 476 1221 499 1244 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 370 476 1245 475 1245 476 1245 475 371 475 370 476 370 476 371 475 371 475 370 476 370 476 371 475 371 476 370 476 370 476 371 475 371 475 371 475 371 475 371 475 1245 475 371 475 1245 475 371 475 371 475 371 475 1245 475 1245 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 476 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 371 475 1245 475 1245 475 1245 475 371 475 1245 475 1246 474 +# +name: Heat_hi +type: raw +frequency: 38000 +duty_cycle: 0.330000 +data: 535 314 532 314 533 313 533 312 534 313 533 312 508 24840 3569 1647 508 1213 536 342 505 342 504 341 505 1214 506 340 506 340 506 340 505 340 506 1214 506 341 504 1216 504 1217 503 343 503 1218 502 1219 501 1219 502 1219 502 1219 502 345 502 344 502 1219 502 345 501 345 502 345 502 345 501 345 501 345 501 345 501 345 501 345 502 345 501 1219 502 345 501 1219 501 345 502 345 501 345 501 1219 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1220 500 1219 501 1220 500 345 501 1220 500 345 501 1220 501 1220 500 34815 3564 1653 502 1218 502 344 502 345 501 344 502 1219 501 345 501 345 501 345 501 345 501 1219 502 345 501 1219 502 1220 501 345 502 1219 501 1219 502 1219 501 1219 502 1219 502 345 501 345 501 1220 501 345 502 345 501 345 501 345 501 345 501 345 501 345 502 345 501 345 502 345 501 345 501 1220 501 345 501 345 501 345 501 345 501 1220 500 345 501 346 501 1220 500 1220 501 345 501 345 501 346 500 1220 500 1220 500 1220 500 1220 500 346 500 346 500 346 500 345 501 346 500 345 501 1220 500 346 500 1220 500 1220 500 1220 500 346 500 346 500 346 500 34816 3565 1653 502 1219 501 344 502 345 501 345 501 1219 502 345 501 345 502 345 501 345 501 1219 501 345 501 1219 502 1219 501 345 501 1219 502 1219 501 1219 501 1219 501 1219 501 345 501 345 501 1219 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 345 501 1220 501 346 501 345 501 1220 501 346 500 346 500 1220 500 346 500 345 501 346 500 1220 500 1220 500 1220 501 1220 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 346 500 1220 500 346 500 1220 500 347 499 346 500 346 500 346 500 347 499 347 499 346 500 346 500 347 499 347 499 347 499 347 499 347 499 347 499 347 499 347 499 347 499 1222 498 1222 499 1222 498 347 499 348 498 348 498 347 499 371 475 348 498 348 498 348 498 371 475 1222 498 1246 474 1246 474 372 475 371 475 372 474 372 474 348 498 371 475 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 1246 474 372 474 1246 474 372 474 372 474 372 474 1246 474 1246 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 372 474 1246 474 372 474 1247 473 372 474 1246 474 1246 474 1246 474 From 9fd9dd85e3a157bed74f4ce4b6120433b2983be8 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Wed, 2 Aug 2023 08:45:39 +0400 Subject: [PATCH 14/19] =?UTF-8?q?SubGhz:=20change=20CC1101=5Fext=20TIM17?= =?UTF-8?q?=20resolution=20to=202=C2=B5s=20(#2909)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SubGhz: change the operation of the TIM17 timer in CC1101_ext to 2µs * SubGhz: remove special characters Co-authored-by: あく --- .../drivers/subghz/cc1101_ext/cc1101_ext.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/applications/drivers/subghz/cc1101_ext/cc1101_ext.c b/applications/drivers/subghz/cc1101_ext/cc1101_ext.c index 594a74a0..e9560ce5 100644 --- a/applications/drivers/subghz/cc1101_ext/cc1101_ext.c +++ b/applications/drivers/subghz/cc1101_ext/cc1101_ext.c @@ -37,7 +37,7 @@ #define SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_BUFFER_FULL (256) #define SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_BUFFER_HALF \ (SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_BUFFER_FULL / 2) -#define SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_GUARD_TIME 999 +#define SUBGHZ_DEVICE_CC1101_EXT_ASYNC_TX_GUARD_TIME 999 << 1 /** SubGhz state */ typedef enum { @@ -483,7 +483,7 @@ static void subghz_device_cc1101_ext_capture_ISR() { subghz_device_cc1101_ext->async_rx.capture_callback( true, - LL_TIM_GetCounter(TIM17), + LL_TIM_GetCounter(TIM17) << 1, (void*)subghz_device_cc1101_ext->async_rx.capture_callback_context); } } else { @@ -493,11 +493,11 @@ static void subghz_device_cc1101_ext_capture_ISR() { subghz_device_cc1101_ext->async_rx.capture_callback( false, - LL_TIM_GetCounter(TIM17), + LL_TIM_GetCounter(TIM17) << 1, (void*)subghz_device_cc1101_ext->async_rx.capture_callback_context); } } - LL_TIM_SetCounter(TIM17, 6); + LL_TIM_SetCounter(TIM17, 4); //8>>1 } void subghz_device_cc1101_ext_start_async_rx( @@ -512,7 +512,8 @@ void subghz_device_cc1101_ext_start_async_rx( furi_hal_bus_enable(FuriHalBusTIM17); // Configure TIM - LL_TIM_SetPrescaler(TIM17, 64 - 1); + //Set the timer resolution to 2 us + LL_TIM_SetPrescaler(TIM17, (64 << 1) - 1); LL_TIM_SetCounterMode(TIM17, LL_TIM_COUNTERMODE_UP); LL_TIM_SetAutoReload(TIM17, 0xFFFF); LL_TIM_SetClockDivision(TIM17, LL_TIM_CLOCKDIVISION_DIV1); @@ -606,7 +607,7 @@ static void subghz_device_cc1101_ext_async_tx_refill(uint32_t* buffer, size_t sa uint32_t duration = level_duration_get_duration(ld); furi_assert(duration > 0); - *buffer = duration - 1; + *buffer = duration >> 1; buffer++; samples--; } @@ -692,7 +693,8 @@ bool subghz_device_cc1101_ext_start_async_tx(SubGhzDeviceCC1101ExtCallback callb furi_hal_bus_enable(FuriHalBusTIM17); // Configure TIM - LL_TIM_SetPrescaler(TIM17, 64 - 1); + // Set the timer resolution to 2 us + LL_TIM_SetPrescaler(TIM17, (64 << 1) - 1); LL_TIM_SetCounterMode(TIM17, LL_TIM_COUNTERMODE_UP); LL_TIM_SetAutoReload(TIM17, 0xFFFF); LL_TIM_SetClockDivision(TIM17, LL_TIM_CLOCKDIVISION_DIV1); From 7a45db38812f50649f6501fa43acfc16d16dc2b5 Mon Sep 17 00:00:00 2001 From: Andrey Zakharov Date: Wed, 2 Aug 2023 08:19:00 +0300 Subject: [PATCH 15/19] Fix about screen (#2907) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix about screen * About: use COUNT_OF Co-authored-by: Andrey Zakharov Co-authored-by: あく --- applications/settings/about/about.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/applications/settings/about/about.c b/applications/settings/about/about.c index 55bd43e5..dcd7656f 100644 --- a/applications/settings/about/about.c +++ b/applications/settings/about/about.c @@ -87,6 +87,7 @@ static DialogMessageButton icon2_screen(DialogsApp* dialogs, DialogMessage* mess message, furi_hal_version_get_mic_id(), 63, 27, AlignLeft, AlignCenter); result = dialog_message_show(dialogs, message); dialog_message_set_icon(message, NULL, 0, 0); + dialog_message_set_text(message, NULL, 0, 0, AlignLeft, AlignTop); return result; } @@ -172,8 +173,6 @@ const AboutDialogScreen about_screens[] = { hw_version_screen, fw_version_screen}; -const size_t about_screens_count = sizeof(about_screens) / sizeof(AboutDialogScreen); - int32_t about_settings_app(void* p) { UNUSED(p); DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); @@ -194,7 +193,7 @@ int32_t about_settings_app(void* p) { view_dispatcher_switch_to_view(view_dispatcher, empty_screen_index); while(1) { - if(screen_index >= about_screens_count - 1) { + if(screen_index >= COUNT_OF(about_screens) - 1) { dialog_message_set_buttons(message, "Back", NULL, NULL); } else { dialog_message_set_buttons(message, "Back", NULL, "Next"); @@ -209,7 +208,7 @@ int32_t about_settings_app(void* p) { screen_index--; } } else if(screen_result == DialogMessageButtonRight) { - if(screen_index < about_screens_count) { + if(screen_index < COUNT_OF(about_screens) - 1) { screen_index++; } } else if(screen_result == DialogMessageButtonBack) { From 3e8e99990909c241e164f309a583d76ca3b7305e Mon Sep 17 00:00:00 2001 From: Astra <93453568+Astrrra@users.noreply.github.com> Date: Wed, 2 Aug 2023 23:58:59 +0900 Subject: [PATCH 16/19] [FL-3470] Rename Applications to Apps (#2939) * Applications are now apps * Desktop: Apps in settings Co-authored-by: Aleksandr Kutuzov --- applications/services/loader/loader.h | 2 +- applications/services/loader/loader_cli.c | 2 +- .../desktop_settings/scenes/desktop_settings_scene_favorite.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/applications/services/loader/loader.h b/applications/services/loader/loader.h index 9fc4059f..3da676e6 100644 --- a/applications/services/loader/loader.h +++ b/applications/services/loader/loader.h @@ -6,7 +6,7 @@ extern "C" { #endif #define RECORD_LOADER "loader" -#define LOADER_APPLICATIONS_NAME "Applications" +#define LOADER_APPLICATIONS_NAME "Apps" typedef struct Loader Loader; diff --git a/applications/services/loader/loader_cli.c b/applications/services/loader/loader_cli.c index af3ebf9e..cbec4adc 100644 --- a/applications/services/loader/loader_cli.c +++ b/applications/services/loader/loader_cli.c @@ -14,7 +14,7 @@ static void loader_cli_print_usage() { } static void loader_cli_list() { - printf("Applications:\r\n"); + printf("Apps:\r\n"); for(size_t i = 0; i < FLIPPER_APPS_COUNT; i++) { printf("\t%s\r\n", FLIPPER_APPS[i].name); } diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c index 26e7bc58..e0b4c118 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c @@ -7,10 +7,10 @@ #define APPS_COUNT (FLIPPER_APPS_COUNT + FLIPPER_EXTERNAL_APPS_COUNT) -#define EXTERNAL_BROWSER_NAME ("Applications") +#define EXTERNAL_BROWSER_NAME ("Apps") #define EXTERNAL_BROWSER_INDEX (APPS_COUNT + 1) -#define EXTERNAL_APPLICATION_NAME ("[External Application]") +#define EXTERNAL_APPLICATION_NAME ("[Select App]") #define EXTERNAL_APPLICATION_INDEX (APPS_COUNT + 2) #define PRESELECTED_SPECIAL 0xffffffff From a7aef0bfc27541639aa7be0cfc06a2db0ecc8c9a Mon Sep 17 00:00:00 2001 From: AloneLiberty <111039319+AloneLiberty@users.noreply.github.com> Date: Wed, 2 Aug 2023 15:06:38 +0000 Subject: [PATCH 17/19] NFC: Fix MFC key invalidation (#2912) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * NFC: Fix key invalidation (again~) * NFC: shouldn't be there This code get called each time we check for B key Co-authored-by: あく --- lib/nfc/nfc_worker.c | 69 +++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index 145007bd..b2c845f0 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -810,16 +810,10 @@ static void nfc_worker_mf_classic_key_attack( uint8_t block_num = mf_classic_get_sector_trailer_block_num_by_sector(i); if(mf_classic_is_sector_read(data, i)) continue; if(!mf_classic_is_key_found(data, i, MfClassicKeyA)) { - FURI_LOG_D( - TAG, - "Trying A key for sector %d, key: %04lx%08lx", - i, - (uint32_t)(key >> 32), - (uint32_t)key); + FURI_LOG_D(TAG, "Trying A key for sector %d, key: %012llX", i, key); if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyA)) { mf_classic_set_key_found(data, i, MfClassicKeyA, key); - FURI_LOG_D( - TAG, "Key A found: %04lx%08lx", (uint32_t)(key >> 32), (uint32_t)key); + FURI_LOG_D(TAG, "Key A found: %012llX", key); nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context); uint64_t found_key; @@ -832,18 +826,13 @@ static void nfc_worker_mf_classic_key_attack( } } } + furi_hal_nfc_sleep(); } if(!mf_classic_is_key_found(data, i, MfClassicKeyB)) { - FURI_LOG_D( - TAG, - "Trying B key for sector %d, key: %04lx%08lx", - i, - (uint32_t)(key >> 32), - (uint32_t)key); + FURI_LOG_D(TAG, "Trying B key for sector %d, key: %012llX", i, key); if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyB)) { mf_classic_set_key_found(data, i, MfClassicKeyB, key); - FURI_LOG_D( - TAG, "Key B found: %04lx%08lx", (uint32_t)(key >> 32), (uint32_t)key); + FURI_LOG_D(TAG, "Key B found: %012llX", key); nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context); } } @@ -891,8 +880,9 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { nfc_worker->callback(NfcWorkerEventNewSector, nfc_worker->context); uint8_t block_num = mf_classic_get_sector_trailer_block_num_by_sector(i); if(mf_classic_is_sector_read(data, i)) continue; - bool is_key_a_found = mf_classic_is_key_found(data, i, MfClassicKeyA); - bool is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB); + if(mf_classic_is_key_found(data, i, MfClassicKeyA) && + mf_classic_is_key_found(data, i, MfClassicKeyB)) + continue; uint16_t key_index = 0; while(mf_classic_dict_get_next_key(dict, &key)) { FURI_LOG_T(TAG, "Key %d", key_index); @@ -910,19 +900,12 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { nfc_worker_mf_classic_key_attack(nfc_worker, prev_key, &tx_rx, i); deactivated = true; } - FURI_LOG_D( - TAG, - "Try to auth to sector %d with key %04lx%08lx", - i, - (uint32_t)(key >> 32), - (uint32_t)key); - if(!is_key_a_found) { - is_key_a_found = mf_classic_is_key_found(data, i, MfClassicKeyA); + FURI_LOG_D(TAG, "Try to auth to sector %d with key %012llX", i, key); + if(!mf_classic_is_key_found(data, i, MfClassicKeyA)) { if(mf_classic_authenticate_skip_activate( &tx_rx, block_num, key, MfClassicKeyA, !deactivated, cuid)) { mf_classic_set_key_found(data, i, MfClassicKeyA, key); - FURI_LOG_D( - TAG, "Key A found: %04lx%08lx", (uint32_t)(key >> 32), (uint32_t)key); + FURI_LOG_D(TAG, "Key A found: %012llX", key); nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context); uint64_t found_key; @@ -952,17 +935,19 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { if(mf_classic_is_key_found(data, i, MfClassicKeyA) && memcmp(sec_trailer->key_a, current_key, 6) == 0) { - mf_classic_set_key_not_found(data, i, MfClassicKeyA); - is_key_a_found = false; - FURI_LOG_D(TAG, "Key %dA not found in attack", i); + if(!mf_classic_authenticate_skip_activate( + &tx_rx, block_num, key, MfClassicKeyA, !deactivated, cuid)) { + mf_classic_set_key_not_found(data, i, MfClassicKeyA); + FURI_LOG_D(TAG, "Key %dA not found in attack", i); + } } + furi_hal_nfc_sleep(); + deactivated = true; } - if(!is_key_b_found) { - is_key_b_found = mf_classic_is_key_found(data, i, MfClassicKeyB); + if(!mf_classic_is_key_found(data, i, MfClassicKeyB)) { if(mf_classic_authenticate_skip_activate( &tx_rx, block_num, key, MfClassicKeyB, !deactivated, cuid)) { - FURI_LOG_D( - TAG, "Key B found: %04lx%08lx", (uint32_t)(key >> 32), (uint32_t)key); + FURI_LOG_D(TAG, "Key B found: %012llX", key); mf_classic_set_key_found(data, i, MfClassicKeyB, key); nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context); nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1); @@ -978,12 +963,18 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { if(mf_classic_is_key_found(data, i, MfClassicKeyB) && memcmp(sec_trailer->key_b, current_key, 6) == 0) { - mf_classic_set_key_not_found(data, i, MfClassicKeyB); - is_key_b_found = false; - FURI_LOG_D(TAG, "Key %dB not found in attack", i); + if(!mf_classic_authenticate_skip_activate( + &tx_rx, block_num, key, MfClassicKeyB, !deactivated, cuid)) { + mf_classic_set_key_not_found(data, i, MfClassicKeyB); + FURI_LOG_D(TAG, "Key %dB not found in attack", i); + } + furi_hal_nfc_sleep(); + deactivated = true; } } - if(is_key_a_found && is_key_b_found) break; + if(mf_classic_is_key_found(data, i, MfClassicKeyA) && + mf_classic_is_key_found(data, i, MfClassicKeyB)) + break; if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break; } else { if(!card_removed_notified) { From cf6706c42eebff3631d702aa51119af6925a5b24 Mon Sep 17 00:00:00 2001 From: erikj95 Date: Wed, 2 Aug 2023 17:24:02 +0200 Subject: [PATCH 18/19] NFC CLI: Fix multiple apdu commands from not working when one of them gives an empty response (#2922) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * NFC CLI: Fix multiple apdu commands from not working when one of them gives an empty response * Make PVS happy Co-authored-by: hedger Co-authored-by: あく --- applications/main/nfc/nfc_cli.c | 2 +- lib/nfc/nfc_worker.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/applications/main/nfc/nfc_cli.c b/applications/main/nfc/nfc_cli.c index 0b7e7547..e9617438 100644 --- a/applications/main/nfc/nfc_cli.c +++ b/applications/main/nfc/nfc_cli.c @@ -146,7 +146,7 @@ static void nfc_cli_apdu(Cli* cli, FuriString* args) { resp_size = (tx_rx.rx_bits / 8) * 2; if(!resp_size) { printf("No response\r\n"); - break; + continue; } resp_buffer = malloc(resp_size); uint8_to_hex_chars(tx_rx.rx_data, resp_buffer, resp_size); diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index b2c845f0..36776d80 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -946,13 +946,13 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { } if(!mf_classic_is_key_found(data, i, MfClassicKeyB)) { if(mf_classic_authenticate_skip_activate( - &tx_rx, block_num, key, MfClassicKeyB, !deactivated, cuid)) { + &tx_rx, block_num, key, MfClassicKeyB, !deactivated, cuid)) { //-V547 FURI_LOG_D(TAG, "Key B found: %012llX", key); mf_classic_set_key_found(data, i, MfClassicKeyB, key); nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context); nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1); } - deactivated = true; + deactivated = true; //-V1048 } else { // If the key B is marked as found and matches the searching key, invalidate it MfClassicSectorTrailer* sec_trailer = @@ -964,12 +964,12 @@ void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) { if(mf_classic_is_key_found(data, i, MfClassicKeyB) && memcmp(sec_trailer->key_b, current_key, 6) == 0) { if(!mf_classic_authenticate_skip_activate( - &tx_rx, block_num, key, MfClassicKeyB, !deactivated, cuid)) { + &tx_rx, block_num, key, MfClassicKeyB, !deactivated, cuid)) { //-V547 mf_classic_set_key_not_found(data, i, MfClassicKeyB); FURI_LOG_D(TAG, "Key %dB not found in attack", i); } furi_hal_nfc_sleep(); - deactivated = true; + deactivated = true; //-V1048 } } if(mf_classic_is_key_found(data, i, MfClassicKeyA) && From c7648eb932bb8accedfc3a10ca54c953c7476996 Mon Sep 17 00:00:00 2001 From: Lesha Lomalkin Date: Wed, 2 Aug 2023 18:38:51 +0300 Subject: [PATCH 19/19] fbtenv: add additional environ variable to control execution flow (#2938) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fbtenv: add flags FBT_PRESERVE_TAR, FBT_SKIP_CHECK_SOURCED for usage with external tools * fbtenv: beautify, add info to fbtenv_print_config section if FBT_VERBOSE * fbtenv: fixes Co-authored-by: あく --- scripts/toolchain/fbtenv.sh | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/scripts/toolchain/fbtenv.sh b/scripts/toolchain/fbtenv.sh index a86b0ece..c5040ed8 100755 --- a/scripts/toolchain/fbtenv.sh +++ b/scripts/toolchain/fbtenv.sh @@ -82,6 +82,9 @@ fbtenv_restore_env() fbtenv_check_sourced() { + if [ -n "${FBT_SKIP_CHECK_SOURCED:-""}" ]; then + return 0; + fi case "${ZSH_EVAL_CONTEXT:-""}" in *:file:*) setopt +o nomatch; # disabling 'no match found' warning in zsh return 0;; @@ -200,7 +203,7 @@ fbtenv_download_toolchain_tar() return 0; } -fbtenv_remove_old_tooclhain() +fbtenv_remove_old_toolchain() { printf "Removing old toolchain.."; rm -rf "${TOOLCHAIN_ARCH_DIR:?}"; @@ -231,12 +234,14 @@ fbtenv_unpack_toolchain() fbtenv_cleanup() { - printf "Cleaning up.."; if [ -n "${FBT_TOOLCHAIN_PATH:-""}" ]; then - rm -rf "${FBT_TOOLCHAIN_PATH:?}/toolchain/"*.tar.gz; + printf "Cleaning up.."; rm -rf "${FBT_TOOLCHAIN_PATH:?}/toolchain/"*.part; + if [ -z "${FBT_PRESERVE_TAR:-""}" ]; then + rm -rf "${FBT_TOOLCHAIN_PATH:?}/toolchain/"*.tar.gz; + fi + echo "done"; fi - echo "done"; trap - 2; return 0; } @@ -289,16 +294,22 @@ fbtenv_download_toolchain() fbtenv_curl_wget_check || return 1; fbtenv_download_toolchain_tar || return 1; fi - fbtenv_remove_old_tooclhain; + fbtenv_remove_old_toolchain; fbtenv_unpack_toolchain || return 1; fbtenv_cleanup; return 0; } -fbtenv_print_version() +fbtenv_print_config() { - if [ -n "$FBT_VERBOSE" ]; then + if [ -n "${FBT_VERBOSE:-""}" ]; then echo "FBT: using toolchain version $(cat "$TOOLCHAIN_ARCH_DIR/VERSION")"; + if [ -n "${FBT_SKIP_CHECK_SOURCED:-""}" ]; then + echo "FBT: fbtenv will not check if it is sourced or not"; + fi + if [ -n "${FBT_PRESERVE_TAR:-""}" ]; then + echo "FBT: toolchain archives will be saved"; + fi fi } @@ -316,7 +327,7 @@ fbtenv_main() fbtenv_check_env_vars || return 1; fbtenv_check_download_toolchain || return 1; fbtenv_set_shell_prompt; - fbtenv_print_version; + fbtenv_print_config; PATH="$TOOLCHAIN_ARCH_DIR/python/bin:$PATH"; PATH="$TOOLCHAIN_ARCH_DIR/bin:$PATH"; PATH="$TOOLCHAIN_ARCH_DIR/protobuf/bin:$PATH";