1 /* This NetX test concentrates on the basic BSD UDP non-blocking operation. */
2
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
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 NX_UDP_SOCKET server_socket;
21 static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)];
22 #define BSD_THREAD_PRIORITY 2
23 #define NUM_CLIENTS 20
24 /* Define the counters used in the test application... */
25
26 static ULONG error_counter;
27
28
29 /* Define thread prototypes. */
30
31 static void ntest_0_entry(ULONG thread_input);
32 static void ntest_1_entry(ULONG thread_input);
33 extern void test_control_return(UINT status);
34 extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req);
35 static void validate_bsd_structure(void);
36 #ifdef FEATURE_NX_IPV6
37 static NXD_ADDRESS ipv6_address_ip0;
38 static NXD_ADDRESS ipv6_address_ip1;
39 #endif /* FEATURE_NX_IPV6 */
40 static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"};
41 static char *response[4] = {"Response1", "Response2", "Response3", "Response4"};
42 static void validate_bsd_structure(void);
43 /* Define what the initial system looks like. */
44
45 #ifdef CTEST
test_application_define(void * first_unused_memory)46 VOID test_application_define(void *first_unused_memory)
47 #else
48 void netx_bsd_udp_basic_blocking_test_application_define(void *first_unused_memory)
49 #endif
50 {
51
52 CHAR *pointer;
53 UINT status;
54
55
56 /* Setup the working pointer. */
57 pointer = (CHAR *) first_unused_memory;
58
59 error_counter = 0;
60
61 /* Create the main thread. */
62 tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0,
63 pointer, DEMO_STACK_SIZE,
64 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
65
66 pointer = pointer + DEMO_STACK_SIZE;
67
68 /* Create the main thread. */
69 tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0,
70 pointer, DEMO_STACK_SIZE,
71 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
72
73 pointer = pointer + DEMO_STACK_SIZE;
74
75
76 /* Initialize the NetX system. */
77 nx_system_initialize();
78
79 /* Create a packet pool. */
80 status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2);
81 pointer = pointer + (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2;
82
83 if (status)
84 error_counter++;
85
86 /* Create an IP instance. */
87 status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256,
88 pointer, 2048, 1);
89 pointer = pointer + 2048;
90
91 /* Create another IP instance. */
92 status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256,
93 pointer, 2048, 2);
94 pointer = pointer + 2048;
95 if (status)
96 error_counter++;
97
98 /* Enable ARP and supply ARP cache memory for IP Instance 0. */
99 status = nx_arp_enable(&ip_0, (void *) pointer, 1024);
100 pointer = pointer + 1024;
101 if (status)
102 error_counter++;
103
104 /* Enable ARP and supply ARP cache memory for IP Instance 1. */
105 status = nx_arp_enable(&ip_1, (void *) pointer, 1024);
106 pointer = pointer + 1024;
107 if (status)
108 error_counter++;
109
110 /* Enable UDP processing for both IP instances. */
111 status = nx_udp_enable(&ip_0);
112 status += nx_udp_enable(&ip_1);
113
114 /* Enable BSD */
115 status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY);
116
117 /* Check UDP enable and BSD init status. */
118 if (status)
119 error_counter++;
120 }
121
122 #ifdef FEATURE_NX_IPV6
test_udp_server6(void)123 static void test_udp_server6(void)
124 {
125 int sockfd;
126 struct sockaddr_in6 remote_addr, local_addr;
127 int ret;
128 char buf[30];
129 int addrlen;
130
131
132 sockfd = socket(AF_INET6, SOCK_DGRAM, 0);
133 if(sockfd < 0)
134 error_counter++;
135 memset(&local_addr, 0, sizeof(local_addr));
136 local_addr.sin6_family = AF_INET6;
137 local_addr.sin6_port = htons(12345);
138
139
140 ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr));
141 if(ret < 0)
142 error_counter++;
143
144 /* Receive data from the client. */
145 addrlen = sizeof(remote_addr);
146 ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen);
147 if(ret <= 0)
148 error_counter++;
149
150 if(addrlen != sizeof(struct sockaddr_in6))
151 error_counter++;
152
153 if((remote_addr.sin6_family != AF_INET6) ||
154 (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) ||
155 (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) ||
156 (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) ||
157 (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3])) ||
158 (remote_addr.sin6_port != htons(54321)))
159 error_counter++;
160
161 /* Validate the data. */
162 if((ret != (INT)strlen(requests[1])) || strncmp(buf, requests[1], ret))
163 error_counter++;
164
165 /* Send a response back. */
166 ret = sendto(sockfd, response[1], strlen(response[1]), 0, (struct sockaddr*)&remote_addr, addrlen);
167 if(ret != (INT)strlen(response[1]))
168 error_counter++;
169
170
171 /* Close downt he socket. */
172 ret = soc_close(sockfd);
173 if(ret < 0)
174 error_counter++;
175
176 }
177 #endif /* FEATURE_NX_IPV6 */
178
test_udp_server4(void)179 static void test_udp_server4(void)
180 {
181 int sockfd;
182 struct sockaddr_in remote_addr, local_addr;
183 int ret;
184 char buf[30];
185 int addrlen;
186
187
188 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
189 if(sockfd < 0)
190 error_counter++;
191
192 local_addr.sin_family = AF_INET;
193 local_addr.sin_port = htons(12345);
194 local_addr.sin_addr.s_addr = INADDR_ANY;
195
196 ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr));
197 if(ret < 0)
198 error_counter++;
199
200 /* Receive data from the client. */
201 addrlen = sizeof(remote_addr);
202 ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen);
203 if(ret <= 0)
204 error_counter++;
205
206 if(addrlen != sizeof(struct sockaddr_in))
207 error_counter++;
208
209 if((remote_addr.sin_family != AF_INET) ||
210 (remote_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1,2,3,5))) ||
211 (remote_addr.sin_port != htons(54321)))
212 error_counter++;
213
214 /* Validate the data. */
215 if((ret != (int)strlen(requests[0])) || strncmp(buf, requests[0], ret))
216 error_counter++;
217
218 /* Send a response back. */
219 ret = sendto(sockfd, response[0], strlen(response[0]), 0, (struct sockaddr*)&remote_addr, addrlen);
220 if(ret != (int)strlen(response[0]))
221 error_counter++;
222
223
224 /* Close downt he socket. */
225 ret = soc_close(sockfd);
226 if(ret < 0)
227 error_counter++;
228
229 }
230
231
232
233 /* Define the test threads. */
ntest_0_entry(ULONG thread_input)234 static void ntest_0_entry(ULONG thread_input)
235 {
236 #ifdef FEATURE_NX_IPV6
237 char mac_ip0[6];
238 char mac_ip1[6];
239 UINT status;
240 #endif
241
242
243 printf("NetX Test: Basic BSD UDP Blocking Test...................");
244
245 /* Check for earlier error. */
246 if (error_counter)
247 {
248
249 printf("ERROR!\n");
250 test_control_return(1);
251 }
252
253 #ifdef FEATURE_NX_IPV6
254 /* First set up IPv6 addresses. */
255 ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6;
256 ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000;
257 ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000;
258 ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff;
259 ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456;
260
261 ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6;
262 ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000;
263 ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000;
264 ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff;
265 ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457;
266
267 status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL);
268 status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL);
269
270 status += nxd_ipv6_enable(&ip_0);
271 status += nxd_ipv6_enable(&ip_1);
272
273 mac_ip0[0] = (char)(ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8);
274 mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF;
275 mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff;
276 mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff;
277 mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff;
278 mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff;
279
280 mac_ip1[0] = (char)(ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8);
281 mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF;
282 mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff;
283 mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff;
284 mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff;
285 mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff;
286
287 status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0, mac_ip1);
288 status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip0);
289
290 if(status)
291 error_counter++;
292 #endif
293 test_udp_server4();
294
295 tx_thread_sleep(3);
296
297 #ifdef FEATURE_NX_IPV6
298 test_udp_server6();
299 #endif
300
301
302 tx_thread_sleep(1);
303
304 validate_bsd_structure();
305
306 if(error_counter)
307 printf("ERROR!\n");
308 else
309 printf("SUCCESS!\n");
310
311 if(error_counter)
312 test_control_return(1);
313
314 test_control_return(0);
315 }
316
ntest_1_entry(ULONG thread_input)317 static void ntest_1_entry(ULONG thread_input)
318 {
319
320 UINT status;
321 NX_PACKET *packet_ptr;
322 ULONG actual_status;
323
324
325
326 /* Ensure the IP instance has been initialized. */
327 status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE);
328
329 /* Check status... */
330 if (status != NX_SUCCESS)
331 {
332
333 printf("ERROR!\n");
334 test_control_return(3);
335 }
336
337 /* Create a socket. */
338 status = nx_udp_socket_create(&ip_1, &server_socket, "Server Socket",
339 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 10);
340
341 /* Check for error. */
342 if (status)
343 error_counter++;
344
345 /* Allocate a packet. */
346 status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_WAIT_FOREVER);
347 if (status)
348 error_counter++;
349
350 /* Fill in the packet with data */
351 memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[0], strlen(requests[0]));
352
353 packet_ptr -> nx_packet_length = strlen(requests[0]);
354 packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
355
356 /* Bind to a UDP port. */
357 status = nx_udp_socket_bind(&server_socket, 54321, NX_WAIT_FOREVER);
358 if(status)
359 error_counter++;
360
361 /* Send a UDP packet */
362 status = nx_udp_socket_send(&server_socket, packet_ptr, IP_ADDRESS(1,2,3,4), 12345);
363 if(status)
364 error_counter++;
365
366 /* Ready to reaceive a message */
367 status = nx_udp_socket_receive(&server_socket, &packet_ptr, NX_WAIT_FOREVER);
368 if(status)
369 error_counter++;
370
371 /* Validate the content. */
372 if(packet_ptr -> nx_packet_length != strlen(response[0]))
373 error_counter++;
374 else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[0], strlen(response[0])))
375 error_counter++;
376
377
378 status = nx_udp_socket_unbind(&server_socket);
379 if(status)
380 error_counter++;
381
382 status = nx_udp_socket_delete(&server_socket);
383 if(status)
384 error_counter++;
385
386 #ifdef FEATURE_NX_IPV6
387 tx_thread_sleep(3);
388
389
390 /* Create a socket. */
391 status = nx_udp_socket_create(&ip_1, &server_socket, "Server Socket",
392 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 10);
393
394 /* Check for error. */
395 if (status)
396 error_counter++;
397
398 /* Allocate a packet. */
399 status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_WAIT_FOREVER);
400 if (status)
401 error_counter++;
402
403 /* Fill in the packet with data */
404 memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[1], strlen(requests[1]));
405
406 packet_ptr -> nx_packet_length = strlen(requests[1]);
407 packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
408
409 /* Bind to a UDP port. */
410 status = nx_udp_socket_bind(&server_socket, 54321, NX_WAIT_FOREVER);
411 if(status)
412 error_counter++;
413
414 /* Send a UDP packet */
415 status = nxd_udp_socket_send(&server_socket, packet_ptr, &ipv6_address_ip0, 12345);
416 if(status)
417 error_counter++;
418
419 error_counter++;
420 /* Ready to reaceive a message */
421 status = nx_udp_socket_receive(&server_socket, &packet_ptr, NX_WAIT_FOREVER);
422 if(status)
423 error_counter++;
424
425 /* Validate the content. */
426 if(packet_ptr -> nx_packet_length != strlen(response[1]))
427 error_counter++;
428 else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[1], strlen(response[1])))
429 error_counter++;
430 else
431 error_counter--;
432
433 status = nx_udp_socket_unbind(&server_socket);
434 if(status)
435 error_counter++;
436
437 status = nx_udp_socket_delete(&server_socket);
438 if(status)
439 error_counter++;
440
441 #endif
442
443 }
444
445 extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS];
446 extern TX_BLOCK_POOL nx_bsd_socket_block_pool;
validate_bsd_structure(void)447 static void validate_bsd_structure(void)
448 {
449 int i;
450 /* Make sure every BSD socket should be free by now. */
451
452 for(i = 0; i < NX_BSD_MAX_SOCKETS; i++)
453 {
454 if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE)
455 {
456 error_counter++;
457 }
458
459 if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket ||
460 nx_bsd_socket_array[i].nx_bsd_socket_udp_socket)
461 {
462 error_counter++;
463 }
464 }
465
466 /* Make sure all the NX SOCKET control blocks are released. */
467 if(nx_bsd_socket_block_pool.tx_block_pool_available !=
468 nx_bsd_socket_block_pool.tx_block_pool_total)
469 {
470 error_counter++;
471 }
472
473 /* Make sure all the sockets are released */
474 if(ip_0.nx_ip_tcp_created_sockets_ptr ||
475 ip_0.nx_ip_udp_created_sockets_ptr)
476 {
477 error_counter++;
478 return;
479 }
480 }
481
482 #else
483 extern void test_control_return(UINT status);
484
485 #ifdef CTEST
test_application_define(void * first_unused_memory)486 VOID test_application_define(void *first_unused_memory)
487 #else
488 void netx_bsd_udp_basic_blocking_test_application_define(void *first_unused_memory)
489 #endif
490 {
491
492 /* Print out test information banner. */
493 printf("NetX Test: Basic BSD UDP Blocking Test...................N/A\n");
494
495 test_control_return(3);
496 }
497 #endif
498