CanKit.Pro.J1939
1.2.3
dotnet add package CanKit.Pro.J1939 --version 1.2.3
NuGet\Install-Package CanKit.Pro.J1939 -Version 1.2.3
<PackageReference Include="CanKit.Pro.J1939" Version="1.2.3" />
<PackageVersion Include="CanKit.Pro.J1939" Version="1.2.3" />
<PackageReference Include="CanKit.Pro.J1939" />
paket add CanKit.Pro.J1939 --version 1.2.3
#r "nuget: CanKit.Pro.J1939, 1.2.3"
#:package CanKit.Pro.J1939@1.2.3
#addin nuget:?package=CanKit.Pro.J1939&version=1.2.3
#tool nuget:?package=CanKit.Pro.J1939&version=1.2.3
CanKit.Pro.J1939
Application-layer SAE J1939 node for CanKit.Pro, covering SRS FR-J1939-001..006 (Must) and FR-J1939-007 (Should).
What it does
- PGN send/receive with 29-bit Priority / PF / PS / SA encoding &
decoding via
CanKit.Pro.Addressing.J1939Id(FR-J1939-001). - SPN extraction from PGN payloads with configurable resolution and
offset (little-endian, 1..64-bit fields) via
J1939Spn(FR-J1939-002). - Address claiming (PGN 0xEE00) with SAE J1939-81 §4.4.3 NAME arbitration and the 250 ms announcement window (FR-J1939-003).
- Address-Claim fallback (FR-J1939-004): after losing the preferred
address to a higher-priority NAME the node scans the arbitrary address
field (0x80..0xF7, wrapping once) and only broadcasts Cannot Claim
(PGN 0xEE00 from SA = 0xFE) when the field is exhausted. Governed by
J1939NodeOptions.EnableArbitraryAddressClaiming(default: derived from the NAME's Arbitrary Address Capable bit). - Request-PGN (PGN 0xEA00) send and receive (FR-J1939-005).
- Auto-routing to J1939-TP for payloads > 8 bytes; direct 29-bit frames for payloads ≤ 8 bytes (FR-J1939-006).
- Periodic PGN send (FR-J1939-007): every periodic PGN — single-
frame and multi-frame alike — is emitted on a fixed-rate grid anchored
on the L2
DeadlineScheduler(t0 + n × period), so the long-run rate does not drift by the per-emission send time; ticks whose previous emission is still in flight are skipped and ticks that fell behind are coalesced. The schedule snapshots the caller's payload into an owned buffer at Start-time and handsSendAsyncthe same immutable bytes on every tick, so in-place edits to the caller buffer afterStartPeriodicSendare not observable on the wire.SendAsync's pre-flight claim gate runs on every emission, so the schedule stops putting frames on the wire as soon as the node leavesClaimedand resumes automatically after a fresh claim — the emitted 29-bit ID is composed from the currently-claimed SA. Send failures (includingJ1939NoAddressExceptionfrom the claim gate) are surfaced viaBackgroundExceptionOccurred. The caller supplies the transmit period; mapping application PGNs to their SAE J1939-71 standard rate is the caller's responsibility (no PGN rate catalog is embedded). A native L1IPeriodicTxoptimization for single-frame PGNs remains a follow-up — its L1 error-propagation blocker is resolved (IPeriodicTx.Faulted).
Architecture
- Composes strictly on L2 (
CanKit.Pro.RawCan.ICanBusService,CanKit.Pro.Actor.IProtocolActor,CanKit.Pro.Reliability.DeadlineScheduler) — no vendor SDK dependency. - Uses
CanKit.Pro.Addressinghelpers (J1939Id,J1939Pgn,J1939Fields,J1939Name); the node never reimplements ID / PGN / NAME math. - Delegates multi-frame transport to
CanKit.Pro.J1939Tpper FR-J1939-006. - Follows the same factory / interface / impl pattern as
CanKit.Pro.UdsandCanKit.Pro.J1939Tp.
Usage
var options = new J1939NodeOptions(
new J1939Name(
identityNumber: 0x12345,
manufacturerCode: 0x0AB,
ecuInstance: 0, functionInstance: 0, function: 0x81,
reserved: false,
vehicleSystem: 0, vehicleSystemInstance: 0,
industryGroup: 0, arbitraryAddressCapable: false));
using var bus = CanBus.Open("virtual://demo/0", cfg => cfg.SetProtocolMode(CanProtocolMode.Can20));
using var node = J1939Node.Open(bus, options);
await node.ClaimAddressAsync(preferredAddress: 0x11);
// Direct single-frame PGN (≤ 8 bytes).
await node.SendAsync(new J1939Message(pgn: 0xFEF0, payload: new byte[] { 1, 2, 3, 4 }));
// Multi-frame PGN (> 8 bytes) auto-routes through J1939-TP.
await node.SendAsync(new J1939Message(pgn: 0xFECA, payload: new byte[64]));
// Request-PGN.
await node.RequestPgnAsync(requestedPgn: 0xFEF1, destinationAddress: 0xFF);
// SPN extraction (little-endian, physical = raw * resolution + offset).
node.MessageReceived += (_, msg) =>
{
double speed = J1939Spn.Extract(msg.Payload.Span,
byteOffset: 3, startBit: 0, bitLength: 16,
resolution: 0.125, offset: 0.0);
};
Status
Published on nuget.org since 1.2.0.
Install
dotnet add package CanKit.Pro.J1939
# 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.J1939Tp, 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.2.3)
- CanKit.Pro.Addressing (>= 1.2.3)
- CanKit.Pro.J1939Tp (>= 1.2.3)
- CanKit.Pro.RawCan (>= 1.2.3)
- CanKit.Pro.Reliability (>= 1.2.3)
- 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.2.3)
- CanKit.Pro.Addressing (>= 1.2.3)
- CanKit.Pro.J1939Tp (>= 1.2.3)
- CanKit.Pro.RawCan (>= 1.2.3)
- CanKit.Pro.Reliability (>= 1.2.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|