Skip to content

Commit

Permalink
[icd] Add steps for checking ICD during commissioning
Browse files Browse the repository at this point in the history
  • Loading branch information
erjiaqing committed Oct 20, 2023
1 parent 3e1cc30 commit 8319252
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 4 deletions.
16 changes: 16 additions & 0 deletions src/controller/AutoCommissioner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,13 @@ CommissioningStage AutoCommissioner::GetNextCommissioningStageInternal(Commissio
}
return CommissioningStage::kFindOperational;
case CommissioningStage::kFindOperational:
if (mParams.GetIcdRegistrationStrategy() != IcdRegistrationStrategy::kIgnore)
{
return CommissioningStage::kIcdDiscovery;
}
return CommissioningStage::kSendComplete;
case CommissioningStage::kIcdDiscovery:
// TODO(#29385): Register to the ICD.
return CommissioningStage::kSendComplete;
case CommissioningStage::kSendComplete:
return CommissioningStage::kCleanup;
Expand Down Expand Up @@ -705,6 +712,15 @@ CHIP_ERROR AutoCommissioner::CommissioningStepFinished(CHIP_ERROR err, Commissio
case CommissioningStage::kFindOperational:
mOperationalDeviceProxy = report.Get<OperationalNodeFoundData>().operationalProxy;
break;
case CommissioningStage::kIcdDiscovery: {
IcdInfo icdInfo = report.Get<IcdInfo>();
if (icdInfo.isIcd)
{
mNeedIcdRegistraion = true;
ChipLogDetail(Controller, "AutoCommissioner: Device is ICD");
}
break;
}
case CommissioningStage::kCleanup:
ReleasePAI();
ReleaseDAC();
Expand Down
2 changes: 2 additions & 0 deletions src/controller/AutoCommissioner.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ class AutoCommissioner : public CommissioningDelegate
ReadCommissioningInfo mDeviceCommissioningInfo;
bool mNeedsDST = false;

bool mNeedIcdRegistraion = false;

// TODO: Why were the nonces statically allocated, but the certs dynamically allocated?
uint8_t * mDAC = nullptr;
uint16_t mDACLen = 0;
Expand Down
48 changes: 48 additions & 0 deletions src/controller/CHIPDeviceController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1880,6 +1880,9 @@ void DeviceCommissioner::OnDone(app::ReadClient *)
case CommissioningStage::kCheckForMatchingFabric:
ParseFabrics();
break;
case CommissioningStage::kIcdDiscovery:
ParseIcdInfo();
break;
default:
// We're not trying to read anything here, just exit
break;
Expand Down Expand Up @@ -2175,6 +2178,43 @@ void DeviceCommissioner::ParseFabrics()
CommissioningStageComplete(return_err, report);
}

void DeviceCommissioner::ParseIcdInfo()
{
CHIP_ERROR err;
IcdInfo info;
IcdManagement::Attributes::FeatureMap::TypeInfo::DecodableType featureMap;

err = mAttributeCache->Get<IcdManagement::Attributes::FeatureMap::TypeInfo>(kRootEndpointId, featureMap);
if (err == CHIP_NO_ERROR)
{
info.isIcd = true;
info.checkInProtocolSupport = !!(featureMap & 0x1);
}
else if (err == CHIP_ERROR_IM_STATUS_CODE_RECEIVED)
{
app::StatusIB statusIB;
err = mAttributeCache->GetStatus(
app::ConcreteAttributePath(kRootEndpointId, IcdManagement::Id, IcdManagement::Attributes::FeatureMap::Id), statusIB);
if (err != CHIP_NO_ERROR)
{
CommissioningStageComplete(err);
return;
}
if (statusIB.mStatus == Protocols::InteractionModel::Status::UnsupportedCluster)
{
info.isIcd = false;
}
else
{
err = statusIB.ToChipError();
}
}

CommissioningDelegate::CommissioningReport report;
report.Set<IcdInfo>(info);
CommissioningStageComplete(err, report);
}

