From cda25c3715e92205192771a2ba7a41e0e7d09fbc Mon Sep 17 00:00:00 2001 From: Ian Chua Date: Tue, 22 Sep 2026 21:54:10 +0800 Subject: [PATCH] refactor: connect_printer api and dialog --- src/slic3r/GUI/DeviceManager.cpp | 26 +++++++++- src/slic3r/GUI/ReleaseNote.cpp | 49 ++++++++++++++++++- src/slic3r/GUI/ReleaseNote.hpp | 4 ++ src/slic3r/GUI/WebRtcMediaController.hpp | 2 +- src/slic3r/Utils/BBLPrinterAgent.cpp | 4 +- src/slic3r/Utils/BBLPrinterAgent.hpp | 2 +- src/slic3r/Utils/IPrinterAgent.hpp | 14 ++++-- src/slic3r/Utils/MoonrakerPrinterAgent.cpp | 17 ++++--- src/slic3r/Utils/MoonrakerPrinterAgent.hpp | 4 +- src/slic3r/Utils/NetworkAgent.cpp | 11 ++--- src/slic3r/Utils/NetworkAgent.hpp | 2 +- src/slic3r/Utils/OrcaPrinterAgent.cpp | 3 +- src/slic3r/Utils/OrcaPrinterAgent.hpp | 2 +- .../PrinterAgentPluginCapability.cpp | 10 ++++ .../PrinterAgentPluginCapability.hpp | 3 +- ...PrinterAgentPluginCapabilityTrampoline.hpp | 4 +- 16 files changed, 125 insertions(+), 32 deletions(-) diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index b50cd36021..22b048d29c 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -4,6 +4,7 @@ #include "I18N.hpp" #include "libslic3r/Time.hpp" #include "libslic3r/Thread.hpp" +#include "slic3r/Utils/Http.hpp" #include "slic3r/Utils/NetworkAgent.hpp" #include "slic3r/Utils/NetworkAgentFactory.hpp" #include "GuiColor.hpp" @@ -2619,9 +2620,32 @@ int MachineObject::connect(bool use_openssl) std::string username = m_agent ? m_agent->default_lan_username() : std::string(); std::string password = get_access_code(); + std::string port; + std::string host = Http::get_host_from_url(get_dev_ip(), &port); + std::string ca_file; + + if (GUI::wxGetApp().preset_bundle) { + const auto& config = GUI::wxGetApp().preset_bundle->printers.get_edited_preset().config; + if (port.empty()) + port = config.opt_string("printhost_port"); + ca_file = config.opt_string("printhost_cafile"); + } + + if (host.empty()) + host = get_dev_ip(); + if (m_agent) { try { - return m_agent->connect_printer(get_dev_id(), get_dev_ip(), username, password, use_openssl); + PrinterConnectionParams params{ + get_dev_id(), + host, + port, + username, + password, + use_openssl, + ca_file + }; + return m_agent->connect_printer(params); } catch (...) { ; } diff --git a/src/slic3r/GUI/ReleaseNote.cpp b/src/slic3r/GUI/ReleaseNote.cpp index 0078656c6d..b691aabcb5 100644 --- a/src/slic3r/GUI/ReleaseNote.cpp +++ b/src/slic3r/GUI/ReleaseNote.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include "Plater.hpp" @@ -29,6 +30,7 @@ #include "DeviceCore/DevManager.h" #include "DeviceCore/DevStorage.h" #include "md4c/src/md4c-html.h" +#include "../Utils/Http.hpp" namespace Slic3r { namespace GUI { @@ -1461,6 +1463,45 @@ InputIpAddressDialog::InputIpAddressDialog(wxWindow *parent) m_input_top_sizer->Add(0, 0, 0, wxTOP, FromDIP(4)); m_input_top_sizer->Add(m_input_area, 0, wxRIGHT | wxEXPAND, FromDIP(18)); + m_tips_cafile = new Label(ip_input_top_panel, _L("HTTPS CA File")); + m_input_cafile = new wxTextCtrl(ip_input_top_panel, wxID_ANY); + m_input_cafile->SetMinSize(wxSize(FromDIP(260), FromDIP(28))); + m_input_cafile->SetMaxSize(wxSize(FromDIP(260), FromDIP(28))); + + m_button_cafile = new Button(ip_input_top_panel, _L("Browse") + " " + dots); + m_button_cafile->SetStyle(ButtonStyle::Regular, ButtonType::Parameter); + m_button_cafile->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { + static const auto filemasks = _L("Certificate files (*.crt, *.pem)|*.crt;*.pem|All files|*.*"); + wxFileDialog openFileDialog(this, _L("Open CA certificate file"), "", "", filemasks, + wxFD_OPEN | wxFD_FILE_MUST_EXIST); + if (openFileDialog.ShowModal() != wxID_CANCEL) + m_input_cafile->SetValue(openFileDialog.GetPath()); + }); + + auto cafile_input_sizer = new wxBoxSizer(wxHORIZONTAL); + cafile_input_sizer->Add(m_input_cafile, 1, wxALIGN_CENTER_VERTICAL); + cafile_input_sizer->Add(m_button_cafile, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(10)); + + m_cafile_hint = new Label(ip_input_top_panel, _L("HTTPS CA file is optional. It is only needed if you use HTTPS with a self-signed certificate.")); + m_cafile_hint->Wrap(FromDIP(352)); + + m_input_top_sizer->Add(m_tips_cafile, 0, wxTOP | wxEXPAND, FromDIP(10)); + m_input_top_sizer->Add(cafile_input_sizer, 0, wxTOP | wxEXPAND, FromDIP(4)); + m_input_top_sizer->Add(m_cafile_hint, 0, wxTOP | wxEXPAND, FromDIP(4)); + + if (!Http::ca_file_supported()) { + m_input_cafile->Disable(); + m_button_cafile->Disable(); + m_cafile_hint->SetLabel(_L("This system uses HTTPS certificates from the system Certificate Store or Keychain. To use a custom CA file, import it there.")); + m_cafile_hint->Wrap(FromDIP(352)); + } + + if (wxGetApp().preset_bundle) { + const auto& config = wxGetApp().preset_bundle->printers.get_edited_preset().config; + if (config.has("printhost_cafile")) + m_input_cafile->SetValue(from_u8(config.opt_string("printhost_cafile"))); + } + ip_input_top_panel->SetSizer(m_input_top_sizer); ip_input_top_panel->Layout(); ip_input_top_panel->Fit(); @@ -1823,6 +1864,12 @@ void InputIpAddressDialog::on_ok(wxMouseEvent& evt) Layout(); Fit(); + if (wxGetApp().preset_bundle) { + auto& config = wxGetApp().preset_bundle->printers.get_edited_preset().config; + if (Http::ca_file_supported()) + config.opt_string("printhost_cafile") = m_input_cafile->GetValue().ToStdString(); + } + token_.reset(this, nop_deleter); m_thread = new boost::thread(boost::bind(&InputIpAddressDialog::workerThreadFunc, this, str_ip, str_access_code, str_sn, str_model_id, str_name)); } @@ -2093,7 +2140,7 @@ InputIpAddressDialog::~InputIpAddressDialog() void InputIpAddressDialog::on_dpi_changed(const wxRect& suggested_rect) { - + m_button_cafile->Rescale(); } diff --git a/src/slic3r/GUI/ReleaseNote.hpp b/src/slic3r/GUI/ReleaseNote.hpp index cfd372bc97..5d7c0b25c4 100644 --- a/src/slic3r/GUI/ReleaseNote.hpp +++ b/src/slic3r/GUI/ReleaseNote.hpp @@ -315,12 +315,16 @@ public: Button* m_button_manual_setup{ nullptr }; Label* m_tips_ip{ nullptr }; Label* m_tips_access_code{ nullptr }; + Label* m_tips_cafile{ nullptr }; + Label* m_cafile_hint{ nullptr }; Label* m_tips_sn{nullptr}; Label* m_tips_modelID{nullptr}; Label* m_test_right_msg{ nullptr }; Label* m_test_wrong_msg{ nullptr }; TextInput* m_input_ip{ nullptr }; TextInput* m_input_access_code{ nullptr }; + wxTextCtrl* m_input_cafile{ nullptr }; + Button* m_button_cafile{ nullptr }; TextInput* m_input_printer_name{ nullptr }; TextInput* m_input_sn{ nullptr }; ComboBox* m_input_modelID{ nullptr }; diff --git a/src/slic3r/GUI/WebRtcMediaController.hpp b/src/slic3r/GUI/WebRtcMediaController.hpp index edeb03813a..7a2ab02abb 100644 --- a/src/slic3r/GUI/WebRtcMediaController.hpp +++ b/src/slic3r/GUI/WebRtcMediaController.hpp @@ -1,7 +1,7 @@ #pragma once #include "IMediaController.hpp" -#include +#include #include diff --git a/src/slic3r/Utils/BBLPrinterAgent.cpp b/src/slic3r/Utils/BBLPrinterAgent.cpp index 48bd70d4b4..f1a335b8c8 100644 --- a/src/slic3r/Utils/BBLPrinterAgent.cpp +++ b/src/slic3r/Utils/BBLPrinterAgent.cpp @@ -254,13 +254,13 @@ int BBLPrinterAgent::send_message(std::string dev_id, std::string json_str, int return -1; } -int BBLPrinterAgent::connect_printer(std::string dev_id, std::string dev_ip, std::string username, std::string password, bool use_ssl) +int BBLPrinterAgent::connect_printer(const PrinterConnectionParams& params) { auto& plugin = BBLNetworkPlugin::instance(); auto agent = plugin.get_agent(); auto func = plugin.get_connect_printer(); if (func && agent) { - return func(agent, dev_id, dev_ip, username, password, use_ssl); + return func(agent, params.dev_id, params.host, params.username, params.password, params.use_ssl); } return -1; } diff --git a/src/slic3r/Utils/BBLPrinterAgent.hpp b/src/slic3r/Utils/BBLPrinterAgent.hpp index aaec01006e..62f25f6927 100644 --- a/src/slic3r/Utils/BBLPrinterAgent.hpp +++ b/src/slic3r/Utils/BBLPrinterAgent.hpp @@ -35,7 +35,7 @@ public: int command_axis_control(std::string dev_id, std::string axis, double unit, double input_val, int speed, bool is_core_xy, bool supports_mqtt_axis_control, int sequence_id, bool lan_mode) override; std::string default_lan_username() const override { return "bblp"; } - int connect_printer(std::string dev_id, std::string dev_ip, std::string username, std::string password, bool use_ssl) override; + int connect_printer(const PrinterConnectionParams& params) override; int disconnect_printer() override; int send_message_to_printer(std::string dev_id, std::string json_str, int qos, int flag) override; diff --git a/src/slic3r/Utils/IPrinterAgent.hpp b/src/slic3r/Utils/IPrinterAgent.hpp index 67e36b38d9..5ce6daa123 100644 --- a/src/slic3r/Utils/IPrinterAgent.hpp +++ b/src/slic3r/Utils/IPrinterAgent.hpp @@ -13,11 +13,9 @@ #include #include #include -#include #include #include #include -#include "ICameraSignalingChannel.hpp" namespace Slic3r { @@ -36,6 +34,16 @@ struct AgentInfo { std::string description; ///< Brief description of the agent's capabilities, e.g. "Orca printer agent" }; +struct PrinterConnectionParams { + std::string dev_id; + std::string host; + std::string port; + std::string username; + std::string password; + bool use_ssl = false; + std::string ca_file; +}; + /** * FilamentSyncMode - Modes for filament data synchronization. * @@ -205,7 +213,7 @@ public: /** * Establish a direct LAN connection to a printer. */ - virtual int connect_printer(std::string dev_id, std::string dev_ip, std::string username, std::string password, bool use_ssl) = 0; + virtual int connect_printer(const PrinterConnectionParams& params) = 0; /** * Tear down the active LAN printer connection. diff --git a/src/slic3r/Utils/MoonrakerPrinterAgent.cpp b/src/slic3r/Utils/MoonrakerPrinterAgent.cpp index 22a7dd2f56..77f5955d5d 100644 --- a/src/slic3r/Utils/MoonrakerPrinterAgent.cpp +++ b/src/slic3r/Utils/MoonrakerPrinterAgent.cpp @@ -1,5 +1,6 @@ #include "MoonrakerPrinterAgent.hpp" #include "Http.hpp" +#include "IPrinterAgent.hpp" #include "libslic3r/Preset.hpp" #include "libslic3r/PresetBundle.hpp" #include "slic3r/GUI/GUI_App.hpp" @@ -136,9 +137,9 @@ int MoonrakerPrinterAgent::send_message_to_printer(std::string dev_id, std::stri return handle_request(dev_id, json_str); } -int MoonrakerPrinterAgent::connect_printer(std::string dev_id, std::string dev_ip, std::string username, std::string password, bool use_ssl) +int MoonrakerPrinterAgent::connect_printer(const PrinterConnectionParams& params) { - if (dev_id.empty() || dev_ip.empty()) { + if (params.dev_id.empty() || params.host.empty()) { BOOST_LOG_TRIVIAL(error) << "MoonrakerPrinterAgent: connect_printer missing dev_id or dev_ip"; return BAMBU_NETWORK_ERR_INVALID_HANDLE; } @@ -148,7 +149,7 @@ int MoonrakerPrinterAgent::connect_printer(std::string dev_id, std::string dev_i uint64_t gen; { std::lock_guard lock(connect_mutex); - init_device_info(dev_id, dev_ip, username, password, use_ssl); + init_device_info(params.dev_id, params.host, params.username, params.password, params.use_ssl, params.port); gen = ++connect_generation; base_url = device_info.base_url; api_key = device_info.api_key; @@ -170,7 +171,7 @@ int MoonrakerPrinterAgent::connect_printer(std::string dev_id, std::string dev_i // Launch connection in background thread (capture by value to avoid data races) { std::lock_guard lock(connect_mutex); - connect_thread = std::thread([this, dev_id, base_url, api_key, gen]() { perform_connection_async(dev_id, base_url, api_key, gen); }); + connect_thread = std::thread([this, params, base_url, api_key, gen]() { perform_connection_async(params.dev_id, base_url, api_key, gen); }); } return BAMBU_NETWORK_SUCCESS; @@ -1040,7 +1041,7 @@ int MoonrakerPrinterAgent::handle_request(const std::string& dev_id, const std:: return BAMBU_NETWORK_SUCCESS; } -bool MoonrakerPrinterAgent::init_device_info(std::string dev_id, std::string dev_ip, std::string username, std::string password, bool use_ssl) +bool MoonrakerPrinterAgent::init_device_info(const std::string& dev_id, const std::string& dev_ip, const std::string& username, const std::string& password, bool use_ssl, const std::string& port) { device_info = MoonrakerDeviceInfo{}; auto* preset_bundle = GUI::wxGetApp().preset_bundle; @@ -1050,12 +1051,14 @@ bool MoonrakerPrinterAgent::init_device_info(std::string dev_id, std::string dev auto& preset = preset_bundle->printers.get_edited_preset(); const auto& printer_cfg = preset.config; - device_info.dev_ip = dev_ip; + device_info.dev_ip = dev_ip; device_info.api_key = password; device_info.model_name = printer_cfg.opt_string("printer_model"); device_info.model_id = preset.get_printer_type(preset_bundle); - device_info.base_url = use_ssl ? "https://" + dev_ip : "http://" + dev_ip; + device_info.base_url = normalize_base_url(dev_ip, port); + if (use_ssl && boost::istarts_with(device_info.base_url, "http://")) + device_info.base_url.replace(0, 7, "https://"); device_info.dev_id = dev_id; device_info.version = ""; device_info.dev_name = device_info.dev_id; diff --git a/src/slic3r/Utils/MoonrakerPrinterAgent.hpp b/src/slic3r/Utils/MoonrakerPrinterAgent.hpp index d75930fad8..9af738e413 100644 --- a/src/slic3r/Utils/MoonrakerPrinterAgent.hpp +++ b/src/slic3r/Utils/MoonrakerPrinterAgent.hpp @@ -28,7 +28,7 @@ public: // Communication int send_message(std::string dev_id, std::string json_str, int qos, int flag) override; - int connect_printer(std::string dev_id, std::string dev_ip, std::string username, std::string password, bool use_ssl) override; + int connect_printer(const PrinterConnectionParams& params) override; int disconnect_printer() override; int send_message_to_printer(std::string dev_id, std::string json_str, int qos, int flag) override; @@ -94,7 +94,7 @@ protected: void build_ams_payload(int ams_count, int max_lane_index, const std::vector& trays); // Methods that derived classes may need to override or access - virtual bool init_device_info(std::string dev_id, std::string dev_ip, std::string username, std::string password, bool use_ssl); + virtual bool init_device_info(const std::string& dev_id, const std::string& dev_ip, const std::string& username, const std::string& password, bool use_ssl, const std::string& port); virtual bool fetch_device_info(const std::string& base_url, const std::string& api_key, MoonrakerDeviceInfo& info, std::string& error) const; // State access for derived classes diff --git a/src/slic3r/Utils/NetworkAgent.cpp b/src/slic3r/Utils/NetworkAgent.cpp index 0aef8afddd..d6ffafcdfe 100644 --- a/src/slic3r/Utils/NetworkAgent.cpp +++ b/src/slic3r/Utils/NetworkAgent.cpp @@ -1,13 +1,10 @@ -#include +#include "NetworkAgent.hpp" + #include -#include -#include #include #include #include "IPrinterAgent.hpp" -#include "libslic3r/Utils.hpp" -#include "NetworkAgent.hpp" #include "BBLNetworkPlugin.hpp" namespace Slic3r { @@ -867,10 +864,10 @@ int NetworkAgent::command_axis_control(std::string dev_id, std::string axis, dou return -1; } -int NetworkAgent::connect_printer(std::string dev_id, std::string dev_ip, std::string username, std::string password, bool use_ssl) +int NetworkAgent::connect_printer(const PrinterConnectionParams& params) { if (m_printer_agent) - return m_printer_agent->connect_printer(dev_id, dev_ip, username, password, use_ssl); + return m_printer_agent->connect_printer(params); return -1; } diff --git a/src/slic3r/Utils/NetworkAgent.hpp b/src/slic3r/Utils/NetworkAgent.hpp index 48029d666d..dcbdb1bea6 100644 --- a/src/slic3r/Utils/NetworkAgent.hpp +++ b/src/slic3r/Utils/NetworkAgent.hpp @@ -161,7 +161,7 @@ public: int command_set_nozzle(std::string dev_id, int temp, int sequence_id, bool lan_mode); int command_axis_control(std::string dev_id, std::string axis, double unit, double input_val, int speed, bool is_core_xy, bool supports_mqtt_axis_control, int sequence_id, bool lan_mode); - int connect_printer(std::string dev_id, std::string dev_ip, std::string username, std::string password, bool use_ssl); + int connect_printer(const PrinterConnectionParams& params); int disconnect_printer(); int send_message_to_printer(std::string dev_id, std::string json_str, int qos, int flag); std::string default_lan_username() const; diff --git a/src/slic3r/Utils/OrcaPrinterAgent.cpp b/src/slic3r/Utils/OrcaPrinterAgent.cpp index ef976cfab7..987cc0efdb 100644 --- a/src/slic3r/Utils/OrcaPrinterAgent.cpp +++ b/src/slic3r/Utils/OrcaPrinterAgent.cpp @@ -1,4 +1,5 @@ #include "OrcaPrinterAgent.hpp" +#include "IPrinterAgent.hpp" #include "NetworkAgentFactory.hpp" namespace Slic3r { @@ -26,7 +27,7 @@ int OrcaPrinterAgent::send_message(std::string dev_id, std::string json_str, int return BAMBU_NETWORK_SUCCESS; } -int OrcaPrinterAgent::connect_printer(std::string dev_id, std::string dev_ip, std::string username, std::string password, bool use_ssl) +int OrcaPrinterAgent::connect_printer(const PrinterConnectionParams& params) { return BAMBU_NETWORK_SUCCESS; } diff --git a/src/slic3r/Utils/OrcaPrinterAgent.hpp b/src/slic3r/Utils/OrcaPrinterAgent.hpp index 36457fdfb1..7d2a75fe0f 100644 --- a/src/slic3r/Utils/OrcaPrinterAgent.hpp +++ b/src/slic3r/Utils/OrcaPrinterAgent.hpp @@ -28,7 +28,7 @@ public: // Communication int send_message(std::string dev_id, std::string json_str, int qos, int flag) override; - int connect_printer(std::string dev_id, std::string dev_ip, std::string username, std::string password, bool use_ssl) override; + int connect_printer(const PrinterConnectionParams& params) override; int disconnect_printer() override; int send_message_to_printer(std::string dev_id, std::string json_str, int qos, int flag) override; diff --git a/src/slic3r/plugin/pluginTypes/printerAgent/PrinterAgentPluginCapability.cpp b/src/slic3r/plugin/pluginTypes/printerAgent/PrinterAgentPluginCapability.cpp index 79a443eebc..d0c88404fe 100644 --- a/src/slic3r/plugin/pluginTypes/printerAgent/PrinterAgentPluginCapability.cpp +++ b/src/slic3r/plugin/pluginTypes/printerAgent/PrinterAgentPluginCapability.cpp @@ -97,6 +97,16 @@ void PrinterAgentPluginCapability::RegisterBindings(pybind11::module_& module) .def_readwrite("task_ext_change_assist", &PrintParams::task_ext_change_assist) .def_readwrite("try_emmc_print", &PrintParams::try_emmc_print); + py::class_(printer_agent_module, "PrinterConnectionParams") + .def(py::init<>()) + .def_readwrite("dev_id", &PrinterConnectionParams::dev_id) + .def_readwrite("host", &PrinterConnectionParams::host) + .def_readwrite("port", &PrinterConnectionParams::port) + .def_readwrite("username", &PrinterConnectionParams::username) + .def_readwrite("password", &PrinterConnectionParams::password) + .def_readwrite("use_ssl", &PrinterConnectionParams::use_ssl) + .def_readwrite("ca_file", &PrinterConnectionParams::ca_file); + py::class_>( printer_agent_module, "PrinterAgentBase") .def(py::init<>()) diff --git a/src/slic3r/plugin/pluginTypes/printerAgent/PrinterAgentPluginCapability.hpp b/src/slic3r/plugin/pluginTypes/printerAgent/PrinterAgentPluginCapability.hpp index a4aaf48aa8..d33cee7afe 100644 --- a/src/slic3r/plugin/pluginTypes/printerAgent/PrinterAgentPluginCapability.hpp +++ b/src/slic3r/plugin/pluginTypes/printerAgent/PrinterAgentPluginCapability.hpp @@ -5,7 +5,6 @@ #include "IPrinterAgent.hpp" -#include #include #include @@ -30,7 +29,7 @@ public: AgentInfo get_agent_info() override = 0; - int connect_printer(std::string dev_id, std::string dev_ip, std::string username, std::string password, bool use_ssl) override = 0; + int connect_printer(const PrinterConnectionParams& params) override = 0; int send_message(std::string dev_id, std::string json_str, int qos, int flag) override = 0; int send_message_to_printer(std::string dev_id, std::string json_str, int qos, int flag) override = 0; bool start_discovery(bool start, bool sending) override = 0; diff --git a/src/slic3r/plugin/pluginTypes/printerAgent/PrinterAgentPluginCapabilityTrampoline.hpp b/src/slic3r/plugin/pluginTypes/printerAgent/PrinterAgentPluginCapabilityTrampoline.hpp index 74d5f82ab8..e73ddecb97 100644 --- a/src/slic3r/plugin/pluginTypes/printerAgent/PrinterAgentPluginCapabilityTrampoline.hpp +++ b/src/slic3r/plugin/pluginTypes/printerAgent/PrinterAgentPluginCapabilityTrampoline.hpp @@ -45,9 +45,9 @@ public: ORCA_PY_AGENT_OVERRIDE(AgentInfo, get_agent_info); } - int connect_printer(std::string dev_id, std::string dev_ip, std::string username, std::string password, bool use_ssl) override + int connect_printer(const PrinterConnectionParams& params) override { - ORCA_PY_AGENT_OVERRIDE(int, connect_printer, dev_id, dev_ip, username, password, use_ssl); + ORCA_PY_AGENT_OVERRIDE(int, connect_printer, params); } int disconnect_printer() override