cancel
Showing results for 
Search instead for 
Did you mean: 

setting a backlog, response issue with TCP Raw Socket Server

VSomasekhar
Associate II
  1. How to set the number of simultaneous connections (backlog) in the Raw Socket Listen API? This is the relevant code snippet: /* start tcp listening for echo_pcb */ tcp_echoserver_pcb = tcp_listen( tcp_echoserver_pcb ); In contrast, the BSD/LWIP Sockets Listen API is: int lwip_listen(int s, int backlog)
  2. Do I have to enable this macro in opt.h for the above purpose? #define TCP_LISTEN_BACKLOG
  3. I am running a modified TCP Echo Server on the Board and sending continuous sequence of Modbus requests from the Modscan32 tool to the Modbus server running on the Board with STM32H723Zet6 MCU. But the response is given only to the first Request. The TCP Server is based on the source in the webpage: https://community.st.com/t5/stm32-mcus-embedded-software/how-to-send-data-lwip-tcp-server-to-client/td-p/119556
  4. How to modify the TCP Raw Socket Server mentioned above to send the response for all the request packets? As mentioned, the TCP Raw Socket Server is responding only once, that too after restart.
22 REPLIES 22
STea
ST Employee

Hello @VSomasekhar,

By tweaking the options in lwipopts.h, it should be possible to receive more incoming connections: MEMP_NUM_TCP_PCB, MEMP_NUM_TCP_PCB_LISTEN, MEMP_NUM_NETCONN, etc...

You can refer to the following link for lwIP internal memory pool management: http://www.nongnu.org/lwip/2_0_x/group__lwip__opts__memp.html.

Refer to Solved: How to tune LwIP to receive more incoming connecti... - STMicroelectronics Community

Regards

 

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
STea
ST Employee

Hello @VSomasekhar,

Any updates on this ?

Regards

 

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi,

I've found the specified Macros at: 

STM32CubeIDE\workspace_1.13.2\J1424\Middlewares\Third_Party\LwIP\src\include\lwip\opt.h

Those Macros are already having certain default values. I am not exactly sure what other values should be there for these Macros. I've attached a text file (partof_opts.h) with these Macros definitions in the opts.h file. Please check and mention if these default values are OK.

Let me make the observation more clear:

When I connect the ModScan32 tool to the Modbus server on the Board, the very first request will be answered correctly in a Modbus response packet. The tool continues to send the requests, which are not answered. Since this Modbus server is based on the TCP Raw Socket Echo server, it simply echoes the request data in the response packet for the 2nd request onwards. Hope this helps. 

Hello @VSomasekhar ,

This is clearly a problem with your implementation of callbacks when receiving a message. can you share the app implementation in which you construct the Modbus response. as you based your implementation on the TCP Raw Socket Echo server example you need to construct a packet for each message received in tcp_echoserver.c I assume.
Regards

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi,

I have attached the TCP Raw Server .c and .h files in text format, also described below.

RawTCPServer.c : This contains the entry point to the TCP Raw Server, tcpRawServer(), which is called from the main application. This function calls tcp_echoserver_init(portnum), which takes the execution through the raw socket APIs.

RawTCPServer.h : This contains the implementation of all the TCP raw socket APIs. In the function tcp_echoserver_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err), the 3rd parameter contains the packet buffer pointer having the Modbus request packet. When the Echo Server state is ES_ACCEPTED, I've passed the same packet buffer pointer p, to the Modbus entry point, as given below.

//Modbus entry point

pTx = ModbusIxFace(p);

 

p is processed internally within the Modbus protocol and a response packet is generated, and received into pTx,

which is then linked to the echo server structure 'es' and sent out using the following statement.

/* send back the received data (echo) */

tcp_echoserver_send(tpcb, es);

All the details mentioned above are present in the attachments. If any more details are required, I'll provide.

Please help. Thanks.

 

STea
ST Employee

Hello @VSomasekhar ,

