This is an example code for using the TFTPServer library.

Dependencies:   TFTPServer

Fork of TFTPServerTest by Jaap Vermaas

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

/media/uploads/hudakz/tftpserver01.png

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
  • 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

A similar built-in TFTP client is available also on MAC and Linux operating systems.

References:
Committer:
hudakz
Date:
Fri Mar 16 19:28:34 2018 +0000
Revision:
1:698437bcd48d
Parent:
0:5c9e0971532d
Child:
2:228ce0f5c9c8
Updated for MBED-OS5.

Who changed what in which revision?

UserRevisionLine numberNew 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 * How to use:
hudakz 1:698437bcd48d 5 * -> use DHCP or change the IP to something that works for you
tuxic 0:5c9e0971532d 6 * -> connect to the mbed with a TFTP client in binary(octet) mode
tuxic 0:5c9e0971532d 7 * -> use (s)uspend and (r)esume keys to turn TFTP server on/off
hudakz 1:698437bcd48d 8 * -> upload any file
tuxic 0:5c9e0971532d 9 *
tuxic 0:5c9e0971532d 10 * Copyright (c) 2011 Jaap Vermaas
hudakz 1:698437bcd48d 11 * Modified for MBED-OS5 by Zoltan Hudak 2018
tuxic 0:5c9e0971532d 12 *
hudakz 1:698437bcd48d 13 * This file is part of the LaOS project (see: http://wiki.laoslaser.org)
tuxic 0:5c9e0971532d 14 *
tuxic 0:5c9e0971532d 15 * LaOS is free software: you can redistribute it and/or modify
tuxic 0:5c9e0971532d 16 * it under the terms of the GNU General Public License as published by
tuxic 0:5c9e0971532d 17 * the Free Software Foundation, either version 3 of the License, or
tuxic 0:5c9e0971532d 18 * (at your option) any later version.
tuxic 0:5c9e0971532d 19 *
tuxic 0:5c9e0971532d 20 * LaOS is distributed in the hope that it will be useful,
tuxic 0:5c9e0971532d 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
tuxic 0:5c9e0971532d 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
tuxic 0:5c9e0971532d 23 * GNU General Public License for more details.
tuxic 0:5c9e0971532d 24 *
tuxic 0:5c9e0971532d 25 * You should have received a copy of the GNU General Public License
tuxic 0:5c9e0971532d 26 * along with LaOS. If not, see <http://www.gnu.org/licenses/>.
hudakz 1:698437bcd48d 27 *
hudakz 1:698437bcd48d 28 *
tuxic 0:5c9e0971532d 29 */
tuxic 0:5c9e0971532d 30 #include "mbed.h"
hudakz 1:698437bcd48d 31 #include "SDBlockDevice.h"
hudakz 1:698437bcd48d 32 #include "FATFileSystem.h"
hudakz 1:698437bcd48d 33 #include "EthernetInterface.h"
tuxic 0:5c9e0971532d 34 #include "TFTPServer.h"
hudakz 1:698437bcd48d 35 #include "errno.h"
hudakz 1:698437bcd48d 36
hudakz 1:698437bcd48d 37 Serial pc(USBTX, USBRX);
hudakz 1:698437bcd48d 38 SDBlockDevice bd(p5, p6, p7, p8); // SD card SPI driver pins: mosi, miso, sclk, cs
hudakz 1:698437bcd48d 39 FATFileSystem fs("fs"); // FAT file sytem
hudakz 1:698437bcd48d 40 EthernetInterface net; // Ethernet interface
hudakz 1:698437bcd48d 41 TFTPServer* server; // Pointer to a TFTPServer
hudakz 1:698437bcd48d 42 int myPort = 69; // TFPTServer port
hudakz 1:698437bcd48d 43 Timer timer; // For sending debug messages to the remote client every two seconds
hudakz 1:698437bcd48d 44
hudakz 1:698437bcd48d 45 #define USE_DHCP
tuxic 0:5c9e0971532d 46
hudakz 1:698437bcd48d 47 /**
hudakz 1:698437bcd48d 48 * @brief
hudakz 1:698437bcd48d 49 * @note
hudakz 1:698437bcd48d 50 * @param
hudakz 1:698437bcd48d 51 * @retval
hudakz 1:698437bcd48d 52 */
hudakz 1:698437bcd48d 53 int main()
hudakz 1:698437bcd48d 54 {
hudakz 1:698437bcd48d 55 // Try to mount the filesystem. This should work without the Ethernet.
hudakz 1:698437bcd48d 56 pc.printf("Mounting the filesystem... \r\n");
hudakz 1:698437bcd48d 57 // fflush(stdout);
hudakz 1:698437bcd48d 58
hudakz 1:698437bcd48d 59 int err = fs.mount(&bd);
hudakz 1:698437bcd48d 60 pc.printf("%s\r\n", (err ? "Failed :(\r\n" : "OK\r\n"));
tuxic 0:5c9e0971532d 61
hudakz 1:698437bcd48d 62 if (err)
hudakz 1:698437bcd48d 63 return 1;
hudakz 1:698437bcd48d 64
hudakz 1:698437bcd48d 65 // Open a file. This should work without the Ethernet, too.
hudakz 1:698437bcd48d 66 pc.printf("Opening \"/fs/test.txt\"... \r\n");
hudakz 1:698437bcd48d 67 // fflush(stdout);
hudakz 1:698437bcd48d 68
hudakz 1:698437bcd48d 69 FILE* fp = fopen("/fs/test.txt", "r+");
hudakz 1:698437bcd48d 70 pc.printf("%s\r\n", (!fp ? "Failed :(\r\n" : "OK\r\n"));
hudakz 1:698437bcd48d 71
hudakz 1:698437bcd48d 72 if (!fp)
hudakz 1:698437bcd48d 73 {
hudakz 1:698437bcd48d 74 // Create the test file if it doesn't exist
hudakz 1:698437bcd48d 75 pc.printf("No file found, creating a new file ...\r\n");
hudakz 1:698437bcd48d 76 // fflush(stdout);
hudakz 1:698437bcd48d 77 fp = fopen("/fs/test.txt", "w+");
hudakz 1:698437bcd48d 78 pc.printf("%s\r\n", (!fp ? "Fail :(" : "OK"));
hudakz 1:698437bcd48d 79 if (!fp)
hudakz 1:698437bcd48d 80 error("error: %s (%d)\r\n", strerror(errno), -errno);
tuxic 0:5c9e0971532d 81
hudakz 1:698437bcd48d 82 for (int i = 0; i < 10; i++)
hudakz 1:698437bcd48d 83 {
hudakz 1:698437bcd48d 84 pc.printf("\rWriting numbers (%d/%d)... ", i, 10);
hudakz 1:698437bcd48d 85 // fflush(stdout);
hudakz 1:698437bcd48d 86 err = fprintf(fp, " %d\n", i);
hudakz 1:698437bcd48d 87 if (err < 0)
hudakz 1:698437bcd48d 88 {
hudakz 1:698437bcd48d 89 pc.printf("Fail :(\r\n");
hudakz 1:698437bcd48d 90 error("error: %s (%d)\n", strerror(errno), -errno);
hudakz 1:698437bcd48d 91 }
hudakz 1:698437bcd48d 92 }
hudakz 1:698437bcd48d 93
hudakz 1:698437bcd48d 94 pc.printf("\rWriting numbers (%d/%d)... OK\r\n", 10, 10);
hudakz 1:698437bcd48d 95
hudakz 1:698437bcd48d 96 pc.printf("Seeking file ...\r\n");
hudakz 1:698437bcd48d 97 // fflush(stdout);
hudakz 1:698437bcd48d 98 err = fseek(fp, 0, SEEK_SET);
hudakz 1:698437bcd48d 99 pc.printf("%s\r\n", (err < 0 ? "Fail :(" : "OK"));
hudakz 1:698437bcd48d 100 if (err < 0)
hudakz 1:698437bcd48d 101 {
hudakz 1:698437bcd48d 102 error("error: %s (%d)\r\n", strerror(errno), -errno);
hudakz 1:698437bcd48d 103 }
tuxic 0:5c9e0971532d 104 }
tuxic 0:5c9e0971532d 105
hudakz 1:698437bcd48d 106 // Connect to the Ethernet
hudakz 1:698437bcd48d 107 pc.printf("Connecting to the Ethernet using ");
hudakz 1:698437bcd48d 108 #ifdef USE_DHCP
hudakz 1:698437bcd48d 109 pc.printf("DHCP server ...\r\n");
hudakz 1:698437bcd48d 110 #else
hudakz 1:698437bcd48d 111 pc.printf("fixed IP ...\r\n");
hudakz 1:698437bcd48d 112 net.set_network("192.168.1.185", "255.255.255.0", "192.168.1.1");
hudakz 1:698437bcd48d 113 #endif
hudakz 1:698437bcd48d 114 net.connect();
hudakz 1:698437bcd48d 115 pc.printf("IP: %s\r\n", net.get_ip_address());
hudakz 1:698437bcd48d 116 pc.printf("NetMask: %s\r\n\r\n", net.get_netmask());
hudakz 1:698437bcd48d 117
hudakz 1:698437bcd48d 118 // Create a TFTP server.
hudakz 1:698437bcd48d 119 pc.printf("Creating a TFTP server ...\r\n\r\n");
hudakz 1:698437bcd48d 120 server = new TFTPServer(&net, myPort);
tuxic 0:5c9e0971532d 121
hudakz 1:698437bcd48d 122 int fileCount = 0; // incoming files
hudakz 1:698437bcd48d 123 char fileName[256]; // to display filenames
hudakz 1:698437bcd48d 124
hudakz 1:698437bcd48d 125 timer.start();
hudakz 1:698437bcd48d 126
hudakz 1:698437bcd48d 127 while (1)
hudakz 1:698437bcd48d 128 {
hudakz 1:698437bcd48d 129 server->poll();
hudakz 1:698437bcd48d 130
hudakz 1:698437bcd48d 131 if (pc.readable())
hudakz 1:698437bcd48d 132 {
hudakz 1:698437bcd48d 133 int c = pc.getc();
tuxic 0:5c9e0971532d 134 switch (c) {
hudakz 1:698437bcd48d 135 case 's':
hudakz 1:698437bcd48d 136 server->suspend();
tuxic 0:5c9e0971532d 137 break;
hudakz 1:698437bcd48d 138
tuxic 0:5c9e0971532d 139 case 'r':
hudakz 1:698437bcd48d 140 server->resume();
tuxic 0:5c9e0971532d 141 break;
tuxic 0:5c9e0971532d 142 }
tuxic 0:5c9e0971532d 143 }
hudakz 1:698437bcd48d 144
hudakz 1:698437bcd48d 145 if (server->fileCount() > fileCount)
hudakz 1:698437bcd48d 146 {
hudakz 1:698437bcd48d 147 fileCount = server->fileCount();
hudakz 1:698437bcd48d 148 server->getFileName(fileName);
hudakz 1:698437bcd48d 149 pc.printf("new file: %s\r\n", fileName);
tuxic 0:5c9e0971532d 150 }
hudakz 1:698437bcd48d 151
hudakz 1:698437bcd48d 152 if (timer.read() > 2)
hudakz 1:698437bcd48d 153 {
hudakz 1:698437bcd48d 154 timer.reset();
hudakz 1:698437bcd48d 155
hudakz 1:698437bcd48d 156 switch (server->getState()) {
hudakz 1:698437bcd48d 157 case TFTPServer::LISTENING:
hudakz 1:698437bcd48d 158 pc.printf("main: TFTP server is listening\r\n");
tuxic 0:5c9e0971532d 159 break;
hudakz 1:698437bcd48d 160
hudakz 1:698437bcd48d 161 case TFTPServer::READING:
hudakz 1:698437bcd48d 162 server->getFileName(fileName);
hudakz 1:698437bcd48d 163 pc.printf("main: TFTP server is reading file: %s\r\n", fileName);
tuxic 0:5c9e0971532d 164 break;
hudakz 1:698437bcd48d 165
hudakz 1:698437bcd48d 166 case TFTPServer::WRITING:
hudakz 1:698437bcd48d 167 server->getFileName(fileName);
hudakz 1:698437bcd48d 168 pc.printf("main: TFTP server is writing file: %s\r\n", fileName);
tuxic 0:5c9e0971532d 169 break;
hudakz 1:698437bcd48d 170
hudakz 1:698437bcd48d 171 case TFTPServer::ERROR:
hudakz 1:698437bcd48d 172 pc.printf("main: TFTP error\r\n");
tuxic 0:5c9e0971532d 173 break;
hudakz 1:698437bcd48d 174
hudakz 1:698437bcd48d 175 case TFTPServer::SUSPENDED:
hudakz 1:698437bcd48d 176 pc.printf("main: TFTP suspended\r\n");
tuxic 0:5c9e0971532d 177 break;
hudakz 1:698437bcd48d 178
tuxic 0:5c9e0971532d 179 default:
hudakz 1:698437bcd48d 180 pc.printf("main: Unknown TFTP status\r\n");
tuxic 0:5c9e0971532d 181 break;
tuxic 0:5c9e0971532d 182 }
tuxic 0:5c9e0971532d 183 }
tuxic 0:5c9e0971532d 184 }
tuxic 0:5c9e0971532d 185 }