[controller] merge ReadCommissioningInfo2 into ReadCommissioningInfo (#30978)
* [controller] merge ReadCommissioningInfo2 into ReadCommissioningInfo
* Update src/controller/CHIPDeviceController.cpp
Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
* Update src/controller/CHIPDeviceController.cpp
Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
* Update src/controller/CHIPDeviceController.cpp
Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
* Update src/controller/CHIPDeviceController.cpp
Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
* address comment
---------
Co-authored-by: yunhanw-google <yunhanw@google.com>
Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
diff --git a/src/controller/AutoCommissioner.cpp b/src/controller/AutoCommissioner.cpp
index 82286e3..1b286a4 100644
--- a/src/controller/AutoCommissioner.cpp
+++ b/src/controller/AutoCommissioner.cpp
@@ -725,6 +725,15 @@
switch (report.stageCompleted)
{
case CommissioningStage::kReadCommissioningInfo:
+ break;
+ case CommissioningStage::kReadCommissioningInfo2: {
+ if (!report.Is<ReadCommissioningInfo>())
+ {
+ ChipLogError(Controller,
+ "[BUG] Should read commissioning info, but report is not ReadCommissioningInfo. THIS IS A BUG.");
+ }
+ ReadCommissioningInfo commissioningInfo = report.Get<ReadCommissioningInfo>();
+
mDeviceCommissioningInfo = report.Get<ReadCommissioningInfo>();
if (!mParams.GetFailsafeTimerSeconds().HasValue() && mDeviceCommissioningInfo.general.recommendedFailsafe > 0)
{
@@ -736,22 +745,12 @@
.SetLocationCapability(mDeviceCommissioningInfo.general.locationCapability);
// Don't send DST unless the device says it needs it
mNeedsDST = false;
- break;
- case CommissioningStage::kReadCommissioningInfo2: {
- if (!report.Is<ReadCommissioningInfo2>())
- {
- ChipLogError(
- Controller,
- "[BUG] Should read commissioning info (part 2), but report is not ReadCommissioningInfo2. THIS IS A BUG.");
- }
-
- ReadCommissioningInfo2 commissioningInfo = report.Get<ReadCommissioningInfo2>();
mParams.SetSupportsConcurrentConnection(commissioningInfo.supportsConcurrentConnection);
if (mParams.GetCheckForMatchingFabric())
{
- chip::NodeId nodeId = commissioningInfo.nodeId;
+ chip::NodeId nodeId = commissioningInfo.remoteNodeId;
if (nodeId != kUndefinedNodeId)
{
mParams.SetRemoteNodeId(nodeId);
@@ -760,7 +759,7 @@
if (mParams.GetICDRegistrationStrategy() != ICDRegistrationStrategy::kIgnore)
{
- if (commissioningInfo.isIcd && commissioningInfo.checkInProtocolSupport)
+ if (commissioningInfo.isLIT && commissioningInfo.checkInProtocolSupport)
{
mNeedIcdRegistration = true;
ChipLogDetail(Controller, "AutoCommissioner: ICD supports the check-in protocol.");
diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp
index 4959196..e695461 100644
--- a/src/controller/CHIPDeviceController.cpp
+++ b/src/controller/CHIPDeviceController.cpp
@@ -1922,25 +1922,50 @@
// ClusterStateCache::Callback impl
void DeviceCommissioner::OnDone(app::ReadClient *)
{
+ mReadClient = nullptr;
switch (mCommissioningStage)
{
case CommissioningStage::kReadCommissioningInfo:
- ParseCommissioningInfo();
+ // Silently complete the stage, data will be saved in attribute cache and
+ // will be parsed after all ReadCommissioningInfo stages are completed.
+ CommissioningStageComplete(CHIP_NO_ERROR);
break;
case CommissioningStage::kReadCommissioningInfo2:
- ParseCommissioningInfo2();
+ // Note: Only parse commissioning info in the last ReadCommissioningInfo stage.
+ ParseCommissioningInfo();
break;
default:
- // We're not trying to read anything here, just exit
break;
}
}
void DeviceCommissioner::ParseCommissioningInfo()
{
+ CHIP_ERROR err = CHIP_NO_ERROR;
+ ReadCommissioningInfo info;
+
+ err = ParseCommissioningInfo1(info);
+ if (err == CHIP_NO_ERROR)
+ {
+ err = ParseCommissioningInfo2(info);
+ }
+
+ mAttributeCache = nullptr;
+
+ if (mPairingDelegate != nullptr)
+ {
+ mPairingDelegate->OnReadCommissioningInfo(info);
+ }
+
+ CommissioningDelegate::CommissioningReport report;
+ report.Set<ReadCommissioningInfo>(info);
+ CommissioningStageComplete(err, report);
+}
+
+CHIP_ERROR DeviceCommissioner::ParseCommissioningInfo1(ReadCommissioningInfo & info)
+{
CHIP_ERROR err;
CHIP_ERROR return_err = CHIP_NO_ERROR;
- ReadCommissioningInfo info;
// Try to parse as much as we can here before returning, even if attributes
// are missing or cannot be decoded.
@@ -2080,17 +2105,8 @@
{
ChipLogError(Controller, "Error parsing commissioning information");
}
- mAttributeCache = nullptr;
- mReadClient = nullptr;
- if (mPairingDelegate != nullptr)
- {
- mPairingDelegate->OnReadCommissioningInfo(info);
- }
-
- CommissioningDelegate::CommissioningReport report;
- report.Set<ReadCommissioningInfo>(info);
- CommissioningStageComplete(return_err, report);
+ return return_err;
}
void DeviceCommissioner::ParseTimeSyncInfo(ReadCommissioningInfo & info)
@@ -2153,34 +2169,31 @@
}
}
-void DeviceCommissioner::ParseCommissioningInfo2()
+CHIP_ERROR DeviceCommissioner::ParseCommissioningInfo2(ReadCommissioningInfo & info)
{
- ReadCommissioningInfo2 info;
- CHIP_ERROR return_err = CHIP_NO_ERROR;
+ CHIP_ERROR err = CHIP_NO_ERROR;
using namespace chip::app::Clusters::GeneralCommissioning::Attributes;
- CHIP_ERROR err =
- mAttributeCache->Get<SupportsConcurrentConnection::TypeInfo>(kRootEndpointId, info.supportsConcurrentConnection);
- if (err != CHIP_NO_ERROR)
+
+ if (mAttributeCache->Get<SupportsConcurrentConnection::TypeInfo>(kRootEndpointId, info.supportsConcurrentConnection) !=
+ CHIP_NO_ERROR)
{
// May not be present so don't return the error code, non fatal, default concurrent
ChipLogError(Controller, "Failed to read SupportsConcurrentConnection: %" CHIP_ERROR_FORMAT, err.Format());
info.supportsConcurrentConnection = true;
}
- return_err = ParseFabrics(info);
+ err = ParseFabrics(info);
- if (return_err == CHIP_NO_ERROR)
+ if (err == CHIP_NO_ERROR)
{
- return_err = ParseICDInfo(info);
+ err = ParseICDInfo(info);
}
- CommissioningDelegate::CommissioningReport report;
- report.Set<ReadCommissioningInfo2>(info);
- CommissioningStageComplete(return_err, report);
+ return err;
}
-CHIP_ERROR DeviceCommissioner::ParseFabrics(ReadCommissioningInfo2 & info)
+CHIP_ERROR DeviceCommissioner::ParseFabrics(ReadCommissioningInfo & info)
{
CHIP_ERROR err;
CHIP_ERROR return_err = CHIP_NO_ERROR;
@@ -2230,7 +2243,7 @@
else if (commissionerRootPublicKey.Matches(deviceRootPublicKey))
{
ChipLogProgress(Controller, "DeviceCommissioner::OnDone - fabric root keys match");
- info.nodeId = fabricDescriptor.nodeID;
+ info.remoteNodeId = fabricDescriptor.nodeID;
}
}
}
@@ -2244,13 +2257,13 @@
if (mPairingDelegate != nullptr)
{
- mPairingDelegate->OnFabricCheck(info.nodeId);
+ mPairingDelegate->OnFabricCheck(info.remoteNodeId);
}
return return_err;
}
-CHIP_ERROR DeviceCommissioner::ParseICDInfo(ReadCommissioningInfo2 & info)
+CHIP_ERROR DeviceCommissioner::ParseICDInfo(ReadCommissioningInfo & info)
{
CHIP_ERROR err;
IcdManagement::Attributes::FeatureMap::TypeInfo::DecodableType featureMap;
@@ -2258,14 +2271,14 @@
err = mAttributeCache->Get<IcdManagement::Attributes::FeatureMap::TypeInfo>(kRootEndpointId, featureMap);
if (err == CHIP_NO_ERROR)
{
- info.isIcd = true;
+ info.isLIT = true;
info.checkInProtocolSupport = !!(featureMap & to_underlying(IcdManagement::Feature::kCheckInProtocolSupport));
}
else if (err == CHIP_ERROR_KEY_NOT_FOUND)
{
// This key is optional so not an error
err = CHIP_NO_ERROR;
- info.isIcd = false;
+ info.isLIT = false;
err = CHIP_NO_ERROR;
}
else if (err == CHIP_ERROR_IM_STATUS_CODE_RECEIVED)
@@ -2277,7 +2290,7 @@
{
if (statusIB.mStatus == Protocols::InteractionModel::Status::UnsupportedCluster)
{
- info.isIcd = false;
+ info.isLIT = false;
}
else
{
@@ -2458,7 +2471,8 @@
readParams.mpAttributePathParamsList = readPaths;
readParams.mAttributePathParamsListSize = readPathsSize;
- auto attributeCache = Platform::MakeUnique<app::ClusterStateCache>(*this);
+ // Take ownership of the attribute cache, so it can be released when SendRequest fails.
+ auto attributeCache = std::move(mAttributeCache);
auto readClient = chip::Platform::MakeUnique<app::ReadClient>(
engine, proxy->GetExchangeManager(), attributeCache->GetBufferedCallback(), app::ReadClient::InteractionType::Read);
CHIP_ERROR err = readClient->SendRequest(readParams);
@@ -2509,6 +2523,13 @@
break;
case CommissioningStage::kReadCommissioningInfo: {
ChipLogProgress(Controller, "Sending read request for commissioning information");
+ // Allocate a new ClusterStateCache when starting reading the first batch of attributes.
+ // The cache will be released in:
+ // - SendCommissioningReadRequest when failing to send a read request.
+ // - ParseCommissioningInfo when the last ReadCommissioningInfo stage is completed.
+ // Currently, we have two ReadCommissioningInfo* stages.
+ mAttributeCache = Platform::MakeUnique<app::ClusterStateCache>(*this);
+
// NOTE: this array cannot have more than 9 entries, since the spec mandates that server only needs to support 9
// See R1.1, 2.11.2 Interaction Model Limits
app::AttributePathParams readPaths[9];
diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h
index e013b6a..2007d84 100644
--- a/src/controller/CHIPDeviceController.h
+++ b/src/controller/CHIPDeviceController.h
@@ -952,12 +952,14 @@
void SendCommissioningReadRequest(DeviceProxy * proxy, Optional<System::Clock::Timeout> timeout,
app::AttributePathParams * readPaths, size_t readPathsSize);
#if CHIP_CONFIG_ENABLE_READ_CLIENT
- // Parsers for the two different read clients
void ParseCommissioningInfo();
- void ParseCommissioningInfo2();
+ // Parsing attributes read in kReadCommissioningInfo stage.
+ CHIP_ERROR ParseCommissioningInfo1(ReadCommissioningInfo & info);
+ // Parsing attributes read in kReadCommissioningInfo2 stage.
+ CHIP_ERROR ParseCommissioningInfo2(ReadCommissioningInfo & info);
// Called by ParseCommissioningInfo2
- CHIP_ERROR ParseFabrics(ReadCommissioningInfo2 & info);
- CHIP_ERROR ParseICDInfo(ReadCommissioningInfo2 & info);
+ CHIP_ERROR ParseFabrics(ReadCommissioningInfo & info);
+ CHIP_ERROR ParseICDInfo(ReadCommissioningInfo & info);
// Called by ParseCommissioningInfo
void ParseTimeSyncInfo(ReadCommissioningInfo & info);
#endif // CHIP_CONFIG_ENABLE_READ_CLIENT
diff --git a/src/controller/CommissioningDelegate.h b/src/controller/CommissioningDelegate.h
index 9a7b4eb..67fe2e6 100644
--- a/src/controller/CommissioningDelegate.h
+++ b/src/controller/CommissioningDelegate.h
@@ -684,18 +684,14 @@
NetworkClusters network;
BasicClusterInfo basic;
GeneralCommissioningInfo general;
- bool requiresUTC = false;
- bool requiresTimeZone = false;
- bool requiresDefaultNTP = false;
- bool requiresTrustedTimeSource = false;
- uint8_t maxTimeZoneSize = 1;
- uint8_t maxDSTSize = 1;
-};
-
-struct ReadCommissioningInfo2
-{
- NodeId nodeId = kUndefinedNodeId;
- bool isIcd = false;
+ bool requiresUTC = false;
+ bool requiresTimeZone = false;
+ bool requiresDefaultNTP = false;
+ bool requiresTrustedTimeSource = false;
+ uint8_t maxTimeZoneSize = 1;
+ uint8_t maxDSTSize = 1;
+ NodeId remoteNodeId = kUndefinedNodeId;
+ bool isLIT = false;
bool checkInProtocolSupport = false;
bool supportsConcurrentConnection = true;
};
@@ -730,8 +726,8 @@
public:
virtual ~CommissioningDelegate(){};
/* CommissioningReport is returned after each commissioning step is completed. The reports for each step are:
- * kReadCommissioningInfo: ReadCommissioningInfo
- * kReadCommissioningInfo2: ReadCommissioningInfo2
+ * kReadCommissioningInfo: Reported together with ReadCommissioningInfo2
+ * kReadCommissioningInfo2: ReadCommissioningInfo
* kArmFailsafe: CommissioningErrorInfo if there is an error
* kConfigRegulatory: CommissioningErrorInfo if there is an error
* kConfigureUTCTime: None
@@ -755,9 +751,9 @@
* kSendComplete: CommissioningErrorInfo if there is an error
* kCleanup: none
*/
- struct CommissioningReport : Variant<RequestedCertificate, AttestationResponse, CSRResponse, NocChain, OperationalNodeFoundData,
- ReadCommissioningInfo, ReadCommissioningInfo2, AttestationErrorInfo,
- CommissioningErrorInfo, NetworkCommissioningStatusInfo, TimeZoneResponseInfo>
+ struct CommissioningReport
+ : Variant<RequestedCertificate, AttestationResponse, CSRResponse, NocChain, OperationalNodeFoundData, ReadCommissioningInfo,
+ AttestationErrorInfo, CommissioningErrorInfo, NetworkCommissioningStatusInfo, TimeZoneResponseInfo>
{
CommissioningReport() : stageCompleted(CommissioningStage::kError) {}
CommissioningStage stageCompleted;
diff --git a/src/controller/python/OpCredsBinding.cpp b/src/controller/python/OpCredsBinding.cpp
index 03f4ca0..79995d1 100644
--- a/src/controller/python/OpCredsBinding.cpp
+++ b/src/controller/python/OpCredsBinding.cpp
@@ -160,7 +160,7 @@
mCompletionError = err;
}
}
- if (report.stageCompleted == chip::Controller::CommissioningStage::kReadCommissioningInfo)
+ if (report.stageCompleted == chip::Controller::CommissioningStage::kReadCommissioningInfo2)
{
mReadCommissioningInfo = report.Get<chip::Controller::ReadCommissioningInfo>();
}