1 /* This NetX test concentrates on the basic BSD UDP blocking operation.  */
2 /* The BSD APIs involved in this test are:  socket(), connect(), send(), soc_close() */
3 
4 #include   "tx_api.h"
5 #include   "nx_api.h"
6 #if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4)
7 #include   "nx_icmpv6.h"
8 #include   "nxd_bsd.h"
9 #define     DEMO_STACK_SIZE         4096
10 #define     NUM_MESSAGES              20
11 
12 /* Define the ThreadX and NetX object control blocks...  */
13 
14 static TX_THREAD               ntest_0;
15 static TX_THREAD               ntest_1;
16 
17 static NX_PACKET_POOL          pool_0;
18 static NX_IP                   ip_0;
19 static NX_IP                   ip_1;
20 static ULONG                   bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)];
21 #define BSD_THREAD_PRIORITY    2
22 #define NUM_CLIENTS            10
23 /* Define the counters used in the test application...  */
24 
25 static ULONG                   error_counter;
26 static ULONG                   packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4];
27 
28 /* Define thread prototypes.  */
29 
30 static void    ntest_0_entry(ULONG thread_input);
31 static void    ntest_1_entry(ULONG thread_input);
32 extern void    test_control_return(UINT status);
33 extern void    _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req);
34 static void    validate_bsd_structure(void);
35 extern NX_BSD_SOCKET  nx_bsd_socket_array[NX_BSD_MAX_SOCKETS];
36 #ifdef FEATURE_NX_IPV6
37 static NXD_ADDRESS ipv6_address_ip0;
38 static NXD_ADDRESS ipv6_address_ip1;
39 #endif
40 static char *bsd_send_buffer  = "From BSD Test";
41 static char *netx_send_buffer  = "From Native NetX Test";
42 #ifdef FEATURE_NX_IPV6
43 static char *bsd_send_buffer6 = "From BSD Test 6";
44 static char *netx_send_buffer6 = "From Native NetX Test 6";
45 #endif
46 
47 static void validate_bsd_structure(void);
48 
49 static char *bsd_transmit_v4_thread_stack;
50 static char *bsd_receive_v4_thread_stack;
51 static char *netx_transmit_thread_stack;
52 static char *netx_receive_thread_stack;
53 
54 
55 static TX_THREAD netx_transmit_thread;
56 static TX_THREAD netx_receive_thread;
57 static TX_THREAD bsd_transmit_v4_thread;
58 static TX_THREAD bsd_receive_v4_thread;
59 
60 
61 
62 #ifdef FEATURE_NX_IPV6
63 static char *bsd_transmit_v6_thread_stack;
64 static char *bsd_receive_v6_thread_stack;
65 
66 static TX_THREAD bsd_transmit_v6_thread;
67 static TX_THREAD bsd_receive_v6_thread;
68 #endif
69 
70 static TX_SEMAPHORE bsd_sema;
71 static TX_SEMAPHORE netx_sema;
72 
73 /* Define what the initial system looks like.  */
74 
75 #ifdef CTEST
test_application_define(void * first_unused_memory)76 VOID test_application_define(void *first_unused_memory)
77 #else
78 void    netx_bsd_udp_blocking_bidirection_test_application_define(void *first_unused_memory)
79 #endif
80 {
81 
82 CHAR    *pointer;
83 UINT    status;
84 
85 
86     /* Setup the working pointer.  */
87     pointer =  (CHAR *) first_unused_memory;
88 
89     error_counter =  0;
90 
91     /* Create the main thread.  */
92     tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0,
93                      pointer, DEMO_STACK_SIZE,
94                      2, 2, TX_NO_TIME_SLICE, TX_AUTO_START);
95 
96     pointer =  pointer + DEMO_STACK_SIZE;
97 
98     /* Create the main thread.  */
99     tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0,
100                      pointer, DEMO_STACK_SIZE,
101                      3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
102 
103     pointer =  pointer + DEMO_STACK_SIZE;
104 
105 
106     /* Initialize the NetX system.  */
107     nx_system_initialize();
108 
109     /* Create a packet pool.  */
110     status =  nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area));
111 
112 
113     if (status)
114         error_counter++;
115 
116     /* Create an IP instance.  */
117     status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256,
118                     pointer, 2048, 1);
119     pointer =  pointer + 2048;
120 
121     /* Create another IP instance.  */
122     status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256,
123                     pointer, 2048, 1);
124     pointer =  pointer + 2048;
125     if (status)
126         error_counter++;
127 
128     /* Enable ARP and supply ARP cache memory for IP Instance 0.  */
129     status =  nx_arp_enable(&ip_0, (void *) pointer, 1024);
130     pointer = pointer + 1024;
131     if (status)
132         error_counter++;
133 
134     /* Enable ARP and supply ARP cache memory for IP Instance 1.  */
135     status  =  nx_arp_enable(&ip_1, (void *) pointer, 1024);
136     pointer = pointer + 1024;
137     if (status)
138         error_counter++;
139 
140     /* Enable UDP processing for both IP instances.  */
141     status =  nx_udp_enable(&ip_0);
142     status += nx_udp_enable(&ip_1);
143 
144     /* Enable BSD */
145     status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY);
146 
147     /* Check UDP enable status.  */
148     if (status)
149         error_counter++;
150 
151     netx_transmit_thread_stack = pointer;
152     pointer = pointer + DEMO_STACK_SIZE;
153     netx_receive_thread_stack = pointer;
154     pointer = pointer + DEMO_STACK_SIZE;
155 
156     bsd_transmit_v4_thread_stack = pointer;
157     pointer = pointer + DEMO_STACK_SIZE;
158     bsd_receive_v4_thread_stack = pointer;
159     pointer = pointer + DEMO_STACK_SIZE;
160 
161 #ifdef FEATURE_NX_IPV6
162     bsd_transmit_v6_thread_stack = pointer;
163     pointer = pointer + DEMO_STACK_SIZE;
164     bsd_receive_v6_thread_stack = pointer;
165     pointer = pointer + DEMO_STACK_SIZE;
166 #endif
167 
168     status = tx_semaphore_create(&netx_sema, "NetX test done", 0);
169     status += tx_semaphore_create(&bsd_sema, "BSD test done", 0);
170     if(status != TX_SUCCESS)
171         error_counter++;
172 }
173 
transmit_entry(ULONG thread_input)174 static void    transmit_entry(ULONG thread_input)
175 {
176 int sockfd = thread_input;
177 int ret;
178 int i;
179 struct sockaddr_in peer_addr;
180 
181 
182     for(i = 0; i < NUM_MESSAGES; i++)
183     {
184 
185         peer_addr.sin_family = AF_INET;
186         peer_addr.sin_port = htons(12345);
187         peer_addr.sin_addr.s_addr = htonl(IP_ADDRESS(1, 2, 3, 5));
188 
189         ret = sendto(sockfd, bsd_send_buffer, strlen(bsd_send_buffer), 0, (struct sockaddr*)&peer_addr, sizeof(peer_addr));
190 
191         if(ret != (int)strlen(bsd_send_buffer))
192             error_counter++;
193 
194         tx_thread_relinquish();
195     }
196 
197     tx_semaphore_put(&bsd_sema);
198 
199 }
200 
receive_entry(ULONG thread_input)201 static void    receive_entry(ULONG thread_input)
202 {
203 int  sockfd = thread_input;
204 int  ret;
205 int  i;
206 char buffer[30];
207 struct sockaddr_in peer_addr;
208 int    peer_addr_len;
209 
210 
211     for(i = 0; i < NUM_MESSAGES; i++)
212     {
213         peer_addr_len = sizeof(peer_addr);
214 
215         ret = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&peer_addr, &peer_addr_len);
216 
217         if(peer_addr_len != sizeof(peer_addr))
218             error_counter++;
219         else if((peer_addr.sin_family != AF_INET) ||
220                 (peer_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1, 2, 3, 5))))
221             error_counter++;
222 
223         if(ret != (int)strlen(netx_send_buffer))
224             error_counter++;
225         else if(strncmp(buffer, netx_send_buffer, ret))
226             error_counter++;
227 
228         tx_thread_relinquish();
229     }
230 
231     tx_semaphore_put(&bsd_sema);
232 
233 }
234 
235 #ifdef FEATURE_NX_IPV6
transmit6_entry(ULONG thread_input)236 static void    transmit6_entry(ULONG thread_input)
237 {
238 int sockfd = thread_input;
239 int ret;
240 int i;
241 struct sockaddr_in6 peer_address6;
242 
243 
244 
245     for(i = 0; i < NUM_MESSAGES; i++)
246     {
247 
248         peer_address6.sin6_family = AF_INET6;
249         peer_address6.sin6_port = htons(12345);
250         peer_address6.sin6_addr._S6_un._S6_u32[0] = htonl(ipv6_address_ip1.nxd_ip_address.v6[0]);
251         peer_address6.sin6_addr._S6_un._S6_u32[1] = htonl(ipv6_address_ip1.nxd_ip_address.v6[1]);
252         peer_address6.sin6_addr._S6_un._S6_u32[2] = htonl(ipv6_address_ip1.nxd_ip_address.v6[2]);
253         peer_address6.sin6_addr._S6_un._S6_u32[3] = htonl(ipv6_address_ip1.nxd_ip_address.v6[3]);
254 
255         ret = sendto(sockfd, bsd_send_buffer6, strlen(bsd_send_buffer6), 0, (struct sockaddr*)&peer_address6, sizeof(peer_address6));
256 
257         if(ret != (INT)strlen(bsd_send_buffer6))
258             error_counter++;
259 
260         tx_thread_relinquish();
261     }
262 
263     tx_semaphore_put(&bsd_sema);
264 
265 }
266 
receive6_entry(ULONG thread_input)267 static void    receive6_entry(ULONG thread_input)
268 {
269 int  sockfd = thread_input;
270 int  ret;
271 int  i;
272 char buffer[30];
273 struct sockaddr_in6 peer_addr;
274 int peer_addr_len;
275 
276     for(i = 0; i < NUM_MESSAGES; i++)
277     {
278         peer_addr_len = sizeof(peer_addr);
279 
280         ret = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&peer_addr, &peer_addr_len);
281 
282         if(peer_addr_len != sizeof(peer_addr))
283             error_counter++;
284         else if((peer_addr.sin6_family != AF_INET6) ||
285                 (peer_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) ||
286                 (peer_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) ||
287                 (peer_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) ||
288                 (peer_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3])))
289             error_counter++;
290 
291 
292         if(ret != (INT)strlen(netx_send_buffer6))
293             error_counter++;
294         else if(strncmp(buffer, netx_send_buffer6, ret))
295             error_counter++;
296 
297         tx_thread_relinquish();
298     }
299 
300     tx_semaphore_put(&bsd_sema);
301 
302 }
303 
304 #endif
305 
306 
307 /* Define the test threads.  */
ntest_0_entry(ULONG thread_input)308 static void    ntest_0_entry(ULONG thread_input)
309 {
310 int                 sockfd;
311 struct sockaddr_in  local_addr;
312 UINT                status;
313 #ifdef FEATURE_NX_IPV6
314 struct sockaddr_in6 local_addr6;
315 char                mac_ip0[6];
316 char                mac_ip1[6];
317 int                 sockfd6;
318 INT                 reuseaddr = 1;
319 #endif
320 int                 ret;
321 
322     printf("NetX Test:   Basic BSD UDP Blocking Bidirection Test.......");
323 
324     /* Check for earlier error.  */
325     if (error_counter)
326     {
327 
328         printf("ERROR!\n");
329         test_control_return(1);
330     }
331 #ifdef FEATURE_NX_IPV6
332     /* First set up IPv6 addresses. */
333     ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6;
334     ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000;
335     ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000;
336     ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff;
337     ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456;
338 
339     ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6;
340     ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000;
341     ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000;
342     ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff;
343     ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457;
344 
345     status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL);
346     status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL);
347 
348     status += nxd_ipv6_enable(&ip_0);
349     status += nxd_ipv6_enable(&ip_1);
350 
351     mac_ip0[0] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8;
352     mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF;
353     mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff;
354     mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff;
355     mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff;
356     mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw  & 0xff;
357 
358     mac_ip1[0] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8;
359     mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF;
360     mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff;
361     mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff;
362     mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff;
363     mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw  & 0xff;
364 
365     status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0,  mac_ip1);
366     status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0,  mac_ip0);
367 
368     if(status)
369         error_counter++;
370 
371     tx_thread_sleep(5 * NX_IP_PERIODIC_RATE);
372 #endif
373     tx_semaphore_put(&netx_sema);
374 
375     /* Set up UDP socket */
376     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
377     if(sockfd <= 0)
378         error_counter++;
379 
380     memset(&local_addr, 0, sizeof(local_addr));
381     local_addr.sin_family = AF_INET;
382     local_addr.sin_port = htons(12345);
383 
384 
385     ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr));
386 
387     tx_thread_sleep(20);
388 
389     /* Create a thread to handle IPv4 UDP receive */
390     ret = tx_thread_create(&bsd_transmit_v4_thread, "transmit v4 thread", transmit_entry, sockfd,
391                            bsd_transmit_v4_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START);
392 
393     ret += tx_thread_create(&bsd_receive_v4_thread, "receive v4 thread", receive_entry, sockfd,
394                             bsd_receive_v4_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START);
395     if(ret != TX_SUCCESS)
396         error_counter++;
397 
398 #ifdef FEATURE_NX_IPV6
399     /* Set up UDP socket  */
400     sockfd6 = socket(AF_INET6, SOCK_DGRAM, 0);
401     if(sockfd6 <= 0)
402         error_counter++;
403 
404     setsockopt(sockfd6, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(INT));
405     memset(&local_addr6, 0, sizeof(local_addr6));
406     local_addr6.sin6_family = AF_INET6;
407     local_addr6.sin6_port = htons(12345);
408 
409     ret = bind(sockfd6, (struct sockaddr*)&local_addr6, sizeof(local_addr6));
410     if(ret)
411         error_counter++;
412 
413     /* Create a thread to handle IPv6 UDP receive */
414     ret = tx_thread_create(&bsd_transmit_v6_thread, "transmit v6 thread", transmit6_entry, sockfd6,
415                            bsd_transmit_v6_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START);
416 
417     ret += tx_thread_create(&bsd_receive_v6_thread, "receive v6 thread", receive6_entry, sockfd6,
418                             bsd_receive_v6_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START);
419 
420     if(ret != TX_SUCCESS)
421         error_counter++;
422 
423 #endif
424 
425     status = tx_semaphore_get(&bsd_sema, TX_WAIT_FOREVER);
426     status = tx_semaphore_get(&bsd_sema, TX_WAIT_FOREVER);
427 
428     /* Close down both sockets. */
429 #ifdef FEATURE_NX_IPV6
430     status = tx_semaphore_get(&bsd_sema, TX_WAIT_FOREVER);
431     status = tx_semaphore_get(&bsd_sema, TX_WAIT_FOREVER);
432     ret = soc_close(sockfd6);
433 #endif
434     ret += soc_close(sockfd);
435     if(ret)
436         error_counter++;
437 #ifdef FEATURE_NX_IPV6
438     tx_thread_delete(&bsd_transmit_v6_thread);
439     tx_thread_delete(&bsd_receive_v6_thread);
440 #endif
441 
442     tx_thread_delete(&bsd_transmit_v4_thread);
443     tx_thread_delete(&bsd_receive_v4_thread);
444 
445     if(status)
446         error_counter++;
447 
448     validate_bsd_structure();
449 
450     if(error_counter)
451         printf("ERROR!\n");
452     else
453         printf("SUCCESS!\n");
454 
455     if(error_counter)
456         test_control_return(1);
457 
458     test_control_return(0);
459 }
460 
netx_transmit_entry(ULONG param)461 static void    netx_transmit_entry(ULONG param)
462 {
463 NX_UDP_SOCKET *socket_ptr = (NX_UDP_SOCKET*)param;
464 int i;
465 NX_PACKET *packet_ptr;
466 ULONG status;
467 
468 
469     for(i = 0; i < NUM_MESSAGES; i++)
470     {
471 
472         status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_NO_WAIT);
473         status += nx_packet_data_append(packet_ptr, netx_send_buffer, strlen(netx_send_buffer),
474                                         &pool_0, NX_NO_WAIT);
475         status += nx_udp_socket_send(socket_ptr, packet_ptr, IP_ADDRESS(1,2,3,4), 12345);
476 
477         if(status != NX_SUCCESS)
478             error_counter++;
479 #ifdef FEATURE_NX_IPV6
480         status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_NO_WAIT);
481         status += nx_packet_data_append(packet_ptr, netx_send_buffer6, strlen(netx_send_buffer6),
482                                         &pool_0, NX_NO_WAIT);
483         status += nxd_udp_socket_send(socket_ptr, packet_ptr, &ipv6_address_ip0, 12345);
484 
485         if(status != NX_SUCCESS)
486             error_counter++;
487 #endif
488 
489         tx_thread_relinquish();
490     }
491 
492     tx_semaphore_put(&netx_sema);
493 }
494 
netx_receive_entry(ULONG param)495 static void    netx_receive_entry(ULONG param)
496 {
497 NX_UDP_SOCKET *socket_ptr = (NX_UDP_SOCKET*)param;
498 int i;
499 NX_PACKET *packet_ptr;
500 ULONG status;
501 int   num_messages;
502 
503     num_messages = NUM_MESSAGES;
504 
505 #ifdef FEATURE_NX_IPV6
506     num_messages += NUM_MESSAGES;
507 #endif
508 
509     for(i = 0; i < num_messages; i++)
510     {
511 
512         /* Receive a UDP message from the socket.  */
513         status =  nx_udp_socket_receive(socket_ptr, &packet_ptr, 2 * NX_IP_PERIODIC_RATE);
514 
515 
516         if(status)
517             error_counter++;
518 #ifdef __PRODUCT_NETXDUO__
519         else if(packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V4)
520 #endif
521         {
522             if(packet_ptr -> nx_packet_length != strlen(bsd_send_buffer))
523                 error_counter++;
524             else if(memcmp(packet_ptr -> nx_packet_prepend_ptr, bsd_send_buffer, packet_ptr -> nx_packet_length))
525                 error_counter++;
526         }
527 #ifdef FEATURE_NX_IPV6
528         else if(packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6)
529         {
530             if (packet_ptr -> nx_packet_length != strlen(bsd_send_buffer6))
531                 error_counter++;
532             if(memcmp(packet_ptr -> nx_packet_prepend_ptr, bsd_send_buffer6, packet_ptr -> nx_packet_length))
533                 error_counter++;
534         }
535 #endif
536 #ifdef __PRODUCT_NETXDUO__
537         else
538             error_counter++;
539 #endif
540 
541         nx_packet_release(packet_ptr);
542 
543         tx_thread_relinquish();
544     }
545 
546     tx_semaphore_put(&netx_sema);
547 }
548 
549 
550 
netx_udp_test(void)551 static void    netx_udp_test(void)
552 {
553 NX_UDP_SOCKET    udp_socket;
554 UINT             status;
555     /* Create a socket.  */
556     status =  nx_udp_socket_create(&ip_1, &udp_socket, "Server Socket",
557                                    NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1 * NX_IP_PERIODIC_RATE);
558 
559 
560     /* Check for error.  */
561     if (status)
562         error_counter++;
563 
564     status = nx_udp_socket_bind(&udp_socket, 12345, NX_WAIT_FOREVER);
565     if(status)
566         error_counter++;
567 
568     tx_thread_sleep(20);
569 
570     status = tx_thread_create(&netx_transmit_thread, "netx transmit thread", netx_transmit_entry, (ULONG)&udp_socket,
571                               netx_transmit_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START);
572 
573     status += tx_thread_create(&netx_receive_thread, "netx receive thread", netx_receive_entry, (ULONG)&udp_socket,
574                                netx_receive_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START);
575 
576     if(status != TX_SUCCESS)
577         error_counter++;
578 
579 
580     tx_semaphore_get(&netx_sema, TX_WAIT_FOREVER);
581     tx_semaphore_get(&netx_sema, TX_WAIT_FOREVER);
582 
583 
584     tx_thread_delete(&netx_transmit_thread);
585     tx_thread_delete(&netx_receive_thread);
586 
587     /* Unaccept the server socket.  */
588     status =  nx_udp_socket_unbind(&udp_socket);
589 
590     status += nx_udp_socket_delete(&udp_socket);
591     /* Check for error.  */
592     if (status)
593         error_counter++;
594 
595 }
596 
597 
ntest_1_entry(ULONG thread_input)598 static void    ntest_1_entry(ULONG thread_input)
599 {
600 
601 UINT            status;
602 ULONG           actual_status;
603 
604 
605 
606     /* Ensure the IP instance has been initialized.  */
607     status =  nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE);
608 
609     /* Check status...  */
610     if (status != NX_SUCCESS)
611     {
612 
613         printf("ERROR!\n");
614         test_control_return(3);
615     }
616 
617 
618     tx_semaphore_get(&netx_sema, TX_WAIT_FOREVER);
619     netx_udp_test();
620 
621 
622 }
623 
624 
625 extern TX_BLOCK_POOL nx_bsd_socket_block_pool;
validate_bsd_structure(void)626 static void validate_bsd_structure(void)
627 {
628 int i;
629     /* Make sure every BSD socket should be free by now. */
630 
631     for(i = 0; i < NX_BSD_MAX_SOCKETS; i++)
632     {
633         if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE)
634         {
635             error_counter++;
636         }
637 
638         if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket ||
639            nx_bsd_socket_array[i].nx_bsd_socket_udp_socket)
640         {
641             error_counter++;
642         }
643     }
644 
645     /* Make sure all the NX SOCKET control blocks are released. */
646     if(nx_bsd_socket_block_pool.tx_block_pool_available !=
647        nx_bsd_socket_block_pool.tx_block_pool_total)
648     {
649         error_counter++;
650     }
651 
652     /* Make sure all the sockets are released */
653     if(ip_0.nx_ip_tcp_created_sockets_ptr ||
654        ip_0.nx_ip_udp_created_sockets_ptr)
655     {
656         error_counter++;
657         return;
658     }
659 }
660 
661 #else
662 extern void       test_control_return(UINT status);
663 
664 #ifdef CTEST
test_application_define(void * first_unused_memory)665 VOID test_application_define(void *first_unused_memory)
666 #else
667 void    netx_bsd_udp_blocking_bidirection_test_application_define(void *first_unused_memory)
668 #endif
669 {
670 
671     /* Print out test information banner.  */
672     printf("NetX Test:   Basic BSD UDP Blocking Bidirection Test.......N/A\n");
673 
674     test_control_return(3);
675 }
676 #endif
677