Skip to content

Commit e095654

Browse files
committed
Fixed ambiguity/protected access issue in Socket::open
NetworkStack/NetworkInterface overloads - Multiple inheritance results in ambiguity NetworkStack with templated get_stack overload - get_stack hidden behind protected access prevents template match - explicit call to NetworkInterface::get_stack does not follow vtable Solution is to use two overloaded function for NetworkStack/NetworkInterface, and an overload for a templated type that supports a static_cast to NetworkStack. This resolves the ambiguity without being blocked by protected access. Moved duplicated overloads out to overload of common nsapi_create_stack function.
1 parent 8561209 commit e095654

13 files changed

+49
-103
lines changed

NetworkInterface.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
#ifndef NETWORK_INTERFACE_H
1818
#define NETWORK_INTERFACE_H
1919

20-
#include "NetworkSocketAPI/NetworkStack.h"
20+
// Predeclared class
21+
class NetworkStack;
2122

2223

2324
/** NetworkInterface class
@@ -41,6 +42,8 @@ class NetworkInterface {
4142
friend class TCPSocket;
4243
friend class TCPServer;
4344
friend class SocketAddress;
45+
template <typename IF>
46+
friend NetworkStack *nsapi_create_stack(IF *iface);
4447

4548
/** Provide access to the NetworkStack object
4649
*

NetworkStack.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,3 +249,9 @@ NetworkStack *nsapi_create_stack(nsapi_stack_t *stack)
249249
MBED_ASSERT(sizeof stack->_stack_buffer >= sizeof(NetworkStackWrapper));
250250
return new (stack->_stack_buffer) NetworkStackWrapper;
251251
}
252+
253+
NetworkStack *nsapi_create_stack(NetworkStack *stack)
254+
{
255+
return stack;
256+
}
257+

NetworkStack.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "nsapi_types.h"
2121
#include "NetworkSocketAPI/SocketAddress.h"
22+
#include "NetworkSocketAPI/NetworkInterface.h"
2223

2324

2425
/** NetworkStack class
@@ -280,10 +281,20 @@ class NetworkStack
280281

281282
/** Convert a raw nsapi_stack_t object into a C++ NetworkStack object
282283
*
283-
* @param stack Reference to a raw nsapi_stack_t object
284+
* @param stack Reference to an object that can be converted to a stack
285+
* - A raw nsapi_stack_t object
286+
* - A reference to a network stack
287+
* - A reference to a network interface
284288
* @return Reference to the underlying network stack
285289
*/
286290
NetworkStack *nsapi_create_stack(nsapi_stack_t *stack);
291+
NetworkStack *nsapi_create_stack(NetworkStack *stack);
292+
293+
template <typename IF>
294+
NetworkStack *nsapi_create_stack(IF *iface)
295+
{
296+
return nsapi_create_stack(static_cast<NetworkInterface *>(iface)->get_stack());
297+
}
287298

288299

289300
#endif

Socket.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Socket::Socket()
2323
{
2424
}
2525

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

@@ -34,7 +34,7 @@ int Socket::open(NetworkStack *stack, nsapi_protocol_t proto)
3434
_stack = stack;
3535

