1 #include "SerialControl.h"
3 namespace remote
{ namespace mch
{
5 SerialControl::SerialControl()
6 : port(-1), childPid(-1)
10 SerialControl::~SerialControl()
17 bool SerialControl::openTty(const std::string platform
, const std::string tty
)
19 struct termios newsertio
;
22 Log::debug("TTY already open for %s", tty
.c_str());
26 Log::info("Opening TTY %s", tty
.c_str());
27 port
= open(tty
.c_str(), O_RDWR
| O_NOCTTY
| O_NONBLOCK
);
29 Log::error("Failed to open %s: %s", tty
.c_str(), strerror(errno
));
33 tcgetattr(port
, &oldsertio
); /* save current port settings */
36 * 8 data, no parity, 1 stop bit. Ignore modem control lines. Enable
37 * receive. NO HARDWARE FLOW CONTROL!
39 newsertio
.c_cflag
= CS8
| CLOCAL
| CREAD
;
42 if (platform
== "dig528-2")
43 newsertio
.c_cflag
|= B38400
;
44 else if(platform
== "TMoteSky")
45 newsertio
.c_cflag
= B115200
;
46 else if (platform
== "MicaZ")
47 newsertio
.c_cflag
= B57600
;
49 Log::error("Unknown platform '%s'", platform
.c_str());
51 /* Raw input. Ignore errors and breaks. */
52 newsertio
.c_iflag
= IGNBRK
| IGNPAR
;
55 newsertio
.c_oflag
= 0;
57 /* No echo and no signals. */
58 newsertio
.c_lflag
= 0;
60 /* blocking read until 1 char arrives */
61 newsertio
.c_cc
[VMIN
]=1;
62 newsertio
.c_cc
[VTIME
]=0;
64 /* now clean the modem line and activate the settings for modem */
65 tcflush(port
, TCIFLUSH
);
66 tcsetattr(port
, TCSANOW
, &newsertio
);
71 void SerialControl::closeTty()
76 tcsetattr(port
, TCSANOW
, &oldsertio
);
81 bool SerialControl::runChild(char * const args
[], char * const envp
[])
89 if ((childPid
= fork())) {
90 /* Only use the reader end if we forked. */
98 /* Redirect all standard output to the parent's pipe. */
99 if (dup2(pfd
[1], STDOUT_FILENO
) != -1 &&
100 dup2(pfd
[1], STDERR_FILENO
) != -1) {
103 execve(args
[0], args
, envp
);
105 /* XXX: Make the failed child exit immediately. */
112 bool SerialControl::endChild(bool killChild
)
120 kill(childPid
, SIGKILL
);
122 waitpid(childPid
, &status
, 0);
124 port
= childPid
= -1;
126 return killChild
|| (WIFEXITED(status
) && WEXITSTATUS(status
) == 0);
129 bool SerialControl::controlDTR(bool enable
)
132 int req
= enable
? TIOCMBIS
: TIOCMBIC
;
134 return ioctl(port
, req
, &tmp
) != -1;
137 ssize_t
SerialControl::readBuf(char *buf
, size_t len
)
139 ssize_t res
= read(port
, buf
, len
);
141 if (res
<= 0 && !hasChild())
147 ssize_t
SerialControl::writeBuf(const char* buf
, size_t len
)
149 return write(port
, buf
, len
);
152 bool SerialControl::hasChild()
154 return childPid
!= -1;
157 bool SerialControl::isOpen()
159 return port
!= -1 && !hasChild();
162 int SerialControl::getFd()