I am using FreeRTOS + LwIP to develop a Ethernet based bedside nurse call device. After reading some examples and document, I want to use the LwIP's netconn API to send and receive data under TCP, because I am not familiar with the BSD style API and the raw API may be difficult.
I know the netconn_accept()
function will block the process until a connection request from a remote host arrived, and the netconn_recv()
function will also block the process while waiting for data to arrive...both of these functions will block the process, it is good for a server receiving data, however, my device also need to act as a client which need to trigger a 'call' to the nurse center when the patient press a button. So how can it initiates to send a TCP packet while it is also waiting a connection(blocking the process) from the remote host?
I need to send TCP because I have to use SIP(Session Initiation Protocol) to initiate a call, the it should be reliable because it is a medical device. Thank you very much
@Kyle Heironimus , @werewindle I add you to my question because I know you have experience on LwIP, hope that will not make you inconvenience and hope that you can help, thank you.
You cannot send data to a remote host before it has initiated a connection. That just doesn't make any sense. My question is: do you want your device connect to the remote host, or do you want the remote host initiate a connection to your device?
Right now you're using netconn_accept in your device - that means that you are waiting for the remote host to initiate a connection to your device before your device can signal the remote host. This is entirely expected behavior for the code you've written yet you seem concerned about this. Is this not your intention? If not, why did you code it that way? The other alternative is to have your device initiate the connection to the remote host. There's an example of that use of netconns here. Of course, this involves changes to the other device in your system as well.
So the moral of that story is that you can't send any data when no connection is present, and you're waiting for a connection before you send data. You don't want to wait for the connection, so you have to change your software to initiate the connection rather than wait for the other side to initiate it.
Another problem you might run into is that you want to be able to send and receive data on the same connection at the same time. Most examples I saw for lwip involves blocking calls waiting for data, then reacting to that data by transmitting something back. Sometimes you want to transmit something back without receiving something first. I can help with that too.
This is what worked for me when I created a listening netconn connection.
First, you have to enable timeouts by setting:
#define LWIP_SO_RCVTIMEO 1
Then you have to set up your netconn similarly to this:
pxTCPListener = netconn_new (NETCONN_TCP);
netconn_bind (pxTCPListener, NULL, 23);
netconn_listen (pxTCPListener);
pxNewConnection = netconn_accept (pxTCPListener); //This blocks until connection is accepted
//This is the important line!
pxNewConnection->recv_timeout = 10; //note This is millseconds - lwip works in ms
//This loops until the connection is closed
while(!ERR_IS_FATAL(pxNewConnection->err)) { //Fatal errors include connections being closed, reset, aborted, etc
//This netconn_recv call will now wait 10ms for any new data, then return
if ((pxRxBuffer = netconn_recv (pxNewConnection)) != NULL) {
//Handle received data
}
//Here, do any transmits you want
} //End of while loop from above
That code will allow you to do transmits and receives at the same time without worrying about blocking.