1 /* This NetX test concentrates on the wrapping of RX and TX sequence numbers. */
2
3 #include "tx_api.h"
4 #include "nx_api.h"
5 extern void test_control_return(UINT status);
6
7 #if !defined(NX_DISABLE_IPV4)
8
9 #define DEMO_STACK_SIZE 2048
10
11
12 /* Define the ThreadX and NetX object control blocks... */
13
14 static TX_THREAD thread_0;
15 static TX_THREAD thread_1;
16
17 static NX_PACKET_POOL pool_0;
18 static NX_IP ip_0;
19 static NX_IP ip_1;
20 static NX_TCP_SOCKET client_socket;
21 static NX_TCP_SOCKET server_socket;
22
23
24
25 /* Define the counters used in the demo application... */
26
27 static ULONG thread_0_counter;
28 static ULONG thread_1_counter;
29 static ULONG error_counter;
30
31
32 /* Define thread prototypes. */
33
34 static void thread_0_entry(ULONG thread_input);
35 static void thread_1_entry(ULONG thread_input);
36 static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port);
37 static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket);
38 extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req);
39
40
41 /* Define what the initial system looks like. */
42
43 #ifdef CTEST
test_application_define(void * first_unused_memory)44 VOID test_application_define(void *first_unused_memory)
45 #else
46 void netx_tcp_wrapping_sequence_test_application_define(void *first_unused_memory)
47 #endif
48 {
49
50 CHAR *pointer;
51 UINT status;
52
53
54 /* Setup the working pointer. */
55 pointer = (CHAR *) first_unused_memory;
56
57 thread_0_counter = 0;
58 thread_1_counter = 0;
59 error_counter = 0;
60
61 /* Create the main thread. */
62 tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
63 pointer, DEMO_STACK_SIZE,
64 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
65
66 pointer = pointer + DEMO_STACK_SIZE;
67
68 /* Create the main thread. */
69 tx_thread_create(&thread_1, "thread 1", thread_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, 8192);
81 pointer = pointer + 8192;
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, 1);
94 pointer = pointer + 2048;
95
96 if (status)
97 error_counter++;
98
99 /* Enable ARP and supply ARP cache memory for IP Instance 0. */
100 status = nx_arp_enable(&ip_0, (void *) pointer, 1024);
101 pointer = pointer + 1024;
102
103 /* Enable ARP and supply ARP cache memory for IP Instance 1. */
104 status += nx_arp_enable(&ip_1, (void *) pointer, 1024);
105 pointer = pointer + 1024;
106
107 /* Check ARP enable status. */
108 if (status)
109 error_counter++;
110
111 /* Enable TCP processing for both IP instances. */
112 status = nx_tcp_enable(&ip_0);
113 status += nx_tcp_enable(&ip_1);
114
115 /* Check TCP enable status. */
116 if (status)
117 error_counter++;
118 }
119
120
121
122 /* Define the test threads. */
123
thread_0_entry(ULONG thread_input)124 static void thread_0_entry(ULONG thread_input)
125 {
126
127 UINT status;
128 NX_PACKET *my_packet;
129
130
131
132 /* Print out test information banner. */
133 printf("NetX Test: TCP Wrapping RX/TX Sequence Test..........................");
134
135 /* Check for earlier error. */
136 if (error_counter)
137 {
138
139 printf("ERROR!\n");
140 test_control_return(1);
141 }
142
143 /* Create a socket. */
144 status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket",
145 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300,
146 NX_NULL, NX_NULL);
147
148 /* Check for error. */
149 if (status)
150 error_counter++;
151
152 /* Bind the socket. */
153 status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER);
154
155 /* Check for error. */
156 if (status)
157 error_counter++;
158
159 /* Attempt to connect the socket. */
160 tx_thread_relinquish();
161 status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE);
162
163 /* Check for error. */
164 if (status)
165 error_counter++;
166
167 tx_thread_relinquish();
168
169 /* Loop to repeat things over and over again! */
170 thread_0_counter = 0;
171 while ((thread_0_counter < 2000) && (!error_counter))
172 {
173
174 /* Increment thread 0's counter. */
175 thread_0_counter++;
176
177
178 /* Allocate a packet. */
179 status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER);
180
181 /* Check status. */
182 if (status != NX_SUCCESS)
183 error_counter++;
184
185 /* Write ABCs into the packet payload! */
186 memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28);
187
188 /* Adjust the write pointer. */
189 my_packet -> nx_packet_length = 28;
190 my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28;
191
192 /* Send the packet out! */
193 status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE);
194
195 /* Determine if the status is valid. */
196 if (status)
197 {
198 error_counter++;
199 nx_packet_release(my_packet);
200 }
201
202 /* Allocate a packet. */
203 status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER);
204
205 /* Check status. */
206 if (status != NX_SUCCESS)
207 error_counter++;
208
209 /* Write ABCs into the packet payload! */
210 memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28);
211
212 /* Adjust the write pointer. */
213 my_packet -> nx_packet_length = 28;
214 my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28;
215
216 /* Send the packet out! */
217 status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE);
218
219 /* Determine if the status is valid. */
220 if (status)
221 {
222 error_counter++;
223 nx_packet_release(my_packet);
224 }
225
226 /* Allocate a packet. */
227 status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER);
228
229 /* Check status. */
230 if (status != NX_SUCCESS)
231 error_counter++;
232
233 /* Write ABCs into the packet payload! */
234 memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28);
235
236 /* Adjust the write pointer. */
237 my_packet -> nx_packet_length = 28;
238 my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28;
239
240 /* Send the packet out! */
241 status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE);
242
243 /* Determine if the status is valid. */
244 if (status)
245 {
246 error_counter++;
247 nx_packet_release(my_packet);
248 }
249
250 /* Allocate a packet. */
251 status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER);
252
253 /* Check status. */
254 if (status != NX_SUCCESS)
255 error_counter++;
256
257 /* Write ABCs into the packet payload! */
258 memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28);
259
260 /* Adjust the write pointer. */
261 my_packet -> nx_packet_length = 28;
262 my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28;
263
264 /* Send the packet out! */
265 status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE);
266
267 /* Determine if the status is valid. */
268 if (status)
269 {
270 error_counter++;
271 nx_packet_release(my_packet);
272 }
273
274 tx_thread_suspend(&thread_0);
275 }
276
277 /* Disconnect this socket. */
278 status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE);
279
280 /* Determine if the status is valid. */
281 if (status)
282 error_counter++;
283
284 /* Unbind the socket. */
285 status = nx_tcp_client_socket_unbind(&client_socket);
286
287 /* Check for error. */
288 if (status)
289 error_counter++;
290
291 /* Delete the socket. */
292 status = nx_tcp_socket_delete(&client_socket);
293
294 /* Check for error. */
295 if (status)
296 error_counter++;
297
298 /* Determine if the test was successful. */
299 if ((error_counter) || (thread_0_counter != 2000) || (thread_1_counter != 2000))
300 {
301
302 printf("ERROR!\n");
303 test_control_return(1);
304 }
305 else
306 {
307
308 printf("SUCCESS!\n");
309 test_control_return(0);
310 }
311 }
312
313
thread_1_entry(ULONG thread_input)314 static void thread_1_entry(ULONG thread_input)
315 {
316
317 UINT status;
318 NX_PACKET *packet_ptr;
319 ULONG actual_status;
320 ULONG sequence_increment = 1;
321
322
323 /* Ensure the IP instance has been initialized. */
324 status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE);
325
326 /* Check status... */
327 if (status != NX_SUCCESS)
328 {
329
330 error_counter++;
331 test_control_return(1);
332 }
333
334 /* Create a socket. */
335 status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket",
336 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200,
337 NX_NULL, thread_1_disconnect_received);
338
339 /* Check for error. */
340 if (status)
341 error_counter++;
342
343 /* Setup this thread to listen. */
344 status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received);
345
346 /* Check for error. */
347 if (status)
348 error_counter++;
349
350 /* Accept a client socket connection. */
351 status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE);
352
353 /* Check for error. */
354 if (status)
355 error_counter++;
356
357 /* Supsend thread 0. */
358 tx_thread_suspend(&thread_0);
359 nx_tcp_socket_state_wait(&server_socket, NX_TCP_ESTABLISHED, 2 * NX_IP_PERIODIC_RATE);
360 tx_thread_resume(&thread_0);
361
362 /* Set all the sequence numbers the way we want them for our test. */
363 client_socket.nx_tcp_socket_tx_sequence = 0xFFFFFF00;
364 client_socket.nx_tcp_socket_rx_sequence = 0xFFFFFF00;
365 client_socket.nx_tcp_socket_rx_sequence_acked = 0xFFFFFF00;
366 server_socket.nx_tcp_socket_tx_sequence = 0xFFFFFF00;
367 server_socket.nx_tcp_socket_rx_sequence = 0xFFFFFF00;
368 server_socket.nx_tcp_socket_rx_sequence_acked = 0xFFFFFF00;
369
370 /* Loop to create and establish server connections. */
371 thread_1_counter = 0;
372 while ((thread_1_counter < 2000) && (!error_counter))
373 {
374
375 /* Increment thread 1's counter. */
376 thread_1_counter++;
377
378 /* Receive a TCP message from the socket. */
379 status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE);
380
381 /* Check for error. */
382 if (status)
383 error_counter++;
384 else
385 /* Release the packet. */
386 nx_packet_release(packet_ptr);
387
388 /* Receive a TCP message from the socket. */
389 status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE);
390
391 /* Check for error. */
392 if (status)
393 error_counter++;
394 else
395 /* Release the packet. */
396 nx_packet_release(packet_ptr);
397
398 /* Receive a TCP message from the socket. */
399 status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE);
400
401 /* Check for error. */
402 if (status)
403 error_counter++;
404 else
405 /* Release the packet. */
406 nx_packet_release(packet_ptr);
407
408 /* Receive a TCP message from the socket. */
409 server_socket.nx_tcp_socket_rx_window_last_sent = 0; /* Force an ACK out! */
410 status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE);
411
412 /* Check for error. */
413 if (status)
414 error_counter++;
415 else
416 /* Release the packet. */
417 nx_packet_release(packet_ptr);
418
419 /* Set all the sequence numbers the way we want them for our test. */
420 if ((server_socket.nx_tcp_socket_rx_sequence < 0xFFFFFF00) &&
421 (server_socket.nx_tcp_socket_rx_sequence > 0x100))
422 {
423 client_socket.nx_tcp_socket_tx_sequence = 0xFFFFFF00 + (sequence_increment & 0xFF);
424 client_socket.nx_tcp_socket_rx_sequence = 0xFFFFFF00 + (sequence_increment & 0xFF);
425 client_socket.nx_tcp_socket_rx_sequence_acked = 0xFFFFFF00 + (sequence_increment & 0xFF);
426 server_socket.nx_tcp_socket_tx_sequence = 0xFFFFFF00 + (sequence_increment & 0xFF);
427 server_socket.nx_tcp_socket_rx_sequence = 0xFFFFFF00 + (sequence_increment & 0xFF);
428 server_socket.nx_tcp_socket_rx_sequence_acked = 0xFFFFFF00 + (sequence_increment++ & 0xFF);
429 }
430
431 /* Resume thread 0. */
432 tx_thread_resume(&thread_0);
433 }
434
435 /* Disconnect the server socket. */
436 status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE);
437
438 /* Check for error. */
439 if (status)
440 error_counter++;
441
442 /* Unaccept the server socket. */
443 status = nx_tcp_server_socket_unaccept(&server_socket);
444
445 /* Check for error. */
446 if (status)
447 error_counter++;
448
449 /* Setup server socket for listening again. */
450 status = nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket);
451
452 /* Check for error. */
453 if (status)
454 error_counter++;
455 }
456
457
thread_1_connect_received(NX_TCP_SOCKET * socket_ptr,UINT port)458 static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port)
459 {
460
461 /* Check for the proper socket and port. */
462 if ((socket_ptr != &server_socket) || (port != 12))
463 error_counter++;
464 }
465
466
thread_1_disconnect_received(NX_TCP_SOCKET * socket)467 static void thread_1_disconnect_received(NX_TCP_SOCKET *socket)
468 {
469
470 /* Check for proper disconnected socket. */
471 if (socket != &server_socket)
472 error_counter++;
473 }
474 #else
475
476 #ifdef CTEST
test_application_define(void * first_unused_memory)477 VOID test_application_define(void *first_unused_memory)
478 #else
479 void netx_tcp_wrapping_sequence_test_application_define(void *first_unused_memory)
480 #endif
481 {
482
483 /* Print out test information banner. */
484 printf("NetX Test: TCP Wrapping RX/TX Sequence Test..........................N/A\n");
485
486 test_control_return(3);
487 }
488 #endif
489