Skip to content

IUdsClient Interface

A single Unified Diagnostic Services (ISO 14229-1) client bound to one IIsoTpChannel. One client = one tester ↔ ECU relationship; overlapping requests from multiple callers are serialized by the client so at most one UDS request is outstanding at any time (mirrors ISO 14229-1 §7.3's "one active request per tester" model).

public interface IUdsClient : System.IDisposable

Implements IDisposable

Remarks

The MVP surface covers the seven services listed in SRS FR-UDS-001..007 (0x10, 0x11, 0x22, 0x27, 0x2E, 0x31, 0x3E) plus the raw escape hatch SendRawAsync(ReadOnlyMemory<byte>, CancellationToken). Every method: - Serializes on the client's internal request lock — callers may invoke from arbitrary threads. - Applies P2/P2 timing (SRS FR-UDS-008/009): the initial response is awaited for at most P2ClientMax; every NRC 0x78 (requestCorrectlyReceived-ResponsePending) restarts the P2 (P2StarClientMax) timer. - Surfaces negative responses as UdsNegativeResponseException with the request SID and the raw NRC byte (SRS FR-UDS-010).

The client honours the caller's CancellationToken for both the serialization gate and the response wait; a cancelled call abandons the response but does not corrupt the client (the next call will still see a clean state).

IDisposable.Dispose is thread-safe and idempotent; disposing an active client cancels any pending request and stops the TesterPresent keep-alive (if any).

Properties

IUdsClient.Channel Property

The channel this client is bound to (never null).

CanKit.Pro.IsoTp.IIsoTpChannel Channel { get; }

Property Value

IIsoTpChannel

IUdsClient.CurrentSession Property

The most recently negotiated session, updated on a successful DiagnosticSessionControlAsync(byte, CancellationToken) and reset to Default after a successful EcuResetAsync(UdsEcuResetType, CancellationToken). Starts at Default because ISO 14229-1 §9.2 guarantees an ECU starts up in the default session.

byte CurrentSession { get; }

Property Value

Byte

IUdsClient.Options Property

The immutable options used at construction.

CanKit.Pro.Uds.UdsClientOptions Options { get; }

Property Value

UdsClientOptions

Methods

IUdsClient.DiagnosticSessionControlAsync(byte, CancellationToken) Method

Sends DiagnosticSessionControl (0x10) with a raw sub-function byte. Convenience for vendor-specific session numbers that are not covered by UdsSessionType.

System.Threading.Tasks.Task<byte[]> DiagnosticSessionControlAsync(byte sessionType, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

sessionType Byte

cancellationToken CancellationToken

Returns

Task<Byte[]>

IUdsClient.DiagnosticSessionControlAsync(UdsSessionType, CancellationToken) Method

Sends DiagnosticSessionControl (0x10, SRS FR-UDS-001) with a named UdsSessionType. Returns the raw parameter bytes echoed back by the ECU (session parameter record, typically 4 bytes carrying P2/P2* server timing).

System.Threading.Tasks.Task<byte[]> DiagnosticSessionControlAsync(CanKit.Pro.Uds.UdsSessionType session, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

session UdsSessionType

cancellationToken CancellationToken

Returns

Task<Byte[]>

IUdsClient.DownloadAsync(byte, byte, ReadOnlyMemory<byte>, ReadOnlyMemory<byte>, ReadOnlyMemory<byte>, CancellationToken) Method

Convenience one-shot download that runs the full 0x34 → N × 0x36 → 0x37 sequence for data. The client negotiates maxNumberOfBlockLength with RequestDownload, then loops TransferDataAsync(byte, ReadOnlyMemory<byte>, CancellationToken) with an automatically-managed block sequence counter (starts at 0x01, increments per block, wraps 0xFF → 0x00), and finally calls RequestTransferExitAsync(ReadOnlyMemory<byte>, CancellationToken).

System.Threading.Tasks.Task DownloadAsync(byte dataFormatIdentifier, byte addressAndLengthFormatIdentifier, System.ReadOnlyMemory<byte> memoryAddress, System.ReadOnlyMemory<byte> memorySize, System.ReadOnlyMemory<byte> data, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

dataFormatIdentifier Byte

addressAndLengthFormatIdentifier Byte

memoryAddress ReadOnlyMemory<Byte>

memorySize ReadOnlyMemory<Byte>

data ReadOnlyMemory<Byte>

cancellationToken CancellationToken

Returns

Task

Exceptions

UdsProtocolException
The ECU reported a maxNumberOfBlockLength of 0 or 1 so no payload byte would fit in a TransferData request, or a chunk validation failed.

IUdsClient.EcuResetAsync(UdsEcuResetType, CancellationToken) Method

Sends ECUReset (0x11, SRS FR-UDS-005) and returns the raw powerDownTime parameter (0..1 bytes) echoed back by the ECU. On success, CurrentSession is reset to Default to match the ECU returning to the default session. Callers should typically wait for the ECU to reboot before issuing further requests.

System.Threading.Tasks.Task<byte[]> EcuResetAsync(CanKit.Pro.Uds.UdsEcuResetType resetType, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

resetType UdsEcuResetType

cancellationToken CancellationToken

Returns

Task<Byte[]>

IUdsClient.ReadDataByIdentifierAsync(IReadOnlyList<ushort>, IReadOnlyDictionary<ushort,int>, CancellationToken) Method

Sends ReadDataByIdentifier (0x22) with more than one DID in a single request (SRS FR-UDS-011, ISO 14229-1 §9.3.4). Returns a dictionary keyed by DID with each requested identifier's raw data-record bytes.

System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyDictionary<ushort,byte[]>> ReadDataByIdentifierAsync(System.Collections.Generic.IReadOnlyList<ushort> dataIdentifiers, System.Collections.Generic.IReadOnlyDictionary<ushort,int> dataRecordLengths, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

dataIdentifiers IReadOnlyList<UInt16>

DIDs to request, in the order they are placed on the wire.

dataRecordLengths IReadOnlyDictionary<UInt16,Int32>

Expected dataRecord length (bytes) for every requested DID. ISO 14229-1 §9.3.4.4 does not encode lengths in the positive response — the client must know them from the ECU's DID definition (ODX/CDD/etc.). Zero-length records are allowed.

cancellationToken CancellationToken

Cancels the wait for the ECU response.

Returns

Task<IReadOnlyDictionary<UInt16,Byte[]>>

Exceptions

ArgumentException
A requested DID has no length entry, or a length is negative.

UdsProtocolException
The ECU response is malformed, truncated, missing a DID, or contains DIDs that were not requested.

IUdsClient.ReadDataByIdentifierAsync(ushort, CancellationToken) Method

Sends ReadDataByIdentifier (0x22, SRS FR-UDS-002) for a single Data Identifier. Returns the raw data-record bytes that followed the DID in the positive response.

System.Threading.Tasks.Task<byte[]> ReadDataByIdentifierAsync(ushort dataIdentifier, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

dataIdentifier UInt16

cancellationToken CancellationToken

Returns

Task<Byte[]>

IUdsClient.RequestDownloadAsync(byte, byte, ReadOnlyMemory<byte>, ReadOnlyMemory<byte>, CancellationToken) Method

Sends RequestDownload (0x34, ISO 14229-1 §14.2, SRS FR-UDS-012). Negotiates a download session with the ECU: the tester declares the payload format (compression / encryption via dataFormatIdentifier) and the target memory range (memoryAddress, memorySize) whose widths are packed in addressAndLengthFormatIdentifier. The ECU replies with the maximum TransferData block length it will accept, wrapped in UdsDownloadResponse.

System.Threading.Tasks.Task<CanKit.Pro.Uds.UdsDownloadResponse> RequestDownloadAsync(byte dataFormatIdentifier, byte addressAndLengthFormatIdentifier, System.ReadOnlyMemory<byte> memoryAddress, System.ReadOnlyMemory<byte> memorySize, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

dataFormatIdentifier Byte

Byte encoding the compression method (high nibble) and encryption method (low nibble); 0x00 means "no compression / no encryption".

addressAndLengthFormatIdentifier Byte

Byte packing the width of memoryAddress (low nibble) and memorySize (high nibble) in bytes. Both widths MUST be in 1..0x0F and MUST match the respective buffer lengths.

memoryAddress ReadOnlyMemory<Byte>

Big-endian target start address.

memorySize ReadOnlyMemory<Byte>

Big-endian target byte count.

cancellationToken CancellationToken

Cancels the wait for the ECU response.

Returns

Task<UdsDownloadResponse>

Exceptions

ArgumentOutOfRangeException
A width nibble in addressAndLengthFormatIdentifier is zero, or does not match the buffer length.

IUdsClient.RequestTransferExitAsync(ReadOnlyMemory<byte>, CancellationToken) Method

Sends RequestTransferExit (0x37, ISO 14229-1 §14.4, SRS FR-UDS-012) to close the current transfer session. transferRequestParameterRecord is an optional vendor-specific record (e.g. checksum) appended after the SID.

System.Threading.Tasks.Task RequestTransferExitAsync(System.ReadOnlyMemory<byte> transferRequestParameterRecord=default(System.ReadOnlyMemory<byte>), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

transferRequestParameterRecord ReadOnlyMemory<Byte>

cancellationToken CancellationToken

Returns

Task

IUdsClient.RequestUploadAsync(byte, byte, ReadOnlyMemory<byte>, ReadOnlyMemory<byte>, CancellationToken) Method

Sends RequestUpload (0x35, ISO 14229-1 §14.1, SRS FR-UDS-012). Mirror of RequestDownloadAsync(byte, byte, ReadOnlyMemory<byte>, ReadOnlyMemory<byte>, CancellationToken) for the tester-reads-from-ECU direction; the returned MaxNumberOfBlockLength constrains the size of TransferData responses the ECU will emit.

System.Threading.Tasks.Task<CanKit.Pro.Uds.UdsUploadResponse> RequestUploadAsync(byte dataFormatIdentifier, byte addressAndLengthFormatIdentifier, System.ReadOnlyMemory<byte> memoryAddress, System.ReadOnlyMemory<byte> memorySize, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

dataFormatIdentifier Byte

addressAndLengthFormatIdentifier Byte

memoryAddress ReadOnlyMemory<Byte>

memorySize ReadOnlyMemory<Byte>

cancellationToken CancellationToken

Returns

Task<UdsUploadResponse>

IUdsClient.RoutineControlAsync(UdsRoutineControlType, ushort, ReadOnlyMemory<byte>, CancellationToken) Method

Sends RoutineControl (0x31, SRS FR-UDS-004). The routine control option record (routineControlOptionRecord) is sent verbatim after the routine identifier; the returned array contains the routine info bytes from the positive response (excluding the echoed sub-function and routine identifier).

System.Threading.Tasks.Task<byte[]> RoutineControlAsync(CanKit.Pro.Uds.UdsRoutineControlType routineType, ushort routineIdentifier, System.ReadOnlyMemory<byte> routineControlOptionRecord=default(System.ReadOnlyMemory<byte>), System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

routineType UdsRoutineControlType

routineIdentifier UInt16

routineControlOptionRecord ReadOnlyMemory<Byte>

cancellationToken CancellationToken

Returns

Task<Byte[]>

IUdsClient.SecurityAccessAsync(byte, Func<byte[],byte[]>, CancellationToken) Method

Runs the ISO 14229-1 §9.4 SecurityAccess (0x27, SRS FR-UDS-006) two-step exchange: 1. Send 0x27 requestSeedLevel, receive the seed bytes. 2. Invoke computeKey synchronously with the seed and the returned key, then send 0x27 sendKeyLevel with the caller-computed key bytes. requestSeedLevel must be an odd byte in 0x01..0x7F and sendKeyLevel = requestSeedLevel + 1 is derived automatically. A zero-length seed (ISO 14229-1 §9.4.5.3 "already unlocked") short-circuits the exchange without invoking computeKey.

System.Threading.Tasks.Task SecurityAccessAsync(byte requestSeedLevel, System.Func<byte[],byte[]> computeKey, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

requestSeedLevel Byte

computeKey Func<Byte[],Byte[]>

cancellationToken CancellationToken

Returns

Task

Exceptions

ArgumentOutOfRangeException
requestSeedLevel is not an odd byte in the range 0x01..0x7F.

ArgumentNullException
computeKey is null.

IUdsClient.SendRawAsync(ReadOnlyMemory<byte>, CancellationToken) Method

Sends the raw request bytes verbatim (starting with the SID) and returns the ECU's raw positive-response bytes (again including the response SID). The same P2/P2* timing and NRC handling apply as for the strongly-typed methods.

System.Threading.Tasks.Task<byte[]> SendRawAsync(System.ReadOnlyMemory<byte> request, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

request ReadOnlyMemory<Byte>

cancellationToken CancellationToken

Returns

Task<Byte[]>

IUdsClient.StartTesterPresentKeepAlive(Nullable<TimeSpan>) Method

Starts a background TesterPresent (0x3E) keep-alive that fires every period (defaults to TesterPresentPeriod) until the returned IDisposable is disposed or the client itself is disposed. The keep-alive uses TesterPresentAsync(bool, CancellationToken) under the hood so it serializes with normal requests through the same request lock; a slow request never causes a stale keep-alive frame to interleave (SRS FR-UDS-007).

System.IDisposable StartTesterPresentKeepAlive(System.Nullable<System.TimeSpan> period=null);

Parameters

period Nullable<TimeSpan>

Override for the send interval; must be positive.

Returns

IDisposable

Exceptions

InvalidOperationException
A keep-alive is already running; call IDisposable.Dispose on the previous handle first.

IUdsClient.TesterPresentAsync(bool, CancellationToken) Method

Sends a single TesterPresent (0x3E, SRS FR-UDS-007). When suppressPositiveResponse is true the ISO 14229-1 §7.5 suppressPositiveResponse bit is set (sub-function 0x80) and the method returns as soon as the request is on the wire — the ECU is expected to stay silent. Otherwise the method awaits the positive response.

System.Threading.Tasks.Task TesterPresentAsync(bool suppressPositiveResponse=true, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

suppressPositiveResponse Boolean

cancellationToken CancellationToken

Returns

Task

IUdsClient.TransferDataAsync(byte, ReadOnlyMemory<byte>, CancellationToken) Method

Sends TransferData (0x36, ISO 14229-1 §14.3, SRS FR-UDS-012) with the caller-supplied block sequence counter and payload chunk. Returns the ECU's transferResponseParameterRecord (the bytes that follow the echoed block sequence counter in the positive response — may be empty). The client validates that the ECU echoes back the exact blockSequenceCounter.

System.Threading.Tasks.Task<byte[]> TransferDataAsync(byte blockSequenceCounter, System.ReadOnlyMemory<byte> data, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

blockSequenceCounter Byte

Per ISO 14229-1 §14.3.2 the counter starts at 0x01 for the first TransferData following RequestDownload/Upload, is incremented on each successful transfer, and wraps from 0xFF back to 0x00.

data ReadOnlyMemory<Byte>

Payload chunk. Total request size (SID + BSC + payload = 2 + data.Length) MUST NOT exceed the ECU's MaxNumberOfBlockLength. May be empty when the ECU is expected to synthesise data (e.g. the upload direction).

cancellationToken CancellationToken

Cancels the wait for the ECU response.

Returns

Task<Byte[]>

IUdsClient.UploadAsync(byte, byte, ReadOnlyMemory<byte>, ReadOnlyMemory<byte>, CancellationToken) Method

Convenience one-shot upload that runs the full 0x35 → N × 0x36 → 0x37 sequence and returns the bytes read from the ECU. The client negotiates with RequestUpload, then loops TransferDataAsync(byte, ReadOnlyMemory<byte>, CancellationToken) with an automatically-managed block sequence counter (starts at 0x01, increments per block, wraps 0xFF → 0x00), concatenating the ECU's transferResponseParameterRecords until memorySize bytes were read, and finally calls RequestTransferExitAsync(ReadOnlyMemory<byte>, CancellationToken).

System.Threading.Tasks.Task<byte[]> UploadAsync(byte dataFormatIdentifier, byte addressAndLengthFormatIdentifier, System.ReadOnlyMemory<byte> memoryAddress, System.ReadOnlyMemory<byte> memorySize, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

dataFormatIdentifier Byte

addressAndLengthFormatIdentifier Byte

memoryAddress ReadOnlyMemory<Byte>

memorySize ReadOnlyMemory<Byte>

cancellationToken CancellationToken

Returns

Task<Byte[]>

Exceptions

UdsProtocolException
The ECU delivered an empty TransferData payload before the declared size was reached, or memorySize exceeds what can reasonably be buffered.

IUdsClient.WriteDataByIdentifierAsync(ushort, ReadOnlyMemory<byte>, CancellationToken) Method

Sends WriteDataByIdentifier (0x2E, SRS FR-UDS-003). Completes successfully when the ECU echoes the DID; the DID echo is validated against the request.

System.Threading.Tasks.Task WriteDataByIdentifierAsync(ushort dataIdentifier, System.ReadOnlyMemory<byte> data, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

dataIdentifier UInt16

data ReadOnlyMemory<Byte>

cancellationToken CancellationToken

Returns

Task