Skip to content

Commit b935975

Browse files
Sid23facchinm
authored andcommitted
Handle reconnection inside library
1 parent 50181e7 commit b935975

File tree

2 files changed

+97
-10
lines changed

2 files changed

+97
-10
lines changed

Diff for: src/ArduinoCloud.cpp

+72-6
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ const static int thingIdSlot = 12;
1414

1515
ArduinoCloudClass::ArduinoCloudClass() :
1616
_bearSslClient(NULL),
17-
_mqttClient(256)
17+
// Size of the receive buffer
18+
_mqttClient(MQTT_BUFFER_SIZE)
1819
{
1920
}
2021

@@ -58,17 +59,31 @@ int ArduinoCloudClass::begin(Client& net)
5859
_bearSslClient = new BearSSLClient(net);
5960
_bearSslClient->setEccSlot(keySlot, ECCX08Cert.bytes(), ECCX08Cert.length());
6061

61-
_mqttClient.onMessageAdvanced(ArduinoCloudClass::onMessage);
62-
_mqttClient.begin(server, 8883, *_bearSslClient);
63-
64-
_stdoutTopic = "$aws/things/" + _id + "/stdout";
65-
_stdinTopic = "$aws/things/" + _id + "/stdin";
62+
// Begin function for the MQTTClient
63+
mqttClientBegin(*_bearSslClient);
6664

6765
return 1;
6866
}
6967

68+
// private class method used to initialize mqttClient class member. (called in the begin class method)
69+
void ArduinoCloudClass::mqttClientBegin(Client& net)
70+
{
71+
// MQTT topics definition
72+
_stdoutTopic = "/a/d/" + _id + "/s/o";
73+
_stdinTopic = "/a/d/" + _id + "/s/i";
74+
75+
// use onMessage as callback for received mqtt messages
76+
_mqttClient.onMessageAdvanced(ArduinoCloudClass::onMessage);
77+
_mqttClient.begin(server, 8883, net);
78+
79+
// Set MQTT connection options
80+
_mqttClient.setOptions(mqttOpt.keepAlive, mqttOpt.cleanSession, mqttOpt.timeout);
81+
}
82+
7083
int ArduinoCloudClass::connect()
7184
{
85+
// Username: device id
86+
// Password: empty
7287
if (!_mqttClient.connect(_id.c_str())) {
7388
return 0;
7489
}
@@ -78,11 +93,62 @@ int ArduinoCloudClass::connect()
7893
return 1;
7994
}
8095

96+
bool ArduinoCloudClass::disconnect()
97+
{
98+
return _mqttClient.disconnect();
99+
}
100+
81101
void ArduinoCloudClass::poll()
82102
{
103+
// If user call poll() without parameters use the default ones
104+
poll(MAX_RETRIES, RECONNECTION_TIMEOUT);
105+
}
106+
107+
bool ArduinoCloudClass::mqttReconnect(int maxRetries, int timeout)
108+
{
109+
// Counter for reconnection retries
110+
int retries = 0;
111+
unsigned long start = millis();
112+
113+
// Check for MQTT broker connection, of if maxReties limit is reached
114+
// if MQTTClient is connected , simply do nothing and retun true
115+
while(!_mqttClient.connected() && (retries++ < maxRetries) && (millis() - start < timeout)) {
116+
117+
// Get last MTTQClient error, (a common error may be a buffer overflow)
118+
lwmqtt_err_t err = _mqttClient.lastError();
119+
120+
// try establish the MQTT broker connection
121+
connect();
122+
}
123+
124+
// It was impossible to establish a connection, return
125+
if ((retries == maxRetries) || (millis() - start >= timeout))
126+
return false;
127+
128+
return true;
129+
}
130+
131+
void ArduinoCloudClass::poll(int reconnectionMaxRetries, int reconnectionTimeoutMs)
132+
{
133+
// Method's argument controls
134+
int maxRetries = (reconnectionMaxRetries > 0) ? reconnectionMaxRetries : MAX_RETRIES;
135+
int timeout = (reconnectionTimeoutMs > 0) ? reconnectionTimeoutMs : RECONNECTION_TIMEOUT;
136+
137+
// If the reconnect() culd not establish the connection, return the control to the user sketch
138+
if (!mqttReconnect(maxRetries, timeout))
139+
return;
140+
141+
// MTTQClient connected!, poll() used to retrieve data from MQTT broker
83142
_mqttClient.loop();
84143
}
85144

145+
void ArduinoCloudClass::reconnect(Client& net)
146+
{
147+
// Initialize again the MQTTClient, otherwise it would not be able to receive messages through its callback
148+
mqttClientBegin(net);
149+
connect();
150+
}
151+
86152
void ArduinoCloudClass::onGetTime(unsigned long(*callback)(void))
87153
{
88154
ArduinoBearSSL.onGetTime(callback);

Diff for: src/ArduinoCloudV2.h

+25-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66

77
#include "CloudSerial.h"
88

9+
// Declaration of the struct for the mqtt connection options
10+
typedef struct mqtt_opt{
11+
int keepAlive;
12+
bool cleanSession;
13+
int timeout;
14+
} mqttConnectionOptions;
15+
916
class ArduinoCloudClass {
1017

1118
public:
@@ -14,33 +21,47 @@ class ArduinoCloudClass {
1421

1522
int begin(Client& net);
1623

17-
int connect();
24+
// Class constant declaration
25+
static const int MQTT_BUFFER_SIZE = 256;
26+
static const int MAX_RETRIES = 5;
27+
static const int RECONNECTION_TIMEOUT = 2000;
28+
const mqttConnectionOptions mqttOpt = {120, false, 1000};
1829

30+
int connect();
31+
bool disconnect();
1932
void poll();
2033

34+
// defined for users who want to specify max reconnections reties and timeout between them
35+
void poll(int reconnectionMaxRetries, int reconnectionTimeoutMs);
36+
// It must be a user defined function, in order to avoid ArduinoCloud include specific WiFi file
37+
// in this case this library is independent from the WiFi one
2138
void onGetTime(unsigned long(*)(void));
2239

2340
int connected();
41+
// Clean up existing Mqtt connection, create a new one and initialize it
42+
void reconnect(Client& net);
2443

2544
protected:
2645
friend class CloudSerialClass;
2746
int writeStdout(const byte data[], int length);
47+
// Used to initialize MQTTClient
48+
void mqttClientBegin(Client& net);
49+
// Function in charge of perform MQTT reconnection, basing on class parameters(retries,and timeout)
50+
bool mqttReconnect(int maxRetries, int timeout);
2851

2952
private:
3053
static void onMessage(MQTTClient *client, char topic[], char bytes[], int length);
31-
3254
void handleMessage(char topic[], char bytes[], int length);
3355

34-
private:
3556
String _id;
3657
BearSSLClient* _bearSslClient;
3758
MQTTClient _mqttClient;
3859

60+
// Class attribute to define MTTQ topics 2 for stdIn/out and 2 for data, in order to avoid getting previous pupblished payload
3961
String _stdinTopic;
4062
String _stdoutTopic;
4163
};
4264

43-
4465
extern ArduinoCloudClass ArduinoCloud;
4566

4667
#endif

0 commit comments

Comments
 (0)