A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Stefano Avallone <stavallo@unina.it>
7 */
8
10
11#include <algorithm>
12#include <cmath>
13
14namespace ns3
15{
16
18 : m_qosInfo(0),
19 m_records{{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}
20{
21}
22
24MuEdcaParameterSet::ElementId() const
25{
26 return IE_EXTENSION;
27}
28
30MuEdcaParameterSet::ElementIdExt() const
31{
33}
34
35void
36MuEdcaParameterSet::SetQosInfo(uint8_t qosInfo)
37{
38 m_qosInfo = qosInfo;
39}
40
41void
42MuEdcaParameterSet::SetMuAifsn(uint8_t aci, uint8_t aifsn)
43{
44 NS_ABORT_MSG_IF(aci > 3, "Invalid AC Index value: " << +aci);
45 NS_ABORT_MSG_IF(aifsn == 1 || aifsn > 15, "Invalid AIFSN value: " << +aifsn);
46
47 m_records[aci].aifsnField |= (aifsn & 0x0f);
48 m_records[aci].aifsnField |= (aci & 0x03) << 5;
49}
50
51void
52MuEdcaParameterSet::SetMuCwMin(uint8_t aci, uint16_t cwMin)
53{
54 NS_ABORT_MSG_IF(aci > 3, "Invalid AC Index value: " << +aci);
55 NS_ABORT_MSG_IF(cwMin > 32767, "CWmin exceeds the maximum value");
56
57 auto eCwMin = std::log2(cwMin + 1);
58 NS_ABORT_MSG_IF(std::trunc(eCwMin) != eCwMin, "CWmin is not a power of 2 minus 1");
59
60 m_records[aci].cwMinMax |= (static_cast<uint8_t>(eCwMin) & 0x0f);
61}
62
63void
64MuEdcaParameterSet::SetMuCwMax(uint8_t aci, uint16_t cwMax)
65{
66 NS_ABORT_MSG_IF(aci > 3, "Invalid AC Index value: " << +aci);
67 NS_ABORT_MSG_IF(cwMax > 32767, "CWmin exceeds the maximum value");
68
69 auto eCwMax = std::log2(cwMax + 1);
70 NS_ABORT_MSG_IF(std::trunc(eCwMax) != eCwMax, "CWmax is not a power of 2 minus 1");
71
72 m_records[aci].cwMinMax |= (static_cast<uint8_t>(eCwMax) & 0x0f) << 4;
73}
74
75void
76MuEdcaParameterSet::SetMuEdcaTimer(uint8_t aci, Time timer)
77{
78 NS_ABORT_MSG_IF(aci > 3, "Invalid AC Index value: " << +aci);
79 NS_ABORT_MSG_IF(timer.IsStrictlyPositive() && timer < MicroSeconds(8192),
80 "Timer value is below 8.192 ms");
81 NS_ABORT_MSG_IF(timer > MicroSeconds(2088960), "Timer value is above 2088.96 ms");
82
83 double value = timer.GetMicroSeconds() / 8192.;
84 NS_ABORT_MSG_IF(std::trunc(value) != value, "Timer value is not a multiple of 8 TUs (8192 us)");
85
86 m_records[aci].muEdcaTimer = static_cast<uint8_t>(value);
87}
88
89uint8_t
90MuEdcaParameterSet::GetQosInfo() const
91{
92 return m_qosInfo;
93}
94
95uint8_t
96MuEdcaParameterSet::GetMuAifsn(uint8_t aci) const
97{
98 NS_ABORT_MSG_IF(aci > 3, "Invalid AC Index value: " << +aci);
99 return (m_records[aci].aifsnField & 0x0f);
100}
101
102uint16_t
103MuEdcaParameterSet::GetMuCwMin(uint8_t aci) const
104{
105 NS_ABORT_MSG_IF(aci > 3, "Invalid AC Index value: " << +aci);
106 uint8_t eCwMin = (m_records[aci].cwMinMax & 0x0f);
107 return static_cast<uint16_t>(std::exp2(eCwMin) - 1);
108}
109
110uint16_t
111MuEdcaParameterSet::GetMuCwMax(uint8_t aci) const
112{
113 NS_ABORT_MSG_IF(aci > 3, "Invalid AC Index value: " << +aci);
114 uint8_t eCwMax = ((m_records[aci].cwMinMax >> 4) & 0x0f);
115 return static_cast<uint16_t>(std::exp2(eCwMax) - 1);
116}
117
118Time
119MuEdcaParameterSet::GetMuEdcaTimer(uint8_t aci) const
120{
121 NS_ABORT_MSG_IF(aci > 3, "Invalid AC Index value: " << +aci);
122 return MicroSeconds(m_records[aci].muEdcaTimer * 8192);
123}
124
125uint16_t
126MuEdcaParameterSet::GetInformationFieldSize() const
127{
128 // ElementIdExt (1) + QoS Info (1) + MU Parameter Records (4 * 3)
129 return 14;
130}
131
132void
133MuEdcaParameterSet::SerializeInformationField(Buffer::Iterator start) const
134{
135 start.WriteU8(GetQosInfo());
136 for (const auto& record : m_records)
137 {
138 start.WriteU8(record.aifsnField);
139 start.WriteU8(record.cwMinMax);
140 start.WriteU8(record.muEdcaTimer);
141 }
142}
143
144uint16_t
145MuEdcaParameterSet::DeserializeInformationField(Buffer::Iterator start, uint16_t length)
146{
147 Buffer::Iterator i = start;
148 m_qosInfo = i.ReadU8();
149 for (auto& record : m_records)
150 {
151 record.aifsnField = i.ReadU8();
152 record.cwMinMax = i.ReadU8();
153 record.muEdcaTimer = i.ReadU8();
154 }
155 return 13;
156}
157
158} // namespace ns3
iterator in a Buffer instance
Definition buffer.h:89
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
bool IsStrictlyPositive() const
Exactly equivalent to t > 0.
Definition nstime.h:340
int64_t GetMicroSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:402
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1332
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.
#define IE_EXTENSION
#define IE_EXT_MU_EDCA_PARAMETER_SET