A Discrete-Event Network Simulator
API
block-ack-cache.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2010 MIRKO BANCHI
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: Mirko Banchi <mk.banchi@gmail.com>
19  */
20 
21 #include "ns3/log.h"
22 #include "block-ack-cache.h"
23 #include "qos-utils.h"
24 #include "wifi-utils.h"
25 #include "wifi-mac-header.h"
26 #include "ctrl-headers.h"
27 
28 #define WINSIZE_ASSERT NS_ASSERT ((m_winEnd - m_winStart + 4096) % 4096 == m_winSize - 1)
29 
30 namespace ns3 {
31 
32 NS_LOG_COMPONENT_DEFINE ("BlockAckCache");
33 
34 void
35 BlockAckCache::Init (uint16_t winStart, uint16_t winSize)
36 {
37  NS_LOG_FUNCTION (this << winStart << winSize);
38  m_winStart = winStart;
39  m_winSize = winSize <= 64 ? winSize : 64;
40  m_winEnd = (m_winStart + m_winSize - 1) % 4096;
41  memset (m_bitmap, 0, sizeof (m_bitmap));
42 }
43 
44 uint16_t
46 {
47  return m_winStart;
48 }
49 
50 void
52 {
53  NS_LOG_FUNCTION (this << hdr);
54  uint16_t seqNumber = hdr->GetSequenceNumber ();
55  if (!QosUtilsIsOldPacket (m_winStart, seqNumber))
56  {
57  if (!IsInWindow (seqNumber, m_winStart, m_winSize))
58  {
59  uint16_t delta = (seqNumber - m_winEnd + 4096) % 4096;
60  if (delta > 1)
61  {
62  ResetPortionOfBitmap ((m_winEnd + 1) % 4096, ((seqNumber - 1) + 4096) % 4096);
63  }
64  m_winStart = (m_winStart + delta) % 4096;
65  m_winEnd = seqNumber;
66 
68  }
69  m_bitmap[seqNumber] |= (0x0001 << hdr->GetFragmentNumber ());
70  }
71 }
72 
73 void
75 {
76  NS_LOG_FUNCTION (this << startingSeq);
77  if (!QosUtilsIsOldPacket (m_winStart, startingSeq))
78  {
79  if (IsInWindow (startingSeq, m_winStart, m_winSize))
80  {
81  if (startingSeq != m_winStart)
82  {
83  m_winStart = startingSeq;
84  uint16_t newWinEnd = (m_winStart + m_winSize - 1) % 4096;
85  ResetPortionOfBitmap ((m_winEnd + 1) % 4096, newWinEnd);
86  m_winEnd = newWinEnd;
87 
89  }
90  }
91  else
92  {
93  m_winStart = startingSeq;
94  m_winEnd = (m_winStart + m_winSize - 1) % 4096;
96 
98  }
99  }
100 }
101 
102 void
104 {
105  NS_LOG_FUNCTION (this << start << end);
106  uint16_t i = start;
107  for (; i != end; i = (i + 1) % 4096)
108  {
109  m_bitmap[i] = 0;
110  }
111  m_bitmap[i] = 0;
112 }
113 
114 void
116 {
117  NS_LOG_FUNCTION (this << blockAckHeader);
118  if (blockAckHeader->IsBasic ())
119  {
120  NS_FATAL_ERROR ("Basic block ack is only partially implemented.");
121  }
122  else if (blockAckHeader->IsCompressed ())
123  {
124  uint16_t i = blockAckHeader->GetStartingSequence ();
125  uint16_t end = (i + m_winSize - 1) % 4096;
126  for (; i != end; i = (i + 1) % 4096)
127  {
128  if (m_bitmap[i] == 1)
129  {
130  blockAckHeader->SetReceivedPacket (i);
131  }
132  }
133  if (m_bitmap[i] == 1)
134  {
135  blockAckHeader->SetReceivedPacket (i);
136  }
137  }
138  else if (blockAckHeader->IsMultiTid ())
139  {
140  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
141  }
142 }
143 
144 } //namespace ns3
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void ResetPortionOfBitmap(uint16_t start, uint16_t end)
Reset portion of bitmap functiion.
def start()
Definition: core.py:1844
uint16_t m_winStart
window start
void UpdateWithBlockAckReq(uint16_t startingSeq)
Update with block ack request function.
void Init(uint16_t winStart, uint16_t winSize)
Init function.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
void UpdateWithMpdu(const WifiMacHeader *hdr)
Update with MPDU function.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
bool QosUtilsIsOldPacket(uint16_t startingSeq, uint16_t seqNumber)
This function checks if packet with sequence number seqNumber is an "old" packet. ...
Definition: qos-utils.cc:83
bool IsBasic(void) const
Check if the current ACK policy is basic (i.e.
bool IsCompressed(void) const
Check if the current ACK policy is compressed ACK and not multiple TID.
Headers for Block ack response.
Definition: ctrl-headers.h:181
uint16_t GetStartingSequence(void) const
Return the starting sequence number.
#define WINSIZE_ASSERT
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint16_t GetSequenceNumber(void) const
Return the sequence number of the header.
bool IsInWindow(uint16_t seq, uint16_t winstart, uint16_t winsize)
Definition: wifi-utils.cc:133
void FillBlockAckBitmap(CtrlBAckResponseHeader *blockAckHeader)
Fill block ack bitmap function.
uint16_t m_winEnd
window end
void SetReceivedPacket(uint16_t seq)
Set the bitmap that the packet with the given sequence number was received.
bool IsMultiTid(void) const
Check if the current ACK policy has multiple TID.
uint16_t m_bitmap[4096]
bitmap
uint16_t GetWinStart(void) const
When an A-MPDU is received, the window start may change to a new value depending on the sequence numb...
uint8_t GetFragmentNumber(void) const
Return the fragment number of the header.
uint16_t m_winSize
window size
Implements the IEEE 802.11 MAC header.