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 "/usr/bin/ssh"
240#define RSH "/usr/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;
312class vrpn_TranslationTable {
315 vrpn_TranslationTable(
void);
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;
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,
972class vrpn_TypeDispatcher {
975 vrpn_TypeDispatcher(
void);
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 {
1041 vrpnMsgCallbackEntry *d_genericCallbacks;
1044vrpn_TypeDispatcher::vrpn_TypeDispatcher(
void)
1047 , d_genericCallbacks(NULL)
1059vrpn_TypeDispatcher::~vrpn_TypeDispatcher(
void)
1061 vrpnMsgCallbackEntry *pVMCB, *pVMCB_Del;
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,
1223 vrpnMsgCallbackEntry *new_entry;
1224 vrpnMsgCallbackEntry **ptr;
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");
1248 new_entry =
new vrpnMsgCallbackEntry;
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)
1287 vrpnMsgCallbackEntry *victim, **snitch;
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,
1341 vrpnMsgCallbackEntry *who;
1342 vrpn_HANDLERPARAM p;
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,
1402 vrpn_HANDLERPARAM p;
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");
1522 static vrpn_ConnectionManager manager;
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)
2779 vrpn_int32 *connectedEndpointCounter)
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)
3263 if (
d_outLog->logOutgoingMessage(len, time, type, sender, buffer)) {
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++;
3574 if (
d_parent->get_Jane_value() != 0) {
3575 if (num_messages_read >=
d_parent->get_Jane_value()) {
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++;
3673 if (
d_parent->get_Jane_value() != 0) {
3674 if (num_messages_read >=
d_parent->get_Jane_value()) {
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");
4235 if (
d_inLog->logIncomingMessage(payload_len, time, type, sender, buf)) {
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");
4298 if (
d_inLog->logIncomingMessage(payload_len, time, type, sender,
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,
4954 , d_autoDeleteStatus(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,
5019 , d_autoDeleteStatus(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...
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.
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)
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.
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.
class VRPN_API vrpn_Endpoint_IP
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_File_Connection
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