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