This is an example code for using the TFTPServer library.
Fork of TFTPServerTest by
A simple TFTP server built with the TFTPServer library
In this example a FAT formatted SD card is connected to the MBED board to provide a storage place for a TFTP server. This will allow us to upload files to or download files from the TFTP server (SD card) over an Ethernet connection as well as to use the files uploaded to the TFTP server in a program running on the MBED board.
Schematic
We can use for example the SD Formatter utility to format an SD card for the FAT file system .
NOTE: In the commands below substitute 192.168.1.185
with the actual IP address of your TFTP server. It's printed to the serial terminal of the connected PC during the server start up.
To upload or download files from a MS Windows PC we can use the TFTP client utility as follows:
- To upload for example the
test.txt
file to the TFTP server:
- Open a command prompt in the folder the file is located in.
- Type
tftp 192.168.1.185 put test.txt /fs/test.txt
and hit ENTER
- Open a command prompt in the folder the file is located in.
- To download for example the
test.txt
file from the TFTP server:
- Open a command prompt in the destination folder.
- Type
tftp 192.168.1.185 get /fs/test.txt test.txt
and hit ENTER
- Open a command prompt in the destination folder.
A similar built-in TFTP client is available also on MAC and Linux operating systems.
References:
- The Trivial File Transfer Protocol (TFTP)
- RFC 1350 - The TFT Protocol
- LaOS (The Laser Open Source) project
main.cpp@5:063211afa95c, 2018-03-20 (annotated)
- Committer:
- hudakz
- Date:
- Tue Mar 20 17:54:21 2018 +0000
- Revision:
- 5:063211afa95c
- Parent:
- 4:895c0ae49294
Updated.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
tuxic | 0:5c9e0971532d | 1 | /* |
hudakz | 1:698437bcd48d | 2 | * example program for the TFTPServer library |
tuxic | 0:5c9e0971532d | 3 | * |
tuxic | 0:5c9e0971532d | 4 | * Copyright (c) 2011 Jaap Vermaas |
hudakz | 4:895c0ae49294 | 5 | * Modified by Zoltan Hudak 2018 for MBED-OS5 |
tuxic | 0:5c9e0971532d | 6 | * |
hudakz | 3:77497b352c3f | 7 | * For more detaisl see https://os.mbed.com/users/hudakz/code/TFTPServerTest/ |
hudakz | 3:77497b352c3f | 8 | * |
hudakz | 3:77497b352c3f | 9 | * The TFTPServer is part of the LaOS project (see: http://wiki.laoslaser.org) |
tuxic | 0:5c9e0971532d | 10 | * |
tuxic | 0:5c9e0971532d | 11 | * LaOS is free software: you can redistribute it and/or modify |
tuxic | 0:5c9e0971532d | 12 | * it under the terms of the GNU General Public License as published by |
tuxic | 0:5c9e0971532d | 13 | * the Free Software Foundation, either version 3 of the License, or |
tuxic | 0:5c9e0971532d | 14 | * (at your option) any later version. |
tuxic | 0:5c9e0971532d | 15 | * |
tuxic | 0:5c9e0971532d | 16 | * LaOS is distributed in the hope that it will be useful, |
tuxic | 0:5c9e0971532d | 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
tuxic | 0:5c9e0971532d | 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
tuxic | 0:5c9e0971532d | 19 | * GNU General Public License for more details. |
tuxic | 0:5c9e0971532d | 20 | * |
tuxic | 0:5c9e0971532d | 21 | * You should have received a copy of the GNU General Public License |
tuxic | 0:5c9e0971532d | 22 | * along with LaOS. If not, see <http://www.gnu.org/licenses/>. |
hudakz | 1:698437bcd48d | 23 | * |
tuxic | 0:5c9e0971532d | 24 | */ |
tuxic | 0:5c9e0971532d | 25 | #include "mbed.h" |
hudakz | 1:698437bcd48d | 26 | #include "SDBlockDevice.h" |
hudakz | 1:698437bcd48d | 27 | #include "FATFileSystem.h" |
hudakz | 1:698437bcd48d | 28 | #include "EthernetInterface.h" |
tuxic | 0:5c9e0971532d | 29 | #include "TFTPServer.h" |
hudakz | 1:698437bcd48d | 30 | #include "errno.h" |
hudakz | 1:698437bcd48d | 31 | |
hudakz | 1:698437bcd48d | 32 | Serial pc(USBTX, USBRX); |
hudakz | 1:698437bcd48d | 33 | SDBlockDevice bd(p5, p6, p7, p8); // SD card SPI driver pins: mosi, miso, sclk, cs |
hudakz | 1:698437bcd48d | 34 | FATFileSystem fs("fs"); // FAT file sytem |
hudakz | 1:698437bcd48d | 35 | EthernetInterface net; // Ethernet interface |
hudakz | 1:698437bcd48d | 36 | TFTPServer* server; // Pointer to a TFTPServer |
hudakz | 1:698437bcd48d | 37 | int myPort = 69; // TFPTServer port |
hudakz | 1:698437bcd48d | 38 | |
hudakz | 1:698437bcd48d | 39 | #define USE_DHCP |
tuxic | 0:5c9e0971532d | 40 | |
hudakz | 1:698437bcd48d | 41 | /** |
hudakz | 1:698437bcd48d | 42 | * @brief |
hudakz | 1:698437bcd48d | 43 | * @note |
hudakz | 1:698437bcd48d | 44 | * @param |
hudakz | 1:698437bcd48d | 45 | * @retval |
hudakz | 1:698437bcd48d | 46 | */ |
hudakz | 1:698437bcd48d | 47 | int main() |
hudakz | 1:698437bcd48d | 48 | { |
hudakz | 1:698437bcd48d | 49 | // Try to mount the filesystem. This should work without the Ethernet. |
hudakz | 4:895c0ae49294 | 50 | pc.printf("Mounting the filesystem... "); |
hudakz | 1:698437bcd48d | 51 | |
hudakz | 1:698437bcd48d | 52 | int err = fs.mount(&bd); |
hudakz | 1:698437bcd48d | 53 | pc.printf("%s\r\n", (err ? "Failed :(\r\n" : "OK\r\n")); |
hudakz | 1:698437bcd48d | 54 | if (err) |
hudakz | 4:895c0ae49294 | 55 | return err; |
hudakz | 1:698437bcd48d | 56 | |
hudakz | 1:698437bcd48d | 57 | // Open a file. This should work without the Ethernet, too. |
hudakz | 4:895c0ae49294 | 58 | pc.printf("Opening file '/fs/test.txt'... "); |
hudakz | 1:698437bcd48d | 59 | |
hudakz | 4:895c0ae49294 | 60 | FILE* fp = fopen("/fs/test.txt", "w+"); |
hudakz | 1:698437bcd48d | 61 | pc.printf("%s\r\n", (!fp ? "Failed :(\r\n" : "OK\r\n")); |
hudakz | 1:698437bcd48d | 62 | |
hudakz | 1:698437bcd48d | 63 | if (!fp) |
hudakz | 1:698437bcd48d | 64 | { |
hudakz | 4:895c0ae49294 | 65 | // Create the test file if it doesn't exist |
hudakz | 1:698437bcd48d | 66 | pc.printf("No file found, creating a new file ...\r\n"); |
hudakz | 3:77497b352c3f | 67 | fp = fopen("/fs/test.txt", "w+"); |
hudakz | 3:77497b352c3f | 68 | pc.printf("%s\r\n", (!fp ? "Failed :(" : "OK")); |
hudakz | 1:698437bcd48d | 69 | if (!fp) |
hudakz | 4:895c0ae49294 | 70 | { |
hudakz | 1:698437bcd48d | 71 | error("error: %s (%d)\r\n", strerror(errno), -errno); |
hudakz | 4:895c0ae49294 | 72 | return errno; |
hudakz | 4:895c0ae49294 | 73 | } |
hudakz | 4:895c0ae49294 | 74 | } |
hudakz | 4:895c0ae49294 | 75 | |
hudakz | 4:895c0ae49294 | 76 | for (int i = 0; i < 10; i++) |
hudakz | 4:895c0ae49294 | 77 | { |
hudakz | 4:895c0ae49294 | 78 | pc.printf("Writing numbers (%d/%d)... ", i, 10); |
hudakz | 4:895c0ae49294 | 79 | err = fprintf(fp, " %d\r\n", i); |
hudakz | 4:895c0ae49294 | 80 | if (err < 0) |
hudakz | 1:698437bcd48d | 81 | { |
hudakz | 4:895c0ae49294 | 82 | pc.printf("Fail :(\r\n"); |
hudakz | 4:895c0ae49294 | 83 | error("error: %s (%d)\r\n", strerror(errno), -errno); |
hudakz | 1:698437bcd48d | 84 | } |
hudakz | 4:895c0ae49294 | 85 | else |
hudakz | 4:895c0ae49294 | 86 | pc.printf("OK\r\n"); |
hudakz | 4:895c0ae49294 | 87 | } |
hudakz | 1:698437bcd48d | 88 | |
hudakz | 4:895c0ae49294 | 89 | pc.printf("Writing numbers (%d/%d)... OK\r\n\r\n", 10, 10); |
hudakz | 4:895c0ae49294 | 90 | |
hudakz | 4:895c0ae49294 | 91 | err = fclose(fp); |
hudakz | 4:895c0ae49294 | 92 | pc.printf("Closing file '/fs/test.txt'... "); |
hudakz | 4:895c0ae49294 | 93 | pc.printf("%s\r\n", (err ? "Failed :(\r\n" : "OK\r\n")); |
hudakz | 4:895c0ae49294 | 94 | if (err) |
hudakz | 4:895c0ae49294 | 95 | return err; |
tuxic | 0:5c9e0971532d | 96 | |
hudakz | 1:698437bcd48d | 97 | // Connect to the Ethernet |
hudakz | 1:698437bcd48d | 98 | pc.printf("Connecting to the Ethernet using "); |
hudakz | 1:698437bcd48d | 99 | #ifdef USE_DHCP |
hudakz | 4:895c0ae49294 | 100 | pc.printf("DHCP server... "); |
hudakz | 1:698437bcd48d | 101 | #else |
hudakz | 1:698437bcd48d | 102 | pc.printf("fixed IP ...\r\n"); |
hudakz | 1:698437bcd48d | 103 | net.set_network("192.168.1.185", "255.255.255.0", "192.168.1.1"); |
hudakz | 1:698437bcd48d | 104 | #endif |
hudakz | 4:895c0ae49294 | 105 | err = net.connect(); |
hudakz | 4:895c0ae49294 | 106 | pc.printf("%s\r\n", (err ? "Failed :(\r\n" : "OK\r\n")); |
hudakz | 4:895c0ae49294 | 107 | if (err) |
hudakz | 4:895c0ae49294 | 108 | return err; |
hudakz | 4:895c0ae49294 | 109 | |
hudakz | 4:895c0ae49294 | 110 | pc.printf("IP: %s\r\n", net.get_ip_address()); |
hudakz | 1:698437bcd48d | 111 | pc.printf("NetMask: %s\r\n\r\n", net.get_netmask()); |
hudakz | 1:698437bcd48d | 112 | |
hudakz | 1:698437bcd48d | 113 | // Create a TFTP server. |
hudakz | 4:895c0ae49294 | 114 | pc.printf("Creating a TFTP server... "); |
hudakz | 1:698437bcd48d | 115 | server = new TFTPServer(&net, myPort); |
hudakz | 4:895c0ae49294 | 116 | pc.printf("%s\r\n", (server ? "OK" : "Failed :(")); |
hudakz | 4:895c0ae49294 | 117 | if (!server) |
hudakz | 4:895c0ae49294 | 118 | return 1; |
hudakz | 4:895c0ae49294 | 119 | |
hudakz | 4:895c0ae49294 | 120 | if (server->getState() == TFTPServer::LISTENING) |
hudakz | 4:895c0ae49294 | 121 | pc.printf("\r\nThe TFTP server is listening at port %d.\r\n", myPort); |
hudakz | 4:895c0ae49294 | 122 | else |
hudakz | 4:895c0ae49294 | 123 | { |
hudakz | 4:895c0ae49294 | 124 | pc.printf("\r\nSomething went wrong.\r\nThe TFTP server is not listening.\r\n"); |
hudakz | 4:895c0ae49294 | 125 | return 1; |
hudakz | 4:895c0ae49294 | 126 | } |
tuxic | 0:5c9e0971532d | 127 | |
hudakz | 1:698437bcd48d | 128 | int fileCount = 0; // incoming files |
hudakz | 1:698437bcd48d | 129 | char fileName[256]; // to display filenames |
hudakz | 1:698437bcd48d | 130 | |
hudakz | 1:698437bcd48d | 131 | while (1) |
hudakz | 1:698437bcd48d | 132 | { |
hudakz | 1:698437bcd48d | 133 | server->poll(); |
hudakz | 1:698437bcd48d | 134 | |
hudakz | 1:698437bcd48d | 135 | if (server->fileCount() > fileCount) |
hudakz | 1:698437bcd48d | 136 | { |
hudakz | 1:698437bcd48d | 137 | fileCount = server->fileCount(); |
hudakz | 1:698437bcd48d | 138 | server->getFileName(fileName); |
hudakz | 1:698437bcd48d | 139 | pc.printf("new file: %s\r\n", fileName); |
tuxic | 0:5c9e0971532d | 140 | } |
tuxic | 0:5c9e0971532d | 141 | } |
tuxic | 0:5c9e0971532d | 142 | } |