Skip to content

Commit 94ade54

Browse files
committed
SocketWrapper - copyable networking clients
1 parent 7b95100 commit 94ade54

File tree

9 files changed

+240
-43
lines changed

9 files changed

+240
-43
lines changed

libraries/Ethernet/src/EthernetClient.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@
2121
#define ethernetclient_h
2222

2323
#include "Ethernet.h"
24-
#include "MbedClient.h"
24+
#include "AClient.h"
2525

2626
namespace arduino {
2727

28-
class EthernetClient : public MbedClient {
28+
class EthernetClient : public AClient {
2929
NetworkInterface *getNetwork() {
3030
return Ethernet.getNetwork();
3131
}

libraries/Ethernet/src/EthernetSSLClient.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@
2121
#define ETHERNETSSLCLIENT_H
2222

2323
#include "EthernetClient.h"
24-
#include "MbedSSLClient.h"
24+
#include "AClient.h"
2525

2626
extern const char CA_CERTIFICATES[];
2727

2828
namespace arduino {
2929

30-
class EthernetSSLClient : public arduino::MbedSSLClient {
30+
class EthernetSSLClient : public arduino::ASslClient {
3131
NetworkInterface *getNetwork() {
3232
return Ethernet.getNetwork();
3333
}

libraries/GSM/src/GSMClient.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@
2121
#define gsmclient_h
2222

2323
#include "GSM.h"
24-
#include "MbedClient.h"
24+
#include "AClient.h"
2525

2626
namespace arduino {
2727

28-
class GSMClient : public MbedClient {
28+
class GSMClient : public AClient {
2929
public:
3030
GSMClient();
3131

+139
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
2+
#include "AClient.h"
3+
#include "MbedSSLClient.h"
4+
5+
void arduino::AClient::newMbedClient() {
6+
client.reset(new MbedClient());
7+
client->setNetwork(getNetwork());
8+
}
9+
10+
arduino::AClient::operator bool() {
11+
return client && *client;
12+
}
13+
14+
void arduino::AClient::setSocket(Socket *sock) {
15+
if (!client) {
16+
newMbedClient();
17+
}
18+
client->setSocket(sock);
19+
}
20+
21+
void arduino::AClient::setSocketTimeout(unsigned long timeout) {
22+
if (!client) {
23+
newMbedClient();
24+
}
25+
client->setTimeout(timeout);
26+
}
27+
28+
int arduino::AClient::connect(IPAddress ip, uint16_t port) {
29+
if (!client) {
30+
newMbedClient();
31+
}
32+
return client->connect(ip, port);
33+
}
34+
35+
int arduino::AClient::connect(const char *host, uint16_t port) {
36+
if (!client) {
37+
newMbedClient();
38+
}
39+
return client->connect(host, port);
40+
}
41+
42+
int arduino::AClient::connectSSL(IPAddress ip, uint16_t port) {
43+
if (!client) {
44+
newMbedClient();
45+
}
46+
return client->connectSSL(ip, port);
47+
}
48+
49+
int arduino::AClient::connectSSL(const char *host, uint16_t port, bool disableSNI) {
50+
if (!client) {
51+
newMbedClient();
52+
}
53+
return client->connectSSL(host, port, disableSNI);
54+
}
55+
56+
void arduino::AClient::stop() {
57+
if (!client)
58+
return;
59+
client->stop();
60+
}
61+
62+
uint8_t arduino::AClient::connected() {
63+
if (!client)
64+
return false;
65+
return client->connected();
66+
}
67+
68+
IPAddress arduino::AClient::remoteIP() {
69+
if (!client)
70+
return INADDR_NONE;
71+
return client->remoteIP();
72+
}
73+
74+
uint16_t arduino::AClient::remotePort() {
75+
if (!client)
76+
return 0;
77+
return client->remotePort();
78+
}
79+
80+
size_t arduino::AClient::write(uint8_t b) {
81+
if (!client)
82+
return 0;
83+
return client->write(b);
84+
}
85+
86+
size_t arduino::AClient::write(const uint8_t *buf, size_t size) {
87+
if (!client)
88+
return 0;
89+
return client->write(buf, size);
90+
}
91+
92+
void arduino::AClient::flush() {
93+
if (!client)
94+
return;
95+
client->flush();
96+
}
97+
98+
int arduino::AClient::available() {
99+
if (!client)
100+
return 0;
101+
return client->available();
102+
}
103+
104+
int arduino::AClient::read() {
105+
if (!client)
106+
return -1;
107+
return client->read();
108+
}
109+
110+
int arduino::AClient::read(uint8_t *buf, size_t size) {
111+
if (!client)
112+
return 0;
113+
return client->read(buf, size);
114+
}
115+
116+
int arduino::AClient::peek() {
117+
if (!client)
118+
return -1;
119+
return client->peek();
120+
}
121+
122+
void arduino::ASslClient::newMbedClient() {
123+
client.reset(new MbedSSLClient());
124+
client->setNetwork(getNetwork());
125+
}
126+
127+
void arduino::ASslClient::disableSNI(bool statusSNI) {
128+
if (!client) {
129+
newMbedClient();
130+
}
131+
static_cast<MbedSSLClient*>(client.get())->disableSNI(statusSNI);
132+
}
133+
134+
void arduino::ASslClient::appendCustomCACert(const char* ca_cert) {
135+
if (!client) {
136+
newMbedClient();
137+
}
138+
static_cast<MbedSSLClient*>(client.get())->appendCustomCACert(ca_cert);
139+
}

libraries/SocketWrapper/src/AClient.h

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
AClient.h - Copyable Client implementation for Mbed Core
3+
4+
This library is free software; you can redistribute it and/or
5+
modify it under the terms of the GNU Lesser General Public
6+
License as published by the Free Software Foundation; either
7+
version 2.1 of the License, or (at your option) any later version.
8+
9+
This library is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
Lesser General Public License for more details.
13+
14+
You should have received a copy of the GNU Lesser General Public
15+
License along with this library; if not, write to the Free Software
16+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
*/
18+
19+
#ifndef MBEDACLIENT_H
20+
#define MBEDACLIENT_H
21+
22+
#include <Arduino.h>
23+
#include "MbedClient.h"
24+
25+
namespace arduino {
26+
27+
class AClient : public Client {
28+
public:
29+
30+
virtual int connect(IPAddress ip, uint16_t port);
31+
virtual int connect(const char *host, uint16_t port);
32+
int connectSSL(IPAddress ip, uint16_t port);
33+
int connectSSL(const char* host, uint16_t port, bool disableSNI = false);
34+
virtual void stop();
35+
36+
virtual explicit operator bool();
37+
virtual uint8_t connected();
38+
uint8_t status();
39+
40+
IPAddress remoteIP();
41+
uint16_t remotePort();
42+
43+
virtual size_t write(uint8_t);
44+
virtual size_t write(const uint8_t *buf, size_t size);
45+
virtual void flush();
46+
47+
virtual int available();
48+
virtual int read();
49+
virtual int read(uint8_t *buf, size_t size);
50+
virtual int peek();
51+
52+
void setSocketTimeout(unsigned long timeout);
53+
54+
protected:
55+
friend class EthernetServer;
56+
friend class WiFiServer;
57+
58+
std::shared_ptr<MbedClient> client;
59+
virtual NetworkInterface* getNetwork() = 0;
60+
virtual void newMbedClient();
61+
void setSocket(Socket* sock);
62+
63+
};
64+
65+
class ASslClient : public AClient {
66+
public:
67+
68+
void disableSNI(bool statusSNI);
69+
70+
void appendCustomCACert(const char* ca_cert);
71+
72+
protected:
73+
virtual void newMbedClient();
74+
};
75+
76+
}
77+
#endif

libraries/SocketWrapper/src/MbedClient.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ void arduino::MbedClient::readSocket() {
2424
continue;
2525
}
2626
mutex->lock();
27-
if (sock == nullptr || (closing && borrowed_socket)) {
27+
if (sock == nullptr) {
2828
goto cleanup;
2929
}
3030
ret = sock->recv(data, rxBuffer.availableForStore());
@@ -270,15 +270,14 @@ void arduino::MbedClient::stop() {
270270
if (mutex != nullptr) {
271271
mutex->lock();
272272
}
273-
if (sock != nullptr && borrowed_socket == false) {
273+
if (sock != nullptr) {
274274
if (_own_socket) {
275275
delete sock;
276276
} else {
277277
sock->close();
278278
}
279279
sock = nullptr;
280280
}
281-
closing = true;
282281
if (mutex != nullptr) {
283282
mutex->unlock();
284283
}

libraries/SocketWrapper/src/MbedClient.h

+12-30
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,7 @@
3535

3636
namespace arduino {
3737

38-
class MbedClient : public arduino::Client {
39-
private:
40-
// Helper for copy constructor and assignment operator
41-
void copyClient(const MbedClient& orig) {
42-
auto _sock = orig.sock;
43-
auto _m = (MbedClient*)&orig;
44-
_m->borrowed_socket = true;
45-
_m->stop();
46-
this->setSocket(_sock);
47-
}
38+
class MbedClient {
4839

4940
public:
5041
MbedClient();
@@ -53,31 +44,21 @@ class MbedClient : public arduino::Client {
5344
_timeout = timeout;
5445
}
5546

56-
// Copy constructor, to be used when a Client returned by server.available()
57-
// needs to "survive" event if it goes out of scope
58-
// Sample usage: Client* new_client = new Client(existing_client)
59-
MbedClient(const MbedClient& orig) {
60-
copyClient(orig);
61-
}
62-
63-
MbedClient& operator=(const MbedClient& orig) {
64-
copyClient(orig);
65-
return *this;
66-
}
67-
6847
virtual ~MbedClient() {
6948
stop();
7049
}
7150

51+
void setNetwork(NetworkInterface* network) {_network = network;}
52+
7253
uint8_t status();
7354
int connect(SocketAddress socketAddress);
74-
int connect(IPAddress ip, uint16_t port);
75-
int connect(const char* host, uint16_t port);
55+
virtual int connect(IPAddress ip, uint16_t port);
56+
virtual int connect(const char* host, uint16_t port);
7657
int connectSSL(SocketAddress socketAddress);
7758
int connectSSL(IPAddress ip, uint16_t port);
7859
int connectSSL(const char* host, uint16_t port, bool disableSNI = false);
7960
size_t write(uint8_t);
80-
size_t write(const uint8_t* buf, size_t size) override;
61+
size_t write(const uint8_t* buf, size_t size);
8162
int available();
8263
int read();
8364
int read(uint8_t* buf, size_t size);
@@ -103,22 +84,23 @@ class MbedClient : public arduino::Client {
10384
friend class MbedSSLClient;
10485
friend class MbedSocketClass;
10586

106-
using Print::write;
107-
10887
protected:
109-
virtual NetworkInterface* getNetwork() = 0;
88+
NetworkInterface* getNetwork() {return _network;}
89+
90+
NetworkInterface* _network = nullptr;
11091
Socket* sock = nullptr;
11192

11293
void onBeforeConnect(mbed::Callback<int(void)> cb) {
11394
beforeConnect = cb;
11495
}
11596

11697
private:
98+
99+
MbedClient(const MbedClient&) : _timeout(0) {}
100+
117101
RingBufferN<SOCKET_BUFFER_SIZE> rxBuffer;
118102
bool _status = false;
119-
bool borrowed_socket = false;
120103
bool _own_socket = false;
121-
bool closing = false;
122104
mbed::Callback<int(void)> beforeConnect;
123105
SocketAddress address;
124106
rtos::Thread* reader_th = nullptr;

libraries/WiFi/src/WiFiClient.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@
2121
#define wificlient_h
2222

2323
#include "WiFi.h"
24-
#include "MbedClient.h"
24+
#include "AClient.h"
2525

2626
namespace arduino {
2727

28-
class WiFiClient : public MbedClient {
28+
class WiFiClient : public AClient {
2929
NetworkInterface *getNetwork() {
3030
return WiFi.getNetwork();
3131
}

0 commit comments

Comments
 (0)