Author Topic: TCP Buffer  (Read 37059 times)

Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: TCP Buffer
« Reply #30 on: February 02, 2009, 11:01:52 AM »
Hi Mark,
 I use fnSendBufTCP() to send info, how to I flush the buffer it uses?

Neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: TCP Buffer
« Reply #31 on: February 02, 2009, 11:45:53 AM »
Hi Neil

The buffer is flushed when a connection is closed (see fnResetWindowing() in tcp.c).

It shouldn't be necessary to flush it at any other time - and also quite complicated since it may be used for TCP activity. Closing a connection should therefore be the best method.

Regards

Mark


Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: TCP Buffer
« Reply #32 on: February 02, 2009, 07:46:57 PM »
Hi Mark,
 I am having problems when using fnSendBufTCP(), the processor locks up. I am having problems debugging it as you described, but looked at my code and looks fine. As I am not to sure on how the callback function works with partial acks etc, can you let me know if okay?.

 Here is a copy of my callback function. There is only about 100 characters at a time being sent (will be more when I get it working) and have the following defines:
    #define TCP_BUFFER                2800                               // size of TCP buffer (with USE_BUFFERED_TCP) - generous with M5223X
    #define TCP_BUFFER_FRAME          1400                               // allow this max. TCP frame size
  #define SUPPORT_PEER_WINDOW                                  // respect peer's Open Window when sending TCP frames
        #define WINDOWING_BUFFERS      4                             // we can send 4 frames before requiring ACKs
         #define CONTROL_WINDOW_SIZE     

And the callback function..
  its the TCP_EVENT_ACK and TCP_EVENT_PARTIAL_ACK im not sure about..

int fnTCP(USOCKET Socket, unsigned char ucEvent, unsigned char *ucIp_Data, unsigned short usPortLen)
{
   TCP_MESSAGE test_message;
   unsigned char Value;
   int Loop;
    
    switch (ucEvent) {
    case TCP_EVENT_CONNECTED:
                Diagnostic_TCPSocket.Diagnostics=1;
                ConnectionInfo.DiagHeartbeat=3; //gets decreased in seconds, then send heartbeat to app.
                   break;
    case TCP_EVENT_CLOSE:
      
    case TCP_EVENT_CONREQ:  break;                                           
   
    case TCP_EVENT_ACK:       
     if (fnSendBufTCP(Socket, 0, 0, TCP_BUF_NEXT)) {                  // send next buffered (if waiting)
            return APP_SENT_DATA;                                     // mark that data has been transmitted
        }
      break;
   
    case TCP_EVENT_ARP_RESOLUTION_FAILED:
        break;
    case TCP_EVENT_PARTIAL_ACK:
        if (fnSendBufTCP(Socket, 0, 0, TCP_BUF_REP)) {                   // repeat send buffered
  #ifdef SUPPORT_PEER_WINDOW
            fnSendBufTCP(Socket, 0, 0, (TCP_BUF_NEXT | TCP_BUF_KICK_NEXT)); // kick off any following data as long as windowing allows it
  #endif
            return APP_SENT_DATA;
       }
       break;
    case TCP_EVENT_REGENERATE:
       break;
    case TCP_EVENT_DATA:
                   for(Loop=0;Loop<usPortLen;Loop++)
                   {
                      Value=ucIp_Data[Loop];
                     .. save in buffer here...
                   }
                    break;
    case TCP_EVENT_ABORT:
    case TCP_EVENT_CLOSED:
      Diagnostic_TCPSocket.Diagnostics=0;
      fnTCP_close(Socket);
        break;
        }

    return APP_ACCEPT;
}

Regards
Neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: TCP Buffer
« Reply #33 on: February 02, 2009, 09:24:38 PM »
Hi Neil

You can also use fnTELNETListener() in telnet.c as a reference. This also using buffered TCP.

This is the partial ACK handling that it performs:

#ifdef SUPPORT_PEER_WINDOW
    case TCP_EVENT_PARTIAL_ACK:                                          // possible ack to a part of a transmission received
        if (TELNET_session->wakeOnAck) {
            uTaskerStateChange(TELNET_session->wakeOnAck, UTASKER_ACTIVATE); // wake application so that it can continue with queued receive data
        }

        if (fnSendBufTCP(Socket, 0, usPortLen, TCP_BUF_NEXT)) {          // send next buffered (if waiting)
            return APP_SENT_DATA;
        }
        break;
#endif



I think that your use in this case is incorrect (it is the code from the regenerate case). This means that it tries to resent the last frame rather continuing with next chunks from the buffer.

Regards

Mark

Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: TCP Buffer
« Reply #34 on: February 02, 2009, 10:20:33 PM »
Hi Mark,
 
I see the 'TCP_EVENT_PARTIAL_ACK' , 'TCP_EVENT_ACK' and 'TCP_EVENT_REGENERATE' is used , but these use the Telit structure, and also a task is state is changed uTaskerStateChange(..).

What do I add in their place as Im not using Telit, and only buffers?  Also if I have to add the uTaskerStateChange(..) what task is it effecting?

Neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: TCP Buffer
« Reply #35 on: February 02, 2009, 11:10:28 PM »
Hi Neil

You can ignore the Telnet session specific things. Just look at the way that it interacts with fnSendBufTCP(). The rest is 'application' (in this case Telnet) specific.

Eg. in the partial ack case simple do

        if (fnSendBufTCP(Socket, 0, usPortLen, TCP_BUF_NEXT)) {          // send next buffered (if waiting)
            return APP_SENT_DATA;
        }


In the ACK case, just

        if (fnSendBufTCP(Socket, 0, 0, TCP_BUF_NEXT)) {                  // send next buffered (if waiting)
            iReturn = APP_SENT_DATA;                                     // mark that data has been transmitted
        }


In the regenerate case you can copy all of it.

Of course you can also add your own application specific things as well if it makes sense but probably not for your case.

Regards

Mark


Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: TCP Buffer
« Reply #36 on: February 02, 2009, 11:30:20 PM »
Hi Mark,
  Thanks for that, Im just not familiar with these low level tcp sequences.

Regards

Neil

Offline neil

  • Sr. Member
  • ****
  • Posts: 438
    • View Profile
Re: TCP Buffer
« Reply #37 on: February 02, 2009, 11:53:10 PM »
Hi Mark,
  I noticed that the
case TCP_EVENT_PARTIAL_ACK: 

 in telnet has the following around it:

#ifdef SUPPORT_PEER_WINDOW

is it best to have this in my call back too?

Regards
Neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: TCP Buffer
« Reply #38 on: February 03, 2009, 12:23:55 AM »
Hi Neil

When working with windowing the peer's TCP Windows should generally be respected - if the peer is slow and you are sending a lot of data quickly it would otherwise be possible to close its receive window and then over run it. With the small amounts of data you are sending it will never actually happen (unless the receiver is a very weak device with small memory buffer  - eg. an 8-bit micro with only 1k of receiver space). But I would enable it since it hardly has any extra overhead and then it fully respects TCP operation.

Regards

Mark