Repository: project-chip/connectedhomeip
Pull request #38924: Add support for concatenated QR codes to SetUpCodePairer.
Author: login: bzbarsky-apple
Labels: name: tools
name: examples
name: scripts
name: controller
name: ble
name: review - approved
Created: 2025-05-13T21:17:28Z | Merged: 2025-05-27T23:30:50Z

This requires backends to actually support discovery of multiple things with multiple discriminators. DNS-SD supports that, and BLE has APIs for it, which are not implemented on all platforms yet.  PAF and NFC will need to be fixed to handle it.

### Testing

Manually tested, for both BLE and DNS-SD discovery.


Diff:
diff --git a/examples/chip-tool/commands/common/DeviceScanner.cpp b/examples/chip-tool/commands/common/DeviceScanner.cpp
index 548e461f96ca8e..5ca09c2701e813 100644
--- a/examples/chip-tool/commands/common/DeviceScanner.cpp
+++ b/examples/chip-tool/commands/common/DeviceScanner.cpp
@@ -72,7 +72,7 @@ void DeviceScanner::OnNodeDiscovered(const DiscoveredNodeData & nodeData)
 
     for (size_t i = 0; i < resolutionData.numIPs; i++)
     {
-        auto params                = Controller::SetUpCodePairerParameters(resolutionData, i);
+        auto params                = Controller::SetUpCodePairerParameters(resolutionData, std::make_optional(discriminator), i);
         DeviceScannerResult result = { params, vendorId, productId, discriminator, chip::MakeOptional(resolutionData) };
         interfaceData.push_back(result);
     }
diff --git a/scripts/tools/check_includes_config.py b/scripts/tools/check_includes_config.py
index 94b3742ca6d873..2d4644fa32bef4 100644
--- a/scripts/tools/check_includes_config.py
+++ b/scripts/tools/check_includes_config.py
@@ -163,9 +163,9 @@
     # Uses platform-define to switch between list and array
     'src/lib/dnssd/minimal_mdns/ResponseSender.h': {'list'},
 
-    # Not really for embedded consumers; uses std::deque to keep track
-    # of a list of discovered things.
-    'src/controller/SetUpCodePairer.h': {'deque'},
+    # Not really for embedded consumers, because commissioners tend to not be embedded.
+    'src/controller/SetUpCodePairer.h': {'deque', 'vector'},
+    'src/controller/SetUpCodePairer.cpp': {'vector'},
 
     'src/controller/ExamplePersistentStorage.cpp': {'fstream', 'string', 'map'},
 
diff --git a/src/controller/SetUpCodePairer.cpp b/src/controller/SetUpCodePairer.cpp
index 8449936b6426d7..4e743b0cf3ff46 100644
--- a/src/controller/SetUpCodePairer.cpp
+++ b/src/controller/SetUpCodePairer.cpp
@@ -32,6 +32,7 @@
 #include <memory>
 #include <system/SystemClock.h>
 #include <tracing/metric_event.h>
+#include <vector>
 
 constexpr uint32_t kDeviceDiscoveredTimeout = CHIP_CONFIG_SETUP_CODE_PAIRER_DISCOVERY_TIMEOUT_SECS * chip::kMillisecondsPerSecond;
 
