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