00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00043 #ifndef CCXX_SERIAL_H_
00044 #define CCXX_SERIAL_H_
00045
00046 #ifndef CCXX_MISSING_H_
00047 #include <cc++/missing.h>
00048 #endif
00049
00050 #ifndef CCXX_THREAD_H_
00051 #include <cc++/thread.h>
00052 #endif
00053
00054 #ifndef CCXX_EXCEPTION_H_
00055 #include <cc++/exception.h>
00056 #endif
00057
00058 #ifndef WIN32
00059 typedef int HANDLE;
00060 #define INVALID_HANDLE_VALUE (-1)
00061 #endif
00062
00063 #ifdef CCXX_NAMESPACES
00064 namespace ost {
00065 #endif
00066
00097 class __EXPORT Serial
00098 {
00099 public:
00100 enum Error
00101 {
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 {
00121 flowNone,
00122 flowSoft,
00123 flowHard,
00124 flowBoth
00125 };
00126 typedef enum Flow Flow;
00127
00128 enum Parity
00129 {
00130 parityNone,
00131 parityOdd,
00132 parityEven
00133 };
00134 typedef enum Parity Parity;
00135
00136 enum Pending
00137 {
00138 pendingInput,
00139 pendingOutput,
00140 pendingError
00141 };
00142 typedef enum Pending Pending;
00143
00144 private:
00145 Error errid;
00146 char *errstr;
00147
00148 struct
00149 {
00150 bool thrown: 1;
00151 bool linebuf: 1;
00152 } flags;
00153
00154 void * original;
00155 void * current;
00156
00160 void initSerial(void);
00161
00162 protected:
00163
00164 HANDLE dev;
00165
00166 int bufsize;
00167
00173 void open(const char *fname);
00174
00179 void close(void);
00180
00188 virtual int aRead(char * Data, const int Length);
00189
00196 virtual int aWrite(const char * Data, const int Length);
00197
00205 Error error(Error error, char *errstr = NULL);
00206
00213 inline void error(char *err)
00214 {error(errExtended, err);};
00215
00216
00223 inline void setError(bool enable)
00224 {flags.thrown = !enable;};
00225
00236 int setPacketInput(int size, unsigned char btimer = 0);
00237
00247 int setLineInput(char newline = 13, char nl1 = 0);
00248
00252 void restore(void);
00253
00257 void flushInput(void);
00258
00262 void flushOutput(void);
00263
00267 void waitOutput(void);
00268
00273 void endSerial(void);
00274
00280 void initConfig(void);
00281
00286 Serial()
00287 {initSerial();};
00288
00295 Serial(const char *name);
00296
00297
00298 public:
00299
00306 virtual ~Serial();
00307
00312 Serial &operator=(const Serial &from);
00313
00320 Error setSpeed(unsigned long speed);
00321
00328 Error setCharBits(int bits);
00329
00336 Error setParity(Parity parity);
00337
00344 Error setStopBits(int bits);
00345
00352 Error setFlowControl(Flow flow);
00353
00359 void toggleDTR(timeout_t millisec);
00360
00364 void sendBreak(void);
00365
00372 inline Error getErrorNumber(void)
00373 {return errid;};
00374
00381 inline char *getErrorString(void)
00382 {return errstr;};
00383
00391 inline int getBufferSize(void)
00392 {return bufsize;};
00393
00403 virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
00404 };
00405
00427 class __EXPORT TTYStream : protected std::streambuf, public Serial, public std::iostream
00428 {
00429 private:
00430 int doallocate();
00431
00432 friend TTYStream& crlf(TTYStream&);
00433 friend TTYStream& lfcr(TTYStream&);
00434
00435 protected:
00436 char *gbuf, *pbuf;
00437 timeout_t timeout;
00438
00443 TTYStream();
00444
00449 void allocate(void);
00450
00455 void endStream(void);
00456
00463 int underflow(void);
00464
00473 int uflow(void);
00474
00482 int overflow(int ch);
00483
00484 public:
00491 TTYStream(const char *filename, timeout_t to = 0);
00492
00496 virtual ~TTYStream();
00497
00503 inline void setTimeout(timeout_t to)
00504 {timeout = to;};
00505
00513 void interactive(bool flag);
00514
00521 int sync(void);
00522
00534 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
00535 };
00536
00546 class __EXPORT ttystream : public TTYStream
00547 {
00548 public:
00552 ttystream();
00553
00561 ttystream(const char *name);
00562
00568 void open(const char *name);
00569
00573 void close(void);
00574
00578 inline bool operator!()
00579 {return (dev < 0);};
00580 };
00581
00592 class __EXPORT TTYSession : public Thread, public TTYStream
00593 {
00594 public:
00602 TTYSession(const char *name, int pri = 0, int stack = 0);
00603
00604 virtual ~TTYSession();
00605 };
00606
00607 #ifndef WIN32
00608
00609
00610
00611 class __EXPORT SerialPort;
00612 class __EXPORT SerialService;
00613
00635 class __EXPORT SerialPort: public Serial, public TimerPort
00636 {
00637 private:
00638 SerialPort *next, *prev;
00639 SerialService *service;
00640 #ifdef USE_POLL
00641 struct pollfd *ufd;
00642 #endif
00643 bool detect_pending;
00644 bool detect_output;
00645 bool detect_disconnect;
00646
00647 friend class SerialService;
00648
00649 protected:
00656 SerialPort(SerialService *svc, const char *name);
00657
00662 virtual ~SerialPort();
00663
00668 void setDetectPending( bool );
00669
00673 inline bool getDetectPending( void ) const
00674 { return detect_pending; }
00675
00680 void setDetectOutput( bool );
00681
00685 inline bool getDetectOutput( void ) const
00686 { return detect_output; }
00687
00692 virtual void expired(void);
00693
00699 virtual void pending(void);
00700
00705 virtual void disconnect(void);
00706
00716 inline int output(void *buf, int len)
00717 {return aWrite((char *)buf, len);};
00718
00722 virtual void output(void);
00723
00733 inline int input(void *buf, int len)
00734 {return aRead((char *)buf, len);};
00735 public:
00743 void setTimer(timeout_t timeout = 0);
00744
00750 void incTimer(timeout_t timeout);
00751 };
00752
00775 class __EXPORT SerialService : public Thread, private Mutex
00776 {
00777 private:
00778 fd_set connect;
00779 int iosync[2];
00780 int hiwater;
00781 int count;
00782 SerialPort *first, *last;
00783
00789 void attach(SerialPort *port);
00790
00796 void detach(SerialPort *port);
00797
00801 void run(void);
00802
00803 friend class SerialPort;
00804
00805 protected:
00812 virtual void onUpdate(unsigned char flag);
00813
00818 virtual void onEvent(void);
00819
00826 virtual void onCallback(SerialPort *port);
00827
00828 public:
00838 void update(unsigned char flag = 0xff);
00839
00848 SerialService(int pri = 0, size_t stack = 0, const char *id = NULL);
00849
00853 virtual ~SerialService();
00854
00861 inline int getCount(void)
00862 {return count;};
00863 };
00864
00865 #endif
00866
00867
00868
00869 #ifdef COMMON_STD_EXCEPTION
00870 class __EXPORT SerException : public IOException
00871 {
00872 public:
00873 SerException(const String &str) : IOException(str) {};
00874 };
00875 #endif
00876
00877 #ifdef CCXX_NAMESPACES
00878 }
00879 #endif
00880
00881 #endif
00882