Skip to content

Commit 677b231

Browse files
committed
Add memory management for clients
1 parent 1a68dcf commit 677b231

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-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: 35 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,20 @@ 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+
// Delete copy operations (since unique_ptr can't be copied)
112+
ArduinoCellular(const ArduinoCellular&) = delete;
113+
ArduinoCellular& operator=(const ArduinoCellular&) = delete;
114+
115+
// Enable move operations
116+
ArduinoCellular(ArduinoCellular&&) = default;
117+
ArduinoCellular& operator=(ArduinoCellular&&) = default;
118+
103119
/**
104120
* @brief Initializes the modem.
105121
* This function must be called before using any other functions in the library.
@@ -238,6 +254,7 @@ class ArduinoCellular {
238254
/**
239255
* @brief Gets a HTTP client for the specified server and port.
240256
* The maximum number of HTTP clients is limited by the number of sockets available.
257+
* Call `cleanup()` to release the resources used by the clients once you are done with them.
241258
* @param server The server address.
242259
* @param port The server port.
243260
* @return The HTTP client.
@@ -247,12 +264,26 @@ class ArduinoCellular {
247264
/**
248265
* @brief Gets a HTTPS client for the specified server and port.
249266
* The maximum number of HTTP clients is limited by the number of sockets available.
267+
* Call `cleanup()` to release the resources used by the clients once you are done with them.
250268
* @param server The server address.
251269
* @param port The server port.
252270
* @return The HTTPS client.
253271
*/
254272
HttpClient getHTTPSClient(const char * server, const int port);
255273

274+
/**
275+
* @brief Cleans up the clients and releases the resources used by them.
276+
* It's necessary to call this function to free up the memory used by the client
277+
* objects that are created by the library internally.
278+
*/
279+
void cleanup();
280+
281+
/**
282+
* @brief Gets the number of managed clients.
283+
* The clients are managed in the sense of memory management.
284+
*/
285+
size_t getManagedClientCount() const;
286+
256287
/**
257288
* @brief Gets the local IP address.
258289
* @return The local IP address.
@@ -282,6 +313,10 @@ class ArduinoCellular {
282313
SimStatus getSimStatus();
283314

284315
private:
316+
// Each instance manages its own connections
317+
std::vector<std::unique_ptr<ManagedTinyGsmClient>> managedGsmClients;
318+
std::vector<std::unique_ptr<BearSSLClient>> managedSslClients;
319+
285320
bool connectToGPRS(const char * apn, const char * gprsUser, const char * gprsPass);
286321

287322

0 commit comments

Comments
 (0)