Environment and Bench Preflight
Preflight is the boundary between "the application is installed" and "this workstation is correctly prepared to run the selected protocol against your device under test (DUT)". Run it whenever the PC, network adapter, certificate set, VeriStand version, bench wiring, DUT or ChargeLink release changes.
Most first-day failures are environmental rather than protocol defects: the wrong NIC is selected, IPv6 is disabled, UDP 15118 is blocked, another process owns the TCP port, a certificate is expired, or a VeriStand project no longer deploys. Preflight isolates those conditions before a live session creates misleading protocol symptoms.
$CL = 'C:\Program Files\DEVlink\ChargeLink\<VERSION>\charger\bin\chargelink.exe'
$Data = "$env:ProgramData\DEVlink\ChargeLink\data"
The installation has a charger\ and a vehicle\ folder.
1. Record the exact software identity
chargelink --version
chargelink --json license status
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json env doctor --strict
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json runtime list
Make sure no stale session holds a role lock. If runtime list shows a session whose heartbeat is old and whose process no longer exists, recover it:
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
2. Identify the adapter to your DUT and its IPv6 identity
Get-NetAdapter | Sort-Object ifIndex | Format-Table ifIndex,Name,Status,LinkSpeed,MacAddress -AutoSize
Get-NetIPAddress -AddressFamily IPv6 | Where-Object PrefixOrigin -eq 'WellKnown' |
Sort-Object InterfaceIndex | Format-Table InterfaceIndex,InterfaceAlias,IPAddress,AddressState -AutoSize
Get-NetAdapterBinding -Name '<ADAPTER_NAME>' -ComponentID ms_tcpip6
Pick the physical adapter cabled to your DUT (the vehicle or the charger you test). A PLC modem is not connected to this adapter directly: a real powerline (PLC) link is not part of ChargeLink 0.5.0 (see Connecting to Real PLC Hardware). Do not select Wi-Fi, VPN, Hyper-V, Docker or an unrelated USB NIC because it has a lower index. Record two values that every live command needs:
- Interface index, for example
19(--interface-index 19). - Link-local address with zone, for example
fe80::1234:5678:9abc:def0%19: this PC's own address for--advertise-ipv6in the charger role; your DUT charger's address, with this PC's zone index, for--peer-ipv6in the vehicle role.
$IfIndex = 19
$Advertise = (Get-NetIPAddress -InterfaceIndex $IfIndex -AddressFamily IPv6 |
Where-Object IPAddress -like 'fe80::*' | Select-Object -First 1).IPAddress + "%$IfIndex"
$Advertise
Expected: Enabled: True for the IPv6 binding and one fe80:: address in state Preferred.
3. Check the ISO 15118 / DIN ports
Get-NetUDPEndpoint -LocalPort 15118 -ErrorAction SilentlyContinue
Get-NetTCPConnection -LocalPort 50118 -ErrorAction SilentlyContinue
netstat -ano | findstr ':15118 :50118'
An existing listener is not automatically wrong; it can be a ChargeLink session you started. Map the PID with Get-Process -Id <PID>. Use the PowerShell commands above to check ports.
4. Run the ChargeLink live preflight (charger role: ISO 15118-20, ISO 15118-2, DIN 70121)
evse live-preflight resolves the selected profile, checks port ownership and stale sessions, validates TLS material if given, and writes a preflight artifact. It does not start the listener.
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 `
--recover-stale
--source is external-evcc for a DUT on another machine and same-pc for a vehicle simulator on this PC. Repeat with --protocol iso15118-2 or --protocol din70121 and the matching profile. Add --allow-active-evse only when a charger session is intentionally running, and --skip-port-check only for diagnostics.
A successful preflight means ChargeLink accepted the configuration and found no local blocker. It is not proof that your DUT will negotiate. For the vehicle role, the equivalent check against your charger is the transport and TLS probe evcc tls-handshake-probe (ChargeLink as Vehicle).
5. TLS preflight
Validate the certificate material before any TLS session. The doctor accepts PEM files and checks key match, chain and validity period:
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 "$Data\pki\secc-chain.pem" `
--tls-key "$Data\pki\secc-key.pem" `
--tls-cafile "$Data\pki\v2g-root-ca.pem"
Then run the live preflight with the same TLS options plus --tls. For an ISO 15118-2 DUT vehicle that uses TLS 1.2 through Windows SChannel, add --external-evcc-windows-tls --tls-pfx <identity.pfx>. ISO 15118-20 requires TLS 1.3 with mutual authentication and therefore the default TLS adapter with --require-ca; the Windows SChannel adapter cannot select ISO 15118-20. Details and certificate requirements are in TLS and PKI.
Also verify the clock. Certificate validation fails when the workstation time is wrong even if the files are valid:
w32tm /query /status
Get-Date
6. CAN adapter (IEC 61851-23/-24 System A, CHAdeMO)
For IEC 61851-23/-24 System A (CHAdeMO) on a Kvaser channel, list the CANlib channels and check the adapter and cable before the first session:
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json dc-can chademo kvaser-check
Expected: "status": "ok" with an empty problems list and one entry per channel. The send and listen variants of the check are in the CHAdeMO runbook.
If you use the scripted DC-CAN sequences, confirm that they run on this PC. They play fixed frame sequences on a virtual bus and open no hardware:
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json dc-can catalog
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json dc-can virtual-run --protocol chademo --profile dc_can_virtual_evse --frame-count 4
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json dc-can chademo-can-adapter-loop --run-id preflight-dc-can-loop `
--adapter-kind peak-pcan --adapter-mode loopback --channel PCAN_USBBUS1 --bitrate-kbps 500
Accepted --adapter-kind values: peak-pcan, vector-xl, kvaser-canlib, socketcan, slcan, lawicel, usbtin. They are descriptors: the run binds its evidence to the named adapter configuration without opening the hardware, so hardware_loop_evidence_complete is false.
7. NI VeriStand preflight
On the charger PC of the VeriStand bench, the import of the ChargeLink kit for NI VeriStand (Install-ChargeLinkVeriStandKit.ps1) checks the installed NI VeriStand and writes its result to charger\preflight.json in the kit folder. Check the .NET runtime, then, in an administrator PowerShell in the kit's charger folder, check the session configuration without starting VeriStand or a listener:
dotnet --list-runtimes
cd 'C:\ChargeLink-VeriStand\charger'
powershell -NoProfile -ExecutionPolicy Bypass -File .\Start-ChargeLinkVeriStand.ps1 -ValidateOnly
dotnet must list Microsoft.NETCore.App 10.0.x; the check must print Configuration accepted. Run folder: …. Make sure no other VeriStand project is deployed and logical processors 10, 11 and 12 are free of other load. The full procedure is in Set Up the VeriStand Bench.
8. Firewall and endpoint security
Get-NetFirewallRule -Enabled True | Where-Object DisplayName -Match 'ChargeLink|VeriStand' |
Format-Table DisplayName,Direction,Action,Profile -AutoSize
Document every allow rule rather than disabling the firewall globally. The gRPC server accepts only a loopback --listen address and requires its per-start access token on every call; it has no TLS transport, so the management API is local only (Production Security).
9. Bench release checklist
| Area | Required evidence | Result |
|---|---|---|
| ChargeLink identity | Version, license status and doctor output saved | ☐ |
| DUT NIC | Adapter name, interface index, link-local address with zone | ☐ |
| Ports | No unexplained process on UDP 15118 / TCP 50118 | ☐ |
| Live preflight | Charger role: selected protocol/profile passes with --source external-evcc. Vehicle role: the TLS probe reaches your charger | ☐ |
| TLS | PKI doctor passes and clock is synchronised when TLS is used | ☐ |
| CAN (if used) | Kvaser check passes; scripted DC-CAN catalog, virtual run and adapter loop pass if you use them | ☐ |
| VeriStand | Kit import passes (charger\preflight.json kept); Start-ChargeLinkVeriStand.ps1 -ValidateOnly passes | ☐ |
| Safety | Site interlocks, emergency stop and limits verified by the bench owner | ☐ |
| Evidence | Artifact and support roots writable | ☐ |
Only after this checklist is complete should the operator move to the selected protocol runbook.

