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