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:
Fri Mar 01 15:30:16 2013 +0000
Parent:
15:41e3af01f58e
Child:
17:c5089d058eab
Commit message:
Add broadcasting and multicasting

Changed in this revision

Endpoint.cpp Show annotated file Show diff for this revision Revisions of this file
Endpoint.h Show annotated file Show diff for this revision Revisions of this file
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
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
--- a/Endpoint.cpp	Mon Aug 13 09:38:00 2012 +0000
+++ b/Endpoint.cpp	Fri Mar 01 15:30:16 2013 +0000
@@ -1,61 +1,73 @@
-/* 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 "Socket/Endpoint.h"
-#include <cstring>
-
-using std::memset;
-
-Endpoint::Endpoint()  {
-    reset_address();
-}
-Endpoint::~Endpoint() {}
-
-void Endpoint::reset_address(void) {
-    memset(&_remoteHost, 0, sizeof(struct sockaddr_in));
-    _ipAddress[0] = '\0';
-}
-
-int Endpoint::set_address(const char* host, const int port) {
-    //Resolve DNS address or populate hard-coded IP address
-    struct hostent *server = ::gethostbyname(host);
-    if (server == NULL)
-        return -1; //Could not resolve address
-    
-    reset_address();
-    
-    // Set IP address
-    std::memcpy((char*) &_remoteHost.sin_addr.s_addr,
-                (char*) server->h_addr_list[0], server->h_length);
-    _remoteHost.sin_family = AF_INET;
-    
-    // Set port
-    _remoteHost.sin_port = htons(port);
-    
-    return 0;
-}
-
-char* Endpoint::get_address() {
-    if ((_ipAddress[0] == '\0') && (_remoteHost.sin_addr.s_addr != 0))
-            inet_ntoa_r(_remoteHost.sin_addr, _ipAddress, sizeof(_ipAddress));
-    return _ipAddress;
-}
-
-int   Endpoint::get_port() {
-    return ntohs(_remoteHost.sin_port);
-}
+/* 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 "Socket/Endpoint.h"
+#include <cstring>
+#include <cstdio>
+
+Endpoint::Endpoint()  {
+    reset_address();
+}
+Endpoint::~Endpoint() {}
+
+void Endpoint::reset_address(void) {
+    std::memset(&_remoteHost, 0, sizeof(struct sockaddr_in));
+    _ipAddress[0] = '\0';
+}
+
+#include "stdio.h"
+
+int Endpoint::set_address(const char* host, const int port) {
+    reset_address();
+    
+    // IP Address
+    char address[5];
+    char *p_address = address;
+    
+    // Dot-decimal notation
+    int result = std::sscanf(host, "%3u.%3u.%3u.%3u",
+        (unsigned int*)&address[0], (unsigned int*)&address[1],
+        (unsigned int*)&address[2], (unsigned int*)&address[3]);
+    
+    if (result != 4) {
+        // Resolve address with DNS
+        struct hostent *host_address = lwip_gethostbyname(host);
+        if (host_address == NULL)
+            return -1; //Could not resolve address
+        p_address = (char*)host_address->h_addr_list[0];
+    }
+    std::memcpy((char*)&_remoteHost.sin_addr.s_addr, p_address, 4);
+    
+    // Address family
+    _remoteHost.sin_family = AF_INET;
+    
+    // Set port
+    _remoteHost.sin_port = htons(port);
+    
+    return 0;
+}
+
+char* Endpoint::get_address() {
+    if ((_ipAddress[0] == '\0') && (_remoteHost.sin_addr.s_addr != 0))
+            inet_ntoa_r(_remoteHost.sin_addr, _ipAddress, sizeof(_ipAddress));
+    return _ipAddress;
+}
+
+int   Endpoint::get_port() {
+    return ntohs(_remoteHost.sin_port);
+}
--- a/Endpoint.h	Mon Aug 13 09:38:00 2012 +0000
+++ b/Endpoint.h	Fri Mar 01 15:30:16 2013 +0000
@@ -1,63 +1,63 @@
-/* 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 ENDPOINT_H
-#define ENDPOINT_H
-
-class UDPSocket;
-
-/**
-IP Endpoint (address, port)
-*/
-class Endpoint {
-    friend class UDPSocket;
-
-public:
-    /** IP Endpoint (address, port)
-     */
-    Endpoint(void);
-    
-    ~Endpoint(void);
-    
-    /** Reset the address of this endpoint
-     */
-    void reset_address(void);
-    
-    /** Set the address of this endpoint
-    \param host The endpoint address (it can either be an IP Address or a hostname that will be resolved with DNS).
-    \param port The endpoint port
-    \return 0 on success, -1 on failure (when an hostname cannot be resolved by DNS).
-     */
-    int  set_address(const char* host, const int port);
-    
-    /** Get the IP address of this endpoint
-    \return The IP address of this endpoint.
-     */
-    char* get_address(void);
-    
-    /** Get the port of this endpoint
-    \return The port of this endpoint
-     */
-    int get_port(void);
-
-protected:
-    char _ipAddress[16];
-    struct sockaddr_in _remoteHost;
-
-};
-
-#endif
+/* 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 ENDPOINT_H
+#define ENDPOINT_H
+
+class UDPSocket;
+
+/**
+IP Endpoint (address, port)
+*/
+class Endpoint {
+    friend class UDPSocket;
+
+public:
+    /** IP Endpoint (address, port)
+     */
+    Endpoint(void);
+    
+    ~Endpoint(void);
+    
+    /** Reset the address of this endpoint
+     */
+    void reset_address(void);
+    
+    /** Set the address of this endpoint
+    \param host The endpoint address (it can either be an IP Address or a hostname that will be resolved with DNS).
+    \param port The endpoint port
+    \return 0 on success, -1 on failure (when an hostname cannot be resolved by DNS).
+     */
+    int  set_address(const char* host, const int port);
+    
+    /** Get the IP address of this endpoint
+    \return The IP address of this endpoint.
+     */
+    char* get_address(void);
+    
+    /** Get the port of this endpoint
+    \return The port of this endpoint
+     */
+    int get_port(void);
+
+protected:
+    char _ipAddress[17];
+    struct sockaddr_in _remoteHost;
+
+};
+
+#endif
--- a/Socket.cpp	Mon Aug 13 09:38:00 2012 +0000
+++ b/Socket.cpp	Fri Mar 01 15:30:16 2013 +0000
@@ -1,81 +1,89 @@
-/* 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), _blocking(true), _timeout(1500) {
-    
-}
-
-void Socket::set_blocking(bool blocking, unsigned int timeout) {
-    _blocking = blocking;
-    _timeout = timeout;
-}
-
-int Socket::init_socket(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;
-}
-
-int Socket::select(struct timeval *timeout, bool read, bool write) {
-    fd_set fdSet;
-    FD_ZERO(&fdSet);
-    FD_SET(_sock_fd, &fdSet);
-    
-    fd_set* readset  = (read ) ? (&fdSet) : (NULL);
-    fd_set* writeset = (write) ? (&fdSet) : (NULL);
-    
-    int ret = lwip_select(FD_SETSIZE, readset, writeset, NULL, timeout);
-    return (ret <= 0 || !FD_ISSET(_sock_fd, &fdSet)) ? (-1) : (0);
-}
-
-int Socket::wait_readable(TimeInterval& timeout) {
-    return select(&timeout._time, true, false);
-}
-
-int Socket::wait_writable(TimeInterval& timeout) {
-    return select(&timeout._time, false, true);
-}
-
-int Socket::close() {
-    if (_sock_fd < 0)
-        return -1;
-    
-    lwip_close(_sock_fd);
-    _sock_fd = -1;
-    
-    return 0;
-}
-
-Socket::~Socket() {
-    close(); //Don't want to leak
-}
-
-TimeInterval::TimeInterval(unsigned int ms) {
-    _time.tv_sec = ms / 1000;
-    _time.tv_usec = (ms - (_time.tv_sec * 1000)) * 1000;
-}
+/* 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), _blocking(true), _timeout(1500) {
+    
+}
+
+void Socket::set_blocking(bool blocking, unsigned int timeout) {
+    _blocking = blocking;
+    _timeout = timeout;
+}
+
+int Socket::init_socket(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;
+}
+
+int Socket::set_option(int level, int optname, const void *optval, socklen_t optlen) {
+    return lwip_setsockopt(_sock_fd, level, optname, optval, optlen);
+}
+
+int Socket::get_option(int level, int optname, void *optval, socklen_t *optlen) {
+    return lwip_getsockopt(_sock_fd, level, optname, optval, optlen);
+}
+
+int Socket::select(struct timeval *timeout, bool read, bool write) {
+    fd_set fdSet;
+    FD_ZERO(&fdSet);
+    FD_SET(_sock_fd, &fdSet);
+    
+    fd_set* readset  = (read ) ? (&fdSet) : (NULL);
+    fd_set* writeset = (write) ? (&fdSet) : (NULL);
+    
+    int ret = lwip_select(FD_SETSIZE, readset, writeset, NULL, timeout);
+    return (ret <= 0 || !FD_ISSET(_sock_fd, &fdSet)) ? (-1) : (0);
+}
+
+int Socket::wait_readable(TimeInterval& timeout) {
+    return select(&timeout._time, true, false);
+}
+
+int Socket::wait_writable(TimeInterval& timeout) {
+    return select(&timeout._time, false, true);
+}
+
+int Socket::close() {
+    if (_sock_fd < 0)
+        return -1;
+    
+    lwip_close(_sock_fd);
+    _sock_fd = -1;
+    
+    return 0;
+}
+
+Socket::~Socket() {
+    close(); //Don't want to leak
+}
+
+TimeInterval::TimeInterval(unsigned int ms) {
+    _time.tv_sec = ms / 1000;
+    _time.tv_usec = (ms - (_time.tv_sec * 1000)) * 1000;
+}
--- a/Socket.h	Mon Aug 13 09:38:00 2012 +0000
+++ b/Socket.h	Fri Mar 01 15:30:16 2013 +0000
@@ -1,85 +1,103 @@
-/* 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 TimeInterval;
-
-/** Socket file descriptor and select wrapper
-  */
-class Socket {
-public:
-    /** Socket
-     */
-    Socket();
-    
-    /** Set blocking or non-blocking mode of the socket and a timeout on
-        blocking socket operations
-    \param blocking  true for blocking mode, false for non-blocking mode.
-    \param timeout   timeout in ms [Default: (1500)ms].
-    */
-    void set_blocking(bool blocking, unsigned int timeout=1500);
-    
-    /** Close the socket file descriptor
-     */
-    int close();
-    
-    ~Socket();
-    
-protected:
-    int _sock_fd;
-    int init_socket(int type);
-    
-    int wait_readable(TimeInterval& timeout);
-    int wait_writable(TimeInterval& timeout);
-    
-    bool _blocking;
-    unsigned int _timeout;
-    
-private:
-    int select(struct timeval *timeout, bool read, bool write);
-};
-
-/** Time interval class used to specify timeouts
- */
-class TimeInterval {
-    friend class Socket;
-
-public:
-    /** Time Interval
-     \param ms time interval expressed in milliseconds
-      */
-    TimeInterval(unsigned int ms);
-    
-private:
-    struct timeval _time;
-};
-
-#endif /* SOCKET_H_ */
+/* 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 TimeInterval;
+
+/** Socket file descriptor and select wrapper
+  */
+class Socket {
+public:
+    /** Socket
+     */
+    Socket();
+    
+    /** Set blocking or non-blocking mode of the socket and a timeout on
+        blocking socket operations
+    \param blocking  true for blocking mode, false for non-blocking mode.
+    \param timeout   timeout in ms [Default: (1500)ms].
+    */
+    void set_blocking(bool blocking, unsigned int timeout=1500);
+    
+    /** Set socket options
+    \param level     stack level (see: lwip/sockets.h)
+    \param optname   option ID
+    \param optval    option value
+    \param socklen_t length of the option value
+    \return 0 on success, -1 on failure
+    */
+    int set_option(int level, int optname, const void *optval, socklen_t optlen);
+    
+    /** Get socket options
+        \param level     stack level (see: lwip/sockets.h)
+        \param optname   option ID
+        \param optval    buffer pointer where to write the option value
+        \param socklen_t length of the option value
+        \return 0 on success, -1 on failure
+        */
+    int get_option(int level, int optname, void *optval, socklen_t *optlen);
+    
+    /** Close the socket file descriptor
+     */
+    int close();
+    
+    ~Socket();
+    
+protected:
+    int _sock_fd;
+    int init_socket(int type);
+    
+    int wait_readable(TimeInterval& timeout);
+    int wait_writable(TimeInterval& timeout);
+    
+    bool _blocking;
+    unsigned int _timeout;
+    
+private:
+    int select(struct timeval *timeout, bool read, bool write);
+};
+
+/** Time interval class used to specify timeouts
+ */
+class TimeInterval {
+    friend class Socket;
+
+public:
+    /** Time Interval
+     \param ms time interval expressed in milliseconds
+      */
+    TimeInterval(unsigned int ms);
+    
+private:
+    struct timeval _time;
+};
+
+#endif /* SOCKET_H_ */
--- a/TCPSocketConnection.h	Mon Aug 13 09:38:00 2012 +0000
+++ b/TCPSocketConnection.h	Fri Mar 01 15:30:16 2013 +0000
@@ -45,40 +45,32 @@
     */
     bool is_connected(void);
     
