1 /* This test is designed to test the simple dpump host/device class operation.  */
2 
3 #include <stdio.h>
4 #include "tx_api.h"
5 #include "ux_api.h"
6 #include "ux_system.h"
7 #include "ux_utility.h"
8 
9 #include "fx_api.h"
10 
11 #include "ux_device_class_cdc_acm.h"
12 #include "ux_device_stack.h"
13 
14 #include "ux_host_class_cdc_acm.h"
15 #include "ux_host_stack.h"
16 
17 #include "ux_host_class_hid.h"
18 #include "ux_device_class_hid.h"
19 
20 #include "ux_host_class_storage.h"
21 #include "ux_device_class_storage.h"
22 
23 #include "ux_test_dcd_sim_slave.h"
24 #include "ux_test_hcd_sim_host.h"
25 #include "ux_test_utility_sim.h"
26 
27 /* Define constants.  */
28 #define                             UX_CDC_ACM_CONNECTION_DELAY ((UX_RH_ENUMERATION_RETRY + 1)*UX_HOST_CLASS_CDC_ACM_DEVICE_INIT_DELAY)
29 #define                             UX_DEMO_DEBUG_SIZE  (4096*8)
30 #define                             UX_DEMO_STACK_SIZE  1024
31 #define                             UX_DEMO_BUFFER_SIZE (UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1)
32 #define                             UX_DEMO_XMIT_BUFFER_SIZE 512
33 #define                             UX_DEMO_RECEPTION_BUFFER_SIZE 512
34 #define                             UX_DEMO_FILE_BUFFER_SIZE 512
35 #define                             UX_DEMO_RECEPTION_BLOCK_SIZE 64
36 #define                             UX_DEMO_MEMORY_SIZE     (96*1024)
37 #define                             UX_DEMO_FILE_SIZE       (128 * 1024)
38 #define                             UX_RAM_DISK_MEMORY      (256 * 1024)
39 
40 #define                             UX_DEMO_VENDOR_REQUEST 0x54
41 
42 /* Define local/extern function prototypes.  */
43 static VOID                                test_thread_entry(ULONG);
44 static TX_THREAD                           tx_test_thread_simulation0;
45 static TX_THREAD                           tx_test_thread_simulation1;
46 static VOID                                tx_test_thread_simulation0_entry(ULONG);
47 static VOID                                tx_test_thread_simulation1_entry(ULONG);
48 static VOID                                test_cdc_instance_activate(VOID  *cdc_instance);
49 static VOID                                test_cdc_instance_deactivate(VOID *cdc_instance);
50 static VOID                                test_cdc_instance_parameter_change(VOID *cdc_instance);
51 
52 static VOID                                ux_test_hcd_entry_should_not_be_called(UX_TEST_ACTION *action, VOID *params);
53 static VOID                                ux_test_hcd_entry_disconnect(UX_TEST_ACTION *action, VOID *params);
54 static VOID                                ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params);
55 
56 static UINT                                test_ux_device_class_cdc_acm_entry(UX_SLAVE_CLASS_COMMAND *command);
57 
58 static UINT                                test_ms_vendor_request(ULONG request, ULONG request_value, ULONG request_index, ULONG request_length,
59                                                                   UCHAR *transfer_request_buffer, ULONG *transfer_request_length);
60 
61 static VOID                                ux_test_dcd_entry_is_called(UX_TEST_ACTION *action, VOID *params);
62 
63 static UINT test_ux_device_class_cdc_acm_read_halt(UX_SLAVE_CLASS_CDC_ACM *cdc_acm);
64 
65 static UINT test_ux_host_class_cdc_acm_write(UX_HOST_CLASS_CDC_ACM *cdc_acm, UCHAR *data_pointer,
66                                     ULONG requested_length, ULONG *actual_length);
67 static UINT test_ux_host_class_cdc_acm_write_halt_clear(UX_HOST_CLASS_CDC_ACM *cdc_acm);
68 
69 
70 /* Define global data structures.  */
71 static UCHAR                               usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
72 static UX_HOST_CLASS                       *class_driver;
73 static UX_HOST_CLASS_CDC_ACM               *cdc_acm_host_control;
74 static UX_HOST_CLASS_CDC_ACM               *cdc_acm_host_data;
75 
76 static UX_SLAVE_CLASS_CDC_ACM              *cdc_acm_slave;
77 static UCHAR                               cdc_acm_slave_change;
78 static UX_SLAVE_CLASS_CDC_ACM_PARAMETER    parameter;
79 static UCHAR                               cdc_acm_slave_reading = UX_TRUE;
80 
81 static UCHAR                               buffer[UX_DEMO_BUFFER_SIZE];
82 
83 static ULONG                               error_counter;
84 
85 static ULONG                               set_cfg_counter;
86 
87 static ULONG                               rsc_mem_alloc_cnt_on_set_cfg;
88 static ULONG                               rsc_sem_on_set_cfg;
89 static ULONG                               rsc_sem_get_on_set_cfg;
90 static ULONG                               rsc_mutex_on_set_cfg;
91 
92 static ULONG                               rsc_enum_mem_alloc_count;
93 static ULONG                               rsc_enum_sem_usage;
94 static ULONG                               rsc_enum_sem_get_count;
95 static ULONG                               rsc_enum_mutex_usage;
96 
97 static UINT                                class_entry_rc = UX_SUCCESS;
98 
99 static UINT                                vendor_req_rc = UX_SUCCESS;
100 
101 static UX_SLAVE_CLASS_HID_PARAMETER        hid_parameter;
102 
103 /* HID mouse related descriptors */
104 
105 static UCHAR hid_mouse_report[] = {
106 
107     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
108     0x09, 0x02,                    // USAGE (Mouse)
109     0xa1, 0x01,                    // COLLECTION (Application)
110     0x09, 0x01,                    //   USAGE (Pointer)
111     0xa1, 0x00,                    //   COLLECTION (Physical)
112     0x05, 0x09,                    //     USAGE_PAGE (Button)
113     0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
114     0x29, 0x03,                    //     USAGE_MAXIMUM (Button 3)
115     0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
116     0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
117     0x95, 0x03,                    //     REPORT_COUNT (3)
118     0x75, 0x01,                    //     REPORT_SIZE (1)
119     0x81, 0x02,                    //     INPUT (Data,Var,Abs)
120     0x95, 0x01,                    //     REPORT_COUNT (1)
121     0x75, 0x05,                    //     REPORT_SIZE (5)
122     0x81, 0x03,                    //     INPUT (Cnst,Var,Abs)
123     0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
124     0x09, 0x30,                    //     USAGE (X)
125     0x09, 0x31,                    //     USAGE (Y)
126     0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
127     0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
128     0x75, 0x08,                    //     REPORT_SIZE (8)
129     0x95, 0x02,                    //     REPORT_COUNT (2)
130     0x81, 0x06,                    //     INPUT (Data,Var,Rel)
131     0x09, 0x38,                    //     USAGE (Mouse Wheel)
132     0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
133     0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
134     0x75, 0x08,                    //     REPORT_SIZE (8)
135     0x95, 0x01,                    //     REPORT_COUNT (1)
136     0x81, 0x06,                    //     INPUT (Data,Var,Rel)
137     0xc0,                          //   END_COLLECTION
138     0xc0                           // END_COLLECTION
139 };
140 #define HID_MOUSE_REPORT_LENGTH (sizeof(hid_mouse_report)/sizeof(hid_mouse_report[0]))
141 
142 #define     LSB(x) (x & 0x00ff)
143 #define     MSB(x) ((x & 0xff00) >> 8)
144 
145 /* HID Mouse interface descriptors 9+9+7=25 bytes */
146 #define HID_MOUSE_IFC_DESC_ALL(ifc, interrupt_epa)     \
147     /* Interface descriptor */\
148         0x09, 0x04, (ifc), 0x00, 0x01, 0x03, 0x00, 0x00, 0x00,\
149     /* HID descriptor */\
150         0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_MOUSE_REPORT_LENGTH),\
151         MSB(HID_MOUSE_REPORT_LENGTH),\
152     /* Endpoint descriptor (Interrupt) */\
153         0x07, 0x05, (interrupt_epa), 0x03, 0x08, 0x00, 0x08,
154 #define HID_MOUSE_IFC_DESC_ALL_LEN 25
155 
156 /* Storage related descriptors 9+7+7=23 bytes */
157 #define MS_IFC_DESC_ALL(ifc, bulk_in_epa, bulk_out_epa) \
158     /* Interface descriptor */\
159         0x09, 0x04, (ifc), 0x00, 0x03, 0x08, 0x06, 0x50, 0x00,\
160     /* Endpoint descriptor (Bulk In) */\
161         0x07, 0x05, (bulk_in_epa), 0x02, 0x40, 0x00, 0x00,\
162     /* Endpoint descriptor (Bulk Out) */\
163         0x07, 0x05, (bulk_out_epa), 0x02, 0x40, 0x00, 0x00,
164 #define MS_IFC_DESC_ALL_LEN 23
165 
166 /* CDC IAD 8 bytes */
167 #define CDC_IAD_DESC(comm_ifc) \
168     /* Interface association descriptor. 8 bytes.  */\
169     0x08, 0x0b, (comm_ifc), 0x02, 0x02, 0x02, 0x00, 0x00,
170 #define CDC_IAD_DESC_LEN 8
171 
172 /* CDC Communication interface descriptors 9+5+4+5+5+7=35 bytes */
173 #define CDC_COMM_IFC_DESC_ALL(comm_ifc, data_ifc, interrupt_epa) \
174     /* Communication Class Interface Descriptor. 9 bytes. */\
175     0x09, 0x04, (comm_ifc), 0x00, 0x01, 0x02, 0x02, 0x01, 0x00,\
176     /* Header Functional Descriptor 5 bytes */\
177     0x05, 0x24, 0x00, 0x10, 0x01,\
178     /* ACM Functional Descriptor 4 bytes */\
179     0x04, 0x24, 0x02, 0x0f,\
180     /* Union Functional Descriptor 5 bytes */\
181     0x05, 0x24, 0x06,\
182     (comm_ifc),                          /* Master interface */\
183     (data_ifc),                          /* Slave interface  */\
184     /* Call Management Functional Descriptor 5 bytes */\
185     0x05, 0x24, 0x01, 0x03,\
186     (data_ifc),                          /* Data interface   */\
187     /* Endpoint 0x83 descriptor 7 bytes */\
188     0x07, 0x05, (interrupt_epa),\
189     0x03,\
190     0x08, 0x00,\
191     15,
192 #define CDC_COMM_IFC_DESC_ALL_LEN 35
193 
194 /* CDC Data interface descriptors 9+7+7=23 bytes */
195 #define CDC_DATA_IFC_DESC_ALL(ifc, bulk_in_epa, bulk_out_epa) \
196     /* Data Class Interface Descriptor Requirement 9 bytes */\
197     0x09, 0x04, (ifc),\
198     0x00, /* bAlternateSetting */\
199     0x02, /* bNumEndpoints */\
200     0x0A, 0x00, 0x00,\
201     0x00,\
202     /* Endpoint bulk IN descriptor 7 bytes */\
203     0x07, 0x05, (bulk_in_epa),\
204     0x02,\
205     0x40, 0x00,\
206     0x00,\
207     /* Endpoint bulk OUT descriptor 7 bytes */\
208     0x07, 0x05, (bulk_out_epa),\
209     0x02,\
210     0x40, 0x00,\
211     0x00,
212 #define CDC_DATA_IFC_DESC_ALL_LEN 23
213 
214 /* Configuration descriptor 9 bytes */
215 #define CFG_DESC(wTotalLength, bNumInterfaces, bConfigurationValue)\
216     /* Configuration 1 descriptor 9 bytes */\
217     0x09, 0x02, LSB(wTotalLength), MSB(wTotalLength),\
218     (bNumInterfaces), (bConfigurationValue), 0x00,\
219     0x40, 0x00,
220 #define CFG_DESC_LEN 9
221 
222 /* Define device framework.  */
223 
224 static unsigned char device_framework_full_speed[] = {
225 
226     /* Device descriptor     18 bytes
227        0x02 bDeviceClass:    CDC class code
228        0x00 bDeviceSubclass: CDC class sub code
229        0x00 bDeviceProtocol: CDC Device protocol
230 
231        idVendor & idProduct - http://www.linux-usb.org/usb.ids
232     */
233     0x12, 0x01, 0x10, 0x01,
234     0xEF, 0x02, 0x01,
235     0x08,
236     0x84, 0x84, 0x00, 0x00,
237     0x00, 0x01,
238     0x01, 0x02, 03,
239     0x01, /* bNumConfigurations */
240 
241     /* Configuration 1 descriptor 9 bytes */
242     0x09, 0x02, 0x4b, 0x00,
243     0x02, 0x01, 0x00,
244     0xE0, 0x00,
245 
246     /* Interface association descriptor. 8 bytes.  */
247     0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
248 
249     /* Communication Class Interface Descriptor. 9 bytes.   */
250     0x09, 0x04, 0x00,
251     0x00,
252     0x01,
253     0x02, 0x02, 0x01,
254     0x00,
255 
256     /* Header Functional Descriptor 5 bytes */
257     0x05, 0x24, 0x00,
258     0x10, 0x01,
259 
260     /* ACM Functional Descriptor 4 bytes */
261     0x04, 0x24, 0x02,
262     0x0f,
263 
264     /* Union Functional Descriptor 5 bytes */
265     0x05, 0x24, 0x06,
266     0x00,                          /* Master interface */
267     0x01,                          /* Slave interface  */
268 
269     /* Call Management Functional Descriptor 5 bytes */
270     0x05, 0x24, 0x01,
271     0x03,
272     0x01,                          /* Data interface   */
273 
274     /* Endpoint 0x83 descriptor 7 bytes */
275     0x07, 0x05, 0x83,
276     0x03,
277     0x08, 0x00,
278     0xFF,
279 
280     /* Data Class Interface Descriptor Requirement 9 bytes */
281     0x09, 0x04, 0x01,
282     0x00,
283     0x02,
284     0x0A, 0x00, 0x00,
285     0x00,
286 
287     /* Endpoint 0x81 descriptor 7 bytes */
288     0x07, 0x05, 0x81,
289     0x02,
290     0x40, 0x00,
291     0x00,
292 
293     /* Endpoint 0x02 descriptor 7 bytes */
294     0x07, 0x05, 0x02,
295     0x02,
296     0x40, 0x00,
297     0x00,
298 
299     /* Configuration 2 descriptor 9 bytes */
300     0x09, 0x02, (0x4b + 28 + 46), 0x00,
301     0x02, 0x02, 0x00,
302     0x40, 0x00,
303 
304     /* Interface association descriptor. 8 bytes.  */
305     0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
306 
307     /* Communication Class Interface Descriptor Requirement. 9 bytes.   */
308     0x09, 0x04, 0x00,
309     0x00, /* bAlternateSetting */
310     0x00, /* bNumEndpoints */
311     0x02, 0x02, 0x01,
312     0x00,
313 
314     /* Header Functional Descriptor 5 bytes */
315     0x05, 0x24, 0x00,
316     0x10, 0x01,
317 
318     /* ACM Functional Descriptor 4 bytes */
319     0x04, 0x24, 0x02,
320     0x0f,
321 
322     /* Union Functional Descriptor 5 bytes */
323     0x05, 0x24, 0x06,
324     0x00,                          /* Master interface */
325     0x01,                          /* Slave interface  */
326 
327     /* Call Management Functional Descriptor 5 bytes */
328     0x05, 0x24, 0x01,
329     0x03,
330     0x01,                          /* Data interface   */
331 
332     /* Communication Class Interface Descriptor Requirement. 9 bytes.   */
333     0x09, 0x04, 0x00,
334     0x01, /* bAlternateSetting */
335     0x01, /* bNumEndpoints */
336     0x02, 0x02, 0x01,
337     0x00,
338 
339     /* Header Functional Descriptor 5 bytes */
340     0x05, 0x24, 0x00,
341     0x10, 0x01,
342 
343     /* ACM Functional Descriptor 4 bytes */
344     0x04, 0x24, 0x02,
345     0x0f,
346 
347     /* Union Functional Descriptor 5 bytes */
348     0x05, 0x24, 0x06,
349     0x00,                          /* Master interface */
350     0x01,                          /* Slave interface  */
351 
352     /* Call Management Functional Descriptor 5 bytes */
353     0x05, 0x24, 0x01,
354     0x03,
355     0x01,                          /* Data interface   */
356 
357     /* Endpoint 0x83 descriptor 7 bytes */
358     0x07, 0x05, 0x83,
359     0x03,
360     0x08, 0x00,
361     0xFF,
362 
363     /* Data Class Interface Descriptor Requirement 9 bytes */
364     0x09, 0x04, 0x01,
365     0x00, /* bAlternateSetting */
366     0x00, /* bNumEndpoints */
367     0x0A, 0x00, 0x00,
368     0x00,
369 
370     /* Data Class Interface Descriptor Requirement 9 bytes */
371     0x09, 0x04, 0x01,
372     0x01, /* bAlternateSetting */
373     0x02, /* bNumEndpoints */
374     0x0A, 0x00, 0x00,
375     0x00,
376 
377     /* Endpoint 0x81 descriptor 7 bytes */
378     0x07, 0x05, 0x81,
379     0x02,
380     0x40, 0x00,
381     0x00,
382 
383     /* Endpoint 0x02 descriptor 7 bytes */
384     0x07, 0x05, 0x02,
385     0x02,
386     0x40, 0x00,
387     0x00,
388 
389     /* Data Class Interface Descriptor Requirement 9 bytes */
390     0x09, 0x04, 0x01,
391     0x02, /* bAlternateSetting */
392     0x04, /* bNumEndpoints */
393     0x0A, 0x00, 0x00,
394     0x00,
395 
396     /* Endpoint 0x81 descriptor 7 bytes */
397     0x07, 0x05, 0x81,
398     0x02,
399     0x40, 0x00,
400     0x00,
401 
402     /* Endpoint 0x02 descriptor 7 bytes */
403     0x07, 0x05, 0x02,
404     0x02,
405     0x40, 0x00,
406     0x00,
407 
408     /* Endpoint 0x85 descriptor 7 bytes */
409     0x07, 0x05, 0x85,
410     0x02,
411     0x40, 0x00,
412     0x00,
413 
414     /* Endpoint 0x04 descriptor 7 bytes */
415     0x07, 0x05, 0x04,
416     0x02,
417     0x40, 0x00,
418     0x00,
419 
420     /* Configuration 3: CDC + CDC */
421     CFG_DESC(CFG_DESC_LEN+2*(CDC_IAD_DESC_LEN+CDC_COMM_IFC_DESC_ALL_LEN+CDC_DATA_IFC_DESC_ALL_LEN), 4, 3)
422     CDC_IAD_DESC(0)
423     CDC_COMM_IFC_DESC_ALL(0, 1, 0x83)
424     CDC_DATA_IFC_DESC_ALL(1, 0x81, 0x02)
425     CDC_IAD_DESC(2)
426     CDC_COMM_IFC_DESC_ALL(2, 3, 0x86)
427     CDC_DATA_IFC_DESC_ALL(3, 0x84, 0x05)
428 
429     /* Configuration 4: HID + HID */
430     CFG_DESC(CFG_DESC_LEN+2*(HID_MOUSE_IFC_DESC_ALL_LEN), 2, 4)
431     HID_MOUSE_IFC_DESC_ALL(0, 0x81)
432     HID_MOUSE_IFC_DESC_ALL(1, 0x82)
433 
434 };
435 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
436 
437 static unsigned char device_framework_high_speed[] = {
438 
439     /* Device descriptor
440        0x02 bDeviceClass:    CDC class code
441        0x00 bDeviceSubclass: CDC class sub code
442        0x00 bDeviceProtocol: CDC Device protocol
443 
444        idVendor & idProduct - http://www.linux-usb.org/usb.ids
445     */
446     0x12, 0x01, 0x00, 0x02,
447     0xEF, 0x02, 0x01,
448     0x40,
449     0x84, 0x84, 0x00, 0x00,
450     0x00, 0x01,
451     0x01, 0x02, 03,
452     0x01, /* bNumConfigurations */
453 
454     /* Device qualifier descriptor */
455     0x0a, 0x06, 0x00, 0x02,
456     0x02, 0x00, 0x00,
457     0x40,
458     0x01,
459     0x00,
460 
461     /* Configuration 1 descriptor */
462     0x09, 0x02, (0x4b+5), 0x00,
463     0x02, 0x01, 0x00,
464     0xE0, 0x00,
465 
466     /* OTG Descriptor.  */
467     0x05, 0x09, 0x03, 0x02, 0x00,
468 
469     /* Interface association descriptor. */
470     0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
471 
472     /* Communication Class Interface Descriptor Requirement */
473     0x09, 0x04, 0x00,
474     0x00,
475     0x01,
476     0x02, 0x02, 0x01,
477     0x00,
478 
479     /* Header Functional Descriptor */
480     0x05, 0x24, 0x00,
481     0x10, 0x01,
482 
483     /* ACM Functional Descriptor */
484     0x04, 0x24, 0x02,
485     0x0f,
486 
487     /* Union Functional Descriptor */
488     0x05, 0x24, 0x06,
489     0x00,
490     0x01,
491 
492     /* Call Management Functional Descriptor */
493     0x05, 0x24, 0x01,
494     0x00,
495     0x01,
496 
497     /* Endpoint 0x83 descriptor */
498     0x07, 0x05, 0x83,
499     0x03,
500     0x08, 0x00,
501     15,
502 
503     /* Data Class Interface Descriptor Requirement */
504     0x09, 0x04, 0x01,
505     0x00,
506     0x02,
507     0x0A, 0x00, 0x00,
508     0x00,
509 
510     /* Endpoint 0x81 descriptor */
511     0x07, 0x05, 0x81,
512     0x02,
513     0x40, 0x00,
514     0x00,
515 
516     /* Endpoint 0x02 descriptor */
517     0x07, 0x05, 0x02,
518     0x02,
519     0x40, 0x00,
520     0x00,
521 
522     /* Configuration 2 descriptor 9 bytes */
523     0x09, 0x02, (0x4b + 28 + 46), 0x00,
524     0x02, 0x02, 0x00,
525     0x40, 0x00,
526 
527     /* Interface association descriptor. 8 bytes.  */
528     0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
529 
530     /* Communication Class Interface Descriptor Requirement. 9 bytes.   */
531     0x09, 0x04, 0x00,
532     0x00, /* bAlternateSetting */
533     0x00, /* bNumEndpoints */
534     0x02, 0x02, 0x01,
535     0x00,
536 
537     /* Header Functional Descriptor 5 bytes */
538     0x05, 0x24, 0x00,
539     0x10, 0x01,
540 
541     /* ACM Functional Descriptor 4 bytes */
542     0x04, 0x24, 0x02,
543     0x0f,
544 
545     /* Union Functional Descriptor 5 bytes */
546     0x05, 0x24, 0x06,
547     0x00,                          /* Master interface */
548     0x01,                          /* Slave interface  */
549 
550     /* Call Management Functional Descriptor 5 bytes */
551     0x05, 0x24, 0x01,
552     0x03,
553     0x01,                          /* Data interface   */
554 
555     /* Communication Class Interface Descriptor Requirement. 9 bytes.   */
556     0x09, 0x04, 0x00,
557     0x01, /* bAlternateSetting */
558     0x01, /* bNumEndpoints */
559     0x02, 0x02, 0x01,
560     0x00,
561 
562     /* Header Functional Descriptor 5 bytes */
563     0x05, 0x24, 0x00,
564     0x10, 0x01,
565 
566     /* ACM Functional Descriptor 4 bytes */
567     0x04, 0x24, 0x02,
568     0x0f,
569 
570     /* Union Functional Descriptor 5 bytes */
571     0x05, 0x24, 0x06,
572     0x00,                          /* Master interface */
573     0x01,                          /* Slave interface  */
574 
575     /* Call Management Functional Descriptor 5 bytes */
576     0x05, 0x24, 0x01,
577     0x03,
578     0x01,                          /* Data interface   */
579 
580     /* Endpoint 0x83 descriptor 7 bytes */
581     0x07, 0x05, 0x83,
582     0x03,
583     0x08, 0x00,
584     15,
585 
586     /* Data Class Interface Descriptor Requirement 9 bytes */
587     0x09, 0x04, 0x01,
588     0x00,
589     0x00,
590     0x0A, 0x00, 0x00,
591     0x00,
592 
593     /* Data Class Interface Descriptor Requirement 9 bytes */
594     0x09, 0x04, 0x01,
595     0x01,
596     0x02,
597     0x0A, 0x00, 0x00,
598     0x00,
599 
600     /* Endpoint 0x81 descriptor 7 bytes */
601     0x07, 0x05, 0x81,
602     0x02,
603     0x40, 0x00,
604     0x00,
605 
606     /* Endpoint 0x02 descriptor 7 bytes */
607     0x07, 0x05, 0x02,
608     0x02,
609     0x40, 0x00,
610     0x00,
611 
612     /* Data Class Interface Descriptor Requirement 9 bytes */
613     0x09, 0x04, 0x01,
614     0x02, /* bAlternateSetting */
615     0x04, /* bNumEndpoints */
616     0x0A, 0x00, 0x00,
617     0x00,
618 
619     /* Endpoint 0x81 descriptor 7 bytes */
620     0x07, 0x05, 0x81,
621     0x02,
622     0x40, 0x00,
623     0x00,
624 
625     /* Endpoint 0x02 descriptor 7 bytes */
626     0x07, 0x05, 0x02,
627     0x02,
628     0x40, 0x00,
629     0x00,
630 
631     /* Endpoint 0x85 descriptor 7 bytes */
632     0x07, 0x05, 0x85,
633     0x02,
634     0x40, 0x00,
635     0x00,
636 
637     /* Endpoint 0x04 descriptor 7 bytes */
638     0x07, 0x05, 0x04,
639     0x02,
640     0x40, 0x00,
641     0x00,
642 
643     /* Configuration 3: CDC + CDC */
644     CFG_DESC(CFG_DESC_LEN+2*(CDC_IAD_DESC_LEN+CDC_COMM_IFC_DESC_ALL_LEN+CDC_DATA_IFC_DESC_ALL_LEN), 4, 3)
645     CDC_IAD_DESC(0)
646     CDC_COMM_IFC_DESC_ALL(0, 1, 0x83)
647     CDC_DATA_IFC_DESC_ALL(1, 0x81, 0x02)
648     CDC_IAD_DESC(2)
649     CDC_COMM_IFC_DESC_ALL(2, 3, 0x86)
650     CDC_DATA_IFC_DESC_ALL(3, 0x84, 0x05)
651 
652     /* Configuration 4: HID + HID */
653     CFG_DESC(CFG_DESC_LEN+2*(HID_MOUSE_IFC_DESC_ALL_LEN), 2, 4)
654     HID_MOUSE_IFC_DESC_ALL(0, 0x81)
655     HID_MOUSE_IFC_DESC_ALL(1, 0x82)
656 
657 };
658 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
659 
660 
661 static unsigned char string_framework[] = {
662 
663     /* Manufacturer string descriptor : Index 1 - "Express Logic" */
664         0x09, 0x04, 0x01, 0x0c,
665         0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x20, 0x4c,
666         0x6f, 0x67, 0x69, 0x63,
667 
668     /* Product string descriptor : Index 2 - "EL Composite device" */
669         0x09, 0x04, 0x02, 0x13,
670         0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
671         0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
672         0x69, 0x63, 0x65,
673 
674     /* Serial Number string descriptor : Index 3 - "0001" */
675         0x09, 0x04, 0x03, 0x04,
676         0x30, 0x30, 0x30, 0x31,
677 
678     /* Microsoft OS string descriptor : Index 0xEE. String is MSFT100.
679        The last byte is the vendor code used to filter Vendor specific commands.
680        The vendor commands will be executed in the class.
681        This code can be anything but must not be 0x66 or 0x67 which are PIMA class commands.  */
682         0x00, 0x00, 0xEE, 0x08,
683         0x4D, 0x53, 0x46, 0x54,
684         0x31, 0x30, 0x30,
685         UX_DEMO_VENDOR_REQUEST
686 };
687 #define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
688 
689 /* Multiple languages are supported on the device, to add
690     a language besides english, the unicode language code must
691     be appended to the language_id_framework array and the length
692     adjusted accordingly. */
693 static unsigned char language_id_framework[] = {
694 
695     /* English. */
696         0x09, 0x04
697 };
698 #define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
699 
700 /* Simulation actions. */
701 
702 static UX_TEST_SIM_ENTRY_ACTION dcd_transfer_is_called[] = {
703 /* function, request to match,
704    port action, port status,
705    request action, request EP, request data, request actual length, request status,
706    status, additional callback,
707    no_return */
708 {   UX_DCD_TRANSFER_REQUEST, NULL,
709         UX_FALSE, 0,
710         0         , 0, UX_NULL, 0, 0,
711         UX_ERROR , ux_test_dcd_entry_is_called},
712 {   0   }
713 };
714 
715 
716 /* Define the ISR dispatch.  */
717 
718 extern VOID    (*test_isr_dispatch)(void);
719 
720 
721 /* Prototype for test control return.  */
722 
723 void  test_control_return(UINT status);
724 
725 
726 /* Define the ISR dispatch routine.  */
727 
test_isr(void)728 static void test_isr(void)
729 {
730 
731     /* For further expansion of interrupt-level testing.  */
732 }
733 
ux_test_dcd_entry_is_called(UX_TEST_ACTION * action,VOID * params)734 static VOID ux_test_dcd_entry_is_called(UX_TEST_ACTION *action, VOID *params)
735 {
736     error_counter ++;
737 }
738 
test_ms_vendor_request(ULONG request,ULONG request_value,ULONG request_index,ULONG request_length,UCHAR * transfer_request_buffer,ULONG * transfer_request_length)739 static UINT test_ms_vendor_request(ULONG request, ULONG request_value, ULONG request_index, ULONG request_length,
740                                    UCHAR *transfer_request_buffer, ULONG *transfer_request_length)
741 {
742     return vendor_req_rc;
743 }
744 
745 
test_ux_device_class_cdc_acm_entry(UX_SLAVE_CLASS_COMMAND * command)746 static UINT test_ux_device_class_cdc_acm_entry(UX_SLAVE_CLASS_COMMAND *command)
747 {
748     if (class_entry_rc != UX_SUCCESS)
749         return class_entry_rc;
750 
751     switch (command -> ux_slave_class_command_request)
752     {
753         case UX_SLAVE_CLASS_COMMAND_CHANGE:
754             return UX_SUCCESS;
755         default: break;
756     }
757     return _ux_device_class_cdc_acm_entry(command);
758 }
759 
test_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)760 static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
761 {
762 
763 UX_HOST_CLASS_CDC_ACM *cdc_acm = (UX_HOST_CLASS_CDC_ACM *) inst;
764 
765     switch(event)
766     {
767 
768         case UX_DEVICE_INSERTION:
769 
770             if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
771                 cdc_acm_host_control = cdc_acm;
772             else
773                 cdc_acm_host_data = cdc_acm;
774             break;
775 
776         case UX_DEVICE_REMOVAL:
777 
778             if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
779                 cdc_acm_host_control = UX_NULL;
780             else
781                 cdc_acm_host_data = UX_NULL;
782             break;
783 
784         default:
785             break;
786     }
787     return 0;
788 }
789 
test_cdc_instance_activate(VOID * cdc_instance)790 static VOID test_cdc_instance_activate(VOID *cdc_instance)
791 {
792 
793     /* Save the CDC instance.  */
794     cdc_acm_slave = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
795 }
test_cdc_instance_deactivate(VOID * cdc_instance)796 static VOID test_cdc_instance_deactivate(VOID *cdc_instance)
797 {
798 
799     /* Reset the CDC instance.  */
800     cdc_acm_slave = UX_NULL;
801 }
802 
test_cdc_instance_parameter_change(VOID * cdc_instance)803 static VOID test_cdc_instance_parameter_change(VOID *cdc_instance)
804 {
805 
806     /* Set CDC parameter change flag. */
807     cdc_acm_slave_change = UX_TRUE;
808 }
809 
test_ux_error_callback(UINT system_level,UINT system_context,UINT error_code)810 static VOID test_ux_error_callback(UINT system_level, UINT system_context, UINT error_code)
811 {
812 }
813 
ux_test_hcd_entry_should_not_be_called(UX_TEST_ACTION * action,VOID * params)814 static VOID ux_test_hcd_entry_should_not_be_called(UX_TEST_ACTION *action, VOID *params)
815 {
816 
817     error_counter ++;
818 }
819 
ux_test_hcd_entry_disconnect(UX_TEST_ACTION * action,VOID * params)820 static VOID ux_test_hcd_entry_disconnect(UX_TEST_ACTION *action, VOID *params)
821 {
822 
823     ux_test_dcd_sim_slave_disconnect();
824 }
825 
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * params)826 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params)
827 {
828 
829     set_cfg_counter ++;
830 
831     rsc_mem_alloc_cnt_on_set_cfg = ux_test_utility_sim_mem_alloc_count();
832 
833     rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
834     rsc_enum_sem_get_count = ux_test_utility_sim_sem_get_count();
835     rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
836 }
837 
test_ux_device_class_cdc_acm_read_halt(UX_SLAVE_CLASS_CDC_ACM * cdc_acm)838 static UINT test_ux_device_class_cdc_acm_read_halt(UX_SLAVE_CLASS_CDC_ACM *cdc_acm)
839 {
840 UX_SLAVE_ENDPOINT           *endpoint;
841 UX_SLAVE_INTERFACE          *interface;
842 
843     /* This is the first time we are activated. We need the interface to the class.  */
844     interface =  cdc_acm -> ux_slave_class_cdc_acm_interface;
845 
846     /* Locate the endpoints.  */
847     endpoint =  interface -> ux_slave_interface_first_endpoint;
848 
849     /* Check the endpoint direction, if OUT we have the correct endpoint.  */
850     if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_OUT)
851     {
852 
853         /* So the next endpoint has to be the OUT endpoint.  */
854         endpoint =  endpoint -> ux_slave_endpoint_next_endpoint;
855     }
856 
857     return ux_device_stack_endpoint_stall(endpoint);
858 }
859 
860 extern UINT  _ux_host_stack_endpoint_reset(UX_ENDPOINT *endpoint);
test_ux_host_class_cdc_acm_write_halt_clear(UX_HOST_CLASS_CDC_ACM * cdc_acm)861 static UINT test_ux_host_class_cdc_acm_write_halt_clear(UX_HOST_CLASS_CDC_ACM *cdc_acm)
862 {
863     return _ux_host_stack_endpoint_reset(cdc_acm->ux_host_class_cdc_acm_bulk_out_endpoint);
864 }
865 
test_ux_host_class_cdc_acm_write(UX_HOST_CLASS_CDC_ACM * cdc_acm,UCHAR * data_pointer,ULONG requested_length,ULONG * actual_length)866 static UINT test_ux_host_class_cdc_acm_write(UX_HOST_CLASS_CDC_ACM *cdc_acm, UCHAR *data_pointer,
867                                     ULONG requested_length, ULONG *actual_length)
868 {
869 UX_TRANSFER     *transfer_request;
870 UINT            status;
871 ULONG           transfer_request_length;
872 
873     /* Start by resetting the actual length of the transfer.  */
874     *actual_length = 0;
875 
876     /* Get the pointer to the bulk out endpoint transfer request.  */
877     transfer_request =  &cdc_acm -> ux_host_class_cdc_acm_bulk_out_endpoint -> ux_endpoint_transfer_request;
878 
879     /* Program the maximum authorized length for this transfer_request.  */
880     if (requested_length > transfer_request -> ux_transfer_request_maximum_length)
881         transfer_request_length =  transfer_request -> ux_transfer_request_maximum_length;
882     else
883         transfer_request_length =  requested_length;
884 
885     /* Initialize the transfer_request.  */
886     transfer_request -> ux_transfer_request_data_pointer =  data_pointer;
887     transfer_request -> ux_transfer_request_requested_length =  transfer_request_length;
888 
889     /* Perform the transfer.  */
890     status =  ux_host_stack_transfer_request(transfer_request);
891 
892     /* If the transfer is successful, we need to wait for the transfer request to be completed.  */
893     if (status == UX_SUCCESS)
894     {
895 
896         /* Wait for the completion of the transfer request.  */
897         status =  _ux_utility_semaphore_get(&transfer_request -> ux_transfer_request_semaphore, UX_HOST_CLASS_CDC_ACM_CLASS_TRANSFER_TIMEOUT);
898 
899         /* Update the length of the actual data transferred. We do this after the
900             abort of the transfer_request in case some data actually went out.  */
901         *actual_length +=  transfer_request -> ux_transfer_request_actual_length;
902 
903         /* If the semaphore did not succeed we probably have a time out.  */
904         if (status != UX_SUCCESS)
905         {
906 
907             /* All transfers pending need to abort. There may have been a partial transfer.  */
908             ux_host_stack_transfer_request_abort(transfer_request);
909 
910             /* Set the completion code.  */
911             transfer_request -> ux_transfer_request_completion_code =  UX_TRANSFER_TIMEOUT;
912 
913             /* Error trap. */
914             _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_TIMEOUT);
915 
916             /* If trace is enabled, insert this event into the trace buffer.  */
917             UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_TRANSFER_TIMEOUT, transfer_request, 0, 0, UX_TRACE_ERRORS, 0, 0)
918 
919         }
920 
921         /* Report completion code. */
922         status = transfer_request -> ux_transfer_request_completion_code;
923     }
924 
925     /* Return status. */
926     return(status);
927 }
928 
929 
930 /* Define what the initial system looks like.  */
931 
932 #ifdef CTEST
test_application_define(void * first_unused_memory)933 void test_application_define(void *first_unused_memory)
934 #else
935 void    usbx_device_stack_standard_request_test_application_define(void *first_unused_memory)
936 #endif
937 {
938 
939 UINT                    status;
940 CHAR *                  stack_pointer;
941 CHAR *                  memory_pointer;
942 
943     printf("Running Host & Device Standard Request Test......................... ");
944 
945     /* Reset testing counts. */
946     ux_test_utility_sim_mem_alloc_count_reset();
947     ux_test_utility_sim_mutex_create_count_reset();
948     ux_test_utility_sim_sem_create_count_reset();
949     ux_test_utility_sim_sem_get_count_reset();
950     /* Reset error generations */
951     ux_test_utility_sim_mem_alloc_error_generation_stop();
952     ux_test_utility_sim_sem_error_generation_stop();
953     ux_test_utility_sim_mutex_error_generation_stop();
954     ux_test_utility_sim_sem_get_error_generation_stop();
955 
956     /* Initialize the free memory pointer */
957     stack_pointer = (CHAR *) usbx_memory;
958     memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
959 
960     /* Initialize USBX Memory */
961     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
962 
963     /* Check for error.  */
964     if (status != UX_SUCCESS)
965     {
966 
967         printf(" ERROR #1\n");
968         test_control_return(1);
969     }
970 
971     /* Register the error callback. */
972     _ux_utility_error_callback_register(test_ux_error_callback);
973 
974     /* The code below is required for installing the device portion of USBX. No call back for
975        device status change in this example. */
976     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
977                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
978                                        string_framework, STRING_FRAMEWORK_LENGTH,
979                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
980     if(status!=UX_SUCCESS)
981     {
982 
983         printf(" ERROR #5\n");
984         test_control_return(1);
985     }
986 
987     /* Set the parameters for callback when insertion/extraction of a CDC device.  */
988     parameter.ux_slave_class_cdc_acm_instance_activate   =  test_cdc_instance_activate;
989     parameter.ux_slave_class_cdc_acm_instance_deactivate =  test_cdc_instance_deactivate;
990     parameter.ux_slave_class_cdc_acm_parameter_change    =  test_cdc_instance_parameter_change;
991 
992     /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
993     status  =  ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, test_ux_device_class_cdc_acm_entry,
994                                              1,0,  &parameter);
995     status |=  ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, test_ux_device_class_cdc_acm_entry,
996                                              1,2,  &parameter);
997 #if UX_MAX_SLAVE_CLASS_DRIVER > 1
998     if(status!=UX_SUCCESS)
999     {
1000 
1001         printf(" ERROR #7\n");
1002         test_control_return(1);
1003     }
1004 #endif
1005 
1006     /* Initialize the hid class parameters.  */
1007     hid_parameter.ux_device_class_hid_parameter_report_address = hid_mouse_report;
1008     hid_parameter.ux_device_class_hid_parameter_report_length  = HID_MOUSE_REPORT_LENGTH;
1009     hid_parameter.ux_device_class_hid_parameter_callback       = UX_NULL;
1010     hid_parameter.ux_slave_class_hid_instance_activate         = UX_NULL;
1011 
1012     /* Initilize the device hid class. The class is connected with interface 0 */
1013     status  =  ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
1014                                               4, 0, (VOID *)&hid_parameter);
1015     // status |=  ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
1016     //                                           4, 1, (VOID *)&hid_parameter);
1017 #if UX_MAX_SLAVE_CLASS_DRIVER > 1
1018     if(status!=UX_SUCCESS)
1019     {
1020 
1021         printf("Error on line %d, error code: %x\n", __LINE__, status);
1022         test_control_return(1);
1023     }
1024 #endif
1025 
1026     /* MS extensions.  */
1027     status = _ux_device_stack_microsoft_extension_register(UX_DEMO_VENDOR_REQUEST, test_ms_vendor_request);
1028 
1029     if(status!=UX_SUCCESS)
1030     {
1031 
1032         printf(" ERROR #%d\n", __LINE__);
1033         test_control_return(1);
1034     }
1035 
1036     /* Initialize the simulated device controller.  */
1037     status =  _ux_test_dcd_sim_slave_initialize();
1038 
1039     /* Check for error.  */
1040     if (status != TX_SUCCESS)
1041     {
1042 
1043         printf(" ERROR #8\n");
1044         test_control_return(1);
1045     }
1046 
1047     /* The code below is required for installing the host portion of USBX */
1048     status =  ux_host_stack_initialize(test_host_change_function);
1049     if (status != UX_SUCCESS)
1050     {
1051 
1052         printf(" ERROR #2\n");
1053         test_control_return(1);
1054     }
1055 
1056     /* Register CDC-ACM class.  */
1057     status =  ux_host_stack_class_register(_ux_system_host_class_cdc_acm_name, ux_host_class_cdc_acm_entry);
1058     if (status != UX_SUCCESS)
1059     {
1060 
1061         printf(" ERROR #3\n");
1062         test_control_return(1);
1063     }
1064 
1065     /* Register all the USB host controllers available in this system */
1066     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
1067     if (status != UX_SUCCESS)
1068     {
1069 
1070         printf(" ERROR #4\n");
1071         test_control_return(1);
1072     }
1073 
1074     /* Create the main host simulation thread.  */
1075     status =  tx_thread_create(&tx_test_thread_simulation0, "tx test simulation 0", tx_test_thread_simulation0_entry, 0,
1076             stack_pointer, UX_DEMO_STACK_SIZE,
1077             20, 20, 1, TX_AUTO_START);
1078 
1079     /* Check for error.  */
1080     if (status != TX_SUCCESS)
1081     {
1082 
1083         printf(" ERROR #9\n");
1084         test_control_return(1);
1085     }
1086 
1087     /* Create the main slave simulation  thread.  */
1088     status =  tx_thread_create(&tx_test_thread_simulation1, "tx test simulation 1", tx_test_thread_simulation1_entry, 0,
1089             stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
1090             20, 20, 1, TX_AUTO_START);
1091 
1092     /* Check for error.  */
1093     if (status != TX_SUCCESS)
1094     {
1095 
1096         printf(" ERROR #10\n");
1097         test_control_return(1);
1098     }
1099 }
1100 
tx_test_thread_simulation0_entry(ULONG arg)1101 void  tx_test_thread_simulation0_entry(ULONG arg)
1102 {
1103 UINT                                                status;
1104 ULONG                                               actual_length;
1105 UX_DEVICE                                          *device;
1106 UX_ENDPOINT                                        *control_endpoint;
1107 UX_TRANSFER                                        *transfer_request;
1108 UX_SLAVE_TRANSFER                                  *slave_transfer_request;
1109 
1110     stepinfo("\n");
1111 
1112     /* Wait for first enumeration to complete.  */
1113     stepinfo(">>>>>>>>>>>>>>>> Wait for first enumeration completion\n");
1114     while (cdc_acm_host_control == UX_NULL || cdc_acm_host_data == UX_NULL || cdc_acm_slave == UX_NULL)
1115         tx_thread_sleep(10);
1116 
1117     /* Wait for instances to be live. */
1118     tx_thread_sleep(10);
1119 
1120     ux_test_dcd_sim_slave_disconnect();
1121     ux_test_hcd_sim_host_disconnect();
1122 
1123     /* Test connect. Note that we must switch to high speed for tests. */
1124     stepinfo(">>>>>>>>>>>>>>>> Test connect\n");
1125     ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
1126     ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
1127     tx_thread_sleep(UX_CDC_ACM_CONNECTION_DELAY);
1128     if (cdc_acm_host_control == UX_NULL || cdc_acm_host_data == UX_NULL || cdc_acm_slave == UX_NULL)
1129     {
1130 
1131         printf("ERROR #%d: connection not detected\n", __LINE__);
1132         test_control_return(1);
1133     }
1134 
1135     status = ux_host_stack_device_get(0, &device);
1136     if (status != UX_SUCCESS)
1137     {
1138 
1139         printf("ERROR #%d: device_get fail\n", __LINE__);
1140         test_control_return(1);
1141     }
1142     control_endpoint = &device->ux_device_control_endpoint;
1143     transfer_request = &control_endpoint->ux_endpoint_transfer_request;
1144 
1145     slave_transfer_request = &_ux_system_slave->ux_system_slave_device.ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request;
1146 
1147     /* Test bulk stall handling */
1148     stepinfo(">>>>>>>>>>>>>>>> Test Bulk OUT STALL\n");
1149     /* Start waiting stall on device side */
1150     status = test_ux_host_class_cdc_acm_write(cdc_acm_host_data, "TSTALL\n", 7, &actual_length);
1151     if (status != UX_SUCCESS)
1152     {
1153 
1154         printf("ERROR #%d: Bulk OUT fail: %x\n", __LINE__, status);
1155         test_control_return(1);
1156     }
1157 
1158     /* Check endpoint stalled */
1159     status = test_ux_host_class_cdc_acm_write(cdc_acm_host_data, "TEST\n", 5, &actual_length);
1160     if (status != UX_TRANSFER_STALLED)
1161     {
1162 
1163         printf("ERROR #%d: Bulk OUT not stalled: %x\n", __LINE__, status);
1164         test_control_return(1);
1165     }
1166 
1167     /* Clear halt */
1168     status = test_ux_host_class_cdc_acm_write_halt_clear(cdc_acm_host_data);
1169     if (status != UX_SUCCESS)
1170     {
1171 
1172         printf("ERROR #%d: Stall clear fail: %x\n", __LINE__, status);
1173         test_control_return(1);
1174     }
1175 
1176     /* Check endpoint good */
1177     status = test_ux_host_class_cdc_acm_write(cdc_acm_host_data, "TEST\n", 5, &actual_length);
1178     if (status != UX_SUCCESS)
1179     {
1180 
1181         printf("ERROR #%d: Bulk OUT failed: %x\n", __LINE__, status);
1182         test_control_return(1);
1183     }
1184 
1185     /* Test normal requests */
1186     stepinfo(">>>>>>>>>>>>>>>> Test GetDeviceDescriptor\n");
1187     transfer_request -> ux_transfer_request_data_pointer =      buffer;
1188     transfer_request -> ux_transfer_request_requested_length =  64;
1189     transfer_request -> ux_transfer_request_function =          UX_GET_DESCRIPTOR;
1190     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1191     transfer_request -> ux_transfer_request_value =             UX_DEVICE_DESCRIPTOR_ITEM << 8;
1192     transfer_request -> ux_transfer_request_index =             0;
1193     status = ux_host_stack_transfer_request(transfer_request);
1194     if (status != UX_SUCCESS)
1195     {
1196 
1197         printf("ERROR #%d: GetDeviceDescriptor(64) fail\n", __LINE__);
1198         test_control_return(1);
1199     }
1200     if (transfer_request->ux_transfer_request_actual_length != 18)
1201     {
1202 
1203         printf("ERROR #%d: GetDeviceDescriptor(64) actual length is not 18\n", __LINE__);
1204         test_control_return(1);
1205     }
1206 
1207     stepinfo(">>>>>>>>>>>>>>>> Test GetDeviceQualifierDescriptor\n");
1208     transfer_request -> ux_transfer_request_data_pointer =      buffer;
1209     transfer_request -> ux_transfer_request_requested_length =  8;
1210     transfer_request -> ux_transfer_request_function =          UX_GET_DESCRIPTOR;
1211     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1212     transfer_request -> ux_transfer_request_value =             UX_DEVICE_QUALIFIER_DESCRIPTOR_ITEM << 8;
1213     transfer_request -> ux_transfer_request_index =             0;
1214     status = ux_host_stack_transfer_request(transfer_request);
1215     if (status != UX_SUCCESS)
1216     {
1217 
1218         printf("ERROR #%d: GetDeviceQualifierDescriptor(8) fail\n", __LINE__);
1219         test_control_return(1);
1220     }
1221     if (transfer_request->ux_transfer_request_actual_length != 8)
1222     {
1223 
1224         printf("ERROR #%d: GetDeviceQualifierDescriptor(8) actual length is not 8\n", __LINE__);
1225         test_control_return(1);
1226     }
1227 
1228     transfer_request -> ux_transfer_request_requested_length =  64;
1229     status = ux_host_stack_transfer_request(transfer_request);
1230     if (status != UX_SUCCESS)
1231     {
1232 
1233         printf("ERROR #%d: GetDeviceQualifierDescriptor(64) fail\n", __LINE__);
1234         test_control_return(1);
1235     }
1236     if (transfer_request->ux_transfer_request_actual_length != 10)
1237     {
1238 
1239         printf("ERROR #%d: GetDeviceQualifierDescriptor(64) actual length is not 10\n", __LINE__);
1240         test_control_return(1);
1241     }
1242 
1243     _ux_system_slave -> ux_system_slave_device_framework =  _ux_system_slave -> ux_system_slave_device_framework_full_speed;
1244     _ux_system_slave -> ux_system_slave_device_framework_length =  _ux_system_slave -> ux_system_slave_device_framework_length_full_speed;
1245 
1246     status = ux_host_stack_transfer_request(transfer_request);
1247     if (status == UX_SUCCESS)
1248     {
1249 
1250         printf("ERROR #%d: GetDeviceQualifierDescriptor(64) should fail\n", __LINE__);
1251         test_control_return(1);
1252     }
1253 
1254     stepinfo(">>>>>>>>>>>>>>>> Test GetOTGDescriptor\n");
1255     transfer_request -> ux_transfer_request_data_pointer =      buffer;
1256     transfer_request -> ux_transfer_request_requested_length =  64;
1257     transfer_request -> ux_transfer_request_function =          UX_GET_DESCRIPTOR;
1258     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1259     transfer_request -> ux_transfer_request_value =             UX_OTG_DESCRIPTOR_ITEM << 8;
1260     transfer_request -> ux_transfer_request_index =             0;
1261 
1262     status = ux_host_stack_transfer_request(transfer_request);
1263     if (status == UX_SUCCESS)
1264     {
1265 
1266         printf("ERROR #%d: GetOTGDescriptor(64) should fail\n", __LINE__);
1267         test_control_return(1);
1268     }
1269 
1270     _ux_system_slave -> ux_system_slave_device_framework =  _ux_system_slave -> ux_system_slave_device_framework_high_speed;
1271     _ux_system_slave -> ux_system_slave_device_framework_length =  _ux_system_slave -> ux_system_slave_device_framework_length_high_speed;
1272     status = ux_host_stack_transfer_request(transfer_request);
1273     if (status != UX_SUCCESS)
1274     {
1275 
1276         printf("ERROR #%d: GetOTGDescriptor(64) fail: %x\n", __LINE__, status);
1277         test_control_return(1);
1278     }
1279     if (transfer_request->ux_transfer_request_actual_length != 5)
1280     {
1281 
1282         printf("ERROR #%d: GetOTGDescriptor(64) actual length is not 5\n", __LINE__);
1283         test_control_return(1);
1284     }
1285 
1286     transfer_request -> ux_transfer_request_requested_length =  5;
1287     status = ux_host_stack_transfer_request(transfer_request);
1288     if (status != UX_SUCCESS)
1289     {
1290 
1291         printf("ERROR #%d: GetOTGDescriptor(5) fail\n", __LINE__);
1292         test_control_return(1);
1293     }
1294     if (transfer_request->ux_transfer_request_actual_length != 5)
1295     {
1296 
1297         printf("ERROR #%d: GetOTGDescriptor(5) actual length is not 5\n", __LINE__);
1298         test_control_return(1);
1299     }
1300 
1301     stepinfo(">>>>>>>>>>>>>>>> Test GetOtherSpeedDescriptor\n");
1302     transfer_request -> ux_transfer_request_data_pointer =      buffer;
1303     transfer_request -> ux_transfer_request_requested_length =  8;
1304     transfer_request -> ux_transfer_request_function =          UX_GET_DESCRIPTOR;
1305     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1306     transfer_request -> ux_transfer_request_value =             UX_OTHER_SPEED_DESCRIPTOR_ITEM << 8;
1307     transfer_request -> ux_transfer_request_index =             0;
1308     status = ux_host_stack_transfer_request(transfer_request);
1309     if (status != UX_SUCCESS)
1310     {
1311 
1312         printf("ERROR #%d: GetOtherSpeedDescriptor(8) fail\n", __LINE__);
1313         test_control_return(1);
1314     }
1315 
1316     transfer_request -> ux_transfer_request_requested_length =  256;
1317     status = ux_host_stack_transfer_request(transfer_request);
1318     if (status != UX_SUCCESS)
1319     {
1320 
1321         printf("ERROR #%d: GetOtherSpeedDescriptor(256) fail\n", __LINE__);
1322         test_control_return(1);
1323     }
1324 
1325     transfer_request -> ux_transfer_request_value =             (UX_OTHER_SPEED_DESCRIPTOR_ITEM << 8) | 10;
1326     status = ux_host_stack_transfer_request(transfer_request);
1327     if (status == UX_SUCCESS)
1328     {
1329 
1330         printf("ERROR #%d: GetOtherSpeedDescriptor(10, 256) must fail\n", __LINE__);
1331         test_control_return(1);
1332     }
1333 
1334     stepinfo(">>>>>>>>>>>>>>>> Test GetConfigurationDescriptor\n");
1335     transfer_request -> ux_transfer_request_data_pointer =      buffer;
1336     transfer_request -> ux_transfer_request_requested_length =  256;
1337     transfer_request -> ux_transfer_request_function =          UX_GET_DESCRIPTOR;
1338     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1339     transfer_request -> ux_transfer_request_index =             0;
1340 
1341     /* Get existing configuration */
1342     transfer_request -> ux_transfer_request_value =             UX_CONFIGURATION_DESCRIPTOR_ITEM << 8;
1343     status = ux_host_stack_transfer_request(transfer_request);
1344     if (status != UX_SUCCESS)
1345     {
1346 
1347         printf("ERROR #%d: GetConfigurationDescriptor(0, 256) fail\n", __LINE__);
1348         test_control_return(1);
1349     }
1350 
1351     /* Get non-existing configuration */
1352     transfer_request -> ux_transfer_request_value =             (UX_CONFIGURATION_DESCRIPTOR_ITEM << 8) | 10;
1353     status = ux_host_stack_transfer_request(transfer_request);
1354     if (status == UX_SUCCESS)
1355     {
1356 
1357         printf("ERROR #%d: GetConfigurationDescriptor(10, 256) must fail\n", __LINE__);
1358         test_control_return(1);
1359     }
1360 
1361     stepinfo(">>>>>>>>>>>>>>>> Test GetStringDescriptor\n");
1362     transfer_request -> ux_transfer_request_data_pointer =      buffer;
1363     transfer_request -> ux_transfer_request_requested_length =  64;
1364     transfer_request -> ux_transfer_request_function =          UX_GET_DESCRIPTOR;
1365     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1366 
1367     /* Get LangID with big buffer */
1368     transfer_request -> ux_transfer_request_value =             UX_STRING_DESCRIPTOR_ITEM << 8;
1369     transfer_request -> ux_transfer_request_index =             0;
1370     status = ux_host_stack_transfer_request(transfer_request);
1371     if (status != UX_SUCCESS)
1372     {
1373 
1374         printf("ERROR #%d: GetStringDescriptor(0, 64) fail\n", __LINE__);
1375         test_control_return(1);
1376     }
1377 
1378     /* Get LangID with exactly size */
1379     transfer_request -> ux_transfer_request_requested_length =  4;
1380     status = ux_host_stack_transfer_request(transfer_request);
1381     if (status != UX_SUCCESS)
1382     {
1383 
1384         printf("ERROR #%d: GetStringDescriptor(0, 4) fail\n", __LINE__);
1385         test_control_return(1);
1386     }
1387 
1388     /* Get String with small buffer */
1389     transfer_request -> ux_transfer_request_index =             0x0409;
1390     transfer_request -> ux_transfer_request_value =             (UX_STRING_DESCRIPTOR_ITEM << 8) | 1;
1391     status = ux_host_stack_transfer_request(transfer_request);
1392     if (status != UX_SUCCESS)
1393     {
1394 
1395         printf("ERROR #%d: GetStringDescriptor(1, 4) fail\n", __LINE__);
1396         test_control_return(1);
1397     }
1398 
1399     /* Get String with large buffer */
1400     transfer_request -> ux_transfer_request_requested_length =  256;
1401     transfer_request -> ux_transfer_request_value =             (UX_STRING_DESCRIPTOR_ITEM << 8) | 2;
1402     status = ux_host_stack_transfer_request(transfer_request);
1403     if (status != UX_SUCCESS)
1404     {
1405 
1406         printf("ERROR #%d: GetStringDescriptor(2, 256) fail\n", __LINE__);
1407         test_control_return(1);
1408     }
1409 
1410     /* Get String not existing */
1411     transfer_request -> ux_transfer_request_value =             (UX_STRING_DESCRIPTOR_ITEM << 8) | 10;
1412     status = ux_host_stack_transfer_request(transfer_request);
1413     if (status == UX_SUCCESS)
1414     {
1415 
1416         printf("ERROR #%d: GetStringDescriptor(10, 256) must fail\n", __LINE__);
1417         test_control_return(1);
1418     }
1419 
1420     /* Get Manufacturer string descriptor. */
1421     transfer_request -> ux_transfer_request_data_pointer =      buffer;
1422     transfer_request -> ux_transfer_request_requested_length =  0xff;
1423     transfer_request -> ux_transfer_request_function =          UX_GET_DESCRIPTOR;
1424     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1425     transfer_request -> ux_transfer_request_value =             (UX_STRING_DESCRIPTOR_ITEM << 8) | 0x01;
1426     status = ux_host_stack_transfer_request(transfer_request);
1427     if (status != UX_SUCCESS)
1428     {
1429 
1430         printf("ERROR #%d: GetStringDescriptor(10, 256) must fail\n", __LINE__);
1431         test_control_return(1);
1432     }
1433 
1434     UCHAR string_descriptor_manufacturer_length = *(string_framework + 3);
1435     UCHAR get_string_descriptor_manufacturer_expected[] = {
1436         /* bLength. '2 +' is for bLength and bDescriptorType, '0x0c' is the length of
1437            the string, and '*2' is because it's 16-bit unicode, where each character
1438            is 2 bytes, the LSB is the value, and MSB is 0 (for ascii anyways). */
1439         (UCHAR)(2 + string_descriptor_manufacturer_length*2),
1440 
1441         /* bDescriptorType */
1442         0x03,
1443 
1444         /* "Express Logic" in unicode. */
1445         0x45, 0x00,
1446         0x78, 0x00,
1447         0x70, 0x00,
1448         0x72, 0x00,
1449         0x65, 0x00,
1450         0x73, 0x00,
1451         0x20, 0x00,
1452         0x4c, 0x00,
1453         0x6f, 0x00,
1454         0x67, 0x00,
1455         0x69, 0x00,
1456         0x63, 0x00,
1457     };
1458 
1459     /* Ensure the length is correct.  */
1460     if (transfer_request->ux_transfer_request_actual_length != sizeof(get_string_descriptor_manufacturer_expected))
1461     {
1462 
1463         printf("ERROR on line %d\n", __LINE__);
1464         test_control_return(1);
1465     }
1466 
1467     /* Now check the contents. */
1468     if (_ux_utility_memory_compare(transfer_request->ux_transfer_request_data_pointer, get_string_descriptor_manufacturer_expected, sizeof(get_string_descriptor_manufacturer_expected)))
1469     {
1470 
1471         printf("ERROR on line %d\n", __LINE__);
1472         test_control_return(1);
1473     }
1474 
1475     stepinfo(">>>>>>>>>>>>>>>> Test GetDescriptor(unknown)\n");
1476     transfer_request -> ux_transfer_request_data_pointer =      buffer;
1477     transfer_request -> ux_transfer_request_requested_length =  64;
1478     transfer_request -> ux_transfer_request_function =          UX_GET_DESCRIPTOR;
1479     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1480 
1481     /* Get unknown discriptor */
1482     transfer_request -> ux_transfer_request_value =             11 << 8;
1483     transfer_request -> ux_transfer_request_index =             0;
1484     status = ux_host_stack_transfer_request(transfer_request);
1485     if (status == UX_SUCCESS)
1486     {
1487 
1488         printf("ERROR #%d: GetDescriptor(unknown) must fail\n", __LINE__);
1489         test_control_return(1);
1490     }
1491 
1492     stepinfo(">>>>>>>>>>>>>>>> Test GetDescriptor(class)\n");
1493     transfer_request -> ux_transfer_request_data_pointer =      buffer;
1494     transfer_request -> ux_transfer_request_requested_length =  64;
1495     transfer_request -> ux_transfer_request_function =          UX_GET_DESCRIPTOR;
1496     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1497 
1498     /* Get class discriptor */
1499     transfer_request -> ux_transfer_request_value =             (11 + UX_REQUEST_TYPE_CLASS) << 8;
1500     transfer_request -> ux_transfer_request_index =             0;
1501     status = ux_host_stack_transfer_request(transfer_request);
1502     if (status == UX_SUCCESS)
1503     {
1504 
1505         printf("ERROR #%d: GetDescriptor(class) must fail\n", __LINE__);
1506         test_control_return(1);
1507     }
1508 
1509     stepinfo(">>>>>>>>>>>>>>>> Test SetFeature/ClearFeature/GetStatus\n");
1510 
1511     transfer_request -> ux_transfer_request_requested_length =  0;
1512     transfer_request -> ux_transfer_request_data_pointer =      buffer;
1513     transfer_request -> ux_transfer_request_function =          UX_SET_FEATURE;
1514 
1515     /* SetDeviceFeature */
1516     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1517     transfer_request -> ux_transfer_request_value =             UX_REQUEST_FEATURE_DEVICE_REMOTE_WAKEUP;
1518     transfer_request -> ux_transfer_request_index =             0;
1519     status = ux_host_stack_transfer_request(transfer_request);
1520     if (status != UX_SUCCESS)
1521     {
1522 
1523         printf("ERROR #%d: SetDeviceFeature fail\n", __LINE__);
1524         test_control_return(1);
1525     }
1526 
1527     /* SetInterfaceFeature */
1528     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1529     status = ux_host_stack_transfer_request(transfer_request);
1530 
1531     /* Normal write, should be good. */
1532     status = test_ux_host_class_cdc_acm_write(cdc_acm_host_data, "TEST\n", 5, &actual_length);
1533     if (status != UX_SUCCESS)
1534     {
1535 
1536         printf("ERROR #%d: Bulk OUT status %x\n", __LINE__, status);
1537         test_control_return(1);
1538     }
1539 
1540     stepinfo(">>>>>>>>>>>>>>>> Test SetEndpointFeature(0x81)\n");
1541 
1542     /* SetEndpointFeature to existing endpoint */
1543     transfer_request -> ux_transfer_request_index =             0x02;
1544     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_ENDPOINT;
1545     status = ux_host_stack_transfer_request(transfer_request);
1546     if (status != UX_SUCCESS)
1547     {
1548 
1549         printf("ERROR #%d: SetEndpointFeature(0x81) fail\n", __LINE__);
1550         test_control_return(1);
1551     }
1552 
1553     stepinfo(">>>>>>>>>>>>>>>> Test SetEndpointFeature(0x82)\n");
1554 
1555     /* SetEndpointFeature to not existing one */
1556     transfer_request -> ux_transfer_request_index =             0x82;
1557     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_ENDPOINT;
1558     status = ux_host_stack_transfer_request(transfer_request);
1559     if (status == UX_SUCCESS)
1560     {
1561 
1562         printf("ERROR #%d: SetEndpointFeature(0x82) must fail\n", __LINE__);
1563         test_control_return(1);
1564     }
1565 
1566     /* GetDeviceStatus */
1567     transfer_request -> ux_transfer_request_requested_length =  64;
1568     transfer_request -> ux_transfer_request_function =          UX_GET_STATUS;
1569     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1570     transfer_request -> ux_transfer_request_index =             0;
1571     status = ux_host_stack_transfer_request(transfer_request);
1572     if (status != UX_SUCCESS)
1573     {
1574 
1575         printf("ERROR #%d: GetDeviceStatus fail\n", __LINE__);
1576         test_control_return(1);
1577     }
1578 
1579     /* GetDeviceOTGStatus */
1580     transfer_request -> ux_transfer_request_index =             UX_OTG_STATUS_SELECTOR;
1581     status = ux_host_stack_transfer_request(transfer_request);
1582     if (status != UX_SUCCESS)
1583     {
1584 
1585         printf("ERROR #%d: GetDeviceOTGStatus fail\n", __LINE__);
1586         test_control_return(1);
1587     }
1588 
1589     /* GetInterfaceStatus may or may not implement */
1590     transfer_request -> ux_transfer_request_index =             0;
1591     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1592     status = ux_host_stack_transfer_request(transfer_request);
1593 
1594     /* GetEndpointStatus for existing endpoint */
1595     transfer_request -> ux_transfer_request_index =             0x02;
1596     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_ENDPOINT;
1597     status = ux_host_stack_transfer_request(transfer_request);
1598     if (status != UX_SUCCESS)
1599     {
1600 
1601         printf("ERROR #%d: GetEndpointStatus(0x02) fail\n", __LINE__);
1602         test_control_return(1);
1603     }
1604     if (buffer[0] != 1)
1605     {
1606 
1607         printf("ERROR #%d: GetEndpointStatus(0x02) should halt\n", __LINE__);
1608         test_control_return(1);
1609 
1610     }
1611 
1612     /* Write, should return halt. */
1613     status  = test_ux_host_class_cdc_acm_write(cdc_acm_host_data, "TEST\n", 5, &actual_length);
1614     if (status == UX_SUCCESS)
1615     {
1616 
1617         printf("ERROR #%d: Bulk OUT status %x\n", __LINE__, status);
1618         test_control_return(1);
1619     }
1620 
1621     stepinfo(">>>>>>>>>>>>>>>> Test ClearEndpointFeature(0x02)\n");
1622 
1623     /* ClearEndpointFeature for existing endpoint */
1624     transfer_request -> ux_transfer_request_function =          UX_CLEAR_FEATURE;
1625     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_ENDPOINT;
1626     transfer_request -> ux_transfer_request_index =             0x02;
1627     transfer_request -> ux_transfer_request_requested_length =  0;
1628     status = ux_host_stack_transfer_request(transfer_request);
1629     if (status != UX_SUCCESS)
1630     {
1631 
1632         printf("ERROR #%d: ClearEndpointFeature(0x02) fail\n", __LINE__);
1633         test_control_return(1);
1634     }
1635 
1636     /* GetEndpointStatus for existing endpoint to check if clear is done */
1637     transfer_request -> ux_transfer_request_function =          UX_GET_STATUS;
1638     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_ENDPOINT;
1639     transfer_request -> ux_transfer_request_index =             0x02;
1640     transfer_request -> ux_transfer_request_requested_length =  2;
1641     status = ux_host_stack_transfer_request(transfer_request);
1642     if (status != UX_SUCCESS)
1643     {
1644 
1645         printf("ERROR #%d: GetEndpointStatus(0x02) fail\n", __LINE__);
1646         test_control_return(1);
1647     }
1648     if (buffer[0] != 0)
1649     {
1650 
1651         printf("ERROR #%d: GetEndpointStatus(0x02) should clear\n", __LINE__);
1652         test_control_return(1);
1653 
1654     }
1655 
1656     /* Write, should return OK. */
1657     status = test_ux_host_class_cdc_acm_write(cdc_acm_host_data, "TEST\n", 5, &actual_length);
1658     if (status != UX_SUCCESS)
1659     {
1660 
1661         printf("ERROR #%d: Bulk OUT status %x\n", __LINE__, status);
1662         test_control_return(1);
1663     }
1664 
1665     stepinfo(">>>>>>>>>>>>>>>> Test ClearEndpointFeature(0x05)\n");
1666 
1667     /* ClearEndpointFeature on not existing endpoint */
1668     transfer_request -> ux_transfer_request_function =          UX_CLEAR_FEATURE;
1669     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_ENDPOINT;
1670     transfer_request -> ux_transfer_request_index =             0x05;
1671     transfer_request -> ux_transfer_request_requested_length =  0;
1672     status = ux_host_stack_transfer_request(transfer_request);
1673     if (status == UX_SUCCESS)
1674     {
1675 
1676         printf("ERROR #%d: GetEndpointStatus(0x05) must fail\n", __LINE__);
1677         test_control_return(1);
1678     }
1679 
1680     /* ClearDeviceFeature */
1681     transfer_request -> ux_transfer_request_function =          UX_CLEAR_FEATURE;
1682     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1683     transfer_request -> ux_transfer_request_index =             0;
1684     transfer_request -> ux_transfer_request_requested_length =  0;
1685     status = ux_host_stack_transfer_request(transfer_request);
1686     if (status != UX_SUCCESS)
1687     {
1688 
1689         printf("ERROR #%d: ClearDeviceFeature() fail\n", __LINE__);
1690         test_control_return(1);
1691     }
1692 
1693     stepinfo(">>>>>>>>>>>>>>>> Test ClearInterfaceFeature(0x00)\n");
1694 
1695     /* ClearInterfaceFeature, may or may not implement */
1696     transfer_request -> ux_transfer_request_function =          UX_CLEAR_FEATURE;
1697     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1698     transfer_request -> ux_transfer_request_index =             0;
1699     transfer_request -> ux_transfer_request_requested_length =  0;
1700     status = ux_host_stack_transfer_request(transfer_request);
1701 
1702     stepinfo(">>>>>>>>>>>>>>>> Test GetConfiguration\n");
1703     transfer_request -> ux_transfer_request_data_pointer =      buffer;
1704     transfer_request -> ux_transfer_request_requested_length =  1;
1705     transfer_request -> ux_transfer_request_function =          UX_GET_CONFIGURATION;
1706     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1707     transfer_request -> ux_transfer_request_value =             0;
1708     transfer_request -> ux_transfer_request_index =             0;
1709     /* GetConfiguration should OK */
1710     status = ux_host_stack_transfer_request(transfer_request);
1711     if (status != UX_SUCCESS)
1712     {
1713 
1714         printf("ERROR #%d: GetConfiguration fail\n", __LINE__);
1715         test_control_return(1);
1716     }
1717     if (buffer[0] != 1)
1718     {
1719 
1720         printf("ERROR #%d: GetConfiguration should return 1\n", __LINE__);
1721         test_control_return(1);
1722     }
1723 
1724     stepinfo(">>>>>>>>>>>>>>>> Test SetConfiguration\n");
1725     transfer_request -> ux_transfer_request_data_pointer =      UX_NULL;
1726     transfer_request -> ux_transfer_request_requested_length =  0;
1727     transfer_request -> ux_transfer_request_function =          UX_SET_CONFIGURATION;
1728     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1729     transfer_request -> ux_transfer_request_value =             1;
1730     transfer_request -> ux_transfer_request_index =             0;
1731     /* SetConfiguration should OK */
1732     status = ux_host_stack_transfer_request(transfer_request);
1733     if (status != UX_SUCCESS)
1734     {
1735 
1736         printf("ERROR #%d: SetConfiguration fail\n", __LINE__);
1737         test_control_return(1);
1738     }
1739 
1740     /* SetConfiguration to invalid should fail */
1741     transfer_request -> ux_transfer_request_value =             10;
1742     status = ux_host_stack_transfer_request(transfer_request);
1743     if (status == UX_SUCCESS)
1744     {
1745 
1746         printf("ERROR #%d: SetConfiguration(10) must fail\n", __LINE__);
1747         test_control_return(1);
1748     }
1749 
1750     /* SetConfiguration */
1751     transfer_request -> ux_transfer_request_value =             3;
1752     status = ux_host_stack_transfer_request(transfer_request);
1753     if (status != UX_SUCCESS)
1754     {
1755 
1756         printf("ERROR #%d: SetConfiguration(3) must pass\n", __LINE__);
1757         test_control_return(1);
1758     }
1759 
1760     /* SetConfiguration */
1761     transfer_request -> ux_transfer_request_value =             4;
1762     status = ux_host_stack_transfer_request(transfer_request);
1763     if (status != UX_SUCCESS)
1764     {
1765 
1766         printf("ERROR #%d: SetConfiguration(4) must pass\n", __LINE__);
1767         test_control_return(1);
1768     }
1769 
1770     /* Stop reading on device side */
1771     cdc_acm_slave_reading = UX_FALSE;
1772 
1773     stepinfo(">>>>>>>>>>>>>>>> Test SetInterface/GetInterface\n");
1774     transfer_request -> ux_transfer_request_data_pointer =      buffer;
1775     transfer_request -> ux_transfer_request_requested_length =  0;
1776 
1777     /* Unonfiguration */
1778     transfer_request -> ux_transfer_request_function =          UX_SET_CONFIGURATION;
1779     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1780     transfer_request -> ux_transfer_request_value =             0;
1781     status = ux_host_stack_transfer_request(transfer_request);
1782     if (status != UX_SUCCESS)
1783     {
1784 
1785         printf("ERROR #%d: SetConfiguration(0) fail\n", __LINE__);
1786         test_control_return(1);
1787     }
1788 
1789 
1790     /* SetInterface must report error */
1791     transfer_request -> ux_transfer_request_function =          UX_SET_INTERFACE;
1792     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1793     transfer_request -> ux_transfer_request_value =             0;
1794     transfer_request -> ux_transfer_request_index =             0;
1795     status = ux_host_stack_transfer_request(transfer_request);
1796     if (status == UX_SUCCESS)
1797     {
1798 
1799         printf("ERROR #%d: SetInterface must fail when not configured\n", __LINE__);
1800         test_control_return(1);
1801     }
1802 
1803     /* GetInterface must report error */
1804     transfer_request -> ux_transfer_request_requested_length =  1;
1805     transfer_request -> ux_transfer_request_function =          UX_GET_INTERFACE;
1806     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1807     status = ux_host_stack_transfer_request(transfer_request);
1808     if (status == UX_SUCCESS)
1809     {
1810 
1811         printf("ERROR #%d: GetInterface must fail when not configured\n", __LINE__);
1812         test_control_return(1);
1813     }
1814 
1815     /* Back to normal configuration */
1816     transfer_request -> ux_transfer_request_requested_length =  0;
1817     transfer_request -> ux_transfer_request_function =          UX_SET_CONFIGURATION;
1818     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1819     transfer_request -> ux_transfer_request_value =             1;
1820     status = ux_host_stack_transfer_request(transfer_request);
1821     if (status != UX_SUCCESS)
1822     {
1823 
1824         printf("ERROR #%d: SetConfiguration(1) fail\n", __LINE__);
1825         test_control_return(1);
1826     }
1827 
1828     transfer_request -> ux_transfer_request_function =          UX_SET_INTERFACE;
1829     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1830 
1831     /* Good interface */
1832     transfer_request -> ux_transfer_request_value =             0;
1833     transfer_request -> ux_transfer_request_index =             0;
1834     status = ux_host_stack_transfer_request(transfer_request);
1835     if (status != UX_SUCCESS)
1836     {
1837 
1838         printf("ERROR #%d: SetInterface(0.0) should be OK\n", __LINE__);
1839         test_control_return(1);
1840     }
1841 
1842     /* Get interface */
1843     transfer_request -> ux_transfer_request_requested_length =  1;
1844     transfer_request -> ux_transfer_request_function =          UX_GET_INTERFACE;
1845     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1846     status = ux_host_stack_transfer_request(transfer_request);
1847     if (status != UX_SUCCESS)
1848     {
1849 
1850         printf("ERROR #%d: GetInterface fail %x\n", __LINE__, status);
1851         test_control_return(1);
1852     }
1853     if (buffer[0] != 0)
1854     {
1855 
1856         printf("ERROR #%d: GetInterface must return 0 but not %x\n", __LINE__, buffer[0]);
1857         test_control_return(1);
1858     }
1859 
1860     /* Invalid interface */
1861     transfer_request -> ux_transfer_request_requested_length =  0;
1862     transfer_request -> ux_transfer_request_function =          UX_SET_INTERFACE;
1863     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1864 
1865     transfer_request -> ux_transfer_request_value =             0;
1866     transfer_request -> ux_transfer_request_index =             2;
1867     status = ux_host_stack_transfer_request(transfer_request);
1868     if (status == UX_SUCCESS)
1869     {
1870 
1871         printf("ERROR #%d: SetInterface must fail\n", __LINE__);
1872         test_control_return(1);
1873     }
1874 
1875     /* Invalid alternate setting */
1876     transfer_request -> ux_transfer_request_value =             2;
1877     transfer_request -> ux_transfer_request_index =             0;
1878     status = ux_host_stack_transfer_request(transfer_request);
1879     if (status == UX_SUCCESS)
1880     {
1881 
1882         printf("ERROR #%d: SetInterface should fail\n", __LINE__);
1883         test_control_return(1);
1884     }
1885 
1886     /* SetConfiguration(2) */
1887     transfer_request -> ux_transfer_request_requested_length =  0;
1888     transfer_request -> ux_transfer_request_function =          UX_SET_CONFIGURATION;
1889     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1890     transfer_request -> ux_transfer_request_value =             2;
1891     status = ux_host_stack_transfer_request(transfer_request);
1892     if (status != UX_SUCCESS)
1893     {
1894 
1895         printf("ERROR #%d: SetConfiguration(2) fail\n", __LINE__);
1896         test_control_return(1);
1897     }
1898 
1899     /* SetInterface(2, 0, 1) */
1900     transfer_request -> ux_transfer_request_function =          UX_SET_INTERFACE;
1901     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1902     transfer_request -> ux_transfer_request_value =             1;
1903     transfer_request -> ux_transfer_request_index =             0;
1904     status = ux_host_stack_transfer_request(transfer_request);
1905     if (status != UX_SUCCESS)
1906     {
1907 
1908         printf("ERROR #%d: SetInterface(0,1) should be OK\n", __LINE__);
1909         test_control_return(1);
1910     }
1911 
1912     /* GetInterface(2, 0) */
1913     transfer_request -> ux_transfer_request_requested_length =  1;
1914     transfer_request -> ux_transfer_request_function =          UX_GET_INTERFACE;
1915     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1916     status = ux_host_stack_transfer_request(transfer_request);
1917     if (status != UX_SUCCESS)
1918     {
1919 
1920         printf("ERROR #%d: GetInterface must be OK\n", __LINE__);
1921         test_control_return(1);
1922     }
1923     if (buffer[0] != 1)
1924     {
1925 
1926         printf("ERROR #%d: GetInterface must return 1 but not %x\n", __LINE__, buffer[0]);
1927         test_control_return(1);
1928     }
1929 
1930     /* GetInterface(2, 1) */
1931     transfer_request -> ux_transfer_request_index =             1;
1932     status = ux_host_stack_transfer_request(transfer_request);
1933     if (status != UX_SUCCESS)
1934     {
1935 
1936         printf("ERROR #%d: GetInterface must be OK\n", __LINE__);
1937         test_control_return(1);
1938     }
1939     if (buffer[0] != 0)
1940     {
1941 
1942         printf("ERROR #%d: GetInterface must return 0 but not %x\n", __LINE__, buffer[0]);
1943         test_control_return(1);
1944     }
1945 
1946     /* SetInterface(1, 1), OK or STALL due to no class driver on device side. */
1947     transfer_request -> ux_transfer_request_function =          UX_SET_INTERFACE;
1948     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1949     transfer_request -> ux_transfer_request_value =             1;
1950     transfer_request -> ux_transfer_request_index =             1;
1951     status = ux_host_stack_transfer_request(transfer_request);
1952     if (status != UX_SUCCESS && status != UX_TRANSFER_STALLED)
1953     {
1954 
1955         printf("ERROR #%d: SetInterface(1,1) status %x\n", __LINE__, status);
1956         test_control_return(1);
1957     }
1958 
1959     /* SetInterface(1, 2), OK or STALL due to no class driver on device side. */
1960     transfer_request -> ux_transfer_request_value =             2;
1961     transfer_request -> ux_transfer_request_index =             1;
1962     status = ux_host_stack_transfer_request(transfer_request);
1963     if (status != UX_SUCCESS && status != UX_TRANSFER_STALLED)
1964     {
1965 
1966         printf("ERROR #%d: SetInterface(1,2) status %x\n", __LINE__, status);
1967         test_control_return(1);
1968     }
1969 
1970     /* SetInterface(1, 0), OK or STALL due to no class driver on device side. */
1971     transfer_request -> ux_transfer_request_value =             0;
1972     transfer_request -> ux_transfer_request_index =             1;
1973     status = ux_host_stack_transfer_request(transfer_request);
1974     if (status != UX_SUCCESS && status != UX_TRANSFER_STALLED)
1975     {
1976 
1977         printf("ERROR #%d: SetInterface(1,0) status %x\n", __LINE__, status);
1978         test_control_return(1);
1979     }
1980 
1981     stepinfo(">>>>>>>>>>>>>>>> Test SetDescriptor\n");
1982     transfer_request -> ux_transfer_request_data_pointer =      UX_NULL;
1983     transfer_request -> ux_transfer_request_requested_length =  0;
1984     transfer_request -> ux_transfer_request_function =          UX_SET_DESCRIPTOR;
1985     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1986     transfer_request -> ux_transfer_request_value =             0;
1987     transfer_request -> ux_transfer_request_index =             0;
1988     /* SetDescriptor should OK or STALL */
1989     status = ux_host_stack_transfer_request(transfer_request);
1990     if (status != UX_SUCCESS && status != UX_TRANSFER_STALLED)
1991     {
1992 
1993         printf("ERROR #%d: SetDescriptor status %x\n", __LINE__, status);
1994         test_control_return(1);
1995     }
1996 
1997     stepinfo(">>>>>>>>>>>>>>>> Test SyncFrame\n");
1998     transfer_request -> ux_transfer_request_data_pointer =      UX_NULL;
1999     transfer_request -> ux_transfer_request_requested_length =  0;
2000     transfer_request -> ux_transfer_request_function =          UX_SYNCH_FRAME;
2001     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
2002     transfer_request -> ux_transfer_request_value =             0;
2003     transfer_request -> ux_transfer_request_index =             0;
2004     /* SyncFrame should OK or STALL */
2005     status = ux_host_stack_transfer_request(transfer_request);
2006     if (status != UX_SUCCESS && status != UX_TRANSFER_STALLED)
2007     {
2008 
2009         printf("ERROR #%d: SyncFrame status %x\n", __LINE__, status);
2010         test_control_return(1);
2011     }
2012 
2013     stepinfo(">>>>>>>>>>>>>>>> Test Unknown Request\n");
2014     /* Unknown request should STALL */
2015     transfer_request -> ux_transfer_request_function =          20;
2016     status = ux_host_stack_transfer_request(transfer_request);
2017     if (status != UX_TRANSFER_STALLED)
2018     {
2019 
2020         printf("ERROR #%d: Unknown request status %x\n", __LINE__, status);
2021         test_control_return(1);
2022     }
2023 
2024     stepinfo(">>>>>>>>>>>>>>>> Test Class Request\n");
2025     transfer_request -> ux_transfer_request_function =          UX_HOST_CLASS_CDC_ACM_REQ_GET_LINE_CODING;
2026     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_DEVICE;
2027     /* Check DCD transfer call */
2028     error_counter = 0;
2029     ux_test_dcd_sim_slave_set_actions(dcd_transfer_is_called);
2030     /* Process request */
2031     status = ux_host_stack_transfer_request(transfer_request);
2032     if (status != UX_SUCCESS)
2033     {
2034 
2035         printf("ERROR #%d: Class request status %x\n", __LINE__, status);
2036         test_control_return(1);
2037     }
2038     if (error_counter == 0)
2039     {
2040 
2041         printf("ERROR #%d: Class request no DCD transfer\n", __LINE__);
2042         test_control_return(1);
2043     }
2044 
2045     class_entry_rc = UX_ERROR;
2046     status = ux_host_stack_transfer_request(transfer_request);
2047     if (status != UX_TRANSFER_STALLED)
2048     {
2049 
2050         printf("ERROR #%d: Vendor request status %x\n", __LINE__, status);
2051         test_control_return(1);
2052     }
2053 
2054     stepinfo(">>>>>>>>>>>>>>>> Test Vendor Request\n");
2055     transfer_request -> ux_transfer_request_function =          0xEE;
2056     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
2057     status = ux_host_stack_transfer_request(transfer_request);
2058     if (status != UX_TRANSFER_STALLED)
2059     {
2060 
2061         printf("ERROR #%d: Vendor request status %x\n", __LINE__, status);
2062         test_control_return(1);
2063     }
2064 
2065     stepinfo(">>>>>>>>>>>>>>>> Test MS Vendor Request\n");
2066     transfer_request -> ux_transfer_request_function =          UX_DEMO_VENDOR_REQUEST;
2067 
2068     vendor_req_rc = UX_ERROR;
2069     status = ux_host_stack_transfer_request(transfer_request);
2070     if (status != UX_TRANSFER_STALLED)
2071     {
2072 
2073         printf("ERROR #%d: Vendor request status %x\n", __LINE__, status);
2074         test_control_return(1);
2075     }
2076     vendor_req_rc = UX_SUCCESS;
2077 
2078     status = ux_host_stack_transfer_request(transfer_request);
2079     if (status != UX_SUCCESS)
2080     {
2081 
2082         printf("ERROR #%d: Vendor request status %x\n", __LINE__, status);
2083         test_control_return(1);
2084     }
2085 
2086     stepinfo(">>>>>>>>>>>>>>>> ux_slave_transfer_request_status_phase_ignore\n");
2087     /* DCD should not been called */
2088     slave_transfer_request->ux_slave_transfer_request_status_phase_ignore = UX_TRUE;
2089     error_counter = 0;
2090     ux_test_dcd_sim_slave_set_actions(dcd_transfer_is_called);
2091     status = _ux_device_stack_transfer_request(slave_transfer_request, 18, 18);
2092     if (status != UX_SUCCESS)
2093     {
2094 
2095         printf("ERROR #%d: Request not success: %x\n", __LINE__, status);
2096         test_control_return(1);
2097     }
2098     if (error_counter != 0)
2099     {
2100 
2101         printf("ERROR #%d: Unexpected call\n", __LINE__);
2102         test_control_return(1);
2103     }
2104     slave_transfer_request->ux_slave_transfer_request_status_phase_ignore = UX_FALSE;
2105 
2106 
2107     /* Finally disconnect the device. */
2108     ux_device_stack_disconnect();
2109 
2110     /* And deinitialize the class.  */
2111     status =  ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
2112 
2113     /* Deinitialize the device side of usbx.  */
2114     _ux_device_stack_uninitialize();
2115 
2116     /* And finally the usbx system resources.  */
2117     _ux_system_uninitialize();
2118 
2119     /* Successful test.  */
2120     printf("SUCCESS!\n");
2121     test_control_return(0);
2122 
2123 }
2124 
tx_test_thread_simulation1_entry(ULONG arg)2125 void  tx_test_thread_simulation1_entry(ULONG arg)
2126 {
2127 
2128 UINT status;
2129 ULONG                                               actual_length;
2130 
2131     while(1)
2132     {
2133         while(cdc_acm_slave != UX_NULL && cdc_acm_slave_reading)
2134         {
2135 
2136             status = ux_device_class_cdc_acm_read(cdc_acm_slave, buffer, 64, &actual_length);
2137 
2138             if (status == UX_SUCCESS && actual_length)
2139             {
2140 
2141                 if (ux_utility_memory_compare("TSTALL\n", buffer, 7) == UX_SUCCESS)
2142                 {
2143 
2144                     status = test_ux_device_class_cdc_acm_read_halt(cdc_acm_slave);
2145                     if (status != UX_SUCCESS)
2146                     {
2147 
2148                         printf("ERROR #%d: set halt fail: %x\n", __LINE__, status);
2149                         test_control_return(1);
2150                     }
2151                 }
2152             }
2153         }
2154 
2155         /* Sleep so ThreadX on Win32 will delete this thread. */
2156         tx_thread_sleep(10);
2157     }
2158 }
2159