The only way to give a gateway a printer was to edit printers.toml and restart it. A printer added from the console now arrives as a provision_printer message, is checked by actually connecting to it (so a mistyped access code is reported to the operator, not discovered later), and only then is saved to the gateway's own SQLite file and joined to the running fleet - no restart. remove_printer undoes it. Both are answered with a command_result carrying the request id. The access code exists only on the gateway: the cloud relays it once and keeps nothing, which is the platform's rule for printer credentials. The store file is created owner-only; the message type's Debug and the fleet entry's Debug redact the credential; and an unparseable message from the cloud is no longer logged with its payload, because the message that fails to parse is exactly the one carrying an access code. The cloud may not choose a certificate path or serial port on the gateway's disk, so provision_printer cannot carry them. Startup now reads printers.toml (strict, as before; a missing file is fine) and the store (a bad stored entry is skipped, not fatal), so the gateway comes up with its fleet with the API unreachable. Discovery treats stored printers as already configured. rusqlite (MIT, bundled SQLite) passes cargo deny.
101 lines
4.0 KiB
TOML
101 lines
4.0 KiB
TOML
[package]
|
|
name = "continuum-proxy"
|
|
version = "0.1.0"
|
|
edition = "2024"
|
|
description = "Continuum edge gateway daemon - runs on-site, bridges printers to the cloud control plane"
|
|
# Proprietary: deliberately not an SPDX id, so cargo-deny treats it as
|
|
# first-party. See docs/LICENSES.md in continuum-common.
|
|
license = "LicenseRef-Proprietary"
|
|
publish = false
|
|
|
|
[lib]
|
|
name = "continuum_proxy"
|
|
path = "src/lib.rs"
|
|
|
|
[[bin]]
|
|
name = "continuum-proxy"
|
|
path = "src/main.rs"
|
|
|
|
[[example]]
|
|
name = "printer_polymorphism"
|
|
path = "examples/printer_polymorphism.rs"
|
|
|
|
[[example]]
|
|
name = "test_bambu_certs"
|
|
path = "examples/test_bambu_certs.rs"
|
|
|
|
[[example]]
|
|
name = "auto_connect_bambu"
|
|
path = "examples/auto_connect_bambu.rs"
|
|
|
|
[[example]]
|
|
name = "bambu_commands_demo"
|
|
path = "examples/bambu_commands_demo.rs"
|
|
|
|
[[example]]
|
|
name = "live_reports"
|
|
path = "examples/live_reports.rs"
|
|
|
|
[[example]]
|
|
name = "bambu_idle_checks"
|
|
path = "examples/bambu_idle_checks.rs"
|
|
|
|
[dependencies]
|
|
# Real printer protocol clients (MQTT for Bambu, HTTP for PrusaLink/
|
|
# Moonraker, FTPS for gcode transfer) go here once you're ready to build
|
|
# past the stubs in src/printer/ - see that module's doc comment.
|
|
continuum-rust-types = { path = "../continuum-schemas/packages/rust-types" }
|
|
# FOR NON-LOCAL DEV
|
|
# continuum-rust-types = { git = "https://git.octoturge.com/Continuum/continuum-schemas.git" }
|
|
|
|
# Builds a JSON instance straight from the schema files in
|
|
# continuum-schemas/schemas/ - used for Bambu's raw MQTT JSON messages
|
|
# instead of hand-written serde structs (see bambu.rs).
|
|
continuum-schema-instance = { path = "../continuum-common/packages/rust-schema-instance" }
|
|
|
|
tokio = { version = "1.40", features = ["full"] }
|
|
tokio-tungstenite = { version = "0.24", features = ["native-tls"] }
|
|
futures-util = "0.3"
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
toml = "0.8"
|
|
native-tls = "0.2"
|
|
base64 = "0.22"
|
|
tracing = "0.1"
|
|
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }
|
|
anyhow = "1"
|
|
thiserror = "1"
|
|
dotenvy = "0.15"
|
|
tokio-serial = { version = "5.5.0", default-features = false }
|
|
rumqttc = { version = "0.25.1", default-features = false, features = ["use-native-tls"] }
|
|
# Blocking FTPS client for pushing project files to a printer's own
|
|
# storage (see src/printer/bambu_ftps.rs for why the blocking one, not
|
|
# the async one). `deprecated` is what gates `connect_secure_implicit`:
|
|
# Bambu speaks implicit FTPS on 990, which the RFCs deprecated in favour
|
|
# of explicit AUTH TLS. The printers do not care.
|
|
# MIT OR Apache-2.0 - checked against docs/LICENSES.md before adding.
|
|
suppaftp = { version = "12.1.1", features = ["native-tls", "deprecated"] }
|
|
zip = { version = "9.0.3", default-features = false, features = ["deflate-flate2", "aes-crypto"] }
|
|
# Reads the subject CN out of the certificate a printer presents on 8883,
|
|
# which is where its serial number is (see src/discovery.rs). Already in the
|
|
# tree - native-tls is openssl on Linux - so naming it directly adds nothing
|
|
# to the build.
|
|
# Apache-2.0 - checked against docs/LICENSES.md before adding.
|
|
openssl = "0.10"
|
|
flate2 = "1.1.10"
|
|
# HTTPS GET of a presigned job-file URL for the `start_print` command (see
|
|
# src/uplink/download.rs). Features are the bare minimum: TLS via rustls, no
|
|
# openssl-sys; no json/gzip/cookies/etc, since the body is an opaque binary.
|
|
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls-native-roots"] }
|
|
# The local IPv4 addresses, so the SSDP listener can join the multicast group
|
|
# on every interface rather than the one the OS happens to pick (see
|
|
# `bind_ssdp`). Windows PCs routinely have VPN/Hyper-V/WSL adapters.
|
|
# MIT OR BSD-3-Clause - checked against docs/LICENSES.md before adding.
|
|
if-addrs = "0.15"
|
|
# The proxy's local store (src/store.rs): printers added from the console live
|
|
# here, so the gateway keeps its fleet with the API unreachable. `bundled`
|
|
# compiles SQLite from source so the appliance image needs no system library
|
|
# (SQLite itself is public domain).
|
|
# MIT - checked with `cargo deny check licenses` (docs/LICENSES.md policy).
|
|
rusqlite = { version = "0.41", features = ["bundled"] }
|