wifi: Enable exchange of data frames under BA agreement

This commit is contained in:
Stefano Avallone
2022-11-09 17:54:06 +01:00
committed by Stefano Avallone
parent 4352571f8c
commit 029e84de68
6 changed files with 71 additions and 44 deletions

View File

@@ -1539,7 +1539,10 @@ ApWifiMac::Receive(Ptr<const WifiMpdu> mpdu, uint8_t linkId)
mpdu->GetHeader().GetAddr1() == GetFrameExchangeManager(*apLinkId)->GetAddress())
{
Mac48Address to = hdr->GetAddr3();
if (to == GetAddress())
// Address3 can be our MLD address (e.g., this is an MPDU containing a single MSDU
// addressed to us) or a BSSID (e.g., this is an MPDU containing an A-MSDU)
if (to == GetAddress() ||
(hdr->IsQosData() && hdr->IsQosAmsdu() && to == mpdu->GetHeader().GetAddr1()))
{
NS_LOG_DEBUG("frame for me from=" << from);
if (hdr->IsQosData())

View File

@@ -418,7 +418,7 @@ BlockAckManager::HandleInFlightMpdu(uint8_t linkId,
return it->second.second.erase(mpduIt);
}
WifiMacHeader& hdr = (*mpduIt)->GetHeader();
const WifiMacHeader& hdr = (*mpduIt)->GetHeader();
NS_ASSERT(hdr.GetAddr1() == it->first.first);
NS_ASSERT(hdr.IsQosData() && hdr.GetQosTid() == it->first.second);
@@ -468,7 +468,7 @@ BlockAckManager::NotifyGotAck(uint8_t linkId, Ptr<const WifiMpdu> mpdu)
NS_LOG_FUNCTION(this << linkId << *mpdu);
NS_ASSERT(mpdu->GetHeader().IsQosData());
Mac48Address recipient = mpdu->GetHeader().GetAddr1();
Mac48Address recipient = mpdu->GetOriginal()->GetHeader().GetAddr1();
uint8_t tid = mpdu->GetHeader().GetQosTid();
auto it = m_originatorAgreements.find({recipient, tid});
@@ -495,7 +495,7 @@ BlockAckManager::NotifyMissedAck(uint8_t linkId, Ptr<WifiMpdu> mpdu)
NS_LOG_FUNCTION(this << linkId << *mpdu);
NS_ASSERT(mpdu->GetHeader().IsQosData());
Mac48Address recipient = mpdu->GetHeader().GetAddr1();
Mac48Address recipient = mpdu->GetOriginal()->GetHeader().GetAddr1();
uint8_t tid = mpdu->GetHeader().GetQosTid();
auto it = m_originatorAgreements.find({recipient, tid});
@@ -712,7 +712,7 @@ void
BlockAckManager::NotifyGotMpdu(Ptr<const WifiMpdu> mpdu)
{
NS_LOG_FUNCTION(this << *mpdu);
auto originator = mpdu->GetHeader().GetAddr2();
auto originator = mpdu->GetOriginal()->GetHeader().GetAddr2();
NS_ASSERT(mpdu->GetHeader().IsQosData());
auto tid = mpdu->GetHeader().GetQosTid();

View File

@@ -1582,9 +1582,10 @@ HeFrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> mpdu,
mpdu->GetPacket()->PeekHeader(blockAckReq);
NS_ABORT_MSG_IF(blockAckReq.IsMultiTid(), "Multi-TID BlockAckReq not supported");
uint8_t tid = blockAckReq.GetTidInfo();
GetBaManager(tid)->NotifyGotBlockAckRequest(sender,
tid,
blockAckReq.GetStartingSequence());
GetBaManager(tid)->NotifyGotBlockAckRequest(
m_mac->GetMldAddress(sender).value_or(sender),
tid,
blockAckReq.GetStartingSequence());
// Block Acknowledgment context
acknowledgment->stationsReceivingMultiStaBa.emplace(std::make_pair(sender, tid), index);
@@ -1758,8 +1759,11 @@ HeFrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> mpdu,
mpdu->GetPacket()->PeekHeader(blockAck);
uint8_t tid = blockAck.GetTidInfo();
std::pair<uint16_t, uint16_t> ret =
GetBaManager(tid)->NotifyGotBlockAck(m_linkId, blockAck, hdr.GetAddr2(), {tid});
GetWifiRemoteStationManager()->ReportAmpduTxStatus(hdr.GetAddr2(),
GetBaManager(tid)->NotifyGotBlockAck(m_linkId,
blockAck,
m_mac->GetMldAddress(sender).value_or(sender),
{tid});
GetWifiRemoteStationManager()->ReportAmpduTxStatus(sender,
ret.first,
ret.second,
rxSignalInfo.snr,
@@ -1838,12 +1842,12 @@ HeFrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> mpdu,
tid = *tids.begin();
}
std::pair<uint16_t, uint16_t> ret =
GetBaManager(tid)->NotifyGotBlockAck(m_linkId,
blockAck,
hdr.GetAddr2(),
{tid},
index);
std::pair<uint16_t, uint16_t> ret = GetBaManager(tid)->NotifyGotBlockAck(
m_linkId,
blockAck,
m_mac->GetMldAddress(hdr.GetAddr2()).value_or(hdr.GetAddr2()),
{tid},
index);
GetWifiRemoteStationManager()->ReportAmpduTxStatus(hdr.GetAddr2(),
ret.first,
ret.second,
@@ -1923,7 +1927,7 @@ HeFrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> mpdu,
NS_ABORT_MSG_IF(blockAckReq.IsMultiTid(), "Multi-TID BlockAckReq not supported");
uint8_t tid = blockAckReq.GetTidInfo();
auto agreement = GetBaManager(tid)->GetAgreementAsRecipient(sender, tid);
auto agreement = m_mac->GetBaAgreementEstablishedAsRecipient(sender, tid);
if (!agreement)
{
@@ -1931,9 +1935,10 @@ HeFrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> mpdu,
return;
}
GetBaManager(tid)->NotifyGotBlockAckRequest(sender,
tid,
blockAckReq.GetStartingSequence());
GetBaManager(tid)->NotifyGotBlockAckRequest(
m_mac->GetMldAddress(sender).value_or(sender),
tid,
blockAckReq.GetStartingSequence());
NS_LOG_DEBUG("Schedule Block Ack in TB PPDU");
Simulator::Schedule(m_phy->GetSifs(),

View File

@@ -706,7 +706,7 @@ HtFrameExchangeManager::ReleaseSequenceNumber(Ptr<WifiMpdu> mpdu) const
NS_LOG_FUNCTION(this << *mpdu);
// the MPDU should be still in the queue, unless it expired.
const WifiMacHeader& hdr = mpdu->GetHeader();
const WifiMacHeader& hdr = mpdu->GetOriginal()->GetHeader();
if (hdr.IsQosData())
{
uint8_t tid = hdr.GetQosTid();
@@ -1193,7 +1193,12 @@ HtFrameExchangeManager::MissedBlockAck(Ptr<WifiPsdu> psdu,
{
NS_LOG_FUNCTION(this << psdu << txVector << resetCw);
Mac48Address recipient = psdu->GetAddr1();
auto recipient = psdu->GetAddr1();
auto recipientMld = recipient;
if (auto optAddr = GetWifiRemoteStationManager()->GetMldAddress(recipient))
{
recipientMld = *optAddr;
}
bool isBar;
uint8_t tid;
@@ -1220,7 +1225,7 @@ HtFrameExchangeManager::MissedBlockAck(Ptr<WifiPsdu> psdu,
if (edca->UseExplicitBarAfterMissedBlockAck() || isBar)
{
// we have to send a BlockAckReq, if needed
if (GetBaManager(tid)->NeedBarRetransmission(tid, recipient))
if (GetBaManager(tid)->NeedBarRetransmission(tid, recipientMld))
{
NS_LOG_DEBUG("Missed Block Ack, transmit a BlockAckReq");
if (isBar)
@@ -1267,7 +1272,7 @@ HtFrameExchangeManager::MissedBlockAck(Ptr<WifiPsdu> psdu,
else
{
NS_LOG_DEBUG("Missed Block Ack, retransmit data frames");
GetBaManager(tid)->NotifyMissedBlockAck(m_linkId, recipient, tid);
GetBaManager(tid)->NotifyMissedBlockAck(m_linkId, recipientMld, tid);
resetCw = false;
}
}
@@ -1283,7 +1288,12 @@ HtFrameExchangeManager::SendBlockAck(const RecipientBlockAckAgreement& agreement
WifiMacHeader hdr;
hdr.SetType(WIFI_MAC_CTL_BACKRESP);
hdr.SetAddr1(agreement.GetPeer());
auto addr1 = agreement.GetPeer();
if (auto originator = GetWifiRemoteStationManager()->GetAffiliatedStaAddress(addr1))
{
addr1 = *originator;
}
hdr.SetAddr1(addr1);
hdr.SetAddr2(m_self);
hdr.SetDsNotFrom();
hdr.SetDsNotTo();
@@ -1368,8 +1378,11 @@ HtFrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> mpdu,
mpdu->GetPacket()->PeekHeader(blockAck);
uint8_t tid = blockAck.GetTidInfo();
std::pair<uint16_t, uint16_t> ret =
GetBaManager(tid)->NotifyGotBlockAck(m_linkId, blockAck, hdr.GetAddr2(), {tid});
GetWifiRemoteStationManager()->ReportAmpduTxStatus(hdr.GetAddr2(),
GetBaManager(tid)->NotifyGotBlockAck(m_linkId,
blockAck,
m_mac->GetMldAddress(sender).value_or(sender),
{tid});
GetWifiRemoteStationManager()->ReportAmpduTxStatus(sender,
ret.first,
ret.second,
rxSnr,
@@ -1399,7 +1412,7 @@ HtFrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> mpdu,
NS_ABORT_MSG_IF(blockAckReq.IsMultiTid(), "Multi-TID BlockAckReq not supported");
uint8_t tid = blockAckReq.GetTidInfo();
auto agreement = GetBaManager(tid)->GetAgreementAsRecipient(sender, tid);
auto agreement = m_mac->GetBaAgreementEstablishedAsRecipient(sender, tid);
if (!agreement)
{
@@ -1407,9 +1420,10 @@ HtFrameExchangeManager::ReceiveMpdu(Ptr<const WifiMpdu> mpdu,
return;
}
GetBaManager(tid)->NotifyGotBlockAckRequest(sender,
tid,
blockAckReq.GetStartingSequence());
GetBaManager(tid)->NotifyGotBlockAckRequest(
m_mac->GetMldAddress(sender).value_or(sender),
tid,
blockAckReq.GetStartingSequence());
NS_LOG_DEBUG("Schedule Block Ack");
Simulator::Schedule(
@@ -1478,7 +1492,7 @@ HtFrameExchangeManager::EndReceiveAmpdu(Ptr<const WifiPsdu> psdu,
{
// Normal Ack or Implicit Block Ack Request
NS_LOG_DEBUG("Schedule Block Ack");
auto agreement = GetBaManager(tid)->GetAgreementAsRecipient(psdu->GetAddr2(), tid);
auto agreement = m_mac->GetBaAgreementEstablishedAsRecipient(psdu->GetAddr2(), tid);
NS_ASSERT(agreement);
Simulator::Schedule(

View File

@@ -281,7 +281,8 @@ QosTxop::PrepareBlockAckRequest(Mac48Address recipient, uint8_t tid) const
NS_LOG_FUNCTION(this << recipient << +tid);
NS_ASSERT(QosUtilsMapTidToAc(tid) == m_ac);
CtrlBAckRequestHeader reqHdr = m_baManager->GetBlockAckReqHeader(recipient, tid);
CtrlBAckRequestHeader reqHdr =
m_baManager->GetBlockAckReqHeader(m_mac->GetMldAddress(recipient).value_or(recipient), tid);
Ptr<Packet> bar = Create<Packet>();
bar->AddHeader(reqHdr);
@@ -507,9 +508,10 @@ QosTxop::GetNextMpdu(uint8_t linkId,
// Note that PeekNextMpdu() temporarily assigns the next available sequence number
// to the peeked frame
NS_ASSERT(!m_mac->GetBaAgreementEstablishedAsOriginator(recipient, tid) ||
IsInWindow(peekedItem->GetHeader().GetSequenceNumber(),
GetBaStartingSequence(recipient, tid),
GetBaBufferSize(recipient, tid)));
IsInWindow(
peekedItem->GetHeader().GetSequenceNumber(),
GetBaStartingSequence(peekedItem->GetOriginal()->GetHeader().GetAddr1(), tid),
GetBaBufferSize(peekedItem->GetOriginal()->GetHeader().GetAddr1(), tid)));
// try A-MSDU aggregation
if (m_mac->GetHtSupported() && !recipient.IsBroadcast() &&
@@ -674,7 +676,9 @@ QosTxop::CompleteMpduTx(Ptr<WifiMpdu> mpdu)
if (m_mac->GetBaAgreementEstablishedAsOriginator(mpdu->GetHeader().GetAddr1(),
mpdu->GetHeader().GetQosTid()))
{
m_baManager->StorePacket(mpdu);
NS_ASSERT(mpdu->IsQueued());
NS_ASSERT(m_queue->GetAc() == mpdu->GetQueueAc());
m_baManager->StorePacket(m_queue->GetOriginal(mpdu));
}
}

View File

@@ -96,15 +96,15 @@ WifiDefaultAckManager::GetMaxDistFromStartingSeq(Ptr<const WifiMpdu> mpdu,
{
NS_LOG_FUNCTION(this << *mpdu << &txParams);
const WifiMacHeader& hdr = mpdu->GetHeader();
Mac48Address receiver = hdr.GetAddr1();
auto receiver = mpdu->GetHeader().GetAddr1();
auto origReceiver = mpdu->GetOriginal()->GetHeader().GetAddr1();
uint8_t tid = hdr.GetQosTid();
uint8_t tid = mpdu->GetHeader().GetQosTid();
Ptr<QosTxop> edca = m_mac->GetQosTxop(tid);
NS_ABORT_MSG_IF(!m_mac->GetBaAgreementEstablishedAsOriginator(receiver, tid),
NS_ABORT_MSG_IF(!m_mac->GetBaAgreementEstablishedAsOriginator(origReceiver, tid),
"An established Block Ack agreement is required");
uint16_t startingSeq = edca->GetBaStartingSequence(receiver, tid);
uint16_t startingSeq = edca->GetBaStartingSequence(origReceiver, tid);
uint16_t maxDistFromStartingSeq =
(mpdu->GetHeader().GetSequenceNumber() - startingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE;
NS_ABORT_MSG_IF(maxDistFromStartingSeq >= SEQNO_SPACE_HALF_SIZE,
@@ -143,7 +143,7 @@ WifiDefaultAckManager::IsResponseNeeded(Ptr<const WifiMpdu> mpdu,
NS_LOG_FUNCTION(this << *mpdu << &txParams);
uint8_t tid = mpdu->GetHeader().GetQosTid();
Mac48Address receiver = mpdu->GetHeader().GetAddr1();
Mac48Address receiver = mpdu->GetOriginal()->GetHeader().GetAddr1();
Ptr<QosTxop> edca = m_mac->GetQosTxop(tid);
// An immediate response (Ack or Block Ack) is needed if any of the following holds:
@@ -295,8 +295,9 @@ WifiDefaultAckManager::TryAddMpdu(Ptr<const WifiMpdu> mpdu, const WifiTxParamete
// we get here if a response is needed
uint8_t tid = GetTid(mpdu->GetPacket(), hdr);
auto origReceiver = mpdu->GetOriginal()->GetHeader().GetAddr1();
if (!hdr.IsBlockAckReq() && txParams.GetSize(receiver) == 0 &&
hdr.GetSequenceNumber() == m_mac->GetQosTxop(tid)->GetBaStartingSequence(receiver, tid))
hdr.GetSequenceNumber() == m_mac->GetQosTxop(tid)->GetBaStartingSequence(origReceiver, tid))
{
NS_LOG_DEBUG("Sending a single MPDU, no previous frame to ack: request Normal Ack");
WifiNormalAck* acknowledgment = new WifiNormalAck;