[QPG] QPG SDK feature updates (#33436)

* [QPG] QPG SDK feature updates.

* Add LED behavior to identify effects
* Add saving total operational hours in NVM
* Enable reset sequence to trigger BLE advertisements for lock application
* Fix powercycle counting with JLink Reset triggers
* Update status LED behaviour
* Add missing python requirements
* Fix filename in ot-qorvo
* Update CurrentHue and CurrentSaturation storage
* Adjust .zap after TE2
* Disable sleep for FTD devices
* Update Matter software version to include used Matter standard and SDK version
* Fix -Werror=undef on Qorvo variables using GN build flow
* Restore hsv instaed off xy color as we are now saving hsv not xy
* Enable momentary switch feature for generic switch endpoint
* Update attributes and commands to comply with General Diagnostic Cluster requirements
* Remove versions for OTA image from qpg_sdk files
* Move location of mbedtls-config
* Add BLE manager adjustments
* Fix light-switch and thermostat product IDs
* Trigger advertising on greater or equal than 3 resets

* [QPG] Fix CI checks

* Bump ot-qorvo
* Fix paths in zap files
* Remove persistent-storage example from qpg action
* Sync light.matter with light.zap
* Update qpg_sdk repo submodule
* Remove shell example from qpg action
* Fix missing argument declaration and assignment
* Restyled by gn

---------

Co-authored-by: Adam Bodurka <adam.bodurka@qorvo.com>
Co-authored-by: Andrei Litvin <andy314@gmail.com>
diff --git a/.github/workflows/examples-qpg.yaml b/.github/workflows/examples-qpg.yaml
index 2448a0f..bb800eb 100644
--- a/.github/workflows/examples-qpg.yaml
+++ b/.github/workflows/examples-qpg.yaml
@@ -63,8 +63,6 @@
                         --enable-flashbundle \
                         --target qpg-qpg6105-lock \
                         --target qpg-qpg6105-light \
-                        --target qpg-qpg6105-shell \
-                        --target qpg-qpg6105-persistent-storage \
                         --target qpg-qpg6105-light-switch \
                         --target qpg-qpg6105-thermostat \
                         build \
diff --git a/config/qpg/chip-gn/build.sh b/config/qpg/chip-gn/build.sh
index ce0306c..541da26 100755
--- a/config/qpg/chip-gn/build.sh
+++ b/config/qpg/chip-gn/build.sh
@@ -23,6 +23,7 @@
 GN_ROOT_TARGET=$(dirname "$0")
 CHIP_ROOT=$GN_ROOT_TARGET/../../../
 OUTDIR=$CHIP_ROOT/out
+GN_ARGS="qpg_target_ic=\"qpg6105\" qpg_flavour=\"_ext_flash\""
 
 mkdir -p "$OUTDIR"
 gn \
@@ -33,6 +34,7 @@
     --export-compile-commands \
     gen \
     --check \
+    --args="$GN_ARGS" \
     --fail-on-unused-args \
     "$OUTDIR"
 ninja -C "$OUTDIR"
diff --git a/examples/light-switch-app/qpg/BUILD.gn b/examples/light-switch-app/qpg/BUILD.gn
index 055cfd4..84ec9dd 100644
--- a/examples/light-switch-app/qpg/BUILD.gn
+++ b/examples/light-switch-app/qpg/BUILD.gn
@@ -137,7 +137,7 @@
     }
   }
 
-  ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}/QorvoStack_${qpg_target_ic}.ld"
+  ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}${qpg_flavour}/QorvoStack_${qpg_target_ic}${qpg_flavour}.ld"
 
   inputs = [ ldscript ]
 
diff --git a/examples/light-switch-app/qpg/args.gni b/examples/light-switch-app/qpg/args.gni
index 64db098..9a69cd1 100644
--- a/examples/light-switch-app/qpg/args.gni
+++ b/examples/light-switch-app/qpg/args.gni
@@ -30,7 +30,7 @@
 chip_stack_lock_tracking = "none"
 
 matter_device_vid = "0xFFF1"
-matter_device_pid = "0x8006"
+matter_device_pid = "0x8004"
 
 pw_log_BACKEND = "${chip_root}/src/lib/support/pw_log_chip"
 pw_assert_BACKEND = "$dir_pw_assert_log:check_backend"
diff --git a/examples/light-switch-app/qpg/include/CHIPProjectConfig.h b/examples/light-switch-app/qpg/include/CHIPProjectConfig.h
index b6d7572..09df64a 100644
--- a/examples/light-switch-app/qpg/include/CHIPProjectConfig.h
+++ b/examples/light-switch-app/qpg/include/CHIPProjectConfig.h
@@ -40,9 +40,18 @@
  * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION
  *
  * A uint32_t identifying the software version running on the device.
+ * First two bytes are reflecting the Matter standard
+ * Last two bytes are reflecting the SDK version of which the first nibble of the first byte represents the major
+ * version and the second nibble of the first byte has the minor number. The last byte holds the patch number.
+ * example for SDK v0.1.5 with Matter v1.2 standard:
+ * 0x01020105
  */
 #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION
-#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x0003 // Can't be removed, needed for OTA file generation.
+#ifndef OTA_TEST_IMAGE
+#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x01020105
+#else
+#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x01020106
+#endif
 #endif
 
 /**
@@ -53,7 +62,11 @@
  * {MAJOR_VERSION}.0d{MINOR_VERSION}
  */
 #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING
