Skip to content

Commit

Permalink
Lock the stack and use the same working thread to set/get attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
MtTsai authored and JohnWangCH committed Jan 12, 2024
1 parent 16ef002 commit fa46625
Showing 1 changed file with 50 additions and 7 deletions.
57 changes: 50 additions & 7 deletions examples/common/pigweed/rpc_services/Attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,30 @@
#include <lib/core/TLVTags.h>
#include <lib/core/TLVTypes.h>
#include <platform/PlatformManager.h>
#include <future>

namespace chip {
namespace rpc {

struct WriteArgs {
std::promise<EmberAfStatus> *promise;
const chip_rpc_AttributeWrite *request;
const void *data;
};

struct ReadArgs {
std::promise<CHIP_ERROR> *promise;
const app::ConcreteAttributePath *path;
app::AttributeReportIBs::Builder *attributeReports;
};

// Implementation class for chip.rpc.Attributes.
class Attributes : public pw_rpc::nanopb::Attributes::Service<Attributes>
{
public:
::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:
Expand Down Expand Up @@ -70,9 +81,28 @@ class Attributes : public pw_rpc::nanopb::Attributes::Service<Attributes>
default:
return pw::Status::InvalidArgument();
}
RETURN_STATUS_IF_NOT_OK(
emberAfWriteAttribute(request.metadata.endpoint, request.metadata.cluster, request.metadata.attribute_id,
const_cast<uint8_t *>(static_cast<const uint8_t *>(data)), request.metadata.type));

std::promise<EmberAfStatus> writeStatusPromise;
WriteArgs writeArgs = {
.promise = &writeStatusPromise,
.request = &request,
.data = data,
};
chip::DeviceLayer::PlatformMgr().ScheduleWork([](intptr_t ctx) {
DeviceLayer::StackLock lock;

WriteArgs *args = reinterpret_cast<WriteArgs*>(ctx);
args->promise->set_value(
emberAfWriteAttribute(
args->request->metadata.endpoint,
args->request->metadata.cluster,
args->request->metadata.attribute_id,
const_cast<uint8_t *>(static_cast<const uint8_t *>(args->data)),
args->request->metadata.type));
}, reinterpret_cast<intptr_t>(&writeArgs));

RETURN_STATUS_IF_NOT_OK(writeStatusPromise.get_future().get());

return pw::OkStatus();
}

Expand Down Expand Up @@ -190,7 +220,6 @@ class Attributes : public pw_rpc::nanopb::Attributes::Service<Attributes>

::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;
Expand All @@ -199,7 +228,21 @@ class Attributes : public pw_rpc::nanopb::Attributes::Service<Attributes>
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<CHIP_ERROR> 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<ReadArgs*>(ctx);
args->promise->set_value(app::ReadSingleClusterData(subjectDescriptor, false, *(args->path), *(args->attributeReports), nullptr));
}, reinterpret_cast<intptr_t>(&readArgs));

PW_TRY(ChipErrorToPwStatus(readStatusPromise.get_future().get()));

attributeReports.EndOfContainer();
PW_TRY(ChipErrorToPwStatus(writer.EndContainer(outer)));
PW_TRY(ChipErrorToPwStatus(writer.Finalize()));
Expand Down

0 comments on commit fa46625

Please sign in to comment.