Skip to content

Commit

Permalink
Integrate IM event with server (#12641)
Browse files Browse the repository at this point in the history
* Port change from #12059

* Hook server with IM EventManagment and adjust EventManagment

* run codegen
  • Loading branch information
yunhanw-google authored Dec 7, 2021
1 parent fcd9785 commit 6f89b9b
Show file tree
Hide file tree
Showing 39 changed files with 868 additions and 231 deletions.
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 @@ -15442,6 +15442,14 @@
"incoming": 1,
"outgoing": 0
},
{
"name": "TestEmitTestEventRequest",
"code": 20,
"mfgCode": null,
"source": "client",
"incoming": 1,
"outgoing": 0
},
{
"name": "TestSimpleOptionalArgumentRequest",
"code": 19,
Expand Down Expand Up @@ -15524,6 +15532,14 @@
"source": "server",
"incoming": 0,
"outgoing": 1
},
{
"name": "TestEmitTestEventResponse",
"code": 10,
"mfgCode": null,
"source": "server",
"incoming": 0,
"outgoing": 1
}
],
"attributes": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,6 @@
*/
#define CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD 1

/**
* CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE
*
* A size, in bytes, of the individual debug event logging buffer.
*/
#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512)

/**
* CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_TIMEOUT
*
Expand Down
7 changes: 0 additions & 7 deletions examples/lock-app/nxp/k32w/k32w0/include/CHIPProjectConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,6 @@
*/
#define CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD 1

/**
* CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE
*
* A size, in bytes, of the individual debug event logging buffer.
*/
#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512)

/**
* CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_TIMEOUT
*
Expand Down
6 changes: 3 additions & 3 deletions examples/shell/nxp/k32w/k32w0/include/CHIPProjectConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@
#define CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD 1

/**
* CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE
* @def CHIP_CONFIG_ENABLE_SERVER_IM_EVENT
*
* A size, in bytes, of the individual debug event logging buffer.
* @brief Enable Interaction model Event support in server
*/
#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512)
#define CHIP_CONFIG_ENABLE_SERVER_IM_EVENT 0

/**
* CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_TIMEOUT
Expand Down
77 changes: 77 additions & 0 deletions src/app/EventLogging.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
*
* Copyright (c) 2021 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <app/ConcreteEventPath.h>
#include <app/EventLoggingDelegate.h>
#include <app/EventManagement.h>
#include <app/data-model/Encode.h>
#include <app/data-model/List.h> // So we can encode lists

namespace chip {
namespace app {

template <typename T>
class EventLogger : public EventLoggingDelegate
{
public:
EventLogger(const T & aEventData) : mEventData(aEventData){};
CHIP_ERROR WriteEvent(chip::TLV::TLVWriter & aWriter) final override
{
return DataModel::Encode(aWriter, TLV::ContextTag(to_underlying(EventDataIB::Tag::kData)), mEventData);
}

private:
const T & mEventData;
};

/**
* @brief
* Log an event via a EventLoggingDelegate, with options.
*
* The EventLoggingDelegate writes the event metadata and calls the `apDelegate`
* with an TLV::TLVWriter reference so that the user code can emit
* the event data directly into the event log. This form of event
* logging minimizes memory consumption, as event data is serialized
* directly into the target buffer. The event data MUST contain
* context tags to be interpreted within the schema identified by
* `ClusterID` and `EventId`.
*
* @param[in] apDelegate The EventLoggingDelegate to serialize the event data
*
* @param[in] aEventOptions The options for the event metadata.
*
* @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>
CHIP_ERROR LogEvent(const T & aEventData, EndpointId aEndpoint, EventOptions aEventOptions, EventNumber & aEventNumber)
{
EventLogger<T> eventData(aEventData);
ConcreteEventPath path(aEndpoint, aEventData.GetClusterId(), aEventData.GetEventId());
EventManagement & logMgmt = chip::app::EventManagement::GetInstance();
aEventOptions.mPath = path;
aEventOptions.mPriority = aEventData.GetPriorityLevel();
return logMgmt.LogEvent(&eventData, aEventOptions, aEventNumber);
}

} // namespace app
} // namespace chip
21 changes: 6 additions & 15 deletions src/app/EventManagement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,9 +309,7 @@ CHIP_ERROR EventManagement::CalculateEventSize(EventLoggingDelegate * apDelegate
CHIP_ERROR EventManagement::ConstructEvent(EventLoadOutContext * apContext, EventLoggingDelegate * apDelegate,
const EventOptions * apOptions)
{
TLV::TLVType dataContainerType;
uint64_t deltatime = 0;

VerifyOrReturnError(apContext->mCurrentEventNumber >= apContext->mStartingEventNumber, CHIP_NO_ERROR
/* no-op: don't write event, but advance current event Number */);

