Joe English
Last updated: Monday 20 November 2000, 13:01
The scope server protocol (SSP) allows the Scope parser to be accessed by a high-level front end.
The -s flag directs the Scope parser to start in server mode. Extra startup files may be specified in addition to $FL_DIR/startup.exc, which is always read. (This may be overridden by setting the $FL_STARTUP environment variable, as usual.) In server mode, the -f flag is not honored, and the users preference file .flightlab_prefs is not executed.
scope -s [ filename... ]
When the parser is invoked in server mode, the usual read-execute-print loop is bypassed and it instead reads requests from standard input and produces responses on standard output. All diagnostic output is redirected to standard error; the invoking client may choose to capture the parser's standard error output and display it to the user.
Internally, the parser duplicates the initial standard input and standard output to new file descriptors, redirects stdout to stderr, and closes stdin. This is to prevent any possible output from the Scope internal routines from interfering with the protocol stream. In theory, all I/O in the parser internals is done through the functions outputf(), et cetera, but in practice this may not be the case.
To prevent deadlock, at most one request may be pending at any time; that is, the client process must wait for the complete response to be read before issuing another request. Also, the server code must make sure to read the entire request packet before beginning the response.
SSP is a conventional request-response protocol, with some additional out-of-band signals for sending asynchronous output while processing a request, and a special command mode for passing Scope language commands directly to the parser.
Requests from the client to the server and responses from the server to the client are sent as ASCII text. The first line is a single keyword (all caps) indicating the type of request or response. Server responses also contain an informational message on the same line as the response keyword; this is useful for debugging messages. The header line is followed by a series of data lines, the message body. The format of the data lines is determined by the type of message. Each message is terminated by a line containing a single period (.), even if there is no data in the message body.
With the exception of the QUIT request, the server replies with exactly one response.
After the connection has been established, the server sends a HELLO response. The body of the response is a single line containing the SSP protocol level (currently 0.3). After the initial HELLO signal, all other responses are sent only in reply to a request from the client.
quit-request ::= "QUIT", EOL
The QUIT request terminates the server.
After processing this request, the server process closes the connection and exists. The client may close the connection immediately after sending a QUIT request; there is no response from the server.
exec-request ::= "EXEC", EOL, filename, EOL
OK or SCOPE ERROR.
Executes the script file filename. The scope search path is searched for filename.
who-request ::= "WHO", EOL, path-name, EOL
LIST
list-response ::= "LIST", EOL, (variable-description | subgroup-description)*
variable-description ::=
"V", TAB, name, TAB, dimensions, TAB, description, EOL
subgroup-description ::=
"G", TAB, name, TAB, description, EOL
| "C", TAB, name, TAB, class-name, TAB, description, EOL
dimensions ::= number ("," number)*
name ::= [A-Z][A-Z0-9]*
class-name ::= [A-Z][A-Z0-9]* -- component class name --
path-name ::= name ( "_", name)* -- WORLD-relative path name --
get-request ::= "GET", EOL, group-name, EOL, (variable-name, EOL)* group-name ::= path-name variable-name ::= name
DATA
get-response ::= "DATA", EOL, ((variable-name, EOL), data)* data ::= dimensions, EOL, (number, EOL)*, "--", EOL
set-request ::= "SET", EOL, path-name, EOL, ((variable-name, EOL), data)*
OK.
mkgroup-request ::= "MKGROUP", EOL, path-name, EOL, name, EOL.
OK.
vlset-request ::= "VARLIST", EOL, varlist-name, EOL, ( vlentry, EOL )*. varlist-name ::= "@", name. vlentry ::= path-name, (TAB, refrange, (TAB, description)?)?, EOL. refrange ::= integer, ":", integer | "*". -- start:end or "*" == whole range --
OK.
vllist-request ::= "VLINQ", EOL, varlist-name, EOL.
vllist-response ::= "VARLIST", EOL, varlist-name, EOL, (vlentry, EOL)*
A vlentry in a vllist-response will always include the refrange and description, (the description may be empty though), and the refrange field will always be an explicit range, not *.
The server protocol supports a ``pass-through'' mode whereby Scope commands may be passed directly to the parser. This is done by prefixing each command line with the character SSP_CC_COMMAND (\01, ASCII control-A). Note that in general a Scope command may be longer than one line; each input line should be prefixed with this control character.
The Scope back-end acknowledges each command line by sending a SSP_CC_CMDACK (\01, ASCII control-A) character followed by a newline back to the client as soon as the SSP_CC_COMMAND signal has been recognized.
After parsing a complete command, the server sends back a single line containing the control character SSP_CC_CMDREAD (\06, ASCII control-F) then evaluates the command. All Scope output will be sent to the client. After the command has finished executing, the servers sends the control character SSP_CC_CMDDONE (\04, ASCII control-D), at which point the server is ready to accept another protocol request or Scope command.
To avoid a race condition, the client should keep a running count of the number of unacknowledged command lines sent to the server. If the count is greater than zero when the client receives a SSP_CC_CMDACK signal, then there are unparsed command lines still pending. (In general, a Scope command may be several lines long; the SSP_CC_CMDACK and SSP_CC_CMDREAD signals allow the client to determine when a multi-line command has been completed.)
NOTE --There is no error or success indication returned back to the client.

