1 /*
2  * Wireless / Bluetooth USB class
3  *
4  * Copyright (c) 2018 Intel Corporation
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <zephyr/init.h>
10 #include <zephyr/sys/byteorder.h>
11 
12 #include <zephyr/usb/usb_device.h>
13 #include <usb_descriptor.h>
14 
15 #include <zephyr/net_buf.h>
16 
17 #include <zephyr/bluetooth/buf.h>
18 #include <zephyr/bluetooth/hci_raw.h>
19 #include <zephyr/bluetooth/l2cap.h>
20 #include <zephyr/bluetooth/hci_vs.h>
21 #include <zephyr/drivers/bluetooth.h>
22 #include <zephyr/sys/atomic.h>
23 
24 #include <zephyr/logging/log.h>
25 LOG_MODULE_REGISTER(usb_bluetooth, CONFIG_USB_DEVICE_LOG_LEVEL);
26 
27 #define USB_RF_SUBCLASS			0x01
28 #define USB_BLUETOOTH_PROTOCOL		0x01
29 
30 static K_FIFO_DEFINE(rx_queue);
31 static K_FIFO_DEFINE(tx_queue);
32 
33 #define BLUETOOTH_INT_EP_ADDR		0x81
34 #define BLUETOOTH_OUT_EP_ADDR		0x02
35 #define BLUETOOTH_IN_EP_ADDR		0x82
36 
37 /* HCI RX/TX threads */
38 static K_KERNEL_STACK_DEFINE(rx_thread_stack, CONFIG_BT_HCI_TX_STACK_SIZE);
39 static struct k_thread rx_thread_data;
40 static K_KERNEL_STACK_DEFINE(tx_thread_stack, 512);
41 static struct k_thread tx_thread_data;
42 
43 /* HCI USB state flags */
44 static bool configured;
45 
46 /*
47  * Shared variable between bluetooth_status_cb() and hci_tx_thread(),
48  * where hci_tx_thread() has read-only access to it.
49  */
50 static atomic_t suspended;
51 
52 static uint8_t ep_out_buf[USB_MAX_FS_BULK_MPS];
53 
54 struct usb_bluetooth_config {
55 	struct usb_if_descriptor if0;
56 	struct usb_ep_descriptor if0_int_ep;
57 	struct usb_ep_descriptor if0_out_ep;
58 	struct usb_ep_descriptor if0_in_ep;
59 } __packed;
60 
61 USBD_CLASS_DESCR_DEFINE(primary, 0)
62 	struct usb_bluetooth_config bluetooth_cfg = {
63 	/* Interface descriptor 0 */
64 	.if0 = {
65 		.bLength = sizeof(struct usb_if_descriptor),
66 		.bDescriptorType = USB_DESC_INTERFACE,
67 		.bInterfaceNumber = 0,
68 		.bAlternateSetting = 0,
69 		.bNumEndpoints = 3,
70 		.bInterfaceClass = USB_BCC_WIRELESS_CONTROLLER,
71 		.bInterfaceSubClass = USB_RF_SUBCLASS,
72 		.bInterfaceProtocol = USB_BLUETOOTH_PROTOCOL,
73 		.iInterface = 0,
74 	},
75 
76 	/* Interrupt Endpoint */
77 	.if0_int_ep = {
78 		.bLength = sizeof(struct usb_ep_descriptor),
79 		.bDescriptorType = USB_DESC_ENDPOINT,
80 		.bEndpointAddress = BLUETOOTH_INT_EP_ADDR,
81 		.bmAttributes = USB_DC_EP_INTERRUPT,
82 		.wMaxPacketSize = sys_cpu_to_le16(USB_MAX_FS_INT_MPS),
83 		.bInterval = 0x01,
84 	},
85 
86 	/* Data Endpoint OUT */
87 	.if0_out_ep = {
88 		.bLength = sizeof(struct usb_ep_descriptor),
89 		.bDescriptorType = USB_DESC_ENDPOINT,
90 		.bEndpointAddress = BLUETOOTH_OUT_EP_ADDR,
91 		.bmAttributes = USB_DC_EP_BULK,
92 		.wMaxPacketSize = sys_cpu_to_le16(USB_MAX_FS_BULK_MPS),
93 		.bInterval = 0x01,
94 	},
95 
96 	/* Data Endpoint IN */
97 	.if0_in_ep = {
98 		.bLength = sizeof(struct usb_ep_descriptor),
99 		.bDescriptorType = USB_DESC_ENDPOINT,
100 		.bEndpointAddress = BLUETOOTH_IN_EP_ADDR,
101 		.bmAttributes = USB_DC_EP_BULK,
102 		.wMaxPacketSize = sys_cpu_to_le16(USB_MAX_FS_BULK_MPS),
103 		.bInterval = 0x01,
104 	},
105 };
106 
107 #define HCI_INT_EP_IDX			0
108 #define HCI_OUT_EP_IDX			1
109 #define HCI_IN_EP_IDX			2
110 
111 static struct usb_ep_cfg_data bluetooth_ep_data[] = {
112 	{
113 		.ep_cb = usb_transfer_ep_callback,
114 		.ep_addr = BLUETOOTH_INT_EP_ADDR,
115 	},
116 	{
117 		.ep_cb = usb_transfer_ep_callback,
118 		.ep_addr = BLUETOOTH_OUT_EP_ADDR,
119 	},
120 	{
121 		.ep_cb = usb_transfer_ep_callback,
122 		.ep_addr = BLUETOOTH_IN_EP_ADDR,
123 	},
124 };
125 
hci_tx_thread(void * p1,void * p2,void * p3)126 static void hci_tx_thread(void *p1, void *p2, void *p3)
127 {
128 	ARG_UNUSED(p1);
129 	ARG_UNUSED(p2);
130 	ARG_UNUSED(p3);
131 
132 	LOG_DBG("Start USB Bluetooth thread");
133 
134 	while (true) {
135 		struct net_buf *buf;
136 		uint8_t type;
137 
138 		buf = k_fifo_get(&tx_queue, K_FOREVER);
139 
140 		if (atomic_get(&suspended)) {
141 			if (usb_wakeup_request()) {
142 				LOG_DBG("Remote wakeup not enabled/supported");
143 			}
144 			/*
145 			 * Let's wait until operation is resumed.
146 			 * This is independent of usb_wakeup_request() result,
147 			 * as long as device is suspended it should not start
148 			 * any transfers.
149 			 */
150 			while (atomic_get(&suspended)) {
151 				k_sleep(K_MSEC(1));
152 			}
153 		}
154 
155 		type = net_buf_pull_u8(buf);
156 		switch (type) {
157 		case BT_HCI_H4_EVT:
158 			usb_transfer_sync(
159 				bluetooth_ep_data[HCI_INT_EP_IDX].ep_addr,
160 				buf->data, buf->len,
161 				USB_TRANS_WRITE | USB_TRANS_NO_ZLP);
162 			break;
163 		case BT_HCI_H4_ACL:
164 			usb_transfer_sync(
165 				bluetooth_ep_data[HCI_IN_EP_IDX].ep_addr,
166 				buf->data, buf->len,
167 				USB_TRANS_WRITE);
168 			break;
169 		default:
170 			LOG_ERR("Unsupported type %u", type);
171 			break;
172 		}
173 
174 		net_buf_unref(buf);
175 	}
176 }
177 
hci_rx_thread(void * p1,void * p2,void * p3)178 static void hci_rx_thread(void *p1, void *p2, void *p3)
179 {
180 	ARG_UNUSED(p1);
181 	ARG_UNUSED(p2);
182 	ARG_UNUSED(p3);
183 
184 	while (true) {
185 		struct net_buf *buf;
186 		int err;
187 
188 		buf = k_fifo_get(&rx_queue, K_FOREVER);
189 
190 		err = bt_send(buf);
191 		if (err) {
192 			LOG_ERR("Error sending to driver");
193 			net_buf_unref(buf);
194 		}
195 	}
196 }
197 
hci_acl_pkt_len(const uint8_t * data,size_t data_len)198 static uint16_t hci_acl_pkt_len(const uint8_t *data, size_t data_len)
199 {
200 	struct bt_hci_acl_hdr *acl_hdr;
201 	size_t hdr_len = sizeof(*acl_hdr);
202 
203 	if (data_len < hdr_len) {
204 		return 0;
205 	}
206 
207 	acl_hdr = (struct bt_hci_acl_hdr *)data;
208 
209 	return sys_le16_to_cpu(acl_hdr->len) + hdr_len;
210 }
211 
acl_read_cb(uint8_t ep,int size,void * priv)212 static void acl_read_cb(uint8_t ep, int size, void *priv)
213 {
214 	static struct net_buf *buf;
215 	static uint16_t pkt_len;
216 	uint8_t *data = ep_out_buf;
217 
218 	if (size == 0) {
219 		goto restart_out_transfer;
220 	}
221 
222 	if (buf == NULL) {
223 		buf = bt_buf_get_tx(BT_BUF_ACL_OUT, K_FOREVER, data, size);
224 		if (!buf) {
225 			LOG_ERR("Failed to allocate buffer");
226 			goto restart_out_transfer;
227 		}
228 
229 		pkt_len = hci_acl_pkt_len(data, size);
230 		LOG_DBG("pkt_len %u, chunk %u", pkt_len, size);
231 
232 		if (pkt_len == 0) {
233 			LOG_ERR("Failed to get packet length");
234 			net_buf_unref(buf);
235 			buf = NULL;
236 		}
237 	} else {
238 		if (net_buf_tailroom(buf) < size) {
239 			LOG_ERR("Buffer tailroom too small");
240 			net_buf_unref(buf);
241 			buf = NULL;
242 			goto restart_out_transfer;
243 		}
244 
245 		/*
246 		 * Take over the next chunk if HCI packet is
247 		 * larger than USB_MAX_FS_BULK_MPS.
248 		 */
249 		net_buf_add_mem(buf, data, size);
250 		LOG_DBG("len %u, chunk %u", buf->len, size);
251 	}
252 
253 	if (buf != NULL && pkt_len == buf->len - 1) {
254 		k_fifo_put(&rx_queue, buf);
255 		LOG_DBG("put");
256 		buf = NULL;
257 		pkt_len = 0;
258 	}
259 
260 restart_out_transfer:
261 	usb_transfer(bluetooth_ep_data[HCI_OUT_EP_IDX].ep_addr, ep_out_buf,
262 		     sizeof(ep_out_buf), USB_TRANS_READ,
263 		     acl_read_cb, NULL);
264 }
265 
bluetooth_status_cb(struct usb_cfg_data * cfg,enum usb_dc_status_code status,const uint8_t * param)266 static void bluetooth_status_cb(struct usb_cfg_data *cfg,
267 				enum usb_dc_status_code status,
268 				const uint8_t *param)
269 {
270 	ARG_UNUSED(cfg);
271 	atomic_val_t tmp;
272 
273 	/* Check the USB status and do needed action if required */
274 	switch (status) {
275 	case USB_DC_RESET:
276 		LOG_DBG("Device reset detected");
277 		configured = false;
278 		atomic_clear(&suspended);
279 		break;
280 	case USB_DC_CONFIGURED:
281 		LOG_DBG("Device configured");
282 		if (!configured) {
283 			configured = true;
284 			/* Start reading */
285 			acl_read_cb(bluetooth_ep_data[HCI_OUT_EP_IDX].ep_addr,
286 				    0, NULL);
287 		}
288 		break;
289 	case USB_DC_DISCONNECTED:
290 		LOG_DBG("Device disconnected");
291 		/* Cancel any transfer */
292 		usb_cancel_transfer(bluetooth_ep_data[HCI_INT_EP_IDX].ep_addr);
293 		usb_cancel_transfer(bluetooth_ep_data[HCI_IN_EP_IDX].ep_addr);
294 		usb_cancel_transfer(bluetooth_ep_data[HCI_OUT_EP_IDX].ep_addr);
295 		configured = false;
296 		atomic_clear(&suspended);
297 		break;
298 	case USB_DC_SUSPEND:
299 		LOG_DBG("Device suspended");
300 		atomic_set(&suspended, 1);
301 		break;
302 	case USB_DC_RESUME:
303 		tmp = atomic_clear(&suspended);
304 		if (tmp) {
305 			LOG_DBG("Device resumed from suspend");
306 		} else {
307 			LOG_DBG("Spurious resume event");
308 		}
309 		break;
310 	case USB_DC_UNKNOWN:
311 	default:
312 		LOG_DBG("Unknown state");
313 		break;
314 	}
315 }
316 
bluetooth_class_handler(struct usb_setup_packet * setup,int32_t * len,uint8_t ** data)317 static int bluetooth_class_handler(struct usb_setup_packet *setup,
318 				   int32_t *len, uint8_t **data)
319 {
320 	struct net_buf *buf;
321 
322 	if (usb_reqtype_is_to_host(setup) ||
323 	    setup->RequestType.type != USB_REQTYPE_TYPE_CLASS) {
324 		return -ENOTSUP;
325 	}
326 
327 	LOG_DBG("len %u", *len);
328 
329 	buf = bt_buf_get_tx(BT_BUF_CMD, K_NO_WAIT, *data, *len);
330 	if (!buf) {
331 		LOG_ERR("Cannot get free buffer\n");
332 		return -ENOMEM;
333 	}
334 
335 	k_fifo_put(&rx_queue, buf);
336 
337 	return 0;
338 }
339 
bluetooth_interface_config(struct usb_desc_header * head,uint8_t bInterfaceNumber)340 static void bluetooth_interface_config(struct usb_desc_header *head,
341 				       uint8_t bInterfaceNumber)
342 {
343 	ARG_UNUSED(head);
344 
345 	bluetooth_cfg.if0.bInterfaceNumber = bInterfaceNumber;
346 }
347 
348 USBD_DEFINE_CFG_DATA(bluetooth_config) = {
349 	.usb_device_description = NULL,
350 	.interface_config = bluetooth_interface_config,
351 	.interface_descriptor = &bluetooth_cfg.if0,
352 	.cb_usb_status = bluetooth_status_cb,
353 	.interface = {
354 		.class_handler = bluetooth_class_handler,
355 		.custom_handler = NULL,
356 		.vendor_handler = NULL,
357 	},
358 	.num_endpoints = ARRAY_SIZE(bluetooth_ep_data),
359 	.endpoint = bluetooth_ep_data,
360 };
361 
bluetooth_init(void)362 static int bluetooth_init(void)
363 {
364 	int ret;
365 
366 	LOG_DBG("Initialization");
367 
368 	ret = bt_enable_raw(&tx_queue);
369 	if (ret) {
370 		LOG_ERR("Failed to open Bluetooth raw channel: %d", ret);
371 		return ret;
372 	}
373 
374 	k_thread_create(&rx_thread_data, rx_thread_stack,
375 			K_KERNEL_STACK_SIZEOF(rx_thread_stack),
376 			hci_rx_thread, NULL, NULL, NULL,
377 			K_PRIO_COOP(8), 0, K_NO_WAIT);
378 
379 	k_thread_name_set(&rx_thread_data, "usb_bt_rx");
380 
381 	k_thread_create(&tx_thread_data, tx_thread_stack,
382 			K_KERNEL_STACK_SIZEOF(tx_thread_stack),
383 			hci_tx_thread, NULL, NULL, NULL,
384 			K_PRIO_COOP(8), 0, K_NO_WAIT);
385 
386 	k_thread_name_set(&tx_thread_data, "usb_bt_tx");
387 
388 	return 0;
389 }
390 
391 SYS_INIT(bluetooth_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
392