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 /** HID Class */
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_class_hid.h"
29 #include "ux_host_stack.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_host_class_hid_main_item_parse PORTABLE C */
37 /* 6.1 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function parses a main item from the report descriptor. */
45 /* */
46 /* INPUT */
47 /* */
48 /* hid Pointer to HID class */
49 /* item Pointer to item */
50 /* descriptor Pointer to descriptor */
51 /* */
52 /* OUTPUT */
53 /* */
54 /* Completion Status */
55 /* */
56 /* CALLS */
57 /* */
58 /* _ux_host_class_hid_item_data_get Get data item */
59 /* _ux_host_class_hid_report_add Add report */
60 /* _ux_utility_memory_set Memory block set */
61 /* */
62 /* CALLED BY */
63 /* */
64 /* HID Class */
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 /* verified memset and memcpy */
73 /* cases, */
74 /* resulting in version 6.1 */
75 /* */
76 /**************************************************************************/
_ux_host_class_hid_main_item_parse(UX_HOST_CLASS_HID * hid,UX_HOST_CLASS_HID_ITEM * item,UCHAR * descriptor)77 UINT _ux_host_class_hid_main_item_parse(UX_HOST_CLASS_HID *hid, UX_HOST_CLASS_HID_ITEM *item, UCHAR *descriptor)
78 {
79
80 UX_HOST_CLASS_HID_PARSER *hid_parser;
81 UINT status = UX_ERROR;
82 ULONG collection_type;
83
84
85 /* Get the temporary parser structure pointer. */
86 hid_parser = &hid -> ux_host_class_hid_parser;
87
88 /* Analyze the tag. */
89 switch (item -> ux_host_class_hid_item_report_tag)
90 {
91
92 case UX_HOST_CLASS_HID_MAIN_TAG_COLLECTION:
93
94 /* We have a new collection to open. If the collection type is application,
95 we have to differentiate the first collection. */
96 collection_type = _ux_host_class_hid_item_data_get(descriptor, item);
97
98 /* Check the collection type. */
99 if (collection_type == UX_HOST_CLASS_HID_COLLECTION_APPLICATION)
100 {
101
102 /* We have a collection of type application, check if this is the first one */
103 if ((hid_parser -> ux_host_class_hid_parser_main_page == 0) && (hid_parser -> ux_host_class_hid_parser_main_usage == 0))
104 {
105
106 /* It is the first application. Since the main usage and page have not yet
107 been defined, we use the global page and the current local usage. */
108 hid_parser -> ux_host_class_hid_parser_main_page = hid_parser -> ux_host_class_hid_parser_global.ux_host_class_hid_global_item_usage_page;
109 hid_parser -> ux_host_class_hid_parser_main_usage = hid_parser -> ux_host_class_hid_parser_local.ux_host_class_hid_local_item_usages[0];
110 }
111
112 /* Memorize the application. */
113 hid_parser -> ux_host_class_hid_parser_application = collection_type;
114
115 /* Add one collection to this report */
116 hid_parser -> ux_host_class_hid_parser_number_collection++;
117
118 /* Set the status to success. */
119 status = UX_SUCCESS;
120 }
121 else
122 {
123
124 if (hid_parser -> ux_host_class_hid_parser_number_collection >= UX_HOST_CLASS_HID_MAX_COLLECTION)
125 {
126
127 /* Error trap. */
128 _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_HID_COLLECTION_OVERFLOW);
129
130 /* If trace is enabled, insert this event into the trace buffer. */
131 UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_HID_COLLECTION_OVERFLOW, hid, 0, 0, UX_TRACE_ERRORS, 0, 0)
132
133 return(UX_HOST_CLASS_HID_COLLECTION_OVERFLOW);
134 }
135 else
136 {
137
138 hid_parser -> ux_host_class_hid_parser_collection[hid_parser -> ux_host_class_hid_parser_number_collection] = collection_type;
139
140 /* Add one collection to this report. */
141 hid_parser -> ux_host_class_hid_parser_number_collection++;
142
143 /* Set the status to success. */
144 status = UX_SUCCESS;
145 }
146 }
147 break;
148
149 case UX_HOST_CLASS_HID_MAIN_TAG_END_COLLECTION:
150
151 /* We need to pop back the last collection. */
152 if (hid_parser -> ux_host_class_hid_parser_number_collection == 0)
153 {
154
155 /* Error trap. */
156 _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_HID_COLLECTION_OVERFLOW);
157
158 /* If trace is enabled, insert this event into the trace buffer. */
159 UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_HID_COLLECTION_OVERFLOW, hid, 0, 0, UX_TRACE_ERRORS, 0, 0)
160
161 return(UX_HOST_CLASS_HID_COLLECTION_OVERFLOW);
162 }
163
164 else
165
166 hid_parser -> ux_host_class_hid_parser_number_collection--;
167
168 status = UX_SUCCESS;
169 break;
170
171 case UX_HOST_CLASS_HID_MAIN_TAG_INPUT:
172 case UX_HOST_CLASS_HID_MAIN_TAG_OUTPUT:
173 case UX_HOST_CLASS_HID_MAIN_TAG_FEATURE:
174
175 /* We need to add a report. */
176 status = _ux_host_class_hid_report_add(hid, descriptor, item);
177 break;
178 }
179
180 /* We have a new main item, so the local instances have to be cleaned. */
181 _ux_utility_memory_set(&hid_parser -> ux_host_class_hid_parser_local, 0, sizeof(UX_HOST_CLASS_HID_LOCAL_ITEM)); /* Use case of memset is verified. */
182
183 /* Return completion status. */
184 return(status);
185 }
186
187