983f02921c
rust / build / test / clippy / fmt (push) Has been cancelled
Extends the example to exercise the full data-plane through the
new canonical-XML signing path (F28 step 2). Each op is announced
with a "[canonical XML <Op>]" tag in the trace so the lifecycle is
self-documenting:
Connect → Register → Read → Write → CreateSubscription
→ AddMonitoredItems → Publish × N → PublishWriteComplete
→ DeleteMonitoredItems → DeleteSubscription
→ UnregisterItems → Disconnect → SendEnd
Per-section errors are caught and logged but don't abort the
lifecycle — a failed Publish still reaches Disconnect cleanly so
the server-side pending-connection table doesn't fill up.
New env vars MX_RUN_WRITE / MX_RUN_SUBSCRIBE / MX_SUBSCRIBE_COUNT
(defaults: run, run, 3) for opting into / sizing the optional steps.
Live verification on this host (this turn, first run):
register status: 1 item(s); result_code=Some(0) success=Some(true)
TestChildObject.TestInt = AsbVariant{type_id:4,length:4,payload:[99]}
write status: 0 item(s); result_code=Some(0) success=Some(true)
subscription_id=2 result_code=Some(0) success=Some(true)
add status: 0 item(s); result_code=Some(0) success=Some(true)
publish: 0 value(s); result_code=Some(32) success=Some(false)
publish_write_complete: 0 write(s); result_code=Some(0)
delete_monitored_items ok
delete_subscription ok
unregistering ... disconnecting
All 13 canonical-XML-signed ops accepted by MxDataProvider — no SOAP
faults, no HMAC rejections, no decode errors. F28 step 2 verified
end-to-end against the live AVEVA install.
Bonus fix: F26 stream's publish_loop bail logic narrowed.
The original F33 bail-on-any-non-zero-result_code was over-aggressive:
.NET's MxAsbClient.Probe shows that result_code=32 (= 0x20) fires on
*every* Publish poll while values are still being delivered. Updated
publish_loop and the example's Publish loop to bail only on
RESULT_CODE_INVALID_CONNECTION_ID (1) — that one truly means the
session is desynced. Other non-zero result_codes are informational
and the loop continues draining.
New public re-export: mxaccess_asb::RESULT_CODE_INVALID_CONNECTION_ID
(was crate-private under the operations module).
The InvalidConnectionId transient still hits after many back-to-back
test runs against a long-running MxDataProvider — the pending-
connection table fills up — same well-documented behaviour from F32.
A 30-second cool-down restores reliability in our experience.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
mxaccess (Rust port)
Native Rust replacement for AVEVA / Wonderware MXAccess. See ../design/ for
the architectural specification, ../src/ for the .NET reference (the
executable spec), and ../CLAUDE.md for project-wide rules.
Status
M0 — Workspace skeleton. Stub types compile; nothing is implemented yet.
See ../design/60-roadmap.md for the M0–M6 milestone plan.
Layout
rust/
Cargo.toml workspace root
rust-toolchain.toml 1.85 stable
crates/
mxaccess-codec/ pure protocol codec, no I/O
mxaccess-galaxy/ Galaxy SQL resolver (tiberius)
mxaccess-rpc/ DCE/RPC + NTLMv2 + OXID + OBJREF
mxaccess-callback/ INmxSvcCallback RPC server
mxaccess-nmx/ INmxService2 client
mxaccess-asb-nettcp/ net.tcp framing (MC-NMF + MC-NBFX/NBFS)
mxaccess-asb/ IASBIDataV2 client
mxaccess/ async session + Transport trait + public API
mxaccess-compat/ LMXProxyServer-shaped facade
Build
cargo build --workspace
cargo test --workspace
cargo clippy --workspace -- -D warnings
cargo fmt --check
Live probes
. ..\tools\Setup-LiveProbeEnv.ps1
cargo test -p mxaccess --features live -- --ignored
The setup script fetches credentials from Infisical via
wwtools/secrets/Get-Secret.ps1. Never inline plaintext credentials.
License
MIT — see ../LICENSE.