1
#ifndef VRPN_REDUNDANT_TRANSMISSION_H
2
#define VRPN_REDUNDANT_TRANSMISSION_H
4
/// @class vrpn_RedundantTransmission
5
/// Helper class for vrpn_Connection that automates redundant transmission
6
/// for unreliable (low-latency) messages. Call pack_messages() here instead
7
/// of on your connection, and call mainloop() here before calling mainloop()
8
/// on your connection.
10
#include "vrpn_Shared.h" // for timeval, types
11
#include "vrpn_BaseClass.h"
12
#include "vrpn_Connection.h" // for vrpn_HANDLERPARAM, vrpn_Connection
14
class VRPN_API vrpn_RedundantTransmission {
18
vrpn_RedundantTransmission (vrpn_Connection * c);
19
~vrpn_RedundantTransmission (void);
25
vrpn_uint32 defaultRetransmissions (void) const;
26
timeval defaultInterval (void) const;
27
vrpn_bool isEnabled (void) const;
33
virtual void mainloop (void);
34
///< Determines which messages need to be resent and queues
35
///< them up on the connection for transmission.
37
void enable (vrpn_bool);
39
virtual void setDefaults (vrpn_uint32 numRetransmissions,
40
timeval transmissionInterval);
41
///< Set default values for future calls to pack_message().
43
virtual int pack_message
44
(vrpn_uint32 len, timeval time, vrpn_uint32 type,
45
vrpn_uint32 sender, const char * buffer,
46
vrpn_uint32 class_of_service,
47
vrpn_int32 numRetransmissions = -1,
48
timeval * transmissionInterval = NULL);
49
///< If !isEnabled(), does a normal pack_message(), but if isEnabled()
50
///< ignores class_of_service and sends it vrpn_CONNECTION_LOW_LATENCY,
51
///< sending it an additional number of times equal to numRetransmissions
52
///< at minimum intervals of transmissionInterval.
53
///< Specify -1 and NULL to use default values.
57
vrpn_Connection * d_connection;
59
struct queuedMessage {
61
vrpn_uint32 remainingTransmissions;
62
timeval transmissionInterval;
63
timeval nextValidTime;
67
queuedMessage * d_messageList;
68
vrpn_uint32 d_numMessagesQueued;
69
///< For debugging, mostly.
73
vrpn_uint32 d_numTransmissions;
74
timeval d_transmissionInterval;
76
vrpn_bool d_isEnabled;
82
struct vrpn_RedundantController_Protocol {
84
char * encode_set (int * len, vrpn_uint32 num, timeval interval);
85
void decode_set (const char ** buf, vrpn_uint32 * num, timeval * interval);
87
char * encode_enable (int * len, vrpn_bool);
88
void decode_enable (const char ** buf, vrpn_bool *);
90
void register_types (vrpn_Connection *);
92
vrpn_int32 d_set_type;
93
vrpn_int32 d_enable_type;
97
/// @class vrpn_RedundantController
98
/// Accepts commands over a connection to control a local
99
/// vrpn_RedundantTransmission's default parameters.
101
class VRPN_API vrpn_RedundantController : public vrpn_BaseClass {
105
vrpn_RedundantController (vrpn_RedundantTransmission *, vrpn_Connection *);
106
~vrpn_RedundantController (void);
108
void mainloop (void);
109
// Do nothing; vrpn_BaseClass requires this.
113
virtual int register_types (void);
115
vrpn_RedundantController_Protocol d_protocol;
117
static int VRPN_CALLBACK handle_set (void *, vrpn_HANDLERPARAM);
118
static int VRPN_CALLBACK handle_enable (void *, vrpn_HANDLERPARAM);
120
vrpn_RedundantTransmission * d_object;
125
/// @class vrpn_RedundantRemote
126
/// Sends messages to a vrpn_RedundantController so that a
127
/// vrpn_RedundantTransmission on a server can be controlled from a client.
129
class VRPN_API vrpn_RedundantRemote : public vrpn_BaseClass {
133
vrpn_RedundantRemote (vrpn_Connection *);
134
~vrpn_RedundantRemote (void);
136
void mainloop (void);
137
// Do nothing; vrpn_BaseClass requires this.
139
void set (int numRetransmissions, timeval transmissionInterval);
140
void enable (vrpn_bool);
145
int register_types (void);
147
vrpn_RedundantController_Protocol d_protocol;
153
/// @class vrpn_RedundantReceiver
154
/// Helper class that eliminates duplicates; only the first instance of
155
/// a message is delivered. Registers a callback on connection for any
156
/// type it's told to monitor; when it gets a message back, checks its
157
/// list of recently-seen-timestamps for that type; if it isn't on the
158
/// list, it's dispatched and replaces the oldest item on the list.
159
/// List length is limited, so
160
/// if too many messages of the same type (more than VRPN_RR_LENGTH) are
161
/// interleaved - if transmissionInterval * numRetransmissions >
162
/// VRPN_RR_LENGTH * the normal rate of message generation - it will not
163
/// detect the redundant messages.
165
// A TypeDispatcher insists on too much control of its table for
166
// us to use one here - we want to use the same indices as the
167
// vrpn_Connection we're attached to, but if we had our own TypeDispatcher
168
// we'd have an independent, inconsistent set of type & sender ids.
170
#define VRPN_RR_LENGTH 8
172
class VRPN_API vrpn_RedundantReceiver {
176
vrpn_RedundantReceiver (vrpn_Connection *);
177
~vrpn_RedundantReceiver (void);
179
virtual int register_handler (vrpn_int32 type,
180
vrpn_MESSAGEHANDLER handler, void * userdata,
181
vrpn_int32 sender = vrpn_ANY_SENDER);
182
virtual int unregister_handler (vrpn_int32 type,
183
vrpn_MESSAGEHANDLER handler, void * userdata,
184
vrpn_int32 sender = vrpn_ANY_SENDER);
186
void record (vrpn_bool);
187
///< Turns "memory" (tracking statistics of redundant reception)
190
void writeMemory (const char * filename);
191
///< Writes statistics to the named file: timestamp of every message
192
///< received and number of copies of that message. Detects partial
193
///< losses, but not when all copies are lost, since vrpn_RR doesn't
194
///< expect messages.
196
void clearMemory (void);
197
///< Throws away / resets statistics.
201
vrpn_Connection * d_connection;
203
struct VRPN_API RRRecord {
206
timeval timestampSeen [VRPN_RR_LENGTH];
207
int numSeen [VRPN_RR_LENGTH];
208
int nextTimestampToReplace;
210
vrpnMsgCallbackEntry * cb;
211
vrpn_bool handlerIsRegistered;
214
RRRecord d_records [vrpn_CONNECTION_MAX_TYPES];
224
RRMemory * d_lastMemory;
227
static int VRPN_CALLBACK handle_possiblyRedundantMessage (void *, vrpn_HANDLERPARAM);
231
#endif // VRPN_REDUNDANT_TRANSMISSION_H