From 760489954a34484f89915435797b442a8d459b8b Mon Sep 17 00:00:00 2001
From: fabik111 <fabiomassimo.centonze@gmail.com>
Date: Thu, 13 Feb 2025 16:16:10 +0100
Subject: [PATCH 01/14] use network configurator in iotCloud

update test ci

update example of sketch that uses the NetworkConfigurator

use NetworkConfigurator wrappers for agentsManager
---
 .github/workflows/compile-examples.yml        |  19 ++-
 .../ArduinoIoTCloud-NetConfig.ino             |  62 ++++++++
 .../thingProperties.h                         |  47 ++++++
 src/AIoTC_Config.h                            |   8 +
 src/ArduinoIoTCloud.cpp                       |   3 +
 src/ArduinoIoTCloud.h                         |   9 ++
 src/ArduinoIoTCloudTCP.cpp                    | 138 +++++++++++++-----
 src/ArduinoIoTCloudTCP.h                      |   8 +
 8 files changed, 256 insertions(+), 38 deletions(-)
 create mode 100644 examples/ArduinoIoTCloud-NetConfig/ArduinoIoTCloud-NetConfig.ino
 create mode 100644 examples/ArduinoIoTCloud-NetConfig/thingProperties.h

diff --git a/.github/workflows/compile-examples.yml b/.github/workflows/compile-examples.yml
index 5eb4f66d9..94681d24b 100644
--- a/.github/workflows/compile-examples.yml
+++ b/.github/workflows/compile-examples.yml
@@ -21,12 +21,19 @@ jobs:
       UNIVERSAL_LIBRARIES: |
         # Install the ArduinoIoTCloud library from the repository
         - source-path: ./
-        - name: Arduino_ConnectionHandler
+        - source-url: https://github.com/andreagilardoni/Arduino_ConnectionHandler.git
+          version: 0ca6d61eb538c5a21983e582ee1c8794442f8c75
+        - source-url: https://github.com/fabik111/ArduinoBLE.git
+          version: 82e2a28f871e97b313846cee6d9efed8943dca53
         - name: ArduinoHttpClient
         - name: Arduino_DebugUtils
         - name: ArduinoMqttClient
         - name: Arduino_SecureElement
         - name: Arduino_CloudUtils
+        - source-url: https://github.com/andreagilardoni/ArduinoStorage.git
+          version: 39f0bd138103967aaafcaa7f5c0e1e237b4ccb4d
+        - source-url: https://github.com/bcmi-labs/arduino-network-configurator.git
+          version: 962ab36dfb00eb9cebe089907223e576f463519f
       # sketch paths to compile (recursive) for all boards
       UNIVERSAL_SKETCH_PATHS: |
         - examples/ArduinoIoTCloud-Advanced
@@ -127,10 +134,12 @@ jobs:
               - name: ArduinoECCX08
               - name: Blues Wireless Notecard
               - name: RTCZero
-              - name: WiFiNINA
+              - source-url: https://github.com/andreagilardoni/WiFiNINA.git
+                version: ca7a9224f86b9aaf00de4f7feccea583a23b3d53
               - name: Arduino_JSON
               - source-url: https://github.com/adafruit/Adafruit_SleepyDog.git
             sketch-paths: |
+              - examples/ArduinoIoTCloud-NetConfig
               - examples/ArduinoIoTCloud-DeferredOTA
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
@@ -195,6 +204,7 @@ jobs:
               - name: Arduino_Cellular
               - name: Blues Wireless Notecard
             sketch-paths: |
+              - examples/ArduinoIoTCloud-NetConfig
               - examples/ArduinoIoTCloud-DeferredOTA
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
@@ -208,6 +218,7 @@ jobs:
             libraries: |
               - name: Blues Wireless Notecard
             sketch-paths: |
+              - examples/ArduinoIoTCloud-NetConfig
               - examples/ArduinoIoTCloud-DeferredOTA
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
@@ -223,6 +234,7 @@ jobs:
               - name: ArduinoECCX08
               - name: Blues Wireless Notecard
             sketch-paths: |
+              - examples/ArduinoIoTCloud-NetConfig
               - examples/ArduinoIoTCloud-DeferredOTA
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
@@ -238,6 +250,7 @@ jobs:
               - name: ArduinoECCX08
               - name: Blues Wireless Notecard
             sketch-paths: |
+              - examples/ArduinoIoTCloud-NetConfig
               - examples/ArduinoIoTCloud-DeferredOTA
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
@@ -252,6 +265,7 @@ jobs:
               - name: Arduino_Cellular
               - name: Blues Wireless Notecard
             sketch-paths: |
+              - examples/ArduinoIoTCloud-NetConfig
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
               - examples/utility/Provisioning
@@ -264,6 +278,7 @@ jobs:
             libraries: |
               - name: Blues Wireless Notecard
             sketch-paths: |
+              - examples/ArduinoIoTCloud-NetConfig
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
           # Nano ESP32
diff --git a/examples/ArduinoIoTCloud-NetConfig/ArduinoIoTCloud-NetConfig.ino b/examples/ArduinoIoTCloud-NetConfig/ArduinoIoTCloud-NetConfig.ino
new file mode 100644
index 000000000..238b59f55
--- /dev/null
+++ b/examples/ArduinoIoTCloud-NetConfig/ArduinoIoTCloud-NetConfig.ino
@@ -0,0 +1,62 @@
+/*
+  This sketch demonstrates how to exchange data between your board and the Arduino IoT Cloud.
+
+  * Connect a potentiometer (or other analog sensor) to A0.
+  * When the potentiometer (or sensor) value changes the data is sent to the Cloud.
+  * When you flip the switch in the Cloud dashboard the onboard LED lights gets turned ON or OFF.
+
+  IMPORTANT:
+  This sketch works with WiFi, GSM, NB, Ethernet and Lora enabled boards supported by Arduino IoT Cloud.
+  On a LoRa board, if it is configured as a class A device (default and preferred option),
+  values from Cloud dashboard are received only after a value is sent to Cloud.
+
+  The full list of compatible boards can be found here:
+   - https://github.com/arduino-libraries/ArduinoIoTCloud#what
+*/
+
+#include "thingProperties.h"
+
+#if !defined(LED_BUILTIN) && !defined(ARDUINO_NANO_ESP32)
+static int const LED_BUILTIN = 2;
+#endif
+
+void setup() {
+  /* Initialize serial and wait up to 5 seconds for port to open */
+  Serial.begin(9600);
+  for(unsigned long const serialBeginTime = millis(); !Serial && (millis() - serialBeginTime <= 5000); ) { }
+
+  /* Set the debug message level:
+   * - DBG_ERROR: Only show error messages
+   * - DBG_WARNING: Show warning and error messages
+   * - DBG_INFO: Show info, warning, and error messages
+   * - DBG_DEBUG: Show debug, info, warning, and error messages
+   * - DBG_VERBOSE: Show all messages
+   */
+  setDebugMessageLevel(DBG_INFO);
+
+  /* Configure LED pin as an output */
+  pinMode(LED_BUILTIN, OUTPUT);
+
+  /* This function takes care of connecting your sketch variables to the ArduinoIoTCloud object */
+  initProperties();
+
+  /* Initialize Arduino IoT Cloud library */
+  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
+
+  ArduinoCloud.printDebugInfo();
+}
+
+void loop() {
+  ArduinoCloud.update();
+  potentiometer = analogRead(A0);
+  seconds = millis() / 1000;
+}
+
+/*
+ * 'onLedChange' is called when the "led" property of your Thing changes
+ */
+void onLedChange() {
+  Serial.print("LED set to ");
+  Serial.println(led);
+  digitalWrite(LED_BUILTIN, led);
+}
diff --git a/examples/ArduinoIoTCloud-NetConfig/thingProperties.h b/examples/ArduinoIoTCloud-NetConfig/thingProperties.h
new file mode 100644
index 000000000..833927042
--- /dev/null
+++ b/examples/ArduinoIoTCloud-NetConfig/thingProperties.h
@@ -0,0 +1,47 @@
+#if !defined(ARDUINO_SAMD_MKRWIFI1010) && !defined(ARDUINO_SAMD_NANO_33_IOT) &&  !defined(ARDUINO_NANO_RP2040_CONNECT) \
+  && !defined(ARDUINO_PORTENTA_H7_M7) && !defined(ARDUINO_NICLA_VISION) && !defined(ARDUINO_OPTA) && !defined(ARDUINO_GIGA) \
+  && !defined(ARDUINO_UNOR4_WIFI) && !defined(ARDUINO_PORTENTA_C33)
+#error "This example is not compatible with this board."
+#endif
+#include <ArduinoIoTCloud.h>
+#include <Arduino_ConnectionHandler.h>
+#include "ConfiguratorAgents/agents/BLE/BLEAgent.h"
+#include "ConfiguratorAgents/agents/Serial/SerialAgent.h"
+
+void onLedChange();
+
+bool led;
+int potentiometer;
+int seconds;
+
+GenericConnectionHandler ArduinoIoTPreferredConnection;
+KVStore kvStore;
+NetworkConfiguratorClass NetworkConfigurator(ArduinoIoTPreferredConnection);
+BLEAgentClass BLEAgent;
+SerialAgentClass SerialAgent;
+
+void initProperties() {
+  NetworkConfigurator.addAgent(BLEAgent);
+  NetworkConfigurator.addAgent(SerialAgent);
+  NetworkConfigurator.setStorage(kvStore);
+
+  /* For changing the default reset pin uncomment and set your preferred pin.
+   * Use DISABLE_PIN for disabling the reset procedure.
+   * The pin must be in the list of digital pins usable for interrupts.
+   * Please refer to the Arduino documentation for more details:
+   * https://docs.arduino.cc/language-reference/en/functions/external-interrupts/attachInterrupt/
+   */
+  //NetworkConfigurator.setReconfigurePin(your_pin);
+
+  /* Otherwise if you need to monitor the pin status changes
+   * you can set a custom callback function that is fired on every change
+   */
+  //NetworkConfigurator.setPinChangedCallback(your_callback);
+
+  ArduinoCloud.setConfigurator(NetworkConfigurator);
+
+  ArduinoCloud.addProperty(led, Permission::Write).onUpdate(onLedChange);
+  ArduinoCloud.addProperty(potentiometer, Permission::Read).publishOnChange(10);
+  ArduinoCloud.addProperty(seconds, Permission::Read).publishOnChange(1);
+
+}
diff --git a/src/AIoTC_Config.h b/src/AIoTC_Config.h
index 82e5093ef..cf3e259d5 100644
--- a/src/AIoTC_Config.h
+++ b/src/AIoTC_Config.h
@@ -148,6 +148,14 @@
   #define BOARD_STM32H7
 #endif
 
+#if defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_NANO_33_IOT) ||  defined(ARDUINO_NANO_RP2040_CONNECT) \
+  || defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_NICLA_VISION) || defined(ARDUINO_OPTA) || defined(ARDUINO_GIGA) \
+  || defined(ARDUINO_UNOR4_WIFI) || defined(ARDUINO_PORTENTA_C33)
+  #define NETWORK_CONFIGURATOR_ENABLED (1)
+#else
+  #define NETWORK_CONFIGURATOR_ENABLED (0)
+#endif
+
 /******************************************************************************
  * CONSTANTS
  ******************************************************************************/
diff --git a/src/ArduinoIoTCloud.cpp b/src/ArduinoIoTCloud.cpp
index a565cac44..74443ff5b 100644
--- a/src/ArduinoIoTCloud.cpp
+++ b/src/ArduinoIoTCloud.cpp
@@ -27,6 +27,9 @@
 
 ArduinoIoTCloudClass::ArduinoIoTCloudClass()
 : _connection{nullptr}