@@ -40,61 +41,53 @@ using namespace chip::Tracing;
 namespace chip {
 namespace Controller {
 
-namespace {
-
-CHIP_ERROR GetPayload(const char * setUpCode, SetupPayload & payload)
-{
-    bool isQRCode = strncmp(setUpCode, kQRCodePrefix, strlen(kQRCodePrefix)) == 0;
-    if (isQRCode)
-    {
-        ReturnErrorOnFailure(QRCodeSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidQRCodePayload(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-    else
-    {
-        ReturnErrorOnFailure(ManualSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidManualCode(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-
-    return CHIP_NO_ERROR;
-}
-} // namespace
-
 CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode, SetupCodePairerBehaviour commission,
                                        DiscoveryType discoveryType, Optional<Dnssd::CommonResolutionData> resolutionData)
 {
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, mSystemLayer != nullptr, CHIP_ERROR_INCORRECT_STATE);
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, remoteId != kUndefinedNodeId, CHIP_ERROR_INVALID_ARGUMENT);
 
-    SetupPayload payload;
-    ReturnErrorOnFailure(GetPayload(setUpCode, payload));
+    std::vector<SetupPayload> payloads;
+    ReturnErrorOnFailure(SetupPayload::FromStringRepresentation(setUpCode, payloads));
 
-    if (resolutionData.HasValue())
+    // If the caller has provided a specific single resolution data, and we were
+    // only looking for one commissionee, and the caller says that the provided
+    // data matches that one commissionee, just go ahead and use the provided data.
+    //
+    // If we were looking for more than one device (i.e. if either of the
+    // payload arrays involved does not have length 1), we can't make use of the
+    // incoming resolution data, since it does not contain the long
+    // discriminator of the thing that was discovered, and therefore we can't
+    // tell which setup passcode to use for it.
+    if (resolutionData.HasValue() && payloads.size() == 1 && mSetupPayloads.size() == 1)
     {
         VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, discoveryType != DiscoveryType::kAll,
                                       CHIP_ERROR_INVALID_ARGUMENT);
-        if (mRemoteId == remoteId && mSetUpPINCode == payload.setUpPINCode && mConnectionType == commission &&
+        if (mRemoteId == remoteId && mSetupPayloads[0].setUpPINCode == payloads[0].setUpPINCode && mConnectionType == commission &&
             mDiscoveryType == discoveryType)
         {
-            NotifyCommissionableDeviceDiscovered(resolutionData.Value());
+            // Not passing a discriminator is ok, since we have only one payload.
+            NotifyCommissionableDeviceDiscovered(resolutionData.Value(), /* matchedLongDiscriminator = */ std::nullopt);
             return CHIP_NO_ERROR;
         }
     }
 
+    ResetDiscoveryState();
+
     mConnectionType = commission;
     mDiscoveryType  = discoveryType;
     mRemoteId       = remoteId;
-    mSetUpPINCode   = payload.setUpPINCode;
-
-    ResetDiscoveryState();
+    mSetupPayloads  = std::move(payloads);
 
-    if (resolutionData.HasValue())
+    if (resolutionData.HasValue() && mSetupPayloads.size() == 1)
     {
-        NotifyCommissionableDeviceDiscovered(resolutionData.Value());
+        // No need to pass in a discriminator if we have only one payload, which
+        // is good because we don't have a full discriminator here anyway.
+        NotifyCommissionableDeviceDiscovered(resolutionData.Value(), /* matchedLongDiscriminator = */ std::nullopt);
         return CHIP_NO_ERROR;
     }
 
-    ReturnErrorOnFailureWithMetric(kMetricSetupCodePairerPairDevice, Connect(payload));
+    ReturnErrorOnFailureWithMetric(kMetricSetupCodePairerPairDevice, Connect());
     auto errorCode =
         mSystemLayer->StartTimer(System::Clock::Milliseconds32(kDeviceDiscoveredTimeout), OnDeviceDiscoveredTimeoutCallback, this);
     if (CHIP_NO_ERROR == errorCode)
@@ -104,55 +97,50 @@ CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode,
     return errorCode;
 }
 
-CHIP_ERROR SetUpCodePairer::Connect(SetupPayload & payload)
+CHIP_ERROR SetUpCodePairer::Connect()
 {
-    CHIP_ERROR err = CHIP_NO_ERROR;
-    bool isRunning = false;
-
-    bool searchOverAll = !payload.rendezvousInformation.HasValue();
-
     if (mDiscoveryType == DiscoveryType::kAll)
     {
-        if (searchOverAll || payload.rendezvousInformation.Value().Has(RendezvousInformationFlag::kBLE))
+        if (ShouldDiscoverUsing(RendezvousInformationFlag::kBLE))
         {
-            if (CHIP_NO_ERROR == (err = StartDiscoveryOverBLE(payload)))
+            CHIP_ERROR err = StartDiscoveryOverBLE();
+            if (err != CHIP_NO_ERROR)
             {
-                isRunning = true;
+                ChipLogError(Controller, "Failed to start discovery over BLE: %" CHIP_ERROR_FORMAT, err.Format());
             }
-            VerifyOrReturnError(searchOverAll || CHIP_NO_ERROR == err || CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE == err, err);
         }
 
-        if (searchOverAll || payload.rendezvousInformation.Value().Has(RendezvousInformationFlag::kSoftAP))
+        if (ShouldDiscoverUsing(RendezvousInformationFlag::kSoftAP))
         {
-            if (CHIP_NO_ERROR == (err = StartDiscoveryOverSoftAP(payload)))
+            CHIP_ERROR err = StartDiscoveryOverSoftAP();
+            if (err != CHIP_NO_ERROR)
             {
-                isRunning = true;
+                ChipLogError(Controller, "Failed to start discovery over SoftAP: %" CHIP_ERROR_FORMAT, err.Format());
             }
-            VerifyOrReturnError(searchOverAll || CHIP_NO_ERROR == err || CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE == err, err);
         }
-        if (searchOverAll || payload.rendezvousInformation.Value().Has(RendezvousInformationFlag::kWiFiPAF))
+        if (ShouldDiscoverUsing(RendezvousInformationFlag::kWiFiPAF))
         {
-            ChipLogProgress(Controller, "WiFi-PAF: has RendezvousInformationFlag::kWiFiPAF");
-            if (CHIP_NO_ERROR == (err = StartDiscoveryOverWiFiPAF(payload)))
+            ChipLogProgress(Controller,
+                            "WiFi-PAF: has RendezvousInformationFlag::kWiFiPAF or has no discovery capabilities bitmask");
+            CHIP_ERROR err = StartDiscoveryOverWiFiPAF();
+            if (err != CHIP_NO_ERROR)
             {
-                isRunning = true;
+                ChipLogError(Controller, "Failed to start discovery over WiFiPAF: %" CHIP_ERROR_FORMAT, err.Format());
             }
-            VerifyOrReturnError(searchOverAll || CHIP_NO_ERROR == err || CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE == err, err);
         }
     }
 
     // We always want to search on network because any node that has already been commissioned will use on-network regardless of the
     // QR code flag.
-    if (CHIP_NO_ERROR == (err = StartDiscoveryOverDNSSD(payload)))
+    CHIP_ERROR err = StartDiscoveryOverDNSSD();
+    if (err != CHIP_NO_ERROR)
     {
-        isRunning = true;
+        ChipLogError(Controller, "Failed to start discovery over DNS-SD: %" CHIP_ERROR_FORMAT, err.Format());
     }
-    VerifyOrReturnError(searchOverAll || CHIP_NO_ERROR == err, err);
-
-    return isRunning ? CHIP_NO_ERROR : CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
+    return err;
 }
 
-CHIP_ERROR SetUpCodePairer::StartDiscoveryOverBLE(SetupPayload & payload)
+CHIP_ERROR SetUpCodePairer::StartDiscoveryOverBLE()
 {
 #if CONFIG_NETWORK_LAYER_BLE
 #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
@@ -165,8 +153,27 @@ CHIP_ERROR SetUpCodePairer::StartDiscoveryOverBLE(SetupPayload & payload)
 
     // Handle possibly-sync callbacks.
     mWaitingForDiscovery[kBLETransport] = true;
-    CHIP_ERROR err = mBleLayer->NewBleConnectionByDiscriminator(payload.discriminator, this, OnDiscoveredDeviceOverBleSuccess,
-                                                                OnDiscoveredDeviceOverBleError);
+    CHIP_ERROR err;
+    // Not all BLE backends support the new NewBleConnectionByDiscriminators
+    // API, so use the old one when we can (i.e. when we only have one setup
+    // payload), to avoid breaking existing API consumers.
+    if (mSetupPayloads.size() == 1)
+    {
+        err = mBleLayer->NewBleConnectionByDiscriminator(mSetupPayloads[0].discriminator, this, OnDiscoveredDeviceOverBleSuccess,
+                                                         OnDiscoveredDeviceOverBleError);
+    }
+    else
+    {
+        std::vector<SetupDiscriminator> discriminators;
+        discriminators.reserve(mSetupPayloads.size());
+        for (auto & payload : mSetupPayloads)
+        {
+            discriminators.emplace_back(payload.discriminator);
+        }
+        err = mBleLayer->NewBleConnectionByDiscriminators(Span(discriminators.data(), discriminators.size()), this,
+                                                          OnDiscoveredDeviceWithDiscriminatorOverBleSuccess,
+                                                          OnDiscoveredDeviceOverBleError);
+    }
     if (err != CHIP_NO_ERROR)
     {
         mWaitingForDiscovery[kBLETransport] = false;
@@ -201,27 +208,33 @@ CHIP_ERROR SetUpCodePairer::StopDiscoveryOverBLE()
 #endif // CONFIG_NETWORK_LAYER_BLE
 }
 
-CHIP_ERROR SetUpCodePairer::StartDiscoveryOverDNSSD(SetupPayload & payload)
+CHIP_ERROR SetUpCodePairer::StartDiscoveryOverDNSSD()
 {
     ChipLogProgress(Controller, "Starting commissioning discovery over DNS-SD");
 
-    auto & discriminator = payload.discriminator;
-    if (discriminator.IsShortDiscriminator())
-    {
-        mCurrentFilter.type = Dnssd::DiscoveryFilterType::kShortDiscriminator;
-        mCurrentFilter.code = discriminator.GetShortValue();
-    }
-    else
+    Dnssd::DiscoveryFilter filter(Dnssd::DiscoveryFilterType::kNone);
+    if (mSetupPayloads.size() == 1)
     {
-        mCurrentFilter.type = Dnssd::DiscoveryFilterType::kLongDiscriminator;
-        mCurrentFilter.code = discriminator.GetLongValue();
+        auto & discriminator = mSetupPayloads[0].discriminator;
+        if (discriminator.IsShortDiscriminator())
+        {
+            filter.type = Dnssd::DiscoveryFilterType::kShortDiscriminator;
+            filter.code = discriminator.GetShortValue();
+        }
+        else
+        {
+            filter.type = Dnssd::DiscoveryFilterType::kLongDiscriminator;
+            filter.code = discriminator.GetLongValue();
+        }
     }
-    mPayloadVendorID  = payload.vendorID;
-    mPayloadProductID = payload.productID;
+
+    // In theory we could try to filter on the vendor ID if it's the same across all the setup
+    // payloads, but DNS-SD advertisements are not required to include the Vendor ID subtype, so in
+    // practice that's not doable.
 
     // Handle possibly-sync callbacks.
     mWaitingForDiscovery[kIPTransport] = true;
-    CHIP_ERROR err                     = mCommissioner->DiscoverCommissionableNodes(mCurrentFilter);
+    CHIP_ERROR err                     = mCommissioner->DiscoverCommissionableNodes(filter);
     if (err != CHIP_NO_ERROR)
     {
         mWaitingForDiscovery[kIPTransport] = false;
@@ -234,15 +247,12 @@ CHIP_ERROR SetUpCodePairer::StopDiscoveryOverDNSSD()
     ChipLogDetail(Controller, "Stopping commissioning discovery over DNS-SD");
 
     mWaitingForDiscovery[kIPTransport] = false;
-    mCurrentFilter.type                = Dnssd::DiscoveryFilterType::kNone;
-    mPayloadVendorID                   = kNotAvailable;
-    mPayloadProductID                  = kNotAvailable;
 
     mCommissioner->StopCommissionableDiscovery();
     return CHIP_NO_ERROR;
 }
 
-CHIP_ERROR SetUpCodePairer::StartDiscoveryOverSoftAP(SetupPayload & payload)
+CHIP_ERROR SetUpCodePairer::StartDiscoveryOverSoftAP()
 {
     return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
 }
@@ -253,9 +263,17 @@ CHIP_ERROR SetUpCodePairer::StopDiscoveryOverSoftAP()
     return CHIP_NO_ERROR;
 }
 
-CHIP_ERROR SetUpCodePairer::StartDiscoveryOverWiFiPAF(SetupPayload & payload)
+CHIP_ERROR SetUpCodePairer::StartDiscoveryOverWiFiPAF()
 {
 #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
+    if (mSetupPayloads.size() != 1)
+    {
+        ChipLogError(Controller, "WiFiPAF commissioning does not support concatenated QR codes yet.");
+        return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
+    }
+
+    auto & payload = mSetupPayloads[0];
+
     ChipLogProgress(Controller, "Starting commissioning discovery over WiFiPAF");
     VerifyOrReturnError(mCommissioner != nullptr, CHIP_ERROR_INCORRECT_STATE);
 
@@ -310,7 +328,45 @@ bool SetUpCodePairer::ConnectToDiscoveredDevice()
         SetUpCodePairerParameters params(mDiscoveredParameters.front());
         mDiscoveredParameters.pop_front();
 
-        params.SetSetupPINCode(mSetUpPINCode);
+        if (params.mLongDiscriminator)
+        {
+            auto longDiscriminator = *params.mLongDiscriminator;
+            // Look for a matching setup passcode.
+            bool found = false;
+            for (auto & payload : mSetupPayloads)
+            {
+                if (payload.discriminator.MatchesLongDiscriminator(longDiscriminator))
+                {
+                    params.SetSetupPINCode(payload.setUpPINCode);
+                    found = true;
+                    break;
+                }
+            }
+            if (!found)
+            {
+                ChipLogError(Controller, "SetUpCodePairer: Discovered discriminator %u does not match any of our setup payloads",
+                             longDiscriminator);
+                // Move on to the the next discovered params; nothing we can do here.
+                continue;
+            }
+        }
+        else
+        {
+            // No discriminator known for this discovered device.  This can work if we have only one
+            // setup payload, but otherwise we have no idea what setup passcode to use for it.
+            if (mSetupPayloads.size() == 1)
+            {
+                params.SetSetupPINCode(mSetupPayloads[0].setUpPINCode);
+            }
+            else
+            {
+                ChipLogError(Controller,
+                             "SetUpCodePairer: Unable to handle discovered parameters with no discriminator, because it has %u "
+                             "possible payloads",
+                             static_cast<unsigned>(mSetupPayloads.size()));
+                continue;
+            }
+        }
 
 #if CHIP_PROGRESS_LOGGING
         char buf[Transport::PeerAddress::kMaxToStringSize];
@@ -350,7 +406,7 @@ bool SetUpCodePairer::ConnectToDiscoveredDevice()
 }
 
 #if CONFIG_NETWORK_LAYER_BLE
-void SetUpCodePairer::OnDiscoveredDeviceOverBle(BLE_CONNECTION_OBJECT connObj)
+void SetUpCodePairer::OnDiscoveredDeviceOverBle(BLE_CONNECTION_OBJECT connObj, std::optional<uint16_t> matchedLongDiscriminator)
 {
     ChipLogProgress(Controller, "Discovered device to be commissioned over BLE");
 
@@ -362,13 +418,26 @@ void SetUpCodePairer::OnDiscoveredDeviceOverBle(BLE_CONNECTION_OBJECT connObj)
     //
     // It makes it the 'next' thing to try to connect to if there are already some
     // discovered parameters in the list.
-    mDiscoveredParameters.emplace_front(connObj);
+    //
+    // TODO: Consider implementing the SHOULD the spec has about commissioning things
+    // in QR code order by waiting for a second or something before actually starting
+    // the first PASE session when we have multiple setup payloads, and sorting the
+    // results in setup payload order.  If we do this, we might want to restrict it to
+    // cases when the different payloads have different vendor/product IDs, since if
+    // they are all the same product presumably ordering really does not matter.
+    mDiscoveredParameters.emplace_front(connObj, matchedLongDiscriminator);
     ConnectToDiscoveredDevice();
 }
 
 void SetUpCodePairer::OnDiscoveredDeviceOverBleSuccess(void * appState, BLE_CONNECTION_OBJECT connObj)
 {
-    (static_cast<SetUpCodePairer *>(appState))->OnDiscoveredDeviceOverBle(connObj);
+    (static_cast<SetUpCodePairer *>(appState))->OnDiscoveredDeviceOverBle(connObj, std::nullopt);
+}
+
+void SetUpCodePairer::OnDiscoveredDeviceWithDiscriminatorOverBleSuccess(void * appState, uint16_t matchedLongDiscriminator,
+                                                                        BLE_CONNECTION_OBJECT connObj)
+{
+    (static_cast<SetUpCodePairer *>(appState))->OnDiscoveredDeviceOverBle(connObj, std::make_optional(matchedLongDiscriminator));
 }
 
 void SetUpCodePairer::OnDiscoveredDeviceOverBleError(void * appState, CHIP_ERROR err)
@@ -392,6 +461,10 @@ void SetUpCodePairer::OnDiscoveredDeviceOverWifiPAF()
     mWaitingForDiscovery[kWiFiPAFTransport] = false;
     auto param                              = SetUpCodePairerParameters();
     param.SetPeerAddress(Transport::PeerAddress(Transport::Type::kWiFiPAF, mRemoteId));
+    // TODO: This needs to support concatenated QR codes and set the relevant
+    // long discriminator on param.
+    //
+    // See https://github.com/project-chip/connectedhomeip/issues/39134
     mDiscoveredParameters.emplace_back(param);
     ConnectToDiscoveredDevice();
 }
@@ -434,41 +507,38 @@ bool SetUpCodePairer::NodeMatchesCurrentFilter(const Dnssd::DiscoveredNodeData &
         return false;
     }
 
-    // The advertisement may not include a vendor id.
-    if (IdIsPresent(mPayloadVendorID) && IdIsPresent(nodeData.vendorId) && mPayloadVendorID != nodeData.vendorId)
+    // Check whether this matches one of our setup payloads.
+    for (auto & payload : mSetupPayloads)
     {
-        ChipLogProgress(Controller, "Discovered device does not match our vendor id.");
-        return false;
-    }
+        // The advertisement may not include a vendor id, and the payload may not have one either.
+        if (IdIsPresent(payload.vendorID) && IdIsPresent(nodeData.vendorId) && payload.vendorID != nodeData.vendorId)
+        {
+            ChipLogProgress(Controller, "Discovered device vendor ID (%u) does not match our vendor ID (%u).", nodeData.vendorId,
+                            payload.vendorID);
+            continue;
+        }
 
-    // The advertisement may not include a product id.
-    if (IdIsPresent(mPayloadProductID) && IdIsPresent(nodeData.productId) && mPayloadProductID != nodeData.productId)
-    {
-        ChipLogProgress(Controller, "Discovered device does not match our product id.");
-        return false;
-    }
+        // The advertisement may not include a product id, and the payload may not have one either.
+        if (IdIsPresent(payload.productID) && IdIsPresent(nodeData.productId) && payload.productID != nodeData.productId)
+        {
+            ChipLogProgress(Controller, "Discovered device product ID (%u) does not match our product ID (%u).", nodeData.productId,
+                            payload.productID);
+            continue;
+        }
 
-    bool discriminatorMatches = false;
-    switch (mCurrentFilter.type)
-    {
-    case Dnssd::DiscoveryFilterType::kShortDiscriminator:
-        discriminatorMatches = (((nodeData.longDiscriminator >> 8) & 0x0F) == mCurrentFilter.code);
-        break;
-    case Dnssd::DiscoveryFilterType::kLongDiscriminator:
-        discriminatorMatches = (nodeData.longDiscriminator == mCurrentFilter.code);
-        break;
-    case Dnssd::DiscoveryFilterType::kNone:
-        ChipLogDetail(Controller, "Filter type none; all matches will fail");
-        return false;
-    default:
-        ChipLogError(Controller, "Unknown filter type; all matches will fail");
-        return false;
-    }
-    if (!discriminatorMatches)
-    {
-        ChipLogProgress(Controller, "Discovered device does not match our discriminator.");
+        if (!payload.discriminator.MatchesLongDiscriminator(nodeData.longDiscriminator))
+        {
+            ChipLogProgress(Controller, "Discovered device discriminator (%u) does not match our discriminator.",
+                            nodeData.longDiscriminator);
+            continue;
+        }
+
+        ChipLogProgress(Controller, "Discovered device with discriminator %u matches one of our setup payloads",
+                        nodeData.longDiscriminator);
+        return true;
     }
-    return discriminatorMatches;
+
+    return false;
 }
 
 void SetUpCodePairer::NotifyCommissionableDeviceDiscovered(const Dnssd::DiscoveredNodeData & nodeData)
@@ -480,23 +550,26 @@ void SetUpCodePairer::NotifyCommissionableDeviceDiscovered(const Dnssd::Discover
 
     ChipLogProgress(Controller, "Discovered device to be commissioned over DNS-SD");
 
-    NotifyCommissionableDeviceDiscovered(nodeData.Get<Dnssd::CommissionNodeData>());
+    auto & commissionableNodeData = nodeData.Get<Dnssd::CommissionNodeData>();
+
+    NotifyCommissionableDeviceDiscovered(commissionableNodeData, std::make_optional(commissionableNodeData.longDiscriminator));
 }
 
-void SetUpCodePairer::NotifyCommissionableDeviceDiscovered(const Dnssd::CommonResolutionData & resolutionData)
+void SetUpCodePairer::NotifyCommissionableDeviceDiscovered(const Dnssd::CommonResolutionData & resolutionData,
+                                                           std::optional<uint16_t> matchedLongDiscriminator)
 {
     if (mDiscoveryType == DiscoveryType::kDiscoveryNetworkOnlyWithoutPASEAutoRetry)
     {
         // If the discovery type does not want the PASE auto retry mechanism, we will just store
         // a single IP. So the discovery process is stopped as it won't be of any help anymore.
         StopDiscoveryOverDNSSD();
-        mDiscoveredParameters.emplace_back(resolutionData, 0);
+        mDiscoveredParameters.emplace_back(resolutionData, matchedLongDiscriminator, 0);
     }
     else
     {
         for (size_t i = 0; i < resolutionData.numIPs; i++)
         {
-            mDiscoveredParameters.emplace_back(resolutionData, i);
+            mDiscoveredParameters.emplace_back(resolutionData, matchedLongDiscriminator, i);
         }
     }
 
@@ -570,6 +643,8 @@ void SetUpCodePairer::ResetDiscoveryState()
     mCurrentPASEParameters.ClearValue();
     mLastPASEError = CHIP_NO_ERROR;
 
+    mSetupPayloads.clear();
+
     mSystemLayer->CancelTimer(OnDeviceDiscoveredTimeoutCallback, this);
 }
 
@@ -712,7 +787,31 @@ void SetUpCodePairer::OnDeviceDiscoveredTimeoutCallback(System::Layer * layer, v
     }
 }
 
-SetUpCodePairerParameters::SetUpCodePairerParameters(const Dnssd::CommonResolutionData & data, size_t index)
+bool SetUpCodePairer::ShouldDiscoverUsing(RendezvousInformationFlag commissioningChannel) const
+{
+    for (auto & payload : mSetupPayloads)
+    {
+        auto & rendezvousInformation = payload.rendezvousInformation;
+        if (!rendezvousInformation.HasValue())
+        {
+            // No idea which commissioning channels this device supports, so we
+            // should be trying using all of them.
+            return true;
+        }
+
+        if (rendezvousInformation.Value().Has(commissioningChannel))
+        {
+            return true;
+        }
+    }
+
+    // None of the payloads claimed support for this commissioning channel.
+    return false;
+}
+
+SetUpCodePairerParameters::SetUpCodePairerParameters(const Dnssd::CommonResolutionData & data,
+                                                     std::optional<uint16_t> longDiscriminator, size_t index) :
+    mLongDiscriminator(longDiscriminator)
 {
     mInterfaceId = data.interfaceId;
     Platform::CopyString(mHostName, data.hostName);
@@ -732,7 +831,9 @@ SetUpCodePairerParameters::SetUpCodePairerParameters(const Dnssd::CommonResoluti
 }
 
 #if CONFIG_NETWORK_LAYER_BLE
-SetUpCodePairerParameters::SetUpCodePairerParameters(BLE_CONNECTION_OBJECT connObj, bool connected)
+SetUpCodePairerParameters::SetUpCodePairerParameters(BLE_CONNECTION_OBJECT connObj, std::optional<uint16_t> longDiscriminator,
+                                                     bool connected) :
+    mLongDiscriminator(longDiscriminator)
 {
     Transport::PeerAddress peerAddress = Transport::PeerAddress::BLE();
     SetPeerAddress(peerAddress);
diff --git a/src/controller/SetUpCodePairer.h b/src/controller/SetUpCodePairer.h
index baa80bb75f796c..9d4ec1c1a18875 100644
--- a/src/controller/SetUpCodePairer.h
+++ b/src/controller/SetUpCodePairer.h
@@ -42,22 +42,37 @@
 #include <controller/DeviceDiscoveryDelegate.h>
 
 #include <deque>
+#include <optional>
+#include <vector>
 
 namespace chip {
 namespace Controller {
 
 class DeviceCommissioner;
 
+/**
+ * A class that represents a discovered device.  This includes both the inputs to discovery (via the
+ * RendezvousParameters super-class), and the outputs from discovery (the PeerAddress in
+ * RendezvousParameters but also some of our members like mHostName, mInterfaceId,
+ * mLongDiscriminator).
+ */
 class SetUpCodePairerParameters : public RendezvousParameters
 {
 public:
     SetUpCodePairerParameters() = default;
-    SetUpCodePairerParameters(const Dnssd::CommonResolutionData & data, size_t index);
+    SetUpCodePairerParameters(const Dnssd::CommonResolutionData & data, std::optional<uint16_t> longDiscriminator, size_t index);
 #if CONFIG_NETWORK_LAYER_BLE
-    SetUpCodePairerParameters(BLE_CONNECTION_OBJECT connObj, bool connected = true);
+    SetUpCodePairerParameters(BLE_CONNECTION_OBJECT connObj, std::optional<uint16_t> longDiscriminator, bool connected = true);
 #endif // CONFIG_NETWORK_LAYER_BLE
     char mHostName[Dnssd::kHostNameMaxLength + 1] = {};
     Inet::InterfaceId mInterfaceId;
+
+    // The long discriminator of the device that was actually discovered, if this is known.  This
+    // differs from the mSetupDiscriminator member of RendezvousParameters in that the latter may be
+    // a short discriminator from a numeric setup code (which may match multiple devices), while
+    // this member, if set, is always a long discriminator that was actually advertised by the
+    // device represented by our PeerAddress.
+    std::optional<uint16_t> mLongDiscriminator = std::nullopt;
 };
 
 enum class SetupCodePairerBehaviour : uint8_t
@@ -104,14 +119,14 @@ class DLL_EXPORT SetUpCodePairer : public DevicePairingDelegate
     void OnPairingDeleted(CHIP_ERROR error) override;
     void OnCommissioningComplete(NodeId deviceId, CHIP_ERROR error) override;
 
-    CHIP_ERROR Connect(SetupPayload & paload);
-    CHIP_ERROR StartDiscoveryOverBLE(SetupPayload & payload);
+    CHIP_ERROR Connect();
+    CHIP_ERROR StartDiscoveryOverBLE();
     CHIP_ERROR StopDiscoveryOverBLE();
-    CHIP_ERROR StartDiscoveryOverDNSSD(SetupPayload & payload);
+    CHIP_ERROR StartDiscoveryOverDNSSD();
     CHIP_ERROR StopDiscoveryOverDNSSD();
-    CHIP_ERROR StartDiscoveryOverSoftAP(SetupPayload & payload);
+    CHIP_ERROR StartDiscoveryOverSoftAP();
     CHIP_ERROR StopDiscoveryOverSoftAP();
-    CHIP_ERROR StartDiscoveryOverWiFiPAF(SetupPayload & payload);
+    CHIP_ERROR StartDiscoveryOverWiFiPAF();
     CHIP_ERROR StopDiscoveryOverWiFiPAF();
 
     // Returns whether we have kicked off a new connection attempt.
@@ -160,16 +175,19 @@ class DLL_EXPORT SetUpCodePairer : public DevicePairingDelegate
         kTransportTypeCount,
     };
 
-    void NotifyCommissionableDeviceDiscovered(const chip::Dnssd::CommonResolutionData & resolutionData);
+    void NotifyCommissionableDeviceDiscovered(const chip::Dnssd::CommonResolutionData & resolutionData,
+                                              std::optional<uint16_t> matchedLongDiscriminator);
 
     static void OnDeviceDiscoveredTimeoutCallback(System::Layer * layer, void * context);
 
 #if CONFIG_NETWORK_LAYER_BLE
     Ble::BleLayer * mBleLayer = nullptr;
-    void OnDiscoveredDeviceOverBle(BLE_CONNECTION_OBJECT connObj);
+    void OnDiscoveredDeviceOverBle(BLE_CONNECTION_OBJECT connObj, std::optional<uint16_t> matchedLongDiscriminator);
     void OnBLEDiscoveryError(CHIP_ERROR err);
     /////////// BLEConnectionDelegate Callbacks /////////
     static void OnDiscoveredDeviceOverBleSuccess(void * appState, BLE_CONNECTION_OBJECT connObj);
+    static void OnDiscoveredDeviceWithDiscriminatorOverBleSuccess(void * appState, uint16_t matchedLongDiscriminator,
+                                                                  BLE_CONNECTION_OBJECT connObj);
     static void OnDiscoveredDeviceOverBleError(void * appState, CHIP_ERROR err);
 #endif // CONFIG_NETWORK_LAYER_BLE
 #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
@@ -182,20 +200,17 @@ class DLL_EXPORT SetUpCodePairer : public DevicePairingDelegate
     bool NodeMatchesCurrentFilter(const Dnssd::DiscoveredNodeData & nodeData) const;
     static bool IdIsPresent(uint16_t vendorOrProductID);
 
-    Dnssd::DiscoveryFilter mCurrentFilter;
-    // The vendor id and product id from the SetupPayload.  They may be 0, which
-    // indicates "not available" (e.g. because the SetupPayload came from a
-    // short manual code).  In that case we should not filter on those values.
+    bool ShouldDiscoverUsing(RendezvousInformationFlag commissioningChannel) const;
+
+    // kNotAvailable represents unavailable vendor/product ID values in setup payloads.
     static constexpr uint16_t kNotAvailable = 0;
-    uint16_t mPayloadVendorID               = kNotAvailable;
-    uint16_t mPayloadProductID              = kNotAvailable;
 
     DeviceCommissioner * mCommissioner       = nullptr;
     System::Layer * mSystemLayer             = nullptr;
     chip::NodeId mRemoteId                   = kUndefinedNodeId;
-    uint32_t mSetUpPINCode                   = 0;
     SetupCodePairerBehaviour mConnectionType = SetupCodePairerBehaviour::kCommission;
     DiscoveryType mDiscoveryType             = DiscoveryType::kAll;
+    std::vector<SetupPayload> mSetupPayloads;
 
     // While we are trying to pair, we intercept the DevicePairingDelegate
     // notifications from mCommissioner.  We want to make sure we send them on


Reviews:
user: login: copilot-pull-request-reviewer[bot]
body: ## Pull Request Overview

This PR adds support for concatenated QR codes in SetUpCodePairer by extending the APIs to accept multiple setup payloads and an optional long discriminator. The changes include updated method signatures to use std::optional for long discriminators, revised discovery methods that operate on a vector of payloads, and corresponding updates in BLE connection APIs and chip-tool usage.

### Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

<details>
<summary>Show a summary per file</summary>

| File                           | Description                                                      |
| ------------------------------ | ---------------------------------------------------------------- |
| src/controller/SetUpCodePairer.h | Updated function signatures and added long discriminator support  |
| src/controller/SetUpCodePairer.cpp | Revised device pairing and discovery logic for multiple payloads  |
| src/ble/BleLayer.h & BleLayer.cpp | Introduced new API for creating connections using multiple discriminators |
| src/ble/BleConnectionDelegate.h | Added callback for connections established by discriminator matching |
| examples/chip-tool/commands/common/DeviceScanner.cpp | Adjusted parameter initialization for updated pairing parameters |
</details>



<details>
<summary>Comments suppressed due to low confidence (1)</summary>

**src/controller/SetUpCodePairer.cpp:631**
* [nitpick] Clearing mSetupPayloads in ResetDiscoveryState may inadvertently drop stored payloads from a concatenated QR session; please verify that this behavior is consistent with the intended multi-payload discovery flow.
```
mSetupPayloads.clear();
```
</details>


state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-13T21:23:25Z
user: login: bzbarsky-apple
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-13T21:38:02Z
user: login: ksperling-apple
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T01:42:43Z
user: login: bzbarsky-apple
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-22T20:38:42Z
user: login: andy31415
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-22T20:54:23Z
user: login: andy31415
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-22T20:55:13Z
user: login: andy31415
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-22T20:58:17Z
user: login: andy31415
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-22T20:59:39Z
user: login: bzbarsky-apple
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-24T03:16:03Z
user: login: bzbarsky-apple
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-24T03:19:02Z
user: login: andy31415
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-26T11:45:33Z
user: login: andy31415
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-26T11:45:53Z
user: login: andy31415
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-26T11:47:54Z
user: login: andy31415
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-26T11:48:49Z
user: login: andy31415
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-26T11:52:06Z
user: login: andy31415
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-26T11:54:44Z
user: login: andy31415
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-26T11:56:58Z
user: login: andy31415
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-26T11:58:28Z
user: login: andy31415
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-26T12:02:06Z
user: login: andy31415
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-26T12:03:31Z
user: login: bzbarsky-apple
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-27T16:13:53Z
user: login: bzbarsky-apple
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-27T16:14:45Z
user: login: bzbarsky-apple
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-27T16:15:19Z
user: login: bzbarsky-apple
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-27T16:15:49Z
user: login: bzbarsky-apple
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-27T16:16:47Z
user: login: bzbarsky-apple
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-27T16:18:22Z
user: login: andy31415
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-27T16:27:23Z
user: login: bzbarsky-apple
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-27T16:41:36Z
user: login: bzbarsky-apple
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-27T17:09:29Z

Review comments:
diff_hunk: @@ -40,61 +41,44 @@ using namespace chip::Tracing;
 namespace chip {
 namespace Controller {
 
-namespace {
-
-CHIP_ERROR GetPayload(const char * setUpCode, SetupPayload & payload)
-{
-    bool isQRCode = strncmp(setUpCode, kQRCodePrefix, strlen(kQRCodePrefix)) == 0;
-    if (isQRCode)
-    {
-        ReturnErrorOnFailure(QRCodeSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidQRCodePayload(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-    else
-    {
-        ReturnErrorOnFailure(ManualSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidManualCode(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-
-    return CHIP_NO_ERROR;
-}
-} // namespace
-
 CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode, SetupCodePairerBehaviour commission,
                                        DiscoveryType discoveryType, Optional<Dnssd::CommonResolutionData> resolutionData)
 {
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, mSystemLayer != nullptr, CHIP_ERROR_INCORRECT_STATE);
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, remoteId != kUndefinedNodeId, CHIP_ERROR_INVALID_ARGUMENT);
 
-    SetupPayload payload;
-    ReturnErrorOnFailure(GetPayload(setUpCode, payload));
+    std::vector<SetupPayload> payloads;
+    ReturnErrorOnFailure(SetupPayload::FromStringRepresentation(setUpCode, payloads));
 
-    if (resolutionData.HasValue())
+    if (resolutionData.HasValue() && payloads.size() == 1 && mSetupPayloads.size() == 1)
     {
         VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, discoveryType != DiscoveryType::kAll,
                                       CHIP_ERROR_INVALID_ARGUMENT);
-        if (mRemoteId == remoteId && mSetUpPINCode == payload.setUpPINCode && mConnectionType == commission &&
+        if (mRemoteId == remoteId && mSetupPayloads[0].setUpPINCode == payloads[0].setUpPINCode && mConnectionType == commission &&
path: src/controller/SetUpCodePairer.cpp
user: login: Copilot
body: The condition checks mSetupPayloads.size() before mSetupPayloads is assigned (it is set only later via std::move(payloads)), which might lead to inconsistent behavior when processing concatenated QR codes. Consider basing the condition solely on the newly parsed 'payloads' or ensuring mSetupPayloads is properly initialized beforehand.
created_at: 2025-05-13T21:23:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -40,61 +41,44 @@ using namespace chip::Tracing;
 namespace chip {
 namespace Controller {
 
-namespace {
-
-CHIP_ERROR GetPayload(const char * setUpCode, SetupPayload & payload)
-{
-    bool isQRCode = strncmp(setUpCode, kQRCodePrefix, strlen(kQRCodePrefix)) == 0;
-    if (isQRCode)
-    {
-        ReturnErrorOnFailure(QRCodeSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidQRCodePayload(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-    else
-    {
-        ReturnErrorOnFailure(ManualSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidManualCode(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-
-    return CHIP_NO_ERROR;
-}
-} // namespace
-
 CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode, SetupCodePairerBehaviour commission,
                                        DiscoveryType discoveryType, Optional<Dnssd::CommonResolutionData> resolutionData)
 {
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, mSystemLayer != nullptr, CHIP_ERROR_INCORRECT_STATE);
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, remoteId != kUndefinedNodeId, CHIP_ERROR_INVALID_ARGUMENT);
 
-    SetupPayload payload;
-    ReturnErrorOnFailure(GetPayload(setUpCode, payload));
+    std::vector<SetupPayload> payloads;
+    ReturnErrorOnFailure(SetupPayload::FromStringRepresentation(setUpCode, payloads));
 
-    if (resolutionData.HasValue())
+    if (resolutionData.HasValue() && payloads.size() == 1 && mSetupPayloads.size() == 1)
     {
         VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, discoveryType != DiscoveryType::kAll,
                                       CHIP_ERROR_INVALID_ARGUMENT);
-        if (mRemoteId == remoteId && mSetUpPINCode == payload.setUpPINCode && mConnectionType == commission &&
+        if (mRemoteId == remoteId && mSetupPayloads[0].setUpPINCode == payloads[0].setUpPINCode && mConnectionType == commission &&
path: src/controller/SetUpCodePairer.cpp
user: login: bzbarsky-apple
body: This is explicitly checking for what the old payloads were before this call.
created_at: 2025-05-13T21:38:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -310,7 +316,45 @@ bool SetUpCodePairer::ConnectToDiscoveredDevice()
         SetUpCodePairerParameters params(mDiscoveredParameters.front());
         mDiscoveredParameters.pop_front();
 
-        params.SetSetupPINCode(mSetUpPINCode);
+        if (params.mLongDiscriminator)
+        {
+            auto longDiscriminator = *params.mLongDiscriminator;
+            // Look for a matching setup passcode.
+            bool found = false;
+            for (auto & payload : mSetupPayloads)
+            {
+                if (payload.discriminator.MatchesLongDiscriminator(longDiscriminator))
+                {
+                    params.SetSetupPINCode(payload.setUpPINCode);
+                    found = true;
+                    break;
+                }
+            }
+            if (!found)
+            {
+                ChipLogError(Controller, "SetUpCodePairer discovered discriminator %u does not match any of our setup payloads",
path: src/controller/SetUpCodePairer.cpp
user: login: ksperling-apple
body: ```suggestion
                ChipLogError(Controller, "SetUpCodePairer: Discovered discriminator %u does not match any of our setup payloads",
```

(Or get rid of the "SetupCodePairer" prefix entirely since the rest of the logging in this class doesn't appear to do that either.)
created_at: 2025-05-15T01:32:51Z
author_association: CONTRIBUTOR
diff_hunk: @@ -310,7 +316,45 @@ bool SetUpCodePairer::ConnectToDiscoveredDevice()
         SetUpCodePairerParameters params(mDiscoveredParameters.front());
         mDiscoveredParameters.pop_front();
 
-        params.SetSetupPINCode(mSetUpPINCode);
+        if (params.mLongDiscriminator)
+        {
+            auto longDiscriminator = *params.mLongDiscriminator;
+            // Look for a matching setup passcode.
+            bool found = false;
+            for (auto & payload : mSetupPayloads)
+            {
+                if (payload.discriminator.MatchesLongDiscriminator(longDiscriminator))
+                {
+                    params.SetSetupPINCode(payload.setUpPINCode);
+                    found = true;
+                    break;
+                }
+            }
+            if (!found)
+            {
+                ChipLogError(Controller, "SetUpCodePairer discovered discriminator %u does not match any of our setup payloads",
+                             longDiscriminator);
+                // Move on to the the next discovered params; nothing we can do here.
+                continue;
+            }
+        }
+        else
+        {
+            // No discriminator known for this discovered device.  This can work if we have only one
+            // setup payload, but otherwise we have no idea what setup passcode to use for it.
+            if (mSetupPayloads.size() == 1)
+            {
+                params.SetSetupPINCode(mSetupPayloads[0].setUpPINCode);
+            }
+            else
+            {
+                ChipLogError(Controller,
+                             "SetUpCodePairer unable to handle discovered parameters with no discriminator, because it has %u "
path: src/controller/SetUpCodePairer.cpp
user: login: ksperling-apple
body: ```suggestion
                             "SetUpCodePairer: Unable to handle discovered parameters with no discriminator, because it has %u "
```
created_at: 2025-05-15T01:33:15Z
author_association: CONTRIBUTOR
diff_hunk: @@ -392,6 +449,8 @@ void SetUpCodePairer::OnDiscoveredDeviceOverWifiPAF()
     mWaitingForDiscovery[kWiFiPAFTransport] = false;
     auto param                              = SetUpCodePairerParameters();
     param.SetPeerAddress(Transport::PeerAddress(Transport::Type::kWiFiPAF, mRemoteId));
+    // TODO: This needs to support concatenated QR codes and set the relevant
path: src/controller/SetUpCodePairer.cpp
user: login: ksperling-apple
body: File an issue?
created_at: 2025-05-15T01:34:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -392,6 +449,8 @@ void SetUpCodePairer::OnDiscoveredDeviceOverWifiPAF()
     mWaitingForDiscovery[kWiFiPAFTransport] = false;
     auto param                              = SetUpCodePairerParameters();
     param.SetPeerAddress(Transport::PeerAddress(Transport::Type::kWiFiPAF, mRemoteId));
+    // TODO: This needs to support concatenated QR codes and set the relevant
path: src/controller/SetUpCodePairer.cpp
user: login: bzbarsky-apple
body: https://github.com/project-chip/connectedhomeip/issues/39134
created_at: 2025-05-22T20:38:42Z
author_association: CONTRIBUTOR
diff_hunk: @@ -40,61 +41,44 @@ using namespace chip::Tracing;
 namespace chip {
 namespace Controller {
 
-namespace {
-
-CHIP_ERROR GetPayload(const char * setUpCode, SetupPayload & payload)
-{
-    bool isQRCode = strncmp(setUpCode, kQRCodePrefix, strlen(kQRCodePrefix)) == 0;
-    if (isQRCode)
-    {
-        ReturnErrorOnFailure(QRCodeSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidQRCodePayload(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-    else
-    {
-        ReturnErrorOnFailure(ManualSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidManualCode(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-
-    return CHIP_NO_ERROR;
-}
-} // namespace
-
 CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode, SetupCodePairerBehaviour commission,
                                        DiscoveryType discoveryType, Optional<Dnssd::CommonResolutionData> resolutionData)
 {
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, mSystemLayer != nullptr, CHIP_ERROR_INCORRECT_STATE);
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, remoteId != kUndefinedNodeId, CHIP_ERROR_INVALID_ARGUMENT);
 
-    SetupPayload payload;
-    ReturnErrorOnFailure(GetPayload(setUpCode, payload));
+    std::vector<SetupPayload> payloads;
+    ReturnErrorOnFailure(SetupPayload::FromStringRepresentation(setUpCode, payloads));
 
-    if (resolutionData.HasValue())
+    if (resolutionData.HasValue() && payloads.size() == 1 && mSetupPayloads.size() == 1)
path: src/controller/SetUpCodePairer.cpp
user: login: andy31415
body: some explanation comment on why the `== 1` is happening would be nice: when do we expect this codepath to be taken and when not (i.e. when payloads has 1 and not and when is mSetuppayload 1 or not).


created_at: 2025-05-22T20:54:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -40,61 +41,44 @@ using namespace chip::Tracing;
 namespace chip {
 namespace Controller {
 
-namespace {
-
-CHIP_ERROR GetPayload(const char * setUpCode, SetupPayload & payload)
-{
-    bool isQRCode = strncmp(setUpCode, kQRCodePrefix, strlen(kQRCodePrefix)) == 0;
-    if (isQRCode)
-    {
-        ReturnErrorOnFailure(QRCodeSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidQRCodePayload(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-    else
-    {
-        ReturnErrorOnFailure(ManualSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidManualCode(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-
-    return CHIP_NO_ERROR;
-}
-} // namespace
-
 CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode, SetupCodePairerBehaviour commission,
                                        DiscoveryType discoveryType, Optional<Dnssd::CommonResolutionData> resolutionData)
 {
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, mSystemLayer != nullptr, CHIP_ERROR_INCORRECT_STATE);
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, remoteId != kUndefinedNodeId, CHIP_ERROR_INVALID_ARGUMENT);
 
-    SetupPayload payload;
-    ReturnErrorOnFailure(GetPayload(setUpCode, payload));
+    std::vector<SetupPayload> payloads;
+    ReturnErrorOnFailure(SetupPayload::FromStringRepresentation(setUpCode, payloads));
 
-    if (resolutionData.HasValue())
+    if (resolutionData.HasValue() && payloads.size() == 1 && mSetupPayloads.size() == 1)
     {
         VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, discoveryType != DiscoveryType::kAll,
                                       CHIP_ERROR_INVALID_ARGUMENT);
-        if (mRemoteId == remoteId && mSetUpPINCode == payload.setUpPINCode && mConnectionType == commission &&
+        if (mRemoteId == remoteId && mSetupPayloads[0].setUpPINCode == payloads[0].setUpPINCode && mConnectionType == commission &&
             mDiscoveryType == discoveryType)
         {
-            NotifyCommissionableDeviceDiscovered(resolutionData.Value());
+            // Not passing a discriminator is ok, since we have only one payload.
+            NotifyCommissionableDeviceDiscovered(resolutionData.Value(), std::nullopt);
path: src/controller/SetUpCodePairer.cpp
user: login: andy31415
body: ```suggestion
            NotifyCommissionableDeviceDiscovered(resolutionData.Value(), std::nullopt /* matchedNodeDiscriminator */);
```

maybe change it in the other places as well.
created_at: 2025-05-22T20:55:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -40,61 +41,44 @@ using namespace chip::Tracing;
 namespace chip {
 namespace Controller {
 
-namespace {
-
-CHIP_ERROR GetPayload(const char * setUpCode, SetupPayload & payload)
-{
-    bool isQRCode = strncmp(setUpCode, kQRCodePrefix, strlen(kQRCodePrefix)) == 0;
-    if (isQRCode)
-    {
-        ReturnErrorOnFailure(QRCodeSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidQRCodePayload(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-    else
-    {
-        ReturnErrorOnFailure(ManualSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidManualCode(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-
-    return CHIP_NO_ERROR;
-}
-} // namespace
-
 CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode, SetupCodePairerBehaviour commission,
                                        DiscoveryType discoveryType, Optional<Dnssd::CommonResolutionData> resolutionData)
 {
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, mSystemLayer != nullptr, CHIP_ERROR_INCORRECT_STATE);
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, remoteId != kUndefinedNodeId, CHIP_ERROR_INVALID_ARGUMENT);
 
-    SetupPayload payload;
-    ReturnErrorOnFailure(GetPayload(setUpCode, payload));
+    std::vector<SetupPayload> payloads;
+    ReturnErrorOnFailure(SetupPayload::FromStringRepresentation(setUpCode, payloads));
 
-    if (resolutionData.HasValue())
+    if (resolutionData.HasValue() && payloads.size() == 1 && mSetupPayloads.size() == 1)
path: src/controller/SetUpCodePairer.cpp
user: login: andy31415
body: And in particular what does the code below do? It seems to do a check of "if all inputs are the same as what is already stored in the object, then call discovered" ... why does that check not extend to "if I pass an identical payload array" and only applies to "if I send a single identical element"?
created_at: 2025-05-22T20:58:17Z
author_association: CONTRIBUTOR
diff_hunk: @@ -40,61 +41,44 @@ using namespace chip::Tracing;
 namespace chip {
 namespace Controller {
 
-namespace {
-
-CHIP_ERROR GetPayload(const char * setUpCode, SetupPayload & payload)
-{
-    bool isQRCode = strncmp(setUpCode, kQRCodePrefix, strlen(kQRCodePrefix)) == 0;
-    if (isQRCode)
-    {
-        ReturnErrorOnFailure(QRCodeSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidQRCodePayload(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-    else
-    {
-        ReturnErrorOnFailure(ManualSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidManualCode(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-
-    return CHIP_NO_ERROR;
-}
-} // namespace
-
 CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode, SetupCodePairerBehaviour commission,
                                        DiscoveryType discoveryType, Optional<Dnssd::CommonResolutionData> resolutionData)
 {
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, mSystemLayer != nullptr, CHIP_ERROR_INCORRECT_STATE);
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, remoteId != kUndefinedNodeId, CHIP_ERROR_INVALID_ARGUMENT);
 
-    SetupPayload payload;
-    ReturnErrorOnFailure(GetPayload(setUpCode, payload));
+    std::vector<SetupPayload> payloads;
+    ReturnErrorOnFailure(SetupPayload::FromStringRepresentation(setUpCode, payloads));
 
-    if (resolutionData.HasValue())
+    if (resolutionData.HasValue() && payloads.size() == 1 && mSetupPayloads.size() == 1)
     {
         VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, discoveryType != DiscoveryType::kAll,
                                       CHIP_ERROR_INVALID_ARGUMENT);
-        if (mRemoteId == remoteId && mSetUpPINCode == payload.setUpPINCode && mConnectionType == commission &&
+        if (mRemoteId == remoteId && mSetupPayloads[0].setUpPINCode == payloads[0].setUpPINCode && mConnectionType == commission &&
             mDiscoveryType == discoveryType)
         {
-            NotifyCommissionableDeviceDiscovered(resolutionData.Value());
+            // Not passing a discriminator is ok, since we have only one payload.
+            NotifyCommissionableDeviceDiscovered(resolutionData.Value(), std::nullopt);
             return CHIP_NO_ERROR;
         }
     }
 
+    ResetDiscoveryState();
+
     mConnectionType = commission;
     mDiscoveryType  = discoveryType;
     mRemoteId       = remoteId;
-    mSetUpPINCode   = payload.setUpPINCode;
-
-    ResetDiscoveryState();
+    mSetupPayloads  = std::move(payloads);
 
-    if (resolutionData.HasValue())
+    if (resolutionData.HasValue() && mSetupPayloads.size() == 1)
     {
-        NotifyCommissionableDeviceDiscovered(resolutionData.Value());
+        // No need to pass in a discriminator if we have only one payload, which
+        // is good because we don't have a full discriminator here anyway.
+        NotifyCommissionableDeviceDiscovered(resolutionData.Value(), std::nullopt);
         return CHIP_NO_ERROR;
     }
 
-    ReturnErrorOnFailureWithMetric(kMetricSetupCodePairerPairDevice, Connect(payload));
+    ReturnErrorOnFailureWithMetric(kMetricSetupCodePairerPairDevice, Connect());
path: src/controller/SetUpCodePairer.cpp
user: login: andy31415
body: should we log something here? I undrstand here that we have a resolution data, but our mSetupPayloads is larger than 1 ... so we are saying we failed to pair?

Old code seems to say: if you have resolution data then we succeed, otherwise we fail. In the new code we say "if you have resolution data but more than one payload, we still fail as if we had no resolution data". Following what the code is doing through some logs seems beneficial.
created_at: 2025-05-22T20:59:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -40,61 +41,44 @@ using namespace chip::Tracing;
 namespace chip {
 namespace Controller {
 
-namespace {
-
-CHIP_ERROR GetPayload(const char * setUpCode, SetupPayload & payload)
-{
-    bool isQRCode = strncmp(setUpCode, kQRCodePrefix, strlen(kQRCodePrefix)) == 0;
-    if (isQRCode)
-    {
-        ReturnErrorOnFailure(QRCodeSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidQRCodePayload(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-    else
-    {
-        ReturnErrorOnFailure(ManualSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidManualCode(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-
-    return CHIP_NO_ERROR;
-}
-} // namespace
-
 CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode, SetupCodePairerBehaviour commission,
                                        DiscoveryType discoveryType, Optional<Dnssd::CommonResolutionData> resolutionData)
 {
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, mSystemLayer != nullptr, CHIP_ERROR_INCORRECT_STATE);
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, remoteId != kUndefinedNodeId, CHIP_ERROR_INVALID_ARGUMENT);
 
-    SetupPayload payload;
-    ReturnErrorOnFailure(GetPayload(setUpCode, payload));
+    std::vector<SetupPayload> payloads;
+    ReturnErrorOnFailure(SetupPayload::FromStringRepresentation(setUpCode, payloads));
 
-    if (resolutionData.HasValue())
+    if (resolutionData.HasValue() && payloads.size() == 1 && mSetupPayloads.size() == 1)
path: src/controller/SetUpCodePairer.cpp
user: login: bzbarsky-apple
body: This is just preserving an existing hacky codepath that only ever has one value.  I'll add comments.
created_at: 2025-05-24T03:16:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -40,61 +41,44 @@ using namespace chip::Tracing;
 namespace chip {
 namespace Controller {
 
-namespace {
-
-CHIP_ERROR GetPayload(const char * setUpCode, SetupPayload & payload)
-{
-    bool isQRCode = strncmp(setUpCode, kQRCodePrefix, strlen(kQRCodePrefix)) == 0;
-    if (isQRCode)
-    {
-        ReturnErrorOnFailure(QRCodeSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidQRCodePayload(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-    else
-    {
-        ReturnErrorOnFailure(ManualSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidManualCode(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-
-    return CHIP_NO_ERROR;
-}
-} // namespace
-
 CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode, SetupCodePairerBehaviour commission,
                                        DiscoveryType discoveryType, Optional<Dnssd::CommonResolutionData> resolutionData)
 {
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, mSystemLayer != nullptr, CHIP_ERROR_INCORRECT_STATE);
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, remoteId != kUndefinedNodeId, CHIP_ERROR_INVALID_ARGUMENT);
 
-    SetupPayload payload;
-    ReturnErrorOnFailure(GetPayload(setUpCode, payload));
+    std::vector<SetupPayload> payloads;
+    ReturnErrorOnFailure(SetupPayload::FromStringRepresentation(setUpCode, payloads));
 
-    if (resolutionData.HasValue())
+    if (resolutionData.HasValue() && payloads.size() == 1 && mSetupPayloads.size() == 1)
     {
         VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, discoveryType != DiscoveryType::kAll,
                                       CHIP_ERROR_INVALID_ARGUMENT);
-        if (mRemoteId == remoteId && mSetUpPINCode == payload.setUpPINCode && mConnectionType == commission &&
+        if (mRemoteId == remoteId && mSetupPayloads[0].setUpPINCode == payloads[0].setUpPINCode && mConnectionType == commission &&
             mDiscoveryType == discoveryType)
         {
-            NotifyCommissionableDeviceDiscovered(resolutionData.Value());
+            // Not passing a discriminator is ok, since we have only one payload.
+            NotifyCommissionableDeviceDiscovered(resolutionData.Value(), std::nullopt);
             return CHIP_NO_ERROR;
         }
     }
 
+    ResetDiscoveryState();
+
     mConnectionType = commission;
     mDiscoveryType  = discoveryType;
     mRemoteId       = remoteId;
-    mSetUpPINCode   = payload.setUpPINCode;
-
-    ResetDiscoveryState();
+    mSetupPayloads  = std::move(payloads);
 
-    if (resolutionData.HasValue())
+    if (resolutionData.HasValue() && mSetupPayloads.size() == 1)
     {
-        NotifyCommissionableDeviceDiscovered(resolutionData.Value());
+        // No need to pass in a discriminator if we have only one payload, which
+        // is good because we don't have a full discriminator here anyway.
+        NotifyCommissionableDeviceDiscovered(resolutionData.Value(), std::nullopt);
         return CHIP_NO_ERROR;
     }
 
-    ReturnErrorOnFailureWithMetric(kMetricSetupCodePairerPairDevice, Connect(payload));
+    ReturnErrorOnFailureWithMetric(kMetricSetupCodePairerPairDevice, Connect());
path: src/controller/SetUpCodePairer.cpp
user: login: bzbarsky-apple
body: I don't follow the question.  If we have multiple payloads, then the fact that we were given only one resolution data is not enough to stop discovery, because we have multiple payloads.  This is not "failing", this is calling "do discovery", no?

Old code says: If you have resolution data, just use that, otherwise do discovery.

New code says: If you have resolution data (for one thing, by definition) and we were only looking for one thing, use that.  Otherwise, do discovery.
created_at: 2025-05-24T03:19:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -52,12 +54,13 @@ class SetUpCodePairerParameters : public RendezvousParameters
 {
 public:
     SetUpCodePairerParameters() = default;
-    SetUpCodePairerParameters(const Dnssd::CommonResolutionData & data, size_t index);
+    SetUpCodePairerParameters(const Dnssd::CommonResolutionData & data, std::optional<uint16_t> longDiscriminator, size_t index);
 #if CONFIG_NETWORK_LAYER_BLE
-    SetUpCodePairerParameters(BLE_CONNECTION_OBJECT connObj, bool connected = true);
+    SetUpCodePairerParameters(BLE_CONNECTION_OBJECT connObj, std::optional<uint16_t> longDiscriminator, bool connected = true);
path: src/controller/SetUpCodePairer.h
user: login: andy31415
body: if you switch the order of parameters, it would be more backwards compatible with old code ... or we are trying to fail at compile time on purpose?
created_at: 2025-05-26T11:45:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -52,12 +54,13 @@ class SetUpCodePairerParameters : public RendezvousParameters
 {
 public:
     SetUpCodePairerParameters() = default;
-    SetUpCodePairerParameters(const Dnssd::CommonResolutionData & data, size_t index);
+    SetUpCodePairerParameters(const Dnssd::CommonResolutionData & data, std::optional<uint16_t> longDiscriminator, size_t index);
 #if CONFIG_NETWORK_LAYER_BLE
-    SetUpCodePairerParameters(BLE_CONNECTION_OBJECT connObj, bool connected = true);
+    SetUpCodePairerParameters(BLE_CONNECTION_OBJECT connObj, std::optional<uint16_t> longDiscriminator, bool connected = true);
 #endif // CONFIG_NETWORK_LAYER_BLE
     char mHostName[Dnssd::kHostNameMaxLength + 1] = {};
     Inet::InterfaceId mInterfaceId;
+    std::optional<uint16_t> mLongDiscriminator = std::nullopt;
path: src/controller/SetUpCodePairer.h
user: login: andy31415
body: The classes in here could use some documentation - I have a hard time following the delta.

For example this derives from RendezvousParameters which has a mSetupDiscriminator which is essentially a short or a long discriminator ... so if that one is long we duplicate it? And if short we have both or we can have none? What the class contains seems a pain.

Since you went through these, any chance you could add some comments on usage/content?
created_at: 2025-05-26T11:45:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -164,8 +164,10 @@
     'src/lib/dnssd/minimal_mdns/ResponseSender.h': {'list'},
 
     # Not really for embedded consumers; uses std::deque to keep track
-    # of a list of discovered things.
-    'src/controller/SetUpCodePairer.h': {'deque'},
+    # of a list of discovered things and std::vector to keep track of
+    # lists of setup payloads and discriminators.
+    'src/controller/SetUpCodePairer.h': {'deque', 'vector'},
+    'src/controller/SetUpCodePairer.cpp': {'vector'},
path: scripts/tools/check_includes_config.py
user: login: andy31415
body: if h includes header, why do we also include it in the cpp?
created_at: 2025-05-26T11:47:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -164,8 +164,10 @@
     'src/lib/dnssd/minimal_mdns/ResponseSender.h': {'list'},
 
     # Not really for embedded consumers; uses std::deque to keep track
-    # of a list of discovered things.
-    'src/controller/SetUpCodePairer.h': {'deque'},
+    # of a list of discovered things and std::vector to keep track of
path: scripts/tools/check_includes_config.py
user: login: andy31415
body: maybe consider not explaining why we need these (that couples usage and is bound to become out of date if people just shuffle things around. It seems just saying "small embedded devices are not commissioners" or some variant of that may be sufficient.
created_at: 2025-05-26T11:48:49Z
author_association: CONTRIBUTOR
diff_hunk: @@ -40,61 +41,44 @@ using namespace chip::Tracing;
 namespace chip {
 namespace Controller {
 
-namespace {
-
-CHIP_ERROR GetPayload(const char * setUpCode, SetupPayload & payload)
-{
-    bool isQRCode = strncmp(setUpCode, kQRCodePrefix, strlen(kQRCodePrefix)) == 0;
-    if (isQRCode)
-    {
-        ReturnErrorOnFailure(QRCodeSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidQRCodePayload(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-    else
-    {
-        ReturnErrorOnFailure(ManualSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidManualCode(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-
-    return CHIP_NO_ERROR;
-}
-} // namespace
-
 CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode, SetupCodePairerBehaviour commission,
                                        DiscoveryType discoveryType, Optional<Dnssd::CommonResolutionData> resolutionData)
 {
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, mSystemLayer != nullptr, CHIP_ERROR_INCORRECT_STATE);
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, remoteId != kUndefinedNodeId, CHIP_ERROR_INVALID_ARGUMENT);
 
-    SetupPayload payload;
-    ReturnErrorOnFailure(GetPayload(setUpCode, payload));
+    std::vector<SetupPayload> payloads;
+    ReturnErrorOnFailure(SetupPayload::FromStringRepresentation(setUpCode, payloads));
 
-    if (resolutionData.HasValue())
+    if (resolutionData.HasValue() && payloads.size() == 1 && mSetupPayloads.size() == 1)
     {
         VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, discoveryType != DiscoveryType::kAll,
                                       CHIP_ERROR_INVALID_ARGUMENT);
-        if (mRemoteId == remoteId && mSetUpPINCode == payload.setUpPINCode && mConnectionType == commission &&
+        if (mRemoteId == remoteId && mSetupPayloads[0].setUpPINCode == payloads[0].setUpPINCode && mConnectionType == commission &&
             mDiscoveryType == discoveryType)
         {
-            NotifyCommissionableDeviceDiscovered(resolutionData.Value());
+            // Not passing a discriminator is ok, since we have only one payload.
+            NotifyCommissionableDeviceDiscovered(resolutionData.Value(), std::nullopt);
             return CHIP_NO_ERROR;
         }
     }
 
+    ResetDiscoveryState();
+
     mConnectionType = commission;
     mDiscoveryType  = discoveryType;
     mRemoteId       = remoteId;
-    mSetUpPINCode   = payload.setUpPINCode;
-
-    ResetDiscoveryState();
+    mSetupPayloads  = std::move(payloads);
 
-    if (resolutionData.HasValue())
+    if (resolutionData.HasValue() && mSetupPayloads.size() == 1)
     {
-        NotifyCommissionableDeviceDiscovered(resolutionData.Value());
+        // No need to pass in a discriminator if we have only one payload, which
+        // is good because we don't have a full discriminator here anyway.
+        NotifyCommissionableDeviceDiscovered(resolutionData.Value(), std::nullopt);
         return CHIP_NO_ERROR;
     }
 
-    ReturnErrorOnFailureWithMetric(kMetricSetupCodePairerPairDevice, Connect(payload));
+    ReturnErrorOnFailureWithMetric(kMetricSetupCodePairerPairDevice, Connect());
path: src/controller/SetUpCodePairer.cpp
user: login: andy31415
body: I misread the code path here. This whole code does not feel very easy to follow/read :( 
created_at: 2025-05-26T11:52:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -104,55 +88,50 @@ CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode,
     return errorCode;
 }
 
-CHIP_ERROR SetUpCodePairer::Connect(SetupPayload & payload)
+CHIP_ERROR SetUpCodePairer::Connect()
 {
-    CHIP_ERROR err = CHIP_NO_ERROR;
-    bool isRunning = false;
-
-    bool searchOverAll = !payload.rendezvousInformation.HasValue();
-
     if (mDiscoveryType == DiscoveryType::kAll)
     {
-        if (searchOverAll || payload.rendezvousInformation.Value().Has(RendezvousInformationFlag::kBLE))
+        if (ShouldDiscoverUsing(RendezvousInformationFlag::kBLE))
         {
-            if (CHIP_NO_ERROR == (err = StartDiscoveryOverBLE(payload)))
+            CHIP_ERROR err = StartDiscoveryOverBLE();
+            if (err != CHIP_NO_ERROR)
             {
-                isRunning = true;
+                ChipLogError(Controller, "Failed to start discovery over BLE: %" CHIP_ERROR_FORMAT, err.Format());
             }
-            VerifyOrReturnError(searchOverAll || CHIP_NO_ERROR == err || CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE == err, err);
         }
 
-        if (searchOverAll || payload.rendezvousInformation.Value().Has(RendezvousInformationFlag::kSoftAP))
+        if (ShouldDiscoverUsing(RendezvousInformationFlag::kSoftAP))
         {
-            if (CHIP_NO_ERROR == (err = StartDiscoveryOverSoftAP(payload)))
+            CHIP_ERROR err = StartDiscoveryOverSoftAP();
+            if (err != CHIP_NO_ERROR)
             {
-                isRunning = true;
+                ChipLogError(Controller, "Failed to start discovery over SoftAP: %" CHIP_ERROR_FORMAT, err.Format());
             }
-            VerifyOrReturnError(searchOverAll || CHIP_NO_ERROR == err || CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE == err, err);
         }
-        if (searchOverAll || payload.rendezvousInformation.Value().Has(RendezvousInformationFlag::kWiFiPAF))
+        if (ShouldDiscoverUsing(RendezvousInformationFlag::kWiFiPAF))
         {
-            ChipLogProgress(Controller, "WiFi-PAF: has RendezvousInformationFlag::kWiFiPAF");
-            if (CHIP_NO_ERROR == (err = StartDiscoveryOverWiFiPAF(payload)))
+            ChipLogProgress(Controller,
path: src/controller/SetUpCodePairer.cpp
user: login: andy31415
body: I realize we preserve logging here (and correct it), however why is this one-off? why do we log wifi-paf but not others?

It feels to me like this was "the new feature" and a logging path was added for that, however that makes the code inconsistent. I would rather drop this log or log the bitmaps somewhere or log consistently in every code path. Making wifipaf special is odd.
created_at: 2025-05-26T11:54:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -165,8 +144,24 @@ CHIP_ERROR SetUpCodePairer::StartDiscoveryOverBLE(SetupPayload & payload)
 
     // Handle possibly-sync callbacks.
     mWaitingForDiscovery[kBLETransport] = true;
-    CHIP_ERROR err = mBleLayer->NewBleConnectionByDiscriminator(payload.discriminator, this, OnDiscoveredDeviceOverBleSuccess,
-                                                                OnDiscoveredDeviceOverBleError);
+    CHIP_ERROR err;
+    if (mSetupPayloads.size() == 1)
+    {
+        err = mBleLayer->NewBleConnectionByDiscriminator(mSetupPayloads[0].discriminator, this, OnDiscoveredDeviceOverBleSuccess,
+                                                         OnDiscoveredDeviceOverBleError);
+    }
+    else
+    {
+        std::vector<SetupDiscriminator> discriminators;
+        discriminators.reserve(mSetupPayloads.size());
+        for (auto & payload : mSetupPayloads)
path: src/controller/SetUpCodePairer.cpp
user: login: andy31415
body: would the loop variant work for size 1 and > 1? If we would not have if/else the code would be easier to read.

What is the lifetime of the span? Since the vector is on the stack, should we add a comment saying that we know things are safe (I did not check...) ?
created_at: 2025-05-26T11:56:58Z
author_association: CONTRIBUTOR
diff_hunk: @@ -165,8 +144,24 @@ CHIP_ERROR SetUpCodePairer::StartDiscoveryOverBLE(SetupPayload & payload)
 
     // Handle possibly-sync callbacks.
     mWaitingForDiscovery[kBLETransport] = true;
-    CHIP_ERROR err = mBleLayer->NewBleConnectionByDiscriminator(payload.discriminator, this, OnDiscoveredDeviceOverBleSuccess,
-                                                                OnDiscoveredDeviceOverBleError);
+    CHIP_ERROR err;
+    if (mSetupPayloads.size() == 1)
+    {
+        err = mBleLayer->NewBleConnectionByDiscriminator(mSetupPayloads[0].discriminator, this, OnDiscoveredDeviceOverBleSuccess,
+                                                         OnDiscoveredDeviceOverBleError);
+    }
+    else
+    {
+        std::vector<SetupDiscriminator> discriminators;
+        discriminators.reserve(mSetupPayloads.size());
+        for (auto & payload : mSetupPayloads)
path: src/controller/SetUpCodePairer.cpp
user: login: andy31415
body: I see the calls are different - `OnDiscoveredDeviceOverBleSuccess` vs `OnDiscoveredDeviceWithDiscriminatorOverBleSuccess` ... why is that difference important? I would imagine a "discriminator array of size 1" would work the same as "discriminator array of size N".
created_at: 2025-05-26T11:58:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -40,61 +41,44 @@ using namespace chip::Tracing;
 namespace chip {
 namespace Controller {
 
-namespace {
-
-CHIP_ERROR GetPayload(const char * setUpCode, SetupPayload & payload)
-{
-    bool isQRCode = strncmp(setUpCode, kQRCodePrefix, strlen(kQRCodePrefix)) == 0;
-    if (isQRCode)
-    {
-        ReturnErrorOnFailure(QRCodeSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidQRCodePayload(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-    else
-    {
-        ReturnErrorOnFailure(ManualSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidManualCode(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-
-    return CHIP_NO_ERROR;
-}
-} // namespace
-
 CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode, SetupCodePairerBehaviour commission,
                                        DiscoveryType discoveryType, Optional<Dnssd::CommonResolutionData> resolutionData)
 {
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, mSystemLayer != nullptr, CHIP_ERROR_INCORRECT_STATE);
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, remoteId != kUndefinedNodeId, CHIP_ERROR_INVALID_ARGUMENT);
 
-    SetupPayload payload;
-    ReturnErrorOnFailure(GetPayload(setUpCode, payload));
+    std::vector<SetupPayload> payloads;
+    ReturnErrorOnFailure(SetupPayload::FromStringRepresentation(setUpCode, payloads));
 
-    if (resolutionData.HasValue())
+    if (resolutionData.HasValue() && payloads.size() == 1 && mSetupPayloads.size() == 1)
path: src/controller/SetUpCodePairer.cpp
user: login: andy31415
body: I guess my question is about why is a single element special. Hack code path seemed to have been "if input was identical" so why does that not extend to "if multi-item input is identical".

I do not find the existing code too readable :/ 
created_at: 2025-05-26T12:03:30Z
author_association: CONTRIBUTOR
diff_hunk: @@ -40,61 +41,44 @@ using namespace chip::Tracing;
 namespace chip {
 namespace Controller {
 
-namespace {
-
-CHIP_ERROR GetPayload(const char * setUpCode, SetupPayload & payload)
-{
-    bool isQRCode = strncmp(setUpCode, kQRCodePrefix, strlen(kQRCodePrefix)) == 0;
-    if (isQRCode)
-    {
-        ReturnErrorOnFailure(QRCodeSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidQRCodePayload(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-    else
-    {
-        ReturnErrorOnFailure(ManualSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidManualCode(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-
-    return CHIP_NO_ERROR;
-}
-} // namespace
-
 CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode, SetupCodePairerBehaviour commission,
                                        DiscoveryType discoveryType, Optional<Dnssd::CommonResolutionData> resolutionData)
 {
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, mSystemLayer != nullptr, CHIP_ERROR_INCORRECT_STATE);
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, remoteId != kUndefinedNodeId, CHIP_ERROR_INVALID_ARGUMENT);
 
-    SetupPayload payload;
-    ReturnErrorOnFailure(GetPayload(setUpCode, payload));
+    std::vector<SetupPayload> payloads;
+    ReturnErrorOnFailure(SetupPayload::FromStringRepresentation(setUpCode, payloads));
 
-    if (resolutionData.HasValue())
+    if (resolutionData.HasValue() && payloads.size() == 1 && mSetupPayloads.size() == 1)
path: src/controller/SetUpCodePairer.cpp
user: login: bzbarsky-apple
body: Because the whole premise of the hack codepath is that we have _a single resolutionData_, which therefore represents only one thing.  In practice, this is only used by chip-tool for things that don't involve concatenated QR codes.

I agree it's not very readable; I will add documentation.
created_at: 2025-05-27T16:13:52Z
author_association: CONTRIBUTOR
diff_hunk: @@ -52,12 +54,13 @@ class SetUpCodePairerParameters : public RendezvousParameters
 {
 public:
     SetUpCodePairerParameters() = default;
-    SetUpCodePairerParameters(const Dnssd::CommonResolutionData & data, size_t index);
+    SetUpCodePairerParameters(const Dnssd::CommonResolutionData & data, std::optional<uint16_t> longDiscriminator, size_t index);
 #if CONFIG_NETWORK_LAYER_BLE
-    SetUpCodePairerParameters(BLE_CONNECTION_OBJECT connObj, bool connected = true);
+    SetUpCodePairerParameters(BLE_CONNECTION_OBJECT connObj, std::optional<uint16_t> longDiscriminator, bool connected = true);
path: src/controller/SetUpCodePairer.h
user: login: bzbarsky-apple
body: I wanted to fail at compile time on purpose, to catch callsites.  In particular, I did not want the longDiscriminator to be an optional argument.
created_at: 2025-05-27T16:14:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -52,12 +54,13 @@ class SetUpCodePairerParameters : public RendezvousParameters
 {
 public:
     SetUpCodePairerParameters() = default;
-    SetUpCodePairerParameters(const Dnssd::CommonResolutionData & data, size_t index);
+    SetUpCodePairerParameters(const Dnssd::CommonResolutionData & data, std::optional<uint16_t> longDiscriminator, size_t index);
 #if CONFIG_NETWORK_LAYER_BLE
-    SetUpCodePairerParameters(BLE_CONNECTION_OBJECT connObj, bool connected = true);
+    SetUpCodePairerParameters(BLE_CONNECTION_OBJECT connObj, std::optional<uint16_t> longDiscriminator, bool connected = true);
 #endif // CONFIG_NETWORK_LAYER_BLE
     char mHostName[Dnssd::kHostNameMaxLength + 1] = {};
     Inet::InterfaceId mInterfaceId;
+    std::optional<uint16_t> mLongDiscriminator = std::nullopt;
path: src/controller/SetUpCodePairer.h
user: login: bzbarsky-apple
body: I can do that, sure.
created_at: 2025-05-27T16:15:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -164,8 +164,10 @@
     'src/lib/dnssd/minimal_mdns/ResponseSender.h': {'list'},
 
     # Not really for embedded consumers; uses std::deque to keep track
-    # of a list of discovered things.
-    'src/controller/SetUpCodePairer.h': {'deque'},
+    # of a list of discovered things and std::vector to keep track of
path: scripts/tools/check_includes_config.py
user: login: bzbarsky-apple
body: OK, can do.
created_at: 2025-05-27T16:15:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -104,55 +88,50 @@ CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode,
     return errorCode;
 }
 
-CHIP_ERROR SetUpCodePairer::Connect(SetupPayload & payload)
+CHIP_ERROR SetUpCodePairer::Connect()
 {
-    CHIP_ERROR err = CHIP_NO_ERROR;
-    bool isRunning = false;
-
-    bool searchOverAll = !payload.rendezvousInformation.HasValue();
-
     if (mDiscoveryType == DiscoveryType::kAll)
     {
-        if (searchOverAll || payload.rendezvousInformation.Value().Has(RendezvousInformationFlag::kBLE))
+        if (ShouldDiscoverUsing(RendezvousInformationFlag::kBLE))
         {
-            if (CHIP_NO_ERROR == (err = StartDiscoveryOverBLE(payload)))
+            CHIP_ERROR err = StartDiscoveryOverBLE();
+            if (err != CHIP_NO_ERROR)
             {
-                isRunning = true;
+                ChipLogError(Controller, "Failed to start discovery over BLE: %" CHIP_ERROR_FORMAT, err.Format());
             }
-            VerifyOrReturnError(searchOverAll || CHIP_NO_ERROR == err || CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE == err, err);
         }
 
-        if (searchOverAll || payload.rendezvousInformation.Value().Has(RendezvousInformationFlag::kSoftAP))
+        if (ShouldDiscoverUsing(RendezvousInformationFlag::kSoftAP))
         {
-            if (CHIP_NO_ERROR == (err = StartDiscoveryOverSoftAP(payload)))
+            CHIP_ERROR err = StartDiscoveryOverSoftAP();
+            if (err != CHIP_NO_ERROR)
             {
-                isRunning = true;
+                ChipLogError(Controller, "Failed to start discovery over SoftAP: %" CHIP_ERROR_FORMAT, err.Format());
             }
-            VerifyOrReturnError(searchOverAll || CHIP_NO_ERROR == err || CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE == err, err);
         }
-        if (searchOverAll || payload.rendezvousInformation.Value().Has(RendezvousInformationFlag::kWiFiPAF))
+        if (ShouldDiscoverUsing(RendezvousInformationFlag::kWiFiPAF))
         {
-            ChipLogProgress(Controller, "WiFi-PAF: has RendezvousInformationFlag::kWiFiPAF");
-            if (CHIP_NO_ERROR == (err = StartDiscoveryOverWiFiPAF(payload)))
+            ChipLogProgress(Controller,
path: src/controller/SetUpCodePairer.cpp
user: login: bzbarsky-apple
body: The PAF people added this logging.  I don't think it's useful personally, so don't want to add it to the other codepaths, but maybe they need it for debugging for some PAF-specific reason?  I don't want to get sidetracked on trying to align this stuff.
created_at: 2025-05-27T16:16:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -165,8 +144,24 @@ CHIP_ERROR SetUpCodePairer::StartDiscoveryOverBLE(SetupPayload & payload)
 
     // Handle possibly-sync callbacks.
     mWaitingForDiscovery[kBLETransport] = true;
-    CHIP_ERROR err = mBleLayer->NewBleConnectionByDiscriminator(payload.discriminator, this, OnDiscoveredDeviceOverBleSuccess,
-                                                                OnDiscoveredDeviceOverBleError);
+    CHIP_ERROR err;
+    if (mSetupPayloads.size() == 1)
+    {
+        err = mBleLayer->NewBleConnectionByDiscriminator(mSetupPayloads[0].discriminator, this, OnDiscoveredDeviceOverBleSuccess,
+                                                         OnDiscoveredDeviceOverBleError);
+    }
+    else
+    {
+        std::vector<SetupDiscriminator> discriminators;
+        discriminators.reserve(mSetupPayloads.size());
+        for (auto & payload : mSetupPayloads)
path: src/controller/SetUpCodePairer.cpp
user: login: bzbarsky-apple
body: > why is that difference important?

It would, if all the BLE backends implemented the new BLE API.  But they don't (and we don't know which ones don't, since some may be out-of-tree), so we have to use the old one when we can (when we have only one thing) and use the new one only when needed.
created_at: 2025-05-27T16:18:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -165,8 +144,24 @@ CHIP_ERROR SetUpCodePairer::StartDiscoveryOverBLE(SetupPayload & payload)
 
     // Handle possibly-sync callbacks.
     mWaitingForDiscovery[kBLETransport] = true;
-    CHIP_ERROR err = mBleLayer->NewBleConnectionByDiscriminator(payload.discriminator, this, OnDiscoveredDeviceOverBleSuccess,
-                                                                OnDiscoveredDeviceOverBleError);
+    CHIP_ERROR err;
+    if (mSetupPayloads.size() == 1)
+    {
+        err = mBleLayer->NewBleConnectionByDiscriminator(mSetupPayloads[0].discriminator, this, OnDiscoveredDeviceOverBleSuccess,
+                                                         OnDiscoveredDeviceOverBleError);
+    }
+    else
+    {
+        std::vector<SetupDiscriminator> discriminators;
+        discriminators.reserve(mSetupPayloads.size());
+        for (auto & payload : mSetupPayloads)
path: src/controller/SetUpCodePairer.cpp
user: login: andy31415
body: Comment for this would be appropriate
created_at: 2025-05-27T16:27:23Z
author_association: CONTRIBUTOR
diff_hunk: @@ -40,61 +41,44 @@ using namespace chip::Tracing;
 namespace chip {
 namespace Controller {
 
-namespace {
-
-CHIP_ERROR GetPayload(const char * setUpCode, SetupPayload & payload)
-{
-    bool isQRCode = strncmp(setUpCode, kQRCodePrefix, strlen(kQRCodePrefix)) == 0;
-    if (isQRCode)
-    {
-        ReturnErrorOnFailure(QRCodeSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidQRCodePayload(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-    else
-    {
-        ReturnErrorOnFailure(ManualSetupPayloadParser(setUpCode).populatePayload(payload));
-        VerifyOrReturnError(payload.isValidManualCode(), CHIP_ERROR_INVALID_ARGUMENT);
-    }
-
-    return CHIP_NO_ERROR;
-}
-} // namespace
-
 CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode, SetupCodePairerBehaviour commission,
                                        DiscoveryType discoveryType, Optional<Dnssd::CommonResolutionData> resolutionData)
 {
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, mSystemLayer != nullptr, CHIP_ERROR_INCORRECT_STATE);
     VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, remoteId != kUndefinedNodeId, CHIP_ERROR_INVALID_ARGUMENT);
 
-    SetupPayload payload;
-    ReturnErrorOnFailure(GetPayload(setUpCode, payload));
+    std::vector<SetupPayload> payloads;
+    ReturnErrorOnFailure(SetupPayload::FromStringRepresentation(setUpCode, payloads));
 
-    if (resolutionData.HasValue())
+    if (resolutionData.HasValue() && payloads.size() == 1 && mSetupPayloads.size() == 1)
     {
         VerifyOrReturnErrorWithMetric(kMetricSetupCodePairerPairDevice, discoveryType != DiscoveryType::kAll,
                                       CHIP_ERROR_INVALID_ARGUMENT);
-        if (mRemoteId == remoteId && mSetUpPINCode == payload.setUpPINCode && mConnectionType == commission &&
+        if (mRemoteId == remoteId && mSetupPayloads[0].setUpPINCode == payloads[0].setUpPINCode && mConnectionType == commission &&
             mDiscoveryType == discoveryType)
         {
-            NotifyCommissionableDeviceDiscovered(resolutionData.Value());
+            // Not passing a discriminator is ok, since we have only one payload.
+            NotifyCommissionableDeviceDiscovered(resolutionData.Value(), std::nullopt);
path: src/controller/SetUpCodePairer.cpp
user: login: bzbarsky-apple
body: Done.
created_at: 2025-05-27T16:41:36Z
author_association: CONTRIBUTOR
diff_hunk: @@ -165,8 +144,24 @@ CHIP_ERROR SetUpCodePairer::StartDiscoveryOverBLE(SetupPayload & payload)
 
     // Handle possibly-sync callbacks.
     mWaitingForDiscovery[kBLETransport] = true;
-    CHIP_ERROR err = mBleLayer->NewBleConnectionByDiscriminator(payload.discriminator, this, OnDiscoveredDeviceOverBleSuccess,
-                                                                OnDiscoveredDeviceOverBleError);
+    CHIP_ERROR err;
+    if (mSetupPayloads.size() == 1)
+    {
+        err = mBleLayer->NewBleConnectionByDiscriminator(mSetupPayloads[0].discriminator, this, OnDiscoveredDeviceOverBleSuccess,
+                                                         OnDiscoveredDeviceOverBleError);
+    }
+    else
+    {
+        std::vector<SetupDiscriminator> discriminators;
+        discriminators.reserve(mSetupPayloads.size());
+        for (auto & payload : mSetupPayloads)
path: src/controller/SetUpCodePairer.cpp
user: login: bzbarsky-apple
body: Done.
created_at: 2025-05-27T17:09:29Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-05-13T21:35:32Z
body: PR #38924: Size comparison from fdacd16c5b6d84aac37ed15cd411312430bb095c to 8e7b312267437c04c4a7bcf1783a6ad8e0ac32d1
<!--ghr-comment-format:1-->

<details>
<summary>Full report (1 build for stm32)</summary>
<!--ghr-report:full-->

| platform   | target   | config        | section   |   fdacd16c |   8e7b3122 |   change |   % change |
|:-----------|:---------|:--------------|:----------|-----------:|-----------:|---------:|-----------:|
| stm32      | light    | STM32WB5MM-DK | FLASH     |     464532 |     464532 |        0 |        0.0 |
|            |          |               | RAM       |     141416 |     141416 |        0 |        0.0 |

</details>

author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-13T22:28:17Z
body: PR #38924: Size comparison from fdacd16c5b6d84aac37ed15cd411312430bb095c to 78570ceca1f1961dea3198f20e4b8ef15e2e377e
<!--ghr-comment-format:1-->

<details>
<summary>Full report (73 builds for bl602, bl702, bl702l, cc13x4_26x4, cc32xx, cyw30739, efr32, esp32, linux, nrfconnect, nxp, psoc6, qpg, stm32, telink, tizen)</summary>
<!--ghr-report:full-->

| platform    | target                                                | config                   | section   |   fdacd16c |   78570cec |   change |   % change |
|:------------|:------------------------------------------------------|:-------------------------|:----------|-----------:|-----------:|---------:|-----------:|
| bl602       | lighting-app                                          | bl602+mfd+littlefs+rpc   | FLASH     |    1101678 |    1101678 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     178994 |     178994 |        0 |        0.0 |
| bl702       | lighting-app                                          | bl702+eth                | FLASH     |     656472 |     656472 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     134941 |     134941 |        0 |        0.0 |
|             |                                                       | bl702+wifi               | FLASH     |     833750 |     833750 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     124481 |     124481 |        0 |        0.0 |
|             |                                                       | bl706+mfd+rpc+littlefs   | FLASH     |    1066582 |    1066582 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     117349 |     117349 |        0 |        0.0 |
| bl702l      | contact-sensor-app                                    | bl702l+mfd+littlefs      | FLASH     |     896152 |     896152 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     105688 |     105688 |        0 |        0.0 |
|             | lighting-app                                          | bl702l+mfd+littlefs      | FLASH     |     979926 |     979926 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     109836 |     109836 |        0 |        0.0 |
| cc13x4_26x4 | lighting-app                                          | LP_EM_CC1354P10_6        | FLASH     |     820180 |     820180 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     120208 |     120208 |        0 |        0.0 |
|             | lock-ftd                                              | LP_EM_CC1354P10_6        | FLASH     |     830232 |     830232 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     125376 |     125376 |        0 |        0.0 |
|             | pump-app                                              | LP_EM_CC1354P10_6        | FLASH     |     778456 |     778456 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     113780 |     113780 |        0 |        0.0 |
|             | pump-controller-app                                   | LP_EM_CC1354P10_6        | FLASH     |     762764 |     762764 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     113988 |     113988 |        0 |        0.0 |
| cc32xx      | air-purifier                                          | CC3235SF_LAUNCHXL        | FLASH     |     549034 |     549034 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     205192 |     205192 |        0 |        0.0 |
|             | lock                                                  | CC3235SF_LAUNCHXL        | FLASH     |     579722 |     579722 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     205376 |     205376 |        0 |        0.0 |
| cyw30739    | light                                                 | CYW30739B2-P5-EVK-01     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     661693 |     661693 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      77236 |      77236 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-02     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     681545 |     681545 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      79876 |      79876 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-03     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     681545 |     681545 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      79876 |      79876 |        0 |        0.0 |
|             |                                                       | CYW930739M2EVB-02        | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     638485 |     638485 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      72304 |      72304 |        0 |        0.0 |
|             | light-switch                                          | CYW30739B2-P5-EVK-01     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     622981 |     622981 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      73532 |      73532 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-02     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     642625 |     642625 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      76084 |      76084 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-03     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     642625 |     642625 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      76084 |      76084 |        0 |        0.0 |
|             | lock                                                  | CYW30739B2-P5-EVK-01     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     642389 |     642389 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      76532 |      76532 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-02     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     662105 |     662105 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      79084 |      79084 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-03     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     662105 |     662105 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      79084 |      79084 |        0 |        0.0 |
|             | thermostat                                            | CYW30739B2-P5-EVK-01     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     618617 |     618617 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      70628 |      70628 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-02     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     638469 |     638469 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      73260 |      73260 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-03     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     638469 |     638469 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      73260 |      73260 |        0 |        0.0 |
| efr32       | lock-app                                              | BRD4187C                 | FLASH     |     945116 |     945116 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     132024 |     132024 |        0 |        0.0 |
|             |                                                       | BRD4338a                 | FLASH     |     771184 |     771176 |       -8 |       -0.0 |
|             |                                                       |                          | RAM       |     173248 |     173248 |        0 |        0.0 |
|             | window-app                                            | BRD4187C                 | FLASH     |    1037144 |    1037144 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     128160 |     128160 |        0 |        0.0 |
| esp32       | all-clusters-app                                      | c3devkit                 | DRAM      |     103320 |     103320 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    1805474 |    1805474 |        0 |        0.0 |
|             |                                                       |                          | IRAM      |      83846 |      83846 |        0 |        0.0 |
|             |                                                       | m5stack                  | DRAM      |     121932 |     121932 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    1770626 |    1770630 |        4 |        0.0 |
|             |                                                       |                          | IRAM      |     117043 |     117043 |        0 |        0.0 |
| linux       | air-purifier-app                                      | debug                    | *unknown* |       4848 |       4848 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    2786968 |    2787072 |      104 |        0.0 |
|             |                                                       |                          | RAM       |     115032 |     115048 |       16 |        0.0 |
|             | all-clusters-app                                      | debug                    | *unknown* |       5656 |       5656 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    6340660 |    6340764 |      104 |        0.0 |
|             |                                                       |                          | RAM       |     533112 |     533128 |       16 |        0.0 |
|             | all-clusters-minimal-app                              | debug                    | *unknown* |       5528 |       5528 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    5444952 |    5445056 |      104 |        0.0 |
|             |                                                       |                          | RAM       |     225000 |     225016 |       16 |        0.0 |
|             | bridge-app                                            | debug                    | *unknown* |       5560 |       5560 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    4761388 |    4761492 |      104 |        0.0 |
|             |                                                       |                          | RAM       |     204640 |     204656 |       16 |        0.0 |
|             | camera-app                                            | debug                    | *unknown* |       8856 |       8856 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    6883451 |    6883547 |       96 |        0.0 |
|             |                                                       |                          | RAM       |     226168 |     226168 |        0 |        0.0 |
|             | camera-controller                                     | debug                    | *unknown* |       9240 |       9240 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |   14309675 |   14322011 |    12336 |        0.1 |
|             |                                                       |                          | RAM       |     658416 |     658448 |       32 |        0.0 |
|             | chip-tool                                             | debug                    | *unknown* |       6256 |       6256 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |   14591355 |   14604065 |    12710 |        0.1 |
|             |                                                       |                          | RAM       |     645168 |     645184 |       16 |        0.0 |
|             | chip-tool-ipv6only                                    | arm64                    | *unknown* |      40328 |      40336 |        8 |        0.0 |
|             |                                                       |                          | FLASH     |   12572560 |   12585152 |    12592 |        0.1 |
|             |                                                       |                          | RAM       |     691456 |     691448 |       -8 |       -0.0 |
|             | fabric-admin                                          | debug                    | *unknown* |       5936 |       5936 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |   12668741 |   12681291 |    12550 |        0.1 |
|             |                                                       |                          | RAM       |     644528 |     644544 |       16 |        0.0 |
|             | fabric-bridge-app                                     | debug                    | *unknown* |       4808 |       4808 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    4578426 |    4578426 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     190704 |     190704 |        0 |        0.0 |
|             | fabric-sync                                           | debug                    | *unknown* |       5064 |       5064 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    5718709 |    5726261 |     7552 |        0.1 |
|             |                                                       |                          | RAM       |     486560 |     486528 |      -32 |       -0.0 |
|             | lighting-app                                          | debug+rpc+ui             | *unknown* |       6264 |       6264 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    5641777 |    5641873 |       96 |        0.0 |
|             |                                                       |                          | RAM       |     207176 |     207192 |       16 |        0.0 |
|             | lock-app                                              | debug                    | *unknown* |       5496 |       5496 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    4813722 |    4813826 |      104 |        0.0 |
|             |                                                       |                          | RAM       |     194440 |     194456 |       16 |        0.0 |
|             | ota-provider-app                                      | debug                    | *unknown* |       4848 |       4848 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    4439400 |    4439400 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     183888 |     183888 |        0 |        0.0 |
|             | ota-requestor-app                                     | debug                    | *unknown* |       4800 |       4800 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    4567164 |    4567164 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     187760 |     187760 |        0 |        0.0 |
|             | shell                                                 | debug                    | *unknown* |       4272 |       4272 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    3078364 |    3078460 |       96 |        0.0 |
|             |                                                       |                          | RAM       |     148072 |     148088 |       16 |        0.0 |
|             | thermostat-no-ble                                     | arm64                    | *unknown* |       9616 |       9616 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    4224912 |    4224912 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     230864 |     230864 |        0 |        0.0 |
|             | tv-app                                                | debug                    | *unknown* |       5832 |       5832 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    6074533 |    6079669 |     5136 |        0.1 |
|             |                                                       |                          | RAM       |     610984 |     611000 |       16 |        0.0 |
|             | tv-casting-app                                        | debug                    | *unknown* |       5416 |       5416 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |   12780909 |   12781021 |      112 |        0.0 |
|             |                                                       |                          | RAM       |     765456 |     765472 |       16 |        0.0 |
| nrfconnect  | all-clusters-app                                      | nrf52840dk_nrf52840      | FLASH     |     919232 |     919232 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     167326 |     167326 |        0 |        0.0 |
|             |                                                       | nrf7002dk_nrf5340_cpuapp | FLASH     |     911208 |     911208 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     145570 |     145570 |        0 |        0.0 |
|             | all-clusters-minimal-app                              | nrf52840dk_nrf52840      | FLASH     |     856456 |     856456 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     141089 |     141089 |        0 |        0.0 |
| nxp         | contact                                               | k32w0+release            | FLASH     |     591920 |     591920 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      72848 |      72848 |        0 |        0.0 |
|             |                                                       | mcxw71+release           | FLASH     |     624680 |     624680 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      63188 |      63188 |        0 |        0.0 |
|             | light                                                 | k32w0+release            | FLASH     |     617836 |     617836 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      72144 |      72144 |        0 |        0.0 |
|             |                                                       | k32w1+release            | FLASH     |     709152 |     709152 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      72036 |      72036 |        0 |        0.0 |
|             | lock                                                  | mcxw71+release           | FLASH     |     774208 |     774208 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      67612 |      67612 |        0 |        0.0 |
| psoc6       | all-clusters                                          | cy8ckit_062s2_43012      | FLASH     |    1665268 |    1665268 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     212328 |     212328 |        0 |        0.0 |
|             | all-clusters-minimal                                  | cy8ckit_062s2_43012      | FLASH     |    1569764 |    1569764 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     208504 |     208504 |        0 |        0.0 |
|             | light                                                 | cy8ckit_062s2_43012      | FLASH     |    1445228 |    1445228 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     197216 |     197216 |        0 |        0.0 |
|             | lock                                                  | cy8ckit_062s2_43012      | FLASH     |    1475236 |    1475236 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     224936 |     224936 |        0 |        0.0 |
| qpg         | lighting-app                                          | qpg6105+debug            | FLASH     |     666788 |     666788 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     105164 |     105164 |        0 |        0.0 |
|             | lock-app                                              | qpg6105+debug            | FLASH     |     625192 |     625192 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      99792 |      99792 |        0 |        0.0 |
| stm32       | light                                                 | STM32WB5MM-DK            | FLASH     |     464532 |     464532 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     141416 |     141416 |        0 |        0.0 |
| telink      | bridge-app                                            | tl7218x                  | FLASH     |     693534 |     693534 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     101828 |     101828 |        0 |        0.0 |
|             | light-app-ota-compress-lzma-factory-data              | tl3218x                  | FLASH     |     772920 |     772920 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      49980 |      49980 |        0 |        0.0 |
|             | light-app-ota-shell-factory-data                      | tl7218x                  | FLASH     |     780026 |     780026 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     109160 |     109160 |        0 |        0.0 |
|             | light-switch-app-ota-compress-lzma-factory-data       | tl7218x_retention        | FLASH     |     702294 |     702294 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      62544 |      62544 |        0 |        0.0 |
|             | light-switch-app-ota-compress-lzma-shell-factory-data | tlsr9528a                | FLASH     |     740248 |     740248 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      85724 |      85724 |        0 |        0.0 |
|             | lighting-app-ota-factory-data                         | tlsr9118bdk40d           | FLASH     |     606348 |     606348 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     119376 |     119376 |        0 |        0.0 |
|             | lighting-app-ota-rpc-factory-data-4mb                 | tlsr9518adk80d           | FLASH     |     815336 |     815340 |        4 |        0.0 |
|             |                                                       |                          | RAM       |     107428 |     107428 |        0 |        0.0 |
| tizen       | all-clusters-app                                      | arm                      | *unknown* |       5216 |       5216 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    1812152 |    1812188 |       36 |        0.0 |
|             |                                                       |                          | RAM       |      94832 |      94840 |        8 |        0.0 |
|             | chip-tool-ubsan                                       | arm                      | *unknown* |      20600 |      20604 |        4 |        0.0 |
|             |                                                       |                          | FLASH     |   20822742 |   20849934 |    27192 |        0.1 |
|             |                                                       |                          | RAM       |    9059864 |    9073932 |    14068 |        0.2 |

</details>

author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-14T17:53:55Z
body: PR #38924: Size comparison from 6915d2efe30b85f61a4eb6c79565890d0f8e6c38 to 493627c537bbce9970ad3b9c8ca1d19290c4e6e7
<!--ghr-comment-format:1-->

<details>
<summary>Full report (73 builds for bl602, bl702, bl702l, cc13x4_26x4, cc32xx, cyw30739, efr32, esp32, linux, nrfconnect, nxp, psoc6, qpg, stm32, telink, tizen)</summary>
<!--ghr-report:full-->

| platform    | target                                                | config                   | section   |   6915d2ef |   493627c5 |   change |   % change |
|:------------|:------------------------------------------------------|:-------------------------|:----------|-----------:|-----------:|---------:|-----------:|
| bl602       | lighting-app                                          | bl602+mfd+littlefs+rpc   | FLASH     |    1101678 |    1101678 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     178994 |     178994 |        0 |        0.0 |
| bl702       | lighting-app                                          | bl702+eth                | FLASH     |     654940 |     654940 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     134961 |     134961 |        0 |        0.0 |
|             |                                                       | bl702+wifi               | FLASH     |     832446 |     832446 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     124501 |     124501 |        0 |        0.0 |
|             |                                                       | bl706+mfd+rpc+littlefs   | FLASH     |    1064978 |    1064978 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     117365 |     117365 |        0 |        0.0 |
| bl702l      | contact-sensor-app                                    | bl702l+mfd+littlefs      | FLASH     |     894160 |     894160 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     105660 |     105660 |        0 |        0.0 |
|             | lighting-app                                          | bl702l+mfd+littlefs      | FLASH     |     978258 |     978258 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     109836 |     109836 |        0 |        0.0 |
| cc13x4_26x4 | lighting-app                                          | LP_EM_CC1354P10_6        | FLASH     |     820196 |     820196 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     120208 |     120208 |        0 |        0.0 |
|             | lock-ftd                                              | LP_EM_CC1354P10_6        | FLASH     |     830232 |     830232 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     125376 |     125376 |        0 |        0.0 |
|             | pump-app                                              | LP_EM_CC1354P10_6        | FLASH     |     778472 |     778472 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     113780 |     113780 |        0 |        0.0 |
|             | pump-controller-app                                   | LP_EM_CC1354P10_6        | FLASH     |     762780 |     762780 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     113988 |     113988 |        0 |        0.0 |
| cc32xx      | air-purifier                                          | CC3235SF_LAUNCHXL        | FLASH     |     549050 |     549050 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     205192 |     205192 |        0 |        0.0 |
|             | lock                                                  | CC3235SF_LAUNCHXL        | FLASH     |     579738 |     579738 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     205376 |     205376 |        0 |        0.0 |
| cyw30739    | light                                                 | CYW30739B2-P5-EVK-01     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     661709 |     661709 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      77236 |      77236 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-02     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     681561 |     681561 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      79876 |      79876 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-03     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     681561 |     681561 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      79876 |      79876 |        0 |        0.0 |
|             |                                                       | CYW930739M2EVB-02        | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     638501 |     638501 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      72304 |      72304 |        0 |        0.0 |
|             | light-switch                                          | CYW30739B2-P5-EVK-01     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     622997 |     622997 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      73532 |      73532 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-02     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     642641 |     642641 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      76084 |      76084 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-03     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     642641 |     642641 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      76084 |      76084 |        0 |        0.0 |
|             | lock                                                  | CYW30739B2-P5-EVK-01     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     642405 |     642405 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      76532 |      76532 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-02     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     662121 |     662121 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      79084 |      79084 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-03     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     662121 |     662121 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      79084 |      79084 |        0 |        0.0 |
|             | thermostat                                            | CYW30739B2-P5-EVK-01     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     618633 |     618633 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      70628 |      70628 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-02     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     638485 |     638485 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      73260 |      73260 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-03     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     638485 |     638485 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      73260 |      73260 |        0 |        0.0 |
| efr32       | lock-app                                              | BRD4187C                 | FLASH     |     945148 |     945148 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     132024 |     132024 |        0 |        0.0 |
|             |                                                       | BRD4338a                 | FLASH     |     771184 |     771176 |       -8 |       -0.0 |
|             |                                                       |                          | RAM       |     173248 |     173248 |        0 |        0.0 |
|             | window-app                                            | BRD4187C                 | FLASH     |    1037144 |    1037144 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     128160 |     128160 |        0 |        0.0 |
| esp32       | all-clusters-app                                      | c3devkit                 | DRAM      |     103320 |     103320 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    1805488 |    1805488 |        0 |        0.0 |
|             |                                                       |                          | IRAM      |      83846 |      83846 |        0 |        0.0 |
|             |                                                       | m5stack                  | DRAM      |     121932 |     121932 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    1770642 |    1770642 |        0 |        0.0 |
|             |                                                       |                          | IRAM      |     117043 |     117043 |        0 |        0.0 |
| linux       | air-purifier-app                                      | debug                    | *unknown* |       4848 |       4848 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    2787094 |    2787094 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     115048 |     115048 |        0 |        0.0 |
|             | all-clusters-app                                      | debug                    | *unknown* |       5656 |       5656 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    6340786 |    6340786 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     533128 |     533128 |        0 |        0.0 |
|             | all-clusters-minimal-app                              | debug                    | *unknown* |       5528 |       5528 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    5445078 |    5445078 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     225016 |     225016 |        0 |        0.0 |
|             | bridge-app                                            | debug                    | *unknown* |       5560 |       5560 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    4761514 |    4761514 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     204656 |     204656 |        0 |        0.0 |
|             | camera-app                                            | debug                    | *unknown* |       8856 |       8856 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    6883579 |    6883579 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     226168 |     226168 |        0 |        0.0 |
|             | camera-controller                                     | debug                    | *unknown* |       9240 |       9240 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |   14309803 |   14322011 |    12208 |        0.1 |
|             |                                                       |                          | RAM       |     658448 |     658448 |        0 |        0.0 |
|             | chip-tool                                             | debug                    | *unknown* |       6256 |       6256 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |   14591481 |   14604077 |    12596 |        0.1 |
|             |                                                       |                          | RAM       |     645184 |     645184 |        0 |        0.0 |
|             | chip-tool-ipv6only                                    | arm64                    | *unknown* |      40328 |      40336 |        8 |        0.0 |
|             |                                                       |                          | FLASH     |   12572672 |   12585152 |    12480 |        0.1 |
|             |                                                       |                          | RAM       |     691472 |     691448 |      -24 |       -0.0 |
|             | fabric-admin                                          | debug                    | *unknown* |       5936 |       5936 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |   12668867 |   12681303 |    12436 |        0.1 |
|             |                                                       |                          | RAM       |     644544 |     644544 |        0 |        0.0 |
|             | fabric-bridge-app                                     | debug                    | *unknown* |       4808 |       4808 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    4578448 |    4578448 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     190704 |     190704 |        0 |        0.0 |
|             | fabric-sync                                           | debug                    | *unknown* |       5064 |       5064 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    5718725 |    5726277 |     7552 |        0.1 |
|             |                                                       |                          | RAM       |     486560 |     486528 |      -32 |       -0.0 |
|             | lighting-app                                          | debug+rpc+ui             | *unknown* |       6264 |       6264 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    5641905 |    5641905 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     207192 |     207192 |        0 |        0.0 |
|             | lock-app                                              | debug                    | *unknown* |       5496 |       5496 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    4813848 |    4813848 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     194456 |     194456 |        0 |        0.0 |
|             | ota-provider-app                                      | debug                    | *unknown* |       4848 |       4848 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    4439422 |    4439422 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     183888 |     183888 |        0 |        0.0 |
|             | ota-requestor-app                                     | debug                    | *unknown* |       4800 |       4800 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    4567186 |    4567186 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     187760 |     187760 |        0 |        0.0 |
|             | shell                                                 | debug                    | *unknown* |       4272 |       4272 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    3078492 |    3078492 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     148088 |     148088 |        0 |        0.0 |
|             | thermostat-no-ble                                     | arm64                    | *unknown* |       9616 |       9616 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    4224912 |    4224912 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     230864 |     230864 |        0 |        0.0 |
|             | tv-app                                                | debug                    | *unknown* |       5832 |       5832 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    6074661 |    6079685 |     5024 |        0.1 |
|             |                                                       |                          | RAM       |     611000 |     611000 |        0 |        0.0 |
|             | tv-casting-app                                        | debug                    | *unknown* |       5416 |       5416 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |   12781037 |   12781037 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     765472 |     765472 |        0 |        0.0 |
| nrfconnect  | all-clusters-app                                      | nrf52840dk_nrf52840      | FLASH     |     919244 |     919244 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     167326 |     167326 |        0 |        0.0 |
|             |                                                       | nrf7002dk_nrf5340_cpuapp | FLASH     |     911220 |     911220 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     145570 |     145570 |        0 |        0.0 |
|             | all-clusters-minimal-app                              | nrf52840dk_nrf52840      | FLASH     |     856468 |     856468 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     141089 |     141089 |        0 |        0.0 |
| nxp         | contact                                               | k32w0+release            | FLASH     |     591920 |     591920 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      72848 |      72848 |        0 |        0.0 |
|             |                                                       | mcxw71+release           | FLASH     |     624688 |     624688 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      63188 |      63188 |        0 |        0.0 |
|             | light                                                 | k32w0+release            | FLASH     |     617852 |     617852 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      72144 |      72144 |        0 |        0.0 |
|             |                                                       | k32w1+release            | FLASH     |     709160 |     709160 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      72036 |      72036 |        0 |        0.0 |
|             | lock                                                  | mcxw71+release           | FLASH     |     774216 |     774216 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      67612 |      67612 |        0 |        0.0 |
| psoc6       | all-clusters                                          | cy8ckit_062s2_43012      | FLASH     |    1665268 |    1665268 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     212328 |     212328 |        0 |        0.0 |
|             | all-clusters-minimal                                  | cy8ckit_062s2_43012      | FLASH     |    1569764 |    1569764 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     208504 |     208504 |        0 |        0.0 |
|             | light                                                 | cy8ckit_062s2_43012      | FLASH     |    1445228 |    1445228 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     197216 |     197216 |        0 |        0.0 |
|             | lock                                                  | cy8ckit_062s2_43012      | FLASH     |    1475236 |    1475236 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     224936 |     224936 |        0 |        0.0 |
| qpg         | lighting-app                                          | qpg6105+debug            | FLASH     |     666804 |     666804 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     105164 |     105164 |        0 |        0.0 |
|             | lock-app                                              | qpg6105+debug            | FLASH     |     625208 |     625208 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      99792 |      99792 |        0 |        0.0 |
| stm32       | light                                                 | STM32WB5MM-DK            | FLASH     |     464540 |     464540 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     141416 |     141416 |        0 |        0.0 |
| telink      | bridge-app                                            | tl7218x                  | FLASH     |     693548 |     693548 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     101828 |     101828 |        0 |        0.0 |
|             | light-app-ota-compress-lzma-factory-data              | tl3218x                  | FLASH     |     772934 |     772934 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      49980 |      49980 |        0 |        0.0 |
|             | light-app-ota-shell-factory-data                      | tl7218x                  | FLASH     |     780040 |     780040 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     109160 |     109160 |        0 |        0.0 |
|             | light-switch-app-ota-compress-lzma-factory-data       | tl7218x_retention        | FLASH     |     702308 |     702308 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      62544 |      62544 |        0 |        0.0 |
|             | light-switch-app-ota-compress-lzma-shell-factory-data | tlsr9528a                | FLASH     |     740262 |     740262 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      85724 |      85724 |        0 |        0.0 |
|             | lighting-app-ota-factory-data                         | tlsr9118bdk40d           | FLASH     |     606362 |     606362 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     119376 |     119376 |        0 |        0.0 |
|             | lighting-app-ota-rpc-factory-data-4mb                 | tlsr9518adk80d           | FLASH     |     815350 |     815354 |        4 |        0.0 |
|             |                                                       |                          | RAM       |     107428 |     107428 |        0 |        0.0 |
| tizen       | all-clusters-app                                      | arm                      | *unknown* |       5216 |       5216 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    1812316 |    1812316 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      94840 |      94840 |        0 |        0.0 |
|             | chip-tool-ubsan                                       | arm                      | *unknown* |      20600 |      20604 |        4 |        0.0 |
|             |                                                       |                          | FLASH     |   20823118 |   20850342 |    27224 |        0.1 |
|             |                                                       |                          | RAM       |    9060032 |    9074124 |    14092 |        0.2 |

</details>

author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-27T17:22:00Z
body: PR #38924: Size comparison from 88b801fc197f7abe944ebdd92238e74a2740184f to 1577a67358a65de9571759c823d73a245253668b
<!--ghr-comment-format:1-->

<details>
<summary>Full report (75 builds for bl602, bl702, bl702l, cc13x4_26x4, cc32xx, cyw30739, efr32, esp32, linux, nrfconnect, nxp, psoc6, qpg, stm32, telink, tizen)</summary>
<!--ghr-report:full-->

| platform    | target                                                | config                   | section   |   88b801fc |   1577a673 |   change |   % change |
|:------------|:------------------------------------------------------|:-------------------------|:----------|-----------:|-----------:|---------:|-----------:|
| bl602       | lighting-app                                          | bl602+mfd+littlefs+rpc   | FLASH     |    1102242 |    1102242 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     179114 |     179114 |        0 |        0.0 |
| bl702       | lighting-app                                          | bl702+eth                | FLASH     |     655348 |     655348 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     135073 |     135073 |        0 |        0.0 |
|             |                                                       | bl702+wifi               | FLASH     |     832858 |     832858 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     124637 |     124637 |        0 |        0.0 |
|             |                                                       | bl706+mfd+rpc+littlefs   | FLASH     |    1065398 |    1065398 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     117461 |     117461 |        0 |        0.0 |
| bl702l      | contact-sensor-app                                    | bl702l+mfd+littlefs      | FLASH     |     894952 |     894952 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     105772 |     105772 |        0 |        0.0 |
|             | lighting-app                                          | bl702l+mfd+littlefs      | FLASH     |     978678 |     978678 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     109956 |     109956 |        0 |        0.0 |
| cc13x4_26x4 | lighting-app                                          | LP_EM_CC1354P10_6        | FLASH     |     820588 |     820588 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     120288 |     120288 |        0 |        0.0 |
|             | lock-ftd                                              | LP_EM_CC1354P10_6        | FLASH     |     832176 |     832176 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     125440 |     125440 |        0 |        0.0 |
|             | pump-app                                              | LP_EM_CC1354P10_6        | FLASH     |     777680 |     777680 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     113844 |     113844 |        0 |        0.0 |
|             | pump-controller-app                                   | LP_EM_CC1354P10_6        | FLASH     |     761996 |     761996 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     114052 |     114052 |        0 |        0.0 |
| cc32xx      | air-purifier                                          | CC3235SF_LAUNCHXL        | FLASH     |     548254 |     548254 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     205256 |     205256 |        0 |        0.0 |
|             | lock                                                  | CC3235SF_LAUNCHXL        | FLASH     |     581694 |     581694 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     205448 |     205448 |        0 |        0.0 |
| cyw30739    | light                                                 | CYW30739B2-P5-EVK-01     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     662253 |     662253 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      77472 |      77472 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-02     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     682105 |     682105 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      80112 |      80112 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-03     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     682105 |     682105 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      80112 |      80112 |        0 |        0.0 |
|             |                                                       | CYW930739M2EVB-02        | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     639045 |     639045 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      72540 |      72540 |        0 |        0.0 |
|             | light-switch                                          | CYW30739B2-P5-EVK-01     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     623645 |     623645 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      73784 |      73784 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-02     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     643281 |     643281 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      76336 |      76336 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-03     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     643281 |     643281 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      76336 |      76336 |        0 |        0.0 |
|             | lock                                                  | CYW30739B2-P5-EVK-01     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     644573 |     644573 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      76784 |      76784 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-02     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     664281 |     664281 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      79336 |      79336 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-03     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     664281 |     664281 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      79336 |      79336 |        0 |        0.0 |
|             | thermostat                                            | CYW30739B2-P5-EVK-01     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     619241 |     619241 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      70896 |      70896 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-02     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     639093 |     639093 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      73528 |      73528 |        0 |        0.0 |
|             |                                                       | CYW30739B2-P5-EVK-03     | *unknown* |       2040 |       2040 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |     639093 |     639093 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      73528 |      73528 |        0 |        0.0 |
| efr32       | lock-app                                              | BRD4187C                 | FLASH     |     946772 |     946772 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     132092 |     132092 |        0 |        0.0 |
|             |                                                       | BRD4338a                 | FLASH     |     775728 |     775728 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     173320 |     173320 |        0 |        0.0 |
|             | window-app                                            | BRD4187C                 | FLASH     |    1039456 |    1039448 |       -8 |       -0.0 |
|             |                                                       |                          | RAM       |     128228 |     128228 |        0 |        0.0 |
| esp32       | all-clusters-app                                      | c3devkit                 | DRAM      |     103624 |     103624 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    1810020 |    1810020 |        0 |        0.0 |
|             |                                                       |                          | IRAM      |      83846 |      83846 |        0 |        0.0 |
|             |                                                       | m5stack                  | DRAM      |     122412 |     122412 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    1775926 |    1775926 |        0 |        0.0 |
|             |                                                       |                          | IRAM      |     117043 |     117043 |        0 |        0.0 |
| linux       | air-purifier-app                                      | debug                    | *unknown* |       4760 |       4760 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    2715576 |    2715576 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     115024 |     115024 |        0 |        0.0 |
|             | all-clusters-app                                      | debug                    | *unknown* |       5600 |       5600 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    6314966 |    6314966 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     535736 |     535736 |        0 |        0.0 |
|             | all-clusters-minimal-app                              | debug                    | *unknown* |       5464 |       5464 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    5397032 |    5397032 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     225968 |     225968 |        0 |        0.0 |
|             | bridge-app                                            | debug                    | *unknown* |       5496 |       5496 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    4732894 |    4732894 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     205624 |     205624 |        0 |        0.0 |
|             | camera-app                                            | debug                    | *unknown* |       8824 |       8824 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    6840891 |    6840891 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     226864 |     226864 |        0 |        0.0 |
|             | camera-controller                                     | debug                    | *unknown* |       9112 |       9112 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |   14229435 |   14241419 |    11984 |        0.1 |
|             |                                                       |                          | RAM       |     656584 |     656584 |        0 |        0.0 |
|             | chip-tool                                             | debug                    | *unknown* |       6112 |       6112 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |   14592613 |   14604995 |    12382 |        0.1 |
|             |                                                       |                          | RAM       |     653920 |     653920 |        0 |        0.0 |
|             | chip-tool-ipv6only                                    | arm64                    | *unknown* |      40856 |      40864 |        8 |        0.0 |
|             |                                                       |                          | FLASH     |   12569672 |   12581944 |    12272 |        0.1 |
|             |                                                       |                          | RAM       |     700944 |     700920 |      -24 |       -0.0 |
|             | fabric-admin                                          | debug                    | *unknown* |       5800 |       5800 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |   12674067 |   12686321 |    12254 |        0.1 |
|             |                                                       |                          | RAM       |     653704 |     653704 |        0 |        0.0 |
|             | fabric-bridge-app                                     | debug                    | *unknown* |       4736 |       4736 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    4517874 |    4517874 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     191304 |     191304 |        0 |        0.0 |
|             | fabric-sync                                           | debug                    | *unknown* |       4984 |       4984 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    5639669 |    5646997 |     7328 |        0.1 |
|             |                                                       |                          | RAM       |     487400 |     487368 |      -32 |       -0.0 |
|             | lighting-app                                          | debug+rpc+ui             | *unknown* |       6208 |       6208 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    5579809 |    5579809 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     207760 |     207760 |        0 |        0.0 |
|             | lock-app                                              | debug                    | *unknown* |       5432 |       5432 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    4765736 |    4765736 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     195072 |     195072 |        0 |        0.0 |
|             | ota-provider-app                                      | debug                    | *unknown* |       4776 |       4776 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    4369956 |    4369956 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     183928 |     183928 |        0 |        0.0 |
|             | ota-requestor-app                                     | debug                    | *unknown* |       4728 |       4728 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    4497390 |    4497390 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     187864 |     187864 |        0 |        0.0 |
|             | shell                                                 | debug                    | *unknown* |       4240 |       4240 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    3033292 |    3033292 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     149728 |     149728 |        0 |        0.0 |
|             | thermostat-no-ble                                     | arm64                    | *unknown* |       9648 |       9648 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    4177840 |    4177840 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     231184 |     231184 |        0 |        0.0 |
|             | tv-app                                                | debug                    | *unknown* |       5760 |       5760 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    6006741 |    6011669 |     4928 |        0.1 |
|             |                                                       |                          | RAM       |     611600 |     611600 |        0 |        0.0 |
|             | tv-casting-app                                        | debug                    | *unknown* |       5320 |       5320 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |   12728717 |   12728717 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     764992 |     764992 |        0 |        0.0 |
| nrfconnect  | all-clusters-app                                      | nrf52840dk_nrf52840      | FLASH     |     921748 |     921748 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     167532 |     167532 |        0 |        0.0 |
|             |                                                       | nrf7002dk_nrf5340_cpuapp | FLASH     |     912996 |     912996 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     145776 |     145776 |        0 |        0.0 |
|             | all-clusters-minimal-app                              | nrf52840dk_nrf52840      | FLASH     |     858948 |     858948 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     141159 |     141159 |        0 |        0.0 |
| nxp         | contact                                               | k32w0+release            | FLASH     |     592256 |     592256 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      72920 |      72920 |        0 |        0.0 |
|             |                                                       | mcxw71+release           | FLASH     |     625056 |     625056 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      63260 |      63260 |        0 |        0.0 |
|             | light                                                 | k32w0+release            | FLASH     |     618316 |     618316 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      72216 |      72216 |        0 |        0.0 |
|             |                                                       | k32w1+release            | FLASH     |     709568 |     709568 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      72116 |      72116 |        0 |        0.0 |
|             | lock                                                  | mcxw71+release           | FLASH     |     776192 |     776192 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      67676 |      67676 |        0 |        0.0 |
| psoc6       | all-clusters                                          | cy8ckit_062s2_43012      | FLASH     |    1670716 |    1670716 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     212528 |     212528 |        0 |        0.0 |
|             | all-clusters-minimal                                  | cy8ckit_062s2_43012      | FLASH     |    1575148 |    1575148 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     208576 |     208576 |        0 |        0.0 |
|             | light                                                 | cy8ckit_062s2_43012      | FLASH     |    1448108 |    1448108 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     197304 |     197304 |        0 |        0.0 |
|             | lock                                                  | cy8ckit_062s2_43012      | FLASH     |    1480324 |    1480324 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     225016 |     225016 |        0 |        0.0 |
| qpg         | lighting-app                                          | qpg6105+debug            | FLASH     |     667228 |     667228 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     105244 |     105244 |        0 |        0.0 |
|             | lock-app                                              | qpg6105+debug            | FLASH     |     627248 |     627248 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      99872 |      99872 |        0 |        0.0 |
| stm32       | light                                                 | STM32WB5MM-DK            | FLASH     |     464964 |     464964 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     141488 |     141488 |        0 |        0.0 |
| telink      | bridge-app                                            | tl7218x                  | FLASH     |     677302 |     677302 |        0 |        0.0 |
|             |                                                       |                          |           |     694058 |     694058 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      90944 |      90944 |        0 |        0.0 |
|             |                                                       |                          |           |     102084 |     102084 |        0 |        0.0 |
|             | light-app-ota-compress-lzma-factory-data              | tl3218x                  | FLASH     |     766498 |     766498 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      50236 |      50236 |        0 |        0.0 |
|             | light-app-ota-compress-lzma-shell-factory-data        | tl3218x                  | FLASH     |     767530 |     767530 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      40528 |      40528 |        0 |        0.0 |
|             | light-app-ota-shell-factory-data                      | tl7218x                  | FLASH     |     755986 |     755986 |        0 |        0.0 |
|             |                                                       |                          |           |     773608 |     773608 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      97656 |      97656 |        0 |        0.0 |
|             |                                                       |                          |           |     109408 |     109408 |        0 |        0.0 |
|             | light-switch-app-ota-compress-lzma-factory-data       | tl7218x_retention        | FLASH     |     687056 |     687056 |        0 |        0.0 |
|             |                                                       |                          |           |     702954 |     702954 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      51764 |      51764 |        0 |        0.0 |
|             |                                                       |                          |           |      62796 |      62796 |        0 |        0.0 |
|             | light-switch-app-ota-compress-lzma-shell-factory-data | tlsr9528a                | FLASH     |     715506 |     715506 |        0 |        0.0 |
|             |                                                       |                          |           |     740908 |     740908 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      73576 |      73576 |        0 |        0.0 |
|             |                                                       |                          |           |      85968 |      85968 |        0 |        0.0 |
|             | light-switch-app-ota-shell-factory-data               | tl3218x_retention        | FLASH     |     712846 |     712846 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      37212 |      37212 |        0 |        0.0 |
|             | lighting-app-ota-factory-data                         | tlsr9118bdk40d           | FLASH     |     604320 |     604320 |        0 |        0.0 |
|             |                                                       |                          |           |     600452 |     600452 |        0 |        0.0 |
|             |                                                       |                          | RAM       |     106904 |     106904 |        0 |        0.0 |
|             |                                                       |                          |           |     120180 |     120180 |        0 |        0.0 |
|             | lighting-app-ota-rpc-factory-data-4mb                 | tlsr9518adk80d           | FLASH     |     791030 |     791034 |        4 |        0.0 |
|             |                                                       |                          |           |     808922 |     808926 |        4 |        0.0 |
|             |                                                       |                          | RAM       |      96504 |      96504 |        0 |        0.0 |
|             |                                                       |                          |           |     107676 |     107676 |        0 |        0.0 |
| tizen       | all-clusters-app                                      | arm                      | *unknown* |       5280 |       5280 |        0 |        0.0 |
|             |                                                       |                          | FLASH     |    1812232 |    1812232 |        0 |        0.0 |
|             |                                                       |                          | RAM       |      96696 |      96696 |        0 |        0.0 |
|             | chip-tool-ubsan                                       | arm                      | *unknown* |      20796 |      20800 |        4 |        0.0 |
|             |                                                       |                          | FLASH     |   21014902 |   21042094 |    27192 |        0.1 |
|             |                                                       |                          | RAM       |    9155628 |    9169728 |    14100 |        0.2 |

</details>

author_association: NONE