30static size_t MAX_SIZE_T = (size_t)(-1);
32#ifdef VRPN_USE_WINSOCK_SOCKETS
35#define vrpn_closeSocket closesocket
39#define vrpn_socket_error WSAGetLastError()
40static std::string WSA_number_to_string(
int err)
43 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
44 FORMAT_MESSAGE_IGNORE_INSERTS,
45 NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
51#define vrpn_socket_error_to_chars(x) (WSA_number_to_string(x)).c_str()
52#define vrpn_EINTR WSAEINTR
57#define vrpn_closeSocket close
59#define vrpn_socket_error errno
60#define vrpn_socket_error_to_chars(x) strerror(x)
61#define vrpn_EINTR EINTR
64#include <netinet/in.h>
65#include <sys/socket.h>
85#include <arpa/nameser.h>
89#ifndef VRPN_USE_WINSOCK_SOCKETS
92#include <netinet/tcp.h>
97#ifdef VRPN_USE_WINSOCK_SOCKETS
98#define SOCK_CAST (char *)
101#define SOCK_CAST (const char *)
107#if defined(_AIX) || defined(__APPLE__) || defined(ANDROID) || defined(__linux)
108#define GSN_CAST (socklen_t *)
111#define GSN_CAST (unsigned int *)
121int gethostname(
char *,
int);
135#ifndef VRPN_USE_WINSOCK_SOCKETS
136#define INVALID_SOCKET -1
141#pragma warning(disable : 4127)
217 "VRPN_Connection_Dropped_Last_Connection";
225#define getdtablesize() MAXFUPLIM
229#define getdtablesize() MAXFUPLIM
238#define RSH "/app/bin/ssh"
240#define RSH "/app/bin/rsh"
245#define UDP_CALL_TIMEOUT (2)
246#define UDP_CALL_RETRIES (5)
252#define SERVCOUNT (20)
253#define SERVWAIT (120 / SERVCOUNT)
258#define vrpn_CONNECTION_MAX_XLATION_TABLE_SIZE 2000
306struct cRemoteMapping {
308 vrpn_int32 remote_id;
316 ~vrpn_TranslationTable(
void);
320 vrpn_int32 numEntries(
void)
const;
321 vrpn_int32 mapToLocalID(vrpn_int32 remote_id)
const;
328 vrpn_int32 addRemoteEntry(
cName name, vrpn_int32 remote_id,
329 vrpn_int32 local_id);
334 vrpn_bool addLocalID(
const char *name, vrpn_int32 local_id);
339 vrpn_int32 d_numEntries;
343vrpn_TranslationTable::vrpn_TranslationTable(
void)
349 d_entry[i].name = NULL;
350 d_entry[i].remote_id = -1;
351 d_entry[i].local_id = -1;
355vrpn_TranslationTable::~vrpn_TranslationTable(
void) { clear(); }
357vrpn_int32 vrpn_TranslationTable::numEntries(
void)
const
362vrpn_int32 vrpn_TranslationTable::mapToLocalID(vrpn_int32 remote_id)
const
364 if ((remote_id < 0) || (remote_id > d_numEntries)) {
368 fprintf(stderr,
"vrpn_TranslationTable::mapToLocalID: "
369 "Remote ID %d is illegal!\n",
377 fprintf(stderr,
"Remote ID %d maps to local ID %d (%s).\n", remote_id,
378 d_entry[remote_id].local_id, d_entry[remote_id].name);
381 return d_entry[remote_id].local_id;
384vrpn_int32 vrpn_TranslationTable::addRemoteEntry(
cName name,
385 vrpn_int32 remote_id,
390 useEntry = remote_id;
393 fprintf(stderr,
"vrpn_TranslationTable::addRemoteEntry: "
394 "Too many entries in table (%d).\n",
405 if (!d_entry[useEntry].name) {
406 try { d_entry[useEntry].name =
new char[
sizeof(
cName)]; }
408 fprintf(stderr,
"vrpn_TranslationTable::addRemoteEntry: "
414 memcpy(d_entry[useEntry].name, name,
sizeof(
cName));
415 d_entry[useEntry].remote_id = remote_id;
416 d_entry[useEntry].local_id = local_id;
419 fprintf(stderr,
"Set up remote ID %d named %s with local equivalent %d.\n",
420 remote_id, name, local_id);
423 if (d_numEntries <= useEntry) {
424 d_numEntries = useEntry + 1;
430vrpn_bool vrpn_TranslationTable::addLocalID(
const char *name,
435 for (i = 0; i < d_numEntries; i++) {
436 if (d_entry[i].name && !strcmp(d_entry[i].name, name)) {
437 d_entry[i].local_id = local_id;
444void vrpn_TranslationTable::clear(
void)
448 for (i = 0; i < d_numEntries; i++) {
449 if (d_entry[i].name) {
451 delete[] d_entry[i].name;
453 fprintf(stderr,
"vrpn_TranslationTable::clear: delete failed\n");
456 d_entry[i].name = NULL;
458 d_entry[i].local_id = -1;
459 d_entry[i].remote_id = -1;
465 : d_logFileName(NULL)
470 , d_magicCookie(NULL)
471 , d_wroteMagicCookie(vrpn_FALSE)
485 fprintf(stderr,
"vrpn_Log: Out of memory.\n");
504 fprintf(stderr,
"vrpn_Log::~vrpn_Log: delete failed\n");
515 fprintf(stderr,
"vrpn_Log::~vrpn_Log: delete failed\n");
539 fprintf(stderr,
"vrpn_Log::open: Log file has no name.\n");
543 fprintf(stderr,
"vrpn_Log::open: Log file is already open.\n");
551 fprintf(stderr,
"vrpn_Log::open: "
552 "Log file \"%s\" already exists.\n",
560 fprintf(stderr,
"vrpn_Log::open: "
561 "Couldn't open log file \"%s\": ",
569 d_file = fopen(
"/tmp/vrpn_emergency_log",
"r");
573 perror(
"vrpn_Log::open_log: "
574 "Emergency log file \"/tmp/vrpn_emergency_log\" "
575 "already exists.\n");
578 d_file = fopen(
"/tmp/vrpn_emergency_log",
"wb");
580 perror(
"vrpn_Log::open: "
581 "Couldn't open emergency log file "
582 "\"/tmp/vrpn_emergency_log\": ");
590 fprintf(stderr,
"Writing to /tmp/vrpn_emergency_log instead.\n");
599 int final_retval = 0;
603 fprintf(stderr,
"vrpn_Log::close: "
604 "close of log file failed!\n");
613 fprintf(stderr,
"vrpn_Log::close: delete failed\n");
626 int final_retval = 0;
634 fprintf(stderr,
"vrpn_Log::saveLogSoFar: "
635 "Log file is not open!\n");
656 fprintf(stderr,
"vrpn_Log::saveLogSoFar: "
657 "Couldn't write magic cookie to log file "
658 "(got %d, expected %d).\n",
659 static_cast<int>(retval),
679 vrpn_int32 values[6];
681 memcpy(&(values[0]), &lp->
data.
type,
sizeof(vrpn_int32));
682 memcpy(&(values[1]), &lp->
data.
sender,
sizeof(vrpn_int32));
683 memcpy(&(values[2]), &lp->
data.
msg_time.tv_sec,
sizeof(vrpn_int32));
684 memcpy(&(values[3]), &lp->
data.
msg_time.tv_usec,
sizeof(vrpn_int32));
686 memcpy(&(values[5]), &zero,
sizeof(vrpn_int32));
687 retval = fwrite(values,
sizeof(vrpn_int32), 6,
d_file);
691 "vrpn_Log::saveLogSoFar: "
692 "Couldn't write log file (got %d, expected %lud).\n",
693 static_cast<int>(retval),
694 static_cast<unsigned long>(
sizeof(lp->
data)));
707 if (retval !=
static_cast<size_t>(host_len)) {
708 fprintf(stderr,
"vrpn_Log::saveLogSoFar: "
709 "Couldn't write log file.\n");
723 fprintf(stderr,
"vrpn_Log::saveLogSoFar: delete failed\n");
730 fprintf(stderr,
"vrpn_Log::saveLogSoFar: delete failed\n");
742 vrpn_int32 type, vrpn_int32 sender,
752 return logMessage(
static_cast<vrpn_int32
>(payloadLen), time, type,
753 sender, buffer, vrpn_TRUE);
761 vrpn_int32 type, vrpn_int32 sender,
766 return logMessage(payloadLen, time, type, sender, buffer);
773 vrpn_int32 type, vrpn_int32 sender,
const char *buffer,
777 vrpn_int32 effectiveType;
778 vrpn_int32 effectiveSender;
781 effectiveType =
d_types->mapToLocalID(type);
782 effectiveSender =
d_senders->mapToLocalID(sender);
785 effectiveType = type;
786 effectiveSender = sender;
791 if (
checkFilters(payloadLen, time, effectiveType, effectiveSender,
802 fprintf(stderr,
"vrpn_Log::logMessage: "
818 if (payloadLen > 0) {
819 try { lp->
data.
buffer =
new char[payloadLen]; }
821 fprintf(stderr,
"vrpn_Log::logMessage: "
823 try {
delete lp; }
catch (...) {};
828 memcpy(
const_cast<char *
>(lp->
data.
buffer), buffer, payloadLen);
851 std::vector<char> newName;
852 newName.assign(strlen(name) + 100 + 1, 0);
859 dot = strrchr(name,
'.');
861 strncpy(newName.data(), name, dot - name);
864 newName.assign(name, name + strlen(name));
866 len = strlen(newName.data());
867 sprintf(newName.data() + len,
"-%d", index);
869 strcat(newName.data(), dot);
872 return setName(newName.data());
883 fprintf(stderr,
"vrpn_Log::setName: delete failed\n");
904 fprintf(stderr,
"vrpn_Log::setCookie: delete failed\n");
910 fprintf(stderr,
"vrpn_Log::setCookie: Out of memory.\n");
927 fprintf(stderr,
"vrpn_Log::addFilter: Out of memory.\n");
931 newEntry->
filter = filter;
942 vrpn_int32 type, vrpn_int32 sender,
976 ~vrpn_TypeDispatcher(
void);
980 int numTypes(
void)
const;
981 const char *typeName(
int which)
const;
983 vrpn_int32 getTypeID(
const char *name);
986 int numSenders(
void)
const;
987 const char *senderName(
int which)
const;
989 vrpn_int32 getSenderID(
const char *name);
994 vrpn_int32 addType(
const char *name);
995 vrpn_int32 addSender(
const char *name);
997 vrpn_int32 registerType(
const char *name);
1002 vrpn_int32 registerSender(
const char *name);
1010 void *userdata, vrpn_int32 sender);
1017 int doCallbacksFor(vrpn_int32 type, vrpn_int32 sender, timeval time,
1018 vrpn_uint32 len,
const char *buffer);
1019 int doSystemCallbacksFor(vrpn_int32 type, vrpn_int32 sender, timeval time,
1020 vrpn_uint32 len,
const char *buffer,
1027 struct vrpnLocalMapping {
1044vrpn_TypeDispatcher::vrpn_TypeDispatcher(
void)
1047 , d_genericCallbacks(NULL)
1059vrpn_TypeDispatcher::~vrpn_TypeDispatcher(
void)
1064 for (i = 0; i < d_numTypes; i++) {
1065 pVMCB = d_types[i].who_cares;
1068 pVMCB = pVMCB_Del->
next;
1072 fprintf(stderr,
"vrpn_TypeDispatcher::~vrpn_TypeDispatcher: delete failed\n");
1078 pVMCB = d_genericCallbacks;
1082 pVMCB = pVMCB_Del->
next;
1086 fprintf(stderr,
"vrpn_TypeDispatcher::~vrpn_TypeDispatcher: delete failed\n");
1095int vrpn_TypeDispatcher::numTypes(
void)
const {
return d_numTypes; }
1097const char *vrpn_TypeDispatcher::typeName(
int i)
const
1099 if ((i < 0) || (i >= d_numTypes)) {
1102 return d_types[i].name;
1105vrpn_int32 vrpn_TypeDispatcher::getTypeID(
const char *name)
1109 for (i = 0; i < d_numTypes; i++) {
1110 if (!strcmp(name, d_types[i].name)) {
1118int vrpn_TypeDispatcher::numSenders(
void)
const {
return d_numSenders; }
1120const char *vrpn_TypeDispatcher::senderName(
int i)
const
1122 if ((i < 0) || (i >= d_numSenders)) {
1125 return d_senders[i];
1128vrpn_int32 vrpn_TypeDispatcher::getSenderID(
const char *name)
1132 for (i = 0; i < d_numSenders; i++) {
1133 if (!strcmp(name, d_senders[i])) {
1141vrpn_int32 vrpn_TypeDispatcher::addType(
const char *name)
1146 fprintf(stderr,
"vrpn_TypeDispatcher::addType: "
1154 d_types[d_numTypes].who_cares = NULL;
1155 d_types[d_numTypes].cCares = 0;
1158 return d_numTypes - 1;
1161vrpn_int32 vrpn_TypeDispatcher::addSender(
const char *name)
1166 fprintf(stderr,
"vrpn_TypeDispatcher::addSender: "
1167 "Too many! (%d).\n",
1172 if (!d_senders[d_numSenders]) {
1176 try { d_senders[d_numSenders] =
new char[
sizeof(
cName)]; }
1178 fprintf(stderr,
"vrpn_TypeDispatcher::addSender: "
1179 "Can't allocate memory for new record\n");
1185 strncpy(d_senders[d_numSenders], name,
sizeof(
cName) - 1);
1186 d_senders[d_numSenders][
sizeof(
cName) - 1] =
'\0';
1190 return d_numSenders - 1;
1193vrpn_int32 vrpn_TypeDispatcher::registerType(
const char *name)
1198 retval = getTypeID(name);
1203 return addType(name);
1206vrpn_int32 vrpn_TypeDispatcher::registerSender(
const char *name)
1211 retval = getSenderID(name);
1216 return addSender(name);
1219int vrpn_TypeDispatcher::addHandler(vrpn_int32 type,
1228 if (((type < 0) || (type >= d_numTypes)) && (type !=
vrpn_ANY_TYPE)) {
1229 fprintf(stderr,
"vrpn_TypeDispatcher::addHandler: No such type\n");
1235 ((sender < 0) || (sender >= d_numSenders))) {
1236 fprintf(stderr,
"vrpn_TypeDispatcher::addHandler: No such sender\n");
1241 if (handler == NULL) {
1242 fprintf(stderr,
"vrpn_TypeDispatcher::addHandler: NULL handler\n");
1251 new_entry->
sender = sender;
1253 fprintf(stderr,
"vrpn_TypeDispatcher::addHandler: Out of memory\n");
1258 printf(
"Adding user handler for type %ld, sender %ld\n", type, sender);
1267 ptr = &d_genericCallbacks;
1270 ptr = &d_types[type].who_cares;
1274 ptr = &((*ptr)->next);
1277 new_entry->
next = NULL;
1282int vrpn_TypeDispatcher::removeHandler(vrpn_int32 type,
1284 void *userdata, vrpn_int32 sender)
1291 if (((type < 0) || (type >= d_numTypes)) && (type !=
vrpn_ANY_TYPE)) {
1292 fprintf(stderr,
"vrpn_TypeDispatcher::removeHandler: No such type\n");
1299 snitch = &d_genericCallbacks;
1302 snitch = &(d_types[type].who_cares);
1305 while ((victim != NULL) &&
1307 (victim->
sender != sender))) {
1308 snitch = &((*snitch)->next);
1309 victim = victim->
next;
1313 if (victim == NULL) {
1315 "vrpn_TypeDispatcher::removeHandler: No such handler\n");
1320 *snitch = victim->
next;
1324 fprintf(stderr,
"vrpn_TypeDispatcher::removeHandler: delete failed\n");
1331void vrpn_TypeDispatcher::setSystemHandler(vrpn_int32 type,
1334 d_systemMessages[-type] = handler;
1337int vrpn_TypeDispatcher::doCallbacksFor(vrpn_int32 type, vrpn_int32 sender,
1338 timeval time, vrpn_uint32 len,
1349 if (type >= d_numTypes) {
1361 who = d_genericCallbacks;
1367 fprintf(stderr,
"vrpn_TypeDispatcher::doCallbacksFor: "
1368 "Nonzero user generic handler return.\n");
1378 who = d_types[type].who_cares;
1383 fprintf(stderr,
"vrpn_TypeDispatcher::doCallbacksFor: "
1384 "Nonzero user handler return.\n");
1396int vrpn_TypeDispatcher::doSystemCallbacksFor(vrpn_int32 type,
1397 vrpn_int32 sender, timeval time,
1408 fprintf(stderr,
"vrpn_TypeDispatcher::doSystemCallbacksFor: "
1409 "Illegal type %d.\n",
1414 if (!d_systemMessages[-type]) {
1425 return doSystemCallbacksFor(p, userdata);
1437 fprintf(stderr,
"vrpn_TypeDispatcher::doSystemCallbacksFor: "
1438 "Illegal type %d.\n",
1443 if (!d_systemMessages[-p.
type]) {
1447 retval = d_systemMessages[-p.
type](userdata, p);
1449 fprintf(stderr,
"vrpn_TypeDispatcher::doSystemCallbacksFor: "
1450 "Nonzero system handler return.\n");
1456void vrpn_TypeDispatcher::clear(
void)
1461 d_types[i].who_cares = NULL;
1462 d_types[i].cCares = 0;
1464 d_systemMessages[i] = NULL;
1468 if (d_senders[i] != NULL) {
1470 delete[] d_senders[i];
1472 fprintf(stderr,
"vrpn_TypeDispatcher::clear: delete failed\n");
1476 d_senders[i] = NULL;
1495 fprintf(stderr,
"vrpn_ConnectionManager::~vrpn_ConnectionManager: delete failed\n");
1500 while (d_anonList) {
1506 fprintf(stderr,
"vrpn_ConnectionManager::~vrpn_ConnectionManager: delete failed\n");
1532 p =
new knownConnection;
1542 p->next = d_anonList;
1558 knownConnection **snitch)
1562 knownConnection *victim = *snitch;
1564 while (victim && (victim->connection != c)) {
1565 snitch = &((*snitch)->next);
1573 *snitch = victim->
next;
1577 fprintf(stderr,
"vrpn_ConnectionManager::deleteConnection: delete failed\n");
1588 for (p = d_kcList; p && strcmp(p->name, name); p = p->next) {
1594 return p->connection;
1597vrpn_ConnectionManager::vrpn_ConnectionManager(
void)
1615static int vrpn_getmyIP(
char *myIPchar,
unsigned maxlen,
1616 const char *NIC_IP = NULL,
1620 struct hostent *host;
1621 char myIPstring[100];
1623 if (myIPchar == NULL) {
1624 fprintf(stderr,
"vrpn_getmyIP: NULL pointer passed in\n");
1630 if (strlen(NIC_IP) > maxlen) {
1631 fprintf(stderr,
"vrpn_getmyIP: Name too long to return\n");
1635 fprintf(stderr,
"Was given IP address of %s so returning that.\n",
1638 strncpy(myIPchar, NIC_IP, maxlen);
1639 myIPchar[maxlen - 1] =
'\0';
1646 struct sockaddr_in socket_name;
1647 int socket_namelen =
sizeof(socket_name);
1649 if (getsockname(incoming_socket, (
struct sockaddr *)&socket_name,
1651 fprintf(stderr,
"vrpn_getmyIP: cannot get socket name.\n");
1655 sprintf(myIPstring,
"%u.%u.%u.%u",
1656 ntohl(socket_name.sin_addr.s_addr) >> 24,
1657 (ntohl(socket_name.sin_addr.s_addr) >> 16) & 0xff,
1658 (ntohl(socket_name.sin_addr.s_addr) >> 8) & 0xff,
1659 ntohl(socket_name.sin_addr.s_addr) & 0xff);
1662 if ((
unsigned)strlen(myIPstring) > maxlen) {
1663 fprintf(stderr,
"vrpn_getmyIP: Name too long to return\n");
1667 strcpy(myIPchar, myIPstring);
1670 fprintf(stderr,
"Decided on IP address of %s.\n", myIPchar);
1678 if (gethostname(myname,
sizeof(myname))) {
1679 fprintf(stderr,
"vrpn_getmyIP: Error finding local hostname\n");
1684 host = gethostbyname(myname);
1686 fprintf(stderr,
"vrpn_getmyIP: error finding host by name (%s)\n",
1693 if (host->h_length != 4) {
1694 fprintf(stderr,
"vrpn_getmyIP: Host length not 4\n");
1698 sprintf(myIPstring,
"%u.%u.%u.%u",
1699 (
unsigned int)(
unsigned char)host->h_addr_list[0][0],
1700 (
unsigned int)(
unsigned char)host->h_addr_list[0][1],
1701 (
unsigned int)(
unsigned char)host->h_addr_list[0][2],
1702 (
unsigned int)(
unsigned char)host->h_addr_list[0][3]);
1705 if ((
unsigned)strlen(myIPstring) > maxlen) {
1706 fprintf(stderr,
"vrpn_getmyIP: Name too long to return\n");
1710 strcpy(myIPchar, myIPstring);
1712 fprintf(stderr,
"Decided on IP address of %s.\n", myIPchar);
1724 fd_set *exceptfds,
struct timeval *timeout)
1726 fd_set tmpread, tmpwrite, tmpexcept;
1729 struct timeval timeout2;
1730 struct timeval *timeout2ptr;
1731 struct timeval start, stop, now;
1738 if ((timeout != NULL) &&
1739 ((timeout->tv_sec != 0) || (timeout->tv_usec != 0))) {
1740 timeout2 = *timeout;
1741 timeout2ptr = &timeout2;
1746 timeout2ptr = timeout;
1755 if (readfds != NULL) {
1761 if (writefds != NULL) {
1762 tmpwrite = *writefds;
1767 if (exceptfds != NULL) {
1768 tmpexcept = *exceptfds;
1771 FD_ZERO(&tmpexcept);
1775 ret = select(width, &tmpread, &tmpwrite, &tmpexcept, timeout2ptr);
1782 else if ((timeout != NULL) &&
1783 ((timeout->tv_sec != 0) || (timeout->tv_usec != 0))) {
1791 unsigned long usec_left;
1792 usec_left = (stop.tv_sec - now.tv_sec) * 1000000L;
1793 usec_left += stop.tv_usec - now.tv_usec;
1794 timeout2.tv_sec = usec_left / 1000000L;
1795 timeout2.tv_usec = usec_left % 1000000L;
1801 if (readfds != NULL) {
1804 if (writefds != NULL) {
1805 *writefds = tmpwrite;
1807 if (exceptfds != NULL) {
1808 *exceptfds = tmpexcept;
1827#ifndef VRPN_USE_WINSOCK_SOCKETS
1836 ret = write(outfile, buffer + sofar, length - sofar);
1845 }
while ((ret > 0) && (
static_cast<size_t>(sofar) < length));
1847 if (ret == -1)
return (-1);
1848 if (ret == 0)
return (0);
1879 ret = read(infile, buffer + sofar, length - sofar);
1887 }
while ((ret > 0) && (
static_cast<size_t>(sofar) < length));
1889 if (ret == -1)
return (-1);
1890 if (ret == 0)
return (0);
1904 send(outsock, buffer + sofar,
static_cast<int>(length - sofar), 0);
1906 if (nwritten == SOCKET_ERROR) {
1911 }
while (sofar < length);
1913 return static_cast<int>(sofar);
1932 recv(insock, buffer + sofar,
static_cast<int>(length - sofar), 0);
1934 if (nread == SOCKET_ERROR) {
1942 }
while (sofar < length);
1944 return static_cast<int>(sofar);
1962 struct timeval *timeout)
1965 struct timeval timeout2;
1966 struct timeval *timeout2ptr;
1967 struct timeval start, stop, now;
1982 if ((timeout != NULL) &&
1983 ((timeout->tv_sec != 0) || (timeout->tv_usec != 0))) {
1984 timeout2 = *timeout;
1985 timeout2ptr = &timeout2;
1990 timeout2ptr = timeout;
1996 fd_set readfds, exceptfds;
2000 FD_SET(infile, &readfds);
2001 FD_ZERO(&exceptfds);
2002 FD_SET(infile, &exceptfds);
2004 NULL, &exceptfds, timeout2ptr);
2005 if (sel_ret == -1) {
2008 if (FD_ISSET(infile, &exceptfds)) {
2011 if (!FD_ISSET(infile, &readfds)) {
2012 if ((timeout != NULL) && (timeout->tv_sec == 0) &&
2013 (timeout->tv_usec == 0)) {
2014 return static_cast<int>(sofar);
2022 return static_cast<int>(sofar);
2029 if (!FD_ISSET(infile, &readfds)) {
2034#ifndef VRPN_USE_WINSOCK_SOCKETS
2035 ret = read(infile, buffer + sofar, length - sofar);
2045 int nread = recv(infile, buffer + sofar,
2046 static_cast<int>(length - sofar), 0);
2052 }
while ((ret > 0) && (sofar < length));
2053#ifndef VRPN_USE_WINSOCK_SOCKETS
2054 if (ret == -1)
return (-1);
2056 if (ret == 0)
return (0);
2058 return static_cast<int>(sofar);
2071static SOCKET open_socket(
int type,
unsigned short *portno,
2072 const char *IPaddress)
2074 struct sockaddr_in name;
2075 struct hostent *phe;
2079 SOCKET sock = socket(AF_INET, type, 0);
2081 fprintf(stderr,
"open_socket: can't open socket.\n");
2091 vrpn_int32 optval = 1;
2092 vrpn_int32 sockoptsuccess =
2093 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval,
sizeof optval);
2098 namelen =
sizeof(name);
2101 memset((
void *)&name, 0, namelen);
2102 name.sin_family = AF_INET;
2104 name.sin_port = htons(*portno);
2107 name.sin_port = htons(0);
2112 name.sin_addr.s_addr = INADDR_ANY;
2114 else if ((name.sin_addr.s_addr = inet_addr(IPaddress)) == INADDR_NONE) {
2115 if ((phe = gethostbyname(IPaddress)) != NULL) {
2116 memcpy((
void *)&name.sin_addr, (
const void *)phe->h_addr,
2121 fprintf(stderr,
"open_socket: can't get %s host entry\n",
2129 fprintf(stderr,
"open_socket: request port %d, using NIC %d %d %d %d.\n",
2130 portno ? *portno : 0, ntohl(name.sin_addr.s_addr) >> 24,
2131 (ntohl(name.sin_addr.s_addr) >> 16) & 0xff,
2132 (ntohl(name.sin_addr.s_addr) >> 8) & 0xff,
2133 ntohl(name.sin_addr.s_addr) & 0xff);
2136 if (bind(sock, (
struct sockaddr *)&name, namelen) < 0) {
2137 fprintf(stderr,
"open_socket: can't bind address");
2139 fprintf(stderr,
" %d", *portno);
2145 fprintf(stderr,
" (This probably means that another application has "
2146 "the port open already)\n");
2152 if (getsockname(sock, (
struct sockaddr *)&name,
GSN_CAST & namelen)) {
2153 fprintf(stderr,
"vrpn: open_socket: cannot get socket name.\n");
2158 *portno = ntohs(name.sin_port);
2163 fprintf(stderr,
"open_socket: got port %d, using NIC %d %d %d %d.\n",
2164 portno ? *portno : ntohs(name.sin_port),
2165 ntohl(name.sin_addr.s_addr) >> 24,
2166 (ntohl(name.sin_addr.s_addr) >> 16) & 0xff,
2167 (ntohl(name.sin_addr.s_addr) >> 8) & 0xff,
2168 ntohl(name.sin_addr.s_addr) & 0xff);
2178static SOCKET open_udp_socket(
unsigned short *portno,
const char *IPaddress)
2180 return open_socket(SOCK_DGRAM, portno, IPaddress);
2187static SOCKET open_tcp_socket(
unsigned short *portno = NULL,
2188 const char *NIC_IP = NULL)
2190 return open_socket(SOCK_STREAM, portno, NIC_IP);
2197static SOCKET vrpn_connect_udp_port(
const char *machineName,
int remotePort,
2198 const char *NIC_IP = NULL)
2201 struct sockaddr_in udp_name;
2202 struct hostent *remoteHost;
2205 udp_socket = open_udp_socket(NULL, NIC_IP);
2207 udp_namelen =
sizeof(udp_name);
2209 memset((
void *)&udp_name, 0, udp_namelen);
2210 udp_name.sin_family = AF_INET;
2218 if ((udp_name.sin_addr.s_addr = inet_addr(machineName)) == INADDR_NONE) {
2219 remoteHost = gethostbyname(machineName);
2224 u_long foo_mark = 0L;
2225 for (i = 0; i < 4; i++) {
2226 u_long one_char = remoteHost->h_addr_list[0][i];
2227 foo_mark = (foo_mark << 8) | one_char;
2229 udp_name.sin_addr.s_addr = foo_mark;
2231 memcpy(&(udp_name.sin_addr.s_addr), remoteHost->h_addr,
2232 remoteHost->h_length);
2238 "vrpn_connect_udp_port: error finding host by name (%s).\n",
2243#ifndef VRPN_USE_WINSOCK_SOCKETS
2244 udp_name.sin_port = htons(remotePort);
2246 udp_name.sin_port = htons((u_short)remotePort);
2249 if (connect(udp_socket, (
struct sockaddr *)&udp_name, udp_namelen)) {
2250 fprintf(stderr,
"vrpn_connect_udp_port: can't bind udp socket.\n");
2256 udp_namelen =
sizeof(udp_name);
2257 if (getsockname(udp_socket, (
struct sockaddr *)&udp_name,
2259 fprintf(stderr,
"vrpn_connect_udp_port: cannot get socket name.\n");
2267 "vrpn_connect_udp_port: got port %d, using NIC %d %d %d %d.\n",
2268 ntohs(udp_name.sin_port), ntohl(udp_name.sin_addr.s_addr) >> 24,
2269 (ntohl(udp_name.sin_addr.s_addr) >> 16) & 0xff,
2270 (ntohl(udp_name.sin_addr.s_addr) >> 8) & 0xff,
2271 ntohl(udp_name.sin_addr.s_addr) & 0xff);
2300static int get_local_socket_name(
char *local_host,
size_t max_length,
2301 const char *remote_host)
2304 struct sockaddr_in udp_name;
2305 int udp_namelen =
sizeof(udp_name);
2307 SOCKET udp_socket = vrpn_connect_udp_port(remote_host, remote_port, NULL);
2310 "get_local_socket_name: cannot connect_udp_port to %s.\n",
2312 fprintf(stderr,
" (returning 0.0.0.0 so we listen on all ports).\n");
2313 udp_name.sin_addr.s_addr = 0;
2316 if (getsockname(udp_socket, (
struct sockaddr *)&udp_name,
2318 fprintf(stderr,
"get_local_socket_name: cannot get socket name.\n");
2325 char myIPstring[100];
2326 int ret = sprintf(myIPstring,
"%d.%d.%d.%d",
2327 ntohl(udp_name.sin_addr.s_addr) >> 24,
2328 (ntohl(udp_name.sin_addr.s_addr) >> 16) & 0xff,
2329 (ntohl(udp_name.sin_addr.s_addr) >> 8) & 0xff,
2330 ntohl(udp_name.sin_addr.s_addr) & 0xff);
2333 if ((
unsigned)strlen(myIPstring) > max_length) {
2334 fprintf(stderr,
"get_local_socket_name: Name too long to return\n");
2339 strcpy(local_host, myIPstring);
2364 const int local_port,
2365 const char *NIC_IP = NULL)
2378 if (vrpn_getmyIP(myIPchar,
sizeof(myIPchar), NIC_IP, udp_sock)) {
2380 "vrpn_udp_request_lob_packet: Error finding local hostIP\n");
2384 sprintf(msg,
"%s %d", myIPchar, local_port);
2385 msglen =
static_cast<vrpn_int32
>(strlen(msg) +
2389 if (send(udp_sock, msg, msglen, 0) == -1) {
2390 perror(
"vrpn_udp_request_lob_packet: send() failed");
2408static int vrpn_get_a_TCP_socket(
SOCKET *listen_sock,
int *listen_portnum,
2409 const char *NIC_IP = NULL)
2411 struct sockaddr_in listen_name;
2414 listen_namelen =
sizeof(listen_name);
2419 *listen_sock = open_tcp_socket(NULL, NIC_IP);
2420 if (*listen_sock < 0) {
2421 fprintf(stderr,
"vrpn_get_a_TCP_socket: socket didn't open.\n");
2425 if (listen(*listen_sock, 1)) {
2426 fprintf(stderr,
"vrpn_get_a_TCP_socket: listen() failed.\n");
2431 if (getsockname(*listen_sock, (
struct sockaddr *)&listen_name,
2433 fprintf(stderr,
"vrpn_get_a_TCP_socket: cannot get socket name.\n");
2438 *listen_portnum = ntohs(listen_name.sin_port);
2458static int vrpn_poll_for_accept(
SOCKET listen_sock,
SOCKET *accept_sock,
2459 double timeout = 0.0)
2466 FD_SET(listen_sock, &rfds);
2467 t.tv_sec = (long)(timeout);
2468 t.tv_usec = (long)((timeout - t.tv_sec) * 1000000L);
2471 perror(
"vrpn_poll_for_accept: select() failed");
2474 if (FD_ISSET(listen_sock, &rfds)) {
2477 if ((*accept_sock = accept(listen_sock, 0, 0)) == -1) {
2478 perror(
"vrpn_poll_for_accept: accept() failed");
2481#if !defined(_WIN32_WCE) && !defined(__ANDROID__)
2483 struct protoent *p_entry;
2486 if ((p_entry = getprotobyname(
"TCP")) == NULL) {
2488 "vrpn_poll_for_accept: getprotobyname() failed.\n");
2493 if (setsockopt(*accept_sock, p_entry->p_proto, TCP_NODELAY,
2494 SOCK_CAST & nonzero,
sizeof(nonzero)) == -1) {
2495 perror(
"vrpn_poll_for_accept: setsockopt() failed");
2520static int vrpn_start_server(
const char *machine,
char *server_name,
char *args,
2521 const char *IPaddress = NULL)
2524 #include <TargetConditionals.h>
2525 #if TARGET_IPHONE_SIMULATOR
2528 #elif TARGET_OS_IPHONE
2533#if defined(VRPN_USE_WINSOCK_SOCKETS) || defined(__CYGWIN__) || defined(NO_SYSTEM)
2534 fprintf(stderr,
"VRPN: vrpn_start_server not ported"
2535 " for windows winsock or cygwin!\n");
2536 IPaddress = IPaddress;
2538 server_name = server_name;
2548 if (vrpn_get_a_TCP_socket(&server_sock, &PortNum, IPaddress)) {
2549 fprintf(stderr,
"vrpn_start_server: Cannot get listen socket\n");
2553 if ((pid = fork()) == -1) {
2554 fprintf(stderr,
"vrpn_start_server: cannot fork().\n");
2561 int num_descriptors;
2564 const char *rsh_to_use;
2566 if (vrpn_getmyIP(myIPchar,
sizeof(myIPchar), IPaddress, server_sock)) {
2567 fprintf(stderr,
"vrpn_start_server: Error finding my IP\n");
2574#if defined(__ANDROID__)
2578 num_descriptors = sysconf(_SC_OPEN_MAX);
2580 num_descriptors = getdtablesize();
2583 for (loop = 0; loop < num_descriptors; loop++) {
2584 if ((loop != 1) && (loop != 2)) {
2593 if ((rsh_to_use = (
char *)getenv(
"VRPN_RSH")) == NULL) {
2596 sprintf(command,
"%s %s %s %s -client %s %d", rsh_to_use, machine,
2597 server_name, args, myIPchar, PortNum);
2598 ret = system(command);
2599 if ((ret == 127) || (ret == -1)) {
2600 fprintf(stderr,
"vrpn_start_server: system() failed !!!!!\n");
2602 fprintf(stderr,
"Attempted command was: '%s'\n", command);
2618 for (waitloop = 0; waitloop < (
SERVCOUNT); waitloop++) {
2624 ret = vrpn_poll_for_accept(server_sock, &child_socket,
SERVWAIT);
2626 fprintf(stderr,
"vrpn_start_server: Accept poll failed\n");
2635 deadkid = waitpid(-1, &status, WNOHANG);
2636 if (deadkid == pid) {
2637 fprintf(stderr,
"vrpn_start_server: server process exited\n");
2644 "vrpn_start_server: server failed to connect in time\n");
2645 fprintf(stderr,
" (took more than %d seconds)\n",
2654 return (child_socket);
2679 static_cast<char>(remote_log_mode +
'0'));
2701 bp = strrchr(buffer,
'.');
2704 fprintf(stderr,
"check_vrpn_cookie: "
2705 "bad cookie (wanted '%s', got '%s'\n",
2712 "check_vrpn_cookie(): "
2713 "VRPN Note: minor version number doesn't match: (prefer '%s', "
2714 "got '%s'). This is not normally a problem.\n",
2738 bp = strrchr(buffer,
'.');
2739 int majorComparison = strncmp(
2741 if (majorComparison > 0 ||
2744 fprintf(stderr,
"check_vrpn_file_cookie: "
2745 "bad cookie (wanted >='%s' and <='%s', "
2752 fprintf(stderr,
"check_vrpn_file_cookie(): "
2753 "Note: Version number doesn't match: (prefer '%s', got "
2754 "'%s'). This is not normally a problem.\n",
2763 vrpn_int32 *connectedEndpointCounter)
2765 , d_remoteLogMode(0)
2766 , d_remoteInLogName(NULL)
2767 , d_remoteOutLogName(NULL)
2772 , d_dispatcher(dispatcher)
2773 , d_connectionCounter(connectedEndpointCounter)
2779 vrpn_int32 *connectedEndpointCounter)
2783 , d_tcpListenPort(0)
2785 , d_remote_machine_name(NULL)
2786 , d_remote_port_number(0)
2787 , d_tcp_only(vrpn_FALSE)
2796 , d_tcpSequenceNumber(0)
2797 , d_udpSequenceNumber(0)
2798 , d_tcpInbuf((char *)d_tcpAlignedInbuf)
2799 , d_udpInbuf((char *)d_udpAlignedInbuf)
2800 , d_NICaddress(NULL)
2817 fprintf(stderr,
"vrpn_Endpoint::~vrpn_Endpoint: delete failed\n");
2825 fprintf(stderr,
"vrpn_Endpoint::~vrpn_Endpoint: delete failed\n");
2836 fprintf(stderr,
"vrpn_Endpoint::~vrpn_Endpoint: delete failed\n");
2845 fprintf(stderr,
"vrpn_Endpoint::~vrpn_Endpoint: delete failed\n");
2855 fprintf(stderr,
"vrpn_Endpoint::~vrpn_Endpoint: delete failed\n");
2863 fprintf(stderr,
"vrpn_Endpoint::~vrpn_Endpoint: delete failed\n");
2900 fprintf(stderr,
"vrpn_Endpoint_IP::~vrpn_Endpoint_IP: delete failed\n");
2909 fprintf(stderr,
"vrpn_Endpoint_IP::~vrpn_Endpoint_IP: delete failed\n");
2920 fprintf(stderr,
"vrpn_Endpoint_IP::~vrpn_Endpoint_IP: delete failed\n");
2934 return d_types->mapToLocalID(remote_type);
2939 return d_senders->mapToLocalID(remote_sender);
2963 fprintf(stderr,
"vrpn_Endpoint::init: Out of memory!\n");
2985 fd_set readfds, exceptfds;
2986 int tcp_messages_read;
2987 int udp_messages_read;
2989 bool time_to_try_again =
false;
3003 FD_ZERO(&exceptfds);
3021 fprintf(stderr,
"vrpn_Endpoint::mainloop: select failed.\n");
3034 fprintf(stderr,
"vrpn_Endpoint::mainloop: Exception on socket\n");
3043 if (udp_messages_read == -1) {
3044 fprintf(stderr,
"vrpn_Endpoint::mainloop: "
3045 "UDP handling failed, dropping connection\n");
3050 if (udp_messages_read != 0)
3051 printf(
"udp message read = %d\n", udp_messages_read);
3058 if (tcp_messages_read == -1) {
3059 fprintf(stderr,
"vrpn: TCP handling failed, dropping "
3060 "connection (this is normal when a connection "
3067 if (tcp_messages_read) {
3068 printf(
"tcp_message_read %d bytes\n", tcp_messages_read);
3086 printf(
"TRYING_TO_CONNECT\n");
3093 time_to_try_again =
true;
3099 if (time_to_try_again) {
3105 fprintf(stderr,
"vrpn_Endpoint::mainloop: "
3106 "Can't set up new connection!\n");
3118 fprintf(stderr,
"vrpn_Endpoint: mainloop: Bad listen socket\n");
3124 fprintf(stderr,
"vrpn_Endpoint: mainloop: Can't poll for accept\n");
3131 printf(
"vrpn: Connection established\n");
3136 fprintf(stderr,
"vrpn_Endpoint: mainloop: "
3137 "Can't set up new connection!\n");
3149 if (time_to_try_again) {
3166 "vrpn_Endpoint: mainloop: Can't lob UDP request\n");
3182 fprintf(stderr,
"vrpn_Endpoint::mainloop(): "
3183 "Unknown status (%d)\n",
3207 return d_senders->addLocalID(name, which);
3216 return d_types->addLocalID(name, which);
3221 vrpn_int32 local_id)
3223 return d_types->addRemoteEntry(type_name, remote_id, local_id);
3228 vrpn_int32 local_id)
3230 return d_senders->addRemoteEntry(sender_name, remote_id, local_id);
3249 vrpn_int32 type, vrpn_int32 sender,
3251 vrpn_uint32 class_of_service)
3264 fprintf(stderr,
"vrpn_Endpoint::pack_message: "
3265 "Couldn't log outgoing message.!\n");
3277 fprintf(stderr,
"vrpn_Endpoint::pack_message: "
3278 "Not connected, so throwing out message.\n");
3313 return (!ret) ? -1 : 0;
3318 vrpn_int32 ret, sent = 0;
3337 "vrpn_Endpoint::send_pending_reports(): No TCP connection\n");
3346 timeout.tv_usec = 0;
3353 NULL, &f, &timeout);
3355 fprintf(stderr,
"vrpn_Endpoint::send_pending_reports(): "
3356 "select() failed.\n");
3373 printf(
"TCP Sent %d bytes\n", ret);
3376 fprintf(stderr,
"vrpn_Endpoint::send_pending_reports: "
3377 "TCP send failed.\n");
3393 printf(
"UDP Sent %d bytes\n", ret);
3396 fprintf(stderr,
"vrpn_Endpoint::send_pending_reports: "
3397 " UDP send failed.");
3417 vrpn_uint32 portparam = portno;
3418 char myIPchar[1000];
3422 fprintf(stderr,
"Getting IP address of NIC %s.\n",
d_NICaddress);
3431 perror(
"vrpn_Endpoint::pack_udp_description: can't get host name");
3441 fprintf(stderr,
"vrpn_Endpoint::pack_udp_description: "
3442 "Packing UDP %s:%d\n",
3447 return pack_message(
static_cast<vrpn_uint32
>(strlen(myIPchar)) + 1, now,
3458 const char *inName =
"";
3459 const char *outName =
"";
3474 2 *
sizeof(vrpn_int32) + strlen(inName) + 1 + strlen(outName) + 1;
3476 try { buf =
new char[bufsize]; }
3477 catch (...) {
return -1; }
3487 vrpn_int32 bufleft =
static_cast<vrpn_int32
>(bufsize);
3488 vrpn_buffer(bp, &bufleft, (vrpn_int32)strlen(inName));
3489 vrpn_buffer(bp, &bufleft, (vrpn_int32)strlen(outName));
3490 vrpn_buffer(bp, &bufleft, inName,
static_cast<vrpn_int32
>(strlen(inName)));
3493 static_cast<vrpn_int32
>(strlen(outName)));
3495 int ret =
pack_message(
static_cast<vrpn_uint32
>(bufsize - bufleft), now,
3501 fprintf(stderr,
"vrpn_Endpoint::pack_log_description: delete failed\n");
3513 timeval localTimeout;
3514 fd_set readfds, exceptfds;
3515 unsigned num_messages_read = 0;
3520 printf(
"vrpn_Endpoint::handle_tcp_messages() called\n");
3524 localTimeout.tv_sec = timeout->tv_sec;
3525 localTimeout.tv_usec = timeout->tv_usec;
3528 localTimeout.tv_sec = 0;
3529 localTimeout.tv_usec = 0;
3542 FD_ZERO(&exceptfds);
3546 NULL, &exceptfds, &localTimeout);
3547 if (sel_ret == -1) {
3548 fprintf(stderr,
"vrpn_Endpoint::handle_tcp_messages: "
3555 fprintf(stderr,
"vrpn_Endpoint::handle_tcp_messages: "
3556 "Exception on socket\n");
3569 num_messages_read++;
3581 return num_messages_read;
3598 timeval localTimeout;
3599 fd_set readfds, exceptfds;
3600 unsigned num_messages_read = 0;
3605 printf(
"vrpn_Endpoint::handle_udp_messages() called\n");
3609 localTimeout.tv_sec = timeout->tv_sec;
3610 localTimeout.tv_usec = timeout->tv_usec;
3613 localTimeout.tv_sec = 0;
3614 localTimeout.tv_usec = 0;
3626 FD_ZERO(&exceptfds);
3630 &readfds, NULL, &exceptfds, &localTimeout);
3631 if (sel_ret == -1) {
3632 perror(
"vrpn_Endpoint::handle_udp_messages: select failed()");
3638 fprintf(stderr,
"vrpn: vrpn_Endpoint::handle_udp_messages: "
3639 "Exception on socket\n");
3651 if (inbuf_len == -1) {
3652 fprintf(stderr,
"vrpn_Endpoint::handle_udp_message: "
3653 "recv() failed.\n");
3662 inbuf_len -= retval;
3663 inbuf_ptr += retval;
3667 num_messages_read++;
3681 return num_messages_read;
3696 if (sscanf(msg,
"%s %d", machine, &port) != 2) {
3705 struct sockaddr_in client;
3706 struct hostent *host;
3711 fprintf(stderr,
"vrpn_Endpoint::connect_tcp_to: "
3712 "can't open socket\n");
3715 client.sin_family = AF_INET;
3723 if ((client.sin_addr.s_addr = inet_addr(addr)) == INADDR_NONE) {
3724 host = gethostbyname(addr);
3730 u_long foo_mark = 0;
3731 for (i = 0; i < 4; i++) {
3732 u_long one_char = host->h_addr_list[0][i];
3733 foo_mark = (foo_mark << 8) | one_char;
3735 client.sin_addr.s_addr = foo_mark;
3738 memcpy(&(client.sin_addr.s_addr), host->h_addr, host->h_length);
3743#if !defined(hpux) && !defined(__hpux) && !defined(_WIN32) && !defined(sparc)
3744 herror(
"gethostbyname error:");
3746 perror(
"gethostbyname error:");
3748 fprintf(stderr,
"vrpn_Endpoint::connect_tcp_to: "
3749 "error finding host by name (%s)\n",
3755#ifndef VRPN_USE_WINSOCK_SOCKETS
3756 client.sin_port = htons(port);
3758 client.sin_port = htons((u_short)port);
3761 if (connect(
d_tcpSocket, (
struct sockaddr *)&client,
sizeof(client)) < 0) {
3762#ifdef VRPN_USE_WINSOCK_SOCKETS
3764 fprintf(stderr,
"vrpn_Endpoint::connect_tcp_to: Could not connect "
3765 "to machine %d.%d.%d.%d port %d\n",
3766 (
int)(client.sin_addr.S_un.S_un_b.s_b1),
3767 (
int)(client.sin_addr.S_un.S_un_b.s_b2),
3768 (
int)(client.sin_addr.S_un.S_un_b.s_b3),
3769 (
int)(client.sin_addr.S_un.S_un_b.s_b4),
3770 (
int)(ntohs(client.sin_port)));
3771 int error = WSAGetLastError();
3772 fprintf(stderr,
"Winsock error: %d\n", error);
3775 fprintf(stderr,
"vrpn_Endpoint::connect_tcp_to: Could not connect to "
3776 "machine %d.%d.%d.%d port %d\n",
3777 (
int)((client.sin_addr.s_addr >> 24) & 0xff),
3778 (
int)((client.sin_addr.s_addr >> 16) & 0xff),
3779 (
int)((client.sin_addr.s_addr >> 8) & 0xff),
3780 (
int)((client.sin_addr.s_addr >> 0) & 0xff),
3781 (
int)(ntohs(client.sin_port)));
3789#if !defined(_WIN32_WCE) && !defined(__ANDROID__)
3791 struct protoent *p_entry;
3794 if ((p_entry = getprotobyname(
"TCP")) == NULL) {
3797 "vrpn_Endpoint::connect_tcp_to: getprotobyname() failed.\n");
3803 if (setsockopt(
d_tcpSocket, p_entry->p_proto, TCP_NODELAY,
3804 SOCK_CAST & nonzero,
sizeof(nonzero)) == -1) {
3805 perror(
"vrpn_Endpoint::connect_tcp_to: setsockopt() failed");
3822 fprintf(stderr,
"vrpn_Endpoint::connect_udp_to: "
3823 "Couldn't open outbound UDP link.\n");
3873 fprintf(stderr,
"vrpn_Endpoint::drop_connection: Can't log\n");
3888 (*d_connectionCounter)--;
3914 fprintf(stderr,
"vrpn_Endpoint_IP::setNICaddress: delete failed\n");
3921 fprintf(stderr,
"Setting endpoint NIC address to %s.\n", address);
3929 fprintf(stderr,
"vrpn_Endpoint::setNICaddress: Out of memory.\n");
3943 memset(sendbuf, 0,
sizeof(sendbuf));
3946 perror(
"vrpn_Endpoint::setup_new_connection: "
3947 "Internal error - array too small. The code's broken.");
3954 fprintf(stderr,
"vrpn_Endpoint::setup_new_connection: "
3955 "Can't write cookie.\n");
3971 timeout = *pTimeout;
3975 timeout.tv_usec = 0;
3978 fd_set readfds, exceptfds;
3987 FD_ZERO(&exceptfds);
3997 &exceptfds, &timeout) == -1) {
3998 fprintf(stderr,
"vrpn_Endpoint::poll_for_cookie(): select failed.\n");
4006 "vrpn_Endpoint::poll_for_cookie(): Exception on socket\n");
4015 "vrpn_Endpoint::poll_for_cookie: cookie handling failed\n"
4016 " while connecting to \"%s\"\n",
4022 printf(
"vrpn_Endpoint::poll_for_cookie() got cookie\n");
4034 memset(recvbuf, 0,
sizeof(recvbuf));
4038 if (ret != sendlen) {
4039 perror(
"vrpn_Endpoint::finish_new_connection_setup: Can't read cookie");
4060 if ((received_logmode < 0) ||
4062 fprintf(stderr,
"vrpn_Endpoint::finish_new_connection_setup: "
4063 "Got invalid log mode %d\n",
4064 static_cast<int>(received_logmode));
4080 fprintf(stderr,
"vrpn_Endpoint::finish_new_connection_setup: "
4081 "Can't pack remote logging instructions.\n");
4094 unsigned short udp_portnum =
4095 static_cast<unsigned short>(INADDR_ANY);
4098 fprintf(stderr,
"vrpn_Endpoint::finish_new_connection_setup: "
4099 "can't open UDP socket\n");
4106 fprintf(stderr,
"vrpn_Endpoint::finish_new_connection_setup: "
4107 "Can't pack UDP msg\n");
4116 "CONNECTED - vrpn_Endpoint::finish_new_connection_setup.\n");
4133 "vrpn_Endpoint::finish_new_connection_setup: Can't send UDP msg\n");
4158 (*d_connectionCounter)++;
4166 vrpn_int32 header[5];
4167 struct timeval time;
4168 vrpn_int32 sender, type;
4169 size_t len, payload_len, ceil_len;
4173 fprintf(stderr,
"vrpn_Endpoint::getOneTCPMessage(): something to read\n");
4179 fprintf(stderr,
"vrpn_Endpoint::getOneTCPMessage: "
4180 "Can't read header (this is normal when a connection "
4184 len = ntohl(header[0]);
4185 time.tv_sec = ntohl(header[1]);
4186 time.tv_usec = ntohl(header[2]);
4187 sender = ntohl(header[3]);
4188 type = ntohl(header[4]);
4190 fprintf(stderr,
" header: Len %d, Sender %d, Type %d\n", (
int)len,
4191 (
int)sender, (
int)type);
4195 vrpn_int32 header_len =
sizeof(header);
4199 if (header_len >
static_cast<vrpn_int32
>(
sizeof(header))) {
4203 header_len -
sizeof(header)) !=
4204 (int)(header_len -
sizeof(header))) {
4205 fprintf(stderr,
"vrpn_Endpoint::getOneTCPMessage: "
4206 "Can't read header + alignment\n");
4214 payload_len = len - header_len;
4215 ceil_len = payload_len;
4222 if (buflen < ceil_len) {
4224 "vrpn: vrpn_Endpoint::getOneTCPMessage: Message too long\n");
4231 perror(
"vrpn: vrpn_Endpoint::getOneTCPMessage: Can't read body");
4236 fprintf(stderr,
"Couldn't log incoming message.!\n");
4240 retval =
dispatch(type, sender, time,
static_cast<vrpn_uint32
>(payload_len),
4251 vrpn_int32 header[5];
4252 struct timeval time;
4253 vrpn_int32 sender, type;
4254 vrpn_uint32 len, payload_len, ceil_len;
4259 vrpn_uint32 header_len =
sizeof(header);
4264 if (header_len > (vrpn_uint32)inbuf_len) {
4265 fprintf(stderr,
"vrpn_Endpoint::getOneUDPMessage: Can't read header");
4268 memcpy(header, inbuf_ptr,
sizeof(header));
4269 inbuf_ptr += header_len;
4270 len = ntohl(header[0]);
4271 time.tv_sec = ntohl(header[1]);
4272 time.tv_usec = ntohl(header[2]);
4273 sender = ntohl(header[3]);
4274 type = ntohl(header[4]);
4277 fprintf(stderr,
"Message type %ld (local type %ld), sender %ld received\n",
4279 fprintf(stderr,
"Message length is %d (buffer length %d).\n", len,
4286 payload_len = len - header_len;
4287 ceil_len = payload_len;
4293 if (header_len + ceil_len > (vrpn_uint32)inbuf_len) {
4294 fprintf(stderr,
"vrpn_Endpoint::getOneUDPMessage: Can't read payload");
4300 fprintf(stderr,
"Couldn't log incoming message.!\n");
4304 retval =
dispatch(type, sender, time, payload_len, inbuf_ptr);
4309 return ceil_len + header_len;
4313 vrpn_uint32 payload_len,
char *bufptr)
4325 payload_len, bufptr)) {
4332 if (
d_dispatcher->doSystemCallbacksFor(type, sender, time, payload_len,
4334 fprintf(stderr,
"vrpn_Endpoint::dispatch: "
4335 "Nonzero system return\n");
4344 vrpn_int32 &numOut, vrpn_uint32 len,
4345 timeval time, vrpn_int32 type,
4346 vrpn_int32 sender,
const char *buffer,
4347 vrpn_uint32 sequenceNumber)
4352 buffer, sequenceNumber);
4362 sender, buffer, sequenceNumber);
4380 vrpn_uint32 outbuf_size,
4381 vrpn_uint32 initial_out,
4383 struct timeval time,
4389 vrpn_uint32 ceil_len, header_len, total_len;
4390 vrpn_uint32 curr_out = initial_out;
4401 header_len = 5 *
sizeof(vrpn_int32);
4405 total_len = header_len + ceil_len;
4406 if ((curr_out + total_len) > (vrpn_uint32)outbuf_size) {
4420 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(header_len + len);
4421 curr_out +=
sizeof(vrpn_uint32);
4425 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(time.tv_sec);
4426 curr_out +=
sizeof(vrpn_uint32);
4427 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(time.tv_usec);
4428 curr_out +=
sizeof(vrpn_uint32);
4431 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(sender);
4432 curr_out +=
sizeof(vrpn_uint32);
4433 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(type);
4434 curr_out +=
sizeof(vrpn_uint32);
4442 *(vrpn_uint32 *)(
void *)(&outbuf[curr_out]) = htonl(seqNo);
4443 curr_out +=
sizeof(vrpn_uint32);
4446 curr_out = initial_out + header_len;
4451 if (buffer != NULL) {
4452 memcpy(&outbuf[curr_out], buffer, len);
4454 curr_out += ceil_len;
4456 printf(
"Marshalled: len %d, ceil_len %d: '", len, ceil_len);
4459 return curr_out - initial_out;
4468 vrpn_int32 local_id;
4471 fprintf(stderr,
"vrpn: vrpn_Endpoint::handle_type_message: "
4472 "Type name too long\n");
4477 strncpy(type_name, p.
buffer +
sizeof(vrpn_int32),
4482 i = ntohl(*((
const vrpn_int32 *)p.
buffer));
4483 type_name[i] =
'\0';
4486 printf(
"Registering other-side type: '%s'\n", type_name);
4489 local_id = endpoint->
d_dispatcher->getTypeID(type_name);
4491 if (local_id == -1) {
4497 printf(
"vrpn_Endpoint::handle_type_message: NULL d_parent "
4498 "when trying to auto-register remote message type %s.\n",
4504 fprintf(stderr,
"vrpn: Failed to add remote type %s\n", type_name);
4513 if (inName != NULL) {
4516 if (outName != NULL) {
4540 vrpn_int32 local_id;
4543 fprintf(stderr,
"vrpn: vrpn_Endpoint::handle_sender_message():Sender "
4549 strncpy(sender_name, p.
buffer +
sizeof(vrpn_int32),
4554 i = ntohl(*((
const vrpn_int32 *)p.
buffer));
4555 sender_name[i] =
'\0';
4558 printf(
"Registering other-side sender: '%s'\n", sender_name);
4561 local_id = endpoint->
d_dispatcher->getSenderID(sender_name);
4563 if (local_id == -1) {
4569 printf(
"vrpn_Endpoint::handle_sender_message: NULL d_parent "
4570 "when trying to auto-register remote message sender %s\n",
4576 fprintf(stderr,
"vrpn: Failed to add remote sender %s\n", sender_name);
4589 static_cast<vrpn_int32
>(strlen(
d_dispatcher->typeName(which)) + 1);
4591 char buffer[
sizeof(len) +
sizeof(
cName)];
4593 netlen = htonl(len);
4600 printf(
" vrpn_Connection: Packing type '%s', %d\n",
4603 memcpy(buffer, &netlen,
sizeof(netlen));
4604 memcpy(&buffer[
sizeof(len)],
d_dispatcher->typeName(which),
4608 return pack_message((vrpn_uint32)(len +
sizeof(len)), now,
4619 static_cast<vrpn_int32
>(strlen(
d_dispatcher->senderName(which)) + 1);
4621 char buffer[
sizeof(len) +
sizeof(
cName)];
4623 netlen = htonl(len);
4630 printf(
" vrpn_Connection: Packing sender '%s'\n",
4633 memcpy(buffer, &netlen,
sizeof(netlen));
4634 memcpy(&buffer[
sizeof(len)],
d_dispatcher->senderName(which),
4638 return pack_message((vrpn_uint32)(len +
sizeof(len)), now,
4643static int flush_udp_socket(
SOCKET fd)
4645 timeval localTimeout;
4646 fd_set readfds, exceptfds;
4652 localTimeout.tv_sec = 0;
4653 localTimeout.tv_usec = 0;
4661 FD_ZERO(&exceptfds);
4662 FD_SET(fd, &readfds);
4663 FD_SET(fd, &exceptfds);
4665 &exceptfds, &localTimeout);
4666 if (sel_ret == -1) {
4667 fprintf(stderr,
"flush_udp_socket: select failed().");
4672 if (FD_ISSET(fd, &exceptfds)) {
4673 fprintf(stderr,
"flush_udp_socket: Exception on socket.\n");
4678 if (FD_ISSET(fd, &readfds)) {
4681 inbuf_len = recv(fd, buf, 10000, 0);
4682 if (inbuf_len == -1) {
4683 fprintf(stderr,
"flush_udp_socket: recv() failed.\n");
4698 int retval = it->pack_type_description(which);
4711 int retval = it->pack_sender_description(which);
4725 vrpn_int32 inNameLen, outNameLen;
4726 const char **bp = &p.
buffer;
4735 endpoint->
setLogNames(inNameLen == 0 ? NULL : *bp,
4736 outNameLen == 0 ? NULL : *bp + inNameLen + 1);
4737 if (inNameLen > 0) retval = endpoint->
d_inLog->
open();
4738 if (outNameLen > 0) retval = endpoint->
d_outLog->
open();
4753 fprintf(stderr,
"vrpn_Connection::handle_log_message: "
4754 "Remote connection requested logging.\n");
4773 vrpn_int32 type, vrpn_int32 sender,
4775 vrpn_uint32 class_of_service)
4779 printf(
"vrpn_Connection::pack_message: Can't pack because the "
4780 "connection is broken\n");
4786 printf(
"vrpn_Connection::pack_message: bad type (%d)\n", type);
4792 if ((sender < 0) || (sender >=
d_dispatcher->numSenders())) {
4793 printf(
"vrpn_Connection::pack_message: bad sender (%d)\n", sender);
4805 if (it->pack_message(len, time, type, sender, buffer,
4806 class_of_service) != 0) {
4867 it->d_inLog->addFilter(filter, userdata);
4868 it->d_outLog->addFilter(filter, userdata);
4876 int final_retval = 0;
4879 final_retval |= it->d_inLog->saveLogSoFar();
4880 final_retval |= it->d_outLog->saveLogSoFar();
4882 return final_retval;
4950 const char *local_out_logfile_name,
4952 : d_numConnectedEndpoints(0)
4954 , d_autoDeleteStatus(false)
4955 , d_dispatcher(NULL)
4956 , d_serverLogCount(0)
4960 , d_serverLogName(NULL)
4961 , d_updateEndpoint(vrpn_FALSE)
4964 vrpn_Connection::init(epa);
4970 if (local_out_logfile_name) {
4974 fprintf(stderr,
"vrpn_Connection::vrpn_Connection:%d "
4975 "Couldn't create endpoint for log file.\n",
4986 fprintf(stderr,
"vrpn_Connection::vrpn_Connection:%d "
4987 "Couldn't open outgoing log file.\n",
5000 if (local_in_logfile_name) {
5012 const char *local_out_logfile_name,
5013 const char *remote_in_logfile_name,
5014 const char *remote_out_logfile_name,
5016 : connectionStatus(
BROKEN)
5017 , d_numConnectedEndpoints(0)
5019 , d_autoDeleteStatus(false)
5020 , d_dispatcher(NULL)
5021 , d_serverLogCount(0)
5023 , d_serverLogName(NULL)
5024 , d_updateEndpoint(vrpn_FALSE)
5029 vrpn_Connection::init(epa);
5034 fprintf(stderr,
"vrpn_Connection:%d Out of memory.\n", __LINE__);
5043 (((remote_in_logfile_name && strlen(remote_in_logfile_name) > 0)
5046 ((remote_out_logfile_name && strlen(remote_out_logfile_name) > 0)
5049 if (!remote_in_logfile_name) {
5054 new char[strlen(remote_in_logfile_name) + 1];
5062 if (!remote_out_logfile_name) {
5067 new char[strlen(remote_out_logfile_name) + 1];
5078 if (local_in_logfile_name && (strlen(local_in_logfile_name) != 0)) {
5083 fprintf(stderr,
"vrpn_Connection::vrpn_Connection:%d "
5084 "Couldn't open incoming log file.\n",
5091 if (local_out_logfile_name && (strlen(local_out_logfile_name) != 0)) {
5096 fprintf(stderr,
"vrpn_Connection::vrpn_Connection:%d "
5097 "Couldn't open local outgoing log file.\n",
5119 fprintf(stderr,
"vrpn_Connection::~vrpn_Connection: delete failed\n");
5125 if (d_references > 0) {
5127 "vrpn_Connection::~vrpn_Connection: "
5128 "Connection was deleted while %d references still remain.\n",
5144 if (d_references == 0 && d_autoDeleteStatus ==
true) {
5148 fprintf(stderr,
"vrpn_Connection::removeReference: delete failed\n");
5151 }
else if (d_references < 0) {
5153 fprintf(stderr,
"vrpn_Connection::removeReference: "
5154 "Negative reference count. This shouldn't happen.");
5162 fprintf(stderr,
"vrpn_Connection::register_sender: "
5163 "%d senders; new name \"%s\"\n",
5171 fprintf(stderr,
"Sender already defined as id %d.\n", retval);
5179 fprintf(stderr,
"Packing sender description for %s, type %d.\n", name,
5192 it->newLocalSender(name, retval);
5203 fprintf(stderr,
"vrpn_Connection::register_message_type: "
5204 "%d type; new name \"%s\"\n",
5212 fprintf(stderr,
"Type already defined as id %d.\n", retval);
5224 fprintf(stderr,
"Packing type description for %s, type %d.\n", name,
5234 it->newLocalType(name, retval);
5246 struct timeval time,
5247 vrpn_uint32 payload_len,
const char *buf)
5249 return d_dispatcher->doCallbacksFor(type, sender, time, payload_len, buf);
5258 char **local_out_logname,
5259 char **remote_in_logname,
5260 char **remote_out_logname)
5269 if (local_in_logname != NULL)
5271 if (local_out_logname != NULL)
5274 if (remote_in_logname != NULL) {
5277 *remote_in_logname =
5281 fprintf(stderr,
"vrpn_Connection::get_log_names(): Out of memory\n");
5283 *remote_in_logname = NULL;
5286 *remote_in_logname = NULL;
5290 if (remote_out_logname != NULL) {
5293 *remote_out_logname =
5298 fprintf(stderr,
"vrpn_Connection::get_log_names(): Out of memory\n");
5300 *remote_out_logname = NULL;
5303 *remote_out_logname = NULL;
5313 vrpn_int32 *connectedEC)
5319 fprintf(stderr,
"vrpn_Connection::get_log_names(): Out of memory\n");
5336 printf(
"Just read disconnect message from logfile\n");
5345 void *userdata, vrpn_int32 sender)
5347 return d_dispatcher->addHandler(type, handler, userdata, sender);
5352 void *userdata, vrpn_int32 sender)
5354 return d_dispatcher->removeHandler(type, handler, userdata, sender);
5371 if (!it->doing_okay()) {
5418 const char *cname,
const char *local_in_logfile_name,
5419 const char *local_out_logfile_name,
const char *remote_in_logfile_name,
5420 const char *remote_out_logfile_name,
const char *NIC_IPaddress,
5421 bool force_connection)
5423 if (cname == NULL) {
5424 fprintf(stderr,
"vrpn_get_connection_by_name(): NULL name\n");
5430 const char *where_at;
5431 if ((where_at = strrchr(cname,
'@')) != NULL) {
5432 cname = where_at + 1;
5436 if (!force_connection) {
5448 int is_file = !strncmp(cname,
"file:", 5);
5453 local_out_logfile_name);
5455 fprintf(stderr,
"vrpn_get_connection_by_name(): Out of memory.");
5462 cname, port, local_in_logfile_name, local_out_logfile_name,
5463 remote_in_logfile_name, remote_out_logfile_name, NIC_IPaddress);
5465 fprintf(stderr,
"vrpn_get_connection_by_name(): Out of memory.");
5473 fprintf(stderr,
"vrpn_get_connection_by_name(): Could not create new connection.");
5508 const char *local_in_logfile_name,
5509 const char *local_out_logfile_name)
5514 if (cname == NULL) {
5515 fprintf(stderr,
"vrpn_create_server_connection(): NULL name\n");
5519 if (location == NULL) {
5522 int is_loopback = !strncmp(cname,
"loopback:", 9);
5523 int is_mpi = !strncmp(cname,
"mpi:", 4);
5526 XXX_implement_MPI_server_connection;
5528 fprintf(stderr,
"vrpn_create_server_connection(): MPI support not "
5529 "compiled in. Set VRPN_USE_MPI in vrpn_Configure.h "
5530 "and recompile.\n");
5534 fprintf(stderr,
"vrpn_create_server_connection: delete failed\n");
5539 }
else if (is_loopback) {
5543 fprintf(stderr,
"vrpn_create_server_connection(): Out of memory\n");
5554 if (strlen(location) == 0) {
5557 local_in_logfile_name,
5558 local_out_logfile_name);
5560 fprintf(stderr,
"vrpn_create_server_connection(): Out of memory\n");
5569 if (strlen(machine) == 0) {
5573 fprintf(stderr,
"vrpn_create_server_connection(): delete failed\n");
5578 unsigned short port =
5582 local_out_logfile_name, machine);
5584 fprintf(stderr,
"vrpn_create_server_connection(): Out of memory\n");
5591 fprintf(stderr,
"vrpn_create_server_connection(): delete failed\n");
5600 fprintf(stderr,
"vrpn_create_server_connection(): delete failed\n");
5605 fprintf(stderr,
"vrpn_create_server_connection(): Could not create new "
5636 fprintf(stderr,
"vrpn_Connection_IP::connect_to_client:"
5637 " Too many existing connections.\n");
5644 fprintf(stderr,
"vrpn_Connection_IP::connect_to_client:"
5645 " Out of memory on new endpoint\n");
5652 sprintf(msg,
"%s %d", machine, port);
5653 printf(
"vrpn_Connection_IP::connect_to_client: "
5654 "Connection request received: %s\n",
5672 fprintf(stderr,
"vrpn_Connection_IP::handle_connection(): "
5673 "Can't set up new connection!\n");
5687 char rhostname[1000];
5690 printf(
" Received request for UDP channel to %s\n", p.
buffer);
5711 printf(
" Opened UDP channel to %s:%d\n", rhostname, p.
sender);
5720 if (it->send_pending_reports() != 0) {
5724 fprintf(stderr,
"vrpn_Connection_IP::send_pending_reports: "
5725 "Closing failed endpoint.\n");
5738#ifdef VRPN_USE_WINSOCK_SOCKETS
5745 winStatus = WSAStartup(MAKEWORD(1, 1), &wsaData);
5747 fprintf(stderr,
"vrpn_Connection_IP::init(): "
5748 "Failed to set up sockets.\n");
5749 fprintf(stderr,
"WSAStartup failed with error code %d\n", winStatus);
5762 signal(SIGPIPE, (
void (*)(
int))SIG_IGN);
5764 signal(SIGPIPE, SIG_IGN);
5787 const struct timeval *pTimeout)
5795 timeout = *pTimeout;
5799 timeout.tv_usec = 0;
5810 if (request == -1) {
5812 "vrpn_Connection_IP::server_check_for_incoming_connections(): "
5813 "select failed.\n");
5819 else if (request != 0) {
5820 struct sockaddr_in from;
5821 int fromlen =
sizeof(from);
5825 (
struct sockaddr *)&from,
GSN_CAST & fromlen) == -1) {
5827 "vrpn: Error on recvfrom: Bad connection attempt\n");
5832 msg[
sizeof(msg) - 1] =
'\0';
5838 char fromname[1024];
5839 unsigned long addr_num = ntohl(from.sin_addr.s_addr);
5840 sprintf(fromname,
"%lu.%lu.%lu.%lu", (addr_num) >> 24,
5841 (addr_num >> 16) & 0xff, (addr_num >> 8) & 0xff,
5843 printf(
"vrpn: Connection request received from %s: %s\n", fromname,
5854 char *checkHost = NULL;
5856 checkHost =
new char[strlen(msg) + 1];
5858 fprintf(stderr,
"vrpn_Connection_IP::server_check_for_incoming_connections(): "
5864 if (sscanf(msg,
"%s %d", checkHost, &checkPort) != 2) {
5867 "server_check_for_incoming_connections(): Malformed request\n");
5871 fprintf(stderr,
"server_check_for_incoming_connections(): delete failed\n");
5876 if (checkPort < 1024) {
5878 "server_check_for_incoming_connections(): Bad port\n");
5882 fprintf(stderr,
"server_check_for_incoming_connections(): delete failed\n");
5890 for (checkLoop = 0; checkLoop < strlen(checkHost); checkLoop++) {
5891 char checkChar = checkHost[checkLoop];
5892 if (!isalnum(checkChar) && (checkChar !=
'.')) {
5895 "server_check_for_incoming_connections(): Bad hostname\n");
5899 fprintf(stderr,
"server_check_for_incoming_connections(): delete failed\n");
5908 fprintf(stderr,
"server_check_for_incoming_connections(): delete failed\n");
5914 fprintf(stderr,
"vrpn: Too many existing connections; "
5915 "ignoring request from %s\n",
5928 "vrpn_Connection_IP::server_check_for_incoming_connections:\n"
5929 " Out of memory on new endpoint\n");
5946 fprintf(stderr,
"vrpn_Connection_IP::server_check_for_incoming_"
5948 "Couldn't open log file.\n");
5959 sscanf(msg,
"%*s %d", &port);
5983 fprintf(stderr,
"Error accepting on TCP socket.\n");
5988 printf(
"vrpn: TCP connection request received.\n");
5991 fprintf(stderr,
"vrpn: Too many existing connections; "
5992 "ignoring request.\n");
6001 "vrpn_Connection_IP::server_check_for_incoming_connections:\n"
6002 " Out of memory on new endpoint\n");
6015 struct sockaddr_in peer;
6016#ifdef VRPN_USE_WINSOCK_SOCKETS
6017 int peerlen =
sizeof(peer);
6020 int peerlen =
sizeof(peer);
6022 socklen_t peerlen =
sizeof(peer);
6025 unsigned short peer_port = 0;
6026 if (getpeername(newSocket,
static_cast<struct sockaddr *
>(
6027 static_cast<void *
>(&peer)),
6029 peer_port = ntohs(peer.sin_port);
6041 fprintf(stderr,
"vrpn_Connection_IP::server_check_for_incoming_"
6043 "Couldn't open incoming log file.\n");
6115 timeout = *pTimeout;
6119 timeout.tv_usec = 0;
6122 it->mainloop(&timeout);
6124 if (it->status ==
BROKEN) {
6136 unsigned short listen_port_no,
const char *local_in_logfile_name,
6137 const char *local_out_logfile_name,
const char *NIC_IPaddress,
6146 if (NIC_IPaddress != NULL)
try {
6147 char *IP =
new char[strlen(NIC_IPaddress) + 1];
6148 strcpy(IP, NIC_IPaddress);
6151 fprintf(stderr,
"vrpn_Connection_IP::vrpn_Connection_IP(): Out of memory.\n");
6173 printf(
"vrpn: Listening for requests on port %d\n", listen_port_no);
6179 fprintf(stderr,
"Couldn't listen on TCP listening socket.\n");
6190 const char *station_name,
int port,
const char *local_in_logfile_name,
6191 const char *local_out_logfile_name,
const char *remote_in_logfile_name,
6192 const char *remote_out_logfile_name,
const char *NIC_IPaddress,
6195 remote_in_logfile_name, remote_out_logfile_name, epa)
6207 if (NIC_IPaddress != NULL)
try {
6208 char *IP =
new char[strlen(NIC_IPaddress) + 1];
6209 strcpy(IP, NIC_IPaddress);
6212 fprintf(stderr,
"vrpn_Connection_IP::vrpn_Connection_IP(): Out of memory.\n");
6217 isrsh = (strstr(station_name,
"x-vrsh:") ? VRPN_TRUE : VRPN_FALSE);
6218 istcp = (strstr(station_name,
"tcp:") ? VRPN_TRUE : VRPN_FALSE);
6225 fprintf(stderr,
"vrpn_Connection_IP: First endpoint is null!\n");
6238 if (!isrsh && !istcp) {
6245 "vrpn_Connection_IP: Can't get remote machine name!\n");
6268 fprintf(stderr,
"vrpn_Connection_IP: Can't set up socket to lob "
6277 printf(
"vrpn_Connection_IP: Getting the TCP port to listen on\n");
6282 char local_host[64];
6283 get_local_socket_name(local_host,
sizeof(local_host),
6289 local_host) == -1) {
6291 fprintf(stderr,
"vrpn_Connection_IP: Can't create listen socket\n");
6304 NIC_IPaddress) == -1) {
6306 fprintf(stderr,
"vrpn_Connection_IP: Can't lob UDP request\n");
6332 fprintf(stderr,
"vrpn_Connection_IP: Can't poll for accept\n");
6339 printf(
"vrpn: Connection established on initial try "
6340 "(COOKIE_PENDING)\n");
6345 fprintf(stderr,
"vrpn_Connection_IP: "
6346 "Can't set up new connection!\n");
6360 fprintf(stderr,
"vrpn_Connection_IP: Can't get remote machine name "
6361 "for tcp: connection!\n");
6374 printf(
"vrpn_Connection_IP: Getting the TCP port to connect with.\n");
6384 "vrpn_Connection_IP: Can't create TCP connection.\n");
6392 fprintf(stderr,
"vrpn_Connection_IP: "
6393 "Can't set up new connection!\n");
6407 char *server_program;
6414 token = server_args;
6416 while ((token = strchr(token,
',')) != NULL) {
6420 endpoint->
d_tcpSocket = vrpn_start_server(machinename, server_program,
6421 server_args, NIC_IPaddress);
6424 delete[](
char *)machinename;
6426 fprintf(stderr,
"vrpn_Connection_IP: delete failed\n");
6430 if (server_program) {
6432 delete[](
char *)server_program;
6434 fprintf(stderr,
"vrpn_Connection_IP: delete failed\n");
6440 delete[](
char *)server_args;
6442 fprintf(stderr,
"vrpn_Connection_IP: delete failed\n");
6448 fprintf(stderr,
"vrpn_Connection_IP: "
6462 fprintf(stderr,
"vrpn_Connection_IP: "
6463 "Can't set up new connection!\n");
6493 fprintf(stderr,
"vrpn_Connection_IP::~vrpn_Connection_IP: delete failed\n");
6502#ifdef VRPN_USE_WINSOCK_SOCKETS
6504 if (WSACleanup() == SOCKET_ERROR) {
6505 fprintf(stderr,
"~vrpn_Connection_IP(): "
6506 "WSACleanup() failed with error code %d\n",
6536 if (fullname == NULL) {
6539 size_t len = strcspn(fullname,
"@");
6540 if (len >= MAX_SIZE_T) {
6541 fprintf(stderr,
"vrpn_copy_service_name: String too long!\n");
6547 tbuf =
new char[len];
6548 strncpy(tbuf, fullname, len - 1);
6551 fprintf(stderr,
"vrpn_copy_service_name: Out of memory!\n");
6561 int offset =
static_cast<int>(strcspn(fullname,
"@"));
6562 size_t len = strlen(fullname) - offset;
6565 len = strlen(fullname) + 1;
6569 tbuf =
new char[len];
6570 strncpy(tbuf, fullname + offset + 1, len - 1);
6573 fprintf(stderr,
"vrpn_copy_service_location: Out of memory!\n");
6581 char *filename = NULL;
6586 if (!fp)
return NULL;
6588 if (!strncmp(fp,
"file://", 7)) {
6590 }
else if (!strncmp(fp,
"file:", 5)) {
6594 len = 1 + strlen(fp);
6597 filename =
new char[len];
6598 strncpy(filename, fp, len);
6599 filename[len - 1] = 0;
6601 fprintf(stderr,
"vrpn_copy_file_name: Out of memory!\n");
6610static int header_len(
const char *hostspecifier)
6614 if (!strncmp(hostspecifier,
"x-vrpn://", 9) ||
6615 !strncmp(hostspecifier,
"x-vrsh://", 9)) {
6618 else if (!strncmp(hostspecifier,
"x-vrpn:", 7) ||
6619 !strncmp(hostspecifier,
"x-vrsh:", 7)) {
6622 else if (!strncmp(hostspecifier,
"tcp://", 6)) {
6625 else if (!strncmp(hostspecifier,
"tcp:", 4)) {
6628 else if (!strncmp(hostspecifier,
"mpi://", 6)) {
6631 else if (!strncmp(hostspecifier,
"mpi:", 4)) {
6644 size_t nearoffset = 0;
6653 nearoffset = header_len(hostspecifier);
6658 faroffset = strcspn(hostspecifier + nearoffset,
":/");
6659 if (faroffset >= MAX_SIZE_T) {
6660 fprintf(stderr,
"vrpn_copy_machine_name: String too long!\n");
6663 len = 1 + faroffset;
6667 tbuf =
new char[len];
6668 strncpy(tbuf, hostspecifier + nearoffset, len - 1);
6671 fprintf(stderr,
"vrpn_copy_machine_name: Out of memory!\n");
6686 pn += header_len(hostspecifier);
6688 pn = strrchr(pn,
':');
6699 size_t nearoffset = 0;
6704 nearoffset += header_len(hostspecifier);
6706 nearoffset += strcspn(hostspecifier + nearoffset,
"/");
6708 faroffset = strcspn(hostspecifier + nearoffset,
",");
6709 len = (faroffset ? faroffset : strlen(hostspecifier) - nearoffset);
6710 if (len >= MAX_SIZE_T) {
6711 fprintf(stderr,
"vrpn_copy_rsh_program: String too long!\n");
6716 tbuf =
new char[len];
6717 strncpy(tbuf, hostspecifier + nearoffset, len - 1);
6721 fprintf(stderr,
"vrpn_copy_rsh_program: Out of memory!\n");
6729 size_t nearoffset = 0;
6734 nearoffset += header_len(hostspecifier);
6736 nearoffset += strcspn(hostspecifier + nearoffset,
"/");
6737 nearoffset += strcspn(hostspecifier + nearoffset,
",");
6738 faroffset = strlen(hostspecifier);
6739 len = 1 + faroffset - nearoffset;
6741 tbuf =
new char[len];
6742 strncpy(tbuf, hostspecifier + nearoffset, len - 1);
6746 fprintf(stderr,
"vrpn_copy_rsh_arguments: Out of memory!\n");
6761 size_t inputLength = strlen(specifier);
6762 size_t atSymbolIndex = strcspn(specifier,
"@");
6764 char *location = NULL;
6766 if (atSymbolIndex == inputLength) {
6769 location =
new char[inputLength + 1];
6770 strcpy(location, specifier);
6772 fprintf(stderr,
"vrpn_set_service_name: Out of memory!\n");
6781 size_t len = strlen(location) + strlen(newServiceName);
6782 char *newSpecifier = NULL;
6784 newSpecifier =
new char[len + 2];
6785 strcpy(newSpecifier, newServiceName);
6786 strcat(newSpecifier,
"@");
6787 strcat(newSpecifier, location);
6789 fprintf(stderr,
"vrpn_set_service_name: Out of memory!\n");
6793 fprintf(stderr,
"vrpn_set_service_name: delete failed\n");
6801 fprintf(stderr,
"vrpn_set_service_name: delete failed\n");
6804 return newSpecifier;
Combines the function pointer for an Endpoint Allocator with its two arguments into a single callable...
pointer front() const
Shorthand for get_by_index(0)
bool full() const
Can we no longer accommodate a new endpoint?
iterator end() const
Get an iterator suitable only for testing to see if we're "done".
T * acquire(T *endpoint)
Given the result of an endpoint allocator, if it's non-NULL, takes ownership of it.
void compact()
Goes through and gets rid of the NULL entries.
bool destroy(base_pointer endpoint)
Destroys the contained endpoint by address.
void clear()
Tells each held endpoint in turn to drop the connection then deletes it.
iterator begin() const
Get an iterator to the beginning that skips nulls. Invalidated by compacting.
An iterator that goes forward in an EndpointContainer skipping the NULLs, that also acts a bit like a...
An RAII lock/guard class for vrpn_Semaphore.
Singleton class that keeps track of all known VRPN connections and makes sure they're deleted on shut...
void addConnection(vrpn_Connection *, const char *name)
NB implementation is not particularly efficient; we expect to have O(10) connections,...
~vrpn_ConnectionManager(void)
vrpn_Connection * getByName(const char *name)
Searches through d_kcList but NOT d_anonList (Connections constructed with no name)
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,...
virtual void handle_connection(vrpn_Endpoint *endpoint)
This routine is called by a server-side connection when a new connection has just been established,...
SOCKET listen_udp_sock
UDP Connect requests come here.
virtual int mainloop(const struct timeval *timeout=NULL)
Call each time through program main loop to handle receiving any incoming messages and sending any pa...
virtual ~vrpn_Connection_IP(void)
vrpn_Connection_IP(const char *server_name, int port=vrpn_DEFAULT_LISTEN_PORT_NO, const char *local_in_logfile_name=NULL, const char *local_out_logfile_name=NULL, const char *remote_in_logfile_name=NULL, const char *remote_out_logfile_name=NULL, const char *NIC_IPaddress=NULL, vrpn_EndpointAllocator epa=allocateEndpoint)
Make a client connection. To access this from user code, call vrpn_get_connection_by_name()....
virtual void drop_connection(vrpn_Endpoint *endpoint)
Drops the connection with the given, non-NULL endpoint. Depending on if we're a server or a client,...
SOCKET listen_tcp_sock
TCP Connection requests come here.
virtual int send_pending_reports(void)
send pending report, clear the buffer.
virtual int connect_to_client(const char *machine, int port)
This is similar to check connection except that it can be used to receive requests from before a serv...
void drop_connection_and_compact(vrpn_Endpoint *endpoint)
Like drop_connection, except it includes the call to compact the endpoints. Only safe to call if you ...
virtual void server_check_for_incoming_connections(const struct timeval *timeout=NULL)
static int VRPN_CALLBACK handle_UDP_message(void *userdata, vrpn_HANDLERPARAM p)
Routines that handle system messages.
void init(void)
Called by all constructors.
Constructor for a Loopback connection that will basically just pass messages between objects that are...
vrpn_Connection_Loopback()
Make a client connection. To access this from user code, call vrpn_create_server_connection() with a ...
virtual int mainloop(const struct timeval *timeout=NULL)
Call each time through program main loop to handle receiving any incoming messages and sending any pa...
virtual ~vrpn_Connection_Loopback(void)
Generic connection class not specific to the transport mechanism.
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 delete_endpoint(vrpn_Endpoint *endpoint)
Deletes the endpoint and NULLs the entry in the list of open endpoints.
void addReference()
Counting references to this connection.
virtual int time_since_connection_open(struct timeval *elapsed_time)
Returns the time since the connection opened. Some subclasses may redefine time.
virtual void updateEndpoints(void)
This function will be called on the mainloop() iteration after *d_endpointAllocator is called,...
virtual timeval get_time()
returns the current time in the connection (since the epoch – UTC time).
static int VRPN_CALLBACK handle_log_message(void *userdata, vrpn_HANDLERPARAM p)
Routines that handle system messages.
int message_type_is_registered(const char *) const
Returns message type ID, or -1 if unregistered.
virtual const char * sender_name(vrpn_int32 sender)
Returns the name of the specified sender/type, or NULL if the parameter is invalid....
int doSystemCallbacksFor(vrpn_HANDLERPARAM, void *)
virtual vrpn_int32 register_message_type(const char *name)
virtual vrpn_bool connected(void) const
Returns vrpn_true if the connection has been established, vrpn_false if not (For a networkless connec...
virtual int pack_sender_description(vrpn_int32 which)
Send the sender description to ALL endpoints.
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...
int compact_endpoints(void)
Makes sure the endpoint array is set up cleanly for the next pass through.
virtual ~vrpn_Connection(void)
int d_serverLogCount
Server logging w. multiconnection - TCH July 00 Use one "hidden" endpoint for outgoing logs (?...
static vrpn_Endpoint_IP * allocateEndpoint(vrpn_Connection *, vrpn_int32 *connectedEC)
Redefining this and passing it to constructors allows a subclass to use a different subclass of Endpo...
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_int32 d_numConnectedEndpoints
We need to track the number of connected endpoints separately to properly send out got-first-connecti...
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...
vrpn_bool d_updateEndpoint
vrpn_TypeDispatcher * d_dispatcher
Derived classes need access to d_dispatcher in their allocateEndpoint() routine. Several compilers wo...
vrpn_int32 d_serverLogMode
virtual int pack_type_description(vrpn_int32 which)
Send the type description to ALL endpoints.
vrpn::EndpointContainer d_endpoints
Sockets used to talk to remote Connection(s) and other information needed on a per-connection basis.
virtual int save_log_so_far()
Save any messages on any endpoints which have been logged so far.
virtual const char * message_type_name(vrpn_int32 type)
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...
virtual vrpn_bool doing_okay(void) const
Returns vrpn_true if the connection is okay, vrpn_false if not.
virtual int unregister_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
void setAutoDeleteStatus(bool setvalue)
Specify whether this connection should be deleted automatically when it is no longer need (reference ...
int connectionStatus
Status of the connection.
virtual int register_log_filter(vrpn_LOGFILTER filter, void *userdata)
Sets up a filter function for logging. Any user message to be logged is first passed to this function...
timeval start_time
Timekeeping - TCH 30 June 98.
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...
static int VRPN_CALLBACK handle_disconnect_message(void *userdata, vrpn_HANDLERPARAM p)
vrpn_uint32 d_stop_processing_messages_after
If this value is greater than zero, the connection should stop looking for new messages on a given en...
vrpn::BoundEndpointAllocator d_boundEndpointAllocator
Function object wrapping an endpoint allocator and binding its arguments.
Encapsulation of the data and methods for a single IP-based connection to take care of one part of ma...
vrpn_int32 tcp_outbuf_size(void) const
vrpn_float64 d_udpAlignedInbuf[vrpn_CONNECTION_UDP_BUFLEN/sizeof(vrpn_float64)+1]
int handle_udp_messages(const timeval *timeout)
SOCKET d_udpInboundSocket
Inbound unreliable messages come here. Need one for each due to different clock synchronization for e...
virtual ~vrpn_Endpoint_IP(void)
void setNICaddress(const char *)
int connect_tcp_to(const char *msg)
void clearBuffers(void)
Empties out the TCP and UDP send buffers. Needed by vrpn_FileConnection to get at {udp,...
virtual vrpn_bool doing_okay(void) const
SOCKET d_tcpListenSocket
This section deals with when a client connection is trying to establish (or re-establish) a connectio...
vrpn_int32 d_udpSequenceNumber
virtual int send_pending_reports(void)
send pending report, clear the buffer.
timeval d_last_connect_attempt
When the last UDP lob occurred.
vrpn_bool outbound_udp_open(void) const
True if the UDP outbound is open, False if not.
int handle_tcp_messages(const timeval *timeout)
char * d_remote_machine_name
Machine to call.
int getOneTCPMessage(int fd, char *buf, size_t buflen)
vrpn_bool d_tcp_only
For connections made through firewalls or NAT with the tcp: URL, we do not want to allow the endpoint...
int d_tcpListenPort
Socket and port that the client listens on when lobbing datagrams at the server and waiting for it to...
vrpn_Endpoint_IP(vrpn_TypeDispatcher *dispatcher, vrpn_int32 *connectedEndpointCounter)
int d_remote_port_number
Port to connect to on remote machine.
int pack_udp_description(int portno)
SOCKET d_udpOutboundSocket
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.
int getOneUDPMessage(char *buf, size_t buflen)
int mainloop(timeval *timeout)
int connect_udp_to(const char *addr, int port)
Connects d_udpSocket to the specified address and port; returns 0 on success, sets status to BROKEN a...
vrpn_int32 udp_outbuf_size(void) const
SOCKET d_udpLobSocket
Socket to use to lob UDP requests asking for the server to call us back.
vrpn_float64 d_tcpAlignedInbuf[vrpn_CONNECTION_TCP_BUFLEN/sizeof(vrpn_float64)+1]
int setup_new_connection(void)
Sends the magic cookie and other information to its peer. It is called by both the client and server ...
void poll_for_cookie(const timeval *timeout=NULL)
vrpn_int32 d_tcpSequenceNumber
int finish_new_connection_setup(void)
void drop_connection(void)
Should only be called by vrpn_Connection::drop_connection(), since there's more housecleaning to do a...
Encapsulation of the data and methods for a single generic connection to take care of one part of man...
void setConnection(vrpn_Connection *conn)
int local_type_id(vrpn_int32 remote_type) const
Returns the local mapping for the remote type (-1 if none).
static int VRPN_CALLBACK handle_type_message(void *userdata, vrpn_HANDLERPARAM p)
int tryToMarshall(char *outbuf, vrpn_int32 &buflen, vrpn_int32 &numOut, vrpn_uint32 len, timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer, vrpn_uint32 classOfService)
Calls marshall_message(); if that fails, calls send_pending_reports() and then marshalls again....
long d_remoteLogMode
Mode to put the remote logging in.
void clear_other_senders_and_types(void)
Clear out the remote mapping list. This is done when a connection is dropped and we want to try and r...
vrpn_TypeDispatcher * d_dispatcher
virtual ~vrpn_Endpoint(void)
virtual int send_pending_reports(void)=0
send pending report, clear the buffer. This function was protected, now is public,...
virtual int setup_new_connection(void)=0
Sends the magic cookie and other information to its peer. It is called by both the client and server ...
int pack_sender_description(vrpn_int32 which)
Packs a sender description over our socket.
int marshall_message(char *outbuf, vrpn_uint32 outbuf_size, vrpn_uint32 initial_out, vrpn_uint32 len, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer, vrpn_uint32 sequenceNumber)
Marshal the message into the buffer if it will fit.
virtual void drop_connection(void)=0
Should only be called by vrpn_Connection::drop_connection(), since there's more housecleaning to do a...
static int VRPN_CALLBACK handle_sender_message(void *userdata, vrpn_HANDLERPARAM p)
vrpn_int32 * d_connectionCounter
char * d_remoteInLogName
Name of the remote log file.
int pack_log_description(void)
Packs the log description set by setup_new_connection().
virtual int dispatch(vrpn_int32 type, vrpn_int32 sender, timeval time, vrpn_uint32 payload_len, char *bufptr)
int newLocalType(const char *name, vrpn_int32 which)
int newRemoteType(cName type_name, vrpn_int32 remote_id, vrpn_int32 local_id)
Adds a new remote type/sender and returns its index. Returns -1 on error.
vrpn_Endpoint(vrpn_TypeDispatcher *dispatcher, vrpn_int32 *connectedEndpointCounter)
int local_sender_id(vrpn_int32 remote_sender) const
Returns the local mapping for the remote sender (-1 if none).
virtual int pack_message(vrpn_uint32 len, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer, vrpn_uint32 class_of_service)=0
Pack a message that will be sent the next time mainloop() is called. Turn off the RELIABLE flag if yo...
vrpn_TranslationTable * d_senders
vrpn_Connection * d_parent
int newLocalSender(const char *name, vrpn_int32 which)
A new local sender or type has been established; set the local type for it if the other side has decl...
int pack_type_description(vrpn_int32 which)
Packs a type description.
void setLogNames(const char *inName, const char *outName)
vrpn_TranslationTable * d_types
char * d_remoteOutLogName
Name of the remote log file.
int newRemoteSender(cName sender_name, vrpn_int32 remote_id, vrpn_int32 local_id)
vrpn_bool d_wroteMagicCookie
int setCookie(const char *cookieBuffer)
The magic cookie is set to the default value of the version of VRPN compiled, but a more correct valu...
int addFilter(vrpn_LOGFILTER filter, void *userdata)
char * getName()
Allocates a new string and copies the log file name to it. IMPORTANT: code calling this function is r...
vrpn_Log(vrpn_TranslationTable *senders, vrpn_TranslationTable *types)
vrpn_TranslationTable * d_senders
int setName(const char *name)
int checkFilters(vrpn_int32 payloadLen, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer)
int setCompoundName(const char *name, int index)
Takes a name of the form foo.bar and an index <n> and sets the name of the log file to be foo-<n>....
int open(void)
Opens the log file.
vrpn_TranslationTable * d_types
long & logMode(void)
Returns a reference so we can |= it.
vrpnLogFilterEntry * d_filters
int saveLogSoFar(void)
Saves any messages logged so far.
vrpn_LOGLIST * d_firstEntry
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.
timeval lastLogTime()
Returns the time of the last message that was logged.
int logMessage(vrpn_int32 payloadLen, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer, vrpn_bool isRemote=VRPN_FALSE)
We'd like to make this protected, but there's one place it needs to be exposed, at least until we get...
int logOutgoingMessage(vrpn_int32 payloadLen, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer)
int close(void)
Closes and saves the log file.
int v()
Release of resource. ("up")
int p()
Blocking acquire of resource. ("down")
vrpn_LOGFILTER filter
routine to call
void * userdata
passed along
vrpnLogFilterEntry * next
Description of a callback entry for a user type.
vrpnMsgCallbackEntry * next
Next handler.
void * userdata
Passed along.
vrpn_int32 sender
Only if from sender.
vrpn_MESSAGEHANDLER handler
Routine to call.
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.
int write_vrpn_cookie(char *buffer, size_t length, long remote_log_mode)
Writes the magic cookie into buffer with given length.
char * vrpn_copy_file_name(const char *filespecifier)
Utility routines to parse file specifiers FROM service locations.
const char * vrpn_CONTROL
vrpn_CONTROL is the sender used for notification messages sent to the user from the local VRPN implem...
const char * vrpn_got_first_connection
These are the strings that define the system-generated message types that tell when connections are r...
char * vrpn_copy_machine_name(const char *hostspecifier)
#define vrpn_CONNECTION_MAX_XLATION_TABLE_SIZE
const char * vrpn_FILE_MAGIC
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).
char * vrpn_copy_service_name(const char *fullname)
int vrpn_udp_request_lob_packet(SOCKET udp_sock, const char *, const int, const int local_port, const char *NIC_IP=NULL)
This section deals with implementing a method of connection termed a UDP request.
const char * vrpn_dropped_last_connection
#define vrpn_socket_error_to_chars(x)
const size_t vrpn_COOKIE_SIZE
#define vrpn_socket_error
int vrpn_noint_select(int width, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
This routine will perform like a normal select() call, but it will restart if it quit because of an i...
int vrpn_noint_block_read_timeout(SOCKET infile, char buffer[], size_t length, struct timeval *timeout)
This routine will read in a block from the file descriptor.
char * vrpn_copy_rsh_program(const char *hostspecifier)
char * vrpn_copy_rsh_arguments(const char *hostspecifier)
char * vrpn_copy_service_location(const char *fullname)
const char * vrpn_dropped_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).
char * vrpn_set_service_name(const char *specifier, const char *newServiceName)
Utility routine to rename the service name of a given host specifier.
int vrpn_noint_block_read(int infile, char buffer[], size_t length)
int vrpn_noint_block_write(int outfile, const char buffer[], size_t length)
const char * vrpn_got_connection
int check_vrpn_cookie(const char *buffer)
Checks to see if the given buffer has the magic cookie.
int check_vrpn_file_cookie(const char *buffer)
int vrpn_get_port_number(const char *hostspecifier)
const vrpn_int32 vrpn_CONNECTION_UDP_DESCRIPTION
const int vrpn_CONNECTION_UDP_BUFLEN
const vrpn_uint32 vrpn_CONNECTION_RELIABLE
Classes of service for messages, specify multiple by ORing them together Priority of satisfying these...
VRPN_API char * vrpn_copy_rsh_arguments(const char *hostspecifier)
const vrpn_int32 vrpn_CONNECTION_LOG_DESCRIPTION
const int vrpn_CONNECTION_MAX_SENDERS
Types now have their storage dynamically allocated, so we can afford to have large tables....
const vrpn_int32 vrpn_CONNECTION_TYPE_DESCRIPTION
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 check_vrpn_cookie(const char *buffer)
Checks the buffer to see if it is a valid VRPN header cookie. Returns -1 on total mismatch,...
const unsigned vrpn_ALIGN
VRPN buffers are aligned on 8 byte boundaries so that we can pack and unpack doubles into them on arc...
int VRPN_API vrpn_noint_select(int width, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
This routine will perform like a normal select() call, but it will restart if it quit because of an i...
VRPN_API int write_vrpn_cookie(char *buffer, size_t length, long remote_log_mode)
Writes the magic cookie into buffer with given length.
vrpn_Endpoint_IP *(* vrpn_EndpointAllocator)(vrpn_Connection *connection, vrpn_int32 *numActiveConnections)
Function pointer to an endpoint allocator.
vrpn_MESSAGEHANDLER vrpn_LOGFILTER
Type of handler for filters on logfiles is the same as connection handler.
const int vrpn_ANY_TYPE
vrpn_ANY_TYPE can be used to register callbacks for any USER type of message from a given sender....
int(VRPN_CALLBACK * vrpn_MESSAGEHANDLER)(void *userdata, vrpn_HANDLERPARAM p)
Type of a message handler for vrpn_Connection messages.
VRPN_API const char * vrpn_CONTROL
vrpn_CONTROL is the sender used for notification messages sent to the user from the local VRPN implem...
char cName[100]
Length of names within VRPN.
VRPN_API char * vrpn_copy_service_location(const char *fullname)
class VRPN_API vrpn_TypeDispatcher
VRPN_API const char * vrpn_dropped_connection
VRPN_API const char * vrpn_got_first_connection
These are the strings that define the system-generated message types that tell when connections are r...
VRPN_API const char * vrpn_got_connection
class VRPN_API vrpn_TranslationTable
const int vrpn_CONNECTION_MAX_TYPES
VRPN_API char * vrpn_copy_rsh_program(const char *hostspecifier)
const vrpn_int32 vrpn_CONNECTION_DISCONNECT_MESSAGE
const int vrpn_CONNECTION_TCP_BUFLEN
VRPN_API char * vrpn_copy_machine_name(const char *hostspecifier)
int VRPN_API vrpn_noint_block_write(int outfile, const char buffer[], size_t length)
const vrpn_int32 vrpn_CONNECTION_SENDER_DESCRIPTION
VRPN_API const char * vrpn_dropped_last_connection
const long vrpn_LOG_OUTGOING
const long vrpn_LOG_INCOMING
VRPN_API size_t vrpn_cookie_size(void)
Returns the size of the magic cookie buffer, plus any alignment overhead.
int VRPN_API vrpn_noint_block_read(int infile, char buffer[], size_t length)
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)
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.
timeval vrpn_TimevalDiff(const timeval &tv1, const timeval &tv2)
timeval vrpn_TimevalSum(const timeval &tv1, const timeval &tv2)
void vrpn_strcpy(char(&to)[charCount], const char *pSrc)
Null-terminated-string copy function that both guarantees not to overrun the buffer and guarantees th...
#define vrpn_gettimeofday