Skip to content

Commit c16298c

Browse files
authored
Merge pull request #176 from arduino-libraries/restructure-connection-logic
Restructure connection logic
2 parents b6a1257 + b673b59 commit c16298c

11 files changed

+249
-261
lines changed

Diff for: src/AIoTC_Config.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
#endif
4444

4545
#ifndef DBG_VERBOSE
46-
#define DBG_VERBOSE(fmt, ...) Debug.print(DBG_VERBOSE, fmt, ## __VA_ARGS__)
46+
#define DBG_VERBOSE(fmt, ...) //Debug.print(DBG_VERBOSE, fmt, ## __VA_ARGS__)
4747
#endif
4848

4949
/******************************************************************************

Diff for: src/ArduinoIoTCloud.cpp

-28
Original file line numberDiff line numberDiff line change
@@ -172,38 +172,10 @@ Property& ArduinoIoTCloudClass::addPropertyReal(String& property, String name, i
172172
* PROTECTED MEMBER FUNCTIONS
173173
******************************************************************************/
174174

175-
NetworkConnectionState ArduinoIoTCloudClass::checkPhyConnection()
176-
{
177-
NetworkConnectionState const connect_state = _connection->check();
178-
179-
if (_connection->check() != NetworkConnectionState::CONNECTED)
180-
{
181-
if (_iot_status == ArduinoIoTConnectionStatus::CONNECTED)
182-
{
183-
disconnect();
184-
}
185-
}
186-
187-
return connect_state;
188-
}
189-
190175
void ArduinoIoTCloudClass::execCloudEventCallback(ArduinoIoTCloudEvent const event)
191176
{
192177
OnCloudEventCallback callback = _cloud_event_callback[static_cast<size_t>(event)];
193178
if (callback) {
194179
(*callback)();
195180
}
196181
}
197-
198-
void ArduinoIoTCloudClass::printConnectionStatus(ArduinoIoTConnectionStatus status)
199-
{
200-
switch (status)
201-
{
202-
case ArduinoIoTConnectionStatus::IDLE: DBG_INFO ("Arduino IoT Cloud Connection status: IDLE"); break;
203-
case ArduinoIoTConnectionStatus::ERROR: DBG_ERROR("Arduino IoT Cloud Connection status: ERROR"); break;
204-
case ArduinoIoTConnectionStatus::CONNECTING: DBG_INFO ("Arduino IoT Cloud Connection status: CONNECTING"); break;
205-
case ArduinoIoTConnectionStatus::RECONNECTING: DBG_INFO ("Arduino IoT Cloud Connection status: RECONNECTING"); break;
206-
case ArduinoIoTConnectionStatus::CONNECTED: DBG_INFO ("Arduino IoT Cloud Connection status: CONNECTED"); break;
207-
case ArduinoIoTConnectionStatus::DISCONNECTED: DBG_ERROR("Arduino IoT Cloud Connection status: DISCONNECTED"); break;
208-
}
209-
}

Diff for: src/ArduinoIoTCloud.h

+6-16
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
#include "property/types/CloudWrapperInt.h"
3939
#include "property/types/CloudWrapperString.h"
4040

41+
#include "utility/time/TimeService.h"
42+
4143
/******************************************************************************
4244
TYPEDEF
4345
******************************************************************************/
@@ -59,13 +61,6 @@ enum class ArduinoIoTConnectionStatus
5961
ERROR,
6062
};
6163

