1 /* This test is designed to test the simple dpump host/device class operation.  */
2 
3 #include <stdio.h>
4 #include "tx_api.h"
5 #include "ux_api.h"
6 #include "ux_system.h"
7 #include "ux_utility.h"
8 
9 #include "fx_api.h"
10 
11 #include "ux_device_stack.h"
12 #include "ux_device_class_dummy.h"
13 
14 #include "ux_host_stack.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 constants.  */
21 #define                             UX_DEMO_DEBUG_SIZE  (4096*8)
22 #define                             UX_DEMO_STACK_SIZE  1024
23 #define                             UX_DEMO_BUFFER_SIZE (UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1)
24 #define                             UX_DEMO_XMIT_BUFFER_SIZE 512
25 #define                             UX_DEMO_RECEPTION_BUFFER_SIZE 512
26 #define                             UX_DEMO_FILE_BUFFER_SIZE 512
27 #define                             UX_DEMO_RECEPTION_BLOCK_SIZE 64
28 #define                             UX_DEMO_MEMORY_SIZE     (96*1024)
29 #define                             UX_DEMO_FILE_SIZE       (128 * 1024)
30 #define                             UX_RAM_DISK_MEMORY      (256 * 1024)
31 
32 #define                             UX_DEMO_VENDOR_REQUEST 0x54
33 
34 /* Define local/extern function prototypes.  */
35 static VOID                                test_thread_entry(ULONG);
36 static TX_THREAD                           tx_test_thread_simulation0;
37 static TX_THREAD                           tx_test_thread_simulation1;
38 static VOID                                tx_test_thread_simulation0_entry(ULONG);
39 static VOID                                tx_test_thread_simulation1_entry(ULONG);
40 
41 static UINT                                test_ms_vendor_request(ULONG request, ULONG request_value, ULONG request_index, ULONG request_length,
42                                                                   UCHAR *transfer_request_buffer, ULONG *transfer_request_length);
43 
44 
45 /* Define global data structures.  */
46 static UCHAR                               usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
47 
48 static UX_DEVICE_CLASS_DUMMY_PARAMETER     *parameter;
49 
50 static UX_DEVICE                           *host_device = UX_NULL;
51 
52 static UCHAR                               buffer[UX_DEMO_BUFFER_SIZE];
53 
54 static ULONG                               error_counter;
55 
56 static ULONG                               set_cfg_counter;
57 
58 static ULONG                               rsc_mem_alloc_cnt_on_set_cfg;
59 static ULONG                               rsc_sem_on_set_cfg;
60 static ULONG                               rsc_sem_get_on_set_cfg;
61 static ULONG                               rsc_mutex_on_set_cfg;
62 
63 static ULONG                               rsc_enum_mem_alloc_count;
64 static ULONG                               rsc_enum_sem_usage;
65 static ULONG                               rsc_enum_sem_get_count;
66 static ULONG                               rsc_enum_mutex_usage;
67 
68 static UINT                                class_entry_rc = UX_SUCCESS;
69 
70 static UINT                                vendor_req_rc = UX_SUCCESS;
71 static UINT                                vendor_req_ret_len = 0;
72 static ULONG                               vendor_req_req_len;
73 static ULONG                               vendor_req_buf_len;
74 
75 #define     LSB(x) ((x) & 0x00ff)
76 #define     MSB(x) (((x) & 0xff00) >> 8)
77 
78 /* Storage related descriptors 9+7+7=23 bytes */
79 #define MS_IFC_DESC_ALL(ifc, bulk_in_epa, bulk_out_epa) \
80     /* Interface descriptor */\
81         0x09, 0x04, (ifc), 0x00, 0x03, 0x08, 0x06, 0x50, 0x00,\
82     /* Endpoint descriptor (Bulk In) */\
83         0x07, 0x05, (bulk_in_epa), 0x02, 0x40, 0x00, 0x00,\
84     /* Endpoint descriptor (Bulk Out) */\
85         0x07, 0x05, (bulk_out_epa), 0x02, 0x40, 0x00, 0x00,
86 #define MS_IFC_DESC_ALL_LEN 23
87 
88 /* CDC IAD 8 bytes */
89 #define CDC_IAD_DESC(comm_ifc) \
90     /* Interface association descriptor. 8 bytes.  */\
91     0x08, 0x0b, (comm_ifc), 0x02, 0x02, 0x02, 0x00, 0x00,
92 #define CDC_IAD_DESC_LEN 8
93 
94 /* CDC Communication interface descriptors 9+5+4+5+5+7=35 bytes */
95 #define CDC_COMM_IFC_DESC_ALL(comm_ifc, data_ifc, interrupt_epa) \
96     /* Communication Class Interface Descriptor. 9 bytes. */\
97     0x09, 0x04, (comm_ifc), 0x00, 0x01, 0x02, 0x02, 0x01, 0x00,\
98     /* Header Functional Descriptor 5 bytes */\
99     0x05, 0x24, 0x00, 0x10, 0x01,\
100     /* ACM Functional Descriptor 4 bytes */\
101     0x04, 0x24, 0x02, 0x0f,\
102     /* Union Functional Descriptor 5 bytes */\
103     0x05, 0x24, 0x06,\
104     (comm_ifc),                          /* Master interface */\
105     (data_ifc),                          /* Slave interface  */\
106     /* Call Management Functional Descriptor 5 bytes */\
107     0x05, 0x24, 0x01, 0x03,\
108     (data_ifc),                          /* Data interface   */\
109     /* Endpoint 0x83 descriptor 7 bytes */\
110     0x07, 0x05, (interrupt_epa),\
111     0x03,\
112     0x08, 0x00,\
113     0xFF,
114 #define CDC_COMM_IFC_DESC_ALL_LEN 35
115 
116 /* CDC Data interface descriptors 9+7+7=23 bytes */
117 #define CDC_DATA_IFC_DESC_ALL(ifc, bulk_in_epa, bulk_out_epa) \
118     /* Data Class Interface Descriptor Requirement 9 bytes */\
119     0x09, 0x04, (ifc),\
120     0x00, /* bAlternateSetting */\
121     0x02, /* bNumEndpoints */\
122     0x0A, 0x00, 0x00,\
123     0x00,\
124     /* Endpoint bulk IN descriptor 7 bytes */\
125     0x07, 0x05, (bulk_in_epa),\
126     0x02,\
127     0x40, 0x00,\
128     0x00,\
129     /* Endpoint bulk OUT descriptor 7 bytes */\
130     0x07, 0x05, (bulk_out_epa),\
131     0x02,\
132     0x40, 0x00,\
133     0x00,
134 #define CDC_DATA_IFC_DESC_ALL_LEN 23
135 
136 /* Configuration descriptor 9 bytes */
137 #define CFG_DESC(wTotalLength, bNumInterfaces, bConfigurationValue)\
138     /* Configuration 1 descriptor 9 bytes */\
139     0x09, 0x02, LSB(wTotalLength), MSB(wTotalLength),\
140     (bNumInterfaces), (bConfigurationValue), 0x00,\
141     0x40, 0x00,
142 #define CFG_DESC_LEN 9
143 
144 /* Define device framework.  */
145 
146 static unsigned char device_framework_full_speed[] = {
147 
148     /* Device descriptor     18 bytes
149        0x02 bDeviceClass:    CDC class code
150        0x00 bDeviceSubclass: CDC class sub code
151        0x00 bDeviceProtocol: CDC Device protocol
152 
153        idVendor & idProduct - http://www.linux-usb.org/usb.ids
154     */
155     0x12, 0x01, 0x10, 0x01,
156     0xEF, 0x02, 0x01,
157     0x08,
158     0x84, 0x84, 0x00, 0x00,
159     0x00, 0x01,
160     0x01, 0x02, 03,
161     0x01, /* bNumConfigurations */
162 
163     /* Configuration 1 descriptor 9 bytes */
164     0x09, 0x02, 0x4b, 0x00,
165     0x02, 0x01, 0x00,
166     0xE0, 0x00,
167 
168     /* Interface association descriptor. 8 bytes.  */
169     0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
170 
171     /* Communication Class Interface Descriptor. 9 bytes.   */
172     0x09, 0x04, 0x00,
173     0x00,
174     0x01,
175     0x02, 0x02, 0x01,
176     0x00,
177 
178     /* Header Functional Descriptor 5 bytes */
179     0x05, 0x24, 0x00,
180     0x10, 0x01,
181 
182     /* ACM Functional Descriptor 4 bytes */
183     0x04, 0x24, 0x02,
184     0x0f,
185 
186     /* Union Functional Descriptor 5 bytes */
187     0x05, 0x24, 0x06,
188     0x00,                          /* Master interface */
189     0x01,                          /* Slave interface  */
190 
191     /* Call Management Functional Descriptor 5 bytes */
192     0x05, 0x24, 0x01,
193     0x03,
194     0x01,                          /* Data interface   */
195 
196     /* Endpoint 0x83 descriptor 7 bytes */
197     0x07, 0x05, 0x83,
198     0x03,
199     0x08, 0x00,
200     0xFF,
201 
202     /* Data Class Interface Descriptor Requirement 9 bytes */
203     0x09, 0x04, 0x01,
204     0x00,
205     0x02,
206     0x0A, 0x00, 0x00,
207     0x00,
208 
209     /* Endpoint 0x81 descriptor 7 bytes */
210     0x07, 0x05, 0x81,
211     0x02,
212     0x40, 0x00,
213     0x00,
214 
215     /* Endpoint 0x02 descriptor 7 bytes */
216     0x07, 0x05, 0x02,
217     0x02,
218     0x40, 0x00,
219     0x00,
220 
221     /* Configuration 2 descriptor 9 bytes */
222     0x09, 0x02, (0x4b + 28 + 46), 0x00,
223     0x02, 0x02, 0x00,
224     0x40, 0x00,
225 
226     /* Interface association descriptor. 8 bytes.  */
227     0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
228 
229     /* Communication Class Interface Descriptor Requirement. 9 bytes.   */
230     0x09, 0x04, 0x00,
231     0x00, /* bAlternateSetting */
232     0x00, /* bNumEndpoints */
233     0x02, 0x02, 0x01,
234     0x00,
235 
236     /* Header Functional Descriptor 5 bytes */
237     0x05, 0x24, 0x00,
238     0x10, 0x01,
239 
240     /* ACM Functional Descriptor 4 bytes */
241     0x04, 0x24, 0x02,
242     0x0f,
243 
244     /* Union Functional Descriptor 5 bytes */
245     0x05, 0x24, 0x06,
246     0x00,                          /* Master interface */
247     0x01,                          /* Slave interface  */
248 
249     /* Call Management Functional Descriptor 5 bytes */
250     0x05, 0x24, 0x01,
251     0x03,
252     0x01,                          /* Data interface   */
253 
254     /* Communication Class Interface Descriptor Requirement. 9 bytes.   */
255     0x09, 0x04, 0x00,
256     0x01, /* bAlternateSetting */
257     0x01, /* bNumEndpoints */
258     0x02, 0x02, 0x01,
259     0x00,
260 
261     /* Header Functional Descriptor 5 bytes */
262     0x05, 0x24, 0x00,
263     0x10, 0x01,
264 
265     /* ACM Functional Descriptor 4 bytes */
266     0x04, 0x24, 0x02,
267     0x0f,
268 
269     /* Union Functional Descriptor 5 bytes */
270     0x05, 0x24, 0x06,
271     0x00,                          /* Master interface */
272     0x01,                          /* Slave interface  */
273 
274     /* Call Management Functional Descriptor 5 bytes */
275     0x05, 0x24, 0x01,
276     0x03,
277     0x01,                          /* Data interface   */
278 
279     /* Endpoint 0x83 descriptor 7 bytes */
280     0x07, 0x05, 0x83,
281     0x03,
282     0x08, 0x00,
283     0xFF,
284 
285     /* Data Class Interface Descriptor Requirement 9 bytes */
286     0x09, 0x04, 0x01,
287     0x00, /* bAlternateSetting */
288     0x00, /* bNumEndpoints */
289     0x0A, 0x00, 0x00,
290     0x00,
291 
292     /* Data Class Interface Descriptor Requirement 9 bytes */
293     0x09, 0x04, 0x01,
294     0x01, /* bAlternateSetting */
295     0x02, /* bNumEndpoints */
296     0x0A, 0x00, 0x00,
297     0x00,
298 
299     /* Endpoint 0x81 descriptor 7 bytes */
300     0x07, 0x05, 0x81,
301     0x02,
302     0x40, 0x00,
303     0x00,
304 
305     /* Endpoint 0x02 descriptor 7 bytes */
306     0x07, 0x05, 0x02,
307     0x02,
308     0x40, 0x00,
309     0x00,
310 
311     /* Data Class Interface Descriptor Requirement 9 bytes */
312     0x09, 0x04, 0x01,
313     0x02, /* bAlternateSetting */
314     0x04, /* bNumEndpoints */
315     0x0A, 0x00, 0x00,
316     0x00,
317 
318     /* Endpoint 0x81 descriptor 7 bytes */
319     0x07, 0x05, 0x81,
320     0x02,
321     0x40, 0x00,
322     0x00,
323 
324     /* Endpoint 0x02 descriptor 7 bytes */
325     0x07, 0x05, 0x02,
326     0x02,
327     0x40, 0x00,
328     0x00,
329 
330     /* Endpoint 0x85 descriptor 7 bytes */
331     0x07, 0x05, 0x85,
332     0x02,
333     0x40, 0x00,
334     0x00,
335 
336     /* Endpoint 0x04 descriptor 7 bytes */
337     0x07, 0x05, 0x04,
338     0x02,
339     0x40, 0x00,
340     0x00,
341 
342     /* Configuration 3: CDC + CDC */
343     CFG_DESC(CFG_DESC_LEN+2*(CDC_IAD_DESC_LEN+CDC_COMM_IFC_DESC_ALL_LEN+CDC_DATA_IFC_DESC_ALL_LEN), 4, 3)
344     CDC_IAD_DESC(0)
345     CDC_COMM_IFC_DESC_ALL(0, 1, 0x83)
346     CDC_DATA_IFC_DESC_ALL(1, 0x81, 0x02)
347     CDC_IAD_DESC(2)
348     CDC_COMM_IFC_DESC_ALL(2, 3, 0x86)
349     CDC_DATA_IFC_DESC_ALL(3, 0x84, 0x05)
350 };
351 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
352 
353 static unsigned char device_framework_high_speed[] = {
354 
355     /* Device descriptor
356        0x02 bDeviceClass:    CDC class code
357        0x00 bDeviceSubclass: CDC class sub code
358        0x00 bDeviceProtocol: CDC Device protocol
359 
360        idVendor & idProduct - http://www.linux-usb.org/usb.ids
361     */
362     0x12, 0x01, 0x00, 0x02,
363     0xEF, 0x02, 0x01,
364     0x40,
365     0x84, 0x84, 0x00, 0x00,
366     0x00, 0x01,
367     0x01, 0x02, 03,
368     0x01, /* bNumConfigurations */
369 
370     /* Device qualifier descriptor */
371     0x0a, 0x06, 0x00, 0x02,
372     0x02, 0x00, 0x00,
373     0x40,
374     0x01,
375     0x00,
376 
377     /* Configuration 1 descriptor */
378     0x09, 0x02, (0x4b+5), 0x00,
379     0x02, 0x01, 0x00,
380     0xE0, 0x00,
381 
382     /* OTG Descriptor.  */
383     0x05, 0x09, 0x03, 0x02, 0x00,
384 
385     /* Interface association descriptor. */
386     0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
387 
388     /* Communication Class Interface Descriptor Requirement */
389     0x09, 0x04, 0x00,
390     0x00,
391     0x01,
392     0x02, 0x02, 0x01,
393     0x00,
394 
395     /* Header Functional Descriptor */
396     0x05, 0x24, 0x00,
397     0x10, 0x01,
398 
399     /* ACM Functional Descriptor */
400     0x04, 0x24, 0x02,
401     0x0f,
402 
403     /* Union Functional Descriptor */
404     0x05, 0x24, 0x06,
405     0x00,
406     0x01,
407 
408     /* Call Management Functional Descriptor */
409     0x05, 0x24, 0x01,
410     0x00,
411     0x01,
412 
413     /* Endpoint 0x83 descriptor */
414     0x07, 0x05, 0x83,
415     0x03,
416     0x08, 0x00,
417     0xFF,
418 
419     /* Data Class Interface Descriptor Requirement */
420     0x09, 0x04, 0x01,
421     0x00,
422     0x02,
423     0x0A, 0x00, 0x00,
424     0x00,
425 
426     /* Endpoint 0x81 descriptor */
427     0x07, 0x05, 0x81,
428     0x02,
429     0x40, 0x00,
430     0x00,
431 
432     /* Endpoint 0x02 descriptor */
433     0x07, 0x05, 0x02,
434     0x02,
435     0x40, 0x00,
436     0x00,
437 
438     /* Configuration 2 descriptor 9 bytes */
439     0x09, 0x02, (0x4b + 28 + 46), 0x00,
440     0x02, 0x02, 0x00,
441     0x40, 0x00,
442 
443     /* Interface association descriptor. 8 bytes.  */
444     0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
445 
446     /* Communication Class Interface Descriptor Requirement. 9 bytes.   */
447     0x09, 0x04, 0x00,
448     0x00, /* bAlternateSetting */
449     0x00, /* bNumEndpoints */
450     0x02, 0x02, 0x01,
451     0x00,
452 
453     /* Header Functional Descriptor 5 bytes */
454     0x05, 0x24, 0x00,
455     0x10, 0x01,
456 
457     /* ACM Functional Descriptor 4 bytes */
458     0x04, 0x24, 0x02,
459     0x0f,
460 
461     /* Union Functional Descriptor 5 bytes */
462     0x05, 0x24, 0x06,
463     0x00,                          /* Master interface */
464     0x01,                          /* Slave interface  */
465 
466     /* Call Management Functional Descriptor 5 bytes */
467     0x05, 0x24, 0x01,
468     0x03,
469     0x01,                          /* Data interface   */
470 
471     /* Communication Class Interface Descriptor Requirement. 9 bytes.   */
472     0x09, 0x04, 0x00,
473     0x01, /* bAlternateSetting */
474     0x01, /* bNumEndpoints */
475     0x02, 0x02, 0x01,
476     0x00,
477 
478     /* Header Functional Descriptor 5 bytes */
479     0x05, 0x24, 0x00,
480     0x10, 0x01,
481 
482     /* ACM Functional Descriptor 4 bytes */
483     0x04, 0x24, 0x02,
484     0x0f,
485 
486     /* Union Functional Descriptor 5 bytes */
487     0x05, 0x24, 0x06,
488     0x00,                          /* Master interface */
489     0x01,                          /* Slave interface  */
490 
491     /* Call Management Functional Descriptor 5 bytes */
492     0x05, 0x24, 0x01,
493     0x03,
494     0x01,                          /* Data interface   */
495 
496     /* Endpoint 0x83 descriptor 7 bytes */
497     0x07, 0x05, 0x83,
498     0x03,
499     0x08, 0x00,
500     0xFF,
501 
502     /* Data Class Interface Descriptor Requirement 9 bytes */
503     0x09, 0x04, 0x01,
504     0x00,
505     0x00,
506     0x0A, 0x00, 0x00,
507     0x00,
508 
509     /* Data Class Interface Descriptor Requirement 9 bytes */
510     0x09, 0x04, 0x01,
511     0x01,
512     0x02,
513     0x0A, 0x00, 0x00,
514     0x00,
515 
516     /* Endpoint 0x81 descriptor 7 bytes */
517     0x07, 0x05, 0x81,
518     0x02,
519     0x40, 0x00,
520     0x00,
521 
522     /* Endpoint 0x02 descriptor 7 bytes */
523     0x07, 0x05, 0x02,
524     0x02,
525     0x40, 0x00,
526     0x00,
527 
528     /* Data Class Interface Descriptor Requirement 9 bytes */
529     0x09, 0x04, 0x01,
530     0x02, /* bAlternateSetting */
531     0x04, /* bNumEndpoints */
532     0x0A, 0x00, 0x00,
533     0x00,
534 
535     /* Endpoint 0x81 descriptor 7 bytes */
536     0x07, 0x05, 0x81,
537     0x02,
538     0x40, 0x00,
539     0x00,
540 
541     /* Endpoint 0x02 descriptor 7 bytes */
542     0x07, 0x05, 0x02,
543     0x02,
544     0x40, 0x00,
545     0x00,
546 
547     /* Endpoint 0x85 descriptor 7 bytes */
548     0x07, 0x05, 0x85,
549     0x02,
550     0x40, 0x00,
551     0x00,
552 
553     /* Endpoint 0x04 descriptor 7 bytes */
554     0x07, 0x05, 0x04,
555     0x02,
556     0x40, 0x00,
557     0x00,
558 
559     /* Configuration 3: CDC + CDC */
560     CFG_DESC(CFG_DESC_LEN+2*(CDC_IAD_DESC_LEN+CDC_COMM_IFC_DESC_ALL_LEN+CDC_DATA_IFC_DESC_ALL_LEN), 4, 3)
561     CDC_IAD_DESC(0)
562     CDC_COMM_IFC_DESC_ALL(0, 1, 0x83)
563     CDC_DATA_IFC_DESC_ALL(1, 0x81, 0x02)
564     CDC_IAD_DESC(2)
565     CDC_COMM_IFC_DESC_ALL(2, 3, 0x86)
566     CDC_DATA_IFC_DESC_ALL(3, 0x84, 0x05)
567 };
568 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
569 
570 
571 static unsigned char string_framework[] = {
572 
573     /* Manufacturer string descriptor : Index 1 - "Express Logic" */
574         0x09, 0x04, 0x01, 0x0c,
575         0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x20, 0x4c,
576         0x6f, 0x67, 0x69, 0x63,
577 
578     /* Product string descriptor : Index 2 - "EL Composite device" */
579         0x09, 0x04, 0x02, 0x13,
580         0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
581         0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
582         0x69, 0x63, 0x65,
583 
584     /* Serial Number string descriptor : Index 3 - "0001" */
585         0x09, 0x04, 0x03, 0x04,
586         0x30, 0x30, 0x30, 0x31,
587 
588     /* Microsoft OS string descriptor : Index 0xEE. String is MSFT100.
589        The last byte is the vendor code used to filter Vendor specific commands.
590        The vendor commands will be executed in the class.
591        This code can be anything but must not be 0x66 or 0x67 which are PIMA class commands.  */
592         0x00, 0x00, 0xEE, 0x08,
593         0x4D, 0x53, 0x46, 0x54,
594         0x31, 0x30, 0x30,
595         UX_DEMO_VENDOR_REQUEST
596 };
597 #define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
598 
599 /* Multiple languages are supported on the device, to add
600     a language besides english, the unicode language code must
601     be appended to the language_id_framework array and the length
602     adjusted accordingly. */
603 static unsigned char language_id_framework[] = {
604 
605     /* English. */
606         0x09, 0x04
607 };
608 #define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
609 
610 
611 /* Define the ISR dispatch.  */
612 
613 extern VOID    (*test_isr_dispatch)(void);
614 
615 
616 /* Prototype for test control return.  */
617 
618 void  test_control_return(UINT status);
619 
620 
621 /* Define the ISR dispatch routine.  */
622 
test_isr(void)623 static void test_isr(void)
624 {
625 
626     /* For further expansion of interrupt-level testing.  */
627 }
628 
test_ms_vendor_request(ULONG request,ULONG request_value,ULONG request_index,ULONG request_length,UCHAR * transfer_request_buffer,ULONG * transfer_request_length)629 static UINT test_ms_vendor_request(ULONG request, ULONG request_value, ULONG request_index, ULONG request_length,
630                                    UCHAR *transfer_request_buffer, ULONG *transfer_request_length)
631 {
632     vendor_req_req_len = request_length;
633     vendor_req_buf_len = *transfer_request_length;
634     *transfer_request_length = vendor_req_ret_len;
635     return vendor_req_rc;
636 }
637 
test_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)638 static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
639 {
640 
641     switch(event)
642     {
643 
644         case UX_DEVICE_INSERTION:
645             break;
646 
647         case UX_DEVICE_REMOVAL:
648             break;
649 
650         case UX_DEVICE_CONNECTION:
651             host_device = (UX_DEVICE *)inst;
652             break;
653         case UX_DEVICE_DISCONNECTION:
654             if (host_device == (UX_DEVICE *)inst)
655                 host_device = UX_NULL;
656             break;
657 
658         default:
659             break;
660     }
661     return 0;
662 }
663 
test_ux_error_callback(UINT system_level,UINT system_context,UINT error_code)664 static VOID test_ux_error_callback(UINT system_level, UINT system_context, UINT error_code)
665 {
666     if (error_code == UX_DEVICE_ENUMERATION_FAILURE ||
667         error_code == UX_TRANSFER_STALLED)
668     {
669         /* It's normal.  */
670         return;
671     }
672     printf("error 0x%x, 0x%x, 0x%x\n", system_level, system_context, error_code);
673     test_control_return(1);
674 }
675 
676 /* Define what the initial system looks like.  */
677 
678 #ifdef CTEST
test_application_define(void * first_unused_memory)679 void test_application_define(void *first_unused_memory)
680 #else
681 void    usbx_msrc_66679_test_application_define(void *first_unused_memory)
682 #endif
683 {
684 
685 UINT                    status;
686 CHAR *                  stack_pointer;
687 CHAR *                  memory_pointer;
688 
689     printf("Running MSRC 66679 Test............................................. ");
690 
691     /* Reset testing counts. */
692     ux_test_utility_sim_mem_alloc_count_reset();
693     ux_test_utility_sim_mutex_create_count_reset();
694     ux_test_utility_sim_sem_create_count_reset();
695     ux_test_utility_sim_sem_get_count_reset();
696     /* Reset error generations */
697     ux_test_utility_sim_mem_alloc_error_generation_stop();
698     ux_test_utility_sim_sem_error_generation_stop();
699     ux_test_utility_sim_mutex_error_generation_stop();
700     ux_test_utility_sim_sem_get_error_generation_stop();
701 
702     /* Initialize the free memory pointer */
703     stack_pointer = (CHAR *) usbx_memory;
704     memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
705 
706     /* Initialize USBX Memory */
707     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
708 
709     /* Check for error.  */
710     if (status != UX_SUCCESS)
711     {
712 
713         printf(" ERROR #1\n");
714         test_control_return(1);
715     }
716 
717     /* Register the error callback. */
718     _ux_utility_error_callback_register(test_ux_error_callback);
719 
720     /* The code below is required for installing the device portion of USBX. No call back for
721        device status change in this example. */
722     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
723                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
724                                        string_framework, STRING_FRAMEWORK_LENGTH,
725                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
726     if(status!=UX_SUCCESS)
727     {
728 
729         printf(" ERROR #5\n");
730         test_control_return(1);
731     }
732 
733     /* Set the parameters for callback when insertion/extraction of a CDC device.  */
734 
735     /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
736     status  =  ux_device_stack_class_register(_ux_device_class_dummy_name, _ux_device_class_dummy_entry,
737                                              1, 0,  &parameter);
738     if(status!=UX_SUCCESS)
739     {
740 
741         printf(" ERROR #7\n");
742         test_control_return(1);
743     }
744 
745     /* MS extensions.  */
746     status = _ux_device_stack_microsoft_extension_register(UX_DEMO_VENDOR_REQUEST, test_ms_vendor_request);
747 
748     if(status!=UX_SUCCESS)
749     {
750 
751         printf(" ERROR #%d\n", __LINE__);
752         test_control_return(1);
753     }
754 
755     /* Initialize the simulated device controller.  */
756     status =  _ux_test_dcd_sim_slave_initialize();
757 
758     /* Check for error.  */
759     if (status != TX_SUCCESS)
760     {
761 
762         printf(" ERROR #8\n");
763         test_control_return(1);
764     }
765 
766     /* The code below is required for installing the host portion of USBX */
767     status =  ux_host_stack_initialize(test_host_change_function);
768     if (status != UX_SUCCESS)
769     {
770 
771         printf(" ERROR #2\n");
772         test_control_return(1);
773     }
774 
775     /* Register all the USB host controllers available in this system */
776     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
777     if (status != UX_SUCCESS)
778     {
779 
780         printf(" ERROR #4\n");
781         test_control_return(1);
782     }
783 
784     /* Create the main host simulation thread.  */
785     status =  tx_thread_create(&tx_test_thread_simulation0, "tx test simulation 0", tx_test_thread_simulation0_entry, 0,
786             stack_pointer, UX_DEMO_STACK_SIZE,
787             20, 20, 1, TX_AUTO_START);
788 
789     /* Check for error.  */
790     if (status != TX_SUCCESS)
791     {
792 
793         printf(" ERROR #9\n");
794         test_control_return(1);
795     }
796 
797     /* Create the main slave simulation  thread.  */
798     status =  tx_thread_create(&tx_test_thread_simulation1, "tx test simulation 1", tx_test_thread_simulation1_entry, 0,
799             stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
800             20, 20, 1, TX_AUTO_START);
801 
802     /* Check for error.  */
803     if (status != TX_SUCCESS)
804     {
805 
806         printf(" ERROR #10\n");
807         test_control_return(1);
808     }
809 }
810 
tx_test_thread_simulation0_entry(ULONG arg)811 void  tx_test_thread_simulation0_entry(ULONG arg)
812 {
813 UINT                                                status;
814 ULONG                                               actual_length;
815 UX_DEVICE                                          *device;
816 UX_ENDPOINT                                        *control_endpoint;
817 UX_TRANSFER                                        *transfer_request;
818 UX_SLAVE_TRANSFER                                  *slave_transfer_request;
819 
820     stepinfo("\n");
821 
822     /* Wait for first enumeration to complete.  */
823     stepinfo(">>>>>>>>>>>>>>>> Wait for first enumeration completion\n");
824     while (host_device == UX_NULL)
825         tx_thread_sleep(10);
826 
827     /* Wait for instances to be live. */
828     tx_thread_sleep(10);
829 
830     ux_test_dcd_sim_slave_disconnect();
831     ux_test_hcd_sim_host_disconnect();
832 
833     /* Test connect. Note that we must switch to high speed for tests. */
834     stepinfo(">>>>>>>>>>>>>>>> Test connect\n");
835     ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
836     ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
837     tx_thread_sleep(100);
838     if (host_device == UX_NULL)
839     {
840 
841         printf("ERROR #%d: connection not detected\n", __LINE__);
842         test_control_return(1);
843     }
844 
845     device = host_device;
846     control_endpoint = &device->ux_device_control_endpoint;
847     transfer_request = &control_endpoint->ux_endpoint_transfer_request;
848 
849     slave_transfer_request = &_ux_system_slave->ux_system_slave_device.ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request;
850 
851     stepinfo(">>>>>>>>>>>>>>>> Test Vendor Request\n");
852     transfer_request -> ux_transfer_request_function =          0xEE;
853     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
854     status = ux_host_stack_transfer_request(transfer_request);
855     if (status != UX_TRANSFER_STALLED)
856     {
857 
858         printf("ERROR #%d: Vendor request status %x\n", __LINE__, status);
859         test_control_return(1);
860     }
861 
862     stepinfo(">>>>>>>>>>>>>>>> Test MS Vendor Request\n");
863     transfer_request -> ux_transfer_request_function =          UX_DEMO_VENDOR_REQUEST;
864     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
865 
866     vendor_req_rc = UX_ERROR;
867     status = ux_host_stack_transfer_request(transfer_request);
868     if (status != UX_TRANSFER_STALLED)
869     {
870 
871         printf("ERROR #%d: Vendor request status %x\n", __LINE__, status);
872         test_control_return(1);
873     }
874     vendor_req_rc = UX_SUCCESS;
875 
876     status = ux_host_stack_transfer_request(transfer_request);
877     if (status != UX_SUCCESS)
878     {
879 
880         printf("ERROR #%d: Vendor request status %x\n", __LINE__, status);
881         test_control_return(1);
882     }
883 
884     stepinfo(">>>>>>>>>>>>>>>> Test MSRC Error cases\n");
885     /*
886     Execution flow steps:
887     ```
888     - control request transfer message received, properties set as following
889     - request_type = UX_REQUEST_TYPE_VENDOR
890     - request = _ux_system_slave -> ux_system_slave_device_vendor_request)
891     - ux_system_slave_device_vendor_request_function is executed, returns UX_SUCCESS, sets application_data_length
892     - _ux_device_stack_transfer_request(transfer_request, request_length, application_data_length) call results in transfer of request_length bytes of data (0xffff) to the host, buffer overflow occurs
893     ```
894     */
895     vendor_req_rc = UX_SUCCESS;
896     vendor_req_ret_len = 8;
897     transfer_request -> ux_transfer_request_requested_length = 0xFFFF;
898     status = ux_host_stack_transfer_request(transfer_request);
899     UX_TEST_ASSERT(status == UX_SUCCESS);
900     UX_TEST_ASSERT(vendor_req_buf_len <= UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH);
901     UX_TEST_ASSERT(vendor_req_req_len == transfer_request -> ux_transfer_request_requested_length);
902     UX_TEST_ASSERT(transfer_request -> ux_transfer_request_actual_length == vendor_req_ret_len);
903 
904     /* Finally disconnect the device. */
905     ux_device_stack_disconnect();
906 
907     /* Deinitialize the device side of usbx.  */
908     _ux_device_stack_uninitialize();
909 
910     /* And finally the usbx system resources.  */
911     _ux_system_uninitialize();
912 
913     /* Successful test.  */
914     printf("SUCCESS!\n");
915     test_control_return(0);
916 
917 }
918 
tx_test_thread_simulation1_entry(ULONG arg)919 void  tx_test_thread_simulation1_entry(ULONG arg)
920 {
921 
922 UINT status;
923 ULONG                                               actual_length;
924 
925     while(1)
926     {
927 
928         /* Sleep so ThreadX on Win32 will delete this thread. */
929         tx_thread_sleep(10);
930     }
931 }
932