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, &current_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