UCommon
serial.h
Go to the documentation of this file.
1 // Copyright (C) 1999-2005 Open Source Telecom Corporation.
2 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
3 // Copyright (C) 2015 Cherokees of Idaho.
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free software
19 // library without restriction. Specifically, if other files instantiate
20 // templates or use macros or inline functions from this file, or you compile
21 // this file and link it with other files to produce an executable, this
22 // file does not by itself cause the resulting executable to be covered by
23 // the GNU General Public License. This exception does not however
24 // invalidate any other reasons why the executable file might be covered by
25 // the GNU General Public License.
26 //
27 // This exception applies only to the code released under the name GNU
28 // Common C++. If you copy code from other releases into a copy of GNU
29 // Common C++, as the General Public License permits, the exception does
30 // not apply to the code that you add in this way. To avoid misleading
31 // anyone as to the status of such modified files, you must delete
32 // this exception notice from them.
33 //
34 // If you write modifications of your own for GNU Common C++, it is your choice
35 // whether to permit this exception to apply to your modifications.
36 // If you do not wish that, delete this exception notice.
37 //
38 
44 #ifndef COMMONCPP_SERIAL_H_
45 #define COMMONCPP_SERIAL_H_
46 
47 #ifndef COMMONCPP_CONFIG_H_
48 #include <commoncpp/config.h>
49 #endif
50 
51 #ifndef COMMONCPP_THREAD_H_
52 #include <commoncpp/thread.h>
53 #endif
54 
55 #ifndef COMMMONCPP_EXCEPTION_H_
56 #include <commoncpp/exception.h>
57 #endif
58 
59 namespace ost {
60 
91 class __EXPORT Serial
92 {
93 public:
94  enum Error {
95  errSuccess = 0,
96  errOpenNoTty,
97  errOpenFailed,
98  errSpeedInvalid,
99  errFlowInvalid,
100  errParityInvalid,
101  errCharsizeInvalid,
102  errStopbitsInvalid,
103  errOptionInvalid,
104  errResourceFailure,
105  errOutput,
106  errInput,
107  errTimeout,
108  errExtended
109  };
110  typedef enum Error Error;
111 
112  enum Flow {
113  flowNone,
114  flowSoft,
115  flowHard,
116  flowBoth
117  };
118  typedef enum Flow Flow;
119 
120  enum Parity {
121  parityNone,
122  parityOdd,
123  parityEven
124  };
125  typedef enum Parity Parity;
126 
127  enum Pending {
128  pendingInput,
129  pendingOutput,
130  pendingError
131  };
132  typedef enum Pending Pending;
133 
134 private:
135  Error errid;
136  char *errstr;
137 
138  struct {
139  bool thrown: 1;
140  bool linebuf: 1;
141  } flags;
142 
143  void *original;
144  void *current;
145 
149  void initSerial(void);
150 
151 protected:
152  fd_t dev;
153  int bufsize;
154 
160  void open(const char *fname);
161 
166  void close(void);
167 
175  virtual int aRead(char * Data, const int Length);
176 
183  virtual int aWrite(const char * Data, const int Length);
184 
192  Error error(Error error, char *errstr = NULL);
193 
200  inline void error(char *err) {
201  error(errExtended, err);
202  }
203 
204 
211  inline void setError(bool enable) {
212  flags.thrown = !enable;
213  }
214 
225  int setPacketInput(int size, uint8_t btimer = 0);
226 
236  int setLineInput(char newline = 13, char nl1 = 0);
237 
241  void restore(void);
242 
246  void flushInput(void);
247 
251  void flushOutput(void);
252 
256  void waitOutput(void);
257 
262  void endSerial(void);
263 
269  void initConfig(void);
270 
275  Serial() {
276  initSerial();
277  }
278 
285  Serial(const char *name);
286 
287 
288 public:
289 
296  virtual ~Serial();
297 
302  Serial &operator=(const Serial &from);
303 
310  Error setSpeed(unsigned long speed);
311 
318  Error setCharBits(int bits);
319 
326  Error setParity(Parity parity);
327 
334  Error setStopBits(int bits);
335 
342  Error setFlowControl(Flow flow);
343 
349  void toggleDTR(timeout_t millisec);
350 
354  void sendBreak(void);
355 
362  inline Error getErrorNumber(void) const {
363  return errid;
364  }
365 
372  inline char *getErrorString(void) const {
373  return errstr;
374  }
375 
383  inline int getBufferSize(void) const {
384  return bufsize;
385  }
386 
396  virtual bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF);
397 };
398 
420 class __EXPORT TTYStream : protected std::streambuf, public Serial, public std::iostream
421 {
422 private:
423  int doallocate();
424 
425  friend TTYStream& crlf(TTYStream&);
426  friend TTYStream& lfcr(TTYStream&);
427 
428  __DELETE_COPY(TTYStream);
429 
430 protected:
431  char *gbuf, *pbuf;
432  timeout_t timeout;
433 
439 
444  void allocate(void);
445 
450  void endStream(void);
451 
458  int underflow(void) __OVERRIDE;
459 
468  int uflow(void) __OVERRIDE;
469 
477  int overflow(int ch) __OVERRIDE;
478 
479 public:
486  TTYStream(const char *filename, timeout_t to = 0);
487 
491  virtual ~TTYStream();
492 
498  inline void setTimeout(timeout_t to) {
499  timeout = to;
500  }
501 
509  void interactive(bool flag);
510 
517  int sync(void);
518 
530  bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF) __OVERRIDE;
531 };
532 
542 class __EXPORT ttystream : public TTYStream
543 {
544 private:
545  __DELETE_COPY(ttystream);
546 
547 public:
552 
560  ttystream(const char *name);
561 
567  void open(const char *name);
568 
572  void close(void);
573 
577  inline bool operator!() {
578  return (dev < 0);
579  }
580 };
581 
592 class __EXPORT TTYSession : public Thread, public TTYStream
593 {
594 private:
595  __DELETE_COPY(TTYSession);
596 
597 public:
605  TTYSession(const char *name, int pri = 0, int stack = 0);
606 
607  virtual ~TTYSession();
608 };
609 
610 #ifndef _MSWINDOWS_
611 
612 // Not support this right now.......
613 //
614 class SerialPort;
615 class SerialService;
616 
638 class __EXPORT SerialPort: public Serial, public TimerPort
639 {
640 private:
641  SerialPort *next, *prev;
642  SerialService *service;
643 #ifdef USE_POLL
644  struct pollfd *ufd;
645 #endif
646  bool detect_pending;
647  bool detect_output;
648  bool detect_disconnect;
649 
650  friend class SerialService;
651 
652  __DELETE_COPY(SerialPort);
653 
654 protected:
661  SerialPort(SerialService *svc, const char *name);
662 
667  virtual ~SerialPort();
668 
673  void setDetectPending( bool );
674 
678  inline bool getDetectPending( void ) const {
679  return detect_pending;
680  }
681 
686  void setDetectOutput( bool );
687 
691  inline bool getDetectOutput( void ) const {
692  return detect_output;
693  }
694 
699  virtual void expired(void);
700 
706  virtual void pending(void);
707 
712  virtual void disconnect(void);
713 
723  inline int output(void *buf, int len) {
724  return aWrite((char *)buf, len);
725  }
726 
730  virtual void output(void);
731 
741  inline int input(void *buf, int len) {
742  return aRead((char *)buf, len);
743  }
744 
745 public:
753  void setTimer(timeout_t timeout = 0);
754 
760  void incTimer(timeout_t timeout);
761 };
762 
785 class __EXPORT SerialService : public Thread, private Mutex
786 {
787 private:
788  fd_set connect;
789  int iosync[2];
790  int hiwater;
791  int count;
792  SerialPort *first, *last;
793 
794  __DELETE_COPY(SerialService);
795 
801  void attach(SerialPort *port);
802 
808  void detach(SerialPort *port);
809 
813  void run(void) __OVERRIDE;
814 
815  friend class SerialPort;
816 
817 protected:
824  virtual void onUpdate(uint8_t flag);
825 
830  virtual void onEvent(void);
831 
838  virtual void onCallback(SerialPort *port);
839 
840 public:
850  void update(uint8_t flag = 0xff);
851 
860  SerialService(int pri = 0, size_t stack = 0, const char *id = NULL);
861 
865  virtual ~SerialService();
866 
873  inline int getCount(void) const {
874  return count;
875  }
876 };
877 
878 #endif
879 
880 #ifdef CCXX_EXCEPTIONS
881 class __EXPORT SerException : public IOException
882 {
883 public:
884  SerException(const String &str) : IOException(str) {}
885 };
886 #endif
887 
888 } // namespace ost
889 
890 #endif
AppLog & error(AppLog &sl)
Manipulator for error level.
Definition: applog.h:536
GNU Common C++ exception model base classes.
The Serial class is used as the base for all serial I/O services under APE.
Definition: serial.h:92
void restore(void)
Restore serial device to the original settings at time of open.
virtual int aWrite(const char *Data, const int Length)
Writes to serial device.
Serial & operator=(const Serial &from)
Serial ports may also be duplecated by the assignment operator.
void flushInput(void)
Used to flush the input waiting queue.
void setError(bool enable)
This method is used to turn the error handler on or off for "throwing" execptions by manipulating the...
Definition: serial.h:211
Error error(Error error, char *errstr=NULL)
This service is used to throw all serial errors which usually occur during the serial constructor.
Serial()
This allows later ttystream class to open and close a serial device.
Definition: serial.h:275
void toggleDTR(timeout_t millisec)
Set the DTR mode off momentarily.
Error setParity(Parity parity)
Set parity mode.
Error setFlowControl(Flow flow)
Set flow control.
void initConfig(void)
Used to initialize a newly opened serial file handle.
virtual bool isPending(Pending pend, timeout_t timeout=ucommon::Timer::inf)
Get the status of pending operations.
int setLineInput(char newline=13, char nl1=0)
Set "line buffering" read mode and specifies the newline character to be used in seperating line reco...
void error(char *err)
This service is used to thow application defined serial errors where the application specific error c...
Definition: serial.h:200
virtual ~Serial()
The serial base class may be "thrown" as a result on an error, and the "catcher" may then choose to d...
virtual int aRead(char *Data, const int Length)
Reads from serial device.
void open(const char *fname)
Opens the serial device.
Serial(const char *name)
A serial object may be constructed from a named file on the file system.
void close(void)
Closes the serial device.
Error setSpeed(unsigned long speed)
Set serial port speed for both input and output.
int getBufferSize(void) const
Get the "buffer" size for buffered operations.
Definition: serial.h:383
void flushOutput(void)
Used to flush any pending output data.
int setPacketInput(int size, uint8_t btimer=0)
Set packet read mode and "size" of packet read buffer.
void waitOutput(void)
Used to wait until all output has been sent.
Error setCharBits(int bits)
Set character size.
void sendBreak(void)
Send the "break" signal.
Error setStopBits(int bits)
Set number of stop bits.
void endSerial(void)
Used as the default destructor for ending serial I/O services.
char * getErrorString(void) const
Often used by a "catch" to fetch the user set error string of a thrown serial.
Definition: serial.h:372
Error getErrorNumber(void) const
Often used by a "catch" to fetch the last error of a thrown serial.
Definition: serial.h:362
TTY streams are used to represent serial connections that are fully "streamable" objects using C++ st...
Definition: serial.h:421
void interactive(bool flag)
Set tty mode to buffered or "interactive".
void setTimeout(timeout_t to)
Set the timeout control.
Definition: serial.h:498
int uflow(void)
This streambuf method is used for doing unbuffered reads through the establish tty serial port when i...
bool isPending(Pending pend, timeout_t timeout=ucommon::Timer::inf)
Get the status of pending operations.
void allocate(void)
Used to allocate the buffer space needed for iostream operations.
TTYStream(const char *filename, timeout_t to=0)
Create and open a tty serial port.
TTYStream()
This constructor is used to derive "ttystream", a more C++ style version of the TTYStream class.
int underflow(void)
This streambuf method is used to load the input buffer through the established tty serial port.
int overflow(int ch)
This streambuf method is used to write the output buffer through the established tty port.
void endStream(void)
Used to terminate the buffer space and clean up the tty connection.
virtual ~TTYStream()
End the tty stream and cleanup.
int sync(void)
Flushes the stream input and out buffers, writes pending output.
A more natural C++ "ttystream" class for use by non-threaded applications.
Definition: serial.h:543
ttystream(const char *name)
Construct and "open" a tty stream object.
void close(void)
Close method for a tty stream.
bool operator!()
Test to see if stream is opened.
Definition: serial.h:577
void open(const char *name)
Open method for a tty stream.
ttystream()
Construct an unopened "ttystream" object.
The TTYSession aggragates a TTYStream and a Common C++ Thread which is assumed to be the execution co...
Definition: serial.h:593
TTYSession(const char *name, int pri=0, int stack=0)
Create TTY stream that will be managed by it's own thread.
The serial port is an internal class which is attached to and then serviced by a specified SerialServ...
Definition: serial.h:639
virtual ~SerialPort()
Disconnect the Serial Port from the service pool thread and shutdown the port.
void setDetectOutput(bool)
Used to indicate if output ready monitoring should be performed by the service thread.
int output(void *buf, int len)
Transmit "send" data to the serial port.
Definition: serial.h:723
bool getDetectOutput(void) const
Get the current state of the DetectOutput flag.
Definition: serial.h:691
virtual void pending(void)
Called by the service thread when input data is pending for this tty port.
void incTimer(timeout_t timeout)
Derived incTimer to notify the service thread pool of a change in expected timeout.
virtual void expired(void)
Called by the service thread when the objects timer has expired.
SerialPort(SerialService *svc, const char *name)
Construct a tty serial port for a named serial device.
void setDetectPending(bool)
Used to indicate if the service thread should monitor pending data for us.
virtual void disconnect(void)
Called by the service thread when an exception has occured such as a hangup.
bool getDetectPending(void) const
Get the current state of the DetectPending flag.
Definition: serial.h:678
void setTimer(timeout_t timeout=0)
Derived setTimer to notify the service thread pool of changes in expected timeout.
int input(void *buf, int len)
Receive "input" for pending data from the serial port.
Definition: serial.h:741
virtual void output(void)
Perform when output is available for sending data.
The SerialService is a thead service object that is meant to service attached serial ports.
Definition: serial.h:786
virtual void onUpdate(uint8_t flag)
A virtual handler for processing user defined update requests (1-254) which have been posted through ...
virtual ~SerialService()
Terminate the service thread and update attached objects.
int getCount(void) const
Get current reference count.
Definition: serial.h:873
virtual void onEvent(void)
A virtual handler for event loop calls.
SerialService(int pri=0, size_t stack=0, const char *id=NULL)
Create a service thread for attaching serial ports.
void update(uint8_t flag=0xff)
Notify service thread that a port has been added or removed, or a timer changed, so that a new schedu...
virtual void onCallback(SerialPort *port)
A virtual handler for adding support for additional callback events into SerialPort.
Timer ports are used to provide synchronized timing events when managed under a "service thread" such...
Definition: thread.h:563
Common C++ thread class and sychronization objects.