Search code examples
c++cftpstm32mbed

How Can I Setup a FTP-Client Connection on embedded device?


I work on a FTP script for a mbed project. I work with the B-L475E-IOT01A development board and try to send a file to a FTP-Server. Therefore I cant establish a connection with the server with this libary https://os.mbed.com/users/dkato/code/ftp-client/#e069c405c934. Unfortunaly the client doesnt work like it should work. I try to establish connection like this:

bool FTPClient::open(const char* ip_addr, int port, const char* user, const char* pass)
{
    SocketAddress ftpAddress(ip_addr, port);

    //Connect to SocketAddress while using FTP Clients Network interface
    FTPClientControlSock.open(p_network);
    if (FTPClientControlSock.connect(ftpAddress) < 0) {
        printf("ERROR: %s(%d)\r\n", __FILE__, __LINE__);
        return false;
    }

    //recieve ftp server message
    if (FTPClientControlSock.recv(p_ftp_buf, FTP_BUF_SIZE) <= 0) {
        printf("ERROR: %s(%d)\r\n", __FILE__, __LINE__);
        return false;
    }

    //prove ftp server message equals ftp server information messages (starting with not logged in code 220)
    if (strncmp(p_ftp_buf, "220", 3) != 0) {
        printf("ERROR: %s(%d)\r\n", __FILE__, __LINE__);
        return false;
    }

    //store user info in ftp communication and send it
    sprintf(p_ftp_buf, "USER %s\r\n", user);
    printf("%s", p_ftp_buf);
    FTPClientControlSock.send(p_ftp_buf, strlen(p_ftp_buf));

    //recieve ftp server info and print it
    if (FTPClientControlSock.recv(p_ftp_buf, FTP_BUF_SIZE) <= 0) {
        printf("ERROR: %s(%d)\r\n", __FILE__, __LINE__);
        return false;
    }
    printf("%s", p_ftp_buf);

    //prove ftp server message equals ftp server information messages (begin with code 331)
    if (strncmp(p_ftp_buf, "331", 3) != 0) {
        printf("ERROR: %s(%d)\r\n", __FILE__, __LINE__);
        return false;
    }

    //store password in string and send it to server
    sprintf(p_ftp_buf, "PASS %s\r\n", pass);
    printf("%s", p_ftp_buf);
    FTPClientControlSock.send(p_ftp_buf, strlen(p_ftp_buf));

    //recieve ftp server info and print it
    if (FTPClientControlSock.recv(p_ftp_buf, FTP_BUF_SIZE) <= 0) {
        printf("ERROR: %s(%d)\r\n", __FILE__, __LINE__);
        return false;
    }

    //check login was successful
    if (strncmp(p_ftp_buf, "230", 3) != 0) {
        printf("ERROR: %s(%d)\r\n", __FILE__, __LINE__);
        return false;
    }

    printf("%s", p_ftp_buf);
    return true;
}

On the Terminal after this i get an output like this in the console:

220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
220-You are user number 4 of 500 allowed.
220-Local time is now 02:42. Server port: 21.
220-This is a private system - No anonymous login
220 You will be disconnected after 15 minutes of inactivity.
USER user
PASS pass
331 User user OK. Password required
is now 02:42. Server port: 21.
220-This is a private system - No anonymous login
220 You will be disconnected after 15 minutes of inactivity.
ERROR: ./ftp-client/FTPClient.cpp(96) //this is the line where the code 230 gets checked

I dont know really where my mistake is. I expected a successful login and a clear communication to the ftp server. Can you help me pls?


Solution

  • Julien, all the responses from the server follow a pattern.. you need to wait for a \r\n sequence from the server. You need to filter TELNET protocol escape sequences (that start with the byte 0xff or 0xfe, I don't remember from my head) and the codes must be always at the beginning of a line. Also the numbers with a - instead of a space indicate that the message is larger and you should expect another line (the last line of each message has a numeric code followed by a space)

    This is essential to maintain yourself synchronized with the server.... or you'll start receiving responses to different commands than the one you think.

    From the output it is not clear what you try to do, as the only thing you show is the login part to the server.

    Your command lines also have (this is mandatory by the protocol) to end in a sequence \r\n (in that order) you cannot do else, or you can reach a server that doesn't understand you.

    Check RFC-959 - File Transfer Protocol for details on how the ftp protocol works. The transfers are normally handled in a new, different TCP connection, so you normally have to manage the control connection plus a series of data transfers that run in parallel with it.