ChargeLink Native

ISO 15118-20 Operator Runbook

ISO 15118-20 is the second-generation high-level communication protocol for CCS. ChargeLink implements the SupportedAppProtocol, CommonMessages and DC namespaces with a native EXI codec, and runs the full DC EIM session (16 request/response pairs from SupportedAppProtocol to SessionStop) between two machines, with the ChargeLink SECC on one PC and the ChargeLink EVCC on a second PC.

Before you start

  • TLS 1.3 with mutual authentication is mandatory. The listener rejects plaintext, TLS 1.2 and connections without a verified client certificate before the SupportedAppProtocol exchange, and it negotiates only the named groups secp521r1 and x448 and the cipher suites TLS_AES_256_GCM_SHA384 and TLS_CHACHA20_POLY1305_SHA256 (see TLS, PKI and Plug & Charge). You need a V2G root CA, a SECC certificate chain and key for the EVSE, and a vehicle certificate chain and key for the EVCC, all under the same root. Engineering material can be generated with evse tls-material-init (a fresh Annex B-shaped chain on every run, accepted by evse start only with --allow-engineering-tls-identity); production material must follow ISO 15118-20 Annex B (ECDSA P-521, SHA-512). See TLS, PKI and Plug & Charge.
  • TLS named groups. The handshake offers and accepts only secp521r1 and x448, so a peer that offers only other groups (for example P-256 or X25519) is refused before any V2G message. --allow-legacy-tls-named-groups adds secp256r1 after them for engineering interop with such peers.
  • The EVSE identity in the certificate is validated as an Annex B chain to the V2G root. The DNS name is SNI only; the EVCC default --tls-server-name chargelink-secc.local does not need to match a SAN.
  • Complete the preflight: interface index, link-local address, ports, clock.
$CL   = 'C:\ChargeLink\0.5.0-rc2\pc1\bin\chargelink.exe'
$Data = 'C:\ChargeLinkData'
$IfIndex   = <INTERFACE_INDEX>
$Advertise = 'fe80::<ADDRESS>%' + $IfIndex
$Pki       = "$Data\pki"

1. Choose a profile

Profile IDRoleModeLane
iso15118_20_dcEVSEDC EIMReference responder; with --plant-grpc-endpoint the plant-coupled runtime lane
abb_iso20_dc_bpt_eimEVSEDC BPT EIMReference responder (BPT service discovery/detail vectors)
abb_iso20_ac_eim_realistic_continuousEVSEAC EIMReference responder (AC vectors)
abb_iso20_ac_bpt_eimEVSEAC BPT EIMReference responder
abb_iso20_dc_pnc_tls, abb_iso20_ac_pnc_tls, abb_iso20_dc_bpt_pnc_tls, abb_iso20_ac_bpt_pnc_tlsEVSEPnCReference responder; PnC is advertised only when a PnC fixture manifest is configured (see TLS page)
iso15118_20_dc_evcc_referenceEVCCDC EIMLive session (EV case files from the package required)
iso15118_20_ac_evcc_reference, *_bpt_*, *_pnc_*, iso15118_20_dc_evcc_premium_800v, iso15118_20_dc_evcc_cold_demoEVCCvariousDry-run, loopback and deterministic simulation only

AC, DC and BPT are selected from the profile ID tokens (ac, dc, bpt). The installed profile list is authoritative.

The DC EIM session at a glance

ISO 15118-20 DC EIM session sequence between EVCC and ChargeLink SECC EVCC (vehicle) ChargeLink SECC Transport Setup and authorization (common namespace) Service and schedule DC energy transfer Stop SDP request (UDP 15118, ff02::1) → response: address, port, security TCP connect → TLS 1.3 handshake, mutual authentication (Annex B chains) SupportedAppProtocolReq → Res (urn:iso:std:iso:15118:-20:DC selected) SessionSetupReq (EVCCID) → Res (EVSEID, SessionID) AuthorizationSetupReq → Res (EIM) · AuthorizationReq → Res budget 1500 ms per response; V2G_EVCC_Msg_Timeout enforced on the vehicle side ServiceDiscoveryReq → Res (DC, service 2) · ServiceDetailReq → Res (parameter set 1) ServiceSelectionReq → Res · DC_ChargeParameterDiscoveryReq → Res (EV / EVSE limits) ScheduleExchangeReq (Scheduled mode) → Res (schedule tuple, 60 s in the reference profile) DC_CableCheckReq → Res Ongoing… Finished (simulated by the plant provider; 38 s deadline) DC_PreChargeReq (target voltage) → Res (present voltage within tolerance) PowerDeliveryReq (Start) → Res · contactor closes in the plant DC_ChargeLoopReq (target current or voltage) → Res (present V/I, limits) · repeated, 250 ms budget orange: values come from the plant model in the plant‑coupled lane; reference vectors otherwise PowerDeliveryReq (Stop) → Res · DC_WeldingDetectionReq → Res · SessionStopReq → Res · TCP held ≥ 5 s
The 16 request/response pairs of an ISO 15118-20 DC EIM session as ChargeLink runs them, with the response budgets it enforces.

