diff --git a/src/ArduinoIoTCloudTCP.cpp b/src/ArduinoIoTCloudTCP.cpp
index 260525484..cc74a3243 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<int>(SElementArduinoCloudSlot::Key), _cert.bytes(), _cert.length());
+    brokerTLSClient->setEccSlot(static_cast<int>(SElementArduinoCloudSlot::Key), _cert.bytes(), _cert.length());
     #if  OTA_ENABLED
-    _otaClient.setEccSlot(static_cast<int>(SElementArduinoCloudSlot::Key), _cert.bytes(), _cert.length());
+    otaTLSClient->setEccSlot(static_cast<int>(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 29dfc7543..61dc9942f 100644
--- a/src/ArduinoIoTCloudTCP.h
+++ b/src/ArduinoIoTCloudTCP.h
@@ -36,7 +36,7 @@
   #endif
 #endif
 
-#include <tls/utility/TLSClientMqtt.h>
+#include <tls/utility/TLSClientBroker.h>
 #include <tls/utility/TLSClientOta.h>
 
 #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 374618163..11231c946 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 837e76dec..a8cadf011 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 <tls/BearSSLClient.h>
-  class TLSClientMqtt : public BearSSLClient {
+  class TLSClientBroker : public BearSSLClient {
 #elif defined(ARDUINO_PORTENTA_C33)
   /*
    * Arduino Portenta C33
    */
   #include <SSLClient.h>
-  class TLSClientMqtt : public SSLClient {
+  class TLSClientBroker : public SSLClient {
 #elif defined(ARDUINO_NICLA_VISION)
   /*
    * Arduino Nicla Vision
    */
   #include <WiFiSSLSE050Client.h>
-  class TLSClientMqtt : public WiFiSSLSE050Client {
+  class TLSClientBroker : public WiFiSSLSE050Client {
 #elif defined(ARDUINO_EDGE_CONTROL)
   /*
    * Arduino Edge Control
    */
   #include <GSMSSLClient.h>
-  class TLSClientMqtt : public GSMSSLClient {
+  class TLSClientBroker : public GSMSSLClient {
 #elif defined(ARDUINO_UNOR4_WIFI)
   /*
    * Arduino UNO R4 WiFi
    */
   #include <WiFiSSLClient.h>
-  class TLSClientMqtt : public WiFiSSLClient {
+  class TLSClientBroker : public WiFiSSLClient {
 #elif defined(BOARD_ESP)
   /*
    * ESP32*
    * ESP82*
    */
   #include <WiFiClientSecure.h>
-  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 77096b6f2..4e0d06d09 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