vrpn 07.35
Virtual Reality Peripheral Network
Loading...
Searching...
No Matches
vrpn_Auxiliary_Logger.C
Go to the documentation of this file.
1#include <stddef.h> // for size_t
2#include <stdio.h> // for fprintf, stderr
3
5
12
14{
16 "vrpn_Auxiliary_Logger Logging_request");
18 "vrpn_Auxiliary_Logger Logging_response");
20 "vrpn_Auxiliary_Logger Logging_status_request");
21
22 if ((request_logging_m_id == -1) || (report_logging_m_id == -1) ||
24 d_connection = NULL;
25 return -1;
26 }
27 else {
28 return 0;
29 }
30}
31
32// Send a message of the specified type.
33// Note that the pointers may be NULL, so we need to check for this.
35 vrpn_int32 type, const char *local_in_logfile_name,
36 const char *local_out_logfile_name, const char *remote_in_logfile_name,
37 const char *remote_out_logfile_name)
38{
39 if (!d_connection) {
40 return false;
41 }
42
43 // Figure out the lengths, handling NULL pointers.
44 vrpn_int32 lil = 0;
45 if (local_in_logfile_name) {
46 lil = static_cast<vrpn_int32>(strlen(local_in_logfile_name));
47 }
48 vrpn_int32 lol = 0;
49 if (local_out_logfile_name) {
50 lol = static_cast<vrpn_int32>(strlen(local_out_logfile_name));
51 }
52 vrpn_int32 ril = 0;
53 if (remote_in_logfile_name) {
54 ril = static_cast<vrpn_int32>(strlen(remote_in_logfile_name));
55 }
56 vrpn_int32 rol = 0;
57 if (remote_out_logfile_name) {
58 rol = static_cast<vrpn_int32>(strlen(remote_out_logfile_name));
59 }
60
61 struct timeval now;
62 vrpn_int32 bufsize =
63 static_cast<vrpn_int32>(4 * sizeof(lil) + lil + lol + ril + rol);
64 std::vector<char> buf;
65 try {
66 buf.resize(bufsize);
67 } catch (...) {
68 fprintf(stderr, "vrpn_Auxiliary_Logger::pack_log_message_of_type(): "
69 "Out of memory.\n");
70 return false;
71 }
72
73 // Pack a message with the requested type from our sender ID that has
74 // first the four lengths of the strings and then the four strings.
75 // Do not include the NULL termination of the strings in the buffer.
76
77 vrpn_gettimeofday(&now, NULL);
78 char *bpp = buf.data();
79 char **bp = &bpp;
80 vrpn_int32 bufleft = bufsize;
81 vrpn_buffer(bp, &bufleft, lil);
82 vrpn_buffer(bp, &bufleft, lol);
83 vrpn_buffer(bp, &bufleft, ril);
84 vrpn_buffer(bp, &bufleft, rol);
85 if (lil) {
86 vrpn_buffer(bp, &bufleft, local_in_logfile_name, lil);
87 }
88 if (lol) {
89 vrpn_buffer(bp, &bufleft, local_out_logfile_name, lol);
90 }
91 if (ril) {
92 vrpn_buffer(bp, &bufleft, remote_in_logfile_name, ril);
93 }
94 if (rol) {
95 vrpn_buffer(bp, &bufleft, remote_out_logfile_name, rol);
96 }
97 int ret =
98 d_connection->pack_message(bufsize - bufleft, now, type, d_sender_id,
99 buf.data(), vrpn_CONNECTION_RELIABLE);
100 return (ret == 0);
101}
102
103// Unpack the strings from the buffer. Return non-NULL pointers to
104// strings (an empty string when a file name is empty).
106 const char *buf, vrpn_int32 buflen, char **local_in_logfile_name,
107 char **local_out_logfile_name, char **remote_in_logfile_name,
108 char **remote_out_logfile_name)
109{
110 const char *bufptr = buf;
111
112 // Make sure that the buffer contains at least enough space for the four
113 // length
114 // values, then pull the lengths of the strings out of the buffer
115 vrpn_int32 localInNameLen, localOutNameLen, remoteInNameLen,
116 remoteOutNameLen;
117 if (static_cast<size_t>(buflen) < 4 * sizeof(localInNameLen)) {
118 fprintf(stderr, "vrpn_Auxiliary_Logger::unpack_log_message_from_buffer:"
119 " Buffer too small for lengths.\n");
120 return false;
121 }
122 vrpn_unbuffer(&bufptr, &localInNameLen);
123 vrpn_unbuffer(&bufptr, &localOutNameLen);
124 vrpn_unbuffer(&bufptr, &remoteInNameLen);
125 vrpn_unbuffer(&bufptr, &remoteOutNameLen);
126
127 // Make sure we have enough room in the buffer for the four sizes and also
128 // the four
129 // strings of the appropriate size. If so, allocate the space for the
130 // strings and then
131 // copy them out and NULL-terminate them. They are not NULL-terminated in
132 // the message
133 // buffer.
134 int size = 4 * sizeof(localInNameLen) + localInNameLen + localOutNameLen +
135 remoteInNameLen + remoteOutNameLen;
136 if (buflen != size) {
137 fprintf(stderr, "vrpn_Auxiliary_Logger::unpack_log_message_from_buffer:"
138 " Buffer size incorrect\n");
139 return false;
140 }
141 (*local_in_logfile_name) = NULL;
142 (*local_out_logfile_name) = NULL;
143 (*remote_in_logfile_name) = NULL;
144 (*remote_out_logfile_name) = NULL;
145 if (localInNameLen > 0) {
146 try { (*local_in_logfile_name) = new char[localInNameLen + 1]; }
147 catch (...) {
148 fprintf(stderr, "vrpn_Auxiliary_Logger::unpack_log_message_from_"
149 "buffer: Out of memory\n");
150 return false;
151 }
152 memcpy(*local_in_logfile_name, bufptr, localInNameLen);
153 (*local_in_logfile_name)[localInNameLen] = '\0';
154 bufptr += localInNameLen;
155 } else {
156 (*local_in_logfile_name) = NULL;
157 }
158 if (localOutNameLen > 0) {
159 try { (*local_out_logfile_name) = new char[localOutNameLen + 1]; }
160 catch (...) {
161 fprintf(stderr, "vrpn_Auxiliary_Logger::unpack_log_message_from_"
162 "buffer: Out of memory\n");
163 return false;
164 }
165 memcpy(*local_out_logfile_name, bufptr, localOutNameLen);
166 (*local_out_logfile_name)[localOutNameLen] = '\0';
167 bufptr += localOutNameLen;
168 } else {
169 (*local_out_logfile_name) = NULL;
170 }
171 if (remoteInNameLen > 0) {
172 try { (*remote_in_logfile_name) = new char[remoteInNameLen + 1]; }
173 catch (...) {
174 fprintf(stderr, "vrpn_Auxiliary_Logger::unpack_log_message_from_"
175 "buffer: Out of memory\n");
176 return false;
177 }
178 memcpy(*remote_in_logfile_name, bufptr, remoteInNameLen);
179 (*remote_in_logfile_name)[remoteInNameLen] = '\0';
180 bufptr += remoteInNameLen;
181 } else {
182 (*remote_in_logfile_name) = NULL;
183 }
184 if (remoteOutNameLen > 0) {
185 try { (*remote_out_logfile_name) = new char[remoteOutNameLen + 1]; }
186 catch (...) {
187 fprintf(stderr, "vrpn_Auxiliary_Logger::unpack_log_message_from_"
188 "buffer: Out of memory\n");
189 return false;
190 }
191 memcpy(*remote_out_logfile_name, bufptr, remoteOutNameLen);
192 (*remote_out_logfile_name)[remoteOutNameLen] = '\0';
193 bufptr += remoteOutNameLen;
194 } else {
195 (*remote_out_logfile_name) = NULL;
196 }
197
198 return true;
199}
200
203 : vrpn_Auxiliary_Logger(name, c)
204{
205 // Register a handler for the dropped last connection message.
209 fprintf(stderr, "vrpn_Auxiliary_Logger_Server::vrpn_Auxiliary_Logger_"
210 "Server: can't register dropped last connection "
211 "type\n");
212 d_connection = NULL;
213 return;
214 }
217 this, vrpn_ANY_SENDER)) {
218 fprintf(stderr, "vrpn_Auxiliary_Logger_Server::vrpn_Auxiliary_Logger_"
219 "Server: can't register dropped last connection "
220 "handler\n");
221 d_connection = NULL;
222 }
223
224 // Register a handler for the request logging message.
227 d_sender_id)) {
228 fprintf(stderr, "vrpn_Auxiliary_Logger_Server::vrpn_Auxiliary_Logger_"
229 "Server: can't register logging request handler\n");
230 d_connection = NULL;
231 }
232
233 // Register a handler for the request logging-status message
236 d_sender_id)) {
237 fprintf(stderr, "vrpn_Auxiliary_Logger_Server::vrpn_Auxiliary_Logger_"
238 "Server: can't register logging-status request "
239 "handler\n");
240 d_connection = NULL;
241 }
242}
243
244// This handles the last dropped connection message by turning off all
245// logging.
250
251/* static */
252// This method just passes the call on to the virtual function.
261
262/* static */
271
272/* static */
273// This method just parses the raw data in the Handlerparam to produce strings
274// and then
275// passes the call on to the virtual function.
277 void *userdata, vrpn_HANDLERPARAM p)
278{
281 char *localInName = NULL, *localOutName = NULL, *remoteInName = NULL,
282 *remoteOutName = NULL;
283
284 // Attempt to unpack the names from the buffer
286 &localInName, &localOutName,
287 &remoteInName, &remoteOutName)) {
288 fprintf(stderr, "vrpn_Auxiliary_Logger_Server::static_handle_request_"
289 "logging: Could not unpack buffer\n");
290 return -1;
291 }
292
293 // Call the virtual function with the strings, then clean up memory and
294 // return.
295 me->handle_request_logging(localInName, localOutName, remoteInName,
296 remoteOutName);
297 if (localInName) {
298 try {
299 delete[] localInName;
300 } catch (...) {
301 fprintf(stderr, "vrpn_Auxiliary_Logger_Server::static_handle_request_logging: delete failed\n");
302 return -1;
303 }
304 };
305 if (localOutName) {
306 try {
307 delete[] localOutName;
308 } catch (...) {
309 fprintf(stderr, "vrpn_Auxiliary_Logger_Server::static_handle_request_logging: delete failed\n");
310 return -1;
311 }
312 };
313 if (remoteInName) {
314 try {
315 delete[] remoteInName;
316 } catch (...) {
317 fprintf(stderr, "vrpn_Auxiliary_Logger_Server::static_handle_request_logging: delete failed\n");
318 return -1;
319 }
320 };
321 if (remoteOutName) {
322 try {
323 delete[] remoteOutName;
324 } catch (...) {
325 fprintf(stderr, "vrpn_Auxiliary_Logger_Server::static_handle_request_logging: delete failed\n");
326 return -1;
327 }
328 };
329 return 0;
330}
331
333 const char *logger_name, const char *connection_to_log, vrpn_Connection *c)
334 : vrpn_Auxiliary_Logger_Server(logger_name, c)
335 , d_connection_name(NULL)
336 , d_logging_connection(NULL)
337{
338 // Copy the name of the connection to log and its NULL terminator.
339 if ((connection_to_log == NULL) || (strlen(connection_to_log) == 0)) {
340 fprintf(stderr, "vrpn_Auxiliary_Logger_Server_Generic::vrpn_Auxiliary_"
341 "Logger_Server_Generic: Empty logging name passed "
342 "in\n");
343 d_connection = NULL;
344 return;
345 }
346 d_connection_name = new char[strlen(connection_to_log) + 1];
347 memcpy(d_connection_name, connection_to_log, strlen(connection_to_log) + 1);
348}
349
351{
353 try {
355 } catch (...) {
356 fprintf(stderr, "vrpn_Auxiliary_Logger_Server_Generic::~vrpn_Auxiliary_Logger_Server_Generic: delete failed\n");
357 return;
358 }
360 }
361
362 if (d_connection_name) {
363 try {
364 delete[] d_connection_name;
365 } catch (...) {
366 fprintf(stderr, "vrpn_Auxiliary_Logger_Server_Generic::~vrpn_Auxiliary_Logger_Server_Generic: delete failed\n");
367 return;
368 }
369 d_connection_name = NULL;
370 }
371}
372
373// Close an existing logging connection, then (if any of the file
374// names are non-empty) open a new logging connection to the
375// connection we are to log (even if this process already has a
376// connection to it) and then send back the report that we've started
377// logging if we are able. If we cannot open it, then fill in all
378// blank names for the return report.
380 const char *local_in_logfile_name, const char *local_out_logfile_name,
381 const char *remote_in_logfile_name, const char *remote_out_logfile_name)
382{
383 // If we have a logging connection open, reduce its reference
384 // count (which may delete it but will leave it going if some
385 // other object has a pointer to it).
389 }
390
391 // If at least one of the names passed in is not empty, create
392 // a new logging connection. If this fails, report no logging.
393
394 // Find the relevant part of the name (skip past last '@'
395 // if there is one); also find the port number.
396 const char *cname = d_connection_name;
397 const char *where_at; // Part of name past last '@'
398 if ((where_at = strrchr(cname, '@')) != NULL) {
399 cname = where_at + 1; // Chop off the front of the name
400 }
401
402 // Pass "true" to force_connection so that it will open a new
403 // connection even if we already have one with that name.
405 where_at, local_in_logfile_name, local_out_logfile_name,
406 remote_in_logfile_name, remote_out_logfile_name, NULL, true);
408 struct timeval now;
409 vrpn_gettimeofday(&now, NULL);
410 send_text_message("handle_request_logging: Could not create connection "
411 "(files already exist?)",
412 now, vrpn_TEXT_ERROR);
413 send_report_logging(NULL, NULL, NULL, NULL);
415 try {
417 } catch (...) {
418 fprintf(stderr, "vrpn_Auxiliary_Logger_Server_Generic::handle_request_logging: delete failed\n");
419 return;
420 }
422 }
423 return;
424 }
425
426 // Report the logging that we're doing.
427 send_report_logging(local_in_logfile_name, local_out_logfile_name,
428 remote_in_logfile_name, remote_out_logfile_name);
429}
430
432{
433 char *local_in;
434 char *local_out;
435 char *remote_in;
436 char *remote_out;
437 d_logging_connection->get_log_names(&local_in, &local_out, &remote_in,
438 &remote_out);
439 send_report_logging(local_in, local_out, remote_in, remote_out);
440 if (local_in) {
441 try {
442 delete[] local_in;
443 } catch (...) {
444 fprintf(stderr, "vrpn_Auxiliary_Logger_Server_Generic::handle_request_logging_status: delete failed\n");
445 return;
446 }
447 }
448 if (local_out) {
449 try {
450 delete[] local_out;
451 } catch (...) {
452 fprintf(stderr, "vrpn_Auxiliary_Logger_Server_Generic::handle_request_logging_status: delete failed\n");
453 return;
454 }
455 }
456 if (remote_in) {
457 try {
458 delete[] remote_in;
459 } catch (...) {
460 fprintf(stderr, "vrpn_Auxiliary_Logger_Server_Generic::handle_request_logging_status: delete failed\n");
461 return;
462 }
463 }
464 if (remote_out) {
465 try {
466 delete[] remote_out;
467 } catch (...) {
468 fprintf(stderr, "vrpn_Auxiliary_Logger_Server_Generic::handle_request_logging_status: delete failed\n");
469 return;
470 }
471 }
472}
473
481
484 : vrpn_Auxiliary_Logger(name, c)
485{
486 // Register a handler for the report callback from this device,
487 // if we got a connection.
488 if (d_connection != NULL) {
491 d_sender_id)) {
492 fprintf(stderr,
493 "vrpn_Auxiliary_Logger_Remote: can't register handler\n");
494 d_connection = NULL;
495 }
496 }
497 else {
498 fprintf(stderr,
499 "vrpn_Auxiliary_Logger_Remote: Can't get connection!\n");
500 }
501}
502
503/* Static */
507{
510 char *localInName = NULL, *localOutName = NULL, *remoteInName = NULL,
511 *remoteOutName = NULL;
512
513 // Attempt to unpack the names from the buffer
515 &localInName, &localOutName,
516 &remoteInName, &remoteOutName)) {
517 fprintf(stderr, "vrpn_Auxiliary_Logger_Remote::handle_report_message: "
518 "Could not unpack buffer\n");
519 return -1;
520 }
521
522 // Fill in the data type for the callback handlers.
524 cs.msg_time = p.msg_time;
525 cs.local_in_logfile_name = localInName;
526 cs.local_out_logfile_name = localOutName;
527 cs.remote_in_logfile_name = remoteInName;
528 cs.remote_out_logfile_name = remoteOutName;
529
530 // Go down the list of callbacks that have been registered.
531 // Fill in the parameter and call each.
533
534 // Clean up memory and return.
535 if (localInName) {
536 try {
537 delete[] localInName;
538 } catch (...) {
539 fprintf(stderr, "vrpn_Auxiliary_Logger_Server_Generic::handle_report_message: delete failed\n");
540 return -1;
541 }
542 };
543 if (localOutName) {
544 try {
545 delete[] localOutName;
546 } catch (...) {
547 fprintf(stderr, "vrpn_Auxiliary_Logger_Server_Generic::handle_report_message: delete failed\n");
548 return -1;
549 }
550 };
551 if (remoteInName) {
552 try {
553 delete[] remoteInName;
554 } catch (...) {
555 fprintf(stderr, "vrpn_Auxiliary_Logger_Server_Generic::handle_report_message: delete failed\n");
556 return -1;
557 }
558 };
559 if (remoteOutName) {
560 try {
561 delete[] remoteOutName;
562 } catch (...) {
563 fprintf(stderr, "vrpn_Auxiliary_Logger_Server_Generic::handle_report_message: delete failed\n");
564 return -1;
565 }
566 };
567 return 0;
568}
static int VRPN_CALLBACK handle_report_message(void *userdata, vrpn_HANDLERPARAM p)
vrpn_Callback_List< vrpn_AUXLOGGERCB > d_callback_list
virtual void mainloop(void)
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
vrpn_Auxiliary_Logger_Remote(const char *name, vrpn_Connection *c=NULL)
vrpn_Auxiliary_Logger_Server_Generic(const char *logger_name, const char *connection_to_log, vrpn_Connection *c=NULL)
virtual void handle_request_logging(const char *local_in_logfile_name, const char *local_out_logfile_name, const char *remote_in_logfile_name, const char *remote_out_logfile_name)
static int VRPN_CALLBACK static_handle_request_logging(void *userdata, vrpn_HANDLERPARAM p)
static int VRPN_CALLBACK static_handle_request_logging_status(void *userdata, vrpn_HANDLERPARAM p)
static int VRPN_CALLBACK static_handle_dropped_last_connection(void *userdata, vrpn_HANDLERPARAM p)
virtual void handle_dropped_last_connection(void)
virtual void handle_request_logging_status()=0
virtual void handle_request_logging(const char *local_in_logfile_name, const char *local_out_logfile_name, const char *remote_in_logfile_name, const char *remote_out_logfile_name)=0
bool send_report_logging(const char *local_in_logfile_name, const char *local_out_logfile_name, const char *remote_in_logfile_name, const char *remote_out_logfile_name)
vrpn_Auxiliary_Logger_Server(const char *name, vrpn_Connection *c)
bool unpack_log_message_from_buffer(const char *buf, vrpn_int32 buflen, char **local_in_logfile_name, char **local_out_logfile_name, char **remote_in_logfile_name, char **remote_out_logfile_name)
bool pack_log_message_of_type(vrpn_int32 type, const char *local_in_logfile_name, const char *local_out_logfile_name, const char *remote_in_logfile_name, const char *remote_out_logfile_name)
vrpn_Auxiliary_Logger(const char *name, vrpn_Connection *c)
virtual int register_types(void)
Register the types of messages this device sends/receives. Return 0 on success, -1 on fail.
int register_autodeleted_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
Registers a handler with the connection, and remembers to delete at destruction.
vrpn_Connection * d_connection
Connection that this object talks to.
void client_mainloop(void)
Handles functions that all clients should provide in their mainloop() (warning of no server,...
vrpn_int32 d_sender_id
Sender ID registered with the connection.
int send_text_message(const char *msg, struct timeval timestamp, vrpn_TEXT_SEVERITY type=vrpn_TEXT_NORMAL, vrpn_uint32 level=0)
Sends a NULL-terminated text message from the device d_sender_id.
Class from which all user-level (and other) classes that communicate with vrpn_Connections should der...
virtual int init(void)
Initialize things that the constructor can't. Returns 0 on success, -1 on failure.
void call_handlers(const CALLBACK_STRUCT &info)
This will pass the referenced parameter as a const to all the callbacks.
Generic connection class not specific to the transport mechanism.
virtual vrpn_int32 register_message_type(const char *name)
void get_log_names(char **local_in_logname, char **local_out_logname, char **remote_in_logname, char **remote_out_logname)
This function returns the logfile names of this connection in the parameters. It will allocate memory...
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_bool doing_okay(void) const
Returns vrpn_true if the connection is okay, vrpn_false if not.
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...
const char * remote_out_logfile_name
const char * local_in_logfile_name
const char * local_out_logfile_name
const char * remote_in_logfile_name
This structure is what is passed to a vrpn_Connection message callback.
const char * buffer
struct timeval msg_time
@ vrpn_TEXT_ERROR
#define VRPN_CALLBACK
const char * vrpn_dropped_last_connection
vrpn_Connection * vrpn_get_connection_by_name(const char *cname, const char *local_in_logfile_name, const char *local_out_logfile_name, const char *remote_in_logfile_name, const char *remote_out_logfile_name, const char *NIC_IPaddress, bool force_connection)
Create a client connection of arbitrary type (VRPN UDP/TCP, TCP, File, Loopback, MPI).
const vrpn_uint32 vrpn_CONNECTION_RELIABLE
Classes of service for messages, specify multiple by ORing them together Priority of satisfying these...
const int vrpn_ANY_SENDER
vrpn_ANY_SENDER can be used to register callbacks on a given message type from any sender.
VRPN_API int vrpn_unbuffer(const char **buffer, timeval *t)
Utility routine for taking a struct timeval from a buffer that was sent as a message.
VRPN_API int vrpn_buffer(char **insertPt, vrpn_int32 *buflen, const timeval t)
Utility routine for placing a timeval struct into a buffer that is to be sent as a message.
#define vrpn_gettimeofday
Definition vrpn_Shared.h:99