1 /*
2 * Copyright (c) 2022 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <errno.h>
8 #include <zephyr/kernel.h>
9 #include <zephyr/usb/usbd.h>
10 #include <zephyr/drivers/usb/udc.h>
11 #include <zephyr/sys/byteorder.h>
12 #include <zephyr/sys/slist.h>
13 #include <zephyr/drivers/hwinfo.h>
14
15 #include "usbd_device.h"
16 #include "usbd_desc.h"
17 #include "usbd_ch9.h"
18 #include "usbd_config.h"
19 #include "usbd_class.h"
20 #include "usbd_class_api.h"
21 #include "usbd_interface.h"
22 #include "usbd_msg.h"
23
24 #include <zephyr/logging/log.h>
25 LOG_MODULE_REGISTER(usbd_ch9, CONFIG_USBD_LOG_LEVEL);
26
27 #define CTRL_AWAIT_SETUP_DATA 0
28 #define CTRL_AWAIT_STATUS_STAGE 1
29
30 #define SF_TEST_MODE_SELECTOR(wIndex) ((uint8_t)((wIndex) >> 8))
31 #define SF_TEST_LOWER_BYTE(wIndex) ((uint8_t)(wIndex))
32
33 static int nonstd_request(struct usbd_context *const uds_ctx,
34 struct net_buf *const dbuf);
35
reqtype_is_to_host(const struct usb_setup_packet * const setup)36 static bool reqtype_is_to_host(const struct usb_setup_packet *const setup)
37 {
38 return setup->wLength && USB_REQTYPE_GET_DIR(setup->bmRequestType);
39 }
40
reqtype_is_to_device(const struct usb_setup_packet * const setup)41 static bool reqtype_is_to_device(const struct usb_setup_packet *const setup)
42 {
43 return !reqtype_is_to_host(setup);
44 }
45
ch9_set_ctrl_type(struct usbd_context * const uds_ctx,const int type)46 static void ch9_set_ctrl_type(struct usbd_context *const uds_ctx,
47 const int type)
48 {
49 uds_ctx->ch9_data.ctrl_type = type;
50 }
51
ch9_get_ctrl_type(struct usbd_context * const uds_ctx)52 static int ch9_get_ctrl_type(struct usbd_context *const uds_ctx)
53 {
54 return uds_ctx->ch9_data.ctrl_type;
55 }
56
post_status_stage(struct usbd_context * const uds_ctx)57 static int post_status_stage(struct usbd_context *const uds_ctx)
58 {
59 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
60 int ret = 0;
61
62 if (setup->bRequest == USB_SREQ_SET_ADDRESS) {
63 ret = udc_set_address(uds_ctx->dev, setup->wValue);
64 if (ret) {
65 LOG_ERR("Failed to set device address 0x%x", setup->wValue);
66 }
67 }
68
69 if (setup->bRequest == USB_SREQ_SET_FEATURE &&
70 setup->wValue == USB_SFS_TEST_MODE) {
71 uint8_t mode = SF_TEST_MODE_SELECTOR(setup->wIndex);
72
73 ret = udc_test_mode(uds_ctx->dev, mode, false);
74 if (ret) {
75 LOG_ERR("Failed to enable TEST_MODE %u", mode);
76 }
77 }
78
79 uds_ctx->ch9_data.post_status = false;
80
81 return ret;
82 }
83
sreq_set_address(struct usbd_context * const uds_ctx)84 static int sreq_set_address(struct usbd_context *const uds_ctx)
85 {
86 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
87 struct udc_device_caps caps = udc_caps(uds_ctx->dev);
88
89 /* Not specified if wIndex or wLength is non-zero, treat as error */
90 if (setup->wValue > 127 || setup->wIndex || setup->wLength) {
91 errno = -ENOTSUP;
92 return 0;
93 }
94
95 if (setup->RequestType.recipient != USB_REQTYPE_RECIPIENT_DEVICE) {
96 errno = -ENOTSUP;
97 return 0;
98 }
99
100 if (usbd_state_is_configured(uds_ctx)) {
101 errno = -EPERM;
102 return 0;
103 }
104
105 if (caps.addr_before_status) {
106 int ret;
107
108 ret = udc_set_address(uds_ctx->dev, setup->wValue);
109 if (ret) {
110 LOG_ERR("Failed to set device address 0x%x", setup->wValue);
111 return ret;
112 }
113 } else {
114 uds_ctx->ch9_data.post_status = true;
115 }
116
117 if (usbd_state_is_address(uds_ctx) && setup->wValue == 0) {
118 uds_ctx->ch9_data.state = USBD_STATE_DEFAULT;
119 } else {
120 uds_ctx->ch9_data.state = USBD_STATE_ADDRESS;
121 }
122
123
124 return 0;
125 }
126
sreq_set_configuration(struct usbd_context * const uds_ctx)127 static int sreq_set_configuration(struct usbd_context *const uds_ctx)
128 {
129 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
130 const enum usbd_speed speed = usbd_bus_speed(uds_ctx);
131 int ret;
132
133 LOG_INF("Set Configuration Request value %u", setup->wValue);
134
135 /* Not specified if wLength is non-zero, treat as error */
136 if (setup->wValue > UINT8_MAX || setup->wLength) {
137 errno = -ENOTSUP;
138 return 0;
139 }
140
141 if (setup->RequestType.recipient != USB_REQTYPE_RECIPIENT_DEVICE) {
142 errno = -ENOTSUP;
143 return 0;
144 }
145
146 if (usbd_state_is_default(uds_ctx)) {
147 errno = -EPERM;
148 return 0;
149 }
150
151 if (setup->wValue && !usbd_config_exist(uds_ctx, speed, setup->wValue)) {
152 errno = -EPERM;
153 return 0;
154 }
155
156 if (setup->wValue == usbd_get_config_value(uds_ctx)) {
157 LOG_DBG("Already in the configuration %u", setup->wValue);
158 return 0;
159 }
160
161 ret = usbd_config_set(uds_ctx, setup->wValue);
162 if (ret) {
163 LOG_ERR("Failed to set configuration %u, %d",
164 setup->wValue, ret);
165 return ret;
166 }
167
168 if (setup->wValue == 0) {
169 /* Enter address state */
170 uds_ctx->ch9_data.state = USBD_STATE_ADDRESS;
171 } else {
172 uds_ctx->ch9_data.state = USBD_STATE_CONFIGURED;
173 }
174
175 if (ret == 0) {
176 usbd_msg_pub_simple(uds_ctx, USBD_MSG_CONFIGURATION, setup->wValue);
177 }
178
179 return ret;
180 }
181
sreq_set_interface(struct usbd_context * const uds_ctx)182 static int sreq_set_interface(struct usbd_context *const uds_ctx)
183 {
184 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
185 int ret;
186
187 if (setup->RequestType.recipient != USB_REQTYPE_RECIPIENT_INTERFACE) {
188 errno = -ENOTSUP;
189 return 0;
190 }
191
192 /* Not specified if wLength is non-zero, treat as error */
193 if (setup->wLength) {
194 errno = -ENOTSUP;
195 return 0;
196 }
197
198 if (setup->wValue > UINT8_MAX || setup->wIndex > UINT8_MAX) {
199 errno = -ENOTSUP;
200 return 0;
201 }
202
203 if (!usbd_state_is_configured(uds_ctx)) {
204 errno = -EPERM;
205 return 0;
206 }
207
208 ret = usbd_interface_set(uds_ctx, setup->wIndex, setup->wValue);
209 if (ret == -ENOENT) {
210 LOG_INF("Interface or alternate does not exist");
211 errno = ret;
212 ret = 0;
213 }
214
215 return ret;
216 }
217
sreq_feature_halt_notify(struct usbd_context * const uds_ctx,const uint8_t ep,const bool halted)218 static void sreq_feature_halt_notify(struct usbd_context *const uds_ctx,
219 const uint8_t ep, const bool halted)
220 {
221 struct usbd_class_node *c_nd = usbd_class_get_by_ep(uds_ctx, ep);
222
223 if (c_nd != NULL) {
224 usbd_class_feature_halt(c_nd->c_data, ep, halted);
225 }
226 }
227
sreq_clear_feature(struct usbd_context * const uds_ctx)228 static int sreq_clear_feature(struct usbd_context *const uds_ctx)
229 {
230 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
231 uint8_t ep = setup->wIndex;
232 int ret = 0;
233
234 /* Not specified if wLength is non-zero, treat as error */
235 if (setup->wLength) {
236 errno = -ENOTSUP;
237 return 0;
238 }
239
240 /* Not specified in default state, treat as error */
241 if (usbd_state_is_default(uds_ctx)) {
242 errno = -EPERM;
243 return 0;
244 }
245
246 if (usbd_state_is_address(uds_ctx) && setup->wIndex) {
247 errno = -EPERM;
248 return 0;
249 }
250
251 switch (setup->RequestType.recipient) {
252 case USB_REQTYPE_RECIPIENT_DEVICE:
253 if (setup->wIndex != 0) {
254 errno = -EPERM;
255 return 0;
256 }
257
258 if (setup->wValue == USB_SFS_REMOTE_WAKEUP) {
259 LOG_DBG("Clear feature remote wakeup");
260 uds_ctx->status.rwup = false;
261 }
262 break;
263 case USB_REQTYPE_RECIPIENT_ENDPOINT:
264 if (setup->wValue == USB_SFS_ENDPOINT_HALT) {
265 /* UDC checks if endpoint is enabled */
266 errno = usbd_ep_clear_halt(uds_ctx, ep);
267 ret = (errno == -EPERM) ? errno : 0;
268 if (ret == 0) {
269 /* Notify class instance */
270 sreq_feature_halt_notify(uds_ctx, ep, false);
271 }
272 break;
273 }
274 break;
275 case USB_REQTYPE_RECIPIENT_INTERFACE:
276 default:
277 break;
278 }
279
280 return ret;
281 }
282
set_feature_test_mode(struct usbd_context * const uds_ctx)283 static int set_feature_test_mode(struct usbd_context *const uds_ctx)
284 {
285 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
286 uint8_t mode = SF_TEST_MODE_SELECTOR(setup->wIndex);
287
288 if (setup->RequestType.recipient != USB_REQTYPE_RECIPIENT_DEVICE ||
289 SF_TEST_LOWER_BYTE(setup->wIndex) != 0) {
290 errno = -ENOTSUP;
291 return 0;
292 }
293
294 if (udc_test_mode(uds_ctx->dev, mode, true) != 0) {
295 errno = -ENOTSUP;
296 return 0;
297 }
298
299 uds_ctx->ch9_data.post_status = true;
300
301 return 0;
302 }
303
sreq_set_feature(struct usbd_context * const uds_ctx)304 static int sreq_set_feature(struct usbd_context *const uds_ctx)
305 {
306 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
307 uint8_t ep = setup->wIndex;
308 int ret = 0;
309
310 /* Not specified if wLength is non-zero, treat as error */
311 if (setup->wLength) {
312 errno = -ENOTSUP;
313 return 0;
314 }
315
316 if (unlikely(setup->wValue == USB_SFS_TEST_MODE)) {
317 return set_feature_test_mode(uds_ctx);
318 }
319
320 /*
321 * Other request behavior is not specified in the default state, treat
322 * as an error.
323 */
324 if (usbd_state_is_default(uds_ctx)) {
325 errno = -EPERM;
326 return 0;
327 }
328
329 if (usbd_state_is_address(uds_ctx) && setup->wIndex) {
330 errno = -EPERM;
331 return 0;
332 }
333
334 switch (setup->RequestType.recipient) {
335 case USB_REQTYPE_RECIPIENT_DEVICE:
336 if (setup->wIndex != 0) {
337 errno = -EPERM;
338 return 0;
339 }
340
341 if (setup->wValue == USB_SFS_REMOTE_WAKEUP) {
342 LOG_DBG("Set feature remote wakeup");
343 uds_ctx->status.rwup = true;
344 }
345 break;
346 case USB_REQTYPE_RECIPIENT_ENDPOINT:
347 if (setup->wValue == USB_SFS_ENDPOINT_HALT) {
348 /* UDC checks if endpoint is enabled */
349 errno = usbd_ep_set_halt(uds_ctx, ep);
350 ret = (errno == -EPERM) ? errno : 0;
351 if (ret == 0) {
352 /* Notify class instance */
353 sreq_feature_halt_notify(uds_ctx, ep, true);
354 }
355 break;
356 }
357 break;
358 case USB_REQTYPE_RECIPIENT_INTERFACE:
359 default:
360 break;
361 }
362
363 return ret;
364 }
365
std_request_to_device(struct usbd_context * const uds_ctx,struct net_buf * const buf)366 static int std_request_to_device(struct usbd_context *const uds_ctx,
367 struct net_buf *const buf)
368 {
369 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
370 int ret;
371
372 switch (setup->bRequest) {
373 case USB_SREQ_SET_ADDRESS:
374 ret = sreq_set_address(uds_ctx);
375 break;
376 case USB_SREQ_SET_CONFIGURATION:
377 ret = sreq_set_configuration(uds_ctx);
378 break;
379 case USB_SREQ_SET_INTERFACE:
380 ret = sreq_set_interface(uds_ctx);
381 break;
382 case USB_SREQ_CLEAR_FEATURE:
383 ret = sreq_clear_feature(uds_ctx);
384 break;
385 case USB_SREQ_SET_FEATURE:
386 ret = sreq_set_feature(uds_ctx);
387 break;
388 default:
389 errno = -ENOTSUP;
390 ret = 0;
391 break;
392 }
393
394 return ret;
395 }
396
sreq_get_status(struct usbd_context * const uds_ctx,struct net_buf * const buf)397 static int sreq_get_status(struct usbd_context *const uds_ctx,
398 struct net_buf *const buf)
399 {
400 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
401 uint8_t ep = setup->wIndex;
402 uint16_t response = 0;
403
404 if (setup->wLength != sizeof(response)) {
405 errno = -ENOTSUP;
406 return 0;
407 }
408
409 /* Not specified in default state, treat as error */
410 if (usbd_state_is_default(uds_ctx)) {
411 errno = -EPERM;
412 return 0;
413 }
414
415 if (usbd_state_is_address(uds_ctx) && setup->wIndex) {
416 errno = -EPERM;
417 return 0;
418 }
419
420 switch (setup->RequestType.recipient) {
421 case USB_REQTYPE_RECIPIENT_DEVICE:
422 if (setup->wIndex != 0) {
423 errno = -EPERM;
424 return 0;
425 }
426
427 response = uds_ctx->status.rwup ?
428 USB_GET_STATUS_REMOTE_WAKEUP : 0;
429 response |= uds_ctx->status.self_powered ?
430 USB_GET_STATUS_SELF_POWERED : 0;
431 break;
432 case USB_REQTYPE_RECIPIENT_ENDPOINT:
433 response = usbd_ep_is_halted(uds_ctx, ep) ? BIT(0) : 0;
434 break;
435 case USB_REQTYPE_RECIPIENT_INTERFACE:
436 /* Response is always reset to zero.
437 * TODO: add check if interface exist?
438 */
439 break;
440 default:
441 break;
442 }
443
444 if (net_buf_tailroom(buf) < setup->wLength) {
445 errno = -ENOMEM;
446 return 0;
447 }
448
449 LOG_DBG("Get Status response 0x%04x", response);
450 net_buf_add_le16(buf, response);
451
452 return 0;
453 }
454
455 /*
456 * This function handles configuration and USB2.0 other-speed-configuration
457 * descriptor type requests.
458 */
sreq_get_desc_cfg(struct usbd_context * const uds_ctx,struct net_buf * const buf,const uint8_t idx,const bool other_cfg)459 static int sreq_get_desc_cfg(struct usbd_context *const uds_ctx,
460 struct net_buf *const buf,
461 const uint8_t idx,
462 const bool other_cfg)
463 {
464 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
465 enum usbd_speed speed = usbd_bus_speed(uds_ctx);
466 struct usb_cfg_descriptor other_desc;
467 struct usb_cfg_descriptor *cfg_desc;
468 struct usbd_config_node *cfg_nd;
469 enum usbd_speed get_desc_speed;
470 struct usbd_class_node *c_nd;
471 uint16_t len;
472
473 /*
474 * If the other-speed-configuration-descriptor is requested and the
475 * controller (or stack) does not support high speed, respond with
476 * an error.
477 */
478 if (other_cfg && !(USBD_SUPPORTS_HIGH_SPEED &&
479 (usbd_caps_speed(uds_ctx) == USBD_SPEED_HS))) {
480 errno = -ENOTSUP;
481 return 0;
482 }
483
484 if (other_cfg) {
485 if (speed == USBD_SPEED_FS) {
486 get_desc_speed = USBD_SPEED_HS;
487 } else {
488 get_desc_speed = USBD_SPEED_FS;
489 }
490 } else {
491 get_desc_speed = speed;
492 }
493
494 cfg_nd = usbd_config_get(uds_ctx, get_desc_speed, idx + 1);
495 if (cfg_nd == NULL) {
496 LOG_ERR("Configuration descriptor %u not found", idx + 1);
497 errno = -ENOTSUP;
498 return 0;
499 }
500
501 if (other_cfg) {
502 /* Copy the configuration descriptor and update the type */
503 memcpy(&other_desc, cfg_nd->desc, sizeof(other_desc));
504 other_desc.bDescriptorType = USB_DESC_OTHER_SPEED;
505 cfg_desc = &other_desc;
506 } else {
507 cfg_desc = cfg_nd->desc;
508 }
509
510 net_buf_add_mem(buf, cfg_desc, MIN(net_buf_tailroom(buf), cfg_desc->bLength));
511
512 SYS_SLIST_FOR_EACH_CONTAINER(&cfg_nd->class_list, c_nd, node) {
513 struct usb_desc_header **dhp;
514
515 dhp = usbd_class_get_desc(c_nd->c_data, get_desc_speed);
516 if (dhp == NULL) {
517 continue;
518 }
519
520 while (*dhp != NULL && (*dhp)->bLength != 0) {
521 len = MIN(net_buf_tailroom(buf), (*dhp)->bLength);
522 net_buf_add_mem(buf, *dhp, len);
523 dhp++;
524 }
525 }
526
527 if (buf->len > setup->wLength) {
528 net_buf_remove_mem(buf, buf->len - setup->wLength);
529 }
530
531 LOG_DBG("Get Configuration descriptor %u, len %u", idx, buf->len);
532
533 return 0;
534 }
535
536 #define USBD_SN_ASCII7_LENGTH (CONFIG_USBD_HWINFO_DEVID_LENGTH * 2)
537
538 /* Generate valid USB device serial number from hwid */
get_sn_from_hwid(uint8_t sn[static USBD_SN_ASCII7_LENGTH])539 static ssize_t get_sn_from_hwid(uint8_t sn[static USBD_SN_ASCII7_LENGTH])
540 {
541 static const char hex[] = "0123456789ABCDEF";
542 uint8_t hwid[USBD_SN_ASCII7_LENGTH / 2U];
543 ssize_t hwid_len = -ENOSYS;
544
545 if (IS_ENABLED(CONFIG_HWINFO)) {
546 hwid_len = hwinfo_get_device_id(hwid, sizeof(hwid));
547 }
548
549 if (hwid_len < 0) {
550 if (hwid_len == -ENOSYS) {
551 LOG_ERR("HWINFO not implemented or enabled");
552 }
553
554 return hwid_len;
555 }
556
557 for (ssize_t i = 0; i < MIN(hwid_len, sizeof(hwid)); i++) {
558 sn[i * 2] = hex[hwid[i] >> 4];
559 sn[i * 2 + 1] = hex[hwid[i] & 0xF];
560 }
561
562 return MIN(hwid_len, sizeof(hwid)) * 2;
563 }
564
565 /* Copy and convert ASCII-7 string descriptor to UTF16-LE */
string_ascii7_to_utf16le(struct usbd_desc_node * const dn,struct net_buf * const buf,const uint16_t wLength)566 static void string_ascii7_to_utf16le(struct usbd_desc_node *const dn,
567 struct net_buf *const buf, const uint16_t wLength)
568 {
569 uint8_t sn_ascii7_str[USBD_SN_ASCII7_LENGTH];
570 struct usb_desc_header head = {
571 .bDescriptorType = dn->bDescriptorType,
572 };
573 const uint8_t *ascii7_str;
574 size_t len;
575 size_t i;
576
577 if (IS_ENABLED(CONFIG_HWINFO) &&
578 dn->str.utype == USBD_DUT_STRING_SERIAL_NUMBER && dn->str.use_hwinfo) {
579 ssize_t sn_ascii7_str_len = get_sn_from_hwid(sn_ascii7_str);
580
581 if (sn_ascii7_str_len < 0) {
582 errno = -ENOTSUP;
583 return;
584 }
585
586 head.bLength = sizeof(head) + sn_ascii7_str_len * 2;
587 ascii7_str = sn_ascii7_str;
588 } else {
589 head.bLength = dn->bLength;
590 ascii7_str = (uint8_t *)dn->ptr;
591 }
592
593 LOG_DBG("wLength %u, bLength %u, tailroom %u",
594 wLength, head.bLength, net_buf_tailroom(buf));
595
596 len = MIN(net_buf_tailroom(buf), MIN(head.bLength, wLength));
597
598 /* Add bLength and bDescriptorType */
599 net_buf_add_mem(buf, &head, MIN(len, sizeof(head)));
600 len -= MIN(len, sizeof(head));
601
602 for (i = 0; i < len / 2; i++) {
603 __ASSERT(ascii7_str[i] > 0x1F && ascii7_str[i] < 0x7F,
604 "Only printable ascii-7 characters are allowed in USB "
605 "string descriptors");
606 net_buf_add_le16(buf, ascii7_str[i]);
607 }
608
609 if (len & 1) {
610 net_buf_add_u8(buf, ascii7_str[i]);
611 }
612 }
613
sreq_get_desc_dev(struct usbd_context * const uds_ctx,struct net_buf * const buf)614 static int sreq_get_desc_dev(struct usbd_context *const uds_ctx,
615 struct net_buf *const buf)
616 {
617 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
618 struct usb_desc_header *head;
619 size_t len;
620
621 len = MIN(setup->wLength, net_buf_tailroom(buf));
622
623 switch (usbd_bus_speed(uds_ctx)) {
624 case USBD_SPEED_FS:
625 head = uds_ctx->fs_desc;
626 break;
627 case USBD_SPEED_HS:
628 head = uds_ctx->hs_desc;
629 break;
630 default:
631 errno = -ENOTSUP;
632 return 0;
633 }
634
635 if (head == NULL) {
636 return -EINVAL;
637 }
638
639 net_buf_add_mem(buf, head, MIN(len, head->bLength));
640
641 return 0;
642 }
643
sreq_get_desc_str(struct usbd_context * const uds_ctx,struct net_buf * const buf,const uint8_t idx)644 static int sreq_get_desc_str(struct usbd_context *const uds_ctx,
645 struct net_buf *const buf, const uint8_t idx)
646 {
647 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
648 struct usbd_desc_node *d_nd;
649 size_t len;
650
651 /* Get string descriptor */
652 d_nd = usbd_get_descriptor(uds_ctx, USB_DESC_STRING, idx);
653 if (d_nd == NULL) {
654 errno = -ENOTSUP;
655 return 0;
656 }
657
658 if (usbd_str_desc_get_idx(d_nd) == 0U) {
659 /* Language ID string descriptor */
660 struct usb_string_descriptor langid = {
661 .bLength = d_nd->bLength,
662 .bDescriptorType = d_nd->bDescriptorType,
663 .bString = *(uint16_t *)d_nd->ptr,
664 };
665
666 len = MIN(setup->wLength, net_buf_tailroom(buf));
667 net_buf_add_mem(buf, &langid, MIN(len, langid.bLength));
668 } else {
669 /* String descriptors in ASCII7 format */
670 string_ascii7_to_utf16le(d_nd, buf, setup->wLength);
671 }
672
673 return 0;
674 }
675
sreq_get_dev_qualifier(struct usbd_context * const uds_ctx,struct net_buf * const buf)676 static int sreq_get_dev_qualifier(struct usbd_context *const uds_ctx,
677 struct net_buf *const buf)
678 {
679 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
680 /* At Full-Speed we want High-Speed descriptor and vice versa */
681 struct usb_device_descriptor *d_desc =
682 usbd_bus_speed(uds_ctx) == USBD_SPEED_FS ?
683 uds_ctx->hs_desc : uds_ctx->fs_desc;
684 struct usb_device_qualifier_descriptor q_desc = {
685 .bLength = sizeof(struct usb_device_qualifier_descriptor),
686 .bDescriptorType = USB_DESC_DEVICE_QUALIFIER,
687 .bReserved = 0U,
688 };
689 size_t len;
690
691 /*
692 * If the Device Qualifier descriptor is requested and the controller
693 * does not support high speed, respond with an error.
694 */
695 if (!USBD_SUPPORTS_HIGH_SPEED ||
696 usbd_caps_speed(uds_ctx) != USBD_SPEED_HS) {
697 errno = -ENOTSUP;
698 return 0;
699 }
700
701 if (d_desc == NULL) {
702 return -EINVAL;
703 }
704
705 q_desc.bcdUSB = d_desc->bcdUSB;
706 q_desc.bDeviceClass = d_desc->bDeviceClass;
707 q_desc.bDeviceSubClass = d_desc->bDeviceSubClass;
708 q_desc.bDeviceProtocol = d_desc->bDeviceProtocol;
709 q_desc.bMaxPacketSize0 = d_desc->bMaxPacketSize0;
710 q_desc.bNumConfigurations = d_desc->bNumConfigurations;
711
712 LOG_DBG("Get Device Qualifier");
713 len = MIN(setup->wLength, net_buf_tailroom(buf));
714 net_buf_add_mem(buf, &q_desc, MIN(len, q_desc.bLength));
715
716 return 0;
717 }
718
desc_fill_bos_root(struct usbd_context * const uds_ctx,struct usb_bos_descriptor * const root)719 static void desc_fill_bos_root(struct usbd_context *const uds_ctx,
720 struct usb_bos_descriptor *const root)
721 {
722 struct usbd_desc_node *desc_nd;
723
724 root->bLength = sizeof(struct usb_bos_descriptor);
725 root->bDescriptorType = USB_DESC_BOS;
726 root->wTotalLength = root->bLength;
727 root->bNumDeviceCaps = 0;
728
729 SYS_DLIST_FOR_EACH_CONTAINER(&uds_ctx->descriptors, desc_nd, node) {
730 if (desc_nd->bDescriptorType == USB_DESC_BOS) {
731 root->wTotalLength += desc_nd->bLength;
732 root->bNumDeviceCaps++;
733 }
734 }
735 }
736
sreq_get_desc_bos(struct usbd_context * const uds_ctx,struct net_buf * const buf)737 static int sreq_get_desc_bos(struct usbd_context *const uds_ctx,
738 struct net_buf *const buf)
739 {
740 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
741 struct usb_device_descriptor *dev_dsc;
742 struct usb_bos_descriptor bos;
743 struct usbd_desc_node *desc_nd;
744 size_t len;
745
746 if (!IS_ENABLED(CONFIG_USBD_BOS_SUPPORT)) {
747 errno = -ENOTSUP;
748 return 0;
749 }
750
751 switch (usbd_bus_speed(uds_ctx)) {
752 case USBD_SPEED_FS:
753 dev_dsc = uds_ctx->fs_desc;
754 break;
755 case USBD_SPEED_HS:
756 dev_dsc = uds_ctx->hs_desc;
757 break;
758 default:
759 errno = -ENOTSUP;
760 return 0;
761 }
762
763 if (dev_dsc == NULL) {
764 return -EINVAL;
765 }
766
767 if (sys_le16_to_cpu(dev_dsc->bcdUSB) < 0x0201U) {
768 errno = -ENOTSUP;
769 return 0;
770 }
771
772 desc_fill_bos_root(uds_ctx, &bos);
773 len = MIN(net_buf_tailroom(buf), MIN(setup->wLength, bos.wTotalLength));
774
775 LOG_DBG("wLength %u, bLength %u, wTotalLength %u, tailroom %u",
776 setup->wLength, bos.bLength, bos.wTotalLength, net_buf_tailroom(buf));
777
778 net_buf_add_mem(buf, &bos, MIN(len, bos.bLength));
779
780 len -= MIN(len, sizeof(bos));
781 if (len == 0) {
782 return 0;
783 }
784
785 SYS_DLIST_FOR_EACH_CONTAINER(&uds_ctx->descriptors, desc_nd, node) {
786 if (desc_nd->bDescriptorType == USB_DESC_BOS) {
787 LOG_DBG("bLength %u, len %u, tailroom %u",
788 desc_nd->bLength, len, net_buf_tailroom(buf));
789 net_buf_add_mem(buf, desc_nd->ptr, MIN(len, desc_nd->bLength));
790
791 len -= MIN(len, desc_nd->bLength);
792 if (len == 0) {
793 break;
794 }
795 }
796 }
797
798 return 0;
799 }
800
sreq_get_descriptor(struct usbd_context * const uds_ctx,struct net_buf * const buf)801 static int sreq_get_descriptor(struct usbd_context *const uds_ctx,
802 struct net_buf *const buf)
803 {
804 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
805 uint8_t desc_type = USB_GET_DESCRIPTOR_TYPE(setup->wValue);
806 uint8_t desc_idx = USB_GET_DESCRIPTOR_INDEX(setup->wValue);
807
808 LOG_DBG("Get Descriptor request type %u index %u",
809 desc_type, desc_idx);
810
811 if (setup->RequestType.recipient != USB_REQTYPE_RECIPIENT_DEVICE) {
812 /*
813 * If the recipient is not the device then it is probably a
814 * class specific request where wIndex is the interface
815 * number or endpoint and not the language ID. e.g. HID
816 * Class Get Descriptor request.
817 */
818 return nonstd_request(uds_ctx, buf);
819 }
820
821 switch (desc_type) {
822 case USB_DESC_DEVICE:
823 return sreq_get_desc_dev(uds_ctx, buf);
824 case USB_DESC_CONFIGURATION:
825 return sreq_get_desc_cfg(uds_ctx, buf, desc_idx, false);
826 case USB_DESC_OTHER_SPEED:
827 return sreq_get_desc_cfg(uds_ctx, buf, desc_idx, true);
828 case USB_DESC_STRING:
829 return sreq_get_desc_str(uds_ctx, buf, desc_idx);
830 case USB_DESC_DEVICE_QUALIFIER:
831 return sreq_get_dev_qualifier(uds_ctx, buf);
832 case USB_DESC_BOS:
833 return sreq_get_desc_bos(uds_ctx, buf);
834 case USB_DESC_INTERFACE:
835 case USB_DESC_ENDPOINT:
836 default:
837 break;
838 }
839
840 errno = -ENOTSUP;
841 return 0;
842 }
843
sreq_get_configuration(struct usbd_context * const uds_ctx,struct net_buf * const buf)844 static int sreq_get_configuration(struct usbd_context *const uds_ctx,
845 struct net_buf *const buf)
846
847 {
848 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
849 uint8_t cfg = usbd_get_config_value(uds_ctx);
850
851 /* Not specified in default state, treat as error */
852 if (usbd_state_is_default(uds_ctx)) {
853 errno = -EPERM;
854 return 0;
855 }
856
857 if (setup->wLength != sizeof(cfg)) {
858 errno = -ENOTSUP;
859 return 0;
860 }
861
862 if (net_buf_tailroom(buf) < setup->wLength) {
863 errno = -ENOMEM;
864 return 0;
865 }
866
867 net_buf_add_u8(buf, cfg);
868
869 return 0;
870 }
871
sreq_get_interface(struct usbd_context * const uds_ctx,struct net_buf * const buf)872 static int sreq_get_interface(struct usbd_context *const uds_ctx,
873 struct net_buf *const buf)
874 {
875 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
876 struct usb_cfg_descriptor *cfg_desc;
877 struct usbd_config_node *cfg_nd;
878 uint8_t cur_alt;
879
880 if (setup->RequestType.recipient != USB_REQTYPE_RECIPIENT_INTERFACE) {
881 errno = -EPERM;
882 return 0;
883 }
884
885 /* Treat as error in default (not specified) and addressed states. */
886 cfg_nd = usbd_config_get_current(uds_ctx);
887 if (cfg_nd == NULL) {
888 errno = -EPERM;
889 return 0;
890 }
891
892 cfg_desc = cfg_nd->desc;
893
894 if (setup->wIndex > UINT8_MAX ||
895 setup->wIndex > cfg_desc->bNumInterfaces) {
896 errno = -ENOTSUP;
897 return 0;
898 }
899
900 if (usbd_get_alt_value(uds_ctx, setup->wIndex, &cur_alt)) {
901 errno = -ENOTSUP;
902 return 0;
903 }
904
905 LOG_DBG("Get Interfaces %u, alternate %u",
906 setup->wIndex, cur_alt);
907
908 if (setup->wLength != sizeof(cur_alt)) {
909 errno = -ENOTSUP;
910 return 0;
911 }
912
913 if (net_buf_tailroom(buf) < setup->wLength) {
914 errno = -ENOMEM;
915 return 0;
916 }
917
918 net_buf_add_u8(buf, cur_alt);
919
920 return 0;
921 }
922
std_request_to_host(struct usbd_context * const uds_ctx,struct net_buf * const buf)923 static int std_request_to_host(struct usbd_context *const uds_ctx,
924 struct net_buf *const buf)
925 {
926 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
927 int ret;
928
929 switch (setup->bRequest) {
930 case USB_SREQ_GET_STATUS:
931 ret = sreq_get_status(uds_ctx, buf);
932 break;
933 case USB_SREQ_GET_DESCRIPTOR:
934 ret = sreq_get_descriptor(uds_ctx, buf);
935 break;
936 case USB_SREQ_GET_CONFIGURATION:
937 ret = sreq_get_configuration(uds_ctx, buf);
938 break;
939 case USB_SREQ_GET_INTERFACE:
940 ret = sreq_get_interface(uds_ctx, buf);
941 break;
942 default:
943 errno = -ENOTSUP;
944 ret = 0;
945 break;
946 }
947
948 return ret;
949 }
950
vendor_device_request(struct usbd_context * const uds_ctx,struct net_buf * const buf)951 static int vendor_device_request(struct usbd_context *const uds_ctx,
952 struct net_buf *const buf)
953 {
954 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
955 struct usbd_vreq_node *vreq_nd;
956
957 if (!IS_ENABLED(CONFIG_USBD_VREQ_SUPPORT)) {
958 errno = -ENOTSUP;
959 return 0;
960 }
961
962 vreq_nd = usbd_device_get_vreq(uds_ctx, setup->bRequest);
963 if (vreq_nd == NULL) {
964 errno = -ENOTSUP;
965 return 0;
966 }
967
968 if (reqtype_is_to_device(setup) && vreq_nd->to_dev != NULL) {
969 LOG_DBG("Vendor request 0x%02x to device", setup->bRequest);
970 errno = vreq_nd->to_dev(uds_ctx, setup, buf);
971 return 0;
972 }
973
974 if (reqtype_is_to_host(setup) && vreq_nd->to_host != NULL) {
975 LOG_DBG("Vendor request 0x%02x to host", setup->bRequest);
976 errno = vreq_nd->to_host(uds_ctx, setup, buf);
977 return 0;
978 }
979
980 errno = -ENOTSUP;
981 return 0;
982 }
983
nonstd_request(struct usbd_context * const uds_ctx,struct net_buf * const dbuf)984 static int nonstd_request(struct usbd_context *const uds_ctx,
985 struct net_buf *const dbuf)
986 {
987 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
988 struct usbd_class_node *c_nd = NULL;
989 int ret = 0;
990
991 switch (setup->RequestType.recipient) {
992 case USB_REQTYPE_RECIPIENT_ENDPOINT:
993 c_nd = usbd_class_get_by_ep(uds_ctx, setup->wIndex);
994 break;
995 case USB_REQTYPE_RECIPIENT_INTERFACE:
996 c_nd = usbd_class_get_by_iface(uds_ctx, setup->wIndex);
997 break;
998 case USB_REQTYPE_RECIPIENT_DEVICE:
999 c_nd = usbd_class_get_by_req(uds_ctx, setup->bRequest);
1000 break;
1001 default:
1002 break;
1003 }
1004
1005 if (c_nd != NULL) {
1006 if (reqtype_is_to_device(setup)) {
1007 ret = usbd_class_control_to_dev(c_nd->c_data, setup, dbuf);
1008 } else {
1009 ret = usbd_class_control_to_host(c_nd->c_data, setup, dbuf);
1010 }
1011 } else {
1012 return vendor_device_request(uds_ctx, dbuf);
1013 }
1014
1015 return ret;
1016 }
1017
handle_setup_request(struct usbd_context * const uds_ctx,struct net_buf * const buf)1018 static int handle_setup_request(struct usbd_context *const uds_ctx,
1019 struct net_buf *const buf)
1020 {
1021 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
1022 int ret;
1023
1024 errno = 0;
1025
1026 switch (setup->RequestType.type) {
1027 case USB_REQTYPE_TYPE_STANDARD:
1028 if (reqtype_is_to_device(setup)) {
1029 ret = std_request_to_device(uds_ctx, buf);
1030 } else {
1031 ret = std_request_to_host(uds_ctx, buf);
1032 }
1033 break;
1034 case USB_REQTYPE_TYPE_CLASS:
1035 case USB_REQTYPE_TYPE_VENDOR:
1036 ret = nonstd_request(uds_ctx, buf);
1037 break;
1038 default:
1039 errno = -ENOTSUP;
1040 ret = 0;
1041 }
1042
1043 if (errno) {
1044 LOG_INF("protocol error:");
1045 LOG_HEXDUMP_INF(setup, sizeof(*setup), "setup:");
1046 if (errno == -ENOTSUP) {
1047 LOG_INF("not supported");
1048 }
1049 if (errno == -EPERM) {
1050 LOG_INF("not permitted in device state %u",
1051 uds_ctx->ch9_data.state);
1052 }
1053 }
1054
1055 return ret;
1056 }
1057
ctrl_xfer_get_setup(struct usbd_context * const uds_ctx,struct net_buf * const buf)1058 static int ctrl_xfer_get_setup(struct usbd_context *const uds_ctx,
1059 struct net_buf *const buf)
1060 {
1061 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
1062 struct net_buf *buf_b;
1063 struct udc_buf_info *bi, *bi_b;
1064
1065 if (buf->len < sizeof(struct usb_setup_packet)) {
1066 return -EINVAL;
1067 }
1068
1069 memcpy(setup, buf->data, sizeof(struct usb_setup_packet));
1070
1071 setup->wValue = sys_le16_to_cpu(setup->wValue);
1072 setup->wIndex = sys_le16_to_cpu(setup->wIndex);
1073 setup->wLength = sys_le16_to_cpu(setup->wLength);
1074
1075 bi = udc_get_buf_info(buf);
1076
1077 buf_b = buf->frags;
1078 if (buf_b == NULL) {
1079 LOG_ERR("Buffer for data|status is missing");
1080 return -ENODATA;
1081 }
1082
1083 bi_b = udc_get_buf_info(buf_b);
1084
1085 if (reqtype_is_to_device(setup)) {
1086 if (setup->wLength) {
1087 if (!bi_b->data) {
1088 LOG_ERR("%p is not data", buf_b);
1089 return -EINVAL;
1090 }
1091 } else {
1092 if (!bi_b->status) {
1093 LOG_ERR("%p is not status", buf_b);
1094 return -EINVAL;
1095 }
1096 }
1097 } else {
1098 if (!setup->wLength) {
1099 LOG_ERR("device-to-host with wLength zero");
1100 return -ENOTSUP;
1101 }
1102
1103 if (!bi_b->data) {
1104 LOG_ERR("%p is not data", buf_b);
1105 return -EINVAL;
1106 }
1107
1108 }
1109
1110 return 0;
1111 }
1112
spool_data_out(struct net_buf * const buf)1113 static struct net_buf *spool_data_out(struct net_buf *const buf)
1114 {
1115 struct net_buf *next_buf = buf;
1116 struct udc_buf_info *bi;
1117
1118 while (next_buf) {
1119 LOG_INF("spool %p", next_buf);
1120 next_buf = net_buf_frag_del(NULL, next_buf);
1121 if (next_buf) {
1122 bi = udc_get_buf_info(next_buf);
1123 if (bi->status) {
1124 return next_buf;
1125 }
1126 }
1127 }
1128
1129 return NULL;
1130 }
1131
usbd_handle_ctrl_xfer(struct usbd_context * const uds_ctx,struct net_buf * const buf,const int err)1132 int usbd_handle_ctrl_xfer(struct usbd_context *const uds_ctx,
1133 struct net_buf *const buf, const int err)
1134 {
1135 struct usb_setup_packet *setup = usbd_get_setup_pkt(uds_ctx);
1136 struct udc_buf_info *bi;
1137 int ret = 0;
1138
1139 bi = udc_get_buf_info(buf);
1140 if (USB_EP_GET_IDX(bi->ep)) {
1141 LOG_ERR("Can only handle control requests");
1142 return -EIO;
1143 }
1144
1145 if (err && err != -ENOMEM && !bi->setup) {
1146 if (err == -ECONNABORTED) {
1147 LOG_INF("Transfer 0x%02x aborted (bus reset?)", bi->ep);
1148 net_buf_unref(buf);
1149 return 0;
1150 }
1151
1152 LOG_ERR("Control transfer for 0x%02x has error %d, halt",
1153 bi->ep, err);
1154 net_buf_unref(buf);
1155 return err;
1156 }
1157
1158 LOG_INF("Handle control %p ep 0x%02x, len %u, s:%u d:%u s:%u",
1159 buf, bi->ep, buf->len, bi->setup, bi->data, bi->status);
1160
1161 if (bi->setup && bi->ep == USB_CONTROL_EP_OUT) {
1162 struct net_buf *next_buf;
1163
1164 if (ctrl_xfer_get_setup(uds_ctx, buf)) {
1165 LOG_ERR("Malformed setup packet");
1166 net_buf_unref(buf);
1167 goto ctrl_xfer_stall;
1168 }
1169
1170 /* Remove setup packet buffer from the chain */
1171 next_buf = net_buf_frag_del(NULL, buf);
1172 if (next_buf == NULL) {
1173 LOG_ERR("Buffer for data|status is missing");
1174 goto ctrl_xfer_stall;
1175 }
1176
1177 /*
1178 * Handle request and data stage, next_buf is either
1179 * data+status or status buffers.
1180 */
1181 ret = handle_setup_request(uds_ctx, next_buf);
1182 if (ret) {
1183 net_buf_unref(next_buf);
1184 return ret;
1185 }
1186
1187 if (errno) {
1188 /*
1189 * Halt, only protocol errors are recoverable.
1190 * Free data stage and linked status stage buffer.
1191 */
1192 net_buf_unref(next_buf);
1193 goto ctrl_xfer_stall;
1194 }
1195
1196 ch9_set_ctrl_type(uds_ctx, CTRL_AWAIT_STATUS_STAGE);
1197 if (reqtype_is_to_device(setup) && setup->wLength) {
1198 /* Enqueue STATUS (IN) buffer */
1199 next_buf = spool_data_out(next_buf);
1200 if (next_buf == NULL) {
1201 LOG_ERR("Buffer for status is missing");
1202 goto ctrl_xfer_stall;
1203 }
1204
1205 ret = usbd_ep_ctrl_enqueue(uds_ctx, next_buf);
1206 } else {
1207 /* Enqueue DATA (IN) or STATUS (OUT) buffer */
1208 ret = usbd_ep_ctrl_enqueue(uds_ctx, next_buf);
1209 }
1210
1211 return ret;
1212 }
1213
1214 if (bi->status && bi->ep == USB_CONTROL_EP_OUT) {
1215 if (ch9_get_ctrl_type(uds_ctx) == CTRL_AWAIT_STATUS_STAGE) {
1216 LOG_INF("s-in-status finished");
1217 } else {
1218 LOG_WRN("Awaited s-in-status not finished");
1219 }
1220
1221 net_buf_unref(buf);
1222
1223 return 0;
1224 }
1225
1226 if (bi->status && bi->ep == USB_CONTROL_EP_IN) {
1227 net_buf_unref(buf);
1228
1229 if (ch9_get_ctrl_type(uds_ctx) == CTRL_AWAIT_STATUS_STAGE) {
1230 LOG_INF("s-(out)-status finished");
1231 if (unlikely(uds_ctx->ch9_data.post_status)) {
1232 ret = post_status_stage(uds_ctx);
1233 }
1234 } else {
1235 LOG_WRN("Awaited s-(out)-status not finished");
1236 }
1237
1238 return ret;
1239 }
1240
1241 ctrl_xfer_stall:
1242 /*
1243 * Halt only the endpoint over which the host expects
1244 * data or status stage. This facilitates the work of the drivers.
1245 *
1246 * In the case there is -ENOMEM for data OUT stage halt
1247 * control OUT endpoint.
1248 */
1249 if (reqtype_is_to_host(setup)) {
1250 ret = udc_ep_set_halt(uds_ctx->dev, USB_CONTROL_EP_IN);
1251 } else if (setup->wLength) {
1252 uint8_t ep = (err == -ENOMEM) ? USB_CONTROL_EP_OUT : USB_CONTROL_EP_IN;
1253
1254 ret = udc_ep_set_halt(uds_ctx->dev, ep);
1255 } else {
1256 ret = udc_ep_set_halt(uds_ctx->dev, USB_CONTROL_EP_IN);
1257 }
1258
1259 ch9_set_ctrl_type(uds_ctx, CTRL_AWAIT_SETUP_DATA);
1260
1261 return ret;
1262 }
1263
usbd_init_control_pipe(struct usbd_context * const uds_ctx)1264 int usbd_init_control_pipe(struct usbd_context *const uds_ctx)
1265 {
1266 uds_ctx->ch9_data.state = USBD_STATE_DEFAULT;
1267 ch9_set_ctrl_type(uds_ctx, CTRL_AWAIT_SETUP_DATA);
1268
1269 return 0;
1270 }
1271