Author Topic: TCP "full duplex" problem (not working)  (Read 14022 times)

MaurizioB

  • Full Member
  • ***
  • Posts: 13
    • View Profile
TCP "full duplex" problem (not working)
« on: August 03, 2007, 01:41:58 AM »
Hello,
I've already posted this message onto another forum section, but I rthink that this is  the best one.
I'm developing an uart-to-tcp-to-uart converter (using two SBC65EC boards) but I'm having problem with "full duplex" communication over TCP:
when both the serial endpoints starts to talk toghether, the TCP stack seems to hang:
I'can see both the yellow leds on the ethernet connectors blinking "furiously" even if the serial endpoints
stops communicating and no more data is transferred by the endpoints.

The problem apperars even if I try this simple test:
- I have two hyperterminal sessions (let's call then "A" and "B")  connected (using COM1 and COM2 @ 9600 bps) to the two endpoins
- if I send one text file (about 40 kbyte) from terminal "A" to teriminal "B" (or vice-versa) everything works well.
- but if, while terminal "B" is receiving data, i press about 4 or five keys wery quiclky on it, I can see some of them
  appear on the terminal "A" and then the communication hangs!
- Even If close the two terminals (or disconnect the rs232 calbes), I can see the yellow leds on the modtronix board blink forever!

Unfortunately I can't see *what* the two boards have to tell eachother (I can't see the network traffic with etherreal analyzer, maybe because my hub doesn't "spread" it to all ports....).

I'm using two SBC65EC boards (the version.txt file of the tcp stack says "V2.47 Modtronix TCP/IP Stack - 2007 February 22")
with the same code loaded on them


My "data pump" code (called at every main loop) is like this

void DataPump(){
// TCP TO UART DATA TRANSFER
if(TCPIsGetReady(TcpSocket)){
   if (TCPGet(TcpSocket, &cTmp)){ // get the header
      if (cTmp==DATA_MARKER){
         while (TCPGet(TcpSocket, &cTmp)) // copy the data to then uart buffer
         serPutByte(cTmp);
      }
      TCPDiscard(TcpSocket);
   }
}

// UART TO TCP DATA TRANSFER
if (TCPIsPutReady(TcpSocket) && serIsGetReady() )
   TCPPut(TcpSocket,DATA_MARKER);   // Packet Header (for future use)
   while(serIsGetReady())
      TCPPut(TcpSocket,serGetByte());
   TCPFlush(TcpSocket);
}
}



Can anyone help me in someway ?


thank you in advance for you help

Maurizio

OmarZ

  • Hero Member
  • *****
  • Posts: 243
    • View Profile
Re: TCP "full duplex" problem (not working)
« Reply #1 on: August 03, 2007, 12:39:35 PM »
If data length is more than 970bytes, you must call StackTask() function while TCPIsPutReady returns not ok.

I had a lot of problems when i made tests to send long messages(> 970 bytes).
Please, read this long post:
http://forum.modtronix.com/index.php?topic=592.msg1693#msg1693

Now, you should know that a possible solution to your problem can be ....

Code: [Select]
// UART TO TCP DATA TRANSFER
if (TCPIsPutReady(TcpSocket) && serIsGetReady() )
   TCPPut(TcpSocket,DATA_MARKER);   // Packet Header (for future use)
   while(serIsGetReady()){
     while(!TCPIsPutReady(TcpSocket))
         StackTask();
     TCPPut(TcpSocket,serGetByte());
   }
   TCPFlush(TcpSocket);
}


Remember that you will receive NOT only one message, but msgLen = data_length/970; messages; so your client application must manage this.

In version 3.04 you do not need to implement this trick, because it allows you to send "unlimited" amount of bytes! So only one message will be send.

« Last Edit: August 03, 2007, 12:44:50 PM by OmarZ »

MaurizioB

  • Full Member
  • ***
  • Posts: 13
    • View Profile
