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