-#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.1" // Can't be removed, needed for OTA file generation.
+#ifndef OTA_TEST_IMAGE
+#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.2-0.1.5"
+#else
+#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.2-0.1.6"
+#endif
 #endif
 
 /**
diff --git a/examples/light-switch-app/qpg/include/SwitchManager.h b/examples/light-switch-app/qpg/include/SwitchManager.h
index 3f429f0..41eedd1 100644
--- a/examples/light-switch-app/qpg/include/SwitchManager.h
+++ b/examples/light-switch-app/qpg/include/SwitchManager.h
@@ -54,8 +54,8 @@
     };

 

     void Init(void);

-    static void GenericSwitchInitialPress(void);

-    static void GenericSwitchReleasePress(void);

+    static void GenericSwitchInitialPressHandler(AppEvent * aEvent);

+    static void GenericSwitchReleasePressHandler(AppEvent * aEvent);

     static void ToggleHandler(AppEvent * aEvent);

     static void LevelHandler(AppEvent * aEvent);

     static void ColorHandler(AppEvent * aEvent);

diff --git a/examples/light-switch-app/qpg/src/AppTask.cpp b/examples/light-switch-app/qpg/src/AppTask.cpp
index 318e61b..4be2f4e 100644
--- a/examples/light-switch-app/qpg/src/AppTask.cpp
+++ b/examples/light-switch-app/qpg/src/AppTask.cpp
@@ -297,13 +297,13 @@
     case APP_FUNCTION2_SWITCH: {
         if (!btnPressed)
         {
-            ChipLogProgress(NotSpecified, "Switch initial press");
-            SwitchMgr().GenericSwitchInitialPress();
+            ChipLogProgress(NotSpecified, "Switch release press");
+            button_event.Handler = SwitchMgr().GenericSwitchReleasePressHandler;
         }
         else
         {
-            ChipLogProgress(NotSpecified, "Switch release press");
-            SwitchMgr().GenericSwitchReleasePress();
+            ChipLogProgress(NotSpecified, "Switch initial press");
+            button_event.Handler = SwitchMgr().GenericSwitchInitialPressHandler;
         }
         break;
     }
@@ -516,11 +516,15 @@
     // If the system has ble connection(s) uptill the stage above, THEN blink
     // the LEDs at an even rate of 100ms.
     //
-    // Otherwise, blink the LED ON for a very short time.
+    // Otherwise, turn the LED OFF.
     if (sIsThreadProvisioned && sIsThreadEnabled)
     {
         qvIO_LedSet(SYSTEM_STATE_LED, true);
     }
+    else if (sIsThreadProvisioned && !sIsThreadEnabled)
+    {
+        qvIO_LedBlink(SYSTEM_STATE_LED, 950, 50);
+    }
     else if (sHaveBLEConnections)
     {
         qvIO_LedBlink(SYSTEM_STATE_LED, 100, 100);
@@ -532,7 +536,7 @@
     else
     {
         // not commissioned yet
-        qvIO_LedBlink(SYSTEM_STATE_LED, 50, 950);
+        qvIO_LedSet(SYSTEM_STATE_LED, false);
     }
 }
 
diff --git a/examples/light-switch-app/qpg/src/SwitchManager.cpp b/examples/light-switch-app/qpg/src/SwitchManager.cpp
index 45d7079..58b2f1d 100644
--- a/examples/light-switch-app/qpg/src/SwitchManager.cpp
+++ b/examples/light-switch-app/qpg/src/SwitchManager.cpp
@@ -107,20 +107,40 @@
     DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast<intptr_t>(data));

 }

 

-void SwitchManager::GenericSwitchInitialPress(void)

+void SwitchManager::GenericSwitchInitialPressHandler(AppEvent * aEvent)

 {

     // Press moves Position from 0 (idle) to 1 (press)

     uint8_t newPosition = 1;

 

-    SystemLayer().ScheduleLambda(

-        [newPosition] { chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(GENERICSWITCH_ENDPOINT_ID, newPosition); });

+    if (aEvent->Type != AppEvent::kEventType_Button)

+    {

+        ChipLogError(NotSpecified, "Event type not supported!");

+        return;

+    }

+

+    ChipLogProgress(NotSpecified, "GenericSwitchInitialPress new position %d", newPosition);

+    SystemLayer().ScheduleLambda([newPosition] {

+        chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(GENERICSWITCH_ENDPOINT_ID, newPosition);

+        // InitialPress event takes newPosition as event data

+        chip::app::Clusters::SwitchServer::Instance().OnInitialPress(GENERICSWITCH_ENDPOINT_ID, newPosition);

+    });

 }

 

-void SwitchManager::GenericSwitchReleasePress(void)

+void SwitchManager::GenericSwitchReleasePressHandler(AppEvent * aEvent)

 {

     // Release moves Position from 1 (press) to 0

     uint8_t newPosition = 0;

 

-    SystemLayer().ScheduleLambda(

-        [newPosition] { chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(GENERICSWITCH_ENDPOINT_ID, newPosition); });

+    if (aEvent->Type != AppEvent::kEventType_Button)

+    {

+        ChipLogError(NotSpecified, "Event type not supported!");

+        return;

+    }

+

+    ChipLogProgress(NotSpecified, "GenericSwitchReleasePress new position %d", newPosition);

+    SystemLayer().ScheduleLambda([newPosition] {

+        chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(GENERICSWITCH_ENDPOINT_ID, newPosition);

+        // Short Release event takes newPosition as event data

+        chip::app::Clusters::SwitchServer::Instance().OnShortRelease(GENERICSWITCH_ENDPOINT_ID, newPosition);

+    });

 }

diff --git a/examples/light-switch-app/qpg/zap/switch.matter b/examples/light-switch-app/qpg/zap/switch.matter
index e3da4bf..2593757 100644
--- a/examples/light-switch-app/qpg/zap/switch.matter
+++ b/examples/light-switch-app/qpg/zap/switch.matter
@@ -2404,6 +2404,8 @@
     ram      attribute lastNetworkingStatus;
     ram      attribute lastNetworkID;
     ram      attribute lastConnectErrorValue;
+    callback attribute supportedThreadFeatures;
+    callback attribute threadVersion;
     callback attribute generatedCommandList;
     callback attribute acceptedCommandList;
     callback attribute eventList;
@@ -2441,19 +2443,21 @@
     callback attribute networkInterfaces;
     callback attribute rebootCount;
     callback attribute upTime;
+    callback attribute totalOperationalHours;
     callback attribute bootReason;
     callback attribute activeHardwareFaults;
     callback attribute activeRadioFaults;
     callback attribute activeNetworkFaults;
-    ram      attribute testEventTriggersEnabled default = 0;
+    callback attribute testEventTriggersEnabled default = false;
     callback attribute generatedCommandList;
     callback attribute acceptedCommandList;
-    callback attribute eventList;
     callback attribute attributeList;
     callback attribute featureMap;
     callback attribute clusterRevision;
 
     handle command TestEventTrigger;
+    handle command TimeSnapshot;
+    handle command TimeSnapshotResponse;
   }
 
   server cluster SoftwareDiagnostics {
@@ -2729,13 +2733,15 @@
   }
 
   server cluster Switch {
+    emits event InitialPress;
+    emits event ShortRelease;
     ram      attribute numberOfPositions default = 2;
     ram      attribute currentPosition default = 0;
     callback attribute generatedCommandList;
     callback attribute acceptedCommandList;
     callback attribute eventList;
     callback attribute attributeList;
-    ram      attribute featureMap default = 1;
+    ram      attribute featureMap default = 6;
     ram      attribute clusterRevision default = 1;
   }
 }
diff --git a/examples/light-switch-app/qpg/zap/switch.zap b/examples/light-switch-app/qpg/zap/switch.zap
index 9a33d73..b04ff64 100644
--- a/examples/light-switch-app/qpg/zap/switch.zap
+++ b/examples/light-switch-app/qpg/zap/switch.zap
@@ -1623,6 +1623,38 @@
               "reportableChange": 0
             },
             {
+              "name": "SupportedThreadFeatures",
+              "code": 9,
+              "mfgCode": null,
+              "side": "server",
+              "type": "ThreadCapabilitiesBitmap",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ThreadVersion",
+              "code": 10,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
               "name": "GeneratedCommandList",
               "code": 65528,
               "mfgCode": null,
@@ -1859,6 +1891,22 @@
               "source": "client",
               "isIncoming": 1,
               "isEnabled": 1
+            },
+            {
+              "name": "TimeSnapshot",
+              "code": 1,
+              "mfgCode": null,
+              "source": "client",
+              "isIncoming": 1,
+              "isEnabled": 1
+            },
+            {
+              "name": "TimeSnapshotResponse",
+              "code": 2,
+              "mfgCode": null,
+              "source": "server",
+              "isIncoming": 0,
+              "isEnabled": 1
             }
           ],
           "attributes": [
@@ -1874,8 +1922,8 @@
               "bounded": 0,
               "defaultValue": null,
               "reportable": 1,
-              "minInterval": 1,
-              "maxInterval": 65534,
+              "minInterval": 0,
+              "maxInterval": 65344,
               "reportableChange": 0
             },
             {
@@ -1890,8 +1938,8 @@
               "bounded": 0,
               "defaultValue": null,
               "reportable": 1,
-              "minInterval": 1,
-              "maxInterval": 65534,
+              "minInterval": 0,
+              "maxInterval": 65344,
               "reportableChange": 0
             },
             {
@@ -1911,6 +1959,22 @@
               "reportableChange": 0
             },
             {
+              "name": "TotalOperationalHours",
+              "code": 3,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int32u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0x00000000",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
               "name": "BootReason",
               "code": 4,
               "mfgCode": null,
@@ -1981,10 +2045,10 @@
               "side": "server",
               "type": "boolean",
               "included": 1,
-              "storageOption": "RAM",
+              "storageOption": "External",
               "singleton": 0,
               "bounded": 0,
-              "defaultValue": "0",
+              "defaultValue": "false",
               "reportable": 1,
               "minInterval": 1,
               "maxInterval": 65534,
@@ -2023,22 +2087,6 @@
               "reportableChange": 0
             },
             {
-              "name": "EventList",
-              "code": 65530,
-              "mfgCode": null,
-              "side": "server",
-              "type": "array",
-              "included": 1,
-              "storageOption": "External",
-              "singleton": 0,
-              "bounded": 0,
-              "defaultValue": null,
-              "reportable": 1,
-              "minInterval": 1,
-              "maxInterval": 65534,
-              "reportableChange": 0
-            },
-            {
               "name": "AttributeList",
               "code": 65531,
               "mfgCode": null,
@@ -2082,8 +2130,8 @@
               "bounded": 0,
               "defaultValue": null,
               "reportable": 1,
-              "minInterval": 1,
-              "maxInterval": 65534,
+              "minInterval": 0,
+              "maxInterval": 65344,
               "reportableChange": 0
             }
           ],
@@ -6045,7 +6093,7 @@
               "storageOption": "RAM",
               "singleton": 0,
               "bounded": 0,
-              "defaultValue": "1",
+              "defaultValue": "6",
               "reportable": 1,
               "minInterval": 1,
               "maxInterval": 65534,
@@ -6067,6 +6115,22 @@
               "maxInterval": 65534,
               "reportableChange": 0
             }
+          ],
+          "events": [
+            {
+              "name": "InitialPress",
+              "code": 1,
+              "mfgCode": null,
+              "side": "server",
+              "included": 1
+            },
+            {
+              "name": "ShortRelease",
+              "code": 3,
+              "mfgCode": null,
+              "side": "server",
+              "included": 1
+            }
           ]
         }
       ]
diff --git a/examples/lighting-app/qpg/BUILD.gn b/examples/lighting-app/qpg/BUILD.gn
index c835e0b..2677357 100644
--- a/examples/lighting-app/qpg/BUILD.gn
+++ b/examples/lighting-app/qpg/BUILD.gn
@@ -140,7 +140,7 @@
     }
   }
 
-  ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}/QorvoStack_${qpg_target_ic}.ld"
+  ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}${qpg_flavour}/QorvoStack_${qpg_target_ic}${qpg_flavour}.ld"
 
   inputs = [ ldscript ]
 
diff --git a/examples/lighting-app/qpg/include/AppTask.h b/examples/lighting-app/qpg/include/AppTask.h
index 1021b7a..52023c2 100644
--- a/examples/lighting-app/qpg/include/AppTask.h
+++ b/examples/lighting-app/qpg/include/AppTask.h
@@ -63,6 +63,7 @@
 
     static void LightingActionEventHandler(AppEvent * aEvent);
     static void TimerEventHandler(chip::System::Layer * aLayer, void * aAppState);
+    static void TotalHoursTimerHandler(chip::System::Layer * aLayer, void * aAppState);
 
     static void MatterEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg);
     static void UpdateLEDs(void);
diff --git a/examples/lighting-app/qpg/include/CHIPProjectConfig.h b/examples/lighting-app/qpg/include/CHIPProjectConfig.h
index 2e23b21..f20fde3 100644
--- a/examples/lighting-app/qpg/include/CHIPProjectConfig.h
+++ b/examples/lighting-app/qpg/include/CHIPProjectConfig.h
@@ -40,9 +40,18 @@
  * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION
  *
  * A uint32_t identifying the software version running on the device.
+ * First two bytes are reflecting the Matter standard
+ * Last two bytes are reflecting the SDK version of which the first nibble of the first byte represents the major
+ * version and the second nibble of the first byte has the minor number. The last byte holds the patch number.
+ * example for SDK v0.1.5 with Matter v1.2 standard:
+ * 0x01020105
  */
 #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION
-#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x0003
+#ifndef OTA_TEST_IMAGE
+#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x01020105
+#else
+#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x01020106
+#endif
 #endif
 
 /**
@@ -53,8 +62,13 @@
  * {MAJOR_VERSION}.0d{MINOR_VERSION}
  */
 #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING
-#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.1"
+#ifndef OTA_TEST_IMAGE
+#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.2-0.1.5"
+#else
+#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.2-0.1.6"
 #endif
+#endif
+
 /**
  * CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
  *
diff --git a/examples/lighting-app/qpg/src/AppTask.cpp b/examples/lighting-app/qpg/src/AppTask.cpp
index 2bc0ffa..d870ea2 100644
--- a/examples/lighting-app/qpg/src/AppTask.cpp
+++ b/examples/lighting-app/qpg/src/AppTask.cpp
@@ -28,7 +28,6 @@
 #include "AppEvent.h"
 #include "AppTask.h"
 #include "ota.h"
-#include "powercycle_counting.h"
 
 #include <app/server/OnboardingCodesUtil.h>
 
@@ -70,6 +69,7 @@
 #define APP_TASK_PRIORITY 2
 #define APP_EVENT_QUEUE_SIZE 10
 #define QPG_LIGHT_ENDPOINT_ID (1)
+#define TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS (1 * 3600) // this value must be multiplication of 3600
 
 static uint8_t countdown = 0;
 
@@ -96,18 +96,19 @@
 Clusters::Identify::EffectIdentifierEnum sIdentifyEffect = Clusters::Identify::EffectIdentifierEnum::kStopEffect;
 chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider;
 
-// Define a custom attribute persister which makes actual write of the attribute value
+// Define a custom attribute persister which makes actual write of the ColorX attribute value
 // to the non-volatile storage only when it has remained constant for 5 seconds. This is to reduce
-// the flash wearout when the attribute changes frequently as a result of commands.
+// the flash wearout when the attribute changes frequently as a result of MoveToLevel command.
 // DeferredAttribute object describes a deferred attribute, but also holds a buffer with a value to
 // be written, so it must live so long as the DeferredAttributePersistenceProvider object.
 //
-DeferredAttribute gPersisters[] = { DeferredAttribute(ConcreteAttributePath(kLightEndpointId, Clusters::ColorControl::Id,
-                                                                            Clusters::ColorControl::Attributes::CurrentX::Id)),
-                                    DeferredAttribute(ConcreteAttributePath(kLightEndpointId, Clusters::ColorControl::Id,
-                                                                            Clusters::ColorControl::Attributes::CurrentY::Id)),
-                                    DeferredAttribute(ConcreteAttributePath(kLightEndpointId, Clusters::LevelControl::Id,
-                                                                            Clusters::LevelControl::Attributes::CurrentLevel::Id))
+DeferredAttribute gPersisters[] = {
+    DeferredAttribute(
+        ConcreteAttributePath(kLightEndpointId, Clusters::ColorControl::Id, Clusters::ColorControl::Attributes::CurrentHue::Id)),
+    DeferredAttribute(ConcreteAttributePath(kLightEndpointId, Clusters::ColorControl::Id,
+                                            Clusters::ColorControl::Attributes::CurrentSaturation::Id)),
+    DeferredAttribute(
+        ConcreteAttributePath(kLightEndpointId, Clusters::LevelControl::Id, Clusters::LevelControl::Attributes::CurrentLevel::Id))
 
 };
 
@@ -342,6 +343,14 @@
     sIsBLEAdvertisingEnabled = ConnectivityMgr().IsBLEAdvertisingEnabled();
     UpdateLEDs();
 
+    err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS),
+                                                      TotalHoursTimerHandler, this);
+
+    if (err != CHIP_NO_ERROR)
+    {
+        ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err));
+    }
+
     return err;
 }
 
@@ -438,6 +447,32 @@
     sAppTask.PostEvent(&event);
 }
 
+void AppTask::TotalHoursTimerHandler(chip::System::Layer * aLayer, void * aAppState)
+{
+    ChipLogProgress(NotSpecified, "HourlyTimer");
+
+    CHIP_ERROR err;
+    uint32_t totalOperationalHours = 0;
+
+    if (ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours) == CHIP_NO_ERROR)
+    {
+        ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours +
+                                                      (TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS / 3600));
+    }
+    else
+    {
+        ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node");
+    }
+
+    err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS),
+                                                      TotalHoursTimerHandler, nullptr);
+
+    if (err != CHIP_NO_ERROR)
+    {
+        ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err));
+    }
+}
+
 void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
 {
     if (aEvent->Type != AppEvent::kEventType_Timer)
@@ -670,11 +705,15 @@
     // If the system has ble connection(s) uptill the stage above, THEN blink
     // the LEDs at an even rate of 100ms.
     //
-    // Otherwise, blink the LED ON for a very short time.
+    // Otherwise, turn the LED OFF.
     if (sIsThreadProvisioned && sIsThreadEnabled)
     {
         qvIO_LedSet(SYSTEM_STATE_LED, true);
     }
+    else if (sIsThreadProvisioned && !sIsThreadEnabled)
+    {
+        qvIO_LedBlink(SYSTEM_STATE_LED, 950, 50);
+    }
     else if (sHaveBLEConnections)
     {
         qvIO_LedBlink(SYSTEM_STATE_LED, 100, 100);
@@ -686,7 +725,7 @@
     else
     {
         // not commisioned yet
-        qvIO_LedBlink(SYSTEM_STATE_LED, 50, 950);
+        qvIO_LedSet(SYSTEM_STATE_LED, false);
     }
 }
 
diff --git a/examples/lighting-app/qpg/src/ZclCallbacks.cpp b/examples/lighting-app/qpg/src/ZclCallbacks.cpp
index e2255bd..319ea28 100644
--- a/examples/lighting-app/qpg/src/ZclCallbacks.cpp
+++ b/examples/lighting-app/qpg/src/ZclCallbacks.cpp
@@ -160,8 +160,6 @@
  */
 void emberAfOnOffClusterInitCallback(EndpointId endpoint)
 {
-    uint8_t levelValue;
-    XyColor_t xy;
     bool onOffValue = false;
     app::DataModel::Nullable<uint8_t> currentLevel;
     Protocols::InteractionModel::Status status;
@@ -181,20 +179,11 @@
         return;
     }
 
-    levelValue = currentLevel.Value();
-
-    status = ColorControl::Attributes::CurrentY::Get(endpoint, &xy.y);
-    if (status != Protocols::InteractionModel::Status::Success)
-    {
-        return;
-    }
-    status = ColorControl::Attributes::CurrentX::Get(endpoint, &xy.x);
-    if (status != Protocols::InteractionModel::Status::Success)
-    {
-        return;
-    }
-    ChipLogProgress(Zcl, "restore level: %u", levelValue);
-    LightingMgr().InitiateAction(LightingManager::LEVEL_ACTION, 0, 1, &levelValue);
-    ChipLogProgress(Zcl, "restore XY color: %u|%u", xy.x, xy.y);
-    LightingMgr().InitiateAction(LightingManager::COLOR_ACTION_XY, 0, sizeof(xy), (uint8_t *) &xy);
+    HsvColor_t hsv;
+    status = ColorControl::Attributes::CurrentHue::Get(endpoint, &hsv.h);
+    assert(status == Protocols::InteractionModel::Status::Success);
+    status = ColorControl::Attributes::CurrentSaturation::Get(endpoint, &hsv.s);
+    assert(status == Protocols::InteractionModel::Status::Success);
+    ChipLogProgress(Zcl, "restore HSV color: %u|%u", hsv.h, hsv.s);
+    LightingMgr().InitiateAction(LightingManager::COLOR_ACTION_HSV, 0, sizeof(hsv), (uint8_t *) &hsv);
 }
diff --git a/examples/lighting-app/qpg/zap/light.matter b/examples/lighting-app/qpg/zap/light.matter
index 0fb3d8b..72387fd 100644
--- a/examples/lighting-app/qpg/zap/light.matter
+++ b/examples/lighting-app/qpg/zap/light.matter
@@ -2035,6 +2035,8 @@
     ram      attribute lastNetworkingStatus;
     ram      attribute lastNetworkID;
     ram      attribute lastConnectErrorValue;
+    callback attribute supportedThreadFeatures;
+    callback attribute threadVersion;
     callback attribute generatedCommandList;
     callback attribute acceptedCommandList;
     callback attribute attributeList;
@@ -2070,6 +2072,7 @@
     callback attribute networkInterfaces;
     callback attribute rebootCount;
     callback attribute upTime;
+    callback attribute totalOperationalHours;
     callback attribute bootReason;
     callback attribute activeHardwareFaults;
     callback attribute activeRadioFaults;
@@ -2296,7 +2299,7 @@
     callback attribute acceptedCommandList;
     callback attribute attributeList;
     ram      attribute featureMap default = 1;
-    ram      attribute clusterRevision default = 5;
+    ram      attribute clusterRevision default = 6;
 
     handle command Off;
     handle command On;
