FreeRTOS_connect() result

Hi! Which result of the function FreeRTOS_connect() call is considered successful? In the example Code , only 0 is considered successful, but there may be an answer -
pdFREERTOS_ERRNO_EALREADY. Is this also a successful result and is it possible to continue receiving and sending data via a socket?

I can’t see that pdFREERTOS_ERRNO_EALREADY is used in the TCP code. Which version are you using? Can you link to the line number?

Hi! it is not used in the example above. I wanted to clarify how correct it is not to use pdFREERTOS_ERRNO_EALREADY code answer. The link in my previous post contains a link to a specific line (89) in the file sockets_wrapper.c in the coreMQTTAgent demo project.

It is not about the example. I do not see this error code anywhere in the library - GitHub - FreeRTOS/FreeRTOS-Plus-TCP: FreeRTOS-Plus-TCP library repository. +TCP files only. Submoduled into https://github.com/FreeRTOS/FreeRTOS and various other repos.. If the error code is not returned by the library, it cannot be used in the application. Or are you talking about introducing this new error code?

Hi @aggarg, @rtel
Sorry, I made a mistake. The error code is -127 which corresponds to pdFREERTOS_ERRNO_EISCONN. But in any case, in the example, the check is only for 0. How correct is this solution?

This is part of my code:

      state = FreeRTOS_connect(conn->socket,&server,sizeof(server));
      LogDebug(("Con result %x",state));

This is part of output log:

 [18:44:08:283] < [DEBUG] [VTK] [vtk_con_open:113] 
 [18:44:08:283] < Con result ffffff81

I looked at the wrong line in the definitions and copied it. Sorry for misleading you.

#define pdFREERTOS_ERRNO_EALREADY         120 /* Socket already connected */
#define pdFREERTOS_ERRNO_EISCONN          127 /* Socket is already connected */

Thank you for clarifying. In general, attempting to perform connect on a connected socket is an application bug. Still if you need that, feel free to modify the demo code as per your needs.

