1 /* No.4 Files are transferred only via the data connection.
2 rfc959, page 9, 3. DATA TRANSFER FUNCTIONS */
3 #include "tx_api.h"
4 #include "fx_api.h"
5 #include "nx_api.h"
6 #include "nxd_ftp_client.h"
7 #include "nxd_ftp_server.h"
8
9 extern void test_control_return(UINT);
10
11 #if !defined(NX_DISABLE_IPV4)
12
13 #define DEMO_STACK_SIZE 4096
14
15 /* Define the ThreadX, NetX, and FileX object control blocks... */
16 static TX_THREAD server_thread;
17 static TX_THREAD client_thread;
18 static NX_PACKET_POOL server_pool;
19 static NX_IP server_ip;
20 static NX_PACKET_POOL client_pool;
21 static NX_IP client_ip;
22 static FX_MEDIA ram_disk;
23 static UINT data_control_counter;
24
25 /* Define the NetX FTP object control blocks. */
26 static NX_FTP_CLIENT ftp_client;
27 static NX_FTP_SERVER ftp_server;
28
29 /* Define the counters used in the demo application... */
30 static ULONG error_counter = 0;
31 static UINT test_done = NX_FALSE;
32
33 /* Define the memory area for the FileX RAM disk. */
34 static UCHAR ram_disk_memory[32000];
35 static UCHAR ram_disk_sector_cache[512];
36
37
38 #define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4)
39 #define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5)
40
41 extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size,
42 CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors,
43 ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster,
44 UINT heads, UINT sectors_per_track);
45
46 /* Define the FileX and NetX driver entry functions. */
47 extern void _fx_ram_driver(FX_MEDIA *media_ptr);
48 extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr);
49
50 static void client_thread_entry(ULONG thread_input);
51 static void thread_server_entry(ULONG thread_input);
52
53
54 /* Define server login/logout functions. These are stubs for functions that would
55 validate a client login request. */
56 static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info);
57 static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info);
58
59 #ifdef CTEST
test_application_define(void * first_unused_memory)60 VOID test_application_define(void *first_unused_memory)
61 #else
62 void netx_ftp_data_connection_test_application_define(void *first_unused_memory)
63 #endif
64 {
65
66 UINT status;
67 UCHAR *pointer;
68
69
70 /* Setup the working pointer. */
71 pointer = (UCHAR *) first_unused_memory;
72
73 /* Create a helper thread for the server. */
74 tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0,
75 pointer, DEMO_STACK_SIZE,
76 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
77
78 pointer = pointer + DEMO_STACK_SIZE;
79
80 /* Initialize NetX. */
81 nx_system_initialize();
82
83 /* Create the packet pool for the FTP Server. */
84 status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192);
85 pointer = pointer + 8192;
86 if (status)
87 error_counter++;
88
89 /* Create the IP instance for the FTP Server. */
90 status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL,
91 &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1);
92 pointer = pointer + 2048;
93 if (status)
94 error_counter++;
95
96 /* Enable ARP and supply ARP cache memory for server IP instance. */
97 status = nx_arp_enable(&server_ip, (void *) pointer, 1024);
98 pointer = pointer + 1024;
99 if (status)
100 error_counter++;
101
102 /* Enable TCP. */
103 status = nx_tcp_enable(&server_ip);
104 if (status)
105 error_counter++;
106
107 /* Create the FTP server. */
108 status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool,
109 server_login, server_logout);
110 pointer = pointer + DEMO_STACK_SIZE;
111 if (status)
112 error_counter++;
113
114 /* Now set up the FTP Client. */
115
116 /* Create the main FTP client thread. */
117 status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0,
118 pointer, DEMO_STACK_SIZE,
119 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START);
120 pointer = pointer + DEMO_STACK_SIZE ;
121 if (status)
122 error_counter++;
123
124 /* Create a packet pool for the FTP client. */
125 status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192);
126 pointer = pointer + 8192;
127 if (status)
128 error_counter++;
129
130 /* Create an IP instance for the FTP client. */
131 status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL,
132 &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1);
133 pointer = pointer + 2048;
134 if (status)
135 error_counter++;
136
137 /* Enable ARP and supply ARP cache memory for the FTP Client IP. */
138 status = nx_arp_enable(&client_ip, (void *) pointer, 1024);
139 pointer = pointer + 1024;
140 if (status)
141 error_counter++;
142
143 /* Enable TCP for client IP instance. */
144 status = nx_tcp_enable(&client_ip);
145 if (status)
146 error_counter++;
147
148
149 data_control_counter = 0;
150 }
151
152 /* Define the FTP client thread. */
153
client_thread_entry(ULONG thread_input)154 void client_thread_entry(ULONG thread_input)
155 {
156
157 NX_PACKET *my_packet;
158 UINT status;
159
160 /* Format the RAM disk - the memory for the RAM disk was defined above. */
161 status = _fx_media_format(&ram_disk,
162 _fx_ram_driver, /* Driver entry */
163 ram_disk_memory, /* RAM disk memory pointer */
164 ram_disk_sector_cache, /* Media buffer pointer */
165 sizeof(ram_disk_sector_cache), /* Media buffer size */
166 "MY_RAM_DISK", /* Volume Name */
167 1, /* Number of FATs */
168 32, /* Directory Entries */
169 0, /* Hidden sectors */
170 256, /* Total sectors */
171 128, /* Sector size */
172 1, /* Sectors per cluster */
173 1, /* Heads */
174 1); /* Sectors per track */
175
176 /* Check status. */
177 if (status)
178 error_counter++;
179
180 /* Open the RAM disk. */
181 status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache));
182 if (status)
183 error_counter++;
184
185 /* Create an FTP client. */
186 status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool);
187 if (status)
188 error_counter++;
189
190 /* Now connect with the NetX FTP (IPv4) server. */
191 status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE);
192 if (status)
193 error_counter++;
194
195 /* Open a FTP file for writing. */
196 status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE);
197 if (status)
198 error_counter++;
199
200 /* Allocate a FTP packet. */
201 status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE);
202 if (status)
203 error_counter++;
204
205 /* Write ABCs into the packet payload! */
206 memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28);
207
208 /* Adjust the write pointer. */
209 my_packet -> nx_packet_length = 28;
210 my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28;
211
212 /* Write the packet to the file test.txt. */
213 status = nx_ftp_client_file_write(&ftp_client, my_packet, NX_IP_PERIODIC_RATE);
214 if (status)
215 error_counter++;
216
217 /* Close the file. */
218 status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE);
219 if (status)
220 error_counter++;
221
222 /* Now open the same file for reading. */
223 status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_READ, NX_IP_PERIODIC_RATE);
224 if (status)
225 error_counter++;
226
227 /* Read the file. */
228 status = nx_ftp_client_file_read(&ftp_client, &my_packet, NX_IP_PERIODIC_RATE);
229 if (status)
230 error_counter++;
231 else
232 {
233 data_control_counter++;
234 nx_packet_release(my_packet);
235 }
236 /* Close this file. */
237 status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE);
238 if (status)
239 error_counter++;
240
241 status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_READ, NX_IP_PERIODIC_RATE);
242 if (status)
243 error_counter++;
244
245 /* If after closing the client data socket we can also successfully transfer FTP commands, then we can make sure that the The control connection is used for the transfer of commands.*/
246 status = nx_tcp_socket_disconnect(&(ftp_client.nx_ftp_client_data_socket), NX_IP_PERIODIC_RATE);
247 if(status)
248 error_counter++;
249
250 ftp_client.nx_ftp_client_data_socket.nx_tcp_socket_state = NX_TCP_CLOSED;
251
252 nx_tcp_client_socket_unbind(&(ftp_client.nx_ftp_client_data_socket));
253 /* Check for error. */
254 if(status)
255 error_counter++;
256
257
258 /* Delete the socket. */
259 status = nx_tcp_socket_delete(&ftp_client.nx_ftp_client_data_socket);
260
261 /* Check for error. */
262 if(status)
263 error_counter++;
264
265 /* Disconnect the data socket connection we can find that we cannot successfully transfer the files. */
266 /* Read the file. */
267 status = nx_ftp_client_file_read(&ftp_client, &my_packet, NX_IP_PERIODIC_RATE);
268 if (status == NX_NOT_BOUND)
269 data_control_counter++;
270 else
271 {
272 nx_packet_release(my_packet);
273 }
274
275 /* Close this file. */
276 status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE);
277 if (status)
278 error_counter++;
279
280 /* Disconnect from the server. */
281 status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE);
282 if (status)
283 error_counter++;
284
285 /* Delete the FTP client. */
286 status = nx_ftp_client_delete(&ftp_client);
287 if (status)
288 error_counter++;
289
290 /* Set the flag. */
291 test_done = NX_TRUE;
292 }
293
294
295 /* Define the helper FTP server thread. */
thread_server_entry(ULONG thread_input)296 void thread_server_entry(ULONG thread_input)
297 {
298
299 UINT status;
300
301 /* Print out test information banner. */
302 printf("NetX Test: FTP Data Connection Test..................................");
303
304 /* Check for earlier error. */
305 if(error_counter)
306 {
307 printf("ERROR!\n");
308 test_control_return(1);
309 }
310
311 /* OK to start the FTPv6 Server. */
312 status = nx_ftp_server_start(&ftp_server);
313 if (status)
314 error_counter++;
315
316 /* Wait for test. */
317 while(test_done == NX_FALSE)
318 tx_thread_sleep(NX_IP_PERIODIC_RATE);
319
320 status = nx_ftp_server_delete(&ftp_server);
321 if(status)
322 error_counter++;
323
324 if((error_counter != 0) || (data_control_counter != 2))
325 {
326 printf("ERROR!\n");
327 test_control_return(1);
328 }
329 else
330 {
331 printf("SUCCESS!\n");
332 test_control_return(0);
333 }
334 }
335
336
server_login(struct NX_FTP_SERVER_STRUCT * ftp_server_ptr,ULONG client_ip_address,UINT client_port,CHAR * name,CHAR * password,CHAR * extra_info)337 static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info)
338 {
339 /* Always return success. */
340 return(NX_SUCCESS);
341 }
342
server_logout(struct NX_FTP_SERVER_STRUCT * ftp_server_ptr,ULONG client_ip_address,UINT client_port,CHAR * name,CHAR * password,CHAR * extra_info)343 static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info)
344 {
345 /* Always return success. */
346 return(NX_SUCCESS);
347 }
348 #else
349
350 #ifdef CTEST
test_application_define(void * first_unused_memory)351 VOID test_application_define(void *first_unused_memory)
352 #else
353 void netx_ftp_data_connection_test_application_define(void *first_unused_memory)
354 #endif
355 {
356
357 /* Print out test information banner. */
358 printf("NetX Test: FTP Data Connection Test..................................N/A\n");
359
360 test_control_return(3);
361 }
362 #endif