Delays in Sending Data Over TCP on LTE Connection, Depending on Data Size with Thingy 91

Hello,

I am experiencing delays when sending data over a TCP connection on an LTE network. The issue seems to be related to the size of the data being sent – larger payloads result in noticeably higher delays before they are transmitted.

/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/* Controlling LEDs through UART. Press 1-3 on your keyboard to toggle LEDS 1-3
 * on your development kit */

#include <dk_buttons_and_leds.h>
#include <modem/lte_lc.h>
#include <modem/nrf_modem_lib.h>
#include <ncs_version.h>
#include <stdio.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/net/socket.h>

#define SSTRLEN(s) (sizeof(s) - 1)

#define MESSAGE_SIZE 1024

static int sock;
static struct sockaddr_storage server;

K_SEM_DEFINE(lte_connected, 0, 1);
K_MUTEX_DEFINE(mutex);

LOG_MODULE_REGISTER(Proxy, LOG_LEVEL_DBG);

#define SLEEP_TIME_MS 1

#define RECEIVE_BUFF_SIZE 1024

#define RECEIVE_TIMEOUT 1000

const struct device *uart = DEVICE_DT_GET(DT_NODELABEL(uart1));

static uint8_t rx_buf[RECEIVE_BUFF_SIZE] = {0};

#define MAX_RETRIES 3

static int server_resolve(void) {
  int err;
  struct addrinfo *result;
  struct addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_STREAM};

  LOG_INF("Resolving server name: %s, port: %s", SERVER_HOSTNAME, SERVER_PORT);

  err = getaddrinfo(SERVER_HOSTNAME, SERVER_PORT, &hints, &result);
  if (err != 0) {
    LOG_ERR("ERROR: getaddrinfo failed %d: %s\n", err, gai_strerror(err));
    return -EIO;
  }

  if (result == NULL) {
    LOG_ERR("ERROR: Address not found\n");
    return -ENOENT;
  }

  struct sockaddr_in *server4 = ((struct sockaddr_in *)&server);
  server4->sin_addr.s_addr =
      ((struct sockaddr_in *)result->ai_addr)->sin_addr.s_addr;
  server4->sin_family = AF_INET;
  server4->sin_port = ((struct sockaddr_in *)result->ai_addr)->sin_port;

  char ipv4_addr[NET_IPV4_ADDR_LEN];
  inet_ntop(AF_INET, &server4->sin_addr.s_addr, ipv4_addr, sizeof(ipv4_addr));
  LOG_INF("IPv4 Address found %s", ipv4_addr);

  freeaddrinfo(result);

  return 0;
}

static int server_connect(void) {
  int err;
  int retries = 0;

  while (retries < MAX_RETRIES) {
    LOG_INF("Creating socket");
    sock = socket(AF_INET, SOCK_STREAM,
                  /* IPPROTO_IP */ IPPROTO_TCP);
    if (sock < 0) {
      LOG_ERR("Failed to create socket: %d.\n", errno);
      return -errno;
    }

    LOG_INF("Connecting to server");
    err = connect(sock, (struct sockaddr *)&server, sizeof(struct sockaddr_in));
    if (err < 0) {
      LOG_ERR("Connect failed : %d\n", errno);
      close(sock);
      retries++;
      k_sleep(K_SECONDS(1));
    } else {
      LOG_INF("Successfully connected to server");
      return 0;
    }
  }

  LOG_ERR("Failed to connect to server after %d retries", MAX_RETRIES);
  return -ETIMEDOUT;
}

static void lte_handler(const struct lte_lc_evt *const evt) {
  switch (evt->type) {
  case LTE_LC_EVT_NW_REG_STATUS:
    if ((evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_HOME) &&
        (evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_ROAMING)) {
      break;
    }
    LOG_INF("Network registration status: %s",
            evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_HOME
                ? "Connected - home network"
                : "Connected - roaming");
    k_sem_give(&lte_connected);
    break;
  case LTE_LC_EVT_RRC_UPDATE:
    LOG_INF("RRC mode: %s",
            evt->rrc_mode == LTE_LC_RRC_MODE_CONNECTED ? "Connected" : "Idle");
    break;
  default:
    break;
  }
}

