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