ucommon
commoncpp/serial.h
Go to the documentation of this file.
00001 // Copyright (C) 1999-2005 Open Source Telecom Corporation.
00002 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
00003 //
00004 // This program is free software; you can redistribute it and/or modify
00005 // it under the terms of the GNU General Public License as published by
00006 // the Free Software Foundation; either version 2 of the License, or
00007 // (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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_COMMONCPP
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 
00153     fd_t    dev;
00154 
00155     int bufsize;
00156 
00162     void        open(const char *fname);
00163 
00168     void        close(void);
00169 
00177     virtual int aRead(char * Data, const int Length);
00178 
00185     virtual int aWrite(const char * Data, const int Length);
00186 
00194     Error error(Error error, char *errstr = NULL);
00195 
00202     inline void error(char *err)
00203         {error(errExtended, err);};
00204 
00205 
00212     inline void setError(bool enable)
00213         {flags.thrown = !enable;};
00214 
00225     int setPacketInput(int size, unsigned char btimer = 0);
00226 
00236     int setLineInput(char newline = 13, char nl1 = 0);
00237 
00241     void restore(void);
00242 
00246     void flushInput(void);
00247 
00251     void flushOutput(void);
00252 
00256     void waitOutput(void);
00257 
00262     void endSerial(void);
00263 
00269     void initConfig(void);
00270 
00275     Serial()
00276         {initSerial();};
00277 
00284     Serial(const char *name);
00285 
00286 
00287 public:
00288 
00295     virtual ~Serial();
00296 
00301     Serial &operator=(const Serial &from);
00302 
00309     Error setSpeed(unsigned long speed);
00310 
00317     Error setCharBits(int bits);
00318 
00325     Error setParity(Parity parity);
00326 
00333     Error setStopBits(int bits);
00334 
00341     Error setFlowControl(Flow flow);
00342 
00348     void toggleDTR(timeout_t millisec);
00349 
00353     void sendBreak(void);
00354 
00361     inline Error getErrorNumber(void)
00362         {return errid;};
00363 
00370     inline char *getErrorString(void)
00371         {return errstr;};
00372 
00380     inline int getBufferSize(void)
00381         {return bufsize;};
00382 
00392     virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
00393 };
00394 
00416 class __EXPORT TTYStream : protected std::streambuf, public Serial, public std::iostream
00417 {
00418 private:
00419     int doallocate();
00420 
00421     friend TTYStream& crlf(TTYStream&);
00422     friend TTYStream& lfcr(TTYStream&);
00423 
00424 protected:
00425     char *gbuf, *pbuf;
00426     timeout_t timeout;
00427 
00432     TTYStream();
00433 
00438     void allocate(void);
00439 
00444     void endStream(void);
00445 
00452     int underflow(void);
00453 
00462     int uflow(void);
00463 
00471     int overflow(int ch);
00472 
00473 public:
00480     TTYStream(const char *filename, timeout_t to = 0);
00481 
00485     virtual ~TTYStream();
00486 
00492     inline void setTimeout(timeout_t to)
00493         {timeout = to;};
00494 
00502     void interactive(bool flag);
00503 
00510     int sync(void);
00511 
00523     bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
00524 };
00525 
00535 class __EXPORT ttystream : public TTYStream
00536 {
00537 public:
00541     ttystream();
00542 
00550     ttystream(const char *name);
00551 
00557     void open(const char *name);
00558 
00562     void close(void);
00563 
00567     inline bool operator!()
00568         {return (dev < 0);};
00569 };
00570 
00581 class __EXPORT TTYSession : public Thread, public TTYStream
00582 {
00583 public:
00591     TTYSession(const char *name, int pri = 0, int stack = 0);
00592 
00593     virtual ~TTYSession();
00594 };
00595 
00596 #ifndef _MSWINDOWS_
00597 
00598 //  Not support this right now.......
00599 //
00600 class __EXPORT SerialPort;
00601 class __EXPORT SerialService;
00602 
00624 class __EXPORT SerialPort: public Serial, public TimerPort
00625 {
00626 private:
00627     SerialPort *next, *prev;
00628     SerialService *service;
00629 #ifdef  USE_POLL
00630     struct pollfd *ufd;
00631 #endif
00632     bool detect_pending;
00633     bool detect_output;
00634     bool detect_disconnect;
00635 
00636     friend class SerialService;
00637 
00638 protected:
00645     SerialPort(SerialService *svc, const char *name);
00646 
00651     virtual ~SerialPort();
00652 
00657     void setDetectPending( bool );
00658 
00662     inline bool getDetectPending( void ) const
00663         { return detect_pending; }
00664 
00669     void setDetectOutput( bool );
00670 
00674     inline bool getDetectOutput( void ) const
00675         { return detect_output; }
00676 
00681     virtual void expired(void);
00682 
00688     virtual void pending(void);
00689 
00694     virtual void disconnect(void);
00695 
00705     inline int output(void *buf, int len)
00706         {return aWrite((char *)buf, len);};
00707 
00711     virtual void output(void);
00712 
00722     inline int input(void *buf, int len)
00723         {return aRead((char *)buf, len);};
00724 public:
00732     void setTimer(timeout_t timeout = 0);
00733 
00739     void incTimer(timeout_t timeout);
00740 };
00741 
00764 class __EXPORT SerialService : public Thread, private Mutex
00765 {
00766 private:
00767     fd_set connect;
00768     int iosync[2];
00769     int hiwater;
00770     int count;
00771     SerialPort *first, *last;
00772 
00778     void attach(SerialPort *port);
00779 
00785     void detach(SerialPort *port);
00786 
00790     void run(void);
00791 
00792     friend class SerialPort;
00793 
00794 protected:
00801     virtual void onUpdate(unsigned char flag);
00802 
00807     virtual void onEvent(void);
00808 
00815     virtual void onCallback(SerialPort *port);
00816 
00817 public:
00827     void update(unsigned char flag = 0xff);
00828 
00837     SerialService(int pri = 0, size_t stack = 0, const char *id = NULL);
00838 
00842     virtual ~SerialService();
00843 
00850     inline int getCount(void)
00851         {return count;};
00852 };
00853 
00854 #endif
00855 
00856 #ifdef  CCXX_EXCEPTIONS
00857 class __EXPORT SerException : public IOException
00858 {
00859 public:
00860     SerException(const String &str) : IOException(str) {};
00861 };
00862 #endif
00863 
00864 END_NAMESPACE
00865 
00866 #endif
00867