1 #include "usbx_test_common_hid.h"
2 #include "ux_host_class_hid_keyboard.h"
3 
4 
5 #define DUMMY_USBX_MEMORY_SIZE (64*1024)
6 static UCHAR dummy_usbx_memory[DUMMY_USBX_MEMORY_SIZE];
7 
8 static UCHAR hid_report_descriptor[] = {
9 
10     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
11     0x09, 0x06,                    // USAGE (Keyboard)
12     0xa1, 0x01,                    // COLLECTION (Application)
13     0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
14     0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)
15     0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)
16     0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
17     0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
18     0x75, 0x01,                    //   REPORT_SIZE (1)
19     0x95, 0x08,                    //   REPORT_COUNT (8)
20     0x81, 0x02,                    //   INPUT (Data,Var,Abs)
21     0x95, 0x01,                    //   REPORT_COUNT (1)
22     0x75, 0x08,                    //   REPORT_SIZE (8)
23     0x81, 0x03,                    //   INPUT (Cnst,Var,Abs)
24     0x95, 0x05,                    //   REPORT_COUNT (5)
25     0x75, 0x01,                    //   REPORT_SIZE (1)
26     0x05, 0x08,                    //   USAGE_PAGE (LEDs)
27     0x19, 0x01,                    //   USAGE_MINIMUM (Num Lock)
28     0x29, 0x05,                    //   USAGE_MAXIMUM (Kana)
29     0x91, 0x02,                    //   OUTPUT (Data,Var,Abs)
30     0x95, 0x01,                    //   REPORT_COUNT (1)
31     0x75, 0x03,                    //   REPORT_SIZE (3)
32     0x91, 0x03,                    //   OUTPUT (Cnst,Var,Abs)
33     0x95, 0x06,                    //   REPORT_COUNT (6)
34     0x75, 0x08,                    //   REPORT_SIZE (8)
35     0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
36     0x25, 0x65,                    //   LOGICAL_MAXIMUM (101)
37     0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
38     0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))
39     0x29, 0x65,                    //   USAGE_MAXIMUM (Keyboard Application)
40     0x81, 0x00,                    //   INPUT (Data,Ary,Abs)
41     0xc0                           // END_COLLECTION
42 };
43 #define HID_REPORT_LENGTH sizeof(hid_report_descriptor)/sizeof(hid_report_descriptor[0])
44 
45 static UCHAR hid_mouse_report[] = {
46 
47     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
48     0x09, 0x02,                    // USAGE (Mouse)
49     0xa1, 0x01,                    // COLLECTION (Application)
50     0x85, 0x01,                    //   REPORT_ID (1)
51     0x09, 0x01,                    //   USAGE (Pointer)
52     0xa1, 0x00,                    //   COLLECTION (Physical)
53     0x05, 0x09,                    //     USAGE_PAGE (Button)
54     0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
55     0x29, 0x03,                    //     USAGE_MAXIMUM (Button 3)
56     0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
57     0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
58     0x95, 0x03,                    //     REPORT_COUNT (3)
59     0x75, 0x01,                    //     REPORT_SIZE (1)
60     0x81, 0x02,                    //     INPUT (Data,Var,Abs)
61     0x95, 0x01,                    //     REPORT_COUNT (1)
62     0x75, 0x05,                    //     REPORT_SIZE (5)
63     0x81, 0x03,                    //     INPUT (Cnst,Var,Abs)
64     0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
65     0x09, 0x30,                    //     USAGE (X)
66     0x09, 0x31,                    //     USAGE (Y)
67     0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
68     0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
69     0x75, 0x08,                    //     REPORT_SIZE (8)
70     0x95, 0x02,                    //     REPORT_COUNT (2)
71     0x81, 0x06,                    //     INPUT (Data,Var,Rel)
72     0x09, 0x38,                    //     USAGE (Mouse Wheel)
73     0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
74     0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
75     0x75, 0x08,                    //     REPORT_SIZE (8)
76     0x95, 0x01,                    //     REPORT_COUNT (1)
77     0x81, 0x06,                    //     INPUT (Data,Var,Rel)
78     0xc0,                          //   END_COLLECTION
79     0xc0                           // END_COLLECTION
80 };
81 #define HID_MOUSE_REPORT_LENGTH (sizeof(hid_mouse_report)/sizeof(hid_mouse_report[0]))
82 
83 /* Configuration descriptor 9 bytes */
84 #define CFG_DESC(wTotalLength, bNumInterfaces, bConfigurationValue)\
85     /* Configuration 1 descriptor 9 bytes */\
86     0x09, 0x02, LSB(wTotalLength), MSB(wTotalLength),\
87     (bNumInterfaces), (bConfigurationValue), 0x00,\
88     0x40, 0x00,
89 #define CFG_DESC_LEN (9)
90 
91 /* HID Mouse/Keyboard interface descriptors 9+9+7=25 bytes */
92 #define HID_IFC_DESC_ALL(ifc, report_len, interrupt_epa) \
93     /* Interface descriptor */\
94     0x09, 0x04, (ifc), 0x00, 0x01, 0x03, 0x00, 0x00, 0x00,\
95     /* HID descriptor */\
96     0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(report_len),\
97         MSB(report_len),\
98     /* Endpoint descriptor (Interrupt) */\
99     0x07, 0x05, (interrupt_epa), 0x03, 0x08, 0x00, 0x08,
100 #define HID_IFC_DESC_ALL_LEN (9+9+7)
101 
102 static UCHAR device_framework_full_speed[] = {
103 
104     /* Device descriptor */
105         0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
106         0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
107         0x00, 0x01,
108 
109     // /* Configuration descriptor */
110     //     0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
111     //     0x32,
112         CFG_DESC(CFG_DESC_LEN+2*HID_IFC_DESC_ALL_LEN, 2, 0x01)
113 
114     // /* Interface descriptor */
115     //     0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
116     //     0x00,
117     // /* HID descriptor */
118     //     0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
119     //     MSB(HID_REPORT_LENGTH),
120     // /* Endpoint descriptor (Interrupt) */
121     //     0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
122         HID_IFC_DESC_ALL(2, HID_REPORT_LENGTH, 0x82)
123 
124     HID_IFC_DESC_ALL(1, HID_MOUSE_REPORT_LENGTH, 0x81)
125     };
126 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
127 
128 
129 static UCHAR device_framework_high_speed[] = {
130 
131     /* Device descriptor */
132         0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
133         0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
134         0x03, 0x01,
135 
136     /* Device qualifier descriptor */
137         0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
138         0x01, 0x00,
139 
140     // /* Configuration descriptor */
141     //     0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
142     //     0x32,
143     CFG_DESC(CFG_DESC_LEN+2*HID_IFC_DESC_ALL_LEN, 2, 0x01)
144 
145     // /* Interface descriptor */
146     //     0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
147     //     0x00,
148     // /* HID descriptor */
149     //     0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
150     //     MSB(HID_REPORT_LENGTH),
151     // /* Endpoint descriptor (Interrupt) */
152     //     0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
153         HID_IFC_DESC_ALL(2, HID_REPORT_LENGTH, 0x82)
154 
155     HID_IFC_DESC_ALL(1, HID_MOUSE_REPORT_LENGTH, 0x81)
156     };
157 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
158 
159 
160 static UCHAR corrupted_device_framework[DEVICE_FRAMEWORK_LENGTH_FULL_SPEED] = {
161 
162     /* Device descriptor. Length (first byte) is too large. */
163         0xff, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
164         0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
165         0x00, 0x01,
166 
167     /* Configuration descriptor */
168         0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
169         0x32,
170 
171     /* Interface descriptor */
172         0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
173         0x00,
174 
175     /* HID descriptor */
176         0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
177         MSB(HID_REPORT_LENGTH),
178 
179     /* Endpoint descriptor (Interrupt) */
180         0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
181 
182     };
183 
184 static UCHAR corrupted_device_framework_hid[DEVICE_FRAMEWORK_LENGTH_FULL_SPEED] = {
185 
186     /* Device descriptor. */
187         0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
188         0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
189         0x00, 0x01,
190 
191     /* Configuration descriptor */
192         0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
193         0x32,
194 
195     /* Interface descriptor */
196         0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
197         0x00,
198 
199     /* HID descriptor (length too long) */
200         0xff, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
201         MSB(HID_REPORT_LENGTH),
202 
203     /* Endpoint descriptor (Interrupt) */
204         0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
205 
206     };
207 
208 
209     /* String Device Framework :
210      Byte 0 and 1 : Word containing the language ID : 0x0904 for US
211      Byte 2       : Byte containing the index of the descriptor
212      Byte 3       : Byte containing the length of the descriptor string
213     */
214 
215 #define STRING_FRAMEWORK_LENGTH 40
216 static UCHAR string_framework[] = {
217 
218     /* Manufacturer string descriptor : Index 1 */
219         0x09, 0x04, 0x01, 0x0c,
220         0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
221         0x6f, 0x67, 0x69, 0x63,
222 
223     /* Product string descriptor : Index 2 */
224         0x09, 0x04, 0x02, 0x0c,
225         0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
226         0x6f, 0x61, 0x72, 0x64,
227 
228     /* Serial Number string descriptor : Index 3 */
229         0x09, 0x04, 0x03, 0x04,
230         0x30, 0x30, 0x30, 0x31
231     };
232 
233 
234     /* Multiple languages are supported on the device, to add
235        a language besides english, the unicode language code must
236        be appended to the language_id_framework array and the length
237        adjusted accordingly. */
238 #define LANGUAGE_ID_FRAMEWORK_LENGTH 2
239 static UCHAR language_id_framework[] = {
240 
241     /* English. */
242         0x09, 0x04
243     };
244 
245 
246 UINT  _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter);
247 
248 
ux_system_host_change_function(ULONG a,UX_HOST_CLASS * b,VOID * c)249 static UINT ux_system_host_change_function(ULONG a, UX_HOST_CLASS *b, VOID *c)
250 {
251     return 0;
252 }
253 
error_callback(UINT system_level,UINT system_context,UINT error_code)254 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
255 {
256 }
257 
set_hid_descriptor(UCHAR * descriptor,ULONG length)258 static VOID set_hid_descriptor(UCHAR *descriptor, ULONG length)
259 {
260 
261 UX_SLAVE_CLASS     *class;
262 UX_SLAVE_CLASS_HID *hid_class;
263 
264 
265     device_framework_full_speed[DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 9] = LSB(length);
266     device_framework_full_speed[DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 8] = MSB(length);
267     device_framework_high_speed[DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 9] = LSB(length);
268     device_framework_high_speed[DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 8] = MSB(length);
269 
270     /* Modify class settings.  */
271     class = &_ux_system_slave->ux_system_slave_class_array[0];
272     hid_class = (UX_SLAVE_CLASS_HID*)class->ux_slave_class_instance;
273 
274     hid_class->ux_device_class_hid_report_address = descriptor;
275     hid_class->ux_device_class_hid_report_length  = length;
276 }
277 
278 /* Define what the initial system looks like.  */
279 
280 #ifdef CTEST
test_application_define(void * first_unused_memory)281 void test_application_define(void *first_unused_memory)
282 #else
283 void    usbx_ux_device_class_hid_descriptor_send_test_application_define(void *first_unused_memory)
284 #endif
285 {
286 
287 UINT status;
288 CHAR *                          stack_pointer;
289 CHAR *                          memory_pointer;
290 
291 
292     /* Inform user.  */
293     printf("Running ux_device_class_descriptor_send test........................ ");
294 
295     /* Initialize the free memory pointer */
296     stack_pointer = (CHAR *) usbx_memory;
297     memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
298 
299     /* Initialize USBX. Memory */
300     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
301 
302     /* Check for error.  */
303     if (status != UX_SUCCESS)
304     {
305 
306         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
307         test_control_return(1);
308     }
309 
310     /* Register the error callback. */
311     _ux_utility_error_callback_register(error_callback);
312 
313     /* The code below is required for installing the host portion of USBX */
314     status =  ux_host_stack_initialize(ux_system_host_change_function);
315     if (status != UX_SUCCESS)
316     {
317 
318         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
319         test_control_return(1);
320     }
321 
322     status =  ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
323     if (status != UX_SUCCESS)
324     {
325 
326         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
327         test_control_return(1);
328     }
329 
330     /* Register the HID client(s).  */
331     status =  ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry);
332     if (status != UX_SUCCESS)
333     {
334 
335         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
336         test_control_return(1);
337     }
338 
339     /* The code below is required for installing the device portion of USBX. No call back for
340        device status change in this example. */
341     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
342                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
343                                        string_framework, STRING_FRAMEWORK_LENGTH,
344                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
345     if(status!=UX_SUCCESS)
346     {
347 
348         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
349         test_control_return(1);
350     }
351 
352     /* Initialize the hid class parameters.  */
353     hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
354     hid_parameter.ux_device_class_hid_parameter_report_length  = HID_REPORT_LENGTH;
355     hid_parameter.ux_device_class_hid_parameter_callback       = demo_thread_hid_callback;
356 
357     /* Initilize the device hid class. The class is connected with interface 2 */
358     status =  ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
359                                                 1,2, (VOID *)&hid_parameter);
360     if(status!=UX_SUCCESS)
361     {
362 
363         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
364         test_control_return(1);
365     }
366 
367     /* Initialize the simulated device controller.  */
368     status =  _ux_dcd_sim_slave_initialize();
369 
370     /* Check for error.  */
371     if (status != UX_SUCCESS)
372     {
373 
374         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
375         test_control_return(1);
376     }
377 
378     /* Register all the USB host controllers available in this system */
379     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
380 
381     /* Check for error.  */
382     if (status != UX_SUCCESS)
383     {
384 
385         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
386         test_control_return(1);
387     }
388 
389     /* Create the main host simulation thread.  */
390     status =  tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
391             stack_pointer, UX_DEMO_STACK_SIZE,
392             20, 20, 1, TX_AUTO_START);
393 
394     /* Check for error.  */
395     if (status != TX_SUCCESS)
396     {
397 
398         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
399         test_control_return(1);
400     }
401 }
402 
tx_demo_thread_host_simulation_entry(ULONG arg)403 static void  tx_demo_thread_host_simulation_entry(ULONG arg)
404 {
405 
406 UINT                            status;
407 UX_HOST_CLASS_HID_KEYBOARD     *keyboard;
408 UX_ENDPOINT                    *endpoint;
409 UX_TRANSFER                    *transfer_request;
410 UCHAR                           descriptor[1024];
411 UCHAR                          *hid_class_descriptor = device_framework_high_speed + 0x2E;
412 UCHAR                          *hid_class_descriptor_1 = device_framework_high_speed + 0x2E + 9 + 7 + 9;
413 ALIGN_TYPE                      tmp;
414 
415     /* Find the HID class */
416     status = demo_class_hid_get();
417     if (status != UX_SUCCESS)
418     {
419 
420         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
421         test_control_return(1);
422     }
423 
424     /* Get the HID client */
425     hid_client = hid -> ux_host_class_hid_client;
426 
427     /* Check if the instance of the keyboard is live */
428     while (hid_client -> ux_host_class_hid_client_local_instance == UX_NULL)
429         tx_thread_sleep(10);
430 
431     /* Get the keyboard instance */
432     keyboard =  (UX_HOST_CLASS_HID_KEYBOARD *)hid_client -> ux_host_class_hid_client_local_instance;
433 
434     /* Get default endpoint. */
435     endpoint = &hid->ux_host_class_hid_device->ux_device_control_endpoint;
436 
437     /* Get the transfer request. */
438     transfer_request = &endpoint->ux_endpoint_transfer_request;
439 
440     /**************************************************/
441     /** Test case: 'case: UX_DEVICE_CLASS_HID_DESCRIPTOR_HID', index error **/
442     /**************************************************/
443 
444     /* Create a transfer request for the HID class descriptor.  */
445     transfer_request -> ux_transfer_request_data_pointer =      descriptor;
446     transfer_request -> ux_transfer_request_requested_length =  0x09;
447     transfer_request -> ux_transfer_request_function =          UX_GET_DESCRIPTOR;
448     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
449     transfer_request -> ux_transfer_request_value =             UX_HOST_CLASS_HID_DESCRIPTOR << 8;
450     transfer_request -> ux_transfer_request_index =             0x00;
451 
452     /* Send request to HCD layer.  */
453     status = ux_host_stack_transfer_request(transfer_request);
454     if (status != UX_TRANSFER_STALLED)
455     {
456 
457         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
458         test_control_return(1);
459     }
460 
461     /**************************************************/
462     /** Test case: 'case: UX_DEVICE_CLASS_HID_DESCRIPTOR_HID' **/
463     /**************************************************/
464 
465     /* Create a transfer request for the HID class descriptor.  */
466     transfer_request -> ux_transfer_request_data_pointer =      descriptor;
467     transfer_request -> ux_transfer_request_requested_length =  0x09;
468     transfer_request -> ux_transfer_request_function =          UX_GET_DESCRIPTOR;
469     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
470     transfer_request -> ux_transfer_request_value =             UX_HOST_CLASS_HID_DESCRIPTOR << 8;
471     transfer_request -> ux_transfer_request_index =             0x02;
472 
473     /* Send request to HCD layer.  */
474     status = ux_host_stack_transfer_request(transfer_request);
475     if (status != UX_SUCCESS)
476     {
477 
478         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
479         test_control_return(1);
480     }
481 
482     /* Make sure we received the correct number of bytes. */
483     if(transfer_request->ux_transfer_request_actual_length != 0x09)
484     {
485 
486         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
487         test_control_return(1);
488     }
489 
490     /* Make sure we received it correctly. */
491     status = memcmp(transfer_request -> ux_transfer_request_data_pointer, hid_class_descriptor, transfer_request -> ux_transfer_request_actual_length);
492     if(status)
493     {
494 
495         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
496         test_control_return(1);
497     }
498 
499     /**************************************************/
500     /** Test case: 'case: UX_DEVICE_CLASS_HID_DESCRIPTOR_HID' **/
501     /**************************************************/
502 
503     /* Create a transfer request for the HID class descriptor.  */
504     transfer_request -> ux_transfer_request_data_pointer =      descriptor;
505     transfer_request -> ux_transfer_request_requested_length =  0x09;
506     transfer_request -> ux_transfer_request_function =          UX_GET_DESCRIPTOR;
507     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
508     transfer_request -> ux_transfer_request_value =             UX_HOST_CLASS_HID_DESCRIPTOR << 8;
509     transfer_request -> ux_transfer_request_index =             0x01;
510 
511     /* Send request to HCD layer.  */
512     status = _ux_host_stack_transfer_request(transfer_request);
513     if (status != UX_SUCCESS)
514     {
515 
516         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
517         test_control_return(1);
518     }
519 
520     /* Make sure we received the correct number of bytes. */
521     if(transfer_request->ux_transfer_request_actual_length != 0x09)
522     {
523 
524         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
525         test_control_return(1);
526     }
527 
528     /* Make sure we received it correctly. */
529     status = memcmp(transfer_request -> ux_transfer_request_data_pointer, hid_class_descriptor_1, transfer_request -> ux_transfer_request_actual_length);
530     if(status)
531     {
532 
533         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
534         test_control_return(1);
535     }
536 
537     /**************************************************/
538     /** Test case: 'if (descriptor_length < host_length)' in 'case: UX_DEVICE_CLASS_HID_DESCRIPTOR_HID' **/
539     /**************************************************/
540 
541     /* Create a transfer request for the HID class descriptor.  */
542     transfer_request -> ux_transfer_request_data_pointer =      descriptor;
543     transfer_request -> ux_transfer_request_requested_length =  2*0x09;
544     transfer_request -> ux_transfer_request_function =          UX_GET_DESCRIPTOR;
545     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
546     transfer_request -> ux_transfer_request_value =             UX_HOST_CLASS_HID_DESCRIPTOR << 8;
547     transfer_request -> ux_transfer_request_index =             0x02;
548 
549     /* Send request to HCD layer.  */
550     status = ux_host_stack_transfer_request(transfer_request);
551     if (status != UX_SUCCESS)
552     {
553 
554         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
555         test_control_return(1);
556     }
557 
558     /* Make sure we received the correct number of bytes. */
559     if(transfer_request->ux_transfer_request_actual_length != 0x09)
560     {
561 
562         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
563         test_control_return(1);
564     }
565 
566     /* Make sure we received it correctly. */
567     if(memcmp(transfer_request -> ux_transfer_request_data_pointer, hid_class_descriptor, transfer_request -> ux_transfer_request_actual_length))
568     {
569 
570         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
571         test_control_return(1);
572     }
573 
574     /**************************************************/
575     /** Test case: 'if (descriptor_length < host_length)' in 'case UX_DEVICE_CLASS_HID_DESCRIPTOR_REPORT:' **/
576     /**************************************************/
577 
578     /* Create a transfer request for getting report descriptor. Make sure we request a length greater than it really is.  */
579     transfer_request -> ux_transfer_request_data_pointer =      descriptor;
580     transfer_request -> ux_transfer_request_requested_length =  2*HID_REPORT_LENGTH;
581     transfer_request -> ux_transfer_request_function =          UX_GET_DESCRIPTOR;
582     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
583     transfer_request -> ux_transfer_request_value =             UX_HOST_CLASS_HID_REPORT_DESCRIPTOR << 8;
584     transfer_request -> ux_transfer_request_index =             0x02;
585 
586     /* Send request to HCD layer.  */
587     status = ux_host_stack_transfer_request(transfer_request);
588     if (status != UX_SUCCESS)
589     {
590 
591         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
592         test_control_return(1);
593     }
594 
595     /* Make sure we received the correct number of bytes. */
596     if(transfer_request->ux_transfer_request_actual_length != HID_REPORT_LENGTH)
597     {
598 
599         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
600         test_control_return(1);
601     }
602 
603     /* Make sure we received it correctly. */
604     if (memcmp(transfer_request->ux_transfer_request_data_pointer, hid_report_descriptor, transfer_request->ux_transfer_request_actual_length))
605     {
606 
607         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
608         test_control_return(1);
609     }
610 
611     /**************************************************/
612     /** Test case: 'if (device_framework_length <= descriptor_length)' **/
613     /**************************************************/
614 
615     /* Create a transfer request for the HID class descriptor.  */
616     transfer_request -> ux_transfer_request_data_pointer =      descriptor;
617     transfer_request -> ux_transfer_request_requested_length =  0x09;
618     transfer_request -> ux_transfer_request_function =          UX_GET_DESCRIPTOR;
619     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
620     transfer_request -> ux_transfer_request_value =             UX_HOST_CLASS_HID_DESCRIPTOR << 8;
621     transfer_request -> ux_transfer_request_index =             0x02;
622 
623     /* Corrupt the device framework. */
624     tmp = (ALIGN_TYPE)_ux_system_slave -> ux_system_slave_device_framework;
625     _ux_system_slave -> ux_system_slave_device_framework = corrupted_device_framework;
626 
627     /* Send request to HCD layer.  */
628     status = ux_host_stack_transfer_request(transfer_request);
629     if (status != UX_TRANSFER_STALLED)
630     {
631 
632         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
633         test_control_return(1);
634     }
635 
636     /* Restore device framework. */
637     _ux_system_slave -> ux_system_slave_device_framework = (UCHAR *)tmp;
638 
639     /**************************************************/
640     /** Test case: 'if (hid_descriptor_length > UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH)' **/
641     /**************************************************/
642 #if UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH > 255
643 #warning (hid_descriptor_length > UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH) not tested due to buffer size too big
644 #else
645 
646     /* Create a transfer request for the HID class descriptor.  */
647     transfer_request -> ux_transfer_request_data_pointer =      descriptor;
648     transfer_request -> ux_transfer_request_requested_length =  UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH + 1;
649     transfer_request -> ux_transfer_request_function =          UX_GET_DESCRIPTOR;
650     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
651     transfer_request -> ux_transfer_request_value =             UX_HOST_CLASS_HID_DESCRIPTOR << 8;
652     transfer_request -> ux_transfer_request_index =             0x02;
653 
654     /* Corrupt the device framework. */
655     tmp = (ALIGN_TYPE)_ux_system_slave -> ux_system_slave_device_framework;
656     _ux_system_slave -> ux_system_slave_device_framework = corrupted_device_framework_hid;
657 
658     /* Send request to HCD layer.  */
659     status = ux_host_stack_transfer_request(transfer_request);
660     if (status != UX_TRANSFER_STALLED)
661     {
662 
663         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
664         test_control_return(1);
665     }
666 
667     /* Restore device framework. */
668     _ux_system_slave -> ux_system_slave_device_framework = (UCHAR *)tmp;
669 #endif
670 
671     /**************************************************/
672     /** Test case: 'default:' **/
673     /**************************************************/
674 
675     /* Create a transfer request for an unknown request.  */
676     transfer_request -> ux_transfer_request_data_pointer =      descriptor;
677     transfer_request -> ux_transfer_request_requested_length =  0x09;
678     transfer_request -> ux_transfer_request_function =          UX_GET_DESCRIPTOR;
679     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_DEVICE;
680     transfer_request -> ux_transfer_request_value =             0xffff << 8;
681     transfer_request -> ux_transfer_request_index =             0x02;
682 
683     /* Send request to HCD layer.  */
684     status = ux_host_stack_transfer_request(transfer_request);
685     if (status != UX_TRANSFER_STALLED)
686     {
687 
688         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
689         test_control_return(1);
690     }
691 
692     /**************************************************/
693     /** Test case: 'if (length > UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH)' in 'case UX_DEVICE_CLASS_HID_DESCRIPTOR_REPORT:' **/
694     /**************************************************/
695 
696     /* Specific "long" descriptor.  */
697     set_hid_descriptor(hid_report_descriptor, UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH + 1);
698 
699     /* Create a transfer request for getting report descriptor. Make sure we request a length greater than it really is.  */
700     transfer_request -> ux_transfer_request_data_pointer =      descriptor;
701     transfer_request -> ux_transfer_request_requested_length =  UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH + 1;
702     transfer_request -> ux_transfer_request_function =          UX_GET_DESCRIPTOR;
703     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
704     transfer_request -> ux_transfer_request_value =             UX_HOST_CLASS_HID_REPORT_DESCRIPTOR << 8;
705     transfer_request -> ux_transfer_request_index =             0x02;
706 
707     /* Send request to HCD layer.  */
708     status = ux_host_stack_transfer_request(transfer_request);
709     if (status == UX_SUCCESS)
710     {
711 
712         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
713         test_control_return(1);
714     }
715 
716     /* Revert "long" descriptor.  */
717     set_hid_descriptor(hid_report_descriptor, HID_REPORT_LENGTH);
718 
719     /* Now disconnect the device.  */
720     _ux_device_stack_disconnect();
721 
722     /* And deinitialize the class.  */
723     status =  ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
724 
725     /* Deinitialize the device side of usbx.  */
726     _ux_device_stack_uninitialize();
727 
728     /* And finally the usbx system resources.  */
729     _ux_system_uninitialize();
730 
731     /* Successful test.  */
732     printf("SUCCESS!\n");
733     test_control_return(0);
734 }
735 
demo_thread_hid_callback(UX_SLAVE_CLASS_HID * class,UX_SLAVE_CLASS_HID_EVENT * event)736 static UINT    demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
737 {
738     return(UX_SUCCESS);
739 }
740