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 <stdbool.h>
11 #include <stddef.h>
12 #include <stdint.h>
13 
14 #include <zephyr/bluetooth/buf.h>
15 #include <zephyr/bluetooth/hci.h>
16 #include <zephyr/bluetooth/hci_raw.h>
17 #include <zephyr/bluetooth/hci_types.h>
18 #include <zephyr/bluetooth/l2cap.h>
19 #include <zephyr/bluetooth/iso.h>
20 #include <zephyr/device.h>
21 #include <zephyr/devicetree.h>
22 #include <zephyr/drivers/bluetooth.h>
23 #include <zephyr/kernel.h>
24 #include <zephyr/logging/log.h>
25 #include <zephyr/net_buf.h>
26 #include <zephyr/sys/atomic.h>
27 #include <zephyr/sys/byteorder.h>
28 #include <zephyr/sys/util_macro.h>
29 #include <zephyr/sys_clock.h>
30 #include <zephyr/toolchain.h>
31 
32 #include "common/hci_common_internal.h"
33 #include "hci_raw_internal.h"
34 #include "monitor.h"
35 
36 #define LOG_LEVEL CONFIG_BT_HCI_CORE_LOG_LEVEL
37 LOG_MODULE_REGISTER(bt_hci_raw);
38 
39 static struct k_fifo *raw_rx;
40 
41 static bt_buf_rx_freed_cb_t buf_rx_freed_cb;
42 
hci_rx_buf_destroy(struct net_buf * buf)43 static void hci_rx_buf_destroy(struct net_buf *buf)
44 {
45 	net_buf_destroy(buf);
46 
47 	if (buf_rx_freed_cb) {
48 		/* bt_buf_get_rx is used for all types of RX buffers */
49 		buf_rx_freed_cb(BT_BUF_EVT | BT_BUF_ACL_IN | BT_BUF_ISO_IN);
50 	}
51 }
52 
53 NET_BUF_POOL_FIXED_DEFINE(hci_rx_pool, BT_BUF_RX_COUNT, BT_BUF_RX_SIZE, 0, hci_rx_buf_destroy);
54 NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, BT_BUF_CMD_TX_COUNT,
55 			  BT_BUF_CMD_SIZE(CONFIG_BT_BUF_CMD_TX_SIZE), 0, NULL);
56 NET_BUF_POOL_FIXED_DEFINE(hci_acl_pool, CONFIG_BT_BUF_ACL_TX_COUNT,
57 			  BT_BUF_ACL_SIZE(CONFIG_BT_BUF_ACL_TX_SIZE), 0, 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), 0, NULL);
61 #endif /* CONFIG_BT_ISO */
62 
63 #if DT_HAS_CHOSEN(zephyr_bt_hci)
64 #define BT_HCI_NODE   DT_CHOSEN(zephyr_bt_hci)
65 #define BT_HCI_DEV    DEVICE_DT_GET(BT_HCI_NODE)
66 #define BT_HCI_BUS    BT_DT_HCI_BUS_GET(BT_HCI_NODE)
67 #define BT_HCI_NAME   BT_DT_HCI_NAME_GET(BT_HCI_NODE)
68 #else
69 /* The zephyr,bt-hci chosen property is mandatory, except for unit tests */
70 BUILD_ASSERT(IS_ENABLED(CONFIG_ZTEST), "Missing DT chosen property for HCI");
71 #define BT_HCI_DEV    NULL
72 #define BT_HCI_BUS    0
73 #define BT_HCI_NAME   ""
74 #endif
75 
76 struct bt_dev_raw bt_dev = {
77 	.hci = BT_HCI_DEV,
78 };
79 
bt_buf_get_rx(enum bt_buf_type type,k_timeout_t timeout)80 struct net_buf *bt_buf_get_rx(enum bt_buf_type type, k_timeout_t timeout)
81 {
82 	struct net_buf *buf;
83 
84 	switch (type) {
85 	case BT_BUF_EVT:
86 	case BT_BUF_ACL_IN:
87 	case BT_BUF_ISO_IN:
88 		break;
89 	default:
90 		LOG_ERR("Invalid rx type: %u", type);
91 		return NULL;
92 	}
93 
94 	buf = net_buf_alloc(&hci_rx_pool, timeout);
95 	if (!buf) {
96 		return buf;
97 	}
98 
99 	net_buf_add_u8(buf, bt_buf_type_to_h4(type));
100 
101 	return buf;
102 }
103 
bt_buf_rx_freed_cb_set(bt_buf_rx_freed_cb_t cb)104 void bt_buf_rx_freed_cb_set(bt_buf_rx_freed_cb_t cb)
105 {
106 	buf_rx_freed_cb = cb;
107 }
108 
bt_buf_get_tx(enum bt_buf_type type,k_timeout_t timeout,const void * data,size_t size)109 struct net_buf *bt_buf_get_tx(enum bt_buf_type type, k_timeout_t timeout,
110 			      const void *data, size_t size)
111 {
112 	struct net_buf_pool *pool;
113 	struct net_buf *buf;
114 
115 	switch (type) {
116 	case BT_BUF_CMD:
117 		pool = &hci_cmd_pool;
118 		break;
119 	case BT_BUF_ACL_OUT:
120 		pool = &hci_acl_pool;
121 		break;
122 #if defined(CONFIG_BT_ISO)
123 	case BT_BUF_ISO_OUT:
124 		pool = &hci_iso_pool;
125 		break;
126 #endif /* CONFIG_BT_ISO */
127 	default:
128 		LOG_ERR("Invalid tx type: %u", type);
129 		return NULL;
130 	}
131 
132 	buf = net_buf_alloc(pool, timeout);
133 	if (!buf) {
134 		return buf;
135 	}
136 
137 	net_buf_add_u8(buf, bt_buf_type_to_h4(type));
138 
139 	if (data && size) {
140 		if (net_buf_tailroom(buf) < size) {
141 			net_buf_unref(buf);
142 			return NULL;
143 		}
144 
145 		net_buf_add_mem(buf, data, size);
146 	}
147 
148 	return buf;
149 }
150 
bt_buf_get_evt(uint8_t evt,bool discardable,k_timeout_t timeout)151 struct net_buf *bt_buf_get_evt(uint8_t evt, bool discardable, k_timeout_t timeout)
152 {
153 	ARG_UNUSED(evt);
154 	ARG_UNUSED(discardable);
155 
156 	return bt_buf_get_rx(BT_BUF_EVT, timeout);
157 }
158 
bt_hci_recv(const struct device * dev,struct net_buf * buf)159 int bt_hci_recv(const struct device *dev, struct net_buf *buf)
160 {
161 	uint8_t type = buf->data[0];
162 
163 	ARG_UNUSED(dev);
164 
165 	LOG_DBG("buf %p len %u", buf, buf->len);
166 
167 	bt_monitor_send(bt_monitor_opcode(type, BT_MONITOR_RX), buf->data + 1, buf->len - 1);
168 
169 	k_fifo_put(raw_rx, buf);
170 
171 	return 0;
172 }
173 
bt_send(struct net_buf * buf)174 int bt_send(struct net_buf *buf)
175 {
176 	if (buf->len == 0) {
177 		return BT_HCI_ERR_INVALID_PARAM;
178 	}
179 
180 	LOG_DBG("buf %p type %u len %u", buf, buf->data[0], buf->len);
181 
182 	bt_monitor_send(bt_monitor_opcode(buf->data[0], BT_MONITOR_TX),
183 			buf->data + 1, buf->len - 1);
184 
185 	return bt_hci_send(bt_dev.hci, buf);
186 }
187 
bt_enable_raw(struct k_fifo * rx_queue)188 int bt_enable_raw(struct k_fifo *rx_queue)
189 {
190 	int err;
191 
192 	LOG_DBG("");
193 
194 	raw_rx = rx_queue;
195 
196 	if (!device_is_ready(bt_dev.hci)) {
197 		LOG_ERR("HCI driver is not ready");
198 		return -ENODEV;
199 	}
200 
201 	bt_monitor_new_index(BT_MONITOR_TYPE_PRIMARY, BT_HCI_BUS, BT_ADDR_ANY, BT_HCI_NAME);
202 
203 	err = bt_hci_open(bt_dev.hci, bt_hci_recv);
204 	if (err) {
205 		LOG_ERR("HCI driver open failed (%d)", err);
206 		return err;
207 	}
208 
209 	LOG_INF("Lower HCI transport: %s", BT_HCI_NAME);
210 	LOG_INF("Bluetooth enabled in RAW mode");
211 
212 	return 0;
213 }
214