Skip to content

Commit ed25616

Browse files
pennamandreagilardoni
authored andcommitted
ArduinoIoTCloudTCP: switch to messages
1 parent 3e281fa commit ed25616

File tree

2 files changed

+73
-41
lines changed

2 files changed

+73
-41
lines changed

src/ArduinoIoTCloudTCP.cpp

+63-28
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <algorithm>
4444
#include "cbor/CBOREncoder.h"
4545
#include "utility/watchdog/Watchdog.h"
46+
#include <typeinfo>
4647

4748
/******************************************************************************
4849
LOCAL MODULE FUNCTIONS
@@ -74,12 +75,6 @@ ArduinoIoTCloudTCP::ArduinoIoTCloudTCP()
7475
, _password("")
7576
#endif
7677
, _mqttClient{nullptr}
77-
, _deviceTopicOut("")
78-
, _deviceTopicIn("")
79-
, _shadowTopicOut("")
80-
, _shadowTopicIn("")
81-
, _dataTopicOut("")
82-
, _dataTopicIn("")
8378
#if OTA_ENABLED
8479
, _ota_cap{false}
8580
, _ota_error{static_cast<int>(OTAError::None)}
@@ -181,24 +176,21 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress,
181176
_mqttClient.setUsernamePassword(getDeviceId(), _password);
182177
}
183178
#endif
179+
184180
_mqttClient.onMessage(ArduinoIoTCloudTCP::onMessage);
185181
_mqttClient.setKeepAliveInterval(30 * 1000);
186182
_mqttClient.setConnectionTimeout(1500);
187183
_mqttClient.setId(getDeviceId().c_str());
188184

189-
_deviceTopicOut = getTopic_deviceout();
190-
_deviceTopicIn = getTopic_devicein();
185+
getTopic_devicein() = getTopic_devicein();
191186

192-
Property* p;
193-
p = new CloudWrapperString(_lib_version);
194-
addPropertyToContainer(_device.getPropertyContainer(), *p, "LIB_VERSION", Permission::Read, -1);
195-
p = new CloudWrapperString(_thing_id);
196-
_thing_id_property = &addPropertyToContainer(_device.getPropertyContainer(), *p, "thing_id", Permission::ReadWrite, -1).writeOnDemand();
187+
_messageTopicIn = getTopic_messagein();
197188

198189
_thing.begin();
199190
_device.begin();
200191

201192
#if OTA_ENABLED
193+
Property* p;
202194
p = new CloudWrapperBool(_ota_cap);
203195
addPropertyToContainer(_device.getPropertyContainer(), *p, "OTA_CAP", Permission::Read, -1);
204196
p = new CloudWrapperInt(_ota_error);
@@ -322,6 +314,7 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_ConnectMqttBroker()
322314
{
323315
if (_mqttClient.connect(_brokerAddress.c_str(), _brokerPort))
324316
{
317+
_mqttClient.subscribe(getTopic_messagein());
325318
DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s connected to %s:%d", __FUNCTION__, _brokerAddress.c_str(), _brokerPort);
326319
/* Reconfigure timers for next state */
327320
_connection_attempt.begin(AIOT_CONFIG_DEVICE_TOPIC_SUBSCRIBE_RETRY_DELAY_ms, AIOT_CONFIG_MAX_DEVICE_TOPIC_SUBSCRIBE_RETRY_DELAY_ms);
@@ -437,7 +430,7 @@ void ArduinoIoTCloudTCP::handleMessage(int length)
437430
}
438431

