UCommon
/usr/src/RPM/BUILD/ucommon-6.3.3/inc/commoncpp/serial.h
Go to the documentation of this file.
00001 // Copyright (C) 1999-2005 Open Source Telecom Corporation.
00002 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
00003 // Copyright (C) 2015 Cherokees of Idaho.
00004 //
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 2 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public License
00016 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 // As a special exception, you may use this file as part of a free software
00019 // library without restriction.  Specifically, if other files instantiate
00020 // templates or use macros or inline functions from this file, or you compile
00021 // this file and link it with other files to produce an executable, this
00022 // file does not by itself cause the resulting executable to be covered by
00023 // the GNU General Public License.  This exception does not however
00024 // invalidate any other reasons why the executable file might be covered by
00025 // the GNU General Public License.
00026 //
00027 // This exception applies only to the code released under the name GNU
00028 // Common C++.  If you copy code from other releases into a copy of GNU
00029 // Common C++, as the General Public License permits, the exception does
00030 // not apply to the code that you add in this way.  To avoid misleading
00031 // anyone as to the status of such modified files, you must delete
00032 // this exception notice from them.
00033 //
00034 // If you write modifications of your own for GNU Common C++, it is your choice
00035 // whether to permit this exception to apply to your modifications.
00036 // If you do not wish that, delete this exception notice.
00037 //
00038 
00044 #ifndef COMMONCPP_SERIAL_H_
00045 #define COMMONCPP_SERIAL_H_
00046 
00047 #ifndef COMMONCPP_CONFIG_H_
00048 #include <commoncpp/config.h>
00049 #endif
00050 
00051 #ifndef COMMONCPP_THREAD_H_
00052 #include <commoncpp/thread.h>
00053 #endif
00054 
00055 #ifndef COMMMONCPP_EXCEPTION_H_
00056 #include <commoncpp/exception.h>
00057 #endif
00058 
00059 namespace ost {
00060 
00091 class __EXPORT Serial
00092 {
00093 public:
00094     enum Error {
00095         errSuccess = 0,
00096         errOpenNoTty,
00097         errOpenFailed,
00098         errSpeedInvalid,
00099         errFlowInvalid,
00100         errParityInvalid,
00101         errCharsizeInvalid,
00102         errStopbitsInvalid,
00103         errOptionInvalid,
00104         errResourceFailure,
00105         errOutput,
00106         errInput,
00107         errTimeout,
00108         errExtended
00109     };
00110     typedef enum Error Error;
00111 
00112     enum Flow {
00113         flowNone,
00114         flowSoft,
00115         flowHard,
00116         flowBoth
00117     };
00118     typedef enum Flow Flow;
00119 
00120     enum Parity {
00121         parityNone,
00122         parityOdd,
00123         parityEven
00124     };
00125     typedef enum Parity Parity;
00126 
00127     enum Pending {
00128         pendingInput,
00129         pendingOutput,
00130         pendingError
00131     };
00132     typedef enum Pending Pending;
00133 
00134 private:
00135     Error errid;
00136     char *errstr;
00137 
00138     struct {
00139         bool thrown: 1;
00140         bool linebuf: 1;
00141     } flags;
00142 
00143     void *original;
00144     void *current;
00145 
00149     void initSerial(void);
00150 
00151 protected:
00152     fd_t dev;
00153     int bufsize;
00154 
00160     void open(const char *fname);
00161 
00166     void close(void);
00167 
00175     virtual int aRead(char * Data, const int Length);
00176 
00183     virtual int aWrite(const char * Data, const int Length);
00184 
00192     Error error(Error error, char *errstr = NULL);
00193 
00200     inline void error(char *err)
00201         {error(errExtended, err);}
00202 
00203 
00210     inline void setError(bool enable)
00211         {flags.thrown = !enable;}
00212 
00223     int setPacketInput(int size, unsigned char btimer = 0);
00224 
00234     int setLineInput(char newline = 13, char nl1 = 0);
00235 
00239     void restore(void);
00240 
00244     void flushInput(void);
00245 
00249     void flushOutput(void);
00250 
00254     void waitOutput(void);
00255 
00260     void endSerial(void);
00261 
00267     void initConfig(void);
00268 
00273     Serial()
00274         {initSerial();}
00275 
00282     Serial(const char *name);
00283 
00284 
00285 public:
00286 
00293     virtual ~Serial();
00294 
00299     Serial &operator=(const Serial &from);
00300 
00307     Error setSpeed(unsigned long speed);
00308 
00315     Error setCharBits(int bits);
00316 
00323     Error setParity(Parity parity);
00324 
00331     Error setStopBits(int bits);
00332 
00339     Error setFlowControl(Flow flow);
00340 
00346     void toggleDTR(timeout_t millisec);
00347 
00351     void sendBreak(void);
00352 
00359     inline Error getErrorNumber(void)
00360         {return errid;}
00361 
00368     inline char *getErrorString(void)
00369         {return errstr;}
00370 
00378     inline int getBufferSize(void)
00379         {return bufsize;}
00380 
00390     virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
00391 };
00392 
00414 class __EXPORT TTYStream : protected std::streambuf, public Serial, public std::iostream
00415 {
00416 private:
00417     int doallocate();
00418 
00419     friend TTYStream& crlf(TTYStream&);
00420     friend TTYStream& lfcr(TTYStream&);
00421 
00422 protected:
00423     char *gbuf, *pbuf;
00424     timeout_t timeout;
00425 
00430     TTYStream();
00431 
00436     void allocate(void);
00437 
00442     void endStream(void);
00443 
00450     int underflow(void);
00451 
00460     int uflow(void);
00461 
00469     int overflow(int ch);
00470 
00471 public:
00478     TTYStream(const char *filename, timeout_t to = 0);
00479 
00483     virtual ~TTYStream();
00484 
00490     inline void setTimeout(timeout_t to)
00491         {timeout = to;}
00492 
00500     void interactive(bool flag);
00501 
00508     int sync(void);
00509 
00521     bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
00522 };
00523 
00533 class __EXPORT ttystream : public TTYStream
00534 {
00535 public:
00539     ttystream();
00540 
00548     ttystream(const char *name);
00549 
00555     void open(const char *name);
00556 
00560     void close(void);
00561 
00565     inline bool operator!()
00566         {return (dev < 0);}
00567 };
00568 
00579 class __EXPORT TTYSession : public Thread, public TTYStream
00580 {
00581 public:
00589     TTYSession(const char *name, int pri = 0, int stack = 0);
00590 
00591     virtual ~TTYSession();
00592 };
00593 
00594 #ifndef _MSWINDOWS_
00595 
00596 //  Not support this right now.......
00597 //
00598 class SerialPort;
00599 class SerialService;
00600 
00622 class __EXPORT SerialPort: public Serial, public TimerPort
00623 {
00624 private:
00625     SerialPort *next, *prev;
00626     SerialService *service;
00627 #ifdef  USE_POLL
00628     struct pollfd *ufd;
00629 #endif
00630     bool detect_pending;
00631     bool detect_output;
00632     bool detect_disconnect;
00633 
00634     friend class SerialService;
00635 
00636 protected:
00643     SerialPort(SerialService *svc, const char *name);
00644 
00649     virtual ~SerialPort();
00650 
00655     void setDetectPending( bool );
00656 
00660     inline bool getDetectPending( void ) const
00661         { return detect_pending; }
00662 
00667     void setDetectOutput( bool );
00668 
00672     inline bool getDetectOutput( void ) const
00673         { return detect_output; }
00674 
00679     virtual void expired(void);
00680 
00686     virtual void pending(void);
00687 
00692     virtual void disconnect(void);
00693 
00703     inline int output(void *buf, int len)
00704         {return aWrite((char *)buf, len);}
00705 
00709     virtual void output(void);
00710 
00720     inline int input(void *buf, int len)
00721         {return aRead((char *)buf, len);}
00722 
00723 public:
00731     void setTimer(timeout_t timeout = 0);
00732 
00738     void incTimer(timeout_t timeout);
00739 };
00740 
00763 class __EXPORT SerialService : public Thread, private Mutex
00764 {
00765 private:
00766     fd_set connect;
00767     int iosync[2];
00768     int hiwater;
00769     int count;
00770     SerialPort *first, *last;
00771 
00777     void attach(SerialPort *port);
00778 
00784     void detach(SerialPort *port);
00785 
00789     void run(void);
00790 
00791     friend class SerialPort;
00792 
00793 protected:
00800     virtual void onUpdate(unsigned char flag);
00801 
00806     virtual void onEvent(void);
00807 
00814     virtual void onCallback(SerialPort *port);
00815 
00816 public:
00826     void update(unsigned char flag = 0xff);
00827 
00836     SerialService(int pri = 0, size_t stack = 0, const char *id = NULL);
00837 
00841     virtual ~SerialService();
00842 
00849     inline int getCount(void)
00850         {return count;}
00851 };
00852 
00853 #endif
00854 
00855 #ifdef  CCXX_EXCEPTIONS
00856 class __EXPORT SerException : public IOException
00857 {
00858 public:
00859     SerException(const String &str) : IOException(str) {}
00860 };
00861 #endif
00862 
00863 } // namespace ost
00864 
00865 #endif