CanKing service extension that decodes and annotates ISO-TP (ISO 15765-2) traffic on CAN and CAN-FD buses.
The extension observes incoming frames, recognizes the four ISO-TP frame types (Single Frame, First Frame, Consecutive Frame, Flow Control), reassembles multi-frame messages from their constituent Consecutive Frames, and enriches every matching frame with protocol metadata as CanKing frame properties.
It can also be configured to actively participate in transfers by sending Flow Control (FC) frames — both the initial CTS after a First Frame and subsequent CTS frames at block boundaries when fc_block_size > 0.
fc_block_size > 0.Remove all active_addresses entries to turn the extension into a passive observer.
active_addresses is empty.session_timeout_ms are expired and logged.When active_addresses is configured, the extension sends FC(ContinueToSend) frames so the sender proceeds with data transfer.
Note:
This extension never sends segmented messages of its own. It can only receive segmented messages, not transmit.
Depending on frame type and decode state, the extension sets these frame properties:
| Property | Set on | Value |
|---|---|---|
ISOTP.FrameType | All recognised frames | "SF", "FF", "CF", or "FC" |
ISOTP.TpTotalBytes | SF; FF | Payload/Total message length in bytes |
ISOTP.TpFirstDataHex | FF | Hex of data bytes carried in the FF itself |
ISOTP.TpSeqNo | CF | Sequence number nibble (0–15) |
ISOTP.TpSessionProgress | CF | "received/total" byte count |
ISOTP.TpFlowStatus | FC | "CTS", "Wait", "Overflow", or "Reserved" |
ISOTP.TpBlockSize | FC | Block size byte value |
ISOTP.TpSeparationTimeUs | FC | STmin decoded to microseconds |
ISOTP.TpReassemblyComplete | Last CF of a complete message | "true" |
ISOTP.TpPayloadHex | SF; last CF of a complete message | Uppercase hex string of payload / reassembled data |
ISOTP.TpActiveAction | FF (on active FC send); CF at block boundary | "FC sent" |
Configuration is JSON and can be changed at runtime via the CanKing extension config panel.
Default configuration:
{
"session_timeout_ms": 1000,
"extended_addressing": false,
"extended_id": false,
"active_addresses": [
{
"rx_can_id": 2024,
"tx_can_id": 2016,
"rx_address_extension": null,
"tx_address_extension": null
}
],
"broadcast_id": 2015,
"fc_block_size": 0,
"fc_stmin": 0,
"fc_padding": 204,
"fc_use_brs": false
}
The default active_addresses, fc_padding, and broadcast_id values correspond to the standard OBD-II engine ECU scenario:
| Hex | Decimal | Role |
|---|---|---|
0x7E8 | 2024 | Engine ECU response address (rx_can_id) |
0x7E0 | 2016 | Tester physical request address (tx_can_id) |
0x7DF | 2015 | OBD-II functional broadcast address (broadcast_id) |
0xCC | 204 | ISO 15765-2 recommended padding byte (fc_padding) |
Fields:
session_timeout_ms: inactivity timeout for multi-frame sessions. A session is discarded if no Consecutive Frame arrives within this window.
extended_addressing: when true, the first byte of each CAN data field is the N_TA address extension and the PCI byte is at offset 1. Default false.
extended_id: restrict to extended (29-bit) CAN IDs when true; standard (11-bit) IDs when false. Default false.
active_addresses: each entry has the following fields:
rx_can_id: CAN ID on which the remote node sends First Frames to us.tx_can_id: CAN ID used when sending FC frames back.rx_address_extension (optional): expected N_TA byte (data[0]) in received frames when extended_addressing is true. When null, any extension byte is accepted. Ignored when extended_addressing is false.tx_address_extension (optional): N_TA byte prepended to outgoing FC frames when extended_addressing is true. When null, no extension byte is added. Ignored when extended_addressing is false.When a First Frame arrives on rx_can_id (with matching rx_address_extension if applicable), an FC(CTS) is sent on tx_can_id with tx_address_extension prepended. Empty list = fully passive. Default: OBD-II engine ECU pair (0x7E8 / 0x7E0).
broadcast_id: passive-mode CAN ID filter. When set, non-active frames are only annotated if their CAN ID equals this value. Set to null to annotate all non-active frames. Default 2015 (0x7DF).
fc_block_size: block size (BS) byte sent in all outgoing FC frames. 0 means unlimited — the sender may transmit all remaining frames without further FC. Default 0.
fc_stmin: separation time minimum byte sent in all outgoing FC frames, ISO 15765-2 encoded. 0x00–0x7F = 0–127 ms; 0xF1–0xF9 = 100–900 µs; other values = 127 ms fallback. Default 0.
fc_padding: padding byte used to fill outgoing FC frames to 8 bytes. Set to null to send only the mandatory 3 bytes (PCI + BS + STmin) with no padding. Default 204 (0xCC).
fc_use_brs: enable Bit Rate Switch (BRS) in outgoing FC frames when CAN-FD is used. Has no effect on classic CAN frames.
When fc_block_size = 0 (unlimited):
ECU → FF (on rx_can_id) → extension sends FC(BS=0) on tx_can_id
ECU → CF sn=1
ECU → CF sn=2
…
ECU → CF last → message reassembled, ISOTP.TpPayloadHex annotated
When fc_block_size = 2:
ECU → FF (on rx_can_id) → extension sends FC(BS=2)
ECU → CF sn=1
ECU → CF sn=2 → extension sends FC(BS=2) ← block boundary
ECU → CF sn=3
ECU → CF sn=4 → extension sends FC(BS=2) ← block boundary
…
ECU → CF last → message reassembled