ChargeLink

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

StandardCharger session for your DUTRequirementsRunbook
ISO 15118-20Reference 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-2Reference 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 70121Reference 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

ModeCommand shapeSocketsUse
Dry-runevse start --dry-run --protocol P --profile-id IDnoneValidate profile and configuration; prints the activation catalog with the exact listener and vehicle-side commands for every protocol.
Timed listenerevse start --protocol P --profile-id ID --host :: ...UDP 15118, TCPListener that stops after --max-runtime-ms (default 500 ms). Useful for port and firewall checks.
External-EVCC sessionevse start --external-evcc-session ...UDP 15118, TCPThe 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 runtimeas above plus --plant-grpc-endpoint, --requested-power-kw, --target-voltage-v and CHARGELINK_ISO20_RUNTIME_PROFILEUDP 15118, TCP, gRPC clientISO 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

OptionMeaning
--host ::Bind address. Use :: (all IPv6 interfaces) for a DUT on the link, ::1 for a vehicle simulator on the same PC.
--udp-port 15118SDP port. 15118 is the ISO 15118 value; change it only for isolated experiments.
--tcp-port 50118V2GTP port advertised in the SDP response. 0 auto-allocates from 49152–65535.
--advertise-ipv6 fe80::...%NThe link-local address placed in the SDP response. Must be an address of the adapter to your DUT, with its zone index.
--interface-index NWindows interface index of the adapter to your DUT; selects the multicast scope for SDP.
--max-runtime-ms, --heartbeat-interval-msRuntime limit and heartbeat period. With --external-evcc-session use a long limit (for example 1800000 ms) and 1000 ms heartbeats.
--run-idYour run identifier. Without it ChargeLink generates cl-evse-<unix_ms>.
--exi-mode chargelink-exiThe EXI mode. Leave at the default.
--can-backend, --can-channel, --can-bitrateRecorded in the session metadata for DC-CAN profiles; no CAN driver is started.

TLS adapters

SelectionAdapterVersionsClient authenticationUse with
--tls --tls-cert --tls-key --tls-cafile --require-caBuilt-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.3Mutual when --require-ca; mandatory for ISO 15118-20ISO 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 VARWindows SChannelTLS 1.2 onlynoneISO 15118-2 DUTs that require TLS 1.2 with ECDSA through the Windows stack
--tls --external-evcc-dev-tlsBuilt-in, tolerant SNITLS 1.2 onlynoneDevelopment vehicle simulators with relaxed SNI handling; never production
any of the above plus --allow-engineering-tls-identityas selectedas selectedas selectedRequired 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.jsonThe JSON result of the command, as printed.
evse_listener_status.json, evse_runtime_status.json, live_runtime_status.jsonBound ports, advertised address, stop reason, runtime state.
sdp_diagnostics.jsonSDP requests received from your DUT and responses sent.
tls_handshake_diagnostics.jsonNegotiated version, cipher, peer certificate metadata (fingerprints, no bodies).
session_handshake_artifact_gate.jsonRequired versus observed states and messages; status passed, attention_required, failed or not_evaluated.
traces\evse-listener.jsonl, traces\live-v2gtp-frames.jsonlChronological listener events and every V2GTP frame with direction, payload type, length and decode verdict.
protocol\*-live-stack-evidence.jsonProtocol-specific evidence (for example ISO 15118-2 AC/DC, MCS).
manifest.jsonInventory 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.