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