1 /* This test is designed to test the simple video host/device class operation.  */
2 
3 #include <stdio.h>
4 #include "tx_api.h"
5 #include "ux_api.h"
6 #include "ux_system.h"
7 #include "ux_utility.h"
8 #include "ux_hcd_sim_host.h"
9 
10 #include "fx_api.h"
11 
12 #include "ux_device_class_video.h"
13 #include "ux_device_stack.h"
14 
15 #include "ux_host_class_video.h"
16 #include "ux_host_class_dummy.h"
17 
18 #include "ux_test_dcd_sim_slave.h"
19 #include "ux_test_hcd_sim_host.h"
20 #include "ux_test_utility_sim.h"
21 
22 
23 /* Define constants.  */
24 
25 #define                             UX_DEMO_REQUEST_MAX_LENGTH \
26     ((UX_HCD_SIM_HOST_MAX_PAYLOAD) > (UX_SLAVE_REQUEST_DATA_MAX_LENGTH) ? \
27         (UX_HCD_SIM_HOST_MAX_PAYLOAD) : (UX_SLAVE_REQUEST_DATA_MAX_LENGTH))
28 
29 #define                             UX_DEMO_DEBUG_SIZE  (4096*8)
30 #define                             UX_DEMO_STACK_SIZE  1024
31 #define                             UX_DEMO_BUFFER_SIZE (UX_DEMO_REQUEST_MAX_LENGTH + 1)
32 #define                             UX_DEMO_MEMORY_SIZE (128*1024)
33 #define                             UX_DEMO_ENDPOINT_SIZE 480
34 
35 #define                             UX_TEST_LOG_SIZE    (64)
36 
37 
38 /* Define local/extern function prototypes.  */
39 static void        test_thread_entry(ULONG);
40 static TX_THREAD   tx_test_thread_host_simulation;
41 static TX_THREAD   tx_test_thread_slave_simulation;
42 static void        tx_test_thread_host_simulation_entry(ULONG);
43 static void        tx_test_thread_slave_simulation_entry(ULONG);
44 
45 
46 /* Define global data structures.  */
47 static UCHAR                                    usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
48 
49 static UX_HOST_CLASS_DUMMY                      *dummy_control;
50 static UX_HOST_CLASS_DUMMY                      *dummy_tx;
51 static UX_HOST_CLASS_DUMMY                      *dummy_rx;
52 
53 static UX_DEVICE_CLASS_VIDEO                    *device_video;
54 static UX_DEVICE_CLASS_VIDEO_STREAM             *device_video_tx_stream;
55 static UX_DEVICE_CLASS_VIDEO_STREAM             *device_video_rx_stream;
56 static UX_DEVICE_CLASS_VIDEO_PARAMETER           device_video_parameter;
57 static UX_DEVICE_CLASS_VIDEO_STREAM_PARAMETER    device_video_stream_parameter[2];
58 
59 static UX_SLAVE_TRANSFER                        *device_video_tx_transfer;
60 static UX_SLAVE_TRANSFER                        *device_video_rx_transfer;
61 
62 static UX_HOST_CLASS_VIDEO                      *video;
63 
64 static ULONG                               error_counter;
65 
66 static ULONG                               set_cfg_counter;
67 
68 static ULONG                               rsc_mem_free_on_set_cfg;
69 static ULONG                               rsc_sem_on_set_cfg;
70 static ULONG                               rsc_sem_get_on_set_cfg;
71 static ULONG                               rsc_mutex_on_set_cfg;
72 
73 static ULONG                               rsc_enum_sem_usage;
74 static ULONG                               rsc_enum_sem_get_count;
75 static ULONG                               rsc_enum_mutex_usage;
76 static ULONG                               rsc_enum_mem_usage;
77 
78 static ULONG                               rsc_video_sem_usage;
79 static ULONG                               rsc_video_sem_get_count;
80 static ULONG                               rsc_video_mutex_usage;
81 static ULONG                               rsc_video_mem_usage;
82 
83 static ULONG                               interaction_count;
84 
85 static UCHAR                               error_callback_ignore = UX_TRUE;
86 static ULONG                               error_callback_counter;
87 
88 static struct BUFFER_LOG_STRUCT {
89     ULONG length;
90     UCHAR data[256];
91 } buffer_log[UX_TEST_LOG_SIZE];
92 static ULONG buffer_log_count = 0;
93 #define SAVE_BUFFER_LOG(buf,siz) do {                                                      \
94     if (buffer_log_count < UX_TEST_LOG_SIZE) {                                             \
95         ULONG __local_size__ = ((siz) > 256) ? 256 : (siz);                                \
96         buffer_log[buffer_log_count].length = (siz);                                       \
97         _ux_utility_memory_copy(buffer_log[buffer_log_count].data, (buf), __local_size__); \
98     }                                                                                      \
99     buffer_log_count ++;                                                                   \
100 } while(0)
101 
102 static ULONG test_tx_ack_count = 0xFFFFFFFF;
103 static ULONG test_tx_ins_count = 0;
104 static ULONG test_tx_ins_way   = 0;
105 
106 static struct CALLBACK_INVOKE_LOG_STRUCT {
107     VOID *func;
108     VOID *param1;
109     VOID *param2;
110     VOID *param3;
111 } callback_invoke_log[UX_TEST_LOG_SIZE];
112 static ULONG callback_invoke_count = 0;
113 
114 #define SAVE_CALLBACK_INVOKE_LOG(f,p1,p2,p3) do {                \
115     if (callback_invoke_count < UX_TEST_LOG_SIZE) {              \
116         callback_invoke_log[callback_invoke_count].func   = (VOID *)(f);  \
117         callback_invoke_log[callback_invoke_count].param1 = (VOID *)(p1); \
118         callback_invoke_log[callback_invoke_count].param2 = (VOID *)(p2); \
119         callback_invoke_log[callback_invoke_count].param3 = (VOID *)(p3); \
120         callback_invoke_count++;                                 \
121     }                                                            \
122 } while(0)
123 #define RESET_CALLBACK_INVOKE_LOG() do { \
124     callback_invoke_count = 0;           \
125 } while(0)
126 
127 /* Define device framework.  */
128 
129 #define W(d)    UX_DW0(d), UX_DW1(d)
130 #define DW(d)   UX_DW0(d), UX_DW1(d), UX_DW2(d), UX_DW3(d)
131 
132 #define _DEVICE_DESCRIPTOR()                                                                        \
133 /* --------------------------------------- Device Descriptor */                                     \
134 /* 0  bLength, bDescriptorType                               */ 18,   0x01,                         \
135 /* 2  bcdUSB                                                 */ UX_DW0(0x200),UX_DW1(0x200),        \
136 /* 4  bDeviceClass, bDeviceSubClass, bDeviceProtocol         */ 0x00, 0x00, 0x00,                   \
137 /* 7  bMaxPacketSize0                                        */ 0x08,                               \
138 /* 8  idVendor, idProduct                                    */ 0x84, 0x84, 0x01, 0x00,             \
139 /* 12 bcdDevice                                              */ UX_DW0(0x100),UX_DW1(0x100),        \
140 /* 14 iManufacturer, iProduct, iSerialNumber                 */ 0,    0,    0,                      \
141 /* 17 bNumConfigurations                                     */ 1,
142 
143 #define _DEVICE_QUALIFIER_DESCRIPTOR()                                                              \
144 /* ----------------------------- Device Qualifier Descriptor */                                     \
145 /* 0 bLength, bDescriptorType                                */ 10,                 0x06,           \
146 /* 2 bcdUSB                                                  */ UX_DW0(0x200),UX_DW1(0x200),        \
147 /* 4 bDeviceClass, bDeviceSubClass, bDeviceProtocol          */ 0x00,               0x00, 0x00,     \
148 /* 7 bMaxPacketSize0                                         */ 8,                                  \
149 /* 8 bNumConfigurations                                      */ 1,                                  \
150 /* 9 bReserved                                               */ 0,
151 
152 #define _CONFIGURE_DESCRIPTOR(total_len,n_ifc,cfg_v)                                                \
153 /* -------------------------------- Configuration Descriptor */                                     \
154 /* 0 bLength, bDescriptorType                                */ 9,    0x02,                         \
155 /* 2 wTotalLength                                            */ UX_DW0(total_len),UX_DW1(total_len),\
156 /* 4 bNumInterfaces, bConfigurationValue                     */ (n_ifc), (cfg_v),                   \
157 /* 6 iConfiguration                                          */ 0,                                  \
158 /* 7 bmAttributes, bMaxPower                                 */ 0x80, 50,
159 
160 #define _IAD_DESCRIPTOR(ifc_0,ifc_cnt,cls,sub,protocol)                                             \
161 /* ------------------------ Interface Association Descriptor */                                     \
162 /* 0 bLength, bDescriptorType                                */ 8,    0x0B,                         \
163 /* 2 bFirstInterface, bInterfaceCount                        */ (ifc_0), (ifc_cnt),                 \
164 /* 4 bFunctionClass, bFunctionSubClass, bFunctionProtocol    */ (cls), (sub), (protocol),           \
165 /* 7 iFunction                                               */ 0,
166 
167 #define _INTERFACE_DESCRIPTOR(ifc,alt,n_ep,cls,sub,protocol)                                        \
168 /* ------------------------------------ Interface Descriptor */                                     \
169 /* 0 bLength, bDescriptorType                                */ 9,    0x04,                         \
170 /* 2 bInterfaceNumber, bAlternateSetting                     */ (ifc), (alt),                       \
171 /* 4 bNumEndpoints                                           */ (n_ep),                             \
172 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ (cls), (sub), (protocol),           \
173 /* 8 iInterface                                              */ 0,
174 
175 #define _ENDPOINT_DESCRIPTOR(addr,attr,pkt_siz,interval)                                            \
176 /* ------------------------------------- Endpoint Descriptor */                                     \
177 /* 0  bLength, bDescriptorType                                */ 7,               0x05,             \
178 /* 2  bEndpointAddress, bmAttributes                          */ (addr),          (attr),           \
179 /* 4  wMaxPacketSize, bInterval                               */ UX_DW0(pkt_siz),UX_DW1(pkt_siz),(interval),
180 
181 #define _VC_DESCRIPTORS_LEN (14+17+9+17+9)
182 #define _VC_DESCRIPTORS()                                                                           \
183     /*--------------------------- Class VC Interface Descriptor (VC_HEADER).  */                    \
184     14, 0x24, 0x01, W(0x150),                                                                       \
185     W(_VC_DESCRIPTORS_LEN), /* wTotalLength.  */                                                    \
186     DW(6000000),  /* dwClockFrequency.  */                                                          \
187     2, /* bInCollection.  */                                                                        \
188     1, 2, /* BaInterfaceNr(2).  */                                                                  \
189     /*--------------------------- Input Terminal (VC_INPUT_TERMINAL, Camera)  */                    \
190     17, 0x24, 0x02,                                                                                 \
191     0x01, /* bTerminalID, ITT_CAMERA  */                                                            \
192     W(0x201), /* wTerminalType  */                                                                  \
193     0x00, 0x00, W(0), W(0), W(0),                                                                   \
194     0x02, W(0), /* bControlSize, bmControls  */                                                     \
195     /*---------------------------- Output Terminal (VC_OUTPUT_TERMINAL, USB)  */                    \
196     9, 0x24, 0x03,                                                                                  \
197     0x02, /* bTerminalID  */                                                                        \
198     W(0x0101), /* wTerminalType, TT_STREAMING  */                                                   \
199     0x00, 0x01/* bSourceID  */, 0x00,                                                               \
200     /*--------------------------- Input Terminal (VC_INPUT_TERMINAL, USB)  */                       \
201     17, 0x24, 0x02,                                                                                 \
202     0x03, /* bTerminalID  */                                                                        \
203     W(0x101), /* wTerminalType, TT_STREAMING  */                                                    \
204     0x00, 0x00, W(0), W(0), W(0),                                                                   \
205     0x02, W(0), /* bControlSize, bmControls  */                                                     \
206     /*---------------------------- Output Terminal (VC_OUTPUT_TERMINAL, DISPLAY)  */                \
207     9, 0x24, 0x03,                                                                                  \
208     0x04, /* bTerminalID  */                                                                        \
209     W(0x0301), /* wTerminalType, OTT_DISPLAY  */                                                    \
210     0x00, 0x03/* bSourceID  */, 0x00,
211 
212 #if 0
213     /*--------------------------------- Processing Unit (VC_PROCESSING_UNIT)  */                    \
214     12, 0x24, 0x05,                                                                                 \
215     , /* bUnitID  */                                                                                \
216     , /* bSourceID  */                                                                              \
217     W(0),                                                                                           \
218     3 /* bControlSize  */, 0, 0, 0 /*bmControls  */,                                                \
219     0x00, 0x00,                                                                                     \
220     /*--------------------------------- Processing Unit (VC_PROCESSING_UNIT)  */                    \
221     12, 0x24, 0x05,                                                                                 \
222     , /* bUnitID  */                                                                                \
223     , /* bSourceID  */                                                                              \
224     W(0),                                                                                           \
225     3 /* bControlSize  */, 0, 0, 0 /*bmControls  */,                                                \
226     0x00, 0x00,                                                                                     \
227 
228 #endif
229 
230 #define _VS_IN_DESCRIPTORS_LEN (14+11+38)
231 #define _VS_IN_DESCRIPTORS()                                                                        \
232     /*------------------------- Class VS Header Descriptor (VS_INPUT_HEADER)  */                    \
233     14, 0x24, 0x01,                                                                                 \
234     0X01, /* bNumFormats  */                                                                        \
235     W(_VS_IN_DESCRIPTORS_LEN), /* wTotalLength  */                                                  \
236     0x81, /* bEndpointAddress  */                                                                   \
237     0x00,                                                                                           \
238     0x02, /* bTerminalLink  */                                                                      \
239     0x00, /* bStillCaptureMethod  */                                                                \
240     0x00, 0x00, /* bTriggerSupport, bTriggerUsage  */                                               \
241     0x01, 0x00, /* bControlSize, bmaControls  */                                                    \
242     /*------------------------------- VS Format Descriptor (VS_FORMAT_MJPEG)  */                    \
243     11, 0x24, 0x06,                                                                                 \
244     0x01, /* bFormatIndex  */                                                                       \
245     0x01, /* bNumFrameDescriptors  */                                                               \
246     0x01, /* bmFlags  */                                                                            \
247     0x01, /* bDefaultFrameIndex  */                                                                 \
248     0x00, 0x00, 0x00, 0x00,                                                                         \
249     /*--------------------------------- VS Frame Descriptor (VS_FRAME_MJPEG)  */                    \
250     38, 0x24, 0x07,                                                                                 \
251     0x01, /* bFrameIndex  */                                                                        \
252     0x03, /* bmCapabilities  */                                                                     \
253     W(176), W(144), /* wWidth, wHeight  */                                                          \
254     DW(912384), DW(912384), /* dwMinBitRate, dwMaxBitRate  */                                       \
255     DW(38016), /* dwMaxVideoFrameBufSize  */                                                        \
256     DW(666666), /* dwDefaultFrameInterval  */                                                       \
257     0x00, /* bFrameIntervalType  */                                                                 \
258     DW(666666), DW(666666), DW(0), /* dwMinFrameInterval, dwMaxFrameInterval, dwFrameIntervalStep  */
259 
260 #define _VS_OUT_DESCRIPTORS_LEN (11+11+38)
261 #define _VS_OUT_DESCRIPTORS()                                                                       \
262     /*------------------------- Class VS Header Descriptor (VS_OUTPUT_HEADER)  */                   \
263     11, 0x24, 0x02,                                                                                 \
264     0x01, /* bNumFormats  */                                                                        \
265     W(_VS_OUT_DESCRIPTORS_LEN), /* wTotalLength  */                                                 \
266     0x02, /* bEndpointAddress  */                                                                   \
267     0x00,                                                                                           \
268     0x03, /* bTerminalLink  */                                                                      \
269     0x01, 0x00, /* bControlSize, bmaControls  */                                                    \
270     /*------------------------------- VS Format Descriptor (VS_FORMAT_MJPEG)  */                    \
271     11, 0x24, 0x06,                                                                                 \
272     0x01, /* bFormatIndex  */                                                                       \
273     0x01, /* bNumFrameDescriptors  */                                                               \
274     0x01, /* bmFlags  */                                                                            \
275     0x01, /* bDefaultFrameIndex  */                                                                 \
276     0x00, 0x00, 0x00, 0x00,                                                                         \
277     /*--------------------------------- VS Frame Descriptor (VS_FRAME_MJPEG)  */                    \
278     38, 0x24, 0x07,                                                                                 \
279     0x01, /* bFrameIndex  */                                                                        \
280     0x03, /* bmCapabilities  */                                                                     \
281     W(176), W(144), /* wWidth, wHeight  */                                                          \
282     DW(912384), DW(912384), /* dwMinBitRate, dwMaxBitRate  */                                       \
283     DW(38016), /* dwMaxVideoFrameBufSize  */                                                        \
284     DW(666666), /* dwDefaultFrameInterval  */                                                       \
285     0x00, /* bFrameIntervalType  */                                                                 \
286     DW(666666), DW(666666), DW(0), /* dwMinFrameInterval, dwMaxFrameInterval, dwFrameIntervalStep  */
287 
288 
289 #define _CONFIGURE_DESCRIPTORS_LEN (9+ 8+ 9+_VC_DESCRIPTORS_LEN+ 9+_VS_IN_DESCRIPTORS_LEN+9+7+ 9+_VS_OUT_DESCRIPTORS_LEN+9+7)
290 
291 static unsigned char device_framework_full_speed[] = {
292     _DEVICE_DESCRIPTOR()
293      _CONFIGURE_DESCRIPTOR(_CONFIGURE_DESCRIPTORS_LEN,3,1)
294       _IAD_DESCRIPTOR(0,3,0x0E,0x03,0x00)
295 
296        _INTERFACE_DESCRIPTOR(0,0,0,0x0E,0x01,0x01)
297         _VC_DESCRIPTORS()
298 
299        _INTERFACE_DESCRIPTOR(1,0,0,0x0E,0x02,0x00)
300         _VS_IN_DESCRIPTORS()
301         _INTERFACE_DESCRIPTOR(1,1,1,0x0E,0x02,0x00)
302         _ENDPOINT_DESCRIPTOR(0x81,0x05,UX_DEMO_ENDPOINT_SIZE,0x01)
303 
304        _INTERFACE_DESCRIPTOR(2,0,0,0x0E,0x02,0x00)
305         _VS_OUT_DESCRIPTORS()
306         _INTERFACE_DESCRIPTOR(2,1,1,0x0E,0x02,0x00)
307         _ENDPOINT_DESCRIPTOR(0x02,0x05,UX_DEMO_ENDPOINT_SIZE,0x01)
308 };
309 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
310 
311 static unsigned char device_framework_high_speed[] = {
312     _DEVICE_DESCRIPTOR()
313      _DEVICE_QUALIFIER_DESCRIPTOR()
314      _CONFIGURE_DESCRIPTOR(_CONFIGURE_DESCRIPTORS_LEN,3,1)
315       _IAD_DESCRIPTOR(0,3,0x0E,0x03,0x00)
316 
317        _INTERFACE_DESCRIPTOR(0,0,0,0x0E,0x01,0x01)
318         _VC_DESCRIPTORS()
319 
320        _INTERFACE_DESCRIPTOR(1,0,0,0x0E,0x02,0x00)
321         _VS_IN_DESCRIPTORS()
322         _INTERFACE_DESCRIPTOR(1,1,1,0x0E,0x02,0x00)
323         _ENDPOINT_DESCRIPTOR(0x81,0x05,UX_DEMO_ENDPOINT_SIZE,0x01)
324 
325        _INTERFACE_DESCRIPTOR(2,0,0,0x0E,0x02,0x00)
326         _VS_OUT_DESCRIPTORS()
327         _INTERFACE_DESCRIPTOR(2,1,1,0x0E,0x02,0x00)
328         _ENDPOINT_DESCRIPTOR(0x02,0x05,UX_DEMO_ENDPOINT_SIZE,0x01)
329 };
330 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
331 
332 static unsigned char string_framework[] = {
333 
334 /* Manufacturer string descriptor : Index 1 - "Express Logic" */
335     0x09, 0x04, 0x01, 0x0c,
336     0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
337     0x6f, 0x67, 0x69, 0x63,
338 
339 /* Product string descriptor : Index 2 - "EL Composite device" */
340     0x09, 0x04, 0x02, 0x13,
341     0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
342     0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
343     0x69, 0x63, 0x65,
344 
345 /* Serial Number string descriptor : Index 3 - "0001" */
346     0x09, 0x04, 0x03, 0x04,
347     0x30, 0x30, 0x30, 0x31
348 };
349 #define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
350 
351 
352 /* Multiple languages are supported on the device, to add
353     a language besides English, the Unicode language code must
354     be appended to the language_id_framework array and the length
355     adjusted accordingly. */
356 static unsigned char language_id_framework[] = {
357 
358 /* English. */
359     0x09, 0x04
360 };
361 #define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
362 
363 /* Setup requests */
364 
365 static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
366 static UX_TEST_SETUP _GetCfgDescr  = UX_TEST_SETUP_GetCfgDescr;
367 static UX_TEST_SETUP _SetAddress = UX_TEST_SETUP_SetAddress;
368 static UX_TEST_SETUP _GetDeviceDescriptor = UX_TEST_SETUP_GetDevDescr;
369 static UX_TEST_SETUP _GetConfigDescriptor = UX_TEST_SETUP_GetCfgDescr;
370 
371 /* Interaction define */
372 
373 #ifndef ux_device_class_video_payload_write
ux_device_class_video_payload_write(UX_DEVICE_CLASS_VIDEO_STREAM * stream,UCHAR * payload,ULONG length)374 static UINT ux_device_class_video_payload_write(UX_DEVICE_CLASS_VIDEO_STREAM *stream, UCHAR *payload, ULONG length)
375 {
376 
377 UX_SLAVE_ENDPOINT           *endpoint;
378 UX_SLAVE_DEVICE             *device;
379 UCHAR                       *next_payload_buffer;
380 ULONG                       payload_buffer_size;
381 
382 
383     /* Get the pointer to the device.  */
384     device =  &_ux_system_slave -> ux_system_slave_device;
385 
386     /* As long as the device is in the CONFIGURED state.  */
387     if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
388     {
389 
390         /* Cannot proceed with command, the interface is down.  */
391         return(UX_CONFIGURATION_HANDLE_UNKNOWN);
392     }
393 
394     /* Check if endpoint is available.  */
395     endpoint = stream -> ux_device_class_video_stream_endpoint;
396     if (endpoint == UX_NULL)
397         return(UX_ERROR);
398 
399     /* Check if endpoint direction is OK (IN).  */
400     if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == UX_ENDPOINT_OUT)
401         return(UX_ERROR);
402 
403     /* Check payload length.  */
404     payload_buffer_size = stream -> ux_device_class_video_stream_payload_buffer_size;
405     if ((payload_buffer_size - 4) < length)
406         return(UX_ERROR);
407 
408     /* Check overflow!!  */
409     if (stream -> ux_device_class_video_stream_access_pos == stream -> ux_device_class_video_stream_transfer_pos &&
410         stream -> ux_device_class_video_stream_access_pos -> ux_device_class_video_payload_length != 0)
411         return(UX_BUFFER_OVERFLOW);
412 
413     /* Calculate next payload buffer.  */
414     next_payload_buffer = (UCHAR *)stream -> ux_device_class_video_stream_access_pos;
415     next_payload_buffer += payload_buffer_size;
416     if (next_payload_buffer >= stream -> ux_device_class_video_stream_buffer + stream -> ux_device_class_video_stream_buffer_size)
417         next_payload_buffer = stream -> ux_device_class_video_stream_buffer;
418 
419     /* Copy payload.  */
420     _ux_utility_memory_copy(stream -> ux_device_class_video_stream_access_pos -> ux_device_class_video_payload_data, payload, length); /* Use case of memcpy is verified. */
421     stream -> ux_device_class_video_stream_access_pos -> ux_device_class_video_payload_length = length;
422 
423     /* Move payload position.  */
424     stream -> ux_device_class_video_stream_access_pos = (UX_DEVICE_CLASS_VIDEO_PAYLOAD *)next_payload_buffer;
425 
426     return(UX_SUCCESS);
427 }
428 #endif
429 
430 /* Hooks define */
431 
ux_device_class_video_tx_hook(struct UX_TEST_ACTION_STRUCT * action,VOID * params)432 static VOID ux_device_class_video_tx_hook(struct UX_TEST_ACTION_STRUCT *action, VOID *params)
433 {
434 
435 UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION_PARAMS *p = (UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION_PARAMS *)params;
436 UX_SLAVE_TRANSFER                                 *transfer = (UX_SLAVE_TRANSFER *)p -> parameter;
437 UCHAR                                              tmp[32] = {'i','n','s','e','r','t','A',0};
438 
439 
440     (void)params;
441     // printf("%s:%d tTX\n", UX_TEST_FILE, __LINE__);
442 
443     /* Acknowledge payload sent.  */
444     if (test_tx_ack_count)
445     {
446         SAVE_BUFFER_LOG(transfer -> ux_slave_transfer_request_data_pointer, transfer -> ux_slave_transfer_request_requested_length);
447         transfer -> ux_slave_transfer_request_actual_length = transfer -> ux_slave_transfer_request_requested_length;
448         transfer -> ux_slave_transfer_request_completion_code = UX_SUCCESS;
449         ux_test_dcd_sim_slave_transfer_done(transfer, UX_SUCCESS);
450     }
451     if (test_tx_ack_count != 0xFFFFFFFF && test_tx_ack_count > 0)
452         test_tx_ack_count --;
453 
454     /* Insert payloads when sent.  */
455     if (test_tx_ins_count)
456     {
457         tmp[6] = (test_tx_ins_count % 26) + 'A';
458         if (test_tx_ins_way == 0)
459             ux_device_class_video_payload_write(device_video_tx_stream, tmp, 32);
460         else
461         {
462 
463         UCHAR *payload;
464         ULONG payload_length;
465 
466 
467             ux_device_class_video_write_payload_get(device_video_tx_stream, &payload, &payload_length);
468             _ux_utility_memory_copy(payload, tmp, 32);
469             ux_device_class_video_write_payload_commit(device_video_tx_stream, 32);
470         }
471     }
472     if (test_tx_ins_count != 0xFFFFFFFF && test_tx_ins_count > 0)
473         test_tx_ins_count --;
474 }
475 
ux_device_class_video_rx_hook(struct UX_TEST_ACTION_STRUCT * action,VOID * params)476 static VOID ux_device_class_video_rx_hook(struct UX_TEST_ACTION_STRUCT *action, VOID *params)
477 {
478 
479 UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION_PARAMS *p = (UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION_PARAMS *)params;
480 UX_SLAVE_TRANSFER                                 *transfer = (UX_SLAVE_TRANSFER *)p -> parameter;
481 
482 
483     (void)action;
484     (void)params;
485     (void)p;
486     (void)transfer;
487     // printf("tRX\n");
488     device_video_rx_transfer = transfer;
489 }
device_video_rx_simulate_one_payload(UCHAR * payload,ULONG payload_length)490 static VOID device_video_rx_simulate_one_payload(UCHAR *payload, ULONG payload_length)
491 {
492     UX_TEST_ASSERT(device_video_rx_transfer);
493     if (payload_length)
494     {
495         _ux_utility_memory_copy(device_video_rx_transfer->ux_slave_transfer_request_data_pointer, payload, payload_length);
496         device_video_rx_transfer->ux_slave_transfer_request_actual_length = payload_length;
497         device_video_rx_transfer->ux_slave_transfer_request_completion_code = UX_SUCCESS;
498     }
499     ux_test_dcd_sim_slave_transfer_done(device_video_rx_transfer, UX_SUCCESS);
500     _ux_utility_thread_sleep(1);
501 }
502 
503 static UX_TEST_ACTION ux_device_class_video_transfer_hook[] =
504 {
505     {
506         .usbx_function = UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION,
507         .function = UX_DCD_TRANSFER_REQUEST,
508         .action_func = ux_device_class_video_tx_hook,
509         .req_setup = UX_NULL,
510         .req_action = UX_TEST_MATCH_EP,
511         .req_ep_address = 0x81,
512         .do_after = UX_FALSE,
513         .no_return = UX_FALSE,
514     },
515     {
516         .usbx_function = UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION,
517         .function = UX_DCD_TRANSFER_REQUEST,
518         .action_func = ux_device_class_video_rx_hook,
519         .req_setup = UX_NULL,
520         .req_action = UX_TEST_MATCH_EP,
521         .req_ep_address = 0x02,
522         .do_after = UX_FALSE,
523         .no_return = UX_FALSE,
524     },
525 { 0 },
526 };
527 
528 /* Define the ISR dispatch.  */
529 
530 extern VOID    (*test_isr_dispatch)(void);
531 
532 
533 /* Prototype for test control return.  */
534 
535 void  test_control_return(UINT status);
536 
error_callback(UINT system_level,UINT system_context,UINT error_code)537 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
538 {
539 
540     error_callback_counter ++;
541     // printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
542 
543     if (!error_callback_ignore)
544     {
545         {
546             /* Failed test.  */
547             test_control_return(1);
548         }
549     }
550 }
551 
sleep_break_on_error(VOID)552 static UINT  sleep_break_on_error(VOID)
553 {
554 
555     if (error_callback_counter >= 3)
556         return error_callback_counter;
557 
558     return UX_SUCCESS;
559 }
560 
561 /* Define the ISR dispatch routine.  */
562 
test_isr(void)563 static void    test_isr(void)
564 {
565 
566     /* For further expansion of interrupt-level testing.  */
567 }
568 
device_video_activate(VOID * video_instance)569 static VOID    device_video_activate(VOID *video_instance)
570 {
571     device_video = (UX_DEVICE_CLASS_VIDEO *)video_instance;
572     ux_device_class_video_stream_get(device_video, 0, &device_video_tx_stream);
573     ux_device_class_video_stream_get(device_video, 1, &device_video_rx_stream);
574     // printf("sVID:%p,%p,%p\n", video_instance, device_video_tx_stream, device_video_rx_stream);
575 }
device_video_deactivate(VOID * video_instance)576 static VOID    device_video_deactivate(VOID *video_instance)
577 {
578     if ((VOID *)device_video == video_instance)
579     {
580         device_video = UX_NULL;
581         device_video_tx_stream = UX_NULL;
582         device_video_rx_stream = UX_NULL;
583     }
584 }
device_video_tx_stream_change(UX_DEVICE_CLASS_VIDEO_STREAM * video,ULONG alt)585 static VOID    device_video_tx_stream_change(UX_DEVICE_CLASS_VIDEO_STREAM *video, ULONG alt)
586 {
587     SAVE_CALLBACK_INVOKE_LOG(device_video_tx_stream_change, video, (ALIGN_TYPE)alt, 0);
588 }
device_video_rx_stream_change(UX_DEVICE_CLASS_VIDEO_STREAM * video,ULONG alt)589 static VOID    device_video_rx_stream_change(UX_DEVICE_CLASS_VIDEO_STREAM *video, ULONG alt)
590 {
591     SAVE_CALLBACK_INVOKE_LOG(device_video_rx_stream_change, video, (ALIGN_TYPE)alt, 0);
592 
593     device_video_rx_transfer = UX_NULL;
594 }
device_video_vc_control_process(UX_DEVICE_CLASS_VIDEO * video,UX_SLAVE_TRANSFER * transfer)595 static UINT    device_video_vc_control_process(UX_DEVICE_CLASS_VIDEO *video, UX_SLAVE_TRANSFER *transfer)
596 {
597     SAVE_CALLBACK_INVOKE_LOG(device_video_vc_control_process, video, transfer, 0);
598     return(UX_ERROR);
599 }
device_video_vs_control_process(UX_DEVICE_CLASS_VIDEO_STREAM * video,UX_SLAVE_TRANSFER * transfer)600 static UINT    device_video_vs_control_process(UX_DEVICE_CLASS_VIDEO_STREAM *video, UX_SLAVE_TRANSFER *transfer)
601 {
602     SAVE_CALLBACK_INVOKE_LOG(device_video_vs_control_process, video, transfer, 0);
603     return(UX_ERROR);
604 }
device_video_tx_done(UX_DEVICE_CLASS_VIDEO_STREAM * video,ULONG length)605 static VOID    device_video_tx_done(UX_DEVICE_CLASS_VIDEO_STREAM *video, ULONG length)
606 {
607     SAVE_CALLBACK_INVOKE_LOG(device_video_tx_done, video, (ALIGN_TYPE)length, 0);
608 }
device_video_rx_done(UX_DEVICE_CLASS_VIDEO_STREAM * video,ULONG length)609 static VOID    device_video_rx_done(UX_DEVICE_CLASS_VIDEO_STREAM *video, ULONG length)
610 {
611     SAVE_CALLBACK_INVOKE_LOG(device_video_rx_done, video, (ALIGN_TYPE)length, 0);
612 }
613 
test_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)614 static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
615 {
616 
617 UX_HOST_CLASS_DUMMY *dummy = (UX_HOST_CLASS_DUMMY *) inst;
618 
619 
620     switch(event)
621     {
622 
623         case UX_DEVICE_INSERTION:
624 
625             // printf("hINS:%p,%p:%ld\n", cls, inst, dummy -> ux_host_class_dummy_interface -> ux_interface_descriptor.bInterfaceNumber);
626             switch(dummy -> ux_host_class_dummy_interface -> ux_interface_descriptor.bInterfaceNumber)
627             {
628             case 0: dummy_control = dummy; break;
629             case 1: dummy_rx      = dummy; break;
630             case 2: dummy_tx      = dummy; break;
631             }
632             break;
633 
634         case UX_DEVICE_REMOVAL:
635 
636             // printf("hRMV:%p,%p:%ld\n", cls, inst, dummy -> ux_host_class_dummy_interface -> ux_interface_descriptor.bInterfaceNumber);
637             switch(dummy -> ux_host_class_dummy_interface -> ux_interface_descriptor.bInterfaceNumber)
638             {
639             case 0: dummy_control = UX_NULL; break;
640             case 1: dummy_rx      = UX_NULL; break;
641             case 2: dummy_tx      = UX_NULL; break;
642             }
643             break;
644 
645         default:
646             break;
647     }
648     return 0;
649 }
650 
651 
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * params)652 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params)
653 {
654 
655     set_cfg_counter ++;
656 
657     rsc_mem_free_on_set_cfg = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
658     rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
659     rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
660 }
661 
662 
663 /* Define what the initial system looks like.  */
664 
665 #ifdef CTEST
test_application_define(void * first_unused_memory)666 void test_application_define(void *first_unused_memory)
667 #else
668 void    usbx_ux_device_video_basic_test_application_define(void *first_unused_memory)
669 #endif
670 {
671 
672 UINT                    status;
673 CHAR *                  stack_pointer;
674 CHAR *                  memory_pointer;
675 
676 
677     /* Inform user.  */
678     printf("Running Video Device Basic Functionality Test....................... ");
679 
680 #if !UX_TEST_MULTI_IFC_ON || !UX_TEST_MULTI_ALT_ON || !UX_TEST_MULTI_CLS_ON || \
681     (_CONFIGURE_DESCRIPTORS_LEN  > UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH)
682 #warning Tests skipped due to compile option!
683     printf("SKIP SUCCESS!\n");
684     test_control_return(0);
685     return;
686 #endif
687 
688     stepinfo("\n");
689 
690     /* Reset testing counts. */
691     ux_test_utility_sim_mutex_create_count_reset();
692     ux_test_utility_sim_sem_create_count_reset();
693     ux_test_utility_sim_sem_get_count_reset();
694     /* Reset error generations */
695     ux_test_utility_sim_sem_error_generation_stop();
696     ux_test_utility_sim_mutex_error_generation_stop();
697     ux_test_utility_sim_sem_get_error_generation_stop();
698 
699     /* Initialize the free memory pointer */
700     stack_pointer = (CHAR *) usbx_memory;
701     memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
702 
703     /* Initialize USBX Memory */
704     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
705     UX_TEST_CHECK_SUCCESS(status);
706 
707     /* Register the error callback. */
708     _ux_utility_error_callback_register(error_callback);
709 
710     /* The code below is required for installing the host portion of USBX */
711     status =  ux_host_stack_initialize(test_host_change_function);
712     UX_TEST_CHECK_SUCCESS(status);
713 
714     /* Register Audio class.  */
715     status  = ux_host_stack_class_register(_ux_host_class_dummy_name, _ux_host_class_dummy_entry);
716     UX_TEST_CHECK_SUCCESS(status);
717 
718     /* The code below is required for installing the device portion of USBX. No call back for
719        device status change in this example. */
720     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
721                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
722                                        string_framework, STRING_FRAMEWORK_LENGTH,
723                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
724     UX_TEST_CHECK_SUCCESS(status);
725 
726     /* Set the parameters for callback when insertion/extraction of a Video device, with IAD.  */
727 #if defined(UX_DEVICE_STANDALONE)
728     device_video_stream_parameter[0].ux_device_class_video_stream_parameter_task_function = ux_device_class_video_write_task_function;
729 #else
730     device_video_stream_parameter[0].ux_device_class_video_stream_parameter_thread_entry = ux_device_class_video_write_thread_entry;
731 #endif
732     device_video_stream_parameter[0].ux_device_class_video_stream_parameter_callbacks.ux_device_class_video_stream_change = device_video_tx_stream_change;
733     device_video_stream_parameter[0].ux_device_class_video_stream_parameter_callbacks.ux_device_class_video_stream_payload_done = device_video_tx_done;
734     device_video_stream_parameter[0].ux_device_class_video_stream_parameter_callbacks.ux_device_class_video_stream_request = device_video_vs_control_process;
735     device_video_stream_parameter[0].ux_device_class_video_stream_parameter_max_payload_buffer_size = UX_DEMO_ENDPOINT_SIZE;
736     device_video_stream_parameter[0].ux_device_class_video_stream_parameter_max_payload_buffer_nb   = 8;
737 #if defined(UX_DEVICE_STANDALONE)
738     device_video_stream_parameter[1].ux_device_class_video_stream_parameter_task_function = ux_device_class_video_read_task_function;
739 #else
740     device_video_stream_parameter[1].ux_device_class_video_stream_parameter_thread_entry = ux_device_class_video_read_thread_entry;
741 #endif
742     device_video_stream_parameter[1].ux_device_class_video_stream_parameter_callbacks.ux_device_class_video_stream_change = device_video_rx_stream_change;
743     device_video_stream_parameter[1].ux_device_class_video_stream_parameter_callbacks.ux_device_class_video_stream_payload_done = device_video_rx_done;
744     device_video_stream_parameter[1].ux_device_class_video_stream_parameter_callbacks.ux_device_class_video_stream_request = device_video_vs_control_process;
745     device_video_stream_parameter[1].ux_device_class_video_stream_parameter_max_payload_buffer_size = UX_DEMO_ENDPOINT_SIZE;
746     device_video_stream_parameter[1].ux_device_class_video_stream_parameter_max_payload_buffer_nb   = 8;
747     device_video_parameter.ux_device_class_video_parameter_streams = device_video_stream_parameter;
748     device_video_parameter.ux_device_class_video_parameter_streams_nb = 2;
749     device_video_parameter.ux_device_class_video_parameter_callbacks.ux_slave_class_video_instance_activate   = device_video_activate;
750     device_video_parameter.ux_device_class_video_parameter_callbacks.ux_slave_class_video_instance_deactivate = device_video_deactivate;
751     device_video_parameter.ux_device_class_video_parameter_callbacks.ux_device_class_video_request = device_video_vc_control_process;
752     device_video_parameter.ux_device_class_video_parameter_callbacks.ux_device_class_video_arg             = UX_NULL;
753 
754 #if 0
755     printf("Memory requirement UX_DEVICE_CLASS_:\n");
756     printf(" per _VIDEO: %d bytes\n", sizeof(UX_DEVICE_CLASS_VIDEO));
757     printf(" per _VIDEO_STREAM: %d bytes\n", sizeof(UX_DEVICE_CLASS_VIDEO_STREAM));
758     printf(" per _VIDEO_CONTROL: %d bytes\n", sizeof(UX_DEVICE_CLASS_VIDEO_CONTROL));
759     printf("Dynamic memory allocation:\n");
760     temp = (device_video_tx_stream_parameter.ux_device_class_video_stream_parameter_max_payload_buffer_size+8) *
761             device_video_tx_stream_parameter.ux_device_class_video_stream_parameter_max_payload_buffer_nb;
762     printf(" per _payload_buffer_size: (%ld + 8) * %ld = %ld\n",
763         device_video_tx_stream_parameter.ux_device_class_video_stream_parameter_max_payload_buffer_size,
764         device_video_tx_stream_parameter.ux_device_class_video_stream_parameter_max_payload_buffer_nb,
765         temp);
766     temp += sizeof(UX_DEVICE_CLASS_VIDEO_STREAM);
767     printf(" per _stream: _VIDEO_STREAM + _payload_buffer_size = %ld\n", temp);
768     temp += sizeof(UX_DEVICE_CLASS_VIDEO);
769     temp *= 2;
770     printf(" per _video: (_VIDEO + _stream * 1 + _CONTROL * 0) * 2 = %ld\n", temp);
771 #endif
772 
773     /* Initialize the device Audio class. This class owns interfaces starting with 1, 2. */
774     status  = ux_device_stack_class_register(_ux_system_device_class_video_name, ux_device_class_video_entry,
775                                              1, 0,  &device_video_parameter);
776     UX_TEST_CHECK_SUCCESS(status);
777 
778     /* Initialize the simulated device controller.  */
779     status =  _ux_test_dcd_sim_slave_initialize();
780     UX_TEST_CHECK_SUCCESS(status);
781 
782     /* Register all the USB host controllers available in this system */
783     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
784     UX_TEST_CHECK_SUCCESS(status);
785 
786     /* Create the main host simulation thread.  */
787     status =  tx_thread_create(&tx_test_thread_host_simulation, "tx demo host simulation", tx_test_thread_host_simulation_entry, 0,
788             stack_pointer, UX_DEMO_STACK_SIZE,
789             20, 20, 1, TX_AUTO_START);
790     UX_TEST_CHECK_SUCCESS(status);
791 
792     /* Create the main slave simulation  thread.  */
793     status =  tx_thread_create(&tx_test_thread_slave_simulation, "tx demo slave simulation", tx_test_thread_slave_simulation_entry, 0,
794             stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
795             20, 20, 1, TX_AUTO_START);
796     UX_TEST_CHECK_SUCCESS(status);
797 }
798 
test_wait_until_expected(VOID ** ptr,ULONG loop,VOID * expected)799 static UINT test_wait_until_expected(VOID **ptr, ULONG loop, VOID *expected)
800 {
801     while(loop)
802     {
803         _ux_utility_delay_ms(10);
804         if (*ptr == expected)
805             return UX_SUCCESS;
806     }
807     return UX_ERROR;
808 }
test_wait_until_not_expected(VOID ** ptr,ULONG loop,VOID * expected)809 static UINT test_wait_until_not_expected(VOID **ptr, ULONG loop, VOID *expected)
810 {
811     while(loop)
812     {
813         _ux_utility_delay_ms(10);
814         if (*ptr != expected)
815             return UX_SUCCESS;
816     }
817     return UX_ERROR;
818 }
819 #define test_wait_until_not_null(ptr, loop) test_wait_until_not_expected(ptr, loop, UX_NULL)
820 #define test_wait_until_null(ptr, loop) test_wait_until_expected(ptr, loop, UX_NULL)
821 
tx_test_thread_host_simulation_entry(ULONG arg)822 void  tx_test_thread_host_simulation_entry(ULONG arg)
823 {
824 
825 UINT                                                status;
826 ULONG                                               test_n;
827 // ULONG                                               mem_free;
828 UX_DEVICE                                           *device;
829 UX_CONFIGURATION                                    *configuration;
830 UX_INTERFACE                                        *interface;
831 UX_INTERFACE                                        *interface_inst[3][2];
832 // UX_ENDPOINT                                         *control_endpoint;
833 // UX_TRANSFER                                         *transfer_request;
834 UCHAR                                               test_cmp[32];
835 ULONG                                               temp;
836 UCHAR                                               *temp_buf;
837 
838 
839     /* Test connect.  */
840     status  = test_wait_until_not_null((void**)&dummy_control, 100);
841     status |= test_wait_until_not_null((void**)&dummy_tx, 100);
842     status |= test_wait_until_not_null((void**)&dummy_rx, 100);
843     status |= test_wait_until_not_null((void**)&device_video, 100);
844     status |= test_wait_until_not_null((void**)&device_video_rx_stream, 100);
845     status |= test_wait_until_not_null((void**)&device_video_tx_stream, 100);
846     UX_TEST_CHECK_SUCCESS(status);
847 
848     // /* Test disconnect. */
849     // ux_test_dcd_sim_slave_disconnect();
850     // ux_test_hcd_sim_host_disconnect();
851 
852     // /* Reset testing counts. */
853     // ux_test_utility_sim_mutex_create_count_reset();
854     // ux_test_utility_sim_sem_create_count_reset();
855     // ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
856     // /* Save free memory usage. */
857     // mem_free = _ux_system->ux_system_regular_memory_pool_free;
858     // ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
859     // ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
860     // tx_thread_sleep(100);
861     // /* Log create counts for further tests. */
862     // rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
863     // rsc_enum_sem_usage = rsc_sem_on_set_cfg;
864     // rsc_enum_mem_usage = mem_free - rsc_mem_free_on_set_cfg;
865     // /* Log create counts when instances active for further tests. */
866     // rsc_cdc_mutex_usage = ux_test_utility_sim_mutex_create_count() - rsc_enum_mutex_usage;
867     // rsc_cdc_sem_usage = ux_test_utility_sim_sem_create_count() - rsc_enum_sem_usage;
868     // rsc_cdc_mem_usage = rsc_mem_free_on_set_cfg - _ux_system->ux_system_regular_memory_pool_free;
869     // stepinfo("mem free: %ld\n", _ux_system->ux_system_regular_memory_pool_free);
870 
871     /* Validate configuration descriptors.  */
872     /* ... */
873 
874     /* Get testing instances.  */
875 
876     status = ux_host_stack_device_get(0, &device);
877     UX_TEST_CHECK_SUCCESS(status);
878 
879     // control_endpoint = &device->ux_device_control_endpoint;
880     // transfer_request = &control_endpoint->ux_endpoint_transfer_request;
881 
882     status = ux_host_stack_device_configuration_get(device, 0, &configuration);
883     UX_TEST_CHECK_SUCCESS(status);
884 
885     interface = configuration -> ux_configuration_first_interface;
886     while(interface)
887     {
888         // printf("Interface: %ld.%ld\n", interface -> ux_interface_descriptor.bInterfaceNumber, interface -> ux_interface_descriptor.bAlternateSetting);
889         interface_inst[interface -> ux_interface_descriptor.bInterfaceNumber][interface -> ux_interface_descriptor.bAlternateSetting] = interface;
890         interface = interface -> ux_interface_next_interface;
891     }
892 
893     /* Test interface change.  */
894     /* Reset log.  */
895     RESET_CALLBACK_INVOKE_LOG();
896     status  = ux_host_stack_interface_setting_select(interface_inst[1][1]);
897     status |= ux_host_stack_interface_setting_select(interface_inst[1][0]);
898     status |= ux_host_stack_interface_setting_select(interface_inst[1][1]);
899 
900     UX_TEST_CHECK_SUCCESS(status);
901     UX_TEST_ASSERT(callback_invoke_count == 3);
902     UX_TEST_ASSERT(callback_invoke_log[0].func == device_video_tx_stream_change);
903     UX_TEST_ASSERT(callback_invoke_log[0].param1 == device_video_tx_stream);
904     UX_TEST_ASSERT(callback_invoke_log[0].param2 == (VOID*)1);
905     UX_TEST_ASSERT(callback_invoke_log[1].func == device_video_tx_stream_change);
906     UX_TEST_ASSERT(callback_invoke_log[1].param1 == device_video_tx_stream);
907     UX_TEST_ASSERT(callback_invoke_log[1].param2 == 0);
908 
909     RESET_CALLBACK_INVOKE_LOG();
910     status  = ux_host_stack_interface_setting_select(interface_inst[2][1]);
911     status |= ux_host_stack_interface_setting_select(interface_inst[2][0]);
912     status |= ux_host_stack_interface_setting_select(interface_inst[2][1]);
913 
914     UX_TEST_CHECK_SUCCESS(status);
915     UX_TEST_ASSERT(callback_invoke_count == 3);
916     UX_TEST_ASSERT(callback_invoke_log[0].func == device_video_rx_stream_change);
917     UX_TEST_ASSERT(callback_invoke_log[0].param1 == device_video_rx_stream);
918     UX_TEST_ASSERT(callback_invoke_log[0].param2 == (VOID*)1);
919     UX_TEST_ASSERT(callback_invoke_log[1].func == device_video_rx_stream_change);
920     UX_TEST_ASSERT(callback_invoke_log[1].param1 == device_video_rx_stream);
921     UX_TEST_ASSERT(callback_invoke_log[1].param2 == 0);
922 
923     /* Test data streaming.  */
924 
925     /* Wrong interface!  */
926     status  = ux_device_class_video_transmission_start(device_video_rx_stream);
927     status |= ux_device_class_video_reception_start(device_video_tx_stream);
928     UX_TEST_CHECK_NOT_SUCCESS(status);
929 
930     ux_test_link_hooks_from_array(ux_device_class_video_transfer_hook);
931 
932     /* ------------------ Write test.  */
933 
934     status  = ux_device_class_video_payload_write(device_video_tx_stream, "test0", 16);
935     status |= ux_device_class_video_payload_write(device_video_tx_stream, "test1", 16);
936     status |= ux_device_class_video_payload_write(device_video_tx_stream, "test2", 16);
937     status |= ux_device_class_video_payload_write(device_video_tx_stream, "test3", 16);
938     status |= ux_device_class_video_payload_write(device_video_tx_stream, "test4", 16);
939     status |= ux_device_class_video_payload_write(device_video_tx_stream, "test5", 16);
940     status |= ux_device_class_video_payload_write(device_video_tx_stream, "test6", 16);
941     status |= ux_device_class_video_payload_write(device_video_tx_stream, "test7", 16);
942     UX_TEST_CHECK_SUCCESS(status);
943 
944     error_callback_counter = 0;
945     status = ux_device_class_video_payload_write(device_video_tx_stream, "test8", 16);
946     UX_TEST_CHECK_CODE(UX_BUFFER_OVERFLOW, status);
947 
948     /*
949      Keep sending until under-run.
950      No buffer appended while running.
951      */
952 
953     buffer_log_count = 0;
954     test_tx_ack_count = 10;
955     status  = ux_device_class_video_transmission_start(device_video_tx_stream);
956     UX_TEST_CHECK_SUCCESS(status);
957 
958     /* Delay to let thread runs.  */
959     _ux_utility_delay_ms(100);
960 
961     /* Prepare data for checking.  */
962     _ux_utility_memory_set(test_cmp, 0, 16);
963     _ux_utility_memory_copy(test_cmp, "test", 4);
964 
965     /* 8 frame should be available.  */
966     for (test_n = 0; test_n < 8; test_n ++)
967     {
968         // printf("%ld: %ld: %s\n", test_n, buffer_log[test_n].length, buffer_log[test_n].data);
969         test_cmp[4] = (UCHAR)(test_n + '0');
970 
971         UX_TEST_ASSERT(buffer_log[test_n].length == 16);
972 
973         status = _ux_utility_memory_compare(buffer_log[test_n].data, test_cmp, 6);
974         UX_TEST_CHECK_SUCCESS(status);
975     }
976     /* Then under-run, 0 length packets.  */
977     for(;test_n < buffer_log_count; test_n ++)
978     {
979         // printf("%ld: %ld\n", test_n, buffer_log[test_n].length);
980         UX_TEST_ASSERT(buffer_log[test_n].length == 0);
981     }
982 
983     /*
984      Keep sending until under-run.
985      Specific number of buffer appended while running.
986      */
987 
988     for (test_tx_ins_way = 0; test_tx_ins_way < 2; test_tx_ins_way ++)
989     {
990 
991         /* Switch interface to clean up status.  */
992         status  = ux_host_stack_interface_setting_select(interface_inst[1][0]);
993         status |= ux_host_stack_interface_setting_select(interface_inst[1][1]);
994 
995         status  = ux_device_class_video_payload_write(device_video_tx_stream, "test0", 20);
996         status |= ux_device_class_video_payload_write(device_video_tx_stream, "test1", 20);
997         status |= ux_device_class_video_payload_write(device_video_tx_stream, "test2", 20);
998         status |= ux_device_class_video_payload_write(device_video_tx_stream, "test3", 20);
999         UX_TEST_CHECK_SUCCESS(status);
1000 
1001         test_tx_ins_count = 10;
1002         test_tx_ack_count = 20;
1003         buffer_log_count  = 0;
1004         status  = ux_device_class_video_transmission_start(device_video_tx_stream);
1005         UX_TEST_CHECK_SUCCESS(status);
1006 
1007         /* Delay to let thread runs.  */
1008         _ux_utility_delay_ms(300);
1009 
1010         /* Prepare data for checking.  */
1011         _ux_utility_memory_set(test_cmp, 0, 32);
1012 
1013         /* 4 frame should be available.  */
1014         _ux_utility_memory_copy(test_cmp, "test", 4);
1015         for (test_n = 0; test_n < 4; test_n ++)
1016         {
1017             // printf("%ld: %ld: %s\n", test_n, buffer_log[test_n].length, buffer_log[test_n].data);
1018             test_cmp[4] = (UCHAR)(test_n + '0');
1019 
1020             UX_TEST_ASSERT(buffer_log[test_n].length == 20);
1021 
1022             status = _ux_utility_memory_compare(buffer_log[test_n].data, test_cmp, 6);
1023             UX_TEST_CHECK_SUCCESS(status);
1024         }
1025         /* 10 more frame should be available.  */
1026         _ux_utility_memory_copy(test_cmp, "insert", 6);
1027         for (; test_n < 14; test_n ++)
1028         {
1029             // printf("%ld: %ld: %s\n", test_n, buffer_log[test_n].length, buffer_log[test_n].data);
1030             test_cmp[6] = (UCHAR)(((10 - (test_n - 4)) % 26) + 'A');
1031 
1032             UX_TEST_ASSERT(buffer_log[test_n].length == 32);
1033 
1034             status = _ux_utility_memory_compare(buffer_log[test_n].data, test_cmp, 8);
1035             UX_TEST_CHECK_SUCCESS(status);
1036         }
1037         /* Then under-run, 0 length packets.  */
1038         for(;test_n < buffer_log_count; test_n ++)
1039         {
1040             // printf("%ld: %ld\n", test_n, buffer_log[test_n].length);
1041             UX_TEST_ASSERT(buffer_log[test_n].length == 0);
1042         }
1043     }
1044 
1045     UX_TEST_ASSERT(device_video_tx_stream->ux_device_class_video_stream_transfer_pos == device_video_tx_stream->ux_device_class_video_stream_access_pos);
1046 
1047 
1048     /* ------------------ Read test.  */
1049 
1050     UX_TEST_ASSERT(device_video_rx_transfer == UX_NULL);
1051 
1052     temp = 0;
1053     status = ux_device_class_video_read_payload_get(device_video_rx_stream, &temp_buf, &temp);
1054     UX_TEST_CHECK_CODE(UX_BUFFER_OVERFLOW, status);
1055 
1056     status = ux_device_class_video_reception_start(device_video_rx_stream);
1057     UX_TEST_CHECK_SUCCESS(status);
1058     _ux_utility_thread_sleep(1);
1059 
1060     UX_TEST_ASSERT(device_video_rx_transfer != UX_NULL);
1061 
1062     status = ux_device_class_video_read_payload_get(device_video_rx_stream, &temp_buf, &temp);
1063     UX_TEST_CHECK_CODE(UX_BUFFER_OVERFLOW, status);
1064 
1065     RESET_CALLBACK_INVOKE_LOG();
1066 
1067     device_video_rx_simulate_one_payload("012345", 6);
1068     status = ux_device_class_video_read_payload_get(device_video_rx_stream, &temp_buf, &temp);
1069     UX_TEST_CHECK_SUCCESS(status);
1070     for (test_n = 0; test_n < 6; test_n ++)
1071     {
1072         UX_TEST_ASSERT(temp_buf[test_n] == (test_n + '0'));
1073     }
1074     ux_device_class_video_read_payload_free(device_video_rx_stream);
1075 
1076     device_video_rx_simulate_one_payload("012345", 6);
1077     device_video_rx_simulate_one_payload("67", 2);
1078     device_video_rx_simulate_one_payload("89", 2);
1079 
1080     status = ux_device_class_video_read_payload_get(device_video_rx_stream, &temp_buf, &temp);
1081     UX_TEST_CHECK_SUCCESS(status);
1082     UX_TEST_ASSERT(temp == 6);
1083     for (test_n = 0; test_n < 6; test_n ++)
1084     {
1085         UX_TEST_ASSERT(temp_buf[test_n] == (test_n + '0'));
1086     }
1087     ux_device_class_video_read_payload_free(device_video_rx_stream);
1088     status = ux_device_class_video_read_payload_get(device_video_rx_stream, &temp_buf, &temp);
1089     UX_TEST_CHECK_SUCCESS(status);
1090     UX_TEST_ASSERT(temp == 2);
1091     for (; test_n < 8; test_n ++)
1092     {
1093         UX_TEST_ASSERT(temp_buf[test_n-6] == (test_n + '0'));
1094     }
1095     ux_device_class_video_read_payload_free(device_video_rx_stream);
1096     status = ux_device_class_video_read_payload_get(device_video_rx_stream, &temp_buf, &temp);
1097     UX_TEST_CHECK_SUCCESS(status);
1098     UX_TEST_ASSERT(temp == 2);
1099     for (; test_n < 10; test_n ++)
1100     {
1101         UX_TEST_ASSERT(temp_buf[test_n-8] == (test_n + '0'));
1102     }
1103     ux_device_class_video_read_payload_free(device_video_rx_stream);
1104 
1105     UX_TEST_ASSERT(callback_invoke_count == 4);
1106     UX_TEST_ASSERT(callback_invoke_log[0].func == device_video_rx_done);
1107     UX_TEST_ASSERT(callback_invoke_log[0].param1 == device_video_rx_stream);
1108     UX_TEST_ASSERT(callback_invoke_log[1].func == device_video_rx_done);
1109     UX_TEST_ASSERT(callback_invoke_log[1].param1 == device_video_rx_stream);
1110     UX_TEST_ASSERT(callback_invoke_log[2].func == device_video_rx_done);
1111     UX_TEST_ASSERT(callback_invoke_log[2].param1 == device_video_rx_stream);
1112     UX_TEST_ASSERT(callback_invoke_log[3].func == device_video_rx_done);
1113     UX_TEST_ASSERT(callback_invoke_log[3].param1 == device_video_rx_stream);
1114 
1115     RESET_CALLBACK_INVOKE_LOG();
1116     error_callback_counter = 0;
1117     for (test_n = 0; test_n < 10; test_n ++)
1118     {
1119         test_cmp[0] = (UCHAR)(test_n + '0');
1120         device_video_rx_simulate_one_payload(test_cmp, 1);
1121     }
1122 
1123     UX_TEST_ASSERT(callback_invoke_count == 10);
1124     UX_TEST_ASSERT(error_callback_counter == 3);
1125     for (test_n = 0; test_n < 7; test_n ++)
1126     {
1127         status = ux_device_class_video_read_payload_get(device_video_rx_stream, &temp_buf, &temp);
1128         UX_TEST_CHECK_SUCCESS(status);
1129         UX_TEST_ASSERT(temp == 1);
1130         UX_TEST_ASSERT(temp_buf[0] == (test_n + '0'));
1131         ux_device_class_video_read_payload_free(device_video_rx_stream);
1132     }
1133     UX_TEST_CHECK_SUCCESS(ux_device_class_video_read_payload_get(device_video_rx_stream, &temp_buf, &temp));
1134     UX_TEST_ASSERT(temp == 1);
1135     UX_TEST_ASSERT(temp_buf[0] == '9');
1136     ux_device_class_video_read_payload_free(device_video_rx_stream);
1137     UX_TEST_CHECK_CODE(UX_BUFFER_OVERFLOW, ux_device_class_video_read_payload_get(device_video_rx_stream, &temp_buf, &temp));
1138 
1139 
1140     /* Wait pending threads.  */
1141     _ux_utility_thread_sleep(1);
1142 
1143     /* Finally disconnect the device. */
1144     ux_device_stack_disconnect();
1145 
1146     /* And deinitialize the class.  */
1147     ux_device_stack_class_unregister(_ux_system_device_class_video_name, ux_device_class_video_entry);
1148 
1149     /* Deinitialize the device side of usbx.  */
1150     _ux_device_stack_uninitialize();
1151 
1152     /* And finally the usbx system resources.  */
1153     _ux_system_uninitialize();
1154 
1155     /* Successful test.  */
1156     printf("SUCCESS!\n");
1157     test_control_return(0);
1158 
1159 }
1160 
1161 
1162 
tx_test_thread_slave_simulation_entry(ULONG arg)1163 void  tx_test_thread_slave_simulation_entry(ULONG arg)
1164 {
1165     while(1)
1166     {
1167 
1168 #if defined(UX_DEVICE_STANDALONE)
1169 
1170         /* Standalone background task.  */
1171         ux_system_tasks_run();
1172 #else
1173 
1174         /* Sleep so ThreadX on Win32 will delete this thread. */
1175         tx_thread_sleep(10);
1176 #endif
1177     }
1178 }
1179