diff --git a/src/core/net/ip6.cpp b/src/core/net/ip6.cpp index 673cdbc26..152139db3 100644 --- a/src/core/net/ip6.cpp +++ b/src/core/net/ip6.cpp @@ -304,6 +304,29 @@ exit: return error; } +void Ip6::ProcessReceiveCallback(Message &aMessage) +{ + ThreadError error = kThreadError_None; + Message *messageCopy; + + VerifyOrExit(sReceiveIp6DatagramCallback != NULL, ;); + + // make a copy of the datagram to pass to host + VerifyOrExit((messageCopy = NewMessage(0)) != NULL, ;); + SuccessOrExit(error = messageCopy->SetLength(aMessage.GetLength())); + VerifyOrExit(aMessage.CopyTo(0, 0, aMessage.GetLength(), *messageCopy) == aMessage.GetLength(), + error = kThreadError_Drop); + + sReceiveIp6DatagramCallback(messageCopy); + +exit: + + if (error != kThreadError_None && messageCopy != NULL) + { + Message::Free(*messageCopy); + } +} + ThreadError Ip6::HandleDatagram(Message &message, Netif *netif, uint8_t interfaceId, const void *linkMessageInfo, bool fromLocalHost) { @@ -383,13 +406,12 @@ ThreadError Ip6::HandleDatagram(Message &message, Netif *netif, uint8_t interfac // process IPv6 Payload if (receive) { - SuccessOrExit(HandlePayload(message, messageInfo, nextHeader)); - - if (sReceiveIp6DatagramCallback != NULL && fromLocalHost == false) + if (fromLocalHost == false) { - sReceiveIp6DatagramCallback(&message); - ExitNow(error = kThreadError_None); + ProcessReceiveCallback(message); } + + SuccessOrExit(HandlePayload(message, messageInfo, nextHeader)); } if (forward) diff --git a/src/core/net/ip6.hpp b/src/core/net/ip6.hpp index 1fbb270d1..27313ed74 100644 --- a/src/core/net/ip6.hpp +++ b/src/core/net/ip6.hpp @@ -530,7 +530,6 @@ public: */ static uint16_t UpdateChecksum(uint16_t aChecksum, uint16_t aValue); - /** * This static method updates a checksum. * @@ -571,12 +570,14 @@ public: /** * This function registers a callback to provide received raw IPv6 datagrams. * - * @param[in] aCallback A pointer to a function that is called when an IPv6 datagram is received or NULL to disable - * the callback. + * @param[in] aCallback A pointer to a function that is called when an IPv6 datagram is received or NULL to + * disable the callback. * */ static void SetReceiveDatagramCallback(otReceiveIp6DatagramCallback aCallback); +private: + static void ProcessReceiveCallback(Message &aMessage); }; /**