Packet Acknowledgements in TinyOS - wireless

Iam using telosB motes for implementation.
I have come across one of the way for acknowledging the packets,
task void send() {
call PacketAcknowledgements.requestAck(&myMsg);
if(call AMSend.send(1, &myMsg, 0) != SUCCESS) {
post send();
}
}
event void AMSend.sendDone(message_t *msg, error_t error) {
if(call PacketAcknowledgements.wasAcked(msg))
// do something if packet was acked
else
// do something else if packet was not acked (possibly resend)
}
Actually my doubt is, the receiving mote should have to acknowledge the packet or it should have PacketAcknowledgements interface in its application in order to send ACKs.
How this type of acknowledgement works?
And I have checked with my own type of acknowledgement, it works like after receiving the packet the mote acknowledge the packets, if source mote does not receive positive ack in certain time frame then re transmit the packet .
So which is better way of doing?
Please guide & thanks,

In TinyOS acknowledgements are implemented on the lowest communication abstraction level - active message[1]. This means that any component that operates with active messages has a built in support for synchronous acknowledgements.
Actually my doubt is, the receiving mote should have to acknowledge
the packet or it should have PacketAcknowledgements interface in its
application in order to send ACKs.
If you used PacketAcknowledgements.requestAck(&myMsg) to request acknowledgement, then you don't have to write extra code in Receive.receive event handler to process acks as this is done for you by underlying communication layer. All you need to do is wire PacketAcknowledgements interface that your component/module uses to one of the providers (AMSenderC or ActiveMessageC).
How this type of acknowledgement works?
The high level idea is following - calling PacketAcknowledgements.requestAck(&myMsg) sets a flag in a packet header and tells sender component not to signal sendDone event until ack was received (or timed out). When receiver component handles the packet on the other end it reads the flag and sends and ack if requested.
Having said all that, description of your way of acknowledging packets seems very similar to what PacketAcknowledgements offers, so personally I would avoid writing extra code for handling acknowledgements myself and stick with the tools provided.

Related

Manually ACK batch AMQP messages

I'm able to receive batch messages with the codes below. But now my question is, how should I manually ACK the messages. ACK all the messages in the list one by one, or ACK the last message in the list is enough? Thanks in advance!
public class MyMessageListener implements ChannelAwareBatchMessageListener {
#Override
public void onMessageBatch(List<Message> messages, Channel channel){
//Do something......
//option 1
messages.forEach(msg-> channel.basicAck(msg.getMessageProperties().getDeliveryTag(), true);
//option 2
channel.basicAck( messages.get(messages.size()-1).getMessageProperties().getDeliveryTag(), true);
}
}
This depends on your business case , generally speaking acknowledging all the messages will increase the network traffic and consequently your message throughput will go down .
The second option is a pragmatic approach provided it is OK to have the possibility of loosing some intermediate messages which may not have been delivered and a later message is delivered and acknowledged in which case the un-delivered messages will also get ackéd .
So it is a design decision which is driven by the sensitivity of payload of your messages.

omnet retransmitting the data packet at routing protocol

I am working on a wireless routing protocol. I have created a Queue at every node. In this queue, every node kept packet which it already transmitted. If packet is not transmitted by nexthop then previous node will retransmit the packet after timeout. The problem is that when node is trying to retransmitt the packet by calling postRotingHook in handle function to retransmit then it is not doing anything. This postRoutingHook is created locally so it is not actually sending the packet. So how to connect this packet with network for retransmission?
Example: Suppose We have 3 nodes A, B and C. A is source, B is intermediate and C is destination. Node A sent a packet initially. Now node B will forward it to node C. At this time node A will overhear this packet and it will cancel the timer and delete this packet from its Queue. (in normal condition)
Suppose node B could not forward the packet because of some reason then node A should re-transmit the packet after time out. I am unable to achieve this functionality.
My programming scenario is:
I have modified GPSR protocol. Where header file have definition of these 5 INetfilterHooks methods. I didn't use any control packet e.g. request, response, beacon etc. I am directly dealing with data packet which contains some control information. I have implemented my logic in datagramPreRoutingHook() method (when data is received from lower layer) and datagramLocalOutHook() method (when data is received from upper layer).
Source node (at network layer) receives packet from upper layer at IPv4.cc using handlePacketFromHL() ->datagramLocalOutHook(datagram, destIE, nextHopAddr) == INetfilter::IHook::ACCEPT) when it calls datagramLocalOutHook(datagram, destIE, nextHopAddr) then control goes to my routing protocol. It makes necessary changes, Adds source, destination address, creates options and keeps the packet in Queue (for retransmission by scheduling timer) then return ACCEP. Then control again goes to IPv4.cc.
After this process, if time out occurs at my protocol then I am unable to send packet to IPv4.cc. I called postRoutingHook to retransmit the packet then it simly return ACCEPT (as defined in header file) and does nothing. I have tried to call some methods of IPv4.cc by making object of IPv4 in my protocol but these methods are protected so I couldn't access these methods.
I tried with making some public methods of IPv4.cc but it is giving error at further stage.
I have tried to make the object of INetfilter::IHook for calling its postRoutingHook() but is also providing error as object of abstract class can not be created.

