Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inject event management into report engine #36831

Merged
merged 11 commits into from
Dec 18, 2024
1 change: 1 addition & 0 deletions src/app/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ static_library("interaction-model") {
"CommandSender.h",
"DeviceProxy.cpp",
"DeviceProxy.h",
"EventScheduler.h",
"InteractionModelDelegatePointers.cpp",
"InteractionModelDelegatePointers.h",
"InteractionModelEngine.cpp",
Expand Down
16 changes: 14 additions & 2 deletions src/app/EventManagement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ struct CopyAndAdjustDeltaTimeContext
void EventManagement::Init(Messaging::ExchangeManager * apExchangeManager, uint32_t aNumBuffers,
CircularEventBuffer * apCircularEventBuffer, const LogStorageResources * const apLogStorageResources,
MonotonicallyIncreasingCounter<EventNumber> * apEventNumberCounter,
System::Clock::Milliseconds64 aMonotonicStartupTime)
System::Clock::Milliseconds64 aMonotonicStartupTime, EventScheduler * apEventScheduler)
{
CircularEventBuffer * current = nullptr;
CircularEventBuffer * prev = nullptr;
Expand Down Expand Up @@ -124,6 +124,15 @@ void EventManagement::Init(Messaging::ExchangeManager * apExchangeManager, uint3
mBytesWritten = 0;

mMonotonicStartupTime = aMonotonicStartupTime;

if (apEventScheduler == nullptr)
yyzhong-g marked this conversation as resolved.
Show resolved Hide resolved
{
mpEventScheduler = &InteractionModelEngine::GetInstance()->GetReportingEngine();
}
else
{
mpEventScheduler = apEventScheduler;
}
}

CHIP_ERROR EventManagement::CopyToNextBuffer(CircularEventBuffer * apEventBuffer)
Expand Down Expand Up @@ -490,7 +499,10 @@ CHIP_ERROR EventManagement::LogEventPrivate(EventLoggingDelegate * apDelegate, c
opts.mTimestamp.mType == Timestamp::Type::kSystem ? "Sys" : "Epoch", ChipLogValueX64(opts.mTimestamp.mValue));
#endif // CHIP_CONFIG_EVENT_LOGGING_VERBOSE_DEBUG_LOGS

err = InteractionModelEngine::GetInstance()->GetReportingEngine().ScheduleEventDelivery(opts.mPath, mBytesWritten);
if (mpEventScheduler)
{
err = mpEventScheduler->ScheduleEventDelivery(opts.mPath, mBytesWritten);
}
}

return err;
Expand Down
8 changes: 7 additions & 1 deletion src/app/EventManagement.h
yyzhong-g marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "EventLoggingDelegate.h"
#include <access/SubjectDescriptor.h>
#include <app/EventLoggingTypes.h>
#include <app/EventScheduler.h>
#include <app/MessageDef/EventDataIB.h>
#include <app/MessageDef/StatusIB.h>
#include <app/data-model-provider/EventsGenerator.h>
Expand Down Expand Up @@ -225,11 +226,14 @@ class EventManagement : public DataModel::EventsGenerator
* time 0" for cases when we use
* system-time event timestamps.
*
* @param[in] apEventScheduler Scheduler to deliver the event, default is the reporting
* engine in InteractionModelEngine.
*
*/
void Init(Messaging::ExchangeManager * apExchangeManager, uint32_t aNumBuffers, CircularEventBuffer * apCircularEventBuffer,
const LogStorageResources * const apLogStorageResources,
MonotonicallyIncreasingCounter<EventNumber> * apEventNumberCounter,
System::Clock::Milliseconds64 aMonotonicStartupTime);
System::Clock::Milliseconds64 aMonotonicStartupTime, EventScheduler * apEventScheduler = nullptr);

static EventManagement & GetInstance();

Expand Down Expand Up @@ -563,6 +567,8 @@ class EventManagement : public DataModel::EventsGenerator
Timestamp mLastEventTimestamp; ///< The timestamp of the last event in this buffer

System::Clock::Milliseconds64 mMonotonicStartupTime;

