From ecc53d94159b6c9e721f5bbb2b09a44d87d508c3 Mon Sep 17 00:00:00 2001 From: Hyiger <43388146+hyiger@users.noreply.github.com> Date: Thu, 14 May 2026 10:06:52 -0700 Subject: [PATCH] Fix LAN printing crashes and hangs on Bambu H2D (#13296) Two related fixes for LAN printing with newer Bambu networking plugins: 1. FileTransferUtils: guard against missing ft_tunnel_* symbols The eMMC tunnel constructor calls ft_tunnel_create / ft_tunnel_set_status_cb without checking if the plugin exported them. Older plugins (e.g. 01.10.01.01) don't have these symbols, so the calls dereference null and crash when sending a print. Now throw a clear exception so callers can fall back gracefully. 2. PrintJob: disable eMMC print path by default Plugin 02.03.00.62's eMMC tunnel code hangs indefinitely at the upload phase (30%) on Bambu H2D, blocked inside the plugin waiting on a future that never resolves. Cancel doesn't work because the plugin doesn't check cancel_fn during the wait. The plain FTP path works reliably. Default to try_emmc_print=false; opt-in via AppConfig setting "disable_emmc_print" = "0". Also wrap the eMMC tunnel creation in try/catch so a missing-plugin exception cleanly falls back to FTP instead of killing the worker thread. Co-authored-by: hyiger Co-authored-by: Claude Opus 4.6 (1M context) Co-authored-by: SoftFever --- src/slic3r/GUI/Jobs/PrintJob.cpp | 21 ++++++++++++++++++--- src/slic3r/Utils/FileTransferUtils.cpp | 10 +++++++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/Jobs/PrintJob.cpp b/src/slic3r/GUI/Jobs/PrintJob.cpp index 601248dd29..0b29d3a805 100644 --- a/src/slic3r/GUI/Jobs/PrintJob.cpp +++ b/src/slic3r/GUI/Jobs/PrintJob.cpp @@ -215,8 +215,13 @@ void PrintJob::process(Ctl &ctl) std::string devIP = m_dev_ip; std::string accessCode = m_access_code; std::string url = "bambu:///local/" + devIP + "?port=6000&user=" + "bblp" + "&passwd=" + accessCode; - std::unique_ptr tunnel = std::make_unique(module(), url); - emmc_ok = tunnel->sync_start_connect(); + try { + std::unique_ptr tunnel = std::make_unique(module(), url); + emmc_ok = tunnel->sync_start_connect(); + } catch (const std::exception &e) { + BOOST_LOG_TRIVIAL(warning) << "eMMC tunnel unavailable, falling back to FTP: " << e.what(); + emmc_ok = false; + } } { params.dev_id = m_dev_id; @@ -270,7 +275,17 @@ void PrintJob::process(Ctl &ctl) params.auto_flow_cali = this->auto_flow_cali; params.auto_offset_cali = this->auto_offset_cali; params.task_ext_change_assist = this->task_ext_change_assist; - params.try_emmc_print = this->could_emmc_print; + // Allow disabling the eMMC print path via AppConfig. Plugin 02.03.00.62's + // eMMC tunnel code hangs indefinitely at the upload phase with some + // printers (e.g., Bambu H2D), so we default to disabled. Users with + // working eMMC support can opt-in by setting disable_emmc_print = 0. + bool disable_emmc = true; + if (wxGetApp().app_config) { + auto v = wxGetApp().app_config->get("disable_emmc_print"); + if (v == "0" || v == "false") + disable_emmc = false; + } + params.try_emmc_print = this->could_emmc_print && !disable_emmc; if (m_print_type == "from_sdcard_view") { params.dst_file = m_dst_path; diff --git a/src/slic3r/Utils/FileTransferUtils.cpp b/src/slic3r/Utils/FileTransferUtils.cpp index 25fbd4f99a..ebca741af5 100644 --- a/src/slic3r/Utils/FileTransferUtils.cpp +++ b/src/slic3r/Utils/FileTransferUtils.cpp @@ -39,9 +39,17 @@ FileTransferModule::FileTransferModule(ModuleHandle networking_module, int requi FileTransferTunnel::FileTransferTunnel(FileTransferModule &m, const std::string &url) : m_(&m) { + // Guard against missing symbols in older Bambu networking plugins. + // These symbols were added in a newer plugin ABI; if the installed + // plugin predates them, ft_tunnel_create/ft_tunnel_set_status_cb + // will be null and calling them crashes. + if (!m_->ft_tunnel_create || !m_->ft_tunnel_set_status_cb) { + throw std::runtime_error("Bambu networking plugin is too old: missing ft_tunnel_* symbols. " + "Please update the networking plugin."); + } FT_TunnelHandle *h{}; if (m_->ft_tunnel_create(url.c_str(), &h) != 0 || !h) { - + throw std::runtime_error("ft_tunnel_create failed"); } h_ = h;