This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

nrf91_socket_offload_sendto refuses to send large packets

We are developing a device that communicates with a remote management system via tcp sockets over LTE. We are using the NRF Connect SDK 1.4.0 with modem firmware mfw_nrf9160_1.3.0. Using the code below we are able to send packets with sizes up to 2656 bytes without issue. The largest data frame that we are sending is ~9kB manually split into 3 chunks of 2656, 2704 and 4256 bytes. This code produces the first log shown below. Manually limiting the size to 1024 in the function call to send () has little to no effect on the outcome, see the second log below.

So my questions are:

  • How do I handle EAGAIN errors from the library?
  • If 2048 bytes is the limit for nrf91_socket_offload_sendto, why don't I get errno = EMSGSIZE ( = 36) for the other packets?
  • What needs to be done to correctly send all packets via LTE?

int SocketWrite (int sock, uint8_t *pData, int datalen)
{
    u32_t offset = 0U;
    u8_t attempts = 0U;
    int ret;
    
    while (offset < datalen) {
    	ret = send(sock, data + offset, (datalen - offset), 0);
    	// ret = send(sock, data + offset, MIN(1024, (datalen - offset)), 0);
    	if (ret < 0)
        {
          LOG_ERR ("Send failure (%d/%d)", ret, errno);
          if (errno == ENOBUFS)
          {
            LOG_INF ("Waiting for more buffers");
            waitingForBuffers = true;
          }
          else if (errno == EAGAIN)
          {
            LOG_INF ("Resending data");
          }
          else
          {
            break;
          }
        }
        else
        {
          offset += ret;
        }
        
        if (attempts++ > 6)
        {
            LOG_INF ("Force stopping send @ %u iterations", 6);
            break;
        }
    }
    
    if (offset != datalen)
    {
        LOG_WRN ("Sent bytes do not match data len (%u != %u)", offset, datalen);
    }
}

Log without limiting send() call:
[01:15:10.553,649] <inf> networking: Starting sending bytes (2656)
[01:15:10.599,609] <inf> networking: Starting sending bytes (2704)
[01:15:10.599,639] <err> networking: Send failure (-1/11)
[01:15:10.599,639] <inf> networking: Resending data
[01:15:10.699,798] <err> networking: Send failure (-1/11)
[01:15:10.699,829] <inf> networking: Resending data
[01:15:10.799,957] <err> networking: Send failure (-1/11)
[01:15:10.799,957] <inf> networking: Resending data
[01:15:10.900,115] <err> networking: Send failure (-1/11)
[01:15:10.900,115] <inf> networking: Resending data
[01:15:11.000,274] <err> networking: Send failure (-1/11)
[01:15:11.000,274] <inf> networking: Resending data
[01:15:11.100,524] <inf> networking: Force stopping send(to) @ 6 iterations
[01:15:11.100,555] <wrn> networking: Sent bytes do not match payload size (0 != 2704)
[01:15:11.169,311] <inf> networking: Starting sending bytes (4256)
[01:15:11.169,311] <err> networking: Send failure (-1/36)
[01:15:11.169,342] <wrn> networking: Sent bytes do not match payload size (0 != 4256)
Log while limiting send() call:
[01:15:10.553,649] <inf> networking: Starting sending bytes (2656)
[01:15:10.599,609] <inf> networking: Starting sending bytes (2704)
[01:15:10.599,639] <err> networking: Send failure (-1/11)
[01:15:10.599,639] <inf> networking: Resending data
[01:15:10.699,798] <err> networking: Send failure (-1/11)
[01:15:10.699,829] <inf> networking: Resending data
[01:15:10.799,957] <err> networking: Send failure (-1/11)
[01:15:10.799,957] <inf> networking: Resending data
[01:15:10.900,115] <err> networking: Send failure (-1/11)
[01:15:10.900,115] <inf> networking: Resending data
[01:15:11.000,274] <err> networking: Send failure (-1/11)
[01:15:11.000,274] <inf> networking: Resending data
[01:15:11.100,524] <inf> networking: Force stopping send(to) @ 6 iterations
[01:15:11.100,555] <wrn> networking: Sent bytes do not match payload size (0 != 2704)
[01:15:11.169,311] <inf> networking: Starting sending bytes (4256)
[01:15:10.599,639] <err> networking: Send failure (-1/11)
[01:15:10.599,639] <inf> networking: Resending data
[01:15:10.699,798] <err> networking: Send failure (-1/11)
[01:15:10.699,829] <inf> networking: Resending data
[01:15:10.799,957] <err> networking: Send failure (-1/11)
[01:15:10.799,957] <inf> networking: Resending data
[01:15:10.900,115] <err> networking: Send failure (-1/11)
[01:15:10.900,115] <inf> networking: Resending data
[01:15:11.000,274] <err> networking: Send failure (-1/11)
[01:15:11.000,274] <inf> networking: Resending data
[01:15:11.100,524] <inf> networking: Force stopping send(to) @ 6 iterations
[01:15:11.169,342] <wrn> networking: Sent bytes do not match payload size (0 != 4256)

Parents
  • Hi again!

    • How do I handle EAGAIN errors from the library?

    You are handling it correctly, but I would suggest adding a small wait before trying again to give time for the data in the buffer to be read and free up memory.

    • If 2048 bytes is the limit for nrf91_socket_offload_sendto, why don't I get errno = EMSGSIZE ( = 36) for the other packets?

    The function isn't implemented that way, it returns -1 for any error. 

    • What needs to be done to correctly send all packets via LTE?

    Is the socking blocking or non-blocking? There have been a lot of fixes in the BSD Library (now called nRF Modem Library) especially with regard to blocking sockets, so I would again suggest upgrading the NCS version.

  • Hi Heidi,

    Thank you for the information. I have added a small delay (50ms) when an error (EAGAIN and ENOBUFS) is returned. Combining the delay with enabling CONFIG_NRF91_SOCKET_SEND_SPLIT_LARGE_BLOCKS solved our problem.

    All sockets are configured as non-blocking. I will look into upgrading the NCS version.

Reply Children
No Data
Related