X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2Fplatform%2Fwindows%2Fserialport.cpp;h=ad7f8711d059e7679b2f1bd00c94b9f9a95ad27c;hb=2b44051cbfa70deafc30d9767323214debbc1a75;hp=ade4fb214cc4714786dbb0b16828b2777c346f8c;hpb=24048d575419fe909fade9110fab48d17370ee6f;p=deb_libcec.git diff --git a/src/lib/platform/windows/serialport.cpp b/src/lib/platform/windows/serialport.cpp index ade4fb2..ad7f871 100644 --- a/src/lib/platform/windows/serialport.cpp +++ b/src/lib/platform/windows/serialport.cpp @@ -1,7 +1,7 @@ /* * This file is part of the libCEC(R) library. * - * libCEC(R) is Copyright (C) 2011 Pulse-Eight Limited. All rights reserved. + * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. * libCEC(R) is an original work, containing original code. * * libCEC(R) is a trademark of Pulse-Eight Limited. @@ -30,14 +30,15 @@ * http://www.pulse-eight.net/ */ -#include "../sockets/serialport.h" -#include "../util/baudrate.h" -#include "../util/timeutils.h" +#include "env.h" +#include "lib/platform/sockets/serialport.h" +#include "lib/platform/util/baudrate.h" +#include "lib/platform/util/timeutils.h" using namespace std; using namespace PLATFORM; -void CSerialPort::FormatWindowsError(int iErrorCode, CStdString &strMessage) +void FormatWindowsError(int iErrorCode, std::string &strMessage) { if (iErrorCode != ERROR_SUCCESS) { @@ -48,22 +49,81 @@ void CSerialPort::FormatWindowsError(int iErrorCode, CStdString &strMessage) } } -CSerialPort::CSerialPort(void) : - m_handle(INVALID_HANDLE_VALUE), - m_bIsOpen(false), - m_iBaudrate(0), - m_iDatabits(0), - m_iStopbits(0), - m_iParity(0) +bool CSerialSocket::SetTimeouts(serial_socket_t socket, int* iError, DWORD iTimeoutMs) { + if (socket == INVALID_HANDLE_VALUE) + return false; + + if (iTimeoutMs == m_iCurrentReadTimeout) + return true; + + COMMTIMEOUTS cto; + if (iTimeoutMs == 0) + { + cto.ReadIntervalTimeout = MAXDWORD; + cto.ReadTotalTimeoutConstant = 0; + cto.ReadTotalTimeoutMultiplier = 0; + } + else + { + cto.ReadIntervalTimeout = 0; + cto.ReadTotalTimeoutConstant = iTimeoutMs; + cto.ReadTotalTimeoutMultiplier = 0; + } + + if (!SetCommTimeouts(socket, &cto)) + { + *iError = GetLastError(); + return false; + } + else + { + m_iCurrentReadTimeout = iTimeoutMs; + } + + return true; +} + +void CSerialSocket::Close(void) +{ + if (IsOpen()) + SerialSocketClose(m_socket); + m_socket = INVALID_SERIAL_SOCKET_VALUE; } -bool CSerialPort::Open(string name, uint32_t baudrate, uint8_t databits, uint8_t stopbits, uint8_t parity) +void CSerialSocket::Shutdown(void) { - CStdString strComPath = "\\\\.\\" + name; + if (IsOpen()) + SerialSocketClose(m_socket); + m_socket = INVALID_SERIAL_SOCKET_VALUE; +} + +ssize_t CSerialSocket::Write(void* data, size_t len) +{ + return IsOpen() ? SerialSocketWrite(m_socket, &m_iError, data, len) : -1; +} + +ssize_t CSerialSocket::Read(void* data, size_t len, uint64_t iTimeoutMs /* = 0 */) +{ + DWORD dwTimeoutMs((DWORD)iTimeoutMs); + if (iTimeoutMs != (uint64_t)iTimeoutMs) + dwTimeoutMs = MAXDWORD; + + return IsOpen() && SetTimeouts(m_socket, &m_iError, dwTimeoutMs) ? + SerialSocketRead(m_socket, &m_iError, data, len, iTimeoutMs) : + -1; +} + +bool CSerialSocket::Open(uint64_t iTimeoutMs /* = 0 */) +{ + iTimeoutMs = 0; + if (IsOpen()) + return false; + + std::string strComPath = "\\\\.\\" + m_strName; CLockObject lock(m_mutex); - m_handle = CreateFile(strComPath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - if (m_handle == INVALID_HANDLE_VALUE) + m_socket = CreateFile(strComPath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + if (m_socket == INVALID_HANDLE_VALUE) { m_strError = "Unable to open COM port"; FormatWindowsError(GetLastError(), m_strError); @@ -75,7 +135,7 @@ bool CSerialPort::Open(string name, uint32_t baudrate, uint8_t databits, uint8_t commConfig.dwSize = dwSize; if (GetDefaultCommConfig(strComPath.c_str(), &commConfig,&dwSize)) { - if (!SetCommConfig(m_handle, &commConfig,dwSize)) + if (!SetCommConfig(m_socket, &commConfig,dwSize)) { m_strError = "unable to set default config"; FormatWindowsError(GetLastError(), m_strError); @@ -87,16 +147,13 @@ bool CSerialPort::Open(string name, uint32_t baudrate, uint8_t databits, uint8_t FormatWindowsError(GetLastError(), m_strError); } - if (!SetupComm(m_handle, 64, 64)) + if (!SetupComm(m_socket, 64, 64)) { m_strError = "unable to set up the com port"; FormatWindowsError(GetLastError(), m_strError); } - m_iDatabits = databits; - m_iStopbits = stopbits; - m_iParity = parity; - if (!SetBaudRate(baudrate)) + if (!SetBaudRate(m_iBaudrate)) { m_strError = "unable to set baud rate"; FormatWindowsError(GetLastError(), m_strError); @@ -104,7 +161,7 @@ bool CSerialPort::Open(string name, uint32_t baudrate, uint8_t databits, uint8_t return false; } - if (!SetTimeouts(false)) + if (!SetTimeouts(m_socket, &m_iError, 0)) { m_strError = "unable to set timeouts"; FormatWindowsError(GetLastError(), m_strError); @@ -116,95 +173,7 @@ bool CSerialPort::Open(string name, uint32_t baudrate, uint8_t databits, uint8_t return m_bIsOpen; } -bool CSerialPort::SetTimeouts(bool bBlocking) -{ - if (m_handle == INVALID_HANDLE_VALUE) - return false; - - COMMTIMEOUTS cto; - if (!GetCommTimeouts(m_handle, &cto)) - { - m_strError = "GetCommTimeouts failed"; - FormatWindowsError(GetLastError(), m_strError); - return false; - } - - if (bBlocking) - { - cto.ReadIntervalTimeout = 0; - cto.ReadTotalTimeoutConstant = 0; - cto.ReadTotalTimeoutMultiplier = 0; - } - else - { - cto.ReadIntervalTimeout = MAXDWORD; - cto.ReadTotalTimeoutConstant = 0; - cto.ReadTotalTimeoutMultiplier = 0; - } - - if (!SetCommTimeouts(m_handle, &cto)) - { - m_strError = "SetCommTimeouts failed"; - FormatWindowsError(GetLastError(), m_strError); - return false; - } - - return true; -} - -void CSerialPort::Close(void) -{ - CLockObject lock(m_mutex); - if (m_bIsOpen) - { - CloseHandle(m_handle); - m_bIsOpen = false; - } -} - -int64_t CSerialPort::Write(uint8_t* data, uint32_t len) -{ - CLockObject lock(m_mutex); - DWORD iBytesWritten = 0; - if (!m_bIsOpen) - return -1; - - if (!WriteFile(m_handle, data, len, &iBytesWritten, NULL)) - { - m_strError = "Error while writing to COM port"; - FormatWindowsError(GetLastError(), m_strError); - return -1; - } - - return (int64_t)iBytesWritten; -} - -int32_t CSerialPort::Read(uint8_t* data, uint32_t len, uint64_t iTimeoutMs /* = 0 */) -{ - CLockObject lock(m_mutex); - int32_t iReturn(-1); - DWORD iBytesRead = 0; - if (m_handle == 0) - { - m_strError = "Error while reading from COM port: invalid handle"; - return iReturn; - } - - if(!ReadFile(m_handle, data, len, &iBytesRead, NULL) != 0) - { - m_strError = "unable to read from device"; - FormatWindowsError(GetLastError(), m_strError); - iReturn = -1; - } - else - { - iReturn = (int32_t) iBytesRead; - } - - return iReturn; -} - -bool CSerialPort::SetBaudRate(uint32_t baudrate) +bool CSerialSocket::SetBaudRate(uint32_t baudrate) { int32_t rate = IntToBaudrate(baudrate); if (rate < 0) @@ -225,21 +194,21 @@ bool CSerialPort::SetBaudRate(uint32_t baudrate) dcb.fInX = false; dcb.fAbortOnError = true; - if (m_iParity == PAR_NONE) + if (m_iParity == SERIAL_PARITY_NONE) dcb.Parity = NOPARITY; - else if (m_iParity == PAR_EVEN) + else if (m_iParity == SERIAL_PARITY_EVEN) dcb.Parity = EVENPARITY; else dcb.Parity = ODDPARITY; - if (m_iStopbits == 2) + if (m_iStopbits == SERIAL_STOP_BITS_TWO) dcb.StopBits = TWOSTOPBITS; else dcb.StopBits = ONESTOPBIT; - dcb.ByteSize = m_iDatabits; + dcb.ByteSize = (BYTE)m_iDatabits; - if(!SetCommState(m_handle,&dcb)) + if(!SetCommState(m_socket,&dcb)) { m_strError = "SetCommState failed"; FormatWindowsError(GetLastError(), m_strError); @@ -248,9 +217,3 @@ bool CSerialPort::SetBaudRate(uint32_t baudrate) return true; } - -bool CSerialPort::IsOpen(void) -{ - CLockObject lock(m_mutex); - return m_bIsOpen; -}