1 /* This test is designed to test the ux_host_stack_configuration_instance_delete.  */
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(epa) \
53     /* Endpoint descriptor */\
54     0x07, 0x05, (epa), 0x02, 0x40, 0x00, 0x00,
55 
56 #define DPUMP_IFC_DESC_ALL_LEN(nb_ep) (9 + (nb_ep) * 7)
57 
58 #define CFG_DESC_ALL_LEN (CFG_DESC_LEN + \
59     DPUMP_IFC_DESC_ALL_LEN(0) + \
60     DPUMP_IFC_DESC_ALL_LEN(1) + \
61     DPUMP_IFC_DESC_ALL_LEN(2) + \
62     DPUMP_IFC_DESC_ALL_LEN(3) + \
63     DPUMP_IFC_DESC_ALL_LEN(4)   \
64     )
65 
66 #define CFG_DESC_ALL \
67     CFG_DESC(CFG_DESC_ALL_LEN, 5, 1)\
68     DPUMP_IFC_DESC(0, 0, 0)\
69     DPUMP_IFC_DESC(0, 1, 1)\
70     DPUMP_IFC_EP_DESC(0x81)\
71     DPUMP_IFC_DESC(0, 2, 2)\
72     DPUMP_IFC_EP_DESC(0x81)\
73     DPUMP_IFC_EP_DESC(0x02)\
74     DPUMP_IFC_DESC(0, 3, 3)\
75     DPUMP_IFC_EP_DESC(0x81)\
76     DPUMP_IFC_EP_DESC(0x02)\
77     DPUMP_IFC_EP_DESC(0x83)\
78     DPUMP_IFC_DESC(0, 4, 4)\
79     DPUMP_IFC_EP_DESC(0x81)\
80     DPUMP_IFC_EP_DESC(0x02)\
81     DPUMP_IFC_EP_DESC(0x83)\
82     DPUMP_IFC_EP_DESC(0x04)
83 
84 /* Define the counters used in the test application...  */
85 
86 static ULONG                           thread_0_counter;
87 static ULONG                           thread_1_counter;
88 static ULONG                           error_counter;
89 
90 static UCHAR                           error_callback_ignore = UX_FALSE;
91 static ULONG                           error_callback_counter;
92 
93 static UCHAR                           buffer[UX_TEST_BUFFER_SIZE];
94 
95 /* Define USBX test global variables.  */
96 
97 static UX_HOST_CLASS                   *class_driver;
98 static UX_HOST_CLASS_DPUMP             *dpump;
99 static UX_SLAVE_CLASS_DPUMP            *dpump_slave = UX_NULL;
100 
101 
102 static UCHAR device_framework_full_speed[] = {
103 
104     /* Device descriptor 18 bytes */
105     0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
106     0xec, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
107     0x00, 0x01,
108 
109     CFG_DESC_ALL
110 };
111 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
112 
113 static UCHAR device_framework_high_speed[] = {
114 
115     /* Device descriptor */
116     0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
117     0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
118     0x03, 0x01,
119 
120     /* Device qualifier descriptor */
121     0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
122     0x01, 0x00,
123 
124     CFG_DESC_ALL
125 };
126 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
127 
128 /* String Device Framework :
129     Byte 0 and 1 : Word containing the language ID : 0x0904 for US
130     Byte 2       : Byte containing the index of the descriptor
131     Byte 3       : Byte containing the length of the descriptor string
132 */
133 
134 static UCHAR string_framework[] = {
135 
136     /* Manufacturer string descriptor : Index 1 */
137     0x09, 0x04, 0x01, 0x0c,
138     0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
139     0x6f, 0x67, 0x69, 0x63,
140 
141     /* Product string descriptor : Index 2 */
142     0x09, 0x04, 0x02, 0x0c,
143     0x44, 0x61, 0x74, 0x61, 0x50, 0x75, 0x6d, 0x70,
144     0x44, 0x65, 0x6d, 0x6f,
145 
146     /* Serial Number string descriptor : Index 3 */
147     0x09, 0x04, 0x03, 0x04,
148     0x30, 0x30, 0x30, 0x31
149 };
150 #define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
151 
152     /* Multiple languages are supported on the device, to add
153        a language besides English, the unicode language code must
154        be appended to the language_id_framework array and the length
155        adjusted accordingly. */
156 static UCHAR language_id_framework[] = {
157 
158 /* English. */
159     0x09, 0x04
160 };
161 #define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
162 
163 /* Define prototypes for external Host Controller's (HCDs), classes and clients.  */
164 
165 static VOID                ux_test_instance_activate(VOID  *dpump_instance);
166 static VOID                ux_test_instance_deactivate(VOID *dpump_instance);
167 
168 UINT                       _ux_host_class_dpump_entry(UX_HOST_CLASS_COMMAND *command);
169 UINT                       ux_hcd_sim_initialize(UX_HCD *hcd);
170 UINT                       _ux_host_class_dpump_write(UX_HOST_CLASS_DPUMP *dpump, UCHAR * data_pointer,
171                                     ULONG requested_length, ULONG *actual_length);
172 UINT                       _ux_host_class_dpump_read (UX_HOST_CLASS_DPUMP *dpump, UCHAR *data_pointer,
173                                     ULONG requested_length, ULONG *actual_length);
174 
175 static TX_THREAD           ux_test_thread_simulation_0;
176 static TX_THREAD           ux_test_thread_simulation_1;
177 static void                ux_test_thread_simulation_0_entry(ULONG);
178 static void                ux_test_thread_simulation_1_entry(ULONG);
179 
180 
181 /* Define the ISR dispatch.  */
182 
183 extern VOID    (*test_isr_dispatch)(void);
184 
185 
186 /* Prototype for test control return.  */
187 
188 void  test_control_return(UINT status);
189 
190 
191 /* Define the ISR dispatch routine.  */
192 
test_isr(void)193 static void    test_isr(void)
194 {
195 
196     /* For further expansion of interrupt-level testing.  */
197 }
198 
199 
error_callback(UINT system_level,UINT system_context,UINT error_code)200 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
201 {
202 
203     error_callback_counter ++;
204 
205     if (!error_callback_ignore)
206     {
207         {
208             /* Failed test.  */
209             printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
210             test_control_return(1);
211         }
212     }
213 }
214 
test_ux_device_class_dpump_entry(UX_SLAVE_CLASS_COMMAND * command)215 static UINT test_ux_device_class_dpump_entry(UX_SLAVE_CLASS_COMMAND *command)
216 {
217     switch(command->ux_slave_class_command_request)
218     {
219         case UX_SLAVE_CLASS_COMMAND_INITIALIZE:
220         case UX_SLAVE_CLASS_COMMAND_QUERY:
221         case UX_SLAVE_CLASS_COMMAND_CHANGE:
222             return UX_SUCCESS;
223 
224         default:
225             return UX_NO_CLASS_MATCH;
226     }
227 }
228 
test_ux_host_class_dpump_entry(UX_HOST_CLASS_COMMAND * command)229 static UINT test_ux_host_class_dpump_entry(UX_HOST_CLASS_COMMAND *command)
230 {
231     switch (command -> ux_host_class_command_request)
232     {
233         case UX_HOST_CLASS_COMMAND_QUERY:
234         case UX_HOST_CLASS_COMMAND_ACTIVATE:
235             return UX_SUCCESS;
236 
237         default:
238             return UX_NO_CLASS_MATCH;
239     }
240 }
241 
242 /* Define what the initial system looks like.  */
243 
244 #ifdef CTEST
test_application_define(void * first_unused_memory)245 void test_application_define(void *first_unused_memory)
246 #else
247 void    usbx_ux_host_stack_configuration_instance_delete_test_application_define(void *first_unused_memory)
248 #endif
249 {
250 
251 UINT status;
252 CHAR                            *stack_pointer;
253 CHAR                            *memory_pointer;
254 UX_SLAVE_CLASS_DPUMP_PARAMETER  parameter;
255 
256 #if !(UX_TEST_MULTI_IFC_ON)
257     printf("Running ux_host_stack_configuration_instance_delete Test............ SKIP!");
258     test_control_return(0);
259     return;
260 #endif
261 
262     /* Initialize the free memory pointer.  */
263     stack_pointer = (CHAR *) first_unused_memory;
264     memory_pointer = stack_pointer + (UX_TEST_STACK_SIZE * 2);
265 
266     /* Initialize USBX Memory.  */
267     status =  ux_system_initialize(memory_pointer, UX_TEST_MEMORY_SIZE, UX_NULL, 0);
268 
269     /* Check for error.  */
270     if (status != UX_SUCCESS)
271     {
272 
273         printf("Running ux_host_stack_configuration_instance_delete Test............ ERROR #1\n");
274         test_control_return(1);
275     }
276 
277     /* Register the error callback. */
278     _ux_utility_error_callback_register(error_callback);
279 
280     /* The code below is required for installing the host portion of USBX.  */
281     status =  ux_host_stack_initialize(UX_NULL);
282 
283     /* Check for error.  */
284     if (status != UX_SUCCESS)
285     {
286 
287         printf("Running ux_host_stack_configuration_instance_delete Test............ ERROR #2\n");
288         test_control_return(1);
289     }
290 
291     /* Register all the host class drivers for this USBX implementation.  */
292     status =  ux_host_stack_class_register(_ux_system_host_class_dpump_name, test_ux_host_class_dpump_entry);
293 
294     /* Check for error.  */
295     if (status != UX_SUCCESS)
296     {
297 
298         printf("Running ux_host_stack_configuration_instance_delete Test............ ERROR #3\n");
299         test_control_return(1);
300     }
301 
302     /* The code below is required for installing the device portion of USBX */
303     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
304                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
305                                        string_framework, STRING_FRAMEWORK_LENGTH,
306                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH, UX_NULL);
307 
308     /* Check for error.  */
309     if (status != UX_SUCCESS)
310     {
311 
312         printf("Running ux_host_stack_configuration_instance_delete Test............ ERROR #5\n");
313         test_control_return(1);
314     }
315 
316     /* Set the parameters for callback when insertion/extraction of a Data Pump device.  */
317     parameter.ux_slave_class_dpump_instance_activate   =  UX_NULL;
318     parameter.ux_slave_class_dpump_instance_deactivate =  UX_NULL;
319 
320     /* Initialize the device dpump class. The class is connected with interface 0 */
321     status =  ux_device_stack_class_register(_ux_system_slave_class_dpump_name, test_ux_device_class_dpump_entry,
322                                               1, 0, &parameter);
323 
324     /* Check for error.  */
325     if (status != UX_SUCCESS)
326     {
327 
328         printf("Running ux_host_stack_configuration_instance_delete Test............ ERROR #6\n");
329         test_control_return(1);
330     }
331 
332     /* Initialize the simulated device controller.  */
333     status =  _ux_test_dcd_sim_slave_initialize();
334 
335     /* Check for error.  */
336     if (status != UX_SUCCESS)
337     {
338 
339         printf("Running ux_host_stack_configuration_instance_delete Test............ ERROR #7\n");
340         test_control_return(1);
341     }
342 
343     /* Register all the USB host controllers available in this system */
344     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
345 
346     /* Check for error.  */
347     if (status != UX_SUCCESS)
348     {
349 
350         printf("Running ux_host_stack_configuration_instance_delete Test............ ERROR #4\n");
351         test_control_return(1);
352     }
353 
354     /* Create the main host simulation thread.  */
355     status =  tx_thread_create(&ux_test_thread_simulation_0, "test host simulation", ux_test_thread_simulation_0_entry, 0,
356             stack_pointer, UX_TEST_STACK_SIZE,
357             20, 20, 1, TX_AUTO_START);
358 
359     /* Check for error.  */
360     if (status != TX_SUCCESS)
361     {
362 
363         printf("Running ux_host_stack_configuration_instance_delete Test............ ERROR #8\n");
364         test_control_return(1);
365     }
366 }
367 
368 
ux_test_thread_simulation_0_entry(ULONG arg)369 static void  ux_test_thread_simulation_0_entry(ULONG arg)
370 {
371 
372 UINT                     status;
373 INT                      i;
374 UX_DEVICE               *device;
375 UX_CONFIGURATION        *configuration;
376 UX_INTERFACE            *interface;
377 UX_INTERFACE            *interfaces[8];
378 
379     /* Inform user.  */
380     printf("Running ux_host_stack_configuration_instance_delete Test............ ");
381 
382     /* Connect. */
383     ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
384     tx_thread_sleep(100);
385 
386     status = ux_host_stack_device_get(0, &device);
387     if (status != UX_SUCCESS)
388     {
389 
390         printf("ERROR #%d: device_get fail\n", __LINE__);
391         test_control_return(1);
392     }
393 
394     status = ux_host_stack_device_configuration_get(device, 0, &configuration);
395     if (status != UX_SUCCESS)
396     {
397 
398         printf("ERROR #%d: cfg_get fail\n", __LINE__);
399         test_control_return(1);
400     }
401 
402     interface = configuration->ux_configuration_first_interface;
403     for (i = 0; i < 8; i ++)
404     {
405 
406         if (interface == UX_NULL)
407             break;
408 
409         interfaces[i] = interface;
410         interface = interface->ux_interface_next_interface;
411     }
412 
413     /* Set configure. */
414     status = ux_host_stack_device_configuration_select(configuration);
415     if (status != UX_SUCCESS)
416     {
417 
418         printf("ERROR #%d: cfg_set fail\n", __LINE__);
419         test_control_return(1);
420     }
421 
422     /* Switch to interface 0.4 */
423     status = ux_host_stack_interface_setting_select(interfaces[4]);
424     if (status != UX_SUCCESS)
425     {
426 
427         printf("ERROR #%d: ifc_set fail\n", __LINE__);
428         error_counter ++;
429     }
430 
431     /* Reset configuration. */
432     status = _ux_host_stack_device_configuration_reset(device);
433     if (status != UX_SUCCESS)
434     {
435 
436         printf("ERROR #%d: cfg_reset fail\n", __LINE__);
437         error_counter ++;
438     }
439 
440     /* Sleep for a tick to make sure everything is complete.  */
441     tx_thread_sleep(1);
442 
443     /* Check for errors from other threads.  */
444     if (error_counter)
445     {
446 
447         /* Test error.  */
448         printf("ERROR #14\n");
449         test_control_return(1);
450     }
451     else
452     {
453 
454         /* Successful test.  */
455         printf("SUCCESS!\n");
456         test_control_return(0);
457     }
458 }
459