Skip to content

Commit 501a279

Browse files
committed
Add ArduinoCloudDevice
1 parent 0d69bbb commit 501a279

File tree

2 files changed

+221
-0
lines changed

2 files changed

+221
-0
lines changed

src/ArduinoIoTCloudDevice.cpp

+151
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/*
2+
This file is part of ArduinoIoTCloud.
3+
4+
Copyright 2019 ARDUINO SA (http://www.arduino.cc/)
5+
6+
This software is released under the GNU General Public License version 3,
7+
which covers the main part of ArduinoIoTCloud.
8+
The terms of this license can be found at:
9+
https://www.gnu.org/licenses/gpl-3.0.en.html
10+
11+
You can be released from the requirements of the above licenses by purchasing
12+
a commercial license. Buying such a license is mandatory if you want to modify or
13+
otherwise use the software for commercial activities involving the Arduino
14+
software without disclosing the source code of your own applications. To purchase
15+
a commercial license, send an email to [email protected].
16+
*/
17+
18+
/******************************************************************************
19+
* INCLUDE
20+
******************************************************************************/
21+
22+
#include <AIoTC_Config.h>
23+
24+
#ifdef HAS_TCP
25+
26+
#include "ArduinoIoTCloudDevice.h"
27+
#include "interfaces/CloudProcess.h"
28+
29+
/******************************************************************************
30+
CTOR/DTOR
31+
******************************************************************************/
32+
ArduinoCloudDevice::ArduinoCloudDevice(MessageStream *ms)
33+
: CloudProcess(ms),
34+
_state{State::Init},
35+
_attachAttempt(0, 0),
36+
_attached(false),
37+
_registered(false) {
38+
}
39+
40+
void ArduinoCloudDevice::begin() {
41+
_attachAttempt.begin(AIOT_CONFIG_DEVICE_TOPIC_SUBSCRIBE_RETRY_DELAY_ms,
42+
AIOT_CONFIG_MAX_DEVICE_TOPIC_SUBSCRIBE_RETRY_DELAY_ms);
43+
}
44+
45+
void ArduinoCloudDevice::update() {
46+
/* Run through the state machine. */
47+
State nextState = _state;
48+
switch (_state) {
49+
case State::Init: nextState = handleInit(); break;
50+
case State::SendCapabilities: nextState = handleSendCapabilities(); break;
51+
case State::Connected: nextState = handleConnected(); break;
52+
case State::Disconnected: nextState = handleDisconnected(); break;
53+
}
54+
55+
/* Handle external events */
56+
switch (_command) {
57+
case DeviceAttachedCmdId:
58+
_attached = true;
59+
_registered = true;
60+
DEBUG_VERBOSE("CloudDevice::%s Device is attached", __FUNCTION__);
61+
nextState = State::Connected;
62+
break;
63+
64+
case DeviceDetachedCmdId:
65+
_attached = false;
66+
_registered = false;
67+
nextState = State::Init;
68+
break;
69+
70+
case DeviceRegisteredCmdId:
71+
_registered = true;
72+
nextState = State::Connected;
73+
break;
74+
75+
/* We have received a reset command */
76+
case ResetCmdId:
77+
nextState = State::Init;
78+
break;
79+
80+
default:
81+
break;
82+
}
83+
84+
_command = UnknownCmdId;
85+
_state = nextState;
86+
}
87+
88+
int ArduinoCloudDevice::connected() {
89+
return _state != State::Disconnected ? 1 : 0;
90+
}
91+
92+
void ArduinoCloudDevice::handleMessage(Message *m) {
93+
_command = UnknownCmdId;
94+
if (m != nullptr) {
95+
_command = m->id;
96+
}
97+
}
98+
99+
ArduinoCloudDevice::State ArduinoCloudDevice::handleInit() {
100+
/* Reset attempt struct for the nex retry after disconnection */
101+
_attachAttempt.begin(AIOT_CONFIG_DEVICE_TOPIC_SUBSCRIBE_RETRY_DELAY_ms,
102+
AIOT_CONFIG_MAX_DEVICE_TOPIC_SUBSCRIBE_RETRY_DELAY_ms);
103+
104+
_attached = false;
105+
_registered = false;
106+
107+
return State::SendCapabilities;
108+
}
109+
110+
ArduinoCloudDevice::State ArduinoCloudDevice::handleSendCapabilities() {
111+
/* Sends device capabilities message */
112+
Message message = { DeviceBeginCmdId };
113+
deliver(&message);
114+
115+
/* Subscribe to device topic to request */
116+
message = { ThingBeginCmdId };
117+
deliver(&message);
118+
119+
/* No device configuration received. Wait: 4s -> 8s -> 16s -> 32s -> 32s ...*/
120+
_attachAttempt.retry();
121+
DEBUG_VERBOSE("CloudDevice::%s not attached. %d next configuration request in %d ms",
122+
__FUNCTION__, _attachAttempt.getRetryCount(), _attachAttempt.getWaitTime());
123+
return State::Connected;
124+
}
125+
126+
ArduinoCloudDevice::State ArduinoCloudDevice::handleConnected() {
127+
/* Max retry than disconnect */
128+
if (_attachAttempt.getRetryCount() > AIOT_CONFIG_DEVICE_TOPIC_MAX_RETRY_CNT) {
129+
return State::Disconnected;
130+
}
131+
132+
if (!_attached && _attachAttempt.isExpired()) {
133+
if (_registered) {
134+
/* Device configuration received, but invalid thing_id. Do not increase
135+
* counter, but recompute delay.
136+
* Wait: 4s -> 80s -> 160s -> 320s -> 640s -> 1280s -> 1280s ...
137+
*/
138+
_attachAttempt.reconfigure(AIOT_CONFIG_DEVICE_TOPIC_ATTACH_RETRY_DELAY_ms,
139+
AIOT_CONFIG_MAX_DEVICE_TOPIC_ATTACH_RETRY_DELAY_ms);
140+
}
141+
return State::SendCapabilities;
142+
}
143+
144+
return State::Connected;
145+
}
146+
147+
ArduinoCloudDevice::State ArduinoCloudDevice::handleDisconnected() {
148+
return State::Disconnected;
149+
}
150+
151+
#endif /* HAS_TCP */

