\documentclass[10pt]{article}

%----------------------------------------------------------------------
% usepackage statements.  
%
% The latexsym package is required for proper display of the generated plots
% that we're going to be importing. 
%----------------------------------------------------------------------

\usepackage{latexsym}
\usepackage{graphicx}

%----------------------------------------------------------------------
% Create the title page.
%----------------------------------------------------------------------

\title{RMIF Reference Manual}
\author{Gordon James Miller}

%----------------------------------------------------------------------
% Begin the document
%----------------------------------------------------------------------

\begin{document}

\maketitle

\section{Introduction}

Java's RMI and CORBA are designed to facilitate access to ``objects'' residing
on a remote server. In the local process, a proxy object is created that has
the required interface for the object. Method invocations on the proxy object
are converted into a data stream and delivered to the servant process running
on the remote host. The servant process performs the work required by the
method. The results of the method are converted into another data stream and
sent back to the proxy object on the local machine. The proxy object
reconverts the data it receives into objects and passes these back to the
caller. The communication and data conversion are completely hidden to the
caller, giving the same appearance as if the call was done to a local object.

The RMIF protocol is a take-off on Java's Remote Method Invocation (RMI)
protocol. The main purpose of the RMIF protocol is to allow NeXtMidas GUIs to
control Midas applications at remote sites. While the protocol may be applied
to other problems, it's primary goals are to minimize link bandwidth for
data displays and to respond robustly to network drop-outs common to
real-world long-distance multi-hop links. 

Java's RMI was not used for a number of reasons.

\begin{enumerate}

\item Server side applications are not typically Java based.  Java RMI
requires that both the client and servant are written in Java.  This is
because RMI depends on Java serialization to implement the protocol. 

\item The standard RMI implementation is layered on TCP, which severly limits
throughput and rhobustness over real-world links. 

\item Object serialization requires unnecessary over-head and data conversions
to/from network ordering for data displays.

\end{enumerate}

The RMI reference was kept to make it easier for developers that may have
experience with Java RMI.  The concepts and methodology were paralleled
wherever possible.

\section{Remotes and Channels}

\section{Protocol}

RMIF is a packet based protocol that is layered on top of UDP. All routing to
and from remote objects is handled by the UDP header. There is no subrouting
within the RMIF protocol. An RMIF object is defined by a node name (or network
address) and a port number.

An RMIF packet is a 32768 byte packet that begins with an 8-byte header and is
followed by eiter an adjunct header or data. Table~1 shows the sequence of
bytes and their layout in the packet. The size of the data portion of the
payload is the UDP packet size minus the 8 byte header and the adjunct header
if the ADJ byte is greater than zero.

\begin{center}
\begin{tabular}[t]{cll}
Byte Offset & Name & Description \\
\hline
0 & FUNC & Message type.  See the Functions section for details on this. \\
1 & FLAG & Protocol version number and options mask. \\
2 & INFO & Channel number for fast routing of monitored properties. \\
3 & REP  & Packet data representation (VAX|IEEE|EEEI). \\
4 & SEQ  & Sequence number (0-127) for reliable.  \\
5 & TRY &  Number of resends for Reliable packets.  \\
6 & RPT &  Report sequence number.  \\
7 & ADJ &  Number of bytes in adjunct header \\
\hline
\end{tabular}
\end{center}


Another benefit of UDP is that it is connectionless.  A UDP port on a machine
is basically a bucket on a node to catch network packets that are thrown at it.
They can be thrown from anywhere, from any number of sources, in any order.  
Each packet contains the network address and port number of who threw the 
packet, so you can throw something back if called for.  Then you're done.  
No opens, no closes.  Network problems cannot cause connections to hang in an 
unknown state, because there never is a connection.  This leaves the timing 
out and recovery to the application, where appropriate tuning may be applied.

