ParticleFTPClient Library problems

I am using the ParticleFTPClient to send two files to a FileZilla Server. The first file is an ASCII and the second is binary.

The trace (below) shows both files are transferred, but the second file always has a zero length.

(000035)6/6/2018 23:16:31 PM - (not logged in) (72.189.203.172)> Connected on port 25, sending welcome message…
(000035)6/6/2018 23:16:31 PM - (not logged in) (72.189.203.172)> 220-FileZilla Server 0.9.60 beta
(000035)6/6/2018 23:16:31 PM - (not logged in) (72.189.203.172)> 220-written by Tim Kosse (tim.kosse@filezilla-project.org)
(000035)6/6/2018 23:16:31 PM - (not logged in) (72.189.203.172)> 220 Please visit https://filezilla-project.org/
(000035)6/6/2018 23:16:33 PM - (not logged in) (72.189.203.172)> USER aao
(000035)6/6/2018 23:16:33 PM - (not logged in) (72.189.203.172)> 331 Password required for aao
(000035)6/6/2018 23:16:34 PM - (not logged in) (72.189.203.172)> PASS ***
(000035)6/6/2018 23:16:34 PM - aao (72.189.203.172)> 230 Logged on
(000035)6/6/2018 23:16:35 PM - aao (72.189.203.172)> TYPE I
(000035)6/6/2018 23:16:35 PM - aao (72.189.203.172)> 200 Type set to I
(000035)6/6/2018 23:16:36 PM - aao (72.189.203.172)> PASV
(000035)6/6/2018 23:16:36 PM - aao (72.189.203.172)> 227 Entering Passive Mode (142,197,187,219,196,116)
(000035)6/6/2018 23:16:37 PM - aao (72.189.203.172)> STOR 1111_img07.jpg
(000035)6/6/2018 23:16:37 PM - aao (72.189.203.172)> 150 Opening data channel for file upload to server of “/1111_img07.jpg”
(000035)6/6/2018 23:16:38 PM - aao (72.189.203.172)> 226 Successfully transferred “/1111_img07.jpg”
(000035)6/6/2018 23:16:39 PM - aao (72.189.203.172)> QUIT
(000035)6/6/2018 23:16:39 PM - aao (72.189.203.172)> 221 Goodbye
(000035)6/6/2018 23:16:39 PM - aao (72.189.203.172)> disconnected.
(000036)6/6/2018 23:16:40 PM - (not logged in) (72.189.203.172)> Connected on port 25, sending welcome message…
(000036)6/6/2018 23:16:40 PM - (not logged in) (72.189.203.172)> 220-FileZilla Server 0.9.60 beta
(000036)6/6/2018 23:16:40 PM - (not logged in) (72.189.203.172)> 220-written by Tim Kosse (tim.kosse@filezilla-project.org)
(000036)6/6/2018 23:16:40 PM - (not logged in) (72.189.203.172)> 220 Please visit https://filezilla-project.org/
(000036)6/6/2018 23:16:41 PM - (not logged in) (72.189.203.172)> USER aao
(000036)6/6/2018 23:16:41 PM - (not logged in) (72.189.203.172)> 331 Password required for aao
(000036)6/6/2018 23:16:42 PM - (not logged in) (72.189.203.172)> PASS ***
(000036)6/6/2018 23:16:42 PM - aao (72.189.203.172)> 230 Logged on
(000036)6/6/2018 23:16:43 PM - aao (72.189.203.172)> TYPE A
(000036)6/6/2018 23:16:43 PM - aao (72.189.203.172)> 200 Type set to A
(000036)6/6/2018 23:16:44 PM - aao (72.189.203.172)> PASV
(000036)6/6/2018 23:16:44 PM - aao (72.189.203.172)> 227 Entering Passive Mode (142,197,187,219,197,196)
(000036)6/6/2018 23:16:45 PM - aao (72.189.203.172)> STOR 1111_TTC_Profile_7.scn
(000036)6/6/2018 23:16:45 PM - aao (72.189.203.172)> 150 Opening data channel for file upload to server of “/1111_TTC_Profile_7.scn”
(000036)6/6/2018 23:16:46 PM - aao (72.189.203.172)> 226 Successfully transferred “/1111_TTC_Profile_7.scn”
(000036)6/6/2018 23:16:47 PM - aao (72.189.203.172)> QUIT
(000036)6/6/2018 23:16:47 PM - aao (72.189.203.172)> 221 Goodbye
(000036)6/6/2018 23:16:47 PM - aao (72.189.203.172)> disconnected.

If I switch the sequence of sending, the first file always transfers correctly whereas the second file always has a zero length. So this is not related to the file type or a firewall issue. I tried this on a Raspberry PI proFTPD server with the exact same result. I am assuming then it must be either the library or my client code.

I would appreciate the community’s help. My code for sending the files is below:

void ftpProfile(int tranType, String file2SND)
{
  if (ftpFiles == 1)
  {
    pubQueue.Publish("SendFile", file2SND);

    myFile.open(file2SND, O_READ);
    int data;
    long int now = millis();
    //---------------------------------------------------------
    //http://www.nsftools.com/tips/RawFTP.htm
    if (ftp.open(hostname, port, timeout))
    {
      ftp.user(username);
      ftp.pass(password);
      if (tranType == 0) ftp.type("A");    //ASCII
      if (tranType == 1) ftp.type("I");    //Binary
      ftp.stor(file2SND);
    }
    else
    {
      Particle.publish("FTP Error", "Cannot login");
    } //ftp.open
    //----------------------------------------------
    //long int now = millis();
    byte clientBuf[ftpChunk];
    int clientCount = 0;
    while (myFile.available())
    {
      clientBuf[clientCount] = myFile.read();
      clientCount++;
      if (clientCount > (ftpChunk - 1))
      {
        ftp.data.write(clientBuf, ftpChunk);
        clientCount = 0;
      }
    }
    // here is where the extra bytes are sent if the file isn't an exact multiple of 64 bytes.
    if (clientCount > 0) ftp.data.write(clientBuf, clientCount);
    
    ftp.finish();
    //----------------------------------------------
    long int sendTime = millis() - now;

    //ftp.data.flush();    
    ftp.quit();         
    //-------------------
    Particle.publish("Profile FTP: " , ("$$,11," + String(baseNum) + ","  + String(file2SND) + "," + String(sendTime / 1000) + " sec," + "^"));

  } //ftpFiles
}
1 Like

I’d try to add a ftp.data.flush() call before ftp.finish().

But if you want to know where things are failing - or actually all the time - it’s better practice to actually check the return values of the functions you are calling whether the call was successful or not.

Thank you @ScruffR.

I traced the problem to this statement:

while (myFile.available())

What does this do? Why is the first file “available” but not the second file. I am sure both files are on the disk because when switching the sequence of sending the two files, the file that was not “available” was sent fine …

I found the solution from the SDFat library manual.

myFile cannot be a global variable.

So a statement like this is needed:

void ftpProfile(int tranType, String file2SND)
{
if (ftpFiles == 1)
{
pubQueue.Publish(“SendFile”, file2SND);

**SdFile myNewFile;**