A Discrete-Event Network Simulator
API
block-ack-test-suite.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009, 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/test.h"
22 #include "ns3/log.h"
23 #include "ns3/qos-utils.h"
24 #include "ns3/ctrl-headers.h"
25 #include <list>
26 
27 using namespace ns3;
28 
29 NS_LOG_COMPONENT_DEFINE ("BlockAckTest");
30 
40 //-------------------------------------------------------------------------------------
41 
42 /* ----- = old packets
43  * +++++ = new packets
44  *
45  * CASE A: startSeq < endSeq
46  * - - +
47  * initial buffer state: 0 16 56000
48  *
49  *
50  * 0 4095
51  * |------|++++++++++++++++|-----|
52  * ^ ^
53  * | startSeq | endSeq = 4000
54  *
55  * first received packet's sequence control = 64016 (seqNum = 4001, fragNum = 0) -
56  * second received packet's sequence control = 63984 (seqNum = 3999, fragNum = 0) +
57  * 4001 is older seq number so this packet should be inserted at the buffer's begin.
58  * 3999 is previous element of older of new packets: it should be inserted at the end of buffer.
59  *
60  * expected buffer state: 64016 0 16 56000 63984
61  *
62  */
64 {
65 public:
67  virtual ~PacketBufferingCaseA ();
68 private:
69  virtual void DoRun (void);
70  std::list<uint16_t> m_expectedBuffer;
71 };
72 
74  : TestCase ("Check correct order of buffering when startSequence < endSeq")
75 {
76  m_expectedBuffer.push_back (64016);
77  m_expectedBuffer.push_back (0);
78  m_expectedBuffer.push_back (16);
79  m_expectedBuffer.push_back (56000);
80  m_expectedBuffer.push_back (63984);
81 }
82 
84 {
85 }
86 
87 void
89 {
90  std::list<uint16_t> m_buffer;
91  std::list<uint16_t>::iterator i,j;
92  m_buffer.push_back (0);
93  m_buffer.push_back (16);
94  m_buffer.push_back (56000);
95 
96  uint16_t endSeq = 4000;
97 
98  uint16_t receivedSeq = 4001 * 16;
99  uint32_t mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
100  /* cycle to right position for this packet */
101  for (i = m_buffer.begin (); i != m_buffer.end (); i++)
102  {
103  if (QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) >= mappedSeq)
104  {
105  //position found
106  break;
107  }
108  }
109  m_buffer.insert (i, receivedSeq);
110 
111  receivedSeq = 3999 * 16;
112  mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
113  /* cycle to right position for this packet */
114  for (i = m_buffer.begin (); i != m_buffer.end (); i++)
115  {
116  if (QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) >= mappedSeq)
117  {
118  //position found
119  break;
120  }
121  }
122  m_buffer.insert (i, receivedSeq);
123 
124  for (i = m_buffer.begin (), j = m_expectedBuffer.begin (); i != m_buffer.end (); i++, j++)
125  {
126  NS_TEST_EXPECT_MSG_EQ (*i, *j, "error in buffer order");
127  }
128 }
129 
130 
131 /* ----- = old packets
132  * +++++ = new packets
133  *
134  * CASE B: startSeq > endSeq
135  * - + +
136  * initial buffer state: 256 64000 16
137  *
138  *
139  * 0 4095
140  * |++++++|----------------|++++++|
141  * ^ ^
142  * | endSeq = 10 | startSeq
143  *
144  * first received packet's sequence control = 240 (seqNum = 15, fragNum = 0) -
145  * second received packet's sequence control = 241 (seqNum = 15, fragNum = 1) -
146  * third received packet's sequence control = 64800 (seqNum = 4050, fragNum = 0) +
147  * 240 is an old packet should be inserted at the buffer's begin.
148  * 241 is an old packet: second segment of the above packet.
149  * 4050 is a new packet: it should be inserted between 64000 and 16.
150  *
151  * expected buffer state: 240 241 256 64000 64800 16
152  *
153  */
155 {
156 public:
158  virtual ~PacketBufferingCaseB ();
159 private:
160  virtual void DoRun (void);
161  std::list<uint16_t> m_expectedBuffer;
162 };
163 
165  : TestCase ("Check correct order of buffering when startSequence > endSeq")
166 {
167  m_expectedBuffer.push_back (240);
168  m_expectedBuffer.push_back (241);
169  m_expectedBuffer.push_back (256);
170  m_expectedBuffer.push_back (64000);
171  m_expectedBuffer.push_back (64800);
172  m_expectedBuffer.push_back (16);
173 }
174 
176 {
177 }
178 
179 void
181 {
182  std::list<uint16_t> m_buffer;
183  std::list<uint16_t>::iterator i,j;
184  m_buffer.push_back (256);
185  m_buffer.push_back (64000);
186  m_buffer.push_back (16);
187 
188  uint16_t endSeq = 10;
189 
190  uint16_t receivedSeq = 15 * 16;
191  uint32_t mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
192  /* cycle to right position for this packet */
193  for (i = m_buffer.begin (); i != m_buffer.end (); i++)
194  {
195  if (QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) >= mappedSeq)
196  {
197  //position found
198  break;
199  }
200  }
201  m_buffer.insert (i, receivedSeq);
202 
203  receivedSeq = 15 * 16 + 1;
204  mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
205  /* cycle to right position for this packet */
206  for (i = m_buffer.begin (); i != m_buffer.end (); i++)
207  {
208  if (QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) >= mappedSeq)
209  {
210  //position found
211  break;
212  }
213  }
214  m_buffer.insert (i, receivedSeq);
215 
216  receivedSeq = 4050 * 16;
217  mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
218  /* cycle to right position for this packet */
219  for (i = m_buffer.begin (); i != m_buffer.end (); i++)
220  {
221  if (QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) >= mappedSeq)
222  {
223  //position found
224  break;
225  }
226  }
227  m_buffer.insert (i, receivedSeq);
228 
229  for (i = m_buffer.begin (), j = m_expectedBuffer.begin (); i != m_buffer.end (); i++, j++)
230  {
231  NS_TEST_EXPECT_MSG_EQ (*i, *j, "error in buffer order");
232  }
233 }
234 
235 
236 //Test for block ack header
238 {
239 public:
241 private:
242  virtual void DoRun ();
244 };
245 
247  : TestCase ("Check the correctness of block ack compressed bitmap")
248 {
249 }
250 
251 void
253 {
255 
256  //Case 1: startSeq < endSeq
257  // 179 242
259  for (uint32_t i = 179; i < 220; i++)
260  {
262  }
263  for (uint32_t i = 225; i <= 242; i++)
264  {
266  }
267  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetCompressedBitmap (), 0xffffc1ffffffffffLL, "error in compressed bitmap");
269  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetCompressedBitmap (), 0xffffc1ffffffffffLL, "error in compressed bitmap");
270  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (220), false, "error in compressed bitmap");
271  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (225), true, "error in compressed bitmap");
272  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (1500), false, "error in compressed bitmap");
273 
275 
276  //Case 2: startSeq > endSeq
277  // 4090 58
279  for (uint32_t i = 4090; i != 10; i = (i + 1) % 4096)
280  {
282  }
283  for (uint32_t i = 22; i < 25; i++)
284  {
286  }
287  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetCompressedBitmap (), 0x00000000007000ffffLL, "error in compressed bitmap");
289  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.GetCompressedBitmap (), 0x00000000007000ffffLL, "error in compressed bitmap");
290  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (4090), true, "error in compressed bitmap");
291  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (4095), true, "error in compressed bitmap");
292  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (10), false, "error in compressed bitmap");
293  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (35), false, "error in compressed bitmap");
294  NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (80), false, "error in compressed bitmap");
295 }
296 
297 
299 {
300 public:
302 };
303 
305  : TestSuite ("wifi-block-ack", UNIT)
306 {
307  AddTestCase (new PacketBufferingCaseA, TestCase::QUICK);
308  AddTestCase (new PacketBufferingCaseB, TestCase::QUICK);
309  AddTestCase (new CtrlBAckResponseHeaderTest, TestCase::QUICK);
310 }
311 
std::list< uint16_t > m_expectedBuffer
A suite of tests to run.
Definition: test.h:1333
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
bool IsPacketReceived(uint16_t seq) const
Check if the packet with the given sequence number was ACKed in this Block ACK response.
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:278
encapsulates test code
Definition: test.h:1147
void SetStartingSequence(uint16_t seq)
Set the starting sequence number from the given raw sequence control field.
CtrlBAckResponseHeader m_blockAckHdr
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:298
Headers for Block ack response.
Definition: ctrl-headers.h:186
virtual void DoRun(void)
Implementation to actually run this TestCase.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SetType(enum BlockAckType type)
Set the block ACK type.
void ResetBitmap(void)
Reset the bitmap to 0.
void SetReceivedPacket(uint16_t seq)
Set the bitmap that the packet with the given sequence number was received.
This simple test verifies the correctness of buffering for packets received under block ack...
uint32_t QosUtilsMapSeqControlToUniqueInteger(uint16_t seqControl, uint16_t endSequence)
Next function is useful to correctly sort buffered packets under block ack.
Definition: qos-utils.cc:77
virtual void DoRun()
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
static BlockAckTestSuite g_blockAckTestSuite
std::list< uint16_t > m_expectedBuffer
uint64_t GetCompressedBitmap(void) const
Return the compressed bitmap from the block ACK response header.