1 /*
2  * Copyright (c) 2023 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/ztest.h>
8 #include <zephyr/usb/usbd.h>
9 #include <zephyr/usb/usbh.h>
10 
11 #include "usbh_ch9.h"
12 #include "usbh_device.h"
13 
14 #include <zephyr/logging/log.h>
15 LOG_MODULE_REGISTER(usb_test, LOG_LEVEL_INF);
16 
17 #define TEST_DEFAULT_INTERFACE		0
18 #define TEST_DEFAULT_ALTERNATE		1
19 
20 USBD_CONFIGURATION_DEFINE(test_fs_config,
21 			  USB_SCD_SELF_POWERED | USB_SCD_REMOTE_WAKEUP,
22 			  200, NULL);
23 
24 USBD_CONFIGURATION_DEFINE(test_hs_config,
25 			  USB_SCD_SELF_POWERED | USB_SCD_REMOTE_WAKEUP,
26 			  200, NULL);
27 
28 
29 USBD_DESC_LANG_DEFINE(test_lang);
30 USBD_DESC_STRING_DEFINE(test_mfg, "ZEPHYR", 1);
31 USBD_DESC_STRING_DEFINE(test_product, "Zephyr USB Test", 2);
32 USBD_DESC_STRING_DEFINE(test_sn, "0123456789ABCDEF", 3);
33 
34 USBD_DEVICE_DEFINE(test_usbd,
35 		   DEVICE_DT_GET(DT_NODELABEL(zephyr_udc0)),
36 		   0x2fe3, 0xffff);
37 
38 USBH_CONTROLLER_DEFINE(uhs_ctx, DEVICE_DT_GET(DT_NODELABEL(zephyr_uhc0)));
39 
test_cmp_string_desc(struct net_buf * const buf,const int idx)40 static int test_cmp_string_desc(struct net_buf *const buf, const int idx)
41 {
42 	static struct usbd_desc_node *desc_nd;
43 	size_t len;
44 
45 	if (idx == test_mfg.str.idx) {
46 		desc_nd = &test_mfg;
47 	} else if (idx == test_product.str.idx) {
48 		desc_nd = &test_product;
49 	} else if (idx == test_sn.str.idx) {
50 		desc_nd = &test_sn;
51 	} else {
52 		return -ENOTSUP;
53 	}
54 
55 	if (net_buf_pull_u8(buf) != desc_nd->bLength) {
56 		return -EINVAL;
57 	}
58 
59 	if (net_buf_pull_u8(buf) != USB_DESC_STRING) {
60 		return -EINVAL;
61 	}
62 
63 	LOG_HEXDUMP_DBG(buf->data, buf->len, "");
64 	len = MIN(buf->len / 2, desc_nd->bLength / 2);
65 	for (size_t i = 0; i < len; i++) {
66 		uint16_t a = net_buf_pull_le16(buf);
67 		uint16_t b = ((uint8_t *)(desc_nd->ptr))[i];
68 
69 		if (a != b) {
70 			LOG_INF("%c != %c", a, b);
71 			return -EINVAL;
72 		}
73 	}
74 
75 	return 0;
76 }
77 
ZTEST(device_next,test_get_desc_string)78 ZTEST(device_next, test_get_desc_string)
79 {
80 	const uint8_t type = USB_DESC_STRING;
81 	const uint16_t id = 0x0409;
82 	static struct usb_device *udev;
83 	struct net_buf *buf;
84 	int err;
85 
86 	udev = usbh_device_get_any(&uhs_ctx);
87 	zassert_not_null(udev, "No USB device available");
88 
89 	buf = usbh_xfer_buf_alloc(udev, UINT8_MAX);
90 	zassert_not_null(udev, "Failed to allocate buffer");
91 
92 	err = k_mutex_lock(&udev->mutex, K_MSEC(200));
93 	zassert_equal(err, 0, "Failed to lock device");
94 
95 	err = usbh_req_desc(udev, type, 1, id, UINT8_MAX, buf);
96 	zassert_equal(err, 0, "Transfer status is an error");
97 	err = test_cmp_string_desc(buf, 1);
98 	zassert_equal(err, 0, "Descriptor comparison failed");
99 
100 	net_buf_reset(buf);
101 	err = usbh_req_desc(udev, type, 2, id, UINT8_MAX, buf);
102 	zassert_equal(err, 0, "Transfer status is an error");
103 	err = test_cmp_string_desc(buf, 2);
104 	zassert_equal(err, 0, "Descriptor comparison failed");
105 
106 	net_buf_reset(buf);
107 	err = usbh_req_desc(udev, type, 3, id, UINT8_MAX, buf);
108 	zassert_equal(err, 0, "Transfer status is an error");
109 	err = test_cmp_string_desc(buf, 3);
110 	zassert_equal(err, 0, "Descriptor comparison failed");
111 
112 	k_mutex_unlock(&udev->mutex);
113 	usbh_xfer_buf_free(udev, buf);
114 }
115 
ZTEST(device_next,test_vendor_control_in)116 ZTEST(device_next, test_vendor_control_in)
117 {
118 	const uint8_t bmRequestType = (USB_REQTYPE_DIR_TO_HOST << 7) |
119 				      (USB_REQTYPE_TYPE_VENDOR << 5);
120 	static struct usb_device *udev;
121 	const uint8_t bRequest = 0x5c;
122 	const uint16_t wLength = 64;
123 	struct net_buf *buf;
124 	int err;
125 
126 	if (!IS_ENABLED(CONFIG_UHC_VIRTUAL)) {
127 		LOG_WRN("The test was skipped, controller is not supported.");
128 		return;
129 	}
130 
131 	udev = usbh_device_get_any(&uhs_ctx);
132 	zassert_not_null(udev, "No USB device available");
133 
134 	buf = usbh_xfer_buf_alloc(udev, wLength);
135 	zassert_not_null(udev, "Failed to allocate buffer");
136 
137 	err = k_mutex_lock(&udev->mutex, K_MSEC(200));
138 	zassert_equal(err, 0, "Failed to lock device");
139 
140 	/* Perform regular vendor IN transfer */
141 	for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT; i++) {
142 		net_buf_reset(buf);
143 		err = usbh_req_setup(udev, bmRequestType, bRequest, 0, 0, wLength, buf);
144 		zassert_equal(err, 0, "Transfer status is an error");
145 	}
146 
147 	/* Perform vendor IN transfer but omit status stage*/
148 	usbh_req_omit_status(true);
149 	for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT * 2; i++) {
150 		net_buf_reset(buf);
151 		err = usbh_req_setup(udev, bmRequestType, bRequest, 0, 0, wLength, buf);
152 		zassert_equal(err, 0, "Transfer status is an error");
153 	}
154 
155 	/* Perform vendor IN requests but omit data and status stage*/
156 	for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT * 2; i++) {
157 		err = usbh_req_setup(udev, bmRequestType, bRequest, 0, 0, wLength, NULL);
158 		zassert_equal(err, 0, "Transfer status is an error");
159 	}
160 
161 	usbh_req_omit_status(false);
162 
163 	/* Perform regular vendor IN transfer again */
164 	for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT; i++) {
165 		net_buf_reset(buf);
166 		err = usbh_req_setup(udev, bmRequestType, bRequest, 0, 0, wLength, buf);
167 		zassert_equal(err, 0, "Transfer status is an error");
168 	}
169 
170 	k_mutex_unlock(&udev->mutex);
171 	usbh_xfer_buf_free(udev, buf);
172 }
173 
ZTEST(device_next,test_vendor_control_out)174 ZTEST(device_next, test_vendor_control_out)
175 {
176 	const uint8_t bmRequestType = (USB_REQTYPE_DIR_TO_DEVICE << 7) |
177 				      (USB_REQTYPE_TYPE_VENDOR << 5);
178 	const uint8_t bRequest = 0x5b;
179 	static struct usb_device *udev;
180 	const uint16_t wLength = 64;
181 	struct net_buf *buf;
182 	int err;
183 
184 	if (!IS_ENABLED(CONFIG_UHC_VIRTUAL)) {
185 		LOG_WRN("The test was skipped, controller is not supported.");
186 		return;
187 	}
188 
189 	udev = usbh_device_get_any(&uhs_ctx);
190 	zassert_not_null(udev, "No USB device available");
191 
192 	buf = usbh_xfer_buf_alloc(udev, wLength);
193 	zassert_not_null(udev, "Failed to allocate buffer");
194 
195 	err = k_mutex_lock(&udev->mutex, K_MSEC(200));
196 	zassert_equal(err, 0, "Failed to lock device");
197 
198 	/* Perform regular vendor OUT transfer */
199 	for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT; i++) {
200 		net_buf_reset(buf);
201 		for (uint32_t n = 0; n < wLength; n++) {
202 			net_buf_add_u8(buf, n);
203 		}
204 
205 		err = usbh_req_setup(udev, bmRequestType, bRequest, 0, 0, wLength, buf);
206 		zassert_equal(err, 0, "Transfer status is an error");
207 	}
208 
209 	/* Perform vendor OUT transfer but omit status stage*/
210 	usbh_req_omit_status(true);
211 	for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT * 2; i++) {
212 		net_buf_reset(buf);
213 		for (uint32_t n = 0; n < wLength; n++) {
214 			net_buf_add_u8(buf, n);
215 		}
216 
217 		err = usbh_req_setup(udev, bmRequestType, bRequest, 0, 0, wLength, buf);
218 		zassert_equal(err, 0, "Transfer status is an error");
219 	}
220 
221 	/* Perform vendor OUT requests but omit data and status stage*/
222 	for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT * 2; i++) {
223 		err = usbh_req_setup(udev, bmRequestType, bRequest, 0, 0, wLength, NULL);
224 		zassert_equal(err, 0, "Transfer status is an error");
225 	}
226 
227 	usbh_req_omit_status(false);
228 
229 	/* Perform regular vendor OUT transfer again */
230 	for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT; i++) {
231 		net_buf_reset(buf);
232 		for (uint32_t n = 0; n < wLength; n++) {
233 			net_buf_add_u8(buf, n);
234 		}
235 
236 		err = usbh_req_setup(udev, bmRequestType, bRequest, 0, 0, wLength, buf);
237 		zassert_equal(err, 0, "Transfer status is an error");
238 	}
239 
240 	k_mutex_unlock(&udev->mutex);
241 	usbh_xfer_buf_free(udev, buf);
242 }
243 
ZTEST(device_next,test_control_nodata)244 ZTEST(device_next, test_control_nodata)
245 {
246 	const uint8_t bmRequestType = USB_REQTYPE_RECIPIENT_ENDPOINT;
247 	const uint8_t bRequest = USB_SREQ_CLEAR_FEATURE;
248 	const uint16_t wValue = USB_SFS_ENDPOINT_HALT;
249 	const uint16_t wIndex = USB_CONTROL_EP_OUT;
250 	static struct usb_device *udev;
251 	int err;
252 
253 	if (!IS_ENABLED(CONFIG_UHC_VIRTUAL)) {
254 		LOG_WRN("The test was skipped, controller is not supported.");
255 		return;
256 	}
257 
258 	udev = usbh_device_get_any(&uhs_ctx);
259 	zassert_not_null(udev, "No USB device available");
260 
261 	err = k_mutex_lock(&udev->mutex, K_MSEC(200));
262 	zassert_equal(err, 0, "Failed to lock device");
263 
264 	/* Perform regular control transfer */
265 	for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT; i++) {
266 		err = usbh_req_setup(udev,
267 				     bmRequestType, bRequest, wValue, wIndex, 0,
268 				     NULL);
269 		zassert_equal(err, 0, "Transfer status is an error");
270 	}
271 
272 	/* Perform transfer but omit status stage*/
273 	usbh_req_omit_status(true);
274 	for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT * 2; i++) {
275 		err = usbh_req_setup(udev,
276 				     bmRequestType, bRequest, wValue, wIndex, 0,
277 				     NULL);
278 		zassert_equal(err, 0, "Transfer status is an error");
279 	}
280 
281 	usbh_req_omit_status(false);
282 
283 	/* Perform regular control transfer again */
284 	for (uint32_t i = 0; i < CONFIG_UDC_BUF_COUNT; i++) {
285 		err = usbh_req_setup(udev,
286 				     bmRequestType, bRequest, wValue, wIndex, 0,
287 				     NULL);
288 		zassert_equal(err, 0, "Transfer status is an error");
289 	}
290 
291 	k_mutex_unlock(&udev->mutex);
292 }
293 
294 /* Get Configuration request test */
ZTEST(device_next,test_get_configuration)295 ZTEST(device_next, test_get_configuration)
296 {
297 	struct usb_device *udev;
298 	uint8_t cfg = 0;
299 	int err;
300 
301 	udev = usbh_device_get_any(&uhs_ctx);
302 	zassert_not_null(udev, "No USB device available");
303 
304 	err = k_mutex_lock(&udev->mutex, K_MSEC(200));
305 	zassert_equal(err, 0, "Failed to lock device");
306 
307 	err = usbh_req_get_cfg(udev, &cfg);
308 	k_mutex_unlock(&udev->mutex);
309 
310 	switch (udev->state) {
311 	case USB_STATE_DEFAULT:
312 		/* Not specified, expect protocol error */
313 		zassert_equal(err, -EPIPE, "Transfer status is not a protocol error");
314 		break;
315 	case USB_STATE_ADDRESSED:
316 		/* TODO: Expect zero value */
317 		zassert_equal(err, 0, "Transfer status is an error");
318 		zassert_equal(cfg, 0, "Device not in address state");
319 		break;
320 	case USB_STATE_CONFIGURED:
321 		/* TODO: Expect non-zero valid configuration value */
322 		zassert_equal(err, 0, "Transfer status is an error");
323 		zassert_not_equal(cfg, 0, "Device not in configured state");
324 		break;
325 	default:
326 		break;
327 	}
328 }
329 
330 /* Set Interface request test */
ZTEST(device_next,test_set_interface)331 ZTEST(device_next, test_set_interface)
332 {
333 	struct usb_device *udev;
334 	int err;
335 
336 	udev = usbh_device_get_any(&uhs_ctx);
337 	zassert_not_null(udev, "No USB device available");
338 
339 	err = k_mutex_lock(&udev->mutex, K_MSEC(200));
340 	zassert_equal(err, 0, "Failed to lock device");
341 
342 	err = usbh_req_set_alt(udev, TEST_DEFAULT_INTERFACE,
343 			       TEST_DEFAULT_ALTERNATE);
344 	k_mutex_unlock(&udev->mutex);
345 
346 	switch (udev->state) {
347 	case USB_STATE_DEFAULT:
348 		/* Not specified, expect protocol error */
349 	case USB_STATE_ADDRESSED:
350 		/* Expect protocol error */
351 		zassert_equal(err, -EPIPE, "Transfer status is not a protocol error");
352 		break;
353 	case USB_STATE_CONFIGURED:
354 		/* TODO */
355 	default:
356 		break;
357 	}
358 }
359 
usb_test_enable(void)360 static void *usb_test_enable(void)
361 {
362 	int err;
363 
364 	err = usbh_init(&uhs_ctx);
365 	zassert_equal(err, 0, "Failed to initialize USB host");
366 
367 	err = usbh_enable(&uhs_ctx);
368 	zassert_equal(err, 0, "Failed to enable USB host");
369 
370 	err = uhc_bus_reset(uhs_ctx.dev);
371 	zassert_equal(err, 0, "Failed to signal bus reset");
372 
373 	err = uhc_bus_resume(uhs_ctx.dev);
374 	zassert_equal(err, 0, "Failed to signal bus resume");
375 
376 	err = uhc_sof_enable(uhs_ctx.dev);
377 	zassert_equal(err, 0, "Failed to enable SoF generator");
378 
379 	LOG_INF("Host controller enabled");
380 
381 	err = usbd_add_descriptor(&test_usbd, &test_lang);
382 	zassert_equal(err, 0, "Failed to initialize descriptor (%d)", err);
383 
384 	err = usbd_add_descriptor(&test_usbd, &test_mfg);
385 	zassert_equal(err, 0, "Failed to initialize descriptor (%d)", err);
386 
387 	err = usbd_add_descriptor(&test_usbd, &test_product);
388 	zassert_equal(err, 0, "Failed to initialize descriptor (%d)", err);
389 
390 	err = usbd_add_descriptor(&test_usbd, &test_sn);
391 	zassert_equal(err, 0, "Failed to initialize descriptor (%d)", err);
392 
393 	if (USBD_SUPPORTS_HIGH_SPEED &&
394 	    usbd_caps_speed(&test_usbd) == USBD_SPEED_HS) {
395 		err = usbd_add_configuration(&test_usbd, USBD_SPEED_HS, &test_hs_config);
396 		zassert_equal(err, 0, "Failed to add configuration (%d)", err);
397 	}
398 
399 	err = usbd_add_configuration(&test_usbd, USBD_SPEED_FS, &test_fs_config);
400 	zassert_equal(err, 0, "Failed to add configuration (%d)", err);
401 
402 	if (USBD_SUPPORTS_HIGH_SPEED &&
403 	    usbd_caps_speed(&test_usbd) == USBD_SPEED_HS) {
404 		err = usbd_register_all_classes(&test_usbd, USBD_SPEED_HS, 1, NULL);
405 		zassert_equal(err, 0, "Failed to unregister all instances(%d)", err);
406 
407 		err = usbd_unregister_all_classes(&test_usbd, USBD_SPEED_HS, 1);
408 		zassert_equal(err, 0, "Failed to unregister all instances(%d)", err);
409 
410 		err = usbd_register_class(&test_usbd, "loopback_0", USBD_SPEED_HS, 1);
411 		zassert_equal(err, 0, "Failed to register loopback_0 class (%d)", err);
412 	}
413 
414 	err = usbd_register_all_classes(&test_usbd, USBD_SPEED_FS, 1, NULL);
415 	zassert_equal(err, 0, "Failed to unregister all instances(%d)", err);
416 
417 	err = usbd_unregister_all_classes(&test_usbd, USBD_SPEED_FS, 1);
418 	zassert_equal(err, 0, "Failed to unregister all instances(%d)", err);
419 
420 	err = usbd_register_class(&test_usbd, "loopback_0", USBD_SPEED_FS, 1);
421 	zassert_equal(err, 0, "Failed to register loopback_0 class (%d)", err);
422 
423 	err = usbd_init(&test_usbd);
424 	zassert_equal(err, 0, "Failed to initialize device support");
425 
426 	err = usbd_enable(&test_usbd);
427 	zassert_equal(err, 0, "Failed to enable device support");
428 
429 	LOG_INF("Device support enabled");
430 
431 	/* Allow the host time to reset the device. */
432 	k_msleep(200);
433 
434 	return NULL;
435 }
436 
usb_test_shutdown(void * f)437 static void usb_test_shutdown(void *f)
438 {
439 	int err;
440 
441 	err = usbd_disable(&test_usbd);
442 	zassert_equal(err, 0, "Failed to enable device support");
443 
444 	err = usbd_shutdown(&test_usbd);
445 	zassert_equal(err, 0, "Failed to shutdown device support");
446 
447 	LOG_INF("Device support disabled");
448 
449 	err = usbh_disable(&uhs_ctx);
450 	zassert_equal(err, 0, "Failed to disable USB host");
451 
452 	LOG_INF("Host controller disabled");
453 }
454 
455 ZTEST_SUITE(device_next, NULL, usb_test_enable, NULL, NULL, usb_test_shutdown);
456