Skip to content

IJ1939Node Interface

One application-layer SAE J1939 node bound to a single physical bus and a single 64-bit J1939Name identity. The node owns the SAE J1939-81 address-claim state (SRS FR-J1939-003/004), routes outbound PGNs through direct 29-bit frames (≤ 8 bytes) or the shared J1939-TP channel (> 8 bytes, SRS FR-J1939-006), and surfaces every inbound application PGN (including Request-PGN, SRS FR-J1939-005) via MessageReceived.

public interface IJ1939Node : System.IDisposable, System.IAsyncDisposable

Implements IDisposable, IAsyncDisposable

Remarks

The node composes on the CanKit.Pro L2 services (ICanBusService for RX demux and TX confirmation, IProtocolActor for single-writer state, DeadlineScheduler for the SAE J1939-81 §4.4.3.3 250 ms arbitration window and periodic-send timing) and never touches vendor-specific SDKs directly.

IDisposable.Dispose is thread-safe and idempotent. Disposal cancels any in-flight ClaimAddressAsync(byte, CancellationToken) or SendAsync(J1939Message, CancellationToken) call and unwinds the underlying subscriptions and transport channel.

Properties

IJ1939Node.Address Property

The node's claimed source address, or null when it has none (NotClaimed / CannotClaim).

System.Nullable<byte> Address { get; }

Property Value

Nullable<Byte>

IJ1939Node.ClaimState Property

Current SAE J1939-81 claim state (SRS FR-J1939-003/004).

CanKit.Pro.J1939.J1939ClaimState ClaimState { get; }

Property Value

J1939ClaimState

IJ1939Node.Name Property

The node's immutable 64-bit SAE J1939-81 NAME (from Name).

CanKit.Pro.Addressing.J1939Name Name { get; }

Property Value

J1939Name

IJ1939Node.Options Property

Node options captured at construction.

CanKit.Pro.J1939.J1939NodeOptions Options { get; }

Property Value

J1939NodeOptions

Methods

IJ1939Node.ClaimAddressAsync(byte, CancellationToken) Method

Runs the SAE J1939-81 address-claim procedure for preferredAddress (SRS FR-J1939-003): 1. Transmit Address Claim (PGN 0xEE00, SA = preferred) carrying the node's NAME. 2. Listen for contending claims within ClaimAnnounceTimeout (default 250 ms). 3. On a losing contest (peer's NAME numerically lower), transition to CannotClaim, broadcast Cannot Claim (SA = 0xFE) per SAE J1939-81 §4.4.3.4 and throw J1939CannotClaimException (SRS FR-J1939-004).

System.Threading.Tasks.Task ClaimAddressAsync(byte preferredAddress, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

preferredAddress Byte

cancellationToken CancellationToken

Returns

Task

Exceptions

J1939CannotClaimException
The preferred address was lost to a higher-priority NAME and no fallback was available.

IJ1939Node.RequestPgnAsync(uint, byte, CancellationToken) Method

Sends a Request-PGN (SAE J1939-21 PGN 0xEA00, SRS FR-J1939-005). The 3-byte payload carries requestedPgn little-endian; the request itself is a direct single-frame PGN. A destination of 0xFF makes the request global (every node responds with its usual PGN); any other value targets a specific ECU.

System.Threading.Tasks.Task RequestPgnAsync(uint requestedPgn, byte destinationAddress=byte.MaxValue, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

requestedPgn UInt32

destinationAddress Byte

cancellationToken CancellationToken

Returns

Task

IJ1939Node.SendAsync(J1939Message, CancellationToken) Method

Sends message on the bus (SRS FR-J1939-001/006). Payloads ≤ 8 bytes go as one direct 29-bit CAN frame; larger payloads are broken into a TP.BAM (global destination) or TP.CM (specific destination) session on the shared J1939-TP channel. The task completes when the last frame of the message has been TX-confirmed (single frame) or when the TP session finishes (multi-frame).

System.Threading.Tasks.Task SendAsync(CanKit.Pro.J1939.J1939Message message, System.Threading.CancellationToken cancellationToken=default(System.Threading.CancellationToken));

Parameters

message J1939Message

cancellationToken CancellationToken

Returns

Task

Exceptions

J1939NoAddressException
The node has not yet claimed an address.

IJ1939Node.StartPeriodicSend(J1939Message, TimeSpan) Method

Starts sending message periodically at the given period (SRS FR-J1939-007). Every emission — single-frame and multi-frame alike — is driven by the node's actor / SendAsync loop on top of the L2 DeadlineScheduler. Each iteration re-checks the SAE J1939-81 claim state through SendAsync(J1939Message, CancellationToken)'s pre-flight gate, so a concurrent address loss stops wire traffic automatically and a subsequent successful claim (possibly on a different SA) resumes it — the emitted 29-bit ID is composed from the currently-claimed SA on every tick. Send failures are surfaced via BackgroundExceptionOccurred. Disposing the returned handle stops the schedule. Multiple concurrent schedules for the same PGN are allowed (callers may want to send the same PGN to two destinations). The caller supplies period; mapping application PGNs to their SAE J1939-71 standard rate is the caller's responsibility.

Payload snapshot:message's payload is snapshotted into an owned buffer when this method returns and every emission transmits that snapshot. In-place mutation of the caller's original buffer after StartPeriodicSend is NOT observed on the wire — this matches J1939Message's "payload is copied by the sender" contract (Bugbot 3604566680). To change the transmitted data, dispose the returned handle and start a fresh schedule with a new J1939Message.

System.IDisposable StartPeriodicSend(CanKit.Pro.J1939.J1939Message message, System.TimeSpan period);

Parameters

message J1939Message

period TimeSpan

Returns

IDisposable

Exceptions

J1939NoAddressException
The node has not yet claimed an address (matches SendAsync(J1939Message, CancellationToken)'s pre-flight gate).

Events

IJ1939Node.AddressClaimChanged Event

Raised whenever the node's ClaimState transitions (a claim starts, succeeds, is lost, or Cannot Claim is broadcast).

event EventHandler<J1939ClaimEventArgs>? AddressClaimChanged;

Event Type

EventHandler<J1939ClaimEventArgs>

IJ1939Node.BackgroundExceptionOccurred Event

Raised when a background failure (subscription faulted, actor exception, event-handler throw, TP channel background error) must be surfaced to the application.

event EventHandler<Exception>? BackgroundExceptionOccurred;

Event Type

EventHandler<Exception>

IJ1939Node.MessageReceived Event

Raised on the actor's loop thread for every inbound application PGN — both direct single-frame PGNs and reassembled J1939-TP payloads (SRS FR-J1939-001/006). Request PGN (0xEA00) messages are also surfaced here so applications can respond in kind (SRS FR-J1939-005). Handlers must not throw; a throwing handler is caught and reported via BackgroundExceptionOccurred.

event EventHandler<J1939Message>? MessageReceived;

Event Type

EventHandler<J1939Message>