vrpn  07.33
Virtual Reality Peripheral Network
vrpn_Forwarder.C
Go to the documentation of this file.
1 #include <stddef.h> // for NULL
2 
3 #include "vrpn_Forwarder.h"
4 
6  vrpn_Connection *destination)
7  : d_source(source)
8  , d_destination(destination)
9  , d_list(NULL)
10 {
11 
12  if (d_source) {
13  d_source->addReference();
14  }
15  if (d_destination) {
16  d_destination->addReference();
17  }
18 }
19 
21 {
22 
23  vrpn_CONNECTIONFORWARDERRECORD *dlp;
24 
25  while (d_list) {
26  dlp = d_list->next;
27 
28  if (d_source)
29  d_source->unregister_handler(d_list->sourceId, handle_message, this,
30  d_list->sourceServiceId);
31 
32  delete d_list;
33  d_list = dlp;
34  }
35 
36  if (d_source) {
37  d_source->removeReference();
38  }
39  if (d_destination) {
40  d_destination->removeReference();
41  }
42 }
43 
44 int vrpn_ConnectionForwarder::forward(const char *sourceName,
45  const char *sourceServiceId,
46  const char *destinationName,
47  const char *destinationServiceId,
48  vrpn_uint32 classOfService)
49 {
50 
51  vrpn_CONNECTIONFORWARDERRECORD *newList =
52  new vrpn_CONNECTIONFORWARDERRECORD(
53  d_source, d_destination, sourceName, sourceServiceId,
54  destinationName, destinationServiceId, classOfService);
55 
56  if (!newList) return -1;
57 
58  newList->next = d_list;
59  d_list = newList;
60 
61  if (d_source)
62  d_source->register_handler(newList->sourceId, handle_message, this,
63  newList->sourceServiceId);
64 
65  return 0;
66 }
67 
68 int vrpn_ConnectionForwarder::unforward(const char *sourceName,
69  const char *sourceServiceId,
70  const char *destinationName,
71  const char *destinationServiceId,
72  vrpn_uint32 classOfService)
73 {
74 
75  vrpn_CONNECTIONFORWARDERRECORD **snitch;
76  vrpn_CONNECTIONFORWARDERRECORD *victim;
77 
78  vrpn_int32 st, ss, dt, ds;
79 
80  st = d_source->register_message_type(sourceName);
81  ss = d_source->register_sender(sourceServiceId);
82  dt = d_destination->register_message_type(destinationName);
83  ds = d_source->register_sender(destinationServiceId);
84 
85  for (snitch = &d_list, victim = *snitch; victim;
86  snitch = &(victim->next), victim = *snitch) {
87 
88  if ((victim->sourceId == st) && (victim->sourceServiceId == ss) &&
89  (victim->destinationId == dt) &&
90  (victim->destinationServiceId == ds) &&
91  (victim->classOfService == classOfService)) {
92  (*snitch)->next = victim->next;
93  delete victim;
94  victim = *snitch;
95  }
96  }
97 
98  return 0;
99 }
100 
101 // static
102 int vrpn_ConnectionForwarder::handle_message(void *userdata,
104 {
105 
107 
108  vrpn_int32 id = p.type;
109  vrpn_int32 serviceId = p.sender;
110  vrpn_uint32 serviceClass;
111 
112  int retval;
113 
114  // Convert from source's representation for type & sender ID to
115  // that of destination; look up service class to use (defaulted to
116  // vrpn_CONNECTION_RELIABLE).
117 
118  retval = me->map(&id, &serviceId, &serviceClass);
119  if (retval) return -1;
120 
121  if (me->d_destination) {
122  me->d_destination->pack_message(p.payload_len, p.msg_time, id,
123  serviceId, p.buffer, serviceClass);
124 
125  // HACK: should we have this here?
126  me->d_destination->mainloop();
127  }
128 
129  return 0;
130 }
131 
132 vrpn_int32 vrpn_ConnectionForwarder::map(vrpn_int32 *id, vrpn_int32 *serviceId,
133  vrpn_uint32 *classOfService)
134 {
135 
136  vrpn_CONNECTIONFORWARDERRECORD *dlp;
137 
138  for (dlp = d_list; dlp; dlp = dlp->next)
139  if ((*id == dlp->sourceId) && (*serviceId == dlp->sourceServiceId)) {
140  *id = dlp->destinationId;
141  *serviceId = dlp->destinationServiceId;
142  *classOfService = dlp->classOfService;
143  return 0;
144  }
145 
146  return -1;
147 }
148 
149 // Build a mapping from the source Connection's types to the destination
150 // Connection's. Store the class of service to be used on forwarding.
151 
152 vrpn_ConnectionForwarder::vrpn_CONNECTIONFORWARDERRECORD::
153  vrpn_CONNECTIONFORWARDERRECORD(vrpn_Connection *source,
154  vrpn_Connection *dest, const char *iSourceId,
155  const char *iSourceServiceId,
156  const char *iDestId,
157  const char *iDestServiceId, vrpn_uint32 cos)
158  : sourceId(source->register_message_type(iSourceId))
159  , sourceServiceId(source->register_sender(iSourceServiceId))
160  , destinationId(dest->register_message_type(iDestId))
161  , destinationServiceId(dest->register_sender(iDestServiceId))
162  , classOfService(cos)
163  , next(NULL)
164 {
165 }
166 
168  const char *sourceServiceName,
169  vrpn_Connection *destination,
170  const char *destinationServiceName)
171  : d_source(source)
172  , d_sourceService(source->register_sender(sourceServiceName))
173  , d_destination(destination)
174  , d_destinationService(destination->register_sender(destinationServiceName))
175  , d_list(NULL)
176 {
177 
178  if (d_source) {
179  d_source->addReference();
180  }
181  if (d_destination) {
182  d_destination->addReference();
183  }
184 }
185 
187 {
188 
189  vrpn_STREAMFORWARDERRECORD *dlp;
190 
191  while (d_list) {
192  dlp = d_list->next;
193 
194  if (d_source)
195  d_source->unregister_handler(d_list->sourceId, handle_message, this,
196  d_sourceService);
197 
198  delete d_list;
199  d_list = dlp;
200  }
201 
202  if (d_source) {
203  d_source->removeReference();
204  }
205  if (d_destination) {
206  d_destination->removeReference();
207  }
208 }
209 
210 int vrpn_StreamForwarder::forward(const char *sourceName,
211  const char *destinationName,
212  vrpn_uint32 classOfService)
213 {
214 
215  vrpn_STREAMFORWARDERRECORD *newList = new vrpn_STREAMFORWARDERRECORD(
216  d_source, d_destination, sourceName, destinationName, classOfService);
217 
218  if (!newList) return -1;
219 
220  newList->next = d_list;
221  d_list = newList;
222 
223  if (d_source)
224  d_source->register_handler(newList->sourceId, handle_message, this,
225  d_sourceService);
226 
227  return 0;
228 }
229 
230 int vrpn_StreamForwarder::unforward(const char *sourceName,
231  const char *destinationName,
232  vrpn_uint32 classOfService)
233 {
234 
235  vrpn_STREAMFORWARDERRECORD **snitch;
236  vrpn_STREAMFORWARDERRECORD *victim;
237 
238  vrpn_int32 st, dt;
239 
240  st = d_source->register_message_type(sourceName);
241  dt = d_destination->register_message_type(destinationName);
242 
243  for (snitch = &d_list, victim = *snitch; victim;
244  snitch = &(victim->next), victim = *snitch) {
245 
246  if ((victim->sourceId == st) && (victim->destinationId == dt) &&
247  (victim->classOfService == classOfService)) {
248  (*snitch)->next = victim->next;
249  delete victim;
250  victim = *snitch;
251  }
252  }
253 
254  return 0;
255 }
256 
257 // static
258 int vrpn_StreamForwarder::handle_message(void *userdata, vrpn_HANDLERPARAM p)
259 {
260 
261  vrpn_StreamForwarder *me = (vrpn_StreamForwarder *)userdata;
262 
263  vrpn_int32 id = p.type;
264  vrpn_uint32 serviceClass;
265 
266  int retval;
267 
268  // Convert from source's representation for type & sender ID to
269  // that of destination; look up service class to use (defaulted to
270  // vrpn_CONNECTION_RELIABLE).
271 
272  retval = me->map(&id, &serviceClass);
273  if (retval) return -1;
274 
275  if (me->d_destination) {
276  me->d_destination->pack_message(p.payload_len, p.msg_time, id,
277  me->d_destinationService, p.buffer,
278  serviceClass);
279 
280  // HACK: should we have this here?
281  me->d_destination->mainloop();
282  }
283 
284  return 0;
285 }
286 
287 vrpn_int32 vrpn_StreamForwarder::map(vrpn_int32 *id,
288  vrpn_uint32 *classOfService)
289 {
290 
291  vrpn_STREAMFORWARDERRECORD *dlp;
292 
293  for (dlp = d_list; dlp; dlp = dlp->next)
294  if (*id == dlp->sourceId) {
295  *id = dlp->destinationId;
296  *classOfService = dlp->classOfService;
297  return 0;
298  }
299 
300  return -1;
301 }
302 
303 // Build a mapping from the source Connection's types to the destination
304 // Connection's. Store the class of service to be used on forwarding.
305 
306 vrpn_StreamForwarder::vrpn_STREAMFORWARDERRECORD::vrpn_STREAMFORWARDERRECORD(
307  vrpn_Connection *source, vrpn_Connection *dest, const char *iSourceId,
308  const char *iDestId, vrpn_uint32 cos)
309  : sourceId(source->register_message_type(iSourceId))
310  , destinationId(dest->register_message_type(iDestId))
311  , classOfService(cos)
312  , next(NULL)
313 {
314 }
vrpn_StreamForwarder::unforward
int unforward(const char *sourceName, const char *destinationName, vrpn_uint32 classOfService=vrpn_CONNECTION_RELIABLE)
Definition: vrpn_Forwarder.C:230
vrpn_Connection::pack_message
virtual int pack_message(vrpn_uint32 len, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer, vrpn_uint32 class_of_service)
Pack a message that will be sent the next time mainloop() is called. Turn off the RELIABLE flag if yo...
Definition: vrpn_Connection.C:4632
vrpn_ConnectionForwarder::forward
int forward(const char *sourceName, const char *sourceServiceName, const char *destinationName, const char *destinationServiceName, vrpn_uint32 classOfService=vrpn_CONNECTION_RELIABLE)
Definition: vrpn_Forwarder.C:44
vrpn_ConnectionForwarder::unforward
int unforward(const char *sourceName, const char *sourceServiceName, const char *destinationName, const char *destinationServiceName, vrpn_uint32 classOfService=vrpn_CONNECTION_RELIABLE)
Definition: vrpn_Forwarder.C:68
vrpn_HANDLERPARAM::payload_len
vrpn_int32 payload_len
Definition: vrpn_Connection.h:48
vrpn_StreamForwarder::vrpn_StreamForwarder
vrpn_StreamForwarder(vrpn_Connection *source, const char *sourceServiceName, vrpn_Connection *destination, const char *destinationServiceName)
Definition: vrpn_Forwarder.C:167
vrpn_Connection::addReference
void addReference()
Counting references to this connection.
Definition: vrpn_Connection.C:5013
vrpn_HANDLERPARAM::buffer
const char * buffer
Definition: vrpn_Connection.h:49
vrpn_Connection::register_message_type
virtual vrpn_int32 register_message_type(const char *name)
Definition: vrpn_Connection.C:5074
vrpn_ConnectionForwarder::vrpn_ConnectionForwarder
vrpn_ConnectionForwarder(vrpn_Connection *source, vrpn_Connection *destination)
Definition: vrpn_Forwarder.C:5
vrpn_ConnectionForwarder::~vrpn_ConnectionForwarder
~vrpn_ConnectionForwarder(void)
Definition: vrpn_Forwarder.C:20
vrpn_HANDLERPARAM
This structure is what is passed to a vrpn_Connection message callback.
Definition: vrpn_Connection.h:44
vrpn_Connection::unregister_handler
virtual int unregister_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
Definition: vrpn_Connection.C:5206
vrpn_StreamForwarder
Definition: vrpn_Forwarder.h:83
vrpn_Connection::mainloop
virtual int mainloop(const struct timeval *timeout=NULL)=0
Call each time through program main loop to handle receiving any incoming messages and sending any pa...
vrpn_HANDLERPARAM::msg_time
struct timeval msg_time
Definition: vrpn_Connection.h:47
vrpn_Connection
Generic connection class not specific to the transport mechanism.
Definition: vrpn_Connection.h:510
vrpn_Forwarder.h
vrpn_StreamForwarder::forward
int forward(const char *sourceName, const char *destinationName, vrpn_uint32 classOfService=vrpn_CONNECTION_RELIABLE)
Definition: vrpn_Forwarder.C:210
vrpn_Connection::register_sender
virtual vrpn_int32 register_sender(const char *name)
Get a token to use for the string name of the sender or type. Remember to check for -1 meaning failur...
Definition: vrpn_Connection.C:5032
vrpn_HANDLERPARAM::type
vrpn_int32 type
Definition: vrpn_Connection.h:45
vrpn_Connection::removeReference
void removeReference()
Definition: vrpn_Connection.C:5020
vrpn_StreamForwarder::~vrpn_StreamForwarder
~vrpn_StreamForwarder(void)
Definition: vrpn_Forwarder.C:186
vrpn_HANDLERPARAM::sender
vrpn_int32 sender
Definition: vrpn_Connection.h:46
vrpn_Connection::register_handler
virtual int register_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
Set up (or remove) a handler for a message of a given type. Optionally, specify which sender to handl...
Definition: vrpn_Connection.C:5199
vrpn_ConnectionForwarder
Definition: vrpn_Forwarder.h:28