diff --git a/src/ArduinoIoTCloudTCP.cpp b/src/ArduinoIoTCloudTCP.cpp index 26052548..cc74a324 100644 --- a/src/ArduinoIoTCloudTCP.cpp +++ b/src/ArduinoIoTCloudTCP.cpp @@ -59,12 +59,14 @@ ArduinoIoTCloudTCP::ArduinoIoTCloudTCP() #ifdef BOARD_HAS_SECRET_KEY , _password("") #endif +, _brokerTLSClient(nullptr) , _mqttClient{nullptr} , _messageTopicOut("") , _messageTopicIn("") , _dataTopicOut("") , _dataTopicIn("") #if OTA_ENABLED +, _otaTLSClient(nullptr) , _ota(&_message_stream) , _get_ota_confirmation{nullptr} #endif /* OTA_ENABLED */ @@ -79,34 +81,19 @@ ArduinoIoTCloudTCP::ArduinoIoTCloudTCP() int ArduinoIoTCloudTCP::begin(ConnectionHandler & connection, bool const enable_watchdog, String brokerAddress, uint16_t brokerPort) { _connection = &connection; - _brokerAddress = brokerAddress; -#ifdef BOARD_HAS_SECRET_KEY - _brokerPort = _password.length() ? DEFAULT_BROKER_PORT_USER_PASS_AUTH : brokerPort; -#else - _brokerPort = brokerPort; -#endif /* Setup broker TLS client */ - _brokerClient.begin(connection); + TLSClientBroker *brokerTLSClient = new TLSClientBroker(); + brokerTLSClient->begin(connection); -#if OTA_ENABLED +#if OTA_ENABLED /* Setup OTA TLS client */ - _otaClient.begin(connection); + TLSClientOta *otaTLSClient = new TLSClientOta(); + otaTLSClient->begin(connection); +#else + Client *otaTLSClient = nullptr; #endif - /* Setup TimeService */ - _time_service.begin(_connection); - - /* Setup retry timers */ - _connection_attempt.begin(AIOT_CONFIG_RECONNECTION_RETRY_DELAY_ms, AIOT_CONFIG_MAX_RECONNECTION_RETRY_DELAY_ms); - return begin(enable_watchdog, _brokerAddress, _brokerPort); -} - -int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress, uint16_t brokerPort) -{ - _brokerAddress = brokerAddress; - _brokerPort = brokerPort; - #if defined(BOARD_HAS_SECRET_KEY) /* If board is not configured for username and password login */ if(!_password.length()) @@ -135,9 +122,9 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress, DEBUG_ERROR("ArduinoIoTCloudTCP::%s could not read device certificate.", __FUNCTION__); return 0; } - _brokerClient.setEccSlot(static_cast(SElementArduinoCloudSlot::Key), _cert.bytes(), _cert.length()); + brokerTLSClient->setEccSlot(static_cast(SElementArduinoCloudSlot::Key), _cert.bytes(), _cert.length()); #if OTA_ENABLED - _otaClient.setEccSlot(static_cast(SElementArduinoCloudSlot::Key), _cert.bytes(), _cert.length()); + otaTLSClient->setEccSlot(static_cast(SElementArduinoCloudSlot::Key), _cert.bytes(), _cert.length()); #endif #endif #endif @@ -146,7 +133,80 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress, } #endif - _mqttClient.setClient(_brokerClient); + /* Setup TimeService */ + _time_service.begin(_connection); + + return begin(brokerTLSClient, otaTLSClient, enable_watchdog, brokerAddress, brokerPort); +} + +int ArduinoIoTCloudTCP::begin(Client * mqttClient, Client * otaClient, bool const enable_watchdog, String brokerAddress, uint16_t brokerPort) +{ + _brokerTLSClient = mqttClient; +#if OTA_ENABLED + _otaTLSClient = otaClient; +#endif + + /* Setup retry timers */ + _connection_attempt.begin(AIOT_CONFIG_RECONNECTION_RETRY_DELAY_ms, AIOT_CONFIG_MAX_RECONNECTION_RETRY_DELAY_ms); + return begin(enable_watchdog, brokerAddress, brokerPort); +} + +void ArduinoIoTCloudTCP::update() +{ + /* Feed the watchdog. If any of the functions called below + * get stuck than we can at least reset and recover. + */ +#if defined (ARDUINO_ARCH_SAMD) || defined (ARDUINO_ARCH_MBED) + watchdog_reset(); +#endif + + /* Run through the state machine. */ + State next_state = _state; + switch (_state) + { + case State::ConnectPhy: next_state = handle_ConnectPhy(); break; + case State::SyncTime: next_state = handle_SyncTime(); break; + case State::ConnectMqttBroker: next_state = handle_ConnectMqttBroker(); break; + case State::Connected: next_state = handle_Connected(); break; + case State::Disconnect: next_state = handle_Disconnect(); break; + } + _state = next_state; + + /* This watchdog feed is actually needed only by the RP2040 Connect because its + * maximum watchdog window is 8389 ms; despite this we feed it for all + * supported ARCH to keep code aligned. + */ +#if defined (ARDUINO_ARCH_SAMD) || defined (ARDUINO_ARCH_MBED) + watchdog_reset(); +#endif +} + +int ArduinoIoTCloudTCP::connected() +{ + return _mqttClient.connected(); +} + +void ArduinoIoTCloudTCP::printDebugInfo() +{ + DEBUG_INFO("***** Arduino IoT Cloud - configuration info *****"); + DEBUG_INFO("Device ID: %s", getDeviceId().c_str()); + DEBUG_INFO("MQTT Broker: %s:%d", _brokerAddress.c_str(), _brokerPort); +} + +/****************************************************************************** + * PRIVATE MEMBER FUNCTIONS + ******************************************************************************/ + +int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress, uint16_t brokerPort) +{ + _brokerAddress = brokerAddress; +#ifdef BOARD_HAS_SECRET_KEY + _brokerPort = _password.length() ? DEFAULT_BROKER_PORT_USER_PASS_AUTH : brokerPort; +#else + _brokerPort = brokerPort; +#endif + + _mqttClient.setClient(_brokerTLSClient); #ifdef BOARD_HAS_SECRET_KEY if(_password.length()) @@ -167,7 +227,7 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress, _device.begin(); #if OTA_ENABLED && !defined(OFFLOADED_DOWNLOAD) - _ota.setClient(&_otaClient); + _ota.setClient(_otaTLSClient); #endif // OTA_ENABLED && !defined(OFFLOADED_DOWNLOAD) #if OTA_ENABLED && defined(OTA_BASIC_AUTH) @@ -204,55 +264,9 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress, return 1; } -void ArduinoIoTCloudTCP::update() -{ - /* Feed the watchdog. If any of the functions called below - * get stuck than we can at least reset and recover. - */ -#if defined (ARDUINO_ARCH_SAMD) || defined (ARDUINO_ARCH_MBED) - watchdog_reset(); -#endif - - /* Run through the state machine. */ - State next_state = _state; - switch (_state) - { - case State::ConnectPhy: next_state = handle_ConnectPhy(); break; - case State::SyncTime: next_state = handle_SyncTime(); break; - case State::ConnectMqttBroker: next_state = handle_ConnectMqttBroker(); break; - case State::Connected: next_state = handle_Connected(); break; - case State::Disconnect: next_state = handle_Disconnect(); break; - } - _state = next_state; - - /* This watchdog feed is actually needed only by the RP2040 Connect because its - * maximum watchdog window is 8389 ms; despite this we feed it for all - * supported ARCH to keep code aligned. - */ -#if defined (ARDUINO_ARCH_SAMD) || defined (ARDUINO_ARCH_MBED) - watchdog_reset(); -#endif -} - -int ArduinoIoTCloudTCP::connected() -{ - return _mqttClient.connected(); -} - -void ArduinoIoTCloudTCP::printDebugInfo() -{ - DEBUG_INFO("***** Arduino IoT Cloud - configuration info *****"); - DEBUG_INFO("Device ID: %s", getDeviceId().c_str()); - DEBUG_INFO("MQTT Broker: %s:%d", _brokerAddress.c_str(), _brokerPort); -} - -/****************************************************************************** - * PRIVATE MEMBER FUNCTIONS - ******************************************************************************/ - ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_ConnectPhy() { - if (_connection->check() == NetworkConnectionState::CONNECTED) + if ((_connection == nullptr) || (_connection->check() == NetworkConnectionState::CONNECTED)) { if (!_connection_attempt.isRetry() || (_connection_attempt.isRetry() && _connection_attempt.isExpired())) return State::SyncTime; diff --git a/src/ArduinoIoTCloudTCP.h b/src/ArduinoIoTCloudTCP.h index 29dfc754..61dc9942 100644 --- a/src/ArduinoIoTCloudTCP.h +++ b/src/ArduinoIoTCloudTCP.h @@ -36,7 +36,7 @@ #endif #endif -#include +#include #include #if OTA_ENABLED @@ -75,7 +75,7 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass virtual void printDebugInfo() override; int begin(ConnectionHandler & connection, bool const enable_watchdog = true, String brokerAddress = DEFAULT_BROKER_ADDRESS_SECURE_AUTH, uint16_t brokerPort = DEFAULT_BROKER_PORT_SECURE_AUTH); - int begin(bool const enable_watchdog = true, String brokerAddress = DEFAULT_BROKER_ADDRESS_SECURE_AUTH, uint16_t brokerPort = DEFAULT_BROKER_PORT_SECURE_AUTH); + int begin(Client * mqttClient, Client * otaClient = nullptr, bool const enable_watchdog = true, String brokerAddress = DEFAULT_BROKER_ADDRESS_SECURE_AUTH, uint16_t brokerPort = DEFAULT_BROKER_PORT_SECURE_AUTH); #ifdef BOARD_HAS_SECRET_KEY inline void setBoardId (String const device_id) { setDeviceId(device_id); } @@ -104,6 +104,7 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass #endif private: + int begin(bool const enable_watchdog = true, String brokerAddress = DEFAULT_BROKER_ADDRESS_SECURE_AUTH, uint16_t brokerPort = DEFAULT_BROKER_PORT_SECURE_AUTH); static const int MQTT_TRANSMIT_BUFFER_SIZE = 256; enum class State @@ -138,7 +139,7 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass #endif #endif - TLSClientMqtt _brokerClient; + Client * _brokerTLSClient; MqttClient _mqttClient; String _messageTopicOut; @@ -148,7 +149,7 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass #if OTA_ENABLED - TLSClientOta _otaClient; + Client * _otaTLSClient; ArduinoCloudOTA _ota; onOTARequestCallbackFunc _get_ota_confirmation; #endif /* OTA_ENABLED */ diff --git a/src/tls/utility/TLSClientMqtt.cpp b/src/tls/utility/TLSClientBroker.cpp similarity index 88% rename from src/tls/utility/TLSClientMqtt.cpp rename to src/tls/utility/TLSClientBroker.cpp index 37461816..11231c94 100644 --- a/src/tls/utility/TLSClientMqtt.cpp +++ b/src/tls/utility/TLSClientBroker.cpp @@ -12,7 +12,7 @@ #ifdef HAS_TCP -#include "TLSClientMqtt.h" +#include "TLSClientBroker.h" #if defined(BOARD_HAS_SECRET_KEY) #include "tls/AIoTCUPCert.h" @@ -33,7 +33,7 @@ } #endif -void TLSClientMqtt::begin(ConnectionHandler & connection) { +void TLSClientBroker::begin(ConnectionHandler & connection) { #if defined(BOARD_HAS_OFFLOADED_ECCX08) /* Arduino Root CA is configured in nina-fw @@ -60,7 +60,11 @@ void TLSClientMqtt::begin(ConnectionHandler & connection) { */ (void)connection; #elif defined(ARDUINO_ARCH_ESP32) - setCACertBundle(x509_crt_bundle); + #if (ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 4)) + setCACertBundle(x509_crt_bundle, sizeof(x509_crt_bundle)); + #else + setCACertBundle(x509_crt_bundle); + #endif #elif defined(ARDUINO_ARCH_ESP8266) setInsecure(); #endif diff --git a/src/tls/utility/TLSClientMqtt.h b/src/tls/utility/TLSClientBroker.h similarity index 78% rename from src/tls/utility/TLSClientMqtt.h rename to src/tls/utility/TLSClientBroker.h index 837e76de..a8cadf01 100644 --- a/src/tls/utility/TLSClientMqtt.h +++ b/src/tls/utility/TLSClientBroker.h @@ -19,7 +19,7 @@ * Arduino NANO 33 IoT - WiFi */ #include "WiFiSSLClient.h" - class TLSClientMqtt : public WiFiBearSSLClient { + class TLSClientBroker : public WiFiBearSSLClient { #elif defined(BOARD_HAS_ECCX08) /* * Arduino MKR GSM 1400 @@ -29,38 +29,38 @@ * OPTA */ #include - class TLSClientMqtt : public BearSSLClient { + class TLSClientBroker : public BearSSLClient { #elif defined(ARDUINO_PORTENTA_C33) /* * Arduino Portenta C33 */ #include - class TLSClientMqtt : public SSLClient { + class TLSClientBroker : public SSLClient { #elif defined(ARDUINO_NICLA_VISION) /* * Arduino Nicla Vision */ #include - class TLSClientMqtt : public WiFiSSLSE050Client { + class TLSClientBroker : public WiFiSSLSE050Client { #elif defined(ARDUINO_EDGE_CONTROL) /* * Arduino Edge Control */ #include - class TLSClientMqtt : public GSMSSLClient { + class TLSClientBroker : public GSMSSLClient { #elif defined(ARDUINO_UNOR4_WIFI) /* * Arduino UNO R4 WiFi */ #include - class TLSClientMqtt : public WiFiSSLClient { + class TLSClientBroker : public WiFiSSLClient { #elif defined(BOARD_ESP) /* * ESP32* * ESP82* */ #include - class TLSClientMqtt : public WiFiClientSecure { + class TLSClientBroker : public WiFiClientSecure { #endif public: diff --git a/src/tls/utility/TLSClientOta.cpp b/src/tls/utility/TLSClientOta.cpp index 77096b6f..4e0d06d0 100644 --- a/src/tls/utility/TLSClientOta.cpp +++ b/src/tls/utility/TLSClientOta.cpp @@ -56,7 +56,11 @@ void TLSClientOta::begin(ConnectionHandler &connection) { */ (void)connection; #elif defined(ARDUINO_ARCH_ESP32) - setCACertBundle(x509_crt_bundle); + #if (ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 4)) + setCACertBundle(x509_crt_bundle, sizeof(x509_crt_bundle)); + #else + setCACertBundle(x509_crt_bundle); + #endif #elif defined(ARDUINO_ARCH_ESP8266) setInsecure(); #endif