mirror of
https://github.com/espressif/openthread.git
synced 2026-09-13 12:40:05 +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:
+42
-6
@@ -618,7 +618,7 @@ void CoapBase::ProcessReceivedResponse(Msg &aRxMsg)
|
|||||||
if (shouldObserve)
|
if (shouldObserve)
|
||||||
{
|
{
|
||||||
// This is a RFC7641 notification. The request is *not* done!
|
// This is a RFC7641 notification. The request is *not* done!
|
||||||
request.InvokeResponseHandler(&aRxMsg, kErrorNone);
|
mPendingRequests.DispatchResponse(request, kErrorNone, &aRxMsg);
|
||||||
|
|
||||||
request.MarkAsAcknowledged();
|
request.MarkAsAcknowledged();
|
||||||
ExitNow();
|
ExitNow();
|
||||||
@@ -648,7 +648,7 @@ void CoapBase::ProcessReceivedResponse(Msg &aRxMsg)
|
|||||||
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
|
#if OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE
|
||||||
if (shouldObserve)
|
if (shouldObserve)
|
||||||
{
|
{
|
||||||
request.InvokeResponseHandler(&aRxMsg, kErrorNone);
|
mPendingRequests.DispatchResponse(request, kErrorNone, &aRxMsg);
|
||||||
|
|
||||||
// When any Observe response is seen, consider a NON observe
|
// When any Observe response is seen, consider a NON observe
|
||||||
// request "acknowledged" at this point. This will keep the
|
// request "acknowledged" at this point. This will keep the
|
||||||
@@ -669,7 +669,7 @@ void CoapBase::ProcessReceivedResponse(Msg &aRxMsg)
|
|||||||
|
|
||||||
if (request.HasResponseHandler() && request.GetDestinationAddress().IsMulticast())
|
if (request.HasResponseHandler() && request.GetDestinationAddress().IsMulticast())
|
||||||
{
|
{
|
||||||
request.InvokeResponseHandler(&aRxMsg, kErrorNone);
|
mPendingRequests.DispatchResponse(request, kErrorNone, &aRxMsg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1535,6 +1535,7 @@ bool CoapBase::Request::IsObserveSubscription(void) const
|
|||||||
|
|
||||||
CoapBase::PendingRequests::PendingRequests(Instance &aInstance, CoapBase &aCoapBase)
|
CoapBase::PendingRequests::PendingRequests(Instance &aInstance, CoapBase &aCoapBase)
|
||||||
: mCoapBase(aCoapBase)
|
: mCoapBase(aCoapBase)
|
||||||
|
, mDispatchingRequest(nullptr)
|
||||||
, mTimer(aInstance, HandleTimer, this)
|
, mTimer(aInstance, HandleTimer, this)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -1632,13 +1633,48 @@ void CoapBase::PendingRequests::FinalizeRequest(Request &aRequest, Error aResult
|
|||||||
{
|
{
|
||||||
VerifyOrExit(aRequest.HasMessage());
|
VerifyOrExit(aRequest.HasMessage());
|
||||||
|
|
||||||
Remove(aRequest);
|
mRequestMessages.Dequeue(*aRequest.mMessage);
|
||||||
aRequest.InvokeResponseHandler(aResponse, aResult);
|
|
||||||
|
DispatchResponse(aRequest, aResult, aResponse);
|
||||||
|
|
||||||
|
aRequest.mMessage->Free();
|
||||||
|
aRequest.Clear();
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
return;
|
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)
|
void CoapBase::PendingRequests::AbortAllRequests(void)
|
||||||
{
|
{
|
||||||
IgnoreError(AbortAllMatching(Matcher()));
|
IgnoreError(AbortAllMatching(Matcher()));
|
||||||
@@ -1686,7 +1722,7 @@ void CoapBase::PendingRequests::FinalizeRemovedRequestsIn(MessageQueue &aQueue,
|
|||||||
Request request;
|
Request request;
|
||||||
|
|
||||||
request.InitFrom(message);
|
request.InitFrom(message);
|
||||||
request.InvokeResponseHandler(/* aResponse */ nullptr, aResult);
|
DispatchResponse(request, aResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
aQueue.DequeueAndFreeAll();
|
aQueue.DequeueAndFreeAll();
|
||||||
|
|||||||
+21
-4
@@ -571,6 +571,23 @@ public:
|
|||||||
*/
|
*/
|
||||||
Error SendMessage(OwnedPtr<Message> aMessage, const Ip6::MessageInfo &aMessageInfo);
|
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).
|
* Sends an empty CoAP message (using `kCodeEmpty` Code 0.00).
|
||||||
*
|
*
|
||||||
@@ -824,10 +841,6 @@ private:
|
|||||||
bool ShouldRetransmit(void) const;
|
bool ShouldRetransmit(void) const;
|
||||||
void UpdateRetxCounterAndTimeout(TimeMilli aNow);
|
void UpdateRetxCounterAndTimeout(TimeMilli aNow);
|
||||||
bool HasResponseHandler(void) const { return GetCallbacks().HasResponseHandler(); }
|
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 Message &GetMessage(void) const { return *mMessage; }
|
||||||
const Ip6::Address &GetSourceAddress(void) const { return mMetadata.mSourceAddress; }
|
const Ip6::Address &GetSourceAddress(void) const { return mMetadata.mSourceAddress; }
|
||||||
@@ -896,6 +909,9 @@ private:
|
|||||||
void AbortAllRequests(void);
|
void AbortAllRequests(void);
|
||||||
void AbortRequestsMatching(const Ip6::Address &aAddress);
|
void AbortRequestsMatching(const Ip6::Address &aAddress);
|
||||||
Error AbortRequestsMatching(ResponseHandler aHandler, void *aContext);
|
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); }
|
void GetInfo(MessageQueue::Info &aInfo) const { mRequestMessages.GetInfo(aInfo); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -935,6 +951,7 @@ private:
|
|||||||
|
|
||||||
CoapBase &mCoapBase;
|
CoapBase &mCoapBase;
|
||||||
MessageQueue mRequestMessages;
|
MessageQueue mRequestMessages;
|
||||||
|
const Request *mDispatchingRequest;
|
||||||
TimerMilliContext mTimer;
|
TimerMilliContext mTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user