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 #if 0 /* TODO: Enable/disable stepinfo */
20 #define stepinfo printf
21 #else
22 #define stepinfo(...)
23 #endif
24 
25 /* Define constants.  */
26 #define                             UX_DEMO_DEBUG_SIZE  (4096*8)
27 #define                             UX_DEMO_STACK_SIZE  1024
28 #define                             UX_DEMO_BUFFER_SIZE (UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1)
29 #define                             UX_DEMO_XMIT_BUFFER_SIZE 512
30 #define                             UX_DEMO_RECEPTION_BUFFER_SIZE 512
31 #define                             UX_DEMO_FILE_BUFFER_SIZE 512
32 #define                             UX_DEMO_RECEPTION_BLOCK_SIZE 64
33 #define                             UX_DEMO_MEMORY_SIZE     (64*1024)
34 #define                             UX_DEMO_FILE_SIZE       (128 * 1024)
35 #define                             UX_RAM_DISK_MEMORY      (256 * 1024)
36 
37 /* Define local/extern function prototypes.  */
38 static VOID                         test_thread_entry(ULONG);
39 static TX_THREAD                    tx_test_thread_host_simulation;
40 static TX_THREAD                    tx_test_thread_slave_simulation;
41 static VOID                         tx_test_thread_host_simulation_entry(ULONG);
42 static VOID                         tx_test_thread_slave_simulation_entry(ULONG);
43 static VOID                         test_cdc_instance_activate(VOID  *cdc_instance);
44 static VOID                         test_cdc_instance_deactivate(VOID *cdc_instance);
45 static VOID                         test_cdc_instance_parameter_change(VOID *cdc_instance);
46 
47 static VOID                         ux_test_hcd_entry_should_not_be_called(UX_HCD *hcd, UX_TEST_HCD_SIM_ACTION *action, VOID *parameter);
48 static VOID                         ux_test_hcd_entry_disconnect(UX_HCD *hcd, UX_TEST_HCD_SIM_ACTION *action, VOID *parameter);
49 static VOID                         ux_test_hcd_entry_set_cfg(UX_HCD *hcd, UX_TEST_HCD_SIM_ACTION *action, VOID *parameter);
50 
51 /* Define global data structures.  */
52 UCHAR                               usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
53 UX_HOST_CLASS                       *class_driver;
54 UX_HOST_CLASS_CDC_ACM               *cdc_acm_host_control;
55 UX_HOST_CLASS_CDC_ACM               *cdc_acm_host_data;
56 ULONG                               command_received_count;
57 UCHAR                               cdc_acm_reception_buffer[UX_DEMO_RECEPTION_BUFFER_SIZE];
58 UCHAR                               cdc_acm_xmit_buffer[UX_DEMO_XMIT_BUFFER_SIZE];
59 UX_HOST_CLASS_CDC_ACM_RECEPTION     cdc_acm_reception;
60 UCHAR                               *global_reception_buffer;
61 ULONG                               global_reception_size;
62 
63 UX_SLAVE_CLASS_CDC_ACM              *cdc_acm_slave;
64 UCHAR                               cdc_acm_slave_change;
65 UX_SLAVE_CLASS_CDC_ACM_PARAMETER    parameter;
66 UCHAR                               buffer[UX_DEMO_BUFFER_SIZE];
67 ULONG                               echo_mode;
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_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)588 static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
589 {
590 
591 UX_HOST_CLASS_CDC_ACM *cdc_acm = (UX_HOST_CLASS_CDC_ACM *) inst;
592 
593     switch(event)
594     {
595 
596         case UX_DEVICE_INSERTION:
597 
598             if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
599                 cdc_acm_host_control = cdc_acm;
600             else
601                 cdc_acm_host_data = cdc_acm;
602             break;
603 
604         case UX_DEVICE_REMOVAL:
605 
606             if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
607                 cdc_acm_host_control = UX_NULL;
608             else
609                 cdc_acm_host_data = UX_NULL;
610             break;
611 
612         default:
613             break;
614     }
615     return 0;
616 }
617 
test_cdc_instance_activate(VOID * cdc_instance)618 static VOID test_cdc_instance_activate(VOID *cdc_instance)
619 {
620 
621     /* Save the CDC instance.  */
622     cdc_acm_slave = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
623 }
test_cdc_instance_deactivate(VOID * cdc_instance)624 static VOID test_cdc_instance_deactivate(VOID *cdc_instance)
625 {
626 
627     /* Reset the CDC instance.  */
628     cdc_acm_slave = UX_NULL;
629 }
630 
test_cdc_instance_parameter_change(VOID * cdc_instance)631 static VOID test_cdc_instance_parameter_change(VOID *cdc_instance)
632 {
633 
634     /* Set CDC parameter change flag. */
635     cdc_acm_slave_change = UX_TRUE;
636 }
637 
test_swap_framework_bulk_ep_descriptors(VOID)638 static VOID test_swap_framework_bulk_ep_descriptors(VOID)
639 {
640 UCHAR tmp;
641 
642     tmp = device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_1_FS];
643     device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_1_FS] = device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_2_FS];
644     device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_2_FS] = tmp;
645 
646     tmp = device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_1_HS];
647     device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_1_HS] = device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_2_HS];
648     device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_2_HS] = tmp;
649 }
650 
651 
test_ux_error_callback(UINT system_level,UINT system_context,UINT error_code)652 static VOID test_ux_error_callback(UINT system_level, UINT system_context, UINT error_code)
653 {
654 }
655 
ux_test_hcd_entry_should_not_be_called(UX_HCD * hcd,UX_TEST_HCD_SIM_ACTION * action,VOID * parameter)656 static VOID ux_test_hcd_entry_should_not_be_called(UX_HCD *hcd, UX_TEST_HCD_SIM_ACTION *action, VOID *parameter)
657 {
658 
659     error_counter ++;
660 }
661 
ux_test_hcd_entry_disconnect(UX_HCD * hcd,UX_TEST_HCD_SIM_ACTION * action,VOID * parameter)662 static VOID ux_test_hcd_entry_disconnect(UX_HCD *hcd, UX_TEST_HCD_SIM_ACTION *action, VOID *parameter)
663 {
664 
665     ux_test_dcd_sim_slave_disconnect();
666 }
667 
ux_test_hcd_entry_set_cfg(UX_HCD * hcd,UX_TEST_HCD_SIM_ACTION * action,VOID * parameter)668 static VOID ux_test_hcd_entry_set_cfg(UX_HCD *hcd, UX_TEST_HCD_SIM_ACTION *action, VOID *parameter)
669 {
670 
671     set_cfg_counter ++;
672 
673     rsc_mem_free_on_set_cfg = _ux_system->ux_system_regular_memory_pool_free;
674     rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
675     rsc_enum_sem_get_count = ux_test_utility_sim_sem_get_count();
676     rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
677 }
678 
679 /* Define what the initial system looks like.  */
680 
681 #ifdef CTEST
test_application_define(void * first_unused_memory)682 void test_application_define(void *first_unused_memory)
683 #else
684 void    usbx_host_basic_memory_test_application_define(void *first_unused_memory)
685 #endif
686 {
687 
688 UINT                    status;
689 CHAR *                  stack_pointer;
690 CHAR *                  memory_pointer;
691 ULONG                   test_n;
692 
693     printf("Running Host Basic Memory Test............................ ");
694 
695     /* Reset testing counts. */
696     ux_test_utility_sim_mutex_create_count_reset();
697     ux_test_utility_sim_sem_create_count_reset();
698     ux_test_utility_sim_sem_get_count_reset();
699 
700     /* Initialize the free memory pointer */
701     stack_pointer = (CHAR *) usbx_memory;
702     memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
703 
704     /* Initialize USBX Memory */
705     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
706 
707     /* Check for error.  */
708     if (status != UX_SUCCESS)
709     {
710 
711         printf(" ERROR #1\n");
712         test_control_return(1);
713     }
714 
715     /* Register the error callback. */
716     _ux_utility_error_callback_register(test_ux_error_callback);
717 
718     /* The code below is required for installing the host portion of USBX */
719     status =  ux_host_stack_initialize(test_host_change_function);
720     if (status != UX_SUCCESS)
721     {
722 
723         printf(" ERROR #2\n");
724         test_control_return(1);
725     }
726 
727     /* Register CDC-ACM class.  */
728     status =  ux_host_stack_class_register(_ux_system_host_class_cdc_acm_name, ux_host_class_cdc_acm_entry);
729     if (status != UX_SUCCESS)
730     {
731 
732         printf(" ERROR #3\n");
733         test_control_return(1);
734     }
735 
736     /* Register all the USB host controllers available in this system */
737     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
738     if (status != UX_SUCCESS)
739     {
740 
741         printf(" ERROR #4\n");
742         test_control_return(1);
743     }
744 
745     /* The code below is required for installing the device portion of USBX. No call back for
746        device status change in this example. */
747     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
748                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
749                                        string_framework, STRING_FRAMEWORK_LENGTH,
750                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
751     if(status!=UX_SUCCESS)
752     {
753 
754         printf(" ERROR #5\n");
755         test_control_return(1);
756     }
757 
758     /* Set the parameters for callback when insertion/extraction of a CDC device.  */
759     parameter.ux_slave_class_cdc_acm_instance_activate   =  test_cdc_instance_activate;
760     parameter.ux_slave_class_cdc_acm_instance_deactivate =  test_cdc_instance_deactivate;
761     parameter.ux_slave_class_cdc_acm_parameter_change    =  test_cdc_instance_parameter_change;
762 
763     /* Mutex will be created on initialize to protect CDC Bulk IN/OUT */
764     for (test_n = 0; test_n < 2; test_n ++)
765     {
766         ux_test_utility_sim_mutex_error_generation_start(test_n);
767         status =  ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
768                                                  1,0,  &parameter);
769         /* Mutex error should be reported */
770         if(status != UX_MUTEX_ERROR)
771         {
772 
773             printf(" ERROR #6.%ld\n", test_n);
774             test_control_return(1);
775         }
776     }
777     ux_test_utility_sim_mutex_error_generation_stop();
778 
779     /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
780     status =  ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
781                                              1,0,  &parameter);
782 
783     if(status!=UX_SUCCESS)
784     {
785 
786         printf(" ERROR #7\n");
787         test_control_return(1);
788     }
789 
790     /* Initialize the simulated device controller.  */
791     status =  _ux_dcd_sim_slave_initialize();
792 
793     /* Check for error.  */
794     if (status != TX_SUCCESS)
795     {
796 
797         printf(" ERROR #8\n");
798         test_control_return(1);
799     }
800 
801     /* Create the main host simulation thread.  */
802     status =  tx_thread_create(&tx_test_thread_host_simulation, "tx test host simulation", tx_test_thread_host_simulation_entry, 0,
803             stack_pointer, UX_DEMO_STACK_SIZE,
804             20, 20, 1, TX_AUTO_START);
805 
806     /* Check for error.  */
807     if (status != TX_SUCCESS)
808     {
809 
810         printf(" ERROR #9\n");
811         test_control_return(1);
812     }
813 
814     /* Create the main slave simulation  thread.  */
815     status =  tx_thread_create(&tx_test_thread_slave_simulation, "tx test slave simulation", tx_test_thread_slave_simulation_entry, 0,
816             stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
817             20, 20, 1, TX_AUTO_START);
818 
819     /* Check for error.  */
820     if (status != TX_SUCCESS)
821     {
822 
823         printf(" ERROR #10\n");
824         test_control_return(1);
825     }
826 }
827 
tx_test_thread_host_simulation_entry(ULONG arg)828 void  tx_test_thread_host_simulation_entry(ULONG arg)
829 {
830 
831 UINT                                                status;
832 ULONG                                               actual_length;
833 ULONG                                               test_n;
834 ULONG                                               mem_free;
835 
836     stepinfo("\n");
837 
838     /* Find the cdc_acm class and wait for the link to be up.  */
839     status =  test_class_cdc_acm_get();
840     if (status != UX_SUCCESS)
841     {
842 
843         /* DPUMP basic test error.  */
844         printf("ERROR #11: class not found\n");
845         test_control_return(1);
846     }
847     if (!cdc_acm_host_control && !cdc_acm_host_data)
848     {
849 
850         printf("ERROR #12: instance not detected\n");
851         test_control_return(1);
852     }
853     stepinfo("mem free: %ld\n", _ux_system->ux_system_regular_memory_pool_free);
854 
855     /* Test disconnect. */
856     stepinfo(">>>>>>>>>>>>>>>> Test disconnect\n");
857     ux_test_dcd_sim_slave_disconnect();
858     ux_test_hcd_sim_host_disconnect();
859     if (cdc_acm_host_control || cdc_acm_host_data)
860     {
861 
862         printf("ERROR #13: instance not removed when disconnect");
863         test_control_return(1);
864     }
865     stepinfo("mem free: %ld\n", _ux_system->ux_system_regular_memory_pool_free);
866 
867     /* Reset testing counts. */
868     stepinfo(">>>>>>>>>>>>>>>> Test connect & connection resource\n");
869     ux_test_utility_sim_mutex_create_count_reset();
870     ux_test_utility_sim_sem_create_count_reset();
871     ux_test_utility_sim_sem_get_count_reset();
872     ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
873     mem_free = _ux_system->ux_system_regular_memory_pool_free;
874     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
875     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
876     tx_thread_sleep(100);
877     /* Log create counts when SetConfigure for further tests. */
878     rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
879     rsc_enum_sem_usage = rsc_sem_on_set_cfg;
880     rsc_enum_sem_get_count = rsc_sem_get_on_set_cfg;
881     rsc_enum_mem_usage = mem_free - rsc_mem_free_on_set_cfg;
882     stepinfo("mem free: %ld\n", _ux_system->ux_system_regular_memory_pool_free);
883 
884     /* Simulate detach and attach for FS enumeration,
885        and test possible memory allocation error handlings.
886      */
887     if (rsc_enum_mem_usage) stepinfo(">>>>>>>>>>>>>>>> Memory errors enumeration test\n");
888     mem_free = _ux_system->ux_system_regular_memory_pool_free;
889     for (test_n = 8; test_n <= rsc_enum_mem_usage; test_n += 8)
890     {
891 
892         stepinfo("%4ld / %4ld\n", test_n, rsc_enum_mem_usage);
893 
894         /* Check memory level */
895         if (mem_free != _ux_system->ux_system_regular_memory_pool_free)
896         {
897 
898             printf("ERROR #14.%ld: Memory level different after re-enumerations\n", test_n);
899             test_control_return(1);
900         }
901 
902         /* Disconnect. */
903         ux_test_dcd_sim_slave_disconnect();
904         ux_test_hcd_sim_host_disconnect();
905 
906         /* Update memory free level (disconnect) */
907         mem_free = _ux_system->ux_system_regular_memory_pool_free;
908 
909         /* Set memory free level */
910         ux_test_utility_sim_mem_allocate_until(test_n);
911 
912         /* Count SetConfigure */
913         set_cfg_counter = 0;
914         ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
915 
916         /* Connect. */
917         ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
918         ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
919 
920         /* Free memory */
921         ux_test_utility_sim_mem_free_all();
922 
923         /* Check error */
924         if (set_cfg_counter)
925         {
926 
927             printf("ERROR #15.%ld: device detected when there is memory error\n", test_n);
928             test_control_return(1);
929         }
930         stepinfo("mem free: %ld\n", _ux_system->ux_system_regular_memory_pool_free);
931     }
932     if (rsc_enum_mem_usage) stepinfo("\n");
933 
934     /* Finally disconnect the device. */
935     ux_device_stack_disconnect();
936 
937     /* And deinitialize the class.  */
938     status =  ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
939 
940     /* Deinitialize the device side of usbx.  */
941     _ux_device_stack_uninitialize();
942 
943     /* And finally the usbx system resources.  */
944     _ux_system_uninitialize();
945 
946     /* Successful test.  */
947     printf("SUCCESS!\n");
948     test_control_return(0);
949 
950 }
951 
tx_test_thread_slave_simulation_entry(ULONG arg)952 void  tx_test_thread_slave_simulation_entry(ULONG arg)
953 {
954 
955 UINT status;
956 ULONG                                               requested_length;
957 ULONG                                               actual_length;
958 UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_PARAMETER        line_coding;
959 UX_SLAVE_CLASS_CDC_ACM_LINE_STATE_PARAMETER         line_state;
960 UX_SLAVE_CLASS_COMMAND                              class_command;
961 
962 UCHAR                                               data_bit[16];
963 VOID*                                               tmp_alloc;
964 ULONG                                               tmp_alloc_len;
965 
966     while(1)
967     {
968 
969         /* Sleep so ThreadX on Win32 will delete this thread. */
970         tx_thread_sleep(10);
971     }
972 }
973