tclSurrogate Protocol

The so called tclSurrogate protocol is so named because it was first used to connect a Tcl applet to the SIMPL framework.    Since that time the embodied protocol has been used in many other instances than tcl applets. It is commonly used to connect non-Linux OS hosted Tcl/Tk, Python, JAVA or VB apps into a Linux hosted SIMPL app. It has also been used to connect a deeply embedded network appliance (IO Anywhere) into a SIMPL app.

The concept of the tclSurrogate is really very straightward. It is essentially the client-server model. The client in this case embodies the business logic for the SIMPL module whereas the server is a generic SIMPL interfacing piece which exposes this module to the rest of the SIMPL application. Together the client and server piece form a single SIMPL module which appears to exist on the server's network node.

The tclSurrogate daemon (parent) is started up and listens for connections on a defined TCP/IP port.   (default to port 8000).      When a connection is made and accepted the tclSurrogate forks a child process whose purpose in life is to act as the SIMPL interface to the rest of the SIMPL application and to manage the TCP/IP socket communications with the process making the connection. The process making this connection and this child communicate with each other over the TCP/IP socket using the structures described in this document.
 
 

General Message format

The basic protocol message format is as follows:
 
token(2) nbytes(2) ID(4) data(token dependant)

where the number in brackets represents the size of the field in bytes and the byte ordering is little endian.
 
 

Some terminology

We also need to decide on some naming conventions for the various elements involved in a message pass via the tclSurrogate child process.

There are basically 3 players that are involved:

When illustrating the protocol in detail below we will be using these short hand forms for these players.
 
 

Tokens

The following tokens form the basis of this protocol.    The master source for this information is in the C header located at $SIMPL_HOME/surrogates/tclSurrogate/include/surroMsgs.h
 
 
Token Value
NAME_ATTACH 0
NAME_DETACH 1
NAME_LOCATE 2
SEND 3
REPLY 4
RELAY 5
IS_LOGGER_UP 6
LOGIT 7
SEND_NO_REPLY 8
ACK 9
PING 10

 

NAME_ATTACH

sockapp -> child
 
0 32 n/a(4) SIMPL name(20)-null terminated n/a(4) n/a(4)

child -> sockapp
 
4 32 -1 SIMPL name(20)-null terminated pid(4) slot(4)

When the sockapp issues the NAME_ATTACH message it has the effect of setting the SIMPL name on the child process.
 
 

NAME_DETACH

sockapp -> child
 
1 0

child -> sockapp
 
4 4 -1

The NAME_DETACH causes the child process to exit after a 2 second delay.
 
 

NAME_LOCATE

sockapp -> child
 
2 28 n/a(4) SIMPL name(20)-null terminated n/a(4)

child -> sockapp
 
4 28 -1 SIMPL name(20)-null terminated rc(4)

The NAME_LOCATE will have the effect of performing a local name_locate() for the SIMPL name.     The rc field will contain the result of that call which is the SIMPL channelID to be used in a subsequent SEND message in the toWhom field.
 
 

SEND

sockapp -> child
 
3 4+sbytes toWhom(4) sdata(sbytes)

child -> SIMPL receiver(toWhom)
 
sdata(sbytes)

SIMPL receiver -> child
 
rdata(rbytes)

child -> sockapp
 
4 4+rbytes -1 rdata(rbytes)

The toWhom field is the channelID retrieved from a previous NAME_LOCATE call.
 

REPLY

The use of this token has been detailed in the other paragraphs.
 
 

RELAY

SIMPL sender(fromWhom) -> child
 
sdata(sbytes)

child -> sockapp
 
5 4+sbytes fromWhom(4) sdata(sbytes)

sockapp ->  child
 
4 4+rbytes fromWhom(4) rdata(rbytes)

child ->  SIMPL sender(fromWhom)
 
rdata(rbytes)

 

IS_LOGGER_UP

sockapp -> child
 
6 28 n/a(4) trace logger name(20)-null terminated n/a(4)

child -> sockapp
 
4 28 -1 trace logger name(20)-null terminated loggerID(4)

NOTE:  the trace logger name isn't currently checked in the child code,  so this call will return the global loggerID variable for the tclSurrogate parent's trace logger irrespective of the supplied trace logger name.
 
 

LOGIT

sockapp -> child
 
7 52+msglen loggerID(4) fileName(20) funcName20) mask(4) globalMask(4) msg(msglen)

There is no response to the LOGIT call.

The fileName and funcName fields are null terminated strings used to help map the trace log message back to the source code.
 
 

SEND_NO_REPLY

sockapp -> child
 
8 4+sbytes toWhom(4) sdata(sbytes)

child -> SIMPL receiver(toWhom)
 
sdata(sbytes)

The Reply() from the SIMPL receiver is simply discarded in this instance.
 
 

ACK

sockapp -> child
 
9

The ACK is not responded to.
 
 

PING

sockapp -> child
 
10

child -> sockapp
 
4 4 -1