A Rust implementation of the UDS diagnostic stack — ISO 14229 and ISO 13400 — built as layers that each own exactly one standard.
no_std and allocation-free at the core, so the same crates build for a
bare-metal ECU and for a host-side diagnostic tool.
Each crate is scoped by which standard specifies its behaviour, not by convenience. That rule is what keeps the layering honest: a crate that would have to read another standard to do its job has the wrong boundary.
| Crate | Standard | What it owns |
|---|---|---|
uds_protocol |
ISO 14229-1 (format) | The message format. Encodes and decodes UDS requests and responses; no dispatch, no policy, no session state. |
uds_session |
ISO 14229-2 | The session layer, as a sans-io state machine. Never learns its transport, and never reads a clock. |
uds_services |
ISO 14229-1 (behaviour) | Everything in ISO 14229-1 that is not the format: typed service dispatch over caller-defined identifiers, and the clause 8.7 response rules. Declares the transport seam and implements no transport. |
simple_doip |
ISO 13400-2 | DoIP. A no_std, zero-copy protocol core; a no_std tester and entity over edge-nal sockets; and an optional async client and server. |
uds_on_ip |
ISO 14229-5 | The UDSonIP application profile, and the mapping of UDS onto DoIP. |
ISO 14229-1 is the one document too large for that rule to settle on its own,
so it is the stack's only split: uds_protocol owns its format, uds_services
owns everything else in it. Every other standard is owned whole.
The wire codec these share, automotive-wire-codec, is released
separately: it serves protocols outside this stack as well.
Two rules govern how they fit together. ISO 14229-5 decides when something happens and ISO 13400-2 performs what — so a crate that must know whether to act has acquired the requirement, whether or not it also performs it. And each seam is declared by the crate that calls through it, which is why every Cargo edge runs from implementor to declarer.
Under active development, and honest about it: the crates are at different maturities.
| Crate | Where it stands |
|---|---|
uds_protocol |
Implemented. |
simple_doip |
Implemented. |
uds_session |
Pre-implementation: the public surface is complete, the bodies are todo!(). |
uds_on_ip |
Alpha: the API shape is settled, the transport bodies are todo!(). |
uds_services |
Pre-implementation. |
The five crates release in lockstep: one version for the whole stack, every
crate published at it together, one v<version> tag. The stack is at 0.7.0,
and 0.7.0 is not released yet; it will be once the stack's functionality has
been verified. Until then, the last releases on crates.io are the standalone
ones from before the consolidation:
uds_protocol 0.1.0 and
simple_doip 0.6.0.
Requirements and architecture are authored as a
sphinx-needs set under docs/,
and published at https://luminartech.github.io/uds_stack/, rebuilt from
main on every push. They are the specification the code is written
against, not a description written after it.
API documentation is generated by rustdoc and published on docs.rs per crate.
The two are joined by need IDs, which appear in Implements: and Verifies:
annotations in the source.
Some crates still carry an ARCHITECTURE.md. Those are provisional and are
being replaced by the sphinx-needs set; where the two disagree, docs/ wins.
$ cargo build --workspace
$ cargo test --workspace --all-featuresThe no_std crates are checked against a bare-metal target, which a host build
cannot do for you — a workspace lockfile unifies features across members, so a
std dependency enabled by one crate can otherwise reach a no_std sibling
unnoticed:
$ just embeddedThe documentation set has its own toolchain, managed by uv and pinned:
$ uv sync --frozen
$ just doctor # checks for plantuml, the one tool uv cannot pin
$ just check-docs # policy checks, tool self-tests, needs build
$ just html # browsable outputjust --list shows everything. just check-all is the full gate.
See CONTRIBUTING.md. Security issues go through SECURITY.md, not the public issue tracker.
Dual licensed under MIT or Apache-2.0, at your option. Apache-2.0 carries an express patent grant, which matters for an automotive protocol; MIT is here because a downstream that cannot take Apache-2.0 should still have a path.
Neither licence grants any right in the ISO standards this code implements, which remain ISO's. The requirement set cites clauses so that a reader holding the standard can check the transcription; it does not reproduce them. You need your own copy of ISO 14229 and ISO 13400 to verify conformance.