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 #include "ux_host_class_cdc_acm.h"
14 
15 #include "ux_test_dcd_sim_slave.h"
16 #include "ux_test_hcd_sim_host.h"
17 #include "ux_test_utility_sim.h"
18 
19 /* Define constants.  */
20 #define                             UX_DEMO_DEBUG_SIZE  (4096*8)
21 #define                             UX_DEMO_STACK_SIZE  1024
22 #define                             UX_DEMO_BUFFER_SIZE (UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1)
23 #define                             UX_DEMO_XMIT_BUFFER_SIZE 512
24 #define                             UX_DEMO_RECEPTION_BUFFER_SIZE 512
25 #define                             UX_DEMO_FILE_BUFFER_SIZE 512
26 #define                             UX_DEMO_RECEPTION_BLOCK_SIZE 64
27 #define                             UX_DEMO_MEMORY_SIZE     (64*1024)
28 #define                             UX_DEMO_FILE_SIZE       (128 * 1024)
29 #define                             UX_RAM_DISK_MEMORY      (256 * 1024)
30 
31 /* Define local/extern function prototypes.  */
32 static VOID                                test_thread_entry(ULONG);
33 static TX_THREAD                           tx_test_thread_host_simulation;
34 static TX_THREAD                           tx_test_thread_slave_simulation;
35 static VOID                                tx_test_thread_host_simulation_entry(ULONG);
36 static VOID                                tx_test_thread_slave_simulation_entry(ULONG);
37 static VOID                                test_cdc_instance_activate(VOID  *cdc_instance);
38 static VOID                                test_cdc_instance_deactivate(VOID *cdc_instance);
39 static VOID                                test_cdc_instance_parameter_change(VOID *cdc_instance);
40 
41 static UINT                                test_slave_change_function(ULONG change);
42 
43 static VOID                                ux_test_hcd_entry_should_not_be_called(UX_TEST_ACTION *action, VOID *params);
44 static VOID                                ux_test_hcd_entry_disconnect(UX_TEST_ACTION *action, VOID *params);
45 static VOID                                ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params);
46 
47 static VOID                                ux_test_system_host_enum_hub_function(VOID);
48 
49 /* Define global data structures.  */
50 UCHAR                               usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
51 UX_HOST_CLASS                       *class_driver;
52 UX_HOST_CLASS_CDC_ACM               *cdc_acm_host_control;
53 UX_HOST_CLASS_CDC_ACM               *cdc_acm_host_data;
54 ULONG                               command_received_count;
55 UCHAR                               cdc_acm_reception_buffer[UX_DEMO_RECEPTION_BUFFER_SIZE];
56 UCHAR                               cdc_acm_xmit_buffer[UX_DEMO_XMIT_BUFFER_SIZE];
57 UX_HOST_CLASS_CDC_ACM_RECEPTION     cdc_acm_reception;
58 UCHAR                               *global_reception_buffer;
59 ULONG                               global_reception_size;
60 
61 UX_SLAVE_CLASS_CDC_ACM              *cdc_acm_slave;
62 UCHAR                               cdc_acm_slave_change;
63 UX_SLAVE_CLASS_CDC_ACM_PARAMETER    parameter;
64 UCHAR                               buffer[UX_DEMO_BUFFER_SIZE];
65 ULONG                               echo_mode;
66 
67 ULONG                               enum_counter;
68 
69 ULONG                               error_counter;
70 
71 ULONG                               set_cfg_counter;
72 
73 ULONG                               rsc_mem_free_on_set_cfg;
74 ULONG                               rsc_sem_on_set_cfg;
75 ULONG                               rsc_sem_get_on_set_cfg;
76 ULONG                               rsc_mutex_on_set_cfg;
77 
78 ULONG                               rsc_enum_sem_usage;
79 ULONG                               rsc_enum_sem_get_count;
80 ULONG                               rsc_enum_mutex_usage;
81 ULONG                               rsc_enum_mem_usage;
82 
83 /* Define device framework.  */
84 
85 #define             DEVICE_FRAMEWORK_LENGTH_FULL_SPEED      93
86 #define             DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED      103
87 #define             STRING_FRAMEWORK_LENGTH                 47
88 #define             LANGUAGE_ID_FRAMEWORK_LENGTH            2
89 
90 static unsigned char device_framework_full_speed[] = {
91 
92     /* Device descriptor     18 bytes
93        0x02 bDeviceClass:    CDC class code
94        0x00 bDeviceSubclass: CDC class sub code
95        0x00 bDeviceProtocol: CDC Device protocol
96 
97        idVendor & idProduct - http://www.linux-usb.org/usb.ids
98     */
99     0x12, 0x01, 0x10, 0x01,
100     0xEF, 0x02, 0x01,
101     0x08,
102     0x84, 0x84, 0x00, 0x00,
103     0x00, 0x01,
104     0x01, 0x02, 03,
105     0x01,
106 
107     /* Configuration 1 descriptor 9 bytes */
108     0x09, 0x02, 0x4b, 0x00,
109     0x02, 0x01, 0x00,
110     0x40, 0x00,
111 
112     /* Interface association descriptor. 8 bytes.  */
113     0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
114 
115     /* Communication Class Interface Descriptor Requirement. 9 bytes.   */
116     0x09, 0x04, 0x00,
117     0x00,
118     0x01,
119     0x02, 0x02, 0x01,
120     0x00,
121 
122     /* Header Functional Descriptor 5 bytes */
123     0x05, 0x24, 0x00,
124     0x10, 0x01,
125 
126     /* ACM Functional Descriptor 4 bytes */
127     0x04, 0x24, 0x02,
128     0x0f,
129 
130     /* Union Functional Descriptor 5 bytes */
131     0x05, 0x24, 0x06,
132     0x00,                          /* Master interface */
133     0x01,                          /* Slave interface  */
134 
135     /* Call Management Functional Descriptor 5 bytes */
136     0x05, 0x24, 0x01,
137     0x03,
138     0x01,                          /* Data interface   */
139 
140     /* Endpoint 0x83 descriptor 7 bytes */
141     0x07, 0x05, 0x83,
142     0x03,
143     0x08, 0x00,
144     0xFF,
145 
146     /* Data Class Interface Descriptor Requirement 9 bytes */
147     0x09, 0x04, 0x01,
148     0x00,
149     0x02,
150     0x0A, 0x00, 0x00,
151     0x00,
152 
153     /* Endpoint 0x81 descriptor 7 bytes */
154     0x07, 0x05, 0x81, /* @ 93 - 14 + 2 = 81 */
155     0x02,
156     0x40, 0x00,
157     0x00,
158 
159     /* Endpoint 0x02 descriptor 7 bytes */
160     0x07, 0x05, 0x02, /* @ 93 - 7 + 2 = 88 */
161     0x02,
162     0x40, 0x00,
163     0x00,
164 
165 };
166 
167 #define DEVICE_FRAMEWORK_EPA_POS_1_FS (DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 14 + 2)
168 #define DEVICE_FRAMEWORK_EPA_POS_2_FS (DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 7 + 2)
169 
170 static unsigned char device_framework_high_speed[] = {
171 
172     /* Device descriptor
173        0x02 bDeviceClass:    CDC class code
174        0x00 bDeviceSubclass: CDC class sub code
175        0x00 bDeviceProtocol: CDC Device protocol
176 
177        idVendor & idProduct - http://www.linux-usb.org/usb.ids
178     */
179     0x12, 0x01, 0x00, 0x02,
180     0xEF, 0x02, 0x01,
181     0x40,
182     0x84, 0x84, 0x00, 0x00,
183     0x00, 0x01,
184     0x01, 0x02, 03,
185     0x01,
186 
187     /* Device qualifier descriptor */
188     0x0a, 0x06, 0x00, 0x02,
189     0x02, 0x00, 0x00,
190     0x40,
191     0x01,
192     0x00,
193 
194     /* Configuration 1 descriptor */
195     0x09, 0x02, 0x4b, 0x00,
196     0x02, 0x01, 0x00,
197     0x40, 0x00,
198 
199     /* Interface association descriptor. */
200     0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
201 
202     /* Communication Class Interface Descriptor Requirement */
203     0x09, 0x04, 0x00,
204     0x00,
205     0x01,
206     0x02, 0x02, 0x01,
207     0x00,
208 
209     /* Header Functional Descriptor */
210     0x05, 0x24, 0x00,
211     0x10, 0x01,
212 
213     /* ACM Functional Descriptor */
214     0x04, 0x24, 0x02,
215     0x0f,
216 
217     /* Union Functional Descriptor */
218     0x05, 0x24, 0x06,
219     0x00,
220     0x01,
221 
222     /* Call Management Functional Descriptor */
223     0x05, 0x24, 0x01,
224     0x00,
225     0x01,
226 
227     /* Endpoint 0x83 descriptor */
228     0x07, 0x05, 0x83,
229     0x03,
230     0x08, 0x00,
231     0xFF,
232 
233     /* Data Class Interface Descriptor Requirement */
234     0x09, 0x04, 0x01,
235     0x00,
236     0x02,
237     0x0A, 0x00, 0x00,
238     0x00,
239 
240     /* Endpoint 0x81 descriptor */
241     0x07, 0x05, 0x81, /* @ 103 - 14 + 2 = 91 */
242     0x02,
243     0x40, 0x00,
244     0x00,
245 
246     /* Endpoint 0x02 descriptor */
247     0x07, 0x05, 0x02, /* @ 103 - 7 + 2 = 98 */
248     0x02,
249     0x40, 0x00,
250     0x00,
251 
252 };
253 
254 #define DEVICE_FRAMEWORK_EPA_POS_1_HS (DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 14 + 2)
255 #define DEVICE_FRAMEWORK_EPA_POS_2_HS (DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 7 + 2)
256 
257 static unsigned char string_framework[] = {
258 
259     /* Manufacturer string descriptor : Index 1 - "Express Logic" */
260         0x09, 0x04, 0x01, 0x0c,
261         0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
262         0x6f, 0x67, 0x69, 0x63,
263 
264     /* Product string descriptor : Index 2 - "EL Composite device" */
265         0x09, 0x04, 0x02, 0x13,
266         0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
267         0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
268         0x69, 0x63, 0x65,
269 
270     /* Serial Number string descriptor : Index 3 - "0001" */
271         0x09, 0x04, 0x03, 0x04,
272         0x30, 0x30, 0x30, 0x31
273     };
274 
275 
276     /* Multiple languages are supported on the device, to add
277        a language besides english, the unicode language code must
278        be appended to the language_id_framework array and the length
279        adjusted accordingly. */
280 static unsigned char language_id_framework[] = {
281 
282     /* English. */
283         0x09, 0x04
284     };
285 
286 static UX_TEST_SETUP _SetAddress = UX_TEST_SETUP_SetAddress;
287 static UX_TEST_SETUP _GetDeviceDescriptor = UX_TEST_SETUP_GetDevDescr;
288 static UX_TEST_SETUP _GetConfigDescriptor = UX_TEST_SETUP_GetCfgDescr;
289 static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
290 
291 /* Test interactions */
292 
293 /* Disconnect on RESET:
294  * Host still create the EP0 and expects first SETUP request failure.
295  */
296 
297 static UX_TEST_HCD_SIM_ACTION disconnect_on_reset[] = {
298 /* function, request to match,
299    port action, port status,
300    request action, request EP, request data, request actual length, request status,
301    status, additional callback,
302    no_return */
303 {   UX_HCD_RESET_PORT, NULL,
304         UX_TRUE , UX_TEST_PORT_STATUS_DISC,
305         0         , 0, UX_NULL, 0, 0,
306         UX_SUCCESS, ux_test_hcd_entry_disconnect},
307 #if 0
308 {   UX_HCD_CREATE_ENDPOINT, NULL,
309         UX_FALSE, 0,
310         0         , 0, UX_NULL, 0, 0,
311         UX_ERROR , ux_test_hcd_entry_should_not_be_called},
312 #endif
313 {   UX_HCD_TRANSFER_REQUEST, NULL,
314         UX_FALSE, 0,
315         0         , 0, UX_NULL, 0, 0,
316         UX_ERROR , UX_NULL}, /* Request just fail on disconnect */
317 {   UX_HCD_TRANSFER_REQUEST, NULL,
318         UX_FALSE, 0,
319         0         , 0, UX_NULL, 0, 0,
320         UX_ERROR , UX_NULL},
321 {   UX_HCD_TRANSFER_REQUEST, NULL,
322         UX_FALSE, 0,
323         0         , 0, UX_NULL, 0, 0,
324         UX_ERROR , UX_NULL},
325 {   0   }
326 };
327 
328 static UX_TEST_HCD_SIM_ACTION endpoint0_create_fail[] = {
329 /* function, request to match,
330    port action, port status,
331    request action, request EP, request data, request actual length, request status,
332    status, additional callback,
333    no_return */
334 {   UX_HCD_CREATE_ENDPOINT, NULL,
335         UX_FALSE, 0,
336         0         , 0, UX_NULL, 0, 0,
337         UX_ERROR},
338 {   UX_HCD_CREATE_ENDPOINT, NULL,
339         UX_FALSE, 0,
340         0         , 0, UX_NULL, 0, 0,
341         UX_ERROR},
342 {   UX_HCD_CREATE_ENDPOINT, NULL,
343         UX_FALSE, 0,
344         0         , 0, UX_NULL, 0, 0,
345         UX_ERROR},
346 {   UX_HCD_TRANSFER_REQUEST, NULL,
347         UX_FALSE, 0,
348         0         , 0, UX_NULL, 0, 0,
349         UX_ERROR , ux_test_hcd_entry_should_not_be_called},
350 {   0   }
351 };
352 
353 static UX_TEST_HCD_SIM_ACTION disconnect_on_SetAddress[] = {
354 /* function, request to match,
355    port action, port status,
356    request action, request EP, request data, request actual length, request status,
357    status, additional callback,
358    no_return */
359 {   UX_HCD_TRANSFER_REQUEST, &_SetAddress,
360         UX_TRUE, UX_TEST_PORT_STATUS_DISC,
361         UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
362         UX_ERROR},
363 {   UX_HCD_TRANSFER_REQUEST, &_SetAddress,
364         UX_TRUE, UX_TEST_PORT_STATUS_DISC,
365         UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
366         UX_ERROR},
367 {   UX_HCD_TRANSFER_REQUEST, &_SetAddress,
368         UX_TRUE, UX_TEST_PORT_STATUS_DISC,
369         UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
370         UX_ERROR},
371 {   0   }
372 };
373 
374 static UX_TEST_HCD_SIM_ACTION disconnect_on_GetDevDescr[] = {
375 /* function, request to match,
376    port action, port status,
377    request action, request EP, request data, request actual length, request status,
378    status, additional callback,
379    no_return */
380 {   UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
381         UX_TRUE, UX_TEST_PORT_STATUS_DISC,
382         UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
383         UX_ERROR},
384 {   UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
385         UX_TRUE, UX_TEST_PORT_STATUS_DISC,
386         UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
387         UX_ERROR},
388 {   UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
389         UX_FALSE, UX_TEST_PORT_STATUS_DISC,
390         UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
391         0, UX_NULL,
392         UX_TRUE},
393 {   UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
394         UX_TRUE, UX_TEST_PORT_STATUS_DISC,
395         UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
396         UX_ERROR},
397 {   0   }
398 };
399 
400 static UX_TEST_HCD_SIM_ACTION disconnect_on_GetCfgDescr[] = {
401 /* function, request to match,
402    port action, port status,
403    request action, request EP, request data, request actual length, request status,
404    status, additional callback,
405    no_return */
406 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
407         UX_TRUE, UX_TEST_PORT_STATUS_DISC,
408         UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
409         UX_ERROR}, /* First try */
410 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
411         UX_TRUE, UX_TEST_PORT_STATUS_DISC,
412         UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
413         UX_ERROR}, /* Second try */
414 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
415         UX_FALSE, UX_TEST_PORT_STATUS_DISC,
416         UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
417         UX_SUCCESS, UX_NULL,
418         UX_TRUE}, /* Last try first run */
419 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
420         UX_TRUE, UX_TEST_PORT_STATUS_DISC,
421         UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
422         UX_ERROR},
423 {   0   }
424 };
425 
426 static UX_TEST_HCD_SIM_ACTION disconnect_on_SetCfg[] = {
427 /* function, request to match,
428    port action, port status,
429    request action, request EP, request data, request actual length, request status,
430    status, additional callback,
431    no_return */
432 {   UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
433         UX_TRUE, UX_TEST_PORT_STATUS_DISC,
434         UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
435         UX_ERROR}, /* First try */
436 {   UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
437         UX_TRUE, UX_TEST_PORT_STATUS_DISC,
438         UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
439         UX_ERROR}, /* Second try */
440 {   UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
441         UX_TRUE, UX_TEST_PORT_STATUS_DISC,
442         UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
443         UX_ERROR}, /* Last try */
444 {   0   }
445 };
446 
447 static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
448 /* function, request to match,
449    port action, port status,
450    request action, request EP, request data, request actual length, request status,
451    status, additional callback,
452    no_return */
453 {   UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
454         UX_FALSE, UX_TEST_PORT_STATUS_DISC,
455         UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
456         UX_SUCCESS, ux_test_hcd_entry_set_cfg,
457         UX_TRUE}, /* Invoke callback & continue */
458 {   0   }
459 };
460 
461 static UX_TEST_HCD_SIM_ACTION normal_enum_replace[] = {
462 /* function, request to match,
463    port action, port status,
464    request action, request EP, request data, request actual length, request status,
465    status, additional callback,
466    no_return */
467 {   UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
468         UX_FALSE, 0,
469         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 0, 8, 0,
470         UX_SUCCESS, UX_NULL},
471 {   UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
472         UX_FALSE, 0,
473         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 0, 18, 0,
474         UX_SUCCESS, UX_NULL},
475 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
476         UX_FALSE, 0,
477         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 18, UX_CONFIGURATION_DESCRIPTOR_LENGTH, 0,
478         UX_SUCCESS, UX_NULL},
479 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
480         UX_FALSE, 0,
481         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 18, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 18, 0,
482         UX_SUCCESS, UX_NULL},
483 {   0   }
484 }
485 ;
486 
487 /* Define the ISR dispatch.  */
488 
489 extern VOID    (*test_isr_dispatch)(void);
490 
491 
492 /* Prototype for test control return.  */
493 
494 void  test_control_return(UINT status);
495 
496 
497 /* Define the ISR dispatch routine.  */
498 
test_isr(void)499 static void    test_isr(void)
500 {
501 
502     /* For further expansion of interrupt-level testing.  */
503 }
504 
505 
test_class_cdc_acm_get(void)506 static UINT test_class_cdc_acm_get(void)
507 {
508 
509 UINT                                status;
510 UX_HOST_CLASS                       *class;
511 UX_HOST_CLASS_CDC_ACM               *cdc_acm_host;
512 
513 
514     /* Find the main cdc_acm container */
515     status =  ux_host_stack_class_get(_ux_system_host_class_cdc_acm_name, &class);
516     if (status != UX_SUCCESS)
517         return(status);
518 
519     /* We get the first instance of the cdc_acm device */
520     do
521     {
522 
523         status =  ux_host_stack_class_instance_get(class, 0, (void **) &cdc_acm_host);
524         tx_thread_sleep(10);
525     } while (status != UX_SUCCESS);
526 
527     /* We still need to wait for the cdc_acm status to be live */
528     while (cdc_acm_host -> ux_host_class_cdc_acm_state != UX_HOST_CLASS_INSTANCE_LIVE)
529         tx_thread_sleep(10);
530 
531     /* Isolate both the control and data interfaces.  */
532     if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_DATA_CLASS)
533     {
534         /* This is the data interface.  */
535         cdc_acm_host_data = cdc_acm_host;
536 
537         /* In that case, the second one should be the control interface.  */
538         status =  ux_host_stack_class_instance_get(class, 1, (void **) &cdc_acm_host);
539 
540         /* Check error.  */
541         if (status != UX_SUCCESS)
542             return(status);
543 
544         /* Check for the control interfaces.  */
545         if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
546         {
547 
548             /* This is the control interface.  */
549             cdc_acm_host_control = cdc_acm_host;
550 
551             return(UX_SUCCESS);
552 
553         }
554     }
555     else
556     {
557         /* Check for the control interfaces.  */
558         if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
559         {
560 
561             /* This is the control interface.  */
562             cdc_acm_host_control = cdc_acm_host;
563 
564             /* In that case, the second one should be the data interface.  */
565             status =  ux_host_stack_class_instance_get(class, 1, (void **) &cdc_acm_host);
566 
567             /* Check error.  */
568             if (status != UX_SUCCESS)
569                 return(status);
570 
571             /* Check for the data interface.  */
572             if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_DATA_CLASS)
573             {
574 
575                 /* This is the data interface.  */
576                 cdc_acm_host_data = cdc_acm_host;
577 
578                 return(UX_SUCCESS);
579 
580             }
581         }
582     }
583 
584     /* Return ERROR.  */
585     return(UX_ERROR);
586 }
587 
test_slave_change_function(ULONG change)588 static UINT test_slave_change_function(ULONG change)
589 {
590     return 0;
591 }
592 
test_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)593 static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
594 {
595 
596 UX_HOST_CLASS_CDC_ACM *cdc_acm = (UX_HOST_CLASS_CDC_ACM *) inst;
597 
598     switch(event)
599     {
600 
601         case UX_DEVICE_INSERTION:
602 
603             if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
604                 cdc_acm_host_control = cdc_acm;
605             else
606                 cdc_acm_host_data = cdc_acm;
607             break;
608 
609         case UX_DEVICE_REMOVAL:
610 
611             if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
612                 cdc_acm_host_control = UX_NULL;
613             else
614                 cdc_acm_host_data = UX_NULL;
615             break;
616 
617         default:
618             break;
619     }
620     return 0;
621 }
622 
test_cdc_instance_activate(VOID * cdc_instance)623 static VOID    test_cdc_instance_activate(VOID *cdc_instance)
624 {
625 
626     /* Save the CDC instance.  */
627     cdc_acm_slave = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
628 }
test_cdc_instance_deactivate(VOID * cdc_instance)629 static VOID    test_cdc_instance_deactivate(VOID *cdc_instance)
630 {
631 
632     /* Reset the CDC instance.  */
633     cdc_acm_slave = UX_NULL;
634 }
635 
test_cdc_instance_parameter_change(VOID * cdc_instance)636 static VOID test_cdc_instance_parameter_change(VOID *cdc_instance)
637 {
638 
639     /* Set CDC parameter change flag. */
640     cdc_acm_slave_change = UX_TRUE;
641 }
642 
test_swap_framework_bulk_ep_descriptors(VOID)643 static VOID test_swap_framework_bulk_ep_descriptors(VOID)
644 {
645 UCHAR tmp;
646 
647     tmp = device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_1_FS];
648     device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_1_FS] = device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_2_FS];
649     device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_2_FS] = tmp;
650 
651     tmp = device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_1_HS];
652     device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_1_HS] = device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_2_HS];
653     device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_2_HS] = tmp;
654 }
655 
656 
test_ux_error_callback(UINT system_level,UINT system_context,UINT error_code)657 static VOID test_ux_error_callback(UINT system_level, UINT system_context, UINT error_code)
658 {
659     int x = 0;
660 }
661 
ux_test_hcd_entry_should_not_be_called(UX_TEST_ACTION * action,VOID * params)662 static VOID ux_test_hcd_entry_should_not_be_called(UX_TEST_ACTION *action, VOID *params)
663 {
664 
665     error_counter ++;
666 }
667 
ux_test_hcd_entry_disconnect(UX_TEST_ACTION * action,VOID * params)668 static VOID ux_test_hcd_entry_disconnect(UX_TEST_ACTION *action, VOID *params)
669 {
670 
671     ux_test_dcd_sim_slave_disconnect();
672 }
673 
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * params)674 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params)
675 {
676 
677     set_cfg_counter ++;
678 
679     rsc_mem_free_on_set_cfg = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
680     rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
681     rsc_enum_sem_get_count = ux_test_utility_sim_sem_get_count();
682     rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
683 }
684 
ux_test_system_host_enum_hub_function(VOID)685 static VOID ux_test_system_host_enum_hub_function(VOID)
686 {
687     enum_counter ++;
688 }
689 
690 /* Define what the initial system looks like.  */
691 
692 #ifdef CTEST
test_application_define(void * first_unused_memory)693 void test_application_define(void *first_unused_memory)
694 #else
695 void    usbx_host_device_basic_test_application_define(void *first_unused_memory)
696 #endif
697 {
698 
699 UINT                    status;
700 CHAR *                  stack_pointer;
701 CHAR *                  memory_pointer;
702 
703 
704     printf("Running Host & Device Basic Functionality Test...................... ");
705 
706     /* Reset testing counts. */
707     ux_test_utility_sim_mutex_create_count_reset();
708     ux_test_utility_sim_sem_create_count_reset();
709     ux_test_utility_sim_sem_get_count_reset();
710     /* Reset error generations */
711     ux_test_utility_sim_sem_error_generation_stop();
712     ux_test_utility_sim_mutex_error_generation_stop();
713     ux_test_utility_sim_sem_get_error_generation_stop();
714 
715     /* Initialize the free memory pointer */
716     stack_pointer = (CHAR *) usbx_memory;
717     memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
718 
719     /* Initialize USBX Memory */
720     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
721 
722     /* Check for error.  */
723     if (status != UX_SUCCESS)
724     {
725 
726         printf(" ERROR #1\n");
727         test_control_return(1);
728     }
729 
730     /* Register the error callback. */
731     _ux_utility_error_callback_register(test_ux_error_callback);
732 
733     /* The code below is required for installing the host portion of USBX */
734     status =  ux_host_stack_initialize(test_host_change_function);
735     if (status != UX_SUCCESS)
736     {
737 
738         printf(" ERROR #2\n");
739         test_control_return(1);
740     }
741 
742     /* Register CDC-ACM class.  */
743     status =  ux_host_stack_class_register(_ux_system_host_class_cdc_acm_name, ux_host_class_cdc_acm_entry);
744     if (status != UX_SUCCESS)
745     {
746 
747         printf(" ERROR #3\n");
748         test_control_return(1);
749     }
750 
751     /* Simulates hub enum function */
752     enum_counter = 0;
753 #if UX_MAX_DEVICES > 1
754     _ux_system_host->ux_system_host_enum_hub_function = ux_test_system_host_enum_hub_function;
755 #endif
756 
757     /* The code below is required for installing the device portion of USBX. No call back for
758        device status change in this example. */
759     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
760                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
761                                        string_framework, STRING_FRAMEWORK_LENGTH,
762                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,
763                                        test_slave_change_function);
764     if(status!=UX_SUCCESS)
765     {
766 
767         printf(" ERROR #5\n");
768         test_control_return(1);
769     }
770 
771     /* Set the parameters for callback when insertion/extraction of a CDC device.  */
772     parameter.ux_slave_class_cdc_acm_instance_activate   =  test_cdc_instance_activate;
773     parameter.ux_slave_class_cdc_acm_instance_deactivate =  test_cdc_instance_deactivate;
774     parameter.ux_slave_class_cdc_acm_parameter_change    =  test_cdc_instance_parameter_change;
775 
776     /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
777     status =  ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
778                                              1,0,  &parameter);
779 
780     if(status!=UX_SUCCESS)
781     {
782 
783         printf(" ERROR #7\n");
784         test_control_return(1);
785     }
786 
787     /* Initialize the simulated device controller.  */
788     status =  _ux_test_dcd_sim_slave_initialize();
789 
790     /* Check for error.  */
791     if (status != TX_SUCCESS)
792     {
793 
794         printf(" ERROR #8\n");
795         test_control_return(1);
796     }
797 
798     /* Register all the USB host controllers available in this system */
799     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
800     if (status != UX_SUCCESS)
801     {
802 
803         printf(" ERROR #4\n");
804         test_control_return(1);
805     }
806 
807     /* Create the main host simulation thread.  */
808     status =  tx_thread_create(&tx_test_thread_host_simulation, "tx test host simulation", tx_test_thread_host_simulation_entry, 0,
809             stack_pointer, UX_DEMO_STACK_SIZE,
810             20, 20, 1, TX_AUTO_START);
811 
812     /* Check for error.  */
813     if (status != TX_SUCCESS)
814     {
815 
816         printf(" ERROR #9\n");
817         test_control_return(1);
818     }
819 
820     /* Create the main slave simulation  thread.  */
821     status =  tx_thread_create(&tx_test_thread_slave_simulation, "tx test slave simulation", tx_test_thread_slave_simulation_entry, 0,
822             stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
823             20, 20, 1, TX_AUTO_START);
824 
825     /* Check for error.  */
826     if (status != TX_SUCCESS)
827     {
828 
829         printf(" ERROR #10\n");
830         test_control_return(1);
831     }
832 }
833 
tx_test_thread_host_simulation_entry(ULONG arg)834 void  tx_test_thread_host_simulation_entry(ULONG arg)
835 {
836 
837 UINT                                                status;
838 ULONG                                               test_n;
839 ULONG                                               mem_free;
840 
841     stepinfo("\n");
842 
843     /* Find the cdc_acm class and wait for the link to be up.  */
844     status =  test_class_cdc_acm_get();
845     if (status != UX_SUCCESS)
846     {
847 
848         /* DPUMP basic test error.  */
849         printf("ERROR #11: class not found\n");
850         test_control_return(1);
851     }
852     if (!cdc_acm_host_control && !cdc_acm_host_data)
853     {
854 
855         printf("ERROR #12: instance not detected\n");
856         test_control_return(1);
857     }
858     stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
859 
860     /* Test disconnect. */
861     stepinfo(">>>>>>>>>>>>>>>> Test disconnect\n");
862     ux_test_dcd_sim_slave_disconnect();
863     ux_test_hcd_sim_host_disconnect();
864     if (cdc_acm_host_control || cdc_acm_host_data)
865     {
866 
867         printf("ERROR #13: instance not removed when disconnect");
868         test_control_return(1);
869     }
870     stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
871 
872     /* Reset testing counts. */
873     stepinfo(">>>>>>>>>>>>>>>> Test connect & connection resource\n");
874     ux_test_utility_sim_mutex_create_count_reset();
875     ux_test_utility_sim_sem_create_count_reset();
876     ux_test_utility_sim_sem_get_count_reset();
877     ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
878     mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
879     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
880     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
881     tx_thread_sleep(100);
882     /* Log create counts when SetConfigure for further tests. */
883     rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
884     rsc_enum_sem_usage = rsc_sem_on_set_cfg;
885     rsc_enum_sem_get_count = rsc_sem_get_on_set_cfg;
886     rsc_enum_mem_usage = mem_free - rsc_mem_free_on_set_cfg;
887     stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
888 
889     /* Reset enum counter */
890     enum_counter = 0;
891 
892     stepinfo(">>>>>>>>>>>>>>>> Test disconnect on reset\n");
893     ux_test_hcd_sim_host_disconnect();
894     ux_test_hcd_sim_host_set_actions(disconnect_on_reset);
895     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
896     if (cdc_acm_host_control || cdc_acm_host_data)
897     {
898 
899         printf("ERROR #13: instance installed when disconnect on reset");
900         test_control_return(1);
901     }
902     stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
903 #if UX_MAX_DEVICES > 1
904     /* Enumeration should be processed */
905     if (enum_counter == 0)
906     {
907 
908         printf("ERROR #%d: enum entry not invoked\n", __LINE__);
909         test_control_return(1);
910     }
911 #endif
912     stepinfo(">>>>>>>>>>>>>>>> Test EP0 fail\n");
913     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
914     ux_test_hcd_sim_host_disconnect();
915     ux_test_hcd_sim_host_set_actions(endpoint0_create_fail);
916     error_counter = 0;
917     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
918     if (error_counter)
919     {
920 
921         /* DPUMP basic test error.  */
922         printf("ERROR #14: detect EP transfer when EP0 creation fail\n");
923         test_control_return(1);
924     }
925     if (cdc_acm_host_control || cdc_acm_host_data)
926     {
927 
928         printf("ERROR #15: instance installed when EP0 creation fail\n");
929         test_control_return(1);
930     }
931     stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
932 
933     stepinfo(">>>>>>>>>>>>>>>> Test disconnect on SetAddress\n");
934     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
935     ux_test_hcd_sim_host_disconnect();
936     ux_test_hcd_sim_host_set_actions(disconnect_on_SetAddress);
937     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
938     if (cdc_acm_host_control)
939     {
940 
941         printf("ERROR #14: detect device when disconnect on SetAddress\n");
942         test_control_return(1);
943     }
944     stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
945 
946     stepinfo(">>>>>>>>>>>>>>>> Test disconnect on GetDeviceDescriptor\n");
947     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
948     ux_test_hcd_sim_host_disconnect();
949     ux_test_hcd_sim_host_set_actions(disconnect_on_GetDevDescr);
950     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
951     if (cdc_acm_host_control)
952     {
953 
954         printf("ERROR #15: detect device when disconnect on GetDeviceDescriptor\n");
955         test_control_return(1);
956     }
957     stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
958 
959     stepinfo(">>>>>>>>>>>>>>>> Test disconnect on GetConfigureDescriptor\n");
960     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
961     ux_test_hcd_sim_host_disconnect();
962     ux_test_hcd_sim_host_set_actions(disconnect_on_GetCfgDescr);
963     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
964     if (cdc_acm_host_control)
965     {
966 
967         printf("ERROR #16: detect device when disconnect on GetConfigureDescriptor\n");
968         test_control_return(1);
969     }
970     stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
971 
972     stepinfo(">>>>>>>>>>>>>>>> Test disconnect on SetConfigure\n");
973     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
974     ux_test_hcd_sim_host_disconnect();
975     ux_test_hcd_sim_host_set_actions(disconnect_on_SetCfg);
976     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
977     if (cdc_acm_host_control)
978     {
979 
980         printf("ERROR #17: detect device when disconnect on SetConfigure\n");
981         test_control_return(1);
982     }
983     stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
984 
985     stepinfo(">>>>>>>>>>>>>>>> Normal replace descriptor test\n");
986     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
987     ux_test_hcd_sim_host_disconnect();
988     ux_test_hcd_sim_host_set_actions(normal_enum_replace);
989     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
990     tx_thread_sleep(100);
991     if (!cdc_acm_host_control)
992     {
993 
994         printf("ERROR #18: no device detected when replacing DevDescr and CfgDescr\n");
995         test_control_return(1);
996     }
997     stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
998 
999     /* Swap bulk IN/OUT endpoint position.
1000        Simulate detach and attach for HS enumeration,
1001        and test possible mutex creation error handlings.
1002      */
1003     if (rsc_enum_mutex_usage) stepinfo(">>>>>>>>>>>>>>>> Mutex errors enumeration test\n");
1004     for (test_n = 0; test_n < rsc_enum_mutex_usage; test_n ++)
1005     {
1006 
1007         stepinfo("%ld / %ld\n", test_n, rsc_enum_mutex_usage - 1);
1008 
1009         /* Disconnect. */
1010         ux_test_dcd_sim_slave_disconnect();
1011         ux_test_hcd_sim_host_disconnect();
1012 
1013         /* Swap EP address. */
1014         test_swap_framework_bulk_ep_descriptors();
1015 
1016         /* Generate error while the test_n and after mutex are requested */
1017         ux_test_utility_sim_mutex_error_generation_start(test_n);
1018 
1019         /* Count SetConfigure */
1020         set_cfg_counter = 0;
1021         ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
1022 
1023         /* Connect. */
1024         ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
1025         ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
1026 
1027         if (set_cfg_counter)
1028         {
1029 
1030             printf("ERROR #19.%ld: device detected when there is mutex error\n", test_n);
1031             test_control_return(1);
1032         }
1033         stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
1034     }
1035     ux_test_utility_sim_mutex_error_generation_stop();
1036     if (rsc_enum_mutex_usage) stepinfo("\n");
1037 
1038     /* Simulate detach and attach for FS enumeration,
1039        and test possible semaphore creation error handlings.
1040        Note CDC ACM has two semaphore for bulk endpoints, not tested here.
1041      */
1042     if (rsc_enum_sem_usage) stepinfo(">>>>>>>>>>>>>>>> Semaphore errors enumeration test\n");
1043     for (test_n = 0; test_n < rsc_enum_sem_usage; test_n ++)
1044     {
1045 
1046         stepinfo("%2ld / %2ld\n", test_n, rsc_enum_sem_usage - 1);
1047 
1048         /* Disconnect. */
1049         ux_test_dcd_sim_slave_disconnect();
1050         ux_test_hcd_sim_host_disconnect();
1051 
1052         /* Generate error while the test_n and after semaphore are requested */
1053         ux_test_utility_sim_sem_error_generation_start(test_n);
1054 
1055         /* Count SetConfigure */
1056         set_cfg_counter = 0;
1057         ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
1058 
1059         /* Connect. */
1060         ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1061         ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1062 
1063         /* Check error */
1064         if (set_cfg_counter)
1065         {
1066 
1067             printf("ERROR #21.%ld: device detected when there is semaphore error\n", test_n);
1068             test_control_return(1);
1069         }
1070         stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
1071     }
1072     ux_test_utility_sim_sem_error_generation_stop();
1073     if (rsc_enum_sem_usage) stepinfo("\n");
1074 
1075     /* Simulate detach and attach for FS enumeration,
1076        and test possible semaphore get error handlings.
1077      */
1078     if (rsc_enum_sem_get_count) stepinfo(">>>>>>>>>>>>>>>> Semaphore GET errors enumeration test\n");
1079     for (test_n = 0; test_n < rsc_enum_sem_get_count; test_n ++)
1080     {
1081 
1082         stepinfo("%2ld / %2ld\n", test_n, rsc_enum_sem_get_count - 1);
1083 
1084         /* Disconnect. */
1085         ux_test_dcd_sim_slave_disconnect();
1086         ux_test_hcd_sim_host_disconnect();
1087 
1088         /* Generate error while the test_n and after semaphore are requested */
1089         ux_test_utility_sim_sem_get_error_generation_start(test_n);
1090 
1091         /* Count SetConfigure */
1092         set_cfg_counter = 0;
1093         ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
1094 
1095         /* Connect. */
1096         ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1097         ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1098 
1099         if (set_cfg_counter)
1100         {
1101 
1102             printf("ERROR #24.%ld: device detected when there is semaphore GET error\n", test_n);
1103             test_control_return(1);
1104         }
1105         stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
1106     }
1107     ux_test_utility_sim_sem_get_error_generation_stop();
1108     if (rsc_enum_sem_usage) stepinfo("\n");
1109 
1110     /* Finally disconnect the device. */
1111     ux_device_stack_disconnect();
1112 
1113     /* And deinitialize the class.  */
1114     status =  ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
1115 
1116     /* Deinitialize the device side of usbx.  */
1117     _ux_device_stack_uninitialize();
1118 
1119     /* And finally the usbx system resources.  */
1120     _ux_system_uninitialize();
1121 
1122     /* Successful test.  */
1123     printf("SUCCESS!\n");
1124     test_control_return(0);
1125 
1126 }
1127 
tx_test_thread_slave_simulation_entry(ULONG arg)1128 void  tx_test_thread_slave_simulation_entry(ULONG arg)
1129 {
1130 
1131     while(1)
1132     {
1133 
1134         /* Sleep so ThreadX on Win32 will delete this thread. */
1135         tx_thread_sleep(10);
1136     }
1137 }
1138