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