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-10-20 12:20:01

            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              : #define BT_BUF_ACL_RX_COUNT_EXTRA CONFIG_BT_BUF_ACL_RX_COUNT_EXTRA
     155              : #define BT_BUF_ACL_RX_COUNT       (1 + BT_BUF_ACL_RX_COUNT_EXTRA)
     156              : #else
     157            0 : #define BT_BUF_ACL_RX_COUNT_EXTRA 0
     158            0 : #define BT_BUF_ACL_RX_COUNT       0
     159              : #endif /* CONFIG_BT_CONN && CONFIG_BT_HCI_HOST */
     160              : 
     161              : BUILD_ASSERT(BT_BUF_ACL_RX_COUNT <= BT_BUF_ACL_RX_COUNT_MAX,
     162              :              "Maximum number of ACL RX buffer is 65535, reduce CONFIG_BT_BUF_ACL_RX_COUNT_EXTRA");
     163              : 
     164              : /** Data size needed for HCI ACL, HCI ISO or Event RX buffers */
     165            1 : #define BT_BUF_RX_SIZE (MAX(MAX(BT_BUF_ACL_RX_SIZE, BT_BUF_EVT_RX_SIZE), \
     166              :                             BT_BUF_ISO_RX_SIZE))
     167              : 
     168              : /* Controller can generate up to CONFIG_BT_BUF_ACL_TX_COUNT number of unique HCI Number of Completed
     169              :  * Packets events.
     170              :  */
     171              : BUILD_ASSERT(CONFIG_BT_BUF_EVT_RX_COUNT > CONFIG_BT_BUF_ACL_TX_COUNT,
     172              :              "Increase Event RX buffer count to be greater than ACL TX buffer count");
     173              : 
     174              : /** Buffer count needed for HCI ACL or HCI ISO plus Event RX buffers */
     175            1 : #define BT_BUF_RX_COUNT (CONFIG_BT_BUF_EVT_RX_COUNT + \
     176              :                          MAX(BT_BUF_ACL_RX_COUNT, BT_BUF_ISO_RX_COUNT))
     177              : 
     178              : /** Data size needed for HCI Command buffers. */
     179            1 : #define BT_BUF_CMD_TX_SIZE BT_BUF_CMD_SIZE(CONFIG_BT_BUF_CMD_TX_SIZE)
     180              : 
     181              : /** Allocate a buffer for incoming data
     182              :  *
     183              :  *  This will set the buffer type so it doesn't need to be explicitly encoded into the buffer.
     184              :  *
     185              :  *  @param type    Type of buffer. Only BT_BUF_EVT, BT_BUF_ACL_IN and BT_BUF_ISO_IN
     186              :  *                 are allowed.
     187              :  *  @param timeout Non-negative waiting period to obtain a buffer or one of the
     188              :  *                 special values K_NO_WAIT and K_FOREVER.
     189              :  *  @return A new buffer.
     190              :  */
     191            1 : struct net_buf *bt_buf_get_rx(enum bt_buf_type type, k_timeout_t timeout);
     192              : 
     193              : /** A callback to notify about freed buffer in the incoming data pool.
     194              :  *
     195              :  * This callback is called when a buffer of a given type is freed and can be requested through the
     196              :  * @ref bt_buf_get_rx function. However, this callback is called from the context of the buffer
     197              :  * freeing operation and must not attempt to allocate a new buffer from the same pool.
     198              :  *
     199              :  * @warning When this callback is called, the scheduler is locked and the callee must not perform
     200              :  * any action that makes the current thread unready. This callback must only be used for very
     201              :  * short non-blocking operation (e.g. submitting a work item).
     202              :  *
     203              :  * @param type_mask A bit mask of buffer types that have been freed.
     204              :  */
     205            1 : typedef void (*bt_buf_rx_freed_cb_t)(enum bt_buf_type type_mask);
     206              : 
     207              : /** Set the callback to notify about freed buffer in the incoming data pool.
     208              :  *
     209              :  * @param cb Callback to notify about freed buffer in the incoming data pool. If NULL, the callback
     210              :  *           is disabled.
     211              :  */
     212            1 : void bt_buf_rx_freed_cb_set(bt_buf_rx_freed_cb_t cb);
     213              : 
     214              : /** Allocate a buffer for outgoing data
     215              :  *
     216              :  *  This will set the buffer type so it doesn't need to be explicitly encoded into the buffer.
     217              :  *
     218              :  *  @param type    Type of buffer. BT_BUF_CMD or BT_BUF_ACL_OUT.
     219              :  *  @param timeout Non-negative waiting period to obtain a buffer or one of the
     220              :  *                 special values K_NO_WAIT and K_FOREVER.
     221              :  *  @param data    Initial data to append to buffer. This is optional and can be NULL.
     222              :  *  @param size    Initial data size.
     223              :  *  @return A new buffer.
     224              :  */
     225            1 : struct net_buf *bt_buf_get_tx(enum bt_buf_type type, k_timeout_t timeout,
     226              :                               const void *data, size_t size);
     227              : 
     228              : /** Allocate a buffer for an HCI Event
     229              :  *
     230              :  *  This will set the buffer type so it doesn't need to be explicitly encoded into the buffer.
     231              :  *
     232              :  *  @param evt          HCI event code
     233              :  *  @param discardable  Whether the driver considers the event discardable.
     234              :  *  @param timeout      Non-negative waiting period to obtain a buffer or one of
     235              :  *                      the special values K_NO_WAIT and K_FOREVER.
     236              :  *  @return A new buffer.
     237              :  */
     238            1 : struct net_buf *bt_buf_get_evt(uint8_t evt, bool discardable, k_timeout_t timeout);
     239              : 
     240              : /** Set the buffer type. The type is encoded as an H:4 byte prefix as part of
     241              :  *  the payload itself.
     242              :  *
     243              :  *  @param buf   Bluetooth buffer
     244              :  *  @param type  The BT_* type to set the buffer to
     245              :  */
     246            1 : static inline void __deprecated bt_buf_set_type(struct net_buf *buf, enum bt_buf_type type)
     247              : {
     248              :         __ASSERT_NO_MSG(net_buf_headroom(buf) >= 1);
     249              :         net_buf_push_u8(buf, bt_buf_type_to_h4(type));
     250              : }
     251              : 
     252              : 
     253              : /** Get the buffer type. This pulls the H:4 byte prefix from the payload, which means
     254              :  *  that the call can be done only once per buffer.
     255              :  *
     256              :  *  @param buf   Bluetooth buffer
     257              :  *
     258              :  *  @return The BT_* type to of the buffer
     259              :  */
     260            1 : static inline enum bt_buf_type __deprecated bt_buf_get_type(struct net_buf *buf)
     261              : {
     262              :         /* We have to assume the direction since the H:4 type doesn't tell us
     263              :          * if the buffer is incoming or outgoing. The common use case of this API is for outgoing
     264              :          * buffers, so we assume that.
     265              :          */
     266              :         return bt_buf_type_from_h4(net_buf_pull_u8(buf), BT_BUF_OUT);
     267              : }
     268              : 
     269              : /**
     270              :  * @}
     271              :  */
     272              : 
     273              : #ifdef __cplusplus
     274              : }
     275              : #endif
     276              : 
     277              : #endif /* ZEPHYR_INCLUDE_BLUETOOTH_BUF_H_ */
        

Generated by: LCOV version 2.0-1