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
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -14,16 +14,16 @@
* limitations under the License.
*/
#ifndef ETHERNET_INTERFACE_H
#define ETHERNET_INTERFACE_H
#ifndef ETH_INTERFACE_H
#define ETH_INTERFACE_H
#include "NetworkStack.h"
#include "NetworkInterface.h"
/** EthernetInterface class
/** EthInterface class
*
* Common interface that is shared between ethernet hardware.
*/
class EthernetInterface
class EthInterface : public NetworkInterface
{
public:
/** Start the interface

View File

@ -17,13 +17,13 @@
#ifndef MESH_INTERFACE_H
#define MESH_INTERFACE_H
#include "NetworkStack.h"
#include "NetworkInterface.h"
/** MeshInterface class
*
* Common interface that is shared between mesh hardware
*/
class MeshInterface
class MeshInterface : public NetworkInterface
{
public:
/** 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.
*/
#ifndef NETWORK_INTERFACE_H
#define NETWORK_INTERFACE_H
#ifndef NETWORK_STACK_H
#define NETWORK_STACK_H
#include "mbed.h"
#include "SocketAddress.h"

View File

@ -15,6 +15,7 @@
*/
#include "SocketAddress.h"
#include "NetworkInterface.h"
#include "NetworkStack.h"
#include <string.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)
{
memset(&_ip_address, 0, sizeof _ip_address);
_SocketAddress(iface, host, port);
}
// 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);
}
}
SocketAddress::SocketAddress(NetworkInterface *iface, const char *host, uint16_t port)
{
_SocketAddress(iface->get_stack(), host, port);
}
SocketAddress::SocketAddress(const char *addr, uint16_t port)
@ -273,3 +258,29 @@ SocketAddress::operator bool() const
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
class NetworkStack;
class NetworkInterface;
/** SocketAddress class
@ -86,6 +87,19 @@ public:
*/
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
*
* @param host Null-terminated representation of the IP address
@ -157,6 +171,7 @@ public:
operator bool() const;
private:
void _SocketAddress(NetworkStack *iface, const char *host, uint16_t port);
char _ip_address[NSAPI_IP_SIZE];
uint8_t _ip_bytes[NSAPI_IP_BYTES];
nsapi_version_t _ip_version;

View File

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

View File

@ -19,6 +19,7 @@
#include "Socket.h"
#include "TCPSocket.h"
#include "NetworkInterface.h"
#include "NetworkStack.h"
#include "Semaphore.h"
@ -46,6 +47,15 @@ public:
*/
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
*
* Creates a network socket on the specified network stack.
@ -56,6 +66,17 @@ public:
*/
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
*
* 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);
}
TCPSocket::TCPSocket(NetworkInterface *iface)
: _pending(0), _read_sem(0), _write_sem(0)
{
// TCPSocket::open is thread safe
open(iface->get_stack());
}
TCPSocket::~TCPSocket()
{
close();
@ -40,6 +47,12 @@ int TCPSocket::open(NetworkStack *iface)
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)
{
_lock.lock();

View File

@ -18,6 +18,7 @@
#define TCPSOCKET_H
#include "Socket.h"
#include "NetworkInterface.h"
#include "NetworkStack.h"
#include "Semaphore.h"
@ -45,6 +46,15 @@ public:
*/
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
*
* Creates a network socket on the specified network stack.
@ -55,6 +65,17 @@ public:
*/
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
*
* Initiates a connection to a remote server specified by either

View File

@ -28,6 +28,12 @@ UDPSocket::UDPSocket(NetworkStack *iface)
open(iface);
}
UDPSocket::UDPSocket(NetworkInterface *iface)
: _pending(0), _read_sem(0), _write_sem(0)
{
open(iface->get_stack());
}
UDPSocket::~UDPSocket()
{
close();
@ -38,6 +44,11 @@ int UDPSocket::open(NetworkStack *iface)
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)
{
SocketAddress addr(_iface, host, port);

View File

@ -18,6 +18,7 @@
#define UDPSOCKET_H
#include "Socket.h"
#include "NetworkInterface.h"
#include "NetworkStack.h"
#include "Semaphore.h"
@ -45,6 +46,15 @@ public:
*/
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
*
* Creates a network socket on the specified network stack.
@ -55,6 +65,17 @@ public:
*/
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
*
* Sends data to the specified address specified by either a domain name

View File

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