merge
authorPavel Boyko <boyko@iitp.ru>
Wed, 28 Oct 2009 11:48:26 +0300
changeset 5725 26dfa683fc34
parent 5724 c61936794d60 (current diff)
parent 5465 917f7367691e (diff)
child 5726 8776c223c36c
merge
--- a/examples/mesh/mesh.cc	Tue Oct 27 16:27:19 2009 +0300
+++ b/examples/mesh/mesh.cc	Wed Oct 28 11:48:26 2009 +0300
@@ -158,7 +158,16 @@
    * mesh point device
    */
   mesh = MeshHelper::Default ();
-  mesh.SetStackInstaller (m_stack, "Root", Mac48AddressValue (Mac48Address (m_root.c_str ())));
+  if (!Mac48Address (m_root.c_str ()).IsBroadcast ())
+    {
+      mesh.SetStackInstaller (m_stack, "Root", Mac48AddressValue (Mac48Address (m_root.c_str ())));
+    }
+  else
+    {
+      //If root is not set, we do not use "Root" attribute, because it
+      //is specified only for 11s
+      mesh.SetStackInstaller (m_stack);
+    }
   if (m_chan)
     {
       mesh.SetSpreadInterfaceChannels (MeshHelper::SPREAD_CHANNELS);
--- a/src/common/pcap-file-test-suite.cc	Tue Oct 27 16:27:19 2009 +0300
+++ b/src/common/pcap-file-test-suite.cc	Wed Oct 28 11:48:26 2009 +0300
@@ -12,6 +12,8 @@
  * 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:  Craig Dowell (craigdo@ee.washington.edu)
  */
 
 #include <iostream>
@@ -948,6 +950,62 @@
   return false;
 }
 
+// ===========================================================================
+// Test case to make sure that the Pcap::Diff method works as expected
+// ===========================================================================
+class DiffTestCase : public TestCase
+{
+public:
+  DiffTestCase ();
+
+private:
+  virtual bool DoRun (void);
+};
+
+DiffTestCase::DiffTestCase ()
+  : TestCase ("Check that PcapFile::Diff works as expected")
+{
+}
+
+bool
+DiffTestCase::DoRun (void)
+{
+  //
+  // Check that PcapDiff(file, file) is false
+  //
+  std::string filename = NS_TEST_SOURCEDIR + "known.pcap";
+  uint32_t sec(0), usec(0);
+  bool diff = PcapFile::Diff (filename, filename, sec, usec);
+  NS_TEST_EXPECT_MSG_EQ (diff, false, "PcapDiff(file, file) must always be false");
+
+  //
+  // Create different PCAP file (with the same timestamps, but different packets) and check that it is indeed different 
+  //
+  std::string filename2 = "different.pcap";
+  PcapFile f;
+  
+  bool err = f.Open (filename2, "w");
+  NS_TEST_ASSERT_MSG_EQ (err, false, "Open (" << filename2 << ", \"w\") returns error");
+  err = f.Init (1, N_PACKET_BYTES);
+  NS_TEST_ASSERT_MSG_EQ (err, false, "Init (1, " << N_PACKET_BYTES << ") returns error");
+  
+  for (uint32_t i = 0; i < N_KNOWN_PACKETS; ++i)
+    {
+      PacketEntry const & p = knownPackets[i];
+      
+      err = f.Write (p.tsSec, p.tsUsec, (uint8_t const *)p.data, p.origLen);
+      NS_TEST_EXPECT_MSG_EQ (err, false, "Write must not fail");
+    }
+  f.Close ();
+
+  diff = PcapFile::Diff (filename, filename2, sec, usec);
+  NS_TEST_EXPECT_MSG_EQ (diff, true, "PcapDiff(file, file2) must be true");
+  NS_TEST_EXPECT_MSG_EQ (sec,  2, "Files are different from 2.3696 seconds");
+  NS_TEST_EXPECT_MSG_EQ (usec, 3696, "Files are different from 2.3696 seconds");
+  
+  return GetErrorStatus();
+}
+
 class PcapFileTestSuite : public TestSuite
 {
 public:
@@ -963,6 +1021,7 @@
   AddTestCase (new FileHeaderTestCase);
   AddTestCase (new RecordHeaderTestCase);
   AddTestCase (new ReadFileTestCase);
+  AddTestCase (new DiffTestCase);
 }
 
 PcapFileTestSuite pcapFileTestSuite;