Re: TCP "full duplex" problem (not working)
« Reply #2 on: August 05, 2007, 11:51:44 PM »
Hi Omar, thank you for your answer.
I think I'm using the latest version of the firmware (2.47 was the stack version, but the "application version" I'm using is 3.06)

Anyway I'm sure that my stack revision takes already care of "fragmentation" of big quantity of data, becase at the end
of the function "TCPsend" I can see the following code:

//Increment TxCount. If buffer is full, flush it
    if(++ps->TxCount >= TCPGetMaxDataLength() )
        TCPFlush(s);


So I think that my problem is due con "simultaneous" transmission of both endpoints on the TCP, plus "ack" management done by the two endpoints (maybe too much things to do at the same time....).

I read on the form something about the "TCP_NO_WAIT_FOR_ACK" define. I'll try to uncomment that an see what happens.

If you have any other question/suggestion for me they will be *really* appreciated a lot!

Best regards,

Maurizio




If data length is more than 970bytes, you must call StackTask() function while TCPIsPutReady returns not ok.

I had a lot of problems when i made tests to send long messages(> 970 bytes).
Please, read this long post:
http://forum.modtronix.com/index.php?topic=592.msg1693#msg1693

Now, you should know that a possible solution to your problem can be ....

Code: [Select]
// UART TO TCP DATA TRANSFER
if (TCPIsPutReady(TcpSocket) && serIsGetReady() )
   TCPPut(TcpSocket,DATA_MARKER);   // Packet Header (for future use)
   while(serIsGetReady()){
     while(!TCPIsPutReady(TcpSocket))
         StackTask();
     TCPPut(TcpSocket,serGetByte());
   }
   TCPFlush(TcpSocket);
}


Remember that you will receive NOT only one message, but msgLen = data_length/970; messages; so your client application must manage this.

In version 3.04 you do not need to implement this trick, because it allows you to send "unlimited" amount of bytes! So only one message will be send.



MaurizioB

  • Full Member
  • ***
  • Posts: 13
    • View Profile
Re: TCP "full duplex" problem (not working)
« Reply #3 on: August 06, 2007, 11:54:56 PM »
Yesterday I made some other test on my firmware and I'm quite sure that it is not a data length problem: I can send relatively "big" text files (about 10 kbyte) from one board to the other and everything works very fine.
The problem appears only if, while board "A" is sending the file to board "B" , i press some key on the board "B" terminal; after 4 or 5 key-press the ethernet stack hangs!

Here are some symptoms of the "hanged" stack:
- the two yellows led are always ON ( duryng the correct data transfer they blink regularry 4 or 5 times per second)
- if I disconnect one of the two modules from etherent the two leds goes off
- if I reconnect the module, after few seconds, the leds goes on again

Any suggestion will be appreciated a lot!

Maurizio






If data length is more than 970bytes, you must call StackTask() function while TCPIsPutReady returns not ok.

I had a lot of problems when i made tests to send long messages(> 970 bytes).
Please, read this long post:
http://forum.modtronix.com/index.php?topic=592.msg1693#msg1693

Now, you should know that a possible solution to your problem can be ....

Code: [Select]
// UART TO TCP DATA TRANSFER
if (TCPIsPutReady(TcpSocket) && serIsGetReady() )
   TCPPut(TcpSocket,DATA_MARKER);   // Packet Header (for future use)
   while(serIsGetReady()){
     while(!TCPIsPutReady(TcpSocket))
         StackTask();
     TCPPut(TcpSocket,serGetByte());
   }
   TCPFlush(TcpSocket);
}


Remember that you will receive NOT only one message, but msgLen = data_length/970; messages; so your client application must manage this.

In version 3.04 you do not need to implement this trick, because it allows you to send "unlimited" amount of bytes! So only one message will be send.



OmarZ

  • Hero Member
  • *****
  • Posts: 243
    • View Profile
