X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2Fplatform%2Fwindows%2Fserialport.cpp;h=ad7f8711d059e7679b2f1bd00c94b9f9a95ad27c;hb=2b44051cbfa70deafc30d9767323214debbc1a75;hp=bfdc8d53d71917095b444a527f907c0ce8352fb9;hpb=b9187cc6999276ce37a5c9852655fd558ea76b8e;p=deb_libcec.git diff --git a/src/lib/platform/windows/serialport.cpp b/src/lib/platform/windows/serialport.cpp index bfdc8d5..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 "../serialport.h" -#include "../baudrate.h" -#include "../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 CEC; +using namespace PLATFORM; -void FormatWindowsError(int iErrorCode, string &strMessage) +void FormatWindowsError(int iErrorCode, std::string &strMessage) { if (iErrorCode != ERROR_SUCCESS) { @@ -48,160 +49,137 @@ void FormatWindowsError(int iErrorCode, string &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; -CSerialPort::~CSerialPort(void) -{ - Close(); -} + if (iTimeoutMs == m_iCurrentReadTimeout) + return true; -bool CSerialPort::Open(string name, int baudrate, int databits, int stopbits, int parity) -{ - m_handle = CreateFile(name.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - if (m_handle == INVALID_HANDLE_VALUE) - { - m_error = "Unable to open COM port"; - FormatWindowsError(GetLastError(), m_error); - return false; - } - - COMMCONFIG commConfig = {0}; - DWORD dwSize = sizeof(commConfig); - commConfig.dwSize = dwSize; - if (GetDefaultCommConfig(name.c_str(), &commConfig,&dwSize)) + COMMTIMEOUTS cto; + if (iTimeoutMs == 0) { - if (!SetCommConfig(m_handle, &commConfig,dwSize)) - { - m_error = "unable to set default config"; - FormatWindowsError(GetLastError(), m_error); - } + cto.ReadIntervalTimeout = MAXDWORD; + cto.ReadTotalTimeoutConstant = 0; + cto.ReadTotalTimeoutMultiplier = 0; } else { - m_error = "unable to get default config"; - FormatWindowsError(GetLastError(), m_error); - } - - if (!SetupComm(m_handle, 64, 64)) - { - m_error = "unable to set up the com port"; - FormatWindowsError(GetLastError(), m_error); + cto.ReadIntervalTimeout = 0; + cto.ReadTotalTimeoutConstant = iTimeoutMs; + cto.ReadTotalTimeoutMultiplier = 0; } - m_iDatabits = databits; - m_iStopbits = stopbits; - m_iParity = parity; - if (!SetBaudRate(baudrate)) + if (!SetCommTimeouts(socket, &cto)) { - m_error = "unable to set baud rate"; - FormatWindowsError(GetLastError(), m_error); - Close(); + *iError = GetLastError(); return false; } - - if (!SetTimeouts(false)) + else { - m_error = "unable to set timeouts"; - FormatWindowsError(GetLastError(), m_error); - Close(); - return false; + m_iCurrentReadTimeout = iTimeoutMs; } - m_bIsOpen = true; - return m_bIsOpen; + return true; } -bool CSerialPort::SetTimeouts(bool bBlocking) +void CSerialSocket::Close(void) { - if (m_handle == INVALID_HANDLE_VALUE) - return false; + if (IsOpen()) + SerialSocketClose(m_socket); + m_socket = INVALID_SERIAL_SOCKET_VALUE; +} - COMMTIMEOUTS cto; - if (!GetCommTimeouts(m_handle, &cto)) - { - m_error = "GetCommTimeouts failed"; - FormatWindowsError(GetLastError(), m_error); - return false; - } +void CSerialSocket::Shutdown(void) +{ + if (IsOpen()) + SerialSocketClose(m_socket); + m_socket = INVALID_SERIAL_SOCKET_VALUE; +} - if (bBlocking) - { - cto.ReadIntervalTimeout = 0; - cto.ReadTotalTimeoutConstant = 0; - cto.ReadTotalTimeoutMultiplier = 0; - } - else - { - cto.ReadIntervalTimeout = MAXDWORD; - cto.ReadTotalTimeoutConstant = 0; - cto.ReadTotalTimeoutMultiplier = 0; - } +ssize_t CSerialSocket::Write(void* data, size_t len) +{ + return IsOpen() ? SerialSocketWrite(m_socket, &m_iError, data, len) : -1; +} - if (!SetCommTimeouts(m_handle, &cto)) - { - m_error = "SetCommTimeouts failed"; - FormatWindowsError(GetLastError(), m_error); - return false; - } +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 true; + return IsOpen() && SetTimeouts(m_socket, &m_iError, dwTimeoutMs) ? + SerialSocketRead(m_socket, &m_iError, data, len, iTimeoutMs) : + -1; } -void CSerialPort::Close(void) +bool CSerialSocket::Open(uint64_t iTimeoutMs /* = 0 */) { - if (m_bIsOpen) + iTimeoutMs = 0; + if (IsOpen()) + return false; + + std::string strComPath = "\\\\.\\" + m_strName; + CLockObject lock(m_mutex); + m_socket = CreateFile(strComPath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + if (m_socket == INVALID_HANDLE_VALUE) { - CloseHandle(m_handle); - m_bIsOpen = false; + m_strError = "Unable to open COM port"; + FormatWindowsError(GetLastError(), m_strError); + return false; } -} - -int CSerialPort::Write(uint8_t* data, int len) -{ - DWORD iBytesWritten = 0; - if (!m_bIsOpen) - return -1; - if (!WriteFile(m_handle, data, len, &iBytesWritten, NULL)) + COMMCONFIG commConfig = {0}; + DWORD dwSize = sizeof(commConfig); + commConfig.dwSize = dwSize; + if (GetDefaultCommConfig(strComPath.c_str(), &commConfig,&dwSize)) + { + if (!SetCommConfig(m_socket, &commConfig,dwSize)) + { + m_strError = "unable to set default config"; + FormatWindowsError(GetLastError(), m_strError); + } + } + else { - m_error = "Error while writing to COM port"; - FormatWindowsError(GetLastError(), m_error); - return -1; + m_strError = "unable to get default config"; + FormatWindowsError(GetLastError(), m_strError); } - return (int) iBytesWritten; -} + if (!SetupComm(m_socket, 64, 64)) + { + m_strError = "unable to set up the com port"; + FormatWindowsError(GetLastError(), m_strError); + } -int CSerialPort::Read(uint8_t* data, int len, int iTimeoutMs /* = -1 */) -{ - DWORD iBytesRead = 0; - if (m_handle == 0) + if (!SetBaudRate(m_iBaudrate)) { - m_error = "Error while reading from COM port: invalid handle"; - return -1; + m_strError = "unable to set baud rate"; + FormatWindowsError(GetLastError(), m_strError); + Close(); + return false; } - if(!ReadFile(m_handle, data, len, &iBytesRead, NULL) != 0) + if (!SetTimeouts(m_socket, &m_iError, 0)) { - m_error = "unable to read from device"; - FormatWindowsError(GetLastError(), m_error); - iBytesRead = -1; + m_strError = "unable to set timeouts"; + FormatWindowsError(GetLastError(), m_strError); + Close(); + return false; } - return (int) iBytesRead; + m_bIsOpen = true; + return m_bIsOpen; } -bool CSerialPort::SetBaudRate(int baudrate) +bool CSerialSocket::SetBaudRate(uint32_t baudrate) { - m_iBaudrate = baudrate; + int32_t rate = IntToBaudrate(baudrate); + if (rate < 0) + m_iBaudrate = baudrate > 0 ? baudrate : 0; + else + m_iBaudrate = rate; DCB dcb; memset(&dcb,0,sizeof(dcb)); @@ -216,31 +194,26 @@ bool CSerialPort::SetBaudRate(int 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_error = "SetCommState failed"; - FormatWindowsError(GetLastError(), m_error); + m_strError = "SetCommState failed"; + FormatWindowsError(GetLastError(), m_strError); return false; } return true; } - -bool CSerialPort::IsOpen() const -{ - return m_bIsOpen; -}