A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
originator-block-ack-agreement.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009, 2010 MIRKO BANCHI
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Mirko Banchi <mk.banchi@gmail.com>
7 * Tommaso Pecorella <tommaso.pecorella@unifi.it>
8 */
9
11
12#include "wifi-mpdu.h"
13#include "wifi-utils.h"
14
15#include "ns3/log.h"
16
17namespace ns3
18{
19
20NS_LOG_COMPONENT_DEFINE("OriginatorBlockAckAgreement");
21
23 : BlockAckAgreement(recipient, tid),
24 m_state(PENDING)
25{
26}
27
31
32void
37
38bool
43
44bool
49
50bool
55
56bool
61
62bool
67
68uint16_t
70{
71 if (m_txWindow.GetWinSize() == 0)
72 {
73 // the TX window has not been initialized yet
74 return m_startingSeq;
75 }
76 return m_txWindow.GetWinStart();
77}
78
79std::size_t
81{
83}
84
85void
90
91bool
92OriginatorBlockAckAgreement::AllAckedMpdusInTxWindow(const std::set<uint16_t>& seqNumbers) const
93{
94 std::set<std::size_t> distances;
95 for (const auto seqN : seqNumbers)
96 {
97 distances.insert(GetDistance(seqN));
98 }
99
100 for (std::size_t i = 0; i < m_txWindow.GetWinSize(); ++i)
101 {
102 if (distances.contains(i))
103 {
104 continue; // this is one of the positions to ignore
105 }
106 if (!m_txWindow.At(i))
107 {
108 return false; // this position is available or contains an unacknowledged MPDU
109 }
110 }
111 NS_LOG_INFO("TX window is blocked");
112 return true;
113}
114
115void
117{
118 while (m_txWindow.At(0))
119 {
120 m_txWindow.Advance(1); // reset the current head -- ensures loop termination
121 }
122}
123
124void
126{
127 uint16_t mpduSeqNumber = mpdu->GetHeader().GetSequenceNumber();
128 uint16_t distance = GetDistance(mpduSeqNumber);
129
130 if (distance >= SEQNO_SPACE_HALF_SIZE)
131 {
132 NS_LOG_DEBUG("Transmitted an old MPDU, do nothing.");
133 return;
134 }
135
136 // advance the transmit window if an MPDU beyond the current transmit window
137 // is transmitted (see Section 10.24.7.7 of 802.11-2016)
138 if (distance >= m_txWindow.GetWinSize())
139 {
140 std::size_t count = distance - m_txWindow.GetWinSize() + 1;
141 m_txWindow.Advance(count);
142 // transmit window may advance further
145 "Transmitted MPDU beyond current transmit window. New starting sequence number: "
147 }
148}
149
150void
152{
153 uint16_t mpduSeqNumber = mpdu->GetHeader().GetSequenceNumber();
154 uint16_t distance = GetDistance(mpduSeqNumber);
155
156 if (distance >= SEQNO_SPACE_HALF_SIZE)
157 {
158 NS_LOG_DEBUG("Acked an old MPDU, do nothing.");
159 return;
160 }
161
162 // when an MPDU is transmitted, the transmit window is updated such that the
163 // transmitted MPDU is in the window, hence we cannot be notified of the
164 // acknowledgment of an MPDU which is beyond the transmit window
165 m_txWindow.At(distance) = true;
166
167 // the starting sequence number can be advanced to the sequence number of
168 // the nearest unacknowledged MPDU
170 NS_LOG_DEBUG("Starting sequence number: " << m_txWindow.GetWinStart());
171}
172
173void
175{
176 uint16_t mpduSeqNumber = mpdu->GetHeader().GetSequenceNumber();
177 uint16_t distance = GetDistance(mpduSeqNumber);
178
179 if (distance >= SEQNO_SPACE_HALF_SIZE)
180 {
181 NS_LOG_DEBUG("Discarded an old MPDU, do nothing.");
182 return;
183 }
184
185 m_txWindow.Advance(distance + 1);
186 // transmit window may advance further
188 NS_LOG_DEBUG("Discarded MPDU within current transmit window. New starting sequence number: "
190}
191
192} // namespace ns3
Maintains information for a block ack agreement.
uint16_t m_startingSeq
Starting sequence control.
uint16_t m_bufferSize
Buffer size.
static std::size_t GetDistance(uint16_t seqNumber, uint16_t startingSeqNumber)
Get the distance between the given starting sequence number and the given sequence number.
std::size_t GetWinSize() const
Get the window size.
void Advance(std::size_t count)
Advance the current winStart by the given number of positions.
uint16_t GetWinStart() const
Get the current winStart value.
void Init(uint16_t winStart, uint16_t winSize)
Initialize the window with the given starting sequence number and size.
std::vector< bool >::reference At(std::size_t distance)
Get a reference to the element in the window having the given distance from the current winStart.
an EUI-48 address
void NotifyDiscardedMpdu(Ptr< const WifiMpdu > mpdu)
Advance the transmit window beyond the MPDU that has been reported to be discarded.
uint16_t GetStartingSequence() const override
Return the starting sequence number of the transmit window, if a transmit window has been initialized...
BlockAckWindow m_txWindow
originator's transmit window
void NotifyTransmittedMpdu(Ptr< const WifiMpdu > mpdu)
Advance the transmit window so as to include the transmitted MPDU, if the latter is not an old packet...
void NotifyAckedMpdu(Ptr< const WifiMpdu > mpdu)
Record that the given MPDU has been acknowledged and advance the transmit window if possible.
bool IsPending() const
Check if the current state of this agreement is PENDING.
bool IsReset() const
Check if the current state of this agreement is RESET.
void AdvanceTxWindow()
Advance the transmit window so that the starting sequence number is the nearest unacknowledged MPDU.
OriginatorBlockAckAgreement(Mac48Address recipient, uint8_t tid)
Constructor.
bool IsEstablished() const
Check if the current state of this agreement is ESTABLISHED.
void SetState(State state)
Set the current state.
bool AllAckedMpdusInTxWindow(const std::set< uint16_t > &seqNumbers) const
Check whether all the MPDUs in the TX window other than the given ones have been already acknowledged...
State
Represents the state for this agreement.
std::size_t GetDistance(uint16_t seqNumber) const
Get the distance between the current starting sequence number and the given sequence number.
bool IsNoReply() const
Check if the current state of this agreement is NO_REPLY.
bool IsRejected() const
Check if the current state of this agreement is REJECTED.
void InitTxWindow()
Initialize the originator's transmit window by setting its size and starting sequence number equal to...
Smart pointer class similar to boost::intrusive_ptr.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static constexpr uint16_t SEQNO_SPACE_HALF_SIZE
Size of the half the space of sequence numbers (used to determine old packets)
Definition wifi-utils.h:188