Documentation
¶
Overview ¶
Package ccp decodes CCP — the CAN Calibration Protocol (ASAM) — the CAN-native predecessor of XCP that an ECU calibration tool uses to read and write an ECU's memory: connect to a station, characterise (DAQ) measurement, download calibration data, and flash (PROGRAM). It is still in production ECUs (especially older GM / European powertrain modules) and is the CAN-bus sibling of internal/xcp. CCP is a real automotive-security target: it exposes direct ECU memory UPLOAD (read) / DNLOAD (write) and a PROGRAM / CLEAR_MEMORY flash sequence, with the only access control being the optional GET_SEED / UNLOCK seed-and-key handshake — so an attacker on the CAN bus who speaks CCP can exfiltrate calibration/firmware, tamper with calibration, or reflash the ECU. A captured CCP frame identifies the **operation** — a session CONNECT (and the target station address), a SEED & KEY auth, a memory UPLOAD, a calibration DNLOAD, a PROGRAM flash — or, on the slave side, the Command Return Message (with its return code), an event, or DAQ measurement data. It joins the project's automotive family (internal/xcp, uds, kwp, obd2, doip, isotp, canfd).
Wrap-vs-native judgement ¶
Native. A CCP frame is the 8-byte CAN payload: a CRO (Command Receive Object — command byte + counter + params, master → slave) or a DTO (Data Transmission Object — a packet id selecting a Command Return Message / event / DAQ data, slave → master). A byte lookup + a small return-code table; stdlib only, no new go.mod dep.
Verifiable / no confidently-wrong output ¶
The command table and the return-code table are code-generated from scapy's authoritative CCP layer (scapy.contrib.automotive.ccp). Like XCP, CCP is direction-dependent — a command byte (master → slave) and a DTO packet id (slave → master) share the same byte space — so the caller supplies the direction; without it the command interpretation is used and the ambiguity is noted. Only the command byte / packet id, the counter, the return code and (for CONNECT) the little-endian station address are decoded; the remaining command/response parameters are surfaced as raw hex (their layout is command-specific and address-granularity-dependent), never reinterpreted here.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Result ¶
type Result struct {
Direction string `json:"direction"`
// CRO (command, master → slave)
Command string `json:"command,omitempty"`
CommandHex string `json:"command_hex,omitempty"`
CommandCounter *int `json:"command_counter,omitempty"`
StationAddress string `json:"station_address,omitempty"`
// DTO (response/data, slave → master)
PacketIDHex string `json:"packet_id_hex,omitempty"`
DTOType string `json:"dto_type,omitempty"`
ReturnCode string `json:"return_code,omitempty"`
Counter *int `json:"counter,omitempty"`
SecurityRelevance string `json:"security_relevance,omitempty"`
ParamsHex string `json:"params_hex,omitempty"`
Notes []string `json:"notes,omitempty"`
}
Result is the decoded view of a CCP frame.