Skip to content

Commit

Permalink
Add intelligence to the ExchangeContext to determine if a peer is act…
Browse files Browse the repository at this point in the history
…ive (project-chip#29549)

* Add intelligence to the exchange context

* Restyled by whitespace

* Restyled by clang-format

* fix name

* Apply suggestions from code review

Co-authored-by: Tennessee Carmel-Veilleux <[email protected]>

* address review comments

* Apply suggestions from code review

Co-authored-by: Boris Zbarsky <[email protected]>

* address review comments

* fix rebase

* Refactor changes to simplify and remove req on exchange context consummer

* fix comment

* Apply suggestions from code review

Co-authored-by: Boris Zbarsky <[email protected]>

---------

Co-authored-by: Restyled.io <[email protected]>
Co-authored-by: Tennessee Carmel-Veilleux <[email protected]>
Co-authored-by: Boris Zbarsky <[email protected]>
  • Loading branch information
4 people authored and HunsupJung committed Oct 23, 2023
1 parent ee126ee commit 6ac94be
Show file tree
Hide file tree
Showing 7 changed files with 258 additions and 104 deletions.
4 changes: 3 additions & 1 deletion src/messaging/ExchangeContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,6 @@ CHIP_ERROR ExchangeContext::HandleMessage(uint32_t messageCounter, const Payload
if (payloadHeader.NeedsAck())
{
// An acknowledgment needs to be sent back to the peer for this message on this exchange,

HandleNeedsAck(messageCounter, msgFlags);
}
}
Expand Down Expand Up @@ -590,6 +589,9 @@ CHIP_ERROR ExchangeContext::HandleMessage(uint32_t messageCounter, const Payload
app::ICDNotifier::GetInstance().BroadcastNetworkActivityNotification();
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER

// Set kFlagReceivedAtLeastOneMessage to true since we have received at least one new application level message
SetHasReceivedAtLeastOneMessage(true);

if (IsResponseExpected())
{
// Since we got the response, cancel the response timer.
Expand Down
45 changes: 15 additions & 30 deletions src/messaging/ExchangeContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,14 @@ class DLL_EXPORT ExchangeContext : public ReliableMessageContext,
*/
bool IsSendExpected() const { return mFlags.Has(Flags::kFlagWillSendMessage); }

/**
* Tracks whether we have received at least one application level message
* during the life-time of this exchange
*
* @return Returns 'true' if we have received at least one message, else 'false'
*/
inline bool HasReceivedAtLeastOneMessage() { return mFlags.Has(Flags::kFlagReceivedAtLeastOneMessage); }

#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
SessionHolder & GetSessionHolder() { return mSession; }

Expand Down Expand Up @@ -292,42 +300,19 @@ class DLL_EXPORT ExchangeContext : public ReliableMessageContext,
*/
void MessageHandled();

/**
* Updates Sleepy End Device intervals mode in the following way:
* - does nothing for exchanges over Bluetooth LE
* - requests active mode if there are more messages,
* including MRP acknowledgements, expected to be sent or received on
* this exchange.
* - withdraws the request for active mode, otherwise.
*/
void UpdateSEDIntervalMode();

/**
* Requests or withdraws the request for Sleepy End Device active mode
* based on the argument value.
*
* Note that the device switches to the idle mode if no
* exchange nor other component requests the active mode.
*/
void UpdateSEDIntervalMode(bool activeMode);

static ExchangeMessageDispatch & GetMessageDispatch(bool isEphemeralExchange, ExchangeDelegate * delegate);

// If SetAutoReleaseSession() is called, this exchange must be using a SecureSession, and should
// evict it when the exchange is done with all its work (including any MRP traffic).
inline void SetIgnoreSessionRelease(bool ignore);
inline bool ShouldIgnoreSessionRelease();
};
inline void SetIgnoreSessionRelease(bool ignore) { mFlags.Set(Flags::kFlagIgnoreSessionRelease, ignore); }

inline void ExchangeContext::SetIgnoreSessionRelease(bool ignore)
{
mFlags.Set(Flags::kFlagIgnoreSessionRelease, ignore);
}
inline bool ShouldIgnoreSessionRelease() { return mFlags.Has(Flags::kFlagIgnoreSessionRelease); }

inline bool ExchangeContext::ShouldIgnoreSessionRelease()
{
return mFlags.Has(Flags::kFlagIgnoreSessionRelease);
}
inline void SetHasReceivedAtLeastOneMessage(bool hasReceivedMessage)
{
mFlags.Set(Flags::kFlagReceivedAtLeastOneMessage, hasReceivedMessage);
}
};

} // namespace Messaging
} // namespace chip
1 change: 0 additions & 1 deletion src/messaging/ReliableMessageContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ void ReliableMessageContext::HandleRcvdAck(uint32_t ackMessageCounter)
}

CHIP_ERROR ReliableMessageContext::HandleNeedsAck(uint32_t messageCounter, BitFlags<MessageFlagValues> messageFlags)

