GNU CommonC++
|
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 CCXX_SERIAL_H_ 00045 #define CCXX_SERIAL_H_ 00046 00047 #ifndef CCXX_MISSING_H_ 00048 #include <cc++/missing.h> 00049 #endif 00050 00051 #ifndef CCXX_THREAD_H_ 00052 #include <cc++/thread.h> 00053 #endif 00054 00055 #ifndef CCXX_EXCEPTION_H_ 00056 #include <cc++/exception.h> 00057 #endif 00058 00059 #ifndef WIN32 00060 typedef int HANDLE; 00061 #define INVALID_HANDLE_VALUE (-1) 00062 #endif 00063 00064 #ifdef CCXX_NAMESPACES 00065 namespace ost { 00066 #endif 00067 00098 class __EXPORT Serial 00099 { 00100 public: 00101 enum Error { 00102 errSuccess = 0, 00103 errOpenNoTty, 00104 errOpenFailed, 00105 errSpeedInvalid, 00106 errFlowInvalid, 00107 errParityInvalid, 00108 errCharsizeInvalid, 00109 errStopbitsInvalid, 00110 errOptionInvalid, 00111 errResourceFailure, 00112 errOutput, 00113 errInput, 00114 errTimeout, 00115 errExtended 00116 }; 00117 typedef enum Error Error; 00118 00119 enum Flow { 00120 flowNone, 00121 flowSoft, 00122 flowHard, 00123 flowBoth 00124 }; 00125 typedef enum Flow Flow; 00126 00127 enum Parity { 00128 parityNone, 00129 parityOdd, 00130 parityEven 00131 }; 00132 typedef enum Parity Parity; 00133 00134 enum Pending { 00135 pendingInput, 00136 pendingOutput, 00137 pendingError 00138 }; 00139 typedef enum Pending Pending; 00140 00141 private: 00142 Error errid; 00143 char *errstr; 00144 00145 struct { 00146 bool thrown: 1; 00147 bool linebuf: 1; 00148 } flags; 00149 00150 void * original; 00151 void * current; 00152 00156 void initSerial(void); 00157 00158 protected: 00159 00160 HANDLE dev; 00161 00162 int bufsize; 00163 00169 void open(const char *fname); 00170 00175 void close(void); 00176 00184 virtual int aRead(char * Data, const int Length); 00185 00192 virtual int aWrite(const char * Data, const int Length); 00193 00201 Error error(Error error, char *errstr = NULL); 00202 00209 inline void error(char *err) 00210 {error(errExtended, err);}; 00211 00212 00219 inline void setError(bool enable) 00220 {flags.thrown = !enable;}; 00221 00232 int setPacketInput(int size, unsigned char btimer = 0); 00233 00243 int setLineInput(char newline = 13, char nl1 = 0); 00244 00248 void restore(void); 00249 00253 void flushInput(void); 00254 00258 void flushOutput(void); 00259 00263 void waitOutput(void); 00264 00269 void endSerial(void); 00270 00276 void initConfig(void); 00277 00282 Serial() 00283 {initSerial();}; 00284 00291 Serial(const char *name); 00292 00293 00294 public: 00295 00302 virtual ~Serial(); 00303 00308 Serial &operator=(const Serial &from); 00309 00316 Error setSpeed(unsigned long speed); 00317 00324 Error setCharBits(int bits); 00325 00332 Error setParity(Parity parity); 00333 00340 Error setStopBits(int bits); 00341 00348 Error setFlowControl(Flow flow); 00349 00355 void toggleDTR(timeout_t millisec); 00356 00360 void sendBreak(void); 00361 00368 inline Error getErrorNumber(void) 00369 {return errid;}; 00370 00377 inline char *getErrorString(void) 00378 {return errstr;}; 00379 00387 inline int getBufferSize(void) 00388 {return bufsize;}; 00389 00399 virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF); 00400 }; 00401 00423 class __EXPORT TTYStream : protected std::streambuf, public Serial, public std::iostream 00424 { 00425 private: 00426 int doallocate(); 00427 00428 friend TTYStream& crlf(TTYStream&); 00429 friend TTYStream& lfcr(TTYStream&); 00430 00431 protected: 00432 char *gbuf, *pbuf; 00433 timeout_t timeout; 00434 00439 TTYStream(); 00440 00445 void allocate(void); 00446 00451 void endStream(void); 00452 00459 int underflow(void); 00460 00469 int uflow(void); 00470 00478 int overflow(int ch); 00479 00480 public: 00487 TTYStream(const char *filename, timeout_t to = 0); 00488 00492 virtual ~TTYStream(); 00493 00499 inline void setTimeout(timeout_t to) 00500 {timeout = to;}; 00501 00509 void interactive(bool flag); 00510 00517 int sync(void); 00518 00530 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF); 00531 }; 00532 00542 class __EXPORT ttystream : public TTYStream 00543 { 00544 public: 00548 ttystream(); 00549 00557 ttystream(const char *name); 00558 00564 void open(const char *name); 00565 00569 void close(void); 00570 00574 inline bool operator!() 00575 {return (dev < 0);}; 00576 }; 00577 00588 class __EXPORT TTYSession : public Thread, public TTYStream 00589 { 00590 public: 00598 TTYSession(const char *name, int pri = 0, int stack = 0); 00599 00600 virtual ~TTYSession(); 00601 }; 00602 00603 #ifndef WIN32 00604 00605 // Not support this right now....... 00606 // 00607 class __EXPORT SerialPort; 00608 class __EXPORT SerialService; 00609 00631 class __EXPORT SerialPort: public Serial, public TimerPort 00632 { 00633 private: 00634 SerialPort *next, *prev; 00635 SerialService *service; 00636 #ifdef USE_POLL 00637 struct pollfd *ufd; 00638 #endif 00639 bool detect_pending; 00640 bool detect_output; 00641 bool detect_disconnect; 00642 00643 friend class SerialService; 00644 00645 protected: 00652 SerialPort(SerialService *svc, const char *name); 00653 00658 virtual ~SerialPort(); 00659 00664 void setDetectPending( bool ); 00665 00669 inline bool getDetectPending( void ) const 00670 { return detect_pending; } 00671 00676 void setDetectOutput( bool ); 00677 00681 inline bool getDetectOutput( void ) const 00682 { return detect_output; } 00683 00688 virtual void expired(void); 00689 00695 virtual void pending(void); 00696 00701 virtual void disconnect(void); 00702 00712 inline int output(void *buf, int len) 00713 {return aWrite((char *)buf, len);}; 00714 00718 virtual void output(void); 00719 00729 inline int input(void *buf, int len) 00730 {return aRead((char *)buf, len);}; 00731 public: 00739 void setTimer(timeout_t timeout = 0); 00740 00746 void incTimer(timeout_t timeout); 00747 }; 00748 00771 class __EXPORT SerialService : public Thread, private Mutex 00772 { 00773 private: 00774 fd_set connect; 00775 int iosync[2]; 00776 int hiwater; 00777 int count; 00778 SerialPort *first, *last; 00779 00785 void attach(SerialPort *port); 00786 00792 void detach(SerialPort *port); 00793 00797 void run(void); 00798 00799 friend class SerialPort; 00800 00801 protected: 00808 virtual void onUpdate(unsigned char flag); 00809 00814 virtual void onEvent(void); 00815 00822 virtual void onCallback(SerialPort *port); 00823 00824 public: 00834 void update(unsigned char flag = 0xff); 00835 00844 SerialService(int pri = 0, size_t stack = 0, const char *id = NULL); 00845 00849 virtual ~SerialService(); 00850 00857 inline int getCount(void) 00858 {return count;}; 00859 }; 00860 00861 #endif 00862 00863 00864 00865 #ifdef COMMON_STD_EXCEPTION 00866 class __EXPORT SerException : public IOException 00867 { 00868 public: 00869 SerException(const String &str) : IOException(str) {}; 00870 }; 00871 #endif 00872 00873 #ifdef CCXX_NAMESPACES 00874 } 00875 #endif 00876 00877 #endif 00878