1 /* This test is designed to test the ux_utility_descriptor_parse. */
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 "ux_host_stack.h"
10 #include "ux_device_stack.h"
11
12 #include "ux_device_class_cdc_acm.h"
13 #include "ux_host_class_cdc_acm.h"
14
15 #include "ux_host_class_dpump.h"
16 #include "ux_device_class_dpump.h"
17
18 #include "ux_host_class_hid.h"
19 #include "ux_device_class_hid.h"
20
21 #include "ux_host_class_storage.h"
22 #include "ux_device_class_storage.h"
23
24 #include "ux_test_dcd_sim_slave.h"
25 #include "ux_test_hcd_sim_host.h"
26 #include "ux_test_utility_sim.h"
27
28
29 /* Define USBX test constants. */
30
31 #define UX_TEST_STACK_SIZE 4096
32 #define UX_TEST_BUFFER_SIZE 2048
33 #define UX_TEST_RUN 1
34 #define UX_TEST_MEMORY_SIZE (64*1024)
35
36 #define LSB(x) ( (x) & 0x00ff)
37 #define MSB(x) (((x) & 0xff00) >> 8)
38
39 /* Configuration descriptor 9 bytes */
40 #define CFG_DESC(wTotalLength, bNumInterfaces, bConfigurationValue)\
41 /* Configuration 1 descriptor 9 bytes */\
42 0x09, 0x02, LSB(wTotalLength), MSB(wTotalLength),\
43 (bNumInterfaces), (bConfigurationValue), 0x00,\
44 0x40, 0x00,
45 #define CFG_DESC_LEN 9
46
47 /* DPUMP interface descriptors. */
48 #define DPUMP_IFC_DESC(ifc, alt, nb_ep) \
49 /* Interface descriptor */\
50 0x09, 0x04, (ifc), (alt), (nb_ep), 0x99, 0x99, 0x99, 0x00,
51
52 #define DPUMP_IFC_EP_DESC(epaddr, eptype, epsize) \
53 /* Endpoint descriptor */\
54 0x07, 0x05, (epaddr), (eptype), LSB(epsize), MSB(epsize), 0x01,
55
56 #define DPUMP_IFC_DESC_ALL_LEN(nb_ep) (9 + (nb_ep) * 7)
57
58 #define CFG_DESC_ALL_LEN (CFG_DESC_LEN + DPUMP_IFC_DESC_ALL_LEN(4))
59
60 #define CFG_DESC_ALL \
61 CFG_DESC(CFG_DESC_ALL_LEN, 1, 1)\
62 DPUMP_IFC_DESC(0, 0, 4)\
63 DPUMP_IFC_EP_DESC(0x81, 2, 64)\
64 DPUMP_IFC_EP_DESC(0x02, 2, 64)\
65 DPUMP_IFC_EP_DESC(0x83, 1, 64)\
66 DPUMP_IFC_EP_DESC(0x84, 3, 64)\
67
68 /* Define the counters used in the test application... */
69
70 static ULONG thread_0_counter;
71 static ULONG thread_1_counter;
72 static ULONG error_counter;
73
74 static UCHAR error_callback_ignore = UX_FALSE;
75 static ULONG error_callback_counter;
76
77 static UCHAR buffer[UX_TEST_BUFFER_SIZE];
78
79 /* Define USBX test global variables. */
80
81 static UX_HOST_CLASS *class_driver;
82 static UX_HOST_CLASS_DPUMP *dpump;
83 static UX_SLAVE_CLASS_DPUMP *dpump_slave = UX_NULL;
84
85 static UCHAR device_framework_full_speed[] = {
86
87 /* Device descriptor 18 bytes */
88 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
89 0xec, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
90 0x00, 0x01,
91
92 CFG_DESC_ALL
93 };
94 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
95
96 static UCHAR device_framework_high_speed[] = {
97
98 /* Device descriptor */
99 0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
100 0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
101 0x03, 0x01,
102
103 /* Device qualifier descriptor */
104 0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
105 0x01, 0x00,
106
107 CFG_DESC_ALL
108 };
109 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
110
111 /* String Device Framework :
112 Byte 0 and 1 : Word containing the language ID : 0x0904 for US
113 Byte 2 : Byte containing the index of the descriptor
114 Byte 3 : Byte containing the length of the descriptor string
115 */
116
117 static UCHAR string_framework[] = {
118
119 /* Manufacturer string descriptor : Index 1 */
120 0x09, 0x04, 0x01, 0x0c,
121 0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
122 0x6f, 0x67, 0x69, 0x63,
123
124 /* Product string descriptor : Index 2 */
125 0x09, 0x04, 0x02, 0x0c,
126 0x44, 0x61, 0x74, 0x61, 0x50, 0x75, 0x6d, 0x70,
127 0x44, 0x65, 0x6d, 0x6f,
128
129 /* Serial Number string descriptor : Index 3 */
130 0x09, 0x04, 0x03, 0x04,
131 0x30, 0x30, 0x30, 0x31
132 };
133 #define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
134
135 /* Multiple languages are supported on the device, to add
136 a language besides English, the unicode language code must
137 be appended to the language_id_framework array and the length
138 adjusted accordingly. */
139 static UCHAR language_id_framework[] = {
140
141 /* English. */
142 0x09, 0x04
143 };
144 #define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
145
146 /* Define prototypes for external Host Controller's (HCDs), classes and clients. */
147
148 static VOID ux_test_instance_activate(VOID *dpump_instance);
149 static VOID ux_test_instance_deactivate(VOID *dpump_instance);
150
151 UINT _ux_host_class_dpump_entry(UX_HOST_CLASS_COMMAND *command);
152 UINT ux_hcd_sim_initialize(UX_HCD *hcd);
153 UINT _ux_host_class_dpump_write(UX_HOST_CLASS_DPUMP *dpump, UCHAR * data_pointer,
154 ULONG requested_length, ULONG *actual_length);
155 UINT _ux_host_class_dpump_read (UX_HOST_CLASS_DPUMP *dpump, UCHAR *data_pointer,
156 ULONG requested_length, ULONG *actual_length);
157
158 static TX_THREAD ux_test_thread_simulation_0;
159 static TX_THREAD ux_test_thread_simulation_1;
160 static void ux_test_thread_simulation_0_entry(ULONG);
161 static void ux_test_thread_simulation_1_entry(ULONG);
162
163
164 /* Define the ISR dispatch. */
165
166 extern VOID (*test_isr_dispatch)(void);
167
168
169 /* Prototype for test control return. */
170
171 void test_control_return(UINT status);
172
173 /* Simulator actions. */
174
175 static UX_TEST_HCD_SIM_ACTION endpoint0x83_create_del_skip[] = {
176 /* function, request to match,
177 port action, port status,
178 request action, request EP, request data, request actual length, request status,
179 status, additional callback,
180 no_return */
181 { UX_HCD_CREATE_ENDPOINT, NULL,
182 UX_FALSE, 0,
183 UX_TEST_MATCH_EP, 0x83, UX_NULL, 0, 0,
184 UX_SUCCESS},
185 { UX_HCD_CREATE_ENDPOINT, NULL,
186 UX_FALSE, 0,
187 UX_TEST_MATCH_EP, 0x83, UX_NULL, 0, 0,
188 UX_SUCCESS},
189 { 0 }
190 };
191
192 /* Define the ISR dispatch routine. */
193
test_isr(void)194 static void test_isr(void)
195 {
196
197 /* For further expansion of interrupt-level testing. */
198 }
199
200
error_callback(UINT system_level,UINT system_context,UINT error_code)201 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
202 {
203
204 error_callback_counter ++;
205
206 if (!error_callback_ignore)
207 {
208 {
209 /* Failed test. */
210 printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
211 // test_control_return(1);
212 }
213 }
214 }
215
break_on_dpump_ready(VOID)216 static UINT break_on_dpump_ready(VOID)
217 {
218
219 UINT status;
220 UX_HOST_CLASS *class;
221
222 /* Find the main data pump container. */
223 status = ux_host_stack_class_get(_ux_system_host_class_dpump_name, &class);
224 if (status != UX_SUCCESS)
225 /* Do not break. */
226 return UX_SUCCESS;
227
228 /* Find the instance. */
229 status = ux_host_stack_class_instance_get(class, 0, (VOID **) &dpump);
230 if (status != UX_SUCCESS)
231 /* Do not break. */
232 return UX_SUCCESS;
233
234 if (dpump -> ux_host_class_dpump_state != UX_HOST_CLASS_INSTANCE_LIVE)
235 /* Do not break. */
236 return UX_SUCCESS;
237
238 return 1;
239 }
240
break_on_removal(VOID)241 static UINT break_on_removal(VOID)
242 {
243
244 UINT status;
245 UX_DEVICE *device;
246
247 status = ux_host_stack_device_get(0, &device);
248 if (status == UX_SUCCESS)
249 /* Do not break. */
250 return UX_SUCCESS;
251
252 return 1;
253 }
254
255
test_ux_device_class_dpump_entry(UX_SLAVE_CLASS_COMMAND * command)256 static UINT test_ux_device_class_dpump_entry(UX_SLAVE_CLASS_COMMAND *command)
257 {
258 switch(command->ux_slave_class_command_request)
259 {
260 case UX_SLAVE_CLASS_COMMAND_INITIALIZE:
261 case UX_SLAVE_CLASS_COMMAND_QUERY:
262 case UX_SLAVE_CLASS_COMMAND_CHANGE:
263 return UX_SUCCESS;
264
265 default:
266 return UX_NO_CLASS_MATCH;
267 }
268 }
269
test_ux_host_class_dpump_entry(UX_HOST_CLASS_COMMAND * command)270 static UINT test_ux_host_class_dpump_entry(UX_HOST_CLASS_COMMAND *command)
271 {
272 switch (command -> ux_host_class_command_request)
273 {
274 case UX_HOST_CLASS_COMMAND_QUERY:
275 default:
276 return _ux_host_class_dpump_entry(command);
277 }
278 }
279
280 /* Define what the initial system looks like. */
281
282 #ifdef CTEST
test_application_define(void * first_unused_memory)283 void test_application_define(void *first_unused_memory)
284 #else
285 void usbx_ux_utility_descriptor_parse_test_application_define(void *first_unused_memory)
286 #endif
287 {
288
289 UINT status;
290 CHAR *stack_pointer;
291 CHAR *memory_pointer;
292
293 /* Inform user. */
294 printf("Running ux_utility_descriptor_parse Test............................ ");
295
296 /* Initialize the free memory pointer. */
297 stack_pointer = (CHAR *) first_unused_memory;
298 memory_pointer = stack_pointer + (UX_TEST_STACK_SIZE * 2);
299
300 /* Initialize USBX Memory. */
301 status = ux_system_initialize(memory_pointer, UX_TEST_MEMORY_SIZE, UX_NULL, 0);
302
303 /* Check for error. */
304 if (status != UX_SUCCESS)
305 {
306
307 printf("ERROR #%d\n", __LINE__);
308 test_control_return(1);
309 }
310
311 /* Register the error callback. */
312 _ux_utility_error_callback_register(error_callback);
313
314 /* Create the simulation thread. */
315 status = tx_thread_create(&ux_test_thread_simulation_0, "test simulation", ux_test_thread_simulation_0_entry, 0,
316 stack_pointer, UX_TEST_STACK_SIZE,
317 20, 20, 1, TX_AUTO_START);
318
319 /* Check for error. */
320 if (status != TX_SUCCESS)
321 {
322
323 printf("ERROR #%d\n", __LINE__);
324 test_control_return(1);
325 }
326 }
327
328
ux_test_thread_simulation_0_entry(ULONG arg)329 static void ux_test_thread_simulation_0_entry(ULONG arg)
330 {
331 UCHAR input[] = {0,1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf};
332 UCHAR structure[] = {4,2,1,2,4};
333
334 #if 1
335 struct _output {
336 ULONG f1;
337 USHORT f2;
338 UCHAR f3;
339 UCHAR _align_f4[1];
340 USHORT f4;
341 UCHAR _align_f5[2];
342 ULONG f5;
343 } output;
344
345 _ux_utility_descriptor_parse(input, structure, 5, (UCHAR *)&output);
346 if (output.f1 != 0x03020100)
347 {
348
349 printf("ERROR #%d: expect 0x%x but got 0x%lx\n", __LINE__, 0x03020100, output.f1);
350 error_counter ++;
351 }
352 if (output.f2 != 0x0504)
353 {
354
355 printf("ERROR #%d: expect 0x%x but got 0x%x\n", __LINE__, 0x0504, output.f2);
356 error_counter ++;
357 }
358 if (output.f3 != 0x06)
359 {
360
361 printf("ERROR #%d: expect 0x%x but got 0x%x\n", __LINE__, 6, output.f3);
362 error_counter ++;
363 }
364 if (output.f4 != 0x0807)
365 {
366
367 printf("ERROR #%d: expect 0x%x but got 0x%x\n", __LINE__, 7, output.f4);
368 error_counter ++;
369 }
370 if (output.f5 != 0x0c0b0a09)
371 {
372
373 printf("ERROR #%d: expect 0x%x but got 0x%lx\n", __LINE__, 0x0f0e0d0c, output.f5);
374 error_counter ++;
375 }
376 #else
377 ULONG output[8] = {0,0,0,0,0, 0,0,0};
378
379 _ux_utility_descriptor_parse(input, structure, 5, (UCHAR *)output);
380 if (output[0] != 0x03020100)
381 {
382
383 printf("ERROR #%d: expect 0x%x but got 0x%lx\n", __LINE__, 0x03020100, output[0]);
384 error_counter ++;
385 }
386 if (output[1] != 0x0504)
387 {
388
389 printf("ERROR #%d: expect 0x%x but got 0x%lx\n", __LINE__, 0x0504, output[1]);
390 error_counter ++;
391 }
392 if (output[2] != 6)
393 {
394
395 printf("ERROR #%d: expect 0x%x but got 0x%lx\n", __LINE__, 6, output[2]);
396 error_counter ++;
397 }
398 if (output[3] != 0x0807)
399 {
400
401 printf("ERROR #%d: expect 0x%x but got 0x%lx\n", __LINE__, 0x0807, output[3]);
402 error_counter ++;
403 }
404 if (output[4] != 0x0c0b0a09)
405 {
406
407 printf("ERROR #%d: expect 0x%x but got 0x%lx\n", __LINE__, 0x0c0b0a09, output[4]);
408 error_counter ++;
409 }
410 if (output[5] != 0)
411 {
412
413 printf("ERROR #%d: expect 0x%x but got 0x%lx\n", __LINE__, 0, output[5]);
414 error_counter ++;
415 }
416 #endif
417
418 /* Sleep for a tick to make sure everything is complete. */
419 tx_thread_sleep(1);
420
421 /* Check for errors from other threads. */
422 if (error_counter)
423 {
424
425 /* Test error. */
426 printf("ERROR #%d: total %ld errors\n", __LINE__, error_counter);
427 test_control_return(1);
428 }
429 else
430 {
431
432 /* Successful test. */
433 printf("SUCCESS!\n");
434 test_control_return(0);
435 }
436 }
437