1 /*
2  * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "usb_device_config.h"
10 #include "usb.h"
11 
12 #include "usb_device.h"
13 #include "usb_device_dci.h"
14 #include "usb_device_class.h"
15 #include "usb_device_ch9.h"
16 #if ((defined(USB_DEVICE_CONFIG_NUM)) && (USB_DEVICE_CONFIG_NUM > 0U))
17 /*******************************************************************************
18  * Definitions
19  ******************************************************************************/
20 
21 /*!
22  * @brief Standard request callback function typedef.
23  *
24  * This function is used to handle the standard request.
25  *
26  * @param handle          The device handle. It equals the value returned from USB_DeviceInit.
27  * @param setup           The pointer of the setup packet.
28  * @param buffer          It is an out parameter, is used to save the buffer address to response the host's request.
29  * @param length          It is an out parameter, the data length.
30  *
31  * @return A USB error code or kStatus_USB_Success.
32  */
33 typedef usb_status_t (*usb_standard_request_callback_t)(usb_device_common_class_struct_t *classHandle,
34                                                         usb_setup_struct_t *setup,
35                                                         uint8_t **buffer,
36                                                         uint32_t *length);
37 
38 /*******************************************************************************
39  * Prototypes
40  ******************************************************************************/
41 
42 static usb_status_t USB_DeviceCh9GetStatus(usb_device_common_class_struct_t *classHandle,
43                                            usb_setup_struct_t *setup,
44                                            uint8_t **buffer,
45                                            uint32_t *length);
46 static usb_status_t USB_DeviceCh9SetClearFeature(usb_device_common_class_struct_t *classHandle,
47                                                  usb_setup_struct_t *setup,
48                                                  uint8_t **buffer,
49                                                  uint32_t *length);
50 
51 static usb_status_t USB_DeviceCh9SetAddress(usb_device_common_class_struct_t *classHandle,
52                                             usb_setup_struct_t *setup,
53                                             uint8_t **buffer,
54                                             uint32_t *length);
55 static usb_status_t USB_DeviceCh9GetDescriptor(usb_device_common_class_struct_t *classHandle,
56                                                usb_setup_struct_t *setup,
57                                                uint8_t **buffer,
58                                                uint32_t *length);
59 static usb_status_t USB_DeviceCh9GetConfiguration(usb_device_common_class_struct_t *classHandle,
60                                                   usb_setup_struct_t *setup,
61                                                   uint8_t **buffer,
62                                                   uint32_t *length);
63 static usb_status_t USB_DeviceCh9SetConfiguration(usb_device_common_class_struct_t *classHandle,
64                                                   usb_setup_struct_t *setup,
65                                                   uint8_t **buffer,
66                                                   uint32_t *length);
67 static usb_status_t USB_DeviceCh9GetInterface(usb_device_common_class_struct_t *classHandle,
68                                               usb_setup_struct_t *setup,
69                                               uint8_t **buffer,
70                                               uint32_t *length);
71 static usb_status_t USB_DeviceCh9SetInterface(usb_device_common_class_struct_t *classHandle,
72                                               usb_setup_struct_t *setup,
73                                               uint8_t **buffer,
74                                               uint32_t *length);
75 static usb_status_t USB_DeviceCh9SynchFrame(usb_device_common_class_struct_t *classHandle,
76                                             usb_setup_struct_t *setup,
77                                             uint8_t **buffer,
78                                             uint32_t *length);
79 
80 /*******************************************************************************
81  * Variables
82  ******************************************************************************/
83 
84 /* The function list to handle the standard request. */
85 static const usb_standard_request_callback_t s_UsbDeviceStandardRequest[] = {
86     USB_DeviceCh9GetStatus,
87     USB_DeviceCh9SetClearFeature,
88     (usb_standard_request_callback_t)NULL,
89     USB_DeviceCh9SetClearFeature,
90     (usb_standard_request_callback_t)NULL,
91     USB_DeviceCh9SetAddress,
92     USB_DeviceCh9GetDescriptor,
93     (usb_standard_request_callback_t)NULL,
94     USB_DeviceCh9GetConfiguration,
95     USB_DeviceCh9SetConfiguration,
96     USB_DeviceCh9GetInterface,
97     USB_DeviceCh9SetInterface,
98     USB_DeviceCh9SynchFrame,
99 };
100 
101 /*******************************************************************************
102  * Code
103  ******************************************************************************/
104 
105 /*!
106  * @brief Handle get status request.
107  *
108  * This function is used to handle get status request.
109  *
110  * @param handle          The device handle. It equals the value returned from USB_DeviceInit.
111  * @param setup           The pointer of the setup packet.
112  * @param buffer          It is an out parameter, is used to save the buffer address to response the host's request.
113  * @param length          It is an out parameter, the data length.
114  *
115  * @retval kStatus_USB_Success              The request is handled successfully.
116  * @retval kStatus_USB_InvalidRequest       The request can not be handle in current device state,
117  *                                          or, the request is unsupported.
118  */
USB_DeviceCh9GetStatus(usb_device_common_class_struct_t * classHandle,usb_setup_struct_t * setup,uint8_t ** buffer,uint32_t * length)119 static usb_status_t USB_DeviceCh9GetStatus(usb_device_common_class_struct_t *classHandle,
120                                            usb_setup_struct_t *setup,
121                                            uint8_t **buffer,
122                                            uint32_t *length)
123 {
124     usb_status_t error = kStatus_USB_InvalidRequest;
125     uint8_t state      = 0U;
126 
127     if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) != USB_REQUEST_TYPE_DIR_IN) || (setup->wValue != 0U) ||
128         (setup->wLength != 2U))
129     {
130         return error;
131     }
132 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
133     if (kStatus_USB_Success != USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
134     {
135         return kStatus_USB_Error;
136     }
137 #else
138     (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
139 #endif
140 
141     if (((uint8_t)kUSB_DeviceStateAddress != state) && ((uint8_t)kUSB_DeviceStateConfigured != state))
142     {
143         return error;
144     }
145 
146     if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE)
147     {
148 #if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG))
149         if (setup->wIndex == USB_REQUEST_STANDARD_GET_STATUS_OTG_STATUS_SELECTOR)
150         {
151             error =
152                 USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusOtg, &classHandle->standardTranscationBuffer);
153             classHandle->standardTranscationBuffer = USB_SHORT_TO_LITTLE_ENDIAN(classHandle->standardTranscationBuffer);
154             /* The device status length must be USB_DEVICE_STATUS_SIZE. */
155             *length = 1;
156         }
157         else /* Get the device status */
158         {
159 #endif
160             error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDevice,
161                                         &classHandle->standardTranscationBuffer);
162             classHandle->standardTranscationBuffer =
163                 classHandle->standardTranscationBuffer & USB_GET_STATUS_DEVICE_MASK;
164             classHandle->standardTranscationBuffer = USB_SHORT_TO_LITTLE_ENDIAN(classHandle->standardTranscationBuffer);
165             /* The device status length must be USB_DEVICE_STATUS_SIZE. */
166             *length = USB_DEVICE_STATUS_SIZE;
167 #if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG))
168         }
169 #endif
170     }
171     else if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_INTERFACE)
172     {
173 #if ((defined(USB_DEVICE_CONFIG_ROOT2_TEST)) && (USB_DEVICE_CONFIG_ROOT2_TEST > 0U))
174         if (((uint8_t)kUSB_DeviceStateAddress == state) ||
175             (((uint8_t)kUSB_DeviceStateConfigured == state) && (0U == setup->wIndex)))
176         {
177             /* In valid address state, device must stall the status stage for get status (interface) request.
178                In configured state, device must stall the status stage for get status (interface 0) request */
179             return error;
180         }
181 #endif
182         /* Get the interface status */
183         error                                  = kStatus_USB_Success;
184         classHandle->standardTranscationBuffer = 0U;
185         /* The interface status length must be USB_INTERFACE_STATUS_SIZE. */
186         *length = USB_INTERFACE_STATUS_SIZE;
187     }
188     else if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT)
189     {
190 #if ((defined(USB_DEVICE_CONFIG_ROOT2_TEST)) && (USB_DEVICE_CONFIG_ROOT2_TEST > 0U))
191         if ((USB_CONTROL_ENDPOINT != (setup->wIndex & USB_ENDPOINT_NUMBER_MASK)) &&
192             ((uint8_t)kUSB_DeviceStateAddress == state))
193         {
194             /* In valid address, device must stall the status stage for get status (EP) request for no-control endpoint
195              */
196             return error;
197         }
198 #endif
199         /* Get the endpoint status */
200         usb_device_endpoint_status_struct_t endpointStatus;
201         endpointStatus.endpointAddress = (uint8_t)setup->wIndex;
202         endpointStatus.endpointStatus  = (uint16_t)kUSB_DeviceEndpointStateIdle;
203         error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusEndpoint, &endpointStatus);
204         classHandle->standardTranscationBuffer = endpointStatus.endpointStatus & USB_GET_STATUS_ENDPOINT_MASK;
205         classHandle->standardTranscationBuffer = USB_SHORT_TO_LITTLE_ENDIAN(classHandle->standardTranscationBuffer);
206         /* The endpoint status length must be USB_INTERFACE_STATUS_SIZE. */
207         *length = USB_ENDPOINT_STATUS_SIZE;
208     }
209     else
210     {
211         /*no action*/
212     }
213     *buffer = (uint8_t *)&classHandle->standardTranscationBuffer;
214 
215     return error;
216 }
217 
218 /*!
219  * @brief Handle set or clear device feature request.
220  *
221  * This function is used to handle set or clear device feature request.
222  *
223  * @param handle          The device handle. It equals the value returned from USB_DeviceInit.
224  * @param setup           The pointer of the setup packet.
225  * @param buffer          It is an out parameter, is used to save the buffer address to response the host's request.
226  * @param length          It is an out parameter, the data length.
227  *
228  * @retval kStatus_USB_Success              The request is handled successfully.
229  * @retval kStatus_USB_InvalidRequest       The request can not be handle in current device state,
230  *                                          or, the request is unsupported.
231  */
USB_DeviceCh9SetClearFeature(usb_device_common_class_struct_t * classHandle,usb_setup_struct_t * setup,uint8_t ** buffer,uint32_t * length)232 static usb_status_t USB_DeviceCh9SetClearFeature(usb_device_common_class_struct_t *classHandle,
233                                                  usb_setup_struct_t *setup,
234                                                  uint8_t **buffer,
235                                                  uint32_t *length)
236 {
237     usb_status_t error = kStatus_USB_InvalidRequest;
238     uint8_t state      = 0U;
239     uint8_t isSet      = 0U;
240 
241     if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) != USB_REQUEST_TYPE_DIR_OUT) || (setup->wLength != 0U))
242     {
243         return error;
244     }
245 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
246     if (kStatus_USB_Success != USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
247     {
248         return kStatus_USB_Error;
249     }
250 #else
251     (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
252 #endif
253 
254     if (((uint8_t)kUSB_DeviceStateAddress != state) && ((uint8_t)kUSB_DeviceStateConfigured != state))
255     {
256         return error;
257     }
258 
259     /* Identify the request is set or clear the feature. */
260     if (USB_REQUEST_STANDARD_SET_FEATURE == setup->bRequest)
261     {
262         isSet = 1U;
263     }
264 
265     if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE)
266     {
267         /* Set or Clear the device feature. */
268         if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_REMOTE_WAKEUP == setup->wValue)
269         {
270 #if ((defined(USB_DEVICE_CONFIG_REMOTE_WAKEUP)) && (USB_DEVICE_CONFIG_REMOTE_WAKEUP > 0U))
271             USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusRemoteWakeup, &isSet);
272 #endif
273             /* Set or Clear the device remote wakeup feature. */
274             error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventSetRemoteWakeup, &isSet);
275         }
276 #if ((defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) ||                \
277      (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) && \
278     (defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U))
279         else if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_TEST_MODE == setup->wValue)
280         {
281             state = kUSB_DeviceStateTestMode;
282             error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
283         }
284 #endif
285 #if (defined(USB_DEVICE_CONFIG_OTG) && (USB_DEVICE_CONFIG_OTG))
286         else if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_B_HNP_ENABLE == setup->wValue)
287         {
288             error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventSetBHNPEnable, &isSet);
289         }
290 #endif
291         else
292         {
293         }
294     }
295     else if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT)
296     {
297         /* Set or Clear the endpoint feature. */
298         if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT == setup->wValue)
299         {
300 #if ((defined(USB_DEVICE_CONFIG_ROOT2_TEST)) && (USB_DEVICE_CONFIG_ROOT2_TEST > 0U))
301             if ((USB_CONTROL_ENDPOINT != (setup->wIndex & USB_ENDPOINT_NUMBER_MASK)) &&
302                 (kUSB_DeviceStateConfigured != state))
303             {
304                 /* In no-configured state, device must stall the status stage for clear/set feature halt requests for
305                  * no-control endpoint */
306                 return error;
307             }
308             else
309             {
310                 /* In configured state, device must stall the status stage for clear/set feature halt for no-initialized
311                    EP. For contol EP, device must accept status stage of Set Feature Halt (Endpoint 80) in Addressed
312                    State */
313                 usb_device_endpoint_status_struct_t endpointStatus;
314                 endpointStatus.endpointAddress = (uint8_t)setup->wIndex;
315                 error = USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusEndpoint, &endpointStatus);
316                 if (kStatus_USB_Success != error)
317                 {
318                     return error;
319                 }
320             }
321 #else
322             if (USB_CONTROL_ENDPOINT == (setup->wIndex & USB_ENDPOINT_NUMBER_MASK))
323             {
324                 /* Set or Clear the control endpoint status(halt or not). */
325                 if (0U != isSet)
326                 {
327 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
328                     if (kStatus_USB_Success != USB_DeviceStallEndpoint(classHandle->handle, (uint8_t)setup->wIndex))
329                     {
330                         return kStatus_USB_Error;
331                     }
332 #else
333                     (void)USB_DeviceStallEndpoint(classHandle->handle, (uint8_t)setup->wIndex);
334 #endif
335                 }
336                 else
337                 {
338 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
339                     if (kStatus_USB_Success != USB_DeviceUnstallEndpoint(classHandle->handle, (uint8_t)setup->wIndex))
340                     {
341                         return kStatus_USB_Error;
342                     }
343 #else
344                     (void)USB_DeviceUnstallEndpoint(classHandle->handle, (uint8_t)setup->wIndex);
345 #endif
346                 }
347             }
348 #endif
349             /* Set or Clear the endpoint status feature. */
350             if (0U != isSet)
351             {
352                 error = USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventSetEndpointHalt, &setup->wIndex);
353             }
354             else
355             {
356                 error =
357                     USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventClearEndpointHalt, &setup->wIndex);
358             }
359         }
360         else
361         {
362             /*no action*/
363         }
364     }
365     else
366     {
367         /*no action*/
368     }
369 
370     return error;
371 }
372 
373 /*!
374  * @brief Handle set address request.
375  *
376  * This function is used to handle set address request.
377  *
378  * @param handle          The device handle. It equals the value returned from USB_DeviceInit.
379  * @param setup           The pointer of the setup packet.
380  * @param buffer          It is an out parameter, is used to save the buffer address to response the host's request.
381  * @param length          It is an out parameter, the data length.
382  *
383  * @retval kStatus_USB_Success              The request is handled successfully.
384  * @retval kStatus_USB_InvalidRequest       The request can not be handle in current device state.
385  */
USB_DeviceCh9SetAddress(usb_device_common_class_struct_t * classHandle,usb_setup_struct_t * setup,uint8_t ** buffer,uint32_t * length)386 static usb_status_t USB_DeviceCh9SetAddress(usb_device_common_class_struct_t *classHandle,
387                                             usb_setup_struct_t *setup,
388                                             uint8_t **buffer,
389                                             uint32_t *length)
390 {
391     usb_status_t error = kStatus_USB_InvalidRequest;
392     uint8_t state      = 0U;
393 
394     if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) != USB_REQUEST_TYPE_DIR_OUT) ||
395         ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) != USB_REQUEST_TYPE_RECIPIENT_DEVICE) ||
396         (setup->wIndex != 0U) || (setup->wLength != 0U))
397     {
398         return error;
399     }
400 
401 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
402     if (kStatus_USB_Success != USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
403     {
404         return kStatus_USB_Error;
405     }
406 #else
407     (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
408 #endif
409 
410     if (((uint8_t)kUSB_DeviceStateAddressing != state) && ((uint8_t)kUSB_DeviceStateAddress != state) &&
411         ((uint8_t)kUSB_DeviceStateDefault != state)
412 #if ((defined(USB_DEVICE_CONFIG_ROOT2_TEST)) && (USB_DEVICE_CONFIG_ROOT2_TEST > 0U))
413 #else
414         && ((uint8_t)kUSB_DeviceStateConfigured != state)
415 #endif
416     )
417     {
418         return error;
419     }
420 
421     if ((uint8_t)kUSB_DeviceStateAddressing != state)
422     {
423         /* If the device address is not setting, pass the address and the device state will change to
424          * kUSB_DeviceStateAddressing internally. */
425         state = (uint8_t)(setup->wValue & 0xFFU);
426 #if ((defined(USB_DEVICE_CONFIG_ROOT2_TEST)) && (USB_DEVICE_CONFIG_ROOT2_TEST > 0U))
427         /* Setting the address to 128 or above should not be allowed. */
428         if (state >= 0x80U)
429         {
430             return error;
431         }
432 #endif
433         error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusAddress, &state);
434     }
435     else
436     {
437         /* If the device address is setting, set device address and the address will be write into the controller
438          * internally. */
439         error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusAddress, NULL);
440         /* And then change the device state to kUSB_DeviceStateAddress. */
441         if (kStatus_USB_Success == error)
442         {
443             state = (uint8_t)kUSB_DeviceStateAddress;
444             error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
445         }
446     }
447 
448     return error;
449 }
450 
451 /*!
452  * @brief Handle get descriptor request.
453  *
454  * This function is used to handle get descriptor request.
455  *
456  * @param handle          The device handle. It equals the value returned from USB_DeviceInit.
457  * @param setup           The pointer of the setup packet.
458  * @param buffer          It is an out parameter, is used to save the buffer address to response the host's request.
459  * @param length          It is an out parameter, the data length.
460  *
461  * @retval kStatus_USB_Success              The request is handled successfully.
462  * @retval kStatus_USB_InvalidRequest       The request can not be handle in current device state,
463  *                                          or, the request is unsupported.
464  */
USB_DeviceCh9GetDescriptor(usb_device_common_class_struct_t * classHandle,usb_setup_struct_t * setup,uint8_t ** buffer,uint32_t * length)465 static usb_status_t USB_DeviceCh9GetDescriptor(usb_device_common_class_struct_t *classHandle,
466                                                usb_setup_struct_t *setup,
467                                                uint8_t **buffer,
468                                                uint32_t *length)
469 {
470     usb_device_get_descriptor_common_union_t commonDescriptor;
471     usb_status_t error      = kStatus_USB_InvalidRequest;
472     uint8_t state           = 0U;
473     uint8_t descriptorType  = (uint8_t)((setup->wValue & 0xFF00U) >> 8U);
474     uint8_t descriptorIndex = (uint8_t)((setup->wValue & 0x00FFU));
475 
476     if ((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) != USB_REQUEST_TYPE_DIR_IN)
477     {
478         return error;
479     }
480 
481 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
482     if (kStatus_USB_Success != USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
483     {
484         return kStatus_USB_Error;
485     }
486 #else
487     (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
488 #endif
489 
490     if (((uint8_t)kUSB_DeviceStateAddress != state) && ((uint8_t)kUSB_DeviceStateConfigured != state) &&
491         ((uint8_t)kUSB_DeviceStateDefault != state))
492     {
493         return error;
494     }
495     commonDescriptor.commonDescriptor.length = setup->wLength;
496     if (USB_DESCRIPTOR_TYPE_DEVICE == descriptorType)
497     {
498         /* Get the device descriptor */
499         if (((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE) &&
500             (descriptorIndex == 0U) && (setup->wIndex == 0U))
501         {
502             error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetDeviceDescriptor,
503                                             &commonDescriptor.deviceDescriptor);
504         }
505     }
506     else if (USB_DESCRIPTOR_TYPE_CONFIGURE == descriptorType)
507     {
508         /* Get the configuration descriptor */
509         if (((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE) &&
510             (setup->wIndex == 0U))
511         {
512             commonDescriptor.configurationDescriptor.configuration = descriptorIndex;
513             error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetConfigurationDescriptor,
514                                             &commonDescriptor.configurationDescriptor);
515         }
516     }
517     else if (USB_DESCRIPTOR_TYPE_STRING == descriptorType)
518     {
519         /* Get the string descriptor */
520         if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE)
521         {
522             commonDescriptor.stringDescriptor.stringIndex = descriptorIndex;
523             commonDescriptor.stringDescriptor.languageId  = setup->wIndex;
524             error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetStringDescriptor,
525                                             &commonDescriptor.stringDescriptor);
526         }
527     }
528 #if (defined(USB_DEVICE_CONFIG_HID) && (USB_DEVICE_CONFIG_HID > 0U))
529     else if (USB_DESCRIPTOR_TYPE_HID == descriptorType)
530     {
531         /* Get the hid descriptor */
532         if (((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_INTERFACE) &&
533             (descriptorIndex == 0U))
534         {
535             commonDescriptor.hidDescriptor.interfaceNumber = (uint8_t)setup->wIndex;
536             error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetHidDescriptor,
537                                             &commonDescriptor.hidDescriptor);
538         }
539     }
540     else if (USB_DESCRIPTOR_TYPE_HID_REPORT == descriptorType)
541     {
542         /* Get the hid report descriptor */
543         if (((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_INTERFACE) &&
544             (descriptorIndex == 0U))
545         {
546             commonDescriptor.hidReportDescriptor.interfaceNumber = (uint8_t)setup->wIndex;
547             error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetHidReportDescriptor,
548                                             &commonDescriptor.hidReportDescriptor);
549         }
550     }
551     else if (USB_DESCRIPTOR_TYPE_HID_PHYSICAL == descriptorType)
552     {
553         /* Get the hid physical descriptor */
554         if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_INTERFACE)
555         {
556             commonDescriptor.hidPhysicalDescriptor.index           = descriptorIndex;
557             commonDescriptor.hidPhysicalDescriptor.interfaceNumber = (uint8_t)setup->wIndex;
558             error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetHidPhysicalDescriptor,
559                                             &commonDescriptor.hidPhysicalDescriptor);
560         }
561     }
562 #endif
563 #if (defined(USB_DEVICE_CONFIG_CV_TEST) && (USB_DEVICE_CONFIG_CV_TEST > 0U))
564     else if (USB_DESCRIPTOR_TYPE_DEVICE_QUALITIER == descriptorType)
565     {
566         /* Get the device descriptor */
567         if (((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE) &&
568             (descriptorIndex == 0U) && (setup->wIndex == 0U))
569         {
570             error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetDeviceQualifierDescriptor,
571                                             &commonDescriptor.deviceDescriptor);
572         }
573     }
574 #endif
575 #if (defined(USB_DEVICE_CONFIG_LPM_L1) && (USB_DEVICE_CONFIG_LPM_L1 > 0U))
576     else if (USB_DESCRIPTOR_TYPE_BOS == descriptorType)
577     {
578         /* Get the configuration descriptor */
579         if (((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE) &&
580             (setup->wIndex == 0U))
581         {
582             commonDescriptor.configurationDescriptor.configuration = descriptorIndex;
583             error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetBOSDescriptor,
584                                             &commonDescriptor.configurationDescriptor);
585         }
586     }
587 #endif
588     else
589     {
590     }
591     *buffer = commonDescriptor.commonDescriptor.buffer;
592     *length = commonDescriptor.commonDescriptor.length;
593     return error;
594 }
595 
596 /*!
597  * @brief Handle get current configuration request.
598  *
599  * This function is used to handle get current configuration request.
600  *
601  * @param handle          The device handle. It equals the value returned from USB_DeviceInit.
602  * @param setup           The pointer of the setup packet.
603  * @param buffer          It is an out parameter, is used to save the buffer address to response the host's request.
604  * @param length          It is an out parameter, the data length.
605  *
606  * @retval kStatus_USB_Success              The request is handled successfully.
607  * @retval kStatus_USB_InvalidRequest       The request can not be handle in current device state,
608  *                                          or, the request is unsupported.
609  */
USB_DeviceCh9GetConfiguration(usb_device_common_class_struct_t * classHandle,usb_setup_struct_t * setup,uint8_t ** buffer,uint32_t * length)610 static usb_status_t USB_DeviceCh9GetConfiguration(usb_device_common_class_struct_t *classHandle,
611                                                   usb_setup_struct_t *setup,
612                                                   uint8_t **buffer,
613                                                   uint32_t *length)
614 {
615     uint8_t state = 0U;
616 
617     if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) != USB_REQUEST_TYPE_DIR_IN) ||
618         ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) != USB_REQUEST_TYPE_RECIPIENT_DEVICE) ||
619         (setup->wValue != 0U) || (setup->wIndex != 0U) || (setup->wLength != 1U))
620     {
621         return kStatus_USB_InvalidRequest;
622     }
623 
624 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
625     if (kStatus_USB_Success != USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
626     {
627         return kStatus_USB_Error;
628     }
629 #else
630     (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
631 #endif
632 
633     if (((uint8_t)kUSB_DeviceStateAddress != state) && (((uint8_t)kUSB_DeviceStateConfigured != state)))
634     {
635         return kStatus_USB_InvalidRequest;
636     }
637 
638     *length = USB_CONFIGURE_SIZE;
639     *buffer = (uint8_t *)&classHandle->standardTranscationBuffer;
640     return USB_DeviceClassCallback(classHandle->handle, (uint8_t)kUSB_DeviceEventGetConfiguration,
641                                    &classHandle->standardTranscationBuffer);
642 }
643 
644 /*!
645  * @brief Handle set current configuration request.
646  *
647  * This function is used to handle set current configuration request.
648  *
649  * @param handle          The device handle. It equals the value returned from USB_DeviceInit.
650  * @param setup           The pointer of the setup packet.
651  * @param buffer          It is an out parameter, is used to save the buffer address to response the host's request.
652  * @param length          It is an out parameter, the data length.
653  *
654  * @retval kStatus_USB_Success              The request is handled successfully.
655  * @retval kStatus_USB_InvalidRequest       The request can not be handle in current device state,
656  *                                          or, the request is unsupported.
657  */
USB_DeviceCh9SetConfiguration(usb_device_common_class_struct_t * classHandle,usb_setup_struct_t * setup,uint8_t ** buffer,uint32_t * length)658 static usb_status_t USB_DeviceCh9SetConfiguration(usb_device_common_class_struct_t *classHandle,
659                                                   usb_setup_struct_t *setup,
660                                                   uint8_t **buffer,
661                                                   uint32_t *length)
662 {
663     uint8_t state = 0U;
664 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
665     usb_status_t error = kStatus_USB_InvalidRequest;
666 #endif
667 
668     if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) != USB_REQUEST_TYPE_DIR_OUT) ||
669         ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) != USB_REQUEST_TYPE_RECIPIENT_DEVICE) ||
670         (setup->wIndex != 0U) || (setup->wLength != 0U))
671     {
672         return kStatus_USB_InvalidRequest;
673     }
674 
675 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
676     if (kStatus_USB_Success != USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
677     {
678         return kStatus_USB_Error;
679     }
680 #else
681     (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
682 #endif
683 
684     if (((uint8_t)kUSB_DeviceStateAddress != state) && ((uint8_t)kUSB_DeviceStateConfigured != state))
685     {
686         return kStatus_USB_InvalidRequest;
687     }
688 
689     /* The device state is changed to kUSB_DeviceStateConfigured */
690     state = (uint8_t)kUSB_DeviceStateConfigured;
691 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
692     if (kStatus_USB_Success != USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
693     {
694         return kStatus_USB_Error;
695     }
696 #else
697     (void)USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
698 #endif
699     if (0U == setup->wValue)
700     {
701         /* If the new configuration is zero, the device state is changed to kUSB_DeviceStateAddress */
702         state = (uint8_t)kUSB_DeviceStateAddress;
703 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
704         if (kStatus_USB_Success != USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
705         {
706             return kStatus_USB_Error;
707         }
708 #else
709         (void)USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
710 #endif
711     }
712 
713     /* Notify the class layer the configuration is changed */
714 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
715     error = USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventSetConfiguration, &setup->wValue);
716     if (kStatus_USB_Success != error)
717     {
718         return error;
719     }
720 #else
721     (void)USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventSetConfiguration, &setup->wValue);
722 #endif
723     /* Notify the application the configuration is changed */
724     return USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventSetConfiguration, &setup->wValue);
725 }
726 
727 /*!
728  * @brief Handle get the alternate setting of a interface request.
729  *
730  * This function is used to handle get the alternate setting of a interface request.
731  *
732  * @param handle          The device handle. It equals the value returned from USB_DeviceInit.
733  * @param setup           The pointer of the setup packet.
734  * @param buffer          It is an out parameter, is used to save the buffer address to response the host's request.
735  * @param length          It is an out parameter, the data length.
736  *
737  * @retval kStatus_USB_Success              The request is handled successfully.
738  * @retval kStatus_USB_InvalidRequest       The request can not be handle in current device state,
739  *                                          or, the request is unsupported.
740  */
USB_DeviceCh9GetInterface(usb_device_common_class_struct_t * classHandle,usb_setup_struct_t * setup,uint8_t ** buffer,uint32_t * length)741 static usb_status_t USB_DeviceCh9GetInterface(usb_device_common_class_struct_t *classHandle,
742                                               usb_setup_struct_t *setup,
743                                               uint8_t **buffer,
744                                               uint32_t *length)
745 {
746     usb_status_t error = kStatus_USB_InvalidRequest;
747     uint8_t state      = 0U;
748 
749     if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) != USB_REQUEST_TYPE_DIR_IN) ||
750         ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) != USB_REQUEST_TYPE_RECIPIENT_INTERFACE) ||
751         (setup->wValue != 0U) || (setup->wLength != 1U))
752     {
753         return error;
754     }
755 
756 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
757     if (kStatus_USB_Success != USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
758     {
759         return kStatus_USB_Error;
760     }
761 #else
762     (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
763 #endif
764 
765     if (state != (uint8_t)kUSB_DeviceStateConfigured)
766     {
767         return error;
768     }
769     *length                                = USB_INTERFACE_SIZE;
770     *buffer                                = (uint8_t *)&classHandle->standardTranscationBuffer;
771     classHandle->standardTranscationBuffer = (uint16_t)(((uint32_t)setup->wIndex & 0xFFU) << 8U);
772     /* The Bit[15~8] is used to save the interface index, and the alternate setting will be saved in Bit[7~0] by
773      * application. */
774     error = USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventGetInterface,
775                                     &classHandle->standardTranscationBuffer);
776     classHandle->standardTranscationBuffer = USB_SHORT_TO_LITTLE_ENDIAN(classHandle->standardTranscationBuffer);
777     return error;
778 }
779 
780 /*!
781  * @brief Handle set the alternate setting of a interface request.
782  *
783  * This function is used to handle set the alternate setting of a interface request.
784  *
785  * @param handle          The device handle. It equals the value returned from USB_DeviceInit.
786  * @param setup           The pointer of the setup packet.
787  * @param buffer          It is an out parameter, is used to save the buffer address to response the host's request.
788  * @param length          It is an out parameter, the data length.
789  *
790  * @retval kStatus_USB_Success              The request is handled successfully.
791  * @retval kStatus_USB_InvalidRequest       The request can not be handle in current device state,
792  *                                          or, the request is unsupported.
793  */
USB_DeviceCh9SetInterface(usb_device_common_class_struct_t * classHandle,usb_setup_struct_t * setup,uint8_t ** buffer,uint32_t * length)794 static usb_status_t USB_DeviceCh9SetInterface(usb_device_common_class_struct_t *classHandle,
795                                               usb_setup_struct_t *setup,
796                                               uint8_t **buffer,
797                                               uint32_t *length)
798 {
799     uint8_t state = 0U;
800 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
801     usb_status_t error = kStatus_USB_InvalidRequest;
802 #endif
803 
804     if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) != USB_REQUEST_TYPE_DIR_OUT) ||
805         ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) != USB_REQUEST_TYPE_RECIPIENT_INTERFACE) ||
806         (setup->wLength != 0U))
807     {
808         return kStatus_USB_InvalidRequest;
809     }
810 
811 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
812     if (kStatus_USB_Success != USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
813     {
814         return kStatus_USB_Error;
815     }
816 #else
817     (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
818 #endif
819 
820     if (state != (uint8_t)kUSB_DeviceStateConfigured)
821     {
822         return kStatus_USB_InvalidRequest;
823     }
824     classHandle->standardTranscationBuffer = ((setup->wIndex & 0xFFU) << 8U) | (setup->wValue & 0xFFU);
825     /* Notify the class driver the alternate setting of the interface is changed. */
826     /* The Bit[15~8] is used to save the interface index, and the alternate setting is saved in Bit[7~0]. */
827 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
828     error = USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventSetInterface,
829                                  &classHandle->standardTranscationBuffer);
830     if (kStatus_USB_Success != error)
831     {
832         return error;
833     }
834 #else
835     (void)USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventSetInterface,
836                                &classHandle->standardTranscationBuffer);
837 #endif
838     /* Notify the application the alternate setting of the interface is changed. */
839     /* The Bit[15~8] is used to save the interface index, and the alternate setting will is saved in Bit[7~0]. */
840     return USB_DeviceClassCallback(classHandle->handle, (uint32_t)kUSB_DeviceEventSetInterface,
841                                    &classHandle->standardTranscationBuffer);
842 }
843 
844 /*!
845  * @brief Handle get sync frame request.
846  *
847  * This function is used to handle get sync frame request.
848  *
849  * @param handle          The device handle. It equals the value returned from USB_DeviceInit.
850  * @param setup           The pointer of the setup packet.
851  * @param buffer          It is an out parameter, is used to save the buffer address to response the host's request.
852  * @param length          It is an out parameter, the data length.
853  *
854  * @retval kStatus_USB_Success              The request is handled successfully.
855  * @retval kStatus_USB_InvalidRequest       The request can not be handle in current device state,
856  *                                          or, the request is unsupported.
857  */
USB_DeviceCh9SynchFrame(usb_device_common_class_struct_t * classHandle,usb_setup_struct_t * setup,uint8_t ** buffer,uint32_t * length)858 static usb_status_t USB_DeviceCh9SynchFrame(usb_device_common_class_struct_t *classHandle,
859                                             usb_setup_struct_t *setup,
860                                             uint8_t **buffer,
861                                             uint32_t *length)
862 {
863     usb_status_t error = kStatus_USB_InvalidRequest;
864     uint8_t state      = 0U;
865 
866     if (((setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) != USB_REQUEST_TYPE_DIR_IN) ||
867         ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) != USB_REQUEST_TYPE_RECIPIENT_ENDPOINT) ||
868         (setup->wValue != 0U) || (setup->wLength != 2U))
869     {
870         return error;
871     }
872 
873 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
874     if (kStatus_USB_Success != USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state))
875     {
876         return kStatus_USB_Error;
877     }
878 #else
879     (void)USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state);
880 #endif
881 
882     if (state != (uint8_t)kUSB_DeviceStateConfigured)
883     {
884         return error;
885     }
886     /* Synch frame is not implemented by any MS devices. Expected response from device will be STALL until a device
887        exists that supports this command. At that time this script will need to be updated to support a
888        response other than STALL */
889 #if (defined(USB_DEVICE_CONFIG_ROOT2_TEST) && (USB_DEVICE_CONFIG_ROOT2_TEST > 0U))
890     return error;
891 #else
892     classHandle->standardTranscationBuffer = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wIndex);
893     /* Get the sync frame value */
894     error =
895         USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusSynchFrame, &classHandle->standardTranscationBuffer);
896     *buffer = (uint8_t *)&classHandle->standardTranscationBuffer;
897     *length = sizeof(classHandle->standardTranscationBuffer);
898     return error;
899 #endif
900 }
901 
902 /*!
903  * @brief Send the response to the host.
904  *
905  * This function is used to send the response to the host.
906  *
907  * There are two cases this function will be called.
908  * Case one when a setup packet is received in control endpoint callback function:
909  *        1. If there is not data phase in the setup transfer, the function will prime an IN transfer with the data
910  * length is zero for status phase.
911  *        2. If there is an IN data phase, the function will prime an OUT transfer with the actual length to need to
912  * send for data phase. And then prime an IN transfer with the data length is zero for status phase.
913  *        3. If there is an OUT data phase, the function will prime an IN transfer with the actual length to want to
914  * receive for data phase.
915  *
916  * Case two when is not a setup packet received in control endpoint callback function:
917  *        1. The function will prime an IN transfer with data length is zero for status phase.
918  *
919  * @param handle          The device handle. It equals the value returned from USB_DeviceInit.
920  * @param setup           The pointer of the setup packet.
921  * @param error           The error code returned from the standard request function.
922  * @param stage           The stage of the control transfer.
923  * @param buffer          It is an out parameter, is used to save the buffer address to response the host's request.
924  * @param length          It is an out parameter, the data length.
925  *
926  * @return A USB error code or kStatus_USB_Success.
927  */
USB_DeviceControlCallbackFeedback(usb_device_handle handle,usb_setup_struct_t * setup,usb_status_t error,usb_device_control_read_write_sequence_t stage,uint8_t ** buffer,uint32_t * length)928 static usb_status_t USB_DeviceControlCallbackFeedback(usb_device_handle handle,
929                                                       usb_setup_struct_t *setup,
930                                                       usb_status_t error,
931                                                       usb_device_control_read_write_sequence_t stage,
932                                                       uint8_t **buffer,
933                                                       uint32_t *length)
934 {
935     usb_status_t status;
936 
937     if (kStatus_USB_InvalidRequest == error)
938     {
939         /* Stall the control pipe when the request is unsupported. */
940         status = USB_DeviceStallEndpoint(handle, (uint8_t)USB_CONTROL_ENDPOINT);
941     }
942     else
943     {
944         if (*length > setup->wLength)
945         {
946             *length = setup->wLength;
947         }
948 
949         if (kStatus_USB_Success == error)
950         {
951             status = USB_DeviceSendRequest(handle, (USB_CONTROL_ENDPOINT), *buffer, *length);
952         }
953         else
954         {
955             status = USB_DeviceSendRequest(handle, (USB_CONTROL_ENDPOINT), (uint8_t *)NULL, 0U);
956         }
957 
958         if ((kStatus_USB_Success == status) &&
959             (USB_REQUEST_TYPE_DIR_IN == (setup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK)))
960         {
961             status = USB_DeviceRecvRequest(handle, (USB_CONTROL_ENDPOINT), (uint8_t *)NULL, 0U);
962         }
963     }
964 
965     return status;
966 }
967 
968 /*!
969  * @brief Control endpoint callback function.
970  *
971  * This callback function is used to notify uplayer the transfser result of a transfer.
972  * This callback pointer is passed when a specified endpoint initialized by calling API USB_DeviceInitEndpoint.
973  *
974  * @param handle          The device handle. It equals the value returned from USB_DeviceInit.
975  * @param message         The result of a transfer, includes transfer buffer, transfer length and whether is in setup
976  * phase for control pipe.
977  * @param callbackParam  The parameter for this callback. It is same with
978  * usb_device_endpoint_callback_struct_t::callbackParam.
979  *
980  * @return A USB error code or kStatus_USB_Success.
981  */
USB_DeviceControlCallback(usb_device_handle handle,usb_device_endpoint_callback_message_struct_t * message,void * callbackParam)982 static usb_status_t USB_DeviceControlCallback(usb_device_handle handle,
983                                               usb_device_endpoint_callback_message_struct_t *message,
984                                               void *callbackParam)
985 {
986     usb_setup_struct_t *deviceSetup, *setup;
987     usb_device_common_class_struct_t *classHandle;
988     uint8_t *buffer = (uint8_t *)NULL;
989     uint32_t length = 0U;
990     void *temp;
991     usb_status_t status = kStatus_USB_InvalidRequest;
992     uint8_t state       = 0U;
993 
994     /* endpoint callback length is USB_CANCELLED_TRANSFER_LENGTH (0xFFFFFFFFU) when transfer is canceled */
995     if (USB_CANCELLED_TRANSFER_LENGTH == message->length)
996     {
997         return kStatus_USB_Success;
998     }
999 
1000     if (NULL == callbackParam)
1001     {
1002         return status;
1003     }
1004 
1005     classHandle = (usb_device_common_class_struct_t *)callbackParam;
1006     temp        = (void *)&classHandle->setupBuffer[0];
1007     deviceSetup = (usb_setup_struct_t *)temp;
1008 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1009     if (kStatus_USB_Success != USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state))
1010     {
1011         return kStatus_USB_Error;
1012     }
1013 #else
1014     (void)USB_DeviceGetStatus(handle, kUSB_DeviceStatusDeviceState, &state);
1015 #endif
1016 
1017     if (0U != message->isSetup)
1018     {
1019         if ((USB_SETUP_PACKET_SIZE != message->length) || (NULL == message->buffer))
1020         {
1021             /* If a invalid setup is received, the control pipes should be de-init and init again.
1022              * Due to the IP can not meet this require, it is reserved for feature.
1023              */
1024             /*
1025             USB_DeviceDeinitEndpoint(handle,
1026                          USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT));
1027             USB_DeviceDeinitEndpoint(handle,
1028                          USB_CONTROL_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT));
1029             USB_DeviceControlPipeInit(handle, callbackParam);
1030             */
1031             return status;
1032         }
1033         /* Receive a setup request */
1034         temp  = (void *)(message->buffer);
1035         setup = (usb_setup_struct_t *)temp;
1036 
1037         /* Copy the setup packet to the application buffer */
1038         deviceSetup->wValue        = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wValue);
1039         deviceSetup->wIndex        = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wIndex);
1040         deviceSetup->wLength       = USB_SHORT_FROM_LITTLE_ENDIAN(setup->wLength);
1041         deviceSetup->bRequest      = setup->bRequest;
1042         deviceSetup->bmRequestType = setup->bmRequestType;
1043 
1044         /* Check the invalid value */
1045         if ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) > USB_REQUEST_TYPE_RECIPIENT_OTHER)
1046         {
1047 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1048             status = USB_DeviceControlCallbackFeedback(handle, deviceSetup, kStatus_USB_InvalidRequest,
1049                                                        kUSB_DeviceControlPipeSetupStage, NULL, NULL);
1050             return kStatus_USB_InvalidRequest;
1051 #else
1052             (void)USB_DeviceControlCallbackFeedback(handle, deviceSetup, kStatus_USB_InvalidRequest,
1053                                                     kUSB_DeviceControlPipeSetupStage, NULL, NULL);
1054             return status;
1055 #endif
1056         }
1057 
1058         if ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_STANDARD)
1059         {
1060             /* Handle the standard request, only handle the request in request array. */
1061             if (deviceSetup->bRequest <
1062                 ((sizeof(s_UsbDeviceStandardRequest)) / (sizeof(usb_standard_request_callback_t))))
1063             {
1064                 if (s_UsbDeviceStandardRequest[deviceSetup->bRequest] != (usb_standard_request_callback_t)NULL)
1065                 {
1066                     status =
1067                         s_UsbDeviceStandardRequest[deviceSetup->bRequest](classHandle, deviceSetup, &buffer, &length);
1068                 }
1069             }
1070         }
1071         else
1072         {
1073             if ((0U != deviceSetup->wLength) &&
1074                 ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_OUT))
1075             {
1076                 /* Class or vendor request with the OUT data phase. */
1077                 if ((0U != deviceSetup->wLength) &&
1078                     ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_CLASS))
1079                 {
1080                     /* Get data buffer to receive the data from the host. */
1081                     usb_device_control_request_struct_t controlRequest;
1082                     controlRequest.buffer  = (uint8_t *)NULL;
1083                     controlRequest.isSetup = 1U;
1084                     controlRequest.setup   = deviceSetup;
1085                     controlRequest.length  = deviceSetup->wLength;
1086                     status = USB_DeviceClassEvent(handle, kUSB_DeviceClassEventClassRequest, &controlRequest);
1087                     length = controlRequest.length;
1088                     buffer = controlRequest.buffer;
1089                 }
1090                 else if ((0U != deviceSetup->wLength) &&
1091                          ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_VENDOR))
1092                 {
1093                     /* Get data buffer to receive the data from the host. */
1094                     usb_device_control_request_struct_t controlRequest;
1095                     controlRequest.buffer  = (uint8_t *)NULL;
1096                     controlRequest.isSetup = 1U;
1097                     controlRequest.setup   = deviceSetup;
1098                     controlRequest.length  = deviceSetup->wLength;
1099                     status = USB_DeviceClassCallback(handle, (uint32_t)kUSB_DeviceEventVendorRequest, &controlRequest);
1100                     length = controlRequest.length;
1101                     buffer = controlRequest.buffer;
1102                 }
1103                 else
1104                 {
1105                     /*no action*/
1106                 }
1107                 if (kStatus_USB_Success == status)
1108                 {
1109                     /* Prime an OUT transfer */
1110                     if (length > deviceSetup->wLength)
1111                     {
1112                         length = deviceSetup->wLength;
1113                     }
1114                     status = USB_DeviceRecvRequest(handle, USB_CONTROL_ENDPOINT, buffer, length);
1115                     return status;
1116                 }
1117                 else
1118                 {
1119                     /* Other error codes, will stall control endpoint */
1120                     status = kStatus_USB_InvalidRequest;
1121                 }
1122             }
1123             else
1124             {
1125                 /* Class or vendor request with the IN data phase. */
1126                 if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_CLASS))
1127                 {
1128                     /* Get data buffer to response the host. */
1129                     usb_device_control_request_struct_t controlRequest;
1130                     controlRequest.buffer  = (uint8_t *)NULL;
1131                     controlRequest.isSetup = 1U;
1132                     controlRequest.setup   = deviceSetup;
1133                     controlRequest.length  = deviceSetup->wLength;
1134                     status = USB_DeviceClassEvent(handle, kUSB_DeviceClassEventClassRequest, &controlRequest);
1135                     length = controlRequest.length;
1136                     buffer = controlRequest.buffer;
1137                 }
1138                 else if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_VENDOR))
1139                 {
1140                     /* Get data buffer to response the host. */
1141                     usb_device_control_request_struct_t controlRequest;
1142                     controlRequest.buffer  = (uint8_t *)NULL;
1143                     controlRequest.isSetup = 1U;
1144                     controlRequest.setup   = deviceSetup;
1145                     controlRequest.length  = deviceSetup->wLength;
1146                     status = USB_DeviceClassCallback(handle, (uint32_t)kUSB_DeviceEventVendorRequest, &controlRequest);
1147                     length = controlRequest.length;
1148                     buffer = controlRequest.buffer;
1149                 }
1150                 else
1151                 {
1152                     /*no action*/
1153                 }
1154             }
1155         }
1156         /* Buffer that is equal to NULL means the application or classs driver does not prepare a buffer for
1157            sending or receiving the data, so control endpoint will be stalled here. */
1158         if ((0U != length) && (NULL == buffer))
1159         {
1160             status = kStatus_USB_InvalidRequest;
1161         }
1162         /* Send the response to the host. */
1163         status = USB_DeviceControlCallbackFeedback(handle, deviceSetup, status, kUSB_DeviceControlPipeSetupStage,
1164                                                    &buffer, &length);
1165     }
1166     else if ((uint8_t)kUSB_DeviceStateAddressing == state)
1167     {
1168         if (USB_REQUEST_STANDARD_SET_ADDRESS == deviceSetup->bRequest)
1169         {
1170             /* Set the device address to controller. */
1171             status = s_UsbDeviceStandardRequest[deviceSetup->bRequest](classHandle, deviceSetup, &buffer, &length);
1172         }
1173     }
1174 #if ((defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) ||                \
1175      (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))) && \
1176     (defined(USB_DEVICE_CONFIG_USB20_TEST_MODE) && (USB_DEVICE_CONFIG_USB20_TEST_MODE > 0U))
1177     else if ((uint8_t)kUSB_DeviceStateTestMode == state)
1178     {
1179         uint8_t portTestControl = (uint8_t)(deviceSetup->wIndex >> 8);
1180         /* Set the controller.into test mode. */
1181         status = USB_DeviceSetStatus(handle, kUSB_DeviceStatusTestMode, &portTestControl);
1182     }
1183 #endif
1184     else if ((0U != message->length) && (0U != deviceSetup->wLength) &&
1185              ((deviceSetup->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_OUT))
1186     {
1187         if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_CLASS))
1188         {
1189             /* Data received in OUT phase, and notify the class driver. */
1190             usb_device_control_request_struct_t controlRequest;
1191             controlRequest.buffer  = message->buffer;
1192             controlRequest.isSetup = 0U;
1193             controlRequest.setup   = deviceSetup;
1194             controlRequest.length  = message->length;
1195             status                 = USB_DeviceClassEvent(handle, kUSB_DeviceClassEventClassRequest, &controlRequest);
1196         }
1197         else if (((deviceSetup->bmRequestType & USB_REQUEST_TYPE_TYPE_MASK) == USB_REQUEST_TYPE_TYPE_VENDOR))
1198         {
1199             /* Data received in OUT phase, and notify the application. */
1200             usb_device_control_request_struct_t controlRequest;
1201             controlRequest.buffer  = message->buffer;
1202             controlRequest.isSetup = 0U;
1203             controlRequest.setup   = deviceSetup;
1204             controlRequest.length  = message->length;
1205             status = USB_DeviceClassCallback(handle, (uint32_t)kUSB_DeviceEventVendorRequest, &controlRequest);
1206         }
1207         else
1208         {
1209             /*no action*/
1210         }
1211         /* Send the response to the host. */
1212         status = USB_DeviceControlCallbackFeedback(handle, deviceSetup, status, kUSB_DeviceControlPipeDataStage,
1213                                                    &buffer, &length);
1214     }
1215     else
1216     {
1217         /*no action*/
1218     }
1219     return status;
1220 }
1221 
1222 /*!
1223  * @brief Control endpoint initialization function.
1224  *
1225  * This callback function is used to initialize the control pipes.
1226  *
1227  * @param handle          The device handle. It equals the value returned from USB_DeviceInit.
1228  * @param param           The up layer handle.
1229  *
1230  * @return A USB error code or kStatus_USB_Success.
1231  */
USB_DeviceControlPipeInit(usb_device_handle handle,void * param)1232 usb_status_t USB_DeviceControlPipeInit(usb_device_handle handle, void *param)
1233 {
1234     usb_device_endpoint_init_struct_t epInitStruct;
1235     usb_device_endpoint_callback_struct_t epCallback;
1236     usb_status_t status;
1237 
1238     epCallback.callbackFn    = USB_DeviceControlCallback;
1239     epCallback.callbackParam = param;
1240 
1241     epInitStruct.zlt             = 1U;
1242     epInitStruct.transferType    = USB_ENDPOINT_CONTROL;
1243     epInitStruct.interval        = 0;
1244     epInitStruct.endpointAddress = USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
1245     epInitStruct.maxPacketSize   = USB_CONTROL_MAX_PACKET_SIZE;
1246     /* Initialize the control IN pipe */
1247     status = USB_DeviceInitEndpoint(handle, &epInitStruct, &epCallback);
1248 
1249     if (kStatus_USB_Success != status)
1250     {
1251         return status;
1252     }
1253     epInitStruct.endpointAddress = USB_CONTROL_ENDPOINT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT);
1254     /* Initialize the control OUT pipe */
1255     status = USB_DeviceInitEndpoint(handle, &epInitStruct, &epCallback);
1256 
1257     if (kStatus_USB_Success != status)
1258     {
1259 #if (defined(USB_DEVICE_CONFIG_RETURN_VALUE_CHECK) && (USB_DEVICE_CONFIG_RETURN_VALUE_CHECK > 0U))
1260         if (kStatus_USB_Success !=
1261             USB_DeviceDeinitEndpoint(
1262                 handle, USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT)))
1263         {
1264             return kStatus_USB_Error;
1265         }
1266 #else
1267         (void)USB_DeviceDeinitEndpoint(
1268             handle, USB_CONTROL_ENDPOINT | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT));
1269 #endif
1270         return status;
1271     }
1272 
1273     return kStatus_USB_Success;
1274 }
1275 #endif /* USB_DEVICE_CONFIG_NUM */
1276