We are using LWIP 1.3.2(as ported by TexasInstruments), IAR compiler targeting 
a stellaris MCU.
The TI implementation uses a timer tick interrupt 100 times/sec to service the 
LWIP stack.  No RTOS involved. Our application code also runs on this same 
timer tick interrupt so no concurrency issues in play.

We implemented a webservice http client over tcp.
Periodically(about 1-2 times per day), we miss ACKs in the application layer. 
Plain and simple, our tcp_sent callback does not get called. We have timers 
that expire if the ack is not seen.
I have captured the WireShark trace and the ack is being transmitted. For some 
reason the lwip stack does not inform the application layer. I don't know if 
the LWIP stack sees the ack or not.

The odd thing is that under normal load conditions the code works and transmits 
2-3 large HTTP posts/second. This means that within a 12 hour period it works 
2*60*60 *12= 86,400 times without error.

I have adjusted the lwipopts.h settings over and over and nothing seems to 
affect the problem.

I have scanned the 1.4.1 changelog and do not see any defects that specifically 
address this problem, Further complicating the issue is that TI has not ported 
1.4.1. If they had I would have tried it to see if it solves the problem. I am 
not sure how much effort it will be to do the port myself. I am willing to do 
it if there is a specific defect that address my issue.




Here is how the callbacks are being set up:


  if(s_Pcb == NULL)
  {
    s_Pcb = tcp_new();
    err_t bindResult = tcp_bind(s_Pcb, IP_ADDR_ANY, PortNumber);

    UpdateCounters(&g_Diagnostics.BindCounters, bindResult);

    if(bindResult != ERR_OK)
    {
      ClosePcb();
      // try again next time
      return;
    }

    // Setup the TCP callback functions
    tcp_err(s_Pcb, OnError);
    tcp_sent(s_Pcb, OnSent);
    tcp_recv(s_Pcb, OnReceive);

    return;
  }

How we send a chunk of the overall HTTP message:

//*****************************************************************************
// Send next chunk of the message.
//*****************************************************************************
void ContinueTransmittingHttpPostMessage()
{
  err_t result;

  g_BytesAvailable = tcp_sndbuf(s_Pcb);
  g_BytesToSend = Message.StopIndex - Message.TransmitIndex;
  if(g_BytesToSend > 0)
  {
    if(g_BytesToSend > TCP_WND)
    {
      g_BytesToSend = TCP_WND;
    }
    if(g_BytesAvailable >= g_BytesToSend)
    {
      result = tcp_write(s_Pcb, &Message.Body[Message.TransmitIndex], 
g_BytesToSend, 0);
      UpdateCounters(&g_Diagnostics.WriteCounters, result);
      if(result == ERR_OK)
      {
        g_Diagnostics.ulTotalBytesWritten += g_BytesToSend;
        Message.TransmitIndex += g_BytesToSend;
        Message.State = Sending;
        SetTimeout(&Message.StateTimer, 2 Sec);
      }
      else
      {
        StopTransmittingHttpPostMessage();
      }
    }
    else
    {
      g_Diagnostics.ulSendBufferFullErrors++;
    }
  }
}

The tcp_sent callback that doesn't get call (sometimes).

//*****************************************************************************
// Our TCP sent callback.
// Look at tcp_sent for for information.
//*****************************************************************************
static err_t OnSent(void *arg, struct tcp_pcb *pcb, u16_t numBytesAcknowledged)
{
  // Service the watchdog timer
  ServiceWatchdogTimer();

  // We only get called if the web service received > 0 bytes
  g_Diagnostics.ulOnSentCallbacks++;
  g_Diagnostics.ulTotalBytesAcknowledged +=numBytesAcknowledged;

  if(Message.State == Sending)
  {
    Message.BytesAcked += numBytesAcknowledged;
    if(Message.TransmitIndex >= Message.StopIndex)
    {
      if(Message.BytesAcked >= Message.StopIndex)
      {
        Message.State = WaitingForOk;
        SetTimeout(&Message.StateTimer, 2 Sec);
      }
    }
    else
    {
      ContinueTransmittingHttpPostMessage();
    }
  }
  return ERR_OK;
}


John Hoffman
Vice President Software Development
TimeKeeping Systems, Incorporated
30700 Bainbridge Road Unit H
Solon, Ohio  44139
216-595-0890  x108
216-595-0991 (fax)

_______________________________________________
lwip-users mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/lwip-users

Reply via email to