1 
2 
3 /* This is a small demo of the high-performance NetX Duo TCP/IP
4    IPv4/IPv6 dual stack.  This demo concentrates on UDP datagram
5    send/receive in IPv4 and IPv6 network in a simulated Ethernet
6    driver in a multihome environment.  */
7 
8 
9 /*
10    IP_0 has two simulated phyiscal interfaces.
11    The primary interface is 1.2.3.4/255.255.255.0
12    the secondary interface is 2.2.3.4/255.255.255.0
13 
14    IP_1 has two simulated physical interface.
15    The primary interface is 1.2.3.5/255.255.255.0
16    the secondary interface is 2.2.3.5/255.255.255.0
17 
18    Each interface has an IPv6 link local address and
19    an IPv6 global address.  The following table lists the IPv6
20    configuration:
21 
22    IP_0 primary interface Link Local Address:  FE80::
23    IP_0 primary interface Global Address:
24 
25    IP_0 secondary interface Link Local Address:  FE80::
26    IP_0 secondary interface Global Address:
27 
28    IP_1 primary interface Link Local Address:  FE80::
29    IP_1 primary interface Global Address:
30 
31    IP_1 secondary interface Link Local Address:  FE80::
32    IP_1 secondary interface Global Address:
33 
34 
35 
36 
37 
38    These four simulated interfaces are connected to the same channel.
39 
40 
41 
42        ---------  Primary                         Primary   ---------
43        |       |  Interface                       Interface |       |
44        | IP_0  |----------------------     |----------------| IP_1  |
45        |       | 1.2.3.4             |     |       1.2.3.5  |       |
46        |       | 2001::4             |     |       2001::5  |       |
47        |       |                     |     |                |       |
48        |       |                     |     |                |       |
49        |       |-------------------  |     |  --------------|       |
50        |       | Secondary        |  |     |  |   Secondary |       |
51        --------- Interface        |  |     |  |   Interface ---------
52                  2.2.3.4          |  |     |  |     2.2.3.5
53                  2002::4          |  |     |  |     2002::5
54                                ------------------
55                                |                |
56                                |   Switch Box   |
57                                |                |
58                                ------------------
59 
60 
61 */
62 
63 #include   "tx_api.h"
64 #include   "nx_api.h"
65 
66 #if (NX_MAX_PHYSICAL_INTERFACES > 1)
67 
68 #define     DEMO_STACK_SIZE 2048
69 #define     DEMO_DATA       "ABCDEFGHIJKLMNOPQRSTUVWXYZ "
70 #define     PACKET_SIZE     1536
71 #define     POOL_SIZE       ((sizeof(NX_PACKET) + PACKET_SIZE) * 16)
72 
73 /* Define the ThreadX and NetX object control blocks...  */
74 
75 TX_THREAD               thread_0;
76 TX_THREAD               thread_1;
77 
78 NX_PACKET_POOL          pool_0;
79 NX_IP                   ip_0;
80 NX_IP                   ip_1;
81 
82 NX_UDP_SOCKET           socket_0;
83 NX_UDP_SOCKET           socket_1;
84 UCHAR                   pool_buffer[POOL_SIZE];
85 
86 
87 
88 /* Define the counters used in the demo application...  */
89 
90 ULONG                   thread_0_counter;
91 ULONG                   thread_1_counter;
92 ULONG                   error_counter;
93 
94 
95 /* Define thread prototypes.  */
96 
97 void thread_0_entry(ULONG thread_input);
98 void thread_1_entry(ULONG thread_input);
99 
100 void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req);
101 
102 
103 #define PRIMARY_INTERFACE   0
104 #define SECONDARY_INTERFACE 1
105 
106 #ifndef NX_DISABLE_IPV4
107 NXD_ADDRESS ip1_primary_ipv4_address;
108 NXD_ADDRESS ip1_secondary_ipv4_address;
109 #endif /* NX_DISABLE_IPV4 */
110 
111 #ifndef NX_DISABLE_IPV6
112 
113 UINT ip0_primary_linklocal_address_index;
114 UINT ip0_primary_global_address_index;
115 UINT ip0_secondary_linklocal_address_index;
116 UINT ip0_secondary_global_address_index;
117 
118 UINT ip1_primary_linklocal_address_index;
119 UINT ip1_primary_global_address_index;
120 UINT ip1_secondary_linklocal_address_index;
121 UINT ip1_secondary_global_address_index;
122 
123 
124 NXD_ADDRESS ip1_primary_linklocal_address;
125 NXD_ADDRESS ip1_primary_global_address;
126 NXD_ADDRESS ip1_secondary_linklocal_address;
127 NXD_ADDRESS ip1_secondary_global_address;
128 #endif /* NX_DISABLE_IPV6 */
129 
130 #ifndef NX_DISABLE_IPV4
131 
132 #ifndef NX_DISABLE_IPV6
133 /*
134    Define the number of UDP tests.  If IPv6 is enabled, there are 6 tests:
135    (1) UDP packet tranmisssion to the IPv4 address of the primary interface on ip_1;
136    (2) UDP packet transmission to the IPv4 address of the secondary interface on ip_1;
137    (3) UDP packet transmission to the IPv6 link local address of the primary interface on ip_1;
138    (4) UDP packet transmission to the IPv6 link local address of the secondary interface on ip_1;
139    (5) UDP packet transmission to the IPv6 global address of the primary interface on ip_1;
140    (6) UDP packet transmission to the IPv6 global address of the secondary interface on ip_1;
141 */
142 #define NUMBER_OF_TESTS 8
143 
144 
145 #else  /* !NX_DISABLE_IPV6 */
146 /*
147    Define the number of UDP tests.  If IPv6 is enabled, there are 6 tests:
148    (1) UDP packet tranmisssion to the IPv4 address of the primary interface on ip_1;
149    (2) UDP packet transmission to the IPv4 address of the secondary interface on ip_1;
150 
151 */
152 #define NUMBER_OF_TESTS 2
153 #endif /* !NX_DISABLE_IPV6 */
154 
155 #else  /* !NX_DISABLE_IPV4 */
156 /*
157    Define the number of UDP tests.  If IPv6 is enabled, there are 6 tests:
158    (1) UDP packet tranmisssion to the IPv4 address of the primary interface on ip_1;
159    (2) UDP packet transmission to the IPv4 address of the secondary interface on ip_1;
160    (3) UDP packet transmission to the IPv6 link local address of the primary interface on ip_1;
161    (4) UDP packet transmission to the IPv6 link local address of the secondary interface on ip_1;
162    (5) UDP packet transmission to the IPv6 global address of the primary interface on ip_1;
163    (6) UDP packet transmission to the IPv6 global address of the secondary interface on ip_1;
164 */
165 #define NUMBER_OF_TESTS 6
166 #endif /* !NX_DISABLE_IPV4 */
167 
168 /* Define main entry point.  */
169 
main()170 int main()
171 {
172 
173     /* Enter the ThreadX kernel.  */
174     tx_kernel_enter();
175 }
176 
177 
178 /* Define what the initial system looks like.  */
179 
tx_application_define(void * first_unused_memory)180 void    tx_application_define(void *first_unused_memory)
181 {
182 
183 CHAR *pointer;
184 UINT  status;
185 
186 
187     /* Setup the working pointer.  */
188     pointer =  (CHAR *)first_unused_memory;
189 
190     /* Create the main thread.  */
191     tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
192                      pointer, DEMO_STACK_SIZE,
193                      4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
194 
195     pointer =  pointer + DEMO_STACK_SIZE;
196 
197     /* Create the main thread.  */
198     tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0,
199                      pointer, DEMO_STACK_SIZE,
200                      3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
201 
202     pointer =  pointer + DEMO_STACK_SIZE;
203 
204 
205     /* Initialize the NetX system.  */
206     nx_system_initialize();
207 
208     /* Create a packet pool.  */
209     status =  nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pool_buffer, POOL_SIZE);
210 
211     if (status)
212     {
213         error_counter++;
214     }
215 
216     /* Create an IP instance.  */
217     status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver,
218                           pointer, 2048, 1);
219     pointer =  pointer + 2048;
220 
221     /* Create another IP instance.  */
222     status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver,
223                            pointer, 2048, 1);
224     pointer =  pointer + 2048;
225 
226     if (status)
227     {
228         error_counter++;
229     }
230 
231 #ifndef NX_DISABLE_IPV4
232     /* Set the server IP address to ip_1 primary IPv4 address. */
233     ip1_primary_ipv4_address.nxd_ip_version = NX_IP_VERSION_V4;
234     ip1_primary_ipv4_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5);
235 #endif /* NX_DISABLE_IPV4 */
236 
237 
238     /* Attach the second interface to IP_0. Note that this interface is attached during initialization time.
239        Alternatively the second interface may also be attached in thread context, as illustrated below
240        in thead_0_entry function. */
241     status = nx_ip_interface_attach(&ip_0, "IP_0 Secondary Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00, _nx_ram_network_driver);
242 
243     if (status)
244     {
245         error_counter++;
246     }
247 
248 #ifndef NX_DISABLE_IPV4
249     /* Enable ARP and supply ARP cache memory for IP Instance 0.  */
250     status =  nx_arp_enable(&ip_0, (void *)pointer, 1024);
251     pointer = pointer + 1024;
252 
253     /* Enable ARP and supply ARP cache memory for IP Instance 1.  */
254     status +=  nx_arp_enable(&ip_1, (void *)pointer, 1024);
255     pointer = pointer + 1024;
256 
257     /* Check ARP enable status.  */
258     if (status)
259     {
260         error_counter++;
261     }
262 #endif /* NX_DISABLE_IPV4 */
263 #ifndef NX_DISABLE_IPV6
264 
265     /* Enable IPv6 */
266     status = nxd_ipv6_enable(&ip_0);
267     if (status)
268     {
269         error_counter++;
270     }
271 
272     status = nxd_ipv6_enable(&ip_1);
273     if (status)
274     {
275         error_counter++;
276     }
277 #endif /* !NX_DISABLE_IPV6 */
278 
279     /* Enable ICMP */
280     status = nxd_icmp_enable(&ip_0);
281     if (status)
282     {
283         error_counter++;
284     }
285 
286     status = nxd_icmp_enable(&ip_1);
287     if (status)
288     {
289         error_counter++;
290     }
291 
292 
293     /* Enable UDP processing for both IP instances.  */
294     status =  nx_udp_enable(&ip_0);
295     status += nx_udp_enable(&ip_1);
296 
297     if (status)
298     {
299         error_counter++;
300     }
301 }
302 
303 
304 
305 /* Define the test threads.  */
306 
thread_0_entry(ULONG thread_input)307 void    thread_0_entry(ULONG thread_input)
308 {
309 
310 UINT       status;
311 NX_PACKET *my_packet;
312 
313 
314 #ifndef NX_DISABLE_IPV6
315 NXD_ADDRESS       ip_address;
316 NXD_IPV6_ADDRESS *server_ipv6_ptr;
317 #endif /* !NX_DISABLE_IPV6 */
318 
319     NX_PARAMETER_NOT_USED(thread_input);
320 
321     /*
322        At this point, IP_0 already has two interfaces attached during the system initialization phase.
323        Here is a demonstration of attaching a secondary interface to an IP instance (ip_1 in this case)
324        after the IP instance has been created and already started.
325      */
326 
327     /*
328        Attch the second interface to IP_1.  Note that this interface is attached in thread context.
329        Alternatively the second interface may also be attached during system initilization, as illustrated
330        above in tx_application_define.
331      */
332 
333     /* Attach the 2nd interface to IP_1 */
334     status = nx_ip_interface_attach(&ip_1, "IP_1 Secondary Interface", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00, _nx_ram_network_driver);
335 
336     /* Check for error.  */
337     if (status)
338     {
339         error_counter++;
340     }
341 
342 
343 #ifndef NX_DISABLE_IPV4
344     /* Set the server IP address to ip_1 primary IPv4 address. */
345     ip1_secondary_ipv4_address.nxd_ip_version = NX_IP_VERSION_V4;
346     ip1_secondary_ipv4_address.nxd_ip_address.v4 = IP_ADDRESS(2, 2, 3, 5);
347 #endif /* NX_DISABLE_IPV4 */
348 
349 #ifndef NX_DISABLE_IPV6
350 
351 
352     /* Set ip_0 primary link local address. */
353     status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, NX_NULL, 10, &ip0_primary_linklocal_address_index);
354     if (status)
355     {
356         error_counter++;
357     }
358 
359     /* Set ip_1 primary link local address. */
360     status = nxd_ipv6_address_set(&ip_1, PRIMARY_INTERFACE, NX_NULL, 10, &ip1_primary_linklocal_address_index);
361     if (status)
362     {
363         error_counter++;
364     }
365 
366 
367 
368     /* Set ip_0 primary interface global address. */
369     ip_address.nxd_ip_version = NX_IP_VERSION_V6;
370     ip_address.nxd_ip_address.v6[0] = 0x20010000;
371     ip_address.nxd_ip_address.v6[1] = 0;
372     ip_address.nxd_ip_address.v6[2] = 0;
373     ip_address.nxd_ip_address.v6[3] = 4;
374 
375     status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, &ip_address, 64, &ip0_primary_global_address_index);
376 
377     if (status)
378     {
379         error_counter++;
380     }
381 
382     /* Set ip_1 primary interface global address. */
383     ip_address.nxd_ip_version = NX_IP_VERSION_V6;
384     ip_address.nxd_ip_address.v6[0] = 0x20010000;
385     ip_address.nxd_ip_address.v6[1] = 0;
386     ip_address.nxd_ip_address.v6[2] = 0;
387     ip_address.nxd_ip_address.v6[3] = 5;
388 
389     status = nxd_ipv6_address_set(&ip_1, PRIMARY_INTERFACE, &ip_address, 64, &ip1_primary_global_address_index);
390 
391     if (status)
392     {
393         error_counter++;
394     }
395 
396 
397 
398     /* Set ip_0 secondary link local address. */
399     status = nxd_ipv6_address_set(&ip_0, SECONDARY_INTERFACE, NX_NULL, 10, &ip0_secondary_linklocal_address_index);
400     if (status)
401     {
402         error_counter++;
403     }
404 
405     /* Set ip_1 secondary link local address. */
406     status = nxd_ipv6_address_set(&ip_1, SECONDARY_INTERFACE, NX_NULL, 10, &ip1_secondary_linklocal_address_index);
407     if (status)
408     {
409         error_counter++;
410     }
411 
412 
413 
414     /* Set ip_0 secondary interface global address. */
415     ip_address.nxd_ip_version = NX_IP_VERSION_V6;
416     ip_address.nxd_ip_address.v6[0] = 0x20020000;
417     ip_address.nxd_ip_address.v6[1] = 0;
418     ip_address.nxd_ip_address.v6[2] = 0;
419     ip_address.nxd_ip_address.v6[3] = 4;
420 
421     status = nxd_ipv6_address_set(&ip_0, SECONDARY_INTERFACE, &ip_address, 64, &ip0_secondary_global_address_index);
422 
423     if (status)
424     {
425         error_counter++;
426     }
427 
428     /* Set ip_1 primary interface global address. */
429     ip_address.nxd_ip_version = NX_IP_VERSION_V6;
430     ip_address.nxd_ip_address.v6[0] = 0x20020000;
431     ip_address.nxd_ip_address.v6[1] = 0;
432     ip_address.nxd_ip_address.v6[2] = 0;
433     ip_address.nxd_ip_address.v6[3] = 5;
434 
435     status = nxd_ipv6_address_set(&ip_1, SECONDARY_INTERFACE, &ip_address, 64, &ip1_secondary_global_address_index);
436 
437     if (status)
438     {
439         error_counter++;
440     }
441 
442     /* Set the server IP address to ip_1 primary IPv6 link local address. */
443     server_ipv6_ptr = &ip_1.nx_ipv6_address[ip1_primary_linklocal_address_index];
444     ip1_primary_linklocal_address.nxd_ip_version = NX_IP_VERSION_V6;
445     ip1_primary_linklocal_address.nxd_ip_address.v6[0] = server_ipv6_ptr -> nxd_ipv6_address[0];
446     ip1_primary_linklocal_address.nxd_ip_address.v6[1] = server_ipv6_ptr -> nxd_ipv6_address[1];
447     ip1_primary_linklocal_address.nxd_ip_address.v6[2] = server_ipv6_ptr -> nxd_ipv6_address[2];
448     ip1_primary_linklocal_address.nxd_ip_address.v6[3] = server_ipv6_ptr -> nxd_ipv6_address[3];
449 
450     /* Set the server IP address to ip_1 primary IPv6 global address. */
451     server_ipv6_ptr = &ip_1.nx_ipv6_address[ip1_primary_global_address_index];
452     ip1_primary_global_address.nxd_ip_version = NX_IP_VERSION_V6;
453     ip1_primary_global_address.nxd_ip_address.v6[0] = server_ipv6_ptr -> nxd_ipv6_address[0];
454     ip1_primary_global_address.nxd_ip_address.v6[1] = server_ipv6_ptr -> nxd_ipv6_address[1];
455     ip1_primary_global_address.nxd_ip_address.v6[2] = server_ipv6_ptr -> nxd_ipv6_address[2];
456     ip1_primary_global_address.nxd_ip_address.v6[3] = server_ipv6_ptr -> nxd_ipv6_address[3];
457 
458     /* Set the server IP address to ip_1 secondary IPv6 link local address. */
459     server_ipv6_ptr = &ip_1.nx_ipv6_address[ip1_secondary_linklocal_address_index];
460     ip1_secondary_linklocal_address.nxd_ip_version = NX_IP_VERSION_V6;
461     ip1_secondary_linklocal_address.nxd_ip_address.v6[0] = server_ipv6_ptr -> nxd_ipv6_address[0];
462     ip1_secondary_linklocal_address.nxd_ip_address.v6[1] = server_ipv6_ptr -> nxd_ipv6_address[1];
463     ip1_secondary_linklocal_address.nxd_ip_address.v6[2] = server_ipv6_ptr -> nxd_ipv6_address[2];
464     ip1_secondary_linklocal_address.nxd_ip_address.v6[3] = server_ipv6_ptr -> nxd_ipv6_address[3];
465 
466     /* Set the server IP address to ip_1 secondary IPv6 global address. */
467     server_ipv6_ptr = &ip_1.nx_ipv6_address[ip1_secondary_global_address_index];
468     ip1_secondary_global_address.nxd_ip_version = NX_IP_VERSION_V6;
469     ip1_secondary_global_address.nxd_ip_address.v6[0] = server_ipv6_ptr -> nxd_ipv6_address[0];
470     ip1_secondary_global_address.nxd_ip_address.v6[1] = server_ipv6_ptr -> nxd_ipv6_address[1];
471     ip1_secondary_global_address.nxd_ip_address.v6[2] = server_ipv6_ptr -> nxd_ipv6_address[2];
472     ip1_secondary_global_address.nxd_ip_address.v6[3] = server_ipv6_ptr -> nxd_ipv6_address[3];
473 
474 #endif /* !NX_DISABLE_IPV6 */
475 
476 
477     /* Wait 5 seconds for the IP thread to finish its initilization and
478        for the IPv6 stack to finish DAD process. */
479     tx_thread_sleep(5 * NX_IP_PERIODIC_RATE);
480 
481     /* Create a UDP socket.  */
482     status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5);
483 
484     /* Check status.  */
485     if (status)
486     {
487         error_counter++;
488     }
489 
490     /* Bind the UDP socket to the IP port.  */
491     status =  nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER);
492 
493     /* Check status.  */
494     if (status)
495     {
496         error_counter++;
497     }
498 
499 
500     /* Loop to repeat things over and over again!  */
501     while (1)
502     {
503 
504 
505         /* Allocate a packet.  */
506         status =  nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER);
507 
508         /* Check status.  */
509         if (status != NX_SUCCESS)
510         {
511             break;
512         }
513 
514         /* Write ABCs into the packet payload!  */
515         nx_packet_data_append(my_packet, DEMO_DATA, sizeof(DEMO_DATA), &pool_0, TX_WAIT_FOREVER);
516 
517         /* Attempt to send the data. */
518         /* In this demo, we alternate between IPv4 connections and IPv6 connections. */
519         switch (thread_0_counter & (NUMBER_OF_TESTS - 1))
520         {
521 #ifndef NX_DISABLE_IPV4
522         case 0:
523             status =  nxd_udp_socket_source_send(&socket_0, my_packet, &ip1_primary_ipv4_address, 0x89, PRIMARY_INTERFACE);
524             break;
525         case 1:
526             status =  nxd_udp_socket_source_send(&socket_0, my_packet, &ip1_secondary_ipv4_address, 0x89, SECONDARY_INTERFACE);
527             break;
528 #ifndef NX_DISABLE_IPV6
529         case 2:
530             status =  nxd_udp_socket_source_send(&socket_0, my_packet, &ip1_primary_linklocal_address, 0x89, ip0_primary_linklocal_address_index);
531             break;
532         case 3:
533             status =  nxd_udp_socket_source_send(&socket_0, my_packet, &ip1_secondary_linklocal_address, 0x89, ip0_secondary_linklocal_address_index);
534             break;
535         case 4:
536             status =  nxd_udp_socket_source_send(&socket_0, my_packet, &ip1_primary_global_address, 0x89, ip0_primary_global_address_index);
537             break;
538         case 5:
539             status =  nxd_udp_socket_source_send(&socket_0, my_packet, &ip1_secondary_global_address, 0x89, ip0_secondary_global_address_index);
540             break;
541         case 6:
542             status =  nxd_udp_socket_send(&socket_0, my_packet, &ip1_primary_global_address, 0x89);
543             break;
544         case 7:
545             status =  nxd_udp_socket_send(&socket_0, my_packet, &ip1_secondary_global_address, 0x89);
546             break;
547 #endif /* !NX_DISABLE_IPV6 */
548 #else /* !NX_DISABLE_IPV4  */
549 #ifndef NX_DISABLE_IPV6
550         case 0:
551             status =  nxd_udp_socket_source_send(&socket_0, my_packet, &ip1_primary_linklocal_address, 0x89, ip0_primary_linklocal_address_index);
552             break;
553         case 1:
554             status =  nxd_udp_socket_source_send(&socket_0, my_packet, &ip1_secondary_linklocal_address, 0x89, ip0_secondary_linklocal_address_index);
555             break;
556         case 2:
557             status =  nxd_udp_socket_source_send(&socket_0, my_packet, &ip1_primary_global_address, 0x89, ip0_primary_global_address_index);
558             break;
559         case 3:
560             status =  nxd_udp_socket_source_send(&socket_0, my_packet, &ip1_secondary_global_address, 0x89, ip0_secondary_global_address_index);
561             break;
562         case 4:
563             status =  nxd_udp_socket_send(&socket_0, my_packet, &ip1_primary_global_address, 0x89);
564             break;
565         case 5:
566             status =  nxd_udp_socket_send(&socket_0, my_packet, &ip1_secondary_global_address, 0x89);
567             break;
568 #endif /* !NX_DISABLE_IPV6 */
569 #endif /* NX_DISABLE_IPV4 */
570         default:
571             break;
572         }
573         /* Check for error.  */
574         if (status)
575         {
576             nx_packet_release(my_packet);
577             error_counter++;
578         }
579 
580         /* Increment thread 0's counter.  */
581         thread_0_counter++;
582 
583 
584 
585         /* Relinquish to thread 1.  */
586         tx_thread_relinquish();
587     }
588 }
589 
590 
thread_1_entry(ULONG thread_input)591 void    thread_1_entry(ULONG thread_input)
592 {
593 
594 UINT       status;
595 NX_PACKET *my_packet;
596 ULONG      actual_status;
597 
598     NX_PARAMETER_NOT_USED(thread_input);
599 
600     /* Wait 5 seconds for the IP thread to finish its initilization and
601        for the IPv6 stack to finish DAD process. */
602     tx_thread_sleep(5 * NX_IP_PERIODIC_RATE);
603 
604 
605     /* Ensure the IP instance has been initialized.  */
606     status =  nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE);
607 
608     /* Check status...  */
609     if (status != NX_SUCCESS)
610     {
611 
612         error_counter++;
613     }
614 
615 
616 
617     /* Create a UDP socket.  */
618     status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5);
619 
620     /* Check status.  */
621     if (status)
622     {
623         error_counter++;
624     }
625 
626     /* Bind the UDP socket to the IP port.  */
627     status =  nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER);
628 
629     /* Check status.  */
630     if (status)
631     {
632         error_counter++;
633     }
634 
635     /* Loop to create and establish server connections.  */
636     while (1)
637     {
638 
639 
640         /* Receive a UDP packet.  */
641         status =  nx_udp_socket_receive(&socket_1, &my_packet, TX_WAIT_FOREVER);
642 
643         /* Check status.  */
644         if (status != NX_SUCCESS)
645         {
646             break;
647         }
648 
649         /* Release the packet.  */
650         status =  nx_packet_release(my_packet);
651 
652         /* Check status.  */
653         if (status != NX_SUCCESS)
654         {
655             break;
656         }
657 
658         /* Increment thread 1's counter.  */
659         thread_1_counter++;
660     }
661 }
662 #endif
663