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