Skip to content

Commit

Permalink
MRP optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
mkardous-silabs committed Oct 2, 2023
1 parent 0b39434 commit 5ea3ca3
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 18 deletions.
25 changes: 24 additions & 1 deletion src/messaging/ExchangeContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,10 @@ CHIP_ERROR ExchangeContext::HandleMessage(uint32_t messageCounter, const Payload
// layer has completed its work on the ExchangeContext.
ExchangeHandle ref(*this);

// If we received a message from the Peer and we are still expecting a response, we know the peer is active
// If we receive a message from the Peer but if we are not expecting a response, we don't know if the peer is still active
mIsPeerActive = IsResponseExpected();

bool isStandaloneAck = payloadHeader.HasMessageType(Protocols::SecureChannel::MsgType::StandaloneAck);
bool isDuplicate = msgFlags.Has(MessageFlagValues::kDuplicateMessage);

Expand Down Expand Up @@ -565,7 +569,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 @@ -628,6 +631,9 @@ CHIP_ERROR ExchangeContext::HandleMessage(uint32_t messageCounter, const Payload
// If the context was expecting a response to a previously sent message, this message
// is implicitly that response.
SetResponseExpected(false);

// If we received the expected response, we don't if the peer is still active after having sent the message
mIsPeerActive = false;
}

// Don't send messages on to our delegate if our dispatch does not allow
Expand Down Expand Up @@ -689,5 +695,22 @@ void ExchangeContext::ExchangeSessionHolder::GrabExpiredSession(const SessionHan
GrabUnchecked(session);
}

bool ExchangeContext::IsPeerActive()
{
// We can never assume the peer is active if we are sending a group message
VerifyOrReturnError(IsGroupExchangeContext(), false);

// If sender is not initiator, it means the peer sent the first message.
// This means the peer is active if we are sending a message to the peer.
VerifyOrReturnError(!IsInitiator(), true);

// If we create an Ephemeral Exchange, it was just to generate a StandaloneAck
// Since we are sending an ack, we know the peer is active
VerifyOrReturnError(IsEphemeralExchange(), true);

// Return previously stored state if we have no absolute answer
return mIsPeerActive;
}

} // namespace Messaging
} // namespace chip
16 changes: 16 additions & 0 deletions src/messaging/ExchangeContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,20 @@ class DLL_EXPORT ExchangeContext : public ReliableMessageContext,
*/
bool IsSendExpected() const { return mFlags.Has(Flags::kFlagWillSendMessage); }

/**
* Functions checks with information available in the ExchangeContext if the peer is active or not
*
* IF group exchange -> peer is never active
* If we are not initiator -> peer is active
* If ephemeral context -> peer is active
* If we received a message and expect a response -> peer is active
*
* @return true Based on available information, Peer is active
* @return false We weren't able to determine if the peer is active.
* We don't know in which state the peer is.
*/
bool IsPeerActive();

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

Expand Down Expand Up @@ -248,6 +262,8 @@ class DLL_EXPORT ExchangeContext : public ReliableMessageContext,
ExchangeSessionHolder mSession; // The connection state
uint16_t mExchangeId; // Assigned exchange ID.

bool mIsPeerActive = false; // Tells us if the peer is active or not based on messages sent and received

/**
* Track whether we are now expecting a response to a message sent via this exchange (because that
* message had the kExpectResponse flag set in its sendFlags).
Expand Down
1 change: 0 additions & 1 deletion src/messaging/ReliableMessageContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,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
8 changes: 0 additions & 8 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 @@ -226,11 +223,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 Down
31 changes: 23 additions & 8 deletions src/messaging/ReliableMessageMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,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;
CalculateNextRestranTime(entry);
SendFromRetransTable(entry);

return Loop::Continue;
Expand Down Expand Up @@ -277,10 +274,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;
CalculateNextRestranTime(entry);
StartTimer();
}

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

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

if (entry->ec->IsPeerActive())
{
// If we know the peer is active with the exchangeContext, use the Active Retrans timeout
baseTimeout = entry->ec->GetSessionHandle()->GetRemoteMRPConfig().mActiveRetransTimeout;
}
else
{

// If the exchange context doesn't know if the peer is active or not.
// 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
5 changes: 5 additions & 0 deletions src/messaging/ReliableMessageMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,11 @@ class ReliableMessageMgr
#endif // CHIP_CONFIG_TEST

private:
/**
* Calculates the next retransmission time for the entry
*/
void CalculateNextRestranTime(RetransTableEntry * entry);

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

Expand Down

0 comments on commit 5ea3ca3

Please sign in to comment.