[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Patch: Serial Port Interactive Mode Buffering Improved
From: |
Conrad T. Pino |
Subject: |
Patch: Serial Port Interactive Mode Buffering Improved |
Date: |
Wed, 7 Sep 2005 12:10:24 -0700 |
This patch modifies the following files:
demo/serialecho.cpp
demo/serialecho.h
demo/serialmain.cpp
include/cc++/serial.h
src/serial.cpp
This patch is committed on "dev-bcb6-arm" branch between revision
tags "dev-bcb6-arm-0050" and "dev-bcb6-arm-0051".
Index: demo/serialecho.cpp
===================================================================
RCS file: /cvsroot/gnutelephony/testing/commoncpp2/demo/serialecho.cpp,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -p -r1.1.1.1 -r1.1.1.1.2.1
--- demo/serialecho.cpp 23 Apr 2005 22:08:01 -0000 1.1.1.1
+++ demo/serialecho.cpp 7 Sep 2005 19:01:20 -0000 1.1.1.1.2.1
@@ -28,45 +28,56 @@
using namespace std;
SerialEcho::SerialEcho(const char *device,
+ unsigned long speed,
+ int char_bits,
+ Parity parity,
+ int stop_bits,
+ Flow flow,
int priority, int stacksize) :
TTYSession( device, priority, stacksize ) {
cout << "Creating SerialEcho" << endl;
- if (!(*this)) {
+ if (!isOpen()) {
throw xError();
::exit(1);
} else {
cout << "modem ready" << endl;
}
- interactive(false);
+ interactive(true);
- if (setSpeed(38400)) cout << getErrorString() << endl;
- if (setCharBits(8)) cout << getErrorString() << endl;
- if (setParity(Serial::parityNone)) cout << getErrorString() << endl;
- if (setStopBits(1)) cout << getErrorString() << endl;
- if (setFlowControl(Serial::flowHard)) cout << getErrorString() << endl;
+ if (setSpeed(speed)) cout << getErrorString() << endl;
+ if (setCharBits(char_bits)) cout << getErrorString() << endl;
+ if (setParity(parity)) cout << getErrorString() << endl;
+ if (setStopBits(stop_bits)) cout << getErrorString() << endl;
+ if (setFlowControl(flow)) cout << getErrorString() << endl;
+
+// setPacketInput(16,100);
cout << "config done" << endl;
}
void SerialEcho::run() {
- char* s = new char[getBufferSize()];
-
cout << "start monitor" << endl;
- while (s[0] != 'X') {
- while (isPending(Serial::pendingInput)) {
- cout.put( TTYStream::get() );
- }
- sleep(500);
+#if 0
+//FILE *fout = fopen("serial.out", "wt");
+ FILE *fout = stdout;
+ while (isPending(pendingInput)) {
+ fputc( TTYStream::get(), fout );
+ if ( ! isPending( pendingInput, 0 ) ) fflush( fout );
}
+#else
+ int data;
+ while ( ( data = TTYStream::get() ) ) {
+ cout.put( data );
+ if ( ! isPending( pendingInput, 0 ) ) cout.flush();
+ }
+#endif
cout << "end of monitor" << endl;
- delete [] s;
-
exit();
}
Index: demo/serialecho.h
===================================================================
RCS file: /cvsroot/gnutelephony/testing/commoncpp2/demo/serialecho.h,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -p -r1.1.1.1 -r1.1.1.1.2.1
--- demo/serialecho.h 23 Apr 2005 22:08:01 -0000 1.1.1.1
+++ demo/serialecho.h 7 Sep 2005 19:01:20 -0000 1.1.1.1.2.1
@@ -18,7 +18,7 @@
#ifndef SERIALECHO_H
#define SERIALECHO_H
-#include <cc++/common.h>
+#include <cc++/serial.h>
#ifdef CCXX_NAMESPACES
using namespace std;
@@ -28,7 +28,12 @@ using namespace ost;
class SerialEcho : public TTYSession {
public:
- SerialEcho(const char *device,
+ SerialEcho(const char *device,
+ unsigned long speed = 38400,
+ int char_bits = 8,
+ Parity parity = parityNone,
+ int stop_bits = 1,
+ Flow flow = flowHard,
int priority = 0, int stacksize = 0);
// Exception classes
Index: demo/serialmain.cpp
===================================================================
RCS file: /cvsroot/gnutelephony/testing/commoncpp2/demo/serialmain.cpp,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -p -r1.1.1.1 -r1.1.1.1.2.1
--- demo/serialmain.cpp 23 Apr 2005 22:08:01 -0000 1.1.1.1
+++ demo/serialmain.cpp 7 Sep 2005 19:01:20 -0000 1.1.1.1.2.1
@@ -29,16 +29,60 @@
int main(int argc, char **argv)
{
+ const char *device = "/dev/modem2";
+ unsigned long speed = 38400;
+ int char_bits = 8;
+ Serial::Parity parity = Serial::parityNone;
+ int stop_bits = 1;
+ Serial::Flow flow = Serial::flowHard;
+
+ if ( argc > 1 ) device = argv[ 1 ];
+ if ( argc > 2 ) speed = atol( argv[ 2 ] );
+ if ( argc > 3 ) char_bits = atoi( argv[ 3 ] );
+ if ( argc > 4 )
+ switch ( *argv[ 4 ] ) {
+ case 'e':
+ case 'E':
+ parity = Serial::parityEven;
+ break;
+ case 'o':
+ case 'O':
+ parity = Serial::parityOdd;
+ break;
+ default:
+ parity = Serial::parityNone;
+ break;
+ }
+ if ( argc > 5 ) stop_bits = atoi( argv[ 5 ] );
+ if ( argc > 6 )
+ switch ( *argv[ 6 ] ) {
+ case 'b':
+ case 'B':
+ flow = Serial::flowBoth;
+ break;
+ case 'h':
+ case 'H':
+ flow = Serial::flowHard;
+ break;
+ case 's':
+ case 'S':
+ flow = Serial::flowSoft;
+ break;
+ default:
+ flow = Serial::flowNone;
+ break;
+ }
+
cout << "Serial Echo to TCP Sessions" << endl;
SerialEcho *modem;
try {
- modem = new SerialEcho("/dev/modem2");
+ modem = new SerialEcho(device, speed, char_bits, parity, stop_bits, flow);
} catch (SerialEcho::xError *e) {
cout << "Modem Error; aborting" << endl;
::exit(1);
} catch (Serial *e) {
cout << "Serial Error: "
- << modem->getErrorString()
+ << e->getErrorString()
<< "; aborting"
<< endl;
::exit(1);
@@ -46,7 +90,7 @@ int main(int argc, char **argv)
char* b = new char[modem->getBufferSize()];
- cout << "Modem code:" << modem->start() << endl;
+ cout << "Modem start code: " << modem->start() << endl;
while (cin >> b, b[0]) {
@@ -64,4 +108,3 @@ int main(int argc, char **argv)
}
/** 2000 by TeleDynamics Communications Inc - address@hidden/
-
Index: include/cc++/serial.h
===================================================================
RCS file: /cvsroot/gnutelephony/testing/commoncpp2/include/cc++/serial.h,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -p -r1.1.1.1 -r1.1.1.1.2.1
--- include/cc++/serial.h 23 Apr 2005 22:08:11 -0000 1.1.1.1
+++ include/cc++/serial.h 7 Sep 2005 19:01:20 -0000 1.1.1.1.2.1
@@ -143,7 +143,7 @@ public:
private:
Error errid;
- char *errstr;
+ const char *errstr;
struct
{
@@ -160,11 +160,10 @@ private:
void initSerial(void);
protected:
+ size_t getsize;
HANDLE dev;
- int bufsize;
-
/**
* Opens the serial device.
*
@@ -179,6 +178,13 @@ protected:
void close(void);
/**
+ * Tests if the serial device is open.
+ *
+ */
+ inline bool isOpen(void) const
+ {return dev != INVALID_HANDLE_VALUE;}
+
+ /**
* Reads from serial device.
*
* @param Data Point to character buffer to receive data. Buffers MUST
@@ -202,7 +208,7 @@ protected:
* @param error defined serial error id.
* @param errstr string or message to optionally pass.
*/
- Error error(Error error, char *errstr = NULL);
+ Error error(const Error error, const char *errstr = NULL);
/**
* This service is used to thow application defined serial
@@ -210,7 +216,7 @@ protected:
*
* @param errstr string or message to pass.
*/
- inline void error(char *err)
+ inline void error(const char *err)
{error(errExtended, err);};
@@ -254,17 +260,17 @@ protected:
/**
* Used to flush the input waiting queue.
*/
- void flushInput(void);
+ virtual void flushInput(void);
/**
* Used to flush any pending output data.
*/
- void flushOutput(void);
+ virtual void flushOutput(void);
/**
* Used to wait until all output has been sent.
*/
- void waitOutput(void);
+ virtual void waitOutput(void);
/**
* Used as the default destructor for ending serial I/O
@@ -378,7 +384,7 @@ public:
*
* @return string for error message.
*/
- inline char *getErrorString(void)
+ inline const char *getErrorString(void)
{return errstr;};
/**
@@ -388,8 +394,7 @@ public:
*
* @return number of bytes used for buffering.
*/
- inline int getBufferSize(void)
- {return bufsize;};
+ virtual size_t getBufferSize(void);
/**
* Get the status of pending operations. This can be used to
@@ -427,12 +432,12 @@ public:
class __EXPORT TTYStream : protected std::streambuf, public Serial, public
std::iostream
{
private:
- int doallocate();
-
friend TTYStream& crlf(TTYStream&);
friend TTYStream& lfcr(TTYStream&);
protected:
+ size_t bufsize;
+
char *gbuf, *pbuf;
timeout_t timeout;
@@ -455,6 +460,21 @@ protected:
void endStream(void);
/**
+ * Used to flush the input waiting queue.
+ */
+ virtual void flushInput(void);
+
+ /**
+ * Used to flush any pending output data.
+ */
+ virtual void flushOutput(void);
+
+ /**
+ * Used to wait until all output has been sent.
+ */
+ virtual void waitOutput(void);
+
+ /**
* This streambuf method is used to load the input buffer
* through the established tty serial port.
*
Index: src/serial.cpp
===================================================================
RCS file: /cvsroot/gnutelephony/testing/commoncpp2/src/serial.cpp,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -p -r1.1.1.1 -r1.1.1.1.2.1
--- src/serial.cpp 23 Apr 2005 22:08:24 -0000 1.1.1.1
+++ src/serial.cpp 7 Sep 2005 19:01:20 -0000 1.1.1.1.2.1
@@ -130,11 +130,7 @@ Serial::Serial(const char *fname)
open(fname);
-#ifdef WIN32
- if(dev == INVALID_HANDLE_VALUE)
-#else
- if(dev < 0)
-#endif
+ if(!isOpen())
{
error(errOpenFailed);
return;
@@ -154,9 +150,7 @@ Serial::Serial(const char *fname)
CommTimeOuts.WriteTotalTimeoutConstant = 1000;
SetCommTimeouts(dev, &CommTimeOuts) ;
-
#else
-
if(!isatty(dev))
{
Serial::close();
@@ -206,7 +200,6 @@ void Serial::initConfig(void)
attr->fParity = true;
SetCommState(dev, attr);
-
#else
struct termios *attr = (struct termios *)current;
struct termios *orig = (struct termios *)original;
@@ -275,34 +268,61 @@ void Serial::initSerial(void)
void Serial::endSerial(void)
{
+ if(isOpen())
+ {
+ if(original)
#ifdef WIN32
- if(dev == INVALID_HANDLE_VALUE && original)
- SetCommState(dev, (DCB *)original);
+ SetCommState(dev, (DCB *)original);
+#else
+ tcsetattr(dev, TCSANOW, (struct termios *)original);
+#endif
+ Serial::close();
+ }
if(current)
+ {
+#ifdef WIN32
delete (DCB *)current;
+#else
+ delete (struct termios *)original;
+#endif
+ current = NULL;
+ }
if(original)
+ {
+#ifdef WIN32
delete (DCB *)original;
#else
- if(dev < 0 && original)
- tcsetattr(dev, TCSANOW, (struct termios *)original);
-
- if(current)
- delete (struct termios *)current;
-
- if(original)
delete (struct termios *)original;
#endif
- Serial::close();
-
- current = NULL;
- original = NULL;
-
+ original = NULL;
+ }
}
-Serial::Error Serial::error(Error err, char *errs)
+Serial::Error Serial::error(const Error err, const char *errs)
{
+ static const char * errorStrings[ ] =
+ {
+ "errSuccess",
+ "errOpenNoTty",
+ "errOpenFailed",
+ "errSpeedInvalid",
+ "errFlowInvalid",
+ "errParityInvalid",
+ "errCharsizeInvalid",
+ "errStopbitsInvalid",
+ "errOptionInvalid",
+ "errResourceFailure",
+ "errOutput",
+ "errInput",
+ "errTimeout",
+ "errExtended"
+ };
+
+ if(!errs)
+ errs = errorStrings[ err ];
+
errid = err;
errstr = errs;
if(!err)
@@ -336,13 +356,13 @@ int Serial::setPacketInput(int size, uns
return 0;
#else
-#ifdef _PC_MAX_INPUT
- int max = fpathconf(dev, _PC_MAX_INPUT);
-#else
- int max = MAX_INPUT;
-#endif
+ size_t max = getBufferSize();
+
struct termios *attr = (struct termios *)current;
+ if(size < 0)
+ size = 1;
+
if(size > max)
size = max;
@@ -351,7 +371,7 @@ int Serial::setPacketInput(int size, uns
attr->c_cc[VTIME] = btimer;
attr->c_lflag &= ~ICANON;
tcsetattr(dev, TCSANOW, attr);
- bufsize = size;
+ getsize = size;
return size;
#endif
}
@@ -362,7 +382,6 @@ int Serial::setLineInput(char newline, c
// Still to be done......
return 0;
#else
-
struct termios *attr = (struct termios *)current;
attr->c_cc[VMIN] = attr->c_cc[VTIME] = 0;
attr->c_cc[VEOL] = newline;
@@ -370,13 +389,12 @@ int Serial::setLineInput(char newline, c
attr->c_lflag |= ICANON;
tcsetattr(dev, TCSANOW, attr);
#ifdef _PC_MAX_CANON
- bufsize = fpathconf(dev, _PC_MAX_CANON);
+ getsize = fpathconf(dev, _PC_MAX_CANON);
#else
- bufsize = MAX_CANON;
+ getsize = MAX_CANON;
#endif
- return bufsize;
+ return getsize;
#endif
-
}
void Serial::flushInput(void)
@@ -400,7 +418,7 @@ void Serial::flushOutput(void)
void Serial::waitOutput(void)
{
#ifdef WIN32
-
+ FlushFileBuffers(dev);
#else
tcdrain(dev);
#endif
@@ -410,7 +428,7 @@ Serial &Serial::operator=(const Serial &
{
Serial::close();
- if(ser.dev < 0)
+ if(!ser.isOpen())
return *this;
#ifdef WIN32
@@ -435,12 +453,11 @@ Serial &Serial::operator=(const Serial &
void Serial::open(const char * fname)
{
-
#ifndef WIN32
int cflags = O_RDWR | O_NDELAY;
dev = ::open(fname, cflags);
- if(dev > -1)
- initConfig();
+ if(dev < 0)
+ dev = INVALID_HANDLE_VALUE;
#else
// open COMM device
dev = CreateFile(fname,
@@ -450,21 +467,20 @@ void Serial::open(const char * fname)
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING,
NULL);
- if(dev != INVALID_HANDLE_VALUE)
- initConfig();
#endif
+ if(isOpen())
+ initConfig();
}
#ifdef WIN32
int Serial::aRead(char * Data, const int Length)
{
-
unsigned long dwLength = 0, dwError, dwReadLength;
COMSTAT cs;
OVERLAPPED ol;
// Return zero if handle is invalid
- if(dev == INVALID_HANDLE_VALUE)
+ if(!isOpen())
return 0;
// Read max length or only what is available
@@ -552,29 +568,6 @@ void Serial::close()
dev = INVALID_HANDLE_VALUE;
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/*
const int iAsync::getTimeOuts(unsigned long & readTimeout, unsigned long &
writeTimeout)
{
@@ -687,14 +680,12 @@ Serial::Error Serial::setSpeed(unsigned
}
#ifdef WIN32
-
DCB * dcb = (DCB *)current;
dcb->DCBlength = sizeof(DCB);
GetCommState(dev, dcb);
dcb->BaudRate = rate;
SetCommState(dev, dcb) ;
-
#else
struct termios *attr = (struct termios *)current;
cfsetispeed(attr, rate);
@@ -706,14 +697,23 @@ Serial::Error Serial::setSpeed(unsigned
Serial::Error Serial::setFlowControl(Flow flow)
{
-#ifdef WIN32
+ switch(flow)
+ {
+ case flowSoft:
+ case flowBoth:
+ case flowHard:
+ case flowNone:
+ break;
+ default:
+ return error(errFlowInvalid);
+ }
+#ifdef WIN32
DCB * attr = (DCB *)current;
attr->XonChar = ASCII_XON;
attr->XoffChar = ASCII_XOFF;
attr->XonLim = 100;
attr->XoffLim = 100;
-
switch(flow)
{
case flowSoft:
@@ -727,18 +727,12 @@ Serial::Error Serial::setFlowControl(Flo
break;
case flowNone:
break;
- default:
- return error(errFlowInvalid);
}
-
SetCommState(dev, attr);
#else
-
struct termios *attr = (struct termios *)current;
-
attr->c_cflag &= ~CRTSCTS;
attr->c_iflag &= ~(IXON | IXANY | IXOFF);
-
switch(flow)
{
case flowSoft:
@@ -751,20 +745,24 @@ Serial::Error Serial::setFlowControl(Flo
break;
case flowNone:
break;
- default:
- return error(errFlowInvalid);
}
-
tcsetattr(dev, TCSANOW, attr);
-
#endif
return errSuccess;
}
Serial::Error Serial::setStopBits(int bits)
{
-#ifdef WIN32
+ switch(bits)
+ {
+ case 1:
+ case 2:
+ break;
+ default:
+ return error(errStopbitsInvalid);
+ }
+#ifdef WIN32
DCB * attr = (DCB *)current;
switch(bits)
{
@@ -774,15 +772,11 @@ Serial::Error Serial::setStopBits(int bi
case 2:
attr->StopBits = TWOSTOPBITS;
break;
- default:
- return error(errStopbitsInvalid);
}
-
SetCommState(dev, attr);
#else
struct termios *attr = (struct termios *)current;
attr->c_cflag &= ~CSTOPB;
-
switch(bits)
{
case 1:
@@ -790,8 +784,6 @@ Serial::Error Serial::setStopBits(int bi
case 2:
attr->c_cflag |= CSTOPB;
break;
- default:
- return error(errStopbitsInvalid);
}
tcsetattr(dev, TCSANOW, attr);
#endif
@@ -800,25 +792,24 @@ Serial::Error Serial::setStopBits(int bi
Serial::Error Serial::setCharBits(int bits)
{
-#ifdef WIN32
-
- DCB * attr = (DCB *)current;
switch(bits)
{
case 5:
case 6:
case 7:
case 8:
- attr->ByteSize = bits;
break;
default:
return error(errCharsizeInvalid);
}
+
+#ifdef WIN32
+ DCB * attr = (DCB *)current;
+ attr->ByteSize = bits;
SetCommState(dev, attr);
#else
struct termios *attr = (struct termios *)current;
attr->c_cflag &= ~CSIZE;
-
switch(bits)
{
case 5:
@@ -833,8 +824,6 @@ Serial::Error Serial::setCharBits(int bi
case 8:
attr->c_cflag |= CS8;
break;
- default:
- return error(errCharsizeInvalid);
}
tcsetattr(dev, TCSANOW, attr);
#endif
@@ -843,8 +832,17 @@ Serial::Error Serial::setCharBits(int bi
Serial::Error Serial::setParity(Parity parity)
{
-#ifdef WIN32
+ switch(parity)
+ {
+ case parityEven:
+ case parityOdd:
+ case parityNone:
+ break;
+ default:
+ return error(errParityInvalid);
+ }
+#ifdef WIN32
DCB * attr = (DCB *)current;
switch(parity)
{
@@ -857,14 +855,11 @@ Serial::Error Serial::setParity(Parity p
case parityNone:
attr->Parity = NOPARITY;
break;
- default:
- return error(errParityInvalid);
}
SetCommState(dev, attr);
#else
struct termios *attr = (struct termios *)current;
attr->c_cflag &= ~(PARENB | PARODD);
-
switch(parity)
{
case parityEven:
@@ -875,8 +870,6 @@ Serial::Error Serial::setParity(Parity p
break;
case parityNone:
break;
- default:
- return error(errParityInvalid);
}
tcsetattr(dev, TCSANOW, attr);
#endif
@@ -920,6 +913,20 @@ void Serial::toggleDTR(timeout_t millise
#endif
}
+size_t Serial::getBufferSize(void)
+{
+ size_t maxsize;
+#ifdef _PC_MAX_INPUT
+ if(isOpen())
+ maxsize = fpathconf(dev, _PC_MAX_INPUT);
+ else
+ maxsize = pathconf("/dev/tty", _PC_MAX_INPUT);
+#else
+ maxsize = MAX_INPUT;
+#endif
+ return maxsize;
+}
+
bool Serial::isPending(Pending pending, timeout_t timeout)
{
#ifdef WIN32
@@ -992,7 +999,7 @@ bool Serial::isPending(Pending pending,
switch(pending)
{
case pendingInput:
- pfd.events = POLLIN;
+ pfd.events = POLLIN | POLLPRI;
break;
case pendingOutput:
pfd.events = POLLOUT;
@@ -1020,7 +1027,6 @@ bool Serial::isPending(Pending pending,
if(pfd.revents & pfd.events)
return true;
-
#else
struct timeval tv;
fd_set grp;
@@ -1080,7 +1086,7 @@ TTYStream::TTYStream(const char *filenam
gbuf = pbuf = NULL;
timeout = to;
- if(INVALID_HANDLE_VALUE != dev)
+ if(isOpen())
allocate();
}
@@ -1111,6 +1117,9 @@ void TTYStream::endStream(void)
if(bufsize)
sync();
+ setg(NULL, NULL, NULL);
+ setp(NULL, NULL);
+
if(gbuf)
{
delete[] gbuf;
@@ -1127,14 +1136,12 @@ void TTYStream::endStream(void)
void TTYStream::allocate(void)
{
- if(INVALID_HANDLE_VALUE == dev)
+ if(!isOpen())
return;
-#ifdef _PC_MAX_INPUT
- bufsize = fpathconf(dev, _PC_MAX_INPUT);
-#else
- bufsize = MAX_INPUT;
-#endif
+ bufsize = getBufferSize();
+ if(!getsize)
+ getsize = bufsize;
gbuf = new char[bufsize];
pbuf = new char[bufsize];
@@ -1155,119 +1162,110 @@ void TTYStream::allocate(void)
setp(pbuf, pbuf + bufsize);
}
-int TTYStream::doallocate()
+void TTYStream::flushInput(void)
{
- if(bufsize)
- return 0;
-
- allocate();
- return 1;
+ if(gbuf)
+ setg(gbuf, gbuf + bufsize, gbuf + bufsize);
+
+ Serial::flushInput();
}
-void TTYStream::interactive(bool iflag)
+void TTYStream::flushOutput(void)
{
-#ifdef WIN32
- if(dev == INVALID_HANDLE_VALUE)
-#else
- if(dev < 0)
-#endif
- return;
+ if(pbuf)
+ setp(pbuf, pbuf + bufsize);
- if(bufsize >= 1)
- endStream();
+ Serial::flushOutput();
+}
- if(iflag)
- {
- // setting to unbuffered mode
+void TTYStream::waitOutput(void)
+{
+// while(overflow(EOF) == EOF);
+ overflow(EOF);
- bufsize = 1;
- gbuf = new char[bufsize];
+ Serial::waitOutput();
+}
-#if !(defined(STLPORT) || defined(__KCC))
-#if defined(__GNUC__) && (__GNUC__ < 3)
- setb(0,0);
-#endif
-#endif
- setg(gbuf, gbuf+bufsize, gbuf+bufsize);
- setp(pbuf, pbuf);
+void TTYStream::interactive(bool iflag)
+{
+ if(!isOpen())
return;
- }
- if(bufsize < 2)
- allocate();
+ // interactive is 1 else standard size
+ getsize = iflag ? 1 : getBufferSize();
}
int TTYStream::uflow(void)
{
- int rlen;
- unsigned char ch;
+ int ch = underflow();
+
+ if(ch != EOF && gptr())
+ gbump(1);
+
+ return (unsigned char)ch;
+}
- if(bufsize < 2)
+int TTYStream::underflow(void)
+{
+ ssize_t rlen;
+
+ if(!gptr())
{
- if(timeout)
+ if(timeout && !Serial::isPending(pendingInput, timeout))
{
- if(Serial::isPending(pendingInput, timeout))
- rlen = aRead((char *)&ch, 1);
- else
- rlen = -1;
+ setstate(failbit);
+ error(errTimeout);
+ return EOF;
}
- else
- rlen = aRead((char *)&ch, 1);
+
+ unsigned char ch;
+
+ rlen = aRead((char *)&ch, 1);
if(rlen < 1)
{
if(rlen < 0)
- clear(ios::failbit | rdstate());
+ {
+ setstate(failbit);
+ error(errInput);
+ }
return EOF;
}
return ch;
}
- else
- {
- ch = underflow();
- gbump(1);
- return ch;
- }
-}
-
-int TTYStream::underflow(void)
-{
- ssize_t rlen = 1;
-
- if(!gptr())
- return EOF;
if(gptr() < egptr())
return (unsigned char)*gptr();
- rlen = (ssize_t)((gbuf + bufsize) - eback());
if(timeout && !Serial::isPending(pendingInput, timeout))
- rlen = -1;
- else
- rlen = aRead((char *)eback(), rlen);
+ {
+ setstate(failbit);
+ error(errTimeout);
+ return EOF;
+ }
+ if(getsize < 1)
+ return EOF;
+
+ rlen = aRead(gbuf, getsize);
if(rlen < 1)
{
if(rlen < 0)
{
- clear(ios::failbit | rdstate());
+ setstate(failbit);
error(errInput);
}
return EOF;
}
- setg(eback(), eback(), eback() + rlen);
+ setg(gbuf, gbuf, gbuf + rlen);
return (unsigned char) *gptr();
}
int TTYStream::sync(void)
{
- if(bufsize > 1 && pbase() && ((pptr() - pbase()) > 0))
- {
- overflow(0);
- waitOutput();
- setp(pbuf, pbuf + bufsize);
- }
- setg(gbuf, gbuf + bufsize, gbuf + bufsize);
+ waitOutput();
+ flushOutput();
+ flushInput();
return 0;
}
@@ -1276,7 +1274,7 @@ int TTYStream::overflow(int c)
unsigned char ch;
ssize_t rlen, req;
- if(bufsize < 2)
+ if(!pbase())
{
if(c == EOF)
return 0;
@@ -1286,15 +1284,15 @@ int TTYStream::overflow(int c)
if(rlen < 1)
{
if(rlen < 0)
- clear(ios::failbit | rdstate());
+ {
+ setstate(failbit);
+ error(errOutput);
+ }
return EOF;
}
- else
- return c;
- }
- if(!pbase())
- return EOF;
+ return c;
+ }
req = (ssize_t)(pptr() - pbase());
if(req)
@@ -1303,31 +1301,41 @@ int TTYStream::overflow(int c)
if(rlen < 1)
{
if(rlen < 0)
- clear(ios::failbit | rdstate());
+ {
+ setstate(failbit);
+ error(errOutput);
+ }
return EOF;
}
req -= rlen;
}
-
+
if(req)
// memmove(pptr(), pptr() + rlen, req);
memmove(pbuf, pbuf + rlen, req);
setp(pbuf + req, pbuf + bufsize);
- if(c != EOF)
- {
- *pptr() = (unsigned char)c;
- pbump(1);
- }
+ if(c == EOF)
+ return 0;
+
+ *pptr() = (unsigned char)c;
+ pbump(1);
+
return c;
}
bool TTYStream::isPending(Pending pending, timeout_t timer)
{
-// if(pending == pendingInput && in_avail())
-// return true;
-// else if(pending == pendingOutput)
-// flush();
+ switch ( pending )
+ {
+ case pendingInput:
+ if(in_avail())
+ return true;
+ break;
+ case pendingOutput:
+ flush();
+ break;
+ }
return Serial::isPending(pending, timer);
}
@@ -1352,11 +1360,7 @@ TTYStream()
void ttystream::close(void)
{
-#ifdef WIN32
- if (INVALID_HANDLE_VALUE == dev)
-#else
- if(dev < 0)
-#endif
+ if (!isOpen())
return;
endStream();
@@ -1372,7 +1376,7 @@ void ttystream::open(const char *name)
size_t namelen;
long opt;
- if (INVALID_HANDLE_VALUE != dev)
+ if (isOpen())
{
restore();
close();
@@ -1408,7 +1412,7 @@ void ttystream::open(const char *name)
Serial::open(pathname);
- if(INVALID_HANDLE_VALUE == dev)
+ if(!isOpen())
{
error(errOpenFailed);
return;
@@ -1492,6 +1496,7 @@ Thread(pri, stack), TTYStream(filename)
TTYSession::~TTYSession()
{
terminate();
+ endStream();
endSerial();
}
@@ -1508,11 +1513,7 @@ detect_disconnect(true)
next = prev = NULL;
service = NULL;
-#ifdef WIN32
- if(INVALID_HANDLE_VALUE != dev)
-#else
- if(dev > -1)
-#endif
+ if(isOpen())
{
setError(false);
service = svc;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Patch: Serial Port Interactive Mode Buffering Improved,
Conrad T. Pino <=