--- 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