17#if !(defined(_WIN32) && defined(VRPN_USE_WINSOCK_SOCKETS))
18#include <netinet/in.h>
54 if (x == -1) return -1
64 const char *local_in_logfile_name,
65 const char *local_out_logfile_name)
66 :
vrpn_Connection(local_in_logfile_name, local_out_logfile_name, NULL, NULL)
91 fprintf(stderr,
"vrpn_File_Connection::vrpn_File_Connection(): NULL "
92 "zeroeth endpoint\n");
94 connectionStatus = CONNECTED;
95 d_endpoints.front()->status = CONNECTED;
116 fprintf(stderr,
"vrpn_File_Connection: Out of memory!\n");
123 fprintf(stderr,
"vrpn_File_Connection: "
124 "Could not open file \"%s\".\n",
158 fprintf(stderr,
"vrpn_File_Connection: Can't read first message\n");
217 fprintf(stderr,
"vrpn_File_Connection::~vrpn_File_Connection: delete failed\n");
229 fprintf(stderr,
"vrpn_File_Connection::~vrpn_File_Connection: delete failed\n");
236 fprintf(stderr,
"vrpn_File_Connection::~vrpn_File_Connection: delete failed\n");
304 d_filetime_accum_since_last_playback.tv_sec = 0;
305 d_filetime_accum_since_last_playback.tv_usec = 0;
307 d_time_of_last_accum.tv_sec = 0;
308 d_time_of_last_accum.tv_usec = 0;
312 const timeval &now_time)
314 timeval &accum = d_filetime_accum_since_last_playback;
315 timeval &last_accum = d_time_of_last_accum;
322 now_time, d_time_of_last_accum),
324 last_accum = now_time;
328 vrpn_float32 new_rate)
334 d_replay_rate = new_rate;
339 const timeval &now_time)
343 d_filetime_accum_since_last_playback.tv_sec = 0;
344 d_filetime_accum_since_last_playback.tv_usec = 0;
345 d_time_of_last_accum = now_time;
440 const timeval end_time =
462 if (need_to_play_retval > 0) {
468 else if (need_to_play_retval == 0) {
589 vrpn_uint32 playback_this_iteration = 0;
605 playback_this_iteration++;
650 static const timeval tvMAX = {LONG_MAX, 999999L};
697 fprintf(stderr,
"Couldn't log \"incoming\" message during replay!\n");
705 if (header.
type >= 0) {
707 printf(
"vrpn_FC: Msg Sender (%s), Type (%s), at (%ld:%ld)\n",
708 endpoint->other_senders[header.
sender].name,
709 endpoint->other_types[header.
type].name, header.
msg_time.tv_sec,
725 fprintf(stderr,
"vrpn_File_Connection::playone_to_filename: "
726 "Nonzero system return.\n");
766 timeval len = {0, 0};
791 timeval high = {0, 0};
792 timeval low = {LONG_MAX, 999999L};
796 if (retval ==
false) {
798 printf(
"vrpn_File_Connection::find_superlative_user_times: didn't "
799 "successfully save bookmark.\n");
822 if (retval ==
false) {
824 fprintf(stderr,
"vrpn_File_Connection::find_superlative_user_times "
825 "messed up the location in the file stream.\n");
830 if (high.tv_sec != LONG_MIN)
837 fprintf( stderr,
"vrpn_File_Connection::find_superlative_user_times: did not find a highest-time user message\n"
841 if (low.tv_sec != LONG_MAX)
843 d_earliest_user_time = low;
844 d_earliest_user_time_valid = true;
848 fprintf( stderr,
"vrpn_File_Connection::find_superlative_user_times: did not find an earliest user message\n"
871 fprintf(stderr,
"vrpn_File_Connection::vrpn_FileBookmark::~vrpn_FileBookmark: delete failed\n");
878 fprintf(stderr,
"vrpn_File_Connection::vrpn_FileBookmark::~vrpn_FileBookmark: delete failed\n");
903 if (
d_bookmark.oldCurrentLogEntryCopy != NULL) {
904 if (
d_bookmark.oldCurrentLogEntryCopy->data.buffer != NULL) {
906 delete[](
d_bookmark.oldCurrentLogEntryCopy->data.buffer);
908 fprintf(stderr,
"vrpn_File_Connection::store_stream_bookmark: delete failed\n");
915 fprintf(stderr,
"vrpn_File_Connection::store_stream_bookmark: delete failed\n");
922 if (
d_bookmark.oldCurrentLogEntryCopy == NULL) {
925 fprintf(stderr,
"Out of memory error: "
926 "vrpn_File_Connection::store_stream_"
932 d_bookmark.oldCurrentLogEntryCopy->prev = NULL;
933 d_bookmark.oldCurrentLogEntryCopy->data.buffer = NULL;
937 d_bookmark.oldCurrentLogEntryCopy->data.type =
939 d_bookmark.oldCurrentLogEntryCopy->data.sender =
941 d_bookmark.oldCurrentLogEntryCopy->data.msg_time =
943 d_bookmark.oldCurrentLogEntryCopy->data.payload_len =
945 if (
d_bookmark.oldCurrentLogEntryCopy->data.buffer != NULL) {
947 delete[]
d_bookmark.oldCurrentLogEntryCopy->data.buffer;
949 fprintf(stderr,
"vrpn_File_Connection::store_stream_bookmark: delete failed\n");
953 try {
d_bookmark.oldCurrentLogEntryCopy->data.buffer =
959 memcpy(
const_cast<char *
>(
d_bookmark.oldCurrentLogEntryCopy->data.buffer),
984 if (
d_bookmark.oldCurrentLogEntryCopy == NULL) {
991 char *newBuffer = NULL;
993 new char[
d_bookmark.oldCurrentLogEntryCopy->data.payload_len]; }
1002 catch (...) {
return false; }
1008 d_bookmark.oldCurrentLogEntryCopy->data.type;
1010 d_bookmark.oldCurrentLogEntryCopy->data.sender;
1012 d_bookmark.oldCurrentLogEntryCopy->data.msg_time;
1014 d_bookmark.oldCurrentLogEntryCopy->data.payload_len;
1018 d_bookmark.oldCurrentLogEntryCopy->data.buffer,
1024 fprintf(stderr,
"vrpn_File_Connection::return_to_bookmark: delete failed\n");
1031 return (retval == 0);
1073 fprintf(stderr,
"vrpn_File_Connection::read_cookie: "
1074 "No cookie. If you're sure this is a logfile, "
1075 "run add_vrpn_cookie on it and try again.\n");
1087 fprintf(stderr,
"vrpn_File_Connection::read_cookie: "
1088 "No endpoints[0]. Internal failure.\n");
1104 fprintf(stderr,
"vrpn_File_Connection::read_entry: Out of memory.\n");
1113 fprintf(stderr,
"vrpn_File_Connection::read_entry: no open file\n");
1119 fprintf(stderr,
"vrpn_File_Connection::read_entry: delete failed\n");
1134 vrpn_int32 values[6];
1135 retval = fread(values,
sizeof(vrpn_int32), 6,
d_file);
1144 fprintf(stderr,
"vrpn_File_Connection::read_entry: delete failed\n");
1150 header.
type = ntohl(values[0]);
1151 header.
sender = ntohl(values[1]);
1152 header.
msg_time.tv_sec = ntohl(values[2]);
1153 header.
msg_time.tv_usec = ntohl(values[3]);
1163 fprintf(stderr,
"vrpn_File_Connection::read_entry: "
1164 "Out of memory.\n");
1186 newEntry->
next = NULL;
1209 fprintf(stderr,
"vrpn_File_Connection::read_entry: delete failed\n");
1216 fprintf(stderr,
"vrpn_File_Connection::read_entry: delete failed\n");
1226 newEntry->
next = NULL;
1227 newEntry->
prev = NULL;
1284 const char *bufPtr = p.
buffer;
1307 newtime.tv_sec = ((
const vrpn_int32 *)(p.
buffer))[0];
1308 newtime.tv_usec = ((
const vrpn_int32 *)(p.
buffer))[1];
void addConnection(vrpn_Connection *, const char *name)
NB implementation is not particularly efficient; we expect to have O(10) connections,...
void deleteConnection(vrpn_Connection *)
static vrpn_ConnectionManager & instance(void)
The only way to get access to an instance of this class. Guarantees that there is only one,...
vrpn_Connection(const char *local_in_logfile_name, const char *local_out_logfile_name, vrpn_EndpointAllocator epa=allocateEndpoint)
Constructor for server connection. This cannot be called directly any more because vrpn_Connection is...
virtual int do_callbacks_for(vrpn_int32 type, vrpn_int32 sender, struct timeval time, vrpn_uint32 len, const char *buffer)
int doSystemCallbacksFor(vrpn_HANDLERPARAM, void *)
virtual vrpn_int32 register_message_type(const char *name)
vrpn::EndpointContainer d_endpoints
Sockets used to talk to remote Connection(s) and other information needed on a per-connection basis.
vrpn_uint32 get_Jane_value(void)
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...
int connectionStatus
Status of the connection.
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...
Encapsulation of the data and methods for a single generic connection to take care of one part of man...
int local_type_id(vrpn_int32 remote_type) const
Returns the local mapping for the remote type (-1 if none).
int local_sender_id(vrpn_int32 remote_sender) const
Returns the local mapping for the remote sender (-1 if none).
void reset_at_time(const timeval &now_time)
void set_replay_rate(vrpn_float32 new_rate)
void accumulate_to(const timeval &now_time)
vrpn_LOGLIST * oldCurrentLogEntryPtr
vrpn_LOGLIST * oldCurrentLogEntryCopy
virtual int read_cookie(void)
virtual int mainloop(const timeval *timeout=NULL)
bool return_to_bookmark()
virtual int time_since_connection_open(timeval *elapsed_time)
Returns the time since the connection opened. Some subclasses may redefine time.
virtual int close_file(void)
vrpn_int32 d_controllerId
timeval d_highest_user_time
int playone_to_filetime(timeval end_filetime)
void play_to_user_message()
int jump_to_time(vrpn_float64 newtime)
virtual vrpn_File_Connection * get_File_Connection(void)
vrpn_File_Connection implements this as "return this" so it can be used to detect a File_Connection a...
vrpn_bool d_earliest_user_time_valid
int play_to_time(vrpn_float64 end_time)
virtual ~vrpn_File_Connection(void)
int need_to_play(timeval filetime)
int jump_to_filetime(timeval absolute_time)
vrpn_LOGLIST * d_currentLogEntry
static int VRPN_CALLBACK handle_reset(void *, vrpn_HANDLERPARAM)
static int VRPN_CALLBACK handle_set_replay_rate(void *, vrpn_HANDLERPARAM)
virtual int advance_currentLogEntry(void)
virtual int send_pending_reports(void)
send pending report, clear the buffer. This function was protected, now is public,...
vrpn_int32 d_play_to_time_type
vrpn_File_Connection(const char *station_name, const char *local_in_logfile_name=NULL, const char *local_out_logfile_name=NULL)
int play_to_filetime(const timeval end_filetime)
FileTime_Accumulator d_filetime_accum
timeval get_lowest_user_timestamp()
static int VRPN_CALLBACK handle_play_to_time(void *, vrpn_HANDLERPARAM)
timeval d_earliest_user_time
virtual int read_entry(void)
timeval get_highest_user_timestamp()
vrpn_int32 d_set_replay_rate_type
const char * get_filename()
vrpn_FileBookmark d_bookmark
bool store_stream_bookmark()
vrpn_LOGLIST * d_startEntry
vrpn_bool d_highest_user_time_valid
void find_superlative_user_times()
void set_replay_rate(vrpn_float32 rate)
int logIncomingMessage(size_t payloadLen, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer)
Should be called with the timeval adjusted by the clock offset on the receiving Endpoint.
This structure is what is passed to a vrpn_Connection message callback.
Placed here so vrpn_FileConnection can use it too.
size_t vrpn_cookie_size(void)
Returns the size of the magic cookie buffer, plus any alignment overhead.
char * vrpn_copy_file_name(const char *filespecifier)
Utility routines to parse file specifiers FROM service locations.
int check_vrpn_file_cookie(const char *buffer)
const vrpn_int32 vrpn_CONNECTION_UDP_DESCRIPTION
bool vrpn_FILE_CONNECTIONS_SHOULD_ACCUMULATE
bool vrpn_FILE_CONNECTIONS_SHOULD_SKIP_TO_USER_MESSAGES
bool vrpn_FILE_CONNECTIONS_SHOULD_PRELOAD
VRPN_API bool vrpn_FILE_CONNECTIONS_SHOULD_PRELOAD
VRPN_API bool vrpn_FILE_CONNECTIONS_SHOULD_ACCUMULATE
VRPN_API bool vrpn_FILE_CONNECTIONS_SHOULD_SKIP_TO_USER_MESSAGES
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.
bool vrpn_TimevalGreater(const timeval &tv1, const timeval &tv2)
timeval vrpn_TimevalScale(const timeval &tv, double scale)
double vrpn_TimevalMsecs(const timeval &tv)
timeval vrpn_TimevalDiff(const timeval &tv1, const timeval &tv2)
timeval vrpn_MsecsTimeval(const double dMsecs)
timeval vrpn_TimevalSum(const timeval &tv1, const timeval &tv2)
#define vrpn_gettimeofday