From nobody Wed Nov 27 04:35:50 2024 Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4E4E442065 for ; Sun, 13 Oct 2024 18:17:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728843460; cv=none; b=k7re8t+lISo58KYq/jJu5AQFs7Q8HcByuIxQmbU1zcKBcvQRCm/Oh6QPaF/cQhKwJhDk4WxwgsKWmSarxBbbBY0ND8QjYuOzQy0SBmQsp6lYQVfmiLQZ9VvzpOhI0VA8DlM8LZMMAL0gXbo3Btgd/+PeJCTYGKRCxauk4gCXqL4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1728843460; c=relaxed/simple; bh=o7wl8/P1L+YWu7PAMmddhpXP6szhLbVs2vAMj91E0KY=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version:Content-Type; b=AIHgtHd3g3AOyjU3pn54QeKdFbNJNQVCgCfleML1ak1cCxgGIDs40NTpSMgP+cVo21DnWHRS3ae8D2J+OPY8GqF3OOaW7lCEIaL665ED2QQnz/2+856poz3y1p8dqd2d2xhuo1YeefSEYu4x4q3y08Hi2bPvfrK41XyvM1TGeKc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1t039c-0006pA-D7; Sun, 13 Oct 2024 20:17:20 +0200 Received: from [2a0a:edc0:0:1101:1d::ac] (helo=dude04.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t039Y-001bmS-Rd; Sun, 13 Oct 2024 20:17:16 +0200 Received: from ore by dude04.red.stw.pengutronix.de with local (Exim 4.96) (envelope-from ) id 1t039Y-00EdfZ-2Y; Sun, 13 Oct 2024 20:17:16 +0200 From: Oleksij Rempel To: Robin van der Gracht , Oliver Hartkopp , Marc Kleine-Budde , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Jonathan Corbet Cc: Oleksij Rempel , kernel@pengutronix.de, linux-can@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v1] can: j1939: Extend stack documentation with buffer size behavior Date: Sun, 13 Oct 2024 20:17:15 +0200 Message-Id: <20241013181715.3488980-1-o.rempel@pengutronix.de> X-Mailer: git-send-email 2.39.5 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: ore@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org Extend the J1939 stack documentation to include information about how buffer sizes influence stack behavior, detailing handling of simple sessions, TP, and ETP transfers. Additionally, describe various setsockopt(2) options, including their usage and potential error values that can be returned by the stack. Signed-off-by: Oleksij Rempel --- Documentation/networking/j1939.rst | 675 +++++++++++++++++++++++++++++ 1 file changed, 675 insertions(+) diff --git a/Documentation/networking/j1939.rst b/Documentation/networking/= j1939.rst index e4bd7aa1f5aa9..82f25ec8f6c00 100644 --- a/Documentation/networking/j1939.rst +++ b/Documentation/networking/j1939.rst @@ -66,6 +66,90 @@ the library exclusively, or by the in-kernel system excl= usively. J1939 concepts =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 +Data Sent to the J1939 Stack +---------------------------- + +The data buffers sent to the J1939 stack from user space are not CAN frames +themselves. Instead, they are payloads that the J1939 stack converts into +proper CAN frames based on the size of the buffer and the type of transfer= . The +size of the buffer influences how the stack processes the data and determi= nes +the internal code path used for the transfer. + +**Handling of Different Buffer Sizes:** + +- **Buffers with a size of 8 bytes or less:** + + - These are handled as simple sessions internally within the stack. + + - The stack converts the buffer directly into a single CAN frame without + fragmentation. + + - This type of transfer does not require an actual client (receiver) on = the + receiving side. + +- **Buffers up to 1785 bytes:** + + - These are automatically handled as J1939 Transport Protocol (TP) trans= fers. + + - Internally, the stack splits the buffer into multiple 8-byte CAN frame= s. + + - TP transfers can be unicast or broadcast. + + - **Broadcast TP:** Does not require a receiver on the other side and ca= n be + used in broadcast scenarios. + + - **Unicast TP:** Requires an active receiver (client) on the other side= to + acknowledge the transfer. + +- **Buffers from 1786 bytes up to 111 MiB:** + + - These are handled as ISO 11783 Extended Transport Protocol (ETP) trans= fers. + + - ETP transfers are used for larger payloads and are split into multiple= CAN + frames internally. + + - **ETP transfers (unicast):** Require a receiver on the other side to + process the incoming data and acknowledge each step of the transfer. + + - ETP transfers cannot be broadcast like TP transfers, and always requir= e a + receiver for operation. + +**Non-Blocking Operation with `MSG_DONTWAIT`:** + +The J1939 stack supports non-blocking operation when used in combination w= ith +the `MSG_DONTWAIT` flag. In this mode, the stack attempts to take as much = data +as the available memory for the socket allows. It returns the amount of da= ta +that was successfully taken, and it is the responsibility of user space to +monitor this value and handle partial transfers. + +- If the stack cannot take the entire buffer, it returns the number of byt= es + successfully taken, and user space should handle the remainder. + +- **Error handling:** When using `MSG_DONTWAIT`, the user must rely on the + error queue to detect transfer errors. See the **SO_J1939_ERRQUEUE** sec= tion + for details on how to subscribe to error notifications. Without the error + queue, there is no other way for user space to be notified of transfer e= rrors + during non-blocking operations. + +**Behavior and Requirements:** + +- **Simple transfers (<=3D 8 bytes):** Do not require a receiver on the ot= her + side, making them easy to send without needing address claiming or + coordination with a destination. + +- **Unicast TP/ETP:** Requires a receiver on the other side to complete the + transfer. The receiver must acknowledge the transfer for the session to + proceed successfully. + +- **Broadcast TP:** Allows sending data without a receiver, but only works= for + TP transfers. ETP cannot be broadcast and always needs a receiving clien= t. + +These different behaviors depend heavily on the size of the buffer provide= d to +the stack, and the appropriate transport mechanism (TP or ETP) is selected +based on the payload size. The stack automatically manages the fragmentati= on +and reassembly of large payloads and ensures that the correct CAN frames a= re +generated and transmitted for each session. + PGN --- =20 @@ -338,6 +422,459 @@ with ``cmsg_level =3D=3D SOL_J1939 && cmsg_type =3D= =3D SCM_J1939_DEST_ADDR``, } } =20 +setsockopt(2) +^^^^^^^^^^^^^ + +The ``setsockopt(2)`` function is used to configure various socket-level +options for J1939 communication. The following options are supported: + +``SO_J1939_FILTER`` +~~~~~~~~~~~~~~~~~~~ + +The ``SO_J1939_FILTER`` option is essential when the default behavior of +``bind(2)`` and ``connect(2)`` is insufficient for specific use cases. By +default, ``bind(2)`` and ``connect(2)`` allow a socket to be associated wi= th a +single unicast or broadcast address. However, there are scenarios where fi= ner +control over the incoming messages is required, such as filtering by Param= eter +Group Number (PGN) rather than by addresses. + +For example, in a system where multiple types of J1939 messages are being +transmitted, a process might only be interested in a subset of those messa= ges, +such as specific PGNs, and not want to receive all messages destined for i= ts +address or broadcast to the bus. + +By applying the ``SO_J1939_FILTER`` option, you can filter messages based = on: + +- **Source Address (SA)**: Filter messages coming from specific source + addresses. + +- **Source Name**: Filter messages coming from ECUs with specific NAME + identifiers. + +- **Parameter Group Number (PGN)**: Focus on receiving messages with speci= fic + PGNs, filtering out irrelevant ones. + +This filtering mechanism is particularly useful when: + +- You want to receive a subset of messages based on their PGNs, even if the + address is the same. + +- You need to handle both broadcast and unicast messages but only care abo= ut + certain message types or parameters. + +- The ``bind(2)`` and ``connect(2)`` functions only allow binding to a sin= gle + address, which might not be sufficient if the process needs to handle mu= ltiple + PGNs but does not want to open multiple sockets. + +To remove existing filters, you can pass ``optval =3D=3D NULL`` or ``optle= n =3D=3D 0`` +to ``setsockopt(2)``. This will clear all currently set filters. If you wa= nt to +**update** the set of filters, you must pass the updated filter set to +``setsockopt(2)``, as the new filter set will **replace** the old one enti= rely. +This behavior ensures that any previous filter configuration is discarded = and +only the new set is applied. + +Example of removing all filters: + +.. code-block:: c + + setsockopt(sock, SOL_CAN_J1939, SO_J1939_FILTER, NULL, 0); + +**Maximum number of filters:** The maximum amount of filters that can be +applied using ``SO_J1939_FILTER`` is defined by ``J1939_FILTER_MAX``, whic= h is +set to 512. This means you can configure up to 512 individual filters to m= atch +your specific filtering needs. + +Practical use case: **Monitoring Address Claiming** + +One practical use case is monitoring the J1939 address claiming process by +filtering for specific PGNs related to address claiming. This allows a pro= cess +to monitor and handle address claims without processing unrelated messages. + +Example: + +.. code-block:: c + + struct j1939_filter filt[] =3D { + { + .pgn =3D J1939_PGN_ADDRESS_CLAIMED, + .pgn_mask =3D J1939_PGN_PDU1_MAX, + }, { + .pgn =3D J1939_PGN_REQUEST, + .pgn_mask =3D J1939_PGN_PDU1_MAX, + }, { + .pgn =3D J1939_PGN_ADDRESS_COMMANDED, + .pgn_mask =3D J1939_PGN_MAX, + }, + }; + setsockopt(sock, SOL_CAN_J1939, SO_J1939_FILTER, &filt, sizeof(filt)); + +In this example, the socket will only receive messages with the PGNs relat= ed to +address claiming: ``J1939_PGN_ADDRESS_CLAIMED``, ``J1939_PGN_REQUEST``, and +``J1939_PGN_ADDRESS_COMMANDED``. This is particularly useful in scenarios = where +you want to monitor and process address claims without being overwhelmed by +other traffic on the J1939 network. + +``SO_J1939_PROMISC`` +~~~~~~~~~~~~~~~~~~~~ + +The ``SO_J1939_PROMISC`` option enables socket-level promiscuous mode. When +this option is enabled, the socket will receive all J1939 traffic, regardl= ess +of any filters set by ``bind()`` or ``connect()``. This is analogous to +enabling promiscuous mode for an Ethernet interface, where all traffic on = the +network segment is captured. + +However, **`SO_J1939_FILTER` has a higher priority** compared to +``SO_J1939_PROMISC``. This means that even in promiscuous mode, you can re= duce +the number of packets received by applying specific filters with +`SO_J1939_FILTER`. The filters will limit which packets are passed to the +socket, allowing for more refined traffic selection while promiscuous mode= is +active. + +The acceptable value size for this option is ``sizeof(int)``, and the valu= e is +only differentiated between `0` and non-zero. A value of `0` disables +promiscuous mode, while any non-zero value enables it. + +This combination can be useful for debugging or monitoring specific types = of +traffic while still capturing a broad set of messages. + +Example: + +.. code-block:: c + + int value =3D 1; + setsockopt(sock, SOL_CAN_J1939, SO_J1939_PROMISC, &value, sizeof(value= )); + +In this example, setting ``value`` to any non-zero value (e.g., `1`) enabl= es +promiscuous mode, allowing the socket to receive all J1939 traffic on the +network. + +``SO_BROADCAST`` +~~~~~~~~~~~~~~~~ + +The ``SO_BROADCAST`` option enables the sending and receiving of broadcast +messages. By default, broadcast messages are disabled for J1939 sockets. W= hen +this option is enabled, the socket will be allowed to send and receive +broadcast packets on the J1939 network. + +Due to the nature of the CAN bus as a shared medium, all messages transmit= ted +on the bus are visible to all participants. In the context of J1939, +broadcasting refers to using a specific destination address field, where t= he +destination address is set to a value that indicates the message is intend= ed +for all participants (usually a global address such as 0xFF). Enabling the +broadcast option allows the socket to send and receive such broadcast mess= ages. + +The acceptable value size for this option is ``sizeof(int)``, and the valu= e is +only differentiated between `0` and non-zero. A value of `0` disables the +ability to send and receive broadcast messages, while any non-zero value +enables it. + +Example: + +.. code-block:: c + + int value =3D 1; + setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value)); + +In this example, setting ``value`` to any non-zero value (e.g., `1`) enabl= es +the socket to send and receive broadcast messages. + +``SO_J1939_SEND_PRIO`` +~~~~~~~~~~~~~~~~~~~~~~ + +The ``SO_J1939_SEND_PRIO`` option sets the priority of outgoing J1939 mess= ages +for the socket. In J1939, messages can have different priorities, and lower +numerical values indicate higher priority. This option allows the user to +control the priority of messages sent from the socket by adjusting the pri= ority +bits in the CAN identifier. + +The acceptable value **size** for this option is ``sizeof(int)``, and the = value +is expected to be in the range of 0 to 7, where `0` is the highest priorit= y, +and `7` is the lowest. By default, the priority is set to `6` if this opti= on is +not explicitly configured. + +Note that the priority values `0` and `1` can only be set if the process h= as +the `CAP_NET_ADMIN` capability. These are reserved for high-priority traff= ic +and require administrative privileges. + +Example: + +.. code-block:: c + + int prio =3D 3; // Priority value between 0 (highest) and 7 (lowest) + setsockopt(sock, SOL_CAN_J1939, SO_J1939_SEND_PRIO, &prio, sizeof(prio= )); + +In this example, the priority is set to `3`, meaning the outgoing messages= will +be sent with a moderate priority level. + +``SO_J1939_ERRQUEUE`` +~~~~~~~~~~~~~~~~~~~~~ + +The ``SO_J1939_ERRQUEUE`` option enables the socket to receive error messa= ges +from the error queue, providing diagnostic information about transmission +failures, protocol violations, or other issues that occur during J1939 +communication. Once this option is set, user space is required to handle +``MSG_ERRQUEUE`` messages. + +Setting ``SO_J1939_ERRQUEUE`` to ``0`` will purge any currently present er= ror +messages in the error queue. When enabled, error messages can be retrieved +using the ``recvmsg(2)`` system call. + +When subscribing to the error queue, the following error events can be +accessed: + +- **``J1939_EE_INFO_TX_ABORT``**: Transmission abort errors. +- **``J1939_EE_INFO_RX_RTS``**: Reception of RTS (Request to Send) control + frames. +- **``J1939_EE_INFO_RX_DPO``**: Reception of data packets with Data Page O= ffset + (DPO). +- **``J1939_EE_INFO_RX_ABORT``**: Reception abort errors. + +The error queue can be used to correlate errors with specific message tran= sfer +sessions using the session ID (``tskey``). The session ID is assigned via = the +``SOF_TIMESTAMPING_OPT_ID`` flag, which is set by enabling the +``SO_TIMESTAMPING`` option. + +If ``SO_J1939_ERRQUEUE`` is activated, the user is required to pull messag= es +from the error queue, meaning that using plain ``recv(2)`` is not sufficie= nt +anymore. The user must use ``recvmsg(2)`` with appropriate flags to handle +error messages. Failure to do so can result in the socket becoming blocked= with +unprocessed error messages in the queue. + +It is **recommended** that ``SO_J1939_ERRQUEUE`` be used in combination wi= th +``SO_TIMESTAMPING`` in most cases. This enables proper error handling along +with session tracking and timestamping, providing a more detailed analysis= of +message transfers and errors. + +The acceptable value **size** for this option is ``sizeof(int)``, and the = value +is only differentiated between ``0`` and non-zero. A value of ``0`` disabl= es +error queue reception and purges any existing error messages, while any +non-zero value enables it. + +Example: + +.. code-block:: c + + int enable =3D 1; // Enable error queue reception + setsockopt(sock, SOL_CAN_J1939, SO_J1939_ERRQUEUE, &enable, sizeof(ena= ble)); + + // Enable timestamping with session tracking via tskey + int timestamping =3D SOF_TIMESTAMPING_OPT_ID | SOF_TIMESTAMPING_TX_ACK= | + SOF_TIMESTAMPING_TX_SCHED | + SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_OPT= _CMSG; + setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, ×tamping, + sizeof(timestamping)); + +When enabled, error messages can be retrieved using ``recvmsg(2)``. By +combining ``SO_J1939_ERRQUEUE`` with ``SO_TIMESTAMPING`` (with +``SOF_TIMESTAMPING_OPT_ID`` and ``SOF_TIMESTAMPING_OPT_CMSG`` enabled), the +user can track message transfers, retrieve precise timestamps, and correla= te +errors with specific sessions. + +For more information on enabling timestamps and session tracking, refer to= the +`SO_TIMESTAMPING` section. + +``SO_TIMESTAMPING`` +~~~~~~~~~~~~~~~~~~~ + +The ``SO_TIMESTAMPING`` option allows the socket to receive timestamps for +various events related to message transmissions and receptions in J1939. T= his +option is often used in combination with ``SO_J1939_ERRQUEUE`` to provide +detailed diagnostic information, session tracking, and precise timing data= for +message transfers. + +In J1939, all payloads provided by user space, regardless of size, are +processed by the kernel as **sessions**. This includes both single-frame +messages (up to 8 bytes) and multi-frame protocols such as the Transport +Protocol (TP) and Extended Transport Protocol (ETP). Even for small, +single-frame messages, the kernel creates a session to manage the transmis= sion +and reception. The concept of sessions allows the kernel to manage various +aspects of the protocol, such as reassembling multi-frame messages and tra= cking +the status of transmissions. + +When receiving extended error messages from the error queue, the error +information is delivered through a `struct sock_extended_err`, accessible = via +the control message (``cmsg``) retrieved using the ``recvmsg(2)`` system c= all. + +There are two typical origins for the extended error messages in J1939: + +1. ``serr->ee_origin =3D=3D SO_EE_ORIGIN_TIMESTAMPING``: + + In this case, the `serr->ee_info` field will contain one of the followi= ng + timestamp types: + + - ``SCM_TSTAMP_SCHED``: This timestamp is valid for Extended Transport + Protocol (ETP) transfers and simple transfers (8 bytes or less). It + indicates when a message or set of frames has been scheduled for + transmission. + + - For simple transfers (8 bytes or less), it marks the point when the + message is queued and ready to be sent onto the CAN bus. + + - For ETP transfers, it is sent after receiving a CTS (Clear to Send) + frame on the sender side, indicating that a new set of frames has b= een + scheduled for transmission. + + - The Transport Protocol (TP) case is currently not implemented for t= his + timestamp. + + - On the receiver side, the counterpart to this event for ETP is + represented by the ``J1939_EE_INFO_RX_DPO`` message, which indicate= s the + reception of a Data Page Offset (DPO) control frame. + + - ``SCM_TSTAMP_ACK``: This timestamp indicates the acknowledgment of the + message or session. + + - For simple transfers (8 bytes or less), it marks when the message h= as + been sent and an echo confirmation has been received from the CAN + controller, indicating that the frame was transmitted onto the bus. + + - For multi-frame transfers (TP or ETP), it signifies that the entire + session has been acknowledged, typically after receiving the End of + Message Acknowledgment (EOMA) packet. + +2. ``serr->ee_origin =3D=3D SO_EE_ORIGIN_LOCAL``: + + In this case, the `serr->ee_info` field will contain one of the followi= ng + J1939 stack-specific message types: + + - ``J1939_EE_INFO_TX_ABORT``: This message indicates that the transmiss= ion + of a message or session was aborted. The cause of the abort can come = from + various sources: + + - **CAN stack failure**: The J1939 stack was unable to pass the frame= to + the CAN framework for transmission. + + - **Echo failure**: The J1939 stack did not receive an echo confirmat= ion + from the CAN controller, meaning the frame may not have been succes= sfully + transmitted to the CAN bus. + + - **Protocol-level issues**: For multi-frame transfers (TP/ETP), this + could include protocol-related errors, such as an abort signaled by= the + receiver or a timeout at the protocol level, which causes the sessi= on to + terminate prematurely. + + - The corresponding error code is stored in ``serr->ee_data`` + (``session->err`` on kernel side), providing additional details abo= ut + the specific reason for the abort. + + - ``J1939_EE_INFO_RX_RTS``: This message indicates that the J1939 stack= has + received a Request to Send (RTS) control frame, signaling the start o= f a + multi-frame transfer using the Transport Protocol (TP) or Extended + Transport Protocol (ETP). + + - It informs the receiver that the sender is ready to transmit a + multi-frame message and includes details about the total message si= ze + and the number of frames to be sent. + + - Statistics such as ``J1939_NLA_TOTAL_SIZE``, ``J1939_NLA_PGN``, + ``J1939_NLA_SRC_NAME``, and ``J1939_NLA_DEST_NAME`` are provided al= ong + with the ``J1939_EE_INFO_RX_RTS`` message, giving detailed informat= ion + about the incoming transfer. + + - ``J1939_EE_INFO_RX_DPO``: This message indicates that the J1939 stack= has + received a Data Page Offset (DPO) control frame, which is part of the + Extended Transport Protocol (ETP). + + - The DPO frame signals the continuation of an ETP multi-frame messag= e by + indicating the offset position in the data being transferred. It he= lps + the receiver manage large data sets by identifying which portion of= the + message is being received. + + - It is typically paired with a corresponding ``SCM_TSTAMP_SCHED`` ev= ent + on the sender side, which indicates when the next set of frames is + scheduled for transmission. + + - This event includes statistics such as ``J1939_NLA_BYTES_ACKED``, w= hich + tracks the number of bytes acknowledged up to that point in the ses= sion. + + - ``J1939_EE_INFO_RX_ABORT``: This message indicates that the reception= of a + multi-frame message (Transport Protocol or Extended Transport Protoco= l) has + been aborted. + + - The abort can be triggered by protocol-level errors such as timeout= s, an + unexpected frame, or a specific abort request from the sender. + + - This message signals that the receiver cannot continue processing t= he + transfer, and the session is terminated. + + - The corresponding error code is stored in ``serr->ee_data`` + (``session->err`` on kernel side ), providing further details about= the + reason for the abort, such as protocol violations or timeouts. + + - After receiving this message, the receiver discards the partially r= eceived + frames, and the multi-frame session is considered incomplete. + +In both cases, if ``SOF_TIMESTAMPING_OPT_ID`` is enabled, ``serr->ee_data`` +will be set to the session=E2=80=99s unique identifier (``session->tskey``= ). This +allows user space to track message transfers by their session identifier a= cross +multiple frames or stages. + +In all other cases, ``serr->ee_errno`` will be set to ``ENOMSG``, except f= or +the ``J1939_EE_INFO_TX_ABORT`` and ``J1939_EE_INFO_RX_ABORT`` cases, where= the +kernel sets ``serr->ee_data`` to the error stored in ``session->err``. All +protocol-specific errors are converted to standard kernel error values and +stored in ``session->err``. These error values are unified across system c= alls +and ``serr->ee_errno``. Some of the known error values are described in t= he +`Error Codes in the J1939 Stack` section. + +When the `J1939_EE_INFO_RX_RTS` message is provided, it will include the +following statistics for multi-frame messages (TP and ETP): + + - ``J1939_NLA_TOTAL_SIZE``: Total size of the message in the session. + - ``J1939_NLA_PGN``: Parameter Group Number (PGN) identifying the messag= e type. + - ``J1939_NLA_SRC_NAME``: 64-bit name of the source ECU. + - ``J1939_NLA_DEST_NAME``: 64-bit name of the destination ECU. + - ``J1939_NLA_SRC_ADDR``: 8-bit source address of the sending ECU. + - ``J1939_NLA_DEST_ADDR``: 8-bit destination address of the receiving EC= U. + +- For other messages (including single-frame messages), only the following + statistic is included: + + - ``J1939_NLA_BYTES_ACKED``: Number of bytes successfully acknowledged i= n the + session. + +The key flags for ``SO_TIMESTAMPING`` include: + +- ``SOF_TIMESTAMPING_OPT_ID``: Enables the use of a unique session identif= ier + (``tskey``) for each transfer. This identifier helps track message trans= fers + and errors as distinct sessions in user space. When this option is enabl= ed, + ``serr->ee_data`` will be set to ``session->tskey``. + +- ``SOF_TIMESTAMPING_OPT_CMSG``: Sends timestamp information through contr= ol + messages (``struct scm_timestamping``), allowing the application to retr= ieve + timestamps alongside the data. + +- ``SOF_TIMESTAMPING_TX_SCHED``: Provides the timestamp for when a message= is + scheduled for transmission (``SCM_TSTAMP_SCHED``). + +- ``SOF_TIMESTAMPING_TX_ACK``: Provides the timestamp for when a message + transmission is fully acknowledged (``SCM_TSTAMP_ACK``). + +- ``SOF_TIMESTAMPING_RX_SOFTWARE``: Provides timestamps for reception-rela= ted + events (e.g., ``J1939_EE_INFO_RX_RTS``, ``J1939_EE_INFO_RX_DPO``, + ``J1939_EE_INFO_RX_ABORT``). + +These flags enable detailed monitoring of message lifecycles, including +transmission scheduling, acknowledgments, reception timestamps, and gather= ing +detailed statistics about the communication session, especially for multi-= frame +payloads like TP and ETP. + +Example: + +.. code-block:: c + + // Enable timestamping with various options, including session trackin= g and + // statistics + int sock_opt =3D SOF_TIMESTAMPING_OPT_CMSG | + SOF_TIMESTAMPING_TX_ACK | + SOF_TIMESTAMPING_TX_SCHED | + SOF_TIMESTAMPING_OPT_ID | + SOF_TIMESTAMPING_RX_SOFTWARE; + + setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &sock_opt, sizeof(sock_o= pt)); + + + Dynamic Addressing ------------------ =20 @@ -458,3 +995,141 @@ Send: }; =20 sendto(sock, dat, sizeof(dat), 0, (const struct sockaddr *)&saddr, sizeof= (saddr)); + + +Error Codes in the J1939 Stack +------------------------------ + +This section lists all potential kernel error codes that can be exposed to= user +space when interacting with the J1939 stack. It includes both standard err= or +codes and those derived from protocol-specific abort codes. + +- ``EAGAIN``: Operation would block; retry may succeed. One common reason = is + that an active TP or ETP session exists, and an attempt was made to star= t a + new overlapping TP or ETP session between the same peers. + +- ``ENETDOWN``: Network is down. This occurs when the CAN interface is swi= tched + to the "down" state. + +- ``ENOBUFS``: No buffer space available. This error occurs when the CAN + interface's transmit (TX) queue is full, and no more messages can be que= ued. + +- ``EOVERFLOW``: Value too large for defined data type. In J1939, this can + happen if the requested data lies outside of the queued buffer. For exam= ple, + if a CTS (Clear to Send) requests an offset not available in the kernel = buffer + because user space did not provide enough data. + +- ``EBUSY``: Device or resource is busy. For example, this occurs if an + identical session is already active and the stack is unable to recover f= rom + the condition. + +- ``EACCES``: Permission denied. This error can occur, for example, when + attempting to send broadcast messages, but the socket is not configured = with + ``SO_BROADCAST``. + +- ``EADDRNOTAVAIL``: Address not available. This error occurs in cases suc= h as: + + - When attempting to use ``getsockname(2)`` to retrieve the peer's addre= ss, + but the socket is not connected. + + - When trying to send data to or from a NAME, but address claiming for t= he + NAME was not performed or detected by the stack. + +- ``EBADFD``: File descriptor in bad state. This error can occur if: + + - Attempting to send data to an unbound socket. + + - The socket is bound but has no source name, and the source address is + ``J1939_NO_ADDR``. + + - The ``can_ifindex`` is incorrect. + +- ``EFAULT``: Bad address. Occurs mostly when the stack can't copy from or= to a + sockptr, when there is insufficient data from user space, or when the bu= ffer + provided by user space is not large enough for the requested data. + +- ``EINTR``: A signal occurred before any data was transmitted; see ``sign= al(7)``. + +- ``EINVAL``: Invalid argument passed. For example: + + - ``msg->msg_namelen`` is less than ``J1939_MIN_NAMELEN``. + + - ``addr->can_family`` is not equal to ``AF_CAN``. + + - An incorrect PGN was provided. + +- ``ENODEV``: No such device. This happens when the CAN network device can= not + be found for the provided ``can_ifindex`` or if ``can_ifindex`` is 0. + +- ``ENOMEM``: Out of memory. Typically related to issues with memory alloc= ation + in the stack. + +- ``ENOPROTOOPT``: Protocol not available. This can occur when using + ``getsockopt(2)`` or ``setsockopt(2)`` if the requested socket option is= not + available. + +- ``EDESTADDRREQ``: Destination address required. This error occurs: + + - In the case of ``connect(2)``, if the ``struct sockaddr *uaddr`` is ``= NULL``. + + - In the case of ``send*(2)``, if there is an attempt to send an ETP mes= sage + to a broadcast address. + +- ``EDOM``: Argument out of domain. This error may happen if attempting to= send + a TP or ETP message to a PGN that is reserved for control PGNs for TP or= ETP + operations. + +- ``EIO``: I/O error. This can occur if the amount of data provided to the + socket for a TP or ETP session does not match the announced amount of da= ta for + the session. + +- ``ENOENT``: No such file or directory. This can happen when the stack + attempts to transfer CTS or EOMA but cannot find a matching receiving so= cket + anymore. + +- ``ENOIOCTLCMD``: No ioctls are available for the socket layer. + +- ``EPERM``: Operation not permitted. For example, this can occur if a + requested action requires ``CAP_NET_ADMIN`` privileges. + +- ``ENETUNREACH``: Network unreachable. Most likely, this occurs when fram= es + cannot be transmitted to the CAN bus. + +- ``ETIME``: Timer expired. This can happen if a timeout occurs while + attempting to send a simple message, for example, when an echo message f= rom + the controller is not received. + +- ``EPROTO``: Protocol error. + + - Used for various protocol-level errors in J1939, including: + + - Duplicate sequence number. + + - Unexpected EDPO or ECTS packet. + + - Invalid PGN or offset in EDPO/ECTS. + + - Number of EDPO packets exceeded CTS allowance. + + - Any other protocol-level error. + +- ``EMSGSIZE``: Message too long. + +- ``ENOMSG``: No message available. + +- ``EALREADY``: The ECU is already engaged in one or more connection-manag= ed + sessions and cannot support another. + +- ``EHOSTUNREACH``: A timeout occurred, and the session was aborted. + +- ``EBADMSG``: CTS (Clear to Send) messages were received during an active= data + transfer, causing an abort. + +- ``ENOTRECOVERABLE``: The maximum retransmission request limit was reache= d, + and the session cannot recover. + +- ``ENOTCONN``: An unexpected data transfer packet was received. + +- ``EILSEQ``: A bad sequence number was received, and the software could n= ot + recover. + --=20 2.39.5