void DeviceCommissioner::OnArmFailSafe(void * context,
const GeneralCommissioning::Commands::ArmFailSafeResponse::DecodableType & data)
{
Expand Down Expand Up @@ -2782,6 +2822,14 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio
);
}
break;
case CommissioningStage::kIcdDiscovery: {
app::AttributePathParams readPaths[1];
// Read all the feature maps for all the networking clusters on any endpoint to determine what is supported
readPaths[0] =
app::AttributePathParams(app::Clusters::IcdManagement::Id, app::Clusters::IcdManagement::Attributes::FeatureMap::Id);
SendCommissioningReadRequest(proxy, timeout, readPaths, 1);
}
break;
case CommissioningStage::kSendComplete: {
GeneralCommissioning::Commands::CommissioningComplete::Type request;
SendCommand(proxy, request, OnCommissioningCompleteResponse, OnBasicFailure, endpoint, timeout);
Expand Down
1 change: 1 addition & 0 deletions src/controller/CHIPDeviceController.h
Original file line number Diff line number Diff line change
Expand Up @@ -938,6 +938,7 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController,
void ParseFabrics();
// Called by ParseCommissioningInfo
void ParseTimeSyncInfo(ReadCommissioningInfo & info);
void ParseIcdInfo();
#endif // CHIP_CONFIG_ENABLE_READ_CLIENT

static CHIP_ERROR
Expand Down
4 changes: 4 additions & 0 deletions src/controller/CommissioningDelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ const char * StageToString(CommissioningStage stage)
return "FindOperational";
break;

case kIcdDiscovery:
return "ICDDiscovery";
break;

case kSendComplete:
return "SendComplete";
break;
Expand Down
34 changes: 30 additions & 4 deletions src/controller/CommissioningDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,12 @@ enum CommissioningStage : uint8_t
kWiFiNetworkEnable, ///< Send ConnectNetwork (0x31:6) command to the device for the WiFi network
kThreadNetworkEnable, ///< Send ConnectNetwork (0x31:6) command to the device for the Thread network
kFindOperational, ///< Perform operational discovery and establish a CASE session with the device
kSendComplete, ///< Send CommissioningComplete (0x30:4) command to the device
kCleanup, ///< Call delegates with status, free memory, clear timers and state
/// Optional steps for ICD
kIcdDiscovery, ///< Check whether the device is an ICD
/// TODO(#29384): Finish ICD registration implementation in commissioner
/// End of optional steps for ICD
kSendComplete, ///< Send CommissioningComplete (0x30:4) command to the device
kCleanup, ///< Call delegates with status, free memory, clear timers and state
/// Send ScanNetworks (0x31:0) command to the device.
/// ScanNetworks can happen anytime after kArmFailsafe.
/// However, the cirque tests fail if it is earlier in the list
Expand All @@ -71,6 +75,13 @@ enum CommissioningStage : uint8_t
kNeedsNetworkCreds,
};

enum IcdRegistrationStrategy
{
kIgnore, ///< Do not check whether the device is an ICD during commissioning
kBeforeComplete, ///< Do commissioner self-registration or external controller registration,
///< Controller should provide a ICDKey manager for generating symmetric key
};

const char * StageToString(CommissioningStage stage);

struct WiFiCredentials
Expand Down Expand Up @@ -493,6 +504,13 @@ class CommissioningParameters
return *this;
}

IcdRegistrationStrategy GetIcdRegistrationStrategy() const { return mIcdRegistrationStrategy; }
CommissioningParameters & SetIcdRegistrationStrategy(IcdRegistrationStrategy icdRegistrationStrategy)
{
mIcdRegistrationStrategy = icdRegistrationStrategy;
return *this;
}

// Clear all members that depend on some sort of external buffer. Can be
// used to make sure that we are not holding any dangling pointers.
void ClearExternalBufferDependentValues()
Expand Down Expand Up @@ -550,7 +568,8 @@ class CommissioningParameters
Optional<bool> mAttemptWiFiNetworkScan;
Optional<bool> mAttemptThreadNetworkScan; // This automatically gets set to false when a ThreadOperationalDataset is set
Optional<bool> mSkipCommissioningComplete;
bool mCheckForMatchingFabric = false;
IcdRegistrationStrategy mIcdRegistrationStrategy = IcdRegistrationStrategy::kIgnore;
bool mCheckForMatchingFabric = false;
};

struct RequestedCertificate
Expand Down Expand Up @@ -632,6 +651,13 @@ struct ReadCommissioningInfo
uint8_t maxTimeZoneSize = 1;
uint8_t maxDSTSize = 1;
};

struct IcdInfo
{
bool isIcd = false;
bool checkInProtocolSupport = false;
};

struct MatchingFabricInfo
{
NodeId nodeId = kUndefinedNodeId;
Expand Down Expand Up @@ -694,7 +720,7 @@ class CommissioningDelegate
*/
struct CommissioningReport : Variant<RequestedCertificate, AttestationResponse, CSRResponse, NocChain, OperationalNodeFoundData,
ReadCommissioningInfo, AttestationErrorInfo, CommissioningErrorInfo,
NetworkCommissioningStatusInfo, MatchingFabricInfo, TimeZoneResponseInfo>
NetworkCommissioningStatusInfo, MatchingFabricInfo, TimeZoneResponseInfo, IcdInfo>
{
CommissioningReport() : stageCompleted(CommissioningStage::kError) {}
CommissioningStage stageCompleted;
Expand Down

0 comments on commit 8319252

Please sign in to comment.