Intial commit
This commit is contained in:
60
tcl-dp/dunix_patch/dp.tek
Normal file
60
tcl-dp/dunix_patch/dp.tek
Normal file
@@ -0,0 +1,60 @@
|
||||
# TekiFile 1.0
|
||||
|
||||
#
|
||||
|
||||
# TEKI install file for Tcl-DP and the "example" extensions
|
||||
|
||||
#
|
||||
|
||||
lappend newPackage(available) dp4.0
|
||||
|
||||
|
||||
|
||||
set newPackage(dp4.0,name) dp
|
||||
|
||||
set newPackage(dp4.0,version) 4.0
|
||||
|
||||
set newPackage(dp4.0,description) "Tcl-DP"
|
||||
|
||||
set newPackage(dp4.0,requires) {{Tcl 7.6}}
|
||||
|
||||
set newPackage(dp4.0,tekiFile) dp.tek
|
||||
|
||||
set newPackage(dp4.0,updateURL) {}
|
||||
|
||||
set newPackage(dp4.0,registerURL) {}
|
||||
|
||||
set newPackage(dp4.0,srcURL) http://www.cs.cornell.edu/Info/Projects/zeno/Projects/Tcl-DP.html
|
||||
|
||||
set newPackage(dp4.0,srcDir) .
|
||||
|
||||
set newPackage(dp4.0,destDir) dp4.0
|
||||
|
||||
set newPackage(dp4.0,copyright) LICENSE
|
||||
|
||||
set newPackage(dp4.0,infoFile) README
|
||||
|
||||
set newPackage(dp4.0,tclFiles) {
|
||||
|
||||
library/acl.tcl library/distribObj.tcl library/dp_atclose.tcl
|
||||
|
||||
library/dp_atexit.tcl library/ldelete.tcl library/oo.tcl library/rpc.tcl
|
||||
|
||||
}
|
||||
|
||||
set newPackage(dp4.0,dataFiles) {
|
||||
|
||||
api/dpApi.c api/dpApi.h api/dpExample.c api/readme.api
|
||||
|
||||
}
|
||||
|
||||
set newPackage(dp4.0,docDir) doc
|
||||
|
||||
set newPackage(dp4.0,docFiles) {
|
||||
|
||||
dp_accept.html dp_admin.html dp_connect.html
|
||||
|
||||
dp_copy.html dp_netinfo.html dp_rdo.html dp_recv.html dp_rpc.html
|
||||
|
||||
dp_send.html email.html filter.html index.html ipm.html
|
||||
|
||||
743
tcl-dp/dunix_patch/dpSerial.c
Normal file
743
tcl-dp/dunix_patch/dpSerial.c
Normal file
@@ -0,0 +1,743 @@
|
||||
/* Tcl_Channel implementation for serial ports */
|
||||
|
||||
|
||||
|
||||
#include "generic/dpInt.h"
|
||||
|
||||
#include "generic/dpPort.h"
|
||||
|
||||
#include <termios.h>
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
* These names cannot be longer than MAX_LENGTH - 1
|
||||
|
||||
*
|
||||
|
||||
* Note that a given machine may only HAVE 2 serial ports
|
||||
|
||||
* so serial3 and serial4 may not work even if they are
|
||||
|
||||
* listed here.
|
||||
|
||||
*
|
||||
|
||||
* A note on naming: because there is no standard UNIX
|
||||
|
||||
* naming scheme, we must do it by OS. You can add more
|
||||
|
||||
* ports by upping NUM_PORTS and adding the names.
|
||||
|
||||
*
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#define NUM_PORTS 4
|
||||
|
||||
|
||||
|
||||
static char *portNames[NUM_PORTS] = {
|
||||
|
||||
#if defined(__LINUX__)
|
||||
|
||||
"/dev/ttyS0",
|
||||
|
||||
"/dev/ttyS1",
|
||||
|
||||
"/dev/ttyS2",
|
||||
|
||||
"/dev/ttyS3"
|
||||
|
||||
#elif defined(__HPUX__)
|
||||
|
||||
"/dev/plt_rs232_a",
|
||||
|
||||
"/dev/plt_rs232_b",
|
||||
|
||||
NULL,
|
||||
|
||||
NULL
|
||||
|
||||
#elif defined(__SUNOS__) || defined(__SOLARIS__)
|
||||
|
||||
"/dev/ttya",
|
||||
|
||||
"/dev/ttyb",
|
||||
|
||||
"/dev/ttyc",
|
||||
|
||||
"/dev/ttyd"
|
||||
|
||||
#elif defined(__sgi)
|
||||
|
||||
"/dev/ttyd1",
|
||||
|
||||
"/dev/ttyd2",
|
||||
|
||||
"/dev/ttyd3",
|
||||
|
||||
"/dev/ttyd4"
|
||||
|
||||
#elif defined(__FREEBSD__)
|
||||
|
||||
/*
|
||||
|
||||
* Why is it so difficult to find out
|
||||
|
||||
* the names of the damn serial ports in
|
||||
|
||||
* FreeBSD?
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
|
||||
NULL
|
||||
|
||||
#elif defined(__osf__)
|
||||
|
||||
/*
|
||||
|
||||
For OSF
|
||||
|
||||
*/
|
||||
|
||||
"/dev/tty00",
|
||||
|
||||
"/dev/tty01",
|
||||
|
||||
NULL,
|
||||
|
||||
NULL
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
|
||||
* We could assume the worst and just not let
|
||||
|
||||
* DP be compiled. But most people won't
|
||||
|
||||
* even use the serial interface (<sniff>) so we'll
|
||||
|
||||
* just let DP catch it at runtime.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
|
||||
NULL
|
||||
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
int DppOpenSerialChannel _ANSI_ARGS_((Tcl_Interp *interp,
|
||||
|
||||
ClientData instanceData, char *devStr,
|
||||
|
||||
int flags));
|
||||
|
||||
int DppSerialBlock _ANSI_ARGS_((ClientData instanceData,
|
||||
|
||||
int mode));
|
||||
|
||||
int DppSerialClose _ANSI_ARGS_((ClientData instanceData));
|
||||
|
||||
int DppSerialInput _ANSI_ARGS_((ClientData instanceData,
|
||||
|
||||
char *bufPtr, int bufSize,
|
||||
|
||||
int *errorCodePtr));
|
||||
|
||||
int DppSerialOutput _ANSI_ARGS_((ClientData instanceData,
|
||||
|
||||
char *bufPtr, int toWrite,
|
||||
|
||||
int *errorCodePtr));
|
||||
|
||||
int DppSerialSetOption _ANSI_ARGS_((ClientData instanceData,
|
||||
|
||||
int optionName, int val));
|
||||
|
||||
int DppSerialGetOption _ANSI_ARGS_((ClientData instanceData,
|
||||
|
||||
int opt, char *optionName,
|
||||
|
||||
Tcl_DString *dsPtr));
|
||||
|
||||
int DppSerialFileReady _ANSI_ARGS_((ClientData instanceData,
|
||||
|
||||
int mask));
|
||||
|
||||
void DppSerialWatchFile _ANSI_ARGS_((ClientData instanceData,
|
||||
|
||||
int mask));
|
||||
|
||||
|
||||
|
||||
static char * DppBaudRateConsToStr _ANSI_ARGS_((int rate));
|
||||
|
||||
static int DppBaudRateNumToCons _ANSI_ARGS_((int rate));
|
||||
|
||||
static char * DppCheckDevice _ANSI_ARGS_((char *devStr));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------
|
||||
|
||||
*
|
||||
|
||||
* DppOpenSerialChannel -
|
||||
|
||||
*
|
||||
|
||||
* Creates a DP channel using the serial port specified
|
||||
|
||||
* in dev (i.e. "serial1")
|
||||
|
||||
*
|
||||
|
||||
* Returns
|
||||
|
||||
*
|
||||
|
||||
* Tcl_Channel used for I/O.
|
||||
|
||||
*
|
||||
|
||||
* Side Effects
|
||||
|
||||
*
|
||||
|
||||
* None.
|
||||
|
||||
*
|
||||
|
||||
* ------------------------------------------------
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
int
|
||||
|
||||
DppOpenSerialChannel(interp, instanceData, devStr, flags)
|
||||
|
||||
Tcl_Interp *interp;
|
||||
|
||||
ClientData instanceData;
|
||||
|
||||
char *devStr; /* /dev to use */
|
||||
|
||||
int flags; /* T/F to block */
|
||||
|
||||
/* Only block is implemented
|
||||
|
||||
right now */
|
||||
|
||||
{
|
||||
|
||||
SerialState *ssPtr = (SerialState *) instanceData;
|
||||
|
||||
char *openStr;
|
||||
|
||||
int fd, mode = O_RDWR;
|
||||
|
||||
int blockFlag = 0;
|
||||
|
||||
|
||||
|
||||
blockFlag |= 0x1;
|
||||
|
||||
if (flags & 0x2) {
|
||||
|
||||
mode = O_RDONLY;
|
||||
|
||||
}
|
||||
|
||||
if ((openStr = DppCheckDevice(devStr)) == NULL) {
|
||||
|
||||
Tcl_AppendResult(interp, "Unknown device \"", devStr, "\"", NULL);
|
||||
|
||||
return TCL_ERROR;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
fd = open(openStr, mode);
|
||||
|
||||
if (fd == -1) {
|
||||
|
||||
Tcl_AppendResult(interp, "Error opening ", openStr,
|
||||
|
||||
": ", Tcl_PosixError(interp), NULL);
|
||||
|
||||
return TCL_ERROR;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
ssPtr->fd = fd;
|
||||
|
||||
strcpy(ssPtr->deviceName, devStr);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
* Setup the port to a default of 19200, 8N1
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
if (DppSerialSetOption(ssPtr, DP_BAUDRATE, 19200) == TCL_ERROR) {
|
||||
|
||||
goto error;
|
||||
|
||||
}
|
||||
|
||||
if (DppSerialSetOption(ssPtr, DP_CHARSIZE, 8) == TCL_ERROR) {
|
||||
|
||||
goto error;
|
||||
|
||||
}
|
||||
|
||||
if (DppSerialSetOption(ssPtr, DP_PARITY, PARITY_NONE) == TCL_ERROR) {
|
||||
|
||||
goto error;
|
||||
|
||||
}
|
||||
|
||||
if (DppSerialSetOption(ssPtr, DP_STOPBITS, 1) == TCL_ERROR) {
|
||||
|
||||
goto error;
|
||||
|
||||
}
|
||||
|
||||
if (DppSerialSetOption(ssPtr, DP_BLOCK, blockFlag) == TCL_ERROR) {
|
||||
|
||||
goto error;
|
||||
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
|
||||
|
||||
|
||||
error:
|
||||
|
||||
Tcl_AppendResult(interp, "Error configuring serial device", NULL);
|
||||
|
||||
return TCL_ERROR;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* --------------------------------------------------
|
||||
|
||||
*
|
||||
|
||||
* SerialBlock --
|
||||
|
||||
*
|
||||
|
||||
* Sets blocking mode of serial port based on
|
||||
|
||||
* mode.
|
||||
|
||||
*
|
||||
|
||||
* Returns
|
||||
|
||||
*
|
||||
|
||||
* TCL_OK or TCL_ERROR
|
||||
|
||||
*
|
||||
|
||||
* Side Effects
|
||||
|
||||
*
|
||||
|
||||
* None.
|
||||
|
||||
*
|
||||
|
||||
* ---------------------------------------------------
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
int
|
||||
|
||||
DppSerialBlock(instanceData, mode)
|
||||
|
||||
ClientData instanceData;
|
||||
|
||||
int mode;
|
||||
|
||||
{
|
||||
|
||||
if (mode == TCL_MODE_BLOCKING) {
|
||||
|
||||
return DppSerialSetOption(instanceData, DP_BLOCK, 1);
|
||||
|
||||
} else {
|
||||
|
||||
return DppSerialSetOption(instanceData, DP_BLOCK, 0);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* --------------------------------------------------
|
||||
|
||||
*
|
||||
|
||||
* SerialClose --
|
||||
|
||||
*
|
||||
|
||||
* Closes the serial port and frees memory
|
||||
|
||||
* associated with the port.
|
||||
|
||||
*
|
||||
|
||||
* Returns
|
||||
|
||||
*
|
||||
|
||||
* TCL_OK or TCL_ERROR
|
||||
|
||||
*
|
||||
|
||||
* Side Effects
|
||||
|
||||
*
|
||||
|
||||
* Channel is no longer available.
|
||||
|
||||
*
|
||||
|
||||
* ---------------------------------------------------
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
int
|
||||
|
||||
DppSerialClose(instanceData)
|
||||
|
||||
ClientData instanceData;
|
||||
|
||||
{
|
||||
|
||||
SerialState *ssPtr = (SerialState *) instanceData;
|
||||
|
||||
|
||||
|
||||
return close(ssPtr->fd);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* --------------------------------------------------
|
||||
|
||||
*
|
||||
|
||||
* SerialInput --
|
||||
|
||||
*
|
||||
|
||||
* Reads upto bufSize bytes from serial port
|
||||
|
||||
* into buf.
|
||||
|
||||
*
|
||||
|
||||
* Returns
|
||||
|
||||
*
|
||||
|
||||
* Number of bytes read or -1 with POSIX error code
|
||||
|
||||
* in errorCodePtr.
|
||||
|
||||
*
|
||||
|
||||
* Side Effects
|
||||
|
||||
*
|
||||
|
||||
* buf is modified.
|
||||
|
||||
*
|
||||
|
||||
* ---------------------------------------------------
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
int
|
||||
|
||||
DppSerialInput(instanceData, bufPtr, bufSize, errorCodePtr)
|
||||
|
||||
ClientData instanceData;
|
||||
|
||||
char *bufPtr;
|
||||
|
||||
int bufSize;
|
||||
|
||||
int *errorCodePtr;
|
||||
|
||||
{
|
||||
|
||||
SerialState *ssPtr = (SerialState *) instanceData;
|
||||
|
||||
int amount;
|
||||
|
||||
|
||||
|
||||
amount = read(ssPtr->fd, bufPtr, bufSize);
|
||||
|
||||
if (amount > 0) {
|
||||
|
||||
/* We are fine. Return amount read */
|
||||
|
||||
return amount;
|
||||
|
||||
} else if (amount == 0) {
|
||||
|
||||
/* There is no data to be read */
|
||||
|
||||
int flags;
|
||||
|
||||
fcntl(ssPtr->fd, F_GETFL, &flags);
|
||||
|
||||
if (NONBLOCKING(flags)) {
|
||||
|
||||
*errorCodePtr = EAGAIN;
|
||||
|
||||
return -1;
|
||||
|
||||
} else {
|
||||
|
||||
return amount;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Bummer! Set the error code and return */
|
||||
|
||||
*errorCodePtr = errno;
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* --------------------------------------------------
|
||||
|
||||
*
|
||||
|
||||
* SerialOutput --
|
||||
|
||||
*
|
||||
|
||||
* Sends toWrite bytes out through the serial
|
||||
|
||||
* port.
|
||||
|
||||
*
|
||||
|
||||
* Returns
|
||||
|
||||
*
|
||||
|
||||
* Number of bytes written or -1 and a POSIX
|
||||
|
||||
* error in errorCodePtr.
|
||||
|
||||
*
|
||||
|
||||
* Side Effects
|
||||
|
||||
*
|
||||
|
||||
* None.
|
||||
|
||||
*
|
||||
|
||||
* ---------------------------------------------------
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
int
|
||||
|
||||
DppSerialOutput(instanceData, bufPtr, toWrite, errorCodePtr)
|
||||
|
||||
ClientData instanceData;
|
||||
|
||||
char *bufPtr;
|
||||
|
||||
int toWrite;
|
||||
|
||||
int *errorCodePtr;
|
||||
|
||||
{
|
||||
|
||||
int amount;
|
||||
|
||||
SerialState *ssPtr = (SerialState *) instanceData;
|
||||
|
||||
|
||||
|
||||
amount = write(ssPtr->fd, bufPtr, toWrite);
|
||||
|
||||
if (amount > 0) {
|
||||
|
||||
return amount;
|
||||
|
||||
} else if (amount == 0) {
|
||||
|
||||
int flags;
|
||||
|
||||
fcntl(ssPtr->fd, F_GETFL, &flags);
|
||||
|
||||
if (NONBLOCKING(flags)) {
|
||||
|
||||
*errorCodePtr = EAGAIN;
|
||||
|
||||
return -1;
|
||||
|
||||
} else {
|
||||
|
||||
return amount;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
*errorCodePtr = errno;
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* --------------------------------------------------
|
||||
|
||||
*
|
||||
|
||||
* DppSetSerialState --
|
||||
|
||||
*
|
||||
|
||||
* Platform-specific serial option changer.
|
||||
|
||||
*
|
||||
|
||||
* Returns
|
||||
|
||||
*
|
||||
|
||||
* TCL_OK or TCL_ERROR
|
||||
|
||||
*
|
||||
|
||||
* Side Effects
|
||||
|
||||
*
|
||||
|
||||
* None.
|
||||
|
||||
*
|
||||
|
||||
* ---------------------------------------------------
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
int
|
||||
|
||||
DppSerialSetOption(instanceData, optionName, optionVal)
|
||||
|
||||
ClientData instanceData;
|
||||
|
||||
int optionName;
|
||||
|
||||
int optionVal;
|
||||
|
||||
{
|
||||
|
||||
SerialState *ssPtr = (SerialState *) instanceData;
|
||||
|
||||
struct termios term;
|
||||
|
||||
int rate;
|
||||
|
||||
int flags = 0;
|
||||
|
||||
|
||||
|
||||
if (tcgetattr(ssPtr->fd, &term) == -1) {
|
||||
|
||||
return TCL_ERROR;
|
||||
|
||||
}
|
||||
|
||||
switch (optionName) {
|
||||
|
||||
case DP_PARITY:
|
||||
|
||||
if (optionVal == PARITY_NONE) {
|
||||
|
||||
term.c_cflag &= ~PARENB;
|
||||
|
||||
} else {
|
||||
Reference in New Issue
Block a user