439432
/* Topic for OTA properties and device configuration */
440-
if (_deviceTopicIn == topic) {
433+
if (getTopic_devicein() == topic) {
441434
CBORDecoder::decode(_device.getPropertyContainer(), (uint8_t*)bytes, length);
442435

443436
/* Temporary check to avoid flooding device state machine with usless messages */
@@ -468,16 +461,47 @@ void ArduinoIoTCloudTCP::handleMessage(int length)
468461
CBORDecoder::decode(_thing.getPropertyContainer(), (uint8_t*)bytes, length);
469462
}
470463

471-
/* Topic for sync Thing last values on connect */
472-
if (_shadowTopicIn == topic) {
473-
DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s [%d] last values received", __FUNCTION__, millis());
474-
/* Decode last values property array */
475-
CBORDecoder::decode(_thing.getPropertyContainer(), (uint8_t*)bytes, length, true);
476-
/* Unlock thing state machine waiting last values */
477-
Message message = { LastValuesUpdateCmdId };
478-
_thing.handleMessage(&message);
479-
/* Call ArduinoIoTCloud sync user callback*/
480-
execCloudEventCallback(ArduinoIoTCloudEvent::SYNC);
464+
/* Topic for device commands */
465+
if (getTopic_messagein() == topic) {
466+
CommandDown command;
467+
DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s [%d] received %d bytes", __FUNCTION__, millis(), length);
468+
CBORMessageDecoder decoder;
469+
470+
size_t buffer_length = length;
471+
if (decoder.decode((Message*)&command, bytes, buffer_length) != Decoder::Status::Error) {
472+
DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s [%d] received command id %d", __FUNCTION__, millis(), command.c.id);
473+
switch (command.c.id)
474+
{
475+
case CommandId::ThingUpdateCmdId:
476+
{
477+
_thing_id = String(command.thingBeginCmd.params.thing_id);
478+
DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s [%d] device configuration received", __FUNCTION__, millis());
479+
_device.handleMessage((Message*)&command);
480+
}
481+
break;
482+
483+
case CommandId::LastValuesUpdateCmdId:
484+
{
485+
DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s [%d] last values received", __FUNCTION__, millis());
486+
CBORDecoder::decode(_thing.getPropertyContainer(),
487+
(uint8_t*)command.lastValuesUpdateCmd.params.last_values,
488+
command.lastValuesUpdateCmd.params.length, true);
489+
_thing.handleMessage((Message*)&command);
490+
execCloudEventCallback(ArduinoIoTCloudEvent::SYNC);
491+
492+
/*
493+
* NOTE: in this current version properties are not properly integrated with the new paradigm of
494+
* modeling the messages with C structs. The current CBOR library allocates an array in the heap
495+
* thus we need to delete it after decoding it with the old CBORDecoder
496+
*/
497+
free(command.lastValuesUpdateCmd.params.last_values);
498+
}
499+
break;
500+
501+
default:
502+
break;
503+
}
504+
}
481505
}
482506
}
483507

@@ -504,6 +528,17 @@ void ArduinoIoTCloudTCP::sendMessage(Message * msg)
504528
default:
505529
break;
506530
}
531+
532+
uint8_t data[MQTT_TRANSMIT_BUFFER_SIZE];
533+
size_t bytes_encoded = sizeof(data);
534+
CBORMessageEncoder encoder;
535+
536+
if (encoder.encode(msg, data, bytes_encoded) == Encoder::Status::Complete &&
537+
bytes_encoded > 0) {
538+
write(getTopic_messageout(), data, bytes_encoded);
539+
} else {
540+
DEBUG_ERROR("error encoding %d", msg->id);
541+
}
507542
}
508543

509544
void ArduinoIoTCloudTCP::sendPropertyContainerToCloud(String const topic, PropertyContainer & property_container, unsigned int & current_property_index)
@@ -546,7 +581,7 @@ void ArduinoIoTCloudTCP::sendDevicePropertiesToCloud()
546581
addPropertyToContainer(ro_device_property_container, *p, p->name(), p->isWriteableByCloud() ? Permission::ReadWrite : Permission::Read);
547582
}
548583
);
549-
sendPropertyContainerToCloud(_deviceTopicOut, ro_device_property_container, last_device_property_index);
584+
sendPropertyContainerToCloud(getTopic_deviceout(), ro_device_property_container, last_device_property_index);
550585
}
551586

