IsoTpFrameCodec Class¶
Deterministic, side-effect-free codec for ISO 15765-2 (ISO-TP) Protocol-Control-Information frames on classic CAN and CAN-FD. This assembly deliberately contains no scheduler, no channel, no runtime and no vendor-adapter reference; every method here is a pure function over spans and value types.
Inheritance Object → IsoTpFrameCodec
Remarks¶
The codec is agnostic about how the produced payload will be wrapped in a
CanFrame — callers know whether they want classic CAN or CAN-FD and construct the
frame with the appropriate factory (this avoids the inverted-frame-kind defect of the earlier
prototype; see FR-TP-003).
Frame-length capacity is controlled by the isCanFd flag passed to the builders:
classic CAN yields at most 8 bytes on the wire; CAN-FD yields up to 64 bytes and pads to the
next valid CAN-FD DLC step (8, 12, 16, 20, 24, 32, 48, 64).
Fields¶
IsoTpFrameCodec.CanFdMaxData Field¶
Maximum CAN data-length for a CAN-FD frame (64 bytes).
Field Value¶
IsoTpFrameCodec.ClassicCanMaxData Field¶
Maximum CAN data-length for a classic-CAN frame (8 bytes).
Field Value¶
IsoTpFrameCodec.DefaultPaddingByte Field¶
Default padding byte per ISO 15765-2 recommendation (`0xCC` is a common choice; `0xAA` and `0x00` are also seen). Only used when the caller requests padding.
Field Value¶
IsoTpFrameCodec.FirstConsecutiveSequenceNumber Field¶
Sequence number the first Consecutive Frame after a First Frame must carry.
Field Value¶
IsoTpFrameCodec.MaxClassicFirstFrameLength Field¶
Maximum length that fits in the 12-bit classic First-Frame length field.
Field Value¶
IsoTpFrameCodec.MaxFdFirstFrameLength Field¶
Maximum length that fits in the 32-bit CAN-FD First-Frame escape length field.
Field Value¶
IsoTpFrameCodec.SequenceNumberModulus Field¶
Modulus for the CF sequence number (SN wraps 0..15).
Field Value¶
Methods¶
IsoTpFrameCodec.BuildConsecutiveFrame(IsoTpEndpoint, byte, ReadOnlySpan<byte>, bool, bool, byte) Method¶
Writes a Consecutive-Frame CAN payload with sequence number sequenceNumber (0..15) and the given data chunk. Allocates and returns a freshly sized Byte[].
public static byte[] BuildConsecutiveFrame(in CanKit.Pro.IsoTp.IsoTpEndpoint endpoint, byte sequenceNumber, System.ReadOnlySpan<byte> chunk, bool isCanFd, bool padding, byte paddingByte=204);
Parameters¶
endpoint IsoTpEndpoint
sequenceNumber Byte
chunk ReadOnlySpan<Byte>
isCanFd Boolean
padding Boolean
paddingByte Byte
Returns¶
IsoTpFrameCodec.BuildConsecutiveFrame(Span<byte>, IsoTpEndpoint, byte, ReadOnlySpan<byte>, bool, bool, byte) Method¶
Writes a Consecutive-Frame CAN payload into destination. Returns the actual number of bytes written.
public static int BuildConsecutiveFrame(System.Span<byte> destination, in CanKit.Pro.IsoTp.IsoTpEndpoint endpoint, byte sequenceNumber, System.ReadOnlySpan<byte> chunk, bool isCanFd, bool padding, byte paddingByte=204);
Parameters¶
endpoint IsoTpEndpoint
sequenceNumber Byte
chunk ReadOnlySpan<Byte>
isCanFd Boolean
padding Boolean
paddingByte Byte
Returns¶
Exceptions¶
ArgumentOutOfRangeException
The chunk does not fit in a Consecutive Frame for the requested frame kind / addressing,
or destination is too small.
IsoTpFrameCodec.BuildFirstFrame(IsoTpEndpoint, int, ReadOnlySpan<byte>, bool) Method¶
Writes a First-Frame CAN payload announcing a segmented PDU of totalLength bytes and containing the first firstChunk user bytes. Allocates and returns a freshly sized Byte[].
public static byte[] BuildFirstFrame(in CanKit.Pro.IsoTp.IsoTpEndpoint endpoint, int totalLength, System.ReadOnlySpan<byte> firstChunk, bool isCanFd);
Parameters¶
endpoint IsoTpEndpoint
totalLength Int32
firstChunk ReadOnlySpan<Byte>
isCanFd Boolean
Returns¶
IsoTpFrameCodec.BuildFirstFrame(Span<byte>, IsoTpEndpoint, int, ReadOnlySpan<byte>, bool) Method¶
Writes a First-Frame CAN payload into destination. First Frames never use padding — they always fill the underlying CAN frame completely.
public static int BuildFirstFrame(System.Span<byte> destination, in CanKit.Pro.IsoTp.IsoTpEndpoint endpoint, int totalLength, System.ReadOnlySpan<byte> firstChunk, bool isCanFd);
Parameters¶
endpoint IsoTpEndpoint
totalLength Int32
firstChunk ReadOnlySpan<Byte>
isCanFd Boolean
Returns¶
Exceptions¶
ArgumentOutOfRangeException
totalLength is negative or exceeds the addressable range for the
requested frame kind; classic-CAN cannot address totals > 4095 (FF escape form is
CAN-FD-only per ISO 15765-2).
Remarks¶
User bytes copied from firstChunk are capped to
min(firstChunk.Length, frame capacity, totalLength) so the on-wire data never
exceeds the PDU size announced in the FF_DL field (fixes bugbot 3596393504).
IsoTpFrameCodec.BuildFlowControl(IsoTpEndpoint, FlowStatus, byte, byte, bool, bool, byte) Method¶
Writes a Flow-Control CAN payload with the given flowStatus, blockSize and stMinRaw. Allocates and returns a freshly sized Byte[].
public static byte[] BuildFlowControl(in CanKit.Pro.IsoTp.IsoTpEndpoint endpoint, CanKit.Pro.IsoTp.FlowStatus flowStatus, byte blockSize, byte stMinRaw, bool isCanFd, bool padding, byte paddingByte=204);
Parameters¶
endpoint IsoTpEndpoint
flowStatus FlowStatus
blockSize Byte
stMinRaw Byte
isCanFd Boolean
padding Boolean
paddingByte Byte
Returns¶
IsoTpFrameCodec.BuildFlowControl(Span<byte>, IsoTpEndpoint, FlowStatus, byte, byte, bool, bool, byte) Method¶
Writes a Flow-Control CAN payload into destination. Returns the actual number of bytes written. Padding is applied <em>after</em> the BS/STmin bytes, so those are never overwritten (fixes review §1.1 point 3).
public static int BuildFlowControl(System.Span<byte> destination, in CanKit.Pro.IsoTp.IsoTpEndpoint endpoint, CanKit.Pro.IsoTp.FlowStatus flowStatus, byte blockSize, byte stMinRaw, bool isCanFd, bool padding, byte paddingByte=204);
Parameters¶
endpoint IsoTpEndpoint
flowStatus FlowStatus
blockSize Byte
stMinRaw Byte
isCanFd Boolean
padding Boolean
paddingByte Byte
Returns¶
IsoTpFrameCodec.BuildSingleFrame(IsoTpEndpoint, ReadOnlySpan<byte>, bool, bool, byte) Method¶
Writes a Single-Frame CAN payload for the given userData into a freshly allocated Byte[] and returns it. See BuildSingleFrame(Span<byte>, IsoTpEndpoint, ReadOnlySpan<byte>, bool, bool, byte) for the span-based, allocation-free variant.
public static byte[] BuildSingleFrame(in CanKit.Pro.IsoTp.IsoTpEndpoint endpoint, System.ReadOnlySpan<byte> userData, bool isCanFd, bool padding, byte paddingByte=204);
Parameters¶
endpoint IsoTpEndpoint
userData ReadOnlySpan<Byte>
isCanFd Boolean
padding Boolean
paddingByte Byte
Returns¶
IsoTpFrameCodec.BuildSingleFrame(Span<byte>, IsoTpEndpoint, ReadOnlySpan<byte>, bool, bool, byte) Method¶
Writes a Single-Frame CAN payload for the given userData into destination. Returns the actual number of bytes written; the destination buffer must be at least ClassicCanMaxData (or CanFdMaxData for CAN-FD) bytes long.
public static int BuildSingleFrame(System.Span<byte> destination, in CanKit.Pro.IsoTp.IsoTpEndpoint endpoint, System.ReadOnlySpan<byte> userData, bool isCanFd, bool padding, byte paddingByte=204);
Parameters¶
endpoint IsoTpEndpoint
userData ReadOnlySpan<Byte>
isCanFd Boolean
padding Boolean
paddingByte Byte
Returns¶
Exceptions¶
ArgumentOutOfRangeException
userData is empty, exceeds the Single-Frame capacity for the requested
frame-kind/addressing combination, or destination is too small.
Remarks¶
ISO 15765-2 does not define an empty Single Frame: on classic CAN the SF_DL low-nibble range
is 1..7, and on CAN-FD the escape-form LEN byte likewise starts at 1.
A zero-length SF is therefore rejected at build time to prevent producing an on-wire frame
that no conformant peer could parse (fixes bugbot 3594958440).
IsoTpFrameCodec.ConsecutiveFrameMaxDataLength(bool, bool) Method¶
Returns the maximum number of user-data bytes carried in a Consecutive Frame. CF uses a 1-byte PCI on both classic CAN and CAN-FD.
Parameters¶
isCanFd Boolean
usesAddressExtension Boolean
Returns¶
IsoTpFrameCodec.DecodeStMin(byte) Method¶
Decodes an ISO 15765-2 STmin raw byte into a TimeSpan. Reserved values
(0x80..0xF0 and 0xFA..0xFF) are treated as 0x7F = 127 ms per the
specification, which fixes review §1.1 point 6 / FR-TP-007 / FR-RAW-052.
Parameters¶
raw Byte
Returns¶
IsoTpFrameCodec.EncodeStMin(TimeSpan) Method¶
Encodes a TimeSpan STmin value as an ISO 15765-2 raw byte.
- 0..127 ms in 1-ms steps → 0x00..0x7F
- 100..900 µs in 100-µs steps → 0xF1..0xF9
Parameters¶
value TimeSpan
Returns¶
Exceptions¶
ArgumentOutOfRangeException
value is negative.
Remarks¶
The commonly-used values 0 ms and 1 ms encode as 0x00 and 0x01
respectively (fixes review §1.1 point 5). Values that fall between the two ISO 15765-2
ranges (e.g. 999 µs) or exceed 127 ms are clamped to the nearest representable value.
IsoTpFrameCodec.FirstFrameMaxDataLength(bool, bool, bool) Method¶
Returns the number of user-data bytes carried in the First Frame of a segmented PDU.
public static int FirstFrameMaxDataLength(bool isCanFd, bool usesAddressExtension, bool useLongLength);
Parameters¶
isCanFd Boolean
true for CAN-FD, false for classic CAN.
usesAddressExtension Boolean
true when the endpoint burns the first payload
byte for an address-extension byte.
useLongLength Boolean
true when the FF must carry the 32-bit CAN-FD escape
length (for total lengths > 4095); ignored for classic CAN.
Returns¶
Remarks¶
Classic-CAN FF has a 2-byte PCI, so the classic capacity is 8 - 2 - extension
(6 bytes without extension). CAN-FD FF uses the same 2-byte PCI for lengths up to 4095, or
a 6-byte PCI (`FF nibble | 0x00`, `0x00`, then a 32-bit length) when
useLongLength is true.
IsoTpFrameCodec.NextConsecutiveSequenceNumber(byte) Method¶
Returns the next CF sequence number after current (wraps 0..15).
Parameters¶
current Byte
Returns¶
IsoTpFrameCodec.NextValidFrameLength(int, bool) Method¶
Returns the next valid CAN-FD DLC data length that is greater than or equal to dataLength. Classic CAN always pads to 8 bytes.
Parameters¶
dataLength Int32
Number of user bytes that must fit (0..64 for CAN-FD, 0..8 for classic).
isCanFd Boolean
true to use the CAN-FD DLC ladder, false to pad to 8.
Returns¶
Exceptions¶
ArgumentOutOfRangeException
dataLength is negative, exceeds 8 for classic CAN, or exceeds 64 for CAN-FD.
IsoTpFrameCodec.SingleFrameMaxDataLength(bool, bool) Method¶
Returns the maximum number of user-data bytes that fit into a Single Frame on a given frame-kind and addressing mode.
Parameters¶
isCanFd Boolean
true for CAN-FD (up to 64-byte frames), false for classic CAN.
usesAddressExtension Boolean
true when the endpoint burns the first payload
byte for an address-extension byte.
Returns¶
Remarks¶
Classic-CAN SF uses a 1-byte PCI, so the classic capacity is
8 - 1 - (extension ? 1 : 0). CAN-FD SF supports the same 1-byte PCI plus a 2-byte
escape form (`PCI = 0x00`, `LEN` byte) that unlocks the full CAN-FD payload up to
64 - 2 - (extension ? 1 : 0).
IsoTpFrameCodec.SingleFrameShortFormMaxDataLength(bool) Method¶
Returns the maximum number of Single-Frame data bytes that still fit into the classic 1-byte PCI form (SF_DL in the low nibble, 1..7). Beyond this and up to SingleFrameMaxDataLength(bool, bool) the CAN-FD escape form (`0x00 LEN`) must be used.
Parameters¶
usesAddressExtension Boolean
Returns¶
IsoTpFrameCodec.TryParsePci(ReadOnlySpan<byte>, IsoTpEndpoint, bool, Pci) Method¶
Bounds-checked parser for the ISO-TP Protocol-Control-Information of a received CAN frame.
Never throws IndexOutOfRangeException — a truncated frame returns
false with pci set to default (fixes review §1.1 point 6).
public static bool TryParsePci(System.ReadOnlySpan<byte> canPayload, in CanKit.Pro.IsoTp.IsoTpEndpoint endpoint, bool isCanFd, out CanKit.Pro.IsoTp.Pci pci);
Parameters¶
canPayload ReadOnlySpan<Byte>
Raw CAN data payload (up to 8 bytes for classic CAN, up to 64 bytes for CAN-FD).
endpoint IsoTpEndpoint
Endpoint whose addressing mode decides whether the first payload byte is the address-extension byte.
isCanFd Boolean
true when the caller knows the frame was received as a CAN-FD frame, false for
classic CAN. The Single-Frame and First-Frame escape forms (PCI 0x00 LEN … and
PCI 0x10 0x00 LEN[4] …) are only defined on CAN-FD per ISO 15765-2, so this flag is
required to distinguish a legitimate escape header from a malformed classic-CAN PCI whose
SF_DL / FF_DL is zero (fixes review §1.1 point 8 / bugbot 3594958440 / 3594958445).
pci Pci
On success, the parsed PCI view.
Returns¶
Boolean
true when the frame has enough bytes and a valid PCI nibble; false for
truncated frames, reserved PCI nibbles (> 3), reserved Flow-Status values (> 2),
escape-form PCIs on classic CAN, or CAN-FD Single-Frame short-form SF_DL values above
SingleFrameShortFormMaxDataLength(bool) for the endpoint's addressing mode
(those lengths must use the 0x00 LEN escape — 8..15 without address extension,
7..15 with extended/mixed addressing).