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
00039
00040
00046 #ifndef CCXX_SERIAL_H_
00047 #define CCXX_SERIAL_H_
00048
00049 #ifndef CCXX_CONFIG_H_
00050 #include <cc++/config.h>
00051 #endif
00052
00053 #ifndef CCXX_THREAD_H_
00054 #include <cc++/thread.h>
00055 #endif
00056
00057 #include <iostream>
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
00068
00069 class CCXX_CLASS_EXPORT Serial;
00070 class CCXX_CLASS_EXPORT TTYStream;
00071 class CCXX_CLASS_EXPORT ttystream;
00104 class CCXX_CLASS_EXPORT Serial
00105 {
00106 public:
00107 enum Error
00108 {
00109 errSuccess = 0,
00110 errOpenNoTty,
00111 errOpenFailed,
00112 errSpeedInvalid,
00113 errFlowInvalid,
00114 errParityInvalid,
00115 errCharsizeInvalid,
00116 errStopbitsInvalid,
00117 errOptionInvalid,
00118 errResourceFailure,
00119 errOutput,
00120 errInput,
00121 errTimeout,
00122 errExtended
00123 };
00124 typedef enum Error Error;
00125
00126 enum Flow
00127 {
00128 flowNone,
00129 flowSoft,
00130 flowHard,
00131 flowBoth
00132 };
00133 typedef enum Flow Flow;
00134
00135 enum Parity
00136 {
00137 parityNone,
00138 parityOdd,
00139 parityEven
00140 };
00141 typedef enum Parity Parity;
00142
00143 enum Pending
00144 {
00145 pendingInput,
00146 pendingOutput,
00147 pendingError
00148 };
00149 typedef enum Pending Pending;
00150
00151 private:
00152 Error errid;
00153 char *errstr;
00154
00155 struct
00156 {
00157 bool thrown: 1;
00158 bool linebuf: 1;
00159 } flags;
00160
00161 void * original;
00162 void * current;
00163
00167 void initSerial(void);
00168
00169 protected:
00170
00171 HANDLE dev;
00172
00173 int bufsize;
00174
00180 void open(const char *fname);
00181
00186 void close(void);
00187
00195 virtual int aRead(char * Data, const int Length);
00196
00203 virtual int aWrite(const char * Data, const int Length);
00204
00212 Error error(Error error, char *errstr = NULL);
00213
00220 inline void error(char *errstr)
00221 {error(errExtended, errstr);};
00222
00223
00230 inline void setError(bool enable)
00231 {flags.thrown = !enable;};
00232
00243 int setPacketInput(int size, unsigned char btimer = 0);
00244
00254 int setLineInput(char newline = 13, char nl1 = 0);
00255
00259 void restore(void);
00260
00264 void flushInput(void);
00265
00269 void flushOutput(void);
00270
00274 void waitOutput(void);
00275
00280 void endSerial(void);
00281
00287 void initConfig(void);
00288
00293 Serial()
00294 {initSerial();};
00295
00302 Serial(const char *name);
00303
00304
00305 public:
00306
00313 virtual ~Serial()
00314 {endSerial();};
00315
00320 Serial &operator=(const Serial &from);
00321
00328 Error setSpeed(unsigned long speed);
00329
00336 Error setCharBits(int bits);
00337
00344 Error setParity(Parity parity);
00345
00352 Error setStopBits(int bits);
00353
00360 Error setFlowControl(Flow flow);
00361
00367 void toggleDTR(timeout_t millisec);
00368
00372 void sendBreak(void);
00373
00380 inline Error getErrorNumber(void)
00381 {return errid;};
00382
00389 inline char *getErrorString(void)
00390 {return errstr;};
00391
00399 inline int getBufferSize(void)
00400 {return bufsize;};
00401
00411 virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
00412 };
00413
00436 #if defined(__KCC)
00437 #define iostream iostream_withassign
00438 #endif
00439 class CCXX_CLASS_EXPORT TTYStream : protected std::streambuf, public std::iostream, public Serial
00440 {
00441 private:
00442 int doallocate();
00443
00444 friend TTYStream& crlf(TTYStream&);
00445 friend TTYStream& lfcr(TTYStream&);
00446
00447 protected:
00448 char *gbuf, *pbuf;
00449 timeout_t timeout;
00450
00455 TTYStream();
00456
00461 void allocate(void);
00462
00467 void endStream(void);
00468
00475 int underflow(void);
00476
00485 int uflow(void);
00486
00494 int overflow(int ch);
00495
00496 public:
00503 TTYStream(const char *filename, timeout_t to = 0);
00504
00508 virtual ~TTYStream();
00509
00515 inline void setTimeout(timeout_t to)
00516 {timeout = to;};
00517
00525 void interactive(bool flag);
00526
00533 int sync(void);
00534
00546 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
00547 };
00548
00558 class CCXX_CLASS_EXPORT ttystream : public TTYStream
00559 {
00560 public:
00564 ttystream();
00565
00573 ttystream(const char *name);
00574
00580 void open(const char *name);
00581
00585 void close(void);
00586
00590 inline bool operator!()
00591 {return (dev < 0);};
00592 };
00593
00604 class CCXX_CLASS_EXPORT TTYSession : public TTYStream, public Thread
00605 {
00606 public:
00614 TTYSession(const char *name, int pri = 0, int stack = 0);
00615 };
00616
00617 #ifndef WIN32
00618
00619
00620
00621
00622 class SerialPort;
00623 class SerialService;
00624
00646 class SerialPort: public Serial, public TimerPort
00647 {
00648 private:
00649 SerialPort *next, *prev;
00650 SerialService *service;
00651 #ifdef CCXX_USE_POLL
00652 struct pollfd *ufd;
00653 #endif
00654 bool detect_pending;
00655 bool detect_output;
00656 bool detect_disconnect;
00657
00658 friend class SerialService;
00659
00660 protected:
00667 SerialPort(SerialService *svc, const char *name);
00668
00673 virtual ~SerialPort();
00674
00679 void setDetectPending( bool );
00680
00684 bool getDetectPending( void ) const
00685 { return detect_pending; }
00686
00691 void setDetectOutput( bool );
00692
00696 bool getDetectOutput( void ) const
00697 { return detect_output; }
00698
00703 virtual void expired(void)
00704 {return;};
00705
00711 virtual void pending(void)
00712 {return;};
00713
00718 virtual void disconnect(void)
00719 {return;};
00720
00730 inline int output(void *buf, int len)
00731 {return aWrite((char *)buf, len);};
00735 virtual void output(void)
00736 {return;};
00737
00747 inline int input(void *buf, int len)
00748 {return aRead((char *)buf, len);};
00749 public:
00757 void setTimer(timeout_t timeout = 0);
00758
00764 void incTimer(timeout_t timeout);
00765 };
00766
00789 class SerialService : public Thread, private Mutex
00790 {
00791 private:
00792 fd_set connect;
00793 int iosync[2];
00794 int hiwater;
00795 int count;
00796 SerialPort *first, *last;
00797
00803 void attach(SerialPort *port);
00804
00810 void detach(SerialPort *port);
00811
00815 void run(void);
00816
00817 friend class SerialPort;
00818
00819 protected:
00826 virtual void onUpdate(unsigned char flag)
00827 {return;};
00828
00833 virtual void onEvent(void)
00834 {return;};
00835
00842 virtual void onCallback(SerialPort *port)
00843 {return;};
00844
00845 public:
00855 void update(unsigned char flag = 0xff);
00856
00863 SerialService(int pri = 0);
00864
00868 virtual ~SerialService();
00869
00876 inline int getCount(void)
00877 {return count;};
00878 };
00879
00880 #endif
00881
00882
00883
00884 #ifdef COMMON_STD_EXCEPTION
00885 class SerException : public IOException
00886 {
00887 public:
00888 SerException(std::string str) : IOException(str) {};
00889 };
00890 #endif
00891
00892 #ifdef CCXX_NAMESPACES
00893 };
00894 #endif
00895
00896 #endif
00897