@@ -430,7 +430,7 @@ void OperationalSessionSetup::OnSessionEstablishmentError(CHIP_ERROR error, Sess
430
430
// member instead of having a boolean
431
431
// mTryingNextResultDueToSessionEstablishmentError, so we can recover the
432
432
// error in UpdateDeviceData.
433
- if (CHIP_ERROR_TIMEOUT == error)
433
+ if (CHIP_ERROR_TIMEOUT == error || CHIP_ERROR_BUSY == error )
434
434
{
435
435
#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
436
436
// Make a copy of the ReliableMessageProtocolConfig, since our
@@ -480,6 +480,15 @@ void OperationalSessionSetup::OnSessionEstablishmentError(CHIP_ERROR error, Sess
480
480
// Do not touch `this` instance anymore; it has been destroyed in DequeueConnectionCallbacks.
481
481
}
482
482
483
+ void OperationalSessionSetup::OnResponderBusy (System::Clock::Milliseconds16 requestedDelay)
484
+ {
485
+ #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES
486
+ // Store the requested delay, so that we can use it for scheduling our
487
+ // retry.
488
+ mRequestedBusyDelay = requestedDelay;
489
+ #endif
490
+ }
491
+
483
492
void OperationalSessionSetup::OnSessionEstablished (const SessionHandle & session)
484
493
{
485
494
VerifyOrReturn (mState == State::Connecting,
@@ -705,9 +714,22 @@ CHIP_ERROR OperationalSessionSetup::ScheduleSessionSetupReattempt(System::Clock:
705
714
static_assert (UINT16_MAX / CHIP_DEVICE_CONFIG_AUTOMATIC_CASE_RETRY_INITIAL_DELAY_SECONDS >=
706
715
(1 << CHIP_DEVICE_CONFIG_AUTOMATIC_CASE_RETRY_MAX_BACKOFF),
707
716
" Our backoff calculation will overflow." );
708
- timerDelay = System::Clock::Seconds16 (
717
+ System::Clock::Timeout actualTimerDelay = System::Clock::Seconds16 (
709
718
static_cast <uint16_t >(CHIP_DEVICE_CONFIG_AUTOMATIC_CASE_RETRY_INITIAL_DELAY_SECONDS
710
719
<< min ((mAttemptsDone - 1 ), CHIP_DEVICE_CONFIG_AUTOMATIC_CASE_RETRY_MAX_BACKOFF)));
720
+ const bool responseWasBusy = mRequestedBusyDelay != System::Clock::kZero ;
721
+ if (responseWasBusy)
722
+ {
723
+ if (mRequestedBusyDelay > actualTimerDelay)
724
+ {
725
+ actualTimerDelay = mRequestedBusyDelay ;
726
+ }
727
+
728
+ // Reset mRequestedBusyDelay now that we have consumed it, so it does
729
+ // not affect future reattempts not triggered by a busy response.
730
+ mRequestedBusyDelay = System::Clock::kZero ;
731
+ }
732
+
711
733
if (mAttemptsDone % 2 == 0 )
712
734
{
713
735
// It's possible that the other side received one of our Sigma1 messages
@@ -716,11 +738,22 @@ CHIP_ERROR OperationalSessionSetup::ScheduleSessionSetupReattempt(System::Clock:
716
738
// listening for Sigma1 messages again.
717
739
//
718
740
// To handle that, on every other retry, add the amount of time it would
719
- // take the other side to time out.
741
+ // take the other side to time out. It would be nice if we could rely
742
+ // on the delay reported in a BUSY response to just tell us that value,
743
+ // but in practice for old devices BUSY often sends some hardcoded value
744
+ // that tells us nothing about when the other side will decide it has
745
+ // timed out.
720
746
auto additionalTimeout = CASESession::ComputeSigma2ResponseTimeout (GetLocalMRPConfig ().ValueOr (GetDefaultMRPConfig ()));
721
- timerDelay += std::chrono::duration_cast<System::Clock::Seconds16>( additionalTimeout) ;
747
+ actualTimerDelay += additionalTimeout;
722
748
}
723
- CHIP_ERROR err = mInitParams .exchangeMgr ->GetSessionManager ()->SystemLayer ()->StartTimer (timerDelay, TrySetupAgain, this );
749
+ timerDelay = std::chrono::duration_cast<System::Clock::Seconds16>(actualTimerDelay);
750
+
751
+ CHIP_ERROR err = mInitParams .exchangeMgr ->GetSessionManager ()->SystemLayer ()->StartTimer (actualTimerDelay, TrySetupAgain, this );
752
+
753
+ // TODO: If responseWasBusy, should we increment, mRemainingAttempts and
754
+ // mResolveAttemptsAllowed, since we were explicitly told to retry? Hard to
755
+ // tell what consumers expect out of a capped retry count here.
756
+
724
757
// The cast on count() is needed because the type count() returns might not
725
758
// actually be uint16_t; on some platforms it's int.
726
759
ChipLogProgress (Discovery,
0 commit comments