1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** USBX Component                                                        */
16 /**                                                                       */
17 /**   Video Class                                                         */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 
23 /* Include necessary system files.  */
24 
25 #define UX_SOURCE_CODE
26 
27 #include "ux_api.h"
28 #include "ux_host_class_video.h"
29 #include "ux_host_stack.h"
30 
31 
32 /**************************************************************************/
33 /*                                                                        */
34 /*  FUNCTION                                               RELEASE        */
35 /*                                                                        */
36 /*    _ux_host_class_video_input_format_get               PORTABLE C      */
37 /*                                                           6.1          */
38 /*  AUTHOR                                                                */
39 /*                                                                        */
40 /*    Chaoqiong Xiao, Microsoft Corporation                               */
41 /*                                                                        */
42 /*  DESCRIPTION                                                           */
43 /*                                                                        */
44 /*    This function finds the input format(s) for the input terminal.     */
45 /*                                                                        */
46 /*  INPUT                                                                 */
47 /*                                                                        */
48 /*    video                                 Pointer to video class        */
49 /*                                                                        */
50 /*  OUTPUT                                                                */
51 /*                                                                        */
52 /*    Completion Status                                                   */
53 /*                                                                        */
54 /*  CALLS                                                                 */
55 /*                                                                        */
56 /*    _ux_utility_descriptor_parse          Parse descriptor              */
57 /*    _ux_system_error_handler              Log system error              */
58 /*                                                                        */
59 /*  CALLED BY                                                             */
60 /*                                                                        */
61 /*    Video Class                                                         */
62 /*                                                                        */
63 /*  RELEASE HISTORY                                                       */
64 /*                                                                        */
65 /*    DATE              NAME                      DESCRIPTION             */
66 /*                                                                        */
67 /*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
68 /*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
69 /*                                            resulting in version 6.1    */
70 /*                                                                        */
71 /**************************************************************************/
_ux_host_class_video_input_format_get(UX_HOST_CLASS_VIDEO * video)72 UINT  _ux_host_class_video_input_format_get(UX_HOST_CLASS_VIDEO *video)
73 {
74 
75 UCHAR                                           *descriptor;
76 UX_INTERFACE_DESCRIPTOR                         interface_descriptor;
77 UX_HOST_CLASS_VIDEO_INPUT_HEADER_DESCRIPTOR     input_header_descriptor;
78 ULONG                                           total_descriptor_length;
79 ULONG                                           descriptor_length;
80 ULONG                                           descriptor_type;
81 ULONG                                           descriptor_subtype;
82 ULONG                                           descriptor_found;
83 
84 
85     /* Get the descriptor to the entire configuration.  */
86     descriptor =               video -> ux_host_class_video_configuration_descriptor;
87     total_descriptor_length =  video -> ux_host_class_video_configuration_descriptor_length;
88 
89     /* Default is Interface descriptor not yet found.  */
90     descriptor_found =  UX_FALSE;
91 
92     /* Scan the descriptor for the Video Streaming interface.  */
93     while (total_descriptor_length)
94     {
95 
96         /* Gather the length, type and subtype of the descriptor.  */
97         descriptor_length =   *descriptor;
98         descriptor_type =     *(descriptor + 1);
99         descriptor_subtype =  *(descriptor + 2);
100 
101         /* Make sure this descriptor has at least the minimum length.  */
102         if (descriptor_length < 3)
103         {
104 
105             /* Error trap. */
106             _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED);
107 
108             /* If trace is enabled, insert this event into the trace buffer.  */
109             //UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
110 
111             return(UX_DESCRIPTOR_CORRUPTED);
112         }
113 
114         /* Process relative to the descriptor type.  */
115         switch (descriptor_type)
116         {
117 
118 
119         case UX_INTERFACE_DESCRIPTOR_ITEM:
120 
121             /* Parse the interface descriptor and make it machine independent.  */
122             _ux_utility_descriptor_parse(descriptor, _ux_system_interface_descriptor_structure,
123                                             UX_INTERFACE_DESCRIPTOR_ENTRIES, (UCHAR *) &interface_descriptor);
124 
125             /* Ensure we have the correct interface for Video Streaming.  */
126             if ((interface_descriptor.bInterfaceClass == UX_HOST_CLASS_VIDEO_CLASS) &&
127                 (interface_descriptor.bInterfaceSubClass == UX_HOST_CLASS_VIDEO_SUBCLASS_STREAMING))
128             {
129 
130                 /* Mark we have found it.  */
131                 descriptor_found =  UX_TRUE;
132             }
133             else
134             {
135 
136                 descriptor_found =  UX_FALSE;
137             }
138             break;
139 
140 
141         case UX_HOST_CLASS_VIDEO_CS_INTERFACE:
142 
143             /* First make sure we have found the correct generic interface descriptor.  */
144             if (descriptor_found == UX_TRUE)
145             {
146 
147                 /* Check the sub type.  */
148                 switch (descriptor_subtype)
149                 {
150 
151 
152                 case UX_HOST_CLASS_VIDEO_VS_INPUT_HEADER:
153 
154                     /* Make the descriptor machine independent.  */
155                     _ux_utility_descriptor_parse(descriptor, _ux_system_class_video_input_header_descriptor_structure,
156                                                  UX_HOST_CLASS_VIDEO_INPUT_HEADER_DESCRIPTOR_ENTRIES, (UCHAR *) &input_header_descriptor);
157 
158                     /* Get the number of formats.  */
159                     video -> ux_host_class_video_number_formats = input_header_descriptor.bNumFormats;
160 
161                     /* Get the length of formats.  */
162                     video -> ux_host_class_video_length_formats = input_header_descriptor.wTotalLength;
163 
164                     /* Save the descriptor where the formats reside.  */
165                     video -> ux_host_class_video_format_address = descriptor;
166 
167                     /* We are done here.  */
168                     return(UX_SUCCESS);
169 
170                 }
171             }
172             break;
173         }
174 
175         /* Verify if the descriptor is still valid.  */
176         if (descriptor_length > total_descriptor_length)
177         {
178 
179             /* Error trap. */
180             _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED);
181 
182             /* If trace is enabled, insert this event into the trace buffer.  */
183             //UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
184 
185             return(UX_DESCRIPTOR_CORRUPTED);
186         }
187 
188         /* Jump to the next descriptor if we have not reached the end.  */
189         descriptor +=  descriptor_length;
190 
191         /* And adjust the length left to parse in the descriptor.  */
192         total_descriptor_length -=  descriptor_length;
193     }
194 
195     /* Error trap. */
196     _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_VIDEO_WRONG_TYPE);
197 
198     /* We get here when either the report descriptor has a problem or we could
199        not find the right video device.  */
200     return(UX_HOST_CLASS_VIDEO_WRONG_TYPE);
201 }
202 
203