A Discrete-Event Network Simulator
API
mu-edca-parameter-set.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021 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 "mu-edca-parameter-set.h"
21 
22 #include <algorithm>
23 #include <cmath>
24 
25 namespace ns3
26 {
27 
29  : m_qosInfo(0),
30  m_records{{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}
31 {
32 }
33 
35 MuEdcaParameterSet::ElementId() const
36 {
37  return IE_EXTENSION;
38 }
39 
41 MuEdcaParameterSet::ElementIdExt() const
42 {
44 }
45 
46 void
47 MuEdcaParameterSet::SetQosInfo(uint8_t qosInfo)
48 {
49  m_qosInfo = qosInfo;
50 }
51 
52 void
53 MuEdcaParameterSet::SetMuAifsn(uint8_t aci, uint8_t aifsn)
54 {
55  NS_ABORT_MSG_IF(aci > 3, "Invalid AC Index value: " << +aci);
56  NS_ABORT_MSG_IF(aifsn == 1 || aifsn > 15, "Invalid AIFSN value: " << +aifsn);
57 
58  m_records[aci].aifsnField |= (aifsn & 0x0f);
59  m_records[aci].aifsnField |= (aci & 0x03) << 5;
60 }
61 
62 void
63 MuEdcaParameterSet::SetMuCwMin(uint8_t aci, uint16_t cwMin)
64 {
65  NS_ABORT_MSG_IF(aci > 3, "Invalid AC Index value: " << +aci);
66  NS_ABORT_MSG_IF(cwMin > 32767, "CWmin exceeds the maximum value");
67 
68  auto eCwMin = std::log2(cwMin + 1);
69  NS_ABORT_MSG_IF(std::trunc(eCwMin) != eCwMin, "CWmin is not a power of 2 minus 1");
70 
71  m_records[aci].cwMinMax |= (static_cast<uint8_t>(eCwMin) & 0x0f);
72 }
73 
74 void
75 MuEdcaParameterSet::SetMuCwMax(uint8_t aci, uint16_t cwMax)
76 {
77  NS_ABORT_MSG_IF(aci > 3, "Invalid AC Index value: " << +aci);
78  NS_ABORT_MSG_IF(cwMax > 32767, "CWmin exceeds the maximum value");
79 
80  auto eCwMax = std::log2(cwMax + 1);
81  NS_ABORT_MSG_IF(std::trunc(eCwMax) != eCwMax, "CWmax is not a power of 2 minus 1");
82 
83  m_records[aci].cwMinMax |= (static_cast<uint8_t>(eCwMax) & 0x0f) << 4;
84 }
85 
86 void
87 MuEdcaParameterSet::SetMuEdcaTimer(uint8_t aci, Time timer)
88 {
89  NS_ABORT_MSG_IF(aci > 3, "Invalid AC Index value: " << +aci);
90  NS_ABORT_MSG_IF(timer.IsStrictlyPositive() && timer < MicroSeconds(8192),
91  "Timer value is below 8.192 ms");
92  NS_ABORT_MSG_IF(timer > MicroSeconds(2088960), "Timer value is above 2088.96 ms");
93 
94  double value = timer.GetMicroSeconds() / 8192.;
95  NS_ABORT_MSG_IF(std::trunc(value) != value, "Timer value is not a multiple of 8 TUs (8192 us)");
96 
97  m_records[aci].muEdcaTimer = static_cast<uint8_t>(value);
98 }
99 
100 uint8_t
101 MuEdcaParameterSet::GetQosInfo() const
102 {
103  return m_qosInfo;
104 }
105 
106 uint8_t
107 MuEdcaParameterSet::GetMuAifsn(uint8_t aci) const
108 {
109  NS_ABORT_MSG_IF(aci > 3, "Invalid AC Index value: " << +aci);
110  return (m_records[aci].aifsnField & 0x0f);
111 }
112 
113 uint16_t
114 MuEdcaParameterSet::GetMuCwMin(uint8_t aci) const
115 {
116  NS_ABORT_MSG_IF(aci > 3, "Invalid AC Index value: " << +aci);
117  uint8_t eCwMin = (m_records[aci].cwMinMax & 0x0f);
118  return static_cast<uint16_t>(std::exp2(eCwMin) - 1);
119 }
120 
121 uint16_t
122 MuEdcaParameterSet::GetMuCwMax(uint8_t aci) const
123 {
124  NS_ABORT_MSG_IF(aci > 3, "Invalid AC Index value: " << +aci);
125  uint8_t eCwMax = ((m_records[aci].cwMinMax >> 4) & 0x0f);
126  return static_cast<uint16_t>(std::exp2(eCwMax) - 1);
127 }
128 
129 Time
130 MuEdcaParameterSet::GetMuEdcaTimer(uint8_t aci) const
131 {
132  NS_ABORT_MSG_IF(aci > 3, "Invalid AC Index value: " << +aci);
133  return MicroSeconds(m_records[aci].muEdcaTimer * 8192);
134 }
135 
136 uint16_t
137 MuEdcaParameterSet::GetInformationFieldSize() const
138 {
139  // ElementIdExt (1) + QoS Info (1) + MU Parameter Records (4 * 3)
140  return 14;
141 }
142 
143 void
144 MuEdcaParameterSet::SerializeInformationField(Buffer::Iterator start) const
145 {
146  start.WriteU8(GetQosInfo());
147  for (const auto& record : m_records)
148  {
149  start.WriteU8(record.aifsnField);
150  start.WriteU8(record.cwMinMax);
151  start.WriteU8(record.muEdcaTimer);
152  }
153 }
154 
155 uint16_t
156 MuEdcaParameterSet::DeserializeInformationField(Buffer::Iterator start, uint16_t length)
157 {
159  m_qosInfo = i.ReadU8();
160  for (auto& record : m_records)
161  {
162  record.aifsnField = i.ReadU8();
163  record.cwMinMax = i.ReadU8();
164  record.muEdcaTimer = i.ReadU8();
165  }
166  return 13;
167 }
168 
169 } // namespace ns3
iterator in a Buffer instance
Definition: buffer.h:100
uint8_t ReadU8()
Definition: buffer.h:1027
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
bool IsStrictlyPositive() const
Exactly equivalent to t > 0.
Definition: nstime.h:351
int64_t GetMicroSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:413
#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:1350
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.
value
Definition: second.py:48
#define IE_EXTENSION
#define IE_EXT_MU_EDCA_PARAMETER_SET