LCOV - code coverage report
Current view: top level - zephyr/canbus - isotp.h Hit Total Coverage
Test: new.info Lines: 42 44 95.5 %
Date: 2024-12-22 00:14:23

          Line data    Source code
       1           1 : /*
       2             :  * Copyright (c) 2019 Alexander Wachter
       3             :  *
       4             :  * SPDX-License-Identifier: Apache-2.0
       5             :  */
       6             : 
       7             : /**
       8             :  * @file
       9             :  * @brief Public API for ISO-TP (ISO 15765-2:2016)
      10             :  *
      11             :  * ISO-TP is a transport protocol for CAN (Controller Area Network)
      12             :  */
      13             : 
      14             : #ifndef ZEPHYR_INCLUDE_CANBUS_ISOTP_H_
      15             : #define ZEPHYR_INCLUDE_CANBUS_ISOTP_H_
      16             : 
      17             : /**
      18             :  * @brief CAN ISO-TP Protocol
      19             :  * @defgroup can_isotp CAN ISO-TP Protocol
      20             :  * @ingroup connectivity
      21             :  * @{
      22             :  */
      23             : 
      24             : #include <zephyr/drivers/can.h>
      25             : #include <zephyr/types.h>
      26             : #include <zephyr/net_buf.h>
      27             : 
      28             : /*
      29             :  * Abbreviations
      30             :  * BS      Block Size
      31             :  * CAN_DL  CAN LL data size
      32             :  * CF      Consecutive Frame
      33             :  * CTS     Continue to send
      34             :  * DLC     Data length code
      35             :  * FC      Flow Control
      36             :  * FF      First Frame
      37             :  * SF      Single Frame
      38             :  * FS      Flow Status
      39             :  * AE      Address Extension
      40             :  * SN      Sequence Number
      41             :  * ST      Separation time
      42             :  * SA      Source Address
      43             :  * TA      Target Address
      44             :  * RX_DL   CAN RX LL data size
      45             :  * TX_DL   CAN TX LL data size
      46             :  * PCI     Process Control Information
      47             :  */
      48             : 
      49             : /*
      50             :  * N_Result according to ISO 15765-2:2016
      51             :  * ISOTP_ prefix is used to be zephyr conform
      52             :  */
      53             : 
      54             : /** Completed successfully */
      55           1 : #define ISOTP_N_OK              0
      56             : 
      57             : /** Ar/As has timed out */
      58           1 : #define ISOTP_N_TIMEOUT_A      -1
      59             : 
      60             : /** Reception of next FC has timed out */
      61           1 : #define ISOTP_N_TIMEOUT_BS     -2
      62             : 
      63             : /** Cr has timed out */
      64           1 : #define ISOTP_N_TIMEOUT_CR     -3
      65             : 
      66             : /** Unexpected sequence number */
      67           1 : #define ISOTP_N_WRONG_SN       -4
      68             : 
      69             : /** Invalid flow status received*/
      70           1 : #define ISOTP_N_INVALID_FS     -5
      71             : 
      72             : /** Unexpected PDU received */
      73           1 : #define ISOTP_N_UNEXP_PDU      -6
      74             : 
      75             : /** Maximum number of WAIT flowStatus PDUs exceeded */
      76           1 : #define ISOTP_N_WFT_OVRN       -7
      77             : 
      78             : /** FlowStatus OVFLW PDU was received */
      79           1 : #define ISOTP_N_BUFFER_OVERFLW -8
      80             : 
      81             : /** General error */
      82           1 : #define ISOTP_N_ERROR          -9
      83             : 
      84             : /** Implementation specific errors */
      85             : 
      86             : /** Can't bind or send because the CAN device has no filter left*/
      87           1 : #define ISOTP_NO_FREE_FILTER    -10
      88             : 
      89             : /** No net buffer left to allocate */
      90           1 : #define ISOTP_NO_NET_BUF_LEFT   -11
      91             : 
      92             : /** Not sufficient space in the buffer left for the data */
      93           1 : #define ISOTP_NO_BUF_DATA_LEFT  -12
      94             : 
      95             : /** No context buffer left to allocate */
      96           1 : #define ISOTP_NO_CTX_LEFT       -13
      97             : 
      98             : /** Timeout for recv */
      99           1 : #define ISOTP_RECV_TIMEOUT      -14
     100             : 
     101             : /*
     102             :  * CAN ID filtering for ISO-TP fixed addressing according to SAE J1939
     103             :  *
     104             :  * Format of 29-bit CAN identifier:
     105             :  * ------------------------------------------------------
     106             :  * | 28 .. 26 | 25  | 24 | 23 .. 16 | 15 .. 8  | 7 .. 0 |
     107             :  * ------------------------------------------------------
     108             :  * | Priority | EDP | DP | N_TAtype |   N_TA   |  N_SA  |
     109             :  * ------------------------------------------------------
     110             :  */
     111             : 
     112             : /** Position of fixed source address (SA) */
     113           1 : #define ISOTP_FIXED_ADDR_SA_POS         (CONFIG_ISOTP_FIXED_ADDR_SA_POS)
     114             : 
     115             : /** Mask to obtain fixed source address (SA) */
     116           1 : #define ISOTP_FIXED_ADDR_SA_MASK        (CONFIG_ISOTP_FIXED_ADDR_SA_MASK)
     117             : 
     118             : /** Position of fixed target address (TA) */
     119           1 : #define ISOTP_FIXED_ADDR_TA_POS         (CONFIG_ISOTP_FIXED_ADDR_TA_POS)
     120             : 
     121             : /** Mask to obtain fixed target address (TA) */
     122           1 : #define ISOTP_FIXED_ADDR_TA_MASK        (CONFIG_ISOTP_FIXED_ADDR_TA_MASK)
     123             : 
     124             : /** Position of priority in fixed addressing mode */
     125           1 : #define ISOTP_FIXED_ADDR_PRIO_POS       (CONFIG_ISOTP_FIXED_ADDR_PRIO_POS)
     126             : 
     127             : /** Mask for priority in fixed addressing mode */
     128           1 : #define ISOTP_FIXED_ADDR_PRIO_MASK      (CONFIG_ISOTP_FIXED_ADDR_PRIO_MASK)
     129             : 
     130             : /** CAN filter RX mask to match any priority and source address (SA) */
     131           1 : #define ISOTP_FIXED_ADDR_RX_MASK        (CONFIG_ISOTP_FIXED_ADDR_RX_MASK)
     132             : 
     133             : #ifdef __cplusplus
     134             : extern "C" {
     135             : #endif
     136             : 
     137             : /**
     138             :  * @name ISO-TP message ID flags
     139             :  * @anchor ISOTP_MSG_FLAGS
     140             :  *
     141             :  * @{
     142             :  */
     143             : 
     144             : /** Message uses ISO-TP extended addressing (first payload byte of CAN frame) */
     145           1 : #define ISOTP_MSG_EXT_ADDR BIT(0)
     146             : 
     147             : /**
     148             :  * Message uses ISO-TP fixed addressing (according to SAE J1939). Only valid in combination with
     149             :  * ``ISOTP_MSG_IDE``.
     150             :  */
     151           1 : #define ISOTP_MSG_FIXED_ADDR BIT(1)
     152             : 
     153             : /** Message uses extended (29-bit) CAN ID */
     154           1 : #define ISOTP_MSG_IDE BIT(2)
     155             : 
     156             : /** Message uses CAN FD format (FDF) */
     157           1 : #define ISOTP_MSG_FDF BIT(3)
     158             : 
     159             : /** Message uses CAN FD Baud Rate Switch (BRS). Only valid in combination with ``ISOTP_MSG_FDF``. */
     160           1 : #define ISOTP_MSG_BRS BIT(4)
     161             : 
     162             : /** @} */
     163             : 
     164             : /**
     165             :  * @brief ISO-TP message id struct
     166             :  *
     167             :  * Used to pass addresses to the bind and send functions.
     168             :  */
     169           1 : struct isotp_msg_id {
     170             :         /**
     171             :          * CAN identifier
     172             :          *
     173             :          * If ISO-TP fixed addressing is used, isotp_bind ignores SA and
     174             :          * priority sections and modifies TA section in flow control frames.
     175             :          */
     176             :         union {
     177           0 :                 uint32_t std_id  : 11;
     178           0 :                 uint32_t ext_id  : 29;
     179           1 :         };
     180             :         /** ISO-TP extended address (if used) */
     181           1 :         uint8_t ext_addr;
     182             :         /**
     183             :          * ISO-TP frame data length (TX_DL for TX address or RX_DL for RX address).
     184             :          *
     185             :          * Valid values are 8 for classical CAN or 8, 12, 16, 20, 24, 32, 48 and 64 for CAN FD.
     186             :          *
     187             :          * 0 will be interpreted as 8 or 64 (if ISOTP_MSG_FDF is set).
     188             :          *
     189             :          * The value for incoming transmissions (RX_DL) is determined automatically based on the
     190             :          * received first frame and does not need to be set during initialization.
     191             :          */
     192           1 :         uint8_t dl;
     193             :         /** Flags. @see @ref ISOTP_MSG_FLAGS. */
     194           1 :         uint8_t flags;
     195             : };
     196             : 
     197             : /*
     198             :  * STmin is split in two valid ranges:
     199             :  *   0-127: 0ms-127ms
     200             :  * 128-240: Reserved
     201             :  * 241-249: 100us-900us (multiples of 100us)
     202             :  * 250-   : Reserved
     203             :  */
     204             : 
     205             : /**
     206             :  * @brief ISO-TP frame control options struct
     207             :  *
     208             :  * Used to pass the options to the bind and send functions.
     209             :  */
     210           1 : struct isotp_fc_opts {
     211           1 :         uint8_t bs;    /**< Block size. Number of CF PDUs before next CF is sent */
     212           1 :         uint8_t stmin; /**< Minimum separation time. Min time between frames */
     213             : };
     214             : 
     215             : /**
     216             :  * @brief Transmission callback
     217             :  *
     218             :  * This callback is called when a transmission is completed.
     219             :  *
     220             :  * @param error_nr ISOTP_N_OK on success, ISOTP_N_* on error
     221             :  * @param arg      Callback argument passed to the send function
     222             :  */
     223           1 : typedef void (*isotp_tx_callback_t)(int error_nr, void *arg);
     224             : 
     225             : struct isotp_send_ctx;
     226             : struct isotp_recv_ctx;
     227             : 
     228             : /**
     229             :  * @brief Bind an address to a receiving context.
     230             :  *
     231             :  * This function binds an RX and TX address combination to an RX context.
     232             :  * When data arrives from the specified address, it is buffered and can be read
     233             :  * by calling isotp_recv.
     234             :  * When calling this routine, a filter is applied in the CAN device, and the
     235             :  * context is initialized. The context must be valid until calling unbind.
     236             :  *
     237             :  * @param rctx    Context to store the internal states.
     238             :  * @param can_dev The CAN device to be used for sending and receiving.
     239             :  * @param rx_addr Identifier for incoming data.
     240             :  * @param tx_addr Identifier for FC frames.
     241             :  * @param opts    Flow control options.
     242             :  * @param timeout Timeout for FF SF buffer allocation.
     243             :  *
     244             :  * @retval ISOTP_N_OK on success
     245             :  * @retval ISOTP_NO_FREE_FILTER if CAN device has no filters left.
     246             :  */
     247           1 : int isotp_bind(struct isotp_recv_ctx *rctx, const struct device *can_dev,
     248             :                const struct isotp_msg_id *rx_addr,
     249             :                const struct isotp_msg_id *tx_addr,
     250             :                const struct isotp_fc_opts *opts,
     251             :                k_timeout_t timeout);
     252             : 
     253             : /**
     254             :  * @brief Unbind a context from the interface
     255             :  *
     256             :  * This function removes the binding from isotp_bind.
     257             :  * The filter is detached from the CAN device, and if a transmission is ongoing,
     258             :  * buffers are freed.
     259             :  * The context can be discarded safely after calling this function.
     260             :  *
     261             :  * @param rctx    Context that should be unbound.
     262             :  */
     263           1 : void isotp_unbind(struct isotp_recv_ctx *rctx);
     264             : 
     265             : /**
     266             :  * @brief Read out received data from fifo.
     267             :  *
     268             :  * This function reads the data from the receive FIFO of the context.
     269             :  * It blocks if the FIFO is empty.
     270             :  * If an error occurs, the function returns a negative number and leaves the
     271             :  * data buffer unchanged.
     272             :  *
     273             :  * @param rctx    Context that is already bound.
     274             :  * @param data    Pointer to a buffer where the data is copied to.
     275             :  * @param len     Size of the buffer.
     276             :  * @param timeout Timeout for incoming data.
     277             :  *
     278             :  * @retval Number of bytes copied on success
     279             :  * @retval ISOTP_RECV_TIMEOUT when "timeout" timed out
     280             :  * @retval ISOTP_N_* on error
     281             :  */
     282           1 : int isotp_recv(struct isotp_recv_ctx *rctx, uint8_t *data, size_t len, k_timeout_t timeout);
     283             : 
     284             : /**
     285             :  * @brief Get the net buffer on data reception
     286             :  *
     287             :  * This function reads incoming data into net-buffers.
     288             :  * It blocks until the entire packet is received, BS is reached, or an error
     289             :  * occurred. If BS was zero, the data is in a single net_buf. Otherwise,
     290             :  * the data is fragmented in chunks of BS size.
     291             :  * The net-buffers are referenced and must be freed with net_buf_unref after the
     292             :  * data is processed.
     293             :  *
     294             :  * @param rctx    Context that is already bound.
     295             :  * @param buffer  Pointer where the net_buf pointer is written to.
     296             :  * @param timeout Timeout for incoming data.
     297             :  *
     298             :  * @retval Remaining data length for this transfer if BS > 0, 0 for BS = 0
     299             :  * @retval ISOTP_RECV_TIMEOUT when "timeout" timed out
     300             :  * @retval ISOTP_N_* on error
     301             :  */
     302           1 : int isotp_recv_net(struct isotp_recv_ctx *rctx, struct net_buf **buffer, k_timeout_t timeout);
     303             : 
     304             : /**
     305             :  * @brief Send data
     306             :  *
     307             :  * This function is used to send data to a peer that listens to the tx_addr.
     308             :  * An internal work-queue is used to transfer the segmented data.
     309             :  * Data and context must be valid until the transmission has finished.
     310             :  * If a complete_cb is given, this function is non-blocking, and the callback
     311             :  * is called on completion with the return value as a parameter.
     312             :  *
     313             :  * @param sctx        Context to store the internal states.
     314             :  * @param can_dev     The CAN device to be used for sending and receiving.
     315             :  * @param data        Data to be sent.
     316             :  * @param len         Length of the data to be sent.
     317             :  * @param rx_addr     Identifier for FC frames.
     318             :  * @param tx_addr     Identifier for outgoing frames the receiver listens on.
     319             :  * @param complete_cb Function called on completion or NULL.
     320             :  * @param cb_arg      Argument passed to the complete callback.
     321             :  *
     322             :  * @retval ISOTP_N_OK on success
     323             :  * @retval ISOTP_N_* on error
     324             :  */
     325           1 : int isotp_send(struct isotp_send_ctx *sctx, const struct device *can_dev,
     326             :                const uint8_t *data, size_t len,
     327             :                const struct isotp_msg_id *tx_addr,
     328             :                const struct isotp_msg_id *rx_addr,
     329             :                isotp_tx_callback_t complete_cb, void *cb_arg);
     330             : 
     331             : #ifdef CONFIG_ISOTP_ENABLE_CONTEXT_BUFFERS
     332             : /**
     333             :  * @brief Send data with buffered context
     334             :  *
     335             :  * This function is similar to isotp_send, but the context is automatically
     336             :  * allocated from an internal pool.
     337             :  *
     338             :  * @param can_dev     The CAN device to be used for sending and receiving.
     339             :  * @param data        Data to be sent.
     340             :  * @param len         Length of the data to be sent.
     341             :  * @param rx_addr     Identifier for FC frames.
     342             :  * @param tx_addr     Identifier for outgoing frames the receiver listens on.
     343             :  * @param complete_cb Function called on completion or NULL.
     344             :  * @param cb_arg      Argument passed to the complete callback.
     345             :  * @param timeout     Timeout for buffer allocation.
     346             :  *
     347             :  * @retval ISOTP_N_OK on success
     348             :  * @retval ISOTP_N_* on error
     349             :  */
     350             : int isotp_send_ctx_buf(const struct device *can_dev,
     351             :                        const uint8_t *data, size_t len,
     352             :                        const struct isotp_msg_id *tx_addr,
     353             :                        const struct isotp_msg_id *rx_addr,
     354             :                        isotp_tx_callback_t complete_cb, void *cb_arg,
     355             :                        k_timeout_t timeout);
     356             : 
     357             : /**
     358             :  * @brief Send data with buffered context
     359             :  *
     360             :  * This function is similar to isotp_send_ctx_buf, but the data is carried in
     361             :  * a net_buf. net_buf_unref is called on the net_buf when sending is completed.
     362             :  *
     363             :  * @param can_dev     The CAN device to be used for sending and receiving.
     364             :  * @param data        Data to be sent.
     365             :  * @param len         Length of the data to be sent.
     366             :  * @param rx_addr     Identifier for FC frames.
     367             :  * @param tx_addr     Identifier for outgoing frames the receiver listens on.
     368             :  * @param complete_cb Function called on completion or NULL.
     369             :  * @param cb_arg      Argument passed to the complete callback.
     370             :  * @param timeout     Timeout for buffer allocation.
     371             :  *
     372             :  * @retval ISOTP_N_OK on success
     373             :  * @retval ISOTP_* on error
     374             :  */
     375             : int isotp_send_net_ctx_buf(const struct device *can_dev,
     376             :                            struct net_buf *data,
     377             :                            const struct isotp_msg_id *tx_addr,
     378             :                            const struct isotp_msg_id *rx_addr,
     379             :                            isotp_tx_callback_t complete_cb, void *cb_arg,
     380             :                            k_timeout_t timeout);
     381             : 
     382             : #endif /*CONFIG_ISOTP_ENABLE_CONTEXT_BUFFERS*/
     383             : 
     384             : #if defined(CONFIG_ISOTP_USE_TX_BUF) && \
     385             :         defined(CONFIG_ISOTP_ENABLE_CONTEXT_BUFFERS)
     386             : /**
     387             :  * @brief Send data with buffered context
     388             :  *
     389             :  * This function is similar to isotp_send, but the context is automatically
     390             :  * allocated from an internal pool and the data to be send is buffered in an
     391             :  * internal net_buff.
     392             :  *
     393             :  * @param can_dev     The CAN device to be used for sending and receiving.
     394             :  * @param data        Data to be sent.
     395             :  * @param len         Length of the data to be sent.
     396             :  * @param rx_addr     Identifier for FC frames.
     397             :  * @param tx_addr     Identifier for outgoing frames the receiver listens on.
     398             :  * @param complete_cb Function called on completion or NULL.
     399             :  * @param cb_arg      Argument passed to the complete callback.
     400             :  * @param timeout     Timeout for buffer allocation.
     401             :  *
     402             :  * @retval ISOTP_N_OK on success
     403             :  * @retval ISOTP_* on error
     404             :  */
     405             : int isotp_send_buf(const struct device *can_dev,
     406             :                    const uint8_t *data, size_t len,
     407             :                    const struct isotp_msg_id *tx_addr,
     408             :                    const struct isotp_msg_id *rx_addr,
     409             :                    isotp_tx_callback_t complete_cb, void *cb_arg,
     410             :                    k_timeout_t timeout);
     411             : #endif
     412             : 
     413             : /** @cond INTERNAL_HIDDEN */
     414             : 
     415             : struct isotp_callback {
     416             :         isotp_tx_callback_t cb;
     417             :         void *arg;
     418             : };
     419             : 
     420             : struct isotp_send_ctx {
     421             :         int filter_id;
     422             :         uint32_t error_nr;
     423             :         const struct device *can_dev;
     424             :         union {
     425             :                 struct net_buf *buf;
     426             :                 struct {
     427             :                         const uint8_t *data;
     428             :                         size_t len;
     429             :                 };
     430             :         };
     431             :         struct k_work work;
     432             :         struct k_timer timer;
     433             :         union {
     434             :                 struct isotp_callback fin_cb;
     435             :                 struct k_sem fin_sem;
     436             :         };
     437             :         struct isotp_fc_opts opts;
     438             :         uint8_t state;
     439             :         uint8_t tx_backlog;
     440             :         struct k_sem tx_sem;
     441             :         struct isotp_msg_id rx_addr;
     442             :         struct isotp_msg_id tx_addr;
     443             :         uint8_t wft;
     444             :         uint8_t bs;
     445             :         uint8_t sn : 4;
     446             :         uint8_t is_net_buf  : 1;
     447             :         uint8_t is_ctx_slab : 1;
     448             :         uint8_t has_callback: 1;
     449             : };
     450             : 
     451             : struct isotp_recv_ctx {
     452             :         int filter_id;
     453             :         const struct device *can_dev;
     454             :         struct net_buf *buf;
     455             :         struct net_buf *act_frag;
     456             :         /* buffer currently processed in isotp_recv */
     457             :         struct net_buf *recv_buf;
     458             :         sys_snode_t alloc_node;
     459             :         uint32_t length;
     460             :         int error_nr;
     461             :         struct k_work work;
     462             :         struct k_timer timer;
     463             :         struct k_fifo fifo;
     464             :         struct isotp_msg_id rx_addr;
     465             :         struct isotp_msg_id tx_addr;
     466             :         struct isotp_fc_opts opts;
     467             :         uint8_t state;
     468             :         uint8_t bs;
     469             :         uint8_t wft;
     470             :         uint8_t sn_expected : 4;
     471             : };
     472             : 
     473             : /** @endcond */
     474             : 
     475             : /**
     476             :  * @}
     477             :  */
     478             : 
     479             : #ifdef __cplusplus
     480             : }
     481             : #endif
     482             : 
     483             : #endif /* ZEPHYR_INCLUDE_CANBUS_ISOTP_H_ */

Generated by: LCOV version 1.14