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 05 10:40:34 2016 -0500
Parent:
78:0914f9b9b24b
Child:
80:9c6673c93082
Commit message:
Added rough implementation of the API shim

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
SocketAddress.cpp Show annotated file Show diff for this revision Revisions of this file
SocketAddress.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 05 09:20:32 2016 -0500
+++ b/NetworkInterface.h	Tue Apr 05 10:40:34 2016 -0500
@@ -17,6 +17,8 @@
 #ifndef NETWORK_INTERFACE_H
 #define NETWORK_INTERFACE_H
 
+#include "FunctionPointer.h"
+
 /**
  *  @enum ns_error_t
  *  @brief enum of standardized error codes
@@ -75,6 +77,11 @@
     virtual SocketAddress gethostbyname(const char *name, uint16_t port=0);
 
 protected:
+    friend class Socket;
+    friend class UDPSocket;
+    friend class TCPSocket;
+    friend class TCPServer;
+
     /** Enum of socket protocols
     /enum protocol_t
     */
@@ -194,21 +201,21 @@
     \param callback Function to call when accept will succeed, may be called in
                     interrupt context.
     */
-    virtual void socket_attach_accept(void *handle, FuncPtr<void()> callback) = 0;
+    virtual void socket_attach_accept(void *handle, mbed::FuncPtr<void()> callback) = 0;
 
     /** Register a callback on when send is ready
     \param handle   Socket handle
     \param callback Function to call when send will succeed, may be called in
                     interrupt context.
     */
-    virtual void socket_attach_send(void *handle, FuncPtr<void()> callback) = 0;
+    virtual void socket_attach_send(void *handle, mbed::FuncPtr<void()> callback) = 0;
 
     /** Register a callback on when recv is ready
     \param handle   Socket handle
     \param callback Function to call when recv will succeed, may be called in
                     interrupt context.
     */
-    virtual void socket_attach_recv(void *handle, FuncPtr<void()> callback) = 0;
+    virtual void socket_attach_recv(void *handle, mbed::FuncPtr<void()> callback) = 0;
 };
 
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket.cpp	Tue Apr 05 10:40:34 2016 -0500
@@ -0,0 +1,75 @@
+/* Socket
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Socket.h"
+
+Socket::Socket(NetworkInterface *iface, NetworkInterface::protocol_t proto)
+    : _iface(iface)
+{
+    _socket = _iface->socket_create(proto);
+}
+
+Socket::~Socket()
+{
+    if (_socket) {
+        close(false);
+    }
+}
+
+void Socket::set_blocking(bool blocking)
+{
+    _blocking = blocking;
+}
+
+void Socket::set_timeout(unsigned timeout)
+{
+    _timeout = timeout;
+}
+
+int Socket::set_option(int optname, const void *optval, unsigned int optlen)
+{
+    if (!_socket) {
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+
+    return _iface->socket_set_option(_socket, optname, optval, optlen);
+}
+
+int Socket::get_option(int optname, void *optval, unsigned int *optlen)
+{
+    if (!_socket) {
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+
+    return _iface->socket_get_option(_socket, optname, optval, optlen);
+}
+
+int Socket::close(bool shutdown)
+{
+    if (!_socket) {
+        return 0;
+    }
+
+    int err = _iface->socket_close(_socket, shutdown);
+    if (!err) {
+        void *socket = _socket;
+        _socket = 0;
+        _iface->socket_destroy(socket);
+    }
+
+    return err;
+}
+
--- a/Socket.h	Tue Apr 05 09:20:32 2016 -0500
+++ b/Socket.h	Tue Apr 05 10:40:34 2016 -0500
@@ -17,6 +17,8 @@
 #ifndef SOCKET_H
 #define SOCKET_H
 
+#include "SocketAddress.h"
+#include "NetworkInterface.h"
 
 /** Abstract socket class
  */
@@ -24,7 +26,6 @@
 public:
     /** Socket lifetime
      */
-    Socket();
     ~Socket();
     
     /** Set blocking or non-blocking mode of the socket
@@ -57,6 +58,14 @@
     \param shutdown  free the left-over data in message queues
     */
     int close(bool shutdown=true);
+
+protected:
+    Socket(NetworkInterface *iface, NetworkInterface::protocol_t proto);
+
+    NetworkInterface *_iface;
+    void *_socket;
+    bool _blocking;
+    unsigned _timeout;
 };
 
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SocketAddress.cpp	Tue Apr 05 10:40:34 2016 -0500
@@ -0,0 +1,51 @@
+/* Socket
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "SocketAddress.h"
+#include <string.h>
+
+SocketAddress::SocketAddress(const char *addr, uint16_t port)
+{
+    set_ip_address(addr);
+    set_port(port);
+}
+
+SocketAddress::SocketAddress(const SocketAddress &addr)
+{
+    set_ip_address(addr.get_ip_address());
+    set_port(addr.get_port());
+}
+
+void SocketAddress::set_ip_address(const char *addr)
+{
+    strncpy(_ip_address, addr, sizeof _ip_address);
+    _ip_address[sizeof _ip_address - 1] = '\0';
+}
+
+void SocketAddress::set_port(uint16_t port)
+{
+    _port = port;
+}
+
+const char *SocketAddress::get_ip_address() const
+{
+    return _ip_address;
+}
+
+uint16_t SocketAddress::get_port() const
+{
+    return _port;
+}
--- a/SocketAddress.h	Tue Apr 05 09:20:32 2016 -0500
+++ b/SocketAddress.h	Tue Apr 05 10:40:34 2016 -0500
@@ -17,21 +17,24 @@
 #ifndef SOCKET_ADDRESS_H
 #define SOCKET_ADDRESS_H
 
+#include <stdint.h>
+
 /**
  * A general socket address composed of the IP address and port
  */
 class SocketAddress {
 public:
-    /** SocketAddress lifetime 
+    /** SocketAddress construction
+    /param addr Null-terminated string representing the IP address
+    /param port 16-bit port
      */
     SocketAddress(const char *addr = 0, uint16_t port = 0);
     SocketAddress(const SocketAddress &);
-    ~SocketAddress();
    
     /** Set the IP address
-    \param host Null-terminated string representing the IP address
+    \param addr Null-terminated string representing the IP address
      */
-    void set_ip_address(const char *host);
+    void set_ip_address(const char *addr);
 
     /** Set the port
     \param port 16-bit port
@@ -41,12 +44,16 @@
     /** Get the IP address
     \return The string representation of the IP Address
      */
-    const char *get_ip_address();
+    const char *get_ip_address() const;
     
     /** Get the port
     \return The 16-bit port
      */
-    int get_port(void);
+    uint16_t get_port(void) const;
+
+private:
+    char _ip_address[16];
+    uint16_t _port;
 };
 
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TCPServer.cpp	Tue Apr 05 10:40:34 2016 -0500
@@ -0,0 +1,58 @@
+/* Socket
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "TCPServer.h"
+
+TCPServer::TCPServer(NetworkInterface *iface)
+    : Socket(iface, NetworkInterface::TCP)
+{
+}
+
+int TCPServer::bind(uint16_t port)
+{
+    if (!_socket) {
+        return NSAPI_ERROR_NO_SOCKET;   
+    }
+
+    return _iface->socket_bind(_socket, port);
+}
+
+int TCPServer::listen(int backlog)
+{
+    if (!_socket) {
+        return NSAPI_ERROR_NO_SOCKET;   
+    }
+
+    return _iface->socket_listen(_socket, backlog);
+}
+
+int TCPServer::accept(TCPSocket *connection)
+{
+    if (!_socket) {
+        return NSAPI_ERROR_NO_SOCKET;   
+    }
+
+    void *socket = connection->_socket;
+    connection->_socket = 0;
+    _iface->socket_destroy(socket);
+
+    int err = _iface->socket_accept(_socket, &socket);
+    if (!err) {
+        connection->_socket = socket;
+    }
+
+    return err;
+}
--- a/TCPServer.h	Tue Apr 05 09:20:32 2016 -0500
+++ b/TCPServer.h	Tue Apr 05 10:40:34 2016 -0500
@@ -34,7 +34,7 @@
     \param port     The port to listen for incoming connections on
     \return         0 on success, negative on failure
     */
-    int bind(int port);
+    int bind(uint16_t port);
     
     /** Start listening for incoming connections
     \param backlog  Number of pending connections that can be queued up at any
@@ -53,7 +53,7 @@
     \param callback Function to call when accept will succeed, may be called in
                     interrupt context.
     */
-    void attach_accept(FuncPtr<void()> callback);
+    void attach_accept(mbed::FuncPtr<void()> callback);
 };
 
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TCPSocket.cpp	Tue Apr 05 10:40:34 2016 -0500
@@ -0,0 +1,64 @@
+/* Socket
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "TCPSocket.h"
+
+TCPSocket::TCPSocket(NetworkInterface *iface)
+    : Socket(iface, NetworkInterface::TCP)
+{
+}
+
+int TCPSocket::connect(SocketAddress addr)
+{
+    if (!_socket) {
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+
+    return _iface->socket_connect(_socket, addr);
+}
+
+int TCPSocket::connect(const char *host, uint16_t port)
+{
+    SocketAddress addr = _iface->gethostbyname(host, port);
+    if (!addr.get_ip_address()) {
+        return NSAPI_ERROR_DNS_FAILURE;
+    }
+
+    return connect(addr);
+}
+
+bool TCPSocket::is_connected()
+{
+    return _socket && _iface->socket_is_connected(_socket);
+}
+
+int TCPSocket::send(const void *data, unsigned size)
+{
+    if (!_socket) {
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+
+    return _iface->socket_send(_socket, data, size);
+}
+
+int TCPSocket::recv(void *data, unsigned size)
+{
+    if (!_socket) {
+        return NSAPI_ERROR_NO_SOCKET;
+    }
+
+    return _iface->socket_recv(_socket, data, size);
+}
--- a/TCPSocket.h	Tue Apr 05 09:20:32 2016 -0500
+++ b/TCPSocket.h	Tue Apr 05 10:40:34 2016 -0500
@@ -36,7 +36,7 @@
     \param port     The host's port to connect to
     \return         0 on success, negative on failure
     */
-    int connect(const char* host, const int port);
+    int connect(const char *host, uint16_t port);
 
     /** Connects this TCP socket to the server
     \param address  SocketAddress to connect to
@@ -67,13 +67,16 @@
     \param callback Function to call when send will succeed, may be called in
                     interrupt context.
     */
-    void attach_send(FuncPtr<void()> callback);
+    void attach_send(mbed::FuncPtr<void()> callback);
 
     /** 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(FuncPtr<void()> callback);
+    void attach_recv(mbed::FuncPtr<void()> callback);
+
+private:
+    friend class TCPServer;
 };
 
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UDPSocket.cpp	Tue Apr 05 10:40:34 2016 -0500
@@ -0,0 +1,50 @@
+/* Socket
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "UDPSocket.h"
+
+UDPSocket::UDPSocket(NetworkInterface *iface)
+    : Socket(iface, NetworkInterface::UDP)
+{
+}
+
+int UDPSocket::bind(uint16_t port)
+{
+    if (!_socket) {
+        return NSAPI_ERROR_NO_SOCKET;   
+    }
+
+    return _iface->socket_bind(_socket, port);
+}
+
+int UDPSocket::sendto(SocketAddress address, const void *data, unsigned size)
+{
+    if (!_socket) {
+        return NSAPI_ERROR_NO_SOCKET;   
+    }
+
+    return _iface->socket_sendto(_socket, address, data, size);
+}
+
+int UDPSocket::recvfrom(SocketAddress *address, void *buffer, unsigned size)
+{
+    if (!_socket) {
+        return NSAPI_ERROR_NO_SOCKET;   
+    }
+
+    return _iface->socket_recvfrom(_socket, address, buffer, size);
+}
+
--- a/UDPSocket.h	Tue Apr 05 09:20:32 2016 -0500
+++ b/UDPSocket.h	Tue Apr 05 10:40:34 2016 -0500
@@ -34,7 +34,7 @@
     \param port The port to listen for incoming connections on
     \return 0 on success, negative on failure.
     */
-    int bind(int port);
+    int bind(uint16_t port);
 
     /** Send a packet to a remote endpoint
     \param address  The remote SocketAddress
@@ -58,13 +58,13 @@
     \param callback Function to call when send will succeed, may be called in
                     interrupt context.
     */
-    void attach_send(FuncPtr<void()> callback);
+    void attach_send(mbed::FuncPtr<void()> callback);
 
     /** 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(FuncPtr<void()> callback);
+    void attach_recv(mbed::FuncPtr<void()> callback);
 };
 
 #endif