diff --git a/Sming/SmingCore/Network/Ftp/FtpDataFileList.h b/Sming/SmingCore/Network/Ftp/FtpDataFileList.h new file mode 100644 index 0000000000..0c2c46644d --- /dev/null +++ b/Sming/SmingCore/Network/Ftp/FtpDataFileList.h @@ -0,0 +1,39 @@ +/**** + * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development. + * Created 2015 by Skurydin Alexey + * http://github.com/anakod/Sming + * All files of the Sming Core are provided under the LGPL v3 license. + * + * FtpDataFileList.h + * + ****/ + +#ifndef _SMING_CORE_NETWORK_FTP_FTP_DATA_FILE_LIST_H_ +#define _SMING_CORE_NETWORK_FTP_FTP_DATA_FILE_LIST_H_ + +#include "FtpDataStream.h" +#include "FileSystem.h" + +class FtpDataFileList : public FtpDataStream +{ +public: + explicit FtpDataFileList(FtpServerConnection* connection) : FtpDataStream(connection) + { + } + + void transferData(TcpConnectionEvent sourceEvent) override + { + if(completed) { + return; + } + Vector list = fileList(); + debug_d("send file list: %d", list.count()); + for(unsigned i = 0; i < list.count(); i++) { + writeString("01-01-15 01:00AM " + String(fileGetSize(list[i])) + " " + list[i] + "\r\n"); + } + completed = true; + finishTransfer(); + } +}; + +#endif /* _SMING_CORE_NETWORK_FTP_FTP_DATA_FILE_LIST_H_ */ diff --git a/Sming/SmingCore/Network/Ftp/FtpDataRetrieve.h b/Sming/SmingCore/Network/Ftp/FtpDataRetrieve.h new file mode 100644 index 0000000000..f1ebe0bdf2 --- /dev/null +++ b/Sming/SmingCore/Network/Ftp/FtpDataRetrieve.h @@ -0,0 +1,48 @@ +/**** + * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development. + * Created 2015 by Skurydin Alexey + * http://github.com/anakod/Sming + * All files of the Sming Core are provided under the LGPL v3 license. + * + * FtpDataRetrieve.h + * + ****/ + +#ifndef _SMING_CORE_NETWORK_FTP_FTP_DATA_RETRIEVE_H_ +#define _SMING_CORE_NETWORK_FTP_FTP_DATA_RETRIEVE_H_ + +#include "FtpDataStream.h" +#include "FileSystem.h" + +class FtpDataRetrieve : public FtpDataStream +{ +public: + FtpDataRetrieve(FtpServerConnection* connection, const String& fileName) + : FtpDataStream(connection), file(fileOpen(fileName, eFO_ReadOnly)) + { + } + + ~FtpDataRetrieve() + { + fileClose(file); + } + + void transferData(TcpConnectionEvent sourceEvent) override + { + if(completed) { + return; + } + char buf[1024]; + int len = fileRead(file, buf, sizeof(buf)); + write(buf, len, TCP_WRITE_FLAG_COPY); + if(fileIsEOF(file)) { + completed = true; + finishTransfer(); + } + } + +private: + file_t file; +}; + +#endif /* _SMING_CORE_NETWORK_FTP_FTP_DATA_RETRIEVE_H_ */ diff --git a/Sming/SmingCore/Network/Ftp/FtpDataStore.h b/Sming/SmingCore/Network/Ftp/FtpDataStore.h new file mode 100644 index 0000000000..39b123e015 --- /dev/null +++ b/Sming/SmingCore/Network/Ftp/FtpDataStore.h @@ -0,0 +1,55 @@ +/**** + * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development. + * Created 2015 by Skurydin Alexey + * http://github.com/anakod/Sming + * All files of the Sming Core are provided under the LGPL v3 license. + * + * FtpDataStore.h + * + ****/ + +#ifndef _SMING_CORE_NETWORK_FTP_FTP_DATA_STORE_H_ +#define _SMING_CORE_NETWORK_FTP_FTP_DATA_STORE_H_ + +#include "FtpDataStream.h" +#include "FileSystem.h" + +class FtpDataStore : public FtpDataStream +{ +public: + FtpDataStore(FtpServerConnection* connection, const String& fileName) + : FtpDataStream(connection), file(fileOpen(fileName, eFO_WriteOnly | eFO_CreateNewAlways)) + { + } + + ~FtpDataStore() + { + fileClose(file); + } + + err_t onReceive(pbuf* buf) override + { + if(completed) { + return TcpConnection::onReceive(buf); + } + + if(buf == nullptr) { + completed = true; + response(226, "Transfer completed"); + return TcpConnection::onReceive(buf); + } + + pbuf* cur = buf; + while(cur != nullptr && cur->len > 0) { + fileWrite(file, (uint8_t*)cur->payload, cur->len); + cur = cur->next; + } + + return TcpConnection::onReceive(buf); + } + +private: + file_t file; +}; + +#endif /* _SMING_CORE_NETWORK_FTP_FTP_DATA_STORE_H_ */ diff --git a/Sming/SmingCore/Network/Ftp/FtpDataStream.h b/Sming/SmingCore/Network/Ftp/FtpDataStream.h new file mode 100644 index 0000000000..a64749daeb --- /dev/null +++ b/Sming/SmingCore/Network/Ftp/FtpDataStream.h @@ -0,0 +1,80 @@ +/**** + * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development. + * Created 2015 by Skurydin Alexey + * http://github.com/anakod/Sming + * All files of the Sming Core are provided under the LGPL v3 license. + * + * FtpDataStream.h + * + ****/ + +#ifndef _SMING_CORE_NETWORK_FTP_FTP_DATA_STREAM_H_ +#define _SMING_CORE_NETWORK_FTP_FTP_DATA_STREAM_H_ + +#include "FtpServerConnection.h" +#include "TcpConnection.h" + +class FtpDataStream : public TcpConnection +{ +public: + explicit FtpDataStream(FtpServerConnection* connection) : TcpConnection(true), parent(connection) + { + } + + err_t onConnected(err_t err) override + { + //response(125, "Connected"); + setTimeOut(300); // Update timeout + return TcpConnection::onConnected(err); + } + + err_t onSent(uint16_t len) override + { + sent += len; + if(written < sent || !completed) { + return TcpConnection::onSent(len); + } + finishTransfer(); + return TcpConnection::onSent(len); + } + + void finishTransfer() + { + close(); + parent->dataTransferFinished(this); + } + + void response(int code, String text = nullptr) + { + parent->response(code, text); + } + + int write(const char* data, int len, uint8_t apiflags = 0) + { + written += len; + return TcpConnection::write(data, len, apiflags); + } + + void onReadyToSendData(TcpConnectionEvent sourceEvent) override + { + if(!parent->isCanTransfer()) { + return; + } + if(completed && written == 0) { + finishTransfer(); + } + transferData(sourceEvent); + } + + virtual void transferData(TcpConnectionEvent sourceEvent) + { + } + +protected: + FtpServerConnection* parent = nullptr; + bool completed = false; + unsigned written = 0; + unsigned sent = 0; +}; + +#endif /* _SMING_CORE_NETWORK_FTP_FTP_DATA_STREAM_H_ */ diff --git a/Sming/SmingCore/Network/FTPServerConnection.cpp b/Sming/SmingCore/Network/Ftp/FtpServerConnection.cpp similarity index 50% rename from Sming/SmingCore/Network/FTPServerConnection.cpp rename to Sming/SmingCore/Network/Ftp/FtpServerConnection.cpp index 0e37a43491..48ae7e6cfa 100644 --- a/Sming/SmingCore/Network/FTPServerConnection.cpp +++ b/Sming/SmingCore/Network/Ftp/FtpServerConnection.cpp @@ -8,172 +8,18 @@ * ****/ -#include "FTPServerConnection.h" -#include "FTPServer.h" +#include "FtpServerConnection.h" +#include "FtpDataStore.h" +#include "FtpDataRetrieve.h" +#include "FtpDataFileList.h" +#include "../FtpServer.h" #include "NetUtils.h" -#include "TcpConnection.h" -#include "FileSystem.h" -class FTPDataStream : public TcpConnection +err_t FtpServerConnection::onReceive(pbuf* buf) { -public: - explicit FTPDataStream(FTPServerConnection* connection) : TcpConnection(true), parent(connection) - { - } - - err_t onConnected(err_t err) override - { - //response(125, "Connected"); - setTimeOut(300); // Update timeout - return TcpConnection::onConnected(err); - } - - err_t onSent(uint16_t len) override - { - sent += len; - if(written < sent || !completed) { - return TcpConnection::onSent(len); - } - finishTransfer(); - return TcpConnection::onSent(len); - } - - void finishTransfer() - { - close(); - parent->dataTransferFinished(this); - } - - void response(int code, String text = nullptr) - { - parent->response(code, text); - } - - int write(const char* data, int len, uint8_t apiflags = 0) - { - written += len; - return TcpConnection::write(data, len, apiflags); - } - - void onReadyToSendData(TcpConnectionEvent sourceEvent) override - { - if(!parent->isCanTransfer()) { - return; - } - if(completed && written == 0) { - finishTransfer(); - } - transferData(sourceEvent); - } - - virtual void transferData(TcpConnectionEvent sourceEvent) - { - } - -protected: - FTPServerConnection* parent = nullptr; - bool completed = false; - unsigned written = 0; - unsigned sent = 0; -}; - -class FTPDataFileList : public FTPDataStream -{ -public: - explicit FTPDataFileList(FTPServerConnection* connection) : FTPDataStream(connection) - { - } - - void transferData(TcpConnectionEvent sourceEvent) override - { - if(completed) { - return; - } - Vector list = fileList(); - debug_d("send file list: %d", list.count()); - for(unsigned i = 0; i < list.count(); i++) { - writeString("01-01-15 01:00AM " + String(fileGetSize(list[i])) + " " + list[i] + "\r\n"); - } - completed = true; - finishTransfer(); - } -}; - -class FTPDataRetrieve : public FTPDataStream -{ -public: - FTPDataRetrieve(FTPServerConnection* connection, const String& fileName) : FTPDataStream(connection) - { - file = fileOpen(fileName, eFO_ReadOnly); - } - - ~FTPDataRetrieve() - { - fileClose(file); - } - - void transferData(TcpConnectionEvent sourceEvent) override - { - if(completed) { - return; - } - char buf[1024]; - int len = fileRead(file, buf, 1024); - write(buf, len, TCP_WRITE_FLAG_COPY); - if(fileIsEOF(file)) { - completed = true; - finishTransfer(); - } - } - -private: - file_t file; -}; - -class FTPDataStore : public FTPDataStream -{ -public: - FTPDataStore(FTPServerConnection* connection, const String& fileName) : FTPDataStream(connection) - { - file = fileOpen(fileName, eFO_WriteOnly | eFO_CreateNewAlways); - } - - ~FTPDataStore() - { - fileClose(file); - } - - virtual err_t onReceive(pbuf* buf) - { - if(completed) { - return TcpConnection::onReceive(buf); - } - - if(buf == nullptr) { - completed = true; - response(226, "Transfer completed"); - return TcpConnection::onReceive(buf); - } - - pbuf* cur = buf; - while(cur != nullptr && cur->len > 0) { - fileWrite(file, (uint8_t*)cur->payload, cur->len); - cur = cur->next; - } - - return TcpConnection::onReceive(buf); - } - -private: - file_t file; -}; - -/////////////////////////////////////////////////////////////////////////////////////////////////////////// - -err_t FTPServerConnection::onReceive(pbuf* buf) -{ - if(buf == nullptr) + if(buf == nullptr) { return ERR_OK; + } int prev = 0; while(true) { @@ -198,7 +44,7 @@ err_t FTPServerConnection::onReceive(pbuf* buf) return ERR_OK; } -void FTPServerConnection::cmdPort(const String& data) +void FtpServerConnection::cmdPort(const String& data) { int last = getSplitterPos(data, ',', 4); if(last < 0) { @@ -218,7 +64,7 @@ void FTPServerConnection::cmdPort(const String& data) response(200); } -void FTPServerConnection::onCommand(String cmd, String data) +void FtpServerConnection::onCommand(String cmd, String data) { cmd.toUpperCase(); // We ready to quit always :) @@ -289,11 +135,11 @@ void FTPServerConnection::onCommand(String cmd, String data) response(550); }*/ else if(cmd == _F("RETR")) { - createDataConnection(new FTPDataRetrieve(this, makeFileName(data, false))); + createDataConnection(new FtpDataRetrieve(this, makeFileName(data, false))); } else if(cmd == _F("STOR")) { - createDataConnection(new FTPDataStore(this, makeFileName(data, true))); + createDataConnection(new FtpDataStore(this, makeFileName(data, true))); } else if(cmd == _F("LIST")) { - createDataConnection(new FTPDataFileList(this)); + createDataConnection(new FtpDataFileList(this)); } else if(cmd == _F("PASV")) { response(500, F("Passive mode not supported")); } else if(cmd == _F("NOOP")) { @@ -307,23 +153,24 @@ void FTPServerConnection::onCommand(String cmd, String data) debug_e("!!!CASE NOT IMPLEMENTED?!!!"); } -err_t FTPServerConnection::onSent(uint16_t len) +err_t FtpServerConnection::onSent(uint16_t len) { canTransfer = true; return ERR_OK; } -String FTPServerConnection::makeFileName(String name, bool shortIt) +String FtpServerConnection::makeFileName(String name, bool shortIt) { if(name.startsWith("/")) { - name = name.substring(1); + name.remove(0, 1); } if(shortIt && name.length() > 20) { - String ext = ""; - if(name.lastIndexOf('.') != -1) { - ext = name.substring(name.lastIndexOf('.')); + String ext; + int dotPos = name.lastIndexOf('.'); + if(dotPos >= 0) { + ext = name.substring(dotPos); } return name.substring(0, 16) + ext; @@ -331,14 +178,14 @@ String FTPServerConnection::makeFileName(String name, bool shortIt) return name; } -void FTPServerConnection::createDataConnection(TcpConnection* connection) +void FtpServerConnection::createDataConnection(TcpConnection* connection) { dataConnection = connection; dataConnection->connect(ip, port); response(150, F("Connecting")); } -void FTPServerConnection::dataTransferFinished(TcpConnection* connection) +void FtpServerConnection::dataTransferFinished(TcpConnection* connection) { if(connection != dataConnection) { SYSTEM_ERROR("FTP Wrong state: connection != dataConnection"); @@ -348,7 +195,7 @@ void FTPServerConnection::dataTransferFinished(TcpConnection* connection) response(226, F("Transfer Complete.")); } -int FTPServerConnection::getSplitterPos(String data, char splitter, uint8_t number) +int FtpServerConnection::getSplitterPos(const String& data, char splitter, uint8_t number) { uint8_t k = 0; @@ -364,7 +211,7 @@ int FTPServerConnection::getSplitterPos(String data, char splitter, uint8_t numb return -1; } -void FTPServerConnection::response(int code, String text /* = "" */) +void FtpServerConnection::response(int code, String text /* = "" */) { String response = String(code, DEC); if(text.length() == 0) { @@ -384,11 +231,11 @@ void FTPServerConnection::response(int code, String text /* = "" */) flush(); } -void FTPServerConnection::onReadyToSendData(TcpConnectionEvent sourceEvent) +void FtpServerConnection::onReadyToSendData(TcpConnectionEvent sourceEvent) { switch(state) { case eFCS_Ready: - this->writeString(_F("220 Welcome to Sming FTP\r\n"), 0); + writeString(_F("220 Welcome to Sming FTP\r\n"), 0); state = eFCS_Authorization; break; diff --git a/Sming/SmingCore/Network/FTPServerConnection.h b/Sming/SmingCore/Network/Ftp/FtpServerConnection.h similarity index 59% rename from Sming/SmingCore/Network/FTPServerConnection.h rename to Sming/SmingCore/Network/Ftp/FtpServerConnection.h index 071ba0ffd7..b362bfbb4d 100644 --- a/Sming/SmingCore/Network/FTPServerConnection.h +++ b/Sming/SmingCore/Network/Ftp/FtpServerConnection.h @@ -8,8 +8,8 @@ * ****/ -#ifndef _SMING_CORE_NETWORK_FTP_SERVER_CONNECTION_H_ -#define _SMING_CORE_NETWORK_FTP_SERVER_CONNECTION_H_ +#ifndef _SMING_CORE_NETWORK_FTP_FTP_SERVER_CONNECTION_H_ +#define _SMING_CORE_NETWORK_FTP_FTP_SERVER_CONNECTION_H_ #include "TcpConnection.h" #include "IPAddress.h" @@ -17,18 +17,18 @@ #define MAX_FTP_CMD 255 -class FTPServer; +class FtpServer; -enum FTPConnectionState { eFCS_Ready, eFCS_Authorization, eFCS_Active }; +enum FtpConnectionState { eFCS_Ready, eFCS_Authorization, eFCS_Active }; -class FTPServerConnection : public TcpConnection +class FtpServerConnection : public TcpConnection { - friend class FTPDataStream; - friend class FTPServer; + friend class FtpDataStream; + friend class FtpServer; public: - FTPServerConnection(FTPServer* parentServer, tcp_pcb* clientTcp) - : TcpConnection(clientTcp, true), server(parentServer), state(eFCS_Ready) + FtpServerConnection(FtpServer* parentServer, tcp_pcb* clientTcp) + : TcpConnection(clientTcp, true), server(parentServer) { } @@ -42,7 +42,7 @@ class FTPServerConnection : public TcpConnection virtual void onCommand(String cmd, String data); virtual void response(int code, String text = ""); - int getSplitterPos(String data, char splitter, uint8_t number); + int getSplitterPos(const String& data, char splitter, uint8_t number); String makeFileName(String name, bool shortIt); void cmdPort(const String& data); @@ -54,8 +54,8 @@ class FTPServerConnection : public TcpConnection } private: - FTPServer* server; - FTPConnectionState state; + FtpServer* server = nullptr; + FtpConnectionState state = eFCS_Ready; String userName; String renameFrom; @@ -65,4 +65,6 @@ class FTPServerConnection : public TcpConnection bool canTransfer = true; }; -#endif /* _SMING_CORE_NETWORK_FTP_SERVER_CONNECTION_H_ */ +typedef FtpServerConnection FTPServerConnection SMING_DEPRECATED; // @deprecated Use `FtpServerConnection` instead + +#endif /* _SMING_CORE_NETWORK_FTP_FTP_SERVER_CONNECTION_H_ */ diff --git a/Sming/SmingCore/Network/FTPServer.cpp b/Sming/SmingCore/Network/FtpServer.cpp similarity index 50% rename from Sming/SmingCore/Network/FTPServer.cpp rename to Sming/SmingCore/Network/FtpServer.cpp index 169a0fcd82..29835fe98a 100644 --- a/Sming/SmingCore/Network/FTPServer.cpp +++ b/Sming/SmingCore/Network/FtpServer.cpp @@ -8,47 +8,34 @@ * ****/ -#include "FTPServer.h" +#include "FtpServer.h" +#include "Ftp/FtpServerConnection.h" +#include "FileSystem.h" -#include "HttpRequest.h" -#include "HttpResponse.h" -#include "FTPServerConnection.h" -#include "TcpClient.h" -#include "WString.h" - -FTPServer::FTPServer() -{ - setTimeOut(900); // Update timeout -} - -FTPServer::~FTPServer() +TcpConnection* FtpServer::createClient(tcp_pcb* clientTcp) { + return new FtpServerConnection(this, clientTcp); } -TcpConnection* FTPServer::createClient(tcp_pcb* clientTcp) -{ - TcpConnection* con = new FTPServerConnection(this, clientTcp); - return con; -} - -void FTPServer::addUser(const String& login, const String& pass) +void FtpServer::addUser(const String& login, const String& pass) { debug_d("addUser: %s %s", login.c_str(), pass.c_str()); users[login] = pass; } -bool FTPServer::checkUser(const String& login, const String& pass) +bool FtpServer::checkUser(const String& login, const String& pass) { debug_d("checkUser: %s %s", login.c_str(), pass.c_str()); - if(!users.contains(login)) + if(!users.contains(login)) { return false; + } return users[login] == pass; } -bool FTPServer::onCommand(String cmd, String data, FTPServerConnection& connection) +bool FtpServer::onCommand(String cmd, String data, FtpServerConnection& connection) { - if(cmd == "FSFORMAT") { + if(cmd == _F("FSFORMAT")) { spiffs_format(); connection.response(200, F("File system successfully formatted")); return true; diff --git a/Sming/SmingCore/Network/FTPServer.h b/Sming/SmingCore/Network/FtpServer.h similarity index 73% rename from Sming/SmingCore/Network/FTPServer.h rename to Sming/SmingCore/Network/FtpServer.h index 3c06a861c6..9f1e89a912 100644 --- a/Sming/SmingCore/Network/FTPServer.h +++ b/Sming/SmingCore/Network/FtpServer.h @@ -19,18 +19,19 @@ #include "TcpServer.h" #include "WHashMap.h" -#include "WVector.h" #include "WString.h" -class FTPServerConnection; +class FtpServerConnection; -class FTPServer : public TcpServer +class FtpServer : public TcpServer { - friend class FTPServerConnection; + friend class FtpServerConnection; public: - FTPServer(); - ~FTPServer(); + FtpServer() + { + setTimeOut(900); // Update timeout + } void addUser(const String& login, const String& pass); bool checkUser(const String& login, const String& pass); @@ -38,11 +39,13 @@ class FTPServer : public TcpServer protected: TcpConnection* createClient(tcp_pcb* clientTcp) override; - virtual bool onCommand(String cmd, String data, FTPServerConnection& connection); + virtual bool onCommand(String cmd, String data, FtpServerConnection& connection); private: HashMap users; }; +typedef FtpServer FTPServer SMING_DEPRECATED; ///< @deprecated Use `FtpServer` instead + /** @} */ #endif /* _SMING_CORE_NETWORK_FTP_SERVER_H_ */ diff --git a/Sming/SmingCore/SmingCore.h b/Sming/SmingCore/SmingCore.h index f1bd435853..94eb82c626 100644 --- a/Sming/SmingCore/SmingCore.h +++ b/Sming/SmingCore/SmingCore.h @@ -46,7 +46,7 @@ #include "Network/Http/HttpRequest.h" #include "Network/Http/HttpResponse.h" #include "Network/Http/Websocket/WebsocketConnection.h" -#include "Network/FTPServer.h" +#include "Network/FtpServer.h" #include "Network/NetUtils.h" #include "Network/TcpClient.h" #include "Network/TcpConnection.h" diff --git a/samples/CommandProcessing_Debug/app/application.cpp b/samples/CommandProcessing_Debug/app/application.cpp index 59561a0b22..0aa710e09d 100644 --- a/samples/CommandProcessing_Debug/app/application.cpp +++ b/samples/CommandProcessing_Debug/app/application.cpp @@ -12,7 +12,7 @@ #endif HttpServer server; -FTPServer ftp; +FtpServer ftp; TelnetServer telnet; Timer msgTimer; diff --git a/samples/FtpServer_Files/app/application.cpp b/samples/FtpServer_Files/app/application.cpp index 83d0496a0c..8f4a730d74 100644 --- a/samples/FtpServer_Files/app/application.cpp +++ b/samples/FtpServer_Files/app/application.cpp @@ -7,7 +7,7 @@ #define WIFI_PWD "PleaseEnterPass" #endif -FTPServer ftp; +FtpServer ftp; void gotIP(IPAddress ip, IPAddress netmask, IPAddress gateway) { diff --git a/samples/HttpServer_AJAX/app/application.cpp b/samples/HttpServer_AJAX/app/application.cpp index eff781422a..d9a79aa4aa 100644 --- a/samples/HttpServer_AJAX/app/application.cpp +++ b/samples/HttpServer_AJAX/app/application.cpp @@ -8,7 +8,7 @@ #endif HttpServer server; -FTPServer ftp; +FtpServer ftp; int inputs[] = {0, 2}; // Set input GPIO pins here Vector namesInput; diff --git a/samples/HttpServer_ConfigNetwork/app/application.cpp b/samples/HttpServer_ConfigNetwork/app/application.cpp index 1f766f0cda..eaa2e2f5e6 100644 --- a/samples/HttpServer_ConfigNetwork/app/application.cpp +++ b/samples/HttpServer_ConfigNetwork/app/application.cpp @@ -4,7 +4,7 @@ #include "Data/Stream/TemplateFlashMemoryStream.h" HttpServer server; -FTPServer ftp; +FtpServer ftp; BssList networks; String network, password;