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 errSuccess = 0,
00102 errOpenNoTty,
00103 errOpenFailed,
00104 errSpeedInvalid,
00105 errFlowInvalid,
00106 errParityInvalid,
00107 errCharsizeInvalid,
00108 errStopbitsInvalid,
00109 errOptionInvalid,
00110 errResourceFailure,
00111 errOutput,
00112 errInput,
00113 errTimeout,
00114 errExtended
00115 };
00116 typedef enum Error Error;
00117
00118 enum Flow {
00119 flowNone,
00120 flowSoft,
00121 flowHard,
00122 flowBoth
00123 };
00124 typedef enum Flow Flow;
00125
00126 enum Parity {
00127 parityNone,
00128 parityOdd,
00129 parityEven
00130 };
00131 typedef enum Parity Parity;
00132
00133 enum Pending {
00134 pendingInput,
00135 pendingOutput,
00136 pendingError
00137 };
00138 typedef enum Pending Pending;
00139
00140 private:
00141 Error errid;
00142 char *errstr;
00143
00144 struct {
00145 bool thrown: 1;
00146 bool linebuf: 1;
00147 } flags;
00148
00149 void * original;
00150 void * current;
00151
00155 void initSerial(void);
00156
00157 protected:
00158
00159 HANDLE dev;
00160
00161 int bufsize;
00162
00168 void open(const char *fname);
00169
00174 void close(void);
00175
00183 virtual int aRead(char * Data, const int Length);
00184
00191 virtual int aWrite(const char * Data, const int Length);
00192
00200 Error error(Error error, char *errstr = NULL);
00201
00208 inline void error(char *err)
00209 {error(errExtended, err);};
00210
00211
00218 inline void setError(bool enable)
00219 {flags.thrown = !enable;};
00220
00231 int setPacketInput(int size, unsigned char btimer = 0);
00232
00242 int setLineInput(char newline = 13, char nl1 = 0);
00243
00247 void restore(void);
00248
00252 void flushInput(void);
00253
00257 void flushOutput(void);
00258
00262 void waitOutput(void);
00263
00268 void endSerial(void);
00269
00275 void initConfig(void);
00276
00281 Serial()
00282 {initSerial();};
00283
00290 Serial(const char *name);
00291
00292
00293 public:
00294
00301 virtual ~Serial();
00302
00307 Serial &operator=(const Serial &from);
00308
00315 Error setSpeed(unsigned long speed);
00316
00323 Error setCharBits(int bits);
00324
00331 Error setParity(Parity parity);
00332
00339 Error setStopBits(int bits);
00340
00347 Error setFlowControl(Flow flow);
00348
00354 void toggleDTR(timeout_t millisec);
00355
00359 void sendBreak(void);
00360
00367 inline Error getErrorNumber(void)
00368 {return errid;};
00369
00376 inline char *getErrorString(void)
00377 {return errstr;};
00378
00386 inline int getBufferSize(void)
00387 {return bufsize;};
00388
00398 virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
00399 };
00400
00422 class __EXPORT TTYStream : protected std::streambuf, public Serial, public std::iostream
00423 {
00424 private:
00425 int doallocate();
00426
00427 friend TTYStream& crlf(TTYStream&);
00428 friend TTYStream& lfcr(TTYStream&);
00429
00430 protected:
00431 char *gbuf, *pbuf;
00432 timeout_t timeout;
00433
00438 TTYStream();
00439
00444 void allocate(void);
00445
00450 void endStream(void);
00451
00458 int underflow(void);
00459
00468 int uflow(void);
00469
00477 int overflow(int ch);
00478
00479 public:
00486 TTYStream(const char *filename, timeout_t to = 0);
00487
00491 virtual ~TTYStream();
00492
00498 inline void setTimeout(timeout_t to)
00499 {timeout = to;};
00500
00508 void interactive(bool flag);
00509
00516 int sync(void);
00517
00529 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
00530 };
00531
00541 class __EXPORT ttystream : public TTYStream
00542 {
00543 public:
00547 ttystream();
00548
00556 ttystream(const char *name);
00557
00563 void open(const char *name);
00564
00568 void close(void);
00569
00573 inline bool operator!()
00574 {return (dev < 0);};
00575 };
00576
00587 class __EXPORT TTYSession : public Thread, public TTYStream
00588 {
00589 public:
00597 TTYSession(const char *name, int pri = 0, int stack = 0);
00598
00599 virtual ~TTYSession();
00600 };
00601
00602 #ifndef WIN32
00603
00604
00605
00606 class __EXPORT SerialPort;
00607 class __EXPORT SerialService;
00608
00630 class __EXPORT SerialPort: public Serial, public TimerPort
00631 {
00632 private:
00633 SerialPort *next, *prev;
00634 SerialService *service;
00635 #ifdef USE_POLL
00636 struct pollfd *ufd;
00637 #endif
00638 bool detect_pending;
00639 bool detect_output;
00640 bool detect_disconnect;
00641
00642 friend class SerialService;
00643
00644 protected:
00651 SerialPort(SerialService *svc, const char *name);
00652
00657 virtual ~SerialPort();
00658
00663 void setDetectPending( bool );
00664
00668 inline bool getDetectPending( void ) const
00669 { return detect_pending; }
00670
00675 void setDetectOutput( bool );
00676
00680 inline bool getDetectOutput( void ) const
00681 { return detect_output; }
00682
00687 virtual void expired(void);
00688
00694 virtual void pending(void);
00695
00700 virtual void disconnect(void);
00701
00711 inline int output(void *buf, int len)
00712 {return aWrite((char *)buf, len);};
00713
00717 virtual void output(void);
00718
00728 inline int input(void *buf, int len)
00729 {return aRead((char *)buf, len);};
00730 public:
00738 void setTimer(timeout_t timeout = 0);
00739
00745 void incTimer(timeout_t timeout);
00746 };
00747
00770 class __EXPORT SerialService : public Thread, private Mutex
00771 {
00772 private:
00773 fd_set connect;
00774 int iosync[2];
00775 int hiwater;
00776 int count;
00777 SerialPort *first, *last;
00778
00784 void attach(SerialPort *port);
00785
00791 void detach(SerialPort *port);
00792
00796 void run(void);
00797
00798 friend class SerialPort;
00799
00800 protected:
00807 virtual void onUpdate(unsigned char flag);
00808
00813 virtual void onEvent(void);
00814
00821 virtual void onCallback(SerialPort *port);
00822
00823 public:
00833 void update(unsigned char flag = 0xff);
00834
00843 SerialService(int pri = 0, size_t stack = 0, const char *id = NULL);
00844
00848 virtual ~SerialService();
00849
00856 inline int getCount(void)
00857 {return count;};
00858 };
00859
00860 #endif
00861
00862
00863
00864 #ifdef COMMON_STD_EXCEPTION
00865 class __EXPORT SerException : public IOException
00866 {
00867 public:
00868 SerException(const String &str) : IOException(str) {};
00869 };
00870 #endif
00871
00872 #ifdef CCXX_NAMESPACES
00873 }
00874 #endif
00875
00876 #endif
00877