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