GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usbx_host_classes/src/ux_host_class_hid_client_register.c Lines: 25 29 86.2 %
Date: 2026-03-06 18:57:10 Branches: 14 18 77.8 %

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
/**   HID Class                                                           */
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_class_hid.h"
30
#include "ux_host_stack.h"
31
32
UX_COMPILE_TIME_ASSERT(!UX_OVERFLOW_CHECK_MULC_ULONG(UX_HOST_CLASS_HID_MAX_CLIENTS, sizeof(UX_HOST_CLASS_HID_CLIENT)), UX_HOST_CLASS_HID_MAX_CLIENTS_mem_alloc_ovf)
33
34
/**************************************************************************/
35
/*                                                                        */
36
/*  FUNCTION                                               RELEASE        */
37
/*                                                                        */
38
/*    _ux_host_class_hid_client_register                  PORTABLE C      */
39
/*                                                           6.1.12       */
40
/*  AUTHOR                                                                */
41
/*                                                                        */
42
/*    Chaoqiong Xiao, Microsoft Corporation                               */
43
/*                                                                        */
44
/*  DESCRIPTION                                                           */
45
/*                                                                        */
46
/*    This function registers a USB HID client to the HID class. The      */
47
/*    mechanism is similar to the USB stack class registration. The Class */
48
/*    must specify an entry point for the USB stack to send commands      */
49
/*    such as:                                                            */
50
/*                                                                        */
51
/*          UX_HOST_CLASS_COMMAND_QUERY                                   */
52
/*          UX_HOST_CLASS_COMMAND_ACTIVATE                                */
53
/*          UX_HOST_CLASS_COMMAND_DESTROY                                 */
54
/*                                                                        */
55
/*    Note: The C string of hid_client_name must be NULL-terminated and   */
56
/*    the length of it (without the NULL-terminator itself) must be no    */
57
/*    larger than UX_HOST_CLASS_HID_MAX_CLIENT_NAME_LENGTH.               */
58
/*                                                                        */
59
/*  INPUT                                                                 */
60
/*                                                                        */
61
/*    hid_client_name                       Name of HID client            */
62
/*    hid_client_handler                    Handler for HID client        */
63
/*                                                                        */
64
/*  OUTPUT                                                                */
65
/*                                                                        */
66
/*    Completion Status                                                   */
67
/*                                                                        */
68
/*  CALLS                                                                 */
69
/*                                                                        */
70
/*    _ux_host_stack_class_get              Get class                     */
71
/*    _ux_utility_memory_allocate           Allocate memory block         */
72
/*    _ux_utility_memory_copy               Copy memory block             */
73
/*    _ux_utility_string_length_check       Check C string and return     */
74
/*                                          length if null-terminated     */
75
/*                                                                        */
76
/*  CALLED BY                                                             */
77
/*                                                                        */
78
/*    Application                                                         */
79
/*    HID Class                                                           */
80
/*                                                                        */
81
/**************************************************************************/
82
144
UINT  _ux_host_class_hid_client_register(UCHAR *hid_client_name,
83
                                UINT (*hid_client_handler)(struct UX_HOST_CLASS_HID_CLIENT_COMMAND_STRUCT *))
84
{
85
86
UX_HOST_CLASS               *class_ptr;
87
ULONG                       hid_client_index;
88
UINT                        status;
89
UX_HOST_CLASS_HID_CLIENT    *hid_client;
90
144
UINT                        client_name_length =  0;
91
92
    /* If trace is enabled, insert this event into the trace buffer.  */
93
    UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_HID_CLIENT_REGISTER, hid_client_name, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
94
95
    /* Get the length of the client name (exclude null-terminator).  */
96
144
    status =  _ux_utility_string_length_check(hid_client_name, &client_name_length, UX_HOST_CLASS_HID_MAX_CLIENT_NAME_LENGTH);
97
144
    if (status)
98
1
        return(status);
99
100
    /* We need to locate our class container.  */
101
143
    status =  _ux_host_stack_class_get(_ux_system_host_class_hid_name, &class_ptr);
102
103
    /* If we cannot get the class container, it means the HID class was not registered.  */
104
143
    if (status != UX_SUCCESS)
105
1
        return(status);
106
107
    /* From the class container, we get the client pointer which has the list of
108
       HID clients. If the pointer is NULL, the client list was not assigned.  */
109
142
    if (class_ptr -> ux_host_class_client == UX_NULL)
110
    {
111
112
        /* Allocate memory for the class client.
113
         * Allocate size overflow static checked outside the function.
114
         */
115
128
        class_ptr -> ux_host_class_client =  _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY,
116
                                            sizeof(UX_HOST_CLASS_HID_CLIENT)*UX_HOST_CLASS_HID_MAX_CLIENTS);
117
118
        /* Check for successful allocation.  */
119
128
        if (class_ptr -> ux_host_class_client == UX_NULL)
120
1
            return(UX_MEMORY_INSUFFICIENT);
121
    }
