[coap] misc enhancements and simplifications (#4554)

This commits contains the following changes:
- Declare `Metadata` as a private inner class of `CoapBase`. Also
  replace constructors with `Init()` method and removes the default
  empty constructor (since it is not needed).
- Add `ResponseMetadata` as private inner struct in `ResposeQueue`.
- Simplify `ResponsesQueue::FindMatchedResponse()`.
- Declare `CoapBase::Sender` as a protected type.
- Use initializer list in `CoapBase` constructor.
- Use `for` loop for iterating over messages in a message queue.
- Define `ResponseHandler` and `RequestHandler` types.
- Update `TxParameters` class. Add helper method for common
  calculation of span window, and remove unused constant definitions.
- Move more complex method implementation from header file into
  `cpp` file (helps reduce code size).
- Update comments and documentations.
This commit is contained in:
Abtin Keshavarzian
2020-02-25 11:59:10 -08:00
committed by GitHub
parent fe6a7e1493
commit c32a0ee561
5 changed files with 347 additions and 476 deletions
+2 -2
View File
@@ -206,7 +206,7 @@ otError otCoapSendRequestWithParameters(otInstance * aInstance,
return instance.GetApplicationCoap().SendMessage(*static_cast<Coap::Message *>(aMessage),
*static_cast<const Ip6::MessageInfo *>(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<Coap::Message *>(aMessage),
*static_cast<const Ip6::MessageInfo *>(aMessageInfo),
Coap::CoapTxParameters::From(aTxParameters), NULL, NULL);
Coap::TxParameters::From(aTxParameters), NULL, NULL);
}
#endif // OPENTHREAD_CONFIG_COAP_API_ENABLE
+213 -180
View File
@@ -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<Message *>(mPendingRequests.GetHead());
Message * messageToRemove;
CoapMetadata coapMetadata;
// Remove all pending messages.
while (message != NULL)
{
messageToRemove = message;
message = static_cast<Message *>(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<Message *>(mPendingRequests.GetHead()); message != NULL; message = nextMessage)
{
CoapMetadata coapMetadata;
nextMessage = static_cast<Message *>(message->GetNext());
coapMetadata.ReadFrom(*message);
Metadata metadata;
if (coapMetadata.mSourceAddress == aAddress)
nextMessage = static_cast<Message *>(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<Message *>(mPendingRequests.GetHead()); message != NULL; message = nextMessage)
for (Message *message = static_cast<Message *>(mPendingRequests.GetHead()); message != NULL; message = nextMessage)
{
nextMessage = static_cast<Message *>(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<Message *>(mPendingRequests.GetHead()); message != NULL; message = nextMessage)
for (Message *message = static_cast<Message *>(mPendingRequests.GetHead()); message != NULL; message = nextMessage)
{
nextMessage = static_cast<Message *>(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<Message *>(mPendingRequests.GetHead());
Message *message;
while (message != NULL)
for (message = static_cast<Message *>(mPendingRequests.GetHead()); message != NULL;
message = static_cast<Message *>(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 *>(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<Message *>(mQueue.GetHead()); message != NULL;
message = static_cast<Message *>(message->GetNext()))
for (message = static_cast<Message *>(mQueue.GetHead()); message != NULL;
message = static_cast<Message *>(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<Message *>(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<uint32_t>(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<uint32_t>(mAckTimeout * ((2ULL << mMaxRetransmit) - 1) * mAckRandomFactorNumerator /
return CalculateSpan(mMaxRetransmit + 1);
}
uint32_t TxParameters::CalculateSpan(uint32_t aMaxRetx) const
{
return static_cast<uint32_t>(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<const Ip6::MessageInfo *>(aMessageInfo));
}
otError Coap::Send(CoapBase &aCoapBase, ot::Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
return static_cast<Coap &>(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;
+128 -290
View File
@@ -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<const TxParameters *>(aTxParameters) : GetDefault();
}
/**
* This static method returns default CoAP tx parameters.
*
* @returns The default tx parameters.
*
*/
static const TxParameters &GetDefault(void) { return static_cast<const TxParameters &>(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<const CoapTxParameters *>(aTxParameters) : GetDefault();
}
static inline const CoapTxParameters &GetDefault()
{
return *static_cast<const CoapTxParameters *>(&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<Coap &>(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;
};
+2 -2
View File
@@ -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);
+2 -2
View File
@@ -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);
/**