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 /** USBX Component                                                        */
15 /**                                                                       */
16 /**   Device HID Class                                                    */
17 /**                                                                       */
18 /**************************************************************************/
19 /**************************************************************************/
20 
21 #define UX_SOURCE_CODE
22 
23 
24 /* Include necessary system files.  */
25 
26 #include "ux_api.h"
27 #include "ux_device_class_hid.h"
28 #include "ux_device_stack.h"
29 
30 
31 /**************************************************************************/
32 /*                                                                        */
33 /*  FUNCTION                                               RELEASE        */
34 /*                                                                        */
35 /*    _ux_device_class_hid_event_check                    PORTABLE C      */
36 /*                                                           6.3.0        */
37 /*  AUTHOR                                                                */
38 /*                                                                        */
39 /*    Chaoqiong Xiao, Microsoft Corporation                               */
40 /*                                                                        */
41 /*  DESCRIPTION                                                           */
42 /*                                                                        */
43 /*    This function checks if there is an event from the application and  */
44 /*    fill a pointer to access the event.                                 */
45 /*                                                                        */
46 /*  INPUT                                                                 */
47 /*                                                                        */
48 /*    hid                                      Address of hid class       */
49 /*    event                                    Pointer to fill address    */
50 /*                                             to access event            */
51 /*                                                                        */
52 /*  OUTPUT                                                                */
53 /*                                                                        */
54 /*    status                                   UX_SUCCESS if there is an  */
55 /*                                             event                      */
56 /*  CALLS                                                                 */
57 /*                                                                        */
58 /*                                                                        */
59 /*  CALLED BY                                                             */
60 /*                                                                        */
61 /*    Device HID Class                                                    */
62 /*                                                                        */
63 /*  RELEASE HISTORY                                                       */
64 /*                                                                        */
65 /*    DATE              NAME                      DESCRIPTION             */
66 /*                                                                        */
67 /*  10-31-2023     Chaoqiong Xiao           Initial Version 6.3.0         */
68 /*                                                                        */
69 /**************************************************************************/
_ux_device_class_hid_event_check(UX_SLAVE_CLASS_HID * hid,UX_DEVICE_CLASS_HID_EVENT ** hid_event)70 UINT  _ux_device_class_hid_event_check(UX_SLAVE_CLASS_HID *hid,
71                                        UX_DEVICE_CLASS_HID_EVENT **hid_event)
72 {
73 UX_SLAVE_DEVICE                 *device;
74 
75     /* Get the pointer to the device.  */
76     device =  &_ux_system_slave -> ux_system_slave_device;
77 
78     /* Check the device state.  */
79     if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
80         return(UX_DEVICE_HANDLE_UNKNOWN);
81 
82     /* Check if the head and the tail of the event array is the same.  */
83     if (hid -> ux_device_class_hid_event_array_head ==
84         hid -> ux_device_class_hid_event_array_tail)
85 
86         /* No event to report.  */
87         return(UX_ERROR);
88 
89     /* There is an event to report, get the current pointer to the event.  */
90     *hid_event =  hid -> ux_device_class_hid_event_array_tail;
91     return(UX_SUCCESS);
92 }
93 
94 
95 /**************************************************************************/
96 /*                                                                        */
97 /*  FUNCTION                                               RELEASE        */
98 /*                                                                        */
99 /*    _ux_device_class_hid_event_free                     PORTABLE C      */
100 /*                                                           6.3.0        */
101 /*  AUTHOR                                                                */
102 /*                                                                        */
103 /*    Chaoqiong Xiao, Microsoft Corporation                               */
104 /*                                                                        */
105 /*  DESCRIPTION                                                           */
106 /*                                                                        */
107 /*    This function free the event in queue tail.                         */
108 /*                                                                        */
109 /*  INPUT                                                                 */
110 /*                                                                        */
111 /*    hid                                      Address of hid class       */
112 /*                                                                        */
113 /*  OUTPUT                                                                */
114 /*                                                                        */
115 /*                                                                        */
116 /*  CALLS                                                                 */
117 /*                                                                        */
118 /*                                                                        */
119 /*  CALLED BY                                                             */
120 /*                                                                        */
121 /*    Device HID Class                                                    */
122 /*                                                                        */
123 /*  RELEASE HISTORY                                                       */
124 /*                                                                        */
125 /*    DATE              NAME                      DESCRIPTION             */
126 /*                                                                        */
127 /*  10-31-2023     Chaoqiong Xiao           Initial Version 6.3.0         */
128 /*                                                                        */
129 /**************************************************************************/
_ux_device_class_hid_event_free(UX_SLAVE_CLASS_HID * hid)130 VOID  _ux_device_class_hid_event_free(UX_SLAVE_CLASS_HID *hid)
131 {
132 UCHAR                           *pos;
133 
134     pos = (UCHAR *) hid -> ux_device_class_hid_event_array_tail;
135     pos += UX_DEVICE_CLASS_HID_EVENT_QUEUE_ITEM_SIZE(hid);
136     if (pos >= (UCHAR *) hid -> ux_device_class_hid_event_array_end)
137         pos = (UCHAR *) hid -> ux_device_class_hid_event_array;
138     hid -> ux_device_class_hid_event_array_tail = (UX_DEVICE_CLASS_HID_EVENT *) pos;
139 }
140 
141 
142 /**************************************************************************/
143 /*                                                                        */
144 /*  FUNCTION                                               RELEASE        */
145 /*                                                                        */
146 /*    _ux_device_class_hid_event_get                      PORTABLE C      */
147 /*                                                           6.3.0        */
148 /*  AUTHOR                                                                */
149 /*                                                                        */
150 /*    Chaoqiong Xiao, Microsoft Corporation                               */
151 /*                                                                        */
152 /*  DESCRIPTION                                                           */
153 /*                                                                        */
154 /*    This function checks if there is an event from the application      */
155 /*                                                                        */
156 /*  INPUT                                                                 */
157 /*                                                                        */
158 /*    hid                                      Address of hid class       */
159 /*    event                                    Pointer of the event       */
160 /*                                                                        */
161 /*  OUTPUT                                                                */
162 /*                                                                        */
163 /*    status                                   UX_SUCCESS if there is an  */
164 /*                                             event                      */
165 /*  CALLS                                                                 */
166 /*                                                                        */
167 /*    _ux_utility_memory_copy                  Copy memory                */
168 /*                                                                        */
169 /*  CALLED BY                                                             */
170 /*                                                                        */
171 /*    ThreadX                                                             */
172 /*                                                                        */
173 /*  RELEASE HISTORY                                                       */
174 /*                                                                        */
175 /*    DATE              NAME                      DESCRIPTION             */
176 /*                                                                        */
177 /*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
178 /*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
179 /*                                            verified memset and memcpy  */
180 /*                                            cases,                      */
181 /*                                            resulting in version 6.1    */
182 /*  10-31-2023     Chaoqiong Xiao           Modified comment(s),          */
183 /*                                            added zero copy support,    */
184 /*                                            resulting in version 6.3.0  */
185 /*                                                                        */
186 /**************************************************************************/
_ux_device_class_hid_event_get(UX_SLAVE_CLASS_HID * hid,UX_SLAVE_CLASS_HID_EVENT * hid_event)187 UINT  _ux_device_class_hid_event_get(UX_SLAVE_CLASS_HID *hid,
188                                      UX_SLAVE_CLASS_HID_EVENT *hid_event)
189 {
190 
191 UX_DEVICE_CLASS_HID_EVENT       *current_hid_event;
192 UINT                            status;
193 
194     /* If trace is enabled, insert this event into the trace buffer.  */
195     UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_HID_EVENT_GET, hid, hid_event, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
196 
197     /* Check and get event pointer.  */
198     status = _ux_device_class_hid_event_check(hid, &current_hid_event);
199     if (status != UX_SUCCESS)
200         return(status);
201 
202     /* Keep the event data length inside buffer area.  */
203     if (current_hid_event -> ux_device_class_hid_event_length > UX_DEVICE_CLASS_HID_EVENT_MAX_LENGTH(hid))
204         current_hid_event -> ux_device_class_hid_event_length = UX_DEVICE_CLASS_HID_EVENT_MAX_LENGTH(hid);
205 
206     /* fill in the event structure from the user.  */
207     hid_event -> ux_device_class_hid_event_length =  current_hid_event -> ux_device_class_hid_event_length;
208 
209     /* Copy the event data into the user buffer.  */
210     _ux_utility_memory_copy(hid_event -> ux_device_class_hid_event_buffer,
211                             UX_DEVICE_CLASS_HID_EVENT_BUFFER(current_hid_event),
212                             current_hid_event -> ux_device_class_hid_event_length); /* Use case of memcpy is verified. */
213 
214     /* Free the tail event.  */
215     _ux_device_class_hid_event_free(hid);
216 
217     /* Return event status to the user.  */
218     return(UX_SUCCESS);
219 }
220 
221 
222 /**************************************************************************/
223 /*                                                                        */
224 /*  FUNCTION                                               RELEASE        */
225 /*                                                                        */
226 /*    _uxe_device_class_hid_event_get                     PORTABLE C      */
227 /*                                                           6.3.0        */
228 /*  AUTHOR                                                                */
229 /*                                                                        */
230 /*    Chaoqiong Xiao, Microsoft Corporation                               */
231 /*                                                                        */
232 /*  DESCRIPTION                                                           */
233 /*                                                                        */
234 /*    This function checks errors in HID event get function call.         */
235 /*                                                                        */
236 /*  INPUT                                                                 */
237 /*                                                                        */
238 /*    hid                                   Pointer to hid instance       */
239 /*    hid_event                             Pointer to hid event          */
240 /*                                                                        */
241 /*  OUTPUT                                                                */
242 /*                                                                        */
243 /*    None                                                                */
244 /*                                                                        */
245 /*  CALLS                                                                 */
246 /*                                                                        */
247 /*    _ux_device_class_hid_event_get        Get an HID event              */
248 /*                                                                        */
249 /*  CALLED BY                                                             */
250 /*                                                                        */
251 /*    Application                                                         */
252 /*                                                                        */
253 /*  RELEASE HISTORY                                                       */
254 /*                                                                        */
255 /*    DATE              NAME                      DESCRIPTION             */
256 /*                                                                        */
257 /*  10-31-2023     Chaoqiong Xiao           Initial Version 6.3.0         */
258 /*                                                                        */
259 /**************************************************************************/
_uxe_device_class_hid_event_get(UX_SLAVE_CLASS_HID * hid,UX_SLAVE_CLASS_HID_EVENT * hid_event)260 UINT  _uxe_device_class_hid_event_get(UX_SLAVE_CLASS_HID *hid,
261                                       UX_SLAVE_CLASS_HID_EVENT *hid_event)
262 {
263 
264     /* Sanity checks.  */
265     if ((hid == UX_NULL) || (hid_event == UX_NULL))
266         return(UX_INVALID_PARAMETER);
267 
268     /* Invoke function to get event.  */
269     return(_ux_device_class_hid_event_get(hid, hid_event));
270 }
271