cec: clean up lib/platform
authorLars Op den Kamp <lars@opdenkamp.eu>
Tue, 31 Jan 2012 01:33:42 +0000 (02:33 +0100)
committerLars Op den Kamp <lars@opdenkamp.eu>
Tue, 31 Jan 2012 15:28:20 +0000 (16:28 +0100)
19 files changed:
project/libcec.vcxproj
project/libcec.vcxproj.filters
project/testclient.vcxproj
project/testclient.vcxproj.filters
src/lib/CECProcessor.cpp
src/lib/adapter/AdapterCommunication.cpp
src/lib/adapter/AdapterCommunication.h
src/lib/implementations/CECCommandHandler.cpp
src/lib/platform/posix/os-socket.h
src/lib/platform/posix/os-tcp.h [deleted file]
src/lib/platform/posix/os-types.h
src/lib/platform/posix/serialport.cpp
src/lib/platform/sockets/serialport.h
src/lib/platform/sockets/socket.h
src/lib/platform/sockets/tcp.h
src/lib/platform/windows/os-socket.h
src/lib/platform/windows/os-tcp.h [deleted file]
src/lib/platform/windows/os-types.h
src/lib/platform/windows/serialport.cpp

index 9c4c8962a808aad2c28f93308d7f420d1d430f48..d667d14be4dae736396e05eb25acb3c13a821637 100644 (file)
@@ -49,9 +49,9 @@
     <ClInclude Include="..\src\lib\platform\util\StdString.h" />
     <ClInclude Include="..\src\lib\platform\util\timeutils.h" />
     <ClInclude Include="..\src\lib\platform\windows\os-socket.h" />
-    <ClInclude Include="..\src\lib\platform\windows\os-tcp.h" />
     <ClInclude Include="..\src\lib\platform\windows\os-threads.h" />
     <ClInclude Include="..\src\lib\platform\windows\os-types.h" />
+    <ClInclude Include="..\src\lib\platform\windows\stdint.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\src\lib\adapter\AdapterCommunication.cpp" />
index 511d05250d2fa3011c5eb12159a2ca947a01ed5d..37865049c307ba9d3da1a69cb0c4bb49399066af 100644 (file)
@@ -1,9 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
-    <Filter Include="platform">
-      <UniqueIdentifier>{cc48ddc0-be11-43ec-a805-3a9434f443ed}</UniqueIdentifier>
-    </Filter>
     <Filter Include="exports">
       <UniqueIdentifier>{01b9c84a-dcfe-4bdc-b983-69e3e3929b0f}</UniqueIdentifier>
     </Filter>
     <Filter Include="devices">
       <UniqueIdentifier>{bfc43a58-636d-4c1a-b191-486cb8509c7c}</UniqueIdentifier>
     </Filter>
-    <Filter Include="platform\windows">
-      <UniqueIdentifier>{fa3d5953-d288-45e9-93f4-8419e6b701c7}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="platform\threads">
-      <UniqueIdentifier>{38a27e9e-86ad-46f6-a4fb-e1e524267b74}</UniqueIdentifier>
-    </Filter>
     <Filter Include="adapter">
       <UniqueIdentifier>{51614b77-8a0e-47a8-8500-5beb0fd12d49}</UniqueIdentifier>
     </Filter>
-    <Filter Include="platform\util">
-      <UniqueIdentifier>{4e963de7-5c42-40a0-9c81-bb112d5a24f9}</UniqueIdentifier>
+    <Filter Include="platform">
+      <UniqueIdentifier>{7d05b1b5-e728-4f9e-b78f-d63cac4ded8e}</UniqueIdentifier>
     </Filter>
     <Filter Include="platform\sockets">
-      <UniqueIdentifier>{e3945145-efa2-4393-b201-f50e1e775008}</UniqueIdentifier>
+      <UniqueIdentifier>{6cfe4bad-ed3a-4a16-8c59-4489089f5fe5}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="platform\util">
+      <UniqueIdentifier>{39a56ebf-ba93-4e7b-bf72-2f57b99a1ee1}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="platform\threads">
+      <UniqueIdentifier>{be183456-d61e-4283-b642-fe25ed71e9c5}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="platform\windows">
+      <UniqueIdentifier>{65c4a590-4577-40e4-91ad-339e20b99ebe}</UniqueIdentifier>
     </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\src\lib\devices\CECTV.h">
       <Filter>devices</Filter>
     </ClInclude>
-    <ClInclude Include="..\src\lib\platform\os.h">
-      <Filter>platform</Filter>
-    </ClInclude>
-    <ClInclude Include="..\src\lib\platform\windows\os-threads.h">
-      <Filter>platform\windows</Filter>
-    </ClInclude>
-    <ClInclude Include="..\src\lib\platform\windows\os-types.h">
-      <Filter>platform\windows</Filter>
-    </ClInclude>
-    <ClInclude Include="..\src\lib\platform\threads\mutex.h">
-      <Filter>platform\threads</Filter>
-    </ClInclude>
-    <ClInclude Include="..\src\lib\platform\threads\threads.h">
-      <Filter>platform\threads</Filter>
-    </ClInclude>
     <ClInclude Include="..\src\lib\adapter\AdapterCommunication.h">
       <Filter>adapter</Filter>
     </ClInclude>
     <ClInclude Include="..\src\lib\adapter\AdapterMessage.h">
       <Filter>adapter</Filter>
     </ClInclude>
-    <ClInclude Include="..\src\lib\platform\util\StdString.h">
+    <ClInclude Include="..\src\lib\platform\os.h">
+      <Filter>platform</Filter>
+    </ClInclude>
+    <ClInclude Include="..\src\lib\platform\sockets\serialport.h">
+      <Filter>platform\sockets</Filter>
+    </ClInclude>
+    <ClInclude Include="..\src\lib\platform\sockets\socket.h">
+      <Filter>platform\sockets</Filter>
+    </ClInclude>
+    <ClInclude Include="..\src\lib\platform\sockets\tcp.h">
+      <Filter>platform\sockets</Filter>
+    </ClInclude>
+    <ClInclude Include="..\src\lib\platform\util\baudrate.h">
       <Filter>platform\util</Filter>
     </ClInclude>
     <ClInclude Include="..\src\lib\platform\util\buffer.h">
       <Filter>platform\util</Filter>
     </ClInclude>
+    <ClInclude Include="..\src\lib\platform\util\StdString.h">
+      <Filter>platform\util</Filter>
+    </ClInclude>
     <ClInclude Include="..\src\lib\platform\util\timeutils.h">
       <Filter>platform\util</Filter>
     </ClInclude>
-    <ClInclude Include="..\src\lib\platform\sockets\serialport.h">
-      <Filter>platform\sockets</Filter>
+    <ClInclude Include="..\src\lib\platform\threads\mutex.h">
+      <Filter>platform\threads</Filter>
     </ClInclude>
-    <ClInclude Include="..\src\lib\platform\sockets\socket.h">
-      <Filter>platform\sockets</Filter>
+    <ClInclude Include="..\src\lib\platform\threads\threads.h">
+      <Filter>platform\threads</Filter>
     </ClInclude>
     <ClInclude Include="..\src\lib\platform\windows\os-socket.h">
       <Filter>platform\windows</Filter>
     </ClInclude>
-    <ClInclude Include="..\src\lib\platform\util\baudrate.h">
-      <Filter>platform\util</Filter>
+    <ClInclude Include="..\src\lib\platform\windows\os-threads.h">
+      <Filter>platform\windows</Filter>
     </ClInclude>
-    <ClInclude Include="..\src\lib\platform\sockets\tcp.h">
-      <Filter>platform\sockets</Filter>
+    <ClInclude Include="..\src\lib\platform\windows\os-types.h">
+      <Filter>platform\windows</Filter>
     </ClInclude>
-    <ClInclude Include="..\src\lib\platform\windows\os-tcp.h">
+    <ClInclude Include="..\src\lib\platform\windows\stdint.h">
       <Filter>platform\windows</Filter>
     </ClInclude>
   </ItemGroup>
index 0db6eb2e9d717dba33a74abaddb1ba1d81a6b133..fb1957290a362c2ea309f2c9388f09baa73f1292 100644 (file)
   <ItemGroup>
     <ClInclude Include="..\include\cec.h" />
     <ClInclude Include="..\include\cecloader.h" />
-    <ClInclude Include="..\src\lib\platform\os.h" />
-    <ClInclude Include="..\src\lib\platform\threads\mutex.h" />
-    <ClInclude Include="..\src\lib\platform\threads\threads.h" />
-    <ClInclude Include="..\src\lib\platform\timeutils.h" />
-    <ClInclude Include="..\src\lib\platform\windows\dlfcn-win32.h" />
-    <ClInclude Include="..\src\lib\platform\windows\os-threads.h" />
-    <ClInclude Include="..\src\lib\platform\windows\os-types.h" />
   </ItemGroup>
   <ItemGroup>
-    <ClCompile Include="..\src\lib\platform\windows\dlfcn-win32.cpp" />
     <ClCompile Include="..\src\testclient\main.cpp" />
   </ItemGroup>
   <ItemGroup>
