add block ack test suite
authorMirko Banchi <mk.banchi@gmail.com>
Wed, 03 Feb 2010 20:34:54 +0100
changeset 5967 0ca25e25b116
parent 5966 bd34322d49c1
child 5968 f953bc93d9c3
add block ack test suite
src/devices/wifi/block-ack-test-suite.cc
src/devices/wifi/wscript
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/wifi/block-ack-test-suite.cc	Wed Feb 03 20:34:54 2010 +0100
@@ -0,0 +1,214 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 MIRKO BANCHI
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as 
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mirko Banchi <mk.banchi@gmail.com>
+ */
+#include "ns3/test.h"
+#include "ns3/log.h"
+#include "qos-utils.h"
+#include <list>
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("BlockAckTest");
+/**
+ * This simple test verifies the correctness of buffering for packets received
+ * under block ack. In order to completely understand this example is important to cite
+ * section 9.10.3 in IEEE802.11 standard:
+ *
+ * "[...] The sequence number space is considered divided into two parts, one of which
+ * is “old” and one of which is “new” by means of a boundary created by adding half the
+ * sequence number range to the current start of receive window (modulo 2^12)."
+ */
+//-------------------------------------------------------------------------------------
+
+/* ----- = old packets
+ * +++++ = new packets
+ *  
+ *  CASE A: startSeq < endSeq  
+ *                        -  -   +
+ *  initial buffer state: 0 16 56000
+ *
+ * 
+ *    0                            4095
+ *    |------|++++++++++++++++|-----|
+ *           ^                ^
+ *           | startSeq       | endSeq = 4000
+ *
+ *  first received packet's sequence control = 64016 (seqNum = 4001, fragNum = 0) -
+ *  second received packet's sequence control = 63984 (seqNum = 3999, fragNum = 0) +
+ *  4001 is older seq number so this packet should be inserted at the buffer's begin.
+ *  3999 is previous element of older of new packets: it should be inserted at the end of buffer.
+ *  
+ *  expected buffer state: 64016 0 16 56000 63984
+ *
+ */
+class PacketBufferingCaseA : public TestCase
+{
+public:
+  PacketBufferingCaseA ();
+  virtual ~PacketBufferingCaseA ();
+private:
+  virtual bool DoRun (void);
+  std::list<uint16_t> m_expectedBuffer;
+};
+
+PacketBufferingCaseA::PacketBufferingCaseA ()
+  : TestCase ("Check correct order of buffering when startSequence < endSeq")
+{
+  m_expectedBuffer.push_back (64016);
+  m_expectedBuffer.push_back (0);
+  m_expectedBuffer.push_back (16);
+  m_expectedBuffer.push_back (56000);
+  m_expectedBuffer.push_back (63984);
+}
+
+PacketBufferingCaseA::~PacketBufferingCaseA ()
+{}
+
+bool
+PacketBufferingCaseA::DoRun (void)
+{
+  std::list<uint16_t> m_buffer;
+  std::list<uint16_t>::iterator i,j;
+  m_buffer.push_back (0);
+  m_buffer.push_back (16);
+  m_buffer.push_back (56000);
+
+  uint16_t endSeq = 4000;
+  
+  uint16_t receivedSeq = 4001 * 16;
+  uint32_t mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
+  for (i = m_buffer.begin (); i != m_buffer.end () && QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) < mappedSeq; i++);
+    {
+      m_buffer.insert (i, receivedSeq);
+    }
+  
+  receivedSeq = 3999 * 16;
+  mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
+  for (i = m_buffer.begin (); i != m_buffer.end () && QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) < mappedSeq; i++);
+    {
+      m_buffer.insert (i, receivedSeq);
+    }
+
+  for (i = m_buffer.begin (), j = m_expectedBuffer.begin (); i != m_buffer.end (); i++, j++)
+    {
+      NS_TEST_EXPECT_MSG_EQ (*i, *j, "error in buffer order");
+    }
+  return GetErrorStatus ();
+}
+
+/* ----- = old packets
+ * +++++ = new packets
+ *  
+ *  CASE B: startSeq > endSeq
+ *                         -    +    +
+ *  initial buffer state: 256 64000 16
+ *
+ *
+ *    0                            4095
+ *    |++++++|----------------|++++++|
+ *           ^                ^
+ *           | endSeq = 10    | startSeq
+ *
+ *  first received packet's sequence control = 240 (seqNum = 15, fragNum = 0)  -
+ *  second received packet's sequence control = 241 (seqNum = 15, fragNum = 1) -
+ *  third received packet's sequence control = 64800 (seqNum = 4050, fragNum = 0) +
+ *  240 is an old packet should be inserted at the buffer's begin.
+ *  241 is an old packet: second segment of the above packet.
+ *  4050 is a new packet: it should be inserted between 64000 and 16.
+ *  
+ *  expected buffer state: 240 241 256 64000 64800 16
+ *
+ */
+class PacketBufferingCaseB : public TestCase
+{
+public:
+  PacketBufferingCaseB ();
+  virtual ~PacketBufferingCaseB ();
+private:
+  virtual bool DoRun (void);
+  std::list<uint16_t> m_expectedBuffer;
+};
+
+PacketBufferingCaseB::PacketBufferingCaseB ()
+  : TestCase ("Check correct order of buffering when startSequence > endSeq")
+{
+  m_expectedBuffer.push_back (240);
+  m_expectedBuffer.push_back (241);
+  m_expectedBuffer.push_back (256);
+  m_expectedBuffer.push_back (64000);
+  m_expectedBuffer.push_back (64800);
+  m_expectedBuffer.push_back (16);
+}
+
+PacketBufferingCaseB::~PacketBufferingCaseB ()
+{}
+
+bool
+PacketBufferingCaseB::DoRun (void)
+{
+  std::list<uint16_t> m_buffer;
+  std::list<uint16_t>::iterator i,j;
+  m_buffer.push_back (256);
+  m_buffer.push_back (64000);
+  m_buffer.push_back (16);
+
+  uint16_t endSeq = 10;
+
+  uint16_t receivedSeq = 15 * 16;
+  uint32_t mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
+  for (i = m_buffer.begin (); i != m_buffer.end () && QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) < mappedSeq; i++);
+    {
+      m_buffer.insert (i, receivedSeq);
+    }
+
+  receivedSeq = 15 * 16 + 1;
+  mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
+  for (i = m_buffer.begin (); i != m_buffer.end () && QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) < mappedSeq; i++);
+    {
+      m_buffer.insert (i, receivedSeq);
+    }
+
+  receivedSeq = 4050 * 16;
+  mappedSeq = QosUtilsMapSeqControlToUniqueInteger (receivedSeq, endSeq);
+  for (i = m_buffer.begin (); i != m_buffer.end () && QosUtilsMapSeqControlToUniqueInteger ((*i), endSeq) < mappedSeq; i++);
+    {
+      m_buffer.insert (i, receivedSeq);
+    }
+
+  for (i = m_buffer.begin (), j = m_expectedBuffer.begin (); i != m_buffer.end (); i++, j++)
+    {
+      NS_TEST_EXPECT_MSG_EQ (*i, *j, "error in buffer order");
+    }
+  return GetErrorStatus ();
+}
+
+class BlockAckTestSuite : public TestSuite
+{
+public:
+  BlockAckTestSuite ();
+};
+
+BlockAckTestSuite::BlockAckTestSuite ()
+  : TestSuite ("wifi-block-ack", UNIT)
+{
+  AddTestCase (new PacketBufferingCaseA);
+  AddTestCase (new PacketBufferingCaseB);
+}
+
+BlockAckTestSuite g_blockAckTestSuite;
--- a/src/devices/wifi/wscript	Wed Feb 03 20:34:54 2010 +0100
+++ b/src/devices/wifi/wscript	Wed Feb 03 20:34:54 2010 +0100
@@ -60,6 +60,7 @@
         'qos-blocked-destinations.cc',
         'block-ack-agreement.cc',
         'block-ack-manager.cc',
+        'block-ack-test-suite.cc',
         ]
     headers = bld.new_task_gen('ns3header')
     headers.module = 'wifi'