1 
2 #include    "tx_api.h"
3 #include    "nx_api.h"
4 #include    "nxd_tftp_client.h"
5 #include    "nxd_tftp_server.h"
6 #include    "fx_api.h"
7 
8 extern void     test_control_return(UINT);
9 
10 #if !defined(NX_DISABLE_IPV4)
11 
12 #define     DEMO_STACK_SIZE         4096
13 
14 /* Define the ThreadX, NetX, and FileX object control blocks...  */
15 
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 
24 /* Define the NetX DUO TFTP object control blocks.  */
25 
26 static NX_TFTP_CLIENT          client;
27 static NX_TFTP_SERVER          server;
28 
29 /* Define the application global variables */
30 
31 #define                        CLIENT_ADDRESS  IP_ADDRESS(1, 2, 3, 5)
32 #define                        SERVER_ADDRESS  IP_ADDRESS(1, 2, 3, 4)
33 #ifdef __PRODUCT_NETXDUO__
34 #define IP_TYPE 4
35 static NXD_ADDRESS             server_ip_address;
36 #else
37 static ULONG                   server_ip_address;
38 #endif
39 static UINT                    error_counter = 0;
40 
41 /* Define buffer used in the demo application.  */
42 static UCHAR                   buffer[255];
43 static ULONG                   data_length;
44 
45 
46 /* Define the memory area for the FileX RAM disk.  */
47 static UCHAR                   ram_disk_memory[32000];
48 static UCHAR                   ram_disk_sector_cache[512];
49 
50 
51 /* Define function prototypes.  */
52 
53 extern void     _fx_ram_driver(FX_MEDIA *media_ptr);
54 extern void     _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr);
55 
56 static void     client_thread_entry(ULONG thread_input);
57 static void     server_thread_entry(ULONG thread_input);
58 
59 
60 #ifdef CTEST
test_application_define(void * first_unused_memory)61 VOID test_application_define(void *first_unused_memory)
62 #else
63 void    netx_tftp_basic_test_application_define(void *first_unused_memory)
64 #endif
65 {
66 
67 UINT    status;
68 UCHAR   *pointer;
69 
70 
71     /* Setup the working pointer.  */
72     pointer =  (UCHAR *) first_unused_memory;
73 
74     /* Create the main TFTPv6 server thread.  */
75     status = tx_thread_create(&server_thread, "TFTP Server Thread", server_thread_entry, 0,
76                               pointer, DEMO_STACK_SIZE,
77                               4,4, TX_NO_TIME_SLICE, TX_AUTO_START);
78 
79     pointer += DEMO_STACK_SIZE ;
80 
81     /* Check for errors.  */
82     if (status)
83         error_counter++;
84 
85 
86     /* Create the main TFTPv6 client thread at a slightly lower priority.  */
87     status = tx_thread_create(&client_thread, "TFTP Client Thread", client_thread_entry, 0,
88                               pointer, DEMO_STACK_SIZE,
89                               5, 5, TX_NO_TIME_SLICE, TX_DONT_START);
90 
91     pointer += DEMO_STACK_SIZE ;
92 
93     /* Check for errors.  */
94     if (status)
95         error_counter++;
96 
97     /* Initialize the NetX system.  */
98     nx_system_initialize();
99 
100     /* Note: The data portion of a packet is exactly 512 bytes, but the packet payload size must
101        be at least 580 bytes. The remaining bytes are used for the UDP, IP, and Ethernet
102        headers and byte alignment requirements. */
103 
104     status =  nx_packet_pool_create(&server_pool, "TFTP Server Packet Pool", NX_TFTP_PACKET_SIZE, pointer, 8192);
105     pointer = pointer + 8192;
106 
107     /* Check for errors.  */
108     if (status)
109         error_counter++;
110 
111     /* Create the IP instance for the TFTP Server.  */
112     status = nx_ip_create(&server_ip, "NetX Server IP Instance", SERVER_ADDRESS, 0xFFFFFF00UL,
113                                         &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1);
114     pointer = pointer + 2048;
115 
116     /* Check for errors.  */
117     if (status)
118         error_counter++;
119 
120     /* Enable ARP and supply ARP cache memory for IP Instance 0.  */
121     status =  nx_arp_enable(&server_ip, (void *) pointer, 1024);
122     pointer = pointer + 1024;
123 
124     /* Check for errors.  */
125     if (status)
126         error_counter++;
127 
128     /* Enable UDP.  */
129     status =  nx_udp_enable(&server_ip);
130 
131     /* Check for errors.  */
132     if (status)
133         error_counter++;
134 
135 
136     /* Create the TFTP server.  */
137 #ifdef __PRODUCT_NETXDUO__
138     server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
139     server_ip_address.nxd_ip_address.v4 = SERVER_ADDRESS;
140 #else
141     server_ip_address = SERVER_ADDRESS;
142 #endif
143 
144 #ifdef __PRODUCT_NETXDUO__
145     status =  nxd_tftp_server_create(&server, "TFTP Server Instance", &server_ip, &ram_disk,
146                                       pointer, DEMO_STACK_SIZE, &server_pool);
147 #else
148     status =  nx_tftp_server_create(&server, "TFTP Server Instance", &server_ip, &ram_disk,
149                                       pointer, DEMO_STACK_SIZE, &server_pool);
150 #endif
151 
152     pointer =  pointer + DEMO_STACK_SIZE;
153 
154     /* Check for errors for the server.  */
155     if (status)
156         error_counter++;
157 
158     /* Create a packet pool for the TFTP client.  */
159 
160     /* Note: The data portion of a packet is exactly 512 bytes, but the packet payload size must
161        be at least 580 bytes. The remaining bytes are used for the UDP, IP, and Ethernet
162        headers and byte alignment requirements. */
163 
164     status =  nx_packet_pool_create(&client_pool, "TFTP Client Packet Pool", NX_TFTP_PACKET_SIZE, pointer, 8192);
165     pointer =  pointer + 8192;
166 
167     /* Check for errors.  */
168     if (status)
169         error_counter++;
170 
171     /* Create an IP instance for the TFTP client.  */
172     status = nx_ip_create(&client_ip, "TFTP Client IP Instance", CLIENT_ADDRESS, 0xFFFFFF00UL,
173                                                 &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1);
174     pointer = pointer + 2048;
175 
176     /* Check for errors.  */
177     if (status)
178         error_counter++;
179 
180     /* Enable ARP and supply ARP cache memory for IP Instance 1.  */
181     status =  nx_arp_enable(&client_ip, (void *) pointer, 1024);
182     pointer = pointer + 1024;
183 
184     /* Enable UDP for client IP instance.  */
185     status +=  nx_udp_enable(&client_ip);
186     status += nx_icmp_enable(&client_ip);
187 
188     /* Check for errors.  */
189     if (status)
190         error_counter++;
191 
192     tx_thread_resume(&client_thread);
193 }
194 
server_thread_entry(ULONG thread_input)195 void server_thread_entry(ULONG thread_input)
196 {
197 
198 UINT        status;
199 
200     /* Print out test information banner.  */
201     printf("NetX Test:   TFTP Basic Test...........................................");
202 
203     /* Check for earlier error. */
204     if(error_counter)
205     {
206         printf("ERROR!\n");
207         test_control_return(1);
208     }
209 
210     /* Format the RAM disk - the memory for the RAM disk was defined above.  */
211     status = fx_media_format(&ram_disk,
212                             _fx_ram_driver,                  /* Driver entry             */
213                             ram_disk_memory,                 /* RAM disk memory pointer  */
214                             ram_disk_sector_cache,           /* Media buffer pointer     */
215                             sizeof(ram_disk_sector_cache),   /* Media buffer size        */
216                             "MY_RAM_DISK",                   /* Volume Name              */
217                             1,                               /* Number of FATs           */
218                             32,                              /* Directory Entries        */
219                             0,                               /* Hidden sectors           */
220                             256,                            /* Total sectors            */
221                             128,                             /* Sector size              */
222                             1,                               /* Sectors per cluster      */
223                             1,                               /* Heads                    */
224                             1);                              /* Sectors per track        */
225 
226     /* Check for errors.  */
227     if (status)
228         error_counter++;
229 
230     /* Open the RAM disk.  */
231     status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache));
232 
233     /* Check for errors.  */
234     if (status)
235         error_counter++;
236 
237     /* Start the NetX Duo TFTP server.  */
238 #ifdef __PRODUCT_NETXDUO__
239     status =  nxd_tftp_server_start(&server);
240 #else
241     status =  nx_tftp_server_start(&server);
242 #endif
243 
244     /* Check for errors.  */
245     if (status)
246         error_counter++;
247 
248     /* Run for a while */
249     tx_thread_sleep(3 * NX_IP_PERIODIC_RATE);
250 
251 #ifdef __PRODUCT_NETXDUO__
252     nxd_tftp_server_delete(&server);
253 #else
254     nx_tftp_server_delete(&server);
255 #endif
256 
257     if(error_counter)
258     {
259         printf("ERROR!\n");
260         test_control_return(1);
261     }
262     else
263     {
264         printf("SUCCESS!\n");
265         test_control_return(0);
266     }
267 }
268 
269 /* Define the TFTP client thread.  */
270 
client_thread_entry(ULONG thread_input)271 void    client_thread_entry(ULONG thread_input)
272 {
273 
274 NX_PACKET   *my_packet;
275 UINT        status;
276 UINT        all_done = NX_FALSE;
277 
278 
279     /* The TFTP services used below include the NetX equivalent service which will work with
280        NetX Duo TFTP.  However, it is recommended for developers to port their applications
281        to the newer services that take the NXD_ADDRESS type and support both IPv4 and IPv6
282        communication.
283     */
284 
285     /* Create a TFTP client.  */
286 #ifdef __PRODUCT_NETXDUO__
287     status =  nxd_tftp_client_create(&client, "TFTP Client", &client_ip, &client_pool, IP_TYPE);
288 #else
289     status =  nx_tftp_client_create(&client, "TFTP Client", &client_ip, &client_pool);
290 #endif
291 
292     /* Check status.  */
293     if (status)
294         error_counter++;
295 
296     /* Open a TFTP file for writing.  */
297 #ifdef __PRODUCT_NETXDUO__
298     status =  nxd_tftp_client_file_open(&client, "test.txt", &server_ip_address, NX_TFTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE, IP_TYPE);
299 #else
300     status =  nx_tftp_client_file_open(&client, "test.txt", SERVER_ADDRESS, NX_TFTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE);
301 #endif
302 
303     /* Check status.  */
304     if (status)
305         error_counter++;
306 
307     /* Allocate a TFTP packet.  */
308 #ifdef __PRODUCT_NETXDUO__
309     status =  nxd_tftp_client_packet_allocate(&client_pool, &my_packet, NX_IP_PERIODIC_RATE, IP_TYPE);
310 #else
311     status =  nx_tftp_client_packet_allocate(&client_pool, &my_packet, NX_IP_PERIODIC_RATE);
312 #endif
313     /* Check status.  */
314     if (status)
315         error_counter++;
316 
317     /* Write ABCs into the packet payload!  */
318     memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ  ", 28);
319 
320     /* Adjust the write pointer.  */
321     my_packet -> nx_packet_length =  28;
322     my_packet -> nx_packet_append_ptr =  my_packet -> nx_packet_prepend_ptr + 28;
323 
324     /* Write this packet to the file via TFTP.  */
325 #ifdef __PRODUCT_NETXDUO__
326     status =  nxd_tftp_client_file_write(&client, my_packet, NX_IP_PERIODIC_RATE, IP_TYPE);
327 #else
328     status =  nx_tftp_client_file_write(&client, my_packet, NX_IP_PERIODIC_RATE);
329 #endif
330 
331     /* Check status.  */
332     if (status)
333         error_counter++;
334 
335     /* Close this file.  */
336 #ifdef __PRODUCT_NETXDUO__
337     status =  nxd_tftp_client_file_close(&client, IP_TYPE);
338 #else
339     status =  nx_tftp_client_file_close(&client);
340 #endif
341 
342     /* Check status.  */
343     if (status)
344         error_counter++;
345 
346     /* Open the same file for reading.  */
347 #ifdef __PRODUCT_NETXDUO__
348     status =  nxd_tftp_client_file_open(&client, "test.txt", &server_ip_address, NX_TFTP_OPEN_FOR_READ, NX_IP_PERIODIC_RATE, IP_TYPE);
349 #else
350     status =  nx_tftp_client_file_open(&client, "test.txt", SERVER_ADDRESS, NX_TFTP_OPEN_FOR_READ, NX_IP_PERIODIC_RATE);
351 #endif
352 
353     /* Check status.  */
354     if (status)
355         error_counter++;
356     do
357     {
358 
359     /* Read the file back.  */
360 #ifdef __PRODUCT_NETXDUO__
361         status =  nxd_tftp_client_file_read(&client, &my_packet, NX_IP_PERIODIC_RATE, IP_TYPE);
362 #else
363         status =  nx_tftp_client_file_read(&client, &my_packet, NX_IP_PERIODIC_RATE);
364 #endif
365         /* Check for retranmission/dropped packet error. Benign. Try again... */
366         if (status == NX_TFTP_INVALID_BLOCK_NUMBER)
367         {
368             continue;
369         }
370         else if (status == NX_TFTP_END_OF_FILE)
371         {
372             /* All done. */
373             all_done = NX_TRUE;
374         }
375         else if (status)
376         {
377             error_counter++;
378 
379             /* Internal error, invalid packet or error on read. */
380             break;
381         }
382 
383 
384         /* Do something with the packet data and release when done. */
385         nx_packet_data_retrieve(my_packet, buffer, &data_length);
386         buffer[data_length] = 0;
387         nx_packet_release(my_packet);
388 
389     } while (all_done == NX_FALSE);
390 
391     /* Close the file again.  */
392 #ifdef __PRODUCT_NETXDUO__
393     status =  nxd_tftp_client_file_close(&client, IP_TYPE);
394 #else
395     status =  nx_tftp_client_file_close(&client);
396 #endif
397 
398     /* Check status.  */
399     if (status)
400         error_counter++;
401 
402     /* Delete the client.  */
403 #ifdef __PRODUCT_NETXDUO__
404     status =  nxd_tftp_client_delete(&client);
405 #else
406     status =  nx_tftp_client_delete(&client);
407 #endif
408 
409     /* Check status.  */
410     if (status)
411         error_counter++;
412 }
413 #else
414 
415 #ifdef CTEST
test_application_define(void * first_unused_memory)416 VOID test_application_define(void *first_unused_memory)
417 #else
418 void    netx_tftp_basic_test_application_define(void *first_unused_memory)
419 #endif
420 {
421 
422     /* Print out test information banner.  */
423     printf("NetX Test:   TFTP Basic Test...........................................N/A\n");
424 
425     test_control_return(3);
426 }
427 #endif