SimpleFTPServer icon indicating copy to clipboard operation
SimpleFTPServer copied to clipboard

ftplib can't access the root folder in ESP32/ESP32C3

Open firminxu opened this issue 1 year ago • 6 comments

Hello! Firstly, thanks for the the your good job, I can build my ftp sever easily. I have used version 2.1.7 with my ESP32/ESP32C3 device in PlatformIO environment for a while, it works well. After update it to 2.1.8, I can't access root folder of SD. after I rolled back to 2.1.7, it works again. I tested it with below python code. It will print names of all the files in SD card if it worked.

from ftplib import FTP
def download_and_delete_log_csv_files(host, user, password, remote_dir, local_dir):
    with FTP(host) as ftp:
        try:
            # Attempt to login to the FTP server
            ftp.login(user=user, passwd=password)
            print("Login successful.")
            # Change the current working directory on the server
            ftp.cwd(remote_dir)
            print(f"Changed working directory to {remote_dir}.")

            # Explicitly set passive mode
            ftp.set_pasv(True)

            # Get a list of all files in the remote directory
            files = []
            ftp.retrlines('LIST', lambda line: files.append(line))

            # Print all files in the directory
            print("Files in the remote directory:")
            for file_info in files:
                filename = file_info.split(None, 8)[-1]  # Simplify extracting the filename
                print(filename)

        except Exception as e:
            # Handle any exceptions that occur during the process
            print(f"An error occurred: {e}")

host = '192.168.229.145'
user = 'esp8266'
password = 'esp8266'
remote_dir = '/'  # Directory on the FTP server
local_dir = r'D:\temp'  # Local directory

# Call the function to download and delete log CSV files
download_and_delete_log_csv_files(host, user, password, remote_dir, local_dir)

firminxu avatar Jul 19 '24 05:07 firminxu

Hi firminxu, do you have some log to send me? Thanks Renzo

xreef avatar Jul 20 '24 15:07 xreef

Hi Xreef, When it works in version 2.1.7. below is my code in PlatformIO, Similar to example,

#include <Arduino.h>
#include <SD.h>
#include <FS.h>
#include <SPI.h>
#include <SimpleFTPServer.h>
#include <WiFi.h>

const char *ssid = "xxx";
const char *password = "xxxxxxxx";
int retryCount = 0;

// define SD
const int CS = 23;
const int SCKPin = 16;
const int MOSIPin = 17;
const int MISOPin = 2;

File myFile;
FtpServer ftpSrv;

void _callback(FtpOperation ftpOperation, unsigned int freeSpace, unsigned int totalSpace)
{
  Serial.print(">>>>>>>>>>>>>>> _callback ");
  Serial.print(ftpOperation);
  /* FTP_CONNECT,
   * FTP_DISCONNECT,
   * FTP_FREE_SPACE_CHANGE
   */
  Serial.print(" ");
  Serial.print(freeSpace);
  Serial.print(" ");
  Serial.println(totalSpace);

  // freeSpace : totalSpace = x : 360

  if (ftpOperation == FTP_CONNECT)
    Serial.println(F("CONNECTED"));
  if (ftpOperation == FTP_DISCONNECT)
    Serial.println(F("DISCONNECTED"));
};