122
123
    /* De-reference the client pointer into a HID client array pointer.  */
124
141
    hid_client =  (UX_HOST_CLASS_HID_CLIENT *) class_ptr -> ux_host_class_client;
125
126
    /* We need to parse the HID client handler table to find an empty spot.  */
127
186
    for (hid_client_index = 0; hid_client_index < UX_HOST_CLASS_HID_MAX_CLIENTS; hid_client_index++)
128
    {
129
130
        /* Check if this HID client is already used. */
131
185
        if (hid_client -> ux_host_class_hid_client_status == UX_UNUSED)
132
        {
133
134
            /* We have found a free container for the HID client. Copy the name (with null-terminator). */
135
139
            _ux_utility_memory_copy(hid_client -> ux_host_class_hid_client_name, hid_client_name, client_name_length + 1); /* Use case of memcpy is verified. */
136
137
            /* Memorize the handler address of this client. */
138
139
            hid_client -> ux_host_class_hid_client_handler =  hid_client_handler;
139
140
            /* Mark it as being in use.  */
141
139
            hid_client -> ux_host_class_hid_client_status =  UX_USED;
142
143
            /* Return successful completion.  */
144
139
            return(UX_SUCCESS);
145
        }
146
        else
147
        {
148
149
            /* Do a sanity check to make sure the handler is not already installed by
150
               mistake. To verify this, we simple check for the handler entry point.  */
151
46
               if (hid_client -> ux_host_class_hid_client_handler == hid_client_handler)
152
            {
153
154
                /* Error trap. */
155
1
                _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_ALREADY_INSTALLED);
156
157
                /* If trace is enabled, insert this event into the trace buffer.  */
158
                UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_ALREADY_INSTALLED, hid_client_name, 0, 0, UX_TRACE_ERRORS, 0, 0)
159
160
1
                return(UX_HOST_CLASS_ALREADY_INSTALLED);
161
            }
162
        }
163
164
        /* Try the next class.  */
165
45
        hid_client++;
166
    }
167
168
    /* Error trap. */
169
1
    _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_MEMORY_ARRAY_FULL);
170
171
    /* If trace is enabled, insert this event into the trace buffer.  */
172
    UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_MEMORY_ARRAY_FULL, hid_client_name, 0, 0, UX_TRACE_ERRORS, 0, 0)
173
174
    /* No more entries in the class table.  */
175
1
    return(UX_MEMORY_ARRAY_FULL);
176
}
177
178
/**************************************************************************/
179
/*                                                                        */
180
/*  FUNCTION                                               RELEASE        */
181
/*                                                                        */
182
/*    _uxe_host_class_hid_client_register                 PORTABLE C      */
183
/*                                                           6.3.0        */
184
/*  AUTHOR                                                                */
185
/*                                                                        */
186
/*    Chaoqiong Xiao, Microsoft Corporation                               */
187
/*                                                                        */
188
/*  DESCRIPTION                                                           */
189
/*                                                                        */
190
/*    This function checks errors in HID client register function call.   */
191
/*                                                                        */
192
/*  INPUT                                                                 */
193
/*                                                                        */
194
/*    hid_client_name                       Name of HID client            */
195
/*    hid_client_handler                    Handler for HID client        */
196
/*                                                                        */
197
/*  OUTPUT                                                                */
198
/*                                                                        */
199
/*    Status                                                              */
200
/*                                                                        */
201
/*  CALLS                                                                 */
202
/*                                                                        */
203
/*    _ux_host_class_hid_client_register    Register an HID client        */
204
/*                                                                        */
205
/*  CALLED BY                                                             */
206
/*                                                                        */
207
/*    Application                                                         */
208
/*                                                                        */
209
/**************************************************************************/
210
UINT  _uxe_host_class_hid_client_register(UCHAR *hid_client_name,
211
                                UINT (*hid_client_handler)(struct UX_HOST_CLASS_HID_CLIENT_COMMAND_STRUCT *))
212
{
213
214
    /* Sanity checks.  */
215
    if ((hid_client_name == UX_NULL) || (hid_client_handler == UX_NULL))
216
        return(UX_INVALID_PARAMETER);
217
218
    /* Invoke client register function.  */
219
    return(_ux_host_class_hid_client_register(hid_client_name, hid_client_handler));
220
}