TCP server (using net_context) running on nrf7002-DK in STA mode stopping receiving data

Hello everybody,

                         I have very bad problem for me. I am developing application on nrf7002-DK based on STA (station) example. I add own AT command analyzer and SCAN, so I am able to see webs that are available near my nrf7002-DK. With special AT command, i am able to connect to any web that my DK see.

I create AT command that allows me create a TCP server on nrf7002-DK.

static void create_tcp_server1(int port_number)
{
  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	//                                          Vytvoření TCP serveru
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    int rc = net_context_get(AF_INET, SOCK_STREAM, IPPROTO_TCP, &server1.tcp_server);
    if (rc < 0) 
	{
		if(loggovani==true)
		{
           printk("net_context_get selhal: %d\n", rc);
		}
        
    } 
	else 
	{
	    if(loggovani==true)
		{
           printk("Podařilo se definovat parametry TCP serveru\n");
		}
    }
    //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	//                        Definice portu, na kterém poběží server
	//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    struct sockaddr_in addr;
    int ret;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port_number);
    addr.sin_addr.s_addr = INADDR_ANY;
    //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	//                              Svázání serveru s portem
	//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    ret = net_context_bind(server1.tcp_server, (struct sockaddr *)&addr, sizeof(addr));
    if (ret < 0) 
	{
		if(loggovani==true)
		{
           printk("Spojení serveru s portem selhalo: %d\n", ret);
		}

    }
	else 
	{
		if(loggovani==true)
		{
		   printk("Uspesne bindnuto\n");
		}
	}
	//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	//                          Zahájení poslouchání na portu
	//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    ret = net_context_listen(server1.tcp_server, 5);
    if (ret < 0) 
	{
		if(loggovani==true)
		{
           printk("Poslouchání na portu selhalo: %d\n", ret);
		}

    }
	else
	{
		if(loggovani==true)
		{
           printk("Server posloucha na portu\n");
		}
	}
	//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	//                    Nastavení callbacku pro akceptování klienta
	//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    ret = net_context_accept(server1.tcp_server, obsazovani_slotu_server1, K_NO_WAIT, NULL);
    if (ret < 0) {
		if(loggovani==true)
		{
          printk("Pristup selhal: %d\n", ret);
		}
        
    }
	else
	{
		if(loggovani==true)
		{
          printk("Callback pro prihlaseni klienta pridan \n");
		}
	}
	printk("\n+TCPSERVER 1: RUNNING\n");
	server1.is_running=true;
}

I am working with net_context architecture. I try to use sockets, but it doesn't work.

I can show callabck, that I am using for receiving data:

static void prijimac_server1_klient1(struct net_context *context, struct net_pkt *pkt, union net_ip_header *ip_hdr, union net_proto_header *proto_hdr, int status, void *user_data)
{
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	//                 Testování toho, jestli nepřišel prázdný packet
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	if (!pkt)//pokud přišel prázdný packet. znamená to, že se klient odpojil
	{
        printk("\n+TCPSERVER 1, CLIENT 1 DISCONNECTED\n");
		printk("\nOK\n");
		server1.pripojen1=false;
		server1.transparetni_rezim1=false;
		server1.ip_client1=NULL;
		int ret = net_context_accept(server1.tcp_server, obsazovani_slotu_server1, K_NO_WAIT, NULL);
        if (ret < 0) 
		{
			if(loggovani==true)
			{
              printk("Callback pro prihlaseni se podarilo nastavit: %d\n", ret);
			}
        }
	    else
	    {
			if(loggovani==true)
			{
				printk("Callback pro prihlaseni klienta pridan \n");
			} 
	    }
	 }
	 else
	 {
		 if(server1.transparetni_rezim1==false)
		 {
            printk("+TCPSERVER 1, DATA CLIENT 1: ");
		 }
         size_t len = net_pkt_remaining_data(pkt);
		 data_prisla_1_1=true;
         //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
		 //   Kontrola toho, jestli se data vejdou do bufferu
		 //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         if (len > sizeof(server1.buffer)) 
		 {
           len = sizeof(server1.buffer); //snížení velikosti přijímaných dat
         }
         //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
		 //                 Samotné přijetí dat
		 //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         int ret = net_pkt_read(pkt, server1.buffer, len);
		 bool nalezeni= prohledej_buffer_serveru_1("JEDE, JEDE, MASINKA, KOURI SE JI Z KOMINKA");
		 net_pkt_unref(pkt);
         if (pkt) 
         {
	printk("SE nepovedlo\n");
	pkt = NULL;
}
else
{
	printk("POVEDLO se\n");
}  
net_context_recv(context, prijimac_server1_klient1,  K_NO_WAIT, NULL);
         //context->fifo_reserved;
          
		  //printk("%d\n",pocet);
		 //net_context_unref(context);
		 //net_context_ref(context);
		 //net_context_put(context);
		 if(nalezeni==true)
		 {
            printk("\nDATA NALEZENA\n");
			kontrola_nezkresleni_1_1=true;
		 }
		 else
		 {
            printk("\nNENASEL JSEM TO\n");
		 }
         if (ret == 0) 
		 {
           //for(int ukazovatko=0;ukazovatko<len;ukazovatko++)
		   //{
              //printk("%c",server1.buffer[ukazovatko]);
		   //}
		   //printk("\n");
         }
		 else
		 {
			if(loggovani==true)
			{
			   printk("Data se nepodarila nacist\n");   
		    }
	     }
	  }

}

