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 */
32 enum bt_buf_type {
33 	/** HCI command */
34 	BT_BUF_CMD,
35 	/** HCI event */
36 	BT_BUF_EVT,
37 	/** Outgoing ACL data */
38 	BT_BUF_ACL_OUT,
39 	/** Incoming ACL data */
40 	BT_BUF_ACL_IN,
41 	/** Outgoing ISO data */
42 	BT_BUF_ISO_OUT,
43 	/** Incoming ISO data */
44 	BT_BUF_ISO_IN,
45 	/** H:4 data */
46 	BT_BUF_H4,
47 };
48 
49 /** @brief This is a base type for bt_buf user data. */
50 struct bt_buf_data {
51 	uint8_t type;
52 };
53 
54 /* Headroom reserved in buffers, primarily for HCI transport encoding purposes */
55 #define BT_BUF_RESERVE 1
56 
57 /** Helper to include reserved HCI data in buffer calculations */
58 #define BT_BUF_SIZE(size) (BT_BUF_RESERVE + (size))
59 
60 /** Helper to calculate needed buffer size for HCI ACL packets */
61 #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 #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 #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 #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 #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 #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 #define BT_BUF_ISO_RX_SIZE 0
85 #define BT_BUF_ISO_RX_COUNT 0
86 #endif /* CONFIG_BT_ISO */
87 
88 /** Data size needed for HCI ACL, HCI ISO or Event RX buffers */
89 #define BT_BUF_RX_SIZE (MAX(MAX(BT_BUF_ACL_RX_SIZE, BT_BUF_EVT_RX_SIZE), \
90 			    BT_BUF_ISO_RX_SIZE))
91 
92 /** Buffer count needed for HCI ACL, HCI ISO or Event RX buffers */
93 #define BT_BUF_RX_COUNT (MAX(MAX(CONFIG_BT_BUF_EVT_RX_COUNT, \
94 				 CONFIG_BT_BUF_ACL_RX_COUNT), \
95 			     BT_BUF_ISO_RX_COUNT))
96 
97 /** Data size needed for HCI Command buffers. */
98 #define BT_BUF_CMD_TX_SIZE BT_BUF_CMD_SIZE(CONFIG_BT_BUF_CMD_TX_SIZE)
99 
100 /** Allocate a buffer for incoming data
101  *
102  *  This will set the buffer type so bt_buf_set_type() does not need to
103  *  be explicitly called.
104  *
105  *  @param type    Type of buffer. Only BT_BUF_EVT, BT_BUF_ACL_IN and BT_BUF_ISO_IN
106  *                 are allowed.
107  *  @param timeout Non-negative waiting period to obtain a buffer or one of the
108  *                 special values K_NO_WAIT and K_FOREVER.
109  *  @return A new buffer.
110  */
111 struct net_buf *bt_buf_get_rx(enum bt_buf_type type, k_timeout_t timeout);
112 
113 /** Allocate a buffer for outgoing data
114  *
115  *  This will set the buffer type so bt_buf_set_type() does not need to
116  *  be explicitly called.
117  *
118  *  @param type    Type of buffer. Only BT_BUF_CMD, BT_BUF_ACL_OUT or
119  *                 BT_BUF_H4, when operating on H:4 mode, are allowed.
120  *  @param timeout Non-negative waiting period to obtain a buffer or one of the
121  *                 special values K_NO_WAIT and K_FOREVER.
122  *  @param data    Initial data to append to buffer.
123  *  @param size    Initial data size.
124  *  @return A new buffer.
125  */
126 struct net_buf *bt_buf_get_tx(enum bt_buf_type type, k_timeout_t timeout,
127 			      const void *data, size_t size);
128 
129 /** Allocate a buffer for an HCI Event
130  *
131  *  This will set the buffer type so bt_buf_set_type() does not need to
132  *  be explicitly called.
133  *
134  *  @param evt          HCI event code
135  *  @param discardable  Whether the driver considers the event discardable.
136  *  @param timeout      Non-negative waiting period to obtain a buffer or one of
137  *                      the special values K_NO_WAIT and K_FOREVER.
138  *  @return A new buffer.
139  */
140 struct net_buf *bt_buf_get_evt(uint8_t evt, bool discardable, k_timeout_t timeout);
141 
142 /** Set the buffer type
143  *
144  *  @param buf   Bluetooth buffer
145  *  @param type  The BT_* type to set the buffer to
146  */
bt_buf_set_type(struct net_buf * buf,enum bt_buf_type type)147 static inline void bt_buf_set_type(struct net_buf *buf, enum bt_buf_type type)
148 {
149 	((struct bt_buf_data *)net_buf_user_data(buf))->type = type;
150 }
151 
152 /** Get the buffer type
153  *
154  *  @param buf   Bluetooth buffer
155  *
156  *  @return The BT_* type to of the buffer
157  */
bt_buf_get_type(struct net_buf * buf)158 static inline enum bt_buf_type bt_buf_get_type(struct net_buf *buf)
159 {
160 	return (enum bt_buf_type)((struct bt_buf_data *)net_buf_user_data(buf))
161 		->type;
162 }
163 
164 /**
165  * @}
166  */
167 
168 #ifdef __cplusplus
169 }
170 #endif
171 
172 #endif /* ZEPHYR_INCLUDE_BLUETOOTH_BUF_H_ */
173