Base class for IP Based Networking Libraries

Dependencies:   DnsQuery

Dependents:   TempTower BSDInterfaceTests HelloBSDInterface ESP8266InterfaceTests ... more

For a complete getting started guide see the wiki...

Network Socket API

The Network Socket API provides a common interface for using sockets on network devices. The API provides a simple class-based interface that should be familiar to users experienced with other socket APIs. Additionally, the API provides a simple interface for implementing network devices, making it easy to connect hardware agnostic programs to new devices.

Network Interfaces

The NetworkInterface provides an abstract class for network devices that support sockets. Devices should provide a DeviceInterface class that inherits this interface and adds implementation specific methods for using the device. A NetworkInterface must be provided to a Socket constructor to open a socket on the interface. Currently two subclasses are defined for common devices, EthernetInterface and WiFiInterface.

Sockets

The Socket class is used for managing network sockets. Once opened, the socket provides a pipe through which data can sent and recieved to a specific endpoint. The socket class can be instantiated as either a TCPSocket or a UDPSocket which defines the protocol used for the connection.

Files at this revision

API Documentation at this revision

Comitter:
Christopher Haster
Date:
Tue Apr 19 18:23:29 2016 -0500
Parent:
91:cad29ce6a01c
Child:
93:65a9f84862f0
Commit message:
Move to single state-change interrupt

Pros
- Easier to implement
- More similar to SIGIO in BDS sockets

Cons
- Less information, but this information had a high risk of being
faulty/spurious

Changed in this revision

NetworkInterface.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
TCPServer.cpp Show annotated file Show diff for this revision Revisions of this file
TCPServer.h Show annotated file Show diff for this revision Revisions of this file
TCPSocket.cpp Show annotated file Show diff for this revision Revisions of this file
TCPSocket.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/NetworkInterface.h	Tue Apr 19 18:23:12 2016 -0500
+++ b/NetworkInterface.h	Tue Apr 19 18:23:29 2016 -0500
@@ -204,29 +204,13 @@
      */
     virtual int socket_close(void *handle) = 0;
 
-    /** Register a callback on when a new connection is ready
-     *  @param handle   Socket handle
-     *  @param callback Function to call when accept will succeed, may be called in
-     *                  interrupt context.
-     *  @param id       Argument to pass to callback
-     */
-    virtual void socket_attach_accept(void *handle, void (*callback)(void *), void *id) = 0;
-
-    /** Register a callback on when send is ready
+    /** Register a callback on state change of the socket
      *  @param handle   Socket handle
-     *  @param callback Function to call when accept will succeed, may be called in
-     *                  interrupt context.
-     *  @param id       Argument to pass to callback
+     *  @param callback Function to call on state change
+     *  @param data     Argument to pass to callback
+     *  @note Callback may be called in an interrupt context.
      */
-    virtual void socket_attach_send(void *handle, void (*callback)(void *), void *id) = 0;
-
-    /** Register a callback on when recv is ready
-     *  @param handle   Socket handle
-     *  @param callback Function to call when accept will succeed, may be called in
-     *                  interrupt context.
-     *  @param id       Argument to pass to callback
-     */
-    virtual void socket_attach_recv(void *handle, void (*callback)(void *), void *id) = 0;
+    virtual void socket_attach(void *handle, void (*callback)(void *), void *data) = 0;
 };
 
 #endif
--- a/Socket.cpp	Tue Apr 19 18:23:12 2016 -0500
+++ b/Socket.cpp	Tue Apr 19 18:23:29 2016 -0500
@@ -35,6 +35,7 @@
 {
     _iface = iface;
     _socket = _iface->socket_create(proto);
+    _iface->socket_attach(_socket, &Socket::thunk, this);
 }
 
 int Socket::close()
@@ -81,8 +82,15 @@
     return _iface->socket_get_option(_socket, optname, optval, optlen);
 }
 
-void Socket::thunk(void *p) 
+void Socket::thunk(void *data)
 {
-    FunctionPointer *fptr = (FunctionPointer *)p;
-    (*fptr)();
+    Socket *self = (Socket *)data;
+    if (self->_callback) {
+        self->_callback();
+    }
 }
