mirror of
https://github.com/espressif/openthread.git
synced 2026-06-05 21:14:49 +00:00
[coap] add mechanism to access request message in response handler (#13081)
This commit updates `CoapBase::PendingRequests` to track the request currently being processed during callback invocation via the new `mDispatchingRequest` pointer. It also introduces `GetDispatchingRequest()` which returns a copy of the original request `Message`. This enables response handler callbacks to inspect the original request (for example to read specific TLVs). The method is restricted to confirmable requests and must only be called from within the context of a response handler. The method `InvokeResponseHandler` is renamed to `DispatchResponse` to align with the new nomenclature.
This commit is contained in:
committed by
GitHub
parent
0841be04fd
commit
c650cede5a
+42
-6
@@ -618,7 +618,7 @@ void CoapBase::ProcessReceivedResponse(Msg &aRxMsg)
|
||||
if (shouldObserve)
|
||||
{
|
||||
// This is a RFC7641 notification. The request is *not* done!
|
||||
request.InvokeResponseHandler(&aRxMsg, kErrorNone);
|
||||
mPendingRequests.DispatchResponse(request, kErrorNone, &aRxMsg);
|
||||
|
||||
request.MarkAsAcknowledged();
|
||||
ExitNow();
|
||||
@@ -648,7 +648,7 @@ void CoapBase::ProcessReceivedResponse(Msg &aRxMsg)
|
||||
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
|
||||
if (shouldObserve)
|
||||
{
|
||||
request.InvokeResponseHandler(&aRxMsg, kErrorNone);
|
||||
mPendingRequests.DispatchResponse(request, kErrorNone, &aRxMsg);
|
||||
|
||||
// When any Observe response is seen, consider a NON observe
|
||||
// request "acknowledged" at this point. This will keep the
|
||||
@@ -669,7 +669,7 @@ void CoapBase::ProcessReceivedResponse(Msg &aRxMsg)
|
||||
|
||||
if (request.HasResponseHandler() && request.GetDestinationAddress().IsMulticast())
|
||||
{
|
||||
request.InvokeResponseHandler(&aRxMsg, kErrorNone);
|
||||
mPendingRequests.DispatchResponse(request, kErrorNone, &aRxMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1535,6 +1535,7 @@ bool CoapBase::Request::IsObserveSubscription(void) const
|
||||
|
||||
CoapBase::PendingRequests::PendingRequests(Instance &aInstance, CoapBase &aCoapBase)
|
||||
: mCoapBase(aCoapBase)
|
||||
, mDispatchingRequest(nullptr)
|
||||
, mTimer(aInstance, HandleTimer, this)
|
||||
{
|
||||
}
|
||||
@@ -1632,13 +1633,48 @@ void CoapBase::PendingRequests::FinalizeRequest(Request &aRequest, Error aResult
|
||||
{
|
||||
VerifyOrExit(aRequest.HasMessage());
|
||||
|
||||
Remove(aRequest);
|
||||
aRequest.InvokeResponseHandler(aResponse, aResult);
|
||||
mRequestMessages.Dequeue(*aRequest.mMessage);
|
||||
|
||||
DispatchResponse(aRequest, aResult, aResponse);
|
||||
|
||||
aRequest.mMessage->Free();
|
||||
aRequest.Clear();
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void CoapBase::PendingRequests::DispatchResponse(Request &aRequest, Error aResult)
|
||||
{
|
||||
DispatchResponse(aRequest, aResult, /* aResponse */ nullptr);
|
||||
}
|
||||
|
||||
void CoapBase::PendingRequests::DispatchResponse(Request &aRequest, Error aResult, Msg *aResponse)
|
||||
{
|
||||
const Request *prev = mDispatchingRequest;
|
||||
|
||||
mDispatchingRequest = &aRequest;
|
||||
aRequest.GetCallbacks().InvokeResponseHandler(aResponse, aResult);
|
||||
mDispatchingRequest = prev;
|
||||
}
|
||||
|
||||
Error CoapBase::PendingRequests::GetDispatchingRequest(OwnedPtr<Message> &aMessage) const
|
||||
{
|
||||
Error error = kErrorNotFound;
|
||||
|
||||
VerifyOrExit(mDispatchingRequest != nullptr);
|
||||
VerifyOrExit(mDispatchingRequest->IsConfirmable());
|
||||
VerifyOrExit(mDispatchingRequest->HasMessage());
|
||||
|
||||
aMessage.Reset(mCoapBase.CloneMessageWithout<Request::Metadata>(mDispatchingRequest->GetMessage()));
|
||||
VerifyOrExit(aMessage != nullptr, error = kErrorNoBufs);
|
||||
|
||||
error = kErrorNone;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void CoapBase::PendingRequests::AbortAllRequests(void)
|
||||
{
|
||||
IgnoreError(AbortAllMatching(Matcher()));
|
||||
@@ -1686,7 +1722,7 @@ void CoapBase::PendingRequests::FinalizeRemovedRequestsIn(MessageQueue &aQueue,
|
||||
Request request;
|
||||
|
||||
request.InitFrom(message);
|
||||
request.InvokeResponseHandler(/* aResponse */ nullptr, aResult);
|
||||
DispatchResponse(request, aResult);
|
||||
}
|
||||
|
||||
aQueue.DequeueAndFreeAll();
|
||||
|
||||
+21
-4
@@ -571,6 +571,23 @@ public:
|
||||
*/
|
||||
Error SendMessage(OwnedPtr<Message> aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
|
||||
/**
|
||||
* Gets a copy of the request message currently being dispatched (`ResponseHandler` callback is invoked).
|
||||
*
|
||||
* This method can only be used from a `ResponseHandler` callback. It returns a copy of the original request
|
||||
* message if the request was confirmable.
|
||||
*
|
||||
* @param[out] aMessage A reference to an `OwnedPtr` to return a copy of original request message.
|
||||
*
|
||||
* @retval kErrorNone Successfully retrieved and cloned the request message.
|
||||
* @retval kErrorNotFound Not currently dispatching a confirmable request.
|
||||
* @retval kErrorNoBufs Failed to allocate a message for the clone.
|
||||
*/
|
||||
Error GetDispatchingRequest(OwnedPtr<Message> &aMessage) const
|
||||
{
|
||||
return mPendingRequests.GetDispatchingRequest(aMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an empty CoAP message (using `kCodeEmpty` Code 0.00).
|
||||
*
|
||||
@@ -824,10 +841,6 @@ private:
|
||||
bool ShouldRetransmit(void) const;
|
||||
void UpdateRetxCounterAndTimeout(TimeMilli aNow);
|
||||
bool HasResponseHandler(void) const { return GetCallbacks().HasResponseHandler(); }
|
||||
void InvokeResponseHandler(Msg *aMsg, Error aResult) const
|
||||
{
|
||||
GetCallbacks().InvokeResponseHandler(aMsg, aResult);
|
||||
}
|
||||
|
||||
const Message &GetMessage(void) const { return *mMessage; }
|
||||
const Ip6::Address &GetSourceAddress(void) const { return mMetadata.mSourceAddress; }
|
||||
@@ -896,6 +909,9 @@ private:
|
||||
void AbortAllRequests(void);
|
||||
void AbortRequestsMatching(const Ip6::Address &aAddress);
|
||||
Error AbortRequestsMatching(ResponseHandler aHandler, void *aContext);
|
||||
void DispatchResponse(Request &aRequest, Error aResult, Msg *aResponse);
|
||||
void DispatchResponse(Request &aRequest, Error aResult);
|
||||
Error GetDispatchingRequest(OwnedPtr<Message> &aMessage) const;
|
||||
void GetInfo(MessageQueue::Info &aInfo) const { mRequestMessages.GetInfo(aInfo); }
|
||||
|
||||
private:
|
||||
@@ -935,6 +951,7 @@ private:
|
||||
|
||||
CoapBase &mCoapBase;
|
||||
MessageQueue mRequestMessages;
|
||||
const Request *mDispatchingRequest;
|
||||
TimerMilliContext mTimer;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user