mirror of
https://github.com/espressif/openthread.git
synced 2026-06-05 21:14:49 +00:00
[coap] reorganize CoapBase::PendingRequests methods (#12577)
This commit moves all methods belonging to the `CoapBase::PendingRequests` class into a dedicated section in `coap.cpp`. Recent PRs #12421 and #12527 introduced this class and shifted many methods into it, but kept them in their original file locations to maintain reviewable `git` diffs. This update completes the reorganization for better code structure without any functional changes.
This commit is contained in:
committed by
GitHub
parent
69fffdb52d
commit
05ef3b4d04
+166
-160
@@ -464,80 +464,6 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void CoapBase::PendingRequests::HandleTimer(Timer &aTimer)
|
||||
{
|
||||
static_cast<PendingRequests *>(static_cast<TimerMilliContext &>(aTimer).GetContext())->HandleTimer();
|
||||
}
|
||||
|
||||
void CoapBase::PendingRequests::HandleTimer(void)
|
||||
{
|
||||
NextFireTime nextTime;
|
||||
MessageQueue expiredMessages;
|
||||
|
||||
for (Message &message : mRequestMessages)
|
||||
{
|
||||
Request request;
|
||||
|
||||
request.InitFrom(message);
|
||||
|
||||
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
|
||||
if (request.mMetadata.IsObserveSubscription())
|
||||
{
|
||||
// This is an RFC7641 subscription which is already
|
||||
// acknowledged. We do not time it out, so skip it when
|
||||
// determining the next fire time.
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (nextTime.GetNow() >= request.mMetadata.mTimerFireTime)
|
||||
{
|
||||
if (!request.mMetadata.ShouldRetransmit())
|
||||
{
|
||||
// We move the expired request to a separate queue to
|
||||
// finalize it after the loop. This ensures that the
|
||||
// iterator over `mRequestMessages` remains valid
|
||||
// even if the user callback (invoked during
|
||||
// finalization) modifies any pending requests
|
||||
|
||||
mRequestMessages.Dequeue(message);
|
||||
expiredMessages.Enqueue(message);
|
||||
continue;
|
||||
}
|
||||
|
||||
request.mMetadata.UpdateRetxCounterAndTimeout(nextTime.GetNow());
|
||||
request.WriteMetadataInMessage();
|
||||
|
||||
if (!request.mMetadata.mAcknowledged)
|
||||
{
|
||||
RetransmitRequest(request);
|
||||
}
|
||||
}
|
||||
|
||||
nextTime.UpdateIfEarlier(request.mMetadata.mTimerFireTime);
|
||||
}
|
||||
|
||||
mTimer.FireAt(nextTime);
|
||||
|
||||
FinalizeRemovedRequestsIn(expiredMessages, kErrorResponseTimeout);
|
||||
}
|
||||
|
||||
void CoapBase::PendingRequests::FinalizeRequest(Request &aRequest, Error aResult)
|
||||
{
|
||||
FinalizeRequest(aRequest, aResult, /* aResponse */ nullptr);
|
||||
}
|
||||
|
||||
void CoapBase::PendingRequests::FinalizeRequest(Request &aRequest, Error aResult, Msg *aResponse)
|
||||
{
|
||||
VerifyOrExit(aRequest.HasMessage());
|
||||
|
||||
Remove(aRequest);
|
||||
aRequest.mMetadata.mCallbacks.InvokeResponseHandler(aResponse, aResult);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
Error CoapBase::AbortTransaction(ResponseHandler aHandler, void *aContext)
|
||||
{
|
||||
return mPendingRequests.AbortRequestsMatching(aHandler, aContext);
|
||||
@@ -552,92 +478,6 @@ void CoapBase::GetRequestAndCachedResponsesQueueInfo(MessageQueue::Info &aQueueI
|
||||
MessageQueue::AddQueueInfos(aQueueInfo, info);
|
||||
}
|
||||
|
||||
Error CoapBase::PendingRequests::AddClone(const Message &aMessage, uint16_t aCopyLength, Request &aRequest)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
aRequest.mMessage = aMessage.Clone(aCopyLength);
|
||||
VerifyOrExit(aRequest.HasMessage(), error = kErrorNoBufs);
|
||||
|
||||
SuccessOrExit(error = aRequest.AppendMetadataToMessage());
|
||||
|
||||
mRequestMessages.Enqueue(*aRequest.mMessage);
|
||||
|
||||
mTimer.FireAtIfEarlier(aRequest.mMetadata.mTimerFireTime);
|
||||
|
||||
exit:
|
||||
FreeAndNullMessageOnError(aRequest.mMessage, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
void CoapBase::PendingRequests::Remove(Request &aRequest)
|
||||
{
|
||||
VerifyOrExit(aRequest.HasMessage());
|
||||
mRequestMessages.DequeueAndFree(*aRequest.mMessage);
|
||||
aRequest.Clear();
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void CoapBase::PendingRequests::RetransmitRequest(const Request &aRequest)
|
||||
{
|
||||
Error error;
|
||||
Message *clone;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
clone = aRequest.mMessage->Clone(aRequest.mMessage->GetLength() - sizeof(Request::Metadata));
|
||||
VerifyOrExit(clone != nullptr, error = kErrorNoBufs);
|
||||
|
||||
aRequest.mMetadata.CopyInfoTo(messageInfo);
|
||||
|
||||
SuccessOrExit(error = mCoapBase.Send(*clone, messageInfo));
|
||||
|
||||
exit:
|
||||
FreeMessageOnError(clone, error);
|
||||
}
|
||||
|
||||
Error CoapBase::PendingRequests::FindRelatedRequest(const Msg &aMsg, Request &aRequest)
|
||||
{
|
||||
Error error = kErrorNotFound;
|
||||
|
||||
for (Message &message : mRequestMessages)
|
||||
{
|
||||
aRequest.InitFrom(message);
|
||||
|
||||
if (aRequest.mMetadata.HasSamePeerAddrAndPort(aMsg.mMessageInfo) ||
|
||||
aRequest.mMetadata.mDestinationAddress.IsMulticast() ||
|
||||
aRequest.mMetadata.mDestinationAddress.GetIid().IsAnycastLocator())
|
||||
{
|
||||
switch (aMsg.GetType())
|
||||
{
|
||||
case kTypeReset:
|
||||
case kTypeAck:
|
||||
if (aMsg.GetMessageId() == message.ReadMessageId())
|
||||
{
|
||||
ExitNow(error = kErrorNone);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case kTypeConfirmable:
|
||||
case kTypeNonConfirmable:
|
||||
if (aMsg.mMessage.HasSameTokenAs(message))
|
||||
{
|
||||
ExitNow(error = kErrorNone);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aRequest.Clear();
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void CoapBase::Receive(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
Msg rxMsg(AsCoapMessage(&aMessage), aMessageInfo);
|
||||
@@ -1673,12 +1513,100 @@ bool CoapBase::Request::Metadata::IsObserveSubscription(void) const
|
||||
}
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// CoapBase::PendingRequests
|
||||
|
||||
CoapBase::PendingRequests::PendingRequests(Instance &aInstance, CoapBase &aCoapBase)
|
||||
: mCoapBase(aCoapBase)
|
||||
, mTimer(aInstance, HandleTimer, this)
|
||||
{
|
||||
}
|
||||
|
||||
Error CoapBase::PendingRequests::AddClone(const Message &aMessage, uint16_t aCopyLength, Request &aRequest)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
aRequest.mMessage = aMessage.Clone(aCopyLength);
|
||||
VerifyOrExit(aRequest.HasMessage(), error = kErrorNoBufs);
|
||||
|
||||
SuccessOrExit(error = aRequest.AppendMetadataToMessage());
|
||||
|
||||
mRequestMessages.Enqueue(*aRequest.mMessage);
|
||||
|
||||
mTimer.FireAtIfEarlier(aRequest.mMetadata.mTimerFireTime);
|
||||
|
||||
exit:
|
||||
FreeAndNullMessageOnError(aRequest.mMessage, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
void CoapBase::PendingRequests::Remove(Request &aRequest)
|
||||
{
|
||||
VerifyOrExit(aRequest.HasMessage());
|
||||
mRequestMessages.DequeueAndFree(*aRequest.mMessage);
|
||||
aRequest.Clear();
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
Error CoapBase::PendingRequests::FindRelatedRequest(const Msg &aMsg, Request &aRequest)
|
||||
{
|
||||
Error error = kErrorNotFound;
|
||||
|
||||
for (Message &message : mRequestMessages)
|
||||
{
|
||||
aRequest.InitFrom(message);
|
||||
|
||||
if (aRequest.mMetadata.HasSamePeerAddrAndPort(aMsg.mMessageInfo) ||
|
||||
aRequest.mMetadata.mDestinationAddress.IsMulticast() ||
|
||||
aRequest.mMetadata.mDestinationAddress.GetIid().IsAnycastLocator())
|
||||
{
|
||||
switch (aMsg.GetType())
|
||||
{
|
||||
case kTypeReset:
|
||||
case kTypeAck:
|
||||
if (aMsg.GetMessageId() == message.ReadMessageId())
|
||||
{
|
||||
ExitNow(error = kErrorNone);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case kTypeConfirmable:
|
||||
case kTypeNonConfirmable:
|
||||
if (aMsg.mMessage.HasSameTokenAs(message))
|
||||
{
|
||||
ExitNow(error = kErrorNone);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aRequest.Clear();
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void CoapBase::PendingRequests::FinalizeRequest(Request &aRequest, Error aResult)
|
||||
{
|
||||
FinalizeRequest(aRequest, aResult, /* aResponse */ nullptr);
|
||||
}
|
||||
|
||||
void CoapBase::PendingRequests::FinalizeRequest(Request &aRequest, Error aResult, Msg *aResponse)
|
||||
{
|
||||
VerifyOrExit(aRequest.HasMessage());
|
||||
|
||||
Remove(aRequest);
|
||||
aRequest.mMetadata.mCallbacks.InvokeResponseHandler(aResponse, aResult);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void CoapBase::PendingRequests::AbortAllRequests(void)
|
||||
{
|
||||
IgnoreError(AbortAllMatching(Matcher()));
|
||||
@@ -1732,6 +1660,84 @@ void CoapBase::PendingRequests::FinalizeRemovedRequestsIn(MessageQueue &aQueue,
|
||||
aQueue.DequeueAndFreeAll();
|
||||
}
|
||||
|
||||
void CoapBase::PendingRequests::RetransmitRequest(const Request &aRequest)
|
||||
{
|
||||
Error error;
|
||||
Message *clone;
|
||||
Ip6::MessageInfo messageInfo;
|
||||
|
||||
clone = aRequest.mMessage->Clone(aRequest.mMessage->GetLength() - sizeof(Request::Metadata));
|
||||
VerifyOrExit(clone != nullptr, error = kErrorNoBufs);
|
||||
|
||||
aRequest.mMetadata.CopyInfoTo(messageInfo);
|
||||
|
||||
SuccessOrExit(error = mCoapBase.Send(*clone, messageInfo));
|
||||
|
||||
exit:
|
||||
FreeMessageOnError(clone, error);
|
||||
}
|
||||
|
||||
void CoapBase::PendingRequests::HandleTimer(Timer &aTimer)
|
||||
{
|
||||
static_cast<PendingRequests *>(static_cast<TimerMilliContext &>(aTimer).GetContext())->HandleTimer();
|
||||
}
|
||||
|
||||
void CoapBase::PendingRequests::HandleTimer(void)
|
||||
{
|
||||
NextFireTime nextTime;
|
||||
MessageQueue expiredMessages;
|
||||
|
||||
for (Message &message : mRequestMessages)
|
||||
{
|
||||
Request request;
|
||||
|
||||
request.InitFrom(message);
|
||||
|
||||
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
|
||||
if (request.mMetadata.IsObserveSubscription())
|
||||
{
|
||||
// This is an RFC7641 subscription which is already
|
||||
// acknowledged. We do not time it out, so skip it when
|
||||
// determining the next fire time.
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (nextTime.GetNow() >= request.mMetadata.mTimerFireTime)
|
||||
{
|
||||
if (!request.mMetadata.ShouldRetransmit())
|
||||
{
|
||||
// We move the expired request to a separate queue to
|
||||
// finalize it after the loop. This ensures that the
|
||||
// iterator over `mRequestMessages` remains valid
|
||||
// even if the user callback (invoked during
|
||||
// finalization) modifies any pending requests
|
||||
|
||||
mRequestMessages.Dequeue(message);
|
||||
expiredMessages.Enqueue(message);
|
||||
continue;
|
||||
}
|
||||
|
||||
request.mMetadata.UpdateRetxCounterAndTimeout(nextTime.GetNow());
|
||||
request.WriteMetadataInMessage();
|
||||
|
||||
if (!request.mMetadata.mAcknowledged)
|
||||
{
|
||||
RetransmitRequest(request);
|
||||
}
|
||||
}
|
||||
|
||||
nextTime.UpdateIfEarlier(request.mMetadata.mTimerFireTime);
|
||||
}
|
||||
|
||||
mTimer.FireAt(nextTime);
|
||||
|
||||
FinalizeRemovedRequestsIn(expiredMessages, kErrorResponseTimeout);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// CoapBase::PendingRequests::Matcher
|
||||
|
||||
bool CoapBase::PendingRequests::Matcher::Matches(const Request &aRequest) const
|
||||
{
|
||||
bool matches = false;
|
||||
|
||||
Reference in New Issue
Block a user