For testing our prototype which uses a webserver without FileX (just request_notify callback) I would like to serve a csv file with measurement data for download. The file is rather large, up to 30 MB, as it's generated from binary data in RAM. I'm testing with the following code:
UINT serve_measurement_csv(NX_HTTP_SERVER& server, UINT request_type, const string& resource, NX_PACKET& packet)
{
SSP_PARAMETER_NOT_USED(request_type);
SSP_PARAMETER_NOT_USED(packet);
UINT status;
//First, calculate file length and generate HTTP header for file download
const char * header =
"HTTP/1.0 200 \r\n"
"Content-Length:%d\r\n"
"Content-Type: text/plain\r\n"
"Content-Disposition: attachment; filename=measurement.csv\r\n\r\n";
ULONG header_length = 200;
char header_buff[200]; //To be save
//Line length is (4 characters per 12 bit value, one comma (or \r on last column)
//plus \n) multiplied with the number of channels
uint16_t line_length = (5 * ADC_NUM_CHANNELS + 1);
//Calculate the file length as number of lines * line length
uint32_t file_length = line_length * ADC_FAST_BUFFER_SIZE;
header_length = snprintf(header_buff, header_length, header, file_length);
status = nx_http_server_callback_data_send(&server, header_buff, header_length);
if(status != NX_SUCCESS)
log_failed(log_level::ERROR_INTERNAL, "nx_http_server_callback_data_send", status);
string format_string = "\r\n";
for(int i = 0; i < ADC_NUM_CHANNELS; i++)
format_string = string("%d") + (i > 0 ? " " : "") + format_string;
log_message(log_level::VERBOSE_INTERNAL, format_string);
char num_buff[5];
string line;
line.reserve(line_length);
//Next, repeatedly send data of the file in a loop
for(int i = 0; i < ADC_MEASUREMENT_NUM_POINTS; i++)
{
line.clear();
for(int j = 0; j < ADC_NUM_CHANNELS; j++)
{
snprintf(num_buff, 5, "%d", last_measurement[j][i]);
line += num_buff;
if(j < ADC_NUM_CHANNELS - 1)
line += " ";
}
line += "\r\n";
if(i == 0)
log_message(log_level::VERBOSE_INTERNAL, line);
status = nx_http_server_callback_data_send(&server, const_cast<char*>(line.c_str()), line.length());
if(status != NX_SUCCESS)
log_failed(log_level::ERROR_INTERNAL, "nx_http_server_callback_data_send", status);
}
/* Return completion status. */
return(NX_HTTP_CALLBACK_COMPLETED);
}
Firefox will claim that the download failed, wget stops after 4%, and nx_http_server_callback_data_send repeatedly fails with status 0x49. I believe this is the status code
NX_TX_QUEUE_DEPTH (0x49) Maximum transmit queue depth has been reached.
I'm sure that I should not send each line separatedly, but is there anything else I should do to prevent this error? Do I need to wait after a specific number of packets?