• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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