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
00041 #ifndef __CCXX_SERIAL_H__
00042 #define __CCXX_SERIAL_H__
00043
00044 #ifndef __CCXX_CONFIG_H__
00045 #include <cc++/config.h>
00046 #endif
00047
00048 #ifndef __CCXX_THREAD_H__
00049 #include <cc++/thread.h>
00050 #endif
00051
00052 #include <iostream>
00053
00054 #ifdef __NAMESPACES__
00055 namespace ost {
00056 #endif
00057
00058 enum sioerror_t
00059 {
00060 SERIAL_SUCCESS = 0,
00061 SERIAL_OPEN_NOTTY,
00062 SERIAL_OPEN_FAILED,
00063 SERIAL_SPEED_INVALID,
00064 SERIAL_FLOW_INVALID,
00065 SERIAL_PARITY_INVALID,
00066 SERIAL_CHARSIZE_INVALID,
00067 SERIAL_STOPBITS_INVALID,
00068 SERIAL_OPTION_INVALID,
00069 SERIAL_RESOURCE_FAILURE,
00070 SERIAL_OUTPUT_ERROR,
00071 SERIAL_INPUT_ERROR,
00072 SERIAL_TIMEOUT_ERROR,
00073 SERIAL_EXTENDED_ERROR
00074 };
00075 typedef enum sioerror_t sioerror_t;
00076
00077 enum sioflow_t
00078 {
00079 SERIAL_FLOW_NONE,
00080 SERIAL_FLOW_SOFT,
00081 SERIAL_FLOW_HARD,
00082 SERIAL_FLOW_BOTH
00083 };
00084 typedef enum sioflow_t sioflow_t;
00085
00086 enum sioparity_t
00087 {
00088 SERIAL_PARITY_NONE,
00089 SERIAL_PARITY_ODD,
00090 SERIAL_PARITY_EVEN
00091 };
00092 typedef enum sioparity_t sioparity_t;
00093
00094 enum siopend_t
00095 {
00096 SERIAL_PENDING_INPUT,
00097 SERIAL_PENDING_OUTPUT,
00098 SERIAL_PENDING_ERROR
00099 };
00100 typedef enum siopend_t siopend_t;
00101
00133 class Serial
00134 {
00135 private:
00136 sioerror_t errid;
00137 char *errstr;
00138
00139 struct
00140 {
00141 bool thrown: 1;
00142 bool linebuf: 1;
00143 } flags;
00144
00145 void *original, *current;
00146
00150 void initSerial(void);
00151
00152 protected:
00153 int dev;
00154 int bufsize;
00155
00163 sioerror_t Error(sioerror_t error, char *errstr = NULL);
00164
00171 inline void Error(char *errstr)
00172 {Error(SERIAL_EXTENDED_ERROR, errstr);};
00173
00174
00181 inline void setError(bool enable)
00182 {flags.thrown = !enable;};
00183
00194 int setPacketInput(int size, unsigned char btimer = 0);
00195
00204 int setLineInput(char newline = 13, char nl1 = 0);
00205
00209 void Restore(void);
00210
00214 void flushInput(void);
00215
00219 void flushOutput(void);
00220
00224 void waitOutput(void);
00225
00230 void endSerial(void);
00231
00237 void initConfig(void);
00238
00245 Serial(const char *name);
00246
00251 Serial()
00252 {initSerial();};
00253
00254 public:
00261 virtual ~Serial()
00262 {endSerial();};
00263
00268 Serial &operator=(const Serial &from);
00269
00276 sioerror_t setSpeed(unsigned long speed);
00277
00284 sioerror_t setCharBits(int bits);
00285
00292 sioerror_t setParity(sioparity_t parity);
00293
00300 sioerror_t setStopBits(int bits);
00301
00308 sioerror_t setFlowControl(sioflow_t flow);
00309
00315 void toggleDTR(timeout_t millisec);
00316
00320 void sendBreak(void);
00321
00328 inline sioerror_t getErrorNumber(void)
00329 {return errid;};
00330
00337 inline char *getErrorString(void)
00338 {return errstr;};
00339
00347 inline int getBufferSize(void)
00348 {return bufsize;};
00349
00359 virtual bool isPending(siopend_t pend, timeout_t timeout = TIMEOUT_INF);
00360 };
00361
00384 #if defined(STLPORT) || defined(__KCC)
00385 #define iostream iostream_withassign
00386 #endif
00387 class TTYStream : public std::streambuf, public std::iostream, public
00388 Serial
00389 {
00390 private:
00391 int doallocate();
00392
00393 friend TTYStream& crlf(TTYStream&);
00394 friend TTYStream& lfcr(TTYStream&);
00395
00396 protected:
00397 char *gbuf, *pbuf;
00398 timeout_t timeout;
00399
00404 TTYStream();
00405
00410 void Allocate(void);
00411
00416 void endStream(void);
00417
00424 int underflow(void);
00425
00434 int uflow(void);
00435
00443 int overflow(int ch);
00444
00445 public:
00451 TTYStream(const char *filename);
00452
00456 virtual ~TTYStream();
00457
00463 inline void setTimeout(timeout_t to)
00464 {timeout = to;};
00465
00473 void Interactive(bool flag);
00474
00481 int sync(void);
00482
00494 bool isPending(siopend_t pend, timeout_t timeout = TIMEOUT_INF);
00495 };
00496
00506 class ttystream : public TTYStream
00507 {
00508 public:
00512 ttystream();
00513
00521 ttystream(const char *name);
00522
00528 void open(const char *name);
00529
00533 void close(void);
00534
00538 inline bool operator!()
00539 {return (dev < 0);};
00540 };
00541
00552 class TTYSession : public TTYStream, public Thread
00553 {
00554 public:
00562 TTYSession(const char *name, int pri = 0, int stack = 0);
00563 };
00564
00565 class SerialPort;
00566 class SerialService;
00567
00589 class SerialPort: public Serial, public TimerPort
00590 {
00591 private:
00592 SerialPort *next, *prev;
00593 SerialService *service;
00594 #ifdef __CCXX_USE_POLL
00595 struct pollfd *ufd;
00596 #endif
00597 bool detect_pending;
00598 bool detect_output;
00599 bool detect_disconnect;
00600
00601 friend class SerialService;
00602
00603 protected:
00610 SerialPort(SerialService *svc, const char *name);
00611
00616 virtual ~SerialPort();
00617
00622 void setDetectPending( bool );
00623
00627 bool getDetectPending( void ) const
00628 { return detect_pending; }
00629
00634 void setDetectOutput( bool );
00635
00639 bool getDetectOutput( void ) const
00640 { return detect_output; }
00641
00646 virtual void Expired(void)
00647 {return;};
00648
00654 virtual void Pending(void)
00655 {return;};
00656
00661 virtual void Disconnect(void)
00662 {return;};
00663
00673 inline int Output(void *buf, int len)
00674 {return ::write(dev, (char *)buf, len);};
00675
00679 virtual void Output(void)
00680 {return;};
00681
00691 inline int Input(void *buf, int len)
00692 {return ::read(dev, (char *)buf, len);};
00693
00694 public:
00702 void setTimer(timeout_t timeout = 0);
00703
00709 void incTimer(timeout_t timeout);
00710 };
00711
00734 class SerialService : public Thread, private Mutex
00735 {
00736 private:
00737 fd_set connect;
00738 int iosync[2];
00739 int hiwater;
00740 int count;
00741 SerialPort *first, *last;
00742
00748 void Attach(SerialPort *port);
00749
00755 void Detach(SerialPort *port);
00756
00760 void Run(void);
00761
00762 friend class SerialPort;
00763
00764 protected:
00771 virtual void OnUpdate(unsigned char flag)
00772 {return;};
00773
00778 virtual void OnEvent(void)
00779 {return;};
00780
00787 virtual void OnCallback(SerialPort *port)
00788 {return;};
00789
00790 public:
00800 void Update(unsigned char flag = 0xff);
00801
00808 SerialService(int pri = 0);
00809
00813 virtual ~SerialService();
00814
00821 inline int getCount(void)
00822 {return count;};
00823 };
00824
00825 #ifdef COMMON_STD_EXCEPTION
00826 class SerException : public IOException
00827 {
00828 public:
00829 SerException(std::string str) : IOException(str) {};
00830 };
00831 #endif
00832
00833 #ifdef __NAMESPACES__
00834 };
00835 #endif
00836
00837 #endif
00838