Skip to content

IsoTpFunctionalClient Class

ISO-TP functional (1:N broadcast) client per ISO 15765-2 §9 / ISO 14229-1 §7.5.4.

public sealed class IsoTpFunctionalClient : System.IDisposable

Inheritance Object → IsoTpFunctionalClient

Implements IDisposable

Remarks

Functional addressing allows a tester to broadcast a Single-Frame request on a shared functional CAN identifier and collect Single-Frame responses from multiple ECUs, each replying on its own physical response CAN identifier.

Send restriction: ISO 15765-2 §9.4 requires that functional requests are Single Frames only. Attempting to send a PDU that exceeds the Single-Frame capacity for the configured frame kind faults the returned task with InvalidOperationException. This is intentional: the standard prohibits multi-frame functional requests because there is no dedicated physical address to which each ECU could send a Flow-Control frame.

Response collection:SendAndCollectAsync(ReadOnlyMemory<byte>, TimeSpan, CancellationToken) and CollectResponsesAsync(TimeSpan, CancellationToken) collect Single-Frame responses that arrive within a caller-supplied time window. First-Frame responses are not reassembled (they would require the tester to know each ECU's physical response-to-request addressing, which is not available in the general functional-addressing case); they are silently dropped. Flow-Control and Consecutive-Frame messages are likewise dropped.

Threading:SendAndCollectAsync(ReadOnlyMemory<byte>, TimeSpan, CancellationToken), SendAsync(ReadOnlyMemory<byte>, CancellationToken), and CollectResponsesAsync(TimeSpan, CancellationToken) are safe to call from any thread, and concurrently: each call makes its own subscription and shares no state with another. Concurrent collections are merely redundant -- every one of them sees the same responses -- so callers that run several rounds against the same ECUs await each call in turn. Dispose() is thread-safe and idempotent.

Properties

IsoTpFunctionalClient.FunctionalTxCanId Property

The functional TX CAN identifier used for outbound Single Frames.

public uint FunctionalTxCanId { get; }

Property Value

UInt32

IsoTpFunctionalClient.Options Property

The options this client was opened with.

public CanKit.Pro.IsoTp.IsoTpFunctionalOptions Options { get; }

Property Value

IsoTpFunctionalOptions

Methods

IsoTpFunctionalClient.CollectResponsesAsync(TimeSpan, CancellationToken) Method

Creates a fresh response subscription and collects Single-Frame responses from any ECU whose response CAN-ID falls within the configured range for the duration of window.

public System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<CanKit.Pro.IsoTp.IsoTpFunctionalResponse>> CollectResponsesAsync(System.TimeSpan window, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

window TimeSpan

Duration to collect responses.

cancellationToken CancellationToken

Cancels the collection window early.

Returns

Task<IReadOnlyList<IsoTpFunctionalResponse>>
All Single-Frame responses received within the window, in arrival order.

Exceptions

ArgumentOutOfRangeException
window is negative or exceeds what a timer can measure (about 49 days); nothing is subscribed.

ObjectDisposedException
The client was disposed.

Remarks

When called after SendAsync(ReadOnlyMemory<byte>, CancellationToken), there is a small window between send and subscribe where a very fast ECU response may be missed. Use SendAndCollectAsync(ReadOnlyMemory<byte>, TimeSpan, CancellationToken) to eliminate that race.

IsoTpFunctionalClient.Dispose() Method

Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

public void Dispose();

Implements Dispose()

IsoTpFunctionalClient.Listen() Method

Subscribes to the response range now and returns a listener that keeps the subscription across collections. Obtained before a SendAsync(ReadOnlyMemory<byte>, CancellationToken), it closes the gap between send and subscribe that CollectResponsesAsync(TimeSpan, CancellationToken) leaves, and a response that arrives between two of its collections is buffered for the next one.

public CanKit.Pro.IsoTp.IsoTpFunctionalListener Listen();

Returns

IsoTpFunctionalListener

Exceptions

ObjectDisposedException
The client was disposed.

IsoTpFunctionalClient.SendAndCollectAsync(ReadOnlyMemory<byte>, TimeSpan, CancellationToken) Method

Sends pdu as a Single Frame on the functional CAN identifier, then collects Single-Frame responses from any ECU whose response CAN-ID falls within the configured range, returning all responses received within window.

public System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<CanKit.Pro.IsoTp.IsoTpFunctionalResponse>> SendAndCollectAsync(System.ReadOnlyMemory<byte> pdu, System.TimeSpan window, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

pdu ReadOnlyMemory<Byte>

User-data payload. Must fit in one ISO-TP Single Frame (≤ 7 bytes for classic CAN without address extension, ≤ 62 bytes for CAN-FD). Violating this limit faults the task with InvalidOperationException — multi-frame functional requests are prohibited by ISO 15765-2 §9.4.

window TimeSpan

Duration to wait for responses after the Single Frame is TX-confirmed. Expired windows return all responses collected so far; they do not fault the task.

cancellationToken CancellationToken

Cancels both the TX-confirm wait and the response-collection window.

Returns

Task<IReadOnlyList<IsoTpFunctionalResponse>>
All Single-Frame responses received within the window, in arrival order. May be empty if no ECU responded.

Exceptions

InvalidOperationException
pdu exceeds the Single-Frame capacity for the configured frame kind.

ArgumentOutOfRangeException
window is negative or exceeds what a timer can measure (about 49 days); nothing is transmitted.

IsoTpException
The TX-confirm failed (bus-off, driver rejection, or N_As timeout).

IsoTpFunctionalClient.SendAndCollectWithTransmitStampAsync(ReadOnlyMemory<byte>, TimeSpan, CancellationToken) Method

As SendAndCollectAsync(ReadOnlyMemory<byte>, TimeSpan, CancellationToken), also returning when the request was handed to the driver and when it was transmitted (IsoTpTransmitStamps, zero where the driver reports neither). A response that arrived before the handoff answers something else -- the subscription is made before the send, and a frame from between the two is not this request's -- and is left out; a caller keeping its own deadline from a response, such as UDS P2* from an NRC 0x78, anchors it no earlier than the handoff for the same reason.

public System.Threading.Tasks.Task<CanKit.Pro.IsoTp.IsoTpFunctionalCollection> SendAndCollectWithTransmitStampAsync(System.ReadOnlyMemory<byte> pdu, System.TimeSpan window, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

pdu ReadOnlyMemory<Byte>

window TimeSpan

cancellationToken CancellationToken

Returns

Task<IsoTpFunctionalCollection>

IsoTpFunctionalClient.SendAsync(ReadOnlyMemory<byte>, CancellationToken) Method

Sends pdu as a Single Frame on the functional CAN identifier. The returned task completes when the CAN driver confirms the frame was accepted.

public System.Threading.Tasks.Task SendAsync(System.ReadOnlyMemory<byte> pdu, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

pdu ReadOnlyMemory<Byte>

User-data payload. Must fit in a Single Frame (see class remarks).

cancellationToken CancellationToken

Cancels the TX-confirm wait.

Returns

Task

Exceptions

InvalidOperationException
pdu exceeds the Single-Frame capacity.

IsoTpException
TX-confirm failed.

Remarks

Prefer SendAndCollectAsync(ReadOnlyMemory<byte>, TimeSpan, CancellationToken) for the typical request/collect pattern, as it subscribes to the response range before sending so that no fast ECU response is missed.

IsoTpFunctionalClient.SendWithTransmitStampAsync(ReadOnlyMemory<byte>, CancellationToken) Method

As SendAsync(ReadOnlyMemory<byte>, CancellationToken), returning when the frame was handed to the driver and when it was transmitted (IsoTpTransmitStamps, zero where the driver reports neither), for a caller that keeps a deadline from the transmission.

public System.Threading.Tasks.Task<CanKit.Pro.IsoTp.IsoTpTransmitStamps> SendWithTransmitStampAsync(System.ReadOnlyMemory<byte> pdu, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

pdu ReadOnlyMemory<Byte>

cancellationToken CancellationToken

Returns

Task<IsoTpTransmitStamps>