3636
nsapi_socket_t socket;
37-
int err = _stack->socket_open(&socket, proto);
37+
int err = _stack->socket_open(&socket, get_proto());
3838
if (err) {
3939
_lock.unlock();
4040
return err;

Socket.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,11 @@ class Socket {
4646
* @param stack Network stack as target for socket
4747
* @return 0 on success, negative error code on failure
4848
*/
49-
virtual int open(NetworkStack *stack) = 0;
49+
int open(NetworkStack *stack);
5050

51-
template <typename IF>
52-
int open(IF *iface) {
53-
return open(iface->get_stack());
51+
template <typename S>
52+
int open(S *stack) {
53+
return open(nsapi_create_stack(stack));
5454
}
5555

5656
/** Close the socket
@@ -180,7 +180,7 @@ class Socket {
180180

181181
protected:
182182
Socket();
183-
int open(NetworkStack *stack, nsapi_protocol_t proto);
183+
virtual nsapi_protocol_t get_proto() = 0;
184184
virtual void event() = 0;
185185

186186
NetworkStack *_stack;

SocketAddress.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,6 @@ static void ipv6_to_address(char *addr, const uint8_t *bytes)
143143
}
144144

145145

146-
SocketAddress::SocketAddress(NetworkStack *iface, const char *host, uint16_t port)
147-
{
148-
_SocketAddress(iface, host, port);
149-
}
150-
151146
SocketAddress::SocketAddress(nsapi_addr_t addr, uint16_t port)
152147
{
153148
_ip_address[0] = '\0';

SocketAddress.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,14 @@ class SocketAddress {
3838
*
3939
* On failure, the IP address and port will be set to zero
4040
*
41-
* @param iface Network interface to use for DNS resolution
41+
* @param stack Network stack to use for DNS resolution
4242
* @param host Hostname to resolve
4343
* @param port Optional 16-bit port
4444
*/
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)
45+
template <typename S>
46+
SocketAddress(S *stack, const char *host, uint16_t port = 0)
4947
{
50-
_SocketAddress(iface->get_stack(), host, port);
48+
_SocketAddress(nsapi_create_stack(stack), host, port);
5149
}
5250

5351
/** Create a SocketAddress from a raw IP address and port

TCPServer.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,14 @@ TCPServer::TCPServer()
2222
{
2323
}
2424

25-
TCPServer::TCPServer(NetworkStack *stack)
26-
: _pending(0), _accept_sem(0)
27-
{
28-
open(stack);
29-
}
30-
3125
TCPServer::~TCPServer()
3226
{
3327
close();
3428
}
3529

36-
int TCPServer::open(NetworkStack *stack)
30+
nsapi_protocol_t TCPServer::get_proto()
3731
{
38-
return Socket::open(stack, NSAPI_TCP);
32+
return NSAPI_TCP;
3933
}
4034

4135
int TCPServer::listen(int backlog)

TCPServer.h

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -56,22 +56,6 @@ class TCPServer : public Socket {
5656
*/
5757
virtual ~TCPServer();
5858

59-
/** Opens a socket
60-
*
61-
* Creates a network socket on the network stack of the given
62-
* network interface. Not needed if stack is passed to the
63-
* socket's constructor.
64-
*
65-
* @param stack Network stack as target for socket
66-
* @return 0 on success, negative error code on failure
67-
*/
68-
virtual int open(NetworkStack *stack);
69-
70-
template <typename IF>
71-
int open(IF *iface) {
72-
return open(iface->get_stack());
73-
}
74-
7559
/** Listen for connections on a TCP socket
7660
*
7761
* Marks the socket as a passive socket that can be used to accept
@@ -97,7 +81,9 @@ class TCPServer : public Socket {
9781
* @return 0 on success, negative error code on failure
9882
*/
9983
int accept(TCPSocket *connection);
84+
10085
protected:
86+
virtual nsapi_protocol_t get_proto();
10187
virtual void event();
10288

10389
volatile unsigned _pending;

TCPSocket.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,14 @@ TCPSocket::TCPSocket()
2424
{
2525
}
2626

27-
TCPSocket::TCPSocket(NetworkStack *stack)
28-
: _pending(0)
29-
{
30-
open(stack);
31-
}
32-
3327
TCPSocket::~TCPSocket()
3428
{
3529
close();
3630
}
3731

38-
int TCPSocket::open(NetworkStack *stack)
32+
nsapi_protocol_t TCPSocket::get_proto()
3933
{
40-
return Socket::open(stack, NSAPI_TCP);
34+
return NSAPI_TCP;
4135
}
4236

4337
int TCPSocket::connect(const SocketAddress &address)

TCPSocket.h

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,12 @@ class TCPSocket : public Socket {
4040
*
4141
* @param stack Network stack as target for socket
4242
*/
43-
TCPSocket(NetworkStack *stack);
44-
45-
template <typename IF>
46-
TCPSocket(IF *iface)
43+
template <typename S>
44+
TCPSocket(S *stack)
4745
: _pending(0), _read_sem(0), _write_sem(0),
4846
_read_in_progress(false), _write_in_progress(false)
4947
{
50-
open(iface->get_stack());
48+
open(stack);
5149
}
5250

5351
/** Destroy a socket
@@ -56,22 +54,6 @@ class TCPSocket : public Socket {
5654
*/
5755
virtual ~TCPSocket();
5856

59-
/** Opens a socket
60-
*
61-
* Creates a network socket on the network stack of the given
62-
* network interface. Not needed if stack is passed to the
63-
* socket's constructor.
64-
*
65-
* @param stack Network stack as target for socket
66-
* @return 0 on success, negative error code on failure
67-
*/
68-
virtual int open(NetworkStack *stack);
69-
70-
template <typename IF>
71-
int open(IF *iface) {
72-
return open(iface->get_stack());
73-
}
74-
7557
/** Connects TCP socket to a remote host
7658
*
7759
* Initiates a connection to a remote server specified by either
@@ -128,6 +110,7 @@ class TCPSocket : public Socket {
128110
protected:
129111
friend class TCPServer;
130112

113+
virtual nsapi_protocol_t get_proto();
131114
virtual void event();
132115

133116
volatile unsigned _pending;

UDPSocket.cpp

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,14 @@ UDPSocket::UDPSocket()
2424
{
2525
}
2626

27-
UDPSocket::UDPSocket(NetworkStack *stack)
28-
: _pending(0), _read_sem(0), _write_sem(0),
29-
_read_in_progress(false), _write_in_progress(false)
30-
{
31-
open(stack);
32-
}
33-
3427
UDPSocket::~UDPSocket()
3528
{
3629
close();
3730
}
3831

39-
int UDPSocket::open(NetworkStack *stack)
32+
nsapi_protocol_t UDPSocket::get_proto()
4033
{
41-
return Socket::open(stack, NSAPI_UDP);
34+
return NSAPI_UDP;
4235
}
4336

4437
int UDPSocket::sendto(const char *host, uint16_t port, const void *data, unsigned size)

UDPSocket.h

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,12 @@ class UDPSocket : public Socket {
4040
*
4141
* @param stack Network stack as target for socket
4242
*/
43-
UDPSocket(NetworkStack *stack);
44-
45-
template <typename IF>
46-
UDPSocket(IF *iface)
43+
template <typename S>
44+
UDPSocket(S *stack)
4745
: _pending(0), _read_sem(0), _write_sem(0),
4846
_read_in_progress(false), _write_in_progress(false)
4947
{
50-
open(iface->get_stack());
48+
open(stack);
5149
}
5250

5351
/** Destroy a socket
@@ -56,22 +54,6 @@ class UDPSocket : public Socket {
5654
*/
5755
virtual ~UDPSocket();
5856

59-
/** Opens a socket
60-
*
61-
* Creates a network socket on the network stack of the given
62-
* network interface. Not needed if stack is passed to the
63-
* socket's constructor.
64-
*
65-
* @param stack Network stack as target for socket
66-
* @return 0 on success, negative error code on failure
67-
*/
68-
virtual int open(NetworkStack *stack);
69-
70-
template <typename IF>
71-
int open(IF *iface) {
72-
return open(iface->get_stack());
73-
}
74-
7557
/** Send a packet over a UDP socket
7658
*
7759
* Sends data to the specified address specified by either a domain name
@@ -126,6 +108,7 @@ class UDPSocket : public Socket {
126108
int recvfrom(SocketAddress *address, void *data, unsigned size);
127109

128110
protected:
111+
virtual nsapi_protocol_t get_proto();
129112
virtual void event();
130113

131114
volatile unsigned _pending;

0 commit comments

Comments
 (0)