1 /* Copyright (c) 2023 Nordic Semiconductor ASA
2  * SPDX-License-Identifier: Apache-2.0
3  */
4 
5 #include <zephyr/kernel.h>
6 #include <zephyr/sys/__assert.h>
7 #include <zephyr/sys/time_units.h>
8 #include <zephyr/toolchain/common.h>
9 #include <errno.h>
10 #include <stddef.h>
11 #include <string.h>
12 
13 #include <zephyr/kernel.h>
14 #include <zephyr/arch/cpu.h>
15 #include <zephyr/sys/byteorder.h>
16 #include <zephyr/logging/log.h>
17 #include <zephyr/sys/util.h>
18 
19 #include <zephyr/device.h>
20 #include <zephyr/init.h>
21 #include <zephyr/drivers/uart.h>
22 
23 #include <zephyr/usb/usb_device.h>
24 
25 #include <zephyr/net_buf.h>
26 #include <zephyr/bluetooth/bluetooth.h>
27 #include <zephyr/bluetooth/l2cap.h>
28 #include <zephyr/bluetooth/hci.h>
29 #include <zephyr/bluetooth/buf.h>
30 #include <zephyr/bluetooth/hci_raw.h>
31 
32 LOG_MODULE_REGISTER(hci_uart_async, LOG_LEVEL_DBG);
33 
34 static const struct device *const hci_uart_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_c2h_uart));
35 
36 static K_THREAD_STACK_DEFINE(h2c_thread_stack, CONFIG_BT_HCI_TX_STACK_SIZE);
37 static struct k_thread h2c_thread;
38 
39 struct k_poll_signal uart_h2c_rx_sig;
40 struct k_poll_signal uart_c2h_tx_sig;
41 
42 static K_FIFO_DEFINE(c2h_queue);
43 
44 /** Send raw data on c2h UART.
45  *
46  * Blocks until completion. Not thread-safe.
47  *
48  * @retval 0 on success
49  * @retval -EBUSY Another transmission is in progress. This a
50  * thread-safety violation.
51  * @retval -errno @ref uart_tx error.
52  */
uart_c2h_tx(const uint8_t * data,size_t size)53 static int uart_c2h_tx(const uint8_t *data, size_t size)
54 {
55 	int err;
56 	struct k_poll_signal *sig = &uart_c2h_tx_sig;
57 	struct k_poll_event done[] = {
58 		K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, sig),
59 	};
60 
61 	k_poll_signal_reset(sig);
62 	err = uart_tx(hci_uart_dev, data, size, SYS_FOREVER_US);
63 
64 	if (err) {
65 		LOG_ERR("uart c2h tx: err %d", err);
66 		return err;
67 	}
68 
69 	err = k_poll(done, ARRAY_SIZE(done), K_FOREVER);
70 	__ASSERT_NO_MSG(err == 0);
71 
72 	return 0;
73 }
74 
75 /* Function expects that type is validated and only CMD, ISO or ACL will be used. */
hci_payload_size(const uint8_t * hdr_buf,uint8_t h4_type)76 static uint32_t hci_payload_size(const uint8_t *hdr_buf, uint8_t h4_type)
77 {
78 	switch (h4_type) {
79 	case BT_HCI_H4_CMD:
80 		return ((const struct bt_hci_cmd_hdr *)hdr_buf)->param_len;
81 	case BT_HCI_H4_ACL:
82 		return sys_le16_to_cpu(((const struct bt_hci_acl_hdr *)hdr_buf)->len);
83 	case BT_HCI_H4_ISO:
84 		return bt_iso_hdr_len(
85 			sys_le16_to_cpu(((const struct bt_hci_iso_hdr *)hdr_buf)->len));
86 	default:
87 		LOG_ERR("Invalid type: %u", h4_type);
88 		return 0;
89 	}
90 }
91 
hci_hdr_size(uint8_t h4_type)92 static uint8_t hci_hdr_size(uint8_t h4_type)
93 {
94 	switch (h4_type) {
95 	case BT_HCI_H4_CMD:
96 		return sizeof(struct bt_hci_cmd_hdr);
97 	case BT_HCI_H4_ACL:
98 		return sizeof(struct bt_hci_acl_hdr);
99 	case BT_HCI_H4_ISO:
100 		return sizeof(struct bt_hci_iso_hdr);
101 	default:
102 		LOG_ERR("Unexpected h4 type: %u", h4_type);
103 		return 0;
104 	}
105 }
106 
107 /** Send raw data on c2h UART.
108  *
109  * Blocks until either @p size has been received or special UART
110  * condition occurs on the UART RX line, like an UART break or parity
111  * error.
112  *
113  * Not thread-safe.
114  *
115  * @retval 0 on success
116  * @retval -EBUSY Another transmission is in progress. This a
117  * thread-safety violation.
118  * @retval -errno @ref uart_rx_enable error.
119  * @retval +stop_reason Special condition @ref uart_rx_stop_reason.
120  */
uart_h2c_rx(uint8_t * dst,size_t size)121 static int uart_h2c_rx(uint8_t *dst, size_t size)
122 {
123 	int err;
124 	struct k_poll_signal *sig = &uart_h2c_rx_sig;
125 	struct k_poll_event done[] = {
126 		K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, sig),
127 	};
128 
129 	k_poll_signal_reset(sig);
130 	err = uart_rx_enable(hci_uart_dev, dst, size, SYS_FOREVER_US);
131 
132 	if (err) {
133 		LOG_ERR("uart h2c rx: err %d", err);
134 		return err;
135 	}
136 
137 	k_poll(done, ARRAY_SIZE(done), K_FOREVER);
138 	return sig->result;
139 }
140 
141 /** Inject a HCI EVT Hardware error into the c2h packet stream.
142  *
143  * This uses `bt_recv`, just as if the controller is sending the error.
144  */
send_hw_error(void)145 static void send_hw_error(void)
146 {
147 	const uint8_t err_code = 0;
148 	const uint8_t hci_evt_hw_err[] = {BT_HCI_EVT_HARDWARE_ERROR,
149 					  sizeof(struct bt_hci_evt_hardware_error), err_code};
150 
151 	struct net_buf *buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
152 
153 	net_buf_add_u8(buf, BT_HCI_H4_EVT);
154 	net_buf_add_mem(buf, hci_evt_hw_err, sizeof(hci_evt_hw_err));
155 
156 	/* Inject the message into the c2h queue. */
157 	k_fifo_put(&c2h_queue, buf);
158 
159 	/* The c2h thread will send the message at some point. The host
160 	 * will receive it and reset the controller.
161 	 */
162 }
163 
recover_sync_by_reset_pattern(void)164 static void recover_sync_by_reset_pattern(void)
165 {
166 	/* { BT_HCI_H4_CMD, le_16(HCI_CMD_OP_RESET), len=0 } */
167 	const uint8_t h4_cmd_reset[] = {0x01, 0x03, 0x0C, 0x00};
168 	const uint32_t reset_pattern = sys_get_be32(h4_cmd_reset);
169 	int err;
170 	struct net_buf *h2c_cmd_reset;
171 	uint32_t shift_register = 0;
172 
173 	LOG_DBG("Looking for reset pattern");
174 
175 	while (shift_register != reset_pattern) {
176 		uint8_t read_byte;
177 
178 		uart_h2c_rx(&read_byte, sizeof(uint8_t));
179 		LOG_DBG("h2c: 0x%02x", read_byte);
180 		shift_register = (shift_register * 0x100) + read_byte;
181 	}
182 
183 	LOG_DBG("Pattern found");
184 	h2c_cmd_reset = bt_buf_get_tx(BT_BUF_H4, K_FOREVER, h4_cmd_reset, sizeof(h4_cmd_reset));
185 	LOG_DBG("Fowarding reset");
186 
187 	err = bt_send(h2c_cmd_reset);
188 	__ASSERT(!err, "Failed to send reset: %d", err);
189 }
190 
h2c_h4_transport(void)191 static void h2c_h4_transport(void)
192 {
193 	/* When entering this function, the h2c stream should be
194 	 * 'synchronized'. I.e. The stream should be at a H4 packet
195 	 * boundary.
196 	 *
197 	 * This function returns to signal a desynchronization.
198 	 * When this happens, the caller should resynchronize before
199 	 * entering this function again. It's up to the caller to decide
200 	 * how to resynchronize.
201 	 */
202 
203 	for (;;) {
204 		int err;
205 		struct net_buf *buf;
206 		uint8_t h4_type;
207 		uint8_t hdr_size;
208 		uint8_t *hdr_buf;
209 		uint16_t payload_size;
210 
211 		LOG_DBG("h2c: listening");
212 
213 		/* Read H4 type. */
214 		err = uart_h2c_rx(&h4_type, sizeof(uint8_t));
215 
216 		if (err) {
217 			return;
218 		}
219 		LOG_DBG("h2c: h4_type %d", h4_type);
220 
221 		/* Allocate buf. */
222 		buf = bt_buf_get_tx(BT_BUF_H4, K_FOREVER, &h4_type, sizeof(h4_type));
223 		LOG_DBG("h2c: buf %p", buf);
224 
225 		if (!buf) {
226 			/* `h4_type` was invalid. */
227 			__ASSERT_NO_MSG(hci_hdr_size(h4_type) == 0);
228 
229 			LOG_WRN("bt_buf_get_tx failed h4_type %d", h4_type);
230 			return;
231 		}
232 
233 		/* Read HCI header. */
234 		hdr_size = hci_hdr_size(h4_type);
235 		hdr_buf = net_buf_add(buf, hdr_size);
236 
237 		err = uart_h2c_rx(hdr_buf, hdr_size);
238 		if (err) {
239 			net_buf_unref(buf);
240 			return;
241 		}
242 		LOG_HEXDUMP_DBG(hdr_buf, hdr_size, "h2c: hci hdr");
243 
244 		/* Read HCI payload. */
245 		payload_size = hci_payload_size(hdr_buf, h4_type);
246 
247 		LOG_DBG("h2c: payload_size %u", payload_size);
248 
249 		if (payload_size == 0) {
250 			/* Done, dont rx zero bytes */
251 		} else if (payload_size <= net_buf_tailroom(buf)) {
252 			uint8_t *payload_dst = net_buf_add(buf, payload_size);
253 
254 			err = uart_h2c_rx(payload_dst, payload_size);
255 			if (err) {
256 				net_buf_unref(buf);
257 				return;
258 			}
259 			LOG_HEXDUMP_DBG(payload_dst, payload_size, "h2c: hci payload");
260 		} else {
261 			/* Discard oversize packet. */
262 			uint8_t *discard_dst;
263 			uint16_t discard_size;
264 
265 			LOG_WRN("h2c: Discarding oversize h4_type %d payload_size %d.", h4_type,
266 				payload_size);
267 
268 			/* Reset `buf` so all of it is available. */
269 			net_buf_reset(buf);
270 			discard_dst = net_buf_tail(buf);
271 			discard_size = net_buf_max_len(buf);
272 
273 			while (payload_size) {
274 				uint16_t read_size = MIN(payload_size, discard_size);
275 
276 				err = uart_h2c_rx(discard_dst, read_size);
277 				if (err) {
278 					net_buf_unref(buf);
279 					return;
280 				}
281 
282 				payload_size -= read_size;
283 			}
284 
285 			net_buf_unref(buf);
286 			buf = NULL;
287 		}
288 
289 		LOG_DBG("h2c: packet done");
290 
291 		/* Route buf to Controller. */
292 		if (buf) {
293 			err = bt_send(buf);
294 			if (err) {
295 				/* This is not a transport error. */
296 				LOG_ERR("bt_send err %d", err);
297 				net_buf_unref(buf);
298 				buf = NULL;
299 			}
300 		}
301 
302 		k_yield();
303 	}
304 }
305 
h2c_thread_entry(void * p1,void * p2,void * p3)306 static void h2c_thread_entry(void *p1, void *p2, void *p3)
307 {
308 	k_thread_name_set(k_current_get(), "HCI TX (h2c)");
309 
310 	for (;;) {
311 		LOG_DBG("Synchronized");
312 		h2c_h4_transport();
313 		LOG_WRN("Desynchronized");
314 		send_hw_error();
315 		recover_sync_by_reset_pattern();
316 	}
317 }
318 
callback(const struct device * dev,struct uart_event * evt,void * user_data)319 void callback(const struct device *dev, struct uart_event *evt, void *user_data)
320 {
321 	ARG_UNUSED(user_data);
322 
323 	if (evt->type == UART_RX_DISABLED) {
324 		(void)k_poll_signal_raise(&uart_h2c_rx_sig, 0);
325 	} else if (evt->type == UART_RX_STOPPED) {
326 		(void)k_poll_signal_raise(&uart_h2c_rx_sig, evt->data.rx_stop.reason);
327 	} else if (evt->type == UART_TX_DONE) {
328 		(void)k_poll_signal_raise(&uart_c2h_tx_sig, 0);
329 	}
330 }
331 
hci_uart_init(void)332 static int hci_uart_init(void)
333 {
334 	int err;
335 
336 	k_poll_signal_init(&uart_h2c_rx_sig);
337 	k_poll_signal_init(&uart_c2h_tx_sig);
338 
339 	LOG_DBG("");
340 
341 	if (!device_is_ready(hci_uart_dev)) {
342 		LOG_ERR("HCI UART %s is not ready", hci_uart_dev->name);
343 		return -EINVAL;
344 	}
345 
346 	BUILD_ASSERT(IS_ENABLED(CONFIG_UART_ASYNC_API));
347 	err = uart_callback_set(hci_uart_dev, callback, NULL);
348 
349 	/* Note: Asserts if CONFIG_UART_ASYNC_API is not enabled for `hci_uart_dev`. */
350 	__ASSERT(!err, "err %d", err);
351 
352 	return 0;
353 }
354 
355 SYS_INIT(hci_uart_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
356 
357 const struct {
358 	uint8_t h4;
359 	struct bt_hci_evt_hdr hdr;
360 	struct bt_hci_evt_cmd_complete cc;
361 } __packed cc_evt = {
362 	.h4 = BT_HCI_H4_EVT,
363 	.hdr = {.evt = BT_HCI_EVT_CMD_COMPLETE, .len = sizeof(struct bt_hci_evt_cmd_complete)},
364 	.cc = {.ncmd = 1, .opcode = sys_cpu_to_le16(BT_OP_NOP)},
365 };
366 
c2h_thread_entry(void)367 static void c2h_thread_entry(void)
368 {
369 	k_thread_name_set(k_current_get(), "HCI RX (c2h)");
370 
371 	if (IS_ENABLED(CONFIG_BT_WAIT_NOP)) {
372 		uart_c2h_tx((char *)&cc_evt, sizeof(cc_evt));
373 	}
374 
375 	for (;;) {
376 		struct net_buf *buf;
377 
378 		buf = k_fifo_get(&c2h_queue, K_FOREVER);
379 		uart_c2h_tx(buf->data, buf->len);
380 		net_buf_unref(buf);
381 	}
382 }
383 
hci_uart_main(void)384 void hci_uart_main(void)
385 {
386 	int err;
387 
388 	err = bt_enable_raw(&c2h_queue);
389 	__ASSERT_NO_MSG(!err);
390 
391 	/* TX thread. */
392 	k_thread_create(&h2c_thread, h2c_thread_stack, K_THREAD_STACK_SIZEOF(h2c_thread_stack),
393 			h2c_thread_entry, NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT);
394 
395 	/* Reuse current thread as RX thread. */
396 	c2h_thread_entry();
397 }
398