diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/MTS_IO_LockFile.cpp | 94 | ||||
-rw-r--r-- | src/MTS_IO_SerialConnection.cpp | 85 |
2 files changed, 108 insertions, 71 deletions
diff --git a/src/MTS_IO_LockFile.cpp b/src/MTS_IO_LockFile.cpp index b74ba73..7f84f42 100644 --- a/src/MTS_IO_LockFile.cpp +++ b/src/MTS_IO_LockFile.cpp @@ -18,9 +18,9 @@ * */ -/*! +/*! \file MTS_IO_LockFile.cpp - \brief A brief description + \brief A brief description \date Oct 8, 2014 \author sgodinez @@ -29,13 +29,7 @@ #include <mts/MTS_IO_LockFile.h> #include <mts/MTS_Timer.h> -#include <mts/MTS_Logger.h> -#include <mts/MTS_System.h> -#include <mts/MTS_Text.h> #include <sys/file.h> -#include <sys/stat.h> -#include <errno.h> -#include <string.h> #include <unistd.h> using namespace MTS::IO; @@ -43,79 +37,49 @@ using namespace MTS::IO; LockFile::LockFile(const std::string& sFile) : m_sFile(sFile) , m_iLockFd(-1) +, m_iLockErr(-1) { - } -LockFile::~LockFile() { +LockFile::~LockFile() +{ unlock(); } -bool LockFile::lock(uint32_t attemptMillis) { - if(isLocked()) { +bool LockFile::lock(uint32_t attemptMillis) +{ + if (isLocked()) { return true; } - MTS::Timer timer; - - timer.start(); - while(timer.getMillis() < attemptMillis) { - m_iLockFd =::open(m_sFile.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0644); - if (m_iLockFd < 0) { - // device already locked -> bail out - printWarning("LockFile| Failed to Lock [%s] [%d][%s]", m_sFile.c_str(), errno, strerror(errno)); - - //Check if lock file's process still exists - std::string sResult; - if(MTS::System::readFile(m_sFile, sResult) == 0 && sResult.size() > 0) { - struct stat sts; - std::string sProc = "/proc/" + MTS::Text::trim(sResult); - if (stat(sProc.c_str(), &sts) == -1 && errno == ENOENT) { - printWarning("LockFile| Current Lock's Process [%s] does not exist. Removing lock.", sResult.c_str()); - // process doesn't exist -> remove file - ::unlink(m_sFile.c_str()); - } - } - - } else { - //TODO: Investigate using flock in addition to minicom-style lock : flock(m_iLockFd, LOCK_EX | LOCK_NB); - - // %4d to make concurrent mgetty (if any) happy. - // Mgetty treats 4-bytes lock files as binary, - // not text, PID. Making 5+ char file. Brrr... - char buf[256] = {0}; - size_t written = 0; - - sprintf(buf, "%4d\n", getpid()); - size_t wsize = strlen(buf); - - written = write(m_iLockFd, buf, wsize); - - if (wsize != written) { - printError("LockFile| Error writing to lock file [%s] [%d][%s]", m_sFile.c_str(), errno, strerror(errno)); - close(m_iLockFd); - return false; - } - else { - close(m_iLockFd); + m_iLockFd = ::open(m_sFile.c_str(), O_CREAT | O_RDWR, 0644); + if (m_iLockFd >= 0) { + MTS::Timer timer; + timer.start(); + while (timer.getMillis() < attemptMillis) { + m_iLockErr = ::flock(m_iLockFd, LOCK_EX | LOCK_NB); + if (m_iLockErr == 0) { return true; + } else if (errno != EWOULDBLOCK) { + break; } + ::usleep(((rand() % 10) + 1) * 100000); //Sleep from 100ms to 1 Second } - uint32_t randomSleepTime = ((rand() % 10) + 1) * 100000; //Sleep from 100ms to 1 Second - ::usleep(randomSleepTime); + ::close(m_iLockFd); } + m_iLockFd = -1; return false; } -void LockFile::unlock() { - if(isLocked()) { - ::unlink(m_sFile.c_str()); - //TODO: flock cleanup : flock(m_iLockFd, LOCK_UN); - m_iLockFd = -1; - } +void LockFile::unlock() +{ + ::flock(m_iLockFd, LOCK_UN); + ::close(m_iLockFd); + m_iLockFd = -1; + m_iLockErr = -1; } -bool LockFile::isLocked() { - return m_iLockFd >= 0; +bool LockFile::isLocked() +{ + return m_iLockErr == 0; } - diff --git a/src/MTS_IO_SerialConnection.cpp b/src/MTS_IO_SerialConnection.cpp index a9f3d6e..936d28d 100644 --- a/src/MTS_IO_SerialConnection.cpp +++ b/src/MTS_IO_SerialConnection.cpp @@ -50,6 +50,7 @@ SerialConnection::Builder::Builder(const std::string& sPortName) , m_eParity(OFF) , m_eDataBits(B8) , m_eStopBits(B1) +, m_eFlowControl(NONE) , m_bBuilt(false) { @@ -254,6 +255,77 @@ int SerialConnection::getFileDescriptor() { return h; } +const char* SerialConnection::humanSpeed(speed_t speed) { + const char *hspeed; + switch (speed) { + case B0: hspeed = "B0"; + break; + case B50: hspeed = "B50"; + break; + case B75: hspeed = "B75"; + break; + case B110: hspeed = "B110"; + break; + case B134: hspeed = "B134"; + break; + case B150: hspeed = "B150"; + break; + case B200: hspeed = "B200"; + break; + case B300: hspeed = "B300"; + break; + case B600: hspeed = "B600"; + break; + case B1200: hspeed = "B1200"; + break; + case B1800: hspeed = "B1800"; + break; + case B2400: hspeed = "B2400"; + break; + case B4800: hspeed = "B4800"; + break; + case B9600: hspeed = "B9600"; + break; + case B19200: hspeed = "B19200"; + break; + case B57600: hspeed = "B57600"; + break; + case B115200: hspeed = "B115200"; + break; + default: hspeed = "unknown"; + } + return hspeed; +} + +void SerialConnection::printPortSetting(const termios *options){ + printDebug("SERIAL| port settings:"); + printDebug("SERIAL| in speed:%s out speed:%s", + humanSpeed(cfgetispeed(options)), + humanSpeed(cfgetospeed(options))); + int data_length=0; + if ((options->c_cflag&CSIZE) == CS5) { + data_length = 5; + } + if ((options->c_cflag&CSIZE) == CS6) { + data_length = 6; + } + if ((options->c_cflag&CSIZE) == CS7) { + data_length = 7; + } + if ((options->c_cflag&CSIZE) == CS8) { + data_length = 8; + } + printDebug("SERIAL| data:%d stop bits:%d", data_length,options->c_cflag&CSTOPB?2:1); + if (!(options->c_cflag&PARENB)) { + printDebug("SERIAL| parity: NONE"); + } else if (options->c_cflag&PARODD) { + printDebug("SERIAL| parity: ODD"); + } else { + printDebug("SERIAL| parity: EVEN"); + } + printDebug("SERIAL| CRTSCTS:%d", options->c_cflag&CRTSCTS?1:0); +} + bool SerialConnection::doOpen(const int32_t& timeoutMillis) { m_apHandleLock->lock(); @@ -353,6 +425,7 @@ bool SerialConnection::doOpen(const int32_t& timeoutMillis) { } //Set Parity, Stop Bits, and Data Length + options.c_cflag &= ~(PARODD | PARENB); switch(m_eParity) { case ODD: options.c_cflag |= ( PARODD | PARENB ); @@ -364,7 +437,6 @@ bool SerialConnection::doOpen(const int32_t& timeoutMillis) { case OFF: default: - options.c_cflag &= ~PARENB; break; } @@ -390,7 +462,7 @@ bool SerialConnection::doOpen(const int32_t& timeoutMillis) { switch(m_eStopBits) { case B2: - options.c_cflag &= CSTOPB; + options.c_cflag |= CSTOPB; break; case B1: @@ -401,19 +473,20 @@ bool SerialConnection::doOpen(const int32_t& timeoutMillis) { switch (m_eFlowControl) { case RTS_CTS: - options.c_cflag &= CRTSCTS; + options.c_cflag |= CRTSCTS; break; case NONE: default: - options.c_cflag &= ~(IXON | IXOFF | IXANY); - break; + options.c_cflag &= ~CRTSCTS; + break; } //Set Control Modes options.c_cc[VMIN] = 0; options.c_cc[VTIME] = 2; // tenths of seconds - + printPortSetting(&options); result = tcsetattr(m_iHandle, TCSANOW, &options); + if (result == -1) { printWarning("SERIAL| Failed to set configurations on port [%s] [%d]%s", m_sPortName.c_str(), errno, errno == 13 ? " (Permission Denied)" : ""); |