Skip to content

Commit 12a206a

Browse files
committed
Add managed gsm client
1 parent d692f2d commit 12a206a

File tree

4 files changed

+125
-5
lines changed

4 files changed

+125
-5
lines changed

src/ArduinoCellular.cpp

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

22

33
#include "ArduinoCellular.h"
4+
45
#if defined(ARDUINO_ARCH_MBED)
56
#include "Watchdog.h"
67
#endif
@@ -165,12 +166,19 @@ int ArduinoCellular::getSignalQuality(){
165166
return modem.getSignalQuality();
166167
}
167168

168-
TinyGsmClient ArduinoCellular::getNetworkClient(){
169-
return TinyGsmClient(modem, 0);
169+
ManagedTinyGsmClient ArduinoCellular::getNetworkClient(){
170+
return ManagedTinyGsmClient(modem);
170171
}
171172

172173
HttpClient ArduinoCellular::getHTTPClient(const char * server, const int port){
173-
TinyGsmClient client = getNetworkClient();
174+
ManagedTinyGsmClient client = getNetworkClient();
175+
if (!client.isValid()) {
176+
// Handle error: no available sockets
177+
// Option 1: Return an invalid HttpClient (if supported)
178+
// Option 2: Use a default/shared client (not recommended)
179+
// Option 3: Wait and retry (could add a delay/retry mechanism)
180+
// For now, we'll proceed but the connection will likely fail
181+
}
174182
return HttpClient(client, server, port);
175183
}
176184

@@ -181,7 +189,7 @@ HttpClient ArduinoCellular::getHTTPSClient(const char * server, const int port){
181189
}
182190

183191
BearSSLClient ArduinoCellular::getSecureNetworkClient(){
184-
TinyGsmClient client = getNetworkClient();
192+
ManagedTinyGsmClient client = getNetworkClient();
185193
return BearSSLClient(client);
186194
}
187195
#endif

src/ArduinoCellular.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

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

2021
#if defined __has_include
2122
#if !__has_include (<ArduinoIoTCloud.h>)
@@ -221,7 +222,7 @@ class ArduinoCellular {
221222
* @brief Gets the Network client. (OSI Layer 3)
222223
* @return The GSM client.
223224
*/
224-
TinyGsmClient getNetworkClient();
225+
ManagedTinyGsmClient getNetworkClient();
225226

226227
/**
227228
* @brief Gets the Transport Layer Security (TLS) client. (OSI Layer 4)

src/ManagedTinyGsmClient.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#include "ManagedTinyGsmClient.h"
2+
3+
// Static member definitions
4+
uint32_t ManagedTinyGsmClient::usedSockets = 0;
5+
bool ManagedTinyGsmClient::socketMutex = false;
6+
7+
void ManagedTinyGsmClient::lockSockets() {
8+
// Simple spinlock - not ideal but works for basic protection
9+
while (socketMutex) {
10+
delay(1); // Small delay to prevent busy waiting
11+
}
12+
socketMutex = true;
13+
}
14+
15+
void ManagedTinyGsmClient::unlockSockets() {
16+
socketMutex = false;
17+
}
18+
19+
int ManagedTinyGsmClient::allocateSocket() {
20+
lockSockets();
21+
22+
for (int i = 0; i < TINY_GSM_MUX_COUNT; i++) {
23+
uint32_t mask = 1UL << i;
24+
if (!(usedSockets & mask)) {
25+
usedSockets |= mask; // Set bit i
26+
unlockSockets();
27+
return i;
28+
}
29+
}
30+
31+
unlockSockets();
32+
return -1; // No available sockets
33+
}
34+
35+
void ManagedTinyGsmClient::releaseSocket(int socketId) {
36+
if (socketId >= 0 && socketId < TINY_GSM_MUX_COUNT) {
37+
lockSockets();
38+
uint32_t mask = 1UL << socketId;
39+
usedSockets &= ~mask; // Clear bit socketId
40+
unlockSockets();
41+
}
42+
}
43+
44+
ManagedTinyGsmClient::ManagedTinyGsmClient(TinyGsm& modem)
45+
: socketId(allocateSocket()), TinyGsmClient(modem, socketId) {
46+
// Note: If socketId is -1, the client is invalid
47+
}
48+
49+
ManagedTinyGsmClient::ManagedTinyGsmClient(const ManagedTinyGsmClient& other)
50+
: socketId(allocateSocket()), TinyGsmClient(other) {
51+
// Copy constructor allocates a new socket
52+
// Note: If socketId is -1, the client is invalid
53+
}
54+
55+
ManagedTinyGsmClient& ManagedTinyGsmClient::operator=(const ManagedTinyGsmClient& other) {
56+
if (this != &other) {
57+
TinyGsmClient::operator=(other);
58+
// Keep our own socket - don't change it
59+
}
60+
return *this;
61+
}
62+
63+
ManagedTinyGsmClient::ManagedTinyGsmClient(ManagedTinyGsmClient&& other)
64+
: socketId(other.socketId), TinyGsmClient(other) {
65+
other.socketId = -1; // Mark other as moved-from
66+
}
67+
68+
ManagedTinyGsmClient& ManagedTinyGsmClient::operator=(ManagedTinyGsmClient&& other) {
69+
if (this != &other) {
70+
// Release our current socket
71+
releaseSocket(socketId);
72+
73+
TinyGsmClient::operator=(other);
74+
socketId = other.socketId;
75+
other.socketId = -1; // Mark other as moved-from
76+
}
77+
return *this;
78+
}
79+
80+
ManagedTinyGsmClient::~ManagedTinyGsmClient() {
81+
releaseSocket(socketId);
82+
}

src/ManagedTinyGsmClient.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#ifndef MANAGED_TINY_GSM_CLIENT_H
2+
#define MANAGED_TINY_GSM_CLIENT_H
3+
4+
#include "ModemInterface.h"
5+
6+
class ManagedTinyGsmClient : public TinyGsmClient {
7+
private:
8+
int socketId;
9+
static uint32_t usedSockets; // Bit field to track sockets 0-(TINY_GSM_MUX_COUNT-1)
10+
static bool socketMutex; // Simple mutex flag
11+
12+
static int allocateSocket();
13+
static void releaseSocket(int socketId);
14+
static void lockSockets();
15+
static void unlockSockets();
16+
17+
public:
18+
ManagedTinyGsmClient(TinyGsm& modem);
19+
ManagedTinyGsmClient(const ManagedTinyGsmClient& other);
20+
ManagedTinyGsmClient& operator=(const ManagedTinyGsmClient& other);
21+
ManagedTinyGsmClient(ManagedTinyGsmClient&& other);
22+
ManagedTinyGsmClient& operator=(ManagedTinyGsmClient&& other);
23+
~ManagedTinyGsmClient();
24+
25+
int getSocketId() const { return socketId; }
26+
bool isValid() const { return socketId >= 0; }
27+
};
28+
29+
#endif // MANAGED_TINY_GSM_CLIENT_H

0 commit comments

Comments
 (0)