1 /* This test is designed to test the ux_host_stack_configuration_interface_get.  */
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_host_class_dpump.h"
9 #include "ux_device_class_dpump.h"
10 
11 
12 /* Define USBX test constants.  */
13 
14 #define UX_TEST_STACK_SIZE      4096
15 #define UX_TEST_BUFFER_SIZE     2048
16 #define UX_TEST_RUN             1
17 #define UX_TEST_MEMORY_SIZE     (64*1024)
18 
19 
20 /* Define the counters used in the test application...  */
21 
22 static ULONG                           thread_0_counter;
23 static ULONG                           thread_1_counter;
24 static ULONG                           error_counter;
25 
26 
27 /* Define USBX test global variables.  */
28 
29 static unsigned char                   host_out_buffer[UX_HOST_CLASS_DPUMP_PACKET_SIZE];
30 static unsigned char                   host_in_buffer[UX_HOST_CLASS_DPUMP_PACKET_SIZE];
31 static unsigned char                   slave_buffer[UX_HOST_CLASS_DPUMP_PACKET_SIZE];
32 
33 static UX_HOST_CLASS                   *class_driver;
34 static UX_HOST_CLASS_DPUMP             *dpump;
35 static UX_SLAVE_CLASS_DPUMP            *dpump_slave;
36 
37 
38 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 50
39 static UCHAR device_framework_full_speed[] = {
40 
41     /* Device descriptor */
42         0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
43         0xec, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
44         0x00, 0x01,
45 
46     /* Configuration descriptor */
47         0x09, 0x02, 0x32, 0x00, 0x02, 0x01, 0x00, 0xc0,
48         0x32,
49 
50     /* Interface descriptor */
51         0x09, 0x04, 0x00, 0x00, 0x02, 0x99, 0x99, 0x99,
52         0x00,
53 
54     /* Endpoint descriptor (Bulk Out) */
55         0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00,
56 
57     /* Endpoint descriptor (Bulk In) */
58         0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00,
59 
60     /* Interface descriptor */
61         0x09, 0x04, 0x01, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
62         0x00,
63 
64     /* Interface descriptor */
65         0x09, 0x04, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0xFF,
66         0x00
67     };
68 
69 
70 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 78
71 static UCHAR device_framework_high_speed[] = {
72 
73     /* Device descriptor */
74         0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
75         0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
76         0x03, 0x01,
77 
78     /* Device qualifier descriptor */
79         0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
80         0x01, 0x00,
81 
82     /* Configuration descriptor */
83         0x09, 0x02, 0x32, 0x00, 0x02, 0x01, 0x00, 0xc0,
84         0x32,
85 
86     /* Interface descriptor */
87         0x09, 0x04, 0x00, 0x00, 0x02, 0x99, 0x99, 0x99,
88         0x00,
89 
90     /* Endpoint descriptor (Bulk Out) */
91         0x07, 0x05, 0x01, 0x02, 0x00, 0x02, 0x00,
92 
93     /* Endpoint descriptor (Bulk In) */
94         0x07, 0x05, 0x82, 0x02, 0x00, 0x02, 0x00,
95 
96     /* Interface descriptor */
97         0x09, 0x04, 0x01, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
98         0x00,
99 
100     /* Interface descriptor */
101         0x09, 0x04, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0xFF,
102         0x00
103 
104     };
105 
106     /* String Device Framework :
107      Byte 0 and 1 : Word containing the language ID : 0x0904 for US
108      Byte 2       : Byte containing the index of the descriptor
109      Byte 3       : Byte containing the length of the descriptor string
110     */
111 
112 #define STRING_FRAMEWORK_LENGTH 38
113 static UCHAR string_framework[] = {
114 
115     /* Manufacturer string descriptor : Index 1 */
116         0x09, 0x04, 0x01, 0x0c,
117         0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
118         0x6f, 0x67, 0x69, 0x63,
119 
120     /* Product string descriptor : Index 2 */
121         0x09, 0x04, 0x02, 0x0c,
122         0x44, 0x61, 0x74, 0x61, 0x50, 0x75, 0x6d, 0x70,
123         0x44, 0x65, 0x6d, 0x6f,
124 
125     /* Serial Number string descriptor : Index 3 */
126         0x09, 0x04, 0x03, 0x04,
127         0x30, 0x30, 0x30, 0x31
128     };
129 
130 
131     /* Multiple languages are supported on the device, to add
132        a language besides English, the unicode language code must
133        be appended to the language_id_framework array and the length
134        adjusted accordingly. */
135 #define LANGUAGE_ID_FRAMEWORK_LENGTH 2
136 static UCHAR language_id_framework[] = {
137 
138     /* English. */
139         0x09, 0x04
140     };
141 
142 
143 /* Define prototypes for external Host Controller's (HCDs), classes and clients.  */
144 
145 static VOID                ux_test_instance_activate(VOID  *dpump_instance);
146 static VOID                ux_test_instance_deactivate(VOID *dpump_instance);
147 
148 UINT                       _ux_host_class_dpump_entry(UX_HOST_CLASS_COMMAND *command);
149 UINT                       _ux_host_class_dpump_write(UX_HOST_CLASS_DPUMP *dpump, UCHAR * data_pointer,
150                                     ULONG requested_length, ULONG *actual_length);
151 UINT                       _ux_host_class_dpump_read (UX_HOST_CLASS_DPUMP *dpump, UCHAR *data_pointer,
152                                     ULONG requested_length, ULONG *actual_length);
153 
154 static TX_THREAD           ux_test_thread_host_simulation;
155 static TX_THREAD           ux_test_thread_slave_simulation;
156 static void                ux_test_thread_host_simulation_entry(ULONG);
157 static void                ux_test_thread_slave_simulation_entry(ULONG);
158 
159 
160 /* Define the ISR dispatch.  */
161 
162 extern VOID    (*test_isr_dispatch)(void);
163 
164 
165 /* Prototype for test control return.  */
166 
167 void  test_control_return(UINT status);
168 
169 
170 /* Define the ISR dispatch routine.  */
171 
test_isr(void)172 static void    test_isr(void)
173 {
174 
175     /* For further expansion of interrupt-level testing.  */
176 }
177 
178 
error_callback(UINT system_level,UINT system_context,UINT error_code)179 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
180 {
181     if (error_code != UX_INTERFACE_HANDLE_UNKNOWN)
182     {
183 
184         /* Failed test.  */
185         printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code);
186         test_control_return(1);
187     }
188 
189 }
190 
191 /* Define what the initial system looks like.  */
192 
193 #ifdef CTEST
test_application_define(void * first_unused_memory)194 void test_application_define(void *first_unused_memory)
195 #else
196 void    usbx_ux_host_stack_configuration_interface_get_test_application_define(void *first_unused_memory)
197 #endif
198 {
199 
200 UINT status;
201 CHAR                            *stack_pointer;
202 CHAR                            *memory_pointer;
203 UX_SLAVE_CLASS_DPUMP_PARAMETER  parameter;
204 
205 
206     /* Inform user.  */
207     printf("Running ux_host_stack_configuration_interface_get Test.............. ");
208 
209     /* Initialize the free memory pointer.  */
210     stack_pointer = (CHAR *) first_unused_memory;
211     memory_pointer = stack_pointer + (UX_TEST_STACK_SIZE * 2);
212 
213     /* Initialize USBX Memory.  */
214     status =  ux_system_initialize(memory_pointer, UX_TEST_MEMORY_SIZE, UX_NULL, 0);
215 
216     /* Check for error.  */
217     if (status != UX_SUCCESS)
218     {
219 
220         printf("ERROR #1\n");
221         test_control_return(1);
222     }
223 
224     /* Register the error callback. */
225     _ux_utility_error_callback_register(error_callback);
226 
227     /* The code below is required for installing the host portion of USBX.  */
228     status =  ux_host_stack_initialize(UX_NULL);
229 
230     /* Check for error.  */
231     if (status != UX_SUCCESS)
232     {
233 
234         printf("ERROR #2\n");
235         test_control_return(1);
236     }
237 
238     /* Register all the host class drivers for this USBX implementation.  */
239     status =  ux_host_stack_class_register(_ux_system_host_class_dpump_name, ux_host_class_dpump_entry);
240 
241     /* Check for error.  */
242     if (status != UX_SUCCESS)
243     {
244 
245         printf("ERROR #3\n");
246         test_control_return(1);
247     }
248 
249     /* The code below is required for installing the device portion of USBX */
250     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
251                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
252                                        string_framework, STRING_FRAMEWORK_LENGTH,
253                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH, UX_NULL);
254 
255     /* Check for error.  */
256     if (status != UX_SUCCESS)
257     {
258 
259         printf("ERROR #5\n");
260         test_control_return(1);
261     }
262 
263     /* Set the parameters for callback when insertion/extraction of a Data Pump device.  */
264     parameter.ux_slave_class_dpump_instance_activate   =  ux_test_instance_activate;
265     parameter.ux_slave_class_dpump_instance_deactivate =  ux_test_instance_deactivate;
266 
267     /* Initialize the device dpump class. The class is connected with interface 0 */
268     status =  ux_device_stack_class_register(_ux_system_slave_class_dpump_name, _ux_device_class_dpump_entry,
269                                                1, 0, &parameter);
270 
271     /* Check for error.  */
272     if (status != UX_SUCCESS)
273     {
274 
275         printf("ERROR #6\n");
276         test_control_return(1);
277     }
278 
279     /* Initialize the simulated device controller.  */
280     status =  _ux_dcd_sim_slave_initialize();
281 
282     /* Check for error.  */
283     if (status != UX_SUCCESS)
284     {
285 
286         printf("ERROR #7\n");
287         test_control_return(1);
288     }
289 
290     /* Register all the USB host controllers available in this system */
291     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
292 
293     /* Check for error.  */
294     if (status != UX_SUCCESS)
295     {
296 
297         printf("ERROR #4\n");
298         test_control_return(1);
299     }
300 
301     /* Create the main host simulation thread.  */
302     status =  tx_thread_create(&ux_test_thread_host_simulation, "test host simulation", ux_test_thread_host_simulation_entry, 0,
303             stack_pointer, UX_TEST_STACK_SIZE,
304             20, 20, 1, TX_AUTO_START);
305 
306     /* Check for error.  */
307     if (status != TX_SUCCESS)
308     {
309 
310         printf("ERROR #8\n");
311         test_control_return(1);
312     }
313 }
314 
315 
ux_test_thread_host_simulation_entry(ULONG arg)316 static void  ux_test_thread_host_simulation_entry(ULONG arg)
317 {
318 
319 UINT            status;
320 UX_HOST_CLASS   *class;
321 UX_INTERFACE    *test_interface;
322 
323 
324     /* Find the main data pump container.  */
325     status =  ux_host_stack_class_get(_ux_system_host_class_dpump_name, &class);
326 
327     /* Check for error.  */
328     if (status != UX_SUCCESS)
329     {
330 
331         /* DPUMP basic test error.  */
332         printf("ERROR #9\n");
333         test_control_return(1);
334     }
335 
336     /* We get the first instance of the data pump device.  */
337     do
338     {
339 
340         status =  ux_host_stack_class_instance_get(class, 0, (VOID **) &dpump);
341         tx_thread_relinquish();
342     } while (status != UX_SUCCESS);
343 
344     /* We still need to wait for the data pump status to be live.  */
345     while (dpump -> ux_host_class_dpump_state != UX_HOST_CLASS_INSTANCE_LIVE)
346     {
347 
348         tx_thread_relinquish();
349     }
350 
351     /* At this point, the data pump class has been found.  Now get the interface
352        using invalid interface index.  */
353     status = _ux_host_stack_configuration_interface_get(dpump -> ux_host_class_dpump_device -> ux_device_first_configuration, 3, 0, &test_interface);
354     if (status != UX_INTERFACE_HANDLE_UNKNOWN)
355     {
356 
357         /* ux_host_stack_device_get test error.  */
358         error_counter++;
359     }
360 
361     /* Now get the interface using invalid alternate setting index.  */
362     status = _ux_host_stack_configuration_interface_get(dpump -> ux_host_class_dpump_device -> ux_device_first_configuration, 0, 1, &test_interface);
363     if (status != UX_INTERFACE_HANDLE_UNKNOWN)
364     {
365 
366         /* ux_host_stack_device_get test error.  */
367         error_counter++;
368     }
369 
370     /* Now get the interface using invalid alternate setting index.  */
371     status = _ux_host_stack_configuration_interface_get(dpump -> ux_host_class_dpump_device -> ux_device_first_configuration, 1, 2, &test_interface);
372     if (status != UX_INTERFACE_HANDLE_UNKNOWN)
373     {
374 
375         /* ux_host_stack_device_get test error.  */
376         error_counter++;
377     }
378 
379     /* Sleep for a tick to make sure everything is complete.  */
380     tx_thread_sleep(1);
381 
382     /* Check for errors from other threads.  */
383     if (error_counter)
384     {
385 
386         /* Test error.  */
387         printf("ERROR #10\n");
388         test_control_return(1);
389     }
390     else
391     {
392 
393         /* Successful test.  */
394         printf("SUCCESS!\n");
395         test_control_return(0);
396     }
397 }
398 
ux_test_instance_activate(VOID * dpump_instance)399 static VOID  ux_test_instance_activate(VOID *dpump_instance)
400 {
401 
402     /* Save the DPUMP instance.  */
403     dpump_slave = (UX_SLAVE_CLASS_DPUMP *) dpump_instance;
404 }
405 
ux_test_instance_deactivate(VOID * dpump_instance)406 static VOID  ux_test_instance_deactivate(VOID *dpump_instance)
407 {
408 
409     /* Reset the DPUMP instance.  */
410     dpump_slave = UX_NULL;
411 }
412 
413