In the code you shared in tcp_echoserver_recv you treat the first incoming data with a Modbus response, and you start to echo back the messages received (see the comments in code)

/* first data chunk in p->payload */ the first packet recieved
     es->state = ES_RECEIVED_SERVER;

     //Modbus entry point
     pTx = ModbusIxFace(p);

     /* store reference to incoming pbuf (chain) */
     es->p = pTx;
     
     /* initialize LwIP tcp_sent callback function */
     tcp_sent(tpcb, tcp_echoserver_sent);

     /* send back the received data (echo) */
     tcp_echoserver_send(tpcb, es);

     ret_err = ERR_OK;
   }
   else if (es->state == ES_RECEIVED_SERVER)
   {
     /* more data received from client and previous data has been already sent*/other packets
     if(es->p == NULL)
     {
       es->p = p; //pTx->next;

       /* send back received data */
       tcp_echoserver_send(tpcb, es);
     }

 

try adding the Modbus entry function before passing the pointer to buffer structure to handle "more data received form client "
/* first data chunk in p->payload */ the first packet recieved
     es->state = ES_RECEIVED_SERVER;

     //Modbus entry point
     pTx = ModbusIxFace(p);

     /* store reference to incoming pbuf (chain) */
     es->p = pTx;
     
     /* initialize LwIP tcp_sent callback function */
     tcp_sent(tpcb, tcp_echoserver_sent);

     /* send back the received data (echo) */
     tcp_echoserver_send(tpcb, es);

     ret_err = ERR_OK;
   }
   else if (es->state == ES_RECEIVED_SERVER)
   {
     /* more data received from client and previous data has been already sent*/other packets
     if(es->p == NULL)
     {
       //Modbus entry point
     pTx = ModbusIxFace(p);
     /* store reference to incoming pbuf (chain) */
     es->p = pTx;
       /* send back received data */
       tcp_echoserver_send(tpcb, es);
     }

this is my suggestion after seeing you code and what I got from your description of its behavior. I'm still clawless to the way the ModbusIxFace() function constructs Modbus packets.
Regards



In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

I have implemented the suggested code change. Now I'm getting more number of responses, around 8-12. After that, the server-client connection is breaking. The server continues to run, but there is no ping response and Modbus response from the Board.

These are the requested details regarding the Modbus processing. The ModbusIxFace(..) function is implemented as follows:

 

struct pbuf * ModbusIxFace(struct pbuf *p)

{

MBDEFS_BOOL mbHandle;

struct pbuf *pTx = pbuf_alloc(Layer, TX_BUFFER_SIZE, bufType);

mbHandle = HandleModbusRequest(p->payload);

memcpy(pTx->payload, (void *)(QUERY_MESG_HEADER *)MBSlave_SendBuffer, sizeof(MBSlave_SendBuffer));

//pIx = p;

return pTx;

}

 

The HandleModbusRequest(p->payload) function receives the Modbus request packet in payload of

the packet buffer p. The payload is typecasted into the Modbus packet structure, and the internal

fields are accessed. As per the Modbus protocol specification, the field values are processed, and

the response is built into the byte array, as given below:

MBSlave_SendBuffer[TX_BUFFER_SIZE]

This byte array is copied into the payload of the received packet buffer, pTx, as shown in the

above function.

Although one response packet is sufficient for one request, the response has to be there for

every request. Please help in this regard.

One small correction please. pTx is a new packet buffer and not the received packet buffer. 

VSomasekhar
Associate II

Today's observations: The ModPoll tool continuously sends the configured Modbus requests. With the suggested source code changes, the expected Modbus response is sent for the first 9 requests. I've repeated and confirmed that this is the case. Why is it 9? After 9 responses, it is falling back to echo server mode. I can see the logic in the suggested code changes, and I think it should work. Or maybe the state changes have to be managed more suitably? Or a different Server altogether need to be installed? My initial understanding was that by properly setting the Response, it should be possible to change it to a standard server. I did this attempt, as I couldn't find a better option. I need help in this regard. Many thanks in advance.