vrpn 07.35
Virtual Reality Peripheral Network
Loading...
Searching...
No Matches
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 vrpn_CONNECTIONFORWARDERRECORD *dlp;
23
24 while (d_list) {
25 dlp = d_list->next;
26
27 if (d_source)
28 d_source->unregister_handler(d_list->sourceId, handle_message, this,
29 d_list->sourceServiceId);
30 try {
31 delete d_list;
32 } catch (...) {
33 fprintf(stderr, "vrpn_ConnectionForwarder::~vrpn_ConnectionForwarder(): delete failed\n");
34 return;
35 }
36 d_list = dlp;
37 }
38
39 if (d_source) {
40 d_source->removeReference();
41 }
42 if (d_destination) {
43 d_destination->removeReference();
44 }
45}
46
47int vrpn_ConnectionForwarder::forward(const char *sourceName,
48 const char *sourceServiceId,
49 const char *destinationName,
50 const char *destinationServiceId,
51 vrpn_uint32 classOfService)
52{
53 vrpn_CONNECTIONFORWARDERRECORD *newList = NULL;
54 try { newList =
55 new vrpn_CONNECTIONFORWARDERRECORD(
56 d_source, d_destination, sourceName, sourceServiceId,
57 destinationName, destinationServiceId, classOfService);
58 } catch (...) { return -1; }
59
60 newList->next = d_list;
61 d_list = newList;
62
63 if (d_source)
64 d_source->register_handler(newList->sourceId, handle_message, this,
65 newList->sourceServiceId);
66
67 return 0;
68}
69
70int vrpn_ConnectionForwarder::unforward(const char *sourceName,
71 const char *sourceServiceId,
72 const char *destinationName,
73 const char *destinationServiceId,
74 vrpn_uint32 classOfService)
75{
76
77 vrpn_CONNECTIONFORWARDERRECORD **snitch;
78 vrpn_CONNECTIONFORWARDERRECORD *victim;
79
80 vrpn_int32 st, ss, dt, ds;
81
82 st = d_source->register_message_type(sourceName);
83 ss = d_source->register_sender(sourceServiceId);
84 dt = d_destination->register_message_type(destinationName);
85 ds = d_source->register_sender(destinationServiceId);
86
87 for (snitch = &d_list, victim = *snitch; victim;
88 snitch = &(victim->next), victim = *snitch) {
89
90 if ((victim->sourceId == st) && (victim->sourceServiceId == ss) &&
91 (victim->destinationId == dt) &&
92 (victim->destinationServiceId == ds) &&
93 (victim->classOfService == classOfService)) {
94 (*snitch)->next = victim->next;
95 try {
96 delete victim;
97 } catch (...) {
98 fprintf(stderr, "vrpn_ConnectionForwarder::unforward(): delete failed\n");
99 return -1;
100 }
101 victim = *snitch;
102 }
103 }
104
105 return 0;
106}
107
108// static
109int vrpn_ConnectionForwarder::handle_message(void *userdata,
111{
112
114
115 vrpn_int32 id = p.type;
116 vrpn_int32 serviceId = p.sender;
117 vrpn_uint32 serviceClass;
118
119 int retval;
120
121 // Convert from source's representation for type & sender ID to
122 // that of destination; look up service class to use (defaulted to
123 // vrpn_CONNECTION_RELIABLE).
124
125 retval = me->map(&id, &serviceId, &serviceClass);
126 if (retval) return -1;
127
128 if (me->d_destination) {
129 me->d_destination->pack_message(p.payload_len, p.msg_time, id,
130 serviceId, p.buffer, serviceClass);
131
132 // HACK: should we have this here?
133 me->d_destination->mainloop();
134 }
135
136 return 0;
137}
138
139vrpn_int32 vrpn_ConnectionForwarder::map(vrpn_int32 *id, vrpn_int32 *serviceId,
140 vrpn_uint32 *classOfService)
141{
142
143 vrpn_CONNECTIONFORWARDERRECORD *dlp;
144
145 for (dlp = d_list; dlp; dlp = dlp->next)
146 if ((*id == dlp->sourceId) && (*serviceId == dlp->sourceServiceId)) {
147 *id = dlp->destinationId;
148 *serviceId = dlp->destinationServiceId;
149 *classOfService = dlp->classOfService;
150 return 0;
151 }
152
153 return -1;
154}
155
156// Build a mapping from the source Connection's types to the destination
157// Connection's. Store the class of service to be used on forwarding.
158
159vrpn_ConnectionForwarder::vrpn_CONNECTIONFORWARDERRECORD::
160 vrpn_CONNECTIONFORWARDERRECORD(vrpn_Connection *source,
161 vrpn_Connection *dest, const char *iSourceId,
162 const char *iSourceServiceId,
163 const char *iDestId,
164 const char *iDestServiceId, vrpn_uint32 cos)
165 : sourceId(source->register_message_type(iSourceId))
166 , sourceServiceId(source->register_sender(iSourceServiceId))
167 , destinationId(dest->register_message_type(iDestId))
168 , destinationServiceId(dest->register_sender(iDestServiceId))
169 , classOfService(cos)
170 , next(NULL)
171{
172}
173
175 const char *sourceServiceName,
176 vrpn_Connection *destination,
177 const char *destinationServiceName)
178 : d_source(source)
179 , d_sourceService(source->register_sender(sourceServiceName))
180 , d_destination(destination)
181 , d_destinationService(destination->register_sender(destinationServiceName))
182 , d_list(NULL)
183{
184
185 if (d_source) {
186 d_source->addReference();
187 }
188 if (d_destination) {
189 d_destination->addReference();
190 }
191}
192
194{
195
196 vrpn_STREAMFORWARDERRECORD *dlp;
197
198 while (d_list) {
199 dlp = d_list->next;
200
201 if (d_source)
202 d_source->unregister_handler(d_list->sourceId, handle_message, this,
203 d_sourceService);
204
205 try {
206 delete d_list;
207 } catch (...) {
208 fprintf(stderr, "vrpn_StreamForwarder::~vrpn_StreamForwarder(): delete failed\n");
209 return;
210 }
211 d_list = dlp;
212 }
213
214 if (d_source) {
215 d_source->removeReference();
216 }
217 if (d_destination) {
218 d_destination->removeReference();
219 }
220}
221
222int vrpn_StreamForwarder::forward(const char *sourceName,
223 const char *destinationName,
224 vrpn_uint32 classOfService)
225{
226 vrpn_STREAMFORWARDERRECORD *newList = NULL;
227 try { newList = new vrpn_STREAMFORWARDERRECORD(
228 d_source, d_destination, sourceName, destinationName, classOfService);
229 } catch (...) { return -1; }
230
231 newList->next = d_list;
232 d_list = newList;
233
234 if (d_source)
235 d_source->register_handler(newList->sourceId, handle_message, this,
236 d_sourceService);
237
238 return 0;
239}
240
241int vrpn_StreamForwarder::unforward(const char *sourceName,
242 const char *destinationName,
243 vrpn_uint32 classOfService)
244{
245
246 vrpn_STREAMFORWARDERRECORD **snitch;
247 vrpn_STREAMFORWARDERRECORD *victim;
248
249 vrpn_int32 st, dt;
250
251 st = d_source->register_message_type(sourceName);
252 dt = d_destination->register_message_type(destinationName);
253
254 for (snitch = &d_list, victim = *snitch; victim;
255 snitch = &(victim->next), victim = *snitch) {
256
257 if ((victim->sourceId == st) && (victim->destinationId == dt) &&
258 (victim->classOfService == classOfService)) {
259 (*snitch)->next = victim->next;
260 try {
261 delete victim;
262 } catch (...) {
263 fprintf(stderr, "vrpn_StreamForwarder::unforward(): delete failed\n");
264 return -1;
265 }
266 victim = *snitch;
267 }
268 }
269
270 return 0;
271}
272
273// static
274int vrpn_StreamForwarder::handle_message(void *userdata, vrpn_HANDLERPARAM p)
275{
276
278
279 vrpn_int32 id = p.type;
280 vrpn_uint32 serviceClass;
281
282 int retval;
283
284 // Convert from source's representation for type & sender ID to
285 // that of destination; look up service class to use (defaulted to
286 // vrpn_CONNECTION_RELIABLE).
287
288 retval = me->map(&id, &serviceClass);
289 if (retval) return -1;
290
291 if (me->d_destination) {
292 me->d_destination->pack_message(p.payload_len, p.msg_time, id,
293 me->d_destinationService, p.buffer,
294 serviceClass);
295
296 // HACK: should we have this here?
297 me->d_destination->mainloop();
298 }
299
300 return 0;
301}
302
303vrpn_int32 vrpn_StreamForwarder::map(vrpn_int32 *id,
304 vrpn_uint32 *classOfService)
305{
306
307 vrpn_STREAMFORWARDERRECORD *dlp;
308
309 for (dlp = d_list; dlp; dlp = dlp->next)
310 if (*id == dlp->sourceId) {
311 *id = dlp->destinationId;
312 *classOfService = dlp->classOfService;
313 return 0;
314 }
315
316 return -1;
317}
318
319// Build a mapping from the source Connection's types to the destination
320// Connection's. Store the class of service to be used on forwarding.
321
322vrpn_StreamForwarder::vrpn_STREAMFORWARDERRECORD::vrpn_STREAMFORWARDERRECORD(
323 vrpn_Connection *source, vrpn_Connection *dest, const char *iSourceId,
324 const char *iDestId, vrpn_uint32 cos)
325 : sourceId(source->register_message_type(iSourceId))
326 , destinationId(dest->register_message_type(iDestId))
327 , classOfService(cos)
328 , next(NULL)
329{
330}
vrpn_ConnectionForwarder(vrpn_Connection *source, vrpn_Connection *destination)
Definition: vrpn_Forwarder.C:5
int unforward(const char *sourceName, const char *sourceServiceName, const char *destinationName, const char *destinationServiceName, vrpn_uint32 classOfService=vrpn_CONNECTION_RELIABLE)
int forward(const char *sourceName, const char *sourceServiceName, const char *destinationName, const char *destinationServiceName, vrpn_uint32 classOfService=vrpn_CONNECTION_RELIABLE)
Generic connection class not specific to the transport mechanism.
void addReference()
Counting references to this connection.
virtual vrpn_int32 register_message_type(const char *name)
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...
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...
virtual int unregister_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
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...
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...
int forward(const char *sourceName, const char *destinationName, vrpn_uint32 classOfService=vrpn_CONNECTION_RELIABLE)
int unforward(const char *sourceName, const char *destinationName, vrpn_uint32 classOfService=vrpn_CONNECTION_RELIABLE)
vrpn_StreamForwarder(vrpn_Connection *source, const char *sourceServiceName, vrpn_Connection *destination, const char *destinationServiceName)
This structure is what is passed to a vrpn_Connection message callback.
const char * buffer
struct timeval msg_time
vrpn_int32 payload_len