1 /* This test is designed to test the simple dpump host/device class operation.  */
2 
3 #include <stdio.h>
4 #include "tx_api.h"
5 #include "ux_api.h"
6 #include "ux_system.h"
7 #include "ux_utility.h"
8 
9 #include "fx_api.h"
10 
11 #include "ux_device_class_dummy.h"
12 #include "ux_device_stack.h"
13 #include "ux_host_class_video.h"
14 
15 #include "ux_test_dcd_sim_slave.h"
16 #include "ux_test_hcd_sim_host.h"
17 #include "ux_test_utility_sim.h"
18 
19 /* Define constants.  */
20 #define                             UX_DEMO_DEBUG_SIZE  (4096*8)
21 #define                             UX_DEMO_STACK_SIZE  1024
22 #define                             UX_DEMO_BUFFER_SIZE (UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1)
23 #define                             UX_DEMO_XMIT_BUFFER_SIZE 512
24 #define                             UX_DEMO_RECEPTION_BUFFER_SIZE 512
25 #define                             UX_DEMO_FILE_BUFFER_SIZE 512
26 #define                             UX_DEMO_RECEPTION_BLOCK_SIZE 64
27 #define                             UX_DEMO_MEMORY_SIZE     (64*1024)
28 #define                             UX_DEMO_FILE_SIZE       (128 * 1024)
29 #define                             UX_RAM_DISK_MEMORY      (256 * 1024)
30 
31 /* Define local/extern function prototypes.  */
32 static VOID                                test_thread_entry(ULONG);
33 static TX_THREAD                           tx_test_thread_host_simulation;
34 static TX_THREAD                           tx_test_thread_slave_simulation;
35 static VOID                                tx_test_thread_host_simulation_entry(ULONG);
36 static VOID                                tx_test_thread_slave_simulation_entry(ULONG);
37 
38 static VOID                                ux_test_hcd_entry_should_not_be_called(UX_TEST_ACTION *action, VOID *params);
39 static VOID                                ux_test_hcd_entry_disconnect(UX_TEST_ACTION *action, VOID *params);
40 static VOID                                ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params);
41 
42 static VOID                                ux_test_system_host_enum_hub_function(VOID);
43 
44 /* Define global data structures.  */
45 UCHAR                               usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
46 
47 UX_HOST_CLASS_VIDEO                 *host_video = UX_NULL;
48 
49 ULONG                               enum_counter;
50 
51 ULONG                               error_counter;
52 
53 ULONG                               set_cfg_counter;
54 
55 ULONG                               rsc_mem_free_on_set_cfg;
56 ULONG                               rsc_sem_on_set_cfg;
57 ULONG                               rsc_sem_get_on_set_cfg;
58 ULONG                               rsc_mutex_on_set_cfg;
59 
60 ULONG                               rsc_enum_sem_usage;
61 ULONG                               rsc_enum_sem_get_count;
62 ULONG                               rsc_enum_mutex_usage;
63 ULONG                               rsc_enum_mem_usage;
64 
65 static UX_DEVICE_CLASS_DUMMY                *device_dummy[2] = {UX_NULL, UX_NULL};
66 static UX_DEVICE_CLASS_DUMMY_PARAMETER      device_dummy_parameter;
67 
68 /* Define device framework.  */
69 
70 #define             STRING_FRAMEWORK_LENGTH                 47
71 #define             LANGUAGE_ID_FRAMEWORK_LENGTH            2
72 
73 static unsigned char device_framework_full_speed[] = {
74 
75     /* Device descriptor     18 bytes
76        0xEF bDeviceClass:    Composite class code
77        0x02 bDeviceSubclass: class sub code
78        0x00 bDeviceProtocol: Device protocol
79 
80        idVendor & idProduct - http://www.linux-usb.org/usb.ids
81     */
82     0x12, 0x01, 0x10, 0x01,
83     0xEF, 0x02, 0x01,
84     0x08,
85     0x84, 0x84, 0x00, 0x00,
86     0x00, 0x01,
87     0x01, 0x02, 03,
88     0x01,
89 
90     /* Configuration 1 descriptor 9 bytes @ 0x12 */
91     0x09, 0x02,
92     0xE6, 0x00,
93     0x02, 0x01, 0x00,
94     0x40, 0x00,
95 
96     /* Interface association descriptor @ 0x12+0x09=27 */
97     0x08, 0x0b, 0x00, 0x02, 0x0E, 0x03, 0x00, 0x00,
98 
99     /* VideoControl Interface Descriptor Requirement @ 0x12+0x09+8=35  */
100     0x09, 0x04,
101     0x00, 0x00,
102     0x01,
103     0x0E, 0x01, 0x01,
104     0x00,
105 
106         /* VC_HEADER Descriptor @ 35+9=44 */
107         0x0D, 0x24, 0x01,
108         0x50, 0x01,
109         0x4D, 0x00, /* wTotalLength:  */
110         0x00, 0x00, 0x00, 0x00,
111         0x01, /* bInCollection  */
112         0x01, /* baInterfaceNr(1)  */
113 
114         /* Input Terminal Descriptor (Camera) @ 44+0x0D=57  */
115         0x12, 0x24, 0x02,
116         0x02, /* bTerminalID  */
117         0x01, 0x02, /* wTerminalType ITT_CAMERA  */
118         0x00,
119         0x00,
120         0x00, 0x00, /* wObjectiveFocalLengthMin  */
121         0x00, 0x00, /* wObjectiveFocalLengthMax  */
122         0x00, 0x00, /* wOcularFocalLength        */
123         0x03, /* bControlSize  */
124         0x00, 0x02, 0x00, /* bmControls  */
125 
126         /* Input Terminal Descriptor (Media Transport) @ 57+0x12=75 */
127         0x10, 0x24, 0x02,
128         0x03, /* bTerminalID  */
129         0x02, 0x02, /* wTerminalType ITT_MEDIA_TRANSPORT_INPUT  */
130         0x00,
131         0x00,
132         0x01, /* bControlSize  */
133         0x0D, /* bmControls  */
134         0x05, /* bTransportModeSize  */
135         0xAF, 0xFF, 0xFF, 0x7F, 0x00, /* bmTransportModes  */
136 
137         /* Selector Unit Descriptor @ 75+0x10=91 */
138         0x08, 0x24, 0x04,
139         0x01, /* bUnitID  */
140         0x02, /* bNrInPins  */
141         0x02, /* baSourceID(1)  */
142         0x03, /* baSourceID(2)  */
143         0x00,
144 
145         /* Processing Unit Descriptor @ 91+8=99 */
146         13, 0x24, 0x05,
147         0x05, /* bUnitID  */
148         0x01, /* bSourceID  */
149         0x00, 0x00, /* wMaxMultiplier  */
150         0x03, /* bControlSize  */
151         0x00, 0x00, 0x00, /* bmControls  */
152         0x00,
153         0x00, /* bmVideoStandards  */
154 
155         /* Output Terminal Descriptor @ 99+13=112 */
156         0x09, 0x24, 0x03,
157         0x04, /* bTerminalID  */
158         0x01, 0x01, /* wTerminalType TT_STREAMING */
159         0x00,
160         0x05, /* bSourceID  */
161         0x00,
162 
163         /* Interrupt Endpoint 0x83 descriptor @ 112+9=121 */
164         0x07, 0x05, 0x83,
165         0x03,
166         0x08, 0x00,
167         0x0A,
168 
169         /* CS_ENDPOINT @ 121+7=128 */
170         0x05, 0x25, 0x03,
171         0x20, 0x00, /* wMaxTransferSize  */
172 
173     /* VideoStreaming Interface 1.0 @ 128+5=133 */
174     0x09, 0x04,
175     0x01, 0x00,
176     0x01,
177     0x0E, 0x02, 0x00,
178     0x00,
179 
180         /* VS_INPUT_HEADER @ 133+9=142 */
181         0x0E, 0x24, 0x01,
182         0x01, /* bNumFormats  */
183         0x4C, 0x00, /* wTotalLength  */
184         0x85, /* bEndpointAddress  */
185         0x00,
186         0x04, /* bTerminalLink  */
187         0x03, /* bStillCaptureMethod  */
188         0x00, /* bTriggerSupport  */
189         0x00, /* bTriggerUsage  */
190         0x01, /* bControlSize  */
191         0x00, /* bmaControls   */
192 
193         /* VS_FORMAT_MJPEG @ 142+0xE=156 */
194         0x0B, 0x24, 0x06,
195         0x01, /* bFormatIndex  */
196         0x01, /* bNumFrameDescriptors  */
197         0x01, /* bmFlags  */
198         0x01, /* bDefaultFrameIndex  */
199         0x00, 0x00,
200         0x02, /* bmInterlaceFlags  */
201         0x00, /* bCopyProtect  */
202 
203         /* VS_FRAME_MJPEG @ 156+0x0b=167 */
204         0x1E, 0x24, 0x07,
205         0x01, /* bFrameIndex  */
206         0x02, /* bmCapabilities  */
207         0xA0, 0x00, /* wWidth  160 */
208         0x78, 0x00, /* wHeight 120 */
209         0x00, 0x65, 0x04, 0x00, /* dwMinBitRate  */
210         0x00, 0xA0, 0x0F, 0x00, /* dwMaxBitRate  */
211         0x00, 0x08, 0x00, 0x00, /* dwMaxVideoFrameBufSize  */
212         0x2A, 0x2C, 0x0A, 0x00, /* dwDefaultFrameInterval  */
213         0x01, /* bFrameIntervalType  */
214         0x2A, 0x2C, 0x0A, 0x00, /* dwFrameInterval(1) 666666 */
215 
216         /* VS_STILL_FRAME @ 167+0x1e=197 */
217         0x0F, 0x24, 0x03,
218         0x86, /* bEndpointAddress  */
219         0x02, /* bNumImageSizePatterns  */
220         0x20, 0x03, /* wWidth 800  */
221         0x58, 0x02, /* wHeight 600 */
222         0x20, 0x03, /* wWidth */
223         0x20, 0x03, /* wHeight */
224         0x01, /* bNumCompressionPtr  */
225         0x64, /* bCompression 1:100  */
226 
227         /* VS_COLORFORMAT @ 197+0xf=212 */
228         0x06, 0x24, 0x0D,
229         0x00, 0x00, 0x00,
230 
231         /* Bulk endpoint 0x86 */
232         0x07, 0x05,
233         0x86,
234         0x02,
235         0x40, 0x00,
236         0x00,
237 
238     /* VideoStreaming Interface 1.1  */
239     0x09, 0x04,
240     0x01, 0x01,
241     0x02,
242     0x0E, 0x02, 0x00,
243     0x00,
244 
245         /* ISO Endpoint 0x85 */
246         0x07, 0x05,
247         0x85,
248         0x05,
249         0x80, 0x00, /* 128  */
250         0x01,
251 
252         /* Bulk Endpoint 0x86  */
253         0x07, 0x05,
254         0x86,
255         0x02,
256         0x40, 0x00,
257         0x00,
258 };
259 
260 #define             DEVICE_FRAMEWORK_LENGTH_FULL_SPEED      sizeof(device_framework_full_speed)
261 
262 static unsigned char device_framework_high_speed[] = {
263 
264     /* Device descriptor     18 bytes
265        0xEF bDeviceClass:    Composite class code
266        0x02 bDeviceSubclass: class sub code
267        0x00 bDeviceProtocol: Device protocol
268 
269        idVendor & idProduct - http://www.linux-usb.org/usb.ids
270     */
271     0x12, 0x01, 0x10, 0x01,
272     0xEF, 0x02, 0x01,
273     0x08,
274     0x84, 0x84, 0x00, 0x00,
275     0x00, 0x01,
276     0x01, 0x02, 03,
277     0x01,
278 
279     /* Configuration 1 descriptor 9 bytes @ 0x12 */
280     0x09, 0x02,
281     0xE6, 0x00,
282     0x02, 0x01, 0x00,
283     0x40, 0x00,
284 
285     /* Interface association descriptor @ 0x12+0x09=27 */
286     0x08, 0x0b, 0x00, 0x02, 0x0E, 0x03, 0x00, 0x00,
287 
288     /* VideoControl Interface Descriptor Requirement @ 0x12+0x09+8=35  */
289     0x09, 0x04,
290     0x00, 0x00,
291     0x01,
292     0x0E, 0x01, 0x01,
293     0x00,
294 
295         /* VC_HEADER Descriptor @ 35+9=44 */
296         0x0D, 0x24, 0x01,
297         0x50, 0x01,
298         0x4D, 0x00, /* wTotalLength:  */
299         0x00, 0x00, 0x00, 0x00,
300         0x01, /* bInCollection  */
301         0x01, /* baInterfaceNr(1)  */
302 
303         /* Input Terminal Descriptor (Camera) @ 44+0x0D=57  */
304         0x12, 0x24, 0x02,
305         0x02, /* bTerminalID  */
306         0x01, 0x02, /* wTerminalType ITT_CAMERA  */
307         0x00,
308         0x00,
309         0x00, 0x00, /* wObjectiveFocalLengthMin  */
310         0x00, 0x00, /* wObjectiveFocalLengthMax  */
311         0x00, 0x00, /* wOcularFocalLength        */
312         0x03, /* bControlSize  */
313         0x00, 0x02, 0x00, /* bmControls  */
314 
315         /* Input Terminal Descriptor (Media Transport) @ 57+0x12=75 */
316         0x10, 0x24, 0x02,
317         0x03, /* bTerminalID  */
318         0x02, 0x02, /* wTerminalType ITT_MEDIA_TRANSPORT_INPUT  */
319         0x00,
320         0x00,
321         0x01, /* bControlSize  */
322         0x0D, /* bmControls  */
323         0x05, /* bTransportModeSize  */
324         0xAF, 0xFF, 0xFF, 0x7F, 0x00, /* bmTransportModes  */
325 
326         /* Selector Unit Descriptor @ 75+0x10=91 */
327         0x08, 0x24, 0x04,
328         0x01, /* bUnitID  */
329         0x02, /* bNrInPins  */
330         0x02, /* baSourceID(1)  */
331         0x03, /* baSourceID(2)  */
332         0x00,
333 
334         /* Processing Unit Descriptor @ 91+8=99 */
335         13, 0x24, 0x05,
336         0x05, /* bUnitID  */
337         0x01, /* bSourceID  */
338         0x00, 0x00, /* wMaxMultiplier  */
339         0x03, /* bControlSize  */
340         0x00, 0x00, 0x00, /* bmControls  */
341         0x00,
342         0x00, /* bmVideoStandards  */
343 
344         /* Output Terminal Descriptor @ 99+13=112 */
345         0x09, 0x24, 0x03,
346         0x04, /* bTerminalID  */
347         0x01, 0x01, /* wTerminalType TT_STREAMING */
348         0x00,
349         0x05, /* bSourceID  */
350         0x00,
351 
352         /* Interrupt Endpoint 0x83 descriptor @ 112+9=121 */
353         0x07, 0x05, 0x83,
354         0x03,
355         0x08, 0x08,
356         0x01,
357 
358         /* CS_ENDPOINT @ 121+7=128 */
359         0x05, 0x25, 0x03,
360         0x20, 0x00, /* wMaxTransferSize  */
361 
362     /* VideoStreaming Interface 1.0 @ 128+5=133 */
363     0x09, 0x04,
364     0x01, 0x00,
365     0x01,
366     0x0E, 0x02, 0x00,
367     0x00,
368 
369         /* VS_INPUT_HEADER @ 133+9=142 */
370         0x0E, 0x24, 0x01,
371         0x01, /* bNumFormats  */
372         0x4C, 0x00, /* wTotalLength  */
373         0x85, /* bEndpointAddress  */
374         0x00,
375         0x04, /* bTerminalLink  */
376         0x03, /* bStillCaptureMethod  */
377         0x00, /* bTriggerSupport  */
378         0x00, /* bTriggerUsage  */
379         0x01, /* bControlSize  */
380         0x00, /* bmaControls   */
381 
382         /* VS_FORMAT_MJPEG @ 142+0xE=156 */
383         0x0B, 0x24, 0x06,
384         0x01, /* bFormatIndex  */
385         0x01, /* bNumFrameDescriptors  */
386         0x01, /* bmFlags  */
387         0x01, /* bDefaultFrameIndex  */
388         0x00, 0x00,
389         0x02, /* bmInterlaceFlags  */
390         0x00, /* bCopyProtect  */
391 
392         /* VS_FRAME_MJPEG @ 156+0x0b=167 */
393         0x1E, 0x24, 0x07,
394         0x01, /* bFrameIndex  */
395         0x02, /* bmCapabilities  */
396         0xA0, 0x00, /* wWidth  160 */
397         0x78, 0x00, /* wHeight 120 */
398         0x00, 0x65, 0x04, 0x00, /* dwMinBitRate  */
399         0x00, 0xA0, 0x0F, 0x00, /* dwMaxBitRate  */
400         0x00, 0x08, 0x00, 0x00, /* dwMaxVideoFrameBufSize  */
401         0x2A, 0x2C, 0x0A, 0x00, /* dwDefaultFrameInterval  */
402         0x01, /* bFrameIntervalType  */
403         0x2A, 0x2C, 0x0A, 0x00, /* dwFrameInterval(1) 666666  */
404 
405         /* VS_STILL_FRAME @ 167+0x1e=197 */
406         0x0F, 0x24, 0x03,
407         0x86, /* bEndpointAddress  */
408         0x02, /* bNumImageSizePatterns  */
409         0x20, 0x03, /* wWidth 800  */
410         0x58, 0x02, /* wHeight 600 */
411         0x20, 0x03, /* wWidth */
412         0x20, 0x03, /* wHeight */
413         0x01, /* bNumCompressionPtr  */
414         0x64, /* bCompression 1:100  */
415 
416         /* VS_COLORFORMAT @ 197+0xf=212 */
417         0x06, 0x24, 0x0D,
418         0x00, 0x00, 0x00,
419 
420         /* Bulk endpoint 0x86 */
421         0x07, 0x05,
422         0x86,
423         0x02,
424         0x40, 0x00,
425         0x00,
426 
427     /* VideoStreaming Interface 1.1  */
428     0x09, 0x04,
429     0x01, 0x01,
430     0x02,
431     0x0E, 0x02, 0x00,
432     0x00,
433 
434         /* ISO Endpoint 0x85 */
435         0x07, 0x05,
436         0x85,
437         0x05,
438         0x80, 0x08, /* 2 x 128 = 256 */
439         0x01,
440 
441         /* Bulk Endpoint 0x86  */
442         0x07, 0x05,
443         0x86,
444         0x02,
445         0x40, 0x00,
446         0x00,
447 };
448 #define             DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED      sizeof(device_framework_high_speed)
449 
450 static unsigned char string_framework[] = {
451 
452     /* Manufacturer string descriptor : Index 1 - "Express Logic" */
453         0x09, 0x04, 0x01, 0x0c,
454         0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
455         0x6f, 0x67, 0x69, 0x63,
456 
457     /* Product string descriptor : Index 2 - "EL Composite device" */
458         0x09, 0x04, 0x02, 0x13,
459         0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
460         0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
461         0x69, 0x63, 0x65,
462 
463     /* Serial Number string descriptor : Index 3 - "0001" */
464         0x09, 0x04, 0x03, 0x04,
465         0x30, 0x30, 0x30, 0x31
466     };
467 
468 
469     /* Multiple languages are supported on the device, to add
470        a language besides english, the unicode language code must
471        be appended to the language_id_framework array and the length
472        adjusted accordingly. */
473 static unsigned char language_id_framework[] = {
474 
475     /* English. */
476         0x09, 0x04
477     };
478 
479 static UX_TEST_SETUP _SetAddress = UX_TEST_SETUP_SetAddress;
480 static UX_TEST_SETUP _GetDeviceDescriptor = UX_TEST_SETUP_GetDevDescr;
481 static UX_TEST_SETUP _GetConfigDescriptor = UX_TEST_SETUP_GetCfgDescr;
482 static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
483 
484 /* Test interactions */
485 
486 static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
487 /* function, request to match,
488    port action, port status,
489    request action, request EP, request data, request actual length, request status,
490    status, additional callback,
491    no_return */
492 {   UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
493         UX_FALSE, UX_TEST_PORT_STATUS_DISC,
494         UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
495         UX_SUCCESS, ux_test_hcd_entry_set_cfg,
496         UX_TRUE}, /* Invoke callback & continue */
497 {   0   }
498 };
499 
500 static UX_TEST_HCD_SIM_ACTION normal_enum_replace[] = {
501 /* function, request to match,
502    port action, port status,
503    request action, request EP, request data, request actual length, request status,
504    status, additional callback,
505    no_return */
506 {   UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
507         UX_FALSE, 0,
508         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 0, 8, 0,
509         UX_SUCCESS, UX_NULL},
510 {   UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
511         UX_FALSE, 0,
512         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 0, 18, 0,
513         UX_SUCCESS, UX_NULL},
514 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
515         UX_FALSE, 0,
516         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 18, UX_CONFIGURATION_DESCRIPTOR_LENGTH, 0,
517         UX_SUCCESS, UX_NULL},
518 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
519         UX_FALSE, 0,
520         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 18, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 18, 0,
521         UX_SUCCESS, UX_NULL},
522 {   0   }
523 }
524 ;
525 
526 /* Define the ISR dispatch.  */
527 
528 extern VOID    (*test_isr_dispatch)(void);
529 
530 
531 /* Prototype for test control return.  */
532 
533 void  test_control_return(UINT status);
534 
535 
536 /* Define the ISR dispatch routine.  */
537 
test_isr(void)538 static void    test_isr(void)
539 {
540 
541     /* For further expansion of interrupt-level testing.  */
542 }
543 
test_slave_change_function(ULONG change)544 static UINT test_slave_change_function(ULONG change)
545 {
546     return 0;
547 }
548 
test_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)549 static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
550 {
551 
552 UX_HOST_CLASS_VIDEO *video_inst = (UX_HOST_CLASS_VIDEO *) inst;
553 
554     switch(event)
555     {
556 
557         case UX_DEVICE_INSERTION:
558             host_video = video_inst;
559             break;
560 
561         case UX_DEVICE_REMOVAL:
562             host_video = UX_NULL;
563             break;
564 
565         default:
566             break;
567     }
568     return 0;
569 }
570 
test_dummy_instance_activate(VOID * dummy_instance)571 static VOID    test_dummy_instance_activate(VOID *dummy_instance)
572 {
573     if (device_dummy[0] == UX_NULL)
574     {
575         device_dummy[0] = (UX_DEVICE_CLASS_DUMMY *)dummy_instance;
576         return;
577     }
578     if (device_dummy[1] == UX_NULL)
579     {
580         device_dummy[1] = (UX_DEVICE_CLASS_DUMMY *)dummy_instance;
581         return;
582     }
583 }
test_dummy_instance_deactivate(VOID * dummy_instance)584 static VOID    test_dummy_instance_deactivate(VOID *dummy_instance)
585 {
586     if (device_dummy[0] == dummy_instance)
587         device_dummy[0] = UX_NULL;
588     if (device_dummy[1] == dummy_instance)
589         device_dummy[1] = UX_NULL;
590 }
591 static UX_SLAVE_TRANSFER _last_control_transfer;
592 static UCHAR             _last_control_data[64];
test_dummy_instance_control_request(UX_DEVICE_CLASS_DUMMY * dummy_instance,UX_SLAVE_TRANSFER * transfer)593 static VOID test_dummy_instance_control_request(UX_DEVICE_CLASS_DUMMY *dummy_instance,
594                                         UX_SLAVE_TRANSFER *transfer)
595 {
596 USHORT req_length = _ux_utility_short_get(transfer->ux_slave_transfer_request_setup + 6);
597 #if 0
598     printf("D_Video_Req %x: %x %x, %x %x %x; %d/%d\n",
599         transfer->ux_slave_transfer_request_phase,
600         transfer->ux_slave_transfer_request_setup[0],
601         transfer->ux_slave_transfer_request_setup[1],
602         _ux_utility_short_get(transfer->ux_slave_transfer_request_setup + 2),
603         _ux_utility_short_get(transfer->ux_slave_transfer_request_setup + 4),
604         _ux_utility_short_get(transfer->ux_slave_transfer_request_setup + 6),
605         transfer->ux_slave_transfer_request_actual_length,
606         transfer->ux_slave_transfer_request_requested_length);
607 #endif
608     _ux_utility_memory_copy(&_last_control_transfer, transfer, sizeof(UX_SLAVE_TRANSFER));
609     if (transfer->ux_slave_transfer_request_setup[0] & 0x80) /* GET */
610     {
611         _ux_utility_memory_copy(transfer->ux_slave_transfer_request_data_pointer,
612                                 _last_control_data,
613                                 req_length);
614         _ux_device_stack_transfer_request(transfer, req_length, req_length);
615     }
616     else /* SET */
617     {
618         _ux_utility_memory_copy(_last_control_data,
619                                transfer->ux_slave_transfer_request_data_pointer,
620                                req_length);
621     }
622     // _ux_device_stack_endpoint_stall(transfer->ux_slave_transfer_request_endpoint);
623 }
test_dummy_instance_change(UX_DEVICE_CLASS_DUMMY * dummy_instance)624 static VOID test_dummy_instance_change(UX_DEVICE_CLASS_DUMMY *dummy_instance)
625 {
626 }
627 
test_ux_error_callback(UINT system_level,UINT system_context,UINT error_code)628 static VOID test_ux_error_callback(UINT system_level, UINT system_context, UINT error_code)
629 {
630 }
631 
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * params)632 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params)
633 {
634 
635     set_cfg_counter ++;
636 
637     rsc_mem_free_on_set_cfg = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
638     rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
639     rsc_enum_sem_get_count = ux_test_utility_sim_sem_get_count();
640     rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
641 }
642 
ux_test_system_host_enum_hub_function(VOID)643 static VOID ux_test_system_host_enum_hub_function(VOID)
644 {
645     enum_counter ++;
646 }
647 
648 /* Define what the initial system looks like.  */
649 
650 #ifdef CTEST
test_application_define(void * first_unused_memory)651 void test_application_define(void *first_unused_memory)
652 #else
653 void    usbx_host_class_video_basic_test_application_define(void *first_unused_memory)
654 #endif
655 {
656 
657 UINT                    status;
658 CHAR *                  stack_pointer;
659 CHAR *                  memory_pointer;
660 
661 
662     printf("Running Host Class Video Basic Functionality Test................... ");
663 #if !(UX_TEST_MULTI_IFC_ON && UX_TEST_MULTI_ALT_ON)
664     printf("SKIP!\n");
665     test_control_return(0);
666     return;
667 #endif
668 
669     /* Reset testing counts. */
670     ux_test_utility_sim_mutex_create_count_reset();
671     ux_test_utility_sim_sem_create_count_reset();
672     ux_test_utility_sim_sem_get_count_reset();
673     /* Reset error generations */
674     ux_test_utility_sim_sem_error_generation_stop();
675     ux_test_utility_sim_mutex_error_generation_stop();
676     ux_test_utility_sim_sem_get_error_generation_stop();
677 
678     /* Initialize the free memory pointer */
679     stack_pointer = (CHAR *) usbx_memory;
680     memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
681 
682     /* Initialize USBX Memory */
683     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
684 
685     /* Check for error.  */
686     if (status != UX_SUCCESS)
687     {
688 
689         printf(" ERROR #1\n");
690         test_control_return(1);
691     }
692 
693     /* Register the error callback. */
694     _ux_utility_error_callback_register(test_ux_error_callback);
695 
696     /* The code below is required for installing the host portion of USBX */
697     status =  ux_host_stack_initialize(test_host_change_function);
698     if (status != UX_SUCCESS)
699     {
700 
701         printf(" ERROR #2\n");
702         test_control_return(1);
703     }
704 
705     /* Register CDC-ACM class.  */
706     status =  ux_host_stack_class_register(_ux_system_host_class_video_name, ux_host_class_video_entry);
707     if (status != UX_SUCCESS)
708     {
709 
710         printf(" ERROR #3\n");
711         test_control_return(1);
712     }
713 
714     /* The code below is required for installing the device portion of USBX. No call back for
715        device status change in this example. */
716     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
717                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
718                                        string_framework, STRING_FRAMEWORK_LENGTH,
719                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,
720                                        test_slave_change_function);
721     if(status!=UX_SUCCESS)
722     {
723 
724         printf(" ERROR #5\n");
725         test_control_return(1);
726     }
727 
728     /* Set the parameters for callback when insertion/extraction of a dummy device.  */
729     _ux_utility_memory_set(&device_dummy_parameter, 0, sizeof(device_dummy_parameter));
730     device_dummy_parameter.ux_device_class_dummy_parameter_callbacks.
731         ux_device_class_dummy_instance_activate          = test_dummy_instance_activate;
732     device_dummy_parameter.ux_device_class_dummy_parameter_callbacks.
733         ux_device_class_dummy_instance_deactivate        = test_dummy_instance_deactivate;
734     device_dummy_parameter.ux_device_class_dummy_parameter_callbacks.
735         ux_device_class_dummy_change                     = test_dummy_instance_change;
736     device_dummy_parameter.ux_device_class_dummy_parameter_callbacks.
737         ux_device_class_dummy_control_request            = test_dummy_instance_control_request;
738     /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
739     status  = ux_device_stack_class_register(_ux_system_slave_class_dpump_name,
740                                              _ux_device_class_dummy_entry,
741                                              1, 0, &device_dummy_parameter);
742     status |= ux_device_stack_class_register(_ux_system_slave_class_dpump_name,
743                                              _ux_device_class_dummy_entry,
744                                              1, 1, &device_dummy_parameter);
745 #if UX_MAX_SLAVE_CLASS_DRIVER > 1
746     if(status != UX_SUCCESS)
747     {
748 
749         printf(" ERROR #7\n");
750         test_control_return(1);
751     }
752 #endif
753     /* Initialize the simulated device controller.  */
754     status =  _ux_test_dcd_sim_slave_initialize();
755 
756     /* Check for error.  */
757     if (status != TX_SUCCESS)
758     {
759 
760         printf(" ERROR #8\n");
761         test_control_return(1);
762     }
763 
764     /* Register all the USB host controllers available in this system */
765     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
766     if (status != UX_SUCCESS)
767     {
768 
769         printf(" ERROR #4\n");
770         test_control_return(1);
771     }
772 
773     /* Create the main host simulation thread.  */
774     status =  tx_thread_create(&tx_test_thread_host_simulation, "tx test host simulation", tx_test_thread_host_simulation_entry, 0,
775             stack_pointer, UX_DEMO_STACK_SIZE,
776             20, 20, 1, TX_AUTO_START);
777 
778     /* Check for error.  */
779     if (status != TX_SUCCESS)
780     {
781 
782         printf(" ERROR #9\n");
783         test_control_return(1);
784     }
785 
786     /* Create the main slave simulation  thread.  */
787     status =  tx_thread_create(&tx_test_thread_slave_simulation, "tx test slave simulation", tx_test_thread_slave_simulation_entry, 0,
788             stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
789             20, 20, 1, TX_AUTO_START);
790 
791     /* Check for error.  */
792     if (status != TX_SUCCESS)
793     {
794 
795         printf(" ERROR #10\n");
796         test_control_return(1);
797     }
798 }
799 
800 #define TX_TEST_VIDEO_PARSER_SIZE            32
801 typedef struct TX_TEST_VIDEO_PARSER_STRUCT
802 {
803     UCHAR                   *descriptor_base;
804     ULONG                   parsed_interface[TX_TEST_VIDEO_PARSER_SIZE];
805     ULONG                   parsed_entity[TX_TEST_VIDEO_PARSER_SIZE];
806     ULONG                   parsed_count;
807 } TX_TEST_VIDEO_PARSER;
808 
809 static const TX_TEST_VIDEO_PARSER parser_check =
810 {
811     UX_NULL,
812     {17,  17,  17,  17,  17,  17,  17,  17,
813      115, 115, 115, 115, 115},
814     {26,  39,  57,  73,  81,  94, 103, 110,
815      124, 138, 149, 179, 182},
816     13
817 };
818 
tx_test_video_descriptors_parser(VOID * arg,UCHAR * packed_interface_descriptor,UCHAR * packed_entity_descriptor)819 static UINT tx_test_video_descriptors_parser(VOID  *arg,
820                               UCHAR *packed_interface_descriptor,
821                               UCHAR *packed_entity_descriptor)
822 {
823 TX_TEST_VIDEO_PARSER        *parser;
824 
825     parser = (TX_TEST_VIDEO_PARSER *)arg;
826     parser->parsed_interface[parser->parsed_count] = packed_interface_descriptor - parser->descriptor_base;
827     parser->parsed_entity   [parser->parsed_count] = packed_entity_descriptor    - parser->descriptor_base;
828     parser->parsed_count ++;
829 }
830 
831 
tx_test_thread_host_simulation_entry(ULONG arg)832 void  tx_test_thread_host_simulation_entry(ULONG arg)
833 {
834 
835 UINT                                                status;
836 ULONG                                               test_n;
837 ULONG                                               mem_free;
838 ULONG                                               loop;
839 TX_TEST_VIDEO_PARSER                                parser;
840 ULONG                                               parameter_u32[64/4];
841 USHORT                                              *parameter_u16 = (USHORT*)parameter_u32;
842 UCHAR                                               *parameter_u8 = (UCHAR*)parameter_u32;
843 UX_ENDPOINT                                         *iso_ep;
844 UX_ENDPOINT                                         *int_ep;
845 UX_DEVICE                                           *device;
846 
847 
848     stepinfo("\n");
849     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
850     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
851 
852     /* Find the video class and wait for the link to be up.  */
853     for (loop = 0; loop < 100; loop ++)
854         if (host_video != UX_NULL)
855             break;
856     if (host_video == UX_NULL)
857     {
858         printf("ERROR #%d: enum fail", __LINE__);
859         test_control_return(1);
860     }
861     if (host_video->ux_host_class_video_feature_unit_id != 5)
862     {
863         printf("ERROR #%d: wrong feature bUnitID 0x%lx\n", __LINE__, host_video->ux_host_class_video_feature_unit_id);
864         test_control_return(1);
865     }
866     if (host_video->ux_host_class_video_terminal_id != 2)
867     {
868         printf("ERROR #%d: wrong input bTerminalID 0x%lx\n", __LINE__, host_video->ux_host_class_video_terminal_id);
869         test_control_return(1);
870     }
871     if (host_video->ux_host_class_video_number_formats != 1)
872     {
873         printf("ERROR #%d: wrong VS_HEADER bNumFormats %ld\n", __LINE__, host_video->ux_host_class_video_number_formats);
874         test_control_return(1);
875     }
876     if (host_video->ux_host_class_video_length_formats != 0x004C)
877     {
878         printf("ERROR #%d: wrong VS_HEADER wTotalLength 0x%lx\n", __LINE__, host_video->ux_host_class_video_length_formats);
879         test_control_return(1);
880     }
881     if (host_video->ux_host_class_video_format_address !=
882         (host_video->ux_host_class_video_configuration_descriptor + 124))
883     {
884         printf("ERROR #%d: wrong VS_HEADER addr %p <> %p\n", __LINE__,
885             host_video->ux_host_class_video_format_address,
886             (host_video->ux_host_class_video_configuration_descriptor + 124));
887         test_control_return(1);
888     }
889     int_ep = host_video->ux_host_class_video_device->
890                             ux_device_current_configuration->
891                             ux_configuration_first_interface->
892                             ux_interface_first_endpoint;
893     if (int_ep->ux_endpoint_transfer_request.ux_transfer_request_packet_length != 8)
894     {
895         printf("ERROR #%d: wrong INT max packet length %ld\n", __LINE__, iso_ep->ux_endpoint_transfer_request.ux_transfer_request_packet_length);
896         test_control_return(1);
897     }
898     iso_ep = host_video->ux_host_class_video_device->
899                             ux_device_current_configuration->
900                             ux_configuration_first_interface->
901                             ux_interface_next_interface->
902                             ux_interface_next_interface->ux_interface_first_endpoint;
903     if (iso_ep->ux_endpoint_transfer_request.ux_transfer_request_packet_length != 128)
904     {
905         printf("ERROR #%d: wrong ISO max packet length %ld\n", __LINE__, iso_ep->ux_endpoint_transfer_request.ux_transfer_request_packet_length);
906         test_control_return(1);
907     }
908 
909     /* Re-connect with high speed.  */
910     ux_test_hcd_sim_host_disconnect();
911     ux_test_dcd_sim_slave_disconnect();
912 
913     ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
914     ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
915     /* Find the video class and wait for the link to be up.  */
916     for (loop = 0; loop < 100; loop ++)
917         if (host_video != UX_NULL)
918             break;
919     if (host_video == UX_NULL)
920     {
921         printf("ERROR #%d: enum fail", __LINE__);
922         test_control_return(1);
923     }
924     if (host_video->ux_host_class_video_feature_unit_id != 5)
925     {
926         printf("ERROR #%d: wrong feature bUnitID 0x%lx\n", __LINE__, host_video->ux_host_class_video_feature_unit_id);
927         test_control_return(1);
928     }
929     if (host_video->ux_host_class_video_terminal_id != 2)
930     {
931         printf("ERROR #%d: wrong input bTerminalID 0x%lx\n", __LINE__, host_video->ux_host_class_video_terminal_id);
932         test_control_return(1);
933     }
934     if (host_video->ux_host_class_video_number_formats != 1)
935     {
936         printf("ERROR #%d: wrong VS_HEADER bNumFormats %ld\n", __LINE__, host_video->ux_host_class_video_number_formats);
937         test_control_return(1);
938     }
939     if (host_video->ux_host_class_video_length_formats != 0x004C)
940     {
941         printf("ERROR #%d: wrong VS_HEADER wTotalLength 0x%lx\n", __LINE__, host_video->ux_host_class_video_length_formats);
942         test_control_return(1);
943     }
944     if (host_video->ux_host_class_video_format_address !=
945         (host_video->ux_host_class_video_configuration_descriptor + 124))
946     {
947         printf("ERROR #%d: wrong VS_HEADER addr %p <> %p\n", __LINE__,
948             host_video->ux_host_class_video_format_address,
949             (host_video->ux_host_class_video_configuration_descriptor + 124));
950         test_control_return(1);
951     }
952     int_ep = host_video->ux_host_class_video_device->
953                             ux_device_current_configuration->
954                             ux_configuration_first_interface->
955                             ux_interface_first_endpoint;
956     if (int_ep->ux_endpoint_transfer_request.ux_transfer_request_packet_length != 8*2)
957     {
958         printf("ERROR #%d: wrong INT max packet length %ld\n", __LINE__, iso_ep->ux_endpoint_transfer_request.ux_transfer_request_packet_length);
959         test_control_return(1);
960     }
961     iso_ep = host_video->ux_host_class_video_device->
962                             ux_device_current_configuration->
963                             ux_configuration_first_interface->
964                             ux_interface_next_interface->
965                             ux_interface_next_interface->ux_interface_first_endpoint;
966     if (iso_ep->ux_endpoint_transfer_request.ux_transfer_request_packet_length != 128*2)
967     {
968         printf("ERROR #%d: wrong ISO max packet length %ld\n", __LINE__, iso_ep->ux_endpoint_transfer_request.ux_transfer_request_packet_length);
969         test_control_return(1);
970     }
971 
972     /* Test entities parse.  */
973     ux_utility_memory_set(&parser, 0, sizeof(parser));
974     parser.descriptor_base = host_video->ux_host_class_video_configuration_descriptor;
975     status = _ux_host_class_video_entities_parse(host_video, tx_test_video_descriptors_parser, &parser);
976     if (status != UX_SUCCESS)
977     {
978         printf("ERROR #%d: parse error 0x%x\n", __LINE__, status);
979         test_control_return(1);
980     }
981     for(loop = 0; loop < parser.parsed_count; loop++)
982     {
983         if (parser.parsed_interface[loop] != parser_check.parsed_interface[loop])
984         {
985             printf("ERROR #%d: wrong interface: %ld <> %ld\n", __LINE__,
986                 parser.parsed_interface[loop], parser_check.parsed_interface[loop]);
987             test_control_return(1);
988         }
989         if (parser.parsed_entity[loop] != parser_check.parsed_entity[loop])
990         {
991             printf("ERROR #%d: wrong entity descriptor: %ld <> %ld\n", __LINE__,
992                 parser.parsed_entity[loop], parser_check.parsed_entity[loop]);
993             test_control_return(1);
994         }
995     }
996 
997     /* Test VC_HEADER Descriptor @ device_framework_full_speed[ 35+9=44 ] errors.  */
998     /* Default: bLength = 0x0D (13), bInCollection = 1, baInterfaceNr[0] = 1.  */
999 
1000     /* Case 1 : bInCollection @ 11 = 1, baInterfaceNr[0] @ 12 = 5 (interface number not exist).  */
1001     ux_test_hcd_sim_host_disconnect();
1002     ux_test_dcd_sim_slave_disconnect();
1003     UX_TEST_ASSERT(host_video == UX_NULL);
1004     device_framework_full_speed[44 + 11] = 1;
1005     device_framework_full_speed[44 + 12] = 5;
1006     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1007     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1008     /* Find the video class and wait for the link to be up.  */
1009     for (loop = 0; loop < 100; loop ++)
1010         if (host_video != UX_NULL)
1011             break;
1012     status = ux_host_stack_device_get(0, &device);
1013     UX_TEST_ASSERT(status == UX_SUCCESS && host_video == UX_NULL);
1014     device_framework_full_speed[44 + 11] = 1;
1015     device_framework_full_speed[44 + 12] = 1;
1016 
1017     /* Case 2 : bInCollection @ 11 = 3 (over what in configuration).  */
1018     ux_test_hcd_sim_host_disconnect();
1019     ux_test_dcd_sim_slave_disconnect();
1020     UX_TEST_ASSERT(host_video == UX_NULL);
1021     device_framework_full_speed[44 + 11] = 3;
1022     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1023     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1024     /* Find the video class and wait for the link to be up.  */
1025     for (loop = 0; loop < 100; loop ++)
1026         if (host_video != UX_NULL)
1027             break;
1028     status = ux_host_stack_device_get(0, &device);
1029     UX_TEST_ASSERT(status == UX_SUCCESS && host_video == UX_NULL);
1030     device_framework_full_speed[44 + 11] = 1;
1031 
1032     /* Case 3 : bLength @ 0 = 12 (VC header descriptor length too small).  */
1033     ux_test_hcd_sim_host_disconnect();
1034     ux_test_dcd_sim_slave_disconnect();
1035     UX_TEST_ASSERT(host_video == UX_NULL);
1036     device_framework_full_speed[44 + 0] = 12;
1037     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1038     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1039     /* Find the video class and wait for the link to be up.  */
1040     for (loop = 0; loop < 100; loop ++)
1041         if (host_video != UX_NULL)
1042             break;
1043     status = ux_host_stack_device_get(0, &device);
1044     UX_TEST_ASSERT(status == UX_SUCCESS && host_video == UX_NULL);
1045     device_framework_full_speed[44 + 0] = 13;
1046 
1047     /* Test disconnect. */
1048     stepinfo(">>>>>>>>>>>>>>>> Test disconnect\n");
1049     ux_test_dcd_sim_slave_disconnect();
1050     ux_test_hcd_sim_host_disconnect();
1051     if (host_video != UX_NULL)
1052     {
1053 
1054         printf("ERROR #13: instance not removed when disconnect");
1055         test_control_return(1);
1056     }
1057 
1058     /* Finally disconnect the device. */
1059     ux_device_stack_disconnect();
1060 
1061     /* And deinitialize the class.  */
1062     status  = ux_device_stack_class_unregister(_ux_system_slave_class_dpump_name, _ux_device_class_dummy_entry);
1063     status |= ux_device_stack_class_unregister(_ux_system_slave_class_dpump_name, _ux_device_class_dummy_entry);
1064 
1065     /* Deinitialize the device side of usbx.  */
1066     _ux_device_stack_uninitialize();
1067 
1068     /* And finally the usbx system resources.  */
1069     _ux_system_uninitialize();
1070 
1071     /* Successful test.  */
1072     printf("SUCCESS!\n");
1073     test_control_return(0);
1074 
1075 }
1076 
tx_test_thread_slave_simulation_entry(ULONG arg)1077 void  tx_test_thread_slave_simulation_entry(ULONG arg)
1078 {
1079 
1080     while(1)
1081     {
1082 
1083         /* Sleep so ThreadX on Win32 will delete this thread. */
1084         tx_thread_sleep(10);
1085     }
1086 }
1087