home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
TELECOM
/
xyz.lzh
/
ftserial.c
< prev
next >
Wrap
Text File
|
1995-08-18
|
9KB
|
329 lines
/*
Printed form of this source is Copyright (C) 1995 Coriolis
Group, Inc. All rights reserved. Individual users may
make printed copies for their own personal use.
All other forms are Copyright (C) 1995 Tim Kientzle. All
rights reserved.
Redistribution in source or binary form is permitted only under
the following conditions:
1. If you own a copy of `The Working Programmer's Guide To Serial
Protocols,' then you may redistribute this code as part of
a complete application program under the conditions
described in that book. (See pages xiv, xv.) In any case,
you must abide by terms 4-7 below.
2. Otherwise, if you have received this code as a part of an
application program, it may only be redistributed with the
complete source of that program, under whatever conditions
apply to redistribution of that program as a whole.
3. If you have received this source code by some other means,
you may not redistribute it without explicit written
permission from Tim Kientzle.
4. All advertising materials mentioning features or use of this
software must prominently display the following acknowledgement:
This product is partially based on source code appearing in
`The Working Programmer's Guide to Serial Protocols,'
Copyright (C) 1995 Coriolis Group, Inc. and Tim Kientzle.
5. All programs using this source code must display the above
acknowledgement prominently in the program documentation
and user interface.
6. Neither the name of the Tim Kientzle nor the Coriolis Group, Inc.,
may be used to endorse or promote products derived from this
software without specific prior written permission.
7. Any redistribution in source form must retain the above copyright
notice, this list of conditions, and the disclaimer below.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL TIM KIENTZLE OR THE CORIOLIS GROUP BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ftserial.h"
#include <stdio.h>
#ifdef _UCC
#include <stdlib.h>
#else
int fprintf ();
#endif
#include <stddef.h>
void *malloc (size_t);
void free (void *);
/* System-specific headers for OS9 */
#include <sgstat.h>
/*#include <setsys.h>*/
#include <time.h>
#include <modes.h>
#define TRUE (1)
int _gs_opt (int path, struct sgbuf *buffer);
int _ss_opt (int path, struct sgbuf *buffer);
int memset (char *s, int val, unsigned size);
int _gs_rdy (int path);
int _ss_rel (int path);
int _ss_ssig (int path, short sigcode);
int intercept (int (*inter) ());
int tsleep (unsigned);
int close (int path);
int open (const char *name, short mode);
int read (int path, char *buff, unsigned count);
int write (int path, const char *buffer, unsigned count);
typedef struct PORT_PARAMS PORT_PARAMS;
struct PORT_PARAMS {
PORT_PARAMS *pNext;
struct sgbuf inParams;
struct sgbuf outParams;
};
typedef struct {
PORT_PARAMS *stack;
int inPath;
int outPath;
} SERIAL_PORT_PRIVATE;
static void
DisableTTYOptions (struct sgbuf *pBuf)
{
pBuf->sg_case = 0;
pBuf->sg_backsp = 0;
pBuf->sg_delete = 0;
pBuf->sg_echo = 0;
pBuf->sg_alf = 0;
pBuf->sg_nulls = 0;
pBuf->sg_pause = 0;
pBuf->sg_page = 0;
pBuf->sg_bspch = 0;
pBuf->sg_dlnch = 0;
pBuf->sg_eorch = 0;
pBuf->sg_eofch = 0;
pBuf->sg_rlnch = 0;
pBuf->sg_dulnch = 0;
pBuf->sg_psch = 0;
pBuf->sg_kbich = 0;
pBuf->sg_kbach = 0;
pBuf->sg_bsech = 0;
pBuf->sg_bellch = 0;
pBuf->sg_tabcr = 0;
pBuf->sg_tabsiz = 0;
}
static void
CleanPort (SERIAL_PORT_PRIVATE *port)
{
struct sgbuf buff;
_gs_opt (port->inPath, &buff);
DisableTTYOptions (&buff);
_ss_opt (port->inPath, &buff);
_gs_opt (port->outPath, &buff);
DisableTTYOptions (&buff);
_ss_opt (port->outPath, &buff);
}
int SerialOpen
(SERIAL_PORT *pPort, const char *name) {
SERIAL_PORT_PRIVATE *port;
port = malloc (sizeof (*port));
if (port == NULL)
return serialFatal;
port->stack = NULL;
if ((name == NULL) || (name[0] == 0)) {
port->inPath = 0;
port->outPath = 1;
SerialSaveState (port);
} else {
port->inPath = port->outPath = open (name, 3);
if (port->inPath == -1) {
free (port);
return serialFatal;
}
}
CleanPort (port);
*pPort = port;
return serialOK;
}
int SerialClose
(SERIAL_PORT portPublic) {
SERIAL_PORT_PRIVATE *port = portPublic;
while (port->stack)
SerialRestoreState (portPublic);
if (port->inPath > 2)
close (port->inPath);
if (port->outPath > 2)
close (port->outPath);
free (port);
return serialOK;
}
int SerialSaveState
(SERIAL_PORT portPublic) {
SERIAL_PORT_PRIVATE *port = portPublic;
PORT_PARAMS *pParams;
pParams = malloc (sizeof (*pParams));
if (pParams == NULL)
return serialFatal;
_gs_opt (port->inPath, &(pParams->inParams));
_gs_opt (port->outPath, &(pParams->outParams));
pParams->pNext = port->stack;
port->stack = pParams;
return serialOK;
}
int SerialRestoreState
(SERIAL_PORT portPublic) {
SERIAL_PORT_PRIVATE *port = portPublic;
PORT_PARAMS *pParams;
pParams = port->stack;
if (pParams == NULL)
return serialOK;
port->stack = pParams->pNext;
_ss_opt (port->inPath, &(pParams->inParams));
_ss_opt (port->outPath, &(pParams->outParams));
free (pParams);
return serialOK;
}
int SerialSetWord
(SERIAL_PORT portPublic, int wordLength) {
SERIAL_PORT_PRIVATE *port = portPublic;
struct sgbuf buff;
_gs_opt (port->inPath, &buff);
switch (wordLength) {
case 8:
buff.sg_baud &= 0x1f;
break;
default:
return serialFatal;
}
_ss_opt (port->inPath, &buff);
_gs_opt (port->outPath, &buff);
switch (wordLength) {
case 8:
buff.sg_baud &= 0x1f;
break;
default:
return serialFatal;
}
_ss_opt (port->outPath, &buff);
return serialOK;
}
int SerialSetParity
(SERIAL_PORT portPublic, int parity) {
SERIAL_PORT_PRIVATE *port = portPublic;
struct sgbuf buff;
_gs_opt (port->inPath, &buff);
switch (parity) {
case parityNone:
buff.sg_parity = 0;
break;
default:
return serialFatal;
}
_ss_opt (port->inPath, &buff);
_gs_opt (port->outPath, &buff);
switch (parity) {
case parityNone:
buff.sg_parity = 0;
break;
default:
return serialFatal;
}
_ss_opt (port->outPath, &buff);
return serialOK;
}
int SerialMakeTransparent
(SERIAL_PORT portPublic) {
SERIAL_PORT_PRIVATE *port = portPublic;
struct sgbuf buff;
_gs_opt (port->inPath, &buff);
memset (&(buff.sg_backsp), 0,
((int) &(((struct sgbuf *) 0)->sg_parity)) - ((int) &(((struct sgbuf *) 0)->sg_backsp)));
buff.sg_xon = buff.sg_xoff = 0;
_ss_opt (port->inPath, &buff);
_gs_opt (port->outPath, &buff);
memset (&(buff.sg_backsp), 0,
((int) &(((struct sgbuf *) 0)->sg_parity)) - ((int) &(((struct sgbuf *) 0)->sg_backsp)));
buff.sg_xon = buff.sg_xoff = 0;
_ss_opt (port->outPath, &buff);
return serialOK;
}
static int sigabort = 0;
static int
trap (int sig)
{
if (sig != 101)
sigabort = TRUE;
return 0;
}
int SerialReadWithTimeout
(SERIAL_PORT portPublic, int timeout,
void *pBuffer, unsigned long *pLength) {
SERIAL_PORT_PRIVATE *port = portPublic;
int n = *pLength;
int readsize;
char *p = pBuffer;
intercept (trap);
while (n > 0) {
if ((readsize = _gs_rdy (port->inPath)) < 0) {
int ticks = CLK_TCK * timeout;
int interval = CLK_TCK / 8;
_ss_ssig (port->inPath, 101);
while (((readsize = _gs_rdy (port->inPath)) < 0) && !sigabort && (ticks > 0)) {
tsleep (interval);
ticks -= interval;
}
if (sigabort) {
*pLength -= n;
return serialUserCancel;
}
if (readsize < 0) {
*pLength -= n;
return serialTimeout;
}
_ss_rel (port->inPath);
}
if (readsize > n)
readsize = n;
read (port->inPath, p, readsize);
n -= readsize;
p += readsize;
}
*pLength -= n;
return serialOK;
}
int SerialSend
(SERIAL_PORT portPublic, const void *pBuffer, unsigned long length) {
SERIAL_PORT_PRIVATE *port = portPublic;
intercept (trap);
write (port->outPath, pBuffer, length);
return serialOK;
}
int SerialWaitForSentBytes
(SERIAL_PORT portPublic) {
return serialOK;
}
int SerialSendBreak
(SERIAL_PORT portPublic) {
/* System-specific code to send a break signal. */
return serialOK;
}
int SerialPause
(SERIAL_PORT portPublic, int seconds) {
/* System-specific code to pause without losing serial data. */
return serialOK;
}