RF22

- Main Page
- Classes
- Files
- Examples

- File List

RF22ReliableDatagram.h
1 // RF22ReliableDatagram.h
2 //
3 // Author: Mike McCauley (mikem@airspayce.com)
4 // Copyright (C) 2011 Mike McCauley
5 // $Id: RF22ReliableDatagram.h,v 1.8 2014/04/01 05:06:44 mikem Exp mikem $
6
7 #ifndef RF22ReliableDatagram_h
8 #define RF22ReliableDatagram_h
9
10 #include <RF22Datagram.h>
11
12 // The acknowledgement bit in the FLAGS
13 #define RF22_FLAGS_ACK 0x80
14
15 /////////////////////////////////////////////////////////////////////
16 /// \class RF22ReliableDatagram RF22ReliableDatagram.h <RF22ReliableDatagram.h>
17 /// \brief RF22 subclass for sending addressed, acknowledged, retransmitted datagrams.
18 ///
19 /// Extends RF22Datagram to define addressed, reliable datagrams with acknowledgement and retransmission.
20 /// Based on RF22Datagram, adds flags and sequence numbers. RF22ReliableDatagram is reliable in the sense
21 /// that messages are acknowledged, and unacknowledged messages are retransmitted until acknowledged or the
22 /// retries are exhausted.
23 /// When addressed messages are sent (by sendtoWait()), it will wait for an ack, and retransmit
24 /// after timeout until an ack is received or retries are exhausted.
25 /// When addressed messages are collected by the application (by recvfromAck()),
26 /// an acknowledgement is automatically sent.
27 ///
28 /// The retransmit timeout is randomly varied between timeout and timeout*2 to prevent collisions on all
29 /// retries when 2 nodes happen to start sending at the same time .
30 ///
31 /// Each new message sent by sendtoWait() has its ID incremented.
32 ///
33 /// An ack consists of a message with:
34 /// - TO set to the from address of the original message
35 /// - FROM set to this node address
36 /// - ID set to the ID of the original message
37 /// - FLAGS with the RF22_FLAGS_ACK bit set
38 ///
39 /// Part of the Arduino RF22 library for operating with HopeRF RF22 compatible transceivers
40 /// (see http://www.hoperf.com)
41 class RF22ReliableDatagram : public RF22Datagram
42 {
43 public:
44 /// Constructor.
45 /// \param[in] thisAddress The address to assign to this node. Defaults to 0
46 /// \param[in] slaveSelectPin the Arduino pin number of the output to use to select the RF22 before
47 /// accessing it. Defaults to the normal SS pin for your Arduino (D10 for Diecimila, Uno etc, D53 for Mega)
48 /// \param[in] interrupt The interrupt number to use. Default is interrupt 0 (Arduino input pin 2)
49 RF22ReliableDatagram(uint8_t thisAddress = 0, uint8_t slaveSelectPin = SS, uint8_t interrupt = 0);
50
51 /// Sets the minimum retransmit timeout. If sendtoWait is waiting for an ack
52 /// longer than this time (in milliseconds),
53 /// it will retransmit the message. Defaults to 200ms. The timeout is measured from the end of
54 /// transmission of the message. It must be at least longer than the the transmit
55 /// time of the acknowledgement (preamble+6 octets) plus the latency/poll time of the receiver.
56 /// For fast modulation schemes you can considerably shorten this time.
57 /// The actual timeout is randomly varied between timeout and timeout*2.
58 /// \param[in] timeout The new timeout period in milliseconds
59 void setTimeout(uint16_t timeout);
60
61 /// Sets the max number of retries. Defaults to 3. If set to 0, the message will only be sent once.
62 /// sendtoWait will give up and return false if there is no ack received after all transmissions time out.
63 /// param[in] retries The maximum number a retries.
64 void setRetries(uint8_t retries);
65
66 /// Send the message and waits for an ack. Returns true if an acknowledgement is received.
67 /// Synchronous: any message other than the desired ACK received while waiting is discarded.
68 /// Blocks until an ACK is received or all retries are exhausted (ie up to retries*timeout milliseconds).
69 /// \param[in] address The address to send the message to.
70 /// \param[in] buf Pointer to the binary message to send
71 /// \param[in] len Number of octets to send
72 /// \return true if the message was transmitted and an acknowledgement was received.
73 boolean sendtoWait(uint8_t* buf, uint8_t len, uint8_t address);
74
75 /// If there is a valid message available for this node, send an acknowledgement to the SRC
76 /// address (blocking until this is complete), then copy the message to buf and return true
77 /// else return false.
78 /// If a message is copied, *len is set to the length..
79 /// If from is not NULL, the SRC address is placed in *from.
80 /// If to is not NULL, the DEST address is placed in *to.
81 /// This is the preferred function for getting messages addressed to this node.
82 /// If the message is not a broadcast, acknowledge to the sender before returning.
83 /// You should be sure to call this function frequently enough to not miss any messages
84 /// It is recommended that you call it in your main loop.
85 /// \param[in] buf Location to copy the received message
86 /// \param[in,out] len Available space in buf. Set to the actual number of octets copied.
87 /// \param[in] from If present and not NULL, the referenced uint8_t will be set to the SRC address
88 /// \param[in] to If present and not NULL, the referenced uint8_t will be set to the DEST address
89 /// \param[in] id If present and not NULL, the referenced uint8_t will be set to the ID
90 /// \param[in] flags If present and not NULL, the referenced uint8_t will be set to the FLAGS
91 /// (not just those addressed to this node).
92 /// \return true if a valid message was copied to buf
93 boolean recvfromAck(uint8_t* buf, uint8_t* len, uint8_t* from = NULL, uint8_t* to = NULL, uint8_t* id = NULL, uint8_t* flags = NULL);
94
95 /// Similar to recvfromAck(), this will block until either a valid message available for this node
96 /// or the timeout expires. Starts the receiver automatically.
97 /// You should be sure to call this function frequently enough to not miss any messages
98 /// It is recommended that you call it in your main loop.
99 /// \param[in] buf Location to copy the received message
100 /// \param[in,out] len Available space in buf. Set to the actual number of octets copied.
101 /// \param[in] timeout Maximum time to wait in milliseconds
102 /// \param[in] from If present and not NULL, the referenced uint8_t will be set to the SRC address
103 /// \param[in] to If present and not NULL, the referenced uint8_t will be set to the DEST address
104 /// \param[in] id If present and not NULL, the referenced uint8_t will be set to the ID
105 /// \param[in] flags If present and not NULL, the referenced uint8_t will be set to the FLAGS
106 /// (not just those addressed to this node).
107 /// \return true if a valid message was copied to buf
108 boolean recvfromAckTimeout(uint8_t* buf, uint8_t* len, uint16_t timeout, uint8_t* from = NULL, uint8_t* to = NULL, uint8_t* id = NULL, uint8_t* flags = NULL);
109
110 /// Returns the number of retransmissions
111 /// we have had to send
112 /// \return The number of retransmissions since initialisation.
113 uint16_t retransmissions();
114
115 protected:
116 /// Send an ACK for the message id to the given from address
117 /// Blocks until the ACK has been sent
118 void acknowledge(uint8_t id, uint8_t from);
119
120 /// Checks whether the message currently in the Rx buffer is a new message, not previously received
121 /// based on the from address and the sequence. If it is new, it is acknowledged and returns true
122 /// \return true if there is a message received and it is a new message
123 boolean haveNewMessage();
124
125 private:
126 /// Count of retransmissions we have had to send
127 uint16_t _retransmissions;
128
129 /// The last sequence number to be used
130 /// Defaults to 0
131 uint8_t _lastSequenceNumber;
132
133 // Retransmit timeout (milliseconds)
134 /// Defaults to 200
135 uint16_t _timeout;
136
137 // Retries (0 means one try only)
138 /// Defaults to 3
139 uint8_t _retries;
140
141 /// Array of the last seen sequence number indexed by node address that sent it
142 /// It is used for duplicate detection. Duplicated messages are re-acknowledged when received
143 /// (this is generally due to lost ACKs, causing the sender to retransmit, even though we have already
144 /// received that message)
145 uint8_t _seenIds[256];
146
147
148 };
149
150 #endif
151
RF22ReliableDatagram::acknowledge
void acknowledge(uint8_t id, uint8_t from)
Definition: RF22ReliableDatagram.cpp:150
RF22ReliableDatagram::sendtoWait
boolean sendtoWait(uint8_t *buf, uint8_t len, uint8_t address)
Definition: RF22ReliableDatagram.cpp:42
RF22ReliableDatagram::RF22ReliableDatagram
RF22ReliableDatagram(uint8_t thisAddress=0, uint8_t slaveSelectPin=SS, uint8_t interrupt=0)
Definition: RF22ReliableDatagram.cpp:19
RF22ReliableDatagram::retransmissions
uint16_t retransmissions()
Definition: RF22ReliableDatagram.cpp:145
RF22ReliableDatagram::recvfromAck
boolean recvfromAck(uint8_t *buf, uint8_t *len, uint8_t *from=NULL, uint8_t *to=NULL, uint8_t *id=NULL, uint8_t *flags=NULL)
Definition: RF22ReliableDatagram.cpp:100
RF22ReliableDatagram::haveNewMessage
boolean haveNewMessage()
RF22ReliableDatagram::setRetries
void setRetries(uint8_t retries)
Definition: RF22ReliableDatagram.cpp:36
RF22ReliableDatagram::setTimeout
void setTimeout(uint16_t timeout)
Definition: RF22ReliableDatagram.cpp:30
RF22Datagram
RF22 subclass for addressed, unreliable messages.
Definition: RF22Datagram.h:22
RF22ReliableDatagram::recvfromAckTimeout
boolean recvfromAckTimeout(uint8_t *buf, uint8_t *len, uint16_t timeout, uint8_t *from=NULL, uint8_t *to=NULL, uint8_t *id=NULL, uint8_t *flags=NULL)
Definition: RF22ReliableDatagram.cpp:136
RF22ReliableDatagram
RF22 subclass for sending addressed, acknowledged, retransmitted datagrams.
Definition: RF22ReliableDatagram.h:41