CanKit.Pro.J1939Tp
1.3.0
dotnet add package CanKit.Pro.J1939Tp --version 1.3.0
NuGet\Install-Package CanKit.Pro.J1939Tp -Version 1.3.0
<PackageReference Include="CanKit.Pro.J1939Tp" Version="1.3.0" />
<PackageVersion Include="CanKit.Pro.J1939Tp" Version="1.3.0" />
<PackageReference Include="CanKit.Pro.J1939Tp" />
paket add CanKit.Pro.J1939Tp --version 1.3.0
#r "nuget: CanKit.Pro.J1939Tp, 1.3.0"
#:package CanKit.Pro.J1939Tp@1.3.0
#addin nuget:?package=CanKit.Pro.J1939Tp&version=1.3.0
#tool nuget:?package=CanKit.Pro.J1939Tp&version=1.3.0
CanKit.Pro.J1939Tp
SAE J1939-21 Transport Protocol (TP) for CanKit.Pro. Implements both flavors of the J1939-21 §5.10 transport service:
Status: 1.0.0 – 1.2.3 are withdrawn from nuget.org — they were published as stable before
the API had been reviewed. 1.3.0 will be the first release whose API is stable; until it is
tagged there is no listed version to install, so the dotnet add package line below resolves
nothing and the withdrawn releases come back only on an exact version pin. The public surface
can still change until then. See Versioning.
What is validated, and what is not
Validated: TP.BAM and TP.CM sessions, the T1–T4 timers, Connection Abort codes and retransmission, by the test suite in tests/CanKit.Pro.Tests, between instances of this implementation over CanKit.Adapter.Virtual, directly or through a controllable bus double.
Not validated: Interoperation with third-party J1939 nodes and J1939-21 conformance testing. Nothing in this package has run against real CAN hardware, a conformance tester or a third-party implementation: the test project references CanKit.Adapter.Virtual and no hardware adapter.
- TP.BAM (Broadcast Announce Message) — one sender pushes an up-to-1785-byte PDU to every node on the bus, no acknowledgement (FR-TP-030).
- TP.CM (Connection Mode: RTS / CTS / EndOfMsgAck / Connection Abort) — point-to-point, with block-size negotiation and end-of-message acknowledgement (FR-TP-031).
TP.DT (Data Transfer) frames carry the segmented payload for both flavors, sequence-numbered from 1 (FR-TP-033). Every session runs on its own actor-owned state and its own set of IDeadlines (T1, T2, T3, T4 — FR-TP-032), so multiple sessions can execute in parallel over the same physical bus (FR-TP-034/035) without interfering with each other.
The timers carry J1939-21 §5.10.2.4's meanings: T1 (750 ms) between TP.DTs at the receiver, T2 (1250 ms) from the receiver's CTS to the first TP.DT of the block, T3 (1250 ms) at the originator for the response it is owed — CTS after RTS, the next CTS after a block, EndOfMsgAck after the last packet — and T4 (1050 ms) after a CTS(0) hold. Tr (200 ms) is the time a node has to send a response, not a timer a peer is held to, so there is no option for it (#31); Th (500 ms), the holding time between two CTS(0) messages, is not used by this stack, which sends no CTS(0), so there is no option for it either — the BAM inter-packet spacing of §5.10.3 is BamPacketSpacing, named Th before #144. Connection Abort carries table 7's reason codes and nothing outside the table (J1939TpAbortReason), so a peer stack reads the abort as what happened (#33). A CTS that asks for a packet already sent is served, up to MaxRetransmitRequests (default 2) times per session, after which reason 5 goes out; a PDU1 PGN in a TP.CM is read with its low byte cleared, so a stack that writes the destination address there still reaches the session; and an RTS allowing no packet per CTS opens no session (#58).
Sends are serialized per destination: a send whose destination is busy waits behind the one on the wire, and at most MaxQueuedSendsPerDestination (default 8, counting sends the channel has accepted but not yet started; every BAM goes to the global address, so this bounds the waiting BAMs too) may wait per destination. One more faults at the call, before anything is queued, with J1939TpSendRejectedException instead of growing memory and latency against a peer that answers slowly or never (#204). A queued send has no deadline of its own — a peer may legitimately hold the session ahead of it with CTS(0) — so cancel its token to bound the wait; a cancelled send leaves the queue at once.
The channel ships on nuget.org alongside the other CanKit.Pro.* L2/L3 building blocks. It re-uses:
CanKit.Pro.RawCan— oneICanBusServiceper channel to demultiplex the TP.CM / TP.DT frames back out of the shared bus stream and to confirm outbound frames.CanKit.Pro.Actor— oneIProtocolActormailbox for single-writer session state.CanKit.Pro.Reliability—IDeadlineSchedulerfor T1/T2/T3/T4 and the BAM packet spacing, cancelled/re-armed on the actor's loop.CanKit.Pro.Addressing—J1939Id/J1939Pgnfor composing the TP.CM (PGN 0xEC00) and TP.DT (PGN 0xEB00) 29-bit IDs.
Basic usage
using CanKit.Abstractions.API.Can;
using CanKit.Core;
using CanKit.Pro.J1939Tp;
// One bus, two nodes on their own source addresses.
using var bus = CanBus.Open("virtual://demo/0",
cfg => cfg.SetProtocolMode(CanProtocolMode.Can20).Baud(500_000));
using var sender = J1939Tp.Open(bus, sourceAddress: 0x01);
using var receiver = J1939Tp.Open(bus, sourceAddress: 0x02);
// TP.BAM: broadcast to every node.
await sender.SendBamAsync(pgn: 0xFECA, payload: new byte[100]);
// TP.CM: point-to-point with RTS/CTS/EOM.
await sender.SendCmAsync(pgn: 0xFECB, destinationAddress: 0x02, payload: new byte[300]);
var received = await receiver.ReceiveAsync();
// received.Pgn / received.SourceAddress / received.DestinationAddress / received.Payload
Coverage
| Requirement | Status |
|---|---|
| FR-TP-030 (TP.BAM send/receive) | Yes |
| FR-TP-031 (TP.CM RTS/CTS/EndOfMsgAck) | Yes |
| FR-TP-032 (T1/T2/T3/T4 via DeadlineScheduler, Connection Abort) | Yes |
| FR-TP-033 (BAM and CM told apart by PGN, TP.DT reassembly, SN 1..N) | Yes |
| FR-TP-034 (parallel sessions on shared bus) | Yes |
| FR-TP-035 (multiple concurrent TP.CM peers) | Yes |
Install
dotnet add package CanKit.Pro.J1939Tp
# plus a CanKit adapter for the hardware you actually talk to, e.g.
dotnet add package CanKit.Adapter.Virtual # loopback, no hardware
Dependencies: CanKit.Abstractions, CanKit.Pro.Actor, CanKit.Pro.Addressing, CanKit.Pro.RawCan, CanKit.Pro.Reliability.
Part of CanKit.Pro — higher CAN protocol layers built on top of CanKit, which is consumed as a NuGet package rather than forked.
License
MIT — see LICENSE. CanKit itself is a separate project licensed under Apache-2.0; see THIRD-PARTY-NOTICES.md.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- CanKit.Abstractions (>= 0.5.6)
- CanKit.Pro.Actor (>= 1.3.0)
- CanKit.Pro.Addressing (>= 1.3.0)
- CanKit.Pro.RawCan (>= 1.3.0)
- CanKit.Pro.Reliability (>= 1.3.0)
- Microsoft.Bcl.AsyncInterfaces (>= 10.0.12)
- System.Memory (>= 4.6.3)
- System.Threading.Channels (>= 10.0.12)
-
net10.0
- CanKit.Abstractions (>= 0.5.6)
- CanKit.Pro.Actor (>= 1.3.0)
- CanKit.Pro.Addressing (>= 1.3.0)
- CanKit.Pro.RawCan (>= 1.3.0)
- CanKit.Pro.Reliability (>= 1.3.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on CanKit.Pro.J1939Tp:
| Package | Downloads |
|---|---|
|
CanKit.Pro.J1939
SAE J1939 application-layer node for CanKit.Pro: PGN send/receive with 29-bit Priority/PF/PS/SA encode/decode, SPN scale/offset extraction, PGN 0xEE00 Address Claiming with NAME arbitration (including Cannot-Claim), PGN 0xEA00 Request-PGN, and automatic multi-frame routing through CanKit.Pro.J1939Tp for payloads > 8 bytes. Composes on the CanKit.Pro L2 services (RawCan demux, TX-confirm, Actor, Reliability deadlines) with no vendor-SDK dependency. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.3.0 | 359 | 9/30/2026 |