diff --git a/src/wifi/model/wifi-mpdu.cc b/src/wifi/model/wifi-mpdu.cc index 143649e3a..5a5892490 100644 --- a/src/wifi/model/wifi-mpdu.cc +++ b/src/wifi/model/wifi-mpdu.cc @@ -29,6 +29,7 @@ WifiMpdu::WifiMpdu(Ptr p, const WifiMacHeader& header, Time stamp) auto& original = std::get(m_instanceInfo); original.m_packet = p; original.m_timestamp = stamp; + original.m_retryCount = 0; if (header.IsQosData() && header.IsQosAmsdu()) { @@ -113,6 +114,41 @@ WifiMpdu::GetTimestamp() const return std::get(origInstanceInfo).m_timestamp; } +uint32_t +WifiMpdu::GetRetryCount() const +{ + if (auto original = std::get_if(&m_instanceInfo)) + { + return original->m_retryCount; + } + const auto& origInstanceInfo = std::get>(m_instanceInfo)->m_instanceInfo; + return std::get(origInstanceInfo).m_retryCount; +} + +void +WifiMpdu::IncrementRetryCount() +{ + NS_LOG_FUNCTION(this); + + if (m_header.IsBlockAckReq() || m_header.IsTrigger()) + { + // this function may be called for these frames, but a retry count must not be maintained + // for them + return; + } + + NS_ABORT_MSG_UNLESS(m_header.IsData() || m_header.IsMgt(), + "Frame retry count is not maintained for frames of type " + << m_header.GetTypeString()); + if (auto original = std::get_if(&m_instanceInfo)) + { + ++original->m_retryCount; + return; + } + auto& origInstanceInfo = std::get>(m_instanceInfo)->m_instanceInfo; + ++std::get(origInstanceInfo).m_retryCount; +} + const WifiMacHeader& WifiMpdu::GetHeader() const { @@ -181,6 +217,7 @@ WifiMpdu::Aggregate(Ptr msdu) // An MSDU is going to be aggregated to this MPDU, hence this has to be an A-MSDU now Ptr firstMsdu = Create(*this); original.m_packet = Create(); + original.m_retryCount = 0; DoAggregate(firstMsdu); m_header.SetQosAmsdu(); @@ -370,7 +407,8 @@ WifiMpdu::end() const void WifiMpdu::Print(std::ostream& os) const { - os << m_header << ", payloadSize=" << GetPacketSize() << ", queued=" << IsQueued(); + os << m_header << ", payloadSize=" << GetPacketSize() << ", retryCount=" << GetRetryCount() + << ", queued=" << IsQueued(); if (IsQueued()) { os << ", residualLifetime=" << (GetExpiryTime() - Simulator::Now()).As(Time::US) diff --git a/src/wifi/model/wifi-mpdu.h b/src/wifi/model/wifi-mpdu.h index bab5b74ce..1be38b596 100644 --- a/src/wifi/model/wifi-mpdu.h +++ b/src/wifi/model/wifi-mpdu.h @@ -184,6 +184,16 @@ class WifiMpdu : public SimpleRefCount */ Time GetExpiryTime() const; + /** + * @return the frame retry count + */ + uint32_t GetRetryCount() const; + + /** + * Increment the frame retry count. + */ + void IncrementRetryCount(); + /** * @brief Get the MAC protocol data unit (MPDU) corresponding to this item * (i.e. a copy of the packet stored in this item wrapped with MAC @@ -279,6 +289,7 @@ class WifiMpdu : public SimpleRefCount DeaggregatedMsdus m_msduList; //!< list of aggregated MSDUs included in this MPDU std::optional m_queueIt; //!< Queue iterator pointing to this MPDU, if queued bool m_seqNoAssigned; //!< whether a sequence number has been assigned + uint32_t m_retryCount; //!< the frame retry count maintained for each MSDU, A-MSDU or MMPDU }; /** diff --git a/src/wifi/model/wifi-psdu.cc b/src/wifi/model/wifi-psdu.cc index 91a4bc881..9f2bd20f6 100644 --- a/src/wifi/model/wifi-psdu.cc +++ b/src/wifi/model/wifi-psdu.cc @@ -163,6 +163,16 @@ WifiPsdu::SetDuration(Time duration) } } +void +WifiPsdu::IncrementRetryCount() +{ + NS_LOG_FUNCTION(this); + for (auto& mpdu : m_mpduList) + { + mpdu->IncrementRetryCount(); + } +} + std::set WifiPsdu::GetTids() const { diff --git a/src/wifi/model/wifi-psdu.h b/src/wifi/model/wifi-psdu.h index 9115ea455..c128437b1 100644 --- a/src/wifi/model/wifi-psdu.h +++ b/src/wifi/model/wifi-psdu.h @@ -150,6 +150,11 @@ class WifiPsdu : public SimpleRefCount */ void SetDuration(Time duration); + /** + * Increment the frame retry count for all the MPDUs. + */ + void IncrementRetryCount(); + /** * Get the set of TIDs of the QoS Data frames included in the PSDU. Note that * only single-TID A-MPDUs are currently supported, hence the returned set