[F34] mxaccess-asb: AddMonitoredItems body uses DataContract field names
Rewrite push_monitored_item_body to emit the DataContract field-suffix names from AsbContracts.cs:940-965 (activeField, bufferedField, itemField, sampleIntervalField, timeDeadbandField, userDataField, valueDeadbandField) under prefix `b` bound to the http://schemas.datacontract.org/2004/07/ArchestrAServices.ASBIDataV2Contract namespace. The <Items> wrapper now declares xmlns:b + xmlns:i. The legacy XmlSerializer property names (<Active>, <Item>, <SampleInterval>, <Buffered>) only matter for the canonical-XML HMAC signing input — that emitter at xml_canonical::emit_monitored_item is unchanged and F28 fixture byte-equality still holds for all 13 ops. On the binary NBFX wire MxDataProvider's DataContractSerializer expects the field-suffix form. Wire-byte type encoding matches the captured fixture (add-monitored-items-request-wire.bin): bool → Bool record, ulong → Zero/One/Chars (XmlConvert decimal text), ushort → Zero/One/Int8/Int16/Int32 (smallest-fit binary). Empty string? + null byte[]? emit as empty elements with no <i:nil> attribute (matching the wire). Field order follows the explicit [DataMember(Order = N)] sequence. Adjacent: ItemIdentity is nested via DataContract field names too — NOT the binary <ASBIData> fast-path, which only kicks in at top-level message body members. Verified live against AVEVA MxDataProvider: AddMonitoredItems now returns 1 status item with error_code=0x0000 (previously 0 items; the silent failure was the deliberate DC-schema mismatch); Publish poll #4 delivers the actual tag value as AsbVariant { type_id: 4, length: 4, payload: [99,0,0,0] } through the F26 stream. Pre-existing clippy::format_collect errors in auth.rs:339,342 and client.rs:952 fixed in passing — they were blocking workspace clippy otherwise. Workspace: 757 → 758 tests, clippy -D warnings clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -335,11 +335,18 @@ impl AsbAuthenticator {
|
||||
out.as_mut_slice(),
|
||||
);
|
||||
if std::env::var("MX_ASB_TRACE_DERIVE").ok().is_some() {
|
||||
use std::fmt::Write as _;
|
||||
eprintln!("asb.derive.crypto_key.len={}", crypto_key.len());
|
||||
let hex: String = crypto_key.iter().map(|b| format!("{b:02X}")).collect();
|
||||
let hex = crypto_key.iter().fold(String::new(), |mut s, b| {
|
||||
let _ = write!(s, "{b:02X}");
|
||||
s
|
||||
});
|
||||
eprintln!("asb.derive.crypto_key.hex={hex}");
|
||||
eprintln!("asb.derive.crypto_key.b64={password_b64}");
|
||||
let aes_hex: String = out.iter().map(|b| format!("{b:02X}")).collect();
|
||||
let aes_hex = out.iter().fold(String::new(), |mut s, b| {
|
||||
let _ = write!(s, "{b:02X}");
|
||||
s
|
||||
});
|
||||
eprintln!("asb.derive.aes_key.hex={aes_hex}");
|
||||
}
|
||||
Ok(out)
|
||||
|
||||
Reference in New Issue
Block a user