From 48eabd3cbbace8639a5e64259397f1990d521894 Mon Sep 17 00:00:00 2001 From: Jerry Johns Date: Mon, 7 Mar 2022 08:10:14 -0800 Subject: [PATCH] Cleanup dangling CommissioneedeviceProxy object on CASE session (#15902) establishment failure This cleans up the dangling CommissioneeDeviceProxy object that is usually cleaned up in case of successful commissioning in OnDeviceConnectedFn (i.e successful CASE session establishment upon completion of commissioning). Consequently, failure to establish CASE should do the same *if and only if* the device that we failed to establish CASE with matches the device being commissioned. Tests: - Ensured we hit a VerifyOrDie error due to an open EC if CASE failed to establish, and then ensured that didn't manifest again with these changes. --- src/controller/CHIPDeviceController.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 35dedf31815586..c4494192a92b71 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -1501,12 +1501,23 @@ void DeviceCommissioner::OnDeviceConnectionFailureFn(void * context, PeerId peer { // CASE session establishment failed. DeviceCommissioner * commissioner = static_cast(context); + ChipLogProgress(Controller, "Device connection failed. Error %s", ErrorStr(error)); VerifyOrReturn(commissioner != nullptr, ChipLogProgress(Controller, "Device connection failure callback with null context. Ignoring")); VerifyOrReturn(commissioner->mPairingDelegate != nullptr, ChipLogProgress(Controller, "Device connection failure callback with null pairing delegate. Ignoring")); + // + // If a device is being commissioned currently and it is the very same device that we just failed to establish CASE with, + // we need to clean it up to prevent a dangling CommissioneeDeviceProxy object. + // + if (commissioner->mDeviceBeingCommissioned != nullptr && commissioner->mDeviceBeingCommissioned->GetPeerId() == peerId) + { + commissioner->ReleaseCommissioneeDevice(commissioner->mDeviceBeingCommissioned); + commissioner->mDeviceBeingCommissioned = nullptr; + } + commissioner->mCASESessionManager->ReleaseSession(peerId); if (commissioner->mCommissioningStage == CommissioningStage::kFindOperational && commissioner->mCommissioningDelegate != nullptr)