Re: TCP "full duplex" problem (not working)
« Reply #4 on: August 07, 2007, 11:14:35 AM »
I think you must involve also modtronix team... Maybe you need some "mutex" to avoid collisions.

MaurizioB

  • Full Member
  • ***
  • Posts: 13
    • View Profile
Re: TCP "full duplex" problem (not working)
« Reply #5 on: August 07, 2007, 11:30:30 AM »
Yes, I agree with you, I need some help from the team.
Could you tell me how to get it ? Do they read this forum or do I need to concact them directly ?

Thank you very much for you help, I'll get  you updated if there will be some god news

Maurizio

I think you must involve also modtronix team... Maybe you need some "mutex" to avoid collisions.

OmarZ

  • Hero Member
  • *****
  • Posts: 243
    • View Profile
Re: TCP "full duplex" problem (not working)
« Reply #6 on: August 07, 2007, 01:13:46 PM »
They always read forum messages; i think they are a bit busy because they just came back from Australian winter holidays.
I think that usually they are very active ad they make a really good support if the problem is not related to a specific project. In this case it can be a ethernet stack bug, so it's common for all the customers.

Note: Post also a personal message to modtro2 (forum administrator).


OmarZ

  • Hero Member
  • *****
  • Posts: 243
    • View Profile
Re: TCP "full duplex" problem (not working)
« Reply #7 on: August 07, 2007, 02:47:41 PM »

MaurizioB

  • Full Member
  • ***
  • Posts: 13
    • View Profile
Re: TCP "full duplex" problem (not working)
« Reply #8 on: August 07, 2007, 11:25:45 PM »
Hi Omar, Thank you for the link.

I didn't see it, but anyway my MAC addresses are different and I'm quite sure I'm using a switch (I'll try asap to make the "light" test).

Since my holidays are near too, I'll try to contact the modtronix team when I'll back.

Thank you again for you helpful asisstance, I'll hope we can exhange knowledge again in the future


Maurizio


did you check this?
http://forum.modtronix.com/index.php?topic=145.msg375#msg375

modtro2

  • Administrator
  • Hero Member
  • *****
  • Posts: 564
    • View Profile
Re: TCP "full duplex" problem (not working)
« Reply #9 on: August 08, 2007, 05:02:07 PM »
Hello Maurizio

Sorry for late reply, still catching up with 100s of Emails received during 10 days we were closed.

Your code can become quite complicated if you are sending large files. By default, the TCP buffer is only 970 bytes long. If you are sending files longer than this, you have to call the TCPIsPutReady() function each time before calling the TCPPut() function. You can only call the TCPPut() function if the TCPIsPutReady() function returns true. If not, you have to call the StackTask() function and try again, until TCPIsPutReady() returns true. Best is to use a state machine, like the one used in the sendFileToTcpServer() function in the tcputils.c file included with the source code. Have a look at this function, and see how the TCPPut() function only gets called if TCPIsPutReady() returns true. You are calling the TCPPut() in a while loop without calling the TCPIsPutReady() function! This will cause trouble when writing more than 970 bytes to TCP buffer.

Additionally you should place a StackTask() function after each segment of your code that could schedule tasks to be performed in your code. Place this function after your "TCP TO UART" and " UART TO TCP" segments of code.

OmarZ

  • Hero Member
  • *****
  • Posts: 243
    • View Profile
Re: TCP "full duplex" problem (not working)
« Reply #10 on: August 08, 2007, 10:54:37 PM »
Hi modtronix.
I already suggest him that
http://forum.modtronix.com/index.php?topic=796.msg2319#msg2319
and he told me that this is not the problem...

MaurizioB

  • Full Member
  • ***
  • Posts: 13
    • View Profile
Re: TCP "full duplex" problem (not working)
« Reply #11 on: August 10, 2007, 03:17:00 AM »
Hi,
thank you for the answer; maybe there was a misunderstanding with Omarz when he told me to check the message lenght. I understoot that it was a problem of an old stack version but now I know that I've to take care of the message lenght anyway.