@@ -2343,11 +2346,11 @@
   }
 
   server cluster ColorControl {
-    ram      attribute currentHue default = 0x00;
-    ram      attribute currentSaturation default = 0x00;
+    persist  attribute currentHue default = 0x00;
+    persist  attribute currentSaturation default = 0x00;
     ram      attribute remainingTime default = 0x0000;
-    persist  attribute currentX default = 0x616B;
-    persist  attribute currentY default = 0x607D;
+    ram      attribute currentX default = 0x616B;
+    ram      attribute currentY default = 0x607D;
     ram      attribute colorTemperatureMireds default = 0x00FA;
     ram      attribute colorMode default = 0x01;
     ram      attribute options default = 0x00;
diff --git a/examples/lighting-app/qpg/zap/light.zap b/examples/lighting-app/qpg/zap/light.zap
index 21dbe02..2c0a76a 100644
--- a/examples/lighting-app/qpg/zap/light.zap
+++ b/examples/lighting-app/qpg/zap/light.zap
@@ -1543,6 +1543,38 @@
               "reportableChange": 0
             },
             {
+              "name": "SupportedThreadFeatures",
+              "code": 9,
+              "mfgCode": null,
+              "side": "server",
+              "type": "ThreadCapabilitiesBitmap",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ThreadVersion",
+              "code": 10,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
               "name": "GeneratedCommandList",
               "code": 65528,
               "mfgCode": null,
@@ -1815,6 +1847,22 @@
               "reportableChange": 0
             },
             {
+              "name": "TotalOperationalHours",
+              "code": 3,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int32u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0x00000000",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
               "name": "BootReason",
               "code": 4,
               "mfgCode": null,
@@ -4663,7 +4711,7 @@
               "storageOption": "RAM",
               "singleton": 0,
               "bounded": 0,
-              "defaultValue": "5",
+              "defaultValue": "6",
               "reportable": 1,
               "minInterval": 0,
               "maxInterval": 65344,
@@ -5262,7 +5310,7 @@
               "side": "server",
               "type": "int8u",
               "included": 1,
-              "storageOption": "RAM",
+              "storageOption": "NVM",
               "singleton": 0,
               "bounded": 0,
               "defaultValue": "0x00",
@@ -5278,7 +5326,7 @@
               "side": "server",
               "type": "int8u",
               "included": 1,
-              "storageOption": "RAM",
+              "storageOption": "NVM",
               "singleton": 0,
               "bounded": 0,
               "defaultValue": "0x00",
@@ -5310,7 +5358,7 @@
               "side": "server",
               "type": "int16u",
               "included": 1,
-              "storageOption": "NVM",
+              "storageOption": "RAM",
               "singleton": 0,
               "bounded": 0,
               "defaultValue": "0x616B",
@@ -5326,7 +5374,7 @@
               "side": "server",
               "type": "int16u",
               "included": 1,
-              "storageOption": "NVM",
+              "storageOption": "RAM",
               "singleton": 0,
               "bounded": 0,
               "defaultValue": "0x607D",
diff --git a/examples/lock-app/qpg/BUILD.gn b/examples/lock-app/qpg/BUILD.gn
index 3079487..3db4d0c 100644
--- a/examples/lock-app/qpg/BUILD.gn
+++ b/examples/lock-app/qpg/BUILD.gn
@@ -54,6 +54,7 @@
     "${chip_root}/src/app/clusters/general-diagnostics-server/GenericFaultTestEventTriggerHandler.cpp",
     "${examples_plat_dir}/app/main.cpp",
     "${examples_plat_dir}/ota/ota.cpp",
+    "${examples_plat_dir}/powercycle_counting.c",
     "src/AppTask.cpp",
     "src/BoltLockManager.cpp",
     "src/ZclCallbacks.cpp",
@@ -83,7 +84,7 @@
     "${examples_plat_dir}/ota",
   ]
 
-  defines = []
+  defines = [ "GP_APP_DIVERSITY_POWERCYCLECOUNTING" ]
 
   if (chip_enable_pw_rpc) {
     defines += [
@@ -137,7 +138,7 @@
     }
   }
 
-  ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}/QorvoStack_${qpg_target_ic}.ld"
+  ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}${qpg_flavour}/QorvoStack_${qpg_target_ic}${qpg_flavour}.ld"
 
   inputs = [ ldscript ]
 
diff --git a/examples/lock-app/qpg/include/AppTask.h b/examples/lock-app/qpg/include/AppTask.h
index b4ede0e..a743a1c 100644
--- a/examples/lock-app/qpg/include/AppTask.h
+++ b/examples/lock-app/qpg/include/AppTask.h
@@ -50,6 +50,7 @@
     void UpdateClusterState();
 
     static void ButtonEventHandler(uint8_t btnIdx, bool btnPressed);
+    static void OpenCommissioning(intptr_t arg);
 
 private:
     friend AppTask & GetAppTask(void);
@@ -68,6 +69,7 @@
     static void LockActionEventHandler(AppEvent * aEvent);
     static void JammedLockEventHandler(AppEvent * aEvent);
     static void TimerEventHandler(chip::System::Layer * aLayer, void * aAppState);
+    static void TotalHoursTimerHandler(chip::System::Layer * aLayer, void * aAppState);
 
     static void MatterEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg);
     static void UpdateLEDs(void);
diff --git a/examples/lock-app/qpg/include/CHIPProjectConfig.h b/examples/lock-app/qpg/include/CHIPProjectConfig.h
index 8262246..a35cfc0 100644
--- a/examples/lock-app/qpg/include/CHIPProjectConfig.h
+++ b/examples/lock-app/qpg/include/CHIPProjectConfig.h
@@ -40,9 +40,18 @@
  * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION
  *
  * A uint32_t identifying the software version running on the device.
+ * First two bytes are reflecting the Matter standard
+ * Last two bytes are reflecting the SDK version of which the first nibble of the first byte represents the major
+ * version and the second nibble of the first byte has the minor number. The last byte holds the patch number.
+ * example for SDK v0.1.5 with Matter v1.2 standard:
+ * 0x01020105
  */
 #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION
-#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x0003
+#ifndef OTA_TEST_IMAGE
+#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x01020105
+#else
+#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x01020106
+#endif
 #endif
 
 /**
@@ -53,8 +62,13 @@
  * {MAJOR_VERSION}.0d{MINOR_VERSION}
  */
 #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING
-#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.1"
+#ifndef OTA_TEST_IMAGE
+#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.2-0.1.5"
+#else
+#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.2-0.1.6"
 #endif
+#endif
+
 /**
  * CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
  *
diff --git a/examples/lock-app/qpg/src/AppTask.cpp b/examples/lock-app/qpg/src/AppTask.cpp
index 7f9d922..d2f3298 100644
--- a/examples/lock-app/qpg/src/AppTask.cpp
+++ b/examples/lock-app/qpg/src/AppTask.cpp
@@ -16,6 +16,11 @@
  *    limitations under the License.
  */
 
+#if !defined(GP_APP_DIVERSITY_POWERCYCLECOUNTING)
+#error This application requires powercycle counting.
+#endif
+
+#include "powercycle_counting.h"
 #include "qvIO.h"
 
 #include "AppConfig.h"
@@ -59,6 +64,9 @@
 #define APP_TASK_PRIORITY 2
 #define APP_EVENT_QUEUE_SIZE 10
 #define QPG_LOCK_ENDPOINT_ID (1)
+#define TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS (1 * 3600) // this value must be multiplication of 3600
+
+#define NMBR_OF_RESETS_BLE_ADVERTISING (3)
 
 namespace {
 TaskHandle_t sAppTaskHandle;
@@ -114,15 +122,26 @@
     switch (sIdentifyEffect)
     {
     case Clusters::Identify::EffectIdentifierEnum::kBlink:
+        ChipLogProgress(Zcl, "kBlink");
+        qvIO_LedBlink(LOCK_STATE_LED, 100, 100);
+        break;
     case Clusters::Identify::EffectIdentifierEnum::kBreathe:
+        ChipLogProgress(Zcl, "kBreathe");
+        qvIO_LedBlink(LOCK_STATE_LED, 500, 500);
+        break;
     case Clusters::Identify::EffectIdentifierEnum::kOkay:
+        ChipLogProgress(Zcl, "kOkay");
+        qvIO_LedBlink(LOCK_STATE_LED, 1000, 1000);
+        break;
     case Clusters::Identify::EffectIdentifierEnum::kChannelChange:
+        ChipLogProgress(Zcl, "kChannelChange");
         SystemLayer().ScheduleLambda([identify] {
             (void) chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds16(5), OnTriggerIdentifyEffectCompleted,
                                                                identify);
         });
         break;
     case Clusters::Identify::EffectIdentifierEnum::kFinishEffect:
+        ChipLogProgress(Zcl, "kFinishEffect");
         SystemLayer().ScheduleLambda([identify] {
             (void) chip::DeviceLayer::SystemLayer().CancelTimer(OnTriggerIdentifyEffectCompleted, identify);
             (void) chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds16(1), OnTriggerIdentifyEffectCompleted,
@@ -130,9 +149,11 @@
         });
         break;
     case Clusters::Identify::EffectIdentifierEnum::kStopEffect:
+        ChipLogProgress(Zcl, "kStopEffect");
         SystemLayer().ScheduleLambda(
             [identify] { (void) chip::DeviceLayer::SystemLayer().CancelTimer(OnTriggerIdentifyEffectCompleted, identify); });
         sIdentifyEffect = Clusters::Identify::EffectIdentifierEnum::kStopEffect;
+        qvIO_LedSet(LOCK_STATE_LED, false);
         break;
     default:
         ChipLogProgress(Zcl, "No identifier effect");
@@ -204,6 +225,21 @@
     chip::app::DnssdServer::Instance().SetExtendedDiscoveryTimeoutSecs(extDiscTimeoutSecs);
 #endif
 }