The Scope back-end may produce asynchronous output to be displayed to the user. Asynchrounous output will only be sent in the following states:
There are two kinds of asynchronous output: messages and block output. Messages contain a single line of text; block output can be any length.
Block output mode is initiated with the SSP_CC_OUTPUT signal (\017, ASCII control-O) and terminated with the SSP_CC_FINISH signal (\016, ASCII control-N). All data received between these two signals should be presented directly to the user.
Asynchronous messages begin with a SSP_CC_MSG signal (\05, ASCII control-E) followed by a one-character key letter designating the type of message. The message data is everything after the key letter and before the end of line.
At present only the following message types are used:
NOTE --Asynchronous messages may appear in the middle of block output.
In progress...
To use the SSP module in a Tcl application, use:
package require SSP
Or:
source $FL_DIR/tcl/ssp.tcl
The ssp:open command initiates a Scope session. By default, it runs scope as a subprocess on the current host. The following options are available:
The following options to ssp:open connect to a Scope server process over the network instead of running the server locally.
When running over a network, the -quiet, -scope, and -startup flags are ignored.
At present (Flightlab version 2.6.5) the Scope executable does not include facilities for listening on a network port. In the interim, you can use:
# on remote host: tcp -s 7267 -e scope -s
To be written...
ssp:get group { variable ... }
ssp:get queries the value of the listed variable names in the specified Scope group. It returns a paired list of variable name-value pairs. The value is returned as a list of lists of floating point numbers (since values in Scope are 2-D matrices).
If any variable is complex, the imaginary part is discarded. (%%% bug).
ssp:set group { variable value... }
Sets each variable to value in group. The values are lists of lists of floating point numbers (as with ssp:get).
ssp:SET group { name value ... }
ssp:GET group { name ... }
ssp:WHO group
ssp:DESCRIBE ident (??? check)
ssp:EXEC filename
ssp:VARLIST @vlname [ varname... ] (??? check)
ssp:QUIT
ssp:cmdOK ssp:evalOK
ssp:cmdOK returns 1 if the Scope backend is ready to accept a protocol command, 0 otherwise. ssp:evalOK returns 1 if it is ready to accept command-mode input.
The SSP module stores status data in the global array SSP. Applications can add variable traces to the elements of this array or configure it as the -textvariable of a Tk widget to monitor the current SSP status.
At present, only the following elements are defined:
Example of use:
global SSP label .messageline -textvariable SSP(messageLine)
The scopecon package is a set of Tk utilities which configure a Tk text widget as an interactive ``console'' for accessing the scope server process in command mode.
The ssp package must be loaded before scopecon.
source $FL_DIR/tcl/scopecon.tcl
/***********************************************************************
* Copyright (C) 1996 Advanced Rotorcraft Technology Inc. *
* All rights reserved *
***********************************************************************
*
* File: ssp.h
* Author: Joe English
* Created: 1 March 1996
* Description: Scope Server Protocol
*
* $Date: 97/01/27 18:58:27 $
* $Revision: 1.7 $
* $Locker: $
*/
#ifndef SSP_H
#define SSP_H 1
#define SSP_PROTOCOL_VERSION "0.3"
/*
* Request codes:
*/
typedef enum
{
SSP_REQ_WHO, /* list contents of group */
SSP_REQ_GET, /* get variable(s) */
SSP_REQ_SET, /* set variable(s) */
SSP_REQ_MKGROUP, /* create group */
SSP_REQ_EXEC, /* execute server-side script file */
SSP_REQ_VARLIST, /* specify variable list */
SSP_REQ_VLINQ, /* inquire variable list */
SSP_REQ_QUIT, /* shut down */
SSP_REQ_COMMAND, /* enter scope read-eval-print loop (pseudo-request) */
_SSP_REQ_BADREQUEST,/* error condition; malformed request */
_SSP_REQ_SYNC, /* "." on a line by itself; resync */
_SSP_REQ_EOF /* error condition; closed connection */
} SSP_REQUEST;
/*
* Response codes:
*/
typedef enum
{
SSP_RSP_HELLO = 100, /* sign-on mesage; ready to go */
SSP_RSP_OK, /* request processed; no data */
SSP_RSP_VARS, /* list of variables follows */
SSP_RSP_DATA, /* list of variables with data follows */
SSP_RSP_VARLIST, /* variable list contents */
/* Error codes: */
SSP_RSP_BADREQ, /* bad request */
SSP_RSP_ERROR, /* Scope error */
SSP_RSP_FAILURE, /* general failure -- terminating */
SSP_RSP_NYI, /* feature not yet implemented */
_SSP_RESP_LAST
} SSP_RESPONSE;
/*
* Control codes for pass-through mode to command line:
*/
#define SSP_CC_COMMAND '\01' /* client->server: command line input */
#define SSP_CC_CANCEL '\030' /* client->server: cancel current cmd */
#define SSP_CC_CMDACK '\01' /* server->client: acknowledge cmdline */
#define SSP_CC_CMDREAD '\06' /* server->client: cmd complete */
#define SSP_CC_CMDDONE '\04' /* server->client: cmd finished executing */
#define SSP_CC_MSG '\05' /* server->client: message line */
#define SSP_CC_OUTPUT '\017' /* server->client: begin output */
#define SSP_CC_FINISH '\016' /* server->client: output done */
#endif /* SSP_H */
In server mode, interactive commands like KEYBOARD, INPUT, PLOT, and HELP do not work.
Should distinguish error output from normal output.
Server should be able to send asynchronous messages (status updates, error messages, etc.) to be displayed to the user. (partially done -- async mode).
Client should supply some services (HELP, INPUT, PLOT) to the server.