Another benefit of UDP is throughput.  In TCP, system drivers usually 
limit the number of outstanding packets to 12.  This means that until the
remote connection receives the packet and acknowledges receipt, the local 
socket will hold-off outgoing packets.  Using typical a typical maximum 
transfer unit, MTU, ot 1500 bytes and roundtrip delay of 500 ms, we can 
calculate a maximum sustained transfer rate of 12*1500/.5 = 36kby/sec.

\section{Functions}

The currently supported functions and their corresponding byte numbers are:

\begin{center}
\begin{tabular}[t]{lcl}
Name     & Val & Description \\
\hline
SET      & 101 & Set a named property \\
GET      & 102 & Request the value of a named property \\
RET      & 103 & Return the value for a GET request \\
ACK      & 104 & Acknowledge the value for a SET request \\
OPEN     & 105 & Open connection to a remote or a channe \\
OPENED   & 115 & Acknowledges an OPEN request \\
CLOSE    & 106 & Close connection to a remote or a channel \\
CLOSED   & 116 & Acknowledges an CLOSE request \\
MODIFY   & 114 & Modify a channel connection \\
PING     & 109 & Request keep-alive status. \\
PONG     & 110 & Response to a PING. \\
DHDR     & 111 & Process data header \\
DBUF     & 112 & Process data buffer \\
DBUFC    & 117 & Process compressed data buffer \\
DBUFD    & 118 & Process compressed data buffer \\
GETPROP  & 121 & Request list of published properties \\
RETPROP  & 122 & Return number of properties or property names \\
RECEIPT  & 123 & Acknowledge receipt of a reliable packet \\
LINKTEST & 124 & Perform a linktest between the client and servant. \\
\hline\\
\end{tabular}
\end{center}

\subsection{GET/RET/SET/ACK}

Remote property access is accomplished with the GET, RET, SET, and ACK
functions. These methods allow a client to retrieve and set the values of
properties on the remote server.  The set of properties that can be retrieved
from the remote server can be retrieved using the GETPROP function.  The set
of properties that are being set or retrieved is encoded within the data
section of the packet.

The encoding of the data for the GET and SET packets is done in ASCII.  The
format for the encoding supports encapsulating multiple property name/value
pairs within the same packet.  The syntax of the encoded data is name/value
pairs where the name of the property and its value are seperated by and equals
sign and the name/value pairs are seperated by commas.  The entire string must
be encapsulated within a pair of curly braces.

For example, to set freq, amp, and options properties on a remote object the
data portion of a RMIF packet with the FUNC=SET would be (notice in this case
that the options arg is a structure, and must be recursively encoded in this
format):

\begin{verbatim}
   {FREQ=1.3E6,AMP=1,OPTIONS={MODE=1,AXIS=NONE}}
\end{verbatim}


When a GET packet is received by the servant, it MUST send an ACK packet back
to the caller. The data section of the ACK MUST contain the encoded values of
the properties that were requested, in the same order that they were
requested.

When a SET packet is received by the servant, it MUST send a RET packet back
to the caller. The data section of the RET MUST contain the encoded current
values of the properties that were set, in the same order that they were
requested. In this way, the caller can verify that the properties were set
correctly.

\subsection{PING/PONG}

Provides a mechanism to determine if an RMIF servant is alive and listening to
packets. When a ping is received by the servant process it MUST send an exact
copy of the received packet with the FUNC byte changed from PING to PONG back
to the caller. The data that is contained within the packet is not to be
changed by the servant. Client applications can rely on this to use PING
packets to measure latency by embedding the time that the packet is sent
within the PING. The PONG response will then contain this same time and can be
compared against the current time to measure latency.

The representation of any data within PING and PONG packets is undefined. This
is allowed by the requirement that the servant not manipulate the data within
the PING packet and the PONG goes back only to the caller.

While a connection is established between a client and a servant, the client
will periodically send PING packets to the servant to determine the alive
status of the servant and the latency.

\subsection{GETPROP/RETPROP}

