From b6ebabf2e40561b454648ef441a5a799c17a6356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Duda?= Date: Fri, 14 Oct 2016 18:37:26 +0200 Subject: [PATCH] Message: Add Clone method. (#804) * Message: Add Clone method. Packet cloning is done only inside ip6.cpp right now, but this method might be useful for MPL and CoAP retransmissions in order to not repeat the same code. --- src/core/common/message.cpp | 26 ++++++++++++++++++++++++++ src/core/common/message.hpp | 10 +++++++++- src/core/net/ip6.cpp | 12 +----------- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/core/common/message.cpp b/src/core/common/message.cpp index 167cbd896..2237d3606 100644 --- a/src/core/common/message.cpp +++ b/src/core/common/message.cpp @@ -455,6 +455,32 @@ int Message::CopyTo(uint16_t aSourceOffset, uint16_t aDestinationOffset, uint16_ return bytesCopied; } +Message *Message::Clone(void) const +{ + ThreadError error = kThreadError_None; + Message *messageCopy; + + VerifyOrExit((messageCopy = GetMessagePool()->New(GetType(), GetReserved())) != NULL, error = kThreadError_NoBufs); + SuccessOrExit(error = messageCopy->SetLength(GetLength())); + CopyTo(0, 0, GetLength(), *messageCopy); + + // Copy selected message information. + messageCopy->SetOffset(GetOffset()); + messageCopy->SetInterfaceId(GetInterfaceId()); + messageCopy->SetSubType(GetSubType()); + messageCopy->SetLinkSecurityEnabled(IsLinkSecurityEnabled()); + +exit: + + if (error != kThreadError_None && messageCopy != NULL) + { + messageCopy->Free(); + messageCopy = NULL; + } + + return messageCopy; +} + uint16_t Message::GetDatagramTag(void) const { return mInfo.mDatagramTag; diff --git a/src/core/common/message.hpp b/src/core/common/message.hpp index 53f4f4f36..fda272dd1 100644 --- a/src/core/common/message.hpp +++ b/src/core/common/message.hpp @@ -384,6 +384,14 @@ public: */ int CopyTo(uint16_t aSourceOffset, uint16_t aDestinationOffset, uint16_t aLength, Message &aMessage) const; + /** + * This method creates a copy of the current Message. It allocates the new one + * from the same Message Poll as the original Message. + * + * @returns A pointer to the message or NULL if insufficient message buffers are available. + */ + Message *Clone(void) const; + /** * This method returns the datagram tag used for 6LoWPAN fragmentation. * @@ -559,7 +567,7 @@ public: uint16_t UpdateChecksum(uint16_t aChecksum, uint16_t aOffset, uint16_t aLength) const; private: - MessagePool *GetMessagePool(void) { return mInfo.mMessagePool; } + MessagePool *GetMessagePool(void) const { return mInfo.mMessagePool; } void SetMessagePool(MessagePool *aMessagePool) { mInfo.mMessagePool = aMessagePool; } diff --git a/src/core/net/ip6.cpp b/src/core/net/ip6.cpp index c60dc5c89..2162b1a02 100644 --- a/src/core/net/ip6.cpp +++ b/src/core/net/ip6.cpp @@ -412,20 +412,10 @@ ThreadError Ip6::ProcessReceiveCallback(const Message &aMessage, const MessageIn } // make a copy of the datagram to pass to host - VerifyOrExit((messageCopy = NewMessage(0)) != NULL, error = kThreadError_NoBufs); - SuccessOrExit(error = messageCopy->SetLength(aMessage.GetLength())); - aMessage.CopyTo(0, 0, aMessage.GetLength(), *messageCopy); - messageCopy->SetLinkSecurityEnabled(aMessage.IsLinkSecurityEnabled()); - + VerifyOrExit((messageCopy = aMessage.Clone()) != NULL, error = kThreadError_NoBufs); mReceiveIp6DatagramCallback(messageCopy, mReceiveIp6DatagramCallbackContext); exit: - - if (error != kThreadError_None && messageCopy != NULL) - { - messageCopy->Free(); - } - return error; }