Skip to content

Commit 9e5f513

Browse files
authored
Merge pull request #449 from arduino-libraries/new-ota-structure
New ota structure
2 parents 6838688 + 249bae3 commit 9e5f513

34 files changed

+2326
-1363
lines changed

.github/workflows/compile-examples.yml

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ jobs:
2222
# Install the ArduinoIoTCloud library from the repository
2323
- source-path: ./
2424
- name: Arduino_ConnectionHandler
25+
- name: ArduinoHttpClient
2526
- name: Arduino_DebugUtils
2627
- name: ArduinoMqttClient
2728
- name: Arduino_SecureElement

library.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ category=Communication
88
url=https://github.com/arduino-libraries/ArduinoIoTCloud
99
architectures=mbed,samd,esp8266,mbed_nano,mbed_portenta,mbed_nicla,esp32,mbed_opta,mbed_giga,renesas_portenta,renesas_uno,mbed_edge
1010
includes=ArduinoIoTCloud.h
11-
depends=Arduino_ConnectionHandler,Arduino_DebugUtils,Arduino_SecureElement,ArduinoMqttClient,ArduinoECCX08,RTCZero,Adafruit SleepyDog Library,Arduino_ESP32_OTA,Arduino_Portenta_OTA
11+
depends=Arduino_ConnectionHandler,Arduino_DebugUtils,Arduino_SecureElement,ArduinoMqttClient,ArduinoECCX08,RTCZero,Adafruit SleepyDog Library,ArduinoHttpClient

src/AIoTC_Config.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
#endif
6666

6767
#ifdef ARDUINO_SAMD_MKRGSM1400
68-
#define OTA_STORAGE_SSU (1)
68+
#define OTA_STORAGE_SSU (1) // OTA_STORAGE_SSU is not implemented yet in OTASamd
6969
#else
7070
#define OTA_STORAGE_SSU (0)
7171
#endif
@@ -80,7 +80,7 @@
8080
#define OTA_STORAGE_ESP (1)
8181
#endif
8282

83-
#if (OTA_STORAGE_SFU || OTA_STORAGE_SSU || OTA_STORAGE_SNU || OTA_STORAGE_PORTENTA_QSPI || OTA_STORAGE_ESP)
83+
#if (OTA_STORAGE_SFU || OTA_STORAGE_SNU || OTA_STORAGE_PORTENTA_QSPI || OTA_STORAGE_ESP)
8484
#define OTA_ENABLED (1)
8585
#else
8686
#define OTA_ENABLED (0)

src/ArduinoIoTCloudDevice.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,6 @@ ArduinoCloudDevice::State ArduinoCloudDevice::handleConnected() {
135135
}
136136
return State::SendCapabilities;
137137
}
138-
139138
return State::Connected;
140139
}
141140

src/ArduinoIoTCloudTCP.cpp

+45-134
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,11 @@
2222
#include <AIoTC_Config.h>
2323

2424
#ifdef HAS_TCP
25-
#include <ArduinoIoTCloudTCP.h>
26-
27-
#if defined(BOARD_HAS_SECRET_KEY)
28-
#include "tls/AIoTCUPCert.h"
29-
#endif
3025

31-
#ifdef BOARD_HAS_ECCX08
32-
#include "tls/BearSSLTrustAnchors.h"
33-
#endif
34-
35-
#if defined(BOARD_HAS_SE050) || defined(BOARD_HAS_SOFTSE)
36-
#include "tls/AIoTCSSCert.h"
37-
#endif
26+
#include <ArduinoIoTCloudTCP.h>
3827

3928
#if OTA_ENABLED
40-
#include "utility/ota/OTA.h"
29+
#include "ota/OTA.h"
4130
#endif
4231

