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

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
/**   Device HID Class                                                    */
19
/**                                                                       */
20
/**************************************************************************/
21
/**************************************************************************/
22
23
#define UX_SOURCE_CODE
24
25
26
/* Include necessary system files.  */
27
28
#include "ux_api.h"
29
#include "ux_device_class_hid.h"
30
#include "ux_device_stack.h"
31
32
33
/**************************************************************************/
34
/*                                                                        */
35
/*  FUNCTION                                               RELEASE        */
36
/*                                                                        */
37
/*    _ux_device_class_hid_event_set                      PORTABLE C      */
38
/*                                                           6.3.0        */
39
/*  AUTHOR                                                                */
40
/*                                                                        */
41
/*    Chaoqiong Xiao, Microsoft Corporation                               */
42
/*                                                                        */
43
/*  DESCRIPTION                                                           */
44
/*                                                                        */
45
/*    This function sends an event to the hid class. It is processed      */
46
/*    asynchronously by the interrupt thread.                             */
47
/*                                                                        */
48
/*  INPUT                                                                 */
49
/*                                                                        */
50
/*    hid                                      Address of hid class       */
51
/*    event                                    Pointer of the event       */
52
/*                                                                        */
53
/*  OUTPUT                                                                */
54
/*                                                                        */
55
/*    status                                   UX_SUCCESS if there is an  */
56
/*                                             event                      */
57
/*  CALLS                                                                 */
58
/*                                                                        */
59
/*    _ux_utility_memory_copy                  Copy memory                */
60
/*    _ux_device_event_flags_set               Set event flags            */
61
/*                                                                        */
62
/*  CALLED BY                                                             */
63
/*                                                                        */
64
/*    ThreadX                                                             */
65
/*                                                                        */
66
/**************************************************************************/
67
1381
UINT  _ux_device_class_hid_event_set(UX_SLAVE_CLASS_HID *hid,
68
                                     UX_SLAVE_CLASS_HID_EVENT *hid_event)
69
{
70
71
UX_DEVICE_CLASS_HID_EVENT   *current_hid_event;
72
UX_DEVICE_CLASS_HID_EVENT   *next_hid_event;
73
UCHAR                       *next_position;
74
75
    /* If trace is enabled, insert this event into the trace buffer.  */
76
    UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_HID_EVENT_SET, hid, hid_event, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
77
78
    /* Current position of the head.  */
79
1381
    current_hid_event =  hid -> ux_device_class_hid_event_array_head;
80
81
    /* If the pointer is NULL, the round robin buffer has not been activated.  */
82
1381
    if (current_hid_event == UX_NULL)
83
2
        return (UX_ERROR);
84
85
    /* Calculate the next position.  */
86
1379
    next_position = (UCHAR *)current_hid_event + UX_DEVICE_CLASS_HID_EVENT_QUEUE_ITEM_SIZE(hid);
87
1379
    if (next_position >= (UCHAR *)hid -> ux_device_class_hid_event_array_end)
88
83
        next_position = (UCHAR *)hid -> ux_device_class_hid_event_array;
89
1379
    next_hid_event = (UX_DEVICE_CLASS_HID_EVENT *)next_position;
90
91
    /* Any place left for this event ? */
92
1379
    if (next_hid_event == hid -> ux_device_class_hid_event_array_tail)
93
58
        return (UX_ERROR);
94
95
    /* There is an event to report, get the current pointer to the event.  */
96
1321
    current_hid_event =  hid -> ux_device_class_hid_event_array_head;
97
98
    /* Update the head.  */
99
1321
    hid -> ux_device_class_hid_event_array_head = next_hid_event;
100
101
    /* Check if this event has a report ID.  */
102
1321
    if (hid -> ux_device_class_hid_report_id == UX_TRUE)
103
    {
104
105
        /* Yes, there's a report ID. Check to see if our event buffer can also
106
           fit the extra byte.  */
107
40
        if (hid_event -> ux_device_class_hid_event_length + 1 > UX_DEVICE_CLASS_HID_EVENT_MAX_LENGTH(hid))
108
        {
109
110
            /* Error trap. */
111
1
            _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_MEMORY_INSUFFICIENT);
112
113
            /* If trace is enabled, insert this event into the trace buffer.  */
114
            UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_MEMORY_INSUFFICIENT, 0, 0, 0, UX_TRACE_ERRORS, 0, 0)
115
116
            /* Return overflow error.  */
117
1
            return(UX_MEMORY_INSUFFICIENT);
118
        }
