The DIVE Client Interface

Reference Document
Web site: <http://www.sics.se/dive/manual/dci.html>

Emmanuel Frécon - <emmanuel@sics.se>
Olof Hagsand - <olof@sics.se>
The Swedish Institute of Computer Science, Stockholm, November 23, 1995

1. Introduction

This document describes the principles and the functionalites of the DIVE Client Interface, also known as DCI. It requires some background knowledge about C, TCL [1] and DIVE [2] [3].

Previously, the only way to interface with the DIVE system from an external programming environment was to link the external program with the DIVE libraries. The Dive/Tcl interface [5] represents a step forward for those who want to prototype or to write simple applications by enabling simple scripting code in Tcl. However, the Dive/Tcl interface has only limited capabilities to communicate with external applications.

The DCI interface described in this document offers an alternative way to interface DIVE with external programming environments, such as applications written in other languages, or complex programming systems in need of a clean separation.

In short, every DIVE application can act as a TCP server, listening for connections and offering Dive/Tcl capabilities to any connected client. Clients can send Dive/Tcl commands to the TCP server, receive replies and be notified when given DIVE events occur.

This document first describes how an external application (the client) communicates with a Dive peer (the server) over a Tcp connection, followed by a description of the Dive/Tcl commands that have been added to DCI. The PDU format is then described and a simple example concludes the document.

2. Communication Layer

An external application (DCI client) starts a communication with a Dive peer (DCI server) by establishing a TCP connection to the the DCI server on a predefined port (currently the default port is 7120).

After the connection is established, the client can send Dive/Tcl commands over the connection, and receive output from the server.

2.1. Client to server

The client simply sends Dive/Tcl command strings over the TCP connection for the server to evaluate in its Dive/Tcl interpretor. As usual, Dive/Tcl commands must be terminated by carriage-return to mark the end of a command.

2.2. Server to client

Three different types of information may be relayed from the server to the client. Therefore, an abstract notion of "channels" have been used. The different channels are relayed over the same TCP connection. However, an integer in each packet defines which channel the message belongs to.

The three different types of information (channels) are the following:

3. DCI Command Interface

3.1. Dive/Tcl Command Interface

DCI clients can use the set of Dive/Tcl commands described in [5]. The behaviour of "dive_register" is however slightly different. Indeed, the result of registered procedures is sent back to the DCI client on a specific channel.

A list of all events that can be registered and all Dive/Tcl commands can be found in [5].

For each DCI client currently connected, an actor is created and distributed. Actors are discussed in [6].

3.2. DCI Specific Commands

3.2.1. dci_out channel msg

Send back on the communication channel "channel" (see section 2) the message contained in the string "msg". This specific command can be used when objects in the world (typically inserted by the DCI client) want to send back results to the DCI client. This is performed by sending a command containing "dci_out" to the actor corresponding to the DCI client. The channel numbered 0, 1 and 2 correspond to the channels listed in section 2.2. No check on the channel number is performed, allowing applications to use some other channel numbers, if needed.

4. Low-Level Protocol

Communication between clients and servers is done over a TCP/IP connection. The separate channels, as described in Section 2, are implemented by a number in the header of each message. The structure of each message is the following:

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                        Magic = 710420                         :
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   :                        Nbyte                                  :
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   :                        Channel                                :
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   :                        Dive/Tcl Command                       :
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   :                        ...                                    :
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

"Magic" is a magic number, stored in a machine independent unsigned long. "Nbyte" is the size in bytes of the string part of the message, stored in a machine independent unsigned long. "Channel" indicates the channel of the reply from the server to the client. The channel value is 0 for Succesful command return, 1 for erroneous command return and 2 for Dive event notification. "Channel" has no meaning for client to server communication. "Dive/Tcl Command" contains a NULL terminated Dive/Tcl command string with length "Nbyte".

"Magic", "Nbyte" and "Type" are in network byte order unsigned 32-bit integers.

5. Examples

5.1. DCI Script

The following example defines a Dive/Tcl script that moves an object upwards when it is selected by a user:

     proc move_up {type id sub_type origin src_id x y z} {
       dive_move $id 0 0.5 0 LOCAL_C
       return "Click $id"
     }
     
     set ball [dive_find_entity_byname "ball"]
     dive_register INTERACTION_SIGNAL DIVE_IA_SELECT $ball \
        "" move_up

The example shows how the "move_up" Tcl procedure is registered (by "dive_register") to be invoked when a Dive "select" (interaction signal of type select) occurs at the object named "ball". The "move_up" procedure itself only calls "dive_move" to displace the object.

Note that this example is similar to the example at the beginning of [5], except that it sends back information to the DCI client, namely which object was clicked.

5.2. C example

In <http://www.sics.se/dive/manual/examples/divesh.c>, an example of how external C applications can use the DCI interface can be found. This example is able to handle two usual cases:

  1. It is able to read a Dive/Tcl script file, establish a connection with a DCI server (i.e. a Dive application which was started with the DCI option on), and gives the content of the script file for execution to the DCI server. It will then live until the user abort it. An example of a script that can be executed from this application can be found in <http://www.sics.se/dive/manual/examples/dci_clock.tcl>.
  2. It is able to establish a connection with a DCI server (i.e. a Dive application which was started with the DCI option on) and to submit for execution each line the user enters. All messages coming from the server on channel 0 are written to stdout. All messages coming from the server on channel 1 are written on stderr. All messages coming from the server on channel 2 are formatted then written on stdout. An example of what a user can enter at the command line can be found in section 5.1.

References

[1] Tcl and the Tk toolkit, John K. Ousterhout, Addison-Wesley Publishing Co., 1994

[2] Dive 2.2 reference manual

[3] Christer Carlsson and Olof Hagsand, "Dive - A Platform for Multi-User Virtual Environments", "Computers and Graphics", 17(6), 1993

[4] Dive 3.2 file format interface

[5] Emmanuel Frécon and Olof Hagsand, "The Dive/Tcl Behaviour Interface", Reference Document, available at <http://www.sics.se/dive/manual/tcl-behaviour.html>

[6] Tomas Axling, Emmanuel Frécon and Olof Hagsand, "Actors or Process Bound Entities", Reference Document, available at <http://www.sics.se/dive/manual/actor.html>