vrpn  07.33
Virtual Reality Peripheral Network
vrpn_ForwarderController.C
Go to the documentation of this file.
1 #include <stdio.h> // for fprintf, stderr
2 #include <string.h> // for memcpy, strlen, NULL, etc
3 
4 #include "vrpn_Connection.h" // for vrpn_Connection, etc
6 #include "vrpn_Shared.h" // for timeval, vrpn_gettimeofday
7 #if !(defined(_WIN32) && defined(VRPN_USE_WINSOCK_SOCKETS))
8 #include <netinet/in.h> // for htonl, ntohl
9 #endif
10 
11 #include "vrpn_Forwarder.h" // for vrpn_ConnectionForwarder
12 
14  : d_connection(c)
15  , d_myId(-1)
16 {
17 
18  if (!c) return;
19 
21 
22  d_myId = c->register_sender("vrpn_Forwarder_Brain");
23 
25  c->register_message_type("vrpn_Forwarder_Brain start_forwarding");
26  d_forward_type = c->register_message_type("vrpn_Forwarder_Brain forward");
27 }
28 
30 {
31 
32  if (d_connection) {
34  }
35 }
36 
37 // static
38 char *
40  vrpn_int32 remote_port)
41 {
42  char *outbuf;
43 
44  vrpn_int32 nPort;
45 
46  *length = sizeof(vrpn_int32);
47  outbuf = new char[*length];
48  if (!outbuf) {
49  *length = 0;
50  return NULL;
51  }
52 
53  nPort = htonl(remote_port);
54  memcpy(outbuf, &nPort, sizeof(vrpn_int32));
55 
56  return outbuf;
57 }
58 
59 // static
61  const char *buffer, vrpn_int32 *remote_port)
62 {
63  vrpn_int32 port;
64 
65  if (!buffer || !remote_port) return;
66 
67  memcpy(&port, buffer, sizeof(vrpn_int32));
68  *remote_port = ntohl(port);
69 }
70 
71 // static
73  vrpn_int32 *length, vrpn_int32 remote_port, const char *service_name,
74  const char *message_type)
75 {
76  char *outbuf;
77 
78  vrpn_int32 nPort;
79  vrpn_int32 nSLen;
80  vrpn_int32 nTLen;
81 
82  *length = static_cast<int>(3 * sizeof(vrpn_int32) + strlen(service_name) +
83  strlen(message_type));
84  outbuf = new char[*length];
85  if (!outbuf) {
86  *length = 0;
87  return NULL;
88  }
89 
90  // fprintf(stderr, "Encoding forward %s of %s on port %d.\n",
91  // message_type, service_name, remote_port);
92 
93  // Put all the char [] at the end of the message so we don't have to
94  // worry about padding and alignment.
95 
96  nPort = htonl(remote_port);
97  nSLen = htonl(static_cast<vrpn_int32>(strlen(service_name)));
98  nTLen = htonl(static_cast<vrpn_int32>(strlen(message_type)));
99  memcpy(outbuf, &nPort, sizeof(vrpn_int32));
100  memcpy(outbuf + sizeof(vrpn_int32), &nSLen, sizeof(vrpn_int32));
101  memcpy(outbuf + 2 * sizeof(vrpn_int32), &nTLen, sizeof(vrpn_int32));
102  strcpy(outbuf + 3 * sizeof(vrpn_int32), service_name);
103  strcpy(outbuf + 3 * sizeof(vrpn_int32) + strlen(service_name),
104  message_type);
105 
106  return outbuf;
107 }
108 
109 // static
111  vrpn_int32 *remote_port,
112  char **service_name,
113  char **message_type)
114 {
115  vrpn_int32 port;
116  vrpn_int32 Slength;
117  vrpn_int32 Tlength;
118  char *Soutbuf;
119  char *Toutbuf;
120 
121  if (!buffer || !remote_port || !message_type) return;
122 
123  // All the char [] are at the end of the message so we don't have to
124  // worry about padding and alignment.
125 
126  memcpy(&port, buffer, sizeof(vrpn_int32));
127  *remote_port = ntohl(port);
128  memcpy(&Slength, buffer + sizeof(vrpn_int32), sizeof(vrpn_int32));
129  Slength = ntohl(Slength);
130  Soutbuf = new char[1 + Slength];
131  memcpy(&Tlength, buffer + 2 * sizeof(vrpn_int32), sizeof(vrpn_int32));
132  Tlength = ntohl(Tlength);
133  Toutbuf = new char[1 + Tlength];
134  if (!Soutbuf || !Toutbuf) {
135  *remote_port = -1;
136  *service_name = NULL;
137  *message_type = NULL;
138  return;
139  }
140  strncpy(Soutbuf, buffer + 3 * sizeof(vrpn_int32), Slength);
141  Soutbuf[Slength] = '\0';
142  *service_name = Soutbuf;
143  strncpy(Toutbuf, buffer + 3 * sizeof(vrpn_int32) + Slength, Tlength);
144  Toutbuf[Tlength] = '\0';
145  *message_type = Toutbuf;
146 }
147 
150  , d_myForwarders(NULL)
151 {
152 
153  if (!c) return;
154 
155  c->register_handler(d_start_forwarding_type, handle_start, this, d_myId);
156  c->register_handler(d_forward_type, handle_forward, this, d_myId);
157 }
158 
160 {
161 
162  if (!d_connection) return;
163 
165  this, d_myId);
166  d_connection->unregister_handler(d_forward_type, handle_forward, this,
167  d_myId);
168 
169  // Destroy my list of forwarders
171  for (fp = d_myForwarders; fp; fp = fp->next) {
172  if (fp->connection) delete fp->connection;
173  if (fp->forwarder) delete fp->forwarder;
174  }
175 }
176 
178 {
179 
181 
182  for (fp = d_myForwarders; fp; fp = fp->next)
183  if (fp->connection) fp->connection->mainloop();
184 }
185 
187 {
188 
190 
191  // Make sure it isn't already there
192 
193  for (fp = d_myForwarders; fp; fp = fp->next)
194  if (fp->port == remote_port) {
195  fprintf(stderr, "vrpn_Forwarder_Server::start_remote_forwarding: "
196  "Already open on port %d.\n",
197  remote_port);
198  return;
199  }
200 
201  // Create it and add it to the list
202 
203  fp = new vrpn_Forwarder_List;
204 
205  fp->port = remote_port;
206  fp->connection = vrpn_create_server_connection(remote_port);
208 
209  fp->next = d_myForwarders;
210  d_myForwarders = fp;
211 
212  // fprintf(stderr, "vrpn_Forwarder_Server::start_remote_forwarding: "
213  //"On port %d.\n", remote_port);
214 }
215 
217  const char *service_name,
218  const char *message_type)
219 {
220 
222  vrpn_Forwarder_List *it = NULL;
223  int retval;
224 
225  // Find the forwarder requested
226 
227  for (fp = d_myForwarders; fp; fp = fp->next)
228  if (fp->port == remote_port) it = fp;
229 
230  if (!it) {
231  fprintf(stderr,
232  "vrpn_Forwarder_Server: No forwarder open on port %d.\n",
233  remote_port);
234  return;
235  }
236 
237  // Forward that message type from that service
238 
239  retval = it->forwarder->forward(message_type, service_name, message_type,
240  service_name);
241  if (retval) {
242  fprintf(stderr, "vrpn_Forwarder_Server: Couldn't forward messages of "
243  "type \"%s\" on port %d.\n",
244  message_type, remote_port);
245  return;
246  }
247 }
248 
249 // static
250 int vrpn_Forwarder_Server::handle_start(void *userdata, vrpn_HANDLERPARAM p)
251 {
253  vrpn_int32 port;
254 
256  me->start_remote_forwarding(port);
257  return 0;
258 }
259 
260 // static
261 int vrpn_Forwarder_Server::handle_forward(void *userdata, vrpn_HANDLERPARAM p)
262 {
264  vrpn_int32 port;
265  char *typebuffer;
266  char *servicebuffer;
267 
268  decode_forward_message_type(p.buffer, &port, &servicebuffer, &typebuffer);
269  if (!servicebuffer || !typebuffer) return -1; // memory allocation failure
270  me->forward_message_type(port, servicebuffer, typebuffer);
271 
272  delete[] servicebuffer;
273  delete[] typebuffer;
274  return 0;
275 }
276 
279 {
280 }
281 
283 
285 {
286 
287  struct timeval now;
288  char *buffer;
289  vrpn_int32 length;
290 
291  vrpn_gettimeofday(&now, NULL);
292  buffer = encode_start_remote_forwarding(&length, remote_port);
293 
294  if (!buffer) return; // memory allocation failure
295 
297  buffer, vrpn_CONNECTION_RELIABLE);
298  delete[] buffer;
299 }
300 
302  const char *service_name,
303  const char *message_type)
304 {
305  struct timeval now;
306  char *buffer;
307  vrpn_int32 length;
308 
309  vrpn_gettimeofday(&now, NULL);
310  buffer = encode_forward_message_type(&length, remote_port, service_name,
311  message_type);
312 
313  if (!buffer) return; // memory allocation failure
314 
315  d_connection->pack_message(length, now, d_forward_type, d_myId, buffer,
317  delete[] buffer;
318 }
vrpn_Forwarder_Server::forward_message_type
virtual void forward_message_type(vrpn_int32 remote_port, const char *service_name, const char *message_type)
Definition: vrpn_ForwarderController.C:216
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_Forwarder_List::connection
vrpn_Connection * connection
Definition: vrpn_ForwarderController.h:87
vrpn_Forwarder_Controller::start_remote_forwarding
virtual void start_remote_forwarding(vrpn_int32 remote_port)
Definition: vrpn_ForwarderController.C:284
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_Forwarder_Brain::~vrpn_Forwarder_Brain
virtual ~vrpn_Forwarder_Brain(void)
Definition: vrpn_ForwarderController.C:29
vrpn_Forwarder_Controller::forward_message_type
virtual void forward_message_type(vrpn_int32 remote_port, const char *service_name, const char *message_type)
Definition: vrpn_ForwarderController.C:301
vrpn_Forwarder_List::next
vrpn_Forwarder_List * next
Definition: vrpn_ForwarderController.h:85
vrpn_Forwarder_Brain::d_myId
vrpn_int32 d_myId
Definition: vrpn_ForwarderController.h:58
vrpn_ConnectionForwarder
class VRPN_API vrpn_ConnectionForwarder
Definition: vrpn_ForwarderController.h:34
vrpn_Forwarder_Server::~vrpn_Forwarder_Server
virtual ~vrpn_Forwarder_Server(void)
Definition: vrpn_ForwarderController.C:159
vrpn_Forwarder_Server::mainloop
virtual void mainloop(void)
Definition: vrpn_ForwarderController.C:177
vrpn_Forwarder_Server::vrpn_Forwarder_Server
vrpn_Forwarder_Server(vrpn_Connection *)
Definition: vrpn_ForwarderController.C:148
vrpn_Forwarder_Brain
Definition: vrpn_ForwarderController.h:38
vrpn_Forwarder_Server::d_myForwarders
vrpn_Forwarder_List * d_myForwarders
Definition: vrpn_ForwarderController.h:106
vrpn_Forwarder_List
Definition: vrpn_ForwarderController.h:84
vrpn_Connection::addReference
void addReference()
Counting references to this connection.
Definition: vrpn_Connection.C:5013
vrpn_Forwarder_Brain::decode_forward_message_type
static void decode_forward_message_type(const char *buffer, vrpn_int32 *remote_port, char **service_name, char **message_type)
Definition: vrpn_ForwarderController.C:110
vrpn_Forwarder_Controller::~vrpn_Forwarder_Controller
~vrpn_Forwarder_Controller(void)
Definition: vrpn_ForwarderController.C:282
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_Forwarder_List::forwarder
vrpn_ConnectionForwarder * forwarder
Definition: vrpn_ForwarderController.h:88
vrpn_CONNECTION_RELIABLE
const vrpn_uint32 vrpn_CONNECTION_RELIABLE
Classes of service for messages, specify multiple by ORing them together Priority of satisfying these...
Definition: vrpn_Connection.h:120
vrpn_HANDLERPARAM
This structure is what is passed to a vrpn_Connection message callback.
Definition: vrpn_Connection.h:44
vrpn_Shared.h
vrpn_Forwarder_Server
Definition: vrpn_ForwarderController.h:91
vrpn_Forwarder_Brain::d_forward_type
vrpn_int32 d_forward_type
Definition: vrpn_ForwarderController.h:61
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_Forwarder_Brain::encode_start_remote_forwarding
static char * encode_start_remote_forwarding(vrpn_int32 *length, vrpn_int32 remote_port)
Definition: vrpn_ForwarderController.C:39
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_Connection
Generic connection class not specific to the transport mechanism.
Definition: vrpn_Connection.h:510
vrpn_Connection.h
vrpn_Forwarder.h
vrpn_gettimeofday
#define vrpn_gettimeofday
Definition: vrpn_Shared.h:89
vrpn_Forwarder_List::port
vrpn_int32 port
Definition: vrpn_ForwarderController.h:86
vrpn_Forwarder_Brain::encode_forward_message_type
static char * encode_forward_message_type(vrpn_int32 *length, vrpn_int32 remote_port, const char *service_name, const char *message_type)
Definition: vrpn_ForwarderController.C:72
vrpn_ForwarderController.h
vrpn_Forwarder_Brain::d_start_forwarding_type
vrpn_int32 d_start_forwarding_type
Definition: vrpn_ForwarderController.h:60
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_Forwarder_Brain::decode_start_remote_forwarding
static void decode_start_remote_forwarding(const char *buffer, vrpn_int32 *remote_port)
Definition: vrpn_ForwarderController.C:60
vrpn_Forwarder_Brain::d_connection
vrpn_Connection * d_connection
Definition: vrpn_ForwarderController.h:56
vrpn_Connection::removeReference
void removeReference()
Definition: vrpn_Connection.C:5020
vrpn_Forwarder_Server::start_remote_forwarding
virtual void start_remote_forwarding(vrpn_int32 remote_port)
Definition: vrpn_ForwarderController.C:186
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_Forwarder_Controller::vrpn_Forwarder_Controller
vrpn_Forwarder_Controller(vrpn_Connection *)
Definition: vrpn_ForwarderController.C:277
vrpn_Forwarder_Brain::vrpn_Forwarder_Brain
vrpn_Forwarder_Brain(vrpn_Connection *)
Definition: vrpn_ForwarderController.C:13
vrpn_create_server_connection
vrpn_Connection * vrpn_create_server_connection(const char *cname, const char *local_in_logfile_name, const char *local_out_logfile_name)
Create a server connection of arbitrary type (VRPN UDP/TCP, TCP, File, Loopback, MPI).
Definition: vrpn_Connection.C:5358