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