{
CHIP_ERROR err = HandleNeedsAckInner(messageCounter, messageFlags);

Expand Down
26 changes: 8 additions & 18 deletions src/messaging/ReliableMessageContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,6 @@ class ReliableMessageContext
/// Set if this exchange is requesting Sleepy End Device active mode
void SetRequestingActiveMode(bool activeMode);

/// Determine whether this exchange is requesting Sleepy End Device active mode
bool IsRequestingActiveMode() const;

/// Determine whether this exchange is a EphemeralExchange for replying a StandaloneAck
bool IsEphemeralExchange() const;

Expand Down Expand Up @@ -169,14 +166,17 @@ class ReliableMessageContext
/// When set, we have had Close() or Abort() called on us already.
kFlagClosed = (1u << 7),

/// When set, signifies that the exchange is requesting Sleepy End Device active mode.
kFlagActiveMode = (1u << 8),

/// When set, signifies that the exchange created sorely for replying a StandaloneAck
kFlagEphemeralExchange = (1u << 9),
kFlagEphemeralExchange = (1u << 8),

/// When set, ignore session being released, because we are releasing it ourselves.
kFlagIgnoreSessionRelease = (1u << 10),
kFlagIgnoreSessionRelease = (1u << 9),

// This flag is used to determine if the peer (receiver) should be considered active or not.
// When set, sender knows it has received at least one application-level message
// from the peer and can assume the peer (receiver) is active.
// If the flag is not set, we don't know if the peer (receiver) is active or not.
kFlagReceivedAtLeastOneMessage = (1u << 10),

/// When set:
///
Expand Down Expand Up @@ -238,11 +238,6 @@ inline bool ReliableMessageContext::HasPiggybackAckPending() const
return mFlags.Has(Flags::kFlagAckMessageCounterIsValid);
}

inline bool ReliableMessageContext::IsRequestingActiveMode() const
{
return mFlags.Has(Flags::kFlagActiveMode);
}

inline void ReliableMessageContext::SetAutoRequestAck(bool autoReqAck)
{
mFlags.Set(Flags::kFlagAutoRequestAck, autoReqAck);
Expand All @@ -253,11 +248,6 @@ inline void ReliableMessageContext::SetAckPending(bool inAckPending)
mFlags.Set(Flags::kFlagAckPending, inAckPending);
}

inline void ReliableMessageContext::SetRequestingActiveMode(bool activeMode)
{
mFlags.Set(Flags::kFlagActiveMode, activeMode);
}

inline bool ReliableMessageContext::IsEphemeralExchange() const
{
return mFlags.Has(Flags::kFlagEphemeralExchange);
Expand Down
31 changes: 23 additions & 8 deletions src/messaging/ReliableMessageMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,7 @@ void ReliableMessageMgr::ExecuteActions()
" Send Cnt %d",
messageCounter, ChipLogValueExchange(&entry->ec.Get()), entry->sendCount);

// Choose active/idle timeout from PeerActiveMode of session per 4.11.2.1. Retransmissions.
System::Clock::Timestamp baseTimeout = entry->ec->GetSessionHandle()->GetMRPBaseTimeout();
System::Clock::Timestamp backoff = ReliableMessageMgr::GetBackoff(baseTimeout, entry->sendCount);
entry->nextRetransTime = System::SystemClock().GetMonotonicTimestamp() + backoff;
CalculateNextRetransTime(*entry);
SendFromRetransTable(entry);

return Loop::Continue;
Expand Down Expand Up @@ -272,10 +269,7 @@ System::Clock::Timestamp ReliableMessageMgr::GetBackoff(System::Clock::Timestamp

void ReliableMessageMgr::StartRetransmision(RetransTableEntry * entry)
{
// Choose active/idle timeout from PeerActiveMode of session per 4.11.2.1. Retransmissions.
System::Clock::Timestamp baseTimeout = entry->ec->GetSessionHandle()->GetMRPBaseTimeout();
System::Clock::Timestamp backoff = ReliableMessageMgr::GetBackoff(baseTimeout, entry->sendCount);
entry->nextRetransTime = System::SystemClock().GetMonotonicTimestamp() + backoff;
CalculateNextRetransTime(*entry);
StartTimer();
}

Expand Down Expand Up @@ -456,6 +450,27 @@ CHIP_ERROR ReliableMessageMgr::MapSendError(CHIP_ERROR error, uint16_t exchangeI
return error;
}

void ReliableMessageMgr::CalculateNextRetransTime(RetransTableEntry & entry)
{
System::Clock::Timestamp baseTimeout = System::Clock::Milliseconds64(0);

// Check if we have received at least one application-level message
if (entry.ec->HasReceivedAtLeastOneMessage())
{
// If we have received at least one message, assume peer is active and use ActiveRetransTimeout
baseTimeout = entry.ec->GetSessionHandle()->GetRemoteMRPConfig().mActiveRetransTimeout;
}
else
{
// If we haven't received at least one message
// Choose active/idle timeout from PeerActiveMode of session per 4.11.2.1. Retransmissions.
baseTimeout = entry.ec->GetSessionHandle()->GetMRPBaseTimeout();
}

System::Clock::Timestamp backoff = ReliableMessageMgr::GetBackoff(baseTimeout, entry.sendCount);
entry.nextRetransTime = System::SystemClock().GetMonotonicTimestamp() + backoff;
}

#if CHIP_CONFIG_TEST
int ReliableMessageMgr::TestGetCountRetransTable()
{
Expand Down
8 changes: 8 additions & 0 deletions src/messaging/ReliableMessageMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,14 @@ class ReliableMessageMgr
#endif // CHIP_CONFIG_TEST

private:
/**
* Calculates the next retransmission time for the entry
* Function sets the nextRetransTime of the entry
*
* @param[in,out] entry RetransTableEntry for which we need to calculate the nextRetransTime
*/
void CalculateNextRetransTime(RetransTableEntry & entry);

ObjectPool<ExchangeContext, CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS> & mContextPool;
chip::System::Layer * mSystemLayer;

Expand Down
Loading

0 comments on commit 6ac94be

Please sign in to comment.