[coap] fix secure coap retransmission issue (#2128)

This commit fixes a bug in SecureCoap encountered when testing commissioning.

A little bit of background - after GetOwner method in CoAP was introduced, a problem with a static handler of mRetransmissionTimer showed up. In single instance mode, whenever retransmission timer striked, static GetOwner method from Coap class was called, regardless if the timer was a member of a Coap or SecureCoap class.

As there are separate instances for Coap and SecureCoap: mCoap and mCoapSecure, the former one was always returned. In result, there was no chance to handle messages queued for retransmission in an instance of SecureCoap. This resulted in commissionig failure in case a retransmission of JoinerFinalize message was needed.

The same pattern would apply for any class that uses inheritance and uses GetOwner in static handlers.

This fix extends the Coap constructor with an optional parameter -aRetransmissionHandler. This way, SecureCoap instances can register their own static timer handler and thereby use correct GetOwner funcion.
This commit is contained in:
Robert Lubos
2017-08-24 11:26:36 -07:00
committed by Jonathan Hui
parent d85bb5a2c1
commit 293d0d4c66
4 changed files with 20 additions and 6 deletions
+2 -2
View File
@@ -49,10 +49,10 @@
namespace ot {
namespace Coap {
Coap::Coap(ThreadNetif &aNetif):
Coap::Coap(ThreadNetif &aNetif, Timer::Handler aRetransmissionHandler):
ThreadNetifLocator(aNetif),
mSocket(aNetif.GetIp6().mUdp),
mRetransmissionTimer(aNetif.GetInstance(), &Coap::HandleRetransmissionTimer, this),
mRetransmissionTimer(aNetif.GetInstance(), aRetransmissionHandler, this),
mResources(NULL),
mContext(NULL),
mInterceptor(NULL),
+10 -3
View File
@@ -443,10 +443,11 @@ public:
/**
* This constructor initializes the object.
*
* @param[in] aNetif A reference to the Netif 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);
Coap(ThreadNetif &aNetif, Timer::Handler aRetransmissionHandler = &Coap::HandleRetransmissionTimer);
/**
* This method starts the CoAP service.
@@ -646,6 +647,12 @@ public:
const MessageQueue &GetCachedResponses(void) const { return mResponsesQueue.GetResponses(); }
protected:
/**
* Retransmission timer handler.
*
*/
void HandleRetransmissionTimer(void);
/**
* This method send a message.
*
@@ -688,8 +695,8 @@ private:
otError SendCopy(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
otError SendEmptyMessage(Header::Type aType, const Header &aRequestHeader,
const Ip6::MessageInfo &aMessageInfo);
static void HandleRetransmissionTimer(Timer &aTimer);
void HandleRetransmissionTimer(void);
static Coap &GetOwner(const Context &aContext);
+6 -1
View File
@@ -48,7 +48,7 @@ namespace ot {
namespace Coap {
CoapSecure::CoapSecure(ThreadNetif &aNetif):
Coap(aNetif),
Coap(aNetif, &CoapSecure::HandleRetransmissionTimer),
mConnectedCallback(NULL),
mConnectedContext(NULL),
mTransportCallback(NULL),
@@ -320,6 +320,11 @@ CoapSecure &CoapSecure::GetOwner(const Context &aContext)
return coap;
}
void CoapSecure::HandleRetransmissionTimer(Timer &aTimer)
{
GetOwner(aTimer).Coap::HandleRetransmissionTimer();
}
} // namespace Coap
} // namespace ot
+2
View File
@@ -214,6 +214,8 @@ private:
static void HandleUdpTransmit(Tasklet &aTasklet);
void HandleUdpTransmit(void);
static void HandleRetransmissionTimer(Timer &aTimer);
static CoapSecure &GetOwner(const Context &aContext);
Ip6::MessageInfo mPeerAddress;