comparing with http://code.nsnam.org/ns-3-dev searching for changes changeset: 3953:5da8d25d3fec user: Craig Dowell date: Sat Nov 29 14:10:03 2008 -0800 summary: beginnings of a name to object lookup diff -r 503e8d54ee1d -r 5da8d25d3fec examples/csma-star.cc --- a/examples/csma-star.cc Fri Nov 28 15:12:05 2008 +0000 +++ b/examples/csma-star.cc Sat Nov 29 14:10:03 2008 -0800 @@ -23,17 +23,17 @@ // Network topology (default) // -// n2 + + n3 . +// n3 + + n2 . // | ... |\ /| ... | . // ======= \ / ======= . // CSMA \ / CSMA . // \ / . -// n1 +--- n0 ---+ n4 . +// n4 +--- n0 ---+ n1 . // | ... | / \ | ... | . // ======= / \ ======= . // CSMA / \ CSMA . // / \ . -// n6 + + n5 . +// n5 + + n6 . // | ... | | ... | . // ======= ======= . // CSMA CSMA . diff -r 503e8d54ee1d -r 5da8d25d3fec src/core/wscript --- a/src/core/wscript Fri Nov 28 15:12:05 2008 +0000 +++ b/src/core/wscript Sat Nov 29 14:10:03 2008 -0800 @@ -73,6 +73,7 @@ def build(bld): 'trace-source-accessor.cc', 'config.cc', 'callback.cc', + 'name-list.cc', ] core.uselib = 'RT' @@ -118,6 +119,7 @@ def build(bld): 'object-vector.h', 'deprecated.h', 'abort.h', + 'name-list.h', ] if sys.platform == 'win32': changeset: 3957:4aff71a211f5 parent: 3953:5da8d25d3fec parent: 3956:4ddcca845f07 user: Craig Dowell date: Sat Nov 29 14:10:16 2008 -0800 summary: branch merge diff -r 5da8d25d3fec -r 4aff71a211f5 src/devices/wifi/dca-txop.cc --- a/src/devices/wifi/dca-txop.cc Sat Nov 29 14:10:03 2008 -0800 +++ b/src/devices/wifi/dca-txop.cc Sat Nov 29 14:10:16 2008 -0800 @@ -475,6 +475,10 @@ DcaTxop::MissedCts (void) MY_DEBUG ("Cts Fail"); WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); station->ReportFinalRtsFailed (); + if (!m_txFailedCallback.IsNull ()) + { + m_txFailedCallback (m_currentHdr); + } // to reset the dcf. m_currentPacket = 0; m_dcf->ResetCw (); @@ -522,7 +526,11 @@ DcaTxop::MissedAck (void) MY_DEBUG ("Ack Fail"); WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); station->ReportFinalDataFailed (); - // to reset the dcf. + if (!m_txFailedCallback.IsNull ()) + { + m_txFailedCallback (m_currentHdr); + } + // to reset the dcf. m_currentPacket = 0; m_dcf->ResetCw (); } @@ -530,10 +538,6 @@ DcaTxop::MissedAck (void) { MY_DEBUG ("Retransmit"); m_currentHdr.SetRetry (); - if (!m_txFailedCallback.IsNull ()) - { - m_txFailedCallback (m_currentHdr); - } m_dcf->UpdateFailedCw (); } m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ())); changeset: 3958:b2f7b830d002 user: Craig Dowell date: Sat Nov 29 14:17:46 2008 -0800 summary: add name-list to core diff -r 4aff71a211f5 -r b2f7b830d002 src/core/name-list.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/name-list.cc Sat Nov 29 14:17:46 2008 -0800 @@ -0,0 +1,297 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2008 University of Washington + * + * 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 + */ + +#include "ns3/object.h" +#include "ns3/log.h" +#include "ns3/assert.h" +#include "ns3/abort.h" +#include "ns3/simulator.h" +#include "name-list.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("NameList"); + +/** + * \brief private implementation detail of the NameList API. + */ +class NameListPriv +{ +public: + NameListPriv (); + ~NameListPriv (); + + bool Add (Ptr obj, std::string name); + Ptr GetObjectOfName (std::string name); + + static NameListPriv *Get (void); + +private: + static NameListPriv **DoGet (void); + + static void Delete (void); + std::vector, std::string> > m_names; +}; + +NameListPriv * +NameListPriv::Get (void) +{ + return *(DoGet ()); +} + +NameListPriv ** +NameListPriv::DoGet (void) +{ + NS_LOG_FUNCTION_NOARGS (); + + // + // ptr is declared as a function-local static variable. This variable is + // guaranteed to be initialized to zero (by code generated by the compiler) + // the first time the function is called. Afterward it acts like a global + // variable whose scope is defined by the function. + // + static NameListPriv *ptr = 0; + + // + // We "piggyback" on the guaranteed initialization of ptr to zero and do + // essentially the same thing the compiler did there in order to create + // the private object one time. This is a simple way to implement a + // singleton (a simpleton?). + // + if (ptr == 0) + { + ptr = new NameListPriv; + Simulator::ScheduleDestroy (&NameListPriv::Delete); + } + // + // Returns a pointer to the pointer to the name list implementation object. + // Why? See NameListPriv::Delete + // + return &ptr; +} + +void +NameListPriv::Delete (void) +{ + NS_LOG_FUNCTION_NOARGS (); + + // + // DoGet returns a pointer to a pointer to the private implementation. We + // need to call the destructor on the pointer, and also set the pointer + // itself to zero to complete the teardown. + // + NameListPriv **ptr = DoGet (); + // + // This is a sneaky, behind the sheets way to get the object pointed to by the + // function local variable ptr, with scope up in DoGet, torn down and the + // pointer set to zero. + // + delete *ptr; + *ptr = 0; +} + +NameListPriv::NameListPriv () +{ + NS_LOG_FUNCTION_NOARGS (); +} + +NameListPriv::~NameListPriv () +{ + NS_LOG_FUNCTION_NOARGS (); + + // + // Clean up the list of names we have stored. This function is expected to be + // called during Simulator::Destroy + // + for (std::vector, std::string> >::iterator i = m_names.begin (); i != m_names.end (); ++i) + { + // + // We just decrement the reference count here. We leave it to others, + // for example the node list, to call dispose. + // + Ptr object = i->first; + i->first = 0; + } + // + // get rid of all of the pairs in the underlying vector. + // + m_names.erase (m_names.begin (), m_names.end ()); +} + +bool +NameListPriv::Add (Ptr object, std::string name) +{ + // + // We demand that all objects have a unique name in this particular namespace. + // If the proposed name is unique, we add it to the collection and return true. + // If there is an existing name in the collection, then we refuse to add it + // and return false. + // + if (GetObjectOfName (name) == 0) + { + m_names.push_back (std::make_pair (object, name)); + return true; + } + else + { + return false; + } +} + +Ptr +NameListPriv::GetObjectOfName (std::string name) +{ + NS_LOG_FUNCTION (name); + + // + // Just do a simple, old-fashioned, linear search through the name/object mappings + // for a name match. If we find an object of the given name, return its Ptr. The + // inability to find an object/name pair is reflected by returning a zero Ptr. + // + for (std::vector, std::string> >::iterator i = m_names.begin (); i != m_names.end (); ++i) + { + if (i->second == name) + { + return i->first; + } + } + return 0; +} + +} + +namespace ns3 { + +bool +NameList::Add (Ptr object, std::string name) +{ + return NameListPriv::Get ()->Add (object, name); +} + +Ptr +NameList::GetObjectOfNameInternal (std::string name) +{ + return NameListPriv::Get ()->GetObjectOfName (name); +} + +}//namespace ns3 + +#ifdef RUN_SELF_TESTS + +#include "test.h" +#include "object-factory.h" + +namespace { + +class TestObject : public ns3::Object +{ +public: + static ns3::TypeId GetTypeId (void) + { + static ns3::TypeId tid = ns3::TypeId ("TestObject") + .SetParent (Object::GetTypeId ()) + .HideFromDocumentation () + .AddConstructor (); + return tid; + } + TestObject () {} + virtual void Dispose (void) {} +}; + +class FakeTestObject : public ns3::Object +{ +public: + static ns3::TypeId GetTypeId (void) + { + static ns3::TypeId tid = ns3::TypeId ("FaleTestObject") + .SetParent (Object::GetTypeId ()) + .HideFromDocumentation () + .AddConstructor (); + return tid; + } + FakeTestObject () {} + virtual void Dispose (void) {} +}; + +} // namespace anonymous + +namespace ns3 { + +class NameListTest : public Test +{ +public: + NameListTest (); + virtual bool RunTests (void); +}; + +NameListTest::NameListTest () + : Test ("NameList") +{ +} + +bool +NameListTest::RunTests (void) +{ + bool result = true; + + std::string name1 = "Test Object 1"; + Ptr obj1 = CreateObject (); + + result = NameList::Add (obj1, name1); + NS_TEST_ASSERT_EQUAL (result, true); + + result = NameList::Add (obj1, name1); + NS_TEST_ASSERT_EQUAL (result, false); + + std::string name2 = "Test Object 2"; + Ptr obj2 = CreateObject (); + + result = NameList::Add (obj2, name2); + NS_TEST_ASSERT_EQUAL (result, true); + + Ptr obj = NameList::GetObjectOfName (name1); + NS_TEST_ASSERT_EQUAL (obj, obj1); + + Ptr fobj = NameList::GetObjectOfName (name1); + NS_TEST_ASSERT_EQUAL (fobj, 0); + + obj = NameList::GetObjectOfName (name2); + NS_TEST_ASSERT_EQUAL (obj, obj2); + + obj = NameList::GetObjectOfName ("yadda"); + NS_TEST_ASSERT_EQUAL (obj, 0); + + // + // Run the simulator and destroy it to get the Destroy method called on the + // private implementation object. We don't hack in a way here to get access + // to the raw pointer and assert that it is zeroed since taht really doesn't + // tell us that the memory allcated during the tests has successfully been + // released. Instead we depend on seeing a valgrind-clean run of the unit + // tests to really determine if the clean up was successful. + // + Simulator::Run (); + Simulator::Destroy (); + + return result; +} + +static NameListTest g_nameListTests; + +} // namespace ns3 + +#endif /* RUN_SELF_TESTS */ diff -r 4aff71a211f5 -r b2f7b830d002 src/core/name-list.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/name-list.h Sat Nov 29 14:17:46 2008 -0800 @@ -0,0 +1,80 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2008 University of Washington + * + * 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 + */ + +#ifndef NAME_LIST_H +#define NAME_LIST_H + +#include +#include "ns3/ptr.h" +#include "ns3/object.h" + +namespace ns3 { + +/** + * \brief A container of name and Ptr associations that allows us to + * give any ns3 Object a name. This is a flat namespace and we require all + * names to be unique. + */ +class NameList +{ +public: + /** + * \brief Add an object to name association to the global name list. The + * provided name string must be unique in the flat object name space. + * + * \param object Ptr to the object we want to associate a name with. + * \param name String containing the name of the object. + * \returns True if the pair is successfully added or false + * if the name already exists in the namespace. + */ + static bool Add (Ptr object, std::string name); + + /** + * \brief Retrieve an object of a given name from the global name list. + * + * \param name String containing the name of the object. + * \returns Ptr to the object associated with the parameter name if one + * exists otherwise the null Ptr. + */ + template + static Ptr GetObjectOfName (std::string name); + +private: + static Ptr GetObjectOfNameInternal (std::string name); + +}; + +template +Ptr +NameList::GetObjectOfName (std::string name) +{ + Ptr obj = NameList::GetObjectOfNameInternal (name); + if (obj) + { + return obj->GetObject (); + } + else + { + return 0; + } +} + + +}//namespace ns3 + +#endif /* NAME_LIST_H */ changeset: 3959:f3ea59b6758e user: Craig Dowell date: Sun Nov 30 17:04:54 2008 -0800 summary: name list becomes a simple bimap diff -r b2f7b830d002 -r f3ea59b6758e src/core/name-list.cc --- a/src/core/name-list.cc Sat Nov 29 14:17:46 2008 -0800 +++ b/src/core/name-list.cc Sun Nov 30 17:04:54 2008 -0800 @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include "ns3/object.h" #include "ns3/log.h" #include "ns3/assert.h" @@ -26,6 +27,21 @@ namespace ns3 { namespace ns3 { NS_LOG_COMPONENT_DEFINE ("NameList"); + +class NameListNode +{ +public: + NameListNode () {} + ~NameListNode () {m_children.clear ();} + + uint32_t GetNChildren () {return m_children.size ();} + NameListNode *GetChild (uint32_t n) {return m_children[n];} + void AddChild (NameListNode *child) {m_children.push_back (child);} + void SetName (std::string name) {m_name = name;} +private: + std::vector m_children; + std::string m_name; +}; /** * \brief private implementation detail of the NameList API. @@ -38,6 +54,7 @@ public: bool Add (Ptr obj, std::string name); Ptr GetObjectOfName (std::string name); + std::string GetNameOfObject (Ptr object); static NameListPriv *Get (void); @@ -137,12 +154,10 @@ NameListPriv::Add (Ptr object, s NameListPriv::Add (Ptr object, std::string name) { // - // We demand that all objects have a unique name in this particular namespace. - // If the proposed name is unique, we add it to the collection and return true. - // If there is an existing name in the collection, then we refuse to add it - // and return false. + // This class operates sort of like a bidirectional map, so we demand that all + // objects and names are unique.. // - if (GetObjectOfName (name) == 0) + if (GetObjectOfName (name) == 0 && GetNameOfObject (object).empty ()) { m_names.push_back (std::make_pair (object, name)); return true; @@ -173,9 +188,25 @@ NameListPriv::GetObjectOfName (std::stri return 0; } +std::string +NameListPriv::GetNameOfObject (Ptr object) +{ + NS_LOG_FUNCTION (object); + + // + // Just do a simple, old-fashioned, linear search through the name/object mappings + // for an object match. If we find an object of the given name, return its name. The + // inability to find an object/name pair is reflected by returning an empty string. + // + for (std::vector, std::string> >::iterator i = m_names.begin (); i != m_names.end (); ++i) + { + if (i->first == object) + { + return i->second; + } + } + return std::string (); } - -namespace ns3 { bool NameList::Add (Ptr object, std::string name) @@ -187,6 +218,12 @@ NameList::GetObjectOfNameInternal (std:: NameList::GetObjectOfNameInternal (std::string name) { return NameListPriv::Get ()->GetObjectOfName (name); +} + +std::string +NameList::GetNameOfObject (Ptr object) +{ + return NameListPriv::Get ()->GetNameOfObject (object); } }//namespace ns3 @@ -252,10 +289,22 @@ NameListTest::RunTests (void) std::string name1 = "Test Object 1"; Ptr obj1 = CreateObject (); + // + // Put an pair into the name list + // result = NameList::Add (obj1, name1); NS_TEST_ASSERT_EQUAL (result, true); - result = NameList::Add (obj1, name1); + // + // We shouldn't be able to put another pair into the list with either the same + // name or same object in it. + // + Ptr someOtherObject = CreateObject (); + + result = NameList::Add (someOtherObject, name1); + NS_TEST_ASSERT_EQUAL (result, false); + + result = NameList::Add (obj1, "Some other name"); NS_TEST_ASSERT_EQUAL (result, false); std::string name2 = "Test Object 2"; @@ -267,14 +316,24 @@ NameListTest::RunTests (void) Ptr obj = NameList::GetObjectOfName (name1); NS_TEST_ASSERT_EQUAL (obj, obj1); + std::string name = NameList::GetNameOfObject (obj); + NS_TEST_ASSERT_EQUAL (name, name1); + Ptr fobj = NameList::GetObjectOfName (name1); NS_TEST_ASSERT_EQUAL (fobj, 0); obj = NameList::GetObjectOfName (name2); NS_TEST_ASSERT_EQUAL (obj, obj2); + name = NameList::GetNameOfObject (obj); + NS_TEST_ASSERT_EQUAL (name, name2); + obj = NameList::GetObjectOfName ("yadda"); NS_TEST_ASSERT_EQUAL (obj, 0); + + Ptr objx = CreateObject (); + name = NameList::GetNameOfObject (obj); + NS_TEST_ASSERT_EQUAL (name.empty (), true); // // Run the simulator and destroy it to get the Destroy method called on the diff -r b2f7b830d002 -r f3ea59b6758e src/core/name-list.h --- a/src/core/name-list.h Sat Nov 29 14:17:46 2008 -0800 +++ b/src/core/name-list.h Sun Nov 30 17:04:54 2008 -0800 @@ -54,6 +54,8 @@ public: template static Ptr GetObjectOfName (std::string name); + static std::string GetNameOfObject (Ptr object); + private: static Ptr GetObjectOfNameInternal (std::string name); changeset: 3960:e505f050f330 user: Craig Dowell date: Sun Nov 30 17:35:12 2008 -0800 summary: teach csma-one-subnet.cc to use some NameList functionality diff -r f3ea59b6758e -r e505f050f330 examples/csma-one-subnet.cc --- a/examples/csma-one-subnet.cc Sun Nov 30 17:04:54 2008 -0800 +++ b/examples/csma-one-subnet.cc Sun Nov 30 17:35:12 2008 -0800 @@ -64,6 +64,14 @@ main (int argc, char *argv[]) NodeContainer nodes; nodes.Create (4); +// +// Associate human readable names with some of the nodes so we can refer to them +// easily. +// + NameList::Add (nodes.Get (0), "Node 0"); + NameList::Add (nodes.Get (1), "Node 1"); + NameList::Add (nodes.Get (3), "Node 3"); + NS_LOG_INFO ("Build Topology"); CsmaHelper csma; csma.SetChannelAttribute ("DataRate", DataRateValue (5000000)); @@ -74,9 +82,20 @@ main (int argc, char *argv[]) // NetDeviceContainer devices = csma.Install (nodes); +// +// Associate human readable names with some of the devices so we can refer to them +// easily. Recall that the CsmaHelper will return a container arranged so the zeroth +// device in the returned container corresponds to the zeroth node in the node +// container passed as a parameter. +// + NameList::Add (devices.Get (0), "Node 0/eth0"); + NameList::Add (devices.Get (1), "Node 1/eth0"); + NameList::Add (devices.Get (3), "Node 3/eth0"); + InternetStackHelper internet; internet.Install (nodes); +// // We've got the "hardware" in place. Now we need to add IP addresses. // NS_LOG_INFO ("Assign IP Addresses."); @@ -85,7 +104,14 @@ main (int argc, char *argv[]) Ipv4InterfaceContainer interfaces = ipv4.Assign (devices); // -// Create an OnOff application to send UDP datagrams from node zero to node 1. +// Associate human readable names with some of the Ipv4 Interfaces so we can +// refer to them easily. +// + NameList::Add (interfaces.GetInterface (0), "Node 0/ipv4"); + NameList::Add (interfaces.GetInterface (1), "Node 1/ipv4"); + +// +// Create an OnOff application to send UDP datagrams from "Node 0" to "Node 1". // NS_LOG_INFO ("Create Applications."); uint16_t port = 9; // Discard port (RFC 863) @@ -95,7 +121,7 @@ main (int argc, char *argv[]) onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1))); onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0))); - ApplicationContainer app = onoff.Install (nodes.Get (0)); + ApplicationContainer app = onoff.Install (NameList::GetObjectOfName ("Node 0")); // Start the application app.Start (Seconds (1.0)); app.Stop (Seconds (10.0)); @@ -103,19 +129,19 @@ main (int argc, char *argv[]) // Create an optional packet sink to receive these packets PacketSinkHelper sink ("ns3::UdpSocketFactory", Address (InetSocketAddress (Ipv4Address::GetAny (), port))); - app = sink.Install (nodes.Get (1)); + app = sink.Install (NameList::GetObjectOfName ("Node 1")); app.Start (Seconds (0.0)); // -// Create a similar flow from n3 to n0, starting at time 1.1 seconds +// Create a similar flow from "Node 3" to "Node 0", starting at time 1.1 seconds // onoff.SetAttribute ("Remote", AddressValue (InetSocketAddress (interfaces.GetAddress (0), port))); - app = onoff.Install (nodes.Get (3)); + app = onoff.Install (NameList::GetObjectOfName ("Node 3")); app.Start(Seconds (1.1)); app.Stop (Seconds (10.0)); - app = sink.Install (nodes.Get (0)); + app = sink.Install (NameList::GetObjectOfName ("Node 0")); app.Start (Seconds (0.0)); // diff -r f3ea59b6758e -r e505f050f330 src/helper/ipv4-interface-container.cc --- a/src/helper/ipv4-interface-container.cc Sun Nov 30 17:04:54 2008 -0800 +++ b/src/helper/ipv4-interface-container.cc Sun Nov 30 17:35:12 2008 -0800 @@ -28,6 +28,13 @@ Ipv4InterfaceContainer::GetAddress (uint uint32_t interface = m_interfaces[i].second; return ipv4->GetAddress (interface); } + +Ptr +Ipv4InterfaceContainer::GetInterface (uint32_t i) const +{ + return m_interfaces[i].first; +} + void Ipv4InterfaceContainer::SetMetric (uint32_t i, uint16_t metric) { diff -r f3ea59b6758e -r e505f050f330 src/helper/ipv4-interface-container.h --- a/src/helper/ipv4-interface-container.h Sun Nov 30 17:04:54 2008 -0800 +++ b/src/helper/ipv4-interface-container.h Sun Nov 30 17:35:12 2008 -0800 @@ -31,6 +31,9 @@ public: uint32_t GetN (void) const; Ipv4Address GetAddress (uint32_t i) const; + + Ptr GetInterface (uint32_t i) const; + void SetMetric (uint32_t i, uint16_t metric); void Add (Ptr ipv4, uint32_t interface); changeset: 3961:2b65d827c7c6 user: Craig Dowell date: Sun Nov 30 18:50:33 2008 -0800 summary: teach some helpers about NameList diff -r e505f050f330 -r 2b65d827c7c6 examples/csma-one-subnet.cc --- a/examples/csma-one-subnet.cc Sun Nov 30 17:35:12 2008 -0800 +++ b/examples/csma-one-subnet.cc Sun Nov 30 18:50:33 2008 -0800 @@ -47,16 +47,19 @@ main (int argc, char *argv[]) #if 0 LogComponentEnable ("CsmaOneSubnetExample", LOG_LEVEL_INFO); #endif + // // Make the random number generators generate reproducible results. // RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8); + // // Allow the user to override any of the defaults and the above Bind() at // run-time, via command-line arguments // CommandLine cmd; cmd.Parse (argc, argv); + // // Explicitly create the nodes required by the topology (shown above). // @@ -76,6 +79,7 @@ main (int argc, char *argv[]) CsmaHelper csma; csma.SetChannelAttribute ("DataRate", DataRateValue (5000000)); csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2))); + // // Now fill out the topology by creating the net devices required to connect // the nodes to the channels and hooking them up. @@ -159,7 +163,9 @@ main (int argc, char *argv[]) // and can be read by the "tcpdump -r" command (use "-tt" option to // display timestamps correctly) // - CsmaHelper::EnablePcapAll ("csma-one-subnet"); + CsmaHelper::EnablePcap ("csma-one-subnet", "Node 0/eth0"); + CsmaHelper::EnablePcap ("csma-one-subnet", "Node 1/eth0"); + CsmaHelper::EnablePcap ("csma-one-subnet", "Node 3/eth0"); // // Now, do the actual simulation. // diff -r e505f050f330 -r 2b65d827c7c6 src/helper/csma-helper.cc --- a/src/helper/csma-helper.cc Sun Nov 30 17:35:12 2008 -0800 +++ b/src/helper/csma-helper.cc Sun Nov 30 18:50:33 2008 -0800 @@ -25,7 +25,9 @@ #include "ns3/csma-channel.h" #include "ns3/pcap-writer.h" #include "ns3/config.h" +#include "ns3/name-list.h" #include "ns3/packet.h" +#include "ns3/abort.h" #include namespace ns3 { @@ -96,6 +98,15 @@ CsmaHelper::EnablePcap (std::string file oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/TxQueue/Enqueue"; Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&CsmaHelper::EnqueueEvent, pcap)); } + +void +CsmaHelper::EnablePcap (std::string filename, std::string devname) +{ + Ptr device = NameList::GetObjectOfName (devname); + NS_ABORT_MSG_UNLESS (device, "CsmaHelper::EnablePcap(): Device name not found"); + EnablePcap (filename, device->GetNode ()->GetId (), device->GetIfIndex ()); +} + void CsmaHelper::EnablePcap (std::string filename, NetDeviceContainer d) { diff -r e505f050f330 -r 2b65d827c7c6 src/helper/csma-helper.h --- a/src/helper/csma-helper.h Sun Nov 30 17:35:12 2008 -0800 +++ b/src/helper/csma-helper.h Sun Nov 30 18:50:33 2008 -0800 @@ -96,6 +96,13 @@ public: * been fully constructed. */ static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid); + /** + * \param filename filename prefix to use for pcap files. + * \param devname the name of a device stored in the NameList. + * + * Enable pcap output on the device specified by name + */ + static void EnablePcap (std::string filename, std::string devname); /** * \param filename filename prefix to use for pcap files. * \param d container of devices of type ns3::CsmaNetDevice diff -r e505f050f330 -r 2b65d827c7c6 src/helper/emu-helper.cc --- a/src/helper/emu-helper.cc Sun Nov 30 17:35:12 2008 -0800 +++ b/src/helper/emu-helper.cc Sun Nov 30 18:50:33 2008 -0800 @@ -25,8 +25,9 @@ #include "ns3/emu-net-device.h" #include "ns3/pcap-writer.h" #include "ns3/config.h" +#include "ns3/name-list.h" #include "ns3/packet.h" - +#include "ns3/abort.h" #include "emu-helper.h" NS_LOG_COMPONENT_DEFINE ("EmuHelper"); @@ -87,6 +88,14 @@ EmuHelper::EnablePcap ( "/$ns3::EmuNetDevice/TxQueue/Enqueue"; Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&EmuHelper::EnqueueEvent, pcap)); +} + +void +EmuHelper::EnablePcap (std::string filename, std::string devname) +{ + Ptr device = NameList::GetObjectOfName (devname); + NS_ABORT_MSG_UNLESS (device, "EmuHelper::EnablePcap(): Device name not found"); + EnablePcap (filename, device->GetNode ()->GetId (), device->GetIfIndex ()); } void diff -r e505f050f330 -r 2b65d827c7c6 src/helper/emu-helper.h --- a/src/helper/emu-helper.h Sun Nov 30 17:35:12 2008 -0800 +++ b/src/helper/emu-helper.h Sun Nov 30 18:50:33 2008 -0800 @@ -81,8 +81,15 @@ public: * This method should be invoked after the network topology has * been fully constructed. */ - static void EnablePcap (std::string filename, uint32_t nodeid, - uint32_t deviceid); + static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid); + + /** + * \param filename filename prefix to use for pcap files. + * \param devname name of device + * + * Enable pcap output on the named device. + */ + static void EnablePcap (std::string filename, std::string devname); /** * \param filename filename prefix to use for pcap files. diff -r e505f050f330 -r 2b65d827c7c6 src/helper/point-to-point-helper.cc --- a/src/helper/point-to-point-helper.cc Sun Nov 30 17:35:12 2008 -0800 +++ b/src/helper/point-to-point-helper.cc Sun Nov 30 18:50:33 2008 -0800 @@ -25,10 +25,10 @@ #include "ns3/pcap-writer.h" #include "ns3/config.h" #include "ns3/packet.h" - +#include "ns3/name-list.h" +#include "ns3/abort.h" namespace ns3 { - PointToPointHelper::PointToPointHelper () { @@ -96,6 +96,15 @@ PointToPointHelper::EnablePcap (std::str oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/TxQueue/Enqueue"; Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PointToPointHelper::EnqueueEvent, pcap)); } + +void +PointToPointHelper::EnablePcap (std::string filename, std::string devname) +{ + Ptr device = NameList::GetObjectOfName (devname); + NS_ABORT_MSG_UNLESS (device, "PointToPointHelper::EnablePcap(): Device name not found"); + EnablePcap (filename, device->GetNode ()->GetId (), device->GetIfIndex ()); +} + void PointToPointHelper::EnablePcap (std::string filename, NetDeviceContainer d) { diff -r e505f050f330 -r 2b65d827c7c6 src/helper/point-to-point-helper.h --- a/src/helper/point-to-point-helper.h Sun Nov 30 17:35:12 2008 -0800 +++ b/src/helper/point-to-point-helper.h Sun Nov 30 18:50:33 2008 -0800 @@ -95,6 +95,15 @@ public: * been fully constructed. */ static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid); + + /** + * \param filename filename prefix to use for pcap files. + * \param devname name of device + * + * Enable pcap output on the named device. + */ + static void EnablePcap (std::string filename, std::string devname); + /** * \param filename filename prefix to use for pcap files. * \param d container of devices of type ns3::PointToPointNetDevice diff -r e505f050f330 -r 2b65d827c7c6 src/helper/yans-wifi-phy-helper.cc --- a/src/helper/yans-wifi-phy-helper.cc Sun Nov 30 17:35:12 2008 -0800 +++ b/src/helper/yans-wifi-phy-helper.cc Sun Nov 30 18:50:33 2008 -0800 @@ -26,6 +26,8 @@ #include "ns3/wifi-net-device.h" #include "ns3/pcap-writer.h" #include "ns3/simulator.h" +#include "ns3/name-list.h" +#include "ns3/abort.h" #include "ns3/config.h" namespace ns3 { @@ -229,6 +231,15 @@ YansWifiPhyHelper::EnablePcap (std::stri oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/RxOk"; Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapPhyRxEvent, pcap)); } + +void +YansWifiPhyHelper::EnablePcap (std::string filename, std::string devname) +{ + Ptr device = NameList::GetObjectOfName (devname); + NS_ABORT_MSG_UNLESS (device, "YansWifiPhyHelper::EnablePcap(): Device name not found"); + EnablePcap (filename, device->GetNode ()->GetId (), device->GetIfIndex ()); +} + void YansWifiPhyHelper::EnablePcap (std::string filename, NetDeviceContainer d) { diff -r e505f050f330 -r 2b65d827c7c6 src/helper/yans-wifi-phy-helper.h --- a/src/helper/yans-wifi-phy-helper.h Sun Nov 30 17:35:12 2008 -0800 +++ b/src/helper/yans-wifi-phy-helper.h Sun Nov 30 18:50:33 2008 -0800 @@ -92,6 +92,15 @@ public: * been fully constructed. */ static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid); + + /** + * \param filename filename prefix to use for pcap files. + * \param devname name of device + * + * Enable pcap output on the named device. + */ + static void EnablePcap (std::string filename, std::string devname); + /** * \param filename filename prefix to use for pcap files. * \param d container of devices of type ns3::WifiNetDevice changeset: 3962:80eb17912bcd tag: tip user: Craig Dowell date: Sun Nov 30 18:55:38 2008 -0800 summary: remove dead code diff -r 2b65d827c7c6 -r 80eb17912bcd src/core/name-list.cc --- a/src/core/name-list.cc Sun Nov 30 18:50:33 2008 -0800 +++ b/src/core/name-list.cc Sun Nov 30 18:55:38 2008 -0800 @@ -27,21 +27,6 @@ namespace ns3 { namespace ns3 { NS_LOG_COMPONENT_DEFINE ("NameList"); - -class NameListNode -{ -public: - NameListNode () {} - ~NameListNode () {m_children.clear ();} - - uint32_t GetNChildren () {return m_children.size ();} - NameListNode *GetChild (uint32_t n) {return m_children[n];} - void AddChild (NameListNode *child) {m_children.push_back (child);} - void SetName (std::string name) {m_name = name;} -private: - std::vector m_children; - std::string m_name; -}; /** * \brief private implementation detail of the NameList API.