+
+void AppTask::OpenCommissioning(intptr_t arg)
+{
+    // Enable BLE advertisements
+
+    SystemLayer().ScheduleLambda([] {
+        CHIP_ERROR err;
+        err = chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow();
+        if (err == CHIP_NO_ERROR)
+        {
+            ChipLogProgress(NotSpecified, "BLE advertising started. Waiting for Pairing.");
+        }
+    });
+}
+
 CHIP_ERROR AppTask::Init()
 {
     CHIP_ERROR err = CHIP_NO_ERROR;
@@ -246,6 +282,14 @@
     sIsBLEAdvertisingEnabled = ConnectivityMgr().IsBLEAdvertisingEnabled();
     UpdateLEDs();
 
+    err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS),
+                                                      TotalHoursTimerHandler, this);
+
+    if (err != CHIP_NO_ERROR)
+    {
+        ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err));
+    }
+
     return err;
 }
 
@@ -363,6 +407,32 @@
     sAppTask.PostEvent(&event);
 }
 
+void AppTask::TotalHoursTimerHandler(chip::System::Layer * aLayer, void * aAppState)
+{
+    ChipLogProgress(NotSpecified, "HourlyTimer");
+
+    CHIP_ERROR err;
+    uint32_t totalOperationalHours = 0;
+
+    if (ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours) == CHIP_NO_ERROR)
+    {
+        ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours +
+                                                      (TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS / 3600));
+    }
+    else
+    {
+        ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node");
+    }
+
+    err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS),
+                                                      TotalHoursTimerHandler, nullptr);
+
+    if (err != CHIP_NO_ERROR)
+    {
+        ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err));
+    }
+}
+
 void AppTask::FunctionTimerEventHandler(AppEvent * aEvent)
 {
     if (aEvent->Type != AppEvent::kEventType_Timer)
@@ -660,11 +730,15 @@
     // If the system has ble connection(s) uptill the stage above, THEN blink
     // the LEDs at an even rate of 100ms.
     //
-    // Otherwise, blink the LED ON for a very short time.
+    // Otherwise, turn the LED OFF.
     if (sIsThreadProvisioned && sIsThreadEnabled)
     {
         qvIO_LedSet(SYSTEM_STATE_LED, true);
     }
+    else if (sIsThreadProvisioned && !sIsThreadEnabled)
+    {
+        qvIO_LedBlink(SYSTEM_STATE_LED, 950, 50);
+    }
     else if (sHaveBLEConnections)
     {
         qvIO_LedBlink(SYSTEM_STATE_LED, 100, 100);
@@ -676,7 +750,7 @@
     else
     {
         // not commisioned yet
-        qvIO_LedBlink(SYSTEM_STATE_LED, 50, 950);
+        qvIO_LedSet(SYSTEM_STATE_LED, false);
     }
 }
 
@@ -718,3 +792,21 @@
         break;
     }
 }
+
+extern "C" {
+void gpAppFramework_Reset_cbTriggerResetCountCompleted(void)
+{
+    uint8_t resetCount = gpAppFramework_Reset_GetResetCount();
+
+    ChipLogProgress(NotSpecified, "%d resets so far", resetCount);
+    if (resetCount >= NMBR_OF_RESETS_BLE_ADVERTISING)
+    {
+        // Open commissioning if no fabric was available
+        if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0)
+        {
+            ChipLogProgress(NotSpecified, "No fabrics, starting commissioning.");
+            AppTask::OpenCommissioning((intptr_t) 0);
+        }
+    }
+}
+}
diff --git a/examples/lock-app/qpg/zap/lock.matter b/examples/lock-app/qpg/zap/lock.matter
index cf98169..aa523a5 100644
--- a/examples/lock-app/qpg/zap/lock.matter
+++ b/examples/lock-app/qpg/zap/lock.matter
@@ -2258,6 +2258,8 @@
     ram      attribute lastNetworkingStatus;
     ram      attribute lastNetworkID;
     ram      attribute lastConnectErrorValue;
+    callback attribute supportedThreadFeatures;
+    callback attribute threadVersion;
     callback attribute generatedCommandList;
     callback attribute acceptedCommandList;
     callback attribute attributeList;
@@ -2293,6 +2295,7 @@
     callback attribute networkInterfaces;
     callback attribute rebootCount;
     callback attribute upTime;
+    callback attribute totalOperationalHours;
     callback attribute bootReason;
     callback attribute activeHardwareFaults;
     callback attribute activeRadioFaults;
@@ -2480,7 +2483,7 @@
     callback attribute acceptedCommandList;
     callback attribute eventList;
     callback attribute attributeList;
-    ram      attribute featureMap default = 0x0001;
+    ram      attribute featureMap default = 0x0000;
     ram      attribute clusterRevision default = 2;
   }
 }
@@ -2558,7 +2561,7 @@
     callback attribute acceptedCommandList;
     callback attribute attributeList;
     ram      attribute featureMap default = 0x181;
-    ram      attribute clusterRevision default = 6;
+    ram      attribute clusterRevision default = 7;
 
     handle command LockDoor;
     handle command UnlockDoor;
diff --git a/examples/lock-app/qpg/zap/lock.zap b/examples/lock-app/qpg/zap/lock.zap
index 9d13502..d4116f8 100644
--- a/examples/lock-app/qpg/zap/lock.zap
+++ b/examples/lock-app/qpg/zap/lock.zap
@@ -1543,6 +1543,38 @@
               "reportableChange": 0
             },
             {
+              "name": "SupportedThreadFeatures",
+              "code": 9,
+              "mfgCode": null,
+              "side": "server",
+              "type": "ThreadCapabilitiesBitmap",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ThreadVersion",
+              "code": 10,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
               "name": "GeneratedCommandList",
               "code": 65528,
               "mfgCode": null,
@@ -1815,6 +1847,22 @@
               "reportableChange": 0
             },
             {
+              "name": "TotalOperationalHours",
+              "code": 3,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int32u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0x00000000",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
               "name": "BootReason",
               "code": 4,
               "mfgCode": null,
@@ -4224,7 +4272,7 @@
               "storageOption": "RAM",
               "singleton": 0,
               "bounded": 0,
-              "defaultValue": "0x0001",
+              "defaultValue": "0x0000",
               "reportable": 1,
               "minInterval": 1,
               "maxInterval": 65534,
@@ -5179,7 +5227,7 @@
               "storageOption": "RAM",
               "singleton": 0,
               "bounded": 0,
-              "defaultValue": "6",
+              "defaultValue": "7",
               "reportable": 1,
               "minInterval": 0,
               "maxInterval": 65344,
diff --git a/examples/persistent-storage/qpg/BUILD.gn b/examples/persistent-storage/qpg/BUILD.gn
index 683a5ed..546ec94 100644
--- a/examples/persistent-storage/qpg/BUILD.gn
+++ b/examples/persistent-storage/qpg/BUILD.gn
@@ -58,7 +58,7 @@
 
   output_dir = root_out_dir
 
-  ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}/QorvoStack_${qpg_target_ic}.ld"
+  ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}${qpg_flavour}/QorvoStack_${qpg_target_ic}${qpg_flavour}.ld"
 
   inputs = [ ldscript ]
 
diff --git a/examples/platform/qpg/app/main.cpp b/examples/platform/qpg/app/main.cpp
index d7ba22f..647d248 100644
--- a/examples/platform/qpg/app/main.cpp
+++ b/examples/platform/qpg/app/main.cpp
@@ -192,7 +192,7 @@
     qvIO_EnableSleep(true);
 #elif CHIP_DEVICE_CONFIG_THREAD_FTD
     ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router);
-    qvIO_EnableSleep(true);
+    qvIO_EnableSleep(false);
 #else
     ret = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice);
     qvIO_EnableSleep(false);
diff --git a/examples/platform/qpg/powercycle_counting.c b/examples/platform/qpg/powercycle_counting.c
index d9e1165..83177e7 100644
--- a/examples/platform/qpg/powercycle_counting.c
+++ b/examples/platform/qpg/powercycle_counting.c
@@ -118,7 +118,8 @@
 
 void gpAppFramework_Reset_Init(void)
 {
-    if (gpReset_GetResetReason() == gpReset_ResetReason_HW_Por)
+    if ((gpReset_GetResetReason() == gpReset_ResetReason_HW_Por) ||
+        (gpReset_GetResetReason() == gpReset_ResetReason_UnSpecified)) // Use this reset reason for JLink resets
     {
         gpAppFramework_HardwareResetTriggered();
     }
diff --git a/examples/shell/qpg/BUILD.gn b/examples/shell/qpg/BUILD.gn
index d325be3..ec477e1 100644
--- a/examples/shell/qpg/BUILD.gn
+++ b/examples/shell/qpg/BUILD.gn
@@ -66,7 +66,7 @@
 
   defines = []
 
-  ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}/QorvoStack_${qpg_target_ic}.ld"
+  ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}${qpg_flavour}/QorvoStack_${qpg_target_ic}${qpg_flavour}.ld"
 
   inputs = [ ldscript ]
 
diff --git a/examples/shell/qpg/args.gni b/examples/shell/qpg/args.gni
index cc3d97a..478e91d 100644
--- a/examples/shell/qpg/args.gni
+++ b/examples/shell/qpg/args.gni
@@ -29,7 +29,6 @@
 
 matter_device_vid = "0xFFF1"
 matter_device_pid = "0x8006"
-matter_device_software_version = "0x0001"
-matter_device_software_version_string = "1.0"
+matter_ota_test_image = false
 
 chip_openthread_ftd = false
diff --git a/examples/thermostat/qpg/BUILD.gn b/examples/thermostat/qpg/BUILD.gn
index 9989e34..11a0317 100644
--- a/examples/thermostat/qpg/BUILD.gn
+++ b/examples/thermostat/qpg/BUILD.gn
@@ -136,7 +136,7 @@
     }
   }
 
