cancel
Showing results for 
Search instead for 
Did you mean: 

NetXDuo WebServer File Upload

coso2
Associate II

Hi everyone,

I am trying to send the firmware to the MCU via webpage. I want to send chunks of the file (4096 bytes) to the mcu, so it can store in ram, do some checks and then store it in an external memory. The firmware size can be maximum of 1.7MB (all the web pages and content are embedded in the firmware). 

The webserver is running, and I have the request notify callback function

#define fwBufferSize 5000
CHAR fwBuffer[fwBufferSize];

UINT webserver_request_notify_callback(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr)
{
  CHAR temp_string[30] = {'\0'};
  CHAR data[512] = {'\0'};
  UINT string_length;
  NX_PACKET *resp_packet_ptr;
  NX_PACKET *currentPacket;
  UINT status;
  ULONG total_bytes_sent;
  ULONG total_bytes_received;
  ULONG connections;
  ULONG disconnections;
  ULONG length;
  ULONG aOffset, aLength;
  UINT actualSize;
  ULONG bytes_read;
  ULONG packetLength;
  CHAR *destination_ptr;
  UINT destination_size;
  UINT *actual_size;
  CHAR *server_thread_name;

  if (strcmp(resource, "/fwupload") == 0)
  {
	  TX_MEMSET(fwBuffer, '\0', fwBufferSize);

	  _nx_web_http_server_content_length_get(packet_ptr, &actual_size);
	  printf("Actual_size = %lu, ", actual_size);

	  _nx_web_http_server_callback_data_send(server_ptr, defaultResponse, strlen(defaultResponse));

      /* Return completion status. */
      return(NX_SUCCESS);
  }
  else
  {
    return NX_SUCCESS;
  }
...
...
...

On the webpage side I have this script 

        <script type="text/javascript">
            document.addEventListener("DOMContentLoaded", function() {
                document.getElementById('btnUploadFirmware').addEventListener('click', function() {
                    uploadFirmware();
                });
            });
            function uploadFirmware() {
                var file = document.getElementById("fwFile").files[0];
                Upload(file, 4096);
            }
            function Upload(file, chunkSize) {
                var iterations = Math.ceil(file.size / chunkSize);
                var ChunkNumber = 0;
                for (let i = 0; i < iterations; i++) {
                    var blob;
                    ChunkNumber += 1;
                    var LoopChunk = ChunkNumber;
                    var startChunk = chunkSize * (ChunkNumber - 1);
                    if (file.size > chunkSize * ChunkNumber) {
                        blob = file.slice(startChunk, (ChunkNumber * chunkSize));
                    } else {
                        var remainingLength = file.size - startChunk;
                        blob = file.slice(startChunk, startChunk + remainingLength);
                    }
                    req = new XMLHttpRequest();
                    req.open("POST", "/fwupload", false);
                    req.onload = (event) => {
                        console.log(LoopChunk);
                    }
                    ;
                    req.send(blob);
                }
            }
        </script>

So, I divide the file in chunks of 4096 bytes max and send them to the MCU.

The function 

_nx_web_http_server_content_length_get

give me the right amount of bytes received (according to the content-length), but when I try to get the data with

_nx_web_http_server_content_get_extended

I only get 1460 bytes

Thanks in advice for any hint or help

coso2

 

1 ACCEPTED SOLUTION

Accepted Solutions
mbrossett
Associate III

Create a loop and keep calling _nx_web_http_server_content_get_extended() until you have gotten all the data as determined by _nx_web_http_server_content_length_get()

 

Standard TCP packet data payload is 1460. So chunking the data into 4380 bytes, or some other multiple of 1460, would be more efficient (less packets sent) but not required. 

View solution in original post

2 REPLIES 2
mbrossett
Associate III

Create a loop and keep calling _nx_web_http_server_content_get_extended() until you have gotten all the data as determined by _nx_web_http_server_content_length_get()

 

Standard TCP packet data payload is 1460. So chunking the data into 4380 bytes, or some other multiple of 1460, would be more efficient (less packets sent) but not required. 

coso2
Associate II

@mbrossett  Thanks, it is working!

I share the code I ended up with:

  if (strcmp(resource, "/fwupload") == 0)
  {	  
	  TX_MEMSET(fwBuffer, 0, fwBufferSize);

	  _nx_web_http_server_content_length_get(packet_ptr, &actual_size);
	  printf("Actual_size = %lu ", actual_size);

	  int numberOfIterations;
	  numberOfIterations = actual_size / 1460;

	  if((numberOfIterations * 1460) < actual_size)
	  {
		  numberOfIterations += 1;
	  }

	  ULONG BytesCopied = 0;
	  ULONG totalBytes = 0;
	  for(int i = 0; i < numberOfIterations; i++)
	  {
		  _nx_web_http_server_content_get_extended(server_ptr, packet_ptr, totalBytes, fwBuffer + totalBytes, fwBufferSize - totalBytes, &BytesCopied);
		  totalBytes += BytesCopied;
		  printf(" | #%d = %lu ", i, BytesCopied);
	  }

	  printf("| Copied to buffer = %lu\r\n", totalBytes);

	  if(totalBytes != actual_size)
	  {
		  //ERROR
	  }

	  _nx_web_http_server_callback_data_send(server_ptr, defaultResponse, strlen(defaultResponse));

      return(NX_SUCCESS);
  }

 With the fwBuffer and fwBufferSize declared as

#define fwBufferSize 5840
CHAR fwBuffer[fwBufferSize];

 And on the javascript size the chunks are of 5840 Bytes