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,12 +75,6 @@ ArduinoIoTCloudTCP::ArduinoIoTCloudTCP()
74
75
, _password(" " )
75
76
#endif
76
77
, _mqttClient{nullptr }
77
- , _deviceTopicOut(" " )
78
- , _deviceTopicIn(" " )
79
- , _shadowTopicOut(" " )
80
- , _shadowTopicIn(" " )
81
- , _dataTopicOut(" " )
82
- , _dataTopicIn(" " )
83
78
#if OTA_ENABLED
84
79
, _ota_cap{false }
85
80
, _ota_error{static_cast <int >(OTAError::None)}
@@ -181,24 +176,21 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress,
181
176
_mqttClient.setUsernamePassword (getDeviceId (), _password);
182
177
}
183
178
#endif
179
+
184
180
_mqttClient.onMessage (ArduinoIoTCloudTCP::onMessage);
185
181
_mqttClient.setKeepAliveInterval (30 * 1000 );
186
182
_mqttClient.setConnectionTimeout (1500 );
187
183
_mqttClient.setId (getDeviceId ().c_str ());
188
184
189
- _deviceTopicOut = getTopic_deviceout ();
190
- _deviceTopicIn = getTopic_devicein ();
185
+ getTopic_devicein () = getTopic_devicein ();
191
186
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 ();
197
188
198
189
_thing.begin ();
199
190
_device.begin ();
200
191
201
192
#if OTA_ENABLED
193
+ Property* p;
202
194
p = new CloudWrapperBool (_ota_cap);
203
195
addPropertyToContainer (_device.getPropertyContainer (), *p, " OTA_CAP" , Permission::Read, -1 );
204
196
p = new CloudWrapperInt (_ota_error);
@@ -322,6 +314,7 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_ConnectMqttBroker()
322
314
{
323
315
if (_mqttClient.connect (_brokerAddress.c_str (), _brokerPort))
324
316
{
317
+ _mqttClient.subscribe (getTopic_messagein ());
325
318
DEBUG_VERBOSE (" ArduinoIoTCloudTCP::%s connected to %s:%d" , __FUNCTION__, _brokerAddress.c_str (), _brokerPort);
326
319
/* Reconfigure timers for next state */
327
320
_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)
437
430
}
438
431
439
432
/* Topic for OTA properties and device configuration */
440
- if (_deviceTopicIn == topic) {
433
+ if (getTopic_devicein () == topic) {
441
434
CBORDecoder::decode (_device.getPropertyContainer (), (uint8_t *)bytes, length);
442
435
443
436
/* Temporary check to avoid flooding device state machine with usless messages */
@@ -468,16 +461,47 @@ void ArduinoIoTCloudTCP::handleMessage(int length)
468
461
CBORDecoder::decode (_thing.getPropertyContainer (), (uint8_t *)bytes, length);
469
462
}
470
463
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
+ }
481
505
}
482
506
}
483
507
@@ -504,6 +528,17 @@ void ArduinoIoTCloudTCP::sendMessage(Message * msg)
504
528
default :
505
529
break ;
506
530
}
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
+ }
507
542
}
508
543
509
544
void ArduinoIoTCloudTCP::sendPropertyContainerToCloud (String const topic, PropertyContainer & property_container, unsigned int & current_property_index)
@@ -546,7 +581,7 @@ void ArduinoIoTCloudTCP::sendDevicePropertiesToCloud()
546
581
addPropertyToContainer (ro_device_property_container, *p, p->name (), p->isWriteableByCloud () ? Permission::ReadWrite : Permission::Read);
547
582
}
548
583
);
549
- sendPropertyContainerToCloud (_deviceTopicOut , ro_device_property_container, last_device_property_index);
584
+ sendPropertyContainerToCloud (getTopic_deviceout () , ro_device_property_container, last_device_property_index);
550
585
}
551
586
552
587
#if OTA_ENABLED
@@ -559,7 +594,7 @@ void ArduinoIoTCloudTCP::sendDevicePropertyToCloud(String const name)
559
594
if (p != nullptr )
560
595
{
561
596
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);
563
598
}
564
599
}
565
600
#endif
@@ -575,12 +610,12 @@ void ArduinoIoTCloudTCP::requestLastValue()
575
610
576
611
void ArduinoIoTCloudTCP::requestThingId ()
577
612
{
578
- if (!_mqttClient.subscribe (_deviceTopicIn ))
613
+ if (!_mqttClient.subscribe (getTopic_devicein () ))
579
614
{
580
615
/* If device_id is wrong the board can't connect to the broker so this condition
581
616
* should never happen.
582
617
*/
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 ());
584
619
}
585
620
}
586
621
0 commit comments