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_1 = UX_NULL;
48 UX_HOST_CLASS_VIDEO                 *host_video_2 = UX_NULL;
49 
50 ULONG                               enum_counter;
51 
52 ULONG                               error_counter;
53 
54 ULONG                               set_cfg_counter;
55 
56 ULONG                               rsc_mem_free_on_set_cfg;
57 ULONG                               rsc_sem_on_set_cfg;
58 ULONG                               rsc_sem_get_on_set_cfg;
59 ULONG                               rsc_mutex_on_set_cfg;
60 
61 ULONG                               rsc_enum_sem_usage;
62 ULONG                               rsc_enum_sem_get_count;
63 ULONG                               rsc_enum_mutex_usage;
64 ULONG                               rsc_enum_mem_usage;
65 
66 static UX_DEVICE_CLASS_DUMMY                *device_dummy[2] = {UX_NULL, UX_NULL};
67 static UX_DEVICE_CLASS_DUMMY_PARAMETER      device_dummy_parameter;
68 
69 /* Define device framework.  */
70 
71 #define             STRING_FRAMEWORK_LENGTH                 47
72 #define             LANGUAGE_ID_FRAMEWORK_LENGTH            2
73 
74 static unsigned char device_framework_full_speed[] = {
75 
76     /* Device descriptor     18 bytes
77        0xEF bDeviceClass:    Composite class code
78        0x02 bDeviceSubclass: class sub code
79        0x00 bDeviceProtocol: Device protocol
80 
81        idVendor & idProduct - http://www.linux-usb.org/usb.ids
82     */
83     18, 0x01, 0x10, 0x01,
84     0xEF, 0x02, 0x01,
85     0x08,
86     0x84, 0x84, 0x00, 0x00,
87     0x00, 0x01,
88     0x01, 0x02, 03,
89     0x01,
90 
91     /* Configuration 1 descriptor 9 bytes @ 0 */
92     0x09, 0x02,
93     0x81, 0x01,        /* wTotalLength 9+8+108+92+23+129+16=385(0x181)  */
94     0x02, 0x01, 0x00,
95     0x40, 0x00,
96 
97     /* Interface association descriptor @ 9 */
98     0x08, 0x0b, 0x00, 0x03, 0x0E, 0x03, 0x00, 0x00,
99 
100     /* VideoControl Interface Descriptor Requirement @ 17; 9+87+7+5=108  */
101     0x09, 0x04,
102     0x00, 0x00,
103     0x01,
104     0x0E, 0x01, 0x01,
105     0x00,
106 
107         /* VC_HEADER Descriptor @ 26 */
108         14, 0x24, 0x01,
109         0x50, 0x01,
110         87, 0x00, /* wTotalLength: 14+18+16+8+13+9+9=87  */
111         0x00, 0x00, 0x00, 0x00,
112         0x02, /* bInCollection  */
113         0x01, /* baInterfaceNr(1)  */
114         0x02, /* baInterfaceNr(2)  */
115 
116         /* Input Terminal Descriptor (Camera) @ 40  */
117         18, 0x24, 0x02,
118         0x02, /* bTerminalID  */
119         0x01, 0x02, /* wTerminalType ITT_CAMERA  */
120         0x00,
121         0x00,
122         0x00, 0x00, /* wObjectiveFocalLengthMin  */
123         0x00, 0x00, /* wObjectiveFocalLengthMax  */
124         0x00, 0x00, /* wOcularFocalLength        */
125         0x03, /* bControlSize  */
126         0x00, 0x02, 0x00, /* bmControls  */
127 
128         /* Input Terminal Descriptor (Media Transport) @ 58  */
129         16, 0x24, 0x02,
130         0x03, /* bTerminalID  */
131         0x02, 0x02, /* wTerminalType ITT_MEDIA_TRANSPORT_INPUT  */
132         0x00,
133         0x00,
134         0x01, /* bControlSize  */
135         0x0D, /* bmControls  */
136         0x05, /* bTransportModeSize  */
137         0xAF, 0xFF, 0xFF, 0x7F, 0x00, /* bmTransportModes  */
138 
139         /* Selector Unit Descriptor @ 74  */
140         0x08, 0x24, 0x04,
141         0x01, /* bUnitID  */
142         0x02, /* bNrInPins  */
143         0x02, /* baSourceID(1)  */
144         0x03, /* baSourceID(2)  */
145         0x00,
146 
147         /* Processing Unit Descriptor @ 82 */
148         13, 0x24, 0x05,
149         0x05, /* bUnitID  */
150         0x01, /* bSourceID  */
151         0x00, 0x00, /* wMaxMultiplier  */
152         0x03, /* bControlSize  */
153         0x00, 0x00, 0x00, /* bmControls  */
154         0x00,
155         0x00, /* bmVideoStandards  */
156 
157         /* Output Terminal Descriptor @ 95 */
158         0x09, 0x24, 0x03,
159         0x04, /* bTerminalID  */
160         0x01, 0x01, /* wTerminalType TT_STREAMING */
161         0x00,
162         0x05, /* bSourceID  */
163         0x00,
164 
165         /* Output Terminal Descriptor @ 104 */
166         0x09, 0x24, 0x03,
167         0x06, /* bTerminalID  */
168         0x01, 0x01, /* wTerminalType TT_STREAMING */
169         0x00,
170         0x05, /* bSourceID  */
171         0x00,
172 
173         /* Interrupt Endpoint 0x83 descriptor @ 113 */
174         0x07, 0x05, 0x83,
175         0x03,
176         0x08, 0x00,
177         0x0A,
178 
179         /* CS_ENDPOINT @ 120 */
180         0x05, 0x25, 0x03,
181         0x20, 0x00, /* wMaxTransferSize  */
182 
183     /* VideoStreaming Interface 1.0 @ 125; 9+76+7=92 */
184     0x09, 0x04,
185     0x01, 0x00,
186     0x01,
187     0x0E, 0x02, 0x00,
188     0x00,
189 
190         /* VS_INPUT_HEADER @ 134 */
191         14, 0x24, 0x01,
192         0x01, /* bNumFormats  */
193         76, 0x00, /* wTotalLength 14+11+30+15+6=76(0x4C)  */
194         0x85, /* bEndpointAddress  */
195         0x00,
196         0x04, /* bTerminalLink  */
197         0x03, /* bStillCaptureMethod  */
198         0x00, /* bTriggerSupport  */
199         0x00, /* bTriggerUsage  */
200         0x01, /* bControlSize  */
201         0x00, /* bmaControls   */
202 
203         /* VS_FORMAT_MJPEG @ 134+14=148 */
204         11, 0x24, 0x06,
205         0x01, /* bFormatIndex  */
206         0x01, /* bNumFrameDescriptors  */
207         0x01, /* bmFlags  */
208         0x01, /* bDefaultFrameIndex  */
209         0x00, 0x00,
210         0x02, /* bmInterlaceFlags  */
211         0x00, /* bCopyProtect  */
212 
213         /* VS_FRAME_MJPEG @ 148+11=159 */
214         30, 0x24, 0x07,
215         0x01, /* bFrameIndex  */
216         0x02, /* bmCapabilities  */
217         0xA0, 0x00, /* wWidth  */
218         0x78, 0x00, /* wHeight  */
219         0x00, 0x65, 0x04, 0x00, /* dwMinBitRate  */
220         0x00, 0xA0, 0x0F, 0x00, /* dwMaxBitRate  */
221         0x00, 0x08, 0x00, 0x00, /* dwMaxVideoFrameBufSize  */
222         0x2A, 0x2C, 0x0A, 0x00, /* dwDefaultFrameInterval  */
223         0x01, /* bFrameIntervalType  */
224         0x2A, 0x2C, 0x0A, 0x00, /* dwFrameInterval(1)  */
225 
226         /* VS_STILL_FRAME @ 159+30=189 */
227         15, 0x24, 0x03,
228         0x86, /* bEndpointAddress  */
229         0x02, /* bNumImageSizePatterns  */
230         0x20, 0x03, /* wWidth 800  */
231         0x58, 0x02, /* wHeight 600 */
232         0x20, 0x03, /* wWidth */
233         0x20, 0x03, /* wHeight */
234         0x01, /* bNumCompressionPtr  */
235         0x64, /* bCompression 1:100  */
236 
237         /* VS_COLORFORMAT @ 189+15=204 */
238         0x06, 0x24, 0x0D,
239         0x00, 0x00, 0x00,
240 
241         /* Bulk endpoint 0x86 @ 204+6=210 */
242         0x07, 0x05,
243         0x86,
244         0x02,
245         0x40, 0x00,
246         0x00,
247 
248     /* VideoStreaming Interface 1.1 @ 210+7=217; 9+7+7=23 */
249     0x09, 0x04,
250     0x01, 0x01,
251     0x02,
252     0x0E, 0x02, 0x00,
253     0x00,
254 
255         /* ISO Endpoint 0x85 @ 217+9=226 */
256         0x07, 0x05,
257         0x85,
258         0x05,
259         0x00, 0x02,
260         0x01,
261 
262         /* Bulk Endpoint 0x86 @ 226+7=233 */
263         0x07, 0x05,
264         0x86,
265         0x02,
266         0x40, 0x00,
267         0x00,
268 
269     /* VideoStreaming Interface 2.0 @ 233+7=240; 9+120=129  */
270     0x09, 0x04,
271     0x02, 0x00,
272     0x00,
273     0x0E, 0x02, 0x00,
274     0x00,
275 
276         /* VS_INPUT_HEADER @ 240+9=249  */
277         14, 0x24, 0x01,
278         0x01, /* bNumFormats  */
279         120, 0x00, /* wTotalLength 14+52+48+6=120(0x78)  */
280         0x87, /* bEndpointAddress  */
281         0x00,
282         0x06, /* bTerminalLink  */
283         0x00, /* bStillCaptureMethod  */
284         0x00, /* bTriggerSupport  */
285         0x00, /* bTriggerUsage  */
286         0x01, /* bControlSize  */
287         0x00, /* bmaControls   */
288 
289         /* VS_FORMAT_H264 @ 249+14=263 */
290         52, 0x24, 0x13,
291         0x01, /* bFormatIndex  */
292         0x01, /* bNumFrameDescriptors  */
293         0x01, /* bDefaultFrameIndex  */
294         0x00, /* bMaxCodecConfigDelay  */
295         0x00, /* bmSupportedSliceModes  */
296         0x00, /* bmSupportedSyncFrameTypes  */
297         0x00, /* bResolutionScaling  */
298         0x00, /* Reserved  */
299         0x00, /* bmSupportedRateControlModes  */
300         0x01, 0x00, /* wMaxMBperSecOneResolutionNoScalability  */
301         0x00, 0x00, /* wMaxMBperSecTwoResolutionsNoScalability  */
302         0x00, 0x00, /* wMaxMBperSecThreeResolutionsNoScalability  */
303         0x00, 0x00, /* wMaxMBperSecFourResolutionsNoScalability  */
304         0x00, 0x00, /* wMaxMBperSecOneResolutionTemporalScalability  */
305         0x00, 0x00, /* wMaxMBperSecTwoResolutionsTemporalScalability  */
306         0x00, 0x00, /* wMaxMBperSecThreeResolutionsTemporalScalability  */
307         0x00, 0x00, /* wMaxMBperSecFourResolutionsTemporalScalability  */
308         0x00, 0x00, /* wMaxMBperSecOneResolutionTemporalQualityScalability  */
309         0x00, 0x00, /* wMaxMBperSecTwoResolutionsTemporalQualityScalability  */
310         0x00, 0x00, /* wMaxMBperSecThreeResolutionsTemporalQualityScalability  */
311         0x00, 0x00, /* wMaxMBperSecFourResolutionsTemporalQualityScalability  */
312         0x00, 0x00, /* wMaxMBperSecOneResolutionTemporalSpatialScalability  */
313         0x00, 0x00, /* wMaxMBperSecTwoResolutionsTemporalSpatialScalability  */
314         0x00, 0x00, /* wMaxMBperSecThreeResolutionsTemporalSpatialScalability  */
315         0x00, 0x00, /* wMaxMBperSecFourResolutionsTemporalSpatialScalability  */
316         0x00, 0x00, /* wMaxMBperSecOneResolutionFullScalability  */
317         0x00, 0x00, /* wMaxMBperSecTwoResolutionsFullScalability  */
318         0x00, 0x00, /* wMaxMBperSecThreeResolutionsFullScalability  */
319         0x00, 0x00, /* wMaxMBperSecFourResolutionsFullScalability  */
320 
321         /* VS_FRAME_H264  */
322         48, 0x24, 0x14,
323         0x01, /* bFrameIndex  */
324         0xA0, 0x00, /* wWidth  */
325         0x78, 0x00, /* wHeight  */
326         0x00, 0x00, /* wSARwidth  */
327         0x00, 0x00, /* wSARheight  */
328         0x00, 0x00, /* wProfile  */
329         0x1F, /* bLevelIDC  */
330         0x00, 0x00, /* wConstrainedToolset  */
331         0x00, 0x00, 0x00, 0x00, /* bmSupportedUsages  */
332         0x00, 0x00, /* bmCapabilities  */
333         0x00, 0x00, 0x00, 0x00, /* bmSVCCapabilities  */
334         0x00, 0x00, 0x00, 0x00, /* bmMVCCapabilities  */
335         0x00, 0x65, 0x04, 0x00, /* dwMinBitRate  */
336         0x00, 0xA0, 0x0F, 0x00, /* dwMaxBitRate  */
337         0x2A, 0x2C, 0x0A, 0x00, /* dwDefaultFrameInterval  */
338         0x01, /* bNumFrameIntervals  */
339         0x2A, 0x2C, 0x0A, 0x00, /* dwFrameInterval(1)  */
340 
341         /* VS_COLORFORMAT */
342         6, 0x24, 0x0D,
343         0x00, 0x00, 0x00,
344 
345     /* VideoStreaming Interface 2.1: 9+7=16  */
346     0x09, 0x04,
347     0x02, 0x01,
348     0x01,
349     0x0E, 0x02, 0x00,
350     0x00,
351 
352         /* ISO Endpoint 0x87 */
353         0x07, 0x05,
354         0x87,
355         0x05,
356         0x00, 0x02,
357         0x01,
358 };
359 
360 #define             DEVICE_FRAMEWORK_LENGTH_FULL_SPEED      sizeof(device_framework_full_speed)
361 #define             DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED      sizeof(device_framework_full_speed)
362 #define             device_framework_high_speed             device_framework_full_speed
363 
364 static unsigned char string_framework[] = {
365 
366     /* Manufacturer string descriptor : Index 1 - "Express Logic" */
367         0x09, 0x04, 0x01, 0x0c,
368         0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
369         0x6f, 0x67, 0x69, 0x63,
370 
371     /* Product string descriptor : Index 2 - "EL Composite device" */
372         0x09, 0x04, 0x02, 0x13,
373         0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
374         0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
375         0x69, 0x63, 0x65,
376 
377     /* Serial Number string descriptor : Index 3 - "0001" */
378         0x09, 0x04, 0x03, 0x04,
379         0x30, 0x30, 0x30, 0x31
380     };
381 
382 
383     /* Multiple languages are supported on the device, to add
384        a language besides english, the unicode language code must
385        be appended to the language_id_framework array and the length
386        adjusted accordingly. */
387 static unsigned char language_id_framework[] = {
388 
389     /* English. */
390         0x09, 0x04
391     };
392 
393 static UX_TEST_SETUP _SetAddress = UX_TEST_SETUP_SetAddress;
394 static UX_TEST_SETUP _GetDeviceDescriptor = UX_TEST_SETUP_GetDevDescr;
395 static UX_TEST_SETUP _GetConfigDescriptor = UX_TEST_SETUP_GetCfgDescr;
396 static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
397 
398 /* Test interactions */
399 
400 static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
401 /* function, request to match,
402    port action, port status,
403    request action, request EP, request data, request actual length, request status,
404    status, additional callback,
405    no_return */
406 {   UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
407         UX_FALSE, UX_TEST_PORT_STATUS_DISC,
408         UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
409         UX_SUCCESS, ux_test_hcd_entry_set_cfg,
410         UX_TRUE}, /* Invoke callback & continue */
411 {   0   }
412 };
413 
414 static UX_TEST_HCD_SIM_ACTION normal_enum_replace[] = {
415 /* function, request to match,
416    port action, port status,
417    request action, request EP, request data, request actual length, request status,
418    status, additional callback,
419    no_return */
420 {   UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
421         UX_FALSE, 0,
422         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 0, 8, 0,
423         UX_SUCCESS, UX_NULL},
424 {   UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
425         UX_FALSE, 0,
426         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 0, 18, 0,
427         UX_SUCCESS, UX_NULL},
428 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
429         UX_FALSE, 0,
430         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 18, UX_CONFIGURATION_DESCRIPTOR_LENGTH, 0,
431         UX_SUCCESS, UX_NULL},
432 {   UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
433         UX_FALSE, 0,
434         UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 18, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 18, 0,
435         UX_SUCCESS, UX_NULL},
436 {   0   }
437 }
438 ;
439 
440 /* Define the ISR dispatch.  */
441 
442 extern VOID    (*test_isr_dispatch)(void);
443 
444 
445 /* Prototype for test control return.  */
446 
447 void  test_control_return(UINT status);
448 
449 
450 /* Define the ISR dispatch routine.  */
451 
test_isr(void)452 static void    test_isr(void)
453 {
454 
455     /* For further expansion of interrupt-level testing.  */
456 }
457 
test_slave_change_function(ULONG change)458 static UINT test_slave_change_function(ULONG change)
459 {
460     return 0;
461 }
462 
test_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)463 static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
464 {
465 
466 UX_HOST_CLASS_VIDEO *video_inst = (UX_HOST_CLASS_VIDEO *) inst;
467 UX_INTERFACE        *interface_inst = video_inst -> ux_host_class_video_streaming_interface;
468     stepinfo("H_Video_Change %lx: %p %p\n", event, (void*)cls, inst);
469     switch(event)
470     {
471 
472         case UX_DEVICE_INSERTION:
473             if (interface_inst -> ux_interface_descriptor.bInterfaceNumber == 1)
474                 host_video_1 = video_inst;
475             if (interface_inst -> ux_interface_descriptor.bInterfaceNumber == 2)
476                 host_video_2 = video_inst;
477             break;
478 
479         case UX_DEVICE_REMOVAL:
480             if (host_video_1 == video_inst)
481                 host_video_1 = UX_NULL;
482             if (host_video_2 == video_inst)
483                 host_video_2 = UX_NULL;
484             break;
485 
486         default:
487             break;
488     }
489     return 0;
490 }
491 
test_dummy_instance_activate(VOID * dummy_instance)492 static VOID    test_dummy_instance_activate(VOID *dummy_instance)
493 {
494     if (device_dummy[0] == UX_NULL)
495     {
496         device_dummy[0] = (UX_DEVICE_CLASS_DUMMY *)dummy_instance;
497         return;
498     }
499     if (device_dummy[1] == UX_NULL)
500     {
501         device_dummy[1] = (UX_DEVICE_CLASS_DUMMY *)dummy_instance;
502         return;
503     }
504 }
test_dummy_instance_deactivate(VOID * dummy_instance)505 static VOID    test_dummy_instance_deactivate(VOID *dummy_instance)
506 {
507     if (device_dummy[0] == dummy_instance)
508         device_dummy[0] = UX_NULL;
509     if (device_dummy[1] == dummy_instance)
510         device_dummy[1] = UX_NULL;
511 }
512 static UX_SLAVE_TRANSFER _last_control_transfer;
513 static UCHAR             _last_control_data[64];
514 static UCHAR             _probe_control_data[UX_HOST_CLASS_VIDEO_PROBE_COMMIT_LENGTH] =
515 {
516     0, 0, /* bmHint */
517     1, /* bFormatIndex  */
518     1, /* bFrameIndex  */
519     UX_DW0(666666),UX_DW1(666666),UX_DW2(666666),UX_DW3(666666), /* dwFrameInterval  */
520     UX_W0(0), UX_W1(0), /* wKeyFrameRate  */
521     UX_W0(0), UX_W1(0), /* wPFrameRate  */
522     UX_W0(0), UX_W1(0), /* wCompQuality */
523     UX_W0(0), UX_W1(0), /* wCompQuality */
524     UX_W0(0), UX_W1(0), /* wDelay */
525     UX_DW0(460800),UX_DW1(460800),UX_DW2(460800),UX_DW3(460800), /* dwMaxVideoFrameSize @ 18 */
526     UX_DW0(256),UX_DW1(256),UX_DW2(256),UX_DW3(256), /* dwMaxPayloadTransferSize @ 22 */
527     UX_DW0(6000000),UX_DW1(6000000),UX_DW2(6000000),UX_DW3(6000000), /* dwClockFrequency */
528     0, /* bmFramingInfo  */
529     0, /* bPreferedVersion  */
530     0, /* bMinVersion  */
531     0, /* bMaxVersion  */
532 };
test_dummy_instance_control_request(UX_DEVICE_CLASS_DUMMY * dummy_instance,UX_SLAVE_TRANSFER * transfer)533 static VOID test_dummy_instance_control_request(UX_DEVICE_CLASS_DUMMY *dummy_instance,
534                                         UX_SLAVE_TRANSFER *transfer)
535 {
536 USHORT req_length = _ux_utility_short_get(transfer->ux_slave_transfer_request_setup + 6);
537 UCHAR  cs         = *(transfer->ux_slave_transfer_request_setup + 4);
538 #if 0
539     printf("D_Video_Req %lx: %x %x, %lx %lx %lx; %ld/%ld\n",
540         transfer->ux_slave_transfer_request_phase,
541         transfer->ux_slave_transfer_request_setup[0],
542         transfer->ux_slave_transfer_request_setup[1],
543         _ux_utility_short_get(transfer->ux_slave_transfer_request_setup + 2),
544         _ux_utility_short_get(transfer->ux_slave_transfer_request_setup + 4),
545         _ux_utility_short_get(transfer->ux_slave_transfer_request_setup + 6),
546         transfer->ux_slave_transfer_request_actual_length,
547         transfer->ux_slave_transfer_request_requested_length);
548 #endif
549     _ux_utility_memory_copy(&_last_control_transfer, transfer, sizeof(UX_SLAVE_TRANSFER));
550     if (transfer->ux_slave_transfer_request_setup[0] & 0x80) /* GET */
551     {
552         switch(cs)
553         {
554         case UX_HOST_CLASS_VIDEO_VS_PROBE_CONTROL:
555             _ux_utility_memory_copy(transfer->ux_slave_transfer_request_data_pointer,
556                                     _probe_control_data,
557                                     UX_MIN(req_length, sizeof(_probe_control_data)));
558             _ux_device_stack_transfer_request(transfer, sizeof(_probe_control_data), req_length);
559             break;
560         case UX_HOST_CLASS_VIDEO_VS_COMMIT_CONTROL:
561         default:
562             _ux_utility_memory_copy(transfer->ux_slave_transfer_request_data_pointer,
563                                     _probe_control_data/*_last_control_data*/,
564                                     req_length);
565             _ux_device_stack_transfer_request(transfer, req_length, req_length);
566         }
567     }
568     else /* SET */
569     {
570         _ux_utility_memory_copy(_last_control_data,
571                                transfer->ux_slave_transfer_request_data_pointer,
572                                req_length);
573         /* Nothing to SET.  */
574     }
575 }
test_dummy_instance_change(UX_DEVICE_CLASS_DUMMY * dummy_instance)576 static VOID test_dummy_instance_change(UX_DEVICE_CLASS_DUMMY *dummy_instance)
577 {
578 }
579 
test_ux_error_callback(UINT system_level,UINT system_context,UINT error_code)580 static VOID test_ux_error_callback(UINT system_level, UINT system_context, UINT error_code)
581 {
582 }
583 
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * params)584 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params)
585 {
586 
587     set_cfg_counter ++;
588 
589     rsc_mem_free_on_set_cfg = ux_test_regular_memory_free();
590     rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
591     rsc_enum_sem_get_count = ux_test_utility_sim_sem_get_count();
592     rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
593 }
594 
ux_test_system_host_enum_hub_function(VOID)595 static VOID ux_test_system_host_enum_hub_function(VOID)
596 {
597     enum_counter ++;
598 }
599 
600 /* Define what the initial system looks like.  */
601 
602 #ifdef CTEST
test_application_define(void * first_unused_memory)603 void test_application_define(void *first_unused_memory)
604 #else
605 void    usbx_host_class_video_format_h264_test_application_define(void *first_unused_memory)
606 #endif
607 {
608 
609 UINT                    status;
610 CHAR *                  stack_pointer;
611 CHAR *                  memory_pointer;
612 
613 
614     printf("Running ux_host_class_video VS_FORMAT_H264 Test..................... ");
615 #if !(UX_TEST_MULTI_IFC_OVER(3) && UX_TEST_MULTI_ALT_ON)
616     printf("SKIP!\n");
617     test_control_return(0);
618     return;
619 #endif
620     if (UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH < DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED)
621     {
622         printf("SKIP (D REQ BUF insufficient)!\n");
623         test_control_return(0);
624         return;
625     }
626 
627     /* Reset testing counts. */
628     ux_test_utility_sim_mutex_create_count_reset();
629     ux_test_utility_sim_sem_create_count_reset();
630     ux_test_utility_sim_sem_get_count_reset();
631     /* Reset error generations */
632     ux_test_utility_sim_sem_error_generation_stop();
633     ux_test_utility_sim_mutex_error_generation_stop();
634     ux_test_utility_sim_sem_get_error_generation_stop();
635 
636     /* Initialize the free memory pointer */
637     stack_pointer = (CHAR *) usbx_memory;
638     memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
639 
640     /* Initialize USBX Memory */
641     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
642 
643     /* Check for error.  */
644     if (status != UX_SUCCESS)
645     {
646 
647         printf(" ERROR #%d\n", __LINE__);
648         test_control_return(1);
649     }
650 
651     /* Register the error callback. */
652     _ux_utility_error_callback_register(test_ux_error_callback);
653 
654     /* The code below is required for installing the host portion of USBX */
655     status =  ux_host_stack_initialize(test_host_change_function);
656     if (status != UX_SUCCESS)
657     {
658 
659         printf(" ERROR #%d\n", __LINE__);
660         test_control_return(1);
661     }
662 
663     /* Register CDC-ACM class.  */
664     status =  ux_host_stack_class_register(_ux_system_host_class_video_name, ux_host_class_video_entry);
665     if (status != UX_SUCCESS)
666     {
667 
668         printf(" ERROR #%d\n", __LINE__);
669         test_control_return(1);
670     }
671 
672     /* The code below is required for installing the device portion of USBX. No call back for
673        device status change in this example. */
674     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
675                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
676                                        string_framework, STRING_FRAMEWORK_LENGTH,
677                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,
678                                        test_slave_change_function);
679     if(status!=UX_SUCCESS)
680     {
681 
682         printf(" ERROR #%d\n", __LINE__);
683         test_control_return(1);
684     }
685 
686     /* Set the parameters for callback when insertion/extraction of a dummy device.  */
687     _ux_utility_memory_set(&device_dummy_parameter, 0, sizeof(device_dummy_parameter));
688     device_dummy_parameter.ux_device_class_dummy_parameter_callbacks.
689         ux_device_class_dummy_instance_activate          = test_dummy_instance_activate;
690     device_dummy_parameter.ux_device_class_dummy_parameter_callbacks.
691         ux_device_class_dummy_instance_deactivate        = test_dummy_instance_deactivate;
692     device_dummy_parameter.ux_device_class_dummy_parameter_callbacks.
693         ux_device_class_dummy_change                     = test_dummy_instance_change;
694     device_dummy_parameter.ux_device_class_dummy_parameter_callbacks.
695         ux_device_class_dummy_control_request            = test_dummy_instance_control_request;
696     /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
697     status  = ux_device_stack_class_register(_ux_system_slave_class_dpump_name,
698                                              _ux_device_class_dummy_entry,
699                                              1, 0, &device_dummy_parameter);
700     status |= ux_device_stack_class_register(_ux_system_slave_class_dpump_name,
701                                              _ux_device_class_dummy_entry,
702                                              1, 1, &device_dummy_parameter);
703     status |= ux_device_stack_class_register(_ux_system_slave_class_dpump_name,
704                                              _ux_device_class_dummy_entry,
705                                              1, 2, &device_dummy_parameter);
706     if(status != UX_SUCCESS)
707     {
708 
709         printf(" ERROR #%d\n", __LINE__);
710         test_control_return(1);
711     }
712 
713     /* Initialize the simulated device controller.  */
714     status =  _ux_test_dcd_sim_slave_initialize();
715 
716     /* Check for error.  */
717     if (status != TX_SUCCESS)
718     {
719 
720         printf(" ERROR #%d\n", __LINE__);
721         test_control_return(1);
722     }
723 
724     /* Register all the USB host controllers available in this system */
725     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
726     if (status != UX_SUCCESS)
727     {
728 
729         printf(" ERROR #%d\n", __LINE__);
730         test_control_return(1);
731     }
732 
733     /* Create the main host simulation thread.  */
734     status =  tx_thread_create(&tx_test_thread_host_simulation, "tx test host simulation", tx_test_thread_host_simulation_entry, 0,
735             stack_pointer, UX_DEMO_STACK_SIZE,
736             20, 20, 1, TX_AUTO_START);
737 
738     /* Check for error.  */
739     if (status != TX_SUCCESS)
740     {
741 
742         printf(" ERROR #%d\n", __LINE__);
743         test_control_return(1);
744     }
745 
746     /* Create the main slave simulation  thread.  */
747     status =  tx_thread_create(&tx_test_thread_slave_simulation, "tx test slave simulation", tx_test_thread_slave_simulation_entry, 0,
748             stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
749             20, 20, 1, TX_AUTO_START);
750 
751     /* Check for error.  */
752     if (status != TX_SUCCESS)
753     {
754 
755         printf(" ERROR #%d\n", __LINE__);
756         test_control_return(1);
757     }
758 }
759 
tx_test_thread_host_simulation_entry(ULONG arg)760 void  tx_test_thread_host_simulation_entry(ULONG arg)
761 {
762 
763 UINT                                                status;
764 ULONG                                               test_n;
765 ULONG                                               mem_free;
766 ULONG                                               loop;
767 ULONG                                               parameter_u32[64/4];
768 USHORT                                              *parameter_u16 = (USHORT*)parameter_u32;
769 UCHAR                                               *parameter_u8 = (UCHAR*)parameter_u32;
770 UX_HOST_CLASS_VIDEO_PARAMETER_FORMAT_DATA           format_data;
771 UX_HOST_CLASS_VIDEO_PARAMETER_FRAME_DATA            frame_data;
772 
773 
774     stepinfo("\n");
775     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
776     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
777 
778     /* Find the video class and wait for the link to be up.  */
779     for (loop = 0; loop < 100; loop ++)
780         if (host_video_1 != UX_NULL && host_video_2 != UX_NULL)
781             break;
782     if (host_video_1 == UX_NULL || host_video_2 == UX_NULL)
783     {
784         printf("ERROR #%d: enum fail", __LINE__);
785         test_control_return(1);
786     }
787     if (host_video_1->ux_host_class_video_feature_unit_id != 5)
788     {
789         printf("ERROR #%d: wrong feature bUnitID 0x%lx\n", __LINE__, host_video_1->ux_host_class_video_feature_unit_id);
790         test_control_return(1);
791     }
792     if (host_video_1->ux_host_class_video_terminal_id != 2)
793     {
794         printf("ERROR #%d: wrong input bTerminalID 0x%lx\n", __LINE__, host_video_1->ux_host_class_video_terminal_id);
795         test_control_return(1);
796     }
797     if (host_video_1->ux_host_class_video_number_formats != 1)
798     {
799         printf("ERROR #%d: wrong VS_HEADER bNumFormats %ld\n", __LINE__, host_video_1->ux_host_class_video_number_formats);
800         test_control_return(1);
801     }
802     if (host_video_1->ux_host_class_video_length_formats != 0x004C)
803     {
804         printf("ERROR #%d: wrong VS_HEADER wTotalLength 0x%lx\n", __LINE__, host_video_1->ux_host_class_video_length_formats);
805         test_control_return(1);
806     }
807     if (host_video_1->ux_host_class_video_format_address !=
808         (host_video_1->ux_host_class_video_configuration_descriptor + 134))
809     {
810         printf("ERROR #%d: wrong VS_HEADER addr %p <> %p\n", __LINE__,
811             host_video_1->ux_host_class_video_format_address,
812             (host_video_1->ux_host_class_video_configuration_descriptor + 134));
813         test_control_return(1);
814     }
815 
816     if (host_video_2->ux_host_class_video_feature_unit_id != 5)
817     {
818         printf("ERROR #%d: wrong feature bUnitID 0x%lx\n", __LINE__, host_video_2->ux_host_class_video_feature_unit_id);
819         test_control_return(1);
820     }
821     if (host_video_2->ux_host_class_video_terminal_id != 2)
822     {
823         printf("ERROR #%d: wrong input bTerminalID 0x%lx\n", __LINE__, host_video_2->ux_host_class_video_terminal_id);
824         test_control_return(1);
825     }
826     if (host_video_2->ux_host_class_video_number_formats != 1)
827     {
828         printf("ERROR #%d: wrong VS_HEADER bNumFormats %ld\n", __LINE__, host_video_2->ux_host_class_video_number_formats);
829         test_control_return(1);
830     }
831     if (host_video_2->ux_host_class_video_length_formats != 120)
832     {
833         printf("ERROR #%d: wrong VS_HEADER wTotalLength 0x%lx\n", __LINE__, host_video_2->ux_host_class_video_length_formats);
834         test_control_return(1);
835     }
836     if (host_video_2->ux_host_class_video_format_address !=
837         (host_video_2->ux_host_class_video_configuration_descriptor + 249))
838     {
839         printf("ERROR #%d: wrong VS_HEADER addr %p <> %p\n", __LINE__,
840             host_video_2->ux_host_class_video_format_address,
841             (host_video_2->ux_host_class_video_configuration_descriptor + 249));
842         test_control_return(1);
843     }
844 
845     mem_free = ux_test_regular_memory_free();
846 
847     /* Test ioctl(UX_HOST_CLASS_VIDEO_IOCTL_GET_FORMAT_DATA) */
848     format_data.ux_host_class_video_parameter_format_requested = 0;
849     status = ux_host_class_video_ioctl(host_video_1, UX_HOST_CLASS_VIDEO_IOCTL_GET_FORMAT_DATA, &format_data);
850     UX_TEST_ASSERT(status == UX_HOST_CLASS_VIDEO_WRONG_TYPE);
851     format_data.ux_host_class_video_parameter_format_requested = 1;
852     status = ux_host_class_video_ioctl(host_video_1, UX_HOST_CLASS_VIDEO_IOCTL_GET_FORMAT_DATA, &format_data);
853     UX_TEST_ASSERT(status == UX_SUCCESS);
854     UX_TEST_ASSERT(format_data.ux_host_class_video_parameter_format_subtype == UX_HOST_CLASS_VIDEO_VS_FORMAT_MJPEG);
855     UX_TEST_ASSERT(format_data.ux_host_class_video_parameter_format_guid == UX_NULL);
856     UX_TEST_ASSERT(format_data.ux_host_class_video_parameter_number_frame_descriptors == 1);
857     format_data.ux_host_class_video_parameter_format_requested = 1;
858     status = ux_host_class_video_ioctl(host_video_2, UX_HOST_CLASS_VIDEO_IOCTL_GET_FORMAT_DATA, &format_data);
859     UX_TEST_ASSERT(status == UX_SUCCESS);
860     UX_TEST_ASSERT(format_data.ux_host_class_video_parameter_format_subtype == UX_HOST_CLASS_VIDEO_VS_FORMAT_H264);
861     UX_TEST_ASSERT(format_data.ux_host_class_video_parameter_format_guid == UX_NULL);
862     UX_TEST_ASSERT(format_data.ux_host_class_video_parameter_number_frame_descriptors == 1);
863 
864     /* Test _ux_host_class_video_frame_parameters_set.  */
865     status = _ux_host_class_video_frame_parameters_set(host_video_1,
866         UX_HOST_CLASS_VIDEO_VS_FORMAT_MJPEG, 160, 120, 666666);
867     UX_TEST_ASSERT_MESSAGE(status == UX_SUCCESS, "ERROR #%d: set parameters fail 0x%x\n", __LINE__, status);
868     _ux_utility_long_put(_probe_control_data + 22, 0);
869     status = _ux_host_class_video_frame_parameters_set(host_video_1,
870         UX_HOST_CLASS_VIDEO_VS_FORMAT_MJPEG, 160, 120, 666666);
871     UX_TEST_ASSERT_MESSAGE(status != UX_SUCCESS, "ERROR #%d: set parameters should fail\n", __LINE__);
872     _ux_utility_long_put(_probe_control_data + 22, 1024 * 3 + 1);
873     status = _ux_host_class_video_frame_parameters_set(host_video_1,
874         UX_HOST_CLASS_VIDEO_VS_FORMAT_MJPEG, 160, 120, 666666);
875     UX_TEST_ASSERT_MESSAGE(status != UX_SUCCESS, "ERROR #%d: set parameters should fail\n", __LINE__);
876     UX_TEST_ASSERT(mem_free == ux_test_regular_memory_free());
877 
878     _ux_utility_long_put(_probe_control_data + 22, 256);
879     status = _ux_host_class_video_frame_parameters_set(host_video_2,
880         UX_HOST_CLASS_VIDEO_VS_FORMAT_H264, 160, 120, 666666);
881     UX_TEST_ASSERT_MESSAGE(status == UX_SUCCESS, "ERROR #%d: set parameters fail 0x%x\n", __LINE__, status);
882     _ux_utility_long_put(_probe_control_data + 22, 0);
883     status = _ux_host_class_video_frame_parameters_set(host_video_2,
884         UX_HOST_CLASS_VIDEO_VS_FORMAT_H264, 160, 120, 666666);
885     UX_TEST_ASSERT_MESSAGE(status != UX_SUCCESS, "ERROR #%d: set parameters should fail\n", __LINE__);
886     _ux_utility_long_put(_probe_control_data + 22, 1024 * 3 + 1);
887     status = _ux_host_class_video_frame_parameters_set(host_video_2,
888         UX_HOST_CLASS_VIDEO_VS_FORMAT_H264, 160, 120, 666666);
889     UX_TEST_ASSERT_MESSAGE(status != UX_SUCCESS, "ERROR #%d: set parameters should fail\n", __LINE__);
890 
891     UX_TEST_ASSERT(mem_free == ux_test_regular_memory_free());
892 
893     /* Test video start (failed due to bandwidth 512 limit, see endpoint wMaxPacketSize).  */
894     _ux_utility_long_put(_probe_control_data + 22, 3072);
895     status = ux_host_class_video_start(host_video_1);
896     UX_TEST_ASSERT_MESSAGE(status != UX_SUCCESS, "ERROR #%d: start should fail\n", __LINE__);
897     UX_TEST_ASSERT(mem_free == ux_test_regular_memory_free());
898     status = ux_host_class_video_start(host_video_2);
899     UX_TEST_ASSERT_MESSAGE(status != UX_SUCCESS, "ERROR #%d: start should fail\n", __LINE__);
900     UX_TEST_ASSERT(mem_free == ux_test_regular_memory_free());
901 
902     /* Test video start (success).  */
903     _ux_utility_long_put(_probe_control_data + 22, 512);
904     status = ux_host_class_video_start(host_video_1);
905     UX_TEST_ASSERT_MESSAGE(status == UX_SUCCESS, "ERROR #%d: start fail 0x%x", __LINE__, status);
906     UX_TEST_ASSERT(mem_free == ux_test_regular_memory_free());
907     status = ux_host_class_video_stop(host_video_1);
908     UX_TEST_ASSERT(status == UX_SUCCESS);
909     status = ux_host_class_video_start(host_video_2);
910     UX_TEST_ASSERT_MESSAGE(status == UX_SUCCESS, "ERROR #%d: start fail 0x%x", __LINE__, status);
911     UX_TEST_ASSERT(mem_free == ux_test_regular_memory_free());
912 
913     /* Test disconnect. */
914     stepinfo(">>>>>>>>>>>>>>>> Test disconnect\n");
915     ux_test_dcd_sim_slave_disconnect();
916     ux_test_hcd_sim_host_disconnect();
917     if (host_video_1 != UX_NULL)
918     {
919 
920         printf("ERROR #13: instance not removed when disconnect");
921         test_control_return(1);
922     }
923 
924     /* Finally disconnect the device. */
925     ux_device_stack_disconnect();
926 
927     /* And deinitialize the class.  */
928     status  = ux_device_stack_class_unregister(_ux_system_slave_class_dpump_name, _ux_device_class_dummy_entry);
929     status |= ux_device_stack_class_unregister(_ux_system_slave_class_dpump_name, _ux_device_class_dummy_entry);
930 
931     /* Deinitialize the device side of usbx.  */
932     _ux_device_stack_uninitialize();
933 
934     /* And finally the usbx system resources.  */
935     _ux_system_uninitialize();
936 
937     /* Successful test.  */
938     printf("SUCCESS!\n");
939     test_control_return(0);
940 
941 }
942 
tx_test_thread_slave_simulation_entry(ULONG arg)943 void  tx_test_thread_slave_simulation_entry(ULONG arg)
944 {
945 
946     while(1)
947     {
948 
949         /* Sleep so ThreadX on Win32 will delete this thread. */
950         tx_thread_sleep(10);
951     }
952 }
953