From 00a3905fdeab181899d959ea83978a4212b3551f Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Tue, 20 Feb 2018 09:29:40 -0800 Subject: [PATCH] [mac] avoid data poll timeout when a duplicate frame is received (#2563) This commit changes how `Mac::HandleReceivedFrame()` handles duplicate received frame when a sleepy device is waiting for data after a data poll ack from parent indicating a pending frame. This change ensures that the sleepy device can go to sleep faster and avoid a data poll timeout. --- src/core/mac/mac.cpp | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index ba902eb37..87415a305 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -1741,7 +1741,35 @@ void Mac::HandleReceivedFrame(Frame *aFrame, otError aError) } // Security Processing - SuccessOrExit(error = ProcessReceiveSecurity(*aFrame, srcaddr, neighbor)); + error = ProcessReceiveSecurity(*aFrame, srcaddr, neighbor); + + switch (error) + { + case OT_ERROR_DUPLICATED: + + // Allow a duplicate received frame pass, only if the + // current operation is `kOperationWaitingForData` (i.e., + // the sleepy device is waiting to receive a frame after + // a data poll ack from parent indicating there is a + // pending frame for it). This ensures that the sleepy + // device goes to sleep faster and avoids a data poll + // timeout. + // + // Note that `error` is checked again later after the + // operation `kOperationWaitingForData` is processed + // so the duplicate frame will not be passed to any + // registered `Receiver`. + + VerifyOrExit(mOperation == kOperationWaitingForData); + + // Fall through + + case OT_ERROR_NONE: + break; + + default: + ExitNow(); + } if (neighbor != NULL) { @@ -1811,6 +1839,8 @@ void Mac::HandleReceivedFrame(Frame *aFrame, otError aError) FinishOperation(); } + SuccessOrExit(error); + break; default: