\subsection{Command Forwarding Through the Serial Line}
This is a set of utility routines which transport commands and
responses to and from a serial port connected to a Macintosh terminal
server.  This is derived from the
routines provided by David Maden for the EL734 motor controller. This
utility is used by many of the SICS drivers. These
functions are implemented in sinqserial.*. The following functions are
defined:

@d ss @{
   int SerialOpen(void **pData, char *pHost, int iPort, int iChannel);
   int SerialForceOpen(void **pData, char *pHost, int iPort, int iChannel);
   int SerialConfig(void **pData, int iTmo);
   int SerialGetTmo(void **pData);
   int SerialATerm(void **pData, char *pTerm);
   int SerialAGetTerm(void **pData, char *pTerm, int iTermLen);
   int SerialSendTerm(void **pData, char *pTerm);
   int SerialGetSocket(void **pData);
   int SerialClose(void **pData);
   int SerialSend(void **pData, char *pCommand);
   int SerialReceive(void **pData, char *pBuffer, int iBufLen);
   int SerialError(int iError, char *pError, int iErrLen);
   int SerialWriteRead(void **pData, char *pCommand, 
                       char *pBuffer, int iBufLen); 
@}

Each of these functions returns 1 on success or a negative value on the
likely event of an error. These negative values double as error codes.
These error codes can be translated into text with SerialError.


{\bf SerialOpen} opens a connection to a RS--232 at the computer pHost. The
 terminal server is leistening at port iPort and the serial line is
iChannel. pData is a void pointer. It will be initialized with a data
structure holding internal connection information. This pointer must be
passed along with each of the other functions.

{\bf SerialNewOpen} is a second form of SerialOpen. The difference is in
connection management. SerialOpen uses an existing network connection to the
Macintosh, if existing. Thus data transfer is shared between many devices.
This is fine as long as the devices reply to messages quick enough. But a
slow device may block all communication.
 SerialNewOpen forces a new socket to be opened. Thereby a new thread is
started in the   Macintosh serial port server and devices get decoupled.
This scheme is recommended for devices which reply slowly to RS--232
requests.


{\bf SerialConfig} configure the timeout to iTmo. This is the timeout the
terminal server waits for commands to appear. pData is
the pointer as initialized by SerialOpen.

{\bf GetSerialTmo} returns the currently valid timeout value.

{\bf SerialATerm} sets the expected string terminator to pTerm.
{\bf SerialAGetTerm} copies maximum iTermLen characters of teminator
information to pTerm.
{\bf SerialSendTerm} sets the default terminator to send after each command.
{\bf SerialClose} closes the connection to the RS--232 connection. pData is
the pointer as initialized by SerialOpen.

{\bf SerialSend} sends pCommand onto the serial connection.  pData is
the pointer as initialized by SerialOpen. Please note, that this command
clears the receive buffer at the terminal server. This means any answers
pending from prior commands are deleted. This function can send only one
single command. The Dornier velocity selector cannot handle more, anyway.


{\bf SerialReceive} reads from the RS--232 connection into the buffer
pBuffer, but maximum iBufLen characters. This version check with select for
pending data and returns NODATA if nothing is available. pData is
the pointer as initialized by SerialOpen.

{\bf SerialError} translates any of the negative error codes into a readable
form. The error code is iError. Maximum iErrLen characters of text will
be copied to pError. pData is
the pointer as initialized by SerialOpen.
  
{\bf SerialWriteRead} writes the command pCommand to the port and tries 
to read a reply during the timeout period. Maximum iBufLen characters of
answer will be copied to pBuffer. This function return a positive value 
on success or a negative error code. In case of an error pBuffer will
be filled with an error message instead.


SerialWriteRead loops on SerialReceive until data becomes available. But
only for the maximum period specified as time out. In this loop
SerialWriteRead calls a function which waits some time. By default this
function maps to the system function sleep. However, an application might
choose to specify another function instead. For instance a yield in a 
window system or a SicsWait in a SICS system. This feature may allow an
application to do further processing while waiting for data to appear
at a serial line. In order to do this the
following typedef and function are necessary.

@d sf @{
   typedef int (*SerialSleep)(void *pData, int iTime);
   void SetSerialSleep(void **pData, SerialSleep pFunc, void *pUserData);
@}

The sleep function must take two parameters: A void pointer described below
and an integer time value to waist.

{\bf SetSerialSleep} takes a pointer as returned by SetialOpen as first
 parameter. The second parameter is the sleep function. The third parameter
is a pointer to an application defined data structure which will be passed
on as first parameter to the sleep function by the system. 
 



@o serialsinq.h -d @{
/*----------------------------------------------------------------------------
                      S E R I A L S I N Q

  Utility functions for maintaining a connection to a RS--232 port on a
  Macintosh computer running the SINQ terminal server application.

  Mark Koennecke, Juli 1997

  copyright: see implementation file
------------------------------------------------------------------------------*/
#ifndef SERIALSINQ
#define SERIALSINQ
#define NOREPLY -100
#define NOCONNECTION -121
#define SELECTFAIL -120
#define TIMEOUT    -130
#define INTERRUPTED -132;

@<ss@>
/*-------------------------- The sleeperette -----------------------------*/
@<sf@>
#endif
@}
