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 TTYSession : public TTYStream, public Thread
00593 {
00594 public:
00602 TTYSession(const char *name, int pri = 0, int stack = 0);
00603 };
00604
00605 #ifndef WIN32
00606
00607
00608
00609 class __EXPORT SerialPort;
00610 class __EXPORT SerialService;
00611
00633 class __EXPORT SerialPort: public Serial, public TimerPort
00634 {
00635 private:
00636 SerialPort *next, *prev;
00637 SerialService *service;
00638 #ifdef USE_POLL
00639 struct pollfd *ufd;
00640 #endif
00641 bool detect_pending;
00642 bool detect_output;
00643 bool detect_disconnect;
00644
00645 friend class SerialService;
00646
00647 protected:
00654 SerialPort(SerialService *svc, const char *name);
00655
00660 virtual ~SerialPort();
00661
00666 void setDetectPending( bool );
00667
00671 inline bool getDetectPending( void ) const
00672 { return detect_pending; }
00673
00678 void setDetectOutput( bool );
00679
00683 inline bool getDetectOutput( void ) const
00684 { return detect_output; }
00685
00690 virtual void expired(void);
00691
00697 virtual void pending(void);
00698
00703 virtual void disconnect(void);
00704
00714 inline int output(void *buf, int len)
00715 {return aWrite((char *)buf, len);};
00716
00720 virtual void output(void);
00721
00731 inline int input(void *buf, int len)
00732 {return aRead((char *)buf, len);};
00733 public:
00741 void setTimer(timeout_t timeout = 0);
00742
00748 void incTimer(timeout_t timeout);
00749 };
00750
00773 class __EXPORT SerialService : public Thread, private Mutex
00774 {
00775 private:
00776 fd_set connect;
00777 int iosync[2];
00778 int hiwater;
00779 int count;
00780 SerialPort *first, *last;
00781
00787 void attach(SerialPort *port);
00788
00794 void detach(SerialPort *port);
00795
00799 void run(void);
00800
00801 friend class SerialPort;
00802
00803 protected:
00810 virtual void onUpdate(unsigned char flag);
00811
00816 virtual void onEvent(void);
00817
00824 virtual void onCallback(SerialPort *port);
00825
00826 public:
00836 void update(unsigned char flag = 0xff);
00837
00846 SerialService(int pri = 0, size_t stack = 0, const char *id = NULL);
00847
00851 virtual ~SerialService();
00852
00859 inline int getCount(void)
00860 {return count;};
00861 };
00862
00863 #endif
00864
00865
00866
00867 #ifdef COMMON_STD_EXCEPTION
00868 class __EXPORT SerException : public IOException
00869 {
00870 public:
00871 SerException(const String &str) : IOException(str) {};
00872 };
00873 #endif
00874
00875 #ifdef CCXX_NAMESPACES
00876 }
00877 #endif
00878
00879 #endif
00880