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
  • I use the NRF Connect vs code extension. This release: nRF Connect SDK Toolchain v2.9, which executes this command:

    *  Executing task: nRF Connect: Build: proxy-usb-udp/build

    Building proxy-usb-udp
    west build --build-dir /***/proxy-usb-udp/build /***/proxy-usb-udp

  • Hi,

    Is your issue reproducible on nrf9160-dk board?

    Best regards,
    Dejan

  • Hi,

    Which network do you use? Have you tried to use another network?

    Is this issue reproducible on Thingy91?

    Best regards,
    Dejan

  • 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

Related