From adbef3b8207ee13db6b0aaf0f05c3a0ff7c89d7a Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Mon, 24 Apr 2017 18:47:00 -0700 Subject: [PATCH] Ensure fairness in handling of data polls from sleepy children (#1646) To ensure fairness in handling of data requests (data polls) from sleepy children, once a message is scheduled and prepared for indirect transmission to a child, the child index is remembered and in the subsequent tx schedule, the check for data polls begins from the next child index. --- src/core/thread/mesh_forwarder.cpp | 28 ++++++++++++++++++++++++++-- src/core/thread/mesh_forwarder.hpp | 3 +-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp index fd1d73de2..5863570fd 100644 --- a/src/core/thread/mesh_forwarder.cpp +++ b/src/core/thread/mesh_forwarder.cpp @@ -67,6 +67,7 @@ MeshForwarder::MeshForwarder(ThreadNetif &aThreadNetif): mSendMessageMaxMacTxAttempts(Mac::kDirectFrameMacTxAttempts), mSendMessageKeyId(0), mSendMessageDataSequenceNumber(0), + mStartChildIndex(0), mMeshSource(Mac::kShortAddrInvalid), mMeshDest(Mac::kShortAddrInvalid), mAddMeshHeader(false), @@ -240,6 +241,8 @@ void MeshForwarder::ScheduleTransmissionTask(void) { ThreadError error = kThreadError_None; uint8_t numChildren; + uint8_t childIndex; + uint8_t nextIndex; Child *children; VerifyOrExit(mSendBusy == false, error = kThreadError_Busy); @@ -250,9 +253,21 @@ void MeshForwarder::ScheduleTransmissionTask(void) children = mNetif.GetMle().GetChildren(&numChildren); - for (int i = 0; i < numChildren; i++) + if (mStartChildIndex >= numChildren) { - Child &child = children[i]; + mStartChildIndex = 0; + } + + childIndex = mStartChildIndex; + + for (uint8_t iterations = numChildren; iterations > 0; iterations--, childIndex = nextIndex) + { + Child &child = children[childIndex]; + + if ((nextIndex = childIndex + 1) == numChildren) + { + nextIndex = 0; + } if (!child.IsStateValidOrRestoring() || !child.IsDataRequestPending()) { @@ -293,6 +308,15 @@ void MeshForwarder::ScheduleTransmissionTask(void) } } + // To ensure fairness in handling of data requests from sleepy + // children, once a message is scheduled and prepared for indirect + // transmission to a child, the `mStartChildIndex` is updated to + // the next index after the current child. Subsequent call to + // `ScheduleTransmissionTask()` will begin the iteration through + // the children list from this index. + + mStartChildIndex = nextIndex; + mNetif.GetMac().SendFrameRequest(mMacSender); ExitNow(); } diff --git a/src/core/thread/mesh_forwarder.hpp b/src/core/thread/mesh_forwarder.hpp index 7ee5cacc1..12db81c3e 100644 --- a/src/core/thread/mesh_forwarder.hpp +++ b/src/core/thread/mesh_forwarder.hpp @@ -316,6 +316,7 @@ private: uint8_t mSendMessageMaxMacTxAttempts; uint8_t mSendMessageKeyId; uint8_t mSendMessageDataSequenceNumber; + uint8_t mStartChildIndex; Mac::Address mMacSource; Mac::Address mMacDest; @@ -335,8 +336,6 @@ private: bool mScanning; DataPollManager mDataPollManager; - - SourceMatchController mSourceMatchController; };