Scope: observation only — my own network traffic + binary metadata (dynamic deps, strings). Architecture identification for interoperability. No decryption, no pinning bypass, no key extraction, no impersonation client. Nothing is re-implemented here — only identified.
- Device: Bambu Lab X1C — SN
00M00X000000000, LAN IP192.168.20.154 - Account: cloud OK, MQTT cloud
us.mqtt.bambulab.com:8883(useru_1504114800) - Printer
ipcamtelemetry (given):agora_service:"disable",brtc_service:"enable",tutk_server:"disable" - Date: 2026-06-24
- Tooling:
otool -L,strings,lsof,dig,whois(read-only)
Cloud camera transport on this X1C firmware = BRTC (Bambu's own WebRTC stack), signaled
through DevSignal.bambu.com.
Confidence by evidence type:
- Binary capability: ✅ strong — Bambu Studio ships and supports all three transports and selects one per-device at runtime.
- Per-device selection: ✅ strong (telemetry) — the X1C itself reports
brtc_service:"enable"with Agora and TUTK disabled. - Per-device network proof: ⏳ pending — the LAN capture caught no camera stream (printer was LAN-reachable → Studio prefers the local path; see §2.3). The decisive cloud capture must be run off the LAN (iPhone 4G hotspot). Expectation below in §2.4.
Bambu Studio links three camera transports and picks one based on what the printer advertises:
| URI scheme (in plugin) | Transport | SDK / endpoint | State on this X1C |
|---|---|---|---|
bambu:///agora?app= |
Agora SD-RTN | AgoraRtcKit.framework v4.2.6.248, *.edge.agora.io / *.edge.sd-rtn.com |
agora_service: disable |
bambu:///tutk?uid= |
TUTK (ThroughTek) | REST …/iot-service/api/user/ttcode |
tutk_server: disable |
brtc://emmc/%1% |
BRTC (Bambu RTC) | signaling DevSignal.bambu.com (proprietary) |
brtc_service: enable ✅ |
bambu:///local/ |
LAN RTSP | liblive555.dylib, rtsps://…:322 |
used when on-LAN |
Reading: Agora is bundled as a legacy / fallback transport (older firmware & other models), but it is disabled on this device. The current X1C firmware has migrated the cloud camera to BRTC, Bambu's in-house WebRTC.
AgoraCore.framework AgoraRtcKit.framework
AgoraSoundTouch.framework Agoraffmpeg.framework
libbambu_networking.dylib (46 MB, closed network plugin)
libBambuSource.dylib liblive555.dylib (RTSP, LAN camera)
AgoraRtcKitidentifies as Agora RTC SDK 4.2.6.248, with edge hosts*.edge.agora.io,*.edge.sd-rtn.com(Agora's Software-Defined RTN).otool -L libbambu_networking.dylibdoes not statically link the Agora frameworks → they aredlopen'd at runtime only when the Agora transport is selected. Consistent with per-device transport switching.
bambu:///agora?app= ← Agora channel join
bambu:///tutk?uid= ← TUTK P2P by device UID
brtc://emmc/%1% ← BRTC stream
bambu:///local/ ← LAN
…/iot-service/api/user/ttcode ← TUTK TTCode credential endpoint
…/iot-service/api/user/applications/%2%/cert?aes256=%3% ← device cert (Agora/BRTC auth)
https://api.bambulab.com/v1 ← cloud REST base
ssl://us.mqtt.bambulab.com:8883 ← cloud MQTT
Signaling / device-service host family (none resolve publicly → internal split-horizon DNS):
DevSignal.bambu.com ← BRTC signaling (camera)
DevConnect.bambu.com DevBind.bambu.com Devseclink.bambu.com
DevInf.bambu.com DevModel.bambu.com DevName.bambu.com DevVersion.bambu.com
DeviceSubscribeManager strings confirm an auto local/cloud channel switch: Studio creates a
local channel when the printer IP is reachable and only falls back to the cloud channel when the
local one is missing or stale ("local channel doesn't provide data for a long time, switch to
cloud").
While Bambu Studio ran on the LAN, sampled every 2 s:
UDP *:2021 (discovery / SSDP listen)
UDP *:58424 (media/listen)
TCP 192.168.20.165 → 54.185.138.159:8883 (cloud MQTT — AWS / EMQX Cloud Pro)
TCP 192.168.20.165 → 192.168.20.154:8883 (LOCAL printer MQTT)
No new socket appeared — no :322 RTSP, no Agora edge, no DevSignal — i.e. the camera live
view was not streaming during the window, and with the printer LAN-reachable Studio would have
used the local path anyway. Inconclusive for the cloud transport by design.
Goal: make the printer unreachable on the LAN so Studio is forced onto the cloud channel, then open the camera and classify the hosts contacted.
- Switch the Mac's network to the iPhone 4G hotspot (printer no longer routable).
- Confirm the local MQTT link is gone, only the cloud one remains:
lsof -nP -iTCP -a -c BambuStudio | grep 8883→ should show only the AWS IP, not192.168.20.154. - Start the host monitor (no sudo needed — we only need the remote IPs):
for i in $(seq 1 45); do lsof -nP -i -a -c BambuStudio | awk 'NR>1{print $9}'; echo ---; sleep 2; done | tee ~/bambu_cloud_conns.log - Open the camera live view in Bambu Studio for ~30 s.
- Reverse/whois every new remote IP:
dig +short -x <IP>; whois <IP> | grep -iE 'OrgName|netname'
Interpretation:
- New UDP flow +
DevSignal.bambu.com/ Bambu-owned IPs, noagora.io/sd-rtn.com→ confirms BRTC. - Hosts under
*.edge.agora.io/*.edge.sd-rtn.com→ Agora (would contradict the telemetry). ThroughTek/iotcplatformASN → TUTK.
| Transport | Path to a legal third-party client | Verdict |
|---|---|---|
| Agora | Fetch per-session token from Bambu cloud endpoint + official Agora SDK | Tractable — but disabled on this device |
| TUTK | POST /v1/iot-service/api/user/ttcode + ThroughTek SDK (license, heavy) |
Heavy — and disabled |
| BRTC (active) | Proprietary signaling (DevSignal.bambu.com), no public SDK, internal DNS, no documented API |
Dead end for a clean third-party cloud client |
Because the active transport is BRTC — undocumented, no SDK, internal-only signaling — there is no viable, legal way to consume the cloud camera from a third-party app without reverse-engineering Bambu's signaling and impersonating their client, which is explicitly out of scope.
Use the LAN relay, not the cloud. For a product, stream the printer's local RTSPS feed and re-publish it:
- Source:
rtsps://bblp:<access_code>@192.168.20.154:322/streaming/live/1 - Relay: go2rtc or ffmpeg (→ WebRTC/HLS/MJPEG for the app UI), optionally behind your own tunnel for remote access.
Rationale:
- The cloud transport (BRTC) is proprietary and a realistic dead end (§3).
- The LAN RTSPS feed is stable, documented in
renderer/printers/bambulab/PROTOCOL.md, requires only the access code the user already holds, and stays entirely within the user's network — no legal/ToS exposure, no dependency on Bambu's cloud signaling. - For "remote" viewing, tunnel the relay (your infra) rather than touching Bambu's cloud path.
Status: cloud verdict established by binary + device telemetry; network confirmation pending the 4G test (§2.4). This file will be updated with the captured cloud hosts once that run is done.