Skip to content

Design Spec: XCP Measurement / Calibration Workflows

Document Control

Field Value
Status Implemented
Command surface canarchy xcp scan, xcp info, xcp dump, xcp trace, xcp read, xcp commands
Primary area Protocol, transport, CLI
Related specs docs/design/uds-transaction-workflows.md, docs/design/active-transmit-safety.md
Issues #327, #467

Goal

Bring XCP (Universal Measurement and Calibration Protocol, ASAM MCD-1) coverage to the same structured-output surface used for UDS. XCP is the master/slave protocol used for ECU calibration and measurement: the master sends Command Transfer Objects (CTOs) and the slave answers and streams measured values as Data Transfer Objects (DTOs). CANarchy speaks enough of the XCP-on-CAN command layer to discover responders, pair command/response transactions from a capture, and surface raw DAQ measurement payloads.

User-Facing Motivation

Calibration/measurement tooling (Caring Caribou, vendor MC tools) treats XCP as first-class, but CANarchy previously had no XCP awareness. Analysts working a bus that carries XCP traffic could only see raw frames. These workflows let them discover XCP slaves, read command/response exchanges with named commands and error codes, and extract DAQ measurement payloads — all through the canonical JSON/JSONL envelope.

Requirements

ID Type Requirement
REQ-XCP-01 Ubiquitous The system shall provide a pure parser that maps CAN frames to XCP command/response transactions and DAQ measurement events, naming commands and error codes from a bundled catalog and opening no live hardware.
REQ-XCP-02 Event-driven When xcp scan <interface> is invoked, the system shall transmit an XCP CONNECT command on the request id and report each CTO response on the response id as a transaction, parsing CONNECT positive responses into resource / max-CTO / max-DTO / version fields.
REQ-XCP-03 Event-driven When xcp trace <interface> is invoked, the system shall pair command CTOs on the request id with the following response CTOs on the response id, emitting named transactions with positive/error status.
REQ-XCP-04 Event-driven When xcp read <interface> is invoked, the system shall surface DAQ DTOs on the response id (packet identifier 0x00–0xFB) as raw measurement events, skipping CTO response/error/event/service frames.
REQ-XCP-05 Ubiquitous xcp scan shall be an active-transmit command honouring the active-transmit safety model (--ack-active, [safety].require_active_ack, YES confirmation); xcp trace, xcp read, and xcp commands shall be passive/reference.
REQ-XCP-05a Optional feature Where xcp scan --dry-run is specified, the system shall report the planned CONNECT frame (planned_frame, mode: dry_run) without opening the transport or transmitting.
REQ-XCP-06 Optional feature Where --request-id / --response-id are supplied, the system shall use those CAN ids; otherwise it shall default to 0x3E0 (request) and 0x3E1 (response).
REQ-XCP-07 Unwanted behaviour If a supplied request/response id is not a valid CAN id, the system shall return a structured error with code XCP_INVALID_ID and exit code 1.
REQ-XCP-08 State-driven While the scaffold transport backend is active, the system shall return deterministic sample XCP transactions/measurements instead of opening a live interface.
REQ-XCP-09 Ubiquitous xcp scan, xcp trace, xcp read, and xcp commands shall be exposed as MCP tools (xcp_scan, xcp_trace, xcp_read, xcp_commands); the active xcp_scan tool shall be in _ACTIVE_TRANSMIT_TOOLS with a mandatory ack_active=true and dry_run defaulting to true.
REQ-XCP-10 Event-driven When xcp info <interface> is invoked, the system shall CONNECT to the request/response id pair and report the slave's basic capabilities, additionally querying the optional GET_STATUS, GET_COMM_MODE_INFO, and GET_ID commands.
REQ-XCP-11 Event-driven When xcp dump <interface> --address --size is invoked, the system shall CONNECT and upload the address range in --chunk-size chunks via SET_MTA + UPLOAD (or SHORT_UPLOAD with --short-upload), supporting an --output file and reporting bytes_read / complete progress metadata.
REQ-XCP-12 Ubiquitous xcp info and xcp dump shall be active-transmit commands honouring the active-transmit safety model with --dry-run request plans that need no interface, and shall apply strict bounds (MAX_DUMP_BYTES, chunk size ≤ MAX_CTO-1).
REQ-XCP-13 Unwanted behaviour xcp info / xcp dump errors shall distinguish no response (XCP_NO_RESPONSE), protocol error responses (XCP_ERROR_RESPONSE), unsupported optional commands (reported per-command as status: unsupported), bounds validation (XCP_INVALID_VALUE / XCP_DUMP_TOO_LARGE / XCP_INVALID_CHUNK_SIZE, exit 1), and transport failures (TRANSPORT_UNAVAILABLE, exit 2).
REQ-XCP-14 Ubiquitous xcp info and xcp dump shall be CLI-only operator actions and shall not be exposed as MCP tools.

