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>
192 lines
6.8 KiB
C#
192 lines
6.8 KiB
C#
using ArchestrAServices.ASBContract;
|
|
using ArchestrAServices.ASBIDataV2Contract;
|
|
|
|
namespace ArchestrAServices.ASBIDataV2Adapter;
|
|
|
|
public static class IDataV2toV2Extensions
|
|
{
|
|
public static ArchestrAServices.ASBIDataV2Contract.ItemStatus ToTrueV2ItemStatus(this ItemStatusV2 v2ItemStatus)
|
|
{
|
|
ArchestrAServices.ASBIDataV2Contract.ItemStatus result = new ArchestrAServices.ASBIDataV2Contract.ItemStatus
|
|
{
|
|
ErrorCodeSpecified = v2ItemStatus.ErrorCodeSpecified
|
|
};
|
|
if (v2ItemStatus.ErrorCodeSpecified)
|
|
{
|
|
result.ErrorCode = v2ItemStatus.ErrorCode;
|
|
}
|
|
result.Item = v2ItemStatus.Item.ToV2ItemIdentity();
|
|
result.Status = v2ItemStatus.Status.ToV2ASBStatus();
|
|
return result;
|
|
}
|
|
|
|
public static ArchestrAServices.ASBIDataV2Contract.ItemStatus[] ToTrueV2ItemStatusArray(this ItemStatusV2[] v2ItemStatus)
|
|
{
|
|
ArchestrAServices.ASBIDataV2Contract.ItemStatus[] array = new ArchestrAServices.ASBIDataV2Contract.ItemStatus[v2ItemStatus.Length];
|
|
for (int i = 0; i < v2ItemStatus.Length; i++)
|
|
{
|
|
array[i] = v2ItemStatus[i].ToTrueV2ItemStatus();
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public static ItemStatusV2 ToMirroredV1ItemStatus(this ArchestrAServices.ASBContract.ItemStatus v1ItemStatus)
|
|
{
|
|
ItemStatusV2 result = new ItemStatusV2
|
|
{
|
|
ErrorCodeSpecified = v1ItemStatus.ErrorCodeSpecified
|
|
};
|
|
if (v1ItemStatus.ErrorCodeSpecified)
|
|
{
|
|
result.ErrorCode = v1ItemStatus.ErrorCode;
|
|
}
|
|
result.Item = v1ItemStatus.Item;
|
|
result.Status = default(ArchestrAServices.ASBContract.ASBStatus);
|
|
return result;
|
|
}
|
|
|
|
public static ItemStatusV2[] ToMirroredV1ItemStatusArray(this ArchestrAServices.ASBContract.ItemStatus[] v1ItemStatus)
|
|
{
|
|
ItemStatusV2[] array = new ItemStatusV2[v1ItemStatus.Length];
|
|
for (int i = 0; i < v1ItemStatus.Length; i++)
|
|
{
|
|
array[i] = v1ItemStatus[i].ToMirroredV1ItemStatus();
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public static ItemStatusV2 ToMirroredV2ItemStatus(this ArchestrAServices.ASBIDataV2Contract.ItemStatus trueV2ItemStatus)
|
|
{
|
|
ItemStatusV2 result = new ItemStatusV2
|
|
{
|
|
ErrorCodeSpecified = trueV2ItemStatus.ErrorCodeSpecified
|
|
};
|
|
if (trueV2ItemStatus.ErrorCodeSpecified)
|
|
{
|
|
result.ErrorCode = trueV2ItemStatus.ErrorCode;
|
|
}
|
|
result.Item = trueV2ItemStatus.Item.ToV1ItemIdentity();
|
|
result.Status = trueV2ItemStatus.Status.ToV1ASBStatus();
|
|
return result;
|
|
}
|
|
|
|
public static ItemStatusV2[] ToMirroredV2ItemStatusArray(this ArchestrAServices.ASBIDataV2Contract.ItemStatus[] truev2ItemStatus)
|
|
{
|
|
ItemStatusV2[] array = new ItemStatusV2[truev2ItemStatus.Length];
|
|
for (int i = 0; i < truev2ItemStatus.Length; i++)
|
|
{
|
|
array[i] = truev2ItemStatus[i].ToMirroredV2ItemStatus();
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public static WriteValueV2 ToMirroredV2WriteValue(this ArchestrAServices.ASBIDataV2Contract.WriteValue trueV2WriteValue)
|
|
{
|
|
WriteValueV2 result = new WriteValueV2
|
|
{
|
|
ArrayElementIndexSpecified = trueV2WriteValue.ArrayElementIndexSpecified
|
|
};
|
|
if (trueV2WriteValue.ArrayElementIndexSpecified)
|
|
{
|
|
result.ArrayElementIndex = trueV2WriteValue.ArrayElementIndex;
|
|
}
|
|
result.Comment = trueV2WriteValue.Comment;
|
|
result.HasQTSpecified = trueV2WriteValue.HasQTSpecified;
|
|
if (trueV2WriteValue.HasQTSpecified)
|
|
{
|
|
result.HasQT = trueV2WriteValue.HasQT;
|
|
}
|
|
result.HasQT = trueV2WriteValue.HasQT;
|
|
result.Status = trueV2WriteValue.Status.ToV1ASBStatus();
|
|
result.Timestamp = trueV2WriteValue.Timestamp;
|
|
result.Value = trueV2WriteValue.Value.ToV1Variant();
|
|
return result;
|
|
}
|
|
|
|
public static WriteValueV2[] ToMirroredV2WriteValueArray(this ArchestrAServices.ASBIDataV2Contract.WriteValue[] trueV2WriteValue)
|
|
{
|
|
WriteValueV2[] array = new WriteValueV2[trueV2WriteValue.Length];
|
|
for (int i = 0; i < trueV2WriteValue.Length; i++)
|
|
{
|
|
array[i] = trueV2WriteValue[i].ToMirroredV2WriteValue();
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public static ItemWriteCompleteV2 ToMirroredV1ItemWriteComplete(this ArchestrAServices.ASBContract.ItemWriteComplete v2ItemWriteComplete)
|
|
{
|
|
ItemWriteCompleteV2 itemWriteCompleteV = new ItemWriteCompleteV2();
|
|
itemWriteCompleteV.Status = v2ItemWriteComplete.Status.ToMirroredV1ItemStatusArray();
|
|
itemWriteCompleteV.WriteHandleSpecified = v2ItemWriteComplete.WriteHandleSpecified;
|
|
if (v2ItemWriteComplete.WriteHandleSpecified)
|
|
{
|
|
itemWriteCompleteV.WriteHandle = v2ItemWriteComplete.WriteHandle;
|
|
}
|
|
return itemWriteCompleteV;
|
|
}
|
|
|
|
public static ItemWriteCompleteV2[] ToMirroredV1ItemWriteCompleteArray(this ArchestrAServices.ASBContract.ItemWriteComplete[] v1ItemWriteComplete)
|
|
{
|
|
ItemWriteCompleteV2[] array = new ItemWriteCompleteV2[v1ItemWriteComplete.Length];
|
|
for (int i = 0; i < v1ItemWriteComplete.Length; i++)
|
|
{
|
|
array[i] = v1ItemWriteComplete[i].ToMirroredV1ItemWriteComplete();
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public static ItemWriteCompleteV2 ToMirroredV2ItemWriteComplete(this ArchestrAServices.ASBIDataV2Contract.ItemWriteComplete v2ItemWriteComplete)
|
|
{
|
|
ItemWriteCompleteV2 itemWriteCompleteV = new ItemWriteCompleteV2();
|
|
itemWriteCompleteV.Status = v2ItemWriteComplete.Status.ToMirroredV2ItemStatusArray();
|
|
itemWriteCompleteV.WriteHandleSpecified = v2ItemWriteComplete.WriteHandleSpecified;
|
|
if (v2ItemWriteComplete.WriteHandleSpecified)
|
|
{
|
|
itemWriteCompleteV.WriteHandle = v2ItemWriteComplete.WriteHandle;
|
|
}
|
|
return itemWriteCompleteV;
|
|
}
|
|
|
|
public static ItemWriteCompleteV2[] ToMirroredV2ItemWriteCompleteArray(this ArchestrAServices.ASBIDataV2Contract.ItemWriteComplete[] v2ItemWriteComplete)
|
|
{
|
|
ItemWriteCompleteV2[] array = new ItemWriteCompleteV2[v2ItemWriteComplete.Length];
|
|
for (int i = 0; i < v2ItemWriteComplete.Length; i++)
|
|
{
|
|
array[i] = v2ItemWriteComplete[i].ToMirroredV2ItemWriteComplete();
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public static ArchestrAServices.ASBIDataV2Contract.WriteValue ToTrueV2WriteValue(this WriteValueV2 mirroredV2WriteValue)
|
|
{
|
|
ArchestrAServices.ASBIDataV2Contract.WriteValue result = new ArchestrAServices.ASBIDataV2Contract.WriteValue
|
|
{
|
|
ArrayElementIndexSpecified = mirroredV2WriteValue.ArrayElementIndexSpecified
|
|
};
|
|
if (mirroredV2WriteValue.ArrayElementIndexSpecified)
|
|
{
|
|
result.ArrayElementIndex = mirroredV2WriteValue.ArrayElementIndex;
|
|
}
|
|
result.Comment = mirroredV2WriteValue.Comment;
|
|
result.HasQT = mirroredV2WriteValue.HasQT;
|
|
result.Status = mirroredV2WriteValue.Status.ToV2ASBStatus();
|
|
result.TimestampSpecified = mirroredV2WriteValue.TimestampSpecified;
|
|
if (mirroredV2WriteValue.TimestampSpecified)
|
|
{
|
|
result.Timestamp = mirroredV2WriteValue.Timestamp;
|
|
}
|
|
result.Value = mirroredV2WriteValue.Value.ToV2Variant();
|
|
return result;
|
|
}
|
|
|
|
public static ArchestrAServices.ASBIDataV2Contract.WriteValue[] ToTrueV2WriteValueArray(this WriteValueV2[] mirroredV2WriteValue)
|
|
{
|
|
ArchestrAServices.ASBIDataV2Contract.WriteValue[] array = new ArchestrAServices.ASBIDataV2Contract.WriteValue[mirroredV2WriteValue.Length];
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
array[i] = mirroredV2WriteValue[i].ToTrueV2WriteValue();
|
|
}
|
|
return array;
|
|
}
|
|
}
|