| .. SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) | 
 |  | 
 | ==================== | 
 | ISO 15765-2 (ISO-TP) | 
 | ==================== | 
 |  | 
 | Overview | 
 | ======== | 
 |  | 
 | ISO 15765-2, also known as ISO-TP, is a transport protocol specifically defined | 
 | for diagnostic communication on CAN. It is widely used in the automotive | 
 | industry, for example as the transport protocol for UDSonCAN (ISO 14229-3) or | 
 | emission-related diagnostic services (ISO 15031-5). | 
 |  | 
 | ISO-TP can be used both on CAN CC (aka Classical CAN) and CAN FD (CAN with | 
 | Flexible Datarate) based networks. It is also designed to be compatible with a | 
 | CAN network using SAE J1939 as data link layer (however, this is not a | 
 | requirement). | 
 |  | 
 | Specifications used | 
 | ------------------- | 
 |  | 
 | * ISO 15765-2:2024 : Road vehicles - Diagnostic communication over Controller | 
 |   Area Network (DoCAN). Part 2: Transport protocol and network layer services. | 
 |  | 
 | Addressing | 
 | ---------- | 
 |  | 
 | In its simplest form, ISO-TP is based on two kinds of addressing modes for the | 
 | nodes connected to the same network: | 
 |  | 
 | * physical addressing is implemented by two node-specific addresses and is used | 
 |   in 1-to-1 communication. | 
 |  | 
 | * functional addressing is implemented by one node-specific address and is used | 
 |   in 1-to-N communication. | 
 |  | 
 | Three different addressing formats can be employed: | 
 |  | 
 | * "normal" : each address is represented simply by a CAN ID. | 
 |  | 
 | * "extended": each address is represented by a CAN ID plus the first byte of | 
 |   the CAN payload; both the CAN ID and the byte inside the payload shall be | 
 |   different between two addresses. | 
 |  | 
 | * "mixed": each address is represented by a CAN ID plus the first byte of | 
 |   the CAN payload; the CAN ID is different between two addresses, but the | 
 |   additional byte is the same. | 
 |  | 
 | Transport protocol and associated frame types | 
 | --------------------------------------------- | 
 |  | 
 | When transmitting data using the ISO-TP protocol, the payload can either fit | 
 | inside one single CAN message or not, also considering the overhead the protocol | 
 | is generating and the optional extended addressing. In the first case, the data | 
 | is transmitted at once using a so-called Single Frame (SF). In the second case, | 
 | ISO-TP defines a multi-frame protocol, in which the sender provides (through a | 
 | First Frame - FF) the PDU length which is to be transmitted and also asks for a | 
 | Flow Control (FC) frame, which provides the maximum supported size of a macro | 
 | data block (``blocksize``) and the minimum time between the single CAN messages | 
 | composing such block (``stmin``). Once this information has been received, the | 
 | sender starts to send frames containing fragments of the data payload (called | 
 | Consecutive Frames - CF), stopping after every ``blocksize``-sized block to wait | 
 | confirmation from the receiver which should then send another Flow Control | 
 | frame to inform the sender about its availability to receive more data. | 
 |  | 
 | How to Use ISO-TP | 
 | ================= | 
 |  | 
 | As with others CAN protocols, the ISO-TP stack support is built into the | 
 | Linux network subsystem for the CAN bus, aka. Linux-CAN or SocketCAN, and | 
 | thus follows the same socket API. | 
 |  | 
 | Creation and basic usage of an ISO-TP socket | 
 | -------------------------------------------- | 
 |  | 
 | To use the ISO-TP stack, ``#include <linux/can/isotp.h>`` shall be used. A | 
 | socket can then be created using the ``PF_CAN`` protocol family, the | 
 | ``SOCK_DGRAM`` type (as the underlying protocol is datagram-based by design) | 
 | and the ``CAN_ISOTP`` protocol: | 
 |  | 
 | .. code-block:: C | 
 |  | 
 |     s = socket(PF_CAN, SOCK_DGRAM, CAN_ISOTP); | 
 |  | 
 | After the socket has been successfully created, ``bind(2)`` shall be called to | 
 | bind the socket to the desired CAN interface; to do so: | 
 |  | 
 | * a TX CAN ID shall be specified as part of the sockaddr supplied to the call | 
 |   itself. | 
 |  | 
 | * a RX CAN ID shall also be specified, unless broadcast flags have been set | 
 |   through socket option (explained below). | 
 |  | 
 | Once bound to an interface, the socket can be read from and written to using | 
 | the usual ``read(2)`` and ``write(2)`` system calls, as well as ``send(2)``, | 
 | ``sendmsg(2)``, ``recv(2)`` and ``recvmsg(2)``. | 
 | Unlike the CAN_RAW socket API, only the ISO-TP data field (the actual payload) | 
 | is sent and received by the userspace application using these calls. The address | 
 | information and the protocol information are automatically filled by the ISO-TP | 
 | stack using the configuration supplied during socket creation. In the same way, | 
 | the stack will use the transport mechanism when required (i.e., when the size | 
 | of the data payload exceeds the MTU of the underlying CAN bus). | 
 |  | 
 | The sockaddr structure used for SocketCAN has extensions for use with ISO-TP, | 
 | as specified below: | 
 |  | 
 | .. code-block:: C | 
 |  | 
 |     struct sockaddr_can { | 
 |         sa_family_t can_family; | 
 |         int         can_ifindex; | 
 |         union { | 
 |             struct { canid_t rx_id, tx_id; } tp; | 
 |         ... | 
 |         } can_addr; | 
 |     } | 
 |  | 
 | * ``can_family`` and ``can_ifindex`` serve the same purpose as for other | 
 |   SocketCAN sockets. | 
 |  | 
 | * ``can_addr.tp.rx_id`` specifies the receive (RX) CAN ID and will be used as | 
 |   a RX filter. | 
 |  | 
 | * ``can_addr.tp.tx_id`` specifies the transmit (TX) CAN ID | 
 |  | 
 | ISO-TP socket options | 
 | --------------------- | 
 |  | 
 | When creating an ISO-TP socket, reasonable defaults are set. Some options can | 
 | be modified with ``setsockopt(2)`` and/or read back with ``getsockopt(2)``. | 
 |  | 
 | General options | 
 | ~~~~~~~~~~~~~~~ | 
 |  | 
 | General socket options can be passed using the ``CAN_ISOTP_OPTS`` optname: | 
 |  | 
 | .. code-block:: C | 
 |  | 
 |     struct can_isotp_options opts; | 
 |     ret = setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_OPTS, &opts, sizeof(opts)) | 
 |  | 
 | where the ``can_isotp_options`` structure has the following contents: | 
 |  | 
 | .. code-block:: C | 
 |  | 
 |     struct can_isotp_options { | 
 |         u32 flags; | 
 |         u32 frame_txtime; | 
 |         u8  ext_address; | 
 |         u8  txpad_content; | 
 |         u8  rxpad_content; | 
 |         u8  rx_ext_address; | 
 |     }; | 
 |  | 
 | * ``flags``: modifiers to be applied to the default behaviour of the ISO-TP | 
 |   stack. Following flags are available: | 
 |  | 
 |   * ``CAN_ISOTP_LISTEN_MODE``: listen only (do not send FC frames); normally | 
 |     used as a testing feature. | 
 |  | 
 |   * ``CAN_ISOTP_EXTEND_ADDR``: use the byte specified in ``ext_address`` as an | 
 |     additional address component. This enables the "mixed" addressing format if | 
 |     used alone, or the "extended" addressing format if used in conjunction with | 
 |     ``CAN_ISOTP_RX_EXT_ADDR``. | 
 |  | 
 |   * ``CAN_ISOTP_TX_PADDING``: enable padding for transmitted frames, using | 
 |     ``txpad_content`` as value for the padding bytes. | 
 |  | 
 |   * ``CAN_ISOTP_RX_PADDING``: enable padding for the received frames, using | 
 |     ``rxpad_content`` as value for the padding bytes. | 
 |  | 
 |   * ``CAN_ISOTP_CHK_PAD_LEN``: check for correct padding length on the received | 
 |     frames. | 
 |  | 
 |   * ``CAN_ISOTP_CHK_PAD_DATA``: check padding bytes on the received frames | 
 |     against ``rxpad_content``; if ``CAN_ISOTP_RX_PADDING`` is not specified, | 
 |     this flag is ignored. | 
 |  | 
 |   * ``CAN_ISOTP_HALF_DUPLEX``: force ISO-TP socket in half duplex mode | 
 |     (that is, transport mechanism can only be incoming or outgoing at the same | 
 |     time, not both). | 
 |  | 
 |   * ``CAN_ISOTP_FORCE_TXSTMIN``: ignore stmin from received FC; normally | 
 |     used as a testing feature. | 
 |  | 
 |   * ``CAN_ISOTP_FORCE_RXSTMIN``: ignore CFs depending on rx stmin; normally | 
 |     used as a testing feature. | 
 |  | 
 |   * ``CAN_ISOTP_RX_EXT_ADDR``: use ``rx_ext_address`` instead of ``ext_address`` | 
 |     as extended addressing byte on the reception path. If used in conjunction | 
 |     with ``CAN_ISOTP_EXTEND_ADDR``, this flag effectively enables the "extended" | 
 |     addressing format. | 
 |  | 
 |   * ``CAN_ISOTP_WAIT_TX_DONE``: wait until the frame is sent before returning | 
 |     from ``write(2)`` and ``send(2)`` calls (i.e., blocking write operations). | 
 |  | 
 |   * ``CAN_ISOTP_SF_BROADCAST``: use 1-to-N functional addressing (cannot be | 
 |     specified alongside ``CAN_ISOTP_CF_BROADCAST``). | 
 |  | 
 |   * ``CAN_ISOTP_CF_BROADCAST``: use 1-to-N transmission without flow control | 
 |     (cannot be specified alongside ``CAN_ISOTP_SF_BROADCAST``). | 
 |     NOTE: this is not covered by the ISO 15765-2 standard. | 
 |  | 
 |   * ``CAN_ISOTP_DYN_FC_PARMS``: enable dynamic update of flow control | 
 |     parameters. | 
 |  | 
 | * ``frame_txtime``: frame transmission time (defined as N_As/N_Ar inside the | 
 |   ISO standard); if ``0``, the default (or the last set value) is used. | 
 |   To set the transmission time to ``0``, the ``CAN_ISOTP_FRAME_TXTIME_ZERO`` | 
 |   macro (equal to 0xFFFFFFFF) shall be used. | 
 |  | 
 | * ``ext_address``: extended addressing byte, used if the | 
 |   ``CAN_ISOTP_EXTEND_ADDR`` flag is specified. | 
 |  | 
 | * ``txpad_content``: byte used as padding value for transmitted frames. | 
 |  | 
 | * ``rxpad_content``: byte used as padding value for received frames. | 
 |  | 
 | * ``rx_ext_address``: extended addressing byte for the reception path, used if | 
 |   the ``CAN_ISOTP_RX_EXT_ADDR`` flag is specified. | 
 |  | 
 | Flow Control options | 
 | ~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 | Flow Control (FC) options can be passed using the ``CAN_ISOTP_RECV_FC`` optname | 
 | to provide the communication parameters for receiving ISO-TP PDUs. | 
 |  | 
 | .. code-block:: C | 
 |  | 
 |     struct can_isotp_fc_options fc_opts; | 
 |     ret = setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_RECV_FC, &fc_opts, sizeof(fc_opts)); | 
 |  | 
 | where the ``can_isotp_fc_options`` structure has the following contents: | 
 |  | 
 | .. code-block:: C | 
 |  | 
 |     struct can_isotp_options { | 
 |         u8 bs; | 
 |         u8 stmin; | 
 |         u8 wftmax; | 
 |     }; | 
 |  | 
 | * ``bs``: blocksize provided in flow control frames. | 
 |  | 
 | * ``stmin``: minimum separation time provided in flow control frames; can | 
 |   have the following values (others are reserved): | 
 |  | 
 |   * 0x00 - 0x7F : 0 - 127 ms | 
 |  | 
 |   * 0xF1 - 0xF9 : 100 us - 900 us | 
 |  | 
 | * ``wftmax``: maximum number of wait frames provided in flow control frames. | 
 |  | 
 | Link Layer options | 
 | ~~~~~~~~~~~~~~~~~~ | 
 |  | 
 | Link Layer (LL) options can be passed using the ``CAN_ISOTP_LL_OPTS`` optname: | 
 |  | 
 | .. code-block:: C | 
 |  | 
 |     struct can_isotp_ll_options ll_opts; | 
 |     ret = setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_LL_OPTS, &ll_opts, sizeof(ll_opts)); | 
 |  | 
 | where the ``can_isotp_ll_options`` structure has the following contents: | 
 |  | 
 | .. code-block:: C | 
 |  | 
 |     struct can_isotp_ll_options { | 
 |         u8 mtu; | 
 |         u8 tx_dl; | 
 |         u8 tx_flags; | 
 |     }; | 
 |  | 
 | * ``mtu``: generated and accepted CAN frame type, can be equal to ``CAN_MTU`` | 
 |   for classical CAN frames or ``CANFD_MTU`` for CAN FD frames. | 
 |  | 
 | * ``tx_dl``: maximum payload length for transmitted frames, can have one value | 
 |   among: 8, 12, 16, 20, 24, 32, 48, 64. Values above 8 only apply to CAN FD | 
 |   traffic (i.e.: ``mtu = CANFD_MTU``). | 
 |  | 
 | * ``tx_flags``: flags set into ``struct canfd_frame.flags`` at frame creation. | 
 |   Only applies to CAN FD traffic (i.e.: ``mtu = CANFD_MTU``). | 
 |  | 
 | Transmission stmin | 
 | ~~~~~~~~~~~~~~~~~~ | 
 |  | 
 | The transmission minimum separation time (stmin) can be forced using the | 
 | ``CAN_ISOTP_TX_STMIN`` optname and providing an stmin value in microseconds as | 
 | a 32bit unsigned integer; this will overwrite the value sent by the receiver in | 
 | flow control frames: | 
 |  | 
 | .. code-block:: C | 
 |  | 
 |     uint32_t stmin; | 
 |     ret = setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_TX_STMIN, &stmin, sizeof(stmin)); | 
 |  | 
 | Reception stmin | 
 | ~~~~~~~~~~~~~~~ | 
 |  | 
 | The reception minimum separation time (stmin) can be forced using the | 
 | ``CAN_ISOTP_RX_STMIN`` optname and providing an stmin value in microseconds as | 
 | a 32bit unsigned integer; received Consecutive Frames (CF) which timestamps | 
 | differ less than this value will be ignored: | 
 |  | 
 | .. code-block:: C | 
 |  | 
 |     uint32_t stmin; | 
 |     ret = setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_RX_STMIN, &stmin, sizeof(stmin)); | 
 |  | 
 | Multi-frame transport support | 
 | ----------------------------- | 
 |  | 
 | The ISO-TP stack contained inside the Linux kernel supports the multi-frame | 
 | transport mechanism defined by the standard, with the following constraints: | 
 |  | 
 | * the maximum size of a PDU is defined by a module parameter, with an hard | 
 |   limit imposed at build time. | 
 |  | 
 | * when a transmission is in progress, subsequent calls to ``write(2)`` will | 
 |   block, while calls to ``send(2)`` will either block or fail depending on the | 
 |   presence of the ``MSG_DONTWAIT`` flag. | 
 |  | 
 | * no support is present for sending "wait frames": whether a PDU can be fully | 
 |   received or not is decided when the First Frame is received. | 
 |  | 
 | Errors | 
 | ------ | 
 |  | 
 | Following errors are reported to userspace: | 
 |  | 
 | RX path errors | 
 | ~~~~~~~~~~~~~~ | 
 |  | 
 | ============ =============================================================== | 
 | -ETIMEDOUT   timeout of data reception | 
 | -EILSEQ      sequence number mismatch during a multi-frame reception | 
 | -EBADMSG     data reception with wrong padding | 
 | ============ =============================================================== | 
 |  | 
 | TX path errors | 
 | ~~~~~~~~~~~~~~ | 
 |  | 
 | ========== ================================================================= | 
 | -ECOMM     flow control reception timeout | 
 | -EMSGSIZE  flow control reception overflow | 
 | -EBADMSG   flow control reception with wrong layout/padding | 
 | ========== ================================================================= | 
 |  | 
 | Examples | 
 | ======== | 
 |  | 
 | Basic node example | 
 | ------------------ | 
 |  | 
 | Following example implements a node using "normal" physical addressing, with | 
 | RX ID equal to 0x18DAF142 and a TX ID equal to 0x18DA42F1. All options are left | 
 | to their default. | 
 |  | 
 | .. code-block:: C | 
 |  | 
 |   int s; | 
 |   struct sockaddr_can addr; | 
 |   int ret; | 
 |  | 
 |   s = socket(PF_CAN, SOCK_DGRAM, CAN_ISOTP); | 
 |   if (s < 0) | 
 |       exit(1); | 
 |  | 
 |   addr.can_family = AF_CAN; | 
 |   addr.can_ifindex = if_nametoindex("can0"); | 
 |   addr.can_addr.tp.tx_id = 0x18DA42F1 | CAN_EFF_FLAG; | 
 |   addr.can_addr.tp.rx_id = 0x18DAF142 | CAN_EFF_FLAG; | 
 |  | 
 |   ret = bind(s, (struct sockaddr *)&addr, sizeof(addr)); | 
 |   if (ret < 0) | 
 |       exit(1); | 
 |  | 
 |   /* Data can now be received using read(s, ...) and sent using write(s, ...) */ | 
 |  | 
 | Additional examples | 
 | ------------------- | 
 |  | 
 | More complete (and complex) examples can be found inside the ``isotp*`` userland | 
 | tools, distributed as part of the ``can-utils`` utilities at: | 
 | https://github.com/linux-can/can-utils |