22 #include "ns3/abort.h"
25 #include "ns3/recipient-block-ack-agreement.h"
26 #include "ns3/ap-wifi-mac.h"
27 #include "ns3/sta-wifi-mac.h"
29 #include "ns3/snr-tag.h"
34 #undef NS_LOG_APPEND_CONTEXT
35 #define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_self << "] "
46 static TypeId tid =
TypeId (
"ns3::HeFrameExchangeManager")
48 .AddConstructor<HeFrameExchangeManager> ()
49 .SetGroupName (
"Wifi")
55 : m_triggerFrameInAmpdu (false)
69 if (
m_mac->GetHeConfiguration ()->GetMpduBufferSize () > 64)
102 "A Multi-User Scheduler can only be aggregated to an AP");
104 "A Multi-User Scheduler can only be aggregated to an HE AP");
126 || (mpdu->GetHeader ().IsQosData ()
127 && !mpdu->GetHeader ().GetAddr1 ().IsGroup ()
130 txFormat =
m_muScheduler->NotifyAccessGranted (edca, availableTime, initialFrame);
142 NS_LOG_DEBUG (
"The Multi-user Scheduler returned DL_MU_TX with empty psduMap, do not transmit");
155 NS_LOG_DEBUG (
"The Multi-user Scheduler returned UL_MU_TX with empty Trigger Frame, do not transmit");
179 NS_LOG_DEBUG (
"Block Ack Manager returned no frame to send");
183 if (peekedItem->GetHeader ().IsBlockAckReq ())
189 NS_ASSERT (peekedItem->GetHeader ().IsTrigger ());
204 #ifdef NS3_BUILD_PROFILE_DEBUG
209 for (
const auto& psdu : psduMap)
211 for (
const auto& mpdu : *
PeekPointer (psdu.second))
213 NS_ASSERT (mpdu->GetHeader ().IsCtl () || !mpdu->GetHeader ().HasData () || mpdu->IsQueued ());
247 auto it = std::find_if (psduMap.begin (), psduMap.end (),
249 { return psdu.second->GetAddr1 () == to; });
250 if (it != psduMap.end ())
287 std::set<uint8_t> tids = psdu.second->
GetTids ();
288 NS_ABORT_MSG_IF (tids.size () > 1,
"Acknowledgment method incompatible with a Multi-TID A-MPDU");
289 uint8_t tid = *tids.begin ();
303 mpdu = *psdu->
begin ();
326 std::map<uint16_t, CtrlBAckRequestHeader> recipients;
334 uint16_t staId =
m_apMac->GetAssociationId (staIt->first);
336 txVector.
SetHeMuUserInfo (staId, staIt->second.blockAckTxVector.GetHeMuUserInfo (staId));
337 recipients.emplace (staId, staIt->second.barHeader);
396 { return psdu.second->GetAddr1 () == station.first; });
400 std::vector<Ptr<WifiMacQueueItem>> mpduList (psduMapIt->second->begin (), psduMapIt->second->end ());
401 NS_ASSERT (mpduList.size () == psduMapIt->second->GetNMpdus ());
404 station.second.blockAckTxVector.SetLength (acknowledgment->
ulLength);
405 mpduList.push_back (
PrepareMuBar (station.second.blockAckTxVector,
406 {{psduMapIt->first, station.second.barHeader}}));
407 psduMapIt->second = Create<WifiPsdu> (std::move (mpduList));
411 responseTxVector = &acknowledgment->stationsReplyingWithBlockAck.begin ()->second.blockAckTxVector;
420 && (mpdu = *m_psduMap.begin ()->second->begin ())->GetHeader ().IsTrigger ());
425 m_staExpectTbPpduFrom.clear ();
429 m_staExpectTbPpduFrom.insert (station.first.first);
441 + m_muScheduler->GetUlMuInfo ().tbPpduDuration;
450 && !m_txParams.m_txVector.IsUlMu ()
451 && m_psduMap.size () == 1 && m_psduMap.begin ()->first ==
SU_STA_ID
452 && (mpdu = *m_psduMap.begin ()->second->begin ())->GetHeader ().IsTrigger ())
454 CtrlTriggerHeader trigger;
455 mpdu->GetPacket ()->PeekHeader (trigger);
460 m_staExpectTbPpduFrom.clear ();
462 for (
const auto& userInfo : trigger)
464 auto staIt = m_apMac->GetStaList ().find (userInfo.GetAid12 ());
465 NS_ASSERT (staIt != m_apMac->GetStaList ().end ());
466 m_staExpectTbPpduFrom.insert (staIt->second);
471 WifiNoAck* acknowledgment =
static_cast<WifiNoAck*
> (m_txParams.m_acknowledgment.get ());
472 txVector = trigger.GetHeTbTxVector (trigger.begin ()->GetAid12 ());
476 m_phy->GetPhyBand ());
479 responseTxVector = &txVector;
484 else if (m_txParams.m_txVector.IsUlMu ()
489 NS_ASSERT (m_staMac != 0 && m_staMac->IsAssociated ());
490 txVector = m_mac->GetWifiRemoteStationManager ()->GetBlockAckTxVector (m_psduMap.begin ()->second->GetAddr1 (),
491 m_txParams.m_txVector);
492 responseTxVector = &txVector;
497 else if (m_txParams.m_txVector.IsUlMu ()
504 NS_ABORT_MSG (
"Unable to handle the selected acknowledgment method ("
505 << m_txParams.m_acknowledgment.get () <<
")");
510 for (
const auto& psdu : m_psduMap)
512 psduMap.emplace (psdu.first, psdu.second);
516 if (m_txParams.m_txVector.IsUlMu ())
519 m_txParams.m_txVector,
520 m_phy->GetPhyBand ());
524 txDuration = m_phy->CalculateTxDuration (psduMap, m_txParams.m_txVector, m_phy->GetPhyBand ());
527 Time durationId = GetPsduDurationId (txDuration, m_txParams);
528 for (
auto& psdu : m_psduMap)
530 psdu.second->SetDuration (durationId);
536 if (!m_txParams.m_txVector.IsUlMu ())
543 Time timeout = txDuration + m_phy->GetSifs () + m_phy->GetSlot ()
544 + m_phy->CalculatePhyPreambleAndHeaderDuration (*responseTxVector);
545 m_channelAccessManager->NotifyAckTimeoutStartNow (
timeout);
553 this, mpdu, m_txParams.m_txVector);
558 this, psdu, m_txParams.m_txVector);
562 &m_psduMap, &m_staExpectTbPpduFrom, m_staExpectTbPpduFrom.size ());
567 &m_psduMap, &m_staExpectTbPpduFrom, m_staExpectTbPpduFrom.size ());
571 this, m_psduMap.begin ()->second, m_txParams.m_txVector);
580 ForwardPsduMapDown (psduMap, m_txParams.m_txVector);
588 for (
const auto& psdu : psduMap)
590 NS_LOG_DEBUG (
"Transmitting: [STAID=" << psdu.first <<
", " << *psdu.second <<
"]");
593 for (
const auto& psdu : psduMap)
595 NotifyTxToEdca (psdu.second);
597 if (psduMap.size () > 1 || psduMap.begin ()->second->IsAggregate () || psduMap.begin ()->second->IsSingle ())
602 m_phy->Send (psduMap, txVector);
606 HeFrameExchangeManager::PrepareMuBar (
const WifiTxVector& responseTxVector,
607 std::map<uint16_t, CtrlBAckRequestHeader> recipients)
const
614 SetTargetRssi (muBar);
618 for (
auto& userInfo : muBar)
620 auto recipientIt = recipients.find (userInfo.GetAid12 ());
621 NS_ASSERT (recipientIt != recipients.end ());
624 userInfo.SetMuBarTriggerDepUserInfo (recipientIt->second);
633 if (muBar.GetNUserInfoFields () > 1)
635 rxAddress = Mac48Address::GetBroadcast ();
640 rxAddress = m_apMac->GetStaList ().at (recipients.begin ()->first);
652 return Create<WifiMacQueueItem> (bar, hdr);
664 if (acknowledgment->
method == WifiAcknowledgment::DL_MU_BAR_BA_SEQUENCE)
677 duration += m_phy->GetSifs ()
678 + m_phy->CalculateTxDuration (
GetAckSize (), info.ackTxVector, m_phy->GetPhyBand ());
684 duration += m_phy->GetSifs ()
686 info.blockAckTxVector, m_phy->GetPhyBand ());
691 const auto& info = stations.second;
692 duration += m_phy->GetSifs ()
694 info.blockAckReqTxVector, m_phy->GetPhyBand ())
697 info.blockAckTxVector, m_phy->GetPhyBand ());
705 else if (acknowledgment->
method == WifiAcknowledgment::DL_MU_TF_MU_BAR)
714 const auto& info = stations.second;
715 NS_ASSERT (info.blockAckTxVector.GetHeMuUserInfoMap ().size () == 1);
716 uint16_t staId = info.blockAckTxVector.GetHeMuUserInfoMap ().begin ()->first;
718 info.blockAckTxVector,
719 m_phy->GetPhyBand (),
722 if (currBlockAckDuration > duration)
724 duration = currBlockAckDuration;
730 dlMuTfMuBarAcknowledgment->
ulLength = HePhy::ConvertHeTbPpduDurationToLSigLength (duration, m_phy->GetPhyBand ());
732 duration = HePhy::ConvertLSigLengthToHeTbPpduDuration (dlMuTfMuBarAcknowledgment->
ulLength,
733 txVector, m_phy->GetPhyBand ());
737 + m_phy->CalculateTxDuration (muBarSize,
739 m_phy->GetPhyBand ())
740 + m_phy->GetSifs () + duration;
745 else if (acknowledgment->
method == WifiAcknowledgment::DL_MU_AGGREGATE_TF)
754 const auto& info = stations.second;
755 NS_ASSERT (info.blockAckTxVector.GetHeMuUserInfoMap ().size () == 1);
756 uint16_t staId = info.blockAckTxVector.GetHeMuUserInfoMap ().begin ()->first;
758 info.blockAckTxVector,
759 m_phy->GetPhyBand (),
762 if (currBlockAckDuration > duration)
764 duration = currBlockAckDuration;
770 dlMuAggrTfAcknowledgment->
ulLength = HePhy::ConvertHeTbPpduDurationToLSigLength (duration, m_phy->GetPhyBand ());
772 duration = HePhy::ConvertLSigLengthToHeTbPpduDuration (dlMuAggrTfAcknowledgment->
ulLength,
773 txVector, m_phy->GetPhyBand ());
780 else if (acknowledgment->
method == WifiAcknowledgment::UL_MU_MULTI_STA_BA)
786 m_phy->GetPhyBand ());
792 else if (acknowledgment->
method == WifiAcknowledgment::ACK_AFTER_TB_PPDU)
801 VhtFrameExchangeManager::CalculateAcknowledgmentTime (acknowledgment);
806 HeFrameExchangeManager::GetTxDuration (uint32_t ppduPayloadSize,
Mac48Address receiver,
811 return VhtFrameExchangeManager::GetTxDuration (ppduPayloadSize, receiver, txParams);
818 && txParams.
m_acknowledgment->method == WifiAcknowledgment::DL_MU_AGGREGATE_TF)
826 ppduPayloadSize = MpduAggregator::GetSizeIfAggregated (info->second.muBarSize, ppduPayloadSize);
829 uint16_t staId = (txParams.
m_txVector.
IsDlMu () ? m_apMac->GetAssociationId (receiver)
830 : m_staMac->GetAssociationId ());
831 Time psduDuration = m_phy->CalculateTxDuration (ppduPayloadSize, txParams.
m_txVector,
832 m_phy->GetPhyBand (), staId);
839 const std::set<Mac48Address>* staMissedTbPpduFrom,
840 std::size_t nSolicitedStations)
842 NS_LOG_FUNCTION (
this << psduMap << staMissedTbPpduFrom->size () << nSolicitedStations);
846 && psduMap->begin ()->second->GetHeader (0).IsTrigger ());
849 NS_ASSERT (!staMissedTbPpduFrom->empty ());
852 if (staMissedTbPpduFrom->size () == nSolicitedStations)
855 m_edca->UpdateFailedCw ();
857 TransmissionFailed ();
859 else if (!m_multiStaBaEvent.IsRunning ())
862 TransmissionSucceeded ();
869 HeFrameExchangeManager::BlockAcksInTbPpduTimeout (
WifiPsduMap* psduMap,
870 const std::set<Mac48Address>* staMissedBlockAckFrom,
871 std::size_t nSolicitedStations)
877 && (m_txParams.m_acknowledgment->method == WifiAcknowledgment::DL_MU_AGGREGATE_TF
878 || m_txParams.m_acknowledgment->method == WifiAcknowledgment::DL_MU_TF_MU_BAR));
881 NS_ASSERT (!staMissedBlockAckFrom->empty ());
885 if (staMissedBlockAckFrom->size () == nSolicitedStations)
889 m_mac->GetWifiRemoteStationManager ()->ReportDataFailed (*psduMap->begin ()->second->begin ());
898 m_triggerFrame =
nullptr;
900 for (
const auto& sta : *staMissedBlockAckFrom)
909 MissedBlockAck (psdu, m_txParams.m_txVector, psduResetCw);
910 resetCw = resetCw || psduResetCw;
921 m_edca->UpdateFailedCw ();
924 if (staMissedBlockAckFrom->size () == nSolicitedStations)
927 TransmissionFailed ();
931 TransmissionSucceeded ();
944 m_mac->GetWifiRemoteStationManager ()->ReportDataFailed (*psdu->
begin ());
946 MissedBlockAck (psdu, m_txParams.m_txVector, resetCw);
961 uint16_t staId = m_staMac->GetAssociationId ();
968 NS_ASSERT_MSG (heConfiguration != 0,
"This STA has to be an HE station to send an HE TB PPDU");
971 uint8_t powerLevel = m_mac->GetWifiRemoteStationManager ()->GetDefaultTxPowerLevel ();
989 int8_t pathLossDb = trigger.
GetApTxPower () -
static_cast<int8_t
> (m_mac->GetWifiRemoteStationManager ()->GetMostRecentRssi (triggerSender));
990 double reqTxPowerDbm =
static_cast<double> (userInfoIt->GetUlTargetRssi () + pathLossDb);
993 uint8_t numPowerLevels = m_phy->GetNTxPower ();
994 if (numPowerLevels > 1)
996 double stepDbm = (m_phy->GetTxPowerEnd () - m_phy->GetTxPowerStart ()) / (numPowerLevels - 1);
997 powerLevel =
static_cast<uint8_t
> (ceil ((reqTxPowerDbm - m_phy->GetTxPowerStart ()) / stepDbm));
998 if (powerLevel > numPowerLevels)
1000 powerLevel = numPowerLevels;
1003 if (reqTxPowerDbm > m_phy->GetPowerDbm (powerLevel))
1005 NS_LOG_WARN (
"The requested power level (" << reqTxPowerDbm <<
"dBm) cannot be satisfied (max: " << m_phy->GetTxPowerEnd () <<
"dBm)");
1009 <<
"input {pathLoss=" << pathLossDb <<
"dB, reqTxPower=" << reqTxPowerDbm <<
"dBm}"
1010 <<
" output {powerLevel=" << +powerLevel <<
" -> " << m_phy->GetPowerDbm (powerLevel) <<
"dBm}"
1011 <<
" PHY power capa {min=" << m_phy->GetTxPowerStart () <<
"dBm, max=" << m_phy->GetTxPowerEnd () <<
"dBm, levels:" << +numPowerLevels <<
"}");
1022 trigger.
SetApTxPower (
static_cast<int8_t
> (m_phy->GetPowerDbm (m_mac->GetWifiRemoteStationManager ()->GetDefaultTxPowerLevel ())));
1023 for (
auto& userInfo : trigger)
1025 const auto staList = m_apMac->GetStaList ();
1026 auto itAidAddr = staList.find (userInfo.GetAid12 ());
1027 NS_ASSERT (itAidAddr != staList.end ());
1028 int8_t rssi =
static_cast<int8_t
> (m_mac->GetWifiRemoteStationManager ()->GetMostRecentRssi (itAidAddr->second));
1029 rssi = (rssi >= -20) ? -20 : ((rssi <= -110) ? -110 : rssi);
1030 userInfo.SetUlTargetRssi (rssi);
1041 && txParams.
m_acknowledgment->method == WifiAcknowledgment::UL_MU_MULTI_STA_BA);
1053 receiver = staInfo.first.first;
1054 uint8_t tid = staInfo.first.second;
1055 std::size_t index = staInfo.second;
1057 blockAck.
SetAid11 (m_apMac->GetAssociationId (receiver), index);
1063 NS_LOG_DEBUG (
"Multi-STA Block Ack: Sending All-ack to=" << receiver);
1071 NS_LOG_DEBUG (
"Multi-STA Block Ack: Sending Ack to=" << receiver);
1079 auto addressTidPair = staInfo.first;
1080 auto agreementIt = m_agreements.find (addressTidPair);
1081 NS_ASSERT (agreementIt != m_agreements.end ());
1082 agreementIt->second.FillBlockAckBitmap (&blockAck, index);
1084 <<
" to=" << receiver <<
" tid=" << +tid);
1097 Ptr<WifiPsdu> psdu = GetWifiPsdu (Create<WifiMacQueueItem> (packet, hdr),
1105 m_phy->GetPhyBand ());
1110 psdu->
SetDuration (GetPsduDurationId (txDuration, params));
1119 m_muSnrTag.Reset ();
1120 Simulator::Schedule (txDuration, &HeFrameExchangeManager::TransmissionSucceeded,
this);
1128 NS_ASSERT (m_staMac != 0 && m_staMac->IsAssociated ());
1130 NS_LOG_DEBUG (
"Received a Trigger Frame (basic variant) soliciting a transmission");
1134 NS_LOG_DEBUG (
"Carrier Sensing required and channel busy, do nothing");
1144 std::vector<uint8_t> tids;
1145 uint16_t staId = m_staMac->GetAssociationId ();
1148 for (uint8_t i = 0; i < 4; i++)
1151 tids.push_back (acIt->second.GetHighTid ());
1152 tids.push_back (acIt->second.GetLowTid ());
1165 Time ppduDuration = HePhy::ConvertLSigLengthToHeTbPpduDuration (trigger.
GetUlLength (),
1167 m_phy->GetPhyBand ());
1169 for (
const auto& tid : tids)
1184 && TryAddMpdu (mpdu, txParams, ppduDuration))
1200 std::vector<Ptr<WifiMacQueueItem>> mpduList = m_mpduAggregator->GetNextAmpdu (item, txParams,
1203 psdu = (mpduList.size () > 1 ? Create<WifiPsdu> (std::move (mpduList))
1204 : Create<WifiPsdu> (item,
true));
1213 SendPsduMapWithProtection (
WifiPsduMap {{staId, psdu}}, txParams);
1218 SendQosNullFramesInTbPpdu (trigger, hdr);
1227 NS_ASSERT (m_staMac != 0 && m_staMac->IsAssociated ());
1233 NS_LOG_DEBUG (
"Carrier Sensing required and channel busy, do nothing");
1255 Time ppduDuration = HePhy::ConvertLSigLengthToHeTbPpduDuration (trigger.
GetUlLength (),
1257 m_phy->GetPhyBand ());
1261 std::vector<Ptr<WifiMacQueueItem>> mpduList;
1266 && IsWithinSizeAndTimeLimits (txParams.
GetSizeIfAddMpdu (mpdu = Create<WifiMacQueueItem> (Create<Packet> (),
1268 hdr.
GetAddr2 (), txParams, ppduDuration))
1270 NS_LOG_DEBUG (
"Aggregating a QoS Null frame with tid=" << +tid);
1279 mpduList.push_back (mpdu);
1283 if (mpduList.empty ())
1285 NS_LOG_DEBUG (
"Not enough time to send a QoS Null frame");
1289 Ptr<WifiPsdu> psdu = (mpduList.size () > 1 ? Create<WifiPsdu> (std::move (mpduList))
1290 : Create<WifiPsdu> (mpduList.front (),
true));
1291 uint16_t staId = m_staMac->GetAssociationId ();
1292 SendPsduMapWithProtection (
WifiPsduMap {{staId, psdu}}, txParams);
1305 if (txVector.
IsUlMu () && m_txTimer.IsRunning ()
1306 && m_txTimer.GetReason () == WifiTxTimer::WAIT_TB_PPDU_AFTER_BASIC_TF)
1310 && m_txParams.m_acknowledgment->method == WifiAcknowledgment::UL_MU_MULTI_STA_BA);
1314 if (m_staExpectTbPpduFrom.find (sender) == m_staExpectTbPpduFrom.end ())
1316 NS_LOG_WARN (
"Received a TB PPDU from an unexpected station: " << sender);
1322 NS_LOG_DEBUG (
"Received a BlockAckReq in a TB PPDU from " << sender);
1328 auto agreementIt = m_agreements.find ({sender, tid});
1329 NS_ASSERT (agreementIt != m_agreements.end ());
1334 acknowledgment->
baType.
m_bitmapLen.push_back (GetBlockAckType (sender, tid).m_bitmapLen.at (0));
1336 m_muSnrTag.Set (staId, rxSignalInfo.
snr);
1340 NS_LOG_DEBUG (
"Received an S-MPDU in a TB PPDU from " << sender <<
" (" << *mpdu <<
")");
1343 auto agreementIt = m_agreements.find ({sender, tid});
1344 NS_ASSERT (agreementIt != m_agreements.end ());
1345 agreementIt->second.NotifyReceivedMpdu (mpdu);
1351 m_muSnrTag.Set (staId, rxSignalInfo.
snr);
1360 VhtFrameExchangeManager::ReceiveMpdu (mpdu, rxSignalInfo, txVector, inAmpdu);
1367 m_multiStaBaEvent = Simulator::Schedule (m_phy->GetSifs (),
1368 &HeFrameExchangeManager::SendMultiStaBlockAck,
1369 this, std::cref (m_txParams));
1373 m_staExpectTbPpduFrom.erase (sender);
1375 if (m_staExpectTbPpduFrom.empty ())
1378 m_txTimer.Cancel ();
1379 m_channelAccessManager->NotifyAckTimeoutResetNow ();
1381 if (!m_multiStaBaEvent.IsRunning ())
1387 TransmissionSucceeded ();
1397 if (hdr.
IsAck () && m_txTimer.IsRunning ()
1398 && m_txTimer.GetReason () == WifiTxTimer::WAIT_NORMAL_ACK_AFTER_DL_MU_PPDU)
1401 NS_ASSERT (m_txParams.m_acknowledgment);
1402 NS_ASSERT (m_txParams.m_acknowledgment->method == WifiAcknowledgment::DL_MU_BAR_BA_SEQUENCE);
1408 auto it = m_psduMap.find (staId);
1413 ReceivedNormalAck (*it->second->begin (), m_txParams.m_txVector, txVector, rxSignalInfo, tag.
Get ());
1415 else if (hdr.
IsBlockAck () && m_txTimer.IsRunning ()
1416 && m_txTimer.GetReason () == WifiTxTimer::WAIT_BLOCK_ACKS_IN_TB_PPDU)
1419 NS_LOG_DEBUG (
"Received BlockAck in TB PPDU from=" << sender);
1428 std::pair<uint16_t,uint16_t> ret = GetBaManager (tid)->NotifyGotBlockAck (blockAck, hdr.
GetAddr2 (),
1430 m_mac->GetWifiRemoteStationManager ()->ReportAmpduTxStatus (hdr.
GetAddr2 (), ret.first, ret.second,
1431 rxSignalInfo.
snr, tag.
Get (), m_txParams.m_txVector);
1434 if (m_staExpectTbPpduFrom.erase (sender) == 0)
1436 NS_LOG_WARN (
"Received a BlockAck from an unexpected stations: " << sender);
1440 if (m_staExpectTbPpduFrom.empty ())
1443 m_txTimer.Cancel ();
1444 m_channelAccessManager->NotifyAckTimeoutResetNow ();
1445 m_triggerFrame =
nullptr;
1449 TransmissionSucceeded ();
1452 else if (hdr.
IsBlockAck () && m_txTimer.IsRunning ()
1453 && m_txTimer.GetReason () == WifiTxTimer::WAIT_BLOCK_ACK_AFTER_TB_PPDU)
1459 "A Multi-STA BlockAck is expected after a TB PPDU");
1462 NS_ASSERT (m_staMac !=
nullptr && m_staMac->IsAssociated ());
1463 uint16_t staId = m_staMac->GetAssociationId ();
1466 if (indices.empty ())
1468 NS_LOG_DEBUG (
"No Per AID TID Info subfield intended for me");
1476 for (
const auto& index : indices)
1483 NS_ABORT_IF (m_psduMap.empty () || m_psduMap.begin ()->first != staId);
1484 GetBaManager (tid)->NotifyGotAck (*m_psduMap.at (staId)->begin ());
1489 if (blockAck.
GetAckType (index) && tid == 14)
1493 NS_ABORT_IF (m_psduMap.empty () || m_psduMap.begin ()->first != staId);
1494 std::set<uint8_t> tids = m_psduMap.at (staId)->GetTids ();
1495 NS_ABORT_MSG_IF (tids.size () > 1,
"Multi-TID A-MPDUs not supported yet");
1496 tid = *tids.begin ();
1499 std::pair<uint16_t,uint16_t> ret = GetBaManager (tid)->NotifyGotBlockAck (blockAck,
1502 m_mac->GetWifiRemoteStationManager ()->ReportAmpduTxStatus (hdr.
GetAddr2 (), ret.first,
1503 ret.second, rxSignalInfo.
snr,
1504 tag.
Get (staId), m_txParams.m_txVector);
1507 if (m_psduMap.at (staId)->GetHeader (0).IsQosData ()
1509 || std::any_of (blockAck.
GetBitmap (index).begin (),
1511 [](uint8_t b) { return b != 0; })))
1513 NS_ASSERT (m_psduMap.at (staId)->GetHeader (0).HasData ());
1514 NS_ASSERT (m_psduMap.at (staId)->GetHeader (0).GetQosTid () == tid);
1519 m_mac->GetQosTxop (tid)->StartMuEdcaTimerNow ();
1524 m_txTimer.Cancel ();
1525 m_channelAccessManager->NotifyAckTimeoutResetNow ();
1531 if (m_staMac ==
nullptr)
1539 m_triggerFrameInAmpdu =
true;
1548 || !m_staMac->IsAssociated ()
1556 uint16_t staId = m_staMac->GetAssociationId ();
1561 NS_LOG_DEBUG (
"Received MU-BAR Trigger Frame from=" << sender);
1562 m_mac->GetWifiRemoteStationManager ()->ReportRxOk (sender, rxSignalInfo, txVector);
1570 auto agreementIt = m_agreements.find ({sender, tid});
1572 if (agreementIt == m_agreements.end ())
1574 NS_LOG_DEBUG (
"There's not a valid agreement for this BlockAckReq");
1581 Simulator::Schedule (m_phy->GetSifs (), &HeFrameExchangeManager::SendBlockAck,
this,
1583 GetHeTbTxVector (trigger, hdr.
GetAddr2 ()), rxSignalInfo.
snr);
1587 Simulator::Schedule (m_phy->GetSifs (), &HeFrameExchangeManager::ReceiveBasicTrigger,
1588 this, trigger, hdr);
1590 else if (trigger.
IsBsrp ())
1592 Simulator::Schedule (m_phy->GetSifs (), &HeFrameExchangeManager::SendQosNullFramesInTbPpdu,
1593 this, trigger, hdr);
1599 VhtFrameExchangeManager::ReceiveMpdu (mpdu, rxSignalInfo, txVector, inAmpdu);
1607 VhtFrameExchangeManager::ReceiveMpdu (mpdu, rxSignalInfo, txVector, inAmpdu);;
1612 const WifiTxVector& txVector,
const std::vector<bool>& perMpduStatus)
1614 std::set<uint8_t> tids = psdu->
GetTids ();
1616 if (txVector.
IsUlMu () && m_txTimer.IsRunning ()
1617 && m_txTimer.GetReason () == WifiTxTimer::WAIT_TB_PPDU_AFTER_BASIC_TF)
1621 && m_txParams.m_acknowledgment->method == WifiAcknowledgment::UL_MU_MULTI_STA_BA);
1625 if (m_staExpectTbPpduFrom.find (sender) == m_staExpectTbPpduFrom.end ())
1627 NS_LOG_WARN (
"Received a TB PPDU from an unexpected station: " << sender);
1631 NS_LOG_DEBUG (
"Received an A-MPDU in a TB PPDU from " << sender <<
" (" << *psdu <<
")");
1633 if (std::any_of (tids.begin (), tids.end (),
1634 [&psdu](uint8_t tid)
1635 { return psdu->GetAckPolicyForTid (tid) == WifiMacHeader::NORMAL_ACK; }))
1637 if (std::all_of (perMpduStatus.cbegin (), perMpduStatus.cend (), [](
bool v) { return v; }))
1647 for (
const auto& tid : tids)
1650 acknowledgment->
baType.
m_bitmapLen.push_back (GetBlockAckType (sender, tid).m_bitmapLen.at (0));
1654 m_muSnrTag.Set (staId, rxSignalInfo.
snr);
1660 m_multiStaBaEvent = Simulator::Schedule (m_phy->GetSifs (),
1661 &HeFrameExchangeManager::SendMultiStaBlockAck,
1662 this, std::cref (m_txParams));
1666 m_staExpectTbPpduFrom.erase (sender);
1668 if (m_staExpectTbPpduFrom.empty ())
1671 m_txTimer.Cancel ();
1672 m_channelAccessManager->NotifyAckTimeoutResetNow ();
1674 if (!m_multiStaBaEvent.IsRunning ())
1680 TransmissionSucceeded ();
1688 if (txVector.
IsUlMu () && m_txTimer.IsRunning ()
1689 && m_txTimer.GetReason () == WifiTxTimer::WAIT_QOS_NULL_AFTER_BSRP_TF)
1693 if (m_staExpectTbPpduFrom.find (sender) == m_staExpectTbPpduFrom.end ())
1695 NS_LOG_WARN (
"Received a TB PPDU from an unexpected station: " << sender);
1699 { return mpdu->GetHeader ().IsQosData ()
1700 && !mpdu->GetHeader ().HasData ();
1703 NS_LOG_WARN (
"No QoS Null frame in the received PSDU");
1707 NS_LOG_DEBUG (
"Received QoS Null frames in a TB PPDU from " << sender);
1710 m_staExpectTbPpduFrom.erase (sender);
1712 if (m_staExpectTbPpduFrom.empty ())
1715 m_txTimer.Cancel ();
1716 m_channelAccessManager->NotifyAckTimeoutResetNow ();
1721 TransmissionSucceeded ();
1728 if (m_triggerFrameInAmpdu)
1731 auto psduIt = psdu->
begin ();
1732 while (psduIt != psdu->
end ())
1734 if ((*psduIt)->GetHeader ().IsTrigger ())
1736 ReceiveMpdu (*psduIt, rxSignalInfo, txVector,
false);
1741 m_triggerFrameInAmpdu =
false;
1746 VhtFrameExchangeManager::EndReceiveAmpdu (psdu, rxSignalInfo, txVector, perMpduStatus);