static int modem_configure(void) {
  int err;

  LOG_INF("Initializing modem library");

  err = nrf_modem_lib_init();
  if (err) {
    LOG_ERR("Failed to initialize the modem library, error: %d", err);
    return err;
  }

  LOG_INF("Disabling PSM and eDRX");
  err = lte_lc_psm_req(false);
  if (err) {
    LOG_ERR("Failed to disable PSM, error: %d", err);
    return err;
  }

  err = lte_lc_edrx_req(false);
  if (err) {
    LOG_ERR("Failed to disable eDRX, error: %d", err);
    return err;
  }

  LOG_INF("Connecting to LTE network");
  err = lte_lc_connect_async(lte_handler);
  if (err) {
    LOG_ERR("Error in lte_lc_connect_async, error: %d", err);
    return err;
  }

  k_sem_take(&lte_connected, K_FOREVER);
  LOG_INF("Connected to LTE network");

  return 0;
}


int main(void) {
  int ret;
  int err;

  err = modem_configure();
  if (err) {
    LOG_ERR("Failed to configure the modem");
    return 0;
  }

  if (server_resolve() != 0) {
    LOG_ERR("Failed to resolve server name");
    return 0;
  }

  if (server_connect() != 0) {
    LOG_ERR("Failed to initialize client");
    return 0;
  }

  const uint8_t buffer[] =
      "$VAL$2025-01-27 09:11:39.234       "
      "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789"
      // "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789"
      // "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789"
      // "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789"
      "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789\r\n";

  while (1) {
   

    int err = send(sock, buffer, sizeof(buffer), 0);
    const int end_ms = k_uptime_get_32();
    if (err < 0) {
      LOG_ERR("Failed to send message, %d", errno);
      if (server_connect() != 0) {
        LOG_ERR("Failed to initialize client");
        return 0;
      }
      // return 0;
    }
    LOG_INF("%dms Sent: %dms %dbytes", start_ms, end_ms - start_ms,
            sizeof(buffer));
    k_msleep(100 - (k_uptime_get_32() - start_ms));
  }

  (void)close(sock);
}

These are some logs during correct working.

I: 448855ms Sent: 0ms 143bytes
I: 448955ms Sent: 0ms 143bytes
I: 449055ms Sent: 0ms 143bytes
I: 449155ms Sent: 0ms 143bytes
I: 449255ms Sent: 0ms 143bytes
I: 449355ms Sent: 0ms 143bytes
I: 449455ms Sent: 0ms 143bytes
I: 449555ms Sent: 0ms 143bytes
I: 449655ms Sent: 1ms 143bytes
I: 449755ms Sent: 1ms 143bytes
I: 449855ms Sent: 1ms 143bytes
I: 449955ms Sent: 1ms 143bytes
I: 450055ms Sent: 1ms 143bytes
I: 450156ms Sent: 0ms 143bytes
I: 450257ms Sent: 0ms 143bytes
I: 450357ms Sent: 0ms 143bytes
I: 450457ms Sent: 0ms 143bytes
I: 450557ms Sent: 0ms 143bytes
I: 450657ms Sent: 0ms 143bytes
I: 450757ms Sent: 0ms 143bytes
I: 450857ms Sent: 1ms 143bytes

And here with a bigger buffer:

