**Serial Port Interface to TCP/IP (SPiT)**

**Programmer\'s Reference**

T. Nolan

April 22, 2002

# Overview

This document describes the operation of the Serial Port Interface to
TCP/IP (SPiT) software. SPiT is a program that resides in the PC that is
connected directly to the P24 MISC instrument controller board via two
serial cables. The HET flight software, running on the P24 MISC,
communicates with SPiT through the two serial port connnections. SPiT
presents a TCP/IP interface to external programs that need to gain
access to the flight software serial data. The following diagram
illustrates this concept.

**GSE Operation through Serial Port Interface to TCP/IP**

# SPiT Configurations

As the figure shows, ground support equipment (GSE) can communicate with
the HET instrument in three different configurations (labeled "GSE-1,"
"GSE-2," and "GSE-3").

***Single PC.*** GSE-1 is running in the same PC that SPiT runs in.
Thus, the simplest setup involves only one PC for instrument support
software. The single PC runs SPiT, Tbug (the visual debugger), and one
or more GSE programs that can send commands and receive telemetry. In
this setup, Tbug and GSE-1 use TCP/IP socket functions to communicate
with SPiT, but the communications never leave the PC. In this mode, the
socket connections provide interprocess communications.

***Locally networked PC.*** GSE-2 is running on a PC that is connected
to the SPiT PC via a local-area network. The GSE opens a client-side
connection to SPiT using socket functions, knowing the IP address of the
server PC and SPiT's well-known port number. Although it is not shown in
the diagram, Tbug can run in this configuration as well. Thus, one PC
can be dedicated to instrument control (running SPiT with serial port
connections to the instrument) and another computer in the lab can
contain the development tools and instrument control software.

***Remote PC.*** In the third configuration, GSE-3, the GSE software and
SPiT software run on separate Internet host computers. The GSE opens a
client-side connection to SPiT using the SPiT host computer's assigned
Internet name or IP address and SPiT's well-known port number. This
configuration could be useful if the HET instrument were operating at a
remote location (e.g., for calibration or integration), since real-time
data could thereby be acquired at GSFC.

Up to five TCP/IP sessions can be established at once, and each session
can request any combination of command or telemetry access. GSE software
in all three configurations (single PC, local, and remote) could be
operated simultaneously. This has operational benefits, since it can be
useful to have more than one telemetry stream and command console. For
example, a dedicated logger application could be running constantly to
perform the simple task of capturing all telemetry and storing it to
disk. Moreover, Tbug, if it is running, needs command access, and a
separate instrument command console may run simultaneously. SPiT does
not currently perform any validation or identification. While it would
be difficult for someone to inadvertently command the instrument, a
determined person could do so. A security layer can be added at a future
time.

# Theory of Operation 

The basic theory of operation of SPiT is simple. SPiT opens a
server-side socket and listens for remote connections. A GSE program
opens a client-side connection to SPiT through its host computer IP
address or name and its well-known port. After the socket pair is
connected, the GSE sends a packet notifying SPiT that it wishes to
establish one or more of the following communications sessions: (1) send
commands to instrument through command port; (2) receive command
response information from instrument through command port; (3) receive
telemetry from instrument through telemetry port.

All information, including the initial session type packet, is
transmitted between the GSE and SPiT in packets. The packet format is as
follows:

Serial Port Interface to TCP/IP (SPiT) Packet Format

  ------------ ---------- -------------------------- ---------------------
  Length       Opcode     Parameter                  Data

  4 bytes      4 bytes    4 bytes                    Variable=length-8
  ------------ ---------- -------------------------- ---------------------

The length word gives the number of bytes to follow (not including the
length word itself). The opcode determines the nature of the packet.
Four opcodes are currently defined: Session, Command, Response, or
Telemetry. The parameter is a subcode that further defines the opcode.
The data field is variable-length, and dependent upon the opcode. For
session packets, there is no data (length = 8), and the parameter
specifies the session type (one or more of the bits representing
command, response, and telemetery). For command packets, the data is the
serial string that is to be sent as-is to the flight instrument. A
newline ordinarily terminates this string. For response packets, the
data field contains the ASCII characters sent by the flight instrument
as-is. A carriage return-newline pair ordinarily terminates this string.
For telemetry packets, the data field contains a 272-byte CCSDS
telemetry packet sent by the flight instrument (length=280).

