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.
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).
Property Value¶
IJ1939Node.ClaimState Property¶
Current SAE J1939-81 claim state (SRS FR-J1939-003/004).
Property Value¶
IJ1939Node.Name Property¶
The node's immutable 64-bit SAE J1939-81 NAME (from Name).
Property Value¶
IJ1939Node.Options Property¶
Node options captured at construction.
Property Value¶
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¶
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¶
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¶
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¶
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 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 Type¶
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.