From f7115044597c427b5bfb86fe0dec6436ed2752ac Mon Sep 17 00:00:00 2001 From: Lars Op den Kamp Date: Mon, 21 May 2012 14:45:39 +0200 Subject: [PATCH] platform: added tcp server sockets for posix --- src/lib/Makefile.am | 3 +- src/lib/platform/posix/serversocket.cpp | 152 ++++++++++++++++++++++++ src/lib/platform/sockets/serversocket.h | 90 ++++++++++++++ src/lib/platform/sockets/tcp.h | 42 +++++++ 4 files changed, 286 insertions(+), 1 deletion(-) create mode 100644 src/lib/platform/posix/serversocket.cpp create mode 100644 src/lib/platform/sockets/serversocket.h diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 19f5e6f..593cc15 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -29,7 +29,8 @@ libcec_la_SOURCES = CECProcessor.cpp \ implementations/SLCommandHandler.cpp \ implementations/VLCommandHandler.cpp \ implementations/RLCommandHandler.cpp \ - platform/posix/serialport.cpp + platform/posix/serialport.cpp \ + platform/posix/serversocket.cpp libcec_la_LDFLAGS = @LIBS@ -version-info @VERSION@ libcec_la_CPPFLAGS = -I@abs_top_srcdir@/include diff --git a/src/lib/platform/posix/serversocket.cpp b/src/lib/platform/posix/serversocket.cpp new file mode 100644 index 0000000..dce13d3 --- /dev/null +++ b/src/lib/platform/posix/serversocket.cpp @@ -0,0 +1,152 @@ +/* + * 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 + * http://www.pulse-eight.com/ + * http://www.pulse-eight.net/ + */ + +#include "../os.h" +#include "../sockets/tcp.h" +#include "../sockets/serversocket.h" + +using namespace std; +using namespace PLATFORM; + +bool CTcpServerSocket::Open(uint64_t UNUSED(iTimeoutMs)) +{ + bool bReturn(false); + struct addrinfo *address(NULL), *addr(NULL); + if (!TcpResolveAddress("localhost", m_iPort, &m_iError, &address)) + { + m_strError = strerror(m_iError); + return bReturn; + } + + for(addr = address; !bReturn && addr; addr = addr->ai_next) + { + m_socket = TcpCreateSocket(addr, &m_iError); + if (m_socket != INVALID_SOCKET_VALUE) + { + bReturn = true; + break; + } + else + { + m_strError = strerror(m_iError); + } + } + + if (bReturn) + { + m_iError = bind(m_socket, addr->ai_addr, addr->ai_addrlen); + if (m_iError) + { + m_strError = strerror(m_iError); + bReturn = false; + } + } + + freeaddrinfo(address); + + if (bReturn) + { + m_iError = listen(m_socket, 16); + if (m_iError) + { + m_strError = strerror(m_iError); + bReturn = false; + } + } + + return bReturn; +} + +void CTcpServerSocket::Close(void) +{ + if (IsOpen()) + TcpSocketClose(m_socket); + m_socket = INVALID_SOCKET_VALUE; +} + +void CTcpServerSocket::Shutdown(void) +{ + Close(); +} + +bool CTcpServerSocket::IsOpen(void) +{ + return m_socket != INVALID_SOCKET_VALUE; +} + +CStdString CTcpServerSocket::GetError(void) +{ + CStdString strError; + strError = m_strError.IsEmpty() && m_iError != 0 ? strerror(m_iError) : m_strError; + return strError; +} + +int CTcpServerSocket::GetErrorNumber(void) +{ + return m_iError; +} + +CStdString CTcpServerSocket::GetName(void) +{ + CStdString strName("localhost"); + return strName; +} + +ISocket* CTcpServerSocket::Accept(void) +{ + struct sockaddr clientAddr; + unsigned int iClientLen(sizeof(clientAddr)); + tcp_socket_t client = accept(m_socket, &clientAddr, &iClientLen); + + if (client != INVALID_SOCKET_VALUE) + { + CTcpClientSocket *socket = new CTcpClientSocket(client); + return (ISocket*)socket; + } + + m_strError = strerror(m_iError); + return NULL; +} + +tcp_socket_t CTcpServerSocket::TcpCreateSocket(struct addrinfo* addr, int* iError) +{ + 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; + } + + TcpSetNoDelay(fdSock); + + return fdSock; +} diff --git a/src/lib/platform/sockets/serversocket.h b/src/lib/platform/sockets/serversocket.h new file mode 100644 index 0000000..edc7fcd --- /dev/null +++ b/src/lib/platform/sockets/serversocket.h @@ -0,0 +1,90 @@ +#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 + * http://www.pulse-eight.com/ + * http://www.pulse-eight.net/ + */ + +#include "socket.h" + +using namespace std; + +namespace PLATFORM +{ + class IServerSocket : public ISocket + { + public: + IServerSocket() : ISocket() {} + + virtual ~IServerSocket(void) {} + + virtual bool Open(uint64_t iTimeoutMs = 0) = 0; + virtual void Close(void) = 0; + virtual void Shutdown(void) = 0; + virtual bool IsOpen(void) = 0; + ssize_t Write(void* data, size_t len) { (void) data; (void) len; return EINVAL; } + ssize_t Read(void* data, size_t len, uint64_t iTimeoutMs = 0) { (void) data; (void) len; (void) iTimeoutMs; return EINVAL; } + virtual CStdString GetError(void) = 0; + virtual int GetErrorNumber(void) = 0; + virtual CStdString GetName(void) = 0; + + virtual ISocket* Accept(void) = 0; + }; + + class CTcpServerSocket : public IServerSocket + { + public: + CTcpServerSocket(uint16_t iPort) : + IServerSocket(), + m_iPort(iPort), + m_socket(INVALID_SOCKET_VALUE), + m_iError(0) {} + + virtual ~CTcpServerSocket(void) {} + + virtual bool Open(uint64_t iTimeoutMs = 0); + virtual void Close(void); + virtual void Shutdown(void); + virtual bool IsOpen(void); + virtual CStdString GetError(void); + virtual int GetErrorNumber(void); + virtual CStdString GetName(void); + + virtual ISocket* Accept(void); + + protected: + virtual tcp_socket_t TcpCreateSocket(struct addrinfo* addr, int* iError); + + protected: + uint16_t m_iPort; + tcp_socket_t m_socket; + CStdString m_strError; + int m_iError; + }; +} diff --git a/src/lib/platform/sockets/tcp.h b/src/lib/platform/sockets/tcp.h index ffc372c..1693354 100644 --- a/src/lib/platform/sockets/tcp.h +++ b/src/lib/platform/sockets/tcp.h @@ -120,6 +120,48 @@ namespace PLATFORM uint16_t m_iPort; }; + class CTcpClientSocket : public CCommonSocket + { + public: + CTcpClientSocket(tcp_socket_t socket) : + CCommonSocket(socket, "tcpclient") {} + + virtual ~CTcpClientSocket(void) {} + + virtual bool Open(uint64_t iTimeoutMs = 0) + { + (void) iTimeoutMs; + return true; + } + + virtual void Close(void) + { + TcpSocketClose(m_socket); + m_socket = INVALID_SOCKET_VALUE; + } + + virtual void Shutdown(void) + { + 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); + } + + virtual bool IsOpen(void) + { + return m_socket != INVALID_SOCKET_VALUE; + } + }; + class CTcpConnection : public CProtectedSocket { public: -- 2.34.1