summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--FTPClient.cpp15
-rw-r--r--FTPClient.h2
-rw-r--r--FTPCommon.cpp7
-rw-r--r--FTPCommon.h15
-rw-r--r--FTPServer.cpp46
-rw-r--r--FTPServer.h8
-rw-r--r--library.properties2
7 files changed, 44 insertions, 51 deletions
diff --git a/FTPClient.cpp b/FTPClient.cpp
index e32af21..84c4fdb 100644
--- a/FTPClient.cpp
+++ b/FTPClient.cpp
@@ -10,6 +10,8 @@
FTPClient::FTPClient(FS &_FSImplementation) : FTPCommon(_FSImplementation)
{
+ // set aTimeout to never expire, will be used later by ::waitFor(...)
+ aTimeout.resetToNeverExpires();
}
void FTPClient::begin(const ServerInfo &theServer)
@@ -216,20 +218,20 @@ int8_t FTPClient::controlConnect()
return -1;
}
-bool FTPClient::waitFor(const uint16_t respCode, const __FlashStringHelper *errorString, uint16_t timeOut)
+bool FTPClient::waitFor(const int16_t respCode, const __FlashStringHelper *errorString, uint16_t timeOutMs)
{
// initalize waiting
- if (0 == waitUntil)
+ if (!aTimeout.canExpire())
{
- waitUntil = millis();
- waitUntil += timeOut;
+ aTimeout.reset(timeOutMs);
_serverStatus.desc.clear();
}
else
{
// timeout
- if ((int32_t)(millis() - waitUntil) >= 0)
+ if (aTimeout.expired())
{
+ aTimeout.resetToNeverExpires();
FTP_DEBUG_MSG("Waiting for code %u - timeout!", respCode);
_serverStatus.code = errorTimeout;
if (errorString)
@@ -241,7 +243,6 @@ bool FTPClient::waitFor(const uint16_t respCode, const __FlashStringHelper *erro
_serverStatus.desc = F("timeout");
}
ftpState = cTimeout;
- waitUntil = 0;
return false;
}
@@ -269,7 +270,7 @@ bool FTPClient::waitFor(const uint16_t respCode, const __FlashStringHelper *erro
FTP_DEBUG_MSG("Waiting for code %u success, SMTP server replies: %s", respCode, _serverStatus.desc.c_str());
}
- waitUntil = 0;
+ aTimeout.resetToNeverExpires();
return (respCode == _serverStatus.code);
}
else
diff --git a/FTPClient.h b/FTPClient.h
index 1d3d6b4..9f3fd06 100644
--- a/FTPClient.h
+++ b/FTPClient.h
@@ -108,7 +108,7 @@ protected:
int8_t controlConnect(); // connects to ServerInfo, returns -1: no connection possible, +1: connection established
- bool waitFor(const uint16_t respCode, const __FlashStringHelper *errorString = nullptr, uint16_t timeOut = 10000);
+ bool waitFor(const int16_t respCode, const __FlashStringHelper *errorString = nullptr, uint16_t timeOut = 10000);
};
// basically just the same as FTPClient but has a different connect() method to account for SSL/TLS
diff --git a/FTPCommon.cpp b/FTPCommon.cpp
index 66211a8..4b8af4c 100644
--- a/FTPCommon.cpp
+++ b/FTPCommon.cpp
@@ -1,6 +1,7 @@
#include "FTPCommon.h"
-FTPCommon::FTPCommon(FS &_FSImplementation) : THEFS(_FSImplementation)
+FTPCommon::FTPCommon(FS &_FSImplementation) :
+ THEFS(_FSImplementation), sTimeOutMs(FTP_TIME_OUT*60*1000), aTimeout(FTP_TIME_OUT*60*1000)
{
}
@@ -17,9 +18,9 @@ void FTPCommon::stop()
freeBuffer();
}
-void FTPCommon::setTimeout(uint16_t timeout)
+void FTPCommon::setTimeout(uint32_t timeoutMs)
{
- sTimeOut = timeout;
+ sTimeOutMs = timeoutMs;
}
uint16_t FTPCommon::allocateBuffer(uint16_t desiredBytes)
diff --git a/FTPCommon.h b/FTPCommon.h
index 55844f7..9b3fb29 100644
--- a/FTPCommon.h
+++ b/FTPCommon.h
@@ -5,8 +5,9 @@
#include <FS.h>
#include <WiFiClient.h>
#include <WString.h>
+#include <PolledTimeout.h>
-#define FTP_CTRL_PORT 21 // Command port on wich server is listening
+#define FTP_CTRL_PORT 21 // Command port on which server is listening
#define FTP_DATA_PORT_PASV 50009 // Data port in passive mode
#define FTP_TIME_OUT 5 // Disconnect client after 5 minutes of inactivity
#define FTP_CMD_SIZE 127 // allow max. 127 chars in a received command
@@ -81,6 +82,8 @@
#define FTP_CMD_LE_SYST 0x54535953 // "SYST" as uint32_t (little endian)
#define FTP_CMD_BE_SYST 0x53595354 // "SYST" as uint32_t (big endian)
+using esp8266::polledTimeout::oneShotMs; // import the type to the local namespace
+
class FTPCommon
{
public:
@@ -89,11 +92,11 @@ public:
FTPCommon(FS &_FSImplementation);
virtual ~FTPCommon();
- // stops the FTP Server or Client
+ // stops the FTP Server or Client, i.e. stops control and data connections
virtual void stop();
- // set a timeout in seconds
- void setTimeout(uint16_t timeout = FTP_TIME_OUT * 60);
+ // set disconnect timeout in millisecords
+ void setTimeout(uint32_t timeoutMs = FTP_TIME_OUT * 60 * 1000);
// needs to be called frequently (e.g. in loop() )
// to process ftp requests
@@ -112,8 +115,8 @@ protected:
virtual int8_t dataConnect(); // connects to dataIP:dataPort, returns -1: no data connection possible, +1: data connection established
bool parseDataIpPort(const char *p);
- uint16_t sTimeOut = // disconnect after 5 min of inactivity
- FTP_TIME_OUT * 60;
+ uint32_t sTimeOutMs; // disconnect timeout
+ oneShotMs aTimeout; // timeout from esp8266 core library
bool doFiletoNetwork();
bool doNetworkToFile();
diff --git a/FTPServer.cpp b/FTPServer.cpp
index 4a03712..e153649 100644
--- a/FTPServer.cpp
+++ b/FTPServer.cpp
@@ -56,7 +56,10 @@ static const char aSpace[] PROGMEM = " ";
static const char aSlash[] PROGMEM = "/";
// constructor
-FTPServer::FTPServer(FS &_FSImplementation) : FTPCommon(_FSImplementation) {}
+FTPServer::FTPServer(FS &_FSImplementation) : FTPCommon(_FSImplementation)
+{
+ aTimeout.resetToNeverExpires();
+}
void FTPServer::begin(const String &uname, const String &pword)
{
@@ -151,7 +154,7 @@ void FTPServer::handleFTP()
control = controlServer.available();
// wait 10s for login command
- updateTimeout(10);
+ aTimeout.reset(10 * 1000);
cmdState = cCheck;
}
}
@@ -185,7 +188,7 @@ void FTPServer::handleFTP()
else if (cmdState == cLoginOk) // tell client "Login ok!"
{
FTP_SEND_MSG(230, "Login successful.");
- updateTimeout(sTimeOut);
+ aTimeout.reset(sTimeOutMs);
cmdState = cProcess;
}
@@ -194,12 +197,13 @@ void FTPServer::handleFTP()
//
else if (readChar() > 0)
{
- // enforce USER than PASS commands before anything else
- if (((cmdState == cUserId) && (FTP_CMD(USER) != command)) ||
- ((cmdState == cPassword) && (FTP_CMD(PASS) != command)))
+ // enforce USER than PASS commands before anything else except the FEAT command
+ // that should be supported to indicate server features even before login
+ if ((FTP_CMD(FEAT) != command) && (((cmdState == cUserId) && (FTP_CMD(USER) != command)) ||
+ ((cmdState == cPassword) && (FTP_CMD(PASS) != command))))
{
FTP_SEND_MSG(530, "Please login with USER and PASS.");
- FTP_DEBUG_MSG("ignoring before login: cwd=%s cmd[%x]=%s, params='%s'", cwd.c_str(), command, cmdString.c_str(), parameters.c_str());
+ FTP_DEBUG_MSG("ignoring before login: command %s [%x], params='%s'", cmdString.c_str(), command, parameters.c_str());
command = 0;
return;
}
@@ -225,7 +229,7 @@ void FTPServer::handleFTP()
if (_FTP_PASS.length())
{
// wait 10s for PASS command
- updateTimeout(10);
+ aTimeout.reset(10 * 1000);
FTP_SEND_MSG(331, "Please specify the password.");
cmdState = cPassword;
}
@@ -240,7 +244,7 @@ void FTPServer::handleFTP()
}
else
{
- updateTimeout(sTimeOut);
+ aTimeout.reset(sTimeOutMs);
}
}
}
@@ -259,7 +263,7 @@ void FTPServer::handleFTP()
}
// check for timeout
- if (!((int32_t)(millisEndConnection - millis()) > 0))
+ if (aTimeout.expired())
{
FTP_SEND_MSG(530, "Timeout.");
FTP_DEBUG_MSG("client connection timed out");
@@ -308,7 +312,7 @@ int8_t FTPServer::processCommand()
// make the full path of parameters (even if this makes no sense for all commands)
String path = getFileName(parameters, true);
- FTP_DEBUG_MSG("processing: cmd=%s[%x], params='%s' (cwd='%s')", cmdString.c_str(), command, parameters.c_str());
+ FTP_DEBUG_MSG("processing: command %s [%x], params='%s' (cwd='%s')", cmdString.c_str(), command, parameters.c_str(), cwd.c_str());
///////////////////////////////////////
// //
@@ -472,7 +476,7 @@ int8_t FTPServer::processCommand()
else
{
FTP_SEND_MSG(501, "Can't interpret parameters");
- }
+ }
}
//
@@ -596,10 +600,6 @@ int8_t FTPServer::processCommand()
{
data.println(fn);
}
- else
- {
- FTP_DEBUG_MSG("Implemetation of %s [%x] command - internal BUG", cmdString.c_str(), command);
- }
}
if (FTP_CMD(MLSD) == command)
@@ -910,6 +910,8 @@ int8_t FTPServer::processCommand()
else if (FTP_CMD(FEAT) == command)
{
FTP_SEND_DASHMSG(211, "Features:\r\n MLSD\r\n MDTM\r\n SIZE\r\n211 End.");
+ command = 0; // clear command code and
+ rc = 0; // return 0 to prevent progression of state machine in case FEAT was a command before login
}
//
@@ -967,7 +969,7 @@ int8_t FTPServer::processCommand()
//
else
{
- FTP_DEBUG_MSG("Unknown command: %s [%#x], param: '%s')", cmdString.c_str(), command, parameters.c_str());
+ FTP_DEBUG_MSG("Unknown command: %s, params: '%s')", cmdString.c_str(), parameters.c_str());
FTP_SEND_MSG(500, "unknown command \"%s\"", cmdString.c_str());
}
@@ -1006,7 +1008,6 @@ int8_t FTPServer::dataConnect()
return rc;
}
-
void FTPServer::closeTransfer()
{
uint32_t deltaT = (int32_t)(millis() - millisBeginTrans);
@@ -1085,7 +1086,7 @@ int8_t FTPServer::readChar()
// clear cmdline
cmdLine.clear();
- FTP_DEBUG_MSG("readChar() success, command=%x, cmdString='%s', params='%s'", command, cmdString.c_str(), parameters.c_str());
+ // FTP_DEBUG_MSG("readChar() success, cmdString='%s' [%x], params='%s'", cmdString.c_str(), command, parameters.c_str());
return 1;
}
else
@@ -1196,10 +1197,3 @@ String FTPServer::makeDateTimeStr(time_t ft)
strftime((char *)tmp.c_str(), 17, "%Y%m%d%H%M%S", _tm);
return tmp;
}
-
-void FTPServer::updateTimeout(uint16_t s)
-{
- millisEndConnection = s;
- millisEndConnection *= 60000UL;
- millisEndConnection += millis();
-}
diff --git a/FTPServer.h b/FTPServer.h
index f5f1448..84e20a7 100644
--- a/FTPServer.h
+++ b/FTPServer.h
@@ -30,7 +30,7 @@
** **
*******************************************************************************/
#include "FTPCommon.h"
-#define FTP_SERVER_VERSION "0.9.6-20200526"
+#define FTP_SERVER_VERSION "0.9.7-20200529"
class FTPServer : public FTPCommon
{
@@ -46,9 +46,6 @@ public:
// stops the FTP server
void stop();
- // set the FTP server's timeout in seconds
- void setTimeout(uint16_t timeout = FTP_TIME_OUT * 60);
-
// needs to be called frequently (e.g. in loop() )
// to process ftp requests
void handleFTP();
@@ -81,7 +78,6 @@ private:
String getFileName(const String &param, bool fullFilePath = false);
String makeDateTimeStr(time_t fileTime);
int8_t readChar();
- void updateTimeout(uint16_t timeout);
// server specific
bool dataPassiveConn = true; // PASV (passive) mode is our default
@@ -96,8 +92,6 @@ private:
internalState cmdState, // state of ftp control connection
transferState; // state of ftp data connection
-
- uint32_t millisEndConnection;
};
#endif // FTP_SERVER_H
diff --git a/library.properties b/library.properties
index cfaf8cf..0bf7adb 100644
--- a/library.properties
+++ b/library.properties
@@ -1,5 +1,5 @@
name=FtpClientServer
-version=0.9.6
+version=0.9.7
author=Daniel Plasa
maintainer=dplasa@gmail.com
sentence=Simple FTP server for SPIFFS and LittleFS on esp8266/esp32