-    /*! \brief Send data to the remote host. Applications are responsible for 
-     *         checking that all data has been sent; if only some of the data was
-     *         transmitted, the application needs to attempt delivery of the
-     *         remaining data.
-     * \param data The buffer to send to the host.
-     * \param length The length of the buffer to send.
-     * \return the number of written bytes on success (>=0) or -1 on failure
+    /** Send data to the remote host.
+    \param data The buffer to send to the host.
+    \param length The length of the buffer to send.
+    \return the number of written bytes on success (>=0) or -1 on failure
      */
     int send(char* data, int length);
     
-    /*! \brief Send all the data to the remote host. This method continues to send
-     *         data until either all data has been sent, or an error occurs, or a
-     *         timeout occurs.
-     * \param data The buffer to send to the host.
-     * \param length The length of the buffer to send.
-     * \return the number of written bytes on success (>=0) or -1 on failure
-     */
+    /** Send all the data to the remote host.
+    \param data The buffer to send to the host.
+    \param length The length of the buffer to send.
+    \return the number of written bytes on success (>=0) or -1 on failure
+    */
     int send_all(char* data, int length);
     
-    /*! \brief Receive data from the remote host. Return as soon as some data is
-     *         available.
-     * \param data The buffer in which to store the data received from the host.
-     * \param length The maximum length of the buffer.
-     * \return the number of received bytes on success (>=0) or -1 on failure
+    /** 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.
+    \return the number of received bytes on success (>=0) or -1 on failure
      */
     int receive(char* data, int length);
     
