diff --git a/src/wifi/model/ht/ht-frame-exchange-manager.cc b/src/wifi/model/ht/ht-frame-exchange-manager.cc index eaddac602..be5840fae 100644 --- a/src/wifi/model/ht/ht-frame-exchange-manager.cc +++ b/src/wifi/model/ht/ht-frame-exchange-manager.cc @@ -242,6 +242,11 @@ HtFrameExchangeManager::SendAddBaResponse(const MgtAddBaRequestHeader* reqHdr, packet->AddHeader(respHdr); packet->AddHeader(actionHdr); + // Get the MLD address of the originator, if an ML setup was performed + if (auto originatorMld = GetWifiRemoteStationManager()->GetMldAddress(originator)) + { + originator = *originatorMld; + } bool htSupported = GetWifiRemoteStationManager()->GetHtSupported() && GetWifiRemoteStationManager()->GetHtSupported(originator); GetBaManager(tid)->CreateRecipientAgreement(respHdr, @@ -307,7 +312,8 @@ HtFrameExchangeManager::SendDelbaFrame(Mac48Address addr, uint8_t tid, bool byOr NS_LOG_FUNCTION(this << addr << +tid << byOriginator); WifiMacHeader hdr; hdr.SetType(WIFI_MAC_MGT_ACTION); - hdr.SetAddr1(addr); + // use the remote link address if addr is an MLD address + hdr.SetAddr1(GetWifiRemoteStationManager()->GetAffiliatedStaAddress(addr).value_or(addr)); hdr.SetAddr2(m_self); hdr.SetAddr3(m_bssid); hdr.SetDsNotTo(); @@ -561,6 +567,8 @@ HtFrameExchangeManager::NotifyReceivedNormalAck(Ptr mpdu) } else if (mpdu->GetHeader().IsAction()) { + auto addr1 = mpdu->GetHeader().GetAddr1(); + auto address = GetWifiRemoteStationManager()->GetMldAddress(addr1).value_or(addr1); WifiActionHeader actionHdr; Ptr p = mpdu->GetPacket()->Copy(); p->RemoveHeader(actionHdr); @@ -573,12 +581,11 @@ HtFrameExchangeManager::NotifyReceivedNormalAck(Ptr mpdu) auto tid = delBa.GetTid(); if (delBa.IsByOriginator()) { - GetBaManager(tid)->DestroyOriginatorAgreement(mpdu->GetHeader().GetAddr1(), - tid); + GetBaManager(tid)->DestroyOriginatorAgreement(address, tid); } else { - GetBaManager(tid)->DestroyRecipientAgreement(mpdu->GetHeader().GetAddr1(), tid); + GetBaManager(tid)->DestroyRecipientAgreement(address, tid); } } else if (actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_ADDBA_REQUEST) @@ -590,7 +597,7 @@ HtFrameExchangeManager::NotifyReceivedNormalAck(Ptr mpdu) Simulator::Schedule(edca->GetAddBaResponseTimeout(), &QosTxop::AddBaResponseTimeout, edca, - mpdu->GetHeader().GetAddr1(), + address, addBa.GetTid()); } else if (actionHdr.GetAction().blockAck == WifiActionHeader::BLOCK_ACK_ADDBA_RESPONSE) @@ -598,12 +605,11 @@ HtFrameExchangeManager::NotifyReceivedNormalAck(Ptr mpdu) // A recipient Block Ack agreement must exist MgtAddBaResponseHeader addBa; p->PeekHeader(addBa); - auto originator = mpdu->GetHeader().GetAddr1(); auto tid = addBa.GetTid(); - NS_ASSERT_MSG(GetBaManager(tid)->GetAgreementAsRecipient(originator, tid), - "Recipient BA agreement {" << originator << ", " << +tid + NS_ASSERT_MSG(GetBaManager(tid)->GetAgreementAsRecipient(address, tid), + "Recipient BA agreement {" << address << ", " << +tid << "} not found"); - m_pendingAddBaResp.erase({originator, tid}); + m_pendingAddBaResp.erase({address, tid}); } } } diff --git a/src/wifi/model/wifi-mac.cc b/src/wifi/model/wifi-mac.cc index 4882af2e7..da3447108 100644 --- a/src/wifi/model/wifi-mac.cc +++ b/src/wifi/model/wifi-mac.cc @@ -1117,11 +1117,11 @@ WifiMac::Receive(Ptr mpdu, uint8_t linkId) { NS_LOG_FUNCTION(this << *mpdu << linkId); - const WifiMacHeader* hdr = &mpdu->GetHeader(); - Ptr packet = mpdu->GetPacket()->Copy(); + const WifiMacHeader* hdr = &mpdu->GetOriginal()->GetHeader(); Mac48Address to = hdr->GetAddr1(); Mac48Address from = hdr->GetAddr2(); - auto& link = GetLink(SINGLE_LINK_OP_ID); + auto myAddr = hdr->IsData() ? Mac48Address::ConvertFrom(GetDevice()->GetAddress()) + : GetFrameExchangeManager(linkId)->GetAddress(); // We don't know how to deal with any frame that is not addressed to // us (and odds are there is nothing sensible we could do anyway), @@ -1129,7 +1129,7 @@ WifiMac::Receive(Ptr mpdu, uint8_t linkId) // // The derived class may also do some such filtering, but it doesn't // hurt to have it here too as a backstop. - if (to != GetAddress()) + if (to != myAddr) { return; } @@ -1140,7 +1140,9 @@ WifiMac::Receive(Ptr mpdu, uint8_t linkId) // frames to be flying about if we are a QoS STA. NS_ASSERT(GetQosSupported()); + auto& link = GetLink(linkId); WifiActionHeader actionHdr; + Ptr packet = mpdu->GetPacket()->Copy(); packet->RemoveHeader(actionHdr); switch (actionHdr.GetCategory()) @@ -1175,7 +1177,9 @@ WifiMac::Receive(Ptr mpdu, uint8_t linkId) // seems a waste given the level of the current model) // and act by locally establishing the agreement on // the appropriate queue. - GetQosTxop(respHdr.GetTid())->GotAddBaResponse(respHdr, from); + auto recipientMld = link.stationManager->GetMldAddress(from); + auto recipient = (recipientMld ? *recipientMld : from); + GetQosTxop(respHdr.GetTid())->GotAddBaResponse(respHdr, recipient); auto htFem = DynamicCast(link.feManager); if (htFem) { @@ -1190,6 +1194,8 @@ WifiMac::Receive(Ptr mpdu, uint8_t linkId) case WifiActionHeader::BLOCK_ACK_DELBA: { MgtDelBaHeader delBaHdr; packet->RemoveHeader(delBaHdr); + auto recipientMld = link.stationManager->GetMldAddress(from); + auto recipient = (recipientMld ? *recipientMld : from); if (delBaHdr.IsByOriginator()) { @@ -1199,14 +1205,14 @@ WifiMac::Receive(Ptr mpdu, uint8_t linkId) // destroy it. GetQosTxop(delBaHdr.GetTid()) ->GetBaManager() - ->DestroyRecipientAgreement(from, delBaHdr.GetTid()); + ->DestroyRecipientAgreement(recipient, delBaHdr.GetTid()); } else { // We must have been the originator. We need to // tell the correct queue that the agreement has // been torn down - GetQosTxop(delBaHdr.GetTid())->GotDelBaFrame(&delBaHdr, from); + GetQosTxop(delBaHdr.GetTid())->GotDelBaFrame(&delBaHdr, recipient); } // This frame is now completely dealt with, so we're done. return;