Skip to content

Commit

Permalink
fabric scoped event support (#13907)
Browse files Browse the repository at this point in the history
  • Loading branch information
yunhanw-google authored and pull[bot] committed Sep 2, 2023
1 parent 3335cf4 commit 1325960
Show file tree
Hide file tree
Showing 27 changed files with 577 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2620,6 +2620,10 @@ server cluster TestCluster = 1295 {
SimpleEnum arg6[] = 6;
}

info event TestFabricScopedEvent = 2 {
fabric_idx arg1 = 1;
}

attribute boolean boolean = 0;
attribute bitmap8 bitmap8 = 1;
attribute bitmap16 bitmap16 = 2;
Expand Down Expand Up @@ -2717,6 +2721,10 @@ server cluster TestCluster = 1295 {
BOOLEAN arg3 = 2;
}

request struct TestEmitTestFabricScopedEventRequestRequest {
INT8U arg1 = 0;
}

request struct TestEnumsRequestRequest {
vendor_id arg1 = 0;
SimpleEnum arg2 = 1;
Expand Down Expand Up @@ -2770,6 +2778,10 @@ server cluster TestCluster = 1295 {
INT64U value = 0;
}

response struct TestEmitTestFabricScopedEventResponse {
INT64U value = 0;
}

response struct TestEnumsResponse {
vendor_id arg1 = 0;
SimpleEnum arg2 = 1;
Expand All @@ -2794,6 +2806,7 @@ server cluster TestCluster = 1295 {
command Test(): DefaultSuccess = 0;
command TestAddArguments(TestAddArgumentsRequest): TestAddArgumentsResponse = 4;
command TestEmitTestEventRequest(TestEmitTestEventRequestRequest): TestEmitTestEventResponse = 20;
command TestEmitTestFabricScopedEventRequest(TestEmitTestFabricScopedEventRequestRequest): TestEmitTestFabricScopedEventResponse = 21;
command TestEnumsRequest(TestEnumsRequestRequest): TestEnumsResponse = 14;
command TestListInt8UArgumentRequest(TestListInt8UArgumentRequestRequest): BooleanResponse = 10;
command TestListInt8UReverseRequest(TestListInt8UReverseRequestRequest): TestListInt8UReverseResponse = 13;
Expand Down
16 changes: 16 additions & 0 deletions examples/all-clusters-app/all-clusters-common/all-clusters-app.zap
Original file line number Diff line number Diff line change
Expand Up @@ -15854,6 +15854,14 @@
"source": "client",
"incoming": 1,
"outgoing": 0
},
{
"name": "TestEmitTestFabricScopedEventRequest",
"code": 21,
"mfgCode": null,
"source": "client",
"incoming": 1,
"outgoing": 0
}
],
"attributes": [
Expand Down Expand Up @@ -15937,6 +15945,14 @@
"source": "server",
"incoming": 0,
"outgoing": 1
},
{
"name": "TestEmitTestFabricScopedEventResponse",
"code": 11,
"mfgCode": null,
"source": "server",
"incoming": 0,
"outgoing": 1
}
],
"attributes": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2169,6 +2169,10 @@ server cluster TestCluster = 1295 {
SimpleEnum arg6[] = 6;
}

info event TestFabricScopedEvent = 2 {
fabric_idx arg1 = 1;
}

attribute boolean boolean = 0;
attribute bitmap8 bitmap8 = 1;
attribute bitmap16 bitmap16 = 2;
Expand Down
21 changes: 19 additions & 2 deletions src/app/EventLogging.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <app/EventLoggingDelegate.h>
#include <app/EventManagement.h>
#include <app/data-model/Encode.h>
#include <app/data-model/FabricScoped.h>
#include <app/data-model/List.h> // So we can encode lists

namespace chip {
Expand Down Expand Up @@ -53,15 +54,31 @@ class EventLogger : public EventLoggingDelegate
* context tags to be interpreted within the schema identified by
* `ClusterID` and `EventId`.
*
* @param[in] apDelegate The EventLoggingDelegate to serialize the event data
* LogEvent has 2 variant, one for fabric-scoped events and one for non-fabric-scoped events.
* @param[in] aEventData The event cluster object
* @param[in] aEndpoint The current cluster's Endpoint Id
* @param[in] aUrgent The EventOption Type, kUrgent or kNotUrgent
* @param[out] aEventNumber The event Number if the event was written to the
* log, 0 otherwise. The Event number is expected to monotonically increase.
*
* @return CHIP_ERROR CHIP Error Code
*/
template <typename T>
template <typename T, std::enable_if_t<DataModel::IsFabricScoped<T>::value, bool> = true>
CHIP_ERROR LogEvent(const T & aEventData, EndpointId aEndpoint, EventNumber & aEventNumber,
EventOptions::Type aUrgent = EventOptions::Type::kNotUrgent)
{
EventLogger<T> eventData(aEventData);
ConcreteEventPath path(aEndpoint, aEventData.GetClusterId(), aEventData.GetEventId());
EventManagement & logMgmt = chip::app::EventManagement::GetInstance();
EventOptions eventOptions;
eventOptions.mUrgent = aUrgent;
eventOptions.mPath = path;
eventOptions.mPriority = aEventData.GetPriorityLevel();
eventOptions.mFabricIndex = aEventData.GetFabricIndex();
return logMgmt.LogEvent(&eventData, eventOptions, aEventNumber);
}

template <typename T, std::enable_if_t<!DataModel::IsFabricScoped<T>::value, bool> = true>
CHIP_ERROR LogEvent(const T & aEventData, EndpointId aEndpoint, EventNumber & aEventNumber,
EventOptions::Type aUrgent = EventOptions::Type::kNotUrgent)
{
Expand Down
7 changes: 6 additions & 1 deletion src/app/EventLoggingTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <app/util/basic-types.h>
#include <lib/core/CHIPCore.h>
#include <lib/core/CHIPTLV.h>
#include <lib/core/Optional.h>
#include <system/SystemPacketBuffer.h>

constexpr size_t kNumPriorityLevel = 3;
Expand Down Expand Up @@ -140,6 +141,8 @@ class EventOptions
PriorityLevel mPriority = PriorityLevel::Invalid;
Type mUrgent = Type::kNotUrgent; /**< A flag denoting if the event is time sensitive. When kUrgent is set, it causes
the event log to be flushed. */
// kUndefinedFabricIndex 0 means not fabric associated at all
FabricIndex mFabricIndex = kUndefinedFabricIndex;
};

/**
Expand All @@ -149,7 +152,8 @@ class EventOptions
struct EventLoadOutContext
{
EventLoadOutContext(TLV::TLVWriter & aWriter, PriorityLevel aPriority, EventNumber aStartingEventNumber) :
mWriter(aWriter), mPriority(aPriority), mStartingEventNumber(aStartingEventNumber), mCurrentEventNumber(0), mFirst(true)
mWriter(aWriter), mPriority(aPriority), mStartingEventNumber(aStartingEventNumber), mCurrentEventNumber(0), mFirst(true),
mFabricIndex(0)
{}

TLV::TLVWriter & mWriter;
Expand All @@ -161,6 +165,7 @@ struct EventLoadOutContext
size_t mEventCount = 0;
ClusterInfo * mpInterestedEventPaths = nullptr;
bool mFirst = true;
FabricIndex mFabricIndex = kUndefinedFabricIndex;
};
} // namespace app
} // namespace chip
46 changes: 35 additions & 11 deletions src/app/EventManagement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ struct EventEnvelopeContext
EndpointId mEndpointId = 0;
EventId mEventId = 0;
EventNumber mEventNumber = 0;
FabricIndex mFabricIndex = kUndefinedFabricIndex;
};

void EventManagement::InitializeCounter(Platform::PersistedStorage::Key * apCounterKey, uint32_t aCounterEpoch,
Expand Down Expand Up @@ -359,6 +360,13 @@ CHIP_ERROR EventManagement::ConstructEvent(EventLoadOutContext * apContext, Even

// Callback to write the EventData
ReturnErrorOnFailure(apDelegate->WriteEvent(apContext->mWriter));

// The fabricIndex profile tag is internal use only for fabric filtering when retrieving event from circular event buffer,
// and would not go on the wire.
if (apOptions->mFabricIndex != kUndefinedFabricIndex)
{
apContext->mWriter.Put(TLV::ProfileTag(kEventManagementProfile, kFabricIndexTag), apOptions->mFabricIndex);
}
eventDataIBBuilder.EndOfEventDataIB();
ReturnErrorOnFailure(eventDataIBBuilder.GetError());
eventReportBuilder.EndOfEventReportIB();
Expand Down Expand Up @@ -406,25 +414,28 @@ CircularEventBuffer * EventManagement::GetPriorityBuffer(PriorityLevel aPriority

CHIP_ERROR EventManagement::CopyAndAdjustDeltaTime(const TLVReader & aReader, size_t aDepth, void * apContext)
{
CHIP_ERROR err = CHIP_NO_ERROR;
CopyAndAdjustDeltaTimeContext * ctx = static_cast<CopyAndAdjustDeltaTimeContext *>(apContext);
TLVReader reader(aReader);

if ((aReader.GetTag() == TLV::ContextTag(to_underlying(EventDataIB::Tag::kSystemTimestamp))) && !(ctx->mpContext->mFirst))
if (aReader.GetTag() == TLV::ProfileTag(kEventManagementProfile, kFabricIndexTag))
{
// Does not go on the wire.
return CHIP_NO_ERROR;
}
else if ((aReader.GetTag() == TLV::ContextTag(to_underlying(EventDataIB::Tag::kSystemTimestamp))) && !(ctx->mpContext->mFirst))
{
err = ctx->mpWriter->Put(TLV::ContextTag(to_underlying(EventDataIB::Tag::kDeltaSystemTimestamp)),
ctx->mpContext->mCurrentTime.mValue - ctx->mpContext->mPreviousTime.mValue);
return ctx->mpWriter->Put(TLV::ContextTag(to_underlying(EventDataIB::Tag::kDeltaSystemTimestamp)),
ctx->mpContext->mCurrentTime.mValue - ctx->mpContext->mPreviousTime.mValue);
}
else if ((aReader.GetTag() == TLV::ContextTag(to_underlying(EventDataIB::Tag::kEpochTimestamp))) && !(ctx->mpContext->mFirst))
{
err = ctx->mpWriter->Put(TLV::ContextTag(to_underlying(EventDataIB::Tag::kDeltaEpochTimestamp)),
ctx->mpContext->mCurrentTime.mValue - ctx->mpContext->mPreviousTime.mValue);
return ctx->mpWriter->Put(TLV::ContextTag(to_underlying(EventDataIB::Tag::kDeltaEpochTimestamp)),
ctx->mpContext->mCurrentTime.mValue - ctx->mpContext->mPreviousTime.mValue);
}
else
{
err = ctx->mpWriter->CopyElement(reader);
return ctx->mpWriter->CopyElement(reader);
}
return err;
}

void EventManagement::VendEventNumber()
Expand Down Expand Up @@ -487,8 +498,9 @@ CHIP_ERROR EventManagement::LogEventPrivate(EventLoggingDelegate * apDelegate, c
// Create all event specific data
// Timestamp; encoded as a delta time

opts.mUrgent = aEventOptions.mUrgent;
opts.mPath = aEventOptions.mPath;
opts.mUrgent = aEventOptions.mUrgent;
opts.mPath = aEventOptions.mPath;
opts.mFabricIndex = aEventOptions.mFabricIndex;

ctxt.mCurrentEventNumber = mLastEventNumber;
ctxt.mCurrentTime.mValue = mLastEventTimestamp.mValue;
Expand Down Expand Up @@ -584,6 +596,12 @@ static bool IsInterestedEventPaths(EventLoadOutContext * eventLoadOutContext, co
{
return false;
}

if (event.mFabricIndex != kUndefinedFabricIndex && eventLoadOutContext->mFabricIndex != event.mFabricIndex)
{
return false;
}

ConcreteEventPath path(event.mEndpointId, event.mClusterId, event.mEventId);
for (auto * interestedPath = eventLoadOutContext->mpInterestedEventPaths; interestedPath != nullptr;
interestedPath = interestedPath->mpNext)
Expand Down Expand Up @@ -661,7 +679,7 @@ CHIP_ERROR EventManagement::CopyEventsSince(const TLVReader & aReader, size_t aD
}

CHIP_ERROR EventManagement::FetchEventsSince(TLVWriter & aWriter, ClusterInfo * apClusterInfolist, EventNumber & aEventMin,
size_t & aEventCount)
size_t & aEventCount, FabricIndex aFabricIndex)
{
// TODO: Add particular set of event Paths in FetchEventsSince so that we can filter the interested paths
CHIP_ERROR err = CHIP_NO_ERROR;
Expand All @@ -674,6 +692,7 @@ CHIP_ERROR EventManagement::FetchEventsSince(TLVWriter & aWriter, ClusterInfo *
ScopedLock lock(sInstance);
#endif // !CHIP_SYSTEM_CONFIG_NO_LOCKING

context.mFabricIndex = aFabricIndex;
context.mpInterestedEventPaths = apClusterInfolist;
err = GetEventReader(reader, PriorityLevel::Critical, &bufWrapper);
SuccessOrExit(err);
Expand Down Expand Up @@ -747,6 +766,11 @@ CHIP_ERROR EventManagement::FetchEventParameters(const TLVReader & aReader, size
envelope->mCurrentTime.mType = Timestamp::Type::kEpoch;
envelope->mCurrentTime.mValue = epochTime;
}

if (reader.GetTag() == TLV::ProfileTag(kEventManagementProfile, kFabricIndexTag))
{
ReturnErrorOnFailure(reader.Get(envelope->mFabricIndex));
}
return CHIP_NO_ERROR;
}

Expand Down
7 changes: 5 additions & 2 deletions src/app/EventManagement.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@

namespace chip {
namespace app {
constexpr size_t kMaxEventSizeReserve = 512;
constexpr const uint32_t kEventManagementProfile = 0x1;
constexpr const uint32_t kFabricIndexTag = 0x1;
constexpr size_t kMaxEventSizeReserve = 512;
constexpr uint16_t kRequiredEventField =
(1 << to_underlying(EventDataIB::Tag::kPriority)) | (1 << to_underlying(EventDataIB::Tag::kPath));

Expand Down Expand Up @@ -322,6 +324,7 @@ class EventManagement
* completion, the event number of the next one we plan to fetch.
*
* @param[out] aEventCount The number of fetched event
* @param[in] aFabricIndex fabric index for current read handler
* @retval #CHIP_END_OF_TLV The function has reached the end of the
* available log entries at the specified
* priority level
Expand All @@ -336,7 +339,7 @@ class EventManagement
*
*/
CHIP_ERROR FetchEventsSince(chip::TLV::TLVWriter & aWriter, ClusterInfo * apClusterInfolist, EventNumber & aEventMin,
size_t & aEventCount);
size_t & aEventCount, FabricIndex aFabricIndex);

/**
* @brief
Expand Down
17 changes: 17 additions & 0 deletions src/app/clusters/test-cluster-server/test-cluster-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,7 @@ bool emberAfTestClusterClusterTestListStructArgumentRequestCallback(

return SendBooleanResponse(commandObj, commandPath, shouldReturnTrue);
}

bool emberAfTestClusterClusterTestEmitTestEventRequestCallback(
CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
const Commands::TestEmitTestEventRequest::DecodableType & commandData)
Expand All @@ -586,6 +587,22 @@ bool emberAfTestClusterClusterTestEmitTestEventRequestCallback(
return true;
}

bool emberAfTestClusterClusterTestEmitTestFabricScopedEventRequestCallback(
CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
const Commands::TestEmitTestFabricScopedEventRequest::DecodableType & commandData)
{
Commands::TestEmitTestFabricScopedEventResponse::Type responseData;
Events::TestFabricScopedEvent::Type event{ commandData.arg1 };

if (CHIP_NO_ERROR != LogEvent(event, commandPath.mEndpointId, responseData.value))
{
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_FAILURE);
return true;
}
commandObj->AddResponseData(commandPath, responseData);
return true;
}

bool emberAfTestClusterClusterTestListInt8UArgumentRequestCallback(
CommandHandler * commandObj, ConcreteCommandPath const & commandPath,
Commands::TestListInt8UArgumentRequest::DecodableType const & commandData)
Expand Down
3 changes: 2 additions & 1 deletion src/app/reporting/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,8 @@ CHIP_ERROR Engine::BuildSingleReportDataEventReports(ReportDataMessage::Builder
{
EventReportIBs::Builder & eventReportIBs = aReportDataBuilder.CreateEventReports();
SuccessOrExit(err = aReportDataBuilder.GetError());
err = eventManager.FetchEventsSince(*(eventReportIBs.GetWriter()), clusterInfoList, eventMin, eventCount);
err = eventManager.FetchEventsSince(*(eventReportIBs.GetWriter()), clusterInfoList, eventMin, eventCount,
apReadHandler->GetAccessingFabricIndex());

if ((err == CHIP_END_OF_TLV) || (err == CHIP_ERROR_TLV_UNDERRUN) || (err == CHIP_NO_ERROR))
{
Expand Down
2 changes: 1 addition & 1 deletion src/app/tests/TestEventLogging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ static void CheckLogReadOut(nlTestSuite * apSuite, chip::app::EventManagement &
uint8_t backingStore[1024];
size_t totalNumElements;
writer.Init(backingStore, 1024);
err = alogMgmt.FetchEventsSince(writer, clusterInfo, startingEventNumber, eventCount);
err = alogMgmt.FetchEventsSince(writer, clusterInfo, startingEventNumber, eventCount, 0);
NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR || err == CHIP_END_OF_TLV);

reader.Init(backingStore, writer.GetLengthWritten());
Expand Down
8 changes: 8 additions & 0 deletions src/app/zap-templates/templates/app/cluster-objects.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,14 @@ public:
{{zapTypeToEncodableClusterObjectType type}} {{asLowerCamelCase name}}{{> cluster_objects_field_init}};
{{/zcl_event_fields}}

{{#if event_is_fabric_scoped}}
{{#unless event_is_fabric_index_nullable}}
auto GetFabricIndex() const {
return {{ asLowerCamelCase event_fabric_idx_field }};
}
{{/unless}}
{{/if}}

CHIP_ERROR Encode(TLV::TLVWriter &writer, TLV::Tag tag) const;
};

Expand Down
Loading

0 comments on commit 1325960

Please sign in to comment.