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 <ble_types/types.h>
22 #include <net/buf.h>
23 #include <bluetooth/hci.h>
24 
25 /** Possible types of buffers passed around the Bluetooth stack */
26 enum bt_buf_type {
27 	/** HCI command */
28 	BT_BUF_CMD,
29 	/** HCI event */
30 	BT_BUF_EVT,
31 	/** Outgoing ACL data */
32 	BT_BUF_ACL_OUT,
33 	/** Incoming ACL data */
34 	BT_BUF_ACL_IN,
35 	/** H:4 data */
36 	BT_BUF_H4,
37 };
38 
39 /** Minimum amount of user data size for buffers passed to the stack. */
40 #define BT_BUF_USER_DATA_MIN 4 // __DEPRECATED_MACRO
41 
42 #if defined(CONFIG_BT_HCI_RAW)
43 #define BT_BUF_RESERVE MAX(CONFIG_BT_HCI_RESERVE, CONFIG_BT_HCI_RAW_RESERVE)
44 #else
45 #define BT_BUF_RESERVE CONFIG_BT_HCI_RESERVE
46 #endif
47 
48 #define BT_BUF_SIZE(size) (BT_BUF_RESERVE + (size))
49 
50 /** Data size neeed for HCI RX buffers */
51 #define BT_BUF_RX_SIZE (BT_BUF_SIZE(CONFIG_BT_RX_BUF_LEN))
52 
53 /** Allocate a buffer for incoming data
54  *
55  *  This will set the buffer type so bt_buf_set_type() does not need to
56  *  be explicitly called before bt_recv_prio().
57  *
58  *  @param type    Type of buffer. Only BT_BUF_EVT and BT_BUF_ACL_IN are
59  *                 allowed.
60  *  @param timeout Non-negative waiting period to obtain a buffer or one of the
61  *                 special values K_NO_WAIT and K_FOREVER.
62  *  @return A new buffer.
63  */
64 struct net_buf *bt_buf_get_rx(enum bt_buf_type type, k_timeout_t timeout);
65 
66 /** Allocate a buffer for outgoing data
67  *
68  *  This will set the buffer type so bt_buf_set_type() does not need to
69  *  be explicitly called before bt_send().
70  *
71  *  @param type    Type of buffer. Only BT_BUF_CMD, BT_BUF_ACL_OUT or
72  *                 BT_BUF_H4, when operating on H:4 mode, are allowed.
73  *  @param timeout Non-negative waiting period to obtain a buffer or one of the
74  *                 special values K_NO_WAIT and K_FOREVER.
75  *  @param data    Initial data to append to buffer.
76  *  @param size    Initial data size.
77  *  @return A new buffer.
78  */
79 struct net_buf *bt_buf_get_tx(enum bt_buf_type type, k_timeout_t timeout,
80 			      const void *data, size_t size);
81 
82 /** Allocate a buffer for an HCI Command Complete/Status Event
83  *
84  *  This will set the buffer type so bt_buf_set_type() does not need to
85  *  be explicitly called before bt_recv_prio().
86  *
87  *  @param timeout Non-negative waiting period to obtain a buffer or one of the
88  *                 special values K_NO_WAIT and K_FOREVER.
89  *  @return A new buffer.
90  */
91 struct net_buf *bt_buf_get_cmd_complete(k_timeout_t timeout);
92 
93 /** Allocate a buffer for an HCI Event
94  *
95  *  This will set the buffer type so bt_buf_set_type() does not need to
96  *  be explicitly called before bt_recv_prio() or bt_recv().
97  *
98  *  @param evt          HCI event code
99  *  @param discardable  Whether the driver considers the event discardable.
100  *  @param timeout      Non-negative waiting period to obtain a buffer or one of
101  *                      the special values K_NO_WAIT and K_FOREVER.
102  *  @return A new buffer.
103  */
104 struct net_buf *bt_buf_get_evt(u8_t evt, bool discardable, k_timeout_t timeout);
105 
106 /** Set the buffer type
107  *
108  *  @param buf   Bluetooth buffer
109  *  @param type  The BT_* type to set the buffer to
110  */
bt_buf_set_type(struct net_buf * buf,enum bt_buf_type type)111 static inline void bt_buf_set_type(struct net_buf *buf, enum bt_buf_type type)
112 {
113 	*(u8_t *)net_buf_user_data(buf) = type;
114 }
115 
116 /** Get the buffer type
117  *
118  *  @param buf   Bluetooth buffer
119  *
120  *  @return The BT_* type to of the buffer
121  */
bt_buf_get_type(struct net_buf * buf)122 static inline enum bt_buf_type bt_buf_get_type(struct net_buf *buf)
123 {
124 	/* De-referencing the pointer from net_buf_user_data(buf) as a
125 	 * pointer to an enum causes issues on qemu_x86 because the true
126 	 * size is 8-bit, but the enum is 32-bit on qemu_x86. So we put in
127 	 * a temporary cast to 8-bit to ensure only 8 bits are read from
128 	 * the pointer.
129 	 */
130 	return (enum bt_buf_type)(*(u8_t *)net_buf_user_data(buf));
131 }
132 
133 /**
134  * @}
135  */
136 
137 #endif /* ZEPHYR_INCLUDE_BLUETOOTH_BUF_H_ */
138