Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • danc/MicroCART
  • snawerdt/MicroCART_17-18
  • bbartels/MicroCART_17-18
  • jonahu/MicroCART
4 results
Show changes
Showing
with 0 additions and 3021 deletions
set(ATMELLIB_PUBLIC_HEADERS
vrpn_atmellib_errno.h
vrpn_atmellib.h)
set(ATMELLIB_SOURCES
vrpn_atmellib_helper.h
vrpn_atmellib_helper.C
vrpn_atmellib_iobasic.C
vrpn_atmellib_openclose.C
vrpn_atmellib_register.C
vrpn_atmellib_tester.C)
add_library(vrpn_atmel ${ATMELLIB_PUBLIC_HEADERS} ${ATMELLIB_SOURCES})
set_property(TARGET
vrpn_atmel
PROPERTY
PUBLIC_HEADER
${ATMELLIB_PUBLIC_HEADERS})
set_property(TARGET
vrpn_atmel
PROPERTY
FOLDER
"Library")
if(VRPN_INSTALL)
install(TARGETS
vrpn_atmel
ARCHIVE
DESTINATION
lib
COMPONENT
serversdk
PUBLIC_HEADER
DESTINATION
include
COMPONENT
serversdk)
endif()
/* -*- Mode:C -*- */
/***************************************************************************************************/
/* */
/* Copyright (C) 2003 Bauhaus University Weimar */
/* Released into the public domain on 6/23/2007 as part of the VRPN project */
/* by Jan P. Springer. */
/* */
/***************************************************************************************************/
/* */
/* module : vrpn_atmellib.h */
/* project : vrpn_avango */
/* description: part of vrpn_avango_atmel_server */
/* */
/***************************************************************************************************/
/* */
/* */
/***************************************************************************************************/
#if !defined(VRPN_AVANGO_ATMELLIB_SERIAL_H)
#define VRPN_AVANGO_ATMELLIB_SERIAL_H
/* includes, system */
/* #include <> */
/* includes, project */
#include "vrpn_atmellib_errno.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*************************************************************************************************/
/* constants you have to remember */
/* maiximum time to wait for a new byte from the atmel */
#define VRPN_ATMELLIB_SELECT_WAIT_SEC 0
#define VRPN_ATMELLIB_SELECT_WAIT_USEC 150000
/*************************************************************************************************/
/* types, exported (enum, struct, union, typedef) */
/*************************************************************************************************/
/* the 2 bytes which defines a message from/to the microcontroller */
struct command_t {
unsigned char addr;
unsigned char value;
};
/*************************************************************************************************/
typedef int error_t;
typedef int handle_t;
/*************************************************************************************************/
/* for development purpose mainly
displays a value as Bits on the screen */
extern void outBit( unsigned char );
/*************************************************************************************************/
/* BASICS */
/*************************************************************************************************/
/* opens the the specified port (whole path needed) and sets the parameters
for the communication with the microcontroller
CAUTION: the return value is a program specific file handler and not the
system file handler */
extern handle_t openPort(const char*i, const int baud, struct termios * init_param);
/* close the specified port and reset all parameters */
extern error_t closePort (handle_t, struct termios * init_param);
/* checks if the given file handler is valid: returns 1 (true) if the handle is invalid otherwise
return 0 (false) */
extern error_t handle_invalid (int);
/* checks if the register is valid */
extern error_t register_invalid( unsigned char );
/*************************************************************************************************/
/* LOW LEVEL INTERFACE */
/*************************************************************************************************/
/* send one/more command(s) to the microcontroller which don't change the state of it
the return value of the command - i.e. the value of a register - is returned in the
second calling variable */
extern int getCmd (handle_t, struct command_t*);
/* send one/more command(s) to the microcontroller which change the state of the microcontrolle */
extern int setCmd (int, struct command_t*);
/* set the value of the specified register */
extern error_t
setRegister( handle_t Hd , const unsigned char Register , const unsigned char Val);
/* get the value of the specified register */
extern int getRegister( handle_t Hd , const unsigned char Register);
#if defined(__cplusplus)
} /* extern "C" { */
#endif
#endif /* #if !defined(VRPN_AVANGO_ATMELLIB_SERIAL_H) */
/* -*- Mode:C -*- */
/***************************************************************************************************/
/* */
/* Copyright (C) 2003 Bauhaus University Weimar */
/* Released into the public domain on 6/23/2007 as part of the VRPN project */
/* by Jan P. Springer. */
/* */
/***************************************************************************************************/
/* */
/* module : atmel_serial_errno.h */
/* project : atmellib */
/* description: error numbers of the lib */
/* */
/***************************************************************************************************/
#if !defined(ATMELLIB_SERIAL_ERRNO_H)
#define ATMELLIB_SERIAL_ERRNO_H
/* program specific error codes */
#define ATMELLIB_NOERROR 1 /* no error */
#define ATMELLIB_ERROR_GENERAL -1 /* general error */
#define ATMELLIB_ERROR_SEQTO -5 /* sequence to small */
#define ATMELLIB_ERROR_NORESPVAL -6 /* the mc didn't confirm the command */
#define ATMELLIB_ERROR_NOCOMVAL -7 /* no valid command (must be bigger than 127 ) */
#define ATMELLIB_ERROR_REGINV -10 /* the register is invalid */
#define ATMELLIB_ERROR_VALINV -11 /* the value register is invalid */
#define ATMELLIB_ERROR_RESINV -12 /* hardware ressource invalid */
#define ATMELLIB_ERROR_NOTINIT -13 /* the prequists are not ok: i.e. to put a
light on the pin must be in output mode */
#define ATMELLIB_ERROR_PARAMINV -14 /* functioncall with invalid parameter*/
#define ATMELLIB_ERROR_NOSTATEVAL -15 /* no valid state or not able to read it out */
#endif /* #if !defined(ATMELLIB_SERIAL_ERRNO_H) */
/***************************************************************************************************/
/* */
/* Copyright (C) 2004 Bauhaus University Weimar */
/* Released into the public domain on 6/23/2007 as part of the VRPN project */
/* by Jan P. Springer. */
/* */
/***************************************************************************************************/
/* */
/* module : vrpn_atmellib_helper.C */
/* project : atmel-avango */
/* description: part of the serial lib for the Atmel */
/* miscellaneous functions */
/* */
/***************************************************************************************************/
/* include system headers */
#include <errno.h> // for error_t
#include <stdio.h> // for printf
/* include i/f header */
#include "vrpn_atmellib.h" // for command_t, getCmd, setCmd, etc
#include "vrpn_atmellib_errno.h" // for ATMELLIB_NOERROR, etc
#include "vrpn_atmellib_helper.h"
/***************************************************************************************************/
/* set the defined bit in the command to the expected value and leave the rest like it is */
/***************************************************************************************************/
error_t
setBitCmd( struct command_t * Cmd , const unsigned char Pos , unsigned char Val )
{
/* check if the parameter are valid */
if ((Val != 0) && (Val != 1))
return ATMELLIB_ERROR_VALINV;
if (Pos > 7)
return ATMELLIB_ERROR_VALINV;
/* check if the value for "our" pin is already correct else change it */
if (Pos == 7) {
/* bit seven is in byte one */
if (((*Cmd).addr) & 0x01) {
if (Val == 0)
(*Cmd).addr -= 1; /* it's 1 and it has to be 0*/
}
else {
if (Val == 1) /* it's 0 and it has to be 1 */
(*Cmd).addr += 1;
}
}
else { /* the bits in the second byte */
unsigned char Reference = 0x01 << Pos;
if ( ((*Cmd).value) & Reference ) {
if (Val == 0)
(*Cmd).value -= PowToTwo(Pos);
}
else { /* change necessary */
if (Val == 1)
(*Cmd).value += PowToTwo(Pos);
}
}
return ATMELLIB_NOERROR;
}
/***************************************************************************************************/
/* change only one bit of the value of the specified register */
/***************************************************************************************************/
error_t
setBitReg( const handle_t Hd , const unsigned char Reg , \
const unsigned char Pos , const unsigned char Val )
{
struct command_t Cmd;
error_t R;
unsigned char i;
/* check if the parameters are valid */
if ((Val != 0) && (Val != 1))
return ATMELLIB_ERROR_VALINV;
/* set the correct address for the register */
/* check if the first bit is already set or if it has to be done here */
if (Reg & 0x80)
Cmd.addr = Reg;
else {
Cmd.addr = Reg + 64;
Cmd.addr <<= 1;
}
Cmd.value = 0x00;
/* get the current setting of the register on the microcontroller */
/* if you get sth invalid try again */
for (i=0 ; i<10 ; ++i) {
if ( (R = getCmd( Hd , &Cmd )) != ATMELLIB_NOERROR )
return R;
if ( Cmd.value<128)
break;
}
if (i==10)
return ATMELLIB_ERROR_NOSTATEVAL;
if ( (R = setBitCmd( &Cmd , Pos , Val )) != ATMELLIB_NOERROR)
return R;
/* write the corrected value back to the microcontroller */
if ( (R = setCmd( Hd , &Cmd )) != ATMELLIB_NOERROR )
return R;
return ATMELLIB_NOERROR;
}
/***************************************************************************************************/
/* 2^Exponent */
/***************************************************************************************************/
unsigned int
PowToTwo( unsigned int Exponent )
{
unsigned int i;
unsigned int R = 1;
for( i=0 ; i<Exponent ; i++)
R *= 2;
return R;
}
/***************************************************************************************************/
/* valid address byte to the specified register */
/* the MSB data bit is set to zero */
/***************************************************************************************************/
unsigned char
getAddress( unsigned char Reg )
{
Reg += 64;
Reg <<= 1;
return Reg;
}
/***************************************************************************************************/
/* set the value in a two byte command */
/***************************************************************************************************/
void
setValue( struct command_t * Cmd , unsigned char Val)
{
if (Val>127) {
Val -= 128;
if ( ! ((*Cmd).addr & 0x01))
(*Cmd).addr +=1;
}
else
if ((*Cmd).addr & 0x01)
(*Cmd).addr -=1;
(*Cmd).value = Val;
}
/***************************************************************************************************/
/* helper function */
/***************************************************************************************************/
/* extern */ void
outBit( unsigned char Arg )
{
unsigned char Ref;
for ( Ref=0x80 ; Ref != 0x00 ; Ref >>= 1 ) {
if (Ref & Arg)
printf("1");
else
printf("0");
}
printf("\n");
}
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
# pragma set woff 1174
#endif
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
# pragma reset woff 1174
#endif
/* -*- Mode:C -*- */
/***************************************************************************************************/
/* */
/* Copyright (C) 2003 Bauhaus University Weimar */
/* Released into the public domain on 6/23/2007 as part of the VRPN project */
/* by Jan P. Springer. */
/* */
/***************************************************************************************************/
/* */
/* module : lib */
/* project : atmellib */
/* description: private part of the header for internal use */
/* */
/***************************************************************************************************/
/* $Id: vrpn_atmellib_helper.h,v 1.1 2007/06/25 19:56:16 taylorr Exp $ */
#if !defined(ATMELLIB_SERIAL_HELPER_H)
#define ATMELLIB_SERIAL_HELPER_H
/* includes, system */
/* #include <> */
#include <errno.h> // for error_t
/* includes, project */
#include "vrpn_atmellib.h" // for handle_t
#if defined(__cplusplus)
extern "C" {
#endif
/*****************************************************************/
/* types, variables NOT exported, internal (static) */
/* internal functions */
/* set the specified bit in the given Command without interfering the other bits*/
error_t setBitCmd( struct command_t * Command , \
const unsigned char Position , unsigned char Value );
/* set the specified bit in the Register without interfering the other bits */
error_t setBitReg( const handle_t Handle , const unsigned char Register , \
const unsigned char Position , const unsigned char Value );
/* gives you the 2^Exponent */
unsigned int PowToTwo( unsigned int Exponent);
/* valid address byte for the specified Register
the MSB data bit is set to zero */
unsigned char getAddress( unsigned char Register );
/* set a value in an two byte command*/
void setValue( struct command_t * Command , unsigned char Value);
#if defined(__cplusplus)
} /* extern "C" { */
#endif
#endif /* #if !defined(ATMELLIB_SERIAL_HELPER_H) */
/***************************************************************************************************/
/* */
/* Copyright (C) 2004 Bauhaus University Weimar */
/* Released into the public domain on 6/23/2007 as part of the VRPN project */
/* by Jan P. Springer. */
/* */
/***************************************************************************************************/
/* */
/* module : vrpn_atmel_iobasic.C */
/* project : atmel-avango */
/* description: basic functions for serial io access on the tty */
/* */
/***************************************************************************************************/
//#define VRPN_ATMELLIB_VERBOSE_OUTBIT
//#define VRPN_ATMELLIB_VERBOSE
/* include system headers */
#include <errno.h> // for errno, ENXIO, error_t
#include <stddef.h> // for size_t
#include <stdio.h> // for fprintf, stderr, NULL, etc
#include <string.h> // for strerror
#include <sys/select.h> // for select, FD_SET, FD_ZERO, etc
#include <termios.h> // for tcflush, TCIOFLUSH
#include <unistd.h> // for read, write
/* include i/f header */
#include "vrpn_Shared.h" // for timeval
#include "vrpn_atmellib.h" // for command_t, handle_t, etc
#include "vrpn_atmellib_errno.h" // for ATMELLIB_ERROR_NORESPVAL, etc
/***************************************************************************************************/
/* read data from the tty */
/* returns the bytes read or one of the system wide error codes returned by read */
/***************************************************************************************************/
static int
read_wrapper (handle_t fd, void* buf, size_t len)
{
return read (fd, buf, len);
}
/***************************************************************************************************/
/* write data to the tty: return the byte written or one of the system
wide error codes returned by write */
/***************************************************************************************************/
static int
write_wrapper ( handle_t fd , const void* buf , size_t len )
{
return write (fd , buf , len );
}
/***************************************************************************************************/
/* make a select for lib-wide time and if this is successfully read one byte */
/***************************************************************************************************/
static int
select_read_wrapper(handle_t fd , struct timeval * time)
{
fd_set rdfs;
unsigned char byte;
int ret;
FD_ZERO( &rdfs );
FD_SET(fd , &rdfs);
ret = select( fd+1, &rdfs, NULL, NULL, time);
if (ret<0) {
fprintf(stderr, "select_read_wrapper:: error during select: %s (%i)\n",
strerror(errno) ,errno);
return ATMELLIB_ERROR_NORESPVAL;
}
else if (ret==0) {
// time expired
fprintf(stderr, "vrpn_atmellib::select_read_wrapper: select timed out\n" );
return ATMELLIB_ERROR_NORESPVAL;
}
// successful select -> read out one command
if ((ret = read_wrapper(fd , (void *) (&byte), 1)) <=0 )
return ret;
#ifdef VRPN_ATMELLIB_VERBOSE_OUTBIT
outBit(byte);
#endif
return byte;
}
/***************************************************************************************************/
/* make a select for lib-wide time and if this is successfully read one byte */
/***************************************************************************************************/
static int
select_write_wrapper(handle_t fd , struct timeval * time, unsigned char * data , int len)
{
fd_set wrfs;
int ret;
FD_ZERO( &wrfs );
FD_SET(fd , &wrfs);
ret = select( fd+1, NULL, &wrfs, NULL, time);
if (ret<0) {
fprintf(stderr,
"vrpn_atmellib::select_write_wrapper::error during waiting for writing permission: %s (%i)\n",
strerror(errno) ,errno);
return ATMELLIB_ERROR_NORESPVAL;
}
else if (ret==0) {
// time expired
fprintf(stderr, "vrpn_atmellib::select_write_wrapper: timed out in wrapper\n" );
return ATMELLIB_ERROR_NORESPVAL;
}
// successful select -> write down command
// write twice to ensure that the atmel receives it
//write_wrapper(fd , (void *) data, len);
return write_wrapper(fd , (void *) data, len);
}
/***************************************************************************************************/
/* PART OF THE BASIC INTERFACE: for explainations to the functions see the header file */
/***************************************************************************************************/
/***************************************************************************************************/
/* get the value of one register */
/***************************************************************************************************/
/* extern */ error_t
getCmd (handle_t fd, struct command_t* Cmd)
{
struct timeval time_wait;
int ret;
#ifdef VRPN_ATMEL_SERIAL_VRPN
unsigned char read_val;
#endif
// some adds to measure time for reading out
#ifdef VRPN_ATMELLIB_TIME_MEASURE
struct timeval start;
struct timeval end;
int sec, usec;
vrpn_gettimeofday( &start , 0);
#endif
unsigned char PossibilityOne;
unsigned char PossibilityTwo;
unsigned char Reference;
/* check if the given parameters are valid */
if (handle_invalid(fd))
return ENXIO;
if ((*Cmd).addr < 128)
return ATMELLIB_ERROR_NOCOMVAL;
PossibilityOne = (*Cmd).addr;
PossibilityTwo = (*Cmd).addr;
Reference = 0x01;
if (Reference & PossibilityTwo)
/* the LSB of the Address is 1 -> make 0 -> use XOR operator */
PossibilityTwo ^= Reference;
else
/* the LSB of the address is 0 -> make 1 -> use OR operator */
PossibilityTwo |= Reference;
#ifdef VRPN_ATMEL_SERIAL_VRPN
vrpn_flush_input_buffer(fd);
vrpn_flush_output_buffer(fd);
#else
tcflush( fd , TCIOFLUSH );
#endif
time_wait.tv_sec = VRPN_ATMELLIB_SELECT_WAIT_SEC;
time_wait.tv_usec = VRPN_ATMELLIB_SELECT_WAIT_USEC;
#ifdef VRPN_ATMEL_SERIAL_VRPN
vrpn_write_characters(fd, (&((*Cmd).addr)) , 1);
#else
/* you have to send the address first */
if ( (ret = select_write_wrapper( fd ,
&(time_wait),
(&((*Cmd).addr)) ,
1 ))
!= 1 ) {
fprintf(stderr, "\n vrpn_atmellib::getCmd: Error while writing down. error=%i\n",
ret);
return ret;
}
#endif
while (time_wait.tv_usec!=0) {
#ifdef VRPN_ATMEL_SERIAL_VRPN
if (( vrpn_read_available_characters(fd, &(read_val), 1, &time_wait)) != 1) {
fprintf(stderr, "vrpn_atmellib::getCmd: Error vrpn_read_available_characters for first byte\n");
break;
}
// else
ret = read_val;
#else
if ((ret = select_read_wrapper(fd, &time_wait)) < 0) {
fprintf(stderr, "vrpn_atmellib::getCmd:\
Error select_read_wrapper for first byte: %i\n" , ret);
break;
}
#endif
// found expected first byte
if ((ret==PossibilityOne) || (ret==PossibilityTwo )) {
(*Cmd).addr = ret;
#ifdef VRPN_ATMEL_SERIAL_VRPN
if (( vrpn_read_available_characters(fd, &(read_val), 1, &time_wait)) != 1) {
fprintf(stderr, "vrpn_atmellib::getCmd: Error vrpn_read_available_characters.\n");;
break;
}
//else
ret = read_val;
#else
ret = select_read_wrapper(fd, &time_wait);
#endif
if ((ret < 0) || (ret > 128)) {
fprintf(stderr, "vrpn_atmellib::getCmd: Error reading second byte: %i\n\n" , ret);
break;
}
(*Cmd).value = ret;
#ifdef VRPN_ATMELLIB_TIME_MEASURE
// display time for
vrpn_gettimeofday( &end , 0);
sec=end.tv_sec-start.tv_sec;
usec=end.tv_usec-start.tv_usec;
printf("Time for reading out: sec=%i , usec=%i\n", sec, usec);
#endif
return ATMELLIB_NOERROR;
}
}
return ATMELLIB_ERROR_NORESPVAL;
}
/***************************************************************************************************/
/* write one command to the mc and wait for confirmation */
/***************************************************************************************************/
/* extern */ error_t
setCmd (handle_t fd , struct command_t * Cmd)
{
struct timeval time_wait;
int ret;
#ifdef VRPN_ATMEL_SERIAL_VRPN
unsigned char read_val;
#endif
// some adds to measure time for reading out
#ifdef VRPN_ATMELLIB_TIME_MEASURE
struct timeval start;
struct timeval end;
int sec, usec;
vrpn_gettimeofday( &start , 0);
#endif
/* check if the given parameters are valid */
if (handle_invalid(fd))
return ENXIO;
if ((*Cmd).addr < 128)
return ATMELLIB_ERROR_NOCOMVAL;
time_wait.tv_sec = VRPN_ATMELLIB_SELECT_WAIT_SEC;
time_wait.tv_usec = VRPN_ATMELLIB_SELECT_WAIT_USEC;
#ifdef VRPN_ATMEL_SERIAL_VRPN
vrpn_write_characters(fd, (unsigned char*) Cmd, 2);
#else
if ( (ret = select_write_wrapper( fd ,
&(time_wait),
(unsigned char*) Cmd ,
2 ))
!= 2 ) {
fprintf(stderr, "\n vrpn_atmellib::setCmd: Error while writing down. error=%i\n",
ret);
return ret;
}
#endif
#ifdef VRPN_ATMEL_SERIAL_VRPN
vrpn_flush_input_buffer(fd);
vrpn_flush_output_buffer(fd);
#else
tcflush( fd , TCIOFLUSH );
#endif
while (time_wait.tv_usec!=0) {
#ifdef VRPN_ATMEL_SERIAL_VRPN
if (( vrpn_read_available_characters(fd, &(read_val), 1, &time_wait)) != 1) {
fprintf(stderr, "vrpn_atmellib::setCmd: Error vrpn_read_available_characters.\n");;
break;
}
//else
ret = read_val;
#else
if ((ret = select_read_wrapper(fd, &time_wait)) < 0) {
fprintf(stderr, "vrpn_atmellib::setCmd: Error select_read_wrapper for first byte: %i\n" , ret);
break;
}
#endif
// found expected first byte
if (ret==(*Cmd).addr) {
#ifdef VRPN_ATMEL_SERIAL_VRPN
if (( vrpn_read_available_characters(fd, &(read_val), 1, &time_wait)) != 1) {
printf("Error vrpn_read_available_characters.\n");;
break;
}
//else
ret = read_val;
#else
ret = select_read_wrapper(fd, &time_wait);
#endif
if (ret!=(*Cmd).value) {
printf("vrpn_atmellib::setCmd: Error select_read_wrapper for second byte: %i\n" , ret);
break;
}
#ifdef ATMELLIB_TIME_MEASURE
// display time for
vrpn_gettimeofday( &end , 0);
sec=end.tv_sec-start.tv_sec;
usec=end.tv_usec-start.tv_usec;
printf("Time for writing down: sec=%i , usec=%i\n", sec, usec);
#endif
return ATMELLIB_NOERROR;
}
}
return ATMELLIB_ERROR_NORESPVAL;
}
/* file static for <ident> or <what> */
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
# pragma set woff 1174
#endif
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
# pragma reset woff 1174
#endif
/***************************************************************************************************/
/* */
/* Copyright (C) 2004 Bauhaus University Weimar */
/* Released into the public domain on 6/23/2007 as part of the VRPN project */
/* by Jan P. Springer. */
/* */
/***************************************************************************************************/
/* */
/* module : vrpn_atmellib_openclose.C */
/* project : atmel-avango */
/* description: handle open, close and initalization of the tty */
/* */
/***************************************************************************************************/
/* include system headers */
#include <errno.h> // for ENXIO, error_t
#include <fcntl.h> // for open, O_NOCTTY, O_RDWR
#include <termios.h> // for termios, cfsetispeed, etc
#include <unistd.h> // for close, isatty
/* include i/f header */
#include "vrpn_atmellib.h" // for handle_t, handle_invalid
#include "vrpn_atmellib_errno.h" // for ATMELLIB_NOERROR
/***************************************************************************************************/
/* internal (static) functions */
/*****************************************************************/
/* set the parameter to communicate with the microcontroller */
/*****************************************************************/
static int
Set_Params( handle_t fd , const int baud, struct termios * init_param)
{
struct termios Params;
/* get the actual parameters of the tty */
tcgetattr( fd , &Params );
/* save the init values of the tty */
(*init_param) = Params;
/* wait time for new data */
Params.c_cc[VTIME] = 0;
Params.c_cc[VMIN] = 1;
if (baud==38400) {
Params.c_cflag = B38400 | CSIZE | CS8 | CREAD | CLOCAL | HUPCL;
cfsetospeed( &Params , B38400 );
cfsetispeed( &Params , B38400 );
}
else {
// 9600 baud is default
Params.c_cflag = B9600 | CSIZE | CS8 | CREAD | CLOCAL | HUPCL;
cfsetospeed( &Params , B9600 );
cfsetispeed( &Params , B9600 );
}
Params.c_iflag = (IGNBRK | IGNPAR);
Params.c_lflag = 0;
Params.c_oflag = 0;
/* activate the new settings */
tcsetattr( fd , TCSANOW , &Params );
return ATMELLIB_NOERROR;
}
/***************************************************************************************************/
/* PART OF THE BASIC INTERFACE: for explainations to the functions see the header file */
/***************************************************************************************************/
/***************************************************************************************************/
/* open the specified serial port and set the parameter that it's ready to communicate with the mc*/
/***************************************************************************************************/
/* extern */ handle_t
openPort (const char* tty , const int baud, struct termios * init_param)
{
handle_t fd;
/* try to open thespecified device */
if ( (fd = open( tty , O_RDWR | O_NOCTTY )) < 0)
return fd;
/* check if the open file is a tty */
if (!isatty( fd )) {
close (fd);
return -1;
}
/* set the correct serial parameter to communicate with the microcontroller */
if ( Set_Params( fd , baud, init_param ) < 0 )
{
close (fd);
return -1;
}
return fd;
}
/***************************************************************************************************/
/* close the specified port and reset the parameter to the initial values */
/***************************************************************************************************/
/* extern */ error_t
closePort (handle_t fd , struct termios * init_param)
{
if (handle_invalid(fd))
return ENXIO;
/* first reset the parameters and then close the port */
tcsetattr( fd , TCSADRAIN, init_param );
close( fd );
return ATMELLIB_NOERROR;
}
/* file static for <ident> or <what> */
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
# pragma set woff 1174
#endif
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
# pragma reset woff 1174
#endif
/***************************************************************************************************/
/* */
/* Copyright (C) 2003 Bauhaus University Weimar */
/* Released into the public domain on 6/23/2007 as part of the VRPN project */
/* by Jan P. Springer. */
/* */
/***************************************************************************************************/
/* */
/* module : vrpn_atmellib_register.C */
/* project : atmel-avango */
/* description: function of an easy high level interface for access to the registers */
/* */
/***************************************************************************************************/
/* include system headers */
#include <errno.h> // for ENXIO, error_t
/* include i/f header */
#include "vrpn_atmellib.h" // for command_t, handle_invalid, etc
#include "vrpn_atmellib_errno.h" // for ATMELLIB_ERROR_REGINV, etc
#include "vrpn_atmellib_helper.h" // for getAddress, setValue
/***************************************************************************************************/
/* HIGH LEVEL INTERFACE */
/***************************************************************************************************/
/***************************************************************************************************/
/* write the value of the specified register and wait for confirmation */
/***************************************************************************************************/
/* extern */ error_t
setRegister( handle_t Handle , const unsigned char Register , const unsigned char Value)
{
struct command_t Cmd;
/* check if the arguments are valid */
if (handle_invalid(Handle))
return ENXIO;
if (register_invalid( Register ) != ATMELLIB_NOERROR)
return ATMELLIB_ERROR_REGINV;
/* combine the parameter to a valid commande */
Cmd.addr = getAddress( Register );
setValue( &Cmd , Value );
/* send the command to the microcontroller */
return ( setCmd( Handle , &Cmd ) );
}
/***************************************************************************************************/
/* read out the value of the specified register */
/***************************************************************************************************/
/*extern*/ int
getRegister( handle_t Handle , const unsigned char Register )
{
error_t R;
struct command_t Cmd;
/* check if the arguments are valid */
if (handle_invalid(Handle))
return ENXIO;
if (register_invalid( Register ) == ATMELLIB_ERROR_GENERAL)
return ATMELLIB_ERROR_REGINV;
/* make a valid command */
Cmd.addr = getAddress( Register );
/* Send the command to the microcontroller */
if ( (R = getCmd( Handle , &Cmd )) != ATMELLIB_NOERROR)
return R;
/* get the value */
if ( Cmd.addr & 0x01 ) Cmd.value += 128;
return (Cmd.value);
}
/* file static for <ident> or <what> */
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
# pragma set woff 1174
#endif
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
# pragma reset woff 1174
#endif
/***************************************************************************************************/
/* */
/* Copyright (C) 2004 Bauhaus University Weimar */
/* Released into the public domain on 6/23/2007 as part of the VRPN project */
/* by Jan P. Springer. */
/* */
/***************************************************************************************************/
/* */
/* module : vrpn_atmellib_tester.C */
/* project : atmel-avango */
/* description: functions to test the state */
/* */
/***************************************************************************************************/
/* include system headers */
#include <errno.h> // for error_t
/* include i/f header */
#include "vrpn_atmellib.h" // for handle_t
#include "vrpn_atmellib_errno.h" // for ATMELLIB_ERROR_GENERAL, etc
/***************************************************************************************************/
/* internal (static) variables */
/* define a invalid handle */
const static int invalid_handle = -1;
/***************************************************************************************************/
/* test if the given handler is a valid handle */
/***************************************************************************************************/
/* extern */ error_t
handle_invalid (handle_t handle)
{
return (invalid_handle == handle);
}
/***************************************************************************************************/
/* test if the register is valid - if it exists on the mc */
/***************************************************************************************************/
/* extern */ error_t
register_invalid (unsigned char Register)
{
if (Register > 63) {
return ATMELLIB_ERROR_GENERAL;
}
return ATMELLIB_NOERROR;
}
/* file static for <ident> or <what> */
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
# pragma set woff 1174
#endif
#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
# pragma reset woff 1174
#endif
.depend
make.out
makefile
pc_cygwin
pc_linux
sgi_irix
sparc_solaris
powerpc_aix
*.vcproj.*.user
cmake_minimum_required(VERSION 2.6)
#-----------------------------------------------------------------------------
# XXX Things to make better.
#
# XXX clock_drift_estimator
# Move applications into subprojects in visual studio
# Make the files with ".c" extension also compile as C++.
# Make the c_interface_example work
#-----------------------------------------------------------------------------
# Build the client applications if we've been asked to.
if(VRPN_BUILD_CLIENTS)
if(NOT VRPN_CLIENT_LIBRARY)
message(FATAL_ERROR
"Cannot compile clients without either the client or full library. Enable one and try again.")
endif()
#-----------------------------------------------------------------------------
# Libraries we need to do our thing.
find_package(GLUT)
if(APPLE)
mark_as_advanced(GLUT_cocoa_LIBRARY)
endif()
find_package(OpenGL)
set(CLIENTS_SOURCES
vrpn_print_devices.C
vrpn_print_performance.C
vrpn_print_messages.C
)
set(TEST_SOURCES
add_vrpn_cookie.C
bdbox_client.C
clock_drift_estimator.C
ff_client.C
forcedevice_test_client.cpp
forwarderClient.C
#midi_client.C # XXX TODO No vrpn_Sound_Remote ever defined in this repository
#ohm_client.C # XXX TODO No vrpn_Ohmmeter (vrpn_Ohmmeter.h) defined in this repository
phan_client.C
printcereal.C
printvals.C
sound_client.C
sphere_client.C
testSharedObject.C
test_Zaber.C
test_imager.C
test_mutex.C
text.C
tracker_to_poser.cpp
vrpn_LamportClock.t.C
vrpn_ping.C
)
if(NOT WIN32)
# TODO: These need "open" calls modified to build on win.
list(APPEND
TEST_SOURCES
logfilesenders.C
logfiletypes.C
checklogfile.C)
endif()
###
# Tests
###
if(BUILD_TESTING)
foreach(SOURCE ${TEST_SOURCES})
get_filename_component(APP ${SOURCE} NAME_WE)
add_executable(${APP} ${SOURCE})
target_link_libraries(${APP} ${VRPN_CLIENT_LIBRARY})
set_target_properties(${APP} PROPERTIES FOLDER Tests)
if(VRPN_INSTALL)
install(TARGETS ${APP} RUNTIME DESTINATION bin COMPONENT tests)
endif()
endforeach()
if(GLUT_FOUND AND OPENGL_FOUND)
include_directories(${GLUT_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR})
add_executable(testimager_client testimager_client.C)
target_link_libraries(testimager_client
${VRPN_CLIENT_LIBRARY}
${GLUT_glut_LIBRARY}
${OPENGL_LIBRARIES})
set_target_properties(testimager_client PROPERTIES FOLDER Tests)
if(VRPN_INSTALL)
install(TARGETS
testimager_client
RUNTIME
DESTINATION
bin
COMPONENT
tests)
endif()
option(VRPN_GLUT_IS_STATIC_FREEGLUT
"Is the GLUT used for the imaging test client a static build of FreeGLUT?"
NO)
mark_as_advanced(VRPN_GLUT_IS_STATIC_FREEGLUT)
if(VRPN_GLUT_IS_STATIC_FREEGLUT)
set_property(TARGET
testimager_client
PROPERTY
COMPILE_DEFINITIONS
"FREEGLUT_STATIC")
endif()
endif()
endif()
add_executable(c_interface_example
c_interface_example.c
c_interface.h
c_interface.cpp)
target_link_libraries(c_interface_example ${VRPN_CLIENT_LIBRARY})
set_target_properties(c_interface_example PROPERTIES FOLDER Tests)
if(VRPN_INSTALL)
install(TARGETS
c_interface_example
RUNTIME
DESTINATION
bin
COMPONENT
tests)
endif()
###
# Clients
###
foreach(SOURCE ${CLIENTS_SOURCES})
get_filename_component(APP ${SOURCE} NAME_WE)
add_executable(${APP} ${SOURCE})
target_link_libraries(${APP} ${VRPN_CLIENT_LIBRARY})
set_target_properties(${APP} PROPERTIES FOLDER Clients)
if(VRPN_INSTALL)
install(TARGETS ${APP} RUNTIME DESTINATION bin COMPONENT clients)
endif()
endforeach()
###
# Servers
###
add_executable(run_auxiliary_logger run_auxiliary_logger.C)
target_link_libraries(run_auxiliary_logger ${VRPN_CLIENT_LIBRARY})
set_target_properties(run_auxiliary_logger PROPERTIES FOLDER Servers)
if(VRPN_INSTALL)
install(TARGETS
run_auxiliary_logger
RUNTIME
DESTINATION
bin
COMPONENT
servers)
endif()
endif()
2009-12-15 Russell M. Taylor II <taylorr@cs.unc.edu>
* c_interface_example.cpp : Gets rid of a compiler warning.
2009-12-15 Russell M. Taylor II <taylorr@cs.unc.edu>
* CmakeLists.txt : Improvements by Ryan Pavlik to the Cmake files that
make them cleaner and use more modern constructions. Also various
bug fixes to make code compile on a number of architectures.
* bdbox_client.C : Compiles with modern VRPN.
* logfilesenders.c : Compiles on all architectures.
* logfiletypes.c : Same.
* testimager_client.C : Compiles on Apple.
* tracker_to_poser.cpp : Compiles on all architectures.
2009-11-27 Russell M. Taylor II <taylorr@cs.unc.edu>
* CMakeLists.txt : Turning off testimager_client on all but Windows.
* testimager_client.C : Removing declarations that aren't needed but that
only worked on Windows.
2009-11-23 Russell M. Taylor II <taylorr@cs.unc.edu>
* ff_client.C : Picking lint found by a new compiler (const declarations and
printf format descriptions.
* phan_client.C : Same.
* printceral.C : Same.
* sphere_client.C : Same.
* text.C : Same.
* vrpn_print_devices.C : Same.
2009-11-21 Russell M. Taylor II <taylorr@cs.unc.edu>
* CMakeLists.txt : File to describe to the Cmake build system how
to compile VRPN.
* ff_client.C : Upgrade to compile on Windows with recent VRPN.
* phan_client.C : same.
* testSharedObject.C : same.
* text.C : same.
* vrpn_ping.C : same.
2009-11-12 Russell M. Taylor II <taylorr@cs.unc.edu>
* sound_client.c : Fixed it so that it compiles. There must
have been an inadvertent cutting out of some lines in
the code.
2009-09-24 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Turned "-g" flag into "$(DEBUG_FLAGS)" throughout.
2009-07-20 Russell M. Taylor II <taylorr@cs.unc.edu>
* run_auxiliary_logger.C : Added a test program that
lets you connect and ask for a log file for some
duration.
* run_auxiliary_logger.dsp : Same.
* run_auxiliary_logger.vcproj : Same.
2009_06_16 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Removed UNC-specific include and library paths.
2009_04_17 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Patch from Hans Lambermont to make it compile under Linux.
* test_imager.C : Same.
2009_03_07 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Added entry to compile a C-interface example program.
* c_interface.cpp : Code to provide a C interface to remote classes.
* c_interface.h : Same.
* c_interface_example.c : Example C program using the interface.
2009_01_21 Russell M. Taylor II <taylorr@cs.unc.edu>
* forcedevice_test_client.vcproj : Making it compile with quatlib
in expected location.
* sphere_client.vcproj : Same.
* vrpn_print_devices.C : Removed limit on the number of sensors per
tracker. Now uses a vector to keep track of counts, which
can add more until we run out of memory.
2008_07_02 Russell M. Taylor II <taylorr@cs.unc.edu>
* vrpn_print_devices.C : Has the code not preload or
accumulate in case of reading from a file.
2008_03_04 Russell M. Taylor II <taylorr@cs.unc.edu>
* clock_drift_estimator.C : Replaces vrpn_Connection
constructor with call to vrpn_create_server_connection()
* test_imager.C : Same.
* testimager_client.C : Whitespace changes
* vrpn_print_devices.C : Added Text_Receiver to the objects
being created, so you can print out text messages from an
object as well.
2007-12-13 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Has VRPN fileconnections neither preload
nor accumulate in case we open a logfile to read the
device.
2007-08-05 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Fixed a race-condition bug at startup that
would cause a crash when a Glut function was called before
Glut was initialized.
2007-06-28 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Added linking with pthreads because of vrpn_Thread class.
2007-06-19 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Adding patch submitted by Patrick Hartling from
Infiscape.com for making this compile on MacOSX
to create universal binaries.
2007-03-17 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Adding a build environment for cross-compiling to
ARM from PCs running Cygwin
2007-03-03 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Making this code compile under pc_linux_arm.
2006-10-04 Russell M. Taylor II <taylorr@cs.unc.edu>
* clock_drift_estimator.vcproj : Updated to use the August 2006 version
of the DirectX SDK and the Microsoft Platform SDK
for Windows Server 20003 R2.
* forcedevice_test_client.vcproj : Same.
* printcerial.vcproj : Same.
* printvals.vcproj : Same.
* sphere_client.vcproj : Same.
* test_imager.vcproj : Same.
* test_zaber.vcproj : Same.
* testimager_client.vcproj : Same.
* tracker_to_poser.vcproj : Same.
* vrpn_print_devices.vcproj : Same.
2006-08-23 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : It now renders when it gets the
end of a frame, which helps reduce the tearing in the
video being displayed.
2006-07-12 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Adding a call to make the connection limit
the number of messages it will handle before returning control
to the application. This prevents the server from choking the
whole program by continually filling the network with packets.
2006-06-21 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Added install and uninstall.
2006-03-12 Russell M. Taylor II <taylorr@cs.unc.edu>
* *.vcproj : Visual C++ 2005 project files for VRPN.
2006-02-17 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Switched to the more standard
GL/glut.h for the include.
* testimager_client.dsp : Modified so that it looks in
the NSRG buildime rather than a nearby local
directory.
2005-10-17 Russell M. Taylor II <taylorr@cs.unc.edu>
* forcedevice_test_client.cpp : Modified to also include the
presentation of a cube using the triangle interface.
2005-10-04 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Added target for 64-bit Intel-based SGI compilation.
2005-09-22 Russell M. Taylor II <taylorr@cs.unc.edu>
* forcedevice_test_client.C : Modified to only put
in normalized directions.
2005-08-23 Russell M. Taylor II <taylorr@cs.unc.edu>
* clock_drift_estimator.C : Diff went crazy, so it is hard to
tell. Newer version.
2005-08-10 Ben Wilde <wilde@cs.unc.edu>
* forcedevice_test_client.cpp
-Added tests for the line and plane constraints. The plane
seems to work fine, but the line constraint has a strange
behavior. Either due to poor implementation or vrpn problem.
2005-07-23 Russell M. Taylor II <taylorr@cs.unc.edu>
* clock_drift_estimator.C : Application to estimate the drift between
the local machine's clock and another machine's clock using
the PING/PONG response from an arbitrary server object.
* clock_drift_estimator.dsp : Project file for this.
2005-07-08 Russell M. Taylor II <taylorr@cs.unc.edu>
* forcedevice_test_client.cpp : Deleted objects before exiting.
* phan_client.C : Same.
* sphere_client.C : Same.
2005-07-08 Russell M. Taylor II <taylorr@cs.unc.edu>
* printcereal.dsp : Added include directories on $(SYSTEMDRIVE)
and lib directories also on $(SYSTEMDRIVE) so that the
apps can build correctly with only edits in the
vrpn_Configure.h file if things are installed in standard
locations.
* forcedevice_test_client.dsp : Same.
* printvals.h : Same.
* setrouter.dsp : Same.
* test_imager.dsp : Same.
* test_zaber.dsp : Same.
* testimager_client.dsp : Same.
* tracker_to_poser.dsp : Same.
* vrpn_Router_Client_GUI.dsp : Same.
* vrpn_print_devices.dsp : Same.
2005-07-06 Russell M. Taylor II <taylorr@cs.unc.edu>
* clock_client.C : Removed.
* vrpnTrackerClient.cpp : Same.
* printcereal.C : Removed Synchronized.
* printvals.c : Same.
* sound_client.c : same.
* test_imager.C : Deleted objects that had been created, to
avoid reference-count warning at the end.
2005-04-07 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Clears image to black so that
anything not filled in has a definite value.
2005-02-25 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Removed -LANG:std from compile, no streams
used in the code anymore.
2005-02-01 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Added John Stone's definitions to make
things compile under 64-bit Linux.
2005-01-11 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Modified to handle red, green,
blue channels from client.
2004-12-14 Russell M. Taylor II <taylorr@cs.unc.edu>
* vrpnTrackerClient.cpp : Fixed compiler warnings.
2004-12-07 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Swapped out test_tempimager for test_imager.
* test_imager.dsp : Same.
* test_imager.C : Same.
* test_tempimager.dsp : Same.
* test_tempimager.C : Same.
2004-12-07 Russell M. Taylor II <taylorr@cs.unc.edu>
* Modified to use vrpn_Imager rather than vrpn_TempImager.
2004-11-03 Russell M. Taylor II <taylorr@cs.unc.edu>
* Happy Birthday to me!
* Makefile : Added John Stone's additions to make it compile on
64-bit Solaris
2004-09-16 Russell M. Taylor II <taylorr@cs.unc.edu>
Adding Chris VanderKnyff's changes that enable DLL linkage
for applications. Heading towards enabling C# and other language
support.
* forcedevice_test_client.cpp : Adding VRPN_CALLBACK.
* printcereal.C : same.
* printvals.C : same.
* sphere_client.C : same.
* test_Zaber.C : same.
* test_tempimager.C : same.
* testimager_client.C : same.
* tracker_to_poser.cpp : same.
* vrpn_Router_Client_GUI.C : same.
* vrpn_print_devices.C : same.
* forcedevice_test_client.dsp : Making it depend on the project
that causes both VRPN and VRPNDLL projects to be built, rather
than on VRPN. If you try to make it depend on both
VRPN and VRPNDLL, you get linking trouble.
* printcereal.dsp : same.
* printvals.dsp : same.
* setrouter.dsp : same.
* sphere_client.dsp : same.
* test_tempimager.dsp : same.
* test_zaber.dsp : same.
* testimager_client.dsp : same.
* tracker_to_poser.dsp : same.
* vrpn_Router_Client_GUI.dsp : same.
* vrpn_print_devices.dsp : same.
2004-09-15 Russell M. Taylor II <taylorr@cs.unc.edu>
* forcedevice_test_client.dsp : Changing code generation back to
DLL-based for all classes, like it was supposed to be in
the first place. Confusion over the cause for a crash led
us to incorrectly change it before.
* printcereal.dsp : Same.
* printvals.dsp : Same.
* setrouter.dsp : Same.
* sphere_client.dsp : Same.
* test_tempimager.dsp : Same.
* test_zaber.dsp : Same.
* testimager_client.dsp : Same.
* tracker_to_poser.dsp : Same.
* vrpn_Router_Client_GUI.dsp : Same.
* vrpn_print_devices.dsp : Same.
2004-08-31 Russell M. Taylor II <taylorr@cs.unc.edu>
* forcedevice_test_client.dsp : Changing code generation to use
multithreaded non-DLL for both debug and release. This turns
out to have always been the proper setting to use.
Unfortunately, all apps have to be rebuild with new settings,
and all libraries have to use the same setting.
* printcereal.dsp : Same.
* printvals.dsp : Same.
* setrouter.dsp : Same.
* sphere_client.dsp : Same.
* test_tempimager.dsp : Same.
* test_zaber.dsp : Same.
* testimager_client.dsp : Same.
* tracker_to_poser.dsp : Same.
* vrpn_Router_Client_GUI.dsp : Same.
* vrpn_print_devices.dsp : Same.
2004-08-06 Russell M. Taylor II <taylorr@cs.unc.edu>
* printcereal.C : Removed references to objects that were never
created.
2004-07-27 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Adding build rule for .cpp (Horrible Windows extension
that is the same as the default rule in Unix for running the
C-pre-processor). Adding rule to build force test client.
* forcedevice_test.client.cpp : Removing unused variables.
2004-07-22 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Changed default port number.
* test_force_device_client.cpp : Test program for vrpn_ForceDevice/
* test_force_device_client.dsp : Project file to build this.
2004-05-23 Russell M. Taylor II <taylorr@cs.unc.edu>
* tracker_to_poser.cpp : Can specify name of tracker and poser
on command line.
2004-05-22 Russell M. Taylor II <taylorr@cs.unc.edu>
* client_to_poser.cpp : New application to read from tracker
and send to poser.
* client_to_poser.dsp : Project file for this app.
2004-04-08 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Adding flag to SGI compile in the hope that it would
fix things and let us use the new streams libraries. It
got us part of the way there on my system.
* clock_client.C : Added Patrick Hartling's changes to make VRPN
compile with Visual Studio.NET, which required switching to
new streams, which required retrofitting SGIs to use old
streams (using yet another define in vrpn_Configure.h).
* test_tempimager.C : same.
* vrpnTrackerClient.cpp : Same.
* vrpn_LamportClock.t.C : Same.
2004-04-07 Russell M. Taylor II <taylorr@cs.unc.edu>
* test_Zaber.C : Using vrpn_gettimeofday() not gettimeofday().
* testimager_client.C : Same.
* vrpn_ping.C : Same.
* vrpn_print_devices.C : Same.
2003-12-08 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Added #ifdef-ed out line to save log.
2003-07-24 Matt McCallus <mccallus@cs.unc.edu>
* sound_client.c : white space, include path removed.
2003-05-05 Russell M. Taylor II <taylorr@cs.unc.edu>
* printcereal.C : main() now returns int like it should.
* printvals.C : Same.
* sphere_clien.C : Same.
* test_Zaber.C : Same.
* test_tempimager.C : Uses new interface to TempImager.
* test_tempimager.dsp : Release version compiles now.
* test_zaber.dsp : Same.
2002-12-06 Russell M. Taylor II <taylorr@cs.unc.edu>
* printcereal.dsp : DSP files have been modified to not do definitions
of VRPN_NO_STREAMS and other constants directly, rather these
are now set by editing vrpn_Configure.h. Also, made projects
compile in both debug and release versions.
* printvals.dsp : Same.
* setrouter.dsp : Same.
* sphere_client.dsp : Same.
* test_zaber.dsp : Same.
* vrpn_Router_Client_GUI.dsp : Same.
* vrpn_print_devices.dsp : Same.
* testimager_client.C : Comment change.
2002-11-24 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Modified to use new vrpn_Tempimager class.
* testimager_client.dsp : Made os that Release version can be built
and is stored in the correct place.
2002-10-30 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Only post redisplay to Glut once before it
actually calls the display function. Otherwise, the calls
bunch up and the application even stops responding to windows
events.
* test_tempimager.dsp : Enables build for Release.
* test_zaber.dsp : Same.
* testimager_client.dsp : Same.
2002-10-14 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Scales faster, puts in more timing info.
2002-09-27 Russell M. Taylor II <taylorr@cs.unc.edu>
* testimager_client.C : Displays TempImager server output in OpenGL/Glut.
* testimager_client.dsp : Project file for testimager_client.C.
2002-09-13 Russell M. Taylor II <taylorr@cs.unc.edu>
* test_Zaber.C : Modified to use vrpn_Analog_Output. Not tested.
2002-09-07 Russell M. Taylor II <taylorr@cs.unc.edu>
* test_tempimager.C : Test file for TempImager class.
* test_tempimager.dsp : build file.
* Makefile : same.
2002-07-09 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Removing seldom-used clients that don't compile on
all architectures.
2002-07-08 Russell M. Taylor II <taylorr@cs.unc.edu>
* vrpn_print_devices.C : Added handlers for velocity and
acceleration to the tracker device.
2002-05-06 Russell M. Taylor II <taylorr@cs.unc.edu>
* haptic : New directory with examples of using a Phantom.
2002-05-03 Russell M. Taylor II <taylorr@cs.unc.edu>
* test_Zaber.C : Program to joj the Zaber back and forth once we have gotten
a response to see where it is.
* vrpn_zaber.dsp : Build file to make the test program.
2001-11-10 Russell M. Taylor II <taylorr@cs.unc.edu>
* vrpn_print_devices.C : Modify to compile under Windows CE development environment.
2001-06-26 Russell M. Taylor II <taylorr@cs.unc.edu>
* vrpn_print_devices.C : Updates to use cleaner Tracker code.
2001-06-02 Russell M. Taylor II <taylorr@cs.unc.edu>
* vrpn_print_devices.C : Program to print all message types from a list
of devices (Tracker, Button, Analog, Dial).
* Makefile : Changed to include building the new application.
2001-04-26 Russell M. Taylor II <taylorr@cs.unc.edu>
* sound_client.c : Changed to compile with more recent version.
2001-04-19 Adam Seeger <seeger@cs.unc.edu>
* phan_client.C, sphere_client.C (main): added while-loop to wait until
the connection is established before sending commands
2001-02-17 Tom Hudson <hudson@cs.unc.edu>
* printvals.c (main) : remove code to Usage(), change command-line
parameters to work with new logging methods.
(init) : work with new logging methods.
(Usage) : new function.
2000-11-06 Russell M. Taylor II <taylorr@cs.unc.edu>
* printvals.c (handle_cntl_c) : The ^C handler in Windows is
multi-threaded, which means it is busy tearing down
the connections while the main loop is still going.
This fixes it so that a flag is set and the main thread
does the shutdown.
2000-10-18 Tom Hudson <hudson@cs.unc.edu>
* printvals.c (init) : sometimes use vrpn_DelayedConnection instead
of a straight vrpn_(Synchronized_)Connection
(Usage) : new option -delay
(main) : parse new option -delay, fix set of redundant
transmission time
(handle_gotConnection) : fix set of redundant transmission time
2000-10-17 Tom Hudson <hudson@cs.unc.edu>
* printvals.c (handle_gotConnection) : new function
(init) : register handle_gotConnection
2000-10-16 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Added vrpn_ping test program
2000-10-11 Tom Hudson <hudson@cs.unc.edu>
* printvals.c : add vrpn_RedundantRemote, global parameters
(init) : create vrpn_RedundantRemote
(main) : add parameters -quiet, -red
2000-09-13 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Added vrpn_ping compilation
* vrpn_ping.C : New file
2000-09-12 Tom Hudson <hudson@cs.unc.edu>
* testSharedObject : added more complete test of features
2000-08-24 Russell M. Taylor II <taylorr@cs.unc.edu>
* Makefile : Added AIX compile
2000-08-24 Russell M. Taylor II <taylorr@cs.unc.edu>
* setrouter : New file
* vrpn_Router_Client_GUI : New file
* Makefile : Added two router test clients, one of which uses GLUT
2000-08-12 Russell M. Taylor II <taylorr@cs.unc.edu>
* printcereal.C (handle_control_C) : fixed deletion bug
# Couldn't understand or usefully modify the former makefile.
# Copied the one from ../server_src here and put the former one
# in Makefile.old
##########################
# common definitions. For non-UNC sites, uncomment one of the lines
# that defines hw_os for the machine you are on in the section just
# below. Then, the code should compile in your environment.
#
#HW_OS := sgi_irix
#HW_OS := sparc_solaris
#HW_OS := sparc_solaris_64
#HW_OS := hp700_hpux10
#HW_OS := pc_linux
HW_OS := pc_linux64
#HW_OS := pc_linux_ia64
# Try using this to cross-compile for ARM on a PC running Linux
#HW_OS := pc_linux_arm
# Try using this to cross-compile for ARM on a PC running Cygwin
#HW_OS := pc_cygwin_arm
#HW_OS := pc_cygwin
#HW_OS := pc_FreeBSD
#HW_OS := powerpc_aix
#HW_OS := powerpc_macosx
#HW_OS := universal_macosx
#HW_OS := macosx_32_64
#HW_OS := macosx_64
##########################
INSTALL_DIR := /usr/local
BIN_DIR := $(INSTALL_DIR)/bin
INCLUDE_DIR := $(INSTALL_DIR)/include
LIB_DIR := $(INSTALL_DIR)/lib
ifndef HW_OS
# hw_os does not exist on FreeBSD at UNC
UNAME := $(shell uname -s)
ifeq ($(UNAME), FreeBSD)
HW_OS := pc_FreeBSD
else
# pc_cygwin doesn't have HW_OS
ifeq ($(UNAME), CYGWIN_NT-4.0)
HW_OS := pc_cygwin
else
ifeq ($(UNAME), CYGWIN_98-4.10)
HW_OS := pc_cygwin
else
HW_OS := $(shell hw_os)
endif
endif
endif
endif
# check if its for pxfl
ifdef PBASE_ROOT
HW_OS := hp_flow
ifeq ($(PXFL_COMPILER), aCC)
HW_OS = hp_flow_aCC
endif
endif
CC := g++
ARCH_LIBS := -lpthread -lquat -lm
ifeq ($(HW_OS),pc_linux)
CC := g++
endif
ifeq ($(HW_OS),pc_linux_ia64)
CC := g++
endif
ifeq ($(HW_OS), pc_linux_arm)
CC := arm-linux-g++
RANLIB := arm-linux-ranlib
AR := arm-linux-ar ruv
endif
ifeq ($(HW_OS), pc_cygwin_arm)
CC := arm-unknown-linux-gnu-g++
RANLIB := arm-unknown-linux-gnu-ranlib
AR := arm-unknown-linux-gnu-ar ruv
endif
ifeq ($(HW_OS),pc_linux64)
CC := g++ -m64
endif
ifeq ($(HW_OS),sgi_irix)
ifndef SGI_ABI
SGI_ABI := n32
endif
ifndef SGI_ARCH
SGI_ARCH := mips3
endif
OBJECT_DIR_SUFFIX := .$(SGI_ABI).$(SGI_ARCH)
CC := CC -$(SGI_ABI) -$(SGI_ARCH)
GLUTLIBS := -lglut -lGLU -lGL -lXmu -lXext -lX11
endif
ifeq ($(HW_OS),hp700_hpux10)
CC := CC +a1
endif
ifeq ($(HW_OS), hp_flow_aCC)
CC := /opt/aCC/bin/aCC
endif
ifeq ($(HW_OS),sparc_solaris)
CC := /opt/SUNWspro/bin/CC
ARCH_LIBS := -lsocket -lnsl $(ARCH_LIBS)
endif
ifeq ($(HW_OS),sparc_solaris_64)
CC := /opt/SUNWspro/bin/CC -xarch=v9a
AR := /opt/SUNWspro/bin/CC -xarch=v9a -xar -o
ARCH_LIBS := -lsocket -lnsl $(ARCH_LIBS)
endif
ifeq ($(HW_OS),powerpc_aix)
# CC := /usr/ibmcxx/bin/xlC_r -g -qarch=pwr3 -w -+
CC := /usr/ibmcxx/bin/xlC_r $(DEBUG_FLAGS) -qarch=pwr3 -w -+
endif
ifeq ($(HW_OS),pc_cygwin)
ARCH_LIBS := -lquat -lcygwin -luser32 -lgdi32 -lcomdlg32 -lwsock32
endif
#CFLAGS = -I../ -I../quat -g
override CFLAGS := -I../ -I../quat $(DEBUG_FLAGS) $(CFLAGS)
override CXXFLAGS := -I../ -I../quat $(DEBUG_FLAGS) $(CXXFLAGS)
.SUFFIXES: .cpp
.c.o:
$(CC) $(CFLAGS) -c $*.c
.C.o:
$(CC) $(CXXFLAGS) -c $*.C
.cpp.o:
$(CC) $(CXXFLAGS) -c $*.cpp
OBJ_DIR := $(HW_OS)$(OBJECT_DIR_SUFFIX)
LIB_DIR := ../$(OBJ_DIR)
#LFLAGS = -g -L$(LIB_DIR) -L../quat/$(HW_OS)$(OBJECT_DIR_SUFFIX)
override LFLAGS := -L$(LIB_DIR) -L../quat/$(HW_OS)$(OBJECT_DIR_SUFFIX) $(DEBUG_FLAGS) $(LDFLAGS)
$(OBJ_DIR)/%.o: %.c
@[ -d $(OBJ_DIR) ] || mkdir -p $(OBJ_DIR)
$(CC) $(CFLAGS) -o $@ -c $<
$(OBJ_DIR)/%.o: %.C
@[ -d $(OBJ_DIR) ] || mkdir -p $(OBJ_DIR)
$(CC) $(CXXFLAGS) -o $@ -c $<
$(OBJ_DIR)/%.o: %.cpp
@[ -d $(OBJ_DIR) ] || mkdir -p $(OBJ_DIR)
$(CC) $(CXXFLAGS) -o $@ -c $<
INSTALL_APPS := vrpn_print_devices forcedevice_test_client vrpn_ping \
add_vrpn_cookie vrpn_print_performance vrpn_print_messages
APPS := $(INSTALL_APPS) printvals printcereal checklogfile logfilesenders \
logfiletypes text forwarderClient bdbox_client ff_client phan_client \
sphere_client bdbox_client test_mutex test_imager c_interface_example
all: $(APPS)
.PHONY: vrpn_print_devices
vrpn_print_devices: $(OBJ_DIR)/vrpn_print_devices
.PHONY: vrpn_print_messages
vrpn_print_messages: $(OBJ_DIR)/vrpn_print_messages
.PHONY: vrpn_print_performance
vrpn_print_performance: $(OBJ_DIR)/vrpn_print_performance
.PHONY: forcedevice_test_client
forcedevice_test_client: $(OBJ_DIR)/forcedevice_test_client
.PHONY: printvals
printvals: $(OBJ_DIR)/printvals
.PHONY: printcereal
printcereal: $(OBJ_DIR)/printcereal
.PHONY: checklogfile
checklogfile: $(OBJ_DIR)/checklogfile
.PHONY: bdbox_client
bdbox_client: $(OBJ_DIR)/bdbox_client
.PHONY: ff_client
ff_client: $(OBJ_DIR)/ff_client
.PHONY: phan_client
phan_client: $(OBJ_DIR)/phan_client
.PHONY: sphere_client
sphere_client: $(OBJ_DIR)/sphere_client
.PHONY: forwarderClient
forwarderClient: $(OBJ_DIR)/forwarderClient
.PHONY: add_vrpn_cookie
add_vrpn_cookie: $(OBJ_DIR)/add_vrpn_cookie
.PHONY: testSharedObject
testSharedObject: $(OBJ_DIR)/testSharedObject
.PHONY: vrpn_ping
vrpn_ping: $(OBJ_DIR)/vrpn_ping
.PHONY: testLamport
testLamport: $(OBJ_DIR)/testLamport
.PHONY: test_mutex
test_mutex: $(OBJ_DIR)/test_mutex
.PHONY: test_imager
test_imager: $(OBJ_DIR)/test_imager
.PHONY: c_interface_example
c_interface_example: $(OBJ_DIR)/c_interface_example
.PHONY: text
text: $(OBJ_DIR)/text
$(OBJ_DIR)/sound_client: $(OBJ_DIR)/sound_client.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/sound_client \
$(OBJ_DIR)/sound_client.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/vrpn_print_messages: $(OBJ_DIR)/vrpn_print_messages.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/vrpn_print_messages \
$(OBJ_DIR)/vrpn_print_messages.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/printvals: $(OBJ_DIR)/printvals.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/printvals \
$(OBJ_DIR)/printvals.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/vrpn_print_devices: $(OBJ_DIR)/vrpn_print_devices.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/vrpn_print_devices \
$(OBJ_DIR)/vrpn_print_devices.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/vrpn_print_messages: $(OBJ_DIR)/vrpn_print_messages.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/vrpn_print_messages \
$(OBJ_DIR)/vrpn_print_messages.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/vrpn_print_performance: $(OBJ_DIR)/vrpn_print_performance.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/vrpn_print_performance \
$(OBJ_DIR)/vrpn_print_performance.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/printcereal: $(OBJ_DIR)/printcereal.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/printcereal \
$(OBJ_DIR)/printcereal.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/bdbox_client: $(OBJ_DIR)/bdbox_client.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/bdbox_client \
$(OBJ_DIR)/bdbox_client.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/ff_client: $(OBJ_DIR)/ff_client.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/ff_client \
$(OBJ_DIR)/ff_client.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/forcedevice_test_client: $(OBJ_DIR)/forcedevice_test_client.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/forcedevice_test_client \
$(OBJ_DIR)/forcedevice_test_client.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/phan_client: $(OBJ_DIR)/phan_client.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/phan_client \
$(OBJ_DIR)/phan_client.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/sphere_client: $(OBJ_DIR)/sphere_client.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/sphere_client \
$(OBJ_DIR)/sphere_client.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/listen_client: $(OBJ_DIR)/listen_client.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/listen_client \
$(OBJ_DIR)/listen_client.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/text: $(OBJ_DIR)/text.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/text \
$(OBJ_DIR)/text.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/forwarderClient: $(OBJ_DIR)/forwarderClient.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/forwarderClient \
$(OBJ_DIR)/forwarderClient.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/checklogfile: $(OBJ_DIR)/checklogfile.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/checklogfile \
$(OBJ_DIR)/checklogfile.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/add_vrpn_cookie: $(OBJ_DIR)/add_vrpn_cookie.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/add_vrpn_cookie \
$(OBJ_DIR)/add_vrpn_cookie.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/testSharedObject: $(OBJ_DIR)/testSharedObject.o \
$(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/testSharedObject \
$(OBJ_DIR)/testSharedObject.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/vrpn_ping: $(OBJ_DIR)/vrpn_ping.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/vrpn_ping \
$(OBJ_DIR)/vrpn_ping.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/testLamport: $(OBJ_DIR)/vrpn_LamportClock.t.o \
$(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/testLamport \
$(OBJ_DIR)/vrpn_LamportClock.t.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/test_mutex: $(OBJ_DIR)/test_mutex.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/test_mutex \
$(OBJ_DIR)/test_mutex.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/test_imager: $(OBJ_DIR)/test_imager.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/test_imager \
$(OBJ_DIR)/test_imager.o -lvrpn $(ARCH_LIBS)
$(OBJ_DIR)/c_interface_example: $(OBJ_DIR)/c_interface_example.o $(OBJ_DIR)/c_interface.o $(LIB_DIR)/libvrpn.a
$(CC) $(LFLAGS) -o $(OBJ_DIR)/c_interface_example \
$(OBJ_DIR)/c_interface_example.o $(OBJ_DIR)/c_interface.o -lvrpn $(ARCH_LIBS)
# These utilities actually DON'T use libvrpn
$(OBJ_DIR)/logfilesenders: $(OBJ_DIR)/logfilesenders.o
$(CC) $(LFLAGS) -o $(OBJ_DIR)/logfilesenders \
$(OBJ_DIR)/logfilesenders.o
$(OBJ_DIR)/logfiletypes: $(OBJ_DIR)/logfiletypes.o
$(CC) $(LFLAGS) -o $(OBJ_DIR)/logfiletypes $(OBJ_DIR)/logfiletypes.o
install: all
-mkdir -p $(BIN_DIR)
( cd $(BIN_DIR) ; rm -f $(INSTALL_APPS) )
( cd $(OBJ_DIR) ; cp $(INSTALL_APPS) $(BIN_DIR) )
( cd $(BIN_DIR) ; strip $(INSTALL_APPS) )
uninstall:
( cd $(BIN_DIR) ; rm -f $(INSTALL_APPS) )
clean:
rm -f $(OBJ_DIR)/*
$(LIB_DIR)/libvrpn.a:
#include <stdio.h> // for fprintf, fclose, fopen, etc
#include <stdlib.h> // for exit
#include <vrpn_Connection.h> // for vrpn_cookie_size, etc
static const char DESC[] = "Reads a vrpn log; writes out the same log with a (current-version) "
"magic cookie in front.";
// TODO:
// Smart checking of command-line arguments
// Check to see if there's already a magic cookie there.
// ? Allow the user to specify cookie version inserted (non-current)
void Usage (char * name) {
fprintf(stderr, "%s\n", DESC);
fprintf(stderr, "Usage: %s <input filename> <output filename>\n",
name);
}
int main (int argc, char ** argv) {
FILE * f_in;
FILE * f_out;
char magicbuf [733]; // HACK
char a;
char * in_name;
char * out_name;
int final_retval = 0;
int retval;
// parse command line arguments
if (argc != 3) {
Usage(argv[0]);
exit(0);
}
in_name = argv[1];
out_name = argv[2];
f_in = fopen(in_name, "rb");
if (!f_in) {
fprintf(stderr, "Couldn't open input file %s.\n", in_name);
exit(0);
}
// check to see if f_out exists
f_out = fopen(out_name, "rb");
if (f_out) {
fprintf(stderr, "Output file \"%s\" already exists.\n", out_name);
fclose(f_in);
exit(0);
}
f_out = fopen(out_name, "wb");
if (!f_out) {
fprintf(stderr, "Couldn't open output file (%s).\n", out_name);
fclose(f_in);
exit(0);
}
retval = write_vrpn_cookie(magicbuf, vrpn_cookie_size() + 1,
vrpn_LOG_NONE);
if (retval < 0) {
fprintf(stderr, "vrpn_Connection::close_log: "
"Couldn't create magic cookie.\n");
goto CLEANUP;
}
retval = static_cast<int>(fwrite(magicbuf, 1, vrpn_cookie_size(), f_out));
if (retval != vrpn_cookie_size()) {
fprintf(stderr, "vrpn_Connection::close_log: "
"Couldn't write magic cookie to log file "
"(got %d, expected %d).\n",
retval, static_cast<int>(vrpn_cookie_size()));
goto CLEANUP;
}
while (!final_retval && !feof(f_in)) {
a = fgetc(f_in);
fputc(a, f_out);
}
CLEANUP:
fclose(f_out);
fclose(f_in);
}
// test client for sgi button/dial box
/*
button layout:
00 01 02 03
04 05 06 07 08 09
10 11 12 13 14 15
16 17 18 19 20 21
22 23 24 25 26 27
28 29 30 31
dial layout:
06 07
04 05
02 03
00 01
*/
#include <stdio.h> // for printf, NULL
#include <vrpn_Analog.h> // for vrpn_ANALOGCB, etc
#include <vrpn_Button.h> // for vrpn_BUTTONCB, etc
#include "vrpn_Configure.h" // for VRPN_CALLBACK
#include "vrpn_Types.h" // for vrpn_float64
/*
// this is the one in the PIT area
#define BDBOX_SERVER "sgibox0@x-vrsh://152.2.128.163/~seeger/src/vrpn/server_src/sgi_irix/vrpn_server,-f,~seeger/src/config/sgibox.cfg,-q"
*/
#define BDBOX_SERVER "sgibox0@x-vrsh://nano//net/nano/nano1/bin/vrpn_server,-f,/net/nano/nano1/config/sgibdbox.cfg,-q,4501,>/dev/null"
/*****************************************************************************
*
Callback handler
*
*****************************************************************************/
void VRPN_CALLBACK handle_button_change(void *userdata, const vrpn_BUTTONCB b)
{
static int count=0;
static int buttonstate = 1;
if (b.state != buttonstate) {
printf("button #%d is in state %d\n", b.button, b.state);
buttonstate = b.state;
count++;
}
if (count > 20) {
*(int*)userdata = 1;
}
}
void VRPN_CALLBACK handle_dial_change(void *userdata, const vrpn_ANALOGCB info)
{
static double channel_values[vrpn_CHANNEL_MAX];
static bool initialized = false;
int i;
if (!initialized) {
for (i = 0; i < vrpn_CHANNEL_MAX; i++) {
channel_values[i] = 0.0;
}
initialized = true;
}
for (i = 0; i < info.num_channel; i++){
if (channel_values[i] != info.channel[i]) {
printf("dial #%d has value %f\n", i, (float)(info.channel[i]));
}
channel_values[i] = info.channel[i];
}
}
int main(int argc, char *argv[])
{
int done = 0;
vrpn_Analog_Remote *bd_dials;
vrpn_Button_Remote *bd_buttons;
printf("Connecting to sgi button/dial box:\n" BDBOX_SERVER "\n");
// initialize the buttons
bd_buttons = new vrpn_Button_Remote(BDBOX_SERVER);
bd_buttons->register_change_handler(&done, handle_button_change);
// initialize the dials
bd_dials = new vrpn_Analog_Remote(BDBOX_SERVER);
bd_dials->register_change_handler(NULL, handle_dial_change);
// main loop
while (!done ){
bd_dials->mainloop();
bd_buttons->mainloop();
}
} /* main */
/* Example of providing an interface to VRPN client-side objects through C.
* Initially made to handle the Tracker and Button objects, for the purpose
* of connecting to a Spaceball through Fortran. If you know how to link
* C and C++ code into Fortran, then you should be able to use it to link.
* (Note, you may need to add an underscore to the name of the C functions.)
* Also note, the implementation code is C++ code, but exposes its functions using
* a C interface.
*/
#include <stddef.h> // for NULL
#include <vrpn_Button.h> // for vrpn_Button_Remote, etc
#include <vrpn_Tracker.h> // for vrpn_TRACKERCB, etc
#include "c_interface.h"
#include "vrpn_Configure.h" // for VRPN_CALLBACK
/* Helper function that receives the callback handler from the C++ Tracker
* remote, repackages the values, and calls the user callback function. */
void VRPN_CALLBACK handle_tracker_pos_quat (void *userdata, const vrpn_TRACKERCB t)
{
vrpn_c_tracker_callback_function f = (vrpn_c_tracker_callback_function)(userdata);
f(t.sensor, t.pos, t.quat);
};
/* Open a tracker device, returning an opaque pointer to it. Returns NULL on
* failure, an opaque pointer to the tracker device on success. The tracker
* pointer needs to be passed to the poll and close functions. */
extern "C" void *vrpn_c_open_tracker(const char *device_name, vrpn_c_tracker_callback_function callback)
{
vrpn_Tracker_Remote *tkr = new vrpn_Tracker_Remote(device_name);
if (tkr != NULL) {
/* Tell the callback handler what function to call. */
tkr->register_change_handler((void*)callback, handle_tracker_pos_quat);
}
return tkr;
};
/* Poll the tracker whose device pointer is passed in. This will cause the
* callback handler to be called whenever a new value comes in for
* a sensor. Returns false if the device is not working. */
extern "C" vrpn_c_bool vrpn_c_poll_tracker(void *device)
{
if (device == NULL) { return false; }
vrpn_Tracker_Remote *tkr = (vrpn_Tracker_Remote *)device;
tkr->mainloop();
return true;
};
/* Close the tracker whose device pointer is passed in. Returns true on success,
* false on failure. */
extern "C" vrpn_c_bool vrpn_c_close_tracker(void *device)
{
if (device == NULL) { return false; }
vrpn_Tracker_Remote *tkr = (vrpn_Tracker_Remote *)device;
delete tkr;
return true;
};
/* Helper function that receives the callback handler from the C++ Button
* remote, repackages the values, and calls the user callback function. */
void VRPN_CALLBACK handle_button_event (void *userdata, const vrpn_BUTTONCB b)
{
vrpn_c_button_callback_function f = (vrpn_c_button_callback_function)(userdata);
f(b.button, (b.state != 0));
};
/* Open a button device, returning an opaque pointer to it. Returns NULL on
* failure, an opaque pointer to the button device on success. The button
* device pointer needs to be passed to the read and close functions. */
extern "C" void *vrpn_c_open_button(const char *device_name, vrpn_c_button_callback_function callback)
{
vrpn_Button_Remote *btn = new vrpn_Button_Remote(device_name);
if (btn != NULL) {
/* Tell the callback handler what function to call. */
btn->register_change_handler((void*)callback, handle_button_event);
}
return btn;
};
/* Poll the button whose device pointer is passed in. This will cause the
* callback handler to be called whenever a new value comes in for
* a button. Returns false if the device is not working. */
extern "C" vrpn_c_bool vrpn_c_poll_button(void *device)
{
if (device == NULL) { return false; }
vrpn_Button_Remote *btn = (vrpn_Button_Remote *)device;
btn->mainloop();
return true;
};
/* Close the button whose device pointer is passed in. Returns true on success,
* false on failure. */
extern "C" vrpn_c_bool vrpn_c_close_button(void *device)
{
if (device == NULL) { return false; }
vrpn_Button_Remote *btn = (vrpn_Button_Remote *)device;
delete btn;
return true;
};
/* Example of providing an interface to VRPN client-side objects through C.
* Initially made to handle the Tracker and Button objects, for the purpose
* of connecting to a Spaceball through Fortran. If you know how to link
* C and C++ code into Fortran, then you should be able to use it to link.
* (Note, you may need to add an underscore to the name of the C functions.)
* Also note, the implementation code is C++ code, but exposes its functions using
* a C interface.
*/
#ifdef __cplusplus
extern "C" {
#endif
typedef char vrpn_c_bool;
/* Function prototype for the function that will be called whenever a tracker
* report comes in. */
typedef void (*vrpn_c_tracker_callback_function)(unsigned sensor, const double pos[3], const double quat[4]);
/* Open a tracker device, returning an opaque pointer to it. Returns NULL on
* failure, an opaque pointer to the tracker device on success. The tracker
* pointer needs to be passed to the poll and close functions. */
void *vrpn_c_open_tracker(const char *device_name, vrpn_c_tracker_callback_function callback);
/* Poll the tracker whose device pointer is passed in. This will cause the
* callback handler to be called whenever a new value comes in for
* a sensor. Returns false if the device is not working. */
vrpn_c_bool vrpn_c_poll_tracker(void *device);
/* Close the tracker whose device pointer is passed in. Returns true on success,
* false on failure. */
vrpn_c_bool vrpn_c_close_tracker(void *device);
/* Function prototype for the function that will be called whenever a button
* report comes in. */
typedef void (*vrpn_c_button_callback_function)(const unsigned button, const vrpn_c_bool value);
/* Open a button device, returning an opaque pointer to it. Returns NULL on
* failure, an opaque pointer to the button device on success. The button
* device pointer needs to be passed to the read and close functions. */
void *vrpn_c_open_button(const char *device_name, vrpn_c_button_callback_function callback);
/* Poll the button whose device pointer is passed in. This will cause the
* callback handler to be called whenever a new value comes in for
* a button. Returns false if the device is not working. */
vrpn_c_bool vrpn_c_poll_button(void *device);
/* Close the button whose device pointer is passed in. Returns true on success,
* false on failure. */
vrpn_c_bool vrpn_c_close_button(void *device);
#ifdef __cplusplus
} /* end of extern "C" */
#endif
#include <stdio.h> // for printf
#include "c_interface.h"
void tracker_callback(unsigned sensor, const double pos[3], const double quat[4])
{
printf("Tracker sensor %d at (%lf,%lf,%lf) with orientation (%lf,%lf,%lf,%lf)\n",
sensor, pos[0], pos[1], pos[2], quat[0], quat[1], quat[2], quat[3]);
}
void button_callback(unsigned button, vrpn_c_bool value)
{
const char *state = (value?"pressed":"released");
printf("Button %d %s\n", button, state);
}
int main()
{
void *tkr;
void *btn;
const char *device_name = "Spaceball0@localhost";
printf("This is just a simple dummy application to show how you could access VRPN from straight C with a C-style interface.\n");
printf("It will try to connect to a local tracker and button device %s\n", device_name);
tkr = vrpn_c_open_tracker(device_name, tracker_callback);
btn = vrpn_c_open_button(device_name, button_callback);
while (1) {
vrpn_c_poll_tracker(tkr);
vrpn_c_poll_button(btn);
}
return 0;
}
#include <fcntl.h> // for open, O_RDONLY
#include <stdio.h> // for printf, fprintf, stderr
#include <stdlib.h> // for exit
#include <string.h> // for strcmp
#ifndef _WIN32
#include <netinet/in.h> // for ntohl
#include <unistd.h> // for close, read
#else
#include <io.h>
#endif
#include <vrpn_Connection.h> // for vrpn_HANDLERPARAM, etc
#include "vrpn_Shared.h" // for timeval, vrpn_TimevalMsecs
const int buflen = 8000;
void Usage (const char * name) {
fprintf(stderr, "Usage: %s [-n|-s] <filename>\n", name);
fprintf(stderr," -n: Print names instead of numbers.\n");
fprintf(stderr," -s: Summary only, start/end/duration\n");
}
int main (int argc, char ** argv) {
char * filename;
int name_mode = 0, summary_mode = 0;
char buffer [buflen];
vrpn_HANDLERPARAM header;
int file;
int retval;
if (argc < 2) {
Usage(argv[0]);
exit(0);
}
filename = argv[1];
if (!strcmp(argv[1], "-n")) {
filename = argv[2];
name_mode = 1;
fprintf(stderr, "FATAL ERROR: Name mode not implemented.\n");
exit(0);
} else if (!strcmp(argv[1], "-s")) {
filename = argv[2];
summary_mode = 1;
}
#ifdef _WIN32
// blech
const int oflag = O_RDONLY | O_BINARY;
#else
const int oflag = O_RDONLY;
#endif
file = open(filename, oflag);
if (file == -1) {
fprintf(stderr, "Couldn't open \"%s\".\n", filename);
exit(0);
}
struct timeval tvFirst, time;
int cEntries = 0;
while (1) {
int len;
long sender;
long type;
int len2;
retval = read(file, &header, sizeof(header));
if (retval < 0) { printf("ERROR\n"); close(file); exit(0); }
if (!retval) {
if (summary_mode) {
printf("Last timestamp in file: %ld:%ld\n", time.tv_sec, static_cast<long>(time.tv_usec));
timeval tvDuration = vrpn_TimevalDiff(time, tvFirst);
double dDuration = vrpn_TimevalMsecs(tvDuration) / 1000.0;
printf("Duration: %ld:%ld\n", tvDuration.tv_sec, static_cast<long>(tvDuration.tv_usec));
printf("%d enties over %gs = %.3fHz\n",
cEntries, dDuration, cEntries/dDuration);
} else {
printf("EOF\n");
}
close(file);
break;
}
cEntries++;
len = ntohl(header.payload_len);
time.tv_sec = ntohl(header.msg_time.tv_sec);
time.tv_usec = ntohl(header.msg_time.tv_usec);
sender = ntohl(header.sender);
type = ntohl(header.type);
if (summary_mode) {
static int first = 1;
if (first) {
printf("First timestamp in file: %ld:%ld\n", time.tv_sec, static_cast<long>(time.tv_usec));
tvFirst = time;
first = 0;
}
}
if (!summary_mode) {
if (name_mode)
printf("%ld from %ld, payload length %d\n",
type, sender, len);
else
printf("Message type %ld, sender %ld, payload length %d\n",
type, sender, len);
}
retval = read(file, buffer, len);
if (retval < 0) { printf("ERROR\n"); close(file); exit(0); }
if (!retval) { printf("EOF\n"); close(file); exit(0); }
if (summary_mode) {
continue;
}
printf(" <%d bytes> at %ld:%ld\n", retval, time.tv_sec, static_cast<long>(time.tv_usec));
switch (type) {
case vrpn_CONNECTION_SENDER_DESCRIPTION:
len2 = ntohl(* ((int *) buffer));
buffer[len2 + sizeof(int)] = 0;
printf(" The name of sender #%ld is \"%s\".\n", sender, buffer + sizeof(int));
break;
case vrpn_CONNECTION_TYPE_DESCRIPTION:
len2 = ntohl(* ((int *) buffer));
buffer[len2 + sizeof(int)] = 0;
printf(" The name of type #%ld is \"%s\".\n", sender, buffer + sizeof(int));
break;
case vrpn_CONNECTION_UDP_DESCRIPTION:
buffer[len] = 0;
printf(" UDP host is \"%s\", port %ld.\n", buffer, sender);
break;
case vrpn_CONNECTION_LOG_DESCRIPTION:
buffer[len] = 0;
printf(" Log to file \"%s\".\n", buffer);
break;
}
}
return 0;
}
/* clock_drift_estimator.C
This is a VRPN client program that will connect to a VRPN
server device use the built-in ping/poing messages from the
vrpn_BaseClass to estimate both the round-trip time for
VRPN messages and the clock drift between the client machine
and the server machine.
*/
#include <math.h> // for floor
#include <stdio.h> // for NULL, printf, fprintf, etc
#include <stdlib.h> // for exit
#include <vrpn_Shared.h> // for vrpn_gettimeofday, timeval, vrpn_TimevalSum, etc
#ifndef _WIN32_WCE
#include <signal.h> // for signal, SIGINT
#endif
#include <string.h> // for strcmp
#include <vrpn_BaseClass.h> // for vrpn_BaseClass
#include <vrpn_Connection.h> // for vrpn_Connection, etc
#include <vrpn_Tracker.h> // for vrpn_Tracker_NULL
#include "vrpn_Configure.h" // for VRPN_CALLBACK
int done = 0; // Signals that the program should exit
//-------------------------------------
// This object is used to connect to whatever server object is
// specified. The server object can be anything, a tracker, a button,
// an analog, etc. It just needs to be derived from vrpn_BaseClass
// so that it implements the ping/pong messages.
// XXX Later, make an interface to this so that it can be more generally
// useful as an estimator and move the printing up to the application.
class vrpn_Clock_Drift_Estimator : public vrpn_BaseClass {
public:
// The constructor adds another entry for the Pong message handler,
// so that we can use these responses to estimate.
vrpn_Clock_Drift_Estimator(const char * name, double min_repeat_wait_secs = 0, double estimation_interval_secs = 10, vrpn_Connection * c = NULL) :
vrpn_BaseClass(name, c),
d_doing_estimate(false),
d_doing_ping(false),
d_count(0)
{
vrpn_BaseClass::init();
if (d_connection != NULL) {
// Put in an additional handler for the pong message so that we can
// tell when we get a response.
register_autodeleted_handler(d_pong_message_id, handle_pong, this, d_sender_id);
// Initialize the member variables used in estimating the time.
// We want the estimation interval to start two seconds into the
// future to give things time to settle in and get connected.
vrpn_gettimeofday(&d_next_interval_time, NULL);
d_next_interval_time.tv_sec += 2;
d_next_ping_time = d_next_interval_time;
// Initialize the estimation interval and minimum waits used to
// tell when to do things.
if ( (min_repeat_wait_secs < 0) || (estimation_interval_secs <= 0) || (min_repeat_wait_secs > estimation_interval_secs) ) {
fprintf(stderr,"vrpn_Clock_Drift_Estimator::vrpn_Clock_Drift_Estimator(): Invalid time parameters (using 0, 10)\n");
min_repeat_wait_secs = 0;
estimation_interval_secs = 10;
}
d_min_repeat_wait.tv_sec = static_cast<long>(floor(min_repeat_wait_secs));
d_min_repeat_wait.tv_usec = static_cast<long>(floor( (min_repeat_wait_secs - d_min_repeat_wait.tv_sec) * 1e6));
d_estimation_interval.tv_sec = static_cast<long>(floor(estimation_interval_secs));
d_estimation_interval.tv_usec = static_cast<long>(floor( (min_repeat_wait_secs - d_estimation_interval.tv_sec) * 1e6));
d_last_ping_time.tv_sec = d_last_ping_time.tv_usec = 0;
}
};
~vrpn_Clock_Drift_Estimator() { return; };
/// Mainloop the connection to send the message.
void mainloop(void) {
client_mainloop();
if (d_connection) {
// Send any pings, collect any pongs.
d_connection->mainloop();
// See if it is time for the next interval to start. Start it if so.
struct timeval now;
vrpn_gettimeofday(&now, NULL);
if (vrpn_TimevalGreater(now, d_next_interval_time) || vrpn_TimevalEqual(now, d_next_interval_time)) {
// If we were doing an estimate, print the results.
if (d_doing_estimate) {
if (d_count == 0) {
fprintf(stderr,"vrpn_Clock_Drift_Estimator::mainloop(): Zero count in ping response!\n");
} else {
printf("vrpn_Clock_Drift_Estimator::mainloop(): Clock statistics for %d responses:\n", d_count);
printf(" Round-trip time: mean = %lg, min = %lg, max = %lg\n", d_sum_rtt/d_count, d_min_rtt, d_max_rtt);
printf(" Remote clock offset: mean = %lg, min = %lg, max = %lg\n", d_sum_skew/d_count, d_min_skew, d_max_skew);
}
}
// Set up for the next estimate interval.
d_doing_estimate = true;
d_next_interval_time = vrpn_TimevalSum(now, d_estimation_interval);
d_next_ping_time = now;
d_count = 0;
d_sum_rtt = 0;
d_sum_skew = 0;
}
// See if it is time to send the next ping. Send it if so.
if (vrpn_TimevalGreater(now, d_next_ping_time) | vrpn_TimevalEqual(now, d_next_ping_time)) {
vrpn_gettimeofday(&now, NULL);
//printf("XXX ping\n");
d_connection->pack_message(0, now, d_ping_message_id, d_sender_id,
NULL, vrpn_CONNECTION_RELIABLE);
d_last_ping_time = now;
// Tells the pong callback to listen to the response.
d_doing_ping = true;
// Don't do another until we hear a response.
d_next_ping_time = now;
d_next_ping_time.tv_sec += 10000;
}
// Send any pings, collect any pongs.
d_connection->mainloop();
}
};
protected:
// The interval over which to test before printing results,
// and the minimum time to wait between sending pings
struct timeval d_estimation_interval;
struct timeval d_min_repeat_wait;
// When we're going to next try a ping and when the next estimation interval starts
struct timeval d_next_ping_time;
struct timeval d_next_interval_time;
// When we last sent a ping.
struct timeval d_last_ping_time;
// Have we started doing an estimate or a ping?
bool d_doing_estimate;
bool d_doing_ping;
// Ping statistics
double d_min_rtt; // Round-trip time
double d_max_rtt;
double d_sum_rtt;
double d_min_skew; // Skew is from remote time to local time
double d_max_skew;
double d_sum_skew;
unsigned d_count;
/// No types to register beyond the ping/pong, which are done in BaseClass.
virtual int register_types(void) { return 0; };
// Report the elapsed time in seconds between the first and second time, where
// the first time is sooner. It will return a negative number if the first
// is later than the second.
static double elapsed_secs(const struct timeval &t1, const struct timeval &t2)
{
return 1e-3 * vrpn_TimevalMsecs( vrpn_TimevalDiff(t2,t1) );
};
static int VRPN_CALLBACK handle_pong(void *userdata, vrpn_HANDLERPARAM p)
{
//printf("XXX PONG\n");
vrpn_Clock_Drift_Estimator *me = static_cast<vrpn_Clock_Drift_Estimator *>(userdata);
// If we're currently estimating, then update the statistics based on
// the time of the response and the time we asked for a response.
if (me->d_doing_ping) {
struct timeval now;
vrpn_gettimeofday(&now, NULL);
// Find the round trip was by subtracting the time the last
// ping was sent from the current time.
double rtt = elapsed_secs(me->d_last_ping_time, now);
// Estimate the clock skew by assuming that the response was generated
// halfway between the sending time and now. We want to compute
// the number to add to the remote clock value to produce a time in
// the local clock value.
struct timeval interval = vrpn_TimevalDiff(now, me->d_last_ping_time);
struct timeval half_interval = vrpn_TimevalScale(interval, 0.5);
struct timeval expected = vrpn_TimevalSum(me->d_last_ping_time, half_interval);
double remote_to_local = elapsed_secs(p.msg_time, expected);
// If this is the first return, set the min and max values to the values
if (me->d_count == 0) {
me->d_min_rtt = me->d_max_rtt = rtt;
me->d_min_skew = me->d_max_skew = remote_to_local;
}
// Add these into the ongoing statistics and increment the count of
// samples.
me->d_sum_rtt += rtt;
if (rtt < me->d_min_rtt) { me->d_min_rtt = rtt; }
if (rtt > me->d_max_rtt) { me->d_max_rtt = rtt; }
me->d_sum_skew += remote_to_local;
if (remote_to_local < me->d_min_skew) { me->d_min_skew = remote_to_local; }
if (remote_to_local > me->d_max_skew) { me->d_max_skew = remote_to_local; }
me->d_count++;
// Set the time for the next ping. Mark us down as not doing an
// estimate, so we'll ignore misaligned pong responses.
me->d_next_ping_time = vrpn_TimevalSum(now, me->d_min_repeat_wait);
me->d_doing_ping = false;
}
return 0;
};
};
static vrpn_Clock_Drift_Estimator *g_clock = NULL;
static vrpn_Connection *g_connection = NULL;
static vrpn_Tracker_NULL *g_tracker = NULL;
// WARNING: On Windows systems, this handler is called in a separate
// thread from the main program (this differs from Unix). To avoid all
// sorts of chaos as the main program continues to handle packets, we
// set a done flag here and let the main program shut down in its own
// thread by calling shutdown() to do all of the stuff we used to do in
// this handler.
void handle_cntl_c(int) {
done = 1;
}
void Usage (const char * arg0) {
fprintf(stderr,
"Usage: %s server_to_use | LOCAL\n"
" server_to_use: VRPN name of device to connect to (eg: Tracker0@ioglab)\n"
" 'LOCAL' means to launch a local server on a dedicated connection\n",
arg0);
exit(0);
}
int main (int argc, char * argv [])
{
if (argc != 2) {
Usage(argv[0]);
} else {
if (strcmp(argv[1], "LOCAL") == 0) {
printf("Opening local server on dedicated connection\n");
g_connection = vrpn_create_server_connection();
g_tracker = new vrpn_Tracker_NULL("Tracker0", g_connection);
g_clock = new vrpn_Clock_Drift_Estimator("Tracker0@localhost", 0.01, 5);
} else {
printf("Connecting to server %s\n", argv[1]);
g_clock = new vrpn_Clock_Drift_Estimator(argv[1], 0.01, 5);
}
}
#ifndef _WIN32_WCE
// signal handler so logfiles get closed right
signal(SIGINT, handle_cntl_c);
#endif
/*
* main interactive loop
*/
printf("Press ^C to exit.\n");
while ( ! done ) {
g_clock->mainloop();
if (g_tracker) { g_tracker->mainloop(); }
if (g_connection) { g_connection->mainloop(); }
}
if (g_clock) { delete g_clock; g_clock = NULL; }
if (g_tracker) { delete g_tracker; g_tracker = NULL; }
if (g_connection) { delete g_connection; g_connection = NULL; }
return 0;
} /* main */