Skip to content

Commit

Permalink
Add FTP passive mode, server port, remove directory function
Browse files Browse the repository at this point in the history
Some FTP server doesn't allow files exchange in active mode. Passive mode can solve this problem.
Passive mode is enable by default.
  • Loading branch information
tryhus committed Jan 9, 2019
1 parent 30de202 commit 810e98c
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 25 deletions.
22 changes: 12 additions & 10 deletions examples/FTP/FTP.ino
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ void setup() {
void loop() {

Serial.println("Connect to FTP server.");
if (ftp.connect(SECRET_FTP_HOST, SECRET_FTP_USER, SECRET_FTP_PASSWORD) == false) {
if (ftp.connect(SECRET_FTP_HOST, SECRET_FTP_USER, SECRET_FTP_PASSWORD, SECRET_FTP_PORT) == false) {
Serial.println("Failed to Connect to FTP server.");
}

Expand All @@ -71,14 +71,14 @@ void loop() {
Serial.print("Free space ");
Serial.println(fileSystem.freeSpace());

Serial.println("Create remote file : test");
Serial.println("Create remote directory : test");
if (ftp.mkdir("test") == false) {
Serial.println("Failed to create the file.");
Serial.println("Failed to create the directory.");
}

Serial.println("Rename remote file : test to test2");
Serial.println("Rename remote directory : test to test2");
if (ftp.rename("test", "test2") == false) {
Serial.println("Failed to rename the file.");
Serial.println("Failed to rename the directory.");
}

Serial.println("Write a binary file in local memory");
Expand All @@ -87,15 +87,17 @@ void loop() {
if (fileSystem.write("myFile", &valueWR, sizeof(valueWR)) == false) {
Serial.println("Failed to write file");
}

Serial.println("Send the file to the server");
if (ftp.upload("myFile", "myFileToServer") == false) {
Serial.println("Failed to upload the file.");
ftp.printError();
}

Serial.println("Retreive the file from the server to local memory");
if (ftp.download("myFileToServer", "myFileToLocalMemory") == false) {
Serial.println("Failed to download the file.");
ftp.printError();
}

Serial.println("Check that the original file is identical to the one that was received");
Expand Down Expand Up @@ -129,11 +131,11 @@ void loop() {
Serial.println("Failed to display files.");
}

Serial.println("Delete the created files");
if (ftp.remove("test2") == false) {
Serial.println("Delete the created file and directory");
if (ftp.removeDirectory("test2") == false) {
Serial.println("Failed to remove files : test2.");
}
if (ftp.remove("myFileToServer") == false) {
if (ftp.removeFile("myFileToServer") == false) {
Serial.println("Failed to remove files : myFileToServer.");
}

Expand Down
11 changes: 6 additions & 5 deletions examples/FTP/arduino_secrets.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#define SECRET_PINNUMBER ""
#define SECRET_GPRS_APN "" // replace your GPRS APN
#define SECRET_GPRS_LOGIN "" // replace with your GPRS login
#define SECRET_GPRS_LOGIN "" // replace with your GPRS login
#define SECRET_GPRS_PASSWORD "" // replace with your GPRS password

#define SECRET_FTP_HOST "" // replace with your FTP host server
#define SECRET_FTP_USER "" // replace with your FTP user
#define SECRET_FTP_PASSWORD "" // replace with your FTP password
#define SECRET_FTP_REMOTE_DIR "/" // replace with your FTP default remote directory
#define SECRET_FTP_HOST "" // replace with your FTP host server
#define SECRET_FTP_USER "" // replace with your FTP user
#define SECRET_FTP_PASSWORD "" // replace with your FTP password
#define SECRET_FTP_PORT 21 // replace with your FTP port (optional)
#define SECRET_FTP_REMOTE_DIR "/" // replace with your FTP default remote directory
64 changes: 59 additions & 5 deletions src/GSMFTP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ GSMFTP::~GSMFTP()
_file.clear();
}

bool GSMFTP::connect(String hostname, String user, String password)
bool GSMFTP::connect(String hostname, String user, String password, uint16_t port, bool passiveMode)
{
uint32_t start = millis();
String command;
Expand All @@ -57,7 +57,14 @@ bool GSMFTP::connect(String hostname, String user, String password)
return false;
}

MODEM.send("AT+UFTP=6,0");
command = (passiveMode == true) ? "AT+UFTP=6,1" : "AT+UFTP=6,0";
MODEM.send(command);
if (MODEM.waitForResponse(100) != 1) {
return false;
}

command = "AT+UFTP=7," + String(port);
MODEM.send(command);
if (MODEM.waitForResponse(100) != 1) {
return false;
}
Expand Down Expand Up @@ -163,7 +170,7 @@ bool GSMFTP::mkdir(const String& name, uint32_t timeout)
return false;
}

bool GSMFTP::remove(const String& name, uint32_t timeout)
bool GSMFTP::removeFile(const String& name, uint32_t timeout)
{
uint32_t start = millis();
if (_connected == false) {
Expand Down Expand Up @@ -192,6 +199,36 @@ bool GSMFTP::remove(const String& name, uint32_t timeout)
return false;
}

bool GSMFTP::removeDirectory(const String& name, uint32_t timeout)
{
uint32_t start = millis();
if (_connected == false) {
return false;
}

_dirRemoved = -2;
String command = "AT+UFTPC=11,\"" + name + "\"";

while ((millis() - start) < timeout) {
if (_dirRemoved == -2) {
_dirRemoved = -1;
MODEM.send(command);
if (MODEM.waitForResponse(100) != 1) {
return false;
}
}
MODEM.poll();
if (_dirRemoved == 0) {
_dirRemoved = -2;
MODEM.send(command);
}
else if (_dirRemoved == 1) {
return true;
}
}
return false;
}

bool GSMFTP::rename(const String& oldName, const String& name, uint32_t timeout)
{
uint32_t start = millis();
Expand Down Expand Up @@ -241,7 +278,6 @@ bool GSMFTP::download(const String& remoteFileName, const String& localFileName,
MODEM.poll();
if (_fileDownloaded == 0) {
_fileDownloaded = -2;
MODEM.send(command);
}
else if (_fileDownloaded == 1) {
return true;
Expand Down Expand Up @@ -270,7 +306,6 @@ bool GSMFTP::upload(const String& localFileName, const String& remoteFileName, u
MODEM.poll();
if (_fileUploaded == 0) {
_fileUploaded = -2;
MODEM.send(command);
}
else if (_fileUploaded == 1) {
return true;
Expand Down Expand Up @@ -308,6 +343,22 @@ bool GSMFTP::cd(const String& name, uint32_t timeout)
return false;
}

void GSMFTP::printError()
{
String res = "FTP last error : ";
String response;

MODEM.send("AT+UFTPER");

if ((MODEM.waitForResponse(1000, &response) == 1) &&
(response.startsWith("+UFTPER:"))) {
res += response.substring(8);
}else {
res += "no response";
}
Serial.println(res);
}

GSMFTP::FTPFileElem GSMFTP::file(uint16_t i)
{
if (i < _file.count) {
Expand Down Expand Up @@ -452,6 +503,9 @@ void GSMFTP::handleUrc(const String& urc)
else if (urc.startsWith("+UUFTPCR: 2,")) {
_fileRemoved = (urc.charAt(urc.lastIndexOf(",") + 1) == '1') ? 1 : 0;
}
else if (urc.startsWith("+UUFTPCR: 11,")) {
_dirRemoved = (urc.charAt(urc.lastIndexOf(",") + 1) == '1') ? 1 : 0;
}
else if (urc.startsWith("+UUFTPCR: 3,")) {
_fileRenamed = (urc.charAt(urc.lastIndexOf(",") + 1) == '1') ? 1 : 0;
}
Expand Down
27 changes: 22 additions & 5 deletions src/GSMFTP.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ class GSMFTP : public ModemUrcHandler {
@param hostname FTP server hostname
@param user FTP user name
@param password FTP password
@param port FTP server port
@param passiveMode true if passive mode is active
@return true if no error
*/
bool connect(String hostname, String user, String password);
bool connect(String hostname, String user, String password, uint16_t port, bool passiveMode=true);
/** Disconnect to the FTP server
@return true if no error
*/
Expand All @@ -74,12 +76,18 @@ class GSMFTP : public ModemUrcHandler {
@return true if no error
*/
bool mkdir(const String& name, uint32_t timeout=10000);
/** Delete directory on the FTP server
@param name name of the directory to delete
@param timeout maximum time allow to execute the function
@return true if no error
*/
bool removeDirectory(const String&, uint32_t timeout = 10000);
/** Delete file on the FTP server
@param name name of the file to delete
@param timeout maximum time allow to execute the function
@return true if no error
@param name name of the file to delete
@param timeout maximum time allow to execute the function
@return true if no error
*/
bool remove(const String&, uint32_t timeout = 10000);
bool removeFile(const String&, uint32_t timeout = 10000);
/** Rename file on the FTP server
@param oldName name of the file to rename
@param name new name of the file to rename
Expand Down Expand Up @@ -108,6 +116,14 @@ class GSMFTP : public ModemUrcHandler {
*/
bool upload(const String& localFileName, const String&remoteFileName, uint32_t timeout = 10000);

/** Print the error class and code of the last FTP operation
@brief
0,0 mean no error otherwise {error class},{error code}.
For the description refer to the documention :
https://www.u-blox.com/sites/default/files/u-blox-CEL_ATCommands_%28UBX-13002752%29.pdf
*/
void printError();

private:
static const uint32_t c_connectionTimeout = 10000;

Expand All @@ -132,6 +148,7 @@ class GSMFTP : public ModemUrcHandler {
int _dirCreated;
int _dirChanged;
int _fileRemoved;
int _dirRemoved;
int _fileRenamed;
int _fileDownloaded;
int _fileUploaded;
Expand Down

0 comments on commit 810e98c

Please sign in to comment.