@@ -1201,24 +1201,39 @@ void DeviceCommissioner::OnFailedToExtendedArmFailSafeDeviceAttestation(void * c
1201
1201
void DeviceCommissioner::OnICDManagementRegisterClientResponse (
1202
1202
void * context, const app::Clusters::IcdManagement::Commands::RegisterClientResponse::DecodableType & data)
1203
1203
{
1204
+ CHIP_ERROR err = CHIP_NO_ERROR;
1204
1205
DeviceCommissioner * commissioner = static_cast <DeviceCommissioner *>(context);
1205
- VerifyOrReturn (commissioner != nullptr , ChipLogProgress (Controller, " Command response callback with null context. Ignoring" ));
1206
+ VerifyOrExit (commissioner != nullptr , err = CHIP_ERROR_INVALID_ARGUMENT);
1207
+ VerifyOrExit (commissioner->mCommissioningStage == CommissioningStage::kICDRegistration , err = CHIP_ERROR_INCORRECT_STATE);
1208
+ VerifyOrExit (commissioner->mDeviceBeingCommissioned != nullptr , err = CHIP_ERROR_INCORRECT_STATE);
1206
1209
1207
- if (commissioner->mCommissioningStage != CommissioningStage:: kICDRegistration )
1210
+ if (commissioner->mPairingDelegate != nullptr )
1208
1211
{
1209
- return ;
1212
+ commissioner->mPairingDelegate ->OnICDRegistrationComplete (commissioner->mDeviceBeingCommissioned ->GetDeviceId (),
1213
+ data.ICDCounter );
1210
1214
}
1211
1215
1212
- if (commissioner->mDeviceBeingCommissioned == nullptr )
1213
- {
1214
- return ;
1215
- }
1216
+ exit :
1217
+ CommissioningDelegate::CommissioningReport report;
1218
+ commissioner->CommissioningStageComplete (err, report);
1219
+ }
1220
+
1221
+ void DeviceCommissioner::OnICDManagementStayActiveResponse (
1222
+ void * context, const app::Clusters::IcdManagement::Commands::StayActiveResponse::DecodableType & data)
1223
+ {
1224
+ CHIP_ERROR err = CHIP_NO_ERROR;
1225
+ DeviceCommissioner * commissioner = static_cast <DeviceCommissioner *>(context);
1226
+ VerifyOrExit (commissioner != nullptr , err = CHIP_ERROR_INVALID_ARGUMENT);
1227
+ VerifyOrExit (commissioner->mCommissioningStage == CommissioningStage::kICDSendStayActive , err = CHIP_ERROR_INCORRECT_STATE);
1228
+ VerifyOrExit (commissioner->mDeviceBeingCommissioned != nullptr , err = CHIP_ERROR_INCORRECT_STATE);
1216
1229
1217
1230
if (commissioner->mPairingDelegate != nullptr )
1218
1231
{
1219
- commissioner->mPairingDelegate ->OnICDRegistrationComplete (commissioner->mDeviceBeingCommissioned ->GetDeviceId (),
1220
- data.ICDCounter );
1232
+ commissioner->mPairingDelegate ->OnICDStayActiveComplete (commissioner->mDeviceBeingCommissioned ->GetDeviceId (),
1233
+ data.promisedActiveDuration );
1221
1234
}
1235
+
1236
+ exit :
1222
1237
CommissioningDelegate::CommissioningReport report;
1223
1238
commissioner->CommissioningStageComplete (CHIP_NO_ERROR, report);
1224
1239
}
@@ -1854,7 +1869,8 @@ void DeviceCommissioner::OnDeviceConnectedFn(void * context, Messaging::Exchange
1854
1869
{
1855
1870
// CASE session established.
1856
1871
DeviceCommissioner * commissioner = static_cast <DeviceCommissioner *>(context);
1857
- VerifyOrDie (commissioner->mCommissioningStage == CommissioningStage::kFindOperational );
1872
+ VerifyOrDie (commissioner->mCommissioningStage == CommissioningStage::kFindOperationalForStayActive ||
1873
+ commissioner->mCommissioningStage == CommissioningStage::kFindOperationalForCommissioningComplete );
1858
1874
VerifyOrDie (commissioner->mDeviceBeingCommissioned ->GetDeviceId () == sessionHandle->GetPeer ().GetNodeId ());
1859
1875
commissioner->CancelCASECallbacks (); // ensure all CASE callbacks are unregistered
1860
1876
@@ -1867,7 +1883,8 @@ void DeviceCommissioner::OnDeviceConnectionFailureFn(void * context, const Scope
1867
1883
{
1868
1884
// CASE session establishment failed.
1869
1885
DeviceCommissioner * commissioner = static_cast <DeviceCommissioner *>(context);
1870
- VerifyOrDie (commissioner->mCommissioningStage == CommissioningStage::kFindOperational );
1886
+ VerifyOrDie (commissioner->mCommissioningStage == CommissioningStage::kFindOperationalForStayActive ||
1887
+ commissioner->mCommissioningStage == CommissioningStage::kFindOperationalForCommissioningComplete );
1871
1888
VerifyOrDie (commissioner->mDeviceBeingCommissioned ->GetDeviceId () == peerId.GetNodeId ());
1872
1889
commissioner->CancelCASECallbacks (); // ensure all CASE callbacks are unregistered
1873
1890
@@ -1908,7 +1925,8 @@ void DeviceCommissioner::OnDeviceConnectionRetryFn(void * context, const ScopedN
1908
1925
ChipLogValueScopedNodeId (peerId), error.Format (), retryTimeout.count ());
1909
1926
1910
1927
auto self = static_cast <DeviceCommissioner *>(context);
1911
- VerifyOrDie (self->mCommissioningStage == CommissioningStage::kFindOperational );
1928
+ VerifyOrDie (self->GetCommissioningStage () == CommissioningStage::kFindOperationalForStayActive ||
1929
+ self->GetCommissioningStage () == CommissioningStage::kFindOperationalForCommissioningComplete );
1912
1930
VerifyOrDie (self->mDeviceBeingCommissioned ->GetDeviceId () == peerId.GetNodeId ());
1913
1931
1914
1932
// We need to do the fail-safe arming over the PASE session.
@@ -1936,7 +1954,7 @@ void DeviceCommissioner::OnDeviceConnectionRetryFn(void * context, const ScopedN
1936
1954
}
1937
1955
1938
1956
// A false return is fine; we don't want to make the fail-safe shorter here.
1939
- self->ExtendArmFailSafeInternal (commissioneeDevice, CommissioningStage:: kFindOperational , failsafeTimeout,
1957
+ self->ExtendArmFailSafeInternal (commissioneeDevice, self-> GetCommissioningStage () , failsafeTimeout,
1940
1958
MakeOptional (kMinimumCommissioningStepTimeout ), OnExtendFailsafeForCASERetrySuccess,
1941
1959
OnExtendFailsafeForCASERetryFailure, /* fireAndForget = */ true );
1942
1960
}
@@ -3180,13 +3198,7 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio
3180
3198
}
3181
3199
}
3182
3200
break ;
3183
- case CommissioningStage::kICDSendStayActive : {
3184
- // TODO(#24259): Send StayActiveRequest once server supports this.
3185
- CommissioningStageComplete (CHIP_NO_ERROR);
3186
- }
3187
- break ;
3188
- case CommissioningStage::kFindOperational : {
3189
- // If there is an error, CommissioningStageComplete will be called from OnDeviceConnectionFailureFn.
3201
+ case CommissioningStage::kEvictPreviousCaseSessions : {
3190
3202
auto scopedPeerId = GetPeerScopedId (proxy->GetDeviceId ());
3191
3203
3192
3204
// If we ever had a commissioned device with this node ID before, we may
@@ -3196,7 +3208,13 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio
3196
3208
// clearing the ones associated with our fabric index is good enough and
3197
3209
// we don't need to worry about ExpireAllSessionsOnLogicalFabric.
3198
3210
mSystemState ->SessionMgr ()->ExpireAllSessions (scopedPeerId);
3199
-
3211
+ CommissioningStageComplete (CHIP_NO_ERROR);
3212
+ return ;
3213
+ }
3214
+ case CommissioningStage::kFindOperationalForStayActive :
3215
+ case CommissioningStage::kFindOperationalForCommissioningComplete : {
3216
+ // If there is an error, CommissioningStageComplete will be called from OnDeviceConnectionFailureFn.
3217
+ auto scopedPeerId = GetPeerScopedId (proxy->GetDeviceId ());
3200
3218
mSystemState ->CASESessionMgr ()->FindOrEstablishSession (scopedPeerId, &mOnDeviceConnectedCallback ,
3201
3219
&mOnDeviceConnectionFailureCallback
3202
3220
#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
@@ -3206,7 +3224,31 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio
3206
3224
);
3207
3225
}
3208
3226
break ;
3227
+ case CommissioningStage::kICDSendStayActive : {
3228
+ if (!(params.GetICDStayActiveDurationMsec ().HasValue ()))
3229
+ {
3230
+ ChipLogProgress (Controller, " Skipping kICDSendStayActive" );
3231
+ CommissioningStageComplete (CHIP_NO_ERROR);
3232
+ return ;
3233
+ }
3234
+
3235
+ // StayActive Command happens over CASE Connection
3236
+ IcdManagement::Commands::StayActiveRequest::Type request;
3237
+ request.stayActiveDuration = params.GetICDStayActiveDurationMsec ().Value ();
3238
+ ChipLogError (Controller, " Send ICD StayActive with Duration %u" , request.stayActiveDuration );
3239
+ CHIP_ERROR err =
3240
+ SendCommissioningCommand (proxy, request, OnICDManagementStayActiveResponse, OnBasicFailure, endpoint, timeout);
3241
+ if (err != CHIP_NO_ERROR)
3242
+ {
3243
+ // We won't get any async callbacks here, so just complete our stage.
3244
+ ChipLogError (Controller, " Failed to send IcdManagement.StayActive command: %" CHIP_ERROR_FORMAT, err.Format ());
3245
+ CommissioningStageComplete (err);
3246
+ return ;
3247
+ }
3248
+ }
3249
+ break ;
3209
3250
case CommissioningStage::kSendComplete : {
3251
+ // CommissioningComplete command happens over the CASE connection.
3210
3252
GeneralCommissioning::Commands::CommissioningComplete::Type request;
3211
3253
CHIP_ERROR err =
3212
3254
SendCommissioningCommand (proxy, request, OnCommissioningCompleteResponse, OnBasicFailure, endpoint, timeout);
0 commit comments