I'm leaving for summer holidays now   8-), but I'll try to put in pratice your asuggestion as soon as I'll back.
I'll give you my feedback.

Best Regards

Maurizio



 
Hello Maurizio

Sorry for late reply, still catching up with 100s of Emails received during 10 days we were closed.

Your code can become quite complicated if you are sending large files. By default, the TCP buffer is only 970 bytes long. If you are sending files longer than this, you have to call the TCPIsPutReady() function each time before calling the TCPPut() function. You can only call the TCPPut() function if the TCPIsPutReady() function returns true. If not, you have to call the StackTask() function and try again, until TCPIsPutReady() returns true. Best is to use a state machine, like the one used in the sendFileToTcpServer() function in the tcputils.c file included with the source code. Have a look at this function, and see how the TCPPut() function only gets called if TCPIsPutReady() returns true. You are calling the TCPPut() in a while loop without calling the TCPIsPutReady() function! This will cause trouble when writing more than 970 bytes to TCP buffer.

Additionally you should place a StackTask() function after each segment of your code that could schedule tasks to be performed in your code. Place this function after your "TCP TO UART" and " UART TO TCP" segments of code.

OmarZ

  • Hero Member
  • *****
  • Posts: 243
    • View Profile
Re: TCP "full duplex" problem (not working)
« Reply #12 on: August 11, 2007, 05:49:17 AM »
The "problem" affect versions 3.05 and 3.06.
Version 3.04 works without any trick.

you must change in this way:

Code: [Select]
// UART TO TCP DATA TRANSFER
if (TCPIsPutReady(TcpSocket) && serIsGetReady() )
   TCPPut(TcpSocket,DATA_MARKER);   // Packet Header (for future use)
   while(serIsGetReady()){
     while(!TCPIsPutReady(TcpSocket))
         StackTask();
     TCPPut(TcpSocket,serGetByte());
   }
   TCPFlush(TcpSocket);
}

change also
// TCP TO UART DATA TRANSFER
code!

MaurizioB

  • Full Member
  • ***
  • Posts: 13
    • View Profile
Re: TCP "full duplex" problem (not working)
« Reply #13 on: September 10, 2007, 11:26:31 PM »
Hello,
I came back from my summer holidays and  I put pratically you suggestion but nothing changes in the module behaviour: the tcp stack hangs as soon as I press 5 or 6 keys on the terminal while it is receiving data from the other terminal.

Anyway I discovered one interesting thing that, I hope, can help you to find the problem

If I replace my network switch with a hub (in order to try to log the network traffic witch etherreal software) the problem disappears at all and everything works well!!!

Please notice that I'm using a very simple newtwork configuration,just the two modtronix modules and one PC, so I can allow myself to use one hun intstead of a switch.

Does this mean something for you ?

Maurizio



Hello Maurizio

Sorry for late reply, still catching up with 100s of Emails received during 10 days we were closed.

Your code can become quite complicated if you are sending large files. By default, the TCP buffer is only 970 bytes long. If you are sending files longer than this, you have to call the TCPIsPutReady() function each time before calling the TCPPut() function. You can only call the TCPPut() function if the TCPIsPutReady() function returns true. If not, you have to call the StackTask() function and try again, until TCPIsPutReady() returns true. Best is to use a state machine, like the one used in the sendFileToTcpServer() function in the tcputils.c file included with the source code. Have a look at this function, and see how the TCPPut() function only gets called if TCPIsPutReady() returns true. You are calling the TCPPut() in a while loop without calling the TCPIsPutReady() function! This will cause trouble when writing more than 970 bytes to TCP buffer.

Additionally you should place a StackTask() function after each segment of your code that could schedule tasks to be performed in your code. Place this function after your "TCP TO UART" and " UART TO TCP" segments of code.