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 "block-ack-cache.h"
22 #include "ctrl-headers.h"
23 #include "wifi-mac-header.h"
24 #include "qos-utils.h"
25 #include "ns3/log.h"
26 
27 #define WINSIZE_ASSERT NS_ASSERT ((m_winEnd - m_winStart + 4096) % 4096 == m_winSize - 1)
28 
29 namespace ns3 {
30 
31 NS_LOG_COMPONENT_DEFINE ("BlockAckCache");
32 
33 void
34 BlockAckCache::Init (uint16_t winStart, uint16_t winSize)
35 {
36  NS_LOG_FUNCTION (this << winStart << winSize);
37  m_winStart = winStart;
38  m_winSize = winSize <= 64 ? winSize : 64;
39  m_winEnd = (m_winStart + m_winSize - 1) % 4096;
40  memset (m_bitmap, 0, sizeof (m_bitmap));
41 }
42 
43 uint16_t
45 {
46  return m_winStart;
47 }
48 
49 void
51 {
52  NS_LOG_FUNCTION (this << hdr);
53  uint16_t seqNumber = hdr->GetSequenceNumber ();
54  if (!QosUtilsIsOldPacket (m_winStart, seqNumber))
55  {
56  if (!IsInWindow (seqNumber))
57  {
58  uint16_t delta = (seqNumber - m_winEnd + 4096) % 4096;
59  if (delta > 1)
60  {
61  ResetPortionOfBitmap ((m_winEnd + 1) % 4096, ((seqNumber - 1) + 4096) % 4096);
62  }
63  m_winStart = (m_winStart + delta) % 4096;
64  m_winEnd = seqNumber;
65 
67  }
68  m_bitmap[seqNumber] |= (0x0001 << hdr->GetFragmentNumber ());
69  }
70 }
71 
72 void
74 {
75  NS_LOG_FUNCTION (this << startingSeq);
76  if (!QosUtilsIsOldPacket (m_winStart, startingSeq))
77  {
78  if (IsInWindow (startingSeq))
79  {
80  if (startingSeq != m_winStart)
81  {
82  m_winStart = startingSeq;
83  uint16_t newWinEnd = (m_winStart + m_winSize - 1) % 4096;
84  ResetPortionOfBitmap ((m_winEnd + 1) % 4096, newWinEnd);
85  m_winEnd = newWinEnd;
86 
88  }
89  }
90  else
91  {
92  m_winStart = startingSeq;
93  m_winEnd = (m_winStart + m_winSize - 1) % 4096;
95 
97  }
98  }
99 }
100 
101 void
103 {
104  NS_LOG_FUNCTION (this << start << end);
105  uint16_t i = start;
106  for (; i != end; i = (i + 1) % 4096)
107  {
108  m_bitmap[i] = 0;
109  }
110  m_bitmap[i] = 0;
111 }
112 
113 bool
114 BlockAckCache::IsInWindow (uint16_t seq) const
115 {
116  NS_LOG_FUNCTION (this << seq);
117  return ((seq - m_winStart + 4096) % 4096) < m_winSize;
118 }
119 
120 void
122 {
123  NS_LOG_FUNCTION (this << blockAckHeader);
124  if (blockAckHeader->IsBasic ())
125  {
126  NS_FATAL_ERROR ("Basic block ack is only partially implemented.");
127  }
128  else if (blockAckHeader->IsCompressed ())
129  {
130  uint16_t i = blockAckHeader->GetStartingSequence ();
131  uint16_t end = (i + m_winSize - 1) % 4096;
132  for (; i != end; i = (i + 1) % 4096)
133  {
134  if (m_bitmap[i] == 1)
135  {
136  blockAckHeader->SetReceivedPacket (i);
137  }
138  }
139  if (m_bitmap[i] == 1)
140  {
141  blockAckHeader->SetReceivedPacket (i);
142  }
143  }
144  else if (blockAckHeader->IsMultiTid ())
145  {
146  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
147  }
148 }
149 
150 } //namespace ns3
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
uint16_t GetFragmentNumber(void) const
Return the fragment number of the header.
void ResetPortionOfBitmap(uint16_t start, uint16_t end)
Reset portion of bitmap functiion.
uint16_t GetStartingSequence(void) const
Return the starting sequence number.
def start()
Definition: core.py:1790
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:201
bool IsCompressed(void) const
Check if the current ACK policy is compressed ACK and not multiple TID.
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:88
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...
Headers for Block ack response.
Definition: ctrl-headers.h:190
#define WINSIZE_ASSERT
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool IsBasic(void) const
Check if the current ACK policy is basic (i.e.
void FillBlockAckBitmap(CtrlBAckResponseHeader *blockAckHeader)
Fill block ack bitmap function.
uint8_t m_winSize
window size
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 IsInWindow(uint16_t seq) const
Is in window function.
uint16_t m_bitmap[4096]
bitmap
bool IsMultiTid(void) const
Check if the current ACK policy has multiple TID.
Implements the IEEE 802.11 MAC header.
uint16_t GetSequenceNumber(void) const
Return the sequence number of the header.