1 /* This is a small demo of the NetX TCP/IP stack using the AUTO IP module. */
2
3 #include "nx_auto_ip.h"
4 #include "tx_api.h"
5 #include "nx_api.h"
6
7
8 #define DEMO_STACK_SIZE 4096
9
10 extern void test_control_return(UINT status);
11
12 #if !defined(NX_DISABLE_IPV4)
13
14 /* Define the ThreadX and NetX object control blocks... */
15
16 static TX_THREAD ntest_0;
17 static TX_THREAD ntest_1;
18 static NX_PACKET_POOL pool_0;
19 static NX_IP ip_0;
20 static NX_IP ip_1;
21 static NX_TCP_SOCKET server_socket;
22 static NX_TCP_SOCKET client_socket;
23 static TX_SEMAPHORE sema_0;
24 static TX_SEMAPHORE sema_1;
25
26
27 /* Define the AUTO IP structures for each IP instance. */
28
29 static NX_AUTO_IP auto_ip_0;
30 static NX_AUTO_IP auto_ip_1;
31
32
33 /* Define the counters used in the demo application... */
34 static ULONG address_changes;
35 static ULONG error_counter;
36 static ULONG packet_counter;
37 static ULONG conn_ip_address;
38
39 /* Define thread prototypes. */
40
41 static void ntest_0_entry(ULONG thread_input);
42 static void ntest_1_entry(ULONG thread_input);
43 static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port);
44 static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket);
45 static void ip_address_changed(NX_IP *ip_ptr, VOID *auto_ip_address);
46 extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req);
47 extern void test_control_return(UINT status);
48
49
50 /* Define what the initial system looks like. */
51 #ifdef CTEST
test_application_define(void * first_unused_memory)52 VOID test_application_define(void *first_unused_memory)
53 #else
54 void netx_auto_ip_basic_test_application_define(void *first_unused_memory)
55 #endif
56 {
57
58 CHAR *pointer;
59 UINT status;
60
61
62 /* Setup the working pointer. */
63 pointer = (CHAR *) first_unused_memory;
64
65 /* Initializes the variables. */
66 error_counter = 0;
67 packet_counter = 0;
68
69 /* Create the main thread. */
70 tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0,
71 pointer, DEMO_STACK_SIZE,
72 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
73 pointer = pointer + DEMO_STACK_SIZE;
74
75 /* Create the main thread. */
76 tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0,
77 pointer, DEMO_STACK_SIZE,
78 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
79 pointer = pointer + DEMO_STACK_SIZE;
80
81 /* Initialize the NetX system. */
82 nx_system_initialize();
83
84 /* Create a packet pool. */
85 status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16);
86 pointer = pointer + 1536*16;
87
88 if (status)
89 error_counter++;
90
91 /* Create an IP instance. */
92 status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver,
93 pointer, 4096, 1);
94 pointer = pointer + 4096;
95
96 /* Create another IP instance. */
97 status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver,
98 pointer, 4096, 1);
99 pointer = pointer + 4096;
100
101 if (status)
102 error_counter++;
103
104 /* Enable ARP and supply ARP cache memory for IP Instance 0. */
105 status = nx_arp_enable(&ip_0, (void *) pointer, 1024);
106 pointer = pointer + 1024;
107
108 /* Enable ARP and supply ARP cache memory for IP Instance 1. */
109 status += nx_arp_enable(&ip_1, (void *) pointer, 1024);
110 pointer = pointer + 1024;
111
112 /* Check ARP enable status. */
113 if (status)
114 error_counter++;
115
116 /* Enable TCP processing for both IP instances. */
117 status = nx_tcp_enable(&ip_0);
118 status += nx_tcp_enable(&ip_1);
119
120 /* Check UDP enable status. */
121 if (status)
122 error_counter++;
123
124 /* Create the AutoIP instance for each IP instance. */
125 status = nx_auto_ip_create(&auto_ip_0, "AutoIP 0", &ip_0, pointer, 4096, 2);
126 pointer = pointer + 4096;
127 status += nx_auto_ip_create(&auto_ip_1, "AutoIP 1", &ip_1, pointer, 4096, 2);
128 pointer = pointer + 4096;
129
130 /* Check AutoIP create status. */
131 if (status)
132 error_counter++;
133
134 /* Start both AutoIP instances. */
135 status = nx_auto_ip_start(&auto_ip_0, 0 /*IP_ADDRESS(169,254,254,255)*/);
136 status += nx_auto_ip_start(&auto_ip_1, 0 /*IP_ADDRESS(169,254,254,255)*/);
137
138 /* Check AutoIP start status. */
139 if (status)
140 error_counter++;
141
142 /* Register an IP address change function for each IP instance. */
143 status = nx_ip_address_change_notify(&ip_0, ip_address_changed, (void *) &auto_ip_0);
144 status += nx_ip_address_change_notify(&ip_1, ip_address_changed, (void *) &auto_ip_1);
145
146 /* Check IP address change notify status. */
147 if (status)
148 error_counter++;
149
150 /* Create semaphores. */
151 status = tx_semaphore_create(&sema_0, "SEMA 0", 0);
152 status += tx_semaphore_create(&sema_1, "SEMA 1", 0);
153
154 /* Check semaphore create status. */
155 if (status)
156 error_counter++;
157 }
158
159
160
161 /* Define the test threads. */
162
ntest_0_entry(ULONG thread_input)163 void ntest_0_entry(ULONG thread_input)
164 {
165
166 UINT status;
167 ULONG network_mask;
168
169 printf("NetX Test: Auto_IP Basic Processing Test.............................");
170
171 status = tx_semaphore_get(&sema_0, (NX_AUTO_IP_PROBE_NUM * NX_AUTO_IP_PROBE_MAX + NX_AUTO_IP_ANNOUNCE_NUM * NX_AUTO_IP_ANNOUNCE_INTERVAL) * NX_IP_PERIODIC_RATE);
172
173 /* Check status. */
174 if(status)
175 {
176 printf("ERROR!\n");
177 test_control_return(1);
178 }
179
180 /* Wakeup thread_1. */
181 tx_semaphore_put(&sema_1);
182
183 /* Pickup the current IP address. */
184
185 nx_ip_address_get(&ip_0, &conn_ip_address, &network_mask);
186
187 /* Check whether the AutoIP allocates addresses in the range of 169.254.1.0 through 169.254.254.255.*/
188 if((conn_ip_address & 0xFFFF0000UL) != IP_ADDRESS(169, 254, 0, 0) || (conn_ip_address < IP_ADDRESS(169, 254, 1, 0)) || (conn_ip_address > IP_ADDRESS(169, 254, 254, 255)))
189 {
190 printf("ERROR!\n");
191 test_control_return(1);
192 }
193
194 /* Create a TCP socket. */
195 status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket",
196 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200,
197 NX_NULL, ntest_0_disconnect_received);
198
199 /* Check status. */
200 if (status)
201 error_counter++;
202
203 /* Setup this thread to listen. */
204 status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received);
205
206 /* Check for error. */
207 if (status)
208 error_counter++;
209
210 /* Accept a client socket connection. */
211 status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE);
212
213 /* Check for error. */
214 if (status)
215 error_counter++;
216
217 /* Server socket disconnect the connection. */
218 status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE);
219
220 /* Check for error. */
221 if(status)
222 error_counter++;
223
224 /* Unaccepted the server socket. */
225 status = nx_tcp_server_socket_unaccept(&server_socket);
226
227 /* Check for error. */
228 if(status)
229 error_counter++;
230
231 /* Unlisted on the server port. */
232 status = nx_tcp_server_socket_unlisten(&ip_0, 12);
233
234 /* Check for error. */
235 if (status)
236 error_counter++;
237
238 /* Delete the socket. */
239 status = nx_tcp_socket_delete(&server_socket);
240
241 /* Check for error. */
242 if(status)
243 error_counter++;
244
245 /* Stop the AutoIP instance auto_ip_0. */
246 status = nx_auto_ip_stop(&auto_ip_0);
247
248 /* Check for error. */
249 if(status)
250 error_counter++;
251
252 /* Delete the AutoIP instance auto_ip_0. */
253 status = nx_auto_ip_delete(&auto_ip_0);
254
255 /* Check for error. */
256 if(status)
257 error_counter++;
258
259 }
260
261
ntest_1_entry(ULONG thread_input)262 void ntest_1_entry(ULONG thread_input)
263 {
264
265 UINT status;
266 ULONG ip_address;
267 ULONG network_mask;
268
269 status = tx_semaphore_get(&sema_1, (NX_AUTO_IP_PROBE_NUM * NX_AUTO_IP_PROBE_MAX + NX_AUTO_IP_ANNOUNCE_NUM * NX_AUTO_IP_ANNOUNCE_INTERVAL) * NX_IP_PERIODIC_RATE);
270
271 /* Check status. */
272 if(status)
273 {
274 printf("ERROR!\n");
275 test_control_return(1);
276 }
277
278 tx_semaphore_get(&sema_1, TX_WAIT_FOREVER);
279
280 /* Pickup the current IP address. */
281 nx_ip_address_get(&ip_1, &ip_address, &network_mask);
282
283 /* Check whether the AutoIP allocates addresses in the range of 169.254.1.0 through 169.254.254.255.*/
284 if((ip_address & 0xFFFF0000UL) != IP_ADDRESS(169, 254, 0, 0) || (ip_address < IP_ADDRESS(169, 254, 1, 0)) || (ip_address > IP_ADDRESS(169, 254, 254, 255)))
285 {
286 printf("ERROR!\n");
287 test_control_return(1);
288 }
289
290
291 /* Create a socket. */
292 status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket",
293 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200,
294 NX_NULL, NX_NULL);
295
296 /* Check for error. */
297 if (status)
298 error_counter++;
299
300 /* Bind the socket. */
301 status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE);
302
303 /* Check for error. */
304 if (status)
305 error_counter++;
306
307 /* Attempt to connect the socket. */
308 status = nx_tcp_client_socket_connect(&client_socket, conn_ip_address, 12, 5 * NX_IP_PERIODIC_RATE);
309
310 /* Check for error. */
311 if (status)
312 error_counter++;
313
314 /* Disconnect this socket. */
315 status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE);
316
317 /* Determine if the status is valid. */
318 if (status)
319 error_counter++;
320
321 /* Unbind the socket. */
322 status = nx_tcp_client_socket_unbind(&client_socket);
323
324 /* Check for error. */
325 if (status)
326 error_counter++;
327
328 /* Delete the socket. */
329 status = nx_tcp_socket_delete(&client_socket);
330
331 /* Check for error. */
332 if (status)
333 error_counter++;
334
335 /* Stop the AutoIP instance auto_ip_1. */
336 status = nx_auto_ip_stop(&auto_ip_1);
337
338 /* Check for error. */
339 if(status)
340 error_counter++;
341
342 /* Delete the AutoIP instance auto_ip_1. */
343 status = nx_auto_ip_delete(&auto_ip_1);
344
345 /* Check for error. */
346 if(status)
347 error_counter++;
348
349 /* Determine if the test was successful. */
350 if (error_counter)
351 {
352 printf("ERROR!\n");
353 test_control_return(1);
354 }
355 else
356 {
357 printf("SUCCESS!\n");
358 test_control_return(0);
359 }
360 }
361
ip_address_changed(NX_IP * ip_ptr,VOID * auto_ip_address)362 void ip_address_changed(NX_IP *ip_ptr, VOID *auto_ip_address)
363 {
364
365 ULONG ip_address;
366 ULONG network_mask;
367 NX_AUTO_IP *auto_ip_ptr;
368
369
370 /* Setup pointer to auto IP instance. */
371 auto_ip_ptr = (NX_AUTO_IP *) auto_ip_address;
372
373 /* Pickup the current IP address. */
374 nx_ip_address_get(ip_ptr, &ip_address, &network_mask);
375
376 /* Determine if the IP address has changed back to zero. If so, make sure the
377 AutoIP instance is started. */
378 if (ip_address == 0)
379 {
380
381 /* Get the last AutoIP address for this node. */
382 nx_auto_ip_get_address(auto_ip_ptr, &ip_address);
383
384 /* Start this AutoIP instance. */
385 nx_auto_ip_start(auto_ip_ptr, ip_address);
386 }
387
388 /* Determine if the IP address has transitioned to a non local IP address. */
389 else if ((ip_address & 0xFFFF0000UL) != IP_ADDRESS(169, 254, 0, 0))
390 {
391
392 /* Stop the AutoIP processing. */
393 nx_auto_ip_stop(auto_ip_ptr);
394
395 /* Delete the AutoIP instance. */
396 nx_auto_ip_delete(auto_ip_ptr);
397 }
398
399 /* Increment a counter. */
400 address_changes++;
401
402 /* Wakeup test threads. */
403 if(ip_ptr == &ip_0)
404 tx_semaphore_put(&sema_0);
405 else
406 tx_semaphore_put(&sema_1);
407 }
408
ntest_0_connect_received(NX_TCP_SOCKET * socket_ptr,UINT port)409 static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port)
410 {
411
412 /* Check for the proper socket and port. */
413 if ((socket_ptr != &server_socket) || (port != 12))
414 error_counter++;
415 }
416
ntest_0_disconnect_received(NX_TCP_SOCKET * socket)417 static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket)
418 {
419
420 /* Check for proper disconnected socket. */
421 if (socket != &server_socket)
422 error_counter++;
423 }
424 #else
425
426 #ifdef CTEST
test_application_define(void * first_unused_memory)427 VOID test_application_define(void *first_unused_memory)
428 #else
429 void netx_auto_ip_basic_test_application_define(void *first_unused_memory)
430 #endif
431 {
432
433 /* Print out test information banner. */
434 printf("NetX Test: Auto_IP Basic Processing Test.............................N/A\n");
435
436 test_control_return(3);
437 }
438 #endif
439