The Virtual Reality Behavior System (VRBS):

Communications Protocol and PERL API Specification

* DRAFT *

David R. Nadeau, John L. Moreland
San Diego Supercomputer Center (SDSC)

Version 1.0, July 10, 1995


Introduction

This is a *DRAFT* protocol specification for the VRBS protocol being implemented at SDSC. This document is provided as a quick, but sparse, look at the details of the communications protocol. It is all subject to change as we find problems and modify it to fix them.

Justifications and system architecture for VRBS are discussed in two papers on VRBS, both to be presented at VRML 95 in December. Those papers are available at:


Protocol Structure

The VRBS protocol defines two types of communications packets: a message and a response. Messages are sent by the browser to the interpreter, or by the interpreter to the browser, whenever an action is intended.

Responses are acknowledgements of message receipt and execution and are sent by the browser to the interpreter, but never from the interpreter back to the browser. This non-symmetry is essential to avoid deadlocks. See the VRBS papers for more information.

Messages and responses always have three parts: the pre-header, the header, and the arguments. The pre-header part gives the size, in bytes, of the header. The header part gives the opcode class and opcode of the action desired, along with the size, in bytes, of the arguments. The arguments part gives a list of argument values that vary depending upon the opcode class and opcode.

The use of a pre-header byte count allows the header to have a different size in future versions of the protocol. Receivers of the message will read the entire header in, based upon the pre-header's stated size, but only process the fields they know about.

The use of an argument byte count in the header has the same purpose as that in the pre-header. This allows for a variable length list of arguments depending upon the opcode class and opcode.

Further discussion of these fields may be found in the VRBS papers.

Message

	Field			Internal	External

Pre-header:
	Header_nBytes		8-bit		1 byte (binary)

Header:
	Opcode_class		8-bit		whatever
	Opcode			8-bit		whatever
	Args_nBytes		32-bit ?	whatever

Args:
	Args...			whatever	whatever

Messages always give an Opcode_Class (general catagory of opcode), Opcode (the actual thing to do), and Args_nBytes (number of bytes in the arguments that follow).

Response

Pre-header:
	Header_nBytes		8-bit		1 byte (binary)

Header:
	Opcode_class		8-bit		whatever
	    Always "Response"
	Opcode			8-bit		whatever
	    Ack | Error
	Args_nBytes		32-bit ?	whatever

Args:
	Opcode_class		8-bit		whatever
	Opcode			8-bit		whatever
	Args...			whatever	whatever

Responses always give an Opcode_Class (always a "Response"), an Opcode (always either "Ack" or "Error"), and Args_nBytes (number of bytes in the arguments that follow).

