RemoteTerminalDoc.tioga
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Last tweaked by Mike Spreitzer on March 22, 1991 9:43 am PST
Willie-sue, April 21, 1988 12:08:30 pm PDT
RemoteTerminal
CEDAR 7.0 — FOR INTERNAL XEROX USE ONLY
RemoteTerminal
Mike Spreitzer
© Copyright 1987, 1988 Xerox Corporation. All rights reserved.
Abstract: The RemoteTerminal package allows one Cedar machine to provide terminal services (mouse & keyboard input, screen output) for another.
Created by: Mike Spreitzer
Maintained by: Mike Spreitzer <Spreitzer.pa>
Keywords: Terminal, Remote Terminal, Remote Host, Terminal Location, Advice, X11
XEROX  Xerox Corporation
   Palo Alto Research Center
   3333 Coyote Hill Road
   Palo Alto, California 94304

For Internal Xerox Use Only
0. Introduction
These packages make it possible for one machine (called the "terminal" machine, or the "server") act as a terminal for another (called the "host" machine, or the client). In the context of the HomeComputing project, the terminal machine would most usefully be at home, and the host machine in the office.
1. User Interface
On the host machine:
In DCedar:
Boot with the standard bootfile, using the J switch; this will do a full boot but use Remote.loadees instead of the usual Basic.Loadees. If you roll your own loadees, be sure to start from Remote.loadees, which you can find with `OpenR Remote.Loadees'. Alternatively, you can `Install RemoteViewersHost' (in a directory into which you've BroughtOver the public parts of RemoteViewersHost.DF).
Make a checkpoint, if you wish (if you don't, of course, rollback or boot will nullify the effects of this boot/installation).
In PCedar:
Use the RemoteViewersHost world(s) instead of RawViewers or X11Viewers. There is a RemoteViewersHost.commad, so you can
unix% CedarCommander RemoteViewersHost
You cannot run more than one RemoteViewersHost world on a machine at a time. When use of the LocalRegistryDaemon becomes widespread, this will change.
The `Bye' button is not recommended yet.
On the terminal machine:
In DCedar:
Installation goes like this:
% BringOver -mp RemoteTerminal
... boring output ...
To be a terminal for, e.g., McCormick, do this when McCormick is idle:
% TerminalByVirtual
... boring output ...
% ConnectTo pup[McCormick]
%
There are two styles of terminal implementation available. One uses the D-machines' virtual terminals in a manner very similar to the way Cedar does. The other uses Viewers. The commands `TerminalByVirtual' and `TerminalByViewer' indicate which style you wish to use; you cannot connect to a machine without indicating an implementation style.
If something goes wrong, an error message would have been printed out. What this step is doing is trying to convince McCormick that this machine will provide terminal services for it.
The host address is given as a protocol family followed by an address or name in brackets. Case is significant in the protocol family name. Examples are "pup[McCormick]", "pup[3#265#]", "xns[Tallahatchie]", "xns[0-003.2-857-435-576.]", "arpa[Skipjack]", and "arpa[13.0.12.200]".
A terminal machine may be a terminal for more than one host at a time.
In PCedar:
First issue the `TerminalByViewer' command or the `TerminalByX11Bitmap' command, to specify which style of terminal implementation you wish to use (there may be other styles available in the future). Then `RemoteTerminalConnectTo HostName'.
In PCedar, host names are given as `<host>-<protocol>:<control port>'. If the <protocol> is `ARPA' and the <host> has no dash in it, the `-<protocol>' can be omitted. Currently, ARPA is the only protocol available. If the <control port> is 58812, the `:<control port>' can be omitted. Currently, the control port is always 58812.
You cannot yet run the RemoteTerminal in more than one Cedar world on a machine at a time.
The TerminalByX11Bitmap command creates an X window whose application (in Cedar XTk terminology) is ``X11RemoteCedarTerminal''. You can thus control where the X window appears by issuing the command
% X11DefaultServer viewmachine:0.0
in the Terminal Cedar world, which will cause subsequent creations of the X window to appear on screen 0 of X server 0 on the machine named ``viewmachine''. You can elide the ``.0'' or the ``:0.0'', as those are the defaults.
Using the RemoteTerminal/RemoteHost system for advising (DCedar only)
There are two ways.
In the first way, the advisee sets the BOOLEAN variable RemoteViewersHost.cc to TRUE (after loading the Remote Host software, of course), and then uses the RemoteTerminal/RemoteHost system is used in the normal fashion. This involves the advisee idling, and the advisor remotely logging in to the advisee's machine. Because RemoteViewersHost.cc is TRUE, output goes to both screens, and the advisee can see what the advisor is doing.
The second way is a special perversion of the RemoteTerminal mechanisms, and does not involve changing who's logged in. Both the advisor and the advisee each issue a command to set up the advice session, and they both issue a command to close down the advice session. Checkpoints should not be made during advice sessions. An advise session is started by the advisor issuing the "Advise AdviseeMachine" command, and then the advisee issuing the "AdviceFrom AdvisorMachine" command, in that order. Note the spelling, and that the appropriate machine names have to be substituted. While this connection is being set up, the advisor may temporarily see a screen full of trash; more likely he will temporarily see a misleading screen (e.g., one that looks like his last use of the SimpleTerminal, which was probably to log in). During the advice session, the advisee also gets to see output on his screen, including cursor tracking. To close down the session, the "StopAdvise" command must be executed on the advisor's machine. To do this, the advisor must manually swap virtual terminals (with control-leftshift-rightshift) back to his native terminal, and issue the command. Also, the "RejectAdvice" command may optionally be executed on the advisee's machine, either before or after the advisor does "StopAdvise" (note that if it's done before, it must be done by the advisor, because he's the one driving the advisee's machine).
Protocol Version Mismatches
There are three different network protocols involved in the RemoteTerminal system (TerminalCoordination, SimpleTerminal, and Viewers). All are subject to further development. To help avoid confusion, there is a little version checking done whenever such a network stream is opened. A version is a small integer (e.g., 10). Each side (host and terminal) knows the range of versions that it is willing to use, and the conversation begins with an exchange of these ranges. If there is any overlap, the conversation takes place in the highest version of the protocol that both sides are willing to use. If there is no overlap, the conversation terminates. If you're lucky, there'll be messages posted in the MessageWindows of the host and terminal explaining that this has happened, and giving the protocol version ranges that the two machines are willing to use. Knowing these ranges tells you how to fix the problem. Update one or both of the machines so there's some overlap in the versions they're willing to use. The latest versions of the host and terminal software are willing to speak the following versions:
Protocol  | Host | Terminal
Coordination  | [1..2] | [1..2]
Simple Terminal I/O | [1..1] | [1..1]
Viewers I/O  | [10..16] | [10..16]
On a running system, you can determine what versions the software you're running are willing to use by issuing the `HostVersions' and `TerminalVersions' commands.
Transport Chaos (DCedar only)
Things are still chaotic. The Cedar packages have variants that don't use certain of the transport protocols. The CedarChest packages consult CommDriverRegistry and use whatever's available.
In general
For DCedar
The host machine will go idle whenever it doesn't know where its terminal is. In particular, whenever you hard-boot it, it doesn't know where its terminal is.
The location of the terminal can change only when the host is idle. While in idle, if a key is hit, the location becomes the local hardware. If, while idle, an offer of terminal services comes in over the network, it will be accepted.
In general, both sides (host and terminal) of this software try to show the appropriate screen to the user. If this fails, try manually swapping screens (with control-shift-shift).
You can disconnect by idling the host. The host will drop the connection if it misses communication with the terminal long enough for PUP streams to decide it's really gone (on the order of a minute); note that the host does not miss communication while it is doing low-level things like inloading and outloading memory (e.g., for a checkpoint, rollback, or boot). You can break the connection from the terminal side by issuing the "Disconnect" command.
You can do full boots, and use Iago, and make checkpoints, and all that stuff, remotely --- except when using ARPA (ie TCP/IP) protocols, due to misfeatures in the bootfile. The only things you can't do remotely are hit the physical boot button and hold down keys to indicate boot switches.
Although keyboard sampling and mouse/cursor tracking are done on the terminal, things like the fast-mouse parameters and screen escapes are determined by the host. That is, whatever they are set or changed to on the host is sent down to the terminal and obeyed, as best possible.
Viewers is automatically told to assume the size of the black-and-white display is that of the terminal's viewport.
Color somewhat works. The color display method (e.g., Dither8, SmoothFullColor, &etc) is determined by the host and sent down to the terminal, which tries to cooperate. The side for the color display, and its resolution, are also controlled from the host. In an ideal world, the host's default choices for these things would depend on the terminal's physical details and machine profile; but this is not an ideal world.
Fiala/Greene compression will be used on the Imager operations iff both sides are willing. Both PCedar sides default to willing, and both DCedar sides default to unwilling.
For PCedar
Watch the SystemScript for informative and debugging messages.
For Both
The flavor (D or P) of the host and terminal are independent --- they work in any combination.
2. Commands
name TerminalByViewer:
syntax
TerminalByViewer
description
Specifies an implementation style for remote terminals. This style presents the remote Viewers world in a Viewer in the terminal world. The remote terminal viewer can be scrolled, but not scaled. The remote terminal viewer can be moved and resized. Due to the nature of the Imager interface, the remote terminal viewer cannot be scrolled, moved, or resized during the time that an Imager.DoWithBuffer operation or ImagerBackdoor.SaveBuffer* .. ImagerBackdoor.DiscardBuffer sequence is executing. The implementation ensures this restriction by holding the Viewers lock on the viewer during such operations. The only `normal' use of ImagerBackdoor.SaveBuffer* .. ImagerBackdoor.DiscardBuffer is pop-up menus of various kinds. Tioga paints each line with a Imager.DoWithBuffer operation. I'm not aware of other uses of these operations.
examples
% TerminalByViewer
stop/undo
Don't even try.
name TerminalByVirtual:
syntax
TerminalByVirtual
description
Specifies an implementation style for remote terminals. This style presents the remote Viewers world in a Terminal.Virtual, as is available only in DCedar.
examples
% TerminalByVirtual
stop/undo
Don't even try.
name RemoteTerminalConnectTo:
Aliases
RTConnectTo: RTCT:
syntax
RemoteTerminalConnectTo HostName*
description
Offer termial services to the given hosts.
examples
% RemoteTerminalConnectTo arpa[Skipjack]
stop/undo
Idling the Host machine or using the Disconnect command below will retract this offer.
name RemoteTerminalDisconnect:
Aliases
RTDisconnect: RTD:
syntax
RemoteTerminalDisconnect HostName*
description
Retract offer of termial services to the given hosts. If no hosts are given, all offers are retracted.
examples
% RemoteTerminalDisconnect
stop/undo
The RemoteTerminalConnectTo command can be used to make a new offer.
name See:
syntax
See HostName
description
Currently, the RemoteTerminals software provides terminal services for a remote host on a local Terminal.Virtual (the things that you cycle through with control-shift-shift). The See command selects the Terminal.Virtual being used for the given host.
examples
% See arpa[Skipjack]
name ListHosts:
syntax
ListHosts
description
Lists the set of hosts that this machine is currently willing to provide terminal services for.
examples
% ListHosts
name HostVersions:
syntax
HostVersions
description
Lists the version ranges for the RemoteHost/RemoteTerminal protocols that this machine is willing to speak (as a Host).
examples
% HostVersions
TerminalCoordination: [1 .. 2]
Viewers: [10 .. 16]
SimpleTerminal: [1 .. 1]
name TerminalVersions:
syntax
TerminalVersions
description
Lists the version ranges for the RemoteHost/RemoteTerminal protocols that this machine is willing to speak (as a Terminal).
examples
% TerminalVersions
TerminalCoordination: [1 .. 2]
Viewers: [10 .. 16]
SimpleTerminal: [1 .. 1]
name VersionsAtHost:
syntax
VersionsAtHost HostName
description
Lists the version ranges for the RemoteHost/RemoteTerminal protocols that the given host machine is willing to speak.
examples
% VersionsAtHost xns[Wasp]
"TerminalCoordination" 1 2; "Viewers" 10 16; "SimpleTerminal" 1 1;
name GetHostsTerminal:
syntax
GetHostsTerminal HostName
description
Reports what the given host thinks its terminal is.
examples
% GetHostsTerminal xns[Wasp]
stable"local"
name AdviceFrom:
syntax
AdviceFrom HostName
description
Done on the advisee machine, in preparation for advice.
examples
% AdviceFrom xns[Wasp]
name RejectAdvice:
syntax
RejectAdvice
description
Done on the advisee machine, to end an advice session.
examples
% RejectAdvice
name Advise:
syntax
Advise HostName
description
Done on the advisor machine, to initiate an advice session.
examples
% Advise pup[Bennington]
name StopAdvise:
syntax
StopAdvise HostName
description
Done on the advisor machine, to end an advice session.
examples
% StopAdvise pup[Bennington]
name BeCodingHost:
syntax
BeCodingHost
description
Done on the host machine, to indicate willingness to use compression in the Viewers protocol.
examples
% BeCodingHost
name BePlainHost:
syntax
BePlainHost
description
Done on the host machine, to indicate unwillingness to use compression in the Viewers protocol.
examples
% BePlainHost
3. Monitoring
There are five sets of monitoring tools available for extracting information from the RemoteTerminal.
The first three use data collected by a special feature. When the host machine receives notice that a key has been depressed, it sends a special acknowledgement, which includes the time, back to the terminal machine. In this way, we get a time-stamped round-trip report.
Terminal Stats
Issuing the command `TerminalStats' (on the Terminal machine) displays three histograms of transit times for key-press events. One shows the distribution of `up-link' (terminal to host) transit times; another shows `down-link' transit times, and a third shows round-trip times. You can do all the usual Histogram things with them; try exploring the menu pop-up buttons and mouse clicks on the data area, if you refuse to read the Histograms document.
Transit History
Interpreting `← RemoteTerminal.ViewHistory[]' (on the Terminal machine) makes a typescript viewer with a `History' menu button. Hitting that menu button causes the details of the recent key-press event trips to be printed. Three times are printed: the time the key was depressed, the time that event was received on the Host, and the time the reply was received on the Terminal. Then the mouse position and the event itself are printed. If you aren't running sufficiently recent software on both sides, the mouse position and event itself will look boring. The trips are remembered in a fixed-size circular buffer. Left- and Middle- clicking the History button displays the trips since the last one displayed; Right-clicking displays all available trips.
Terminal Header Line
This is not optional. An area is reserved at the top of the terminal screen for display of certain information; the host machine thinks the terminal screen is correspondingly shorter than it actually is. The information displayed consists mainly of abstracts of the information presented by the transit time histograms and by the NetWatch tool; since this information is displayed on the terminal screen, it is not necessary to swap virtual terminals (which is painfully slow on certain kinds of machines) to see it. The information is updated every 15 seconds. Currently, the header line looks something like this:
15:51:36 Term=243#240#; rt min=0.35s max=10.85s avg=1.13s run avg=1.37s; link 2: rcv 37/3912 pkts, 00/123 bad, 00.0% run avg; rtr: 3/123, dup: 1/45, res: 0/0, rcv: 15/834, snd: 10/789
The first figure is the time at which the last sampling period ended. Next is an address of the terminal machine. Next comes a summary of the round trip times: the minimum, maximum, and average over the last sampling period (15 seconds), and a running average (0.95*old avg + 0.05*new avg). Then there is a summary of received packets on the "last network": its number (among nets connected directly to the terminal machine), the incremental/total number of packets received, the incremental/total number of them that had "bad" receive status, and a running average (same decay rate) of percentage of bad packets. Finally, there are some statistics from the stream (if it's PUP) for the Viewers protocol: the incremental/total number of retransmitted, received duplicates, resource limited, received, and sent packets.
ImagerSender Stats
The command `Install ImagerByteSenderMonitor' (on the Host machine) will create some displays concerned with the encoding of Imager operations. As this is unlikely to be interesting to random users, I won't bother describing it.
Host Spy
The command `HostSpy' (on the Host machine) will create some a display concerned with the detailed operation of the stream, similar to the information at the tail of the terminal header.
4. How It Works
There are a few interfaces introduced to deal with new concepts.
The terminal location
The interface for this is TerminalLocation. The location of the terminal of a Cedar workstation is now variable. It may be the local hardware (previously this was the only choice). It may be across a network (the interface claims to offer PUP, XNS, and ARPA network connections; in fact, only PUP is implemented). Or it may be undefined.
Providing terminal services
The interface for this is TerminalMultiServing. It deals with the question, ``what machines, if any, am I providing terminal services for across the network?''. An older interface, TerminalServing, is also supported for backward compatibility.
General issues for Hosts and Terminals
The HostAndTerminalOps interface, from the HostCoordination package, provides procedures for setting and querying the protocol version ranges supported. Ignore the GetChannel procedure.
Selecting the screen to show
There is this more basic interface, Terminal, that exports the abstraction of multiplexing multiple "virtual terminals" onto the one physical terminal (i.e., what's managed by the previous two interfaces). However, up till now there hasn't been a good way to get all clients of this interface to coordinate properly to get the right virtual terminal `selected' for display on the one physical terminal at the right time. Now there is. The idea is to associate a priority variable with each terminal; the one with the highest priority is displayed. I've made SimpleTerminal, Idle, and RemoteTerminal subscribe to this theory.
5. Organization
There are six package roles: {coordination, simple terminal I/O, and viewers I/O} on each of {Host, Terminal}. Here are the packages that fill them (they all live on Cedar, except those concerning Terminal or Viewers I/O --- they live on CedarChest):
   | Host  | Terminal
Coordination  | HostCoordination | TerminalCoordination
Simple Terminal I/O | RemoteSimpleHost | RemoteSimpleTerminal
Viewers I/O  | RemoteViewersHost | RemoteTerminal and
    RemoteViewersTerminalByVirtual
There is one DF for each Host role. The two most primitive (HostCoordination and RemoteSimpleHost) Host packages are built into the bootfile. The other, RemoteViewersHost, is loaded either by booting with the J switch (which means to use the `Remote.Loadees' instead of the `Basic.Loadees') or by issuing the command `Install RemoteViewersHost' (in a directory into which RemoteViewersHost has been BroughtOver).
On the terminal side, things are more complex, because I plan to have alternate implementations of how to be a terminal. RemoteTerminal is at the top of the Terminal side's pyramid; it currently has wired into it the fact that RemoteViewersTerminalByVirtual provides the (currently) only way to implement a Viewers terminal.
6. Details
6.1. Sockets
pup/xns/arpa  | Host  | Terminal
Coordination  | 90/90/58812  | 91/91/58813
Simple Terminal I/O |   | 87/87/58810
Viewers I/O  |   | 88/88/58811
6.2. Protocol Versions
The Inscript/Viewers conversion is carried out via a protocol that is still somewhat under development. Consequently, we are concerned with versions of that protocol. Each conversation begins with both conversants sending a range (i.e., min and max) of versions they are willing to converse in. If there is any overlap, the conversation takes place in the highest version they both can handle. If there is no overlap, both conversants stop conversing.
There is a need to document protocols (oh boy!). Here are the rules of my notation. An expression of the form "a; b" indicates that b happens after a; "a | b" indicates a and b happen in any order, even interleaved; "^ a" indicates that a is sent from the terminal to the host; "Ë a" indicates that a is sent from the host to the terminal; "l, m, ... n: T" describes data named l, m, ... n, each of type T; parentheses are used for grouping; "IF a THEN b ELSE c FI" means the obvious thing.
passchar: CHAR ~ CHAR.LAST;
VersionRange: TYPE ~ RECORD [max, min: BYTE];
Ctl7: TYPE ~ RECORD [willingToCode: {'C, 'P}, reject: {'R, 'A}];
TimeCtl: TYPE ~ {'T, 'N};
6:
(^ passchar tv: VersionRange) | (Ë passchar hv: VersionRange);
MIN[tv.max, hv.max]=6 AND MAX[tv.min, hv.min]<=6
(^ tReject: {'R, 'A}) | (Ë hctl: Ctl7);
If either reject is 'R, stop conversation.
The data conversation is now carried out. Iff hctl.willingToCode='C, the data going from the host to the terminal are compressed with the FG1C method.
7:
Differs from 6 in allowing the terminal to indicate willingness to use compression.
(^ passchar tv: VersionRange) | (Ë passchar hv: VersionRange);
MIN[tv.max, hv.max]=6 AND MAX[tv.min, hv.min]<=6
(^ tctl: Ctl7) | (Ë hctl: Ctl7);
If either reject is 'R, stop conversation.
The data conversation is now carried out. Iff both willingToCodes are 'C, the data going from the host to the terminal are compressed with the FG1C method.
8:
Differs from 7 in adding SetMouseGrain, SetFastMouseParms, and SetEscapes to the data conversation.
9:
Differs from 8 in the data conversation.
10:
Differs from 9 in the data conversation.
11:
Differs from 10 in the data conversation, by adding the timing probes & replies.
12:
Differs from 11 in that initial negotiation allows host to declare that it will be sending fine-grain timing in the imager operations.
(^ passchar tv: VersionRange) | (Ë passchar hv: VersionRange);
MIN[tv.max, hv.max]=12 AND MAX[tv.min, hv.min]<=12
(^ tctl: Ctl7) | (Ë hctl: Ctl7; TimeCtl);
If either reject is 'R, stop conversation.
The data conversation is now carried out. Iff both willingToCodes are 'C, the data going from the host to the terminal are compressed with the FG1C method. Iff the TimeCtl is 'T, fine-grain timing is included in the data conversation; otherwise the TimeCtl is 'N
13:
Differs from 12 in that timing probes and replies additionally carry mouse position and ActionBody.
16:
Differs from 15 in adding MousePosition as a kind of InterminalSetting.