Expand Down Expand Up @@ -347,11 +345,8 @@ CHIP_ERROR EventManagement::ConstructEvent(EventLoadOutContext * apContext, Even

ReturnErrorOnFailure(eventDataIBBuilder.GetError());

ReturnErrorOnFailure(apContext->mWriter.StartContainer(ContextTag(chip::to_underlying(EventDataIB::Tag::kData)),
TLV::kTLVType_Structure, dataContainerType));
// Callback to write the EventData
ReturnErrorOnFailure(apDelegate->WriteEvent(apContext->mWriter));
ReturnErrorOnFailure(apContext->mWriter.EndContainer(dataContainerType));
eventDataIBBuilder.EndOfEventDataIB();
ReturnErrorOnFailure(eventDataIBBuilder.GetError());
eventReportBuilder.EndOfEventReportIB();
Expand Down Expand Up @@ -512,16 +507,13 @@ CHIP_ERROR EventManagement::LogEventPrivate(EventLoggingDelegate * apDelegate, E
opts = EventOptions(timestamp);
// Start the event container (anonymous structure) in the circular buffer
writer.Init(*mpEventBuffer);

// check whether the entry is to be logged or discarded silently
VerifyOrExit(aEventOptions.mPriority >= CHIP_CONFIG_EVENT_GLOBAL_PRIORITY, /* no-op */);

opts.mPriority = aEventOptions.mPriority;
// Create all event specific data
// Timestamp; encoded as a delta time

opts.mTimestamp = aEventOptions.mTimestamp;

if (GetPriorityBuffer(aEventOptions.mPriority)->GetFirstEventTimestamp() == 0)
{
GetPriorityBuffer(aEventOptions.mPriority)->UpdateFirstLastEventTime(opts.mTimestamp);
Expand Down Expand Up @@ -576,17 +568,16 @@ CHIP_ERROR EventManagement::LogEventPrivate(EventLoggingDelegate * apDelegate, E

#if CHIP_CONFIG_EVENT_LOGGING_VERBOSE_DEBUG_LOGS
ChipLogDetail(EventLogging,
"LogEvent event number: 0x" ChipLogFormatX64 " schema priority: %u cluster id: " ChipLogFormatMEI
" event id: 0x%" PRIx32 " %s timestamp: 0x" ChipLogFormatX64,
ChipLogValueX64(aEventNumber), static_cast<unsigned>(opts.mPriority), ChipLogValueMEI(opts.mPath.mClusterId),
opts.mPath.mEventId, opts.mTimestamp.mType == Timestamp::Type::kSystem ? "Sys" : "Epoch",
ChipLogValueX64(opts.mTimestamp.mValue));
"LogEvent event number: 0x" ChipLogFormatX64 " schema priority: %u, endpoint id: 0x%" PRIx16
" cluster id: " ChipLogFormatMEI " event id: 0x%" PRIx32 " %s timestamp: 0x" ChipLogFormatX64,
ChipLogValueX64(aEventNumber), static_cast<unsigned>(opts.mPriority), opts.mPath.mEndpointId,
ChipLogValueMEI(opts.mPath.mClusterId), opts.mPath.mEventId,
opts.mTimestamp.mType == Timestamp::Type::kSystem ? "Sys" : "Epoch", ChipLogValueX64(opts.mTimestamp.mValue));
#endif // CHIP_CONFIG_EVENT_LOGGING_VERBOSE_DEBUG_LOGS

if (opts.mUrgent == EventOptions::Type::kUrgent)
{
ConcreteEventPath path(opts.mPath.mEndpointId, opts.mPath.mClusterId, opts.mPath.mEventId);
err = InteractionModelEngine::GetInstance()->GetReportingEngine().ScheduleUrgentEventDelivery(path);
err = InteractionModelEngine::GetInstance()->GetReportingEngine().ScheduleUrgentEventDelivery(opts.mPath);
}
}

Expand Down
24 changes: 23 additions & 1 deletion src/app/clusters/test-cluster-server/test-cluster-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <app/AttributeAccessInterface.h>
#include <app/CommandHandler.h>
#include <app/ConcreteCommandPath.h>
#include <app/EventLogging.h>
#include <app/util/attribute-storage.h>
#include <lib/core/CHIPSafeCasts.h>
#include <lib/core/CHIPTLV.h>
Expand Down Expand Up @@ -443,9 +444,30 @@ bool emberAfTestClusterClusterTestListStructArgumentRequestCallback(

return SendBooleanResponse(commandObj, commandPath, shouldReturnTrue);
}
bool emberAfTestClusterClusterTestEmitTestEventRequestCallback(
CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
const Commands::TestEmitTestEventRequest::DecodableType & commandData)
{
Commands::TestEmitTestEventResponse::Type responseData;
Structs::SimpleStruct::Type arg4;
DataModel::List<const Structs::SimpleStruct::Type> arg5;
DataModel::List<const SimpleEnum> arg6;
EventOptions eventOptions;

// TODO: Add code to pull arg4, arg5 and arg6 from the arguments of the command
Events::TestEvent::Type event{ commandData.arg1, commandData.arg2, commandData.arg3, arg4, arg5, arg6 };

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

bool emberAfTestClusterClusterTestListInt8UArgumentRequestCallback(
app::CommandHandler * commandObj, app::ConcreteCommandPath const & commandPath,
CommandHandler * commandObj, ConcreteCommandPath const & commandPath,
Commands::TestListInt8UArgumentRequest::DecodableType const & commandData)
{
bool shouldReturnTrue = true;
Expand Down
33 changes: 33 additions & 0 deletions src/app/server/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include <app/server/Server.h>

#include <app/EventManagement.h>
#include <app/InteractionModelEngine.h>
#include <app/server/Dnssd.h>
#include <app/server/EchoHandler.h>
Expand Down Expand Up @@ -70,6 +71,17 @@ namespace chip {

Server Server::sServer;

#if CHIP_CONFIG_ENABLE_SERVER_IM_EVENT
#define CHIP_NUM_EVENT_LOGGING_BUFFERS 3
static uint8_t sInfoEventBuffer[CHIP_DEVICE_CONFIG_EVENT_LOGGING_INFO_BUFFER_SIZE];
static uint8_t sDebugEventBuffer[CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE];
static uint8_t sCritEventBuffer[CHIP_DEVICE_CONFIG_EVENT_LOGGING_CRIT_BUFFER_SIZE];
static ::chip::PersistedCounter sCritEventIdCounter;
static ::chip::PersistedCounter sInfoEventIdCounter;
static ::chip::PersistedCounter sDebugEventIdCounter;
static ::chip::app::CircularEventBuffer sLoggingBuffer[CHIP_NUM_EVENT_LOGGING_BUFFERS];
#endif // CHIP_CONFIG_ENABLE_SERVER_IM_EVENT

CHIP_ERROR Server::Init(AppDelegate * delegate, uint16_t secureServicePort, uint16_t unsecureServicePort)
{
mSecuredServicePort = secureServicePort;
Expand Down Expand Up @@ -138,6 +150,27 @@ CHIP_ERROR Server::Init(AppDelegate * delegate, uint16_t secureServicePort, uint
err = chip::app::InteractionModelEngine::GetInstance()->Init(&mExchangeMgr, nullptr);
SuccessOrExit(err);

#if CHIP_CONFIG_ENABLE_SERVER_IM_EVENT
// Initialize event logging subsystem
{
::chip::Platform::PersistedStorage::Key debugEventIdCounterStorageKey = CHIP_DEVICE_CONFIG_PERSISTED_STORAGE_DEBUG_EIDC_KEY;
::chip::Platform::PersistedStorage::Key critEventIdCounterStorageKey = CHIP_DEVICE_CONFIG_PERSISTED_STORAGE_CRIT_EIDC_KEY;
::chip::Platform::PersistedStorage::Key infoEventIdCounterStorageKey = CHIP_DEVICE_CONFIG_PERSISTED_STORAGE_INFO_EIDC_KEY;

::chip::app::LogStorageResources logStorageResources[] = {
{ &sDebugEventBuffer[0], sizeof(sDebugEventBuffer), &debugEventIdCounterStorageKey,
CHIP_DEVICE_CONFIG_EVENT_ID_COUNTER_EPOCH, &sDebugEventIdCounter, ::chip::app::PriorityLevel::Debug },
{ &sInfoEventBuffer[0], sizeof(sInfoEventBuffer), &infoEventIdCounterStorageKey,
CHIP_DEVICE_CONFIG_EVENT_ID_COUNTER_EPOCH, &sInfoEventIdCounter, ::chip::app::PriorityLevel::Info },
{ &sCritEventBuffer[0], sizeof(sCritEventBuffer), &critEventIdCounterStorageKey,
CHIP_DEVICE_CONFIG_EVENT_ID_COUNTER_EPOCH, &sCritEventIdCounter, ::chip::app::PriorityLevel::Critical }
};

chip::app::EventManagement::GetInstance().Init(&mExchangeMgr, CHIP_NUM_EVENT_LOGGING_BUFFERS, &sLoggingBuffer[0],
&logStorageResources[0]);
}
#endif // CHIP_CONFIG_ENABLE_SERVER_IM_EVENT

#if defined(CHIP_APP_USE_ECHO)
err = InitEchoHandler(&gExchangeMgr);
SuccessOrExit(err);
Expand Down
8 changes: 5 additions & 3 deletions src/app/tests/TestEventLogging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,11 @@ class TestEventGenerator : public chip::app::EventLoggingDelegate
public:
CHIP_ERROR WriteEvent(chip::TLV::TLVWriter & aWriter)
{
CHIP_ERROR err = CHIP_NO_ERROR;
err = aWriter.Put(kLivenessDeviceStatus, mStatus);
return err;
chip::TLV::TLVType dataContainerType;
ReturnErrorOnFailure(aWriter.StartContainer(chip::TLV::ContextTag(chip::to_underlying(chip::app::EventDataIB::Tag::kData)),
chip::TLV::kTLVType_Structure, dataContainerType));
ReturnErrorOnFailure(aWriter.Put(kLivenessDeviceStatus, mStatus));
return aWriter.EndContainer(dataContainerType);
}

void SetStatus(int32_t aStatus) { mStatus = aStatus; }
Expand Down
8 changes: 5 additions & 3 deletions src/app/tests/TestReadInteraction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,11 @@ class TestEventGenerator : public chip::app::EventLoggingDelegate
public:
CHIP_ERROR WriteEvent(chip::TLV::TLVWriter & aWriter)
{
CHIP_ERROR err = CHIP_NO_ERROR;
err = aWriter.Put(kTestEventTag, mStatus);
return err;
chip::TLV::TLVType dataContainerType;
ReturnErrorOnFailure(aWriter.StartContainer(chip::TLV::ContextTag(chip::to_underlying(chip::app::EventDataIB::Tag::kData)),
chip::TLV::kTLVType_Structure, dataContainerType));
ReturnErrorOnFailure(aWriter.Put(kTestEventTag, mStatus));
return aWriter.EndContainer(dataContainerType);
}

void SetStatus(int32_t aStatus) { mStatus = aStatus; }
Expand Down
8 changes: 5 additions & 3 deletions src/app/tests/integration/MockEvents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,11 @@ void LivenessEventGenerator::Generate(void)

CHIP_ERROR LivenessEventGenerator::WriteEvent(chip::TLV::TLVWriter & aWriter)
{
CHIP_ERROR err = CHIP_NO_ERROR;
err = aWriter.Put(kLivenessDeviceStatus, mStatus);
return err;
chip::TLV::TLVType dataContainerType;
ReturnErrorOnFailure(aWriter.StartContainer(chip::TLV::ContextTag(chip::to_underlying(chip::app::EventDataIB::Tag::kData)),
chip::TLV::kTLVType_Structure, dataContainerType));
ReturnErrorOnFailure(aWriter.Put(kLivenessDeviceStatus, mStatus));
return aWriter.EndContainer(dataContainerType);
}

chip::EventNumber LivenessEventGenerator::LogLiveness(chip::NodeId aNodeId, chip::EndpointId aEndpointId,
Expand Down
17 changes: 17 additions & 0 deletions src/app/zap-templates/zcl/data-model/chip/test-cluster.xml
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,16 @@ limitations under the License.
<arg name="arg1" type="BOOLEAN" optional="true"/>
</command>

<command source="client" code="0x14" name="TestEmitTestEventRequest"
optional="false" response="TestEmitTestEventResponse">
<description>
Command that takes identical arguments to the fields of the TestEvent and logs the TestEvent to the buffer. Command returns an event ID as the response.
</description>
<arg name="arg1" type="INT8U"/>
<arg name="arg2" type="SimpleEnum"/>
<arg name="arg3" type="BOOLEAN"/>
</command>

<command source="server" code="0x00" name="TestSpecificResponse" optional="false" disableDefaultResponse="true">
<description>
Simple response for TestWithResponse with a simple return value
Expand Down Expand Up @@ -482,6 +492,13 @@ limitations under the License.
<arg name="arg1" type="SimpleStruct"/>
</command>

<command source="server" code="0x0A" name="TestEmitTestEventResponse" optional="false" disableDefaultResponse="true">
<description>
Delivers the ID of an event in response to test command emitting events.
</description>
<arg name="value" type="INT64U"/>
</command>

<event code="0x0001" name="TestEvent" priority="info" side="server">
<description>Example test event</description>
<field id="1" name="arg1" type="INT8U"/>
Expand Down
Loading

0 comments on commit 6f89b9b

Please sign in to comment.