diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 8bcba1f5c06564..88bef7820efd71 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -489,6 +489,17 @@ void DeviceCommissioner::Shutdown() } #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY + // If we have a commissionee device for the device being commissioned, + // release it now, before we release our whole commissionee pool. + if (mDeviceBeingCommissioned != nullptr) + { + auto * commissionee = FindCommissioneeDevice(mDeviceBeingCommissioned->GetDeviceId()); + if (commissionee) + { + ReleaseCommissioneeDevice(commissionee); + } + } + // Release everything from the commissionee device pool here. DeviceController::Shutdown releases operational. mCommissioneeDevicePool.ReleaseAll(); @@ -1561,6 +1572,15 @@ void DeviceCommissioner::CommissioningStageComplete(CHIP_ERROR err, Commissionin { // Once this stage is complete, reset mDeviceBeingCommissioned - this will be reset when the delegate calls the next step. MATTER_TRACE_EVENT_SCOPE("CommissioningStageComplete", "DeviceCommissioner"); + + if (mDeviceBeingCommissioned == nullptr) + { + // We are getting a stray callback (e.g. due to un-cancellable + // operations) when we are not in fact commissioning anything. Just + // ignore it. + return; + } + NodeId nodeId = mDeviceBeingCommissioned->GetDeviceId(); DeviceProxy * proxy = mDeviceBeingCommissioned; mDeviceBeingCommissioned = nullptr;