I do net_pkt_unref().

If I connect to network, create and run TCP server, i can connect TCP client into TCP server. I am able to send data from client to server. But after maybe a 20 message.

I can show you log of communication:

> AT#TCPSERVER=1,1,6523

+TCPSERVER 1: RUNNING
OK
+TCPSERVER 1, CLIENT 1 CONNECTED
OK
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

DATA NALEZENA
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

DATA NALEZENA
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

DATA NALEZENA
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

DATA NALEZENA
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

DATA NALEZENA
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

DATA NALEZENA
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

DATA NALEZENA
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

DATA NALEZENA
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

DATA NALEZENA
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

DATA NALEZENA
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

DATA NALEZENA
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

DATA NALEZENA
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

DATA NALEZENA
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

DATA NALEZENA
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

NENASEL JSEM TO
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

NENASEL JSEM TO
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

NENASEL JSEM TO
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

DATA NALEZENA
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

DATA NALEZENA
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

DATA NALEZENA
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

NENASEL JSEM TO
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

NENASEL JSEM TO
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

NENASEL JSEM TO
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

NENASEL JSEM TO
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

NENASEL JSEM TO
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

NENASEL JSEM TO
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

NENASEL JSEM TO
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

NENASEL JSEM TO
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

NENASEL JSEM TO
+TCPSERVER 1, DATA CLIENT 1: SE nepovedlo

NENASEL JSEM TO

+TCPSERVER 1, CLIENT 1 DISCONNECTED

CONNECTION DATA FLOW TIME EXPIRED

DATA DISTORTION

OK

this log shows: if message +TCPSERVER 1: DATA CLIENT 1: means, that data will be read by server (now without plot into console)

I added function, that will disconnect client, that didn't send message for some time (maybe 30 seconds). If I do disconnection of client and I do new connection, data start flow (only maybe 20 messages). If you do net_context unref and put.

void disconnect_server_1_client_1()
{
	    int navratova=0;
		//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
		//             První fáze odpojování klienta
		//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	    navratova=net_context_unref(server1.client1);
		if(navratova==0)
		{
			if(loggovani==true)
		    {
              printk("Klient 1 server 1 se odpojuje, krok 1\n");
			}
		}
		else
		{
			if(loggovani==true)
		    {
              printk("Odpojeni klienta 1 server 1 se nezdarilo\n");
			}
		}
	    navratova=net_context_put(server1.client1); 
		if(navratova==0)
		{
			if(loggovani==true)
		    {
              printk("Klient 1 server 1 se odpojuje, krok 2\n");
			}
		}
		else
		{
			if(loggovani==true)
		    {
              printk("Odpojeni klienta 1 server 1 se nezdarilo\n");
			}
		}
		server1.pripojen1=false;
		printk("\n+TCPSERVER 1, CLIENT 1 DISCONNECTED\n");
		//printk("\nOK\n");
};

My prj. conf looks like this:

#
# Copyright (c) 2022 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#
CONFIG_WIFI=y
CONFIG_WIFI_NRF70=y