-    /*! \brief Receive all the data from the remote host. This method continues to receive
-     *         data until either length bytes has been received, or an error occurs, or a
-     *         timeout occurs.
-     * \param data The buffer in which to store the data received from the host.
-     * \param length The maximum length of the buffer.
-     * \return the number of received bytes on success (>=0) or -1 on failure
-     */
+    /** Receive all the 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.
+    \return the number of received bytes on success (>=0) or -1 on failure
+    */
     int receive_all(char* data, int length);
 
 private:
--- a/TCPSocketServer.cpp	Mon Aug 13 09:38:00 2012 +0000
+++ b/TCPSocketServer.cpp	Fri Mar 01 15:30:16 2013 +0000
@@ -1,78 +1,78 @@
-/* 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_socket(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) {
-    if (_sock_fd < 0)
-        return -1;
-    
-    if (!_blocking) {
-        TimeInterval timeout(_timeout);
-        if (wait_readable(timeout) != 0)
-            return -1;
-    }
-    connection.reset_address();
-    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;
-    connection._is_connected = true;
-    
-    return 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 "TCPSocketServer.h"
+
+#include <cstring>
+
+using std::memset;
+using std::memcpy;
+
+TCPSocketServer::TCPSocketServer() {
+    
+}
+
+int TCPSocketServer::bind(int port) {
+    if (init_socket(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) {
+    if (_sock_fd < 0)
+        return -1;
+    
+    if (!_blocking) {
+        TimeInterval timeout(_timeout);
+        if (wait_readable(timeout) != 0)
+            return -1;
+    }
+    connection.reset_address();
+    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;
+    connection._is_connected = true;
+    
+    return 0;
+}
--- a/TCPSocketServer.h	Mon Aug 13 09:38:00 2012 +0000
+++ b/TCPSocketServer.h	Fri Mar 01 15:30:16 2013 +0000
@@ -1,52 +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"
-
-/** TCP Server.
-  */
-class TCPSocketServer : public Socket {
-  public:
-    /** Instantiate a TCP Server.
-    */
-    TCPSocketServer();
-    
-    /** Bind a socket to a specific port.
-    \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 backlog number of pending connections that can be queued up at any
-                   one time [Default: 1].
-    \return 0 on success, -1 on failure.
-    */
-    int listen(int backlog=1);
-    
-    /** Accept a new connection.
-    \param connection A TCPSocketConnection instance that will handle the incoming connection.
-    \return 0 on success, -1 on failure.
-    */
-    int accept(TCPSocketConnection& connection);
-};
-
-#endif
+/* 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"
+
+/** TCP Server.
+  */
+class TCPSocketServer : public Socket {
+  public:
+    /** Instantiate a TCP Server.
+    */
+    TCPSocketServer();
+    
+    /** Bind a socket to a specific port.
+    \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 backlog number of pending connections that can be queued up at any
+                   one time [Default: 1].
+    \return 0 on success, -1 on failure.
+    */
+    int listen(int backlog=1);
+    
+    /** Accept a new connection.
+    \param connection A TCPSocketConnection instance that will handle the incoming connection.
+    \return 0 on success, -1 on failure.
+    */
+    int accept(TCPSocketConnection& connection);
+};
+
+#endif
--- a/UDPSocket.cpp	Mon Aug 13 09:38:00 2012 +0000
+++ b/UDPSocket.cpp	Fri Mar 01 15:30:16 2013 +0000
@@ -49,6 +49,21 @@
     return 0;
 }
 
