\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; @ /*-------------------------- The sleeperette -----------------------------*/ @ #endif @}