ucommon
|
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