When the GSE establishes a telemetry session, it will begin receiving
telemetry packets from the instrument as soon as it sends the session
packet (assuming the instrument is generating telemetry). No
acknowledgements are needed or expected. If the GSE computer stops
receiving for some reason (i.e., it is taking too long to process a
packet) the SPiT will drop packets until the socket unblocks.

Response sessions operate in a similar manner to telemetry sessions.
When the GSE establishes a response session, it will begin receiving
response packets as soon as it sends the session packet. It may be
convenient to separate the response from the command session in this way
to simplify the software design. For example, there could be a simple
console application that issues a "printf" every time it receives a
response packet.

Command sessions receive no data from the instrument. Instead, after the
GSE sends a session packet to initiate a command session, SPiT waits for
command packets from the GSE. The data field from ach such packet is
extracted and written to the serial port just as if it were keystrokes
received through a terminal.

Functions are provided to format, send, and receive packets.
Notification of packet arrival can be accomplished through Winsock
system calls (e.g., WSAAsyncSelect()).

# Packet Formats

Opcodes and Parameters

  ------------ ----------------- ----------------------------------------
  Opcode       Parameters        Description

  OP_SES (1)   SES_SNDCMD (0x10) Establish new session; send commands to
                                 instrument

               SES_RCVCMD (0x20) Establish new session; receive command
                                 responses from instrument

               SES_RCVTLM (0x40) Establish new session; receive telemetry
                                 data

  OP_CMD       0                 Command for delivery to instrument

  OP_RSP       0                 Command response from instrument

  OP_TLM       0                 Telemetry data packet from instrument
  ------------ ----------------- ----------------------------------------

***Commanding session.*** To send commands to the instrument through
SPiT, a program sends a packet with OP_SES and SES_SNDCMD in the opcode
and parameter fields. The data field is empty. The length is 8 bytes,
not including the 4-byte length field itself. This packet should be the
first thing sent after the socket connection is established. There is no
acknowledgement. After sending this packet, the program can send command
packets. A command packet has OP_CMD in the opcode field, zero in the
parameter field, and a non-empty data field. SPiT transmits the contents
of the data field to the instrument over the command serial port as-is.
If a carriage return is part of the command string, it must be included
in the data field.

More than one PC can establish a commanding session. SPiT simply
serializes access to the instrument among multiple command sources. The
command PCs must coordinate command activity among themselves. For
example, Tbug, the interactive debugger for the MISC chip, can be
configured to operate remotely through SPiT. It establishes a session
for commanding and responses, and communicates in this manner with Tmon
running on the MISC. While the target program under test is running,
that program may respond to higher-level commands, which can be sent
from a GSE program. The GSE program also needs to have command access at
the same time as Tbug.

***Response session.*** The instrument ordinarily responds to each
command it receives. It sends these responses over the command serial
port. In order to receive these responses, a GSE program must send an
OP_SES packet with the SES_RCVCMD bit set in the parameter field. This
parameter may be combined with SES_SNDCMD to be able to send commands
and receive responses. However, note that only one OP_SES packet can be
sent per session, and it must be the first packet sent after completing
the socket connection. All desired accesses must be placed in the
parameter field of this one OP_SES packet.

A GSE that has requested command responses will begin receiving OP_RSP
packets. In an OP_RSP packet the parameter is zero and the data field
will contain the command response as it was received from the instrument
over the serial port. SPiT uses a timeout setting on the serial port
such that, in general, each packet will contain a complete line of text
transmitted by the instrument. However, this behavior is not guaranteed,
and a GSE may have to assemble one or more OP_RSP packets if the
response is lengthy or irregularly timed.