CONFIG_SERIAL=y
CONFIG_NRFX_UART0=y
CONFIG_UART_ASYNC_API=y
# WPA supplicant
CONFIG_WIFI_NRF70_LOG_LEVEL_INF=n
CONFIG_WIFI_NRF70_LOG_LEVEL_DBG=n
CONFIG_WIFI_NRF70_LOG_LEVEL_DEFAULT=n
CONFIG_WIFI_NRF70_LOG_LEVEL_WRN=n
CONFIG_WIFI_NRF70_LOG_LEVEL_OFF=n
CONFIG_WIFI_NRF70_LOG_LEVEL_ERR=n

CONFIG_WIFI_READY_LIB=y
CONFIG_WIFI_NM_WPA_SUPPLICANT=y
CONFIG_WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_DBG=n
CONFIG_WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_INF=n
CONFIG_WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_DEFAULT=n
CONFIG_WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_ERR=n
CONFIG_WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_OFF=n
CONFIG_WIFI_NM_WPA_SUPPLICANT_LOG_LEVEL_WRN=n
CONFIG_NRF_WIFI_RPU_RECOVERY=y

CONFIG_WIFI_CREDENTIALS=y
CONFIG_WIFI_CREDENTIALS_STATIC=y
CONFIG_WIFI_CREDENTIALS_STATIC_SSID="yyyyyyyyyy"
CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="xxxxxxxxxx"

# Networking
CONFIG_NETWORKING=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_LOG=n
CONFIG_NET_IPV4=y
CONFIG_NET_UDP=y
CONFIG_NET_TCP=y
CONFIG_NET_DHCPV4=y

CONFIG_NET_MGMT_EVENT_LOG_LEVEL_DBG=n
CONFIG_NET_MGMT_EVENT_LOG_LEVEL_DEFAULT=n
CONFIG_NET_MGMT_EVENT_LOG_LEVEL_INF=n
CONFIG_NET_MGMT_EVENT_LOG_LEVEL_ERR=n
CONFIG_NET_MGMT_EVENT_LOG_LEVEL_WRN=n
CONFIG_NET_MGMT_EVENT_LOG_LEVEL_OFF=n



CONFIG_NET_PKT_RX_COUNT=32
CONFIG_NET_PKT_TX_COUNT=32
CONFIG_NRF70_RX_NUM_BUFS=16

# Below section is the primary contributor to SRAM and is currently
# tuned for performance, but this will be revisited in the future.
CONFIG_NET_BUF_RX_COUNT=64
CONFIG_NET_BUF_TX_COUNT=64
CONFIG_HEAP_MEM_POOL_SIZE=47000
CONFIG_HEAP_MEM_POOL_IGNORE_MIN=y
CONFIG_NRF_WIFI_CTRL_HEAP_SIZE=20000
CONFIG_NRF_WIFI_DATA_HEAP_SIZE=60000
CONFIG_NET_TC_TX_COUNT=1

CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=1
CONFIG_NET_MAX_CONTEXTS=50
CONFIG_NET_CONTEXT_SYNC_RECV=y

CONFIG_INIT_STACKS=y

CONFIG_NET_L2_ETHERNET=y
CONFIG_NET_L2_WIFI_MGMT=y
CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL_DBG=n
CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL_INF=n
CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL_WRN=n
CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL_ERR=n
CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL_DEFAULT=n
CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL_OFF=n

CONFIG_WIFI_MGMT_SCAN_SSID_FILT_MAX=4

CONFIG_NET_CONFIG_SETTINGS=y
CONFIG_NET_CONFIG_INIT_TIMEOUT=0

CONFIG_NET_SOCKETS_POLL_MAX=15

# Memories
CONFIG_MAIN_STACK_SIZE=60400
CONFIG_NET_TX_STACK_SIZE=16384
CONFIG_NET_RX_STACK_SIZE=16384
CONFIG_STA_SAMPLE_START_WIFI_THREAD_STACK_SIZE=60400

# Debugging
CONFIG_STACK_SENTINEL=y
CONFIG_DEBUG_COREDUMP=y
CONFIG_DEBUG_COREDUMP_BACKEND_LOGGING=y
CONFIG_DEBUG_COREDUMP_MEMORY_DUMP_MIN=y
CONFIG_SHELL_CMDS_RESIZE=n


# Kernel options
CONFIG_ENTROPY_GENERATOR=y

# Logging
CONFIG_LOG_BUFFER_SIZE=16384
CONFIG_POSIX_CLOCK=y

CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.168.1.99"
CONFIG_NET_CONFIG_MY_IPV4_NETMASK="255.255.255.0"
CONFIG_NET_CONFIG_MY_IPV4_GW="192.168.1.1"

