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