@@ -74,7 +74,8 @@ extern "C" unsigned long getTime()
7474 ******************************************************************************/
7575
7676ArduinoIoTCloudTCP::ArduinoIoTCloudTCP ()
77- : _lastSyncRequestTickTime{0 }
77+ : _state{State::ConnectMqttBroker}
78+ , _lastSyncRequestTickTime{0 }
7879, _mqtt_data_buf{0 }
7980, _mqtt_data_len{0 }
8081, _mqtt_data_request_retransmit{false }
@@ -186,7 +187,18 @@ void ArduinoIoTCloudTCP::update()
186187#endif /* OTA_ENABLED */
187188
188189 if (checkPhyConnection () != NetworkConnectionState::CONNECTED) return ;
189- if (checkCloudConnection () != ArduinoIoTConnectionStatus::CONNECTED) return ;
190+
191+ State next_state = _state;
192+ switch (_state)
193+ {
194+ case State::ConnectMqttBroker: next_state = handle_ConnectMqttBroker (); break ;
195+ case State::SubscribeMqttTopics: next_state = handle_SubscribeMqttTopics (); break ;
196+ case State::Connected: next_state = handle_Connected (); break ;
197+ }
198+ _state = next_state;
199+
200+ /* For now exit here if we are not connected. */
201+ if (_state != State::Connected) return ;
190202
191203 /* Check if a primitive property wrapper is locally changed.
192204 * This function requires an existing time service which in
@@ -250,44 +262,71 @@ void ArduinoIoTCloudTCP::setOTAStorage(OTAStorage & ota_storage)
250262}
251263#endif /* OTA_ENABLED */
252264
253- int ArduinoIoTCloudTCP::reconnect ()
254- {
255- if (_mqttClient.connected ()) {
256- _mqttClient.stop ();
257- }
258- return connect ();
259- }
260-
261265/* *****************************************************************************
262- * PROTECTED MEMBER FUNCTIONS
266+ * PRIVATE MEMBER FUNCTIONS
263267 ******************************************************************************/
264268
265- int ArduinoIoTCloudTCP::connect ()
269+ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_ConnectMqttBroker ()
266270{
267- if (!_mqttClient.connect (_brokerAddress.c_str (), _brokerPort)) return CONNECT_FAILURE;
268- if (_mqttClient.subscribe (_stdinTopic) == 0 ) return CONNECT_FAILURE_SUBSCRIBE;
269- if (_mqttClient.subscribe (_dataTopicIn) == 0 ) return CONNECT_FAILURE_SUBSCRIBE;
270- if (_mqttClient.subscribe (_ota_topic_in) == 0 ) return CONNECT_FAILURE_SUBSCRIBE;
271+ if (_mqttClient.connect (_brokerAddress.c_str (), _brokerPort))
272+ return State::SubscribeMqttTopics;
273+
274+ DBG_ERROR (" ArduinoIoTCloudTCP::%s could not connect to %s:%d" , __FUNCTION__, _brokerAddress.c_str (), _brokerPort);
275+ return State::ConnectMqttBroker;
276+ }
277+
278+ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_SubscribeMqttTopics ()
279+ {
280+ if (!_mqttClient.subscribe (_stdinTopic))
281+ {
282+ DBG_ERROR (" ArduinoIoTCloudTCP::%s could not subscribe to %s" , __FUNCTION__, _stdinTopic.c_str ());
283+ return State::SubscribeMqttTopics;
284+ }
285+
286+ if (!_mqttClient.subscribe (_dataTopicIn))
287+ {
288+ DBG_ERROR (" ArduinoIoTCloudTCP::%s could not subscribe to %s" , __FUNCTION__, _dataTopicIn.c_str ());
289+ return State::SubscribeMqttTopics;
290+ }
291+
292+ if (!_mqttClient.subscribe (_ota_topic_in))
293+ {
294+ DBG_ERROR (" ArduinoIoTCloudTCP::%s could not subscribe to %s" , __FUNCTION__, _ota_topic_in.c_str ());
295+ return State::SubscribeMqttTopics;
296+ }
271297
272298 if (_shadowTopicIn != " " )
273299 {
274- if (_mqttClient.subscribe (_shadowTopicIn) == 0 ) return CONNECT_FAILURE_SUBSCRIBE;
300+ if (!_mqttClient.subscribe (_shadowTopicIn))
301+ {
302+ DBG_ERROR (" ArduinoIoTCloudTCP::%s could not subscribe to %s" , __FUNCTION__, _ota_topic_in.c_str ());
303+ return State::SubscribeMqttTopics;
304+ }
275305 _syncStatus = ArduinoIoTSynchronizationStatus::SYNC_STATUS_WAIT_FOR_CLOUD_VALUES;
276306 _lastSyncRequestTickTime = 0 ;
277307 }
278308
279- return CONNECT_SUCCESS;
309+ DBG_VERBOSE (" Connected to Arduino IoT Cloud" );
310+ execCloudEventCallback (ArduinoIoTCloudEvent::CONNECT);
311+ return State::Connected;
280312}
281313
282- void ArduinoIoTCloudTCP::disconnect ()
314+ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_Connected ()
283315{
316+ if (_mqttClient.connected ())
317+ return State::Connected;
318+
319+ /* The last message was definitely lost, trigger a retransmit. */
320+ _mqtt_data_request_retransmit = true ;
321+
322+ /* We are not connected anymore, trigger the callback for a disconnected event. */
323+ execCloudEventCallback (ArduinoIoTCloudEvent::DISCONNECT);
324+
325+ /* Forcefully disconnect MQTT client and trigger a reconnection. */
284326 _mqttClient.stop ();
327+ return State::ConnectMqttBroker;
285328}
286329
287- /* *****************************************************************************
288- * PRIVATE MEMBER FUNCTIONS
289- ******************************************************************************/
290-
291330void ArduinoIoTCloudTCP::onMessage (int length)
292331{
293332 ArduinoCloud.handleMessage (length);
@@ -345,62 +384,6 @@ void ArduinoIoTCloudTCP::requestLastValue()
345384 write (_shadowTopicOut, CBOR_REQUEST_LAST_VALUE_MSG, sizeof (CBOR_REQUEST_LAST_VALUE_MSG));
346385}
347386
348- ArduinoIoTConnectionStatus ArduinoIoTCloudTCP::checkCloudConnection ()
349- {
350- ArduinoIoTConnectionStatus next_iot_status = _iot_status;
351-
352- switch (_iot_status)
353- {
354- case ArduinoIoTConnectionStatus::IDLE: next_iot_status = ArduinoIoTConnectionStatus::CONNECTING; break ;
355- case ArduinoIoTConnectionStatus::ERROR: next_iot_status = ArduinoIoTConnectionStatus::RECONNECTING; break ;
356- case ArduinoIoTConnectionStatus::DISCONNECTED: next_iot_status = ArduinoIoTConnectionStatus::RECONNECTING; break ;
357- case ArduinoIoTConnectionStatus::CONNECTING:
358- {
359- DBG_INFO (" Arduino IoT Cloud connecting ..." );
360- int const ret = connect ();
361- if (ret == CONNECT_SUCCESS)
362- {
363- next_iot_status = ArduinoIoTConnectionStatus::CONNECTED;
364- }
365- else if (ret == CONNECT_FAILURE_SUBSCRIBE)
366- {
367- DBG_ERROR (" ERROR - Please verify your THING ID" );
368- }
369- }
370- break ;
371-
372- case ArduinoIoTConnectionStatus::RECONNECTING:
373- {
374- DBG_INFO (" Arduino IoT Cloud reconnecting ..." );
375- if (reconnect () == CONNECT_SUCCESS)
376- {
377- next_iot_status = ArduinoIoTConnectionStatus::CONNECTED;
378- }
379- }
380- break ;
381-
382- case ArduinoIoTConnectionStatus::CONNECTED:
383- {
384- if (!_mqttClient.connected ())
385- {
386- next_iot_status = ArduinoIoTConnectionStatus::DISCONNECTED;
387- _mqtt_data_request_retransmit = true ;
388- }
389- }
390- break ;
391- }
392-
393- if (next_iot_status != _iot_status)
394- {
395- printConnectionStatus (next_iot_status);
396- if (next_iot_status == ArduinoIoTConnectionStatus::DISCONNECTED) execCloudEventCallback (ArduinoIoTCloudEvent::DISCONNECT);
397- else if (next_iot_status == ArduinoIoTConnectionStatus::CONNECTED) execCloudEventCallback (ArduinoIoTCloudEvent::CONNECT);
398- _iot_status = next_iot_status;
399- }
400-
401- return _iot_status;
402- }
403-
404387int ArduinoIoTCloudTCP::write (String const topic, byte const data[], int const length)
405388{
406389 if (_mqttClient.beginMessage (topic, length, false , 0 )) {
0 commit comments