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