35#include <linux/serial.h>
81 if (!
fUrl.
Set(url,
"|baud=|break|cts|xon|noinit|",
"term", emsg))
return false;
84 if (
fUrl.
Path().substr(0,1) !=
"/") {
88 speed_t speed = B115200;
89 unsigned long nsbaud = 0;
93 if (baud==
"2400") speed = B2400;
94 if (baud==
"4800") speed = B4800;
95 if (baud==
"9600") speed = B9600;
96 if (baud==
"19200" || baud==
"19k") speed = B19200;
97 if (baud==
"38400" || baud==
"38k") speed = B38400;
98 if (baud==
"57600" || baud==
"57k") speed = B57600;
99 if (baud==
"115200" || baud==
"115k") speed = B115200;
100 if (baud==
"230400" || baud==
"230k") speed = B230400;
101 if (baud==
"460800" || baud==
"460k") speed = B460800;
102 if (baud==
"500000" || baud==
"500k") speed = B500000;
103 if (baud==
"921600" || baud==
"921k") speed = B921600;
104 if (baud==
"1000000" || baud==
"1000k" || baud==
"1M") speed = B1000000;
105 if (baud==
"1152000" || baud==
"1152k") speed = B1152000;
106 if (baud==
"1500000" || baud==
"1500k") speed = B1500000;
107 if (baud==
"2000000" || baud==
"2000k" || baud==
"2M") speed = B2000000;
108 if (baud==
"2500000" || baud==
"2500k") speed = B2500000;
109 if (baud==
"3000000" || baud==
"3000k" || baud==
"3M") speed = B3000000;
110 if (baud==
"3500000" || baud==
"3500k") speed = B3500000;
111 if (baud==
"4000000" || baud==
"4000k" || baud==
"4M") speed = B4000000;
115 if (baud==
"5000000" || baud==
"5000k" || baud==
"5M") nsbaud = 5000000;
116 if (baud==
"6000000" || baud==
"6000k" || baud==
"6M") nsbaud = 6000000;
117 if (baud==
"6666666" || baud==
"6666k") nsbaud = 6666666;
118 if (baud==
"10000000" || baud==
"10000k" || baud==
"10M") nsbaud = 10000000;
119 if (baud==
"12000000" || baud==
"12000k" || baud==
"12M") nsbaud = 12000000;
121 emsg.
Init(
"RlinkPortTerm::Open()",
122 string(
"invalid baud rate '") + baud +
"' specified");
130 fd = open(
fUrl.
Path().c_str(), O_RDWR|O_NOCTTY);
133 string(
"open() for '") +
fUrl.
Path() +
"' failed: ",
139 emsg.
Init(
"RlinkPortTerm::Open()",
140 string(
"isatty() check for '") +
fUrl.
Path() +
141 "' failed: not a TTY");
146 if (::tcgetattr(fd, &
fTiosOld) != 0) {
148 string(
"tcgetattr() for '") +
fUrl.
Path() +
"' failed: ",
154 struct serial_struct sioctl = {};
158 if (::ioctl(fd, TIOCGSERIAL, &sioctl) < 0) {
160 string(
"ioctl(TIOCGSERIAL) for '")+
fUrl.
Path()+
"' failed: ",
165 double fcdivisor = double(sioctl.baud_base) / double(nsbaud);
166 cdivisor = int(fcdivisor + 0.5);
195 if (::cfsetspeed(&
fTiosNew, speed) != 0) {
197 string(
"cfsetspeed() for '") + baud +
"' failed: ",
204 sioctl.flags |= ASYNC_SPD_CUST;
205 sioctl.custom_divisor = cdivisor;
206 if (::ioctl(fd, TIOCSSERIAL, &sioctl) < 0) {
208 string(
"ioctl(TIOCSSERIAL) for '")+
fUrl.
Path()+
"' failed: ",
231 if (::tcsetattr(fd, TCSANOW, &
fTiosNew) != 0) {
233 string(
"tcsetattr() for '") +
fUrl.
Path() +
"' failed: ",
244 if (::tcgetattr(fd, &tios) != 0) {
246 string(
"2nd tcgetattr() for '") +
fUrl.
Path() +
247 "' failed: ", errno);
252 const char* pmsg = 0;
253 if (tios.c_iflag !=
fTiosNew.c_iflag) pmsg =
"c_iflag";
254 if (tios.c_oflag !=
fTiosNew.c_oflag) pmsg =
"c_oflag";
255 if (tios.c_cflag !=
fTiosNew.c_cflag) pmsg =
"c_cflag";
256 if (tios.c_lflag !=
fTiosNew.c_lflag) pmsg =
"c_lflag";
257 if (::cfgetispeed(&tios) != speed) pmsg =
"ispeed";
258 if (::cfgetospeed(&tios) != speed) pmsg =
"ospeed";
259 for (
int i=0; i<NCCS; i++) {
260 if (tios.c_cc[i] !=
fTiosNew.c_cc[i]) pmsg =
"c_cc char";
264 if (speed != B38400 && pmsg) {
265 emsg.
Init(
"RlinkPortTerm::Open()",
266 string(
"tcsetattr() failed to set") +
string(pmsg));
276 if (tcsendbreak(fd, 0) != 0) {
278 string(
"tcsendbreak() for '") +
fUrl.
Path() +
279 "' failed: ", errno);
285 if (
Write(buf, 1, emsg) != 1) {
317 os << bl << (text?text:
"--") <<
"RlinkPortTerm @ " <<
this << endl;
328 const struct termios& tios)
const
331 os << bl << name <<
":" << endl;
332 os << bl <<
" c_iflag : " <<
RosPrintf(tios.c_iflag,
"x0",8);
333 if (tios.c_iflag & BRKINT) os <<
" BRKINT";
334 if (tios.c_iflag & ICRNL) os <<
" ICRNL ";
335 if (tios.c_iflag & IGNBRK) os <<
" IGNBRK";
336 if (tios.c_iflag & IGNCR) os <<
" IGNCR ";
337 if (tios.c_iflag & IGNPAR) os <<
" IGNPAR";
338 if (tios.c_iflag & INLCR) os <<
" INLCR ";
339 if (tios.c_iflag & INPCK) os <<
" INPCK ";
340 if (tios.c_iflag & ISTRIP) os <<
" ISTRIP";
341 if (tios.c_iflag & IXOFF) os <<
" IXOFF ";
342 if (tios.c_iflag & IXON) os <<
" IXON ";
343 if (tios.c_iflag & PARMRK) os <<
" PARMRK";
346 os << bl <<
" c_oflag : " <<
RosPrintf(tios.c_oflag,
"x0",8);
347 if (tios.c_oflag & OPOST) os <<
" OPOST ";
350 os << bl <<
" c_cflag : " <<
RosPrintf(tios.c_cflag,
"x0",8);
351 if (tios.c_cflag & CLOCAL) os <<
" CLOCAL";
352 if (tios.c_cflag & CREAD) os <<
" CREAD ";
353 if ((tios.c_cflag & CSIZE) == CS5) os <<
" CS5 ";
354 if ((tios.c_cflag & CSIZE) == CS6) os <<
" CS6 ";
355 if ((tios.c_cflag & CSIZE) == CS7) os <<
" CS7 ";
356 if ((tios.c_cflag & CSIZE) == CS8) os <<
" CS8 ";
357 if (tios.c_cflag & CSTOPB) os <<
" CSTOPB";
358 if (tios.c_cflag & HUPCL) os <<
" HUPCL ";
359 if (tios.c_cflag & PARENB) os <<
" PARENB";
360 if (tios.c_cflag & PARODD) os <<
" PARODD";
361 speed_t speed = cfgetispeed(&tios);
363 if (speed == B2400) baud = 2400;
364 if (speed == B4800) baud = 4800;
365 if (speed == B9600) baud = 9600;
366 if (speed == B19200) baud = 19200;
367 if (speed == B38400) baud = 38400;
368 if (speed == B57600) baud = 57600;
369 if (speed == B115200) baud = 115200;
370 if (speed == B230400) baud = 230400;
371 if (speed == B460800) baud = 460800;
372 if (speed == B500000) baud = 500000;
373 if (speed == B921600) baud = 921600;
374 if (speed == B1000000) baud = 1000000;
375 if (speed == B1152000) baud = 1152000;
376 if (speed == B1500000) baud = 1500000;
377 if (speed == B2000000) baud = 2000000;
378 if (speed == B2500000) baud = 2500000;
379 if (speed == B3000000) baud = 3000000;
380 if (speed == B3500000) baud = 3500000;
381 if (speed == B4000000) baud = 4000000;
382 os <<
" speed: " <<
RosPrintf(baud,
"d", 7);
385 os << bl <<
" c_lflag : " <<
RosPrintf(tios.c_lflag,
"x0",8);
386 if (tios.c_lflag & ECHO) os <<
" ECHO ";
387 if (tios.c_lflag & ECHOE) os <<
" ECHOE ";
388 if (tios.c_lflag & ECHOK) os <<
" ECHOK ";
389 if (tios.c_lflag & ECHONL) os <<
" ECHONL";
390 if (tios.c_lflag & ICANON) os <<
" ICANON";
391 if (tios.c_lflag & IEXTEN) os <<
" IEXTEN";
392 if (tios.c_lflag & ISIG) os <<
" ISIG ";
393 if (tios.c_lflag & NOFLSH) os <<
" NOFLSH";
394 if (tios.c_lflag & TOSTOP) os <<
" TOSTOP";
397 os << bl <<
" c_cc : " << endl;
398 os << bl <<
" [VEOF] : " <<
RosPrintf(tios.c_cc[VEOF],
"o",3);
399 os <<
" [VEOL] : " <<
RosPrintf(tios.c_cc[VEOL],
"o",3);
400 os <<
" [VERASE]: " <<
RosPrintf(tios.c_cc[VERASE],
"o",3);
401 os <<
" [VINTR] : " <<
RosPrintf(tios.c_cc[VINTR],
"o",3) << endl;
402 os << bl <<
" [VKILL] : " <<
RosPrintf(tios.c_cc[VKILL],
"o",3);
403 os <<
" [VQUIT] : " <<
RosPrintf(tios.c_cc[VQUIT],
"o",3);
404 os <<
" [VSUSP] : " <<
RosPrintf(tios.c_cc[VSUSP],
"o",3);
405 os <<
" [VSTART]: " <<
RosPrintf(tios.c_cc[VSTART],
"o",3) << endl;
406 os << bl <<
" [VSTOP] : " <<
RosPrintf(tios.c_cc[VSTOP],
"o",3);
407 os <<
" [VMIN] : " <<
RosPrintf(tios.c_cc[VMIN],
"o",3);
408 os <<
" [VTIME] : " <<
RosPrintf(tios.c_cc[VTIME],
"o",3) << endl;
void Init(const std::string &meth, const std::string &text)
FIXME_docs.
void InitErrno(const std::string &meth, const std::string &text, int errnum)
FIXME_docs.
virtual ~RlinkPortTerm()
Destructor.
virtual bool Open(const std::string &url, RerrMsg &emsg)
FIXME_docs.
virtual void Close()
FIXME_docs.
virtual void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
RlinkPortTerm()
Default constructor.
void DumpTios(std::ostream &os, int ind, const std::string &name, const struct termios &tios) const
FIXME_docs.
static const uint8_t kc_xon
static const uint8_t kc_xoff
bool IsOpen() const
FIXME_docs.
bool fXon
xon attribute set
virtual void Close()
FIXME_docs.
virtual int Write(const uint8_t *buf, size_t size, RerrMsg &emsg)
FIXME_docs.
virtual void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
I/O appicator to generate fill characters.
bool FindOpt(const std::string &name) const
FIXME_docs.
bool Set(const std::string &url, const std::string &optlist, RerrMsg &emsg)
FIXME_docs.
void SetPath(const std::string &path)
FIXME_docs.
const std::string & Path() const
FIXME_docs.
RosPrintfS< bool > RosPrintf(bool value, const char *form=0, int width=0, int prec=0)
Creates a print object for the formatted output of a bool value.
Declaration of class ReventLoop.