diff --git a/src/wifi/model/mac-rx-middle.cc b/src/wifi/model/mac-rx-middle.cc index 8667c61eb..a4973beeb 100644 --- a/src/wifi/model/mac-rx-middle.cc +++ b/src/wifi/model/mac-rx-middle.cc @@ -161,17 +161,28 @@ MacRxMiddle::SetForwardCallback(ForwardUpCallback callback) } OriginatorRxStatus& -MacRxMiddle::Lookup(const WifiMacHeader& hdr) +MacRxMiddle::Lookup(Ptr mpdu) { - NS_LOG_FUNCTION(hdr); + NS_LOG_FUNCTION(*mpdu); + const auto& hdr = mpdu->GetOriginal()->GetHeader(); const auto source = hdr.GetAddr2(); - if (hdr.IsQosData() && !source.IsGroup()) + const auto dest = hdr.GetAddr1(); + if (hdr.IsQosData() && !dest.IsGroup()) { - /* only for QoS data non-broadcast frames */ + /* only for QoS data unicast frames */ const auto key = std::make_pair(source, hdr.GetQosTid()); auto [it, inserted] = m_qosOriginatorStatus.try_emplace(key); return it->second; } + else if (hdr.IsQosData() && dest.IsGroup()) + { + /* for QoS data groupcast frames: use the (nonconcealed) group address as key */ + const auto groupAddress = + hdr.IsQosAmsdu() ? mpdu->begin()->second.GetDestinationAddr() : hdr.GetAddr1(); + const auto key = std::make_pair(groupAddress, hdr.GetQosTid()); + auto [it, inserted] = m_qosOriginatorStatus.insert({key, {}}); + return it->second; + } /* - management frames * - QoS data broadcast frames * - non-QoS data frames @@ -256,7 +267,7 @@ MacRxMiddle::Receive(Ptr mpdu, uint8_t linkId) const auto& hdr = mpdu->GetOriginal()->GetHeader(); NS_ASSERT(hdr.IsData() || hdr.IsMgt()); - auto& originator = Lookup(hdr); + auto& originator = Lookup(mpdu); /** * The check below is really unneeded because it can fail in a lot of * normal cases. Specifically, it is possible for sequence numbers to diff --git a/src/wifi/model/mac-rx-middle.h b/src/wifi/model/mac-rx-middle.h index c308da454..764180c28 100644 --- a/src/wifi/model/mac-rx-middle.h +++ b/src/wifi/model/mac-rx-middle.h @@ -59,14 +59,15 @@ class MacRxMiddle : public SimpleRefCount friend class MacRxMiddleTest; /** * Look up for OriginatorRxStatus associated with the sender address - * (by looking at ADDR2 field in the header). + * (by looking at ADDR2 field in the header) for unicast. For groupcast, + * the (nonconcealed) group address is used instead. * The method creates a new OriginatorRxStatus if one is not already presented. * - * @param hdr the MAC header + * @param mpdu the received MPDU * * @return OriginatorRxStatus */ - OriginatorRxStatus& Lookup(const WifiMacHeader& hdr); + OriginatorRxStatus& Lookup(Ptr mpdu); /** * Check if we have already received the packet from the sender before * (by looking at the sequence control field).