index 45e1fe0ece70c9e6c66d01c962bc453cb0913a59..70acf3d3041ea6202fe042add81dbe2caf3622f8 100644 (file)
@@ -7,12 +7,6 @@
     <Filter Include="platform">
       <UniqueIdentifier>{f08c0a80-22d9-4bdd-90de-b9cf5fa88f99}</UniqueIdentifier>
     </Filter>
-    <Filter Include="platform\threads">
-      <UniqueIdentifier>{fb28e188-b2a5-48d3-9010-b56024b19850}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="platform\windows">
-      <UniqueIdentifier>{a8b22b54-3252-44fb-a499-e42f9bac0e15}</UniqueIdentifier>
-    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\include\cec.h">
     <ClInclude Include="..\include\cecloader.h">
       <Filter>exports</Filter>
     </ClInclude>
-    <ClInclude Include="..\src\lib\platform\os.h">
-      <Filter>platform</Filter>
-    </ClInclude>
-    <ClInclude Include="..\src\lib\platform\timeutils.h">
-      <Filter>platform</Filter>
-    </ClInclude>
-    <ClInclude Include="..\src\lib\platform\windows\dlfcn-win32.h">
-      <Filter>platform\windows</Filter>
-    </ClInclude>
-    <ClInclude Include="..\src\lib\platform\windows\os-threads.h">
-      <Filter>platform\windows</Filter>
-    </ClInclude>
-    <ClInclude Include="..\src\lib\platform\windows\os-types.h">
-      <Filter>platform\windows</Filter>
-    </ClInclude>
-    <ClInclude Include="..\src\lib\platform\threads\mutex.h">
-      <Filter>platform\threads</Filter>
-    </ClInclude>
-    <ClInclude Include="..\src\lib\platform\threads\threads.h">
-      <Filter>platform\threads</Filter>
-    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\src\testclient\main.cpp" />
-    <ClCompile Include="..\src\lib\platform\windows\dlfcn-win32.cpp">
-      <Filter>platform\windows</Filter>
-    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="testclient.rc" />
index b54426cb5d255342fcee9b1bee435c1f26dda536..6faf72c5e5b8ae3e8890024184da2115e9bf8d32 100644 (file)
@@ -54,13 +54,13 @@ CCECProcessor::CCECProcessor(CLibCEC *controller, const char *strDeviceName, cec
     m_iBaseDevice((cec_logical_address)CEC_DEFAULT_BASE_DEVICE),
     m_lastInitiator(CECDEVICE_UNKNOWN),
     m_strDeviceName(strDeviceName),
+    m_communication(NULL),
     m_controller(controller),
     m_bMonitor(false),
     m_iStandardLineTimeout(3),
     m_iRetryLineTimeout(3),
     m_iLastTransmission(0)
 {
-  m_communication = new CAdapterCommunication(this);
   m_logicalAddresses.Clear();
   m_logicalAddresses.Set(iLogicalAddress);
   m_types.clear();
@@ -75,13 +75,13 @@ CCECProcessor::CCECProcessor(CLibCEC *controller, const char *strDeviceName, con
     m_iBaseDevice((cec_logical_address)CEC_DEFAULT_BASE_DEVICE),
     m_strDeviceName(strDeviceName),
     m_types(types),
+    m_communication(NULL),
     m_controller(controller),
     m_bMonitor(false),
     m_iStandardLineTimeout(3),
     m_iRetryLineTimeout(3),
     m_iLastTransmission(0)
 {
-  m_communication = new CAdapterCommunication(this);
   m_logicalAddresses.Clear();
   for (int iPtr = 0; iPtr < 16; iPtr++)
   {
@@ -133,12 +133,14 @@ bool CCECProcessor::OpenConnection(const char *strPort, uint16_t iBaudRate, uint
 {
   bool bReturn(false);
   CLockObject lock(m_mutex);
-  if (!m_communication)
+  if (m_communication)
   {
-    CLibCEC::AddLog(CEC_LOG_ERROR, "no connection handler found");
+    CLibCEC::AddLog(CEC_LOG_ERROR, "existing connection handler found");
     return bReturn;
   }
 
+  m_communication = new CAdapterCommunication(this, strPort, iBaudRate);
+
   /* check for an already opened connection */
   if (m_communication->IsOpen())
   {
@@ -152,7 +154,7 @@ bool CCECProcessor::OpenConnection(const char *strPort, uint16_t iBaudRate, uint
   bool bConnected(false), bPinged(false);
 
   /* open a new connection */
-  while (iNow < iTarget && (bConnected = m_communication->Open(strPort, iBaudRate, iTimeoutMs)) == false)
+  while (iNow < iTarget && (bConnected = m_communication->Open(iTimeoutMs)) == false)
   {
     CLibCEC::AddLog(CEC_LOG_ERROR, "could not open a connection (try %d)", ++iConnectTry);
     Sleep(500);
@@ -423,9 +425,7 @@ void *CCECProcessor::Process(void)
     {
       CLockObject lock(m_mutex);
       if (m_commandBuffer.Pop(command))
-      {
         bParseFrame = true;
-      }
       else if (m_communication->IsOpen() && m_communication->Read(msg, 50))
       {
         if ((bParseFrame = (ParseMessage(msg) && !IsStopped())) == true)
index cd112c21e0f2263175a33d098d7c862610998c3f..c0f9ea165a98ebb1823a3cd6248cebf0309c22d3 100644 (file)
@@ -42,13 +42,13 @@ using namespace std;
 using namespace CEC;
 using namespace PLATFORM;
 
-CAdapterCommunication::CAdapterCommunication(CCECProcessor *processor) :
+CAdapterCommunication::CAdapterCommunication(CCECProcessor *processor, const char *strPort, uint16_t iBaudRate /* = 38400 */) :
     m_port(NULL),
     m_processor(processor),
     m_iLineTimeout(0),
     m_iFirmwareVersion(CEC_FW_VERSION_UNKNOWN)
 {
-  m_port = new PLATFORM::CSerialPort;
+  m_port = new PLATFORM::CSerialPort(strPort, iBaudRate);
 }
 
 CAdapterCommunication::~CAdapterCommunication(void)
@@ -62,7 +62,7 @@ CAdapterCommunication::~CAdapterCommunication(void)
   }
 }
 
-bool CAdapterCommunication::Open(const char *strPort, uint16_t iBaudRate /* = 38400 */, uint32_t iTimeoutMs /* = 10000 */)
+bool CAdapterCommunication::Open(uint32_t iTimeoutMs /* = 10000 */)
 {
   uint64_t iNow = GetTimeMs();
   uint64_t iTimeout = iNow + iTimeoutMs;
@@ -85,9 +85,9 @@ bool CAdapterCommunication::Open(const char *strPort, uint16_t iBaudRate /* = 38
   bool bConnected(false);
   while (!bConnected && iNow < iTimeout)
   {
-    if ((bConnected = m_port->Open(strPort, iBaudRate)) == false)
+    if ((bConnected = m_port->Open(iTimeout)) == false)
     {
-      strError.Format("error opening serial port '%s': %s", strPort, m_port->GetError().c_str());
+      strError.Format("error opening serial port '%s': %s", m_port->GetName().c_str(), m_port->GetError().c_str());
       Sleep(250);
       iNow = GetTimeMs();
     }
@@ -439,10 +439,10 @@ bool CAdapterCommunication::WaitForAck(CCECAdapterMessage &message)
   return bTransmitSucceeded && !bError;
 }
 
-void CAdapterCommunication::AddData(uint8_t *data, uint8_t iLen)
+void CAdapterCommunication::AddData(uint8_t *data, size_t iLen)
 {
   CLockObject lock(m_mutex);
-  for (uint8_t iPtr = 0; iPtr < iLen; iPtr++)
+  for (size_t iPtr = 0; iPtr < iLen; iPtr++)
     m_inBuffer.Push(data[iPtr]);
 
   m_rcvCondition.Signal();
@@ -450,8 +450,8 @@ void CAdapterCommunication::AddData(uint8_t *data, uint8_t iLen)
 
 bool CAdapterCommunication::ReadFromDevice(uint32_t iTimeout)
 {
-  int32_t iBytesRead;
-  uint8_t buff[1024];
+  ssize_t iBytesRead;
+  uint8_t buff[256];
   if (!m_port)
     return false;
 
@@ -459,13 +459,13 @@ bool CAdapterCommunication::ReadFromDevice(uint32_t iTimeout)
   iBytesRead = m_port->Read(buff, sizeof(buff), iTimeout);
   if (iBytesRead < 0 || iBytesRead > 256)
   {
-    CStdString strError;
-    strError.Format("error reading from serial port: %s", m_port->GetError().c_str());
-    CLibCEC::AddLog(CEC_LOG_ERROR, strError);
+    CLibCEC::AddLog(CEC_LOG_ERROR, "error reading from serial port: %s", m_port->GetError().c_str());
     return false;
   }
   else if (iBytesRead > 0)
-    AddData(buff, (uint8_t) iBytesRead);
+  {
+    AddData(buff, iBytesRead);
+  }
 
   return iBytesRead > 0;
 }
@@ -474,7 +474,7 @@ void CAdapterCommunication::SendMessageToAdapter(CCECAdapterMessage *msg)
 {
   CLockObject adapterLock(m_mutex);
   CLockObject lock(msg->mutex);
-  if (m_port->Write(msg->packet.data, msg->Size()) != (int32_t) msg->Size())
+  if (m_port->Write(msg->packet.data, msg->Size()) != (ssize_t) msg->Size())
   {
     CStdString strError;
     strError.Format("error writing to serial port: %s", m_port->GetError().c_str());
index e8dab2a6dba3d3d96e2978b4b06e92696c9891a6..54f30cef3265b8ff32d43b0f6f3f236e3632d38c 100644 (file)
@@ -38,7 +38,7 @@
 
 namespace PLATFORM
 {
-  class CSerialPort;
+  class ISocket;
 }
 
 namespace CEC
@@ -49,10 +49,10 @@ namespace CEC
   class CAdapterCommunication : private PLATFORM::CThread
   {
   public:
-    CAdapterCommunication(CCECProcessor *processor);
+    CAdapterCommunication(CCECProcessor *processor, const char *strPort, uint16_t iBaudRate = 38400);
     virtual ~CAdapterCommunication();
 
-    bool Open(const char *strPort, uint16_t iBaudRate = 38400, uint32_t iTimeoutMs = 10000);
+    bool Open(uint32_t iTimeoutMs = 10000);
     bool Read(CCECAdapterMessage &msg, uint32_t iTimeout = 1000);
     bool Write(CCECAdapterMessage *data);
     void Close(void);
@@ -72,10 +72,10 @@ namespace CEC
   private:
     void SendMessageToAdapter(CCECAdapterMessage *msg);
     void WriteNextCommand(void);
-    void AddData(uint8_t *data, uint8_t iLen);
+    void AddData(uint8_t *data, size_t iLen);
     bool ReadFromDevice(uint32_t iTimeout);
 
-    PLATFORM::CSerialPort *                      m_port;
+    PLATFORM::ISocket *                          m_port;
     CCECProcessor *                              m_processor;
     PLATFORM::SyncedBuffer<uint8_t>              m_inBuffer;
     PLATFORM::SyncedBuffer<CCECAdapterMessage *> m_outBuffer;
index 5fe3ebae6156aabd4c35812e882dffff33431e44..331315d77e7870f6a9e46a9058c5773dc166c5fd 100644 (file)
@@ -959,7 +959,7 @@ bool CCECCommandHandler::Transmit(cec_command &command, bool bExpectResponse /*
     while (!bReturn && ++iTries <= iMaxTries)
     {
       m_expectedResponse = expectedResponse;
-      if ((bReturn = m_processor->Transmit(command)))
+      if ((bReturn = m_processor->Transmit(command)) == true)
       {
         CLibCEC::AddLog(CEC_LOG_DEBUG, "command transmitted");
         if (bExpectResponse)
index 9d557c1b4583a9bc631642f60e38036910f04cef..468cc3deb4dfa075a60bff9cd2ca899e8ac0d5d8 100644 (file)
 #include "../util/timeutils.h"
 #include <stdio.h>
 #include <fcntl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <poll.h>
 
 namespace PLATFORM
 {
+  // Standard sockets
+  //@{
   inline void SocketClose(socket_t socket)
   {
-    if (socket != INVALID_SOCKET)
+    if (socket != INVALID_SOCKET_VALUE)
       close(socket);
   }
 
   inline void SocketSetBlocking(socket_t socket, bool bSetTo)
   {
-//    return bSetTo ?
-//            fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) & ~O_NONBLOCK) == 0 :
-//            fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) | O_NONBLOCK) == 0;
-    fcntl(socket, F_SETFL, bSetTo ? FNDELAY : 0);
+    if (socket != INVALID_SOCKET_VALUE)
+    {
+      if (bSetTo)
+        fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) & ~O_NONBLOCK);
+      else
+        fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) | O_NONBLOCK);
+    }
   }
 
-  inline int64_t SocketWrite(socket_t socket, int *iError, uint8_t* data, uint32_t len)
+  inline ssize_t SocketWrite(socket_t socket, int *iError, void* data, size_t len)
   {
     fd_set port;
 
-    if (socket == -1)
+    if (socket == INVALID_SOCKET_VALUE)
     {
       *iError = EINVAL;
       return -1;
     }
 
-    int64_t iBytesWritten = 0;
+    ssize_t iBytesWritten(0);
     struct timeval *tv(NULL);
 
-    while (iBytesWritten < len)
+    while (iBytesWritten < (ssize_t)len)
     {
       FD_ZERO(&port);
       FD_SET(socket, &port);
@@ -82,7 +93,7 @@ namespace PLATFORM
         return -1;
       }
 
-      returnv = write(socket, data + iBytesWritten, len - iBytesWritten);
+      returnv = write(socket, (char*)data + iBytesWritten, len - iBytesWritten);
       if (returnv == -1)
       {
         *iError = errno;
@@ -94,15 +105,15 @@ namespace PLATFORM
     return iBytesWritten;
   }
 
-  inline int32_t SocketRead(socket_t socket, int *iError, uint8_t* data, uint32_t len, uint64_t iTimeoutMs /*= 0*/)
+  inline ssize_t SocketRead(socket_t socket, int *iError, void* data, size_t len, uint64_t iTimeoutMs /*= 0*/)
   {
     fd_set port;
     struct timeval timeout, *tv;
     int64_t iNow(0), iTarget(0);
-    int32_t iBytesRead = 0;
+    ssize_t iBytesRead(0);
     *iError = 0;
 
-    if (socket == -1)
+    if (socket == INVALID_SOCKET_VALUE)
     {
       *iError = EINVAL;
       return -1;
@@ -114,7 +125,7 @@ namespace PLATFORM
       iTarget = iNow + (int64_t) iTimeoutMs;
     }
 
-    while (iBytesRead < (int32_t) len && (iTimeoutMs == 0 || iTarget > iNow))
+    while (iBytesRead >= 0 && iBytesRead < (ssize_t)len && (iTimeoutMs == 0 || iTarget > iNow))
     {
       if (iTimeoutMs == 0)
       {
@@ -141,7 +152,7 @@ namespace PLATFORM
         break; //nothing to read
       }
 
-      returnv = read(socket, data + iBytesRead, len - iBytesRead);
+      returnv = read(socket, (char*)data + iBytesRead, len - iBytesRead);
       if (returnv == -1)
       {
         *iError = errno;
@@ -156,4 +167,155 @@ namespace PLATFORM
 
     return iBytesRead;
   }
+  //@}
+
+  // TCP
+  //@{
+  inline void TcpSocketClose(tcp_socket_t socket)
+  {
+    SocketClose(socket);
+  }
+
+  inline void TcpSocketShutdown(tcp_socket_t socket)
+  {
+    if (socket != INVALID_SOCKET_VALUE)
+      shutdown(socket, SHUT_RDWR);
+  }
+
+  inline ssize_t TcpSocketWrite(tcp_socket_t socket, int *iError, void* data, size_t len)
+  {
+    if (socket == INVALID_SOCKET_VALUE)
+    {
+      *iError = EINVAL;
+      return -1;
+    }
+
+    ssize_t iReturn = send(socket, data, len, 0);
+    if (iReturn < (ssize_t)len)
+      *iError = errno;
+    return iReturn;
+  }
+
+  inline ssize_t TcpSocketRead(tcp_socket_t socket, int *iError, void* data, size_t len, uint64_t iTimeoutMs /*= 0*/)
+  {
+    int64_t iNow(0), iTarget(0);
+    ssize_t iBytesRead(0);
+    *iError = 0;
+
+    if (socket == INVALID_SOCKET_VALUE)
+    {
+      *iError = EINVAL;
+      return -1;
+    }
+
+    if (iTimeoutMs > 0)
+    {
+      iNow    = GetTimeMs();
+      iTarget = iNow + (int64_t) iTimeoutMs;
+    }
+
+    struct pollfd fds;
+    fds.fd = socket;
+    fds.events = POLLIN;
+    fds.revents = 0;
+
+    while (iBytesRead >= 0 && iBytesRead < (ssize_t)len && (iTimeoutMs == 0 || iTarget > iNow))
+    {
+      if (iTimeoutMs > 0)
+      {
+        int iPollResult = poll(&fds, 1, iTarget - iNow);
+        if (iPollResult == 0)
+        {
+          *iError = ETIMEDOUT;
+          return -ETIMEDOUT;
+        }
+      }
+
+      ssize_t iReadResult = (iTimeoutMs > 0) ?
+          recv(socket, (char*)data + iBytesRead, len - iBytesRead, MSG_DONTWAIT) :
+          recv(socket, data, len, MSG_WAITALL);
+      if (iReadResult < 0)
+      {
+        if (errno == EAGAIN && iTimeoutMs > 0)
+          continue;
+        *iError = errno;
+        return -errno;
+      }
+      else if (iReadResult == 0 || (iReadResult != (ssize_t)len && iTimeoutMs == 0))
+      {
+        *iError = ECONNRESET;
+        return -ECONNRESET;
+      }
+
+      iBytesRead += iReadResult;
+
+      if (iTimeoutMs > 0)
+        iNow = GetTimeMs();
+    }
+
+    if (iBytesRead < (ssize_t)len)
+      *iError = ETIMEDOUT;
+    return iBytesRead;
+  }
+
+  inline bool TcpResolveAddress(const char *strHost, uint16_t iPort, int *iError, struct addrinfo **info)
+  {
+    struct   addrinfo hints;
+    char     service[33];
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family   = AF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_protocol = IPPROTO_TCP;
+    sprintf(service, "%d", iPort);
+
+    *iError = getaddrinfo(strHost, service, &hints, info);
+    return !(*iError);
+  }
+
+  inline int TcpGetSocketError(tcp_socket_t socket)
+  {
+    int iReturn(0);
+    socklen_t optLen = sizeof(socket_t);
+    getsockopt(socket, SOL_SOCKET, SO_ERROR, (void *)&iReturn, &optLen);
+    return iReturn;
+  }
+
+  inline bool TcpSetNoDelay(tcp_socket_t socket)
+  {
+    int iSetTo(1);
+    setsockopt(socket, SOL_TCP, TCP_NODELAY, &iSetTo, sizeof(iSetTo));
+    return true;
+  }
+
+  inline bool TcpConnectSocket(tcp_socket_t socket, struct addrinfo* addr, int *iError, uint64_t iTimeout = 0)
+  {
+    *iError = 0;
+    int iConnectResult = connect(socket, addr->ai_addr, addr->ai_addrlen);
+    if (iConnectResult == -1)
+    {
+      if (errno == EINPROGRESS)
+      {
+        struct pollfd pfd;
+        pfd.fd = socket;
+        pfd.events = POLLOUT;
+        pfd.revents = 0;
+
+        int iPollResult = poll(&pfd, 1, iTimeout);
+        if (iPollResult == 0)
+          *iError = ETIMEDOUT;
+        else if (iPollResult == -1)
+          *iError = errno;
+
+        socklen_t errlen = sizeof(int);
+        getsockopt(socket, SOL_SOCKET, SO_ERROR, (void *)iError, &errlen);
+      }
+      else
+      {
+        *iError = errno;
+      }
+    }
+
+    return *iError == 0;
+  }
+  //@}
 }
diff --git a/src/lib/platform/posix/os-tcp.h b/src/lib/platform/posix/os-tcp.h
deleted file mode 100644 (file)
index 86d0603..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-#pragma once
-/*
- * This file is part of the libCEC(R) library.
- *
- * 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.
- *
- * This program is dual-licensed; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *
- * Alternatively, you can license this library under a commercial license,
- * please contact Pulse-Eight Licensing for more information.
- *
- * For more information contact:
- * Pulse-Eight Licensing       <license@pulse-eight.com>
- *     http://www.pulse-eight.com/
- *     http://www.pulse-eight.net/
- */
-
-#include "../os.h"
-#include "../sockets/socket.h"
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <poll.h>
-
-namespace PLATFORM
-{
-  inline void TcpShutdownSocket(socket_t socket)
-  {
-    shutdown(socket, SHUT_RDWR);
-  }
-
-  inline int TcpGetSocketError(socket_t socket)
-  {
-    int iReturn(0);
-    socklen_t optLen = sizeof(socket_t);
-    getsockopt(socket, SOL_SOCKET, SO_ERROR, (void *)&iReturn, &optLen);
-    return iReturn;
-  }
-
-  inline bool TcpSetNoDelay(socket_t socket)
-  {
-    int iSetTo(1);
-    setsockopt(socket, SOL_TCP, TCP_NODELAY, &iSetTo, sizeof(iSetTo));
-    return true;
-  }
-
-  inline bool TcpConnectSocket(socket_t socket, struct addrinfo* addr, int *iError, uint64_t iTimeout = 0)
-  {
-    bool bConnected = (connect(socket, addr->ai_addr, addr->ai_addrlen) == 0);
-    if (!bConnected && errno == EINPROGRESS)
-    {
-      struct pollfd pfd;
-      pfd.fd = socket;
-      pfd.events = POLLOUT;
-      pfd.revents = 0;
-
-      int iPollResult = poll(&pfd, 1, iTimeout);
-      if (iPollResult == 0)
-        *iError = ETIMEDOUT;
-      else if (iPollResult == -1)
-        *iError = errno;
-      else
-        bConnected = true;
-    }
-    else
-    {
-      *iError = errno;
-    }
-
-    return bConnected;
-  }
-
-  inline bool TcpResolveAddress(const char *strHost, uint16_t iPort, int *iError, struct addrinfo **info)
-  {
-    struct   addrinfo hints;
-    char     service[33];
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_family   = AF_UNSPEC;
-    hints.ai_socktype = SOCK_STREAM;
-    hints.ai_protocol = IPPROTO_TCP;
-    sprintf(service, "%d", iPort);
-
-    *iError = getaddrinfo(strHost, service, &hints, info);
-    return !(*iError);
-  }
-}
index 2b6c50f8262499761aef11668829312d9dcc96ec..631e96508e963a9cfb1b88184e463fc80527d837 100644 (file)
@@ -47,6 +47,7 @@
 #define DECLSPEC
 
 typedef int socket_t;
-#define INVALID_SOCKET (-1)
-#define SOCKET_ERROR   (-1)
-
+typedef socket_t tcp_socket_t;
+#define INVALID_SOCKET_VALUE        (-1)
+typedef socket_t serial_socket_t;
+#define INVALID_SERIAL_SOCKET_VALUE (-1)
index 7af3d0e822a4bb8adf3a6988a193c87fe96f5a77..5557064555be90200cc2eeb7873522f6c1de9359 100644 (file)
@@ -35,6 +35,7 @@
 #include <fcntl.h>
 #include "../sockets/serialport.h"
 #include "../util/baudrate.h"
+#include "../posix/os-socket.h"
 
 #if defined(__APPLE__)
 #ifndef XCASE
 using namespace std;
 using namespace PLATFORM;
 
-CSerialPort::CSerialPort()
+void CSerialSocket::Close(void)
 {
-  m_bToStdOut = false;
+  SocketClose(m_socket);
+}
+
+void CSerialSocket::Shutdown(void)
+{
+  SocketClose(m_socket);
+}
+
+ssize_t CSerialSocket::Write(void* data, size_t len)
+{
+  return SocketWrite(m_socket, &m_iError, data, len);
+}
+
+ssize_t CSerialSocket::Read(void* data, size_t len, uint64_t iTimeoutMs /* = 0 */)
+{
+  return SocketRead(m_socket, &m_iError, data, len, iTimeoutMs);
 }
 
 //setting all this stuff up is a pain in the ass
-bool CSerialPort::Open(string name, uint32_t baudrate, uint8_t databits /* = 8 */, uint8_t stopbits /* = 1 */, uint8_t parity /* = PAR_NONE */)
+bool CSerialSocket::Open(uint64_t iTimeoutMs /* = 0 */)
 {
-  m_strName = name;
+  iTimeoutMs = 0;
   CLockObject lock(m_mutex);
 
-  if (databits < 5 || databits > 8)
+  if (m_iDatabits != SERIAL_DATA_BITS_FIVE && m_iDatabits != SERIAL_DATA_BITS_SIX &&
+      m_iDatabits != SERIAL_DATA_BITS_SEVEN && m_iDatabits != SERIAL_DATA_BITS_EIGHT)
   {
     m_strError = "Databits has to be between 5 and 8";
     return false;
   }
 
-  if (stopbits != 1 && stopbits != 2)
+  if (m_iStopbits != SERIAL_STOP_BITS_ONE && m_iStopbits != SERIAL_STOP_BITS_TWO)
   {
     m_strError = "Stopbits has to be 1 or 2";
     return false;
   }
 
-  if (parity != PAR_NONE && parity != PAR_EVEN && parity != PAR_ODD)
+  if (m_iParity != SERIAL_PARITY_NONE && m_iParity != SERIAL_PARITY_EVEN && m_iParity != SERIAL_PARITY_ODD)
   {
     m_strError = "Parity has to be none, even or odd";
     return false;
   }
 
-  m_socket = open(name.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
+  m_socket = open(m_strName.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
 
-  if (m_socket == INVALID_SOCKET)
+  if (m_socket == INVALID_SERIAL_SOCKET_VALUE)
   {
     m_strError = strerror(errno);
     return false;
@@ -89,22 +106,22 @@ bool CSerialPort::Open(string name, uint32_t baudrate, uint8_t databits /* = 8 *
 
   SocketSetBlocking(m_socket, false);
 
-  if (!SetBaudRate(baudrate))
+  if (!SetBaudRate(m_iBaudrate))
     return false;
 
   m_options.c_cflag |= (CLOCAL | CREAD);
   m_options.c_cflag &= ~HUPCL;
 
   m_options.c_cflag &= ~CSIZE;
-  if (databits == 5) m_options.c_cflag |= CS5;
-  if (databits == 6) m_options.c_cflag |= CS6;
-  if (databits == 7) m_options.c_cflag |= CS7;
-  if (databits == 8) m_options.c_cflag |= CS8;
+  if (m_iDatabits == SERIAL_DATA_BITS_FIVE)  m_options.c_cflag |= CS5;
+  if (m_iDatabits == SERIAL_DATA_BITS_SIX)   m_options.c_cflag |= CS6;
+  if (m_iDatabits == SERIAL_DATA_BITS_SEVEN) m_options.c_cflag |= CS7;
+  if (m_iDatabits == SERIAL_DATA_BITS_EIGHT) m_options.c_cflag |= CS8;
 
   m_options.c_cflag &= ~PARENB;
-  if (parity == PAR_EVEN || parity == PAR_ODD)
+  if (m_iParity == SERIAL_PARITY_EVEN || m_iParity == SERIAL_PARITY_ODD)
     m_options.c_cflag |= PARENB;
-  if (parity == PAR_ODD)
+  if (m_iParity == SERIAL_PARITY_ODD)
     m_options.c_cflag |= PARODD;
 
 #ifdef CRTSCTS
@@ -113,20 +130,16 @@ bool CSerialPort::Open(string name, uint32_t baudrate, uint8_t databits /* = 8 *
   m_options.c_cflag &= ~CNEW_RTSCTS;
 #endif
 
-  if (stopbits == 1) m_options.c_cflag &= ~CSTOPB;
+  if (m_iStopbits == SERIAL_STOP_BITS_ONE) m_options.c_cflag &= ~CSTOPB;
   else m_options.c_cflag |= CSTOPB;
   
   //I guessed a little here
   m_options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG | XCASE | ECHOK | ECHONL | ECHOCTL | ECHOPRT | ECHOKE | TOSTOP);
 
-  if (parity == PAR_NONE)
-  {
+  if (m_iParity == SERIAL_PARITY_NONE)
     m_options.c_iflag &= ~INPCK;
-  }
   else
-  {
     m_options.c_iflag |= INPCK | ISTRIP;
-  }
 
   m_options.c_iflag &= ~(IXON | IXOFF | IXANY | BRKINT | INLCR | IGNCR | ICRNL | IUCLC | IMAXBEL);
   m_options.c_oflag &= ~(OPOST | ONLCR | OCRNL);
@@ -138,11 +151,12 @@ bool CSerialPort::Open(string name, uint32_t baudrate, uint8_t databits /* = 8 *
   }
   
   SocketSetBlocking(m_socket, true);
+  m_bIsOpen = true;
 
   return true;
 }
 
-bool CSerialPort::SetBaudRate(uint32_t baudrate)
+bool CSerialSocket::SetBaudRate(uint32_t baudrate)
 {
   int rate = IntToBaudrate(baudrate);
   if (rate == -1)
@@ -152,7 +166,7 @@ bool CSerialPort::SetBaudRate(uint32_t baudrate)
     m_strError = buff;
     return false;
   }
-  
+
   //get the current port attributes
   if (tcgetattr(m_socket, &m_options) != 0)
   {
@@ -165,7 +179,7 @@ bool CSerialPort::SetBaudRate(uint32_t baudrate)
     m_strError = strerror(errno);
     return false;
   }
-  
+
   if (cfsetospeed(&m_options, rate) != 0)
   {
     m_strError = strerror(errno);
index 7b0a3a0be8af8b9764c74e2ca4f68d5f94871f26..c74cc05d38ec967dfef8923af15ff466158beb09 100644 (file)
 
 namespace PLATFORM
 {
-  #define PAR_NONE 0
-  #define PAR_EVEN 1
-  #define PAR_ODD  2
+  enum SerialParity
+  {
+    SERIAL_PARITY_NONE = 0,
+    SERIAL_PARITY_EVEN,
+    SERIAL_PARITY_ODD
+  };
+
+  enum SerialStopBits
+  {
+    SERIAL_STOP_BITS_ONE = 1,
+    SERIAL_STOP_BITS_TWO = 2
+  };
+
+  enum SerialDataBits
+  {
+    SERIAL_DATA_BITS_FIVE  = 5,
+    SERIAL_DATA_BITS_SIX   = 6,
+    SERIAL_DATA_BITS_SEVEN = 7,
+    SERIAL_DATA_BITS_EIGHT = 8
+  };
 
-  class CSerialPort : public CSocket
+  class CSerialSocket : public CCommonSocket<serial_socket_t>
   {
     public:
-      CSerialPort(void);
-      virtual ~CSerialPort(void) {}
+      CSerialSocket(const CStdString &strName, uint32_t iBaudrate, SerialDataBits iDatabits = SERIAL_DATA_BITS_EIGHT, SerialStopBits iStopbits = SERIAL_STOP_BITS_ONE, SerialParity iParity = SERIAL_PARITY_NONE) :
+          CCommonSocket<serial_socket_t>(INVALID_SERIAL_SOCKET_VALUE, strName),
+          m_bIsOpen(false),
+          m_iBaudrate(iBaudrate),
+          m_iDatabits(iDatabits),
+          m_iStopbits(iStopbits),
+          m_iParity(iParity) {}
 
-      bool Open(std::string name, uint32_t baudrate, uint8_t databits = 8, uint8_t stopbits = 1, uint8_t parity = PAR_NONE);
+      virtual ~CSerialSocket(void) {}
 
-      CStdString GetName(void) const
+      virtual bool Open(uint64_t iTimeoutMs = 0);
+      virtual void Close(void);
+      virtual void Shutdown(void);
+      virtual ssize_t Write(void* data, size_t len);
+      virtual ssize_t Read(void* data, size_t len, uint64_t iTimeoutMs = 0);
+
+      virtual bool IsOpen(void)
       {
-        CStdString strName;
-        strName = m_strName;
-        return strName;
+        return m_socket != INVALID_SERIAL_SOCKET_VALUE &&
+            m_bIsOpen;
       }
 
-    #ifdef __WINDOWS__
-      virtual bool IsOpen(void);
-      virtual void Close(void);
-      virtual int64_t Write(uint8_t* data, uint32_t len);
-      virtual int32_t Read(uint8_t* data, uint32_t len, uint64_t iTimeoutMs = 0);
-    #endif
+      virtual bool SetBaudRate(uint32_t baudrate);
 
-    private:
-      bool SetBaudRate(uint32_t baudrate);
+    protected:
+  #ifndef __WINDOWS__
+      struct termios  m_options;
+  #endif
 
-    private:
-    #ifdef __WINDOWS__
-      void FormatWindowsError(int iErrorCode, CStdString &strMessage);
-      bool SetTimeouts(bool bBlocking);
+      bool            m_bIsOpen;
+      uint32_t        m_iBaudrate;
+      SerialDataBits  m_iDatabits;
+      SerialStopBits  m_iStopbits;
+      SerialParity    m_iParity;
+  };
 
-      HANDLE                m_handle; 
-      bool                  m_bIsOpen;
-      uint32_t              m_iBaudrate;
-      uint8_t               m_iDatabits;
-      uint8_t               m_iStopbits;
-      uint8_t               m_iParity;
-      int64_t               m_iTimeout;
-      SyncedBuffer<uint8_t> m_buffer;
-      HANDLE                m_ovHandle;
-  #else
-      struct termios     m_options;
-  #endif
-      std::string  m_strName;
-      bool         m_bToStdOut;
+  class CSerialPort : public CProtectedSocket<CSerialSocket>
+  {
+  public:
+    CSerialPort(const CStdString &strName, uint32_t iBaudrate, SerialDataBits iDatabits = SERIAL_DATA_BITS_EIGHT, SerialStopBits iStopbits = SERIAL_STOP_BITS_ONE, SerialParity iParity = SERIAL_PARITY_NONE) :
+      CProtectedSocket<CSerialSocket> (new CSerialSocket(strName, iBaudrate, iDatabits, iStopbits, iParity)) {}
+    virtual ~CSerialPort(void) {}
   };
 };
index 2e8acdbdca4de00fb7b76822b0ed36214c870d9f..388bb2d8a0d2fd13e2500207f13481ce31dfbbf9 100644 (file)
 
 namespace PLATFORM
 {
-  class CSocket : public PreventCopy
+  class ISocket : public PreventCopy
   {
-    public:
-      CSocket(void) :
-        m_socket(INVALID_SOCKET),
-        m_iError(0) {};
+  public:
+    ISocket(void) {};
+    virtual ~ISocket(void) {}
 
-      virtual ~CSocket(void)
-      {
-        Close();
-      }
+    virtual bool Open(uint64_t iTimeoutMs = 0) = 0;
+    virtual void Close(void) = 0;
+    virtual void Shutdown(void) = 0;
+    virtual bool IsOpen(void) = 0;
+    virtual ssize_t Write(void* data, size_t len) = 0;
+    virtual ssize_t Read(void* data, size_t len, uint64_t iTimeoutMs = 0) = 0;
+    virtual CStdString GetError(void) = 0;
+    virtual int GetErrorNumber(void) = 0;
+    virtual CStdString GetName(void) = 0;
+  };
 
-      virtual bool IsOpen(void)
-      {
-        CLockObject lock(m_mutex);
-        return m_socket != INVALID_SOCKET &&
-            m_socket != SOCKET_ERROR;
-      }
+  template <typename _SType>
+  class CCommonSocket : public ISocket
+  {
+  public:
+    CCommonSocket(_SType initialSocketValue, const CStdString &strName) :
+      m_socket(initialSocketValue),
+      m_strName(strName),
+      m_iError(0) {}
 
-      virtual void Close(void)
-      {
-        CLockObject lock(m_mutex);
-        SocketClose(m_socket);
-        m_socket = INVALID_SOCKET;
-        m_strError = "";
-      }
+    virtual ~CCommonSocket(void) {}
 
-      virtual int64_t Write(uint8_t* data, uint32_t len)
-      {
-        CLockObject lock(m_mutex);
-        int64_t iReturn = SocketWrite(m_socket, &m_iError, data, len);
-        m_strError = strerror(m_iError);
-        return iReturn;
-      }
+    virtual CStdString GetError(void)
+    {
+      CStdString strError;
+      strError = m_strError.IsEmpty() && m_iError != 0 ? strerror(m_iError) : m_strError;
+      return strError;
+    }
+
+    virtual int GetErrorNumber(void)
+    {
+      return m_iError;
+    }
+
+    virtual CStdString GetName(void)
+    {
+      CStdString strName;
+      strName = m_strName;
+      return strName;
+    }
+
+  protected:
+    _SType     m_socket;
+    CStdString m_strError;
+    CStdString m_strName;
+    int        m_iError;
+    CMutex     m_mutex;
+  };
+
+  template <typename _Socket>
+  class CProtectedSocket : public ISocket
+  {
+  public:
+    CProtectedSocket(_Socket *socket) :
+      m_socket(socket),
+      m_iUseCount(0) {}
+
+    virtual ~CProtectedSocket(void)
+    {
+      Close();
+      delete m_socket;
+    }
 
-      virtual int32_t Read(uint8_t* data, uint32_t len, uint64_t iTimeoutMs = 0)
+    virtual bool Open(uint64_t iTimeoutMs = 0)
+    {
+      bool bReturn(false);
+      if (m_socket && WaitReady())
       {
-        CLockObject lock(m_mutex);
-        int32_t iReturn = SocketRead(m_socket, &m_iError, data, len, iTimeoutMs);
-        m_strError = strerror(m_iError);
-        return iReturn;
+        bReturn = m_socket->Open(iTimeoutMs);
+        MarkReady();
       }
+      return bReturn;
+    }
 
-      virtual CStdString GetError(void) const
+    virtual void Close(void)
+    {
+      if (m_socket && WaitReady())
       {
-        CStdString strReturn;
-        strReturn = m_strError;
-        return strReturn;
+        m_socket->Close();
+        MarkReady();
       }
+    }
 
-      virtual int GetErrorNumber(void) const
+    virtual void Shutdown(void)
+    {
+      if (m_socket && WaitReady())
       {
-        return m_iError;
+        m_socket->Shutdown();
+        MarkReady();
       }
+    }
+
+    virtual bool IsOpen(void)
+    {
+      CLockObject lock(m_mutex);
+      return m_socket && m_socket->IsOpen();
+    }
+
+    virtual bool IsBusy(void)
+    {
+      CLockObject lock(m_mutex);
+      return m_socket && m_iUseCount > 0;
+    }
+
+    virtual int GetUseCount(void)
+    {
+      CLockObject lock(m_mutex);
+      return m_iUseCount;
+    }
+
+    virtual ssize_t Write(void* data, size_t len)
+    {
+      if (!m_socket || !WaitReady())
+        return EINVAL;
+
+      ssize_t iReturn = m_socket->Write(data, len);
+      MarkReady();
+
+      return iReturn;
+    }
+
+    virtual ssize_t Read(void* data, size_t len, uint64_t iTimeoutMs = 0)
+    {
+      if (!m_socket || !WaitReady())
+        return EINVAL;
+
+      ssize_t iReturn = m_socket->Read(data, len, iTimeoutMs);
+      MarkReady();
+
+      return iReturn;
+    }
+
+    virtual CStdString GetError(void)
+    {
+      CStdString strError;
+      CLockObject lock(m_mutex);
+      strError = m_socket ? m_socket->GetError() : "";
+      return strError;
+    }
+
+    virtual int GetErrorNumber(void)
+    {
+      CLockObject lock(m_mutex);
+      return m_socket ? m_socket->GetErrorNumber() : EINVAL;
+    }
+
+    virtual CStdString GetName(void)
+    {
+      CStdString strName;
+      CLockObject lock(m_mutex);
+      strName = m_socket ? m_socket->GetName() : "";
+      return strName;
+    }
+
+  private:
+    bool WaitReady(void)
+    {
+      CLockObject lock(m_mutex);
+      if (m_iUseCount > 0)
+        m_condition.Wait(m_mutex);
+
+      if (m_iUseCount > 0)
+        return false;
+
+      ++m_iUseCount;
+      return true;
+    }
+
+    void MarkReady(void)
+    {
+      CLockObject lock(m_mutex);
+      if (m_iUseCount > 0)
+        --m_iUseCount;
+      m_condition.Broadcast();
+    }
 
-    protected:
-      socket_t   m_socket;
-      CStdString m_strError;
-      int        m_iError;
-      CMutex     m_mutex;
+    _Socket   *m_socket;
+    CMutex     m_mutex;
+    CCondition m_condition;
+    int        m_iUseCount;
   };
 };
index ef9c418aaa82568d7b24008e0e8be5c487605add..ffc372ccacfcad10e7cb90a7d4c7aff94bfc5849 100644 (file)
 
 #include "socket.h"
 
-#if defined(__WINDOWS__)
-#include "../windows/os-tcp.h"
-#else
-#include "../posix/os-tcp.h"
-#endif
-
 using namespace std;
 
 namespace PLATFORM
 {
-  class CTcpSocket : public CSocket
+  class CTcpSocket : public CCommonSocket<tcp_socket_t>
   {
     public:
-      CTcpSocket(void) {};
+      CTcpSocket(const CStdString &strHostname, uint16_t iPort) :
+        CCommonSocket<tcp_socket_t>(INVALID_SOCKET_VALUE, strHostname),
+        m_iPort(iPort) {}
+
       virtual ~CTcpSocket(void) {}
 
-      virtual bool Open(const CStdString &strHostname, uint16_t iPort, uint64_t nTimeout)
+      virtual bool Open(uint64_t iTimeoutMs = 0)
       {
         bool bReturn(false);
         struct addrinfo *address(NULL), *addr(NULL);
-        CLockObject lock(m_mutex);
-        if (!TcpResolveAddress(strHostname.c_str(), iPort, &m_iError, &address))
+        if (!TcpResolveAddress(m_strName.c_str(), m_iPort, &m_iError, &address))
         {
           m_strError = strerror(m_iError);
           return bReturn;
@@ -62,8 +58,8 @@ namespace PLATFORM
 
         for(addr = address; !bReturn && addr; addr = addr->ai_next)
         {
-          m_socket = TcpCreateSocket(addr, &m_iError, nTimeout);
-          if (m_socket != INVALID_SOCKET && m_socket != SOCKET_ERROR)
+          m_socket = TcpCreateSocket(addr, &m_iError, iTimeoutMs);
+          if (m_socket != INVALID_SOCKET_VALUE)
             bReturn = true;
           else
             m_strError = strerror(m_iError);
@@ -73,34 +69,62 @@ namespace PLATFORM
         return bReturn;
       }
 
+      virtual void Close(void)
+      {
+        TcpSocketClose(m_socket);
+        m_socket = INVALID_SOCKET_VALUE;
+      }
+
       virtual void Shutdown(void)
       {
-        CLockObject lock(m_mutex);
-        if (m_socket != INVALID_SOCKET && m_socket != SOCKET_ERROR)
-          TcpShutdownSocket(m_socket);
-        m_socket = INVALID_SOCKET;
-        m_strError = "";
+        TcpSocketShutdown(m_socket);
+        m_socket = INVALID_SOCKET_VALUE;
+      }
+
+      virtual ssize_t Write(void* data, size_t len)
+      {
+        return TcpSocketWrite(m_socket, &m_iError, data, len);
+      }
+
+      virtual ssize_t Read(void* data, size_t len, uint64_t iTimeoutMs = 0)
+      {
+        return TcpSocketRead(m_socket, &m_iError, data, len, iTimeoutMs);
       }
 
-  protected:
-    virtual socket_t TcpCreateSocket(struct addrinfo* addr, int* iError, uint64_t iTimeout)
-    {
-      socket_t fdSock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
-      if (fdSock == INVALID_SOCKET || fdSock == SOCKET_ERROR)
+      virtual bool IsOpen(void)
       {
-        *iError = errno;
-        return (socket_t)SOCKET_ERROR;
+        return m_socket != INVALID_SOCKET_VALUE;
       }
 
-      if (!TcpConnectSocket(fdSock, addr, iError, iTimeout))
+    protected:
+      virtual tcp_socket_t TcpCreateSocket(struct addrinfo* addr, int* iError, uint64_t iTimeout)
       {
-        SocketClose(fdSock);
-        return (socket_t)SOCKET_ERROR;
+        tcp_socket_t fdSock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
+        if (fdSock == INVALID_SOCKET_VALUE)
+        {
+          *iError = errno;
+          return (tcp_socket_t)INVALID_SOCKET_VALUE;
+        }
+
+        if (!TcpConnectSocket(fdSock, addr, iError, iTimeout))
+        {
+          TcpSocketClose(fdSock);
+          return (tcp_socket_t)INVALID_SOCKET_VALUE;
+        }
+
+        TcpSetNoDelay(fdSock);
+
+        return fdSock;
       }
 
-      TcpSetNoDelay(fdSock);
+      uint16_t   m_iPort;
+  };
 
-      return fdSock;
-    }
+  class CTcpConnection : public CProtectedSocket<CTcpSocket>
+  {
+  public:
+    CTcpConnection(const CStdString &strHostname, uint16_t iPort) :
+      CProtectedSocket<CTcpSocket> (new CTcpSocket(strHostname, iPort)) {}
+    virtual ~CTcpConnection(void) {}
   };
 };
index 95883e2ad96ab229460da2b21554968c85b27322..ad98edb59e5c46648abdd8131a2cc4511d787c5a 100644 (file)
@@ -64,101 +64,214 @@ namespace PLATFORM
     }
   }
 
-  inline void SocketClose(socket_t socket)
+  // Serial port
+  //@{
+  inline void SerialSocketClose(serial_socket_t socket)
   {
-    if (socket != SOCKET_ERROR && socket != INVALID_SOCKET)
-      closesocket(socket);
+    if (socket != INVALID_HANDLE_VALUE)
+      CloseHandle(socket);
   }
 
-  inline void SocketSetBlocking(socket_t socket, bool bSetTo)
+  inline ssize_t SerialSocketWrite(serial_socket_t socket, int *iError, void* data, size_t len)
   {
-    u_long nVal = bSetTo ? 1 : 0;
-    ioctlsocket(socket, FIONBIO, &nVal);
+    DWORD iBytesWritten(0);
+    if (socket != INVALID_HANDLE_VALUE)
+    {
+      if (!WriteFile(socket, data, len, &iBytesWritten, NULL))
+      {
+        *iError = GetLastError();
+        return -1;
+      }
+      return (ssize_t)iBytesWritten;
+    }
+
+    return -1;
   }
 
-  inline int64_t SocketWrite(socket_t socket, int *iError, uint8_t* data, uint32_t len)
+  inline ssize_t SerialSocketRead(serial_socket_t socket, int *iError, void* data, size_t len, uint64_t iTimeoutMs /*= 0*/)
   {
-    int64_t iReturn(-1);
-    if (socket != SOCKET_ERROR && socket != INVALID_SOCKET)
+    DWORD iBytesRead(0);
+    if (socket != INVALID_HANDLE_VALUE)
     {
-      iReturn = send(socket, (char*)data, len, 0);
-      if (iReturn <= 0)
-        *iError = GetSocketError();
+      if(!ReadFile(socket, data, len, &iBytesRead, NULL) != 0)
+      {
+        *iError = GetLastError();
+        return -1;
+      }
+      return (ssize_t)iBytesRead;
     }
-    return iReturn;
+    return -1;
   }
+  //@}
 
-  inline int SocketReadFixed(socket_t socket, char *buf, int iLength, int iFlags)
+  // TCP
+  //@{
+  inline void TcpSocketSetBlocking(tcp_socket_t socket, bool bSetTo)
   {
-    int iReadResult(1), iBytesRead(0);
+    u_long iSetTo = bSetTo ? 0 : 1;
+    ioctlsocket(socket, FIONBIO, &iSetTo);
+  }
 
-    if ((iFlags & MSG_WAITALL) == 0)
-      return recv(socket, buf, iLength, iFlags);
+  inline void TcpSocketClose(tcp_socket_t socket)
+  {
+    closesocket(socket);
+  }
 
-    iFlags &= ~MSG_WAITALL;
-    while(iBytesRead < iLength && iReadResult > 0)
+  inline void TcpSocketShutdown(tcp_socket_t socket)
+  {
+    if (socket != INVALID_SOCKET &&
+        socket != SOCKET_ERROR)
+      shutdown(socket, SHUT_RDWR);
+  }
+
+  inline ssize_t TcpSocketWrite(tcp_socket_t socket, int *iError, void* data, size_t len)
+  {
+    if (socket == INVALID_SOCKET ||
+        socket == SOCKET_ERROR)
     {
-      if ((iReadResult = recv(socket, buf + iBytesRead, iLength - iBytesRead, iFlags)) < 0)
-        return iReadResult;
+      *iError = EINVAL;
+      return -1;
     }
-    return iLength - iBytesRead;
+
+    ssize_t iReturn = send(socket, (char*)data, len, 0);
+    if (iReturn < (ssize_t)len)
+      *iError = errno;
+    return iReturn;
   }
 
-  inline int32_t SocketRead(socket_t socket, void *buf, uint32_t nLen)
+  inline ssize_t TcpSocketRead(tcp_socket_t socket, int *iError, void* data, size_t len, uint64_t iTimeoutMs /*= 0*/)
   {
-    int iReadResult = SocketReadFixed(socket, (char *)buf, nLen, MSG_WAITALL);
+    int64_t iNow(0), iTarget(0);
+    ssize_t iBytesRead(0);
+    *iError = 0;
 
-    if (iReadResult == -1)
-      return GetSocketError();
-    if (iReadResult < (int)nLen)
-      return ECONNRESET;
+    if (socket == INVALID_SOCKET ||
+        socket == SOCKET_ERROR)
+    {
+      *iError = EINVAL;
+      return -1;
+    }
 
-    return 0;
-  }
+    if (iTimeoutMs > 0)
+    {
+      iNow    = GetTimeMs();
+      iTarget = iNow + (int64_t) iTimeoutMs;
+    }
 
-  inline int32_t SocketRead(socket_t socket, int *iError, uint8_t* data, uint32_t iLength, uint64_t iTimeoutMs)
-  {
-    int iReadResult(0);
-    uint32_t iBytesRead(0);
     fd_set fd_read;
     struct timeval tv;
+    while (iBytesRead >= 0 && iBytesRead < (ssize_t)len && (iTimeoutMs == 0 || iTarget > iNow))
+    {
+      if (iTimeoutMs > 0)
+      {
+        tv.tv_sec  =        (long)(iTimeoutMs / 1000);
+        tv.tv_usec = 1000 * (long)(iTimeoutMs % 1000);
 
-    if (iTimeoutMs <= 0)
-      return EINVAL;
+        FD_ZERO(&fd_read);
+        FD_SET(socket, &fd_read);
 
-    uint64_t iNow = GetTimeMs();
-    uint64_t iTarget = iNow + iTimeoutMs;
+        if (select(socket + 1, &fd_read, NULL, NULL, &tv) == 0)
+          return ETIMEDOUT;
+        TcpSocketSetBlocking(socket, false);
+      }
 
-    while(iNow < iTarget && iBytesRead < iLength)
-    {
-      tv.tv_sec  = (long)(iTarget - iNow / 1000);
-      tv.tv_usec = (long)(1000 * (iTarget - iNow % 1000));
+      ssize_t iReadResult = (iTimeoutMs > 0) ?
+          recv(socket, (char*)data + iBytesRead, len - iBytesRead, MSG_WAITALL) :
+          recv(socket, (char*)data, len, MSG_WAITALL);
+      *iError = GetSocketError();
+      if (iReadResult < 0)
+      {
+        if (errno == EAGAIN && iTimeoutMs > 0)
+          continue;
+        *iError = errno;
+        return -1;
+      }
+      else if (iReadResult == 0 || (iReadResult != (ssize_t)len && iTimeoutMs == 0))
+      {
+        *iError = ECONNRESET;
+        return -1;
+      }
 
-      FD_ZERO(&fd_read);
-      FD_SET(socket, &fd_read);
+      iBytesRead += iReadResult;
 
-      if ((iReadResult = select(socket + 1, &fd_read, NULL, NULL, &tv)) == 0)
-        return ETIMEDOUT;
+      if (iTimeoutMs > 0)
+      {
+        TcpSocketSetBlocking(socket, true);
+        iNow = GetTimeMs();
+      }
+    }
+    return 0;
+  }
 
-      SocketSetBlocking(socket, false);
+  inline bool TcpResolveAddress(const char *strHost, uint16_t iPort, int *iError, struct addrinfo **info)
+  {
+    struct   addrinfo hints;
+    char     service[33];
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family   = AF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_protocol = IPPROTO_TCP;
+    sprintf(service, "%d", iPort);
 
-      iReadResult = SocketReadFixed(socket, (char *)data + iBytesRead, iLength - iBytesRead, 0);
+    *iError = getaddrinfo(strHost, service, &hints, info);
+    return !(*iError);
+  }
 
-      SocketSetBlocking(socket, true);
+  inline int TcpGetSocketError(tcp_socket_t socket)
+  {
+    int iReturn(0);
+    socklen_t optLen = sizeof(tcp_socket_t);
+    getsockopt(socket, SOL_SOCKET, SO_ERROR, (char *)&iReturn, &optLen);
+    return iReturn;
+  }
 
-      if (iReadResult == -1)
+  inline bool TcpSetNoDelay(tcp_socket_t socket)
+  {
+    int iSetTo(1);
+    setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&iSetTo, sizeof(iSetTo));
+    return true;
+  }
+
+  inline bool TcpConnectSocket(tcp_socket_t socket, struct addrinfo* addr, int *iError, uint64_t iTimeout = 0)
+  {
+    TcpSocketSetBlocking(socket, false);
+
+    *iError = 0;
+    int iConnectResult = connect(socket, addr->ai_addr, addr->ai_addrlen);
+    if (iConnectResult == -1)
+    {
+      if (GetSocketError() == EINPROGRESS ||
+          GetSocketError() == EAGAIN)
       {
-        int iError = GetSocketError();
-        if (iError == EAGAIN)
-          continue;
-        return iError;
-      }
-      else if (iReadResult == 0)
-        return ECONNRESET;
+        fd_set fd_write, fd_except;
+        struct timeval tv;
+        tv.tv_sec  =        (long)(iTimeout / 1000);
+        tv.tv_usec = 1000 * (long)(iTimeout % 1000);
 
-      iBytesRead += iReadResult;
+        FD_ZERO(&fd_write);
+        FD_ZERO(&fd_except);
+        FD_SET(socket, &fd_write);
+        FD_SET(socket, &fd_except);
+
+        int iPollResult = select(sizeof(socket)*8, NULL, &fd_write, &fd_except, &tv);
+        if (iPollResult == 0)
+          *iError = ETIMEDOUT;
+        else if (iPollResult == -1)
+          *iError = GetSocketError();
+        else
+        {
+          socklen_t errlen = sizeof(int);
+          getsockopt(socket, SOL_SOCKET, SO_ERROR, (char *)iError, &errlen);
+        }
+      }
+      else
+      {
+        *iError = errno;
+      }
     }
 
-    return iBytesRead == iLength ? 0 : ECONNRESET;
+    TcpSocketSetBlocking(socket, true);
+
+    return *iError == 0;
   }
 }
diff --git a/src/lib/platform/windows/os-tcp.h b/src/lib/platform/windows/os-tcp.h
deleted file mode 100644 (file)
index b05a3dd..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-#pragma once
-/*
- * This file is part of the libCEC(R) library.
- *
- * 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.
- *
- * This program is dual-licensed; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *
- * Alternatively, you can license this library under a commercial license,
- * please contact Pulse-Eight Licensing for more information.
- *
- * For more information contact:
- * Pulse-Eight Licensing       <license@pulse-eight.com>
- *     http://www.pulse-eight.com/
- *     http://www.pulse-eight.net/
- */
-
-#include "../os.h"
-#include "../sockets/socket.h"
-
-namespace PLATFORM
-{
-  inline void TcpShutdownSocket(socket_t socket)
-  {
-    shutdown(socket, SHUT_RDWR);
-  }
-
-  inline int TcpResolveAddress(const CStdString &strHostname, uint16_t iPort, struct addrinfo *address)
-  {
-     struct addrinfo hints;
-     char   service[33];
-
-     memset(&hints, 0, sizeof(hints));
-     hints.ai_family   = AF_UNSPEC;
-     hints.ai_socktype = SOCK_STREAM;
-     hints.ai_protocol = IPPROTO_TCP;
-     sprintf(service, "%d", iPort);
-
-     return getaddrinfo(strHostname.c_str(), service, &hints, &address);
-   }
-
-  inline int TcpGetSocketError()
-  {
-    int error = WSAGetLastError();
-    switch(error)
-    {
-      case WSAEINPROGRESS: return EINPROGRESS;
-      case WSAECONNRESET : return ECONNRESET;
-      case WSAETIMEDOUT  : return ETIMEDOUT;
-      case WSAEWOULDBLOCK: return EAGAIN;
-      default            : return error;
-    }
-  }
-
-  inline int TcpConnectSocket(struct addrinfo* addr, socket_t socket, int *iError, uint64_t iTimeout)
-  {
-    int nRes = 0;
-    socklen_t errlen = sizeof(int);
-
-    SocketSetBlocking(socket, false);
-
-    /* connect to the other side */
-    nRes = connect(socket, addr->ai_addr, addr->ai_addrlen);
-
-    /* poll until a connection is established */
-    if (nRes == -1)
-    {
-      if (TcpGetSocketError() == EINPROGRESS || TcpGetSocketError() == EAGAIN)
-      {
-        fd_set fd_write, fd_except;
-        struct timeval tv;
-        tv.tv_sec  = (long)(iTimeout / 1000);
-        tv.tv_usec = (long)(1000 * (iTimeout % 1000));
-
-        FD_ZERO(&fd_write);
-        FD_ZERO(&fd_except);
-        FD_SET(socket, &fd_write);
-        FD_SET(socket, &fd_except);
-
-        nRes = select(sizeof(socket)*8, NULL, &fd_write, &fd_except, &tv);
-        if (nRes == 0)
-        {
-          *iError = ETIMEDOUT;
-          return SOCKET_ERROR;
-        }
-        else if (nRes == -1)
-        {
-          *iError = TcpGetSocketError();
-          return SOCKET_ERROR;
-        }
-
-        /* check for errors */
-        getsockopt(socket, SOL_SOCKET, SO_ERROR, (char *)iError, &errlen);
-      }
-      else
-      {
-        *iError = TcpGetSocketError();
-      }
-    }
-
-    SocketSetBlocking(socket, true);
-
-    return 0;
-  }
-
-  inline bool TcpSetNoDelay(socket_t socket)
-  {
-    int nVal = 1;
-    setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&nVal, sizeof(nVal));
-    return true;
-  }
-}
index de12f08426095313fd7ef233cc19737e24e6a729..84edac9e414244c65b51d7535d92d38add4f3bb6 100644 (file)
 #include <stddef.h>
 #include <process.h>
 
-typedef SOCKET socket_t;
+typedef SOCKET tcp_socket_t;
+#define INVALID_SOCKET_VALUE        INVALID_SOCKET
+typedef HANDLE serial_socket_t;
+#define INVALID_SERIAL_SOCKET_VALUE INVALID_HANDLE_VALUE
 
 typedef signed __int8    int8_t;
 typedef signed __int16   int16_t;
@@ -61,6 +64,15 @@ typedef unsigned __int16 uint16_t;
 typedef unsigned __int32 uint32_t;
 typedef unsigned __int64 uint64_t;
 
+#ifndef _SSIZE_T_DEFINED
+#ifdef  _WIN64
+typedef __int64    ssize_t;
+#else
+typedef _W64 int   ssize_t;
+#endif
+#define _SSIZE_T_DEFINED
+#endif
+
 #define snprintf _snprintf
 
 #if defined(_MSC_VER)
index dba963157f52e0a5a6f4cbc7398682c82405eb3b..680b1f0426174729827e1b85c1ca4e75e136922f 100644 (file)
@@ -37,7 +37,7 @@
 using namespace std;
 using namespace PLATFORM;
 
-void CSerialPort::FormatWindowsError(int iErrorCode, CStdString &strMessage)
+void FormatWindowsError(int iErrorCode, CStdString &strMessage)
 {
   if (iErrorCode != ERROR_SUCCESS)
   {
@@ -48,22 +48,67 @@ 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 SetTimeouts(serial_socket_t socket, int* iError, bool bBlocking)
 {
+  if (socket == INVALID_HANDLE_VALUE)
+         return false;
+
+  COMMTIMEOUTS cto;
+  if (!GetCommTimeouts(socket, &cto))
+  {
+    *iError = GetLastError();
+    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(socket, &cto))
+  {
+    *iError = GetLastError();
+    return false;
+  }
+
+  return true;
 }
 
-bool CSerialPort::Open(string name, uint32_t baudrate, uint8_t databits, uint8_t stopbits, uint8_t parity)
+void CSerialSocket::Close(void)
 {
-  CStdString strComPath = "\\\\.\\" + name;
+  SerialSocketClose(m_socket);
+}
+
+void CSerialSocket::Shutdown(void)
+{
+  SerialSocketClose(m_socket);
+}
+
+ssize_t CSerialSocket::Write(void* data, size_t len)
+{
+  return SerialSocketWrite(m_socket, &m_iError, data, len);
+}
+
+ssize_t CSerialSocket::Read(void* data, size_t len, uint64_t iTimeoutMs /* = 0 */)
+{
+  return SerialSocketRead(m_socket, &m_iError, data, len, iTimeoutMs);
+}
+
+bool CSerialSocket::Open(uint64_t iTimeoutMs /* = 0 */)
+{
+  iTimeoutMs = 0;
+  CStdString 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 +120,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 +132,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 +146,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, false))
   {
     m_strError = "unable to set timeouts";
     FormatWindowsError(GetLastError(), m_strError);
@@ -116,95 +158,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 +179,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 +202,3 @@ bool CSerialPort::SetBaudRate(uint32_t baudrate)
 
   return true;
 }
-
-bool CSerialPort::IsOpen(void)
-{
-  CLockObject lock(m_mutex);
-  return m_bIsOpen;
-}