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:

main.cpp

Committer:
hudakz
Date:
2018-03-16
Revision:
2:228ce0f5c9c8
Parent:
1:698437bcd48d
Child:
3:77497b352c3f

File content as of revision 2:228ce0f5c9c8:

/*
 * example program for the TFTPServer library
 *
 * How to use:
 * -> use DHCP or change the IP to something that works for you
 * -> connect to the mbed with a TFTP client in binary(octet) mode
 * -> use (s)uspend and (r)esume keys to turn TFTP server on/off
 * -> upload any file
 * 
 * Copyright (c) 2011 Jaap Vermaas
 * Modified for MBED-OS5 by Zoltan Hudak 2018
 *
 *   This file is part of the LaOS project (see: http://wiki.laoslaser.org)
 *
 *   LaOS is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   LaOS is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with LaOS.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * 
 */
#include "mbed.h"
#include "SDBlockDevice.h"
#include "FATFileSystem.h"
#include "EthernetInterface.h"
#include "TFTPServer.h"
#include "errno.h"

Serial              pc(USBTX, USBRX);
SDBlockDevice       bd(p5, p6, p7, p8); // SD card SPI driver pins: mosi, miso, sclk, cs
FATFileSystem       fs("fs");           // FAT file sytem
EthernetInterface   net;                // Ethernet interface
TFTPServer*         server;             // Pointer to a TFTPServer
int                 myPort = 69;        // TFPTServer port
Timer               timer;              // For sending debug messages to the remote client every two seconds

#define USE_DHCP

/**
 * @brief
 * @note
 * @param
 * @retval
 */
int main()
{
    // Try to mount the filesystem. This should work without the Ethernet.
    pc.printf("Mounting the filesystem... \r\n");

    int err = fs.mount(&bd);
    pc.printf("%s\r\n", (err ? "Failed :(\r\n" : "OK\r\n"));

    if (err)
        return 1;

    // Open a file. This should work without the Ethernet, too.
    pc.printf("Opening \"/fs/test.txt\"... \r\n");

    FILE*   fp = fopen("/fs/test.txt", "r+");
    pc.printf("%s\r\n", (!fp ? "Failed :(\r\n" : "OK\r\n"));

    if (!fp)
    {
        // Create the test file if it doesn't exist
        pc.printf("No file found, creating a new file ...\r\n");
       fp = fopen("/fs/test.txt", "w+");
        pc.printf("%s\r\n", (!fp ? "Fail :(" : "OK"));
        if (!fp)
            error("error: %s (%d)\r\n", strerror(errno), -errno);

        for (int i = 0; i < 10; i++)
        {
            pc.printf("\rWriting numbers (%d/%d)... ", i, 10);
            err = fprintf(fp, "    %d\n", i);
            if (err < 0)
            {
                pc.printf("Fail :(\r\n");
                error("error: %s (%d)\n", strerror(errno), -errno);
            }
        }

        pc.printf("\rWriting numbers (%d/%d)... OK\r\n", 10, 10);

        pc.printf("Seeking file ...\r\n");
        err = fseek(fp, 0, SEEK_SET);
        pc.printf("%s\r\n", (err < 0 ? "Fail :(" : "OK"));
        if (err < 0)
        {
            error("error: %s (%d)\r\n", strerror(errno), -errno);
        }
    }

    // Connect to the Ethernet
    pc.printf("Connecting to the Ethernet using ");
#ifdef USE_DHCP
    pc.printf("DHCP server ...\r\n");
#else
    pc.printf("fixed IP ...\r\n");
    net.set_network("192.168.1.185", "255.255.255.0", "192.168.1.1");
#endif
    net.connect();
    pc.printf("IP: %s\r\n", net.get_ip_address());
    pc.printf("NetMask: %s\r\n\r\n", net.get_netmask());

    // Create a TFTP server.
    pc.printf("Creating a TFTP server ...\r\n\r\n");
    server = new TFTPServer(&net, myPort);

    int     fileCount = 0;  // incoming files
    char    fileName[256];  // to display filenames

    timer.start();

    while (1)
    {
        server->poll();

        if (pc.readable())
        {
            int c = pc.getc();
            switch (c) {
                case 's':
                    server->suspend();
                    break;

                case 'r':
                    server->resume();
                    break;
            }
        }

        if (server->fileCount() > fileCount)
        {
            fileCount = server->fileCount();
            server->getFileName(fileName);
            pc.printf("new file: %s\r\n", fileName);
        }

        if (timer.read() > 2)
        {
            timer.reset();

            switch (server->getState()) {
                case TFTPServer::LISTENING:
                    pc.printf("main: TFTP server is listening\r\n");
                    break;

                case TFTPServer::READING:
                    server->getFileName(fileName);
                    pc.printf("main: TFTP server is reading file: %s\r\n", fileName);
                    break;

                case TFTPServer::WRITING:
                    server->getFileName(fileName);
                    pc.printf("main: TFTP server is writing file: %s\r\n", fileName);
                    break;

                case TFTPServer::ERROR:
                    pc.printf("main: TFTP error\r\n");
                    break;

                case TFTPServer::SUSPENDED:
                    pc.printf("main: TFTP suspended\r\n");
                    break;

                default:
                    pc.printf("main: Unknown TFTP status\r\n");
                    break;
            }
        }
    }
}