Compare commits

...
Author SHA1 Message Date
Hanif Koh 138fa26847 Support the 02.08.04 Bambu Network Plug-in Series
The 02.08.02 series appended queue_plate_id to PrintParams and nothing
after it changed the ABI OrcaSlicer calls, so adding the field brings
the current layout up to 02.08.04. Make 02.08.04 the latest series and
drop 02.08.01 from the whitelist: its PrintParams no longer matches, and
its malformed bind table is refused by dyld on macOS 27, so it cannot
load there. A stored 02.08.01 falls back to the latest series through
the existing unsupported-version path.
2026-10-06 17:20:11 +08:00
3 changed files with 45 additions and 34 deletions
+2 -1
View File
@@ -596,7 +596,8 @@ PrintParams_Legacy BBLNetworkPlugin::as_legacy(PrintParams& param)
} }
// Every PrintParams field except the four the 02.08.01 series added // Every PrintParams field except the four the 02.08.01 series added
// (task_timelapse_use_internal, extruder_cali_manual_mode, svc_context, slicer_uid). // (task_timelapse_use_internal, extruder_cali_manual_mode, svc_context, slicer_uid) and the
// queue_plate_id 02.08.02 appended.
PrintParams_0203 BBLNetworkPlugin::as_0203(PrintParams& param) PrintParams_0203 BBLNetworkPlugin::as_0203(PrintParams& param)
{ {
PrintParams_0203 p; PrintParams_0203 p;
+7 -4
View File
@@ -336,6 +336,7 @@ struct PrintParams {
bool try_emmc_print; bool try_emmc_print;
std::string svc_context; std::string svc_context;
std::string slicer_uid; std::string slicer_uid;
std::string queue_plate_id;
}; };
struct TaskQueryParams struct TaskQueryParams
@@ -412,7 +413,7 @@ enum class NetworkAbi {
Unsupported, // no generation in this build can call it - never dispatch through it Unsupported, // no generation in this build can call it - never dispatch through it
Legacy, // 01.10.01: PrintParams_Legacy; send_message/send_message_to_printer take no flag Legacy, // 01.10.01: PrintParams_Legacy; send_message/send_message_to_printer take no flag
V0203, // 02.03.00: PrintParams_0203; bind takes no dev_model V0203, // 02.03.00: PrintParams_0203; bind takes no dev_model
Current, // 02.08.01: the layouts and signatures this build declares directly Current, // 02.08.04: the layouts and signatures this build declares directly
}; };
struct NetworkLibraryVersion { struct NetworkLibraryVersion {
@@ -425,10 +426,12 @@ struct NetworkLibraryVersion {
}; };
// Every row names the generation that can call it, so a series can never be offered without a // Every row names the generation that can call it, so a series can never be offered without a
// host-side ABI for it. Series with no generation - 02.01.01, 02.00.02 and older - must stay out; // host-side ABI for it. Series with no generation - 02.08.01 (whose PrintParams lacks the
// is_supported_network_version() is the gate that keeps them from loading. // queue_plate_id that 02.08.02 appended, and whose malformed bind table macOS 27 refuses to
// load), 02.01.01, 02.00.02 and older - must stay out; is_supported_network_version() is the
// gate that keeps them from loading.
static const NetworkLibraryVersion AVAILABLE_NETWORK_VERSIONS[] = { static const NetworkLibraryVersion AVAILABLE_NETWORK_VERSIONS[] = {
{"02.08.01", "02.08.01", nullptr, true, nullptr, NetworkAbi::Current}, {"02.08.04", "02.08.04", nullptr, true, nullptr, NetworkAbi::Current},
{"02.03.00", "02.03.00", nullptr, false, {"02.03.00", "02.03.00", nullptr, false,
"An older plug-in series. Features that need newer plug-in support, such as print-failure " "An older plug-in series. Features that need newer plug-in support, such as print-failure "
"snapshots in the device error dialog, are unavailable.", NetworkAbi::V0203}, "snapshots in the device error dialog, are unavailable.", NetworkAbi::V0203},
+36 -29
View File
@@ -78,31 +78,34 @@ TEST_CASE("Series and managed classification", "[NetworkVersions]")
TEST_CASE_METHOD(PluginFolderFixture, "Managed builds fold into the series; customs are surfaced", "[NetworkVersions]") TEST_CASE_METHOD(PluginFolderFixture, "Managed builds fold into the series; customs are surfaced", "[NetworkVersions]")
{ {
add_plugin("02.08.01.55"); // managed, same series -> folded into the 02.08.01 row add_plugin("02.08.04.60"); // managed, same series -> folded into the 02.08.04 row
add_plugin("02.09.00.10"); // managed, unknown series -> not listed add_plugin("02.09.00.10"); // managed, unknown series -> not listed
add_plugin("02.08.01.55"); // managed, series this build no longer has an ABI for -> not listed
add_plugin("02.03.00.62"); // managed, older whitelisted series -> folded into 02.03.00 add_plugin("02.03.00.62"); // managed, older whitelisted series -> folded into 02.03.00
add_plugin("02.01.01.52"); // managed, series with no ABI in this build -> not listed add_plugin("02.01.01.52"); // managed, series with no ABI in this build -> not listed
add_plugin("02.08.01_custom"); // custom, whitelisted series -> listed under it add_plugin("02.08.04_custom"); // custom, whitelisted series -> listed under it
add_plugin("02.08.01.52-dev"); // custom (dash-suffixed), whitelisted series -> listed add_plugin("02.08.04.52-dev"); // custom (dash-suffixed), whitelisted series -> listed
auto versions = get_all_available_versions(); auto versions = get_all_available_versions();
// The specific managed build never gets its own row - the series represents it. // The specific managed build never gets its own row - the series represents it.
REQUIRE(count_version(versions, "02.08.01.55") == 0); REQUIRE(count_version(versions, "02.08.04.60") == 0);
REQUIRE(count_version(versions, "02.08.01") == 1); REQUIRE(count_version(versions, "02.08.04") == 1);
REQUIRE(count_version(versions, "02.09.00.10") == 0); REQUIRE(count_version(versions, "02.09.00.10") == 0);
REQUIRE(count_version(versions, "02.08.01.55") == 0);
REQUIRE(count_version(versions, "02.08.01") == 0);
REQUIRE(count_version(versions, "02.03.00.62") == 0); REQUIRE(count_version(versions, "02.03.00.62") == 0);
REQUIRE(count_version(versions, "02.03.00") == 1); REQUIRE(count_version(versions, "02.03.00") == 1);
REQUIRE(count_version(versions, "02.01.01.52") == 0); REQUIRE(count_version(versions, "02.01.01.52") == 0);
// Custom-named builds are distinct files kept under their own name. // Custom-named builds are distinct files kept under their own name.
REQUIRE(count_version(versions, "02.08.01_custom") == 1); REQUIRE(count_version(versions, "02.08.04_custom") == 1);
REQUIRE(count_version(versions, "02.08.01.52-dev") == 1); REQUIRE(count_version(versions, "02.08.04.52-dev") == 1);
// Newest series first, its customs nested under it (suffix sort: "" < ".52-dev" < "_custom"), // Newest series first, its customs nested under it (suffix sort: "" < ".52-dev" < "_custom"),
// then older series, legacy last. // then older series, legacy last.
REQUIRE(versions[0].version == "02.08.01"); REQUIRE(versions[0].version == "02.08.04");
REQUIRE(versions[1].version == "02.08.01.52-dev"); REQUIRE(versions[1].version == "02.08.04.52-dev");
REQUIRE(versions[2].version == "02.08.01_custom"); REQUIRE(versions[2].version == "02.08.04_custom");
REQUIRE(versions[3].version == "02.03.00"); REQUIRE(versions[3].version == "02.03.00");
REQUIRE(versions.back().version == BAMBU_NETWORK_AGENT_VERSION_LEGACY); REQUIRE(versions.back().version == BAMBU_NETWORK_AGENT_VERSION_LEGACY);
@@ -111,9 +114,9 @@ TEST_CASE_METHOD(PluginFolderFixture, "Managed builds fold into the series; cust
REQUIRE_FALSE(versions[3].is_latest); REQUIRE_FALSE(versions[3].is_latest);
// Customs sort/render nested under their series (non-empty suffix, base = the series). // Customs sort/render nested under their series (non-empty suffix, base = the series).
REQUIRE(versions[1].base_version == "02.08.01"); REQUIRE(versions[1].base_version == "02.08.04");
REQUIRE_FALSE(versions[1].suffix.empty()); REQUIRE_FALSE(versions[1].suffix.empty());
REQUIRE(versions[2].base_version == "02.08.01"); REQUIRE(versions[2].base_version == "02.08.04");
REQUIRE_FALSE(versions[2].suffix.empty()); REQUIRE_FALSE(versions[2].suffix.empty());
// "(Latest)" is the series row, never a nested custom build. // "(Latest)" is the series row, never a nested custom build.
@@ -123,20 +126,20 @@ TEST_CASE_METHOD(PluginFolderFixture, "Managed builds fold into the series; cust
REQUIRE_FALSE(versions[2].is_latest); REQUIRE_FALSE(versions[2].is_latest);
// The stored default that drives download and update-check decisions is now the series. // The stored default that drives download and update-check decisions is now the series.
REQUIRE(std::string(get_latest_network_version()) == "02.08.01"); REQUIRE(std::string(get_latest_network_version()) == "02.08.04");
} }
TEST_CASE_METHOD(PluginFolderFixture, "Only the loaded series is marked installed", "[NetworkVersions]") TEST_CASE_METHOD(PluginFolderFixture, "Only the loaded series is marked installed", "[NetworkVersions]")
{ {
add_plugin("02.08.01.55"); add_plugin("02.08.04.60");
add_plugin("02.08.01_custom"); add_plugin("02.08.04_custom");
// The loaded plug-in reports its full build (02.08.01.55); the series row is what gets marked. // The loaded plug-in reports its full build (02.08.04.60); the series row is what gets marked.
{ {
auto versions = get_all_available_versions("02.08.01.55"); auto versions = get_all_available_versions("02.08.04.60");
int marked = 0; int marked = 0;
for (const auto& info : versions) for (const auto& info : versions)
if (info.is_loaded) { ++marked; REQUIRE(info.version == "02.08.01"); } if (info.is_loaded) { ++marked; REQUIRE(info.version == "02.08.04"); }
REQUIRE(marked == 1); REQUIRE(marked == 1);
} }
@@ -152,10 +155,10 @@ TEST_CASE_METHOD(PluginFolderFixture, "Only the loaded series is marked installe
// A loaded custom build matches its own row, never the bare series. // A loaded custom build matches its own row, never the bare series.
{ {
auto versions = get_all_available_versions("02.08.01_custom"); auto versions = get_all_available_versions("02.08.04_custom");
int marked = 0; int marked = 0;
for (const auto& info : versions) for (const auto& info : versions)
if (info.is_loaded) { ++marked; REQUIRE(info.version == "02.08.01_custom"); } if (info.is_loaded) { ++marked; REQUIRE(info.version == "02.08.04_custom"); }
REQUIRE(marked == 1); REQUIRE(marked == 1);
} }
@@ -167,11 +170,11 @@ TEST_CASE_METHOD(PluginFolderFixture, "Only the loaded series is marked installe
TEST_CASE("Only whitelisted series pass the load gate", "[NetworkVersions]") TEST_CASE("Only whitelisted series pass the load gate", "[NetworkVersions]")
{ {
// Each whitelisted series, its builds, and custom-named builds of that series. // Each whitelisted series, its builds, and custom-named builds of that series.
REQUIRE(is_supported_network_version("02.08.01")); REQUIRE(is_supported_network_version("02.08.04"));
REQUIRE(is_supported_network_version("02.08.01.52")); REQUIRE(is_supported_network_version("02.08.04.52"));
REQUIRE(is_supported_network_version("02.08.01.55")); REQUIRE(is_supported_network_version("02.08.04.60"));
REQUIRE(is_supported_network_version("02.08.01_custom")); REQUIRE(is_supported_network_version("02.08.04_custom"));
REQUIRE(is_supported_network_version("02.08.01.52-dev")); REQUIRE(is_supported_network_version("02.08.04.52-dev"));
REQUIRE(is_supported_network_version("02.03.00")); REQUIRE(is_supported_network_version("02.03.00"));
REQUIRE(is_supported_network_version("02.03.00.62")); REQUIRE(is_supported_network_version("02.03.00.62"));
REQUIRE(is_supported_network_version("02.03.00.70")); REQUIRE(is_supported_network_version("02.03.00.70"));
@@ -179,6 +182,9 @@ TEST_CASE("Only whitelisted series pass the load gate", "[NetworkVersions]")
REQUIRE(is_supported_network_version(BAMBU_NETWORK_AGENT_VERSION_LEGACY)); REQUIRE(is_supported_network_version(BAMBU_NETWORK_AGENT_VERSION_LEGACY));
// Series whitelisted by previous Orca releases that no generation here can call. // Series whitelisted by previous Orca releases that no generation here can call.
REQUIRE_FALSE(is_supported_network_version("02.08.01"));
REQUIRE_FALSE(is_supported_network_version("02.08.01.55"));
REQUIRE_FALSE(is_supported_network_version("02.08.01_custom"));
REQUIRE_FALSE(is_supported_network_version("02.01.01.52")); REQUIRE_FALSE(is_supported_network_version("02.01.01.52"));
REQUIRE_FALSE(is_supported_network_version("02.00.02.50")); REQUIRE_FALSE(is_supported_network_version("02.00.02.50"));
@@ -198,9 +204,9 @@ TEST_CASE("Each version resolves to the ABI generation that can call it", "[Netw
{ {
// The generation is keyed on the series, so every build of a series - including the // The generation is keyed on the series, so every build of a series - including the
// custom-named ones - resolves to the same one. // custom-named ones - resolves to the same one.
CHECK(network_plugin_abi("02.08.01") == NetworkAbi::Current); CHECK(network_plugin_abi("02.08.04") == NetworkAbi::Current);
CHECK(network_plugin_abi("02.08.01.55") == NetworkAbi::Current); CHECK(network_plugin_abi("02.08.04.60") == NetworkAbi::Current);
CHECK(network_plugin_abi("02.08.01.52-dev") == NetworkAbi::Current); CHECK(network_plugin_abi("02.08.04.52-dev") == NetworkAbi::Current);
CHECK(network_plugin_abi("02.03.00") == NetworkAbi::V0203); CHECK(network_plugin_abi("02.03.00") == NetworkAbi::V0203);
CHECK(network_plugin_abi("02.03.00.62") == NetworkAbi::V0203); CHECK(network_plugin_abi("02.03.00.62") == NetworkAbi::V0203);
CHECK(network_plugin_abi("02.03.00_custom") == NetworkAbi::V0203); CHECK(network_plugin_abi("02.03.00_custom") == NetworkAbi::V0203);
@@ -208,6 +214,7 @@ TEST_CASE("Each version resolves to the ABI generation that can call it", "[Netw
// Anything the load gate rejects must dispatch through nothing at all, rather than // Anything the load gate rejects must dispatch through nothing at all, rather than
// defaulting to a layout it does not share. // defaulting to a layout it does not share.
CHECK(network_plugin_abi("02.08.01.55") == NetworkAbi::Unsupported);
CHECK(network_plugin_abi("02.01.01.52") == NetworkAbi::Unsupported); CHECK(network_plugin_abi("02.01.01.52") == NetworkAbi::Unsupported);
CHECK(network_plugin_abi("02.00.02.50") == NetworkAbi::Unsupported); CHECK(network_plugin_abi("02.00.02.50") == NetworkAbi::Unsupported);
CHECK(network_plugin_abi("02.09.00.10") == NetworkAbi::Unsupported); CHECK(network_plugin_abi("02.09.00.10") == NetworkAbi::Unsupported);
@@ -234,7 +241,7 @@ TEST_CASE_METHOD(PluginFolderFixture, "Legacy series never adopts discovered bui
// With nothing else on disk, the series holds "(Latest)" even though its library is // With nothing else on disk, the series holds "(Latest)" even though its library is
// not installed. // not installed.
for (const auto& info : versions) { for (const auto& info : versions) {
if (info.version == "02.08.01") { if (info.version == "02.08.04") {
REQUIRE(info.is_latest); REQUIRE(info.is_latest);
REQUIRE_FALSE(info.is_loaded); REQUIRE_FALSE(info.is_loaded);
} }