-  ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}/QorvoStack_${qpg_target_ic}.ld"
+  ldscript = "${qpg_sdk_root}/Libraries/Qorvo/QorvoStack/gen/QorvoStack_${qpg_target_ic}${qpg_flavour}/QorvoStack_${qpg_target_ic}${qpg_flavour}.ld"
 
   inputs = [ ldscript ]
 
diff --git a/examples/thermostat/qpg/args.gni b/examples/thermostat/qpg/args.gni
index d5dcdfe..693375e 100644
--- a/examples/thermostat/qpg/args.gni
+++ b/examples/thermostat/qpg/args.gni
@@ -29,7 +29,7 @@
 chip_stack_lock_tracking = "none"
 
 matter_device_vid = "0xFFF1"
-matter_device_pid = "0x8006"
+matter_device_pid = "0x8003"
 
 pw_log_BACKEND = "${chip_root}/src/lib/support/pw_log_chip"
 pw_assert_BACKEND = "$dir_pw_assert_log:check_backend"
diff --git a/examples/thermostat/qpg/include/CHIPProjectConfig.h b/examples/thermostat/qpg/include/CHIPProjectConfig.h
index afab6cd..5a134c1 100644
--- a/examples/thermostat/qpg/include/CHIPProjectConfig.h
+++ b/examples/thermostat/qpg/include/CHIPProjectConfig.h
@@ -40,9 +40,18 @@
  * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION
  *
  * A uint32_t identifying the software version running on the device.
+ * First two bytes are reflecting the Matter standard
+ * Last two bytes are reflecting the SDK version of which the first nibble of the first byte represents the major
+ * version and the second nibble of the first byte has the minor number. The last byte holds the patch number.
+ * example for SDK v0.1.5 with Matter v1.2 standard:
+ * 0x01020105
  */
 #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION
-#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x0003 // Can't be removed, needed for OTA file generation.
+#ifndef OTA_TEST_IMAGE
+#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x01020105
+#else
+#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x01020106
+#endif
 #endif
 
 /**
@@ -53,7 +62,11 @@
  * {MAJOR_VERSION}.0d{MINOR_VERSION}
  */
 #ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING
-#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.1" // Can't be removed, needed for OTA file generation.
+#ifndef OTA_TEST_IMAGE
+#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.2-0.1.5"
+#else
+#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.2-0.1.6"
+#endif
 #endif
 
 /**
diff --git a/examples/thermostat/qpg/src/AppTask.cpp b/examples/thermostat/qpg/src/AppTask.cpp
index 7297541..5bd1e9c 100644
--- a/examples/thermostat/qpg/src/AppTask.cpp
+++ b/examples/thermostat/qpg/src/AppTask.cpp
@@ -460,11 +460,15 @@
     // If the system has ble connection(s) uptill the stage above, THEN blink
     // the LEDs at an even rate of 100ms.
     //
-    // Otherwise, blink the LED ON for a very short time.
+    // Otherwise, turn the LED OFF.
     if (sIsThreadProvisioned && sIsThreadEnabled)
     {
         qvIO_LedSet(SYSTEM_STATE_LED, true);
     }
+    else if (sIsThreadProvisioned && !sIsThreadEnabled)
+    {
+        qvIO_LedBlink(SYSTEM_STATE_LED, 950, 50);
+    }
     else if (sHaveBLEConnections)
     {
         qvIO_LedBlink(SYSTEM_STATE_LED, 100, 100);
@@ -476,7 +480,7 @@
     else
     {
         // not commissioned yet
-        qvIO_LedBlink(SYSTEM_STATE_LED, 50, 950);
+        qvIO_LedSet(SYSTEM_STATE_LED, false);
     }
 }
 
diff --git a/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter b/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter
index 2605360..b47ca94 100644
--- a/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter
+++ b/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter
@@ -2027,6 +2027,8 @@
     ram      attribute lastNetworkingStatus;
     ram      attribute lastNetworkID;
     ram      attribute lastConnectErrorValue;
+    callback attribute supportedThreadFeatures;
+    callback attribute threadVersion;
     ram      attribute featureMap default = 2;
     ram      attribute clusterRevision default = 1;
 
diff --git a/examples/thermostat/qpg/zap/thermostaticRadiatorValve.zap b/examples/thermostat/qpg/zap/thermostaticRadiatorValve.zap
index 2b61c6b..a7f0c9c 100644
--- a/examples/thermostat/qpg/zap/thermostaticRadiatorValve.zap
+++ b/examples/thermostat/qpg/zap/thermostaticRadiatorValve.zap
@@ -1503,6 +1503,38 @@
               "reportableChange": 0
             },
             {
+              "name": "SupportedThreadFeatures",
+              "code": 9,
+              "mfgCode": null,
+              "side": "server",
+              "type": "ThreadCapabilitiesBitmap",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ThreadVersion",
+              "code": 10,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
               "name": "FeatureMap",
               "code": 65532,
               "mfgCode": null,
diff --git a/scripts/build/builders/qpg.py b/scripts/build/builders/qpg.py
index e641b6f..ef3b674 100644
--- a/scripts/build/builders/qpg.py
+++ b/scripts/build/builders/qpg.py
@@ -88,6 +88,16 @@
             raise Exception('Unknown board #: %r' % self)
 
 
+class QpgFlavour(Enum):
+    EXT_FLASH = 1
+
+    def GnFlavourName(self):
+        if self == QpgFlavour.EXT_FLASH:
+            return '_ext_flash'
+        else:
+            raise Exception('Unknown flavour #: %r' % self)
+
+
 class QpgBuilder(GnBuilder):
 
     def __init__(self,
@@ -95,6 +105,7 @@
                  runner,
                  app: QpgApp = QpgApp.LIGHT,
                  board: QpgBoard = QpgBoard.QPG6105,
+                 flavour: QpgFlavour = QpgFlavour.EXT_FLASH,
                  enable_rpcs: bool = False,
                  update_image: bool = False):
         super(QpgBuilder, self).__init__(
@@ -102,15 +113,16 @@
             runner=runner)
         self.app = app
         self.board = board
+        self.flavour = flavour
         self.enable_rpcs = enable_rpcs
         self.update_image = update_image
 
     def GnBuildArgs(self):
-        args = ['qpg_target_ic=\"%s\"' % self.board.GnArgName()]
+        args = ['qpg_target_ic=\"%s\" qpg_flavour=\"%s\"' % (self.board.GnArgName(), self.flavour.GnFlavourName())]
         if self.enable_rpcs:
             args.append('import("//with_pw_rpc.gni")')
         if self.update_image:
-            args.append('matter_device_software_version_string=\"1.1_OTA_TEST\" matter_device_software_version=4')
+            args.append('matter_ota_test_image=true')
         return args
 
     def build_outputs(self):
diff --git a/scripts/setup/requirements.qpg.txt b/scripts/setup/requirements.qpg.txt
index 3216862..6670c10 100644
--- a/scripts/setup/requirements.qpg.txt
+++ b/scripts/setup/requirements.qpg.txt
@@ -1 +1,3 @@
-pylzma
\ No newline at end of file
+pylzma
+intelhex
+ecdsa
\ No newline at end of file
diff --git a/src/platform/qpg/BLEManagerImpl.cpp b/src/platform/qpg/BLEManagerImpl.cpp
index 271c9b0..45d291e 100644
--- a/src/platform/qpg/BLEManagerImpl.cpp
+++ b/src/platform/qpg/BLEManagerImpl.cpp
@@ -98,10 +98,10 @@
     err = BleLayer::Init(this, this, &DeviceLayer::SystemLayer());
     SuccessOrExit(err);
 
-    appCbacks.stackCback    = ExternalCbHandler;
-    appCbacks.chrReadCback  = HandleTXCharRead;
-    appCbacks.chrWriteCback = HandleRXCharWrite;
-    appCbacks.cccCback      = _handleTXCharCCCDWrite;
+    appCbacks.stackCallback    = ExternalCbHandler;
+    appCbacks.chrReadCallback  = HandleTXCharRead;
+    appCbacks.chrWriteCallback = HandleRXCharWrite;
+    appCbacks.cccCallback      = _handleTXCharCCCDWrite;
 
 #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
     qvCHIP_BleSetUUIDs(chipUUID_CHIPoBLE_Service, chipUUID_CHIPoBLEChar_TX.bytes, chipUUID_CHIPoBLEChar_RX.bytes,
@@ -210,7 +210,7 @@
     case DeviceEventType::kCHIPoBLESubscribe: {
         ChipDeviceEvent connEstEvent;
 
-        ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLESubscribe");
+        ChipLogDetail(DeviceLayer, "_OnPlatformEvent kCHIPoBLESubscribe");
         HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX);
         connEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished;
         PlatformMgr().PostEventOrDie(&connEstEvent);
@@ -220,7 +220,7 @@
     case DeviceEventType::kCHIPoBLEUnsubscribe: {
         ChipDeviceEvent connClosedEvent;
 
-        ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEUnsubscribe");
+        ChipLogDetail(DeviceLayer, "_OnPlatformEvent kCHIPoBLEUnsubscribe");
         HandleUnsubscribeReceived(event->CHIPoBLEUnsubscribe.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX);
         connClosedEvent.Type = DeviceEventType::kCHIPoBLEConnectionClosed;
         PlatformMgr().PostEventOrDie(&connClosedEvent);
@@ -228,14 +228,14 @@
     break;
 
     case DeviceEventType::kCHIPoBLEWriteReceived: {
-        ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEWriteReceived");
+        ChipLogDetail(DeviceLayer, "_OnPlatformEvent kCHIPoBLEWriteReceived");
         HandleWriteReceived(event->CHIPoBLEWriteReceived.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_RX,
                             PacketBufferHandle::Adopt(event->CHIPoBLEWriteReceived.Data));
     }
     break;
 
     case DeviceEventType::kCHIPoBLEConnectionError: {
-        ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEConnectionError");
+        ChipLogDetail(DeviceLayer, "_OnPlatformEvent kCHIPoBLEConnectionError");
         HandleConnectionError(event->CHIPoBLEConnectionError.ConId, event->CHIPoBLEConnectionError.Reason);
     }
     break;
@@ -250,7 +250,7 @@
         break;
 
     case DeviceEventType::kCHIPoBLEIndicateConfirm: {
-        ChipLogProgress(DeviceLayer, "_OnPlatformEvent kCHIPoBLEIndicateConfirm");
+        ChipLogDetail(DeviceLayer, "_OnPlatformEvent kCHIPoBLEIndicateConfirm");
         HandleIndicationConfirmation(event->CHIPoBLEIndicateConfirm.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX);
     }
     break;
@@ -610,7 +610,7 @@
 {
     CHIP_ERROR err = CHIP_NO_ERROR;
 
-    ChipLogProgress(DeviceLayer, "Write request received for CHIPoBLE Client RX characteristic (con %u, len %u)", connId, len);
+    ChipLogDetail(DeviceLayer, "Write request received for CHIPoBLE Client RX characteristic (con %u, len %u)", connId, len);
 
     // Copy the data to a packet buffer.
     PacketBufferHandle buf = System::PacketBufferHandle::NewWithData(pValue, len, 0, 0);
@@ -727,11 +727,6 @@
             ChipLogError(DeviceLayer, "QVCHIP_DM_ADV_STOP_IND error: %d", (int) pDmEvt->advSetStop.status);
             return;
         }
-
-        if (mFlags.Has(Flags::kRestartAdvertising))
-        {
-            BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising);
-        }
         break;
     }
     case QVCHIP_DM_CONN_OPEN_IND: {
@@ -843,13 +838,13 @@
         /* Process advertising/scanning and connection-related messages */
         if (pMsg->event >= QVCHIP_DM_CBACK_START && pMsg->event <= QVCHIP_DM_CBACK_END)
         {
-            ChipLogProgress(DeviceLayer, "DM event %d: status %d", pMsg->event, pMsg->status);
+            ChipLogDetail(DeviceLayer, "DM event %d: status %d", pMsg->event, pMsg->status);
             sInstance.HandleDmMsg((qvCHIP_Ble_DmEvt_t *) pMsg);
         }
         /* Process attribute-related messages */
         else if (pMsg->event >= QVCHIP_ATT_CBACK_START && pMsg->event <= QVCHIP_ATT_CBACK_END)
         {
-            ChipLogProgress(DeviceLayer, "ATT event %d: status %d", pMsg->event, pMsg->status);
+            ChipLogDetail(DeviceLayer, "ATT event %d: status %d", pMsg->event, pMsg->status);
             sInstance.HandleAttMsg((qvCHIP_Ble_AttEvt_t *) pMsg);
         }
         else
