summaryrefslogtreecommitdiffstats
path: root/FTPCommon.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'FTPCommon.cpp')
-rw-r--r--FTPCommon.cpp146
1 files changed, 146 insertions, 0 deletions
diff --git a/FTPCommon.cpp b/FTPCommon.cpp
new file mode 100644
index 0000000..66211a8
--- /dev/null
+++ b/FTPCommon.cpp
@@ -0,0 +1,146 @@
+#include "FTPCommon.h"
+
+FTPCommon::FTPCommon(FS &_FSImplementation) : THEFS(_FSImplementation)
+{
+}
+
+FTPCommon::~FTPCommon()
+{
+ stop();
+}
+
+void FTPCommon::stop()
+{
+ control.stop();
+ data.stop();
+ file.close();
+ freeBuffer();
+}
+
+void FTPCommon::setTimeout(uint16_t timeout)
+{
+ sTimeOut = timeout;
+}
+
+uint16_t FTPCommon::allocateBuffer(uint16_t desiredBytes)
+{
+ // allocate a big buffer for file transfers
+ uint16_t maxBlock = ESP.getMaxFreeBlockSize() / 2;
+
+ if (desiredBytes > maxBlock)
+ desiredBytes = maxBlock;
+
+ while (fileBuffer == NULL && desiredBytes > 0)
+ {
+ fileBuffer = (uint8_t *)malloc(desiredBytes);
+ if (NULL == fileBuffer)
+ {
+ FTP_DEBUG_MSG("Cannot allocate buffer for file transfer, re-trying");
+ // try with less bytes
+ desiredBytes--;
+ }
+ else
+ {
+ fileBufferSize = desiredBytes;
+ }
+ }
+ return fileBufferSize;
+}
+
+void FTPCommon::freeBuffer()
+{
+ free(fileBuffer);
+ fileBuffer = NULL;
+}
+
+int8_t FTPCommon::dataConnect()
+{
+ // open our own data connection
+ data.stop();
+ FTP_DEBUG_MSG("Open data connection to %s:%u", dataIP.toString().c_str(), dataPort);
+ data.connect(dataIP, dataPort);
+ return data.connected() ? 1 : -1;
+}
+
+bool FTPCommon::parseDataIpPort(const char *p)
+{
+ // parse IP and data port of "ip,ip,ip,ip,port,port"
+ uint8_t parsecount = 0;
+ uint8_t tmp[6];
+ while (parsecount < sizeof(tmp))
+ {
+ tmp[parsecount++] = atoi(p);
+ p = strchr(p, ',');
+ if (NULL == p || *(++p) == '\0')
+ break;
+ }
+ if (parsecount >= sizeof(tmp))
+ {
+ // copy first 4 bytes = IP
+ for (uint8_t i = 0; i < 4; ++i)
+ dataIP[i] = tmp[i];
+ // data port is 5,6
+ dataPort = tmp[4] * 256 + tmp[5];
+ return true;
+ }
+ return false;
+}
+
+bool FTPCommon::doFiletoNetwork()
+{
+ // data connection lost or no more bytes to transfer?
+ if (!data.connected() || (bytesTransfered >= file.size()))
+ {
+ return false;
+ }
+
+ // how many bytes to transfer left?
+ uint32_t nb = (file.size() - bytesTransfered);
+ if (nb > fileBufferSize)
+ nb = fileBufferSize;
+
+ // transfer the file
+ FTP_DEBUG_MSG("Transfer %d bytes fs->net", nb);
+ nb = file.readBytes((char *)fileBuffer, nb);
+ if (nb > 0)
+ {
+ data.write(fileBuffer, nb);
+ bytesTransfered += nb;
+ }
+
+ return (nb > 0);
+}
+
+bool FTPCommon::doNetworkToFile()
+{
+ // Avoid blocking by never reading more bytes than are available
+ int16_t navail = data.available();
+
+ if (navail > 0)
+ {
+ if (navail > fileBufferSize)
+ navail = fileBufferSize;
+ FTP_DEBUG_MSG("Transfer %d bytes net->FS", navail);
+ navail = data.read(fileBuffer, navail);
+ file.write(fileBuffer, navail);
+ bytesTransfered += navail;
+ }
+
+ if (!data.connected() && (navail <= 0))
+ {
+ // connection closed or no more bytes to read
+ return false;
+ }
+ else
+ {
+ // inidcate, we need to be called again
+ return true;
+ }
+}
+
+void FTPCommon::closeTransfer()
+{
+ freeBuffer();
+ file.close();
+ data.stop();
+}