diff options
| -rw-r--r-- | include/mts/MTS_IO_LockFile.h | 6 | ||||
| -rw-r--r-- | include/mts/MTS_IO_SerialConnection.h | 2 | ||||
| -rw-r--r-- | src/MTS_IO_LockFile.cpp | 94 | ||||
| -rw-r--r-- | src/MTS_IO_SerialConnection.cpp | 85 | 
4 files changed, 111 insertions, 76 deletions
| diff --git a/include/mts/MTS_IO_LockFile.h b/include/mts/MTS_IO_LockFile.h index 730cf3c..22e641b 100644 --- a/include/mts/MTS_IO_LockFile.h +++ b/include/mts/MTS_IO_LockFile.h @@ -34,11 +34,8 @@  namespace MTS {      namespace IO { -          class LockFile : MTS::NonCopyable { -              public: -                  LockFile(const std::string& sFilePath);                  virtual ~LockFile(); @@ -46,11 +43,10 @@ namespace MTS {                  void unlock();                  bool isLocked(); -            protected: -              private:                  std::string m_sFile;                  int m_iLockFd; +                int m_iLockErr;          };      } diff --git a/include/mts/MTS_IO_SerialConnection.h b/include/mts/MTS_IO_SerialConnection.h index a4ca011..b0ce663 100644 --- a/include/mts/MTS_IO_SerialConnection.h +++ b/include/mts/MTS_IO_SerialConnection.h @@ -173,6 +173,8 @@ namespace MTS {                  virtual int doWrite(const char* pBuffer, const uint32_t& iSize, int32_t& timeoutMillis);                  void cleanup(); +                void printPortSetting(const termios *options); +                const char* humanSpeed(speed_t speed);          };      }  } 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)" : ""); | 
