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 <stdint.h> 22 : 23 : #include <zephyr/net_buf.h> 24 : #include <zephyr/bluetooth/hci.h> 25 : #include <zephyr/sys/util.h> 26 : 27 : #ifdef __cplusplus 28 : extern "C" { 29 : #endif 30 : 31 : /** Possible types of buffers passed around the Bluetooth stack in a form of bitmask. */ 32 1 : enum bt_buf_type { 33 : /** HCI command */ 34 : BT_BUF_CMD = BIT(0), 35 : /** HCI event */ 36 : BT_BUF_EVT = BIT(1), 37 : /** Outgoing ACL data */ 38 : BT_BUF_ACL_OUT = BIT(2), 39 : /** Incoming ACL data */ 40 : BT_BUF_ACL_IN = BIT(3), 41 : /** Outgoing ISO data */ 42 : BT_BUF_ISO_OUT = BIT(4), 43 : /** Incoming ISO data */ 44 : BT_BUF_ISO_IN = BIT(5), 45 : /** H:4 data */ 46 : BT_BUF_H4 = BIT(6), 47 : }; 48 : 49 : /** @brief This is a base type for bt_buf user data. */ 50 1 : struct bt_buf_data { 51 0 : uint8_t type; 52 : }; 53 : 54 : /* Headroom reserved in buffers, primarily for HCI transport encoding purposes */ 55 0 : #define BT_BUF_RESERVE 1 56 : 57 : /** Helper to include reserved HCI data in buffer calculations */ 58 1 : #define BT_BUF_SIZE(size) (BT_BUF_RESERVE + (size)) 59 : 60 : /** Helper to calculate needed buffer size for HCI ACL packets */ 61 1 : #define BT_BUF_ACL_SIZE(size) BT_BUF_SIZE(BT_HCI_ACL_HDR_SIZE + (size)) 62 : 63 : /** Helper to calculate needed buffer size for HCI Event packets. */ 64 1 : #define BT_BUF_EVT_SIZE(size) BT_BUF_SIZE(BT_HCI_EVT_HDR_SIZE + (size)) 65 : 66 : /** Helper to calculate needed buffer size for HCI Command packets. */ 67 1 : #define BT_BUF_CMD_SIZE(size) BT_BUF_SIZE(BT_HCI_CMD_HDR_SIZE + (size)) 68 : 69 : /** Helper to calculate needed buffer size for HCI ISO packets. */ 70 1 : #define BT_BUF_ISO_SIZE(size) BT_BUF_SIZE(BT_HCI_ISO_HDR_SIZE + \ 71 : BT_HCI_ISO_SDU_TS_HDR_SIZE + \ 72 : (size)) 73 : 74 : /** Data size needed for HCI ACL RX buffers */ 75 1 : #define BT_BUF_ACL_RX_SIZE BT_BUF_ACL_SIZE(CONFIG_BT_BUF_ACL_RX_SIZE) 76 : 77 : /** Data size needed for HCI Event RX buffers */ 78 1 : #define BT_BUF_EVT_RX_SIZE BT_BUF_EVT_SIZE(CONFIG_BT_BUF_EVT_RX_SIZE) 79 : 80 : #if defined(CONFIG_BT_ISO) 81 : #define BT_BUF_ISO_RX_SIZE BT_BUF_ISO_SIZE(CONFIG_BT_ISO_RX_MTU) 82 : #define BT_BUF_ISO_RX_COUNT CONFIG_BT_ISO_RX_BUF_COUNT 83 : #else 84 0 : #define BT_BUF_ISO_RX_SIZE 0 85 0 : #define BT_BUF_ISO_RX_COUNT 0 86 : #endif /* CONFIG_BT_ISO */ 87 : 88 : /* see Core Spec v6.0 vol.4 part E 7.4.5 */ 89 0 : #define BT_BUF_ACL_RX_COUNT_MAX 65535 90 : 91 : #if defined(CONFIG_BT_CONN) && defined(CONFIG_BT_HCI_HOST) 92 : /* The host needs more ACL buffers than maximum ACL links. This is because of 93 : * the way we re-assemble ACL packets into L2CAP PDUs. 94 : * 95 : * We keep around the first buffer (that comes from the driver) to do 96 : * re-assembly into, and if all links are re-assembling, there will be no buffer 97 : * available for the HCI driver to allocate from. 98 : * 99 : * TODO: When CONFIG_BT_BUF_ACL_RX_COUNT is removed, 100 : * remove the MAX and only keep (CONFIG_BT_MAX_CONN + 1) 101 : */ 102 : #define BT_BUF_ACL_RX_COUNT \ 103 : (MAX(CONFIG_BT_BUF_ACL_RX_COUNT, (CONFIG_BT_MAX_CONN + 1)) + \ 104 : CONFIG_BT_BUF_ACL_RX_COUNT_EXTRA) 105 : #else 106 0 : #define BT_BUF_ACL_RX_COUNT 0 107 : #endif /* CONFIG_BT_CONN && CONFIG_BT_HCI_HOST */ 108 : 109 : #if defined(CONFIG_BT_BUF_ACL_RX_COUNT) && CONFIG_BT_BUF_ACL_RX_COUNT > 0 110 : #warning "CONFIG_BT_BUF_ACL_RX_COUNT is deprecated, see Zephyr 4.1 migration guide" 111 : #endif /* CONFIG_BT_BUF_ACL_RX_COUNT && CONFIG_BT_BUF_ACL_RX_COUNT > 0 */ 112 : 113 : BUILD_ASSERT(BT_BUF_ACL_RX_COUNT <= BT_BUF_ACL_RX_COUNT_MAX, 114 : "Maximum number of ACL RX buffer is 65535, reduce CONFIG_BT_BUF_ACL_RX_COUNT_EXTRA"); 115 : 116 : /** Data size needed for HCI ACL, HCI ISO or Event RX buffers */ 117 1 : #define BT_BUF_RX_SIZE (MAX(MAX(BT_BUF_ACL_RX_SIZE, BT_BUF_EVT_RX_SIZE), \ 118 : BT_BUF_ISO_RX_SIZE)) 119 : 120 : /** Buffer count needed for HCI ACL, HCI ISO or Event RX buffers */ 121 1 : #define BT_BUF_RX_COUNT (MAX(MAX(CONFIG_BT_BUF_EVT_RX_COUNT, \ 122 : BT_BUF_ACL_RX_COUNT), \ 123 : BT_BUF_ISO_RX_COUNT)) 124 : 125 : /** Data size needed for HCI Command buffers. */ 126 1 : #define BT_BUF_CMD_TX_SIZE BT_BUF_CMD_SIZE(CONFIG_BT_BUF_CMD_TX_SIZE) 127 : 128 : /** Allocate a buffer for incoming data 129 : * 130 : * This will set the buffer type so bt_buf_set_type() does not need to 131 : * be explicitly called. 132 : * 133 : * @param type Type of buffer. Only BT_BUF_EVT, BT_BUF_ACL_IN and BT_BUF_ISO_IN 134 : * are allowed. 135 : * @param timeout Non-negative waiting period to obtain a buffer or one of the 136 : * special values K_NO_WAIT and K_FOREVER. 137 : * @return A new buffer. 138 : */ 139 1 : struct net_buf *bt_buf_get_rx(enum bt_buf_type type, k_timeout_t timeout); 140 : 141 : /** A callback to notify about freed buffer in the incoming data pool. 142 : * 143 : * This callback is called when a buffer of a given type is freed and can be requested through the 144 : * @ref bt_buf_get_rx function. However, this callback is called from the context of the buffer 145 : * freeing operation and must not attempt to allocate a new buffer from the same pool. 146 : * 147 : * @warning When this callback is called, the scheduler is locked and the callee must not perform 148 : * any action that makes the current thread unready. This callback must only be used for very 149 : * short non-blocking operation (e.g. submitting a work item). 150 : * 151 : * @param type_mask A bit mask of buffer types that have been freed. 152 : */ 153 1 : typedef void (*bt_buf_rx_freed_cb_t)(enum bt_buf_type type_mask); 154 : 155 : /** Set the callback to notify about freed buffer in the incoming data pool. 156 : * 157 : * @param cb Callback to notify about freed buffer in the incoming data pool. If NULL, the callback 158 : * is disabled. 159 : */ 160 1 : void bt_buf_rx_freed_cb_set(bt_buf_rx_freed_cb_t cb); 161 : 162 : /** Allocate a buffer for outgoing data 163 : * 164 : * This will set the buffer type so bt_buf_set_type() does not need to 165 : * be explicitly called. 166 : * 167 : * @param type Type of buffer. Only BT_BUF_CMD, BT_BUF_ACL_OUT or 168 : * BT_BUF_H4, when operating on H:4 mode, are allowed. 169 : * @param timeout Non-negative waiting period to obtain a buffer or one of the 170 : * special values K_NO_WAIT and K_FOREVER. 171 : * @param data Initial data to append to buffer. 172 : * @param size Initial data size. 173 : * @return A new buffer. 174 : */ 175 1 : struct net_buf *bt_buf_get_tx(enum bt_buf_type type, k_timeout_t timeout, 176 : const void *data, size_t size); 177 : 178 : /** Allocate a buffer for an HCI Event 179 : * 180 : * This will set the buffer type so bt_buf_set_type() does not need to 181 : * be explicitly called. 182 : * 183 : * @param evt HCI event code 184 : * @param discardable Whether the driver considers the event discardable. 185 : * @param timeout Non-negative waiting period to obtain a buffer or one of 186 : * the special values K_NO_WAIT and K_FOREVER. 187 : * @return A new buffer. 188 : */ 189 1 : struct net_buf *bt_buf_get_evt(uint8_t evt, bool discardable, k_timeout_t timeout); 190 : 191 : /** Set the buffer type 192 : * 193 : * @param buf Bluetooth buffer 194 : * @param type The BT_* type to set the buffer to 195 : */ 196 1 : static inline void bt_buf_set_type(struct net_buf *buf, enum bt_buf_type type) 197 : { 198 : ((struct bt_buf_data *)net_buf_user_data(buf))->type = type; 199 : } 200 : 201 : /** Get the buffer type 202 : * 203 : * @param buf Bluetooth buffer 204 : * 205 : * @return The BT_* type to of the buffer 206 : */ 207 1 : static inline enum bt_buf_type bt_buf_get_type(struct net_buf *buf) 208 : { 209 : return (enum bt_buf_type)((struct bt_buf_data *)net_buf_user_data(buf)) 210 : ->type; 211 : } 212 : 213 : /** 214 : * @} 215 : */ 216 : 217 : #ifdef __cplusplus 218 : } 219 : #endif 220 : 221 : #endif /* ZEPHYR_INCLUDE_BLUETOOTH_BUF_H_ */