I: 4456ms Sent: 0ms 353bytes
I: 4556ms Sent: 0ms 353bytes
I: 4656ms Sent: 0ms 353bytes
I: 4756ms Sent: 0ms 353bytes
I: 4856ms Sent: 0ms 353bytes
I: 4956ms Sent: 0ms 353bytes
I: 5056ms Sent: 0ms 353bytes
I: 5156ms Sent: 0ms 353bytes
I: 5256ms Sent: 0ms 353bytes
I: 5356ms Sent: 0ms 353bytes
I: 5456ms Sent: 0ms 353bytes
I: 5556ms Sent: 0ms 353bytes
I: 5656ms Sent: 0ms 353bytes
I: 5756ms Sent: 0ms 353bytes
I: 5856ms Sent: 0ms 353bytes
I: 5956ms Sent: 0ms 353bytes
I: 6056ms Sent: 0ms 353bytes
I: 6156ms Sent: 0ms 353bytes
I: 6256ms Sent: 200ms 353bytes
I: 6459ms Sent: 0ms 353bytes
I: 6560ms Sent: 0ms 353bytes
I: 6660ms Sent: 0ms 353bytes
I: 6760ms Sent: 1604ms 353bytes
I: 8367ms Sent: 0ms 353bytes
I: 8468ms Sent: 0ms 353bytes
I: 8568ms Sent: 1ms 353bytes
I: RRC mode: Idle
I: RRC mode: Connected
I: 8669ms Sent: 4816ms 353bytes
I: 13487ms Sent: 1ms 353bytes
I: 13587ms Sent: 1ms 353bytes
I: 13687ms Sent: 1ms 353bytes
I: 13788ms Sent: 197ms 353bytes
I: 13988ms Sent: 0ms 353bytes
I: 14089ms Sent: 0ms 353bytes
I: 14189ms Sent: 717ms 353bytes

Has anyone else encountered similar issues with TCP data transmission delays over LTE, especially with varying data sizes? If so, could you share any insights or solutions on how to optimize data transmission for consistent and minimal delays?

Any advice or suggestions would be greatly appreciated!

