mbed socket API

Dependents:   EthernetInterface EthernetInterface_RSF EthernetInterface EthernetInterface ... more

Deprecated

This is an mbed 2 sockets library. For mbed 5, network sockets have been revised to better support additional network stacks and thread safety here.

Files at this revision

API Documentation at this revision

Comitter:
emilmont
Date:
Wed Jul 25 14:59:37 2012 +0000
Parent:
2:b227d242f3c7
Child:
4:75988d748e4d
Commit message:
Split TCPSocketServer from TCPSocketConnection

Changed in this revision

Socket.cpp Show annotated file Show diff for this revision Revisions of this file
Socket.h Show annotated file Show diff for this revision Revisions of this file
TCPSocket.cpp Show diff for this revision Revisions of this file
TCPSocket.h Show diff for this revision Revisions of this file
TCPSocketConnection.cpp Show annotated file Show diff for this revision Revisions of this file
TCPSocketConnection.h Show annotated file Show diff for this revision Revisions of this file
TCPSocketServer.cpp Show annotated file Show diff for this revision Revisions of this file
TCPSocketServer.h Show annotated file Show diff for this revision Revisions of this file
UDPSocket.cpp Show annotated file Show diff for this revision Revisions of this file
UDPSocket.h Show annotated file Show diff for this revision Revisions of this file
socket.h Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket.cpp	Wed Jul 25 14:59:37 2012 +0000
@@ -0,0 +1,72 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "Socket/Socket.h"
+#include <cstring>
+
+using std::memset;
+
+Socket::Socket() : _sock_fd(-1) {
+    
+}
+
+int Socket::init(int type) {
+    if (_sock_fd != -1)
+        return -1;
+    
+    int fd = lwip_socket(AF_INET, type, 0);
+    if (fd < 0)
+        return -1;
+    
+    _sock_fd = fd;
+    return 0;
+}
+
+
+void Socket::set_timeout(int timeout) {
+    _timeout.tv_sec = timeout / 1000;
+    _timeout.tv_usec = (timeout - (_timeout.tv_sec * 1000)) * 1000;
+}
+
+int Socket::select(fd_set* readset, fd_set* writeset) {
+    if ((_timeout.tv_sec == 0) && (_timeout.tv_usec == 0))
+        return 0;
+    
+    FD_ZERO(&_fdSet);
+    FD_SET(_sock_fd, &_fdSet);
+    
+    int ret = lwip_select(FD_SETSIZE, readset, writeset, NULL, &_timeout);
+    return (ret <= 0 || !FD_ISSET(_sock_fd, &_fdSet)) ? (-1) : (0);
+}
+
+int Socket::wait_readable(void) {
+    return select(&_fdSet, NULL);
+}
+
+int Socket::wait_writable(void) {
+    return select(NULL, &_fdSet);
+}
+
+int Socket::close() {
+    if (_sock_fd < 0)
+        return -1;
+    
+    lwip_close(_sock_fd);
+    _sock_fd = -1;
+    
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket.h	Wed Jul 25 14:59:37 2012 +0000
@@ -0,0 +1,54 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef SOCKET_H_
+#define SOCKET_H_
+
+#include "lwip/sockets.h"
+#include "lwip/netdb.h"
+
+//DNS
+inline struct hostent *gethostbyname(const char *name) {
+  return lwip_gethostbyname(name);
+}
+
+inline int gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) {
+  return lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop);
+}
+
+class Socket {
+public:
+    Socket();
+    
+    int close();
+    
+protected:
+    int _sock_fd;
+    int init(int type);
+    
+    void set_timeout(int timeout);
+    int wait_readable(void);
+    int wait_writable(void);
+
+private:
+    // At the moment, we assume a simple single threaded access to the socket
+    struct timeval _timeout;
+    fd_set _fdSet;
+    int select(fd_set* readset, fd_set* writeset);
+};
+
+#endif /* SOCKET_H_ */
--- a/TCPSocket.cpp	Mon Jul 23 11:52:50 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,278 +0,0 @@
-/* Copyright (C) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
- 
-#include "TCPSocket.h"
-
-#include <cstring>
-
-using std::memset;
-
-TCPSocket::TCPSocket() : m_sock(-1)
-{
-}
-
-TCPSocket::~TCPSocket()
-{
-  close(); //Don't want to leak 
-}
-
-int TCPSocket::connect(char* host, int port, int timeout)
-{
-  int ret = init();
-  if( ret < 0 ) 
-  {
-    return -1;
-  }
-
-  //Populate m_remoteHost
-  std::memset(&m_remoteHost, 0, sizeof(struct sockaddr_in));
-
-  //Resolve DNS address or populate hard-coded IP address
-  struct hostent *server = gethostbyname(host);
-  if(server == NULL)
-  {
-    return -1; //Could not resolve address
-  }
-  std::memcpy((char*)&m_remoteHost.sin_addr.s_addr, (char*)server->h_addr_list[0], server->h_length);
-
-  m_remoteHost.sin_family = AF_INET;
-  m_remoteHost.sin_port = htons(port);
-  
-  ret = ::connect(m_sock, (const struct sockaddr *)&m_remoteHost, sizeof(m_remoteHost));
-  if (ret < 0)
-  {
-    close();
-    return -1;
-  }
-  
-  return 0;
-}
-
-int TCPSocket::bind(int port)
-{
-  int ret = init();
-  if( ret < 0 ) 
-  {
-    return -1;
-  }
-  
-  struct sockaddr_in localHost;
-  std::memset(&localHost, 0, sizeof(localHost));
- 
-  localHost.sin_family = AF_INET;
-  localHost.sin_port = htons(port);
-  localHost.sin_addr.s_addr = INADDR_ANY;
-  
-  ret = ::bind(m_sock, (const struct sockaddr *)&localHost, sizeof(localHost));
-  if (ret < 0)
-  {
-    close();
-    return -1;
-  }
-
-  return 0;
-}
-
-int TCPSocket::listen(int max)
-{
-  if( m_sock < 0 )
-  {
-    return -1;
-  }
-  
-  int ret = ::listen(m_sock, max);
-  if (ret < 0)
-  {
-    close();
-    return -1;
-  }
-  
-  return 0;
-}
-
-int TCPSocket::accept(TCPSocket& socket, char** host, int* port, int timeout)
-{
-  if( m_sock < 0 )
-  {
-    return -1;
-  }
-
-  //Populate m_remoteHost
-  std::memset(&socket.m_remoteHost, 0, sizeof(struct sockaddr_in));
-
-  struct timeval t_val; //t_val will be decremented on each call to select()
-  t_val.tv_sec = timeout / 1000;
-  t_val.tv_usec = (timeout - (t_val.tv_sec * 1000)) * 1000;
-  //Wait for socket to get some connection request (i.e. to be "readable")
-  //Creating FS set
-  fd_set socksSet;
-  FD_ZERO(&socksSet);
-  FD_SET(m_sock, &socksSet);
-  int ret = ::select(FD_SETSIZE, &socksSet, NULL, NULL, &t_val);
-  if(ret <= 0 || !FD_ISSET(m_sock, &socksSet))
-  {
-    return -1; //Timeout
-  }
-  
-  socklen_t newSockRemoteHostLen = sizeof(socket.m_remoteHost);
-  
-  ret = ::accept(m_sock, (struct sockaddr*)&socket.m_remoteHost, &newSockRemoteHostLen);
-  if( ret < 0 )
-  {
-    return -1; //Accept failed
-  }
-  
-  socket.m_sock = ret; //ret is the new socket's fd
-  socket.m_closedByRemoteHost = false;
-  
-  static char hostBuf[16];
-  inet_ntoa_r(socket.m_remoteHost.sin_addr, hostBuf, sizeof(hostBuf));
-  
-  *host = hostBuf;
-  *port = ntohs(socket.m_remoteHost.sin_port);
-
-  return 0;
-}
-
-// -1 if unsuccessful, else number of bytes written
-int TCPSocket::send(char* data, int length, int timeout)
-{
-  if( m_sock < 0 )
-  {
-    return -1;
-  }
-  
-  if( m_closedByRemoteHost )
-  {
-    return 0;
-  }
-
-  size_t writtenLen = 0;
-  struct timeval t_val; //t_val will be decremented on each call to select()
-  t_val.tv_sec = timeout / 1000;
-  t_val.tv_usec = (timeout - (t_val.tv_sec * 1000)) * 1000;
-  while(writtenLen < length)
-  {
-    //Wait for socket to be writeable
-    //Creating FS set
-    fd_set socksSet;
-    FD_ZERO(&socksSet);
-    FD_SET(m_sock, &socksSet);
-
-    int ret = ::select(FD_SETSIZE, NULL, &socksSet, NULL, &t_val);
-    if(ret <= 0 || !FD_ISSET(m_sock, &socksSet))
-    {
-      return writtenLen; //Timeout -- FIXME should we return -1 or writtenLength ?
-    }
-
-    ret = ::send(m_sock, data + writtenLen, length - writtenLen, 0);
-    if( ret > 0)
-    {
-      writtenLen += ret;
-      continue;
-    }
-    else if( ret == 0 )
-    {
-      m_closedByRemoteHost = true;
-      return writtenLen; //Connection was closed by remote host -- FIXME how do we signal that the connection was closed ?
-    }
-    else
-    {
-      return -1; //Connnection error
-    }
-  }
-  
-  return writtenLen;
-}
-
-// -1 if unsuccessful, else number of bytes received
-int TCPSocket::receive(char* data, int length, int timeout)
-{
-  if( m_sock < 0 )
-  {
-    return -1;
-  }
-  
-  if( m_closedByRemoteHost )
-  {
-    return 0;
-  }
-  
-  size_t readLen = 0;
-  struct timeval t_val; //t_val will be decremented on each call to select()
-  t_val.tv_sec = timeout / 1000;
-  t_val.tv_usec = (timeout - (t_val.tv_sec * 1000)) * 1000;
-  while(readLen < length)
-  {
-    //Wait for socket to be readable
-    //Creating FS set
-    fd_set socksSet;
-    FD_ZERO(&socksSet);
-    FD_SET(m_sock, &socksSet);
-    int ret = ::select(FD_SETSIZE, &socksSet, NULL, NULL, &t_val);
-    if(ret <= 0 || !FD_ISSET(m_sock, &socksSet))
-    {
-      return readLen; //Timeout -- FIXME should we return -1 or writtenLength ?
-    }
-
-    ret = ::recv(m_sock, data + readLen, length - readLen, 0);
-    if( ret > 0)
-    {
-      readLen += ret;
-      continue;
-    }
-    else if( ret == 0 )
-    {
-      m_closedByRemoteHost = true;
-      return readLen; //Connection was closed by remote host -- FIXME how do we signal that the connection was closed ?
-    }
-    else
-    {
-      return -1; //Connnection error
-    }
-  }
-  return readLen;
-}
-
-int TCPSocket::close()
-{
-  if( m_sock < 0 )
-  {
-    return -1;
-  }
-
-  ::close(m_sock);
-  m_sock = -1;
-  
-  return 0;
-}
-
-int TCPSocket::init()
-{
-  if( m_sock != -1 )
-  {
-    return -1;
-  }
-  m_sock = ::socket(AF_INET, SOCK_STREAM, 0); //TCP socket
-  if (m_sock < 0)
-  {
-    return -1; //Could not create socket (Out of memory / available descriptors)
-  }
-  m_closedByRemoteHost = false;
-  return 0;
-}
--- a/TCPSocket.h	Mon Jul 23 11:52:50 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/* Copyright (C) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef TCPSOCKET_H
-#define TCPSOCKET_H
-
-#include "Socket/socket.h"
-
-/**
-This is a C++ abstraction for TCP networking sockets.
-*/
-class TCPSocket
-{
-  public:
-  
-    /** Instantiate a TCP Socket.
-    */
-    TCPSocket();
-    
-    ~TCPSocket();
-
-    /** Connect the TCP Socket to the following host.
-    \param host The host to connect to. It can either be an IP Address or a hostname that will be resolved with DNS.
-    \param port The host's port to connect to.
-    \param timeout The maximum time in ms during which to try to connect.
-    \return 0 on success, -1 on failure.
-    */
-    int connect(char* host, int port, int timeout = 0);
-
-    /** Bind a socket to a specific port.
-    For a listening socket, bind the socket to the following port. The socket will start listening for incoming connections on this port on the call to listen().
-    \param port The port to listen for incoming connections on.
-    \return 0 on success, -1 on failure.
-    */
-    int bind(int port);
-
-    /** Start listening for incoming connections.
-    \param max The maximum number of connections that can be accepted.
-    \return 0 on success, -1 on failure.
-    */
-    int listen(int max);
-
-    /** Accept a new connection.
-    \param socket A socket instance that will handle the incoming connection.
-    \param host The reference that will point to the client's IP address.
-    \param port The reference that will point to the client's port.
-    \param timeout The maximum time in ms during which to wait for an incoming connection.
-    \return 0 on success, -1 on failure.
-    */
-    int accept(TCPSocket& socket, char** host, int* port, int timeout = 0);
-
-    /** Send data to the remote host.
-    \param data The buffer to send to the host.
-    \param length The length of the buffer to send.
-    \param timeout The maximum amount of time in ms to wait while trying to send the buffer.
-    \return the number of written bytes on success (>=0) or -1 on failure
-    */
-    int send(char* data, int length, int timeout = 0);
-
-    /** Receive data from the remote host.
-    \param data The buffer in which to store the data received from the host.
-    \param length The maximum length of the buffer.
-    \param timeout The maximum amount of time in ms to wait while trying to receive data.
-    \return the number of received bytes on success (>=0) or -1 on failure
-    */
-    int receive(char* data, int length, int timeout = 0);
-
-    /** Close the socket.
-    */
-    int close();
-    
-  private:
-    int init();
-
-    int m_sock;
-    bool m_closedByRemoteHost;
-    struct sockaddr_in m_remoteHost;
-
-};
-
-#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TCPSocketConnection.cpp	Wed Jul 25 14:59:37 2012 +0000
@@ -0,0 +1,146 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "TCPSocketConnection.h"
+#include <cstring>
+
+using std::memset;
+using std::memcpy;
+
+TCPSocketConnection::TCPSocketConnection() :
+        _closedByRemoteHost(false) {
+    memset(&_remoteHost, 0, sizeof(struct sockaddr_in));
+    _ipAddress[0] = '\0';
+}
+
+int TCPSocketConnection::connect(char* host, int port) {
+    if (init(SOCK_STREAM) < 0)
+        return -1;
+    
+    //Resolve DNS address or populate hard-coded IP address
+    struct hostent *server = gethostbyname(host);
+    if (server == NULL)
+        return -1; //Could not resolve address
+    
+    memcpy((char*) &_remoteHost.sin_addr.s_addr,
+           (char*) server->h_addr_list[0], server->h_length);
+    
+    _remoteHost.sin_family = AF_INET;
+    _remoteHost.sin_port = htons(port);
+    if (lwip_connect(_sock_fd, (const struct sockaddr *) &_remoteHost, sizeof(_remoteHost)) < 0) {
+        close();
+        return -1;
+    }
+    
+    return 0;
+}
+
+int TCPSocketConnection::send(char* data, int length, int timeout) {
+    if ((_sock_fd < 0) || _closedByRemoteHost)
+        return -1;
+    
+    set_timeout(timeout);
+    if (wait_writable() != 0)
+        return -1;
+    
+    int n = lwip_send(_sock_fd, data, length, 0);
+    _closedByRemoteHost = (n == 0);
+    
+    return n;
+}
+
+// -1 if unsuccessful, else number of bytes written
+int TCPSocketConnection::send_all(char* data, int length, int timeout) {
+    if ((_sock_fd < 0) || _closedByRemoteHost)
+        return -1;
+    
+    size_t writtenLen = 0;
+    set_timeout(timeout);
+    while (writtenLen < length) {
+        // Wait for socket to be writeable
+        if (wait_writable() != 0)
+            return writtenLen; //Timeout -- FIXME should we return -1 or writtenLength ?
+        
+        int ret = lwip_send(_sock_fd, data + writtenLen, length - writtenLen, 0);
+        if (ret > 0) {
+            writtenLen += ret;
+            continue;
+        } else if (ret == 0) {
+            _closedByRemoteHost = true;
+            return writtenLen; //Connection was closed by remote host -- FIXME how do we signal that the connection was closed ?
+        } else {
+            return -1; //Connnection error
+        }
+    }
+    
+    return writtenLen;
+}
+
+int TCPSocketConnection::receive(char* data, int length, int timeout) {
+    if ((_sock_fd < 0) || _closedByRemoteHost)
+        return -1;
+    
+    set_timeout(timeout);
+    if (wait_readable() != 0)
+        return -1;
+    
+    int n = lwip_recv(_sock_fd, data, length, 0);
+    _closedByRemoteHost = (n == 0);
+    
+    return n;
+}
+
+// -1 if unsuccessful, else number of bytes received
+int TCPSocketConnection::receive_all(char* data, int length, int timeout) {
+    if ((_sock_fd < 0) || _closedByRemoteHost)
+        return -1;
+    
+    size_t readLen = 0;
+    set_timeout(timeout);
+    while (readLen < length) {
+        //Wait for socket to be readable
+        if (wait_readable() != 0)
+            return readLen; //Timeout -- FIXME should we return -1 or writtenLength ?
+        
+        int ret = lwip_recv(_sock_fd, data + readLen, length - readLen, 0);
+        if (ret > 0) {
+            readLen += ret;
+        } else if (ret == 0) {
+            _closedByRemoteHost = true;
+            return readLen; //Connection was closed by remote host -- FIXME how do we signal that the connection was closed ?
+        } else {
+            return -1; //Connnection error
+        }
+    }
+    return readLen;
+}
+
+char* TCPSocketConnection::get_address() {
+    if (_ipAddress[0] == '\0') {
+        if (_remoteHost.sin_addr.s_addr == 0)
+            return NULL;
+        inet_ntoa_r(_remoteHost.sin_addr, _ipAddress, sizeof(_ipAddress));
+    }
+    return _ipAddress;
+}
+int   TCPSocketConnection::get_port() {
+    return ntohs(_remoteHost.sin_port);
+}
+
+TCPSocketConnection::~TCPSocketConnection() {
+    close(); //Don't want to leak 
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TCPSocketConnection.h	Wed Jul 25 14:59:37 2012 +0000
@@ -0,0 +1,87 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef TCPSOCKET_H
+#define TCPSOCKET_H
+
+#include "Socket/Socket.h"
+
+/**
+This is a C++ abstraction for TCP networking sockets.
+*/
+class TCPSocketConnection : public Socket {
+    friend class TCPSocketServer;
+    
+public:
+    /** Instantiate a TCP Socket.
+    */
+    TCPSocketConnection();
+    
+    ~TCPSocketConnection();
+    
+    /** Connect the TCP Socket to the following host.
+    \param host The host to connect to. It can either be an IP Address or a hostname that will be resolved with DNS.
+    \param port The host's port to connect to.
+    \return 0 on success, -1 on failure.
+    */
+    int connect(char* host, int port);
+    
+    /** Send data to the remote host.
+    \param data The buffer to send to the host.
+    \param length The length of the buffer to send.
+    \param timeout The maximum amount of time in ms to wait while trying to send the buffer.
+    \return the number of written bytes on success (>=0) or -1 on failure
+     */
+    int send(char* data, int length, int timeout=0);
+    
+    /** Send data to the remote host.
+    \param data The buffer to send to the host.
+    \param length The length of the buffer to send.
+    \param timeout The maximum amount of time in ms to wait while trying to send the buffer.
+    \return the number of written bytes on success (>=0) or -1 on failure
+    */
+    int send_all(char* data, int length, int timeout=0);
+    
+    /** Receive data from the remote host.
+    \param data The buffer in which to store the data received from the host.
+    \param length The maximum length of the buffer.
+    \param timeout The maximum amount of time in ms to wait while trying to receive data.
+    \return the number of received bytes on success (>=0) or -1 on failure
+     */
+    int receive(char* data, int length, int timeout=0);
+    
+    /** Receive data from the remote host.
+    \param data The buffer in which to store the data received from the host.
+    \param length The maximum length of the buffer.
+    \param timeout The maximum amount of time in ms to wait while trying to receive data.
+    \return the number of received bytes on success (>=0) or -1 on failure
+    */
+    int receive_all(char* data, int length, int timeout=0);
+    
+    char* get_address();
+    int   get_port();
+    
+private:
+    char _ipAddress[16];
+    
+    bool _closedByRemoteHost;
+    struct sockaddr_in _remoteHost;
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TCPSocketServer.cpp	Wed Jul 25 14:59:37 2012 +0000
@@ -0,0 +1,79 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "TCPSocketServer.h"
+
+#include <cstring>
+
+using std::memset;
+using std::memcpy;
+
+TCPSocketServer::TCPSocketServer() {
+    
+}
+
+int TCPSocketServer::bind(int port) {
+    if (init(SOCK_STREAM) < 0)
+        return -1;
+    
+    struct sockaddr_in localHost;
+    memset(&localHost, 0, sizeof(localHost));
+    
+    localHost.sin_family = AF_INET;
+    localHost.sin_port = htons(port);
+    localHost.sin_addr.s_addr = INADDR_ANY;
+    
+    if (lwip_bind(_sock_fd, (const struct sockaddr *) &localHost, sizeof(localHost)) < 0) {
+        close();
+        return -1;
+    }
+    
+    return 0;
+}
+
+int TCPSocketServer::listen(int max) {
+    if (_sock_fd < 0)
+        return -1;
+    
+    if (lwip_listen(_sock_fd, max) < 0) {
+        close();
+        return -1;
+    }
+    
+    return 0;
+}
+
+int TCPSocketServer::accept(TCPSocketConnection& connection, int timeout) {
+    if (_sock_fd < 0)
+        return -1;
+    
+    set_timeout(timeout);
+    if (wait_readable() != 0)
+        return -1;
+    
+    socklen_t newSockRemoteHostLen = sizeof(connection._remoteHost);
+    int fd = lwip_accept(_sock_fd, (struct sockaddr*) &connection._remoteHost, &newSockRemoteHostLen);
+    if (fd < 0)
+        return -1; //Accept failed
+    connection._sock_fd = fd;
+    
+    return 0;
+}
+
+TCPSocketServer::~TCPSocketServer() {
+    close(); //Don't want to leak 
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TCPSocketServer.h	Wed Jul 25 14:59:37 2012 +0000
@@ -0,0 +1,52 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef TCPSOCKETSERVER_H
+#define TCPSOCKETSERVER_H
+
+#include "Socket/Socket.h"
+#include "TCPSocketConnection.h"
+
+class TCPSocketServer : Socket {
+  public:
+    /** Instantiate a TCP Socket.
+    */
+    TCPSocketServer();
+    
+    ~TCPSocketServer();
+    
+    /** Bind a socket to a specific port.
+    For a listening socket, bind the socket to the following port. The socket will start listening for incoming connections on this port on the call to listen().
+    \param port The port to listen for incoming connections on.
+    \return 0 on success, -1 on failure.
+    */
+    int bind(int port);
+
+    /** Start listening for incoming connections.
+    \param max The maximum number of connections that can be accepted.
+    \return 0 on success, -1 on failure.
+    */
+    int listen(int max);
+
+    /** Accept a new connection.
+    \param socket A socket instance that will handle the incoming connection.
+    \return 0 on success, -1 on failure.
+    */
+    int accept(TCPSocketConnection& connection, int timeout=0);
+};
+
+#endif
--- a/UDPSocket.cpp	Mon Jul 23 11:52:50 2012 +0000
+++ b/UDPSocket.cpp	Wed Jul 25 14:59:37 2012 +0000
@@ -22,183 +22,98 @@
 
 using std::memset;
 
-UDPSocket::UDPSocket() : m_sock(-1)
-{
-}
-
-UDPSocket::~UDPSocket()
-{
-  close(); //Don't want to leak
+UDPSocket::UDPSocket() {
 }
 
-int UDPSocket::bind(int port)
-{
-  int ret = init();
-  if( ret < 0 ) 
-  {
-    return -1;
-  }
-  
-  struct sockaddr_in localHost;
-  std::memset(&localHost, 0, sizeof(localHost));
- 
-  localHost.sin_family = AF_INET;
-  localHost.sin_port = htons(port);
-  localHost.sin_addr.s_addr = INADDR_ANY;
-  
-  ret = ::bind(m_sock, (const struct sockaddr *)&localHost, sizeof(localHost));
-  if (ret < 0)
-  {
-    close();
-    return -1;
-  }
-
-  return 0;
+// Server initialization
+int UDPSocket::bind(int port) {
+    if (init(SOCK_DGRAM) < 0)
+        return -1;
+    
+    struct sockaddr_in localHost;
+    std::memset(&localHost, 0, sizeof(localHost));
+    
+    localHost.sin_family = AF_INET;
+    localHost.sin_port = htons(port);
+    localHost.sin_addr.s_addr = INADDR_ANY;
+    
+    if (lwip_bind(_sock_fd, (const struct sockaddr *) &localHost, sizeof(localHost)) < 0) {
+        close();
+        return -1;
+    }
+    
+    return 0;
 }
 
 // -1 if unsuccessful, else number of bytes written
-int UDPSocket::sendTo(char* data, int length, char* host, int port, int timeout)
-{
-  if( m_sock < 0 )
-  {
-    return -1;
-  }
-  
-  struct sockaddr_in remoteHost;
- 
-  //Populate m_remoteHost
-  std::memset(&remoteHost, 0, sizeof(struct sockaddr_in));
-
-  //Resolve DNS address or populate hard-coded IP address
-  struct hostent *server = ::gethostbyname(host);
-  if(server == NULL)
-  {
-    return -1; //Could not resolve address
-  }
-  std::memcpy((char*)&remoteHost.sin_addr.s_addr, (char*)server->h_addr_list[0], server->h_length);
-
-  remoteHost.sin_family = AF_INET;
-  remoteHost.sin_port = htons(port);
-
-  size_t writtenLen = 0;
-  struct timeval t_val; //t_val will be decremented on each call to select()
-  t_val.tv_sec = timeout / 1000;
-  t_val.tv_usec = (timeout - (t_val.tv_sec * 1000)) * 1000;
-  while(writtenLen < length)
-  {
-    //Wait for socket to be writeable
-    //Creating FS set
-    fd_set socksSet;
-    FD_ZERO(&socksSet);
-    FD_SET(m_sock, &socksSet);
-
-    int ret = ::select(FD_SETSIZE, NULL, &socksSet, NULL, &t_val);
-    if(ret <= 0 || !FD_ISSET(m_sock, &socksSet))
-    {
-      return writtenLen; //Timeout -- FIXME should we return -1 or writtenLength ?
+int UDPSocket::sendTo(char* data, int length, char* host, int port, int timeout) {
+    if (_sock_fd < 0)
+        return -1;
+    
+    struct sockaddr_in remoteHost;
+    
+    //Populate m_remoteHost
+    std::memset(&remoteHost, 0, sizeof(struct sockaddr_in));
+    
+    //Resolve DNS address or populate hard-coded IP address
+    struct hostent *server = ::gethostbyname(host);
+    if (server == NULL) {
+        return -1; //Could not resolve address
     }
-
-    ret = ::sendto(m_sock, data + writtenLen, length - writtenLen, 0, (const struct sockaddr *)&remoteHost, sizeof(remoteHost));
-    if( ret > 0)
-    {
-      writtenLen += ret;
-      continue;
+    std::memcpy((char*) &remoteHost.sin_addr.s_addr,
+            (char*) server->h_addr_list[0], server->h_length);
+    
+    remoteHost.sin_family = AF_INET;
+    remoteHost.sin_port = htons(port);
+    
+    size_t writtenLen = 0;
+    set_timeout(timeout);
+    while (writtenLen < length) {
+        //Wait for socket to be writeable
+        //Creating FS set
+        if (wait_writable() != 0)
+            return writtenLen; //Timeout -- FIXME should we return -1 or writtenLength ?
+        
+        int ret = lwip_sendto(_sock_fd, data + writtenLen, length - writtenLen, 0,
+                (const struct sockaddr *) &remoteHost, sizeof(remoteHost));
+        if (ret > 0) {
+            writtenLen += ret;
+        } else if (ret == 0) {
+            return writtenLen; //Connection was closed by server -- FIXME how do we signal that the connection was closed ?
+        } else {
+            return -1; //Connnection error
+        }
     }
-    else if( ret == 0 )
-    {
-      return writtenLen; //Connection was closed by server -- FIXME how do we signal that the connection was closed ?
-    }
-    else
-    {
-      return -1; //Connnection error
-    }
-  }
-  
-  return writtenLen;
+    
+    return writtenLen;
 }
 
 // -1 if unsuccessful, else number of bytes received
-int UDPSocket::receiveFrom(char* data, int length, char** host, int* port, int timeout)
-{
-  if( m_sock < 0 )
-  {
-    return -1;
-  }
-
-  struct sockaddr_in remoteHost;
- 
-  //Populate m_remoteHost
-  std::memset(&remoteHost, 0, sizeof(struct sockaddr_in));
-  
-  socklen_t remoteHostLen = sizeof(remoteHost);
-
-  size_t readLen = 0;
-  struct timeval t_val; //t_val will be decremented on each call to select()
-  t_val.tv_sec = timeout / 1000;
-  t_val.tv_usec = (timeout - (t_val.tv_sec * 1000)) * 1000;
-  
-  //No loop here as we don't want to mix packets from different sources
-  do
-  {
-    //Wait for socket to be readable
-    //Creating FS set
-    fd_set socksSet;
-    FD_ZERO(&socksSet);
-    FD_SET(m_sock, &socksSet);
-    int ret = ::select(FD_SETSIZE, &socksSet, NULL, NULL, &t_val);
-    if(ret <= 0 || !FD_ISSET(m_sock, &socksSet))
-    {
-      break; //Timeout -- FIXME should we return -1 or writtenLength ?
-    }
+int UDPSocket::receiveFrom(char* data, int length, char** host, int* port, int timeout) {
+    if (_sock_fd < 0)
+        return -1;
+    
+    set_timeout(timeout);
+    if (wait_readable() != 0)
+        return -1;
+    
+    struct sockaddr_in remoteHost;
+    std::memset(&remoteHost, 0, sizeof(struct sockaddr_in));
     
-    ret = ::recvfrom(m_sock, data + readLen, length - readLen, 0, (struct sockaddr*)&remoteHost, &remoteHostLen);
-    if( ret > 0)
-    {
-      readLen += ret;
-    }
-    else if( ret == 0 )
-    {
-      //Connection was closed by server -- FIXME how do we signal that the connection was closed ?
-      //Continue and populate address
-    }
-    else
-    {
-      return -1; //Connection error
-    }
-  } while(0);
-  
-  static char hostBuf[16];
-  inet_ntoa_r(remoteHost.sin_addr, hostBuf, sizeof(hostBuf));
-  
-  *host = hostBuf;
-  *port = ntohs(remoteHost.sin_port);
-  
-  return readLen;
+    socklen_t remoteHostLen = sizeof(remoteHost);
+    int n = lwip_recvfrom(_sock_fd, data, length, 0, (struct sockaddr*) &remoteHost, &remoteHostLen);
+    if (n < 0)
+        return -1;
+    
+    static char hostBuf[16];
+    inet_ntoa_r(remoteHost.sin_addr, hostBuf, sizeof(hostBuf));
+    
+    *host = hostBuf;
+    *port = ntohs(remoteHost.sin_port);
+    
+    return n;
 }
 
-int UDPSocket::close()
-{
-  if( m_sock < 0 )
-  {
-    return -1;
-  }
-
-  ::close(m_sock);
-  m_sock = -1;
-  
-  return 0;
+UDPSocket::~UDPSocket() {
+    close(); //Don't want to leak
 }
-
-int UDPSocket::init()
-{
-  if( m_sock != -1 )
-  {
-    return -1;
-  }
-  m_sock = ::socket(AF_INET, SOCK_DGRAM, 0); //UDP socket
-  if (m_sock < 0)
-  {
-    return -1; //Could not create socket (Out of memory / available descriptors)
-  }
-  return 0;
-}
--- a/UDPSocket.h	Mon Jul 23 11:52:50 2012 +0000
+++ b/UDPSocket.h	Wed Jul 25 14:59:37 2012 +0000
@@ -19,23 +19,21 @@
 #ifndef UDPSOCKET_H
 #define UDPSOCKET_H
 
-#include "Socket/socket.h"
+#include "Socket/Socket.h"
 #include <cstdint>
 
 /**
 This is a C++ abstraction for UDP networking sockets.
 */
-class UDPSocket
-{
+class UDPSocket : public Socket {
   public:
-  
     /** Instantiate a UDP Socket.
     */
     UDPSocket();
     
     ~UDPSocket();
-
-    /** Bind a socket to a specific port.
+    
+    /** Bind a UDP Server Socket to a specific port
     For a listening socket, bind the socket to the following port.
     \param port The port to listen for incoming connections on, using 0 here will select a random port.
     \return 0 on success, -1 on failure.
@@ -61,16 +59,6 @@
     \return the number of received bytes on success (>=0) or -1 on failure
     */
     int receiveFrom(char* data, int length, char** host, int* port, int timeout = 0);
-
-    /** Close the socket.
-    */
-    int close();
-
-  private:
-    int init();
-
-    int m_sock;
-  
 };
 
 #endif 
--- a/socket.h	Mon Jul 23 11:52:50 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-#ifndef SOCKET_H_
-#define SOCKET_H_
-
-#include "lwip/sockets.h"
-
-#define OK 0                //No error
-
-#define NET_FULL 1          //>All available resources are already used
-#define NET_EMPTY 2         //>No resource
-#define NET_NOTFOUND 3      //>Element cannot be found
-#define NET_INVALID 4       //>Invalid
-#define NET_CONTEXT 5       //>Called in a wrong context (eg during an interrupt)
-#define NET_TIMEOUT 6       //>Timeout
-#define NET_UNKNOWN 7       //>Unknown error
-#define NET_OVERFLOW 8      //>Overflow
-#define NET_PROCESSING 9    //>Command is processing
-#define NET_INTERRUPTED 10  //>Current operation has been interrupted
-#define NET_MOREINFO 11     //>More info on this error can be retrieved elsewhere (eg in a parameter passed as ptr)
-#define NET_ABORT 12        //>Current operation must be aborted
-#define NET_DIFF 13         //>Items that should match are different
-#define NET_AUTH 14         //>Authentication failed
-#define NET_PROTOCOL 15     //>Protocol error
-#define NET_OOM 16          //>Out of memory
-#define NET_CONN 17         //>Connection error
-#define NET_CLOSED 18       //>Connection was closed by remote end
-#define NET_TOOSMALL 19     //>Buffer is too small
-
-inline int accept(int s, struct sockaddr *addr, socklen_t *addrlen) {
-  return lwip_accept(s, addr, addrlen);
-}
-
-inline int bind(int s, const struct sockaddr *name, socklen_t namelen) {
-  return lwip_bind(s, name, namelen);
-}
-
-inline int shutdown(int s, int how) {
-  return lwip_shutdown(s, how);
-}
-
-inline int getsockname (int s, struct sockaddr *name, socklen_t *namelen) {
-  return lwip_getsockname(s, name, namelen);
-}
-
-inline int getpeername (int s, struct sockaddr *name, socklen_t *namelen) {
-  return lwip_getpeername(s, name, namelen);
-}
-
-inline int getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen) {
-  return lwip_getsockopt(s, level, optname, optval, optlen);
-}
-
-inline int setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen) {
-  return lwip_setsockopt(s, level, optname, optval, optlen);
-}
-
-inline int connect(int s, const struct sockaddr *name, socklen_t namelen) {
-  return lwip_connect(s, name, namelen);
-}
-
-inline int listen(int s, int backlog) {
-  return lwip_listen(s, backlog);
-}
-
-inline int recv(int s, void *mem, size_t len, int flags) {
-  return lwip_recv(s, mem, len, flags);
-}
-
-inline int recvfrom(int s, void *mem, size_t len, int flags,
-      struct sockaddr *from, socklen_t *fromlen) {
-  return lwip_recvfrom(s, mem, len, flags, from, fromlen);
-}
-
-inline int send(int s, const void *dataptr, size_t size, int flags) {
-  return lwip_send(s, dataptr, size, flags);
-}
-
-inline int sendto(int s, const void *dataptr, size_t size, int flags,
-    const struct sockaddr *to, socklen_t tolen) {
-  return lwip_sendto(s, dataptr, size, flags, to, tolen);
-}
-
-inline int socket(int domain, int type, int protocol) {
-  return lwip_socket(domain, type, protocol);
-}
-
-inline int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
-                struct timeval *timeout) {
-  return lwip_select(maxfdp1, readset, writeset, exceptset, timeout);
-}
-
-inline int ioctlsocket(int s, long cmd, void *argp) {
-  return lwip_ioctl(s, cmd, argp);
-}
-
-inline int read(int s, void *mem, size_t len) {
-  return lwip_read(s, mem, len);
-}
-
-inline int write(int s, const void *dataptr, size_t size) {
-  return lwip_write(s, dataptr, size);
-}
-
-inline int close(int s) {
-  return lwip_close(s);
-}
-
-#include "lwip/netdb.h"
-
-//DNS
-inline struct hostent *gethostbyname(const char *name) {
-  return lwip_gethostbyname(name);
-}
-
-inline int gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) {
-  return lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop);
-}
-
-inline void freeaddrinfo(struct addrinfo *ai) {
-  return lwip_freeaddrinfo(ai);
-}
-
-inline int getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res) {
-  return lwip_getaddrinfo(nodename, servname, hints, res);
-}
-
-#endif /* SOCKET_H_ */