@@ -929,6 +924,7 @@
         ChipLogDetail(DeviceLayer, "bleAdv Timeout : Start slow advertisement");
         sInstance.mFlags.Set(Flags::kRestartAdvertising);
         sInstance.StopAdvertising();
+        BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising);
     }
 }
 
diff --git a/src/platform/qpg/ConfigurationManagerImpl.cpp b/src/platform/qpg/ConfigurationManagerImpl.cpp
index a7a59bf..6dc81dc 100644
--- a/src/platform/qpg/ConfigurationManagerImpl.cpp
+++ b/src/platform/qpg/ConfigurationManagerImpl.cpp
@@ -71,6 +71,12 @@
         SuccessOrExit(err);
     }
 
+    if (!QPGConfig::ConfigValueExists(QPGConfig::kCounterKey_TotalOperationalHours))
+    {
+        err = StoreTotalOperationalHours(0);
+        SuccessOrExit(err);
+    }
+
     qvRebootReason = qvCHIP_GetResetReason();
 
     switch (qvRebootReason)
@@ -121,12 +127,6 @@
 
 CHIP_ERROR ConfigurationManagerImpl::GetTotalOperationalHours(uint32_t & totalOperationalHours)
 {
-    if (!QPGConfig::ConfigValueExists(QPGConfig::kCounterKey_TotalOperationalHours))
-    {
-        totalOperationalHours = 0;
-        return CHIP_NO_ERROR;
-    }
-
     return QPGConfig::ReadConfigValue(QPGConfig::kCounterKey_TotalOperationalHours, totalOperationalHours);
 }
 
diff --git a/src/platform/qpg/args.gni b/src/platform/qpg/args.gni
index 9466964..75e99c6 100644
--- a/src/platform/qpg/args.gni
+++ b/src/platform/qpg/args.gni
@@ -42,13 +42,6 @@
 chip_build_tests = false
 
 openthread_external_mbedtls = mbedtls_target
-openthread_project_core_config_file =
-    "openthread-core-${qpg_target_ic}-config.h"
-openthread_core_config_platform_check_file =
-    "openthread-core-${qpg_target_ic}-config-check.h"
-openthread_core_config_deps = [
-  "${chip_root}/third_party/openthread/platforms/qpg:libopenthread-qpg-config",
-]
 
 openthread_external_platform =
     "${chip_root}/third_party/openthread/platforms/qpg:libopenthread-qpg"
diff --git a/third_party/openthread/ot-qorvo b/third_party/openthread/ot-qorvo
index 279324e..95ecf78 160000
--- a/third_party/openthread/ot-qorvo
+++ b/third_party/openthread/ot-qorvo
@@ -1 +1 @@
-Subproject commit 279324ecd8385f8fc3c044bda8452deeefc8beee
+Subproject commit 95ecf788f6b70c37bfe296360b0321616ab80fb3
diff --git a/third_party/openthread/platforms/qpg/BUILD.gn b/third_party/openthread/platforms/qpg/BUILD.gn
index d7e0b95..9ced65f 100644
--- a/third_party/openthread/platforms/qpg/BUILD.gn
+++ b/third_party/openthread/platforms/qpg/BUILD.gn
@@ -16,6 +16,7 @@
 import("//build_overrides/openthread.gni")
 import("//build_overrides/qpg_sdk.gni")
 
+import("${chip_root}/src/platform/device.gni")
 import("${qpg_sdk_build_root}/qpg_sdk.gni")
 
 # QPGxxxx settings and OT glue code
@@ -26,6 +27,11 @@
   include_dirs = [ "${openthread_qpg_root}/src/${openthread_qpg_family}" ]
 
   include_dirs += [ "${chip_root}/examples/platform/qpg" ]
+
+  defines = [
+    "QORVO_FTD=${chip_openthread_ftd}",
+    "QORVO_RCP=0",
+  ]
 }
 
 source_set("openthread_core_config_qpg") {
@@ -40,7 +46,7 @@
 }
 
 source_set("openthread_mbedtls_config_qpg") {
-  sources = [ "${openthread_qpg_root}/src/${openthread_qpg_family}/crypto/${openthread_qpg_family}-mbedtls-config.h" ]
+  sources = [ "${qpg_sdk_build_root}/repo/Libraries/Qorvo/mbedtls_alt/inc/${openthread_qpg_family}-mbedtls-config.h" ]  # "${openthread_qpg_root}/third_party/Qorvo/repo/${openthread_qpg_family}/inc/${openthread_qpg_family}-mbedtls-config.h",
 }
 
 source_set("libopenthread-qpg") {
@@ -52,7 +58,7 @@
     "${openthread_qpg_root}/src/${openthread_qpg_family}/misc.c",
     "${openthread_qpg_root}/src/${openthread_qpg_family}/platform.c",
     "${openthread_qpg_root}/src/${openthread_qpg_family}/radio.c",
-    "${openthread_qpg_root}/src/${openthread_qpg_family}/settings.cpp",
+    "${openthread_qpg_root}/src/${openthread_qpg_family}/settings.c",
     "${openthread_qpg_root}/src/${openthread_qpg_family}/uart.c",
   ]
 