Hi, @aggarg . How i can send RST packet to the device?I am establishing a connection with the device. Then I reset my FreeRTOS-based device. And the program tries to establish a connection with the device again. But the device stops responding to SYN packets, Perhaps because it considers the connection open because there was no proper close socket (FIN). How do I tell the device that I need to reset the connection? Below is my code. and a fragment of WIRESHARK capture. So I guess I need to send an RST or FIN packet. Which function does this? Freertos_FreeRTOS_shutdown?

 state = FreeRTOS_connect(conn->socket,&server,sizeof(server));
      LogDebug(("Con result %d",(int)state));
      if ( (state !=0) )
       {
           LogDebug(("Try to reset socket"));
           //Sockets_Disconnect(conn->socket); 
           FreeRTOS_shutdown(conn->socket,FREERTOS_SHUT_RDWR); 
                for (;;)
                 {
                   xResult = FreeRTOS_recv(conn->socket,pDummyBuffer,sizeof(pDummyBuffer),0);
                     if ( ( xResult < 0 ) && ( xResult != -pdFREERTOS_ERRNO_EWOULDBLOCK ) )
                          break;
                 } 


The connection will be restored if I unplug and plug again network cable of the target device.

How are you resetting the FreeRTOS device?

If you’re removing the power source then I’d assume the connection and all information around the connection would be lost - so you should just be able to kill the connection from the connectors-side and try again.

If you’re hitting some kind of reset function, then I’d recommend you tear down the socket completely which should consist of a call to FreeRTOS_shutdown followed by a call to FreeRTOS_closesocket(). You can use the example here are reference.

1 Like

HI! @kstribrn thank you for reply. Yes, resetting the device completely clears the data jn the connector side (Freertos device). After restarting and calling theFreeRTOS_connect() function, the function returns the code -116 (* Connection timed out */), because the device stops responding to new ACK requests. then I call the FreeRTOS_shutdown() function, but I don’t see that RST packets would be generated for the target (192.168.51.10) device to reset the last connection on the target device side. How do I force an RST packet to be sent, I assume that the function FreeRTOS_shutdown() does not send RST if the socket status is closed


. How do I force an RST packet to be sent?

if the peer does not respond to SYN packets but is generally operating (ie a concurrent ping succeeds), that means that the SYN backlog queue (ie the number passed to listen() on the peer side) is exhausted - or some kind of firewall in between silently discards the SYN request, possibly due to some kind of anti spam policy (what is the network infra structure between your device and server)?

IMHO, this is a suboptimal requirement in RFC 733 - the SYN is silently dropped by the server if the queue is full, making it impossible for the client to distinguish between a dropped connection or a general unreachability.

You can not remotely force an existing connection closed that FreeRTOS does not know about, eg if you come out of reset and there is an existing half open connection from the last power cycle. You may want to check if your server can be configured to support a bigger backlog queue. Innthat context, it is also worth knowing how many concurrent requests your server can handle at the same time - if the server is coded as

do {accept,handle,close} forever

instead of

do {accept, spawn worker thread which closes} forever

, you will pontentially always face communication problems. A working communication always requires both peers to be coded sufficiently for the use case at hand.

I believe that the protocol is incorrectly implemented in the target device.Please see attached image

Network disconect behaviour - Libraries - FreeRTOS Community Forums

I believe we discussed this before.

No,
in this post, I asked a question about the network behavior on a device(192.168.51.13) with freertos on board that I am developing. And I have a problem with a device(192.168.51.10) from another developer, whose program I do not have access to at all. When I mentioned disconnecting the cable here, I was not disconnecting the cable from my device. And it is not my device that is not responding to SYN packets. For me, this device (192.168.51.10)is a black box inside, I am not its developer, but I am trying to establish a connection with it from my FREERTOS device(192.168.51.13)

well yes, of course, if the server application is buggy, then it may well be the culprit of the communication problems you are experiencing.

One thing that strikes me odd is that the source port numbers for which the server sends RSTs are very far apart. What normally happens (I do not know if FreeRTOS+TCP does it that way as well, though) is that unless your client binds the local port explicitly prior to connecting (which is very rare), the stack selects a local port in numeric ascending order before reestablishing a connection.

So if you get two RSTs from the server for long gone connections in rapid succession, that would be a hint that the server has a bug in which it at times keeps an existing connection open. Does your log reach back long enough to trace when those connections were established? Or could you have an ip address conflich in your network (you can easily verify that by looking at the MAC addresses)?

Btw, any reasonably well coded networking app uses timeouts to ensure that interrupted connections will eventually terminate. Could it be the case that the server app has either no timouts at all or atrociously long ones?

few hours.

The server device is a specific device for non-cash payment in a vending machine. Judging by its hostname, it is assembled on an espressif chip. LWIP is possible inside it. No matter how long the device has been in error, the socket is not reset from the server side. There is no timeout. And I’m looking for a software way to reset the connection on the server side.

if the server is stuck, say, on a blocking recv() with no timeout and possibly incomplete handling of error codes in the application code, there is nothing you can do on the client side to get it out of that state. If the server is a complete black box, ie something where you can not even install additional software (eg a tcp or udp server that waits for “reset me hard” command), you do have a problem…

Note that none of that is a problem or shortcoming of tcp, just of tcp application code.

Possibly the server suffers from a very common pitfall in socket programming, that is, assumes that a recv() with a small number of requested bytes would always return the bytes in a single chunk. It does not; even a recv(,…4…) may fragment the transmission into smaller chunks - the return value of recv() will tell you how many bytes actually were read; if need be, you need to resubmit recv() calls for the rest. I can not recall how many times I saw code like

if (recv(,…x…) > 0)

which will almost inevitably cause very nasty comm problems of all kinds.

2 Likes

@RAc I absolutely agree with you. I started communicating with the developers of the server device. Perhaps the tcp keepalive mechanism will help solve the problem. The server device responds to keepalive packets.but does not close the socket if they are missing.