[M5] tools+fixtures: F28 canonical-XML signing target captured from .NET
Adds `MxAsbClient.Probe --dump-signed-xml` flag that builds five ConnectedRequest shapes (AuthenticateMe, Disconnect, KeepAlive, RegisterItemsRequest, UnregisterItemsRequest) with deterministic field values and prints `AsbSerialization.ToXml(...)` output. The output is exactly what `AsbSystemAuthenticator.Sign` HMACs (`AsbSystemAuthenticator.cs:79`), so the Rust port's canonical-XML emitter must produce byte-identical bytes for HMAC parity. Captured fixtures land under `rust/crates/mxaccess-asb/tests/fixtures/signed-xml/`: - `authenticate-me.xml` — 1000 bytes - `disconnect.xml` — 980 bytes - `keep-alive.xml` — 705 bytes - `register-items.xml` — 1068 bytes - `unregister-items.xml` — 1072 bytes Plus a `README.md` documenting 10 inferred XmlSerializer rules (element name = class name not WrapperName, field order = declaration order not [MessageBodyMember.Order], `[XmlType.Namespace]` on field type causes per-child xmlns redeclaration on the children not the wrapper, `*Specified` pattern controls Xxx emission, CRLF + 2-space indent + utf-16 declaration but UTF-8 bytes fed to HMAC). `.gitattributes` marks the XML fixtures as binary (`*.xml -text`) so neither `core.autocrlf` nor `text` filters can rewrite the byte content — CRLF is part of the canonical form and must survive round-trip through Git untouched. `MxAsbClient.csproj` gains `<InternalsVisibleTo Include="MxAsbClient .Probe" />` so the probe can reach the internal `AsbSerialization` helper without making it public. Workspace: 702 tests pass (no Rust changes — fixtures only). F28 follow-up updated with the captured fixtures + the inferred rules. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+3
-1
@@ -139,7 +139,9 @@ F25 (`mxaccess-asb` IASBIDataV2 client) and F26 (`mxaccess::Session` over `AsbTr
|
|||||||
**Source:** F25 live-bring-up; `AsbSystemAuthenticator.cs:79` + `AsbSerialization.cs:12-48`.
|
**Source:** F25 live-bring-up; `AsbSystemAuthenticator.cs:79` + `AsbSerialization.cs:12-48`.
|
||||||
**Why deferred:** `AsbSystemAuthenticator.Sign` HMACs `Encoding.UTF8.GetBytes(request.ToXml())` — the XML text produced by .NET's `XmlSerializer.Serialize(writer, value)` with `XmlSerializerNamespaces` = `"urn:invensys.schemas"`, then re-parsed via `XDocument.Load` and re-saved to normalise xmlns attribute ordering (xsi before xsd; see `AsbSerialization.cs:36-47`). The HMAC must match the server's recomputation, which uses the same XmlSerializer on the deserialised request — so the Rust port has to produce byte-identical XML. We currently HMAC the NBFX wire bytes of the unsigned envelope, which never matches.
|
**Why deferred:** `AsbSystemAuthenticator.Sign` HMACs `Encoding.UTF8.GetBytes(request.ToXml())` — the XML text produced by .NET's `XmlSerializer.Serialize(writer, value)` with `XmlSerializerNamespaces` = `"urn:invensys.schemas"`, then re-parsed via `XDocument.Load` and re-saved to normalise xmlns attribute ordering (xsi before xsd; see `AsbSerialization.cs:36-47`). The HMAC must match the server's recomputation, which uses the same XmlSerializer on the deserialised request — so the Rust port has to produce byte-identical XML. We currently HMAC the NBFX wire bytes of the unsigned envelope, which never matches.
|
||||||
|
|
||||||
**Resolves when:** A canonical XmlSerializer-compatible emitter lands in `mxaccess-asb` (probably `crates/mxaccess-asb/src/xml_canonical.rs`). Scope per request type: `AuthenticateMe`, `Disconnect`, `KeepAlive`, `RegisterItemsRequest`, `UnregisterItemsRequest`, `ReadRequest`, `WriteBasicRequest`, `PublishWriteCompleteRequest`, `CreateSubscriptionRequest`, `DeleteSubscriptionRequest`, `AddMonitoredItemsRequest`, `DeleteMonitoredItemsRequest`, `PublishRequest`. Each derives its XML form from the `[MessageContract] / [MessageBodyMember(Order = N, Namespace = ...)]` attributes plus per-type `[XmlType(Namespace = ...)]` on `AuthenticationData` / `PublicKey`. Validation: capture .NET probe's `request.ToXml()` output for each operation (instrument `AsbSystemAuthenticator.Sign` with a hex+UTF-8 trace, run `MxAsbClient.Probe`) and assert byte-equal vs the Rust emitter. The `request_xml_utf8` argument to `AsbAuthenticator::sign` is already wired correctly — only the producer is missing. Once HMAC matches, the existing `ConnectionValidator` header path (`mac` + `iv` base64 round-trip) is already validated by the F23 unit tests. **Resolves**: F25 live AuthenticateMe + RegisterItems + every signed operation; M5 DoD bullets 1+2 unblocked.
|
**Resolves when:** A canonical XmlSerializer-compatible emitter lands in `mxaccess-asb` (probably `crates/mxaccess-asb/src/xml_canonical.rs`). Scope per request type: `AuthenticateMe`, `Disconnect`, `KeepAlive`, `RegisterItemsRequest`, `UnregisterItemsRequest`, `ReadRequest`, `WriteBasicRequest`, `PublishWriteCompleteRequest`, `CreateSubscriptionRequest`, `DeleteSubscriptionRequest`, `AddMonitoredItemsRequest`, `DeleteMonitoredItemsRequest`, `PublishRequest`. Each derives its XML form from the `[MessageContract] / [MessageBodyMember(Order = N, Namespace = ...)]` attributes plus per-type `[XmlType(Namespace = ...)]` on `AuthenticationData` / `PublicKey`. The `request_xml_utf8` argument to `AsbAuthenticator::sign` is already wired correctly — only the producer is missing. Once HMAC matches, the existing `ConnectionValidator` header path (`mac` + `iv` base64 round-trip) is already validated by the F23 unit tests. **Resolves**: F25 live AuthenticateMe + RegisterItems + every signed operation; M5 DoD bullets 1+2 unblocked.
|
||||||
|
|
||||||
|
**Captured fixtures (this commit).** `MxAsbClient.Probe --dump-signed-xml` (new flag, 2026-05-05) produces canonical `request.ToXml()` output for the five primary ConnectedRequest shapes; fixtures saved under `rust/crates/mxaccess-asb/tests/fixtures/signed-xml/{authenticate-me,disconnect,keep-alive,register-items,unregister-items}.xml`. Byte sizes pinned: 1000/980/705/1068/1072. The companion `README.md` documents 10 inferred XmlSerializer rules — most importantly: (1) element name = class name (NOT MessageContract.WrapperName), (2) field order = C# declaration order (NOT [MessageBodyMember.Order]), (3) `[XmlType(Namespace=...)]` on a field's type causes per-child xmlns redeclaration on the children, NOT the wrapper element, (4) the `*Specified` pattern controls whether `<Xxx>` is emitted, (5) CRLF line endings + 2-space indent + UTF-8-bytes-of-utf-16-declaration. The Rust emitter has a concrete byte target to converge on.
|
||||||
|
|
||||||
### F29 — Align `mxaccess-asb-nettcp::nbfs` static dictionary ids with canonical `[MC-NBFS]` table
|
### F29 — Align `mxaccess-asb-nettcp::nbfs` static dictionary ids with canonical `[MC-NBFS]` table
|
||||||
**Severity:** P2 — diagnostic-only today; blocks future fault-body decoding.
|
**Severity:** P2 — diagnostic-only today; blocks future fault-body decoding.
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# These fixtures are byte-equal targets for the F28 canonical XML
|
||||||
|
# emitter — `XmlSerializer.Serialize(...)` output that the .NET
|
||||||
|
# reference HMACs in `AsbSystemAuthenticator.Sign`. CRLF line endings
|
||||||
|
# are part of the canonical form (StringWriter default on Windows),
|
||||||
|
# so Git MUST NOT touch them. `-text` marks them as binary so neither
|
||||||
|
# `core.autocrlf` nor `text` filters can rewrite the bytes.
|
||||||
|
*.xml -text
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
# Signed-request XML fixtures
|
||||||
|
|
||||||
|
Canonical `XmlSerializer` output for every `ConnectedRequest` shape that
|
||||||
|
the .NET reference HMACs in `AsbSystemAuthenticator.Sign`
|
||||||
|
(`src/MxAsbClient/AsbSystemAuthenticator.cs:79`). The Rust port's
|
||||||
|
canonical-XML emitter (F28) must produce these exact UTF-8 bytes for
|
||||||
|
the HMAC to match the server's recomputation.
|
||||||
|
|
||||||
|
## Capture procedure
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
dotnet run --project src\MxAsbClient.Probe -c Release -- --dump-signed-xml > capture.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
The probe's `--dump-signed-xml` flag (added 2026-05-05) builds each
|
||||||
|
shape with deterministic field values and prints the output of
|
||||||
|
`AsbSerialization.ToXml(...)` (`src/MxAsbClient/AsbSerialization.cs:12`).
|
||||||
|
|
||||||
|
## Pinned values
|
||||||
|
|
||||||
|
All shapes use the same `ConnectionValidator`:
|
||||||
|
- `ConnectionId = 8cba964a-74c1-ef74-f6aa-761b3540191b`
|
||||||
|
- `MessageNumber = 42`
|
||||||
|
- `MessageAuthenticationCode = AAECAwQFBgcICQoLDA0ODw==` (base64 of bytes 0..15)
|
||||||
|
- `SignatureInitializationVector = EBESExQVFhcYGRobHB0eHw==` (base64 of bytes 16..31)
|
||||||
|
|
||||||
|
`AuthenticateMe` and `Disconnect` use `AuthenticationData` with:
|
||||||
|
- `Data = "deterministic-ciphertext-bytes"` (base64-encoded)
|
||||||
|
- `InitializationVector = "0123456789abcdef"` (base64-encoded)
|
||||||
|
|
||||||
|
`RegisterItemsRequest` uses one `ItemIdentity` with
|
||||||
|
`Type = Name (0)`, `ReferenceType = Absolute (1)`,
|
||||||
|
`Name = "TestChildObject.TestInt"`, `ContextName = ""`.
|
||||||
|
|
||||||
|
`UnregisterItemsRequest` uses one `ItemIdentity` with
|
||||||
|
`Type = Id (1)`, `ReferenceType = Absolute (1)`, `Name = null`,
|
||||||
|
`ContextName = null`, `Id = 0xCAFEBABEDEADBEEF (14627333968688430831)`,
|
||||||
|
`IdSpecified = true`.
|
||||||
|
|
||||||
|
## Observed serialiser behaviour
|
||||||
|
|
||||||
|
These rules were inferred from the captured output and from the .NET
|
||||||
|
source for `XmlSerializer`:
|
||||||
|
|
||||||
|
1. **Element name = class name**, NOT `[MessageContract.WrapperName]`.
|
||||||
|
`XmlSerializer` does not honour WCF's MessageContract attributes.
|
||||||
|
|
||||||
|
2. **Top-element xmlns ordering** (after `<?xml ... ?>`):
|
||||||
|
`xmlns:xsi`, then `xmlns:xsd`, then default `xmlns`.
|
||||||
|
The `AsbSerialization.ToXml` post-process (`AsbSerialization.cs:36-47`)
|
||||||
|
reparses with `XDocument.Load` and reorders to put `xsi` before
|
||||||
|
`xsd` — `XmlSerializer`'s native order is the opposite.
|
||||||
|
|
||||||
|
3. **Field order = C# declaration order** (with inherited fields
|
||||||
|
first), NOT `[MessageBodyMember.Order]`.
|
||||||
|
|
||||||
|
4. **`[XmlType(Namespace = ...)]` on a field's type** triggers an
|
||||||
|
`xmlns="..."` redeclaration on EACH child element of that type's
|
||||||
|
instance, NOT on the wrapper element itself. e.g. inside
|
||||||
|
`<ConnectionValidator>`, every direct child gets
|
||||||
|
`xmlns="http://asb.contracts.data/20111111"`.
|
||||||
|
|
||||||
|
5. **`byte[]` fields** serialise as base64 text content.
|
||||||
|
**`Guid`** as canonical lowercase D-format (`8cba964a-74c1-...`).
|
||||||
|
**`ulong`** as decimal.
|
||||||
|
**`bool`** as `"true"` / `"false"`.
|
||||||
|
|
||||||
|
6. **Null reference-type fields** with `[XmlElement(IsNullable = true)]`
|
||||||
|
produce `<Name xsi:nil="true" xmlns="..." />`.
|
||||||
|
Empty string fields produce a self-closing `<ContextName xmlns="..." />`.
|
||||||
|
|
||||||
|
7. **`*Specified` pattern**: a public bool field named `XxxSpecified` =
|
||||||
|
`true` causes XmlSerializer to emit the corresponding `<Xxx>`
|
||||||
|
element. `IdSpecified = false` (default) → `<Id>` omitted.
|
||||||
|
`IdSpecified = true` → `<Id>` emitted with the int value.
|
||||||
|
The `*Specified` field itself is `[XmlIgnore]` and never emitted.
|
||||||
|
|
||||||
|
8. **Self-closing elements** use ` />` (space before `/>`).
|
||||||
|
|
||||||
|
9. **Indentation**: 2 spaces, `\r\n` line endings, no trailing
|
||||||
|
newline after the closing tag.
|
||||||
|
|
||||||
|
10. **XML declaration**: `<?xml version="1.0" encoding="utf-16"?>` —
|
||||||
|
note `utf-16` even though `AsbSystemAuthenticator.Sign` HMACs
|
||||||
|
`Encoding.UTF8.GetBytes(...)` of this string. The declaration is
|
||||||
|
a static .NET StringWriter default; the actual byte encoding fed
|
||||||
|
to HMAC is UTF-8.
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
- `authenticate-me.xml` — `AuthenticateMe`
|
||||||
|
- `disconnect.xml` — `Disconnect`
|
||||||
|
- `keep-alive.xml` — `KeepAlive`
|
||||||
|
- `register-items.xml` — `RegisterItemsRequest`
|
||||||
|
- `unregister-items.xml` — `UnregisterItemsRequest`
|
||||||
|
|
||||||
|
Each file is the verbatim UTF-8 representation of `request.ToXml()`,
|
||||||
|
with literal `\r\n` line endings preserved. Treat as binary (don't
|
||||||
|
let your editor reformat).
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-16"?>
|
||||||
|
<AuthenticateMe xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:invensys.schemas">
|
||||||
|
<ConnectionValidator>
|
||||||
|
<ConnectionId xmlns="http://asb.contracts.data/20111111">8cba964a-74c1-ef74-f6aa-761b3540191b</ConnectionId>
|
||||||
|
<MessageNumber xmlns="http://asb.contracts.data/20111111">42</MessageNumber>
|
||||||
|
<MessageAuthenticationCode xmlns="http://asb.contracts.data/20111111">AAECAwQFBgcICQoLDA0ODw==</MessageAuthenticationCode>
|
||||||
|
<SignatureInitializationVector xmlns="http://asb.contracts.data/20111111">EBESExQVFhcYGRobHB0eHw==</SignatureInitializationVector>
|
||||||
|
</ConnectionValidator>
|
||||||
|
<ConsumerAuthenticationData>
|
||||||
|
<Data xmlns="http://asb.contracts.data/20111111">ZGV0ZXJtaW5pc3RpYy1jaXBoZXJ0ZXh0LWJ5dGVz</Data>
|
||||||
|
<InitializationVector xmlns="http://asb.contracts.data/20111111">MDEyMzQ1Njc4OWFiY2RlZg==</InitializationVector>
|
||||||
|
</ConsumerAuthenticationData>
|
||||||
|
</AuthenticateMe>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-16"?>
|
||||||
|
<Disconnect xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:invensys.schemas">
|
||||||
|
<ConnectionValidator>
|
||||||
|
<ConnectionId xmlns="http://asb.contracts.data/20111111">8cba964a-74c1-ef74-f6aa-761b3540191b</ConnectionId>
|
||||||
|
<MessageNumber xmlns="http://asb.contracts.data/20111111">42</MessageNumber>
|
||||||
|
<MessageAuthenticationCode xmlns="http://asb.contracts.data/20111111">AAECAwQFBgcICQoLDA0ODw==</MessageAuthenticationCode>
|
||||||
|
<SignatureInitializationVector xmlns="http://asb.contracts.data/20111111">EBESExQVFhcYGRobHB0eHw==</SignatureInitializationVector>
|
||||||
|
</ConnectionValidator>
|
||||||
|
<ConsumerAuthenticationData>
|
||||||
|
<Data xmlns="http://asb.contracts.data/20111111">ZGlzY29ubmVjdC1jaXBoZXJ0ZXh0</Data>
|
||||||
|
<InitializationVector xmlns="http://asb.contracts.data/20111111">MDEyMzQ1Njc4OWFiY2RlZg==</InitializationVector>
|
||||||
|
</ConsumerAuthenticationData>
|
||||||
|
</Disconnect>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-16"?>
|
||||||
|
<KeepAlive xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:invensys.schemas">
|
||||||
|
<ConnectionValidator>
|
||||||
|
<ConnectionId xmlns="http://asb.contracts.data/20111111">8cba964a-74c1-ef74-f6aa-761b3540191b</ConnectionId>
|
||||||
|
<MessageNumber xmlns="http://asb.contracts.data/20111111">42</MessageNumber>
|
||||||
|
<MessageAuthenticationCode xmlns="http://asb.contracts.data/20111111">AAECAwQFBgcICQoLDA0ODw==</MessageAuthenticationCode>
|
||||||
|
<SignatureInitializationVector xmlns="http://asb.contracts.data/20111111">EBESExQVFhcYGRobHB0eHw==</SignatureInitializationVector>
|
||||||
|
</ConnectionValidator>
|
||||||
|
</KeepAlive>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-16"?>
|
||||||
|
<RegisterItemsRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:invensys.schemas">
|
||||||
|
<ConnectionValidator>
|
||||||
|
<ConnectionId xmlns="http://asb.contracts.data/20111111">8cba964a-74c1-ef74-f6aa-761b3540191b</ConnectionId>
|
||||||
|
<MessageNumber xmlns="http://asb.contracts.data/20111111">42</MessageNumber>
|
||||||
|
<MessageAuthenticationCode xmlns="http://asb.contracts.data/20111111">AAECAwQFBgcICQoLDA0ODw==</MessageAuthenticationCode>
|
||||||
|
<SignatureInitializationVector xmlns="http://asb.contracts.data/20111111">EBESExQVFhcYGRobHB0eHw==</SignatureInitializationVector>
|
||||||
|
</ConnectionValidator>
|
||||||
|
<Items>
|
||||||
|
<Type xmlns="urn:data.data.asb.iom:2">0</Type>
|
||||||
|
<ReferenceType xmlns="urn:data.data.asb.iom:2">1</ReferenceType>
|
||||||
|
<Name xmlns="urn:data.data.asb.iom:2">TestChildObject.TestInt</Name>
|
||||||
|
<ContextName xmlns="urn:data.data.asb.iom:2" />
|
||||||
|
</Items>
|
||||||
|
<RequireId>true</RequireId>
|
||||||
|
<RegisterOnly>false</RegisterOnly>
|
||||||
|
</RegisterItemsRequest>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-16"?>
|
||||||
|
<UnregisterItemsRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:invensys.schemas">
|
||||||
|
<ConnectionValidator>
|
||||||
|
<ConnectionId xmlns="http://asb.contracts.data/20111111">8cba964a-74c1-ef74-f6aa-761b3540191b</ConnectionId>
|
||||||
|
<MessageNumber xmlns="http://asb.contracts.data/20111111">42</MessageNumber>
|
||||||
|
<MessageAuthenticationCode xmlns="http://asb.contracts.data/20111111">AAECAwQFBgcICQoLDA0ODw==</MessageAuthenticationCode>
|
||||||
|
<SignatureInitializationVector xmlns="http://asb.contracts.data/20111111">EBESExQVFhcYGRobHB0eHw==</SignatureInitializationVector>
|
||||||
|
</ConnectionValidator>
|
||||||
|
<Items>
|
||||||
|
<Type xmlns="urn:data.data.asb.iom:2">1</Type>
|
||||||
|
<ReferenceType xmlns="urn:data.data.asb.iom:2">1</ReferenceType>
|
||||||
|
<Name xsi:nil="true" xmlns="urn:data.data.asb.iom:2" />
|
||||||
|
<ContextName xsi:nil="true" xmlns="urn:data.data.asb.iom:2" />
|
||||||
|
<Id xmlns="urn:data.data.asb.iom:2">14627333968688430831</Id>
|
||||||
|
</Items>
|
||||||
|
</UnregisterItemsRequest>
|
||||||
@@ -53,6 +53,93 @@ if (args.Any(arg => arg.Equals("--dump-register-payload", StringComparison.Ordin
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// `--dump-signed-xml` produces deterministic .NET `XmlSerializer` output
|
||||||
|
// for each ConnectedRequest type that goes through `AsbSystemAuthenticator
|
||||||
|
// .Sign` (`AsbSystemAuthenticator.cs:79`). The output is exactly what
|
||||||
|
// the .NET HMAC computation runs over, so the Rust port's canonical-XML
|
||||||
|
// emitter (F28) needs to produce byte-identical bytes for every type
|
||||||
|
// listed here. Connection IDs, MACs, IVs, and message numbers are pinned
|
||||||
|
// to deterministic values so the dump is reproducible.
|
||||||
|
if (args.Any(arg => arg.Equals("--dump-signed-xml", StringComparison.OrdinalIgnoreCase)))
|
||||||
|
{
|
||||||
|
Guid connectionId = Guid.Parse("8cba964a-74c1-ef74-f6aa-761b3540191b");
|
||||||
|
byte[] mac = Convert.FromBase64String("AAECAwQFBgcICQoLDA0ODw==");
|
||||||
|
byte[] sigIv = Convert.FromBase64String("EBESExQVFhcYGRobHB0eHw==");
|
||||||
|
|
||||||
|
void Dump(string label, object request)
|
||||||
|
{
|
||||||
|
string xml = AsbSerialization.ToXml(request);
|
||||||
|
byte[] xmlBytes = System.Text.Encoding.UTF8.GetBytes(xml);
|
||||||
|
Console.WriteLine($"--- {label} ({xmlBytes.Length} UTF-8 bytes) ---");
|
||||||
|
Console.WriteLine(xml);
|
||||||
|
Console.WriteLine($"--- {label} (base64) ---");
|
||||||
|
Console.WriteLine(Convert.ToBase64String(xmlBytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
ConnectionValidator validator = new()
|
||||||
|
{
|
||||||
|
ConnectionId = connectionId,
|
||||||
|
MessageNumber = 42,
|
||||||
|
MessageAuthenticationCode = mac,
|
||||||
|
SignatureInitializationVector = sigIv,
|
||||||
|
};
|
||||||
|
|
||||||
|
AuthenticateMe authMe = new()
|
||||||
|
{
|
||||||
|
ConnectionValidator = validator,
|
||||||
|
ConsumerAuthenticationData = new AuthenticationData
|
||||||
|
{
|
||||||
|
Data = Convert.FromBase64String("ZGV0ZXJtaW5pc3RpYy1jaXBoZXJ0ZXh0LWJ5dGVz"),
|
||||||
|
InitializationVector = Convert.FromBase64String("MDEyMzQ1Njc4OWFiY2RlZg=="),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
Dump("AuthenticateMe", authMe);
|
||||||
|
|
||||||
|
Disconnect disconnect = new()
|
||||||
|
{
|
||||||
|
ConnectionValidator = validator,
|
||||||
|
ConsumerAuthenticationData = new AuthenticationData
|
||||||
|
{
|
||||||
|
Data = Convert.FromBase64String("ZGlzY29ubmVjdC1jaXBoZXJ0ZXh0"),
|
||||||
|
InitializationVector = Convert.FromBase64String("MDEyMzQ1Njc4OWFiY2RlZg=="),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
Dump("Disconnect", disconnect);
|
||||||
|
|
||||||
|
KeepAlive keepAlive = new() { ConnectionValidator = validator };
|
||||||
|
Dump("KeepAlive", keepAlive);
|
||||||
|
|
||||||
|
RegisterItemsRequest registerDump = new()
|
||||||
|
{
|
||||||
|
ConnectionValidator = validator,
|
||||||
|
Items = [new ItemIdentity
|
||||||
|
{
|
||||||
|
Type = (ushort)ItemIdentityType.Name,
|
||||||
|
ReferenceType = (ushort)ItemReferenceType.Absolute,
|
||||||
|
Name = "TestChildObject.TestInt",
|
||||||
|
ContextName = string.Empty,
|
||||||
|
}],
|
||||||
|
RequireId = true,
|
||||||
|
RegisterOnly = false,
|
||||||
|
};
|
||||||
|
Dump("RegisterItemsRequest", registerDump);
|
||||||
|
|
||||||
|
UnregisterItemsRequest unregisterDump = new()
|
||||||
|
{
|
||||||
|
ConnectionValidator = validator,
|
||||||
|
Items = [new ItemIdentity
|
||||||
|
{
|
||||||
|
Type = (ushort)ItemIdentityType.Id,
|
||||||
|
ReferenceType = (ushort)ItemReferenceType.Absolute,
|
||||||
|
Id = 0xCAFE_BABE_DEAD_BEEFul,
|
||||||
|
IdSpecified = true,
|
||||||
|
}],
|
||||||
|
};
|
||||||
|
Dump("UnregisterItemsRequest", unregisterDump);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (probeConnectFailure)
|
if (probeConnectFailure)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -14,4 +14,9 @@
|
|||||||
<PackageReference Include="System.ServiceModel.Primitives" Version="10.0.652802" />
|
<PackageReference Include="System.ServiceModel.Primitives" Version="10.0.652802" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<InternalsVisibleTo Include="MxAsbClient.Probe" />
|
||||||
|
<InternalsVisibleTo Include="MxAsbClient.Tests" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
Reference in New Issue
Block a user