62-
enum class ArduinoIoTSynchronizationStatus
63-
{
64-
SYNC_STATUS_SYNCHRONIZED,
65-
SYNC_STATUS_WAIT_FOR_CLOUD_VALUES,
66-
SYNC_STATUS_VALUES_PROCESSED
67-
};
68-
6964
enum class ArduinoIoTCloudEvent : size_t
7065
{
7166
SYNC = 0, CONNECT = 1, DISCONNECT = 2
@@ -98,6 +93,8 @@ class ArduinoIoTCloudClass
9893

9994
inline ConnectionHandler * getConnection() { return _connection; }
10095

96+
inline unsigned long getInternalTime() { return _time_service.getTime(); }
97+
10198
void addCallback(ArduinoIoTCloudEvent const event, OnCloudEventCallback callback);
10299

103100
#define addProperty( v, ...) addPropertyReal(v, #v, __VA_ARGS__)
@@ -138,18 +135,11 @@ class ArduinoIoTCloudClass
138135

139136
protected:
140137

141-
virtual int connect () = 0;
142-
virtual void disconnect() = 0;
143-
144-
inline ArduinoIoTConnectionStatus getIoTStatus() { return _iot_status; }
145-
146138
ConnectionHandler * _connection = nullptr;
147139
PropertyContainer _property_container;
148-
ArduinoIoTConnectionStatus _iot_status = ArduinoIoTConnectionStatus::IDLE;
140+
TimeService _time_service;
149141

150-
NetworkConnectionState checkPhyConnection();
151-
void execCloudEventCallback(ArduinoIoTCloudEvent const event);
152-
static void printConnectionStatus(ArduinoIoTConnectionStatus status);
142+
void execCloudEventCallback(ArduinoIoTCloudEvent const event);
153143

154144
private:
155145

Diff for: src/ArduinoIoTCloudLPWAN.cpp

+65-43
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,22 @@
3333

3434
static size_t const CBOR_LORA_MSG_MAX_SIZE = 255;
3535

36+
/******************************************************************************
37+
LOCAL MODULE FUNCTIONS
38+
******************************************************************************/
39+
40+
extern "C" unsigned long getTime()
41+
{
42+
return ArduinoCloud.getInternalTime();
43+
}
44+
3645
/******************************************************************************
3746
CTOR/DTOR
3847
******************************************************************************/
3948

4049
ArduinoIoTCloudLPWAN::ArduinoIoTCloudLPWAN()
41-
: _retryEnable{false}
50+
: _state{State::ConnectPhy}
51+
, _retryEnable{false}
4252
, _maxNumRetry{5}
4353
, _intervalRetry{1000}
4454
{
@@ -58,45 +68,21 @@ int ArduinoIoTCloudLPWAN::begin(ConnectionHandler& connection, bool retry)
5868
{
5969
_connection = &connection;
6070
_retryEnable = retry;
71+
_time_service.begin(nullptr);
6172
return 1;
6273
}
6374

6475
void ArduinoIoTCloudLPWAN::update()
6576
{
66-
// Check if a primitive property wrapper is locally changed
67-
updateTimestampOnLocallyChangedProperties(_property_container);
68-
69-
ArduinoIoTConnectionStatus next_iot_status = _iot_status;
70-
71-
/* Since we do not have a direct connection to the Arduino IoT Cloud servers
72-
* there is no such thing is a 'cloud connection state' since the LoRa
73-
* board connection state to the gateway is all the information we have.
74-
*/
75-
NetworkConnectionState const net_con_state = checkPhyConnection();
76-
if (net_con_state == NetworkConnectionState::CONNECTED) { next_iot_status = ArduinoIoTConnectionStatus::CONNECTED; execCloudEventCallback(ArduinoIoTCloudEvent::CONNECT); }
77-
else if(net_con_state == NetworkConnectionState::CONNECTING) { next_iot_status = ArduinoIoTConnectionStatus::CONNECTING; }
78-
else if(net_con_state == NetworkConnectionState::DISCONNECTED) { next_iot_status = ArduinoIoTConnectionStatus::DISCONNECTED; execCloudEventCallback(ArduinoIoTCloudEvent::DISCONNECT); }
79-
80-
if(next_iot_status != _iot_status)
77+
/* Run through the state machine. */
78+
State next_state = _state;
79+
switch (_state)
8180
{
82-
printConnectionStatus(next_iot_status);
83-
_iot_status = next_iot_status;
84-
}
85-
86-
if(net_con_state != NetworkConnectionState::CONNECTED) return;
87-
88-
if (_connection->available()) {
89-
uint8_t msgBuf[CBOR_LORA_MSG_MAX_SIZE];
90-
uint8_t i = 0;
91-
while (_connection->available()) {
92-
msgBuf[i++] = _connection->read();
93-
}
94-
95-
CBORDecoder::decode(_property_container, msgBuf, sizeof(msgBuf));
81+
case State::ConnectPhy: next_state = handle_ConnectPhy(); break;
82+
case State::SyncTime: next_state = handle_SyncTime(); break;
83+
case State::Connected: next_state = handle_Connected(); break;
9684
}
97-
98-
sendPropertiesToCloud();
99-
execCloudEventCallback(ArduinoIoTCloudEvent::SYNC);
85+
_state = next_state;
10086
}
10187

10288
void ArduinoIoTCloudLPWAN::printDebugInfo()
@@ -106,23 +92,58 @@ void ArduinoIoTCloudLPWAN::printDebugInfo()
10692
}
10793

10894
/******************************************************************************
109-
* PROTECTED MEMBER FUNCTIONS
95+
* PRIVATE MEMBER FUNCTIONS
11096
******************************************************************************/
11197

112-
int ArduinoIoTCloudLPWAN::connect()
98+
ArduinoIoTCloudLPWAN::State ArduinoIoTCloudLPWAN::handle_ConnectPhy()
11399
{
114-
_connection->connect();
115-
return 1;
100+
if (_connection->check() == NetworkConnectionState::CONNECTED)
101+
return State::SyncTime;
102+
else
103+
return State::ConnectPhy;
116104
}
117105

118-
void ArduinoIoTCloudLPWAN::disconnect()
106+
ArduinoIoTCloudLPWAN::State ArduinoIoTCloudLPWAN::handle_SyncTime()
119107
{
120-
_connection->disconnect();
108+
unsigned long const internal_posix_time = _time_service.getTime();
109+
DBG_VERBOSE("ArduinoIoTCloudLPWAN::%s internal clock configured to posix timestamp %d", __FUNCTION__, internal_posix_time);
110+
DBG_INFO("Connected to Arduino IoT Cloud");
111+
return State::Connected;
121112
}
122113

123-
/******************************************************************************
124-
* PRIVATE MEMBER FUNCTIONS
125-
******************************************************************************/
114+
ArduinoIoTCloudLPWAN::State ArduinoIoTCloudLPWAN::handle_Connected()
115+
{
116+
if (!connected())
117+
{
118+
DBG_ERROR("ArduinoIoTCloudLPWAN::%s connection to gateway lost", __FUNCTION__);
119+
return State::ConnectPhy;
120+
}
121+
122+
/* Check if a primitive property wrapper is locally changed. */
123+
updateTimestampOnLocallyChangedProperties(_property_container);
124+
125+
/* Decode available data. */
126+
if (_connection->available())
127+
decodePropertiesFromCloud();
128+
129+
/* If properties need updating sent them to the cloud. */
130+
sendPropertiesToCloud();
131+
132+
return State::Connected;
133+
}
134+
135+
void ArduinoIoTCloudLPWAN::decodePropertiesFromCloud()
136+
{
137+
uint8_t lora_msg_buf[CBOR_LORA_MSG_MAX_SIZE];
138+
size_t bytes_received;
139+
for (bytes_received = 0;
140+
_connection->available() && (bytes_received < CBOR_LORA_MSG_MAX_SIZE);
141+
bytes_received++)
142+
{
143+
lora_msg_buf[bytes_received] = _connection->read();
144+
}
145+
CBORDecoder::decode(_property_container, lora_msg_buf, bytes_received);
146+
}
126147

127148
void ArduinoIoTCloudLPWAN::sendPropertiesToCloud()
128149
{
@@ -138,7 +159,8 @@ int ArduinoIoTCloudLPWAN::writeProperties(const byte data[], int length)
138159
{
139160
int retcode = _connection->write(data, length);
140161
int i = 0;
141-
while (_retryEnable && retcode < 0 && i < _maxNumRetry) {
162+
while (_retryEnable && retcode < 0 && i < _maxNumRetry)
163+
{
142164
delay(_intervalRetry);
143165
retcode = _connection->write(data, length);
144166
i++;

Diff for: src/ArduinoIoTCloudLPWAN.h

+13-6
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,25 @@ class ArduinoIoTCloudLPWAN : public ArduinoIoTCloudClass
5050
inline void setIntervalRetry(long val) { _intervalRetry = val; }
5151

5252

53-
protected:
54-
55-
virtual int connect () override;
56-
virtual void disconnect () override;
57-
58-
5953
private:
6054

55+
enum class State
56+
{
57+
ConnectPhy,
58+
SyncTime,
59+
Connected,
60+
};
61+
62+
State _state;
6163
bool _retryEnable;
6264
int _maxNumRetry;
6365
long _intervalRetry;
6466

67+
State handle_ConnectPhy();
68+
State handle_SyncTime();
69+
State handle_Connected();
70+
71+
void decodePropertiesFromCloud();
6572
void sendPropertiesToCloud();
6673
int writeProperties(const byte data[], int length);
6774
};

0 commit comments

Comments
 (0)