A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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
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
32namespace ns3
33{
34
35NS_LOG_COMPONENT_DEFINE("MultiUserScheduler");
36
37NS_OBJECT_ENSURE_REGISTERED(MultiUserScheduler);
38
39TypeId
41{
42 static TypeId tid =
43 TypeId("ns3::MultiUserScheduler")
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.",
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
90void
92{
93 NS_LOG_FUNCTION(this);
94 m_apMac = nullptr;
95 m_edca = nullptr;
96 m_lastTxInfo.clear();
99}
100
101void
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
118void
120{
121 NS_LOG_FUNCTION(this);
122
124 {
127 }
128}
129
130void
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
143void
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
169MultiUserScheduler::GetHeFem(uint8_t linkId) const
170{
171 return StaticCast<HeFrameExchangeManager>(m_apMac->GetFrameExchangeManager(linkId));
172}
173
174void
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
281MultiUserScheduler::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
306void
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
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
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.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
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:423
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:444
bool IsInitialized() const
Check if the object has been initialized.
Definition: object.cc:251
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
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
AttributeValue implementation for Time.
Definition: nstime.h:1406
@ NOT_REQUESTED
Definition: txop.h:110
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
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:878
Ptr< HeConfiguration > GetHeConfiguration() const
Definition: wifi-mac.cc:1780
uint8_t GetNLinks() const
Get the number of links (can be greater than 1 for 11be devices only).
Definition: wifi-mac.cc:947
RecipientAgreementOptConstRef GetBaAgreementEstablishedAsRecipient(Mac48Address originator, uint8_t tid) const
Definition: wifi-mac.cc:1724
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager(uint8_t linkId=0) const
Definition: wifi-mac.cc:920
Ptr< QosTxop > GetQosTxop(AcIndex ac) const
Accessor for a specified EDCA object.
Definition: wifi-mac.cc:513
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:884
#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
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:81
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1427
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1407
#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:1319
@ 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
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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:189
@ WIFI_MAC_CTL_TRIGGER
@ WIFI_MAC_QOSDATA_NULL
Information to be provided in case of DL MU transmission.
Information to be provided in case of UL MU transmission.