Page 1 of 2
FTP Get File help
Posted: Wed Nov 02, 2011 12:56 pm
by Musco
I have been working on a project with the goal of accessing an FTP server and downloading files to update various devices, as well as the Netburner itself. The trouble I am running in to is when I try to download the file from the server. I start off by establishing a connection with the FTP server, followed by the FTPGetFileNames function (which works). Upon using the FTPGetFile function, the return value is -4 (COMMANDFAIL or COMMANDERROR). Any insight would be much appreciated as to what causes this error return value.
Re: FTP Get File help
Posted: Wed Nov 02, 2011 1:09 pm
by rnixon
Is this with the FTP client example code?
Re: FTP Get File help
Posted: Wed Nov 16, 2011 12:54 pm
by Musco
My apologies for not responding earlier. I am running a custom program with FTP client functionality. I was able to fix the problems I was receiving with the error codes. I have hit another bump in the road. I can download the bin file to the netburner but now I would like to save it to the on board flash file system. I have reviewed the EFFS-STD example and went ahead and allocated enough flash memory for the file system. Now I would like to take the input stream data received from the FTPGetFile function and store it into a file.
Re: FTP Get File help
Posted: Fri Nov 18, 2011 11:05 am
by Musco
Update:
I have been taking the following steps to find a possible solution:
1. Establish FTP connection and use FTPGetFile to get file from FTP server.
2. In order to read returned FD from FTPGetFile, I use a similar function to that of FTPD_GetFileFromClient from ftp_f.cpp in example EFFS-STD-HTTP.
3. Write buffer that FD was read into to a file in the file system.
When using ReadWithTimeout, it looks to have read the entire FD then returns -1. What type of failure causes this return value? Any help would be much appreciated, thanks!
Re: FTP Get File help
Posted: Fri Nov 18, 2011 2:41 pm
by greengene
if i'm understanding what you're doing, you are trying to read a file stored in
the effs file system by using ReadWithTimeout() - that's not gonna work.
to read/write the EFFS files, you need to use the EFFS commands, e.g.,
fs_read()/fs_write().
Re: FTP Get File help
Posted: Mon Nov 21, 2011 6:55 am
by Musco
Thanks for the response.
What I am trying to read with ReadWithTimeout() is the file descriptor returned from the FTPGetFile function. After reading that into a buffer, I will then write it to a file in the file system using fs_write. I'm assuming this is the easiest way to get a file from an FTP site stored in the netburner's file system but if I'm wrong, please point me in the right direction.
Re: FTP Get File help
Posted: Mon Nov 21, 2011 9:02 am
by greengene
ok, i was assuming the worst, but it looks like you are almost there.
i expect that the return code of -1 is EOF on trying to read past the
end of file. so as in the example, return > 0 is byte count, 0 is timeout,
and an unspecified -1 appear to be the standard EOF.
i'd just go with that since it appears to be working.
Re: FTP Get File help
Posted: Tue Nov 22, 2011 12:12 pm
by Musco
I still can't quite figure out why the read returns -1. I'm using code copied directly from the EFFS-STD-HTTP example. The GetFileFromClient() function does almost exactly what i want to do except in my case, the Netburner is acting as the FTP client and receiving a file from an FTP server. Here is the code I am using to read the file descriptor returned from FTPGetFile() and then write to a file in the netburner's flash file system.
Code: Select all
#define FTP_BUFFER_SIZE ( 500 * 1024 )
static char FTP_buffer[FTP_BUFFER_SIZE] __attribute__( ( aligned( 16 ) ) );
int ftp = FTP_InitializeSession( AsciiToIp( SERVER_IP_ADDR ),
FTP_PORT,
USER,
PASS,
200 );
if ( ftp > 0 ) // if the var ftp is > 0, it is the session handle
{
int fd = FTPGetFile(ftp, fileName, TRUE, 5 * TICKS_PER_SECOND);
if(fd > 0)
{
wfile = fs_open( fileName, "w+" );
int bytes_read;
int bytes_written;
int retry;
int FtpBufIndex = 0; // position in buffer
/* This loop will read the file data from the client, accumulate
* data until FTP_BUFFER_SIZE is reached, then write the data to
* flash in one write.
*/
do
{
bytes_read = ReadWithTimeout( fd, FTP_buffer + FtpBufIndex,
FTP_BUFFER_SIZE - FtpBufIndex,
TICKS_PER_SECOND * 20 );
iprintf("Bytes read: %d\r\n", bytes_read );
if ( bytes_read > 0 )
{
FtpBufIndex += bytes_read;
iprintf( "FtpBufIndex: %d\r\n", FtpBufIndex );
}
if ( FtpBufIndex == FTP_BUFFER_SIZE )
{
bytes_written = 0;
retry = 0;
do {
// buffer, size of item, number of items, file handle
bytes_written = fs_write( FTP_buffer, 1, FtpBufIndex, wfile );
iprintf("bytes_written: %d\r\n", bytes_written);
if ( bytes_written < FtpBufIndex )
{
iprintf("Retry: %d\r\n", retry);
OSTimeDly( TICKS_PER_SECOND / 4 );
retry++;
}
} while ( (bytes_written < FtpBufIndex) && ( retry < 10 ) );
FtpBufIndex = 0;
}
} while ( ( bytes_read > 0 ) && ( retry < 10 ) );
if ( retry >= 10 )
{
iprintf("Error - could not write file: %s\r\n", file_name);
do {
bytes_read = ReadWithTimeout( fd, FTP_buffer, FTP_BUFFER_SIZE, TICKS_PER_SECOND * 2 );
//iprintf("Bytes read: %d\r\n", bytes_read );
} while ( bytes_read > 0 );
fs_close( wfile );
fs_delete( file_name );
return ( FTPD_FAIL );
}
iprintf("FtpBufIndex: %d\r\n", FtpBufIndex);
if ( FtpBufIndex )
{
bytes_written = fs_write( FTP_buffer, 1, FtpBufIndex, wfile );
iprintf( "wrote %d bytes\r\n", bytes_written );
if ( bytes_written < FtpBufIndex )
{
iprintf("Error - could not write file: %s\r\n", file_name);
do {
bytes_read = ReadWithTimeout( fd, FTP_buffer, FTP_BUFFER_SIZE, TICKS_PER_SECOND * 2 );
//iprintf("Bytes read: %d\r\n", bytes_read );
} while ( bytes_read > 0 );
fs_close( wfile );
fs_delete( file_name );
return ( FTPD_FAIL );
}
}
fs_close( wfile );
return( FTPD_OK );
}
}
Re: FTP Get File help
Posted: Tue Nov 22, 2011 1:18 pm
by rnixon
Saw this on the ftp get manual page, but not sure if it is the cause of the prob you are having:
Important: After the file descriptor has been returned, you must call the FTPGetCommandResult function to get the result from the read. Warning: Failing to do this will cause the system to get out of sync. A return value of 226 is normal.
Re: FTP Get File help
Posted: Tue Nov 22, 2011 1:31 pm
by Musco
Oops I forgot to include that part of my code in the post... I do call that function after trying to read the file descriptor.
Code: Select all
close(fd);
rv = FTPGetCommandResult( ftp, tmp_resultbuff, 255, 5 * TICKS_PER_SECOND );
if ( rv != 226 )
{
sprintf(buffer,"\n\r1Error Command result = %d %s\r\n",rv,tmp_resultbuff);
writestring(fdDebugSerial,buffer);
}
}
I forgot to mention that the file I am trying to get using FTPGetFile() is a binary file with size about 131,000 bytes. I tested the same code using a 35 byte text file instead and it worked perfectly.