diff --git a/FtpServer.cpp b/FtpServer.cpp index 9d65877..c24eb57 100644 --- a/FtpServer.cpp +++ b/FtpServer.cpp @@ -172,7 +172,29 @@ uint8_t FtpServer::handleFTP() { cmdStage = FTP_Client; } else if (cmdStage == FTP_Client) { // Ftp server idle -#ifdef ESP8266 +#if (FTP_SERVER_NETWORK_TYPE == NETWORK_WiFiNINA) +// if (client && !client.connected()) { +// client.stop(); +// DEBUG_PRINTLN(F("CLIENT STOP!!")); +// } + byte status; + client = ftpServer.available(&status); + /* + * CLOSED = 0, + LISTEN = 1, + SYN_SENT = 2, + SYN_RCVD = 3, + ESTABLISHED = 4, + FIN_WAIT_1 = 5, + FIN_WAIT_2 = 6, + CLOSE_WAIT = 7, + CLOSING = 8, + LAST_ACK = 9, + TIME_WAIT = 10 + * + */ +// DEBUG_PRINTLN(status); +#elif defined(ESP8266) if( ftpServer.hasClient()) { client.stop(); @@ -915,14 +937,16 @@ int FtpServer::dataConnect( bool out150 ) uint16_t count = 1000; // wait up to a second while( ! data.connected() && count -- > 0 ) { - #ifdef ESP8266 + #if (FTP_SERVER_NETWORK_TYPE == NETWORK_WiFiNINA) + data = dataServer.available(); + #elif defined(ESP8266) if( dataServer.hasClient()) { data.stop(); data = dataServer.available(); } #else - data = dataServer.accept(); + data = dataServer.accept(); #endif delay( 1 ); } @@ -2151,7 +2175,7 @@ uint16_t FtpServer::fileSize( FTP_FILE file ) { return true; } } -#elif STORAGE_TYPE <= STORAGE_SDFAT2 +#elif STORAGE_TYPE <= STORAGE_SDFAT2 || STORAGE_TYPE == STORAGE_SPIFM bool FtpServer::openFile( char path[ FTP_CWD_SIZE ], int readTypeInt ){ DEBUG_PRINT(F("File to open ") ); DEBUG_PRINT( path ); diff --git a/FtpServer.h b/FtpServer.h index ebb00e2..8b686b4 100644 --- a/FtpServer.h +++ b/FtpServer.h @@ -18,652 +18,9 @@ #ifndef FTP_SERVER_H #define FTP_SERVER_H -#define FTP_SERVER_VERSION "2021-11-09" +#define FTP_SERVER_VERSION "2022-03-11" #include -#if ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif - -// -//#if(NETWORK_ESP8266_SD == DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP8266) -// #define ESP8266_GT_2_4_2_SD_STORAGE_SELECTED -// #define DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP8266 NETWORK_ESP8266 -//#endif - -#if !defined(FTP_SERVER_NETWORK_TYPE) -// select Network type based - #if defined(ESP8266) || defined(ESP31B) - #if(NETWORK_ESP8266_242 == DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP8266) - #define ARDUINO_ESP8266_RELEASE_2_4_2 - - #define FTP_SERVER_NETWORK_TYPE_SELECTED NETWORK_ESP8266_242 - - #define FTP_SERVER_NETWORK_TYPE NETWORK_ESP8266 - #else - #define FTP_SERVER_NETWORK_TYPE DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP8266 - #endif - - #define STORAGE_TYPE DEFAULT_STORAGE_TYPE_ESP8266 - #elif defined(ESP32) - #define FTP_SERVER_NETWORK_TYPE DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP32 - #define STORAGE_TYPE DEFAULT_STORAGE_TYPE_ESP32 - #elif defined(ARDUINO_ARCH_SAMD) - #define FTP_SERVER_NETWORK_TYPE DEFAULT_FTP_SERVER_NETWORK_TYPE_SAMD - #define STORAGE_TYPE DEFAULT_STORAGE_TYPE_SAMD - #else - #define FTP_SERVER_NETWORK_TYPE DEFAULT_FTP_SERVER_NETWORK_TYPE_ARDUINO - #define STORAGE_TYPE DEFAULT_STORAGE_TYPE_ARDUINO - // #define STORAGE_SD_ENABLED - #endif -#endif - -#ifndef FTP_SERVER_NETWORK_TYPE_SELECTED - #define FTP_SERVER_NETWORK_TYPE_SELECTED FTP_SERVER_NETWORK_TYPE -#endif - - -#if defined(ESP8266) || defined(ESP31B) - #ifndef STORAGE_SD_FORCE_DISABLE - #define STORAGE_SD_ENABLED - #endif - #ifndef STORAGE_SPIFFS_FORCE_DISABLE - #define STORAGE_SPIFFS_ENABLED - #endif -#elif defined(ESP32) - #ifndef STORAGE_SD_FORCE_DISABLE - #define STORAGE_SD_ENABLED - #endif - #ifndef STORAGE_SPIFFS_FORCE_DISABLE - #define STORAGE_SPIFFS_ENABLED - #endif -#else - #ifndef STORAGE_SD_FORCE_DISABLE - #define STORAGE_SD_ENABLED - #endif -#endif - - -// Includes and defined based on Network Type -#if(FTP_SERVER_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) - -// Note: -// No SSL/WSS support for client in Async mode -// TLS lib need a sync interface! - -#if defined(ESP8266) -#include -//#include -#elif defined(ESP32) -#include -//#include - -#define FTP_CLIENT_NETWORK_CLASS WiFiClient -//#define FTP_CLIENT_NETWORK_SSL_CLASS WiFiClientSecure -#define FTP_SERVER_NETWORK_SERVER_CLASS WiFiServer - -#elif defined(ESP31B) -#include -#else -#error "network type ESP8266 ASYNC only possible on the ESP mcu!" -#endif - -#elif(FTP_SERVER_NETWORK_TYPE == NETWORK_ESP8266 || FTP_SERVER_NETWORK_TYPE == NETWORK_ESP8266_242) - - #if !defined(ESP8266) && !defined(ESP31B) - #error "network type ESP8266 only possible on the ESP mcu!" - #endif - - #ifdef ESP8266 - #include - #else - #include - #endif - #define FTP_CLIENT_NETWORK_CLASS WiFiClient - //#define FTP_CLIENT_NETWORK_SSL_CLASS WiFiClientSecure - #define FTP_SERVER_NETWORK_SERVER_CLASS WiFiServer - #define NET_CLASS WiFi - #define CommandIs( a ) (command != NULL && ! strcmp_P( command, PSTR( a ))) - #define ParameterIs( a ) ( parameter != NULL && ! strcmp_P( parameter, PSTR( a ))) - #elif(FTP_SERVER_NETWORK_TYPE == NETWORK_W5100) - - #ifdef STM32_DEVICE - #define FTP_CLIENT_NETWORK_CLASS TCPClient - #define FTP_SERVER_NETWORK_SERVER_CLASS TCPServer - #define CommandIs( a ) ( ! strcmp_PF( command, PSTR( a ))) - #define ParameterIs( a ) ( ! strcmp_PF( parameter, PSTR( a ))) - #define NET_CLASS Ethernet - #else - #include - #include - #define FTP_CLIENT_NETWORK_CLASS EthernetClient - #define FTP_SERVER_NETWORK_SERVER_CLASS EthernetServer - #define NET_CLASS Ethernet - #define CommandIs( a ) ( ! strcmp_PF( command, PSTR( a ))) - #define ParameterIs( a ) ( ! strcmp_PF( parameter, PSTR( a ))) - #endif - -#elif(FTP_SERVER_NETWORK_TYPE == NETWORK_ENC28J60) - - #include - - #define FTP_CLIENT_NETWORK_CLASS UIPClient - #define FTP_SERVER_NETWORK_SERVER_CLASS UIPServer - #define NET_CLASS Ethernet - #define CommandIs( a ) ( ! strcmp_PF( command, PSTR( a ))) - #define ParameterIs( a ) ( ! strcmp_PF( parameter, PSTR( a ))) - //SSLClient client(base_client, TAs, (size_t)TAs_NUM, A5); -#elif(FTP_SERVER_NETWORK_TYPE == NETWORK_ESP32) - - #include - //#include - #define FTP_CLIENT_NETWORK_CLASS WiFiClient - //#define FTP_CLIENT_NETWORK_SSL_CLASS WiFiClientSecure - #define FTP_SERVER_NETWORK_SERVER_CLASS WiFiServer - #define NET_CLASS WiFi - #define CommandIs( a ) (command != NULL && ! strcmp_P( command, PSTR( a ))) - #define ParameterIs( a ) ( parameter != NULL && ! strcmp_P( parameter, PSTR( a ))) -#elif(FTP_SERVER_NETWORK_TYPE == NETWORK_ESP32_ETH) - - #include - #define FTP_CLIENT_NETWORK_CLASS WiFiClient - #define FTP_SERVER_NETWORK_SERVER_CLASS WiFiServer - #define NET_CLASS Ethernet - #define CommandIs( a ) ( ! strcmp_PF( command, PSTR( a ))) - #define ParameterIs( a ) ( ! strcmp_PF( parameter, PSTR( a ))) -#elif(FTP_SERVER_NETWORK_TYPE == NETWORK_WiFiNINA) - - #include - #define FTP_CLIENT_NETWORK_CLASS WiFiClient - //#define FTP_CLIENT_NETWORK_SSL_CLASS WiFiSSLClient - #define FTP_SERVER_NETWORK_SERVER_CLASS WiFiServer - #define NET_CLASS WiFi - #define CommandIs( a ) ( ! strcmp_PF( command, PSTR( a ))) - #define ParameterIs( a ) ( ! strcmp_PF( parameter, PSTR( a ))) -#elif(FTP_SERVER_NETWORK_TYPE == NETWORK_SEEED_RTL8720DN) - - #include - #define FTP_CLIENT_NETWORK_CLASS WiFiClient - //#define FTP_CLIENT_NETWORK_SSL_CLASS WiFiSSLClient - #define FTP_SERVER_NETWORK_SERVER_CLASS WiFiServer - #define NET_CLASS WiFi - #define CommandIs( a ) ( ! strcmp_PF( command, PSTR( a ))) - #define ParameterIs( a ) ( ! strcmp_PF( parameter, PSTR( a ))) -#else - #error "no network type selected!" -#endif - -#if(STORAGE_TYPE == STORAGE_SPIFFS) - #if defined(ESP32) -// #define FS_NO_GLOBALS - #include - - #define FTP_FILE File - #define FTP_DIR File - #else - #ifdef ARDUINO_ESP8266_RELEASE_2_4_2 - #define FS_NO_GLOBALS - #include "FS.h" - #define FTP_FILE fs::File - #define FTP_DIR fs::Dir - #else - #include "FS.h" - #define FTP_FILE File - #define FTP_DIR Dir - #endif - - #endif - - -#if ESP8266 - #define FTP_FILE_READ "r" - #define FTP_FILE_READ_ONLY "r" - #define FTP_FILE_READ_WRITE "w+" - #define FTP_FILE_WRITE_APPEND "a+" - #define FTP_FILE_WRITE_CREATE "w+" -#else - #define FTP_FILE_READ "r" - #define FTP_FILE_READ_ONLY "r" - #define FTP_FILE_READ_WRITE "w" - #define FTP_FILE_WRITE_APPEND "a" - #define FTP_FILE_WRITE_CREATE "w" -#endif - - #define STORAGE_MANAGER SPIFFS -#elif(STORAGE_TYPE == STORAGE_FFAT) - #include "FS.h" - #include "FFat.h" - - #define STORAGE_MANAGER FFat - - #define FTP_FILE File - #define FTP_DIR File - - #define FTP_FILE_READ "r" - #define FTP_FILE_READ_ONLY "r" - #define FTP_FILE_READ_WRITE "w" - #define FTP_FILE_WRITE_APPEND "a" - #define FTP_FILE_WRITE_CREATE "w" - -#elif(STORAGE_TYPE == STORAGE_LITTLEFS) - #if ESP8266 - #include "LittleFS.h" - #define STORAGE_MANAGER LittleFS - #define FTP_FILE File - #define FTP_DIR Dir - - #define FTP_FILE_READ "r" - #define FTP_FILE_READ_ONLY "r" - #define FTP_FILE_READ_WRITE "w+" - #define FTP_FILE_WRITE_APPEND "a+" - #define FTP_FILE_WRITE_CREATE "w+" - #else -#if ESP_ARDUINO_VERSION_MAJOR >= 2 - #include "FS.h" - #include "LittleFS.h" - #define STORAGE_MANAGER LittleFS -#else - #include "LITTLEFS.h" - #define STORAGE_MANAGER LITTLEFS -#endif - #define FTP_FILE File - #define FTP_DIR File - - #define FTP_FILE_READ "r" - #define FTP_FILE_READ_ONLY "r" - #define FTP_FILE_READ_WRITE "w" - #define FTP_FILE_WRITE_APPEND "a" - #define FTP_FILE_WRITE_CREATE "w" - #endif -#elif(STORAGE_TYPE == STORAGE_SD) - #include - #include - - #define STORAGE_MANAGER SD - #define FTP_FILE File - #define FTP_DIR File - - #define FTP_FILE_READ FILE_READ - #define FTP_FILE_READ_ONLY FILE_READ - #define FTP_FILE_READ_WRITE FILE_WRITE -#ifdef ESP32 - #define FTP_FILE_READ_WRITE FILE_WRITE - #define FTP_FILE_WRITE_APPEND FILE_APPEND -#else - #define FTP_FILE_READ_WRITE FILE_WRITE - #define FTP_FILE_WRITE_APPEND FILE_WRITE -#endif - #define FTP_FILE_WRITE_CREATE FILE_WRITE - -#elif(STORAGE_TYPE == STORAGE_SEEED_SD) - #include - #define STORAGE_MANAGER SD - - #include "SD/Seeed_SD.h" - - - -// #define STORAGE_MANAGER SPIFLASH -// #include "SFUD/Seeed_SFUD.h" - - #define FTP_FILE File - #define FTP_DIR File - - #define FTP_FILE_READ FILE_READ - #define FTP_FILE_READ_ONLY FILE_READ - #define FTP_FILE_READ_WRITE FILE_WRITE - #define FTP_FILE_WRITE_APPEND FILE_APPEND - #define FTP_FILE_WRITE_CREATE FILE_WRITE - -#elif (STORAGE_TYPE == STORAGE_SDFAT1) - #include - #include - - #define STORAGE_MANAGER sd - #define FTP_FILE SdFile - #define FTP_DIR SdFile - extern SdFat STORAGE_MANAGER; - - #define FTP_FILE_READ O_READ - #define FTP_FILE_READ_ONLY O_RDONLY - #define FTP_FILE_READ_WRITE O_RDWR - #define FTP_FILE_WRITE_APPEND O_WRITE | O_APPEND - #define FTP_FILE_WRITE_CREATE O_WRITE | O_CREAT -#elif (STORAGE_TYPE == STORAGE_SDFAT2) - #include - #include - - #define STORAGE_MANAGER sd - #define FTP_FILE FsFile - #define FTP_DIR FsFile - extern SdFat STORAGE_MANAGER; - - #define FTP_FILE_READ O_READ - #define FTP_FILE_READ_ONLY O_RDONLY - #define FTP_FILE_READ_WRITE O_RDWR - #define FTP_FILE_WRITE_APPEND O_WRITE | O_APPEND - #define FTP_FILE_WRITE_CREATE O_WRITE | O_CREAT -#elif (STORAGE_TYPE == STORAGE_SPIFM) - #include - #include - #include - - #define STORAGE_MANAGER fatfs - #define FTP_FILE File - #define FTP_DIR File - extern FatFileSystem STORAGE_MANAGER; - extern Adafruit_SPIFlash flash; - #define FTP_FILE_READ O_READ - #define FTP_FILE_READ_ONLY O_RDONLY - #define FTP_FILE_READ_WRITE O_RDWR - #define FTP_FILE_WRITE_APPEND O_WRITE | O_APPEND - #define FTP_FILE_WRITE_CREATE O_WRITE | O_CREAT - -#elif (STORAGE_TYPE == STORAGE_FATFS) - #include - #include - - #define STORAGE_MANAGER sdff - #define FTP_FILE FileFs - #define FTP_DIR DirFs - extern FatFsClass STORAGE_MANAGER; - #define O_READ FA_READ - #define O_WRITE FA_WRITE - #define O_RDWR FA_READ | FA_WRITE - #define O_CREAT FA_CREATE_ALWAYS - #define O_APPEND FA_OPEN_APPEND - - #define FTP_FILE_READ O_READ - #define FTP_FILE_READ_ONLY O_RDONLY - #define FTP_FILE_READ_WRITE O_RDWR - #define FTP_FILE_WRITE_APPEND O_WRITE | O_APPEND - #define FTP_FILE_WRITE_CREATE O_WRITE | O_CREAT -#endif - -//#ifdef FTP_CLIENT_NETWORK_SSL_CLASS -//#define FTP_CLIENT_NETWORK_CLASS FTP_CLIENT_NETWORK_SSL_CLASS -//#endif - -#define OPEN_CLOSE_SPIFFS -#define OPEN_CLOSE_SD - -// Setup debug printing macros. -#ifdef FTP_SERVER_DEBUG - #define DEBUG_PRINT(...) { DEBUG_PRINTER.print(__VA_ARGS__); } - #define DEBUG_PRINTLN(...) { DEBUG_PRINTER.println(__VA_ARGS__); } -#else - #define DEBUG_PRINT(...) {} - #define DEBUG_PRINTLN(...) {} -#endif - -#define FTP_CMD_PORT 21 // Command port on wich server is listening -#define FTP_DATA_PORT_DFLT 20 // Default data port in active mode -#define FTP_DATA_PORT_PASV 50009 // Data port in passive mode - -#define FF_MAX_LFN 255 // max size of a long file name -#define FTP_CMD_SIZE FF_MAX_LFN+8 // max size of a command -#define FTP_CWD_SIZE FF_MAX_LFN+8 // max size of a directory name -#define FTP_FIL_SIZE FF_MAX_LFN // max size of a file name -#define FTP_CRED_SIZE 16 // max size of username and password -#define FTP_NULLIP() IPAddress(0,0,0,0) - -enum ftpCmd { FTP_Stop = 0, // In this stage, stop any connection - FTP_Init, // initialize some variables - FTP_Client, // wait for client connection - FTP_User, // wait for user name - FTP_Pass, // wait for user password - FTP_Cmd }; // answers to commands - -enum ftpTransfer { FTP_Close = 0, // In this stage, close data channel - FTP_Retrieve, // retrieve file - FTP_Store, // store file - FTP_List, // list of files - FTP_Nlst, // list of name of files - FTP_Mlsd }; // listing for machine processing - -enum ftpDataConn { FTP_NoConn = 0,// No data connexion - FTP_Pasive, // Pasive type - FTP_Active }; // Active type - -enum FtpOperation { - FTP_CONNECT, - FTP_DISCONNECT, - FTP_FREE_SPACE_CHANGE -}; - -enum FtpTransferOperation { - FTP_UPLOAD_START = 0, - FTP_UPLOAD = 1, - - FTP_DOWNLOAD_START = 2, - FTP_DOWNLOAD = 3, - - - FTP_TRANSFER_STOP = 4, - FTP_DOWNLOAD_STOP = 4, - FTP_UPLOAD_STOP = 4, - - FTP_TRANSFER_ERROR = 5, - FTP_DOWNLOAD_ERROR = 5, - FTP_UPLOAD_ERROR = 5 -}; - -class FtpServer -{ -public: - FtpServer( uint16_t _cmdPort = FTP_CMD_PORT, uint16_t _pasvPort = FTP_DATA_PORT_PASV ); - - void begin( const char * _user, const char * _pass, const char * welcomeMessage = "Welcome to Simply FTP server" ); - void begin( const char * welcomeMessage = "Welcome to Simply FTP server" ); - - void end(); - void setLocalIp(IPAddress localIp); - void credentials( const char * _user, const char * _pass ); - uint8_t handleFTP(); - - void setCallback(void (*_callbackParam)(FtpOperation ftpOperation, unsigned int freeSpace, unsigned int totalSpace) ) - { - _callback = _callbackParam; - } - - void setTransferCallback(void (*_transferCallbackParam)(FtpTransferOperation ftpOperation, const char* name, unsigned int transferredSize) ) - { - _transferCallback = _transferCallbackParam; - } - -private: - void (*_callback)(FtpOperation ftpOperation, unsigned int freeSpace, unsigned int totalSpace){}; - void (*_transferCallback)(FtpTransferOperation ftpOperation, const char* name, unsigned int transferredSize){}; - - void iniVariables(); - void clientConnected(); - void disconnectClient(); - bool processCommand(); - bool haveParameter(); - int dataConnect( bool out150 = true ); - bool dataConnected(); - bool doRetrieve(); - bool doStore(); - bool doList(); - bool doMlsd(); - void closeTransfer(); - void abortTransfer(); - bool makePath( char * fullName, char * param = NULL ); - bool makeExistsPath( char * path, char * param = NULL ); - bool openDir( FTP_DIR * pdir ); - bool isDir( char * path ); - uint8_t getDateTime( char * dt, uint16_t * pyear, uint8_t * pmonth, uint8_t * pday, - uint8_t * phour, uint8_t * pminute, uint8_t * second ); - char * makeDateTimeStr( char * tstr, uint16_t date, uint16_t time ); - bool timeStamp( char * path, uint16_t year, uint8_t month, uint8_t day, - uint8_t hour, uint8_t minute, uint8_t second ); - bool getFileModTime( char * path, uint16_t * pdate, uint16_t * ptime ); -#if STORAGE_TYPE != STORAGE_FATFS - bool getFileModTime( uint16_t * pdate, uint16_t * ptime ); -#endif - int8_t readChar(); - - const char* getFileName(FTP_FILE *file){ - #if STORAGE_TYPE <= STORAGE_SDFAT2 - int max_characters = 100; - char f_name[max_characters]; - file->getName(f_name, max_characters); - String filename = String(f_name); - return filename.c_str(); - #elif STORAGE_TYPE == STORAGE_FATFS - return file->fileName(); - #else - return file->name(); - #endif - } - bool exists( const char * path ) { -#if STORAGE_TYPE == STORAGE_SPIFFS || (STORAGE_TYPE == STORAGE_SD && FTP_SERVER_NETWORK_TYPE == NETWORK_ESP8266_242) - if (strcmp(path, "/") == 0) return true; -#endif -#if STORAGE_TYPE == STORAGE_FFAT || (STORAGE_TYPE == STORAGE_LITTLEFS && defined(ESP32)) - FTP_DIR f = STORAGE_MANAGER.open(path, "r"); - return (f == true); -#else - return STORAGE_MANAGER.exists( path ); -#endif - }; - bool remove( const char * path ) { return STORAGE_MANAGER.remove( path ); }; -#if STORAGE_TYPE == STORAGE_SPIFFS - bool makeDir( const char * path ) { return false; }; - bool removeDir( const char * path ) { return false; }; -#else - bool makeDir( const char * path ) { return STORAGE_MANAGER.mkdir( path ); }; - bool removeDir( const char * path ) { return STORAGE_MANAGER.rmdir( path ); }; -#endif - -#if STORAGE_TYPE == STORAGE_SD - bool rename( const char * path, const char * newpath ); -#else - bool rename( const char * path, const char * newpath ) { return STORAGE_MANAGER.rename( path, newpath ); }; -#endif -#if (STORAGE_TYPE == STORAGE_SEEED_SD) - bool openFile( char path[ FTP_CWD_SIZE ], int readTypeInt ); -#elif (STORAGE_TYPE == STORAGE_SD && defined(ESP8266))// FTP_SERVER_NETWORK_TYPE_SELECTED == NETWORK_ESP8266_242) - bool openFile( char path[ FTP_CWD_SIZE ], int readTypeInt ); -#elif (STORAGE_TYPE == STORAGE_SPIFFS || STORAGE_TYPE == STORAGE_LITTLEFS || STORAGE_TYPE == STORAGE_FFAT ) - bool openFile( const char * path, const char * readType ); -// bool openFile( char path[ FTP_CWD_SIZE ], int readTypeInt ); -#elif STORAGE_TYPE <= STORAGE_SDFAT2 - bool openFile( char path[ FTP_CWD_SIZE ], int readTypeInt ); -#else - bool openFile( char path[ FTP_CWD_SIZE ], const char * readType ); - bool openFile( const char * path, const char * readType ); -// bool openFile( char path[ FTP_CWD_SIZE ], int readTypeInt ); -#endif -// bool openFile( char path[ FTP_CWD_SIZE ], const char * readType ); -// bool openFile( const char * path, const char * readType ); - uint16_t fileSize( FTP_FILE file ); - -#if STORAGE_TYPE == STORAGE_SPIFFS || STORAGE_TYPE == STORAGE_LITTLEFS -#if ESP8266 - uint32_t capacity() { - FSInfo fi; - STORAGE_MANAGER.info(fi); - - return fi.totalBytes >> 1; - }; - uint32_t free() { - FSInfo fi; - STORAGE_MANAGER.info(fi); - - return (fi.totalBytes - fi.usedBytes) >> 1; - }; -#else - uint32_t capacity() { - return STORAGE_MANAGER.totalBytes() >> 1; - }; - uint32_t free() { - return (STORAGE_MANAGER.totalBytes() - - STORAGE_MANAGER.usedBytes()) >> 1; - }; -#endif -#elif STORAGE_TYPE == STORAGE_SD - uint32_t capacity() { return true; }; - uint32_t free() { return true; }; -#elif STORAGE_TYPE == STORAGE_SEEED_SD - uint32_t capacity() { - return STORAGE_MANAGER.totalBytes() >> 1; - }; - uint32_t free() { - return (STORAGE_MANAGER.totalBytes() - - STORAGE_MANAGER.usedBytes()) >> 1; - }; -#elif STORAGE_TYPE == STORAGE_SDFAT1 - uint32_t capacity() { return STORAGE_MANAGER.card()->cardSize() >> 1; }; - uint32_t free() { return STORAGE_MANAGER.vol()->freeClusterCount() * - STORAGE_MANAGER.vol()->sectorsPerCluster() >> 1; }; -#elif STORAGE_TYPE == STORAGE_SDFAT2 - uint32_t capacity() { return STORAGE_MANAGER.card()->sectorCount() >> 1; }; - uint32_t free() { return STORAGE_MANAGER.vol()->freeClusterCount() * - STORAGE_MANAGER.vol()->sectorsPerCluster() >> 1; }; -#elif STORAGE_TYPE == STORAGE_SPIFM - uint32_t capacity() { return flash.size() >> 10; }; - uint32_t free() { return 0; }; // TODO // -#elif STORAGE_TYPE == STORAGE_FATFS - uint32_t capacity() { return STORAGE_MANAGER.capacity(); }; - uint32_t free() { return STORAGE_MANAGER.free(); }; -#elif STORAGE_TYPE == STORAGE_FFAT - uint32_t capacity() { return STORAGE_MANAGER.totalBytes(); }; - uint32_t free() { return STORAGE_MANAGER.freeBytes(); }; -#endif - bool legalChar( char c ) // Return true if char c is allowed in a long file name - { - if( c == '"' || c == '*' || c == '?' || c == ':' || - c == '<' || c == '>' || c == '|' ) - return false; -#if STORAGE_TYPE == STORAGE_FATFS - return 0x1f < c && c < 0xff; -#else - return 0x1f < c && c < 0x7f; -#endif - } - - IPAddress localIp; // IP address of server as seen by clients - IPAddress dataIp; // IP address of client for data - FTP_SERVER_NETWORK_SERVER_CLASS ftpServer; - FTP_SERVER_NETWORK_SERVER_CLASS dataServer; - - - FTP_CLIENT_NETWORK_CLASS client; - FTP_CLIENT_NETWORK_CLASS data; - - FTP_FILE file; - FTP_DIR dir; - - ftpCmd cmdStage; // stage of ftp command connexion - ftpTransfer transferStage; // stage of data connexion - ftpDataConn dataConn; // type of data connexion - - bool anonymousConnection = false; - - uint8_t __attribute__((packed, aligned(4))) // need to be aligned to 32bit for Esp8266 SPIClass::transferBytes() - buf[ FTP_BUF_SIZE ]; // data buffer for transfers - char cmdLine[ FTP_CMD_SIZE ]; // where to store incoming char from client - char cwdName[ FTP_CWD_SIZE ]; // name of current directory - char rnfrName[ FTP_CWD_SIZE ]; // name of file for RNFR command - const char * user; // user name - const char * pass; // password - char command[ 5 ]; // command sent by client - bool rnfrCmd; // previous command was RNFR - char * parameter; // point to begin of parameters sent by client - const char * welcomeMessage; - uint16_t cmdPort, - pasvPort, - dataPort; - uint16_t iCL; // pointer to cmdLine next incoming char - uint16_t nbMatch; - - uint32_t millisDelay, // - millisEndConnection, // - millisBeginTrans, // store time of beginning of a transaction - bytesTransfered; // -}; +#include #endif // FTP_SERVER_H diff --git a/FtpServerKey.h b/FtpServerKey.h index 567e6f4..e197e3d 100644 --- a/FtpServerKey.h +++ b/FtpServerKey.h @@ -17,8 +17,10 @@ #ifndef FTP_SERVER_CONFIG_H #define FTP_SERVER_CONFIG_H +#define FTP_SERVER_VERSION "2022-03-11" + // Uncomment to enable printing out nice debug messages. - #define FTP_SERVER_DEBUG +// #define FTP_SERVER_DEBUG // Define where debug output will be printed. #define DEBUG_PRINTER Serial @@ -34,15 +36,18 @@ #define STORAGE_FFAT 8 // ESP32 FFAT #define NETWORK_ESP8266_ASYNC (0) -#define NETWORK_ESP8266 (1) -// && (defined(ESP8266) && ARDUINO_ESP8266_MAJOR<3) -#define NETWORK_ESP8266_242 (6) -#define NETWORK_W5100 (2) -#define NETWORK_ENC28J60 (3) -#define NETWORK_ESP32 (4) -#define NETWORK_ESP32_ETH (5) -#define NETWORK_WiFiNINA (7) -#define NETWORK_SEEED_RTL8720DN (8) +#define NETWORK_ESP8266 (1) // Standard ESP8266WiFi +#define NETWORK_ESP8266_242 (6) // ESP8266WiFi before 2.4.2 core +#define NETWORK_W5100 (2) // Standard Arduino Ethernet library +#define NETWORK_ENC28J60 (3) // UIPEthernet library +#define NETWORK_ESP32 (4) // Standard WiFi library +#define NETWORK_ESP32_ETH (5) // Standard ETH library +#define NETWORK_WiFiNINA (7) // Standard WiFiNINA library +#define NETWORK_SEEED_RTL8720DN (8) // Standard SEED WiFi library +//#define NETWORK_ETHERNET_LARGE (9) +#define NETWORK_ETHERNET_ENC (10) // EthernetENC library (evolution of UIPEthernet +//#define NETWORK_ETHERNET_STM (11) +#define NETWORK_UIPETHERNET (12) // UIPEthernet library same of NETWORK_ENC28J60 #ifndef DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP8266 #define DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP8266 NETWORK_ESP8266 diff --git a/FtpServerNoConf.h b/FtpServerNoConf.h new file mode 100644 index 0000000..a271e39 --- /dev/null +++ b/FtpServerNoConf.h @@ -0,0 +1,682 @@ +/* + * FtpServer Arduino, esp8266 and esp32 library for Ftp Server + * Derived form Jean-Michel Gallego version + * + * AUTHOR: Renzo Mischianti + * + * https://www.mischianti.org/2020/02/08/ftp-server-on-esp8266-and-esp32 + * + */ + + +/******************************************************************************* + ** ** + ** DEFINITIONS FOR FTP SERVER ** + ** ** + *******************************************************************************/ + +#ifndef FTP_SERVER_NO_CONF_H +#define FTP_SERVER_NO_CONF_H + +#if ARDUINO >= 100 +#include "Arduino.h" +#else +#include "WProgram.h" +#endif + +// +//#if(NETWORK_ESP8266_SD == DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP8266) +// #define ESP8266_GT_2_4_2_SD_STORAGE_SELECTED +// #define DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP8266 NETWORK_ESP8266 +//#endif + +#if !defined(FTP_SERVER_NETWORK_TYPE) +// select Network type based + #if defined(ESP8266) || defined(ESP31B) + #if(NETWORK_ESP8266_242 == DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP8266) + #define ARDUINO_ESP8266_RELEASE_2_4_2 + + #define FTP_SERVER_NETWORK_TYPE_SELECTED NETWORK_ESP8266_242 + + #define FTP_SERVER_NETWORK_TYPE NETWORK_ESP8266 + #else + #define FTP_SERVER_NETWORK_TYPE DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP8266 + #endif + + #define STORAGE_TYPE DEFAULT_STORAGE_TYPE_ESP8266 + #elif defined(ESP32) + #define FTP_SERVER_NETWORK_TYPE DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP32 + #define STORAGE_TYPE DEFAULT_STORAGE_TYPE_ESP32 + #elif defined(ARDUINO_ARCH_SAMD) + #define FTP_SERVER_NETWORK_TYPE DEFAULT_FTP_SERVER_NETWORK_TYPE_SAMD + #define STORAGE_TYPE DEFAULT_STORAGE_TYPE_SAMD + #else + #define FTP_SERVER_NETWORK_TYPE DEFAULT_FTP_SERVER_NETWORK_TYPE_ARDUINO + #define STORAGE_TYPE DEFAULT_STORAGE_TYPE_ARDUINO + // #define STORAGE_SD_ENABLED + #endif +#endif + +#ifndef FTP_SERVER_NETWORK_TYPE_SELECTED + #define FTP_SERVER_NETWORK_TYPE_SELECTED FTP_SERVER_NETWORK_TYPE +#endif + + +#if defined(ESP8266) || defined(ESP31B) + #ifndef STORAGE_SD_FORCE_DISABLE + #define STORAGE_SD_ENABLED + #endif + #ifndef STORAGE_SPIFFS_FORCE_DISABLE + #define STORAGE_SPIFFS_ENABLED + #endif +#elif defined(ESP32) + #ifndef STORAGE_SD_FORCE_DISABLE + #define STORAGE_SD_ENABLED + #endif + #ifndef STORAGE_SPIFFS_FORCE_DISABLE + #define STORAGE_SPIFFS_ENABLED + #endif +#else + #ifndef STORAGE_SD_FORCE_DISABLE + #define STORAGE_SD_ENABLED + #endif +#endif + + +// Includes and defined based on Network Type +#if(FTP_SERVER_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) + + // Note: + // No SSL/WSS support for client in Async mode + // TLS lib need a sync interface! + + #if defined(ESP8266) + #include + //#include + #define FTP_CLIENT_NETWORK_CLASS WiFiClient + //#define FTP_CLIENT_NETWORK_SSL_CLASS WiFiClientSecure + #define FTP_SERVER_NETWORK_SERVER_CLASS WiFiServer + + #elif defined(ESP32) + #include + //#include + + #define FTP_CLIENT_NETWORK_CLASS WiFiClient + //#define FTP_CLIENT_NETWORK_SSL_CLASS WiFiClientSecure + #define FTP_SERVER_NETWORK_SERVER_CLASS WiFiServer + #elif defined(ESP31B) + #include + + #define FTP_CLIENT_NETWORK_CLASS WiFiClient + //#define FTP_CLIENT_NETWORK_SSL_CLASS WiFiClientSecure + #define FTP_SERVER_NETWORK_SERVER_CLASS WiFiServer + #else + #error "network type ESP8266 ASYNC only possible on the ESP mcu!" + #endif + +#elif(FTP_SERVER_NETWORK_TYPE == NETWORK_ESP8266 || FTP_SERVER_NETWORK_TYPE == NETWORK_ESP8266_242) + + #if !defined(ESP8266) && !defined(ESP31B) + #error "network type ESP8266 only possible on the ESP mcu!" + #endif + + #ifdef ESP8266 + #include + #else + #include + #endif + #define FTP_CLIENT_NETWORK_CLASS WiFiClient + //#define FTP_CLIENT_NETWORK_SSL_CLASS WiFiClientSecure + #define FTP_SERVER_NETWORK_SERVER_CLASS WiFiServer + #define NET_CLASS WiFi +// #define CommandIs( a ) (command != NULL && ! strcmp_P( command, PSTR( a ))) +// #define ParameterIs( a ) ( parameter != NULL && ! strcmp_P( parameter, PSTR( a ))) +#elif(FTP_SERVER_NETWORK_TYPE == NETWORK_W5100 || FTP_SERVER_NETWORK_TYPE == NETWORK_ETHERNET_ENC) + + #include + #include + #define FTP_CLIENT_NETWORK_CLASS EthernetClient + #define FTP_SERVER_NETWORK_SERVER_CLASS EthernetServer + #define NET_CLASS Ethernet + +// #if defined(ESP8266) || defined(ESP32) +// #define CommandIs( a ) (command != NULL && ! strcmp_P( command, PSTR( a ))) +// #define ParameterIs( a ) ( parameter != NULL && ! strcmp_P( parameter, PSTR( a ))) +// #else +// #define CommandIs( a ) ( ! strcmp_PF( command, PSTR( a ))) +// #define ParameterIs( a ) ( ! strcmp_PF( parameter, PSTR( a ))) +// #endif +#elif(FTP_SERVER_NETWORK_TYPE == NETWORK_ENC28J60 || FTP_SERVER_NETWORK_TYPE == NETWORK_UIPETHERNET) + + #include + + #define FTP_CLIENT_NETWORK_CLASS UIPClient + #define FTP_SERVER_NETWORK_SERVER_CLASS UIPServer + #define NET_CLASS Ethernet +// #if define(ESP8266) || define(ESP32) +// #define CommandIs( a ) (command != NULL && ! strcmp_P( command, PSTR( a ))) +// #define ParameterIs( a ) ( parameter != NULL && ! strcmp_P( parameter, PSTR( a ))) +// #else +// #define CommandIs( a ) ( ! strcmp_PF( command, PSTR( a ))) +// #define ParameterIs( a ) ( ! strcmp_PF( parameter, PSTR( a ))) +// #endif +#elif(FTP_SERVER_NETWORK_TYPE == NETWORK_ESP32) + + #include + //#include + #define FTP_CLIENT_NETWORK_CLASS WiFiClient + //#define FTP_CLIENT_NETWORK_SSL_CLASS WiFiClientSecure + #define FTP_SERVER_NETWORK_SERVER_CLASS WiFiServer + #define NET_CLASS WiFi +// #define CommandIs( a ) (command != NULL && ! strcmp_P( command, PSTR( a ))) +// #define ParameterIs( a ) ( parameter != NULL && ! strcmp_P( parameter, PSTR( a ))) +#elif(FTP_SERVER_NETWORK_TYPE == NETWORK_ESP32_ETH) + + #include + #define FTP_CLIENT_NETWORK_CLASS WiFiClient + #define FTP_SERVER_NETWORK_SERVER_CLASS WiFiServer + #define NET_CLASS Ethernet +// #define CommandIs( a ) ( ! strcmp_PF( command, PSTR( a ))) +// #define ParameterIs( a ) ( ! strcmp_PF( parameter, PSTR( a ))) +#elif(FTP_SERVER_NETWORK_TYPE == NETWORK_WiFiNINA) + + #include + #define FTP_CLIENT_NETWORK_CLASS WiFiClient + //#define FTP_CLIENT_NETWORK_SSL_CLASS WiFiSSLClient + #define FTP_SERVER_NETWORK_SERVER_CLASS WiFiServer + #define NET_CLASS WiFi +// #define CommandIs( a ) ( ! strcmp_PF( command, PSTR( a ))) +// #define ParameterIs( a ) ( ! strcmp_PF( parameter, PSTR( a ))) +#elif(FTP_SERVER_NETWORK_TYPE == NETWORK_SEEED_RTL8720DN) + + #include + #define FTP_CLIENT_NETWORK_CLASS WiFiClient + //#define FTP_CLIENT_NETWORK_SSL_CLASS WiFiSSLClient + #define FTP_SERVER_NETWORK_SERVER_CLASS WiFiServer + #define NET_CLASS WiFi +// #define CommandIs( a ) ( ! strcmp_PF( command, PSTR( a ))) +// #define ParameterIs( a ) ( ! strcmp_PF( parameter, PSTR( a ))) +#else + #error "no network type selected!" +#endif + +#if defined(ESP8266) || defined(ESP32) + #define CommandIs( a ) (command != NULL && ! strcmp_P( command, PSTR( a ))) + #define ParameterIs( a ) ( parameter != NULL && ! strcmp_P( parameter, PSTR( a ))) +#else + #define CommandIs( a ) ( ! strcmp_PF( command, PSTR( a ))) + #define ParameterIs( a ) ( ! strcmp_PF( parameter, PSTR( a ))) +#endif + +#if(STORAGE_TYPE == STORAGE_SPIFFS) + #if defined(ESP32) +// #define FS_NO_GLOBALS + #include + + #define FTP_FILE File + #define FTP_DIR File + #else + #ifdef ARDUINO_ESP8266_RELEASE_2_4_2 + #define FS_NO_GLOBALS + #include "FS.h" + #define FTP_FILE fs::File + #define FTP_DIR fs::Dir + #else + #include "FS.h" + #define FTP_FILE File + #define FTP_DIR Dir + #endif + + #endif + + +#if ESP8266 + #define FTP_FILE_READ "r" + #define FTP_FILE_READ_ONLY "r" + #define FTP_FILE_READ_WRITE "w+" + #define FTP_FILE_WRITE_APPEND "a+" + #define FTP_FILE_WRITE_CREATE "w+" +#else + #define FTP_FILE_READ "r" + #define FTP_FILE_READ_ONLY "r" + #define FTP_FILE_READ_WRITE "w" + #define FTP_FILE_WRITE_APPEND "a" + #define FTP_FILE_WRITE_CREATE "w" +#endif + + #define STORAGE_MANAGER SPIFFS +#elif(STORAGE_TYPE == STORAGE_FFAT) + #include "FS.h" + #include "FFat.h" + + #define STORAGE_MANAGER FFat + + #define FTP_FILE File + #define FTP_DIR File + + #define FTP_FILE_READ "r" + #define FTP_FILE_READ_ONLY "r" + #define FTP_FILE_READ_WRITE "w" + #define FTP_FILE_WRITE_APPEND "a" + #define FTP_FILE_WRITE_CREATE "w" + +#elif(STORAGE_TYPE == STORAGE_LITTLEFS) + #if ESP8266 + #include "LittleFS.h" + #define STORAGE_MANAGER LittleFS + #define FTP_FILE File + #define FTP_DIR Dir + + #define FTP_FILE_READ "r" + #define FTP_FILE_READ_ONLY "r" + #define FTP_FILE_READ_WRITE "w+" + #define FTP_FILE_WRITE_APPEND "a+" + #define FTP_FILE_WRITE_CREATE "w+" + #else +#if ESP_ARDUINO_VERSION_MAJOR >= 2 + #include "FS.h" + #include "LittleFS.h" + #define STORAGE_MANAGER LittleFS +#else + #include "LITTLEFS.h" + #define STORAGE_MANAGER LITTLEFS +#endif + #define FTP_FILE File + #define FTP_DIR File + + #define FTP_FILE_READ "r" + #define FTP_FILE_READ_ONLY "r" + #define FTP_FILE_READ_WRITE "w" + #define FTP_FILE_WRITE_APPEND "a" + #define FTP_FILE_WRITE_CREATE "w" + #endif +#elif(STORAGE_TYPE == STORAGE_SD) + #include + #include + + #define STORAGE_MANAGER SD + #define FTP_FILE File + #define FTP_DIR File + + #define FTP_FILE_READ FILE_READ + #define FTP_FILE_READ_ONLY FILE_READ + #define FTP_FILE_READ_WRITE FILE_WRITE +#ifdef ESP32 + #define FTP_FILE_READ_WRITE FILE_WRITE + #define FTP_FILE_WRITE_APPEND FILE_APPEND +#else + #define FTP_FILE_READ_WRITE FILE_WRITE + #define FTP_FILE_WRITE_APPEND FILE_WRITE +#endif + #define FTP_FILE_WRITE_CREATE FILE_WRITE + +#elif(STORAGE_TYPE == STORAGE_SEEED_SD) + #include + #define STORAGE_MANAGER SD + + #include "SD/Seeed_SD.h" + + + +// #define STORAGE_MANAGER SPIFLASH +// #include "SFUD/Seeed_SFUD.h" + + #define FTP_FILE File + #define FTP_DIR File + + #define FTP_FILE_READ FILE_READ + #define FTP_FILE_READ_ONLY FILE_READ + #define FTP_FILE_READ_WRITE FILE_WRITE + #define FTP_FILE_WRITE_APPEND FILE_APPEND + #define FTP_FILE_WRITE_CREATE FILE_WRITE + +#elif (STORAGE_TYPE == STORAGE_SDFAT1) + #include + #include + + #define STORAGE_MANAGER sd + #define FTP_FILE SdFile + #define FTP_DIR SdFile + extern SdFat STORAGE_MANAGER; + + #define FTP_FILE_READ O_READ + #define FTP_FILE_READ_ONLY O_RDONLY + #define FTP_FILE_READ_WRITE O_RDWR + #define FTP_FILE_WRITE_APPEND O_WRITE | O_APPEND + #define FTP_FILE_WRITE_CREATE O_WRITE | O_CREAT +#elif (STORAGE_TYPE == STORAGE_SDFAT2) + #include + #include + + #define STORAGE_MANAGER sd + #define FTP_FILE FsFile + #define FTP_DIR FsFile + extern SdFat STORAGE_MANAGER; + + #define FTP_FILE_READ O_READ + #define FTP_FILE_READ_ONLY O_RDONLY + #define FTP_FILE_READ_WRITE O_RDWR + #define FTP_FILE_WRITE_APPEND O_WRITE | O_APPEND + #define FTP_FILE_WRITE_CREATE O_WRITE | O_CREAT +#elif (STORAGE_TYPE == STORAGE_SPIFM) + #include + #include + #include + + #define STORAGE_MANAGER fatfs + #define FTP_FILE File + #define FTP_DIR File + extern FatFileSystem STORAGE_MANAGER; + extern Adafruit_SPIFlash flash; + #define FTP_FILE_READ FILE_READ + #define FTP_FILE_READ_ONLY FILE_READ + #define FTP_FILE_READ_WRITE FILE_WRITE + #define FTP_FILE_WRITE_APPEND FILE_WRITE + #define FTP_FILE_WRITE_CREATE FILE_WRITE + +#elif (STORAGE_TYPE == STORAGE_FATFS) + #include + #include + + #define STORAGE_MANAGER sdff + #define FTP_FILE FileFs + #define FTP_DIR DirFs + extern FatFsClass STORAGE_MANAGER; + #define O_READ FA_READ + #define O_WRITE FA_WRITE + #define O_RDWR FA_READ | FA_WRITE + #define O_CREAT FA_CREATE_ALWAYS + #define O_APPEND FA_OPEN_APPEND + + #define FTP_FILE_READ O_READ + #define FTP_FILE_READ_ONLY O_RDONLY + #define FTP_FILE_READ_WRITE O_RDWR + #define FTP_FILE_WRITE_APPEND O_WRITE | O_APPEND + #define FTP_FILE_WRITE_CREATE O_WRITE | O_CREAT +#endif + +//#ifdef FTP_CLIENT_NETWORK_SSL_CLASS +//#define FTP_CLIENT_NETWORK_CLASS FTP_CLIENT_NETWORK_SSL_CLASS +//#endif + +#define OPEN_CLOSE_SPIFFS +#define OPEN_CLOSE_SD + +// Setup debug printing macros. +#ifdef FTP_SERVER_DEBUG + #define DEBUG_PRINT(...) { DEBUG_PRINTER.print(__VA_ARGS__); } + #define DEBUG_PRINTLN(...) { DEBUG_PRINTER.println(__VA_ARGS__); } +#else + #define DEBUG_PRINT(...) {} + #define DEBUG_PRINTLN(...) {} +#endif + +#define FTP_CMD_PORT 21 // Command port on wich server is listening +#define FTP_DATA_PORT_DFLT 20 // Default data port in active mode +#define FTP_DATA_PORT_PASV 50009 // Data port in passive mode + +#define FF_MAX_LFN 255 // max size of a long file name +#define FTP_CMD_SIZE FF_MAX_LFN+8 // max size of a command +#define FTP_CWD_SIZE FF_MAX_LFN+8 // max size of a directory name +#define FTP_FIL_SIZE FF_MAX_LFN // max size of a file name +#define FTP_CRED_SIZE 16 // max size of username and password +#define FTP_NULLIP() IPAddress(0,0,0,0) + +enum ftpCmd { FTP_Stop = 0, // In this stage, stop any connection + FTP_Init, // initialize some variables + FTP_Client, // wait for client connection + FTP_User, // wait for user name + FTP_Pass, // wait for user password + FTP_Cmd }; // answers to commands + +enum ftpTransfer { FTP_Close = 0, // In this stage, close data channel + FTP_Retrieve, // retrieve file + FTP_Store, // store file + FTP_List, // list of files + FTP_Nlst, // list of name of files + FTP_Mlsd }; // listing for machine processing + +enum ftpDataConn { FTP_NoConn = 0,// No data connexion + FTP_Pasive, // Pasive type + FTP_Active }; // Active type + +enum FtpOperation { + FTP_CONNECT, + FTP_DISCONNECT, + FTP_FREE_SPACE_CHANGE +}; + +enum FtpTransferOperation { + FTP_UPLOAD_START = 0, + FTP_UPLOAD = 1, + + FTP_DOWNLOAD_START = 2, + FTP_DOWNLOAD = 3, + + + FTP_TRANSFER_STOP = 4, + FTP_DOWNLOAD_STOP = 4, + FTP_UPLOAD_STOP = 4, + + FTP_TRANSFER_ERROR = 5, + FTP_DOWNLOAD_ERROR = 5, + FTP_UPLOAD_ERROR = 5 +}; + +class FtpServer +{ +public: + FtpServer( uint16_t _cmdPort = FTP_CMD_PORT, uint16_t _pasvPort = FTP_DATA_PORT_PASV ); + + void begin( const char * _user, const char * _pass, const char * welcomeMessage = "Welcome to Simply FTP server" ); + void begin( const char * welcomeMessage = "Welcome to Simply FTP server" ); + + void end(); + void setLocalIp(IPAddress localIp); + void credentials( const char * _user, const char * _pass ); + uint8_t handleFTP(); + + void setCallback(void (*_callbackParam)(FtpOperation ftpOperation, unsigned int freeSpace, unsigned int totalSpace) ) + { + _callback = _callbackParam; + } + + void setTransferCallback(void (*_transferCallbackParam)(FtpTransferOperation ftpOperation, const char* name, unsigned int transferredSize) ) + { + _transferCallback = _transferCallbackParam; + } + +private: + void (*_callback)(FtpOperation ftpOperation, unsigned int freeSpace, unsigned int totalSpace){}; + void (*_transferCallback)(FtpTransferOperation ftpOperation, const char* name, unsigned int transferredSize){}; + + void iniVariables(); + void clientConnected(); + void disconnectClient(); + bool processCommand(); + bool haveParameter(); + int dataConnect( bool out150 = true ); + bool dataConnected(); + bool doRetrieve(); + bool doStore(); + bool doList(); + bool doMlsd(); + void closeTransfer(); + void abortTransfer(); + bool makePath( char * fullName, char * param = NULL ); + bool makeExistsPath( char * path, char * param = NULL ); + bool openDir( FTP_DIR * pdir ); + bool isDir( char * path ); + uint8_t getDateTime( char * dt, uint16_t * pyear, uint8_t * pmonth, uint8_t * pday, + uint8_t * phour, uint8_t * pminute, uint8_t * second ); + char * makeDateTimeStr( char * tstr, uint16_t date, uint16_t time ); + bool timeStamp( char * path, uint16_t year, uint8_t month, uint8_t day, + uint8_t hour, uint8_t minute, uint8_t second ); + bool getFileModTime( char * path, uint16_t * pdate, uint16_t * ptime ); +#if STORAGE_TYPE != STORAGE_FATFS + bool getFileModTime( uint16_t * pdate, uint16_t * ptime ); +#endif + int8_t readChar(); + + const char* getFileName(FTP_FILE *file){ + #if STORAGE_TYPE <= STORAGE_SDFAT2 + int max_characters = 100; + char f_name[max_characters]; + file->getName(f_name, max_characters); + String filename = String(f_name); + return filename.c_str(); + #elif STORAGE_TYPE == STORAGE_FATFS + return file->fileName(); + #else + return file->name(); + #endif + } + bool exists( const char * path ) { +#if STORAGE_TYPE == STORAGE_SPIFFS || (STORAGE_TYPE == STORAGE_SD && FTP_SERVER_NETWORK_TYPE == NETWORK_ESP8266_242) + if (strcmp(path, "/") == 0) return true; +#endif +#if STORAGE_TYPE == STORAGE_FFAT || (STORAGE_TYPE == STORAGE_LITTLEFS && defined(ESP32)) + FTP_DIR f = STORAGE_MANAGER.open(path, "r"); + return (f == true); +#else + return STORAGE_MANAGER.exists( path ); +#endif + }; + bool remove( const char * path ) { return STORAGE_MANAGER.remove( path ); }; +#if STORAGE_TYPE == STORAGE_SPIFFS + bool makeDir( const char * path ) { return false; }; + bool removeDir( const char * path ) { return false; }; +#else + bool makeDir( const char * path ) { return STORAGE_MANAGER.mkdir( path ); }; + bool removeDir( const char * path ) { return STORAGE_MANAGER.rmdir( path ); }; +#endif + +#if STORAGE_TYPE == STORAGE_SD + bool rename( const char * path, const char * newpath ); +#else + bool rename( const char * path, const char * newpath ) { return STORAGE_MANAGER.rename( path, newpath ); }; +#endif +#if (STORAGE_TYPE == STORAGE_SEEED_SD) + bool openFile( char path[ FTP_CWD_SIZE ], int readTypeInt ); +#elif (STORAGE_TYPE == STORAGE_SD && defined(ESP8266))// FTP_SERVER_NETWORK_TYPE_SELECTED == NETWORK_ESP8266_242) + bool openFile( char path[ FTP_CWD_SIZE ], int readTypeInt ); +#elif (STORAGE_TYPE == STORAGE_SPIFFS || STORAGE_TYPE == STORAGE_LITTLEFS || STORAGE_TYPE == STORAGE_FFAT ) + bool openFile( const char * path, const char * readType ); +// bool openFile( char path[ FTP_CWD_SIZE ], int readTypeInt ); +#elif STORAGE_TYPE <= STORAGE_SDFAT2 || STORAGE_TYPE == STORAGE_SPIFM + bool openFile( char path[ FTP_CWD_SIZE ], int readTypeInt ); +#else + bool openFile( char path[ FTP_CWD_SIZE ], const char * readType ); + bool openFile( const char * path, const char * readType ); +// bool openFile( char path[ FTP_CWD_SIZE ], int readTypeInt ); +#endif +// bool openFile( char path[ FTP_CWD_SIZE ], const char * readType ); +// bool openFile( const char * path, const char * readType ); + uint16_t fileSize( FTP_FILE file ); + +#if STORAGE_TYPE == STORAGE_SPIFFS || STORAGE_TYPE == STORAGE_LITTLEFS +#if ESP8266 + uint32_t capacity() { + FSInfo fi; + STORAGE_MANAGER.info(fi); + + return fi.totalBytes >> 1; + }; + uint32_t free() { + FSInfo fi; + STORAGE_MANAGER.info(fi); + + return (fi.totalBytes - fi.usedBytes) >> 1; + }; +#else + uint32_t capacity() { + return STORAGE_MANAGER.totalBytes() >> 1; + }; + uint32_t free() { + return (STORAGE_MANAGER.totalBytes() - + STORAGE_MANAGER.usedBytes()) >> 1; + }; +#endif +#elif STORAGE_TYPE == STORAGE_SD + uint32_t capacity() { return true; }; + uint32_t free() { return true; }; +#elif STORAGE_TYPE == STORAGE_SEEED_SD + uint32_t capacity() { + return STORAGE_MANAGER.totalBytes() >> 1; + }; + uint32_t free() { + return (STORAGE_MANAGER.totalBytes() - + STORAGE_MANAGER.usedBytes()) >> 1; + }; +#elif STORAGE_TYPE == STORAGE_SDFAT1 + uint32_t capacity() { return STORAGE_MANAGER.card()->cardSize() >> 1; }; + uint32_t free() { return STORAGE_MANAGER.vol()->freeClusterCount() * + STORAGE_MANAGER.vol()->sectorsPerCluster() >> 1; }; +#elif STORAGE_TYPE == STORAGE_SDFAT2 + uint32_t capacity() { return STORAGE_MANAGER.card()->sectorCount() >> 1; }; + uint32_t free() { return STORAGE_MANAGER.vol()->freeClusterCount() * + STORAGE_MANAGER.vol()->sectorsPerCluster() >> 1; }; +#elif STORAGE_TYPE == STORAGE_SPIFM + uint32_t capacity() { return flash.size() >> 10; }; + uint32_t free() { return 0; }; // TODO // +#elif STORAGE_TYPE == STORAGE_FATFS + uint32_t capacity() { return STORAGE_MANAGER.capacity(); }; + uint32_t free() { return STORAGE_MANAGER.free(); }; +#elif STORAGE_TYPE == STORAGE_FFAT + uint32_t capacity() { return STORAGE_MANAGER.totalBytes(); }; + uint32_t free() { return STORAGE_MANAGER.freeBytes(); }; +#endif + bool legalChar( char c ) // Return true if char c is allowed in a long file name + { + if( c == '"' || c == '*' || c == '?' || c == ':' || + c == '<' || c == '>' || c == '|' ) + return false; +#if STORAGE_TYPE == STORAGE_FATFS + return 0x1f < c && c < 0xff; +#else + return 0x1f < c && c < 0x7f; +#endif + } + + IPAddress localIp; // IP address of server as seen by clients + IPAddress dataIp; // IP address of client for data + FTP_SERVER_NETWORK_SERVER_CLASS ftpServer; + FTP_SERVER_NETWORK_SERVER_CLASS dataServer; + + + FTP_CLIENT_NETWORK_CLASS client; + FTP_CLIENT_NETWORK_CLASS data; + + FTP_FILE file; + FTP_DIR dir; + + ftpCmd cmdStage; // stage of ftp command connexion + ftpTransfer transferStage; // stage of data connexion + ftpDataConn dataConn; // type of data connexion + + bool anonymousConnection = false; + + uint8_t __attribute__((aligned(4))) // need to be aligned to 32bit for Esp8266 SPIClass::transferBytes() + buf[ FTP_BUF_SIZE ]; // data buffer for transfers + char cmdLine[ FTP_CMD_SIZE ]; // where to store incoming char from client + char cwdName[ FTP_CWD_SIZE ]; // name of current directory + char rnfrName[ FTP_CWD_SIZE ]; // name of file for RNFR command + const char * user; // user name + const char * pass; // password + char command[ 5 ]; // command sent by client + bool rnfrCmd; // previous command was RNFR + char * parameter; // point to begin of parameters sent by client + const char * welcomeMessage; + uint16_t cmdPort, + pasvPort, + dataPort; + uint16_t iCL; // pointer to cmdLine next incoming char + uint16_t nbMatch; + + uint32_t millisDelay, // + millisEndConnection, // + millisBeginTrans, // store time of beginning of a transaction + bytesTransfered; // +}; + +#endif // FTP_SERVER_NO_CONF_H diff --git a/README.md b/README.md index e0fffe5..9027e10 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ - Wio Terminal (SdFat 2, and native FAT) #### Changelog +- 2022-03-17 1.3.0 Fix enc28j60 and w5500 support and restructuring for local settings - 2022-02-25 1.2.1 Fix anonymous user begin and fix SPIFFS wrong display - 2022-02-22 1.2.0 Add anonymous user and implement correct RFC (#9 now work correctly with File Explorer) - 2022-02-01 1.1.1 Add workaround to start FTP server before connection, add end and setLocalIP method. diff --git a/examples/FTPServer_ESP32_FFAT_enc28j60/FTPServer_ESP32_FFAT_enc28j60.ino b/examples/FTPServer_ESP32_FFAT_enc28j60/FTPServer_ESP32_FFAT_enc28j60.ino new file mode 100644 index 0000000..78b6bb1 --- /dev/null +++ b/examples/FTPServer_ESP32_FFAT_enc28j60/FTPServer_ESP32_FFAT_enc28j60.ino @@ -0,0 +1,130 @@ +/* + * FtpServer esp32 with FFat and EthernetENC (or UIPEthernet) + * + * AUTHOR: Renzo Mischianti + * + * https://www.mischianti.org/2020/02/08/ftp-server-on-esp8266-and-esp32 + * + */ + +#include "Arduino.h" +#include +#include + +#include "FS.h" +#include "FFat.h" + +#include + +#define MACADDRESS 0x00,0x01,0x02,0x03,0x04,0x05 +#define MYIPADDR 192,168,1,28 +#define MYIPMASK 255,255,255,0 +#define MYDNS 192,168,1,1 +#define MYGW 192,168,1,1 + +uint8_t macaddress[6] = {MACADDRESS}; + +FtpServer ftpSrv; //set #define FTP_DEBUG in ESP8266FtpServer.h to see ftp verbose on serial + +void _callback(FtpOperation ftpOperation, unsigned int freeSpace, unsigned int totalSpace){ + Serial.print(">>>>>>>>>>>>>>> _callback " ); + Serial.print(ftpOperation); + /* FTP_CONNECT, + * FTP_DISCONNECT, + * FTP_FREE_SPACE_CHANGE + */ + Serial.print(" "); + Serial.print(freeSpace); + Serial.print(" "); + Serial.println(totalSpace); + + // freeSpace : totalSpace = x : 360 + + if (ftpOperation == FTP_CONNECT) Serial.println(F("CONNECTED")); + if (ftpOperation == FTP_DISCONNECT) Serial.println(F("DISCONNECTED")); +}; +void _transferCallback(FtpTransferOperation ftpOperation, const char* name, unsigned int transferredSize){ + Serial.print(">>>>>>>>>>>>>>> _transferCallback " ); + Serial.print(ftpOperation); + /* FTP_UPLOAD_START = 0, + * FTP_UPLOAD = 1, + * + * FTP_DOWNLOAD_START = 2, + * FTP_DOWNLOAD = 3, + * + * FTP_TRANSFER_STOP = 4, + * FTP_DOWNLOAD_STOP = 4, + * FTP_UPLOAD_STOP = 4, + * + * FTP_TRANSFER_ERROR = 5, + * FTP_DOWNLOAD_ERROR = 5, + * FTP_UPLOAD_ERROR = 5 + */ + Serial.print(" "); + Serial.print(name); + Serial.print(" "); + Serial.println(transferredSize); +}; + + +void setup(void){ + Serial.begin(115200); + + Serial.println("Begin Ethernet"); + + Ethernet.init(5); + if (Ethernet.begin(macaddress)) { // Dynamic IP setup + Serial.println("DHCP OK!"); + }else{ + Serial.println("Failed to configure Ethernet using DHCP"); + // Check for Ethernet hardware present + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :("); + while (true) { + delay(1); // do nothing, no point running without Ethernet hardware + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println("Ethernet cable is not connected."); + } + + IPAddress ip(MYIPADDR); + IPAddress dns(MYDNS); + IPAddress gw(MYGW); + IPAddress sn(MYIPMASK); + Ethernet.begin(macaddress, ip, dns, gw, sn); + Serial.println("STATIC OK!"); + } + delay(5000); + + + Serial.print("Local IP : "); + Serial.println(Ethernet.localIP()); + Serial.print("Subnet Mask : "); + Serial.println(Ethernet.subnetMask()); + Serial.print("Gateway IP : "); + Serial.println(Ethernet.gatewayIP()); + Serial.print("DNS Server : "); + Serial.println(Ethernet.dnsServerIP()); + + Serial.println("Ethernet Successfully Initialized"); + + /////FTP Setup, ensure FFat is started before ftp; ///////// + if (FFat.begin(true)) { + Serial.println("FFat opened!"); + + ftpSrv.setCallback(_callback); + ftpSrv.setTransferCallback(_transferCallback); + + ftpSrv.begin("user","password"); //username, password for ftp. set ports in ESP8266FtpServer.h (default 21, 50009 for PASV) + Serial.println("FTP server started!"); + } else { + Serial.println("FFat opened FAIL!!!!!"); + } + +} +void loop(void){ + ftpSrv.handleFTP(); //make sure in loop you call handleFTP()!! + // server.handleClient(); //example if running a webserver you still need to call .handleClient(); + +} diff --git a/library.properties b/library.properties index 2018c72..e5356dc 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=SimpleFTPServer -version=1.2.1 +version=1.3.0 author=Renzo Mischianti maintainer=Renzo Mischianti sentence=Simple FTP server for esp8266, esp32 and Arduino