4332
#include <algorithm>
@@ -67,26 +56,16 @@ ArduinoIoTCloudTCP::ArduinoIoTCloudTCP()
6756
, _mqtt_data_buf{0}
6857
, _mqtt_data_len{0}
6958
, _mqtt_data_request_retransmit{false}
70-
#ifdef BOARD_HAS_ECCX08
71-
, _sslClient(nullptr, ArduinoIoTCloudTrustAnchor, ArduinoIoTCloudTrustAnchor_NUM, getTime)
72-
#endif
7359
#ifdef BOARD_HAS_SECRET_KEY
7460
, _password("")
7561
#endif
7662
, _mqttClient{nullptr}
77-
, _deviceTopicOut("")
78-
, _deviceTopicIn("")
7963
, _messageTopicOut("")
8064
, _messageTopicIn("")
8165
, _dataTopicOut("")
8266
, _dataTopicIn("")
8367
#if OTA_ENABLED
84-
, _ota_cap{false}
85-
, _ota_error{static_cast<int>(OTAError::None)}
86-
, _ota_img_sha256{"Inv."}
87-
, _ota_url{""}
88-
, _ota_req{false}
89-
, _ask_user_before_executing_ota{false}
68+
, _ota(&_message_stream)
9069
, _get_ota_confirmation{nullptr}
9170
#endif /* OTA_ENABLED */
9271
{
@@ -107,8 +86,16 @@ int ArduinoIoTCloudTCP::begin(ConnectionHandler & connection, bool const enable_
10786
_brokerPort = brokerPort;
10887
#endif
10988

89+
/* Setup broker TLS client */
90+
_brokerClient.begin(connection);
91+
92+
#if OTA_ENABLED
93+
/* Setup OTA TLS client */
94+
_otaClient.begin(connection);
95+
#endif
96+
11097
/* Setup TimeService */
111-
_time_service.begin(&connection);
98+
_time_service.begin(_connection);
11299

113100
/* Setup retry timers */
114101
_connection_attempt.begin(AIOT_CONFIG_RECONNECTION_RETRY_DELAY_ms, AIOT_CONFIG_MAX_RECONNECTION_RETRY_DELAY_ms);
@@ -148,33 +135,19 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress,
148135
DEBUG_ERROR("ArduinoIoTCloudTCP::%s could not read device certificate.", __FUNCTION__);
149136
return 0;
150137
}
151-
_sslClient.setEccSlot(static_cast<int>(SElementArduinoCloudSlot::Key), _cert.bytes(), _cert.length());
138+
_brokerClient.setEccSlot(static_cast<int>(SElementArduinoCloudSlot::Key), _cert.bytes(), _cert.length());
139+
#if OTA_ENABLED
140+
_otaClient.setEccSlot(static_cast<int>(SElementArduinoCloudSlot::Key), _cert.bytes(), _cert.length());
141+
#endif
152142
#endif
153143
#endif
144+
154145
#if defined(BOARD_HAS_SECRET_KEY)
155146
}
156147
#endif
157148

158-
#if defined(BOARD_HAS_OFFLOADED_ECCX08)
159-
160-
#elif defined(BOARD_HAS_ECCX08)
161-
_sslClient.setClient(_connection->getClient());
162-
#elif defined(ARDUINO_PORTENTA_C33)
163-
_sslClient.setClient(_connection->getClient());
164-
_sslClient.setCACert(AIoTSSCert);
165-
#elif defined(ARDUINO_NICLA_VISION)
166-
_sslClient.appendCustomCACert(AIoTSSCert);
167-
#elif defined(ARDUINO_EDGE_CONTROL)
168-
_sslClient.appendCustomCACert(AIoTUPCert);
169-
#elif defined(ARDUINO_UNOR4_WIFI)
170-
171-
#elif defined(ARDUINO_ARCH_ESP32)
172-
_sslClient.setCACertBundle(x509_crt_bundle);
173-
#elif defined(ARDUINO_ARCH_ESP8266)
174-
_sslClient.setInsecure();
175-
#endif
149+
_mqttClient.setClient(_brokerClient);
176150

