diff --git a/src/core/coap/coap_secure.cpp b/src/core/coap/coap_secure.cpp index db3123066..4c7bf74d7 100644 --- a/src/core/coap/coap_secure.cpp +++ b/src/core/coap/coap_secure.cpp @@ -53,17 +53,24 @@ CoapSecure::CoapSecure(Instance &aInstance) , mConnectedContext(NULL) , mTransportCallback(NULL) , mTransportContext(NULL) + , mTransmitQueue() + , mTransmitTask(aInstance, &CoapSecure::HandleTransmit, this) , mLayerTwoSecurity(false) { } #if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE -CoapSecure::CoapSecure(Instance &aInstance, Timer::Handler aRetransmissionTimer, Timer::Handler aResponsesQueueTimer) +CoapSecure::CoapSecure(Instance & aInstance, + Tasklet::Handler aHandleTransmit, + Timer::Handler aRetransmissionTimer, + Timer::Handler aResponsesQueueTimer) : CoapBase(aInstance, aRetransmissionTimer, aResponsesQueueTimer) , mConnectedCallback(NULL) , mConnectedContext(NULL) , mTransportCallback(NULL) , mTransportContext(NULL) + , mTransmitQueue() + , mTransmitTask(aInstance, aHandleTransmit, this) , mLayerTwoSecurity(true) { } @@ -100,6 +107,12 @@ otError CoapSecure::Stop(void) Disconnect(); } + for (Message *message = mTransmitQueue.GetHead(); message != NULL; message = message->GetNext()) + { + mTransmitQueue.Dequeue(*message); + message->Free(); + } + mTransportCallback = NULL; mTransportContext = NULL; @@ -230,7 +243,9 @@ otError CoapSecure::SendMessage(Message & aMessage, otError CoapSecure::Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { OT_UNUSED_VARIABLE(aMessageInfo); - return GetNetif().GetDtls().Send(aMessage, aMessage.GetLength()); + mTransmitQueue.Enqueue(aMessage); + mTransmitTask.Post(); + return OT_ERROR_NONE; } void CoapSecure::Receive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo) @@ -351,6 +366,38 @@ exit: return error; } +void CoapSecure::HandleTransmit(Tasklet &aTasklet) +{ + aTasklet.GetOwner().HandleTransmit(); +} + +void CoapSecure::HandleTransmit(void) +{ + otError error = OT_ERROR_NONE; + Message *message = mTransmitQueue.GetHead(); + + VerifyOrExit(message != NULL); + mTransmitQueue.Dequeue(*message); + + if (mTransmitQueue.GetHead() != NULL) + { + mTransmitTask.Post(); + } + + SuccessOrExit(error = GetDtls().Send(*message, message->GetLength())); + +exit: + if (error != OT_ERROR_NONE) + { + otLogNoteMeshCoP("CoapSecure Transmit: %s", otThreadErrorToString(error)); + message->Free(); + } + else + { + otLogDebgMeshCoP("CoapSecure Transmit: %s", otThreadErrorToString(error)); + } +} + void CoapSecure::HandleRetransmissionTimer(Timer &aTimer) { aTimer.GetOwner().CoapBase::HandleRetransmissionTimer(); @@ -365,11 +412,17 @@ void CoapSecure::HandleResponsesQueueTimer(Timer &aTimer) ApplicationCoapSecure::ApplicationCoapSecure(Instance &aInstance) : CoapSecure(aInstance, + &ApplicationCoapSecure::HandleTransmit, &ApplicationCoapSecure::HandleRetransmissionTimer, &ApplicationCoapSecure::HandleResponsesQueueTimer) { } +void ApplicationCoapSecure::HandleTransmit(Tasklet &aTasklet) +{ + aTasklet.GetOwner().CoapSecure::HandleTransmit(); +} + void ApplicationCoapSecure::HandleRetransmissionTimer(Timer &aTimer) { aTimer.GetOwner().CoapBase::HandleRetransmissionTimer(); diff --git a/src/core/coap/coap_secure.hpp b/src/core/coap/coap_secure.hpp index 6cb8e2c71..540245ba0 100644 --- a/src/core/coap/coap_secure.hpp +++ b/src/core/coap/coap_secure.hpp @@ -86,7 +86,10 @@ public: * @param[in] aResponsesQueueTimer Handler for Queue Responses. * */ - explicit CoapSecure(Instance &aInstance, Timer::Handler aRetransmissionTimer, Timer::Handler aResponsesQueueTimer); + explicit CoapSecure(Instance & aInstance, + Tasklet::Handler aUdpTransmitHandle, + Timer::Handler aRetransmissionTimer, + Timer::Handler aResponsesQueueTimer); #endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE /** @@ -331,7 +334,7 @@ public: const Ip6::MessageInfo &GetPeerMessageInfo(void) const { return mPeerAddress; } protected: - void HandleUdpTransmit(void); + void HandleTransmit(void); private: virtual otError Send(Message &aMessage, const Ip6::MessageInfo &aMessageInfo); @@ -347,12 +350,15 @@ private: static void HandleRetransmissionTimer(Timer &aTimer); static void HandleResponsesQueueTimer(Timer &aTimer); + static void HandleTransmit(Tasklet &aTasklet); Ip6::MessageInfo mPeerAddress; ConnectedCallback mConnectedCallback; void * mConnectedContext; TransportCallback mTransportCallback; void * mTransportContext; + MessageQueue mTransmitQueue; + Tasklet mTransmitTask; bool mLayerTwoSecurity : 1; }; @@ -377,6 +383,7 @@ public: private: static void HandleRetransmissionTimer(Timer &aTimer); static void HandleResponsesQueueTimer(Timer &aTimer); + static void HandleTransmit(Tasklet &aTasklet); }; #endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE