Add open call as alternative to passing NetworkInterface at construction

Pros
- Allows memory to be statically allocated
- Avoids issues with Thread creation before entering main
- Matches existing APIs such as FunctionPointer and Ticker

Cons
- Does not enforce passing a NetworkInterface
pull/2216/head^2
Christopher Haster 2016-03-13 07:08:27 -05:00
parent 4c7992cb24
commit d38ccb70a6
8 changed files with 87 additions and 29 deletions

View File

@ -16,12 +16,12 @@
#include "Socket.h"
Socket::Socket(NetworkInterface *iface, nsapi_protocol_t proto)
: _iface(iface)
Socket::Socket()
: _iface(0)
, _socket(0)
, _blocking(true)
, _timeout(0)
{
_socket = _iface->socket_create(proto);
}
Socket::~Socket()
@ -31,6 +31,28 @@ Socket::~Socket()
}
}
int Socket::open(NetworkInterface *iface, nsapi_protocol_t proto)
{
_iface = iface;
_socket = _iface->socket_create(proto);
}
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;
}
void Socket::set_blocking(bool blocking)
{
_blocking = blocking;
@ -59,22 +81,6 @@ int Socket::get_option(int optname, void *optval, unsigned int *optlen)
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;
}
void Socket::thunk(void *p)
{
FunctionPointer *fptr = (FunctionPointer *)p;

View File

@ -27,6 +27,11 @@ public:
/** Socket lifetime
*/
virtual ~Socket();
/** Open the socket
* @param iface Interface to open socket on
*/
virtual int open(NetworkInterface *iface) = 0;
/** Set blocking or non-blocking mode of the socket
* @param blocking true for blocking mode, false for non-blocking mode.
@ -60,7 +65,8 @@ public:
int close(bool shutdown=true);
protected:
Socket(NetworkInterface *iface, nsapi_protocol_t proto);
Socket();
int open(NetworkInterface *iface, nsapi_protocol_t proto);
static void thunk(void *);

View File

@ -17,11 +17,20 @@
#include "TCPServer.h"
#include "Timer.h"
TCPServer::TCPServer(NetworkInterface *iface)
: Socket(iface, NSAPI_TCP)
TCPServer::TCPServer()
{
}
TCPServer::TCPServer(NetworkInterface *iface)
{
open(iface);
}
int TCPServer::open(NetworkInterface *iface)
{
return Socket::open(iface, NSAPI_TCP);
}
int TCPServer::bind(uint16_t port)
{
if (!_socket) {
@ -45,15 +54,16 @@ int TCPServer::accept(TCPSocket *connection)
mbed::Timer timer;
timer.start();
void *socket = connection->_socket;
connection->_socket = 0;
_iface->socket_destroy(socket);
if (connection->_socket) {
connection->close();
}
while (true) {
if (!_socket) {
return NSAPI_ERROR_NO_SOCKET;
}
void *socket;
int err = _iface->socket_accept(_socket, &socket);
if (err > 0) {

View File

@ -27,8 +27,14 @@ class TCPServer : public Socket {
public:
/** TCP Server lifetime
*/
TCPServer();
TCPServer(NetworkInterface *iface);
virtual ~TCPServer();
/** Open the socket
* @param iface Interface to open socket on
*/
virtual int open(NetworkInterface *iface);
/** Bind a socket to a specific port
* @param port The port to listen for incoming connections on

View File

@ -17,11 +17,20 @@
#include "TCPSocket.h"
#include "Timer.h"
TCPSocket::TCPSocket(NetworkInterface *iface)
: Socket(iface, NSAPI_TCP)
TCPSocket::TCPSocket()
{
}
TCPSocket::TCPSocket(NetworkInterface *iface)
{
open(iface);
}
int TCPSocket::open(NetworkInterface *iface)
{
return Socket::open(iface, NSAPI_TCP);
}
int TCPSocket::connect(const SocketAddress &addr)
{
if (!_socket) {

View File

@ -26,8 +26,14 @@ class TCPSocket : public Socket {
public:
/** TCP socket lifetime
*/
TCPSocket();
TCPSocket(NetworkInterface *iface);
virtual ~TCPSocket();
/** Open the socket
* @param iface Interface to open socket on
*/
virtual int open(NetworkInterface *iface);
/** Connects this TCP socket to the server
* @param host The host to connect to. It can either be an IP Address

View File

@ -17,11 +17,20 @@
#include "UDPSocket.h"
#include "Timer.h"
UDPSocket::UDPSocket(NetworkInterface *iface)
: Socket(iface, NSAPI_UDP)
UDPSocket::UDPSocket()
{
}
UDPSocket::UDPSocket(NetworkInterface *iface)
{
open(iface);
}
int UDPSocket::open(NetworkInterface *iface)
{
return Socket::open(iface, NSAPI_UDP);
}
int UDPSocket::bind(uint16_t port)
{
if (!_socket) {

View File

@ -26,8 +26,14 @@ class UDPSocket : public Socket {
public:
/** UDPSocket lifetime
*/
UDPSocket();
UDPSocket(NetworkInterface *iface);
virtual ~UDPSocket();
/** Open the socket
* @param iface Interface to open socket on
*/
virtual int open(NetworkInterface *iface);
/** Bind a UDP Server Socket to a specific port
* @param port The port to listen for incoming connections on