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