A Discrete-Event Network Simulator
API
mu-edca-parameter-set.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2021 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
22#include <cmath>
23#include <algorithm>
24
25namespace ns3 {
26
28 : m_qosInfo (0),
29 m_records {{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}
30{
31}
32
34MuEdcaParameterSet::ElementId () const
35{
36 return IE_EXTENSION;
37}
38
40MuEdcaParameterSet::ElementIdExt () const
41{
43}
44
45bool
46MuEdcaParameterSet::IsPresent (void) const
47{
48 auto timerNotNull = [](const ParameterRecord &r) { return r.muEdcaTimer != 0; };
49
50 bool isPresent = std::all_of (m_records.begin (), m_records.end (), timerNotNull);
51 if (isPresent)
52 {
53 return true;
54 }
55 NS_ABORT_MSG_IF (std::any_of (m_records.begin (), m_records.end (), timerNotNull),
56 "MU EDCA Timers must be either all zero or all non-zero.");
57 return false;
58}
59
60void
61MuEdcaParameterSet::SetQosInfo (uint8_t qosInfo)
62{
63 m_qosInfo = qosInfo;
64}
65
66void
67MuEdcaParameterSet::SetMuAifsn (uint8_t aci, uint8_t aifsn)
68{
69 NS_ABORT_MSG_IF (aci > 3, "Invalid AC Index value: " << +aci);
70 NS_ABORT_MSG_IF (aifsn == 1 || aifsn > 15, "Invalid AIFSN value: " << +aifsn);
71
72 m_records[aci].aifsnField |= (aifsn & 0x0f);
73 m_records[aci].aifsnField |= (aci & 0x03) << 5;
74}
75
76void
77MuEdcaParameterSet::SetMuCwMin (uint8_t aci, uint16_t cwMin)
78{
79 NS_ABORT_MSG_IF (aci > 3, "Invalid AC Index value: " << +aci);
80 NS_ABORT_MSG_IF (cwMin > 32767, "CWmin exceeds the maximum value");
81
82 auto eCwMin = std::log2 (cwMin + 1);
83 NS_ABORT_MSG_IF (std::trunc (eCwMin) != eCwMin, "CWmin is not a power of 2 minus 1");
84
85 m_records[aci].cwMinMax |= (static_cast<uint8_t> (eCwMin) & 0x0f);
86}
87
88void
89MuEdcaParameterSet::SetMuCwMax (uint8_t aci, uint16_t cwMax)
90{
91 NS_ABORT_MSG_IF (aci > 3, "Invalid AC Index value: " << +aci);
92 NS_ABORT_MSG_IF (cwMax > 32767, "CWmin exceeds the maximum value");
93
94 auto eCwMax = std::log2 (cwMax + 1);
95 NS_ABORT_MSG_IF (std::trunc (eCwMax) != eCwMax, "CWmax is not a power of 2 minus 1");
96
97 m_records[aci].cwMinMax |= (static_cast<uint8_t> (eCwMax) & 0x0f) << 4;
98}
99
100void
101MuEdcaParameterSet::SetMuEdcaTimer (uint8_t aci, Time timer)
102{
103 NS_ABORT_MSG_IF (aci > 3, "Invalid AC Index value: " << +aci);
104 NS_ABORT_MSG_IF (timer.IsStrictlyPositive () && timer < MicroSeconds (8192),
105 "Timer value is below 8.192 ms");
106 NS_ABORT_MSG_IF (timer > MicroSeconds (2088960), "Timer value is above 2088.96 ms");
107
108 double value = timer.GetMicroSeconds () / 8192.;
109 NS_ABORT_MSG_IF (std::trunc (value) != value, "Timer value is not a multiple of 8 TUs (8192 us)");
110
111 m_records[aci].muEdcaTimer = static_cast<uint8_t> (value);
112}
113
114uint8_t
115MuEdcaParameterSet::GetQosInfo (void) const
116{
117 return m_qosInfo;
118}
119
120uint8_t
121MuEdcaParameterSet::GetMuAifsn (uint8_t aci) const
122{
123 NS_ABORT_MSG_IF (aci > 3, "Invalid AC Index value: " << +aci);
124 return (m_records[aci].aifsnField & 0x0f);
125}
126
127uint16_t
128MuEdcaParameterSet::GetMuCwMin (uint8_t aci) const
129{
130 NS_ABORT_MSG_IF (aci > 3, "Invalid AC Index value: " << +aci);
131 uint8_t eCwMin = (m_records[aci].cwMinMax & 0x0f);
132 return static_cast<uint16_t> (std::exp2 (eCwMin) - 1);
133}
134
135uint16_t
136MuEdcaParameterSet::GetMuCwMax (uint8_t aci) const
137{
138 NS_ABORT_MSG_IF (aci > 3, "Invalid AC Index value: " << +aci);
139 uint8_t eCwMax = ((m_records[aci].cwMinMax >> 4) & 0x0f);
140 return static_cast<uint16_t> (std::exp2 (eCwMax) - 1);
141}
142
143Time
144MuEdcaParameterSet::GetMuEdcaTimer (uint8_t aci) const
145{
146 NS_ABORT_MSG_IF (aci > 3, "Invalid AC Index value: " << +aci);
147 return MicroSeconds (m_records[aci].muEdcaTimer * 8192);
148}
149
150uint8_t
151MuEdcaParameterSet::GetInformationFieldSize () const
152{
153 NS_ASSERT (IsPresent ());
154 // ElementIdExt (1) + QoS Info (1) + MU Parameter Records (4 * 3)
155 return 14;
156}
157
159MuEdcaParameterSet::Serialize (Buffer::Iterator i) const
160{
161 if (!IsPresent ())
162 {
163 return i;
164 }
165 return WifiInformationElement::Serialize (i);
166}
167
168uint16_t
169MuEdcaParameterSet::GetSerializedSize () const
170{
171 if (!IsPresent ())
172 {
173 return 0;
174 }
175 return WifiInformationElement::GetSerializedSize ();
176}
177
178void
179MuEdcaParameterSet::SerializeInformationField (Buffer::Iterator start) const
180{
181 if (IsPresent ())
182 {
183 start.WriteU8 (GetQosInfo ());
184 for (const auto& record : m_records)
185 {
186 start.WriteU8 (record.aifsnField);
187 start.WriteU8 (record.cwMinMax);
188 start.WriteU8 (record.muEdcaTimer);
189 }
190 }
191}
192
193uint8_t
194MuEdcaParameterSet::DeserializeInformationField (Buffer::Iterator start, uint8_t length)
195{
197 m_qosInfo = i.ReadU8 ();
198 for (auto& record : m_records)
199 {
200 record.aifsnField = i.ReadU8 ();
201 record.cwMinMax = i.ReadU8 ();
202 record.muEdcaTimer = i.ReadU8 ();
203 }
204 return 13;
205}
206
207} //namespace ns3
iterator in a Buffer instance
Definition: buffer.h:99
uint8_t ReadU8(void)
Definition: buffer.h:1021
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
int64_t GetMicroSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:388
bool IsStrictlyPositive(void) const
Exactly equivalent to t > 0.
Definition: nstime.h:333
#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
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1261
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint8_t WifiInformationElementId
This type is used to represent an Information Element ID.
def start()
Definition: core.py:1852
#define IE_EXTENSION
#define IE_EXT_MU_EDCA_PARAMETER_SET