Large File transfer-- FTP lwIP 1.4.1 Chat Conversation End

Go To Last Post
2 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello to all, 

Currently I'm working on a project that need to have the option to transfer a CSV file (1gb) to a client machine. Since the board that I'm using SAM4E ARM® Cortex®-M4 has a provided http library by the vendor using raw API lwIP, I''ve decided to try out implementing a FTP server. 

I've found several FTP servers on Internet, perfectly working example from RTOS but it was no build on lwIP. some netconn examples provided by NXP but that I didn't had the time to test it out. 
The current FTP that I'm trying to make working is using raw API and FatFs file system which is perfectly suitable for me. 
Unfortunately, I have been studying and testing raw API and lwIP, but I've been stuck in a problem for so long that I can't think of a way to tackle it anymore!

I've manage to connect to my laptop form the embedded device and receive the TCP three handshake  and send commands, but unfortunately the main goal is far away. :)

In attachments are files from my wireshark captures and a screen shot from the command prompt in Windows machine.

The problems comes from the tcp_sndbuf becoming 0 after the first packet is send. 
From the wireshark file you can observe that the last packet from the server is with a FIN flag, but the complete file is not send.

Both functions that are used to send the file. 

static void send_file(struct ftpd_datastate *fsd, struct tcp_pcb *pcb)   
{   
    FRESULT rc;
    
    if (!fsd->connected) 
    {  
        return;  
    }

    if (fsd->fil) 
    {
        UINT len;
    
        if (sfifo_space(&fsd->fifo) < (DATACONNECT_BUFFER_SIZE - 2))
        {  
            send_data(pcb, fsd);   
            return; 
        }

        rc = f_read(fsd->fil, buffer_x, sizeof (buffer_x), &len);
//        rc = f_read(fsd->fil, buffer_x, 100, &len);
        if (rc || (len == 0)) 
        {
            f_close(fsd->fil);
            fsd->fil = NULL;
            return;
        }
    
        sfifo_write(&fsd->fifo, buffer_x, len);
        send_data(pcb, fsd);
           
        if (sfifo_used(&fsd->fifo) < 1024)
        {  
            send_data(pcb, fsd);   
            return; 
        }

        rc = f_read(fsd->fil, buffer_x, sfifo_space(&fsd->fifo), &len);
        if (rc || (len == 0)) 
        {
            f_close(fsd->fil);
            fsd->fil = NULL;
            return;
        
        }
    
        sfifo_write(&fsd->fifo, buffer_x, len);

    } 
    else 
    {
        struct ftpd_msgstate *fsm;   
        struct tcp_pcb *msgpcb;   
        if (sfifo_used(&fsd->fifo) > 0) 
        {   
            send_data(pcb, fsd);   
            return;   
        }  
    
        fsm = fsd->msgfs;   
        msgpcb = fsd->msgpcb;   

        f_close(fsd->fil);        
        fsd->fil = NULL;  
        ftpd_dataclose(pcb, fsd); 
        fsm->datapcb = NULL;   
        fsm->datafs = NULL;   
        fsm->state = FTPD_IDLE;   
        send_msg(msgpcb, fsm, msg226);   
    }
    return; 
}

static void send_data(struct tcp_pcb *pcb, struct ftpd_datastate *fsd)  
{  
    err_t err;  
    u16_t len;  
    int i;
    if (sfifo_used(&fsd->fifo) > 0) 
    {   
        if (tcp_sndbuf(pcb) < sfifo_used(&fsd->fifo)) 
        {   
            len = tcp_sndbuf(pcb);   
        } 
        else 
        {   
            len = (u16_t)sfifo_used(&fsd->fifo);   
        }  
        i = fsd->fifo.readpos;   
        if ((i + len) > fsd->fifo.size) 
        {  
            err = tcp_write(pcb, fsd->fifo.buffer + i, (u16_t)(fsd->fifo.size - i), 1);   
            if (err != ERR_OK)
            {   
                return;   
            }   
            len -= fsd->fifo.size - i;   
            fsd->fifo.readpos = 0;   
            i = 0;  
        } 
        err = tcp_write(pcb, fsd->fifo.buffer + i, len, 1);   
        if (err != ERR_OK) 
        {   
               return;   
        }   
           fsd->fifo.readpos += len; 
    }   
}

 

 

I'm familiar that raw API use callback functions that's why I'm having trouble understanding how exactly the  flow of the program goes. Maybe an advice or a example will be highly appreciate..

Any feedback on the function will be welcome!! 

KR,

Metio 

 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...