dbb580b2c8
Adds `MxAsbClient.Probe --dump-signed-xml` flag that builds five ConnectedRequest shapes (AuthenticateMe, Disconnect, KeepAlive, RegisterItemsRequest, UnregisterItemsRequest) with deterministic field values and prints `AsbSerialization.ToXml(...)` output. The output is exactly what `AsbSystemAuthenticator.Sign` HMACs (`AsbSystemAuthenticator.cs:79`), so the Rust port's canonical-XML emitter must produce byte-identical bytes for HMAC parity. Captured fixtures land under `rust/crates/mxaccess-asb/tests/fixtures/signed-xml/`: - `authenticate-me.xml` — 1000 bytes - `disconnect.xml` — 980 bytes - `keep-alive.xml` — 705 bytes - `register-items.xml` — 1068 bytes - `unregister-items.xml` — 1072 bytes Plus a `README.md` documenting 10 inferred XmlSerializer rules (element name = class name not WrapperName, field order = declaration order not [MessageBodyMember.Order], `[XmlType.Namespace]` on field type causes per-child xmlns redeclaration on the children not the wrapper, `*Specified` pattern controls Xxx emission, CRLF + 2-space indent + utf-16 declaration but UTF-8 bytes fed to HMAC). `.gitattributes` marks the XML fixtures as binary (`*.xml -text`) so neither `core.autocrlf` nor `text` filters can rewrite the byte content — CRLF is part of the canonical form and must survive round-trip through Git untouched. `MxAsbClient.csproj` gains `<InternalsVisibleTo Include="MxAsbClient .Probe" />` so the probe can reach the internal `AsbSerialization` helper without making it public. Workspace: 702 tests pass (no Rust changes — fixtures only). F28 follow-up updated with the captured fixtures + the inferred rules. 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.