177-
_mqttClient.setClient(_sslClient);
178151
#ifdef BOARD_HAS_SECRET_KEY
179152
if(_password.length())
180153
{
@@ -187,32 +160,19 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress,
187160
_mqttClient.setConnectionTimeout(1500);
188161
_mqttClient.setId(getDeviceId().c_str());
189162

190-
_deviceTopicOut = getTopic_deviceout();
191-
_deviceTopicIn = getTopic_devicein();
192-
_messageTopicIn = getTopic_messagein();
193163
_messageTopicOut = getTopic_messageout();
164+
_messageTopicIn = getTopic_messagein();
194165

195166
_thing.begin();
196167
_device.begin();
197168

198-
#if OTA_ENABLED
199-
Property* p;
200-
p = new CloudWrapperBool(_ota_cap);
201-
addPropertyToContainer(_device.getPropertyContainer(), *p, "OTA_CAP", Permission::Read, -1);
202-
p = new CloudWrapperInt(_ota_error);
203-
addPropertyToContainer(_device.getPropertyContainer(), *p, "OTA_ERROR", Permission::Read, -1);
204-
p = new CloudWrapperString(_ota_img_sha256);
205-
addPropertyToContainer(_device.getPropertyContainer(), *p, "OTA_SHA256", Permission::Read, -1);
206-
p = new CloudWrapperString(_ota_url);
207-
addPropertyToContainer(_device.getPropertyContainer(), *p, "OTA_URL", Permission::ReadWrite, -1);
208-
p = new CloudWrapperBool(_ota_req);
209-
addPropertyToContainer(_device.getPropertyContainer(), *p, "OTA_REQ", Permission::ReadWrite, -1);
210-
211-
_ota_cap = OTA::isCapable();
212-
213-
_ota_img_sha256 = OTA::getImageSHA256();
214-
DEBUG_VERBOSE("SHA256: HASH(%d) = %s", strlen(_ota_img_sha256.c_str()), _ota_img_sha256.c_str());
215-
#endif // OTA_ENABLED
169+
#if OTA_ENABLED && !defined(OFFLOADED_DOWNLOAD)
170+
_ota.setClient(&_otaClient);
171+
#endif // OTA_ENABLED && !defined(OFFLOADED_DOWNLOAD)
172+
173+
#if OTA_ENABLED && defined(OTA_BASIC_AUTH)
174+
_ota.setAuthentication(getDeviceId().c_str(), _password.c_str());
175+
#endif // OTA_ENABLED && !defined(OFFLOADED_DOWNLOAD) && defined(OTA_BASIC_AUTH)
216176

217177
#ifdef BOARD_HAS_OFFLOADED_ECCX08
218178
if (String(WiFi.firmwareVersion()) < String("1.4.4")) {
@@ -323,9 +283,6 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_ConnectMqttBroker()
323283
/* Subscribe to message topic to receive commands */
324284
_mqttClient.subscribe(_messageTopicIn);
325285

326-
/* Temoporarly subscribe to device topic to receive OTA properties */
327-
_mqttClient.subscribe(_deviceTopicIn);
328-
329286
/* Reconfigure timers for next state */
330287
_connection_attempt.begin(AIOT_CONFIG_DEVICE_TOPIC_SUBSCRIBE_RETRY_DELAY_ms, AIOT_CONFIG_MAX_DEVICE_TOPIC_SUBSCRIBE_RETRY_DELAY_ms);
331288

@@ -360,50 +317,24 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_Connected()
360317
/* Call CloudDevice process to get configuration */
361318
_device.update();
362319

363-
if (_device.isAttached()) {
364-
/* Call CloudThing process to synchronize properties */
365-
_thing.update();
366-
}
367-
368-
#if OTA_ENABLED
369-
if (_device.connected()) {
370-
handle_OTARequest();
320+
#if OTA_ENABLED
321+
if(_get_ota_confirmation != nullptr &&
322+
_ota.getState() == OTACloudProcessInterface::State::OtaAvailable &&
323+
_get_ota_confirmation()) {
324+
_ota.approveOta();
371325
}
372-
#endif /* OTA_ENABLED */
373326

374-
return State::Connected;
375-
}
327+
_ota.update();
328+
#endif // OTA_ENABLED
376329

377-
#if OTA_ENABLED
378-
void ArduinoIoTCloudTCP::handle_OTARequest() {
379-
/* Request a OTA download if the hidden property
380-
* OTA request has been set.
381-
*/
382330

383-
if (_ota_req)
384-
{
385-
bool const ota_execution_allowed_by_user = (_get_ota_confirmation != nullptr && _get_ota_confirmation());
386-
bool const perform_ota_now = ota_execution_allowed_by_user || !_ask_user_before_executing_ota;
387-
if (perform_ota_now) {
388-
/* Clear the error flag. */
389-
_ota_error = static_cast<int>(OTAError::None);
390-
/* Clear the request flag. */
391-
_ota_req = false;
392-
/* Transmit the cleared request flags to the cloud. */
393-
sendDevicePropertyToCloud("OTA_REQ");
394-
/* Call member function to handle OTA request. */
395-
_ota_error = OTA::onRequest(_ota_url, _connection->getInterface());
396-
/* If something fails send the OTA error to the cloud */
397-
sendDevicePropertyToCloud("OTA_ERROR");
398-
}
331+
if (_device.isAttached()) {
332+
/* Call CloudThing process to synchronize properties */
333+
_thing.update();
399334
}
400335

401-
/* Check if we have received the OTA_URL property and provide
402-
* echo to the cloud.
403-
*/
404-
sendDevicePropertyToCloud("OTA_URL");
336+
return State::Connected;
405337
}
406-
#endif /* OTA_ENABLED */
407338

408339
ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_Disconnect()
409340
{
@@ -441,11 +372,6 @@ void ArduinoIoTCloudTCP::handleMessage(int length)
441372
bytes[i] = _mqttClient.read();
442373
}
443374

444-
/* Topic for OTA properties and device configuration */
445-
if (_deviceTopicIn == topic) {
446-
CBORDecoder::decode(_device.getPropertyContainer(), (uint8_t*)bytes, length);
447-
}
448-
449375
/* Topic for user input data */
450376
if (_dataTopicIn == topic) {
451377
CBORDecoder::decode(_thing.getPropertyContainer(), (uint8_t*)bytes, length);
@@ -502,6 +428,14 @@ void ArduinoIoTCloudTCP::handleMessage(int length)
502428
}
503429
break;
504430

431+
#if OTA_ENABLED
432+
case CommandId::OtaUpdateCmdDownId:
433+
{
434+
DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s [%d] ota update received", __FUNCTION__, millis());
435+
_ota.handleMessage((Message*)&command);
436+
}
437+
#endif
438+
505439
default:
506440
break;
507441
}
@@ -522,14 +456,6 @@ void ArduinoIoTCloudTCP::sendMessage(Message * msg)
522456
_thing.getPropertyContainerIndex());
523457
break;
524458

525-
#if OTA_ENABLED
526-
case DeviceBeginCmdId:
527-
sendDevicePropertyToCloud("OTA_CAP");
528-
sendDevicePropertyToCloud("OTA_ERROR");
529-
sendDevicePropertyToCloud("OTA_SHA256");
530-
break;
531-
#endif
532-
533459
default:
534460
break;
535461
}
@@ -562,21 +488,6 @@ void ArduinoIoTCloudTCP::sendPropertyContainerToCloud(String const topic, Proper
562488
}
563489
}
564490

565-
#if OTA_ENABLED
566-
void ArduinoIoTCloudTCP::sendDevicePropertyToCloud(String const name)
567-
{
568-
PropertyContainer temp_device_property_container;
569-
unsigned int last_device_property_index = 0;
570-
571-
Property* p = getProperty(this->_device.getPropertyContainer(), name);
572-
if(p != nullptr)
573-
{
574-
addPropertyToContainer(temp_device_property_container, *p, p->name(), p->isWriteableByCloud() ? Permission::ReadWrite : Permission::Read);
575-
sendPropertyContainerToCloud(_deviceTopicOut, temp_device_property_container, last_device_property_index);
576-
}
577-
}
578-
#endif
579-
580491
void ArduinoIoTCloudTCP::attachThing(String thingId)
581492
{
582493
_thing_id = thingId;

0 commit comments

Comments
 (0)