GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: core/src/ux_host_stack_interfaces_scan.c Lines: 36 36 100.0 %
Date: 2024-12-12 17:16:36 Branches: 18 18 100.0 %

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