First Session with Your Device Under Test
This tutorial runs one session between ChargeLink and your device under test (DUT). ChargeLink plays one role: the charger when your DUT is a vehicle, EVCC or on-board charger, or the vehicle when your DUT is a charger or SECC. The example is ISO 15118-20 DC EIM, the main use of ChargeLink; the other standards follow the same steps in their runbooks.
You need: an installed and activated ChargeLink (Install and Activate); your DUT connected to an Ethernet adapter of the ChargeLink PC with IPv6 enabled; and TLS material that your DUT trusts (TLS and PKI). No DUT yet? Run the self-test instead.
$CL = 'C:\Program Files\DEVlink\ChargeLink\<VERSION>\charger\bin\chargelink.exe'
$Data = "$env:ProgramData\DEVlink\ChargeLink\data"
$Pki = "$Data\pki"
The installation has a charger\ and a vehicle\ folder. The chargelink.exe in either folder runs either role.
1. Choose the role
| Your DUT | ChargeLink role | Commands in this tutorial | Guide |
|---|---|---|---|
| Vehicle, EVCC, on-board charger or vehicle simulator | Charger (EVSE/SECC) | evse live-preflight, evse start --external-evcc-session | ChargeLink as Charger |
| Charger, SECC or charger simulator | Vehicle (EV/EVCC) | evcc tls-handshake-probe, evcc activate-profile | ChargeLink as Vehicle |
2. Confirm the installation
chargelink --version
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json env doctor
chargelink --json license status
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json profile list
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json profile show iso15118_20_dc
Expected: version 0.5.0; doctor "status": "ok"; license "code": "LIC_OK"; a list of 64 profiles with id, protocol, role and description; the profile iso15118_20_dc shown as an EVSE ISO 15118-20 profile with connector ccs2 and EXI mode chargelink-exi. The vehicle-role profile is iso15118_20_dc_evcc_reference.
3. Identify the adapter to your DUT
Get-NetAdapter | Sort-Object ifIndex | Format-Table ifIndex,Name,Status,LinkSpeed -AutoSize
$IfIndex = <INTERFACE_INDEX>
$Advertise = (Get-NetIPAddress -InterfaceIndex $IfIndex -AddressFamily IPv6 |
Where-Object IPAddress -like 'fe80::*' | Select-Object -First 1).IPAddress + "%$IfIndex"
$Advertise
Use the physical adapter cabled to your DUT, not Wi-Fi, VPN or a virtual adapter. The zone index after % is always this PC's interface index. The full set of checks (IPv6 binding, ports, clock, firewall) is in Environment and Bench Preflight; the firewall rules for the charger role are in Install and Activate.
4. Check the TLS material
ISO 15118-20 requires TLS 1.3 with mutual authentication. ChargeLink and your DUT must trust the same V2G root. In the charger role ChargeLink needs the SECC chain and key; in the vehicle role it needs the vehicle chain and key. Check the files before the session:
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse tls-pki-doctor `
--protocol iso15118-20 --profile-id iso15118_20_dc `
--tls --require-ca --tls-cert "$Pki\secc-chain.pem" --tls-key "$Pki\secc-key.pem" --tls-cafile "$Pki\v2g-root-ca.pem"
w32tm /query /status
If your DUT accepts imported certificates, evse tls-material-init --bench-pki generates an engineering charger identity and an engineering vehicle identity under one root; see TLS and PKI. Engineering material is for test benches only.
5a. ChargeLink as charger: your vehicle is the DUT
Validate the configuration without opening sockets:
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse start --dry-run --protocol iso15118-20 --profile-id iso15118_20_dc
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse stop
Expected: "mode": "dry_run", "status": "validated" and a generated run_id. The result also prints the listener.activation_catalog: for each protocol, the exact listener command and the matching vehicle-side command. Keep this output; it is the authoritative recipe for your installation.
Run the live preflight, then start the charger and leave the window open:
$Run = "first-dut-$(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
Start the session on your DUT. From a second PowerShell window (define $Data and $Run there too), watch the charger:
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json evse status --run-id $Run
Get-Content "$Data\artifacts\$Run\traces\live-v2gtp-frames.jsonl" -Tail 20
When your DUT has ended its session, stop the charger and evaluate the run:
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 evse live-closure-gate --run-id $Run --source external-evcc `
--require-sdp --require-tcp-peer --require-tls --require-v2gtp --require-exi --write-artifacts
A good session: the closure gate reports that SDP, a live TCP peer, TLS, the V2GTP exchange and EXI decoding were observed; tls_handshake_diagnostics.json shows TLS 1.3 with your DUT's certificate; traces\live-v2gtp-frames.jsonl lists every request of your DUT with its decode verdict. Without a plant model this charger is a reference responder: it answers each request with the validated reference response and does not follow the requested current. For a charger whose responses follow a simulated power stage, use the NI VeriStand bench.
5b. ChargeLink as vehicle: your charger is the DUT
Start your charger so that it listens on the link. Prove transport and mutual TLS first; the probe sends no SDP, V2GTP or EXI:
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::<DUT_ADDRESS>%' + $IfIndex) --tcp-port 50118 --connect-timeout-ms 1000 `
--tls --tls-cert "$Pki\vehicle-chain.pem" --tls-key "$Pki\vehicle-key.pem" --tls-cafile "$Pki\v2g-root-ca.pem" --require-ca
Judge the probe on its status field: the exit code says whether the probe ran, the status says what your charger decided. Then run the full session. The vehicle role needs two files from the vehicle folder of the kit (vehicle\cases\); their EV values are test values:
$env:CHARGELINK_ISO20_LIVE_SEMANTIC_CASE = 'C:\Program Files\DEVlink\ChargeLink\<VERSION>\vehicle\cases\nominal.json'
$env:CHARGELINK_ISO20_FULL_WIRE_SESSION_MANIFEST = 'C:\Program Files\DEVlink\ChargeLink\<VERSION>\vehicle\cases\full-wire-session-manifest.json'
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
If SDP finds no charger, connect directly: replace --use-sdp with --peer-ipv6 ('fe80::<DUT_ADDRESS>%' + $IfIndex) --probe-peer.
A good session: summary.json shows every required state as observed, protocol_summary.json shows SDP, TCP, TLS and V2GTP as observed, and diagnostics.json lists no missing state. Each response wait is bounded by the ISO 15118-20 V2G_EVCC_Msg_Timeout for its message type.
6. Locate the evidence
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json runtime list
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json artifacts index
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json artifacts integrity --run-id <RUN_ID>
Each run directory contains manifest.json with a SHA-256 for every file. How to read traces, manifests and reports is in Trace, Evidence and Reports.
What you have proved
- The CLI runs from the installed path and reports the expected version and license.
- ChargeLink and your DUT discover each other on the link (or connect directly), complete the TLS 1.3 mutual handshake and exchange V2GTP/EXI messages.
- The session is recorded under the chosen artifact root with integrity hashes.
What you have not proved: physical-layer interoperability (PLC, control pilot), measured electrical behaviour, or conformance of your DUT. Continue with First 60 Minutes to leave the workstation in a supportable state, and with the protocol runbook for the standard you test.

