AnsweredAssumed Answered

Issue with upload of file to web server over HTTP

Question asked by samuel boivineau on Oct 15, 2015
Latest reply on Oct 22, 2015 by Carlos_Musich

Hello,

 

I am still evaluating the rtcs stack with the K64F120M and I am currently trying to get a flash over HTTP by sending the hex file from a web page.

 

First, is there any application note or example that I would have missed ?

 

I tried my implementation by using as base, the httpsrv example. So a function is called when using this form :

 

    <form enctype="multipart/form-data" action="http:flash.cgi" method="POST">
   <input type="hidden" name="MAX_FILE_SIZE" value="100000" />
   Choose a file to upload: <input name="uploadedfile" type="file" /><br />
   <input type="submit" value="Upload File" />

                   </form>

 

And here is this function :

It reads by chunk of 1024, and prints the 5 first bytes.

 

static _mqx_int cgi_flash(HTTPSRV_CGI_REQ_STRUCT* param)
{
    HTTPSRV_CGI_RES_STRUCT response = {0};
    char buffer[1024];
    uint32_t len = 0;
    uint32_t cnt = 0;
    volatile uint32_t initial_len = 0;
    uint32_t i = 0;

    if (param->request_method != HTTPSRV_REQ_POST)
    {
        return(0);
    }

    if(param->content_length)
    {
      initial_len = param->content_length;
      printf("cgi_flash : initial_len = %u\n", (unsigned int)initial_len);
      while(param->content_length>0)
      {
        len = HTTPSRV_cgi_read(param->ses_handle, buffer, (param->content_length > sizeof(buffer)) ? sizeof(buffer) : param->content_length);
        param->content_length -= len;
        cnt+=len;
        printf("HTTPSRV_cgi_read : %u octets (%u/%u) :", (unsigned int)len, (unsigned int)cnt, (unsigned int)initial_len);
        for(i=0; i<5; i++)
        {
            printf("0x%x ", buffer[i]);
        }
        printf("...\n");
      }
    }
    printf("File received, sending HTTP_OK\n");

    response.ses_handle = param->ses_handle;
    response.content_type = HTTPSRV_CONTENT_TYPE_PLAIN;
    response.status_code = HTTPSRV_CODE_OK;
    /*
    ** When the keep-alive is used we have to calculate a correct content length
    ** so the receiver knows when to ACK the data and continue with a next request.
    ** Please see RFC2616 section 4.4 for further details.
    */

    /* Calculate content length while saving it to buffer */
    response.data = NULL;
    response.data_length = param->content_length;
    response.content_length = response.data_length;
    /* Send response */
    HTTPSRV_cgi_write(&response);
    return (response.content_length);
}

 

Currently, when I am trying this solution with an example file of 100 bytes, it works.

With 5000 bytes, function HTTPSRV_cgi_read hangs after the third chunk, unless in firefox I hit the button to stop the loading, or even I close firefox. Then I got this result in two parts on the serial port :

 

cgi_flash : initial_len = 5306
HTTPSRV_cgi_read : 1024 octets (1024/5306) :0x2d 0x2d 0x2d 0x2d 0x2d ...
HTTPSRV_cgi_read : 1024 octets (2048/5306) :0x68 0x69 0x6a 0x6b 0x6c ...
HTTPSRV_cgi_read : 1024 octets (3072/5306) :0xa 0x31 0x62 0x63 0x64 ...
HTTPSRV_cgi_read : 1024 octets (4096/5306) :0x68 0x69 0x6a 0x6b 0x6c ...
[Here Firefox was closed]
HTTPSRV_cgi_read : 0 octets (4096/5306) :0x68 0x69 0x6a 0x6b 0x6c ...
HTTPSRV_cgi_read : 1024 octets (5120/5306) :0x6b 0x6c 0x6d 0x6e 0x6f ...
HTTPSRV_cgi_read : 186 octets (5306/5306) :0x63 0x64 0x65 0x66 0x67 ...
File received, sending HTTP_OK

 

I have changed HTTPSRVCFG_RX_BUFFER_SIZE to 10000, but it doesn't change anything.

I have also tried to change some settings of rtcs without succes :

 

#define DEFAULT_CONNECT_TIMEOUT    (180000L)   /* 3 mins */
#define DEFAULT_RETRANSMISSION_TIMEOUT (3000)  /* 3 sec  */
#define DEFAULT_SEND_TIMEOUT       (DEFAULT_CONNECT_TIMEOUT/2)
#define DEFAULT_RECEIVE_TIMEOUT    (0)     /* no timeout */
#define DEFAULT_NOWAIT             FALSE
#define DEFAULT_TCP_SEND_NOWAIT    FALSE
#define DEFAULT_UDP_SEND_NOWAIT    TRUE    /* UDP non-blocking by default */
#define DEFAULT_RECEIVE_NOWAIT     TRUE//FALSE
#define DEFAULT_WAIT               TRUE//FALSE   /* don't wait for ack */
#define DEFAULT_PUSH               TRUE    /* push */
#define DEFAULT_CHECKSUM_BYPASS    FALSE   /* perform checksum */
#define DEFAULT_TBSIZE             (-1)
#define DEFAULT_RBSIZE             (-1)
#define DEFAULT_UDP_RBSIZE         (RTCSCFG_UDP_RX_BUFFER_SIZE)
#define DEFAULT_MAXRTO             (0)
#define DEFAULT_MAXRCV_WND         (0)
#define DEFAULT_KEEPALIVE          (0)
#define DEFAULT_NO_NAGLE_ALGORITHM TRUE    /* do not use Nagle by default */
#define DEFAULT_NOSWRBUF           FALSE
#define DEFAULT_TIMEWAIT_TIMEOUT   (2*1000) /* msec */ /* 0 = default 4 mins.*/
#define DEFAULT_TCPSECUREDRAFT_0   FALSE
#define DEFAULT_DELAY_ACK          (TCP_ACKDELAY)
#define DEFAULT_IP6_MULTICAST_HOPS (1)
#define DEFAULT_KEEPIDLE           (2*60*60) /* 2 hours, in seconds */
#define DEFAULT_KEEPINTVL          (75)  /* in seconds */
#define DEFAULT_KEEPCNT            (8)   /* send 8 keepalives before connection drop */

 

So here are my questions :

- Do you think that it's possible to download and flash in the same time (I will be using the swap feature, so any error in transmission won't be an issue, the user will just have to retry)

- Is there any way maybe to control the flow between the form uploading the file, and the cgi receiving it, in order to let the flash function work ?

- I was thinking of a javascript that would read the .hex file and send each line with a loop, by POST requests, controlling the flow with POST/GET, and while updating the status to the user (1% 2% etc), maybe it would be better ?

 

Thanks for your help !

Outcomes