Parents Reply Children
  • Yes I am using a Thingy91.

    *** Booting nRF Connect SDK v2.9.0-7787b2649840 ***
    *** Using Zephyr OS v3.7.99-1f8f3dc29142 ***
    I: Initializing modem library
    I: Disabling PSM and eDRX
    I: Connecting to LTE network
    I: RRC mode: Connected
    I: Network registration status: Connected - home network
    I: Connected to LTE network
    I: Resolving server name: x, port: x
    I: IPv4 Address found x
    I: Creating socket
    I: Connecting to server
    I: Successfully connected to server
    I: UART Proxy
    I: 3727ms Sent: 1ms 1053bytes
    I: 4027ms Sent: 0ms 1053bytes
    I: 4327ms Sent: 0ms 1053bytes
    I: 4627ms Sent: 1ms 1053bytes
    I: 4927ms Sent: 0ms 1053bytes
    I: 5227ms Sent: 0ms 1053bytes
    I: 5527ms Sent: 1ms 1053bytes
    I: 5828ms Sent: 0ms 1053bytes
    I: 6128ms Sent: 1ms 1053bytes
    I: 6428ms Sent: 1ms 1053bytes
    I: 6728ms Sent: 0ms 1053bytes
    I: RRC mode: Idle
    I: RRC mode: Connected
    I: 7028ms Sent: 6228ms 1053bytes
    I: 13259ms Sent: 0ms 1053bytes
    I: 13559ms Sent: 1271ms 1053bytes
    I: 14833ms Sent: 0ms 1053bytes
    I: 15133ms Sent: 447ms 1053bytes
    I: 15583ms Sent: 0ms 1053bytes
    I: 15883ms Sent: 403ms 1053bytes
    I: 16289ms Sent: 4465ms 1053bytes
    I: 20757ms Sent: 1451ms 1053bytes
    I: 22211ms Sent: 0ms 1053bytes
    I: 22511ms Sent: 447ms 1053bytes
    I: 22961ms Sent: 1005ms 1053bytes
    I: 23969ms Sent: 271ms 1053bytes
    I: 24269ms Sent: 0ms 1053bytes
    I: 24569ms Sent: 351ms 1053bytes
    I: 24923ms Sent: 757ms 1053bytes
    I: 25683ms Sent: 5392ms 1053bytes
    I: 31078ms Sent: 0ms 1053bytes
    I: 31378ms Sent: 0ms 1053bytes
    I: 31678ms Sent: 150ms 1053bytes
    I: 31978ms Sent: 530ms 1053bytes
    I: 32511ms Sent: 747ms 1053bytes
    I: 33261ms Sent: 677ms 1053bytes

  • I think it is depending on this configuration variable:

    CONFIG_NRF_MODEM_LIB_SHMEM_TX_SIZE
    When is settled to 8192:
    I: 4480ms Sent: 1ms 3083bytes
    I: 5480ms Sent: 1ms 3083bytes
    I: RRC mode: Idle
    I: RRC mode: Connected
    I: 6480ms Sent: 6492ms 3083bytes
    I: 12975ms Sent: 981ms 3083bytes
    I: RRC mode: Idle
    I: RRC mode: Connected
    I: 13975ms Sent: 7475ms 3083bytes
    I: 21453ms Sent: 1335ms 3083bytes
    I: 22791ms Sent: 1884ms 3083bytes
    I: 24678ms Sent: 4589ms 3083bytes
    I: 29270ms Sent: 1387ms 3083bytes
    I: 30660ms Sent: 1493ms 3083bytes
    I: 32156ms Sent: 1387ms 3083bytes
    I: RRC mode: Idle
    I: RRC mode: Connected
    I: 33546ms Sent: 6309ms 3083bytes
    I: RRC mode: Idle
    I: RRC mode: Connected
    I: 39858ms Sent: 5036ms 3083bytes
    I: 44897ms Sent: 1476ms 3083bytes
    I: 46376ms Sent: 2060ms 3083bytes
    I: 48439ms Sent: 1534ms 3083bytes
    I: 49976ms Sent: 1630ms 3083bytes
    I: 51609ms Sent: 2265ms 3083bytes
    I: 53877ms Sent: 1411ms 3083bytes
    I: 55291ms Sent: 1655ms 3083bytes
    3083 * 2 good sents = 6166 -> 8192 - 6166 = 2026 < 3083
    And with 32768:
    I: 3365ms Sent: 2ms 3083bytes
    I: 4365ms Sent: 2ms 3083bytes
    I: 5365ms Sent: 1ms 3083bytes
    I: 6366ms Sent: 0ms 3083bytes
    I: 7366ms Sent: 0ms 3083bytes
    I: 8366ms Sent: 1ms 3083bytes
    I: RRC mode: Idle
    I: 9367ms Sent: 0ms 3083bytes
    I: RRC mode: Connected
    I: 10367ms Sent: 44ms 3083bytes
    I: 11367ms Sent: 1ms 3083bytes
    I: 12367ms Sent: 8ms 3083bytes
    I: RRC mode: Idle
    I: RRC mode: Connected
    I: 13367ms Sent: 5843ms 3083bytes
    I: 19213ms Sent: 1045ms 3083bytes
    I: RRC mode: Idle
    I: RRC mode: Connected
    I: 20261ms Sent: 6629ms 3083bytes
    3083 * 10 good sents = 30830 -> 32768 - 30830 = 1938 < 3083
    To be honest, I am new with nordic boards, so I cannot understand it well, surely. If you can help me, I will be thankful.
  • Hi,

    Thank you for additional information.

    CONFIG_NRF_MODEM_LIB_SHMEM_TX_SIZE is the amount of shared memory owned by the application and used for sending the data to the modem. The RX/TX must fit the data for the largest command or socket operation executed.

    This area holds all outgoing data from the application to the modem, e.g. buffers passed to `send()`, AT commands. The size must be a multiple of four to keep the memory partitions word-aligned.

    You can find more information about memory regions of the modem library in the documentation.

    Best regards,
    Dejan

  • Hi, 

    In one of your previous replies, there was this command "west build --build-dir /***/proxy-usb-udp/build /***/proxy-usb-udp".
    Which specific sample did you build? Is your application based on any of the NCS samples?

    Best regards,
    Dejan 

Related