Feature flags

Every iso15118 feature flag, what it gates, and how to compile only the message sets and roles your target actually needs.

One crate, so downstream manages one version and cross-protocol types are shared without a semver dance. Everything is additive: every combination compiles, and CI proves it over 129 of them.

Every flag gates real code. A flag that gates nothing is a promise.

default = ["std", "iso2", "iso20", "sdp", "slac", "evcc", "secc", "pnc"]

Environment

FlagEffect
stdAdds std::error::Error implementations and Ipv6Addr helpers. Off by default nowhere — but turning it off is what builds for a microcontroller.

alloc is not a feature; it is a requirement. In bit-packed EXI a decoded string is a run of bit-shifted code points, so it can never borrow from the input and has to be owned.

Roles

FlagEffect
evccThe vehicle-side session driver.
seccThe charger-side session driver.

A role driver needs a protocol to drive: secc on its own compiles and gates nothing, because with no message set there is no flow.

Protocols

FlagEffect
iso2ISO 15118-2:2014 — all 34 body messages, the ordering graph and the charging-profile rule.
iso20Shorthand for all four -20 schema sets.
iso20-commonISO 15118-20 CommonMessages. Implied by each of the four below.
iso20-acAC charging.
iso20-dcDC charging.
iso20-wptWireless power transfer.
iso20-acdpAutomated connection device — the pantograph.

There is no iso20-bpt. Bidirectional power transfer is not a schema set: the BPT_* types live inside AC and DC and are generated with them.

FlagEffect
sdpSECC discovery: the codec and the vehicle-side retry engine.
slacISO 15118-3 frames and the matching state machines for both roles.

Security

FlagEffect
pncThe Plug & Charge signature profile. The hash and the curve are traits, so this pulls in no cryptography.
pnc-rustcryptoA concrete backend for those traits: sha2, p256, p521.

pnc-rustcrypto is the only flag that adds a dependency tree. It is off by default because a controller with a secure element wants the traits and not an implementation of them — but it is what a charging station on a general-purpose CPU, and every test, would otherwise have to write itself.

Integration

FlagEffect
serdeSerialize/Deserialize on the message types and the session state — what -20 pause and resume across a power cycle needs. Protocol and Protocols serialise as their stable short names, so serde, Display and a hand-written match produce one spelling.
tracingStructured events from the protocol engines — which message, in which phase, under which protocol, and which timer ran out. No spans: an engine that never blocks has no interval to open one over, and no payload values, because a SessionID identifies a charging session and a contract certificate identifies a person. Compiles to nothing when off.

Compiling only what you need

A DC-only embedded vehicle controller:

cargo add iso15118 --no-default-features --features evcc,iso20-dc,pnc

gets exactly that. The message sets it does not enable do not exist in the binary — grammar tables included. See Embedded and no_std for what that costs and what else to configure.

The additivity contract

Additive means enabling a feature never removes or changes an item, so two dependents of this crate in one build cannot break each other. CI enforces it with cargo hack check --feature-powerset --depth 2, which is 129 combinations, on every change.

The one place features affect presence rather than content is module gating: secc and evcc only appear when at least one protocol generation is also enabled, because a driver with no message set would be an empty shell. That still only decides when a module appears, never what it contains.