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