1 /*
2 * Copyright (C) 2006 Bertrik Sikken (bertrik@sikken.nl)
3 * Copyright (c) 2016 Intel Corporation
4 * Copyright (c) 2022, sakumisu
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8 #include "usbd_core.h"
9
10 /* general descriptor field offsets */
11 #define DESC_bLength 0 /** Length offset */
12 #define DESC_bDescriptorType 1 /** Descriptor type offset */
13
14 /* config descriptor field offsets */
15 #define CONF_DESC_wTotalLength 2 /** Total length offset */
16 #define CONF_DESC_bConfigurationValue 5 /** Configuration value offset */
17 #define CONF_DESC_bmAttributes 7 /** configuration characteristics */
18
19 /* interface descriptor field offsets */
20 #define INTF_DESC_bInterfaceNumber 2 /** Interface number offset */
21 #define INTF_DESC_bAlternateSetting 3 /** Alternate setting offset */
22
23 #define USB_EP_OUT_NUM 8
24 #define USB_EP_IN_NUM 8
25
26 struct usbd_tx_rx_msg {
27 uint8_t ep;
28 uint32_t nbytes;
29 usbd_endpoint_callback cb;
30 };
31
32 USB_NOCACHE_RAM_SECTION struct usbd_core_priv {
33 /** Setup packet */
34 USB_MEM_ALIGNX struct usb_setup_packet setup;
35 /** Pointer to data buffer */
36 uint8_t *ep0_data_buf;
37 /** Remaining bytes in buffer */
38 uint32_t ep0_data_buf_residue;
39 /** Total length of control transfer */
40 uint32_t ep0_data_buf_len;
41 /** Zero length packet flag of control transfer */
42 bool zlp_flag;
43 /** Pointer to registered descriptors */
44 #ifdef CONFIG_USBDEV_ADVANCE_DESC
45 const struct usb_descriptor *descriptors;
46 #else
47 const uint8_t *descriptors;
48 #endif
49 struct usb_msosv1_descriptor *msosv1_desc;
50 struct usb_msosv2_descriptor *msosv2_desc;
51 struct usb_bos_descriptor *bos_desc;
52 /* Buffer used for storing standard, class and vendor request data */
53 USB_MEM_ALIGNX uint8_t req_data[CONFIG_USBDEV_REQUEST_BUFFER_LEN];
54
55 /** Currently selected configuration */
56 uint8_t configuration;
57 uint8_t speed;
58 #ifdef CONFIG_USBDEV_TEST_MODE
59 bool test_mode;
60 #endif
61 struct usbd_interface *intf[8];
62 uint8_t intf_offset;
63
64 struct usbd_tx_rx_msg tx_msg[USB_EP_IN_NUM];
65 struct usbd_tx_rx_msg rx_msg[USB_EP_OUT_NUM];
66 } g_usbd_core;
67
68 static void usbd_class_event_notify_handler(uint8_t event, void *arg);
69
usbd_print_setup(struct usb_setup_packet * setup)70 static void usbd_print_setup(struct usb_setup_packet *setup)
71 {
72 USB_LOG_INFO("Setup: "
73 "bmRequestType 0x%02x, bRequest 0x%02x, wValue 0x%04x, wIndex 0x%04x, wLength 0x%04x\r\n",
74 setup->bmRequestType,
75 setup->bRequest,
76 setup->wValue,
77 setup->wIndex,
78 setup->wLength);
79 }
80
is_device_configured(void)81 static bool is_device_configured(void)
82 {
83 return (g_usbd_core.configuration != 0);
84 }
85
86 /**
87 * @brief configure and enable endpoint
88 *
89 * This function sets endpoint configuration according to one specified in USB
90 * endpoint descriptor and then enables it for data transfers.
91 *
92 * @param [in] ep_desc Endpoint descriptor byte array
93 *
94 * @return true if successfully configured and enabled
95 */
usbd_set_endpoint(const struct usb_endpoint_descriptor * ep_desc)96 static bool usbd_set_endpoint(const struct usb_endpoint_descriptor *ep_desc)
97 {
98 struct usbd_endpoint_cfg ep_cfg;
99
100 ep_cfg.ep_addr = ep_desc->bEndpointAddress;
101 ep_cfg.ep_mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
102 ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
103
104 USB_LOG_INFO("Open ep:0x%02x type:%u mps:%u\r\n",
105 ep_cfg.ep_addr, ep_cfg.ep_type, ep_cfg.ep_mps);
106
107 return usbd_ep_open(&ep_cfg) == 0 ? true : false;
108 }
109 /**
110 * @brief Disable endpoint for transferring data
111 *
112 * This function cancels transfers that are associated with endpoint and
113 * disabled endpoint itself.
114 *
115 * @param [in] ep_desc Endpoint descriptor byte array
116 *
117 * @return true if successfully deconfigured and disabled
118 */
usbd_reset_endpoint(const struct usb_endpoint_descriptor * ep_desc)119 static bool usbd_reset_endpoint(const struct usb_endpoint_descriptor *ep_desc)
120 {
121 struct usbd_endpoint_cfg ep_cfg;
122
123 ep_cfg.ep_addr = ep_desc->bEndpointAddress;
124 ep_cfg.ep_mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
125 ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
126
127 USB_LOG_INFO("Close ep:0x%02x type:%u\r\n",
128 ep_cfg.ep_addr, ep_cfg.ep_type);
129
130 return usbd_ep_close(ep_cfg.ep_addr) == 0 ? true : false;
131 }
132
133 /**
134 * @brief get specified USB descriptor
135 *
136 * This function parses the list of installed USB descriptors and attempts
137 * to find the specified USB descriptor.
138 *
139 * @param [in] type_index Type and index of the descriptor
140 * @param [out] data Descriptor data
141 * @param [out] len Descriptor length
142 *
143 * @return true if the descriptor was found, false otherwise
144 */
145 #ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_get_descriptor(uint16_t type_index,uint8_t ** data,uint32_t * len)146 static bool usbd_get_descriptor(uint16_t type_index, uint8_t **data, uint32_t *len)
147 {
148 uint8_t type = 0U;
149 uint8_t index = 0U;
150 bool found = true;
151 uint8_t str_len = 0;
152
153 type = HI_BYTE(type_index);
154 index = LO_BYTE(type_index);
155
156 switch (type) {
157 case USB_DESCRIPTOR_TYPE_DEVICE:
158 *data = (uint8_t *)g_usbd_core.descriptors->device_descriptor;
159 *len = g_usbd_core.descriptors->device_descriptor[0];
160 break;
161 case USB_DESCRIPTOR_TYPE_CONFIGURATION:
162 g_usbd_core.speed = usbd_get_port_speed(0);
163 if (g_usbd_core.speed == USB_SPEED_HIGH) {
164 if (g_usbd_core.descriptors->hs_config_descriptor) {
165 *data = (uint8_t *)g_usbd_core.descriptors->hs_config_descriptor;
166 *len = (g_usbd_core.descriptors->hs_config_descriptor[CONF_DESC_wTotalLength] |
167 (g_usbd_core.descriptors->hs_config_descriptor[CONF_DESC_wTotalLength + 1] << 8));
168 } else {
169 found = false;
170 }
171 } else {
172 if (g_usbd_core.descriptors->fs_config_descriptor) {
173 *data = (uint8_t *)g_usbd_core.descriptors->fs_config_descriptor;
174 *len = (g_usbd_core.descriptors->fs_config_descriptor[CONF_DESC_wTotalLength] |
175 (g_usbd_core.descriptors->fs_config_descriptor[CONF_DESC_wTotalLength + 1] << 8));
176 } else {
177 found = false;
178 }
179 }
180
181 break;
182 case USB_DESCRIPTOR_TYPE_STRING:
183 if (index == USB_STRING_LANGID_INDEX) {
184 (*data)[0] = 0x04;
185 (*data)[1] = 0x03;
186 (*data)[2] = 0x09;
187 (*data)[3] = 0x04;
188 *len = 4;
189 } else if (index == USB_OSDESC_STRING_DESC_INDEX) {
190 if (g_usbd_core.descriptors->msosv1_descriptor) {
191 USB_LOG_INFO("read MS OS 1.0 descriptor string\r\n");
192 *data = g_usbd_core.descriptors->msosv1_descriptor->string;
193 *len = g_usbd_core.descriptors->msosv1_descriptor->string_len;
194 } else {
195 }
196 } else {
197 if (g_usbd_core.descriptors->string_descriptor[index - 1]) {
198 str_len = strlen((const char *)g_usbd_core.descriptors->string_descriptor[index - 1]);
199
200 (*data)[0] = str_len * 2 + 2;
201 (*data)[1] = 0x03;
202 for (uint16_t i = 0; i < str_len; i++) {
203 (*data)[i * 2 + 2] = g_usbd_core.descriptors->string_descriptor[index - 1][i];
204 (*data)[i * 2 + 3] = 0;
205 }
206
207 *len = str_len * 2 + 2;
208 } else {
209 found = false;
210 }
211 }
212 break;
213 case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER:
214 if (g_usbd_core.descriptors->device_quality_descriptor) {
215 *data = (uint8_t *)g_usbd_core.descriptors->device_quality_descriptor;
216 *len = g_usbd_core.descriptors->device_quality_descriptor[0];
217 } else {
218 found = false;
219 }
220
221 break;
222 case USB_DESCRIPTOR_TYPE_OTHER_SPEED:
223 if (g_usbd_core.speed == USB_SPEED_HIGH) {
224 if (g_usbd_core.descriptors->fs_other_speed_descriptor) {
225 *data = (uint8_t *)g_usbd_core.descriptors->fs_other_speed_descriptor;
226 *len = (g_usbd_core.descriptors->fs_other_speed_descriptor[CONF_DESC_wTotalLength] |
227 (g_usbd_core.descriptors->fs_other_speed_descriptor[CONF_DESC_wTotalLength] << 8));
228 } else {
229 found = false;
230 }
231 } else {
232 if (g_usbd_core.descriptors->hs_other_speed_descriptor) {
233 *data = (uint8_t *)g_usbd_core.descriptors->hs_other_speed_descriptor;
234 *len = (g_usbd_core.descriptors->hs_other_speed_descriptor[CONF_DESC_wTotalLength] |
235 (g_usbd_core.descriptors->hs_other_speed_descriptor[CONF_DESC_wTotalLength] << 8));
236 } else {
237 found = false;
238 }
239 }
240 break;
241
242 case USB_DESCRIPTOR_TYPE_BINARY_OBJECT_STORE:
243 USB_LOG_INFO("read BOS descriptor string\r\n");
244 break;
245
246 default:
247 found = false;
248 break;
249 }
250
251 if (found == false) {
252 /* nothing found */
253 USB_LOG_ERR("descriptor <type:%x,index:%x> not found!\r\n", type, index);
254 }
255 return found;
256 }
257 #else
usbd_get_descriptor(uint16_t type_index,uint8_t ** data,uint32_t * len)258 static bool usbd_get_descriptor(uint16_t type_index, uint8_t **data, uint32_t *len)
259 {
260 uint8_t type = 0U;
261 uint8_t index = 0U;
262 uint8_t *p = NULL;
263 uint32_t cur_index = 0U;
264 bool found = false;
265
266 type = HI_BYTE(type_index);
267 index = LO_BYTE(type_index);
268
269 if ((type == USB_DESCRIPTOR_TYPE_STRING) && (index == USB_OSDESC_STRING_DESC_INDEX)) {
270 USB_LOG_INFO("read MS OS 2.0 descriptor string\r\n");
271
272 if (!g_usbd_core.msosv1_desc) {
273 return false;
274 }
275
276 //*data = (uint8_t *)g_usbd_core.msosv1_desc->string;
277 memcpy(*data, (uint8_t *)g_usbd_core.msosv1_desc->string, g_usbd_core.msosv1_desc->string[0]);
278 *len = g_usbd_core.msosv1_desc->string[0];
279
280 return true;
281 } else if (type == USB_DESCRIPTOR_TYPE_BINARY_OBJECT_STORE) {
282 USB_LOG_INFO("read BOS descriptor string\r\n");
283
284 if (!g_usbd_core.bos_desc) {
285 return false;
286 }
287
288 //*data = g_usbd_core.bos_desc->string;
289 memcpy(*data, (uint8_t *)g_usbd_core.bos_desc->string, g_usbd_core.bos_desc->string_len);
290 *len = g_usbd_core.bos_desc->string_len;
291 return true;
292 }
293 /*
294 * Invalid types of descriptors,
295 * see USB Spec. Revision 2.0, 9.4.3 Get Descriptor
296 */
297 else if ((type == USB_DESCRIPTOR_TYPE_INTERFACE) || (type == USB_DESCRIPTOR_TYPE_ENDPOINT) ||
298 #ifndef CONFIG_USB_HS
299 (type > USB_DESCRIPTOR_TYPE_ENDPOINT)) {
300 #else
301 (type > USB_DESCRIPTOR_TYPE_OTHER_SPEED)) {
302 #endif
303 return false;
304 }
305
306 p = (uint8_t *)g_usbd_core.descriptors;
307
308 cur_index = 0U;
309
310 while (p[DESC_bLength] != 0U) {
311 if (p[DESC_bDescriptorType] == type) {
312 if (cur_index == index) {
313 found = true;
314 break;
315 }
316
317 cur_index++;
318 }
319
320 /* skip to next descriptor */
321 p += p[DESC_bLength];
322 }
323
324 if (found) {
325 if ((type == USB_DESCRIPTOR_TYPE_CONFIGURATION) || ((type == USB_DESCRIPTOR_TYPE_OTHER_SPEED))) {
326 /* configuration or other speed descriptor is an
327 * exception, length is at offset 2 and 3
328 */
329 *len = (p[CONF_DESC_wTotalLength]) |
330 (p[CONF_DESC_wTotalLength + 1] << 8);
331 } else {
332 /* normally length is at offset 0 */
333 *len = p[DESC_bLength];
334 }
335 memcpy(*data, p, *len);
336 } else {
337 /* nothing found */
338 USB_LOG_ERR("descriptor <type:0x%02x,index:0x%02x> not found!\r\n", type, index);
339 }
340
341 return found;
342 }
343 #endif
344
345 /**
346 * @brief set USB configuration
347 *
348 * This function configures the device according to the specified configuration
349 * index and alternate setting by parsing the installed USB descriptor list.
350 * A configuration index of 0 unconfigures the device.
351 *
352 * @param [in] config_index Configuration index
353 * @param [in] alt_setting Alternate setting number
354 *
355 * @return true if successfully configured false if error or unconfigured
356 */
357 static bool usbd_set_configuration(uint8_t config_index, uint8_t alt_setting)
358 {
359 uint8_t cur_alt_setting = 0xFF;
360 uint8_t cur_config = 0xFF;
361 bool found = false;
362 uint8_t *p;
363 #ifdef CONFIG_USBDEV_ADVANCE_DESC
364 if (g_usbd_core.speed == USB_SPEED_HIGH) {
365 p = (uint8_t *)g_usbd_core.descriptors->hs_config_descriptor;
366 } else {
367 p = (uint8_t *)g_usbd_core.descriptors->fs_config_descriptor;
368 }
369 #else
370 p = (uint8_t *)g_usbd_core.descriptors;
371 #endif
372 /* configure endpoints for this configuration/altsetting */
373 while (p[DESC_bLength] != 0U) {
374 switch (p[DESC_bDescriptorType]) {
375 case USB_DESCRIPTOR_TYPE_CONFIGURATION:
376 /* remember current configuration index */
377 cur_config = p[CONF_DESC_bConfigurationValue];
378
379 if (cur_config == config_index) {
380 found = true;
381 }
382
383 break;
384
385 case USB_DESCRIPTOR_TYPE_INTERFACE:
386 /* remember current alternate setting */
387 cur_alt_setting =
388 p[INTF_DESC_bAlternateSetting];
389 break;
390
391 case USB_DESCRIPTOR_TYPE_ENDPOINT:
392 if ((cur_config != config_index) ||
393 (cur_alt_setting != alt_setting)) {
394 break;
395 }
396
397 found = usbd_set_endpoint((struct usb_endpoint_descriptor *)p);
398 break;
399
400 default:
401 break;
402 }
403
404 /* skip to next descriptor */
405 p += p[DESC_bLength];
406 }
407
408 return found;
409 }
410
411 /**
412 * @brief set USB interface
413 *
414 * @param [in] iface Interface index
415 * @param [in] alt_setting Alternate setting number
416 *
417 * @return true if successfully configured false if error or unconfigured
418 */
419 static bool usbd_set_interface(uint8_t iface, uint8_t alt_setting)
420 {
421 const uint8_t *if_desc = NULL;
422 struct usb_endpoint_descriptor *ep_desc;
423 uint8_t cur_alt_setting = 0xFF;
424 uint8_t cur_iface = 0xFF;
425 bool ret = false;
426 uint8_t *p;
427 #ifdef CONFIG_USBDEV_ADVANCE_DESC
428 if (g_usbd_core.speed == USB_SPEED_HIGH) {
429 p = (uint8_t *)g_usbd_core.descriptors->hs_config_descriptor;
430 } else {
431 p = (uint8_t *)g_usbd_core.descriptors->fs_config_descriptor;
432 }
433 #else
434 p = (uint8_t *)g_usbd_core.descriptors;
435 #endif
436 USB_LOG_DBG("iface %u alt_setting %u\r\n", iface, alt_setting);
437
438 while (p[DESC_bLength] != 0U) {
439 switch (p[DESC_bDescriptorType]) {
440 case USB_DESCRIPTOR_TYPE_INTERFACE:
441 /* remember current alternate setting */
442 cur_alt_setting = p[INTF_DESC_bAlternateSetting];
443 cur_iface = p[INTF_DESC_bInterfaceNumber];
444
445 if (cur_iface == iface &&
446 cur_alt_setting == alt_setting) {
447 if_desc = (void *)p;
448 }
449
450 USB_LOG_DBG("Current iface %u alt setting %u",
451 cur_iface, cur_alt_setting);
452 break;
453
454 case USB_DESCRIPTOR_TYPE_ENDPOINT:
455 if (cur_iface == iface) {
456 ep_desc = (struct usb_endpoint_descriptor *)p;
457
458 if (cur_alt_setting != alt_setting) {
459 ret = usbd_reset_endpoint(ep_desc);
460 } else {
461 ret = usbd_set_endpoint(ep_desc);
462 }
463 }
464
465 break;
466
467 default:
468 break;
469 }
470
471 /* skip to next descriptor */
472 p += p[DESC_bLength];
473 }
474
475 usbd_class_event_notify_handler(USBD_EVENT_SET_INTERFACE, (void *)if_desc);
476
477 return ret;
478 }
479
480 /**
481 * @brief handle a standard device request
482 *
483 * @param [in] setup The setup packet
484 * @param [in,out] data Data buffer
485 * @param [in,out] len Pointer to data length
486 *
487 * @return true if the request was handled successfully
488 */
489 static bool usbd_std_device_req_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
490 {
491 uint16_t value = setup->wValue;
492 bool ret = true;
493
494 switch (setup->bRequest) {
495 case USB_REQUEST_GET_STATUS:
496 /* bit 0: self-powered */
497 /* bit 1: remote wakeup */
498 (*data)[0] = 0x00;
499 (*data)[1] = 0x00;
500 *len = 2;
501 break;
502
503 case USB_REQUEST_CLEAR_FEATURE:
504 case USB_REQUEST_SET_FEATURE:
505 if (value == USB_FEATURE_REMOTE_WAKEUP) {
506 if (setup->bRequest == USB_REQUEST_SET_FEATURE) {
507 usbd_event_handler(USBD_EVENT_SET_REMOTE_WAKEUP);
508 } else {
509 usbd_event_handler(USBD_EVENT_CLR_REMOTE_WAKEUP);
510 }
511 } else if (value == USB_FEATURE_TEST_MODE) {
512 #ifdef CONFIG_USBDEV_TEST_MODE
513 g_usbd_core.test_mode = true;
514 usbd_execute_test_mode(setup);
515 #endif
516 }
517 *len = 0;
518 break;
519
520 case USB_REQUEST_SET_ADDRESS:
521 usbd_set_address(value);
522 *len = 0;
523 break;
524
525 case USB_REQUEST_GET_DESCRIPTOR:
526 ret = usbd_get_descriptor(value, data, len);
527 break;
528
529 case USB_REQUEST_SET_DESCRIPTOR:
530 ret = false;
531 break;
532
533 case USB_REQUEST_GET_CONFIGURATION:
534 *data = (uint8_t *)&g_usbd_core.configuration;
535 *len = 1;
536 break;
537
538 case USB_REQUEST_SET_CONFIGURATION:
539 value &= 0xFF;
540
541 if (!usbd_set_configuration(value, 0)) {
542 ret = false;
543 } else {
544 g_usbd_core.configuration = value;
545 usbd_class_event_notify_handler(USBD_EVENT_CONFIGURED, NULL);
546 usbd_event_handler(USBD_EVENT_CONFIGURED);
547 }
548 *len = 0;
549 break;
550
551 case USB_REQUEST_GET_INTERFACE:
552 case USB_REQUEST_SET_INTERFACE:
553 ret = false;
554 break;
555
556 default:
557 ret = false;
558 break;
559 }
560
561 return ret;
562 }
563
564 /**
565 * @brief handle a standard interface request
566 *
567 * @param [in] setup The setup packet
568 * @param [in,out] data Data buffer
569 * @param [in,out] len Pointer to data length
570 *
571 * @return true if the request was handled successfully
572 */
573 static bool usbd_std_interface_req_handler(struct usb_setup_packet *setup,
574 uint8_t **data, uint32_t *len)
575 {
576 uint8_t type = HI_BYTE(setup->wValue);
577 uint8_t intf_num = LO_BYTE(setup->wIndex);
578 bool ret = true;
579
580 /* Only when device is configured, then interface requests can be valid. */
581 if (!is_device_configured()) {
582 return false;
583 }
584
585 switch (setup->bRequest) {
586 case USB_REQUEST_GET_STATUS:
587 (*data)[0] = 0x00;
588 (*data)[1] = 0x00;
589 *len = 2;
590 break;
591
592 case USB_REQUEST_GET_DESCRIPTOR:
593 if (type == 0x22) { /* HID_DESCRIPTOR_TYPE_HID_REPORT */
594 USB_LOG_INFO("read hid report descriptor\r\n");
595
596 for (uint8_t i = 0; i < g_usbd_core.intf_offset; i++) {
597 struct usbd_interface *intf = g_usbd_core.intf[i];
598
599 if (intf && (intf->intf_num == intf_num)) {
600 //*data = (uint8_t *)intf->hid_report_descriptor;
601 memcpy(*data, intf->hid_report_descriptor, intf->hid_report_descriptor_len);
602 *len = intf->hid_report_descriptor_len;
603 return true;
604 }
605 }
606 }
607 ret = false;
608 break;
609 case USB_REQUEST_CLEAR_FEATURE:
610 case USB_REQUEST_SET_FEATURE:
611 ret = false;
612 break;
613 case USB_REQUEST_GET_INTERFACE:
614 (*data)[0] = 0;
615 *len = 1;
616 break;
617
618 case USB_REQUEST_SET_INTERFACE:
619 usbd_set_interface(setup->wIndex, setup->wValue);
620 *len = 0;
621 break;
622
623 default:
624 ret = false;
625 break;
626 }
627
628 return ret;
629 }
630
631 /**
632 * @brief handle a standard endpoint request
633 *
634 * @param [in] setup The setup packet
635 * @param [in,out] data Data buffer
636 * @param [in,out] len Pointer to data length
637 *
638 * @return true if the request was handled successfully
639 */
640 static bool usbd_std_endpoint_req_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
641 {
642 uint8_t ep = (uint8_t)setup->wIndex;
643 bool ret = true;
644
645 /* Only when device is configured, then endpoint requests can be valid. */
646 if (!is_device_configured()) {
647 return false;
648 }
649
650 switch (setup->bRequest) {
651 case USB_REQUEST_GET_STATUS:
652 (*data)[0] = 0x00;
653 (*data)[1] = 0x00;
654 *len = 2;
655 break;
656 case USB_REQUEST_CLEAR_FEATURE:
657 if (setup->wValue == USB_FEATURE_ENDPOINT_HALT) {
658 USB_LOG_ERR("ep:%02x clear halt\r\n", ep);
659
660 usbd_ep_clear_stall(ep);
661 break;
662 } else {
663 ret = false;
664 }
665 *len = 0;
666 break;
667 case USB_REQUEST_SET_FEATURE:
668 if (setup->wValue == USB_FEATURE_ENDPOINT_HALT) {
669 USB_LOG_ERR("ep:%02x set halt\r\n", ep);
670
671 usbd_ep_set_stall(ep);
672 } else {
673 ret = false;
674 }
675 *len = 0;
676 break;
677
678 case USB_REQUEST_SYNCH_FRAME:
679 ret = false;
680 break;
681 default:
682 ret = false;
683 break;
684 }
685
686 return ret;
687 }
688
689 /**
690 * @brief handle standard requests (list in chapter 9)
691 *
692 * @param [in] setup The setup packet
693 * @param [in,out] data Data buffer
694 * @param [in,out] len Pointer to data length
695 *
696 * @return true if the request was handled successfully
697 */
698 static int usbd_standard_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
699 {
700 int rc = 0;
701
702 switch (setup->bmRequestType & USB_REQUEST_RECIPIENT_MASK) {
703 case USB_REQUEST_RECIPIENT_DEVICE:
704 if (usbd_std_device_req_handler(setup, data, len) == false) {
705 rc = -1;
706 }
707
708 break;
709
710 case USB_REQUEST_RECIPIENT_INTERFACE:
711 if (usbd_std_interface_req_handler(setup, data, len) == false) {
712 rc = -1;
713 }
714
715 break;
716
717 case USB_REQUEST_RECIPIENT_ENDPOINT:
718 if (usbd_std_endpoint_req_handler(setup, data, len) == false) {
719 rc = -1;
720 }
721
722 break;
723
724 default:
725 rc = -1;
726 break;
727 }
728
729 return rc;
730 }
731
732 /**
733 * @brief handler for class requests
734 *
735 * If a custom request handler was installed, this handler is called first.
736 *
737 * @param [in] setup The setup packet
738 * @param [in,out] data Data buffer
739 * @param [in,out] len Pointer to data length
740 *
741 * @return true if the request was handled successfully
742 */
743 static int usbd_class_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
744 {
745 if ((setup->bmRequestType & USB_REQUEST_RECIPIENT_MASK) == USB_REQUEST_RECIPIENT_INTERFACE) {
746 for (uint8_t i = 0; i < g_usbd_core.intf_offset; i++) {
747 struct usbd_interface *intf = g_usbd_core.intf[i];
748
749 if (intf && intf->class_interface_handler && (intf->intf_num == (setup->wIndex & 0xFF))) {
750 return intf->class_interface_handler(setup, data, len);
751 }
752 }
753 } else if ((setup->bmRequestType & USB_REQUEST_RECIPIENT_MASK) == USB_REQUEST_RECIPIENT_ENDPOINT) {
754 for (uint8_t i = 0; i < g_usbd_core.intf_offset; i++) {
755 struct usbd_interface *intf = g_usbd_core.intf[i];
756
757 if (intf && intf->class_endpoint_handler) {
758 return intf->class_endpoint_handler(setup, data, len);
759 }
760 }
761 }
762 return -1;
763 }
764
765 /**
766 * @brief handler for vendor requests
767 *
768 * If a custom request handler was installed, this handler is called first.
769 *
770 * @param [in] setup The setup packet
771 * @param [in,out] data Data buffer
772 * @param [in,out] len Pointer to data length
773 *
774 * @return true if the request was handled successfully
775 */
776 static int usbd_vendor_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
777 {
778 uint32_t desclen;
779 #ifdef CONFIG_USBDEV_ADVANCE_DESC
780 if (g_usbd_core.descriptors->msosv1_descriptor) {
781 if (setup->bRequest == g_usbd_core.descriptors->msosv1_descriptor->vendor_code) {
782 switch (setup->wIndex) {
783 case 0x04:
784 USB_LOG_INFO("get Compat ID\r\n");
785 desclen = g_usbd_core.msosv1_desc->compat_id[0] +
786 (g_usbd_core.msosv1_desc->compat_id[1] << 8) +
787 (g_usbd_core.msosv1_desc->compat_id[2] << 16) +
788 (g_usbd_core.msosv1_desc->compat_id[3] << 24);
789
790 *data = (uint8_t *)g_usbd_core.descriptors->msosv1_descriptor->compat_id;
791 *len = desclen;
792 return 0;
793 case 0x05:
794 USB_LOG_INFO("get Compat id properties\r\n");
795 desclen = g_usbd_core.msosv1_desc->comp_id_property[setup->wValue][0] +
796 (g_usbd_core.msosv1_desc->comp_id_property[setup->wValue][1] << 8) +
797 (g_usbd_core.msosv1_desc->comp_id_property[setup->wValue][2] << 16) +
798 (g_usbd_core.msosv1_desc->comp_id_property[setup->wValue][3] << 24);
799
800 *data = (uint8_t *)g_usbd_core.descriptors->msosv1_descriptor->comp_id_property[setup->wValue];
801 *len = desclen;
802 return 0;
803 default:
804 USB_LOG_ERR("unknown vendor code\r\n");
805 return -1;
806 }
807 }
808 } else if (g_usbd_core.descriptors->msosv2_descriptor) {
809 if (setup->bRequest == g_usbd_core.descriptors->msosv2_descriptor->vendor_code) {
810 switch (setup->wIndex) {
811 case WINUSB_REQUEST_GET_DESCRIPTOR_SET:
812 USB_LOG_INFO("GET MS OS 2.0 Descriptor\r\n");
813 *data = (uint8_t *)g_usbd_core.descriptors->msosv2_descriptor->compat_id;
814 *len = g_usbd_core.descriptors->msosv2_descriptor->compat_id_len;
815 return 0;
816 default:
817 USB_LOG_ERR("unknown vendor code\r\n");
818 return -1;
819 }
820 }
821 } else if (g_usbd_core.descriptors->webusb_url_descriptor) {
822 if (setup->bRequest == g_usbd_core.descriptors->webusb_url_descriptor->vendor_code) {
823 switch (setup->wIndex) {
824 case WINUSB_REQUEST_GET_DESCRIPTOR_SET:
825 USB_LOG_INFO("GET Webusb url Descriptor\r\n");
826 *data = (uint8_t *)g_usbd_core.descriptors->webusb_url_descriptor->string;
827 *len = g_usbd_core.descriptors->webusb_url_descriptor->string_len;
828 return 0;
829 default:
830 USB_LOG_ERR("unknown vendor code\r\n");
831 return -1;
832 }
833 }
834 }
835 #else
836 if (g_usbd_core.msosv1_desc) {
837 if (setup->bRequest == g_usbd_core.msosv1_desc->vendor_code) {
838 switch (setup->wIndex) {
839 case 0x04:
840 USB_LOG_INFO("get Compat ID\r\n");
841 //*data = (uint8_t *)msosv1_desc->compat_id;
842 desclen = g_usbd_core.msosv1_desc->compat_id[0] +
843 (g_usbd_core.msosv1_desc->compat_id[1] << 8) +
844 (g_usbd_core.msosv1_desc->compat_id[2] << 16) +
845 (g_usbd_core.msosv1_desc->compat_id[3] << 24);
846 memcpy(*data, g_usbd_core.msosv1_desc->compat_id, desclen);
847 *len = desclen;
848 return 0;
849 case 0x05:
850 USB_LOG_INFO("get Compat id properties\r\n");
851 //*data = (uint8_t *)msosv1_desc->comp_id_property[setup->wValue];
852 desclen = g_usbd_core.msosv1_desc->comp_id_property[setup->wValue][0] +
853 (g_usbd_core.msosv1_desc->comp_id_property[setup->wValue][1] << 8) +
854 (g_usbd_core.msosv1_desc->comp_id_property[setup->wValue][2] << 16) +
855 (g_usbd_core.msosv1_desc->comp_id_property[setup->wValue][3] << 24);
856 memcpy(*data, g_usbd_core.msosv1_desc->comp_id_property[setup->wValue], desclen);
857 *len = desclen;
858 return 0;
859 default:
860 USB_LOG_ERR("unknown vendor code\r\n");
861 return -1;
862 }
863 }
864 } else if (g_usbd_core.msosv2_desc) {
865 if (setup->bRequest == g_usbd_core.msosv2_desc->vendor_code) {
866 switch (setup->wIndex) {
867 case WINUSB_REQUEST_GET_DESCRIPTOR_SET:
868 USB_LOG_INFO("GET MS OS 2.0 Descriptor\r\n");
869 //*data = (uint8_t *)msosv2_desc->compat_id;
870 memcpy(*data, g_usbd_core.msosv2_desc->compat_id, g_usbd_core.msosv2_desc->compat_id_len);
871 *len = g_usbd_core.msosv2_desc->compat_id_len;
872 return 0;
873 default:
874 USB_LOG_ERR("unknown vendor code\r\n");
875 return -1;
876 }
877 }
878 }
879 #endif
880 for (uint8_t i = 0; i < g_usbd_core.intf_offset; i++) {
881 struct usbd_interface *intf = g_usbd_core.intf[i];
882
883 if (intf && intf->vendor_handler && (intf->vendor_handler(setup, data, len) == 0)) {
884 return 0;
885 }
886 }
887
888 return -1;
889 }
890
891 /**
892 * @brief handle setup request( standard/class/vendor/other)
893 *
894 * @param [in] setup The setup packet
895 * @param [in,out] data Data buffer
896 * @param [in,out] len Pointer to data length
897 *
898 * @return true if the request was handles successfully
899 */
900 static bool usbd_setup_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
901 {
902 switch (setup->bmRequestType & USB_REQUEST_TYPE_MASK) {
903 case USB_REQUEST_STANDARD:
904 if (usbd_standard_request_handler(setup, data, len) < 0) {
905 #ifdef CONFIG_USBDEV_ADVANCE_DESC
906 if (g_usbd_core.speed == USB_SPEED_FULL) {
907 if ((setup->bRequest == 0x06) && (setup->wValue == 0x0600)) {
908 USB_LOG_WRN("Ignore DQD in fs\r\n"); /* Device Qualifier Descriptor */
909 return false;
910 }
911 }
912 #else
913 #ifndef CONFIG_USB_HS
914 if ((setup->bRequest == 0x06) && (setup->wValue == 0x0600)) {
915 USB_LOG_WRN("Ignore DQD in fs\r\n"); /* Device Qualifier Descriptor */
916 return false;
917 }
918 #endif
919 #endif
920 USB_LOG_ERR("standard request error\r\n");
921 usbd_print_setup(setup);
922 return false;
923 }
924 break;
925 case USB_REQUEST_CLASS:
926 if (usbd_class_request_handler(setup, data, len) < 0) {
927 USB_LOG_ERR("class request error\r\n");
928 usbd_print_setup(setup);
929 return false;
930 }
931 break;
932 case USB_REQUEST_VENDOR:
933 if (usbd_vendor_request_handler(setup, data, len) < 0) {
934 USB_LOG_ERR("vendor request error\r\n");
935 usbd_print_setup(setup);
936 return false;
937 }
938 break;
939
940 default:
941 return false;
942 }
943
944 return true;
945 }
946
947 static void usbd_class_event_notify_handler(uint8_t event, void *arg)
948 {
949 for (uint8_t i = 0; i < g_usbd_core.intf_offset; i++) {
950 struct usbd_interface *intf = g_usbd_core.intf[i];
951
952 if (arg) {
953 struct usb_interface_descriptor *desc = (struct usb_interface_descriptor *)arg;
954 if (intf && intf->notify_handler && (desc->bInterfaceNumber == (intf->intf_num))) {
955 intf->notify_handler(event, arg);
956 }
957 } else {
958 if (intf && intf->notify_handler) {
959 intf->notify_handler(event, arg);
960 }
961 }
962 }
963 }
964
965 void usbd_event_connect_handler(void)
966 {
967 usbd_event_handler(USBD_EVENT_CONNECTED);
968 }
969
970 void usbd_event_disconnect_handler(void)
971 {
972 usbd_event_handler(USBD_EVENT_DISCONNECTED);
973 }
974
975 void usbd_event_resume_handler(void)
976 {
977 usbd_event_handler(USBD_EVENT_RESUME);
978 }
979
980 void usbd_event_suspend_handler(void)
981 {
982 usbd_event_handler(USBD_EVENT_SUSPEND);
983 }
984
985 void usbd_event_reset_handler(void)
986 {
987 usbd_set_address(0);
988 g_usbd_core.configuration = 0;
989
990 #ifdef CONFIG_USBDEV_TEST_MODE
991 g_usbd_core.test_mode = false;
992 #endif
993 struct usbd_endpoint_cfg ep0_cfg;
994
995 ep0_cfg.ep_mps = USB_CTRL_EP_MPS;
996 ep0_cfg.ep_type = USB_ENDPOINT_TYPE_CONTROL;
997 ep0_cfg.ep_addr = USB_CONTROL_IN_EP0;
998 usbd_ep_open(&ep0_cfg);
999
1000 ep0_cfg.ep_addr = USB_CONTROL_OUT_EP0;
1001 usbd_ep_open(&ep0_cfg);
1002
1003 usbd_class_event_notify_handler(USBD_EVENT_RESET, NULL);
1004 usbd_event_handler(USBD_EVENT_RESET);
1005 }
1006
1007 void usbd_event_ep0_setup_complete_handler(uint8_t *psetup)
1008 {
1009 struct usb_setup_packet *setup = &g_usbd_core.setup;
1010
1011 memcpy(setup, psetup, 8);
1012 #ifdef CONFIG_USBDEV_SETUP_LOG_PRINT
1013 usbd_print_setup(setup);
1014 #endif
1015 if (setup->wLength > CONFIG_USBDEV_REQUEST_BUFFER_LEN) {
1016 if ((setup->bmRequestType & USB_REQUEST_DIR_MASK) == USB_REQUEST_DIR_OUT) {
1017 USB_LOG_ERR("Request buffer too small\r\n");
1018 usbd_ep_set_stall(USB_CONTROL_IN_EP0);
1019 return;
1020 }
1021 }
1022
1023 g_usbd_core.ep0_data_buf = g_usbd_core.req_data;
1024 g_usbd_core.ep0_data_buf_residue = setup->wLength;
1025 g_usbd_core.ep0_data_buf_len = setup->wLength;
1026 g_usbd_core.zlp_flag = false;
1027
1028 /* handle class request when all the data is received */
1029 if (setup->wLength && ((setup->bmRequestType & USB_REQUEST_DIR_MASK) == USB_REQUEST_DIR_OUT)) {
1030 USB_LOG_DBG("Start reading %d bytes from ep0\r\n", setup->wLength);
1031 usbd_ep_start_read(USB_CONTROL_OUT_EP0, g_usbd_core.ep0_data_buf, setup->wLength);
1032 return;
1033 }
1034
1035 /* Ask installed handler to process request */
1036 if (!usbd_setup_request_handler(setup, &g_usbd_core.ep0_data_buf, &g_usbd_core.ep0_data_buf_len)) {
1037 usbd_ep_set_stall(USB_CONTROL_IN_EP0);
1038 return;
1039 }
1040 #ifdef CONFIG_USBDEV_TEST_MODE
1041 /* send status in test mode, so do not execute downward, just return */
1042 if (g_usbd_core.test_mode) {
1043 g_usbd_core.test_mode = false;
1044 return;
1045 }
1046 #endif
1047 /* Send smallest of requested and offered length */
1048 g_usbd_core.ep0_data_buf_residue = MIN(g_usbd_core.ep0_data_buf_len, setup->wLength);
1049 if (g_usbd_core.ep0_data_buf_residue > CONFIG_USBDEV_REQUEST_BUFFER_LEN) {
1050 USB_LOG_ERR("Request buffer too small\r\n");
1051 return;
1052 }
1053
1054 /* Send data or status to host */
1055 usbd_ep_start_write(USB_CONTROL_IN_EP0, g_usbd_core.ep0_data_buf, g_usbd_core.ep0_data_buf_residue);
1056 /*
1057 * Set ZLP flag when host asks for a bigger length and the data size is
1058 * multiplier of USB_CTRL_EP_MPS, to indicate the transfer done after zlp
1059 * sent.
1060 */
1061 if ((setup->wLength > g_usbd_core.ep0_data_buf_len) && (!(g_usbd_core.ep0_data_buf_len % USB_CTRL_EP_MPS))) {
1062 g_usbd_core.zlp_flag = true;
1063 USB_LOG_DBG("EP0 Set zlp\r\n");
1064 }
1065 }
1066
1067 void usbd_event_ep0_in_complete_handler(uint8_t ep, uint32_t nbytes)
1068 {
1069 struct usb_setup_packet *setup = &g_usbd_core.setup;
1070
1071 g_usbd_core.ep0_data_buf += nbytes;
1072 g_usbd_core.ep0_data_buf_residue -= nbytes;
1073
1074 USB_LOG_DBG("EP0 send %d bytes, %d remained\r\n", nbytes, g_usbd_core.ep0_data_buf_residue);
1075
1076 if (g_usbd_core.ep0_data_buf_residue != 0) {
1077 /* Start sending the remain data */
1078 usbd_ep_start_write(USB_CONTROL_IN_EP0, g_usbd_core.ep0_data_buf, g_usbd_core.ep0_data_buf_residue);
1079 } else {
1080 if (g_usbd_core.zlp_flag == true) {
1081 g_usbd_core.zlp_flag = false;
1082 /* Send zlp to host */
1083 USB_LOG_DBG("EP0 Send zlp\r\n");
1084 usbd_ep_start_write(USB_CONTROL_IN_EP0, NULL, 0);
1085 } else {
1086 /* Satisfying three conditions will jump here.
1087 * 1. send status completely
1088 * 2. send zlp completely
1089 * 3. send last data completely.
1090 */
1091 if (setup->wLength && ((setup->bmRequestType & USB_REQUEST_DIR_MASK) == USB_REQUEST_DIR_IN)) {
1092 /* if all data has sent completely, start reading out status */
1093 usbd_ep_start_read(USB_CONTROL_OUT_EP0, NULL, 0);
1094 }
1095 }
1096 }
1097 }
1098
1099 void usbd_event_ep0_out_complete_handler(uint8_t ep, uint32_t nbytes)
1100 {
1101 struct usb_setup_packet *setup = &g_usbd_core.setup;
1102
1103 if (nbytes > 0) {
1104 g_usbd_core.ep0_data_buf += nbytes;
1105 g_usbd_core.ep0_data_buf_residue -= nbytes;
1106
1107 USB_LOG_DBG("EP0 recv %d bytes, %d remained\r\n", nbytes, g_usbd_core.ep0_data_buf_residue);
1108
1109 if (g_usbd_core.ep0_data_buf_residue == 0) {
1110 /* Received all, send data to handler */
1111 g_usbd_core.ep0_data_buf = g_usbd_core.req_data;
1112 if (!usbd_setup_request_handler(setup, &g_usbd_core.ep0_data_buf, &g_usbd_core.ep0_data_buf_len)) {
1113 usbd_ep_set_stall(USB_CONTROL_IN_EP0);
1114 return;
1115 }
1116
1117 /*Send status to host*/
1118 usbd_ep_start_write(USB_CONTROL_IN_EP0, NULL, 0);
1119 } else {
1120 /* Start reading the remain data */
1121 usbd_ep_start_read(USB_CONTROL_OUT_EP0, g_usbd_core.ep0_data_buf, g_usbd_core.ep0_data_buf_residue);
1122 }
1123 } else {
1124 /* Read out status completely, do nothing */
1125 USB_LOG_DBG("EP0 recv out status\r\n");
1126 }
1127 }
1128
1129 void usbd_event_ep_in_complete_handler(uint8_t ep, uint32_t nbytes)
1130 {
1131 if (g_usbd_core.tx_msg[ep & 0x7f].cb) {
1132 g_usbd_core.tx_msg[ep & 0x7f].cb(ep, nbytes);
1133 }
1134 }
1135
1136 void usbd_event_ep_out_complete_handler(uint8_t ep, uint32_t nbytes)
1137 {
1138 if (g_usbd_core.rx_msg[ep & 0x7f].cb) {
1139 g_usbd_core.rx_msg[ep & 0x7f].cb(ep, nbytes);
1140 }
1141 }
1142
1143 #ifdef CONFIG_USBDEV_ADVANCE_DESC
1144 void usbd_desc_register(struct usb_descriptor *desc)
1145 {
1146 memset(&g_usbd_core, 0, sizeof(struct usbd_core_priv));
1147
1148 g_usbd_core.descriptors = desc;
1149 g_usbd_core.intf_offset = 0;
1150
1151 g_usbd_core.tx_msg[0].ep = 0x80;
1152 g_usbd_core.tx_msg[0].cb = usbd_event_ep0_in_complete_handler;
1153 g_usbd_core.rx_msg[0].ep = 0x00;
1154 g_usbd_core.rx_msg[0].cb = usbd_event_ep0_out_complete_handler;
1155 }
1156 #else
1157 void usbd_desc_register(const uint8_t *desc)
1158 {
1159 memset(&g_usbd_core, 0, sizeof(struct usbd_core_priv));
1160
1161 g_usbd_core.descriptors = desc;
1162 g_usbd_core.intf_offset = 0;
1163
1164 g_usbd_core.tx_msg[0].ep = 0x80;
1165 g_usbd_core.tx_msg[0].cb = usbd_event_ep0_in_complete_handler;
1166 g_usbd_core.rx_msg[0].ep = 0x00;
1167 g_usbd_core.rx_msg[0].cb = usbd_event_ep0_out_complete_handler;
1168 }
1169
1170 /* Register MS OS Descriptors version 1 */
1171 void usbd_msosv1_desc_register(struct usb_msosv1_descriptor *desc)
1172 {
1173 g_usbd_core.msosv1_desc = desc;
1174 }
1175
1176 /* Register MS OS Descriptors version 2 */
1177 void usbd_msosv2_desc_register(struct usb_msosv2_descriptor *desc)
1178 {
1179 g_usbd_core.msosv2_desc = desc;
1180 }
1181
1182 void usbd_bos_desc_register(struct usb_bos_descriptor *desc)
1183 {
1184 g_usbd_core.bos_desc = desc;
1185 }
1186 #endif
1187
1188 void usbd_add_interface(struct usbd_interface *intf)
1189 {
1190 intf->intf_num = g_usbd_core.intf_offset;
1191 g_usbd_core.intf[g_usbd_core.intf_offset] = intf;
1192 g_usbd_core.intf_offset++;
1193 }
1194
1195 void usbd_add_endpoint(struct usbd_endpoint *ep)
1196 {
1197 if (ep->ep_addr & 0x80) {
1198 g_usbd_core.tx_msg[ep->ep_addr & 0x7f].ep = ep->ep_addr;
1199 g_usbd_core.tx_msg[ep->ep_addr & 0x7f].cb = ep->ep_cb;
1200 } else {
1201 g_usbd_core.rx_msg[ep->ep_addr & 0x7f].ep = ep->ep_addr;
1202 g_usbd_core.rx_msg[ep->ep_addr & 0x7f].cb = ep->ep_cb;
1203 }
1204 }
1205
1206 bool usb_device_is_configured(void)
1207 {
1208 return g_usbd_core.configuration;
1209 }
1210
1211 int usbd_initialize(void)
1212 {
1213 return usb_dc_init();
1214 }
1215
1216 int usbd_deinitialize(void)
1217 {
1218 g_usbd_core.intf_offset = 0;
1219 usb_dc_deinit();
1220 return 0;
1221 }
1222
1223 __WEAK void usbd_event_handler(uint8_t event)
1224 {
1225 switch (event) {
1226 case USBD_EVENT_RESET:
1227 break;
1228 case USBD_EVENT_CONNECTED:
1229 break;
1230 case USBD_EVENT_DISCONNECTED:
1231 break;
1232 case USBD_EVENT_RESUME:
1233 break;
1234 case USBD_EVENT_SUSPEND:
1235 break;
1236 case USBD_EVENT_CONFIGURED:
1237 break;
1238 case USBD_EVENT_SET_REMOTE_WAKEUP:
1239 break;
1240 case USBD_EVENT_CLR_REMOTE_WAKEUP:
1241 break;
1242
1243 default:
1244 break;
1245 }
1246 }
1247