EventScheduler * mpEventScheduler = nullptr;
};

} // namespace app
Expand Down
51 changes: 51 additions & 0 deletions src/app/EventScheduler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
*
* Copyright (c) 2024 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.
*/

/**
* @file
*
* @brief
* Define EventScheduler interface. Event scheduler is used by EventManagement to notify that events are ready to be scheduled.
* Usually this is implemented by the Reporting Engine to find the proper ReadHandlers and deliver the events.
*
*/
#pragma once

#include <app/ConcreteEventPath.h>
#include <lib/core/CHIPError.h>

namespace chip {
namespace app {

class EventScheduler
yyzhong-g marked this conversation as resolved.
Show resolved Hide resolved
{
public:
virtual ~EventScheduler() = default;

/**
* @brief
* Schedule the event delivery
*
* @param[in] aPath The path to the event.
* @param[in] aBytesWritten Bytes that the event is written into the buffer in EventManagement.
*/
CHIP_ERROR virtual ScheduleEventDelivery(ConcreteEventPath & aPath, uint32_t aBytesWritten) = 0;
};

} // namespace app
} // namespace chip
5 changes: 3 additions & 2 deletions src/app/InteractionModelEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ InteractionModelEngine * InteractionModelEngine::GetInstance()

CHIP_ERROR InteractionModelEngine::Init(Messaging::ExchangeManager * apExchangeMgr, FabricTable * apFabricTable,
reporting::ReportScheduler * reportScheduler, CASESessionManager * apCASESessionMgr,
SubscriptionResumptionStorage * subscriptionResumptionStorage)
SubscriptionResumptionStorage * subscriptionResumptionStorage,
EventManagement * eventManagement)
{
VerifyOrReturnError(apFabricTable != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(apExchangeMgr != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
Expand All @@ -165,7 +166,7 @@ CHIP_ERROR InteractionModelEngine::Init(Messaging::ExchangeManager * apExchangeM
ReturnErrorOnFailure(mpFabricTable->AddFabricDelegate(this));
ReturnErrorOnFailure(mpExchangeMgr->RegisterUnsolicitedMessageHandlerForProtocol(Protocols::InteractionModel::Id, this));

mReportingEngine.Init();
mReportingEngine.Init(eventManagement);

StatusIB::RegisterErrorFormatter();

Expand Down
4 changes: 3 additions & 1 deletion src/app/InteractionModelEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,13 @@ class InteractionModelEngine : public Messaging::UnsolicitedMessageHandler,
* @param[in] apExchangeMgr A pointer to the ExchangeManager object.
* @param[in] apFabricTable A pointer to the FabricTable object.
* @param[in] apCASESessionMgr An optional pointer to a CASESessionManager (used for re-subscriptions).
* @parma[in] eventManagement An optional pointer to a EventManagement. Use the global instance if not presented.
yyzhong-g marked this conversation as resolved.
Show resolved Hide resolved
*
*/
CHIP_ERROR Init(Messaging::ExchangeManager * apExchangeMgr, FabricTable * apFabricTable,
reporting::ReportScheduler * reportScheduler, CASESessionManager * apCASESessionMgr = nullptr,
SubscriptionResumptionStorage * subscriptionResumptionStorage = nullptr);
SubscriptionResumptionStorage * subscriptionResumptionStorage = nullptr,
EventManagement * eventManagement = nullptr);

void Shutdown();

Expand Down
30 changes: 20 additions & 10 deletions src/app/reporting/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,20 @@ bool IsClusterDataVersionEqualTo(DataModel::Provider * dataModel, const Concrete

Engine::Engine(InteractionModelEngine * apImEngine) : mpImEngine(apImEngine) {}

CHIP_ERROR Engine::Init()
CHIP_ERROR Engine::Init(EventManagement * apEventManagement)
{
mNumReportsInFlight = 0;
mCurReadHandlerIdx = 0;

if (apEventManagement == nullptr)
{
mpEventManagement = &EventManagement::GetInstance();
}
else
{
mpEventManagement = apEventManagement;
}

return CHIP_NO_ERROR;
}

Expand Down Expand Up @@ -560,20 +570,20 @@ CHIP_ERROR Engine::BuildSingleReportDataEventReports(ReportDataMessage::Builder
size_t eventCount = 0;
bool hasEncodedStatus = false;
TLV::TLVWriter backup;
bool eventClean = true;
auto & eventMin = apReadHandler->GetEventMin();
EventManagement & eventManager = EventManagement::GetInstance();
bool hasMoreChunks = false;
bool eventClean = true;
auto & eventMin = apReadHandler->GetEventMin();
bool hasMoreChunks = false;

aReportDataBuilder.Checkpoint(backup);

VerifyOrExit(apReadHandler->GetEventPathList() != nullptr, );

// If the eventManager is not valid or has not been initialized,
// If the mpEventManagement is not valid or has not been initialized,
// skip the rest of processing
VerifyOrExit(eventManager.IsValid(), ChipLogError(DataManagement, "EventManagement has not yet initialized"));
VerifyOrExit(mpEventManagement != nullptr && mpEventManagement->IsValid(),
ChipLogError(DataManagement, "EventManagement has not yet initialized"));

eventClean = apReadHandler->CheckEventClean(eventManager);
eventClean = apReadHandler->CheckEventClean(*mpEventManagement);

// proceed only if there are new events.
if (eventClean)
Expand All @@ -593,8 +603,8 @@ CHIP_ERROR Engine::BuildSingleReportDataEventReports(ReportDataMessage::Builder
err = CheckAccessDeniedEventPaths(*(eventReportIBs.GetWriter()), hasEncodedStatus, apReadHandler);
SuccessOrExit(err);

err = eventManager.FetchEventsSince(*(eventReportIBs.GetWriter()), apReadHandler->GetEventPathList(), eventMin, eventCount,
apReadHandler->GetSubjectDescriptor());
err = mpEventManagement->FetchEventsSince(*(eventReportIBs.GetWriter()), apReadHandler->GetEventPathList(), eventMin,
eventCount, apReadHandler->GetSubjectDescriptor());

if ((err == CHIP_END_OF_TLV) || (err == CHIP_ERROR_TLV_UNDERRUN) || (err == CHIP_NO_ERROR))
{
Expand Down
11 changes: 8 additions & 3 deletions src/app/reporting/Engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#pragma once

#include <access/AccessControl.h>
#include <app/EventScheduler.h>
#include <app/MessageDef/ReportDataMessage.h>
#include <app/ReadHandler.h>
#include <app/data-model-provider/ProviderChangeListener.h>
Expand Down Expand Up @@ -55,7 +56,7 @@ namespace reporting {
* At its core, it tries to gather and pack as much relevant attributes changes and/or events as possible into a report
* message before sending that to the reader. It continues to do so until it has no more work to do.
*/
class Engine : public DataModel::ProviderChangeListener
class Engine : public DataModel::ProviderChangeListener, public EventScheduler
{
public:
/**
Expand All @@ -66,10 +67,12 @@ class Engine : public DataModel::ProviderChangeListener
/**
* Initializes the reporting engine. Should only be called once.
*
* @param[in] A pointer to EventManagement. Use the global one by default.
yyzhong-g marked this conversation as resolved.
Show resolved Hide resolved
*
* @retval #CHIP_NO_ERROR On success.
* @retval other Was unable to retrieve data and write it into the writer.
*/
CHIP_ERROR Init();
CHIP_ERROR Init(EventManagement * apEventManagement = nullptr);

void Shutdown();

Expand Down Expand Up @@ -101,7 +104,7 @@ class Engine : public DataModel::ProviderChangeListener
* Schedule the event delivery
*
*/
CHIP_ERROR ScheduleEventDelivery(ConcreteEventPath & aPath, uint32_t aBytesWritten);
CHIP_ERROR ScheduleEventDelivery(ConcreteEventPath & aPath, uint32_t aBytesWritten) override;

/*
* Resets the tracker that tracks the currently serviced read handler.
Expand Down Expand Up @@ -287,6 +290,8 @@ class Engine : public DataModel::ProviderChangeListener
#endif

InteractionModelEngine * mpImEngine = nullptr;

EventManagement * mpEventManagement = nullptr;
};

}; // namespace reporting
Expand Down
Loading