GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: core/src/ux_host_stack_class_register.c Lines: 18 22 81.8 %
Date: 2026-03-06 18:57:10 Branches: 8 12 66.7 %

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_class_register                       PORTABLE C      */
37
/*                                                           6.1          */
38
/*  AUTHOR                                                                */
39
/*                                                                        */
40
/*    Chaoqiong Xiao, Microsoft Corporation                               */
41
/*                                                                        */
42
/*  DESCRIPTION                                                           */
43
/*                                                                        */
44
/*    This function registers a USB class to the USB stack. The Class     */
45
/*    must specify an entry point for the USB stack to send commands      */
46
/*    such as:                                                            */
47
/*                                                                        */
48
/*                  UX_HOST_CLASS_COMMAND_QUERY                           */
49
/*                  UX_HOST_CLASS_COMMAND_ACTIVATE                        */
50
/*                  UX_HOST_CLASS_COMMAND_DESTROY                         */
51
/*                                                                        */
52
/*    Note: The C string of class_name must be NULL-terminated and the    */
53
/*    length of it (without the NULL-terminator itself) must be no larger */
54
/*    than UX_MAX_CLASS_NAME_LENGTH.                                      */
55
/*                                                                        */
56
/*  INPUT                                                                 */
57
/*                                                                        */
58
/*    class_name                            Name of class                 */
59
/*    class_entry_function                  Entry function of the class   */
60
/*                                                                        */
61
/*  OUTPUT                                                                */
62
/*                                                                        */
63
/*    Completion Status                                                   */
64
/*                                                                        */
65
/*  CALLS                                                                 */
66
/*                                                                        */
67
/*    _ux_utility_string_length_check       Check C string and return     */
68
/*                                          length if null-terminated     */
69
/*    _ux_utility_memory_copy               Copy memory block             */
70
/*                                                                        */
71
/*  CALLED BY                                                             */
72
/*                                                                        */
73
/*    Application                                                         */
74
/*    USBX Components                                                     */
75
/*                                                                        */
76
/**************************************************************************/
77
411
UINT  _ux_host_stack_class_register(UCHAR *class_name,
78
                        UINT (*class_entry_function)(struct UX_HOST_CLASS_COMMAND_STRUCT *))
79
{
80
81
UX_HOST_CLASS       *class_inst;
82
#if !defined(UX_NAME_REFERENCED_BY_POINTER)
83
UINT                status;
84
411
UINT                class_name_length =  0;
85
#endif
86
#if UX_MAX_CLASS_DRIVER > 1
87
ULONG               class_index;
88
#endif
89
90
    /* If trace is enabled, insert this event into the trace buffer.  */
91
    UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_STACK_CLASS_REGISTER, class_name, class_entry_function, 0, 0, UX_TRACE_HOST_STACK_EVENTS, 0, 0)
92
93
#if !defined(UX_NAME_REFERENCED_BY_POINTER)
94
    /* Get the length of the class name (exclude null-terminator).  */
95
411
    status =  _ux_utility_string_length_check(class_name, &class_name_length, UX_MAX_CLASS_NAME_LENGTH);
96
411
    if (status)
97
1
        return(status);
98
#endif
99
100
    /* Get first class.  */
101
410
    class_inst =  _ux_system_host -> ux_system_host_class_array;
102
103
#if UX_MAX_CLASS_DRIVER > 1
104
    /* We need to parse the class table to find an empty spot.  */
105
493
    for (class_index = 0; class_index < _ux_system_host -> ux_system_host_max_class; class_index++)
106
    {
107
#endif
108
109
        /* Check if this class is already used.  */
110
492
        if (class_inst -> ux_host_class_status == UX_UNUSED)
111
        {
112
113
#if defined(UX_NAME_REFERENCED_BY_POINTER)
114
            class_inst -> ux_host_class_name = (const UCHAR *) class_name;
115
#else
116
117
            /* We have found a free container for the class. Copy the name (with null-terminator).  */
118
408
            _ux_utility_memory_copy(class_inst -> ux_host_class_name, class_name, class_name_length + 1); /* Use case of memcpy is verified. */
119
#endif
120
121
            /* Memorize the entry function of this class.  */
122
408
            class_inst -> ux_host_class_entry_function =  class_entry_function;
123
124
            /* Mark it as used.  */
125
408
            class_inst -> ux_host_class_status =  UX_USED;
126
127
            /* Return successful completion.  */
128
408
            return(UX_SUCCESS);
129
        }
130
131
        /* Do a sanity check to make sure the class is not already installed by
132
           mistake. To verify this, we simple check for the class entry point.  */
133
        else
134
        {
135
136
            /* Check for an already installed class entry function.  */
137
84
            if(class_inst -> ux_host_class_entry_function == class_entry_function)
138
            {
139
140
                /* Error trap. */
141
1
                _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_INIT, UX_HOST_CLASS_ALREADY_INSTALLED);
142
143
                /* If trace is enabled, insert this event into the trace buffer.  */
144
                UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_ALREADY_INSTALLED, class_name, 0, 0, UX_TRACE_ERRORS, 0, 0)
145
146
                /* Yes, return an error.  */
147
1
                return(UX_HOST_CLASS_ALREADY_INSTALLED);
148
            }
149
        }
150
#if UX_MAX_CLASS_DRIVER > 1
151
        /* Move to the next class.  */
152
83
        class_inst ++;
153
    }
154
#endif
155
156
    /* If trace is enabled, insert this event into the trace buffer.  */
157
    UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_MEMORY_ARRAY_FULL, class_name, 0, 0, UX_TRACE_ERRORS, 0, 0)
158
159
    /* Error trap. */
160
1
    _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_INIT, UX_MEMORY_ARRAY_FULL);
161
162
    /* No more entries in the class table.  */
163
1
    return(UX_MEMORY_ARRAY_FULL);
164
}
165
166
167
/**************************************************************************/
168
/*                                                                        */
169
/*  FUNCTION                                               RELEASE        */
170
/*                                                                        */
171
/*    _uxe_host_stack_class_register                      PORTABLE C      */
172
/*                                                           6.3.0        */
173
/*  AUTHOR                                                                */
174
/*                                                                        */
175
/*    Chaoqiong Xiao, Microsoft Corporation                               */
176
/*                                                                        */
177
/*  DESCRIPTION                                                           */
178
/*                                                                        */
179
/*    This function checks errors in host stack class register function   */
180
/*    call.                                                               */
181
/*                                                                        */
182
/*  INPUT                                                                 */
183
/*                                                                        */
184
/*    class_name                            Name of class                 */
185
/*    class_entry_function                  Entry function of the class   */
186
/*                                                                        */
187
/*  OUTPUT                                                                */
188
/*                                                                        */
189
/*    None                                                                */
190
/*                                                                        */
191
/*  CALLS                                                                 */
192
/*                                                                        */
193
/*    _ux_host_stack_class_instance_get     Host stack class instance get */
194
/*                                                                        */
195
/*  CALLED BY                                                             */
196
/*                                                                        */
197
/*    Application                                                         */
198
/*                                                                        */
199
/**************************************************************************/
200
UINT  _uxe_host_stack_class_register(UCHAR *class_name,
201
                        UINT (*class_entry_function)(struct UX_HOST_CLASS_COMMAND_STRUCT *))
202
{
203
204
    /* Sanity checks.  */
205
    if ((class_name == UX_NULL) || (class_entry_function == UX_NULL))
206
        return(UX_INVALID_PARAMETER);
207
208
    /* Invoke class register function.  */
209
    return(_ux_host_stack_class_register(class_name, class_entry_function));
210
}