GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: core/src/ux_host_stack_interfaces_scan.c Lines: 36 36 100.0 %
Date: 2026-03-06 18:57:10 Branches: 18 18 100.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026-present Eclipse ThreadX contributors
4
 *
5
 * This program and the accompanying materials are made available under the
6
 * terms of the MIT License which is available at
7
 * https://opensource.org/licenses/MIT.
8
 *
9
 * SPDX-License-Identifier: MIT
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
/**************************************************************************/
68
1055
UINT  _ux_host_stack_interfaces_scan(UX_CONFIGURATION *configuration, UCHAR * descriptor)
69
{
70
71
ULONG                               total_configuration_length;
72
UINT                                descriptor_length;
73
UINT                                descriptor_type;
74
ULONG                               status;
75
ULONG                               interface_association_descriptor_present;
76
ULONG                               interface_in_iad_count;
77
UX_INTERFACE_ASSOCIATION_DESCRIPTOR interface_association;
78
79
    /* Retrieve the size of all the configuration descriptor.  */
80
1055
    total_configuration_length =  configuration -> ux_configuration_descriptor.wTotalLength;
81
82
    /* Set the IAD to false.  */
83
1055
    interface_association_descriptor_present = UX_FALSE;
84
85
    /* Set the IAD interface count to zero.  */
86
1055
    interface_in_iad_count = 0;
87
88
    /* Scan the entire descriptor and search for interfaces. We should also ensure that
89
       the descriptor is valid by verifying the length of each descriptor scanned.  */
90
8481
    while (total_configuration_length)
91
    {
92
93
        /* Gather the length and type of the descriptor.  */
94
7550
        descriptor_length =  *descriptor;
95
7550
        descriptor_type =    *(descriptor + 1);
96
97
        /* Make sure this descriptor has at least the minimum length.  */
98
7550
        if (descriptor_length < 3)
99
        {
100
101
            /* Error trap. */
102
1
            _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_DESCRIPTOR_CORRUPTED);
103
104
            /* If trace is enabled, insert this event into the trace buffer.  */
105
            UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
106
107
1
            return(UX_DESCRIPTOR_CORRUPTED);
108
        }
109
110
        /* Check the type for an interface association descriptor.  */
111
7549
        if (descriptor_type == UX_INTERFACE_ASSOCIATION_DESCRIPTOR_ITEM)
112
        {
113
114
            /* Parse the interface association descriptor and make it machine independent.  */
115
253
            _ux_utility_descriptor_parse(descriptor,
116
                            _ux_system_interface_association_descriptor_structure,
117
                            UX_INTERFACE_ASSOCIATION_DESCRIPTOR_ENTRIES,
118
                            (UCHAR *) &interface_association);
119
120
            /* Retrieve the CLASS/SUBCLASS from descriptor and store it in the configuration instance.  */
121
253
            configuration -> ux_configuration_iad_class    = interface_association.bFunctionClass;
122
253
            configuration -> ux_configuration_iad_subclass = interface_association.bFunctionSubClass;
123
253
            configuration -> ux_configuration_iad_protocol = interface_association.bFunctionProtocol;
124
125
            /* We have an IAD.  */
126
253
            interface_association_descriptor_present = UX_TRUE;
127
128
            /* Memorize the number of interfaces attached to this IAD.  */
129
253
            interface_in_iad_count = interface_association.bInterfaceCount;
130
        }
131
132
        /* Check the type for an interface descriptor.  */
133
7549
        if (descriptor_type == UX_INTERFACE_DESCRIPTOR_ITEM)
134
        {
135
136
            /* We have found an interface descriptor. This descriptor contains at least
137
               the default alternate setting (with value 0) and may have others.  */
138
1973
            status =  _ux_host_stack_new_interface_create(configuration, descriptor, total_configuration_length);
139
140
            /* Are we within an IAD ? */
141
1973
            if (interface_association_descriptor_present == UX_TRUE)
142
            {
143
144
                /* Decrement the number of interfaces attached here.  */
145
504
                interface_in_iad_count--;
146
147
                /* Are we at the end of the interface count ? */
148
504
                if (interface_in_iad_count == 0)
149
                {
150
151
                    /* Set the IAD to false now.  */
152
242
                    interface_association_descriptor_present = UX_FALSE;
153
154
                    /* Reset the IAD Class/Subclass/Protocol. */
155
242
                    configuration -> ux_configuration_iad_class    = 0;
156
242
                    configuration -> ux_configuration_iad_subclass = 0;
157
242
                    configuration -> ux_configuration_iad_protocol = 0;
158
159
                }
160
            }
161
162
            /* Check return status.  */
163
1973
            if(status != UX_SUCCESS)
164
121
                return(status);
165
        }
166
167
        /* Check the type for an OTG descriptor.  */
168
7428
        if (descriptor_type == UX_OTG_DESCRIPTOR_ITEM)
169
170
            /* Retrieve the bmAttributes for SRP/HNP support.  */
171
7
            configuration -> ux_configuration_otg_capabilities = (ULONG) *(descriptor + UX_OTG_BM_ATTRIBUTES);
172
173
        /* Verify if the descriptor is still valid.  */
174
7428
        if (descriptor_length > total_configuration_length)
175
        {
176
177
            /* Error trap. */
178
2
            _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_DESCRIPTOR_CORRUPTED);
179
180
            /* If trace is enabled, insert this event into the trace buffer.  */
181
            UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, descriptor, 0, 0, UX_TRACE_ERRORS, 0, 0)
182
183
2
            return(UX_DESCRIPTOR_CORRUPTED);
184
        }
185
        /* Jump to the next descriptor if we have not reached the end.  */
186
7426
        descriptor +=  descriptor_length;
187
188
        /* And adjust the length left to parse in the descriptor.  */
189
7426
        total_configuration_length -=  descriptor_length;
190
    }
191
192
    /* Return successful completion.  */
193
931
    return(UX_SUCCESS);
194
}
195