This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PROCESSOR-SDK-AMIC110: FTP transfer succeed in some files but fail in some files

Part Number: PROCESSOR-SDK-AMIC110
Other Parts Discussed in Thread: AMIC110

Hi,

I am using ndk_3_61_01_01 to implement FTP in AMIC110.

Now I am facing a problem that FTP works well in transferring some files but it fails when transferring some files.

FTP connection is ok but it looks data transferring has some problem.

In the failure cases, the return value of (int)recvnc(ioh->data_socket, (void**)&(ioh->DataBuf), 0, &hBuffer) is -1, then I get the error code from fdError() is 22.

From serrno.h, it shows the meaning of error code 22 is invalid argument.

I don't understand what "invalid argument" means and also don't understand why there is no problem in transferring some files but fails in some files.

Does anyone has the similar issue? Any idea?

Thank you in advance.

Kind regards,

Sandro

  • Hi Sandro,

    Is the FTP application from Processor SDK release?  (nimu/example/ftpAPP)? or something different?

    Have you checked if power cycle/restarting the application for the fail cases still result in failure for those files?

    What is the Processor SDK release you are using? Is it 6.3?

    Thanks

  • Hi Aravind,

    The FTP application is modified from ti\pdk_am335x_1_0_17\packages\ti\transport\ndk\nimu\example\ftpApp.

    We refer to the sample code of FoE, then modify ftp_filerout_write() in ftp_filerout.cpp to receive the firmware file.

    Yes, file transfer always fails after power cycle for those files.

    Below is the PDK/NDK I use now.

    Thank you.

  • Hi Sandro,

    Thanks.. Can you share the files that fail FTP connection? Also the modifications that you have done on ftp_filerout.c file (I assume you have a typo for the source file as the CPP extension, since there is no C++ source file from the Processor SDK example.

    Have you tried to single step NDK and tried to understand why is NDK reporting invalid arguments? Why a successful transfer does not have this issue?

    Please let me know.

    Thanks

  • Hi Aravind,

    I attach two source files which are related to FTP application. A source file with cpp extension is because I call some cpp functions in it.

    I use FTP to transfer two files (.bin file), one is always success and the other always fails. I zip them because .bin files are not able to be attached here. AMIC.bin can be transferred successfully and FPGA.bin always fails.

    I trace the code in order to understand why NDK report error but I am stopped in NDK_recvnc() because I can not open its declaration, so I never try to single step in NDK_recvnc(). But I will try single step in NDK_recvnc() to see what happen.

    Thank you.

     /**
      * Include files
      */
    #include "ti/transport/ndk/nimu/example/ftpApp/modules.h"
    
    #if 1
    
    #include <ti/csl/csl_error.h>
    #include <ti/fs/fatfs/ff.h>
    #include <ti/transport/ndk/nimu/example/ftpApp/ftpserver/ftpserver.h>
    #include "FW_Update.h"
    /**
     * Local functions
     */
    static int32_t func_opts (io_handler_t *ioh);
    static int32_t func_user (io_handler_t *ioh);
    static int32_t func_pass (io_handler_t *ioh);
    static int32_t func_stor (io_handler_t *ioh);
    static int32_t func_dele (io_handler_t *ioh);
    static int32_t func_xrmd (io_handler_t *ioh);
    static int32_t func_cwd (io_handler_t *ioh);
    static int32_t func_xpwd (io_handler_t *ioh);
    static int32_t func_retr (io_handler_t *ioh);
    static int32_t func_list (io_handler_t *ioh);
    static int32_t func_port (io_handler_t *ioh);
    static int32_t func_nlst (io_handler_t *ioh);
    static int32_t func_quit (io_handler_t *ioh);
    static int32_t func_noop (io_handler_t *ioh);
    static int32_t func_syst (io_handler_t *ioh);
    static int32_t func_type (io_handler_t *ioh);
    static int32_t func_pwd  (io_handler_t *ioh);
    static int32_t func_size (io_handler_t *ioh);
    static int32_t func_pasv (io_handler_t *ioh);
    /**
     * Local variables
     */
    ftp_cmd_handler_t cmd_handler[] =
    {
        {"OPTS", 4, func_opts },
        {"USER", 4, func_user },
        {"PASS", 4, func_pass },
        {"STOR", 4, func_stor },
        {"DELE", 4, func_dele },
        {"XRMD", 4, func_xrmd },
        {"CWD",  3, func_cwd },
        {"XPWD", 4, func_xpwd },
        {"RETR", 4, func_retr },
        {"LIST", 4, func_list },
        {"PORT", 4, func_port },
        {"NLST", 4, func_nlst },
        {"LIST", 4, func_nlst },
        {"QUIT", 4, func_quit },
        {"SYST", 4, func_syst },
        {"TYPE", 4, func_type },
        {"PWD",  3, func_pwd },
        {"noop", 4, func_noop },
        {"PASV", 4, func_pasv },
        {"SIZE", 4, func_size },
        {NULL, 0, NULL }
    };
    
    extern char ftpUser[NAME_AND_PASSWD_LEN];
    extern char ftpPassword[NAME_AND_PASSWD_LEN];
    
    /**
     * @brief  Return second argument from input string.
     */
    static void argument_collector(char *_buffer, char  *_nameBuffer)
    {
        /* TODO: Use malloc */
        char bf[1024];
        char sep[2] = " ";
        char *word;
        int32_t  wcount=0;
    
        strcpy(bf, _buffer);
        for (word = strtok(bf, sep);word;word = strtok(NULL, sep))
        {
            wcount++;
            if(wcount == 2)
            {
                strcpy(_nameBuffer, word);
            }
        }
    }
    
    /**
     * check_authentificated
     */
    static boolean_t check_authentificated (io_handler_t *ioh)
    {
        if (!ioh->authenticated)
        {
            sprintf(ioh->send_buffer,"530 Please log in with USER and PASS first. \r\n");
            send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
            return FALSE;
        }
    
        return TRUE;
    }
    
    /**
     * func_opts
     */
    static int32_t func_opts (io_handler_t *ioh)
    {
        int32_t bytes;
    
        argument_collector (ioh->receive_buffer, ioh->temp);
    
        sprintf(ioh->send_buffer,"530 Please log in with USER and PASS first.\r\n");
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
    
        if (bytes > 0) return ERROR_SUCCESS;
        return -1;
    }
    
    
    /**
     * func_user
     */
    static int32_t func_user (io_handler_t *ioh)
    {
        int32_t bytes;
    
        argument_collector (ioh->receive_buffer, ioh->user);
    
        sprintf(ioh->send_buffer,"331 Password required \r\n");
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
    
        if (bytes > 0) return ERROR_SUCCESS;
        return -1;
    }
    
    /**
     * func_pass
     */
    static int32_t func_pass (io_handler_t *ioh)
    {
        int32_t bytes;
    
        argument_collector (ioh->receive_buffer, ioh->password);
        if (strcmp (ioh->user, ftpUser) == 0 && strcmp (ioh->password, ftpPassword) == 0)
        {
            sprintf(ioh->send_buffer,"230 Public login successful \r\n");
            bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
            if (bytes < 0) return -1;
            ioh->authenticated = 1;
        }
        else
        {
            sprintf(ioh->send_buffer,"530 Invalid username or password \r\n");
            bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
            if (bytes < 0) return -1;
            ioh->authenticated = 0;
        }
    
        if (bytes > 0) return ERROR_SUCCESS;
        return -1;
    }
    
    /**
     * func_dele
     */
    static int32_t func_dele (io_handler_t *ioh)
    {
        int32_t bytes;
        char path[64];
    
        if (!check_authentificated (ioh)) return -1;
        argument_collector(ioh->receive_buffer, path);
    
        if(0)
        {
            sprintf(ioh->send_buffer, "550 File not found\r\n");
        }
        else
        {
            sprintf(ioh->send_buffer, "200 Ok\r\n");
        }
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
    
        if (bytes > 0) return ERROR_SUCCESS;
        return -1;
    }
    
    /**
     * func_xrmd
     */
    static int32_t func_xrmd (io_handler_t *ioh)
    {
        int32_t bytes;
        char path[64];
    
        if (!check_authentificated (ioh)) return -1;
        argument_collector(ioh->receive_buffer, path);
    
        if (0)
        {
            sprintf(ioh->send_buffer, "550 Directory not found\r\n");
        }
        else
        {
            sprintf(ioh->send_buffer, "200 Ok\r\n");
        }
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
    
        if (bytes > 0) return ERROR_SUCCESS;
        return -1;
    }
    
    /**
     * func_stor
     */
    uint32_t Write_Adr = 0;
    static int32_t func_stor (io_handler_t *ioh)
    {
        int32_t bytes;
        char filename[64];
    
        if (!check_authentificated (ioh)) return -1;
    
        argument_collector(ioh->receive_buffer, filename);
    
        sprintf(ioh->send_buffer,"150 OK\r\n");
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
        // Reset the Writing Address of Flash Programming
        Write_Adr = 0;
    
        if (ftp_filerout_write (ioh, filename) == 0)
        {
            sprintf(ioh->send_buffer, "226 File transfer completed\r\n");
        }
        else
        {
            sprintf(ioh->send_buffer, "450 Requested file action not taken\r\n");
        }
    
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
        if (bytes > 0) return ERROR_SUCCESS;
    
        return -1;
    }
    
    /**
     * func_cwd
     */
    static int32_t func_cwd (io_handler_t *ioh)
    {
        int32_t bytes;
        char path[64];
    
        if (!check_authentificated (ioh)) return -1;
        argument_collector(ioh->receive_buffer, path);
        strcpy(ioh->current_working_dir_path, path);
        if (1)
        {
            sprintf(ioh->send_buffer, "250 CWD successful. /%s is current directory\r\n", ioh->current_working_dir_path);
        }
        else
        {
            sprintf(ioh->send_buffer, "550 CWD failed.\r\n");
        }
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
    
        if (bytes > 0) return ERROR_SUCCESS;
        return -1;
    }
    
    /**
     * func_xpwd
     */
    static int32_t func_xpwd (io_handler_t *ioh)
    {
        int32_t bytes;
        if (!check_authentificated (ioh)) return -1;
    
        sprintf(ioh->send_buffer, "257 \"%s\" is current directory\r\n", ioh->current_working_dir_path);
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
        if (bytes > 0) return ERROR_SUCCESS;
        return -1;
    }
    
    /**
     * func_retr
     */
    static int32_t func_retr (io_handler_t *ioh)
    {
        int32_t bytes;
        char filename[64];
        if (!check_authentificated (ioh)) return -1;
    
        argument_collector(ioh->receive_buffer, filename);
    
        sprintf(ioh->send_buffer,"150 Transfering... \r\n");
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
    
        if (ftp_filerout_read (ioh, filename) == CSL_SOK)
        {
            sprintf(ioh->send_buffer,"226 File transfer completed... \r\n");
        }
        else
        {
            sprintf(ioh->send_buffer,"450 Requested file action not taken\r\n");
        }
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
    
        fdClose(ioh->data_socket);
    
        if (bytes > 0) return ERROR_SUCCESS;
        return -1;
    }
    
    /**
     * func_list
     */
    static int32_t func_list (io_handler_t *ioh)
    {
        int32_t bytes;
        // Get file list from flash (AMIC)
    
    
        if (!check_authentificated(ioh))
            return -1;
    
        sprintf(ioh->send_buffer, "150 Transfering... \r\n");
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
        if(strcmp(ioh->current_working_dir_path,"/") == 0)
        {
    
        strcpy(FileListString, "07-01-2020 19:17:39 <DIR> AMIC110\r\n07-01-2020 19:17:39 <DIR> DSP\r\n07-01-2020 19:17:39 <DIR> FPGA\r\n");
        }
        else if (strcmp(ioh->current_working_dir_path, "/AMIC110" )== 0)
        {
            Get_FileString_AMIC();
        }
        else if (strcmp(ioh->current_working_dir_path, "/DSP" )== 0)
        {
            strcpy(FileListString, "07-01-2020 19:17:39 1234567 CPU01.bin\r\n07-01-2020 19:17:39 1234567 CPU02.bin\r\n");
        }
        else if (strcmp(ioh->current_working_dir_path, "/FPGA") == 0)
        {
            strcpy(FileListString, "07-01-2020 19:17:39 765445 FPGA_00.00.3\r\n");
        }
        // Send list contents via Data socket
        send(ioh->data_socket, FileListString, strlen(FileListString), 0);
    
        sprintf(ioh->send_buffer, "226 File transfer completed... \r\n");
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
    
        fdClose(ioh->data_socket);
    
        if (bytes > 0)
            return ERROR_SUCCESS;
        return -1;
    }
    
    /**
     * func_port
     */
    static int32_t func_port (io_handler_t *ioh)
    {
        int act_port[2];
        int act_ip[4], port_dec;
        char ip_decimal[40];
        struct sockaddr_in remoteaddr_act;
        int32_t bytes;
    
        if (!check_authentificated (ioh)) return -1;
    
        if (ioh->data_socket) fdClose(ioh->data_socket);
        ioh->data_socket = socket(AF_INET, SOCK_STREAMNC, IPPROTO_TCP);
    
        /* local variables */
        sscanf(ioh->receive_buffer, "PORT %d,%d,%d,%d,%d,%d", &act_ip[0], &act_ip[1], &act_ip[2], &act_ip[3], &act_port[0], &act_port[1]);
        sprintf(ip_decimal, "%d.%d.%d.%d", act_ip[0], act_ip[1], act_ip[2],act_ip[3]);
        port_dec = (act_port[0] * 256) + act_port[1];
    
        /* Prepare address for connect */
        memset( &remoteaddr_act,0, sizeof(struct sockaddr_in) );
        remoteaddr_act.sin_family = AF_INET;
        remoteaddr_act.sin_addr.s_addr = inet_addr(ip_decimal);
        remoteaddr_act.sin_port = NDK_htons(port_dec);
    
        if (connect (ioh->data_socket, (struct sockaddr *)&remoteaddr_act, (int32_t) sizeof(struct sockaddr_in)) == SOCKET_ERROR)
        {
            sprintf(ioh->send_buffer, "425 Something is wrong, can't start the active connection... \r\n");
            bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
            fdClose(ioh->data_socket);
        }
        else
        {
            sprintf(ioh->send_buffer, "200 Ok\r\n");
            bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
        }
    
        if (bytes > 0) return ERROR_SUCCESS;
        return -1;
    }
    
    /**
     * func_nlst
     */
    static int32_t func_nlst (io_handler_t *ioh)
    {
        //char *buffer;
        int32_t bytes;
    
        // Get file list from flash (AMIC)
        Get_FileString_AMIC();
    
        if (!check_authentificated(ioh))
            return -1;
    
        sprintf(ioh->send_buffer, "150 Transfering... \r\n");
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
        strcpy(FileListString, "AMIC110<DIR>\r\nDSP<DIR>\r\nFPGA<DIR>\r\n");
        // Send list contents via Data socket
        send(ioh->data_socket, FileListString, strlen(FileListString), 0);
    
        sprintf(ioh->send_buffer, "226 File transfer completed... \r\n");
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
    
        fdClose(ioh->data_socket);
    
        if (bytes > 0) return ERROR_SUCCESS;
        return -1;
    }
    
    /**
     * func_quit
     */
    static int32_t func_quit (io_handler_t *ioh)
    {
        int32_t bytes;
        sprintf(ioh->send_buffer,"221 Connection closed by the FTP client\r\n");
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
    
        ioh->running = FALSE;
    
        if (bytes > 0) return ERROR_SUCCESS;
        return -1;
    }
    /**
     * func_noop
     */
    static int32_t func_noop (io_handler_t *ioh)
    {
        int32_t bytes;
    
        if (!check_authentificated (ioh)) return -1;
    
        sprintf(ioh->send_buffer, "200 Ok\r\n");
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
    
    
        if (bytes > 0) return ERROR_SUCCESS;
        return -1;
    }
    /**
     * func_syst
     */
    static int32_t func_syst (io_handler_t *ioh)
    {
        int32_t bytes;
    
        if (!check_authentificated (ioh)) return -1;
    
        sprintf(ioh->send_buffer, "215 TI-RTOS system type.\r\n");
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
    
    
        if (bytes > 0) return ERROR_SUCCESS;
        return -1;
    }
    /**
     * func_pwd
     */
    static int32_t func_pwd (io_handler_t *ioh)
    {
        int32_t bytes;
    
        if (!check_authentificated (ioh)) return -1;
    
        sprintf(ioh->send_buffer, "257 %s is current directory..\r\n", ioh->current_working_dir_path);
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
    
    
        if (bytes > 0) return ERROR_SUCCESS;
        return -1;
    }
    /**
     * func_type
     */
    static int32_t func_type (io_handler_t *ioh)
    {
        char Type;
        int32_t bytes;
    
        if (!check_authentificated (ioh)) return -1;
    
        /* local variables */
        if(ioh->receive_buffer[5] == 'I' || ioh->receive_buffer[5] == 'A') {
            sprintf(ioh->send_buffer, "200 Command okay.\r\n");
        }
        else
        {
            sprintf(ioh->send_buffer, "504 Command not implemented for that parameter.\r\n");
        }
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
    
        if (bytes > 0) return ERROR_SUCCESS;
        return -1;
    }
    /**
     * func_size
     */
    static int32_t func_size (io_handler_t *ioh)
    {
        int32_t bytes;
    
        if (!check_authentificated (ioh)) return -1;
    
        sprintf(ioh->send_buffer, "550 Requested action not taken.\r\n");
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
    
    
        if (bytes > 0) return ERROR_SUCCESS;
        return -1;
    }
    /**
     * func_pasv
     */
    static int32_t func_pasv (io_handler_t *ioh)
    {
        int act_port[2];
        int act_ip[4], port_dec;
        char ip_decimal[40];
        struct sockaddr_in remoteaddr_act,client_addr;
        int32_t bytes;
        int len = sizeof(struct sockaddr_in);
        if (!check_authentificated (ioh)) return -1;
    
        //if (ioh->data_socket) fdClose(ioh->data_socket);
        sprintf(ioh->send_buffer, "227 Entering Passive Mode (192,168,1,4,0,20).\r\n");
        bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
        if( (ioh->data_socket = accept(ioh->data_socket, (struct sockaddr*)&client_addr, &len)) == INVALID_SOCKET)
        {
            /* Timeout, Wait a short time and try again */
            fdClose (ioh->socket);
            return;
        }
        /*ioh->data_socket = socket(AF_INET, SOCK_STREAMNC, IPPROTO_TCP);
    
    
        port_dec = 20;
    
    
        memset( &remoteaddr_act,0, sizeof(struct sockaddr_in) );
        remoteaddr_act.sin_family = AF_INET;
        remoteaddr_act.sin_addr.s_addr = NDK_htonl(INADDR_ANY);
        remoteaddr_act.sin_port = NDK_htons(port_dec);
    
    
        if (bind(ioh->data_socket, (struct sockaddr*)&remoteaddr_act, sizeof(struct sockaddr_in)) == SOCKET_ERROR)
        {
            fdClose(ioh->data_socket);
            return;
        }
    
        if (listen(ioh->data_socket, 5) == SOCKET_ERROR)
        {
            fdClose(ioh->data_socket);
            return;
        }*/
        /* Set listen timeout to make watchdog work */
        /*timeout.tv_sec = 10000;
            if (setsockopt(ioh->data_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == SOCKET_ERROR)
            {
                fdClose(ioh->data_socket);
                return;
            }*/
    
        //if (connect (ioh->data_socket, (struct sockaddr *)&remoteaddr_act, (int32_t) sizeof(struct sockaddr_in)) == SOCKET_ERROR)
        /*if (ioh->data_socket = accept (ioh->data_socket, (struct sockaddr *)&remoteaddr_act, &len) == INVALID_SOCKET)
        {
            sprintf(ioh->send_buffer, "421 Service not available, closing control connection. \r\n");
            bytes = send(ioh->socket, ioh->send_buffer, strlen(ioh->send_buffer), 0);
            fdClose(ioh->data_socket);
        }
        else
        {*/
    
            /*ftp_get_file_list();
            data_send = send(ioh->data_socket, FileListString, strlen(FileListString), 0);
            fdClose(ioh->data_socket);*/
        //}
    
        if (bytes > 0) return ERROR_SUCCESS;
        return -1;
    }
    #endif
    

    ftp_filerout.cpp

    FPGA_ftp_fail.zip

    AMIC_ftp_ok.zip

  • Hi Aravind,

    I try to step in NDK function but not able to understand more because of assembly with registers.

  • Hi Sandro,

    You do not need to step into assembly function. As you see on the left side, the CCS debugger is asking for you to provide the source file from NDK. You can click "Locate File" and provide the source file.

    Then CCS latches to that file for your future debugging on that source file. You don't need to provide the source file location everytime.

    Also, it would be better if you rebuild NDK with optimizations turned off.

    Here is the thread talking about how to rebuild NDK.

    https://e2e.ti.com/support/processors-group/processors/f/processors-forum/947275/faq-how-do-you-rebuild-the-ndk

    Please note that I may not be able to debug your source files. I will try when (if) I get some time - it may take a while.

    So, suggest you to try with rebuild NDK and debug on what might be happening inside NDK.

    Please share your findings.

    Thanks