Line 1... |
Line 1... |
// $Id: RlinkPortTerm.cpp 516 2013-05-05 21:24:52Z mueller $
|
// $Id: RlinkPortTerm.cpp 607 2014-11-30 20:02:48Z mueller $
|
//
|
//
|
// Copyright 2011-2013 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
// Copyright 2011-2013 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
//
|
//
|
// This program is free software; you may redistribute and/or modify it under
|
// This program is free software; you may redistribute and/or modify it under
|
// the terms of the GNU General Public License as published by the Free
|
// the terms of the GNU General Public License as published by the Free
|
Line 23... |
Line 23... |
// 2011-03-27 374 1.0 Initial version
|
// 2011-03-27 374 1.0 Initial version
|
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
|
|
/*!
|
/*!
|
\file
|
\file
|
\version $Id: RlinkPortTerm.cpp 516 2013-05-05 21:24:52Z mueller $
|
\version $Id: RlinkPortTerm.cpp 607 2014-11-30 20:02:48Z mueller $
|
\brief Implemenation of RlinkPortTerm.
|
\brief Implemenation of RlinkPortTerm.
|
*/
|
*/
|
|
|
#include <sys/types.h>
|
#include <sys/types.h>
|
#include <sys/stat.h>
|
#include <sys/stat.h>
|
Line 135... |
Line 135... |
"' failed: not a TTY");
|
"' failed: not a TTY");
|
close(fd);
|
close(fd);
|
return false;
|
return false;
|
}
|
}
|
|
|
if (tcgetattr(fd, &fTiosOld) != 0) {
|
if (::tcgetattr(fd, &fTiosOld) != 0) {
|
emsg.InitErrno("RlinkPortTerm::Open()",
|
emsg.InitErrno("RlinkPortTerm::Open()",
|
string("tcgetattr() for '") + fUrl.Path() + "' failed: ",
|
string("tcgetattr() for '") + fUrl.Path() + "' failed: ",
|
errno);
|
errno);
|
close(fd);
|
::close(fd);
|
return false;
|
return false;
|
}
|
}
|
|
|
bool use_cts = fUrl.FindOpt("cts");
|
bool use_cts = fUrl.FindOpt("cts");
|
bool use_xon = fUrl.FindOpt("xon");
|
bool use_xon = fUrl.FindOpt("xon");
|
Line 169... |
Line 169... |
fTiosNew.c_cflag |= CRTSCTS; // enable hardware flow control
|
fTiosNew.c_cflag |= CRTSCTS; // enable hardware flow control
|
}
|
}
|
|
|
fTiosNew.c_lflag = 0;
|
fTiosNew.c_lflag = 0;
|
|
|
if (cfsetspeed(&fTiosNew, speed) != 0) {
|
if (::cfsetspeed(&fTiosNew, speed) != 0) {
|
emsg.InitErrno("RlinkPortTerm::Open()",
|
emsg.InitErrno("RlinkPortTerm::Open()",
|
string("cfsetspeed() for '") + baud + "' failed: ",
|
string("cfsetspeed() for '") + baud + "' failed: ",
|
errno);
|
errno);
|
close(fd);
|
close(fd);
|
return false;
|
return false;
|
Line 193... |
Line 193... |
if (use_xon) {
|
if (use_xon) {
|
fTiosNew.c_cc[VSTART] = kc_xon; // setup XON -> ^Q
|
fTiosNew.c_cc[VSTART] = kc_xon; // setup XON -> ^Q
|
fTiosNew.c_cc[VSTOP] = kc_xoff; // setup XOFF -> ^S
|
fTiosNew.c_cc[VSTOP] = kc_xoff; // setup XOFF -> ^S
|
}
|
}
|
|
|
if (tcsetattr(fd, TCSANOW, &fTiosNew) != 0) {
|
if (::tcsetattr(fd, TCSANOW, &fTiosNew) != 0) {
|
emsg.InitErrno("RlinkPortTerm::Open()",
|
emsg.InitErrno("RlinkPortTerm::Open()",
|
string("tcsetattr() for '") + fUrl.Path() + "' failed: ",
|
string("tcsetattr() for '") + fUrl.Path() + "' failed: ",
|
errno);
|
errno);
|
close(fd);
|
::close(fd);
|
return false;
|
return false;
|
}
|
}
|
|
|
// tcsetattr() returns success if any of the requested changes could be
|
// tcsetattr() returns success if any of the requested changes could be
|
// successfully carried out. Therefore the termios structure is read back
|
// successfully carried out. Therefore the termios structure is read back
|
// and verified.
|
// and verified.
|
|
|
struct termios tios;
|
struct termios tios;
|
if (tcgetattr(fd, &tios) != 0) {
|
if (::tcgetattr(fd, &tios) != 0) {
|
emsg.InitErrno("RlinkPortTerm::Open()",
|
emsg.InitErrno("RlinkPortTerm::Open()",
|
string("2nd tcgetattr() for '") + fUrl.Path() +
|
string("2nd tcgetattr() for '") + fUrl.Path() +
|
"' failed: ", errno);
|
"' failed: ", errno);
|
close(fd);
|
::close(fd);
|
return false;
|
return false;
|
}
|
}
|
|
|
const char* pmsg = 0;
|
const char* pmsg = 0;
|
if (tios.c_iflag != fTiosNew.c_iflag) pmsg = "c_iflag";
|
if (tios.c_iflag != fTiosNew.c_iflag) pmsg = "c_iflag";
|
if (tios.c_oflag != fTiosNew.c_oflag) pmsg = "c_oflag";
|
if (tios.c_oflag != fTiosNew.c_oflag) pmsg = "c_oflag";
|
if (tios.c_cflag != fTiosNew.c_cflag) pmsg = "c_cflag";
|
if (tios.c_cflag != fTiosNew.c_cflag) pmsg = "c_cflag";
|
if (tios.c_lflag != fTiosNew.c_lflag) pmsg = "c_lflag";
|
if (tios.c_lflag != fTiosNew.c_lflag) pmsg = "c_lflag";
|
if (cfgetispeed(&tios) != speed) pmsg = "ispeed";
|
if (::cfgetispeed(&tios) != speed) pmsg = "ispeed";
|
if (cfgetospeed(&tios) != speed) pmsg = "ospeed";
|
if (::cfgetospeed(&tios) != speed) pmsg = "ospeed";
|
for (int i=0; i<NCCS; i++) {
|
for (int i=0; i<NCCS; i++) {
|
if (tios.c_cc[i] != fTiosNew.c_cc[i]) pmsg = "c_cc char";
|
if (tios.c_cc[i] != fTiosNew.c_cc[i]) pmsg = "c_cc char";
|
}
|
}
|
|
|
if (pmsg) {
|
if (pmsg) {
|
emsg.Init("RlinkPortTerm::Open()",
|
emsg.Init("RlinkPortTerm::Open()",
|
string("tcsetattr() failed to set") + string(pmsg));
|
string("tcsetattr() failed to set") + string(pmsg));
|
close(fd);
|
::close(fd);
|
return false;
|
return false;
|
}
|
}
|
|
|
fFdWrite = fd;
|
fFdWrite = fd;
|
fFdRead = fd;
|
fFdRead = fd;
|
Line 263... |
Line 263... |
void RlinkPortTerm::Close()
|
void RlinkPortTerm::Close()
|
{
|
{
|
if (!IsOpen()) return;
|
if (!IsOpen()) return;
|
|
|
if (fFdWrite >= 0) {
|
if (fFdWrite >= 0) {
|
tcflush(fFdWrite, TCIOFLUSH);
|
::tcflush(fFdWrite, TCIOFLUSH);
|
tcsetattr(fFdWrite, TCSANOW, &fTiosOld);
|
::tcsetattr(fFdWrite, TCSANOW, &fTiosOld);
|
}
|
}
|
RlinkPort::Close();
|
RlinkPort::Close();
|
|
|
return;
|
return;
|
}
|
}
|