lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] netconn_recv blocking forever


From: Çağlar AKYÜZ
Subject: Re: [lwip-users] netconn_recv blocking forever
Date: Thu, 08 Mar 2007 16:29:13 +0200
User-agent: Mozilla Thunderbird 1.5.0.10 (Windows/20070221)

Mateusz Plocinski wrote:
Hi,
I'm using an ARM7 FreeRTOS port of lwip. I'm trying to implement a
thread which waits for data from PC using netconn_recv. Everything
works fine in most situations (for week or longer without any
problems), but when I disconnect network cable or PC simply hangs up
without closing a connection, my lwip socket thread still sits in
netconn_recv function.

Is there any way to check if connection isnt dead while thread is
blocked in netconn_recv? I need to know in few seconds if I should
close connection because I need to quickly restart connection to my
ARM hardware (and I have only on thread so I cant open more sockets to
wait for connection).

Just don't use netconn_recv. Instead use raw api with callbacks enabled. Then sleep in your task with vTaskDelayUntil api of FreeRTOS. This way if something goes wrong, you won't be blocking
forever in netconn_recv and you will have a chance to correct things up.

There is a nice code in the list illustrating the use of raw api. I'm using this code happly with my SAM7X with FreeRTOS installed. I searched thru the list but unable to find the link. So I'm attaching my own modified version.

By the way, using raw api is not that much hard. I was able to migrate my code from netconn api to raw api in hours keeping
in mind that I'm not a code guru. Just give it a try.

Regards
Caglar AKYUZ


err_t netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
/* This callback function is called when stack receives data from the MAC
    * interface(on our port of course). Then we can process this message
*/ static int settings[SETTINGS_LENGTH];
   (void) arg;
   if (err == ERR_OK && p != NULL)
   {
       /* if config_mode is not 0, then we are in configuration mode */
       if( config_mode ) {
configure_device_tcp( &settings[0] , pcb , p ); } else {
           /* Process message then if we are not in config mode */
process_tcp_message( &settings[0] , pcb , p ); } /* Acknowledge stack that we have processed the message so that it can
        * inrcrease window size
       ,
        */
       tcp_recved(pcb, p->tot_len);
       /* Never forget to free a buffer! */
pbuf_free(p); }
   else
       pbuf_free(p); /* Never forget to free a buffer! */

   if (err == ERR_OK && p == NULL)
   {
/* If we are here this means that other side has closed the connection. */
       tcp_arg(pcb, NULL);
       tcp_sent(pcb, NULL);
       tcp_recv(pcb, NULL);
       tcp_close(pcb);
       pioA_toggle_led( 1 );
/* Inform mac task that communication is closed. Otherwise, it will immediately * send conversion data as soon as a client arrives without waiting the
        * send commdand.
        */
       comm_open = 0;
   }
   return ERR_OK;
}

err_t netio_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
/* When there is a connection request this function is called by the stack */
   (void) arg;
   (void) err;
   tcp_arg(pcb, NULL);
   tcp_sent(pcb, NULL);
/* Inform stack about which function to call-back when there is data on the line */
   tcp_recv(pcb, netio_recv);
/* Hold the accepted connection pcb. This will used later when we desire to send
    * data asynchronously from the receive callback function
    */
   netio_pcb = pcb;
   pioA_toggle_led( 0 );
   return ERR_OK;
}

struct tcp_pcb* netio_init(void)
{
/* This function initalizes the connection. We start listenin on the desired port * and our defined callback function to be called by the stack when someone
    * arrives
    */
   struct tcp_pcb *pcb;
pcb = tcp_new();
   tcp_bind(pcb, IP_ADDR_ANY, SETTINGS_PAGE[LOCAL_PORT]);
pcb = tcp_listen(pcb); tcp_accept(pcb, netio_accept);
   return pcb;
}





reply via email to

[Prev in Thread] Current Thread [Next in Thread]