These functions are used to retrieve the set of properties for an RMIF
servant. The GETPROP function uses the INFO header field to specify the name
of the property to retrieve. If the INFO field is set to zero, then the caller
is requesting the number of properties that are supported. If the INFO field
is set to a value greater than zero, then the caller is requesting the name of
the property with that index.

When a servant receives a GETPROP function, it MUST send a RETPROP packet back
to the caller. The contents of the data section of the RETPROP will contain
either the number of properties that are supported, or the name of the
property at the requested index.

Notes:
\begin{enumerate}
\item According to the original rmif fortran code, the returned property name
      contains only the first 4 characters.
\item Why do we not just send all of the names of all of the properties when
      the INFO field contains 0.
\end{enumerate}

\subsection{OPEN/OPENED}

OPEN packets are used by the client to open a communication connection between
it and the servant.  The client MUST send an OPEN packet with the INFO field
set to zero in order to establish communication with the servant.  The servant
will create a new remote and associate this new remote with the address and
port of the OPEN packet (taken from the UDP packet information).

The client may also send OPEN packets with the info field set to a positive
integer to open a channel for a particular set of data.

The servant, when it receives any OPEN packet MUST respond with an OPENED
packet with the INFO field set to the same value that was received.

\subsection{CLOSE/CLOSED}

CLOSE packets are used by the client to indicate to the servant that it is no
longer interested in receiving the data from that channel or the remote. As
with the OPEN packet, the INFO field indicates whether to close the entire
connection (INFO = 0) or just a channel (INFO > 0).

The servant, when it receives any CLOSE packet MUST respond with a CLOSED
packet with the INFO field set to the same value that was received. After
receiving the CLOSE packet, no information will be sent to that channel or
that remote depending on what was closed.

\subsection{MODIFY}

\subsection{DHDR/DBUF/DBUFC/DBUFD}

These are the data packets. DHDR packets contain header information, DBUF
packets contain the raw data, DBUFC packets contain compressed data, and DBUFD
packets contain ???.

Normally these packets are sent unreliably.

Notes:
\begin{enumerate}
\item What is the compression algorithm used?
\item What is a DBUFD packet?
\end{enumerate}

\subsection{RECEIPT}

These packets are used to acknowledge the receipt of any packet that has been
marked for reliable delivery. The SEQ number of the outgoing RECEIPT packet
MUST match the sequence number of the received packet. Due to their nature
RECEIPT packets don't get processed the same way as the other packets. They
are not acknowledged nor are they included as part of the sequencing
algorithm. Their only purpose is to indicate that the remote process has
received the packet.

\section{Delivery}

UDP is a connectionless, non-guaranteed protocol. For some types of packets
that are exchanged between and RMIF servant and client, this is acceptable,
for others it is not. Typically, data display packets do not need to be sent
reliably, while all others require some reliability. The RMIF protocol
implements a reliable sending algorithm for those packets that require some
sort of guarantee of delivery.

Unreliable packets set the SEQ header byte to -1. Reliable packets have SEQ
set to a counter (0-127) by the sender, along with a retry count TRY. If the
sender does not get a receipt in a reasonable time, it will resend the packet. 
By combining the reliable and unreliable streams in the same socket, priority
schemes can be implemented that, for instance, favor controls over data.

When a servant receives a packet that has a SEQ number greater than zero, it
MUST send a RECEIPT packet.  The RECEIPT packet MUST have its SEQ number set
to the same value as the SEQ number in the received packet.

(reasonable delay = after a tunable tolerance plus the last measured round
trip delay.)

\section{Representation}

RMIF must operate within a heterogenous environment. Each RMIF header MUST
specify the representation of the data in the REPR field.  The allowed values
are as follows

\begin{description}
\item[67] CRAY data representation.
\item[69] EEEI data representation.
\item[73] IEEE data representation.
\item[86] VAX data representation.
\end{description}

Applications SHOULD check the representation and only perform data conversions
if necessary.

\end{document}
