A Discrete-Event Network Simulator
API
rr-multi-user-scheduler.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2020 Universita' degli Studi di Napoli Federico II
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Stefano Avallone <stavallo@unina.it>
19  */
20 
21 #include "ns3/log.h"
23 #include "ns3/wifi-protection.h"
24 #include "ns3/wifi-acknowledgment.h"
25 #include "ns3/wifi-psdu.h"
27 #include "he-configuration.h"
28 #include "he-phy.h"
29 #include <algorithm>
30 
31 namespace ns3 {
32 
33 NS_LOG_COMPONENT_DEFINE ("RrMultiUserScheduler");
34 
35 NS_OBJECT_ENSURE_REGISTERED (RrMultiUserScheduler);
36 
37 TypeId
39 {
40  static TypeId tid = TypeId ("ns3::RrMultiUserScheduler")
42  .SetGroupName ("Wifi")
43  .AddConstructor<RrMultiUserScheduler> ()
44  .AddAttribute ("NStations",
45  "The maximum number of stations that can be granted an RU in a DL MU OFDMA transmission",
46  UintegerValue (4),
48  MakeUintegerChecker<uint8_t> (1, 74))
49  .AddAttribute ("EnableTxopSharing",
50  "If enabled, allow A-MPDUs of different TIDs in a DL MU PPDU.",
51  BooleanValue (true),
54  .AddAttribute ("ForceDlOfdma",
55  "If enabled, return DL_MU_TX even if no DL MU PPDU could be built.",
56  BooleanValue (false),
59  .AddAttribute ("EnableUlOfdma",
60  "If enabled, return UL_MU_TX if DL_MU_TX was returned the previous time.",
61  BooleanValue (true),
64  .AddAttribute ("EnableBsrp",
65  "If enabled, send a BSRP Trigger Frame before an UL MU transmission.",
66  BooleanValue (true),
69  .AddAttribute ("UlPsduSize",
70  "The default size in bytes of the solicited PSDU (to be sent in a TB PPDU)",
71  UintegerValue (500),
73  MakeUintegerChecker<uint32_t> ())
74  .AddAttribute ("UseCentral26TonesRus",
75  "If enabled, central 26-tone RUs are allocated, too, when the "
76  "selected RU type is at least 52 tones.",
77  BooleanValue (false),
80  .AddAttribute ("MaxCredits",
81  "Maximum amount of credits a station can have. When transmitting a DL MU PPDU, "
82  "the amount of credits received by each station equals the TX duration (in "
83  "microseconds) divided by the total number of stations. Stations that are the "
84  "recipient of the DL MU PPDU have to pay a number of credits equal to the TX "
85  "duration (in microseconds) times the allocated bandwidth share",
86  TimeValue (Seconds (1)),
88  MakeTimeChecker ())
89  ;
90  return tid;
91 }
92 
94  : m_ulTriggerType (TriggerFrameType::BASIC_TRIGGER)
95 {
96  NS_LOG_FUNCTION (this);
97 }
98 
100 {
102 }
103 
104 void
106 {
107  NS_LOG_FUNCTION (this);
108  NS_ASSERT (m_apMac != nullptr);
109  m_apMac->TraceConnectWithoutContext ("AssociatedSta",
111  m_apMac->TraceConnectWithoutContext ("DeAssociatedSta",
113  for (const auto& ac : wifiAcList)
114  {
115  m_staList.insert ({ac.first, {}});
116  }
118 }
119 
120 void
122 {
123  NS_LOG_FUNCTION (this);
124  m_staList.clear ();
125  m_candidates.clear ();
126  m_trigger = nullptr;
127  m_txParams.Clear ();
128  m_apMac->TraceDisconnectWithoutContext ("AssociatedSta",
130  m_apMac->TraceDisconnectWithoutContext ("DeAssociatedSta",
133 }
134 
137 {
138  NS_LOG_FUNCTION (this);
139 
141 
142  if (mpdu != 0 && !GetWifiRemoteStationManager ()->GetHeSupported (mpdu->GetHeader ().GetAddr1 ()))
143  {
144  return SU_TX;
145  }
146 
148  {
149  return TrySendingBsrpTf ();
150  }
151 
154  {
155  TxFormat txFormat = TrySendingBasicTf ();
156 
157  if (txFormat != DL_MU_TX)
158  {
159  return txFormat;
160  }
161  }
162 
163  return TrySendingDlMuPpdu ();
164 }
165 
168 {
169  NS_LOG_FUNCTION (this);
170 
171  CtrlTriggerHeader trigger (TriggerFrameType::BSRP_TRIGGER, GetDlMuInfo ().txParams.m_txVector);
172 
174  txVector.SetGuardInterval (trigger.GetGuardInterval ());
175 
176  Ptr<Packet> packet = Create<Packet> ();
177  packet->AddHeader (trigger);
178 
180  if (trigger.GetNUserInfoFields () == 1)
181  {
182  NS_ASSERT (m_apMac->GetStaList ().find (trigger.begin ()->GetAid12 ()) != m_apMac->GetStaList ().end ());
183  receiver = m_apMac->GetStaList ().at (trigger.begin ()->GetAid12 ());
184  }
185 
187  hdr.SetAddr1 (receiver);
188  hdr.SetAddr2 (m_apMac->GetAddress ());
189  hdr.SetDsNotTo ();
190  hdr.SetDsNotFrom ();
191 
192  Ptr<WifiMacQueueItem> item = Create<WifiMacQueueItem> (packet, hdr);
193 
194  m_txParams.Clear ();
195  // set the TXVECTOR used to send the Trigger Frame
196  m_txParams.m_txVector = m_apMac->GetWifiRemoteStationManager ()->GetRtsTxVector (receiver);
197 
198  if (!m_heFem->TryAddMpdu (item, m_txParams, m_availableTime))
199  {
200  // sending the BSRP Trigger Frame is not possible, hence return NO_TX. In
201  // this way, no transmission will occur now and the next time we will
202  // try again sending a BSRP Trigger Frame.
203  NS_LOG_DEBUG ("Remaining TXOP duration is not enough for BSRP TF exchange");
204  return NO_TX;
205  }
206 
207  // Compute the time taken by each station to transmit 8 QoS Null frames
208  Time qosNullTxDuration = Seconds (0);
209  for (const auto& userInfo : trigger)
210  {
211  Time duration = WifiPhy::CalculateTxDuration (m_sizeOf8QosNull, txVector,
212  m_apMac->GetWifiPhy ()->GetPhyBand (),
213  userInfo.GetAid12 ());
214  qosNullTxDuration = Max (qosNullTxDuration, duration);
215  }
216 
217  if (m_availableTime != Time::Min ())
218  {
219  // TryAddMpdu only considers the time to transmit the Trigger Frame
221  NS_ASSERT (m_txParams.m_acknowledgment && m_txParams.m_acknowledgment->acknowledgmentTime.IsZero ());
223 
224  if (m_txParams.m_protection->protectionTime
225  + m_txParams.m_txDuration // BSRP TF tx time
226  + m_apMac->GetWifiPhy ()->GetSifs ()
227  + qosNullTxDuration
228  > m_availableTime)
229  {
230  NS_LOG_DEBUG ("Remaining TXOP duration is not enough for BSRP TF exchange");
231  return NO_TX;
232  }
233  }
234 
235  NS_LOG_DEBUG ("Duration of QoS Null frames: " << qosNullTxDuration.As (Time::MS));
236  trigger.SetUlLength (HePhy::ConvertHeTbPpduDurationToLSigLength (qosNullTxDuration,
237  m_apMac->GetWifiPhy ()->GetPhyBand ()));
238  trigger.SetCsRequired (true);
239  m_heFem->SetTargetRssi (trigger);
240 
241  packet = Create<Packet> ();
242  packet->AddHeader (trigger);
243  m_trigger = Create<WifiMacQueueItem> (packet, hdr);
244 
246  m_tbPpduDuration = qosNullTxDuration;
247 
248  return UL_MU_TX;
249 }
250 
253 {
254  NS_LOG_FUNCTION (this);
255 
256  // check if an UL OFDMA transmission is possible after a DL OFDMA transmission
257  NS_ABORT_MSG_IF (m_ulPsduSize == 0, "The UlPsduSize attribute must be set to a non-null value");
258 
259  // determine which of the stations served in DL have UL traffic
260  uint32_t maxBufferSize = 0;
261  // candidates sorted in decreasing order of queue size
262  std::multimap<uint8_t, CandidateInfo, std::greater<uint8_t>> ulCandidates;
263 
264  for (const auto& candidate : m_candidates)
265  {
266  uint8_t queueSize = m_apMac->GetMaxBufferStatus (candidate.first->address);
267  if (queueSize == 255)
268  {
269  NS_LOG_DEBUG ("Buffer status of station " << candidate.first->address << " is unknown");
270  maxBufferSize = std::max (maxBufferSize, m_ulPsduSize);
271  }
272  else if (queueSize == 254)
273  {
274  NS_LOG_DEBUG ("Buffer status of station " << candidate.first->address << " is not limited");
275  maxBufferSize = 0xffffffff;
276  }
277  else
278  {
279  NS_LOG_DEBUG ("Buffer status of station " << candidate.first->address << " is " << +queueSize);
280  maxBufferSize = std::max (maxBufferSize, static_cast<uint32_t> (queueSize * 256));
281  }
282  // serve the station if its queue size is not null
283  if (queueSize > 0)
284  {
285  ulCandidates.emplace (queueSize, candidate);
286  }
287  }
288 
289  // if the maximum buffer size is 0, skip UL OFDMA and proceed with trying DL OFDMA
290  if (maxBufferSize > 0)
291  {
292  NS_ASSERT (!ulCandidates.empty ());
293  std::size_t count = ulCandidates.size ();
294  std::size_t nCentral26TonesRus;
295  HeRu::RuType ruType = HeRu::GetEqualSizedRusForStations (m_apMac->GetWifiPhy ()->GetChannelWidth (),
296  count, nCentral26TonesRus);
297  if (!m_useCentral26TonesRus || ulCandidates.size () == count)
298  {
299  nCentral26TonesRus = 0;
300  }
301  else
302  {
303  nCentral26TonesRus = std::min (ulCandidates.size () - count, nCentral26TonesRus);
304  }
305 
306  WifiTxVector txVector;
308  auto candidateIt = ulCandidates.begin ();
309 
310  if (GetLastTxFormat () == DL_MU_TX)
311  {
312  txVector.SetChannelWidth (GetDlMuInfo ().txParams.m_txVector.GetChannelWidth ());
313  txVector.SetGuardInterval (CtrlTriggerHeader ().GetGuardInterval ());
314 
315  for (std::size_t i = 0; i < count + nCentral26TonesRus; i++)
316  {
317  NS_ASSERT (candidateIt != ulCandidates.end ());
318  uint16_t staId = candidateIt->second.first->aid;
319  // AssignRuIndices will be called below to set RuSpec
320  txVector.SetHeMuUserInfo (staId,
321  {{(i < count ? ruType : HeRu::RU_26_TONE), 1, false},
323  GetDlMuInfo ().txParams.m_txVector.GetNss (staId)});
324 
325  candidateIt++;
326  }
327  }
328  else
329  {
330  CtrlTriggerHeader trigger;
331  GetUlMuInfo ().trigger->GetPacket ()->PeekHeader (trigger);
332 
333  txVector.SetChannelWidth (trigger.GetUlBandwidth ());
334  txVector.SetGuardInterval (trigger.GetGuardInterval ());
335 
336  for (std::size_t i = 0; i < count + nCentral26TonesRus; i++)
337  {
338  NS_ASSERT (candidateIt != ulCandidates.end ());
339  uint16_t staId = candidateIt->second.first->aid;
340  auto userInfoIt = trigger.FindUserInfoWithAid (staId);
341  NS_ASSERT (userInfoIt != trigger.end ());
342  // AssignRuIndices will be called below to set RuSpec
343  txVector.SetHeMuUserInfo (staId,
344  {{(i < count ? ruType : HeRu::RU_26_TONE), 1, false},
345  HePhy::GetHeMcs (userInfoIt->GetUlMcs ()),
346  userInfoIt->GetNss ()});
347 
348  candidateIt++;
349  }
350  }
351 
352  // remove candidates that will not be served
353  ulCandidates.erase (candidateIt, ulCandidates.end ());
354  AssignRuIndices (txVector);
355 
357  Ptr<Packet> packet = Create<Packet> ();
358  packet->AddHeader (trigger);
359 
361  if (ulCandidates.size () == 1)
362  {
363  receiver = ulCandidates.begin ()->second.first->address;
364  }
365 
367  hdr.SetAddr1 (receiver);
368  hdr.SetAddr2 (m_apMac->GetAddress ());
369  hdr.SetDsNotTo ();
370  hdr.SetDsNotFrom ();
371 
372  Ptr<WifiMacQueueItem> item = Create<WifiMacQueueItem> (packet, hdr);
373 
374  // compute the maximum amount of time that can be granted to stations.
375  // This value is limited by the max PPDU duration
376  Time maxDuration = GetPpduMaxTime (txVector.GetPreambleType ());
377 
378  m_txParams.Clear ();
379  // set the TXVECTOR used to send the Trigger Frame
380  m_txParams.m_txVector = m_apMac->GetWifiRemoteStationManager ()->GetRtsTxVector (receiver);
381 
382  if (!m_heFem->TryAddMpdu (item, m_txParams, m_availableTime))
383  {
384  // an UL OFDMA transmission is not possible, hence return NO_TX. In
385  // this way, no transmission will occur now and the next time we will
386  // try again performing an UL OFDMA transmission.
387  NS_LOG_DEBUG ("Remaining TXOP duration is not enough for UL MU exchange");
388  return NO_TX;
389  }
390 
391  if (m_availableTime != Time::Min ())
392  {
393  // TryAddMpdu only considers the time to transmit the Trigger Frame
397 
398  maxDuration = Min (maxDuration, m_availableTime
399  - m_txParams.m_protection->protectionTime
401  - m_apMac->GetWifiPhy ()->GetSifs ()
402  - m_txParams.m_acknowledgment->acknowledgmentTime);
403  if (maxDuration.IsNegative ())
404  {
405  NS_LOG_DEBUG ("Remaining TXOP duration is not enough for UL MU exchange");
406  return NO_TX;
407  }
408  }
409 
410  // Compute the time taken by each station to transmit a frame of maxBufferSize size
411  Time bufferTxTime = Seconds (0);
412  for (const auto& userInfo : trigger)
413  {
414  Time duration = WifiPhy::CalculateTxDuration (maxBufferSize, txVector,
415  m_apMac->GetWifiPhy ()->GetPhyBand (),
416  userInfo.GetAid12 ());
417  bufferTxTime = Max (bufferTxTime, duration);
418  }
419 
420  if (bufferTxTime < maxDuration)
421  {
422  // the maximum buffer size can be transmitted within the allowed time
423  maxDuration = bufferTxTime;
424  }
425  else
426  {
427  // maxDuration may be a too short time. If it does not allow any station to
428  // transmit at least m_ulPsduSize bytes, give up the UL MU transmission for now
429  Time minDuration = Seconds (0);
430  for (const auto& userInfo : trigger)
431  {
432  Time duration = WifiPhy::CalculateTxDuration (m_ulPsduSize, txVector,
433  m_apMac->GetWifiPhy ()->GetPhyBand (),
434  userInfo.GetAid12 ());
435  minDuration = (minDuration.IsZero () ? duration : Min (minDuration, duration));
436  }
437 
438  if (maxDuration < minDuration)
439  {
440  // maxDuration is a too short time, hence return NO_TX. In this way,
441  // no transmission will occur now and the next time we will try again
442  // performing an UL OFDMA transmission.
443  NS_LOG_DEBUG ("Available time " << maxDuration.As (Time::MS) << " is too short");
444  return NO_TX;
445  }
446  }
447 
448  // maxDuration is the time to grant to the stations. Finalize the Trigger Frame
449  NS_LOG_DEBUG ("TB PPDU duration: " << maxDuration.As (Time::MS));
450  trigger.SetUlLength (HePhy::ConvertHeTbPpduDurationToLSigLength (maxDuration,
451  m_apMac->GetWifiPhy ()->GetPhyBand ()));
452  trigger.SetCsRequired (true);
453  m_heFem->SetTargetRssi (trigger);
454  // set Preferred AC to the AC that gained channel access
455  for (auto& userInfo : trigger)
456  {
457  userInfo.SetBasicTriggerDepUserInfo (0, 0, m_edca->GetAccessCategory ());
458  }
459 
460  packet = Create<Packet> ();
461  packet->AddHeader (trigger);
462  m_trigger = Create<WifiMacQueueItem> (packet, hdr);
463 
465  m_tbPpduDuration = maxDuration;
466 
467  return UL_MU_TX;
468  }
469  return DL_MU_TX;
470 }
471 
472 void
474 {
475  NS_LOG_FUNCTION (this << aid << address);
476 
477  if (GetWifiRemoteStationManager ()->GetHeSupported (address))
478  {
479  for (auto& staList : m_staList)
480  {
481  staList.second.push_back (MasterInfo {aid, address, 0.0});
482  }
483  }
484 }
485 
486 void
488 {
489  NS_LOG_FUNCTION (this << aid << address);
490 
491  if (GetWifiRemoteStationManager ()->GetHeSupported (address))
492  {
493  for (auto& staList : m_staList)
494  {
495  staList.second.remove_if ([&aid, &address] (const MasterInfo& info)
496  { return info.aid == aid && info.address == address; });
497  }
498  }
499 }
500 
503 {
504  NS_LOG_FUNCTION (this);
505 
506  AcIndex primaryAc = m_edca->GetAccessCategory ();
507 
508  if (m_staList[primaryAc].empty ())
509  {
510  NS_LOG_DEBUG ("No HE stations associated: return SU_TX");
511  return TxFormat::SU_TX;
512  }
513 
514  std::size_t count = std::min (static_cast<std::size_t> (m_nStations), m_staList[primaryAc].size ());
515  std::size_t nCentral26TonesRus;
516  HeRu::RuType ruType = HeRu::GetEqualSizedRusForStations (m_apMac->GetWifiPhy ()->GetChannelWidth (), count,
517  nCentral26TonesRus);
518  NS_ASSERT (count >= 1);
519 
521  {
522  nCentral26TonesRus = 0;
523  }
524 
525  uint8_t currTid = wifiAcList.at (primaryAc).GetHighTid ();
526 
528 
529  if (mpdu != nullptr && mpdu->GetHeader ().IsQosData ())
530  {
531  currTid = mpdu->GetHeader ().GetQosTid ();
532  }
533 
534  // determine the list of TIDs to check
535  std::vector<uint8_t> tids;
536 
538  {
539  for (auto acIt = wifiAcList.find (primaryAc); acIt != wifiAcList.end (); acIt++)
540  {
541  uint8_t firstTid = (acIt->first == primaryAc ? currTid : acIt->second.GetHighTid ());
542  tids.push_back (firstTid);
543  tids.push_back (acIt->second.GetOtherTid (firstTid));
544  }
545  }
546  else
547  {
548  tids.push_back (currTid);
549  }
550 
551  Ptr<HeConfiguration> heConfiguration = m_apMac->GetHeConfiguration ();
552  NS_ASSERT (heConfiguration != 0);
553 
554  m_txParams.Clear ();
556  m_txParams.m_txVector.SetChannelWidth (m_apMac->GetWifiPhy ()->GetChannelWidth ());
557  m_txParams.m_txVector.SetGuardInterval (heConfiguration->GetGuardInterval ().GetNanoSeconds ());
558  m_txParams.m_txVector.SetBssColor (heConfiguration->GetBssColor ());
559 
560  // The TXOP limit can be exceeded by the TXOP holder if it does not transmit more
561  // than one Data or Management frame in the TXOP and the frame is not in an A-MPDU
562  // consisting of more than one MPDU (Sec. 10.22.2.8 of 802.11-2016).
563  // For the moment, we are considering just one MPDU per receiver.
564  Time actualAvailableTime = (m_initialFrame ? Time::Min () : m_availableTime);
565 
566  // iterate over the associated stations until an enough number of stations is identified
567  auto staIt = m_staList[primaryAc].begin ();
568  m_candidates.clear ();
569 
570  while (staIt != m_staList[primaryAc].end ()
571  && m_candidates.size () < std::min (static_cast<std::size_t> (m_nStations), count + nCentral26TonesRus))
572  {
573  NS_LOG_DEBUG ("Next candidate STA (MAC=" << staIt->address << ", AID=" << staIt->aid << ")");
574 
575  HeRu::RuType currRuType = (m_candidates.size () < count ? ruType : HeRu::RU_26_TONE);
576 
577  // check if the AP has at least one frame to be sent to the current station
578  for (uint8_t tid : tids)
579  {
580  AcIndex ac = QosUtilsMapTidToAc (tid);
581  NS_ASSERT (ac >= primaryAc);
582  // check that a BA agreement is established with the receiver for the
583  // considered TID, since ack sequences for DL MU PPDUs require block ack
584  if (m_apMac->GetQosTxop (ac)->GetBaAgreementEstablished (staIt->address, tid))
585  {
586  mpdu = m_apMac->GetQosTxop (ac)->PeekNextMpdu (tid, staIt->address);
587 
588  // we only check if the first frame of the current TID meets the size
589  // and duration constraints. We do not explore the queues further.
590  if (mpdu != 0)
591  {
592  // Use a temporary TX vector including only the STA-ID of the
593  // candidate station to check if the MPDU meets the size and time limits.
594  // An RU of the computed size is tentatively assigned to the candidate
595  // station, so that the TX duration can be correctly computed.
596  WifiTxVector suTxVector = GetWifiRemoteStationManager ()->GetDataTxVector (mpdu->GetHeader ()),
597  txVectorCopy = m_txParams.m_txVector;
598 
600  {{currRuType, 1, false},
601  suTxVector.GetMode (),
602  suTxVector.GetNss ()});
603 
604  if (!m_heFem->TryAddMpdu (mpdu, m_txParams, actualAvailableTime))
605  {
606  NS_LOG_DEBUG ("Adding the peeked frame violates the time constraints");
607  m_txParams.m_txVector = txVectorCopy;
608  }
609  else
610  {
611  // the frame meets the constraints
612  NS_LOG_DEBUG ("Adding candidate STA (MAC=" << staIt->address << ", AID="
613  << staIt->aid << ") TID=" << +tid);
614  m_candidates.push_back ({staIt, mpdu});
615  break; // terminate the for loop
616  }
617  }
618  else
619  {
620  NS_LOG_DEBUG ("No frames to send to " << staIt->address << " with TID=" << +tid);
621  }
622  }
623  }
624 
625  // move to the next station in the list
626  staIt++;
627  }
628 
629  if (m_candidates.empty ())
630  {
631  if (m_forceDlOfdma)
632  {
633  NS_LOG_DEBUG ("The AP does not have suitable frames to transmit: return NO_TX");
634  return NO_TX;
635  }
636  NS_LOG_DEBUG ("The AP does not have suitable frames to transmit: return SU_TX");
637  return SU_TX;
638  }
639 
640  return TxFormat::DL_MU_TX;
641 }
642 
643 MultiUserScheduler::DlMuInfo
644 RrMultiUserScheduler::ComputeDlMuInfo (void)
645 {
646  NS_LOG_FUNCTION (this);
647 
648  if (m_candidates.empty ())
649  {
650  return DlMuInfo ();
651  }
652 
653  uint16_t bw = m_apMac->GetWifiPhy ()->GetChannelWidth ();
654 
655  // compute how many stations can be granted an RU and the RU size
656  std::size_t nRusAssigned = m_txParams.GetPsduInfoMap ().size ();
657  std::size_t nCentral26TonesRus;
658  HeRu::RuType ruType = HeRu::GetEqualSizedRusForStations (bw, nRusAssigned, nCentral26TonesRus);
659 
660  NS_LOG_DEBUG (nRusAssigned << " stations are being assigned a " << ruType << " RU");
661 
662  if (!m_useCentral26TonesRus || m_candidates.size () == nRusAssigned)
663  {
664  nCentral26TonesRus = 0;
665  }
666  else
667  {
668  nCentral26TonesRus = std::min (m_candidates.size () - nRusAssigned, nCentral26TonesRus);
669  NS_LOG_DEBUG (nCentral26TonesRus << " stations are being assigned a 26-tones RU");
670  }
671 
672  DlMuInfo dlMuInfo;
673 
674  // We have to update the TXVECTOR
675  dlMuInfo.txParams.m_txVector.SetPreambleType (m_txParams.m_txVector.GetPreambleType ());
676  dlMuInfo.txParams.m_txVector.SetChannelWidth (m_txParams.m_txVector.GetChannelWidth ());
677  dlMuInfo.txParams.m_txVector.SetGuardInterval (m_txParams.m_txVector.GetGuardInterval ());
678  dlMuInfo.txParams.m_txVector.SetBssColor (m_txParams.m_txVector.GetBssColor ());
679 
680  auto candidateIt = m_candidates.begin (); // iterator over the list of candidate receivers
681 
682  for (std::size_t i = 0; i < nRusAssigned + nCentral26TonesRus; i++)
683  {
684  NS_ASSERT (candidateIt != m_candidates.end ());
685 
686  uint16_t staId = candidateIt->first->aid;
687  // AssignRuIndices will be called below to set RuSpec
688  dlMuInfo.txParams.m_txVector.SetHeMuUserInfo (staId,
689  {{(i < nRusAssigned ? ruType : HeRu::RU_26_TONE), 1, false},
690  m_txParams.m_txVector.GetMode (staId),
691  m_txParams.m_txVector.GetNss (staId)});
692  candidateIt++;
693  }
694 
695  // remove candidates that will not be served
696  m_candidates.erase (candidateIt, m_candidates.end ());
697 
698  AssignRuIndices (dlMuInfo.txParams.m_txVector);
699  m_txParams.Clear ();
700 
702 
703  // Compute the TX params (again) by using the stored MPDUs and the final TXVECTOR
704  Time actualAvailableTime = (m_initialFrame ? Time::Min () : m_availableTime);
705 
706  for (const auto& candidate : m_candidates)
707  {
708  mpdu = candidate.second;
709  NS_ASSERT (mpdu != nullptr);
710 
711  bool ret = m_heFem->TryAddMpdu (mpdu, dlMuInfo.txParams, actualAvailableTime);
712  NS_UNUSED (ret);
713  NS_ASSERT_MSG (ret, "Weird that an MPDU does not meet constraints when "
714  "transmitted over a larger RU");
715  }
716 
717  // We have to complete the PSDUs to send
718  Ptr<WifiMacQueue> queue;
719  Mac48Address receiver;
720 
721  for (const auto& candidate : m_candidates)
722  {
723  // Let us try first A-MSDU aggregation if possible
724  mpdu = candidate.second;
725  NS_ASSERT (mpdu != nullptr);
726  uint8_t tid = mpdu->GetHeader ().GetQosTid ();
727  receiver = mpdu->GetHeader ().GetAddr1 ();
728  NS_ASSERT (receiver == candidate.first->address);
729 
730  NS_ASSERT (mpdu->IsQueued ());
731  WifiMacQueueItem::QueueIteratorPair queueIt = mpdu->GetQueueIteratorPairs ().front ();
732  NS_ASSERT (queueIt.queue != nullptr);
733  Ptr<WifiMacQueueItem> item = *queueIt.it;
734  queueIt.it++;
735 
736  if (!mpdu->GetHeader ().IsRetry ())
737  {
738  // this MPDU must have been dequeued from the AC queue and we can try
739  // A-MSDU aggregation
740  item = m_heFem->GetMsduAggregator ()->GetNextAmsdu (mpdu, dlMuInfo.txParams, m_availableTime, queueIt);
741 
742  if (item == nullptr)
743  {
744  // A-MSDU aggregation failed or disabled
745  item = *mpdu->GetQueueIteratorPairs ().front ().it;
746  }
747  m_apMac->GetQosTxop (QosUtilsMapTidToAc (tid))->AssignSequenceNumber (item);
748  }
749 
750  // Now, let's try A-MPDU aggregation if possible
751  std::vector<Ptr<WifiMacQueueItem>> mpduList = m_heFem->GetMpduAggregator ()->GetNextAmpdu (item, dlMuInfo.txParams, m_availableTime, queueIt);
752 
753  if (mpduList.size () > 1)
754  {
755  // A-MPDU aggregation succeeded, update psduMap
756  dlMuInfo.psduMap[candidate.first->aid] = Create<WifiPsdu> (std::move (mpduList));
757  }
758  else
759  {
760  dlMuInfo.psduMap[candidate.first->aid] = Create<WifiPsdu> (item, true);
761  }
762  }
763 
764  AcIndex primaryAc = m_edca->GetAccessCategory ();
765 
766  // The amount of credits received by each station equals the TX duration (in
767  // microseconds) divided by the number of stations.
768  double creditsPerSta = dlMuInfo.txParams.m_txDuration.ToDouble (Time::US)
769  / m_staList[primaryAc].size ();
770  // Transmitting stations have to pay a number of credits equal to the TX duration
771  // (in microseconds) times the allocated bandwidth share.
772  double debitsPerMhz = dlMuInfo.txParams.m_txDuration.ToDouble (Time::US)
773  / (nRusAssigned * HeRu::GetBandwidth (ruType)
774  + nCentral26TonesRus * HeRu::GetBandwidth (HeRu::RU_26_TONE));
775 
776  // assign credits to all stations
777  for (auto& sta : m_staList[primaryAc])
778  {
779  sta.credits += creditsPerSta;
780  sta.credits = std::min (sta.credits, m_maxCredits.ToDouble (Time::US));
781  }
782 
783  // subtract debits to the selected stations
784  candidateIt = m_candidates.begin ();
785 
786  for (std::size_t i = 0; i < nRusAssigned + nCentral26TonesRus; i++)
787  {
788  NS_ASSERT (candidateIt != m_candidates.end ());
789 
790  candidateIt->first->credits -= debitsPerMhz * HeRu::GetBandwidth (i < nRusAssigned ? ruType : HeRu::RU_26_TONE);
791 
792  candidateIt++;
793  }
794 
795  // sort the list in decreasing order of credits
796  m_staList[primaryAc].sort ([] (const MasterInfo& a, const MasterInfo& b)
797  { return a.credits > b.credits; });
798 
799  NS_LOG_DEBUG ("Next station to serve has AID=" << m_staList[primaryAc].front ().aid);
800 
801  return dlMuInfo;
802 }
803 
804 void
805 RrMultiUserScheduler::AssignRuIndices (WifiTxVector& txVector)
806 {
807  NS_LOG_FUNCTION (this << txVector);
808 
809  uint8_t bw = txVector.GetChannelWidth ();
810 
811  // find the RU types allocated in the TXVECTOR
812  std::set<HeRu::RuType> ruTypeSet;
813  for (const auto& userInfo : txVector.GetHeMuUserInfoMap ())
814  {
815  ruTypeSet.insert (userInfo.second.ru.GetRuType ());
816  }
817 
818  std::vector<HeRu::RuSpec> ruSet, central26TonesRus;
819 
820  // This scheduler allocates equal sized RUs and optionally the remaining 26-tone RUs
821  if (ruTypeSet.size () == 2)
822  {
823  // central 26-tone RUs have been allocated
824  NS_ASSERT (ruTypeSet.find (HeRu::RU_26_TONE) != ruTypeSet.end ());
825  ruTypeSet.erase (HeRu::RU_26_TONE);
826  NS_ASSERT (ruTypeSet.size () == 1);
827  central26TonesRus = HeRu::GetCentral26TonesRus (bw, *ruTypeSet.begin ());
828  }
829 
830  NS_ASSERT (ruTypeSet.size () == 1);
831  ruSet = HeRu::GetRusOfType (bw, *ruTypeSet.begin ());
832 
833  auto ruSetIt = ruSet.begin ();
834  auto central26TonesRusIt = central26TonesRus.begin ();
835 
836  for (const auto& userInfo : txVector.GetHeMuUserInfoMap ())
837  {
838  if (userInfo.second.ru.GetRuType () == *ruTypeSet.begin ())
839  {
840  NS_ASSERT (ruSetIt != ruSet.end ());
841  txVector.SetRu (*ruSetIt, userInfo.first);
842  ruSetIt++;
843  }
844  else
845  {
846  NS_ASSERT (central26TonesRusIt != central26TonesRus.end ());
847  txVector.SetRu (*central26TonesRusIt, userInfo.first);
848  central26TonesRusIt++;
849  }
850  }
851 }
852 
854 RrMultiUserScheduler::ComputeUlMuInfo (void)
855 {
856  return UlMuInfo {m_trigger, m_tbPpduDuration, std::move (m_txParams)};
857 }
858 
859 } //namespace ns3
ns3::RrMultiUserScheduler::m_trigger
Ptr< WifiMacQueueItem > m_trigger
Trigger Frame to send.
Definition: rr-multi-user-scheduler.h:137
ns3::CtrlTriggerHeader::end
ConstIterator end(void) const
Get a const iterator indicating past-the-last User Info field in the list.
Definition: ctrl-headers.cc:2016
ns3::TypeId
a unique identifier for an interface.
Definition: type-id.h:59
NS_LOG_COMPONENT_DEFINE
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
ns3::MultiUserScheduler::DL_MU_TX
@ DL_MU_TX
Definition: multi-user-scheduler.h:66
ns3::MultiUserScheduler::UlMuInfo
Information to be provided in case of UL MU transmission.
Definition: multi-user-scheduler.h:79
ns3::MultiUserScheduler::m_edca
Ptr< QosTxop > m_edca
the AC that gained channel access
Definition: multi-user-scheduler.h:137
NS_OBJECT_ENSURE_REGISTERED
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
NS_ASSERT
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
ns3::WifiMacQueueItem::GetPacket
Ptr< const Packet > GetPacket(void) const
Get the packet stored in this item.
Definition: wifi-mac-queue-item.cc:57
ns3::RrMultiUserScheduler::TrySendingBsrpTf
virtual TxFormat TrySendingBsrpTf(void)
Check if it is possible to send a BSRP Trigger Frame given the current time limits.
Definition: rr-multi-user-scheduler.cc:167
ns3::MakeTimeChecker
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
ns3::BooleanValue
AttributeValue implementation for Boolean.
Definition: boolean.h:37
ns3::Packet::PeekHeader
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:290
ns3::MultiUserScheduler::GetDlMuInfo
DlMuInfo & GetDlMuInfo(void)
Get the information required to perform a DL MU transmission.
Definition: multi-user-scheduler.cc:161
ns3::RrMultiUserScheduler::AssignRuIndices
void AssignRuIndices(WifiTxVector &txVector)
Assign an RU index to all the RUs allocated by the given TXVECTOR.
Definition: rr-multi-user-scheduler.cc:805
ns3::RrMultiUserScheduler::m_enableTxopSharing
bool m_enableTxopSharing
allow A-MPDUs of different TIDs in a DL MU PPDU
Definition: rr-multi-user-scheduler.h:128
ns3::RrMultiUserScheduler::DoInitialize
void DoInitialize(void) override
Initialize() implementation.
Definition: rr-multi-user-scheduler.cc:105
min
#define min(a, b)
Definition: 80211b.c:42
ns3::Packet::AddHeader
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
ns3::WifiTxParameters::m_txDuration
Time m_txDuration
TX duration of the frame.
Definition: wifi-tx-parameters.h:65
ns3::RrMultiUserScheduler::TrySendingDlMuPpdu
virtual TxFormat TrySendingDlMuPpdu(void)
Check if it is possible to send a DL MU PPDU given the current time limits.
Definition: rr-multi-user-scheduler.cc:502
ns3::MultiUserScheduler
MultiUserScheduler is an abstract base class defining the API that APs supporting at least VHT can us...
Definition: multi-user-scheduler.h:51
ns3::Time::IsNegative
bool IsNegative(void) const
Exactly equivalent to t <= 0.
Definition: nstime.h:309
ns3
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::MultiUserScheduler::DlMuInfo::txParams
WifiTxParameters txParams
the transmission parameters
Definition: multi-user-scheduler.h:74
ns3::CtrlTriggerHeader::GetGuardInterval
uint16_t GetGuardInterval(void) const
Get the guard interval duration (in nanoseconds) of the solicited HE TB PPDU.
Definition: ctrl-headers.cc:1919
ns3::WifiPhy::CalculateTxDuration
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1610
ns3::MultiUserScheduler::DlMuInfo::psduMap
WifiPsduMap psduMap
the DL MU PPDU to transmit
Definition: multi-user-scheduler.h:73
ns3::WifiTxVector::SetGuardInterval
void SetGuardInterval(uint16_t guardInterval)
Sets the guard interval duration (in nanoseconds)
Definition: wifi-tx-vector.cc:259
ns3::MultiUserScheduler::DoDispose
void DoDispose(void) override
Destructor implementation.
Definition: multi-user-scheduler.cc:57
ns3::WifiMacHeader::SetDsNotFrom
void SetDsNotFrom(void)
Un-set the From DS bit in the Frame Control field.
Definition: wifi-mac-header.cc:90
ns3::MultiUserScheduler::m_initialFrame
bool m_initialFrame
true if a TXOP is being started
Definition: multi-user-scheduler.h:139
ns3::WifiMacQueueItem::QueueIteratorPair::queue
WifiMacQueue * queue
pointer to the queue where the MSDU is enqueued
Definition: wifi-mac-queue-item.h:148
ns3::RrMultiUserScheduler::m_ulTriggerType
TriggerFrameType m_ulTriggerType
Trigger Frame type for UL MU.
Definition: rr-multi-user-scheduler.h:140
ns3::TriggerFrameType
TriggerFrameType
The different Trigger frame types.
Definition: ctrl-headers.h:561
ns3::RrMultiUserScheduler
RrMultiUserScheduler is a simple OFDMA scheduler that indicates to perform a DL OFDMA transmission if...
Definition: rr-multi-user-scheduler.h:43
ns3::Mac48Address
an EUI-48 address
Definition: mac48-address.h:44
Min
#define Min(a, b)
Definition: aarf-wifi-manager.cc:25
ns3::QosTxop::PeekNextMpdu
Ptr< const WifiMacQueueItem > PeekNextMpdu(uint8_t tid=8, Mac48Address recipient=Mac48Address::GetBroadcast())
Peek the next frame to transmit to the given receiver and of the given TID from the block ack manager...
Definition: qos-txop.cc:353
ns3::RrMultiUserScheduler::m_forceDlOfdma
bool m_forceDlOfdma
return DL_OFDMA even if no DL MU PPDU was built
Definition: rr-multi-user-scheduler.h:129
ns3::WifiTxVector
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
Definition: wifi-tx-vector.h:71
ns3::RrMultiUserScheduler::m_nStations
uint8_t m_nStations
Number of stations/slots to fill.
Definition: rr-multi-user-scheduler.h:127
ns3::Time::As
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:429
ns3::MakeBooleanAccessor
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: boolean.h:85
ns3::Min
int64x64_t Min(const int64x64_t &a, const int64x64_t &b)
Minimum.
Definition: int64x64.h:218
he-phy.h
Declaration of ns3::HePhy class and ns3::HeSigAParameters struct.
ns3::RrMultiUserScheduler::MasterInfo::address
Mac48Address address
station's MAC Address
Definition: rr-multi-user-scheduler.h:118
ns3::TypeId::SetParent
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
ns3::MultiUserScheduler::SU_TX
@ SU_TX
Definition: multi-user-scheduler.h:65
ns3::WifiTxParameters::m_protection
std::unique_ptr< WifiProtection > m_protection
protection method
Definition: wifi-tx-parameters.h:63
ns3::RrMultiUserScheduler::SelectTxFormat
TxFormat SelectTxFormat(void) override
Select the format of the next transmission.
Definition: rr-multi-user-scheduler.cc:136
ns3::MultiUserScheduler::UlMuInfo::trigger
Ptr< WifiMacQueueItem > trigger
the Trigger frame used to solicit TB PPDUs
Definition: multi-user-scheduler.h:80
ns3::RrMultiUserScheduler::m_maxCredits
Time m_maxCredits
Max amount of credits a station can have.
Definition: rr-multi-user-scheduler.h:136
ns3::GetPpduMaxTime
Time GetPpduMaxTime(WifiPreamble preamble)
Get the maximum PPDU duration (see Section 10.14 of 802.11-2016) for the PHY layers defining the aPPD...
Definition: wifi-utils.cc:254
ns3::WifiMacHeader::SetAddr1
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
Definition: wifi-mac-header.cc:108
ns3::WifiMacQueueItem::QueueIteratorPair::it
ConstIterator it
iterator pointing to the MSDU in the queue
Definition: wifi-mac-queue-item.h:149
ns3::RrMultiUserScheduler::DoDispose
void DoDispose(void) override
Destructor implementation.
Definition: rr-multi-user-scheduler.cc:121
ns3::WifiMacHeader
Implements the IEEE 802.11 MAC header.
Definition: wifi-mac-header.h:85
ns3::Time::ToDouble
double ToDouble(enum Unit unit) const
Get the Time value expressed in a particular unit.
Definition: nstime.h:530
ns3::Ptr
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
ns3::Max
int64x64_t Max(const int64x64_t &a, const int64x64_t &b)
Maximum.
Definition: int64x64.h:230
ns3::HePhy::ConvertHeTbPpduDurationToLSigLength
static uint16_t ConvertHeTbPpduDurationToLSigLength(Time ppduDuration, WifiPhyBand band)
Definition: he-phy.cc:250
ns3::Mac48Address::GetBroadcast
static Mac48Address GetBroadcast(void)
Definition: mac48-address.cc:170
ns3::RrMultiUserScheduler::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: rr-multi-user-scheduler.cc:38
ns3::MultiUserScheduler::GetUlMuInfo
UlMuInfo & GetUlMuInfo(void)
Get the information required to solicit an UL MU transmission.
Definition: multi-user-scheduler.cc:178
ns3::RrMultiUserScheduler::m_enableBsrp
bool m_enableBsrp
send a BSRP before an UL MU transmission
Definition: rr-multi-user-scheduler.h:131
ns3::CtrlTriggerHeader::GetUlBandwidth
uint16_t GetUlBandwidth(void) const
Get the bandwidth of the solicited HE TB PPDU.
Definition: ctrl-headers.cc:1892
ns3::RrMultiUserScheduler::MasterInfo::aid
uint16_t aid
station's AID
Definition: rr-multi-user-scheduler.h:117
max
#define max(a, b)
Definition: 80211b.c:43
ns3::MultiUserScheduler::m_availableTime
Time m_availableTime
the time available for frame exchange
Definition: multi-user-scheduler.h:138
ns3::MultiUserScheduler::DlMuInfo
Information to be provided in case of DL MU transmission.
Definition: multi-user-scheduler.h:72
ns3::Time::IsZero
bool IsZero(void) const
Exactly equivalent to t == 0.
Definition: nstime.h:301
ns3::RrMultiUserScheduler::MasterInfo::credits
double credits
credits accumulated by the station
Definition: rr-multi-user-scheduler.h:119
ns3::CtrlTriggerHeader::begin
ConstIterator begin(void) const
Get a const iterator pointing to the first User Info field in the list.
Definition: ctrl-headers.cc:2010
ns3::QosUtilsMapTidToAc
AcIndex QosUtilsMapTidToAc(uint8_t tid)
Maps TID (Traffic ID) to Access classes.
Definition: qos-utils.cc:126
ns3::RrMultiUserScheduler::m_candidates
std::list< CandidateInfo > m_candidates
Candidate stations for MU TX.
Definition: rr-multi-user-scheduler.h:135
ns3::RrMultiUserScheduler::m_staList
std::map< AcIndex, std::list< MasterInfo > > m_staList
Per-AC list of stations (next to serve first)
Definition: rr-multi-user-scheduler.h:134
ns3::BSRP_TRIGGER
@ BSRP_TRIGGER
Definition: ctrl-headers.h:566
NS_UNUSED
#define NS_UNUSED(x)
Mark a local variable as unused.
Definition: unused.h:36
ns3::HeRu::RuType
RuType
The different HE Resource Unit (RU) types.
Definition: he-ru.h:42
ns3::MultiUserScheduler::m_heFem
Ptr< HeFrameExchangeManager > m_heFem
HE Frame Exchange Manager.
Definition: multi-user-scheduler.h:136
ns3::CtrlTriggerHeader
Headers for Trigger frames.
Definition: ctrl-headers.h:886
ns3::MultiUserScheduler::UL_MU_TX
@ UL_MU_TX
Definition: multi-user-scheduler.h:67
ns3::WifiTxVector::GetHeMuUserInfoMap
const HeMuUserInfoMap & GetHeMuUserInfoMap(void) const
Get a const reference to the map HE MU user-specific transmission information indexed by STA-ID.
Definition: wifi-tx-vector.cc:420
ns3::HeRu::GetEqualSizedRusForStations
static RuType GetEqualSizedRusForStations(uint16_t bandwidth, std::size_t &nStations, std::size_t &nCentral26TonesRus)
Given the channel bandwidth and the number of stations candidate for being assigned an RU,...
Definition: he-ru.cc:537
ns3::WIFI_MAC_CTL_TRIGGER
@ WIFI_MAC_CTL_TRIGGER
Definition: wifi-mac-header.h:38
ns3::WifiTxParameters::Clear
void Clear(void)
Reset the TX parameters.
Definition: wifi-tx-parameters.cc:67
ns3::MakeBooleanChecker
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
first.address
address
Definition: first.py:44
ns3::WIFI_PREAMBLE_HE_MU
@ WIFI_PREAMBLE_HE_MU
Definition: wifi-phy-common.h:71
ns3::WifiTxVector::GetPreambleType
WifiPreamble GetPreambleType(void) const
Definition: wifi-tx-vector.cc:147
ns3::Time
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
ns3::WifiTxVector::SetChannelWidth
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
Definition: wifi-tx-vector.cc:253
NS_ABORT_MSG_IF
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
ns3::MultiUserScheduler::m_apMac
Ptr< ApWifiMac > m_apMac
the AP wifi MAC
Definition: multi-user-scheduler.h:135
NS_ASSERT_MSG
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
ns3::CtrlTriggerHeader::GetNUserInfoFields
std::size_t GetNUserInfoFields(void) const
Get the number of User Info fields in this Trigger Frame.
Definition: ctrl-headers.cc:2034
ns3::WifiTxVector::GetChannelWidth
uint16_t GetChannelWidth(void) const
Definition: wifi-tx-vector.cc:153
ns3::RrMultiUserScheduler::TrySendingBasicTf
virtual TxFormat TrySendingBasicTf(void)
Check if it is possible to send a Basic Trigger Frame given the current time limits.
Definition: rr-multi-user-scheduler.cc:252
ns3::MultiUserScheduler::GetWifiRemoteStationManager
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager(void) const
Get the station manager attached to the AP.
Definition: multi-user-scheduler.cc:121
ns3::WifiTxParameters::m_acknowledgment
std::unique_ptr< WifiAcknowledgment > m_acknowledgment
acknowledgment method
Definition: wifi-tx-parameters.h:64
ns3::WifiMacQueueItem::QueueIteratorPair
Information needed to remove an MSDU from the queue.
Definition: wifi-mac-queue-item.h:147
ns3::MakeCallback
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
ns3::wifiAcList
const std::map< AcIndex, WifiAc > wifiAcList
Map containing the four ACs in increasing order of priority (according to Table 10-1 "UP-to-AC Mappin...
Definition: qos-utils.cc:120
ns3::WifiRemoteStationManager::GetDataTxVector
WifiTxVector GetDataTxVector(const WifiMacHeader &header)
Definition: wifi-remote-station-manager.cc:535
ns3::WifiMacHeader::SetAddr2
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
Definition: wifi-mac-header.cc:114
NS_LOG_FUNCTION_NOARGS
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log-macros-enabled.h:209
ns3::Time::Min
static Time Min()
Minimum representable Time Not to be confused with Min(Time,Time).
Definition: nstime.h:274
he-frame-exchange-manager.h
ns3::WifiTxVector::GetNss
uint8_t GetNss(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the number of spatial streams.
Definition: wifi-tx-vector.cc:171
ns3::RrMultiUserScheduler::RrMultiUserScheduler
RrMultiUserScheduler()
Definition: rr-multi-user-scheduler.cc:93
NS_LOG_DEBUG
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
ns3::WifiTxParameters::m_txVector
WifiTxVector m_txVector
TXVECTOR of the frame being prepared.
Definition: wifi-tx-parameters.h:62
ns3::HeRu::RU_26_TONE
@ RU_26_TONE
Definition: he-ru.h:43
ns3::Seconds
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
ns3::RrMultiUserScheduler::m_tbPpduDuration
Time m_tbPpduDuration
Duration of the solicited TB PPDUs.
Definition: rr-multi-user-scheduler.h:138
ns3::WifiTxVector::SetHeMuUserInfo
void SetHeMuUserInfo(uint16_t staId, HeMuUserInfo userInfo)
Set the HE MU user-specific transmission information for the given STA-ID.
Definition: wifi-tx-vector.cc:410
ns3::BASIC_TRIGGER
@ BASIC_TRIGGER
Definition: ctrl-headers.h:562
ns3::RrMultiUserScheduler::m_enableUlOfdma
bool m_enableUlOfdma
enable the scheduler to also return UL_OFDMA
Definition: rr-multi-user-scheduler.h:130
ns3::TimeValue
AttributeValue implementation for Time.
Definition: nstime.h:1353
ns3::AcIndex
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition: qos-utils.h:71
NS_LOG_FUNCTION
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Definition: log-macros-enabled.h:244
ns3::MultiUserScheduler::NO_TX
@ NO_TX
Definition: multi-user-scheduler.h:64
ns3::MultiUserScheduler::GetLastTxFormat
TxFormat GetLastTxFormat(void) const
Get the format of the last transmission, as determined by the last call to NotifyAccessGranted that d...
Definition: multi-user-scheduler.cc:155
ns3::MultiUserScheduler::m_sizeOf8QosNull
uint32_t m_sizeOf8QosNull
size in bytes of 8 QoS Null frames
Definition: multi-user-scheduler.h:140
ns3::RrMultiUserScheduler::m_ulPsduSize
uint32_t m_ulPsduSize
the size in byte of the solicited PSDU
Definition: rr-multi-user-scheduler.h:133
ns3::UintegerValue
Hold an unsigned integer type.
Definition: uinteger.h:44
ns3::WifiTxVector::SetRu
void SetRu(HeRu::RuSpec ru, uint16_t staId)
Set the RU specification for the STA-ID.
Definition: wifi-tx-vector.cc:395
ns3::RrMultiUserScheduler::m_txParams
WifiTxParameters m_txParams
TX parameters.
Definition: rr-multi-user-scheduler.h:139
ns3::RrMultiUserScheduler::~RrMultiUserScheduler
virtual ~RrMultiUserScheduler()
Definition: rr-multi-user-scheduler.cc:99
he-configuration.h
ns3::WifiMacHeader::SetDsNotTo
void SetDsNotTo(void)
Un-set the To DS bit in the Frame Control field.
Definition: wifi-mac-header.cc:102
ns3::MultiUserScheduler::TxFormat
TxFormat
Enumeration of the possible transmission formats.
Definition: multi-user-scheduler.h:63
ns3::RrMultiUserScheduler::m_useCentral26TonesRus
bool m_useCentral26TonesRus
whether to allocate central 26-tone RUs
Definition: rr-multi-user-scheduler.h:132
ns3::WifiTxVector::SetBssColor
void SetBssColor(uint8_t color)
Set the BSS color.
Definition: wifi-tx-vector.cc:309
ns3::MakeUintegerAccessor
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: uinteger.h:45
ns3::MultiUserScheduler::DoInitialize
void DoInitialize(void) override
Initialize() implementation.
Definition: multi-user-scheduler.cc:88
ns3::RrMultiUserScheduler::NotifyStationDeassociated
void NotifyStationDeassociated(uint16_t aid, Mac48Address address)
Notify the scheduler that a station deassociated with the AP.
Definition: rr-multi-user-scheduler.cc:487
ns3::QosTxop::GetAccessCategory
AcIndex GetAccessCategory(void) const override
Get the access category.
Definition: qos-txop.cc:779
ns3::RrMultiUserScheduler::MasterInfo
Information used to sort stations.
Definition: rr-multi-user-scheduler.h:116
ns3::WIFI_PREAMBLE_HE_TB
@ WIFI_PREAMBLE_HE_TB
Definition: wifi-phy-common.h:72
ns3::RrMultiUserScheduler::NotifyStationAssociated
void NotifyStationAssociated(uint16_t aid, Mac48Address address)
Notify the scheduler that a station associated with the AP.
Definition: rr-multi-user-scheduler.cc:473
ns3::CtrlTriggerHeader::FindUserInfoWithAid
ConstIterator FindUserInfoWithAid(ConstIterator start, uint16_t aid12) const
Get a const iterator pointing to the first User Info field found (starting from the one pointed to by...
Definition: ctrl-headers.cc:2040
ns3::WifiTxVector::SetPreambleType
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
Definition: wifi-tx-vector.cc:247
ns3::Time::MS
@ MS
millisecond
Definition: nstime.h:116
ns3::WifiTxVector::GetMode
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode.
Definition: wifi-tx-vector.cc:111
ns3::MakeTimeAccessor
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: nstime.h:1354
ns3::empty
make Callback use a separate empty type
Definition: empty.h:34
ns3::HePhy::GetHeMcs
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
Definition: he-phy.cc:957
rr-multi-user-scheduler.h