[mac] move ack processing to HandleTransmitDone() (#9245)

This commit is contained in:
Jonathan Hui
2023-06-30 15:14:00 -07:00
committed by GitHub
parent ef8deb506f
commit bad7994c28
9 changed files with 66 additions and 97 deletions
+1 -6
View File
@@ -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)
+2 -7
View File
@@ -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
View File
@@ -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());
+1 -6
View File
@@ -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.
+1 -1
View File
@@ -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)
{
+1 -6
View File
@@ -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,
+2 -4
View File
@@ -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)
+1 -1
View File
@@ -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))