In the argument list, the first two fields are always Opcode_class (a copy of the original message's Opcode_class field), and Opcode (also a copy from the original message). The remaining arguments are a return value (for "Ack" messages) or an error message (for "Error" messages).

All fields (except the Header_nBytes field) are NULL-terminated variable-length strings. The Header_nBytes field is a binary 1-byte value.


Protocol

The VRBS protocol divides messages in to opcode classes. Each class groups together a set of opcodes all used for a similar purpose. For instance, all messages from a behavior script to a world managed by a browser are in the ClBehaviorToWorld opcode class. This includes opcodes like OpSetNodeField to set a field in a node, and OpReplaceNode to replace a node.

Opcode classes follow a naming convention. The first two characters are always "Cl" for "class". The next word is the name of the type of sender, such as "Behavior" or "Browser". Next is the word "To", followed by the name of the type of receiver, such as "Interpreter" or "World".

The following sections list each of the opcode classes and their opcodes.

Classes and Opcodes

[0]	ClNone
	------

	[0]	OpNone			-
			Ack returns	-



[1]	ClResponse
	----------

	[0]	OpAck			opcodeClass, opcode
			No Ack

	[1]	OpError			opcodeClass, opcode, erCode, erMsg
			No Ack



[2]	ClBehaviorToWorld
	-----------------

	[0]	OpGetWorldUrl		worldId
			Ack returns	url

	[1]	OpGetNodeNames		worldId
			Ack returns	nameList, typeList

	[2]	OpGetNodeBBox		worldId, nodeName
			Ack returns	w, h, d, x, y, z

	[3]	OpGetNodeType		worldId, nodeName
			Ack returns	nodeType

	[4]	OpSetNodeField		worldId, nodeName, fieldName, fieldVal
			Ack returns	-

	[5]	OpGetNodeField		worldId, nodeName, fieldName
			Ack returns	fieldVal

	[6]	OpSetNodeField1		worldId, nodeName, fieldName, index, val
			Ack returns	-

	[7]	OpGetNodeField1		worldId, nodeName, fieldName, index
			Ack returns	val

	[8]	OpDeleteNode		worldId, nodeName
			Ack returns	-

	[9]	OpInsertNode		worldId, nodeName, iLoc, vrmlText
			Ack returns	-

	[10]	OpReplaceNode		worldId, nodeName, vrmlText
			Ack returns	-



[3]	ClBehaviorToBehavior
	--------------------

	No opcodes at this time



[4]	ClBehaviorToBrowser
	-------------------

	[0]	OpGetBrowserHost	-
			Ack returns	hostName

	[1]	OpGetBrowserPort	-
			Ack returns	portNum

	[2]	OpGetBrowserName	-
			Ack returns	browserName

	[3]	OpGetBrowserVersion	-
			Ack returns	versionNum

	[4]	OpGetBrowserFeatures	-
			Ack returns	featureList

	[5]	OpGetBrowserNodeTypes	-
			Ack returns	typeList

	[6]	OpGetBrowserNodeFields	typeName
			Ack returns	fieldList

	[7]	OpGetBrowserViewerTypes	-
			Ack returns	viewerList



[5]	ClBehaviorToInterpreter
	-----------------------

	No opcodes at this time



[6]	ClBrowserToWorld
	--------------

	No opcodes at this time



[7]	ClBrowserToBehavior
	-----------------

	No opcodes at this time



[8]	ClBrowserToBrowser
	----------------

	No opcodes at this time



[9]	ClBrowserToInterpreter
	--------------------

	No opcodes at this time



[10]	ClInterpreterToWorld
	------------------

	[0]	OpAddEventInterest	worldId, eventType, eventParams...
			Ack returns	-

	[1]	OpRemoveEventInterest	worldId, eventType, eventParams...
			Ack returns	-

	[2]	OpReady			worldId
			Ack returns	-



[11]	ClInterpreterToBehavior
	-----------------------



[12]	ClInterpreterToBrowser
	----------------------

	[0]	OpHello			-
			Ack returns	protoVersion, protoParams...

	[1]	OpInformation		worldId, erCode, erMsg
			Ack returns	-

	[2]	OpWawrning		worldId, erCode, erMsg
			Ack returns	-

	[3]	OpError			worldId, erCode, erMsg
			Ack returns	-



[13]	ClInterpreterToInterpreter
	--------------------------

	No opcodes at this time



[14]	ClWorldToWorld
	--------------

	No opcodes at this time



[15]	ClWorldToBehavior
	-----------------

	[0]	OpBehaviorStart		worldId, pkgName
			No Ack

	[1]	OpBehaviorStop		worldId, pkgName
			No Ack

	[2]	OpBehaviorEvent		worldId, eventType, eventParams...
			No Ack



[16]	ClWorldToBrowser
	----------------

	No opcodes at this time



[17]	ClWorldToInterpreter
	--------------------

	[0]	OpLoadBehavior		worldId, pkgName, behaviorText
			No Ack

	[1]	OpLoadBehaviorFile	worldId, pkgName, localFileName
			No Ack

	[2]	OpUnloadBehavior	-	
			No Ack

	[3]	OpQuitInterpreter	-
			No Ack

All opcodeClass and opcode values are reserved for future expansion, including those not listed above.

Arguments

The opcode argument names listed in the preceding section are defined below.

Errors Codes

[0]	ErIllegal
[1]	ErSyntax
[2]	ErResources
[3]	ErBadWorld
[4]	ErBadNodeName
[5]	ErBadFieldName
[6]	ErBadFieldValue

Event Codes

[0]	EvNodeButtonPress
[1]	EvNodeButtonRelease
		Interest		worldId, nodeName
		Delivery		worldId, nodeName, butMask, keyMask

[2]	EvNodeKeyPress
[3]	EvNodeKeyRelease
		Interest		worldId, nodeName
		Delivery		worldId, nodeName, butMask, keyMask, key


[4]	EvNodePointerWithin2
[5]	EvNodePointerEnter2
[6]	EvNodePointerLeave2
		Interest		worldId, nodeName
		Delivery		worldId, nodeName, butMask, keyMask,
					x, y

[7]	EvNodePointerWithin3
[8]	EvNodePointerEnter3
[9]	EvNodePointerLeave3
		Interest		worldId, nodeName
		Delivery		worldId, nodeName, butMask, keyMask,
					x, y, z

[10]	EvNodeChange
		Interest		worldId, nodeName
		Delivery		worldId, nodeName

[11]	EvNodeFieldChange
		Interest		worldId, nodeName, fieldName
		Delivery		worldId, nodeName, fieldName

[12]	EvTimer
		Interest		worldId, timeOffset
		Delivery		worldId, timeOffset

[13]	EvWorldEnter
[14]	EvWorldLeave
		Interest		worldId
		Delivery		worldId

Feature Codes

vrml1.0		Supports the full VRML 1.0 spec.
vrml1.1		Supports the full VRML 1.1 spec.
inventor1.0	Supports the full OpenInventor 1.0 spec.
inventor2.0	Supports the full OpenInventor 2.0 spec.

Viewer Codes

examiner	Supports an examiner viewer.
fly		Supports a fly viewer.
plane		Supports a plane viewer.
walk		Supports a walk viewer.

Perl API

A new PERL interpreter is started for each top-level world in a browser. The interpreter is killed when the browser flushes the top-level world from it's memory cache. So, there may be more than one interpreter running at any given time.

All functions return a -1 or NULL on failure, and 0 or a usable value on success.

World Attributes
----------------

$url =		&GetWorldUrl( $worldId )
$id =		&GetWorldId( )
@nodeNT =	&GetNodeNames( $worldId )



Node Instance Attributes
------------------------

( $w, $h, $d, $x, $y, $z ) = &GetNodeBBox( $worldId, $nodeName )

$nodeType =	&GetNodeType( $worldId, $nodeName )

$status =	SetNodeField( $worldId, $nodeName, $fieldName, $fieldVal )
$fieldValue =	GetNodeField( $worldId, $nodeName, $fieldName )

$status =	SetNodeField1( $worldId, $nodeName, $fieldName, $index, $val)
$val =		GetNodeField1( $worldId, $nodeName, $fieldName, $index )

$status =	DeleteNode( $worldId, $nodeName )
$status =	InsertNode( $worldId, $nodeName, $iLoc, $vrmlText )
$status =	ReplaceNode( $worldId, $nodeName, $vrmlText )



Browser Attributes
------------------

$hostName =	&GetBrowserHost( )
$portNum =	&GetBrowserPort( )
$browserName =	&GetBrowserName( )
$versionNum =	&GetBrowserVersion( )
@featureList =	&GetBrowserExtensions( )

@types =	&GetBrowserNodeTypes( )
@fields =	&GetBrowserNodeFields( $typeName )
@viewers =	&GetBrowserViewerTypes( )


World Events
------------

$eventId =	&AddEvent( $func, $data, $eventType, %eventParams )
$status =	&RemoveEvent( $eventId )

Event functions will be called with:

	&func( $eventId, $data, $eventType, %eventParams )

Event parameters are tag-value pairs:

	"butMask"	$butMask
	"fieldName"	$fieldName
	"key"		$key
	"keyMask"	$keyMask
	"nodeName"	$nodeName
	"timeOffset"	$timeOffset
	"worldId"	$worldId
	"x"		$x
	"y"		$y
	"z"		$z

See the event discussion in the protocol section for event interest and detail parameters.
Dave Nadeau, nadeau@sdsc.edu, John Moreland, moreland@sdsc.edu, September 1995
San Diego Supercomputer Center (SDSC), San Diego, CA