From 2d770941b6318c75e3b430af0c03ed93b5f55347 Mon Sep 17 00:00:00 2001 From: chendejin Date: Fri, 14 Jun 2024 19:39:10 +0800 Subject: [PATCH] Added write request cancel function --- src/controller/CHIPDeviceController.cpp | 11 ++++++++++- src/controller/CHIPDeviceController.h | 1 + src/controller/WriteInteraction.h | 18 +++++++++++++++++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 7a345f20bb9829..1b7534e3dce086 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -1030,6 +1030,12 @@ void DeviceCommissioner::CancelCommissioningInteractions() mInvokeCancelFn(); mInvokeCancelFn = nullptr; } + if (mWriteCancelFn) + { + ChipLogDetail(Controller, "Cancelling write request for step '%s'", StageToString(mCommissioningStage)); + mWriteCancelFn(); + mWriteCancelFn = nullptr; + } if (mOnDeviceConnectedCallback.IsRegistered()) { ChipLogDetail(Controller, "Cancelling CASE setup for step '%s'", StageToString(mCommissioningStage)); @@ -1979,6 +1985,7 @@ void DeviceCommissioner::CommissioningStageComplete(CHIP_ERROR err, Commissionin DeviceProxy * proxy = mDeviceBeingCommissioned; mDeviceBeingCommissioned = nullptr; mInvokeCancelFn = nullptr; + mWriteCancelFn = nullptr; if (mPairingDelegate != nullptr) { @@ -2753,10 +2760,12 @@ CHIP_ERROR DeviceCommissioner::SendCommissioningWriteRequest(DeviceProxy * devic WriteResponseSuccessCallback successCb, WriteResponseFailureCallback failureCb) { + VerifyOrDie(!mWriteCancelFn); // we don't make parallel (cancellable) calls auto onSuccessCb = [this, successCb](const app::ConcreteAttributePath & aPath) { successCb(this); }; auto onFailureCb = [this, failureCb](const app::ConcreteAttributePath * aPath, CHIP_ERROR aError) { failureCb(this, aError); }; return WriteAttribute(device->GetSecureSession().Value(), endpoint, cluster, attribute, requestData, onSuccessCb, onFailureCb, - /* aTimedWriteTimeoutMs = */ NullOptional, /* onDoneCb = */ nullptr, /* aDataVersion = */ NullOptional); + /* aTimedWriteTimeoutMs = */ NullOptional, /* onDoneCb = */ nullptr, /* aDataVersion = */ NullOptional, + /* outCancelFn = */ &mWriteCancelFn); } void DeviceCommissioner::SendCommissioningReadRequest(DeviceProxy * proxy, Optional timeout, diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index 7ff21922b02591..029383c1837ad1 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -820,6 +820,7 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, CommissioningStage mCommissioningStage = CommissioningStage::kSecurePairing; bool mRunCommissioningAfterConnection = false; Internal::InvokeCancelFn mInvokeCancelFn; + Internal::WriteCancelFn mWriteCancelFn; ObjectPool mCommissioneeDevicePool; diff --git a/src/controller/WriteInteraction.h b/src/controller/WriteInteraction.h index 19e383d738efe8..de95e45f6c100c 100644 --- a/src/controller/WriteInteraction.h +++ b/src/controller/WriteInteraction.h @@ -23,11 +23,17 @@ #include #include #include +#include #include namespace chip { namespace Controller { +namespace Internal { +// WriteCancelFn functions on WriteAttribute() are for internal use only. +typedef std::function WriteCancelFn; +} // namespace Internal + /* * An adapter callback that permits applications to provide std::function callbacks for success, error and on done. * This permits a slightly more flexible programming model that allows applications to pass in lambdas and bound member functions @@ -130,7 +136,8 @@ CHIP_ERROR WriteAttribute(const SessionHandle & sessionHandle, chip::EndpointId AttributeId attributeId, const AttrType & requestData, WriteCallback::OnSuccessCallbackType onSuccessCb, WriteCallback::OnErrorCallbackType onErrorCb, const Optional & aTimedWriteTimeoutMs, WriteCallback::OnDoneCallbackType onDoneCb = nullptr, - const Optional & aDataVersion = NullOptional) + const Optional & aDataVersion = NullOptional, + Internal::WriteCancelFn * outCancelFn = nullptr) { auto callback = Platform::MakeUnique(onSuccessCb, onErrorCb, onDoneCb, sessionHandle->IsGroupSession()); VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY); @@ -151,6 +158,15 @@ CHIP_ERROR WriteAttribute(const SessionHandle & sessionHandle, chip::EndpointId ReturnErrorOnFailure(client->SendWriteRequest(sessionHandle)); + // If requested by the caller, provide a way to cancel the write interaction. + if (outCancelFn != nullptr) + { + *outCancelFn = [rawCallback = callback.get(), rawClient = client.get()]() { + chip::Platform::Delete(rawClient); + chip::Platform::Delete(rawCallback); + }; + } + // At this point the handle will ensure our callback's OnDone is always // called. client.release();