Add legacy libmbus normalized XML output format - #108
Merged
Conversation
- Walk the VIFE extension chain from the correct offset when the plaintext VIF precedes the VIFE bytes (plaintext-before-extension). Records that previously aborted with InvalidValueInformation now parse. - Decode a 6-byte data field carrying a date/time VIF (0x6D) as a type I (CP48) timestamp instead of type F, matching EN 13757-3.
Add an "xml" format to serialize_mbus_data that reproduces libmbus's mbus_frame_data_xml_normalized() output byte for byte, as a drop-in for consumers of the rSCADA/libmbus normalized XML. - New src/rscada_xml.rs renders the SlaveInformation header and normalized DataRecords (VIF unit/quantity normalization table, medium and product name lookups, BCD/integer/real/date/string value decoding, XML escaping), matching libmbus semantics including the pre-LSB-first binary formatting and 20xx-century date handling used to generate the reference corpus. - Wire the format into serialize_mbus_data and expose it through the CLI (-t xml) and the Python bindings' accepted-format list. The wasm binding passes the format through unchanged.
Diff the "xml" output against the reference .norm.xml files in tests/rscada/test-frames. Frames that do not yet match libmbus are listed in KNOWN_MISMATCHES; the test fails if one starts matching so the list can only shrink. 61/73 frames match with std alone, 69/73 with plaintext-before-extension enabled.
- README: list xml among the output formats, add CLI and library usage examples, and add it to the format reference table and CLI help block. - CHANGELOG: note the new xml format and the two parser fixes it surfaced.
- Add a "Parse to XML" button to the web app, wired to the xml format with xml syntax highlighting and an .xml download. - Rebuild the bundled wasm artifacts (wasm-pack --target web) so the parser in the browser knows the new xml format, and bump the cache-buster query strings to 0.2.0 so browsers load the refreshed build.
# Conflicts: # docs/m_bus_parser_wasm_pack_bg.wasm
xml is now a supported format, so the unsupported-format test uses a genuinely invalid name and the render test asserts xml produces the libmbus <MBusData> document.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an
xmloutput format that reproduces libmbus's (rSCADA)mbus_frame_data_xml_normalized()output byte for byte, so consumers of thelegacy normalized XML can use this parser as a drop-in, and so the parser can
be diffed against the reference
.norm.xmlcorpus intests/rscada.The format is available everywhere
serialize_mbus_datais:serialize_mbus_data(hex, "xml", None)m-bus-parser-cli parse -d "..." -t xmlparse(data, "xml")What's included
src/rscada_xml.rs— renders theSlaveInformationheader andnormalized
DataRecords: VIF unit/quantity normalization table, medium andproduct-name lookups, BCD/integer/real/date/string value decoding, and XML
escaping. Matches libmbus semantics including the pre-LSB-first binary
formatting and 20xx-century date handling used when the reference corpus was
generated.
tests/rscada_xml.rs) diffing thexmloutput against thereference files. Frames that don't yet match are tracked in
KNOWN_MISMATCHES; the test fails if one starts matching, so the list canonly shrink.
VIF precedes the VIFE bytes (
plaintext-before-extension); records thatpreviously aborted with
InvalidValueInformationnow parse.0x6D) as type I (CP48) instead of type F,per EN 13757-3.
parser knows the format.
Parity
Byte-for-byte matches against the reference corpus:
stdalonestd,plaintext-before-extensionThe remaining 4 mismatches diverge because the parser rejects BCD data with
non-decimal nibbles (the
Fhsign marker and manufacturer error markers likeDDh) and aborts the record stream, whereas libmbus decodes them leniently.Verification
cargo fmt --check,cargo clippy -D warnings, andcargo testall passacross no-features /
std/plaintext-before-extension..norm.xml.m_bus_parse(frame, "xml")(the function the web buttoncalls) also returns byte-identical output, verified via a Node-target build.