src/ArduinoIoTCloudDevice.h

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
This file is part of the Arduino_SecureElement library.
3+
4+
Copyright (c) 2024 Arduino SA
5+
6+
This Source Code Form is subject to the terms of the Mozilla Public
7+
License, v. 2.0. If a copy of the MPL was not distributed with this
8+
file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
11+
#ifndef ARDUINO_IOT_CLOUD_DEVICE_H
12+
#define ARDUINO_IOT_CLOUD_DEVICE_H
13+
14+
/******************************************************************************
15+
* INCLUDE
16+
******************************************************************************/
17+
18+
#include "interfaces/CloudProcess.h"
19+
#include "utility/time/TimedAttempt.h"
20+
#include "property/PropertyContainer.h"
21+
22+
/******************************************************************************
23+
* CLASS DECLARATION
24+
******************************************************************************/
25+
26+
class ArduinoCloudDevice : public CloudProcess {
27+
public:
28+
29+
ArduinoCloudDevice(MessageStream* stream);
30+
virtual void update() override;
31+
virtual void handleMessage(Message* m) override;
32+
33+
virtual void begin();
34+
virtual int connected();
35+
36+
inline PropertyContainer &getPropertyContainer() {
37+
return _propertyContainer;
38+
};
39+
inline unsigned int &getPropertyContainerIndex() {
40+
return _propertyContainerIndex;
41+
}
42+
inline bool isAttached() {
43+
return _attached;
44+
};
45+
46+
47+
private:
48+
49+
enum class State {
50+
Disconnected,
51+
Init,
52+
SendCapabilities,
53+
Connected,
54+
};
55+
56+
State _state;
57+
CommandId _command;
58+
TimedAttempt _attachAttempt;
59+
PropertyContainer _propertyContainer;
60+
unsigned int _propertyContainerIndex;
61+
bool _attached;
62+
bool _registered;
63+
64+
State handleInit();
65+
State handleSendCapabilities();
66+
State handleConnected();
67+
State handleDisconnected();
68+
};
69+
70+
#endif /* ARDUINO_IOT_CLOUD_DEVICE_H */

0 commit comments

Comments
 (0)