Skip to content

Commit

Permalink
Added write request cancel function
Browse files Browse the repository at this point in the history
  • Loading branch information
DejinChen committed Jun 14, 2024
1 parent 236743e commit 2d77094
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 2 deletions.
11 changes: 10 additions & 1 deletion src/controller/CHIPDeviceController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -1979,6 +1985,7 @@ void DeviceCommissioner::CommissioningStageComplete(CHIP_ERROR err, Commissionin
DeviceProxy * proxy = mDeviceBeingCommissioned;
mDeviceBeingCommissioned = nullptr;
mInvokeCancelFn = nullptr;
mWriteCancelFn = nullptr;

if (mPairingDelegate != nullptr)
{
Expand Down Expand Up @@ -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<System::Clock::Timeout> 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 @@ -820,6 +820,7 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController,
CommissioningStage mCommissioningStage = CommissioningStage::kSecurePairing;
bool mRunCommissioningAfterConnection = false;
Internal::InvokeCancelFn mInvokeCancelFn;
Internal::WriteCancelFn mWriteCancelFn;

ObjectPool<CommissioneeDeviceProxy, kNumMaxActiveDevices> mCommissioneeDevicePool;

Expand Down
18 changes: 17 additions & 1 deletion src/controller/WriteInteraction.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,17 @@
#include <app/WriteClient.h>
#include <controller/CommandSenderAllocator.h>
#include <controller/TypedCommandCallback.h>
#include <functional>
#include <lib/core/Optional.h>

namespace chip {
namespace Controller {

namespace Internal {
// WriteCancelFn functions on WriteAttribute() are for internal use only.
typedef std::function<void()> 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
Expand Down Expand Up @@ -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<uint16_t> & aTimedWriteTimeoutMs,
WriteCallback::OnDoneCallbackType onDoneCb = nullptr,
const Optional<DataVersion> & aDataVersion = NullOptional)
const Optional<DataVersion> & aDataVersion = NullOptional,
Internal::WriteCancelFn * outCancelFn = nullptr)
{
auto callback = Platform::MakeUnique<WriteCallback>(onSuccessCb, onErrorCb, onDoneCb, sessionHandle->IsGroupSession());
VerifyOrReturnError(callback != nullptr, CHIP_ERROR_NO_MEMORY);
Expand All @@ -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();
Expand Down

0 comments on commit 2d77094

Please sign in to comment.