Goodmorning,
I'm using an imxrt1064 processor and I've implemented succesfully a server and client lwip with no operative system. I write you to have some reassurances about the method that I use to reconnect in case of disconnection.
For a TCP server:
When the client disconnect from the board, I simply call the method:
tcp_accept(porttcp_pcb, tcpserver_accept);
since the client send simply a [FIN, ACK] sequence that doesn't erase my tcp_port content.
For a TCP client:
When the server disconnects from the board, I call all over again the inizialization procedure (code below):
err_t tcpclient_initialize(const ip4_addr_t* localIpAddress, u16_t localPort);
err_t tcpclient_connect(const ip4_addr_t* remoteIpAddress, u16_t remotePort);
I have to do that because when the client disconnects, it sends [RST, ACK] which automatically calls
void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb);
that's the reason why I have to initialize all over again.
err_t tcpclient_initialize(const ip4_addr_t* localIpAddress, u16_t localPort)
{
porttcp_pcb2 = tcp_new_ip_type(IPADDR_TYPE_V4);
if (porttcp_pcb2 != NULL)
{
return tcp_bind(porttcp_pcb2, localIpAddress, localPort);
}
return ERR_MEM;
}
err_t tcpclient_connect(const ip4_addr_t* ipAddress, u16_t remotePort)
{
//ip4_addr_t DestIPaddr;
//IP4_ADDR( &DestIPaddr, 192, 168, 0, 100 );
if (porttcp_pcb2 != NULL)
{
err_t err = tcp_connect(porttcp_pcb2, (ip_addr_t*)ipAddress, remotePort, tcpclient_accept);
return err;
}
/* deallocate the pcb */
memp_free(MEMP_TCP_PCB, porttcp_pcb2);
return ERR_MEM;
}
I have two questions:
bool tcpclient_valid(const ip4_addr_t* localIpAddress, u16_t localPort)
{
ip_addr_t *ipAddress = (ip_addr_t*)localIpAddress;
if(porttcp_pcb2 != NULL)
return (porttcp_pcb2->local_port==localPort) & (porttcp_pcb2->local_ip.addr == ipAddress->addr);
return false;
}
Thank you
Solved! Go to Solution.
Hello,
Unfortunately, we do not provide support for the LwIP stack. This is provided "AS IS" and any support on it is done by the community. We can give some guidelines but we are not capable to give full support on this TPCIP stack. Allow me to answer each one of your questions:
The fact that you are using the stack with NON-Operating System makes this more complicated. This is because all this is done based on a super loop and callbacks. Therefore you need to add validation of what would happen if the connection changes to disconnected. Let's take as an example the lwip_tcpecho_bm example, It is possible to activate the keepalive and this will detect when the connection is closed from the other end and this will trigger the ERR_ABRT event on the LwIP. The implementation of what to do if the keepalive happens is what is missing. This would have to be implemented by the application. In this case, the connection should be dropped and a new one should start. This is our suggestion to handle the disconnection from the other side.
In regards to the link-up/down detection. You can add a function on the ethernet interface functions that will allow up to validate the PHY status. This function will return true if the link is up and false if the link is down. The validation of this can be added in the support loop. For this, I have created an example code that shows how to implement this. I took as a base the lwip_tcpecho_bm SDK example and just made a couple of changes in files lwip_tcpecho_bm.c and enet_ethernetif.c. I attached these files here for your reference.
I hope this can help you with the issue. Please let me know if you have any other doubt and I will check how can we help you.
Hello to all,
since I haven't received any answer in the last week, I'm opening a ticket support.
Hello,
Unfortunately, we do not provide support for the LwIP stack. This is provided "AS IS" and any support on it is done by the community. We can give some guidelines but we are not capable to give full support on this TPCIP stack. Allow me to answer each one of your questions:
The fact that you are using the stack with NON-Operating System makes this more complicated. This is because all this is done based on a super loop and callbacks. Therefore you need to add validation of what would happen if the connection changes to disconnected. Let's take as an example the lwip_tcpecho_bm example, It is possible to activate the keepalive and this will detect when the connection is closed from the other end and this will trigger the ERR_ABRT event on the LwIP. The implementation of what to do if the keepalive happens is what is missing. This would have to be implemented by the application. In this case, the connection should be dropped and a new one should start. This is our suggestion to handle the disconnection from the other side.
In regards to the link-up/down detection. You can add a function on the ethernet interface functions that will allow up to validate the PHY status. This function will return true if the link is up and false if the link is down. The validation of this can be added in the support loop. For this, I have created an example code that shows how to implement this. I took as a base the lwip_tcpecho_bm SDK example and just made a couple of changes in files lwip_tcpecho_bm.c and enet_ethernetif.c. I attached these files here for your reference.
I hope this can help you with the issue. Please let me know if you have any other doubt and I will check how can we help you.
Thank you victorjimenez,
I tested the link up/down function and it works.
I'all search on the net about the keep alive with lwIP. You can consider the case solved.
Thank you
Hello,
For the server, it is correct that once the recv or send fails you can just loop back to the accept() so can wait for new connections.
For the client, this is not the way. You should not check for the structures. The best way is to check the send or recv function return code. If the return code is different than ERR_OK then you can just go and close the connection with netconn_close() and then netconn_delete(). After this, you need to create a new socket so you can have a new socket control block to ensure that the connection can be reestablished again with the new foreign port. This foreign port may be a different one and you will no know until you try the connect () again.
Regards,
Victor
Hello victorjimenez,
thank you for your answer.
I try to explain better the situation. My code started from the example tcpecho of NXP SDK. After further tests, I verified that what happens for the client, happens for the server as well. In attachment you can find Wireshark capture where as example the board is a Client connected to the PC Server.
When I close the PC server, as you can see in the attachment, sometimes the simple FIN,ACK sequence is sent by PC and sometimes the RST,ACK is sent. Besides there is a third case where the cable is unplugged and nothing is sent.
When PC transmits FIN, ACK, I can simply connect/accept and the client/server restarts, with RST,ACK the tcp_pcb_remove function is called and I need to reinitialize the socket.
I check for netconn_close() and then netconn_delete() in the SDK API but I didn't find them.
I have two questions:
How can I know if I have to call the simply connect/accept or reinitialize the socket? Simply checking the socket != NULL doesn't work.
How can I know that the cable has been unplugged?
Thank you.