void _transferCallback(FtpTransferOperation ftpOperation, const char *name, unsigned int transferredSize)
{
  Serial.print(">>>>>>>>>>>>>>> _transferCallback ");
  Serial.print(ftpOperation);
  /* FTP_UPLOAD_START = 0,
   * FTP_UPLOAD = 1,
   *
   * FTP_DOWNLOAD_START = 2,
   * FTP_DOWNLOAD = 3,
   *
   * FTP_TRANSFER_STOP = 4,
   * FTP_DOWNLOAD_STOP = 4,
   * FTP_UPLOAD_STOP = 4,
   *
   * FTP_TRANSFER_ERROR = 5,
   * FTP_DOWNLOAD_ERROR = 5,
   * FTP_UPLOAD_ERROR = 5
   */
  Serial.print(" ");
  Serial.print(name);
  Serial.print(" ");
  Serial.println(transferredSize);
};
void setup()
{
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  SPI.begin(SCKPin, MISOPin, MOSIPin, CS);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(1000);
    Serial.println("Connecting to WiFi...");
    retryCount++;
    if (retryCount > 10)
    {
      Serial.println("Failed to connect to WiFi");
      break;
    }
  }

  if (WiFi.status() == WL_CONNECTED) 
  {
    Serial.println("Connected to the WiFi network"); 
    Serial.print("IP address:");
    Serial.println(WiFi.localIP());
  }
  while (!Serial)
  {
    ;
  }
  if (!SD.begin(CS))
  {
    Serial.println("initialization failed!");
    return;
  }
  else
  {
    Serial.println("SD card initialization succeeded.");
  }
  myFile = SD.open("/example.txt", FILE_WRITE);
  if (myFile)
  {
    Serial.println("Writing to example.txt");
    myFile.println("Hello, FTP Server!");
    myFile.close();
    Serial.println("Done writing to example.txt");
  }
  else
  {
    Serial.println("error opening example.txt");
  }
  ftpSrv.setCallback(_callback);
  ftpSrv.setTransferCallback(_transferCallback);
  ftpSrv.begin("esp8266", "esp8266");
}

void loop()
{
  ftpSrv.handleFTP();
}

platformIO.ini is as below

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps = xreef/[email protected]

and #define DEFAULT_STORAGE_TYPE_ESP32 STORAGE_SD in FtpServerKey,h. when I run python code I posted, I got

Login successful.
Changed working directory to /.
Files in the remote directory:
Volume Information
example.txt

firminxu avatar Jul 23 '24 07:07 firminxu

When it works in version 2.1.8. All code is the same as above. platformio.ini is as below:

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps = xreef/[email protected]

when I run python code I posted, I got 530 error

Login successful.
Changed working directory to /.
An error occurred: 530 

firminxu avatar Jul 23 '24 07:07 firminxu

I have a similar issue - ESP8266/Arduino 2.3.2 - using FileZilla it sometimes connects and gets the directory once and after that error message as follows:

Status:	Connecting to 192.168.51.47:21...
Status:	Connection established, waiting for welcome message...
Status:	Plain FTP is insecure. Please switch to FTP over TLS.
Status:	Server does not support non-ASCII characters.
Status:	Logged in
Status:	Retrieving directory listing...
Command:	PWD
Response:	211-Extensions supported:
Response:	 MLST type*;modify*;size*;
Response:	 MLSD
Response:	 MDTM
Response:	 MFMT
Response:	 UTF8
Response:	 SIZE
Response:	 SITE FREE
Response:	211 End.
Error:	Failed to parse returned path.
Error:	Failed to retrieve directory listing

Reverting to previous version (2.1.7) resolves the problem.

amgrays avatar Aug 11 '24 21:08 amgrays

same here with Arduino core 3.x, esp32-S3, esp32-c3 and LittleFS example esp8266_esp32_LittleFS

esp log show this

[ 12709][E][vfs_api.cpp:23] open(): File system is not mounted

FTP client shows this

Status:	Logged in
Status:	Retrieving directory listing of "/"...
Command:	CWD /
Response:	550 / not found.
Error:	Failed to retrieve directory listing
Status:	Retrieving directory listing of "/"...
Command:	CWD /
Response:	550 / not found.
Error:	Failed to retrieve directory listing
Status:	Retrieving directory listing of "/"...
Command:	CWD /

vortigont avatar Aug 28 '24 14:08 vortigont

I have had the same issue. I had thought it was because my ftpserver runs in a separate task, but building the ardunio_esp32_sd example I got the same issue and also the same mounting error. Looking through the ftpserverkey.h file I found the problem. The default store for esp32 in version 2.1.8 is STORAGE_FFAT and not STORAGE_SD. Simply change the default storage type to STORAGE_SD and you should be good.

Relevant section from ftpserverkey.h file in the simpleftpserver library source code as follows:

// esp32 configuration #ifndef DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP32 #define DEFAULT_FTP_SERVER_NETWORK_TYPE_ESP32 NETWORK_ESP32 #define DEFAULT_STORAGE_TYPE_ESP32 STORAGE_SD // STORAGE_FFAT /**

Should say this makes the windows ftp client work perfectly . However still can't get Andftp or other android apps to connect for some reason.

ifrew avatar Sep 07 '24 18:09 ifrew