Skip to content

Commit

Permalink
Fixed bug where chunked reports would fail on Synchronized report sch…
Browse files Browse the repository at this point in the history
…eduler and added tests for Syncrhonized report scheduler interaction

Also fixed behavior of Synchronized Report scheduler on Early Reports cases
  • Loading branch information
lpbeliveau-silabs committed Nov 23, 2023
1 parent 3eb9c02 commit 7114628
Show file tree
Hide file tree
Showing 7 changed files with 371 additions and 226 deletions.
1 change: 1 addition & 0 deletions src/app/reporting/ReportScheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class ReportScheduler : public ReadHandler::Observer, public ICDStateObserver
IsEngineRunScheduled()));
}

bool IsChunkedReport() const { return mReadHandler->IsChunkedReport(); }
bool IsEngineRunScheduled() const { return mFlags.Has(ReadHandlerNodeFlags::EngineRunScheduled); }
void SetEngineRunScheduled(bool aEngineRunScheduled)
{
Expand Down
2 changes: 1 addition & 1 deletion src/app/reporting/ReportSchedulerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class ReportSchedulerImpl : public ReportScheduler
void OnSubscriptionReportSent(ReadHandler * aReadHandler) final;
void OnReadHandlerDestroyed(ReadHandler * aReadHandler) override;

bool IsReportScheduled(ReadHandler * aReadHandler);
virtual bool IsReportScheduled(ReadHandler * aReadHandler);

void ReportTimerCallback() override;

Expand Down
36 changes: 30 additions & 6 deletions src/app/reporting/SynchronizedReportSchedulerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void SynchronizedReportSchedulerImpl::CancelReport()
}

/// @brief Checks if the timer is active for the ReportScheduler
bool SynchronizedReportSchedulerImpl::IsReportScheduled()
bool SynchronizedReportSchedulerImpl::IsReportScheduled(ReadHandler * ReadHandler)
{
return mTimerDelegate->IsTimerActive(this);
}
Expand Down Expand Up @@ -140,7 +140,7 @@ CHIP_ERROR SynchronizedReportSchedulerImpl::CalculateNextReportTimeout(Timeout &
bool reportableAtMin = false;

mNodesPool.ForEachActiveObject([&reportableNow, &reportableAtMin, this, now](ReadHandlerNode * node) {
if (!node->IsEngineRunScheduled())
if (!node->IsEngineRunScheduled() || node->IsChunkedReport())
{
if (node->IsReportableNow(now))
{
Expand Down Expand Up @@ -180,25 +180,49 @@ CHIP_ERROR SynchronizedReportSchedulerImpl::CalculateNextReportTimeout(Timeout &
/// the engine already verifies that read handlers are reportable before sending a report
void SynchronizedReportSchedulerImpl::TimerFired()
{
Timestamp now = mTimerDelegate->GetCurrentMonotonicTimestamp();
Timestamp now = mTimerDelegate->GetCurrentMonotonicTimestamp();
bool firedEarly = true;

InteractionModelEngine::GetInstance()->GetReportingEngine().ScheduleRun();

mNodesPool.ForEachActiveObject([now](ReadHandlerNode * node) {
mNodesPool.ForEachActiveObject([now, &firedEarly](ReadHandlerNode * node) {
if (node->GetMinTimestamp() <= now)
{
node->SetCanBeSynced(true);
}

if (node->IsReportableNow(now))
{
// We assume we fired the timer early if no handler is reportable at the moment
firedEarly = false;
node->SetEngineRunScheduled(true);
ChipLogProgress(DataManagement, "Handler: %p with min: 0x" ChipLogFormatX64 " and max: 0x" ChipLogFormatX64 "", (node),
ChipLogValueX64(node->GetMinTimestamp().count()), ChipLogValueX64(node->GetMaxTimestamp().count()));
}

return Loop::Continue;
});

// If there are no handlers registers, no need to schedule the next report
if (mNodesPool.Allocated() && firedEarly)
{
ReadHandlerNode * firstNode = nullptr;

// If we fired the timer early, we need to restart the timer
mNodesPool.ForEachActiveObject([&firstNode](ReadHandlerNode * node) {
firstNode = node;
return Loop::Break;
});

bool firstNodeFound = (nullptr != firstNode);
VerifyOrReturn(firstNodeFound);

Timeout timeout = Milliseconds32(0);
ReturnOnFailure(CalculateNextReportTimeout(timeout, firstNode, now));
ScheduleReport(timeout, nullptr, now);
}
else
{
InteractionModelEngine::GetInstance()->GetReportingEngine().ScheduleRun();
}
}

} // namespace reporting
Expand Down
2 changes: 1 addition & 1 deletion src/app/reporting/SynchronizedReportSchedulerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class SynchronizedReportSchedulerImpl : public ReportSchedulerImpl, public Timer

void OnTransitionToIdle() override;

bool IsReportScheduled();
bool IsReportScheduled(ReadHandler * ReadHandler) override;

void TimerFired() override;

Expand Down
4 changes: 2 additions & 2 deletions src/app/reporting/tests/MockReportScheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace reporting {

static chip::app::DefaultTimerDelegate sTimerDelegate;
static ReportSchedulerImpl sTestDefaultReportScheduler(&sTimerDelegate);
static SynchronizedReportSchedulerImpl sTestReportScheduler(&sTimerDelegate);
static SynchronizedReportSchedulerImpl sTestSyncReportScheduler(&sTimerDelegate);

ReportSchedulerImpl * GetDefaultReportScheduler()
{
Expand All @@ -38,7 +38,7 @@ ReportSchedulerImpl * GetDefaultReportScheduler()

SynchronizedReportSchedulerImpl * GetSynchronizedReportScheduler()
{
return &sTestReportScheduler;
return &sTestSyncReportScheduler;
}

} // namespace reporting
Expand Down
Loading

0 comments on commit 7114628

Please sign in to comment.