Sent acks are received by multiple nodes in Veins-4a2 using prepareWSM method

I use OMNeT++-4.6, sumo-0.22.0 and Veins-4a2.
In my scenario, when an RSU receives a message from a node, it sends an ACK using the prepareWSM method:
sendWSM(prepareWSM("ack", ackLengthBits, type_SCH, ackPriority, senderId , 2))
So, the RSU sends an ACK to senderID which is the sender node of the message.
In my log file, I notice that there are some nodes - not only the original sender node - which receive this ACK.
I need to know if prepareWSM method diffuse the ACK to all nodes encountered or if what I did to send only the ACK to the sender node is correct?
Although you can set the receiver address for the WaveShortMessage, it is ignored in the Mac1609_4.cc (line 178 ff.), since originally only broadcast transmission is used in C2X-communication:
//send the packet
Mac80211Pkt* mac = new Mac80211Pkt(pktToSend->getName(), pktToSend->getKind());
mac->setDestAddr(LAddress::L2BROADCAST);
To achieve your wished acknowledgement system you have to check the recipient address of each message you receive in the APP layer and ignore messages which are not addressed to your address (myId).

sendReliable message sometimes not received by opposite peer

I've created a real time game for Google Play Game Services. It's in the later alpha stages right now. I have a question about sendReliableMessage. I've noticed certain cases where the other peer doesn't receive the message. I am aware that there is a callback onRealTimeMessageSent and I have some code in my MainActivity:
#Override
public void onRealTimeMessageSent(int i, int i2, String s) {
if(i== GamesStatusCodes.STATUS_OK)
{
}
else
{
lastMessageStatus=i;
sendToast("lastMessageStatus:"+Integer.toString(lastMessageStatus));
}
}
My games render loop is checking every iteration the value of lastMessageStatus and if there was something other than STATUS_OK I'm painting a T-Rex right now.
My question is is checking the sent status really enough? I also could create source code where the sender has to wait for an Acknowledged message. Each message would be stamped with a UUID and if ack is not received within a timeout then the sender would send the message again? Is an ACK based system necessary to create a persistent connection?
I've noticed certain cases where there is some lag before the opposite peer received the reliable message and I was wondering is there a timeout on the sendReliable message? Google Play Services documentation doesn't seem to indicate in the documentation that there is a timeout at all.
Thank you
Reliable messages are just that, reliable. There are not a lot of use cases for the onRealTimeMessageSent callback for reliable messages because, as you said, it does not guarantee that the recipient has processed the message yet. Only that it was sent.
It may seem annoying, but an ACK-based system is the best way to know for sure that your user has received the message. A UUID is one good way to do this. I have done this myself and found it to work great (although now you have round-trip latency).
As far as timeout, that is not implemented in the RealTime Messaging API. I have personally found round trip latency (send message, receive ACK in callback) to be about 200ms, and I have never found a way to make a message fail to deliver eventually even when purposefully using bad network conditions.

Block TCP-send till ACK returned

I am programming a client application sending TCP/IP packets to a server. Because of timeout issues I want to start a timer as soon as the ACK-Package is returned (so there can be no timeout while the package has not reached the server). I want to use the winapi.
Setting the Socket to blocking mode doesn't help, because the send command returns as soon as the data is written into the buffer (if I am not mistaken). Is there a way to block send till the ACK was returned, or is there any other way to do this without writing my own TCP-implementation?
Regards
It sounds like you want to do the minimum implementation to achieve your goal. In this case you should set your socket to blocking, and following the send which blocks until all data is sent, you call recv which in turn will block until the ACK packet is received or the server end closes or aborts the connection.
If you wanted to go further with your implementation you'd have to structure your client application in such a way that supports asynchronous communication. There are a few techniques with varying degrees of complexity; polling using select() simple, event model using WSASelectEvent/WSAWaitForMultipleEvents challenging, and the IOCompletionPort model which is very complicated.
peudocode... Will wait until ack is recevied, after which time you can call whatever functionallity you want -i chose some made up function send_data.. which would then send information over the socket after receiving the ack.
data = ''
while True
readable, writable, errors = select([socket])
if socket in readble
data += recv(socket)
if is_ack(data)
timer.start() #not sure why you want this
break
send_data(socket)

Resources