1 /* hci_userchan.c - HCI user channel Bluetooth handling */
2
3 /*
4 * Copyright (c) 2015-2016 Intel Corporation
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #include <errno.h>
10 #include <zephyr/sys/atomic.h>
11 #include <zephyr/sys/byteorder.h>
12 #include <zephyr/devicetree.h>
13
14 #include <zephyr/drivers/bluetooth.h>
15 #include <zephyr/bluetooth/buf.h>
16 #include <zephyr/bluetooth/hci_raw.h>
17 #include <zephyr/bluetooth/l2cap.h>
18 #include <zephyr/bluetooth/iso.h>
19
20 #include <zephyr/bluetooth/hci.h>
21
22 #include "common/hci_common_internal.h"
23
24 #include "monitor.h"
25 #include "hci_raw_internal.h"
26
27 #define LOG_LEVEL CONFIG_BT_HCI_CORE_LOG_LEVEL
28 #include <zephyr/logging/log.h>
29 LOG_MODULE_REGISTER(bt_hci_raw);
30
31 static struct k_fifo *raw_rx;
32
33 #if defined(CONFIG_BT_HCI_RAW_H4_ENABLE)
34 static uint8_t raw_mode = BT_HCI_RAW_MODE_H4;
35 #else
36 static uint8_t raw_mode;
37 #endif
38
39 static bt_buf_rx_freed_cb_t buf_rx_freed_cb;
40
hci_rx_buf_destroy(struct net_buf * buf)41 static void hci_rx_buf_destroy(struct net_buf *buf)
42 {
43 net_buf_destroy(buf);
44
45 if (buf_rx_freed_cb) {
46 /* bt_buf_get_rx is used for all types of RX buffers */
47 buf_rx_freed_cb(BT_BUF_EVT | BT_BUF_ACL_IN | BT_BUF_ISO_IN);
48 }
49 }
50
51 NET_BUF_POOL_FIXED_DEFINE(hci_rx_pool, BT_BUF_RX_COUNT, BT_BUF_RX_SIZE, sizeof(struct bt_buf_data),
52 hci_rx_buf_destroy);
53 NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, BT_BUF_CMD_TX_COUNT,
54 BT_BUF_CMD_SIZE(CONFIG_BT_BUF_CMD_TX_SIZE),
55 sizeof(struct bt_buf_data), NULL);
56 NET_BUF_POOL_FIXED_DEFINE(hci_acl_pool, CONFIG_BT_BUF_ACL_TX_COUNT,
57 BT_BUF_ACL_SIZE(CONFIG_BT_BUF_ACL_TX_SIZE),
58 sizeof(struct bt_buf_data), NULL);
59 #if defined(CONFIG_BT_ISO)
60 NET_BUF_POOL_FIXED_DEFINE(hci_iso_pool, CONFIG_BT_ISO_TX_BUF_COUNT,
61 BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU),
62 sizeof(struct bt_buf_data), NULL);
63 #endif /* CONFIG_BT_ISO */
64
65 #if DT_HAS_CHOSEN(zephyr_bt_hci)
66 #define BT_HCI_NODE DT_CHOSEN(zephyr_bt_hci)
67 #define BT_HCI_DEV DEVICE_DT_GET(BT_HCI_NODE)
68 #define BT_HCI_BUS BT_DT_HCI_BUS_GET(BT_HCI_NODE)
69 #define BT_HCI_NAME BT_DT_HCI_NAME_GET(BT_HCI_NODE)
70 #else
71 /* The zephyr,bt-hci chosen property is mandatory, except for unit tests */
72 BUILD_ASSERT(IS_ENABLED(CONFIG_ZTEST), "Missing DT chosen property for HCI");
73 #define BT_HCI_DEV NULL
74 #define BT_HCI_BUS 0
75 #define BT_HCI_NAME ""
76 #endif
77
78 struct bt_dev_raw bt_dev = {
79 .hci = BT_HCI_DEV,
80 };
81 struct bt_hci_raw_cmd_ext *cmd_ext;
82 static size_t cmd_ext_size;
83
bt_buf_get_rx(enum bt_buf_type type,k_timeout_t timeout)84 struct net_buf *bt_buf_get_rx(enum bt_buf_type type, k_timeout_t timeout)
85 {
86 struct net_buf *buf;
87
88 switch (type) {
89 case BT_BUF_EVT:
90 case BT_BUF_ACL_IN:
91 case BT_BUF_ISO_IN:
92 break;
93 default:
94 LOG_ERR("Invalid rx type: %u", type);
95 return NULL;
96 }
97
98 buf = net_buf_alloc(&hci_rx_pool, timeout);
99 if (!buf) {
100 return buf;
101 }
102
103 net_buf_reserve(buf, BT_BUF_RESERVE);
104 bt_buf_set_type(buf, type);
105
106 return buf;
107 }
108
bt_buf_rx_freed_cb_set(bt_buf_rx_freed_cb_t cb)109 void bt_buf_rx_freed_cb_set(bt_buf_rx_freed_cb_t cb)
110 {
111 buf_rx_freed_cb = cb;
112 }
113
bt_buf_get_tx(enum bt_buf_type type,k_timeout_t timeout,const void * data,size_t size)114 struct net_buf *bt_buf_get_tx(enum bt_buf_type type, k_timeout_t timeout,
115 const void *data, size_t size)
116 {
117 struct net_buf_pool *pool;
118 struct net_buf *buf;
119
120 switch (type) {
121 case BT_BUF_CMD:
122 pool = &hci_cmd_pool;
123 break;
124 case BT_BUF_ACL_OUT:
125 pool = &hci_acl_pool;
126 break;
127 #if defined(CONFIG_BT_ISO)
128 case BT_BUF_ISO_OUT:
129 pool = &hci_iso_pool;
130 break;
131 #endif /* CONFIG_BT_ISO */
132 case BT_BUF_H4:
133 if (IS_ENABLED(CONFIG_BT_HCI_RAW_H4) &&
134 raw_mode == BT_HCI_RAW_MODE_H4) {
135 uint8_t h4_type = ((uint8_t *)data)[0];
136
137 switch (h4_type) {
138 case BT_HCI_H4_CMD:
139 type = BT_BUF_CMD;
140 pool = &hci_cmd_pool;
141 break;
142 case BT_HCI_H4_ACL:
143 type = BT_BUF_ACL_OUT;
144 pool = &hci_acl_pool;
145 break;
146 #if defined(CONFIG_BT_ISO)
147 case BT_HCI_H4_ISO:
148 type = BT_BUF_ISO_OUT;
149 pool = &hci_iso_pool;
150 break;
151 #endif /* CONFIG_BT_ISO */
152 default:
153 LOG_ERR("Unknown H4 type %u", h4_type);
154 return NULL;
155 }
156
157 /* Adjust data pointer to discard the header */
158 data = (uint8_t *)data + 1;
159 size--;
160 break;
161 }
162 __fallthrough;
163 default:
164 LOG_ERR("Invalid tx type: %u", type);
165 return NULL;
166 }
167
168 buf = net_buf_alloc(pool, timeout);
169 if (!buf) {
170 return buf;
171 }
172
173 net_buf_reserve(buf, BT_BUF_RESERVE);
174 bt_buf_set_type(buf, type);
175
176 if (data && size) {
177 if (net_buf_tailroom(buf) < size) {
178 net_buf_unref(buf);
179 return NULL;
180 }
181
182 net_buf_add_mem(buf, data, size);
183 }
184
185 return buf;
186 }
187
bt_buf_get_evt(uint8_t evt,bool discardable,k_timeout_t timeout)188 struct net_buf *bt_buf_get_evt(uint8_t evt, bool discardable, k_timeout_t timeout)
189 {
190 return bt_buf_get_rx(BT_BUF_EVT, timeout);
191 }
192
bt_hci_recv(const struct device * dev,struct net_buf * buf)193 int bt_hci_recv(const struct device *dev, struct net_buf *buf)
194 {
195 ARG_UNUSED(dev);
196
197 LOG_DBG("buf %p len %u", buf, buf->len);
198
199 bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len);
200
201 if (IS_ENABLED(CONFIG_BT_HCI_RAW_H4) &&
202 raw_mode == BT_HCI_RAW_MODE_H4) {
203 switch (bt_buf_get_type(buf)) {
204 case BT_BUF_EVT:
205 net_buf_push_u8(buf, BT_HCI_H4_EVT);
206 break;
207 case BT_BUF_ACL_IN:
208 net_buf_push_u8(buf, BT_HCI_H4_ACL);
209 break;
210 case BT_BUF_ISO_IN:
211 if (IS_ENABLED(CONFIG_BT_ISO)) {
212 net_buf_push_u8(buf, BT_HCI_H4_ISO);
213 break;
214 }
215 __fallthrough;
216 default:
217 LOG_ERR("Unknown type %u", bt_buf_get_type(buf));
218 return -EINVAL;
219 }
220 }
221
222 /* Queue to RAW rx queue */
223 k_fifo_put(raw_rx, buf);
224
225 return 0;
226 }
227
bt_cmd_complete_ext(uint16_t op,uint8_t status)228 static void bt_cmd_complete_ext(uint16_t op, uint8_t status)
229 {
230 struct net_buf *buf;
231 struct bt_hci_evt_cc_status *cc;
232
233 if (status == BT_HCI_ERR_EXT_HANDLED) {
234 return;
235 }
236
237 buf = bt_hci_cmd_complete_create(op, sizeof(*cc));
238 cc = net_buf_add(buf, sizeof(*cc));
239 cc->status = status;
240
241 bt_hci_recv(bt_dev.hci, buf);
242 }
243
bt_send_ext(struct net_buf * buf)244 static uint8_t bt_send_ext(struct net_buf *buf)
245 {
246 struct bt_hci_cmd_hdr *hdr;
247 struct net_buf_simple_state state;
248 int i;
249 uint16_t op;
250 uint8_t status;
251
252 status = BT_HCI_ERR_SUCCESS;
253
254 if (!cmd_ext) {
255 return status;
256 }
257
258 net_buf_simple_save(&buf->b, &state);
259
260 if (buf->len < sizeof(*hdr)) {
261 LOG_ERR("No HCI Command header");
262 return BT_HCI_ERR_INVALID_PARAM;
263 }
264
265 hdr = net_buf_pull_mem(buf, sizeof(*hdr));
266 if (buf->len < hdr->param_len) {
267 LOG_ERR("Invalid HCI CMD packet length");
268 return BT_HCI_ERR_INVALID_PARAM;
269 }
270
271 op = sys_le16_to_cpu(hdr->opcode);
272
273 for (i = 0; i < cmd_ext_size; i++) {
274 struct bt_hci_raw_cmd_ext *cmd = &cmd_ext[i];
275
276 if (cmd->op == op) {
277 if (buf->len < cmd->min_len) {
278 status = BT_HCI_ERR_INVALID_PARAM;
279 } else {
280 status = cmd->func(buf);
281 }
282
283 break;
284 }
285 }
286
287 if (status) {
288 bt_cmd_complete_ext(op, status);
289 return status;
290 }
291
292 net_buf_simple_restore(&buf->b, &state);
293
294 return status;
295 }
296
bt_send(struct net_buf * buf)297 int bt_send(struct net_buf *buf)
298 {
299 LOG_DBG("buf %p len %u", buf, buf->len);
300
301 if (buf->len == 0) {
302 return BT_HCI_ERR_INVALID_PARAM;
303 }
304
305 bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len);
306
307 if (IS_ENABLED(CONFIG_BT_HCI_RAW_CMD_EXT) &&
308 bt_buf_get_type(buf) == BT_BUF_CMD) {
309 uint8_t status;
310
311 status = bt_send_ext(buf);
312 if (status) {
313 return status;
314 }
315 }
316
317 return bt_hci_send(bt_dev.hci, buf);
318 }
319
bt_hci_raw_set_mode(uint8_t mode)320 int bt_hci_raw_set_mode(uint8_t mode)
321 {
322 LOG_DBG("mode %u", mode);
323
324 if (IS_ENABLED(CONFIG_BT_HCI_RAW_H4)) {
325 switch (mode) {
326 case BT_HCI_RAW_MODE_PASSTHROUGH:
327 case BT_HCI_RAW_MODE_H4:
328 raw_mode = mode;
329 return 0;
330 }
331 }
332
333 return -EINVAL;
334 }
335
bt_hci_raw_get_mode(void)336 uint8_t bt_hci_raw_get_mode(void)
337 {
338 if (IS_ENABLED(CONFIG_BT_HCI_RAW_H4)) {
339 return raw_mode;
340 }
341
342 return BT_HCI_RAW_MODE_PASSTHROUGH;
343 }
344
bt_hci_raw_cmd_ext_register(struct bt_hci_raw_cmd_ext * cmds,size_t size)345 void bt_hci_raw_cmd_ext_register(struct bt_hci_raw_cmd_ext *cmds, size_t size)
346 {
347 if (IS_ENABLED(CONFIG_BT_HCI_RAW_CMD_EXT)) {
348 cmd_ext = cmds;
349 cmd_ext_size = size;
350 }
351 }
352
bt_enable_raw(struct k_fifo * rx_queue)353 int bt_enable_raw(struct k_fifo *rx_queue)
354 {
355 int err;
356
357 LOG_DBG("");
358
359 raw_rx = rx_queue;
360
361 if (!device_is_ready(bt_dev.hci)) {
362 LOG_ERR("HCI driver is not ready");
363 return -ENODEV;
364 }
365
366 bt_monitor_new_index(BT_MONITOR_TYPE_PRIMARY, BT_HCI_BUS, BT_ADDR_ANY, BT_HCI_NAME);
367
368 err = bt_hci_open(bt_dev.hci, bt_hci_recv);
369 if (err) {
370 LOG_ERR("HCI driver open failed (%d)", err);
371 return err;
372 }
373
374 LOG_INF("Bluetooth enabled in RAW mode");
375
376 return 0;
377 }
378