A Discrete-Event Network Simulator
QKDNetSim v2.0 (NS-3 v3.41) @ (+)
API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
multi-user-scheduler.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Universita' degli Studi di Napoli Federico II
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Stefano Avallone <stavallo@unina.it>
18  */
19 
20 #include "multi-user-scheduler.h"
21 
22 #include "he-configuration.h"
24 
25 #include "ns3/abort.h"
26 #include "ns3/log.h"
27 #include "ns3/qos-txop.h"
28 #include "ns3/wifi-acknowledgment.h"
29 #include "ns3/wifi-mac-trailer.h"
30 #include "ns3/wifi-protection.h"
31 
32 namespace ns3
33 {
34 
35 NS_LOG_COMPONENT_DEFINE("MultiUserScheduler");
36 
37 NS_OBJECT_ENSURE_REGISTERED(MultiUserScheduler);
38 
39 TypeId
41 {
42  static TypeId tid =
43  TypeId("ns3::MultiUserScheduler")
44  .SetParent<Object>()
45  .SetGroupName("Wifi")
46  .AddAttribute("AccessReqInterval",
47  "Duration of the interval between two consecutive requests for "
48  "channel access made by the MultiUserScheduler. Such requests are "
49  "made independently of the presence of frames in the queues of the "
50  "AP and are intended to allow the AP to coordinate UL MU transmissions "
51  "even without DL traffic. A null duration indicates that such "
52  "requests shall not be made.",
53  TimeValue(Seconds(0)),
56  .AddAttribute("AccessReqAc",
57  "The Access Category for which the MultiUserScheduler makes requests "
58  "for channel access.",
60  MakeEnumAccessor<AcIndex>(&MultiUserScheduler::m_accessReqAc),
62  "AC_BE",
64  "AC_VI",
66  "AC_VO",
68  "AC_BK"))
69  .AddAttribute("DelayAccessReqUponAccess",
70  "If enabled, the access request interval is measured starting "
71  "from the last time an EDCA function obtained channel access. "
72  "Otherwise, the access request interval is measured starting "
73  "from the last time the MultiUserScheduler made a request for "
74  "channel access.",
75  BooleanValue(true),
78  return tid;
79 }
80 
82 {
83 }
84 
86 {
88 }
89 
90 void
92 {
93  NS_LOG_FUNCTION(this);
94  m_apMac = nullptr;
95  m_edca = nullptr;
96  m_lastTxInfo.clear();
99 }
100 
101 void
103 {
104  NS_LOG_FUNCTION(this);
105  if (!m_apMac)
106  {
107  Ptr<ApWifiMac> apMac = this->GetObject<ApWifiMac>();
108  // verify that it's a valid AP mac and that
109  // the AP mac was not set before
110  if (apMac)
111  {
112  this->SetWifiMac(apMac);
113  }
114  }
116 }
117 
118 void
120 {
121  NS_LOG_FUNCTION(this);
122 
124  {
127  }
128 }
129 
130 void
132 {
133  NS_LOG_FUNCTION(this << interval.As(Time::MS));
134  m_accessReqInterval = interval;
135  // start the timer if past initialization
137  {
140  }
141 }
142 
143 void
145 {
146  NS_LOG_FUNCTION(this << mac);
147  m_apMac = mac;
148 
149  // When VHT DL MU-MIMO will be supported, we will have to lower this requirement
150  // and allow a Multi-user scheduler to be installed on a VHT AP.
152  "MultiUserScheduler can only be installed on HE APs");
153 
154  for (uint8_t linkId = 0; linkId < m_apMac->GetNLinks(); linkId++)
155  {
156  auto heFem = DynamicCast<HeFrameExchangeManager>(m_apMac->GetFrameExchangeManager(linkId));
157  NS_ASSERT(heFem);
158  heFem->SetMultiUserScheduler(this);
159  }
160 }
161 
164 {
165  return m_apMac->GetWifiRemoteStationManager(linkId);
166 }
167 
169 MultiUserScheduler::GetHeFem(uint8_t linkId) const
170 {
171  return StaticCast<HeFrameExchangeManager>(m_apMac->GetFrameExchangeManager(linkId));
172 }
173 
174 void
176 {
177  NS_LOG_FUNCTION(this);
178 
179  // request channel access if not requested yet
180  auto edca = m_apMac->GetQosTxop(m_accessReqAc);
181 
182  for (uint8_t linkId = 0; linkId < m_apMac->GetNLinks(); linkId++)
183  {
184  if (edca->GetAccessStatus(linkId) == Txop::NOT_REQUESTED)
185  {
187  }
188  }
189 
190  // restart timer
192  {
195  }
196 }
197 
200  Time availableTime,
201  bool initialFrame,
202  uint16_t allowedWidth,
203  uint8_t linkId)
204 {
205  NS_LOG_FUNCTION(this << edca << availableTime << initialFrame << allowedWidth << linkId);
206 
207  m_edca = edca;
208  m_availableTime = availableTime;
209  m_initialFrame = initialFrame;
210  m_allowedWidth = allowedWidth;
211  m_linkId = linkId;
212 
214  {
215  // restart access timer
218  {
221  this);
222  }
223  }
224 
225  TxFormat txFormat = SelectTxFormat();
226 
227  if (txFormat == DL_MU_TX)
228  {
229  m_lastTxInfo[linkId].dlInfo = ComputeDlMuInfo();
230  }
231  else if (txFormat == UL_MU_TX)
232  {
233  m_lastTxInfo[linkId].ulInfo = ComputeUlMuInfo();
235  }
236 
237  if (txFormat != NO_TX)
238  {
239  m_lastTxInfo[linkId].lastTxFormat = txFormat;
240  }
241  return txFormat;
242 }
243 
246 {
247  return m_lastTxInfo[linkId].lastTxFormat;
248 }
249 
252 {
253  NS_ABORT_MSG_IF(m_lastTxInfo[linkId].lastTxFormat != DL_MU_TX,
254  "Next transmission is not DL MU");
255 
256 #ifdef NS3_BUILD_PROFILE_DEBUG
257  // check that all the addressed stations support HE
258  for (auto& psdu : m_lastTxInfo[linkId].dlInfo.psduMap)
259  {
260  auto receiver = psdu.second->GetAddr1();
261  auto linkId = m_apMac->IsAssociated(receiver);
262  NS_ABORT_MSG_IF(!linkId, "Station " << receiver << " should be associated");
263  NS_ABORT_MSG_IF(!GetWifiRemoteStationManager(*linkId)->GetHeSupported(receiver),
264  "Station " << psdu.second->GetAddr1() << " does not support HE");
265  }
266 #endif
267 
268  return m_lastTxInfo[linkId].dlInfo;
269 }
270 
273 {
274  NS_ABORT_MSG_IF(m_lastTxInfo[linkId].lastTxFormat != UL_MU_TX,
275  "Next transmission is not UL MU");
276 
277  return m_lastTxInfo[linkId].ulInfo;
278 }
279 
281 MultiUserScheduler::GetTriggerFrame(const CtrlTriggerHeader& trigger, uint8_t linkId) const
282 {
283  NS_LOG_FUNCTION(this << linkId);
284 
285  Ptr<Packet> packet = Create<Packet>();
286  packet->AddHeader(trigger);
287 
289  if (trigger.GetNUserInfoFields() == 1)
290  {
291  auto aid = trigger.begin()->GetAid12();
292  auto aidAddrMapIt = m_apMac->GetStaList(linkId).find(aid);
293  NS_ASSERT(aidAddrMapIt != m_apMac->GetStaList(linkId).end());
294  receiver = aidAddrMapIt->second;
295  }
296 
298  hdr.SetAddr1(receiver);
299  hdr.SetAddr2(GetHeFem(linkId)->GetAddress());
300  hdr.SetDsNotTo();
301  hdr.SetDsNotFrom();
302 
303  return Create<WifiMpdu>(packet, hdr);
304 }
305 
306 void
308 {
309  NS_LOG_FUNCTION(this);
310 
311  // Set the CS Required subfield to true, unless the UL Length subfield is less
312  // than or equal to 76 (see Section 26.5.2.5 of 802.11ax-2021)
313  m_lastTxInfo[m_linkId].ulInfo.trigger.SetCsRequired(
314  m_lastTxInfo[m_linkId].ulInfo.trigger.GetUlLength() > 76);
315 
316  GetHeFem(m_linkId)->SetTargetRssi(m_lastTxInfo[m_linkId].ulInfo.trigger);
317 }
318 
319 uint32_t
321 {
322  // find the maximum number of TIDs for which a BlockAck agreement has been established
323  // with an STA, among all the STAs solicited by the given Trigger Frame
324  uint8_t maxNTids = 0;
325  for (const auto& userInfo : trigger)
326  {
327  auto address = m_apMac->GetMldOrLinkAddressByAid(userInfo.GetAid12());
328  NS_ASSERT_MSG(address, "AID " << userInfo.GetAid12() << " not found");
329 
330  uint8_t staNTids = 0;
331  for (uint8_t tid = 0; tid < 8; tid++)
332  {
334  {
335  staNTids++;
336  }
337  }
338  maxNTids = std::max(maxNTids, staNTids);
339  }
340 
341  // compute the size in bytes of maxNTids QoS Null frames
343  header.SetDsTo();
344  header.SetDsNotFrom();
345  uint32_t headerSize = header.GetSerializedSize();
346  uint32_t maxSize = 0;
347 
348  for (uint8_t i = 0; i < maxNTids; i++)
349  {
350  maxSize = MpduAggregator::GetSizeIfAggregated(headerSize + WIFI_MAC_FCS_LENGTH, maxSize);
351  }
352 
353  return maxSize;
354 }
355 
356 } // namespace ns3
#define max(a, b)
Definition: 80211b.c:42
const std::map< uint16_t, Mac48Address > & GetStaList(uint8_t linkId) const
Get a const reference to the map of associated stations on the given link.
std::optional< Mac48Address > GetMldOrLinkAddressByAid(uint16_t aid) const
std::optional< uint8_t > IsAssociated(const Mac48Address &address) const
Get the ID of a link (if any) that has been setup with the station having the given MAC address.
void RequestAccess(Ptr< Txop > txop)
Headers for Trigger frames.
Definition: ctrl-headers.h:942
ConstIterator begin() const
Get a const iterator pointing to the first User Info field in the list.
std::size_t GetNUserInfoFields() const
Get the number of User Info fields in this Trigger Frame.
Hold variables of type enum.
Definition: enum.h:62
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
bool IsRunning() const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:76
an EUI-48 address
Definition: mac48-address.h:46
static Mac48Address GetBroadcast()
static uint32_t GetSizeIfAggregated(uint32_t mpduSize, uint32_t ampduSize)
Compute the size of the A-MPDU resulting from the aggregation of an MPDU of size mpduSize and an A-MP...
bool m_initialFrame
true if a TXOP is being started
void NotifyNewAggregate() override
Notify all Objects aggregated to this one of a new Object being aggregated.
void DoInitialize() override
Initialize() implementation.
void AccessReqTimeout()
Perform actions required on expiration of the channel access request timer, such as requesting channe...
TxFormat GetLastTxFormat(uint8_t linkId)
Get the format of the last transmission on the given link, as determined by the last call to NotifyAc...
Ptr< ApWifiMac > m_apMac
the AP wifi MAC
void CheckTriggerFrame()
Ensure that the Trigger Frame returned in case of UL MU transmission is correct.
static TypeId GetTypeId()
Get the type ID.
uint16_t m_allowedWidth
the allowed width in MHz for the current transmission
Time m_availableTime
the time available for frame exchange
EventId m_accessReqTimer
the timer controlling additional channel access requests
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager(uint8_t linkId) const
Get the station manager attached to the AP on the given link.
UlMuInfo & GetUlMuInfo(uint8_t linkId)
Get the information required to solicit an UL MU transmission on the given link.
uint8_t m_linkId
the ID of the link over which channel access has been granted
virtual TxFormat SelectTxFormat()=0
Select the format of the next transmission.
void SetAccessReqInterval(Time interval)
Set the duration of the interval between two consecutive requests for channel access made by the Mult...
TxFormat NotifyAccessGranted(Ptr< QosTxop > edca, Time availableTime, bool initialFrame, uint16_t allowedWidth, uint8_t linkId)
Notify the Multi-user Scheduler that the given AC of the AP gained channel access.
uint32_t GetMaxSizeOfQosNullAmpdu(const CtrlTriggerHeader &trigger) const
Get the maximum size in bytes among the A-MPDUs containing QoS Null frames and solicited by the given...
bool m_restartTimerUponAccess
whether the channel access timer has to be restarted upon channel access
virtual DlMuInfo ComputeDlMuInfo()=0
Compute the information required to perform a DL MU transmission.
Ptr< QosTxop > m_edca
the AC that gained channel access
virtual UlMuInfo ComputeUlMuInfo()=0
Prepare the information required to solicit an UL MU transmission.
void DoDispose() override
Destructor implementation.
Ptr< WifiMpdu > GetTriggerFrame(const CtrlTriggerHeader &trigger, uint8_t linkId) const
Get an MPDU containing the given Trigger Frame.
AcIndex m_accessReqAc
AC we request channel access for.
DlMuInfo & GetDlMuInfo(uint8_t linkId)
Get the information required to perform a DL MU transmission on the given link.
Ptr< HeFrameExchangeManager > GetHeFem(uint8_t linkId) const
Get the HE Frame Exchange Manager attached to the AP on the given link.
Time m_accessReqInterval
duration of the interval between channel access requests
void SetWifiMac(Ptr< ApWifiMac > mac)
Set the wifi MAC.
TxFormat
Enumeration of the possible transmission formats.
std::map< uint8_t, LastTxInfo > m_lastTxInfo
Information about the last transmission.
A base class which provides memory management and object aggregation.
Definition: object.h:89
virtual void NotifyNewAggregate()
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition: object.cc:331
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:352
bool IsInitialized() const
Check if the object has been initialized.
Definition: object.cc:212
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
bool IsStrictlyPositive() const
Exactly equivalent to t > 0.
Definition: nstime.h:351
@ MS
millisecond
Definition: nstime.h:117
@ NOT_REQUESTED
Definition: txop.h:103
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
Implements the IEEE 802.11 MAC header.
uint32_t GetSerializedSize() const override
void SetDsNotFrom()
Un-set the From DS bit in the Frame Control field.
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
void SetDsTo()
Set the To DS bit in the Frame Control field.
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
void SetDsNotTo()
Un-set the To DS bit in the Frame Control field.
Ptr< FrameExchangeManager > GetFrameExchangeManager(uint8_t linkId=SINGLE_LINK_OP_ID) const
Get the Frame Exchange Manager associated with the given link.
Definition: wifi-mac.cc:864
Ptr< HeConfiguration > GetHeConfiguration() const
Definition: wifi-mac.cc:1749
uint8_t GetNLinks() const
Get the number of links (can be greater than 1 for 11be devices only).
Definition: wifi-mac.cc:933
RecipientAgreementOptConstRef GetBaAgreementEstablishedAsRecipient(Mac48Address originator, uint8_t tid) const
Definition: wifi-mac.cc:1693
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager(uint8_t linkId=0) const
Definition: wifi-mac.cc:906
Ptr< QosTxop > GetQosTxop(AcIndex ac) const
Accessor for a specified EDCA object.
Definition: wifi-mac.cc:499
Ptr< ChannelAccessManager > GetChannelAccessManager(uint8_t linkId=SINGLE_LINK_OP_ID) const
Get the Channel Access Manager associated with the given link.
Definition: wifi-mac.cc:870
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#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:86
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
@ AC_BE
Best Effort.
Definition: qos-utils.h:75
@ AC_VO
Voice.
Definition: qos-utils.h:81
@ AC_VI
Video.
Definition: qos-utils.h:79
@ AC_BK
Background.
Definition: qos-utils.h:77
address
Definition: first.py:47
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1414
static const uint16_t WIFI_MAC_FCS_LENGTH
The length in octets of the IEEE 802.11 MAC FCS field.
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:194
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
@ WIFI_MAC_CTL_TRIGGER
@ WIFI_MAC_QOSDATA_NULL
mac
Definition: third.py:92
Information to be provided in case of DL MU transmission.
Information to be provided in case of UL MU transmission.