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 #include "ux_hcd_sim_host.h"
9 
10 #include "fx_api.h"
11 
12 #include "ux_device_class_cdc_acm.h"
13 #include "ux_device_stack.h"
14 #include "ux_host_class_cdc_acm.h"
15 
16 #include "ux_test_dcd_sim_slave.h"
17 #include "ux_test_hcd_sim_host.h"
18 #include "ux_test_utility_sim.h"
19 
20 #define                             UX_DEMO_REQUEST_MAX_LENGTH \
21     ((UX_HCD_SIM_HOST_MAX_PAYLOAD) > (UX_SLAVE_REQUEST_DATA_MAX_LENGTH) ? \
22         (UX_HCD_SIM_HOST_MAX_PAYLOAD) : (UX_SLAVE_REQUEST_DATA_MAX_LENGTH))
23 
24 /* Define constants.  */
25 #define                             UX_CDC_ACM_CONNECTION_DELAY ((UX_RH_ENUMERATION_RETRY + 1)*UX_HOST_CLASS_CDC_ACM_DEVICE_INIT_DELAY)
26 #define                             UX_DEMO_DEBUG_SIZE  (4096*8)
27 #define                             UX_DEMO_STACK_SIZE  1024
28 #define                             UX_DEMO_BUFFER_SIZE (UX_DEMO_REQUEST_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     (128*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_thread_host_reception_callback(UX_HOST_CLASS_CDC_ACM *cdc_acm, UINT status, UCHAR *reception_buffer, ULONG reception_size);
44 static VOID        demo_cdc_instance_activate(VOID  *cdc_instance);
45 static VOID        demo_cdc_instance_deactivate(VOID *cdc_instance);
46 static VOID        demo_cdc_instance_parameter_change(VOID *cdc_instance);
47 static UINT        test_usbx_simulator_cdc_acm_host_send_command(UCHAR *string, ULONG length, ULONG no_ack);
48 static UINT        tx_test_thread_slave_simulation_response(UCHAR *string, ULONG length);
49 
50 static UINT        ux_test_host_class_cdc_acm_command(UX_HOST_CLASS_CDC_ACM *cdc_acm, ULONG command, ULONG value, UCHAR *data_buffer, ULONG data_length, ULONG *actual_length);
51 
52 static VOID        ux_test_host_class_cdc_acm_device_status_change_callback(struct UX_HOST_CLASS_CDC_ACM_STRUCT *cdc_acm,
53                                                                             ULONG  notification_type, ULONG notification_value);
54 
55 static VOID        ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params);
56 static VOID        ux_test_hcd_entry_interaction_request_sem_put(UX_TEST_ACTION *action, VOID *params);
57 static VOID        ux_test_hcd_entry_interaction_invoked(UX_TEST_ACTION *action, VOID *params);
58 static VOID        ux_test_hcd_entry_interaction_wait_transfer_disconnection(UX_TEST_ACTION *action, VOID *params);
59 
60 #define test_usbx_simulator_cdc_acm_host_send_at_command(s,l) test_usbx_simulator_cdc_acm_host_send_command(s,l,UX_FALSE)
61 #define test_usbx_simulator_cdc_acm_host_send_string(s,l)     test_usbx_simulator_cdc_acm_host_send_command(s,l,UX_TRUE)
62 
63 /* Define global data structures.  */
64 static UCHAR                               usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
65 static UX_HOST_CLASS                       *class_driver;
66 static UX_HOST_CLASS_CDC_ACM               *cdc_acm_host_control;
67 static UX_HOST_CLASS_CDC_ACM               *cdc_acm_host_data;
68 static ULONG                               notification_count;
69 static ULONG                               command_received_count;
70 static UCHAR                               cdc_acm_reception_buffer[UX_DEMO_RECEPTION_BUFFER_SIZE];
71 static UCHAR                               cdc_acm_xmit_buffer[UX_DEMO_XMIT_BUFFER_SIZE];
72 static UX_HOST_CLASS_CDC_ACM_RECEPTION     cdc_acm_reception;
73 static UCHAR                               *global_reception_buffer;
74 static ULONG                               global_reception_size;
75 static UCHAR                               cdc_acm_reception_overflow = UX_FALSE;
76 
77 static UX_SLAVE_CLASS_CDC_ACM              *cdc_acm_slave;
78 static UCHAR                               cdc_acm_slave_change;
79 static UX_SLAVE_CLASS_CDC_ACM_PARAMETER    parameter;
80 static UCHAR                               buffer[UX_DEMO_BUFFER_SIZE * 4]; /* Large enough to avoid memory access exception.  */
81 static UCHAR                               cdc_acm_slave_bulk_read_write = UX_TRUE;
82 
83 static ULONG                               error_counter;
84 
85 static ULONG                               set_cfg_counter;
86 
87 static ULONG                               rsc_mem_free_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_sem_usage;
93 static ULONG                               rsc_enum_sem_get_count;
94 static ULONG                               rsc_enum_mutex_usage;
95 static ULONG                               rsc_enum_mem_usage;
96 
97 static ULONG                               rsc_cdc_sem_usage;
98 static ULONG                               rsc_cdc_sem_get_count;
99 static ULONG                               rsc_cdc_mutex_usage;
100 static ULONG                               rsc_cdc_mem_usage;
101 
102 static ULONG                               interaction_count;
103 
104 static UCHAR                               error_callback_ignore = UX_TRUE;
105 static ULONG                               error_callback_counter;
106 
107 static UCHAR                                _rsp_ok[UX_DEMO_BUFFER_SIZE] = {'O', 'K', '\r', '\n', '\0'};
108 
109 /* Define device framework.  */
110 
111 #define             DEVICE_FRAMEWORK_LENGTH_FULL_SPEED      (93 + 7)
112 #define             DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED      (103 + 7)
113 #define             STRING_FRAMEWORK_LENGTH                 47
114 #define             LANGUAGE_ID_FRAMEWORK_LENGTH            2
115 
116 static unsigned char device_framework_full_speed[] = {
117 
118     /* Device descriptor     18 bytes
119        0x02 bDeviceClass:    CDC class code
120        0x00 bDeviceSubclass: CDC class sub code
121        0x00 bDeviceProtocol: CDC Device protocol
122 
123        idVendor & idProduct - http://www.linux-usb.org/usb.ids
124     */
125     0x12, 0x01, 0x10, 0x01,
126     0xEF, 0x02, 0x01,
127     0x08,
128     0x84, 0x84, 0x00, 0x00,
129     0x00, 0x01,
130     0x01, 0x02, 03,
131     0x01,
132 
133     /* Configuration 1 descriptor 9 bytes */
134     0x09, 0x02, 0x52, 0x00,
135     0x02, 0x01, 0x00,
136     0x40, 0x00,
137 
138     /* Interface association descriptor. 8 bytes.  */
139     0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
140 
141     /* Communication Class Interface Descriptor Requirement. 9 bytes.   */
142     0x09, 0x04, 0x00,
143     0x00,
144     0x02,
145     0x02, 0x02, 0x01,
146     0x00,
147 
148     /* Header Functional Descriptor 5 bytes */
149     0x05, 0x24, 0x00,
150     0x10, 0x01,
151 
152     /* ACM Functional Descriptor 4 bytes */
153     0x04, 0x24, 0x02,
154     0x0f,
155 
156     /* Union Functional Descriptor 5 bytes */
157     0x05, 0x24, 0x06,
158     0x00,                          /* Master interface */
159     0x01,                          /* Slave interface  */
160 
161     /* Call Management Functional Descriptor 5 bytes */
162     0x05, 0x24, 0x01,
163     0x03,
164     0x01,                          /* Data interface   */
165 
166     /* Endpoint 0x04 descriptor 7 bytes */
167     0x07, 0x05, 0x04,
168     0x03,
169     0x08, 0x00,
170     15,
171 
172     /* Endpoint 0x83 descriptor 7 bytes */
173     0x07, 0x05, 0x83,
174     0x03,
175     0x08, 0x00,
176     0xFF,
177 
178     /* Data Class Interface Descriptor Requirement 9 bytes */
179     0x09, 0x04, 0x01,
180     0x00,
181     0x02,
182     0x0A, 0x00, 0x00,
183     0x00,
184 
185     /* Endpoint 0x02 descriptor 7 bytes */
186     0x07, 0x05, 0x02, /* @ 93 - 14 + 2 = 81 */
187     0x02,
188     0x40, 0x00,
189     0x00,
190 
191     /* Endpoint 0x81 descriptor 7 bytes */
192     0x07, 0x05, 0x81, /* @ 93 - 7 + 2 = 88 */
193     0x02,
194     0x40, 0x00,
195     0x00,
196 
197 };
198 
199 #define DEVICE_FRAMEWORK_EPA_POS_1_FS (DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 14 + 2)
200 #define DEVICE_FRAMEWORK_EPA_POS_2_FS (DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 7 + 2)
201 
202 static unsigned char device_framework_high_speed[] = {
203 
204     /* Device descriptor
205        0x02 bDeviceClass:    CDC class code
206        0x00 bDeviceSubclass: CDC class sub code
207        0x00 bDeviceProtocol: CDC Device protocol
208 
209        idVendor & idProduct - http://www.linux-usb.org/usb.ids
210     */
211     0x12, 0x01, 0x00, 0x02,
212     0xEF, 0x02, 0x01,
213     0x40,
214     0x84, 0x84, 0x00, 0x00,
215     0x00, 0x01,
216     0x01, 0x02, 03,
217     0x01,
218 
219     /* Device qualifier descriptor */
220     0x0a, 0x06, 0x00, 0x02,
221     0x02, 0x00, 0x00,
222     0x40,
223     0x01,
224     0x00,
225 
226     /* Configuration 1 descriptor */
227     0x09, 0x02, 0x52, 0x00,
228     0x02, 0x01, 0x00,
229     0x40, 0x00,
230 
231     /* Interface association descriptor. */
232     0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
233 
234     /* Communication Class Interface Descriptor Requirement */
235     0x09, 0x04, 0x00,
236     0x00,
237     0x02,
238     0x02, 0x02, 0x01,
239     0x00,
240 
241     /* Header Functional Descriptor */
242     0x05, 0x24, 0x00,
243     0x10, 0x01,
244 
245     /* ACM Functional Descriptor */
246     0x04, 0x24, 0x02,
247     0x0f,
248 
249     /* Union Functional Descriptor */
250     0x05, 0x24, 0x06,
251     0x00,
252     0x01,
253 
254     /* Call Management Functional Descriptor */
255     0x05, 0x24, 0x01,
256     0x00,
257     0x01,
258 
259     /* Endpoint 0x04 descriptor */
260     0x07, 0x05, 0x04,
261     0x03,
262     0x08, 0x00,
263     10,
264 
265     /* Endpoint 0x83 descriptor */
266     0x07, 0x05, 0x83,
267     0x03,
268     0x08, 0x00,
269     10,
270 
271     /* Data Class Interface Descriptor Requirement */
272     0x09, 0x04, 0x01,
273     0x00,
274     0x02,
275     0x0A, 0x00, 0x00,
276     0x00,
277 
278     /* Endpoint 0x02 descriptor */
279     0x07, 0x05, 0x02, /* @ 103 - 14 + 2 = 91 */
280     0x02,
281     0x40, 0x00,
282     0x00,
283 
284     /* Endpoint 0x81 descriptor */
285     0x07, 0x05, 0x81, /* @ 103 - 7 + 2 = 98 */
286     0x02,
287     0x40, 0x00,
288     0x00,
289 
290 };
291 
292 #define DEVICE_FRAMEWORK_EPA_POS_1_HS (DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 14 + 2)
293 #define DEVICE_FRAMEWORK_EPA_POS_2_HS (DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 7 + 2)
294 
295 static unsigned char string_framework[] = {
296 
297     /* Manufacturer string descriptor : Index 1 - "Express Logic" */
298         0x09, 0x04, 0x01, 0x0c,
299         0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
300         0x6f, 0x67, 0x69, 0x63,
301 
302     /* Product string descriptor : Index 2 - "EL Composite device" */
303         0x09, 0x04, 0x02, 0x13,
304         0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
305         0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
306         0x69, 0x63, 0x65,
307 
308     /* Serial Number string descriptor : Index 3 - "0001" */
309         0x09, 0x04, 0x03, 0x04,
310         0x30, 0x30, 0x30, 0x31
311     };
312 
313 
314     /* Multiple languages are supported on the device, to add
315        a language besides english, the unicode language code must
316        be appended to the language_id_framework array and the length
317        adjusted accordingly. */
318 static unsigned char language_id_framework[] = {
319 
320     /* English. */
321         0x09, 0x04
322     };
323 
324 #define DEVICE_FRAMEWORK1_LENGTH            (18 +9 +8 +9+5+4+5+5+ 9+7+7) /* =86 */
325 #define DEVICE_FRAMEWORK1_CFG_TOTAL_LEN_POS (18+2)
326 #define DEVICE_FRAMEWORK1_IFC1_N_EPS_POS    (86-7-7-9+4)
327 #define DEVICE_FRAMEWORK1_IFC1_EPA1_POS     (86-7-7+2)
328 #define DEVICE_FRAMEWORK1_IFC1_EPA2_POS     (86-7+2)
329 
330 static unsigned char device_framework_no_interrupt_ep[] = {
331 
332     /* Device descriptor     18 bytes
333        0x02 bDeviceClass:    CDC class code
334        0x00 bDeviceSubclass: CDC class sub code
335        0x00 bDeviceProtocol: CDC Device protocol
336 
337        idVendor & idProduct - http://www.linux-usb.org/usb.ids
338     */
339     0x12, 0x01, 0x10, 0x01,
340     0xEF, 0x02, 0x01,
341     0x08,
342     0x84, 0x84, 0x00, 0x00,
343     0x00, 0x01,
344     0x01, 0x02, 0x03,
345     0x01,
346 
347     /* Configuration 1 descriptor 9 bytes */
348     0x09, 0x02, 0x44, 0x00, /* wTotalLength @ 21 */
349     0x02, 0x01, 0x00,
350     0x40, 0x00,
351 
352     /* Interface association descriptor. 8 bytes.  */
353     0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
354 
355     /* Communication Class Interface Descriptor Requirement. 9 bytes.   */
356     0x09, 0x04, 0x00,
357     0x00,
358     0x00,
359     0x02, 0x02, 0x01,
360     0x00,
361 
362     /* Header Functional Descriptor 5 bytes */
363     0x05, 0x24, 0x00,
364     0x10, 0x01,
365 
366     /* ACM Functional Descriptor 4 bytes */
367     0x04, 0x24, 0x02,
368     0x0f,
369 
370     /* Union Functional Descriptor 5 bytes */
371     0x05, 0x24, 0x06,
372     0x00,                          /* Master interface */
373     0x01,                          /* Slave interface  */
374 
375     /* Call Management Functional Descriptor 5 bytes */
376     0x05, 0x24, 0x01,
377     0x03,
378     0x01,                          /* Data interface   */
379 
380     /* Data Class Interface Descriptor Requirement 9 bytes */
381     0x09, 0x04, 0x01,
382     0x00,
383     0x02, /* bNumEndpoints @ 86 - 14 - 9 + 4 = 67 */
384     0x0A, 0x00, 0x00,
385     0x00,
386 
387     /* Endpoint 0x81 descriptor 7 bytes */
388     0x07, 0x05, 0x81, /* @ 86 - 14 + 2 = 73 */
389     0x02,
390     0x40, 0x00,
391     0x00,
392 
393     /* Endpoint 0x02 descriptor 7 bytes */
394     0x07, 0x05, 0x02, /* @ 86 - 7 + 2 = 81 */
395     0x02,
396     0x40, 0x00,
397     0x00,
398 
399 };
400 
401 static unsigned char replaced_cfg_descriptor[] =
402 {
403     /* Configuration 1 descriptor 9 bytes */
404     0x09, 0x02, 0x52, 0x00,
405     0x02, 0x01, 0x00,
406     0x40, 0x00,
407 
408     /* Interface association descriptor. 8 bytes.  */
409     0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
410 
411     /* Communication Class Interface Descriptor Requirement. 9 bytes.   */
412     0x09, 0x04, 0x00,
413     0x00,
414     0x02,
415     0x02, 0x02, 0x01,
416     0x00,
417 
418     /* Header Functional Descriptor 5 bytes */
419     0x05, 0x24, 0x00,
420     0x10, 0x01,
421 
422     /* ACM Functional Descriptor 4 bytes */
423     0x04, 0x24, 0x02,
424     0x0f,
425 
426     /* Union Functional Descriptor 5 bytes */
427     0x05, 0x24, 0x06,
428     0x00,                          /* Master interface */
429     0x01,                          /* Slave interface  */
430 
431     /* Call Management Functional Descriptor 5 bytes */
432     0x05, 0x24, 0x01,
433     0x03,
434     0x01,                          /* Data interface   */
435 
436     /* Endpoint 0x04 descriptor 7 bytes */
437     0x07, 0x05, 0x04,
438     0x03,
439     0x08, 0x00,
440     10,
441 
442     /* Endpoint 0x83 descriptor 7 bytes */
443     0x07, 0x05, 0x83,
444     0x03,
445     0x08, 0x00,
446     10,
447 
448     /* Data Class Interface Descriptor Requirement 9 bytes */
449     0x09, 0x04, 0x01,
450     0x00,
451     0x02,
452     0x0A, 0x00, 0x00,
453     0x00,
454 
455     /* Endpoint 0x02 descriptor 7 bytes */
456     0x07, 0x05, 0x02, /* @ 93 - 14 + 2 = 81 */
457     0x02,
458     0x40, 0x00,
459     0x00,
460 
461     /* Endpoint 0x81 descriptor 7 bytes */
462     0x07, 0x05, 0x81, /* @ 93 - 7 + 2 = 88 */
463     0x02,
464     0x40, 0x00,
465     0x00,
466 };
467 
468 static unsigned char replaced_cfg_descriptor_no_bulk[] =
469 {
470     /* Configuration 1 descriptor */
471     0x09, 0x02, 0x52 - 7, 0x00,
472     0x02, 0x01, 0x00,
473     0x40, 0x00,
474 
475     /* Interface association descriptor. */
476     0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
477 
478     /* Communication Class Interface Descriptor Requirement */
479     0x09, 0x04, 0x00,
480     0x00,
481     0x02,
482     0x02, 0x02, 0x01,
483     0x00,
484 
485     /* Header Functional Descriptor */
486     0x05, 0x24, 0x00,
487     0x10, 0x01,
488 
489     /* ACM Functional Descriptor */
490     0x04, 0x24, 0x02,
491     0x0f,
492 
493     /* Union Functional Descriptor */
494     0x05, 0x24, 0x06,
495     0x00,
496     0x01,
497 
498     /* Call Management Functional Descriptor */
499     0x05, 0x24, 0x01,
500     0x00,
501     0x01,
502 
503     /* Endpoint 0x04 descriptor */
504     0x07, 0x05, 0x04,
505     0x03,
506     0x08, 0x00,
507     10,
508 
509     /* Endpoint 0x83 descriptor */
510     0x07, 0x05, 0x83,
511     0x03,
512     0x08, 0x00,
513     10,
514 
515     /* Data Class Interface Descriptor Requirement */
516     0x09, 0x04, 0x01,
517     0x00,
518     0x01,
519     0x0A, 0x00, 0x00,
520     0x00,
521 
522     /* Endpoint 0x02 descriptor */
523     0x07, 0x05, 0x02, /* @ - 7 + 2 */
524     0x02,
525     0x40, 0x00,
526     0x00,
527 
528 };
529 
530 /* Setup requests */
531 
532 static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
533 static UX_TEST_SETUP _GetCfgDescr  = UX_TEST_SETUP_GetCfgDescr;
534 static UX_TEST_SETUP _SetAddress = UX_TEST_SETUP_SetAddress;
535 static UX_TEST_SETUP _GetDeviceDescriptor = UX_TEST_SETUP_GetDevDescr;
536 static UX_TEST_SETUP _GetConfigDescriptor = UX_TEST_SETUP_GetCfgDescr;
537 
538 /* Interaction define */
539 
540 static UX_TEST_HCD_SIM_ACTION check_ignore_next_transfer_request[] = {
541 /* function, request to match,
542    port action, port status,
543    request action, request EP, request data, request actual length, request status,
544    status, additional callback,
545    no_return */
546 {   UX_HCD_TRANSFER_REQUEST, UX_NULL,
547         UX_FALSE, 0,
548         0, 0, UX_NULL, 0, 0,
549         UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
550 {   0   }
551 };
552 
553 static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
554 /* function, request to match,
555    port action, port status,
556    request action, request EP, request data, request actual length, request status,
557    status, additional callback,
558    no_return */
559 {   UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
560         UX_FALSE, UX_TEST_PORT_STATUS_DISC,
561         UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
562         UX_SUCCESS, ux_test_hcd_entry_set_cfg,
563         UX_TRUE}, /* Invoke callback & continue */
564 {   0   }
565 };
566 
567 static UX_TEST_HCD_SIM_ACTION wait_disconn_on_transfer_0[] = {
568 /* function, request to match,
569    port action, port status,
570    request action, request EP, request data, request actual length, request status,
571    status, additional callback,
572    no_return */
573 {   UX_HCD_TRANSFER_REQUEST, UX_NULL,
574         UX_FALSE, 0,
575         0, 0, UX_NULL, 0, 0,
576         UX_ERROR, ux_test_hcd_entry_interaction_wait_transfer_disconnection},
577 {   0   }
578 };
579 
580 static UX_TEST_HCD_SIM_ACTION error_on_transfer_0[] = {
581 /* function, request to match,
582    port action, port status,
583    request action, request EP, request data, request actual length, request status,
584    status, additional callback,
585    no_return */
586 {   UX_HCD_TRANSFER_REQUEST, UX_NULL,
587         UX_FALSE, 0,
588         UX_TEST_SIM_REQ_ANSWER, 0, UX_NULL, 0, UX_ERROR,
589         UX_ERROR},
590 {   0   }
591 };
592 
593 static UX_TEST_HCD_SIM_ACTION error_on_transfer_1[] = {
594 /* function, request to match,
595    port action, port status,
596    request action, request EP, request data, request actual length, request status,
597    status, additional callback,
598    no_return */
599 {   UX_HCD_TRANSFER_REQUEST, UX_NULL,
600         UX_FALSE, 0,
601         UX_TEST_SIM_REQ_ANSWER, 0, UX_NULL, ~0, 0,
602         UX_SUCCESS, ux_test_hcd_entry_interaction_invoked}, /* All requested */
603 {   UX_HCD_TRANSFER_REQUEST, UX_NULL,
604         UX_FALSE, 0,
605         UX_TEST_SIM_REQ_ANSWER, 0, UX_NULL, 0, UX_ERROR,
606         UX_ERROR, ux_test_hcd_entry_interaction_invoked}, /* Error */
607 {   0   }
608 };
609 
610 static UX_TEST_HCD_SIM_ACTION good_on_transfer_1[] = {
611 /* function, request to match,
612    port action, port status,
613    request action, request EP, request data, request actual length, request status,
614    status, additional callback,
615    no_return */
616 {   UX_HCD_TRANSFER_REQUEST, UX_NULL,
617         UX_FALSE, 0,
618         UX_TEST_SIM_REQ_ANSWER, 0, UX_NULL, ~0, 0, /* Return all required */
619         UX_SUCCESS, ux_test_hcd_entry_interaction_invoked}, /* All requested */
620 {   UX_HCD_TRANSFER_REQUEST, UX_NULL,
621         UX_FALSE, 0,
622         UX_TEST_SIM_REQ_ANSWER, 0, UX_NULL, 0, 0, /* Return ZLP */
623         UX_SUCCESS, ux_test_hcd_entry_interaction_invoked}, /* No Error */
624 {   0   }
625 };
626 
627 static UX_TEST_HCD_SIM_ACTION good_on_transfer_0_ZLP[] = {
628 /* function, request to match,
629    port action, port status,
630    request action, request EP, request data, request actual length, request status,
631    status, additional callback,
632    no_return */
633 {   UX_HCD_TRANSFER_REQUEST, UX_NULL,
634         UX_FALSE, 0,
635         UX_TEST_SIM_REQ_ANSWER, 0, UX_NULL, 0, 0, /* Return ZLP */
636         UX_SUCCESS, ux_test_hcd_entry_interaction_request_sem_put}, /* No Error */
637 {   0   }
638 };
639 
640 static UX_TEST_HCD_SIM_ACTION error_on_transfer_interruptEP[] = {
641 /* function, request to match,
642    port action, port status,
643    request action, request EP, request data, request actual length, request status,
644    status, additional callback,
645    no_return */
646 {   UX_HCD_TRANSFER_REQUEST, UX_NULL,
647         UX_FALSE, 0,
648         UX_TEST_MATCH_EP, 0x83, UX_NULL, 0, 0,
649         UX_ERROR, ux_test_hcd_entry_interaction_invoked}, /* Error */
650 {   0   }
651 };
652 
653 static UX_TEST_HCD_SIM_ACTION replaced_GetCfgDescr[] = {
654 /* function, request to match,
655    port action, port status,
656    request action, request EP, request data, request actual length, request status,
657    status, additional callback,
658    no_return */
659 {   UX_HCD_TRANSFER_REQUEST, &_GetCfgDescr,
660         UX_FALSE, 0,
661         UX_TEST_SETUP_MATCH_REQ | UX_TEST_SIM_REQ_ANSWER, 0, replaced_cfg_descriptor, 9, 0,
662         UX_SUCCESS, ux_test_hcd_entry_interaction_invoked}, /* Invoke callback & answer */
663 {   UX_HCD_TRANSFER_REQUEST, &_GetCfgDescr,
664         UX_FALSE, 0,
665         UX_TEST_SETUP_MATCH_REQ | UX_TEST_SIM_REQ_ANSWER, 0, replaced_cfg_descriptor, sizeof(replaced_cfg_descriptor), 0,
666         UX_SUCCESS, ux_test_hcd_entry_interaction_invoked}, /* Invoke callback & answer */
667 {   0   }
668 };
669 
670 static UX_TEST_HCD_SIM_ACTION enum_replace_no_bulk[] = {
671 /* function, request to match,
672    port action, port status,
673    request action, request EP, request data, request actual length, request status,
674    status, additional callback,
675    no_return */
676 {   UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
677         UX_FALSE, 0,
678         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 0, 8, 0,
679         UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
680 {   UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
681         UX_FALSE, 0,
682         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 0, 18, 0,
683         UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
684 
685         /* Note: Each enumeration does two GetConfigurations (the second one is in _ux_host_class_cdc_acm_capabilities_get.c) */
686 
687         /* 1st. */
688 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
689         UX_FALSE, 0,
690         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, UX_CONFIGURATION_DESCRIPTOR_LENGTH, 0,
691         UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
692 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
693         UX_FALSE, 0,
694         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, sizeof(replaced_cfg_descriptor_no_bulk), 0,
695         UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
696 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
697         UX_FALSE, 0,
698         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, UX_CONFIGURATION_DESCRIPTOR_LENGTH, 0,
699         UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
700 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
701         UX_FALSE, 0,
702         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, sizeof(replaced_cfg_descriptor_no_bulk), 0,
703         UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
704 
705         /* 2nd. */
706 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
707         UX_FALSE, 0,
708         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, UX_CONFIGURATION_DESCRIPTOR_LENGTH, 0,
709         UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
710 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
711         UX_FALSE, 0,
712         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, sizeof(replaced_cfg_descriptor_no_bulk), 0,
713         UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
714 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
715         UX_FALSE, 0,
716         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, UX_CONFIGURATION_DESCRIPTOR_LENGTH, 0,
717         UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
718 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
719         UX_FALSE, 0,
720         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, sizeof(replaced_cfg_descriptor_no_bulk), 0,
721         UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
722 
723         /* 3rd. */
724 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
725         UX_FALSE, 0,
726         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, UX_CONFIGURATION_DESCRIPTOR_LENGTH, 0,
727         UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
728 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
729         UX_FALSE, 0,
730         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, sizeof(replaced_cfg_descriptor_no_bulk), 0,
731         UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
732 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
733         UX_FALSE, 0,
734         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, UX_CONFIGURATION_DESCRIPTOR_LENGTH, 0,
735         UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
736 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
737         UX_FALSE, 0,
738         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, sizeof(replaced_cfg_descriptor_no_bulk), 0,
739         UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
740 {   0   }
741 };
742 
743 /* Define the ISR dispatch.  */
744 
745 extern VOID    (*test_isr_dispatch)(void);
746 
747 
748 /* Prototype for test control return.  */
749 
750 void  test_control_return(UINT status);
751 
error_callback(UINT system_level,UINT system_context,UINT error_code)752 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
753 {
754 
755     error_callback_counter ++;
756 
757     if (!error_callback_ignore)
758     {
759         {
760             /* Failed test.  */
761             printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
762             test_control_return(1);
763         }
764     }
765 }
766 
sleep_break_on_error(VOID)767 static UINT  sleep_break_on_error(VOID)
768 {
769 
770     if (error_callback_counter >= 3)
771         return error_callback_counter;
772 
773     return UX_SUCCESS;
774 }
775 
776 /* Define the ISR dispatch routine.  */
777 
test_isr(void)778 static void    test_isr(void)
779 {
780 
781     /* For further expansion of interrupt-level testing.  */
782 }
783 
784 
demo_class_cdc_acm_get(void)785 static UINT demo_class_cdc_acm_get(void)
786 {
787 
788 UINT                                status;
789 UX_HOST_CLASS                       *class;
790 UX_HOST_CLASS_CDC_ACM               *cdc_acm_host;
791 
792 
793     /* Find the main cdc_acm container */
794     status =  ux_host_stack_class_get(_ux_system_host_class_cdc_acm_name, &class);
795     if (status != UX_SUCCESS)
796         return(status);
797 
798     /* We get the first instance of the cdc_acm device */
799     do
800     {
801 
802         status =  ux_host_stack_class_instance_get(class, 0, (void **) &cdc_acm_host);
803         tx_thread_sleep(10);
804     } while (status != UX_SUCCESS);
805 
806     /* We still need to wait for the cdc_acm status to be live */
807     while (cdc_acm_host -> ux_host_class_cdc_acm_state != UX_HOST_CLASS_INSTANCE_LIVE)
808         tx_thread_sleep(10);
809 
810     /* Isolate both the control and data interfaces.  */
811     if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_DATA_CLASS)
812     {
813         /* This is the data interface.  */
814         cdc_acm_host_data = cdc_acm_host;
815 
816         /* In that case, the second one should be the control interface.  */
817         status =  ux_host_stack_class_instance_get(class, 1, (void **) &cdc_acm_host);
818 
819         /* Check error.  */
820         if (status != UX_SUCCESS)
821             return(status);
822 
823         /* Check for the control interfaces.  */
824         if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
825         {
826 
827             /* This is the control interface.  */
828             cdc_acm_host_control = cdc_acm_host;
829 
830             return(UX_SUCCESS);
831 
832         }
833     }
834     else
835     {
836         /* Check for the control interfaces.  */
837         if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
838         {
839 
840             /* This is the control interface.  */
841             cdc_acm_host_control = cdc_acm_host;
842 
843             /* In that case, the second one should be the data interface.  */
844             status =  ux_host_stack_class_instance_get(class, 1, (void **) &cdc_acm_host);
845 
846             /* Check error.  */
847             if (status != UX_SUCCESS)
848                 return(status);
849 
850             /* Check for the data interface.  */
851             if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_DATA_CLASS)
852             {
853 
854                 /* This is the data interface.  */
855                 cdc_acm_host_data = cdc_acm_host;
856 
857                 return(UX_SUCCESS);
858 
859             }
860         }
861     }
862 
863     /* Return ERROR.  */
864     return(UX_ERROR);
865 }
866 
demo_system_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)867 static UINT demo_system_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
868 {
869 
870 UX_HOST_CLASS_CDC_ACM *cdc_acm = (UX_HOST_CLASS_CDC_ACM *) inst;
871 
872     switch(event)
873     {
874 
875         case UX_DEVICE_INSERTION:
876 
877             if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
878                 cdc_acm_host_control = cdc_acm;
879             else
880                 cdc_acm_host_data = cdc_acm;
881             break;
882 
883         case UX_DEVICE_REMOVAL:
884 
885             if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
886                 cdc_acm_host_control = UX_NULL;
887             else
888                 cdc_acm_host_data = UX_NULL;
889             break;
890 
891         default:
892             break;
893     }
894     return 0;
895 }
896 
demo_cdc_instance_activate(VOID * cdc_instance)897 static VOID    demo_cdc_instance_activate(VOID *cdc_instance)
898 {
899 
900     /* Save the CDC instance.  */
901     cdc_acm_slave = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
902 }
demo_cdc_instance_deactivate(VOID * cdc_instance)903 static VOID    demo_cdc_instance_deactivate(VOID *cdc_instance)
904 {
905 
906     /* Reset the CDC instance.  */
907     cdc_acm_slave = UX_NULL;
908 }
909 
demo_cdc_instance_parameter_change(VOID * cdc_instance)910 static VOID demo_cdc_instance_parameter_change(VOID *cdc_instance)
911 {
912 
913     /* Set CDC parameter change flag. */
914     cdc_acm_slave_change = UX_TRUE;
915 }
916 
test_swap_framework_bulk_ep_descriptors(VOID)917 static VOID test_swap_framework_bulk_ep_descriptors(VOID)
918 {
919 UCHAR tmp;
920 
921     tmp = device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_1_FS];
922     device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_1_FS] = device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_2_FS];
923     device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_2_FS] = tmp;
924 
925     tmp = device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_1_HS];
926     device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_1_HS] = device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_2_HS];
927     device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_2_HS] = tmp;
928 }
929 
test_slave_cdc_acm_transfer_disconnect(UX_SLAVE_CLASS_CDC_ACM * cdc_acm,ULONG ep_dir)930 static VOID test_slave_cdc_acm_transfer_disconnect(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, ULONG ep_dir)
931 {
932 
933 UX_SLAVE_ENDPOINT           *endpoint;
934 UX_SLAVE_DEVICE             *device;
935 UX_SLAVE_INTERFACE          *interface;
936 UX_SLAVE_TRANSFER           *transfer_request;
937 
938     /* Get the pointer to the device.  */
939     device =  &_ux_system_slave -> ux_system_slave_device;
940 
941     /* This is the first time we are activated. We need the interface to the class.  */
942     interface =  cdc_acm -> ux_slave_class_cdc_acm_interface;
943 
944     /* Locate the endpoints.  */
945     endpoint =  interface -> ux_slave_interface_first_endpoint;
946 
947     /* Check the endpoint direction, if OUT we have the correct endpoint.  */
948     if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != ep_dir)
949     {
950 
951         /* So the next endpoint has to be the OUT endpoint.  */
952         endpoint =  endpoint -> ux_slave_endpoint_next_endpoint;
953     }
954 
955     /* All CDC reading  are on the endpoint OUT, from the host.  */
956     transfer_request =  &endpoint -> ux_slave_endpoint_transfer_request;
957 
958     /* Continue transfer. */
959     transfer_request -> ux_slave_transfer_request_actual_length = endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize;
960 
961     /* Change device state. */
962     device -> ux_slave_device_state = UX_DEVICE_ATTACHED;
963 
964     /* Inform hcd. */
965     _ux_utility_semaphore_put(&transfer_request -> ux_slave_transfer_request_semaphore);
966 
967     /* Wait a while for transfer request handling. */
968     tx_thread_sleep(50);
969 
970     /* Change device state. */
971     device -> ux_slave_device_state = UX_DEVICE_CONFIGURED;
972 }
973 
ux_test_hcd_entry_interaction_wait_transfer_disconnection(UX_TEST_ACTION * action,VOID * _params)974 static VOID ux_test_hcd_entry_interaction_wait_transfer_disconnection(UX_TEST_ACTION *action, VOID *_params)
975 {
976 UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY_PARAMS   *params = _params;
977 UX_TRANSFER                         *transfer_request = (UX_TRANSFER *)params->parameter;
978 UX_ENDPOINT                         *endpoint;
979 UX_DEVICE                           *device;
980 
981     endpoint = transfer_request -> ux_transfer_request_endpoint;
982     device = endpoint -> ux_endpoint_device;
983 
984     while(device -> ux_device_state > UX_DEVICE_RESET)
985         tx_thread_sleep(10);
986 }
987 
ux_test_hcd_entry_interaction_invoked(UX_TEST_ACTION * action,VOID * params)988 static VOID ux_test_hcd_entry_interaction_invoked(UX_TEST_ACTION *action, VOID *params)
989 {
990 
991     interaction_count ++;
992 }
993 
ux_test_hcd_entry_interaction_request_sem_put(UX_TEST_ACTION * action,VOID * params)994 static VOID ux_test_hcd_entry_interaction_request_sem_put(UX_TEST_ACTION *action, VOID *params)
995 {
996 
997     interaction_count ++;
998 
999 }
1000 
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * params)1001 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params)
1002 {
1003 
1004     set_cfg_counter ++;
1005 
1006     rsc_mem_free_on_set_cfg = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
1007     rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
1008     rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
1009 }
1010 
1011 /* Define what the initial system looks like.  */
1012 
1013 #ifdef CTEST
test_application_define(void * first_unused_memory)1014 void test_application_define(void *first_unused_memory)
1015 #else
1016 void    usbx_cdc_acm_basic_test_application_define(void *first_unused_memory)
1017 #endif
1018 {
1019 
1020 UINT                    status;
1021 CHAR *                  stack_pointer;
1022 CHAR *                  memory_pointer;
1023 ULONG                   test_n;
1024 
1025     /* Inform user.  */
1026     printf("Running CDC ACM Basic Functionality Test............................ ");
1027 
1028     /* Reset testing counts. */
1029     ux_test_utility_sim_mutex_create_count_reset();
1030     ux_test_utility_sim_sem_create_count_reset();
1031     ux_test_utility_sim_sem_get_count_reset();
1032     /* Reset error generations */
1033     ux_test_utility_sim_sem_error_generation_stop();
1034     ux_test_utility_sim_mutex_error_generation_stop();
1035     ux_test_utility_sim_sem_get_error_generation_stop();
1036 
1037     /* Initialize the free memory pointer */
1038     stack_pointer = (CHAR *) usbx_memory;
1039     memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
1040 
1041     /* Initialize USBX Memory */
1042     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
1043 
1044     /* Check for error.  */
1045     if (status != UX_SUCCESS)
1046     {
1047 
1048         printf("ERROR #1\n");
1049         test_control_return(1);
1050     }
1051 
1052     /* Register the error callback. */
1053     _ux_utility_error_callback_register(error_callback);
1054 
1055     /* The code below is required for installing the host portion of USBX */
1056     status =  ux_host_stack_initialize(demo_system_host_change_function);
1057     if (status != UX_SUCCESS)
1058     {
1059 
1060         printf("ERROR #2\n");
1061         test_control_return(1);
1062     }
1063 
1064     /* Register CDC-ACM class.  */
1065     status =  ux_host_stack_class_register(_ux_system_host_class_cdc_acm_name, ux_host_class_cdc_acm_entry);
1066     if (status != UX_SUCCESS)
1067     {
1068 
1069         printf("ERROR #3\n");
1070         test_control_return(1);
1071     }
1072 
1073     /* The code below is required for installing the device portion of USBX. No call back for
1074        device status change in this example. */
1075     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
1076                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
1077                                        string_framework, STRING_FRAMEWORK_LENGTH,
1078                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
1079     if(status!=UX_SUCCESS)
1080     {
1081 
1082         printf("ERROR #5\n");
1083         test_control_return(1);
1084     }
1085 
1086     /* Set the parameters for callback when insertion/extraction of a CDC device.  */
1087     parameter.ux_slave_class_cdc_acm_instance_activate   =  demo_cdc_instance_activate;
1088     parameter.ux_slave_class_cdc_acm_instance_deactivate =  demo_cdc_instance_deactivate;
1089     parameter.ux_slave_class_cdc_acm_parameter_change    =  demo_cdc_instance_parameter_change;
1090 
1091     /* Mutex will be created on initialize to protect CDC Bulk IN/OUT */
1092     for (test_n = 0; test_n < 2; test_n ++)
1093     {
1094         ux_test_utility_sim_mutex_error_generation_start(test_n);
1095         status =  ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
1096                                                  1,0,  &parameter);
1097         /* Mutex error should be reported */
1098         if(status != UX_MUTEX_ERROR)
1099         {
1100 
1101             printf("ERROR #46.%ld\n", test_n);
1102             test_control_return(1);
1103         }
1104     }
1105     ux_test_utility_sim_mutex_error_generation_stop();
1106 
1107     /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
1108     status =  ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
1109                                              1,0,  &parameter);
1110 
1111     if(status!=UX_SUCCESS)
1112     {
1113 
1114         printf("ERROR #6\n");
1115         test_control_return(1);
1116     }
1117 
1118     /* Initialize the simulated device controller.  */
1119     status =  _ux_dcd_sim_slave_initialize();
1120 
1121     /* Check for error.  */
1122     if (status != TX_SUCCESS)
1123     {
1124 
1125         printf("ERROR #7\n");
1126         test_control_return(1);
1127     }
1128 
1129     /* Register all the USB host controllers available in this system */
1130     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
1131     if (status != UX_SUCCESS)
1132     {
1133 
1134         printf("ERROR #4\n");
1135         test_control_return(1);
1136     }
1137 
1138     /* Create the main host simulation thread.  */
1139     status =  tx_thread_create(&tx_test_thread_host_simulation, "tx demo host simulation", tx_test_thread_host_simulation_entry, 0,
1140             stack_pointer, UX_DEMO_STACK_SIZE,
1141             20, 20, 1, TX_AUTO_START);
1142 
1143     /* Check for error.  */
1144     if (status != TX_SUCCESS)
1145     {
1146 
1147         printf("ERROR #8\n");
1148         test_control_return(1);
1149     }
1150 
1151     /* Create the main slave simulation  thread.  */
1152     status =  tx_thread_create(&tx_test_thread_slave_simulation, "tx demo slave simulation", tx_test_thread_slave_simulation_entry, 0,
1153             stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
1154             20, 20, 1, TX_AUTO_START);
1155 
1156     /* Check for error.  */
1157     if (status != TX_SUCCESS)
1158     {
1159 
1160         printf("ERROR #9\n");
1161         test_control_return(1);
1162     }
1163 }
1164 
tx_test_thread_host_simulation_entry(ULONG arg)1165 void  tx_test_thread_host_simulation_entry(ULONG arg)
1166 {
1167 
1168 UINT                                                status;
1169 UX_HOST_CLASS_CDC_ACM_LINE_CODING                   line_coding_host;
1170 UX_HOST_CLASS_CDC_ACM_LINE_STATE                    line_state_host;
1171 ULONG                                               actual_length;
1172 UCHAR                                               at_cmd[16];
1173 UX_SLAVE_CLASS_CDC_ACM *                            cdc_acm_slave_bak;
1174 UX_HOST_CLASS_CDC_ACM *                             cdc_acm_host_ctrl_bak;
1175 UX_HOST_CLASS_CDC_ACM *                             cdc_acm_host_data_bak;
1176 ULONG                                               test_n;
1177 UX_HOST_CLASS_COMMAND                               command;
1178 UX_HOST_CLASS_COMMAND                               command1;
1179 ULONG                                               mem_free;
1180 
1181     stepinfo("\n");
1182 
1183     /* Find the cdc_acm class and wait for the link to be up.  */
1184     status =  demo_class_cdc_acm_get();
1185     if (status != UX_SUCCESS)
1186     {
1187 
1188         /* CDC ACM basic test error.  */
1189         printf("ERROR #10\n");
1190         test_control_return(1);
1191     }
1192 
1193     /* Reception parameter */
1194     cdc_acm_reception.ux_host_class_cdc_acm_reception_block_size = UX_DEMO_RECEPTION_BLOCK_SIZE;
1195     cdc_acm_reception.ux_host_class_cdc_acm_reception_data_buffer = cdc_acm_reception_buffer;
1196     cdc_acm_reception.ux_host_class_cdc_acm_reception_data_buffer_size = UX_DEMO_RECEPTION_BUFFER_SIZE;
1197     cdc_acm_reception.ux_host_class_cdc_acm_reception_callback = test_thread_host_reception_callback;
1198 
1199     /* Save slave instance for later tests. */
1200     cdc_acm_slave_bak = cdc_acm_slave;
1201     /* Save host instances for later tests. */
1202     cdc_acm_host_ctrl_bak = cdc_acm_host_control;
1203     cdc_acm_host_data_bak = cdc_acm_host_data;
1204 
1205     /* Test disconnect. */
1206     ux_test_dcd_sim_slave_disconnect();
1207     ux_test_hcd_sim_host_disconnect();
1208 
1209     /* Test reception on instance inactive */
1210     stepinfo(">>>>>>>>>>>> Start reception when interface is inactive\n");
1211     status = ux_host_class_cdc_acm_reception_start(cdc_acm_host_data_bak, &cdc_acm_reception);
1212     if (status == UX_SUCCESS)
1213     {
1214 
1215         /* CDC ACM basic test error.  */
1216         printf("ERROR #86: error must be reported when invoking reception while interface is not ready\n");
1217         test_control_return(1);
1218     }
1219 
1220     /* Test stop reception on inactive interface */
1221     stepinfo(">>>>>>>>>>>> Stop reception when interface is inactive\n");
1222     status = ux_host_class_cdc_acm_reception_stop(cdc_acm_host_data_bak, &cdc_acm_reception);
1223     if (status == UX_SUCCESS)
1224     {
1225 
1226         /* CDC ACM basic test error.  */
1227         printf("ERROR #91: error not reported when stop reception on inactive interface\n");
1228         test_control_return(1);
1229     }
1230 
1231     /* Reset testing counts. */
1232     ux_test_utility_sim_mutex_create_count_reset();
1233     ux_test_utility_sim_sem_create_count_reset();
1234     ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
1235     /* Save free memory usage. */
1236     mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
1237     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1238     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1239     tx_thread_sleep(100);
1240     /* Log create counts for further tests. */
1241     rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
1242     rsc_enum_sem_usage = rsc_sem_on_set_cfg;
1243     rsc_enum_mem_usage = mem_free - rsc_mem_free_on_set_cfg;
1244     /* Log create counts when instances active for further tests. */
1245     rsc_cdc_mutex_usage = ux_test_utility_sim_mutex_create_count() - rsc_enum_mutex_usage;
1246     rsc_cdc_sem_usage = ux_test_utility_sim_sem_create_count() - rsc_enum_sem_usage;
1247     rsc_cdc_mem_usage = rsc_mem_free_on_set_cfg - _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
1248     stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
1249 
1250     /* Start the reception on control interface.  */
1251     stepinfo(">>>>>>>>>>>> Start reception on control interface\n");
1252     status = ux_host_class_cdc_acm_reception_start(cdc_acm_host_control, &cdc_acm_reception);
1253     if (status == UX_SUCCESS)
1254     {
1255 
1256         /* CDC ACM basic test error.  */
1257         printf("ERROR #87: error must be reported when invoking reception on control interface\n");
1258         test_control_return(1);
1259     }
1260 
1261     /* Start and stop immediately.  */
1262     stepinfo(">>>>>>>>>>>> Start reception and stop it immediately\n");
1263     status  = ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
1264     status |= ux_host_class_cdc_acm_reception_stop(cdc_acm_host_data, &cdc_acm_reception);
1265     if (status != UX_SUCCESS)
1266     {
1267 
1268         /* CDC ACM basic test error.  */
1269         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1270         test_control_return(1);
1271     }
1272 
1273     /* Transfer error. */
1274     stepinfo(">>>>>>>>>>>> Start reception request error\n");
1275     ux_test_hcd_sim_host_set_actions(error_on_transfer_0);
1276     status = ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
1277     if (status == UX_SUCCESS)
1278     {
1279 
1280         /* CDC ACM basic test error.  */
1281         printf("ERROR #88: error must be reported when transfer request error\n");
1282         test_control_return(1);
1283     }
1284 
1285     /* Start the reception for test.  */
1286     status = ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
1287     if (status != UX_SUCCESS)
1288     {
1289 
1290         /* CDC ACM basic test error.  */
1291         printf("ERROR #89: Start reception fail\n");
1292         test_control_return(1);
1293     }
1294 
1295     /* Test stop reception on wrong interface */
1296     status = ux_host_class_cdc_acm_reception_stop(cdc_acm_host_control, &cdc_acm_reception);
1297     if (status == UX_SUCCESS)
1298     {
1299 
1300         /* CDC ACM basic test error.  */
1301         printf("ERROR #90: error not reported when stop reception on wrong interface\n");
1302         test_control_return(1);
1303     }
1304 
1305     /* Stop reception for test */
1306     status = ux_host_class_cdc_acm_reception_stop(cdc_acm_host_data, &cdc_acm_reception);
1307     if (status != UX_SUCCESS)
1308     {
1309 
1310         /* CDC ACM basic test error.  */
1311         printf("ERROR #92: stop reception failed\n");
1312         test_control_return(1);
1313     }
1314 
1315     /* Start the reception for cdc_acm.  */
1316     status = ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
1317 
1318     /* Get the current data rate.  */
1319     stepinfo(">>>>>>>>>>>> ATB: get baud\n");
1320     status = test_usbx_simulator_cdc_acm_host_send_at_command("ATB",3);
1321 
1322     /* The device may be extracted after we start sending\receiving.  */
1323     if (status != UX_SUCCESS)
1324     {
1325 
1326         /* CDC ACM basic test error.  */
1327         printf("ERROR #11\n");
1328         test_control_return(1);
1329     }
1330 
1331     /* Get the current stop bit rate.  */
1332     stepinfo(">>>>>>>>>>>> ATS: get stop bits\n");
1333     status = test_usbx_simulator_cdc_acm_host_send_at_command("ATS",3);
1334 
1335     /* The device may be extracted after we start sending\receiving.  */
1336     if (status != UX_SUCCESS)
1337     {
1338 
1339         /* CDC ACM basic test error.  */
1340         printf("ERROR #12\n");
1341         test_control_return(1);
1342     }
1343 
1344     /* Get the current parity rate.  */
1345     stepinfo(">>>>>>>>>>>> ATP: get parity\n");
1346     status = test_usbx_simulator_cdc_acm_host_send_at_command("ATP",3);
1347 
1348     /* The device may be extracted after we start sending\receiving.  */
1349     if (status != UX_SUCCESS)
1350     {
1351 
1352         /* CDC ACM basic test error.  */
1353         printf("ERROR #13\n");
1354         test_control_return(1);
1355     }
1356 
1357     /* Get the current data bit rate.  */
1358     stepinfo(">>>>>>>>>>>> ATD: data bits\n");
1359     status = test_usbx_simulator_cdc_acm_host_send_at_command("ATD",3);
1360 
1361     /* The device may be extracted after we start sending\receiving.  */
1362     if (status != UX_SUCCESS)
1363     {
1364 
1365         /* CDC ACM basic test error.  */
1366         printf("ERROR #14\n");
1367         test_control_return(1);
1368     }
1369 
1370     /* Get the current RTS state.  */
1371     stepinfo(">>>>>>>>>>>> ATR: RTS\n");
1372     status = test_usbx_simulator_cdc_acm_host_send_at_command("ATR",3);
1373 
1374     /* The device may be extracted after we start sending\receiving.  */
1375     if (status != UX_SUCCESS)
1376     {
1377 
1378         /* CDC ACM basic test error.  */
1379         printf("ERROR #15\n");
1380         test_control_return(1);
1381     }
1382 
1383     /* Get the current DTR rate.  */
1384     stepinfo(">>>>>>>>>>>> ATT: DTR\n");
1385     status = test_usbx_simulator_cdc_acm_host_send_at_command("ATT",3);
1386 
1387     /* The device may be extracted after we start sending\receiving.  */
1388     if (status != UX_SUCCESS)
1389     {
1390 
1391         /* CDC ACM basic test error.  */
1392         printf("ERROR #16\n");
1393         test_control_return(1);
1394     }
1395 
1396     /* Stop after receive.  */
1397     stepinfo(">>>>>>>>>>>> Start reception and stop it immediately\n");
1398     status |= ux_host_class_cdc_acm_reception_stop(cdc_acm_host_data, &cdc_acm_reception);
1399     status  = ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
1400     if (status != UX_SUCCESS)
1401     {
1402 
1403         /* CDC ACM basic test error.  */
1404         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1405         test_control_return(1);
1406     }
1407 
1408     /* Read 64 bytes and next device side expect 64 byte */
1409     stepinfo(">>>>>>>>>>>> ATOP: 64/64\n");
1410     status = test_usbx_simulator_cdc_acm_host_send_at_command("ATOP", 4);
1411     if (status != UX_SUCCESS)
1412     {
1413 
1414         /* CDC ACM basic test error.  */
1415         printf("ERROR #%d\n", __LINE__);
1416         test_control_return(1);
1417     }
1418 
1419     /* Set the line coding. */
1420     stepinfo(">>>>>>>>>>>> ATL: Set LineCoding\n");
1421     at_cmd[0] = 'A';
1422     at_cmd[1] = 'T';
1423     at_cmd[2] = 'L';
1424     at_cmd[3] = 0x00;
1425     at_cmd[4] = 0xC2;
1426     at_cmd[5] = 0x01;
1427     at_cmd[6] = 0x00; /* 115200: 0x0001C200 */
1428     at_cmd[7] = UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_STOP_BIT;
1429     at_cmd[8] = UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_PARITY;
1430     at_cmd[9] = 7;
1431     status = test_usbx_simulator_cdc_acm_host_send_at_command(at_cmd,62);
1432 
1433     /* The device may be extracted after we start sending\receiving.  */
1434     if (status != UX_SUCCESS)
1435     {
1436 
1437         /* CDC ACM basic test error.  */
1438         printf("ERROR #33\n");
1439         test_control_return(1);
1440     }
1441 
1442     /* Change the line coding values.  */
1443     stepinfo(">>>>>>>>>>>> IOCTRL: SetLineCoding\n");
1444     line_coding_host.ux_host_class_cdc_acm_line_coding_dter = 9600;
1445     line_coding_host.ux_host_class_cdc_acm_line_coding_stop_bit = UX_HOST_CLASS_CDC_ACM_LINE_CODING_STOP_BIT_15;
1446     line_coding_host.ux_host_class_cdc_acm_line_coding_parity = UX_HOST_CLASS_CDC_ACM_LINE_CODING_PARITY_EVEN;
1447     line_coding_host.ux_host_class_cdc_acm_line_coding_data_bits = 5;
1448 
1449     status = _ux_host_class_cdc_acm_ioctl(cdc_acm_host_control, UX_HOST_CLASS_CDC_ACM_IOCTL_SET_LINE_CODING,
1450                                 &line_coding_host);
1451 
1452     if (status != UX_SUCCESS)
1453     {
1454 
1455         /* CDC ACM basic test error.  */
1456         printf("ERROR #17\n");
1457         test_control_return(1);
1458     }
1459 
1460     /* Slave should invoke parameter change callback */
1461     if (cdc_acm_slave_change != UX_TRUE)
1462     {
1463 
1464         /* CDC ACM basic test error. */
1465         printf("ERROR #25\n");
1466         test_control_return(1);
1467     }
1468     /* Reset slave change flag */
1469     cdc_acm_slave_change = UX_FALSE;
1470 
1471     /* Change the line state values.  */
1472     stepinfo(">>>>>>>>>>>> IOCTRL: SetLineState\n");
1473     line_state_host.ux_host_class_cdc_acm_line_state_rts = 0;
1474     line_state_host.ux_host_class_cdc_acm_line_state_dtr = 0;
1475 
1476     status = _ux_host_class_cdc_acm_ioctl(cdc_acm_host_control, UX_HOST_CLASS_CDC_ACM_IOCTL_SET_LINE_STATE,
1477                                 &line_state_host);
1478 
1479     if (status != UX_SUCCESS)
1480     {
1481 
1482         /* CDC ACM basic test error.  */
1483         printf("ERROR #18\n");
1484         test_control_return(1);
1485     }
1486 
1487     /* Slave should invoke parameter change callback */
1488     if (cdc_acm_slave_change != UX_TRUE)
1489     {
1490 
1491         /* CDC ACM basic test error. */
1492         printf("ERROR #26\n");
1493         test_control_return(1);
1494     }
1495     /* Reset slave change flag */
1496     cdc_acm_slave_change = UX_FALSE;
1497 
1498     /* Reobtain the cdc acm line values.  */
1499     /* Get the current data rate.  */
1500     stepinfo(">>>>>>>>>>>> ATB: baud rate\n");
1501     status = test_usbx_simulator_cdc_acm_host_send_at_command("ATB",3);
1502 
1503     /* The device may be extracted after we start sending\receiving.  */
1504     if (status != UX_SUCCESS)
1505     {
1506 
1507         /* CDC ACM basic test error.  */
1508         printf("ERROR #19\n");
1509         test_control_return(1);
1510     }
1511 
1512     /* Get the current stop bit rate.  */
1513     stepinfo(">>>>>>>>>>>> ATS: stop bits\n");
1514     status = test_usbx_simulator_cdc_acm_host_send_at_command("ATS",3);
1515 
1516     /* The device may be extracted after we start sending\receiving.  */
1517     if (status != UX_SUCCESS)
1518     {
1519 
1520         /* CDC ACM basic test error.  */
1521         printf("ERROR #20\n");
1522         test_control_return(1);
1523     }
1524 
1525     /* Get the current parity rate.  */
1526     stepinfo(">>>>>>>>>>>> ATP: parity\n");
1527     status = test_usbx_simulator_cdc_acm_host_send_at_command("ATP",3);
1528 
1529     /* The device may be extracted after we start sending\receiving.  */
1530     if (status != UX_SUCCESS)
1531     {
1532 
1533         /* CDC ACM basic test error.  */
1534         printf("ERROR #21\n");
1535         test_control_return(1);
1536     }
1537 
1538     /* Get the current data bit rate.  */
1539     stepinfo(">>>>>>>>>>>> ATD: data bits\n");
1540     status = test_usbx_simulator_cdc_acm_host_send_at_command("ATD",3);
1541 
1542     /* The device may be extracted after we start sending\receiving.  */
1543     if (status != UX_SUCCESS)
1544     {
1545 
1546         /* CDC ACM basic test error.  */
1547         printf("ERROR #22\n");
1548         test_control_return(1);
1549     }
1550 
1551     /* Get the current RTS state.  */
1552     stepinfo(">>>>>>>>>>>> ATR: RTS\n");
1553     status = test_usbx_simulator_cdc_acm_host_send_at_command("ATR",3);
1554 
1555     /* The device may be extracted after we start sending\receiving.  */
1556     if (status != UX_SUCCESS)
1557     {
1558 
1559         /* CDC ACM basic test error.  */
1560         printf("ERROR #23\n");
1561         test_control_return(1);
1562     }
1563 
1564     /* Test enumeration different descriptors */
1565 
1566     /* Initialize to disconnect */
1567     ux_test_dcd_sim_slave_disconnect();
1568     ux_test_hcd_sim_host_disconnect();
1569 
1570     /* Test enumeration no interrupt EP */
1571     stepinfo(">>>>>>>>>>>> Enumerate device wihtout interrupt EP\n");
1572     _ux_system_slave->ux_system_slave_device_framework_full_speed = device_framework_no_interrupt_ep;
1573     _ux_system_slave->ux_system_slave_device_framework_length_full_speed = sizeof(device_framework_no_interrupt_ep);
1574     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1575     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1576     ux_utility_delay_ms(UX_CDC_ACM_CONNECTION_DELAY);
1577     /* Instances should be ready */
1578     if (!cdc_acm_slave || !cdc_acm_host_control || !cdc_acm_host_data)
1579     {
1580 
1581         printf("ERROR #57: instance should ready after reconnect without interrupt EP\n");
1582         test_control_return(1);
1583     }
1584     ux_test_dcd_sim_slave_disconnect();
1585     ux_test_hcd_sim_host_disconnect();
1586     /* Instances should be removed */
1587     if (cdc_acm_slave || cdc_acm_host_control || cdc_acm_host_data)
1588     {
1589 
1590         printf("ERROR #60: instance should removed after disconnect without interrupt EP\n");
1591         test_control_return(1);
1592     }
1593 
1594     stepinfo(">>>>>>>>>>>> Enumerate device wihtout one of bulk EP\n");
1595     /* Pause bulk read/write since there is no bulk EP. */
1596     cdc_acm_slave_bulk_read_write = UX_FALSE;
1597 
1598     /* Test enumeration no bulk EP */
1599 
1600     ux_test_hcd_sim_host_set_actions(enum_replace_no_bulk);
1601     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1602     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1603     ux_utility_delay_ms(UX_CDC_ACM_CONNECTION_DELAY);
1604     /* Data instances should not be ready */
1605     if (cdc_acm_host_data)
1606     {
1607 
1608         printf("ERROR #58: instance should NOT ready after reconnect without one of bulk EP\n");
1609         test_control_return(1);
1610     }
1611     UX_TEST_ASSERT(ux_test_check_actions_empty());
1612 
1613     ux_test_dcd_sim_slave_disconnect();
1614     ux_test_hcd_sim_host_disconnect();
1615     if (cdc_acm_slave || cdc_acm_host_control)
1616     {
1617 
1618         printf("ERROR #61: instance should be removed after disconnect without one of bulk EP\n");
1619         test_control_return(1);
1620     }
1621 
1622     replaced_cfg_descriptor_no_bulk[sizeof(replaced_cfg_descriptor_no_bulk) - 7 + 2] ^= 0x80;
1623     ux_test_hcd_sim_host_set_actions(enum_replace_no_bulk);
1624     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1625     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1626     ux_utility_delay_ms(UX_CDC_ACM_CONNECTION_DELAY);
1627     /* Data instances should not be ready */
1628     if (cdc_acm_host_data)
1629     {
1630 
1631         printf("ERROR #59: instance should NOT ready after reconnect without one of bulk EP\n");
1632         test_control_return(1);
1633     }
1634 
1635     /* Restore frameworks */
1636     ux_test_dcd_sim_slave_disconnect();
1637     ux_test_hcd_sim_host_disconnect();
1638     _ux_system_slave->ux_system_slave_device_framework_full_speed = device_framework_full_speed;
1639     _ux_system_slave->ux_system_slave_device_framework_length_full_speed = DEVICE_FRAMEWORK_LENGTH_FULL_SPEED;
1640     ux_test_hcd_sim_host_set_actions(UX_NULL);
1641     cdc_acm_slave_bulk_read_write = UX_TRUE;
1642 
1643     /* Swap EP address for different EP sequence. */
1644     stepinfo(">>>>>>>>>>>> Enumerate device swap bulk EP addresses\n");
1645     ux_test_dcd_sim_slave_disconnect();
1646     ux_test_hcd_sim_host_disconnect();
1647     test_swap_framework_bulk_ep_descriptors();
1648     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1649     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1650     ux_utility_delay_ms(UX_CDC_ACM_CONNECTION_DELAY);
1651     /* Instances should be ready */
1652     if (!cdc_acm_slave || !cdc_acm_host_control || !cdc_acm_host_data)
1653     {
1654 
1655         printf("ERROR #53: instance not ready after reconnect (%p,%p,%p)\n", cdc_acm_slave, cdc_acm_host_control, cdc_acm_host_data);
1656         test_control_return(1);
1657     }
1658 
1659     if (cdc_acm_host_control->ux_host_class_cdc_acm_interrupt_endpoint)
1660     {
1661 
1662         stepinfo(">>>>>>>>>>>> Notification reception test\n");
1663 
1664         /* Set notification callback */
1665         status = _ux_host_class_cdc_acm_ioctl(cdc_acm_host_control, UX_HOST_CLASS_CDC_ACM_IOCTL_NOTIFICATION_CALLBACK,
1666                                     (VOID*)ux_test_host_class_cdc_acm_device_status_change_callback);
1667         if (status != UX_SUCCESS)
1668         {
1669 
1670             printf("ERROR #55: notification callback set fail\n");
1671             test_control_return(1);
1672         }
1673         interaction_count = 0;
1674         ux_test_hcd_sim_host_set_actions(check_ignore_next_transfer_request);
1675         /* Simulate notification! */
1676         cdc_acm_host_control->ux_host_class_cdc_acm_interrupt_endpoint->ux_endpoint_transfer_request.ux_transfer_request_completion_code = UX_SUCCESS;
1677         _ux_host_class_cdc_acm_transfer_request_completed(&cdc_acm_host_control->ux_host_class_cdc_acm_interrupt_endpoint->ux_endpoint_transfer_request);
1678         /* There should be call of transfer to re-start notification monitoring */
1679         if (interaction_count == 0)
1680         {
1681 
1682             printf("ERROR #56: notification monitoring not reactivated\n");
1683             test_control_return(1);
1684         }
1685 
1686     }
1687 
1688     /* Start the reception for cdc_acm.  */
1689     status = ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
1690     if (status != UX_SUCCESS)
1691     {
1692 
1693         printf("ERROR #54: reception start error\n");
1694         test_control_return(1);
1695     }
1696 
1697     /* Get the current DTR rate.  */
1698     stepinfo(">>>>>>>>>>>> ATT: get DTR\n");
1699     status = test_usbx_simulator_cdc_acm_host_send_at_command("ATT",3);
1700 
1701     /* The device may be extracted after we start sending\receiving.  */
1702     if (status != UX_SUCCESS)
1703     {
1704 
1705         /* CDC ACM basic test error.  */
1706         printf("ERROR #24\n");
1707         test_control_return(1);
1708     }
1709 
1710     /* Try invalid command on IOCTL.  */
1711     stepinfo(">>>>>>>>>>>> ATF: invalid device IOCTRL command\n");
1712     status = test_usbx_simulator_cdc_acm_host_send_at_command("ATF",3);
1713 
1714     /* The device may be extracted after we start sending\receiving.  */
1715     if (status != UX_SUCCESS)
1716     {
1717 
1718         /* CDC ACM basic test error.  */
1719         printf("ERROR #36\n");
1720         test_control_return(1);
1721     }
1722 
1723     /* Try slave ABORT command on IOCTL.  */
1724     stepinfo(">>>>>>>>>>>> ATA: slave IOCTRL ABORT test\n");
1725     status = test_usbx_simulator_cdc_acm_host_send_at_command("ATA",3);
1726 
1727     /* The device may be extracted after we start sending\receiving.  */
1728     if (status != UX_SUCCESS)
1729     {
1730 
1731         /* CDC ACM basic test error.  */
1732         printf("ERROR #37\n");
1733         test_control_return(1);
1734     }
1735 
1736     /* Start reception again if it's aborted */
1737     ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
1738     /* Read until there is no data from slave */
1739     do
1740     {
1741         status = command_received_count;
1742         tx_thread_sleep(20);
1743     } while(status != command_received_count);
1744 
1745     /* Try overflow */
1746     stepinfo(">>>>>>>>>>>> Reception overflow test\n");
1747     cdc_acm_reception_overflow = UX_TRUE;
1748     /* Start writing long buffer in device side */
1749     test_usbx_simulator_cdc_acm_host_send_string("ATO\0", 4);
1750     /* Waiting overflow detection */
1751     status = 50;
1752     while(cdc_acm_reception_overflow && status --)
1753     {
1754         tx_thread_sleep(20);
1755     }
1756     if (cdc_acm_reception_overflow)
1757     {
1758 
1759         printf("ERROR #93: Reception overflow not detected\n");
1760         cdc_acm_reception_overflow = UX_FALSE;
1761         test_control_return(1);
1762     }
1763     /* Continue reception */
1764     ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
1765 
1766     /* GetLineCoding with larger buffer size
1767        response should be OK with correct bytes */
1768     stepinfo(">>>>>>>>>>>> GetLineCoding with larger buffer than line coding data\n");
1769     status = ux_test_host_class_cdc_acm_command(cdc_acm_host_control, UX_HOST_CLASS_CDC_ACM_REQ_GET_LINE_CODING,
1770                                                 0, cdc_acm_reception_buffer, UX_HOST_CLASS_CDC_ACM_LINE_CODING_LENGTH + 1,
1771                                                 &actual_length);
1772 
1773     /* The device may be extracted after we start sending\receiving.  */
1774     if (status != UX_SUCCESS)
1775     {
1776 
1777         /* CDC ACM basic test error.  */
1778         printf("ERROR #27\n");
1779         test_control_return(1);
1780     }
1781     /* Returned number of bytes should be correct */
1782     if (actual_length != UX_HOST_CLASS_CDC_ACM_LINE_CODING_LENGTH)
1783     {
1784 
1785         /* CDC ACM basic test error.  */
1786         printf("ERROR #28\n");
1787         test_control_return(1);
1788     }
1789 
1790     /* Host command test */
1791 
1792     /* Undefined command */
1793     stepinfo(">>>>>>>>>>>> Invalid command\n");
1794     status = _ux_host_class_cdc_acm_command(cdc_acm_host_control, UX_HOST_CLASS_CDC_ACM_REQ_GET_LINE_CODING + 7,
1795                                             0, cdc_acm_reception_buffer, UX_HOST_CLASS_CDC_ACM_LINE_CODING_LENGTH + 1);
1796 
1797     /* The device may be extracted after we start sending\receiving.  */
1798     if (status == UX_SUCCESS)
1799     {
1800 
1801         /* CDC ACM basic test error.  */
1802         printf("ERROR #29\n");
1803         test_control_return(1);
1804     }
1805 
1806     /* Semaphore protection error test */
1807     stepinfo(">>>>>>>>>>>> Semaphore get error on command\n");
1808     ux_test_utility_sim_sem_get_error_generation_start(0);
1809     status = _ux_host_class_cdc_acm_command(cdc_acm_host_control, UX_HOST_CLASS_CDC_ACM_REQ_GET_LINE_CODING,
1810                                             0, cdc_acm_reception_buffer, UX_HOST_CLASS_CDC_ACM_LINE_CODING_LENGTH);
1811     if (status == UX_SUCCESS)
1812     {
1813 
1814         printf("ERROR #64: no error reported on control semaphore error\n");
1815         test_control_return(1);
1816     }
1817     ux_test_utility_sim_sem_get_error_generation_stop();
1818 
1819     /* Host entry test */
1820 
1821     /* Invalid command */
1822     stepinfo(">>>>>>>>>>>> Host Entry - Invalid command\n");
1823     command.ux_host_class_command_request =  0xFF;
1824     status = ux_host_class_cdc_acm_entry(&command);
1825     if (status == UX_SUCCESS)
1826     {
1827 
1828         printf("ERROR #62: no error report on invalid command entry\n");
1829         test_control_return(1);
1830     }
1831 
1832     stepinfo(">>>>>>>>>>>> Host Entry - Query\n");
1833 
1834     /* Query test - wrong class */
1835     command.ux_host_class_command_request = UX_HOST_CLASS_COMMAND_QUERY;
1836     command.ux_host_class_command_usage = UX_HOST_CLASS_COMMAND_USAGE_CSP;
1837     command.ux_host_class_command_class = 0xFF;
1838     status = ux_host_class_cdc_acm_entry(&command);
1839     if (status == UX_SUCCESS)
1840     {
1841 
1842         printf("ERROR #63: no error report when Query class wrong\n");
1843         test_control_return(1);
1844     }
1845 
1846     /* Query test - CTRL & DLC */
1847     command.ux_host_class_command_request = UX_HOST_CLASS_COMMAND_QUERY;
1848     command.ux_host_class_command_usage = UX_HOST_CLASS_COMMAND_USAGE_CSP;
1849     command.ux_host_class_command_class = UX_HOST_CLASS_CDC_CONTROL_CLASS;
1850     command.ux_host_class_command_subclass = UX_HOST_CLASS_CDC_DLC_SUBCLASS;
1851     command.ux_host_class_command_iad_class = 0;
1852     command.ux_host_class_command_iad_subclass = 0;
1853     status = ux_host_class_cdc_acm_entry(&command);
1854     if (status != UX_SUCCESS)
1855     {
1856 
1857         printf("ERROR #64: error report when Query class OK\n");
1858         test_control_return(1);
1859     }
1860 
1861     /* Query test - wrong IAD */
1862     command.ux_host_class_command_request = UX_HOST_CLASS_COMMAND_QUERY;
1863     command.ux_host_class_command_usage = UX_HOST_CLASS_COMMAND_USAGE_CSP;
1864     command.ux_host_class_command_class = UX_HOST_CLASS_CDC_CONTROL_CLASS;
1865     command.ux_host_class_command_subclass = UX_HOST_CLASS_CDC_DLC_SUBCLASS;
1866     command.ux_host_class_command_iad_class = 0xFE;
1867     status = ux_host_class_cdc_acm_entry(&command);
1868     if (status == UX_SUCCESS)
1869     {
1870 
1871         printf("ERROR #65: no error report when Query class IAD wrong");
1872         test_control_return(1);
1873     }
1874 
1875     /* Host class deactivate & activate */
1876     stepinfo(">>>>>>>>>>>> Host CDC deactivate & activate\n");
1877     command.ux_host_class_command_container = cdc_acm_host_control->ux_host_class_cdc_acm_interface;
1878     command.ux_host_class_command_class_ptr = cdc_acm_host_control->ux_host_class_cdc_acm_class;
1879     command.ux_host_class_command_instance = cdc_acm_host_control;
1880     command.ux_host_class_command_request =  UX_HOST_CLASS_COMMAND_DEACTIVATE;
1881 
1882     command1.ux_host_class_command_container = cdc_acm_host_data->ux_host_class_cdc_acm_interface;
1883     command1.ux_host_class_command_class_ptr = cdc_acm_host_data->ux_host_class_cdc_acm_class;
1884     command1.ux_host_class_command_instance = cdc_acm_host_data;
1885     command1.ux_host_class_command_request =  UX_HOST_CLASS_COMMAND_DEACTIVATE;
1886 
1887     ux_host_class_cdc_acm_entry(&command);
1888     /* Instance should be removed */
1889     if (cdc_acm_host_control)
1890     {
1891 
1892         printf("ERROR #67: control instance not deactivate\n");
1893         test_control_return(1);
1894     }
1895 
1896     ux_host_class_cdc_acm_entry(&command1);
1897     /* Instance should be removed */
1898     if (cdc_acm_host_data)
1899     {
1900 
1901         printf("ERROR #67: control instance not deactivate\n");
1902         test_control_return(1);
1903     }
1904 
1905     command.ux_host_class_command_request =  UX_HOST_CLASS_COMMAND_ACTIVATE;
1906     ux_host_class_cdc_acm_entry(&command);
1907     /* Instance should be back */
1908     if (!cdc_acm_host_control)
1909     {
1910 
1911         printf("ERROR #68: control instance not activate\n");
1912         test_control_return(1);
1913     }
1914 
1915     command1.ux_host_class_command_request =  UX_HOST_CLASS_COMMAND_ACTIVATE;
1916     ux_host_class_cdc_acm_entry(&command1);
1917     /* Instance should be back */
1918     if (!cdc_acm_host_data)
1919     {
1920 
1921         printf("ERROR #68: control instance not activate\n");
1922         test_control_return(1);
1923     }
1924 
1925     /* Start the reception for cdc_acm.  */
1926     status = ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
1927     if (status != UX_SUCCESS)
1928     {
1929 
1930         printf("ERROR #70: reception start error\n");
1931         test_control_return(1);
1932     }
1933 
1934     /* Get the current stop bit rate. */
1935     stepinfo(">>>>>>>>>>>> ATS: stop bits\n");
1936     status = test_usbx_simulator_cdc_acm_host_send_at_command("ATS",3);
1937 
1938     /* The device may be extracted after we start sending\receiving.  */
1939     if (status != UX_SUCCESS)
1940     {
1941 
1942         /* CDC ACM basic test error.  */
1943         printf("ERROR #69\n");
1944         test_control_return(1);
1945     }
1946 
1947     /* Sim: slave lost configure while reading pending. */
1948     stepinfo(">>>>>>>>>>>> Slave lost connection while reading\n");
1949     ux_utility_memory_set(cdc_acm_xmit_buffer, 0x00, 3);
1950     status = ux_host_class_cdc_acm_write(cdc_acm_host_data, cdc_acm_xmit_buffer, 128, &actual_length);
1951     /* Simulate disconnect after first packet sent */
1952     test_slave_cdc_acm_transfer_disconnect(cdc_acm_slave_bak, UX_ENDPOINT_OUT);
1953     status = ux_host_class_cdc_acm_write(cdc_acm_host_data, cdc_acm_xmit_buffer, 64, &actual_length);
1954     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1955     tx_thread_sleep(50);
1956 
1957     /* Sim: slave lost configure while writing pending. */
1958     stepinfo(">>>>>>>>>>>> Slave lost connection while writing\n");
1959     status = test_usbx_simulator_cdc_acm_host_send_string("\0",1);
1960     status = test_usbx_simulator_cdc_acm_host_send_string("ATW",3);
1961     /* The device may be extracted after we start sending\receiving.  */
1962     if (status != UX_SUCCESS)
1963     {
1964 
1965         /* CDC ACM basic test error.  */
1966         printf("ERROR #42\n");
1967         test_control_return(1);
1968     }
1969     tx_thread_sleep(20);
1970     test_slave_cdc_acm_transfer_disconnect(cdc_acm_slave_bak, UX_ENDPOINT_IN);
1971 
1972     /* Now disconnect the device.  */
1973     ux_test_dcd_sim_slave_disconnect();
1974 
1975     /* Read/write through disconnected slave should return error */
1976     stepinfo(">>>>>>>>>>>> R/W on deactivated slave interface instance\n");
1977     /* Try read, error must be returned */
1978     status = ux_device_class_cdc_acm_read(cdc_acm_slave_bak, buffer, UX_DEMO_BUFFER_SIZE, &actual_length);
1979     if (status == UX_SUCCESS)
1980     {
1981 
1982         /* CDC ACM basic test error.  */
1983         printf("ERROR #40\n");
1984         test_control_return(1);
1985 
1986     }
1987 
1988     /* Try write, error must be returned */
1989     status = ux_device_class_cdc_acm_write(cdc_acm_slave_bak, buffer, UX_DEMO_BUFFER_SIZE, &actual_length);
1990     if (status == UX_SUCCESS)
1991     {
1992 
1993         /* CDC ACM basic test error.  */
1994         printf("ERROR #41\n");
1995         test_control_return(1);
1996 
1997     }
1998 
1999     stepinfo(">>>>>>>>>>>> R/W on invalid interface instance\n");
2000 
2001     /* Try host read on control interface, error must be returned. */
2002     status = ux_host_class_cdc_acm_read(cdc_acm_host_control, buffer, 64, &actual_length);
2003     if (status != UX_HOST_CLASS_INSTANCE_UNKNOWN)
2004     {
2005 
2006         /* CDC ACM basic test error.  */
2007         printf("ERROR #47\n");
2008         test_control_return(1);
2009     }
2010 
2011     /* Try host write, error must be returned. */
2012     status = ux_host_class_cdc_acm_write(cdc_acm_host_control, buffer, 64, &actual_length);
2013     if (status != UX_HOST_CLASS_INSTANCE_UNKNOWN)
2014     {
2015 
2016         /* CDC ACM basic test error.  */
2017         printf("ERROR #48\n");
2018         test_control_return(1);
2019     }
2020 
2021     stepinfo(">>>>>>>>>>>> R/W on deactivated host interface instance\n");
2022 
2023     ux_test_hcd_sim_host_disconnect();
2024     tx_thread_sleep(50);
2025 
2026     /* Try host read on disconnected interface, error must be returned. */
2027     status = ux_host_class_cdc_acm_read(cdc_acm_host_data_bak, buffer, 64, &actual_length);
2028     if (status != UX_HOST_CLASS_INSTANCE_UNKNOWN)
2029     {
2030 
2031         /* CDC ACM basic test error.  */
2032         printf("ERROR #49\n");
2033         test_control_return(1);
2034     }
2035 
2036     /* Try host write, error must be returned. */
2037     status = ux_host_class_cdc_acm_write(cdc_acm_host_data_bak, buffer, 64, &actual_length);
2038     if (status != UX_HOST_CLASS_INSTANCE_UNKNOWN)
2039     {
2040 
2041         /* CDC ACM basic test error.  */
2042         printf("ERROR #43\n");
2043         test_control_return(1);
2044     }
2045 
2046     stepinfo(">>>>>>>>>>>> IOCTRL on deactivated host interface instance\n");
2047     status = ux_host_class_cdc_acm_ioctl(cdc_acm_host_data_bak, 0, UX_NULL);
2048     if (status == UX_SUCCESS)
2049     {
2050 
2051         printf("ERROR #73: IOCTRL on deactivated interface should report error\n");
2052         test_control_return(1);
2053     }
2054 
2055     ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
2056     ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
2057     while(!cdc_acm_host_control || !cdc_acm_host_data)
2058         tx_thread_sleep(10);
2059 
2060     /* Host IOCTRL tests */
2061 
2062     /* Try invalid IOCTRL command */
2063     stepinfo(">>>>>>>>>>>> IOCTRL invalid command\n");
2064     status = ux_host_class_cdc_acm_ioctl(cdc_acm_host_control, 0xFF, UX_NULL);
2065     if (status != UX_FUNCTION_NOT_SUPPORTED)
2066     {
2067 
2068         printf("ERROR #74: IOCTRL with invalid command should report UX_FUNCTION_NOT_SUPPORTED\n");
2069         test_control_return(1);
2070     }
2071 
2072     /* Try IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_GET_DEVICE_STATUS */
2073     stepinfo(">>>>>>>>>>>> IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_GET_DEVICE_STATUS\n");
2074     status = ux_host_class_cdc_acm_ioctl(cdc_acm_host_control, UX_HOST_CLASS_CDC_ACM_IOCTL_GET_DEVICE_STATUS, &test_n);
2075     if (status != UX_SUCCESS)
2076     {
2077 
2078         printf("ERROR #75: IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_GET_DEVICE_STATUS should be OK\n");
2079         test_control_return(1);
2080     }
2081 
2082     /* Try IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_ABORT_OUT_PIPE */
2083     stepinfo(">>>>>>>>>>>> IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_ABORT_OUT_PIPE\n");
2084     status = ux_host_class_cdc_acm_ioctl(cdc_acm_host_data, UX_HOST_CLASS_CDC_ACM_IOCTL_ABORT_OUT_PIPE, UX_NULL);
2085     if (status != UX_SUCCESS)
2086     {
2087 
2088         printf("ERROR #76: IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_ABORT_OUT_PIPE should be OK\n");
2089         test_control_return(1);
2090     }
2091 
2092     /* Try IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_ABORT_IN_PIPE */
2093     stepinfo(">>>>>>>>>>>> IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_ABORT_IN_PIPE\n");
2094     status = ux_host_class_cdc_acm_ioctl(cdc_acm_host_data, UX_HOST_CLASS_CDC_ACM_IOCTL_ABORT_IN_PIPE, UX_NULL);
2095     if (status != UX_SUCCESS)
2096     {
2097 
2098         printf("ERROR #77: IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_ABORT_IN_PIPE should be OK\n");
2099         test_control_return(1);
2100     }
2101 
2102     /* Try IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_SEND_BREAK */
2103     stepinfo(">>>>>>>>>>>> IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_SEND_BREAK\n");
2104     status = ux_host_class_cdc_acm_ioctl(cdc_acm_host_control, UX_HOST_CLASS_CDC_ACM_IOCTL_SEND_BREAK, &test_n);
2105     /* Not supported by simulator */
2106     if (status == UX_SUCCESS)
2107     {
2108 
2109         printf("ERROR #78: IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_SEND_BREAK should fail\n");
2110         test_control_return(1);
2111     }
2112 
2113     /* Try IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_GET/SET_LINE_CODING */
2114     stepinfo(">>>>>>>>>>>> IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_GET/SET_LINE_CODING without enough memory\n");
2115 
2116     /* Use out memories */
2117     ux_test_utility_sim_mem_allocate_until(UX_HOST_CLASS_CDC_ACM_LINE_CODING_LENGTH);
2118 
2119     /* UX_HOST_CLASS_CDC_ACM_IOCTL_GET_LINE_CODING */
2120     status = ux_host_class_cdc_acm_ioctl(cdc_acm_host_data, UX_HOST_CLASS_CDC_ACM_IOCTL_GET_LINE_CODING, &test_n);
2121     if (status != UX_MEMORY_INSUFFICIENT)
2122     {
2123 
2124         printf("ERROR #80: IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_GET_LINE_CODING should be fail if no memory\n");
2125         test_control_return(1);
2126     }
2127 
2128     /* UX_HOST_CLASS_CDC_ACM_IOCTL_SET_LINE_CODING */
2129     status = ux_host_class_cdc_acm_ioctl(cdc_acm_host_data, UX_HOST_CLASS_CDC_ACM_IOCTL_SET_LINE_CODING, &line_coding_host);
2130     if (status != UX_MEMORY_INSUFFICIENT)
2131     {
2132 
2133         printf("ERROR #81: IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_SET_LINE_CODING should be fail if no memory\n");
2134         test_control_return(1);
2135     }
2136 
2137     /* Free memory */
2138     ux_test_utility_sim_mem_free_all();
2139 
2140     /* Try host read/write with semaphore error. */
2141     stepinfo(">>>>>>>>>>>> R/W semaphore error\n");
2142 
2143     /* Try host write, error must be returned. */
2144     ux_test_utility_sim_sem_get_error_exception_add(UX_NULL, UX_WAIT_FOREVER);
2145     ux_test_utility_sim_sem_get_error_generation_start(0);
2146 
2147     /* Write small size */
2148     status = ux_host_class_cdc_acm_write(cdc_acm_host_data, buffer, 64, &actual_length);
2149     if (status == UX_SUCCESS)
2150     {
2151 
2152         /* CDC ACM basic test error.  */
2153         printf("ERROR #52: write semaphore error not reported\n");
2154         test_control_return(1);
2155     }
2156 
2157     /* Read large size */
2158     status = ux_host_class_cdc_acm_read(cdc_acm_host_data, buffer, UX_DEMO_BUFFER_SIZE, &actual_length);
2159     if (status == UX_SUCCESS)
2160     {
2161 
2162         /* CDC ACM basic test error.  */
2163         printf("ERROR #51: read semaphore error not reported\n");
2164         test_control_return(1);
2165     }
2166     ux_test_utility_sim_sem_get_error_generation_stop();
2167     ux_test_utility_sim_sem_get_error_exception_reset();
2168 
2169     /* Try host read/write with transfer error. */
2170     stepinfo(">>>>>>>>>>>> R/W transfer error\n");
2171 
2172     ux_test_hcd_sim_host_set_actions(error_on_transfer_0);
2173     status = ux_host_class_cdc_acm_write(cdc_acm_host_data, buffer, 64, &actual_length);
2174     if (status == UX_SUCCESS)
2175     {
2176 
2177         /* CDC ACM basic test error.  */
2178         printf("ERROR #82: write transfer request error not reported\n");
2179         test_control_return(1);
2180     }
2181 
2182     /* Stop reception for test */
2183     status = ux_host_class_cdc_acm_reception_stop(cdc_acm_host_data, &cdc_acm_reception);
2184 
2185     ux_test_hcd_sim_host_set_actions(error_on_transfer_0);
2186     /* Read large size */
2187     status = ux_host_class_cdc_acm_read(cdc_acm_host_data, buffer, UX_DEMO_BUFFER_SIZE, &actual_length);
2188     if (status == UX_SUCCESS)
2189     {
2190 
2191         /* CDC ACM basic test error.  */
2192         printf("ERROR #83: read transfer request error not reported\n");
2193         test_control_return(1);
2194     }
2195 
2196     /* Error on second transfer request */
2197     ux_test_hcd_sim_host_set_actions(error_on_transfer_1);
2198 
2199     /* Put a semaphore for first transfer request. */
2200     _ux_utility_semaphore_put(&cdc_acm_host_data->ux_host_class_cdc_acm_bulk_in_endpoint->ux_endpoint_transfer_request.ux_transfer_request_semaphore);
2201 
2202     /* Read large size */
2203     status = ux_host_class_cdc_acm_read(cdc_acm_host_data, buffer, UX_DEMO_BUFFER_SIZE, &actual_length);
2204     if (status == UX_SUCCESS)
2205     {
2206 
2207         /* CDC ACM basic test error.  */
2208         printf("ERROR #84: read transfer request error not reported\n");
2209         test_control_return(1);
2210     }
2211     if (actual_length == 0)
2212     {
2213 
2214         /* CDC ACM basic test error.  */
2215         printf("ERROR #85: actual length should not be 0\n");
2216         test_control_return(1);
2217     }
2218 
2219     /* Flush device. */
2220     status = ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
2221     status = test_usbx_simulator_cdc_acm_host_send_string("ATO0",4);
2222     status = test_usbx_simulator_cdc_acm_host_send_string("ATO0",4);
2223     _tx_thread_sleep(10);
2224 
2225     /* Stop reception for read test. */
2226     status = ux_host_class_cdc_acm_reception_stop(cdc_acm_host_data, &cdc_acm_reception);
2227 
2228     stepinfo(">>>>>>>>>>>> Read transfer good\n");
2229 
2230     /* ATO1: expect return OK */
2231     status = test_usbx_simulator_cdc_acm_host_send_string("ATO1",4);
2232 
2233     /* Read, expect short package. */
2234     status = ux_host_class_cdc_acm_read(cdc_acm_host_data, cdc_acm_reception_buffer, 64, &actual_length);
2235     if (status != UX_SUCCESS)
2236     {
2237 
2238         /* CDC ACM basic test error.  */
2239         printf("ERROR #86: read transfer request error should not be reported\n");
2240         test_control_return(1);
2241     }
2242     if (actual_length != 2)
2243     {
2244 
2245         /* CDC ACM basic test error.  */
2246         printf("ERROR #87: actual length should be 2\n");
2247         test_control_return(1);
2248     }
2249 
2250     /* ATO1: expect return OK */
2251     status = test_usbx_simulator_cdc_acm_host_send_string("ATO1",4);
2252 
2253     /* Read, expect exact size. */
2254     status = ux_host_class_cdc_acm_read(cdc_acm_host_data, cdc_acm_reception_buffer, 2, &actual_length);
2255     if (status != UX_SUCCESS)
2256     {
2257 
2258         /* CDC ACM basic test error.  */
2259         printf("ERROR #86: read transfer request error should not be reported\n");
2260         test_control_return(1);
2261     }
2262     if (actual_length != 2)
2263     {
2264 
2265         /* CDC ACM basic test error.  */
2266         printf("ERROR #87: actual length should be 2\n");
2267         test_control_return(1);
2268     }
2269 
2270     /* ATO0: expect ZLP */
2271     test_usbx_simulator_cdc_acm_host_send_string("ATO0",4);
2272     status = ux_host_class_cdc_acm_read(cdc_acm_host_data, cdc_acm_reception_buffer, 64, &actual_length);
2273     if (status != UX_SUCCESS)
2274     {
2275 
2276         /* CDC ACM basic test error.  */
2277         printf("ERROR #94: read transfer request error should not be reported\n");
2278         test_control_return(1);
2279     }
2280     if (actual_length != 0)
2281     {
2282 
2283         /* CDC ACM basic test error.  */
2284         printf("ERROR #95: actual length should be 0 but not %ld\n", actual_length);
2285         test_control_return(1);
2286     }
2287 
2288 #if defined(UX_DEVICE_CLASS_CDC_ACM_WRITE_AUTO_ZLP)
2289     test_usbx_simulator_cdc_acm_host_send_string("ATO2",4);
2290     status = ux_host_class_cdc_acm_read(cdc_acm_host_data, cdc_acm_reception_buffer, UX_DEMO_RECEPTION_BUFFER_SIZE, &actual_length);
2291     if (status != UX_SUCCESS)
2292     {
2293 
2294         /* CDC ACM basic test error.  */
2295         printf("ERROR #%d: read transfer request error should not be reported\n", __LINE__);
2296         test_control_return(1);
2297     }
2298     if (actual_length != 64)
2299     {
2300 
2301         /* CDC ACM basic test error.  */
2302         printf("ERROR #%d: actual length should be 64 but not %ld\n", __LINE__, actual_length);
2303         test_control_return(1);
2304     }
2305 #endif
2306 
2307     /* Start the reception for cdc_acm.  */
2308     status = ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
2309 
2310     /* Swap bulk IN/OUT endpoint position.
2311        Simulate detach and attach for HS enumeration,
2312        and test possible mutex creation error handlings.
2313      */
2314     if (rsc_cdc_mutex_usage) stepinfo(">>>>>>>>>>>> Enumerate mutex error\n");
2315     for (test_n = 0; test_n < rsc_cdc_mutex_usage; test_n ++)
2316     {
2317 
2318         stepinfo("%4ld / %4ld\n", test_n, rsc_cdc_mutex_usage - 1);
2319 
2320         /* Disconnect. */
2321         ux_test_dcd_sim_slave_disconnect();
2322         ux_test_hcd_sim_host_disconnect();
2323 
2324         /* Swap EP address. */
2325         test_swap_framework_bulk_ep_descriptors();
2326 
2327         /* Generate error while the test_n and after mutex are requested */
2328         ux_test_utility_sim_mutex_error_generation_start(test_n + rsc_enum_mutex_usage);
2329 
2330         /* Connect. */
2331         ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
2332         ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
2333         tx_thread_sleep(100);
2334 
2335         if (cdc_acm_host_control && cdc_acm_host_data)
2336         {
2337 
2338             printf("ERROR #97: at least one interface should fail\n");
2339             test_control_return(1);
2340         }
2341     }
2342     ux_test_utility_sim_mutex_error_generation_stop();
2343 
2344     /* Simulate detach and attach for FS enumeration,
2345        and test possible semaphore creation error handlings.
2346      */
2347     ux_test_utility_sim_sem_get_error_exception_add(&_ux_system_host -> ux_system_host_hcd_semaphore, UX_WAIT_FOREVER);
2348     if (rsc_cdc_sem_usage) stepinfo(">>>>>>>>>>>> Enumerate semaphore error\n");
2349     for (test_n = 0; test_n < rsc_cdc_sem_usage; test_n ++)
2350     {
2351 
2352         stepinfo("%4ld / %4ld\n", test_n, rsc_cdc_sem_usage - 1);
2353 
2354         /* Disconnect. */
2355         ux_test_dcd_sim_slave_disconnect();
2356         ux_test_hcd_sim_host_disconnect();
2357 
2358         /* Generate error while the test_n and after semaphore are requested */
2359         ux_test_utility_sim_sem_error_generation_start(test_n + rsc_enum_sem_usage);
2360 
2361         /* Connect. */
2362         error_callback_counter = 0;
2363         ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
2364         ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
2365         #if 0
2366         tx_thread_sleep(100);
2367         #else
2368         /* Wait until error detected. */
2369         ux_test_breakable_sleep(100, sleep_break_on_error);
2370         #endif
2371 
2372         if (cdc_acm_host_control && cdc_acm_host_data)
2373         {
2374 
2375             printf("ERROR #97: at least one interface should fail\n");
2376             test_control_return(1);
2377         }
2378     }
2379     ux_test_utility_sim_sem_error_generation_stop();
2380     ux_test_utility_sim_sem_get_error_exception_reset();
2381 
2382     stepinfo(">>>>>>>>>>>> Enumerate interrupt EP transfer request error\n");
2383     /* Disconnect. */
2384     ux_test_dcd_sim_slave_disconnect();
2385     ux_test_hcd_sim_host_disconnect();
2386     /* Transfer error on interrupt IN 0x83 */
2387     ux_test_hcd_sim_host_set_actions(error_on_transfer_interruptEP);
2388     /* Connect. */
2389     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
2390     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
2391     tx_thread_sleep(100);
2392     if (cdc_acm_host_control)
2393     {
2394 
2395         printf("ERROR #96: control interface should fail\n");
2396         test_control_return(1);
2397     }
2398 
2399     stepinfo(">>>>>>>>>>>> Capabilities get\n");
2400 
2401     /* Confirm connection */
2402     ux_test_dcd_sim_slave_disconnect();
2403     ux_test_hcd_sim_host_disconnect();
2404     ux_test_hcd_sim_host_set_actions(UX_NULL);
2405     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
2406     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
2407     test_n = 10;
2408     while(cdc_acm_host_control == UX_NULL && test_n --)
2409         tx_thread_sleep(10);
2410     if (cdc_acm_host_control == UX_NULL)
2411     {
2412 
2413         printf("ERROR #99: CDC ACM control interface is not ready\n");
2414         test_control_return(1);
2415     }
2416 
2417     /* Some of descriptor length is too small */
2418     replaced_cfg_descriptor[9+8+9+5] = 0;
2419     ux_test_hcd_sim_host_set_actions(replaced_GetCfgDescr);
2420     status = _ux_host_class_cdc_acm_capabilities_get(cdc_acm_host_control);
2421     if (status != UX_DESCRIPTOR_CORRUPTED)
2422     {
2423 
2424         printf("ERROR #100: descriptor error should be reported\n");
2425         test_control_return(1);
2426     }
2427 
2428     /* Some of descriptor length is too large */
2429     replaced_cfg_descriptor[9+8+9+5] = sizeof(replaced_cfg_descriptor);
2430     ux_test_hcd_sim_host_set_actions(replaced_GetCfgDescr);
2431     status = _ux_host_class_cdc_acm_capabilities_get(cdc_acm_host_control);
2432     if (status != UX_DESCRIPTOR_CORRUPTED)
2433     {
2434 
2435         printf("ERROR #101: no descriptor error reported\n");
2436         test_control_return(1);
2437     }
2438 
2439     /* Restore descriptor size */
2440     replaced_cfg_descriptor[9+8+9+5] = device_framework_full_speed[18 + 9+8+9+5];
2441     /* Set descriptor sub class to DLC */
2442     replaced_cfg_descriptor[9+8 + 6] = UX_HOST_CLASS_CDC_DLC_SUBCLASS;
2443     ux_test_hcd_sim_host_set_actions(replaced_GetCfgDescr);
2444     status = _ux_host_class_cdc_acm_capabilities_get(cdc_acm_host_control);
2445     if (status != UX_SUCCESS)
2446     {
2447 
2448         printf("ERROR #102: no error expected\n");
2449         test_control_return(1);
2450     }
2451 
2452     stepinfo(">>>>>>>>>>>> Deactivate while writing\n");
2453     test_usbx_simulator_cdc_acm_host_send_string("ATK",3); /* Disconnect after 10 tick */
2454     ux_test_hcd_sim_host_set_actions(wait_disconn_on_transfer_0);
2455     status = ux_host_class_cdc_acm_write(cdc_acm_host_data, cdc_acm_xmit_buffer, 16384, &actual_length);
2456 
2457     stepinfo(">>>>>>>>>>>> All Done\n");
2458 
2459     /* Finally disconnect the device. */
2460     ux_device_stack_disconnect();
2461 
2462     /* And deinitialize the class.  */
2463     status =  ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
2464 
2465     /* Deinitialize the device side of usbx.  */
2466     _ux_device_stack_uninitialize();
2467 
2468     /* And finally the usbx system resources.  */
2469     _ux_system_uninitialize();
2470 
2471     /* Successful test.  */
2472     printf("SUCCESS!\n");
2473     test_control_return(0);
2474 
2475 }
2476 
2477 
test_usbx_simulator_cdc_acm_host_send_command(UCHAR * string,ULONG length,ULONG no_ack)2478 UINT test_usbx_simulator_cdc_acm_host_send_command(UCHAR *string, ULONG length, ULONG no_ack)
2479 {
2480 
2481 UINT        status;
2482 ULONG       actual_length;
2483 
2484     /* Perform a write to the modem to echo values. And wait for the answer. */
2485     ux_utility_memory_copy(cdc_acm_xmit_buffer, string,length);
2486     cdc_acm_xmit_buffer[length] = 0x0d;
2487     cdc_acm_xmit_buffer[length+1] = 0x0a;
2488 
2489     /* Update the length. */
2490     length += 2;
2491 
2492     /* Send the AT command.  */
2493     status = ux_host_class_cdc_acm_write(cdc_acm_host_data, cdc_acm_xmit_buffer, length, &actual_length);
2494 
2495     /* The device may be extracted after we start sending\receiving.  */
2496     if (status != UX_SUCCESS)
2497         return(status);
2498 
2499     /* Wait for the answer. */
2500     if (!no_ack)
2501         while(command_received_count == 0)
2502             tx_thread_sleep(10);
2503 
2504     /* Reset receive count. */
2505     command_received_count = 0;
2506 
2507     /* Return status.  */
2508     return(status);
2509 }
2510 
test_thread_host_reception_callback(UX_HOST_CLASS_CDC_ACM * cdc_acm,UINT status,UCHAR * reception_buffer,ULONG reception_size)2511 void    test_thread_host_reception_callback(UX_HOST_CLASS_CDC_ACM *cdc_acm, UINT status, UCHAR *reception_buffer, ULONG reception_size)
2512 {
2513 
2514     /* Incase target to test overflow case, buffers are not moved. */
2515     if (!cdc_acm_reception_overflow)
2516     {
2517         /* And move to the next reception buffer.  Check if we are at the end of the application buffer.  */
2518         if (cdc_acm_reception.ux_host_class_cdc_acm_reception_data_tail + cdc_acm_reception.ux_host_class_cdc_acm_reception_block_size >=
2519             cdc_acm_reception.ux_host_class_cdc_acm_reception_data_buffer + cdc_acm_reception.ux_host_class_cdc_acm_reception_data_buffer_size)
2520 
2521             /* We are at the end of the buffer. Move back to the beginning.  */
2522             cdc_acm_reception.ux_host_class_cdc_acm_reception_data_tail =  cdc_acm_reception.ux_host_class_cdc_acm_reception_data_buffer;
2523 
2524         else
2525 
2526             /* Program the tail to be after the current buffer.  */
2527             cdc_acm_reception.ux_host_class_cdc_acm_reception_data_tail +=  cdc_acm_reception.ux_host_class_cdc_acm_reception_block_size;
2528     }
2529     if (status == UX_BUFFER_OVERFLOW)
2530         cdc_acm_reception_overflow = UX_FALSE;
2531 
2532     /* Keep the buffer pointer and length received.  */
2533     global_reception_buffer = reception_buffer;
2534     global_reception_size = reception_size;
2535 
2536     /* We have received a response.  */
2537     command_received_count++;
2538 
2539     return;
2540 }
2541 
ux_test_host_class_cdc_acm_device_status_change_callback(struct UX_HOST_CLASS_CDC_ACM_STRUCT * cdc_acm,ULONG notification_type,ULONG notification_value)2542 static VOID ux_test_host_class_cdc_acm_device_status_change_callback(
2543     struct UX_HOST_CLASS_CDC_ACM_STRUCT *cdc_acm,
2544     ULONG  notification_type,
2545     ULONG notification_value)
2546 {
2547 
2548     /* We received a notification */
2549     notification_count ++;
2550 }
2551 
2552 
tx_test_thread_slave_simulation_entry(ULONG arg)2553 void  tx_test_thread_slave_simulation_entry(ULONG arg)
2554 {
2555 
2556 UINT                                                status;
2557 ULONG                                               requested_length;
2558 ULONG                                               actual_length;
2559 UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_PARAMETER        line_coding;
2560 UX_SLAVE_CLASS_CDC_ACM_LINE_STATE_PARAMETER         line_state;
2561 UX_SLAVE_CLASS_COMMAND                              class_command;
2562 
2563 UCHAR                                               data_bit[16];
2564 
2565 ULONG read_size = 64;
2566 ULONG write_size;
2567 
2568     /* The stack/class code always invoke ux_device_class_cdc_acm_entry correct.
2569        Do a command request error test here. */
2570     class_command.ux_slave_class_command_request = 0xFF;
2571     status = ux_device_class_cdc_acm_entry(&class_command);
2572     /* Error should be reported */
2573     if (status == UX_SUCCESS)
2574     {
2575 
2576         /* CDC ACM basic test error.  */
2577         printf("ERROR #30\n");
2578         test_control_return(1);
2579     }
2580 
2581     /* On CDC ACM driver initialize, there is memory allocation for:
2582        - instance of the device cdc_acm class
2583        - mute for each of endpoint (EP IN and EP OUT)
2584          mute creation never fails so there is no tests.
2585      */
2586     /* Use out memories */
2587     ux_test_utility_sim_mem_allocate_until(sizeof(UX_SLAVE_CLASS_CDC_ACM));
2588 
2589     /* Try initialize CDC ACM instance */
2590     class_command.ux_slave_class_command_request = UX_SLAVE_CLASS_COMMAND_INITIALIZE;
2591     status = ux_device_class_cdc_acm_entry(&class_command);
2592     /* Error should be reported */
2593     if (status == UX_SUCCESS)
2594     {
2595 
2596         /* CDC ACM basic test error.  */
2597         printf("ERROR #32\n");
2598         test_control_return(1);
2599     }
2600 
2601     /* Free memory after test */
2602     ux_test_utility_sim_mem_free_all();
2603 
2604     while(1)
2605     {
2606 
2607         /* Ensure the CDC class is mounted.  */
2608         while(cdc_acm_slave != UX_NULL && cdc_acm_slave_bulk_read_write == UX_TRUE)
2609         {
2610 
2611             /* Read from the CDC class.  */
2612             status = ux_device_class_cdc_acm_read(cdc_acm_slave, buffer, read_size, &actual_length);
2613 
2614             if (status != UX_SUCCESS)
2615             {
2616 
2617                 break;
2618             }
2619 
2620             /* Change read size for different read cases */
2621             if (read_size <= 64)
2622                 read_size = UX_SLAVE_REQUEST_DATA_MAX_LENGTH;
2623 
2624             /* The actual length becomes the requested length.  */
2625             requested_length = actual_length;
2626 
2627             /* Check for AT command. */
2628             if (*buffer == 'A' && *(buffer + 1) == 'T')
2629             {
2630 
2631                 /* This is a AT command.  Decode next byte. */
2632                 switch (*(buffer + 2))
2633                 {
2634                     case 'K' : /* Break! */
2635 
2636                         tx_thread_sleep(10);
2637                         ux_test_hcd_sim_host_disconnect();
2638                         break;
2639 
2640                     case 'O' :
2641 
2642                         /* Start writing. */
2643                         switch(*(buffer + 3))
2644                         {
2645                             case '0': /* ZLP */
2646                                 write_size = 0;
2647                                 break;
2648                             case '1': /* Short packet of 2 */
2649                                 write_size = 2;
2650                                 break;
2651                             case '2': /* Full packet of 64 */
2652                                 write_size = 64;
2653                                 break;
2654                             case '3': /* Full packet of 512 */
2655                                 write_size = 512;
2656                                 break;
2657                             case '4': /* Full packet of 4096 */
2658                                 write_size = 4096;
2659                                 break;
2660                             case '5': /* Full packet of 8128 */
2661                                 write_size = 8128;
2662                                 break;
2663                             case 'P': /* Full packet of 64 */
2664                                 write_size = 64;
2665                                 read_size = 64; /* Next read is 64 */
2666                                 break;
2667                             default:
2668                                 write_size = UX_DEMO_BUFFER_SIZE * 4;
2669                                 break;
2670                         }
2671 
2672                         status = ux_device_class_cdc_acm_write(cdc_acm_slave, buffer, write_size, &actual_length);
2673                         if (status == UX_TRANSFER_BUS_RESET)
2674                             status = ux_device_class_cdc_acm_write(cdc_acm_slave, buffer, write_size, &actual_length);
2675 
2676                         break;
2677 
2678                     case 'W' :
2679 
2680                         /* Start writing. */
2681                         status = ux_device_class_cdc_acm_write(cdc_acm_slave, buffer, UX_DEMO_BUFFER_SIZE, &actual_length);
2682                         if (status == UX_SUCCESS)
2683                         {
2684 
2685                             /* CDC ACM basic test error.  */
2686                             printf("ERROR #50\n");
2687                             test_control_return(1);
2688                         }
2689 
2690                         break;
2691 
2692                     case 'A' :
2693 
2694                         /* This is to try abort XMIT. Pending or next XMIT aborted. */
2695                         status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave, UX_SLAVE_CLASS_CDC_ACM_IOCTL_ABORT_PIPE, (VOID*)UX_SLAVE_CLASS_CDC_ACM_ENDPOINT_XMIT);
2696                         /* Error should not be reported */
2697                         if (status != UX_SUCCESS)
2698                         {
2699 
2700                             /* CDC ACM basic test error.  */
2701                             printf("ERROR #35\n");
2702                             test_control_return(1);
2703                         }
2704 
2705                         /* This is to try abort RCV. */
2706                         status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave, UX_SLAVE_CLASS_CDC_ACM_IOCTL_ABORT_PIPE, (VOID*)UX_SLAVE_CLASS_CDC_ACM_ENDPOINT_RCV);
2707                         /* Error should not be reported */
2708                         if (status != UX_SUCCESS)
2709                         {
2710 
2711                             /* CDC ACM basic test error.  */
2712                             printf("ERROR #39\n");
2713                             test_control_return(1);
2714                         }
2715 
2716                         /* This is to try abort unknown. */
2717                         status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave, UX_SLAVE_CLASS_CDC_ACM_IOCTL_ABORT_PIPE, (VOID*)0xFF);
2718                         /* Error should be reported */
2719                         if (status == UX_SUCCESS)
2720                         {
2721 
2722                             /* CDC ACM basic test error.  */
2723                             printf("ERROR #47\n");
2724                             test_control_return(1);
2725                         }
2726 
2727                         status = tx_test_thread_slave_simulation_response(_rsp_ok, UX_DEMO_BUFFER_SIZE - 2);
2728                         if (status != UX_SUCCESS)
2729                         {
2730                             /* Try again if it's aborted */
2731                             status = tx_test_thread_slave_simulation_response(_rsp_ok, UX_DEMO_BUFFER_SIZE - 2);
2732                         }
2733                         if (status != UX_SUCCESS)
2734                         {
2735 
2736                             /* CDC ACM basic test error.  */
2737                             printf("ERROR #44: response sent error %x\n", status);
2738                             test_control_return(1);
2739                         }
2740 
2741                         break;
2742 
2743                     case 'F' :
2744 
2745                         /* This is to try invalid IOCTRL code */
2746                         status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave, 0xFF, 0);
2747 
2748                         /* Error should be reported */
2749                         if (status == UX_SUCCESS)
2750                         {
2751 
2752                             /* CDC ACM basic test error.  */
2753                             printf("ERROR #34\n");
2754                             test_control_return(1);
2755                         }
2756                         /* Send response any case */
2757                         status = tx_test_thread_slave_simulation_response("OK", 2);
2758                         if (status == UX_TRANSFER_BUS_RESET)
2759                             status = tx_test_thread_slave_simulation_response("OK", 2);
2760                         /* Send ZLP */
2761                         ux_device_class_cdc_acm_write(cdc_acm_slave, buffer, 0, &actual_length);
2762                         break;
2763 
2764                     case 'L' :
2765 
2766                         /* This is to set line coding. */
2767                         line_coding.ux_slave_class_cdc_acm_parameter_baudrate = buffer[3] + (buffer[4] << 8) + (buffer[5] << 16) + (buffer[6] << 24);
2768                         line_coding.ux_slave_class_cdc_acm_parameter_stop_bit = *(buffer + 7);
2769                         line_coding.ux_slave_class_cdc_acm_parameter_parity = *(buffer + 8);
2770                         line_coding.ux_slave_class_cdc_acm_parameter_data_bit = *(buffer + 9);
2771                         status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave, UX_SLAVE_CLASS_CDC_ACM_IOCTL_SET_LINE_CODING, &line_coding);
2772 
2773                         if (status != UX_SUCCESS)
2774                         {
2775 
2776                             /* CDC ACM basic test error.  */
2777                             printf("ERROR #38\n");
2778                             test_control_return(1);
2779                         }
2780                         /* Send response any case */
2781                         status = tx_test_thread_slave_simulation_response("OK", 2);
2782                         break;
2783 
2784                     case 'B' :
2785 
2786                         /* This is to retrieve BAUD rate.  */
2787                         status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave, UX_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_CODING, &line_coding);
2788 
2789                         /* Any error ? */
2790                         if (status == UX_SUCCESS)
2791                         {
2792                             /* Decode BAUD rate. */
2793                             switch (line_coding.ux_slave_class_cdc_acm_parameter_baudrate)
2794                             {
2795 
2796                                 case 300 :
2797                                     status = tx_test_thread_slave_simulation_response("300", 3);
2798                                     break;
2799 
2800                                 case 1200 :
2801                                     status = tx_test_thread_slave_simulation_response("1200", 4);
2802                                     break;
2803 
2804                                 case 2400 :
2805                                     status = tx_test_thread_slave_simulation_response("2400", 4);
2806                                     break;
2807 
2808                                 case 4800 :
2809                                     status = tx_test_thread_slave_simulation_response("4800", 4);
2810                                     break;
2811 
2812                                 case 9600 :
2813                                     status = tx_test_thread_slave_simulation_response("9600", 4);
2814                                     break;
2815 
2816                                 case 14400 :
2817                                     status = tx_test_thread_slave_simulation_response("14400", 5);
2818                                     break;
2819 
2820                                 case 19200 :
2821                                     status = tx_test_thread_slave_simulation_response("19200", 5);
2822                                     break;
2823 
2824                                 case 28800 :
2825                                     status = tx_test_thread_slave_simulation_response("28800", 5);
2826                                     break;
2827 
2828                                 case 38400 :
2829                                     status = tx_test_thread_slave_simulation_response("38400", 5);
2830                                     break;
2831 
2832                                 case 57600 :
2833                                     status = tx_test_thread_slave_simulation_response("57600", 5);
2834                                     break;
2835 
2836                                 case 115200 :
2837                                     status = tx_test_thread_slave_simulation_response("115200", 6);
2838                                     break;
2839 
2840                                 case 230400 :
2841                                     status = tx_test_thread_slave_simulation_response("230400", 6);
2842                                     break;
2843                             }
2844 
2845                         }
2846                         break;
2847 
2848 
2849                     case 'S' :
2850 
2851                         /* This is to retrieve stop bit rate.  */
2852                         status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave, UX_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_CODING, &line_coding);
2853 
2854                         /* Any error ? */
2855                         if (status == UX_SUCCESS)
2856                         {
2857 
2858                             /* Decode stop bit. */
2859                             switch (line_coding.ux_slave_class_cdc_acm_parameter_stop_bit)
2860                             {
2861 
2862                                 case 0 :
2863                                     status = tx_test_thread_slave_simulation_response("0 Stop bit", 10);
2864                                     break;
2865 
2866                                 case 1 :
2867                                     status = tx_test_thread_slave_simulation_response("1.5 Stop bit", 12);
2868                                     break;
2869 
2870                                 case 2 :
2871                                     status = tx_test_thread_slave_simulation_response("2 Stop bit", 10);
2872                                     break;
2873                             }
2874                         }
2875                         break;
2876 
2877 
2878                     case 'P' :
2879 
2880                         /* This is to retrieve parity rate.  */
2881                         status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave, UX_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_CODING, &line_coding);
2882 
2883                         /* Any error ? */
2884                         if (status == UX_SUCCESS)
2885                         {
2886 
2887                             /* Decode Parity bit. */
2888                             switch (line_coding.ux_slave_class_cdc_acm_parameter_parity)
2889                             {
2890 
2891                                 case 0 :
2892                                     status = tx_test_thread_slave_simulation_response("Parity none", 11);
2893                                     break;
2894 
2895                                 case 1 :
2896                                     status = tx_test_thread_slave_simulation_response("Parity odd", 10);
2897                                     break;
2898 
2899                                 case 2 :
2900                                     status = tx_test_thread_slave_simulation_response("Parity even", 11);
2901                                     break;
2902 
2903                                 case 3 :
2904                                     status = tx_test_thread_slave_simulation_response("Parity mark", 11);
2905                                     break;
2906 
2907                                 case 4 :
2908                                     status = tx_test_thread_slave_simulation_response("Parity space", 12);
2909                                     break;
2910 
2911 
2912                             }
2913                         }
2914                         break;
2915 
2916                     case 'D' :
2917 
2918                         /* This is to retrieve Data Bit.  */
2919                         status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave, UX_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_CODING, &line_coding);
2920 
2921                         /* Any error ? */
2922                         if (status == UX_SUCCESS)
2923                         {
2924                             /* Copy generic string.  */
2925                             ux_utility_memory_copy(data_bit, "Data Bit x",10);
2926 
2927                             /* Put data bit value.  */
2928                             data_bit[9] = line_coding.ux_slave_class_cdc_acm_parameter_data_bit + '0';
2929 
2930                             /* Send data.  */
2931                             status = tx_test_thread_slave_simulation_response(data_bit, 10);
2932                         }
2933                         break;
2934 
2935                     case 'R' :
2936 
2937                         /* This is to retrieve RTS state.  */
2938                         status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave, UX_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_STATE, &line_state);
2939 
2940                         /* Any error ? */
2941                         if (status == UX_SUCCESS)
2942                         {
2943                             /* Check state.  */
2944                             if (line_state.ux_slave_class_cdc_acm_parameter_rts == UX_TRUE)
2945 
2946                                 /* State is ON.  */
2947                                 status = tx_test_thread_slave_simulation_response("RTS ON", 6);
2948 
2949                             else
2950 
2951                                 /* State is OFF.  */
2952                                 status = tx_test_thread_slave_simulation_response("RTS OFF", 7);
2953 
2954                         }
2955                         break;
2956 
2957                     case 'T' :
2958 
2959                         /* This is to retrieve DTR state.  */
2960                         status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave, UX_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_STATE, &line_state);
2961 
2962                         /* Any error ? */
2963                         if (status == UX_SUCCESS)
2964                         {
2965                             /* Check state.  */
2966                             if (line_state.ux_slave_class_cdc_acm_parameter_dtr == UX_TRUE)
2967 
2968                                 /* State is ON.  */
2969                                 status = tx_test_thread_slave_simulation_response("DTR ON", 6);
2970 
2971                             else
2972 
2973                                 /* State is OFF.  */
2974                                 status = tx_test_thread_slave_simulation_response("DTR OFF", 7);
2975 
2976                         }
2977                         break;
2978                 }
2979             }
2980             else
2981             {
2982 
2983                 /* Not an AT command, just echo back.  */
2984                 /* Check the status.  If OK, we will write to the CDC instance.  */
2985                 status = ux_device_class_cdc_acm_write(cdc_acm_slave, buffer, requested_length, &actual_length);
2986 
2987                 /* Check for CR/LF.  */
2988                 if (buffer[requested_length - 1] == '\r')
2989                 {
2990 
2991                     /* Copy LF value into user buffer.  */
2992                     ux_utility_memory_copy(buffer, "\n",  1);
2993 
2994                     /* And send it again.  */
2995                     status = ux_device_class_cdc_acm_write(cdc_acm_slave, buffer, 1, &actual_length);
2996 
2997                 }
2998             }
2999         }
3000 
3001         /* Sleep so ThreadX on Win32 will delete this thread. */
3002         tx_thread_sleep(10);
3003     }
3004 }
3005 
tx_test_thread_slave_simulation_response(UCHAR * string,ULONG length)3006 UINT  tx_test_thread_slave_simulation_response(UCHAR *string, ULONG length)
3007 {
3008 
3009 UINT        status;
3010 ULONG       actual_length;
3011 
3012     /* Perform a write to the modem to echo values. And wait for the answer. */
3013     ux_utility_memory_copy(buffer, string,length);
3014     buffer[length] = 0x0d;
3015     buffer[length+1] = 0x0a;
3016 
3017     /* Update the length. */
3018     length += 2;
3019 
3020     /* Check the status.  If OK, we will write to the CDC instance.  */
3021     status = ux_device_class_cdc_acm_write(cdc_acm_slave, buffer, length, &actual_length);
3022 
3023     /* Return status. */
3024     return(status);
3025 }
3026 
ux_test_host_class_cdc_acm_command(UX_HOST_CLASS_CDC_ACM * cdc_acm,ULONG command,ULONG value,UCHAR * data_buffer,ULONG data_length,ULONG * actual_length)3027 static UINT ux_test_host_class_cdc_acm_command(UX_HOST_CLASS_CDC_ACM *cdc_acm, ULONG command,
3028                                                ULONG value, UCHAR *data_buffer, ULONG data_length,
3029                                                ULONG *actual_length)
3030 {
3031 
3032 UX_ENDPOINT     *control_endpoint;
3033 UX_TRANSFER     *transfer_request;
3034 UINT            status;
3035 ULONG           request_direction;
3036 
3037     /* We need to get the default control endpoint transfer request pointer.  */
3038     control_endpoint =  &cdc_acm -> ux_host_class_cdc_acm_device -> ux_device_control_endpoint;
3039     transfer_request =  &control_endpoint -> ux_endpoint_transfer_request;
3040     switch(command)
3041     {
3042         case UX_HOST_CLASS_CDC_ACM_REQ_GET_ENCAPSULATED_COMMAND:
3043         case UX_HOST_CLASS_CDC_ACM_REQ_GET_COMM_FEATURE:
3044         case UX_HOST_CLASS_CDC_ACM_REQ_GET_LINE_CODING:
3045         case UX_HOST_CLASS_CDC_ACM_REQ_GET_RINGER_PARMS:
3046         case UX_HOST_CLASS_CDC_ACM_REQ_GET_OPERATION_PARMS:
3047         case UX_HOST_CLASS_CDC_ACM_REQ_GET_LINE_PARMS:
3048 
3049             request_direction = UX_REQUEST_IN;
3050             break;
3051 
3052         default:
3053 
3054             request_direction = UX_REQUEST_OUT;
3055     }
3056 
3057     /* Protect the control endpoint semaphore here.  It will be unprotected in the
3058        transfer request function.  */
3059     status =  _ux_utility_semaphore_get(&cdc_acm -> ux_host_class_cdc_acm_device -> ux_device_protection_semaphore, UX_WAIT_FOREVER);
3060 
3061     /* Check for status.  */
3062     if (status != UX_SUCCESS)
3063 
3064         /* Something went wrong. */
3065         return(status);
3066 
3067     /* Create a transfer_request for the request.  */
3068     transfer_request -> ux_transfer_request_data_pointer     =  data_buffer;
3069     transfer_request -> ux_transfer_request_requested_length =  data_length;
3070     transfer_request -> ux_transfer_request_function         =  command;
3071     transfer_request -> ux_transfer_request_type             =  request_direction | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
3072     transfer_request -> ux_transfer_request_value            =  value;
3073     transfer_request -> ux_transfer_request_index            =  cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceNumber;
3074 
3075     /* Send request to HCD layer.  */
3076     status =  ux_host_stack_transfer_request(transfer_request);
3077 
3078     /* Fill actual length */
3079     if (actual_length) {
3080         *actual_length = transfer_request -> ux_transfer_request_actual_length;
3081     }
3082 
3083     /* Return completion status.  */
3084     return(status);
3085 }
3086 
3087