552587
#if OTA_ENABLED
@@ -559,7 +594,7 @@ void ArduinoIoTCloudTCP::sendDevicePropertyToCloud(String const name)
559594
if(p != nullptr)
560595
{
561596
addPropertyToContainer(temp_device_property_container, *p, p->name(), p->isWriteableByCloud() ? Permission::ReadWrite : Permission::Read);
562-
sendPropertyContainerToCloud(_deviceTopicOut, temp_device_property_container, last_device_property_index);
597+
sendPropertyContainerToCloud(getTopic_deviceout(), temp_device_property_container, last_device_property_index);
563598
}
564599
}
565600
#endif
@@ -575,12 +610,12 @@ void ArduinoIoTCloudTCP::requestLastValue()
575610

576611
void ArduinoIoTCloudTCP::requestThingId()
577612
{
578-
if (!_mqttClient.subscribe(_deviceTopicIn))
613+
if (!_mqttClient.subscribe(getTopic_devicein()))
579614
{
580615
/* If device_id is wrong the board can't connect to the broker so this condition
581616
* should never happen.
582617
*/
583-
DEBUG_ERROR("ArduinoIoTCloudTCP::%s could not subscribe to %s", __FUNCTION__, _deviceTopicIn.c_str());
618+
DEBUG_ERROR("ArduinoIoTCloudTCP::%s could not subscribe to %s", __FUNCTION__, getTopic_devicein().c_str());
584619
}
585620
}
586621

src/ArduinoIoTCloudTCP.h

+10-13
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@
5656
#include <utility/ota/OTA.h>
5757
#endif
5858

59+
#include "cbor/MessageDecoder.h"
60+
#include "cbor/MessageEncoder.h"
61+
5962
/******************************************************************************
6063
CONSTANTS
6164
******************************************************************************/
@@ -163,10 +166,8 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass
163166

164167
MqttClient _mqttClient;
165168

166-
String _deviceTopicOut;
167-
String _deviceTopicIn;
168-
String _shadowTopicOut;
169-
String _shadowTopicIn;
169+
String _messageTopicOut;
170+
String _messageTopicIn;
170171
String _dataTopicOut;
171172
String _dataTopicIn;
172173

@@ -182,8 +183,10 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass
182183

183184
inline String getTopic_deviceout() { return String("/a/d/" + getDeviceId() + "/e/o");}
184185
inline String getTopic_devicein () { return String("/a/d/" + getDeviceId() + "/e/i");}
185-
inline String getTopic_shadowout() { return ( getThingId().length() == 0) ? String("") : String("/a/t/" + getThingId() + "/shadow/o"); }
186-
inline String getTopic_shadowin () { return ( getThingId().length() == 0) ? String("") : String("/a/t/" + getThingId() + "/shadow/i"); }
186+
187+
inline String getTopic_messageout() { return String("/a/d/" + getDeviceId() + "/c/up");}
188+
inline String getTopic_messagein () { return String("/a/d/" + getDeviceId() + "/c/dw");}
189+
187190
inline String getTopic_dataout () { return ( getThingId().length() == 0) ? String("") : String("/a/t/" + getThingId() + "/e/o"); }
188191
inline String getTopic_datain () { return ( getThingId().length() == 0) ? String("") : String("/a/t/" + getThingId() + "/e/i"); }
189192

@@ -198,17 +201,11 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass
198201
void sendMessage(Message * msg);
199202
void sendPropertyContainerToCloud(String const topic, PropertyContainer & property_container, unsigned int & current_property_index);
200203
void sendThingPropertiesToCloud();
201-
void sendDevicePropertiesToCloud();
202-
void requestLastValue();
203-
void requestThingId();
204+
204205
void attachThing();
205206
void detachThing();
206207
int write(String const topic, byte const data[], int const length);
207208

208-
#if OTA_ENABLED
209-
void sendDevicePropertyToCloud(String const name);
210-
#endif
211-
212209
};
213210

214211
/******************************************************************************

0 commit comments

Comments
 (0)