Skip to content

Commit 01f38cc

Browse files
committed
Added better support for NetworkInterface/NetworkStack
Mostly reduced code duplication for NetworkInterface/NetworkStack arguments. Moved to templated Socket constructors/open member functions. This allows multiple inheritance to be used for classes that provide both a NetworkInterface and NetworkStack, such as the esp8266.
1 parent 5b63cbb commit 01f38cc

File tree

10 files changed

+160
-209
lines changed

10 files changed

+160
-209
lines changed

Socket.cpp

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,35 +17,34 @@
1717
#include "Socket.h"
1818

1919
Socket::Socket()
20-
: _iface(0)
20+
: _stack(0)
2121
, _socket(0)
2222
, _timeout(osWaitForever)
2323
{
2424
}
2525

26-
int Socket::open(NetworkStack *iface, nsapi_protocol_t proto)
26+
int Socket::open(NetworkStack *stack, nsapi_protocol_t proto)
2727
{
2828
_lock.lock();
2929

30-
if (_iface != NULL) {
30+
if (_stack != NULL || stack == NULL) {
3131
_lock.unlock();
3232
return NSAPI_ERROR_PARAMETER;
3333
}
34-
_iface = iface;
34+
_stack = stack;
3535

36-
void *socket;
37-
int err = _iface->socket_open(&socket, proto);
36+
nsapi_socket_t socket;
37+
int err = _stack->socket_open(&socket, proto);
3838
if (err) {
3939
_lock.unlock();
4040
return err;
4141
}
4242

4343
_socket = socket;
4444
_event.attach(this, &Socket::event);
45-
_iface->socket_attach(_socket, Callback<void()>::thunk, &_event);
45+
_stack->socket_attach(_socket, Callback<void()>::thunk, &_event);
4646

4747
_lock.unlock();
48-
4948
return 0;
5049
}
5150

@@ -55,11 +54,10 @@ int Socket::close()
5554

5655
int ret = 0;
5756
if (_socket) {
58-
_iface->socket_attach(_socket, 0, 0);
59-
60-
void * socket = _socket;
57+
_stack->socket_attach(_socket, 0, 0);
58+
nsapi_socket_t socket = _socket;
6159
_socket = 0;
62-
ret = _iface->socket_close(socket);
60+
ret = _stack->socket_close(socket);
6361
}
6462

6563
// Wakeup anything in a blocking operation
@@ -87,10 +85,12 @@ int Socket::bind(const char *address, uint16_t port)
8785
int Socket::bind(const SocketAddress &address)
8886
{
8987
_lock.lock();
88+
int ret;
9089

91-
int ret = NSAPI_ERROR_NO_SOCKET;
92-
if (_socket) {
93-
ret = _iface->socket_bind(_socket, address);
90+
if (!_socket) {
91+
ret = NSAPI_ERROR_NO_SOCKET;
92+
} else {
93+
ret = _stack->socket_bind(_socket, address);
9494
}
9595

9696
_lock.unlock();
@@ -119,10 +119,12 @@ void Socket::set_timeout(int timeout)
119119
int Socket::setsockopt(int level, int optname, const void *optval, unsigned optlen)
120120
{
121121
_lock.lock();
122+
int ret;
122123

123-
int ret = NSAPI_ERROR_NO_SOCKET;
124-
if (_socket) {
125-
ret = _iface->setsockopt(_socket, level, optname, optval, optlen);
124+
if (!_socket) {
125+
ret = NSAPI_ERROR_NO_SOCKET;
126+
} else {
127+
ret = _stack->setsockopt(_socket, level, optname, optval, optlen);
126128
}
127129

128130
_lock.unlock();
@@ -132,10 +134,12 @@ int Socket::setsockopt(int level, int optname, const void *optval, unsigned optl
132134
int Socket::getsockopt(int level, int optname, void *optval, unsigned *optlen)
133135
{
134136
_lock.lock();
137+
int ret;
135138

136-
int ret = NSAPI_ERROR_NO_SOCKET;
137-
if (_socket) {
138-
ret = _iface->getsockopt(_socket, level, optname, optval, optlen);
139+
if (!_socket) {
140+
ret = NSAPI_ERROR_NO_SOCKET;
141+
} else {
142+
ret = _stack->getsockopt(_socket, level, optname, optval, optlen);
139143
}
140144

141145
_lock.unlock();

Socket.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,19 @@ class Socket {
3939

4040
/** Opens a socket
4141
*
42-
* Creates a network socket on the specified network stack.
43-
* Not needed if stack is passed to the socket's constructor.
42+
* Creates a network socket on the network stack of the given
43+
* network interface. Not needed if stack is passed to the
44+
* socket's constructor.
4445
*
45-
* @param iface Network stack as target for socket
46+
* @param stack Network stack as target for socket
4647
* @return 0 on success, negative error code on failure
4748
*/
48-
virtual int open(NetworkStack *iface) = 0;
49+
virtual int open(NetworkStack *stack) = 0;
50+
51+
template <typename IF>
52+
int open(IF *iface) {
53+
return open(iface->get_stack());
54+
}
4955

5056
/** Close the socket
5157
*
@@ -174,10 +180,10 @@ class Socket {
174180

175181
protected:
176182
Socket();
177-
int open(NetworkStack *iface, nsapi_protocol_t proto);
183+
int open(NetworkStack *stack, nsapi_protocol_t proto);
178184
virtual void event() = 0;
179185

180-
NetworkStack *_iface;
186+
NetworkStack *_stack;
181187
nsapi_socket_t _socket;
182188
uint32_t _timeout;
183189
mbed::Callback<void()> _event;

SocketAddress.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,6 @@ SocketAddress::SocketAddress(NetworkStack *iface, const char *host, uint16_t por
148148
_SocketAddress(iface, host, port);
149149
}
150150

151-
SocketAddress::SocketAddress(NetworkInterface *iface, const char *host, uint16_t port)
152-
{
153-
_SocketAddress(iface->get_stack(), host, port);
154-
}
155-
156151
SocketAddress::SocketAddress(nsapi_addr_t addr, uint16_t port)
157152
{
158153
_ip_address[0] = '\0';

SocketAddress.h

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,6 @@ class NetworkInterface;
3131
*/
3232
class SocketAddress {
3333
public:
34-
/** Create a SocketAddress from a hostname and port
35-
*
36-
* The hostname may be either a domain name or an IP address. If the
37-
* hostname is an IP address, no network transactions will be performed.
38-
*
39-
* On failure, the IP address and port will be set to zero
40-
*
41-
* @param iface Network stack to use for DNS resolution
42-
* @param host Hostname to resolve
43-
* @param port Optional 16-bit port
44-
*/
45-
SocketAddress(NetworkStack *iface, const char *host, uint16_t port = 0);
46-
4734
/** Create a SocketAddress from a hostname and port
4835
*
4936
* The hostname may be either a domain name or an IP address. If the
@@ -55,7 +42,13 @@ class SocketAddress {
5542
* @param host Hostname to resolve
5643
* @param port Optional 16-bit port
5744
*/
58-
SocketAddress(NetworkInterface *iface, const char *host, uint16_t port = 0);
45+
SocketAddress(NetworkStack *iface, const char *host, uint16_t port = 0);
46+
47+
template <typename IF>
48+
SocketAddress(IF *iface, const char *host, uint16_t port = 0)
49+
{
50+
_SocketAddress(iface->get_stack(), host, port);
51+
}
5952

6053
/** Create a SocketAddress from a raw IP address and port
6154
*

TCPServer.cpp

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,40 +22,31 @@ TCPServer::TCPServer()
2222
{
2323
}
2424

25-
TCPServer::TCPServer(NetworkStack *iface)
25+
TCPServer::TCPServer(NetworkStack *stack)
2626
: _pending(0), _accept_sem(0)
2727
{
28-
open(iface);
29-
}
30-
31-
TCPServer::TCPServer(NetworkInterface *iface)
32-
: _pending(0), _accept_sem(0)
33-
{
34-
open(iface->get_stack());
28+
open(stack);
3529
}
3630

3731
TCPServer::~TCPServer()
3832
{
3933
close();
4034
}
4135

42-
int TCPServer::open(NetworkStack *iface)
36+
int TCPServer::open(NetworkStack *stack)
4337
{
44-
return Socket::open(iface, NSAPI_TCP);
45-
}
46-
47-
int TCPServer::open(NetworkInterface *iface)
48-
{
49-
return TCPServer::open(iface->get_stack());
38+
return Socket::open(stack, NSAPI_TCP);
5039
}
5140

5241
int TCPServer::listen(int backlog)
5342
{
5443
_lock.lock();
44+
int ret;
5545

56-
int ret = NSAPI_ERROR_NO_SOCKET;
57-
if (_socket) {
58-
ret = _iface->socket_listen(_socket, backlog);
46+
if (!_socket) {
47+
ret = NSAPI_ERROR_NO_SOCKET;
48+
} else {
49+
ret = _stack->socket_listen(_socket, backlog);
5950
}
6051

6152
_lock.unlock();
@@ -65,28 +56,29 @@ int TCPServer::listen(int backlog)
6556
int TCPServer::accept(TCPSocket *connection)
6657
{
6758
_lock.lock();
59+
int ret;
6860

69-
int ret = NSAPI_ERROR_NO_SOCKET;
7061
while (true) {
7162
if (!_socket) {
7263
ret = NSAPI_ERROR_NO_SOCKET;
7364
break;
74-
}
65+
}
7566

7667
_pending = 0;
7768
void *socket;
78-
ret = _iface->socket_accept(&socket, _socket);
69+
ret = _stack->socket_accept(&socket, _socket);
70+
7971
if (0 == ret) {
8072
connection->_lock.lock();
8173

8274
if (connection->_socket) {
8375
connection->close();
8476
}
8577

86-
connection->_iface = _iface;
78+
connection->_stack = _stack;
8779
connection->_socket = socket;
8880
connection->_event = Callback<void()>(connection, &TCPSocket::event);
89-
_iface->socket_attach(socket, &Callback<void()>::thunk, &connection->_event);
81+
_stack->socket_attach(socket, &Callback<void()>::thunk, &connection->_event);
9082

9183
connection->_lock.unlock();
9284
break;

TCPServer.h

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -34,49 +34,43 @@ class TCPServer : public Socket {
3434
*/
3535
TCPServer();
3636

37-
/** Destroy a socket
38-
*
39-
* Closes socket if the socket is still open
40-
*/
41-
virtual ~TCPServer();
42-
43-
/** Create a socket on a network stack
44-
*
45-
* Creates and opens a socket on the specified network stack.
46-
*
47-
* @param iface Network stack as target for socket
48-
*/
49-
TCPServer(NetworkStack *iface);
50-
5137
/** Create a socket on a network interface
5238
*
5339
* Creates and opens a socket on the network stack of the given
5440
* network interface.
5541
*
56-
* @param iface Network interface as target for socket
42+
* @param stack Network stack as target for socket
5743
*/
58-
TCPServer(NetworkInterface *iface);
44+
TCPServer(NetworkStack *stack);
5945

60-
/** Opens a socket
61-
*
62-
* Creates a network socket on the specified network stack.
63-
* Not needed if stack is passed to the socket's constructor.
46+
template <typename IF>
47+
TCPServer(IF *iface)
48+
: _pending(0), _accept_sem(0)
49+
{
50+
open(iface->get_stack());
51+
}
52+
53+
/** Destroy a socket
6454
*
65-
* @param iface Network stack as target for socket
66-
* @return 0 on success, negative error code on failure
55+
* Closes socket if the socket is still open
6756
*/
68-
virtual int open(NetworkStack *iface);
69-
57+
virtual ~TCPServer();
58+
7059
/** Opens a socket
7160
*
7261
* Creates a network socket on the network stack of the given
7362
* network interface. Not needed if stack is passed to the
7463
* socket's constructor.
7564
*
76-
* @param iface Network interface as target for socket
65+
* @param stack Network stack as target for socket
7766
* @return 0 on success, negative error code on failure
7867
*/
79-
virtual int open(NetworkInterface *iface);
68+
virtual int open(NetworkStack *stack);
69+
70+
template <typename IF>
71+
int open(IF *iface) {
72+
return open(iface->get_stack());
73+
}
8074

8175
/** Listen for connections on a TCP socket
8276
*
@@ -105,6 +99,7 @@ class TCPServer : public Socket {
10599
int accept(TCPSocket *connection);
106100
protected:
107101
virtual void event();
102+
108103
volatile unsigned _pending;
109104
rtos::Semaphore _accept_sem;
110105
};

0 commit comments

Comments
 (0)