From fa46625296f61a86b1328c8607ce56bfe1f3b177 Mon Sep 17 00:00:00 2001 From: MtTsai <7930801+MtTsai@users.noreply.github.com> Date: Sat, 7 Jan 2023 16:02:05 +0800 Subject: [PATCH] Lock the stack and use the same working thread to set/get attributes --- .../common/pigweed/rpc_services/Attributes.h | 57 ++++++++++++++++--- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/examples/common/pigweed/rpc_services/Attributes.h b/examples/common/pigweed/rpc_services/Attributes.h index 223ec3336f25bb..9fcf77a331fd9b 100644 --- a/examples/common/pigweed/rpc_services/Attributes.h +++ b/examples/common/pigweed/rpc_services/Attributes.h @@ -28,10 +28,23 @@ #include #include #include +#include namespace chip { namespace rpc { +struct WriteArgs { + std::promise *promise; + const chip_rpc_AttributeWrite *request; + const void *data; +}; + +struct ReadArgs { + std::promise *promise; + const app::ConcreteAttributePath *path; + app::AttributeReportIBs::Builder *attributeReports; +}; + // Implementation class for chip.rpc.Attributes. class Attributes : public pw_rpc::nanopb::Attributes::Service { @@ -39,8 +52,6 @@ class Attributes : public pw_rpc::nanopb::Attributes::Service ::pw::Status Write(const chip_rpc_AttributeWrite & request, pw_protobuf_Empty & response) { const void * data; - DeviceLayer::StackLock lock; - switch (request.data.which_data) { case chip_rpc_AttributeData_data_bool_tag: @@ -70,9 +81,28 @@ class Attributes : public pw_rpc::nanopb::Attributes::Service default: return pw::Status::InvalidArgument(); } - RETURN_STATUS_IF_NOT_OK( - emberAfWriteAttribute(request.metadata.endpoint, request.metadata.cluster, request.metadata.attribute_id, - const_cast(static_cast(data)), request.metadata.type)); + + std::promise writeStatusPromise; + WriteArgs writeArgs = { + .promise = &writeStatusPromise, + .request = &request, + .data = data, + }; + chip::DeviceLayer::PlatformMgr().ScheduleWork([](intptr_t ctx) { + DeviceLayer::StackLock lock; + + WriteArgs *args = reinterpret_cast(ctx); + args->promise->set_value( + emberAfWriteAttribute( + args->request->metadata.endpoint, + args->request->metadata.cluster, + args->request->metadata.attribute_id, + const_cast(static_cast(args->data)), + args->request->metadata.type)); + }, reinterpret_cast(&writeArgs)); + + RETURN_STATUS_IF_NOT_OK(writeStatusPromise.get_future().get()); + return pw::OkStatus(); } @@ -190,7 +220,6 @@ class Attributes : public pw_rpc::nanopb::Attributes::Service ::pw::Status ReadAttributeIntoTlvBuffer(const app::ConcreteAttributePath & path, MutableByteSpan & tlvBuffer) { - Access::SubjectDescriptor subjectDescriptor{ .authMode = chip::Access::AuthMode::kPase }; app::AttributeReportIBs::Builder attributeReports; TLV::TLVWriter writer; TLV::TLVType outer; @@ -199,7 +228,21 @@ class Attributes : public pw_rpc::nanopb::Attributes::Service writer.Init(tlvBuffer); PW_TRY(ChipErrorToPwStatus(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outer))); PW_TRY(ChipErrorToPwStatus(attributeReports.Init(&writer, kReportContextTag))); - PW_TRY(ChipErrorToPwStatus(app::ReadSingleClusterData(subjectDescriptor, false, path, attributeReports, nullptr))); + + std::promise readStatusPromise; + ReadArgs readArgs = { + .promise = &readStatusPromise, + .path = &path, + .attributeReports = &attributeReports, + }; + chip::DeviceLayer::PlatformMgr().ScheduleWork([](intptr_t ctx) { + Access::SubjectDescriptor subjectDescriptor{ .authMode = chip::Access::AuthMode::kPase }; + ReadArgs *args = reinterpret_cast(ctx); + args->promise->set_value(app::ReadSingleClusterData(subjectDescriptor, false, *(args->path), *(args->attributeReports), nullptr)); + }, reinterpret_cast(&readArgs)); + + PW_TRY(ChipErrorToPwStatus(readStatusPromise.get_future().get())); + attributeReports.EndOfContainer(); PW_TRY(ChipErrorToPwStatus(writer.EndContainer(outer))); PW_TRY(ChipErrorToPwStatus(writer.Finalize()));