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