1 #ifndef USBX_UX_TEST_CDC_ECM_H
2 #define USBX_UX_TEST_CDC_ECM_H
3
4 #include "ux_api.h"
5 #include "ux_system.h"
6 #include "ux_utility.h"
7 #include "ux_network_driver.h"
8 #include "ux_host_class_cdc_ecm.h"
9 #include "ux_device_class_cdc_ecm.h"
10 #include "ux_test_dcd_sim_slave.h"
11 #include "ux_test_hcd_sim_host.h"
12 #include "ux_test_utility_sim.h"
13 #include "ux_test.h"
14 #include "ux_test_actions.h"
15
16 //#define LOCAL_MACHINE
17
18 typedef struct DEVICE_INIT_DATA
19 {
20 UCHAR *framework;
21 ULONG framework_length;
22 UCHAR *string_framework;
23 ULONG string_framework_length;
24 UCHAR dont_register_hcd;
25 UCHAR dont_connect_to_host;
26 } DEVICE_INIT_DATA;
27
28 #define DEMO_IP_THREAD_STACK_SIZE (8*1024)
29 #define HOST_IP_ADDRESS IP_ADDRESS(192,168,1,176)
30 #define HOST_SOCKET_PORT_UDP 45054
31 #define HOST_SOCKET_PORT_TCP 45056
32 #define DEVICE_IP_ADDRESS IP_ADDRESS(192,168,1,175)
33 #define DEVICE_SOCKET_PORT_UDP 45055
34 #define DEVICE_SOCKET_PORT_TCP 45057
35
36 #ifndef TEST_NX_PACKET_CHAIN
37 #define TCP_WINDOW 1600
38 #define PACKET_PAYLOAD 1600
39 #define WRITE_APPEND_SIZE (0)
40 #define PACKET_POOL_SIZE (PACKET_PAYLOAD*10000)
41 #define HOST_IP_POOL_SIZE (PACKET_PAYLOAD*UX_HOST_CLASS_CDC_ECM_NX_PKPOOL_ENTRIES)
42 #define DEVICE_IP_POOL_SIZE (PACKET_PAYLOAD*UX_DEVICE_CLASS_CDC_ECM_NX_PKPOOL_ENTRIES)
43 #else
44 #define TCP_WINDOW 1400
45 #define PACKET_PAYLOAD (256)
46 #define WRITE_APPEND_SIZE (300)
47 #define PACKET_POOL_SIZE (PACKET_PAYLOAD*10000)
48 #define HOST_IP_POOL_SIZE (PACKET_PAYLOAD*UX_HOST_CLASS_CDC_ECM_NX_PKPOOL_ENTRIES)
49 #define DEVICE_IP_POOL_SIZE (PACKET_PAYLOAD*UX_DEVICE_CLASS_CDC_ECM_NX_PKPOOL_ENTRIES)
50 #endif
51 #define ARP_MEMORY_SIZE 1024
52
53 /* Define local constants. */
54
55 #define UX_DEMO_STACK_SIZE (4*1024)
56 #define UX_USBX_MEMORY_SIZE (128*1024)
57
58 /* Define basic test constants. */
59
60 #ifndef BASIC_TEST_NUM_ITERATIONS
61 #define BASIC_TEST_NUM_ITERATIONS 10
62 #endif
63 #ifndef BASIC_TEST_NUM_PACKETS_PER_ITERATION
64 #define BASIC_TEST_NUM_PACKETS_PER_ITERATION 10
65 #endif
66 #define BASIC_TEST_NUM_TOTAL_PACKETS (BASIC_TEST_NUM_ITERATIONS*BASIC_TEST_NUM_PACKETS_PER_ITERATION)
67 #define BASIC_TEST_HOST 0
68 #define BASIC_TEST_DEVICE 1
69 #define BASIC_TEST_TCP 0
70 #define BASIC_TEST_UDP 1
71
72 /* Host */
73
74 static UX_HOST_CLASS *class_driver_host;
75 static UX_HOST_CLASS_CDC_ECM *cdc_ecm_host;
76 static UX_HOST_CLASS_CDC_ECM *cdc_ecm_host_from_system_change_function;
77 static TX_THREAD thread_host;
78 static UCHAR thread_stack_host[UX_DEMO_STACK_SIZE];
79 static NX_IP nx_ip_host;
80 static NX_PACKET_POOL ip_pool_host;
81 static UCHAR ip_pool_host_name[] = "NetX Host IP Pool";
82 static NX_PACKET_POOL packet_pool_host;
83 static NX_PACKET_POOL *packet_pool_host_ptr = &packet_pool_host;
84 static NX_UDP_SOCKET udp_socket_host;
85 static NX_TCP_SOCKET tcp_socket_host;
86 static CHAR *packet_pool_memory_host;
87 static CHAR ip_thread_stack_host[DEMO_IP_THREAD_STACK_SIZE];
88 static CHAR arp_memory_host[ARP_MEMORY_SIZE];
89
90 /* Device */
91
92 static TX_THREAD thread_device;
93 static UX_HOST_CLASS *class_driver_device;
94 static UX_SLAVE_CLASS_CDC_ECM *cdc_ecm_device;
95 static UX_SLAVE_CLASS_CDC_ECM_PARAMETER cdc_ecm_parameter;
96 static UCHAR thread_stack_device[UX_DEMO_STACK_SIZE];
97 static NX_IP nx_ip_device;
98 static NX_PACKET_POOL ip_pool_device;
99 static NX_PACKET_POOL packet_pool_device;
100 static NX_UDP_SOCKET udp_socket_device;
101 static NX_TCP_SOCKET tcp_socket_device;
102 static CHAR *packet_pool_memory_device;
103 static CHAR ip_thread_stack_device[DEMO_IP_THREAD_STACK_SIZE];
104 static CHAR arp_memory_device[ARP_MEMORY_SIZE];
105
106 static UCHAR global_is_device_initialized;
107 static UCHAR global_host_ready_for_application;
108
109 static ULONG global_basic_test_num_writes_host;
110 static ULONG global_basic_test_num_reads_host;
111 static ULONG global_basic_test_num_writes_device;
112 static ULONG global_basic_test_num_reads_device;
113
114 /* Define local prototypes and definitions. */
115 static void thread_entry_host(ULONG arg);
116 static void thread_entry_device(ULONG arg);
117 static void post_init_host();
118 static void post_init_device();
119
120 #define DEFAULT_FRAMEWORK_LENGTH sizeof(default_device_framework)
121 static unsigned char default_device_framework[] = {
122
123 /* Device Descriptor */
124 0x12, /* bLength */
125 0x01, /* bDescriptorType */
126 0x10, 0x01, /* bcdUSB */
127 0xef, /* bDeviceClass - Depends on bDeviceSubClass */
128 0x02, /* bDeviceSubClass - Depends on bDeviceProtocol */
129 0x01, /* bDeviceProtocol - There's an IAD */
130 0x40, /* bMaxPacketSize0 */
131 0x70, 0x07, /* idVendor */
132 0x42, 0x10, /* idProduct */
133 0x00, 0x01, /* bcdDevice */
134 0x01, /* iManufacturer */
135 0x02, /* iProduct */
136 0x03, /* iSerialNumber */
137 0x01, /* bNumConfigurations */
138
139 /* Configuration Descriptor @ 18 */
140 0x09, /* bLength */
141 0x02, /* bDescriptorType */
142 0x58, 0x00, /* wTotalLength */
143 0x02, /* bNumInterfaces */
144 0x01, /* bConfigurationValue */
145 0x00, /* iConfiguration */
146 0xc0, /* bmAttributes - Self-powered */
147 0x00, /* bMaxPower */
148
149 /* Interface Association Descriptor @ 18+9=27 */
150 0x08, /* bLength */
151 0x0b, /* bDescriptorType */
152 0x00, /* bFirstInterface */
153 0x02, /* bInterfaceCount */
154 0x02, /* bFunctionClass - CDC - Communication */
155 0x06, /* bFunctionSubClass - ECM */
156 0x00, /* bFunctionProtocol - No class specific protocol required */
157 0x00, /* iFunction */
158
159 /* Interface Descriptor @ 27+8=35 */
160 0x09, /* bLength */
161 0x04, /* bDescriptorType */
162 0x00, /* bInterfaceNumber */
163 0x00, /* bAlternateSetting */
164 0x01, /* bNumEndpoints */
165 0x02, /* bInterfaceClass - CDC - Communication */
166 0x06, /* bInterfaceSubClass - ECM */
167 0x00, /* bInterfaceProtocol - No class specific protocol required */
168 0x00, /* iInterface */
169
170 /* CDC Header Functional Descriptor @ 35+9=44 */
171 0x05, /* bLength */
172 0x24, /* bDescriptorType */
173 0x00, /* bDescriptorSubType */
174 0x10, 0x01, /* bcdCDC */
175
176 /* CDC ECM Functional Descriptor @ 44+5=49 */
177 0x0d, /* bLength */
178 0x24, /* bDescriptorType */
179 0x0f, /* bDescriptorSubType */
180 0x04, /* iMACAddress */
181 0x00, 0x00, 0x00, 0x00, /* bmEthernetStatistics */
182 0xea, 0x05, /* wMaxSegmentSize */
183 0x00, 0x00, /* wNumberMCFilters */
184 0x00, /* bNumberPowerFilters */
185
186 /* CDC Union Functional Descriptor @ 49+13=62 */
187 0x05, /* bLength */
188 0x24, /* bDescriptorType */
189 0x06, /* bDescriptorSubType */
190 0x00, /* bmMasterInterface */
191 0x01, /* bmSlaveInterface0 */
192
193 /* Endpoint Descriptor */
194 0x07, /* bLength */
195 0x05, /* bDescriptorType */
196 0x83, /* bEndpointAddress */
197 0x03, /* bmAttributes - Interrupt */
198 0x08, 0x00, /* wMaxPacketSize */
199 0x08, /* bInterval */
200
201 /* Interface Descriptor */
202 0x09, /* bLength */
203 0x04, /* bDescriptorType */
204 0x01, /* bInterfaceNumber */
205 0x00, /* bAlternateSetting */
206 0x00, /* bNumEndpoints */
207 0x0a, /* bInterfaceClass - CDC - Data */
208 0x00, /* bInterfaceSubClass - Should be 0x00 */
209 0x00, /* bInterfaceProtocol - No class specific protocol required */
210 0x00, /* iInterface */
211
212 /* Interface Descriptor */
213 0x09, /* bLength */
214 0x04, /* bDescriptorType */
215 0x01, /* bInterfaceNumber */
216 0x01, /* bAlternateSetting */
217 0x02, /* bNumEndpoints */
218 0x0a, /* bInterfaceClass - CDC - Data */
219 0x00, /* bInterfaceSubClass - Should be 0x00 */
220 0x00, /* bInterfaceProtocol - No class specific protocol required */
221 0x00, /* iInterface */
222
223 /* Endpoint Descriptor */
224 0x07, /* bLength */
225 0x05, /* bDescriptorType */
226 0x02, /* bEndpointAddress */
227 0x02, /* bmAttributes - Bulk */
228 0x40, 0x00, /* wMaxPacketSize */
229 0x00, /* bInterval */
230
231 /* Endpoint Descriptor */
232 0x07, /* bLength */
233 0x05, /* bDescriptorType */
234 0x81, /* bEndpointAddress */
235 0x02, /* bmAttributes - Bulk */
236 0x40, 0x00, /* wMaxPacketSize */
237 0x00, /* bInterval */
238
239 };
240
241 static unsigned char default_string_framework[] = {
242
243 /* Manufacturer string descriptor : Index 1 - "Express Logic" */
244 0x09, 0x04, 0x01, 0x0c,
245 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x20, 0x4c,
246 0x6f, 0x67, 0x69, 0x63,
247
248 /* Product string descriptor : Index 2 - "EL CDCECM Device" */
249 0x09, 0x04, 0x02, 0x10,
250 0x45, 0x4c, 0x20, 0x43, 0x44, 0x43, 0x45, 0x43,
251 0x4d, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
252
253 /* Serial Number string descriptor : Index 3 - "0001" */
254 0x09, 0x04, 0x03, 0x04,
255 0x30, 0x30, 0x30, 0x31,
256
257 /* MAC Address string descriptor : Index 4 - "001E5841B879" */
258 0x09, 0x04, 0x04, 0x0C,
259 0x30, 0x30, 0x31, 0x45, 0x35, 0x38,
260 0x34, 0x31, 0x42, 0x38, 0x37, 0x39,
261
262 };
263
264 /* Multiple languages are supported on the device, to add
265 a language besides english, the unicode language code must
266 be appended to the language_id_framework array and the length
267 adjusted accordingly. */
268 static unsigned char language_id_framework[] = {
269
270 /* English. */
271 0x09, 0x04
272 };
273
274 static DEVICE_INIT_DATA default_device_init_data = {
275 .framework = default_device_framework,
276 .framework_length = sizeof(default_device_framework),
277 .string_framework = default_string_framework,
278 .string_framework_length = sizeof(default_string_framework)
279 };
280
ux_test_cdc_ecm_initialize_use_framework(void * first_unused_memory,DEVICE_INIT_DATA * device_init_data)281 static void ux_test_cdc_ecm_initialize_use_framework(void *first_unused_memory, DEVICE_INIT_DATA *device_init_data)
282 {
283
284 CHAR *memory_pointer = first_unused_memory;
285
286 /* Initialize possible uninitialized device init values. */
287
288 if (device_init_data->framework == NULL)
289 {
290 device_init_data->framework = default_device_framework;
291 device_init_data->framework_length = sizeof(default_device_framework);
292 }
293
294 if (device_init_data->string_framework == NULL)
295 {
296 device_init_data->string_framework = default_string_framework;
297 device_init_data->string_framework_length = sizeof(default_string_framework);
298 }
299
300 /* Initialize USBX Memory. */
301 ux_system_initialize(memory_pointer, UX_USBX_MEMORY_SIZE, UX_NULL, 0);
302 memory_pointer += UX_USBX_MEMORY_SIZE;
303
304 /* It looks weird if this doesn't have a comment! */
305 ux_utility_error_callback_register(ux_test_error_callback);
306
307 /* Perform the initialization of the network driver. */
308 UX_TEST_CHECK_SUCCESS(ux_network_driver_init());
309
310 /* Initialize the NetX system. */
311 nx_system_initialize();
312
313 /* Now allocate memory for the packet pools. Note that using the memory passed
314 to us by ThreadX is mucho bettero than putting it in global memory because
315 we can reuse the memory for each test. So no more having to worry about
316 running out of memory! */
317 packet_pool_memory_host = memory_pointer;
318 memory_pointer += PACKET_POOL_SIZE + HOST_IP_POOL_SIZE;
319 packet_pool_memory_device = memory_pointer;
320 memory_pointer += PACKET_POOL_SIZE + DEVICE_IP_POOL_SIZE;
321
322 /* Create the host thread. */
323 UX_TEST_CHECK_SUCCESS(tx_thread_create(&thread_host, "host thread", thread_entry_host, (ULONG)(ALIGN_TYPE)device_init_data,
324 thread_stack_host, UX_DEMO_STACK_SIZE,
325 30, 30, 1, TX_DONT_START));
326 UX_THREAD_EXTENSION_PTR_SET(&thread_host, device_init_data)
327 tx_thread_resume(&thread_host);
328
329 /* Create the slave thread. */
330 UX_TEST_CHECK_SUCCESS(tx_thread_create(&thread_device, "device thread", thread_entry_device, (ULONG)(ALIGN_TYPE)device_init_data,
331 thread_stack_device, UX_DEMO_STACK_SIZE,
332 30, 30, 1, TX_DONT_START));
333 UX_THREAD_EXTENSION_PTR_SET(&thread_device, device_init_data)
334 tx_thread_resume(&thread_device);
335 }
336
ux_test_cdc_ecm_initialize(void * first_unused_memory)337 static void ux_test_cdc_ecm_initialize(void *first_unused_memory)
338 {
339
340 ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &default_device_init_data);
341 }
342
system_change_function(ULONG event,UX_HOST_CLASS * class,VOID * instance)343 static UINT system_change_function(ULONG event, UX_HOST_CLASS *class, VOID *instance)
344 {
345 if (event == UX_DEVICE_INSERTION)
346 {printf("hINS\n");
347 cdc_ecm_host_from_system_change_function = instance;
348 }
349 else if (event == UX_DEVICE_REMOVAL)
350 {printf("hRM\n");
351 cdc_ecm_host_from_system_change_function = UX_NULL;
352 }
353 return(UX_SUCCESS);
354 }
355
class_cdc_ecm_get_host(void)356 static void class_cdc_ecm_get_host(void)
357 {
358
359 UX_HOST_CLASS *class;
360
361 /* Find the main storage container */
362 UX_TEST_CHECK_SUCCESS(ux_host_stack_class_get(_ux_system_host_class_cdc_ecm_name, &class));
363
364 /* We get the first instance of the storage device */
365 UX_TEST_CHECK_SUCCESS(ux_test_host_stack_class_instance_get(class, 0, (void **) &cdc_ecm_host));
366
367 /* We still need to wait for the cdc-ecm status to be live */
368 UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uint(&cdc_ecm_host -> ux_host_class_cdc_ecm_state, UX_HOST_CLASS_INSTANCE_LIVE));
369
370 /* Now wait for the link to be up. */
371 UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&cdc_ecm_host->ux_host_class_cdc_ecm_link_state, UX_HOST_CLASS_CDC_ECM_LINK_STATE_UP));
372 }
373
demo_cdc_ecm_instance_activate(VOID * cdc_ecm_instance)374 static VOID demo_cdc_ecm_instance_activate(VOID *cdc_ecm_instance)
375 {
376
377 /* Save the CDC instance. */
378 cdc_ecm_device = (UX_SLAVE_CLASS_CDC_ECM *) cdc_ecm_instance;
379 }
380
demo_cdc_ecm_instance_deactivate(VOID * cdc_ecm_instance)381 static VOID demo_cdc_ecm_instance_deactivate(VOID *cdc_ecm_instance)
382 {
383
384 /* Reset the CDC instance. */
385 cdc_ecm_device = UX_NULL;
386 }
387
388 /* Copied and pasted from ux_device_class_cdc_ecm_change.c. */
ux_test_device_class_cdc_ecm_set_link_state(UX_SLAVE_CLASS_CDC_ECM * cdc_ecm,UCHAR new_link_state)389 static void ux_test_device_class_cdc_ecm_set_link_state(UX_SLAVE_CLASS_CDC_ECM *cdc_ecm, UCHAR new_link_state)
390 {
391
392 /* Declare the link to be down. */
393 cdc_ecm_device -> ux_slave_class_cdc_ecm_link_state = new_link_state;
394
395 /* We have a thread waiting for an event, we wake it up with a NETWORK NOTIFICATION CHANGE event.
396 In turn they will release the NetX resources used and suspend. */
397 UX_TEST_CHECK_SUCCESS(_ux_utility_event_flags_set(&cdc_ecm_device -> ux_slave_class_cdc_ecm_event_flags_group, UX_DEVICE_CLASS_CDC_ECM_NETWORK_NOTIFICATION_EVENT, TX_OR));
398 }
399
read_packet_tcp(NX_TCP_SOCKET * tcp_socket,ULONG num_reads,CHAR * name)400 static void read_packet_tcp(NX_TCP_SOCKET *tcp_socket, ULONG num_reads, CHAR *name)
401 {
402
403 NX_PACKET *rcv_packet;
404 ULONG num_writes_from_peer;
405
406 #ifndef LOCAL_MACHINE
407 if (num_reads % 100 == 0)
408 #endif
409 stepinfo("%s reading tcp packet# %lu\n", name, num_reads);
410
411 UX_TEST_CHECK_SUCCESS(nx_tcp_socket_receive(tcp_socket, &rcv_packet, NX_WAIT_FOREVER));
412
413 num_writes_from_peer = *(ULONG *)rcv_packet->nx_packet_prepend_ptr;
414 UX_TEST_ASSERT(num_writes_from_peer == num_reads);
415
416 UX_TEST_CHECK_SUCCESS(nx_packet_release(rcv_packet));
417 }
418
write_packet_tcp(NX_TCP_SOCKET * tcp_socket,NX_PACKET_POOL * packet_pool,ULONG num_writes,CHAR * name)419 static void write_packet_tcp(NX_TCP_SOCKET *tcp_socket, NX_PACKET_POOL *packet_pool, ULONG num_writes, CHAR *name)
420 {
421
422 NX_PACKET *out_packet;
423
424 UX_TEST_CHECK_SUCCESS(nx_packet_allocate(packet_pool, &out_packet, NX_TCP_PACKET, NX_WAIT_FOREVER));
425
426 *(ULONG *)out_packet->nx_packet_prepend_ptr = num_writes;
427 out_packet->nx_packet_length = sizeof(ULONG);
428 out_packet->nx_packet_append_ptr = out_packet->nx_packet_prepend_ptr + out_packet->nx_packet_length;
429 #if WRITE_APPEND_SIZE > 0
430 /* Append data until packet chain created. */
431 for (int i = 0, remain = WRITE_APPEND_SIZE; i < WRITE_APPEND_SIZE; i += 10)
432 {
433 remain = WRITE_APPEND_SIZE - i;
434 if (remain < 10)
435 {
436 nx_packet_data_append(out_packet, "0123456789", remain, packet_pool, NX_WAIT_FOREVER);
437 break;
438 }
439 else
440 {
441 nx_packet_data_append(out_packet, "0123456789", 10, packet_pool, NX_WAIT_FOREVER);
442 }
443 }
444 #endif
445
446 #ifndef LOCAL_MACHINE
447 if (num_writes % 100 == 0)
448 #endif
449 stepinfo("%s writing tcp packet# %lu\n", name, num_writes);
450
451 UX_TEST_CHECK_SUCCESS(nx_tcp_socket_send(tcp_socket, out_packet, NX_WAIT_FOREVER));
452 }
453
read_packet_udp(NX_UDP_SOCKET * udp_socket,ULONG num_reads,CHAR * name)454 static void read_packet_udp(NX_UDP_SOCKET *udp_socket, ULONG num_reads, CHAR *name)
455 {
456
457 NX_PACKET *rcv_packet;
458 ULONG num_writes_from_peer;
459
460 #ifndef LOCAL_MACHINE
461 if (num_reads % 100 == 0)
462 #endif
463 stepinfo("%s reading udp packet# %lu\n", name, num_reads);
464
465 UX_TEST_CHECK_SUCCESS(nx_udp_socket_receive(udp_socket, &rcv_packet, NX_WAIT_FOREVER));
466
467 num_writes_from_peer = *(ULONG *)rcv_packet->nx_packet_prepend_ptr;
468 UX_TEST_ASSERT(num_writes_from_peer == num_reads);
469
470 UX_TEST_CHECK_SUCCESS(nx_packet_release(rcv_packet));
471 }
472
write_udp(NX_UDP_SOCKET * udp_socket,NX_PACKET_POOL * packet_pool,ULONG ip_address,ULONG port,ULONG num_writes,CHAR * name,ULONG len)473 static void write_udp(NX_UDP_SOCKET *udp_socket, NX_PACKET_POOL *packet_pool, ULONG ip_address, ULONG port, ULONG num_writes, CHAR *name, ULONG len)
474 {
475
476 NX_PACKET *out_packet;
477 ULONG i, remain;
478
479 UX_TEST_CHECK_SUCCESS(nx_packet_allocate(packet_pool, &out_packet, NX_UDP_PACKET, NX_WAIT_FOREVER));
480
481 *(ULONG *)out_packet->nx_packet_prepend_ptr = num_writes;
482 out_packet->nx_packet_length = sizeof(ULONG);
483 out_packet->nx_packet_append_ptr = out_packet->nx_packet_prepend_ptr + out_packet->nx_packet_length;
484 if (len > 4)
485 {
486
487 /* Append packet data. */
488 for (i = 0, remain = len - 4; i < len - 4; i += 10)
489 {
490 remain = len - 4 - i;
491 if (remain < 10)
492 {
493 nx_packet_data_append(out_packet, "0123456789", remain, packet_pool, NX_WAIT_FOREVER);
494 break;
495 }
496 else
497 {
498 nx_packet_data_append(out_packet, "0123456789", 10, packet_pool, NX_WAIT_FOREVER);
499 }
500 }
501 }
502
503 #ifndef LOCAL_MACHINE
504 if (num_writes % 100 == 0)
505 #endif
506 stepinfo("%s writing udp packet# %lu, %ld\n", name, num_writes, out_packet->nx_packet_length);
507
508 UX_TEST_CHECK_SUCCESS(nx_udp_socket_send(udp_socket, out_packet, ip_address, port));
509 }
510
write_packet_udp(NX_UDP_SOCKET * udp_socket,NX_PACKET_POOL * packet_pool,ULONG ip_address,ULONG port,ULONG num_writes,CHAR * name)511 static void write_packet_udp(NX_UDP_SOCKET *udp_socket, NX_PACKET_POOL *packet_pool, ULONG ip_address, ULONG port, ULONG num_writes, CHAR *name)
512 {
513 write_udp(udp_socket, packet_pool, ip_address, port, num_writes, name, 4 + WRITE_APPEND_SIZE);
514 }
515
cdc_ecm_basic_test(UCHAR host_or_device,UCHAR socket_type)516 static void cdc_ecm_basic_test(UCHAR host_or_device, UCHAR socket_type)
517 {
518
519 UINT i;
520 UINT num_iters;
521
522 if (host_or_device == BASIC_TEST_HOST)
523 {
524
525 if (socket_type == BASIC_TEST_TCP)
526 {
527
528 for (num_iters = 0; num_iters < BASIC_TEST_NUM_ITERATIONS; num_iters++)
529 {
530
531 for (i = 0; i < BASIC_TEST_NUM_PACKETS_PER_ITERATION; i++)
532 write_packet_tcp(&tcp_socket_host, &packet_pool_host, global_basic_test_num_writes_host++, "host");
533
534 for (i = 0; i < BASIC_TEST_NUM_PACKETS_PER_ITERATION; i++)
535 read_packet_tcp(&tcp_socket_host, global_basic_test_num_reads_host++, "host");
536 }
537 }
538 else
539 {
540
541 for (num_iters = 0; num_iters < BASIC_TEST_NUM_ITERATIONS; num_iters++)
542 {
543
544 for (i = 0; i < BASIC_TEST_NUM_PACKETS_PER_ITERATION; i++)
545 write_packet_udp(&udp_socket_host, &packet_pool_host, DEVICE_IP_ADDRESS, DEVICE_SOCKET_PORT_UDP, global_basic_test_num_writes_host++, "host");
546
547 for (i = 0; i < BASIC_TEST_NUM_PACKETS_PER_ITERATION; i++)
548 read_packet_udp(&udp_socket_host, global_basic_test_num_reads_host++, "host");
549 }
550 }
551
552 /* Wait for all transfers to complete. */
553 UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&global_basic_test_num_writes_host, BASIC_TEST_NUM_TOTAL_PACKETS));
554 UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&global_basic_test_num_reads_host, BASIC_TEST_NUM_TOTAL_PACKETS));
555
556 if (socket_type == BASIC_TEST_TCP)
557
558 /* Wait for all ACKs to complete. */
559 /* TODO: find better way. */
560 tx_thread_sleep(MS_TO_TICK(1000));
561
562 /* Reset for next test. */
563 global_basic_test_num_reads_host = 0;
564 global_basic_test_num_writes_host = 0;
565 }
566 else
567 {
568
569 if (socket_type == BASIC_TEST_TCP)
570 {
571
572 for (num_iters = 0; num_iters < BASIC_TEST_NUM_ITERATIONS; num_iters++)
573 {
574
575 for (i = 0; i < BASIC_TEST_NUM_PACKETS_PER_ITERATION; i++)
576 write_packet_tcp(&tcp_socket_device, &packet_pool_device, global_basic_test_num_writes_device++, "device");
577
578 for (i = 0; i < BASIC_TEST_NUM_PACKETS_PER_ITERATION; i++)
579 read_packet_tcp(&tcp_socket_device, global_basic_test_num_reads_device++, "device");
580 }
581 }
582 else
583 {
584
585 for (num_iters = 0; num_iters < BASIC_TEST_NUM_ITERATIONS; num_iters++)
586 {
587
588 for (i = 0; i < BASIC_TEST_NUM_PACKETS_PER_ITERATION; i++)
589 write_packet_udp(&udp_socket_device, &packet_pool_device, HOST_IP_ADDRESS, HOST_SOCKET_PORT_UDP, global_basic_test_num_writes_device++, "device");
590
591 for (i = 0; i < BASIC_TEST_NUM_PACKETS_PER_ITERATION; i++)
592 read_packet_udp(&udp_socket_device, global_basic_test_num_reads_device++, "device");
593 }
594 }
595
596 /* Wait for all transfers to complete. */
597 UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&global_basic_test_num_writes_device, BASIC_TEST_NUM_TOTAL_PACKETS));
598 UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&global_basic_test_num_reads_device, BASIC_TEST_NUM_TOTAL_PACKETS));
599
600 /* Reset for next test. */
601 global_basic_test_num_reads_device = 0;
602 global_basic_test_num_writes_device = 0;
603 }
604 }
605
thread_entry_host(ULONG device_init_data_ptr)606 static void thread_entry_host(ULONG device_init_data_ptr)
607 {
608
609 DEVICE_INIT_DATA *device_init_data;
610
611 UX_THREAD_EXTENSION_PTR_GET(device_init_data, DEVICE_INIT_DATA, device_init_data_ptr);
612
613 /* Wait for device to initialize. */
614 UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&global_is_device_initialized, 1));
615
616 /* Create the IP instance. */
617
618 UX_TEST_CHECK_SUCCESS(nx_packet_pool_create(&packet_pool_host, "NetX Host Packet Pool", PACKET_PAYLOAD, packet_pool_memory_host, PACKET_POOL_SIZE));
619 UX_TEST_CHECK_SUCCESS(nx_packet_pool_create(&ip_pool_host, ip_pool_host_name, PACKET_PAYLOAD, packet_pool_memory_host+PACKET_POOL_SIZE, HOST_IP_POOL_SIZE));
620 UX_TEST_CHECK_SUCCESS(nx_ip_create(&nx_ip_host, "NetX Host Thread", HOST_IP_ADDRESS, 0xFF000000UL,
621 &ip_pool_host, _ux_network_driver_entry, ip_thread_stack_host, DEMO_IP_THREAD_STACK_SIZE, 1));
622
623 /* Setup ARP. */
624
625 UX_TEST_CHECK_SUCCESS(nx_arp_enable(&nx_ip_host, (void *)arp_memory_host, ARP_MEMORY_SIZE));
626 UX_TEST_CHECK_SUCCESS(nx_arp_static_entry_create(&nx_ip_host, DEVICE_IP_ADDRESS, 0x0000001E, 0x80032CD8));
627
628 /* Setup UDP. */
629
630 UX_TEST_CHECK_SUCCESS(nx_udp_enable(&nx_ip_host));
631 UX_TEST_CHECK_SUCCESS(nx_udp_socket_create(&nx_ip_host, &udp_socket_host, "USB HOST UDP SOCKET", NX_IP_NORMAL, NX_DONT_FRAGMENT, 20, 20));
632 UX_TEST_CHECK_SUCCESS(nx_udp_socket_bind(&udp_socket_host, HOST_SOCKET_PORT_UDP, NX_NO_WAIT));
633
634 /* Setup TCP. */
635
636 UX_TEST_CHECK_SUCCESS(nx_tcp_enable(&nx_ip_host));
637 UX_TEST_CHECK_SUCCESS(nx_tcp_socket_create(&nx_ip_host, &tcp_socket_host, "USB HOST TCP SOCKET", NX_IP_NORMAL, NX_DONT_FRAGMENT, NX_IP_TIME_TO_LIVE, TCP_WINDOW, NX_NULL, NX_NULL));
638 UX_TEST_CHECK_SUCCESS(nx_tcp_server_socket_listen(&nx_ip_host, HOST_SOCKET_PORT_TCP, &tcp_socket_host, 5, NX_NULL));
639
640 /* The code below is required for installing the host portion of USBX. */
641 UX_TEST_CHECK_SUCCESS(ux_host_stack_initialize(system_change_function));
642
643 /* Register cdc_ecm class. */
644 UX_TEST_CHECK_SUCCESS(ux_host_stack_class_register(_ux_system_host_class_cdc_ecm_name, ux_host_class_cdc_ecm_entry));
645
646 if (!device_init_data->dont_register_hcd)
647 {
648
649 /* Register all the USB host controllers available in this system. */
650 UX_TEST_CHECK_SUCCESS(ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize, 0, 0));
651
652 /* Find the storage class. */
653 class_cdc_ecm_get_host();
654
655 if (!device_init_data->dont_connect_to_host)
656 {
657
658 /* Connect to device TCP socket. */
659 UX_TEST_CHECK_SUCCESS(nx_tcp_server_socket_accept(&tcp_socket_host, NX_WAIT_FOREVER));
660 }
661 }
662 global_host_ready_for_application = 1;
663
664 /* Call test code. */
665 post_init_host();
666
667 /* We need to disconnect the host and device. This is because the NetX cleaning
668 process (in usbxtestcontrol.c) includes disconnect the device, which tries
669 to send a RST packet to the peer (or something). By disconnecting here,
670 we ensure the deactivate routines notify the network driver so that the
671 packet tranmissiong is stopped there. */
672 ux_test_disconnect_slave();
673 ux_test_disconnect_host_wait_for_enum_completion();
674
675 /* And finally the usbx system resources. */
676 _ux_system_uninitialize();
677
678 /* Successful test. */
679 printf("SUCCESS!\n");
680 test_control_return(0);
681 }
682
thread_entry_device(ULONG device_init_data_ptr)683 static void thread_entry_device(ULONG device_init_data_ptr)
684 {
685
686 DEVICE_INIT_DATA *device_init_data;
687
688 UX_THREAD_EXTENSION_PTR_GET(device_init_data, DEVICE_INIT_DATA, device_init_data_ptr)
689
690 /* Create the IP instance. */
691
692 UX_TEST_CHECK_SUCCESS(nx_packet_pool_create(&packet_pool_device, "NetX Device Packet Pool", PACKET_PAYLOAD, packet_pool_memory_device, PACKET_POOL_SIZE));
693 UX_TEST_CHECK_SUCCESS(nx_packet_pool_create(&ip_pool_device, "NetX Device IP Pool", PACKET_PAYLOAD, packet_pool_memory_device+PACKET_POOL_SIZE, DEVICE_IP_POOL_SIZE));
694
695 UX_TEST_CHECK_SUCCESS(nx_ip_create(&nx_ip_device, "NetX Device Thread", DEVICE_IP_ADDRESS, 0xFF000000L, &ip_pool_device,
696 _ux_network_driver_entry, ip_thread_stack_device, DEMO_IP_THREAD_STACK_SIZE, 1));
697
698 /* Setup ARP. */
699
700 UX_TEST_CHECK_SUCCESS(nx_arp_enable(&nx_ip_device, (void *)arp_memory_device, ARP_MEMORY_SIZE));
701 UX_TEST_CHECK_SUCCESS(nx_arp_static_entry_create(&nx_ip_device, HOST_IP_ADDRESS, 0x0000001E, 0x5841B878));
702
703 /* Setup UDP. */
704
705 UX_TEST_CHECK_SUCCESS(nx_udp_enable(&nx_ip_device));
706 UX_TEST_CHECK_SUCCESS(nx_udp_socket_create(&nx_ip_device, &udp_socket_device, "USB DEVICE UDP SOCKET", NX_IP_NORMAL, NX_DONT_FRAGMENT, 20, 20));
707 UX_TEST_CHECK_SUCCESS(nx_udp_socket_bind(&udp_socket_device, DEVICE_SOCKET_PORT_UDP, NX_NO_WAIT));
708
709 /* Setup TCP. */
710
711 UX_TEST_CHECK_SUCCESS(nx_tcp_enable(&nx_ip_device));
712 UX_TEST_CHECK_SUCCESS(nx_tcp_socket_create(&nx_ip_device, &tcp_socket_device, "USB DEVICE TCP SOCKET", NX_IP_NORMAL, NX_DONT_FRAGMENT, NX_IP_TIME_TO_LIVE, 100, NX_NULL, NX_NULL));
713 UX_TEST_CHECK_SUCCESS(nx_tcp_client_socket_bind(&tcp_socket_device, DEVICE_SOCKET_PORT_TCP, NX_WAIT_FOREVER));
714
715 /* The code below is required for installing the device portion of USBX.
716 In this demo, DFU is possible and we have a call back for state change. */
717 UX_TEST_CHECK_SUCCESS(ux_device_stack_initialize(device_init_data->framework, device_init_data->framework_length,
718 device_init_data->framework, device_init_data->framework_length,
719 device_init_data->string_framework, device_init_data->string_framework_length,
720 language_id_framework, sizeof(language_id_framework),
721 UX_NULL));
722
723 /* Set the parameters for callback when insertion/extraction of a CDC device. Set to NULL.*/
724 cdc_ecm_parameter.ux_slave_class_cdc_ecm_instance_activate = demo_cdc_ecm_instance_activate;
725 cdc_ecm_parameter.ux_slave_class_cdc_ecm_instance_deactivate = demo_cdc_ecm_instance_deactivate;
726
727 /* Define a NODE ID. */
728 cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_local_node_id[0] = 0x00;
729 cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_local_node_id[1] = 0x1e;
730 cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_local_node_id[2] = 0x58;
731 cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_local_node_id[3] = 0x41;
732 cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_local_node_id[4] = 0xb8;
733 cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_local_node_id[5] = 0x78;
734
735 /* Define a remote NODE ID. */
736 cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_remote_node_id[0] = 0x00;
737 cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_remote_node_id[1] = 0x1e;
738 cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_remote_node_id[2] = 0x58;
739 cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_remote_node_id[3] = 0x41;
740 cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_remote_node_id[4] = 0xb8;
741 cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_remote_node_id[5] = 0x79;
742
743 /* Initialize the device cdc_ecm class. */
744 UX_TEST_CHECK_SUCCESS(ux_device_stack_class_register(_ux_system_slave_class_cdc_ecm_name, ux_device_class_cdc_ecm_entry, 1, 0, &cdc_ecm_parameter));
745
746 /* Initialize the simulated device controller. */
747 UX_TEST_CHECK_SUCCESS(_ux_test_dcd_sim_slave_initialize());
748
749 global_is_device_initialized = UX_TRUE;
750
751 if (!device_init_data->dont_connect_to_host)
752 {
753
754 if (!device_init_data->dont_register_hcd)
755 {
756
757 UX_TEST_CHECK_SUCCESS(ux_test_wait_for_non_null((VOID **)&cdc_ecm_device));
758 UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&cdc_ecm_device->ux_slave_class_cdc_ecm_link_state, UX_DEVICE_CLASS_CDC_ECM_LINK_STATE_UP));
759
760 /* Connect to host TCP socket. */
761 UX_TEST_CHECK_SUCCESS(nx_tcp_client_socket_connect(&tcp_socket_device, HOST_IP_ADDRESS, HOST_SOCKET_PORT_TCP, NX_WAIT_FOREVER));
762 }
763
764 /* Wait for host - believe this is so that we know host is always first... gives us some 'determinism'. */
765 UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&global_host_ready_for_application, 1));
766 }
767
768 /* Call test code. */
769 post_init_device();
770 }
771
772 #endif