Page 1 of 1

ESP32 FTP Server

Posted: Mon May 14, 2018 12:02 am
by kolban
Over the last period, there have been some requests for FTP Server capabilities. Fortunately, it isn't horrendous to implement the FTP Server protocol and an attempt was made to produce one using C++ classes that would run on an ESP32 under ESP-IDF.

The first pass at this has been completed and the effort is available as part of the CPP_UTILS package found here: ... /cpp_utils

This should be enough to get us all going and can serve as a base for interest and enhancements.

Here are some preliminary docs:

FTP Server
FTP (File Transfer Protocol) is a technology specification that allows one to request files from a remote server or store files to a remote server. On the popular operating systems such as Windows, Linux and Mac, there are both FTP Server implementations and FTP Client implementations. For the ESP32, an implementation of an FTP server component is available. When used, it allows the ESP32 to become an FTP server that will respond to remote FTP client requests to send and receive files. This assumes that that an implementation of a Posix compliant file system has been made available such as found with the SPIFFs or FAT components.
To use the FTP server technology, an ESP32 should be network connected (eg. WiFi) and then create and configured an instance of the FTPServer C++ class.

For example:

Code: Select all

FTPServer* ftpServer = new FTPServer();
ftpServer->setCallbacks(new FTPFileCallbacks());
When designing the FTP server for the ESP32, it was felt that there might be opportunities for use beyond just serving files. There might be opportunities for other areas such as providing OTA images for flash. To accommodate this, a callback technique was introduced through a C++ class called FTPCallbacks. This class exposes a series of virtual functions that can be implemented in your own class that inherits from FTPCallbacks. Your class will then be called during the life cycle of FTP operations. Specifically, the following methods are exposed:

• void onStoreStart(std::string fileName) – Called at the start of a store request when the client wishes to store a new file.
• size_t onStoreData(uint8_t* data, size_t size) – Called repeatedly to provide a new chunk of data from the client to the server as part of the store request.
• void onStoreEnd() - Called at the end of store request to indicate that the file transfer has been completed.
• void onRetrieveStart(std::string fileName) – Called at the start of a retrieve request when the client wishes to retrieve a file.
• size_t onRetrieveData(uint8_t* data, size_t size) – Call repeatedly when the client is ready for the next chunk of data. The return from this call is the size of data to be returned. To indicate that there is no further data, return 0.
• void onRetrieveEnd() - Called when the data has been sent to the client.
• std::string onDir() - Return a listing of the current directory.

An implementation of this class called FTPFileCallbacks is provided which maps these commands to the Posix file-system.
An FTP Server listens on a TCP/IP port number. The default is 21. Should we wish to specify our own port number, we can call setPort(portNumber) prior to calling start().

Since an FTP client can retrieve and store data, we may wish to include degrees of security. The most basic technique is that of a userid/password pair. By default, the ESP32 class doesn't require these but if we wish, we can enable that capability by calling setCredentials(userid, password) prior to calling start(). If configured in this manner, then the FTP client must provide a userid/password pair that match before further access will be granted. Note that FTP (by default) is inherently insecure as the data (including userid/password pairs) are transmitted in the clear without encryption. While various FTP implementations can and do provide transport channel level encryption using SSL/TLS, this has not yet been implemented in this project.

Re: ESP32 FTP Server

Posted: Tue May 29, 2018 12:16 pm
by snahmad75
FTPServer expect these mathods to be implemented.

int chdir(const char *path)
FRESULT result = f_chdir(path);
return result == FR_OK ? 0 : -1;

char *getcwd(char *buf, size_t size)
FRESULT result = f_getcwd(buf, size);
return result == FR_OK ? buf : NULL;

__fs = new FATFS_VFS("/spiflash", "storage");

But getcwd return "\:0" not /spiflash

Re: ESP32 FTP Server

Posted: Tue May 29, 2018 2:41 pm
by kolban
The thing about an FTP server is that, in principle, it can handle multiple concurrent clients. The concept of a the "current working directory" is a process/system wide concept on the ESP32. One of the things I am still wrestling with is the design and implementation of how I want to maintain the notion of the current directory on a per client connection basis. There are two possibilities.... the first is that I restrict the FTP server to just one incoming client ... problem solved. The other is that I maintain the logical concept of the current working directory per client connection and then explicitly add the path to the current working directory on each relative path supplied by the client.

Re: ESP32 FTP Server

Posted: Tue May 29, 2018 3:56 pm
by snahmad75
In my case. i need to support only one client at a time. How we can solve it.

I am adding support for folder creation and deletion.

ofstream and ifstream get failure. fopen and fclose is better less failure.

I need to add browser to sub folder feature as well ? any idea how easy to add.

Re: ESP32 FTP Server

Posted: Tue May 29, 2018 7:55 pm
by snahmad75
Hi Kolban,

have you written FTPServer test code. kindly share it

Re: ESP32 FTP Server

Posted: Tue May 29, 2018 8:44 pm
by kolban
There are a couple of pages of notes on it in the latest release of my ESP32 book of notes found here:

Realize it is free for download but contributions for its maintenance and upkeep welcomed.

Oh wait ... I just realize that I copied/pasted the same text in the first post in this thread.