Separate interface from stack in NSAPI

This patch consists of:
-Add NetworkInterface to wrap objects bound to a stack and update
    socket code to handle this in addition to NetworkStacks
-Update MeshInterface to inherit from NetworkInterface
-Update NanostackInterface so it only inherits from NetworkStack
-Add MeshInterfaceNanostack and update LoWPANNDInterface and
    ThreadInterface to inherit from this
pull/2216/head^2
Russ Butler 2016-05-26 23:54:05 -05:00 committed by Christopher Haster
parent 3ee8e30ae4
commit 90cd978785
13 changed files with 198 additions and 33 deletions

View File

@ -1,4 +1,4 @@
/* EthernetInterface /* EthInterface
* Copyright (c) 2015 ARM Limited * Copyright (c) 2015 ARM Limited
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -14,16 +14,16 @@
* limitations under the License. * limitations under the License.
*/ */
#ifndef ETHERNET_INTERFACE_H #ifndef ETH_INTERFACE_H
#define ETHERNET_INTERFACE_H #define ETH_INTERFACE_H
#include "NetworkStack.h" #include "NetworkInterface.h"
/** EthernetInterface class /** EthInterface class
* *
* Common interface that is shared between ethernet hardware. * Common interface that is shared between ethernet hardware.
*/ */
class EthernetInterface class EthInterface : public NetworkInterface
{ {
public: public:
/** Start the interface /** Start the interface

View File

@ -17,13 +17,13 @@
#ifndef MESH_INTERFACE_H #ifndef MESH_INTERFACE_H
#define MESH_INTERFACE_H #define MESH_INTERFACE_H
#include "NetworkStack.h" #include "NetworkInterface.h"
/** MeshInterface class /** MeshInterface class
* *
* Common interface that is shared between mesh hardware * Common interface that is shared between mesh hardware
*/ */
class MeshInterface class MeshInterface : public NetworkInterface
{ {
public: public:
/** Start the interface /** Start the interface

41
NetworkInterface.h Normal file
View File

@ -0,0 +1,41 @@
/* NetworkStack
* 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.
*/
#ifndef NETWORK_INTERFACE_H
#define NETWORK_INTERFACE_H
#include "mbed.h"
#include "SocketAddress.h"
class NetworkInterface {
public:
virtual ~NetworkInterface() {};
NetworkInterface() {}
/** Get the internally stored IP address
/return IP address of the interface or null if not yet connected
*/
virtual const char *get_ip_address() = 0;
protected:
friend class Socket;
friend class UDPSocket;
friend class TCPSocket;
friend class TCPServer;
friend class SocketAddress;
virtual NetworkStack * get_stack(void) = 0;
};
#endif

View File

@ -14,8 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
#ifndef NETWORK_INTERFACE_H #ifndef NETWORK_STACK_H
#define NETWORK_INTERFACE_H #define NETWORK_STACK_H
#include "mbed.h" #include "mbed.h"
#include "SocketAddress.h" #include "SocketAddress.h"

View File

@ -15,6 +15,7 @@
*/ */
#include "SocketAddress.h" #include "SocketAddress.h"
#include "NetworkInterface.h"
#include "NetworkStack.h" #include "NetworkStack.h"
#include <string.h> #include <string.h>
#include "mbed.h" #include "mbed.h"
@ -144,28 +145,12 @@ static void ipv6_to_address(char *addr, const uint8_t *bytes)
SocketAddress::SocketAddress(NetworkStack *iface, const char *host, uint16_t port) SocketAddress::SocketAddress(NetworkStack *iface, const char *host, uint16_t port)
{ {
memset(&_ip_address, 0, sizeof _ip_address); _SocketAddress(iface, host, port);
}
// Check for valid IP addresses SocketAddress::SocketAddress(NetworkInterface *iface, const char *host, uint16_t port)
if (host && ipv4_is_valid(host)) { {
_ip_version = NSAPI_IPv4; _SocketAddress(iface->get_stack(), host, port);
ipv4_from_address(_ip_bytes, host);
set_port(port);
} else if (host && ipv6_is_valid(host)) {
_ip_version = NSAPI_IPv6;
ipv6_from_address(_ip_bytes, host);
set_port(port);
} else {
// DNS lookup
int err = iface->gethostbyname(this, host);
if (!err) {
set_port(port);
} else {
_ip_version = NSAPI_IPv4;
memset(_ip_bytes, 0, NSAPI_IPv4_BYTES);
set_port(0);
}
}
} }
SocketAddress::SocketAddress(const char *addr, uint16_t port) SocketAddress::SocketAddress(const char *addr, uint16_t port)
@ -273,3 +258,29 @@ SocketAddress::operator bool() const
return false; return false;
} }
void SocketAddress::_SocketAddress(NetworkStack *iface, const char *host, uint16_t port)
{
memset(&_ip_address, 0, sizeof _ip_address);
// Check for valid IP addresses
if (host && ipv4_is_valid(host)) {
_ip_version = NSAPI_IPv4;
ipv4_from_address(_ip_bytes, host);
set_port(port);
} else if (host && ipv6_is_valid(host)) {
_ip_version = NSAPI_IPv6;
ipv6_from_address(_ip_bytes, host);
set_port(port);
} else {
// DNS lookup
int err = iface->gethostbyname(this, host);
if (!err) {
set_port(port);
} else {
_ip_version = NSAPI_IPv4;
memset(_ip_bytes, 0, NSAPI_IPv4_BYTES);
set_port(0);
}
}
}

View File

@ -65,6 +65,7 @@ enum nsapi_version_t {
// Predeclared classes // Predeclared classes
class NetworkStack; class NetworkStack;
class NetworkInterface;
/** SocketAddress class /** SocketAddress class
@ -86,6 +87,19 @@ public:
*/ */
SocketAddress(NetworkStack *iface, const char *host, uint16_t port = 0); SocketAddress(NetworkStack *iface, const char *host, uint16_t port = 0);
/** Create a SocketAddress from a hostname and port
*
* The hostname may be either a domain name or an IP address. If the
* hostname is an IP address, no network transactions will be performed.
*
* On failure, the IP address and port will be set to zero
*
* @param iface Network interface to use for DNS resolution
* @param host Hostname to resolve
* @param port Optional 16-bit port
*/
SocketAddress(NetworkInterface *iface, const char *host, uint16_t port = 0);
/** Create a SocketAddress from an IP address and port /** Create a SocketAddress from an IP address and port
* *
* @param host Null-terminated representation of the IP address * @param host Null-terminated representation of the IP address
@ -157,6 +171,7 @@ public:
operator bool() const; operator bool() const;
private: private:
void _SocketAddress(NetworkStack *iface, const char *host, uint16_t port);
char _ip_address[NSAPI_IP_SIZE]; char _ip_address[NSAPI_IP_SIZE];
uint8_t _ip_bytes[NSAPI_IP_BYTES]; uint8_t _ip_bytes[NSAPI_IP_BYTES];
nsapi_version_t _ip_version; nsapi_version_t _ip_version;

View File

@ -28,6 +28,12 @@ TCPServer::TCPServer(NetworkStack *iface)
open(iface); open(iface);
} }
TCPServer::TCPServer(NetworkInterface *iface)
: _pending(0), _accept_sem(0)
{
open(iface->get_stack());
}
TCPServer::~TCPServer() TCPServer::~TCPServer()
{ {
close(); close();
@ -38,6 +44,11 @@ int TCPServer::open(NetworkStack *iface)
return Socket::open(iface, NSAPI_TCP); return Socket::open(iface, NSAPI_TCP);
} }
int TCPServer::open(NetworkInterface *iface)
{
return TCPServer::open(iface->get_stack());
}
int TCPServer::listen(int backlog) int TCPServer::listen(int backlog)
{ {
_lock.lock(); _lock.lock();

View File

@ -19,6 +19,7 @@
#include "Socket.h" #include "Socket.h"
#include "TCPSocket.h" #include "TCPSocket.h"
#include "NetworkInterface.h"
#include "NetworkStack.h" #include "NetworkStack.h"
#include "Semaphore.h" #include "Semaphore.h"
@ -46,6 +47,15 @@ public:
*/ */
TCPServer(NetworkStack *iface); TCPServer(NetworkStack *iface);
/** Create a socket on a network interface
*
* Creates and opens a socket on the network stack of the given
* network interface.
*
* @param iface Network interface as target for socket
*/
TCPServer(NetworkInterface *iface);
/** Opens a socket /** Opens a socket
* *
* Creates a network socket on the specified network stack. * Creates a network socket on the specified network stack.
@ -56,6 +66,17 @@ public:
*/ */
virtual int open(NetworkStack *iface); virtual int open(NetworkStack *iface);
/** Opens a socket
*
* Creates a network socket on the network stack of the given
* network interface. Not needed if stack is passed to the
* socket's constructor.
*
* @param iface Network interface as target for socket
* @return 0 on success, negative error code on failure
*/
virtual int open(NetworkInterface *iface);
/** Listen for connections on a TCP socket /** Listen for connections on a TCP socket
* *
* Marks the socket as a passive socket that can be used to accept * Marks the socket as a passive socket that can be used to accept

View File

@ -29,6 +29,13 @@ TCPSocket::TCPSocket(NetworkStack *iface)
open(iface); open(iface);
} }
TCPSocket::TCPSocket(NetworkInterface *iface)
: _pending(0), _read_sem(0), _write_sem(0)
{
// TCPSocket::open is thread safe
open(iface->get_stack());
}
TCPSocket::~TCPSocket() TCPSocket::~TCPSocket()
{ {
close(); close();
@ -40,6 +47,12 @@ int TCPSocket::open(NetworkStack *iface)
return Socket::open(iface, NSAPI_TCP); return Socket::open(iface, NSAPI_TCP);
} }
int TCPSocket::open(NetworkInterface *iface)
{
// Socket::open is thread safe
return TCPSocket::open(iface->get_stack());
}
int TCPSocket::connect(const SocketAddress &addr) int TCPSocket::connect(const SocketAddress &addr)
{ {
_lock.lock(); _lock.lock();

View File

@ -18,6 +18,7 @@
#define TCPSOCKET_H #define TCPSOCKET_H
#include "Socket.h" #include "Socket.h"
#include "NetworkInterface.h"
#include "NetworkStack.h" #include "NetworkStack.h"
#include "Semaphore.h" #include "Semaphore.h"
@ -45,6 +46,15 @@ public:
*/ */
TCPSocket(NetworkStack *iface); TCPSocket(NetworkStack *iface);
/** Create a socket on a network interface
*
* Creates and opens a socket on the network stack of the given
* network interface.
*
* @param iface Network interface as target for socket
*/
TCPSocket(NetworkInterface *iface);
/** Opens a socket /** Opens a socket
* *
* Creates a network socket on the specified network stack. * Creates a network socket on the specified network stack.
@ -55,6 +65,17 @@ public:
*/ */
virtual int open(NetworkStack *iface); virtual int open(NetworkStack *iface);
/** Opens a socket
*
* Creates a network socket on the network stack of the given
* network interface. Not needed if stack is passed to the
* socket's constructor.
*
* @param iface Network interface as target for socket
* @return 0 on success, negative error code on failure
*/
virtual int open(NetworkInterface *iface);
/** Connects TCP socket to a remote host /** Connects TCP socket to a remote host
* *
* Initiates a connection to a remote server specified by either * Initiates a connection to a remote server specified by either

View File

@ -28,6 +28,12 @@ UDPSocket::UDPSocket(NetworkStack *iface)
open(iface); open(iface);
} }
UDPSocket::UDPSocket(NetworkInterface *iface)
: _pending(0), _read_sem(0), _write_sem(0)
{
open(iface->get_stack());
}
UDPSocket::~UDPSocket() UDPSocket::~UDPSocket()
{ {
close(); close();
@ -38,6 +44,11 @@ int UDPSocket::open(NetworkStack *iface)
return Socket::open(iface, NSAPI_UDP); return Socket::open(iface, NSAPI_UDP);
} }
int UDPSocket::open(NetworkInterface *iface)
{
return UDPSocket::open(iface->get_stack());
}
int UDPSocket::sendto(const char *host, uint16_t port, const void *data, unsigned size) int UDPSocket::sendto(const char *host, uint16_t port, const void *data, unsigned size)
{ {
SocketAddress addr(_iface, host, port); SocketAddress addr(_iface, host, port);

View File

@ -18,6 +18,7 @@
#define UDPSOCKET_H #define UDPSOCKET_H
#include "Socket.h" #include "Socket.h"
#include "NetworkInterface.h"
#include "NetworkStack.h" #include "NetworkStack.h"
#include "Semaphore.h" #include "Semaphore.h"
@ -45,6 +46,15 @@ public:
*/ */
UDPSocket(NetworkStack *iface); UDPSocket(NetworkStack *iface);
/** Create a socket on a network interface
*
* Creates and opens a socket on the network stack of the given
* network interface.
*
* @param iface Network interface as target for socket
*/
UDPSocket(NetworkInterface *iface);
/** Opens a socket /** Opens a socket
* *
* Creates a network socket on the specified network stack. * Creates a network socket on the specified network stack.
@ -55,6 +65,17 @@ public:
*/ */
virtual int open(NetworkStack *iface); virtual int open(NetworkStack *iface);
/** Opens a socket
*
* Creates a network socket on the network stack of the given
* network interface. Not needed if stack is passed to the
* socket's constructor.
*
* @param iface Network interface as target for socket
* @return 0 on success, negative error code on failure
*/
virtual int open(NetworkInterface *iface);
/** Send a packet over a UDP socket /** Send a packet over a UDP socket
* *
* Sends data to the specified address specified by either a domain name * Sends data to the specified address specified by either a domain name

View File

@ -17,7 +17,7 @@
#ifndef WIFI_INTERFACE_H #ifndef WIFI_INTERFACE_H
#define WIFI_INTERFACE_H #define WIFI_INTERFACE_H
#include "NetworkStack.h" #include "NetworkInterface.h"
/** Enum of WiFi encryption types /** Enum of WiFi encryption types
* *
@ -37,7 +37,7 @@ enum nsapi_security_t {
* *
* Common interface that is shared between WiFi devices * Common interface that is shared between WiFi devices
*/ */
class WiFiInterface class WiFiInterface: public NetworkInterface
{ {
public: public:
/** Start the interface /** Start the interface