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; }