diff --git a/include/openthread-types.h b/include/openthread-types.h index b810f8386..49c27c840 100644 --- a/include/openthread-types.h +++ b/include/openthread-types.h @@ -859,6 +859,29 @@ typedef struct otMacCounters uint32_t mRxErrOther; ///< The number of received packets with other error. } otMacCounters; +/** + * This structure represents the message buffer information. + */ +typedef struct otBufferInfo +{ + uint16_t mTotalBuffers; ///< The number of buffers in the pool. + uint16_t mFreeBuffers; ///< The number of free message buffers. + uint16_t m6loSendMessages; ///< The number of messages in the 6lo send queue. + uint16_t m6loSendBuffers; ///< The number of buffers in the 6lo send queue. + uint16_t m6loReassemblyMessages; ///< The number of messages in the 6LoWPAN reassembly queue. + uint16_t m6loReassemblyBuffers; ///< The number of buffers in the 6LoWPAN reassembly queue. + uint16_t mIp6Messages; ///< The number of messages in the IPv6 send queue. + uint16_t mIp6Buffers; ///< The number of buffers in the IPv6 send queue. + uint16_t mMplMessages; ///< The number of messages in the MPL send queue. + uint16_t mMplBuffers; ///< The number of buffers in the MPL send queue. + uint16_t mMleMessages; ///< The number of messages in the MLE send queue. + uint16_t mMleBuffers; ///< The number of buffers in the MLE send queue. + uint16_t mArpMessages; ///< The number of messages in the ARP send queue. + uint16_t mArpBuffers; ///< The number of buffers in the ARP send queue. + uint16_t mCoapClientMessages; ///< The number of messages in the CoAP client send queue. + uint16_t mCoapClientBuffers; ///< The number of buffers in the CoAP client send queue. +} otBufferInfo; + /** * @} * diff --git a/include/openthread.h b/include/openthread.h index 35d25388d..60b1c3702 100644 --- a/include/openthread.h +++ b/include/openthread.h @@ -2053,6 +2053,15 @@ OTAPI ThreadError OTCALL otSendDiagnosticReset(otInstance *aInstance, const otIp */ OTAPI const otMacCounters *OTCALL otGetMacCounters(otInstance *aInstance); +/** + * Get the Message Buffer information. + * + * @param[in] aInstance A pointer to the OpenThread instance. + * @param[out] aBufferInfo A pointer where the message buffer information is written. + * + */ +OTAPI void OTCALL otGetMessageBufferInfo(otInstance *aInstance, otBufferInfo *aBufferInfo); + /** * @} * diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index fd0185161..860efc091 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -67,6 +67,7 @@ const struct Command Interpreter::sCommands[] = { { "help", &Interpreter::ProcessHelp }, { "blacklist", &Interpreter::ProcessBlacklist }, + { "bufferinfo", &Interpreter::ProcessBufferInfo }, { "channel", &Interpreter::ProcessChannel }, { "child", &Interpreter::ProcessChild }, { "childmax", &Interpreter::ProcessChildMax }, @@ -303,6 +304,27 @@ exit: AppendResult(error); } +void Interpreter::ProcessBufferInfo(int argc, char *argv[]) +{ + otBufferInfo bufferInfo; + (void)argc; + (void)argv; + + otGetMessageBufferInfo(mInstance, &bufferInfo); + + sServer->OutputFormat("total: %d\r\n", bufferInfo.mTotalBuffers); + sServer->OutputFormat("free: %d\r\n", bufferInfo.mFreeBuffers); + sServer->OutputFormat("6lo send: %d %d\r\n", bufferInfo.m6loSendMessages, bufferInfo.m6loSendBuffers); + sServer->OutputFormat("6lo reas: %d %d\r\n", bufferInfo.m6loReassemblyMessages, bufferInfo.m6loReassemblyBuffers); + sServer->OutputFormat("ip6: %d %d\r\n", bufferInfo.mIp6Messages, bufferInfo.mIp6Buffers); + sServer->OutputFormat("mpl: %d %d\r\n", bufferInfo.mMplMessages, bufferInfo.mMplBuffers); + sServer->OutputFormat("mle: %d %d\r\n", bufferInfo.mMleMessages, bufferInfo.mMleBuffers); + sServer->OutputFormat("arp: %d %d\r\n", bufferInfo.mArpMessages, bufferInfo.mArpBuffers); + sServer->OutputFormat("coap: %d %d\r\n", bufferInfo.mCoapClientMessages, bufferInfo.mCoapClientBuffers); + + AppendResult(kThreadError_None); +} + void Interpreter::ProcessChannel(int argc, char *argv[]) { ThreadError error = kThreadError_None; diff --git a/src/cli/cli.hpp b/src/cli/cli.hpp index 364633e81..032c6e09e 100644 --- a/src/cli/cli.hpp +++ b/src/cli/cli.hpp @@ -141,6 +141,7 @@ private: void OutputBytes(const uint8_t *aBytes, uint8_t aLength); void ProcessHelp(int argc, char *argv[]); + void ProcessBufferInfo(int argc, char *argv[]); void ProcessBlacklist(int argc, char *argv[]); void ProcessChannel(int argc, char *argv[]); void ProcessChild(int argc, char *argv[]); diff --git a/src/core/coap/coap_client.hpp b/src/core/coap/coap_client.hpp index 54b195976..bd5e9e1e7 100644 --- a/src/core/coap/coap_client.hpp +++ b/src/core/coap/coap_client.hpp @@ -241,6 +241,14 @@ public: ThreadError SendMessage(Message &aMessage, const Ip6::MessageInfo &aMessageInfo, otCoapResponseHandler aHandler = NULL, void *aContext = NULL); + /** + * This method returns a reference to the request message list. + * + * @returns A reference to the request message list. + * + */ + const MessageQueue &GetRequestMessages(void) const { return mPendingRequests; } + private: Message *CopyAndEnqueueMessage(const Message &aMessage, uint16_t aCopyLength, const RequestMetadata &aRequestMetadata); diff --git a/src/core/common/message.cpp b/src/core/common/message.cpp index f9a6e67d7..b53abba4a 100644 --- a/src/core/common/message.cpp +++ b/src/core/common/message.cpp @@ -221,6 +221,18 @@ exit: return error; } +uint8_t Message::GetBufferCount(void) const +{ + uint8_t rval = 1; + + for (const Buffer *curBuffer = GetNextBuffer(); curBuffer; curBuffer->GetNextBuffer()) + { + rval++; + } + + return rval; +} + uint16_t Message::GetOffset(void) const { return mInfo.mOffset; @@ -819,4 +831,16 @@ ThreadError MessageQueue::Dequeue(Message &aMessage) return kThreadError_None; } +void MessageQueue::GetInfo(uint16_t &aMessageCount, uint16_t &aBufferCount) const +{ + aMessageCount = 0; + aBufferCount = 0; + + for (const Message *message = mInterface.mHead; message; message = message->GetNext()) + { + aMessageCount++; + aBufferCount += message->GetBufferCount(); + } +} + } // namespace Thread diff --git a/src/core/common/message.hpp b/src/core/common/message.hpp index 1d590e029..05021d70f 100644 --- a/src/core/common/message.hpp +++ b/src/core/common/message.hpp @@ -258,6 +258,12 @@ public: */ ThreadError SetLength(uint16_t aLength); + /** + * This method returns the number of buffers in the message. + * + */ + uint8_t GetBufferCount(void) const; + /** * This method returns the byte offset within the message. * @@ -683,6 +689,15 @@ public: */ ThreadError Dequeue(Message &aMessage); + /** + * This method returns the number of messages and buffers enqueued. + * + * @param[out] aMessageCount Returns the number of messages enqueued. + * @param[out] aBufferCount Returns the number of buffers enqueued. + * + */ + void GetInfo(uint16_t &aMessageCount, uint16_t &aBufferCount) const; + private: /** * This static method adds a message to a list. @@ -745,6 +760,14 @@ public: */ ThreadError Free(Message *aMessage); + /** + * This method returns the number of free buffers. + * + * @returns The number of free buffers. + * + */ + uint16_t GetFreeBufferCount(void) const { return static_cast(mNumFreeBuffers); } + private: Buffer *NewBuffer(void); ThreadError FreeBuffers(Buffer *aBuffer); diff --git a/src/core/net/ip6.hpp b/src/core/net/ip6.hpp index d973ecb6e..0b507db12 100644 --- a/src/core/net/ip6.hpp +++ b/src/core/net/ip6.hpp @@ -330,6 +330,14 @@ public: */ otInstance *GetInstance(); + /** + * This method returns a reference to the send queue. + * + * @returns A reference to the send queue. + * + */ + const MessageQueue &GetSendQueue(void) const { return mSendQueue; } + Routes mRoutes; Icmp mIcmp; Udp mUdp; diff --git a/src/core/net/ip6_mpl.hpp b/src/core/net/ip6_mpl.hpp index 6faa9afbf..26646a4c1 100644 --- a/src/core/net/ip6_mpl.hpp +++ b/src/core/net/ip6_mpl.hpp @@ -504,6 +504,14 @@ public: */ void SetMatchingAddress(const Address &aAddress) { mMatchingAddress = &aAddress; } + /** + * This method returns a reference to the buffered message set. + * + * @returns A reference to the buffered message set. + * + */ + const MessageQueue &GetBufferedMessageSet(void) const { return mBufferedMessageSet; } + private: enum { diff --git a/src/core/openthread.cpp b/src/core/openthread.cpp index 855736a86..d85f919aa 100644 --- a/src/core/openthread.cpp +++ b/src/core/openthread.cpp @@ -897,6 +897,34 @@ const otMacCounters *otGetMacCounters(otInstance *aInstance) return &aInstance->mThreadNetif.GetMac().GetCounters(); } +void otGetMessageBufferInfo(otInstance *aInstance, otBufferInfo *aBufferInfo) +{ + aBufferInfo->mTotalBuffers = OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS; + + aBufferInfo->mFreeBuffers = aInstance->mThreadNetif.GetIp6().mMessagePool.GetFreeBufferCount(); + + aInstance->mThreadNetif.GetMeshForwarder().GetSendQueue().GetInfo(aBufferInfo->m6loSendMessages, + aBufferInfo->m6loSendBuffers); + + aInstance->mThreadNetif.GetMeshForwarder().GetReassemblyQueue().GetInfo(aBufferInfo->m6loReassemblyMessages, + aBufferInfo->m6loReassemblyBuffers); + + aInstance->mThreadNetif.GetMeshForwarder().GetResolvingQueue().GetInfo(aBufferInfo->mArpMessages, + aBufferInfo->mArpBuffers); + + aInstance->mThreadNetif.GetIp6().GetSendQueue().GetInfo(aBufferInfo->mIp6Messages, + aBufferInfo->mIp6Buffers); + + aInstance->mThreadNetif.GetIp6().mMpl.GetBufferedMessageSet().GetInfo(aBufferInfo->mMplMessages, + aBufferInfo->mMplBuffers); + + aInstance->mThreadNetif.GetMle().GetMessageQueue().GetInfo(aBufferInfo->mMleMessages, + aBufferInfo->mMleBuffers); + + aInstance->mThreadNetif.GetCoapClient().GetRequestMessages().GetInfo(aBufferInfo->mCoapClientMessages, + aBufferInfo->mCoapClientBuffers); +} + bool otIsIp6AddressEqual(const otIp6Address *a, const otIp6Address *b) { return *static_cast(a) == *static_cast(b); diff --git a/src/core/thread/mesh_forwarder.hpp b/src/core/thread/mesh_forwarder.hpp index 748fb3566..5ed5e4536 100644 --- a/src/core/thread/mesh_forwarder.hpp +++ b/src/core/thread/mesh_forwarder.hpp @@ -171,6 +171,30 @@ public: */ void SetDiscoverParameters(uint32_t aScanChannels, uint16_t aScanDuration); + /** + * This method returns a reference to the send queue. + * + * @returns A reference to the send queue. + * + */ + const MessageQueue &GetSendQueue(void) const { return mSendQueue; } + + /** + * This method returns a reference to the reassembly queue. + * + * @returns A reference to the reassembly queue. + * + */ + const MessageQueue &GetReassemblyQueue(void) const { return mReassemblyList; } + + /** + * This method returns a reference to the resolving queue. + * + * @returns A reference to the resolving queue. + * + */ + const MessageQueue &GetResolvingQueue(void) const { return mResolvingQueue; } + private: enum { diff --git a/src/core/thread/mle_router.hpp b/src/core/thread/mle_router.hpp index 95f8bebdb..9f2aa3299 100644 --- a/src/core/thread/mle_router.hpp +++ b/src/core/thread/mle_router.hpp @@ -623,6 +623,14 @@ public: */ void FillRouteTlv(RouteTlv &aTlv); + /** + * This method returns a reference to the send queue. + * + * @returns A reference to the send queue. + * + */ + const MessageQueue &GetMessageQueue(void) const { return mDelayedResponses; } + private: enum {