A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
block-ack-cache.cc
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 #include "block-ack-cache.h"
21 #include "ctrl-headers.h"
22 #include "wifi-mac-header.h"
23 #include "qos-utils.h"
24 #include "ns3/log.h"
25 
26 #define WINSIZE_ASSERT NS_ASSERT ((m_winEnd - m_winStart + 4096) % 4096 == m_winSize - 1)
27 
28 NS_LOG_COMPONENT_DEFINE ("BlockAckCache");
29 
30 namespace ns3 {
31 
32 void
33 BlockAckCache::Init (uint16_t winStart, uint16_t winSize)
34 {
35  NS_LOG_FUNCTION (this << winStart << winSize);
36  m_winStart = winStart;
37  m_winSize = winSize <= 64 ? winSize : 64;
38  m_winEnd = (m_winStart + m_winSize - 1) % 4096;
39  memset (m_bitmap, 0, sizeof (m_bitmap));
40 }
41 
42 void
43 BlockAckCache::UpdateWithMpdu (const WifiMacHeader *hdr)
44 {
45  NS_LOG_FUNCTION (this << hdr);
46  uint16_t seqNumber = hdr->GetSequenceNumber ();
47  if (!QosUtilsIsOldPacket (m_winStart, seqNumber))
48  {
49  if (!IsInWindow (seqNumber))
50  {
51  uint16_t delta = (seqNumber - m_winEnd + 4096) % 4096;
52  if (delta > 1)
53  {
54  ResetPortionOfBitmap ((m_winEnd + 1) % 4096, ((seqNumber - 1) + 4096) % 4096);
55  }
56  m_winStart = (m_winStart + delta) % 4096;
57  m_winEnd = seqNumber;
58 
59  WINSIZE_ASSERT;
60  }
61  m_bitmap[seqNumber] |= (0x0001 << hdr->GetFragmentNumber ());
62  }
63 }
64 
65 void
66 BlockAckCache::UpdateWithBlockAckReq (uint16_t startingSeq)
67 {
68  NS_LOG_FUNCTION (this << startingSeq);
69  if (!QosUtilsIsOldPacket (m_winStart, startingSeq))
70  {
71  if (IsInWindow (startingSeq))
72  {
73  if (startingSeq != m_winStart)
74  {
75  m_winStart = startingSeq;
76  uint16_t newWinEnd = (m_winStart + m_winSize - 1) % 4096;
77  ResetPortionOfBitmap ((m_winEnd + 1) % 4096, newWinEnd);
78  m_winEnd = newWinEnd;
79 
80  WINSIZE_ASSERT;
81  }
82  }
83  else
84  {
85  m_winStart = startingSeq;
86  m_winEnd = (m_winStart + m_winSize - 1) % 4096;
87  ResetPortionOfBitmap (m_winStart, m_winEnd);
88 
89  WINSIZE_ASSERT;
90  }
91  }
92 }
93 
94 void
95 BlockAckCache::ResetPortionOfBitmap (uint16_t start, uint16_t end)
96 {
97  NS_LOG_FUNCTION (this << start << end);
98  uint32_t i = start;
99  for (; i != end; i = (i + 1) % 4096)
100  {
101  m_bitmap[i] = 0;
102  }
103  m_bitmap[i] = 0;
104 }
105 
106 bool
107 BlockAckCache::IsInWindow (uint16_t seq)
108 {
109  NS_LOG_FUNCTION (this << seq);
110  return ((seq - m_winStart + 4096) % 4096) < m_winSize;
111 }
112 
113 void
114 BlockAckCache::FillBlockAckBitmap (CtrlBAckResponseHeader *blockAckHeader)
115 {
116  NS_LOG_FUNCTION (this << blockAckHeader);
117  if (blockAckHeader->IsBasic ())
118  {
119  NS_FATAL_ERROR ("Basic block ack is only partially implemented.");
120  }
121  else if (blockAckHeader->IsCompressed ())
122  {
123  uint32_t i = blockAckHeader->GetStartingSequence ();
124  uint32_t end = (i + m_winSize - 1) % 4096;
125  for (; i != end; i = (i + 1) % 4096)
126  {
127  if (m_bitmap[i] == 1)
128  {
129  blockAckHeader->SetReceivedPacket (i);
130  }
131  }
132  if (m_bitmap[i] == 1)
133  {
134  blockAckHeader->SetReceivedPacket (i);
135  }
136  }
137  else if (blockAckHeader->IsMultiTid ())
138  {
139  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
140  }
141 }
142 
143 } // namespace ns3
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
bool QosUtilsIsOldPacket(uint16_t startingSeq, uint16_t seqNumber)
Definition: qos-utils.cc:86
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72