updated copyright messages for 2013
[deb_libcec.git] / src / lib / platform / windows / serialport.cpp
index 443b426b2fd9c9e174e830b00e1ece7b5ade7961..e1cec66d83ce10c2cdc73e56202c1989aa991278 100644 (file)
@@ -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-2013 Pulse-Eight Limited.  All rights reserved.
  * libCEC(R) is an original work, containing original code.
  *
  * libCEC(R) is a trademark of Pulse-Eight Limited.
  *     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,167 +49,142 @@ 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, uint32_t baudrate, uint8_t databits, uint8_t stopbits, uint8_t parity)
-{
-  CLockObject lock(&m_mutex);
-  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;
-
-  COMMTIMEOUTS cto;
-  if (!GetCommTimeouts(m_handle, &cto))
-  {
-    m_error = "GetCommTimeouts failed";
-    FormatWindowsError(GetLastError(), m_error);
-    return false;
-  }
+  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;
-  }
+void CSerialSocket::Shutdown(void)
+{
+  if (IsOpen())
+    SerialSocketClose(m_socket);
+  m_socket = INVALID_SERIAL_SOCKET_VALUE;
+}
 
-  if (!SetCommTimeouts(m_handle, &cto))
+ssize_t CSerialSocket::Write(void* data, size_t len)
+{
+  if (IsOpen())
   {
-    m_error = "SetCommTimeouts failed";
-    FormatWindowsError(GetLastError(), m_error);
-    return false;
+    ssize_t iReturn = SerialSocketWrite(m_socket, &m_iError, data, len);
+    if (iReturn != (ssize_t)len)
+    {
+      m_strError = "unable to write to the serial port";
+      FormatWindowsError(GetLastError(), m_strError);
+    }
+    return iReturn;
   }
-
-  return true;
+  return -1;
 }
 
-void CSerialPort::Close(void)
+ssize_t CSerialSocket::Read(void* data, size_t len, uint64_t iTimeoutMs /* = 0 */)
 {
-  CLockObject lock(&m_mutex);
-  if (m_bIsOpen)
-  {
-    CloseHandle(m_handle);
-    m_bIsOpen = false;
-  }
+  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;
 }
 
-int8_t CSerialPort::Write(const cec_frame &data)
+bool CSerialSocket::Open(uint64_t iTimeoutMs /* = 0 */)
 {
-  CLockObject lock(&m_mutex);
-  DWORD iBytesWritten = 0;
-  if (!m_bIsOpen)
-    return -1;
+  iTimeoutMs = 0;
+  if (IsOpen())
+    return false;
 
-  if (!WriteFile(m_handle, data.data, data.size, &iBytesWritten, NULL))
+  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)
   {
-    m_error = "Error while writing to COM port";
-    FormatWindowsError(GetLastError(), m_error);
-    return -1;
+    m_strError = "Unable to open COM port";
+    FormatWindowsError(GetLastError(), m_strError);
+    return false;
   }
 
-  return (int8_t)iBytesWritten;
-}
+  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_strError = "unable to get default config";
+    FormatWindowsError(GetLastError(), m_strError);
+  }
 
-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)
+  if (!SetupComm(m_socket, 64, 64))
   {
-    m_error = "Error while reading from COM port: invalid handle";
-    return iReturn;
+    m_strError = "unable to set up the com port";
+    FormatWindowsError(GetLastError(), m_strError);
   }
 
-  if(!ReadFile(m_handle, data, len, &iBytesRead, NULL) != 0)
+  if (!SetBaudRate(m_iBaudrate))
   {
-    m_error = "unable to read from device";
-    FormatWindowsError(GetLastError(), m_error);
-    iReturn = -1;
+    m_strError = "unable to set baud rate";
+    FormatWindowsError(GetLastError(), m_strError);
+    Close();
+    return false;
   }
-  else
+
+  if (!SetTimeouts(m_socket, &m_iError, 0))
   {
-    iReturn = (int32_t) iBytesRead;
+    m_strError = "unable to set timeouts";
+    FormatWindowsError(GetLastError(), m_strError);
+    Close();
+    return false;
   }
 
-  return iReturn;
+  m_strError.clear();
+  m_bIsOpen = true;
+  return m_bIsOpen;
 }
 
-bool CSerialPort::SetBaudRate(uint32_t baudrate)
+bool CSerialSocket::SetBaudRate(uint32_t baudrate)
 {
   int32_t rate = IntToBaudrate(baudrate);
   if (rate < 0)
@@ -229,32 +205,26 @@ 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_error = "SetCommState failed";
-    FormatWindowsError(GetLastError(), m_error);
+    m_strError = "SetCommState failed";
+    FormatWindowsError(GetLastError(), m_strError);
     return false;
   }
 
   return true;
 }
-
-bool CSerialPort::IsOpen()
-{
-  CLockObject lock(&m_mutex);
-  return m_bIsOpen;
-}