2. EVSE: reference-responder session for an external EVCC

Use this lane to validate a vehicle or EVCC simulator against ChargeLink discovery, TLS 1.3, V2GTP framing and message sequencing. Every request is decoded and answered with the validated reference response for that message.

$Run = "iso20-dc-$(Get-Date -Format yyyyMMdd-HHmmss)"

chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse live-preflight --source external-evcc `
  --protocol iso15118-20 --profile-id iso15118_20_dc `
  --host '::' --tcp-port 50118 --udp-port 15118 `
  --advertise-ipv6 $Advertise --interface-index $IfIndex `
  --tls --tls-cert "$Pki\secc-chain.pem" --tls-key "$Pki\secc-key.pem" --tls-cafile "$Pki\v2g-root-ca.pem" --require-ca `
  --recover-stale

chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse start --external-evcc-session --run-id $Run `
  --protocol iso15118-20 --profile-id iso15118_20_dc `
  --host '::' --tcp-port 50118 --udp-port 15118 `
  --advertise-ipv6 $Advertise --interface-index $IfIndex `
  --tls --tls-cert "$Pki\secc-chain.pem" --tls-key "$Pki\secc-key.pem" --tls-cafile "$Pki\v2g-root-ca.pem" --require-ca `
  --max-runtime-ms 1800000 --heartbeat-interval-ms 1000

Notes:

  • --external-evcc-session keeps the listener open until --max-runtime-ms elapses or an operator stop arrives, and defaults UDP to 15118.
  • --tcp-port 0 auto-allocates a port from 49152–65535; the bound port is reported in the JSON result and in evse_listener_status.json.
  • Do not use --external-evcc-windows-tls or --external-evcc-dev-tls for ISO 15118-20: both select TLS 1.2, which the ISO 15118-20 admission check rejects.
  • The response budget is enforced: ChargeLoop 250 ms, ServiceDetail 4500 ms, other messages 1500 ms, CableCheck 38 s. Exceeding a budget is recorded as a finding.

In a second window:

chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse status --run-id $Run
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse list-state --run-id $Run
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json runtime inspect --run-id $Run

3. EVSE: plant-coupled runtime session (DC EIM)

This is the lane in which ChargeLink encodes every ISO 15118-20 response from the live session state and from plant measurements, and drives PreCharge, PowerDelivery and the DC charge loop against the vehicle's targets. It requires:

  • profile iso15118_20_dc, TLS 1.3 mutual (--require-ca);
  • --plant-grpc-endpoint: the ChargeLink gRPC endpoint to which the plant provider (the VeriStand owner host) is bound;
  • explicit --requested-power-kw and --target-voltage-v (zero means unset and is rejected);
  • the environment variable CHARGELINK_ISO20_RUNTIME_PROFILE pointing to a runtime profile JSON (schema chargelink.iso15118_20.dc_eim.runtime_profile.v1).

On the NI VeriStand bench, the owner host started by Start-SeccSession.ps1 runs this lane for you with the package's runtime profile; operators do not type this command. The runtime profile fields are described on the NI VeriStand Bench page. Control mode is scheduled only; dynamic is rejected by the runtime.

4. EVCC: probe a real charger (transport and TLS only)

Before attempting a session against a third-party SECC, prove TCP reachability and the mutual TLS 1.3 handshake. The probe deliberately has no session arguments:

chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evcc tls-handshake-probe `
  --protocol iso15118-20 --profile-id iso15118_20_dc_evcc_reference `
  --peer-ipv6 'fe80::<SECC_ADDRESS>%' + $IfIndex --tcp-port 50118 `
  --tls --tls-cert "$Pki\vehicle-chain.pem" --tls-key "$Pki\vehicle-key.pem" --tls-cafile "$Pki\v2g-root-ca.pem" --require-ca

Judge the result on the reported status, not on the exit code: the exit code says whether the probe ran, the status says what the SECC decided. The link-local zone index must be this machine's interface index, not the peer's.

5. EVCC: full DC EIM session against a SECC

The live EVCC session refuses to run with hidden defaults: two files delivered in the package's pc2\cases folder must be named through environment variables before evcc activate-profile is started. The EV values in them are test values, not a vehicle implementation.

VariableFilePurpose
CHARGELINK_ISO20_LIVE_SEMANTIC_CASEEV case JSON, for example pc2\cases\nominal.jsonThe vehicle's identity (EVCCID with Annex C check digit) and electrical parameters: present, precharge and target voltage, target current, power, EV limits, tolerances, safe limits, precharge and charge-loop timeouts.
CHARGELINK_ISO20_FULL_WIRE_SESSION_MANIFESTfull-wire session manifest, pc2\cases\full-wire-session-manifest.jsonReference encodings against which the EVCC checks its own session. Use the delivered manifest.
$env:CHARGELINK_ISO20_LIVE_SEMANTIC_CASE        = 'C:\ChargeLink\0.5.0-rc2\pc2\cases\nominal.json'
$env:CHARGELINK_ISO20_FULL_WIRE_SESSION_MANIFEST = 'C:\ChargeLink\0.5.0-rc2\pc2\cases\full-wire-session-manifest.json'

# standard flow: SDP discovery on the bench adapter
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evcc activate-profile `
  --protocol iso15118-20 --profile-id iso15118_20_dc_evcc_reference `
  --use-sdp --interface-index $IfIndex --tcp-port 50118 --exi-mode chargelink-exi `
  --tls --tls-cert "$Pki\vehicle-chain.pem" --tls-key "$Pki\vehicle-key.pem" --tls-cafile "$Pki\v2g-root-ca.pem" --require-ca `
  --max-steps 14 --requested-power-kw 80

# fallback for transport isolation: direct TCP (no --use-sdp, explicit peer and port)
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evcc activate-profile `
  --protocol iso15118-20 --profile-id iso15118_20_dc_evcc_reference `
  --peer-ipv6 ('fe80::<SECC_ADDRESS>%' + $IfIndex) --tcp-port 50118 --probe-peer --exi-mode chargelink-exi `
  --tls --tls-cert "$Pki\vehicle-chain.pem" --tls-key "$Pki\vehicle-key.pem" --tls-cafile "$Pki\v2g-root-ca.pem" --require-ca `
  --max-steps 14 --requested-power-kw 80

Every response wait is bounded by the ISO 15118-20 V2G_EVCC_Msg_Timeout for that message type. The session stays inside the schedule it negotiated; the reference runtime profile offers 60 s. The package's runtime profile offers one 60 s charging schedule; schedule renegotiation is answered when the EV requests it (the SECC never triggers it), so a longer session needs an EV that renegotiates or a profile with a longer schedule.

6. Stop and preserve evidence

chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse stop --run-id $Run
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json artifacts inspect --run-id $Run
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json artifacts integrity --run-id $Run
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse live-closure-gate --run-id $Run --source external-evcc `
  --require-sdp --require-tcp-peer --require-tls --require-v2gtp --require-exi --write-artifacts

Files to expect in $Data\artifacts\$Run: evse_listener_status.json, evse_runtime_status.json, sdp_diagnostics.json, tls_handshake_diagnostics.json, session_handshake_artifact_gate.json, traces\evse-listener.jsonl, traces\live-v2gtp-frames.jsonl, manifest.json. The closure gate reads them and reports whether SDP, a live TCP peer, TLS, V2GTP exchange and EXI decoding were observed.

What a passing run proves, and what it does not

ProvesDoes not prove
IPv6 link-local discovery, TCP, TLS 1.3 mutual authentication, V2GTP framing and EXI decoding with the real peer; message ordering and response budgets; for the plant-coupled lane, protocol decisions correlated with simulated electrical behaviour.Accredited ISO 15118 conformance; measured isolation (CableCheck is simulated by the plant model); physical PLC/SLAC, control pilot or power hardware; interoperability with vehicles not tested; a live control API (the gRPC GetProtocolState reports unobserved for a stand-alone listener).

Limits specific to ISO 15118-20: the TLS handshake accepts only the named groups secp521r1 and x448 (peers that offer only P-256 are refused unless the legacy option is given); the plant-coupled lane runs Scheduled or Dynamic control mode as offered by the runtime profile (the package offers Scheduled); in Dynamic mode MobilityNeedsMode 1 and pricing 0 only, available power from a profile script; no SECC-initiated pause or standby; AC and BPT are reference-responder lanes; CertificateInstallation and MeteringConfirmation are not handled by the live EVSE lane; PnC advertisement requires a fixture manifest. See Capability Boundaries.