1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** USBX Component */
17 /** */
18 /** Video Class */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23
24 /* Include necessary system files. */
25
26 #define UX_SOURCE_CODE
27
28 #include "ux_api.h"
29 #include "ux_host_class_video.h"
30 #include "ux_host_stack.h"
31
32
33 /**************************************************************************/
34 /* */
35 /* FUNCTION RELEASE */
36 /* */
37 /* _ux_host_class_video_entities_parse PORTABLE C */
38 /* 6.1.12 */
39 /* AUTHOR */
40 /* */
41 /* Chaoqiong Xiao, Microsoft Corporation */
42 /* */
43 /* DESCRIPTION */
44 /* */
45 /* This function parsees all interface descriptors and their video */
46 /* class specific descriptors. */
47 /* */
48 /* The function scans the device configuration descriptor. Once the */
49 /* interface descriptors of the video instance are found, each video */
50 /* class descriptors belong to the interface are passed to parse */
51 /* function for caller one by one to parse. The interface descriptor */
52 /* is also passed to provide more information. Another pointer to */
53 /* arguments is also available as parse function parameter for caller */
54 /* to pass necessary caller specific data to process in parse function.*/
55 /* */
56 /* The descriptor parsing can be terminated by returning non-zero */
57 /* code in parse function. */
58 /* */
59 /* INPUT */
60 /* */
61 /* video Pointer to video instance */
62 /* parse_function Parse function for each */
63 /* video class descriptor */
64 /* arg Parse function argument */
65 /* */
66 /* OUTPUT */
67 /* */
68 /* Completion Status */
69 /* */
70 /* CALLS */
71 /* */
72 /* CALLED BY */
73 /* */
74 /* Video Class */
75 /* Application */
76 /* */
77 /* RELEASE HISTORY */
78 /* */
79 /* DATE NAME DESCRIPTION */
80 /* */
81 /* 09-30-2020 Chaoqiong Xiao Initial Version 6.1 */
82 /* 08-02-2021 Wen Wang Modified comment(s), */
83 /* fixed spelling error, */
84 /* resulting in version 6.1.8 */
85 /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
86 /* fixed parameter/variable */
87 /* names conflict C++ keyword, */
88 /* resulting in version 6.1.12 */
89 /* */
90 /**************************************************************************/
_ux_host_class_video_entities_parse(UX_HOST_CLASS_VIDEO * video,UINT (* parse_function)(VOID * arg,UCHAR * packed_interface_descriptor,UCHAR * packed_entity_descriptor),VOID * arg)91 UINT _ux_host_class_video_entities_parse(UX_HOST_CLASS_VIDEO *video,
92 UINT(*parse_function)(VOID *arg,
93 UCHAR *packed_interface_descriptor,
94 UCHAR *packed_entity_descriptor),
95 VOID* arg)
96 {
97
98 UCHAR *descriptor;
99 UCHAR *interface_descriptor;
100 UX_INTERFACE *interface_ptr;
101 ULONG total_descriptor_length;
102 ULONG descriptor_length;
103 ULONG descriptor_type;
104 UINT status;
105
106
107 /* Device state check. */
108 if (video -> ux_host_class_video_device -> ux_device_state != UX_DEVICE_CONFIGURED)
109 return(UX_HOST_CLASS_VIDEO_DEVICE_NOT_READY);
110
111 /* Get the descriptor to the selected format. */
112 descriptor = video -> ux_host_class_video_configuration_descriptor;
113 total_descriptor_length = video -> ux_host_class_video_configuration_descriptor_length;
114
115 /* Haven't found interface yet. */
116 interface_descriptor = UX_NULL;
117
118 /* Scan the descriptor for the Video Streaming interface. */
119 while (total_descriptor_length)
120 {
121
122 /* Gather the length, type and subtype of the descriptor. */
123 descriptor_length = *descriptor;
124 descriptor_type = *(descriptor + 1);
125
126 /* Make sure this descriptor has at least the minimum length. */
127 if (descriptor_length < 3)
128 return(UX_DESCRIPTOR_CORRUPTED);
129
130 /* Process relative to descriptor type. */
131 switch (descriptor_type)
132 {
133
134 case UX_INTERFACE_DESCRIPTOR_ITEM:
135
136 /* Haven't found it. */
137 interface_descriptor = UX_NULL;
138
139 /* Ensure we have the correct interface for Video Control/Streaming. */
140 if (descriptor[5] == UX_HOST_CLASS_VIDEO_CLASS)
141 {
142
143 /* VideoControl Interface. */
144 if (descriptor[6] == UX_HOST_CLASS_VIDEO_SUBCLASS_CONTROL)
145
146 /* Mark we have found it. */
147 interface_descriptor = descriptor;
148 else
149 {
150
151 /* VideoStreaming interface, currently only one supported. */
152 interface_ptr = video -> ux_host_class_video_streaming_interface;
153 if (descriptor[2] == interface_ptr -> ux_interface_descriptor.bInterfaceNumber)
154
155 /* Mark we have found it. */
156 interface_descriptor = descriptor;
157 }
158 }
159 break;
160
161 case UX_HOST_CLASS_VIDEO_CS_INTERFACE:
162
163 /* Have we found the video interface yet? */
164 if (interface_descriptor != UX_NULL)
165 {
166
167 /* Yes, parse the entity descriptor. */
168 status = parse_function(arg, interface_descriptor, descriptor);
169
170 /* Terminate the parsing if status is not 0. */
171 if (status)
172 return(UX_SUCCESS);
173 }
174 break;
175 }
176
177 /* Verify if the descriptor is still valid. */
178 if (descriptor_length > total_descriptor_length)
179 return(UX_DESCRIPTOR_CORRUPTED);
180
181 /* Jump to the next descriptor if we have not reached the end. */
182 descriptor += descriptor_length;
183
184 /* And adjust the length left to parse in the descriptor. */
185 total_descriptor_length -= descriptor_length;
186 }
187
188 /* We get here when all descriptors scanned. */
189 return(UX_SUCCESS);
190 }
191