diff --git a/src/core/api/instance_api.cpp b/src/core/api/instance_api.cpp index 70171adfa..f87d8cac5 100644 --- a/src/core/api/instance_api.cpp +++ b/src/core/api/instance_api.cpp @@ -92,7 +92,7 @@ otInstance::otInstance(void) : mLinkRaw(*this), #endif // OPENTHREAD_ENABLE_RAW_LINK_API #if OPENTHREAD_ENABLE_APPLICATION_COAP - mApplicationCoap(mThreadNetif), + mApplicationCoap(*this), #endif // OPENTHREAD_ENABLE_APPLICATION_COAP #if OPENTHREAD_CONFIG_ENABLE_DYNAMIC_LOG_LEVEL mLogLevel(static_cast(OPENTHREAD_CONFIG_LOG_LEVEL)), diff --git a/src/core/coap/coap.cpp b/src/core/coap/coap.cpp index 44cf127cd..1703f2de6 100644 --- a/src/core/coap/coap.cpp +++ b/src/core/coap/coap.cpp @@ -32,6 +32,7 @@ #include +#include "openthread-instance.h" #include "common/code_utils.hpp" #include "common/debug.hpp" #include "common/logging.hpp" @@ -47,34 +48,35 @@ namespace ot { namespace Coap { -Coap::Coap(ThreadNetif &aNetif, Timer::Handler aRetransmissionHandler): +CoapBase::CoapBase(ThreadNetif &aNetif, Timer::Handler aRetransmissionTimerHandler, + Timer::Handler aResponsesQueueTimerHandler): ThreadNetifLocator(aNetif), mSocket(aNetif.GetIp6().mUdp), - mRetransmissionTimer(aNetif.GetInstance(), aRetransmissionHandler, this), + mRetransmissionTimer(aNetif.GetInstance(), aRetransmissionTimerHandler, this), mResources(NULL), mContext(NULL), mInterceptor(NULL), - mResponsesQueue(aNetif), + mResponsesQueue(aNetif.GetInstance(), aResponsesQueueTimerHandler, this), mDefaultHandler(NULL), mDefaultHandlerContext(NULL) { mMessageId = static_cast(otPlatRandomGet()); } -otError Coap::Start(uint16_t aPort) +otError CoapBase::Start(uint16_t aPort) { otError error; Ip6::SockAddr sockaddr; sockaddr.mPort = aPort; - SuccessOrExit(error = mSocket.Open(&Coap::HandleUdpReceive, this)); + SuccessOrExit(error = mSocket.Open(&CoapBase::HandleUdpReceive, this)); SuccessOrExit(error = mSocket.Bind(sockaddr)); exit: return error; } -otError Coap::Stop(void) +otError CoapBase::Stop(void) { Message *message = mPendingRequests.GetHead(); Message *messageToRemove; @@ -95,7 +97,7 @@ otError Coap::Stop(void) return mSocket.Close(); } -otError Coap::AddResource(Resource &aResource) +otError CoapBase::AddResource(Resource &aResource) { otError error = OT_ERROR_NONE; @@ -111,7 +113,7 @@ exit: return error; } -void Coap::RemoveResource(Resource &aResource) +void CoapBase::RemoveResource(Resource &aResource) { if (mResources == &aResource) { @@ -133,13 +135,13 @@ exit: aResource.mNext = NULL; } -void Coap::SetDefaultHandler(otCoapRequestHandler aHandler, void *aContext) +void CoapBase::SetDefaultHandler(otCoapRequestHandler aHandler, void *aContext) { mDefaultHandler = aHandler; mDefaultHandlerContext = aContext; } -Message *Coap::NewMessage(const Header &aHeader, uint8_t aPriority) +Message *CoapBase::NewMessage(const Header &aHeader, uint8_t aPriority) { Message *message = NULL; @@ -155,8 +157,8 @@ exit: return message; } -otError Coap::SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo, - otCoapResponseHandler aHandler, void *aContext) +otError CoapBase::SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo, + otCoapResponseHandler aHandler, void *aContext) { otError error; Header header; @@ -210,13 +212,13 @@ exit: return error; } -otError Coap::Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo) +otError CoapBase::Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { return mSocket.SendTo(aMessage, aMessageInfo); } -otError Coap::SendEmptyMessage(Header::Type aType, const Header &aRequestHeader, - const Ip6::MessageInfo &aMessageInfo) +otError CoapBase::SendEmptyMessage(Header::Type aType, const Header &aRequestHeader, + const Ip6::MessageInfo &aMessageInfo) { otError error = OT_ERROR_NONE; Header responseHeader; @@ -241,8 +243,8 @@ exit: return error; } -otError Coap::SendHeaderResponse(Header::Code aCode, const Header &aRequestHeader, - const Ip6::MessageInfo &aMessageInfo) +otError CoapBase::SendHeaderResponse(Header::Code aCode, const Header &aRequestHeader, + const Ip6::MessageInfo &aMessageInfo) { otError error = OT_ERROR_NONE; Header responseHeader; @@ -286,23 +288,7 @@ exit: return error; } -Coap &Coap::GetOwner(const Context &aContext) -{ -#if OPENTHREAD_ENABLE_MULTIPLE_INSTANCES - Coap &coap = *static_cast(aContext.GetContext()); -#else - Coap &coap = otGetThreadNetif().GetCoap(); - OT_UNUSED_VARIABLE(aContext); -#endif - return coap; -} - -void Coap::HandleRetransmissionTimer(Timer &aTimer) -{ - GetOwner(aTimer).HandleRetransmissionTimer(); -} - -void Coap::HandleRetransmissionTimer(void) +void CoapBase::HandleRetransmissionTimer(void) { uint32_t now = TimerMilli::GetNow(); uint32_t nextDelta = 0xffffffff; @@ -364,9 +350,9 @@ void Coap::HandleRetransmissionTimer(void) } } -void Coap::FinalizeCoapTransaction(Message &aRequest, const CoapMetadata &aCoapMetadata, - Header *aResponseHeader, Message *aResponse, - const Ip6::MessageInfo *aMessageInfo, otError aResult) +void CoapBase::FinalizeCoapTransaction(Message &aRequest, const CoapMetadata &aCoapMetadata, + Header *aResponseHeader, Message *aResponse, + const Ip6::MessageInfo *aMessageInfo, otError aResult) { DequeueMessage(aRequest); @@ -377,7 +363,7 @@ void Coap::FinalizeCoapTransaction(Message &aRequest, const CoapMetadata &aCoapM } } -otError Coap::AbortTransaction(otCoapResponseHandler aHandler, void *aContext) +otError CoapBase::AbortTransaction(otCoapResponseHandler aHandler, void *aContext) { otError error = OT_ERROR_NOT_FOUND; Message *message; @@ -398,8 +384,8 @@ otError Coap::AbortTransaction(otCoapResponseHandler aHandler, void *aContext) } -Message *Coap::CopyAndEnqueueMessage(const Message &aMessage, uint16_t aCopyLength, - const CoapMetadata &aCoapMetadata) +Message *CoapBase::CopyAndEnqueueMessage(const Message &aMessage, uint16_t aCopyLength, + const CoapMetadata &aCoapMetadata) { otError error = OT_ERROR_NONE; Message *messageCopy = NULL; @@ -441,7 +427,7 @@ exit: return messageCopy; } -void Coap::DequeueMessage(Message &aMessage) +void CoapBase::DequeueMessage(Message &aMessage) { mPendingRequests.Dequeue(aMessage); @@ -458,7 +444,7 @@ void Coap::DequeueMessage(Message &aMessage) // the timer would just shoot earlier and then it'd be setup again. } -otError Coap::SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo) +otError CoapBase::SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { otError error; Message *messageCopy = NULL; @@ -480,8 +466,8 @@ exit: return error; } -Message *Coap::FindRelatedRequest(const Header &aResponseHeader, const Ip6::MessageInfo &aMessageInfo, - Header &aRequestHeader, CoapMetadata &aCoapMetadata) +Message *CoapBase::FindRelatedRequest(const Header &aResponseHeader, const Ip6::MessageInfo &aMessageInfo, + Header &aRequestHeader, CoapMetadata &aCoapMetadata) { Message *message = mPendingRequests.GetHead(); @@ -527,13 +513,13 @@ exit: return message; } -void Coap::HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo) +void CoapBase::HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo) { static_cast(aContext)->Receive(*static_cast(aMessage), *static_cast(aMessageInfo)); } -void Coap::Receive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo) +void CoapBase::Receive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { otError error; Header header; @@ -557,8 +543,8 @@ exit: } } -void Coap::ProcessReceivedResponse(Header &aResponseHeader, Message &aMessage, - const Ip6::MessageInfo &aMessageInfo) +void CoapBase::ProcessReceivedResponse(Header &aResponseHeader, Message &aMessage, + const Ip6::MessageInfo &aMessageInfo) { Header requestHeader; CoapMetadata coapMetadata; @@ -636,7 +622,7 @@ exit: } } -void Coap::ProcessReceivedRequest(Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo) +void CoapBase::ProcessReceivedRequest(Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { char uriPath[Resource::kMaxReceivedUriPath] = ""; char *curUriPath = uriPath; @@ -758,8 +744,9 @@ CoapMetadata::CoapMetadata(bool aConfirmable, const Ip6::MessageInfo &aMessageIn mConfirmable = aConfirmable; } -ResponsesQueue::ResponsesQueue(ThreadNetif &aNetif): - mTimer(aNetif.GetInstance(), &ResponsesQueue::HandleTimer, this) +ResponsesQueue::ResponsesQueue(otInstance &aInstance, Timer::Handler aHandler, void *aContext): + mQueue(), + mTimer(aInstance, aHandler, aContext) { } @@ -896,22 +883,6 @@ void ResponsesQueue::DequeueAllResponses(void) } } -ResponsesQueue &ResponsesQueue::GetOwner(const Context &aContext) -{ -#if OPENTHREAD_ENABLE_MULTIPLE_INSTANCES - ResponsesQueue &queue = *static_cast(aContext.GetContext()); -#else - ResponsesQueue &queue = otGetThreadNetif().GetCoap().mResponsesQueue; - OT_UNUSED_VARIABLE(aContext); -#endif - return queue; -} - -void ResponsesQueue::HandleTimer(Timer &aTimer) -{ - GetOwner(aTimer).HandleTimer(); -} - void ResponsesQueue::HandleTimer(void) { Message *message; @@ -940,5 +911,62 @@ uint32_t EnqueuedResponseHeader::GetRemainingTime(void) const return remainingTime >= 0 ? static_cast(remainingTime) : 0; } +Coap::Coap(ThreadNetif &aNetif): + CoapBase(aNetif, &Coap::HandleRetransmissionTimer, &Coap::HandleResponsesQueueTimer) +{ +} + +Coap &Coap::GetOwner(const Context &aContext) +{ +#if OPENTHREAD_ENABLE_MULTIPLE_INSTANCES + Coap &coap = *static_cast(aContext.GetContext()); +#else + Coap &coap = otGetThreadNetif().GetCoap(); + OT_UNUSED_VARIABLE(aContext); +#endif + return coap; +} + +void Coap::HandleRetransmissionTimer(Timer &aTimer) +{ + GetOwner(aTimer).CoapBase::HandleRetransmissionTimer(); +} + +void Coap::HandleResponsesQueueTimer(Timer &aTimer) +{ + GetOwner(aTimer).CoapBase::HandleResponsesQueueTimer(); +} + +#if OPENTHREAD_ENABLE_APPLICATION_COAP + +ApplicationCoap::ApplicationCoap(otInstance &aInstance): + CoapBase(aInstance.mThreadNetif, &ApplicationCoap::HandleRetransmissionTimer, + &ApplicationCoap::HandleResponsesQueueTimer) +{ +} + +ApplicationCoap &ApplicationCoap::GetOwner(const Context &aContext) +{ +#if OPENTHREAD_ENABLE_MULTIPLE_INSTANCES + ApplicationCoap &coap = *static_cast(aContext.GetContext()); +#else + ApplicationCoap &coap = otGetInstance()->mApplicationCoap; + OT_UNUSED_VARIABLE(aContext); +#endif + return coap; +} + +void ApplicationCoap::HandleRetransmissionTimer(Timer &aTimer) +{ + GetOwner(aTimer).CoapBase::HandleRetransmissionTimer(); +} + +void ApplicationCoap::HandleResponsesQueueTimer(Timer &aTimer) +{ + GetOwner(aTimer).CoapBase::HandleResponsesQueueTimer(); +} + +#endif // OPENTHREAD_ENABLE_APPLICATION_COAP + } // namespace Coap } // namespace ot diff --git a/src/core/coap/coap.hpp b/src/core/coap/coap.hpp index e1fc2b09c..dbb8a7bea 100644 --- a/src/core/coap/coap.hpp +++ b/src/core/coap/coap.hpp @@ -93,7 +93,7 @@ enum OT_TOOL_PACKED_BEGIN class CoapMetadata { - friend class Coap; + friend class CoapBase; public: @@ -199,7 +199,7 @@ private: */ class Resource : public otCoapResource { - friend class Coap; + friend class CoapBase; public: enum @@ -332,10 +332,12 @@ public: /** * Default class constructor. * - * @param[in] aNetif A reference to the network interface that CoAP server should be assigned to. + * @param[in] aInstance A reference to the OpenThread instance. + * @param[in] aHandler A timer handler provided by owner of `RespponseQueue`. + * @param[in] aContext A pointer to arbitrary context information (used along with timer handler). * */ - ResponsesQueue(ThreadNetif &aNetif); + ResponsesQueue(otInstance &aInstance, Timer::Handler aHandler, void *aContext); /** * Add given response to the cache. @@ -403,6 +405,15 @@ public: */ const MessageQueue &GetResponses(void) const { return mQueue; } + /** + * Callback handler for timer. + * + * This method must be invoked by the owner of `ResponsesQueue` instance when the timer expires from the `aHandler` + * callback function provided in the constructor. + * + */ + void HandleTimer(void); + private: enum { @@ -410,19 +421,16 @@ private: }; void DequeueResponse(Message &aMessage) { mQueue.Dequeue(aMessage); aMessage.Free(); } - static ResponsesQueue &GetOwner(const Context &aContext); - static void HandleTimer(Timer &aTimer); - void HandleTimer(void); MessageQueue mQueue; TimerMilli mTimer; }; /** - * This class implements the CoAP client and server. + * This class implements the common base for CoAP client and server. * */ -class Coap: public ThreadNetifLocator +class CoapBase: public ThreadNetifLocator { friend class ResponsesQueue; @@ -442,15 +450,6 @@ public: */ typedef otError(* Interceptor)(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, void *aContext); - /** - * This constructor initializes the object. - * - * @param[in] aNetif A reference to the Netif object. - * @param[in] aRetransmissionHandler An optional pointer to the retransmission handler, used by CoapSecure. - * - */ - Coap(ThreadNetif &aNetif, Timer::Handler aRetransmissionHandler = &Coap::HandleRetransmissionTimer); - /** * This method starts the CoAP service. * @@ -649,14 +648,37 @@ public: const MessageQueue &GetCachedResponses(void) const { return mResponsesQueue.GetResponses(); } protected: + /** + * This constructor initializes the object. + * + * @param[in] aNetif A reference to the Netif object. + * @param[in] aRetransmissionTimerHandler A timer handler provided by sub-class for `mRetranmissionTimer`. + * @param[in] aResponsesQueueTimerHandler A timer handler provided by sub-class for `mReponsesQueue` timer. + * + */ + CoapBase(ThreadNetif &aNetif, Timer::Handler aRetransmissionTimerHandler, + Timer::Handler aResponsesQueueTimerHandler); + /** * Retransmission timer handler. * + * This method must be invoked by sub-class when the timer expires from the `aRetransmissionTimerHandler` + * callback function provided in the constructor. + * */ void HandleRetransmissionTimer(void); /** - * This method send a message. + * `ResponsesQueue` timer handler. + * + * This method must be invoked by sub-class when the timer expires from the `aResponsesQueueTimerHandler` + * callback function provided in the constructor. + * + */ + void HandleResponsesQueueTimer(void) { mResponsesQueue.HandleTimer(); } + + /** + * 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. @@ -698,10 +720,6 @@ private: otError SendEmptyMessage(Header::Type aType, const Header &aRequestHeader, const Ip6::MessageInfo &aMessageInfo); - static void HandleRetransmissionTimer(Timer &aTimer); - - static Coap &GetOwner(const Context &aContext); - MessageQueue mPendingRequests; uint16_t mMessageId; TimerMilli mRetransmissionTimer; @@ -716,6 +734,52 @@ private: void *mDefaultHandlerContext; }; +/** + * This class implements the CoAP client and server. + * + */ +class Coap: public CoapBase +{ +public: + /** + * This constructor initializes the object. + * + * @param[in] aNetif A reference to the Netif object. + * + */ + Coap(ThreadNetif &aNetif); + +private: + static Coap &GetOwner(const Context &aContext); + static void HandleRetransmissionTimer(Timer &aTimer); + static void HandleResponsesQueueTimer(Timer &aTimer); +}; + +#if OPENTHREAD_ENABLE_APPLICATION_COAP + +/** + * This class implements the application CoAP client and server. + * + */ +class ApplicationCoap: public CoapBase +{ +public: + /** + * This constructor initializes the object. + * + * @param[in] aNetif A reference to the otInstance + * + */ + ApplicationCoap(otInstance &aInstance); + +private: + static ApplicationCoap &GetOwner(const Context &aContext); + static void HandleRetransmissionTimer(Timer &aTimer); + static void HandleResponsesQueueTimer(Timer &aTimer); +}; + +#endif + } // namespace Coap } // namespace ot diff --git a/src/core/coap/coap_secure.cpp b/src/core/coap/coap_secure.cpp index 03377cd85..64d469766 100644 --- a/src/core/coap/coap_secure.cpp +++ b/src/core/coap/coap_secure.cpp @@ -46,7 +46,7 @@ namespace ot { namespace Coap { CoapSecure::CoapSecure(ThreadNetif &aNetif): - Coap(aNetif, &CoapSecure::HandleRetransmissionTimer), + CoapBase(aNetif, &CoapSecure::HandleRetransmissionTimer, &CoapSecure::HandleResponsesQueueTimer), mConnectedCallback(NULL), mConnectedContext(NULL), mTransportCallback(NULL), @@ -66,7 +66,7 @@ otError CoapSecure::Start(uint16_t aPort, TransportCallback aCallback, void *aCo // to transmit/receive messages, so do not open it in that case. if (mTransportCallback == NULL) { - error = Coap::Start(aPort); + error = CoapBase::Start(aPort); } return error; @@ -88,7 +88,7 @@ otError CoapSecure::Stop(void) mTransportCallback = NULL; mTransportContext = NULL; - return Coap::Stop(); + return CoapBase::Stop(); } otError CoapSecure::Connect(const Ip6::MessageInfo &aMessageInfo, ConnectedCallback aCallback, void *aContext) @@ -134,7 +134,7 @@ otError CoapSecure::SendMessage(Message &aMessage, otCoapResponseHandler aHandle VerifyOrExit(IsConnected(), error = OT_ERROR_INVALID_STATE); - error = Coap::SendMessage(aMessage, mPeerAddress, aHandler, aContext); + error = CoapBase::SendMessage(aMessage, mPeerAddress, aHandler, aContext); exit: otLogFuncExitErr(error); @@ -144,7 +144,7 @@ exit: otError CoapSecure::SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo, otCoapResponseHandler aHandler, void *aContext) { - return Coap::SendMessage(aMessage, aMessageInfo, aHandler, aContext); + return CoapBase::SendMessage(aMessage, aMessageInfo, aHandler, aContext); } otError CoapSecure::Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo) @@ -222,7 +222,7 @@ void CoapSecure::HandleDtlsReceive(uint8_t *aBuf, uint16_t aLength) VerifyOrExit((message = GetInstance().mMessagePool.New(Message::kTypeIp6, 0)) != NULL); SuccessOrExit(message->Append(aBuf, aLength)); - Coap::Receive(*message, mPeerAddress); + CoapBase::Receive(*message, mPeerAddress); exit: @@ -322,7 +322,12 @@ CoapSecure &CoapSecure::GetOwner(const Context &aContext) void CoapSecure::HandleRetransmissionTimer(Timer &aTimer) { - GetOwner(aTimer).Coap::HandleRetransmissionTimer(); + GetOwner(aTimer).CoapBase::HandleRetransmissionTimer(); +} + +void CoapSecure::HandleResponsesQueueTimer(Timer &aTimer) +{ + GetOwner(aTimer).CoapBase::HandleResponsesQueueTimer(); } } // namespace Coap diff --git a/src/core/coap/coap_secure.hpp b/src/core/coap/coap_secure.hpp index 8aca0eb16..bc763415a 100644 --- a/src/core/coap/coap_secure.hpp +++ b/src/core/coap/coap_secure.hpp @@ -45,7 +45,7 @@ class ThreadNetif; namespace Coap { -class CoapSecure: public Coap +class CoapSecure: public CoapBase { public: /** @@ -217,6 +217,7 @@ private: void HandleUdpTransmit(void); static void HandleRetransmissionTimer(Timer &aTimer); + static void HandleResponsesQueueTimer(Timer &aTimer); static CoapSecure &GetOwner(const Context &aContext); diff --git a/src/core/meshcop/meshcop.hpp b/src/core/meshcop/meshcop.hpp index dc9d20001..e3253b977 100644 --- a/src/core/meshcop/meshcop.hpp +++ b/src/core/meshcop/meshcop.hpp @@ -52,7 +52,7 @@ enum * This function create Message for MeshCoP * */ -inline Message *NewMeshCoPMessage(Coap::Coap &aCoap, const Coap::Header &aHeader) +inline Message *NewMeshCoPMessage(Coap::CoapBase &aCoap, const Coap::Header &aHeader) { return aCoap.NewMessage(aHeader, kMeshCoPMessagePriority); } diff --git a/src/core/openthread-instance.h b/src/core/openthread-instance.h index fe41cce8f..9e3f34845 100644 --- a/src/core/openthread-instance.h +++ b/src/core/openthread-instance.h @@ -95,7 +95,7 @@ typedef struct otInstance #endif // OPENTHREAD_ENABLE_RAW_LINK_API #if OPENTHREAD_ENABLE_APPLICATION_COAP - ot::Coap::Coap mApplicationCoap; + ot::Coap::ApplicationCoap mApplicationCoap; #endif // OPENTHREAD_ENABLE_APPLICATION_COAP #if OPENTHREAD_CONFIG_ENABLE_DYNAMIC_LOG_LEVEL