diff --git a/src/core/common/message.cpp b/src/core/common/message.cpp index eb3ac6ed3..d848d6a58 100644 --- a/src/core/common/message.cpp +++ b/src/core/common/message.cpp @@ -497,6 +497,16 @@ void Message::SetTimeout(uint8_t aTimeout) mInfo.mTimeout = aTimeout; } +int8_t Message::GetInterfaceId(void) const +{ + return mInfo.mInterfaceId; +} + +void Message::SetInterfaceId(int8_t aInterfaceId) +{ + mInfo.mInterfaceId = aInterfaceId; +} + bool Message::GetDirectTransmission(void) const { return mInfo.mDirectTx; diff --git a/src/core/common/message.hpp b/src/core/common/message.hpp index 94f29238a..e800f928e 100644 --- a/src/core/common/message.hpp +++ b/src/core/common/message.hpp @@ -114,6 +114,7 @@ struct MessageInfo uint8_t mChildMask[8]; ///< A bit-vector to indicate which sleepy children need to receive this. uint16_t mPanId; ///< The Destination PAN ID. uint8_t mTimeout; ///< Seconds remaining before dropping the message. + int8_t mInterfaceId; ///< The interface ID. uint8_t mType : 2; ///< Identifies the type of message. bool mDirectTx : 1; ///< Used to indicate whether a direct transmission is required. @@ -433,6 +434,22 @@ public: */ void SetTimeout(uint8_t aTimeout); + /** + * This method returns the interface ID. + * + * @returns The interface ID. + * + */ + int8_t GetInterfaceId(void) const; + + /** + * This method sets the interface ID. + * + * @param[in] aInterfaceId The interface ID value. + * + */ + void SetInterfaceId(int8_t aInterfaceId); + /** * This method returns whether or not message forwarding is scheduled for direct transmission. * diff --git a/src/core/net/ip6.cpp b/src/core/net/ip6.cpp index d2497ad01..add9a5982 100644 --- a/src/core/net/ip6.cpp +++ b/src/core/net/ip6.cpp @@ -53,6 +53,7 @@ Ip6::Ip6(void): mUdp(*this), mMpl(*this), mForwardingEnabled(false), + mSendQueueTask(mTaskletScheduler, HandleSendQueue, this), mReceiveIp6DatagramCallback(NULL), mReceiveIp6DatagramCallbackContext(NULL), mIsReceiveIp6FilterEnabled(false), @@ -198,12 +199,29 @@ exit: if (error == kThreadError_None) { - HandleDatagram(message, NULL, messageInfo.mInterfaceId, NULL, false); + message.SetInterfaceId(messageInfo.mInterfaceId); + mSendQueue.Enqueue(message); + mSendQueueTask.Post(); } return error; } +void Ip6::HandleSendQueue(void *aContext) +{ + static_cast(aContext)->HandleSendQueue(); +} + +void Ip6::HandleSendQueue(void) +{ + while (mSendQueue.GetHead()) + { + Message *message = mSendQueue.GetHead(); + mSendQueue.Dequeue(*message); + HandleDatagram(*message, NULL, message->GetInterfaceId(), NULL, false); + } +} + ThreadError Ip6::HandleOptions(Message &message) { ThreadError error = kThreadError_None; diff --git a/src/core/net/ip6.hpp b/src/core/net/ip6.hpp index 305f716b2..77d3b35ab 100644 --- a/src/core/net/ip6.hpp +++ b/src/core/net/ip6.hpp @@ -332,6 +332,9 @@ public: TimerScheduler mTimerScheduler; private: + static void HandleSendQueue(void *aContext); + void HandleSendQueue(void); + void ProcessReceiveCallback(const Message &aMessage, const MessageInfo &aMessageInfo, uint8_t aIpProto); ThreadError HandleExtensionHeaders(Message &message, uint8_t &nextHeader, bool receive); ThreadError HandleFragment(Message &message); @@ -343,6 +346,9 @@ private: Mpl mMpl; bool mForwardingEnabled; + MessageQueue mSendQueue; + Tasklet mSendQueueTask; + otReceiveIp6DatagramCallback mReceiveIp6DatagramCallback; void *mReceiveIp6DatagramCallbackContext; bool mIsReceiveIp6FilterEnabled;