1 /** @file
2 * @brief Bluetooth HCI driver API.
3 *
4 * Copyright (c) 2024 Johan Hedberg
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8 #ifndef ZEPHYR_INCLUDE_DRIVERS_BLUETOOTH_H_
9 #define ZEPHYR_INCLUDE_DRIVERS_BLUETOOTH_H_
10
11 /**
12 * @brief Bluetooth HCI APIs
13 * @defgroup bt_hci_api Bluetooth HCI APIs
14 *
15 * @since 3.7
16 * @version 0.2.0
17 *
18 * @ingroup bluetooth
19 * @{
20 */
21
22 #include <stdbool.h>
23 #include <stdint.h>
24 #include <zephyr/net/buf.h>
25 #include <zephyr/bluetooth/buf.h>
26 #include <zephyr/bluetooth/addr.h>
27 #include <zephyr/bluetooth/hci_vs.h>
28 #include <zephyr/device.h>
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 struct bt_hci_setup_params {
35 /** The public identity address to give to the controller. This field is used when the
36 * driver selects @kconfig{CONFIG_BT_HCI_SET_PUBLIC_ADDR} to indicate that it supports
37 * setting the controller's public address.
38 */
39 bt_addr_t public_addr;
40 };
41
42 enum {
43 /* The host should never send HCI_Reset */
44 BT_HCI_QUIRK_NO_RESET = BIT(0),
45 /* The controller does not auto-initiate a DLE procedure when the
46 * initial connection data length parameters are not equal to the
47 * default data length parameters. Therefore the host should initiate
48 * the DLE procedure after connection establishment.
49 */
50 BT_HCI_QUIRK_NO_AUTO_DLE = BIT(1),
51 };
52
53 /** Possible values for the 'bus' member of the bt_hci_driver struct */
54 enum bt_hci_bus {
55 BT_HCI_BUS_VIRTUAL = 0,
56 BT_HCI_BUS_USB = 1,
57 BT_HCI_BUS_PCCARD = 2,
58 BT_HCI_BUS_UART = 3,
59 BT_HCI_BUS_RS232 = 4,
60 BT_HCI_BUS_PCI = 5,
61 BT_HCI_BUS_SDIO = 6,
62 BT_HCI_BUS_SPI = 7,
63 BT_HCI_BUS_I2C = 8,
64 BT_HCI_BUS_IPM = 9,
65 };
66
67 #define BT_DT_HCI_QUIRK_OR(node_id, prop, idx) DT_STRING_TOKEN_BY_IDX(node_id, prop, idx)
68 #define BT_DT_HCI_QUIRKS_GET(node_id) COND_CODE_1(DT_NODE_HAS_PROP(node_id, bt_hci_quirks), \
69 (DT_FOREACH_PROP_ELEM_SEP(node_id, \
70 bt_hci_quirks, \
71 BT_DT_HCI_QUIRK_OR, \
72 (|))), \
73 (0))
74 #define BT_DT_HCI_QUIRKS_INST_GET(inst) BT_DT_HCI_QUIRKS_GET(DT_DRV_INST(inst))
75
76 #define BT_DT_HCI_NAME_GET(node_id) DT_PROP_OR(node_id, bt_hci_name, "HCI")
77 #define BT_DT_HCI_NAME_INST_GET(inst) BT_DT_HCI_NAME_GET(DT_DRV_INST(inst))
78
79 #define BT_DT_HCI_BUS_GET(node_id) DT_STRING_TOKEN_OR(node_id, bt_hci_bus, BT_HCI_BUS_VIRTUAL)
80 #define BT_DT_HCI_BUS_INST_GET(inst) BT_DT_HCI_BUS_GET(DT_DRV_INST(inst))
81
82 typedef int (*bt_hci_recv_t)(const struct device *dev, struct net_buf *buf);
83
84 __subsystem struct bt_hci_driver_api {
85 int (*open)(const struct device *dev, bt_hci_recv_t recv);
86 int (*close)(const struct device *dev);
87 int (*send)(const struct device *dev, struct net_buf *buf);
88 #if defined(CONFIG_BT_HCI_SETUP)
89 int (*setup)(const struct device *dev,
90 const struct bt_hci_setup_params *param);
91 #endif /* defined(CONFIG_BT_HCI_SETUP) */
92 };
93
94 /**
95 * @brief Open the HCI transport.
96 *
97 * Opens the HCI transport for operation. This function must not
98 * return until the transport is ready for operation, meaning it
99 * is safe to start calling the send() handler.
100 *
101 * @param dev HCI device
102 * @param recv This is callback through which the HCI driver provides the
103 * host with data from the controller. The buffer passed to
104 * the callback will have its type set with bt_buf_set_type().
105 * The callback is expected to be called from thread context.
106 *
107 * @return 0 on success or negative POSIX error number on failure.
108 */
bt_hci_open(const struct device * dev,bt_hci_recv_t recv)109 static inline int bt_hci_open(const struct device *dev, bt_hci_recv_t recv)
110 {
111 const struct bt_hci_driver_api *api = (const struct bt_hci_driver_api *)dev->api;
112
113 return api->open(dev, recv);
114 }
115
116 /**
117 * @brief Close the HCI transport.
118 *
119 * Closes the HCI transport. This function must not return until the
120 * transport is closed.
121 *
122 * @param dev HCI device
123 *
124 * @return 0 on success or negative POSIX error number on failure.
125 */
bt_hci_close(const struct device * dev)126 static inline int bt_hci_close(const struct device *dev)
127 {
128 const struct bt_hci_driver_api *api = (const struct bt_hci_driver_api *)dev->api;
129
130 if (api->close == NULL) {
131 return -ENOSYS;
132 }
133
134 return api->close(dev);
135 }
136
137 /**
138 * @brief Send HCI buffer to controller.
139 *
140 * Send an HCI packet to the controller. The packet type of the buffer
141 * must be set using bt_buf_set_type().
142 *
143 * @note This function must only be called from a cooperative thread.
144 *
145 * @param dev HCI device
146 * @param buf Buffer containing data to be sent to the controller.
147 *
148 * @return 0 on success or negative POSIX error number on failure.
149 */
bt_hci_send(const struct device * dev,struct net_buf * buf)150 static inline int bt_hci_send(const struct device *dev, struct net_buf *buf)
151 {
152 const struct bt_hci_driver_api *api = (const struct bt_hci_driver_api *)dev->api;
153
154 return api->send(dev, buf);
155 }
156
157 #if defined(CONFIG_BT_HCI_SETUP) || defined(__DOXYGEN__)
158 /**
159 * @brief HCI vendor-specific setup
160 *
161 * Executes vendor-specific commands sequence to initialize
162 * BT Controller before BT Host executes Reset sequence. This is normally
163 * called directly after bt_hci_open().
164 *
165 * @note @kconfig{CONFIG_BT_HCI_SETUP} must be selected for this
166 * field to be available.
167 *
168 * @return 0 on success or negative POSIX error number on failure.
169 */
bt_hci_setup(const struct device * dev,struct bt_hci_setup_params * params)170 static inline int bt_hci_setup(const struct device *dev, struct bt_hci_setup_params *params)
171 {
172 const struct bt_hci_driver_api *api = (const struct bt_hci_driver_api *)dev->api;
173
174 if (api->setup == NULL) {
175 return -ENOSYS;
176 }
177
178 return api->setup(dev, params);
179 }
180 #endif
181
182 /**
183 * @}
184 */
185
186 /* The following functions are not strictly part of the HCI driver API, in that
187 * they do not take as input a struct device which implements the HCI driver API.
188 */
189
190 /**
191 * @brief Setup the HCI transport, which usually means to reset the
192 * Bluetooth IC.
193 *
194 * @note A weak version of this function is included in the H4 driver, so
195 * defining it is optional per board.
196 *
197 * @param dev The device structure for the bus connecting to the IC
198 *
199 * @return 0 on success, negative error value on failure
200 */
201 int bt_hci_transport_setup(const struct device *dev);
202
203 /**
204 * @brief Teardown the HCI transport.
205 *
206 * @note A weak version of this function is included in the IPC driver, so
207 * defining it is optional. NRF5340 includes support to put network core
208 * in reset state.
209 *
210 * @param dev The device structure for the bus connecting to the IC
211 *
212 * @return 0 on success, negative error value on failure
213 */
214 int bt_hci_transport_teardown(const struct device *dev);
215
216 /** Allocate an HCI event buffer.
217 *
218 * This function allocates a new buffer for an HCI event. It is given the
219 * event code and the total length of the parameters. Upon successful return
220 * the buffer is ready to have the parameters encoded into it.
221 *
222 * @param evt HCI event OpCode.
223 * @param len Length of event parameters.
224 *
225 * @return Newly allocated buffer.
226 */
227 struct net_buf *bt_hci_evt_create(uint8_t evt, uint8_t len);
228
229 /** Allocate an HCI Command Complete event buffer.
230 *
231 * This function allocates a new buffer for HCI Command Complete event.
232 * It is given the OpCode (encoded e.g. using the BT_OP macro) and the total
233 * length of the parameters. Upon successful return the buffer is ready to have
234 * the parameters encoded into it.
235 *
236 * @param op HCI command OpCode.
237 * @param plen Length of command parameters.
238 *
239 * @return Newly allocated buffer.
240 */
241 struct net_buf *bt_hci_cmd_complete_create(uint16_t op, uint8_t plen);
242
243 /** Allocate an HCI Command Status event buffer.
244 *
245 * This function allocates a new buffer for HCI Command Status event.
246 * It is given the OpCode (encoded e.g. using the BT_OP macro) and the status
247 * code. Upon successful return the buffer is ready to have the parameters
248 * encoded into it.
249 *
250 * @param op HCI command OpCode.
251 * @param status Status code.
252 *
253 * @return Newly allocated buffer.
254 */
255 struct net_buf *bt_hci_cmd_status_create(uint16_t op, uint8_t status);
256
257 #ifdef __cplusplus
258 }
259 #endif
260
261 #endif /* ZEPHYR_INCLUDE_DRIVERS_BLUETOOTH_H_ */
262