Hi, I’m using OAT 3.02, GCC, ADL with the ED TCP/IP stack.
According to the documentation and to my observation, apparently the ED TCP/IP stack has no mechanism to tell if the ACK of an already sent message has been received, altought the mechanism for the timeout/retry expiration does exists because the library returns the code -33 (ED_ERR_DISTANT_NO_RESP) when this occurrs telling the upper layer that an ACK of the package being sent never arrived.
How can I know when a sent TCP package has been ACKed so I can be sure that the package arrived ?
Hello,
Have you tried the TCPIP debug tool (described in chapter 9 of “Open AT 3.02 tools manual”)?
This function together with Ethereal should be able to show you the ACK messages.
The TCPIP debug function has been provided from version 2.11 of Open AT SDK.
/Snoooze
Yes I have and my TCP connections work fine. But I think I wrongly selected the Topic. I really don’t need to track every single ACK of every single packet I send, I know that the stack manages that so I don’t have to deal with the TCP implementation.
What I need is to know when a packet has been succesfuly received by the remote peer (the SYN-ACK interchange has completed correctly). The stack’s API provides a mechanism to inform when the SYN-ACK interchange fails (ED_ERR_DISTANT_NO_RESP), and that’s OK but I don’t know how to track succesful transmissions.
jc
I’ve been working with my Wavecom contact and this is his reply:
[color=blue]The TCP application has been designed to mask the details of lower level TCP functions. As such, it will not notify the application of each ACK from every TCP packet. The lower level TCP protocol will handle re-transmissions automatically and provide a higher level message on the success of the transmission. I assume you are using the ed_SocketTCPStart function. One of the parameters to that function is a callback function that is supposed to handle assorted messages dealing with whether the transmission was successful or not. The error conditions you’ve already experienced judging from your email below. If the transmission is successful, the callback function will only receive ED_INFO_WAITING_FOR_DATA letting your application know it is OK to send more data. It is implied that all packets sent received the proper ACK and the app will not send notification of every ACK of every packet.
I underlined some key aspects. These are my observations of what I have found:
ED_INFO_WAITING_FOR_DATA is received only after succesfuly openning the socket but not after succesfuly sending data. So it can not be used to track succesful transmissions. In fact there is no response code on the call back function that indicates succesful transmission.
I think the problem relies on the fact that the stack may handle simultaneous packet transmissions making the confirmation of every single message sent by the user a problem because to wich message the posible confirmation signal refers to ? so I think that’s why this mechanism doesn’t exists.
If what I say is true, I see only two possible aproachs to try assure packet transmission reability:
-
Send one packet (call to ed_SendDataExt function) and wait a fixed time for a possible fail on the timeot/retry ACK waiting mechanism. So If there is no fail, the packet was succesfuly transmited. This time is about 1 min. so this is no way to go because I need a lot more of throughput.
-
Send packets (call to ed_SendDataExt function) until the MaxLen parameter on the pfDataRequest callback function becomes less than what I need to send. Then I’ll
have to keep sending dummy packets (zero length) until MaxLen becomes large again, so when this happens I can ASSUME that some or all of the first packets I sent where succesfuly transmitted (it depends on how strict I am on losing packets. I may say a lot ). So I have to guess wich packets arrived and wich are still pending (this is bad).
If the connection fails, I also have to assume that all of the packets I sent where not succesfuly transmited increasing the probabilty of packet retransmissions (this is not too bad).
These are my two scenarios. One that leaves me with virtualy no trhoughput and One that leaves me an unreliable transmission that doesn’t exploit TCP confirmation advantages.
As I mentioned I think the problem lies on the stack accepting messages before dealing with previous ones. This has the advantage that the user doesn’t have to deal with transmission buffers, but has the disadvantages named above, in the contrary if it could take just one message at a time and not receive new ones until the previous one has been ACKed or lost, letting the user buffer it’s data, the confirmation signaling could be easily done and the user could be sure of what message arrived or failed.
I need some tips of you guys. I may be terrible wrong and confused with the stack’s API.
Note:
I have another issue when using scenario 2. I get RTK exceptions when I pass multiple messages to the stack. Considering my clear rejection to scenario 1 this leaves me with no scenarios. I will post this problem on another topic so things won’t get messy with this post.
Thanks, sorry for the long message.
puh… that was a long message …
Just a few comments…
The TCP protocol is designed to take care of the transmissions problems that could occur after the session has been set up. So basically the layer above TCP should trust that TCP is doing its job properly and getting the data over to the other entity with retransmission and other control mechanisms.
Another view of it is that TCP is far from optimized to work well with GPRS.
Or maybe I should say that GPRS is not optimized for transferring TCP traffic (TCP is older than GPRS).
Even though GPRS is packetswitched thoughout, it has many big differences compared to a wirebound IP network. And “normal” TCP stacks may perform poorly when used in a GPRS network.
This is not a problem (ok, maybe its aproblem for you ), its the way the most TCP stacks work. The TCP use a technique called “sliding window” to transmit several packets instead of ACK:ing each and every one in a sequencial order and then transmit the next packet. Without this technique, the available bandwidth would not be used in an effective way.
Now to my suggestion…
I think we have to accept that the TCP stack is working as it is (and as it should), even though you would like to know (from the underlaying layer) when your packet has been received at the remote entity.
I’m not sure if I understand your application correctly but I think I would implement some kind of application layer protocol that takes care of ACK:ing every packet of data that the application want to transmit to the remote entity.
/Snoooze