119
120
        /* Store the report ID.  */
121
39
        *UX_DEVICE_CLASS_HID_EVENT_BUFFER(current_hid_event) =  (UCHAR)(hid_event -> ux_device_class_hid_event_report_id);
122
123
        /* Store the data itself.  */
124
39
        _ux_utility_memory_copy(UX_DEVICE_CLASS_HID_EVENT_BUFFER(current_hid_event) + 1,
125
39
                                hid_event -> ux_device_class_hid_event_buffer,
126
                                hid_event -> ux_device_class_hid_event_length); /* Use case of memcpy is verified. */
127
128
        /* fill in the event structure from the user.  */
129
39
        current_hid_event -> ux_device_class_hid_event_length =  hid_event -> ux_device_class_hid_event_length + 1;
130
    }
131
    else
132
    {
133
134
        /* No report ID to consider.  */
135
136
        /* Store copy of data so application can free event there (easier use).  */
137
1281
        _ux_utility_memory_copy(UX_DEVICE_CLASS_HID_EVENT_BUFFER(current_hid_event),
138
1281
                                hid_event -> ux_device_class_hid_event_buffer,
139
                                hid_event -> ux_device_class_hid_event_length); /* Use case of memcpy is verified. */
140
141
        /* fill in the event structure from the user.  */
142
1281
        current_hid_event -> ux_device_class_hid_event_length = hid_event -> ux_device_class_hid_event_length;
143
    }
144
145
#if defined(UX_DEVICE_STANDALONE)
146
147
    /* Set state machine to start sending if no transfer on going.  */
148
    if (hid -> ux_device_class_hid_event_state != UX_STATE_WAIT &&
149
        hid -> ux_device_class_hid_event_state != UX_STATE_EXIT)
150
        hid -> ux_device_class_hid_event_state = UX_STATE_RESET;
151
#else
152
153
    /* Set an event to wake up the interrupt thread.  */
154
1320
    _ux_device_event_flags_set(&hid -> ux_device_class_hid_event_flags_group, UX_DEVICE_CLASS_HID_NEW_EVENT, UX_OR);
155
#endif
156
157
    /* Return event status to the user.  */
158
1320
    return(UX_SUCCESS);
159
}
160
161
162
/**************************************************************************/
163
/*                                                                        */
164
/*  FUNCTION                                               RELEASE        */
165
/*                                                                        */
166
/*    _uxe_device_class_hid_event_set                     PORTABLE C      */
167
/*                                                           6.3.0        */
168
/*  AUTHOR                                                                */
169
/*                                                                        */
170
/*    Chaoqiong Xiao, Microsoft Corporation                               */
171
/*                                                                        */
172
/*  DESCRIPTION                                                           */
173
/*                                                                        */
174
/*    This function checks errors in HID event set function call.         */
175
/*                                                                        */
176
/*  INPUT                                                                 */
177
/*                                                                        */
178
/*    hid                                   Pointer to hid instance       */
179
/*    hid_event                             Pointer to hid event          */
180
/*                                                                        */
181
/*  OUTPUT                                                                */
182
/*                                                                        */
183
/*    None                                                                */
184
/*                                                                        */
185
/*  CALLS                                                                 */
186
/*                                                                        */
187
/*    _ux_device_class_hid_event_set        Set an HID event              */
188
/*                                                                        */
189
/*  CALLED BY                                                             */
190
/*                                                                        */
191
/*    Application                                                         */
192
/*                                                                        */
193
/**************************************************************************/
194
UINT  _uxe_device_class_hid_event_set(UX_SLAVE_CLASS_HID *hid,
195
                                      UX_SLAVE_CLASS_HID_EVENT *hid_event)
196
{
197
198
    /* Sanity checks.  */
199
    if ((hid == UX_NULL) || (hid_event == UX_NULL))
200
        return(UX_INVALID_PARAMETER);
201
202
    /* Invoke function to get event.  */
203
    return(_ux_device_class_hid_event_set(hid, hid_event));
204
}