mirror of
https://github.com/espressif/openthread.git
synced 2026-08-24 19:29:52 +00:00
[mac] move ack processing to HandleTransmitDone() (#9245)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
+50
-51
@@ -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<NeighborTable>().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<DataPollSender>().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<ChildTable>().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<ChildTable>().FindChild(aSrcAddr, Child::kInStateAnyExceptInvalid);
|
||||
VerifyOrExit(child != nullptr);
|
||||
|
||||
csl = reinterpret_cast<const CslIe *>(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());
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<Mac>().RecordFrameTransmitStatus(aFrame, aAckFrame, aError, aRetryCount, aWillRetx);
|
||||
Get<Mac>().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<LinkRaw
|
||||
void SubMac::Callbacks::RecordCcaStatus(bool, uint8_t) {}
|
||||
|
||||
void SubMac::Callbacks::RecordFrameTransmitStatus(const TxFrame &aFrame,
|
||||
RxFrame *aAckFrame,
|
||||
Error aError,
|
||||
uint8_t aRetryCount,
|
||||
bool aWillRetx)
|
||||
{
|
||||
Get<LinkRaw>().RecordFrameTransmitStatus(aFrame, aAckFrame, aError, aRetryCount, aWillRetx);
|
||||
Get<LinkRaw>().RecordFrameTransmitStatus(aFrame, aError, aRetryCount, aWillRetx);
|
||||
}
|
||||
|
||||
void SubMac::Callbacks::TransmitDone(TxFrame &aFrame, RxFrame *aAckFrame, Error aError)
|
||||
|
||||
@@ -251,7 +251,7 @@ void Link::InvokeSendDone(Error aError, Mac::RxFrame *aAckFrame)
|
||||
{
|
||||
SetState(kStateReceive);
|
||||
|
||||
Get<Mac::Mac>().RecordFrameTransmitStatus(mTxFrame, aAckFrame, aError, /* aRetryCount */ 0, /* aWillRetx */ false);
|
||||
Get<Mac::Mac>().RecordFrameTransmitStatus(mTxFrame, aError, /* aRetryCount */ 0, /* aWillRetx */ false);
|
||||
Get<Mac::Mac>().HandleTransmitDone(mTxFrame, aAckFrame, aError);
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user