+int UDPSocket::join_multicast_group(const char* address) {
+    struct ip_mreq mreq;
+    
+    // Set up group address 
+    mreq.imr_multiaddr.s_addr = inet_addr(address);
+    mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+    
+    return set_option(IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
+}
+
+int UDPSocket::set_broadcasting(void) {
+    int option = 1;
+    return set_option(SOL_SOCKET, SO_BROADCAST, &option, sizeof(option));
+}
+
 // -1 if unsuccessful, else number of bytes written
 int UDPSocket::sendTo(Endpoint &remote, char *packet, int length) {
     if (_sock_fd < 0)
--- a/UDPSocket.h	Mon Aug 13 09:38:00 2012 +0000
+++ b/UDPSocket.h	Fri Mar 01 15:30:16 2013 +0000
@@ -45,6 +45,17 @@
     */
     int bind(int port);
     
+    /** Join the multicast group at the given address
+    \param address  The address of the multicast group
+    \return 0 on success, -1 on failure.
+    */
+    int join_multicast_group(const char* address);
+    
+    /** Set the socket in broadcasting mode
+    \return 0 on success, -1 on failure.
+    */
+    int set_broadcasting(void);
+    
     /** Send a packet to a remote endpoint
     \param remote   The remote endpoint
     \param packet   The packet to be sent