The j1939 authors | 9d71dd0 | 2018-10-08 11:48:36 +0200 | [diff] [blame] | 1 | .. SPDX-License-Identifier: (GPL-2.0 OR MIT) |
| 2 | |
| 3 | =================== |
| 4 | J1939 Documentation |
| 5 | =================== |
| 6 | |
| 7 | Overview / What Is J1939 |
| 8 | ======================== |
| 9 | |
| 10 | SAE J1939 defines a higher layer protocol on CAN. It implements a more |
| 11 | sophisticated addressing scheme and extends the maximum packet size above 8 |
| 12 | bytes. Several derived specifications exist, which differ from the original |
| 13 | J1939 on the application level, like MilCAN A, NMEA2000 and especially |
| 14 | ISO-11783 (ISOBUS). This last one specifies the so-called ETP (Extended |
| 15 | Transport Protocol) which is has been included in this implementation. This |
| 16 | results in a maximum packet size of ((2 ^ 24) - 1) * 7 bytes == 111 MiB. |
| 17 | |
| 18 | Specifications used |
| 19 | ------------------- |
| 20 | |
| 21 | * SAE J1939-21 : data link layer |
| 22 | * SAE J1939-81 : network management |
| 23 | * ISO 11783-6 : Virtual Terminal (Extended Transport Protocol) |
| 24 | |
| 25 | .. _j1939-motivation: |
| 26 | |
| 27 | Motivation |
| 28 | ========== |
| 29 | |
| 30 | Given the fact there's something like SocketCAN with an API similar to BSD |
| 31 | sockets, we found some reasons to justify a kernel implementation for the |
| 32 | addressing and transport methods used by J1939. |
| 33 | |
| 34 | * **Addressing:** when a process on an ECU communicates via J1939, it should |
| 35 | not necessarily know its source address. Although at least one process per |
| 36 | ECU should know the source address. Other processes should be able to reuse |
| 37 | that address. This way, address parameters for different processes |
| 38 | cooperating for the same ECU, are not duplicated. This way of working is |
| 39 | closely related to the UNIX concept where programs do just one thing, and do |
| 40 | it well. |
| 41 | |
| 42 | * **Dynamic addressing:** Address Claiming in J1939 is time critical. |
| 43 | Furthermore data transport should be handled properly during the address |
| 44 | negotiation. Putting this functionality in the kernel eliminates it as a |
| 45 | requirement for _every_ user space process that communicates via J1939. This |
| 46 | results in a consistent J1939 bus with proper addressing. |
| 47 | |
| 48 | * **Transport:** both TP & ETP reuse some PGNs to relay big packets over them. |
| 49 | Different processes may thus use the same TP & ETP PGNs without actually |
| 50 | knowing it. The individual TP & ETP sessions _must_ be serialized |
| 51 | (synchronized) between different processes. The kernel solves this problem |
| 52 | properly and eliminates the serialization (synchronization) as a requirement |
| 53 | for _every_ user space process that communicates via J1939. |
| 54 | |
| 55 | J1939 defines some other features (relaying, gateway, fast packet transport, |
| 56 | ...). In-kernel code for these would not contribute to protocol stability. |
| 57 | Therefore, these parts are left to user space. |
| 58 | |
| 59 | The J1939 sockets operate on CAN network devices (see SocketCAN). Any J1939 |
| 60 | user space library operating on CAN raw sockets will still operate properly. |
| 61 | Since such library does not communicate with the in-kernel implementation, care |
| 62 | must be taken that these two do not interfere. In practice, this means they |
| 63 | cannot share ECU addresses. A single ECU (or virtual ECU) address is used by |
| 64 | the library exclusively, or by the in-kernel system exclusively. |
| 65 | |
| 66 | J1939 concepts |
| 67 | ============== |
| 68 | |
| 69 | PGN |
| 70 | --- |
| 71 | |
| 72 | The PGN (Parameter Group Number) is a number to identify a packet. The PGN |
| 73 | is composed as follows: |
| 74 | 1 bit : Reserved Bit |
| 75 | 1 bit : Data Page |
| 76 | 8 bits : PF (PDU Format) |
| 77 | 8 bits : PS (PDU Specific) |
| 78 | |
| 79 | In J1939-21 distinction is made between PDU1 format (where PF < 240) and PDU2 |
| 80 | format (where PF >= 240). Furthermore, when using PDU2 format, the PS-field |
| 81 | contains a so-called Group Extension, which is part of the PGN. When using PDU2 |
| 82 | format, the Group Extension is set in the PS-field. |
| 83 | |
| 84 | On the other hand, when using PDU1 format, the PS-field contains a so-called |
| 85 | Destination Address, which is _not_ part of the PGN. When communicating a PGN |
| 86 | from user space to kernel (or visa versa) and PDU2 format is used, the PS-field |
| 87 | of the PGN shall be set to zero. The Destination Address shall be set |
| 88 | elsewhere. |
| 89 | |
| 90 | Regarding PGN mapping to 29-bit CAN identifier, the Destination Address shall |
| 91 | be get/set from/to the appropriate bits of the identifier by the kernel. |
| 92 | |
| 93 | |
| 94 | Addressing |
| 95 | ---------- |
| 96 | |
| 97 | Both static and dynamic addressing methods can be used. |
| 98 | |
| 99 | For static addresses, no extra checks are made by the kernel, and provided |
| 100 | addresses are considered right. This responsibility is for the OEM or system |
| 101 | integrator. |
| 102 | |
| 103 | For dynamic addressing, so-called Address Claiming, extra support is foreseen |
| 104 | in the kernel. In J1939 any ECU is known by it's 64-bit NAME. At the moment of |
| 105 | a successful address claim, the kernel keeps track of both NAME and source |
| 106 | address being claimed. This serves as a base for filter schemes. By default, |
| 107 | packets with a destination that is not locally, will be rejected. |
| 108 | |
| 109 | Mixed mode packets (from a static to a dynamic address or vice versa) are |
| 110 | allowed. The BSD sockets define separate API calls for getting/setting the |
| 111 | local & remote address and are applicable for J1939 sockets. |
| 112 | |
| 113 | Filtering |
| 114 | --------- |
| 115 | |
| 116 | J1939 defines white list filters per socket that a user can set in order to |
| 117 | receive a subset of the J1939 traffic. Filtering can be based on: |
| 118 | |
| 119 | * SA |
| 120 | * SOURCE_NAME |
| 121 | * PGN |
| 122 | |
| 123 | When multiple filters are in place for a single socket, and a packet comes in |
| 124 | that matches several of those filters, the packet is only received once for |
| 125 | that socket. |
| 126 | |
| 127 | How to Use J1939 |
| 128 | ================ |
| 129 | |
| 130 | API Calls |
| 131 | --------- |
| 132 | |
| 133 | On CAN, you first need to open a socket for communicating over a CAN network. |
| 134 | To use J1939, #include <linux/can/j1939.h>. From there, <linux/can.h> will be |
| 135 | included too. To open a socket, use: |
| 136 | |
| 137 | .. code-block:: C |
| 138 | |
| 139 | s = socket(PF_CAN, SOCK_DGRAM, CAN_J1939); |
| 140 | |
| 141 | J1939 does use SOCK_DGRAM sockets. In the J1939 specification, connections are |
| 142 | mentioned in the context of transport protocol sessions. These still deliver |
| 143 | packets to the other end (using several CAN packets). SOCK_STREAM is not |
| 144 | supported. |
| 145 | |
| 146 | After the successful creation of the socket, you would normally use the bind(2) |
| 147 | and/or connect(2) system call to bind the socket to a CAN interface. After |
| 148 | binding and/or connecting the socket, you can read(2) and write(2) from/to the |
| 149 | socket or use send(2), sendto(2), sendmsg(2) and the recv*() counterpart |
| 150 | operations on the socket as usual. There are also J1939 specific socket options |
| 151 | described below. |
| 152 | |
| 153 | In order to send data, a bind(2) must have been successful. bind(2) assigns a |
| 154 | local address to a socket. |
| 155 | |
| 156 | Different from CAN is that the payload data is just the data that get send, |
| 157 | without it's header info. The header info is derived from the sockaddr supplied |
| 158 | to bind(2), connect(2), sendto(2) and recvfrom(2). A write(2) with size 4 will |
| 159 | result in a packet with 4 bytes. |
| 160 | |
| 161 | The sockaddr structure has extensions for use with J1939 as specified below: |
| 162 | |
| 163 | .. code-block:: C |
| 164 | |
| 165 | struct sockaddr_can { |
| 166 | sa_family_t can_family; |
| 167 | int can_ifindex; |
| 168 | union { |
| 169 | struct { |
| 170 | __u64 name; |
| 171 | /* pgn: |
| 172 | * 8 bit: PS in PDU2 case, else 0 |
| 173 | * 8 bit: PF |
| 174 | * 1 bit: DP |
| 175 | * 1 bit: reserved |
| 176 | */ |
| 177 | __u32 pgn; |
| 178 | __u8 addr; |
| 179 | } j1939; |
| 180 | } can_addr; |
| 181 | } |
| 182 | |
| 183 | can_family & can_ifindex serve the same purpose as for other SocketCAN sockets. |
| 184 | |
| 185 | can_addr.j1939.pgn specifies the PGN (max 0x3ffff). Individual bits are |
| 186 | specified above. |
| 187 | |
| 188 | can_addr.j1939.name contains the 64-bit J1939 NAME. |
| 189 | |
| 190 | can_addr.j1939.addr contains the address. |
| 191 | |
| 192 | The bind(2) system call assigns the local address, i.e. the source address when |
| 193 | sending packages. If a PGN during bind(2) is set, it's used as a RX filter. |
| 194 | I.e. only packets with a matching PGN are received. If an ADDR or NAME is set |
| 195 | it is used as a receive filter, too. It will match the destination NAME or ADDR |
| 196 | of the incoming packet. The NAME filter will work only if appropriate Address |
| 197 | Claiming for this name was done on the CAN bus and registered/cached by the |
| 198 | kernel. |
| 199 | |
| 200 | On the other hand connect(2) assigns the remote address, i.e. the destination |
| 201 | address. The PGN from connect(2) is used as the default PGN when sending |
| 202 | packets. If ADDR or NAME is set it will be used as the default destination ADDR |
| 203 | or NAME. Further a set ADDR or NAME during connect(2) is used as a receive |
| 204 | filter. It will match the source NAME or ADDR of the incoming packet. |
| 205 | |
| 206 | Both write(2) and send(2) will send a packet with local address from bind(2) and |
| 207 | the remote address from connect(2). Use sendto(2) to overwrite the destination |
| 208 | address. |
| 209 | |
| 210 | If can_addr.j1939.name is set (!= 0) the NAME is looked up by the kernel and |
| 211 | the corresponding ADDR is used. If can_addr.j1939.name is not set (== 0), |
| 212 | can_addr.j1939.addr is used. |
| 213 | |
| 214 | When creating a socket, reasonable defaults are set. Some options can be |
| 215 | modified with setsockopt(2) & getsockopt(2). |
| 216 | |
| 217 | RX path related options: |
| 218 | |
| 219 | - SO_J1939_FILTER - configure array of filters |
| 220 | - SO_J1939_PROMISC - disable filters set by bind(2) and connect(2) |
| 221 | |
| 222 | By default no broadcast packets can be send or received. To enable sending or |
| 223 | receiving broadcast packets use the socket option SO_BROADCAST: |
| 224 | |
| 225 | .. code-block:: C |
| 226 | |
| 227 | int value = 1; |
| 228 | setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value)); |
| 229 | |
| 230 | The following diagram illustrates the RX path: |
| 231 | |
| 232 | .. code:: |
| 233 | |
| 234 | +--------------------+ |
| 235 | | incoming packet | |
| 236 | +--------------------+ |
| 237 | | |
| 238 | V |
| 239 | +--------------------+ |
| 240 | | SO_J1939_PROMISC? | |
| 241 | +--------------------+ |
| 242 | | | |
| 243 | no | | yes |
| 244 | | | |
| 245 | .---------' `---------. |
| 246 | | | |
| 247 | +---------------------------+ | |
| 248 | | bind() + connect() + | | |
| 249 | | SOCK_BROADCAST filter | | |
| 250 | +---------------------------+ | |
| 251 | | | |
| 252 | |<---------------------' |
| 253 | V |
| 254 | +---------------------------+ |
| 255 | | SO_J1939_FILTER | |
| 256 | +---------------------------+ |
| 257 | | |
| 258 | V |
| 259 | +---------------------------+ |
| 260 | | socket recv() | |
| 261 | +---------------------------+ |
| 262 | |
| 263 | TX path related options: |
| 264 | SO_J1939_SEND_PRIO - change default send priority for the socket |
| 265 | |
| 266 | Message Flags during send() and Related System Calls |
| 267 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 268 | |
| 269 | send(2), sendto(2) and sendmsg(2) take a 'flags' argument. Currently |
| 270 | supported flags are: |
| 271 | |
| 272 | * MSG_DONTWAIT, i.e. non-blocking operation. |
| 273 | |
| 274 | recvmsg(2) |
Adam Zerella | c5f75a1 | 2019-10-01 21:16:58 +1000 | [diff] [blame] | 275 | ^^^^^^^^^^ |
The j1939 authors | 9d71dd0 | 2018-10-08 11:48:36 +0200 | [diff] [blame] | 276 | |
| 277 | In most cases recvmsg(2) is needed if you want to extract more information than |
| 278 | recvfrom(2) can provide. For example package priority and timestamp. The |
| 279 | Destination Address, name and packet priority (if applicable) are attached to |
| 280 | the msghdr in the recvmsg(2) call. They can be extracted using cmsg(3) macros, |
| 281 | with cmsg_level == SOL_J1939 && cmsg_type == SCM_J1939_DEST_ADDR, |
| 282 | SCM_J1939_DEST_NAME or SCM_J1939_PRIO. The returned data is a uint8_t for |
| 283 | priority and dst_addr, and uint64_t for dst_name. |
| 284 | |
| 285 | .. code-block:: C |
| 286 | |
| 287 | uint8_t priority, dst_addr; |
| 288 | uint64_t dst_name; |
| 289 | |
| 290 | for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { |
| 291 | switch (cmsg->cmsg_level) { |
| 292 | case SOL_CAN_J1939: |
| 293 | if (cmsg->cmsg_type == SCM_J1939_DEST_ADDR) |
| 294 | dst_addr = *CMSG_DATA(cmsg); |
| 295 | else if (cmsg->cmsg_type == SCM_J1939_DEST_NAME) |
| 296 | memcpy(&dst_name, CMSG_DATA(cmsg), cmsg->cmsg_len - CMSG_LEN(0)); |
| 297 | else if (cmsg->cmsg_type == SCM_J1939_PRIO) |
| 298 | priority = *CMSG_DATA(cmsg); |
| 299 | break; |
| 300 | } |
| 301 | } |
| 302 | |
| 303 | Dynamic Addressing |
| 304 | ------------------ |
| 305 | |
| 306 | Distinction has to be made between using the claimed address and doing an |
| 307 | address claim. To use an already claimed address, one has to fill in the |
| 308 | j1939.name member and provide it to bind(2). If the name had claimed an address |
| 309 | earlier, all further messages being sent will use that address. And the |
| 310 | j1939.addr member will be ignored. |
| 311 | |
| 312 | An exception on this is PGN 0x0ee00. This is the "Address Claim/Cannot Claim |
| 313 | Address" message and the kernel will use the j1939.addr member for that PGN if |
| 314 | necessary. |
| 315 | |
| 316 | To claim an address following code example can be used: |
| 317 | |
| 318 | .. code-block:: C |
| 319 | |
| 320 | struct sockaddr_can baddr = { |
| 321 | .can_family = AF_CAN, |
| 322 | .can_addr.j1939 = { |
| 323 | .name = name, |
| 324 | .addr = J1939_IDLE_ADDR, |
| 325 | .pgn = J1939_NO_PGN, /* to disable bind() rx filter for PGN */ |
| 326 | }, |
| 327 | .can_ifindex = if_nametoindex("can0"), |
| 328 | }; |
| 329 | |
| 330 | bind(sock, (struct sockaddr *)&baddr, sizeof(baddr)); |
| 331 | |
| 332 | /* for Address Claiming broadcast must be allowed */ |
| 333 | int value = 1; |
| 334 | setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value)); |
| 335 | |
| 336 | /* configured advanced RX filter with PGN needed for Address Claiming */ |
| 337 | const struct j1939_filter filt[] = { |
| 338 | { |
| 339 | .pgn = J1939_PGN_ADDRESS_CLAIMED, |
| 340 | .pgn_mask = J1939_PGN_PDU1_MAX, |
| 341 | }, { |
Marc Kleine-Budde | 8ac9d71 | 2019-11-21 10:47:50 +0100 | [diff] [blame] | 342 | .pgn = J1939_PGN_REQUEST, |
The j1939 authors | 9d71dd0 | 2018-10-08 11:48:36 +0200 | [diff] [blame] | 343 | .pgn_mask = J1939_PGN_PDU1_MAX, |
| 344 | }, { |
| 345 | .pgn = J1939_PGN_ADDRESS_COMMANDED, |
| 346 | .pgn_mask = J1939_PGN_MAX, |
| 347 | }, |
| 348 | }; |
| 349 | |
| 350 | setsockopt(sock, SOL_CAN_J1939, SO_J1939_FILTER, &filt, sizeof(filt)); |
| 351 | |
| 352 | uint64_t dat = htole64(name); |
| 353 | const struct sockaddr_can saddr = { |
| 354 | .can_family = AF_CAN, |
| 355 | .can_addr.j1939 = { |
| 356 | .pgn = J1939_PGN_ADDRESS_CLAIMED, |
| 357 | .addr = J1939_NO_ADDR, |
| 358 | }, |
| 359 | }; |
| 360 | |
| 361 | /* Afterwards do a sendto(2) with data set to the NAME (Little Endian). If the |
| 362 | * NAME provided, does not match the j1939.name provided to bind(2), EPROTO |
| 363 | * will be returned. |
| 364 | */ |
| 365 | sendto(sock, dat, sizeof(dat), 0, (const struct sockaddr *)&saddr, sizeof(saddr)); |
| 366 | |
| 367 | If no-one else contests the address claim within 250ms after transmission, the |
| 368 | kernel marks the NAME-SA assignment as valid. The valid assignment will be kept |
| 369 | among other valid NAME-SA assignments. From that point, any socket bound to the |
| 370 | NAME can send packets. |
| 371 | |
| 372 | If another ECU claims the address, the kernel will mark the NAME-SA expired. |
| 373 | No socket bound to the NAME can send packets (other than address claims). To |
| 374 | claim another address, some socket bound to NAME, must bind(2) again, but with |
| 375 | only j1939.addr changed to the new SA, and must then send a valid address claim |
| 376 | packet. This restarts the state machine in the kernel (and any other |
| 377 | participant on the bus) for this NAME. |
| 378 | |
| 379 | can-utils also include the jacd tool, so it can be used as code example or as |
| 380 | default Address Claiming daemon. |
| 381 | |
| 382 | Send Examples |
| 383 | ------------- |
| 384 | |
| 385 | Static Addressing |
| 386 | ^^^^^^^^^^^^^^^^^ |
| 387 | |
| 388 | This example will send a PGN (0x12300) from SA 0x20 to DA 0x30. |
| 389 | |
| 390 | Bind: |
| 391 | |
| 392 | .. code-block:: C |
| 393 | |
| 394 | struct sockaddr_can baddr = { |
| 395 | .can_family = AF_CAN, |
| 396 | .can_addr.j1939 = { |
| 397 | .name = J1939_NO_NAME, |
| 398 | .addr = 0x20, |
| 399 | .pgn = J1939_NO_PGN, |
| 400 | }, |
| 401 | .can_ifindex = if_nametoindex("can0"), |
| 402 | }; |
| 403 | |
| 404 | bind(sock, (struct sockaddr *)&baddr, sizeof(baddr)); |
| 405 | |
| 406 | Now, the socket 'sock' is bound to the SA 0x20. Since no connect(2) was called, |
| 407 | at this point we can use only sendto(2) or sendmsg(2). |
| 408 | |
| 409 | Send: |
| 410 | |
| 411 | .. code-block:: C |
| 412 | |
| 413 | const struct sockaddr_can saddr = { |
| 414 | .can_family = AF_CAN, |
| 415 | .can_addr.j1939 = { |
| 416 | .name = J1939_NO_NAME; |
| 417 | .pgn = 0x30, |
| 418 | .addr = 0x12300, |
| 419 | }, |
| 420 | }; |
| 421 | |
| 422 | sendto(sock, dat, sizeof(dat), 0, (const struct sockaddr *)&saddr, sizeof(saddr)); |