***Telemetry session.*** A GSE can request access to telemetry data by
setting the SES_RCVTLM bit in the OP_SES packet. Once this packet is
received, SPiT begins delivering telemetry to the GSE. A telemetry
packet has OP_TLM in the opcode field and zero in the parameter field.
The data field is ordinarily 272 bytes long (so the length field is
280). Multiple GSE programs can request simultaneous access to telemetry
data. SPiT sends each telemetry packet to every connected program with
an active telemetry session.

# Software Interface

The WinTCP software package contains functions to establish a
client-side connection and to send and receive packets in the format
used by SPiT. It also contains all the server-side functionality that
SPiT itself uses -- SPiT is linked with Win TCP. The package is
self-documented. The following table lists the functions and their
operation.

WinTCP Functions

  ----------------------------------- -----------------------------------
  Function                            Description

  Int net_startup(void)               Wrapper for WSAStartup. Call this
                                      function before making any other
                                      calls to Winsock. You must call
                                      net_cleanup() before terminating.

  Void net_cleanup(void)              Wrapper for WSACleanup().

  Void net_debug(int debug)           Enable verbose output (debug==1) or
                                      terse output (debug==0).

  SOCKET net_open(char \*host, char   Open client-side connection to SPiT
  \*service, int port)                server. Specify host name and port
                                      number. Set service to NULL.

  Void net_close(int s)               Close a connection that has been
                                      opened with net_open(). Pass the
                                      socket that net_open() returned.
                                      (Should be declared as type
                                      SOCKET).

  Int sendPKG(int sockfd, int opcode, Format and send SPiT packet. Sockfd
  int param, void \*data, int ldata)  is the socket returned by
                                      net_open(). Opcode, param, and data
                                      are the corresponding fields in the
                                      packet. Ldata is the length of the
                                      data array in bytes. Total packet
                                      length must not exceed MAXBUF, a
                                      defined constant in WinTCP.h.
                                      Returns a negative value on error.
                                      Returns the number of bytes
                                      actually written to the socket on
                                      success, which can be less than the
                                      entire packet if the socket is
                                      nonblocking.

  int recvPKG(int sockfd, int \*len,  Receive a SPiT packet. Len gets
  int \*opcode, int \*prm, void       filled in with the length of the
  \*data)                             data field, opcode, prm and data
                                      get filled in with the
                                      corresponding fields in the packet.
                                      This should only be called on a
                                      blocking socket. It returns a
                                      negative value on error or timeout.
                                      The timeout value is set by defined
                                      constants in WinTCP.h. On success,
                                      returns the value of the opcode.

  int recvPKGn(int sockfd, int \*len, Non-blocking version of recvPKG.
  int \*opcode, int \*prm, void       Call when sockfd is a non-blocking
  \*data)                             socket. Can return a negative value
                                      if the read would block. However,
                                      it will never return a partial
                                      packet. On success, returns the
                                      value of the opcode.
  ----------------------------------- -----------------------------------

Most of these functions are capable of generating diagnostic output when
verbose output is enabled (net_debug(1)) and most are capable of
generating error messages even when terse output is enabled
(net_debug(0)). The output is done through console output functions
ConsoleOut, DebugOut, ErrorOut, and WinsockErr. Each of these functions
follows the same argument convention as printf(). The first argument is
a character string that contains characters plus optional formatting
codes, and optional arguments to be formatted follow. These functions
all equate to printf() in a console application. In a windows
application, you will have to provide substitute functions. You could,
for example, create wrappers for sprintf and MessageBox. SPiT uses
functions in ConsoleWin.cpp that create a scrolling text box that has
the appearance of a console window.

A sample client application, dclient, is provided to demonstrate the
simplest way to interact with SPiT. It is a console application that
establishes a telemetry session and prints a line to the console every
time a telemetry packet is received.

A more sophisticated example can be found in the Tbug source code. When
networked operation is specified, Tbug opens a command and response
session, sets its socket to non-blocking, and requests asynchronous
notification of socket events through WSAAsyncSelect(). In this manner,
Tbug gets a message every time a packet is sent by SPiT and is available
for reading by Tbug.