diff --git a/include/openthread-types.h b/include/openthread-types.h index 9422a65ab..757b2600d 100644 --- a/include/openthread-types.h +++ b/include/openthread-types.h @@ -167,6 +167,10 @@ typedef enum ThreadError */ kThreadError_ResponseTimeout = 30, + /** + * Received a duplicated frame. + */ + kThreadError_Duplicated = 31, kThreadError_Error = 255, } ThreadError; @@ -822,6 +826,7 @@ typedef struct otMacCounters uint32_t mRxOther; ///< The number of received other types of frames. uint32_t mRxWhitelistFiltered; ///< The number of received packets filtered by whitelist. uint32_t mRxDestAddrFiltered; ///< The number of received packets filtered by destination check. + uint32_t mRxDuplicated; ///< The number of received duplicated packets. uint32_t mRxErrNoFrame; ///< The number of received packets that do not contain contents. uint32_t mRxErrUnknownNeighbor; ///< The number of received packets from unknown neighbor. uint32_t mRxErrInvalidSrcAddr; ///< The number of received packets whose source address is invalid. diff --git a/src/cli/README.md b/src/cli/README.md index 016d54ea7..255c49714 100644 --- a/src/cli/README.md +++ b/src/cli/README.md @@ -360,6 +360,7 @@ RxTotal: 11 RxOther: 0 RxWhitelistFiltered: 0 RxDestAddrFiltered: 0 + RxDuplicated: 0 RxErrNoFrame: 0 RxErrNoUnknownNeighbor: 0 RxErrInvalidSrcAddr: 0 diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 05a15c9e8..952fd2e82 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -512,6 +512,7 @@ void Interpreter::ProcessCounters(int argc, char *argv[]) sServer->OutputFormat(" RxOther: %d\r\n", counters->mRxOther); sServer->OutputFormat(" RxWhitelistFiltered: %d\r\n", counters->mRxWhitelistFiltered); sServer->OutputFormat(" RxDestAddrFiltered: %d\r\n", counters->mRxDestAddrFiltered); + sServer->OutputFormat(" RxDuplicated: %d\r\n", counters->mRxDuplicated); sServer->OutputFormat(" RxErrNoFrame: %d\r\n", counters->mRxErrNoFrame); sServer->OutputFormat(" RxErrNoUnknownNeighbor: %d\r\n", counters->mRxErrUnknownNeighbor); sServer->OutputFormat(" RxErrInvalidSrcAddr: %d\r\n", counters->mRxErrInvalidSrcAddr); diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index a1a51916c..5a2939728 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -1059,10 +1059,22 @@ ThreadError Mac::ProcessReceiveSecurity(Frame &aFrame, const Address &aSrcAddr, ExitNow(error = kThreadError_Security); } - VerifyOrExit((keySequence > aNeighbor->mKeySequence) || - ((keySequence == aNeighbor->mKeySequence) && - (frameCounter >= aNeighbor->mValid.mLinkFrameCounter)), - error = kThreadError_Security); + if (keySequence < aNeighbor->mKeySequence) + { + ExitNow(error = kThreadError_Security); + } + else if (keySequence == aNeighbor->mKeySequence) + { + if ((frameCounter + 1) < aNeighbor->mValid.mLinkFrameCounter) + { + ExitNow(error = kThreadError_Security); + } + else if ((frameCounter + 1) == aNeighbor->mValid.mLinkFrameCounter) + { + // drop duplicated packets + ExitNow(error = kThreadError_Duplicated); + } + } extAddress = &aSrcAddr.mExtAddress; @@ -1109,11 +1121,11 @@ ThreadError Mac::ProcessReceiveSecurity(Frame &aFrame, const Address &aSrcAddr, exit: - if (error != kThreadError_None) + if (error == kThreadError_Security) { for (Receiver *receiver = mReceiveHead; receiver; receiver = receiver->mNext) { - receiver->HandleReceivedFrame(aFrame, kThreadError_Security); + receiver->HandleReceivedFrame(aFrame, error); } } @@ -1322,6 +1334,10 @@ exit: mCounters.mRxDestAddrFiltered++; break; + case kThreadError_Duplicated: + mCounters.mRxDuplicated++; + break; + default: mCounters.mRxErrOther++; break; diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index dfdc5b0bf..54097df16 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -179,6 +179,7 @@ const NcpBase::GetPropertyHandlerEntry NcpBase::mGetPropertyHandlerTable[] = { SPINEL_PROP_CNTR_RX_ERR_SECURITY, &NcpBase::GetPropertyHandler_MAC_CNTR }, { SPINEL_PROP_CNTR_RX_ERR_BAD_FCS, &NcpBase::GetPropertyHandler_MAC_CNTR }, { SPINEL_PROP_CNTR_RX_ERR_OTHER, &NcpBase::GetPropertyHandler_MAC_CNTR }, + { SPINEL_PROP_CNTR_RX_PKT_DUP, &NcpBase::GetPropertyHandler_MAC_CNTR }, { SPINEL_PROP_CNTR_TX_IP_SEC_TOTAL, &NcpBase::GetPropertyHandler_NCP_CNTR }, { SPINEL_PROP_CNTR_TX_IP_INSEC_TOTAL, &NcpBase::GetPropertyHandler_NCP_CNTR }, @@ -2438,6 +2439,10 @@ ThreadError NcpBase::GetPropertyHandler_MAC_CNTR(uint8_t header, spinel_prop_key value = macCounters->mRxDestAddrFiltered; break; + case SPINEL_PROP_CNTR_RX_PKT_DUP: + value = macCounters->mRxDuplicated; + break; + case SPINEL_PROP_CNTR_RX_ERR_EMPTY: value = macCounters->mRxErrNoFrame; break; diff --git a/src/ncp/spinel.h b/src/ncp/spinel.h index e8c7ba6c7..5eaff6bad 100644 --- a/src/ncp/spinel.h +++ b/src/ncp/spinel.h @@ -728,6 +728,10 @@ typedef enum /** Format: `L` (Read-only) */ SPINEL_PROP_CNTR_RX_ERR_OTHER = SPINEL_PROP_CNTR__BEGIN + 113, + /// The number of received duplicated. + /** Format: `L` (Read-only) */ + SPINEL_PROP_CNTR_RX_PKT_DUP = SPINEL_PROP_CNTR__BEGIN + 114, + /// The total number of secure transmitted IP messages. /** Format: `L` (Read-only) */ SPINEL_PROP_CNTR_TX_IP_SEC_TOTAL = SPINEL_PROP_CNTR__BEGIN + 200,