Layout:
- src/ .NET 10 x64 reference: MxNativeCodec, MxNativeClient,
MxAsbClient, probes, tests, harnesses. Executable spec.
- design/ Architectural plan for the Rust port (M0–M6), error
model, protocol invariants, risks (R1–R16), adversarial
review log (review.md).
- rust/ Rust workspace. M0 skeleton + M1 codec parity.
mxaccess-codec: 215 unit tests + 2 cross-implementation
parity tests (byte-identical against .NET reference).
Other crates are M0 stubs awaiting M2+.
- captures/ Frida + netsh + pcap evidence per CLAUDE.md
("captures are evidence, not throwaway logs").
- analysis/ Decompiled C# (frida/proxy/decompiled-*),
Ghidra exports for native DLLs (`exports/` only —
working state at `projects/` and AVEVA's input
binaries at `input/` are gitignored).
- docs/ Reverse-engineering reference docs.
- tools/ Setup-LiveProbeEnv.ps1 (Infisical credential fetcher),
Compute-Crc.ps1 (.NET parity helper).
- .github/workflows/ Rust CI: fmt + build + test + clippy on Windows.
- LICENSE MIT (Joseph Doherty, 2026).
Verified:
- cargo test --workspace → 217 passed (215 unit + 2 .NET parity), 0 failed
- cargo clippy --workspace -- -D warnings → clean
- cargo fmt --all -- --check → clean
- cargo publish --dry-run -p mxaccess-codec → packages cleanly
Excluded from history (see .gitignore):
- **/bin, **/obj, **/target — build artifacts
- analysis/ghidra/projects/ — Ghidra working state (regenerable)
- analysis/ghidra/input/ — AVEVA proprietary DLLs (vendor IP)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
13 KiB
Core Remaining Work
Current Baseline
The pure managed .NET 10 x64 ASB path is feasible and live-proven. It can:
- read the ASB solution shared secret through DPAPI,
- authenticate to the live
IASBIDataV2net.tcp endpoint, - register/read
TestChildObject.TestInt, - reject null public collection arguments before touching client state in the main multi-item APIs,
- decode/read/write the core scalar and array ASB type matrix,
- write
Int32values and read them back, - write through either positional write parameters or
AsbWriteOptions, - poll
PublishWriteCompletefor write completion, - create a subscription, add monitored items, publish updates, and delete the monitored items/subscription,
- configure subscription creation and monitored-item registration through stable option records while preserving the original positional overloads,
- map publish responses into callback-ready values with decoded value, timestamp, quality, ASB status elements, and item-id-to-tag-name resolution,
- expose publish result summaries and value-presence helpers alongside the raw publish response and mapped values,
- expose derived publish/data-change status summaries and item-status array summary mapping while preserving raw statuses,
- raise mapped publish updates through the
MxAsbClientPublishedValueReceivedevent, - adapt ASB publish updates into an MXAccess-like server/item-handle
DataChangedfacade, - advise compatibility items through either positional subscription parameters
or the shaped
AsbSubscriptionOptions/AsbMonitoredItemOptionsoverload, - map known ASB global and item error codes to named
AsbErrorCodevalues, - summarize ASB status payload quality/category/detail while preserving raw unknown values,
- wait for async write completion by handle with timeout, poll interval, and optional delayed readback without retrying the write,
- cancel write-completion polling before the next poll or during polling/
readback delays through
AsbWriteCompletionOptions.CancellationToken, - perform idempotent best-effort ASB cleanup with signed
Disconnect, independent channel/factory close-or-abort handling, and cleanup result reporting, - explicitly reconnect by cleaning up the current ASB channel, retrying connection creation with caller-controlled attempts/delay, returning a fresh client, and preserving attempt plus cleanup evidence without replaying operations,
- connect through a stable
AsbConnectionOptionsAPI object with early endpoint validation and matching compatibility-server register/advise options overloads, - keep payload serialization diagnostics out of the public API surface while retaining friend-only probe/test access,
- bound ASB cleanup disconnect and close operations with caller-controlled timeouts,
- cancel ASB cleanup before graceful disconnect/close by aborting local channel/factory objects when the cleanup token is already canceled,
- live-prove canceled cleanup on an opened ASB connection, including skipped
disconnect, local channel/factory abort, and
RequiresNewConnection, - test cleanup partial-failure behavior for closed objects, faulted objects, close failure with abort fallback, abort failure reporting, and configured close timeout propagation,
- capture safe connection-failure evidence for refused ASB endpoints without destabilizing the live provider,
- clean up partially-created WCF channel/factory objects when ASB connection setup fails before a disposable client is returned,
- match installed AVEVA proxy behavior for
UnregisterItems, - register/read multiple tags in one request.
- document the supported ASB
Variantwire format, scalar/array payload layouts, timestamp/duration handling, and quality/status payload parsing indocs\ASB-Variant-Wire-Format.md, - document the recommended ASB/native integration boundary and staged migration
in
docs\ASB-Native-Integration-Decision.md.
Recent NMX Warning Triage
System Platform warning:
NMX Header ... buffer size pktHeader.dwDataSize 381 doesn't match received message size of 46
The warning is emitted by NmxAdptr.dll in the ProcessDataReceived path, not
by the pure ASB client. The 46 byte received size matches the standalone NMX
TransferData envelope size. A valid TransferData operation must send the
46-byte envelope plus the declared inner body; if the service receives only the
envelope, or any envelope whose inner-length field does not match the actual
body length, the adapter logs this class of header-size warning.
Mitigation now applied:
src\NmxComHarnessno longer sends a default self-transfer body. The--self-transferpath requires explicit--transfer-body-hex, validates the 46-byte envelope length field, and rejects empty/header-only transfers unless--allow-empty-transferis explicitly supplied for a controlled probe.src\MxNativeClientvalidates low-levelTransferDatabodies before sending through both COM and managed DCE/RPC paths.src\MxNativeClient.Probenow requires explicit validated--transfer-body-hexfor managedTransferDataprobes.
Build/test verification after mitigation:
dotnet build src\NmxComHarness\NmxComHarness.csprojdotnet build src\MxNativeClient\MxNativeClient.csprojdotnet build src\MxNativeClient.Probe\MxNativeClient.Probe.csprojdotnet run --project src\MxNativeClient.Tests\MxNativeClient.Tests.csprojdotnet run --project src\MxNativeCodec.Tests\MxNativeCodec.Tests.csproj
Remaining Core Work
-
ASB type matrix
- Core scalar/array decode, live read, and live write coverage is complete for Boolean, Int32, Float, Double, String, DateTime, Duration, and deployed array tags.
- Remaining work is adding less common ASB types only as needed by real deployed tags.
- ASB variant type IDs, payload layout, timestamp handling, duration handling,
and quality/status payload parsing are documented in
docs\ASB-Variant-Wire-Format.md.
-
ASB subscriptions and publish
CreateSubscription,AddMonitoredItems,Publish,DeleteMonitoredItems, andDeleteSubscriptionare implemented and live-proven.AsbSubscriptionOptionsandAsbMonitoredItemOptionsnow provide stable option-object overloads for subscription creation and monitored-item registration.- Mapped publish updates are exposed through a .NET event and a handle-based data-change facade.
- The compatibility
Advisefacade also acceptsAsbSubscriptionOptionsandAsbMonitoredItemOptions; the probe path can exercise this options overload and live compatibility subscribe has been verified through it. AsbPublishResultnow carries a derived result summary andHasValueshelper while retaining the rawPublishResponse.AsbPublishedValueandMxAsbDataChangeEventexpose derivedStatusSummaryhelpers for callers that want named status categories without losing raw status elements.- Item identity mapping and basic cleanup behavior are live-proven; continue validating callback/update ordering under churn.
-
Status and error mapping
- Success-path publish quality/status decoding is implemented for ASB status elements, including
MxQuality. - Named global/item ASB error-code mapping is implemented, and live probes cover
InvalidMonitoredItems,OperationFailed,MonitoredItemsNotFound,WriteFailedBadTypeMismatch, invalid subscription delete global0x000C, publish0x0020, and bad-quality value status. - Status summaries classify good/uncertain/bad quality, known MX status categories, request timeout detail, and platform/no-communication detail.
- Broaden remaining live non-success ASB
ArchestrAError, item status, quality bytes, and known detail cases into the managed status model when safe source conditions are available, especially access denied and no communication. - Safe current-VM probes did not produce access denied or no communication: same-value direct ASB writes to secured/verified booleans succeeded, and a read-only sweep of 20 protected-value tags returned good quality.
- Preserve unknown payloads without guessing.
- Tests now cover success, invalid item, wrong-type write completion, invalid cleanup evidence inputs, access denied, timeout, no communication, and async write completion statuses.
- Success-path publish quality/status decoding is implemented for ASB status elements, including
-
Write variants
- Core scalar and deployed array writes are live-proven beyond basic
Int32. AsbWriteOptionsnow provides an option-object overload for basic writes while preserving the existing positional overloads.- Add timestamp/status/comment handling where the provider supports it.
- Write completion polling by handle with timeout, optional delayed readback,
option validation, and caller cancellation is implemented and live-proven
for
Int32; extend evidence across other supported write shapes.
- Core scalar and deployed array writes are live-proven beyond basic
-
OperationComplete parity
- Basic write completion through
PublishWriteCompleteis proven. - Direct
IASBIDataV2has no activate/suspend or generic OperationComplete contract, and create-subscription, add-monitored, publish, delete-monitored, and delete-subscription operations do not enqueuePublishWriteCompleterecords. - Continue trigger search outside the direct IDataV2 write-completion queue if a safe runtime candidate appears.
- Do not synthesize
OperationCompletefor operations until native behavior is proven.
- Basic write completion through
5a. Completion-only operation status
- One-byte NMX completion-only frames are preserved as raw, unpromoted
statuses, including
0x00,0x41, and0xEF. - Only the observed 5-byte status-word frame
00 00 50 80 00maps toMxStatus.WriteCompleteOkand can raise the MXAccess-compatible write-complete event. - Exact native
MXSTATUS_PROXY[]conversion for completion-only bytes still needs decompiled mapping evidence or a native public event capture before promotion. - Current available decompiled/Ghidra outputs did not expose a mapping table for completion-only bytes.
-
Buffered data
- Find a runtime/source condition that emits buffered sample batches.
- ASB
MonitoredItem.Bufferedis now exposed and live-proven againstTestMachine_001.TestHistoryValue, but the observed publish response still carries one current value rather than a multi-sample buffered batch. - Map any proven batch payloads into the compatibility event model.
-
Production cleanup
- Reduce trace verbosity and make SOAP/body dumps opt-in.
- Channel/factory disposal now sends best-effort signed
Disconnect, closes channel/factory independently with caller-controlled timeouts, and records cleanup results. - Cleanup cancellation is implemented for cancellation requested before graceful disconnect/close starts; already-running synchronous WCF cleanup calls remain bounded by configured timeouts.
- Canceled cleanup is live-proven on an opened ASB channel and completes via local abort without hanging.
- Explicit reconnect is implemented and live-proven for the normal cleanup and reconnect path.
- Resolve additional live partial cleanup behavior after ASB channel failures when a safe provider condition is available.
- Safe refused-endpoint connection failure evidence is captured; source-level no-communication evidence still needs a safe provider condition.
- Partial ASB connection setup failure now runs channel/factory close-or-abort cleanup before rethrowing.
-
Public library shaping
- The main probe-grade API primitives have been shaped into stable public option/helper surfaces; continue only for concrete caller gaps.
AsbConnectionOptionsnow frontsMxAsbDataClient.Connect, the string overload delegates to it, andMxAsbCompatibilityServer.Registeraccepts the same options object.AsbWriteOptionsnow fronts the basic write path while preserving the existing positional write overloads.MxAsbCompatibilityServer.Advisenow has an options overload, and the probe can route compatibility subscribe through it.AsbPayloadDebughas been narrowed to an internal friend-only diagnostic helper for test/probe assemblies.AsbWriteCompletionOptionsnow owns timeout/poll/readback validation and exposes a cancellation token for caller-controlled polling waits.AsbSubscriptionOptionsandAsbMonitoredItemOptionsnow avoid extending positional primitive overloads as subscription policy grows.AsbPublishResultnow exposes common summary helpers without hiding raw response details.AsbPublishedValue,MxAsbDataChangeEvent, andAsbResultMappernow expose derived status-summary helpers for common caller paths.- Public collection null guards are explicit for the main multi-item APIs.
docs\ASB-Native-Integration-Decision.mdrecords the current integration decision: useMxAsbClientas the preferred regular tag data-plane adapter behind a higher-level compatibility routing facade, while keeping native NMX responsible for callback-only and not-yet-proven MXAccess semantics.- Focused non-live tests now cover public options defaults/validation, compatibility overload visibility, write-completion/readback DTO shape, and publish-result helpers. Add deeper request-construction tests only where future API growth makes them necessary.
- Keep compatibility behavior documented where the deployed provider differs from ideal success semantics.