Files
mxaccess/rust
Joseph Doherty c4bf0a0a04 [M5] mxaccess-asb: F25 step 3 — response decoders + Read request body
Foundation for response decoding. Adds:

* `contracts::ItemStatus` — ports `AsbContracts.cs:639-722`. Wire
  layout matches `WriteToStream` exactly: Item (ItemIdentity binary)
  → Status (AsbStatus binary, from F24) → ErrorCode (u16) →
  ErrorCodeSpecified (u8 bool). Note this is NOT the DataMember
  declaration order — the binary serialiser hand-picks Item-first.

* `encode_item_status_array` / `decode_item_status_array` — same
  4-byte int32 count + per-element WriteToStream pattern as the
  ItemIdentity array codec.

* `operations::collect_asbidata_payloads(tokens, field_name)` — walks
  an NBFX token stream and pulls out `<{field}><ASBIData>{Bytes}
  </ASBIData></{field}>` payload bytes. Returns Vec<Vec<u8>> because
  some response shapes (ReadResponse) carry multiple ASBIData
  payloads (Status + Values).

* `decode_register_items_response` / `decode_unregister_items_response`
  — parse SOAP body NBFX tokens into typed RegisterItemsResponse /
  UnregisterItemsResponse. The optional ItemCapabilities array (XML-
  serialised, not binary) is recorded as a presence flag for now;
  decoding the individual ItemRegistration records is a follow-up.

* `build_read_request_body(items)` — simplest unary IASBIDataV2
  request, just `<ReadRequest xmlns="..."><Items><ASBIData>...
  </ASBIData></Items></ReadRequest>`.

* `OperationError` — typed error for response-decode failures
  (`MissingField { field }` and codec wraps).

9 new tests: ItemStatus round-trip (default + with id + with status
payload), ItemStatus array round-trip, RegisterItemsResponse
round-trip via synthetic body, ItemCapabilities presence detection,
UnregisterItemsResponse round-trip, multi-payload extraction (ReadResponse-
shape Status + Values), Read body shape correctness, MissingField
error when Status is absent.

Stubbed for next F25 iteration: Write / PublishWriteComplete /
CreateSubscription / AddMonitoredItems / DeleteMonitoredItems /
Publish builders, ReadResponse + WriteResponse decoders (need
WriteValue / RuntimeValue contract codecs), and the AsbClient
network loop.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 11:32:36 -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.