+#if NETWORK_CONFIGURATOR_ENABLED
+, _configurator{nullptr}
+#endif
 , _time_service(TimeService)
 , _thing_id{"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}
 , _lib_version{AIOT_CONFIG_LIB_VERSION}
diff --git a/src/ArduinoIoTCloud.h b/src/ArduinoIoTCloud.h
index 7cea9382e..95f7379d1 100644
--- a/src/ArduinoIoTCloud.h
+++ b/src/ArduinoIoTCloud.h
@@ -25,6 +25,9 @@
 #include <AIoTC_Config.h>
 
 #include <Arduino_ConnectionHandler.h>
+#if NETWORK_CONFIGURATOR_ENABLED
+#include <NetworkConfigurator.h>
+#endif
 
 #if defined(DEBUG_ERROR) || defined(DEBUG_WARNING) || defined(DEBUG_INFO) || defined(DEBUG_DEBUG) || defined(DEBUG_VERBOSE)
 #  include <Arduino_DebugUtils.h>
@@ -101,6 +104,9 @@ class ArduinoIoTCloudClass
     inline unsigned long getInternalTime()              { return _time_service.getTime(); }
     inline unsigned long getLocalTime()                 { return _time_service.getLocalTime(); }
 
+    #if NETWORK_CONFIGURATOR_ENABLED
+    inline void setConfigurator(NetworkConfiguratorClass & configurator) { _configurator = &configurator; }
+    #endif
     void addCallback(ArduinoIoTCloudEvent const event, OnCloudEventCallback callback);
 
 #define addProperty( v, ...) addPropertyReal(v, #v, __VA_ARGS__)
@@ -146,6 +152,9 @@ class ArduinoIoTCloudClass
   protected:
 
     ConnectionHandler * _connection;
+    #if NETWORK_CONFIGURATOR_ENABLED
+    NetworkConfiguratorClass * _configurator = nullptr;
+    #endif
     TimeServiceClass & _time_service;
     String _thing_id;
     String _lib_version;
diff --git a/src/ArduinoIoTCloudTCP.cpp b/src/ArduinoIoTCloudTCP.cpp
index dc8bb86d0..2d1600e35 100644
--- a/src/ArduinoIoTCloudTCP.cpp
+++ b/src/ArduinoIoTCloudTCP.cpp
@@ -35,7 +35,7 @@
 #include <typeinfo>
 
 /******************************************************************************
-   LOCAL MODULE FUNCTIONS
+  LOCAL MODULE FUNCTIONS
  ******************************************************************************/
 
 unsigned long getTime()
@@ -48,7 +48,7 @@ unsigned long getTime()
  ******************************************************************************/
 
 ArduinoIoTCloudTCP::ArduinoIoTCloudTCP()
-: _state{State::ConnectPhy}
+: _state{State::ConfigPhy}
 , _connection_attempt(0,0)
 , _message_stream(std::bind(&ArduinoIoTCloudTCP::sendMessage, this, std::placeholders::_1))
 , _thing(&_message_stream)
@@ -84,24 +84,16 @@ int ArduinoIoTCloudTCP::begin(ConnectionHandler & connection, bool const enable_
   _connection = &connection;
   _brokerAddress = brokerAddress;
 
-  ArduinoIoTAuthenticationMode authMode = ArduinoIoTAuthenticationMode::CERTIFICATE;
+  _authMode = ArduinoIoTAuthenticationMode::CERTIFICATE;
 #if defined (BOARD_HAS_SECRET_KEY)
   /* If board supports and sketch is configured for username and password login */
   if(_password.length()) {
-    authMode = ArduinoIoTAuthenticationMode::PASSWORD;
+    _authMode = ArduinoIoTAuthenticationMode::PASSWORD;
   }
 #endif
 
-  /* Setup broker TLS client */
-  _brokerClient.begin(connection, authMode);
-
-#if  OTA_ENABLED
-  /* Setup OTA TLS client */
-  _otaClient.begin(connection);
-#endif
-
   /* If board is configured for certificate authentication and mTLS */
-  if(authMode == ArduinoIoTAuthenticationMode::CERTIFICATE)
+  if(_authMode == ArduinoIoTAuthenticationMode::CERTIFICATE)
   {
 #if defined(BOARD_HAS_SECURE_ELEMENT)
     if (!_selement.begin())
@@ -141,9 +133,6 @@ int ArduinoIoTCloudTCP::begin(ConnectionHandler & connection, bool const enable_
     _brokerPort = (brokerPort == DEFAULT_BROKER_PORT_AUTO) ? DEFAULT_BROKER_PORT_USER_PASS_AUTH : brokerPort;
   }
 
-  /* 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);
@@ -151,6 +140,7 @@ int ArduinoIoTCloudTCP::begin(ConnectionHandler & connection, bool const enable_
 
 int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress, uint16_t brokerPort)
 {
+  _enable_watchdog = enable_watchdog;
   _brokerAddress = brokerAddress;
   _brokerPort = brokerPort;
 
@@ -195,20 +185,12 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress,
   }
 #endif
 
-  /* Since we do not control what code the user inserts
-   * between ArduinoIoTCloudTCP::begin() and the first
-   * call to ArduinoIoTCloudTCP::update() it is wise to
-   * set a rather large timeout at first.
-   */
-#if defined (ARDUINO_ARCH_SAMD) || defined (ARDUINO_ARCH_MBED)
-  if (enable_watchdog) {
-    /* Initialize watchdog hardware */
-    watchdog_enable();
-    /* Setup callbacks to feed the watchdog during offloaded network operations (connection/download)*/
-    watchdog_enable_network_feed(_connection->getInterface());
+#if NETWORK_CONFIGURATOR_ENABLED
+  if(_configurator != nullptr){
+    _configurator->enableBLE(false);
+    _configurator->begin();
   }
 #endif
-
   return 1;
 }
 
@@ -225,12 +207,16 @@ void ArduinoIoTCloudTCP::update()
   State next_state = _state;
   switch (_state)
   {
+  case State::ConfigPhy:            next_state = handle_ConfigPhy();            break;
+  case State::updatePhy:            next_state = handle_updatePhy();            break;
+  case State::Init:                 next_state = handle_Init();                 break;
   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
@@ -241,11 +227,24 @@ void ArduinoIoTCloudTCP::update()
   watchdog_reset();
 #endif
 
+  /* Poll the network configurator to check if it is updating the configuration.
+   * The polling must be performed only if the the first configuration is completed.
+   */
+  #if NETWORK_CONFIGURATOR_ENABLED
+  if(_configurator != nullptr && _state > State::Init && _configurator->update() == NetworkConfiguratorStates::UPDATING_CONFIG){
+    _state = State::updatePhy;
+  }
+  #endif
+
 #if OTA_ENABLED
   /* OTA FSM needs to reach the Idle state before being able to run independently from
    * the mqttClient. The state can be reached only after the mqttClient is connected to
    * the broker.
    */
+  if(_state <= State::Init){
+    return;
+  }
+
   if((_ota.getState() != OTACloudProcessInterface::Resume &&
       _ota.getState() != OTACloudProcessInterface::OtaBegin) ||
       _mqttClient.connected()) {
@@ -262,6 +261,9 @@ void ArduinoIoTCloudTCP::update()
 
 int ArduinoIoTCloudTCP::connected()
 {
+  if (_state <= State::Init) {
+    return 0;
+  }
   return _mqttClient.connected();
 }
 
@@ -276,6 +278,70 @@ void ArduinoIoTCloudTCP::printDebugInfo()
  * PRIVATE MEMBER FUNCTIONS
  ******************************************************************************/
 
+ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_ConfigPhy()
+{
+#if NETWORK_CONFIGURATOR_ENABLED
+  if (_configurator == nullptr) {
+    return State::Init;
+  }
+
+  if(_configurator->update() == NetworkConfiguratorStates::CONFIGURED) {
+      _configurator->disconnectAgent();
+      return State::Init;
+    }
+  return State::ConfigPhy;
+#else
+  return State::Init;
+#endif
+
+}
+
+ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_updatePhy()
+{
+#if NETWORK_CONFIGURATOR_ENABLED
+  if(_configurator != nullptr && _configurator->update() == NetworkConfiguratorStates::CONFIGURED){
+    _configurator->disconnectAgent();
+    // Go to Connected state since the connectionHandler obj doesn't change
+    return State::Connected;
+  }
+
+  return State::updatePhy;
+#else
+  return State::Connected;
+#endif
+}
+
+ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_Init()
+{
+  /* Setup broker TLS client */
+  /* Setup broker TLS client */
+  _brokerClient.begin(*_connection, _authMode);
+
+#if  OTA_ENABLED
+  /* Setup OTA TLS client */
+  _otaClient.begin(*_connection);
+#endif
+
+  /* Setup TimeService */
+  _time_service.begin(_connection);
+
+  /* Since we do not control what code the user inserts
+   * between ArduinoIoTCloudTCP::begin() and the first
+   * call to ArduinoIoTCloudTCP::update() it is wise to
+   * set a rather large timeout at first.
+   */
+#if defined (ARDUINO_ARCH_SAMD) || defined (ARDUINO_ARCH_MBED)
+  if (_enable_watchdog) {
+    /* Initialize watchdog hardware */
+    watchdog_enable();
+    /* Setup callbacks to feed the watchdog during offloaded network operations (connection/download)*/
+    watchdog_enable_network_feed(_connection->getInterface());
+  }
+#endif
+
+  return State::ConnectPhy;
+}
+
 ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_ConnectPhy()
 {
   if (_connection->check() == NetworkConnectionState::CONNECTED)
@@ -467,10 +533,10 @@ void ArduinoIoTCloudTCP::handleMessage(int length)
           execCloudEventCallback(ArduinoIoTCloudEvent::SYNC);
 
           /*
-           * NOTE: in this current version properties are not properly integrated with the new paradigm of
-           * modeling the messages with C structs. The current CBOR library allocates an array in the heap
-           * thus we need to delete it after decoding it with the old CBORDecoder
-           */
+          * NOTE: in this current version properties are not properly integrated with the new paradigm of
+          * modeling the messages with C structs. The current CBOR library allocates an array in the heap
+          * thus we need to delete it after decoding it with the old CBORDecoder
+          */
           free(command.lastValuesUpdateCmd.params.last_values);
         }
         break;
@@ -525,8 +591,8 @@ void ArduinoIoTCloudTCP::sendPropertyContainerToCloud(String const topic, Proper
     if (bytes_encoded > 0)
     {
       /* If properties have been encoded store them in the back-up buffer
-       * in order to allow retransmission in case of failure.
-       */
+      * in order to allow retransmission in case of failure.
+      */
       _mqtt_data_len = bytes_encoded;
       memcpy(_mqtt_data_buf, data, _mqtt_data_len);
       /* Transmit the properties to the MQTT broker */
@@ -633,8 +699,8 @@ int ArduinoIoTCloudTCP::updateCertificate(String authorityKeyIdentifier, String
 #endif
 
 /******************************************************************************
- * EXTERN DEFINITION
- ******************************************************************************/
+* EXTERN DEFINITION
+******************************************************************************/
 
 ArduinoIoTCloudTCP ArduinoCloud;
 
diff --git a/src/ArduinoIoTCloudTCP.h b/src/ArduinoIoTCloudTCP.h
index 6560a5f70..c9b4bd11e 100644
--- a/src/ArduinoIoTCloudTCP.h
+++ b/src/ArduinoIoTCloudTCP.h
@@ -120,6 +120,9 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass
 
     enum class State
     {
+      ConfigPhy,
+      updatePhy,
+      Init,
       ConnectPhy,
       SyncTime,
       ConnectMqttBroker,
@@ -133,11 +136,13 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass
     ArduinoCloudThing _thing;
     ArduinoCloudDevice _device;
 
+    ArduinoIoTAuthenticationMode _authMode;
     String _brokerAddress;
     uint16_t _brokerPort;
     uint8_t _mqtt_data_buf[MQTT_TRANSMIT_BUFFER_SIZE];
     int _mqtt_data_len;
     bool _mqtt_data_request_retransmit;
+    bool _enable_watchdog;
 
 #if defined(BOARD_HAS_SECRET_KEY)
     String _password;
@@ -170,6 +175,9 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass
     inline String getTopic_dataout  () { return ( getThingId().length() == 0) ? String("") : String("/a/t/" + getThingId() + "/e/o"); }
     inline String getTopic_datain   () { return ( getThingId().length() == 0) ? String("") : String("/a/t/" + getThingId() + "/e/i"); }
 
+    State handle_ConfigPhy();
+    State handle_updatePhy();
+    State handle_Init();
     State handle_ConnectPhy();
     State handle_SyncTime();
     State handle_ConnectMqttBroker();

From 850bea28a26b71194ab9e8a9c8ae002b3dfc69c8 Mon Sep 17 00:00:00 2001
From: fabik111 <fabiomassimo.centonze@gmail.com>
Date: Wed, 19 Mar 2025 16:30:20 +0100
Subject: [PATCH 02/14] add disconnect method

---
 src/ArduinoIoTCloud.h      |  2 +-
 src/ArduinoIoTCloudTCP.cpp | 31 +++++++++++++++++++++++++------
 src/ArduinoIoTCloudTCP.h   |  7 +++++--
 3 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/src/ArduinoIoTCloud.h b/src/ArduinoIoTCloud.h
index 95f7379d1..4512e9a6d 100644
--- a/src/ArduinoIoTCloud.h
+++ b/src/ArduinoIoTCloud.h
@@ -90,7 +90,7 @@ class ArduinoIoTCloudClass
     virtual void update        () = 0;
     virtual int  connected     () = 0;
     virtual void printDebugInfo() = 0;
-
+    virtual void disconnect    () { }
             void push();
             bool setTimestamp(String const & prop_name, unsigned long const timestamp);
 
diff --git a/src/ArduinoIoTCloudTCP.cpp b/src/ArduinoIoTCloudTCP.cpp
index 2d1600e35..deecd3ea4 100644
--- a/src/ArduinoIoTCloudTCP.cpp
+++ b/src/ArduinoIoTCloudTCP.cpp
@@ -79,7 +79,7 @@ ArduinoIoTCloudTCP::ArduinoIoTCloudTCP()
  * PUBLIC MEMBER FUNCTIONS
  ******************************************************************************/
 
-int ArduinoIoTCloudTCP::begin(ConnectionHandler & connection, bool const enable_watchdog, String brokerAddress, uint16_t brokerPort)
+int ArduinoIoTCloudTCP::begin(ConnectionHandler & connection, bool const enable_watchdog, String brokerAddress, uint16_t brokerPort, bool auto_reconnect)
 {
   _connection = &connection;
   _brokerAddress = brokerAddress;
@@ -135,14 +135,17 @@ int ArduinoIoTCloudTCP::begin(ConnectionHandler & connection, bool const enable_
 
   /* 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);
+  return begin(enable_watchdog, _brokerAddress, _brokerPort, auto_reconnect);
 }
 
-int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress, uint16_t brokerPort)
+int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress, uint16_t brokerPort, bool auto_reconnect)
 {
   _enable_watchdog = enable_watchdog;
   _brokerAddress = brokerAddress;
   _brokerPort = brokerPort;
+  _auto_reconnect = auto_reconnect;
+
+  _state = State::ConfigPhy;
 
   _mqttClient.setClient(_brokerClient);
 
@@ -215,6 +218,7 @@ void ArduinoIoTCloudTCP::update()
   case State::ConnectMqttBroker:    next_state = handle_ConnectMqttBroker();    break;
   case State::Connected:            next_state = handle_Connected();            break;
   case State::Disconnect:           next_state = handle_Disconnect();           break;
+  case State::Disconnected:                                                     break;
   }
 
   _state = next_state;
@@ -274,6 +278,16 @@ void ArduinoIoTCloudTCP::printDebugInfo()
   DEBUG_INFO("MQTT Broker: %s:%d", _brokerAddress.c_str(), _brokerPort);
 }
 
+void ArduinoIoTCloudTCP::disconnect() {
+  if (_state == State::ConfigPhy || _state == State::Init) {
+    return;
+  }
+
+  _mqttClient.stop();
+  _auto_reconnect = false;
+  _state = State::Disconnect;
+}
+
 /******************************************************************************
  * PRIVATE MEMBER FUNCTIONS
  ******************************************************************************/
@@ -447,9 +461,13 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_Disconnect()
   DEBUG_INFO("Disconnected from Arduino IoT Cloud");
   execCloudEventCallback(ArduinoIoTCloudEvent::DISCONNECT);
 
-  /* Setup timer for broker connection and restart */
-  _connection_attempt.begin(AIOT_CONFIG_RECONNECTION_RETRY_DELAY_ms, AIOT_CONFIG_MAX_RECONNECTION_RETRY_DELAY_ms);
-  return State::ConnectPhy;
+  if(_auto_reconnect) {
+    /* Setup timer for broker connection and restart */
+    _connection_attempt.begin(AIOT_CONFIG_RECONNECTION_RETRY_DELAY_ms, AIOT_CONFIG_MAX_RECONNECTION_RETRY_DELAY_ms);
+    return State::ConnectPhy;
+  }
+
+  return State::Disconnected;
 }
 
 void ArduinoIoTCloudTCP::onMessage(int length)
@@ -696,6 +714,7 @@ int ArduinoIoTCloudTCP::updateCertificate(String authorityKeyIdentifier, String
   }
   return 0;
 }
+
 #endif
 
 /******************************************************************************
diff --git a/src/ArduinoIoTCloudTCP.h b/src/ArduinoIoTCloudTCP.h
index c9b4bd11e..aa075827c 100644
--- a/src/ArduinoIoTCloudTCP.h
+++ b/src/ArduinoIoTCloudTCP.h
@@ -72,9 +72,10 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass
     virtual void update        () override;
     virtual int  connected     () override;
     virtual void printDebugInfo() override;
+    virtual void disconnect    () override;
 
-    int begin(ConnectionHandler & connection, bool const enable_watchdog = true, String brokerAddress = DEFAULT_BROKER_ADDRESS, uint16_t brokerPort = DEFAULT_BROKER_PORT_AUTO);
-    int begin(bool const enable_watchdog = true, String brokerAddress = DEFAULT_BROKER_ADDRESS, uint16_t brokerPort = DEFAULT_BROKER_PORT_AUTO);
+    int begin(ConnectionHandler & connection, bool const enable_watchdog = true, String brokerAddress = DEFAULT_BROKER_ADDRESS, uint16_t brokerPort = DEFAULT_BROKER_PORT_AUTO, bool auto_reconnect = true);
+    int begin(bool const enable_watchdog = true, String brokerAddress = DEFAULT_BROKER_ADDRESS, uint16_t brokerPort = DEFAULT_BROKER_PORT_AUTO, bool auto_reconnect = true);
 
 #if defined(BOARD_HAS_SECURE_ELEMENT)
     int updateCertificate(String authorityKeyIdentifier, String serialNumber, String notBefore, String notAfter, String signature);
@@ -128,6 +129,7 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass
       ConnectMqttBroker,
       Connected,
       Disconnect,
+      Disconnected,
     };
 
     State _state;
@@ -143,6 +145,7 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass
     int _mqtt_data_len;
     bool _mqtt_data_request_retransmit;
     bool _enable_watchdog;
+    bool _auto_reconnect;
 
 #if defined(BOARD_HAS_SECRET_KEY)
     String _password;

From 97e88d34742ee01cd2a329bbdb9ea62d69808316 Mon Sep 17 00:00:00 2001
From: fabik111 <fabiomassimo.centonze@gmail.com>
Date: Mon, 31 Mar 2025 16:11:19 +0200
Subject: [PATCH 03/14] new Provisioning_2.0 sketch

---
 .github/workflows/compile-examples.yml        |  24 +-
 .../utility/Provisioning_2.0/CSRHandler.cpp   | 424 ++++++++++++++++++
 .../utility/Provisioning_2.0/CSRHandler.h     |  74 +++
 .../Provisioning_2.0/ClaimingHandler.cpp      | 173 +++++++
 .../Provisioning_2.0/ClaimingHandler.h        |  50 +++
 .../Provisioning_2.0/Provisioning_2.0.ino     | 222 +++++++++
 .../utility/Provisioning_2.0/SecretsHelper.h  |  20 +
 .../Provisioning_2.0/thingProperties.h        |  33 ++
 src/ArduinoIoTCloudTCP.cpp                    |   2 +-
 9 files changed, 1013 insertions(+), 9 deletions(-)
 create mode 100644 examples/utility/Provisioning_2.0/CSRHandler.cpp
 create mode 100644 examples/utility/Provisioning_2.0/CSRHandler.h
 create mode 100644 examples/utility/Provisioning_2.0/ClaimingHandler.cpp
 create mode 100644 examples/utility/Provisioning_2.0/ClaimingHandler.h
 create mode 100644 examples/utility/Provisioning_2.0/Provisioning_2.0.ino
 create mode 100644 examples/utility/Provisioning_2.0/SecretsHelper.h
 create mode 100644 examples/utility/Provisioning_2.0/thingProperties.h

diff --git a/.github/workflows/compile-examples.yml b/.github/workflows/compile-examples.yml
index 94681d24b..794a90077 100644
--- a/.github/workflows/compile-examples.yml
+++ b/.github/workflows/compile-examples.yml
@@ -21,19 +21,20 @@ jobs:
       UNIVERSAL_LIBRARIES: |
         # Install the ArduinoIoTCloud library from the repository
         - source-path: ./
-        - source-url: https://github.com/andreagilardoni/Arduino_ConnectionHandler.git
-          version: 0ca6d61eb538c5a21983e582ee1c8794442f8c75
+        - source-url: https://github.com/fabik111/Arduino_ConnectionHandler.git
+          version: e8539870f2f8b7936f3126070b45055c38856bb1
         - source-url: https://github.com/fabik111/ArduinoBLE.git
           version: 82e2a28f871e97b313846cee6d9efed8943dca53
         - name: ArduinoHttpClient
         - name: Arduino_DebugUtils
         - name: ArduinoMqttClient
-        - name: Arduino_SecureElement
-        - name: Arduino_CloudUtils
-        - source-url: https://github.com/andreagilardoni/ArduinoStorage.git
-          version: 39f0bd138103967aaafcaa7f5c0e1e237b4ccb4d
-        - source-url: https://github.com/bcmi-labs/arduino-network-configurator.git
-          version: 962ab36dfb00eb9cebe089907223e576f463519f
+        - source-url: https://github.com/fabik111/Arduino_SecureElement.git
+          version: f5a23964a1c70048e48d5ed2d2657004446f0e3d
+        - source-url: https://github.com/fabik111/Arduino_CloudUtils.git
+          version: a8b52eaf500c63b2e8bd3e4b6f6c77b70fc3e65d
+        - source-url: https://github.com/arduino-libraries/Arduino_KVStore.git
+        - source-url: https://github.com/arduino-libraries/Arduino_UniqueHWId.git
+        - source-url: https://github.com/arduino-libraries/Arduino_NetworkConfigurator.git
       # sketch paths to compile (recursive) for all boards
       UNIVERSAL_SKETCH_PATHS: |
         - examples/ArduinoIoTCloud-Advanced
@@ -145,6 +146,7 @@ jobs:
               - examples/ArduinoIoTCloud-Schedule
               - examples/utility/Provisioning
               - examples/utility/SelfProvisioning
+              - examples/utility/Provisioning_2.0
           - board:
               type: wan
             platforms: |
@@ -209,6 +211,7 @@ jobs:
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
               - examples/utility/Provisioning
+              - examples/utility/Provisioning_2.0
           # Nicla Vision
           - board:
               type: mbed_nicla
@@ -223,6 +226,7 @@ jobs:
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
               - examples/utility/Provisioning
+              - examples/utility/Provisioning_2.0
           # Opta
           - board:
               type: mbed_opta
@@ -239,6 +243,7 @@ jobs:
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
               - examples/utility/Provisioning
+              - examples/utility/Provisioning_2.0
           # GIGA
           - board:
               type: mbed_giga
@@ -255,6 +260,7 @@ jobs:
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
               - examples/utility/Provisioning
+              - examples/utility/Provisioning_2.0
           # Portenta C33
           - board:
               type: renesas_portenta
@@ -269,6 +275,7 @@ jobs:
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
               - examples/utility/Provisioning
+              - examples/utility/Provisioning_2.0
           # UNO R4 WiFi
           - board:
               type: renesas_uno
@@ -281,6 +288,7 @@ jobs:
               - examples/ArduinoIoTCloud-NetConfig
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
+              - examples/utility/Provisioning_2.0
           # Nano ESP32
           - board:
               type: arduino_esp32
diff --git a/examples/utility/Provisioning_2.0/CSRHandler.cpp b/examples/utility/Provisioning_2.0/CSRHandler.cpp
new file mode 100644
index 000000000..4f7649fb7
--- /dev/null
+++ b/examples/utility/Provisioning_2.0/CSRHandler.cpp
@@ -0,0 +1,424 @@
+/*
+  Copyright (c) 2024 Arduino SA
+
+  This Source Code Form is subject to the terms of the Mozilla Public
+  License, v. 2.0. If a copy of the MPL was not distributed with this
+  file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*/
+
+#include "CSRHandler.h"
+#include <utility/SElementArduinoCloudCertificate.h>
+#include <utility/SElementCSR.h>
+#include <utility/SElementArduinoCloudDeviceId.h>
+#include <utility/SElementArduinoCloud.h>
+#include <utility/SElementArduinoCloudJWT.h>
+#include <utility/time/TimeService.h>
+#include <stdlib.h>
+#include "Arduino_DebugUtils.h"
+#include <Arduino_HEX.h>
+
+#define RESPONSE_TIMEOUT 5000
+#define CONNECTION_RETRY_TIMEOUT_MS 2000
+#define BACKEND_INTERVAL_s 12
+#define MAX_CSR_REQUEST_INTERVAL 180000
+#define MAX_CSR_REQUEST_INTERVAL_ATTEMPTS 15
+
+constexpr char *server = "boards-v2.arduino.cc";
+
+CSRHandlerClass::CSRHandlerClass() :
+  _ledFeedback{LEDFeedbackClass::getInstance()},
+  _state{CSRHandlerStates::END},
+  _nextRequestAt{0},
+  _requestAttempt{0},
+  _startWaitingResponse{0},
+  _uhwid{nullptr},
+  _certForCSR{nullptr},
+  _connectionHandler{nullptr},
+  _secureElement{nullptr},
+  _tlsClient{nullptr},
+  _client{nullptr},
+  _fw_version{""},
+  _deviceId{""},
+  _issueYear{0},
+  _issueMonth{0},
+  _issueDay{0},
+  _issueHour{0} {
+  memset(_serialNumber, 0, sizeof(_serialNumber));
+  memset(_authorityKeyIdentifier, 0, sizeof(_authorityKeyIdentifier));
+  memset(_signature, 0, sizeof(_signature));
+}
+
+CSRHandlerClass::~CSRHandlerClass() {
+  if (_certForCSR) {
+    delete _certForCSR;
+    _certForCSR = nullptr;
+  }
+  if (_client) {
+    delete _client;
+    _client = nullptr;
+  }
+
+  if(_tlsClient){
+    delete _tlsClient;
+    _tlsClient = nullptr;
+  }
+}
+
+bool CSRHandlerClass::begin(ConnectionHandler &connectionHandler, SecureElement &secureElement, String &uhwid) {
+  if(_state != CSRHandlerStates::END) {
+    return true;
+  }
+
+  if(uhwid == "") {
+    return false;
+  }
+
+  _connectionHandler = &connectionHandler;
+  _secureElement = &secureElement;
+  _uhwid = &uhwid;
+
+#ifdef BOARD_HAS_WIFI
+  _fw_version = WiFi.firmwareVersion();
+#endif
+  if(!_tlsClient){
+    _tlsClient = new TLSClientMqtt();
+  }
+  _tlsClient->begin(*_connectionHandler);
+  _tlsClient->setTimeout(RESPONSE_TIMEOUT);
+  _client = new HttpClient(*_tlsClient, server, 443);
+  TimeService.begin(_connectionHandler);
+  _requestAttempt = 0;
+  _nextRequestAt = 0;
+  _startWaitingResponse = 0;
+  _state = CSRHandlerStates::BUILD_CSR;
+}
+
+void CSRHandlerClass::end() {
+  if (_client) {
+    _client->stop();
+    delete _client;
+    _client = nullptr;
+  }
+
+  if (_certForCSR) {
+    delete _certForCSR;
+    _certForCSR = nullptr;
+  }
+
+  if(_tlsClient){
+    delete _tlsClient;
+    _tlsClient = nullptr;
+  }
+  _fw_version = "";
+  _deviceId = "";
+  _state = CSRHandlerStates::END;
+}
+
+CSRHandlerClass::CSRHandlerStates CSRHandlerClass::poll() {
+  switch (_state) {
+    case CSRHandlerStates::BUILD_CSR:            _state = handleBuildCSR          (); break;
+    case CSRHandlerStates::REQUEST_SIGNATURE:    _state = handleRequestSignature  (); break;
+    case CSRHandlerStates::WAITING_RESPONSE:     _state = handleWaitingResponse   (); break;
+    case CSRHandlerStates::PARSE_RESPONSE:       _state = handleParseResponse     (); break;
+    case CSRHandlerStates::BUILD_CERTIFICATE:    _state = handleBuildCertificate  (); break;
+    case CSRHandlerStates::CERT_CREATED:         _state = handleCertCreated       (); break;
+    case CSRHandlerStates::WAITING_COMPLETE_RES: _state = handleWaitingCompleteRes(); break;
+    case CSRHandlerStates::COMPLETED:                                                 break;
+    case CSRHandlerStates::ERROR:                         handleError             (); break;
+    case CSRHandlerStates::END:                                                       break;
+  }
+
+  return _state;
+}
+
+void CSRHandlerClass::updateNextRequestAt() {
+  uint32_t delay;
+  if(_requestAttempt <= MAX_CSR_REQUEST_INTERVAL_ATTEMPTS) {
+    delay = BACKEND_INTERVAL_s * _requestAttempt * 1000; // use linear backoff since backend has a rate limit
+  }else {
+    delay = MAX_CSR_REQUEST_INTERVAL;
+  }
+
+  _nextRequestAt = millis() + delay + jitter();
+}
+
+uint32_t CSRHandlerClass::jitter(uint32_t base, uint32_t max) {
+  srand(millis());
+  return base + rand() % (max - base);
+}
+
+bool CSRHandlerClass::postRequest(const char *url, String &postData) {
+  if(!_client){
+    _client = new HttpClient(*_tlsClient, server, 443);
+  }
+
+  uint32_t ts = getTimestamp();
+  if(ts == 0){
+    DEBUG_WARNING("CSRH::%s Failed getting timestamp", __FUNCTION__);
+    return false;
+  }
+
+  String token = getAIoTCloudJWT(*_secureElement, *_uhwid, ts, 1);
+
+  _requestAttempt++;
+  _client->beginRequest();
+
+  if(_client->post(url) == 0){
+    _client->sendHeader("Host", server);
+    _client->sendHeader("Connection", "close");
+    _client->sendHeader("Content-Type", "application/json;charset=UTF-8");
+    _client->sendHeader("Authorization", "Bearer " + token);
+    _client->sendHeader("Content-Length", postData.length());
+    _client->beginBody();
+    _client->print(postData);
+    _startWaitingResponse = millis();
+    return true;
+  }
+  return false;
+}
+
+uint32_t CSRHandlerClass::getTimestamp() {
+  uint8_t getTsAttempt = 0;
+  uint32_t ts = 0;
+  do{
+    TimeService.sync();
+    ts = TimeService.getTime();
+    getTsAttempt++;
+  }while(ts == 0 && getTsAttempt < 3);
+
+  return ts;
+}
+
+CSRHandlerClass::CSRHandlerStates CSRHandlerClass::handleBuildCSR() {
+  if (!_certForCSR) {
+    _certForCSR = new ECP256Certificate();
+  }
+  _certForCSR->begin();
+
+  _certForCSR->setSubjectCommonName(*_uhwid);
+
+  if (!SElementCSR::build(*_secureElement, *_certForCSR, static_cast<int>(SElementArduinoCloudSlot::Key), true)) {
+    DEBUG_ERROR("CSRH::%s Error generating CSR!", __FUNCTION__);
+    _ledFeedback.setMode(LEDFeedbackClass::LEDFeedbackMode::ERROR);
+    return CSRHandlerStates::ERROR;
+  }
+  return CSRHandlerStates::REQUEST_SIGNATURE;
+}
+
+CSRHandlerClass::CSRHandlerStates CSRHandlerClass::handleRequestSignature() {
+  CSRHandlerStates nextState = _state;
+
+  if(millis() < _nextRequestAt) {
+    return nextState;
+  }
+
+  NetworkConnectionState connectionRes = _connectionHandler->check();
+  if (connectionRes != NetworkConnectionState::CONNECTED) {
+    nextNetworkRetry();
+    return nextState;
+  }
+
+  if(!_certForCSR){
+    return CSRHandlerStates::BUILD_CSR;
+  }
+
+  String csr = _certForCSR->getCSRPEM();
+  csr.replace("\n", "\\n");
+
+  String PostData = "{\"csr\":\"";
+  PostData += csr;
+  PostData += "\"}";
+  DEBUG_INFO("CSRH Downloading certificate...");
+
+  if(postRequest("/provisioning/v1/onboarding/provision/csr", PostData)){
+    nextState = CSRHandlerStates::WAITING_RESPONSE;
+  } else {
+    updateNextRequestAt();
+    DEBUG_WARNING("CSRH::%s Failed sending request, retrying in %d ms", __FUNCTION__, _nextRequestAt - millis());
+  }
+
+  return nextState;
+}
+
+CSRHandlerClass::CSRHandlerStates CSRHandlerClass::handleWaitingResponse() {
+  CSRHandlerStates nextState = _state;
+  NetworkConnectionState connectionRes = _connectionHandler->check();
+  if (connectionRes != NetworkConnectionState::CONNECTED) {
+    nextNetworkRetry();
+    _client->stop();
+    return CSRHandlerStates::REQUEST_SIGNATURE;
+  }
+
+  if (millis() - _startWaitingResponse > RESPONSE_TIMEOUT) {
+    _client->stop();
+    updateNextRequestAt();
+    DEBUG_WARNING("CSRH::%s CSR request timeout, retrying in %d ms", __FUNCTION__, _nextRequestAt - millis());
+    nextState = CSRHandlerStates::REQUEST_SIGNATURE;
+  }
+
+
+  int statusCode = _client->responseStatusCode();
+  if(statusCode == 200){
+    nextState = CSRHandlerStates::PARSE_RESPONSE;
+  } else {
+    _client->stop();
+    updateNextRequestAt();
+    DEBUG_WARNING("CSRH::%s CSR request error code %d, retrying in %d ms", __FUNCTION__, statusCode ,_nextRequestAt - millis());
+    nextState = CSRHandlerStates::REQUEST_SIGNATURE;
+  }
+
+  return nextState;
+}
+
+CSRHandlerClass::CSRHandlerStates CSRHandlerClass::handleParseResponse() {
+  String certResponse = _client->responseBody();
+  _client->stop();
+
+  /* Parse the response in format:
+   * device_id|authority_key_identifier|not_before|serial|signature_asn1_x|signature_asn1_y
+   */
+  char *response = (char *)certResponse.c_str();
+  char *token[6];
+  int i = 1;
+  token[0] = strtok(response, "|");
+  for (; i < 6; i++) {
+    char *tok = strtok(NULL, "|");
+    if(tok == NULL){
+      break;
+    }
+    token[i] = tok;
+  }
+
+  if(i < 6 || strlen(token[0]) != 36 || strlen(token[1]) != 40
+   || strlen(token[2]) < 10 || strlen(token[3]) != 32
+   || strlen(token[4]) != 64 || strlen(token[5]) != 64
+   || sscanf(token[2], "%4d-%2d-%2dT%2d", &_issueYear, &_issueMonth, &_issueDay, &_issueHour) != 4){
+    updateNextRequestAt();
+    DEBUG_ERROR("CSRH::%s Error parsing response, retrying in %d ms", __FUNCTION__, _nextRequestAt - millis());
+    return CSRHandlerStates::REQUEST_SIGNATURE;
+  }
+
+  _deviceId = token[0];
+  hex::decode(token[1], _authorityKeyIdentifier, sizeof(_authorityKeyIdentifier));
+  hex::decode(token[3], _serialNumber, sizeof(_serialNumber));
+  hex::decode(token[4], _signature, sizeof(_signature));
+  hex::decode(token[5], &_signature[32], sizeof(_signature) - 32);
+
+  return CSRHandlerStates::BUILD_CERTIFICATE;
+}
+
+CSRHandlerClass::CSRHandlerStates CSRHandlerClass::handleBuildCertificate() {
+  int expireYears = 31;
+
+  if (!SElementArduinoCloudDeviceId::write(*_secureElement, _deviceId, SElementArduinoCloudSlot::DeviceId)) {
+    DEBUG_ERROR("CSRH::%s Error storing device id!", __FUNCTION__);
+    _ledFeedback.setMode(LEDFeedbackClass::LEDFeedbackMode::ERROR);
+    return CSRHandlerStates::ERROR;
+  }
+
+  ECP256Certificate cert;
+  cert.begin();
+
+  cert.setSubjectCommonName(_deviceId);
+  cert.setIssuerCountryName("US");
+  cert.setIssuerOrganizationName("Arduino LLC US");
+  cert.setIssuerOrganizationalUnitName("IT");
+  cert.setIssuerCommonName("Arduino");
+  cert.setSignature(_signature, sizeof(_signature));
+  cert.setAuthorityKeyId(_authorityKeyIdentifier, sizeof(_authorityKeyIdentifier));
+  cert.setSerialNumber(_serialNumber, sizeof(_serialNumber));
+  cert.setIssueYear(_issueYear);
+  cert.setIssueMonth(_issueMonth);
+  cert.setIssueDay(_issueDay);
+  cert.setIssueHour(_issueHour);
+  cert.setExpireYears(expireYears);
+
+  if (!SElementArduinoCloudCertificate::build(*_secureElement, cert, static_cast<int>(SElementArduinoCloudSlot::Key))) {
+    DEBUG_ERROR("CSRH::%s Error building secureElement compressed cert!", __FUNCTION__);
+    _ledFeedback.setMode(LEDFeedbackClass::LEDFeedbackMode::ERROR);
+    return CSRHandlerStates::ERROR;
+  }
+
+  if (!SElementArduinoCloudCertificate::write(*_secureElement, cert, SElementArduinoCloudSlot::CompressedCertificate)) {
+    DEBUG_ERROR("CSRH::%s Error storing cert!" , __FUNCTION__);
+    _ledFeedback.setMode(LEDFeedbackClass::LEDFeedbackMode::ERROR);
+    return CSRHandlerStates::ERROR;
+  }
+
+  DEBUG_INFO("CSRH Certificate created!");
+  _nextRequestAt = 0;
+  _requestAttempt = 0;
+  return CSRHandlerStates::CERT_CREATED;
+}
+
+CSRHandlerClass::CSRHandlerStates CSRHandlerClass::handleCertCreated() {
+  CSRHandlerStates nextState = _state;
+
+  if(millis() < _nextRequestAt) {
+    return nextState;
+  }
+
+  NetworkConnectionState connectionRes = _connectionHandler->check();
+  if (connectionRes != NetworkConnectionState::CONNECTED) {
+    nextNetworkRetry();
+    return nextState;
+  }
+
+  String PostData = "{\"wifi_fw_version\":\"";
+  PostData += _fw_version;
+  PostData += "\"}";
+  if(postRequest("/provisioning/v1/onboarding/provision/complete", PostData)){
+    nextState = CSRHandlerStates::WAITING_COMPLETE_RES;
+  } else {
+    updateNextRequestAt();
+    DEBUG_WARNING("CSRH::%s Error sending complete request, retrying in %d ms", __FUNCTION__, _nextRequestAt - millis());
+  }
+
+  return nextState;
+}
+
+CSRHandlerClass::CSRHandlerStates CSRHandlerClass::handleWaitingCompleteRes() {
+  CSRHandlerStates nextState = _state;
+  NetworkConnectionState connectionRes = _connectionHandler->check();
+  if (connectionRes != NetworkConnectionState::CONNECTED) {
+    nextNetworkRetry();
+    _client->stop();
+    return CSRHandlerStates::CERT_CREATED;
+  }
+
+  if (millis() - _startWaitingResponse > RESPONSE_TIMEOUT) {
+    _client->stop();
+    updateNextRequestAt();
+    DEBUG_WARNING("CSRH::%s Complete request timeout, retrying in %d ms", __FUNCTION__, _nextRequestAt - millis());
+    nextState = CSRHandlerStates::CERT_CREATED;
+  }
+
+  int statusCode = _client->responseStatusCode();
+  if(statusCode == 200){
+    if (_certForCSR) {
+      delete _certForCSR;
+      _certForCSR = nullptr;
+    }
+    DEBUG_INFO("CSRH Provisioning completed!");
+    nextState = CSRHandlerStates::COMPLETED;
+  } else if (statusCode == 429 || statusCode == 503) {
+    updateNextRequestAt();
+    nextState = CSRHandlerStates::CERT_CREATED;
+  } else {
+    DEBUG_WARNING("CSRH::%s Complete request error code %d, retrying in %d ms", __FUNCTION__, statusCode ,_nextRequestAt - millis());
+    _requestAttempt = 0;
+    _nextRequestAt = 0;
+    nextState = CSRHandlerStates::REQUEST_SIGNATURE;
+  }
+  _client->stop();
+
+  return nextState;
+}
+
+void CSRHandlerClass::nextNetworkRetry() {
+  _nextRequestAt = millis() + CONNECTION_RETRY_TIMEOUT_MS;
+}
+
+void CSRHandlerClass::handleError() {
+  _ledFeedback.update();
+}
diff --git a/examples/utility/Provisioning_2.0/CSRHandler.h b/examples/utility/Provisioning_2.0/CSRHandler.h
new file mode 100644
index 000000000..1165ac05b
--- /dev/null
+++ b/examples/utility/Provisioning_2.0/CSRHandler.h
@@ -0,0 +1,74 @@
+/*
+  Copyright (c) 2024 Arduino SA
+
+  This Source Code Form is subject to the terms of the Mozilla Public
+  License, v. 2.0. If a copy of the MPL was not distributed with this
+  file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*/
+
+#pragma once
+#include <Arduino.h>
+#include <Arduino_ConnectionHandler.h>
+#include <Arduino_SecureElement.h>
+#include <tls/utility/TLSClientMqtt.h>
+#include <ArduinoHttpClient.h>
+#include "Utility/LEDFeedback/LEDFeedback.h"
+#define JITTER_BASE 0
+#define JITTER_MAX 1000
+
+class CSRHandlerClass {
+public:
+  CSRHandlerClass();
+  ~CSRHandlerClass();
+  enum class CSRHandlerStates {
+    BUILD_CSR,
+    REQUEST_SIGNATURE,
+    WAITING_RESPONSE,
+    PARSE_RESPONSE,
+    BUILD_CERTIFICATE,
+    CERT_CREATED,
+    WAITING_COMPLETE_RES,
+    COMPLETED,
+    ERROR,
+    END
+  };
+  bool begin(ConnectionHandler &connectionHandler, SecureElement &secureElement, String &uhwid);
+  void end();
+  CSRHandlerStates poll();
+private:
+  CSRHandlerStates _state;
+  unsigned long _nextRequestAt;
+  uint32_t _requestAttempt;
+  uint32_t _startWaitingResponse;
+  String *_uhwid;
+  String _fw_version;
+
+  int _issueYear;
+  uint8_t _issueMonth;
+  uint8_t _issueDay;
+  uint8_t _issueHour;
+  byte _serialNumber[16];
+  byte _authorityKeyIdentifier[20];
+  byte _signature[64];
+  String _deviceId;
+
+  ECP256Certificate *_certForCSR;
+  ConnectionHandler *_connectionHandler;
+  SecureElement *_secureElement;
+  TLSClientMqtt *_tlsClient;
+  HttpClient *_client;
+  LEDFeedbackClass &_ledFeedback;
+  void updateNextRequestAt();
+  void nextNetworkRetry();
+  uint32_t jitter(uint32_t base = JITTER_BASE, uint32_t max = JITTER_MAX);
+  bool postRequest(const char *url, String &postData);
+  uint32_t getTimestamp();
+  CSRHandlerStates handleBuildCSR();
+  CSRHandlerStates handleRequestSignature();
+  CSRHandlerStates handleWaitingResponse();
+  CSRHandlerStates handleParseResponse();
+  CSRHandlerStates handleBuildCertificate();
+  CSRHandlerStates handleCertCreated();
+  CSRHandlerStates handleWaitingCompleteRes();
+  void handleError();
+};
diff --git a/examples/utility/Provisioning_2.0/ClaimingHandler.cpp b/examples/utility/Provisioning_2.0/ClaimingHandler.cpp
new file mode 100644
index 000000000..3e794300d
--- /dev/null
+++ b/examples/utility/Provisioning_2.0/ClaimingHandler.cpp
@@ -0,0 +1,173 @@
+/*
+  Copyright (c) 2024 Arduino SA
+
+  This Source Code Form is subject to the terms of the Mozilla Public
+  License, v. 2.0. If a copy of the MPL was not distributed with this
+  file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*/
+
+#include "ClaimingHandler.h"
+#include <utility/SElementArduinoCloudJWT.h>
+#include "Arduino_DebugUtils.h"
+#include <ArduinoBLE.h>
+#include "utility/HCI.h"
+#include <Arduino_HEX.h>
+
+ClaimingHandlerClass::ClaimingHandlerClass():
+  _uhwid {nullptr},
+  _state {ClaimingHandlerStates::END},
+  _secureElement {nullptr},
+  _clearStoredCredentials {nullptr},
+  _agentManager { AgentsManagerClass::getInstance()},
+  _ledFeedback {LEDFeedbackClass::getInstance()} {
+  _receivedEvent = ClaimingReqEvents::NONE;
+  _ts = 0;
+}
+
+bool ClaimingHandlerClass::begin(SecureElement &secureElement, String &uhwid, ClearStoredCredentialsHandler clearStoredCredentials) {
+  if(_state != ClaimingHandlerStates::END) {
+    return true;
+  }
+
+  if(uhwid == "" || clearStoredCredentials == nullptr) {
+    return false;
+  }
+
+  if (!_agentManager.addRequestHandler(RequestType::GET_ID, getIdRequestCb)) {
+    return false;
+  }
+
+  if (!_agentManager.addRequestHandler(RequestType::RESET, resetStoredCredRequestCb)) {
+    return false;
+  }
+
+  if(!_agentManager.addRequestHandler(RequestType::GET_BLE_MAC_ADDRESS, getBLEMacAddressRequestCb)) {
+    return false;
+  }
+
+  if (!_agentManager.addReturnTimestampCallback(setTimestamp)) {
+    return false;
+  }
+
+  _agentManager.begin();
+  _uhwid = &uhwid;
+  _secureElement = &secureElement;
+  _clearStoredCredentials = clearStoredCredentials;
+  _state = ClaimingHandlerStates::INIT;
+}
+
+void ClaimingHandlerClass::end() {
+  if(_state == ClaimingHandlerStates::END) {
+    return;
+  }
+
+  _agentManager.removeReturnTimestampCallback();
+  _agentManager.removeRequestHandler(RequestType::GET_ID);
+  _agentManager.removeRequestHandler(RequestType::RESET);
+  _agentManager.end();
+  _state = ClaimingHandlerStates::END;
+}
+
+void ClaimingHandlerClass::poll() {
+  if(_state == ClaimingHandlerStates::END) {
+    return;
+  }
+  _ledFeedback.update();
+  _agentManager.update();
+
+  switch (_receivedEvent) {
+    case ClaimingReqEvents::GET_ID:              getIdReqHandler           (); break;
+    case ClaimingReqEvents::RESET:               resetStoredCredReqHandler (); break;
+    case ClaimingReqEvents::GET_BLE_MAC_ADDRESS: getBLEMacAddressReqHandler(); break;
+  }
+  _receivedEvent = ClaimingReqEvents::NONE;
+  return;
+}
+
+void ClaimingHandlerClass::getIdReqHandler() {
+  if (_ts != 0) {
+    byte _uhwidBytes[32];
+    hex::decode(_uhwid->c_str(), _uhwidBytes, _uhwid->length());
+    //Send UHWID
+    ProvisioningOutputMessage idMsg = {MessageOutputType::UHWID};
+    idMsg.m.uhwid = _uhwidBytes;
+    _agentManager.sendMsg(idMsg);
+
+    String token = getAIoTCloudJWT(*_secureElement, *_uhwid, _ts, 1);
+    if (token == "") {
+      DEBUG_ERROR("CH::%s Error: token not created", __FUNCTION__);
+      sendStatus(StatusMessage::ERROR);
+      return;
+    }
+
+    //Send JWT
+    ProvisioningOutputMessage jwtMsg = {MessageOutputType::JWT};
+    jwtMsg.m.jwt = token.c_str();
+    _agentManager.sendMsg(jwtMsg);
+    _ts = 0;
+  } else {
+    DEBUG_ERROR("CH::%s Error: timestamp not provided" , __FUNCTION__);
+    sendStatus(StatusMessage::PARAMS_NOT_FOUND);
+  }
+}
+
+void ClaimingHandlerClass::resetStoredCredReqHandler() {
+  if( !_clearStoredCredentials()){
+    DEBUG_ERROR("CH::%s Error: reset stored credentials failed", __FUNCTION__);
+    sendStatus(StatusMessage::ERROR);
+  } else {
+    sendStatus(StatusMessage::RESET_COMPLETED);
+  }
+
+}
+
+void ClaimingHandlerClass::getBLEMacAddressReqHandler() {
+  uint8_t mac[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+  bool activated = false;
+  ConfiguratorAgent * connectedAgent = _agentManager.getConnectedAgent();
+  if(!_agentManager.isAgentEnabled(ConfiguratorAgent::AgentTypes::BLE) || (connectedAgent != nullptr &&
+    connectedAgent->getAgentType() != ConfiguratorAgent::AgentTypes::BLE)) {
+      activated = true;
+      BLE.begin();
+  }
+
+  HCI.readBdAddr(mac);
+
+  for(int i = 0; i < 3; i++){
+    uint8_t byte = mac[i];
+    mac[i] = mac[5-i];
+    mac[5-i] = byte;
+  }
+  if (activated) {
+    BLE.end();
+  }
+
+  ProvisioningOutputMessage outputMsg;
+  outputMsg.type = MessageOutputType::BLE_MAC_ADDRESS;
+  outputMsg.m.BLEMacAddress = mac;
+  _agentManager.sendMsg(outputMsg);
+}
+
+void ClaimingHandlerClass::getIdRequestCb() {
+  DEBUG_VERBOSE("CH Get ID request received");
+  _receivedEvent = ClaimingReqEvents::GET_ID;
+}
+void ClaimingHandlerClass::setTimestamp(uint64_t ts) {
+  _ts = ts;
+}
+
+void ClaimingHandlerClass::resetStoredCredRequestCb() {
+  DEBUG_VERBOSE("CH Reset stored credentials request received");
+  _receivedEvent = ClaimingReqEvents::RESET;
+}
+
+void ClaimingHandlerClass::getBLEMacAddressRequestCb() {
+  DEBUG_VERBOSE("CH Get BLE MAC address request received");
+  _receivedEvent = ClaimingReqEvents::GET_BLE_MAC_ADDRESS;
+}
+
+bool ClaimingHandlerClass::sendStatus(StatusMessage msg) {
+  ProvisioningOutputMessage statusMsg = { MessageOutputType::STATUS, { msg } };
+  return _agentManager.sendMsg(statusMsg);
+}
diff --git a/examples/utility/Provisioning_2.0/ClaimingHandler.h b/examples/utility/Provisioning_2.0/ClaimingHandler.h
new file mode 100644
index 000000000..7229b47c0
--- /dev/null
+++ b/examples/utility/Provisioning_2.0/ClaimingHandler.h
@@ -0,0 +1,50 @@
+/*
+  Copyright (c) 2024 Arduino SA
+
+  This Source Code Form is subject to the terms of the Mozilla Public
+  License, v. 2.0. If a copy of the MPL was not distributed with this
+  file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*/
+
+#pragma once
+#include "Arduino.h"
+#include "ConfiguratorAgents/AgentsManager.h"
+#include <Arduino_SecureElement.h>
+#include "Utility/LEDFeedback/LEDFeedback.h"
+
+typedef bool (*ClearStoredCredentialsHandler)();
+class ClaimingHandlerClass {
+public:
+  ClaimingHandlerClass();
+  bool begin(SecureElement &secureElement, String &uhwid, ClearStoredCredentialsHandler clearStoredCredentials);
+  void end();
+  void poll();
+private:
+  String *_uhwid;
+  enum class ClaimingHandlerStates {
+    INIT,
+    END
+  };
+  enum class ClaimingReqEvents { NONE,
+                                 GET_ID,
+                                 RESET,
+                                 GET_BLE_MAC_ADDRESS };
+  static inline ClaimingReqEvents _receivedEvent;
+  ClaimingHandlerStates _state;
+  AgentsManagerClass &_agentManager;
+  LEDFeedbackClass &_ledFeedback;
+  static inline uint64_t _ts;
+  SecureElement *_secureElement;
+
+  bool sendStatus(StatusMessage msg);
+  /* Commands handlers */
+  void getIdReqHandler();
+  void resetStoredCredReqHandler();
+  void getBLEMacAddressReqHandler();
+  ClearStoredCredentialsHandler _clearStoredCredentials;
+  /* Callbacks for receiving commands */
+  static void getIdRequestCb();
+  static void setTimestamp(uint64_t ts);
+  static void resetStoredCredRequestCb();
+  static void getBLEMacAddressRequestCb();
+};
diff --git a/examples/utility/Provisioning_2.0/Provisioning_2.0.ino b/examples/utility/Provisioning_2.0/Provisioning_2.0.ino
new file mode 100644
index 000000000..5cc612e8f
--- /dev/null
+++ b/examples/utility/Provisioning_2.0/Provisioning_2.0.ino
@@ -0,0 +1,222 @@
+/*
+  Copyright (c) 2024 Arduino SA
+
+  This Source Code Form is subject to the terms of the Mozilla Public
+  License, v. 2.0. If a copy of the MPL was not distributed with this
+  file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*/
+#include "thingProperties.h"
+#include "CSRHandler.h"
+#include "ClaimingHandler.h"
+#include "SecretsHelper.h"
+#include <Arduino_FlashFormatter.h>
+#include <Arduino_SecureElement.h>
+#include <utility/SElementArduinoCloudDeviceId.h>
+#include <utility/SElementArduinoCloudCertificate.h>
+#include "Utility/LEDFeedback/LEDFeedback.h"
+
+enum class DeviceState {
+    HARDWARE_CHECK,
+    BEGIN,
+    NETWORK_CONFIG,
+    CSR,
+    BEGIN_CLOUD,
+    RUN,
+    ERROR
+  };
+
+DeviceState _state = DeviceState::HARDWARE_CHECK;
+SecureElement secureElement;
+
+String uhwid = "";
+bool resetEvent = false;
+
+CSRHandlerClass CSRHandler;
+ClaimingHandlerClass ClaimingHandler;
+
+bool clearStoredCredentials() {
+  const uint8_t empty[4] = {0x00,0x00,0x00,0x00};
+  if(!NetworkConfigurator.resetStoredConfiguration() || \
+    !secureElement.writeSlot(static_cast<int>(SElementArduinoCloudSlot::DeviceId), (byte*)empty, sizeof(empty)) || \
+    !secureElement.writeSlot(static_cast<int>(SElementArduinoCloudSlot::CompressedCertificate), (byte*)empty, sizeof(empty))) {
+    return false;
+  }
+
+  ArduinoCloud.disconnect();
+  resetEvent = true;
+  return true;
+  }
+
+void setup() {
+  Serial.begin(9600);
+
+  delay(1500);
+
+  setDebugMessageLevel(4);
+
+  initProperties();
+  AgentsManagerClass::getInstance().begin();
+  LEDFeedbackClass::getInstance().begin();
+  DEBUG_INFO("Starting Provisioning");
+}
+
+void sendStatus(StatusMessage msg) {
+  ProvisioningOutputMessage outMsg = { MessageOutputType::STATUS, { msg } };
+  AgentsManagerClass::getInstance().sendMsg(outMsg);
+}
+
+DeviceState handleHardwareCheck() {
+  // Init the secure element
+  if(!secureElement.begin()) {
+    DEBUG_ERROR("Sketch: Error during secureElement begin!");
+    LEDFeedbackClass::getInstance().setMode(LEDFeedbackClass::LEDFeedbackMode::ERROR);
+    sendStatus(StatusMessage::HW_ERROR_SE_BEGIN);
+    return DeviceState::ERROR;
+  }
+
+  if (!secureElement.locked()) {
+    if (!secureElement.writeConfiguration()) {
+      DEBUG_ERROR("Sketch: Writing secureElement configuration failed!");
+      LEDFeedbackClass::getInstance().setMode(LEDFeedbackClass::LEDFeedbackMode::ERROR);
+      sendStatus(StatusMessage::HW_ERROR_SE_CONFIG);
+      return DeviceState::ERROR;
+    }
+
+    if (!secureElement.lock()) {
+      DEBUG_ERROR("Sketch: Locking secureElement configuration failed!");
+      LEDFeedbackClass::getInstance().setMode(LEDFeedbackClass::LEDFeedbackMode::ERROR);
+      sendStatus(StatusMessage::HW_ERROR_SE_LOCK);
+      return DeviceState::ERROR;
+    }
+    DEBUG_INFO("secureElement locked successfully");
+  }
+
+  FlashFormatter flashFormatter;
+  // Check if the board storage is properly formatted
+  if(!flashFormatter.checkandFormatPartition()) {
+    DEBUG_ERROR("Sketch: Error partitioning storage");
+    LEDFeedbackClass::getInstance().setMode(LEDFeedbackClass::LEDFeedbackMode::ERROR);
+    sendStatus(StatusMessage::FAIL_TO_PARTITION_STORAGE);
+    return DeviceState::ERROR;
+  }
+
+  return DeviceState::BEGIN;
+}
+
+DeviceState handleBegin() {
+  uhwid = GetUHWID();
+  if(uhwid == ""){
+    DEBUG_ERROR("Sketch: Error getting UHWID");
+    LEDFeedbackClass::getInstance().setMode(LEDFeedbackClass::LEDFeedbackMode::ERROR);
+    sendStatus(StatusMessage::ERROR_GENERATING_UHWID);
+    return DeviceState::ERROR;
+  }
+  // Scan the network options
+  NetworkConfigurator.scanNetworkOptions();
+  NetworkConfigurator.begin();
+  ClaimingHandler.begin(secureElement, uhwid, clearStoredCredentials);
+  DEBUG_INFO("BLE Available");
+  return DeviceState::NETWORK_CONFIG;
+}
+
+DeviceState handleNetworkConfig() {
+  ClaimingHandler.poll();
+  if(resetEvent){
+    resetEvent = false;
+  }
+  NetworkConfiguratorStates s = NetworkConfigurator.update();
+
+  DeviceState nextState = _state;
+  if (s == NetworkConfiguratorStates::CONFIGURED) {
+    String deviceId = "";
+    SElementArduinoCloudDeviceId::read(secureElement, deviceId, SElementArduinoCloudSlot::DeviceId);
+
+    if (deviceId == "") {
+      CSRHandler.begin(ArduinoIoTPreferredConnection, secureElement, uhwid);
+      nextState = DeviceState::CSR;
+    } else {
+      nextState = DeviceState::BEGIN_CLOUD;
+    }
+  }
+  return nextState;
+}
+
+DeviceState handleCSR() {
+  NetworkConfigurator.update();
+  ClaimingHandler.poll();
+  if(resetEvent) {
+    resetEvent = false;
+    CSRHandler.end();
+    return DeviceState::NETWORK_CONFIG;
+  }
+
+  DeviceState nextState = _state;
+
+  CSRHandlerClass::CSRHandlerStates res = CSRHandler.poll();
+  if (res == CSRHandlerClass::CSRHandlerStates::COMPLETED) {
+    CSRHandler.end();
+    nextState = DeviceState::BEGIN_CLOUD;
+  }
+
+  return nextState;
+}
+
+DeviceState handleBeginCloud() {
+  // Close the connection to the peer (App mobile, FE, etc)
+  NetworkConfigurator.disconnectAgent();
+  // Close the BLE connectivity
+  if (NetworkConfigurator.isAgentEnabled(ConfiguratorAgent::AgentTypes::BLE)) {
+    NetworkConfigurator.enableAgent(ConfiguratorAgent::AgentTypes::BLE, false);
+  }
+  // Connect to Arduino IoT Cloud
+  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
+  ArduinoCloud.printDebugInfo();
+
+  return DeviceState::RUN;
+}
+
+void cloudConnectedHandler(bool connected) {
+  static bool _status = false;
+  if(connected != _status){
+    _status = connected;
+    if(connected){
+      LEDFeedbackClass::getInstance().setMode(LEDFeedbackClass::LEDFeedbackMode::CONNECTED_TO_CLOUD);
+    } else {
+      LEDFeedbackClass::getInstance().setMode(LEDFeedbackClass::LEDFeedbackMode::NONE);
+    }
+  }
+}
+
+DeviceState handleRun() {
+  ClaimingHandler.poll();
+  if(resetEvent) {
+    resetEvent = false;
+    return DeviceState::NETWORK_CONFIG;
+  }
+
+  DeviceState nextState = _state;
+  ArduinoCloud.update();
+
+  cloudConnectedHandler(ArduinoCloud.connected());
+
+  return nextState;
+}
+
+DeviceState handleError() {
+  LEDFeedbackClass::getInstance().update();
+  AgentsManagerClass::getInstance().update();
+  return DeviceState::ERROR;
+}
+
+void loop() {
+  switch (_state) {
+    case DeviceState::HARDWARE_CHECK:  _state = handleHardwareCheck(); break;
+    case DeviceState::BEGIN:           _state = handleBegin        (); break;
+    case DeviceState::NETWORK_CONFIG : _state = handleNetworkConfig(); break;
+    case DeviceState::CSR:             _state = handleCSR          (); break;
+    case DeviceState::BEGIN_CLOUD:     _state = handleBeginCloud   (); break;
+    case DeviceState::RUN:             _state = handleRun          (); break;
+    case DeviceState::ERROR:           _state = handleError        (); break;
+    default:                                                           break;
+  }
+}
diff --git a/examples/utility/Provisioning_2.0/SecretsHelper.h b/examples/utility/Provisioning_2.0/SecretsHelper.h
new file mode 100644
index 000000000..bdb6354d1
--- /dev/null
+++ b/examples/utility/Provisioning_2.0/SecretsHelper.h
@@ -0,0 +1,20 @@
+/*
+  Copyright (c) 2024 Arduino SA
+
+  This Source Code Form is subject to the terms of the Mozilla Public
+  License, v. 2.0. If a copy of the MPL was not distributed with this
+  file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*/
+
+#pragma once
+
+#include <Arduino.h>
+#include <Arduino_UniqueHWId.h>
+
+inline String GetUHWID() {
+  UniqueHWId Id;
+  if (Id.begin()) {
+    return Id.get();
+  }
+  return "";
+}
diff --git a/examples/utility/Provisioning_2.0/thingProperties.h b/examples/utility/Provisioning_2.0/thingProperties.h
new file mode 100644
index 000000000..0bdc6c85f
--- /dev/null
+++ b/examples/utility/Provisioning_2.0/thingProperties.h
@@ -0,0 +1,33 @@
+/*
+  Copyright (c) 2024 Arduino SA
+
+  This Source Code Form is subject to the terms of the Mozilla Public
+  License, v. 2.0. If a copy of the MPL was not distributed with this
+  file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*/
+#if defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRNB1500) || defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310)
+#error "Board not supported for Provisioning 2.0"
+#endif
+
+#include <ArduinoIoTCloud.h>
+#include <GenericConnectionHandler.h>
+#include <Arduino_KVStore.h>
+#include "NetworkConfigurator.h"
+#include "ConfiguratorAgents/agents/BLE/BLEAgent.h"
+#include "ConfiguratorAgents/agents/Serial/SerialAgent.h"
+
+GenericConnectionHandler ArduinoIoTPreferredConnection;
+KVStore kvStore;
+BLEAgentClass BLEAgent;
+SerialAgentClass SerialAgent;
+NetworkConfiguratorClass NetworkConfigurator(ArduinoIoTPreferredConnection);
+
+void initProperties() {
+
+  NetworkConfigurator.addAgent(BLEAgent);
+  NetworkConfigurator.addAgent(SerialAgent);
+  NetworkConfigurator.setStorage(kvStore);
+  ArduinoCloud.setConfigurator(NetworkConfigurator);
+}
+
+
diff --git a/src/ArduinoIoTCloudTCP.cpp b/src/ArduinoIoTCloudTCP.cpp
index deecd3ea4..2f2f67770 100644
--- a/src/ArduinoIoTCloudTCP.cpp
+++ b/src/ArduinoIoTCloudTCP.cpp
@@ -190,7 +190,7 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress,
 
 #if NETWORK_CONFIGURATOR_ENABLED
   if(_configurator != nullptr){
-    _configurator->enableBLE(false);
+    _configurator->enableAgent(ConfiguratorAgent::AgentTypes::BLE,false);
     _configurator->begin();
   }
 #endif

From b36f3ec8db0257b2d87c50e6dc3cb35fcbb66361 Mon Sep 17 00:00:00 2001
From: fabik111 <fabiomassimo.centonze@gmail.com>
Date: Wed, 2 Apr 2025 17:53:51 +0200
Subject: [PATCH 04/14] rename NetworkConfigurator.h into
 Arduino_NetworkConfigurator.h

---
 examples/utility/Provisioning_2.0/thingProperties.h | 1 -
 src/ArduinoIoTCloud.h                               | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/examples/utility/Provisioning_2.0/thingProperties.h b/examples/utility/Provisioning_2.0/thingProperties.h
index 0bdc6c85f..d2127c693 100644
--- a/examples/utility/Provisioning_2.0/thingProperties.h
+++ b/examples/utility/Provisioning_2.0/thingProperties.h
@@ -12,7 +12,6 @@
 #include <ArduinoIoTCloud.h>
 #include <GenericConnectionHandler.h>
 #include <Arduino_KVStore.h>
-#include "NetworkConfigurator.h"
 #include "ConfiguratorAgents/agents/BLE/BLEAgent.h"
 #include "ConfiguratorAgents/agents/Serial/SerialAgent.h"
 
diff --git a/src/ArduinoIoTCloud.h b/src/ArduinoIoTCloud.h
index 4512e9a6d..16e07d1c7 100644
--- a/src/ArduinoIoTCloud.h
+++ b/src/ArduinoIoTCloud.h
@@ -26,7 +26,7 @@
 
 #include <Arduino_ConnectionHandler.h>
 #if NETWORK_CONFIGURATOR_ENABLED
-#include <NetworkConfigurator.h>
+#include <Arduino_NetworkConfigurator.h>
 #endif
 
 #if defined(DEBUG_ERROR) || defined(DEBUG_WARNING) || defined(DEBUG_INFO) || defined(DEBUG_DEBUG) || defined(DEBUG_VERBOSE)

From 3f5419f75455a87ab69bb47c936f4b5db41500ea Mon Sep 17 00:00:00 2001
From: fabik111 <fabiomassimo.centonze@gmail.com>
Date: Tue, 8 Apr 2025 15:11:30 +0200
Subject: [PATCH 05/14] update test

---
 .github/workflows/compile-examples.yml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/compile-examples.yml b/.github/workflows/compile-examples.yml
index 794a90077..4123bf35b 100644
--- a/.github/workflows/compile-examples.yml
+++ b/.github/workflows/compile-examples.yml
@@ -188,7 +188,8 @@ jobs:
               - name: ArduinoECCX08
               - name: Blues Wireless Notecard
               - name: RTCZero
-              - name: MKRNB
+              - source-url: https://github.com/fabik111/MKRNB
+                version: f514c2a497b80a1f1992f62156f4ba12569db464
               - source-url: https://github.com/adafruit/Adafruit_SleepyDog.git
             sketch-paths: |
               - examples/ArduinoIoTCloud-Notecard

From 43b3ae4ccde629ddef310978f0ccf19fe2fb1ac9 Mon Sep 17 00:00:00 2001
From: fabik111 <fabiomassimo.centonze@gmail.com>
Date: Fri, 11 Apr 2025 11:45:18 +0200
Subject: [PATCH 06/14] add GET_PROVISIONING_SKETCH_VERSION command

---
 .../Provisioning_2.0/ClaimingHandler.cpp      | 25 ++++++++++++++++---
 .../Provisioning_2.0/ClaimingHandler.h        |  5 +++-
 .../Provisioning_2.0/Provisioning_2.0.ino     |  2 ++
 3 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/examples/utility/Provisioning_2.0/ClaimingHandler.cpp b/examples/utility/Provisioning_2.0/ClaimingHandler.cpp
index 3e794300d..7456f410b 100644
--- a/examples/utility/Provisioning_2.0/ClaimingHandler.cpp
+++ b/examples/utility/Provisioning_2.0/ClaimingHandler.cpp
@@ -13,6 +13,8 @@
 #include "utility/HCI.h"
 #include <Arduino_HEX.h>
 
+extern const char *SKETCH_VERSION;
+
 ClaimingHandlerClass::ClaimingHandlerClass():
   _uhwid {nullptr},
   _state {ClaimingHandlerStates::END},
@@ -45,6 +47,10 @@ bool ClaimingHandlerClass::begin(SecureElement &secureElement, String &uhwid, Cl
     return false;
   }
 
+  if(!_agentManager.addRequestHandler(RequestType::GET_PROVISIONING_SKETCH_VERSION, getProvSketchVersionRequestCb)) {
+    return false;
+  }
+
   if (!_agentManager.addReturnTimestampCallback(setTimestamp)) {
     return false;
   }
@@ -76,9 +82,10 @@ void ClaimingHandlerClass::poll() {
   _agentManager.update();
 
   switch (_receivedEvent) {
-    case ClaimingReqEvents::GET_ID:              getIdReqHandler           (); break;
-    case ClaimingReqEvents::RESET:               resetStoredCredReqHandler (); break;
-    case ClaimingReqEvents::GET_BLE_MAC_ADDRESS: getBLEMacAddressReqHandler(); break;
+    case ClaimingReqEvents::GET_ID:                  getIdReqHandler               (); break;
+    case ClaimingReqEvents::RESET:                   resetStoredCredReqHandler     (); break;
+    case ClaimingReqEvents::GET_BLE_MAC_ADDRESS:     getBLEMacAddressReqHandler    (); break;
+    case ClaimingReqEvents::GET_PROV_SKETCH_VERSION: getProvSketchVersionReqHandler(); break;
   }
   _receivedEvent = ClaimingReqEvents::NONE;
   return;
@@ -149,6 +156,13 @@ void ClaimingHandlerClass::getBLEMacAddressReqHandler() {
   _agentManager.sendMsg(outputMsg);
 }
 
+void ClaimingHandlerClass::getProvSketchVersionReqHandler() {
+  ProvisioningOutputMessage outputMsg;
+  outputMsg.type = MessageOutputType::PROV_SKETCH_VERSION;
+  outputMsg.m.provSketchVersion = SKETCH_VERSION;
+  _agentManager.sendMsg(outputMsg);
+}
+
 void ClaimingHandlerClass::getIdRequestCb() {
   DEBUG_VERBOSE("CH Get ID request received");
   _receivedEvent = ClaimingReqEvents::GET_ID;
@@ -167,6 +181,11 @@ void ClaimingHandlerClass::getBLEMacAddressRequestCb() {
   _receivedEvent = ClaimingReqEvents::GET_BLE_MAC_ADDRESS;
 }
 
+void ClaimingHandlerClass::getProvSketchVersionRequestCb() {
+  DEBUG_VERBOSE("CH Get provisioning sketch version request received");
+  _receivedEvent = ClaimingReqEvents::GET_PROV_SKETCH_VERSION;
+}
+
 bool ClaimingHandlerClass::sendStatus(StatusMessage msg) {
   ProvisioningOutputMessage statusMsg = { MessageOutputType::STATUS, { msg } };
   return _agentManager.sendMsg(statusMsg);
diff --git a/examples/utility/Provisioning_2.0/ClaimingHandler.h b/examples/utility/Provisioning_2.0/ClaimingHandler.h
index 7229b47c0..fc6a2605e 100644
--- a/examples/utility/Provisioning_2.0/ClaimingHandler.h
+++ b/examples/utility/Provisioning_2.0/ClaimingHandler.h
@@ -28,7 +28,8 @@ class ClaimingHandlerClass {
   enum class ClaimingReqEvents { NONE,
                                  GET_ID,
                                  RESET,
-                                 GET_BLE_MAC_ADDRESS };
+                                 GET_BLE_MAC_ADDRESS,
+                                 GET_PROV_SKETCH_VERSION};
   static inline ClaimingReqEvents _receivedEvent;
   ClaimingHandlerStates _state;
   AgentsManagerClass &_agentManager;
@@ -41,10 +42,12 @@ class ClaimingHandlerClass {
   void getIdReqHandler();
   void resetStoredCredReqHandler();
   void getBLEMacAddressReqHandler();
+  void getProvSketchVersionReqHandler();
   ClearStoredCredentialsHandler _clearStoredCredentials;
   /* Callbacks for receiving commands */
   static void getIdRequestCb();
   static void setTimestamp(uint64_t ts);
   static void resetStoredCredRequestCb();
   static void getBLEMacAddressRequestCb();
+  static void getProvSketchVersionRequestCb();
 };
diff --git a/examples/utility/Provisioning_2.0/Provisioning_2.0.ino b/examples/utility/Provisioning_2.0/Provisioning_2.0.ino
index 5cc612e8f..14fc3aecc 100644
--- a/examples/utility/Provisioning_2.0/Provisioning_2.0.ino
+++ b/examples/utility/Provisioning_2.0/Provisioning_2.0.ino
@@ -15,6 +15,8 @@
 #include <utility/SElementArduinoCloudCertificate.h>
 #include "Utility/LEDFeedback/LEDFeedback.h"
 
+const char *SKETCH_VERSION = "0.1.0";
+
 enum class DeviceState {
     HARDWARE_CHECK,
     BEGIN,

From a8ad0e2f91d99e43f6f243a74d678ba45b3196e8 Mon Sep 17 00:00:00 2001
From: pennam <m.pennasilico@arduino.cc>
Date: Mon, 14 Apr 2025 11:10:16 +0200
Subject: [PATCH 07/14] compile-examples: save provisioning binary as artifact

---
 .github/workflows/compile-examples.yml | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/.github/workflows/compile-examples.yml b/.github/workflows/compile-examples.yml
index 4123bf35b..9541fb6bf 100644
--- a/.github/workflows/compile-examples.yml
+++ b/.github/workflows/compile-examples.yml
@@ -368,6 +368,9 @@ jobs:
             ${{ matrix.sketch-paths }}
           enable-deltas-report: "true"
           sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }}
+          cli-compile-flags: |
+            - --output-dir
+            - ${{ runner.temp }}/arduino-cli-output
 
       - name: Write data to size trends report spreadsheet
         # Update report on every push to the master branch
@@ -384,3 +387,10 @@ jobs:
         with:
           name: sketches-report-${{ matrix.board.artifact-name-suffix }}
           path: ${{ env.SKETCHES_REPORTS_PATH }}
+
+      - name: Save build artifact
+        if: github.event_name == 'pull_request'
+        uses: actions/upload-artifact@v4
+        with:
+          name: provisioning-${{ matrix.board.artifact-name-suffix }}
+          path: ${{ runner.temp }}/arduino-cli-output/Provisioning*

From 9d58d9dbc8814b725b88adbc024becc8ceeb203b Mon Sep 17 00:00:00 2001
From: fabik111 <fabiomassimo.centonze@gmail.com>
Date: Mon, 14 Apr 2025 15:17:33 +0200
Subject: [PATCH 08/14] update compile ci

---
 .github/workflows/compile-examples.yml            | 15 ++++++++-------
 .../ArduinoIoTCloud-NetConfig/thingProperties.h   |  1 +
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/.github/workflows/compile-examples.yml b/.github/workflows/compile-examples.yml
index 9541fb6bf..d2839b11a 100644
--- a/.github/workflows/compile-examples.yml
+++ b/.github/workflows/compile-examples.yml
@@ -22,9 +22,8 @@ jobs:
         # Install the ArduinoIoTCloud library from the repository
         - source-path: ./
         - source-url: https://github.com/fabik111/Arduino_ConnectionHandler.git
-          version: e8539870f2f8b7936f3126070b45055c38856bb1
-        - source-url: https://github.com/fabik111/ArduinoBLE.git
-          version: 82e2a28f871e97b313846cee6d9efed8943dca53
+          version: 0314cf54593029aea05bb8c179e40a26128f7d67
+        - name: ArduinoBLE
         - name: ArduinoHttpClient
         - name: Arduino_DebugUtils
         - name: ArduinoMqttClient
@@ -136,7 +135,7 @@ jobs:
               - name: Blues Wireless Notecard
               - name: RTCZero
               - source-url: https://github.com/andreagilardoni/WiFiNINA.git
-                version: ca7a9224f86b9aaf00de4f7feccea583a23b3d53
+                version: 31616ac5a30f6281c68f982bc39800771b2fbaeb
               - name: Arduino_JSON
               - source-url: https://github.com/adafruit/Adafruit_SleepyDog.git
             sketch-paths: |
@@ -188,8 +187,7 @@ jobs:
               - name: ArduinoECCX08
               - name: Blues Wireless Notecard
               - name: RTCZero
-              - source-url: https://github.com/fabik111/MKRNB
-                version: f514c2a497b80a1f1992f62156f4ba12569db464
+              - name: MKRNB
               - source-url: https://github.com/adafruit/Adafruit_SleepyDog.git
             sketch-paths: |
               - examples/ArduinoIoTCloud-Notecard
@@ -221,6 +219,7 @@ jobs:
               - name: arduino:mbed_nicla
             libraries: |
               - name: Blues Wireless Notecard
+              - name: ArduinoECCX08
             sketch-paths: |
               - examples/ArduinoIoTCloud-NetConfig
               - examples/ArduinoIoTCloud-DeferredOTA
@@ -271,6 +270,7 @@ jobs:
             libraries: |
               - name: Arduino_Cellular
               - name: Blues Wireless Notecard
+              - name: ArduinoECCX08
             sketch-paths: |
               - examples/ArduinoIoTCloud-NetConfig
               - examples/ArduinoIoTCloud-Notecard
@@ -285,6 +285,7 @@ jobs:
               - name: arduino:renesas_uno
             libraries: |
               - name: Blues Wireless Notecard
+              - name: ArduinoECCX08
             sketch-paths: |
               - examples/ArduinoIoTCloud-NetConfig
               - examples/ArduinoIoTCloud-Notecard
@@ -393,4 +394,4 @@ jobs:
         uses: actions/upload-artifact@v4
         with:
           name: provisioning-${{ matrix.board.artifact-name-suffix }}
-          path: ${{ runner.temp }}/arduino-cli-output/Provisioning*
+          path: ${{ runner.temp }}/arduino-cli-output/Provisioning_2.0*
diff --git a/examples/ArduinoIoTCloud-NetConfig/thingProperties.h b/examples/ArduinoIoTCloud-NetConfig/thingProperties.h
index 833927042..ce3e17a39 100644
--- a/examples/ArduinoIoTCloud-NetConfig/thingProperties.h
+++ b/examples/ArduinoIoTCloud-NetConfig/thingProperties.h
@@ -5,6 +5,7 @@
 #endif
 #include <ArduinoIoTCloud.h>
 #include <Arduino_ConnectionHandler.h>
+#include <GenericConnectionHandler.h>
 #include "ConfiguratorAgents/agents/BLE/BLEAgent.h"
 #include "ConfiguratorAgents/agents/Serial/SerialAgent.h"
 

From 51edc23d48b484262081e5e62ec22969cd2a4697 Mon Sep 17 00:00:00 2001
From: fabik111 <fabiomassimo.centonze@gmail.com>
Date: Tue, 15 Apr 2025 10:40:22 +0200
Subject: [PATCH 09/14] add define for compile with test env

---
 examples/utility/Provisioning_2.0/CSRHandler.cpp       | 4 ++++
 examples/utility/Provisioning_2.0/Provisioning_2.0.ino | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/examples/utility/Provisioning_2.0/CSRHandler.cpp b/examples/utility/Provisioning_2.0/CSRHandler.cpp
index 4f7649fb7..1a6101e4b 100644
--- a/examples/utility/Provisioning_2.0/CSRHandler.cpp
+++ b/examples/utility/Provisioning_2.0/CSRHandler.cpp
@@ -23,7 +23,11 @@
 #define MAX_CSR_REQUEST_INTERVAL 180000
 #define MAX_CSR_REQUEST_INTERVAL_ATTEMPTS 15
 
+#ifdef COMPILE_TEST
+constexpr char *server = "boards-v2.oniudra.cc";
+#else
 constexpr char *server = "boards-v2.arduino.cc";
+#endif
 
 CSRHandlerClass::CSRHandlerClass() :
   _ledFeedback{LEDFeedbackClass::getInstance()},
diff --git a/examples/utility/Provisioning_2.0/Provisioning_2.0.ino b/examples/utility/Provisioning_2.0/Provisioning_2.0.ino
index 14fc3aecc..c6ccc5c9d 100644
--- a/examples/utility/Provisioning_2.0/Provisioning_2.0.ino
+++ b/examples/utility/Provisioning_2.0/Provisioning_2.0.ino
@@ -171,7 +171,11 @@ DeviceState handleBeginCloud() {
     NetworkConfigurator.enableAgent(ConfiguratorAgent::AgentTypes::BLE, false);
   }
   // Connect to Arduino IoT Cloud
+#ifdef COMPILE_TEST
+  ArduinoCloud.begin(ArduinoIoTPreferredConnection, false, "mqtts-sa.iot.oniudra.cc");
+#else
   ArduinoCloud.begin(ArduinoIoTPreferredConnection);
+#endif
   ArduinoCloud.printDebugInfo();
 
   return DeviceState::RUN;

From f4c330b3d187c2220185db95474eef394f90db6b Mon Sep 17 00:00:00 2001
From: pennam <m.pennasilico@arduino.cc>
Date: Tue, 15 Apr 2025 10:52:36 +0200
Subject: [PATCH 10/14] Add dedicated workflow to compile provisioning binaries

---
 .github/workflows/compile-provisioning.yml | 205 +++++++++++++++++++++
 1 file changed, 205 insertions(+)
 create mode 100644 .github/workflows/compile-provisioning.yml

diff --git a/.github/workflows/compile-provisioning.yml b/.github/workflows/compile-provisioning.yml
new file mode 100644
index 000000000..4bf4362ab
--- /dev/null
+++ b/.github/workflows/compile-provisioning.yml
@@ -0,0 +1,205 @@
+name: Compile Provisioning
+
+on:
+  pull_request:
+    paths:
+      - ".github/workflows/compile-provisioning.yml"
+      - "examples/**"
+      - "src/**"
+  push:
+    paths:
+      - ".github/workflows/compile-provisioning.yml"
+      - "examples/**"
+      - "src/**"
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+
+    env:
+      # libraries to install for all boards
+      UNIVERSAL_LIBRARIES: |
+        # Install the ArduinoIoTCloud library from the repository
+        - source-path: ./
+        - source-url: https://github.com/fabik111/Arduino_ConnectionHandler.git
+          version: 0314cf54593029aea05bb8c179e40a26128f7d67
+        - name: ArduinoBLE
+        - name: ArduinoECCX08
+        - name: ArduinoBearSSL
+        - name: ArduinoHttpClient
+        - name: Arduino_DebugUtils
+        - name: ArduinoMqttClient
+        - source-url: https://github.com/fabik111/Arduino_SecureElement.git
+          version: f5a23964a1c70048e48d5ed2d2657004446f0e3d
+        - source-url: https://github.com/fabik111/Arduino_CloudUtils.git
+          version: a8b52eaf500c63b2e8bd3e4b6f6c77b70fc3e65d
+        - source-url: https://github.com/arduino-libraries/Arduino_KVStore.git
+        - source-url: https://github.com/arduino-libraries/Arduino_UniqueHWId.git
+        - source-url: https://github.com/arduino-libraries/Arduino_NetworkConfigurator.git
+      # sketch paths to compile (recursive) for all boards
+      UNIVERSAL_SKETCH_PATHS: |
+        - examples/utility/Provisioning_2.0
+      SKETCHES_REPORTS_PATH: sketches-reports
+
+    strategy:
+      fail-fast: false
+
+      matrix:
+        board:
+          - fqbn: arduino:samd:mkrwifi1010
+            type: nina
+            artifact-name-suffix: arduino-samd-mkrwifi1010
+          - fqbn: arduino:samd:nano_33_iot
+            type: nina
+            artifact-name-suffix: arduino-samd-nano_33_iot
+          - fqbn: arduino:mbed_portenta:envie_m7:split=100_0
+            type: mbed_portenta
+            artifact-name-suffix: arduino-mbed_portenta-envie_m7
+          - fqbn: arduino:mbed_nano:nanorp2040connect
+            type: nina
+            artifact-name-suffix: arduino-mbed_nano-nanorp2040connect
+          - fqbn: arduino:mbed_nicla:nicla_vision
+            type: mbed_nicla
+            artifact-name-suffix: arduino-mbed_nicla-nicla_vision
+          - fqbn: arduino:mbed_opta:opta
+            type: mbed_opta
+            artifact-name-suffix: arduino-mbed_opta-opta
+          - fqbn: arduino:mbed_giga:giga
+            type: mbed_giga
+            artifact-name-suffix: arduino-mbed_giga-giga
+          - fqbn: arduino:renesas_portenta:portenta_c33
+            type: renesas_portenta
+            artifact-name-suffix: arduino-renesas_portenta-portenta_c33
+          - fqbn: arduino:renesas_uno:unor4wifi
+            type: renesas_uno
+            artifact-name-suffix: arduino-renesas_uno-unor4wifi
+
+        # make board type-specific customizations to the matrix jobs
+        include:
+          # MKR WiFi 1010, Nano 33 IoT, Nano RP2040 Connect
+          - board:
+              type: nina
+            platforms: |
+              # Install samd and mbed_nano platform via Boards Manager
+              - name: arduino:samd
+              - name: arduino:mbed_nano
+            libraries: |
+              - name: RTCZero
+              - source-url: https://github.com/andreagilardoni/WiFiNINA.git
+                version: 31616ac5a30f6281c68f982bc39800771b2fbaeb
+              - name: Arduino_JSON
+              - source-url: https://github.com/adafruit/Adafruit_SleepyDog.git
+          # Portenta
+          - board:
+              type: mbed_portenta
+            platforms: |
+              # Install mbed_portenta platform via Boards Manager
+              - name: arduino:mbed_portenta
+            libraries: |
+              - name: Arduino_Cellular
+          # Nicla Vision
+          - board:
+              type: mbed_nicla
+            platforms: |
+              # Install mbed_nicla platform via Boards Manager
+              - name: arduino:mbed_nicla
+          # Opta
+          - board:
+              type: mbed_opta
+            platforms: |
+              # Install mbed_opta platform via Boards Manager
+              - name: arduino:mbed_opta
+          # GIGA
+          - board:
+              type: mbed_giga
+            platforms: |
+              # Install mbed_giga platform via Boards Manager
+              - name: arduino:mbed_giga
+          # Portenta C33
+          - board:
+              type: renesas_portenta
+            platforms: |
+              # Install renesas_portenta platform via Boards Manager
+              - name: arduino:renesas_portenta
+            libraries: |
+              - name: Arduino_Cellular
+          # UNO R4 WiFi
+          - board:
+              type: renesas_uno
+            platforms: |
+              # Install renesas_uno platform via Boards Manager
+              - name: arduino:renesas_uno
+
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+
+      - name: Compile production provisioning sketch
+        uses: arduino/compile-sketches@v1
+        with:
+          github-token: ${{ secrets.GITHUB_TOKEN }}
+          platforms: ${{ matrix.platforms }}
+          fqbn: ${{ matrix.board.fqbn }}
+          libraries: |
+            ${{ env.UNIVERSAL_LIBRARIES }}
+            ${{ matrix.libraries }}
+          sketch-paths: |
+            ${{ env.UNIVERSAL_SKETCH_PATHS }}
+            ${{ matrix.sketch-paths }}
+          enable-deltas-report: "true"
+          sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }}
+          cli-compile-flags: |
+            - --verbose
+            - --output-dir
+            - ${{ runner.temp }}/provisioning-prod
+
+      - name: Compile staging provisioning sketch
+        uses: arduino/compile-sketches@v1
+        with:
+          github-token: ${{ secrets.GITHUB_TOKEN }}
+          platforms: ${{ matrix.platforms }}
+          fqbn: ${{ matrix.board.fqbn }}
+          libraries: |
+            ${{ env.UNIVERSAL_LIBRARIES }}
+            ${{ matrix.libraries }}
+          sketch-paths: |
+            ${{ env.UNIVERSAL_SKETCH_PATHS }}
+            ${{ matrix.sketch-paths }}
+          enable-deltas-report: "true"
+          sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }}
+          cli-compile-flags: |
+            - --verbose
+            - --build-property
+            - "build.extra_flags=-DCOMPILE_TEST=1"
+            - --output-dir
+            - ${{ runner.temp }}/provisioning-staging
+
+      - name: Write data to size trends report spreadsheet
+        # Update report on every push to the master branch
+        if: github.event_name == 'push' && github.ref == 'refs/heads/master'
+        uses: arduino/report-size-trends@main
+        with:
+          sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }}
+          google-key-file: ${{ secrets.GOOGLE_KEY_FILE }}
+          spreadsheet-id: 1I6NZkpZpf8KugBkE92adB1Z3_b7ZepOpCdYTOigJpN4
+
+      - name: Save memory usage change report as artifact
+        if: github.event_name == 'pull_request'
+        uses: actions/upload-artifact@v4
+        with:
+          name: sketches-report-${{ matrix.board.artifact-name-suffix }}
+          path: ${{ env.SKETCHES_REPORTS_PATH }}
+
+      - name: Save production artifact
+        if: github.event_name == 'pull_request'
+        uses: actions/upload-artifact@v4
+        with:
+          name: provisioning-prod-${{ matrix.board.artifact-name-suffix }}
+          path: ${{ runner.temp }}/provisioning-prod/
+
+      - name: Save staging artifact
+        if: github.event_name == 'pull_request'
+        uses: actions/upload-artifact@v4
+        with:
+          name: provisioning-staging-${{ matrix.board.artifact-name-suffix }}
+          path: ${{ runner.temp }}/provisioning-staging/

From 67ec58213e5133ec027d47c402c1b121395dcfed Mon Sep 17 00:00:00 2001
From: pennam <m.pennasilico@arduino.cc>
Date: Tue, 15 Apr 2025 13:43:04 +0200
Subject: [PATCH 11/14] cleanup compile examples

---
 .github/workflows/compile-examples.yml | 23 +----------------------
 1 file changed, 1 insertion(+), 22 deletions(-)

diff --git a/.github/workflows/compile-examples.yml b/.github/workflows/compile-examples.yml
index d2839b11a..9c60a5c9f 100644
--- a/.github/workflows/compile-examples.yml
+++ b/.github/workflows/compile-examples.yml
@@ -24,6 +24,7 @@ jobs:
         - source-url: https://github.com/fabik111/Arduino_ConnectionHandler.git
           version: 0314cf54593029aea05bb8c179e40a26128f7d67
         - name: ArduinoBLE
+        - name: Arduino_KVStore
         - name: ArduinoHttpClient
         - name: Arduino_DebugUtils
         - name: ArduinoMqttClient
@@ -31,8 +32,6 @@ jobs:
           version: f5a23964a1c70048e48d5ed2d2657004446f0e3d
         - source-url: https://github.com/fabik111/Arduino_CloudUtils.git
           version: a8b52eaf500c63b2e8bd3e4b6f6c77b70fc3e65d
-        - source-url: https://github.com/arduino-libraries/Arduino_KVStore.git
-        - source-url: https://github.com/arduino-libraries/Arduino_UniqueHWId.git
         - source-url: https://github.com/arduino-libraries/Arduino_NetworkConfigurator.git
       # sketch paths to compile (recursive) for all boards
       UNIVERSAL_SKETCH_PATHS: |
@@ -145,7 +144,6 @@ jobs:
               - examples/ArduinoIoTCloud-Schedule
               - examples/utility/Provisioning
               - examples/utility/SelfProvisioning
-              - examples/utility/Provisioning_2.0
           - board:
               type: wan
             platforms: |
@@ -210,7 +208,6 @@ jobs:
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
               - examples/utility/Provisioning
-              - examples/utility/Provisioning_2.0
           # Nicla Vision
           - board:
               type: mbed_nicla
@@ -219,14 +216,12 @@ jobs:
               - name: arduino:mbed_nicla
             libraries: |
               - name: Blues Wireless Notecard
-              - name: ArduinoECCX08
             sketch-paths: |
               - examples/ArduinoIoTCloud-NetConfig
               - examples/ArduinoIoTCloud-DeferredOTA
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
               - examples/utility/Provisioning
-              - examples/utility/Provisioning_2.0
           # Opta
           - board:
               type: mbed_opta
@@ -243,7 +238,6 @@ jobs:
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
               - examples/utility/Provisioning
-              - examples/utility/Provisioning_2.0
           # GIGA
           - board:
               type: mbed_giga
@@ -260,7 +254,6 @@ jobs:
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
               - examples/utility/Provisioning
-              - examples/utility/Provisioning_2.0
           # Portenta C33
           - board:
               type: renesas_portenta
@@ -270,13 +263,11 @@ jobs:
             libraries: |
               - name: Arduino_Cellular
               - name: Blues Wireless Notecard
-              - name: ArduinoECCX08
             sketch-paths: |
               - examples/ArduinoIoTCloud-NetConfig
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
               - examples/utility/Provisioning
-              - examples/utility/Provisioning_2.0
           # UNO R4 WiFi
           - board:
               type: renesas_uno
@@ -285,12 +276,10 @@ jobs:
               - name: arduino:renesas_uno
             libraries: |
               - name: Blues Wireless Notecard
-              - name: ArduinoECCX08
             sketch-paths: |
               - examples/ArduinoIoTCloud-NetConfig
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
-              - examples/utility/Provisioning_2.0
           # Nano ESP32
           - board:
               type: arduino_esp32
@@ -369,9 +358,6 @@ jobs:
             ${{ matrix.sketch-paths }}
           enable-deltas-report: "true"
           sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }}
-          cli-compile-flags: |
-            - --output-dir
-            - ${{ runner.temp }}/arduino-cli-output
 
       - name: Write data to size trends report spreadsheet
         # Update report on every push to the master branch
@@ -388,10 +374,3 @@ jobs:
         with:
           name: sketches-report-${{ matrix.board.artifact-name-suffix }}
           path: ${{ env.SKETCHES_REPORTS_PATH }}
-
-      - name: Save build artifact
-        if: github.event_name == 'pull_request'
-        uses: actions/upload-artifact@v4
-        with:
-          name: provisioning-${{ matrix.board.artifact-name-suffix }}
-          path: ${{ runner.temp }}/arduino-cli-output/Provisioning_2.0*

From d97774d1a6a5931f11a5a4ef80152bf2c50f676b Mon Sep 17 00:00:00 2001
From: pennam <m.pennasilico@arduino.cc>
Date: Wed, 16 Apr 2025 14:42:51 +0200
Subject: [PATCH 12/14] update compile examples library refs

---
 .github/workflows/compile-examples.yml | 48 +++++++++++++++-----------
 1 file changed, 27 insertions(+), 21 deletions(-)

diff --git a/.github/workflows/compile-examples.yml b/.github/workflows/compile-examples.yml
index 9c60a5c9f..79c30b5a6 100644
--- a/.github/workflows/compile-examples.yml
+++ b/.github/workflows/compile-examples.yml
@@ -21,17 +21,17 @@ jobs:
       UNIVERSAL_LIBRARIES: |
         # Install the ArduinoIoTCloud library from the repository
         - source-path: ./
-        - source-url: https://github.com/fabik111/Arduino_ConnectionHandler.git
-          version: 0314cf54593029aea05bb8c179e40a26128f7d67
         - name: ArduinoBLE
         - name: Arduino_KVStore
         - name: ArduinoHttpClient
         - name: Arduino_DebugUtils
         - name: ArduinoMqttClient
-        - source-url: https://github.com/fabik111/Arduino_SecureElement.git
-          version: f5a23964a1c70048e48d5ed2d2657004446f0e3d
-        - source-url: https://github.com/fabik111/Arduino_CloudUtils.git
-          version: a8b52eaf500c63b2e8bd3e4b6f6c77b70fc3e65d
+        - source-url: https://github.com/arduino-libraries/Arduino_ConnectionHandler.git
+          version: 0314cf54593029aea05bb8c179e40a26128f7d67
+        - source-url: https://github.com/arduino-libraries/Arduino_SecureElement.git
+          version: 4900febf84435c1a06bb13451bced3bac6f16e76
+        - source-url: https://github.com/arduino-libraries/Arduino_CloudUtils.git
+          version: 2e2facc2209b66905c180ec0058ef8b083912278
         - source-url: https://github.com/arduino-libraries/Arduino_NetworkConfigurator.git
       # sketch paths to compile (recursive) for all boards
       UNIVERSAL_SKETCH_PATHS: |
@@ -111,12 +111,13 @@ jobs:
               # Install samd platform via Boards Manager
               - name: arduino:samd
             libraries: |
-              - name: ArduinoBearSSL
+              - source-url: https://github.com/arduino-libraries/ArduinoBearSSL.git
+                version: a891ad3cb15bca3d080adc8188a63277f92fa81c
               - name: ArduinoECCX08
               - name: Blues Wireless Notecard
               - name: RTCZero
               - name: WiFi101
-              - source-url: https://github.com/adafruit/Adafruit_SleepyDog.git
+              - name: Adafruit SleepyDog Library
             sketch-paths: |
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
@@ -129,14 +130,14 @@ jobs:
               - name: arduino:samd
               - name: arduino:mbed_nano
             libraries: |
-              - name: ArduinoBearSSL
+              - source-url: https://github.com/arduino-libraries/ArduinoBearSSL.git
+                version: a891ad3cb15bca3d080adc8188a63277f92fa81c
               - name: ArduinoECCX08
               - name: Blues Wireless Notecard
               - name: RTCZero
-              - source-url: https://github.com/andreagilardoni/WiFiNINA.git
-                version: 31616ac5a30f6281c68f982bc39800771b2fbaeb
-              - name: Arduino_JSON
-              - source-url: https://github.com/adafruit/Adafruit_SleepyDog.git
+              - source-url: https://github.com/arduino-libraries/WiFiNINA.git
+                version: 69e786c5c73fe94b7f408853550f6f151cfc58b0
+              - name: Adafruit SleepyDog Library
             sketch-paths: |
               - examples/ArduinoIoTCloud-NetConfig
               - examples/ArduinoIoTCloud-DeferredOTA
@@ -154,7 +155,7 @@ jobs:
               - name: Blues Wireless Notecard
               - name: RTCZero
               - name: MKRWAN
-              - source-url: https://github.com/adafruit/Adafruit_SleepyDog.git
+              - name: Adafruit SleepyDog Library
             sketch-paths: |
               - examples/ArduinoIoTCloud-Notecard
           # GSM boards
@@ -164,12 +165,13 @@ jobs:
               # Install samd platform via Boards Manager
               - name: arduino:samd
             libraries: |
-              - name: ArduinoBearSSL
+              - source-url: https://github.com/arduino-libraries/ArduinoBearSSL.git
+                version: a891ad3cb15bca3d080adc8188a63277f92fa81c
               - name: ArduinoECCX08
               - name: Blues Wireless Notecard
               - name: RTCZero
               - name: MKRGSM
-              - source-url: https://github.com/adafruit/Adafruit_SleepyDog.git
+              - name: Adafruit SleepyDog Library
             sketch-paths: |
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
@@ -181,12 +183,13 @@ jobs:
               # Install samd platform via Boards Manager
               - name: arduino:samd
             libraries: |
-              - name: ArduinoBearSSL
+              - source-url: https://github.com/arduino-libraries/ArduinoBearSSL.git
+                version: a891ad3cb15bca3d080adc8188a63277f92fa81c
               - name: ArduinoECCX08
               - name: Blues Wireless Notecard
               - name: RTCZero
               - name: MKRNB
-              - source-url: https://github.com/adafruit/Adafruit_SleepyDog.git
+              - name: Adafruit SleepyDog Library
             sketch-paths: |
               - examples/ArduinoIoTCloud-Notecard
               - examples/ArduinoIoTCloud-Schedule
@@ -198,7 +201,8 @@ jobs:
               # Install mbed_portenta platform via Boards Manager
               - name: arduino:mbed_portenta
             libraries: |
-              - name: ArduinoBearSSL
+              - source-url: https://github.com/arduino-libraries/ArduinoBearSSL.git
+                version: a891ad3cb15bca3d080adc8188a63277f92fa81c
               - name: ArduinoECCX08
               - name: Arduino_Cellular
               - name: Blues Wireless Notecard
@@ -229,7 +233,8 @@ jobs:
               # Install mbed_opta platform via Boards Manager
               - name: arduino:mbed_opta
             libraries: |
-              - name: ArduinoBearSSL
+              - source-url: https://github.com/arduino-libraries/ArduinoBearSSL.git
+                version: a891ad3cb15bca3d080adc8188a63277f92fa81c
               - name: ArduinoECCX08
               - name: Blues Wireless Notecard
             sketch-paths: |
@@ -245,7 +250,8 @@ jobs:
               # Install mbed_giga platform via Boards Manager
               - name: arduino:mbed_giga
             libraries: |
-              - name: ArduinoBearSSL
+              - source-url: https://github.com/arduino-libraries/ArduinoBearSSL.git
+                version: a891ad3cb15bca3d080adc8188a63277f92fa81c
               - name: ArduinoECCX08
               - name: Blues Wireless Notecard
             sketch-paths: |

From a40a3bd2b710984ba3be4c36bf73b2caa6e45a20 Mon Sep 17 00:00:00 2001
From: pennam <m.pennasilico@arduino.cc>
Date: Wed, 16 Apr 2025 14:43:10 +0200
Subject: [PATCH 13/14] update compile provisioning library refs

---
 .github/workflows/compile-provisioning.yml | 60 +++++++++++++++++-----
 1 file changed, 47 insertions(+), 13 deletions(-)

diff --git a/.github/workflows/compile-provisioning.yml b/.github/workflows/compile-provisioning.yml
index 4bf4362ab..e4aa0d923 100644
--- a/.github/workflows/compile-provisioning.yml
+++ b/.github/workflows/compile-provisioning.yml
@@ -21,21 +21,26 @@ jobs:
       UNIVERSAL_LIBRARIES: |
         # Install the ArduinoIoTCloud library from the repository
         - source-path: ./
-        - source-url: https://github.com/fabik111/Arduino_ConnectionHandler.git
-          version: 0314cf54593029aea05bb8c179e40a26128f7d67
         - name: ArduinoBLE
-        - name: ArduinoECCX08
-        - name: ArduinoBearSSL
+          version: 1.4.0
         - name: ArduinoHttpClient
+          version: 0.6.1
         - name: Arduino_DebugUtils
+          version: 1.4.0
         - name: ArduinoMqttClient
-        - source-url: https://github.com/fabik111/Arduino_SecureElement.git
-          version: f5a23964a1c70048e48d5ed2d2657004446f0e3d
-        - source-url: https://github.com/fabik111/Arduino_CloudUtils.git
-          version: a8b52eaf500c63b2e8bd3e4b6f6c77b70fc3e65d
-        - source-url: https://github.com/arduino-libraries/Arduino_KVStore.git
+          version: 0.1.8
+        - name: Arduino_KVStore
+          version: 1.0.0
+        - source-url: https://github.com/arduino-libraries/Arduino_ConnectionHandler.git
+          version: 0314cf54593029aea05bb8c179e40a26128f7d67
+        - source-url: https://github.com/arduino-libraries/Arduino_SecureElement.git
+          version: 4900febf84435c1a06bb13451bced3bac6f16e76
+        - source-url: https://github.com/arduino-libraries/Arduino_CloudUtils.git
+          version: 2e2facc2209b66905c180ec0058ef8b083912278
         - source-url: https://github.com/arduino-libraries/Arduino_UniqueHWId.git
+          version: 7e1bfeb586cac00f043c39997a1e9937ed8152b0
         - source-url: https://github.com/arduino-libraries/Arduino_NetworkConfigurator.git
+          version: d887ec0fd15d3d6bd427fa3e2c4f95b582f964a0
       # sketch paths to compile (recursive) for all boards
       UNIVERSAL_SKETCH_PATHS: |
         - examples/utility/Provisioning_2.0
@@ -82,53 +87,82 @@ jobs:
             platforms: |
               # Install samd and mbed_nano platform via Boards Manager
               - name: arduino:samd
+                version: 1.8.14
               - name: arduino:mbed_nano
+                version: 4.2.4
             libraries: |
               - name: RTCZero
-              - source-url: https://github.com/andreagilardoni/WiFiNINA.git
-                version: 31616ac5a30f6281c68f982bc39800771b2fbaeb
-              - name: Arduino_JSON
-              - source-url: https://github.com/adafruit/Adafruit_SleepyDog.git
+                version: 1.6.0
+              - name: ArduinoECCX08
+                version: 1.3.8
+              - name: Adafruit SleepyDog Library
+                version: 1.6.5
+              - source-url: https://github.com/arduino-libraries/ArduinoBearSSL.git
+                version: a891ad3cb15bca3d080adc8188a63277f92fa81c
+              - source-url: https://github.com/arduino-libraries/WiFiNINA.git
+                version: 69e786c5c73fe94b7f408853550f6f151cfc58b0
           # Portenta
           - board:
               type: mbed_portenta
             platforms: |
               # Install mbed_portenta platform via Boards Manager
               - name: arduino:mbed_portenta
+                version: 4.2.4
             libraries: |
               - name: Arduino_Cellular
+                version: 1.2.1
+              - name: ArduinoECCX08
+                version: 1.3.8
+              - source-url: https://github.com/arduino-libraries/ArduinoBearSSL.git
+                version: a891ad3cb15bca3d080adc8188a63277f92fa81c
           # Nicla Vision
           - board:
               type: mbed_nicla
             platforms: |
               # Install mbed_nicla platform via Boards Manager
               - name: arduino:mbed_nicla
+                version: 4.2.4
           # Opta
           - board:
               type: mbed_opta
             platforms: |
               # Install mbed_opta platform via Boards Manager
               - name: arduino:mbed_opta
+                version: 4.2.4
+            libraries: |
+              - name: ArduinoECCX08
+                version: 1.3.8
+              - source-url: https://github.com/arduino-libraries/ArduinoBearSSL.git
+                version: a891ad3cb15bca3d080adc8188a63277f92fa81c
           # GIGA
           - board:
               type: mbed_giga
             platforms: |
               # Install mbed_giga platform via Boards Manager
               - name: arduino:mbed_giga
+                version: 4.2.4
+            libraries: |
+              - name: ArduinoECCX08
+                version: 1.3.8
+              - source-url: https://github.com/arduino-libraries/ArduinoBearSSL.git
+                version: a891ad3cb15bca3d080adc8188a63277f92fa81c
           # Portenta C33
           - board:
               type: renesas_portenta
             platforms: |
               # Install renesas_portenta platform via Boards Manager
               - name: arduino:renesas_portenta
+                version: 1.4.1
             libraries: |
               - name: Arduino_Cellular
+                version: 1.2.1
           # UNO R4 WiFi
           - board:
               type: renesas_uno
             platforms: |
               # Install renesas_uno platform via Boards Manager
               - name: arduino:renesas_uno
+                version: 1.4.1
 
     steps:
       - name: Checkout

From b7e20b791ea581d349113b672e9eca0e23e6601f Mon Sep 17 00:00:00 2001
From: pennam <m.pennasilico@arduino.cc>
Date: Wed, 16 Apr 2025 14:45:20 +0200
Subject: [PATCH 14/14] Provisioning v0.1.1

---
 examples/utility/Provisioning_2.0/Provisioning_2.0.ino | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/examples/utility/Provisioning_2.0/Provisioning_2.0.ino b/examples/utility/Provisioning_2.0/Provisioning_2.0.ino
index c6ccc5c9d..5f9e2831c 100644
--- a/examples/utility/Provisioning_2.0/Provisioning_2.0.ino
+++ b/examples/utility/Provisioning_2.0/Provisioning_2.0.ino
@@ -15,7 +15,7 @@
 #include <utility/SElementArduinoCloudCertificate.h>
 #include "Utility/LEDFeedback/LEDFeedback.h"
 
-const char *SKETCH_VERSION = "0.1.0";
+const char *SKETCH_VERSION = "0.1.1";
 
 enum class DeviceState {
     HARDWARE_CHECK,