@@ -60,13 +60,10 @@ unsigned long getTime()
6060ArduinoIoTCloudTCP::ArduinoIoTCloudTCP ()
6161: _state{State::ConnectPhy}
6262, _connection_attempt(0 ,0 )
63+ , _message_stream(std::bind(&ArduinoIoTCloudTCP::sendMessage, this , std::placeholders::_1))
64+ , _thing(&_message_stream)
65+ , _thing_id_property{nullptr }
6366, _device_property_container{0 }
64- , _thing_property_container{0 }
65- , _last_checked_property_index{0 }
66- , _tz_offset{0 }
67- , _tz_offset_property{nullptr }
68- , _tz_dst_until{0 }
69- , _tz_dst_until_property{nullptr }
7067, _mqtt_data_buf{0 }
7168, _mqtt_data_len{0 }
7269, _mqtt_data_request_retransmit{false }
@@ -214,10 +211,8 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress,
214211#endif /* OTA_ENABLED */
215212 p = new CloudWrapperString (_thing_id);
216213 _thing_id_property = &addPropertyToContainer (_device_property_container, *p, " thing_id" , Permission::ReadWrite, -1 ).writeOnDemand ();
217- p = new CloudWrapperInt (_tz_offset);
218- _tz_offset_property = &addPropertyToContainer (_thing_property_container, *p, " tz_offset" , Permission::ReadWrite, -1 ).writeOnDemand ();
219- p = new CloudWrapperUnsignedInt (_tz_dst_until);
220- _tz_dst_until_property = &addPropertyToContainer (_thing_property_container, *p, " tz_dst_until" , Permission::ReadWrite, -1 ).writeOnDemand ();
214+
215+ _thing.begin ();
221216
222217#if OTA_ENABLED
223218 _ota_cap = OTA::isCapable ();
@@ -274,7 +269,6 @@ void ArduinoIoTCloudTCP::update()
274269 case State::SubscribeDeviceTopic: next_state = handle_SubscribeDeviceTopic (); break ;
275270 case State::CheckDeviceConfig: next_state = handle_CheckDeviceConfig (); break ;
276271 case State::SubscribeThingTopics: next_state = handle_SubscribeThingTopics (); break ;
277- case State::RequestLastValues: next_state = handle_RequestLastValues (); break ;
278272 case State::Connected: next_state = handle_Connected (); break ;
279273 case State::Disconnect: next_state = handle_Disconnect (); break ;
280274 }
@@ -328,12 +322,13 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_ConnectPhy()
328322
329323ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_SyncTime ()
330324{
331- #pragma GCC diagnostic push
332- #pragma GCC diagnostic ignored "-Wunused-variable"
333- unsigned long const internal_posix_time = _time_service.getTime ();
334- #pragma GCC diagnostic pop
335- DEBUG_VERBOSE (" ArduinoIoTCloudTCP::%s internal clock configured to posix timestamp %d" , __FUNCTION__, internal_posix_time);
336- return State::ConnectMqttBroker;
325+ if (TimeServiceClass::isTimeValid (getTime ()))
326+ {
327+ DEBUG_VERBOSE (" ArduinoIoTCloudTCP::%s internal clock configured to posix timestamp %d" , __FUNCTION__, getTime ());
328+ return State::ConnectMqttBroker;
329+ }
330+
331+ return State::ConnectPhy;
337332}
338333
339334ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_ConnectMqttBroker ()
@@ -477,38 +472,12 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_SubscribeThingTopics()
477472
478473 /* Successfully subscribed to thing topics, reconfigure timers for next state and go on */
479474 _connection_attempt.begin (AIOT_CONFIG_TIMEOUT_FOR_LASTVALUES_SYNC_ms);
480- return State::RequestLastValues;
481- }
482-
483- ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_RequestLastValues ()
484- {
485- if (!_mqttClient.connected () || _thing_id_property->isDifferentFromCloud ())
486- {
487- return State::Disconnect;
488- }
489-
490- /* Check whether or not we need to send a new request. */
491- if (_connection_attempt.isRetry () && !_connection_attempt.isExpired ())
492- return State::RequestLastValues;
493-
494- /* Track the number of times a get-last-values request was sent to the cloud.
495- * If no data is received within a certain number of retry-requests it's a better
496- * strategy to disconnect and re-establish connection from the ground up.
497- */
498- if (_connection_attempt.getRetryCount () > AIOT_CONFIG_LASTVALUES_SYNC_MAX_RETRY_CNT)
499- {
500- return State::Disconnect;
501- }
502-
503- _connection_attempt.retry ();
504- requestLastValue ();
505- DEBUG_VERBOSE (" ArduinoIoTCloudTCP::%s [%d] last values requested" , __FUNCTION__, _time_service.getTime ());
506- return State::RequestLastValues;
475+ return State::Connected;
507476}
508477
509478ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_Connected ()
510479{
511- if (!_mqttClient.connected ())
480+ if (!_mqttClient.connected () || _thing_id_property-> isDifferentFromCloud () || !_thing. connected () )
512481 {
513482 /* The last message was definitely lost, trigger a retransmit. */
514483 _mqtt_data_request_retransmit = true ;
@@ -517,20 +486,6 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_Connected()
517486 /* We are connected so let's to our stuff here. */
518487 else
519488 {
520- if (_thing_id_property->isDifferentFromCloud ())
521- {
522- return State::Disconnect;
523- }
524-
525- /* Check if a primitive property wrapper is locally changed.
526- * This function requires an existing time service which in
527- * turn requires an established connection. Not having that
528- * leads to a wrong time set in the time service which inhibits
529- * the connection from being established due to a wrong data
530- * in the reconstructed certificate.
531- */
532- updateTimestampOnLocallyChangedProperties (_thing_property_container);
533-
534489 /* Retransmit data in case there was a lost transaction due
535490 * to phy layer or MQTT connectivity loss.
536491 */
@@ -539,27 +494,11 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_Connected()
539494 _mqtt_data_request_retransmit = false ;
540495 }
541496
542- /* Configure Time service with timezone data:
543- * _tz_offset [offset + dst]
544- * _tz_dst_until [posix timestamp until _tz_offset is valid]
545- */
546- if (_tz_offset_property->isDifferentFromCloud () || _tz_dst_until_property->isDifferentFromCloud ()) {
547- _tz_offset_property->fromCloudToLocal ();
548- _tz_dst_until_property->fromCloudToLocal ();
549- _time_service.setTimeZoneData (_tz_offset, _tz_dst_until);
550- }
497+ /* Call CloudThing process to synchronize properties */
498+ _thing.update ();
551499
552- /* Check if any properties need encoding and send them to
553- * the cloud if necessary.
554- */
555- sendThingPropertiesToCloud ();
500+ return State::Connected;
556501
557- unsigned long const internal_posix_time = _time_service.getTime ();
558- if (internal_posix_time < _tz_dst_until) {
559- return State::Connected;
560- } else {
561- return State::RequestLastValues;
562- }
563502 }
564503}
565504
@@ -604,9 +543,15 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_Disconnect()
604543 /* TODO add device topic */
605544 _mqttClient.stop ();
606545 }
546+
547+ Message message = { ResetCmdId };
548+ _thing.handleMessage (&message);
549+
607550 DEBUG_INFO (" Disconnected from Arduino IoT Cloud" );
608551 execCloudEventCallback (ArduinoIoTCloudEvent::DISCONNECT);
609552
553+ updateThingTopics ();
554+
610555 /* Setup timer for broker connection and restart */
611556 _connection_attempt.begin (AIOT_CONFIG_RECONNECTION_RETRY_DELAY_ms, AIOT_CONFIG_MAX_RECONNECTION_RETRY_DELAY_ms);
612557 return State::ConnectPhy;
@@ -630,25 +575,47 @@ void ArduinoIoTCloudTCP::handleMessage(int length)
630575 /* Topic for OTA properties and device configuration */
631576 if (_deviceTopicIn == topic) {
632577 CBORDecoder::decode (_device_property_container, (uint8_t *)bytes, length);
633- _state = State::CheckDeviceConfig;
578+ if (_thing_id_property->isDifferentFromCloud () && (_thing_id.length () != 0 )) {
579+ _state = State::Disconnect;
580+ } else {
581+ _state = State::CheckDeviceConfig;
582+ }
634583 }
635584
636585 /* Topic for user input data */
637586 if (_dataTopicIn == topic) {
638- CBORDecoder::decode (_thing_property_container , (uint8_t *)bytes, length);
587+ CBORDecoder::decode (_thing. getPropertyContainer () , (uint8_t *)bytes, length);
639588 }
640589
641590 /* Topic for sync Thing last values on connect */
642- if (( _shadowTopicIn == topic) && (_state == State::RequestLastValues) )
591+ if (_shadowTopicIn == topic)
643592 {
644593 DEBUG_VERBOSE (" ArduinoIoTCloudTCP::%s [%d] last values received" , __FUNCTION__, millis ());
645- CBORDecoder::decode (_thing_property_container, (uint8_t *)bytes, length, true );
646- _time_service.setTimeZoneData (_tz_offset, _tz_dst_until);
594+ CBORDecoder::decode (_thing.getPropertyContainer (), (uint8_t *)bytes, length, true );
595+ Message message = { LastValuesUpdateCmdId };
596+ _thing.handleMessage (&message);
647597 execCloudEventCallback (ArduinoIoTCloudEvent::SYNC);
648598 _state = State::Connected;
649599 }
650600}
651601
602+ void ArduinoIoTCloudTCP::sendMessage (Message * msg)
603+ {
604+ switch (msg->id )
605+ {
606+ case PropertiesUpdateCmdId:
607+ sendThingPropertiesToCloud ();
608+ break ;
609+
610+ case LastValuesBeginCmdId:
611+ requestLastValue ();
612+ break ;
613+
614+ default :
615+ break ;
616+ }
617+ }
618+
652619void ArduinoIoTCloudTCP::sendPropertyContainerToCloud (String const topic, PropertyContainer & property_container, unsigned int & current_property_index)
653620{
654621 int bytes_encoded = 0 ;
@@ -669,7 +636,7 @@ void ArduinoIoTCloudTCP::sendPropertyContainerToCloud(String const topic, Proper
669636
670637void ArduinoIoTCloudTCP::sendThingPropertiesToCloud ()
671638{
672- sendPropertyContainerToCloud (_dataTopicOut, _thing_property_container, _last_checked_property_index );
639+ sendPropertyContainerToCloud (_dataTopicOut, _thing. getPropertyContainer (), _thing. getPropertyContainerIndex () );
673640}
674641
675642void ArduinoIoTCloudTCP::sendDevicePropertiesToCloud ()
0 commit comments