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 /** Host Stack */
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_stack.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_host_stack_interfaces_scan PORTABLE C */
37 /* 6.1 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function scans all the interfaces and alternate settings for */
45 /* particular configuration. */
46 /* */
47 /* INPUT */
48 /* */
49 /* configuration Where the interface(s) will */
50 /* be attached */
51 /* descriptor Contains the entire descriptor*/
52 /* for this configuration */
53 /* */
54 /* OUTPUT */
55 /* */
56 /* None */
57 /* */
58 /* CALLS */
59 /* */
60 /* _ux_utility_descriptor_parse Parse interface descriptor */
61 /* _ux_host_stack_new_interface_create Create new interface */
62 /* */
63 /* CALLED BY */
64 /* */
65 /* USBX Components */
66 /* */
67 /* RELEASE HISTORY */
68 /* */
69 /* DATE NAME DESCRIPTION */
70 /* */
71 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
72 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
73 /* resulting in version 6.1 */
74 /* */
75 /**************************************************************************/
_ux_host_stack_interfaces_scan(UX_CONFIGURATION * configuration,UCHAR * descriptor)76 UINT _ux_host_stack_interfaces_scan(UX_CONFIGURATION *configuration, UCHAR * descriptor)
77 {
78
79 ULONG total_configuration_length;
80 UINT descriptor_length;
81 UINT descriptor_type;
82 ULONG status;
83 ULONG interface_association_descriptor_present;
84 ULONG interface_in_iad_count;
85 UX_INTERFACE_ASSOCIATION_DESCRIPTOR interface_association;
86
87 /* Retrieve the size of all the configuration descriptor. */
88 total_configuration_length = configuration -> ux_configuration_descriptor.wTotalLength;
89
90 /* Set the IAD to false. */
91 interface_association_descriptor_present = UX_FALSE;
92
93 /* Set the IAD interface count to zero. */
94 interface_in_iad_count = 0;
95
96 /* Scan the entire descriptor and search for interfaces. We should also ensure that
97 the descriptor is valid by verifying the length of each descriptor scanned. */
98 while (total_configuration_length)
99 {
100
101 /* Gather the length and type of the descriptor. */
102 descriptor_length = *descriptor;
103 descriptor_type = *(descriptor + 1);
104
105 /* Make sure this descriptor has at least the minimum length. */
106 if (descriptor_length < 3)
107 {
108
109 /* Error trap. */
110 _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_DESCRIPTOR_CORRUPTED);
111
112 /* If trace is enabled, insert this event into the trace buffer. */
113 UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
114
115 return(UX_DESCRIPTOR_CORRUPTED);
116 }
117
118 /* Check the type for an interface association descriptor. */
119 if (descriptor_type == UX_INTERFACE_ASSOCIATION_DESCRIPTOR_ITEM)
120 {
121
122 /* Parse the interface association descriptor and make it machine independent. */
123 _ux_utility_descriptor_parse(descriptor,
124 _ux_system_interface_association_descriptor_structure,
125 UX_INTERFACE_ASSOCIATION_DESCRIPTOR_ENTRIES,
126 (UCHAR *) &interface_association);
127
128 /* Retrieve the CLASS/SUBCLASS from descriptor and store it in the configuration instance. */
129 configuration -> ux_configuration_iad_class = interface_association.bFunctionClass;
130 configuration -> ux_configuration_iad_subclass = interface_association.bFunctionSubClass;
131 configuration -> ux_configuration_iad_protocol = interface_association.bFunctionProtocol;
132
133 /* We have an IAD. */
134 interface_association_descriptor_present = UX_TRUE;
135
136 /* Memorize the number of interfaces attached to this IAD. */
137 interface_in_iad_count = interface_association.bInterfaceCount;
138 }
139
140 /* Check the type for an interface descriptor. */
141 if (descriptor_type == UX_INTERFACE_DESCRIPTOR_ITEM)
142 {
143
144 /* We have found an interface descriptor. This descriptor contains at least
145 the default alternate setting (with value 0) and may have others. */
146 status = _ux_host_stack_new_interface_create(configuration, descriptor, total_configuration_length);
147
148 /* Are we within an IAD ? */
149 if (interface_association_descriptor_present == UX_TRUE)
150 {
151
152 /* Decrement the number of interfaces attached here. */
153 interface_in_iad_count--;
154
155 /* Are we at the end of the interface count ? */
156 if (interface_in_iad_count == 0)
157 {
158
159 /* Set the IAD to false now. */
160 interface_association_descriptor_present = UX_FALSE;
161
162 /* Reset the IAD Class/Subclass/Protocol. */
163 configuration -> ux_configuration_iad_class = 0;
164 configuration -> ux_configuration_iad_subclass = 0;
165 configuration -> ux_configuration_iad_protocol = 0;
166
167 }
168 }
169
170 /* Check return status. */
171 if(status != UX_SUCCESS)
172 return(status);
173 }
174
175 /* Check the type for an OTG descriptor. */
176 if (descriptor_type == UX_OTG_DESCRIPTOR_ITEM)
177
178 /* Retrieve the bmAttributes for SRP/HNP support. */
179 configuration -> ux_configuration_otg_capabilities = (ULONG) *(descriptor + UX_OTG_BM_ATTRIBUTES);
180
181 /* Verify if the descriptor is still valid. */
182 if (descriptor_length > total_configuration_length)
183 {
184
185 /* Error trap. */
186 _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_DESCRIPTOR_CORRUPTED);
187
188 /* If trace is enabled, insert this event into the trace buffer. */
189 UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
190
191 return(UX_DESCRIPTOR_CORRUPTED);
192 }
193 /* Jump to the next descriptor if we have not reached the end. */
194 descriptor += descriptor_length;
195
196 /* And adjust the length left to parse in the descriptor. */
197 total_configuration_length -= descriptor_length;
198 }
199
200 /* Return successful completion. */
201 return(UX_SUCCESS);
202 }
203
204