ChargeLink as Charger
In the charger role ChargeLink is the charger-side communication controller (EVSE/SECC), and your device under test (DUT) is the vehicle: a vehicle, an EVCC, an on-board charger or a vehicle simulator. For ISO 15118 and DIN 70121, ChargeLink advertises itself through SDP on UDP 15118, accepts your DUT's TCP connection (plain or TLS), frames V2GTP, decodes EXI and answers the protocol sequence. This page explains the sessions per standard, the listener modes, the TLS adapters, the lifecycle files and the day-to-day commands. Protocol-specific steps are in the runbooks.
The charger session per standard
| Standard | Charger session for your DUT | Requirements | Runbook |
|---|---|---|---|
| ISO 15118-20 | Reference responder: evse start --external-evcc-session with profile iso15118_20_dc (DC EIM) or iso15118_20_ac_eim (AC EIM). Plant-coupled DC EIM charger: every response follows the live session and the plant model, in Scheduled and Dynamic control mode as offered by the runtime profile. | TLS 1.3 with mutual authentication. The plant-coupled charger runs on the NI VeriStand bench. | ISO 15118-20 |
| MCS (ISO 15118-20 over 10BASE-T1S) | Plant-coupled charger with the MCS energy service, Scheduled control mode. In this release, the MCS charger connects to a ChargeLink vehicle: the CE/ID connector signals travel on the coupler link, a ChargeLink interface. | NI VeriStand bench, a USB 10BASE-T1S adapter, TLS 1.3 mutual. | MCS |
| ISO 15118-2 | Reference responder for DC EIM and AC EIM, plain or TLS. The plant-coupled DC EIM charger (profile iso15118_2_dc_eim) needs --plant-grpc-endpoint; in this release, it connects to a ChargeLink vehicle. | Optional TLS: Windows SChannel (TLS 1.2) or the built-in TLS adapter (TLS 1.2/1.3). | ISO 15118-2 |
| DIN 70121 | Reference responder for DC; it answers requests that match the reference request encodings. The plant-coupled DC charger (profile din70121_dc) needs --plant-grpc-endpoint; in this release, it connects to a ChargeLink vehicle. | No TLS (DIN 70121 has none). | DIN 70121 |
| IEC 61851-23/-24 System A (CHAdeMO) | Station role with a simulated plant (dc-can chademo evse). In this release, the station connects to a ChargeLink EV: the station tells the EV over the plant link which case to run. | Virtual CAN hub over TCP or a Kvaser CANlib channel; plant link over TCP. | CHAdeMO |
To run this charger against ChargeLink as vehicle instead of a DUT, see Self-test without a device under test.
Listener modes
| Mode | Command shape | Sockets | Use |
|---|---|---|---|
| Dry-run | evse start --dry-run --protocol P --profile-id ID | none | Validate profile and configuration; prints the activation catalog with the exact listener and vehicle-side commands for every protocol. |
| Timed listener | evse start --protocol P --profile-id ID --host :: ... | UDP 15118, TCP | Listener that stops after --max-runtime-ms (default 500 ms). Useful for port and firewall checks. |
| External-EVCC session | evse start --external-evcc-session ... | UDP 15118, TCP | The session for your DUT. Keeps listening until the runtime limit or an operator stop; serves the reference responses (or the plant-coupled runtime for ISO 15118-20 DC EIM). |
| Plant-coupled runtime | as above plus --plant-grpc-endpoint, --requested-power-kw, --target-voltage-v and CHARGELINK_ISO20_RUNTIME_PROFILE | UDP 15118, TCP, gRPC client | ISO 15118-20 DC EIM with dynamic responses; started by the VeriStand owner host. |
--foreground is accepted and only recorded; the listener always runs in the foreground of the shell that started it. Use a dedicated PowerShell window per listener and stop it with evse stop from another window or Ctrl+C.
Network options
| Option | Meaning |
|---|---|
--host :: | Bind address. Use :: (all IPv6 interfaces) for a DUT on the link, ::1 for a vehicle simulator on the same PC. |
--udp-port 15118 | SDP port. 15118 is the ISO 15118 value; change it only for isolated experiments. |
--tcp-port 50118 | V2GTP port advertised in the SDP response. 0 auto-allocates from 49152–65535. |
--advertise-ipv6 fe80::...%N | The link-local address placed in the SDP response. Must be an address of the adapter to your DUT, with its zone index. |
--interface-index N | Windows interface index of the adapter to your DUT; selects the multicast scope for SDP. |
--max-runtime-ms, --heartbeat-interval-ms | Runtime limit and heartbeat period. With --external-evcc-session use a long limit (for example 1800000 ms) and 1000 ms heartbeats. |
--run-id | Your run identifier. Without it ChargeLink generates cl-evse-<unix_ms>. |
--exi-mode chargelink-exi | The EXI mode. Leave at the default. |
--can-backend, --can-channel, --can-bitrate | Recorded in the session metadata for DC-CAN profiles; no CAN driver is started. |
TLS adapters
| Selection | Adapter | Versions | Client authentication | Use with |
|---|---|---|---|---|
--tls --tls-cert --tls-key --tls-cafile --require-ca | Built-in (default) | ISO 15118-20: TLS 1.3 only with the named groups secp521r1 and x448 and the ISO 15118-20 cipher suites (--iso20-curve-profile, --allow-legacy-tls-named-groups); other protocols: 1.2 and 1.3 | Mutual when --require-ca; mandatory for ISO 15118-20 | ISO 15118-20; ISO 15118-2 DUTs that support TLS 1.3, or TLS 1.2 without the Windows stack |
--tls --external-evcc-windows-tls --tls-pfx F --tls-pfx-password-env VAR | Windows SChannel | TLS 1.2 only | none | ISO 15118-2 DUTs that require TLS 1.2 with ECDSA through the Windows stack |
--tls --external-evcc-dev-tls | Built-in, tolerant SNI | TLS 1.2 only | none | Development vehicle simulators with relaxed SNI handling; never production |
any of the above plus --allow-engineering-tls-identity | as selected | as selected | as selected | Required when the server identity comes from evse tls-material-init (subject marked "ENGINEERING ONLY"); without it the listener refuses to start. Development and test only. |
PEM aliases: --cert, --key, --ca; --tls-pkcs12 for --tls-pfx. Passwords belong in --tls-pfx-password-env, never on the command line. The complete certificate requirements are in TLS and PKI.
Lifecycle and role locks
Every listener owns a session directory under the runtime root and an active role lock:
<runtime-root>\sessions\<run-id>\state.json protocol, profile, host, ports, status
<runtime-root>\sessions\<run-id>\pid.json process id and executable
<runtime-root>\sessions\<run-id>\lock.json session lock, stale_after_ms 300000
<runtime-root>\sessions\<run-id>\heartbeat.json sequence and last heartbeat time
<runtime-root>\sessions\<run-id>\lifecycle.log starting / running / stopped lines
<runtime-root>\sessions\<run-id>\stop.flag written by evse stop
<runtime-root>\active\evse.lock.json one EVSE at a time per runtime root
Only one charger session can be live per runtime root. A second evse start fails with CL-RUNTIME-001 while the lock is held. A session becomes stale when its PID is gone or the heartbeat is older than 300 s; stale sessions are inspectable but do not block a new start after recovery.
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse status # the active session (or --run-id X)
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse list-state
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json runtime list --role evse
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json runtime inspect --run-id <RUN_ID>
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json runtime locks
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse stop --run-id <RUN_ID> # writes stop.flag; the listener exits at its next heartbeat
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json runtime recover --stale-only --dry-run
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json runtime recover --stale-only # release locks of dead sessions
Never delete runtime files by hand while a listener is running. evse live-preflight --recover-stale performs the same recovery as part of the preflight.
Evidence produced by a listener
| File (under the run directory) | Content |
|---|---|
command_result.json | The JSON result of the command, as printed. |
evse_listener_status.json, evse_runtime_status.json, live_runtime_status.json | Bound ports, advertised address, stop reason, runtime state. |
sdp_diagnostics.json | SDP requests received from your DUT and responses sent. |
tls_handshake_diagnostics.json | Negotiated version, cipher, peer certificate metadata (fingerprints, no bodies). |
session_handshake_artifact_gate.json | Required versus observed states and messages; status passed, attention_required, failed or not_evaluated. |
traces\evse-listener.jsonl, traces\live-v2gtp-frames.jsonl | Chronological listener events and every V2GTP frame with direction, payload type, length and decode verdict. |
protocol\*-live-stack-evidence.json | Protocol-specific evidence (for example ISO 15118-2 AC/DC, MCS). |
manifest.json | Inventory with SHA-256 per file and redaction class. |
Evaluate a run with evse live-closure-gate --run-id X --source external-evcc --require-sdp --require-tcp-peer --require-tls --require-v2gtp --require-exi. Each --require-* flag turns a missing observation into a failure of the closure check. How to read the run folder is in Trace, Evidence and Reports.
Diagnostic runs without a DUT
These commands write evidence from built-in reference data and are useful for regression and support cases:
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse listener-policy
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse external-evcc-session-policy # the activation catalog for every protocol
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse iso20-setup-path --write-artifacts
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse iso20-dc-charge-loop-path --write-artifacts
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse iso20-completion-pass --write-artifacts
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse iso2-setup-path --write-artifacts
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse din70121-dc-setup-path --write-artifacts
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse tls-pki-doctor --tls --tls-cert C --tls-key K --tls-cafile CA --require-ca
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse live-closure-plan --advertise-ipv6 $Advertise --interface-index $IfIndex
Safety rule for physical benches
The reference-responder sessions never command a power stage. The plant-coupled session commands a simulated plant through the VeriStand owner host, whose safe start-up profile keeps the contactor open and current at zero until the protocol and the safety inputs (Safety.InterlockClosed, Safety.IsolationValid, Safety.EmergencyStop) permit closure, and which fails safe on watchdog expiry. Any coupling of your DUT to real power electronics is outside the software and requires its own safety design.

