1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 
13 /**************************************************************************/
14 /**************************************************************************/
15 /**                                                                       */
16 /** USBX Component                                                        */
17 /**                                                                       */
18 /**   HID Keyboard Client                                                 */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 
24 /**************************************************************************/
25 /*                                                                        */
26 /*  COMPONENT DEFINITION                                   RELEASE        */
27 /*                                                                        */
28 /*    ux_host_class_hid_keyboard.h                        PORTABLE C      */
29 /*                                                           6.2.0        */
30 /*  AUTHOR                                                                */
31 /*                                                                        */
32 /*    Chaoqiong Xiao, Microsoft Corporation                               */
33 /*                                                                        */
34 /*  DESCRIPTION                                                           */
35 /*                                                                        */
36 /*    This file contains all the header and extern functions used by the  */
37 /*    USBX HID keyboard client.                                           */
38 /*                                                                        */
39 /*  RELEASE HISTORY                                                       */
40 /*                                                                        */
41 /*    DATE              NAME                      DESCRIPTION             */
42 /*                                                                        */
43 /*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
44 /*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
45 /*                                            used UX prefix to refer to  */
46 /*                                            TX symbols instead of using */
47 /*                                            them directly,              */
48 /*                                            resulting in version 6.1    */
49 /*  08-02-2021     Wen Wang                 Modified comment(s),          */
50 /*                                            added extern "C" keyword    */
51 /*                                            for compatibility with C++, */
52 /*                                            resulting in version 6.1.8  */
53 /*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
54 /*                                            added standalone support,   */
55 /*                                            resulting in version 6.1.10 */
56 /*  04-25-2022     Chaoqiong Xiao           Modified comment(s),          */
57 /*                                            fixed clients management,   */
58 /*                                            resulting in version 6.1.11 */
59 /*  10-31-2022     Chaoqiong Xiao           Modified comment(s),          */
60 /*                                            improved HID OUTPUT report  */
61 /*                                            handling in standalone mode,*/
62 /*                                            resulting in version 6.2.0  */
63 /*                                                                        */
64 /**************************************************************************/
65 
66 #ifndef UX_HOST_CLASS_HID_KEYBOARD_H
67 #define UX_HOST_CLASS_HID_KEYBOARD_H
68 
69 /* Determine if a C++ compiler is being used.  If so, ensure that standard
70    C is used to process the API information.  */
71 
72 #ifdef   __cplusplus
73 
74 /* Yes, C++ compiler is present.  Use standard C.  */
75 extern   "C" {
76 
77 #endif
78 
79 
80 /* Define HID Keyboard Class constants.  */
81 
82 #define UX_HOST_CLASS_HID_KEYBOARD_BUFFER_LENGTH            128
83 #define UX_HOST_CLASS_HID_KEYBOARD_USAGE_ARRAY_LENGTH       64
84 
85 /* Each item in usage array takes 4 bytes. Check memory bytes calculation overflow here.  */
86 #if UX_OVERFLOW_CHECK_MULC_ULONG(UX_HOST_CLASS_HID_KEYBOARD_USAGE_ARRAY_LENGTH, 4)
87 #error UX_HOST_CLASS_HID_KEYBOARD_USAGE_ARRAY_LENGTH too large for memory allocation
88 #endif
89 
90 /* Define HID Keyboard Class LED keys.  */
91 
92 #define UX_HID_LED_KEY_CAPS_LOCK                            0x39
93 #define UX_HID_LED_KEY_NUM_LOCK                             0x53
94 #define UX_HID_LED_KEY_SCROLL_LOCK                          0x47
95 
96 
97 /* Define HID Keyboard Class Modifier Keys.  */
98 
99 #define UX_HID_MODIFIER_KEY_LEFT_CONTROL                    0xe0
100 #define UX_HID_MODIFIER_KEY_LEFT_SHIFT                      0xe1
101 #define UX_HID_MODIFIER_KEY_LEFT_ALT                        0xe2
102 #define UX_HID_MODIFIER_KEY_LEFT_GUI                        0xe3
103 #define UX_HID_MODIFIER_KEY_RIGHT_CONTROL                   0xe4
104 #define UX_HID_MODIFIER_KEY_RIGHT_SHIFT                     0xe5
105 #define UX_HID_MODIFIER_KEY_RIGHT_ALT                       0xe6
106 #define UX_HID_MODIFIER_KEY_RIGHT_GUI                       0xe7
107 
108 
109 /* Define HID Keyboard States.  */
110 
111 #define UX_HID_KEYBOARD_STATE_NUM_LOCK                      0x0001
112 #define UX_HID_KEYBOARD_STATE_CAPS_LOCK                     0x0002
113 #define UX_HID_KEYBOARD_STATE_SCROLL_LOCK                   0x0004
114 #define UX_HID_KEYBOARD_STATE_MASK_LOCK                     0x0007
115 
116 #define UX_HID_KEYBOARD_STATE_LEFT_SHIFT                    0x0100
117 #define UX_HID_KEYBOARD_STATE_RIGHT_SHIFT                   0x0200
118 #define UX_HID_KEYBOARD_STATE_SHIFT                         0x0300
119 
120 #define UX_HID_KEYBOARD_STATE_LEFT_ALT                      0x0400
121 #define UX_HID_KEYBOARD_STATE_RIGHT_ALT                     0x0800
122 #define UX_HID_KEYBOARD_STATE_ALT                           0x0a00
123 
124 #define UX_HID_KEYBOARD_STATE_LEFT_CTRL                     0x1000
125 #define UX_HID_KEYBOARD_STATE_RIGHT_CTRL                    0x2000
126 #define UX_HID_KEYBOARD_STATE_CTRL                          0x3000
127 
128 #define UX_HID_KEYBOARD_STATE_LEFT_GUI                      0x4000
129 #define UX_HID_KEYBOARD_STATE_RIGHT_GUI                     0x8000
130 #define UX_HID_KEYBOARD_STATE_GUI                           0xa000
131 
132 #define UX_HID_KEYBOARD_STATE_KEY_UP                        0x10000
133 #define UX_HID_KEYBOARD_STATE_FUNCTION                      0x20000
134 
135 /* Define HID keyboard generic equivalences.  */
136 
137 #define UX_HID_KEYBOARD_NO_KEY                              0
138 #define UX_HID_KEYBOARD_PHANTOM_STATE                       0x01
139 #define UX_HID_KEYBOARD_KEY_LETTER_A                        0x04
140 #define UX_HID_KEYBOARD_KEY_LETTER_Z                        0x1D
141 #define UX_HID_KEYBOARD_KEYS_KEYPAD_LOWER_RANGE             0x54
142 #define UX_HID_KEYBOARD_KEYS_KEYPAD_UPPER_RANGE             0x67
143 #define UX_HID_KEYBOARD_KEYS_UPPER_RANGE                    115
144 
145 /* Define HID keyboard ioctl Functions.  */
146 
147 #define UX_HID_KEYBOARD_IOCTL_SET_LAYOUT                    0
148 #define UX_HID_KEYBOARD_IOCTL_DISABLE_KEYS_DECODE           1
149 #define UX_HID_KEYBOARD_IOCTL_ENABLE_KEYS_DECODE            2
150 
151 /* Define HID keyboard layout array.  */
152 
153 #define UX_HID_KEYBOARD_REGULAR_ARRAY_US                                    \
154    0,0,0,0,                                                                 \
155    'a','b','c','d','e','f','g','h','i','j','k','l','m','n',                 \
156    'o','p','q','r','s','t','u','v','w','x','y','z',                         \
157    '1','2','3','4','5','6','7','8','9','0',                                 \
158    0x0d,0x1b,0x08,0x07,0x20,'-','=','[',']',                                \
159    '\\','#',';',0x27,'`',',','.','/',0xf0,                                  \
160    0xbb,0xbc,0xbd,0xbe,0xbf,0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,             \
161    0x00,0xf1,0x00,0xd2,0xc7,0xc9,0xd3,0xcf,0xd1,0xcd,0xcb,0xd0,0xc8,0xf2,   \
162    '/','*','-','+',                                                         \
163    0x0d,'1','2','3','4','5','6','7','8','9','0','.','\\',0x00,0x00,'=',     \
164    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
165 
166 #define UX_HID_KEYBOARD_SHIFT_ARRAY_US                                      \
167    0,0,0,0,                                                                 \
168    'A','B','C','D','E','F','G','H','I','J','K','L','M','N',                 \
169    'O','P','Q','R','S','T','U','V','W','X','Y','Z',                         \
170    '!','@','#','$','%','^','&','*','(',')',                                 \
171    0x0d,0x1b,0x08,0x07,0x20,'_','+','{','}',                                \
172    '|','~',':','"','~','<','>','?',0xf0,                                    \
173    0xbb,0xbc,0xbd,0xbe,0xbf,0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,             \
174    0x00,0xf1,0x00,0xd2,0xc7,0xc9,0xd3,0xcf,0xd1,0xcd,0xcb,0xd0,0xc8,0xf2,   \
175    '/','*','-','+',                                                         \
176    0x0d,'1','2','3','4','5','6','7','8','9','0','.','\\',0x00,0x00,'=',     \
177    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
178 
179 #define UX_HID_KEYBOARD_NUMLOCK_ON_ARRAY                                    \
180    '/','*','-','+',                                                         \
181    0x0d,                                                                    \
182    '1','2','3','4','5','6','7','8','9','0',                                 \
183    '.','\\',0x00,0x00,'=',
184 
185 #define UX_HID_KEYBOARD_NUMLOCK_OFF_ARRAY                                   \
186    '/','*','-','+',                                                         \
187    0x0d,                                                                    \
188    0xcf,0xd0,0xd1,0xcb,'5',0xcd,0xc7,0xc8,0xc9,0xd2,                        \
189    0xd3,'\\',0x00,0x00,'=',
190 
191 /* Define HID Keyboard layout (key mapping) structure.  */
192 
193 typedef struct UX_HOST_CLASS_HID_KEYBOARD_LAYOUT_STRUCT
194 {
195 
196     UCHAR           *ux_host_class_hid_keyboard_layout_regular_array;
197     UCHAR           *ux_host_class_hid_keyboard_layout_shift_array;
198     UCHAR           *ux_host_class_hid_keyboard_layout_numlock_on_array;
199     UCHAR           *ux_host_class_hid_keyboard_layout_numlock_off_array;
200     ULONG           ux_host_class_hid_keyboard_layout_keys_upper_range;
201     ULONG           ux_host_class_hid_keyboard_layout_letters_lower_range;
202     ULONG           ux_host_class_hid_keyboard_layout_letters_upper_range;
203     ULONG           ux_host_class_hid_keyboard_layout_keypad_lower_range;
204     ULONG           ux_host_class_hid_keyboard_layout_keypad_upper_range;
205 } UX_HOST_CLASS_HID_KEYBOARD_LAYOUT;
206 
207 /* Define HID Keyboard Class structure.  */
208 
209 typedef struct UX_HOST_CLASS_HID_KEYBOARD_STRUCT
210 {
211 
212     ULONG           ux_host_class_hid_keyboard_state;
213     UCHAR           *ux_host_class_hid_keyboard_key_state;
214     ULONG           ux_host_class_hid_keyboard_key_count;
215     UX_HOST_CLASS_HID   *ux_host_class_hid_keyboard_hid;
216     USHORT          ux_host_class_hid_keyboard_id;
217 #if !defined(UX_HOST_STANDALONE)
218     VOID            *ux_host_class_hid_keyboard_thread_stack;
219     UX_THREAD       ux_host_class_hid_keyboard_thread;
220     UX_SEMAPHORE    ux_host_class_hid_keyboard_semaphore;
221 #else
222     UX_HOST_CLASS_HID_REPORT
223                     *ux_host_class_hid_keyboard_out_report;
224     UINT            ux_host_class_hid_keyboard_status;
225     UCHAR           ux_host_class_hid_keyboard_enum_state;
226     UCHAR           ux_host_class_hid_keyboard_next_state;
227     UCHAR           ux_host_class_hid_keyboard_out_state;
228     UCHAR           reserved;
229 #endif
230     ULONG           ux_host_class_hid_keyboard_alternate_key_state;
231     ULONG           ux_host_class_hid_keyboard_led_mask;
232     ULONG           *ux_host_class_hid_keyboard_usage_array;
233     ULONG           *ux_host_class_hid_keyboard_usage_array_head;
234     ULONG           *ux_host_class_hid_keyboard_usage_array_tail;
235     UX_HOST_CLASS_HID_KEYBOARD_LAYOUT *ux_host_class_hid_keyboard_layout;
236     ULONG           ux_host_class_hid_keyboard_keys_decode_disable;
237 } UX_HOST_CLASS_HID_KEYBOARD;
238 
239 typedef struct UX_HOST_CLASS_HID_CLIENT_KEYBOARD_STRUCT
240 {
241     UX_HOST_CLASS_HID_KEYBOARD   ux_host_class_hid_client_keyboard_keyboard;
242     UX_HOST_CLASS_HID_CLIENT     ux_host_class_hid_client_keyboard_client;
243 } UX_HOST_CLASS_HID_CLIENT_KEYBOARD;
244 
245 /* Define HID Keyboard Class function prototypes.  */
246 
247 VOID    _ux_host_class_hid_keyboard_callback(UX_HOST_CLASS_HID_REPORT_CALLBACK *callback);
248 UINT    _ux_host_class_hid_keyboard_activate(UX_HOST_CLASS_HID_CLIENT_COMMAND *command);
249 UINT    _ux_host_class_hid_keyboard_deactivate(UX_HOST_CLASS_HID_CLIENT_COMMAND *command);
250 UINT    _ux_host_class_hid_keyboard_entry(UX_HOST_CLASS_HID_CLIENT_COMMAND *command);
251 VOID    _ux_host_class_hid_keyboard_thread(ULONG thread_entry);
252 UINT    _ux_host_class_hid_keyboard_key_get(UX_HOST_CLASS_HID_KEYBOARD *keyboard_instance,
253                                             ULONG *keyboard_key, ULONG *keyboard_state);
254 UINT    _ux_host_class_hid_keyboard_ioctl(UX_HOST_CLASS_HID_KEYBOARD *keyboard_instance,
255                                         ULONG ioctl_function, VOID *parameter);
256 
257 VOID    _ux_host_class_hid_keyboard_tasks_run(UX_HOST_CLASS_HID_CLIENT *client);
258 
259 /* Define HID Keyboard Class API prototypes.  */
260 
261 #define ux_host_class_hid_keyboard_entry                   _ux_host_class_hid_keyboard_entry
262 #define ux_host_class_hid_keyboard_key_get                 _ux_host_class_hid_keyboard_key_get
263 #define ux_host_class_hid_keyboard_ioctl                   _ux_host_class_hid_keyboard_ioctl
264 
265 /* Determine if a C++ compiler is being used.  If so, complete the standard
266    C conditional started above.  */
267 #ifdef __cplusplus
268 }
269 #endif
270 
271 #endif
272 
273