kopia lustrzana https://github.com/lora-aprs/LoRa_APRS_iGate
FTP lib got added again in correct version
rodzic
b658ed2ed6
commit
75024a2617
|
@ -1,5 +0,0 @@
|
|||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2020 Peter Buchegger
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -1,34 +0,0 @@
|
|||
# ESP-FTP-Server-Lib
|
||||
|
||||
This library will provide a simple and modern FTP server for your ESP32 or ESP8266 device.
|
||||
You can setup multiple users and mutliple filesystems (SD-Card, MMC-Card or/and SPIFFS).
|
||||
|
||||
## Examples
|
||||
|
||||
In the example folder you can find a very simple usage of the FTP server. You just need to setup the users, add the filesystems which you want to use, and call the handle function in the loop.
|
||||
|
||||
## Known Commands to the server
|
||||
|
||||
Currently all kind of simple commands are known to the server:
|
||||
* CDUP
|
||||
* CWD
|
||||
* DELE
|
||||
* LISST
|
||||
* MKD
|
||||
* PORT
|
||||
* PWD
|
||||
* RETR
|
||||
* RMD
|
||||
* RNFR
|
||||
* RNTO
|
||||
* STOR
|
||||
* TYPE
|
||||
* SYST
|
||||
* QUIT
|
||||
* ABOR
|
||||
|
||||
## What is still missing / TODO
|
||||
|
||||
Some commands are still missing, if you need them create a ticket :)
|
||||
|
||||
Currently just the active mode is supported. For the passive mode you need to wait until version 1.0.0.
|
|
@ -1,11 +0,0 @@
|
|||
name=ESP-FTP-Server-Lib
|
||||
version=0.9.3
|
||||
author=Peter Buchegger <peter@pbuchegger.at>
|
||||
maintainer=Peter Buchegger <peter@pbuchegger.at>
|
||||
sentence=Simple and modern FTP server for ESP devices.
|
||||
paragraph=With this library you can run a simple and modern FTP server on your ESP32 or ESP8266. You can mount multiple filesystems like SD-Card, MMC-Card or SPIFFS at the same time.
|
||||
category=Communication
|
||||
url=https://github.com/peterus/ESP-FTP-Server-Lib
|
||||
architectures=esp8266,esp32,arduino-esp32
|
||||
includes=ESP-FTP-Server-Lib.h
|
||||
depends=
|
|
@ -1,9 +0,0 @@
|
|||
|
||||
[env:ttgo-lora32-v1]
|
||||
platform = espressif32
|
||||
board = ttgo-lora32-v1
|
||||
framework = arduino
|
||||
test_build_project_src = yes
|
||||
monitor_speed = 115200
|
||||
check_flags =
|
||||
cppcheck: --suppress=*:*.pio\* --suppress=unusedFunction
|
|
@ -1,19 +0,0 @@
|
|||
#ifndef CDUP_H_
|
||||
#define CDUP_H_
|
||||
|
||||
#include <WiFiClient.h>
|
||||
#include "../FTPCommand.h"
|
||||
|
||||
class CDUP : public FTPCommand
|
||||
{
|
||||
public:
|
||||
explicit CDUP(WiFiClient * const Client) : FTPCommand("CDUP", 0, Client) {}
|
||||
|
||||
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
|
||||
{
|
||||
WorkDirectory.goPathUp();
|
||||
SendResponse(250, "Ok. Current directory is " + WorkDirectory.getPath());
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,37 +0,0 @@
|
|||
#ifndef CWD_H_
|
||||
#define CWD_H_
|
||||
|
||||
#include <WiFiClient.h>
|
||||
#include "../FTPCommand.h"
|
||||
|
||||
class CWD : public FTPCommand
|
||||
{
|
||||
public:
|
||||
explicit CWD(WiFiClient * const Client, FTPFilesystem * const Filesystem) : FTPCommand("CWD", 1, Client, Filesystem) {}
|
||||
|
||||
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
|
||||
{
|
||||
FTPPath path = WorkDirectory;
|
||||
Serial.println(Line[1]);
|
||||
if(Line[1] == "..")
|
||||
{
|
||||
path.goPathUp();
|
||||
}
|
||||
else
|
||||
{
|
||||
path.changePath(Line[1]);
|
||||
}
|
||||
File dir = _Filesystem->open(path.getPath());
|
||||
if(dir.isDirectory())
|
||||
{
|
||||
WorkDirectory = path;
|
||||
SendResponse(250, "Ok. Current directory is " + WorkDirectory.getPath());
|
||||
}
|
||||
else
|
||||
{
|
||||
SendResponse(550, "Directory does not exist");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,31 +0,0 @@
|
|||
#ifndef DELE_H_
|
||||
#define DELE_H_
|
||||
|
||||
#include <WiFiClient.h>
|
||||
#include "../FTPCommand.h"
|
||||
|
||||
class DELE : public FTPCommand
|
||||
{
|
||||
public:
|
||||
explicit DELE(WiFiClient * const Client, FTPFilesystem * const Filesystem) : FTPCommand("DELE", 1, Client, Filesystem) {}
|
||||
|
||||
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
|
||||
{
|
||||
String filepath = WorkDirectory.getFilePath(Line[1]);
|
||||
if(!_Filesystem->exists(filepath))
|
||||
{
|
||||
SendResponse(550, "File " + filepath + " not found");
|
||||
return;
|
||||
}
|
||||
if(_Filesystem->remove(filepath))
|
||||
{
|
||||
SendResponse(250, " Deleted \"" + filepath + "\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
SendResponse(450, "Can't delete \"" + filepath + "\"");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,58 +0,0 @@
|
|||
#ifndef LIST_H_
|
||||
#define LIST_H_
|
||||
|
||||
#include <WiFiClient.h>
|
||||
#include "../FTPCommand.h"
|
||||
#include "../common.h"
|
||||
|
||||
class LIST : public FTPCommand
|
||||
{
|
||||
public:
|
||||
explicit LIST(WiFiClient * const Client, FTPFilesystem * const Filesystem, IPAddress * DataAddress, int * DataPort)
|
||||
: FTPCommand("LIST", 1, Client, Filesystem, DataAddress, DataPort)
|
||||
{}
|
||||
|
||||
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
|
||||
{
|
||||
if(!ConnectDataConnection())
|
||||
{
|
||||
return;
|
||||
}
|
||||
File dir = _Filesystem->open(WorkDirectory.getPath());
|
||||
if(!dir || !dir.isDirectory())
|
||||
{
|
||||
CloseDataConnection();
|
||||
SendResponse(550, "Can't open directory " + WorkDirectory.getPath());
|
||||
return;
|
||||
}
|
||||
int cnt = 0;
|
||||
File f = dir.openNextFile();
|
||||
while(f)
|
||||
{
|
||||
String filename = f.name();
|
||||
filename.remove(0, filename.lastIndexOf('/') + 1);
|
||||
if(f.isDirectory())
|
||||
{
|
||||
data_print("drwxr-xr-x");
|
||||
}
|
||||
else
|
||||
{
|
||||
data_print("-rw-r--r--");
|
||||
}
|
||||
String filesize = String(f.size());
|
||||
data_print(" 1 owner group ");
|
||||
int fill_cnt = 13 - filesize.length();
|
||||
for(int i = 0; i < fill_cnt; i++)
|
||||
{
|
||||
data_print(" ");
|
||||
}
|
||||
data_println(filesize + " Jan 01 1970 " + filename);
|
||||
cnt++;
|
||||
f = dir.openNextFile();
|
||||
}
|
||||
CloseDataConnection();
|
||||
SendResponse(226, String(cnt) + " matches total");
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,31 +0,0 @@
|
|||
#ifndef MKD_H_
|
||||
#define MKD_H_
|
||||
|
||||
#include <WiFiClient.h>
|
||||
#include "../FTPCommand.h"
|
||||
|
||||
class MKD : public FTPCommand
|
||||
{
|
||||
public:
|
||||
explicit MKD(WiFiClient * const Client, FTPFilesystem * const Filesystem) : FTPCommand("MKD", 1, Client, Filesystem) {}
|
||||
|
||||
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
|
||||
{
|
||||
String filepath = WorkDirectory.getFilePath(Line[1]);
|
||||
if(_Filesystem->exists(filepath))
|
||||
{
|
||||
SendResponse(521, "Can't create \"" + filepath + "\", Directory exists");
|
||||
return;
|
||||
}
|
||||
if(_Filesystem->mkdir(filepath))
|
||||
{
|
||||
SendResponse(257, "\"" + filepath + "\" created");
|
||||
}
|
||||
else
|
||||
{
|
||||
SendResponse(550, "Can't create \"" + filepath + "\"");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,27 +0,0 @@
|
|||
#ifndef PORT_H_
|
||||
#define PORT_H_
|
||||
|
||||
#include <WiFiClient.h>
|
||||
#include "../FTPCommand.h"
|
||||
#include "../common.h"
|
||||
|
||||
class PORT : public FTPCommand
|
||||
{
|
||||
public:
|
||||
explicit PORT(WiFiClient * const Client, IPAddress * DataAddress, int * DataPort)
|
||||
: FTPCommand("PORT", 1, Client, 0, DataAddress, DataPort)
|
||||
{}
|
||||
|
||||
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
|
||||
{
|
||||
std::vector<String> connection_details = Split<std::vector<String>>(Line[1], ',');
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
(*_DataAddress)[i] = connection_details[i].toInt();
|
||||
}
|
||||
*_DataPort = connection_details[4].toInt() * 256 + connection_details[5].toInt();
|
||||
SendResponse(200, "PORT command successful");
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,18 +0,0 @@
|
|||
#ifndef PWD_H_
|
||||
#define PWD_H_
|
||||
|
||||
#include <WiFiClient.h>
|
||||
#include "../FTPCommand.h"
|
||||
|
||||
class PWD : public FTPCommand
|
||||
{
|
||||
public:
|
||||
explicit PWD(WiFiClient * const Client) : FTPCommand("PWD", 0, Client) {}
|
||||
|
||||
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
|
||||
{
|
||||
SendResponse(257, "\"" + WorkDirectory.getPath() + "\" is your current directory");
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,55 +0,0 @@
|
|||
#ifndef RETR_H_
|
||||
#define RETR_H_
|
||||
|
||||
#include <WiFiClient.h>
|
||||
#include "../FTPCommand.h"
|
||||
#include "../common.h"
|
||||
|
||||
#define FTP_BUF_SIZE 4096
|
||||
|
||||
class RETR : public FTPCommandTransfer
|
||||
{
|
||||
public:
|
||||
explicit RETR(WiFiClient * const Client, FTPFilesystem * const Filesystem, IPAddress * DataAddress, int * DataPort)
|
||||
: FTPCommandTransfer("RETR", 1, Client, Filesystem, DataAddress, DataPort)
|
||||
{}
|
||||
|
||||
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
|
||||
{
|
||||
if(trasferInProgress())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(!ConnectDataConnection())
|
||||
{
|
||||
return;
|
||||
}
|
||||
String path = WorkDirectory.getFilePath(Line[1]);
|
||||
_file = _Filesystem->open(path);
|
||||
if(!_file || _file.isDirectory())
|
||||
{
|
||||
CloseDataConnection();
|
||||
SendResponse(550, "Can't open " + path);
|
||||
return;
|
||||
}
|
||||
workOnData();
|
||||
}
|
||||
|
||||
void workOnData() override
|
||||
{
|
||||
uint8_t buffer[FTP_BUF_SIZE];
|
||||
size_t nb = _file.read(buffer, FTP_BUF_SIZE);
|
||||
if(nb > 0)
|
||||
{
|
||||
data_send(buffer, nb);
|
||||
return;
|
||||
}
|
||||
CloseDataConnection();
|
||||
SendResponse(226, "File successfully transferred");
|
||||
_file.close();
|
||||
}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,31 +0,0 @@
|
|||
#ifndef RMD_H_
|
||||
#define RMD_H_
|
||||
|
||||
#include <WiFiClient.h>
|
||||
#include "../FTPCommand.h"
|
||||
|
||||
class RMD : public FTPCommand
|
||||
{
|
||||
public:
|
||||
explicit RMD(WiFiClient * const Client, FTPFilesystem * const Filesystem) : FTPCommand("RMD", 1, Client, Filesystem) {}
|
||||
|
||||
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
|
||||
{
|
||||
String filepath = WorkDirectory.getFilePath(Line[1]);
|
||||
if(!_Filesystem->exists(filepath))
|
||||
{
|
||||
SendResponse(550, "Folder " + filepath + " not found");
|
||||
return;
|
||||
}
|
||||
if(_Filesystem->rmdir(filepath))
|
||||
{
|
||||
SendResponse(250, " Deleted \"" + filepath + "\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
SendResponse(450, "Can't delete \"" + filepath + "\"");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,67 +0,0 @@
|
|||
#ifndef RNFR_H_
|
||||
#define RNFR_H_
|
||||
|
||||
#include <WiFiClient.h>
|
||||
#include "../FTPCommand.h"
|
||||
|
||||
class RNFR_RNTO : public FTPCommand
|
||||
{
|
||||
public:
|
||||
explicit RNFR_RNTO(WiFiClient * const Client, FTPFilesystem * const Filesystem) : FTPCommand("RN", 1, Client, Filesystem), _fromSet(false) {}
|
||||
|
||||
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
|
||||
{
|
||||
if(Line[0] == "RNFR")
|
||||
{
|
||||
from(WorkDirectory, Line);
|
||||
}
|
||||
else if(Line[0] == "RNTO")
|
||||
{
|
||||
to(WorkDirectory, Line);
|
||||
}
|
||||
}
|
||||
|
||||
void from(const FTPPath & WorkDirectory, const std::vector<String> & Line)
|
||||
{
|
||||
String filepath = WorkDirectory.getFilePath(Line[1]);
|
||||
if(!_Filesystem->exists(filepath))
|
||||
{
|
||||
SendResponse(550, "File " + Line[1] + " not found");
|
||||
return;
|
||||
}
|
||||
_fromSet = true;
|
||||
_from = filepath;
|
||||
SendResponse(350, "RNFR accepted - file exists, ready for destination");
|
||||
}
|
||||
|
||||
void to(const FTPPath & WorkDirectory, const std::vector<String> & Line)
|
||||
{
|
||||
if(!_fromSet)
|
||||
{
|
||||
SendResponse(503, "Need RNFR before RNTO");
|
||||
return;
|
||||
}
|
||||
String filepath = WorkDirectory.getFilePath(Line[1]);
|
||||
if(_Filesystem->exists(filepath))
|
||||
{
|
||||
SendResponse(553, "File " + Line[1] + " already exists");
|
||||
return;
|
||||
}
|
||||
if(_Filesystem->rename(_from, filepath))
|
||||
{
|
||||
SendResponse(250, "File successfully renamed or moved");
|
||||
}
|
||||
else
|
||||
{
|
||||
SendResponse(451, "Rename/move failure");
|
||||
}
|
||||
_fromSet = false;
|
||||
_from = "";
|
||||
}
|
||||
|
||||
private:
|
||||
bool _fromSet;
|
||||
String _from;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,55 +0,0 @@
|
|||
#ifndef STOR_H_
|
||||
#define STOR_H_
|
||||
|
||||
#include <WiFiClient.h>
|
||||
#include "../FTPCommand.h"
|
||||
#include "../common.h"
|
||||
|
||||
#define FTP_BUF_SIZE 4096
|
||||
|
||||
class STOR : public FTPCommandTransfer
|
||||
{
|
||||
public:
|
||||
explicit STOR(WiFiClient * const Client, FTPFilesystem * const Filesystem, IPAddress * DataAddress, int * DataPort)
|
||||
: FTPCommandTransfer("STOR", 1, Client, Filesystem, DataAddress, DataPort)
|
||||
{}
|
||||
|
||||
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
|
||||
{
|
||||
if(trasferInProgress())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(!ConnectDataConnection())
|
||||
{
|
||||
return;
|
||||
}
|
||||
String path = WorkDirectory.getFilePath(Line[1]);
|
||||
_file = _Filesystem->open(path, "w");
|
||||
if(!_file)
|
||||
{
|
||||
CloseDataConnection();
|
||||
SendResponse(451, "Can't open/create " + path);
|
||||
return;
|
||||
}
|
||||
workOnData();
|
||||
}
|
||||
|
||||
void workOnData() override
|
||||
{
|
||||
uint8_t buffer[FTP_BUF_SIZE];
|
||||
int nb = data_read(buffer, FTP_BUF_SIZE);
|
||||
if(nb > 0)
|
||||
{
|
||||
_file.write(buffer, nb);
|
||||
return;
|
||||
}
|
||||
CloseDataConnection();
|
||||
SendResponse(226, "File successfully transferred");
|
||||
_file.close();
|
||||
}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,28 +0,0 @@
|
|||
#ifndef TYPE_H_
|
||||
#define TYPE_H_
|
||||
|
||||
#include <WiFiClient.h>
|
||||
#include "../FTPCommand.h"
|
||||
|
||||
class TYPE : public FTPCommand
|
||||
{
|
||||
public:
|
||||
explicit TYPE(WiFiClient * const Client) : FTPCommand("TYPE", 1, Client) {}
|
||||
|
||||
void run(FTPPath & WorkDirectory, const std::vector<String> & Line) override
|
||||
{
|
||||
if(Line[1] == "A")
|
||||
{
|
||||
SendResponse(200, "TYPE is now ASCII");
|
||||
return;
|
||||
}
|
||||
else if(Line[1] == "I")
|
||||
{
|
||||
SendResponse(200, "TYPE is now 8-bit binary");
|
||||
return;
|
||||
}
|
||||
SendResponse(504, "Unknow TYPE");
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,56 +0,0 @@
|
|||
#include "ESP-FTP-Server-Lib.h"
|
||||
|
||||
FTPServer::FTPServer()
|
||||
: _Server(FTP_CTRL_PORT, 1)
|
||||
{
|
||||
}
|
||||
|
||||
FTPServer::~FTPServer()
|
||||
{
|
||||
}
|
||||
|
||||
void FTPServer::addUser(const String & Username, const String & Password)
|
||||
{
|
||||
FTPUser user(Username, Password);
|
||||
_UserList.push_back(user);
|
||||
}
|
||||
|
||||
void FTPServer::addUser(const FTPUser & User)
|
||||
{
|
||||
_UserList.push_back(User);
|
||||
}
|
||||
|
||||
void FTPServer::addFilesystem(String Name, FS * const Filesystem)
|
||||
{
|
||||
_Filesystem.addFilesystem(Name, Filesystem);
|
||||
}
|
||||
|
||||
bool FTPServer::begin()
|
||||
{
|
||||
_Server.begin();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isNotConnected(const std::shared_ptr<FTPConnection> & con)
|
||||
{
|
||||
return !con->connected();
|
||||
}
|
||||
|
||||
void FTPServer::handle()
|
||||
{
|
||||
if(_Server.hasClient())
|
||||
{
|
||||
std::shared_ptr<FTPConnection> connection = std::shared_ptr<FTPConnection>(new FTPConnection(_Server.available(), _UserList, _Filesystem));
|
||||
_Connections.push_back(connection);
|
||||
}
|
||||
for(std::shared_ptr<FTPConnection> con: _Connections)
|
||||
{
|
||||
con->handle();
|
||||
}
|
||||
_Connections.remove_if(isNotConnected);
|
||||
}
|
||||
|
||||
size_t FTPServer::countConnections() const
|
||||
{
|
||||
return _Connections.size();
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
#ifndef ESP_FTP_LIB_H_
|
||||
#define ESP_FTP_LIB_H_
|
||||
|
||||
#include <list>
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "FTPUser.h"
|
||||
#include "FTPConnection.h"
|
||||
#include "FTPFilesystem.h"
|
||||
|
||||
class FTPServer
|
||||
{
|
||||
public:
|
||||
FTPServer();
|
||||
virtual ~FTPServer();
|
||||
|
||||
void addUser(const String & Username, const String & Password);
|
||||
void addUser(const FTPUser & User);
|
||||
|
||||
void addFilesystem(String Name, FS * const Filesystem);
|
||||
|
||||
bool begin();
|
||||
void handle();
|
||||
|
||||
size_t countConnections() const;
|
||||
|
||||
private:
|
||||
WiFiServer _Server;
|
||||
|
||||
std::list<FTPUser> _UserList;
|
||||
std::list<std::shared_ptr<FTPConnection>> _Connections;
|
||||
|
||||
FTPFilesystem _Filesystem;
|
||||
};
|
||||
|
||||
#define FTP_DEBUG(txt) Serial.print("[DEBUG] "); Serial.println(txt)
|
||||
|
||||
#endif
|
|
@ -1,133 +0,0 @@
|
|||
#ifndef FTP_COMMAND_H_
|
||||
#define FTP_COMMAND_H_
|
||||
|
||||
#include <WiFiClient.h>
|
||||
#include <Arduino.h>
|
||||
#include "FTPPath.h"
|
||||
#include "FTPFilesystem.h"
|
||||
|
||||
class FTPCommand
|
||||
{
|
||||
public:
|
||||
FTPCommand(String Name, int ExpectedArgumentCnt, WiFiClient * const Client, FTPFilesystem * const Filesystem = 0, IPAddress * DataAddress = 0, int * DataPort = 0)
|
||||
: _Name(Name), _ExpectedArgumentCnt(ExpectedArgumentCnt),
|
||||
_Filesystem(Filesystem),
|
||||
_DataAddress(DataAddress), _DataPort(DataPort), _Client(Client), _DataConnection(0) {}
|
||||
virtual ~FTPCommand() {}
|
||||
|
||||
String getName() const
|
||||
{
|
||||
return _Name;
|
||||
}
|
||||
|
||||
virtual void run(FTPPath & WorkDirectory, const std::vector<String> & Line) = 0;
|
||||
|
||||
void SendResponse(int Code, String Text)
|
||||
{
|
||||
_Client->print(Code);
|
||||
_Client->print(" ");
|
||||
_Client->println(Text);
|
||||
}
|
||||
|
||||
bool ConnectDataConnection()
|
||||
{
|
||||
if(_DataConnection == 0)
|
||||
{
|
||||
_DataConnection = new WiFiClient();
|
||||
}
|
||||
if(_DataConnection->connected())
|
||||
{
|
||||
_DataConnection->stop();
|
||||
}
|
||||
_DataConnection->connect(*_DataAddress, *_DataPort);
|
||||
if(!_DataConnection->connected())
|
||||
{
|
||||
_DataConnection->stop();
|
||||
SendResponse(425, "No data connection");
|
||||
return false;
|
||||
}
|
||||
SendResponse(150, "Accepted data connection");
|
||||
return true;
|
||||
}
|
||||
|
||||
void data_print(String str)
|
||||
{
|
||||
if(_DataConnection == 0 || !_DataConnection->connected())
|
||||
{
|
||||
return;
|
||||
}
|
||||
_DataConnection->print(str);
|
||||
}
|
||||
|
||||
void data_println(String str)
|
||||
{
|
||||
if(_DataConnection == 0 || !_DataConnection->connected())
|
||||
{
|
||||
return;
|
||||
}
|
||||
_DataConnection->println(str);
|
||||
}
|
||||
|
||||
void data_send(uint8_t * c, size_t l)
|
||||
{
|
||||
if(_DataConnection == 0 || !_DataConnection->connected())
|
||||
{
|
||||
return;
|
||||
}
|
||||
_DataConnection->write(c, l);
|
||||
}
|
||||
|
||||
int data_read(uint8_t * c, size_t l)
|
||||
{
|
||||
if(_DataConnection == 0 || !_DataConnection->connected())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return _DataConnection->readBytes(c, l);
|
||||
}
|
||||
|
||||
void CloseDataConnection()
|
||||
{
|
||||
_DataConnection->stop();
|
||||
}
|
||||
|
||||
protected:
|
||||
String _Name;
|
||||
int _ExpectedArgumentCnt;
|
||||
FTPFilesystem * const _Filesystem;
|
||||
IPAddress * const _DataAddress;
|
||||
int * const _DataPort;
|
||||
|
||||
private:
|
||||
WiFiClient * const _Client;
|
||||
WiFiClient * _DataConnection;
|
||||
};
|
||||
|
||||
class FTPCommandTransfer : public FTPCommand
|
||||
{
|
||||
public:
|
||||
FTPCommandTransfer(String Name, int ExpectedArgumentCnt, WiFiClient * const Client, FTPFilesystem * const Filesystem = 0, IPAddress * DataAddress = 0, int * DataPort = 0)
|
||||
: FTPCommand(Name, ExpectedArgumentCnt, Client, Filesystem, DataAddress, DataPort) {}
|
||||
|
||||
virtual void workOnData() = 0;
|
||||
|
||||
bool trasferInProgress()
|
||||
{
|
||||
return _file;
|
||||
}
|
||||
|
||||
void abort()
|
||||
{
|
||||
if(_file)
|
||||
{
|
||||
CloseDataConnection();
|
||||
SendResponse(426, "Transfer aborted");
|
||||
_file.close();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
File _file;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,207 +0,0 @@
|
|||
#include "ESP-FTP-Server-Lib.h"
|
||||
#include "common.h"
|
||||
#include "Commands/CDUP.h"
|
||||
#include "Commands/CWD.h"
|
||||
#include "Commands/DELE.h"
|
||||
#include "Commands/LIST.h"
|
||||
#include "Commands/MKD.h"
|
||||
#include "Commands/PORT.h"
|
||||
#include "Commands/PWD.h"
|
||||
#include "Commands/RETR.h"
|
||||
#include "Commands/RMD.h"
|
||||
#include "Commands/RNFR_RNTO.h"
|
||||
#include "Commands/STOR.h"
|
||||
#include "Commands/TYPE.h"
|
||||
|
||||
FTPConnection::FTPConnection(const WiFiClient & Client, std::list<FTPUser> & UserList, FTPFilesystem & Filesystem)
|
||||
: _ClientState(Idle), _Client(Client), _Filesystem(Filesystem), _UserList(UserList), _AuthUsername("")
|
||||
{
|
||||
std::shared_ptr<FTPCommandTransfer> retr = std::shared_ptr<FTPCommandTransfer>(new RETR(&_Client, &_Filesystem, &_DataAddress, &_DataPort));
|
||||
std::shared_ptr<FTPCommandTransfer> stor = std::shared_ptr<FTPCommandTransfer>(new STOR(&_Client, &_Filesystem, &_DataAddress, &_DataPort));
|
||||
|
||||
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new CDUP(&_Client)));
|
||||
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new CWD(&_Client, &_Filesystem)));
|
||||
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new DELE(&_Client, &_Filesystem)));
|
||||
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new LIST(&_Client, &_Filesystem, &_DataAddress, &_DataPort)));
|
||||
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new MKD(&_Client, &_Filesystem)));
|
||||
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new PORT(&_Client, &_DataAddress, &_DataPort)));
|
||||
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new PWD(&_Client)));
|
||||
_FTPCommands.push_back(retr);
|
||||
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new RMD(&_Client, &_Filesystem)));
|
||||
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new RNFR_RNTO(&_Client, &_Filesystem)));
|
||||
_FTPCommands.push_back(stor);
|
||||
_FTPCommands.push_back(std::shared_ptr<FTPCommand>(new TYPE(&_Client)));
|
||||
|
||||
_FTPCommandsTransfer.push_back(retr);
|
||||
_FTPCommandsTransfer.push_back(stor);
|
||||
|
||||
Serial.print("New Connection from ");
|
||||
Serial.print(_Client.remoteIP());
|
||||
Serial.print(":");
|
||||
Serial.println(_Client.remotePort());
|
||||
_Client.println("220--- Welcome to FTP Server for ESP32 ---");
|
||||
_Client.println("220--- By Peter Buchegger ---");
|
||||
_Client.println("220 -- Version 0.1 ---");
|
||||
}
|
||||
|
||||
FTPConnection::~FTPConnection()
|
||||
{
|
||||
Serial.println("Connection closed!");
|
||||
}
|
||||
|
||||
bool FTPConnection::readUntilLineEnd()
|
||||
{
|
||||
while(_Client.available())
|
||||
{
|
||||
char c = _Client.read();
|
||||
if(c == '\n')
|
||||
{
|
||||
_LineSplited = Split<std::vector<String>>(_Line, ' ');
|
||||
return true;
|
||||
}
|
||||
if(c >= 32 && c < 127)
|
||||
{
|
||||
_Line += c;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FTPConnection::handle()
|
||||
{
|
||||
if(!_Client.connected())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for(std::shared_ptr<FTPCommandTransfer> cmd: _FTPCommandsTransfer)
|
||||
{
|
||||
if(cmd->trasferInProgress())
|
||||
{
|
||||
cmd->workOnData();
|
||||
}
|
||||
}
|
||||
if(!readUntilLineEnd())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// we have a new command in the queue:
|
||||
Serial.println(_Line);
|
||||
String command = _LineSplited[0];
|
||||
|
||||
// This commands are always possible:
|
||||
if(command == "SYST")
|
||||
{
|
||||
_Client.println("215 UNIX Type: L8");
|
||||
_Line = "";
|
||||
return true;
|
||||
}
|
||||
else if(command == "QUIT")
|
||||
{
|
||||
_Client.println("221 Goodbye");
|
||||
_Client.stop();
|
||||
_Line = "";
|
||||
return true;
|
||||
}
|
||||
else if(command == "ABOR")
|
||||
{
|
||||
for(std::shared_ptr<FTPCommandTransfer> cmd: _FTPCommandsTransfer)
|
||||
{
|
||||
cmd->abort();
|
||||
}
|
||||
_Client.println("226 Data connection closed");
|
||||
_Line = "";
|
||||
return true;
|
||||
}
|
||||
|
||||
// Logged in?
|
||||
switch (_ClientState)
|
||||
{
|
||||
case Idle:
|
||||
if(command == "USER")
|
||||
{
|
||||
c_USER();
|
||||
}
|
||||
break;
|
||||
|
||||
case UsernamePass:
|
||||
if(command == "PASS")
|
||||
{
|
||||
c_PASS();
|
||||
}
|
||||
break;
|
||||
|
||||
case AuthPass:
|
||||
{
|
||||
std::vector<std::shared_ptr<FTPCommand>>::iterator cmdIter = std::find_if(_FTPCommands.begin(), _FTPCommands.end(), [&](std::shared_ptr<FTPCommand> cmd)
|
||||
{
|
||||
if(command == cmd->getName() || (cmd->getName() == "RN" && (command == "RNFR" || command == "RNTO")))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
);
|
||||
if(cmdIter != _FTPCommands.end())
|
||||
{
|
||||
(*cmdIter)->run(_WorkDirectory, _LineSplited);
|
||||
_Line = "";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
_Client.println("500 Unknow command");
|
||||
break;
|
||||
}
|
||||
_Line = "";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FTPConnection::connected()
|
||||
{
|
||||
return _Client.connected();
|
||||
}
|
||||
|
||||
void FTPConnection::c_USER()
|
||||
{
|
||||
String username = _LineSplited[1];
|
||||
std::list<FTPUser>::iterator userIter = std::find_if(_UserList.begin(), _UserList.end(), [&](const FTPUser & user)
|
||||
{
|
||||
if(username == user.Username)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
);
|
||||
if(userIter != _UserList.end())
|
||||
{
|
||||
_AuthUsername = username;
|
||||
_Client.println("331 OK. Password required");
|
||||
_ClientState = UsernamePass;
|
||||
return;
|
||||
}
|
||||
_Client.println("530 user not found");
|
||||
}
|
||||
|
||||
void FTPConnection::c_PASS()
|
||||
{
|
||||
String password = _LineSplited[1];
|
||||
String username = _AuthUsername;
|
||||
std::list<FTPUser>::iterator _user = std::find_if(_UserList.begin(), _UserList.end(), [&](const FTPUser & user)
|
||||
{
|
||||
if(username == user.Username && password == user.Password)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
);
|
||||
if(_user != _UserList.end())
|
||||
{
|
||||
_Client.println("230 OK.");
|
||||
_ClientState = AuthPass;
|
||||
return;
|
||||
}
|
||||
_Client.println("530 passwort not correct");
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
#ifndef FTP_CONNECTION_H_
|
||||
#define FTP_CONNECTION_H_
|
||||
|
||||
#include <vector>
|
||||
#include <WiFiServer.h>
|
||||
#include "FTPPath.h"
|
||||
#include "FTPCommand.h"
|
||||
|
||||
#define FTP_CTRL_PORT 21
|
||||
#define FTP_USER_TIME_OUT 5
|
||||
#define FTP_CMD_SIZE 255 + 8 // max size of a command
|
||||
#define FTP_DIRNAME_SIZE 255 + 8 // max size of a directory name
|
||||
#define FTP_FILENAME_SIZE 255 // max size of a file name
|
||||
|
||||
class FTPConnection
|
||||
{
|
||||
public:
|
||||
FTPConnection(const WiFiClient & Client, std::list<FTPUser> & UserList, FTPFilesystem & Filesystem);
|
||||
virtual ~FTPConnection();
|
||||
|
||||
bool readUntilLineEnd();
|
||||
|
||||
bool handle();
|
||||
|
||||
bool connected();
|
||||
|
||||
|
||||
private:
|
||||
enum ClientState
|
||||
{
|
||||
Idle,
|
||||
UsernamePass,
|
||||
AuthPass,
|
||||
};
|
||||
|
||||
void c_USER();
|
||||
void c_PASS();
|
||||
|
||||
ClientState _ClientState;
|
||||
WiFiClient _Client;
|
||||
FTPFilesystem & _Filesystem;
|
||||
String _FilePath;
|
||||
|
||||
String _Line;
|
||||
std::vector<String> _LineSplited;
|
||||
|
||||
std::list<FTPUser> & _UserList;
|
||||
String _AuthUsername;
|
||||
|
||||
IPAddress _DataAddress;
|
||||
int _DataPort;
|
||||
|
||||
FTPPath _WorkDirectory;
|
||||
|
||||
std::vector<std::shared_ptr<FTPCommand>> _FTPCommands;
|
||||
std::vector<std::shared_ptr<FTPCommandTransfer>> _FTPCommandsTransfer;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,120 +0,0 @@
|
|||
#include "FTPFilesystem.h"
|
||||
#include "common.h"
|
||||
|
||||
FTPFilesystem::FTPFilesystem()
|
||||
{
|
||||
}
|
||||
|
||||
FTPFilesystem::~FTPFilesystem()
|
||||
{
|
||||
}
|
||||
|
||||
void FTPFilesystem::addFilesystem(String Name, FS * const Filesystem)
|
||||
{
|
||||
_Filesystems[Name] = Filesystem;
|
||||
}
|
||||
|
||||
void FTPFilesystem::clearFilesystemList()
|
||||
{
|
||||
_Filesystems.clear();
|
||||
}
|
||||
|
||||
File FTPFilesystem::open(const String & path, const char* mode)
|
||||
{
|
||||
if(path == "/")
|
||||
{
|
||||
std::shared_ptr<FTPFileImpl> root = std::shared_ptr<FTPFileImpl>(new FTPFileImpl("/"));
|
||||
for(auto const & f: _Filesystems)
|
||||
{
|
||||
root->addFilesystem(f.first);
|
||||
}
|
||||
return File(root);
|
||||
}
|
||||
FS * fs = getFilesystem(path);
|
||||
return fs->open(getPathWithoutFS(path), mode);
|
||||
}
|
||||
|
||||
bool FTPFilesystem::exists(const String & path)
|
||||
{
|
||||
FS * fs = getFilesystem(path);
|
||||
if(fs == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return fs->exists(getPathWithoutFS(path));
|
||||
}
|
||||
|
||||
bool FTPFilesystem::remove(const String & path)
|
||||
{
|
||||
FS * fs = getFilesystem(path);
|
||||
if(fs == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return fs->remove(getPathWithoutFS(path));
|
||||
}
|
||||
|
||||
bool FTPFilesystem::rename(const String & pathFrom, const String & pathTo)
|
||||
{
|
||||
FS * fsFrom = getFilesystem(pathFrom);
|
||||
FS * fsTo = getFilesystem(pathTo);
|
||||
if(fsFrom == 0 || fsTo == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(fsFrom != fsTo)
|
||||
{
|
||||
// cant move/rename from one filesystem to another one!
|
||||
return false;
|
||||
}
|
||||
return fsFrom->rename(getPathWithoutFS(pathFrom), getPathWithoutFS(pathTo));
|
||||
}
|
||||
|
||||
bool FTPFilesystem::mkdir(const String & path)
|
||||
{
|
||||
FS * fs = getFilesystem(path);
|
||||
if(fs == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return fs->mkdir(getPathWithoutFS(path));
|
||||
}
|
||||
|
||||
bool FTPFilesystem::rmdir(const String & path)
|
||||
{
|
||||
FS * fs = getFilesystem(path);
|
||||
if(fs == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return fs->rmdir(getPathWithoutFS(path));
|
||||
}
|
||||
|
||||
void FTPFilesystem::printFilesystems()
|
||||
{
|
||||
for (auto const & fs: _Filesystems)
|
||||
{
|
||||
Serial.println(fs.first);
|
||||
}
|
||||
}
|
||||
|
||||
FS * FTPFilesystem::getFilesystem(String path)
|
||||
{
|
||||
std::list<String> splitted = FTPPath::splitPath(path);
|
||||
String name = *(splitted.begin());
|
||||
std::map<String, fs::FS *>::iterator iter = _Filesystems.find(name);
|
||||
if(iter == _Filesystems.end())
|
||||
{
|
||||
Serial.println("[ERROR] Filesystem not found!");
|
||||
return 0;
|
||||
}
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
String FTPFilesystem::getPathWithoutFS(String path)
|
||||
{
|
||||
std::list<String> splitted = FTPPath::splitPath(path);
|
||||
splitted.pop_front();
|
||||
String path_without = FTPPath::createPath(splitted);
|
||||
return path_without;
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
#ifndef FTP_FILESYSTEM_H_
|
||||
#define FTP_FILESYSTEM_H_
|
||||
|
||||
#include <map>
|
||||
#include <FS.h>
|
||||
#include <FSImpl.h>
|
||||
#include "FTPPath.h"
|
||||
|
||||
class FTPFilesystem
|
||||
{
|
||||
public:
|
||||
FTPFilesystem();
|
||||
virtual ~FTPFilesystem();
|
||||
|
||||
void addFilesystem(String Name, FS * const Filesystem);
|
||||
void clearFilesystemList();
|
||||
|
||||
File open(const String & path, const char* mode = FILE_READ);
|
||||
bool exists(const String & path);
|
||||
bool remove(const String & path);
|
||||
bool rename(const String & pathFrom, const String & pathTo);
|
||||
bool mkdir(const String & path);
|
||||
bool rmdir(const String & path);
|
||||
|
||||
void printFilesystems();
|
||||
|
||||
#ifndef UNIT_TEST
|
||||
private:
|
||||
#endif
|
||||
FS * getFilesystem(String path);
|
||||
static String getPathWithoutFS(String path);
|
||||
|
||||
std::map<String, FS *> _Filesystems;
|
||||
};
|
||||
|
||||
class FTPFileImpl : public fs::FileImpl
|
||||
{
|
||||
public:
|
||||
explicit FTPFileImpl(String name) : _Name(name) {}
|
||||
~FTPFileImpl() {}
|
||||
size_t write(const uint8_t *buf, size_t size) override { return 0; };
|
||||
size_t read(uint8_t* buf, size_t size) override { return 0; };
|
||||
void flush() override {};
|
||||
bool seek(uint32_t pos, SeekMode mode) override { return false; };
|
||||
size_t position() const override { return 0; };
|
||||
size_t size() const override { return 0; };
|
||||
void close() override {};
|
||||
time_t getLastWrite() override { return 0; };
|
||||
const char* name() const override { return _Name.c_str(); };
|
||||
boolean isDirectory(void) override { return true; };
|
||||
fs::FileImplPtr openNextFile(const char* mode) override
|
||||
{
|
||||
if(_Filesystems.empty())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
String next = _Filesystems.front();
|
||||
_Filesystems.pop_front();
|
||||
return fs::FileImplPtr(new FTPFileImpl(next));
|
||||
}
|
||||
void rewindDirectory(void) override {};
|
||||
operator bool() override { return false; };
|
||||
|
||||
void addFilesystem(String name) { _Filesystems.push_back(name); }
|
||||
private:
|
||||
String _Name;
|
||||
std::list<String> _Filesystems;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,75 +0,0 @@
|
|||
#include "FTPPath.h"
|
||||
#include "common.h"
|
||||
|
||||
FTPPath::FTPPath()
|
||||
{
|
||||
}
|
||||
|
||||
FTPPath::FTPPath(String path)
|
||||
{
|
||||
changePath(path);
|
||||
}
|
||||
|
||||
FTPPath::~FTPPath()
|
||||
{
|
||||
}
|
||||
|
||||
void FTPPath::changePath(String path)
|
||||
{
|
||||
std::list<String> p = splitPath(path);
|
||||
std::copy(p.begin(), p.end(), std::back_inserter(_Path));
|
||||
}
|
||||
|
||||
void FTPPath::goPathUp()
|
||||
{
|
||||
_Path.pop_back();
|
||||
}
|
||||
|
||||
String FTPPath::getPath() const
|
||||
{
|
||||
return createPath(_Path);
|
||||
}
|
||||
|
||||
String FTPPath::getFilePath(String filename) const
|
||||
{
|
||||
if(*filename.begin() == '/')
|
||||
{
|
||||
return filename;
|
||||
}
|
||||
if(_Path.size() == 0)
|
||||
{
|
||||
return "/" + filename;
|
||||
}
|
||||
return getPath() + "/" + filename;
|
||||
}
|
||||
|
||||
std::list<String> FTPPath::splitPath(String path)
|
||||
{
|
||||
std::list<String> p = Split<std::list<String>>(path, '/');
|
||||
p.erase(
|
||||
std::remove_if(p.begin(), p.end(), [](const String & s)
|
||||
{
|
||||
if(s.isEmpty())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}),
|
||||
p.end());
|
||||
return p;
|
||||
}
|
||||
|
||||
String FTPPath::createPath(std::list<String> path)
|
||||
{
|
||||
if(path.size() == 0)
|
||||
{
|
||||
return "/";
|
||||
}
|
||||
String new_path;
|
||||
for(const String & p: path)
|
||||
{
|
||||
new_path += "/";
|
||||
new_path += p;
|
||||
}
|
||||
return new_path;
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
#ifndef FTP_PATH_H_
|
||||
#define FTP_PATH_H_
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <list>
|
||||
|
||||
class FTPPath
|
||||
{
|
||||
public:
|
||||
FTPPath();
|
||||
explicit FTPPath(String path);
|
||||
virtual ~FTPPath();
|
||||
|
||||
void changePath(String path);
|
||||
void goPathUp();
|
||||
|
||||
String getPath() const;
|
||||
String getFilePath(String filename) const;
|
||||
|
||||
static std::list<String> splitPath(String path);
|
||||
static String createPath(std::list<String> path);
|
||||
|
||||
private:
|
||||
std::list<String> _Path;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,14 +0,0 @@
|
|||
#ifndef FTP_USER_H_
|
||||
#define FTP_USER_H_
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
class FTPUser
|
||||
{
|
||||
public:
|
||||
FTPUser(const String & username, const String & password) : Username(username), Password(password) {}
|
||||
const String Username;
|
||||
const String Password;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,22 +0,0 @@
|
|||
#include "common.h"
|
||||
|
||||
/*
|
||||
template <typename T>
|
||||
T Split(String str, char parser)
|
||||
{
|
||||
T str_array;
|
||||
int last_idx = 0;
|
||||
int next_idx = str.indexOf(parser, last_idx);
|
||||
do
|
||||
{
|
||||
str_array.push_back(str.substring(last_idx, next_idx));
|
||||
last_idx = next_idx + 1;
|
||||
next_idx = str.indexOf(parser, last_idx);
|
||||
if(next_idx == -1 && last_idx != 0)
|
||||
{
|
||||
str_array.push_back(str.substring(last_idx, str.length()));
|
||||
}
|
||||
} while (next_idx != -1);
|
||||
return str_array;
|
||||
}
|
||||
*/
|
|
@ -1,27 +0,0 @@
|
|||
#ifndef COMMON_H_
|
||||
#define COMMON_H_
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
template <typename T>
|
||||
T Split(String str, char parser)
|
||||
{
|
||||
T str_array;
|
||||
int last_idx = 0;
|
||||
int next_idx = str.indexOf(parser, last_idx);
|
||||
do
|
||||
{
|
||||
str_array.push_back(str.substring(last_idx, next_idx));
|
||||
last_idx = next_idx + 1;
|
||||
next_idx = str.indexOf(parser, last_idx);
|
||||
if(next_idx == -1 && last_idx != 0)
|
||||
{
|
||||
str_array.push_back(str.substring(last_idx, str.length()));
|
||||
}
|
||||
} while (next_idx != -1);
|
||||
return str_array;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -12,7 +12,7 @@ lib_deps =
|
|||
sandeepmistry/LoRa @ 0.7.2
|
||||
peterus/APRS-Decoder-Lib @ 0.0.5
|
||||
peterus/APRS-IS-Lib @ 0.0.7
|
||||
peterus/ESP-FTP-Server-Lib @ 0.9.2
|
||||
peterus/ESP-FTP-Server-Lib @ 0.9.3
|
||||
peterus/LoRa-APRS-Lib @ 0.0.5
|
||||
check_tool = cppcheck
|
||||
check_flags =
|
||||
|
|
Ładowanie…
Reference in New Issue