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 |