fe2a6db786
rust / build / test / clippy / fmt (push) Has been cancelled
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>
233 lines
13 KiB
Markdown
233 lines
13 KiB
Markdown
# 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 `IASBIDataV2` net.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 `Int32` values and read them back,
|
|
- write through either positional write parameters or `AsbWriteOptions`,
|
|
- poll `PublishWriteComplete` for 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 `MxAsbClient` `PublishedValueReceived`
|
|
event,
|
|
- adapt ASB publish updates into an MXAccess-like server/item-handle
|
|
`DataChanged` facade,
|
|
- advise compatibility items through either positional subscription parameters
|
|
or the shaped `AsbSubscriptionOptions` / `AsbMonitoredItemOptions` overload,
|
|
- map known ASB global and item error codes to named `AsbErrorCode` values,
|
|
- 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 `AsbConnectionOptions` API 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 `Variant` wire format, scalar/array payload
|
|
layouts, timestamp/duration handling, and quality/status payload parsing in
|
|
`docs\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:
|
|
|
|
```text
|
|
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\NmxComHarness` no longer sends a default self-transfer body. The
|
|
`--self-transfer` path requires explicit `--transfer-body-hex`, validates the
|
|
46-byte envelope length field, and rejects empty/header-only transfers unless
|
|
`--allow-empty-transfer` is explicitly supplied for a controlled probe.
|
|
- `src\MxNativeClient` validates low-level `TransferData` bodies before sending
|
|
through both COM and managed DCE/RPC paths.
|
|
- `src\MxNativeClient.Probe` now requires explicit validated
|
|
`--transfer-body-hex` for managed `TransferData` probes.
|
|
|
|
Build/test verification after mitigation:
|
|
|
|
- `dotnet build src\NmxComHarness\NmxComHarness.csproj`
|
|
- `dotnet build src\MxNativeClient\MxNativeClient.csproj`
|
|
- `dotnet build src\MxNativeClient.Probe\MxNativeClient.Probe.csproj`
|
|
- `dotnet run --project src\MxNativeClient.Tests\MxNativeClient.Tests.csproj`
|
|
- `dotnet run --project src\MxNativeCodec.Tests\MxNativeCodec.Tests.csproj`
|
|
|
|
## Remaining Core Work
|
|
|
|
1. 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`.
|
|
|
|
2. ASB subscriptions and publish
|
|
- `CreateSubscription`, `AddMonitoredItems`, `Publish`, `DeleteMonitoredItems`, and `DeleteSubscription` are implemented and live-proven.
|
|
- `AsbSubscriptionOptions` and `AsbMonitoredItemOptions` now 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 `Advise` facade also accepts
|
|
`AsbSubscriptionOptions` and `AsbMonitoredItemOptions`; the probe path can
|
|
exercise this options overload and live compatibility subscribe has been
|
|
verified through it.
|
|
- `AsbPublishResult` now carries a derived result summary and `HasValues`
|
|
helper while retaining the raw `PublishResponse`.
|
|
- `AsbPublishedValue` and `MxAsbDataChangeEvent` expose derived
|
|
`StatusSummary` helpers 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.
|
|
|
|
3. 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 global `0x000C`, publish `0x0020`, 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.
|
|
|
|
4. Write variants
|
|
- Core scalar and deployed array writes are live-proven beyond basic `Int32`.
|
|
- `AsbWriteOptions` now 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.
|
|
|
|
5. OperationComplete parity
|
|
- Basic write completion through `PublishWriteComplete` is proven.
|
|
- Direct `IASBIDataV2` has no activate/suspend or generic OperationComplete
|
|
contract, and create-subscription, add-monitored, publish,
|
|
delete-monitored, and delete-subscription operations do not enqueue
|
|
`PublishWriteComplete` records.
|
|
- Continue trigger search outside the direct IDataV2 write-completion queue
|
|
if a safe runtime candidate appears.
|
|
- Do not synthesize `OperationComplete` for operations until native behavior is proven.
|
|
|
|
5a. Completion-only operation status
|
|
- One-byte NMX completion-only frames are preserved as raw, unpromoted
|
|
statuses, including `0x00`, `0x41`, and `0xEF`.
|
|
- Only the observed 5-byte status-word frame `00 00 50 80 00` maps to
|
|
`MxStatus.WriteCompleteOk` and 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.
|
|
|
|
6. Buffered data
|
|
- Find a runtime/source condition that emits buffered sample batches.
|
|
- ASB `MonitoredItem.Buffered` is now exposed and live-proven against
|
|
`TestMachine_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.
|
|
|
|
7. 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.
|
|
|
|
8. Public library shaping
|
|
- The main probe-grade API primitives have been shaped into stable public
|
|
option/helper surfaces; continue only for concrete caller gaps.
|
|
- `AsbConnectionOptions` now fronts `MxAsbDataClient.Connect`, the string
|
|
overload delegates to it, and `MxAsbCompatibilityServer.Register` accepts
|
|
the same options object.
|
|
- `AsbWriteOptions` now fronts the basic write path while preserving the
|
|
existing positional write overloads.
|
|
- `MxAsbCompatibilityServer.Advise` now has an options overload, and the
|
|
probe can route compatibility subscribe through it.
|
|
- `AsbPayloadDebug` has been narrowed to an internal friend-only diagnostic
|
|
helper for test/probe assemblies.
|
|
- `AsbWriteCompletionOptions` now owns timeout/poll/readback validation and
|
|
exposes a cancellation token for caller-controlled polling waits.
|
|
- `AsbSubscriptionOptions` and `AsbMonitoredItemOptions` now avoid extending
|
|
positional primitive overloads as subscription policy grows.
|
|
- `AsbPublishResult` now exposes common summary helpers without hiding raw
|
|
response details.
|
|
- `AsbPublishedValue`, `MxAsbDataChangeEvent`, and `AsbResultMapper` now
|
|
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.md` records the current integration
|
|
decision: use `MxAsbClient` as 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.
|