Skip to content

Commit

Permalink
Add a way to ask a ReadClient what its liveness check timeout is. (#2…
Browse files Browse the repository at this point in the history
  • Loading branch information
bzbarsky-apple authored and pull[bot] committed Feb 22, 2024
1 parent ca9bd91 commit 2005170
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 29 deletions.
79 changes: 50 additions & 29 deletions src/app/ReadClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -789,39 +789,12 @@ CHIP_ERROR ReadClient::RefreshLivenessCheckTimer()
{
CHIP_ERROR err = CHIP_NO_ERROR;

VerifyOrReturnError(mState == ClientState::SubscriptionActive, CHIP_ERROR_INCORRECT_STATE);
VerifyOrReturnError(IsSubscriptionActive(), CHIP_ERROR_INCORRECT_STATE);

CancelLivenessCheckTimer();

System::Clock::Timeout timeout;

if (mLivenessTimeoutOverride != System::Clock::kZero)
{
timeout = mLivenessTimeoutOverride;
}
else
{
VerifyOrReturnError(mReadPrepareParams.mSessionHolder, CHIP_ERROR_INCORRECT_STATE);

//
// To calculate the duration we're willing to wait for a report to come to us, we take into account the maximum interval of
// the subscription AND the time it takes for the report to make it to us in the worst case. This latter bit involves
// computing the Ack timeout from the publisher for the ReportData message being sent to us using our IDLE interval as the
// basis for that computation.
//
// Make sure to use the retransmission computation that includes backoff. For purposes of that computation, treat us as
// active now (since we are right now sending/receiving messages), and use the default "how long are we guaranteed to stay
// active" threshold for now.
//
// TODO: We need to find a good home for this logic that will correctly compute this based on transport. For now, this will
// suffice since we don't use TCP as a transport currently and subscriptions over BLE aren't really a thing.
//
const auto & ourMrpConfig = GetDefaultMRPConfig();
auto publisherTransmissionTimeout =
GetRetransmissionTimeout(ourMrpConfig.mActiveRetransTimeout, ourMrpConfig.mIdleRetransTimeout,
System::SystemClock().GetMonotonicTimestamp(), Transport::kMinActiveTime);
timeout = System::Clock::Seconds16(mMaxInterval) + publisherTransmissionTimeout;
}
ReturnErrorOnFailure(ComputeLivenessCheckTimerTimeout(&timeout));

// EFR32/MBED/INFINION/K32W's chrono count return long unsigned, but other platform returns unsigned
ChipLogProgress(
Expand All @@ -834,6 +807,37 @@ CHIP_ERROR ReadClient::RefreshLivenessCheckTimer()
return err;
}

CHIP_ERROR ReadClient::ComputeLivenessCheckTimerTimeout(System::Clock::Timeout * aTimeout)
{
if (mLivenessTimeoutOverride != System::Clock::kZero)
{
*aTimeout = mLivenessTimeoutOverride;
return CHIP_NO_ERROR;
}

VerifyOrReturnError(mReadPrepareParams.mSessionHolder, CHIP_ERROR_INCORRECT_STATE);

//
// To calculate the duration we're willing to wait for a report to come to us, we take into account the maximum interval of
// the subscription AND the time it takes for the report to make it to us in the worst case. This latter bit involves
// computing the Ack timeout from the publisher for the ReportData message being sent to us using our IDLE interval as the
// basis for that computation.
//
// Make sure to use the retransmission computation that includes backoff. For purposes of that computation, treat us as
// active now (since we are right now sending/receiving messages), and use the default "how long are we guaranteed to stay
// active" threshold for now.
//
// TODO: We need to find a good home for this logic that will correctly compute this based on transport. For now, this will
// suffice since we don't use TCP as a transport currently and subscriptions over BLE aren't really a thing.
//
const auto & ourMrpConfig = GetDefaultMRPConfig();
auto publisherTransmissionTimeout =
GetRetransmissionTimeout(ourMrpConfig.mActiveRetransTimeout, ourMrpConfig.mIdleRetransTimeout,
System::SystemClock().GetMonotonicTimestamp(), Transport::kMinActiveTime);
*aTimeout = System::Clock::Seconds16(mMaxInterval) + publisherTransmissionTimeout;
return CHIP_NO_ERROR;
}

void ReadClient::CancelLivenessCheckTimer()
{
InteractionModelEngine::GetInstance()->GetExchangeManager()->GetSessionManager()->SystemLayer()->CancelTimer(
Expand Down Expand Up @@ -1188,5 +1192,22 @@ void ReadClient::TriggerResubscribeIfScheduled(const char * reason)
OnResubscribeTimerCallback(nullptr, this);
}

Optional<System::Clock::Timeout> ReadClient::GetSubscriptionTimeout()
{
if (!IsSubscriptionType() || !IsSubscriptionActive())
{
return NullOptional;
}

System::Clock::Timeout timeout;
CHIP_ERROR err = ComputeLivenessCheckTimerTimeout(&timeout);
if (err != CHIP_NO_ERROR)
{
return NullOptional;
}

return MakeOptional(timeout);
}

} // namespace app
} // namespace chip
11 changes: 11 additions & 0 deletions src/app/ReadClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,16 @@ class ReadClient : public Messaging::ExchangeDelegate
*/
void TriggerResubscribeIfScheduled(const char * reason);

/**
* Returns the timeout after which we consider the subscription to have
* dropped, if we have received no messages within that amount of time.
*
* Returns NullOptional if a subscription has not yet been established (and
* hence the MaxInterval is not yet known), or if the subscription session
* is gone and hence the relevant MRP parameters can no longer be determined.
*/
Optional<System::Clock::Timeout> GetSubscriptionTimeout();

private:
friend class TestReadInteraction;
friend class InteractionModelEngine;
Expand Down Expand Up @@ -471,6 +481,7 @@ class ReadClient : public Messaging::ExchangeDelegate
static void OnLivenessTimeoutCallback(System::Layer * apSystemLayer, void * apAppState);
CHIP_ERROR ProcessSubscribeResponse(System::PacketBufferHandle && aPayload);
CHIP_ERROR RefreshLivenessCheckTimer();
CHIP_ERROR ComputeLivenessCheckTimerTimeout(System::Clock::Timeout * aTimeout);
void CancelLivenessCheckTimer();
void CancelResubscribeTimer();
void MoveToState(const ClientState aTargetState);
Expand Down

0 comments on commit 2005170

Please sign in to comment.