ARGONNE NATIONAL LABORATORY
9700 South Cass Avenue
Argonne, IL 60439
-----------------
ANL/MCS-TM-218
-----------------
CAVEcomm Users Manual
by
Terrence L. Disz, Michael E. Papka, Michael Pellegrino
Mathematics and Computer Science Division, ANL
and
Matthew Szymanski
The Electronic Visualization Laboratory, University of Illinois at Chicago
Mathematics and Computer Science Division, ANL
Technical Memorandum No. 218
September 1996
This work was supported by the Mathematical, Information, and
Computational Sciences Division subprogram of the Office of
Computational and Technology Research, U.S. Department of Energy,
under Contract W-31-109-Eng-38.
Abstract
The CAVEcomm library is a set of routines designed to generalize the
communications between virtual environments and supercomputers.
Library Model
The model for the library is that of a client/server. Somewhere at a
known URL is a broker whose purpose is to mediate the communications
between various client applications (CAVE, simulations, etc.).
The Broker
The broker maintains tables of all clients and of all sessions (applications)
that are registered with it.
The table of clients includes such elementary information as the client's
capabilities (machine type, model, etc.) as well as basic application information
(CAVE application, IBM simulation, etc.). Clients can query the broker
for this information.
The table of sessions includes information on all sessions (applications)
that any registered client can run. The table maintains such information
as executable names, data files, command line arguments, etc. Of course,
clients cannot attach to sessions outside of the realm of their physical
machine. For example, clients cannot run a CAVE application unless
CAVE functiexists onality on their machine. Clients can query the broker for
this session information.
The broker executable is in the bin subdirectory within the
CAVEcomm distribution.
To run the broker, type ./c2cbroker -
commandline arguments
Commandline arguments include the following:
- -c2cdbg { 100-140 }
- Specifies the level of debuging messages output by the broker,
100 being the lowest level of c2c internal messages and 140 being
the greatest.
- -c2curl_filename {
my_url_file }
- Contains the URL for the broker, the idea being that this
file lives in some common shared file space that all users of a given
instance can access.
- -c2c_port { port number }
- Specifies the particular port that the broker will be listening on,
thereby allowing users to pick an arbitrary port number and use that port
over and over, thus eliminating the need to change the config files.
Example:
./c2cbroker -c2c_port 10001 -c2cdbg 140
This command will start a broker process on the machine from which it is run,
listening on port 10001, and printing out all the internal c2c debug
messages available.
The Client
Each CAVEcomm client is an application (CAVE, simulation, etc.) that
has the power to attach to any other application on the broker. A
simulation that is registered with the broker can be accessed by any
other application on the broker such as visualization applications or
virtual environments.
Communications Transport
The CAVEcomm library uses the Nexus communications library
developed at the Mathematics and
Computer Science Division at
Argonne National Laboratory.
While Nexus is the communications transport, the user does not need
any prerequisite knowledge in using it. All Nexus communications calls
are encapsulated in the library; thus, the user is unaware of the Nexus
presence.
By using Nexus, the CAVEcomm library is able to support various
communications protocols such as TCP/IP sockets and shared memory, as well
as various message-passing libraries.
CAVEcomm Library
All functions in the CAVEcomm library start with the prefix c2c.
The CAVEcomm library contains functions that are broken down into various sections.
General Routines
- int c2cGetDebugLevel(void);
- Get the current maximum debugging level in an application.
- void c2cInit(int *argc, char
*argv[],CaveEnv *env);
- Start all communications functionality. Its arguments are the
argument count, argument vector, and a structure describing the
application's operating environment. It must be the first CAVEcomm library call
made (except for c2cReadConfigFile or if the world routines are
used). If the CAVEcomm library is used with the CAVE library, the
call to c2cInit must occur after the
call to CAVEInit is made.
- void c2cPrintf(int level, char
*format, ...);
- Print the text. The text consists of a chracter string describing how to format the text and any applicable variables contained in the format. This function is similar to the printf
function found in the standard I/O C library. The level
parameter tells the library at what level to print the text.
- int c2cReadConfigFile(char
*filename,c2cConfig *config);
- Read filename for
application definitions. The definitions are placed into config,
which contains all known application definitions. If
filename is null, the default file
.c2cConfig is attempted to be opened. If filename or .c2cConfig
cannot be opened; E_OPEN_CONFIG_FILE is returned, otherwise, E_SUCCESS
is returned.
- void c2cSetDebugLevel(int level);
- Set the current maximum debugging level in an application.
- void c2cTerminate(void);
- End all communications functionality. It is the last CAVEcomm library
call made (unless the world routines
are used).
Broker Routines
- HostId c2cBrokerAttach(URL url);
- Attach to the broker listed by url. The URL must be of the
format c2cBroker://{ip hostname}:{ip port}/. Supplying a URL
of a different format will give unpredictable results. A HostId is
returned uniquely describing that broker.
- int c2cBrokerDetach(HostId host);
- Detach from the broker specified by host. No further references
can be made to host after it is detached. E_INVALID_HOST is returned if
HostId does not match a host that was previously attatched with
c2cBrokerAttach; otherwise, E_SUCCESS is returned.
- int c2cBrokerKill(HostId host);
- Terminate the broker specified by host. All database information
on the broker is disposed of, and all programs connected are terminated.
Most programs will never issue this call. E_INVALID_HOST is returned if
HostId does not match a host that was previously attached with
c2cBrokerAttach; otherwise, E_SUCCESS is returned.
- CAVEId c2cGetClientId(HostId host,char *name);
- Query the broker host, and return the assigned CAVEId of the client name. The
CAVEId is returned if the client name is found; otherwise, E_INVALID_CLIENT is returned.
If the host is invalid, E_INVALID_HOST is returned.
- int c2cGetClients(HostId host,int
*num_clients,CaveEnv **client_list);
- Retrieve a list of all
clients currently registered on broker host. The number of
clients registered is returned is in num_clients along with an
array of all the registered CaveEnv structures. E_INVALID_HOST is
returned if HostId does not match a host that was previously attatched
to with c2cBrokerAttach; otherwise, E_SUCCESS is returned.
- SessionId c2cGetSessionId(HostId
host,char *name);
- Query the broker host, and return the
assigned SessionId of the session name. The SessionId is
returned if the session name is found; otherwise, E_INVALID_SESSION is
returned. If the host is invalid, E_INVALID_HOST is returned.
- int c2cGetSessions(HostId host,int
*num_sessions,CaveSession **session_list);
- Retrieve a list of
all sessions currently registered on broker host. The number of
sessions registered is returned is in num_sessions along with an
array of all the registered CaveSession structures. E_INVALID_HOST is
returned if HostId does not match a host that was previously attatched
to with c2cBrokerAttach; otherwise, E_SUCCESS is returned.
- int c2cKillSession(HostId
host,SessionId session,CAVEId cave);
- Not yet implemented.
- CAVEId c2cRegister(HostId
host,CaveEnv *env);
- Register the application on broker
host with the environment env. All subsequent queries to
the broker with respect to clients will reflect that application's
presence. E_INVALID_HOST is returned if HostId does not match a host
that was previously attatched with c2cBrokerAttach; E_CLIENT_EXISTS
is returned if the client name is already used on the broker. If
there are no errors, a CAVEId (0 or higher) is returned.
- int c2cSessionAttach(HostId
host,SessionId session, CAVEId cave);
- Not yet implemented.
- SessionId c2cSessionCreate(HostId
host,CaveSession *ses);
- Create a session on broker host
with session ses. All subsequent queries to the broker with
respect to sessions will reflect that application session's presence.
E_INVALID_HOST is returned if HostId does not match a host that was
previously attached with c2cBrokerAttach. E_SESSION_EXISTS is
returned if the session name is already used on the broker. If all
goes well, E_SUCCESS is returned.
- int c2cSessionDetach(HostId
host,CAVEId cave);
- Not yet implemented.
- int c2cSubscribe(HostId host,CAVEId
datasource,StreamType stream,void *callback);
- Inform the broker
host that your application would like receive stream data of
type stream from datasource, and call callback when
any incoming data is to be processed. The remote application will then
start streaming the requested data to the application. E_INVALID_HOST
is returned if HostId does not match a host that was previously
attatched with c2cBrokerAttach. E_INVALID_CAVE_ID is returned if
datasource is invalid on host. E_INVALID_STREAM is
returned if datasource does not have stream available.
E_SUCCESS is returned upon successful subscription to stream.
- int c2cUnregister(HostId host,CAVEId
cave);
- Tell the broker host to remove an application
from the client list. All subsequent queries to the broker with
respect to clients will not reflect that application's presence.
E_INVALID_HOST is returned if HostId does not match a host that was
previously attatched with c2cBrokerAttach. E_INVALID_CAVE_ID is
returned if cave is invalid on host. E_SUCCESS is
returned upon successful subscription to stream.
- int c2cUnsubscribe(HostId
host,CAVEId datasource,StreamType stream,void *callback);
- Inform broker host that an application would like cancel
the streaming of data of type stream from datasource with
the matching callback callback. The remote application no
longer streams data to that application. E_INVALID_HOST is returned if
HostId does not match a host that was previously attatched with
c2cBrokerAttach. E_INVALID_CAVE_ID is returned if datasource
is invalid on host. E_INVALID_STREAM is returned if
datasource does not have stream available.
E_INVALID_CALLBACK is returned if a callback is given that was not used
for a subscription to stream. E_SUCCESS is returned upon
successful unsubscription to stream.
Data Routines
- void c2cFreeDataBuffer(void
*buffer);
- Free the data buffer bufffer (accessed with
c2cGetn calls) from memory.
- void c2cFreePackBuffer(c2cBuffer
**buffer);
- Free the data buffer buffer (accessed with
c2cPackn calls) from memory.
- void c2cGetChar(void *buffer,char *data,int size);
- Get size characters from buffer, and put them into data.
- void c2cGetDouble(void
*buffer,double *data,int size);
- Get size doubles from
buffer, and put them into data.
- void c2cGetFloat(void *buffer,float
*data,int size);
- Get size floats from buffer, and
put them into data.
- void c2cGetInt(void *buffer,int
*data,int size);
- Get size integers from buffer,
and put them into data.
- void c2cGetLong(void *buffer,long
*data,int size);
- Get size long integers from
buffer, and put them into data.
- void c2cInitPackBuffer(c2cBuffer
**buffer);
- Initialize data buffer buffer for future
packing.
- void c2cPackChar(c2cBuffer
**buffer,char *data,int size);
- Add size blocks of
character data to buffer for broadcast later.
- void c2cPackDouble(c2cBuffer
**buffer,double *data,int size);
- Add size blocks of
double data to buffer for broadcast later.
- void c2cPackFloat(c2cBuffer
**buffer,float *data,int size);
- Add size blocks of float
data to buffer for broadcast later.
- void c2cPackInt(c2cBuffer
**buffer,int *data,int size);
- Add size blocks of integer
data to buffer for broadcast later.
- void c2cPackLong(c2cBuffer
**buffer,long *data,int size);
- Add size blocks of long
data to buffer for broadcast later.
- int c2cRegisterStream(StreamType
stream,void *subscribecallback,void *unsubscribecallback);
- Register a stream in an application. No streams can be
subscribed to until they are registered. If subscribecallback
is supplied (it is not null), that callback will be executed every time
the stream is subscribed to. If unsubscribecallback is supplied
(it is not null), that callback will be executed every time the stream
is unsubscribed to. E_STREAM_REGISTERED is returned if the
stream is already registered. E_SUCCESS is returned otherwise.
- int c2cSendStream(CAVEId sourceid,
c2cBuffer **buffer,StreamType stream);
- Cast a buffer of data
buffer (previously packed with c2cPackn routines) of
stream type stream to all applications subscribed to that stream
with a source identifier of sourceid. The source identifier
tells the remote processes who sent them the stream. E_INVALID_STREAM
is returned if the stream was not registered; otherwise, E_SUCCESS is
returned.
- int c2cSendHeadTracker(float x,float
y,float z,float a,float e,float r);
- Cast local CAVE head
tracker information (passed via parameters) to all applications
subscribed to the stream S_HEAD_TRACKER. E_INVALID_STREAM is returned
if the stream was not registered; otherwise, E_SUCCESS is returned.
- int c2cSendUser(CAVEId sourceId,
CAVEUser *user);
- Cast local CAVE user (all trackers, buttons,
joystick and world info) to all applications subscribed to the stream
S_CAVE_USER. E_INVALID_STREAM is returned if the stream was not
registered; otherwise, E_SUCCESS is returned.
- int c2cSendWandButtons(CAVEId
sourceId, int b1,int b2,int b3,int b4);
- Cast local CAVE wand
button information (passed via parameters) to all applications
subscribed to the stream S_WAND_BUTTON. E_INVALID_STREAM is returned
if the stream was not registered; otherwise, E_SUCCESS is returned.
- int c2cSendWandJoystick(CAVEId
sourceId, float joyx,float joyy);
- Cast local CAVE wand joystick
information (passed via parameters) to all applications subscribed to
the stream S_WAND_JOYSTICK. E_INVALID_STREAM is returned if the stream
was not registered; otherwise, E_SUCCESS is returned.
- int c2cSendWandTracker(float x,float
y,float z,float a,float e,float r);
- Cast local CAVE wand
tracker information (passed via parameters) to all applications
subscribed to the stream S_WAND_TRACKER. E_INVALID_STREAM is returned
if the stream was not registered; otherwise, E_SUCCESS is returned.
- int c2cSendWorldPosition(float
x,float y,float z,float a,float e,float r);
- Cast local CAVE
world position (passed via parameters) to all applications subscribed
to the stream S_WORLD_POSITION. E_INVALID_STREAM is returned if the
stream was not registered; otherwise, E_SUCCESS is returned.
- int c2cUnregisterStream(StreamType
stream)
- Unregister a stream with an application. No remote
applications can subscribe to a stream once it is unregistered.
E_INVALID_STREAM is returned if the stream was not registered;
otherwise, E_SUCCESS is returned.
World Routines
- void c2cDrawAllUsers(void);
- Draw all users that are tracked via c2cTrackUserInit.
- void c2cDrawSomeUsers(int count,char *users[]);
- Draw a list of users that are tracked via
c2cTrackUserInit. The number of users in the list as well as the
application names of the users to draw are passed as parameters.
- int c2cDrawUser(char *user);
- Draw a user that is tracked via
c2cTrackUserInit. The user to draw is specified by giving his
applicaion name for user. E_INVALID_CLIENT is returned if an invalid
client name is given. E_SUCCESS is returned otherwise.
- void c2cTrackUserInit(char *user,void *callback);
- Start tracking user (specified by application name). The rendering
of the user can be user defined by supplying a callback. Whenever a draw
command is issued, this callback will be executed. If null is given as the
callback, a default stick-man representation of the user will be rendered.
E_INVALID_CLIENT is returned if user is invalid. E_INVALID_STREAM is returned if
user does not have tracking available. E_SUCCESS is returned upon
successful tracking initializaion.
- int c2cTrackUserExit(char *user,void
*callback);
- Cancel the tracking of user (specified by
application name). The callback of the tracked user must match that given when initiated.
E_INVALID_CLIENT is returned if user is invalid.
E_INVALID_STREAM is returned if user does not have tracking
available. E_SUCCESS is returned upon successful tracking exiting.
- void c2cWorldDataInit(void);
- Initialize necessary data structures needed for world
communications. This must be the
first CAVEcomm library call issued in an application (except for
c2cReadConfigFile). If the application running is a CAVE application,
it must occur before the call to
CAVEInit is made. In addition, if any CAVEcomm application
wishes to use the user-tracking facilities, it must make a call to c2cWorldDataInit
(whether the application is CAVE based or not).
- void c2cWorldDataSubscribe(char
*user,StreamType stream,void *callback);
- Subscribe to
user (specified by application name) for data stream
stream and to call callback when the data is received.
E_INVALID_CLIENT
is returned if user is invalid. E_INVALID_STREAM is returned
if user does not have stream available. E_SUCCESS is
returned upon successful data subscription.
- void c2cWorldDataUnsubscribe(char
*user,StreamType stream,void *callback);
- Unsubscribe to the
data stream stream that was previously subscribed to from
user (specified by his application name) with callback.
E_INVALID_CLIENT is returned if user is invalid.
E_INVALID_STREAM is returned if user does not have stream
available. E_INVALID_CALLBACK is returned if a callback is given
that was not used for a subscription to stream. E_SUCCESS is
returned upon successful data unsubscription.
- void c2cWorldExit(void);
- Terminate all World functionality. This must be the last CAVEcomm library call
issued in an application.
- CAVEId c2cWorldGetClientId(char
*name);
- Query the broker, and return the assigned CAVEId of the
client name. The CAVEId is returned if the client name is
found; otherwise, E_INVALID_CLIENT is returned.
- SessionId c2cWorldGetSessionId(char
*name);
- Query the broker, and return the assigned SessionId of
the session name. The SessionId is returned if the session name
is found; otherwise, E_INVALID_SESSION is returned.
- void c2cWorldInit(int *argc,char
*argv[]);
- Initiate all World functionality. If the CAVEcomm
library is used with the CAVE library, it must occur after the call to CAVEInit is
made.
- int c2cWorldSendStream(c2cBuffer
**buffer,StreamType stream);
- Cast a buffer of data
buffer (previously packed with c2cPackn routines) of
stream type stream to all applications subscribed to that
stream. E_INVALID_STREAM is returned if the stream was not registered;
otherwise, E_SUCCESS is returned.
Global Variables
The CAVEcomm library maintains the following global variable that the user can
access:
- CaveEnv c2cEnv
- This variable maintains all local environment information that was registered
with c2cInit.
Data Structures
The CAVEcomm library has data structures that are accessible by the
user.
CaveEnv
/* Structure defining CAVE environment */
typedef struct caveenv
{
char name[C2C_NAME_SIZE]; /* Unique name for this CAVE */
int type; /* Type of session this is (CAVE, I-Desk, etc...) */
int id; /* Id of the client */
}CaveEnv;
CaveSession
/* Structure describing a CAVE session */
typedef struct cavesession
{
CAVEId owner; /* Who owns the session on the broker */
char name[C2C_NAME_SIZE]; /* Unique name describing the session */
char pathname[C2C_PATH_SIZE]; /* Where to find the application */
char execname[C2C_EXE_SIZE]; /* Executable name */
char args[C2C_ARGS_SIZE]; /* Command line arguments */
int id; /* Id of the session */
}CaveSession;
CAVEUser
/* Structure defining CAVE user */
typedef struct caveuser
{
float headx,heady,headz, /* Head tracker location */
heada,heade,headr, /* Head tracker orientation */
wandx,wandy,wandz, /* Wand tracker location */
wanda,wande,wandr, /* Wand tracker orientation */
worldx,worldy,worldz, /* World location */
worlda,worlde,worldr; /* World orientation */
int but1,but2, /* Button information */
but3,but4;
float joyx,joyy; /* joystick information */
}CAVEUser;
c2cConfig
/* Structure defining a CAVEcomm session */
typedef struct c2cconfig
{
URL broker; /* URL to connect to broker with */
CaveEnv env; /* Local environment parameters */
CaveSession session; /* Session info for this CAVE app */
}c2cConfig;
CAVEcomm Configuration File
The CAVEcomm library looks for a configuration file (.c2cConfig by
default) that defines certain aspects of the application. The format for
the configuration file is keyword [option]. Keywords are not case
sensitive. Application definitions are as follows:
- Broker "Broker URL"
- A known URL of the broker that
one is to register and attach to. The broker URL must be of the format c2cBroker://{ip
hostname}:{ip port}/.
- DebugLevel level
- The level for debugging the application. Debugging will be set at
level as soon as the parser finishes processing the DebugLevel keyword.
- ClientName "Client application name"
- The name of the application that is used when registering on the broker.
- ClientAppType type
- The application type describing what type of application it is (CAVE,
ImmersaDesk, simulation).
- SessionName "Session name"
- Name of the session given to the broker upon session creation.
- SessionPath "Pathname to application"
- Pathname of the executable for the session. It is given to the broker
upon session creation.
- SessionExe "Session executable name"
- Executable name of the application for the session. It is given to the
broker upon session creation.
- SessionArgs "Command line arguments"
- Command line arguments needed to run the application. They are given
to the broker upon session creation.
CAVEcomm Constants
Stream Types
- S_HEAD_TRACKER
- Head tracker information
- S_WAND_TRACKER
- Wand tracker information
- S_WAND_BUTTON
- Button information
- S_WAND_JOYSTICK
- Joystick information
- S_WORLD_POSITION
- CAVE location in the world
- S_CAVE_USER
- User information (trackers/buttons etc... all in one)
Session Types
- ST_CAVE
- CAVE session
- ST_CAVE_SIMULATOR
- CAVE simulator session
- ST_IMMERSADESK
- ImmersaDesk session
- ST_SIMULATION
- Data simulation of some sort
Data Types
- DT_CHAR
- Character data
- DT_INT
- Integer data
- DT_LONG
- Long integer data
- DT_FLOAT
- Float data
- DT_DOUBLE
- Double data
Error Messages As Seen by User
- E_SUCCESS
- No error at all
- E_BROKER_ATTACH
- Attach to the broker failed
- E_SUBSCRIBE_NO_STREAM
- Subscribe to non-existant stream
- E_INVALID_HOSTID
- Bad host id given
- E_INVALID_CALLBACK
- Bad callback given
- E_INVALID_STREAM
- Stream never registeged
- E_STREAM_REGISTERED
- Stream already registered
- E_INVALID_HOST
- Invalid host id given
- E_INVALID_CAVEID
- Invalid CAVE id given
- E_INVALID_BROKER_URL
- Invalid broker URL given
- E_INVALID_CLIENT
- Invalid client name given
- E_INVALID_SESSION
- Invalid session name given
- E_CLIENT_EXISTS
- Client already registered on broker
- E_SESSION_EXISTS
- Session already created on broker
- E_OPEN_CONFIG_FILE
- Error opening configuration file
Various Array Sizes
- C2C_NAME_SIZE
- Size of session string
- C2C_URL_SIZE
- Size of a URL string
- C2C_PATH_SIZE
- Size of path string
- C2C_EXE_SIZE
- Size of exe string
- C2C_ARGS_SIZE
- Size of argument string
Miscellaneous Constant Definitions
- C2C_CONFIG_FILE
- Default config file to open if none is given
- C2C_BROKER_URL_FILE
- Default filename to house broker URL
- CONFIG_FILE_LINE_SIZE
- Max size of a file line in configuration file
- CONFIG_OPTION_SIZE
- Max size of an option in configuration file
- C2C_SUBSCRIBE
- Flag for World subscribe operation
- C2C_UNSUBSCRIBE
- Flag for World unsubscribe operation
Sample Applications
New Samples
- Multiple CAVE OpenGL Application
- Makefile
CAVE One Code
CAVE Two Code
CAVE Three Code
- Inventor CAVE Application
- Client C++ Code
Client Header Code
Server C++ Code
Server Header Code
- Supercomputer to CAVE Application
- CAVE Side C Code
CAVE Side Header Code
Supercomputer Side C Code
Supercomputer Side Header Code
Old Samples
- Multiple CAVE GL Application
- Makefile
CAVE One Code
CAVE Two Code
- Client Server Application
- Client C Code
Server C Code
Sample applications
New Samples
- Multiple CAVE OpenGL Application
- Makefile
CAVE One Code
CAVE Two Code
CAVE Three Code
- Inventor CAVE Application
- Client C++ Code
Client Header Code
Server C++ Code
Server Header Code
- Supercomputer to CAVE Application
- CAVE Side C Code
CAVE Side Header Code
Supercomputer Side C Code
Supercomputer Side Header Code
Old Samples
- Multiple CAVE GL Application
- Makefile
CAVE One Code
CAVE Two Code
- Client Server Application
- Client C Code
Server C Code
Acknowledgments
The following people have contributed to the development of the
CAVEcomm library: Terry Disz, Ian Foster, Terry Franguiadakis, Jonathan
Geisler, Dan Heath, Ivan Judson, Bob Olson, Mike Papka, Mike
Pellegrino, Rick Stevens, Matthew Szymanski, and Steve Tuecke.