1 /* This demo tests the feature to create the Telnet packet pool instead of the default
2 behavior of the Telnet Server creating its own packet pool.
3
4 NX_TELNET_SERVER_USER_CREATE_PACKET_POOL must be defined in the test.
5 */
6
7 #include "tx_api.h"
8 #include "nx_api.h"
9 #include <stdio.h>
10 #include <stdlib.h>
11 extern void test_control_return(UINT);
12
13 #if defined(NX_TELNET_SERVER_USER_CREATE_PACKET_POOL) && !defined(NX_DISABLE_IPV4)
14
15
16 #include "nxd_telnet_client.h"
17 #include "nxd_telnet_server.h"
18
19 #define DEMO_STACK_SIZE 4096
20
21
22 /* Define the ThreadX and NetX object control blocks... */
23
24 static TX_THREAD server_thread;
25 static TX_THREAD client_thread;
26 static NX_PACKET_POOL pool_server;
27 static NX_PACKET_POOL pool_client;
28 static NX_IP ip_server;
29 static NX_IP ip_client;
30
31 /* Define TELNET objects. */
32
33 static NX_TELNET_SERVER my_server;
34 static NX_TELNET_CLIENT my_client;
35
36
37 #define SERVER_ADDRESS IP_ADDRESS(1,2,3,4)
38 #define CLIENT_ADDRESS IP_ADDRESS(1,2,3,5)
39
40
41 /* Define the counters used in the demo application... */
42
43 static ULONG error_counter;
44
45 /* Define timeout in ticks for connecting and sending/receiving data. */
46
47 #define TELNET_TIMEOUT 200
48
49 /* Define function prototypes. */
50
51 static void thread_server_entry(ULONG thread_input);
52 static void thread_client_entry(ULONG thread_input);
53
54 /* Replace the 'ram' driver with your actual Ethernet driver. */
55 extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req);
56
57
58 /* Define the application's TELNET Server callback routines. */
59
60 static void telnet_new_connection(NX_TELNET_SERVER *server_ptr, UINT logical_connection);
61 static void telnet_receive_data(NX_TELNET_SERVER *server_ptr, UINT logical_connection, NX_PACKET *packet_ptr);
62 static void telnet_connection_end(NX_TELNET_SERVER *server_ptr, UINT logical_connection);
63
64
65 /* Define what the initial system looks like. */
66 #ifdef CTEST
test_application_define(void * first_unused_memory)67 VOID test_application_define(void *first_unused_memory)
68 #else
69 void netx_telnet_create_packet_pool_test_application_define(void *first_unused_memory)
70 #endif
71 {
72
73 UINT status;
74 CHAR *pointer;
75
76
77 /* Setup the working pointer. */
78 pointer = (CHAR *) first_unused_memory;
79
80 /* Create the server thread. */
81 tx_thread_create(&server_thread, "server thread", thread_server_entry, 0,
82 pointer, DEMO_STACK_SIZE,
83 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
84
85 pointer = pointer + DEMO_STACK_SIZE;
86
87 /* Create the client thread. */
88 tx_thread_create(&client_thread, "client thread", thread_client_entry, 0,
89 pointer, DEMO_STACK_SIZE,
90 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START);
91
92 pointer = pointer + DEMO_STACK_SIZE;
93
94 /* Initialize the NetX system. */
95 nx_system_initialize();
96
97 /* Create packet pool. */
98 status = nx_packet_pool_create(&pool_server, "Server NetX Packet Pool", 600, pointer, 8192);
99 pointer = pointer + 8192;
100 if(status)
101 error_counter++;
102
103 /* Create an IP instance. */
104 status = nx_ip_create(&ip_server, "Server NetX IP Instance", SERVER_ADDRESS,
105 0xFFFFFF00UL, &pool_server, _nx_ram_network_driver_512,
106 pointer, 4096, 1);
107 pointer = pointer + 4096;
108 if(status)
109 error_counter++;
110
111 /* Create another packet pool. */
112 status = nx_packet_pool_create(&pool_client, "Client NetX Packet Pool", 600, pointer, 8192);
113 pointer = pointer + 8192;
114 if(status)
115 error_counter++;
116
117 /* Create another IP instance. */
118 status = nx_ip_create(&ip_client, "Client NetX IP Instance", CLIENT_ADDRESS,
119 0xFFFFFF00UL, &pool_client, _nx_ram_network_driver_512,
120 pointer, 4096, 1);
121 pointer = pointer + 4096;
122 if(status)
123 error_counter++;
124
125 /* Enable ARP and supply ARP cache memory for IP Instance 0. */
126 status = nx_arp_enable(&ip_server, (void *) pointer, 1024);
127 pointer = pointer + 1024;
128 if(status)
129 error_counter++;
130
131 /* Enable ARP and supply ARP cache memory for IP Instance 1. */
132 status = nx_arp_enable(&ip_client, (void *) pointer, 1024);
133 pointer = pointer + 1024;
134 if(status)
135 error_counter++;
136
137 /* Enable TCP processing for both IP instances. */
138 status = nx_tcp_enable(&ip_server);
139 status += nx_tcp_enable(&ip_client);
140 if(status)
141 error_counter++;
142
143 /* Create the NetX Duo TELNET Server. */
144 status = nx_telnet_server_create(&my_server, "Telnet Server", &ip_server,
145 pointer, 2048, telnet_new_connection, telnet_receive_data,
146 telnet_connection_end);
147
148 /* Check for errors. */
149 if (status)
150 error_counter++;
151
152 pointer = pointer + 2048;
153
154 status = nx_telnet_server_packet_pool_set(&my_server, &pool_server);
155
156 /* Check for errors. */
157 if (status)
158 error_counter++;
159 }
160
161 /* Define the Server thread. */
thread_server_entry(ULONG thread_input)162 void thread_server_entry(ULONG thread_input)
163 {
164
165 UINT status;
166
167 /* Print out test information banner. */
168 printf("NetX Test: Telnet Create Packet Pool Test............................");
169
170 /* Check for earlier error. */
171 if(error_counter)
172 {
173 printf("ERROR!\n");
174 test_control_return(1);
175 }
176
177 /* Start the TELNET Server. */
178 status = nx_telnet_server_start(&my_server);
179 if (status)
180 error_counter++;
181
182 tx_thread_sleep(100);
183
184 status = nx_telnet_server_delete(&my_server);
185 if (status)
186 error_counter++;
187
188 }
189
190 /* Define the client thread. */
thread_client_entry(ULONG thread_input)191 void thread_client_entry(ULONG thread_input)
192 {
193
194 NX_PACKET *my_packet;
195 UINT status;
196
197 tx_thread_sleep(50);
198
199 /* Create a TELENT client instance. */
200 status = nx_telnet_client_create(&my_client, "My TELNET Client", &ip_client, 600);
201 if (status)
202 error_counter++;
203
204 /* Connect the TELNET client to the TELNET Server at port 23 over IPv4. */
205 status = nx_telnet_client_connect(&my_client, SERVER_ADDRESS, NX_TELNET_SERVER_PORT, TELNET_TIMEOUT);
206 if (status)
207 error_counter++;
208
209 /* Allocate a packet. */
210 status = nx_packet_allocate(&pool_client, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER);
211 if (status)
212 error_counter++;
213
214 /* Build a simple 1-byte message. */
215 nx_packet_data_append(my_packet, "a", 1, &pool_client, NX_WAIT_FOREVER);
216
217 /* Send the packet to the TELNET Server. */
218 status = nx_telnet_client_packet_send(&my_client, my_packet, TELNET_TIMEOUT);
219 if (status)
220 error_counter++;
221
222 /* Pickup the Server header. */
223 status = nx_telnet_client_packet_receive(&my_client, &my_packet, TELNET_TIMEOUT);
224 if (status)
225 error_counter++;
226
227 /* At this point the packet should contain the Server's banner
228 message sent by the Server callback function below. Just
229 release it for this demo. */
230 nx_packet_release(my_packet);
231
232 /* Pickup the Server echo of the character. */
233 status = nx_telnet_client_packet_receive(&my_client, &my_packet, TELNET_TIMEOUT);
234 if (status)
235 error_counter++;
236
237 /* At this point the packet should contain the character 'a' that
238 we sent earlier. Just release the packet for now. */
239 nx_packet_release(my_packet);
240
241 /* Now disconnect form the TELNET Server. */
242 status = nx_telnet_client_disconnect(&my_client, TELNET_TIMEOUT);
243 if (status)
244 error_counter++;
245
246 /* Delete the TELNET Client. */
247 status = nx_telnet_client_delete(&my_client);
248 if (status)
249 error_counter++;
250
251 tx_thread_sleep(100);
252
253 if(error_counter)
254 {
255 printf("ERROR!\n");
256 test_control_return(1);
257 }
258 else
259 {
260 printf("SUCCESS!\n");
261 test_control_return(0);
262 }
263 }
264
265
266 /* This routine is called by the NetX Telnet Server whenever a new Telnet client
267 connection is established. */
telnet_new_connection(NX_TELNET_SERVER * server_ptr,UINT logical_connection)268 void telnet_new_connection(NX_TELNET_SERVER *server_ptr, UINT logical_connection)
269 {
270
271 UINT status;
272 NX_PACKET *packet_ptr;
273
274 /* Allocate a packet for client greeting. */
275 status = nx_packet_allocate(&pool_server, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT);
276 if (status)
277 error_counter++;
278
279 /* Build a banner message and a prompt. */
280 nx_packet_data_append(packet_ptr, "**** Welcome to NetX TELNET Server ****\r\n\r\n\r\n", 45,
281 &pool_server, NX_NO_WAIT);
282
283 nx_packet_data_append(packet_ptr, "NETX> ", 6, &pool_server, NX_NO_WAIT);
284
285 /* Send the packet to the client. */
286 status = nx_telnet_server_packet_send(server_ptr, logical_connection, packet_ptr, TELNET_TIMEOUT);
287
288 if (status)
289 {
290 error_counter++;
291 nx_packet_release(packet_ptr);
292 }
293 }
294
295
296 /* This routine is called by the NetX Telnet Server whenever data is present on a Telnet client
297 connection. */
telnet_receive_data(NX_TELNET_SERVER * server_ptr,UINT logical_connection,NX_PACKET * packet_ptr)298 void telnet_receive_data(NX_TELNET_SERVER *server_ptr, UINT logical_connection, NX_PACKET *packet_ptr)
299 {
300
301 UINT status;
302 UCHAR alpha;
303
304
305 /* This demo just echoes the character back and on <cr,lf> sends a new prompt back to the
306 client. A real system would most likely buffer the character(s) received in a buffer
307 associated with the supplied logical connection and process according to it. */
308
309
310 /* Just throw away carriage returns. */
311 if ((packet_ptr -> nx_packet_prepend_ptr[0] == '\r') && (packet_ptr -> nx_packet_length == 1))
312 {
313
314 nx_packet_release(packet_ptr);
315 return;
316 }
317
318 /* Setup new line on line feed. */
319 if ((packet_ptr -> nx_packet_prepend_ptr[0] == '\n') || (packet_ptr -> nx_packet_prepend_ptr[1] == '\n'))
320 {
321
322 /* Clean up the packet. */
323 packet_ptr -> nx_packet_length = 0;
324 packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_data_start + NX_TCP_PACKET;
325 packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_data_start + NX_TCP_PACKET;
326
327 /* Build the next prompt. */
328 nx_packet_data_append(packet_ptr, "\r\nNETX> ", 8, &pool_server, NX_NO_WAIT);
329
330 /* Send the packet to the client. */
331 status = nx_telnet_server_packet_send(server_ptr, logical_connection, packet_ptr, TELNET_TIMEOUT);
332 if (status)
333 {
334 error_counter++;
335 nx_packet_release(packet_ptr);
336 }
337
338 return;
339 }
340
341 /* Pickup first character (usually only one from client). */
342 alpha = packet_ptr -> nx_packet_prepend_ptr[0];
343
344 /* Echo character. */
345 status = nx_telnet_server_packet_send(server_ptr, logical_connection, packet_ptr, TELNET_TIMEOUT);
346 if (status)
347 {
348 error_counter++;
349 nx_packet_release(packet_ptr);
350 }
351
352 /* Check for a disconnection. */
353 if (alpha == 'q')
354 {
355
356 /* Initiate server disconnection. */
357 nx_telnet_server_disconnect(server_ptr, logical_connection);
358 }
359 }
360
361
362 /* This routine is called by the NetX Telnet Server whenever the client disconnects. */
telnet_connection_end(NX_TELNET_SERVER * server_ptr,UINT logical_connection)363 void telnet_connection_end(NX_TELNET_SERVER *server_ptr, UINT logical_connection)
364 {
365 /* Cleanup any application specific connection or buffer information. */
366 return;
367 }
368
369
370 #else /* NX_TELNET_SERVER_USER_CREATE_PACKET_POOL */
371
372 #ifdef CTEST
test_application_define(void * first_unused_memory)373 VOID test_application_define(void *first_unused_memory)
374 #else
375 void netx_telnet_create_packet_pool_test_application_define(void *first_unused_memory)
376 #endif
377 {
378 /* Print out test information banner. */
379 printf("NetX Test: Telnet Create Packet Pool Test............................N/A\n");
380 test_control_return(3);
381 }
382 #endif /* NX_TELNET_SERVER_USER_CREATE_PACKET_POOL */
383