-
Add addressing on top of CAN (destination address & broadcast)
-
Any (max 1780) length packets. Packets of 9 or more use Transport Protocol (fragmentation) Such packets use different CANid for the same PGN.
-
only 29bit, non-RTR CAN frames
-
CAN id is composed of
- 0..8: SA (source address)
- 9..26:
- PDU1: PGN+DA (destination address)
- PDU2: PGN
- 27..29: PRIO
-
SA / DA may be dynamically assigned via j1939-81 Fixed rules of precedence in Specification, no master necessary
J1939 is just another protocol that fits in the Berkely sockets.
socket(AF_CAN, SOCK_DGRAM, CAN_J1939)
SA, DA & PGN are used, not CAN id.
Berkeley socket API is used to communicate these to userspace:
- SA+PGN is put in sockname (getsockname)
- DA+PGN is put in peername (getpeername) PGN is put in both structs
PRIO is a datalink property, and irrelevant for interpretation Therefore, PRIO is not in sockname or peername.
The data that is [recv][recvfrom] or [send][sendto] is the real payload. Unlike CAN_RAW, where addressing info is data.
J1939 handles packets of 8+ bytes with Transport Protocol fragmentation transparently. No fixed data size is necessary.
send(sock, data, 8, 0);
will emit a single CAN frame.
send(sock, data, 9, 0);
will use fragmentation, emitting 1+ CAN frames.
- socket
- bind / connect
- recvfrom / sendto
- getsockname / getpeername
struct sockaddr_can {
sa_family_t can_family;
int can_ifindex;
union {
struct {
__u64 name;
__u32 pgn;
__u8 addr;
} j1939;
} can_addr;
}
-
can_addr.j1939.pgn is PGN
-
can_addr.j1939.addr & can_addr.j1939.name determine the ECU
-
receiving address information, addr is always set, name is set when available.
-
When providing address information, name != 0 indicates dynamic addressing
-