--- a/src/common/pcap-file.cc	Tue Oct 27 16:27:19 2009 +0300
+++ b/src/common/pcap-file.cc	Wed Oct 28 11:48:26 2009 +0300
@@ -14,14 +14,16 @@
  * 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:  Craig Dowell (craigdo@ee.washington.edu)
  */
 
 #include <iostream>
 #include <stdio.h>
 #include <stdlib.h>
+#include <cstring>
 
 #include "pcap-file.h"
-
 //
 // This file is used as part of the ns-3 test framework, so please refrain from 
 // adding any ns-3 specific constructs such as Packet to this file.
@@ -516,4 +518,65 @@
   return false;
 }
 
+bool
+PcapFile::Diff (std::string const & f1, std::string const & f2, 
+                uint32_t & sec, uint32_t & usec, 
+                uint32_t snapLen)
+{
+  PcapFile pcap[2];
+  for (int i = 0; i < 2; ++i)
+    {
+      std::string const & file = (i == 0) ? f1 : f2;
+      bool err = pcap[i].Open (file, "r");
+      if (err)
+        {
+          // Can't open file
+          return true;
+        }
+    }
+  
+  uint8_t data[2][snapLen];
+  uint32_t tsSec[2], tsUsec[2], inclLen[2], origLen[2], readLen[2];
+  bool err[2];
+  bool diff(false);
+  
+  while (1)
+    {
+      for (int i = 0; i < 2; ++i)
+        err[i] = pcap[i].Read (data[i], snapLen, tsSec[i], tsUsec[i], inclLen[i], origLen[i], readLen[i]);
+    
+      sec = tsSec[0];
+      usec = tsUsec[0];
+      
+      if (err[0] != err[1])
+        {
+          diff = true; // Read status doesn't match
+          break;
+        }
+      
+      if (err[0]) break; // nothing left
+      
+      if (tsSec[0] != tsSec[1] || tsUsec[0] != tsUsec[1])
+        {
+          diff = true; // Next packet timestamps do not match
+          break;
+        }
+      
+      if (readLen[0] != readLen[1])
+        {
+          diff = true; // Packet lengths do not match
+          break;
+        }
+      
+      if (std::memcmp(data[0], data[1], readLen[0]) != 0)
+        {
+          diff = true; // Packet data do not match
+          break;
+        }
+    }  
+  pcap[0].Close ();
+  pcap[1].Close ();
+  return diff;
+}
+
 } //namespace ns3
--- a/src/common/pcap-file.h	Tue Oct 27 16:27:19 2009 +0300
+++ b/src/common/pcap-file.h	Wed Oct 28 11:48:26 2009 +0300
@@ -14,6 +14,8 @@
  * 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:  Craig Dowell (craigdo@ee.washington.edu)
  */
 
 #ifndef PCAP_FILE_H
@@ -125,7 +127,7 @@
    * time zone from UTC/GMT.  For example, Pacific Standard Time in the US is
    * GMT-8, so one would enter -8 for that correction.  Defaults to 0 (UTC).
    *
-   * \returns false if the open succeeds, true otherwise.
+   * \return false if the open succeeds, true otherwise.
    *
    * \warning Calling this method on an existing file will result in the loss
    * any existing data.
@@ -135,8 +137,31 @@
              int32_t timeZoneCorrection = ZONE_DEFAULT,
              bool swapMode = false);
 
+  /**
+   * \brief Write next packet to file
+   * 
+   * \param tsSec       Packet timestamp, seconds 
+   * \param tsUsec      Packet timestamp, microseconds
+   * \param data        Data buffer
+   * \param totalLen    Total packet length
+   * 
+   * \return true on error, false otherwise
+   */
   bool Write (uint32_t tsSec, uint32_t tsUsec, uint8_t const * const data, uint32_t totalLen);
 