diff --git a/third_party/qpg_sdk/BUILD.gn b/third_party/qpg_sdk/BUILD.gn
index e20c43d..0007a85 100755
--- a/third_party/qpg_sdk/BUILD.gn
+++ b/third_party/qpg_sdk/BUILD.gn
@@ -102,11 +102,10 @@
 
 qpg_make_build("qpg_stack") {
   make_sources = [ "${qpg_sdk_root}/Components/Qorvo" ]
-  make_output = [ "${target_gen_dir}/${qpg_sdk_lib_dir}/QorvoStack/libQorvoStack_${qpg_target_ic}.a" ]
+  make_output = [ "${target_gen_dir}/${qpg_sdk_lib_dir}/QorvoStack/libQorvoStack_${qpg_target_ic}${qpg_flavour}.a" ]
   make_args = [
     "-f",
-    rebase_path(qpg_sdk_root, root_build_dir) +
-        "/Libraries/Qorvo/QorvoStack/Makefile.QorvoStack_${qpg_target_ic}",
+    rebase_path(qpg_sdk_root, root_build_dir) + "/Libraries/Qorvo/QorvoStack/Makefile.QorvoStack_${qpg_target_ic}${qpg_flavour}",
     "FREERTOS_REPO_DIR=" + rebase_path(chip_root, root_build_dir) +
         "/third_party/freertos/repo",
     "WORKDIR=" + rebase_path(target_gen_dir, root_build_dir) +
@@ -116,15 +115,15 @@
 
 static_library("qpg_stack_lib") {
   deps = [ "${chip_root}/third_party/qpg_sdk:qpg_stack" ]
-  libs = [ "${target_gen_dir}/${qpg_sdk_lib_dir}/QorvoStack/libQorvoStack_${qpg_target_ic}.a" ]
+  libs = [ "${target_gen_dir}/${qpg_sdk_lib_dir}/QorvoStack/libQorvoStack_${qpg_target_ic}${qpg_flavour}.a" ]
 }
 
 qpg_make_build("qpg_glue") {
   make_sources = [ "${qpg_sdk_root}/Components/Qorvo/Matter" ]
-  make_output = [ "${target_gen_dir}/${qpg_sdk_lib_dir}/MatterQorvoGlue/libMatterQorvoGlue_${qpg_target_ic}_libbuild.a" ]
+  make_output = [ "${target_gen_dir}/${qpg_sdk_lib_dir}/MatterQorvoGlue/libMatterQorvoGlue_${qpg_target_ic}${qpg_flavour}_libbuild.a" ]
   make_args = [
     "-f",
-    rebase_path(qpg_sdk_root, root_build_dir) + "/Libraries/Qorvo/MatterQorvoGlue/Makefile.MatterQorvoGlue_${qpg_target_ic}_libbuild",
+    rebase_path(qpg_sdk_root, root_build_dir) + "/Libraries/Qorvo/MatterQorvoGlue/Makefile.MatterQorvoGlue_${qpg_target_ic}${qpg_flavour}_libbuild",
     "FREERTOS_REPO_DIR=" + rebase_path(chip_root, root_build_dir) +
         "/third_party/freertos/repo",
     "WORKDIR=" + rebase_path(target_gen_dir, root_build_dir) +
@@ -133,7 +132,11 @@
 }
 static_library("qpg_glue_lib") {
   deps = [ "${chip_root}/third_party/qpg_sdk:qpg_glue" ]
-  libs = [ "${target_gen_dir}/${qpg_sdk_lib_dir}/MatterQorvoGlue/libMatterQorvoGlue_${qpg_target_ic}_libbuild.a" ]
+  if (qpg_target_ic == "qpg6105") {
+    libs = [ "${target_gen_dir}/${qpg_sdk_lib_dir}/MatterQorvoGlue/libMatterQorvoGlue_${qpg_target_ic}${qpg_flavour}_libbuild.a" ]
+  } else {
+    assert(false, "QPG target not specified")
+  }
 }
 
 # openthread toevoegen
@@ -141,16 +144,16 @@
 #
 qpg_make_build("qpg_bootloader") {
   make_sources = [ "${qpg_sdk_root}/Libraries/Qorvo/Bootloader" ]
-  make_output = [ "${target_gen_dir}/${qpg_sdk_lib_dir}/Bootloader_${qpg_target_ic}_compr_secure/libBootloader_${qpg_target_ic}_compr_secure.a" ]
+  make_output = [ "${target_gen_dir}/${qpg_sdk_lib_dir}/BootloaderSections_${qpg_target_ic}_compr_secure/libBootloaderSections_${qpg_target_ic}_compr_secure.a" ]
   make_args = [
     "-f",
-    rebase_path(qpg_sdk_root, root_build_dir) + "/Libraries/Qorvo/Bootloader/Makefile.Bootloader_${qpg_target_ic}_compr_secure",
+    rebase_path(qpg_sdk_root, root_build_dir) + "/Libraries/Qorvo/Bootloader/Makefile.BootloaderSections_${qpg_target_ic}_compr_secure",
     "FREERTOS_REPO_DIR=" + rebase_path(chip_root, root_build_dir) +
         "/third_party/freertos/repo",
     "WORKDIR=" + rebase_path(target_gen_dir, root_build_dir) +
-        "/${qpg_sdk_lib_dir}/Bootloader_${qpg_target_ic}_compr_secure",
+        "/${qpg_sdk_lib_dir}/BootloaderSections_${qpg_target_ic}_compr_secure",
     "UMB_WORKDIR=" + rebase_path(target_gen_dir, root_build_dir) +
-        "/${qpg_sdk_lib_dir}/UMB_${qpg_target_board}_nrt_flash_compr_secure",
+        "/${qpg_sdk_lib_dir}/Bootloader_QPG6105DK_B01_nrt_flash_compr_secure",
   ]
 }
 config("qpg_retain_bootloader") {
@@ -163,7 +166,7 @@
 
 static_library("qpg_bootloader_lib") {
   deps = [ "${chip_root}/third_party/qpg_sdk:qpg_bootloader" ]
-  libs = [ "${target_gen_dir}/${qpg_sdk_lib_dir}/Bootloader_${qpg_target_ic}_compr_secure/libBootloader_${qpg_target_ic}_compr_secure.a" ]
+  libs = [ "${target_gen_dir}/${qpg_sdk_lib_dir}/BootloaderSections_${qpg_target_ic}_compr_secure/libBootloaderSections_${qpg_target_ic}_compr_secure.a" ]
   public_configs = [ ":qpg_retain_bootloader" ]
 }
 
diff --git a/third_party/qpg_sdk/qpg_executable.gni b/third_party/qpg_sdk/qpg_executable.gni
index f759edd..0196b59 100644
--- a/third_party/qpg_sdk/qpg_executable.gni
+++ b/third_party/qpg_sdk/qpg_executable.gni
@@ -138,12 +138,8 @@
       if (matter_device_pid != "") {
         ota_header_options += [ "-pid=${matter_device_pid}" ]
       }
-      if (matter_device_software_version != "") {
-        ota_header_options += [ "-vn=${matter_device_software_version}" ]
-      }
-      if (matter_device_software_version_string != "") {
-        ota_header_options +=
-            [ "-vs=\"${matter_device_software_version_string}\"" ]
+      if (matter_ota_test_image) {
+        ota_header_options += [ "-tui" ]
       }
       deps = [ ":$executable_target_name" ]
     }
diff --git a/third_party/qpg_sdk/qpg_platform.gni b/third_party/qpg_sdk/qpg_platform.gni
new file mode 100644
index 0000000..c2249e6
--- /dev/null
+++ b/third_party/qpg_sdk/qpg_platform.gni
@@ -0,0 +1,31 @@
+# Copyright (c) 2020 Project CHIP Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//build_overrides/chip.gni")
+import("${chip_root}/src/crypto/crypto.gni")
+
+declare_args() {
+  # QPG chip
+  qpg_target_ic = "unset"
+  qpg_flavour = ""
+  mbedtls_alt_enabled = true
+}
+
+if (qpg_target_ic == "qpg6105") {
+  mbedtls_alt_enabled = true
+  arm_float_abi = "soft"
+  arm_arch = "armv7e-m"
+} else {
+  assert(qpg_target_ic != "", "qpg_target_ic must be specified")
+}
diff --git a/third_party/qpg_sdk/qpg_sdk.gni b/third_party/qpg_sdk/qpg_sdk.gni
index d8898c3..1fb81a6 100644
--- a/third_party/qpg_sdk/qpg_sdk.gni
+++ b/third_party/qpg_sdk/qpg_sdk.gni
@@ -16,6 +16,7 @@
 import("//build_overrides/jlink.gni")
 import("//build_overrides/openthread.gni")
 import("//build_overrides/qpg_sdk.gni")
+import("qpg_platform.gni")
 
 declare_args() {
   # Location of the QPG SDK.
@@ -24,26 +25,16 @@
   # subdirectory in qpg_sdk_root where the binary library builds (.a) are to be found
   qpg_sdk_lib_dir = "Work"
 
-  # Target IC for QPG SDK
-  qpg_target_ic = "qpg6105"
-
-  # Target board for QPG SDK
-  qpg_target_board = "QPG6105DK_B01"
-
   # an option to disable referencing qorvo object archive files (*.a)
   qpg_sdk_include_platform_libs = true
 
   # Enable Sleepy end device
   enable_sleepy_device = false
 
-  # Enable mbedtls HW acceleration
-  mbedtls_alt_enabled = true
-
   # OTA parameters
   matter_device_vid = ""
   matter_device_pid = ""
-  matter_device_software_version = ""
-  matter_device_software_version_string = ""
+  matter_ota_test_image = false
 }
 
 assert(qpg_sdk_root != "", "qpg_sdk_root must be specified")
@@ -105,11 +96,8 @@
     if (matter_device_pid != "") {
       defines += [ "CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID=${matter_device_pid}" ]
     }
-    if (matter_device_software_version_string != "") {
-      defines += [ "CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING=\"${matter_device_software_version_string}\"" ]
-    }
-    if (matter_device_software_version != "") {
-      defines += [ "CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION=${matter_device_software_version}" ]
+    if (matter_ota_test_image) {
+      defines += [ "OTA_TEST_IMAGE" ]
     }
 
     if (qpg_target_ic == "qpg6200") {
diff --git a/third_party/qpg_sdk/repo b/third_party/qpg_sdk/repo
index e47e299..5b5fb54 160000
--- a/third_party/qpg_sdk/repo
+++ b/third_party/qpg_sdk/repo
@@ -1 +1 @@
-Subproject commit e47e299445caf8f139e2270e848e628167dca5cb
+Subproject commit 5b5fb541e9ef615db8fd5d2fae66c9c15bf884b0