From 617f8958dd8aa36e3b3f14ec32a230a9735dbbad Mon Sep 17 00:00:00 2001 From: Yakun Xu Date: Wed, 1 May 2019 09:37:48 +0800 Subject: [PATCH] [mesh-forwarder] verify data request is ack with fp=1 (#3785) --- doc/spinel-protocol-src/spinel-prop-core.md | 3 ++- examples/platforms/cc1352/radio.c | 3 +++ examples/platforms/cc2538/radio.c | 3 +++ examples/platforms/cc2650/radio.c | 3 +++ examples/platforms/cc2652/radio.c | 3 +++ examples/platforms/da15000/radio.c | 4 ++++ examples/platforms/efr32/radio.c | 4 ++++ examples/platforms/emsk/radio.c | 3 +++ examples/platforms/gp712/radio.c | 4 ++++ examples/platforms/kw41z/radio.c | 4 ++++ examples/platforms/nrf52811/radio.c | 4 ++++ examples/platforms/nrf52840/radio.c | 4 ++++ examples/platforms/posix/radio.c | 2 ++ examples/platforms/posix/sim/radio-sim.c | 2 ++ examples/platforms/qpg6095/radio.c | 4 ++++ examples/platforms/samr21/radio.c | 4 ++++ include/openthread/platform/radio.h | 18 ++++++++++-------- src/core/mac/mac_frame.hpp | 9 +++++++++ src/core/thread/mesh_forwarder.cpp | 2 +- src/core/thread/mesh_forwarder.hpp | 2 +- src/core/thread/mesh_forwarder_ftd.cpp | 10 +++++++--- src/ncp/ncp_base_radio.cpp | 8 +++++++- src/ncp/spinel.h | 3 ++- src/posix/platform/radio_spinel.cpp | 2 ++ 24 files changed, 92 insertions(+), 16 deletions(-) diff --git a/doc/spinel-protocol-src/spinel-prop-core.md b/doc/spinel-protocol-src/spinel-prop-core.md index 2e87f7549..660bf2302 100644 --- a/doc/spinel-protocol-src/spinel-prop-core.md +++ b/doc/spinel-protocol-src/spinel-prop-core.md @@ -529,7 +529,8 @@ The bit values in `MD_FLAG` are defined as follows: 15 | 0x0001 | MD_FLAG_TX | Packet was transmitted, not received. 13 | 0x0004 | MD_FLAG_BAD_FCS | Packet was received with bad FCS 12 | 0x0008 | MD_FLAG_DUPE | Packet seems to be a duplicate -0-11, 14 | 0xFFF2 | MD_FLAG_RESERVED | Flags reserved for future use. +11 | 0x0010 | MD_FLAG_ACKED_FP | Packet was acknowledged with frame pending set +0-10, 14 | 0xFFE2 | MD_FLAG_RESERVED | Flags reserved for future use. The format of `MD_PHY` is specified by the PHY layer currently in use, and may contain information such as the channel, LQI, antenna, or other diff --git a/examples/platforms/cc1352/radio.c b/examples/platforms/cc1352/radio.c index 584ecddcd..715afeba1 100644 --- a/examples/platforms/cc1352/radio.c +++ b/examples/platforms/cc1352/radio.c @@ -1881,6 +1881,9 @@ static void cc1352RadioProcessTransmitDone(otInstance * aInstance, static void cc1352RadioProcessReceiveDone(otInstance *aInstance, otRadioFrame *aReceiveFrame, otError aReceiveError) { + // TODO Set this flag only when the packet is really acknowledged with frame pending set. + // See https://github.com/openthread/openthread/pull/3785 + aReceiveFrame->mInfo.mRxInfo.mAckedWithFramePending = true; #if OPENTHREAD_ENABLE_DIAG if (otPlatDiagModeGet()) diff --git a/examples/platforms/cc2538/radio.c b/examples/platforms/cc2538/radio.c index 884433a3e..62367ee0e 100644 --- a/examples/platforms/cc2538/radio.c +++ b/examples/platforms/cc2538/radio.c @@ -711,6 +711,9 @@ void cc2538RadioProcess(otInstance *aInstance) if ((sState == OT_RADIO_STATE_RECEIVE && sReceiveFrame.mLength > 0) || (sState == OT_RADIO_STATE_TRANSMIT && sReceiveFrame.mLength > IEEE802154_ACK_LENGTH)) { + // TODO Set this flag only when the packet is really acknowledged with frame pending set. + // See https://github.com/openthread/openthread/pull/3785 + sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = true; #if OPENTHREAD_ENABLE_DIAG if (otPlatDiagModeGet()) diff --git a/examples/platforms/cc2650/radio.c b/examples/platforms/cc2650/radio.c index 26451fd0e..49ee8b1c5 100644 --- a/examples/platforms/cc2650/radio.c +++ b/examples/platforms/cc2650/radio.c @@ -1798,6 +1798,9 @@ static void cc2650RadioProcessTransmitDone(otInstance * aInstance, static void cc2650RadioProcessReceiveDone(otInstance *aInstance, otRadioFrame *aReceiveFrame, otError aReceiveError) { + // TODO Set this flag only when the packet is really acknowledged with frame pending set. + // See https://github.com/openthread/openthread/pull/3785 + aReceiveFrame->mInfo.mRxInfo.mAckedWithFramePending = true; #if OPENTHREAD_ENABLE_DIAG if (otPlatDiagModeGet()) diff --git a/examples/platforms/cc2652/radio.c b/examples/platforms/cc2652/radio.c index b314caad5..2d2422cf5 100644 --- a/examples/platforms/cc2652/radio.c +++ b/examples/platforms/cc2652/radio.c @@ -1861,6 +1861,9 @@ static void cc2652RadioProcessTransmitDone(otInstance * aInstance, static void cc2652RadioProcessReceiveDone(otInstance *aInstance, otRadioFrame *aReceiveFrame, otError aReceiveError) { + // TODO Set this flag only when the packet is really acknowledged with frame pending set. + // See https://github.com/openthread/openthread/pull/3785 + aReceiveFrame->mInfo.mRxInfo.mAckedWithFramePending = true; #if OPENTHREAD_ENABLE_DIAG if (otPlatDiagModeGet()) diff --git a/examples/platforms/da15000/radio.c b/examples/platforms/da15000/radio.c index 69f15983f..dfb284c0b 100644 --- a/examples/platforms/da15000/radio.c +++ b/examples/platforms/da15000/radio.c @@ -508,6 +508,10 @@ void da15000RadioProcess(otInstance *aInstance) sAckFrame = true; } + // TODO Set this flag only when the packet is really acknowledged with frame pending set. + // See https://github.com/openthread/openthread/pull/3785 + sReceiveFrame[sReadFrame].mInfo.mRxInfo.mAckedWithFramePending = true; + otPlatRadioReceiveDone(sThreadInstance, &sReceiveFrame[sReadFrame], OT_ERROR_NONE); sReadFrame = (sReadFrame + 1) % RADIO_FRAMES_BUFFER_SIZE; diff --git a/examples/platforms/efr32/radio.c b/examples/platforms/efr32/radio.c index cdfdc5466..6c34bff40 100644 --- a/examples/platforms/efr32/radio.c +++ b/examples/platforms/efr32/radio.c @@ -680,6 +680,10 @@ static void processNextRxPacket(otInstance *aInstance, RAIL_Handle_t aRailHandle sReceiveError = OT_ERROR_NONE; + // TODO Set this flag only when the packet is really acknowledged with frame pending set. + // See https://github.com/openthread/openthread/pull/3785 + sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = true; + #if OPENTHREAD_ENABLE_DIAG if (otPlatDiagModeGet()) diff --git a/examples/platforms/emsk/radio.c b/examples/platforms/emsk/radio.c index 797d34969..fad42e3b3 100644 --- a/examples/platforms/emsk/radio.c +++ b/examples/platforms/emsk/radio.c @@ -564,6 +564,9 @@ void emskRadioProcess(otInstance *aInstance) if ((sState == OT_RADIO_STATE_RECEIVE) && (sReceiveFrame.mLength > 0)) { + // TODO Set this flag only when the packet is really acknowledged with frame pending set. + // See https://github.com/openthread/openthread/pull/3785 + sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = true; otPlatRadioReceiveDone(aInstance, &sReceiveFrame, sReceiveError); } diff --git a/examples/platforms/gp712/radio.c b/examples/platforms/gp712/radio.c index c64a449f6..ff6031c2e 100644 --- a/examples/platforms/gp712/radio.c +++ b/examples/platforms/gp712/radio.c @@ -226,6 +226,10 @@ void cbQorvoRadioReceiveDone(otRadioFrame *aPacket, otError aError) sLastReceivedPower = aPacket->mInfo.mRxInfo.mRssi; } + // TODO Set this flag only when the packet is really acknowledged with frame pending set. + // See https://github.com/openthread/openthread/pull/3785 + aPacket->mInfo.mRxInfo.mAckedWithFramePending = true; + otPlatRadioReceiveDone(pQorvoInstance, aPacket, aError); } diff --git a/examples/platforms/kw41z/radio.c b/examples/platforms/kw41z/radio.c index c007d65ef..9a5d6f7bc 100644 --- a/examples/platforms/kw41z/radio.c +++ b/examples/platforms/kw41z/radio.c @@ -987,6 +987,10 @@ void kw41zRadioProcess(otInstance *aInstance) if (sRxDone) { + // TODO Set this flag only when the packet is really acknowledged with frame pending set. + // See https://github.com/openthread/openthread/pull/3785 + sRxFrame.mInfo.mRxInfo.mAckedWithFramePending = true; + #if OPENTHREAD_ENABLE_DIAG if (otPlatDiagModeGet()) diff --git a/examples/platforms/nrf52811/radio.c b/examples/platforms/nrf52811/radio.c index 66f31411f..0275404d8 100644 --- a/examples/platforms/nrf52811/radio.c +++ b/examples/platforms/nrf52811/radio.c @@ -552,6 +552,10 @@ void nrf5RadioProcess(otInstance *aInstance) { if (sReceivedFrames[i].mPsdu != NULL) { + // TODO Set this flag only when the packet is really acknowledged with frame pending set. + // See https://github.com/openthread/openthread/pull/3785 + sReceivedFrames[i].mInfo.mRxInfo.mAckedWithFramePending = true; + #if OPENTHREAD_ENABLE_DIAG if (otPlatDiagModeGet()) diff --git a/examples/platforms/nrf52840/radio.c b/examples/platforms/nrf52840/radio.c index a513dd00e..28dac274f 100644 --- a/examples/platforms/nrf52840/radio.c +++ b/examples/platforms/nrf52840/radio.c @@ -552,6 +552,10 @@ void nrf5RadioProcess(otInstance *aInstance) { if (sReceivedFrames[i].mPsdu != NULL) { + // TODO Set this flag only when the packet is really acknowledged with frame pending set. + // See https://github.com/openthread/openthread/pull/3785 + sReceivedFrames[i].mInfo.mRxInfo.mAckedWithFramePending = true; + #if OPENTHREAD_ENABLE_DIAG if (otPlatDiagModeGet()) diff --git a/examples/platforms/posix/radio.c b/examples/platforms/posix/radio.c index 0b4f7a0ef..c467378ee 100644 --- a/examples/platforms/posix/radio.c +++ b/examples/platforms/posix/radio.c @@ -776,6 +776,7 @@ void radioSendAck(void) if (isDataRequestAndHasFramePending(sReceiveFrame.mPsdu)) { sAckMessage.mPsdu[0] |= IEEE802154_FRAME_PENDING; + sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = true; } sAckMessage.mPsdu[1] = 0; @@ -824,6 +825,7 @@ void radioProcessFrame(otInstance *aInstance) sReceiveFrame.mInfo.mRxInfo.mRssi = -20; sReceiveFrame.mInfo.mRxInfo.mLqi = OT_RADIO_LQI_NONE; + sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = false; // generate acknowledgment if (isAckRequested(sReceiveFrame.mPsdu)) { diff --git a/examples/platforms/posix/sim/radio-sim.c b/examples/platforms/posix/sim/radio-sim.c index 1d08fb35e..9f6e66618 100644 --- a/examples/platforms/posix/sim/radio-sim.c +++ b/examples/platforms/posix/sim/radio-sim.c @@ -642,6 +642,7 @@ void radioSendAck(void) if (isDataRequestAndHasFramePending(sReceiveFrame.mPsdu)) { sAckMessage.mPsdu[0] |= IEEE802154_FRAME_PENDING; + sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = true; } sAckMessage.mPsdu[1] = 0; @@ -690,6 +691,7 @@ void radioProcessFrame(otInstance *aInstance) sReceiveFrame.mInfo.mRxInfo.mRssi = -20; sReceiveFrame.mInfo.mRxInfo.mLqi = OT_RADIO_LQI_NONE; + sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = false; // generate acknowledgment if (isAckRequested(sReceiveFrame.mPsdu)) { diff --git a/examples/platforms/qpg6095/radio.c b/examples/platforms/qpg6095/radio.c index b12ba1db2..d6b7c2588 100644 --- a/examples/platforms/qpg6095/radio.c +++ b/examples/platforms/qpg6095/radio.c @@ -217,6 +217,10 @@ void cbQorvoRadioTransmitDone(otRadioFrame *aPacket, bool aFramePending, otError void cbQorvoRadioReceiveDone(otRadioFrame *aPacket, otError aError) { + // TODO Set this flag only when the packet is really acknowledged with frame pending set. + // See https://github.com/openthread/openthread/pull/3785 + aPacket->mInfo.mRxInfo.mAckedWithFramePending = true; + otPlatRadioReceiveDone(pQorvoInstance, aPacket, aError); } diff --git a/examples/platforms/samr21/radio.c b/examples/platforms/samr21/radio.c index 595504725..621b26301 100644 --- a/examples/platforms/samr21/radio.c +++ b/examples/platforms/samr21/radio.c @@ -225,6 +225,10 @@ static void handleRx(void) sReceiveFrame.mInfo.mRxInfo.mUsec = 0; // Don't support microsecond timer for now. } + // TODO Set this flag only when the packet is really acknowledged with frame pending set. + // See https://github.com/openthread/openthread/pull/3785 + sReceiveFrame.mInfo.mRxInfo.mAckedWithFramePending = true; + #if OPENTHREAD_ENABLE_DIAG if (otPlatDiagModeGet()) diff --git a/include/openthread/platform/radio.h b/include/openthread/platform/radio.h index 6f6334e4f..3cd020f96 100644 --- a/include/openthread/platform/radio.h +++ b/include/openthread/platform/radio.h @@ -202,8 +202,12 @@ typedef struct otRadioFrame */ struct { - int8_t mRssi; ///< Received signal strength indicator in dBm for received frames. - uint8_t mLqi; ///< Link Quality Indicator for received frames. + /** + * The timestamp when the frame was received (milliseconds). + * Applicable/Required only when raw-link-api feature (`OPENTHREAD_ENABLE_RAW_LINK_API`) is enabled. + * + */ + uint32_t mMsec; /** * The timestamp when the frame was received (microseconds, the offset to mMsec). @@ -211,13 +215,11 @@ typedef struct otRadioFrame * */ uint16_t mUsec; + int8_t mRssi; ///< Received signal strength indicator in dBm for received frames. + uint8_t mLqi; ///< Link Quality Indicator for received frames. - /** - * The timestamp when the frame was received (milliseconds). - * Applicable/Required only when raw-link-api feature (`OPENTHREAD_ENABLE_RAW_LINK_API`) is enabled. - * - */ - uint32_t mMsec; + // Flags + bool mAckedWithFramePending : 1; /// This indicates if this frame was acknowledged with frame pending set. } mRxInfo; } mInfo; } otRadioFrame; diff --git a/src/core/mac/mac_frame.hpp b/src/core/mac/mac_frame.hpp index fbf4e5d12..020e9a24a 100644 --- a/src/core/mac/mac_frame.hpp +++ b/src/core/mac/mac_frame.hpp @@ -1017,6 +1017,15 @@ public: */ bool IsARetransmission(void) const { return mInfo.mTxInfo.mIsARetx; } + /** + * This method indicates whether or not the received frame is acknowledged with frame pending set. + * + * @retval TRUE This frame is acknowledged with frame pending set. + * @retval FALSE This frame is acknowledged with frame pending not set. + * + */ + bool IsAckedWithFramePending(void) const { return mInfo.mRxInfo.mAckedWithFramePending; } + /** * This method sets the retransmission flag attribute. * diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp index b59224254..50387bd91 100644 --- a/src/core/thread/mesh_forwarder.cpp +++ b/src/core/thread/mesh_forwarder.cpp @@ -1269,7 +1269,7 @@ void MeshForwarder::HandleReceivedFrame(Mac::Frame &aFrame) if (commandId == Mac::Frame::kMacCmdDataRequest) { - HandleDataRequest(macSource, linkInfo); + HandleDataRequest(aFrame, macSource, linkInfo); } else { diff --git a/src/core/thread/mesh_forwarder.hpp b/src/core/thread/mesh_forwarder.hpp index b4ef6706d..aa4209643 100644 --- a/src/core/thread/mesh_forwarder.hpp +++ b/src/core/thread/mesh_forwarder.hpp @@ -398,7 +398,7 @@ private: const Mac::Address & aMacSource, const Mac::Address & aMacDest, const otThreadLinkInfo &aLinkInfo); - void HandleDataRequest(const Mac::Address &aMacSource, const otThreadLinkInfo &aLinkInfo); + void HandleDataRequest(const Mac::Frame &aFrame, const Mac::Address &aMacSource, const otThreadLinkInfo &aLinkInfo); static otError GetFragmentHeader(const uint8_t * aFrame, uint8_t aFrameLength, diff --git a/src/core/thread/mesh_forwarder_ftd.cpp b/src/core/thread/mesh_forwarder_ftd.cpp index 08c82b263..e4fee44b5 100644 --- a/src/core/thread/mesh_forwarder_ftd.cpp +++ b/src/core/thread/mesh_forwarder_ftd.cpp @@ -551,7 +551,9 @@ void MeshForwarder::SendMesh(Message &aMessage, Mac::Frame &aFrame) mMessageNextOffset = aMessage.GetLength(); } -void MeshForwarder::HandleDataRequest(const Mac::Address &aMacSource, const otThreadLinkInfo &aLinkInfo) +void MeshForwarder::HandleDataRequest(const Mac::Frame & aFrame, + const Mac::Address & aMacSource, + const otThreadLinkInfo &aLinkInfo) { Child * child; uint16_t indirectMsgCount; @@ -568,6 +570,10 @@ void MeshForwarder::HandleDataRequest(const Mac::Address &aMacSource, const otTh child->ResetLinkFailures(); indirectMsgCount = child->GetIndirectMessageCount(); + otLogInfoMac("Rx data poll, src:0x%04x, qed_msgs:%d, rss:%d ack-fp:%d", child->GetRloc16(), indirectMsgCount, + aLinkInfo.mRss, aFrame.IsAckedWithFramePending()); + VerifyOrExit(aFrame.IsAckedWithFramePending()); + if (!mSourceMatchController.IsEnabled() || (indirectMsgCount > 0)) { child->SetDataRequestPending(true); @@ -575,8 +581,6 @@ void MeshForwarder::HandleDataRequest(const Mac::Address &aMacSource, const otTh mScheduleTransmissionTask.Post(); - otLogInfoMac("Rx data poll, src:0x%04x, qed_msgs:%d, rss:%d", child->GetRloc16(), indirectMsgCount, aLinkInfo.mRss); - exit: return; } diff --git a/src/ncp/ncp_base_radio.cpp b/src/ncp/ncp_base_radio.cpp index c1f917567..46b5d4b1e 100644 --- a/src/ncp/ncp_base_radio.cpp +++ b/src/ncp/ncp_base_radio.cpp @@ -78,7 +78,13 @@ void NcpBase::LinkRawReceiveDone(otRadioFrame *aFrame, otError aError) // Append metadata (rssi, etc) SuccessOrExit(mEncoder.WriteInt8(aFrame->mInfo.mRxInfo.mRssi)); // RSSI SuccessOrExit(mEncoder.WriteInt8(-128)); // Noise Floor (Currently unused) - SuccessOrExit(mEncoder.WriteUint16(flags)); // Flags + + if (aFrame->mInfo.mRxInfo.mAckedWithFramePending) + { + flags |= SPINEL_MD_FLAG_ACKED_FP; + } + + SuccessOrExit(mEncoder.WriteUint16(flags)); // Flags SuccessOrExit(mEncoder.OpenStruct()); // PHY-data SuccessOrExit(mEncoder.WriteUint8(aFrame->mChannel)); // 802.15.4 channel (Receive channel) diff --git a/src/ncp/spinel.h b/src/ncp/spinel.h index 7a68c1151..153e0468f 100644 --- a/src/ncp/spinel.h +++ b/src/ncp/spinel.h @@ -399,7 +399,8 @@ enum SPINEL_MD_FLAG_TX = 0x0001, //!< Packet was transmitted, not received. SPINEL_MD_FLAG_BAD_FCS = 0x0004, //!< Packet was received with bad FCS SPINEL_MD_FLAG_DUPE = 0x0008, //!< Packet seems to be a duplicate - SPINEL_MD_FLAG_RESERVED = 0xFFF2, //!< Flags reserved for future use. + SPINEL_MD_FLAG_ACKED_FP = 0x0010, //!< Packet was acknowledged with frame pending set + SPINEL_MD_FLAG_RESERVED = 0xFFE2, //!< Flags reserved for future use. }; enum diff --git a/src/posix/platform/radio_spinel.cpp b/src/posix/platform/radio_spinel.cpp index ef9b7ee56..3290615a2 100644 --- a/src/posix/platform/radio_spinel.cpp +++ b/src/posix/platform/radio_spinel.cpp @@ -635,6 +635,8 @@ otError RadioSpinel::ParseRadioFrame(otRadioFrame &aFrame, const uint8_t *aBuffe if (receiveError == OT_ERROR_NONE) { aFrame.mLength = static_cast(size); + + aFrame.mInfo.mRxInfo.mAckedWithFramePending = ((flags & SPINEL_MD_FLAG_ACKED_FP) != 0); } else if (receiveError < OT_NUM_ERRORS) {