+
+void Socket::attach(FunctionPointer callback)
+{
+    _callback = callback;
+}
--- a/Socket.h	Tue Apr 19 18:23:12 2016 -0500
+++ b/Socket.h	Tue Apr 19 18:23:29 2016 -0500
@@ -63,6 +63,19 @@
      */
     int close();
 
+    /** Register a callback on state change of the socket
+     *  @param callback Function to call on state change
+     *  @note Callback may be called in an interrupt context.
+     *        The callback should not perform long operations 
+     *        such as recv or send calls.
+     */
+    void attach(FunctionPointer callback);
+
+    template <typename T, typename M>
+    void attach(T *tptr, M mptr) {
+        attach(FunctionPointer(tptr, mptr));
+    }
+
 protected:
     Socket();
     int open(NetworkInterface *iface, nsapi_protocol_t proto);
@@ -73,6 +86,7 @@
     void *_socket;
     bool _blocking;
     unsigned _timeout;
+    FunctionPointer _callback;
 };
 
 #endif
--- a/TCPServer.cpp	Tue Apr 19 18:23:12 2016 -0500
+++ b/TCPServer.cpp	Tue Apr 19 18:23:29 2016 -0500
@@ -76,22 +76,3 @@
         }
     }
 }
-
-
-void TCPServer::attach_accept(FunctionPointer callback)
-{
-    _accept_cb = callback;
-
-    if (_socket && _accept_cb) {
-        return _iface->socket_attach_accept(_socket, Socket::thunk, &_accept_cb);
-    } else if (_socket) {
-        return _iface->socket_attach_accept(_socket, 0, 0);
-    }
-}
-
-TCPServer::~TCPServer()
-{
-    if (_socket && _accept_cb) {
-        _iface->socket_attach_accept(_socket, 0, 0);
-    }
-}
--- a/TCPServer.h	Tue Apr 19 18:23:12 2016 -0500
+++ b/TCPServer.h	Tue Apr 19 18:23:29 2016 -0500
@@ -54,20 +54,6 @@
      * @return          0 on success, negative on failure.
      */
     int accept(TCPSocket *connection);
-
-    /** Register a callback on when a new connection is ready
-     * @param callback  Function to call when accept will succeed, may be called in
-     *                  interrupt context.
-     */
-    void attach_accept(FunctionPointer callback);
-
-    template <typename T, typename M>
-    void attach_accept(T *tptr, M mptr) {
-        attach_accept(FunctionPointer(tptr, mptr));
-    }
-
-private:
-    FunctionPointer _accept_cb;
 };
 
 #endif
--- a/TCPSocket.cpp	Tue Apr 19 18:23:12 2016 -0500
+++ b/TCPSocket.cpp	Tue Apr 19 18:23:29 2016 -0500
@@ -90,37 +90,3 @@
         }
     }
 }
-
-
-void TCPSocket::attach_send(FunctionPointer callback)
-{
-    _send_cb = callback;
-
-    if (_socket && _send_cb) {
-        return _iface->socket_attach_send(_socket, Socket::thunk, &_send_cb);
-    } else if (_socket) {
-        return _iface->socket_attach_send(_socket, 0, 0);
-    }
-}
-
-void TCPSocket::attach_recv(FunctionPointer callback)
-{
-    _recv_cb = callback;
-
-    if (_socket && _recv_cb) {
-        return _iface->socket_attach_recv(_socket, Socket::thunk, &_recv_cb);
-    } else if (_socket) {
-        return _iface->socket_attach_recv(_socket, 0, 0);
-    }
-}
-
-TCPSocket::~TCPSocket()
-{
-    if (_socket && _send_cb) {
-        _iface->socket_attach_send(_socket, 0, 0);
-    }
-
-    if (_socket && _recv_cb) {
-        _iface->socket_attach_recv(_socket, 0, 0);
-    }
-}
--- a/TCPSocket.h	Tue Apr 19 18:23:12 2016 -0500
+++ b/TCPSocket.h	Tue Apr 19 18:23:29 2016 -0500
@@ -28,7 +28,6 @@
      */
     TCPSocket();
     TCPSocket(NetworkInterface *iface);
-    virtual ~TCPSocket();
 
     /** Open the socket
      *  @param iface    Interface to open socket on
@@ -68,33 +67,8 @@
      */
     int recv(void *data, unsigned size);
 
-    /** Register a callback on when send is ready
-     *  @param callback Function to call when send will succeed, may be called in
-     *                  interrupt context.
-     */
-    void attach_send(FunctionPointer callback);
-
-    template <typename T, typename M>
-    void attach_send(T *tptr, M mptr) {
-        attach_send(FunctionPointer(tptr, mptr));
-    }
-
-    /** Register a callback on when recv is ready
-     *  @param callback Function to call when recv will succeed, may be called in
-     *                  interrupt context.
-     */
-    void attach_recv(FunctionPointer callback);
-
-    template <typename T, typename M>
-    void attach_recv(T *tptr, M mptr) {
-        attach_recv(FunctionPointer(tptr, mptr));
-    }
-
 private:
     friend class TCPServer;
-
-    FunctionPointer _send_cb;
-    FunctionPointer _recv_cb;
 };
 
 #endif
--- a/UDPSocket.cpp	Tue Apr 19 18:23:12 2016 -0500
+++ b/UDPSocket.cpp	Tue Apr 19 18:23:29 2016 -0500
@@ -75,35 +75,3 @@
         }
     }
 }
-
-
-void UDPSocket::attach_send(FunctionPointer callback)
-{
-    _send_cb = callback;
-    if (_socket && _send_cb) {
-        return _iface->socket_attach_send(_socket, Socket::thunk, &_send_cb);
-    } else if (_socket) {
-        return _iface->socket_attach_send(_socket, 0, 0);
-    }
-}
-
-void UDPSocket::attach_recv(FunctionPointer callback)
-{
-    _recv_cb = callback;
-    if (_socket && _recv_cb) {
-        return _iface->socket_attach_recv(_socket, Socket::thunk, &_recv_cb);
-    } else if (_socket) {
-        return _iface->socket_attach_recv(_socket, 0, 0);
-    }
-}
-
-UDPSocket::~UDPSocket()
-{
-    if (_socket && _send_cb) {
-        _iface->socket_attach_send(_socket, 0, 0);
-    }
-
-    if (_socket && _recv_cb) {
-        _iface->socket_attach_recv(_socket, 0, 0);
-    }
-}
--- a/UDPSocket.h	Tue Apr 19 18:23:12 2016 -0500
+++ b/UDPSocket.h	Tue Apr 19 18:23:29 2016 -0500
@@ -28,7 +28,6 @@
      */
     UDPSocket();
     UDPSocket(NetworkInterface *iface);
-    virtual ~UDPSocket();
 
     /** Open the socket
      *  @param iface    Interface to open socket on
@@ -58,32 +57,6 @@
      *  @return         The number of received bytes on success, negative on failure
      */
     int recvfrom(SocketAddress *address, void *buffer, unsigned size);
-
-    /** Register a callback on when send is ready
-     *  @param callback Function to call when send will succeed, may be called in
-     *                  interrupt context.
-     */
-    void attach_send(FunctionPointer callback);
-
-    template <typename T, typename M>
-    void attach_send(T *tptr, M mptr) {
-        attach_send(FunctionPointer(tptr, mptr));
-    }
-
-    /** Register a callback on when recv is ready
-     *  @param callback Function to call when recv will succeed, may be called in
-     *                  interrupt context.
-     */
-    void attach_recv(FunctionPointer callback);
-
-    template <typename T, typename M>
-    void attach_recv(T *tptr, M mptr) {
-        attach_recv(FunctionPointer(tptr, mptr));
-    }
-
-private:
-    FunctionPointer _send_cb;
-    FunctionPointer _recv_cb;
 };
 
 #endif