# printing of scan results puts pressure on queues in new locking
# design in net_mgmt. So, use a higher timeout for a crowded
# environment.
CONFIG_NET_MGMT_EVENT_QUEUE_TIMEOUT=50

CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS=n
CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY=n

CONFIG_WIFI_SCAN_DWELL_TIME_ACTIVE=50
CONFIG_WIFI_SCAN_DWELL_TIME_PASSIVE=130

CONFIG_WIFI_LOG_LEVEL_OFF=n
CONFIG_WIFI_LOG_LEVEL_INF=n

CONFIG_LOG_BACKEND_NET_AUTOSTART=n
CONFIG_LOG=n
CONFIG_LOG_DEFAULT_LEVEL=3

CONFIG_TIMER=y
CONFIG_COUNTER=y
CONFIG_CLOCK_CONTROL=y
CONFIG_CLOCK_CONTROL_NRF=y
CONFIG_NRFX_CLOCK=y
CONFIG_RTC_ALARM=y
CONFIG_RTC_UPDATE=y
CONFIG_NET_ICMPV4_ACCEPT_BROADCAST=y

#CONFIG_NET_BUF_DATA_SIZE=8192
CONFIG_NET_BUF_POOL_USAGE=y

CONFIG_NET_RX_DEFAULT_PRIORITY=7

Could you please help me solve this problem, I want to be able read any count of messages.

Kind regards

Jaroslav Havel 

  • Hi, Jaroslav.

    We'll do our best to help you.

    Could you please specify again what your specific problem is?

    I am working with net_context architecture. I try to use sockets, but it doesn't work.

    What specifically doesn't work when you're trying to use sockets?

    I added function, that will disconnect client, that didn't send message for some time (maybe 30 seconds). If I do disconnection of client and I do new connection, data start flow (only maybe 20 messages). If you do net_context unref and put.

    Is it that you're only able to receive 20 messages before a disconnect occurs?

    Could you please help me solve this problem, I want to be able read any count of messages.

    Or is it a different number of messages you're able to receive before the disconnect occurs?

    Best regards,
    Mathias

  • Hi, Mathias,

    if I tryied to use sockets, I got error (operation is not supported). So I decided to use net_context and it seems to me it works. I don't think it matters.Let's not talk now about why I don't use sockets but net_context, I need to get it working on net_context (although maybe converting it to sockets could be a solution).

    My problem is that my server stops receiving data after I got maybe 20 messanges. After maybe 20 messanges, my TCP server is not able to receive any data. If I close connection with client and re-open it, I am able to receive new 20 messanges (maybe 20). After this, the connection freezes. Only if I re-open connectin with client, I am able to receive data (only 20 messages and them freeze).

    I want to be able receive messages without any limit on the number (using TCP). Each message could be 8192 bytes length. Maybe 100 messages per minute per connection. 

    Personally, I think the problem is in memories, buffers and packets management. I don't really understand it, I think my buffers are overflowing and then the packets are being dropped, which is why the callback for the receive event is not triggered.

    I attached my settings in my previous post (main post) and I would like to ask for your assessment of whether I am working correctly with memory, buffers, packets, etc. I am not very familiar with this yet.

    Kind regards

    Jaroslav

  • Hi Mathias,

                          I thing for start it will be hard to understand each other. Maybe it is because I am not able to decribe my problem. But I can send project (in .zip) or a video when I show issue. If you are interested, please give me some contact or link for send a video or complete project.

    Kind regards

    Jaroslav

  • Hi Mathias,

                        I have some news, that can help us solve problem with TCP server. I also implemented the TCP server in another project based on the SoftAP example. It's a different project, based on the fact that the nrf7002-DK behaves as an AP, there is no scan, etc., but the implementation of my TCP server is the same.I found exactly the same behavior of the TCP server. In the case when the TCP server receives several messages, it is blocked (frozen). It does not accept any more messages on a specific connection with the client. The number of messages is smaller (about 4 to 5), this is because the buffer sizes are specified differently.

    I think the problem arises with memory release.

    The implementation of the server and callback for receiving data is the same as in the main post.

    Kind Regards

    Jaroslav

  • Hi, Jaroslav.

    I got some input from a colleague that you should use POSIX sockets. Have a look at the HTTPS Client and UDP samples for references.

    Best regards,
    Mathias

Related