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