43
43
#include < algorithm>
44
44
#include " cbor/CBOREncoder.h"
45
45
#include " utility/watchdog/Watchdog.h"
46
+ #include < typeinfo>
46
47
47
48
/* *****************************************************************************
48
49
LOCAL MODULE FUNCTIONS
@@ -74,10 +75,8 @@ ArduinoIoTCloudTCP::ArduinoIoTCloudTCP()
74
75
, _password(" " )
75
76
#endif
76
77
, _mqttClient{nullptr }
77
- , _deviceTopicOut(" " )
78
- , _deviceTopicIn(" " )
79
- , _shadowTopicOut(" " )
80
- , _shadowTopicIn(" " )
78
+ , _messageTopicOut(" " )
79
+ , _messageTopicIn(" " )
81
80
, _dataTopicOut(" " )
82
81
, _dataTopicIn(" " )
83
82
#if OTA_ENABLED
@@ -181,6 +180,7 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress,
181
180
_mqttClient.setUsernamePassword (getDeviceId (), _password);
182
181
}
183
182
#endif
183
+
184
184
_mqttClient.onMessage (ArduinoIoTCloudTCP::onMessage);
185
185
_mqttClient.setKeepAliveInterval (30 * 1000 );
186
186
_mqttClient.setConnectionTimeout (1500 );
@@ -189,11 +189,8 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress,
189
189
_deviceTopicOut = getTopic_deviceout ();
190
190
_deviceTopicIn = getTopic_devicein ();
191
191
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 ();
192
+ _messageTopicOut = getTopic_messageout ();
193
+ _messageTopicIn = getTopic_messagein ();
197
194
198
195
_thing.begin ();
199
196
_device.begin ();
@@ -322,6 +319,7 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_ConnectMqttBroker()
322
319
{
323
320
if (_mqttClient.connect (_brokerAddress.c_str (), _brokerPort))
324
321
{
322
+ _mqttClient.subscribe (getTopic_messagein ());
325
323
DEBUG_VERBOSE (" ArduinoIoTCloudTCP::%s connected to %s:%d" , __FUNCTION__, _brokerAddress.c_str (), _brokerPort);
326
324
/* Reconfigure timers for next state */
327
325
_connection_attempt.begin (AIOT_CONFIG_DEVICE_TOPIC_SUBSCRIBE_RETRY_DELAY_ms, AIOT_CONFIG_MAX_DEVICE_TOPIC_SUBSCRIBE_RETRY_DELAY_ms);
@@ -465,19 +463,50 @@ void ArduinoIoTCloudTCP::handleMessage(int length)
465
463
466
464
/* Topic for user input data */
467
465
if (_dataTopicIn == topic) {
468
- CBORDecoder::decode (_thing .getPropertyContainer (), (uint8_t *)bytes, length);
466
+ CBORDecoder::decode (getThing () .getPropertyContainer (), (uint8_t *)bytes, length);
469
467
}
470
468
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);
469
+ /* Topic for device commands */
470
+ if (_messageTopicIn == topic) {
471
+ CommandDown command;
472
+ DEBUG_VERBOSE (" ArduinoIoTCloudTCP::%s [%d] received %d bytes" , __FUNCTION__, millis (), length);
473
+ CBORMessageDecoder decoder;
474
+
475
+ size_t buffer_length = length;
476
+ if (decoder.decode ((Message*)&command, bytes, buffer_length) != Decoder::Status::Error) {
477
+ DEBUG_VERBOSE (" ArduinoIoTCloudTCP::%s [%d] received command id %d" , __FUNCTION__, millis (), command.c .id );
478
+ switch (command.c .id )
479
+ {
480
+ case CommandId::ThingUpdateCmdId:
481
+ {
482
+ _thing_id = String (command.thingBeginCmd .params .thing_id );
483
+ DEBUG_VERBOSE (" ArduinoIoTCloudTCP::%s [%d] device configuration received" , __FUNCTION__, millis ());
484
+ _device.handleMessage ((Message*)&command);
485
+ }
486
+ break ;
487
+
488
+ case CommandId::LastValuesUpdateCmdId:
489
+ {
490
+ DEBUG_VERBOSE (" ArduinoIoTCloudTCP::%s [%d] last values received" , __FUNCTION__, millis ());
491
+ CBORDecoder::decode (getThing ().getPropertyContainer (),
492
+ (uint8_t *)command.lastValuesUpdateCmd .params .last_values ,
493
+ command.lastValuesUpdateCmd .params .length , true );
494
+ _thing.handleMessage ((Message*)&command);
495
+ execCloudEventCallback (ArduinoIoTCloudEvent::SYNC);
496
+
497
+ /*
498
+ * NOTE: in this current version properties are not properly integrated with the new paradigm of
499
+ * modeling the messages with C structs. The current CBOR library allocates an array in the heap
500
+ * thus we need to delete it after decoding it with the old CBORDecoder
501
+ */
502
+ free (msg->params .last_values );
503
+ }
504
+ break ;
505
+
506
+ default :
507
+ break ;
508
+ }
509
+ }
481
510
}
482
511
}
483
512
@@ -504,6 +533,17 @@ void ArduinoIoTCloudTCP::sendMessage(Message * msg)
504
533
default :
505
534
break ;
506
535
}
536
+
537
+ uint8_t data[MQTT_TRANSMIT_BUFFER_SIZE];
538
+ size_t bytes_encoded = sizeof (data);
539
+ CBORMessageEncoder encoder;
540
+
541
+ if (encoder.encode (msg, data, bytes_encoded) == Encoder::Status::Complete &&
542
+ bytes_encoded > 0 ) {
543
+ write (_messageTopicOut, data, bytes_encoded);
544
+ } else {
545
+ DEBUG_ERROR (" error encoding %d" , msg->id );
546
+ }
507
547
}
508
548
509
549
void ArduinoIoTCloudTCP::sendPropertyContainerToCloud (String const topic, PropertyContainer & property_container, unsigned int & current_property_index)
0 commit comments