+  /**
+   * \brief Read next packet from file
+   * 
+   * \param data        [out] Data buffer
+   * \param maxBytes    Allocated data buffer size
+   * \param tsSec       [out] Packet timestamp, seconds
+   * \param tsUsec      [out] Packet timestamp, microseconds
+   * \param inclLen     [out] Included length
+   * \param origLen     [out] Original length
+   * \param readLen     [out] Number of bytes read
+   * 
+   * \return true if read failed, false otherwise
+   */
   bool Read (uint8_t * const data, 
              uint32_t maxBytes,
              uint32_t &tsSec, 
@@ -154,6 +179,21 @@
   uint32_t GetSigFigs (void);
   uint32_t GetSnapLen (void);
   uint32_t GetDataLinkType (void);
+  
+  /**
+   * \brief Compare two PCAP files packet-by-packet
+   * 
+   * \return true if files are different, false otherwise
+   * 
+   * \param  f1         First PCAP file name
+   * \param  f2         Second PCAP file name
+   * \param  sec        [out] Time stamp of first different packet, seconds. Undefined if files doesn't differ.
+   * \param  uses       [out] Time stamp of first different packet, microseconds. Undefined if files doesn't differ.
+   * \param  snapLen    Snap length (if used)
+   */
+  static bool Diff (std::string const & f1, std::string const & f2, 
+                    uint32_t & sec, uint32_t & usec, 
+                    uint32_t snapLen = SNAPLEN_DEFAULT);
 
 private:
   typedef struct {
--- a/src/devices/mesh/flame/flame-protocol-mac.cc	Tue Oct 27 16:27:19 2009 +0300
+++ b/src/devices/mesh/flame/flame-protocol-mac.cc	Wed Oct 28 11:48:26 2009 +0300
@@ -31,6 +31,8 @@
 }
 FlameProtocolMac::~FlameProtocolMac ()
 {
+  m_protocol = 0;
+  m_parent = 0;
 }
 void
 FlameProtocolMac::SetParent (Ptr<MeshWifiInterfaceMac> parent)
--- a/src/devices/mesh/flame/flame-protocol.cc	Tue Oct 27 16:27:19 2009 +0300
+++ b/src/devices/mesh/flame/flame-protocol.cc	Wed Oct 28 11:48:26 2009 +0300
@@ -127,7 +127,7 @@
   return tid;
 }
 FlameProtocol::FlameProtocol () :
-  m_address (Mac48Address ()), m_broadcastInterval (Seconds (5)), m_lastBroadcast (Simulator::Now ()),
+  m_address (Mac48Address ()), m_broadcastInterval (Seconds (5)), m_lastBroadcast (Seconds (0)),
       m_maxCost (32), m_myLastSeqno (1), m_rtable (CreateObject<FlameRtable> ())
 {
 }
@@ -137,6 +137,9 @@
 void
 FlameProtocol::DoDispose ()
 {
+  m_interfaces.clear ();
+  m_rtable = 0;
+  m_mp = 0;
 }
 bool
 FlameProtocol::RequestRoute (uint32_t sourceIface, const Mac48Address source, const Mac48Address destination,
@@ -224,8 +227,12 @@
                   m_stats.totalDropped++;
                   return false;
                 }
+              tag.receiver = result.retransmitter;
             }
-          tag.receiver = result.retransmitter;
+          else
+            {
+              tag.receiver = Mac48Address::GetBroadcast ();
+            }
           if (result.retransmitter == Mac48Address::GetBroadcast ())
             {
               m_stats.txBroadcast++;
@@ -262,19 +269,21 @@
     }
   FlameHeader flameHdr;
   packet->RemoveHeader (flameHdr);
-  if ((destination == GetAddress ()) && (m_lastBroadcast + m_broadcastInterval < Simulator::Now ()))
-      {
-        Ptr<Packet> packet = Create<Packet> ();
-        m_mp->Send(packet, Mac48Address::GetBroadcast (), 0);
-        m_lastBroadcast = Simulator::Now ();
-      }
-  NS_ASSERT (protocolType == FLAME_PROTOCOL);
-  protocolType = flameHdr.GetProtocol ();
-  if ((HandleDataFrame (flameHdr.GetSeqno (), source, flameHdr, tag.transmitter, fromIface))
-      || packet->GetSize () == 0)
+  if (HandleDataFrame (flameHdr.GetSeqno (), source, flameHdr, tag.transmitter, fromIface))
     {
       return false;
     }
+  // Start PATH_UPDATE procedure if destination is our own address and last broadcast was sent more
+  // than broadcast interval ago or was not sent at all
+  if ((destination == GetAddress ()) && ((m_lastBroadcast + m_broadcastInterval < Simulator::Now ())
+      || (m_lastBroadcast == Seconds (0))))
+    {
+      Ptr<Packet> packet = Create<Packet> ();
+      m_mp->Send (packet, Mac48Address::GetBroadcast (), 0);
+      m_lastBroadcast = Simulator::Now ();
+    }
+  NS_ASSERT (protocolType == FLAME_PROTOCOL);
+  protocolType = flameHdr.GetProtocol ();
   return true;
 }
 bool