LCOV - code coverage report
Current view: top level - zephyr/bluetooth - buf.h Coverage Total Hit
Test: new.info Lines: 78.6 % 28 22
Test Date: 2025-09-05 16:43:28

            Line data    Source code
       1            1 : /** @file
       2              :  *  @brief Bluetooth data buffer API
       3              :  */
       4              : 
       5              : /*
       6              :  * Copyright (c) 2016 Intel Corporation
       7              :  *
       8              :  * SPDX-License-Identifier: Apache-2.0
       9              :  */
      10              : 
      11              : #ifndef ZEPHYR_INCLUDE_BLUETOOTH_BUF_H_
      12              : #define ZEPHYR_INCLUDE_BLUETOOTH_BUF_H_
      13              : 
      14              : /**
      15              :  * @brief Data buffers
      16              :  * @defgroup bt_buf Data buffers
      17              :  * @ingroup bluetooth
      18              :  * @{
      19              :  */
      20              : 
      21              : #include <stddef.h>
      22              : #include <stdint.h>
      23              : 
      24              : #include <zephyr/autoconf.h>
      25              : #include <zephyr/bluetooth/hci.h>
      26              : #include <zephyr/bluetooth/hci_types.h>
      27              : #include <zephyr/net_buf.h>
      28              : #include <zephyr/sys/util.h>
      29              : #include <zephyr/sys/util_macro.h>
      30              : #include <zephyr/sys_clock.h>
      31              : #include <zephyr/toolchain.h>
      32              : 
      33              : #ifdef __cplusplus
      34              : extern "C" {
      35              : #endif
      36              : 
      37              : /** Possible types of buffers passed around the Bluetooth stack in a form of bitmask. */
      38            1 : enum bt_buf_type {
      39              :         /** Unknown/invalid packet type, used for error checking */
      40              :         BT_BUF_TYPE_NONE = 0,
      41              :         /** HCI command */
      42              :         BT_BUF_CMD = BIT(0),
      43              :         /** HCI event */
      44              :         BT_BUF_EVT = BIT(1),
      45              :         /** Outgoing ACL data */
      46              :         BT_BUF_ACL_OUT = BIT(2),
      47              :         /** Incoming ACL data */
      48              :         BT_BUF_ACL_IN = BIT(3),
      49              :         /** Outgoing ISO data */
      50              :         BT_BUF_ISO_OUT = BIT(4),
      51              :         /** Incoming ISO data */
      52              :         BT_BUF_ISO_IN = BIT(5),
      53              : };
      54              : 
      55              : /** Direction of HCI packets. Only used for mapping H:4 to BT_BUF_* values. */
      56            1 : enum bt_buf_dir {
      57              :         /** Packet from the controller to the host */
      58              :         BT_BUF_IN,
      59              :         /** Packet from the host to the controller */
      60              :         BT_BUF_OUT,
      61              : };
      62              : 
      63              : /** Convert from bt_buf_type to H:4 type.
      64              :  *
      65              :  *  @param type The bt_buf_type to convert
      66              :  *  @return The H:4 type
      67              :  */
      68            1 : static inline uint8_t bt_buf_type_to_h4(enum bt_buf_type type)
      69              : {
      70              :         switch (type) {
      71              :         case BT_BUF_CMD:
      72              :                 return BT_HCI_H4_CMD;
      73              :         case BT_BUF_ACL_IN:
      74              :         case BT_BUF_ACL_OUT:
      75              :                 return BT_HCI_H4_ACL;
      76              :         case BT_BUF_ISO_IN:
      77              :         case BT_BUF_ISO_OUT:
      78              :                 return BT_HCI_H4_ISO;
      79              :         case BT_BUF_EVT:
      80              :                 return BT_HCI_H4_EVT;
      81              :         default:
      82              :                 __ASSERT_NO_MSG(false);
      83              :                 return 0;
      84              :         }
      85              : }
      86              : 
      87              : /** Convert from H:4 type to bt_buf_type.
      88              :  *
      89              :  *  @param h4_type The H:4 type to convert
      90              :  *  @param dir     The direction of the packet
      91              :  *  @return The bt_buf_type
      92              :  */
      93            1 : static inline enum bt_buf_type bt_buf_type_from_h4(uint8_t h4_type, enum bt_buf_dir dir)
      94              : {
      95              :         switch (h4_type) {
      96              :         case BT_HCI_H4_CMD:
      97              :                 return BT_BUF_CMD;
      98              :         case BT_HCI_H4_ACL:
      99              :                 return dir == BT_BUF_OUT ? BT_BUF_ACL_OUT : BT_BUF_ACL_IN;
     100              :         case BT_HCI_H4_EVT:
     101              :                 return BT_BUF_EVT;
     102              :         case BT_HCI_H4_ISO:
     103              :                 return dir == BT_BUF_OUT ? BT_BUF_ISO_OUT : BT_BUF_ISO_IN;
     104              :         default:
     105              :                 return BT_BUF_TYPE_NONE;
     106              :         }
     107              : }
     108              : 
     109              : /* Headroom reserved in buffers, primarily for HCI transport encoding purposes */
     110            0 : #define BT_BUF_RESERVE 1
     111              : 
     112              : /** Helper to include reserved HCI data in buffer calculations */
     113            1 : #define BT_BUF_SIZE(size) (BT_BUF_RESERVE + (size))
     114              : 
     115              : /** Helper to calculate needed buffer size for HCI ACL packets */
     116            1 : #define BT_BUF_ACL_SIZE(size) BT_BUF_SIZE(BT_HCI_ACL_HDR_SIZE + (size))
     117              : 
     118              : /** Helper to calculate needed buffer size for HCI Event packets. */
     119            1 : #define BT_BUF_EVT_SIZE(size) BT_BUF_SIZE(BT_HCI_EVT_HDR_SIZE + (size))
     120              : 
     121              : /** Helper to calculate needed buffer size for HCI Command packets. */
     122            1 : #define BT_BUF_CMD_SIZE(size) BT_BUF_SIZE(BT_HCI_CMD_HDR_SIZE + (size))
     123              : 
     124              : /** Helper to calculate needed buffer size for HCI ISO packets. */
     125            1 : #define BT_BUF_ISO_SIZE(size) BT_BUF_SIZE(BT_HCI_ISO_HDR_SIZE + \
     126              :                                           BT_HCI_ISO_SDU_TS_HDR_SIZE + \
     127              :                                           (size))
     128              : 
     129              : /** Data size needed for HCI ACL RX buffers */
     130            1 : #define BT_BUF_ACL_RX_SIZE BT_BUF_ACL_SIZE(CONFIG_BT_BUF_ACL_RX_SIZE)
     131              : 
     132              : /** Data size needed for HCI Event RX buffers */
     133            1 : #define BT_BUF_EVT_RX_SIZE BT_BUF_EVT_SIZE(CONFIG_BT_BUF_EVT_RX_SIZE)
     134              : 
     135              : #if defined(CONFIG_BT_ISO)
     136              : #define BT_BUF_ISO_RX_SIZE BT_BUF_ISO_SIZE(CONFIG_BT_ISO_RX_MTU)
     137              : #define BT_BUF_ISO_RX_COUNT CONFIG_BT_ISO_RX_BUF_COUNT
     138              : #else
     139            0 : #define BT_BUF_ISO_RX_SIZE 0
     140            0 : #define BT_BUF_ISO_RX_COUNT 0
     141              : #endif /* CONFIG_BT_ISO */
     142              : 
     143              : /* see Core Spec v6.0 vol.4 part E 7.4.5 */
     144            0 : #define BT_BUF_ACL_RX_COUNT_MAX 65535
     145              : 
     146              : #if defined(CONFIG_BT_CONN) && defined(CONFIG_BT_HCI_HOST)
     147              :  /* The host needs more ACL buffers than maximum ACL links. This is because of
     148              :   * the way we re-assemble ACL packets into L2CAP PDUs.
     149              :   *
     150              :   * We keep around the first buffer (that comes from the driver) to do
     151              :   * re-assembly into, and if all links are re-assembling, there will be no buffer
     152              :   * available for the HCI driver to allocate from.
     153              :   *
     154              :   * TODO: When CONFIG_BT_BUF_ACL_RX_COUNT is removed,
     155              :   *       remove the MAX and only keep the 1.
     156              :   */
     157              : #define BT_BUF_ACL_RX_COUNT_EXTRA CONFIG_BT_BUF_ACL_RX_COUNT_EXTRA
     158              : #define BT_BUF_ACL_RX_COUNT       (MAX(CONFIG_BT_BUF_ACL_RX_COUNT, 1) + BT_BUF_ACL_RX_COUNT_EXTRA)
     159              : #else
     160            0 : #define BT_BUF_ACL_RX_COUNT_EXTRA 0
     161            0 : #define BT_BUF_ACL_RX_COUNT       0
     162              : #endif /* CONFIG_BT_CONN && CONFIG_BT_HCI_HOST */
     163              : 
     164              : #if defined(CONFIG_BT_BUF_ACL_RX_COUNT) && CONFIG_BT_BUF_ACL_RX_COUNT > 0
     165              : #warning "CONFIG_BT_BUF_ACL_RX_COUNT is deprecated, see Zephyr 4.1 migration guide"
     166              : #endif /* CONFIG_BT_BUF_ACL_RX_COUNT && CONFIG_BT_BUF_ACL_RX_COUNT > 0 */
     167              : 
     168              : BUILD_ASSERT(BT_BUF_ACL_RX_COUNT <= BT_BUF_ACL_RX_COUNT_MAX,
     169              :              "Maximum number of ACL RX buffer is 65535, reduce CONFIG_BT_BUF_ACL_RX_COUNT_EXTRA");
     170              : 
     171              : /** Data size needed for HCI ACL, HCI ISO or Event RX buffers */
     172            1 : #define BT_BUF_RX_SIZE (MAX(MAX(BT_BUF_ACL_RX_SIZE, BT_BUF_EVT_RX_SIZE), \
     173              :                             BT_BUF_ISO_RX_SIZE))
     174              : 
     175              : /* Controller can generate up to CONFIG_BT_BUF_ACL_TX_COUNT number of unique HCI Number of Completed
     176              :  * Packets events.
     177              :  */
     178              : BUILD_ASSERT(CONFIG_BT_BUF_EVT_RX_COUNT > CONFIG_BT_BUF_ACL_TX_COUNT,
     179              :              "Increase Event RX buffer count to be greater than ACL TX buffer count");
     180              : 
     181              : /** Buffer count needed for HCI ACL or HCI ISO plus Event RX buffers */
     182            1 : #define BT_BUF_RX_COUNT (CONFIG_BT_BUF_EVT_RX_COUNT + \
     183              :                          MAX(BT_BUF_ACL_RX_COUNT, BT_BUF_ISO_RX_COUNT))
     184              : 
     185              : /** Data size needed for HCI Command buffers. */
     186            1 : #define BT_BUF_CMD_TX_SIZE BT_BUF_CMD_SIZE(CONFIG_BT_BUF_CMD_TX_SIZE)
     187              : 
     188              : /** Allocate a buffer for incoming data
     189              :  *
     190              :  *  This will set the buffer type so it doesn't need to be explicitly encoded into the buffer.
     191              :  *
     192              :  *  @param type    Type of buffer. Only BT_BUF_EVT, BT_BUF_ACL_IN and BT_BUF_ISO_IN
     193              :  *                 are allowed.
     194              :  *  @param timeout Non-negative waiting period to obtain a buffer or one of the
     195              :  *                 special values K_NO_WAIT and K_FOREVER.
     196              :  *  @return A new buffer.
     197              :  */
     198            1 : struct net_buf *bt_buf_get_rx(enum bt_buf_type type, k_timeout_t timeout);
     199              : 
     200              : /** A callback to notify about freed buffer in the incoming data pool.
     201              :  *
     202              :  * This callback is called when a buffer of a given type is freed and can be requested through the
     203              :  * @ref bt_buf_get_rx function. However, this callback is called from the context of the buffer
     204              :  * freeing operation and must not attempt to allocate a new buffer from the same pool.
     205              :  *
     206              :  * @warning When this callback is called, the scheduler is locked and the callee must not perform
     207              :  * any action that makes the current thread unready. This callback must only be used for very
     208              :  * short non-blocking operation (e.g. submitting a work item).
     209              :  *
     210              :  * @param type_mask A bit mask of buffer types that have been freed.
     211              :  */
     212            1 : typedef void (*bt_buf_rx_freed_cb_t)(enum bt_buf_type type_mask);
     213              : 
     214              : /** Set the callback to notify about freed buffer in the incoming data pool.
     215              :  *
     216              :  * @param cb Callback to notify about freed buffer in the incoming data pool. If NULL, the callback
     217              :  *           is disabled.
     218              :  */
     219            1 : void bt_buf_rx_freed_cb_set(bt_buf_rx_freed_cb_t cb);
     220              : 
     221              : /** Allocate a buffer for outgoing data
     222              :  *
     223              :  *  This will set the buffer type so it doesn't need to be explicitly encoded into the buffer.
     224              :  *
     225              :  *  @param type    Type of buffer. BT_BUF_CMD or BT_BUF_ACL_OUT.
     226              :  *  @param timeout Non-negative waiting period to obtain a buffer or one of the
     227              :  *                 special values K_NO_WAIT and K_FOREVER.
     228              :  *  @param data    Initial data to append to buffer. This is optional and can be NULL.
     229              :  *  @param size    Initial data size.
     230              :  *  @return A new buffer.
     231              :  */
     232            1 : struct net_buf *bt_buf_get_tx(enum bt_buf_type type, k_timeout_t timeout,
     233              :                               const void *data, size_t size);
     234              : 
     235              : /** Allocate a buffer for an HCI Event
     236              :  *
     237              :  *  This will set the buffer type so it doesn't need to be explicitly encoded into the buffer.
     238              :  *
     239              :  *  @param evt          HCI event code
     240              :  *  @param discardable  Whether the driver considers the event discardable.
     241              :  *  @param timeout      Non-negative waiting period to obtain a buffer or one of
     242              :  *                      the special values K_NO_WAIT and K_FOREVER.
     243              :  *  @return A new buffer.
     244              :  */
     245            1 : struct net_buf *bt_buf_get_evt(uint8_t evt, bool discardable, k_timeout_t timeout);
     246              : 
     247              : /** Set the buffer type. The type is encoded as an H:4 byte prefix as part of
     248              :  *  the payload itself.
     249              :  *
     250              :  *  @param buf   Bluetooth buffer
     251              :  *  @param type  The BT_* type to set the buffer to
     252              :  */
     253            1 : static inline void __deprecated bt_buf_set_type(struct net_buf *buf, enum bt_buf_type type)
     254              : {
     255              :         __ASSERT_NO_MSG(net_buf_headroom(buf) >= 1);
     256              :         net_buf_push_u8(buf, bt_buf_type_to_h4(type));
     257              : }
     258              : 
     259              : 
     260              : /** Get the buffer type. This pulls the H:4 byte prefix from the payload, which means
     261              :  *  that the call can be done only once per buffer.
     262              :  *
     263              :  *  @param buf   Bluetooth buffer
     264              :  *
     265              :  *  @return The BT_* type to of the buffer
     266              :  */
     267            1 : static inline enum bt_buf_type __deprecated bt_buf_get_type(struct net_buf *buf)
     268              : {
     269              :         /* We have to assume the direction since the H:4 type doesn't tell us
     270              :          * if the buffer is incoming or outgoing. The common use case of this API is for outgoing
     271              :          * buffers, so we assume that.
     272              :          */
     273              :         return bt_buf_type_from_h4(net_buf_pull_u8(buf), BT_BUF_OUT);
     274              : }
     275              : 
     276              : /**
     277              :  * @}
     278              :  */
     279              : 
     280              : #ifdef __cplusplus
     281              : }
     282              : #endif
     283              : 
     284              : #endif /* ZEPHYR_INCLUDE_BLUETOOTH_BUF_H_ */
        

Generated by: LCOV version 2.0-1