diff --git a/src/core/api/coap_api.cpp b/src/core/api/coap_api.cpp index 85be09a79..9844ead9e 100644 --- a/src/core/api/coap_api.cpp +++ b/src/core/api/coap_api.cpp @@ -206,7 +206,7 @@ otError otCoapSendRequestWithParameters(otInstance * aInstance, return instance.GetApplicationCoap().SendMessage(*static_cast(aMessage), *static_cast(aMessageInfo), - Coap::CoapTxParameters::From(aTxParameters), aHandler, aContext); + Coap::TxParameters::From(aTxParameters), aHandler, aContext); } otError otCoapStart(otInstance *aInstance, uint16_t aPort) @@ -253,7 +253,7 @@ otError otCoapSendResponseWithParameters(otInstance * aInstance, return instance.GetApplicationCoap().SendMessage(*static_cast(aMessage), *static_cast(aMessageInfo), - Coap::CoapTxParameters::From(aTxParameters), NULL, NULL); + Coap::TxParameters::From(aTxParameters), NULL, NULL); } #endif // OPENTHREAD_CONFIG_COAP_API_ENABLE diff --git a/src/core/coap/coap.cpp b/src/core/coap/coap.cpp index 9b3f86753..f700df8cd 100644 --- a/src/core/coap/coap.cpp +++ b/src/core/coap/coap.cpp @@ -48,6 +48,8 @@ namespace Coap { CoapBase::CoapBase(Instance &aInstance, Sender aSender) : InstanceLocator(aInstance) + , mPendingRequests() + , mMessageId(Random::NonCrypto::GetUint16()) , mRetransmissionTimer(aInstance, &Coap::HandleRetransmissionTimer, this) , mResources() , mContext(NULL) @@ -57,42 +59,33 @@ CoapBase::CoapBase(Instance &aInstance, Sender aSender) , mDefaultHandlerContext(NULL) , mSender(aSender) { - mMessageId = Random::NonCrypto::GetUint16(); } void CoapBase::ClearRequestsAndResponses(void) { - Message * message = static_cast(mPendingRequests.GetHead()); - Message * messageToRemove; - CoapMetadata coapMetadata; - - // Remove all pending messages. - while (message != NULL) - { - messageToRemove = message; - message = static_cast(message->GetNext()); - - coapMetadata.ReadFrom(*messageToRemove); - FinalizeCoapTransaction(*messageToRemove, coapMetadata, NULL, NULL, OT_ERROR_ABORT); - } - + ClearRequests(NULL); // Clear requests matching any address. mResponsesQueue.DequeueAllResponses(); } void CoapBase::ClearRequests(const Ip6::Address &aAddress) +{ + ClearRequests(&aAddress); +} + +void CoapBase::ClearRequests(const Ip6::Address *aAddress) { Message *nextMessage; - // Remove pending messages with the specified source. for (Message *message = static_cast(mPendingRequests.GetHead()); message != NULL; message = nextMessage) { - CoapMetadata coapMetadata; - nextMessage = static_cast(message->GetNext()); - coapMetadata.ReadFrom(*message); + Metadata metadata; - if (coapMetadata.mSourceAddress == aAddress) + nextMessage = static_cast(message->GetNext()); + metadata.ReadFrom(*message); + + if ((aAddress == NULL) || (metadata.mSourceAddress == *aAddress)) { - FinalizeCoapTransaction(*message, coapMetadata, NULL, NULL, OT_ERROR_ABORT); + FinalizeCoapTransaction(*message, metadata, NULL, NULL, OT_ERROR_ABORT); } } } @@ -108,12 +101,18 @@ void CoapBase::RemoveResource(Resource &aResource) aResource.SetNext(NULL); } -void CoapBase::SetDefaultHandler(otCoapRequestHandler aHandler, void *aContext) +void CoapBase::SetDefaultHandler(RequestHandler aHandler, void *aContext) { mDefaultHandler = aHandler; mDefaultHandlerContext = aContext; } +void CoapBase::SetInterceptor(Interceptor aInterceptor, void *aContext) +{ + mInterceptor = aInterceptor; + mContext = aContext; +} + Message *CoapBase::NewMessage(const otMessageSettings *aSettings) { Message *message = NULL; @@ -125,10 +124,15 @@ exit: return message; } +otError CoapBase::Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) +{ + return mSender(*this, aMessage, aMessageInfo); +} + otError CoapBase::SendMessage(Message & aMessage, const Ip6::MessageInfo &aMessageInfo, - const CoapTxParameters &aTxParameters, - otCoapResponseHandler aHandler, + const TxParameters & aTxParameters, + ResponseHandler aHandler, void * aContext) { otError error; @@ -152,21 +156,22 @@ otError CoapBase::SendMessage(Message & aMessage, if (aMessage.IsConfirmable()) { - // Create a copy of entire message and enqueue it. copyLength = aMessage.GetLength(); } else if (aMessage.IsNonConfirmable() && (aHandler != NULL)) { - // As we do not retransmit non confirmable messages, create a copy of header only, for token information. + // As we do not retransmit non confirmable messages, create a + // copy of header only, for token information. copyLength = aMessage.GetOptionStart(); } if (copyLength > 0) { - CoapMetadata coapMetadata = - CoapMetadata(aMessage.IsConfirmable(), aMessageInfo, aHandler, aContext, aTxParameters); - VerifyOrExit((storedCopy = CopyAndEnqueueMessage(aMessage, copyLength, coapMetadata)) != NULL, - error = OT_ERROR_NO_BUFS); + Metadata metadata; + + metadata.Init(aMessage.IsConfirmable(), aMessageInfo, aHandler, aContext, aTxParameters); + storedCopy = CopyAndEnqueueMessage(aMessage, copyLength, metadata); + VerifyOrExit(storedCopy != NULL, error = OT_ERROR_NO_BUFS); } SuccessOrExit(error = Send(aMessage, aMessageInfo)); @@ -181,6 +186,36 @@ exit: return error; } +otError CoapBase::SendMessage(Message & aMessage, + const Ip6::MessageInfo &aMessageInfo, + ResponseHandler aHandler, + void * aContext) +{ + return SendMessage(aMessage, aMessageInfo, TxParameters::GetDefault(), aHandler, aContext); +} + +otError CoapBase::SendReset(Message &aRequest, const Ip6::MessageInfo &aMessageInfo) +{ + return SendEmptyMessage(OT_COAP_TYPE_RESET, aRequest, aMessageInfo); +} + +otError CoapBase::SendAck(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo) +{ + return SendEmptyMessage(OT_COAP_TYPE_ACKNOWLEDGMENT, aRequest, aMessageInfo); +} + +otError CoapBase::SendEmptyAck(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo) +{ + return (aRequest.GetType() == OT_COAP_TYPE_CONFIRMABLE + ? SendHeaderResponse(OT_COAP_CODE_CHANGED, aRequest, aMessageInfo) + : OT_ERROR_INVALID_ARGS); +} + +otError CoapBase::SendNotFound(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo) +{ + return SendHeaderResponse(OT_COAP_CODE_NOT_FOUND, aRequest, aMessageInfo); +} + otError CoapBase::SendEmptyMessage(Message::Type aType, const Message &aRequest, const Ip6::MessageInfo &aMessageInfo) { otError error = OT_ERROR_NONE; @@ -253,46 +288,45 @@ void CoapBase::HandleRetransmissionTimer(void) { TimeMilli now = TimerMilli::GetNow(); TimeMilli nextTime = now.GetDistantFuture(); - CoapMetadata coapMetadata; - Message * message; + Metadata metadata; Message * nextMessage; Ip6::MessageInfo messageInfo; - for (message = static_cast(mPendingRequests.GetHead()); message != NULL; message = nextMessage) + for (Message *message = static_cast(mPendingRequests.GetHead()); message != NULL; message = nextMessage) { nextMessage = static_cast(message->GetNext()); - coapMetadata.ReadFrom(*message); + metadata.ReadFrom(*message); - if (now >= coapMetadata.mNextTimerShot) + if (now >= metadata.mNextTimerShot) { - if (!coapMetadata.mConfirmable || (coapMetadata.mRetransmissionsRemaining == 0)) + if (!metadata.mConfirmable || (metadata.mRetransmissionsRemaining == 0)) { // No expected response or acknowledgment. - FinalizeCoapTransaction(*message, coapMetadata, NULL, NULL, OT_ERROR_RESPONSE_TIMEOUT); + FinalizeCoapTransaction(*message, metadata, NULL, NULL, OT_ERROR_RESPONSE_TIMEOUT); continue; } // Increment retransmission counter and timer. - coapMetadata.mRetransmissionsRemaining--; - coapMetadata.mRetransmissionTimeout *= 2; - coapMetadata.mNextTimerShot = now + coapMetadata.mRetransmissionTimeout; - coapMetadata.UpdateIn(*message); + metadata.mRetransmissionsRemaining--; + metadata.mRetransmissionTimeout *= 2; + metadata.mNextTimerShot = now + metadata.mRetransmissionTimeout; + metadata.UpdateIn(*message); // Retransmit - if (!coapMetadata.mAcknowledged) + if (!metadata.mAcknowledged) { - messageInfo.SetPeerAddr(coapMetadata.mDestinationAddress); - messageInfo.SetPeerPort(coapMetadata.mDestinationPort); - messageInfo.SetSockAddr(coapMetadata.mSourceAddress); + messageInfo.SetPeerAddr(metadata.mDestinationAddress); + messageInfo.SetPeerPort(metadata.mDestinationPort); + messageInfo.SetSockAddr(metadata.mSourceAddress); SendCopy(*message, messageInfo); } } - if (nextTime > coapMetadata.mNextTimerShot) + if (nextTime > metadata.mNextTimerShot) { - nextTime = coapMetadata.mNextTimerShot; + nextTime = metadata.mNextTimerShot; } } @@ -303,34 +337,33 @@ void CoapBase::HandleRetransmissionTimer(void) } void CoapBase::FinalizeCoapTransaction(Message & aRequest, - const CoapMetadata & aCoapMetadata, + const Metadata & aMetadata, Message * aResponse, const Ip6::MessageInfo *aMessageInfo, otError aResult) { DequeueMessage(aRequest); - if (aCoapMetadata.mResponseHandler != NULL) + if (aMetadata.mResponseHandler != NULL) { - aCoapMetadata.mResponseHandler(aCoapMetadata.mResponseContext, aResponse, aMessageInfo, aResult); + aMetadata.mResponseHandler(aMetadata.mResponseContext, aResponse, aMessageInfo, aResult); } } -otError CoapBase::AbortTransaction(otCoapResponseHandler aHandler, void *aContext) +otError CoapBase::AbortTransaction(ResponseHandler aHandler, void *aContext) { - otError error = OT_ERROR_NOT_FOUND; - Message * message; - Message * nextMessage; - CoapMetadata coapMetadata; + otError error = OT_ERROR_NOT_FOUND; + Message *nextMessage; + Metadata metadata; - for (message = static_cast(mPendingRequests.GetHead()); message != NULL; message = nextMessage) + for (Message *message = static_cast(mPendingRequests.GetHead()); message != NULL; message = nextMessage) { nextMessage = static_cast(message->GetNext()); - coapMetadata.ReadFrom(*message); + metadata.ReadFrom(*message); - if (coapMetadata.mResponseHandler == aHandler && coapMetadata.mResponseContext == aContext) + if (metadata.mResponseHandler == aHandler && metadata.mResponseContext == aContext) { - FinalizeCoapTransaction(*message, coapMetadata, NULL, NULL, OT_ERROR_ABORT); + FinalizeCoapTransaction(*message, metadata, NULL, NULL, OT_ERROR_ABORT); error = OT_ERROR_NONE; } } @@ -338,22 +371,17 @@ otError CoapBase::AbortTransaction(otCoapResponseHandler aHandler, void *aContex return error; } -Message *CoapBase::CopyAndEnqueueMessage(const Message & aMessage, - uint16_t aCopyLength, - const CoapMetadata &aCoapMetadata) +Message *CoapBase::CopyAndEnqueueMessage(const Message &aMessage, uint16_t aCopyLength, const Metadata &aMetadata) { otError error = OT_ERROR_NONE; Message *messageCopy = NULL; - // Create a message copy of requested size. VerifyOrExit((messageCopy = aMessage.Clone(aCopyLength)) != NULL, error = OT_ERROR_NO_BUFS); - // Append the copy with retransmission data. - SuccessOrExit(error = aCoapMetadata.AppendTo(*messageCopy)); + SuccessOrExit(error = aMetadata.AppendTo(*messageCopy)); - mRetransmissionTimer.FireAtIfEarlier(aCoapMetadata.mNextTimerShot); + mRetransmissionTimer.FireAtIfEarlier(aMetadata.mNextTimerShot); - // Enqueue the message. mPendingRequests.Enqueue(*messageCopy); exit: @@ -373,11 +401,9 @@ void CoapBase::DequeueMessage(Message &aMessage) if (mRetransmissionTimer.IsRunning() && (mPendingRequests.GetHead() == NULL)) { - // No more requests pending, stop the timer. mRetransmissionTimer.Stop(); } - // Free the message memory. aMessage.Free(); // No need to worry that the earliest pending message was removed - @@ -390,10 +416,9 @@ otError CoapBase::SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMes Message *messageCopy = NULL; // Create a message copy for lower layers. - VerifyOrExit((messageCopy = aMessage.Clone(aMessage.GetLength() - sizeof(CoapMetadata))) != NULL, - error = OT_ERROR_NO_BUFS); + messageCopy = aMessage.Clone(aMessage.GetLength() - sizeof(Metadata)); + VerifyOrExit(messageCopy != NULL, error = OT_ERROR_NO_BUFS); - // Send the copy. SuccessOrExit(error = Send(*messageCopy, aMessageInfo)); exit: @@ -408,18 +433,18 @@ exit: Message *CoapBase::FindRelatedRequest(const Message & aResponse, const Ip6::MessageInfo &aMessageInfo, - CoapMetadata & aCoapMetadata) + Metadata & aMetadata) { - Message *message = static_cast(mPendingRequests.GetHead()); + Message *message; - while (message != NULL) + for (message = static_cast(mPendingRequests.GetHead()); message != NULL; + message = static_cast(message->GetNext())) { - aCoapMetadata.ReadFrom(*message); + aMetadata.ReadFrom(*message); - if (((aCoapMetadata.mDestinationAddress == aMessageInfo.GetPeerAddr()) || - aCoapMetadata.mDestinationAddress.IsMulticast() || - aCoapMetadata.mDestinationAddress.IsAnycastRoutingLocator()) && - (aCoapMetadata.mDestinationPort == aMessageInfo.GetPeerPort())) + if (((aMetadata.mDestinationAddress == aMessageInfo.GetPeerAddr()) || + aMetadata.mDestinationAddress.IsMulticast() || aMetadata.mDestinationAddress.IsAnycastRoutingLocator()) && + (aMetadata.mDestinationPort == aMessageInfo.GetPeerPort())) { switch (aResponse.GetType()) { @@ -442,8 +467,6 @@ Message *CoapBase::FindRelatedRequest(const Message & aResponse, break; } } - - message = static_cast(message->GetNext()); } exit: @@ -475,23 +498,19 @@ void CoapBase::Receive(ot::Message &aMessage, const Ip6::MessageInfo &aMessageIn void CoapBase::ProcessReceivedResponse(Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { - CoapMetadata coapMetadata; - Message * request = NULL; - otError error = OT_ERROR_NONE; + Metadata metadata; + Message *request = NULL; + otError error = OT_ERROR_NONE; - request = FindRelatedRequest(aMessage, aMessageInfo, coapMetadata); - - if (request == NULL) - { - ExitNow(); - } + request = FindRelatedRequest(aMessage, aMessageInfo, metadata); + VerifyOrExit(request != NULL); switch (aMessage.GetType()) { case OT_COAP_TYPE_RESET: if (aMessage.IsEmpty()) { - FinalizeCoapTransaction(*request, coapMetadata, NULL, NULL, OT_ERROR_ABORT); + FinalizeCoapTransaction(*request, metadata, NULL, NULL, OT_ERROR_ABORT); } // Silently ignore non-empty reset messages (RFC 7252, p. 4.2). @@ -501,14 +520,14 @@ void CoapBase::ProcessReceivedResponse(Message &aMessage, const Ip6::MessageInfo if (aMessage.IsEmpty()) { // Empty acknowledgment. - if (coapMetadata.mConfirmable) + if (metadata.mConfirmable) { - coapMetadata.mAcknowledged = true; - coapMetadata.UpdateIn(*request); + metadata.mAcknowledged = true; + metadata.UpdateIn(*request); } // Remove the message if response is not expected, otherwise await response. - if (coapMetadata.mResponseHandler == NULL) + if (metadata.mResponseHandler == NULL) { DequeueMessage(*request); } @@ -516,7 +535,7 @@ void CoapBase::ProcessReceivedResponse(Message &aMessage, const Ip6::MessageInfo else if (aMessage.IsResponse() && aMessage.IsTokenEqual(*request)) { // Piggybacked response. - FinalizeCoapTransaction(*request, coapMetadata, &aMessage, &aMessageInfo, OT_ERROR_NONE); + FinalizeCoapTransaction(*request, metadata, &aMessage, &aMessageInfo, OT_ERROR_NONE); } // Silently ignore acknowledgments carrying requests (RFC 7252, p. 4.2) @@ -526,20 +545,20 @@ void CoapBase::ProcessReceivedResponse(Message &aMessage, const Ip6::MessageInfo case OT_COAP_TYPE_CONFIRMABLE: // Send empty ACK if it is a CON message. SendAck(aMessage, aMessageInfo); - FinalizeCoapTransaction(*request, coapMetadata, &aMessage, &aMessageInfo, OT_ERROR_NONE); + FinalizeCoapTransaction(*request, metadata, &aMessage, &aMessageInfo, OT_ERROR_NONE); break; case OT_COAP_TYPE_NON_CONFIRMABLE: // Separate response. - if (coapMetadata.mDestinationAddress.IsMulticast() && coapMetadata.mResponseHandler != NULL) + if (metadata.mDestinationAddress.IsMulticast() && metadata.mResponseHandler != NULL) { // If multicast non-confirmable request, allow multiple responses - coapMetadata.mResponseHandler(coapMetadata.mResponseContext, &aMessage, &aMessageInfo, OT_ERROR_NONE); + metadata.mResponseHandler(metadata.mResponseContext, &aMessage, &aMessageInfo, OT_ERROR_NONE); } else { - FinalizeCoapTransaction(*request, coapMetadata, &aMessage, &aMessageInfo, OT_ERROR_NONE); + FinalizeCoapTransaction(*request, metadata, &aMessage, &aMessageInfo, OT_ERROR_NONE); } break; @@ -551,7 +570,8 @@ exit: { if (aMessage.IsConfirmable() || aMessage.IsNonConfirmable()) { - // Successfully parsed a header but no matching request was found - reject the message by sending reset. + // Successfully parsed a header but no matching request was + // found - reject the message by sending reset. SendReset(aMessage, aMessageInfo); } } @@ -575,8 +595,8 @@ void CoapBase::ProcessReceivedRequest(Message &aMessage, const Ip6::MessageInfo case OT_ERROR_NONE: cachedResponse->Finish(); error = Send(*cachedResponse, aMessageInfo); + // fall through - ; case OT_ERROR_NO_BUFS: ExitNow(); @@ -644,11 +664,11 @@ exit: } } -CoapMetadata::CoapMetadata(bool aConfirmable, - const Ip6::MessageInfo &aMessageInfo, - otCoapResponseHandler aHandler, - void * aContext, - const CoapTxParameters &aTxParameters) +void CoapBase::Metadata::Init(bool aConfirmable, + const Ip6::MessageInfo &aMessageInfo, + ResponseHandler aHandler, + void * aContext, + const TxParameters & aTxParameters) { mSourceAddress = aMessageInfo.GetSockAddr(); mDestinationPort = aMessageInfo.GetPeerPort(); @@ -657,20 +677,23 @@ CoapMetadata::CoapMetadata(bool aConfirmable, mResponseContext = aContext; mRetransmissionsRemaining = aTxParameters.mMaxRetransmit; mRetransmissionTimeout = aTxParameters.CalculateInitialRetransmissionTimeout(); + mAcknowledged = false; + mConfirmable = aConfirmable; + mNextTimerShot = + TimerMilli::GetNow() + (aConfirmable ? mRetransmissionTimeout : aTxParameters.CalculateMaxTransmitWait()); +} - if (aConfirmable) - { - // Set next retransmission timeout. - mNextTimerShot = TimerMilli::GetNow() + mRetransmissionTimeout; - } - else - { - // Set overall response timeout. - mNextTimerShot = TimerMilli::GetNow() + aTxParameters.CalculateMaxTransmitWait(); - } +void CoapBase::Metadata::ReadFrom(const Message &aMessage) +{ + uint16_t length = aMessage.GetLength(); - mAcknowledged = false; - mConfirmable = aConfirmable; + assert(length >= sizeof(*this)); + aMessage.Read(length - sizeof(*this), sizeof(*this), this); +} + +int CoapBase::Metadata::UpdateIn(Message &aMessage) const +{ + return aMessage.Write(aMessage.GetLength() - sizeof(*this), sizeof(*this), this); } ResponsesQueue::ResponsesQueue(Instance &aInstance) @@ -689,7 +712,7 @@ otError ResponsesQueue::GetMatchedResponseCopy(const Message & aRequest, cacheResponse = FindMatchedResponse(aRequest, aMessageInfo); VerifyOrExit(cacheResponse != NULL, error = OT_ERROR_NOT_FOUND); - *aResponse = cacheResponse->Clone(cacheResponse->GetLength() - sizeof(EnqueuedResponseHeader)); + *aResponse = cacheResponse->Clone(cacheResponse->GetLength() - sizeof(ResponseMetadata)); VerifyOrExit(*aResponse != NULL, error = OT_ERROR_NO_BUFS); exit: @@ -698,54 +721,42 @@ exit: const Message *ResponsesQueue::FindMatchedResponse(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo) const { - Message *matchedResponse = NULL; + Message *message; - for (Message *message = static_cast(mQueue.GetHead()); message != NULL; - message = static_cast(message->GetNext())) + for (message = static_cast(mQueue.GetHead()); message != NULL; + message = static_cast(message->GetNext())) { - EnqueuedResponseHeader enqueuedResponseHeader; - Ip6::MessageInfo messageInfo; - - enqueuedResponseHeader.ReadFrom(*message); - messageInfo = enqueuedResponseHeader.GetMessageInfo(); - - // Check source endpoint - if (messageInfo.GetPeerPort() != aMessageInfo.GetPeerPort()) + if (message->GetMessageId() == aRequest.GetMessageId()) { - continue; - } + ResponseMetadata metadata; - if (messageInfo.GetPeerAddr() != aMessageInfo.GetPeerAddr()) - { - continue; - } + metadata.ReadFrom(*message); - // Check Message Id - if (message->GetMessageId() != aRequest.GetMessageId()) - { - continue; + if ((metadata.mMessageInfo.GetPeerPort() == aMessageInfo.GetPeerPort()) && + (metadata.mMessageInfo.GetPeerAddr() == aMessageInfo.GetPeerAddr())) + { + break; + } } - - ExitNow(matchedResponse = message); } -exit: - return matchedResponse; + return message; } void ResponsesQueue::EnqueueResponse(Message & aMessage, const Ip6::MessageInfo &aMessageInfo, - const CoapTxParameters &aTxParameters) + const TxParameters & aTxParameters) { - otError error = OT_ERROR_NONE; - Message * responseCopy = NULL; - uint16_t messageCount; - uint16_t bufferCount; - uint32_t exchangeLifetime = aTxParameters.CalculateExchangeLifetime(); - TimeMilli dequeueTime = TimerMilli::GetNow() + exchangeLifetime; - EnqueuedResponseHeader enqueuedResponseHeader(dequeueTime, aMessageInfo); + otError error = OT_ERROR_NONE; + Message * responseCopy = NULL; + uint16_t messageCount; + uint16_t bufferCount; + uint32_t exchangeLifetime = aTxParameters.CalculateExchangeLifetime(); + ResponseMetadata metadata; - // return success if matched response already exists in the cache + metadata.Init(TimerMilli::GetNow() + exchangeLifetime, aMessageInfo); + + // Return success if matched response already exists in the cache. VerifyOrExit(FindMatchedResponse(aMessage, aMessageInfo) == NULL); mQueue.GetInfo(messageCount, bufferCount); @@ -757,7 +768,7 @@ void ResponsesQueue::EnqueueResponse(Message & aMessage, VerifyOrExit((responseCopy = aMessage.Clone()) != NULL); - SuccessOrExit(error = enqueuedResponseHeader.AppendTo(*responseCopy)); + SuccessOrExit(error = metadata.AppendTo(*responseCopy)); mQueue.Enqueue(*responseCopy); if (!mTimer.IsRunning()) @@ -775,6 +786,12 @@ exit: return; } +void ResponsesQueue::DequeueResponse(Message &aMessage) +{ + mQueue.Dequeue(aMessage); + aMessage.Free(); +} + void ResponsesQueue::DequeueOldestResponse(void) { Message *message; @@ -803,59 +820,70 @@ void ResponsesQueue::HandleTimer(Timer &aTimer) void ResponsesQueue::HandleTimer(void) { - Message * message; - EnqueuedResponseHeader enqueuedResponseHeader; + Message * message; + ResponseMetadata metadata; while ((message = static_cast(mQueue.GetHead())) != NULL) { - enqueuedResponseHeader.ReadFrom(*message); + metadata.ReadFrom(*message); - if (TimerMilli::GetNow() >= enqueuedResponseHeader.mDequeueTime) + if (TimerMilli::GetNow() >= metadata.mDequeueTime) { DequeueResponse(*message); } else { - mTimer.Start(enqueuedResponseHeader.GetRemainingTime()); + mTimer.Start(metadata.GetRemainingTime()); break; } } } -uint32_t EnqueuedResponseHeader::GetRemainingTime(void) const +void ResponsesQueue::ResponseMetadata::Init(TimeMilli aDequeueTime, const Ip6::MessageInfo &aMessageInfo) { - TimeMilli now = TimerMilli::GetNow(); - uint32_t remainingTime = 0; - - if (mDequeueTime > now) - { - remainingTime = mDequeueTime - now; - } - - return remainingTime; + mDequeueTime = aDequeueTime; + mMessageInfo = aMessageInfo; } -uint32_t CoapTxParameters::CalculateInitialRetransmissionTimeout(void) const +void ResponsesQueue::ResponseMetadata::ReadFrom(const Message &aMessage) +{ + uint16_t length = aMessage.GetLength(); + + assert(length >= sizeof(*this)); + aMessage.Read(length - sizeof(*this), sizeof(*this), this); +} + +uint32_t ResponsesQueue::ResponseMetadata::GetRemainingTime(void) const +{ + TimeMilli now = TimerMilli::GetNow(); + + return (mDequeueTime > now) ? mDequeueTime - now : 0; +} + +uint32_t TxParameters::CalculateInitialRetransmissionTimeout(void) const { return Random::NonCrypto::GetUint32InRange( mAckTimeout, mAckTimeout * mAckRandomFactorNumerator / mAckRandomFactorDenominator + 1); } -uint32_t CoapTxParameters::CalculateExchangeLifetime(void) const +uint32_t TxParameters::CalculateExchangeLifetime(void) const { - uint32_t maxTransmitSpan = static_cast(mAckTimeout * ((1ULL << mMaxRetransmit) - 1) * - mAckRandomFactorNumerator / mAckRandomFactorDenominator); - uint32_t processingDelay = mAckTimeout; - return maxTransmitSpan + 2 * kDefaultMaxLatency + processingDelay; + // Final `mAckTimeout` is to account for processing delay. + return CalculateSpan(mMaxRetransmit) + 2 * kDefaultMaxLatency + mAckTimeout; } -uint32_t CoapTxParameters::CalculateMaxTransmitWait(void) const +uint32_t TxParameters::CalculateMaxTransmitWait(void) const { - return static_cast(mAckTimeout * ((2ULL << mMaxRetransmit) - 1) * mAckRandomFactorNumerator / + return CalculateSpan(mMaxRetransmit + 1); +} + +uint32_t TxParameters::CalculateSpan(uint32_t aMaxRetx) const +{ + return static_cast(mAckTimeout * ((1ULL << aMaxRetx) - 1) * mAckRandomFactorNumerator / mAckRandomFactorDenominator); } -const otCoapTxParameters CoapTxParameters::kDefaultTxParameters = { +const otCoapTxParameters TxParameters::kDefaultTxParameters = { kDefaultAckTimeout, kDefaultAckRandomFactorNumerator, kDefaultAckRandomFactorDenominator, @@ -898,6 +926,11 @@ void Coap::HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessage *static_cast(aMessageInfo)); } +otError Coap::Send(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) +{ + return static_cast(aCoapBase).Send(aMessage, aMessageInfo); +} + otError Coap::Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { return mSocket.IsBound() ? mSocket.SendTo(aMessage, aMessageInfo) : OT_ERROR_INVALID_STATE; diff --git a/src/core/coap/coap.hpp b/src/core/coap/coap.hpp index ffdf97c5d..bde7aa62a 100644 --- a/src/core/coap/coap.hpp +++ b/src/core/coap/coap.hpp @@ -59,141 +59,75 @@ namespace Coap { * */ -class CoapTxParameters : public otCoapTxParameters +/** + * This type represents a function pointer which is called when a CoAP response is received or on the request timeout. + * + * Please see otCoapResponseHandler for details. + * + */ +typedef otCoapResponseHandler ResponseHandler; + +/** + * This type represents a function pointer which is called when a CoAP request associated with a given URI path is + * received. + * + * Please see otCoapRequestHandler for details. + * + */ +typedef otCoapRequestHandler RequestHandler; + +/** + * This structure represents the CoAP transmission parameters. + * + */ +class TxParameters : public otCoapTxParameters { + friend class CoapBase; + friend class ResponsesQueue; + public: /** - * Protocol Constants (RFC 7252). + * This static method coverts a pointer to `otCoapTxParameters` to `Coap::TxParamters` + * + * If the pointer is NULL, the default parameters are used instead. + * + * @param[in] aTxParameters A pointer to tx parameter. + * + * @returns A reference to corresponding `TxParamters` if @p aTxParameters is not NULL, otherwise the default tx + * parameters. * */ + static const TxParameters &From(const otCoapTxParameters *aTxParameters) + { + return aTxParameters ? *static_cast(aTxParameters) : GetDefault(); + } + + /** + * This static method returns default CoAP tx parameters. + * + * @returns The default tx parameters. + * + */ + static const TxParameters &GetDefault(void) { return static_cast(kDefaultTxParameters); } + +private: enum { kDefaultAckTimeout = OPENTHREAD_CONFIG_COAP_ACK_TIMEOUT_MILLIS, kDefaultAckRandomFactorNumerator = OPENTHREAD_CONFIG_COAP_ACK_RANDOM_FACTOR_NUMERATOR, kDefaultAckRandomFactorDenominator = OPENTHREAD_CONFIG_COAP_ACK_RANDOM_FACTOR_DENOMINATOR, kDefaultMaxRetransmit = OPENTHREAD_CONFIG_COAP_MAX_RETRANSMIT, - kDefaultNStart = 1, - kDefaultLeisure = 5000, // in milliseconds - kDefaultProbingRate = 1, - - kDefaultMaxTransmitSpan = kDefaultAckTimeout * ((1ULL << kDefaultMaxRetransmit) - 1) * - kDefaultAckRandomFactorNumerator / kDefaultAckRandomFactorDenominator, - kDefaultMaxTransmitWait = kDefaultAckTimeout * ((2ULL << kDefaultMaxRetransmit) - 1) * - kDefaultAckRandomFactorNumerator / kDefaultAckRandomFactorDenominator, - kDefaultMaxLatency = 100000, // in milliseconds - kDefaultProcessingDelay = kDefaultAckTimeout, - kDefaultMaxRtt = 2 * kDefaultMaxLatency + kDefaultProcessingDelay, - kDefaultExchangeLifetime = kDefaultMaxTransmitSpan + 2 * kDefaultMaxLatency + kDefaultProcessingDelay, - kDefaultNonLifetime = kDefaultMaxTransmitSpan + kDefaultMaxLatency + kDefaultMaxLatency = 100000, // in millisecond }; uint32_t CalculateInitialRetransmissionTimeout(void) const; uint32_t CalculateExchangeLifetime(void) const; uint32_t CalculateMaxTransmitWait(void) const; + uint32_t CalculateSpan(uint32_t aMaxRetx) const; - static inline const CoapTxParameters &From(const otCoapTxParameters *aTxParameters) - { - return aTxParameters ? *static_cast(aTxParameters) : GetDefault(); - } - - static inline const CoapTxParameters &GetDefault() - { - return *static_cast(&kDefaultTxParameters); - } - -private: static const otCoapTxParameters kDefaultTxParameters; }; -/** - * This class implements metadata required for CoAP retransmission. - * - */ -class CoapMetadata -{ - friend class CoapBase; - -public: - /** - * Default constructor for the object. - * - */ - CoapMetadata(void) - : mDestinationPort(0) - , mResponseHandler(NULL) - , mResponseContext(NULL) - , mNextTimerShot(0) - , mRetransmissionTimeout(0) - , mRetransmissionsRemaining(0) - , mAcknowledged(false) - , mConfirmable(false){}; - - /** - * This constructor initializes the object with specific values. - * - * @param[in] aConfirmable Information if the request is confirmable or not. - * @param[in] aMessageInfo Addressing information. - * @param[in] aHandler Pointer to a handler function for the response. - * @param[in] aContext Context for the handler function. - * @param[in] aTxParameters Transmission parameters. - * - */ - CoapMetadata(bool aConfirmable, - const Ip6::MessageInfo &aMessageInfo, - otCoapResponseHandler aHandler, - void * aContext, - const CoapTxParameters &aTxParameters); - - /** - * This method appends request data to the message. - * - * @param[in] aMessage A reference to the message. - * - * @retval OT_ERROR_NONE Successfully appended the bytes. - * @retval OT_ERROR_NO_BUFS Insufficient available buffers to grow the message. - * - */ - otError AppendTo(Message &aMessage) const { return aMessage.Append(this, sizeof(*this)); } - - /** - * This method reads request data from the message. - * - * @param[in] aMessage A reference to the message. - * - */ - void ReadFrom(const Message &aMessage) - { - uint16_t length = aMessage.Read(aMessage.GetLength() - sizeof(*this), sizeof(*this), this); - assert(length == sizeof(*this)); - OT_UNUSED_VARIABLE(length); - } - - /** - * This method updates request data in the message. - * - * @param[in] aMessage A reference to the message. - * - * @returns The number of bytes updated. - * - */ - int UpdateIn(Message &aMessage) const - { - return aMessage.Write(aMessage.GetLength() - sizeof(*this), sizeof(*this), this); - } - -private: - Ip6::Address mSourceAddress; ///< IPv6 address of the message source. - Ip6::Address mDestinationAddress; ///< IPv6 address of the message destination. - uint16_t mDestinationPort; ///< UDP port of the message destination. - otCoapResponseHandler mResponseHandler; ///< A function pointer that is called on response reception. - void * mResponseContext; ///< A pointer to arbitrary context information. - TimeMilli mNextTimerShot; ///< Time when the timer should shoot for this message. - uint32_t mRetransmissionTimeout; ///< Delay that is applied to next retransmission. - uint8_t mRetransmissionsRemaining; ///< Number of retransmissions remaining. - bool mAcknowledged : 1; ///< Information that request was acknowledged. - bool mConfirmable : 1; ///< Information that message is confirmable. -}; - /** * This class implements CoAP resource handling. * @@ -211,11 +145,11 @@ public: /** * This constructor initializes the resource. * - * @param[in] aUriPath A pointer to a NULL-terminated string for the Uri-Path. + * @param[in] aUriPath A pointer to a NULL-terminated string for the URI path. * @param[in] aHandler A function pointer that is called when receiving a CoAP message for @p aUriPath. * @param[in] aContext A pointer to arbitrary context information. */ - Resource(const char *aUriPath, otCoapRequestHandler aHandler, void *aContext) + Resource(const char *aUriPath, RequestHandler aHandler, void *aContext) { mUriPath = aUriPath; mHandler = aHandler; @@ -224,9 +158,9 @@ public: } /** - * This method returns a pointer to the Uri-Path. + * This method returns a pointer to the URI path. * - * @returns A pointer to the Uri-Path. + * @returns A pointer to the URI path. * */ const char *GetUriPath(void) const { return mUriPath; } @@ -238,81 +172,6 @@ private: } }; -/** - * This class implements metadata required for caching CoAP responses. - * - */ -class EnqueuedResponseHeader -{ - friend class ResponsesQueue; - -public: - /** - * Default constructor creating empty object. - * - */ - EnqueuedResponseHeader(void) - : mDequeueTime(0) - , mMessageInfo() - { - } - - /** - * Constructor creating object with valid dequeue time and message info. - * - * @param[in] aMessageInfo The message info containing source endpoint identification. - * - */ - explicit EnqueuedResponseHeader(TimeMilli aDequeueTime, const Ip6::MessageInfo &aMessageInfo) - : mDequeueTime(aDequeueTime) - , mMessageInfo(aMessageInfo) - { - } - - /** - * This method appends metadata to the message. - * - * @param[in] aMessage A reference to the message. - * - * @retval OT_ERROR_NONE Successfully appended the bytes. - * @retval OT_ERROR_NO_BUFS Insufficient available buffers to grow the message. - */ - otError AppendTo(Message &aMessage) const { return aMessage.Append(this, sizeof(*this)); } - - /** - * This method reads request data from the message. - * - * @param[in] aMessage A reference to the message. - * - */ - void ReadFrom(const Message &aMessage) - { - uint16_t length = aMessage.Read(aMessage.GetLength() - sizeof(*this), sizeof(*this), this); - assert(length == sizeof(*this)); - OT_UNUSED_VARIABLE(length); - } - - /** - * This method returns number of milliseconds in which the message should be sent. - * - * @returns The number of milliseconds in which the message should be sent. - * - */ - uint32_t GetRemainingTime(void) const; - - /** - * This method returns the message info of cached CoAP response. - * - * @returns The message info of the cached CoAP response. - * - */ - const Ip6::MessageInfo &GetMessageInfo(void) const { return mMessageInfo; } - -private: - TimeMilli mDequeueTime; - const Ip6::MessageInfo mMessageInfo; -}; - /** * This class caches CoAP responses to implement message deduplication. * @@ -341,9 +200,7 @@ public: * @param[in] aTxParameters Transmission parameters. * */ - void EnqueueResponse(Message & aMessage, - const Ip6::MessageInfo &aMessageInfo, - const CoapTxParameters &aTxParameters); + void EnqueueResponse(Message &aMessage, const Ip6::MessageInfo &aMessageInfo, const TxParameters &aTxParameters); /** * This method removes the oldest response from the cache. @@ -385,23 +242,19 @@ private: kMaxCachedResponses = OPENTHREAD_CONFIG_COAP_SERVER_MAX_CACHED_RESPONSES, }; - /** - * This method checks whether a CoAP response exists in the cache that matches a given Message ID and source - * endpoint. - * - * @param[in] aRequest The CoAP message containing Message ID. - * @param[in] aMessageInfo The message info containing source endpoint address and port. - * - * @returns A pointer to the matching cached response or NULL if not found. - * - */ - const Message *FindMatchedResponse(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo) const; - - void DequeueResponse(Message &aMessage) + struct ResponseMetadata { - mQueue.Dequeue(aMessage); - aMessage.Free(); - } + void Init(TimeMilli aDequeueTime, const Ip6::MessageInfo &aMessageInfo); + otError AppendTo(Message &aMessage) const { return aMessage.Append(this, sizeof(*this)); } + void ReadFrom(const Message &aMessage); + uint32_t GetRemainingTime(void) const; + + TimeMilli mDequeueTime; + Ip6::MessageInfo mMessageInfo; + }; + + const Message *FindMatchedResponse(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo) const; + void DequeueResponse(Message &aMessage); static void HandleTimer(Timer &aTimer); void HandleTimer(void); @@ -419,19 +272,6 @@ class CoapBase : public InstanceLocator friend class ResponsesQueue; public: - /** - * This function pointer is called to send a CoAP message. - * - * @param[in] aCoapBase A reference to the CoAP agent. - * @param[in] aMessage A reference to the message to send. - * @param[in] aMessageInfo A reference to the message info associated with @p aMessage. - * - * @retval OT_ERROR_NONE Successfully sent CoAP message. - * @retval OT_ERROR_NO_BUFS Failed to allocate retransmission data. - * - */ - typedef otError (*Sender)(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); - /** * This function pointer is called before CoAP server processing a CoAP message. * @@ -486,7 +326,7 @@ public: * @param[in] aContext A pointer to arbitrary context information. May be NULL if not used. * */ - void SetDefaultHandler(otCoapRequestHandler aHandler, void *aContext); + void SetDefaultHandler(RequestHandler aHandler, void *aContext); /** * This method creates a new message with a CoAP header. @@ -515,13 +355,13 @@ public: * @param[in] aContext A pointer to arbitrary context information. * * @retval OT_ERROR_NONE Successfully sent CoAP message. - * @retval OT_ERROR_NO_BUFS Failed to allocate retransmission data. + * @retval OT_ERROR_NO_BUFS Insufficient buffers available to send the CoAP message. * */ otError SendMessage(Message & aMessage, const Ip6::MessageInfo &aMessageInfo, - const CoapTxParameters &aTxParameters, - otCoapResponseHandler aHandler = NULL, + const TxParameters & aTxParameters, + ResponseHandler aHandler = NULL, void * aContext = NULL); /** @@ -537,16 +377,13 @@ public: * @param[in] aContext A pointer to arbitrary context information. * * @retval OT_ERROR_NONE Successfully sent CoAP message. - * @retval OT_ERROR_NO_BUFS Failed to allocate retransmission data. + * @retval OT_ERROR_NO_BUFS Insufficient buffers available to send the CoAP response. * */ otError SendMessage(Message & aMessage, const Ip6::MessageInfo &aMessageInfo, - otCoapResponseHandler aHandler = NULL, - void * aContext = NULL) - { - return SendMessage(aMessage, aMessageInfo, CoapTxParameters::GetDefault(), aHandler, aContext); - } + ResponseHandler aHandler = NULL, + void * aContext = NULL); /** * This method sends a CoAP reset message. @@ -559,10 +396,7 @@ public: * @retval OT_ERROR_INVALID_ARGS The @p aRequest is not of confirmable type. * */ - otError SendReset(Message &aRequest, const Ip6::MessageInfo &aMessageInfo) - { - return SendEmptyMessage(OT_COAP_TYPE_RESET, aRequest, aMessageInfo); - } + otError SendReset(Message &aRequest, const Ip6::MessageInfo &aMessageInfo); /** * This method sends header-only CoAP response message. @@ -589,10 +423,7 @@ public: * @retval OT_ERROR_INVALID_ARGS The @p aRequest header is not of confirmable type. * */ - otError SendAck(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo) - { - return SendEmptyMessage(OT_COAP_TYPE_ACKNOWLEDGMENT, aRequest, aMessageInfo); - } + otError SendAck(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo); /** * This method sends a CoAP ACK message on which a dummy CoAP response is piggybacked. @@ -605,12 +436,7 @@ public: * @retval OT_ERROR_INVALID_ARGS The @p aRequest header is not of confirmable type. * */ - otError SendEmptyAck(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo) - { - return (aRequest.GetType() == OT_COAP_TYPE_CONFIRMABLE - ? SendHeaderResponse(OT_COAP_CODE_CHANGED, aRequest, aMessageInfo) - : OT_ERROR_INVALID_ARGS); - } + otError SendEmptyAck(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo); /** * This method sends a header-only CoAP message to indicate no resource matched for the request. @@ -622,10 +448,7 @@ public: * @retval OT_ERROR_NO_BUFS Insufficient buffers available to send the CoAP response. * */ - otError SendNotFound(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo) - { - return SendHeaderResponse(OT_COAP_CODE_NOT_FOUND, aRequest, aMessageInfo); - } + otError SendNotFound(const Message &aRequest, const Ip6::MessageInfo &aMessageInfo); /** * This method aborts CoAP transactions associated with given handler and context. @@ -639,7 +462,7 @@ public: * @retval OT_ERROR_NOT_FOUND CoAP transaction associated with given handler was not found. * */ - otError AbortTransaction(otCoapResponseHandler aHandler, void *aContext); + otError AbortTransaction(ResponseHandler aHandler, void *aContext); /** * This method sets interceptor to be called before processing a CoAP packet. @@ -648,11 +471,7 @@ public: * @param[in] aContext A pointer to arbitrary context information. * */ - void SetInterceptor(Interceptor aInterceptor, void *aContext) - { - mInterceptor = aInterceptor; - mContext = aContext; - } + void SetInterceptor(Interceptor aInterceptor, void *aContext); /** * This method returns a reference to the request message list. @@ -671,6 +490,19 @@ public: const MessageQueue &GetCachedResponses(void) const { return mResponsesQueue.GetResponses(); } protected: + /** + * This function pointer is called to send a CoAP message. + * + * @param[in] aCoapBase A reference to the CoAP agent. + * @param[in] aMessage A reference to the message to send. + * @param[in] aMessageInfo A reference to the message info associated with @p aMessage. + * + * @retval OT_ERROR_NONE Successfully sent CoAP message. + * @retval OT_ERROR_NO_BUFS Failed to allocate retransmission data. + * + */ + typedef otError (*Sender)(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); + /** * This constructor initializes the object. * @@ -679,7 +511,7 @@ protected: * member method of a descendant of this class. * */ - explicit CoapBase(Instance &aInstance, Sender aSender); + CoapBase(Instance &aInstance, Sender aSender); /** * This method receives a CoAP message. @@ -691,16 +523,39 @@ protected: void Receive(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); private: + struct Metadata + { + void Init(bool aConfirmable, + const Ip6::MessageInfo &aMessageInfo, + ResponseHandler aHandler, + void * aContext, + const TxParameters & aTxParameters); + + otError AppendTo(Message &aMessage) const { return aMessage.Append(this, sizeof(*this)); } + void ReadFrom(const Message &aMessage); + int UpdateIn(Message &aMessage) const; + + Ip6::Address mSourceAddress; // IPv6 address of the message source. + Ip6::Address mDestinationAddress; // IPv6 address of the message destination. + uint16_t mDestinationPort; // UDP port of the message destination. + ResponseHandler mResponseHandler; // A function pointer that is called on response reception. + void * mResponseContext; // A pointer to arbitrary context information. + TimeMilli mNextTimerShot; // Time when the timer should shoot for this message. + uint32_t mRetransmissionTimeout; // Delay that is applied to next retransmission. + uint8_t mRetransmissionsRemaining; // Number of retransmissions remaining. + bool mAcknowledged : 1; // Information that request was acknowledged. + bool mConfirmable : 1; // Information that message is confirmable. + }; + static void HandleRetransmissionTimer(Timer &aTimer); void HandleRetransmissionTimer(void); - Message *CopyAndEnqueueMessage(const Message &aMessage, uint16_t aCopyLength, const CoapMetadata &aCoapMetadata); + void ClearRequests(const Ip6::Address *aAddress); + Message *CopyAndEnqueueMessage(const Message &aMessage, uint16_t aCopyLength, const Metadata &aMetadata); void DequeueMessage(Message &aMessage); - Message *FindRelatedRequest(const Message & aResponse, - const Ip6::MessageInfo &aMessageInfo, - CoapMetadata & aCoapMetadata); + Message *FindRelatedRequest(const Message &aResponse, const Ip6::MessageInfo &aMessageInfo, Metadata &aMetadata); void FinalizeCoapTransaction(Message & aRequest, - const CoapMetadata & aCoapMetadata, + const Metadata & aMetadata, Message * aResponse, const Ip6::MessageInfo *aMessageInfo, otError aResult); @@ -711,20 +566,7 @@ private: otError SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo); otError SendEmptyMessage(Message::Type aType, const Message &aRequest, const Ip6::MessageInfo &aMessageInfo); - /** - * This method sends a message. - * - * @param[in] aMessage A reference to the message to send. - * @param[in] aMessageInfo A reference to the message info associated with @p aMessage. - * - * @retval OT_ERROR_NONE Successfully sent CoAP message. - * @retval OT_ERROR_NO_BUFS Failed to allocate retransmission data. - * - */ - otError Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) - { - return mSender(*this, aMessage, aMessageInfo); - } + otError Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); MessageQueue mPendingRequests; uint16_t mMessageId; @@ -736,10 +578,10 @@ private: Interceptor mInterceptor; ResponsesQueue mResponsesQueue; - otCoapRequestHandler mDefaultHandler; - void * mDefaultHandlerContext; + RequestHandler mDefaultHandler; + void * mDefaultHandlerContext; - Sender mSender; + const Sender mSender; }; /** @@ -778,13 +620,9 @@ public: otError Stop(void); private: - static otError Send(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo) - { - return static_cast(aCoapBase).Send(aMessage, aMessageInfo); - } - otError Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); - - static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo); + static otError Send(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); + static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo); + otError Send(ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); Ip6::UdpSocket mSocket; }; diff --git a/src/core/coap/coap_secure.cpp b/src/core/coap/coap_secure.cpp index ffdec6c27..f6befbbc0 100644 --- a/src/core/coap/coap_secure.cpp +++ b/src/core/coap/coap_secure.cpp @@ -152,7 +152,7 @@ void CoapSecure::SetSslAuthMode(bool aVerifyPeerCertificate) #endif // OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE -otError CoapSecure::SendMessage(Message &aMessage, otCoapResponseHandler aHandler, void *aContext) +otError CoapSecure::SendMessage(Message &aMessage, ResponseHandler aHandler, void *aContext) { otError error = OT_ERROR_NONE; @@ -166,7 +166,7 @@ exit: otError CoapSecure::SendMessage(Message & aMessage, const Ip6::MessageInfo &aMessageInfo, - otCoapResponseHandler aHandler, + ResponseHandler aHandler, void * aContext) { return CoapBase::SendMessage(aMessage, aMessageInfo, aHandler, aContext); diff --git a/src/core/coap/coap_secure.hpp b/src/core/coap/coap_secure.hpp index 65f62fc1c..1dc2f3906 100644 --- a/src/core/coap/coap_secure.hpp +++ b/src/core/coap/coap_secure.hpp @@ -262,7 +262,7 @@ public: * @retval OT_ERROR_INVALID_STATE DTLS connection was not initialized. * */ - otError SendMessage(Message &aMessage, otCoapResponseHandler aHandler = NULL, void *aContext = NULL); + otError SendMessage(Message &aMessage, ResponseHandler aHandler = NULL, void *aContext = NULL); /** * This method sends a CoAP message over secure DTLS connection. @@ -283,7 +283,7 @@ public: */ otError SendMessage(Message & aMessage, const Ip6::MessageInfo &aMessageInfo, - otCoapResponseHandler aHandler = NULL, + ResponseHandler aHandler = NULL, void * aContext = NULL); /**