diff --git a/applications/main/gpio/scenes/gpio_scene_usb_uart_config.c b/applications/main/gpio/scenes/gpio_scene_usb_uart_config.c index e2ab6626447..8fcacd40396 100644 --- a/applications/main/gpio/scenes/gpio_scene_usb_uart_config.c +++ b/applications/main/gpio/scenes/gpio_scene_usb_uart_config.c @@ -27,6 +27,7 @@ static const uint32_t baudrate_list[] = { 460800, 921600, }; +static const char* software_de_re[] = {"None", "4"}; bool gpio_scene_usb_uart_cfg_on_event(void* context, SceneManagerEvent event) { GpioApp* app = context; @@ -84,6 +85,17 @@ static void line_port_cb(VariableItem* item) { view_dispatcher_send_custom_event(app->view_dispatcher, GpioUsbUartEventConfigSet); } +static void line_software_de_re_cb(VariableItem* item) { + GpioApp* app = variable_item_get_context(item); + furi_assert(app); + uint8_t index = variable_item_get_current_value_index(item); + + variable_item_set_current_value_text(item, software_de_re[index]); + + app->usb_uart_cfg->software_de_re = index; + view_dispatcher_send_custom_event(app->view_dispatcher, GpioUsbUartEventConfigSet); +} + static void line_flow_cb(VariableItem* item) { GpioApp* app = variable_item_get_context(item); furi_assert(app); @@ -155,6 +167,11 @@ void gpio_scene_usb_uart_cfg_on_enter(void* context) { app->var_item_flow = item; line_ensure_flow_invariant(app); + item = variable_item_list_add( + var_item_list, "DE/RE Pin", COUNT_OF(software_de_re), line_software_de_re_cb, app); + variable_item_set_current_value_index(item, app->usb_uart_cfg->software_de_re); + variable_item_set_current_value_text(item, software_de_re[app->usb_uart_cfg->software_de_re]); + variable_item_list_set_selected_item( var_item_list, scene_manager_get_scene_state(app->scene_manager, GpioAppViewUsbUartCfg)); diff --git a/applications/main/gpio/usb_uart_bridge.c b/applications/main/gpio/usb_uart_bridge.c index 9bc759dc895..366c5cdc4ef 100644 --- a/applications/main/gpio/usb_uart_bridge.c +++ b/applications/main/gpio/usb_uart_bridge.c @@ -6,11 +6,16 @@ #include #include +//TODO: FL-3276 port to new USART API +#include +#include + #define USB_CDC_PKT_LEN CDC_DATA_SZ #define USB_UART_RX_BUF_SIZE (USB_CDC_PKT_LEN * 5) #define USB_CDC_BIT_DTR (1 << 0) #define USB_CDC_BIT_RTS (1 << 1) +#define USB_USART_DE_RE_PIN &gpio_ext_pa4 static const GpioPin* flow_pins[][2] = { {&gpio_ext_pa7, &gpio_ext_pa6}, // 2, 3 @@ -247,6 +252,17 @@ static int32_t usb_uart_worker(void* context) { usb_uart->cfg.flow_pins = usb_uart->cfg_new.flow_pins; events |= WorkerEvtCtrlLineSet; } + if(usb_uart->cfg.software_de_re != usb_uart->cfg_new.software_de_re) { + usb_uart->cfg.software_de_re = usb_uart->cfg_new.software_de_re; + if(usb_uart->cfg.software_de_re != 0) { + furi_hal_gpio_write(USB_USART_DE_RE_PIN, true); + furi_hal_gpio_init( + USB_USART_DE_RE_PIN, GpioModeOutputPushPull, GpioPullNo, GpioSpeedMedium); + } else { + furi_hal_gpio_init( + USB_USART_DE_RE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + } + } api_lock_unlock(usb_uart->cfg_lock); } if(events & WorkerEvtLineCfgSet) { @@ -260,6 +276,8 @@ static int32_t usb_uart_worker(void* context) { usb_uart_vcp_deinit(usb_uart, usb_uart->cfg.vcp_ch); usb_uart_serial_deinit(usb_uart, usb_uart->cfg.uart_ch); + furi_hal_gpio_init(USB_USART_DE_RE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + if(usb_uart->cfg.flow_pins != 0) { furi_hal_gpio_init_simple(flow_pins[usb_uart->cfg.flow_pins - 1][0], GpioModeAnalog); furi_hal_gpio_init_simple(flow_pins[usb_uart->cfg.flow_pins - 1][1], GpioModeAnalog); @@ -298,7 +316,24 @@ static int32_t usb_uart_tx_thread(void* context) { if(len > 0) { usb_uart->st.tx_cnt += len; + + if(usb_uart->cfg.software_de_re != 0) + furi_hal_gpio_write(USB_USART_DE_RE_PIN, false); + furi_hal_uart_tx(usb_uart->cfg.uart_ch, data, len); + + if(usb_uart->cfg.software_de_re != 0) { + //TODO: FL-3276 port to new USART API + if(usb_uart->cfg.uart_ch == FuriHalUartIdUSART1) { + while(!LL_USART_IsActiveFlag_TC(USART1)) + ; + } else if(usb_uart->cfg.uart_ch == FuriHalUartIdLPUART1) { + while(!LL_LPUART_IsActiveFlag_TC(LPUART1)) + ; + } + + furi_hal_gpio_write(USB_USART_DE_RE_PIN, true); + } } } } diff --git a/applications/main/gpio/usb_uart_bridge.h b/applications/main/gpio/usb_uart_bridge.h index b456c3cc4e5..ebb103f5487 100644 --- a/applications/main/gpio/usb_uart_bridge.h +++ b/applications/main/gpio/usb_uart_bridge.h @@ -11,6 +11,7 @@ typedef struct { uint8_t flow_pins; uint8_t baudrate_mode; uint32_t baudrate; + uint8_t software_de_re; } UsbUartConfig; typedef struct { diff --git a/applications/main/nfc/nfc_app.c b/applications/main/nfc/nfc_app.c index ec528ad9c46..bf15161aa08 100644 --- a/applications/main/nfc/nfc_app.c +++ b/applications/main/nfc/nfc_app.c @@ -343,7 +343,7 @@ bool nfc_load_file(NfcApp* instance, FuriString* path, bool show_dialog) { nfc_supported_cards_load_cache(instance->nfc_supported_cards); FuriString* load_path = furi_string_alloc(); - if(nfc_has_shadow_file_internal(instance, path)) { + if(nfc_has_shadow_file_internal(instance, path)) { //-V1051 nfc_set_shadow_file_path(path, load_path); } else if(furi_string_end_with(path, NFC_APP_SHADOW_EXTENSION)) { size_t path_len = furi_string_size(path); diff --git a/applications/services/rpc/rpc_gui.c b/applications/services/rpc/rpc_gui.c index ca8fc61a45f..dd219e2dc45 100644 --- a/applications/services/rpc/rpc_gui.c +++ b/applications/services/rpc/rpc_gui.c @@ -5,6 +5,41 @@ #include #include +// Contract assertion +_Static_assert(InputKeyMAX == 6, "InputKeyMAX"); +_Static_assert(InputTypeMAX == 5, "InputTypeMAX"); + +_Static_assert(InputKeyUp == (int32_t)PB_Gui_InputKey_UP, "InputKeyUp != PB_Gui_InputKey_UP"); +_Static_assert( + InputKeyDown == (int32_t)PB_Gui_InputKey_DOWN, + "InputKeyDown != PB_Gui_InputKey_DOWN"); +_Static_assert( + InputKeyRight == (int32_t)PB_Gui_InputKey_RIGHT, + "InputKeyRight != PB_Gui_InputKey_RIGHT"); +_Static_assert( + InputKeyLeft == (int32_t)PB_Gui_InputKey_LEFT, + "InputKeyLeft != PB_Gui_InputKey_LEFT"); +_Static_assert(InputKeyOk == (int32_t)PB_Gui_InputKey_OK, "InputKeyOk != PB_Gui_InputKey_OK"); +_Static_assert( + InputKeyBack == (int32_t)PB_Gui_InputKey_BACK, + "InputKeyBack != PB_Gui_InputKey_BACK"); + +_Static_assert( + InputTypePress == (int32_t)PB_Gui_InputType_PRESS, + "InputTypePress != PB_Gui_InputType_PRESS"); +_Static_assert( + InputTypeRelease == (int32_t)PB_Gui_InputType_RELEASE, + "InputTypeRelease != PB_Gui_InputType_RELEASE"); +_Static_assert( + InputTypeShort == (int32_t)PB_Gui_InputType_SHORT, + "InputTypeShort != PB_Gui_InputType_SHORT"); +_Static_assert( + InputTypeLong == (int32_t)PB_Gui_InputType_LONG, + "InputTypeLong != PB_Gui_InputType_LONG"); +_Static_assert( + InputTypeRepeat == (int32_t)PB_Gui_InputType_REPEAT, + "InputTypeRepeat != PB_Gui_InputType_REPEAT"); + #define TAG "RpcGui" typedef enum { @@ -168,63 +203,20 @@ static void RpcSession* session = rpc_gui->session; furi_assert(session); - InputEvent event; - - bool invalid = false; - - switch(request->content.gui_send_input_event_request.key) { - case PB_Gui_InputKey_UP: - event.key = InputKeyUp; - break; - case PB_Gui_InputKey_DOWN: - event.key = InputKeyDown; - break; - case PB_Gui_InputKey_RIGHT: - event.key = InputKeyRight; - break; - case PB_Gui_InputKey_LEFT: - event.key = InputKeyLeft; - break; - case PB_Gui_InputKey_OK: - event.key = InputKeyOk; - break; - case PB_Gui_InputKey_BACK: - event.key = InputKeyBack; - break; - default: - // Invalid key - invalid = true; - break; - } + bool is_valid = (request->content.gui_send_input_event_request.key < (int32_t)InputKeyMAX) && + (request->content.gui_send_input_event_request.type < (int32_t)InputTypeMAX); - switch(request->content.gui_send_input_event_request.type) { - case PB_Gui_InputType_PRESS: - event.type = InputTypePress; - break; - case PB_Gui_InputType_RELEASE: - event.type = InputTypeRelease; - break; - case PB_Gui_InputType_SHORT: - event.type = InputTypeShort; - break; - case PB_Gui_InputType_LONG: - event.type = InputTypeLong; - break; - case PB_Gui_InputType_REPEAT: - event.type = InputTypeRepeat; - break; - default: - // Invalid type - invalid = true; - break; - } - - if(invalid) { + if(!is_valid) { rpc_send_and_release_empty( session, request->command_id, PB_CommandStatus_ERROR_INVALID_PARAMETERS); return; } + InputEvent event = { + .key = (int32_t)request->content.gui_send_input_event_request.key, + .type = (int32_t)request->content.gui_send_input_event_request.type, + }; + // Event sequence shenanigans event.sequence_source = INPUT_SEQUENCE_SOURCE_SOFTWARE; if(event.type == InputTypePress) { @@ -264,6 +256,29 @@ static void rpc_system_gui_virtual_display_render_callback(Canvas* canvas, void* canvas_draw_xbm(canvas, 0, 0, canvas->width, canvas->height, rpc_gui->virtual_display_buffer); } +static void rpc_system_gui_virtual_display_input_callback(InputEvent* event, void* context) { + furi_assert(event); + furi_assert(event->key < InputKeyMAX); + furi_assert(event->type < InputTypeMAX); + furi_assert(context); + + RpcGuiSystem* rpc_gui = context; + RpcSession* session = rpc_gui->session; + + FURI_LOG_D(TAG, "VirtulDisplay: SendInputEvent"); + + PB_Main rpc_message = { + .command_id = 0, + .command_status = PB_CommandStatus_OK, + .has_next = false, + .which_content = PB_Main_gui_send_input_event_request_tag, + .content.gui_send_input_event_request.key = (int32_t)event->key, + .content.gui_send_input_event_request.type = (int32_t)event->type, + }; + + rpc_send_and_release(session, &rpc_message); +} + static void rpc_system_gui_start_virtual_display_process(const PB_Main* request, void* context) { furi_assert(request); furi_assert(context); @@ -300,6 +315,15 @@ static void rpc_system_gui_start_virtual_display_process(const PB_Main* request, rpc_gui->virtual_display_view_port, rpc_system_gui_virtual_display_render_callback, rpc_gui); + + if(request->content.gui_start_virtual_display_request.send_input) { + FURI_LOG_D(TAG, "VirtulDisplay: input forwarding requested"); + view_port_input_callback_set( + rpc_gui->virtual_display_view_port, + rpc_system_gui_virtual_display_input_callback, + rpc_gui); + } + gui_add_view_port(rpc_gui->gui, rpc_gui->virtual_display_view_port, GuiLayerFullscreen); rpc_send_and_release_empty(session, request->command_id, PB_CommandStatus_OK); diff --git a/applications/settings/about/about.c b/applications/settings/about/about.c index dcd7656fc47..8f0798d9cf6 100644 --- a/applications/settings/about/about.c +++ b/applications/settings/about/about.c @@ -11,7 +11,7 @@ typedef DialogMessageButton (*AboutDialogScreen)(DialogsApp* dialogs, DialogMessage* message); -static DialogMessageButton product_screen(DialogsApp* dialogs, DialogMessage* message) { +static DialogMessageButton about_screen_product(DialogsApp* dialogs, DialogMessage* message) { DialogMessageButton result; FuriString* screen_header = furi_string_alloc_printf( @@ -31,8 +31,6 @@ static DialogMessageButton product_screen(DialogsApp* dialogs, DialogMessage* me dialog_message_set_text( message, furi_string_get_cstr(screen_text), 0, 26, AlignLeft, AlignTop); result = dialog_message_show(dialogs, message); - dialog_message_set_header(message, NULL, 0, 0, AlignLeft, AlignTop); - dialog_message_set_text(message, NULL, 0, 0, AlignLeft, AlignTop); furi_string_free(screen_header); furi_string_free(screen_text); @@ -40,7 +38,7 @@ static DialogMessageButton product_screen(DialogsApp* dialogs, DialogMessage* me return result; } -static DialogMessageButton address_screen(DialogsApp* dialogs, DialogMessage* message) { +static DialogMessageButton about_screen_address(DialogsApp* dialogs, DialogMessage* message) { DialogMessageButton result; const char* screen_text = "Flipper Devices Inc\n" @@ -50,12 +48,11 @@ static DialogMessageButton address_screen(DialogsApp* dialogs, DialogMessage* me dialog_message_set_text(message, screen_text, 0, 0, AlignLeft, AlignTop); result = dialog_message_show(dialogs, message); - dialog_message_set_text(message, NULL, 0, 0, AlignLeft, AlignTop); return result; } -static DialogMessageButton compliance_screen(DialogsApp* dialogs, DialogMessage* message) { +static DialogMessageButton about_screen_compliance(DialogsApp* dialogs, DialogMessage* message) { DialogMessageButton result; const char* screen_text = "For all compliance\n" @@ -64,35 +61,71 @@ static DialogMessageButton compliance_screen(DialogsApp* dialogs, DialogMessage* dialog_message_set_text(message, screen_text, 0, 0, AlignLeft, AlignTop); result = dialog_message_show(dialogs, message); - dialog_message_set_text(message, NULL, 0, 0, AlignLeft, AlignTop); return result; } -static DialogMessageButton icon1_screen(DialogsApp* dialogs, DialogMessage* message) { +static DialogMessageButton about_screen_icon1(DialogsApp* dialogs, DialogMessage* message) { DialogMessageButton result; dialog_message_set_icon(message, &I_Certification1_103x56, 13, 0); result = dialog_message_show(dialogs, message); - dialog_message_set_icon(message, NULL, 0, 0); return result; } -static DialogMessageButton icon2_screen(DialogsApp* dialogs, DialogMessage* message) { +static DialogMessageButton about_screen_icon2(DialogsApp* dialogs, DialogMessage* message) { DialogMessageButton result; dialog_message_set_icon(message, &I_Certification2_46x33, 15, 10); dialog_message_set_text( 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; } -static DialogMessageButton hw_version_screen(DialogsApp* dialogs, DialogMessage* message) { +static DialogMessageButton about_screen_cert_china_0(DialogsApp* dialogs, DialogMessage* message) { + DialogMessageButton result; + + dialog_message_set_icon(message, &I_CertificationChina0_121x41, 3, 3); + result = dialog_message_show(dialogs, message); + + return result; +} + +static DialogMessageButton about_screen_cert_china_1(DialogsApp* dialogs, DialogMessage* message) { + DialogMessageButton result; + + dialog_message_set_icon(message, &I_CertificationChina1_122x47, 3, 3); + dialog_message_set_text( + message, furi_hal_version_get_srrc_id(), 55, 11, AlignLeft, AlignBottom); + result = dialog_message_show(dialogs, message); + + return result; +} + +static DialogMessageButton about_screen_cert_taiwan(DialogsApp* dialogs, DialogMessage* message) { + DialogMessageButton result; + + dialog_message_set_icon(message, &I_CertificationTaiwan_33x32, 3, 10); + dialog_message_set_text( + message, furi_hal_version_get_ncc_id(), 39, 30, AlignLeft, AlignBottom); + result = dialog_message_show(dialogs, message); + + return result; +} + +static DialogMessageButton about_screen_cert_mexico(DialogsApp* dialogs, DialogMessage* message) { + DialogMessageButton result; + + dialog_message_set_icon(message, &I_CertificationMexico_98x41, 17, 4); + result = dialog_message_show(dialogs, message); + + return result; +} + +static DialogMessageButton about_screen_hw_version(DialogsApp* dialogs, DialogMessage* message) { DialogMessageButton result; FuriString* buffer; buffer = furi_string_alloc(); @@ -118,14 +151,12 @@ static DialogMessageButton hw_version_screen(DialogsApp* dialogs, DialogMessage* dialog_message_set_header(message, "HW Version Info:", 0, 0, AlignLeft, AlignTop); dialog_message_set_text(message, furi_string_get_cstr(buffer), 0, 13, AlignLeft, AlignTop); result = dialog_message_show(dialogs, message); - dialog_message_set_text(message, NULL, 0, 0, AlignLeft, AlignTop); - dialog_message_set_header(message, NULL, 0, 0, AlignLeft, AlignTop); furi_string_free(buffer); return result; } -static DialogMessageButton fw_version_screen(DialogsApp* dialogs, DialogMessage* message) { +static DialogMessageButton about_screen_fw_version(DialogsApp* dialogs, DialogMessage* message) { DialogMessageButton result; FuriString* buffer; buffer = furi_string_alloc(); @@ -157,21 +188,23 @@ static DialogMessageButton fw_version_screen(DialogsApp* dialogs, DialogMessage* dialog_message_set_header(message, "FW Version Info:", 0, 0, AlignLeft, AlignTop); dialog_message_set_text(message, furi_string_get_cstr(buffer), 0, 13, AlignLeft, AlignTop); result = dialog_message_show(dialogs, message); - dialog_message_set_text(message, NULL, 0, 0, AlignLeft, AlignTop); - dialog_message_set_header(message, NULL, 0, 0, AlignLeft, AlignTop); furi_string_free(buffer); return result; } const AboutDialogScreen about_screens[] = { - product_screen, - compliance_screen, - address_screen, - icon1_screen, - icon2_screen, - hw_version_screen, - fw_version_screen}; + about_screen_product, + about_screen_compliance, + about_screen_address, + about_screen_icon1, + about_screen_icon2, + about_screen_cert_china_0, + about_screen_cert_china_1, + about_screen_cert_taiwan, + about_screen_cert_mexico, + about_screen_hw_version, + about_screen_fw_version}; int32_t about_settings_app(void* p) { UNUSED(p); @@ -201,6 +234,10 @@ int32_t about_settings_app(void* p) { screen_result = about_screens[screen_index](dialogs, message); + dialog_message_set_icon(message, NULL, 0, 0); + dialog_message_set_header(message, NULL, 0, 0, AlignLeft, AlignTop); + dialog_message_set_text(message, NULL, 0, 0, AlignLeft, AlignTop); + if(screen_result == DialogMessageButtonLeft) { if(screen_index <= 0) { break; diff --git a/assets/icons/About/CertificationChina0_121x41.png b/assets/icons/About/CertificationChina0_121x41.png new file mode 100644 index 00000000000..1d28577ab3e Binary files /dev/null and b/assets/icons/About/CertificationChina0_121x41.png differ diff --git a/assets/icons/About/CertificationChina1_122x47.png b/assets/icons/About/CertificationChina1_122x47.png new file mode 100644 index 00000000000..c5eebec6776 Binary files /dev/null and b/assets/icons/About/CertificationChina1_122x47.png differ diff --git a/assets/icons/About/CertificationMexico_98x41.png b/assets/icons/About/CertificationMexico_98x41.png new file mode 100644 index 00000000000..9b1e45e6f24 Binary files /dev/null and b/assets/icons/About/CertificationMexico_98x41.png differ diff --git a/assets/icons/About/CertificationTaiwan_33x32.png b/assets/icons/About/CertificationTaiwan_33x32.png new file mode 100644 index 00000000000..bf2bfa21a7b Binary files /dev/null and b/assets/icons/About/CertificationTaiwan_33x32.png differ diff --git a/assets/protobuf b/assets/protobuf index 23ad19a7566..1956b83bba9 160000 --- a/assets/protobuf +++ b/assets/protobuf @@ -1 +1 @@ -Subproject commit 23ad19a756649ed9f6677b598e5361c5cce6847b +Subproject commit 1956b83bba99313ee8d8386e5d35d0549341ca26 diff --git a/lib/toolbox/keys_dict.c b/lib/toolbox/keys_dict.c index 30580bf5e6d..8d6f8c84689 100644 --- a/lib/toolbox/keys_dict.c +++ b/lib/toolbox/keys_dict.c @@ -108,7 +108,7 @@ KeysDict* keys_dict_alloc(const char* path, KeysDictMode mode, size_t key_size) } } stream_rewind(instance->stream); - FURI_LOG_I(TAG, "Loaded dictionary with %u keys", instance->total_keys); + FURI_LOG_I(TAG, "Loaded dictionary with %zu keys", instance->total_keys); furi_string_free(line); @@ -299,13 +299,12 @@ bool keys_dict_delete_key(KeysDict* instance, const uint8_t* key, size_t key_siz furi_assert(key); bool key_removed = false; - bool is_endfile = false; uint8_t* temp_key = malloc(key_size); stream_rewind(instance->stream); - while(!key_removed && !is_endfile) { + while(!key_removed) { if(!keys_dict_get_next_key(instance, temp_key, key_size)) { break; } @@ -332,4 +331,4 @@ bool keys_dict_delete_key(KeysDict* instance, const uint8_t* key, size_t key_siz free(temp_key); return key_removed; -} \ No newline at end of file +} diff --git a/scripts/fbt/util.py b/scripts/fbt/util.py index fb36ef55ac3..62946756823 100644 --- a/scripts/fbt/util.py +++ b/scripts/fbt/util.py @@ -11,6 +11,27 @@ # Excludes all files ending with ~, usually created by editors as backup files GLOB_FILE_EXCLUSION = ["*~"] +# List of environment variables to proxy to child processes +FORWARDED_ENV_VARIABLES = [ + # CI/CD variables + "WORKFLOW_BRANCH_OR_TAG", + "DIST_SUFFIX", + # Python & other tools + "HOME", + "APPDATA", + "PYTHONHOME", + "PYTHONNOUSERSITE", + "TMP", + "TEMP", + # ccache + "CCACHE_DISABLE", + # Colors for tools + "TERM", + # Toolchain + "FBT_TOOLCHAIN_PATH", + "UFBT_HOME", +] + def tempfile_arg_esc_func(arg): arg = quote_spaces(arg) diff --git a/scripts/ufbt/SConstruct b/scripts/ufbt/SConstruct index 46d6635788e..2fc170ad950 100644 --- a/scripts/ufbt/SConstruct +++ b/scripts/ufbt/SConstruct @@ -25,33 +25,10 @@ forward_os_env = { "PATH": os.environ["PATH"], } -# Proxying environment to child processes & scripts -variables_to_forward = [ - # CI/CD variables - "WORKFLOW_BRANCH_OR_TAG", - "DIST_SUFFIX", - # Python & other tools - "HOME", - "APPDATA", - "PYTHONHOME", - "PYTHONNOUSERSITE", - "TMP", - "TEMP", - # Colors for tools - "TERM", -] - -if proxy_env := GetOption("proxy_env"): - variables_to_forward.extend(proxy_env.split(",")) - -for env_value_name in variables_to_forward: - if environ_value := os.environ.get(env_value_name, None): - forward_os_env[env_value_name] = environ_value # Core environment init - loads SDK state, sets up paths, etc. core_env = Environment( variables=ufbt_variables, - ENV=forward_os_env, UFBT_STATE_DIR=ufbt_state_dir, UFBT_CURRENT_SDK_DIR=ufbt_current_sdk_dir, UFBT_SCRIPT_DIR=ufbt_script_dir, @@ -69,6 +46,7 @@ core_env.Append(CPPDEFINES=GetOption("extra_defines")) from fbt.appmanifest import FlipperApplication, FlipperAppType from fbt.sdk.cache import SdkCache from fbt.util import ( + FORWARDED_ENV_VARIABLES, path_as_posix, resolve_real_dir_node, single_quote, @@ -76,8 +54,19 @@ from fbt.util import ( wrap_tempfile, ) +variables_to_forward = list(FORWARDED_ENV_VARIABLES) + +if proxy_env := GetOption("proxy_env"): + variables_to_forward.extend(proxy_env.split(",")) + +for env_value_name in variables_to_forward: + if environ_value := os.environ.get(env_value_name, None): + forward_os_env[env_value_name] = environ_value + + # Base environment with all tools loaded from SDK env = core_env.Clone( + ENV=forward_os_env, toolpath=[core_env["FBT_SCRIPT_DIR"].Dir("fbt_tools")], tools=[ "fbt_tweaks", @@ -477,9 +466,12 @@ else: dist_env.PhonyTarget("dolphin_ext", Action(missing_dolphin_folder, None)) +# print(env.Dump()) dist_env.PhonyTarget( "env", - "@echo $( ${FBT_SCRIPT_DIR.abspath}/toolchain/fbtenv.sh $)", + '@echo "FBT_TOOLCHAIN_PATH=' + + forward_os_env["FBT_TOOLCHAIN_PATH"] + + '" source $( "${FBT_SCRIPT_DIR.abspath}/toolchain/fbtenv.sh" $)', ) dist_env.PostConfigureUfbtEnvionment() diff --git a/scripts/ufbt/project_template/.gitignore b/scripts/ufbt/project_template/.gitignore index e2a15a10a84..81a8981f739 100644 --- a/scripts/ufbt/project_template/.gitignore +++ b/scripts/ufbt/project_template/.gitignore @@ -1,4 +1,6 @@ dist/* .vscode .clang-format -.editorconfig \ No newline at end of file +.editorconfig +.env +.ufbt diff --git a/scripts/ufbt/site_tools/ufbt_help.py b/scripts/ufbt/site_tools/ufbt_help.py index 1df6a0591ae..ab20e2f7de9 100644 --- a/scripts/ufbt/site_tools/ufbt_help.py +++ b/scripts/ufbt/site_tools/ufbt_help.py @@ -44,7 +44,11 @@ 4. Run `ufbt launch` to build and upload your application. How to open a shell with toolchain environment and other build tools: - In your shell, type "source `ufbt -s env`". You can also use "." instead of "source". + In your shell, type "eval `ufbt -s env`". + +How to update uFBT SDK: + Run "ufbt update" to fetch latest SDK. + You can also specify branch, target and/or channel options. See "ufbt update -h" for details. """ diff --git a/scripts/ufbt/site_tools/ufbt_state.py b/scripts/ufbt/site_tools/ufbt_state.py index 0038b66a31f..d9aa0fd6b31 100644 --- a/scripts/ufbt/site_tools/ufbt_state.py +++ b/scripts/ufbt/site_tools/ufbt_state.py @@ -1,6 +1,5 @@ import json import os -import pathlib import sys from functools import reduce diff --git a/site_scons/environ.scons b/site_scons/environ.scons index 74762cb15bb..ece8de2122b 100644 --- a/site_scons/environ.scons +++ b/site_scons/environ.scons @@ -1,13 +1,14 @@ -from SCons.Platform import TempFileMunge +import multiprocessing +import os + from fbt.util import ( - tempfile_arg_esc_func, + FORWARDED_ENV_VARIABLES, + resolve_real_dir_node, single_quote, + tempfile_arg_esc_func, wrap_tempfile, - resolve_real_dir_node, ) - -import os -import multiprocessing +from SCons.Platform import TempFileMunge Import("VAR_ENV") @@ -15,23 +16,9 @@ forward_os_env = { # Import PATH from OS env - scons doesn't do that by default "PATH": os.environ["PATH"], } -# Proxying CI environment to child processes & scripts -variables_to_forward = [ - # CI/CD variables - "WORKFLOW_BRANCH_OR_TAG", - "DIST_SUFFIX", - # Python & other tools - "HOME", - "APPDATA", - "PYTHONHOME", - "PYTHONNOUSERSITE", - "TMP", - "TEMP", - # ccache - "CCACHE_DISABLE", - # Colors for tools - "TERM", -] + +variables_to_forward = list(FORWARDED_ENV_VARIABLES) + if proxy_env := GetOption("proxy_env"): variables_to_forward.extend(proxy_env.split(",")) diff --git a/targets/f18/api_symbols.csv b/targets/f18/api_symbols.csv index 8a5e44c97ca..446f7317240 100644 --- a/targets/f18/api_symbols.csv +++ b/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,50.0,, +Version,+,50.1,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -1330,7 +1330,9 @@ Function,+,furi_hal_version_get_mic_id,const char*, Function,+,furi_hal_version_get_model_code,const char*, Function,+,furi_hal_version_get_model_name,const char*, Function,+,furi_hal_version_get_name_ptr,const char*, +Function,+,furi_hal_version_get_ncc_id,const char*, Function,+,furi_hal_version_get_otp_version,FuriHalVersionOtpVersion, +Function,+,furi_hal_version_get_srrc_id,const char*, Function,-,furi_hal_version_init,void, Function,+,furi_hal_version_uid,const uint8_t*, Function,+,furi_hal_version_uid_size,size_t, diff --git a/targets/f18/furi_hal/furi_hal_version_device.c b/targets/f18/furi_hal/furi_hal_version_device.c index e038b98d737..198ceb3f19f 100644 --- a/targets/f18/furi_hal/furi_hal_version_device.c +++ b/targets/f18/furi_hal/furi_hal_version_device.c @@ -23,3 +23,11 @@ const char* furi_hal_version_get_ic_id() { const char* furi_hal_version_get_mic_id() { return "Pending"; } + +const char* furi_hal_version_get_srrc_id() { + return "Pending"; +} + +const char* furi_hal_version_get_ncc_id() { + return "Pending"; +} \ No newline at end of file diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index 5b308cb3657..498a20d5548 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -1526,7 +1526,9 @@ Function,+,furi_hal_version_get_mic_id,const char*, Function,+,furi_hal_version_get_model_code,const char*, Function,+,furi_hal_version_get_model_name,const char*, Function,+,furi_hal_version_get_name_ptr,const char*, +Function,+,furi_hal_version_get_ncc_id,const char*, Function,+,furi_hal_version_get_otp_version,FuriHalVersionOtpVersion, +Function,+,furi_hal_version_get_srrc_id,const char*, Function,-,furi_hal_version_init,void, Function,+,furi_hal_version_uid,const uint8_t*, Function,+,furi_hal_version_uid_size,size_t, diff --git a/targets/f7/furi_hal/furi_hal_version_device.c b/targets/f7/furi_hal/furi_hal_version_device.c index be3f4bf3f3c..89728998402 100644 --- a/targets/f7/furi_hal/furi_hal_version_device.c +++ b/targets/f7/furi_hal/furi_hal_version_device.c @@ -23,3 +23,11 @@ const char* furi_hal_version_get_ic_id() { const char* furi_hal_version_get_mic_id() { return "210-175991"; } + +const char* furi_hal_version_get_srrc_id() { + return "2023DJ16420"; +} + +const char* furi_hal_version_get_ncc_id() { + return "CCAJ23LP34D0T3"; +} \ No newline at end of file diff --git a/targets/furi_hal_include/furi_hal_version.h b/targets/furi_hal_include/furi_hal_version.h index 98d011cb389..8e7059fbc47 100644 --- a/targets/furi_hal_include/furi_hal_version.h +++ b/targets/furi_hal_include/furi_hal_version.h @@ -92,6 +92,18 @@ const char* furi_hal_version_get_ic_id(); */ const char* furi_hal_version_get_mic_id(); +/** Get SRRC id + * + * @return SRRC id as C-string + */ +const char* furi_hal_version_get_srrc_id(); + +/** Get NCC id + * + * @return NCC id as C-string + */ +const char* furi_hal_version_get_ncc_id(); + /** Get OTP version * * @return OTP Version