lwip-devel
[Top][All Lists]
Advanced

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

Re: [lwip-devel] TCP Client system fault


From: Vinicius Bernardi
Subject: Re: [lwip-devel] TCP Client system fault
Date: Mon, 7 May 2012 22:47:30 -0300


I'm calling sigHUP from the same thread that manage all PPP stuff.

That doesn't mean it's correct. Please have a close look at the current PPP code (versions before 1.4.0 had threading bugs in the ppp input path, so please ensure you take at least 1.4.0 as a reference!). You will find that only the unescaping is done in a separate ppp input thread (plus receiving bytes, but your sio implementation has to be thread safe then, to allow RX and TX to happen from different threads!).

I'm using 1.4.1, but my sio it's not thread safe, at least I didn't pay attention for this.
How do you describe the easy way to integrate both PPP and TCP as there is no reference for that at LWIP code.

Take a look at my actual code : 

First thread : There is only the internal LWIP tcpip_thread ( no changes ) 
Second thread : There is only netconn_* api's ( no additional PPP or another stuff's ) 
Third thread : GSM modem control ( AT commands ) and when the PPP is reached I have this below code : 

              size = sio_read(0, g_GSMBufferRx, 2048);
              if (size == 0)
                 g_gsm_ppp_timeout++;
              pppos_input(0, g_GSMBufferRx, size);

The init code it's something like this : 

            gsm_close_last_ppp();            
            pppInit();
            
            pppSetAuth(PPPAUTHTYPE_ANY, user, password);
            
            g_gsm_ppp_channel = pppOverSerialOpen((void *)SC_GSM_MODEM, gsmPPPCallback, (void *)NULL);

In case of fail, or if I need to close ppp Channel to use it later I use this code : 

   if (g_gsm_ppp_channel != 0xFF)
   {
      pppSigHUP(g_gsm_ppp_channel);
      g_gsm_ppp_channel = 0xFF;
   }

I have just one ppp channel , and just one tcp connection.

Do you have any suggestion, any other model or sample code to follow?

Understanding that only PPP code should call TX and RX, in this mode do you see any issues with actual code?

I had stressed all code, and already turn back the code that you explained, and there is no additional issues, so I understand that for now, there is no additional bugs. ( it's only necessary to activate the MULTITHREAD support of PPP, and this support make TCP to block, and then input data (in a safe way)


No a additional question : How can I be called only when 2 fragments are already available? and how to be called only when it's already transmited.
Because right now I'm receiving callbacks for both parts, not only for full package.

When I say callback I'm talking about functions like this : 

static err_t
sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
{
  struct netconn *conn = (struct netconn *)arg;

  LWIP_UNUSED_ARG(pcb);
  LWIP_ASSERT("conn != NULL", (conn != NULL));

  if (conn->state == NETCONN_WRITE) {
    do_writemore(conn);
  } else if (conn->state == NETCONN_CLOSE) {
    do_close_internal(conn);
  }

  if (conn) {
    /* If the queued byte- or pbuf-count drops below the configured low-water limit,
       let select mark this pcb as writable again. */
    if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) &&
      (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) {
      conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE;
      API_EVENT(conn, NETCONN_EVT_SENDPLUS, len); <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    }
  }
  
  return ERR_OK;
}


Once a packet is unescaped, it is passed into the tcpip_thread by calling pppInput() via tcpip_callback(). Note that pppSigHup() (if that's what you mean by 'sigHUP') is *not* called from this thread in the original lwIP sources (in fact, it's not called from anywhere).

I explained how I'm using the pppSigHup, SIO and all ppp stuff in just one thread, more or less like we have the OWN THREAD code ( but including the GSM support )


Now I don't know if the commented code it's necessary or not, but following the same way, there is no reason to depend's on that code, if the callback functions are optional.

The callback function where you removed code from is *not* optional, it is a vital part of TCP netconns/sockets to work. I'm guessing you mean the callback function that can be passed to netconn_new_with_callback(), but that's a totally different callback. Believe me when I assure you the code you removed *is* necessary and if an ACK can come in while a write is being processed, your threading is messed up!

You are right, what is option is the EVENT the function it self it's not option. Thanks for clarifying !

I'm already using RC1 code, and I still have doubts about PORT requirements, and if the model it's ok, do you have additional tips, or maybe some sample code?
I'm using uC/OS-II and Cortex-M4 MCU.



Simon

reply via email to

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