1 /* 14.19 TCP MUST include an SWS avoidance algorithm in the receiver when effective send MSS < (1/ 2)*RCV_BUFF. */
2
3 /* Procedure
4 1.Connection successfully
5 2.First Client sends 40 data to Server, then check if the last_sent changed
6 3.Then Client sends more 20 data to Server, also check if the last_sent changed
7 4.If the last_sent changed, the SWS avoidance algorithm has not been used. */
8
9 #include "tx_api.h"
10 #include "nx_api.h"
11 #include "nx_tcp.h"
12 extern void test_control_return(UINT status);
13
14 #if !defined(NX_DISABLE_IPV4)
15
16 #define DEMO_STACK_SIZE 2048
17
18 #define MSG "----------abcdefgh20----------ABCDEFGH40----------klmnopqr60----------KLMNOPQR80--------------------"
19
20 /* Define the ThreadX and NetX object control blocks... */
21
22 static TX_THREAD ntest_0;
23 static TX_THREAD ntest_1;
24
25 static NX_PACKET_POOL pool_0;
26 static NX_IP ip_0;
27 static NX_IP ip_1;
28 static NX_TCP_SOCKET client_socket;
29 static NX_TCP_SOCKET server_socket;
30
31 /* Define the counters used in the demo application... */
32
33 static ULONG error_counter;
34 static ULONG data_packet_counter;
35 static UINT is_included;
36 static ULONG mss_option;
37
38 /* Define thread prototypes. */
39
40 static void ntest_0_entry(ULONG thread_input);
41 static void ntest_1_entry(ULONG thread_input);
42 static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port);
43 static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket);
44 extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req);
45
46 /* Define what the initial system looks like. */
47
48 #ifdef CTEST
test_application_define(void * first_unused_memory)49 VOID test_application_define(void *first_unused_memory)
50 #else
51 void netx_14_20_application_define(void *first_unused_memory)
52 #endif
53 {
54 CHAR *pointer;
55 UINT status;
56
57 /* Setup the working pointer. */
58 pointer = (CHAR *) first_unused_memory;
59
60 error_counter = 0;
61 data_packet_counter = 0;
62 is_included = NX_FALSE;
63 mss_option = 0;
64
65 /* Create the main thread. */
66 tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0,
67 pointer, DEMO_STACK_SIZE,
68 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
69
70 pointer = pointer + DEMO_STACK_SIZE;
71
72 /* Create the main thread. */
73 tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0,
74 pointer, DEMO_STACK_SIZE,
75 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
76
77 pointer = pointer + DEMO_STACK_SIZE;
78
79 /* Initialize the NetX system. */
80 nx_system_initialize();
81
82 /* Create a packet pool. */
83 status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192);
84 pointer = pointer + 8192;
85
86 if(status)
87 error_counter++;
88
89 /* Create an IP instance. */
90 status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver,
91 pointer, 2048, 1);
92 pointer = pointer + 2048;
93
94 /* Create another IP instance. */
95 status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver,
96 pointer, 2048, 1);
97 pointer = pointer + 2048;
98
99 if(status)
100 error_counter++;
101
102 /* Enable ARP and supply ARP cache memory for IP Instance 0. */
103 status = nx_arp_enable(&ip_0, (void *) pointer, 1024);
104 pointer = pointer + 1024;
105
106 /* Enable ARP and supply ARP cache memory for IP Instance 1. */
107 status += nx_arp_enable(&ip_1, (void *) pointer, 1024);
108 pointer = pointer + 1024;
109
110 /* Check ARP enable status. */
111 if(status)
112 error_counter++;
113
114 /* Enable TCP processing for both IP instances. */
115 status = nx_tcp_enable(&ip_0);
116 status += nx_tcp_enable(&ip_1);
117
118 /* Check TCP enable status. */
119 if(status)
120 error_counter++;
121 }
122
123 /* Define the test threads. */
124
ntest_0_entry(ULONG thread_input)125 static void ntest_0_entry(ULONG thread_input)
126 {
127 UINT status;
128 ULONG actual_status;
129 NX_PACKET *rcv_packet_ptr;
130 ULONG window_last_sent;
131 ULONG rcv_length;
132
133 /* Print out test information banner. */
134 printf("NetX Test: TCP Spec 14.20 Test.......................................");
135
136 /* Check for earlier error. */
137 if(error_counter)
138 {
139 printf("ERROR!\n");
140 test_control_return(1);
141 }
142
143 /* Ensure the IP instance has been initialized. */
144 status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE);
145
146 /* Check for error. */
147 if(status)
148 error_counter++;
149
150 /* Create a socket. */
151 status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket",
152 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100,
153 NX_NULL, ntest_0_disconnect_received);
154
155 /* Check for error. */
156 if(status)
157 error_counter++;
158
159 /* Setup this thread to listen. */
160 status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received);
161
162 /* Check for error. */
163 if(status)
164 error_counter++;
165
166 /* Accept a client socket connection. */
167 status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE);
168
169 /* Check for error. */
170 if(status)
171 error_counter++;
172
173 tx_thread_suspend(&ntest_0);
174
175 window_last_sent = server_socket.nx_tcp_socket_rx_window_last_sent;
176
177 status = nx_tcp_socket_receive(&server_socket, &rcv_packet_ptr, 2 * NX_IP_PERIODIC_RATE);
178
179 /* Check for error. */
180 if(status)
181 error_counter++;
182 else
183 {
184 /* Check data length and payload */
185 if((rcv_packet_ptr -> nx_packet_length == mss_option) && (!memcmp(rcv_packet_ptr -> nx_packet_prepend_ptr, MSG, mss_option)))
186 data_packet_counter++;
187
188 rcv_length = rcv_packet_ptr -> nx_packet_length;
189
190 /* Release the packet. */
191 nx_packet_release(rcv_packet_ptr);
192 }
193
194 if((data_packet_counter == 1) && (rcv_length <= server_socket.nx_tcp_socket_connect_mss) && (server_socket.nx_tcp_socket_connect_mss >= (0.5 * server_socket.nx_tcp_socket_rx_window_default)))
195 if(window_last_sent != server_socket.nx_tcp_socket_rx_window_last_sent)
196 is_included = NX_TRUE;
197
198
199
200 /* Disconnect the server socket. */
201 status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE);
202
203 /* Check for error. */
204 if(status)
205 error_counter++;
206
207 /* Unaccepted the server socket. */
208 status = nx_tcp_server_socket_unaccept(&server_socket);
209
210 /* Check for error. */
211 if(status)
212 error_counter++;
213
214 /* Unlisten on the server port. */
215 status = nx_tcp_server_socket_unlisten(&ip_0, 12);
216
217 /* Check for error. */
218 if (status)
219 error_counter++;
220
221 /* Delete the socket. */
222 status = nx_tcp_socket_delete(&server_socket);
223
224 /* Check for error. */
225 if(status)
226 error_counter++;
227 }
228
ntest_1_entry(ULONG thread_input)229 static void ntest_1_entry(ULONG thread_input)
230 {
231 UINT status;
232 NX_PACKET *my_packet;
233 char *msg = MSG;
234
235 /* Create a socket. */
236 status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket",
237 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200,
238 NX_NULL, NX_NULL);
239
240 /* Check for error. */
241 if(status)
242 error_counter++;
243
244 /* Bind the socket. */
245 status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE);
246
247 /* Check for error. */
248 if(status)
249 error_counter++;
250
251 status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE);
252
253 if(status)
254 error_counter++;
255
256 mss_option = client_socket.nx_tcp_socket_connect_mss;
257
258
259 status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE);
260
261 /* Check for error. */
262 if(status)
263 error_counter++;
264
265 status = nx_packet_data_append(my_packet, msg, mss_option, &pool_0, NX_IP_PERIODIC_RATE);
266
267 /* Check for error. */
268 if(status)
269 error_counter++;
270
271 /* Send the my_packet0 */
272 status = nx_tcp_socket_send(&client_socket, my_packet, 2 * NX_IP_PERIODIC_RATE);
273
274 /* Check for error. */
275 if(status)
276 error_counter++;
277
278 tx_thread_resume(&ntest_0);
279
280 /* Disconnect this socket. */
281 status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE);
282
283 /* Check for error. */
284 if(status)
285 error_counter++;
286
287 /* Unbind the socket. */
288 status = nx_tcp_client_socket_unbind(&client_socket);
289
290 /* Check for error. */
291 if(status)
292 error_counter++;
293
294 /* Delete the socket. */
295 status = nx_tcp_socket_delete(&client_socket);
296
297 /* Check for error. */
298 if(status)
299 error_counter++;
300
301 /* Determine if the test was successful. */
302 if(error_counter || (data_packet_counter != 1) || (is_included != NX_TRUE))
303 {
304 printf("ERROR!\n");
305 test_control_return(1);
306 }
307 else
308 {
309 printf("SUCCESS!\n");
310 test_control_return(0);
311 }
312 }
313
ntest_0_connect_received(NX_TCP_SOCKET * socket_ptr,UINT port)314 static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port)
315 {
316
317 /* Check for the proper socket and port. */
318 if((socket_ptr != &server_socket) || (port != 12))
319 error_counter++;
320 }
321
ntest_0_disconnect_received(NX_TCP_SOCKET * socket)322 static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket)
323 {
324
325 /* Check for proper disconnected socket. */
326 if(socket != &server_socket)
327 error_counter++;
328 }
329 #else
330
331 #ifdef CTEST
test_application_define(void * first_unused_memory)332 VOID test_application_define(void *first_unused_memory)
333 #else
334 void netx_14_20_application_define(void *first_unused_memory)
335 #endif
336 {
337
338 /* Print out test information banner. */
339 printf("NetX Test: TCP Spec 14.20 Test.......................................N/A\n");
340
341 test_control_return(3);
342 }
343 #endif
344