Command Surface

canarchy xcp scan  <interface> [--request-id 0x3E0] [--response-id 0x3E1] [--ack-active] [--dry-run] [--json|--jsonl|--text]
canarchy xcp info  <interface> [--request-id 0x3E0] [--response-id 0x3E1] [--timeout S] [--ack-active] [--dry-run] [--json|--jsonl|--text]
canarchy xcp dump  <interface> --address 0x08000000 --size N [--chunk-size 4] [--address-extension 0x00]
                   [--short-upload] [--output PATH] [--timeout S] [--ack-active] [--dry-run] [--json|--jsonl|--text]
canarchy xcp trace <interface> [--request-id 0x3E0] [--response-id 0x3E1] [--json|--jsonl|--text]
canarchy xcp read  <interface> [--response-id 0x3E1] [--json|--jsonl|--text]
canarchy xcp commands [--json|--jsonl|--text]

xcp info and xcp dump are implemented in src/canarchy/xcp_active.py on a small XcpClient seam ("send one CTO, observe at most one response CTO"), so the workflow logic is unit-tested with an in-memory fake and only TransportXcpClient touches live hardware. info reports capabilities (connect / status / comm_mode / identification); dump reports per-chunk records plus the assembled memory hex and complete flag, and writes --output when bytes were read.

Wire Model (XCP-on-CAN)

A CTO's first byte is the command code (request) or the response packet identifier (0xFF positive, 0xFE error, 0xFD event, 0xFC service). A DTO's first byte is the packet identifier (ODT number, 0x000xFB) followed by raw measurement bytes. The CONNECT positive response carries resource, comm_mode_basic, max_cto, max_dto, and the protocol/transport layer versions. Real deployments configure the request/response CAN ids per slave in the A2L; CANarchy defaults to 0x3E0 / 0x3E1 and lets the operator override them.

Data Model

xcp scan / xcp trace emit xcp_transaction events (command, command_name, positive, error_code/error_name, connect_info, request_data, response_data, request_id, response_id). xcp read emits xcp_measurement events (pid, data, response_id). xcp commands returns the command catalog (code, name, category). Envelope data reports mode (active for scan, passive for trace/read, reference for commands), the resolved ids, and a count field.

Output Contracts

--json returns the envelope with the data block and an events array; --jsonl streams the events; --text renders an XCP table (responder/ transaction/measurement summaries). All three are shape-consistent with the UDS output.

Error Contracts

Code Trigger Exit code
XCP_INVALID_ID --request-id / --response-id not a valid CAN id 1
XCP_INVALID_VALUE xcp dump address/size/extension out of range 1
XCP_DUMP_TOO_LARGE xcp dump --size over MAX_DUMP_BYTES (65536) 1
XCP_INVALID_CHUNK_SIZE xcp dump --chunk-size outside 1–7 1
XCP_CHUNK_EXCEEDS_MAX_CTO chunk size larger than the slave's MAX_CTO-1 1
XCP_NO_RESPONSE xcp info / xcp dump got no CONNECT response 2
XCP_ERROR_RESPONSE the slave rejected CONNECT 2
ACTIVE_ACK_REQUIRED active xcp command without --ack-active while [safety].require_active_ack is set 1
INTERFACE_REQUIRED no interface and no configured default 1

Responsibilities And Boundaries

In scope: the XCP-on-CAN command parser, scan/trace/read/commands workflows through the standard transport, active-transmit safety on scan/info/dump, the active info capability queries, and bounded dump memory upload.

Out of scope (v1): XCP-on-Ethernet (UDP/TCP) and XCP-on-USB transports; A2L-based signal decoding of DAQ payloads (raw ODT bytes only); active DAQ configuration (ALLOC_DAQ / SET_DAQ_PTR sequences) or calibration writes; seed/key unlock flows; memory writes (dump is read-only). The active info/dump workflows are CLI-only operator actions (not MCP tools); dump uploads a bounded range only.

Deferred Decisions

  • XCP-on-Ethernet transport (pairs conceptually with the DoIP transport work).
  • A2L ingestion to decode DAQ ODT entries into named, scaled signals.