Files
mxaccess/rust
Joseph Doherty e3baeb8803 [M5] mxaccess: F26 step 3 — AsbSession high-level cheap-clone async API
Adds the public high-level entry point for the ASB transport.
Parallel to the NMX-shaped `Session` (rather than unified) because
NMX's `Session` carries CallbackExporter / callback router task /
recovery broadcast / INmxService2 mutex orchestration that has no
ASB analogue — and ASB's request/response loop over a single TCP
stream maps naturally to `Mutex<AsbClient>` that would be foreign
to NMX. Two paths converge at the consumer-facing API but stay
distinct at the orchestration layer.

Struct shape:
```rust
pub struct AsbSession { inner: Arc<AsbSessionInner> }
struct AsbSessionInner {
    transport: Mutex<AsbTransport<TcpStream>>,
    connect_response: ConnectResponse,
}
```

`Clone + Send + Sync` — clones share state through `Arc`, lock
serialises operations. Compile-time `assert_clone_send_sync` test
guards the contract.

API:
* `connect(endpoint, passphrase, crypto_parameters, via_uri,
  connection_id)` — full bring-up (TCP + preamble + DH handshake).
* `from_transport(transport, connect_response)` — build from an
  existing transport (tests, custom transports).
* `connect_response()` — surface the negotiated lifetime /
  Apollo flag.

Operation methods forward to AsbClient:
* `register_items` / `unregister_items` / `read` / `write`
* `keep_alive` / `disconnect`
* `create_subscription` / `add_monitored_items` / `publish` /
  `delete_monitored_items` / `delete_subscription`
* `publish_write_complete`

ClientError → mxaccess::Error mapping via
`ConnectionError::TransportFailure` (consistent with F26 step 2).

1 new test:
* `asb_session_is_clone_send_sync` — compile-time trait-bound
  assertion.

Workspace: 702 tests pass.

Stubbed for next F26 iteration:
* `Stream<Item = MonitoredItemValue>` subscription handle that
  internally drives a publish-loop. Today consumers loop
  `publish().await` themselves.
* Recovery / reconnect policy — needs a captured ASB-side
  disconnect to inform the retry strategy.
* Live-probe wire-byte reconciliation against the WCF DataContract
  XML serializer's actual output.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 13:23:59 -04:00
..

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 M0M6 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.