Skip to content

Commit

Permalink
implemented download, check limitations
Browse files Browse the repository at this point in the history
  • Loading branch information
ldab committed Jul 31, 2019
1 parent 5aabdbc commit 45e7f02
Show file tree
Hide file tree
Showing 8 changed files with 199 additions and 6 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ cache:

env:
- PLATFORMIO_CI_SRC=examples/upload_image/upload_image.ino
- PLATFORMIO_CI_SRC=examples/download_file/download_file.ino

install:
- pip install -U platformio
Expand Down
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,27 @@ A FTP-Client for the ESP32

- [ ] List Dir contents test with different serves;
- [ ] Implement `FEAT` in order to choose which mode to list dir...
- [ ] Implement download;
- [x] Implement download;

## Free Website Hosting

* The idea behind this project is to `upload` the picture via FTP making it available on an URL something like: `www.mysite.com/my_picture.jpg`

* This way you don't need to overload the ESP32, your network remains secure, not open to the world, no port forwarding.

* For this example I uploaded the GitHub Octocat to my [000Webhost](https://www.000webhost.com/) hosted webiste, the file is avalable under: `https://my_user.000webhostapp.com/gallery_gen/XxXxXxXx.jpg`

## Limitation

* I was only able to download files up to ~90KB, as I can't see any usage for that, I did not spend extra time, as it's partially working.
* A new example under [download_file.ino](./examples/donload_file/download_file.ino) has been added;
* `ESP.getMaxAllocHeap()` returned limited amount of free memory, therefore the buffer can't hold the entire downloaded file.
* For this reason I have implemented the last argument of `DownloadFile(const char * filename, unsigned char * buf, size_t length, bool printUART )` which will print the buffer directly to the UART;
* If required, SPIFFS can be used to save the file.

As mentioned [here](https://github.com/espressif/arduino-esp32/issues/1163) and [here](https://github.com/espressif/esp-idf/issues/3497)

## Upload example

* For the uploading example we will use the GitHub Octocat, which binary file is [here](./src/octocat.h):

Expand Down
124 changes: 124 additions & 0 deletions examples/download_file/download_file.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/******************************************************************************
ESP32-CAM remote image access via FTP. Take pictures with ESP32 and upload it via FTP making it accessible for the outisde network.
Leonardo Bispo
July - 2019
https://github.com/ldab/ESP32_FTPClient
Distributed as-is; no warranty is given.
******************************************************************************/
#include "Arduino.h"
#include <WiFi.h>
#include <WiFiClient.h>
#include <ESP32_FTPClient.h>

#define WIFI_SSID ""
#define WIFI_PASS ""

char ftp_server[] = "files.000webhost.com";
char ftp_user[] = "";
char ftp_pass[] = "";

ESP32_FTPClient ftp (ftp_server,ftp_user,ftp_pass);

void setup()
{
Serial.begin( 115200 );

WiFi.begin( WIFI_SSID, WIFI_PASS );

Serial.println("Connecting Wifi...");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());

Serial.print("\nMax Free Heap: ");
Serial.println(ESP.getMaxAllocHeap());
Serial.println("");

ftp.OpenConnection();

//Change directory
ftp.ChangeWorkDir("/public_html/zyro/gallery_gen");

// Create a new file to use as the download example below:
ftp.InitFile("Type A");
ftp.NewFile("helloworld.txt");
ftp.Write("Hi, I'm a new file");
ftp.CloseFile();

//Download the text file or read it
String response = "";
ftp.InitFile("Type A");
ftp.DownloadString("helloworld.txt", response);
Serial.println("The file content is: " + response);

// Get the file size
const char * fileName = "myPhoto.png";
size_t fileSize = 0;
String list[128];

// Get the directory content in order to allocate buffer
// my server response is type=file;size=18;modify=20190731140703;unix.mode=0644;unix.uid=10183013;unix.gid=10183013;unique=809g7c8e92e4; helloworld.txt
ftp.InitFile("Type A");
ftp.ContentList("", list);
for( uint8_t i = 0; i < sizeof(list); i++)
{
uint8_t indexSize = 0;
uint8_t indexMod = 0;

if(list[i].length() > 0)
{
list[i].toLowerCase();

if( list[i].indexOf(fileName) > -1 )
{
indexSize = list[i].indexOf("size") + 5;
indexMod = list[i].indexOf("modify") - 1;

fileSize = list[i].substring(indexSize, indexMod).toInt();
}

// Print the directory details
Serial.println(list[i]);
}
else
break;
}

// Print file size
Serial.println("\nFile size is: " + String(fileSize));

//Dynammically alocate buffer
unsigned char * downloaded_file = (unsigned char *) malloc(fileSize);

// And download the file
ftp.InitFile("Type I");
ftp.DownloadFile(fileName, downloaded_file, fileSize, false);

//Create a new Directory
ftp.InitFile("Type I");
ftp.MakeDir("myNewDir");

//Enter the directory
ftp.ChangeWorkDir("/public_html/zyro/gallery_gen/myNewDir");

//And upload the file to the new directory
ftp.NewFile( fileName );
ftp.WriteData(downloaded_file, fileSize);
ftp.CloseFile();

free(downloaded_file);

ftp.CloseConnection();
}

void loop()
{

}
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "esp32_ftpclient",
"version": "0.0.2",
"version": "0.0.3",
"description": "A FTP-Client for the ESP32",
"keywords": "sensors, low power, mobile, ftp, web, cloud, iot, esp32, espressif",
"authors":
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=esp32_ftpclient
version=0.0.2
version=0.0.3
author=Leonardo Bispo
license=MIT
maintainer=Leonardo Bispo <[email protected]>
Expand Down
6 changes: 3 additions & 3 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
; https://docs.platformio.org/page/projectconf.html

[platformio]
env_default = esp32
src_dir = ./examples/upload_image
lib_dir = ./
default_envs = esp32
src_dir = ./examples/download_file
lib_dir = ./

[env:esp32]
platform = [email protected]
Expand Down
46 changes: 46 additions & 0 deletions src/ESP32_FTPClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ void ESP32_FTPClient::WriteClientBuffered(WiFiClient* cli, unsigned char * data,
void ESP32_FTPClient::GetFTPAnswer (char* result, int offsetStart) {
char thisByte;
outCount = 0;

while (!client.available()) delay(1);

while (client.available()) {
Expand Down Expand Up @@ -210,3 +211,48 @@ void ESP32_FTPClient::ContentList(const char * dir, String * list) {
}

}

void ESP32_FTPClient::DownloadString(const char * filename, String &str) {
Serial.println("Send RETR");
client.print(F("RETR "));
client.println(F(filename));

char _resp[ sizeof(outBuf) ];
GetFTPAnswer(_resp);

while( !GetDataClient()->available() ) delay(1);

while( GetDataClient()->available() )
{
str += GetDataClient()->readString();
}

}

void ESP32_FTPClient::DownloadFile(const char * filename, unsigned char * buf, size_t length, bool printUART ) {
Serial.println("Send RETR");
client.print(F("RETR "));
client.println(F(filename));

char _resp[ sizeof(outBuf) ];
GetFTPAnswer(_resp);

char _buf[2];

while( !dclient.available() ) delay(1);

while(dclient.available())
{
if( !printUART )
dclient.readBytes(buf, length);

else
{
for(size_t _b = 0; _b < length; _b++ )
{
dclient.readBytes(_buf, 1),
Serial.print(_buf[0], HEX);
}
}
}
}
2 changes: 2 additions & 0 deletions src/ESP32_FTPClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,6 @@ class ESP32_FTPClient
void DeleteFile(const char * file);
void MakeDir(const char * dir);
void ContentList(const char * dir, String * list);
void DownloadString(const char * filename, String &str);
void DownloadFile(const char * filename, unsigned char * buf, size_t length, bool printUART = false);
};

0 comments on commit 45e7f02

Please sign in to comment.