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_THREAD_H__
00045 #include <cc++/thread.h>
00046 #else
00047 #ifdef __CCXX_NAMESPACE_H__
00048 #include <cc++/macros.h>
00049 #endif
00050 #endif
00051
00052 #include <iostream>
00053
00054 typedef enum
00055 {
00056 SERIAL_SUCCESS = 0,
00057 SERIAL_OPEN_NOTTY,
00058 SERIAL_OPEN_FAILED,
00059 SERIAL_SPEED_INVALID,
00060 SERIAL_FLOW_INVALID,
00061 SERIAL_PARITY_INVALID,
00062 SERIAL_CHARSIZE_INVALID,
00063 SERIAL_STOPBITS_INVALID,
00064 SERIAL_OPTION_INVALID,
00065 SERIAL_RESOURCE_FAILURE,
00066 SERIAL_OUTPUT_ERROR,
00067 SERIAL_INPUT_ERROR,
00068 SERIAL_TIMEOUT_ERROR,
00069 SERIAL_EXTENDED_ERROR
00070 } sioerror_t;
00071
00072 typedef enum
00073 {
00074 SERIAL_FLOW_NONE,
00075 SERIAL_FLOW_SOFT,
00076 SERIAL_FLOW_HARD,
00077 SERIAL_FLOW_BOTH
00078 } sioflow_t;
00079
00080 typedef enum
00081 {
00082 SERIAL_PARITY_NONE,
00083 SERIAL_PARITY_ODD,
00084 SERIAL_PARITY_EVEN
00085 } sioparity_t;
00086
00087 typedef enum
00088 {
00089 SERIAL_PENDING_INPUT,
00090 SERIAL_PENDING_OUTPUT,
00091 SERIAL_PENDING_ERROR
00092 } siopend_t;
00093
00125 class Serial
00126 {
00127 private:
00128 sioerror_t errid;
00129 char *errstr;
00130
00131 struct
00132 {
00133 bool thrown: 1;
00134 bool linebuf: 1;
00135 } flags;
00136
00137 void *original, *current;
00138
00142 void initSerial(void);
00143
00144 protected:
00145 int dev;
00146 int bufsize;
00147
00155 sioerror_t Error(sioerror_t error, char *errstr = NULL);
00156
00163 inline void Error(char *errstr)
00164 {Error(SERIAL_EXTENDED_ERROR, errstr);};
00165
00166
00173 inline void setError(bool enable)
00174 {flags.thrown = !enable;};
00175
00186 int setPacketInput(int size, unsigned char btimer = 0);
00187
00196 int setLineInput(char newline = 13, char nl1 = 0);
00197
00201 void Restore(void);
00202
00206 void flushInput(void);
00207
00211 void flushOutput(void);
00212
00216 void waitOutput(void);
00217
00222 void endSerial(void);
00223
00229 void initConfig(void);
00230
00237 Serial(const char *name);
00238
00243 Serial()
00244 {initSerial();};
00245
00246 public:
00253 virtual ~Serial()
00254 {endSerial();};
00255
00260 Serial &operator=(const Serial &from);
00261
00268 sioerror_t setSpeed(unsigned long speed);
00269
00276 sioerror_t setCharBits(int bits);
00277
00284 sioerror_t setParity(sioparity_t parity);
00285
00292 sioerror_t setStopBits(int bits);
00293
00300 sioerror_t setFlowControl(sioflow_t flow);
00301
00307 void toggleDTR(timeout_t millisec);
00308
00312 void sendBreak(void);
00313
00320 inline sioerror_t getErrorNumber(void)
00321 {return errid;};
00322
00329 inline char *getErrorString(void)
00330 {return errstr;};
00331
00339 inline int getBufferSize(void)
00340 {return bufsize;};
00341
00351 virtual bool isPending(siopend_t pend, timeout_t timeout = TIMEOUT_INF);
00352 };
00353
00376 #if defined(STLPORT) || defined(__KCC)
00377 #define iostream iostream_withassign
00378 #endif
00379 class TTYStream : public std::streambuf, public std::iostream, public
00380 Serial
00381 {
00382 private:
00383 int doallocate();
00384
00385 friend TTYStream& crlf(TTYStream&);
00386 friend TTYStream& lfcr(TTYStream&);
00387
00388 protected:
00389 char *gbuf, *pbuf;
00390 timeout_t timeout;
00391
00396 TTYStream();
00397
00402 void Allocate(void);
00403
00408 void endStream(void);
00409
00416 int underflow(void);
00417
00426 int uflow(void);
00427
00435 int overflow(int ch);
00436
00437 public:
00443 TTYStream(const char *filename);
00444
00448 ~TTYStream();
00449
00455 inline void setTimeout(timeout_t to)
00456 {timeout = to;};
00457
00465 void Interactive(bool flag);
00466
00473 int sync(void);
00474
00486 bool isPending(siopend_t pend, timeout_t timeout = TIMEOUT_INF);
00487 };
00488
00498 class ttystream : public TTYStream
00499 {
00500 public:
00504 ttystream();
00505
00513 ttystream(const char *name);
00514
00520 void open(const char *name);
00521
00525 void close(void);
00526
00530 inline bool operator!()
00531 {return (dev < 0);};
00532 };
00533
00544 class TTYSession : public TTYStream, public Thread
00545 {
00546 public:
00555 TTYSession(const char *name, Semaphore *start = NULL, int pri = 0, int stack = 0);
00556 };
00557
00558 class SerialPort;
00559 class SerialService;
00560
00582 class SerialPort: public Serial, public TimerPort
00583 {
00584 private:
00585 SerialPort *next, *prev;
00586 SerialService *service;
00587 #ifdef __CCXX_USE_POLL
00588 struct pollfd *ufd;
00589 #endif
00590 bool detect_pending;
00591 bool detect_output;
00592 bool detect_disconnect;
00593
00594 friend class SerialService;
00595
00596 protected:
00603 SerialPort(SerialService *svc, const char *name);
00604
00609 virtual ~SerialPort();
00610
00615 void setDetectPending( bool );
00616
00620 bool getDetectPending( void ) const
00621 { return detect_pending; }
00622
00627 void setDetectOutput( bool );
00628
00632 bool getDetectOutput( void ) const
00633 { return detect_output; }
00634
00639 virtual void Expired(void)
00640 {return;};
00641
00647 virtual void Pending(void)
00648 {return;};
00649
00654 virtual void Disconnect(void)
00655 {return;};
00656
00666 inline int Output(void *buf, int len)
00667 {return ::write(dev, (char *)buf, len);};
00668
00672 virtual void Output(void)
00673 {return;};
00674
00684 inline int Input(void *buf, int len)
00685 {return ::read(dev, (char *)buf, len);};
00686
00687 public:
00695 void setTimer(timeout_t timeout = 0);
00696
00702 void incTimer(timeout_t timeout);
00703 };
00704
00727 class SerialService : public Thread, private Mutex
00728 {
00729 private:
00730 fd_set connect;
00731 int iosync[2];
00732 int hiwater;
00733 int count;
00734 SerialPort *first, *last;
00735
00741 void Attach(SerialPort *port);
00742
00748 void Detach(SerialPort *port);
00749
00753 void Run(void);
00754
00755 friend class SerialPort;
00756
00757 protected:
00764 virtual void OnUpdate(unsigned char flag)
00765 {return;};
00766
00771 virtual void OnEvent(void)
00772 {return;};
00773
00780 virtual void OnCallback(SerialPort *port)
00781 {return;};
00782
00783 public:
00793 void Update(unsigned char flag = 0xff);
00794
00801 SerialService(int pri = 0);
00802
00806 ~SerialService();
00807
00814 inline int getCount(void)
00815 {return count;};
00816 };
00817
00818 #ifdef __CCXX_NAMESPACE_H__
00819 #undef __CCXX_NAMESPACE_H__
00820 #include <cc++/namespace.h>
00821 #endif
00822 #endif
00823