Skip to content

Commit 0ea3956

Browse files
committed
Add memory management for clients
1 parent 1a68dcf commit 0ea3956

File tree

2 files changed

+78
-2
lines changed

2 files changed

+78
-2
lines changed

src/ArduinoCellular.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11

22

33
#include "ArduinoCellular.h"
4-
#include "ManagedTinyGsmClient.h"
54

65
#if defined(ARDUINO_ARCH_MBED)
76
#include "Watchdog.h"
@@ -17,6 +16,10 @@ unsigned long ArduinoCellular::getTime() {
1716
ArduinoCellular::ArduinoCellular() {
1817
}
1918

19+
ArduinoCellular::~ArduinoCellular() {
20+
cleanup();
21+
}
22+
2023
void ArduinoCellular::begin() {
2124
modem.init();
2225

@@ -177,14 +180,34 @@ HttpClient ArduinoCellular::getHTTPClient(const char * server, const int port){
177180

178181
#if defined(ARDUINO_CELLULAR_BEARSSL)
179182
HttpClient ArduinoCellular::getHTTPSClient(const char * server, const int port){
180-
return HttpClient(* new BearSSLClient(* new ManagedTinyGsmClient(modem)), server, port);
183+
auto gsmClient = std::make_unique<ManagedTinyGsmClient>(modem);
184+
auto sslClient = std::make_unique<BearSSLClient>(*gsmClient);
185+
auto& sslRef = *sslClient;
186+
187+
managedGsmClients.push_back(std::move(gsmClient));
188+
managedSslClients.push_back(std::move(sslClient));
189+
return HttpClient(sslRef, server, port);
181190
}
182191

183192
BearSSLClient ArduinoCellular::getSecureNetworkClient(){
184193
return BearSSLClient(* new ManagedTinyGsmClient(modem));
185194
}
186195
#endif
187196

197+
void ArduinoCellular::cleanup() {
198+
/*
199+
It's necessary to to manage the lifetime of the clients created by the library
200+
because the HttpClient and also BearSSLClient classes expect callers to manage the lifetime of the clients.
201+
For convenience, the library provides factory functions that allocate these objects on behalf of the caller.
202+
*/
203+
managedSslClients.clear(); // Destroys BearSSLClient instances
204+
managedGsmClients.clear(); // Destroys ManagedTinyGsmClient instances
205+
}
206+
207+
size_t ArduinoCellular::getManagedClientCount() const {
208+
return managedSslClients.size();
209+
}
210+
188211
bool ArduinoCellular::isConnectedToOperator(){
189212
return modem.isNetworkConnected();
190213
}

src/ArduinoCellular.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include <Arduino.h>
1818
#include <vector>
19+
#include <memory>
1920

2021
#if defined __has_include
2122
#if !__has_include (<ArduinoIoTCloud.h>)
@@ -30,6 +31,7 @@
3031

3132
#include <ModemInterface.h>
3233
#include <TimeUtils.h>
34+
#include "ManagedTinyGsmClient.h"
3335

3436
/**
3537
* @enum ModemModel
@@ -100,6 +102,37 @@ class ArduinoCellular {
100102
*/
101103
ArduinoCellular();
102104

105+
/**
106+
* @brief Destructor for the ArduinoCellular class.
107+
* Cleans up any resources used by the class.
108+
*/
109+
~ArduinoCellular();
110+
111+
/**
112+
* @brief Deleted copy constructor and assignment operator to prevent copying.
113+
* unique_ptr is used to manage the lifetime of the clients but they cannot be copied.
114+
*/
115+
ArduinoCellular(const ArduinoCellular&) = delete;
116+
117+
/**
118+
* @brief Deleted assignment operator to prevent copying.
119+
* unique_ptr is used to manage the lifetime of the clients but they cannot be copied.
120+
*/
121+
ArduinoCellular& operator=(const ArduinoCellular&) = delete;
122+
123+
/**
124+
* @brief Move constructor for the ArduinoCellular class.
125+
* Allows moving the instance to another instance.
126+
*/
127+
ArduinoCellular(ArduinoCellular&&) = default;
128+
129+
/**
130+
* @brief Move assignment operator for the ArduinoCellular class.
131+
* Allows moving the instance to another instance.
132+
* @return A reference to the moved instance.
133+
*/
134+
ArduinoCellular& operator=(ArduinoCellular&&) = default;
135+
103136
/**
104137
* @brief Initializes the modem.
105138
* This function must be called before using any other functions in the library.
@@ -238,6 +271,7 @@ class ArduinoCellular {
238271
/**
239272
* @brief Gets a HTTP client for the specified server and port.
240273
* The maximum number of HTTP clients is limited by the number of sockets available.
274+
* Call `cleanup()` to release the resources used by the clients once you are done with them.
241275
* @param server The server address.
242276
* @param port The server port.
243277
* @return The HTTP client.
@@ -247,12 +281,27 @@ class ArduinoCellular {
247281
/**
248282
* @brief Gets a HTTPS client for the specified server and port.
249283
* The maximum number of HTTP clients is limited by the number of sockets available.
284+
* Call `cleanup()` to release the resources used by the clients once you are done with them.
250285
* @param server The server address.
251286
* @param port The server port.
252287
* @return The HTTPS client.
253288
*/
254289
HttpClient getHTTPSClient(const char * server, const int port);
255290

291+
/**
292+
* @brief Cleans up the clients and releases the resources used by them.
293+
* It's necessary to call this function to free up the memory used by the client
294+
* objects that are created by the library internally.
295+
*/
296+
void cleanup();
297+
298+
/**
299+
* @brief Gets the number of managed clients.
300+
* The clients are managed in the sense of memory management.
301+
* @return The number of managed clients.
302+
*/
303+
size_t getManagedClientCount() const;
304+
256305
/**
257306
* @brief Gets the local IP address.
258307
* @return The local IP address.
@@ -282,6 +331,10 @@ class ArduinoCellular {
282331
SimStatus getSimStatus();
283332

284333
private:
334+
// Each instance manages its own connections
335+
std::vector<std::unique_ptr<ManagedTinyGsmClient>> managedGsmClients;
336+
std::vector<std::unique_ptr<BearSSLClient>> managedSslClients;
337+
285338
bool connectToGPRS(const char * apn, const char * gprsUser, const char * gprsPass);
286339

287340

0 commit comments

Comments
 (0)