@@ -143,7 +143,14 @@ CHIP_ERROR ReadClient::ScheduleResubscription(uint32_t aTimeTillNextResubscripti
143
143
mReadPrepareParams .mSessionHolder .Grab (aNewSessionHandle.Value ());
144
144
}
145
145
146
- mDoCaseOnNextResub = aReestablishCASE;
146
+ mForceCaseOnNextResub = aReestablishCASE;
147
+ if (mForceCaseOnNextResub && mReadPrepareParams .mSessionHolder )
148
+ {
149
+ // Mark our existing session defunct, so that we will try to
150
+ // re-establish it when the timer fires (unless something re-establishes
151
+ // before then).
152
+ mReadPrepareParams .mSessionHolder ->AsSecureSession ()->MarkAsDefunct ();
153
+ }
147
154
148
155
ReturnErrorOnFailure (
149
156
InteractionModelEngine::GetInstance ()->GetExchangeManager ()->GetSessionManager ()->SystemLayer ()->StartTimer (
@@ -1013,7 +1020,16 @@ CHIP_ERROR ReadClient::SendSubscribeRequestImpl(const ReadPrepareParams & aReadP
1013
1020
VerifyOrReturnError (aReadPrepareParams.mSessionHolder , CHIP_ERROR_MISSING_SECURE_SESSION);
1014
1021
1015
1022
auto exchange = mpExchangeMgr->NewContext (aReadPrepareParams.mSessionHolder .Get ().Value (), this );
1016
- VerifyOrReturnError (exchange != nullptr , CHIP_ERROR_NO_MEMORY);
1023
+ if (exchange == nullptr )
1024
+ {
1025
+ if (aReadPrepareParams.mSessionHolder ->AsSecureSession ()->IsActiveSession ())
1026
+ {
1027
+ return CHIP_ERROR_NO_MEMORY;
1028
+ }
1029
+
1030
+ // Trying to subscribe with a defunct session somehow.
1031
+ return CHIP_ERROR_INCORRECT_STATE;
1032
+ }
1017
1033
1018
1034
mExchange .Grab (exchange);
1019
1035
@@ -1081,30 +1097,34 @@ void ReadClient::OnResubscribeTimerCallback(System::Layer * apSystemLayer, void
1081
1097
1082
1098
CHIP_ERROR err;
1083
1099
1084
- ChipLogProgress (DataManagement, " OnResubscribeTimerCallback: DoCASE = %d" , _this->mDoCaseOnNextResub );
1100
+ ChipLogProgress (DataManagement, " OnResubscribeTimerCallback: ForceCASE = %d" , _this->mForceCaseOnNextResub );
1085
1101
_this->mNumRetries ++;
1086
1102
1087
- if (_this->mDoCaseOnNextResub )
1103
+ bool allowResubscribeOnError = true ;
1104
+ if (!_this->mReadPrepareParams .mSessionHolder ||
1105
+ !_this->mReadPrepareParams .mSessionHolder ->AsSecureSession ()->IsActiveSession ())
1088
1106
{
1107
+ // We don't have an active CASE session. We need to go ahead and set
1108
+ // one up, if we can.
1109
+ ChipLogProgress (DataManagement, " Trying to establish a CASE session" );
1089
1110
auto * caseSessionManager = InteractionModelEngine::GetInstance ()->GetCASESessionManager ();
1090
- VerifyOrExit (caseSessionManager != nullptr , err = CHIP_ERROR_INCORRECT_STATE);
1111
+ if (caseSessionManager)
1112
+ {
1113
+ caseSessionManager->FindOrEstablishSession (_this->mPeer , &_this->mOnConnectedCallback ,
1114
+ &_this->mOnConnectionFailureCallback );
1115
+ return ;
1116
+ }
1091
1117
1092
- //
1093
- // We need to mark our session as defunct explicitly since the assessment of a liveness failure
1094
- // is usually triggered by the absence of any exchange activity that would have otherwise
1095
- // automatically marked the session as defunct on a response timeout.
1096
- //
1097
- // Doing so will ensure that the subsequent call to FindOrEstablishSession will not bind to
1098
- // an existing established session but rather trigger establishing a new one.
1099
- //
1100
- if (_this->mReadPrepareParams .mSessionHolder )
1118
+ if (_this->mForceCaseOnNextResub )
1101
1119
{
1102
- _this->mReadPrepareParams .mSessionHolder ->AsSecureSession ()->MarkAsDefunct ();
1120
+ // Caller asked us to force CASE but we have no way to do CASE.
1121
+ // Just stop trying.
1122
+ allowResubscribeOnError = false ;
1103
1123
}
1104
1124
1105
- caseSessionManager-> FindOrEstablishSession (_this-> mPeer , &_this-> mOnConnectedCallback ,
1106
- &_this-> mOnConnectionFailureCallback ) ;
1107
- return ;
1125
+ // No way to send our subscribe request.
1126
+ err = CHIP_ERROR_INCORRECT_STATE ;
1127
+ ExitNow () ;
1108
1128
}
1109
1129
1110
1130
err = _this->SendSubscribeRequest (_this->mReadPrepareParams );
@@ -1114,11 +1134,11 @@ void ReadClient::OnResubscribeTimerCallback(System::Layer * apSystemLayer, void
1114
1134
{
1115
1135
//
1116
1136
// Call Close (which should trigger re-subscription again) EXCEPT if we got here because we didn't have a valid
1117
- // CASESessionManager pointer when mDoCaseOnNextResub was true.
1137
+ // CASESessionManager pointer when mForceCaseOnNextResub was true.
1118
1138
//
1119
1139
// In that case, don't permit re-subscription to occur.
1120
1140
//
1121
- _this->Close (err, err != CHIP_ERROR_INCORRECT_STATE );
1141
+ _this->Close (err, allowResubscribeOnError );
1122
1142
}
1123
1143
}
1124
1144
0 commit comments