diff --git a/src/core/mac/link_raw.cpp b/src/core/mac/link_raw.cpp index ca87f4147..b9c4f6ee4 100644 --- a/src/core/mac/link_raw.cpp +++ b/src/core/mac/link_raw.cpp @@ -273,13 +273,8 @@ exit: #if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO) -void LinkRaw::RecordFrameTransmitStatus(const TxFrame &aFrame, - RxFrame *aAckFrame, - Error aError, - uint8_t aRetryCount, - bool aWillRetx) +void LinkRaw::RecordFrameTransmitStatus(const TxFrame &aFrame, Error aError, uint8_t aRetryCount, bool aWillRetx) { - OT_UNUSED_VARIABLE(aAckFrame); OT_UNUSED_VARIABLE(aWillRetx); if (aError != kErrorNone) diff --git a/src/core/mac/link_raw.hpp b/src/core/mac/link_raw.hpp index 07236f788..4fa474732 100644 --- a/src/core/mac/link_raw.hpp +++ b/src/core/mac/link_raw.hpp @@ -289,7 +289,6 @@ public: * of a frame transmission request, this method is invoked on all frame transmission attempts. * * @param[in] aFrame The transmitted frame. - * @param[in] aAckFrame A pointer to the ACK frame, or `nullptr` if no ACK was received. * @param[in] aError kErrorNone when the frame was transmitted successfully, * kErrorNoAck when the frame was transmitted but no ACK was received, * kErrorChannelAccessFailure tx failed due to activity on the channel, @@ -299,13 +298,9 @@ public: * when there was an error in transmission (i.e., `aError` is not NONE). * */ - void RecordFrameTransmitStatus(const TxFrame &aFrame, - RxFrame *aAckFrame, - Error aError, - uint8_t aRetryCount, - bool aWillRetx); + void RecordFrameTransmitStatus(const TxFrame &aFrame, Error aError, uint8_t aRetryCount, bool aWillRetx); #else - void RecordFrameTransmitStatus(const TxFrame &, RxFrame *, Error, uint8_t, bool) {} + void RecordFrameTransmitStatus(const TxFrame &, Error, uint8_t, bool) {} #endif private: diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index e2834b24f..fcf3ea37f 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -1142,11 +1142,7 @@ void Mac::RecordCcaStatus(bool aCcaSuccess, uint8_t aChannel) } } -void Mac::RecordFrameTransmitStatus(const TxFrame &aFrame, - RxFrame *aAckFrame, - Error aError, - uint8_t aRetryCount, - bool aWillRetx) +void Mac::RecordFrameTransmitStatus(const TxFrame &aFrame, Error aError, uint8_t aRetryCount, bool aWillRetx) { bool ackRequested = aFrame.GetAckRequest(); Address dstAddr; @@ -1202,32 +1198,6 @@ void Mac::RecordFrameTransmitStatus(const TxFrame &aFrame, } } - // Update neighbor's RSSI link info from the received Ack. - - if ((aError == kErrorNone) && ackRequested && (aAckFrame != nullptr) && (neighbor != nullptr)) - { -#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE - SuccessOrExit(mFilter.ApplyToRxFrame(*aAckFrame, neighbor->GetExtAddress(), neighbor)); -#endif - - neighbor->GetLinkInfo().AddRss(aAckFrame->GetRssi()); -#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE - neighbor->AggregateLinkMetrics(/* aSeriesId */ 0, aAckFrame->GetType(), aAckFrame->GetLqi(), - aAckFrame->GetRssi()); -#endif -#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE - ProcessEnhAckProbing(*aAckFrame, *neighbor); -#endif -#if OPENTHREAD_FTD - if (aAckFrame->GetVersion() == Frame::kVersion2015) - { -#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE - ProcessCsl(*aAckFrame, dstAddr); -#endif - } -#endif // OPENTHREAD_FTD - } - // Update MAC counters. mCounters.mTxTotal++; @@ -1271,6 +1241,8 @@ exit: void Mac::HandleTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError) { + bool ackRequested = aFrame.GetAckRequest(); + #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE if (!aFrame.IsEmpty() #if OPENTHREAD_CONFIG_MULTI_RADIO @@ -1280,10 +1252,9 @@ void Mac::HandleTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError) { Address dstAddr; - // Determine whether to re-transmit a broadcast frame. - IgnoreError(aFrame.GetDstAddr(dstAddr)); + // Determine whether to re-transmit a broadcast frame. if (dstAddr.IsBroadcast()) { mBroadcastTransmitCount++; @@ -1305,16 +1276,43 @@ void Mac::HandleTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError) mBroadcastTransmitCount = 0; } -#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 - // Verify Enh-ACK integrity by checking its MIC - if ((aError == kErrorNone) && (aAckFrame != nullptr) && - (ProcessEnhAckSecurity(aFrame, *aAckFrame) != kErrorNone)) + if (ackRequested && (aAckFrame != nullptr)) { - aError = kErrorNoAck; - } + Neighbor *neighbor = Get().FindNeighbor(dstAddr); + +#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE + if ((aError == kErrorNone) && (neighbor != nullptr) && + (mFilter.ApplyToRxFrame(*aAckFrame, neighbor->GetExtAddress(), neighbor) != kErrorNone)) + { + aError = kErrorNoAck; + } #endif + +#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2 + // Verify Enh-ACK integrity by checking its MIC + if ((aError == kErrorNone) && (ProcessEnhAckSecurity(aFrame, *aAckFrame) != kErrorNone)) + { + aError = kErrorNoAck; + } +#endif + + if ((aError == kErrorNone) && (neighbor != nullptr)) + { + neighbor->GetLinkInfo().AddRss(aAckFrame->GetRssi()); +#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE + neighbor->AggregateLinkMetrics(/* aSeriesId */ 0, aAckFrame->GetType(), aAckFrame->GetLqi(), + aAckFrame->GetRssi()); +#endif +#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE + ProcessEnhAckProbing(*aAckFrame, *neighbor); +#endif +#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE + ProcessCsl(*aAckFrame, dstAddr); +#endif + } + } } -#endif // #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE +#endif // OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE #if OPENTHREAD_CONFIG_MULTI_RADIO if (!aFrame.IsEmpty()) @@ -1380,7 +1378,7 @@ void Mac::HandleTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError) break; case kOperationTransmitPoll: - OT_ASSERT(aFrame.IsEmpty() || aFrame.GetAckRequest()); + OT_ASSERT(aFrame.IsEmpty() || ackRequested); if ((aError == kErrorNone) && (aAckFrame != nullptr)) { @@ -1662,7 +1660,7 @@ Error Mac::ProcessEnhAckSecurity(TxFrame &aTxFrame, RxFrame &aAckFrame) VerifyOrExit(securityLevel == Frame::kSecurityEncMic32); IgnoreError(aAckFrame.GetKeyIdMode(keyIdMode)); - VerifyOrExit(keyIdMode == Frame::kKeyIdMode1, error = kErrorNone); + VerifyOrExit(keyIdMode == Frame::kKeyIdMode1); IgnoreError(aTxFrame.GetKeyId(txKeyId)); IgnoreError(aAckFrame.GetKeyId(ackKeyId)); @@ -1858,10 +1856,7 @@ void Mac::HandleReceivedFrame(RxFrame *aFrame, Error aError) } #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE - if (aFrame->GetVersion() == Frame::kVersion2015) - { - ProcessCsl(*aFrame, srcaddr); - } + ProcessCsl(*aFrame, srcaddr); #endif Get().ProcessRxFrame(*aFrame); @@ -2294,16 +2289,20 @@ bool Mac::IsCslSupported(void) const #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE void Mac::ProcessCsl(const RxFrame &aFrame, const Address &aSrcAddr) { - const uint8_t *cur = aFrame.GetHeaderIe(CslIe::kHeaderIeId); - Child *child = Get().FindChild(aSrcAddr, Child::kInStateAnyExceptInvalid); + const uint8_t *cur; + Child *child; const CslIe *csl; - VerifyOrExit(cur != nullptr && child != nullptr && aFrame.GetSecurityEnabled()); + VerifyOrExit(aFrame.IsVersion2015() && aFrame.GetSecurityEnabled()); + + cur = aFrame.GetHeaderIe(CslIe::kHeaderIeId); + VerifyOrExit(cur != nullptr); + + child = Get().FindChild(aSrcAddr, Child::kInStateAnyExceptInvalid); + VerifyOrExit(child != nullptr); csl = reinterpret_cast(cur + sizeof(HeaderIe)); - child->SetCslPeriod(csl->GetPeriod()); - // Use ceiling to ensure the the time diff will be within kUsPerTenSymbols child->SetCslPhase(csl->GetPhase()); child->SetCslSynchronized(true); child->SetCslLastHeard(TimerMilli::GetNow()); diff --git a/src/core/mac/mac.hpp b/src/core/mac/mac.hpp index d433b25a2..b0024f90a 100644 --- a/src/core/mac/mac.hpp +++ b/src/core/mac/mac.hpp @@ -402,7 +402,6 @@ public: * of a frame transmission request, this method is invoked on all frame transmission attempts. * * @param[in] aFrame The transmitted frame. - * @param[in] aAckFrame A pointer to the ACK frame, or `nullptr` if no ACK was received. * @param[in] aError kErrorNone when the frame was transmitted successfully, * kErrorNoAck when the frame was transmitted but no ACK was received, * kErrorChannelAccessFailure tx failed due to activity on the channel, @@ -412,11 +411,7 @@ public: * when there was an error in transmission (i.e., `aError` is not NONE). * */ - void RecordFrameTransmitStatus(const TxFrame &aFrame, - RxFrame *aAckFrame, - Error aError, - uint8_t aRetryCount, - bool aWillRetx); + void RecordFrameTransmitStatus(const TxFrame &aFrame, Error aError, uint8_t aRetryCount, bool aWillRetx); /** * Is called to handle transmit events. diff --git a/src/core/mac/sub_mac.cpp b/src/core/mac/sub_mac.cpp index 9b6879ff0..3a5d83816 100644 --- a/src/core/mac/sub_mac.cpp +++ b/src/core/mac/sub_mac.cpp @@ -642,7 +642,7 @@ void SubMac::HandleTransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aErro shouldRetx = ((aError != kErrorNone) && ShouldHandleRetries() && (mTransmitRetries < aFrame.GetMaxFrameRetries())); - mCallbacks.RecordFrameTransmitStatus(aFrame, aAckFrame, aError, mTransmitRetries, shouldRetx); + mCallbacks.RecordFrameTransmitStatus(aFrame, aError, mTransmitRetries, shouldRetx); if (shouldRetx) { diff --git a/src/core/mac/sub_mac.hpp b/src/core/mac/sub_mac.hpp index 5c244fd03..bbdb88485 100644 --- a/src/core/mac/sub_mac.hpp +++ b/src/core/mac/sub_mac.hpp @@ -155,7 +155,6 @@ public: * of a frame transmission, this method is invoked on all frame transmission attempts. * * @param[in] aFrame The transmitted frame. - * @param[in] aAckFrame A pointer to the ACK frame, or `nullptr` if no ACK was received. * @param[in] aError kErrorNone when the frame was transmitted successfully, * kErrorNoAck when the frame was transmitted but no ACK was received, * kErrorChannelAccessFailure tx failed due to activity on the channel, @@ -165,11 +164,7 @@ public: * when there was an error in current transmission attempt. * */ - void RecordFrameTransmitStatus(const TxFrame &aFrame, - RxFrame *aAckFrame, - Error aError, - uint8_t aRetryCount, - bool aWillRetx); + void RecordFrameTransmitStatus(const TxFrame &aFrame, Error aError, uint8_t aRetryCount, bool aWillRetx); /** * The method notifies user of `SubMac` that the transmit operation has completed, providing, if applicable, diff --git a/src/core/mac/sub_mac_callbacks.cpp b/src/core/mac/sub_mac_callbacks.cpp index 4a3053dd2..ba0269e0f 100644 --- a/src/core/mac/sub_mac_callbacks.cpp +++ b/src/core/mac/sub_mac_callbacks.cpp @@ -71,12 +71,11 @@ void SubMac::Callbacks::RecordCcaStatus(bool aCcaSuccess, uint8_t aChannel) } void SubMac::Callbacks::RecordFrameTransmitStatus(const TxFrame &aFrame, - RxFrame *aAckFrame, Error aError, uint8_t aRetryCount, bool aWillRetx) { - Get().RecordFrameTransmitStatus(aFrame, aAckFrame, aError, aRetryCount, aWillRetx); + Get().RecordFrameTransmitStatus(aFrame, aError, aRetryCount, aWillRetx); } void SubMac::Callbacks::TransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError) @@ -119,12 +118,11 @@ void SubMac::Callbacks::ReceiveDone(RxFrame *aFrame, Error aError) { Get().RecordFrameTransmitStatus(aFrame, aAckFrame, aError, aRetryCount, aWillRetx); + Get().RecordFrameTransmitStatus(aFrame, aError, aRetryCount, aWillRetx); } void SubMac::Callbacks::TransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError) diff --git a/src/core/radio/trel_link.cpp b/src/core/radio/trel_link.cpp index 8eb2b9e88..203e0dfeb 100644 --- a/src/core/radio/trel_link.cpp +++ b/src/core/radio/trel_link.cpp @@ -251,7 +251,7 @@ void Link::InvokeSendDone(Error aError, Mac::RxFrame *aAckFrame) { SetState(kStateReceive); - Get().RecordFrameTransmitStatus(mTxFrame, aAckFrame, aError, /* aRetryCount */ 0, /* aWillRetx */ false); + Get().RecordFrameTransmitStatus(mTxFrame, aError, /* aRetryCount */ 0, /* aWillRetx */ false); Get().HandleTransmitDone(mTxFrame, aAckFrame, aError); } diff --git a/tests/scripts/thread-cert/v1_2_test_enhanced_keep_alive.py b/tests/scripts/thread-cert/v1_2_test_enhanced_keep_alive.py index 9bd10c361..76eea534b 100755 --- a/tests/scripts/thread-cert/v1_2_test_enhanced_keep_alive.py +++ b/tests/scripts/thread-cert/v1_2_test_enhanced_keep_alive.py @@ -134,19 +134,19 @@ class SED_EnhancedKeepAlive(thread_cert.TestCase): self.assertTrue(self.nodes[SED_1].ping(leader_aloc, timeout=USER_POLL_PERIOD * 2)) # 6 - Timeout Child - self.nodes[LEADER].enable_allowlist() - self.nodes[SED_1].enable_allowlist() - self.nodes[SED_1].set_pollperiod(CHILD_TIMEOUT * 1000 * 2) + self.nodes[SED_1].set_pollperiod(CHILD_TIMEOUT * 1000 * 4) self.simulator.go(CHILD_TIMEOUT + 1) self.assertEqual(self.nodes[SED_1].get_state(), 'child') - self.nodes[SED_1].set_pollperiod(USER_POLL_PERIOD * 1000) - self.nodes[LEADER].disable_allowlist() - self.nodes[SED_1].disable_allowlist() self.assertFalse(self.nodes[SED_1].ping(leader_aloc, timeout=USER_POLL_PERIOD * 2)) self.flush_all() + self.nodes[SED_1].stop() + self.nodes[SED_1].set_pollperiod(USER_POLL_PERIOD * 1000) + self.nodes[SED_1].start() + # 7 - Wait SED_1 to re-attach self.simulator.go(240) + self.assertEqual(self.nodes[SED_1].get_state(), 'child') leader_messages = self.simulator.get_messages_sent_by(LEADER) msg = leader_messages.next_mle_message(mle.CommandType.CHILD_ID_RESPONSE) msg.assertSentToNode(self.nodes[SED_1]) @@ -160,20 +160,12 @@ class SED_EnhancedKeepAlive(thread_cert.TestCase): self.flush_all() # 8 - Verify enhanced keep-alive works - self.nodes[LEADER].enable_allowlist() - self.nodes[SED_1].enable_allowlist() - self.nodes[SED_1].set_pollperiod(CHILD_TIMEOUT * 1000 * 2) + self.nodes[SED_1].set_pollperiod(CHILD_TIMEOUT * 1000 * 4) self.simulator.go(CHILD_TIMEOUT // 2) self.assertEqual(self.nodes[SED_1].get_state(), 'child') - self.nodes[LEADER].disable_allowlist() - self.nodes[SED_1].disable_allowlist() non_exist_addr = leader_aloc.replace('fc00', 'fc12') self.assertFalse(self.nodes[SED_1].ping(non_exist_addr)) - self.nodes[LEADER].enable_allowlist() - self.nodes[SED_1].enable_allowlist() self.simulator.go(CHILD_TIMEOUT // 2) - self.nodes[LEADER].disable_allowlist() - self.nodes[SED_1].disable_allowlist() self.nodes[SED_1].set_pollperiod(USER_POLL_PERIOD * 1000) self.assertTrue(self.nodes[SED_1].ping(leader_aloc, timeout=USER_POLL_PERIOD * 2))