FreeVR: Virtual Reality Integration Library
User Guide




    Function List
    Library Dev
    Socket Interface


All materials
Copyright © 2015
William R. Sherman

FreeVR: Telnet/Socket Interface Manual

FreeVR: Telnet/Socket Interface Manual

March 20, 2015 for FreeVR Version 0.6f
Written by Bill Sherman


This guide describes the use of the telnet/socket communications interface to FreeVR applications. As such it can be considered a supplement to the VR System Administration Guide. However, use of the telnet communications system may also come in useful during library or application development, or even during normal application usage. Using this interface, it is possible to text commands to a running FreeVR application either to inquire about the current state of the system, or even to make certain modifications to the system.

There are two primary means by which one would typically interface with the running system: a telnet connection, or a GUI-based socket program. Both forms of interface are currently available, but both require that the system be configured such that a special telnet process be running when an application is started. Therefore, to configure the system to include such a process is presented first.

The configuration section is followed by the GUI-interface section (yet to be written), and then the Text-interface section. The GUI interface is designed to be easy to use, allowing the viewing and modifying of a subset of the library parameters. The text interface is far more complete, and is often more suitable when attempting to debug the system configuration or bugs in the library itself. For most users, the GUI should be sufficient.

Configuring a Socket Process

In order to make use of the socket command connection it will first be necessary to add a "telnet" process to the operating configuration. The default configuration does not include a "telnet" process because of the open nature of the socket communication. While there is no function that would provide a Trojan horse opportunity to a second party that might connect with someone's running application, it would generally still be an undesirable situation — unless they were helping to debug their application.

Although not part of the default system, there is a "default-telnet" process already defined in the built-in configuration. Thus, to include a telnet process into your configuration it is only necessary to add the existing, default, definition to the system in use. Typically this configuration statement would go in the user's personal configuration file (~/.freevrrc). Because the $system variable contains the most recently set system to use, and the += operator allows one to append to objects and options, the following will work in most situations:

	system $system += {
		procs += "default-telnet";

The above is sufficient for making sure the telnet process will be available for communication. However, it is also possible to configure the telnet process to your personal tastes. As the telnet process is a process, it has the same basic options as the input and visual rendering processes. There are of course, a handful of differences.

To define a telnet process, set the process type to telnet. There are four arguments available for the args fields of the definition: "port", "portrange", "prompt", and "password". The "port" argument is set to the socket port with which you wish to connect via the telnet or other program, or this may be the lower-bound of a range of ports. If the value of "portrange" is zero (or less), then the telnet process will only use the "port" port for the listening socket. In some instances, the desired port will be unavailable, which is where the "portrange" argument comes into play. If there is no range, and the port is busy, then the telnet process will continue to attempt opening the given port, pausing 5 seconds between attempts. If the value of "portrange" is positive, then the telnet process will increment the value of the port it attempts to use by one, and continue incrementing when it finds a busy port, until it gets to the port value that is the sum of "port" and "portrange".

The "prompt" argument allows you to set what will be sent back over the socket to indicate the process is ready to accept a command. By default the prompt is set to "FreeVR>". The final argument, "password" is used to set a password that must be entered before the telnet process will accept commands over the socket port. Currently, this password is not encrypted in any way, so if it is stored in one's configuration file, and other's have access to read the file, then they will know the password. Of course, it is possible to use an environment variable to set the password, which would keep it a little more secret (unless the variable itself is set in a readable .cshrc file).

Here is an example definition for a telnet process:

	process "mytelnetproc" = {
		type = telnet;
		printcolor = $ANSI_GREEN;
		args = "port = 3000; portrange = 1;";	# Listen on port 3000 or 3001
		args += "password = itsme; prompt = YO>;";

The GUI Commands

The FreeVR Remote Interface program is a Tcl/Tk script that uses the socket communications protocol to query and set values of a running FreeVR application. The image above reflects the interface as of FreeVR version 0.5g. Some of the features are still under development, and others still in the planning stage.

To run the program, you need to make sure there is a "telnet" process in the current configuration, then run the FreeVR application, and then run the script called fvri.tcl which can be found in the bin directory of the FreeVR distribution.

The top section of the display lists some information about the application, including the library it was compiled with, and the system that is currently running. The first two lines, with the application name and authors gets its information from strings that can be optionally set by the application authors. If no information is set within the program, then no information will be available, thus all FreeVR application programmers are strongly encouraged to supply these pieces of information. The next line down gets its information from the library itself. Information about the version of the library, and how it was compiled are directly incorporated within the library file. And the bottom line is based on the current configuration within which the application is running.

The middle section of the display contains all the controls available through this interface. On the left side are some buttons for gross system commands or popup information. NOTE: there probably is no need to use the "stop looping" button, particularly since no "restart looping" option has yet been added. The "App UI popup" button brings up a window that echoes the user interface information that, like the name and authors information, relies on character strings supplied by the application authors within the program itself.

The middle section (of the middle section) has some global settings such as toggling on and off the display of the FPS (Frames per second) information on all of the screens, or the execution statistics, or the user-interface information. Each of these features can alternately be toggled on a screen by screen basis through keys on the numeric keypad. After that are three features that will be implemented in the very near future — ie. before the release edition of version 0.5g. And then the bottom two both report the current near and far clipping planes, and also allow the user to alter these values.

On the right side of the control pane, are currently two toggle buttons that control the update of the information in the bottom portion of the overall window. For each feature that is enabled, the data of the running application will be continually updated in that bottom display. The current choices are information about all the processes, which is often helpful to determine if there is a problem with one of the processes, and also a report on the tracked user of the system, with data about their inter-ocular distance setting (IOD), and their current travel matrix.

More options are planned, plus some error checking to make sure the socket is available when the script is run. Desires for additional features will also be considered.

The Text-Interface Commands

There are two major groupings of commands that can be sent to a FreeVR application, plus a collection of miscellaneous commands. The first major grouping are the print commands, for making inquiries regarding the running application. The second major grouping are the set commands for setting the values of parts of the running system. Of the miscellaneous commands, the help command is the one of primary importance.

The Print Commands

Specifying a print action begins with either the word print or just the letter p followed by one of the available features of the system that can be requested. As with the general list of commands, there is also an option to return the list of available printable options using the print help command.

Most of the queries that can be made via the print command pertain to information about the current state of objects that make up the actively running system. There is also a command to print the entire configuration setup for the current system, and there is also a command for printing any object from the configuration files, regardless of whether they are part of the active system. [NOTE: recall that a FreeVR configuration can specify multiple hardware setups (aka "systems"), allowing the user to specify a particular system at runtime. The objects used to construct those, alternate, systems can also be queried, but of course there will be no information about their runtime status.]

Except for the "system" object, a running FreeVR application may have multiple active objects of any given type. In fact, there will nearly always be at least three processes, and there will often by multiple windows for rendering, and frequently there will be multiple input devices as well. Thus, except for the "system", it is possible to inquire about a particular object of a given type, or a summary of all the objects of that type.

The special "object" query is used to print information about configuration objects that may or may not be part of the running system. Because objects of different types can have the same name, it is required that the inquiry specify the object type. For example, there may be a window named default and an input named default.

There are also two special forms of the object query. The first special form is to use the word list as the name of the object. Instead of looking for an object with the name "list", FreeVR will return a list of the given type of object. The second special query is to specify the object type as "address" and give a numeric value as the name. In this case, FreeVR will respond with information of the configuration object at the address specified by that number. Many of the query printouts give object addresses, sometimes without the corresponding name (as in a next pointer in a linked list). Thus using the address is the best way to find out what object lies at the other end of the pointer.

Here is the list of all the available queries:

  • context — print the context structure
  • config — print the configuration structure of the running system
  • system — print the system structure
  • procs — print a summary of all the processes
  • proc[<N>] — print the structure of the Nth process
  • inputs — print a list of the available inputs
  • input <name> — print info about a particular input
  • inputdevices — print info about all inputs devices
  • inputdevice[<N>] — print info about the Nth input device
  • windows — print a summary of all the windows
  • window[<N>] — print info about the Nth particular window
  • eyelists — print info about all eyelists
  • eyelist[<N>] — print info about the Nth eyelist
  • eyes — print info about the eyes of the system
  • eye[<N>] — print info about the Nth eye
  • users — print info about all the active users
  • user[<N>] — print info about all the Nth user

  • object|o <type> list — list all <type> config objects
  • object|o <type> <name> — print info about any config object
  • object|o <address|a> <memory address> — print info about any config object (running or not)

The Set Commands

The "set" commands allow the operator to affect the running FreeVR application. The values that can be set are a limited selection of fields of each of the configuration objects, plus a handful of global/context values (such as the overall debugging printout level). As with the printcommands, a set command begins with either the word set or the letter s followed by the object's field to set, and the field's new value. There is once again a help argument that can be given to receive a list of settable features.

The scope of what can be set is of course must smaller than what can be queried. Basically, certain fields of the active window, user, and proc configuration objects can be set, along with any specific input (such as a button or a 6dof-sensor). Also, the global debug (including both the "level" and the "thistoo" values) can be set.

Here is the list of all the available settables:

  • help — print this message (a list of possible setting requests)
  • input <obj> <value> — set the value of an input
    • input <6-sensor> <id> — set the transformation to identity
    • input <6-sensor> loc <x> <y> <z> — set the location ('*' is no-change)
    • input <6-sensor> move <values> — set movement parameters for 6-sensor
    • input <6-sensor> nudger2e|nr <x-rot> <y-rot> <z-rot> — set coordinate adjusters
  • debuglevel|dl <value> — set the global debug level.
  • debugthistoo|dtt <value> — set the global debug-this-too.
  • debuglevel|dl[<N>] <value> — set process N's debug level
  • debugthistoo|dtt[<N>] <value> — set process N's debug-this-too.
  • window[<N>] fps {0,1} — turn off/on a window's fps display
  • window[<N>] fps_loc <v1>,<v2> — relocate a window's fps display
  • window[<N>] fps_color <v1>,<v2>,<v3> — set color of a window's fps display
  • window[<N>] sim — move the view of a simulator window
  • window[<N>] frame {0,1} — turn off/on rendering a window's frame outline in simulator view
  • window[<N>] nudgex <value> — shift the window by <value> along the X-axis
  • window[<N>] nudgey <value> — shift the window by <value> along the Y-axis
  • window[<N>] nudgez <value> — shift the window by <value> along the Z-axis
  • object window[<name>] <any window command> — affect a command on any window in the configuration
  • user[<N>] iod <v1> — set the iod of a user
  • user[<N>] color <v1>,<v2>,<v3> — set the color of a user
  • proc[<N>] end <v1> — set the end_proc flag of a process
  • proc[<N>] done <v1> — set the proc_done flag of a process

Note that setting the end_proc of a process to 1 tells that process to end itself, and except for the main process, whatever process that is will then terminate. The result of this will be a window that goes away, an input that stops inputting, or a telnet process that closes its connection and stops responding. Unfortunately, at the moment, there is no way to then resurrect that process or even start a different new process from scratch. This is on the list of things to do however, so one day this will be possible.

The Lock and Barrier Commands

The lock and barrier commands allow the operator to alter the state of existing locks and barriers in the system, and to create new locks and barriers for the purpose of testing. Locks can be set and released as reader or writer locks, and barriers can be called, to wait until the required number of processes have arrived at the barrier.

The purpose of these commands is almost exclusively for debugging purposes — both for debugging the FreeVR library itself, and also for debugging user applications which make use of locks and/or barriers.

Lock commands are specified by beginning the command line with the word lock or the letter l. Similarly, barrier commands use the word barrier or the letter b. These inputs are then followed by the specific operation (on the same line).

Here is the list of all the available lock operations:

  • help — print a message listing all the lock commands
  • create — create a new lock, printing its address
  • print|p <lock> — print the state of the lock
  • printall|pa <lock> — print the state of all the locks
  • trace|t <lock> <0 | 1> — set the lock's tracing flag
  • setwrite|sw <lock> — wait for and set the write state for the lock
  • relwrite|rw|uw <lock> — release the write state for the lock
  • setread|sr <lock> — wait for and set the write state for the lock
  • relread|rr|ur <lock> — release the write state for the lock

Here is the list of all the available barrier operations:

  • help — print a message listing all the barrier commands
  • create — create a new barrier, printing its address
  • print|p <barrier> — print the state of the barrier
  • printall|pa <barrier> — print the state of all the barriers
  • sync <barrier> — wait for all members to be at the barrier
  • relonce <barrier> — prematurely release the barrier
  • increment <barrier> — add one member to the barrier
  • decrement <barrier> — subtract one member from the barrier

Miscellaneous Commands

In addition to help, print, set, lock, and barrier there are a handful or two of other commands available to the FreeVR user. Three deal with termination of the connection (close), the telnet process (quit) and the entire system (term). Three commands deal with setting, unsetting and viewing variables: setenv, unsetenv, and echo. Five commands are used to control the verbosity to which information queries are responded: verbose, brief, one_line, machine, and fileformat.

But first, a couple of caveats. The unsetenv command does not work on all operating systems (such as IRIX). Not all the file formats are completely implemented (but they will default to an alternate option rather than print nothing). In particular, the "machine" file format has not yet been implemented, and this is a primary why a reasonable GUI interface has not yet been developed. And lastly, the term command is a bit of a cheat. It relies on the fact that the de facto standard for terminating FreeVR applications is by pressing the first (0th) button (usually the 'Esc' key). Thus, what the term command actually does is set the value of the first 2-switch to 1, and thus the program will recognize that as a user pressing the quit button, and it will begin the termination process.

Here is the list of all the upper tier commands (including "print" and "set"):

  • help — this list of commands

  • close — close the connection
  • quit — quit the telnet process
  • term — terminate FreeVR application

  • echo <string> — echo the string back to the output, with variable substitutions
  • setenv <envvar> <value> — set the value of an environment variable
  • unsetenv <envvar> — unset the environment variable

  • verbose — set verbose printing mode
  • brief — set brief printing mode
  • one_line — set one_line printing mode
  • machine — set print style to machine mode
  • fileformat — set the print style to file_format mode

  • print|p <query> — print some info about the FreeVR app
  • set|s <request> — set the value of part of the system

Using Telnet

TODO: consider moving this section to come before the command list

The "telnet" command on Unix and other operating systems provides a simple text interface through which one can send and receive (typically) ASCII information over an IP socket port. A server or some other program must already be listening for a socket connection request before telnet will establish the connection. Therefore, in this case the FreeVR application must be running, and be configured with a "telnet" process type.

To connect with a FreeVR application, one usually types something like:

	% telnet localhost 3000
In this case, we are greeted with the "FreeVR>" prompt after connecting with the same machine on which the telnet command is executed, and the FreeVR telnet process is listening on port 3000. We can, of course, very easily connect with the application from any other machine on the Internet, or same intranet. And the port is whatever is specified in the configuration. The telnet process will typically report to the shell window from which the application was run the name and port number to use to make a connection.

There is one further important note when running on a Linux machine: The telnet process blocks while waiting for user interface, so if there is an active telnet connection when the program quits, the telnet process will wait until something is input. In this case, simply hitting the "return" key should be sufficient.

© Copyright William R. Sherman, 2015.